|
|
1.1 root 1: /*
2: Hatari - videl.c
3:
4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
6:
7: Falcon Videl emulation. The Videl is the graphics shifter chip of the Falcon.
8: It supports free programmable resolutions with 1, 2, 4, 8 or 16 bits per
9: pixel.
10:
11: This file originally came from the Aranym project and has been heavily
12: modified to work for Hatari (but the kudos for the great Videl emulation
13: code goes to the people from the Aranym project of course).
14: */
1.1.1.2 ! root 15: const char VIDEL_rcsid[] = "Hatari $Id: videl.c,v 1.20 2008/11/16 10:19:40 thothy Exp $";
1.1 root 16:
17: #include "main.h"
18: #include "configuration.h"
19: #include "ioMem.h"
20: #include "hostscreen.h"
21: #include "screen.h"
22: #include "stMemory.h"
23: #include "video.h"
24: #include "videl.h"
25: #include <SDL_endian.h>
26:
27:
28: #define handleRead(a) IoMem_ReadByte(a)
29: #define handleReadW(a) IoMem_ReadWord(a)
30: #define Atari2HostAddr(a) (&STRam[a])
31:
32: #define VIDEL_DEBUG 0
33:
34: #if VIDEL_DEBUG
35: #define Dprintf(a) printf a
36: #else
37: #define Dprintf(a)
38: #endif
39:
40: #define HW 0xff8200
41: #define VIDEL_COLOR_REGS_BEGIN 0xff9800
42: #define VIDEL_COLOR_REGS_END 0xffa200
43:
44:
45: static int width, height, bpp, since_last_change;
1.1.1.2 ! root 46: static bool hostColorsSync;
1.1 root 47:
48: /* Autozoom */
49: static int zoomwidth, prev_scrwidth;
50: static int zoomheight, prev_scrheight;
51: static int *zoomxtable;
52: static int *zoomytable;
53:
54: static void VIDEL_renderScreenNoZoom(void);
55: static void VIDEL_renderScreenZoom(void);
56:
57:
58: // Called upon startup and when CPU encounters a RESET instruction.
59: void VIDEL_reset(void)
60: {
61: since_last_change = 0;
62:
63: hostColorsSync = FALSE;
64:
65: /* Autozoom */
66: zoomwidth=prev_scrwidth=0;
67: zoomheight=prev_scrheight=0;
68: zoomxtable=NULL;
69: zoomytable=NULL;
70:
71: // default resolution to boot with
72: width = 640;
73: height = 480;
74: HostScreen_setWindowSize( width, height, 8 );
75: }
76:
77: // monitor write access to Falcon and ST/E color palette registers
78: void VIDEL_ColorRegsWrite(void)
79: {
80: hostColorsSync = FALSE;
81: }
82:
83: void VIDEL_ShiftModeWriteWord(void)
84: {
85: Dprintf(("VIDEL f_shift: %06x = 0x%x\n", IoAccessBaseAddress, handleReadW(HW+0x66)));
86: bUseSTShifter = FALSE;
87: }
88:
89: static long VIDEL_getVideoramAddress(void)
90: {
91: return (handleRead(HW + 1) << 16) | (handleRead(HW + 3) << 8) | handleRead(HW + 0x0d);
92: }
93:
94: static int VIDEL_getScreenBpp(void)
95: {
96: int f_shift = handleReadW(HW + 0x66);
97: int st_shift = handleRead(HW + 0x60);
98: /* to get bpp, we must examine f_shift and st_shift.
99: * f_shift is valid if any of bits no. 10, 8 or 4
100: * is set. Priority in f_shift is: 10 ">" 8 ">" 4, i.e.
101: * if bit 10 set then bit 8 and bit 4 don't care...
102: * If all these bits are 0 and ST shifter is written
103: * after Falcon one, get display depth from st_shift
104: * (as for ST and STE)
105: */
106: int bits_per_pixel;
107: if (f_shift & 0x400) /* Falcon: 2 colors */
108: bits_per_pixel = 1;
109: else if (f_shift & 0x100) /* Falcon: hicolor */
110: bits_per_pixel = 16;
111: else if (f_shift & 0x010) /* Falcon: 8 bitplanes */
112: bits_per_pixel = 8;
113: else if (!bUseSTShifter) /* Falcon: 4 bitplanes */
114: bits_per_pixel = 4;
115: else if (st_shift == 0)
116: bits_per_pixel = 4;
117: else if (st_shift == 0x01)
118: bits_per_pixel = 2;
119: else /* if (st_shift == 0x02) */
120: bits_per_pixel = 1;
121:
122: // Dprintf(("Videl works in %d bpp, f_shift=%04x, st_shift=%d", bits_per_pixel, f_shift, st_shift));
123:
124: return bits_per_pixel;
125: }
126:
127: static int VIDEL_getScreenWidth(void)
128: {
129: return handleReadW(HW + 0x10) * 16 / VIDEL_getScreenBpp();
130: }
131:
132: static int VIDEL_getScreenHeight(void)
133: {
134: int vdb = handleReadW(HW + 0xa8);
135: int vde = handleReadW(HW + 0xaa);
136: int vmode = handleReadW(HW + 0xc2);
137:
138: /* visible y resolution:
139: * Graphics display starts at line VDB and ends at line
140: * VDE. If interlace mode off unit of VC-registers is
141: * half lines, else lines.
142: */
143: int yres = vde - vdb;
144: if (!(vmode & 0x02)) // interlace
145: yres >>= 1;
146: if (vmode & 0x01) // double
147: yres >>= 1;
148:
149: return yres;
150: }
151:
152:
153: /** map the correct colortable into the correct pixel format
154: */
155: static void VIDEL_updateColors(void)
156: {
157: //Dprintf(("ColorUpdate in progress\n"));
158:
159: int i, r, g, b, colors = 1 << bpp;
160:
161: #define F_COLORS(i) handleRead(VIDEL_COLOR_REGS_BEGIN + (i))
162: #define STE_COLORS(i) handleRead(0xff8240 + (i))
163:
164: if (!bUseSTShifter) {
165: for (i = 0; i < colors; i++) {
166: int offset = i << 2;
167: r = F_COLORS(offset) & 0xfc;
168: r |= r>>6;
169: g = F_COLORS(offset + 1) & 0xfc;
170: g |= g>>6;
171: b = F_COLORS(offset + 3) & 0xfc;
172: b |= b>>6;
173: HostScreen_setPaletteColor(i, r,g,b);
174: }
175: HostScreen_updatePalette(colors);
176: } else {
177: for (i = 0; i < colors; i++) {
178: int offset = i << 1;
179: r = STE_COLORS(offset) & 0x0f;
180: r = ((r & 7)<<1)|(r>>3);
181: r |= r<<4;
182: g = (STE_COLORS(offset + 1)>>4) & 0x0f;
183: g = ((g & 7)<<1)|(g>>3);
184: g |= g<<4;
185: b = STE_COLORS(offset + 1) & 0x0f;
186: b = ((b & 7)<<1)|(b>>3);
187: b |= b<<4;
188: HostScreen_setPaletteColor(i, r,g,b);
189: }
190: HostScreen_updatePalette(colors);
191: }
192:
193: hostColorsSync = TRUE;
194: }
195:
196:
197: void VIDEL_ZoomModeChanged(void)
198: {
199: /* User selected another zoom mode, so set a new screen resolution now */
200: HostScreen_setWindowSize(width, height, bpp >= 8 ? bpp : 8);
201: }
202:
203:
1.1.1.2 ! root 204: bool VIDEL_renderScreen(void)
1.1 root 205: {
206: int vw = VIDEL_getScreenWidth();
207: int vh = VIDEL_getScreenHeight();
208: int vbpp = VIDEL_getScreenBpp();
209:
210: if (since_last_change > 2) {
211: if (vw > 0 && vw != width) {
212: Dprintf(("CH width %d\n", width));
213: width = vw;
214: since_last_change = 0;
215: }
216: if (vh > 0 && vh != height) {
217: Dprintf(("CH height %d\n", width));
218: height = vh;
219: since_last_change = 0;
220: }
221: if (vbpp != bpp) {
222: Dprintf(("CH bpp %d\n", vbpp));
223: bpp = vbpp;
224: since_last_change = 0;
225: }
226: }
227: if (since_last_change == 3) {
228: HostScreen_setWindowSize( width, height, bpp >= 8 ? bpp : 8 );
229: }
230: if (since_last_change < 4) {
231: since_last_change++;
1.1.1.2 ! root 232: return false;
1.1 root 233: }
234:
235: if (!HostScreen_renderBegin())
1.1.1.2 ! root 236: return false;
1.1 root 237:
238: if (ConfigureParams.Screen.bZoomLowRes) {
239: VIDEL_renderScreenZoom();
240: } else {
241: VIDEL_renderScreenNoZoom();
242: }
243:
244: HostScreen_renderEnd();
245:
246: HostScreen_update1( FALSE );
1.1.1.2 ! root 247:
! 248: return true;
1.1 root 249: }
250:
251:
252: static void VIDEL_renderScreenNoZoom(void)
253: {
254: int vw = VIDEL_getScreenWidth();
255: int vh = VIDEL_getScreenHeight();
256:
257: int lineoffset = handleReadW(HW + 0x0e) & 0x01ff; // 9 bits
258: int linewidth = handleReadW(HW + 0x10) & 0x03ff; // 10 bits
259: /*
260: I think this implementation is naive:
261: indeed, I suspect that we should instead skip lineoffset
262: words each time we have read "more" than linewidth words
263: (possibly "more" because of the number of bit planes).
264: Moreover, the 1 bit plane mode is particular;
265: while doing some experiments on my Falcon, it seems to
266: behave like the 4 bit planes mode.
267: At last, we have also to take into account the 4 bits register
268: located at the word $ffff8264 (bit offset). This register makes
269: the semantics of the lineoffset register change a little.
270: int bitoffset = handleReadW(HW + 0x64) & 0x000f;
271: The meaning of this register in True Color mode is not clear
272: for me at the moment (and my experiments on the Falcon don't help
273: me).
274: */
275: int nextline = linewidth + lineoffset;
276:
277: if (bpp < 16 && !hostColorsSync) {
278: VIDEL_updateColors();
279: }
280:
281: VIDEL_ConvertScreenNoZoom(vw, vh, bpp, nextline);
282: }
283:
284:
285: void VIDEL_ConvertScreenNoZoom(int vw, int vh, int vbpp, int nextline)
286: {
287: int scrpitch = HostScreen_getPitch();
288:
289: long atariVideoRAM = VIDEL_getVideoramAddress();
290:
1.1.1.2 ! root 291: Uint16 *fvram = (Uint16 *) Atari2HostAddr(atariVideoRAM);
! 292: Uint8 *hvram = HostScreen_getVideoramAddress();
1.1 root 293:
294: int hscrolloffset = (handleRead(HW + 0x65) & 0x0f);
295:
296: /* Clip to SDL_Surface dimensions */
297: int scrwidth = HostScreen_getWidth();
298: int scrheight = HostScreen_getHeight();
299: int vw_clip = vw;
300: int vh_clip = vh;
301: if (vw>scrwidth) vw_clip = scrwidth;
302: if (vh>scrheight) vh_clip = scrheight;
303:
304: /* Horizontal scroll register set? */
305: if (hscrolloffset) {
306: /* Yes, so we need to adjust offset to next line: */
307: nextline += vbpp;
308: }
309:
310: /* Center screen */
311: hvram += ((scrheight-vh_clip)>>1)*scrpitch;
312: hvram += ((scrwidth-vw_clip)>>1)*HostScreen_getBpp();
313:
314: /* Render */
315: if (vbpp < 16) {
316: /* Bitplanes modes */
317:
318: // The SDL colors blitting...
1.1.1.2 ! root 319: Uint8 color[16];
1.1 root 320:
321: // FIXME: The byte swap could be done here by enrolling the loop into 2 each by 8 pixels
322: switch ( HostScreen_getBpp() ) {
323: case 1:
324: {
1.1.1.2 ! root 325: Uint16 *fvram_line = fvram;
! 326: Uint8 *hvram_line = hvram;
1.1 root 327: int h;
328:
329: for (h = 0; h < vh_clip; h++) {
1.1.1.2 ! root 330: Uint16 *fvram_column = fvram_line;
! 331: Uint8 *hvram_column = hvram_line;
1.1 root 332: int w;
333:
334: /* First 16 pixels: */
335: HostScreen_bitplaneToChunky(fvram_column, vbpp, color);
336: memcpy(hvram_column, color+hscrolloffset, 16-hscrolloffset);
337: hvram_column += 16-hscrolloffset;
338: fvram_column += vbpp;
339: /* Now the main part of the line: */
340: for (w = 1; w < (vw_clip+15)>>4; w++) {
341: HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
342: memcpy(hvram_column, color, 16);
343: hvram_column += 16;
344: fvram_column += vbpp;
345: }
346: /* Last pixels of the line for fine scrolling: */
347: if (hscrolloffset) {
348: HostScreen_bitplaneToChunky(fvram_column, vbpp, color);
349: memcpy(hvram_column, color, hscrolloffset);
350: }
351:
352: hvram_line += scrpitch;
353: fvram_line += nextline;
354: }
355: }
356: break;
357: case 2:
358: {
1.1.1.2 ! root 359: Uint16 *fvram_line = fvram;
! 360: Uint16 *hvram_line = (Uint16 *)hvram;
1.1 root 361: int h;
362:
363: for (h = 0; h < vh_clip; h++) {
1.1.1.2 ! root 364: Uint16 *fvram_column = fvram_line;
! 365: Uint16 *hvram_column = hvram_line;
1.1 root 366: int w;
367:
368: for (w = 0; w < (vw_clip+15)>>4; w++) {
369: int j;
370: HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
371:
372: for (j=0; j<16; j++) {
373: *hvram_column++ = HostScreen_getPaletteColor( color[j] );
374: }
375:
376: fvram_column += vbpp;
377: }
378:
379: hvram_line += scrpitch>>1;
380: fvram_line += nextline;
381: }
382: }
383: break;
384: case 3:
385: {
1.1.1.2 ! root 386: Uint16 *fvram_line = fvram;
! 387: Uint8 *hvram_line = hvram;
1.1 root 388: int h;
389:
390: for (h = 0; h < vh_clip; h++) {
1.1.1.2 ! root 391: Uint16 *fvram_column = fvram_line;
! 392: Uint8 *hvram_column = hvram_line;
1.1 root 393: int w;
394:
395: for (w = 0; w < (vw_clip+15)>>4; w++) {
396: int j;
397: HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
398:
399: for (j=0; j<16; j++) {
1.1.1.2 ! root 400: Uint32 tmpColor = HostScreen_getPaletteColor( color[j] );
1.1 root 401: putBpp24Pixel( hvram_column, tmpColor );
402: hvram_column += 3;
403: }
404:
405: fvram_column += vbpp;
406: }
407:
408: hvram_line += scrpitch;
409: fvram_line += nextline;
410: }
411: }
412: break;
413: case 4:
414: {
1.1.1.2 ! root 415: Uint16 *fvram_line = fvram;
! 416: Uint32 *hvram_line = (Uint32 *)hvram;
1.1 root 417: int h;
418:
419: for (h = 0; h < vh_clip; h++) {
1.1.1.2 ! root 420: Uint16 *fvram_column = fvram_line;
! 421: Uint32 *hvram_column = hvram_line;
1.1 root 422: int w;
423:
424: for (w = 0; w < (vw_clip+15)>>4; w++) {
425: int j;
426: HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
427:
428: for (j=0; j<16; j++) {
429: *hvram_column++ = HostScreen_getPaletteColor( color[j] );
430: }
431:
432: fvram_column += vbpp;
433: }
434:
435: hvram_line += scrpitch>>2;
436: fvram_line += nextline;
437: }
438: }
439: break;
440: }
441:
442: } else {
443:
444: // Falcon TC (High Color)
445: switch ( HostScreen_getBpp() ) {
446: case 1:
447: {
448: /* FIXME: when Videl switches to 16bpp, set the palette to 3:3:2 */
1.1.1.2 ! root 449: Uint16 *fvram_line = fvram;
! 450: Uint8 *hvram_line = hvram;
1.1 root 451: int h;
452:
453: for (h = 0; h < vh_clip; h++) {
1.1.1.2 ! root 454: Uint16 *fvram_column = fvram_line;
! 455: Uint8 *hvram_column = hvram_line;
1.1 root 456: int w, tmp;
457:
458: for (w = 0; w < vw_clip; w++) {
459:
460: tmp = SDL_SwapBE16(*fvram_column);
461:
462: *hvram_column = ((tmp>>13) & 7) << 5;
463: *hvram_column |= ((tmp>>8) & 7) << 2;
464: *hvram_column |= ((tmp>>2) & 3);
465:
466: hvram_column++;
467: fvram_column++;
468: }
469:
470: hvram_line += scrpitch;
471: fvram_line += nextline;
472: }
473: }
474: break;
475: case 2:
476: {
1.1.1.2 ! root 477: Uint16 *fvram_line = fvram;
! 478: Uint16 *hvram_line = (Uint16 *)hvram;
1.1 root 479: int h;
480:
481: for (h = 0; h < vh_clip; h++) {
482: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
483: //FIXME: here might be a runtime little/big video endian switch like:
484: // if ( /* videocard memory in Motorola endian format */ false)
485: memcpy(hvram_line, fvram_line, vw_clip<<1);
486: #else
487: int w;
1.1.1.2 ! root 488: Uint16 *fvram_column = fvram_line;
! 489: Uint16 *hvram_column = hvram_line;
1.1 root 490:
491: for (w = 0; w < vw_clip; w++) {
492: // byteswap with SDL asm macros
493: *hvram_column++ = SDL_SwapBE16(*fvram_column++);
494: }
495: #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
496:
497: hvram_line += scrpitch>>1;
498: fvram_line += nextline;
499: }
500: }
501: break;
502: case 3:
503: {
1.1.1.2 ! root 504: Uint16 *fvram_line = fvram;
! 505: Uint8 *hvram_line = hvram;
1.1 root 506: int h;
507:
508: for (h = 0; h < vh_clip; h++) {
1.1.1.2 ! root 509: Uint16 *fvram_column = fvram_line;
! 510: Uint8 *hvram_column = hvram_line;
1.1 root 511: int w;
512:
513: for (w = 0; w < vw_clip; w++) {
514: int data = *fvram_column++;
515:
1.1.1.2 ! root 516: Uint32 tmpColor =
1.1 root 517: HostScreen_getColor(
1.1.1.2 ! root 518: (Uint8) (data & 0xf8),
! 519: (Uint8) ( ((data & 0x07) << 5) |
1.1 root 520: ((data >> 11) & 0x3c)),
1.1.1.2 ! root 521: (Uint8) ((data >> 5) & 0xf8));
1.1 root 522:
523: putBpp24Pixel( hvram_column, tmpColor );
524:
525: hvram_column += 3;
526: }
527:
528: hvram_line += scrpitch;
529: fvram_line += nextline;
530: }
531: }
532: break;
533: case 4:
534: {
1.1.1.2 ! root 535: Uint16 *fvram_line = fvram;
! 536: Uint32 *hvram_line = (Uint32 *)hvram;
1.1 root 537: int h;
538:
539: for (h = 0; h < vh_clip; h++) {
1.1.1.2 ! root 540: Uint16 *fvram_column = fvram_line;
! 541: Uint32 *hvram_column = hvram_line;
1.1 root 542: int w;
543:
544: for (w = 0; w < vw_clip; w++) {
545: int data = *fvram_column++;
546:
547: *hvram_column++ =
548: HostScreen_getColor(
1.1.1.2 ! root 549: (Uint8) (data & 0xf8),
! 550: (Uint8) ( ((data & 0x07) << 5) |
1.1 root 551: ((data >> 11) & 0x3c)),
1.1.1.2 ! root 552: (Uint8) ((data >> 5) & 0xf8));
1.1 root 553: }
554:
555: hvram_line += scrpitch>>2;
556: fvram_line += nextline;
557: }
558: }
559: break;
560: }
561: }
562: }
563:
564:
565: static void VIDEL_renderScreenZoom(void)
566: {
567: /* Atari screen infos */
568: int vw = VIDEL_getScreenWidth();
569: int vh = VIDEL_getScreenHeight();
570:
571: int lineoffset = handleReadW(HW + 0x0e) & 0x01ff; // 9 bits
572: int linewidth = handleReadW(HW + 0x10) & 0x03ff; // 10 bits
573: /* same remark as before: too naive */
574: int nextline = linewidth + lineoffset;
575:
576: if ((vw<32) || (vh<32)) return;
577:
578: if (bpp<16 && !hostColorsSync) {
579: VIDEL_updateColors();
580: }
581:
582: VIDEL_ConvertScreenZoom(vw, vh, bpp, nextline);
583: }
584:
585:
586: void VIDEL_ConvertScreenZoom(int vw, int vh, int vbpp, int nextline)
587: {
588: int i, j, w, h, cursrcline;
589:
1.1.1.2 ! root 590: Uint16 *fvram = (Uint16 *) Atari2HostAddr(VIDEL_getVideoramAddress());
1.1 root 591:
592: /* Host screen infos */
593: int scrpitch = HostScreen_getPitch();
594: int scrwidth = HostScreen_getWidth();
595: int scrheight = HostScreen_getHeight();
596: int scrbpp = HostScreen_getBpp();
1.1.1.2 ! root 597: Uint8 *hvram = (Uint8 *) HostScreen_getVideoramAddress();
1.1 root 598:
599: int hscrolloffset = (handleRead(HW + 0x65) & 0x0f);
600:
601: /* Horizontal scroll register set? */
602: if (hscrolloffset) {
603: /* Yes, so we need to adjust offset to next line: */
604: nextline += vbpp;
605: }
606:
607: /* Integer zoom coef ? */
608: if (/*(bx_options.autozoom.integercoefs) &&*/ (scrwidth>=vw) && (scrheight>=vh)) {
609: int coefx = scrwidth/vw;
610: int coefy = scrheight/vh;
611:
612: scrwidth = vw * coefx;
613: scrheight = vh * coefy;
614:
615: /* Center screen */
616: hvram += ((HostScreen_getHeight()-scrheight)>>1)*scrpitch;
617: hvram += ((HostScreen_getWidth()-scrwidth)>>1)*scrbpp;
618: }
619:
620: /* New zoom ? */
621: if ((zoomwidth != vw) || (scrwidth != prev_scrwidth)) {
622: if (zoomxtable) {
623: free(zoomxtable);
624: }
625: zoomxtable = malloc(sizeof(int)*scrwidth);
626: for (i=0; i<scrwidth; i++) {
627: zoomxtable[i] = (vw*i)/scrwidth;
628: }
629: zoomwidth = vw;
630: prev_scrwidth = scrwidth;
631: }
632: if ((zoomheight != vh) || (scrheight != prev_scrheight)) {
633: if (zoomytable) {
634: free(zoomytable);
635: }
636: zoomytable = malloc(sizeof(int)*scrheight);
637: for (i=0; i<scrheight; i++) {
638: zoomytable[i] = (vh*i)/scrheight;
639: }
640: zoomheight = vh;
641: prev_scrheight = scrheight;
642: }
643:
644: cursrcline = -1;
645:
646: if (vbpp<16) {
1.1.1.2 ! root 647: Uint8 color[16];
1.1 root 648:
649: /* Bitplanes modes */
650: switch(scrbpp) {
651: case 1:
652: {
653: /* One complete planar 2 chunky line */
1.1.1.2 ! root 654: Uint8 *p2cline = malloc(sizeof(Uint8)*vw);
1.1 root 655:
1.1.1.2 ! root 656: Uint16 *fvram_line;
! 657: Uint8 *hvram_line = hvram;
1.1 root 658:
659: for (h = 0; h < scrheight; h++) {
660: fvram_line = fvram + (zoomytable[h] * nextline);
661:
662: /* Recopy the same line ? */
663: if (zoomytable[h] == cursrcline) {
664: memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
665: } else {
1.1.1.2 ! root 666: Uint16 *fvram_column = fvram_line;
! 667: Uint8 *hvram_column = p2cline;
1.1 root 668:
669: /* First 16 pixels of a new line */
670: HostScreen_bitplaneToChunky(fvram_column, vbpp, color);
671: memcpy(hvram_column, color+hscrolloffset, 16-hscrolloffset);
672: hvram_column += 16-hscrolloffset;
673: fvram_column += vbpp;
674: /* Convert main part of the new line */
675: for (w=1; w < (vw+15)>>4; w++) {
676: HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
677: memcpy(hvram_column, color, 16);
678: hvram_column += 16;
679: fvram_column += vbpp;
680: }
681: /* Last pixels of the line for fine scrolling: */
682: if (hscrolloffset) {
683: HostScreen_bitplaneToChunky(fvram_column, vbpp, color);
684: memcpy(hvram_column, color, hscrolloffset);
685: }
686:
687: /* Zoom a new line */
688: for (w=0; w<scrwidth; w++) {
689: hvram_line[w] = p2cline[zoomxtable[w]];
690: }
691: }
692:
693: hvram_line += scrpitch;
694: cursrcline = zoomytable[h];
695: }
696:
697: free(p2cline);
698: }
699: break;
700: case 2:
701: {
702: /* One complete planar 2 chunky line */
1.1.1.2 ! root 703: Uint16 *p2cline = malloc(sizeof(Uint16)*vw);
1.1 root 704:
1.1.1.2 ! root 705: Uint16 *fvram_line = fvram;
! 706: Uint16 *hvram_line = (Uint16 *)hvram;
1.1 root 707:
708: for (h = 0; h < scrheight; h++) {
709: fvram_line = fvram + (zoomytable[h] * nextline);
710:
711: /* Recopy the same line ? */
712: if (zoomytable[h] == cursrcline) {
713: memcpy(hvram_line, hvram_line-(scrpitch>>1), scrwidth*scrbpp);
714: } else {
1.1.1.2 ! root 715: Uint16 *fvram_column = fvram_line;
! 716: Uint16 *hvram_column = p2cline;
1.1 root 717:
718: /* Convert a new line */
719: for (w=0; w < (vw+15)>>4; w++) {
720: HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
721:
722: for (j=0; j<16; j++) {
723: *hvram_column++ = HostScreen_getPaletteColor( color[j] );
724: }
725:
726: fvram_column += vbpp;
727: }
728:
729: /* Zoom a new line */
730: for (w=0; w<scrwidth; w++) {
731: hvram_line[w] = p2cline[zoomxtable[w]];
732: }
733: }
734:
735: hvram_line += scrpitch>>1;
736: cursrcline = zoomytable[h];
737: }
738:
739: free(p2cline);
740: }
741: break;
742: case 3:
743: {
744: /* One complete planar 2 chunky line */
1.1.1.2 ! root 745: Uint8 *p2cline = malloc(sizeof(Uint8)*vw*3);
1.1 root 746:
1.1.1.2 ! root 747: Uint16 *fvram_line;
! 748: Uint8 *hvram_line = hvram;
1.1 root 749:
750: for (h = 0; h < scrheight; h++) {
751: fvram_line = fvram + (zoomytable[h] * nextline);
752:
753: /* Recopy the same line ? */
754: if (zoomytable[h] == cursrcline) {
755: memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
756: } else {
1.1.1.2 ! root 757: Uint16 *fvram_column = fvram_line;
! 758: Uint8 *hvram_column = p2cline;
1.1 root 759:
760: /* Convert a new line */
761: for (w=0; w < (vw+15)>>4; w++) {
762: HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
763:
764: for (j=0; j<16; j++) {
1.1.1.2 ! root 765: Uint32 tmpColor = HostScreen_getPaletteColor( color[j] );
1.1 root 766: putBpp24Pixel( hvram_column, tmpColor );
767: hvram_column += 3;
768: }
769:
770: fvram_column += vbpp;
771: }
772:
773: /* Zoom a new line */
774: for (w=0; w<scrwidth; w++) {
775: hvram_line[w*3] = p2cline[zoomxtable[w]*3];
776: hvram_line[w*3+1] = p2cline[zoomxtable[w]*3+1];
777: hvram_line[w*3+2] = p2cline[zoomxtable[w]*3+2];
778: }
779: }
780:
781: hvram_line += scrpitch;
782: cursrcline = zoomytable[h];
783: }
784:
785: free(p2cline);
786: }
787: break;
788: case 4:
789: {
790: /* One complete planar 2 chunky line */
1.1.1.2 ! root 791: Uint32 *p2cline = malloc(sizeof(Uint32)*vw);
1.1 root 792:
1.1.1.2 ! root 793: Uint16 *fvram_line;
! 794: Uint32 *hvram_line = (Uint32 *)hvram;
1.1 root 795:
796: for (h = 0; h < scrheight; h++) {
797: fvram_line = fvram + (zoomytable[h] * nextline);
798:
799: /* Recopy the same line ? */
800: if (zoomytable[h] == cursrcline) {
801: memcpy(hvram_line, hvram_line-(scrpitch>>2), scrwidth*scrbpp);
802: } else {
1.1.1.2 ! root 803: Uint16 *fvram_column = fvram_line;
! 804: Uint32 *hvram_column = p2cline;
1.1 root 805:
806: /* Convert a new line */
807: for (w=0; w < (vw+15)>>4; w++) {
808: HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
809:
810: for (j=0; j<16; j++) {
811: *hvram_column++ = HostScreen_getPaletteColor( color[j] );
812: }
813:
814: fvram_column += vbpp;
815: }
816:
817: /* Zoom a new line */
818: for (w=0; w<scrwidth; w++) {
819: hvram_line[w] = p2cline[zoomxtable[w]];
820: }
821: }
822:
823: hvram_line += scrpitch>>2;
824: cursrcline = zoomytable[h];
825: }
826:
827: free(p2cline);
828: }
829: break;
830: }
831: } else {
832: /* Falcon TrueColour mode */
833:
834: switch(scrbpp) {
835: case 1:
836: {
837: /* FIXME: when Videl switches to 16bpp, set the palette to 3:3:2 */
1.1.1.2 ! root 838: Uint16 *fvram_line;
! 839: Uint8 *hvram_line = hvram;
1.1 root 840:
841: for (h = 0; h < scrheight; h++) {
1.1.1.2 ! root 842: Uint16 *fvram_column;
! 843: Uint8 *hvram_column;
1.1 root 844:
845: fvram_line = fvram + (zoomytable[h] * nextline);
846: fvram_column = fvram_line;
847: hvram_column = hvram_line;
848:
849: /* Recopy the same line ? */
850: if (zoomytable[h] == cursrcline) {
851: memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
852: } else {
853: for (w = 0; w < scrwidth; w++) {
1.1.1.2 ! root 854: Uint16 srcword;
! 855: Uint8 dstbyte;
1.1 root 856:
857: srcword = SDL_SwapBE16(fvram_column[zoomxtable[w]]);
858:
859: dstbyte = ((srcword>>13) & 7) << 5;
860: dstbyte |= ((srcword>>8) & 7) << 2;
861: dstbyte |= ((srcword>>2) & 3);
862:
863: *hvram_column++ = dstbyte;
864: }
865: }
866:
867: hvram_line += scrpitch;
868: cursrcline = zoomytable[h];
869: }
870: }
871: break;
872: case 2:
873: {
1.1.1.2 ! root 874: Uint16 *fvram_line;
! 875: Uint16 *hvram_line = (Uint16 *)hvram;
1.1 root 876:
877: for (h = 0; h < scrheight; h++) {
1.1.1.2 ! root 878: Uint16 *fvram_column;
! 879: Uint16 *hvram_column;
1.1 root 880:
881: fvram_line = fvram + (zoomytable[h] * nextline);
882: fvram_column = fvram_line;
883: hvram_column = hvram_line;
884:
885: /* Recopy the same line ? */
886: if (zoomytable[h] == cursrcline) {
887: memcpy(hvram_line, hvram_line-(scrpitch>>1), scrwidth*scrbpp);
888: } else {
889: for (w = 0; w < scrwidth; w++) {
1.1.1.2 ! root 890: Uint16 srcword;
1.1 root 891:
892: srcword = SDL_SwapBE16(fvram_column[zoomxtable[w]]);
893: *hvram_column++ = srcword;
894: }
895: }
896:
897: hvram_line += scrpitch>>1;
898: cursrcline = zoomytable[h];
899: }
900: }
901: break;
902: case 3:
903: {
1.1.1.2 ! root 904: Uint16 *fvram_line;
! 905: Uint8 *hvram_line = hvram;
1.1 root 906:
907: for (h = 0; h < scrheight; h++) {
1.1.1.2 ! root 908: Uint16 *fvram_column;
! 909: Uint8 *hvram_column;
1.1 root 910:
911: fvram_line = fvram + (zoomytable[h] * nextline);
912: fvram_column = fvram_line;
913: hvram_column = hvram_line;
914:
915: /* Recopy the same line ? */
916: if (zoomytable[h] == cursrcline) {
917: memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
918: } else {
919: for (w = 0; w < scrwidth; w++) {
1.1.1.2 ! root 920: Uint16 srcword;
! 921: Uint32 dstlong;
1.1 root 922:
923: srcword = fvram_column[zoomxtable[w]];
924:
925: dstlong = HostScreen_getColor(
1.1.1.2 ! root 926: (Uint8) (srcword & 0xf8),
! 927: (Uint8) ( ((srcword & 0x07) << 5) |
1.1 root 928: ((srcword >> 11) & 0x3c)),
1.1.1.2 ! root 929: (Uint8) ((srcword >> 5) & 0xf8));
1.1 root 930:
931: putBpp24Pixel( hvram_column, dstlong );
932: hvram_column += 3;
933: }
934: }
935:
936: hvram_line += scrpitch;
937: cursrcline = zoomytable[h];
938: }
939: }
940: break;
941: case 4:
942: {
1.1.1.2 ! root 943: Uint16 *fvram_line;
! 944: Uint32 *hvram_line = (Uint32 *)hvram;
1.1 root 945:
946: for (h = 0; h < scrheight; h++) {
1.1.1.2 ! root 947: Uint16 *fvram_column;
! 948: Uint32 *hvram_column;
1.1 root 949:
950: fvram_line = fvram + (zoomytable[h] * nextline);
951: fvram_column = fvram_line;
952: hvram_column = hvram_line;
953:
954: /* Recopy the same line ? */
955: if (zoomytable[h] == cursrcline) {
956: memcpy(hvram_line, hvram_line-(scrpitch>>2), scrwidth*scrbpp);
957: } else {
958: for (w = 0; w < scrwidth; w++) {
1.1.1.2 ! root 959: Uint16 srcword;
1.1 root 960:
961: srcword = fvram_column[zoomxtable[w]];
962:
963: *hvram_column++ =
964: HostScreen_getColor(
1.1.1.2 ! root 965: (Uint8) (srcword & 0xf8),
! 966: (Uint8) ( ((srcword & 0x07) << 5) |
1.1 root 967: ((srcword >> 11) & 0x3c)),
1.1.1.2 ! root 968: (Uint8) ((srcword >> 5) & 0xf8));
1.1 root 969: }
970: }
971:
972: hvram_line += scrpitch>>2;
973: cursrcline = zoomytable[h];
974: }
975: }
976: break;
977: }
978: }
979: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.