Annotation of uae/src/od-amiga/ami-win.c, revision 1.1.1.3

1.1       root        1:  /* 
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   * 
                      4:   * Amiga interface
                      5:   * 
1.1.1.2   root        6:   * Copyright 1996,1997,1998 Samuel Devulder.
1.1       root        7:   */
                      8: 
                      9: /*
                     10:  * NOTE:
                     11:  *      - Im quite unhappy with the color allocation scheme in case of
                     12:  *        EXTRA_HALFBRITE...
                     13:  */
                     14: 
                     15: /*
                     16:  * History: (Day/Month/Year)
1.1.1.2   root       17:  *    long ago - Work begins; many things done; I should have kept the history
                     18:  *               log up-to-date.
1.1       root       19:  *    16/10/96 - Rewrote cybergfx support. (there is still a bug if the memory
                     20:  *               is not linear).
                     21:  *    15/11/96 - Inhibit the drive in readdevice().
                     22:  *    23/11/96 - Added call to rexx_init() and gui_handle_event().
                     23:  *    14/12/96 - Added support for graffiti screens.
                     24:  *    14/02/97 - Now uses SetRGB32() for cybergfx screens.
                     25:  *    15/02/97 - Dump iff file when ENV:UAEIFF is defined.
                     26:  *    25/02/97 - Get rid of cybergfx screen direct access.. Now uses 
                     27:  *               BltBitMapRastPort(). Thanks to Mats Eirik Hansen for
                     28:  *               his patch from which I'm widely inspired.
                     29:  *    10/05/97 - Use OpenWindowTag() for public screen. Uses Zoom,
                     30:  *               SimpleRefresh.
                     31:  *    20/08/97 - Removed halfv stuff (use correct_aspect instead).
                     32:  *    21/08/97 - Added HAM support (yeah!).
                     33:  *    05/10/97 - Added drag&drop support.
                     34:  *    13/10/97 - Fixed CyberGFX crash (a missing "return" in flush_line()).
                     35:  *    31/10/97 - Added support for gray output (-T). Added missing "Cyb" 
                     36:  *               prefix to BitMap=NULL in graphics_leave().
                     37:  *    07/12/97 - New calc_err(). UAE screen (-H2) is now a public screen.
1.1.1.2   root       38:  *    25/12/97 - Now use DELTAMOVE for mouse code. Use ENV:UAESM to use 
                     39:  *               pre-selected screenmode (-H2). Happy Chrismas!
                     40:  *    12/02/98 - Now use cybergfx bitmap only for 15+bit screens.
                     41:  *    22/02/98 - Added screen-flahses, exit-key and POWERUP code from 
                     42:  *               Holger Jakob.
                     43:  *    04/03/98 - Added do_inhibit_frame() for GUI feedback.
                     44:  *    06/03/98 - Added GetRGB4 cache in get_nearest_color() for POWERUP.
1.1       root       45:  */
                     46: 
1.1.1.2   root       47: #include "sysconfig.h"
                     48: #include "sysdeps.h"
                     49: 
                     50: /* sam: Argg!! Why did phase5 change the path to cybergraphics ? */
                     51: #define CGX_CGX_H <cybergraphics/cybergraphics.h>
                     52: 
                     53: #ifdef HAVE_LIBRARIES_CYBERGRAPHICS_H
                     54: #define USE_CYBERGFX           /* define this to have cybergraphics support */
                     55: #ifdef HAVE_CYBERGRAPHX_CYBERGRAPHICS_H
                     56: #undef  CGX_CGX_H
                     57: #define CGX_CGX_H <cybergraphx/cybergraphics.h>
                     58: #endif
                     59: #endif
1.1       root       60: 
                     61: /****************************************************************************/
                     62: 
                     63: #include <exec/execbase.h>
                     64: #include <exec/memory.h>
                     65: 
                     66: #include <dos/dos.h>
                     67: 
                     68: #include <graphics/gfxbase.h>
                     69: #include <graphics/displayinfo.h>
                     70: 
                     71: #include <libraries/asl.h>
                     72: #include <intuition/pointerclass.h>
                     73: 
1.1.1.2   root       74: /****************************************************************************/
                     75: 
                     76: #if defined(POWERUP) /* holger jakob */
                     77: #include <powerup/ppclib/interface.h>
                     78: #include <powerup/ppclib/object.h>
                     79: #include <powerup/clib/ppc_protos.h>
                     80: 
                     81: /* inlines are too unstable at the moment */
                     82: #ifndef USE_CLIB
                     83: #include <powerup/ppcproto/intuition.h>
                     84: #include <powerup/ppcproto/graphics.h> /* sam: beware I had to rebuild inlines to have ppcproto/graphics.h or else I only gor ppcinlines/graphics.h from phase5 package */
                     85: #include <powerup/ppcproto/exec.h>
                     86: #include <powerup/ppcproto/asl.h>
                     87: #else
                     88: /* These includes are needed instead */
                     89: #include <clib/exec_protos.h>
                     90: #include <clib/asl_protos.h>
                     91: #include <clib/intuition_protos.h>
                     92: #include <graphics/scale.h>
                     93: #include <clib/graphics_protos.h>
                     94: #define ObtainBestPen(a0, a1, a2, a3, tags...) \
                     95:        ({ULONG _tags[] = { tags }; ObtainBestPenA((a0), (a1), (a2), (a3), (struct TagItem *)_tags);})
                     96: #define OpenScreenTags(a0, tags...) \
                     97:        ({ULONG _tags[] = { tags }; OpenScreenTagList((a0), (struct TagItem *)_tags);})
                     98: #define OpenWindowTags(a0, tags...) \
                     99:        ({ULONG _tags[] = { tags }; OpenWindowTagList((a0), (struct TagItem *)_tags);})
                    100: #define AslRequestTags(a0, tags...) \
                    101:        ({ULONG _tags[] = { tags }; AslRequest((a0), (struct TagItem *)_tags);})
                    102: #define NewObject(a0, a1, tags...) \
                    103:        ({ULONG _tags[] = { tags }; NewObjectA((a0), (a1), (struct TagItem *)_tags);})
                    104: #endif
                    105: 
                    106: #undef  AllocVec
                    107: #undef  FreeVec
                    108: #define AllocVec PPCAllocVec
                    109: #define FreeVec  PPCFreeVec
                    110: 
                    111: /*extern struct ExecBase *SysBase;*/
                    112: struct GfxBase *GfxBase=NULL;
                    113: struct IntuitionBase   *IntuitionBase=NULL;
                    114: struct Library *CyberGfxBase=NULL;
                    115: 
                    116: #include <powerup/ppclib/interface.h>
                    117: /* Sam: this will prevent spilled register problem */
                    118: static void myBltBitMapRastPort(struct BitMap * srcBitMap, long xSrc, 
                    119:                                long ySrc, struct RastPort * destRP, 
                    120:                                long xDest, long yDest, long xSize, 
                    121:                                long ySize, unsigned long minterm);
                    122: static void myWritePixelLine8(struct RastPort*, int, int, int, char *, 
                    123:                              struct RastPort*);
                    124: static void myWritePixelArray8(struct RastPort*, int, int, int, int,
                    125:                               char *, struct RastPort*);
                    126: 
                    127: /****************************************************************************/
                    128: 
                    129: #else /* amigaos */
1.1       root      130: #include <proto/intuition.h>
                    131: #include <proto/graphics.h>
                    132: #include <proto/exec.h>
                    133: #include <proto/asl.h>
1.1.1.2   root      134: #define myBltBitMapRastPort BltBitMapRastPort
                    135: #define myWritePixelLine8   WritePixelLine8
                    136: #define myWritePixelArray8  WritePixelArray8
                    137: #endif
1.1       root      138: 
                    139: #ifdef USE_CYBERGFX
                    140: #ifdef __SASC
1.1.1.2   root      141:  #include CGX_CGX_H
                    142:  #include <proto/cybergraphics.h>
                    143: #else /* not SAS/C => gcc */
                    144:  #include CGX_CGX_H
                    145:  #if defined(POWERUP)
                    146:   #include <powerup/ppcproto/cybergraphics.h>
                    147:  #else /* AMIGAOS */
                    148:   #include <inline/cybergraphics.h>
                    149:  #endif
1.1       root      150: #endif
                    151: #ifndef BMF_SPECIALFMT
                    152: #define BMF_SPECIALFMT 0x80     /* should be cybergraphics.h but isn't for  */
                    153:                                 /* some strange reason */
                    154: #endif
1.1.1.2   root      155: #endif /* USE_CYBERGFX */
1.1       root      156: 
                    157: /****************************************************************************/
                    158: 
                    159: #include <ctype.h>
                    160: #include <signal.h>
                    161: #ifdef __GNUC__
                    162: #include <ix.h>
                    163: #endif
                    164: #ifdef __SASC
                    165: extern struct ExecBase *SysBase;
                    166: #endif
                    167: 
                    168: /****************************************************************************/
                    169: 
                    170: #include "config.h"
                    171: #include "options.h"
1.1.1.3 ! root      172: #include "threaddep/thread.h"
1.1       root      173: #include "uae.h"
                    174: #include "memory.h"
                    175: #include "custom.h"
                    176: #include "readcpu.h"
1.1.1.2   root      177: #include "include/memory.h" /* (or else it's od-amiga/memory.h that is used) */
1.1       root      178: #include "newcpu.h"
                    179: #include "xwin.h"
                    180: #include "keyboard.h"
                    181: #include "keybuf.h"
                    182: #include "gui.h"
                    183: #include "debug.h"
                    184: #include "disk.h"
                    185: 
                    186: #define BitMap Picasso96BitMap  /* Argh! */
                    187: #include "picasso96.h"
                    188: #undef BitMap 
                    189: 
                    190: /****************************************************************************/
                    191: 
                    192: #define use_dither      (!currprefs.no_xhair)
                    193: #define use_gray       (currprefs.use_mitshm)
                    194: 
                    195: #define UAEIFF "UAEIFF"        /* env: var to trigger iff dump */
1.1.1.2   root      196: #define UAESM  "UAESM"         /* env: var for screen mode */  
1.1       root      197: 
                    198: static int need_dither;        /* well.. guess :-) */
1.1.1.2   root      199: static int use_delta_buffer;   /* this will redraw only needed places */
                    200: static int use_cyb;            /* this is for cybergfx truecolor mode */
1.1       root      201: static int use_graffiti;
                    202: static int use_approx_color;
                    203: int dump_iff;
                    204: 
                    205: extern xcolnr xcolors[4096];
                    206: 
                    207:  /* Keyboard and mouse */
                    208: 
                    209: static int keystate[256];
                    210: 
                    211: extern int buttonstate[3];
                    212: extern int lastmx, lastmy;
                    213: extern int newmousecounters;
                    214: 
                    215: static int inwindow;
                    216: 
                    217: static char *oldpixbuf;
                    218: 
                    219: /****************************************************************************/
                    220: /*
                    221:  * prototypes & global vars
                    222:  */
                    223: struct IntuitionBase    *IntuitionBase;
                    224: struct GfxBase          *GfxBase;
                    225: struct Library          *AslBase;
                    226: struct Library          *CyberGfxBase;
                    227: 
1.1.1.2   root      228: unsigned long            frame_num; /* for arexx */
                    229: 
1.1       root      230: static UBYTE            *Line;
                    231: static struct RastPort  *RP;
                    232: static struct Screen    *S;
                    233: static struct Window    *W;
                    234: static struct RastPort  *TempRPort;
                    235: static struct BitMap    *BitMap;
                    236: #ifdef USE_CYBERGFX
                    237: static struct BitMap    *CybBitMap;
                    238: #endif
                    239: static struct ColorMap  *CM;
                    240: static Object           *Pointer; /* for os 39 */
                    241: static UWORD            *Sprite;
                    242: static int              XOffset,YOffset;
                    243: 
                    244: static int os39;        /* kick 39 present */
                    245: static int usepub;      /* use public screen */
                    246: static int usecyb;      /* use cybergraphics.library */
                    247: static int is_halfbrite;
                    248: static int is_ham;
                    249: 
                    250: static int   get_color_failed;
                    251: static int   maxpen;
                    252: static UBYTE pen[256];
                    253: 
                    254: static struct BitMap *myAllocBitMap(ULONG,ULONG,ULONG,ULONG,struct BitMap *);
                    255: static void set_title(void);
                    256: static void myFreeBitMap(struct BitMap *);
                    257: static LONG ObtainColor(ULONG, ULONG, ULONG);
                    258: static void ReleaseColors(void);
                    259: static int  DoSizeWindow(struct Window *,int,int);
                    260: static void disk_hotkeys(void);
                    261: static void graffiti_SetRGB(int,int,int,int);
                    262: static void graffiti_WritePixelLine8(int,int,short,char*);
                    263: static int  SaveIFF(char *filename, struct Screen *scr);
                    264: static int  init_ham(void);
                    265: static void ham_conv(UWORD *src, UBYTE *buf, UWORD len);
                    266: static int  RPDepth(struct RastPort *RP);
                    267: 
                    268: /****************************************************************************/
                    269: 
                    270: void main_window_led(int led, int on);
