Rev 796 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
716 | lvd | 1 | #include "std.h" |
2 | |||
3 | #include "emul.h" |
||
4 | #include "vars.h" |
||
5 | #include "draw.h" |
||
6 | #include "drawnomc.h" |
||
7 | #include "dx.h" |
||
8 | #include "dxr_text.h" |
||
9 | #include "dxr_rsm.h" |
||
10 | #include "dxr_advm.h" |
||
11 | #include "memory.h" |
||
12 | #include "config.h" |
||
13 | |||
14 | #include "util.h" |
||
15 | |||
16 | #ifdef CACHE_ALIGNED |
||
17 | CACHE_ALIGNED unsigned char rbuf[sizeof_rbuf]; |
||
18 | #else // __declspec(align) not available, force QWORD align with old method |
||
19 | __int64 rbuf__[sizeof_rbuf/sizeof(__int64)]; |
||
20 | unsigned char * const rbuf = (unsigned char*)rbuf__; |
||
21 | #endif |
||
22 | |||
23 | unsigned char * const rbuf_s = rbuf + rb2_offs; // frames to mix with noflic and resampler filters |
||
24 | unsigned char * const save_buf = rbuf_s + rb2_offs*MAX_BUFFERS; // used in monitor |
||
25 | |||
26 | T t; |
||
27 | |||
28 | videopoint *vcurr; // ��������� �� ������� ������� �� video[] |
||
29 | // ������ ���������� ������� ������ |
||
30 | // video[i] - ������ ������ (������������ ������ next_t) |
||
31 | // video[i+1] - ����� ������ (������������ ��� ���������) |
||
796 | DimkaM | 32 | static videopoint video[4*MAX_HEIGHT]; |
716 | lvd | 33 | unsigned vmode; // what are drawing: 0-not visible, 1-border, 2-screen |
796 | DimkaM | 34 | static unsigned prev_t; // ���� �� ������� ��� ��������� ��������� ������� |
716 | lvd | 35 | unsigned *atrtab; |
36 | |||
37 | unsigned char colortab[0x100];// map zx attributes to pc attributes |
||
38 | // colortab shifted to 8 and 24 |
||
39 | unsigned colortab_s8[0x100]; |
||
40 | unsigned colortab_s24[0x100]; |
||
41 | |||
42 | /* |
||
43 | #include "drawnomc.cpp" |
||
44 | #include "draw_384.cpp" |
||
45 | */ |
||
46 | |||
47 | PALETTEENTRY pal0[0x100]; // emulator palette |
||
48 | |||
49 | void AtmVideoController::PrepareFrameATM2(int VideoMode) |
||
50 | { |
||
51 | for (int y=0; y<256; y++) |
||
52 | { |
||
53 | if ( VideoMode == 6 ) |
||
54 | { |
||
55 | // �������� � ��������� ����������� |
||
56 | Scanlines[y].Offset = 64*(y/8); |
||
57 | } else { |
||
58 | // �������� � ��������� ����������� |
||
59 | Scanlines[y].Offset = (y<56) ? 0 : 40*(y-56); |
||
60 | } |
||
61 | Scanlines[y].VideoMode = VideoMode; |
||
62 | } |
||
63 | CurrentRayLine = 0; |
||
64 | IncCounter_InRaster = 0; |
||
65 | IncCounter_InBorder = 0; |
||
66 | } |
||
67 | |||
68 | void AtmVideoController::PrepareFrameATM1(int VideoMode) |
||
69 | { |
||
70 | for (int y=56; y<256; y++) |
||
71 | { |
||
72 | Scanlines[y].Offset = 40*(y-56); |
||
73 | Scanlines[y].VideoMode = VideoMode; |
||
74 | } |
||
75 | } |
||
76 | |||
77 | |||
78 | AtmVideoController AtmVideoCtrl; |
||
79 | |||
80 | void video_permanent_tables() |
||
81 | { |
||
82 | // pixel doubling table |
||
83 | unsigned i; //Alone Coder 0.36.7 |
||
84 | for (/*unsigned*/ i = 0; i < 0x100; i++) { |
||
85 | unsigned res = 0; |
||
796 | DimkaM | 86 | for (unsigned j = 0x80; j; j/=2) { |
87 | res <<= 2; |
||
88 | if(i & j) |
||
89 | { |
||
90 | res |= 3; |
||
91 | } |
||
716 | lvd | 92 | } |
93 | t.dbl[i] = res; |
||
94 | } |
||
95 | |||
96 | for (i = 0; i < 0x100; i++) { |
||
97 | unsigned r1 = 0, r2 = 0; |
||
796 | DimkaM | 98 | if(i & 0x01) |
99 | { |
||
100 | r1++; r2 += 1; |
||
101 | } |
||
102 | if(i & 0x02) |
||
103 | { |
||
104 | r1++; r2 += 1; |
||
105 | } |
||
106 | if(i & 0x04) |
||
107 | { |
||
108 | r1++; r2 += 0x100; |
||
109 | } |
||
110 | if(i & 0x08) |
||
111 | { |
||
112 | r1++; r2 += 0x100; |
||
113 | } |
||
114 | if(i & 0x10) |
||
115 | { |
||
116 | r1 += 0x100; r2 += 0x10000; |
||
117 | } |
||
118 | if(i & 0x20) |
||
119 | { |
||
120 | r1 += 0x100; r2 += 0x10000; |
||
121 | } |
||
122 | if(i & 0x40) |
||
123 | { |
||
124 | r1 += 0x100; r2 += 0x1000000; |
||
125 | } |
||
126 | if(i & 0x80) |
||
127 | { |
||
128 | r1 += 0x100; r2 += 0x1000000; |
||
129 | } |
||
716 | lvd | 130 | // low byte of settab - number of pixels in low nibble of i |
131 | // high byte of low word of settab - number of pixels in high nibble of i |
||
132 | t.settab[i] = r1; |
||
133 | t.settab2[i] = r2*4; // *4 - convert square 2x2 to 4x4 |
||
134 | } |
||
135 | |||
136 | i = 0; // calc screen addresses |
||
796 | DimkaM | 137 | for(unsigned p = 0; p < 4; p++) |
138 | { |
||
139 | for(unsigned y = 0; y < 8; y++) |
||
140 | { |
||
141 | for(unsigned o = 0; o < 8; o++, i++) |
||
142 | { |
||
143 | t.scrtab[i] = p * 0x800 + y * 0x20 + o * 0x100; |
||
144 | t.atrtab_hwmc[i] = t.scrtab[i] + 0x2000; |
||
145 | t.atrtab[i] = 0x1800 + (p * 8 + y) * 32; |
||
146 | } |
||
147 | } |
||
148 | } |
||
716 | lvd | 149 | |
150 | // alco table |
||
151 | static unsigned disp_0[] = { 0x0018, 0x2000, 0x2008, 0x2010, 0x2018, 0x0008 }; |
||
152 | static unsigned base_s[] = { 0x10000, 0x14000, 0x14800, 0x15000, 0x11800 }; |
||
153 | static unsigned base_a[] = { 0x11000, 0x15800, 0x15900, 0x15A00, 0x11300 }; |
||
154 | for (unsigned y = 0; y < 304; y++) |
||
155 | for (unsigned x = 0; x < 6; x++) { |
||
156 | unsigned disp = disp_0[x] + (y & 0x38)*4; |
||
157 | ::t.alco[y][x].a = memory + base_a[y/64] + disp; |
||
158 | ::t.alco[y][x].s = memory + base_s[y/64] + disp + (y & 7)*0x100; |
||
159 | } |
||
160 | |||
161 | #ifdef MOD_VID_VD |
||
162 | // this code is only for ygrbYGRB palette |
||
163 | for (unsigned byte = 0; byte < 0x100; byte++) |
||
164 | for (int bit = 0; bit < 8; bit++) |
||
165 | t.vdtab[0][0][byte].m64_u8[7-bit] = (byte & (1 << bit))? 0x11 : 0; |
||
166 | for (int pl = 1; pl < 4; pl++) |
||
167 | for (unsigned byte = 0; byte < 0x100; byte++) |
||
168 | t.vdtab[0][pl][byte] = _mm_slli_pi32(t.vdtab[0][0][byte], pl); |
||
169 | for (i = 0; i < sizeof t.vdtab[0]; i++) |
||
170 | ((unsigned char*)t.vdtab[1])[i] = ((unsigned char*)t.vdtab[0])[i] & 0x0F; |
||
171 | _mm_empty(); |
||
172 | #endif |
||
173 | |||
174 | temp.offset_vscroll_prev = 0; |
||
175 | temp.offset_vscroll = 0; |
||
176 | temp.offset_hscroll_prev = 0; |
||
177 | temp.offset_hscroll = 0; |
||
178 | } |
||
179 | |||
796 | DimkaM | 180 | static unsigned getYUY2(unsigned r, unsigned g, unsigned b) |
716 | lvd | 181 | { |
182 | int y = (int)(0.29*r + 0.59*g + 0.14*b); |
||
183 | int u = (int)(128.0 - 0.14*r - 0.29*g + 0.43*b); |
||
184 | int v = (int)(128.0 + 0.36*r - 0.29*g - 0.07*b); |
||
185 | if (y < 0) y = 0; if (y > 255) y = 255; |
||
186 | if (u < 0) u = 0; if (u > 255) u = 255; |
||
187 | if (v < 0) v = 0; if (v > 255) v = 255; |
||
188 | return WORD4(y,u,y,v); |
||
189 | } |
||
190 | |||
796 | DimkaM | 191 | static void create_palette() |
716 | lvd | 192 | { |
796 | DimkaM | 193 | if((temp.rflags & RF_8BPCH) && temp.obpp == 8) |
194 | { |
||
195 | temp.rflags |= RF_GRAY; |
||
196 | conf.flashcolor = 0; |
||
197 | } |
||
716 | lvd | 198 | |
796 | DimkaM | 199 | PALETTE_OPTIONS *pl = &pals[conf.pal]; |
200 | // Ii Ii Ii Ii |
||
201 | // 00 01 10 11 |
||
202 | unsigned char brights[4] = { u8(pl->ZZ), u8(pl->ZN), u8(pl->NN), u8(pl->BB) }; |
||
203 | unsigned char brtab[16] = |
||
204 | { // ZZ NN ZZ BB |
||
205 | u8(pl->ZZ), u8(pl->ZN), u8(pl->ZZ), u8(pl->ZB), // ZZ |
||
206 | u8(pl->ZN), u8(pl->NN), u8(pl->ZN), u8(pl->NB), // NN |
||
207 | u8(pl->ZZ), u8(pl->ZN), u8(pl->ZZ), u8(pl->ZB), // ZZ (bright=1,ink=0) |
||
208 | u8(pl->ZB), u8(pl->NB), u8(pl->ZB), u8(pl->BB) // BB |
||
209 | }; |
||
716 | lvd | 210 | |
796 | DimkaM | 211 | for(unsigned i = 0; i < 0x100; i++) |
212 | { |
||
213 | unsigned r0, g0, b0; |
||
214 | if(temp.rflags & RF_GRAY) |
||
215 | { // grayscale palette |
||
216 | r0 = g0 = b0 = i; |
||
217 | } |
||
218 | else if(temp.rflags & RF_PALB) |
||
219 | { // palette index: |
||
220 | if(comp.ula_plus_en) // gggrrrbb (ULA+) |
||
221 | { // �������� ������������ ������� |
||
222 | b0 = ((i & 3) * 255) / 3; // 2 ���� |
||
223 | r0 = (((i >> 2) & 7) * 255) / 7; // 3 ���� |
||
224 | g0 = (((i >> 5) & 7) * 255) / 7; // 3 ���� |
||
225 | } |
||
226 | else // gg0rr0bb (ATM / profi / bilinear filter) |
||
227 | { // ���������� ��������� ������� (�� 2 ����) �� ������� ������� �� .ini ����� |
||
228 | b0 = brights[i & 3]; |
||
229 | r0 = brights[(i >> 3) & 3]; |
||
230 | g0 = brights[(i >> 6) & 3]; |
||
231 | } |
||
232 | } |
||
233 | else |
||
234 | { // palette index: ygrbYGRB (������� zx ����� ��� �������) |
||
235 | // ���������� ��������� ������� (�� 4 ����) �� ������� ������� �� .ini ����� |
||
236 | b0 = brtab[((i >> 0) & 1) + ((i >> 2) & 2) + ((i >> 2) & 4) + ((i >> 4) & 8)]; // brtab[ybYB] |
||
237 | r0 = brtab[((i >> 1) & 1) + ((i >> 2) & 2) + ((i >> 3) & 4) + ((i >> 4) & 8)]; // brtab[yrYR] |
||
238 | g0 = brtab[((i >> 2) & 1) + ((i >> 2) & 2) + ((i >> 4) & 4) + ((i >> 4) & 8)]; // brtab[ygYG] |
||
239 | } |
||
716 | lvd | 240 | |
796 | DimkaM | 241 | // transform with current settings |
242 | unsigned r = 0xFF & ((r0 * pl->r11 + g0 * pl->r12 + b0 * pl->r13) / 0x100); |
||
243 | unsigned g = 0xFF & ((r0 * pl->r21 + g0 * pl->r22 + b0 * pl->r23) / 0x100); |
||
244 | unsigned b = 0xFF & ((r0 * pl->r31 + g0 * pl->r32 + b0 * pl->r33) / 0x100); |
||
716 | lvd | 245 | |
796 | DimkaM | 246 | // prepare palette in bitmap header for GDI renderer |
247 | gdibmp.header.bmiColors[i].rgbRed = pal0[i].peRed = BYTE(r); |
||
248 | gdibmp.header.bmiColors[i].rgbGreen = pal0[i].peGreen = BYTE(g); |
||
249 | gdibmp.header.bmiColors[i].rgbBlue = pal0[i].peBlue = BYTE(b); |
||
250 | } |
||
251 | memcpy(syspalette + 10, pal0 + 10, (246 - 9) * sizeof *syspalette); |
||
252 | |||
253 | if(conf.mem_model == MM_PROFI) |
||
254 | { |
||
255 | // profi palette mapping (port out to palette index) |
||
256 | for(unsigned i = 0; i < 0x100; i++) |
||
257 | { |
||
258 | unsigned dst; |
||
259 | dst = i; // Gg0Rr0Bb => Gg0Rr0Bb |
||
260 | t.profi_pal_map[i] = dst; |
||
261 | } |
||
262 | } |
||
716 | lvd | 263 | } |
264 | |||
265 | void atm_zc_tables();//forward |
||
266 | |||
267 | // make colortab: zx-attr -> pc-attr |
||
796 | DimkaM | 268 | static void make_colortab(char flash_active) |
716 | lvd | 269 | { |
796 | DimkaM | 270 | if (conf.flashcolor || conf.ula_plus) |
716 | lvd | 271 | flash_active = 0; |
272 | |||
796 | DimkaM | 273 | for (unsigned a = 0; a < 0x100; a++) // a - zx-attr |
716 | lvd | 274 | { |
275 | unsigned char ink = a & 7; |
||
276 | unsigned char paper = (a >> 3) & 7; |
||
277 | unsigned char bright = (a >> 6) & 1; |
||
278 | unsigned char flash = (a >> 7) & 1; |
||
279 | |||
796 | DimkaM | 280 | // if((conf.flashcolor && ink) || !conf.flashcolor) |
281 | ink |= bright << 3; |
||
716 | lvd | 282 | |
796 | DimkaM | 283 | // if((conf.flashcolor && paper) || !conf.flashcolor) |
284 | paper |= ((conf.flashcolor || (conf.ula_plus && comp.ula_plus_en)) ? flash : bright) << 3; |
||
716 | lvd | 285 | |
286 | if (flash_active && flash) |
||
287 | { |
||
288 | unsigned char t = ink; |
||
289 | ink = paper; |
||
290 | paper = t; |
||
291 | } |
||
292 | |||
796 | DimkaM | 293 | u8 color = u8((paper << 4) | ink); // color - pc-attr |
716 | lvd | 294 | |
295 | colortab[a] = color; |
||
796 | DimkaM | 296 | colortab_s8[a] = unsigned(color << 8U); |
297 | colortab_s24[a] = unsigned(color << 24U); |
||
716 | lvd | 298 | } |
299 | |||
300 | if (conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3 || conf.mem_model == MM_ATM450) |
||
301 | atm_zc_tables(); // update with new flash bit |
||
302 | } |
||
303 | |||
304 | // make attrtab: pc-attr + 0x100*pixel -> palette index |
||
796 | DimkaM | 305 | static void attr_tables() |
716 | lvd | 306 | { |
307 | unsigned char flashcolor = (temp.rflags & RF_MON)? 0 : conf.flashcolor; |
||
308 | for (unsigned a = 0; a < 0x100; a++) |
||
309 | { |
||
796 | DimkaM | 310 | unsigned char ink = (a & 0x0F), paper = u8(a >> 4); |
716 | lvd | 311 | if (flashcolor) |
312 | paper = (paper & 7) + (ink & 8); // paper_bright from ink |
||
313 | |||
314 | if (temp.rflags & RF_GRAY) |
||
315 | { // grayscale palette |
||
316 | t.attrtab[a] = paper*16; |
||
317 | t.attrtab[a+0x100] = ink*16; |
||
318 | } |
||
319 | else if (temp.rflags & RF_COMPPAL) |
||
796 | DimkaM | 320 | { |
321 | // ������� � ������� ULA+ |
||
322 | u8 paper_idx; // fb1ppp |
||
323 | u8 ink_idx; // fb0iii |
||
324 | if(comp.ula_plus_en) |
||
325 | { |
||
326 | u8 flash = (a & 0x80) >> 7; |
||
327 | u8 bright = (a & 8) >> 3; |
||
328 | paper &= 7; |
||
329 | ink &= 7; |
||
330 | u8 pal_no = u8(((flash << 1) | bright) << 4); |
||
331 | paper_idx = u8(pal_no | 8 | paper); |
||
332 | ink_idx = u8(pal_no | 0 | ink); |
||
333 | } |
||
334 | else |
||
335 | { //------ for ATM / profi palette - direct values from palette registers |
||
336 | paper = a >> 4; |
||
337 | ink = a & 0x0F; |
||
338 | paper_idx = u8(((paper & 8) << 1) | (paper & 7)); |
||
339 | ink_idx = u8(((ink & 8) << 1) | (ink & 7)); |
||
340 | } |
||
341 | t.attrtab[a] = comp.comp_pal[paper_idx]; // paper |
||
342 | t.attrtab[a | 0x100] = comp.comp_pal[ink_idx]; // ink |
||
716 | lvd | 343 | } |
344 | else if (temp.rflags & RF_PALB) |
||
345 | { //----------------------------- for bilinear |
||
346 | unsigned char b0,b1, r0,r1, g0,g1; |
||
796 | DimkaM | 347 | b0 = (paper >> 0) & 1; r0 = (paper >> 1) & 1; g0 = (paper >> 2) & 1; |
348 | b1 = (ink >> 0) & 1; r1 = (ink >> 1) & 1; g1 = (ink >> 2) & 1; |
||
716 | lvd | 349 | |
350 | if (flashcolor && (a & 0x80)) |
||
351 | { |
||
796 | DimkaM | 352 | b1 += b0; r1 += r0; g1 += g0; |
353 | r0 = b0 = g0 = 0; |
||
716 | lvd | 354 | } |
355 | else |
||
356 | { |
||
796 | DimkaM | 357 | b0 *= 2; r0 *= 2; g0 *= 2; |
358 | b1 *= 2; r1 *= 2; g1 *= 2; |
||
716 | lvd | 359 | } |
360 | |||
361 | unsigned char br1 = (ink >> 3) & 1; |
||
362 | if (r1) r1 += br1; |
||
363 | if (g1) g1 += br1; |
||
364 | if (b1) b1 += br1; |
||
365 | |||
366 | unsigned char br0 = (paper >> 3) & 1; |
||
367 | if (r0) r0 += br0; |
||
368 | if (g0) g0 += br0; |
||
369 | if (b0) b0 += br0; |
||
370 | |||
371 | // palette index: gg0rr0bb |
||
796 | DimkaM | 372 | t.attrtab[a+0x100] = u8((g1 << 6) + (r1 << 3) + b1); |
373 | t.attrtab[a] = u8((g0 << 6) + (r0 << 3) + b0); |
||
716 | lvd | 374 | } |
375 | else //------------------------------------ all others |
||
376 | { |
||
377 | // palette index: ygrbYGRB |
||
378 | if (flashcolor && (a & 0x80)) |
||
379 | { |
||
380 | t.attrtab[a] = 0; |
||
796 | DimkaM | 381 | t.attrtab[a+0x100] = u8(ink+(paper<<4)); |
716 | lvd | 382 | } |
383 | else |
||
384 | { |
||
796 | DimkaM | 385 | t.attrtab[a] = paper * 0x11; // p[3..0]:p[3..0] (��������) |
386 | t.attrtab[a+0x100] = ink * 0x11; // i[3..0]:i[3..0] (��������) |
||
716 | lvd | 387 | } |
388 | } |
||
389 | } |
||
390 | } |
||
391 | |||
796 | DimkaM | 392 | static void p4bpp_tables() |
716 | lvd | 393 | { |
394 | for (unsigned pass = 0; pass < 2; pass++) { |
||
395 | for (unsigned bt = 0; bt < 0x100; bt++) { |
||
396 | unsigned lf = ((bt >> 3) & 7) + ((bt >> 4) & 8); |
||
397 | unsigned rt = (bt & 7) + ((bt >> 3) & 8); |
||
398 | if (temp.obpp == 8) { |
||
399 | t.p4bpp8[pass][bt] = (t.sctab8[pass][0x0F+0x10*rt] & 0xFFFF) + |
||
400 | (t.sctab8[pass][0x0F+0x10*lf] & 0xFFFF0000); |
||
401 | } else if (temp.obpp == 16) { |
||
796 | DimkaM | 402 | t.p4bpp16[pass][bt * 2 + 0] = t.sctab16[pass][0x03 + 4 * rt]; |
403 | t.p4bpp16[pass][bt * 2 + 1] = t.sctab16[pass][0x03 + 4 * lf]; |
||
716 | lvd | 404 | } else /* if (temp.obpp == 32) */ { |
796 | DimkaM | 405 | t.p4bpp32[pass][bt * 2 + 0] = t.sctab32[pass][0x100 + rt]; |
406 | t.p4bpp32[pass][bt * 2 + 1] = t.sctab32[pass][0x100 + lf]; |
||
716 | lvd | 407 | } |
408 | } |
||
409 | } |
||
410 | } |
||
411 | |||
412 | void atm_zc_tables() // atm,profi screens (use normal zx-flash) |
||
413 | { |
||
414 | for (unsigned pass = 0; pass < 2; pass++) { |
||
415 | for (unsigned at = 0; at < 0x100; at++) { |
||
416 | unsigned pc_attr = colortab[at]; |
||
796 | DimkaM | 417 | if(temp.obpp == 8) |
418 | { |
||
419 | for(unsigned j = 0; j < 4; j++) |
||
420 | { |
||
421 | t.zctab8ad[pass][at * 4 + j] = t.sctab8d[pass][pc_attr * 4 + j]; |
||
422 | } |
||
423 | } |
||
424 | else if(temp.obpp == 16) |
||
425 | { |
||
426 | t.zctab16ad[pass][at] = t.sctab16d[pass][pc_attr]; |
||
427 | t.zctab16ad[pass][at + 0x100] = t.sctab16d[pass][pc_attr + 0x100]; |
||
428 | } |
||
716 | lvd | 429 | else /* if (temp.obpp == 32) */ |
796 | DimkaM | 430 | { |
431 | t.zctab32ad[pass][at] = t.sctab32[pass][pc_attr]; |
||
432 | t.zctab32ad[pass][at + 0x100] = t.sctab32[pass][pc_attr + 0x100]; |
||
433 | } |
||
716 | lvd | 434 | } |
435 | } |
||
436 | |||
437 | // atm palette mapping (port out to palette index) |
||
438 | for (unsigned i = 0; i < 0x100; i++) { |
||
439 | unsigned v = i ^ 0xFF, dst; |
||
440 | if (conf.mem_model == MM_ATM450) |
||
441 | dst = // ATM1: --grbGRB => Gg0Rr0Bb |
||
442 | ((v & 0x20) << 1) | // g |
||
443 | ((v & 0x10) >> 1) | // r |
||
444 | ((v & 0x08) >> 3) | // b |
||
445 | ((v & 0x04) << 5) | // G |
||
446 | ((v & 0x02) << 3) | // R |
||
447 | ((v & 0x01) << 1); // B |
||
448 | else |
||
449 | dst = // ATM2: grbG--RB => Gg0Rr0Bb |
||
450 | ((v & 0x80) >> 1) | // g |
||
451 | ((v & 0x40) >> 3) | // r |
||
452 | ((v & 0x20) >> 5) | // b |
||
453 | ((v & 0x10) << 3) | // G |
||
454 | ((v & 0x02) << 3) | // R |
||
455 | ((v & 0x01) << 1); // B |
||
456 | t.atm_pal_map[i] = dst; |
||
457 | } |
||
458 | } |
||
459 | |||
796 | DimkaM | 460 | static void hires_sc_tables() // atm,profi screens (use zx-attributes & flash -> paper_bright) |
716 | lvd | 461 | { |
462 | for (unsigned pass = 0; pass < 2; pass++) { |
||
463 | for (unsigned at = 0; at < 0x100; at++) { |
||
464 | unsigned pc_attr = (at & 0x80) + (at & 0x38)*2 + (at & 0x40)/8 + (at & 7); |
||
465 | if (temp.obpp == 8) |
||
466 | for (unsigned j = 0; j < 16; j++) |
||
467 | t.zctab8[pass][at*0x10+j] = t.sctab8[pass][pc_attr*0x10+j]; |
||
468 | else if (temp.obpp == 16) |
||
469 | for (unsigned j = 0; j < 4; j++) |
||
470 | t.zctab16[pass][at*4+j] = t.sctab16[pass][pc_attr*4+j]; |
||
471 | else /* if (temp.obpp == 32) */ |
||
472 | for (unsigned j = 0; j < 2; j++) |
||
473 | t.zctab32[pass][at+0x100*j] = t.sctab32[pass][pc_attr+0x100*j]; |
||
474 | } |
||
475 | } |
||
476 | } |
||
477 | |||
796 | DimkaM | 478 | static void calc_noflic_16_32() |
716 | lvd | 479 | { |
480 | unsigned at, pass; |
||
481 | if (temp.obpp == 16) { |
||
482 | for (pass = 0; pass < 2; pass++) { |
||
483 | for (at = 0; at < 2*0x100; at++) |
||
484 | t.sctab16d_nf[pass][at] = (t.sctab16d[pass][at] & temp.shift_mask)/2; |
||
485 | for (at = 0; at < 4*0x100; at++) |
||
486 | t.sctab16_nf[pass][at] = (t.sctab16[pass][at] & temp.shift_mask)/2; |
||
487 | for (at = 0; at < 2*0x100; at++) |
||
488 | t.p4bpp16_nf[pass][at] = (t.p4bpp16[pass][at] & temp.shift_mask)/2; |
||
489 | } |
||
490 | } |
||
491 | if (temp.obpp == 32) { |
||
492 | unsigned shift_mask = 0xFEFEFEFE; |
||
493 | for (pass = 0; pass < 2; pass++) { |
||
494 | for (at = 0; at < 2*0x100; at++) |
||
495 | t.sctab32_nf[pass][at] = (t.sctab32[pass][at] & shift_mask)/2; |
||
496 | for (at = 0; at < 2*0x100; at++) |
||
497 | t.p4bpp32_nf[pass][at] = (t.p4bpp32[pass][at] & shift_mask)/2; |
||
498 | } |
||
499 | } |
||
500 | } |
||
501 | |||
502 | // pal.index => raw video data, shadowed with current scanline pass |
||
796 | DimkaM | 503 | static unsigned raw_data(unsigned index, unsigned pass, unsigned bpp) |
716 | lvd | 504 | { |
505 | if (bpp == 8) |
||
506 | { |
||
507 | if (pass) |
||
508 | { |
||
509 | if (!conf.scanbright) |
||
510 | return 0; |
||
511 | // palette too small to realize noflic/atari with shaded scanlines |
||
512 | if (conf.scanbright < 100 && !conf.noflic && !conf.atariset[0]) |
||
513 | { |
||
514 | if (temp.rflags & RF_PALB) |
||
515 | index = (index & (index << 1) & 0x92) | ((index ^ 0xFF) & (index >> 1) & 0x49); |
||
516 | else |
||
517 | index &= 0x0F; |
||
518 | } |
||
519 | } |
||
796 | DimkaM | 520 | return index * 0x01010101; // 4 ����� (8bit) |
716 | lvd | 521 | } |
522 | |||
523 | unsigned r = pal0[index].peRed, g = pal0[index].peGreen, b = pal0[index].peBlue; |
||
524 | if (pass) |
||
525 | { |
||
526 | r = r * conf.scanbright / 100; |
||
527 | g = g * conf.scanbright / 100; |
||
528 | b = b * conf.scanbright / 100; |
||
529 | } |
||
530 | |||
531 | if (bpp == 32) |
||
796 | DimkaM | 532 | return WORD4(b,g,r,0); // 1 ����� (32bit) |
716 | lvd | 533 | |
534 | // else (bpp == 16) |
||
535 | if (temp.hi15==0) |
||
796 | DimkaM | 536 | return ((b/8) + ((g/4)<<5) + ((r/8)<<11)) * 0x10001; // 2 ����� (16bit) |
716 | lvd | 537 | if (temp.hi15==1) |
796 | DimkaM | 538 | return ((b/8) + ((g/8)<<5) + ((r/8)<<10)) * 0x10001; // 2 ����� (16bit) |
716 | lvd | 539 | if (temp.hi15==2) |
796 | DimkaM | 540 | return getYUY2(r,g,b); // yuyv (32bit) |
716 | lvd | 541 | return 0; |
542 | } |
||
543 | |||
796 | DimkaM | 544 | static unsigned atari_to_raw(unsigned at, unsigned pass) |
716 | lvd | 545 | { |
546 | unsigned c1 = at/0x10, c2 = at & 0x0F; |
||
547 | unsigned raw0 = raw_data(t.attrtab[c1+0x100], pass, temp.obpp); |
||
548 | unsigned raw1 = raw_data(t.attrtab[c2+0x100], pass, temp.obpp); |
||
549 | if (raw0 == raw1) return raw1; |
||
550 | |||
551 | if (temp.obpp == 8) |
||
552 | return (temp.rflags & RF_PALB)? (0x49494949 & ((raw0&raw1)^((raw0^raw1)>>1))) | |
||
553 | (0x92929292 & ((raw0&raw1)|((raw0|raw1)&((raw0&raw1)<<1)))) |
||
554 | : (0x0F0F0F0F & raw0) | (0xF0F0F0F0 & raw1); |
||
555 | |||
556 | return (raw0 & temp.shift_mask)/2 + (raw1 & temp.shift_mask)/2; |
||
557 | } |
||
558 | |||
559 | void pixel_tables() |
||
560 | { |
||
796 | DimkaM | 561 | attr_tables(); |
562 | for(unsigned pass = 0; pass < 2; pass++) |
||
563 | { |
||
564 | for(unsigned at = 0; at < 0x100; at++) |
||
565 | { |
||
566 | unsigned px0 = t.attrtab[at]; // ����� ��������� (������ ������� ���������, ������� 8[idx]->32[xrgb]) |
||
567 | unsigned px1 = t.attrtab[at + 0x100]; // ����� �������� (������ ������� ���������, ������� 8[idx]->32[xrgb]) |
||
716 | lvd | 568 | |
796 | DimkaM | 569 | // 4 ����� (����������, �����������) ��� 8bpp |
570 | // 2 ����� (����������, ��������) ��� 16bpp |
||
571 | // 1 ����� ��� 32bpp |
||
572 | unsigned p0 = raw_data(px0, pass, temp.obpp); // ����� ��������� (������ ��� pc �����������) |
||
573 | unsigned p1 = raw_data(px1, pass, temp.obpp); // ����� �������� (������ ��� pc �����������) |
||
716 | lvd | 574 | |
796 | DimkaM | 575 | // sctab32 required for frame resampler in 16-bit mode, so temp.obpp=16 here |
576 | // ������� ������ 1 ��� |
||
577 | t.sctab32[pass][at] = raw_data(px0, pass, 32); // ����� ��������� (������ ��� pc ����������� xrgb) |
||
578 | t.sctab32[pass][at + 0x100] = raw_data(px1, pass, 32); // ����� �������� (������ ��� pc ����������� xrgb) |
||
716 | lvd | 579 | |
796 | DimkaM | 580 | // 8 bit |
581 | unsigned j; |
||
582 | for(j = 0; j < 0x10; j++) // j - ������� ������ (�������� �/� ��������) 4���� (16 ����������) |
||
583 | { |
||
584 | unsigned mask = (j >> 3) * 0xFF + (j & 0x04)*(0xFF00 / 4) + |
||
585 | (j & 0x02)*(0xFF0000 / 2) + (j & 1) * 0xFF000000; |
||
586 | t.sctab8[pass][j + at * 0x10] = (mask & p1) + (~mask & p0); // ������ ��� pc ����������� 4 ����� |
||
587 | } |
||
588 | for(j = 0; j < 4; j++) // j - ������� ������ (�������� �/� ��������) 2���� (4 ����������) |
||
589 | { |
||
590 | unsigned mask = (j >> 1) * 0xFFFF + (j & 1) * 0xFFFF0000; |
||
591 | t.sctab8d[pass][j + at * 4] = (mask & p1) + (~mask & p0); // ������ ��� pc ����������� 2 ����� � ��������� |
||
592 | } |
||
593 | // ������� ������ (�������� �/� ��������) 1��� (2 ����������) |
||
594 | t.sctab8q[at] = p0; t.sctab8q[at + 0x100] = p1; // ������ ��� pc ����������� 1 ����� � ������������ |
||
716 | lvd | 595 | |
796 | DimkaM | 596 | // 16 bit |
597 | for(j = 0; j < 4; j++) // j - ������� ������ (�������� �/� ��������) 2���� (4 ����������) |
||
598 | { |
||
599 | unsigned mask = (j >> 1) * 0xFFFF + (j & 1) * 0xFFFF0000; |
||
600 | t.sctab16[pass][j + at * 4] = (mask & p1) + (~mask & p0); // ������ ��� pc ����������� 2 ����� |
||
601 | } |
||
602 | // ������� ������ (�������� �/� ��������) 1��� (2 ����������) |
||
603 | t.sctab16d[pass][at] = p0; t.sctab16d[pass][at + 0x100] = p1; // ������ ��� pc ����������� 1 ����� � ��������� |
||
716 | lvd | 604 | |
796 | DimkaM | 605 | unsigned atarimode; |
606 | if(!(temp.rflags & RF_MON) && (atarimode = temp.ataricolors[at])) |
||
607 | { |
||
608 | unsigned rawdata[4], i; |
||
609 | for(i = 0; i < 4; i++) |
||
610 | { |
||
611 | rawdata[i] = atari_to_raw((atarimode >> (8 * i)) & 0xFF, pass); |
||
612 | } |
||
613 | for(i = 0; i < 16; i++) |
||
614 | { |
||
615 | t.sctab8[pass][at * 0x10 + i] = rawdata[i / 4] + 16 * rawdata[i & 3]; |
||
616 | } |
||
617 | for(i = 0; i < 4; i++) |
||
618 | { |
||
619 | t.sctab8d[pass][at * 4 + i] = rawdata[i]; |
||
620 | } |
||
621 | for(i = 0; i < 4; i++) |
||
622 | { |
||
623 | t.sctab16[pass][at * 4 + i] = rawdata[i]; |
||
624 | } |
||
625 | } |
||
626 | } |
||
627 | } |
||
716 | lvd | 628 | |
796 | DimkaM | 629 | p4bpp_tables(); // used for ATM2+ mode0 and Pentagon-4bpp |
716 | lvd | 630 | |
796 | DimkaM | 631 | if(temp.obpp > 8 && conf.noflic) |
632 | { |
||
633 | calc_noflic_16_32(); |
||
634 | } |
||
716 | lvd | 635 | |
796 | DimkaM | 636 | if((temp.rflags & (RF_DRIVER | RF_2X | RF_USEFONT)) == (RF_DRIVER | RF_2X) && // render="double" |
637 | (conf.mem_model == MM_ATM450 || conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3 || conf.mem_model == MM_PROFI)) |
||
638 | { |
||
639 | hires_sc_tables(); |
||
640 | } |
||
716 | lvd | 641 | } |
642 | |||
643 | void video_color_tables() |
||
644 | { |
||
645 | temp.shift_mask = 0xFEFEFEFE; // 32bit, 16bit YUY2 |
||
646 | if (temp.obpp == 16 && temp.hi15==0) temp.shift_mask = 0xF7DEF7DE; |
||
647 | if (temp.obpp == 16 && temp.hi15==1) temp.shift_mask = 0x7BDE7BDE; |
||
648 | |||
649 | create_palette(); |
||
650 | pixel_tables(); |
||
651 | make_colortab(0); |
||
652 | |||
653 | if (temp.rflags & (RF_USEC32 | RF_USE32AS16)) { |
||
654 | for (unsigned at = 0; at < 0x100; at++) { |
||
655 | for (unsigned vl = 0; vl <= 0x10; vl++) { |
||
656 | unsigned br = (at & 0x40) ? 0xFF : 0xBF; |
||
657 | unsigned c1, c2, res; |
||
796 | DimkaM | 658 | c1 = (at & 1) >> 0; c2 = (at & 0x08) >> 3; |
716 | lvd | 659 | unsigned b = (c1*vl + c2*(0x10-vl))*br/0x10; |
796 | DimkaM | 660 | c1 = (at & 2) >> 1; c2 = (at & 0x10) >> 4; |
716 | lvd | 661 | unsigned r = (c1*vl + c2*(0x10-vl))*br/0x10; |
796 | DimkaM | 662 | c1 = (at & 4) >> 2; c2 = (at & 0x20) >> 5; |
716 | lvd | 663 | unsigned g = (c1*vl + c2*(0x10-vl))*br/0x10; |
664 | if (temp.rflags & RF_USE32AS16) { |
||
665 | if (temp.hi15==0) res = (b/8) + ((g/4)<<5) + ((r/8)<<11); |
||
666 | if (temp.hi15==1) res = (b/8) + ((g/8)<<5) + ((r/8)<<10); |
||
667 | if (temp.hi15==2) res = getYUY2(r,g,b); |
||
668 | else res *= 0x10001; // for hi15=0,1 |
||
669 | } else res = WORD4(b,g,r,0); |
||
670 | t.c32tab[at][vl] = res; |
||
671 | } |
||
672 | } |
||
673 | } |
||
674 | setpal(0); |
||
675 | } |
||
676 | |||
677 | void video_timing_tables() |
||
678 | { |
||
679 | if (conf.frame < 2000) |
||
680 | { |
||
681 | conf.frame = 2000; |
||
682 | cpu.SetTpi(conf.frame); |
||
683 | } |
||
684 | if (conf.t_line < 128) conf.t_line = 128; |
||
685 | conf.nopaper &= 1; |
||
686 | atrtab = (comp.pEFF7 & EFF7_HWMC) ? t.atrtab_hwmc : t.atrtab; |
||
687 | |||
688 | // conf.bordersize=2; |
||
689 | // temp.scx = 384, temp.scy = 300; |
||
690 | #define p2cc(p) ((p)/4) // ������� �������� � �������� � ����� ��������� � ������ ��������� (������ ���������� �������� 2 �����, ���� ������ � ���� ���������) |
||
691 | const unsigned width = p2cc(temp.scx); // ������ ������ � ����������� * 2 (�.�. ������������ ������� � �������� �� 1 ����������) |
||
692 | //temp.vidbufsize = temp.scx*temp.scy/4; |
||
693 | |||
694 | // make video table |
||
695 | unsigned mid_lines = 192; // ����� ����� � ����������� ����� ������ (��� �������) |
||
696 | const unsigned buf_mid = 256; // ����� �������� � ����������� ����� ������ (��� �������) |
||
697 | |||
698 | // ������ ������ ������� � �������� (1 ������� = 2 �����) |
||
796 | DimkaM | 699 | temp.b_bottom = temp.b_top = conf.b_top_small; temp.b_left = conf.b_left_small; // border small |
716 | lvd | 700 | if (conf.bordersize==0) temp.b_top = temp.b_left = 0; // border none |
701 | if (conf.bordersize==2) { temp.b_top = conf.b_top_full; temp.b_left = conf.b_left_full; } // border full |
||
702 | |||
703 | // temp.scx - ����� ����� � ������������ �� ����������� |
||
704 | // temp.scy - ����� ����� � ������������ |
||
705 | // 256x192 - border none |
||
706 | // 320x240 - border small |
||
707 | // 384x300 - border full, pentagon: ((36+128+28)*2=384)x(304=64+192+48), scorpion: ((24+128+32)*2=368)x(296=64+192+40))) |
||
708 | temp.b_right = temp.scx - buf_mid - temp.b_left; // ������ ������� ������ ����� ������� � �������� (1 ������� = 1/2 �����) |
||
709 | temp.b_bottom = temp.scy - mid_lines - temp.b_top; // ������ ������� ������ ����� ������� � �������� (1 ������� = 1/2 �����) |
||
710 | |||
796 | DimkaM | 711 | if(conf.nopaper) // ����� nopaper (����� � �������� ������ �����������) |
712 | { |
||
713 | temp.b_bottom += mid_lines; |
||
714 | mid_lines = 0; |
||
715 | } |
||
716 | lvd | 716 | int inx = 0; |
717 | |||
718 | unsigned i; |
||
719 | #define ts(t) (((int)(t) < 0) ? 0 : t) |
||
720 | #define p2t(p) ((p)/2) // ������� �������� � ����� |
||
721 | // conf.paper - ����� ������ �� ������ ������ �� ����������� ����� spectrum ������ |
||
722 | // (�������� ��������� ����� + ��������� ������� ������ + ������ ������ ������� hblank + ����� ������) |
||
723 | // ��� pentagon 128: (16+64)*(32+36+128+28)+32+36 = 17988 ������ |
||
724 | // 16 ����� ��� ������� �������� |
||
725 | // 64 ������ - ������� ������ |
||
726 | // ������ ������ 224 �����: |
||
727 | // 32 ����� hblank |
||
728 | // 36 ������ - ����� ������ |
||
729 | // 128 ������ - ����� ������ |
||
730 | // 28 ������ - ������ ������ |
||
731 | unsigned t = conf.paper - temp.b_top*conf.t_line; // ����� ������ �� ������ �������� ������� (������� hblank + ����� ������ � ������ ������ paper) |
||
732 | const unsigned hblank = conf.t_line - p2t(temp.scx); // ����� ������ � hblank |
||
733 | video[inx++].next_t = ts(t - p2t(temp.b_left)); // ���������� ������ ������� (next_t - ���� ������ ������ ������ �������� �������) |
||
734 | // printf("btop: temp.b_top=%u, conf.b_top_full=%u\n", temp.b_top, conf.b_top_full); |
||
735 | for (i = 0; i < temp.b_top; i++) |
||
736 | { // ������� ������ |
||
737 | video[inx].next_t = ts(t + p2t(buf_mid+temp.b_right)); // ����� ������� ������� (���� ����� ������� ������) |
||
738 | video[inx].screen_ptr = rbuf+width*i; // ��������� �� �� ���� ������� ������ � ������ ��������� |
||
739 | video[inx].nextvmode = 0; // hblank (������� � ����� ������) |
||
740 | // printf("%3u: b=%u, e=%u, o=%u\n", i, video[inx-1].next_t, video[inx].next_t, width*i); |
||
741 | |||
742 | // ������� � ��������� ������ (t - ���� ������ paper ��������� ������ hblank + ����� ������) |
||
743 | inx++; t += conf.t_line; |
||
744 | video[inx++].next_t = ts(t - p2t(temp.b_left)); // ���������� ������ ������� (���� ������ ������ ������� �� ��������� ������) |
||
745 | } |
||
746 | // printf("paper:\n"); |
||
747 | for (i = 0; i < mid_lines; i++) |
||
748 | { // hblank + ����� ������ + ����� + ������ ������ |
||
749 | video[inx].next_t = ts(t); // ����� ������ ������� (���� ������ paper �� ������� ������) |
||
750 | video[inx].screen_ptr = rbuf+width*(i+temp.b_top); // ��������� �� ������ i� ������ ������ ������� � ������ ��������� |
||
751 | video[inx].nextvmode = 2; // ����� ��������������� paper |
||
752 | // printf("%3u: b=%u ", i, video[inx-1].next_t); |
||
753 | |||
754 | inx++; |
||
755 | video[inx].next_t = ts(t + p2t(buf_mid)); // ����� paper (���� ������ ������� ������� �� ������� ������) |
||
756 | video[inx].screen_ptr = rbuf+width*(i+temp.b_top)+p2cc(temp.b_left);// ��������� �� ������ i� ������ paper � ������ ��������� |
||
757 | video[inx].scr_offs = ::t.scrtab[i]; // �������� �� ������ zx ������ (�������) |
||
758 | video[inx].atr_offs = atrtab[i]; // �������� �� ������ ���� ��������� zx ������ |
||
759 | |||
760 | inx++; |
||
761 | video[inx].next_t = ts(t + p2t(buf_mid+temp.b_right)); // ����� ������� ������� (���� ����� ������� ������) |
||
762 | video[inx].screen_ptr = rbuf+width*(i+temp.b_top)+p2cc(buf_mid+temp.b_left); // ��������� �� ������ i� ������ ������� ������� � ������ ��������� |
||
763 | video[inx].nextvmode = 0; // hblank (������� � ����� ������) |
||
764 | |||
765 | // printf("e=%u\n", video[inx].next_t); |
||
766 | // ������� � ��������� ������ (t - ���� ������ paper ��������� ������ hblank + ����� ������) |
||
767 | inx++; t += conf.t_line; |
||
768 | video[inx++].next_t = ts(t - p2t(temp.b_left)); // ���������� ������ ������� (���� ������ ��������� ������) |
||
769 | } |
||
770 | // printf("bbot:\n"); |
||
771 | for (i = 0; i < temp.b_bottom; i++) |
||
772 | { // ������ ������ |
||
773 | video[inx].next_t = ts(t + p2t(buf_mid+temp.b_right)); // ����� ������� ������� (���� ����� ������� ������) |
||
774 | video[inx].screen_ptr = rbuf+width*(i+temp.b_top+mid_lines); // ��������� �� �� ���� i� ������ ������� ������� � ������ ��������� |
||
775 | video[inx].nextvmode = 0; // hblank (������� � ����� ������) |
||
776 | // printf("%3u: b=%u, e=%u\n", i, video[inx-1].next_t, video[inx].next_t); |
||
777 | |||
778 | // ������� � ��������� ������ (t - ���� ������ paper ��������� ������ hblank + ����� ������) |
||
779 | inx++; t += conf.t_line; |
||
780 | video[inx++].next_t = ts(t - p2t(temp.b_left)); // ���������� ������ ������� (���� ������ ��������� ������) |
||
781 | } |
||
782 | video[inx-1].next_t = 0x7FFFFFFF; // ������� ��������� ������ |
||
783 | // exit(0); |
||
784 | |||
785 | temp.evenM1_C0 = conf.even_M1 ? 0xC0 : 0x00; |
||
786 | temp.border_add = conf.border_4T ? 6 : 0; |
||
787 | temp.border_and = conf.border_4T ? 0xFFFFFFFC : 0xFFFFFFFF; |
||
788 | |||
789 | for (i = 0; i < NUM_LEDS; i++) |
||
790 | { |
||
791 | unsigned z = *(&conf.led.ay + i); |
||
792 | int x = (signed short)(z & 0xFFFF); |
||
793 | int y = (signed short)(((z >> 16) & 0x7FFF) + ((z >> 15) & 0x8000)); |
||
794 | if (x < 0) x += width*8; |
||
795 | if (y < 0) y += temp.scy; |
||
796 | DimkaM | 796 | *(&temp.led.ay+i) = (z & 0x80000000) ? rbuf + ((x>>2)&0xFE) + unsigned(y)*width : nullptr; |
716 | lvd | 797 | } |
798 | |||
799 | if (temp.rflags & RF_USEFONT) |
||
800 | create_font_tables(); |
||
801 | |||
802 | needclr = 2; |
||
803 | } |
||
804 | |||
805 | void set_video() |
||
806 | { |
||
807 | // printf("%s\n", __FUNCTION__); |
||
808 | set_vidmode(); |
||
809 | video_color_tables(); |
||
810 | } |
||
811 | |||
812 | void apply_video() |
||
813 | { |
||
814 | // printf("%s\n", __FUNCTION__); |
||
815 | load_ula_preset(); |
||
816 | |||
817 | if(conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3 || conf.mem_model == MM_ATM450 || conf.mem_model == MM_PROFI) |
||
818 | { |
||
819 | conf.render = 1; // ��� ������� � ������� 640x200 �������������� ������ redner = double (640x480) |
||
820 | } |
||
821 | |||
822 | temp.rflags = renders[conf.render].flags; |
||
823 | if (conf.use_comp_pal && (conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3 || conf.mem_model == MM_ATM450 || conf.mem_model == MM_PROFI)) |
||
824 | { |
||
825 | temp.rflags |= RF_COMPPAL | RF_PALB; |
||
826 | // disable palette noflic, only if it is really used |
||
827 | if (temp.obpp == 8 && (temp.rflags & (RF_DRIVER | RF_USEFONT | RF_8BPCH)) == RF_DRIVER) |
||
828 | conf.noflic = 0; |
||
829 | } |
||
830 | |||
796 | DimkaM | 831 | if(conf.ula_plus/* && comp.ula_plus_en*/) |
832 | { |
||
833 | temp.rflags |= RF_COMPPAL | RF_PALB; |
||
834 | } |
||
835 | |||
716 | lvd | 836 | if (renders[conf.render].func == render_rsm) |
837 | conf.flip = 1; // todo: revert back after returning from frame resampler //Alone Coder |
||
838 | |||
839 | if (renders[conf.render].func == render_advmame) |
||
840 | { |
||
841 | if (conf.videoscale == 2) |
||
842 | temp.rflags |= RF_2X; |
||
843 | if (conf.videoscale == 3) |
||
844 | temp.rflags |= RF_3X; |
||
845 | if (conf.videoscale == 4) |
||
846 | temp.rflags |= RF_4X; |
||
847 | } //Alone Coder |
||
848 | |||
849 | set_video(); |
||
850 | calc_rsm_tables(); |
||
851 | video_timing_tables(); |
||
852 | } |
||
853 | |||
854 | __inline unsigned char *raypointer() |
||
855 | { |
||
856 | if (prev_t > conf.frame) |
||
857 | return rbuf + rb2_offs; |
||
858 | if (!vmode) |
||
859 | return vcurr[1].screen_ptr; |
||
860 | unsigned offs = (prev_t - vcurr[-1].next_t) / 4; |
||
861 | return vcurr->screen_ptr + (offs+1) * 2; |
||
862 | } |
||
863 | |||
864 | __inline void clear_until_ray() |
||
865 | { |
||
866 | unsigned char *dst = raypointer(); |
||
796 | DimkaM | 867 | while(dst < rbuf + rb2_offs) |
868 | { |
||
869 | *dst++ = 0; |
||
870 | *dst++ = 0x55; |
||
871 | } |
||
716 | lvd | 872 | } |
873 | |||
874 | void paint_scr(char alt) // alt=0/1 - main/alt screen, alt=2 - ray-painted |
||
875 | { |
||
796 | DimkaM | 876 | if(alt == 2) |
877 | { |
||
878 | update_screen(); |
||
879 | clear_until_ray(); |
||
880 | } |
||
881 | else |
||
882 | { |
||
883 | if(alt) |
||
884 | { |
||
885 | comp.p7FFD ^= 8; |
||
886 | set_banks(); |
||
887 | } |
||
888 | draw_screen(); |
||
889 | if(alt) |
||
890 | { |
||
891 | comp.p7FFD ^= 8; |
||
892 | set_banks(); |
||
893 | } |
||
894 | } |
||
716 | lvd | 895 | } |
896 | |||
897 | // ���������� ��� ������ � �����������/(����� FE/7FFD) ������ �������� |
||
898 | // ���������� ��������� �������/������ � ������������� ����� � �������������� pc ��������� |
||
899 | void update_screen() |
||
900 | { |
||
901 | unsigned last_t = (cpu.t + temp.border_add) & temp.border_and; |
||
796 | DimkaM | 902 | unsigned t = prev_t; // ����������� ��������� �� ���������� ������������� ����� prev_t �� �������� ������������ ����� last_t |
716 | lvd | 903 | // printf("upd_scr: t=%u, lt=%u, vm=%u\n", t, last_t, vmode); |
904 | if (t >= last_t) // ��������� ����� ������ (hblank ���� ��������� ������ �������� �������) |
||
905 | return; |
||
906 | |||
907 | unsigned char b = comp.border_attr; |
||
908 | b |= (b<<4); // �������� ������� ����������� � ������� pc ��������� ink=paper |
||
909 | |||
796 | DimkaM | 910 | if(vmode == 1) |
911 | { |
||
912 | goto mode1; // border |
||
913 | } |
||
716 | lvd | 914 | |
796 | DimkaM | 915 | if(vmode == 2) // screen |
916 | { |
||
716 | lvd | 917 | goto mode2; |
796 | DimkaM | 918 | } |
716 | lvd | 919 | |
920 | mode0: // not visible |
||
921 | { |
||
922 | vmode = 1; |
||
923 | t = vcurr->next_t; // ���� ������ ������ |
||
924 | vcurr++; // ������� � ����� ������ |
||
925 | if (t >= last_t) |
||
926 | { |
||
927 | done: |
||
796 | DimkaM | 928 | prev_t = t; // ��������� ������������ ���� |
716 | lvd | 929 | return; |
930 | } |
||
931 | } |
||
932 | mode1: // border |
||
933 | { |
||
934 | unsigned offs = (t - vcurr[-1].next_t); // �������� � ������ �� ������ ������ (1 ���� = 2 �������) |
||
796 | DimkaM | 935 | unsigned char *ptr = vcurr->screen_ptr + offs/2; // ��������� �� ����� ����� � ������������� ������ (��������� ������ 8pix:attr) |
716 | lvd | 936 | // u8 *pp =ptr; |
937 | ptr = (unsigned char*)(ULONG_PTR(ptr) & ~ULONG_PTR(1)); // ��������� �� ������� ������ |
||
938 | if(offs & 3) |
||
796 | DimkaM | 939 | { // ����� ����� ������� ��������� �� �� ������� ���������� (��� ����� ������� ������ ������ ����������, ����������� ����� ink/paper) |
940 | u8 old_b = (ptr[1] & 0x0F); |
||
941 | if(old_b ^ (b & 0xF)) // ���� ������� ��������� �� ��������� � ���������� |
||
942 | { |
||
943 | u8 mask = u8((unsigned)0xFF00 >> ((offs & 3) * 2)); // ����� �������� (��� 1 - ������������ ���� ink, ��� 0 - paper) |
||
944 | *ptr = mask; |
||
945 | ptr++; |
||
946 | t += 4 - (offs & 3); |
||
947 | *ptr = old_b | (b & 0xF0); // �������� (ink - ������ ���� �������, paper - ������� ���� �������) |
||
948 | ptr++; |
||
949 | } |
||
716 | lvd | 950 | } |
951 | unsigned end = min(vcurr->next_t, last_t); |
||
952 | // printf("upd_scr_m1: o=%uT, p=%u, t=%uT, end=%uT\n", offs, pp - rbuf, t, end); |
||
953 | for (; t < end; t+=4) // ��������� �������� �� ����������� (�� 8 �����) |
||
954 | { |
||
955 | *ptr++ = 0; // ������� �� ������������ |
||
956 | *ptr++ = b; // �������� |
||
957 | } |
||
958 | t = end; |
||
959 | if (t == vcurr->next_t) |
||
960 | { // ������ �����������, ������� � ��������� ����� |
||
961 | vmode = vcurr->nextvmode; |
||
962 | vcurr++; |
||
963 | } |
||
964 | if (t == last_t) // ��������� ���������, ����� |
||
965 | goto done; |
||
966 | |||
967 | if (!vmode) // ������ ��������� ������ |
||
968 | goto mode0; |
||
969 | } |
||
970 | mode2: // screen |
||
971 | { |
||
972 | unsigned offs = (t - vcurr[-1].next_t)/4; // �������� � ����������� �� ������ ������ (1 ���������� = 4 ����� = 8 ��������) |
||
973 | unsigned char *scr = temp.base + vcurr->scr_offs + offs; // spectrum ������� |
||
974 | unsigned char *atr = temp.base + vcurr->atr_offs + offs; // spectrum �������� |
||
975 | unsigned char *ptr = vcurr->screen_ptr + offs*2; // ��������� ������ 8pix:attr |
||
976 | unsigned end = min(last_t, vcurr->next_t); |
||
977 | for (int i = 0; t < end; t += 4, i++) |
||
978 | { |
||
979 | ptr[2*i] = scr[i]; // ����������� spectrum �������� |
||
980 | ptr[2*i+1] = colortab[atr[i]]; // ��������������� spectrum ��������� � pc �������� |
||
981 | } |
||
982 | t = end; |
||
983 | if (t == vcurr->next_t) |
||
984 | { // ����������� ����� ������ �����������, ��������� ������� ������� |
||
985 | vmode = 1; // border |
||
986 | vcurr++; |
||
987 | } |
||
988 | if (t == last_t) // ��������� ���������, ����� |
||
989 | goto done; |
||
990 | goto mode1; // ��������� ������� ������� |
||
991 | } |
||
992 | } |
||
993 | |||
994 | void init_frame() |
||
995 | { |
||
996 | // recreate colors with flash attribute |
||
997 | unsigned char frame = (unsigned char)comp.frame_counter; |
||
998 | if (!(frame & 15) /* && !conf.flashcolor */ ) |
||
999 | make_colortab(frame & 16); |
||
1000 | |||
796 | DimkaM | 1001 | prev_t = -1U; // block MCR |
1002 | temp.base_2 = nullptr; // block paper trace |
||
716 | lvd | 1003 | |
1004 | if (temp.vidblock) |
||
1005 | return; |
||
1006 | |||
1007 | /* [vv] ��������, �.�. ���� ��� ������������ ��� DDp scroll |
||
1008 | // AlCo384 - no border/paper rendering |
||
1009 | if (comp.pEFF7 & EFF7_384) |
||
1010 | return; |
||
1011 | */ |
||
1012 | // GIGASCREEN - no paper rendering |
||
1013 | // if (comp.pEFF7 & EFF7_GIGASCREEN) goto allow_border; //Alone Coder |
||
1014 | |||
1015 | // disable multicolors, border still works |
||
1016 | if ((temp.rflags & RF_BORDER) || // chunk/etc filter |
||
1017 | (conf.mem_model == MM_PROFI && (comp.pDFFD & 0x80)) || // profi hires screen |
||
1018 | ((conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3)&& (comp.pFF77 & 7) != 3) || // ATM-2 hires screen |
||
1019 | (conf.mem_model == MM_ATM450 && (comp.aFE & 0x60) != 0x60)) // ATM-1 hires screen |
||
1020 | { |
||
1021 | if ((conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3)) |
||
1022 | { |
||
1023 | // ATM2, ���� �� ����������� ������������ |
||
1024 | AtmVideoCtrl.PrepareFrameATM2(comp.pFF77 & 7); |
||
1025 | } |
||
1026 | |||
1027 | if (conf.mem_model == MM_ATM450) |
||
1028 | { |
||
1029 | // ATM1, ���� �� ����������� ������������ |
||
1030 | AtmVideoCtrl.PrepareFrameATM1( (comp.aFE >> 5) & 3 ); |
||
1031 | |||
1032 | } |
||
1033 | |||
1034 | // if border update disabled, dont show anything on zx-screen |
||
1035 | if (!conf.updateb) |
||
1036 | return; |
||
1037 | } |
||
1038 | |||
1039 | // paper + border |
||
1040 | temp.base_2 = temp.base; |
||
1041 | //allow_border: |
||
1042 | prev_t = vmode = 0; |
||
1043 | vcurr = video; |
||
1044 | } |
||
1045 | |||
1046 | void flush_frame() |
||
1047 | { |
||
1048 | if (temp.vidblock) |
||
1049 | return; |
||
796 | DimkaM | 1050 | if (prev_t != -1U) |
716 | lvd | 1051 | { // MCR on |
1052 | if (prev_t) |
||
1053 | { // paint until end of frame |
||
1054 | // paint until screen bottom, even if n_lines*t_line < cpu.t (=t_frame) |
||
1055 | unsigned t = cpu.t; |
||
1056 | cpu.t = 0x7FFF0000; |
||
1057 | update_screen(); |
||
1058 | cpu.t = t; |
||
1059 | // if (comp.pEFF7 & EFF7_GIGASCREEN) draw_gigascreen_no_border(); //Alone Coder |
||
1060 | } |
||
1061 | else |
||
1062 | { // MCR on, but no screen updates in last frame - use fast painter |
||
1063 | if (temp.base_2 /*|| (comp.pEFF7 & EFF7_GIGASCREEN)*/ /*Alone Coder*/) |
||
1064 | draw_screen(); |
||
1065 | else |
||
1066 | draw_border(); |
||
1067 | } |
||
1068 | return; |
||
1069 | } |
||
1070 | if (comp.pEFF7 & EFF7_384) |
||
1071 | draw_alco(); |
||
1072 | } |
||
1073 | |||
796 | DimkaM | 1074 | // spectrum colors -> palette indexes (RF_PALB - gggrrrbb format) |
1075 | static const u8 comp_pal[16] = |
||
1076 | { |
||
1077 | // normal bright g r b g r b |
||
1078 | 0x00, // black 000|000|00 00|00|00 |
||
1079 | 0x02, // blue 000|000|10 00|00|10 |
||
1080 | 0x10, // red 000|100|00 00|10|00 |
||
1081 | 0x12, // magenta 000|100|10 00|10|10 |
||
1082 | 0x80, // green 100|000|00 10|00|00 |
||
1083 | 0x82, // cyan 100|000|10 10|00|10 |
||
1084 | 0x90, // yellow 100|100|00 10|10|00 |
||
1085 | 0x92, // white 100|100|10 10|10|10 |
||
1086 | |||
1087 | // high bright g r b g r b |
||
1088 | 0x00, // black 000|000|00 00|00|00 |
||
1089 | 0x03, // blue 000|000|11 00|00|11 |
||
1090 | 0x1C, // red 000|111|00 00|11|00 |
||
1091 | 0x1F, // magenta 000|111|11 00|11|11 |
||
1092 | 0xE0, // green 111|000|00 11|00|00 |
||
1093 | 0xE3, // cyan 111|000|11 11|00|11 |
||
1094 | 0xFC, // yellow 111|111|00 11|11|00 |
||
1095 | 0xFF // white 111|111|11 11|11|11 |
||
1096 | }; |
||
1097 | |||
716 | lvd | 1098 | void load_spec_colors() |
1099 | { |
||
796 | DimkaM | 1100 | for(unsigned flash = 0; flash < 2; flash++) |
1101 | { |
||
1102 | for(unsigned bright = 0; bright < 2; bright++) |
||
1103 | { |
||
1104 | unsigned PalNo = ((flash << 1) | bright) << 4; |
||
1105 | memcpy(comp.comp_pal + (PalNo | (0 << 3)), comp_pal + (bright << 3), sizeof(comp_pal) / 2); // ink |
||
1106 | memcpy(comp.comp_pal + (PalNo | (1 << 3)), comp_pal + (bright << 3), sizeof(comp_pal) / 2); // paper |
||
1107 | } |
||
1108 | } |
||
1109 | temp.comp_pal_changed = 1; |
||
716 | lvd | 1110 | } |