Annotation of uae/src/md-amiga/ami-win.c, revision 1.1.1.1

1.1       root        1:  /* 
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   * 
                      4:   * Amiga interface
                      5:   * 
                      6:   * Copyright 1996 Samuel Devulder, Olaf `Olsen' Barthel.
                      7:   */
                      8: 
                      9: /*
                     10:  * NOTE:
                     11:  *      - Im quite unhappy with the color allocation scheme in case of
                     12:  *        EXTRA_HALFBRITE...
                     13:  *      - It would be better to split this huge file into smaller pieces,
                     14:  *        but I think UAE has already too many different files, so please
                     15:  *        cope with that big one.
                     16:  */
                     17: 
                     18: /*
                     19:  * History: 
                     20:  *    16/10/96 - Rewrote cybergfx support. (there is still a bug if the memory
                     21:  *               is not linear).
                     22:  *    15/11/96 - Inhibit the drive in readdevice().
                     23:  *    23/11/96 - Added call to rexx_init() and gui_handle_event().
                     24:  *    14/12/96 - Added support for graffiti screens.
                     25:  */
                     26: 
                     27: #define USE_CYBERGFX /* undefine this if you don't have CYBERGFX includes */
                     28: 
                     29: /****************************************************************************/
                     30: 
                     31: #include <exec/execbase.h>
                     32: #include <exec/memory.h>
                     33: #include <exec/devices.h>
                     34: #include <exec/io.h>
                     35: 
                     36: #include <dos/dos.h>
                     37: 
                     38: #include <graphics/gfxbase.h>
                     39: #include <graphics/displayinfo.h>
                     40: 
                     41: #include <libraries/asl.h>
                     42: #include <intuition/pointerclass.h>
                     43: 
                     44: #include <devices/trackdisk.h>
                     45: 
                     46: #include <proto/intuition.h>
                     47: #include <proto/graphics.h>
                     48: #include <proto/exec.h>
                     49: #include <proto/asl.h>
                     50: #include <proto/alib.h>
                     51: #include <proto/dos.h>
                     52: 
                     53: #ifdef USE_CYBERGFX
                     54: #include <inline/cybergraphics.h>
                     55: #endif
                     56: 
                     57: /****************************************************************************/
                     58: 
                     59: #include "sysconfig.h"
                     60: #include "sysdeps.h"
                     61: 
                     62: #include <ctype.h>
                     63: #include <signal.h>
                     64: 
                     65: /****************************************************************************/
                     66: 
                     67: #include "uae.h"
                     68: #include "config.h"
                     69: #include "options.h"
                     70: #include "../include/memory.h"
                     71: #include "custom.h"
                     72: #include "readcpu.h"
                     73: #include "newcpu.h"
                     74: #include "xwin.h"
                     75: #include "keyboard.h"
                     76: #include "keybuf.h"
                     77: #include "disk.h"
                     78: #include "debug.h"
                     79: #include "gui.h"
                     80: 
                     81: /****************************************************************************/
                     82: 
                     83: #define use_dither      (!no_xhair)
                     84: 
                     85: static int need_dither;        /* well.. guess :-) */
                     86: static int use_low_bandwidth;  /* this will redraw only needed places */
                     87: static int use_cyb;            /* this is for cybergfx */
                     88: static int use_graffiti;
                     89: 
                     90: xcolnr xcolors[4096];
                     91: 
                     92:  /* Keyboard and mouse */
                     93: 
                     94: static int keystate[256];
                     95: 
                     96: int buttonstate[3];
                     97: int lastmx, lastmy;
                     98: int newmousecounters;
                     99: 
                    100: static int inwindow;
                    101: 
                    102: static char *oldpixbuf;
                    103: 
                    104: struct vidbuf_description gfxvidinfo;
                    105: 
                    106: /****************************************************************************/
                    107: /*
                    108:  * prototypes & global vars
                    109:  */
                    110: struct IntuitionBase    *IntuitionBase;
                    111: struct GfxBase          *GfxBase;
                    112: struct Library          *AslBase;
                    113: struct Library          *CyberGfxBase;
                    114: 
                    115: static UBYTE            *Line;
                    116: static struct RastPort  *RP;
                    117: static struct Screen    *S;
                    118: static struct Window    *W;
                    119: static struct RastPort  *TempRPort;
                    120: static struct BitMap    *BitMap;
                    121: static struct ColorMap  *CM;
                    122: static Object           *Pointer; /* for os 39 */
                    123: static UWORD            *Sprite;
                    124: 
                    125: static int os39;        /* kick 39 present */
                    126: static int usepub;      /* use public screen */
                    127: static int halfv;       /* halve height for non interlaced screen */
                    128: static int usecyb;      /* use cybergraphics.library */
                    129: static int is_halfbrite;
                    130: 
                    131: static int   get_color_failed;
                    132: static int   maxpen;
                    133: static UBYTE pen[256];
                    134: 
                    135: static struct BitMap *myAllocBitMap(ULONG,ULONG,ULONG,ULONG,struct BitMap *);
                    136: static void set_title(void);
                    137: static void myFreeBitMap(struct BitMap *);
                    138: static LONG ObtainColor(ULONG, ULONG, ULONG);
                    139: static void ReleaseColors(void);
                    140: static void DoSizeWindow(struct Window *,int,int);
                    141: static void disk_hotkeys(void);
                    142: static void graffiti_SetRGB(int,int,int,int);
                    143: static void graffiti_WritePixelLine8(int,int,short,char*);
                    144: 
                    145: /****************************************************************************/
                    146: 
                    147: void main_window_led(int led, int on);
                    148: 
                    149: extern int  rexx_init(void);
                    150: extern void rexx_exit(void);
                    151: extern void initpseudodevices(void);
                    152: extern void closepseudodevices(void);
                    153: extern char *to_unix_path(char *s);
                    154: extern char *from_unix_path(char *s);
                    155: extern void split_dir_file(char *src, char **dir, char **file);
                    156: 
                    157: /****************************************************************************/
                    158: 
                    159: static RETSIGTYPE sigbrkhandler(int foo)
                    160: {
                    161:     activate_debugger();
                    162: }
                    163: 
                    164: void setup_brkhandler(void)
                    165: {
                    166:     struct sigaction sa;
                    167:     sa.sa_handler = sigbrkhandler;
                    168:     sa.sa_flags = 0;
                    169:     sa.sa_flags = SA_RESTART;
                    170:     sigemptyset(&sa.sa_mask);
                    171:     sigaction(SIGINT, &sa, NULL);
                    172: }
                    173: 
                    174: /****************************************************************************/
                    175: 
                    176: __inline__ void flush_line(int y)
                    177: {
                    178:     int xs = 0, len;
                    179:     int yoffset = y*gfxvidinfo.rowbytes;
                    180:     char *linebuf = gfxvidinfo.bufmem + yoffset;
                    181:     char *src, *dst;
                    182: 
                    183:     if(y<0 || y>=gfx_requested_height) {
                    184: /*       printf("flush_line out of window: %d\n", y); */
                    185:        return;
                    186:     }
                    187: 
                    188:     if(halfv && (y&1)) return;
                    189: 
                    190:     /*
                    191:      * cybergfx bitmap && no dither
                    192:      */
                    193:     if(use_cyb && !need_dither) {
                    194:         APTR handle;
                    195:         char *baseaddr;
                    196:         
                    197:         handle = LockBitMapTags(RP,LBMI_BASEADDRESS,(LONG)&baseaddr,TAG_DONE);
                    198:         if(handle) {
                    199:             CopyMem(linebuf, baseaddr + yoffset, gfxvidinfo.rowbytes);
                    200:             UnLockBitMap(handle);
                    201:         }
                    202:         return;
                    203:     }
                    204: 
                    205: #if 0
                    206:     if(use_graffiti && !need_dither) {
                    207:         graffiti_WritePixelLine8(0, y, gfxvidinfo.rowbytes, linebuf);
                    208:     }
                    209: #endif
                    210: 
                    211:     /*
                    212:      * cybergfx && dither \_ LOW_BANDWIDTH and 1 byte per pixel in the output
                    213:      * or standard screen / 
                    214:      */
                    215:     len = gfxvidinfo.maxlinetoscr?gfxvidinfo.maxlinetoscr:gfx_requested_width;
                    216: 
                    217:     switch(gfxvidinfo.pixbytes) {
                    218:       case 4: 
                    219:         {   /* sam: we should not arrive here on the amiga */
                    220:             fprintf(stderr, "Bug in flush_line() !\n");
                    221:             abort();
                    222:             return;
                    223:         } break;
                    224:       case 2:
                    225:         {   short *newp = (short *)linebuf;
                    226:             short *oldp = (short *)(oldpixbuf + yoffset);
                    227:             while (*newp++ == *oldp++) if(!--len) return;
                    228:             src   = (char *)--newp; 
                    229:             dst   = (char *)--oldp; 
                    230:             newp += len;
                    231:             oldp += len;
                    232:             while (*--newp == *--oldp);
                    233:             len   = 1 + (oldp - (short *)dst);
                    234:             xs    = (src - linebuf)/2;
                    235:             CopyMem (src, dst, len * 2);
                    236:         } break;
                    237:       case 1:
                    238:         {   char *newp = (char *)linebuf;
                    239:             char *oldp = (char *)(oldpixbuf + yoffset);
                    240:             while (*newp++ == *oldp++) if(!--len) return;
                    241:             src   = (char *)--newp;
                    242:             dst   = (char *)--oldp; 
                    243:             newp += len;
                    244:             oldp += len;
                    245:             while (*--newp == *--oldp);
                    246:             len   = 1 + (oldp - (char *)dst);
                    247:             xs    = (src - linebuf);
                    248:             CopyMem (src, dst, len);
                    249:         } break;
                    250:       default:
                    251:         abort();
                    252:         break;
                    253:       }
                    254:     
                    255:     if(halfv) y>>=1;
                    256: 
                    257:     if (need_dither) {
                    258:         DitherLine(Line, (UWORD *)dst, xs, y, (len+3)&~3, 8);
                    259:     } else CopyMem(dst, Line, len); 
                    260:     
                    261:     if (use_cyb) { /* pixbyte == 1 */
                    262:         APTR handle;
                    263:         char *baseaddr;
                    264:         
                    265:         handle = LockBitMapTags(RP,LBMI_BASEADDRESS,(LONG)&baseaddr,TAG_DONE);
                    266:         if(handle) {
                    267:             CopyMem(Line, baseaddr + yoffset + xs, len);
                    268:             UnLockBitMap(handle);
                    269:         }
                    270:     } else if(use_graffiti) {
                    271:         graffiti_WritePixelLine8(xs, y, len, Line);
                    272:     } else WritePixelLine8(RP, xs, y, len, Line, TempRPort);
                    273: }
                    274: 
                    275: /****************************************************************************/
                    276: 
                    277: void flush_block (int ystart, int ystop)
                    278: {
                    279:     int y;
                    280:     for(y=ystart; y<=ystop; ++y) flush_line(y);
                    281: }
                    282: 
                    283: /****************************************************************************/
                    284: 
                    285: void flush_screen (int ystart, int ystop)
                    286: {
                    287: /* WaitBOVP() ? */
                    288: }
                    289: 
                    290: /****************************************************************************/
                    291: 
                    292: static int RPDepth(struct RastPort *RP)
                    293: {
                    294: #ifdef USE_CYBERGFX
                    295:    if(use_cyb) return GetCyberMapAttr(RP->BitMap,CYBRMATTR_DEPTH);
                    296: #endif
                    297:    if(use_graffiti) return 8;
                    298:    return RP->BitMap->Depth;
                    299: }
                    300: 
                    301: /****************************************************************************/
                    302: 
                    303: static int get_color(int r, int g, int b, xcolnr *cnp)
                    304: {
                    305:     int col;
                    306: 
                    307:     r *= 0x11111111;
                    308:     g *= 0x11111111;
                    309:     b *= 0x11111111;
                    310:     col = ObtainColor(r, g, b);
                    311: 
                    312:     if(col == -1) {
                    313:         get_color_failed = 1;
                    314:         return 0;
                    315:     }
                    316: 
                    317:     *cnp = col;
                    318:     return 1;
                    319: }
                    320: 
                    321: /****************************************************************************/
                    322: /*
                    323:  * FIXME: find a better way to determine closeness of colors (closer to
                    324:  * human perception).
                    325:  */
                    326: static __inline__ int calc_err(int r1, int g1, int b1,
                    327:                                int r2, int g2, int b2)
                    328: {
                    329:     int err = 0; 
                    330: 
                    331:     if((r1>7 && r2<=7) || (r1<=7 && r2>7)) err += 1;
                    332:     if((g1>7 && g2<=7) || (g1<=7 && g2>7)) err += 1;
                    333:     if((b1>7 && b2<=7) || (b1<=7 && b2>7)) err += 1;
                    334: 
                    335:     r1 -= r2; g1 -= g2; b1 -= b2;
                    336:     r1 *= 2;  g1 *= 3;  b1 *= 1;
                    337:     err += r1*r1 + g1*g1 + b1*b1;
                    338: 
                    339:     return err;
                    340: }
                    341: 
                    342: /****************************************************************************/
                    343: 
                    344: static int get_nearest_color(int r, int g, int b)
                    345: {
                    346:     int i, best, err, besterr;
                    347:     int colors;
                    348:     int br=0,bg=0,bb=0;
                    349: 
                    350:     best    = 0;
                    351:     besterr = calc_err(0,0,0, 15,15,15);
                    352:     colors  = is_halfbrite?32:(1<<RPDepth(RP));
                    353:   
                    354:     for(i=0; i<colors; i++ ) {
                    355:         long rgb = GetRGB4(CM, i);
                    356:         int cr, cg, cb;
                    357:         
                    358:         cr = (rgb >> 8) & 15;
                    359:         cg = (rgb >> 4) & 15;
                    360:         cb = (rgb >> 0) & 15;
                    361:           
                    362:         err = calc_err(r,g,b, cr,cg,cb);
                    363:         
                    364:         if(err < besterr) {
                    365:             best = i;
                    366:             besterr = err;
                    367:             br=cr; bg=cg; bb=cb;
                    368:         }
                    369: 
                    370:         if(is_halfbrite) {
                    371:             cr /= 2; cg /= 2; cb /= 2;
                    372:             err = calc_err(r,g,b, cr,cg,cb);
                    373:             if(err < besterr) {
                    374:                 best = i + 32;
                    375:                 besterr = err;
                    376:                 br=cr; bg=cg; bb=cb;
                    377:             }
                    378:         }
                    379:     }
                    380:     return best;
                    381: }
                    382: 
                    383: /****************************************************************************/
                    384: 
                    385: static int init_colors(void)
                    386: {
                    387:     if (need_dither) {
                    388:         /* first try color allocation */
                    389:         int bitdepth = usepub ? RPDepth(RP) : 8;
                    390:         int maxcol;
                    391: 
                    392:         if(bitdepth>=3)
                    393:         do {
                    394:             get_color_failed = 0;
                    395:             setup_dither(bitdepth, get_color);
                    396:             if(get_color_failed) ReleaseColors();
                    397:         } while(get_color_failed && --bitdepth>=3);
                    398:         
                    399:         if(bitdepth >= 3) {
                    400:             printf("Color dithering with %d bits\n",bitdepth);
                    401:             return 1;
                    402:         }
                    403: 
                    404:         /* if that fail then try grey allocation */
                    405:         maxcol = 1<<(usepub ? RPDepth(RP) : 8);
                    406: 
                    407:         do {
                    408:             get_color_failed = 0;
                    409:             setup_greydither_maxcol(maxcol, get_color);
                    410:             if(get_color_failed) ReleaseColors();
                    411:         } while(get_color_failed && --maxcol>=2);
                    412:         
                    413:         if (maxcol >= 2) {
                    414:             printf("Gray dither with %d shades\n",maxcol);
                    415:             return 1;
                    416:         }
                    417:         
                    418:         return 0; /* everything failed :-( */
                    419:     }
                    420:     
                    421:     /* No dither */
                    422:     switch(RPDepth(RP)) {
                    423:       case 6: if (is_halfbrite) {
                    424:         static int tab[]={
                    425:         0x000, 0x00f, 0x0f0, 0x0ff, 0x08f, 0x0f8, 0xf00, 0xf0f,
                    426:         0x80f, 0xff0, 0xfff, 0x88f, 0x8f0, 0x8f8, 0x8ff, 0xf08,
                    427:         0xf80, 0xf88, 0xf8f, 0xff8, /* end of regular pattern */
                    428:         0xa00, 0x0a0, 0xaa0, 0x00a, 0xa0a, 0x0aa, 0xaaa,
                    429:         0xfaa, 0xf6a, 0xa80, 0x06a, 0x6af };
                    430:         int i;
                    431:         for(i=0;i<32;++i) get_color(tab[i]>>8, (tab[i]>>4)&15, tab[i]&15, xcolors);
                    432:         for(i=0;i<4096;++i) xcolors[i] = get_nearest_color(i>>8, (i>>4)&15, i&15);
                    433:         break;
                    434:       }
                    435: 
                    436:       case 1: case 2: case 3: case 4: case 5: case 7: case 8: {
                    437:         int maxcol = 1<<RPDepth(RP);
                    438: 
                    439:         if(maxcol>=8) do {
                    440:             get_color_failed = 0;
                    441:             setup_maxcol(maxcol);
                    442:             alloc_colors256(get_color);
                    443:             if(get_color_failed) ReleaseColors();
                    444:         } while(get_color_failed && --maxcol>=8);
                    445:         else {
                    446:             int i;
                    447:             for(i=0;i<maxcol;++i) {
                    448:                 get_color((i*15)/(maxcol-1), (i*15)/(maxcol-1), 
                    449:                           (i*15)/(maxcol-1), xcolors);
                    450:             }
                    451:         }
                    452:         printf("Using %d colors\n",maxcol);
                    453:         for(maxcol=0;maxcol<4096;++maxcol) 
                    454:             xcolors[maxcol] = get_nearest_color(maxcol>>8, (maxcol>>4)&15, 
                    455:                                                 maxcol&15);
                    456:         } break;
                    457: 
                    458:       case 15:
                    459:         alloc_colors64k(5,5,5,10,5,0);
                    460:         break;
                    461: 
                    462:       case 16:
                    463:         alloc_colors64k(5,6,5,11,5,0);
                    464:         break;
                    465: 
                    466:       case 24: case 32:
                    467:         alloc_colors64k(8,8,8,16,8,0);
                    468:         break;
                    469:     }
                    470:     return 1;
                    471: }
                    472: 
                    473: /****************************************************************************/
                    474: 
                    475: static void setup_sprite(struct Window *W)
                    476: {
                    477:     Sprite = AllocVec(4+2, MEMF_CHIP|MEMF_CLEAR);
                    478:     if(!Sprite) {
                    479:        fprintf(stderr, "Warning: Can not alloc sprite buffer !\n");
                    480:        return;
                    481:     }
                    482:     Sprite[2] = 0x8000; Sprite[3] = 0x8000;
                    483:     SetPointer(W, Sprite, 1, 16, -1, 0);
                    484: }
                    485: 
                    486: /****************************************************************************/
                    487: 
                    488: static int setup_customscreen(void)
                    489: {
                    490:     static struct NewScreen NewScreenStructure = {
                    491:         0,0, 800,600, 3, 0,1,
                    492:         LACE+HIRES, CUSTOMSCREEN|SCREENQUIET|SCREENBEHIND,
                    493:         NULL, (void*)"UAE", NULL, NULL};
                    494:     static struct NewWindow NewWindowStructure = {
                    495:         0,0, 800,600, 0,1,
                    496:         IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_DISKINSERTED|IDCMP_DISKREMOVED|
                    497:         IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW|IDCMP_MOUSEMOVE,
                    498:         WFLG_SMART_REFRESH|WFLG_BACKDROP|WFLG_RMBTRAP|WFLG_NOCAREREFRESH|
                    499:         WFLG_BORDERLESS|WFLG_WINDOWACTIVE|WFLG_REPORTMOUSE,
                    500:         NULL, NULL, (void*)"UAE", NULL, NULL, 5,5, 800,600,
                    501:         CUSTOMSCREEN};
                    502: 
                    503:     NewScreenStructure.Width     = gfx_requested_width;
                    504:     NewScreenStructure.Height    = gfx_requested_height;
                    505:     NewScreenStructure.Depth     = os39?8:(gfx_requested_lores?5:4);
                    506:     NewScreenStructure.ViewModes = SPRITES | (gfx_requested_lores ? NULL : HIRES) |
                    507:                                    (correct_aspect ? LACE : NULL);
                    508:   
                    509:     do S = (void*)OpenScreen(&NewScreenStructure);
                    510:     while(!S && --NewScreenStructure.Depth);
                    511:     if(!S) {
                    512:         fprintf(stderr, "Can't open custom screen !\n");
                    513:         return 0;
                    514:     }
                    515: 
                    516:     CM = S->ViewPort.ColorMap;
                    517:     RP = &S->RastPort;
                    518: 
                    519:     NewWindowStructure.Width  = S->Width;
                    520:     NewWindowStructure.Height = S->Height;
                    521:     NewWindowStructure.Screen = S;
                    522:     W = (void*)OpenWindow(&NewWindowStructure);
                    523:     if(!W) {
                    524:         fprintf(stderr, "Can't open window on custom screen !\n");
                    525:         return 0;
                    526:     }
                    527:     setup_sprite(W);
                    528:     return 1;
                    529: }
                    530: 
                    531: /****************************************************************************/
                    532: 
                    533: static int setup_publicscreen(void)
                    534: {
                    535:     static struct NewWindow NewWindowStructure = {
                    536:         0,0, 800,600, 0,1,
                    537:         IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_DISKINSERTED|IDCMP_DISKREMOVED|
                    538:         IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW|IDCMP_MOUSEMOVE|
                    539:         IDCMP_CLOSEWINDOW,
                    540:         WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_SMART_REFRESH|WFLG_REPORTMOUSE|
                    541:         WFLG_RMBTRAP|WFLG_GIMMEZEROZERO|WFLG_ACTIVATE|WFLG_NOCAREREFRESH|
                    542:         WFLG_CLOSEGADGET,
                    543:         NULL, NULL, (void*)"UAE", NULL, NULL, 5,5, 800,600,
                    544:         PUBLICSCREEN};
                    545: 
                    546:     S = LockPubScreen(NULL);
                    547:     if(!S) {
                    548:         fprintf(stderr,"No public screen !\n");
                    549:         return 0;
                    550:     }
                    551: 
                    552:     CM = S->ViewPort.ColorMap;
                    553: 
                    554:     halfv = (S->ViewPort.Modes & (HIRES|LACE))==HIRES;
                    555: 
                    556:     NewWindowStructure.Width  = gfx_requested_width;
                    557:     NewWindowStructure.Height = gfx_requested_height >> (halfv?1:0);
                    558:     NewWindowStructure.Screen = S;
                    559:     
                    560:     W = (void*)OpenWindow(&NewWindowStructure);
                    561:     UnlockPubScreen(NULL, S);
                    562:     if(!W) {
                    563:         fprintf(stderr,"Can't open window on public screen !\n");
                    564:         CM = NULL;
                    565:         return 0;
                    566:     }
                    567:     DoSizeWindow(W, NewWindowStructure.Width, NewWindowStructure.Height);
                    568:     RP = W->RPort;
                    569:     setup_sprite(W);
                    570:     return 1;
                    571: }
                    572: 
                    573: /****************************************************************************/
                    574: 
                    575: static int setup_userscreen(void)
                    576: {
                    577:     struct ScreenModeRequester *ScreenRequest;
                    578:     ULONG DisplayID;
                    579:     static struct BitMap PointerBitMap;
                    580:     UWORD *PointerLine;
                    581:     LONG ScreenWidth=0,ScreenHeight=0,Depth=0;
                    582:     UWORD OverscanType=0;
                    583:     BOOL AutoScroll=0;
                    584: 
                    585: #ifdef USE_CYBERGFX
                    586:     if(!CyberGfxBase) CyberGfxBase = OpenLibrary("cybergraphics.library",40);
                    587: #endif
                    588:     if(!AslBase) AslBase = OpenLibrary("asl.library",38);
                    589:     if(!AslBase) {
                    590:         fprintf(stderr,"Can't open asl.library v38 !");
                    591:         return 0;
                    592:     }
                    593: 
                    594:     ScreenRequest = AllocAslRequest(ASL_ScreenModeRequest,NULL);
                    595:     if(!ScreenRequest) {
                    596:         fprintf(stderr,"Unable to allocate screen mode requester.\n");
                    597:         return 0;
                    598:     }
                    599: 
                    600:     if(AslRequestTags(ScreenRequest,
                    601:                       ASLSM_TitleText, (ULONG)"Select screen display mode",
                    602:                       ASLSM_InitialDisplayID,    NULL,
                    603:                       ASLSM_InitialDisplayDepth, 8,
                    604:                       ASLSM_InitialDisplayWidth, gfx_requested_width,
                    605:                       ASLSM_InitialDisplayHeight,gfx_requested_height,
                    606:                       ASLSM_MinWidth,            gfx_requested_width,
                    607:                       ASLSM_MinHeight,           gfx_requested_height,
                    608:                       ASLSM_DoWidth,             TRUE,
                    609:                       ASLSM_DoHeight,            TRUE,
                    610:                       ASLSM_DoDepth,             TRUE,
                    611:                       ASLSM_DoOverscanType,      TRUE,
                    612:                       ASLSM_PropertyFlags,       0,
                    613:                       ASLSM_PropertyMask,        DIPF_IS_DUALPF | 
                    614:                                                  DIPF_IS_PF2PRI | 
                    615:                                                  DIPF_IS_HAM    |
                    616:                                                  0,
                    617:                       TAG_DONE)) {
                    618:         ScreenWidth  = ScreenRequest->sm_DisplayWidth;
                    619:         ScreenHeight = ScreenRequest->sm_DisplayHeight;
                    620:         Depth        = ScreenRequest->sm_DisplayDepth;
                    621:         DisplayID    = ScreenRequest->sm_DisplayID;
                    622:         OverscanType = ScreenRequest->sm_OverscanType;
                    623:         AutoScroll   = ScreenRequest->sm_AutoScroll;
                    624:         if(ScreenWidth  < gfx_requested_width) ScreenWidth  = gfx_requested_width;
                    625:         if(ScreenHeight < gfx_requested_height) ScreenHeight = gfx_requested_height;
                    626:         }
                    627:     else DisplayID = INVALID_ID;
                    628:     FreeAslRequest(ScreenRequest);
                    629:     
                    630:     if(DisplayID == (ULONG)INVALID_ID) return 0;
                    631: 
                    632: #ifdef USE_CYBERGFX 
                    633:     if(CyberGfxBase && IsCyberModeID(DisplayID)) use_cyb = 1;
                    634: #endif
                    635: 
                    636:     S = OpenScreenTags(NULL,
                    637:                        SA_DisplayID,                  DisplayID,
                    638:                        SA_Width,                      ScreenWidth,
                    639:                        SA_Height,                     ScreenHeight,
                    640:                        SA_Depth,                      Depth,
                    641:                        SA_Overscan,                   OverscanType,
                    642:                        SA_AutoScroll,                 AutoScroll,
                    643:                        SA_ShowTitle,                  FALSE,
                    644:                        SA_Quiet,                      TRUE,
                    645:                        SA_Behind,                     TRUE,
                    646:                        /* v39 stuff here: */
                    647:                        (os39?SA_BackFill:TAG_DONE),   (ULONG)LAYERS_NOBACKFILL,
                    648:                        SA_SharePens,                  TRUE,
                    649:                        SA_Exclusive,                  (use_cyb?TRUE:FALSE),
                    650:                        SA_Draggable,                  (use_cyb?FALSE:TRUE),
                    651:                        SA_Interleaved,                TRUE,
                    652:                        TAG_DONE);
                    653:     if(!S) {
                    654:         fprintf(stderr,"Unable to open the screen.\n");
                    655:         return 0;
                    656:     }
                    657: 
                    658:     RP           = &S->RastPort;
                    659:     CM           = S->ViewPort.ColorMap;
                    660:     is_halfbrite = (S->ViewPort.Modes & EXTRA_HALFBRITE);
                    661: 
                    662: #ifdef USE_CYBERGFX 
                    663:     if(CyberGfxBase && !GetCyberMapAttr(RP->BitMap,CYBRMATTR_ISLINEARMEM)) {
                    664:         fprintf(stderr,"Cybergraphic screen is not in linear memory!\n");
                    665:         CloseScreen(S); S = NULL;
                    666:         use_cyb = 0;
                    667:         return 0;
                    668:     }
                    669: #endif
                    670: 
                    671:     PointerLine  = malloc(4);/* autodocs says it needs not be in chip memory */
                    672:     if(PointerLine) PointerLine[0]=PointerLine[1]=0;
                    673:     InitBitMap(&PointerBitMap,2,16,1);
                    674:     PointerBitMap.Planes[0] = (PLANEPTR)&PointerLine[0];
                    675:     PointerBitMap.Planes[1] = (PLANEPTR)&PointerLine[1];
                    676: 
                    677:     Pointer = NewObject(NULL,POINTERCLASS,
                    678:                         POINTERA_BitMap,        (ULONG)&PointerBitMap,
                    679:                         POINTERA_WordWidth,     1,
                    680:                         TAG_DONE);
                    681:     if(!Pointer)
                    682:         fprintf(stderr,"Warning: Unable to allocate blank mouse pointer.\n");
                    683: 
                    684:     W = OpenWindowTags(NULL,
                    685:                        WA_Width,                S->Width,
                    686:                        WA_Height,               S->Height,
                    687:                        WA_CustomScreen,         (ULONG)S,
                    688:                        WA_Backdrop,             TRUE,
                    689:                        WA_Borderless,           TRUE,
                    690:                        WA_RMBTrap,              TRUE,
                    691:                        WA_ReportMouse,          TRUE,
                    692:                        WA_IDCMP,                IDCMP_MOUSEBUTTONS|
                    693:                                                 IDCMP_RAWKEY|
                    694:                                                 IDCMP_DISKINSERTED|
                    695:                                                 IDCMP_DISKREMOVED|
                    696:                                                 IDCMP_ACTIVEWINDOW|
                    697:                                                 IDCMP_INACTIVEWINDOW|
                    698:                                                 IDCMP_MOUSEMOVE,
                    699:                        (os39?WA_BackFill:TAG_IGNORE), (ULONG)LAYERS_NOBACKFILL,
                    700:                        (Pointer?WA_Pointer:TAG_IGNORE), (ULONG)Pointer,
                    701:                        TAG_DONE);
                    702: 
                    703:     if(!W) {
                    704:         fprintf(stderr,"Unable to open the window.\n");
                    705:         CloseScreen(S);S=NULL;RP=NULL;CM=NULL;
                    706:         return 0;
                    707:     }
                    708:     if(!Pointer) setup_sprite(W);
                    709:     return 1;
                    710: }
                    711: 
                    712: /****************************************************************************/
                    713: 
                    714: static int setup_graffiti(void)
                    715: {
                    716:     static struct NewScreen NewScreenStructure = {
                    717:         0,-8, 800,600, 4, 0,1,
                    718:         HIRES, CUSTOMSCREEN|SCREENQUIET|SCREENBEHIND,
                    719:         NULL, (void*)"UAE", NULL, NULL};
                    720:     static struct NewWindow NewWindowStructure = {
                    721:         0,0, 800,600, 0,1,
                    722:         IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_DISKINSERTED|IDCMP_DISKREMOVED|
                    723:         IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW|IDCMP_MOUSEMOVE,
                    724:         WFLG_SMART_REFRESH|WFLG_BACKDROP|WFLG_RMBTRAP|WFLG_NOCAREREFRESH|
                    725:         WFLG_BORDERLESS|WFLG_WINDOWACTIVE|WFLG_REPORTMOUSE,
                    726:         NULL, NULL, (void*)"UAE", NULL, NULL, 5,5, 800,600,
                    727:         CUSTOMSCREEN};
                    728:     static short colarr[] = {
                    729:         0x000,0x001,0x008,0x009,0x080,0x081,0x088,0x089,
                    730:         0x800,0x801,0x808,0x809,0x880,0x881,0x888,0x889};
                    731:     int i;
                    732: 
                    733:     NewScreenStructure.Width     = 2*gfx_requested_width;
                    734:     /* I leave 8 extra lines for palette & mode: */
                    735:     NewScreenStructure.Height    = gfx_requested_height+8;  
                    736:     NewScreenStructure.Depth     = 4;
                    737:     NewScreenStructure.ViewModes = HIRES|GENLOCK_AUDIO|GENLOCK_VIDEO;
                    738:   
                    739:     S = (void*)OpenScreen(&NewScreenStructure);
                    740:     if(!S) {
                    741:         fprintf(stderr, "Can't open graffiti screen !\n");
                    742:         return 0;
                    743:     }
                    744: 
                    745:     for(i=0;i<15;++i) {
                    746:         unsigned int rgb = colarr[i];
                    747:         SetRGB4(&S->ViewPort,i,(rgb>>8)&15,(rgb>>4)&15,rgb&15);
                    748:     }
                    749: 
                    750:     CM = S->ViewPort.ColorMap;
                    751:     RP = &S->RastPort;
                    752: 
                    753:     NewWindowStructure.Width  = S->Width;
                    754:     NewWindowStructure.Height = S->Height;
                    755:     NewWindowStructure.Screen = S;
                    756:     W = (void*)OpenWindow(&NewWindowStructure);
                    757:     if(!W) {
                    758:         fprintf(stderr, "Can't open window on graffiti screen !\n");
                    759:         return 0;
                    760:     }
                    761:     setup_sprite(W);
                    762:     {
                    763:     /* make sure cmd part is cleared */
                    764:     int d;
                    765:     for(d = 0;d < 4; ++d) {
                    766:         short *p;
                    767:         int i;
                    768:         p = (void*)RP->BitMap->Planes[d];
                    769:         for(i=0;i<40*7;++i) p[i] = 0;
                    770:     }
                    771:     /* set graffiti mode to lores */
                    772:     *((short*)RP->BitMap->Planes[3]+8*40-1) = 0x0800;
                    773:     for(d=0;d<256;++d) graffiti_SetRGB(d,0,0,0);
                    774:     }
                    775: 
                    776:     return 1;
                    777: }
                    778: 
                    779: /****************************************************************************/
                    780: 
                    781: int graphics_init(void)
                    782: {
                    783:     int i,bitdepth;
                    784: 
                    785:     use_low_bandwidth = 0;
                    786:     need_dither = 0;
                    787:     use_cyb = 0;
                    788:     
                    789:     if (gfx_requested_width < 320)
                    790:        gfx_requested_width = 320;
                    791:     if (gfx_requested_height < 200)
                    792:        gfx_requested_height = 200;
                    793:     gfx_requested_width += 7;
                    794:     gfx_requested_width &= ~7;
                    795:     
                    796:     gfxvidinfo.maxlinetoscr = gfx_requested_width;
                    797:     gfxvidinfo.maxline = gfx_requested_height;
                    798: 
                    799:     if(color_mode == 3) {
                    800:        gfx_requested_width  = 320;
                    801:        gfx_requested_height = 320;
                    802:        gfx_requested_lores  = 1;
                    803:     } /* graffiti */
                    804:     
                    805:     if(SysBase->LibNode.lib_Version < 36) {
                    806:         fprintf(stderr, "UAE needs OS 2.0+ !\n");
                    807:         return 0;
                    808:     }
                    809:     os39   = (SysBase->LibNode.lib_Version>=39);
                    810: 
                    811:     atexit(graphics_leave);
                    812: 
                    813:     IntuitionBase = (void*)OpenLibrary("intuition.library",0L);
                    814:     if(!IntuitionBase) {
                    815:         fprintf(stderr,"No intuition.library ?\n");
                    816:         return 0;
                    817:     }
                    818:     GfxBase = (void*)OpenLibrary("graphics.library",0L);
                    819:     if(!GfxBase) {
                    820:         fprintf(stderr,"No graphics.library ?\n");
                    821:         return 0;
                    822:     }
                    823: 
                    824:     switch(color_mode) {
                    825:       case 3:
                    826:         if(setup_graffiti()) {use_graffiti = 1;break;}
                    827:         fprintf(stderr,"Asking user for screen...\n");
                    828:         /* fall trough */
                    829:       case 2:
                    830:         if(setup_userscreen()) break;
                    831:         fprintf(stderr,"Trying on public screen...\n");
                    832:         /* fall trough */
                    833:       case 1:
                    834:         is_halfbrite = 0;
                    835:         if(setup_publicscreen()) {usepub = 1;break;}
                    836:         fprintf(stderr,"Trying on custom screen...\n");
                    837:         /* fall trough */
                    838:       case 0:
                    839:       default:
                    840:         if(!setup_customscreen()) return 0;
                    841:         break;
                    842:     }
                    843: 
                    844:     Line = AllocVec((gfx_requested_width + 15) & ~15,MEMF_ANY|MEMF_PUBLIC);
                    845:     if(!Line) {
                    846:         fprintf(stderr,"Unable to allocate raster buffer.\n");
                    847:         return 0;
                    848:     }
                    849:     BitMap = myAllocBitMap(gfx_requested_width,1,8,BMF_CLEAR|BMF_MINPLANES,RP->BitMap);
                    850:     if(!BitMap) {
                    851:         fprintf(stderr,"Unable to allocate BitMap.\n");
                    852:         return 0;
                    853:     }
                    854:     TempRPort = AllocVec(sizeof(struct RastPort),MEMF_ANY|MEMF_PUBLIC);
                    855:     if(!TempRPort) {
                    856:         fprintf(stderr,"Unable to allocate RastPort.\n");
                    857:         return 0;
                    858:     }
                    859:     CopyMem(RP,TempRPort,sizeof(struct RastPort));
                    860:     TempRPort->Layer  = NULL;
                    861:     TempRPort->BitMap = BitMap;
                    862: 
                    863:     if(usepub) set_title();
                    864: 
                    865:     bitdepth = RPDepth(RP);
                    866:     if(bitdepth <= 8) {
                    867:         /* chunk2planar is slow so we define use_low_bandwidth for all modes
                    868:            except cybergraphics modes */
                    869:         use_low_bandwidth   = 1; 
                    870:         need_dither         = use_dither || (bitdepth<=1);
                    871:         gfxvidinfo.pixbytes = need_dither?2:1;
                    872:     } else {
                    873:         /* Cybergfx mode */
                    874:         gfxvidinfo.pixbytes = (bitdepth == 24 || bitdepth == 32 ? 4
                    875:                                : bitdepth == 12 || bitdepth == 16 ? 2
                    876:                                : 1);
                    877:     }
                    878:     
                    879:     if (!use_cyb) {
                    880:         gfxvidinfo.rowbytes = gfxvidinfo.pixbytes * gfx_requested_width;
                    881:         gfxvidinfo.bufmem = (char *)calloc(gfxvidinfo.rowbytes, gfx_requested_height+1);
                    882:         /*                                                           ^^ */
                    883:         /*            This is because DitherLine may read one extra row */
                    884:     } else {
                    885: #ifdef USE_CYBERGFX
                    886:         gfxvidinfo.rowbytes = GetCyberMapAttr(RP->BitMap,CYBRMATTR_XMOD);
                    887:         gfxvidinfo.pixbytes = GetCyberMapAttr(RP->BitMap,CYBRMATTR_BPPIX);
                    888:         gfxvidinfo.bufmem = (char *)calloc(gfxvidinfo.rowbytes, gfx_requested_height+1);
                    889: #endif
                    890:     } 
                    891:     if(!gfxvidinfo.bufmem) {
                    892:         fprintf(stderr,"Not enough memory.\n");
                    893:         return 0;
                    894:     } 
                    895: 
                    896:     if (use_low_bandwidth) {
                    897:         gfxvidinfo.maxblocklines = gfx_requested_height-1; /* it seems to increase the speed */
                    898:         oldpixbuf = (char *)calloc(gfxvidinfo.rowbytes, gfx_requested_height);
                    899:         if(!oldpixbuf) {
                    900:             fprintf(stderr,"Not enough memory for oldpixbuf.\n");
                    901:             return 0;
                    902:         }
                    903:     } else {
                    904:         gfxvidinfo.maxblocklines = 100; /* whatever... */
                    905:     }
                    906: 
                    907:     if (!init_colors())
                    908:         return 0;
                    909: 
                    910:     if(!usepub) ScreenToFront(S);
                    911: 
                    912:     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
                    913:     for(i=0; i<256; i++)
                    914:         keystate[i] = 0;
                    915:     
                    916:     lastmx = lastmy = 0; 
                    917:     newmousecounters = 0;
                    918:     inwindow = 0;
                    919: 
                    920:     rexx_init();
                    921:     initpseudodevices();
                    922: 
                    923:     return 1;
                    924: }
                    925: 
                    926: /****************************************************************************/
                    927: 
                    928: void graphics_leave(void)
                    929: {
                    930:     rexx_exit();
                    931:     closepseudodevices();
                    932:     if(BitMap) {
                    933:         WaitBlit();
                    934:         myFreeBitMap(BitMap);
                    935:         BitMap = NULL;
                    936:     }
                    937:     if(TempRPort) {
                    938:         FreeVec(TempRPort);
                    939:         TempRPort = NULL;
                    940:     }
                    941:     if(Line) {
                    942:         FreeVec(Line);
                    943:         Line = NULL;
                    944:     } 
                    945:     if(CM) {
                    946:         ReleaseColors();
                    947:         CM = NULL;
                    948:     }
                    949:     if(W) {
                    950:         CloseWindow(W);
                    951:         W = NULL;
                    952:     }
                    953:     if(Sprite) {
                    954:         FreeVec(Sprite);
                    955:         Sprite = NULL;
                    956:     }
                    957:     if(Pointer) {
                    958:         DisposeObject(Pointer);
                    959:         Pointer = NULL;
                    960:     }
                    961:     if(!usepub && S) {
                    962:         CloseScreen(S);
                    963:         S = NULL;
                    964:     }
                    965:     if(AslBase) {
                    966:         CloseLibrary((void*)AslBase);
                    967:         AslBase = NULL;
                    968:     }
                    969:     if(GfxBase) {
                    970:         CloseLibrary((void*)GfxBase);
                    971:         GfxBase = NULL;
                    972:     }
                    973:     if(IntuitionBase) {
                    974:         CloseLibrary((void*)IntuitionBase);
                    975:         IntuitionBase = NULL;
                    976:     }
                    977:     if(CyberGfxBase) {
                    978:         CloseLibrary((void*)CyberGfxBase);
                    979:         CyberGfxBase = NULL;
                    980:     }
                    981: }
                    982: 
                    983: 
                    984: /***************************************************************************/
                    985: 
                    986: void handle_events(void)
                    987: {
                    988:     struct IntuiMessage *msg;
                    989:     int mx,my,class,code;
                    990:   
                    991:     newmousecounters = 0;
                    992:     
                    993:     /*
                    994:      * This is a hack to simulate ^C as is seems that break_handler
                    995:      * is lost when system() is called.
                    996:      */
                    997:     if(SetSignal(0L, SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D) & 
                    998:                     (SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D)) {
                    999:         activate_debugger();
                   1000:     }
                   1001: 
                   1002:     while((msg=(struct IntuiMessage*)GetMsg(W->UserPort))) {
                   1003:         class = msg->Class;
                   1004:         code  = msg->Code;
                   1005:         mx    = msg->MouseX;
                   1006:         my    = msg->MouseY;
                   1007:         ReplyMsg((struct Message*)msg);
                   1008: 
                   1009:         if(usepub) {
                   1010:             mx -= W->BorderLeft;
                   1011:             my -= W->BorderTop;
                   1012:         }
                   1013: 
                   1014:         if(use_graffiti) {
                   1015:             my -= 8;
                   1016:         }
                   1017:       
                   1018:         switch(class) {
                   1019:           case CLOSEWINDOW:
                   1020:             activate_debugger();
                   1021:             break;
                   1022: 
                   1023:           case RAWKEY: {
                   1024:               int kc       = code&127;
                   1025:               int released = code&128?1:0;
                   1026:             
                   1027:               if(released) {
                   1028:                   keystate[kc] = 0;
                   1029:                   record_key ((kc << 1) | 1);
                   1030:               } else if (!keystate[kc])  {
                   1031:                   keystate[kc] = 1;
                   1032:                   record_key (kc << 1);
                   1033:               }
                   1034:           } break;
                   1035:           
                   1036:           case MOUSEMOVE:
                   1037:             if(inwindow) {
                   1038:                 lastmx = mx >> (use_graffiti?1:0);
                   1039:                 lastmy = my << (halfv?1:0);
                   1040:             } break;
                   1041: 
                   1042:           case MOUSEBUTTONS:
                   1043:             if(code==SELECTDOWN) buttonstate[0]=1;
                   1044:             if(code==SELECTUP)   buttonstate[0]=0;
                   1045:             if(code==MENUDOWN)   buttonstate[2]=1;
                   1046:             if(code==MENUUP)     buttonstate[2]=0;
                   1047:             break;
                   1048:         
                   1049:           /* Those 2 could be of some use later. */
                   1050:           case DISKINSERTED:
                   1051:             /*printf("diskinserted(%d)\n",code);*/
                   1052:             break;
                   1053:           
                   1054:           case DISKREMOVED:
                   1055:             /*printf("diskremoved(%d)\n",code);*/
                   1056:             break;
                   1057:                         
                   1058:           case ACTIVEWINDOW:
                   1059:             inwindow = 1;
                   1060:             newmousecounters = 1;
                   1061:             /* lastmx = mx >> ((use_graffiti?1:0);
                   1062:             lastmy = my<<(halfv?1:0); */
                   1063:             break;
                   1064:                         
                   1065:           case INACTIVEWINDOW:
                   1066:             inwindow = 0;
                   1067:             break;
                   1068:           
                   1069:           default:
                   1070:             fprintf(stderr, "Unknown class: %d\n",class);
                   1071:             break;
                   1072:         }
                   1073:     }
                   1074:     /* "Affengriff" */
                   1075:     if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI]) 
                   1076:         m68k_reset();
                   1077: 
                   1078:     /* PC-like :-) CTRL-ALT-DEL => reboot */
                   1079:     if(keystate[AK_CTRL] && (keystate[AK_LALT] || keystate[AK_RALT]) && 
                   1080:        keystate[AK_DEL]) 
                   1081:         m68k_reset();
                   1082: 
                   1083:     /* CTRL+LSHIFT+LALT+F10 on amiga => F12 on X11 */
                   1084:     /*                  F9           => ScrollLock on X11 (inhibit_frame) */
                   1085:     if(keystate[AK_CTRL] && keystate[AK_LSH] && keystate[AK_LALT]) {
                   1086:         if(keystate[AK_F10]) togglemouse();
                   1087:         if(keystate[AK_F9]) {
                   1088:             inhibit_frame ^= 1;
                   1089:             if(inhibit_frame) printf("display disabled\n");
                   1090:             else printf("display enabled\n");
                   1091:         }
                   1092:     }
                   1093: 
                   1094:     disk_hotkeys();
                   1095:     gui_handle_events();
                   1096: }
                   1097: 
                   1098: /***************************************************************************/
                   1099: 
                   1100: void target_specific_usage(void)
                   1101: {
                   1102:     printf("\n");
                   1103:     printf("----------------------------------------------------------------------------\n");
                   1104:     printf("AMIGA SPECIFIC USAGE:\n");
                   1105:     printf("  -S n                     : Sound emulation accuracy (n = 0, 1, 2 or 3)\n"
                   1106:            "                             For sound emulation, n = 2 is recommended\n");
                   1107:     printf("  -R n                     : Use n Hz to output sound. Common values are\n"
                   1108:            "                             22050 Hz or 44100 Hz\n");
                   1109:     printf("  -B n                     : Use a sound buffer of n bytes (use small\n"
                   1110:            "                             values on fast machines)\n");
                   1111:     printf("  -p command               : Use command to pipe printer output to.\n");
                   1112:     printf("  -I device                : Name of the used serial device (i.e. /dev/ttyS1\n");
                   1113:     printf("  -x                       : Does not use dithering\n");
                   1114:     printf("  On the amiga, Valid resolution (see -d) are:\n");
                   1115:     printf("     0, 1, 2 (320x256); 3 (640x512); 4 (800x600).\n");
                   1116:     printf("  And valid color modes (see -H) are:\n");
                   1117:     printf("     0 => 256 cols max on customscreen;\n");
                   1118:     printf("     1 => OpenWindow on default public screen;\n");
                   1119:     printf("     2 => Ask the user to select a screen mode with ASL requester;\n");
                   1120:     printf("     3 => use a 320x256 graffiti screen.\n");
                   1121:     printf("----------------------------------------------------------------------------\n");
                   1122:     printf("\n");
                   1123: }
                   1124: 
                   1125: /***************************************************************************/
                   1126: 
                   1127: int debuggable(void)
                   1128: {
                   1129:     return 1;
                   1130: }
                   1131: 
                   1132: /***************************************************************************/
                   1133: 
                   1134: int needmousehack(void)
                   1135: {
                   1136:     return 1;
                   1137: }
                   1138: 
                   1139: /***************************************************************************/
                   1140: 
                   1141: void LED(int on)
                   1142: {
                   1143: }
                   1144: 
                   1145: /***************************************************************************/
                   1146: 
                   1147: static int led_state[5];
                   1148: 
                   1149: static void set_title(void)
                   1150: {
                   1151:     static char title[80];
                   1152:     static char ScreenTitle[100];
                   1153: 
                   1154:     if(!usepub) return;
                   1155: 
                   1156:     sprintf(title,"UAE - Power: [%c] Drives: [%c] [%c] [%c] [%c]",
                   1157:             led_state[0]?'X':' ',
                   1158:             led_state[1]?'0':' ',
                   1159:             led_state[2]?'1':' ',
                   1160:             led_state[3]?'2':' ',
                   1161:             led_state[4]?'3':' ');
                   1162:     
                   1163:     if(!*ScreenTitle) {
                   1164:          sprintf(ScreenTitle,
                   1165:                  "UAE-%d.%d.%d � by Bernd Schmidt & contributors, "
                   1166:                  "Amiga Port by Samuel Devulder.",
                   1167:                   (version / 100) % 10, (version / 10) % 10, version % 10);
                   1168:         SetWindowTitles(W, title, ScreenTitle);
                   1169:     } else SetWindowTitles(W, title, (char*)-1);
                   1170: }
                   1171: 
                   1172: /****************************************************************************/
                   1173: 
                   1174: void main_window_led(int led, int on)                /* is used in amigui.c */
                   1175: {
                   1176:   if(led>=0 && led<=4) led_state[led] = on;
                   1177:   set_title();
                   1178: }
                   1179: 
                   1180: /****************************************************************************/
                   1181: 
                   1182: static void unrecord(int kc)
                   1183: {
                   1184:     keystate[kc] = 0;
                   1185:     record_key ((kc << 1) | 1);
                   1186: }
                   1187: 
                   1188: /****************************************************************************/
                   1189: 
                   1190: static void disk_hotkeys(void)
                   1191: {
                   1192:     struct FileRequester *FileRequest;
                   1193:     char buff[80];
                   1194:     int drive;
                   1195:     char *last_file,*last_dir,*s;
                   1196: 
                   1197:     if(!(keystate[AK_CTRL] && keystate[AK_LALT])) return;
                   1198: 
                   1199:     /* CTRL-LSHIFT-LALT F1-F4 => eject_disk */
                   1200:     if(keystate[AK_LSH]) {
                   1201:         int ok = 0;
                   1202: 
                   1203:         if(keystate[AK_F1]) {ok=1;disk_eject(0);
                   1204:                              printf("drive DF0: ejected\n");}
                   1205:         if(keystate[AK_F2]) {ok=1;disk_eject(1);
                   1206:                              printf("drive DF1: ejected\n");}
                   1207:         if(keystate[AK_F3]) {ok=1;disk_eject(2);
                   1208:                              printf("drive DF2: ejected\n");}
                   1209:         if(keystate[AK_F4]) {ok=1;disk_eject(3);
                   1210:                              printf("drive DF3: ejected\n");}
                   1211: 
                   1212:         if(ok) {
                   1213:             unrecord(AK_CTRL);unrecord(AK_LALT);unrecord(AK_LSH); 
                   1214:             unrecord(AK_F1);unrecord(AK_F2);  
                   1215:             unrecord(AK_F3);unrecord(AK_F4);
                   1216:         }
                   1217:         return;
                   1218:     }
                   1219: 
                   1220:     /* CTRL-LALT F1-F4 => insert_disk */
                   1221:     if(keystate[AK_F1])      {drive = 0;unrecord(AK_F1);}
                   1222:     else if(keystate[AK_F2]) {drive = 1;unrecord(AK_F2);}
                   1223:     else if(keystate[AK_F3]) {drive = 2;unrecord(AK_F3);}
                   1224:     else if(keystate[AK_F4]) {drive = 3;unrecord(AK_F4);}
                   1225:     else return;
                   1226:     unrecord(AK_CTRL);unrecord(AK_LALT); 
                   1227: 
                   1228:     switch(drive) {
                   1229:       case 0: last_file = df0; break;
                   1230:       case 1: last_file = df1; break;
                   1231:       case 2: last_file = df2; break;
                   1232:       case 3: last_file = df3; break;
                   1233:       default: return;
                   1234:     }
                   1235: 
                   1236:     split_dir_file(from_unix_path(last_file), &last_dir, &last_file);
                   1237:     if(!last_file) return;
                   1238:     if(!last_dir)  return;
                   1239: 
                   1240:     if(!AslBase) AslBase = OpenLibrary("asl.library",36);
                   1241:     if(!AslBase) {
                   1242:         fprintf(stderr,"Can't open asl.library v36 !");
                   1243:         return;
                   1244:     }
                   1245: 
                   1246:     FileRequest = AllocAslRequest(ASL_FileRequest,NULL);
                   1247:     if(!FileRequest) {
                   1248:         fprintf(stderr,"Unable to allocate file requester.\n");
                   1249:         return;
                   1250:     }
                   1251: 
                   1252:     sprintf(buff,"Select file to use for drive DF%d:",drive);
                   1253:     if(AslRequestTags(FileRequest,
                   1254:                       use_graffiti?TAG_IGNORE:
                   1255:                       ASLFR_Window,         (ULONG)W,
                   1256:                       ASLFR_TitleText,      (ULONG)buff,
                   1257:                       ASLFR_InitialDrawer,  (ULONG)last_dir,
                   1258:                       ASLFR_InitialFile,    (ULONG)last_file,
                   1259:                       ASLFR_InitialPattern, (ULONG)"(#?.adf#?|df?|?)",
                   1260:                       ASLFR_DoPatterns,     TRUE,
                   1261:                       ASLFR_RejectIcons,    TRUE,
                   1262:                       TAG_DONE)) {
                   1263:         free(last_file);
                   1264:         last_file = malloc(3 + strlen(FileRequest->fr_Drawer) +
                   1265:                            strlen(FileRequest->fr_File));
                   1266:         if((last_file)) {
                   1267:             s = last_file;
                   1268:             strcpy(s,FileRequest->fr_Drawer);
                   1269:             if(*s && !(s[strlen(s)-1]==':' || s[strlen(s)-1]=='/')) 
                   1270:                 strcat(s,"/");
                   1271:             strcat(s,FileRequest->fr_File);
                   1272:             last_file = to_unix_path(s);free(s);
                   1273:         }
                   1274:     } else {
                   1275:         free(last_file);
                   1276:         last_file = NULL;
                   1277:     }
                   1278:     FreeAslRequest(FileRequest);
                   1279:     free(last_dir);
                   1280: 
                   1281:     if(last_file) {
                   1282:         disk_insert(drive,last_file);
                   1283:         free(last_file);
                   1284:     }
                   1285: }
                   1286: 
                   1287: /****************************************************************************/
                   1288: /*
                   1289:  * Routines for OS2.0 (code taken out of mpeg_play by Michael Balzer)
                   1290:  */
                   1291: static struct BitMap *myAllocBitMap(ULONG sizex, ULONG sizey, ULONG depth, 
                   1292:                                     ULONG flags, struct BitMap *friend_bitmap)
                   1293: {
                   1294:     struct BitMap *bm;
                   1295:     unsigned long extra;
                   1296:     
                   1297:     if(os39) return AllocBitMap(sizex, sizey, depth, flags, friend_bitmap);
                   1298:     
                   1299:     extra = (depth > 8) ? depth - 8 : 0;
                   1300:     bm = AllocVec( sizeof *bm + (extra * 4), MEMF_CLEAR );
                   1301:     
                   1302:     if( bm )
                   1303:       {
                   1304:           ULONG i;
                   1305:           InitBitMap(bm, depth, sizex, sizey);
                   1306:           for( i=0; i<depth; i++ )
                   1307:             {
                   1308:                 if( !(bm->Planes[i] = AllocRaster(sizex, sizey)) )
                   1309:                   {
                   1310:                       while(i--) FreeRaster(bm->Planes[i], sizex, sizey);
                   1311:                       FreeVec(bm);
                   1312:                       bm = 0;
                   1313:                       break;
                   1314:                   }
                   1315:             }
                   1316:       }
                   1317:     return bm;
                   1318: }
                   1319: 
                   1320: /****************************************************************************/
                   1321: 
                   1322: static void myFreeBitMap(struct BitMap *bm)
                   1323: {
                   1324:     if(os39) {FreeBitMap(bm);return;}
                   1325:     while(bm->Depth--)
                   1326:       FreeRaster(bm->Planes[bm->Depth], bm->BytesPerRow*8, bm->Rows);
                   1327:     FreeVec(bm);
                   1328: }
                   1329: 
                   1330: /****************************************************************************/
                   1331: /*
                   1332:  * find the best appropriate color return -1 if none is available
                   1333:  */
                   1334: static LONG ObtainColor(ULONG r,ULONG g,ULONG b)
                   1335: {
                   1336:     int i, crgb;
                   1337:     int colors;
                   1338: 
                   1339:     if(use_graffiti) {
                   1340:         if(maxpen >= 256) {
                   1341:             fprintf(stderr,"Asking more than 256 colors for graffiti ?\n");
                   1342:             abort();
                   1343:         }
                   1344:         graffiti_SetRGB(maxpen, r>>24, g>>24, b>>24);
                   1345:         return maxpen++;
                   1346:     }
                   1347: 
                   1348:     if(os39 && usepub) {
                   1349:         i = ObtainBestPen(CM,r,g,b,
                   1350:                           OBP_Precision, PRECISION_EXACT,
                   1351:                           OBP_FailIfBad, TRUE,
                   1352:                           TAG_DONE);
                   1353:         if(i != -1) {
                   1354:             if(maxpen<256) pen[maxpen++] = i;
                   1355:             else i = -1;
                   1356:         }
                   1357:         return i;
                   1358:     }
                   1359: 
                   1360:     r >>= 28; g >>= 28; b >>= 28;
                   1361:         
                   1362:     colors = is_halfbrite?32:(1<<RP->BitMap->Depth);
                   1363:   
                   1364:     /* private screen => standard allocation */
                   1365:     if(!usepub) {
                   1366:         if(maxpen >= colors) return -1; /* no more colors available */
                   1367:         SetRGB4(&S->ViewPort, maxpen, r, g, b);
                   1368:         return maxpen++;
                   1369:     }
                   1370: 
                   1371:     /* public => find exact match */
                   1372:     crgb = (r<<8)|(g<<4)|b;
                   1373:     for(i=0; i<colors; i++ ) {
                   1374:         int rgb = GetRGB4(CM, i);
                   1375:         if(rgb == crgb) return i;
                   1376:     }
                   1377:     return -1;
                   1378: }
                   1379: 
                   1380: /****************************************************************************/
                   1381: /*
                   1382:  * free a color entry
                   1383:  */
                   1384: static void ReleaseColors(void)
                   1385: {
                   1386:     if(os39 && usepub && CM) 
                   1387:         while(maxpen>0) ReleasePen(CM, pen[--maxpen]);
                   1388:     else maxpen = 0;
                   1389: }
                   1390: 
                   1391: /****************************************************************************/
                   1392: 
                   1393: static void DoSizeWindow(struct Window *W,int wi,int he)
                   1394: {
                   1395:     register int x,y;
                   1396:     
                   1397:     wi += W->BorderRight + W->BorderLeft;
                   1398:     he += W->BorderBottom + W->BorderTop;
                   1399:     x   = W->LeftEdge;
                   1400:     y   = W->TopEdge;
                   1401:     
                   1402:     if(x + wi >= W->WScreen->Width)  x = W->WScreen->Width - wi;
                   1403:     if(y + he >= W->WScreen->Height) y = W->WScreen->Height - he;
                   1404: 
                   1405:     if(x<0 || y<0) {
                   1406:         fprintf(stderr, "Working screen too small to open window (%dx%d)!\n",
                   1407:                 wi,he);
                   1408:         return;
                   1409:     }
                   1410:     
                   1411:     x  -= W->LeftEdge;
                   1412:     y  -= W->TopEdge;
                   1413:     wi -= W->Width;
                   1414:     he -= W->Height;
                   1415:     
                   1416:     if(x|y)   MoveWindow(W,x,y);
                   1417:     if(wi|he) SizeWindow(W,wi,he);
                   1418: }
                   1419: 
                   1420: /****************************************************************************/
                   1421: /*
                   1422:  * support code for graffiti card
                   1423:  */
                   1424: static void graffiti_SetRGB(int i, int r, int g, int b)
                   1425: {
                   1426:     UWORD **ptr = (void*)RP->BitMap->Planes;
                   1427: 
                   1428:     *(*ptr++ + i) = 0x0406;
                   1429:     *(*ptr++ + i) = (i<<8)|((g>>2)&0x3f);
                   1430:     *(*ptr++ + i) = 0x0606;
                   1431:     *(*ptr   + i) = ((r<<6)&0x3f00)|((b>>2)&0x3f);
                   1432: }
                   1433: 
                   1434: /****************************************************************************/
                   1435: 
                   1436: static void graffiti_WritePixelLine8(int x, int y, short len, char *line)
                   1437: {
                   1438: #if 0
                   1439:     /* standard code */
                   1440:     char **ptr = (void*)RP->BitMap->Planes;
                   1441: 
                   1442:     y += 8;
                   1443:     x += (y*80)<<2;
                   1444:     while(len--) {
                   1445:         *(ptr[x&3] + (x>>2)) = *line++;
                   1446:         ++x;
                   1447:     }
                   1448: #else
                   1449:     /* this one must be quite fast for 680x0 processor */
                   1450:     char **ptr;
                   1451:     char *ptr0,*ptr1,*ptr2,*ptr3;
                   1452:     ptr = (void*)RP->BitMap->Planes;
                   1453:     switch(x&3) {
                   1454:         case 0: ptr0=*ptr++;     ptr1=*ptr++;     ptr2=*ptr++;     ptr3=*ptr; break;
                   1455:         case 1: ptr3=*ptr++ + 1; ptr0=*ptr++;     ptr1=*ptr++;     ptr2=*ptr; break;
                   1456:         case 2: ptr2=*ptr++ + 1; ptr3=*ptr++ + 1; ptr0=*ptr++;     ptr1=*ptr; break;
                   1457:         default:
                   1458:         case 3: ptr1=*ptr++ + 1; ptr2=*ptr++ + 1; ptr3=*ptr++ + 1; ptr0=*ptr; break;
                   1459:     }
                   1460:     x >>= 2; x += (80*(y+8));
                   1461:     ptr0 += x; ptr1 += x; ptr2 += x; ptr3 += x;
                   1462:     ++len;
                   1463:     /* full speed here */
                   1464:     while(1) {
                   1465:         if(--len) *ptr0++ = *line++; else break;
                   1466:         if(--len) *ptr1++ = *line++; else break;
                   1467:         if(--len) *ptr2++ = *line++; else break;
                   1468:         if(--len) *ptr3++ = *line++; else break;
                   1469:     }
                   1470: #endif
                   1471: }

unix.superglobalmegacorp.com

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