Annotation of hatari/src/falcon/videl.c, revision 1.1.1.2

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.