1.1.1.2   root      271: int do_inhibit_frame(int onoff);
1.1       root      272: 
                    273: extern int  rexx_init(void);
                    274: extern void rexx_exit(void);
                    275: extern void initpseudodevices(void);
                    276: extern void closepseudodevices(void);
                    277: extern char *to_unix_path(char *s);
                    278: extern char *from_unix_path(char *s);
                    279: extern void split_dir_file(char *src, char **dir, char **file);
                    280: extern void appw_init(struct Window *W);
                    281: extern void appw_exit(void);
                    282: extern void appw_events(void);
                    283: 
                    284: extern int ievent_alive;
                    285: 
                    286: /****************************************************************************/
                    287: 
                    288: static RETSIGTYPE sigbrkhandler(int foo)
                    289: {
                    290:     activate_debugger();
                    291: }
                    292: 
                    293: void setup_brkhandler(void)
                    294: {
                    295: #ifdef HAVE_SIGACTION
                    296:     struct sigaction sa;
                    297:     sa.sa_handler = (void*)sigbrkhandler;
                    298:     sa.sa_flags = 0;
                    299:     sa.sa_flags = SA_RESTART;
                    300:     sigemptyset(&sa.sa_mask);
                    301:     sigaction(SIGINT, &sa, NULL);
                    302: #else
                    303:     signal(SIGINT,sigbrkhandler);
                    304: #endif
                    305: }
                    306: 
                    307: /****************************************************************************/
1.1.1.2   root      308: /* This is because on powerup, calling 68k CopyMem is too slow              */
                    309: 
                    310: #ifdef CopyMem
                    311: #undef CopyMem
                    312: #endif
                    313: 
                    314: #ifdef POWERUP /* holger, sam: on powerup, use the alignment-optimised
                    315:                  code provided by memcpy() */
                    316: #define CopyMem(src,dst,len) memcpy(dst,src,len)
                    317: #else          /* holger, sam: else do not use ixemul memcpy() but
                    318:                   inline instead */
                    319: #define CopyMem(src,dst,len) myCopyMem(src,dst,len)
                    320: static __inline__ void myCopyMem(void *src, void *dst, int len)
                    321: {
                    322:     char *s=src;char *d=dst;
                    323:     if(len) do *d++=*s++; while(--len);
                    324: }
                    325: #endif
                    326: 
                    327: /****************************************************************************/
1.1       root      328: 
                    329: extern UBYTE cidx[4][8*4096];
                    330: 
                    331: __inline__ void flush_line(int y)
                    332: {
                    333:     int xs = 0, len;
                    334:     int yoffset = y*gfxvidinfo.rowbytes;
                    335:     char *linebuf = gfxvidinfo.bufmem + yoffset;
                    336:     char *src, *dst;
                    337: 
                    338:     if(y<0 || y>=gfxvidinfo.height) {
                    339: /*       printf("flush_line out of window: %d\n", y); */
                    340:        return;
                    341:     }
                    342: 
                    343:     len = gfxvidinfo.width;
                    344: 
                    345:     if(is_ham) {
                    346:         ham_conv((void*)linebuf,Line,len);
1.1.1.2   root      347:         myWritePixelLine8(RP, 0, y, len, Line, TempRPort);
1.1       root      348:         return;
                    349:     }
                    350: 
                    351: #ifdef USE_CYBERGFX
                    352:     /*
1.1.1.2   root      353:      * cybergfx bitmap
1.1       root      354:      */
1.1.1.2   root      355:     if(use_cyb) {
                    356:         myBltBitMapRastPort(CybBitMap, 0, y, 
1.1       root      357:                           RP, XOffset, YOffset+y, 
                    358:                           len, 1, 0xc0);
                    359:         /* sam: I'm worried because BltBitMapRastPort() is known to */
                    360:         /* produce spilled registers with gcc */
                    361:        return;
                    362:     }
                    363: #endif
                    364: 
                    365: #if 0
                    366:     if(use_graffiti && !need_dither) {
                    367:         graffiti_WritePixelLine8(0, y, gfxvidinfo.rowbytes, linebuf);
                    368:     }
                    369: #endif
                    370: 
1.1.1.2   root      371:     if(!use_delta_buffer) {
                    372:       dst = linebuf;
                    373:     } else switch(gfxvidinfo.pixbytes) {
1.1       root      374:       case 4: 
                    375:         {   /* sam: we should not arrive here on the amiga */
                    376:             fprintf(stderr, "Bug in flush_line() !\n");
                    377:             fprintf(stderr, "use_cyb=%d\n",use_cyb);
                    378:             fprintf(stderr, "need_dither=%d\n",need_dither);
                    379:             fprintf(stderr, "depth=%d\n",RPDepth(RP));
                    380:             fprintf(stderr, "Please return those values to maintainer.\n");
                    381:             abort();
                    382:             return;
                    383:         } break;
                    384:       case 2:
                    385:         {   short *newp = (short *)linebuf;
                    386:             short *oldp = (short *)(oldpixbuf + yoffset);
                    387:             while (*newp++ == *oldp++) if(!--len) return;
                    388:             src   = (char *)--newp; 
                    389:             dst   = (char *)--oldp; 
                    390:             newp += len;
                    391:             oldp += len;
                    392:             while (*--newp == *--oldp);
                    393:             len   = 1 + (oldp - (short *)dst);
                    394:             xs    = (src - linebuf)/2;
                    395:             CopyMem (src, dst, len * 2);
                    396:         } break;
                    397:       case 1:
                    398:         {   char *newp = (char *)linebuf;
                    399:             char *oldp = (char *)(oldpixbuf + yoffset);
                    400:             while (*newp++ == *oldp++) if(!--len) return;
                    401:             src   = (char *)--newp;
                    402:             dst   = (char *)--oldp; 
                    403:             newp += len;
                    404:             oldp += len;
                    405:             while (*--newp == *--oldp);
                    406:             len   = 1 + (oldp - (char *)dst);
                    407:             xs    = (src - linebuf);
                    408:             CopyMem (src, dst, len);
1.1.1.2   root      409:          } break;
1.1       root      410:       default:
                    411:         abort();
                    412:         break;
                    413:       }
1.1.1.2   root      414: 
1.1       root      415:     if (need_dither) {
                    416:         DitherLine(Line, (UWORD *)dst, xs, y, (len+3)&~3, 8);
                    417:     } else CopyMem(dst, Line, len); 
                    418:     
1.1.1.2   root      419:     if(use_graffiti) {
1.1       root      420:         graffiti_WritePixelLine8(xs, y, len, Line);
1.1.1.2   root      421:     } else myWritePixelLine8(RP, xs + XOffset, y + YOffset, len, Line, TempRPort);
1.1       root      422: }
                    423: 
                    424: /****************************************************************************/
                    425: 
                    426: void flush_block (int ystart, int ystop)
                    427: {
                    428:     int y;
                    429: #ifdef USE_CYBERGFX
1.1.1.2   root      430:     if(use_cyb) {
1.1       root      431:         int len = gfxvidinfo.width;
1.1.1.2   root      432:         myBltBitMapRastPort(CybBitMap, 
1.1       root      433:             0, ystart, 
                    434:             RP, XOffset, YOffset+ystart, 
                    435:             len, ystop-ystart+1, 0xc0);
                    436:         return;
                    437:     }
                    438: #endif
1.1.1.2   root      439: #if defined(POWERUP)
                    440:     /* sam: on powerup we have to minimize call to the 68k-OS, so better
                    441:        call WritePixelArray8(); once instead of several WritePixelLine8(); */
                    442:     if(!need_dither) {
                    443:        myWritePixelArray8(RP, XOffset, 
                    444:                             ystart + YOffset, 
                    445:                             XOffset + gfxvidinfo.width - 1,
                    446:                             ystop + YOffset, 
                    447:                             gfxvidinfo.bufmem + ystart*gfxvidinfo.rowbytes, 
                    448:                        TempRPort);
                    449:        return;
                    450:     }
                    451: #endif
1.1       root      452:     for(y=ystart; y<=ystop; ++y) flush_line(y);
                    453: }
                    454: 
                    455: /****************************************************************************/
                    456: 
1.1.1.2   root      457: static void save_frame(void)
1.1       root      458: {
                    459:     char *file;
                    460:     static int cpt = 0;
                    461:     char name[80];
                    462: 
                    463:     if(!dump_iff) return;
                    464:     if(!(file = getenv(UAEIFF))) return;
                    465:     if(strchr(file,'%')) sprintf(name,file,cpt++);
                    466:     else sprintf(name,"%s.%05d",file,cpt++);
                    467:     if(W->WScreen) SaveIFF(name,W->WScreen);
                    468: }
                    469: 
                    470: /****************************************************************************/
                    471: 
1.1.1.2   root      472: void flush_screen (int ystart, int ystop)
                    473: {
                    474: /* WaitBOVP() ? */
                    475: }
                    476: 
                    477: /****************************************************************************/
                    478: 
