Annotation of uae/src/od-dos/video/video.c, revision 1.1.1.4

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * DOS video interface.
                      5:   *
                      6:   * (c) 1997 Gustavo Goedert
                      7:   *
                      8:   * Originaly based on svga.c -- (c) 1995 Bernd Schmidt
                      9:   */
                     10: 
                     11: #include "sysconfig.h"
                     12: #include "sysdeps.h"
                     13: 
                     14: #include <dos.h>
                     15: #include <go32.h>
                     16: #include <dpmi.h>
                     17: #include <sys/exceptn.h>
                     18: #include <crt0.h>
                     19: #include <signal.h>
                     20: 
                     21: #include "config.h"
                     22: #include "options.h"
1.1.1.4 ! root       23: #include "threaddep/thread.h"
1.1       root       24: #include "memory.h"
                     25: #include "custom.h"
                     26: #include "xwin.h"
                     27: #include "disk.h"
                     28: #include "uae.h"
                     29: #include "debug.h"
                     30: #include "picasso96.h"
                     31: #include "misc/handlers.h"
                     32: #include "misc/misc.h"
                     33: #include "video/vbe.h"
                     34: 
                     35: int GetColor(int r, int g, int b, xcolnr *cnp);
                     36: void InitColors(void);
                     37: void SetWindowForPicasso(void);
                     38: void SetWindowForAmiga(void);
                     39: uae_u8 *lockscr (void);
                     40: void unlockscr (void);
                     41: 
                     42: extern int debugging;
                     43: 
                     44: xcolnr xcolors[4096];
                     45: struct vidbuf_description gfxvidinfo;
                     46: int NeedDither;
                     47: UBYTE DitherBuf[1000];
                     48: int ColorsAllocated;
                     49: char *LinearMem = NULL;
                     50: int ModeNumber = -1, UseLinear = 0;
                     51: int PicassoModeNumber = -1, PicassoUseLinear = 0;
                     52: int ScreenIsPicasso = 0;
                     53: char PicassoInvalidLines[1200];
                     54: 
                     55: struct bstring *video_mode_menu = NULL;
                     56: 
                     57: void setup_brkhandler(void) {
                     58: }
                     59: 
                     60: void flush_line(int y) {
                     61:     int target_y = y;
                     62:     char *addr;
                     63: 
                     64:     if (debugging)
                     65:        return;
                     66:     if (LinearMem == NULL) {
                     67:        addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
                     68:        if (target_y < CurrentMode.ModeHeight && target_y >= 0) {
                     69:            if (NeedDither) {
                     70:                DitherLine(DitherBuf, (UWORD *)addr, 0, y, gfxvidinfo.width, CurrentMode.BitsPerPixel);
                     71:                addr = DitherBuf;
                     72:            }
                     73:            CurrentMode.PutLine(addr, target_y);
                     74:        }
                     75:     } else if (NeedDither && target_y >= 0) {
                     76:        addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
                     77:        DitherLine(LinearMem + CurrentMode.LogicalLineLength * target_y, (UWORD *)addr, 0, y, gfxvidinfo.width, CurrentMode.BitsPerPixel);
                     78:     }
                     79: }
                     80: 
                     81: void flush_block(int a, int b) {
                     82:     abort();
                     83: }
                     84: 
                     85: void flush_screen(int a, int b) {
                     86: }
                     87: 
                     88: int GetColor(int r, int g, int b, xcolnr *cnp) {
                     89:     if ((CurrentMode.ModeType == T16) && (ColorsAllocated == 16))
                     90:        return -1;
                     91:     else if (ColorsAllocated == 256)
                     92:        return -1;
                     93:     *cnp = ColorsAllocated;
                     94:     DelayedSetPalette(ColorsAllocated, doMask(r, 6, 0), doMask(g, 6, 0), doMask(b, 6, 0));
                     95:     ColorsAllocated++;
                     96:     return 1;
                     97: }
                     98: 
                     99: void InitColors(void) {
                    100:     int i;
                    101: 
                    102:     gfxvidinfo.can_double = 0;
                    103:     if (NeedDither)
                    104:        setup_dither(CurrentMode.BitsPerColor, GetColor);
                    105:     else {
                    106:        ColorsAllocated = 0;
                    107:        if (gfxvidinfo.pixbytes == 1)
                    108:            alloc_colors256(GetColor);
                    109:        else
                    110:            alloc_colors64k(CurrentMode.RedSize,
                    111:                            CurrentMode.GreenSize,
                    112:                            CurrentMode.BlueSize,
                    113:                            CurrentMode.RedPosition,
                    114:                            CurrentMode.GreenPosition,
                    115:                            CurrentMode.BluePosition);
                    116:        if (gfxvidinfo.pixbytes == 1) {
                    117:            for (i = 0; i < 4096; i++)
                    118:                xcolors[i] = xcolors[i] * 0x01010101;
                    119:            gfxvidinfo.can_double = 1;
                    120:        } else if (gfxvidinfo.pixbytes == 2) {
                    121:            for (i = 0; i < 4096; i++)
                    122:                xcolors[i] = xcolors[i] * 0x00010001;
                    123:            gfxvidinfo.can_double = 1;
                    124:        }
                    125:    }
                    126: }
                    127: 
