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

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: */
                     15: const char VIDEL_rcsid[] = "Hatari $Id: videl.c,v 1.17 2007/12/18 20:35:55 thothy Exp $";
                     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;
                     46: static BOOL hostColorsSync;
                     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: 
                    204: void VIDEL_renderScreen(void)
                    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++;
                    232:                return;
                    233:        }
                    234: 
                    235:        if (!HostScreen_renderBegin())
                    236:                return;
                    237: 
                    238:        if (ConfigureParams.Screen.bZoomLowRes) {
                    239:                VIDEL_renderScreenZoom();
                    240:        } else {
                    241:                VIDEL_renderScreenNoZoom();
                    242:        }
                    243: 
                    244:        HostScreen_renderEnd();
                    245: 
                    246:        HostScreen_update1( FALSE );
                    247: }
                    248: 
                    249: 
                    250: static void VIDEL_renderScreenNoZoom(void)
                    251: {
                    252:        int vw   = VIDEL_getScreenWidth();
                    253:        int vh   = VIDEL_getScreenHeight();
                    254: 
                    255:        int lineoffset = handleReadW(HW + 0x0e) & 0x01ff; // 9 bits
                    256:        int linewidth = handleReadW(HW + 0x10) & 0x03ff; // 10 bits
                    257:        /* 
                    258:           I think this implementation is naive: 
                    259:           indeed, I suspect that we should instead skip lineoffset
                    260:           words each time we have read "more" than linewidth words
                    261:           (possibly "more" because of the number of bit planes).
                    262:           Moreover, the 1 bit plane mode is particular;
                    263:           while doing some experiments on my Falcon, it seems to
                    264:           behave like the 4 bit planes mode.
                    265:           At last, we have also to take into account the 4 bits register
                    266:           located at the word $ffff8264 (bit offset). This register makes
                    267:           the semantics of the lineoffset register change a little.
                    268:           int bitoffset = handleReadW(HW + 0x64) & 0x000f;
                    269:           The meaning of this register in True Color mode is not clear
                    270:           for me at the moment (and my experiments on the Falcon don't help
                    271:           me).
                    272:        */
                    273:        int nextline = linewidth + lineoffset;
                    274: 
                    275:        if (bpp < 16 && !hostColorsSync) {
                    276:                VIDEL_updateColors();
                    277:        }
                    278: 
                    279:        VIDEL_ConvertScreenNoZoom(vw, vh, bpp, nextline);
                    280: }
                    281: 
                    282: 
                    283: void VIDEL_ConvertScreenNoZoom(int vw, int vh, int vbpp, int nextline)
                    284: {
                    285:        int scrpitch = HostScreen_getPitch();
                    286: 
                    287:        long atariVideoRAM = VIDEL_getVideoramAddress();
                    288: 
                    289:        uint16 *fvram = (uint16 *) Atari2HostAddr(atariVideoRAM);
                    290:        uint8 *hvram = HostScreen_getVideoramAddress();
                    291: 
                    292:        int hscrolloffset = (handleRead(HW + 0x65) & 0x0f);
                    293: 
                    294:        /* Clip to SDL_Surface dimensions */
                    295:        int scrwidth = HostScreen_getWidth();
                    296:        int scrheight = HostScreen_getHeight();
                    297:        int vw_clip = vw;
                    298:        int vh_clip = vh;
                    299:        if (vw>scrwidth) vw_clip = scrwidth;
                    300:        if (vh>scrheight) vh_clip = scrheight;  
                    301: 
                    302:        /* Horizontal scroll register set? */
                    303:        if (hscrolloffset) {
                    304:                /* Yes, so we need to adjust offset to next line: */
                    305:                nextline += vbpp;
                    306:        }
                    307: 
                    308:        /* Center screen */
                    309:        hvram += ((scrheight-vh_clip)>>1)*scrpitch;
                    310:        hvram += ((scrwidth-vw_clip)>>1)*HostScreen_getBpp();
                    311: 
                    312:        /* Render */
                    313:        if (vbpp < 16) {
                    314:                /* Bitplanes modes */
                    315: 
                    316:                // The SDL colors blitting...
                    317:                uint8 color[16];
                    318: 
                    319:                // FIXME: The byte swap could be done here by enrolling the loop into 2 each by 8 pixels
                    320:                switch ( HostScreen_getBpp() ) {
                    321:                        case 1:
                    322:                                {
                    323:                                        uint16 *fvram_line = fvram;
                    324:                                        uint8 *hvram_line = hvram;
                    325:                                        int h;
                    326: 
                    327:                                        for (h = 0; h < vh_clip; h++) {
                    328:                                                uint16 *fvram_column = fvram_line;
                    329:                                                uint8 *hvram_column = hvram_line;
                    330:                                                int w;
                    331: 
                    332:                                                /* First 16 pixels: */
                    333:                                                HostScreen_bitplaneToChunky(fvram_column, vbpp, color);
                    334:                                                memcpy(hvram_column, color+hscrolloffset, 16-hscrolloffset);
                    335:                                                hvram_column += 16-hscrolloffset;
                    336:                                                fvram_column += vbpp;
                    337:                                                /* Now the main part of the line: */
                    338:                                                for (w = 1; w < (vw_clip+15)>>4; w++) {
                    339:                                                        HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
                    340:                                                        memcpy(hvram_column, color, 16);
                    341:                                                        hvram_column += 16;
                    342:                                                        fvram_column += vbpp;
                    343:                                                }
                    344:                                                /* Last pixels of the line for fine scrolling: */
                    345:                                                if (hscrolloffset) {
                    346:                                                        HostScreen_bitplaneToChunky(fvram_column, vbpp, color);
                    347:                                                        memcpy(hvram_column, color, hscrolloffset);
                    348:                                                }
                    349: 
                    350:                                                hvram_line += scrpitch;
                    351:                                                fvram_line += nextline;
                    352:                                        }
                    353:                                }
                    354:                                break;
                    355:                        case 2:
                    356:                                {
                    357:                                        uint16 *fvram_line = fvram;
                    358:                                        uint16 *hvram_line = (uint16 *)hvram;
                    359:                                        int h;
                    360: 
                    361:                                        for (h = 0; h < vh_clip; h++) {
                    362:                                                uint16 *fvram_column = fvram_line;
                    363:                                                uint16 *hvram_column = hvram_line;
                    364:                                                int w;
                    365: 
                    366:                                                for (w = 0; w < (vw_clip+15)>>4; w++) {
                    367:                                                        int j;
                    368:                                                        HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
                    369: 
                    370:                                                        for (j=0; j<16; j++) {
                    371:                                                                *hvram_column++ = HostScreen_getPaletteColor( color[j] );
                    372:                                                        }
                    373: 
                    374:                                                        fvram_column += vbpp;
                    375:                                                }
                    376: 
                    377:                                                hvram_line += scrpitch>>1;
                    378:                                                fvram_line += nextline;
                    379:                                        }
                    380:                                }
                    381:                                break;
                    382:                        case 3:
                    383:                                {
                    384:                                        uint16 *fvram_line = fvram;
                    385:                                        uint8 *hvram_line = hvram;
                    386:                                        int h;
                    387: 
                    388:                                        for (h = 0; h < vh_clip; h++) {
                    389:                                                uint16 *fvram_column = fvram_line;
                    390:                                                uint8 *hvram_column = hvram_line;
                    391:                                                int w;
                    392: 
                    393:                                                for (w = 0; w < (vw_clip+15)>>4; w++) {
                    394:                                                        int j;
                    395:                                                        HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
                    396: 
                    397:                                                        for (j=0; j<16; j++) {
                    398:                                                                uint32 tmpColor = HostScreen_getPaletteColor( color[j] );
                    399:                                                                putBpp24Pixel( hvram_column, tmpColor );
                    400:                                                                hvram_column += 3;
                    401:                                                        }
                    402: 
                    403:                                                        fvram_column += vbpp;
                    404:                                                }
                    405: 
                    406:                                                hvram_line += scrpitch;
                    407:                                                fvram_line += nextline;
                    408:                                        }
                    409:                                }
                    410:                                break;
                    411:                        case 4:
                    412:                                {
                    413:                                        uint16 *fvram_line = fvram;
                    414:                                        uint32 *hvram_line = (uint32 *)hvram;
                    415:                                        int h;
                    416: 
                    417:                                        for (h = 0; h < vh_clip; h++) {
                    418:                                                uint16 *fvram_column = fvram_line;
                    419:                                                uint32 *hvram_column = hvram_line;
                    420:                                                int w;
                    421: 
                    422:                                                for (w = 0; w < (vw_clip+15)>>4; w++) {
                    423:                                                        int j;
                    424:                                                        HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
                    425: 
                    426:                                                        for (j=0; j<16; j++) {
                    427:                                                                *hvram_column++ = HostScreen_getPaletteColor( color[j] );
                    428:                                                        }
                    429: 
                    430:                                                        fvram_column += vbpp;
                    431:                                                }
                    432: 
                    433:                                                hvram_line += scrpitch>>2;
                    434:                                                fvram_line += nextline;
                    435:                                        }
                    436:                                }
                    437:                                break;
                    438:                }
                    439: 
                    440:        } else {
                    441: 
                    442:                // Falcon TC (High Color)
                    443:                switch ( HostScreen_getBpp() )  {
                    444:                        case 1:
                    445:                                {
                    446:                                        /* FIXME: when Videl switches to 16bpp, set the palette to 3:3:2 */
                    447:                                        uint16 *fvram_line = fvram;
                    448:                                        uint8 *hvram_line = hvram;
                    449:                                        int h;
                    450: 
                    451:                                        for (h = 0; h < vh_clip; h++) {
                    452:                                                uint16 *fvram_column = fvram_line;
                    453:                                                uint8 *hvram_column = hvram_line;
                    454:                                                int w, tmp;
                    455: 
                    456:                                                for (w = 0; w < vw_clip; w++) {
                    457:                                                        
                    458:                                                        tmp = SDL_SwapBE16(*fvram_column);
                    459: 
                    460:                                                        *hvram_column = ((tmp>>13) & 7) << 5;
                    461:                                                        *hvram_column |= ((tmp>>8) & 7) << 2;
                    462:                                                        *hvram_column |= ((tmp>>2) & 3);
                    463: 
                    464:                                                        hvram_column++;
                    465:                                                        fvram_column++;
                    466:                                                }
                    467: 
                    468:                                                hvram_line += scrpitch;
                    469:                                                fvram_line += nextline;
                    470:                                        }
                    471:                                }
                    472:                                break;
                    473:                        case 2:
                    474:                                {
                    475:                                        uint16 *fvram_line = fvram;
                    476:                                        uint16 *hvram_line = (uint16 *)hvram;
                    477:                                        int h;
                    478: 
                    479:                                        for (h = 0; h < vh_clip; h++) {
                    480: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                    481:                                                //FIXME: here might be a runtime little/big video endian switch like:
                    482:                                                //      if ( /* videocard memory in Motorola endian format */ false)
                    483:                                                memcpy(hvram_line, fvram_line, vw_clip<<1);
                    484: #else
                    485:                                                int w;
                    486:                                                uint16 *fvram_column = fvram_line;
                    487:                                                uint16 *hvram_column = hvram_line;
                    488: 
                    489:                                                for (w = 0; w < vw_clip; w++) {
                    490:                                                        // byteswap with SDL asm macros
                    491:                                                        *hvram_column++ = SDL_SwapBE16(*fvram_column++);
                    492:                                                }
                    493: #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
                    494: 
                    495:                                                hvram_line += scrpitch>>1;
                    496:                                                fvram_line += nextline;
                    497:                                        }
                    498:                                }
                    499:                                break;
                    500:                        case 3:
                    501:                                {
                    502:                                        uint16 *fvram_line = fvram;
                    503:                                        uint8 *hvram_line = hvram;
                    504:                                        int h;
                    505: 
                    506:                                        for (h = 0; h < vh_clip; h++) {
                    507:                                                uint16 *fvram_column = fvram_line;
                    508:                                                uint8 *hvram_column = hvram_line;
                    509:                                                int w;
                    510: 
                    511:                                                for (w = 0; w < vw_clip; w++) {
                    512:                                                        int data = *fvram_column++;
                    513: 
                    514:                                                        uint32 tmpColor =
                    515:                                                                HostScreen_getColor(
                    516:                                                                        (uint8) (data & 0xf8),
                    517:                                                                        (uint8) ( ((data & 0x07) << 5) |
                    518:                                                                                          ((data >> 11) & 0x3c)),
                    519:                                                                        (uint8) ((data >> 5) & 0xf8));
                    520:                                                        
                    521:                                                        putBpp24Pixel( hvram_column, tmpColor );
                    522: 
                    523:                                                        hvram_column += 3;
                    524:                                                }
                    525: 
                    526:                                                hvram_line += scrpitch;
                    527:                                                fvram_line += nextline;
                    528:                                        }
                    529:                                }
                    530:                                break;
                    531:                        case 4:
                    532:                                {
                    533:                                        uint16 *fvram_line = fvram;
                    534:                                        uint32 *hvram_line = (uint32 *)hvram;
                    535:                                        int h;
                    536: 
                    537:                                        for (h = 0; h < vh_clip; h++) {
                    538:                                                uint16 *fvram_column = fvram_line;
                    539:                                                uint32 *hvram_column = hvram_line;
                    540:                                                int w;
                    541: 
                    542:                                                for (w = 0; w < vw_clip; w++) {
                    543:                                                        int data = *fvram_column++;
                    544: 
                    545:                                                        *hvram_column++ =
                    546:                                                                HostScreen_getColor(
                    547:                                                                        (uint8) (data & 0xf8),
                    548:                                                                        (uint8) ( ((data & 0x07) << 5) |
                    549:                                                                                          ((data >> 11) & 0x3c)),
                    550:                                                                        (uint8) ((data >> 5) & 0xf8));
                    551:                                                }
                    552: 
                    553:                                                hvram_line += scrpitch>>2;
                    554:                                                fvram_line += nextline;
                    555:                                        }
                    556:                                }
                    557:                                break;
                    558:                }
                    559:        }
                    560: }
                    561: 
                    562: 
                    563: static void VIDEL_renderScreenZoom(void)
                    564: {
                    565:        /* Atari screen infos */
                    566:        int vw   = VIDEL_getScreenWidth();
                    567:        int vh   = VIDEL_getScreenHeight();
                    568: 
                    569:        int lineoffset = handleReadW(HW + 0x0e) & 0x01ff; // 9 bits
                    570:        int linewidth = handleReadW(HW + 0x10) & 0x03ff; // 10 bits
                    571:        /* same remark as before: too naive */
                    572:        int nextline = linewidth + lineoffset;
                    573: 
                    574:        if ((vw<32) || (vh<32))  return;
                    575: 
                    576:        if (bpp<16 && !hostColorsSync) {
                    577:                VIDEL_updateColors();
                    578:        }
                    579: 
                    580:        VIDEL_ConvertScreenZoom(vw, vh, bpp, nextline);
                    581: }
                    582: 
                    583: 
                    584: void VIDEL_ConvertScreenZoom(int vw, int vh, int vbpp, int nextline)
                    585: {
                    586:        int i, j, w, h, cursrcline;
                    587: 
                    588:        uint16 *fvram = (uint16 *) Atari2HostAddr(VIDEL_getVideoramAddress());
                    589: 
                    590:        /* Host screen infos */
                    591:        int scrpitch = HostScreen_getPitch();
                    592:        int scrwidth = HostScreen_getWidth();
                    593:        int scrheight = HostScreen_getHeight();
                    594:        int scrbpp = HostScreen_getBpp();
                    595:        uint8 *hvram = (uint8 *) HostScreen_getVideoramAddress();
                    596: 
                    597:        int hscrolloffset = (handleRead(HW + 0x65) & 0x0f);
                    598: 
                    599:        /* Horizontal scroll register set? */
                    600:        if (hscrolloffset) {
                    601:                /* Yes, so we need to adjust offset to next line: */
                    602:                nextline += vbpp;
                    603:        }
                    604: 
                    605:        /* Integer zoom coef ? */
                    606:        if (/*(bx_options.autozoom.integercoefs) &&*/ (scrwidth>=vw) && (scrheight>=vh)) {
                    607:                int coefx = scrwidth/vw;
                    608:                int coefy = scrheight/vh;
                    609: 
                    610:                scrwidth = vw * coefx;
                    611:                scrheight = vh * coefy;
                    612: 
                    613:                /* Center screen */
                    614:                hvram += ((HostScreen_getHeight()-scrheight)>>1)*scrpitch;
                    615:                hvram += ((HostScreen_getWidth()-scrwidth)>>1)*scrbpp;
                    616:        }
                    617: 
                    618:        /* New zoom ? */
                    619:        if ((zoomwidth != vw) || (scrwidth != prev_scrwidth)) {
                    620:                if (zoomxtable) {
                    621:                        free(zoomxtable);
                    622:                }
                    623:                zoomxtable = malloc(sizeof(int)*scrwidth);
                    624:                for (i=0; i<scrwidth; i++) {
                    625:                        zoomxtable[i] = (vw*i)/scrwidth;
                    626:                }
                    627:                zoomwidth = vw;
                    628:                prev_scrwidth = scrwidth;
                    629:        }
                    630:        if ((zoomheight != vh) || (scrheight != prev_scrheight)) {
                    631:                if (zoomytable) {
                    632:                        free(zoomytable);
                    633:                }
                    634:                zoomytable = malloc(sizeof(int)*scrheight);
                    635:                for (i=0; i<scrheight; i++) {
                    636:                        zoomytable[i] = (vh*i)/scrheight;
                    637:                }
                    638:                zoomheight = vh;
                    639:                prev_scrheight = scrheight;
                    640:        }
                    641: 
                    642:        cursrcline = -1;
                    643: 
                    644:        if (vbpp<16) {
                    645:                uint8 color[16];
                    646: 
                    647:                /* Bitplanes modes */
                    648:                switch(scrbpp) {
                    649:                        case 1:
                    650:                                {
                    651:                                        /* One complete planar 2 chunky line */
                    652:                                        uint8 *p2cline = malloc(sizeof(uint8)*vw);
                    653: 
                    654:                                        uint16 *fvram_line;
                    655:                                        uint8 *hvram_line = hvram;
                    656: 
                    657:                                        for (h = 0; h < scrheight; h++) {
                    658:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    659: 
                    660:                                                /* Recopy the same line ? */
                    661:                                                if (zoomytable[h] == cursrcline) {
                    662:                                                        memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
                    663:                                                } else {
                    664:                                                        uint16 *fvram_column = fvram_line;
                    665:                                                        uint8 *hvram_column = p2cline;
                    666: 
                    667:                                                        /* First 16 pixels of a new line */
                    668:                                                        HostScreen_bitplaneToChunky(fvram_column, vbpp, color);
                    669:                                                        memcpy(hvram_column, color+hscrolloffset, 16-hscrolloffset);
                    670:                                                        hvram_column += 16-hscrolloffset;
                    671:                                                        fvram_column += vbpp;
                    672:                                                        /* Convert main part of the new line */
                    673:                                                        for (w=1; w < (vw+15)>>4; w++) {
                    674:                                                                HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
                    675:                                                                memcpy(hvram_column, color, 16);
                    676:                                                                hvram_column += 16;
                    677:                                                                fvram_column += vbpp;
                    678:                                                        }
                    679:                                                        /* Last pixels of the line for fine scrolling: */
                    680:                                                        if (hscrolloffset) {
                    681:                                                                HostScreen_bitplaneToChunky(fvram_column, vbpp, color);
                    682:                                                                memcpy(hvram_column, color, hscrolloffset);
                    683:                                                        }
                    684: 
                    685:                                                        /* Zoom a new line */
                    686:                                                        for (w=0; w<scrwidth; w++) {
                    687:                                                                hvram_line[w] = p2cline[zoomxtable[w]];
                    688:                                                        }
                    689:                                                }
                    690: 
                    691:                                                hvram_line += scrpitch;
                    692:                                                cursrcline = zoomytable[h];
                    693:                                        }
                    694: 
                    695:                                        free(p2cline);
                    696:                                }
                    697:                                break;
                    698:                        case 2:
                    699:                                {
                    700:                                        /* One complete planar 2 chunky line */
                    701:                                        uint16 *p2cline = malloc(sizeof(uint16)*vw);
                    702: 
                    703:                                        uint16 *fvram_line = fvram;
                    704:                                        uint16 *hvram_line = (uint16 *)hvram;
                    705: 
                    706:                                        for (h = 0; h < scrheight; h++) {
                    707:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    708: 
                    709:                                                /* Recopy the same line ? */
                    710:                                                if (zoomytable[h] == cursrcline) {
                    711:                                                        memcpy(hvram_line, hvram_line-(scrpitch>>1), scrwidth*scrbpp);
                    712:                                                } else {
                    713:                                                        uint16 *fvram_column = fvram_line;
                    714:                                                        uint16 *hvram_column = p2cline;
                    715: 
                    716:                                                        /* Convert a new line */
                    717:                                                        for (w=0; w < (vw+15)>>4; w++) {
                    718:                                                                HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
                    719: 
                    720:                                                                for (j=0; j<16; j++) {
                    721:                                                                        *hvram_column++ = HostScreen_getPaletteColor( color[j] );
                    722:                                                                }
                    723: 
                    724:                                                                fvram_column += vbpp;
                    725:                                                        }
                    726:                                                        
                    727:                                                        /* Zoom a new line */
                    728:                                                        for (w=0; w<scrwidth; w++) {
                    729:                                                                hvram_line[w] = p2cline[zoomxtable[w]];
                    730:                                                        }
                    731:                                                }
                    732: 
                    733:                                                hvram_line += scrpitch>>1;
                    734:                                                cursrcline = zoomytable[h];
                    735:                                        }
                    736: 
                    737:                                        free(p2cline);
                    738:                                }
                    739:                                break;
                    740:                        case 3:
                    741:                                {
                    742:                                        /* One complete planar 2 chunky line */
                    743:                                        uint8 *p2cline = malloc(sizeof(uint8)*vw*3);
                    744: 
                    745:                                        uint16 *fvram_line;
                    746:                                        uint8 *hvram_line = hvram;
                    747: 
                    748:                                        for (h = 0; h < scrheight; h++) {
                    749:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    750: 
                    751:                                                /* Recopy the same line ? */
                    752:                                                if (zoomytable[h] == cursrcline) {
                    753:                                                        memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
                    754:                                                } else {
                    755:                                                        uint16 *fvram_column = fvram_line;
                    756:                                                        uint8 *hvram_column = p2cline;
                    757: 
                    758:                                                        /* Convert a new line */
                    759:                                                        for (w=0; w < (vw+15)>>4; w++) {
                    760:                                                                HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
                    761: 
                    762:                                                                for (j=0; j<16; j++) {
                    763:                                                                        uint32 tmpColor = HostScreen_getPaletteColor( color[j] );
                    764:                                                                        putBpp24Pixel( hvram_column, tmpColor );
                    765:                                                                        hvram_column += 3;
                    766:                                                                }
                    767: 
                    768:                                                                fvram_column += vbpp;
                    769:                                                        }
                    770:                                                        
                    771:                                                        /* Zoom a new line */
                    772:                                                        for (w=0; w<scrwidth; w++) {
                    773:                                                                hvram_line[w*3] = p2cline[zoomxtable[w]*3];
                    774:                                                                hvram_line[w*3+1] = p2cline[zoomxtable[w]*3+1];
                    775:                                                                hvram_line[w*3+2] = p2cline[zoomxtable[w]*3+2];
                    776:                                                        }
                    777:                                                }
                    778: 
                    779:                                                hvram_line += scrpitch;
                    780:                                                cursrcline = zoomytable[h];
                    781:                                        }
                    782: 
                    783:                                        free(p2cline);
                    784:                                }
                    785:                                break;
                    786:                        case 4:
                    787:                                {
                    788:                                        /* One complete planar 2 chunky line */
                    789:                                        uint32 *p2cline = malloc(sizeof(uint32)*vw);
                    790: 
                    791:                                        uint16 *fvram_line;
                    792:                                        uint32 *hvram_line = (uint32 *)hvram;
                    793: 
                    794:                                        for (h = 0; h < scrheight; h++) {
                    795:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    796: 
                    797:                                                /* Recopy the same line ? */
                    798:                                                if (zoomytable[h] == cursrcline) {
                    799:                                                        memcpy(hvram_line, hvram_line-(scrpitch>>2), scrwidth*scrbpp);
                    800:                                                } else {
                    801:                                                        uint16 *fvram_column = fvram_line;
                    802:                                                        uint32 *hvram_column = p2cline;
                    803: 
                    804:                                                        /* Convert a new line */
                    805:                                                        for (w=0; w < (vw+15)>>4; w++) {
                    806:                                                                HostScreen_bitplaneToChunky( fvram_column, vbpp, color );
                    807: 
                    808:                                                                for (j=0; j<16; j++) {
                    809:                                                                        *hvram_column++ = HostScreen_getPaletteColor( color[j] );
                    810:                                                                }
                    811: 
                    812:                                                                fvram_column += vbpp;
                    813:                                                        }
                    814:                                                        
                    815:                                                        /* Zoom a new line */
                    816:                                                        for (w=0; w<scrwidth; w++) {
                    817:                                                                hvram_line[w] = p2cline[zoomxtable[w]];
                    818:                                                        }
                    819:                                                }
                    820: 
                    821:                                                hvram_line += scrpitch>>2;
                    822:                                                cursrcline = zoomytable[h];
                    823:                                        }
                    824: 
                    825:                                        free(p2cline);
                    826:                                }
                    827:                                break;
                    828:                }
                    829:        } else {
                    830:                /* Falcon TrueColour mode */
                    831: 
                    832:                switch(scrbpp) {
                    833:                        case 1:
                    834:                                {
                    835:                                        /* FIXME: when Videl switches to 16bpp, set the palette to 3:3:2 */
                    836:                                        uint16 *fvram_line;
                    837:                                        uint8 *hvram_line = hvram;
                    838: 
                    839:                                        for (h = 0; h < scrheight; h++) {
                    840:                                                uint16 *fvram_column;
                    841:                                                uint8 *hvram_column;
                    842: 
                    843:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    844:                                                fvram_column = fvram_line;
                    845:                                                hvram_column = hvram_line;
                    846: 
                    847:                                                /* Recopy the same line ? */
                    848:                                                if (zoomytable[h] == cursrcline) {
                    849:                                                        memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
                    850:                                                } else {
                    851:                                                        for (w = 0; w < scrwidth; w++) {
                    852:                                                                uint16 srcword;
                    853:                                                                uint8 dstbyte;
                    854:                                                        
                    855:                                                                srcword = SDL_SwapBE16(fvram_column[zoomxtable[w]]);
                    856: 
                    857:                                                                dstbyte = ((srcword>>13) & 7) << 5;
                    858:                                                                dstbyte |= ((srcword>>8) & 7) << 2;
                    859:                                                                dstbyte |= ((srcword>>2) & 3);
                    860: 
                    861:                                                                *hvram_column++ = dstbyte;
                    862:                                                        }
                    863:                                                }
                    864: 
                    865:                                                hvram_line += scrpitch;
                    866:                                                cursrcline = zoomytable[h];
                    867:                                        }
                    868:                                }
                    869:                                break;
                    870:                        case 2:
                    871:                                {
                    872:                                        uint16 *fvram_line;
                    873:                                        uint16 *hvram_line = (uint16 *)hvram;
                    874: 
                    875:                                        for (h = 0; h < scrheight; h++) {
                    876:                                                uint16 *fvram_column;
                    877:                                                uint16 *hvram_column;
                    878: 
                    879:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    880:                                                fvram_column = fvram_line;
                    881:                                                hvram_column = hvram_line;
                    882: 
                    883:                                                /* Recopy the same line ? */
                    884:                                                if (zoomytable[h] == cursrcline) {
                    885:                                                        memcpy(hvram_line, hvram_line-(scrpitch>>1), scrwidth*scrbpp);
                    886:                                                } else {
                    887:                                                        for (w = 0; w < scrwidth; w++) {
                    888:                                                                uint16 srcword;
                    889:                                                        
                    890:                                                                srcword = SDL_SwapBE16(fvram_column[zoomxtable[w]]);
                    891:                                                                *hvram_column++ = srcword;
                    892:                                                        }
                    893:                                                }
                    894: 
                    895:                                                hvram_line += scrpitch>>1;
                    896:                                                cursrcline = zoomytable[h];
                    897:                                        }
                    898:                                }
                    899:                                break;
                    900:                        case 3:
                    901:                                {
                    902:                                        uint16 *fvram_line;
                    903:                                        uint8 *hvram_line = hvram;
                    904: 
                    905:                                        for (h = 0; h < scrheight; h++) {
                    906:                                                uint16 *fvram_column;
                    907:                                                uint8 *hvram_column;
                    908: 
                    909:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    910:                                                fvram_column = fvram_line;
                    911:                                                hvram_column = hvram_line;
                    912: 
                    913:                                                /* Recopy the same line ? */
                    914:                                                if (zoomytable[h] == cursrcline) {
                    915:                                                        memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
                    916:                                                } else {
                    917:                                                        for (w = 0; w < scrwidth; w++) {
                    918:                                                                uint16 srcword;
                    919:                                                                uint32 dstlong;
                    920:                                                        
                    921:                                                                srcword = fvram_column[zoomxtable[w]];
                    922: 
                    923:                                                                dstlong = HostScreen_getColor(
                    924:                                                                                (uint8) (srcword & 0xf8),
                    925:                                                                                (uint8) ( ((srcword & 0x07) << 5) |
                    926:                                                                                          ((srcword >> 11) & 0x3c)),
                    927:                                                                                (uint8) ((srcword >> 5) & 0xf8));
                    928: 
                    929:                                                                putBpp24Pixel( hvram_column, dstlong );
                    930:                                                                hvram_column += 3;
                    931:                                                        }
                    932:                                                }
                    933: 
                    934:                                                hvram_line += scrpitch;
                    935:                                                cursrcline = zoomytable[h];
                    936:                                        }
                    937:                                }
                    938:                                break;
                    939:                        case 4:
                    940:                                {
                    941:                                        uint16 *fvram_line;
                    942:                                        uint32 *hvram_line = (uint32 *)hvram;
                    943: 
                    944:                                        for (h = 0; h < scrheight; h++) {
                    945:                                                uint16 *fvram_column;
                    946:                                                uint32 *hvram_column;
                    947: 
                    948:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    949:                                                fvram_column = fvram_line;
                    950:                                                hvram_column = hvram_line;
                    951: 
                    952:                                                /* Recopy the same line ? */
                    953:                                                if (zoomytable[h] == cursrcline) {
                    954:                                                        memcpy(hvram_line, hvram_line-(scrpitch>>2), scrwidth*scrbpp);
                    955:                                                } else {
                    956:                                                        for (w = 0; w < scrwidth; w++) {
                    957:                                                                uint16 srcword;
                    958:                                                        
                    959:                                                                srcword = fvram_column[zoomxtable[w]];
                    960: 
                    961:                                                                *hvram_column++ =
                    962:                                                                        HostScreen_getColor(
                    963:                                                                                (uint8) (srcword & 0xf8),
                    964:                                                                                (uint8) ( ((srcword & 0x07) << 5) |
                    965:                                                                                          ((srcword >> 11) & 0x3c)),
                    966:                                                                                (uint8) ((srcword >> 5) & 0xf8));
                    967:                                                        }
                    968:                                                }
                    969: 
                    970:                                                hvram_line += scrpitch>>2;
                    971:                                                cursrcline = zoomytable[h];
                    972:                                        }
                    973:                                }
                    974:                                break;
                    975:                }
                    976:        }
                    977: }

unix.superglobalmegacorp.com

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