1.1       root      479: static int RPDepth(struct RastPort *RP)
                    480: {
                    481: #ifdef USE_CYBERGFX
                    482:    if(use_cyb) return GetCyberMapAttr(RP->BitMap,(LONG)CYBRMATTR_DEPTH);
                    483: #endif
                    484:    if(use_graffiti) return 8;
                    485:    return RP->BitMap->Depth;
                    486: }
                    487: 
                    488: /****************************************************************************/
                    489: 
                    490: static int get_color(int r, int g, int b, xcolnr *cnp)
                    491: {
                    492:     int col;
                    493: 
1.1.1.2   root      494:     if(use_gray) r = g = b = (77*r + 151*g + 29*b) / 16;
                    495:     else {r *= 0x11;g *= 0x11;b *= 0x11;}
1.1       root      496: 
1.1.1.2   root      497:     r *= 0x01010101;
                    498:     g *= 0x01010101;
                    499:     b *= 0x01010101;
1.1       root      500:     col = ObtainColor(r, g, b);
                    501: 
                    502:     if(col == -1) {
                    503:         get_color_failed = 1;
                    504:         return 0;
                    505:     }
                    506: 
                    507:     *cnp = col;
                    508:     return 1;
                    509: }
                    510: 
                    511: /****************************************************************************/
                    512: /*
                    513:  * FIXME: find a better way to determine closeness of colors (closer to
                    514:  * human perception).
                    515:  */
                    516: static __inline__ void rgb2xyz(int r, int g, int b,
                    517:                                int *x, int *y, int *z)
                    518: {
                    519:        *x = r*1024 - (g+b)*512;
                    520:        *y = 886*(g-b);
                    521:        *z = (r+g+b)*341;
                    522: }
                    523: static __inline__ int calc_err(int r1, int g1, int b1,
                    524:                                int r2, int g2, int b2)
                    525: {
                    526:     int x1,y1,z1,x2,y2,z2;
                    527: 
                    528:     rgb2xyz(r1,g1,b1,&x1,&y1,&z1);
                    529:     rgb2xyz(r2,g2,b2,&x2,&y2,&z2);
                    530:     x1 -= x2; y1 -= y2; z1 -= z2;
                    531:     return x1*x1 + y1*y1 + z1*z1;
                    532: }
                    533: 
                    534: /****************************************************************************/
                    535: 
                    536: static int get_nearest_color(int r, int g, int b)
                    537: {
                    538:     int i, best, err, besterr;
                    539:     int colors;
                    540:     int br=0,bg=0,bb=0;
1.1.1.2   root      541: #ifdef POWERUP
                    542:     static int *RGB_cache=NULL;
                    543: #endif
1.1       root      544: 
                    545:    if(use_gray) r = g = b = (77*r + 151*g + 29*b) / 256;
                    546: 
                    547:     best    = 0;
                    548:     besterr = calc_err(0,0,0, 15,15,15);
                    549:     colors  = is_halfbrite?32:(1<<RPDepth(RP));
                    550:   
1.1.1.2   root      551: #ifdef POWERUP
                    552:     if(!RGB_cache && 
                    553:        (RGB_cache = malloc(sizeof(*RGB_cache)*colors))) {
                    554:        /* note: The code can work if RGB_cache is not allocated ! */
                    555:        for(i=0;i<colors;++i) RGB_cache[i] = -1;
                    556:     }
                    557: #endif
                    558: 
1.1       root      559:     for(i=0; i<colors; i++ ) {
1.1.1.2   root      560:         long rgb;
1.1       root      561:         int cr, cg, cb;
1.1.1.2   root      562: 
                    563: #ifdef POWERUP
                    564:        /* sam: On powerup, calling GetRGB4() takes plenty of time. Holger
                    565:           Jakob told me that the remapping of the 4096 colors on a 256 color
                    566:           screen calls GetRGB4() more than 1000000 times, resulting in a loop
                    567:           lasting for more than one hour ! To fix this, we'll use a cache
                    568:           in order to avoid OS calls. CONCLUSION: ON POWERUP AVOID CALLING THE
                    569:            OS ROUTINES :((( */
                    570:        if(RGB_cache) {   
                    571:            rgb = RGB_cache[i];
                    572:            if(rgb<0) rgb = RGB_cache[i] = GetRGB4(CM,i);
                    573:        } else rgb = GetRGB4(CM,i);
                    574: #else
                    575:         rgb = GetRGB4(CM, i);
                    576: #endif
1.1       root      577:         cr = (rgb >> 8) & 15;
                    578:         cg = (rgb >> 4) & 15;
                    579:         cb = (rgb >> 0) & 15;
                    580:           
                    581:         err = calc_err(r,g,b, cr,cg,cb);
                    582:         
                    583:         if(err < besterr) {
                    584:             best = i;
                    585:             besterr = err;
                    586:             br=cr; bg=cg; bb=cb;
                    587:         }
                    588: 
                    589:         if(is_halfbrite) {
                    590:             cr /= 2; cg /= 2; cb /= 2;
                    591:             err = calc_err(r,g,b, cr,cg,cb);
                    592:             if(err < besterr) {
                    593:                 best = i + 32;
                    594:                 besterr = err;
                    595:                 br=cr; bg=cg; bb=cb;
                    596:             }
                    597:         }
                    598:     }
                    599:     return best;
                    600: }
                    601: 
                    602: /****************************************************************************/
                    603: 
                    604: static int init_colors(void)
                    605: {
                    606:     gfxvidinfo.can_double = 0;
                    607:     if (need_dither) {
                    608:         /* first try color allocation */
                    609:         int bitdepth = usepub ? 8 : RPDepth(RP);
                    610:         int maxcol;
                    611: 
                    612:         if(!use_gray && bitdepth>=3)
                    613:         do {
                    614:             get_color_failed = 0;
                    615:             setup_dither(bitdepth, get_color);
                    616:             if(get_color_failed) ReleaseColors();
                    617:         } while(get_color_failed && --bitdepth>=3);
                    618:         
                    619:         if(!use_gray && bitdepth>=3) {
                    620:             printf("Color dithering with %d bits\n",bitdepth);
                    621:             return 1;
                    622:         }
                    623: 
                    624:         /* if that fail then try grey allocation */
                    625:         maxcol = 1<<(usepub ? 8 : RPDepth(RP));
                    626: 
                    627:         do {
                    628:             get_color_failed = 0;
                    629:             setup_greydither_maxcol(maxcol, get_color);
                    630:             if(get_color_failed) ReleaseColors();
                    631:         } while(get_color_failed && --maxcol>=2);
                    632:         
                    633:         /* extra pass with approximated colors */
                    634:         if(get_color_failed) do {
                    635:             maxcol=2;
                    636:             use_approx_color = 1;
                    637:             get_color_failed = 0;
                    638:             setup_greydither_maxcol(maxcol, get_color);
                    639:             if(get_color_failed) ReleaseColors();
                    640:         } while(get_color_failed && --maxcol>=2);
                    641: 
                    642:         if (maxcol >= 2) {
                    643:             printf("Gray dither with %d shades.\n",maxcol);
                    644:             return 1;
                    645:         }
                    646:         
                    647:         return 0; /* everything failed :-( */
                    648:     }
                    649:     
                    650:     /* No dither */
                    651:     switch(RPDepth(RP)) {
                    652:       case 6: if (is_halfbrite) {
                    653:         static int tab[]={
                    654:         0x000, 0x00f, 0x0f0, 0x0ff, 0x08f, 0x0f8, 0xf00, 0xf0f,
                    655:         0x80f, 0xff0, 0xfff, 0x88f, 0x8f0, 0x8f8, 0x8ff, 0xf08,
                    656:         0xf80, 0xf88, 0xf8f, 0xff8, /* end of regular pattern */
                    657:         0xa00, 0x0a0, 0xaa0, 0x00a, 0xa0a, 0x0aa, 0xaaa,
                    658:         0xfaa, 0xf6a, 0xa80, 0x06a, 0x6af };
                    659:         int i;
                    660:         for(i=0;i<32;++i) get_color(tab[i]>>8, (tab[i]>>4)&15, tab[i]&15, xcolors);
                    661:         for(i=0;i<4096;++i) xcolors[i] = get_nearest_color(i>>8, (i>>4)&15, i&15);
                    662:         printf("Using %d colors + halfbrite\n",32);
                    663:         break;
                    664:       } else if(is_ham) {
                    665:         int i;
                    666:         for(i=0;i<16;++i) get_color(i,i,i, xcolors);
                    667:         printf("Using %d bits pseudo-truecolor (HAM).\n",12);
                    668:         alloc_colors64k(4,4,4,10,5,0);
                    669:         return init_ham();
                    670:       }
                    671: 
                    672:       case 1: case 2: case 3: case 4: case 5: case 7: case 8: {
                    673:         int maxcol = 1<<RPDepth(RP);
                    674: 
                    675:         if(maxcol>=8 && !use_gray) do {
                    676:             get_color_failed = 0;
                    677:             setup_maxcol(maxcol);
                    678:             alloc_colors256(get_color);
                    679:             if(get_color_failed) ReleaseColors();
                    680:         } while(get_color_failed && --maxcol>=8);
                    681:         else {
                    682:             int i;
                    683:             for(i=0;i<maxcol;++i) {
                    684:                 get_color((i*15)/(maxcol-1), (i*15)/(maxcol-1), 
                    685:                           (i*15)/(maxcol-1), xcolors);
                    686:             }
                    687:         }
                    688:         printf("Using %d colors.\n",maxcol);
                    689:         for(maxcol=0; maxcol<4096; ++maxcol)
                    690:             xcolors[maxcol] = get_nearest_color(maxcol>>8, (maxcol>>4)&15, 
                    691:                                                 maxcol&15);
                    692:         } break;
                    693: 
                    694:       case 15:
                    695:         printf("Using %d bits truecolor.\n",15);
                    696:         alloc_colors64k(5,5,5,10,5,0);
                    697:         break;
                    698: 
                    699:       case 16:
                    700:         printf("Using %d bits truecolor.\n",16);
                    701:         alloc_colors64k(5,6,5,11,5,0);
                    702:         break;
                    703: 
                    704:       case 24: 
                    705:         printf("Using %d bits truecolor.\n",24);
                    706:         alloc_colors64k(8,8,8,16,8,0);
                    707:         break;
                    708: 
                    709:       case 32: 
                    710:         printf("Using %d bits truecolor.\n",32);
                    711:         alloc_colors64k(8,8,8,16,8,0);
                    712:         break;
                    713:     }
                    714:     return 1;
                    715: }
                    716: 
                    717: /****************************************************************************/
                    718: 
1.1.1.2   root      719: static void setup_sprite(struct Window *W, int visible)
1.1       root      720: {
1.1.1.2   root      721:     Sprite = AllocVec((4+2)*sizeof(*Sprite), MEMF_CHIP|MEMF_CLEAR);
1.1       root      722:     if(!Sprite) {
                    723:        fprintf(stderr, "Warning: Can't alloc sprite buffer !\n");
                    724:        return;
                    725:     }
1.1.1.2   root      726:     if(visible) {Sprite[2] = 0x8000; Sprite[3] = 0x8000;}
1.1       root      727:     SetPointer(W, Sprite, 1, 16, -1, 0);
                    728: }
                    729: 
                    730: /****************************************************************************/
                    731: 
                    732: static int setup_customscreen(void)
                    733: {
                    734:     /* hum some of old programming style here :) */
                    735:     static struct NewScreen NewScreenStructure = {
                    736:         0,0, 800,600, 3, 0,1,
                    737:         LACE+HIRES, CUSTOMSCREEN|SCREENQUIET|SCREENBEHIND,
                    738:         NULL, (void*)"UAE", NULL, NULL};
                    739:     static struct NewWindow NewWindowStructure = {
                    740:         0,0, 800,600, 0,1,
                    741:         IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_DISKINSERTED|IDCMP_DISKREMOVED|
1.1.1.2   root      742:         IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW|IDCMP_MOUSEMOVE|
                    743:         IDCMP_DELTAMOVE,
1.1       root      744:         WFLG_SMART_REFRESH|WFLG_BACKDROP|WFLG_RMBTRAP|WFLG_NOCAREREFRESH|
1.1.1.2   root      745:         WFLG_BORDERLESS|WFLG_ACTIVATE|WFLG_REPORTMOUSE,
1.1       root      746:         NULL, NULL, (void*)"UAE", NULL, NULL, 5,5, 800,600,
                    747:         CUSTOMSCREEN};
                    748: 
                    749:     NewScreenStructure.Width     = currprefs.gfx_width;
                    750:     NewScreenStructure.Height    = currprefs.gfx_height;
                    751:     NewScreenStructure.Depth     = os39?8:(currprefs.gfx_lores?5:4);
                    752:     NewScreenStructure.ViewModes = SPRITES | (currprefs.gfx_lores?NULL:HIRES) |
                    753:                                    (currprefs.gfx_height>256?LACE:NULL);
                    754:   
                    755:     do S = (void*)OpenScreen(&NewScreenStructure);
                    756:     while(!S && --NewScreenStructure.Depth);
                    757:     if(!S) {
                    758:         fprintf(stderr, "Can't open custom screen !\n");
                    759:         return 0;
                    760:     }
                    761: 
                    762:     CM = S->ViewPort.ColorMap;
                    763:     RP = &S->RastPort;
                    764: 
                    765:     NewWindowStructure.Width  = S->Width;
                    766:     NewWindowStructure.Height = S->Height;
                    767:     NewWindowStructure.Screen = S;
                    768:     W = (void*)OpenWindow(&NewWindowStructure);
                    769:     if(!W) {
                    770:         fprintf(stderr, "Can't open window on custom screen !\n");
                    771:         return 0;
                    772:     }
1.1.1.2   root      773:     setup_sprite(W,0);
1.1       root      774:     return 1;
                    775: }
                    776: 
                    777: /****************************************************************************/
                    778: 
                    779: static int setup_publicscreen(void)
                    780: {
                    781:     UWORD ZoomArray[4] = {0,0,0,0};
                    782:   
                    783:     S = LockPubScreen(NULL);
                    784:     if(!S) {
                    785:         fprintf(stderr,"No public screen !\n");
                    786:         return 0;
                    787:     }
                    788: 
                    789:     ZoomArray[2] = 128;
                    790:     ZoomArray[3] = S->BarHeight+1;
                    791: 
                    792:     CM = S->ViewPort.ColorMap;
                    793: 
                    794:     if((S->ViewPort.Modes & (HIRES|LACE))==HIRES) {
                    795:         if(currprefs.gfx_height + S->BarHeight + 1 >= S->Height) {
                    796:             currprefs.gfx_height >>= 1;
                    797:             currprefs.gfx_correct_aspect = 1;
                    798:         }
                    799:     }
                    800: 
                    801:     W = OpenWindowTags(NULL,
                    802:                        WA_Title,        (ULONG)"UAE",
                    803:                        WA_AutoAdjust,   TRUE,
                    804:                        WA_InnerWidth,   currprefs.gfx_width,
                    805:                        WA_InnerHeight,  currprefs.gfx_height,
                    806:                        WA_PubScreen,    (ULONG)S,
                    807:                        WA_Zoom,         (ULONG)ZoomArray,
                    808:                        WA_IDCMP,        IDCMP_MOUSEBUTTONS|
                    809:                                         IDCMP_RAWKEY|
                    810:                                         IDCMP_ACTIVEWINDOW|
                    811:                                         IDCMP_INACTIVEWINDOW|
                    812:                                         IDCMP_MOUSEMOVE|
1.1.1.2   root      813:                                         IDCMP_DELTAMOVE|
1.1       root      814:                                         IDCMP_CLOSEWINDOW|
                    815:                                         IDCMP_REFRESHWINDOW|
                    816:                                         IDCMP_NEWSIZE|
                    817:                                         0,
                    818:                        WA_Flags,        WFLG_DRAGBAR|
                    819:                                         WFLG_DEPTHGADGET|
                    820:                                         WFLG_REPORTMOUSE|
                    821:                                         WFLG_RMBTRAP|
                    822:                                         WFLG_ACTIVATE|
                    823:                                         WFLG_CLOSEGADGET|
                    824:                                         WFLG_SMART_REFRESH|
                    825:                                         0,
                    826:                        TAG_DONE);
                    827:       
                    828:     UnlockPubScreen(NULL, S);
                    829: 
                    830:     if(!W) {
                    831:         fprintf(stderr,"Can't open window on public screen !\n");
                    832:         CM = NULL;
                    833:         return 0;
                    834:     }
                    835: 
                    836:     gfxvidinfo.width  = (W->Width  - W->BorderRight - W->BorderLeft);
                    837:     gfxvidinfo.height = (W->Height - W->BorderTop   - W->BorderBottom);
                    838:     XOffset = W->BorderLeft;
                    839:     YOffset = W->BorderTop;
                    840: 
                    841:     RP = W->RPort;
1.1.1.2   root      842:     setup_sprite(W,1);
1.1       root      843: 
                    844:     appw_init(W);
                    845: 
1.1.1.2   root      846: #ifdef USE_CYBERGFX
                    847:     if(CyberGfxBase && GetCyberMapAttr(RP->BitMap,(LONG)CYBRMATTR_ISCYBERGFX) &&
                    848:       (GetCyberMapAttr(RP->BitMap,(LONG)CYBRMATTR_DEPTH)>8)) use_cyb = 1;
                    849: #endif
                    850: 
1.1       root      851:     return 1;
                    852: }
                    853: 
                    854: /****************************************************************************/
                    855: 
