home *** CD-ROM | disk | FTP | other *** search
- /*
- * UAE - The Un*x Amiga Emulator
- *
- * Amiga interface
- *
- * Copyright 1995, 1996 Bernd Schmidt
- * Copyright 1996 Samuel Devulder, Olaf `Olsen' Barthel.
- */
-
- /*
- * NOTE:
- * - Im quite unhappy with the color allocation scheme in case of
- * EXTRA_HALFBRITE...
- */
-
- #define USE_CYBERGFX /* undefine this if you don't have CYBERGFX includes */
-
- /****************************************************************************/
-
- #include <exec/execbase.h>
- #include <exec/memory.h>
-
- #include <graphics/gfxbase.h>
- #include <graphics/displayinfo.h>
-
- #include <libraries/asl.h>
- #include <intuition/pointerclass.h>
-
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/exec.h>
- #include <proto/asl.h>
-
- #ifdef USE_CYBERGFX
- #include <inline/cybergraphics.h>
- #endif
-
- /****************************************************************************/
-
- #include "sysconfig.h"
- #include "sysdeps.h"
-
- /****************************************************************************/
-
- #include "config.h"
- #include "options.h"
- #include "memory.h"
- #include "custom.h"
- #include "newcpu.h"
- #include "xwin.h"
- #include "keyboard.h"
- #include "keybuf.h"
- #include "gui.h"
-
- /****************************************************************************/
-
- static UBYTE *image_mem;
- static int need_dither; /* well.. guess :-) */
- static int use_low_bandwidth; /* this will redraw only needed places */
- static int use_cyb; /* this is for cybergfx */
- xcolnr xcolors[4096];
- /* Keyboard and mouse */
-
- static int keystate[256];
-
- int buttonstate[3];
- int lastmx, lastmy;
- int newmousecounters;
-
- static int inwindow;
-
- static int vsize, hsize, hpixels;
- static char *oldpixbuf;
-
- struct vidbuf_description gfxvidinfo;
-
- /****************************************************************************/
- /*
- * prototypes & global vars
- */
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- struct Library *AslBase;
- struct Library *CyberGfxBase;
-
- static UBYTE *Line;
- static struct RastPort *RP;
- static struct Screen *S;
- static struct Window *W;
- static struct RastPort *TempRPort;
- static struct BitMap *BitMap;
- static struct ColorMap *CM;
- static Object *Pointer; /* for os 39 */
- static UWORD *Sprite;
-
- static int os39; /* kick 39 present */
- static int usepub; /* use public screen */
- static int halfv; /* halve height for non interlaced screen */
- static int usecyb; /* use cybergraphics.library */
- static int is_halfbrite;
-
- static int get_color_failed;
- static int maxpen;
- static UBYTE pen[256];
-
- static struct BitMap *myAllocBitMap(ULONG,ULONG,ULONG,ULONG,struct BitMap *);
- static void set_title(void);
- static void myFreeBitMap(struct BitMap *);
- static LONG ObtainColor(ULONG, ULONG, ULONG);
- static void ReleaseColors(void);
- static void DoSizeWindow(struct Window *,int,int);
-
- /****************************************************************************/
-
- __inline__ void flush_line(int y)
- {
- int xs, len;
- int yoffset = y*gfxvidinfo.rowbytes;
- char *linebuf = gfxvidinfo.bufmem + yoffset;
- char *src, *dst;
-
- if(halfv && (y&1)) return;
-
- if (gfxvidinfo.maxlinetoscr)
- len = gfxvidinfo.maxlinetoscr;
- else
- len = hsize;
-
- switch(gfxvidinfo.pixbytes) {
- case 4:
- { /* sam: we should not arrive here on the amiga */
- fprintf(stderr, "Bug in flush_line() !\n");
- abort();
- return;
- }
- break;
- case 2:
- {
- short *newp = (short *)linebuf;
- short *oldp = (short *)(oldpixbuf + yoffset);
- while (*newp++ == *oldp++) if(!--len) return;
- src = (char *)--newp;
- dst = (char *)--oldp;
- newp += len;
- oldp += len;
- while (*--newp == *--oldp);
- len = 1 + (oldp - (short *)dst);
- xs = (src - linebuf)/2;
- CopyMem (src, dst, len * 2);
- } break;
- case 1:
- {
- char *newp = (char *)linebuf;
- char *oldp = (char *)(oldpixbuf + yoffset);
- while (*newp++ == *oldp++) if(!--len) return;
- src = (char *)--newp;
- dst = (char *)--oldp;
- newp += len;
- oldp += len;
- while (*--newp == *--oldp);
- len = 1 + (oldp - (char *)dst);
- xs = (src - linebuf);
- CopyMem (src, dst, len);
- } break;
-
- default:
- abort();
- break;
- }
-
- if(halfv) y>>=1;
-
- if (need_dither) {
- DitherLine(Line, (UWORD *)dst, xs, y, (len+3)&~3, 8);
- } else CopyMem(dst, Line, len);
-
- if (use_cyb)
- CopyMem(Line, image_mem + xs + yoffset, len);
- else
- WritePixelLine8(RP, xs, y, len, Line, TempRPort);
- }
-
- /****************************************************************************/
-
- void flush_block (int ystart, int ystop)
- {
- if(need_dither || !use_cyb) {
- int y;
- for(y=ystart; y<=ystop; ++y) flush_line(y);
- }
- }
-
- /****************************************************************************/
-
- void flush_screen (int ystart, int ystop)
- {
- /* WaitBOVP() ? */
- }
-
- /****************************************************************************/
-
- void calc_adjustment(void)
- {
- switch (screen_res) {
- case 0: case 1: case 2: /* LoRes, 320x200 */
- gfxvidinfo.x_adjust = prev_max_diwstop - 320;
- break;
-
- case 3: /* 640x480 */
- gfxvidinfo.x_adjust = prev_max_diwstop - 640;
- break;
- default:
- gfxvidinfo.x_adjust = 0;
- break;
- }
- }
-
- /****************************************************************************/
-
- static int get_color(int r, int g, int b, xcolnr *cnp)
- {
- int col;
-
- r *= 0x11111111;
- g *= 0x11111111;
- b *= 0x11111111;
- col = ObtainColor(r, g, b);
-
- if(col == -1) {
- get_color_failed = 1;
- return 0;
- }
-
- *cnp = col;
- return 1;
- }
-
- /****************************************************************************/
- /*
- * FIXME: find a better way to determine closeness of colors (closer to
- * human perception).
- */
- static __inline__ int calc_err(int r1, int g1, int b1,
- int r2, int g2, int b2)
- {
- int err = 0;
-
- if((r1>7 && r2<=7) || (r1<=7 && r2>7)) err += 1;
- if((g1>7 && g2<=7) || (g1<=7 && g2>7)) err += 1;
- if((b1>7 && b2<=7) || (b1<=7 && b2>7)) err += 1;
-
- r1 -= r2; g1 -= g2; b1 -= b2;
- r1 *= 2; g1 *= 3; b1 *= 1;
- err += r1*r1 + g1*g1 + b1*b1;
-
- return err;
- }
-
- /****************************************************************************/
-
- static int get_nearest_color(int r, int g, int b)
- {
- int i, best, err, besterr;
- int colors;
- int br=0,bg=0,bb=0;
-
- best = 0;
- besterr = calc_err(0,0,0, 15,15,15);
- colors = is_halfbrite?32:(1<<RP->BitMap->Depth);
-
- for(i=0; i<colors; i++ ) {
- long rgb = GetRGB4(CM, i);
- int cr, cg, cb;
-
- cr = (rgb >> 8) & 15;
- cg = (rgb >> 4) & 15;
- cb = (rgb >> 0) & 15;
-
- err = calc_err(r,g,b, cr,cg,cb);
-
- if(err < besterr) {
- best = i;
- besterr = err;
- br=cr; bg=cg; bb=cb;
- }
-
- if(is_halfbrite) {
- cr /= 2; cg /= 2; cb /= 2;
- err = calc_err(r,g,b, cr,cg,cb);
- if(err < besterr) {
- best = i + 32;
- besterr = err;
- br=cr; bg=cg; bb=cb;
- }
- }
- }
- return best;
- }
-
- /****************************************************************************/
-
- static int init_colors(void)
- {
- if (need_dither) {
- /* first try color allocation */
- int bitdepth = usepub ? RP->BitMap->Depth : 8;
- int maxcol;
-
- if(bitdepth>=3)
- do {
- get_color_failed = 0;
- setup_dither(bitdepth, get_color);
- if(get_color_failed) ReleaseColors();
- } while(get_color_failed && --bitdepth>=3);
-
- if(bitdepth >= 3) {
- printf("Color dithering with %d bits\n",bitdepth);
- return 1;
- }
-
- /* if that fail then try grey allocation */
- maxcol = 1<<(usepub ? RP->BitMap->Depth : 8);
-
- do {
- get_color_failed = 0;
- setup_greydither_maxcol(maxcol, get_color);
- if(get_color_failed) ReleaseColors();
- } while(get_color_failed && --maxcol>=2);
-
- if (maxcol >= 2) {
- printf("Gray dither with %d shades\n",maxcol);
- return 1;
- }
-
- return 0; /* everything failed :-( */
- }
-
- /* No dither */
- switch(RP->BitMap->Depth) {
- case 6: if (is_halfbrite) {
- static int tab[]={
- 0x000, 0x00f, 0x0f0, 0x0ff, 0x08f, 0x0f8, 0xf00, 0xf0f,
- 0x80f, 0xff0, 0xfff, 0x88f, 0x8f0, 0x8f8, 0x8ff, 0xf08,
- 0xf80, 0xf88, 0xf8f, 0xff8, /* end of regular pattern */
- 0xa00, 0x0a0, 0xaa0, 0x00a, 0xa0a, 0x0aa, 0xaaa,
- 0xfaa, 0xf6a, 0xa80, 0x06a, 0x6af };
- int i;
- for(i=0;i<32;++i) get_color(tab[i]>>8, (tab[i]>>4)&15, tab[i]&15, xcolors);
- for(i=0;i<4096;++i) xcolors[i] = get_nearest_color(i>>8, (i>>4)&15, i&15);
- break;
- }
-
- case 1: case 2: case 3: case 4: case 5: case 7: case8: {
- int maxcol = 1<<RP->BitMap->Depth;
-
- if(maxcol>=8) do {
- get_color_failed = 0;
- setup_maxcol(maxcol);
- alloc_colors256(get_color);
- if(get_color_failed) ReleaseColors();
- } while(get_color_failed && --maxcol>=8);
- else {
- int i;
- for(i=0;i<maxcol;++i) {
- get_color((i*15)/(maxcol-1), (i*15)/(maxcol-1), (i*15)/(maxcol-1), xcolors);
- }
- }
- printf("Using %d colors\n",maxcol);
- for(maxcol=0;maxcol<4096;++maxcol)
- xcolors[maxcol] = get_nearest_color(maxcol>>8, (maxcol>>4)&15, maxcol&15);
- } break;
-
- case 15:
- alloc_colors64k(5,5,5,10,5,0);
- break;
-
- case 16:
- alloc_colors64k(5,6,5,11,5,0);
- break;
-
- case 24: case 32:
- alloc_colors64k(8,8,8,16,8,0);
- break;
- }
- return 1;
- }
-
- /****************************************************************************/
-
- static void setup_sprite(struct Window *W)
- {
- Sprite = AllocVec(4+2, MEMF_CHIP|MEMF_CLEAR);
- if(!Sprite) {
- fprintf(stderr, "Warning: Can not alloc sprite buffer !\n");
- return;
- }
- Sprite[2] = 0x8000; Sprite[3] = 0x8000;
- SetPointer(W, Sprite, 1, 16, -1, 0);
- }
-
- /****************************************************************************/
-
- static int setup_customscreen(void)
- {
- struct NewScreen NewScreenStructure = {
- 0,0, 800,600, 3, 0,1,
- LACE+HIRES, CUSTOMSCREEN|SCREENQUIET|SCREENBEHIND,
- NULL, (void*)"UAE", NULL, NULL};
- struct NewWindow NewWindowStructure = {
- 0,0, 800,600, 0,1,
- IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_DISKINSERTED|IDCMP_DISKREMOVED|
- IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW|IDCMP_MOUSEMOVE,
- WFLG_SMART_REFRESH|WFLG_BACKDROP|WFLG_RMBTRAP|WFLG_NOCAREREFRESH|
- WFLG_BORDERLESS|WFLG_WINDOWACTIVE|WFLG_REPORTMOUSE,
- NULL, NULL, (void*)"UAE", NULL, NULL, 5,5, 800,600,
- CUSTOMSCREEN};
-
- NewScreenStructure.Width = hpixels;
- NewScreenStructure.Height = vsize;
- NewScreenStructure.Depth = os39?8:(use_lores?5:4);
- NewScreenStructure.ViewModes = SPRITES | (use_lores ? NULL : HIRES) |
- (correct_aspect ? LACE : NULL);
-
- do S = (void*)OpenScreen(&NewScreenStructure);
- while(!S && --NewScreenStructure.Depth);
- if(!S) {
- fprintf(stderr, "Can't open custom screen !\n");
- return 0;
- }
-
- CM = S->ViewPort.ColorMap;
- RP = &S->RastPort;
-
- NewWindowStructure.Width = S->Width;
- NewWindowStructure.Height = S->Height;
- NewWindowStructure.Screen = S;
- W = (void*)OpenWindow(&NewWindowStructure);
- if(!W) {
- fprintf(stderr, "Can't open window on custom screen !\n");
- return 0;
- }
- setup_sprite(W);
- return 1;
- }
-
- /****************************************************************************/
-
- static int setup_publicscreen(void)
- {
- struct NewWindow NewWindowStructure = {
- 0,0, 800,600, 0,1,
- IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_DISKINSERTED|IDCMP_DISKREMOVED|
- IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW|IDCMP_MOUSEMOVE,
- WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_SMART_REFRESH|WFLG_REPORTMOUSE|
- WFLG_RMBTRAP|WFLG_GIMMEZEROZERO|WFLG_ACTIVATE|WFLG_NOCAREREFRESH,
- NULL, NULL, (void*)"UAE", NULL, NULL, 5,5, 800,600,
- PUBLICSCREEN};
-
- S = LockPubScreen(NULL);
- if(!S) {
- fprintf(stderr,"No public screen !\n");
- return 0;
- }
-
- CM = S->ViewPort.ColorMap;
-
- halfv = (S->ViewPort.Modes & (HIRES|LACE))==HIRES;
-
- NewWindowStructure.Width = hpixels;
- NewWindowStructure.Height = vsize >> (halfv?1:0);
- NewWindowStructure.Screen = S;
-
- W = (void*)OpenWindow(&NewWindowStructure);
- UnlockPubScreen(NULL, S);
- if(!W) {
- fprintf(stderr,"Can't open window on public screen !\n");
- CM = NULL;
- return 0;
- }
- DoSizeWindow(W, NewWindowStructure.Width, NewWindowStructure.Height);
- RP = W->RPort;
- setup_sprite(W);
- return 1;
- }
-
- /****************************************************************************/
-
- static int setup_userscreen(void)
- {
- struct ScreenModeRequester *ScreenRequest;
- ULONG DisplayID;
- struct BitMap PointerBitMap;
- UWORD PointerLine;
- LONG ScreenWidth=0,ScreenHeight=0,Depth=0;
- UWORD OverscanType=0;
- BOOL AutoScroll=0;
-
- #ifdef USE_CYBERGFX
- CyberGfxBase = OpenLibrary("cybergraphics.library",40);
- #endif
- AslBase = OpenLibrary("asl.library",38);
- if(!AslBase) {
- fprintf(stderr,"Can't open asl.library v38 !");
- return 0;
- }
-
- ScreenRequest = AllocAslRequest(ASL_ScreenModeRequest,NULL);
- if(!ScreenRequest) {
- fprintf(stderr,"Unable to allocate screen mode requester.\n");
- return 0;
- }
-
- if(AslRequestTags(ScreenRequest,
- ASLSM_TitleText, (ULONG)"Select screen display mode",
- ASLSM_InitialDisplayID, NULL,
- ASLSM_InitialDisplayDepth, 8,
- ASLSM_InitialDisplayWidth, hsize,
- ASLSM_InitialDisplayHeight,vsize,
- ASLSM_MinWidth, hsize,
- ASLSM_MinHeight, vsize,
- ASLSM_DoWidth, TRUE,
- ASLSM_DoHeight, TRUE,
- ASLSM_DoDepth, TRUE,
- ASLSM_DoOverscanType, TRUE,
- ASLSM_PropertyFlags, 0,
- ASLSM_PropertyMask, DIPF_IS_DUALPF |
- DIPF_IS_PF2PRI |
- DIPF_IS_HAM |
- 0,
- TAG_DONE)) {
- ScreenWidth = ScreenRequest->sm_DisplayWidth;
- ScreenHeight = ScreenRequest->sm_DisplayHeight;
- Depth = ScreenRequest->sm_DisplayDepth;
- DisplayID = ScreenRequest->sm_DisplayID;
- OverscanType = ScreenRequest->sm_OverscanType;
- AutoScroll = ScreenRequest->sm_AutoScroll;
- if(ScreenWidth < hsize) ScreenWidth = hsize;
- if(ScreenHeight < vsize) ScreenHeight = vsize;
- }
- else DisplayID = INVALID_ID;
- FreeAslRequest(ScreenRequest);
-
- if(DisplayID == (ULONG)INVALID_ID) return 0;
-
- #ifdef USE_CYBERGFX
- if(CyberGfxBase && IsCyberModeID(DisplayID)) use_cyb = 1;
- #endif
-
- S = OpenScreenTags(NULL,
- SA_DisplayID, DisplayID,
- SA_Width, ScreenWidth,
- SA_Height, ScreenHeight,
- SA_Depth, Depth,
- SA_Overscan, OverscanType,
- SA_AutoScroll, AutoScroll,
- SA_ShowTitle, FALSE,
- SA_Quiet, TRUE,
- SA_Behind, TRUE,
- /* v39 stuff here: */
- (os39?SA_BackFill:TAG_DONE), (ULONG)LAYERS_NOBACKFILL,
- SA_SharePens, TRUE,
- SA_Exclusive, (use_cyb?TRUE:FALSE),
- SA_Draggable, (use_cyb?FALSE:TRUE),
- SA_Interleaved, TRUE,
- TAG_DONE);
- if(!S) {
- fprintf(stderr,"Unable to open the screen.\n");
- return 0;
- }
-
- RP = &S->RastPort;
- CM = S->ViewPort.ColorMap;
- is_halfbrite = (S->ViewPort.Modes & EXTRA_HALFBRITE);
-
- PointerLine = 0x0000;
- InitBitMap(&PointerBitMap,2,16,1);
- PointerBitMap.Planes[0] = (PLANEPTR)&PointerLine;
- PointerBitMap.Planes[1] = (PLANEPTR)&PointerLine;
-
- Pointer = NewObject(NULL,POINTERCLASS,
- POINTERA_BitMap, (ULONG)&PointerBitMap,
- POINTERA_WordWidth, 1,
- TAG_DONE);
- if(!Pointer)
- fprintf(stderr,"Warning: Unable to allocate blank mouse pointer.\n");
-
- W = OpenWindowTags(NULL,
- WA_Width, S->Width,
- WA_Height, S->Height,
- WA_CustomScreen, (ULONG)S,
- WA_Backdrop, TRUE,
- WA_Borderless, TRUE,
- WA_RMBTrap, TRUE,
- WA_ReportMouse, TRUE,
- WA_IDCMP, IDCMP_MOUSEBUTTONS|
- IDCMP_RAWKEY|
- IDCMP_DISKINSERTED|
- IDCMP_DISKREMOVED|
- IDCMP_ACTIVEWINDOW|
- IDCMP_INACTIVEWINDOW|
- IDCMP_MOUSEMOVE,
- (os39?WA_BackFill:TAG_IGNORE), (ULONG)LAYERS_NOBACKFILL,
- (Pointer?WA_Pointer:TAG_IGNORE), (ULONG)Pointer,
- TAG_DONE);
-
- if(!W) {
- fprintf(stderr,"Unable to open the window.\n");
- CloseScreen(S);S=NULL;RP=NULL;CM=NULL;
- return 0;
- }
- if(!Pointer) setup_sprite(W);
- return 1;
- }
-
- /****************************************************************************/
-
- int graphics_init(void)
- {
- int i,bitdepth;
-
- use_low_bandwidth = 0;
- need_dither = 0;
- use_cyb = 0;
-
- if (screen_res < 3) {
- fprintf(stderr, "Low resolution mode selected. Forcing 320x200.\n");
- }
-
- vsize = correct_aspect ? 2*numscrlines : numscrlines;
- switch (screen_res) {
- case 0: case 1: case 2:
- hsize = hpixels = 320;
- break;
- case 3:
- hsize = hpixels = 640;
- break;
- case 4:
- hpixels = 796; hsize = 800; /* ??? */
- break;
- }
- gfxvidinfo.maxlinetoscr = hpixels;
-
- if(SysBase->LibNode.lib_Version < 36) {
- fprintf(stderr, "UAE needs os 2.0+ !\n");
- return 0;
- }
- os39 = (SysBase->LibNode.lib_Version>=39);
-
- atexit(graphics_leave);
-
- IntuitionBase = (void*)OpenLibrary("intuition.library",0L);
- if(!IntuitionBase) {
- fprintf(stderr,"No intuition.library ?\n");
- return 0;
- }
- GfxBase = (void*)OpenLibrary("graphics.library",0L);
- if(!GfxBase) {
- fprintf(stderr,"No graphics.library ?\n");
- return 0;
- }
-
- switch(color_mode) {
- case 2:
- if(setup_userscreen()) break;
- fprintf(stderr,"Trying on public screen...\n");
- /* fall trough */
- case 1:
- is_halfbrite = 0;
- if(setup_publicscreen()) {usepub = 1;break;}
- fprintf(stderr,"Trying on custom screen...\n");
- /* fall trough */
- case 0:
- if(!setup_customscreen()) return 0;
- break;
- }
-
- Line = AllocVec((hsize + 15) & ~15,MEMF_ANY|MEMF_PUBLIC);
- if(!Line) {
- fprintf(stderr,"Unable to allocate raster buffer.\n");
- return 0;
- }
- BitMap = myAllocBitMap(hsize,1,8,BMF_CLEAR|BMF_MINPLANES,RP->BitMap);
- if(!BitMap) {
- fprintf(stderr,"Unable to allocate BitMap.\n");
- return 0;
- }
- TempRPort = AllocVec(sizeof(struct RastPort),MEMF_ANY|MEMF_PUBLIC);
- if(!TempRPort) {
- fprintf(stderr,"Unable to allocate RastPort.\n");
- return 0;
- }
- CopyMem(RP,TempRPort,sizeof(struct RastPort));
- TempRPort->Layer = NULL;
- TempRPort->BitMap = BitMap;
-
- if(usepub) set_title();
-
- bitdepth = RP->BitMap->Depth;
- if(bitdepth <= 8) {
- gfxvidinfo.pixbytes = use_xhair?1:2;
- /* chunk2planar is slow so we define use_low_bandwidth for all modes
- except cybergraphics modes */
- use_low_bandwidth = 1;
- need_dither = use_xhair && (bitdepth>1) ? 0 : 1;
- } else {
- gfxvidinfo.pixbytes = (bitdepth == 24 || bitdepth == 32 ? 4
- : bitdepth == 12 || bitdepth == 16 ? 2
- : 1);
- }
-
- if (!use_cyb) {
- gfxvidinfo.rowbytes = gfxvidinfo.pixbytes * hsize;
- gfxvidinfo.bufmem = (char *)calloc(gfxvidinfo.rowbytes, vsize+1);
- /* ^^ */
- /* This is because DitherLine may read one extra row */
- } else {
- #ifdef USE_CYBERGFX
- if(!need_dither) {
- gfxvidinfo.bufmem = (char *)GetCyberMapAttr(RP->BitMap,
- CYBRMATTR_DISPADR);
- gfxvidinfo.rowbytes = GetCyberMapAttr(RP->BitMap,CYBRMATTR_XMOD);
- gfxvidinfo.pixbytes = GetCyberMapAttr(RP->BitMap,CYBRMATTR_BPPIX);
- } else {
- image_mem = (char *)GetCyberMapAttr(RP->BitMap,CYBRMATTR_DISPADR);
- gfxvidinfo.rowbytes = GetCyberMapAttr(RP->BitMap,CYBRMATTR_XMOD);
- gfxvidinfo.pixbytes = GetCyberMapAttr(RP->BitMap,CYBRMATTR_BPPIX);
- gfxvidinfo.bufmem = (char *)calloc(gfxvidinfo.rowbytes, vsize+1);
- }
- #endif
- }
- if(!gfxvidinfo.bufmem) {
- fprintf(stderr,"Not enough memory.\n");
- return 0;
- }
-
- gfxvidinfo.maxline = 100000; /* no limit */
-
- if (use_low_bandwidth) {
- gfxvidinfo.maxblocklines = vsize; /* it seems to increase the speed */
- oldpixbuf = (char *)calloc(gfxvidinfo.rowbytes, vsize);
- if(!oldpixbuf) {
- fprintf(stderr,"Not enough memory.\n");
- return 0;
- }
- } else {
- gfxvidinfo.maxblocklines = 100; /* whatever... */
- }
-
- if (!init_colors())
- return 0;
-
- if(!usepub) ScreenToFront(S);
-
- buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
- for(i=0; i<256; i++)
- keystate[i] = 0;
-
- lastmx = lastmy = 0;
- newmousecounters = 0;
- inwindow = 0;
-
- return 1;
- }
-
- /****************************************************************************/
-
- void graphics_leave(void)
- {
- if(BitMap) {
- WaitBlit();
- myFreeBitMap(BitMap);
- BitMap = NULL;
- }
- if(TempRPort) {
- FreeVec(TempRPort);
- TempRPort = NULL;
- }
- if(Line) {
- FreeVec(Line);
- Line = NULL;
- }
- if(CM) {
- ReleaseColors();
- CM = NULL;
- }
- if(W) {
- CloseWindow(W);
- W = NULL;
- }
- if(Sprite) {
- FreeVec(Sprite);
- Sprite = NULL;
- }
- if(Pointer) {
- DisposeObject(Pointer);
- Pointer = NULL;
- }
- if(!usepub && S) {
- CloseScreen(S);
- S = NULL;
- }
- if(AslBase) {
- CloseLibrary((void*)AslBase);
- AslBase = NULL;
- }
- if(GfxBase) {
- CloseLibrary((void*)GfxBase);
- GfxBase = NULL;
- }
- if(IntuitionBase) {
- CloseLibrary((void*)IntuitionBase);
- IntuitionBase = NULL;
- }
- if(CyberGfxBase) {
- CloseLibrary((void*)CyberGfxBase);
- CyberGfxBase = NULL;
- }
- }
-
-
- /***************************************************************************/
-
- void handle_events(void)
- {
- struct IntuiMessage *msg;
- int mx,my,class,code;
-
- newmousecounters = 0;
- gui_handle_events();
-
- while((msg=(struct IntuiMessage*)GetMsg(W->UserPort))) {
- class = msg->Class;
- code = msg->Code;
- mx = msg->MouseX;
- my = msg->MouseY;
- ReplyMsg((struct Message*)msg);
-
- if(usepub) {
- mx -= W->BorderLeft;
- my -= W->BorderTop;
- }
-
- switch(class) {
- case RAWKEY: {
- int kc = code&127;
- int released = code&128?1:0;
-
- if(released) {
- keystate[kc] = 0;
- record_key ((kc << 1) | 1);
- } else if (!keystate[kc]) {
- keystate[kc] = 1;
- record_key (kc << 1);
- }
- } break;
-
- case MOUSEMOVE:
- if(inwindow) {
- lastmx = mx;
- lastmy = my << (halfv?1:0);
- } break;
-
- case MOUSEBUTTONS:
- if(code==SELECTDOWN) buttonstate[0]=1;
- if(code==SELECTUP) buttonstate[0]=0;
- if(code==MENUDOWN) buttonstate[2]=1;
- if(code==MENUUP) buttonstate[2]=0;
- break;
-
- /* Those 2 could be of some use later. */
- case DISKINSERTED:
- /*printf("diskinserted(%d)\n",code);*/
- break;
-
- case DISKREMOVED:
- /*printf("diskremoved(%d)\n",code);*/
- break;
-
- case ACTIVEWINDOW:
- inwindow = 1;
- newmousecounters = 1;
- lastmx = mx;
- lastmy = my<<(halfv?1:0);
- break;
-
- case INACTIVEWINDOW:
- inwindow = 0;
- break;
-
- default:
- fprintf(stderr, "Unknown class: %d\n",class);
- break;
- }
- }
- /* "Affengriff" */
- if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
- MC68000_reset();
-
- /* PC-like :-) CTRL-ALT-DEL => reboot */
- if(keystate[AK_CTRL] && (keystate[AK_LALT] || keystate[AK_RALT]) &&
- keystate[AK_DEL])
- MC68000_reset();
-
- /* CTRL+LSHIFT+LALT+F10 on amiga => F12 on X11 */
- if(keystate[AK_CTRL] && keystate[AK_LSH] && keystate[AK_LALT] && keystate[AK_F10])
- togglemouse();
- }
-
- /***************************************************************************/
-
- void target_specific_usage(void)
- {
- printf("\n");
- printf("----------------------------------------------------------------------------\n");
- printf("AMIGA SPECIFIC USAGE:\n");
- printf(" -x : Does not use dithering\n");
- printf(" On the amiga, Valid resolution (see -d) are:\n");
- printf(" 0, 1, 2 (320x256); 3 (640x512); 4 (800x600).\n");
- printf(" And valid color modes (see -H) are:\n");
- printf(" 0 => 256 cols max on customscreen;\n");
- printf(" 1 => OpenWindow on default public screen;\n");
- printf(" 2 => Ask the user to select a screen mode with ASL requester.\n");
- printf("----------------------------------------------------------------------------\n");
- printf("\n");
- }
-
- /***************************************************************************/
-
- int debuggable(void)
- {
- return 1;
- }
-
- /***************************************************************************/
-
- int needmousehack(void)
- {
- return 1;
- }
-
- /***************************************************************************/
-
- void LED(int on)
- {
- }
-
- /***************************************************************************/
-
- static int led_state[5];
-
- static void set_title(void)
- {
- static char title[80];
-
- if(!usepub) return;
- sprintf(title,"UAE - Power: [%c] Drives: [%c] [%c] [%c] [%c]",
- led_state[0]?'X':' ',
- led_state[1]?'0':' ',
- led_state[2]?'1':' ',
- led_state[3]?'2':' ',
- led_state[4]?'3':' ');
-
- SetWindowTitles(W,title,(char*)-1);
- }
-
- /***************************************************************************/
- /*
- * gui code
- */
- int quit_program;
-
- static void sigchldhandler(int foo)
- {
- }
-
- int gui_init(void)
- {
- quit_program = 0;
- return 0;
- }
-
- void gui_exit(void)
- {
- }
-
- void gui_led(int led, int on)
- {
- if(led>=0 && led<=4) led_state[led] = on;
- set_title();
- }
-
- void gui_filename(int num, char *name)
- {
- }
-
- static void getline(char *p)
- {
- }
-
- void gui_handle_events(void)
- {
- }
-
- /****************************************************************************/
- /*
- * Routines for OS2.0 (code taken out of mpeg_play by Michael Balzer)
- */
- static struct BitMap *myAllocBitMap(ULONG sizex, ULONG sizey, ULONG depth,
- ULONG flags, struct BitMap *friend_bitmap)
- {
- struct BitMap *bm;
- unsigned long extra;
-
- if(os39) return AllocBitMap(sizex, sizey, depth, flags, friend_bitmap);
-
- extra = (depth > 8) ? depth - 8 : 0;
- bm = AllocVec( sizeof *bm + (extra * 4), MEMF_CLEAR );
-
- if( bm )
- {
- ULONG i;
- InitBitMap(bm, depth, sizex, sizey);
- for( i=0; i<depth; i++ )
- {
- if( !(bm->Planes[i] = AllocRaster(sizex, sizey)) )
- {
- while(i--) FreeRaster(bm->Planes[i], sizex, sizey);
- FreeVec(bm);
- bm = 0;
- break;
- }
- }
- }
- return bm;
- }
-
- /****************************************************************************/
-
- static void myFreeBitMap(struct BitMap *bm)
- {
- if(os39) {FreeBitMap(bm);return;}
- while(bm->Depth--)
- FreeRaster(bm->Planes[bm->Depth], bm->BytesPerRow*8, bm->Rows);
- FreeVec(bm);
- }
-
- /****************************************************************************/
- /*
- * find the best appropriate color return -1 if none is available
- */
- static LONG ObtainColor(ULONG r,ULONG g,ULONG b)
- {
- int i, crgb;
- int colors;
-
- if(os39 && usepub) {
- i = ObtainBestPen(CM,r,g,b,
- OBP_Precision, PRECISION_EXACT,
- OBP_FailIfBad, TRUE,
- TAG_DONE);
- if(i != -1) {
- if(maxpen<256) pen[maxpen++] = i;
- else i = -1;
- }
- return i;
- }
-
- r >>= 28; g >>= 28; b >>= 28;
-
- colors = is_halfbrite?32:(1<<RP->BitMap->Depth);
-
- /* private screen => standard allocation */
- if(!usepub) {
- if(maxpen >= colors) return -1; /* no more colors available */
- SetRGB4(&S->ViewPort, maxpen, r, g, b);
- return maxpen++;
- }
-
- /* public => find exact match */
- crgb = (r<<8)|(g<<4)|b;
- for(i=0; i<colors; i++ ) {
- int rgb = GetRGB4(CM, i);
- if(rgb == crgb) return i;
- }
- return -1;
- }
-
- /****************************************************************************/
- /*
- * free a color entry
- */
- static void ReleaseColors(void)
- {
- if(os39 && usepub && CM)
- while(maxpen>0) ReleasePen(CM, pen[--maxpen]);
- else maxpen = 0;
- }
-
- /****************************************************************************/
-
- static void DoSizeWindow(struct Window *W,int wi,int he)
- {
- register int x,y;
-
- wi += W->BorderRight + W->BorderLeft;
- he += W->BorderBottom + W->BorderTop;
- x = W->LeftEdge;
- y = W->TopEdge;
-
- if(x + wi >= W->WScreen->Width) x = W->WScreen->Width - wi;
- if(y + he >= W->WScreen->Height) y = W->WScreen->Height - he;
-
- x -= W->LeftEdge;
- y -= W->TopEdge;
- wi -= W->Width;
- he -= W->Height;
-
- if(x|y) MoveWindow(W,x,y);
- if(wi|he) SizeWindow(W,wi,he);
- }
-