1.1.1.3   root      128: struct gfxstring *gfxmenu;
                    129: int numgfxitems = 0;
                    130: 
                    131: struct gfxstring{
                    132:     char data[32];
                    133:     int val;
                    134: };
                    135: 
                    136: int gfxmenusort(const void *a, const void *b) {
                    137:    struct gfxstring *ga, *gb;
                    138: 
                    139:    ga = (struct gfxstring *) a;
                    140:    gb = (struct gfxstring *) b;
                    141:    if (ModeList[ga->val].ModeWidth < ModeList[gb->val].ModeWidth)
                    142:       return(-1);
                    143:    else if (ModeList[ga->val].ModeWidth > ModeList[gb->val].ModeWidth)
                    144:       return(1);
                    145:    else if (ModeList[ga->val].ModeHeight < ModeList[gb->val].ModeHeight)
                    146:       return(-1);
                    147:    else if (ModeList[ga->val].ModeHeight > ModeList[gb->val].ModeHeight)
                    148:       return(1);
                    149:    else if (ModeList[ga->val].ModeType < ModeList[gb->val].ModeType)
                    150:       return(-1);
                    151:    else if (ModeList[ga->val].ModeType > ModeList[gb->val].ModeType)
                    152:       return(1);
                    153:    return(0);
                    154: }
                    155: 