1.1.1.2   root      856: static char *get_num(char *s, int *n)
                    857: {
                    858:    int i=0;
                    859:    while(isspace(*s)) ++s;
                    860:    if(*s=='0') {
                    861:      ++s;
                    862:      if(*s=='x' || *s=='X') {
                    863:        do {char c=*++s; 
                    864:            if(c>='0' && c<='9') {i*=16; i+= c-'0';}    else
                    865:            if(c>='a' && c<='f') {i*=16; i+= c-'a'+10;} else
                    866:            if(c>='A' && c<='F') {i*=16; i+= c-'A'+10;} else break;
                    867:        } while(1);
                    868:      } else while(*s>='0' && *s<='7') {i*=8; i+= *s++ - '0';}
                    869:    } else {
                    870:      while(*s>='0' && *s<='9') {i*=10; i+= *s++ - '0';}
                    871:    }
                    872:    *n=i;
                    873:    while(isspace(*s)) ++s;
                    874:    return s;
                    875: }
                    876: 
                    877: /****************************************************************************/
                    878: 
                    879: static void get_displayid(ULONG *DI, LONG *DE)
                    880: {
                    881:    char *s;
                    882:    int di,de;
                    883: 
                    884:    *DI=INVALID_ID;
                    885:    s=getenv(UAESM);if(!s) return;
                    886:    s=get_num(s,&di);
                    887:    if(*s!=':') return;
                    888:    s=get_num(s+1,&de);
                    889:    if(!de) return;
                    890:    *DI=di; *DE=de;
                    891: }
                    892: 
                    893: /****************************************************************************/
                    894: 
