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