1.1       root      156: int graphics_setup(void) {
1.1.1.3   root      157:     int i, j, hasres;
                    158:     struct gfxstring gfxmenuitem;
                    159: 
                    160:     gfxmenu = (struct gfxstring *)calloc(NumberOfModes, sizeof(struct gfxstring));
                    161: 
                    162:     for (i = 0; i < NumberOfModes; i++) {
                    163:        hasres = 0;
                    164:        for (j = 0; j < numgfxitems; j++)
                    165:            if ((ModeList[gfxmenu[j].val].ModeType == ModeList[i].ModeType) &&
                    166:                (ModeList[gfxmenu[j].val].ModeWidth == ModeList[i].ModeWidth) &&
                    167:                (ModeList[gfxmenu[j].val].ModeHeight == ModeList[i].ModeHeight))
                    168:                hasres = 1;
                    169:        if (!hasres) {
                    170:            sprintf(gfxmenu[numgfxitems].data, "%dx%d ", ModeList[i].ModeWidth, ModeList[i].ModeHeight);
                    171:            switch (ModeList[i].ModeType) {
                    172:                case T16:
                    173:                    strcat(gfxmenu[numgfxitems].data, "16 colors");
                    174:                    break;
                    175:                case T256:
                    176:                    strcat(gfxmenu[numgfxitems].data, "256 colors");
                    177:                    break;
                    178:                case T32K:
                    179:                    strcat(gfxmenu[numgfxitems].data, "32k colors");
                    180:                    break;
                    181:                case T64K:
                    182:                    strcat(gfxmenu[numgfxitems].data, "64k colors");
                    183:                    break;
                    184:                case T16M:
                    185:                    strcat(gfxmenu[numgfxitems].data, "16M colors");
                    186:                    break;
                    187:            }
                    188:            gfxmenu[numgfxitems].val = i;
                    189:            numgfxitems++;
                    190:        }
                    191:     }
                    192:     qsort((void *)gfxmenu, numgfxitems, sizeof(struct gfxstring), gfxmenusort);
                    193: 
                    194:     video_mode_menu = (struct bstring *)malloc(sizeof (struct bstring)*(numgfxitems+1));
                    195:     for (i = 0; i < numgfxitems; i++) {
                    196:        video_mode_menu[i].val = -1;
                    197:        video_mode_menu[i].data = strdup(gfxmenu[i].data);
                    198:     }
                    199:     video_mode_menu[numgfxitems].val = -3;
                    200:     video_mode_menu[numgfxitems].data = NULL;
                    201: 
1.1       root      202:     return 1;
                    203: }
                    204: 
1.1.1.3   root      205: void vidmode_menu_selected(int a) {
                    206:     currprefs.gfx_width = ModeList[gfxmenu[a].val].ModeWidth;
                    207:     currprefs.gfx_height = ModeList[gfxmenu[a].val].ModeHeight;
                    208:     switch (ModeList[gfxmenu[a].val].ModeType) {
                    209:        case T16:
                    210:            currprefs.color_mode = 4;
                    211:            break;
                    212:        case T256:
                    213:            currprefs.color_mode = 0;
                    214:            break;
                    215:        case T32K:
                    216:            currprefs.color_mode = 1;
                    217:            break;
                    218:        case T64K:
                    219:            currprefs.color_mode = 2;
                    220:            break;
                    221:        case T16M:
                    222:            currprefs.color_mode = 5;
                    223:            break;
                    224:     }
                    225:     currprefs.gfx_lores=currprefs.gfx_width<640;
                    226:     currprefs.gfx_xcenter=2;
                    227:     currprefs.gfx_ycenter=2;
                    228:     currprefs.gfx_linedbl=0;
                    229:     if (currprefs.gfx_height > 285)
                    230:        currprefs.gfx_linedbl = 1;
                    231:     currprefs.gfx_correct_aspect = 1;
                    232:     if (currprefs.gfx_height > 570)
                    233:        currprefs.gfx_correct_aspect = 0;
                    234: }
                    235: 