1.1       root      895: static int setup_userscreen(void)
                    896: {
                    897:     struct ScreenModeRequester *ScreenRequest;
                    898:     ULONG DisplayID;
                    899:     static struct BitMap PointerBitMap;
                    900:     UWORD *PointerLine;
                    901:     LONG ScreenWidth=0,ScreenHeight=0,Depth=0;
1.1.1.2   root      902:     UWORD OverscanType=OSCAN_STANDARD;
                    903:     BOOL AutoScroll=TRUE;
1.1       root      904: 
                    905:     if(!AslBase) AslBase = OpenLibrary("asl.library",38);
                    906:     if(!AslBase) {
                    907:         fprintf(stderr,"Can't open asl.library v38 !");
                    908:         return 0;
                    909:     }
                    910: 
                    911:     ScreenRequest = AllocAslRequest(ASL_ScreenModeRequest,NULL);
                    912:     if(!ScreenRequest) {
                    913:         fprintf(stderr,"Unable to allocate screen mode requester.\n");
                    914:         return 0;
                    915:     }
                    916: 
1.1.1.2   root      917:     get_displayid(&DisplayID, &Depth);
                    918: 
                    919:     if(DisplayID==(ULONG)INVALID_ID) {
1.1       root      920:     if(AslRequestTags(ScreenRequest,
                    921:                       ASLSM_TitleText, (ULONG)"Select screen display mode",
                    922:                       ASLSM_InitialDisplayID,    NULL,
                    923:                       ASLSM_InitialDisplayDepth, 8,
                    924:                       ASLSM_InitialDisplayWidth, currprefs.gfx_width,
                    925:                       ASLSM_InitialDisplayHeight,currprefs.gfx_height,
                    926:                       ASLSM_MinWidth,            currprefs.gfx_width,
                    927:                       ASLSM_MinHeight,           currprefs.gfx_height,
                    928:                       ASLSM_DoWidth,             TRUE,
                    929:                       ASLSM_DoHeight,            TRUE,
                    930:                       ASLSM_DoDepth,             TRUE,
                    931:                       ASLSM_DoOverscanType,      TRUE,
                    932:                       ASLSM_PropertyFlags,       0,
                    933:                       ASLSM_PropertyMask,        DIPF_IS_DUALPF | 
                    934:                                                  DIPF_IS_PF2PRI | 
                    935:                                                  0,
                    936:                       TAG_DONE)) {
                    937:         ScreenWidth  = ScreenRequest->sm_DisplayWidth;
                    938:         ScreenHeight = ScreenRequest->sm_DisplayHeight;
                    939:         Depth        = ScreenRequest->sm_DisplayDepth;
                    940:         DisplayID    = ScreenRequest->sm_DisplayID;
                    941:         OverscanType = ScreenRequest->sm_OverscanType;
                    942:         AutoScroll   = ScreenRequest->sm_AutoScroll;
                    943:         }
                    944:     else DisplayID = INVALID_ID;
1.1.1.2   root      945:     }
1.1       root      946:     FreeAslRequest(ScreenRequest);
                    947:     
                    948:     if(DisplayID == (ULONG)INVALID_ID) return 0;
                    949: 
                    950: #ifdef USE_CYBERGFX 
1.1.1.2   root      951:     if(CyberGfxBase && IsCyberModeID(DisplayID) && (Depth>8)) use_cyb = 1;
1.1       root      952: #endif
1.1.1.2   root      953:     if((DisplayID & HAM_KEY) && !use_cyb ) Depth = 6; /* only ham6 for the moment */
                    954: #if 0
1.1       root      955:     if(DisplayID & DIPF_IS_HAM) Depth = 6; /* only ham6 for the moment */
1.1.1.2   root      956: #endif
                    957:     if(ScreenWidth  < currprefs.gfx_width)  ScreenWidth  = currprefs.gfx_width;
                    958:     if(ScreenHeight < currprefs.gfx_height) ScreenHeight = currprefs.gfx_height;
1.1       root      959: 
                    960:     S = OpenScreenTags(NULL,
                    961:                        SA_DisplayID,                  DisplayID,
                    962:                        SA_Width,                      ScreenWidth,
                    963:                        SA_Height,                     ScreenHeight,
                    964:                        SA_Depth,                      Depth,
                    965:                        SA_Overscan,                   OverscanType,
                    966:                        SA_AutoScroll,                 AutoScroll,
                    967:                        SA_ShowTitle,                  FALSE,
                    968:                        SA_Quiet,                      TRUE,
                    969:                        SA_Behind,                     TRUE,
                    970:                        SA_PubName,                   (ULONG)"UAE",
                    971:                        /* v39 stuff here: */
                    972:                        (os39?SA_BackFill:TAG_DONE),   (ULONG)LAYERS_NOBACKFILL,
                    973:                        SA_SharePens,                  TRUE,
                    974:                        SA_Exclusive,                  (use_cyb?TRUE:FALSE),
                    975:                        SA_Draggable,                  (use_cyb?FALSE:TRUE),
                    976:                        SA_Interleaved,                TRUE,
                    977:                        TAG_DONE);
                    978:     if(!S) {
                    979:         fprintf(stderr,"Unable to open the screen.\n");
                    980:         return 0;
                    981:     }
1.1.1.2   root      982:     
1.1       root      983:     CM           = S->ViewPort.ColorMap;
                    984:     is_halfbrite = (S->ViewPort.Modes & EXTRA_HALFBRITE);
                    985:     is_ham       = (S->ViewPort.Modes & HAM);
                    986: 
                    987:     PointerLine  = malloc(4);/* autodocs says it needs not be in chip memory */
                    988:     if(PointerLine) PointerLine[0]=PointerLine[1]=0;
                    989:     InitBitMap(&PointerBitMap,2,16,1);
                    990:     PointerBitMap.Planes[0] = (PLANEPTR)&PointerLine[0];
                    991:     PointerBitMap.Planes[1] = (PLANEPTR)&PointerLine[1];
                    992: 
                    993:     Pointer = NewObject(NULL,POINTERCLASS,
                    994:                         POINTERA_BitMap,        (ULONG)&PointerBitMap,
                    995:                         POINTERA_WordWidth,     1,
                    996:                         TAG_DONE);
                    997:     if(!Pointer)
                    998:         fprintf(stderr,"Warning: Unable to allocate blank mouse pointer.\n");
                    999: 
                   1000:     W = OpenWindowTags(NULL,
                   1001:                        WA_Width,                S->Width,
                   1002:                        WA_Height,               S->Height,
                   1003:                        WA_CustomScreen,         (ULONG)S,
                   1004:                        WA_Backdrop,             TRUE,
                   1005:                        WA_Borderless,           TRUE,
                   1006:                        WA_RMBTrap,              TRUE,
1.1.1.2   root     1007:                        WA_Activate,            TRUE,
1.1       root     1008:                        WA_ReportMouse,          TRUE,
                   1009:                        WA_IDCMP,                IDCMP_MOUSEBUTTONS|
                   1010:                                                 IDCMP_RAWKEY|
                   1011:                                                 IDCMP_DISKINSERTED|
                   1012:                                                 IDCMP_DISKREMOVED|
                   1013:                                                 IDCMP_ACTIVEWINDOW|
                   1014:                                                 IDCMP_INACTIVEWINDOW|
1.1.1.2   root     1015:                                                 IDCMP_MOUSEMOVE|
                   1016:                                                 IDCMP_DELTAMOVE,
1.1       root     1017:                        (os39?WA_BackFill:TAG_IGNORE), (ULONG)LAYERS_NOBACKFILL,
                   1018:                        (Pointer?WA_Pointer:TAG_IGNORE), (ULONG)Pointer,
                   1019:                        TAG_DONE);
                   1020: 
                   1021:     if(!W) {
                   1022:         fprintf(stderr,"Unable to open the window.\n");
                   1023:         CloseScreen(S);S=NULL;RP=NULL;CM=NULL;
                   1024:         return 0;
                   1025:     }
1.1.1.2   root     1026:     if(!Pointer) setup_sprite(W,0);
1.1       root     1027: 
                   1028:     RP = W->RPort; /* &S->Rastport if screen is not public */
                   1029:     PubScreenStatus(S, 0);
1.1.1.2   root     1030:     printf("Using screenmode: 0x%x:%d (%u:%d)\n",
                   1031:            DisplayID,Depth, DisplayID,Depth);
1.1       root     1032:    
                   1033:     return 1;
                   1034: }
                   1035: 
                   1036: /****************************************************************************/
                   1037: 
                   1038: static int setup_graffiti(void)
                   1039: {
                   1040:     static struct NewScreen NewScreenStructure = {
                   1041:         0,0, 800,600, 4, 0,1,
                   1042:         HIRES, CUSTOMSCREEN|SCREENQUIET/*|SCREENBEHIND*/,
                   1043:         NULL, (void*)"UAE", NULL, NULL};
                   1044:     static struct NewWindow NewWindowStructure = {
                   1045:         0,0, 800,600, 0,1,
                   1046:         IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_DISKINSERTED|IDCMP_DISKREMOVED|
1.1.1.2   root     1047:         IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW|IDCMP_MOUSEMOVE|
                   1048:        IDCMP_DELTAMOVE,
1.1       root     1049:         WFLG_SMART_REFRESH|WFLG_BACKDROP|WFLG_RMBTRAP|WFLG_NOCAREREFRESH|
1.1.1.2   root     1050:         WFLG_BORDERLESS|WFLG_ACTIVATE|WFLG_REPORTMOUSE,
1.1       root     1051:         NULL, NULL, (void*)"UAE", NULL, NULL, 5,5, 800,600,
                   1052:         CUSTOMSCREEN};
                   1053:     static short colarr[] = {
                   1054:         0x000,0x001,0x008,0x009,0x080,0x081,0x088,0x089,
                   1055:         0x800,0x801,0x808,0x809,0x880,0x881,0x888,0x889};
                   1056:     int i;
                   1057: 
                   1058:     NewScreenStructure.Width     = 2*currprefs.gfx_width;
                   1059:     /* I leave 8 extra lines for palette & mode: */
                   1060:     NewScreenStructure.Height    = currprefs.gfx_height+8;  
                   1061:     NewScreenStructure.Depth     = 4;
                   1062:     NewScreenStructure.ViewModes = HIRES|GENLOCK_AUDIO/*|GENLOCK_VIDEO*/;
                   1063:                                    /*    ^^            ^^ which one ? */
                   1064:   
                   1065:     S = (void*)OpenScreen(&NewScreenStructure);
                   1066:     if(!S) {
                   1067:         fprintf(stderr, "Can't open graffiti screen !\n");
                   1068:         return 0;
                   1069:     }
                   1070: 
                   1071:     for(i=0;i<15;++i) {
                   1072:         unsigned int rgb = colarr[i];
                   1073:         SetRGB4(&S->ViewPort,i,(rgb>>8)&15,(rgb>>4)&15,rgb&15);
                   1074:     }
                   1075: 
                   1076:     CM = S->ViewPort.ColorMap;
                   1077:     RP = &S->RastPort;
                   1078: 
                   1079:     NewWindowStructure.Width  = S->Width;
                   1080:     NewWindowStructure.Height = S->Height;
                   1081:     NewWindowStructure.Screen = S;
                   1082:     W = (void*)OpenWindow(&NewWindowStructure);
                   1083:     if(!W) {
                   1084:         fprintf(stderr, "Can't open window on graffiti screen !\n");
                   1085:         return 0;
                   1086:     }
1.1.1.2   root     1087:     setup_sprite(W,0);
1.1       root     1088:     {
                   1089:     /* make sure cmd part is cleared */
                   1090:     int d;
                   1091:     for(d = 0; d < 4; ++d) {
                   1092:         short *p;
                   1093:         int i;
                   1094:         p = (void*)RP->BitMap->Planes[d];
                   1095:         for(i=0;i<40*7;++i) p[i] = 0;
                   1096:     }
                   1097:     /* set graffiti mode to lores */
                   1098:     *((short*)RP->BitMap->Planes[3]+8*40-1) = 0x0800;
                   1099:     for(d=0;d<256;++d) graffiti_SetRGB(d,0,0,0);
                   1100:     }
                   1101: 
                   1102:     return 1;
                   1103: }
                   1104: 
                   1105: /****************************************************************************/
                   1106: 
                   1107: int graphics_setup(void)
                   1108: {
1.1.1.2   root     1109: #ifdef OS_IS_AMIGAOS
1.1       root     1110:     if(ix_os != OS_IS_AMIGAOS) {
                   1111:         ix_req(NULL, "Abort", NULL, "That version of %s is only for AmigaOS!", __progname);
                   1112:         exit(20);
                   1113:     }    
                   1114: #endif
1.1.1.2   root     1115:     if(((struct ExecBase *)SysBase)->LibNode.lib_Version < 36) {
1.1       root     1116:         fprintf(stderr, "UAE needs OS 2.0+ !\n");
                   1117:         return 0;
                   1118:     }
1.1.1.2   root     1119:     os39   = (((struct ExecBase *)SysBase)->LibNode.lib_Version>=39);
1.1       root     1120: 
                   1121:     atexit(graphics_leave);
                   1122: 
                   1123:     IntuitionBase = (void*)OpenLibrary("intuition.library",0L);
                   1124:     if(!IntuitionBase) {
                   1125:         fprintf(stderr,"No intuition.library ?\n");
                   1126:         return 0;
                   1127:     }
                   1128:     GfxBase = (void*)OpenLibrary("graphics.library",0L);
                   1129:     if(!GfxBase) {
                   1130:         fprintf(stderr,"No graphics.library ?\n");
                   1131:         return 0;
                   1132:     }
                   1133: #ifdef USE_CYBERGFX
                   1134:     if(!CyberGfxBase) CyberGfxBase = OpenLibrary("cybergraphics.library",40);
                   1135: #endif
                   1136:     initpseudodevices();
                   1137: 
                   1138:     return 1;
                   1139: }
                   1140: 
                   1141: /****************************************************************************/
                   1142: 
                   1143: int graphics_init(void)
                   1144: {
                   1145:     int i,bitdepth;
                   1146: 
1.1.1.2   root     1147:     use_delta_buffer = 0;
1.1       root     1148:     need_dither = 0;
                   1149:     use_cyb = 0;
                   1150:     
                   1151:     if (currprefs.gfx_width < 320)
                   1152:         currprefs.gfx_width = 320;
                   1153:     if (!currprefs.gfx_correct_aspect && (currprefs.gfx_height < 64/*200*/))
                   1154:         currprefs.gfx_height = 200;
                   1155:     currprefs.gfx_width += 7;
                   1156:     currprefs.gfx_width &= ~7;
                   1157: 
                   1158:     if (currprefs.color_mode > 5)
                   1159:         fprintf(stderr, "Bad color mode selected. Using default.\n"), currprefs.color_mode = 0;
                   1160:     
                   1161:     if(currprefs.color_mode == 3) { /* graffiti */
                   1162:         currprefs.gfx_width = 320;
                   1163:         if(currprefs.gfx_height > 256) 
                   1164:             currprefs.gfx_height = 256;
                   1165:         currprefs.gfx_lores = 1;
                   1166:     } /* graffiti */
                   1167:     
                   1168:     gfxvidinfo.width  = currprefs.gfx_width;
                   1169:     gfxvidinfo.height = currprefs.gfx_height;
                   1170: 
                   1171:     switch(currprefs.color_mode) {
                   1172:       case 3:
                   1173:         if(setup_graffiti()) {use_graffiti = 1;break;}
                   1174:         fprintf(stderr,"Asking user for screen...\n");
                   1175:         /* fall trough */
                   1176:       case 2:
                   1177:         if(setup_userscreen()) break;
                   1178:         fprintf(stderr,"Trying on public screen...\n");
                   1179:         /* fall trough */
                   1180:       case 1:
                   1181:         is_halfbrite = 0;
                   1182:         if(setup_publicscreen()) {usepub = 1;break;}
                   1183:         fprintf(stderr,"Trying on custom screen...\n");
                   1184:         /* fall trough */
                   1185:       case 0:
                   1186:       default:
                   1187:         if(!setup_customscreen()) return 0;
                   1188:         break;
                   1189:     }
                   1190: 
                   1191:     Line = AllocVec((currprefs.gfx_width + 15) & ~15,MEMF_ANY|MEMF_PUBLIC);
                   1192:     if(!Line) {
                   1193:         fprintf(stderr,"Unable to allocate raster buffer.\n");
                   1194:         return 0;
                   1195:     }
                   1196:     BitMap = myAllocBitMap(currprefs.gfx_width,1,8,BMF_CLEAR|BMF_MINPLANES,RP->BitMap);
                   1197:     if(!BitMap) {
                   1198:         fprintf(stderr,"Unable to allocate BitMap.\n");
                   1199:         return 0;
                   1200:     }
                   1201:     TempRPort = AllocVec(sizeof(struct RastPort),MEMF_ANY|MEMF_PUBLIC);
                   1202:     if(!TempRPort) {
                   1203:         fprintf(stderr,"Unable to allocate RastPort.\n");
                   1204:         return 0;
                   1205:     }
                   1206:     CopyMem(RP,TempRPort,sizeof(struct RastPort));
                   1207:     TempRPort->Layer  = NULL;
                   1208:     TempRPort->BitMap = BitMap;
                   1209: 
                   1210:     if(usepub) set_title();
                   1211: 
                   1212:     bitdepth = RPDepth(RP);
                   1213:     if(is_ham) {
                   1214:         /* ham 6 */
1.1.1.2   root     1215:         use_delta_buffer    = 0; /* needless as the line must be fully */
1.1       root     1216:         need_dither         = 0; /* recomputed */
                   1217:         gfxvidinfo.pixbytes = 2;
                   1218:     } else if(bitdepth <= 8) {
1.1.1.2   root     1219:         /* chunk2planar is slow so we define use_delta_buffer for all modes */
                   1220:         use_delta_buffer    = 1; 
1.1       root     1221:         need_dither         = use_dither || (bitdepth<=1);
                   1222:         gfxvidinfo.pixbytes = need_dither?2:1;
                   1223:     } else {
                   1224:         /* Cybergfx mode */
1.1.1.2   root     1225:         use_delta_buffer    = 0;
                   1226:         need_dither         = 0;
                   1227:         gfxvidinfo.pixbytes = (bitdepth >= 24) ? 4 : (bitdepth >= 12) ? 2 : 1;
1.1       root     1228:     }
                   1229:     
1.1.1.2   root     1230:     gfxvidinfo.emergmem = 0;
                   1231:     gfxvidinfo.linemem = 0;
1.1       root     1232:     if (!use_cyb) {
                   1233:         gfxvidinfo.rowbytes = gfxvidinfo.pixbytes * currprefs.gfx_width;
                   1234:         gfxvidinfo.bufmem = (char *)calloc(gfxvidinfo.rowbytes, currprefs.gfx_height+1);
                   1235:         /*                                                           ^^ */
                   1236:         /*            This is because DitherLine may read one extra row */
                   1237:     } else {
                   1238: #ifdef USE_CYBERGFX
                   1239:         ULONG fmt = 0;
                   1240:         switch(bitdepth) {
                   1241:            case 15: fmt = PIXFMT_RGB15; break;
                   1242:            case 16: fmt = PIXFMT_RGB16; break;
                   1243:            case 24: fmt = PIXFMT_RGB24; break;
                   1244:            case 32: fmt = PIXFMT_ARGB32; break;
                   1245:            default: fprintf(stderr,"Unsupported bitdepth %d.\n",bitdepth); return 0;
                   1246:         }
                   1247:         CybBitMap = myAllocBitMap(currprefs.gfx_width, currprefs.gfx_height+1,
                   1248:                                   bitdepth, 
                   1249:                                   (fmt<<24)|BMF_SPECIALFMT|BMF_MINPLANES, 
                   1250:                                   NULL);
                   1251:         if(CybBitMap) {
                   1252:            gfxvidinfo.rowbytes = GetCyberMapAttr(CybBitMap,CYBRMATTR_XMOD);
                   1253:            gfxvidinfo.pixbytes = GetCyberMapAttr(CybBitMap,CYBRMATTR_BPPIX);
                   1254:            gfxvidinfo.bufmem = (char *)GetCyberMapAttr(CybBitMap,CYBRMATTR_DISPADR);
                   1255:         } else gfxvidinfo.bufmem = NULL;
                   1256: #endif
                   1257:     } 
                   1258:     if(!gfxvidinfo.bufmem) {
                   1259:         fprintf(stderr,"Not enough memory for video bufmem.\n");
                   1260:         return 0;
                   1261:     } 
                   1262: 
1.1.1.2   root     1263:     if (use_delta_buffer) {
1.1       root     1264:         gfxvidinfo.maxblocklines = currprefs.gfx_height-1; /* it seems to increase the speed */
                   1265:         oldpixbuf = (char *)calloc(gfxvidinfo.rowbytes, currprefs.gfx_height);
                   1266:         if(!oldpixbuf) {
                   1267:             fprintf(stderr,"Not enough memory for oldpixbuf.\n");
                   1268:             return 0;
                   1269:         }
                   1270:     } else {
                   1271:         gfxvidinfo.maxblocklines = 0; /* whatever... */
1.1.1.2   root     1272: #ifdef POWERUP        
                   1273:         gfxvidinfo.maxblocklines = 100; /* sam: this will reduce the number of 68k-OS call */
                   1274:                                         /* to be done */
                   1275: #endif
1.1       root     1276:     }
                   1277: 
                   1278:     if (!init_colors()) {
                   1279:         fprintf(stderr,"Failed to init colors.\n");
                   1280:         return 0;
                   1281:     }
                   1282:     switch (gfxvidinfo.pixbytes) {
                   1283:      case 2:
                   1284:         for (i = 0; i < 4096; i++) xcolors[i] *= 0x00010001;
                   1285:         gfxvidinfo.can_double = 1;
                   1286:         break;
                   1287:      case 1:
                   1288:         for (i = 0; i < 4096; i++) xcolors[i] *= 0x01010101;
                   1289:         gfxvidinfo.can_double = 1;
                   1290:         break;
                   1291:      default:
                   1292:         gfxvidinfo.can_double = 0;
                   1293:         break;
                   1294:     }
                   1295: 
                   1296:     if(!usepub) ScreenToFront(S);
                   1297: 
                   1298:     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
                   1299:     for(i=0; i<256; i++)
                   1300:         keystate[i] = 0;
                   1301:     
                   1302:     lastmx = lastmy = 0; 
                   1303:     newmousecounters = 0;
                   1304:     inwindow = 0;
                   1305: 
                   1306:     rexx_init();
                   1307: 
                   1308:     if(getenv(UAEIFF) && !use_cyb) {
                   1309:         dump_iff = 1;
                   1310:         fprintf(stderr,"Saving to \"%s\"\n",getenv(UAEIFF));
                   1311:     }
                   1312: 
                   1313:     return 1;
                   1314: }
                   1315: 
                   1316: /****************************************************************************/
                   1317: 
                   1318: void graphics_leave(void)
                   1319: {
                   1320:     rexx_exit();
                   1321:     closepseudodevices();
                   1322:     appw_exit();
                   1323: #ifdef USE_CYBERGFX
                   1324:     if(CybBitMap) {
                   1325:         WaitBlit();
                   1326:         myFreeBitMap(CybBitMap);
                   1327:         CybBitMap = NULL;
                   1328:     }
                   1329: #endif
                   1330:     if(BitMap) {
                   1331:         WaitBlit();
                   1332:         myFreeBitMap(BitMap);
                   1333:         BitMap = NULL;
                   1334:     }
                   1335:     if(TempRPort) {
                   1336:         FreeVec(TempRPort);
                   1337:         TempRPort = NULL;
                   1338:     }
                   1339:     if(Line) {
                   1340:         FreeVec(Line);
                   1341:         Line = NULL;
                   1342:     } 
                   1343:     if(CM) {
                   1344:         ReleaseColors();
                   1345:         CM = NULL;
                   1346:     }
                   1347:     if(W) {
                   1348:         CloseWindow(W);
                   1349:         W = NULL;
                   1350:     }
                   1351:     if(Sprite) {
                   1352:         FreeVec(Sprite);
                   1353:         Sprite = NULL;
                   1354:     }
                   1355:     if(Pointer) {
                   1356:         DisposeObject(Pointer);
                   1357:         Pointer = NULL;
                   1358:     }
                   1359:     if(!usepub && S) {
                   1360:         if(!CloseScreen(S)) {
                   1361:            fprintf(stderr,"Please close all opened windows on UAE's "
                   1362:                          "screen.\n");
1.1.1.2   root     1363: #ifdef __SASC
1.1       root     1364:           do Delay(50); while(!CloseScreen(S));
1.1.1.2   root     1365: #else
                   1366:           do sleep(1); while(!CloseScreen(S));
                   1367: #endif
1.1       root     1368:        }
                   1369:         S = NULL;
                   1370:     }
                   1371:     if(AslBase) {
                   1372:         CloseLibrary((void*)AslBase);
                   1373:         AslBase = NULL;
                   1374:     }
                   1375:     if(GfxBase) {
                   1376:         CloseLibrary((void*)GfxBase);
                   1377:         GfxBase = NULL;
                   1378:     }
                   1379:     if(IntuitionBase) {
                   1380:         CloseLibrary((void*)IntuitionBase);
                   1381:         IntuitionBase = NULL;
                   1382:     }
                   1383:     if(CyberGfxBase) {
                   1384:         CloseLibrary((void*)CyberGfxBase);
                   1385:         CyberGfxBase = NULL;
                   1386:     }
                   1387: }
                   1388: 
1.1.1.2   root     1389: /****************************************************************************/
                   1390: 
                   1391: int do_inhibit_frame(int onoff)
                   1392: {
                   1393:     if(onoff!=-1) {
                   1394:        inhibit_frame = onoff?1:0;
                   1395:        if(inhibit_frame) printf("display disabled\n");
                   1396:         else printf("display enabled\n");
                   1397:        set_title();
                   1398:     }
                   1399:     return inhibit_frame;
                   1400: }
1.1       root     1401: 
                   1402: /***************************************************************************/
                   1403: 
                   1404: void handle_events(void)
                   1405: {
                   1406:     struct IntuiMessage *msg;
1.1.1.2   root     1407:     int dmx,dmy,class,code;
1.1       root     1408:   
                   1409:     newmousecounters = 0;
1.1.1.2   root     1410: 
                   1411:    /* this function is called at each frame, so: */
                   1412:     ++frame_num;       /* increase frame counter */
                   1413:     save_frame();      /* possibly save frame    */
                   1414: 
1.1       root     1415:     /*
                   1416:      * This is a hack to simulate ^C as is seems that break_handler
                   1417:      * is lost when system() is called.
                   1418:      */
                   1419:     if(SetSignal(0L, SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D) & 
                   1420:                     (SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D)) {
                   1421:         activate_debugger();
                   1422:     }
                   1423: 
1.1.1.2   root     1424: #if defined(POWERUP)
                   1425:     /* Holger: The while-loop caused problems if a key was pressed to fast */
                   1426:     if((msg=(struct IntuiMessage*)GetMsg(W->UserPort))) {
                   1427: #else
1.1       root     1428:     while((msg=(struct IntuiMessage*)GetMsg(W->UserPort))) {
1.1.1.2   root     1429: #endif
1.1       root     1430:         class = msg->Class;
                   1431:         code  = msg->Code;
1.1.1.2   root     1432:         dmx   = msg->MouseX;
                   1433:         dmy   = msg->MouseY;
1.1       root     1434:         ReplyMsg((struct Message*)msg);
                   1435:       
                   1436:         switch(class) {
                   1437:           case IDCMP_NEWSIZE:
1.1.1.2   root     1438:             do_inhibit_frame((W->Flags & WFLG_ZOOMED)?1:0);
1.1       root     1439:             break;
                   1440: 
                   1441:           case IDCMP_REFRESHWINDOW:
1.1.1.2   root     1442:             if(use_delta_buffer) {
1.1       root     1443:                 /* hack: this forces refresh */
                   1444:                 char *ptr = oldpixbuf;
                   1445:                 int i, len = gfxvidinfo.width;
                   1446:                 len *= gfxvidinfo.pixbytes;
                   1447:                 for(i=0;i<currprefs.gfx_height;++i) {
                   1448:                     ptr[00000] ^= 255;
                   1449:                     ptr[len-1] ^= 255;
                   1450:                     ptr += gfxvidinfo.rowbytes;
                   1451:                 }
1.1.1.2   root     1452:             }
                   1453:             BeginRefresh(W);
                   1454:             flush_block(0,currprefs.gfx_height-1);
                   1455:             EndRefresh(W, TRUE);
                   1456:            break;
1.1       root     1457: 
                   1458:           case IDCMP_CLOSEWINDOW:
                   1459:             activate_debugger();
                   1460:             break;
                   1461: 
                   1462:           case IDCMP_RAWKEY: {
                   1463:               int kc       = code&127;
                   1464:               int released = code&128?1:0;
                   1465:             
                   1466:               if(released) {
                   1467:                   keystate[kc] = 0;
                   1468:                   record_key ((kc << 1) | 1);
                   1469:               } else if (!keystate[kc])  {
                   1470:                   keystate[kc] = 1;
                   1471:                   record_key (kc << 1);
                   1472:               }
                   1473:           } break;
                   1474:           
                   1475:           case IDCMP_MOUSEMOVE:
1.1.1.2   root     1476:             lastmx += dmx;
                   1477:             lastmy += dmy;
                   1478:            break;
1.1       root     1479: 
                   1480:           case IDCMP_MOUSEBUTTONS:
                   1481:             if(code==SELECTDOWN) buttonstate[0]=1;
                   1482:             if(code==SELECTUP)   buttonstate[0]=0;
1.1.1.2   root     1483:             if(code==MIDDLEDOWN) buttonstate[2]=1;
                   1484:             if(code==MIDDLEUP)   buttonstate[2]=0;
1.1       root     1485:             if(code==MENUDOWN)   buttonstate[2]=1;
                   1486:             if(code==MENUUP)     buttonstate[2]=0;
                   1487:             break;
                   1488:         
                   1489:           /* Those 2 could be of some use later. */
                   1490:           case IDCMP_DISKINSERTED:
                   1491:             /*printf("diskinserted(%d)\n",code);*/
                   1492:             break;
                   1493:           
                   1494:           case IDCMP_DISKREMOVED:
                   1495:             /*printf("diskremoved(%d)\n",code);*/
                   1496:             break;
                   1497:                         
                   1498:           case IDCMP_ACTIVEWINDOW:
                   1499:             inwindow = 1;
                   1500:             newmousecounters = 1;
                   1501:             break;
                   1502:                         
                   1503:           case IDCMP_INACTIVEWINDOW:
                   1504:             inwindow = 0;
                   1505:             break;
                   1506:           
                   1507:           default:
                   1508:             fprintf(stderr, "Unknown class: %d\n",class);
                   1509:             break;
                   1510:         }
                   1511:     }
                   1512:     /* "Affengriff" */
                   1513:     if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI]) 
                   1514:         m68k_reset();
                   1515: 
                   1516:     /* PC-like :-) CTRL-ALT-DEL => reboot */
                   1517:     if(keystate[AK_CTRL] && (keystate[AK_LALT] || keystate[AK_RALT]) && 
                   1518:        keystate[AK_DEL]) 
                   1519:         m68k_reset();
                   1520: 
                   1521:     /* CTRL+LSHIFT+LALT+F10 on amiga => F12 on X11 */
                   1522:     /*                  F9           => ScrollLock on X11 (inhibit_frame) */
                   1523:     if(keystate[AK_CTRL] && keystate[AK_LSH] && keystate[AK_LALT]) {
1.1.1.2   root     1524: /*        if(keystate[AK_F10]) togglemouse(); */
                   1525:         if(keystate[AK_F8]) {
                   1526:             uae_quit();
                   1527:         }
1.1       root     1528:         if(keystate[AK_F9]) {
1.1.1.2   root     1529:             do_inhibit_frame(inhibit_frame != 2 ? inhibit_frame ^ 1 : 
                   1530:                             inhibit_frame);
                   1531:             DisplayBeep(NULL); 
1.1       root     1532:         }
                   1533:     }
                   1534: 
                   1535:     disk_hotkeys();
                   1536:     gui_handle_events();
                   1537:     appw_events();
                   1538: }
                   1539: 
                   1540: /***************************************************************************/
                   1541: 
                   1542: int debuggable(void)
                   1543: {
                   1544:     return 1;
                   1545: }
                   1546: 
                   1547: /***************************************************************************/
                   1548: 
                   1549: int needmousehack(void)
                   1550: {
1.1.1.2   root     1551:     return 0;
1.1       root     1552: }
                   1553: 
                   1554: /***************************************************************************/
                   1555: 
                   1556: void LED(int on)
                   1557: {
                   1558: }
                   1559: 
                   1560: /***************************************************************************/
                   1561: 
                   1562: /* sam: need to put all this in a separate module */
                   1563: 
                   1564: #ifdef PICASSO96
                   1565: 
                   1566: void DX_Invalidate (int first, int last)
                   1567: {
                   1568: }
                   1569: 
                   1570: int DX_BitsPerCannon (void)
                   1571: {
                   1572:     return 8;
                   1573: }
                   1574: 
                   1575: void DX_SetPalette(int start, int count)
                   1576: {
                   1577: }
                   1578: 
                   1579: int DX_FillResolutions (uae_u16 *ppixel_format)
                   1580: {
                   1581:     return 0;
                   1582: }
                   1583: 
                   1584: void gfx_set_picasso_modeinfo (int w, int h, int depth)
                   1585: {
                   1586: }
                   1587: 
                   1588: void gfx_set_picasso_baseaddr (uaecptr a)
                   1589: {
                   1590: }
                   1591: 
                   1592: void gfx_set_picasso_state (int on)
                   1593: {
                   1594: }
                   1595: 
                   1596: void begindrawing (void)
                   1597: {
                   1598: }
                   1599: 
                   1600: void enddrawing (void)
                   1601: {
                   1602: }
                   1603: 
                   1604: uae_u8 *lockscr (void)
                   1605: {
                   1606: return NULL;
                   1607: }
                   1608: 
                   1609: void unlockscr (void)
                   1610: {
                   1611: }
                   1612: #endif
                   1613: 
                   1614: /***************************************************************************/
                   1615: 
                   1616: static int led_state[5];
                   1617: 
                   1618: static void set_title(void)
                   1619: {
                   1620:     static char title[80];
1.1.1.2   root     1621:     static char ScreenTitle[200];
1.1       root     1622: 
                   1623:     if(!usepub) return;
                   1624: 
                   1625:     sprintf(title,"%sPower: [%c] Drives: [%c] [%c] [%c] [%c]",
                   1626:             inhibit_frame?"UAE (PAUSED) - ":"UAE � ",
                   1627:             led_state[0]?'X':' ',
                   1628:             led_state[1]?'0':' ',
                   1629:             led_state[2]?'1':' ',
                   1630:             led_state[3]?'2':' ',
                   1631:             led_state[4]?'3':' ');
                   1632:     
                   1633:     if(!*ScreenTitle) {
                   1634:          sprintf(ScreenTitle,
1.1.1.2   root     1635:                  "UAE-%d.%d.%d (%s%s%s) � by Bernd Schmidt & contributors, "
                   1636: #ifdef POWERUP
                   1637:                  "Amiga Port by Samuel Devulder & Holger Jakob (PPC extensions).",
                   1638: #else
1.1       root     1639:                  "Amiga Port by Samuel Devulder.",
1.1.1.2   root     1640: #endif
                   1641:                  UAEMAJOR, UAEMINOR, UAESUBREV,
                   1642:                  currprefs.cpu_level==0?"68000":
                   1643:                  currprefs.cpu_level==1?"68010":
                   1644:                  currprefs.cpu_level==2?"68020":"68020/68881",
                   1645:                  currprefs.address_space_24?" 24bits":"",
                   1646:                  currprefs.cpu_compatible?" compat":"");
1.1       root     1647:         SetWindowTitles(W, title, ScreenTitle);
                   1648:     } else SetWindowTitles(W, title, (char*)-1);
                   1649: }
                   1650: 
                   1651: /****************************************************************************/
                   1652: 
                   1653: void main_window_led(int led, int on)                /* is used in amigui.c */
                   1654: {
                   1655:   if(led>=0 && led<=4) led_state[led] = on;
                   1656:   set_title();
                   1657: }
                   1658: 
                   1659: /****************************************************************************/
                   1660: 
                   1661: static void unrecord(int kc)
                   1662: {
                   1663:     keystate[kc] = 0;
                   1664:     record_key ((kc << 1) | 1);
                   1665: }
                   1666: 
                   1667: /****************************************************************************/
                   1668: 
                   1669: static void disk_hotkeys(void)
                   1670: {
                   1671:     struct FileRequester *FileRequest;
                   1672:     char buff[80];
                   1673:     int drive;
                   1674:     char *last_file,*last_dir,*s;
                   1675: 
                   1676:     if(!(keystate[AK_CTRL] && keystate[AK_LALT])) return;
                   1677: 
                   1678:     /* CTRL-LSHIFT-LALT F1-F4 => eject_disk */
                   1679:     if(keystate[AK_LSH]) {
                   1680:         int ok = 0;
                   1681: 
                   1682:         if(keystate[AK_F1]) {ok=1;disk_eject(0);
                   1683:                              printf("drive DF0: ejected\n");}
                   1684:         if(keystate[AK_F2]) {ok=1;disk_eject(1);
                   1685:                              printf("drive DF1: ejected\n");}
                   1686:         if(keystate[AK_F3]) {ok=1;disk_eject(2);
                   1687:                              printf("drive DF2: ejected\n");}
                   1688:         if(keystate[AK_F4]) {ok=1;disk_eject(3);
                   1689:                              printf("drive DF3: ejected\n");}
                   1690: 
                   1691:         if(ok) {
1.1.1.2   root     1692:             DisplayBeep(NULL);
1.1       root     1693:             unrecord(AK_CTRL);unrecord(AK_LALT);unrecord(AK_LSH); 
                   1694:             unrecord(AK_F1);unrecord(AK_F2);  
                   1695:             unrecord(AK_F3);unrecord(AK_F4);
                   1696:         }
                   1697:         return;
                   1698:     }
                   1699: 
                   1700:     /* CTRL-LALT F1-F4 => insert_disk */
                   1701:     if(keystate[AK_F1])      {drive = 0;unrecord(AK_F1);}
                   1702:     else if(keystate[AK_F2]) {drive = 1;unrecord(AK_F2);}
                   1703:     else if(keystate[AK_F3]) {drive = 2;unrecord(AK_F3);}
                   1704:     else if(keystate[AK_F4]) {drive = 3;unrecord(AK_F4);}
                   1705:     else return;
1.1.1.2   root     1706:     DisplayBeep(NULL);
1.1       root     1707:     unrecord(AK_CTRL);unrecord(AK_LALT); 
                   1708: 
                   1709:     switch(drive) {
                   1710:       case 0: case 1: case 2: case 3: last_file = currprefs.df[drive]; break;
                   1711:       default: return;
                   1712:     }
                   1713: 
                   1714:     split_dir_file(from_unix_path(last_file), &last_dir, &last_file);
                   1715:     if(!last_file) return;
                   1716:     if(!last_dir)  return;
                   1717: 
                   1718:     if(!AslBase) AslBase = OpenLibrary("asl.library",36);
                   1719:     if(!AslBase) {
                   1720:         fprintf(stderr,"Can't open asl.library v36 !");
                   1721:         return;
                   1722:     }
                   1723: 
                   1724:     FileRequest = AllocAslRequest(ASL_FileRequest,NULL);
                   1725:     if(!FileRequest) {
                   1726:         fprintf(stderr,"Unable to allocate file requester.\n");
                   1727:         return;
                   1728:     }
                   1729: 
                   1730:     sprintf(buff,"Select file to use for drive DF%d:",drive);
                   1731:     if(AslRequestTags(FileRequest,
                   1732:                       use_graffiti?TAG_IGNORE:
                   1733:                       ASLFR_Window,         (ULONG)W,
                   1734:                       ASLFR_TitleText,      (ULONG)buff,
                   1735:                       ASLFR_InitialDrawer,  (ULONG)last_dir,
                   1736:                       ASLFR_InitialFile,    (ULONG)last_file,
                   1737:                       ASLFR_InitialPattern, (ULONG)"(#?.ad(f|z)#?|df?|?)",
                   1738:                       ASLFR_DoPatterns,     TRUE,
                   1739:                       ASLFR_RejectIcons,    TRUE,
                   1740:                       TAG_DONE)) {
                   1741:         free(last_file);
                   1742:         last_file = malloc(3 + strlen(FileRequest->fr_Drawer) +
                   1743:                            strlen(FileRequest->fr_File));
                   1744:         if((last_file)) {
                   1745:             s = last_file;
                   1746:             strcpy(s,FileRequest->fr_Drawer);
                   1747:             if(*s && !(s[strlen(s)-1]==':' || s[strlen(s)-1]=='/')) 
                   1748:                 strcat(s,"/");
                   1749:             strcat(s,FileRequest->fr_File);
                   1750:             last_file = to_unix_path(s);free(s);
                   1751:         }
                   1752:     } else {
                   1753:         free(last_file);
                   1754:         last_file = NULL;
                   1755:     }
                   1756:     FreeAslRequest(FileRequest);
                   1757:     free(last_dir);
                   1758: 
                   1759:     if(last_file) {
                   1760:         disk_insert(drive,last_file);
                   1761:         free(last_file);
                   1762:     }
                   1763: }
                   1764: 
                   1765: /****************************************************************************/
                   1766: /*
                   1767:  * Routines for OS2.0 (code taken out of mpeg_play by Michael Balzer)
                   1768:  */
                   1769: static struct BitMap *myAllocBitMap(ULONG sizex, ULONG sizey, ULONG depth, 
                   1770:                                     ULONG flags, struct BitMap *friend_bitmap)
                   1771: {
                   1772:     struct BitMap *bm;
                   1773:     unsigned long extra;
                   1774:     
                   1775:     if(os39) return AllocBitMap(sizex, sizey, depth, flags, friend_bitmap);
                   1776:     
                   1777:     extra = (depth > 8) ? depth - 8 : 0;
                   1778:     bm = AllocVec( sizeof *bm + (extra * 4), MEMF_CLEAR );
                   1779:     
                   1780:     if( bm )
                   1781:       {
                   1782:           ULONG i;
                   1783:           InitBitMap(bm, depth, sizex, sizey);
                   1784:           for( i=0; i<depth; i++ )
                   1785:             {
                   1786:                 if( !(bm->Planes[i] = AllocRaster(sizex, sizey)) )
                   1787:                   {
                   1788:                       while(i--) FreeRaster(bm->Planes[i], sizex, sizey);
                   1789:                       FreeVec(bm);
                   1790:                       bm = 0;
                   1791:                       break;
                   1792:                   }
                   1793:             }
                   1794:       }
                   1795:     return bm;
                   1796: }
                   1797: 
                   1798: /****************************************************************************/
                   1799: 
                   1800: static void myFreeBitMap(struct BitMap *bm)
                   1801: {
                   1802:     if(os39) {FreeBitMap(bm);return;}
                   1803:     while(bm->Depth--)
                   1804:       FreeRaster(bm->Planes[bm->Depth], bm->BytesPerRow*8, bm->Rows);
                   1805:     FreeVec(bm);
                   1806: }
                   1807: 
                   1808: /****************************************************************************/
                   1809: /*
                   1810:  * find the best appropriate color. return -1 if none is available
                   1811:  */
                   1812: static LONG ObtainColor(ULONG r,ULONG g,ULONG b)
                   1813: {
                   1814:     int i, crgb;
                   1815:     int colors;
                   1816: 
                   1817:     if(use_graffiti) {
                   1818:         if(maxpen >= 256) {
                   1819:             fprintf(stderr,"Asking more than 256 colors for graffiti ?\n");
                   1820:             abort();
                   1821:         }
                   1822:         graffiti_SetRGB(maxpen, r>>24, g>>24, b>>24);
                   1823:         return maxpen++;
                   1824:     }
                   1825: 
                   1826:     if(os39 && usepub && CM) {
                   1827:         i = ObtainBestPen(CM,r,g,b,
                   1828:                           OBP_Precision, (use_approx_color?PRECISION_GUI:
                   1829:                                                            PRECISION_EXACT),
                   1830:                           OBP_FailIfBad, TRUE,
                   1831:                           TAG_DONE);
                   1832:         if(i != -1) {
                   1833:             if(maxpen<256) pen[maxpen++] = i;
                   1834:             else i = -1;
                   1835:         }
                   1836:         return i;
                   1837:     }
                   1838: 
                   1839:     colors = is_halfbrite?32:(1<<RPDepth(RP));
                   1840:   
                   1841:     /* private screen => standard allocation */
                   1842:     if(!usepub) {
                   1843:         if(maxpen >= colors) return -1; /* no more colors available */
1.1.1.2   root     1844:         if(os39) SetRGB32(&S->ViewPort, maxpen, r, g, b);
                   1845:        else     SetRGB4 (&S->ViewPort, maxpen, r>>28, g>>28, b>>28);
1.1       root     1846:         return maxpen++;
                   1847:     }
                   1848: 
                   1849:     /* public => find exact match */
1.1.1.2   root     1850:     r >>= 28; g >>= 28; b >>= 28;
1.1       root     1851:     if(use_approx_color) return get_nearest_color(r,g,b);
                   1852:     crgb = (r<<8)|(g<<4)|b;
                   1853:     for(i=0; i<colors; i++ ) {
                   1854:         int rgb = GetRGB4(CM, i);
                   1855:         if(rgb == crgb) return i;
                   1856:     }
                   1857:     return -1;
                   1858: }
                   1859: 
                   1860: /****************************************************************************/
                   1861: /*
                   1862:  * free a color entry
                   1863:  */
                   1864: static void ReleaseColors(void)
                   1865: {
                   1866:     if(os39 && usepub && CM) 
                   1867:         while(maxpen>0) ReleasePen(CM, pen[--maxpen]);
                   1868:     else maxpen = 0;
                   1869: }
                   1870: 
                   1871: /****************************************************************************/
                   1872: 
                   1873: static int DoSizeWindow(struct Window *W,int wi,int he)
                   1874: {
                   1875:     register int x,y;
                   1876:     int ret = 1;
                   1877:     
                   1878:     wi += W->BorderRight + W->BorderLeft;
                   1879:     he += W->BorderBottom + W->BorderTop;
                   1880:     x   = W->LeftEdge;
                   1881:     y   = W->TopEdge;
                   1882:     
                   1883:     if(x + wi >= W->WScreen->Width)  x = W->WScreen->Width - wi;
                   1884:     if(y + he >= W->WScreen->Height) y = W->WScreen->Height - he;
                   1885: 
                   1886:     if(x<0 || y<0) {
                   1887:         fprintf(stderr, "Working screen too small to open window (%dx%d)!\n",
                   1888:                 wi, he);
                   1889:         if(x<0) {x = 0; wi = W->WScreen->Width;}
                   1890:         if(y<0) {y = 0; he = W->WScreen->Height;}
                   1891:         ret = 0;
                   1892:     }
                   1893:     
                   1894:     x  -= W->LeftEdge;
                   1895:     y  -= W->TopEdge;
                   1896:     wi -= W->Width;
                   1897:     he -= W->Height;
                   1898:     
                   1899:     if(x|y)   MoveWindow(W,x,y);
                   1900:     if(wi|he) SizeWindow(W,wi,he);
                   1901:     return ret;
                   1902: }
                   1903: 
                   1904: /****************************************************************************/
                   1905: /*
                   1906:  * support code for graffiti card
                   1907:  */
                   1908: static void graffiti_SetRGB(int i, int r, int g, int b)
                   1909: {
                   1910:     UWORD **ptr = (void*)RP->BitMap->Planes;
                   1911: 
                   1912:     *(*ptr++ + i) = 0x0406;
                   1913:     *(*ptr++ + i) = (i<<8)|((g>>2)&0x3f);
                   1914:     *(*ptr++ + i) = 0x0606;
                   1915:     *(*ptr   + i) = ((r<<6)&0x3f00)|((b>>2)&0x3f);
                   1916: }
                   1917: 
                   1918: /****************************************************************************/
                   1919: 
                   1920: static void graffiti_WritePixelLine8(int x, int y, short len, char *line)
                   1921: {
                   1922: #if 0
                   1923:     /* standard code */
                   1924:     char **ptr = (void*)RP->BitMap->Planes;
                   1925: 
                   1926:     y += 8;
                   1927:     x += (y*80)<<2;
                   1928:     while(len--) {
                   1929:         *(ptr[x&3] + (x>>2)) = *line++;
                   1930:         ++x;
                   1931:     }
                   1932: #else
                   1933:     /* this one must be quite fast for 680x0 processor */
                   1934:     char **ptr;
                   1935:     char *ptr0,*ptr1,*ptr2,*ptr3;
                   1936:     ptr = (void*)RP->BitMap->Planes;
                   1937:     switch(x&3) {
                   1938:         case 0: ptr0=*ptr++;     ptr1=*ptr++;     ptr2=*ptr++;     ptr3=*ptr; break;
                   1939:         case 1: ptr3=*ptr++ + 1; ptr0=*ptr++;     ptr1=*ptr++;     ptr2=*ptr; break;
                   1940:         case 2: ptr2=*ptr++ + 1; ptr3=*ptr++ + 1; ptr0=*ptr++;     ptr1=*ptr; break;
                   1941:         default:
                   1942:         case 3: ptr1=*ptr++ + 1; ptr2=*ptr++ + 1; ptr3=*ptr++ + 1; ptr0=*ptr; break;
                   1943:     }
                   1944:     x >>= 2; x += (80*(y+8));
                   1945:     ptr0 += x; ptr1 += x; ptr2 += x; ptr3 += x;
                   1946:     ++len;
                   1947:     /* full speed here */
                   1948:     while(1) {
                   1949:         if(--len) *ptr0++ = *line++; else break;
                   1950:         if(--len) *ptr1++ = *line++; else break;
                   1951:         if(--len) *ptr2++ = *line++; else break;
                   1952:         if(--len) *ptr3++ = *line++; else break;
                   1953:     }
                   1954: #endif
                   1955: }
                   1956: 
                   1957: /****************************************************************************/
                   1958: 
                   1959: #define MAKEID(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|d)
                   1960: 
                   1961: static int SaveIFF(char *filename, struct Screen *scr)
                   1962: {
                   1963:     struct DisplayInfo DI;
                   1964:     FILE *file;
                   1965:     ULONG BODYsize;
                   1966:     ULONG modeid;
                   1967:     ULONG count;
                   1968:     ULONG i;
                   1969:     
                   1970:     struct {ULONG iff_type, iff_length;} chunk;
                   1971:     struct {ULONG fc_type, fc_length, fc_subtype;} FORM;
                   1972:     struct {
                   1973:         UWORD w,h,x,y;
                   1974:         UBYTE depth,masking,compression,pad1;
                   1975:         UWORD transparentColor;
                   1976:         UBYTE xAspect,yAspect;
                   1977:         WORD  pagewidth,pageheight;
                   1978:     } BMHD;
                   1979:     
                   1980:     BODYsize = scr->BitMap.Depth * scr->BitMap.Rows * 2 * ((scr->Width+15)/16);
                   1981:     modeid   = GetVPModeID(&S->ViewPort);
                   1982:     count    = scr->ViewPort.ColorMap->Count;
                   1983:     
                   1984:     FORM.fc_type    = MAKEID('F','O','R','M');
                   1985:     FORM.fc_length  = 4 +                 /* ILBM */
                   1986:                       8 + sizeof(BMHD) +  /* BMHD */
                   1987:                       8 + 4 +             /* CAMG */
                   1988:                       8 + 3*count +       /* CMAP */
                   1989:                       8 + BODYsize;       /* BODY */
                   1990:     FORM.fc_subtype = MAKEID('I','L','B','M');
                   1991:     
                   1992:     if(!(file = fopen(filename,"w"))) return 0;
                   1993:     if(fwrite(&FORM,sizeof(FORM),1,file)!=1) goto err;
                   1994: 
                   1995:     BMHD.w           = 
                   1996:     BMHD.pagewidth   = scr->Width;
                   1997:     BMHD.h           = 
                   1998:     BMHD.pageheight  = scr->Height;
                   1999:     BMHD.x           = 0;
                   2000:     BMHD.y           = 0;
                   2001:     BMHD.depth       = scr->BitMap.Depth;
                   2002:     BMHD.masking     = 0;
                   2003:     BMHD.compression = 0;
                   2004:     BMHD.pad1        = 0;
                   2005:     BMHD.transparentColor = 0;
                   2006:     BMHD.xAspect     = 22;
                   2007:     BMHD.yAspect     = 11;
                   2008: 
                   2009:     if(GetDisplayInfoData(NULL, (UBYTE *)&DI, sizeof(struct DisplayInfo), 
                   2010:                           DTAG_DISP, modeid)) {
                   2011:     BMHD.xAspect     = DI.Resolution.x;
                   2012:     BMHD.yAspect     = DI.Resolution.y;
                   2013:     }
                   2014: 
                   2015:     chunk.iff_type   = MAKEID('B','M','H','D');
                   2016:     chunk.iff_length = sizeof(BMHD);
                   2017:     if(fwrite(&chunk,sizeof(chunk),1,file)!=1 
                   2018:     || fwrite(&BMHD, sizeof(BMHD), 1,file)!=1) goto err;
                   2019: 
                   2020:     chunk.iff_type   = MAKEID('C','A','M','G');
                   2021:     chunk.iff_length = sizeof(modeid);
                   2022:     if(fwrite(&chunk, sizeof(chunk),   1,file)!=1
                   2023:     || fwrite(&modeid,chunk.iff_length,1,file)!=1) goto err;
                   2024: 
                   2025:    chunk.iff_type    = MAKEID('C','M','A','P');
                   2026:    chunk.iff_length  = 3 * count;
                   2027:    if(fwrite(&chunk,sizeof(chunk),1,file)!=1) goto err;
                   2028:    for(i=0; i<count; ++i) {
                   2029:       ULONG c = GetRGB4(scr->ViewPort.ColorMap, i);
                   2030:       UBYTE d;
                   2031:       d = (c>>8)&15;d |= d<<4;if(fwrite(&d,1,1,file)!=1) goto err;
                   2032:       d = (c>>4)&15;d |= d<<4;if(fwrite(&d,1,1,file)!=1) goto err;
                   2033:       d = (c>>0)&15;d |= d<<4;if(fwrite(&d,1,1,file)!=1) goto err;
                   2034:    }
                   2035: 
                   2036:    chunk.iff_type    = MAKEID('B','O','D','Y');
                   2037:    chunk.iff_length  = BODYsize;
                   2038:    if(fwrite(&chunk,sizeof(chunk),1,file)!=1) goto err;
                   2039:    {
                   2040:    int r,p;
                   2041:    struct BitMap *bm = S->RastPort.BitMap;
                   2042:    for(r=0; r<bm->Rows; ++r) for(p=0; p<bm->Depth; ++p)
                   2043:    if(fwrite(bm->Planes[p] + r*bm->BytesPerRow, 2*((S->Width+15)/16), 1, file)!=1) goto err;
                   2044:    }
                   2045:    
                   2046:    fclose(file);
                   2047:    return 1;
                   2048: err: 
                   2049:    fprintf(stderr,"Error writing to \"%s\"\n",filename);
                   2050:    fclose(file);
                   2051:    return 0;
                   2052:    }
                   2053: 
                   2054: /****************************************************************************/
                   2055: /* Here lies an algorithm to convert a 12bits truecolor buffer into a HAM
                   2056:  * buffer. That algorithm is quite fast and if you study it closely, you'll
                   2057:  * understand why there is no need for MMX cpu to subtract three numbers in
                   2058:  * the same time. I can think of a quicker algorithm but it'll need 4096*4096
                   2059:  * = 1<<24 = 16Mb of memory. That's why I'm quite proud of this one which
                   2060:  * only need roughly 64Kb (could be reduced down to 40Kb, but it's not
                   2061:  * worth as I use cidx as a buffer which is 128Kb long)..
                   2062:  ****************************************************************************/
                   2063: 
                   2064: static int dist4(LONG rgb1, LONG rgb2) /* computes distance very quickly */
                   2065: {
                   2066:     int d = 0, t;
                   2067:     t = (rgb1&0xF00)-(rgb2&0xF00); t>>=8; if (t<0) d -= t; else d += t;
                   2068:     t = (rgb1&0x0F0)-(rgb2&0x0F0); t>>=4; if (t<0) d -= t; else d += t;
                   2069:     t = (rgb1&0x00F)-(rgb2&0x00F); t>>=0; if (t<0) d -= t; else d += t;
                   2070: #if 0
                   2071:     t = rgb1^rgb2; 
                   2072:     if(t&15) ++d; t>>=4;
                   2073:     if(t&15) ++d; t>>=4;
                   2074:     if(t&15) ++d;
                   2075: #endif
                   2076:     return d;
                   2077: }
                   2078: 
                   2079: #define d_dst (00000+(UBYTE*)cidx) /* let's use cidx as a buffer */
                   2080: #define d_cmd (16384+(UBYTE*)cidx)
                   2081: #define h_buf (32768+(UBYTE*)cidx)
                   2082: 
                   2083: static int init_ham(void)
                   2084: {
                   2085:     int i,t,RGB;
                   2086: 
                   2087:     /* try direct color first */
                   2088:     for(RGB=0;RGB<4096;++RGB) {
                   2089:         int c,d;
                   2090:         c = d = 50;
                   2091:         for(i=0;i<16;++i) {
                   2092:             t = dist4(i*0x111, RGB);
                   2093:             if(t<d) {
                   2094:                 d = t;
                   2095:                 c = i;
                   2096:             }
                   2097:         }
                   2098:         i = (RGB&0x00F) | ((RGB&0x0F0)<<1) | ((RGB&0xF00)<<2);
                   2099:         d_dst[i] = (d<<2)|3; /* the "|3" is a trick to speedup comparison */
                   2100:         d_cmd[i] = c;        /* in the conversion process */
                   2101:     }
                   2102:     /* then hold & modify */
                   2103:     for(i=0;i<32768;++i) {
                   2104:         int dr, dg, db, d, c;
                   2105:         dr = (i>>10) & 0x1F; dr -= 0x10;if(dr<0) dr = -dr;
                   2106:         dg = (i>>5)  & 0x1F; dg -= 0x10;if(dg<0) dg = -dg;
                   2107:         db = (i>>0)  & 0x1F; db -= 0x10;if(db<0) db = -db;
                   2108:         c  = 0; d = 50;
                   2109:         t = dist4(0,  0*256 + dg*16 + db); if(t < d) {d = t;c = 0;}
                   2110:         t = dist4(0, dr*256 +  0*16 + db); if(t < d) {d = t;c = 1;}
                   2111:         t = dist4(0, dr*256 + dg*16 +  0); if(t < d) {d = t;c = 2;}
                   2112:         h_buf[i] = (d<<2) | c;
                   2113:     }
                   2114:     return 1;
                   2115: }
                   2116: 
                   2117: /* great algorithm: convert trucolor into ham using precalc buffers */