1.1       root      236: int graphics_init(void) {
                    237:     T_ModeType WantedType;
                    238:     int i;
                    239: 
                    240:     /* save produce_sound state */
                    241:     Original_produce_sound = currprefs.produce_sound;
                    242: 
                    243:     switch (currprefs.color_mode) {
                    244:        case 0: WantedType=T256; NeedDither=0; break;
                    245:        case 1: WantedType=T32K; NeedDither=0; break;
                    246:        case 2: WantedType=T64K; NeedDither=0; break;
                    247:        case 3: WantedType=T256; NeedDither=1; break;
                    248:        case 4: WantedType=T16;  NeedDither=1; break;
                    249:        case 5: WantedType=T16M; NeedDither=0; break;
                    250:        default:
                    251:        printf("Invalid color mode.\n");
                    252:        return 0;
                    253:     }
                    254: 
                    255:     if (!InitGfxLib()) {
                    256:        printf("Can't init GfxLib.\n");
                    257:        return 0;
                    258:     }
                    259: 
                    260:     if (!currprefs.no_xhair)
                    261:        for (i = 0; i < NumberOfModes; i++) {
                    262:            if ((ModeList[i].ModeType == WantedType) &&
                    263:                (ModeList[i].ModeWidth == currprefs.gfx_width) &&
                    264:                (ModeList[i].ModeHeight == currprefs.gfx_height) &&
                    265:                 ModeList[i].HasLinear) {
                    266:                ModeNumber = i;
                    267:                UseLinear = 1;
                    268:                break;
                    269:            }
                    270:        }
                    271:     if (ModeNumber == -1)
                    272:        for (i = 0; i < NumberOfModes; i++) {
                    273:            if ((ModeList[i].ModeType == WantedType) &&
                    274:                (ModeList[i].ModeWidth == currprefs.gfx_width) &&
                    275:                (ModeList[i].ModeHeight == currprefs.gfx_height)) {
                    276:                if (ModeList[i].HasWindow || ((!ModeList[i].HasLinear) && (!ModeList[i].HasWindow))) {
                    277:                    ModeNumber = i;
                    278:                    break;
                    279:                }
                    280:            }
                    281:        }
                    282: 
                    283:     if (ModeNumber == -1) {
                    284:        printf("Sorry, this combination of color and video mode is not supported.\n");
                    285:        return 0;
                    286:     }
                    287: 
1.1.1.3   root      288:     if (!SetMode(ModeNumber, UseLinear, 1)) {
1.1       root      289:        printf("Can't start graphics mode.\n");
                    290:        return 0;
                    291:     }
                    292: 
                    293:     if (!NeedDither)
                    294:        gfxvidinfo.pixbytes = CurrentMode.BitsPerPixel>>3;
                    295:     else
                    296:        gfxvidinfo.pixbytes = 2;
                    297: 
                    298:     if (UseLinear) {
                    299:        printf("Using linear framebuffer.\n");
                    300:        if (CanMapBuffer) {
                    301:            LinearMem = CurrentMode.MappedAddress;
                    302:            if (LinearMem != NULL)
                    303:                printf("Mapping linear framebuffer into emulator memory.\n");
                    304:            else {
                    305:                printf("Can't map linear framebuffer.\n");
                    306:                return 0;
                    307:            }
                    308:        }
                    309:     }
                    310: 
                    311:     gfxvidinfo.maxblocklines = 0;
                    312: 
                    313:     gfxvidinfo.width = CurrentMode.ModeWidth;
                    314:     gfxvidinfo.height = CurrentMode.ModeHeight;
                    315:     gfxvidinfo.linemem = 0;
                    316: 
                    317:     InitColors();
                    318:     if ((gfxvidinfo.pixbytes == 1) || NeedDither)
                    319:        LoadPalette();
                    320: 
                    321:     if (UseLinear && CanMapBuffer && (!NeedDither) && (LinearMem != NULL)) {
                    322:        gfxvidinfo.bufmem = LinearMem;
                    323:        gfxvidinfo.rowbytes = CurrentMode.LogicalLineLength;
                    324:     } else {
                    325:        gfxvidinfo.rowbytes = (CurrentMode.ModeWidth * gfxvidinfo.pixbytes + 3) & ~3;
                    326:        gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * CurrentMode.ModeHeight);
                    327:        if (gfxvidinfo.bufmem == NULL) {
                    328:            printf("Can't allocate framebuffer.\n");
                    329:            return 0;
                    330:        }
                    331:     }
                    332: 
                    333:     memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * CurrentMode.ModeHeight);
                    334:     for(i=0; i<gfxvidinfo.height; i++)
                    335:        flush_line(i);
                    336: 
                    337:     /* set up handlers */
                    338:     if (!InstallHandlers()) {
                    339:        printf("Can't install all handlers.\n");
                    340:        return(0);
                    341:     }
                    342: 
                    343:     return 1;
                    344: }
                    345: 
                    346: void graphics_leave(void) {
                    347:     UninstallHandlers();
                    348:     CloseGfxLib();
                    349:     dumpcustom();
                    350:     /* restore produce_sound state */
                    351:     currprefs.produce_sound = Original_produce_sound;
                    352: }
                    353: 