1.1.1.2   root     2118: #undef USE_BITFIELDS
1.1       root     2119: static void ham_conv(UWORD *src, UBYTE *buf, UWORD len)
                   2120: {
                   2121:     /* A good compiler (ie. gcc :) will use bfext/bfins instructions */
                   2122: #ifdef __SASC
                   2123:     union { struct { unsigned int _:17, r:5, g:5, b:5; } _; 
                   2124:            int all;} rgb, RGB;
                   2125: #else
1.1.1.2   root     2126:     union { struct { ULONG _:17,r:5,g:5,b:5;} _; ULONG all;} rgb, RGB;
1.1       root     2127: #endif
                   2128:     rgb.all = 0;
                   2129:     while(len--) {
                   2130:         UBYTE c,t;
                   2131:         RGB.all = *src++;
                   2132:         c = d_cmd[RGB.all];
                   2133:         /* cowabonga! */
                   2134:         t = h_buf[16912 + RGB.all - rgb.all];
1.1.1.2   root     2135: #ifndef USE_BITFIELDS
                   2136:         if(t<=d_dst[RGB.all]) {
                   2137:            static int ht[]={32+10,48+5,16+0}; ULONG m;
                   2138:            t &= 3; m = 0x1F<<(ht[t]&15); 
                   2139:             m = ~m; rgb.all &= m; 
                   2140:             m = ~m; m &= RGB.all;rgb.all |= m;
                   2141:            m >>= ht[t]&15;
                   2142:            c = (ht[t]&~15) | m;
                   2143:         } else {
                   2144:            rgb.all = c;
                   2145:            rgb.all <<= 5; rgb.all |= c; 
                   2146:            rgb.all <<= 5; rgb.all |= c; 
                   2147:         }
                   2148: #else   
1.1       root     2149:         if(t<=d_dst[RGB.all]) {
1.1.1.2   root     2150:             t&=3;
                   2151:             if(!t)        {c = 32; c |= (rgb._.r = RGB._.r);}
                   2152:             else {--t; if(!t) {c = 48; c |= (rgb._.g = RGB._.g);}
                   2153:             else              {c = 16; c |= (rgb._.b = RGB._.b);} }
1.1       root     2154:         } else rgb._.r = rgb._.g = rgb._.b = c;
1.1.1.2   root     2155: #endif
1.1       root     2156:         *buf++ = c;
                   2157:     }
                   2158: }
                   2159: 
1.1.1.2   root     2160: /****************************************************************************/
                   2161: 
                   2162: #ifdef POWERUP
                   2163: /* sam: here is the code to avoid spilled register trouble */
                   2164: static void myBltBitMapRastPort(struct BitMap *srcBitMap, long xSrc, 
                   2165:                                long ySrc, struct RastPort * destRP, 
                   2166:                                long xDest, long yDest, long xSize, 
                   2167:                                long ySize, unsigned long minterm)
                   2168: {
                   2169:     BltBitMapRastPort(srcBitMap,xSrc,ySrc,destRP,
                   2170:                      xDest,yDest,xSize,ySize,minterm);
                   2171: }
                   2172: static void myWritePixelLine8(struct RastPort* a, int b, int c, 
                   2173:                              int d, char *e, struct RastPort*f)
                   2174: {
                   2175:     WritePixelLine8(a,b,c,d,e,f);
                   2176: }
                   2177: static void myWritePixelArray8(struct RastPort *a, int b, int c,
                   2178:                               int d, int e, char *f, struct RastPort *g)
                   2179: {
                   2180:     WritePixelArray8(a,b,c,d,e,f,g);
                   2181: }
                   2182: #endif
                   2183: 

unix.superglobalmegacorp.com

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