1.1.1.3   root      354: int debuggable(void) {
                    355:     return(1);
                    356: }
                    357: 
                    358: int needmousehack(void) {
                    359:     return(0);
1.1       root      360: }
                    361: 
1.1.1.3   root      362: void write_log(const char *buf) {
                    363:     printf(buf);
1.1       root      364: }
                    365: 
                    366: #ifdef PICASSO96
                    367: 
                    368: void PicassoRefresh(void) {
                    369:     if (ScreenIsPicasso && !picasso_vidinfo.extra_mem) {
                    370:        int i;
                    371:        char *addr = gfxmemory + (picasso96_state.Address - gfxmem_start);
                    372:        for (i = 0; i < picasso_vidinfo.height; i++, addr += picasso96_state.BytesPerRow) {
                    373:            if (!PicassoInvalidLines[i])
                    374:                continue;
                    375:            PicassoInvalidLines[i] = 0;
                    376:            CurrentMode.PutLine(addr, i);
                    377:        }
                    378:     }
                    379: }
                    380: 
                    381: void DX_Invalidate (int first, int last) {
                    382:     if (!picasso_vidinfo.extra_mem) {
                    383:        do {
                    384:            PicassoInvalidLines[first] = 1;
                    385:            first++;
                    386:        } while (first <= last);
                    387:     }
                    388: }
                    389: 
                    390: int DX_BitsPerCannon (void) {
                    391:     return 8;
                    392: }
                    393: 
                    394: void DX_SetPalette(int start, int count) {
                    395:     if (!ScreenIsPicasso || picasso_vidinfo.pixbytes != 1)
                    396:        return;
                    397: 
                    398:     while (count-- > 0) {
                    399:        DelayedSetPalette(start, picasso96_state.CLUT[start].Red * 63 / 255,
                    400:                                 picasso96_state.CLUT[start].Green * 63 / 255,
                    401:                                 picasso96_state.CLUT[start].Blue * 63 / 255);
                    402:        start++;
                    403:     }
                    404:     LoadPalette();
                    405: }
                    406: 
                    407: int DX_FillResolutions (uae_u16 *ppixel_format) {
                    408:     int i, count = 0;
                    409:     uae_u16 format = 0;
                    410: 
                    411:     for (i = 0; i < NumberOfModes; i++) {
                    412:        if (ModeList[i].ModeType != T16) {
                    413:            DisplayModes[count].res.width = ModeList[i].ModeWidth;
                    414:            DisplayModes[count].res.height = ModeList[i].ModeHeight;
                    415:            DisplayModes[count].depth = ModeList[i].BitsPerPixel>>3;
                    416:            DisplayModes[count].refresh = 75;
                    417:            switch (DisplayModes[count].depth) {
                    418:                case 1: format |= RGBFF_CHUNKY; break;
                    419:                case 2: format |= RGBFF_R5G6B5PC; break;
                    420:                case 3: format |= RGBFF_B8G8R8; break;
                    421:                case 4: format |= RGBFF_B8G8R8A8; break;
                    422:            }
                    423:            count++;
                    424:        }
                    425:     }
                    426: 
                    427:     *ppixel_format = format;
                    428:     return count;
                    429: }
                    430: 
                    431: void SetWindowForPicasso(void) {
1.1.1.3   root      432:     if (!SetMode(PicassoModeNumber, PicassoUseLinear, 0)) {
1.1       root      433:        printf("Can't start graphics mode.\n");
                    434:        abort();
                    435:     }
                    436:     if (PicassoUseLinear && (CurrentMode.MappedAddress != NULL)) {
                    437:        LinearMem = CurrentMode.MappedAddress;
                    438:        picasso_vidinfo.extra_mem = 1;
                    439:     } else
                    440:        picasso_vidinfo.extra_mem = 0;
                    441:     DX_SetPalette (0, 256);
                    442: }
                    443: 
                    444: void SetWindowForAmiga(void) {
1.1.1.3   root      445:     if (!SetMode(ModeNumber, UseLinear, 0)) {
1.1       root      446:        printf("Can't start graphics mode.\n");
                    447:        abort();
                    448:     }
                    449:     if (UseLinear && (CurrentMode.MappedAddress != NULL) && (!NeedDither)) {
                    450:        LinearMem = CurrentMode.MappedAddress;
                    451:        gfxvidinfo.bufmem = LinearMem;
                    452:     }
                    453:     if ((gfxvidinfo.pixbytes == 1) || NeedDither)
                    454:        LoadPalette();
                    455: }
                    456: 
                    457: void gfx_set_picasso_state (int on) {
                    458:     if (on == ScreenIsPicasso)
                    459:        return;
                    460:     ScreenIsPicasso = on;
                    461:     if (on)
                    462:        SetWindowForPicasso();
                    463:     else
                    464:        SetWindowForAmiga();
                    465: }
                    466: 
                    467: void gfx_set_picasso_modeinfo (int w, int h, int depth) {
                    468:     T_ModeType WantedType;
                    469:     int i;
                    470: 
                    471:     PicassoModeNumber = -1;
                    472:     PicassoUseLinear = 0;
                    473:     switch (depth) {
                    474:        case 8: WantedType=T256; break;
                    475:        case 16: WantedType=T64K; break;
                    476:        case 24:
                    477:        case 32: WantedType=T16M; break;
                    478:        default:
                    479:        printf("Invalid Picasso mode.\n");
                    480:        abort();
                    481:     }
                    482: 
                    483:     if (!currprefs.no_xhair)
                    484:        for (i = 0; i < NumberOfModes; i++) {
                    485:            if ((ModeList[i].ModeType == WantedType) &&
                    486:                (ModeList[i].ModeWidth == w) &&
                    487:                (ModeList[i].ModeHeight == h) &&
                    488:                 ModeList[i].HasLinear) {
                    489:                PicassoModeNumber = i;
                    490:                PicassoUseLinear = 1;
                    491:                break;
                    492:            }
                    493:        }
                    494:     if (PicassoModeNumber == -1)
                    495:        for (i = 0; i < NumberOfModes; i++) {
                    496:            if ((ModeList[i].ModeType == WantedType) &&
                    497:                (ModeList[i].ModeWidth == w) &&
                    498:                (ModeList[i].ModeHeight == h)) {
                    499:                if (ModeList[i].HasWindow || ((!ModeList[i].HasLinear) && (!ModeList[i].HasWindow))) {
                    500:                    PicassoModeNumber = i;
                    501:                    break;
                    502:                }
                    503:            }
                    504:        }
                    505: 
                    506:     if (PicassoModeNumber == -1) {
                    507:        printf("Invalid Picasso mode.\n");
                    508:        abort ();
                    509:     }
                    510: 
                    511:     picasso_vidinfo.width = w;
                    512:     picasso_vidinfo.height = h;
                    513:     picasso_vidinfo.depth = depth;
                    514:     picasso_vidinfo.pixbytes = depth>>3;
                    515:     picasso_vidinfo.rowbytes = ModeList[PicassoModeNumber].LogicalLineLength;
                    516:     if (ScreenIsPicasso)
                    517:        SetWindowForPicasso ();
                    518: }
                    519: 
                    520: uae_u8 *lockscr (void) {
                    521:     return LinearMem;
                    522: }
                    523: 
                    524: void unlockscr (void) {
                    525: }
                    526: 
                    527: #endif

unix.superglobalmegacorp.com

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