|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * BeBox port specific stuff ! 5: * ! 6: * (c) 1996-1998 Christian Bauer ! 7: * (c) 1996 Patrick Hanevold ! 8: */ ! 9: ! 10: #include <AppKit.h> ! 11: #include <InterfaceKit.h> ! 12: #include <KernelKit.h> ! 13: #include <MediaKit.h> ! 14: #include <StorageKit.h> ! 15: #include <device/Joystick.h> ! 16: ! 17: extern "C" { ! 18: #include "sysconfig.h" ! 19: #include "sysdeps.h" ! 20: #include "config.h" ! 21: #include "options.h" ! 22: #include "threaddep/penguin.h" ! 23: #include "uae.h" ! 24: #include "gensound.h" ! 25: #include "sounddep/sound.h" ! 26: #include "events.h" ! 27: #include "memory.h" ! 28: #include "custom.h" ! 29: #include "readcpu.h" ! 30: #include "newcpu.h" ! 31: #include "disk.h" ! 32: #include "gui.h" ! 33: #include "debug.h" ! 34: #include "xwin.h" ! 35: #include "joystick.h" ! 36: #include "keyboard.h" ! 37: #include "keybuf.h" ! 38: #include "gui.h" ! 39: #include "zfile.h" ! 40: #include "picasso96.h" ! 41: } ! 42: ! 43: ! 44: // Constants ! 45: const char APP_SIGNATURE[] = "application/x-vnd.cebix-UAE"; ! 46: ! 47: const uint32 MSG_INSERT_DF0 = 'idf0'; // Messages ! 48: const uint32 MSG_EJECT_DF0 = 'edf0'; ! 49: const uint32 MSG_INSERT_DF1 = 'idf1'; ! 50: const uint32 MSG_EJECT_DF1 = 'edf1'; ! 51: const uint32 MSG_INSERT_DF2 = 'idf2'; ! 52: const uint32 MSG_EJECT_DF2 = 'edf2'; ! 53: const uint32 MSG_INSERT_DF3 = 'idf3'; ! 54: const uint32 MSG_EJECT_DF3 = 'edf3'; ! 55: const uint32 MSG_FLOPPY_PANEL_RETURNED = 'flpn'; ! 56: const uint32 MSG_FR1 = 'mfr1'; ! 57: const uint32 MSG_FR2 = 'mfr2'; ! 58: const uint32 MSG_FR3 = 'mfr3'; ! 59: const uint32 MSG_FR4 = 'mfr4'; ! 60: const uint32 MSG_FR5 = 'mfr5'; ! 61: const uint32 MSG_FR6 = 'mfr6'; ! 62: const uint32 MSG_RESET = 'rset'; ! 63: const uint32 MSG_DEBUG = 'dbug'; ! 64: const uint32 MSG_REDRAW = 'draw'; ! 65: const uint32 MSG_QUIT = 'quit'; ! 66: const uint32 MSG_ABOUT = 'abut'; ! 67: ! 68: const rgb_color PowerDark = {0x40, 0x00, 0x00, 0}; // LED colors ! 69: const rgb_color PowerLight = {0xff, 0x00, 0x00, 0}; ! 70: const rgb_color DriveDark = {0x00, 0x40, 0x00, 0}; ! 71: const rgb_color DriveLight = {0x00, 0xff, 0x00, 0}; ! 72: ! 73: ! 74: // Array for converting Be keycodes to Amiga keycodes ! 75: static const int keycode2amiga[128] = { ! 76: -1, AK_ESC, AK_F1, AK_F2, AK_F3, AK_F4, AK_F5, AK_F6, ! 77: AK_F7, AK_F8, AK_F9, AK_F10, -1, AK_mousestuff, -1, -1, ! 78: ! 79: -1, AK_BACKQUOTE, AK_1, AK_2, AK_3, AK_4, AK_5, AK_6, ! 80: AK_7, AK_8, AK_9, AK_0, AK_MINUS, AK_EQUAL, AK_BS, AK_HELP, ! 81: ! 82: AK_NPLPAREN, AK_NPRPAREN, -1, AK_NPDIV, AK_NPMUL, AK_NPSUB, AK_TAB, AK_Q, ! 83: AK_W, AK_E, AK_R, AK_T, AK_Y, AK_U, AK_I, AK_O, ! 84: ! 85: AK_P, AK_LBRACKET, AK_RBRACKET, AK_BACKSLASH, AK_DEL, AK_LALT, AK_RALT, AK_NP7, ! 86: AK_NP8, AK_NP9, AK_NPADD, AK_CAPSLOCK, AK_A, AK_S, AK_D, AK_F, ! 87: ! 88: AK_G, AK_H, AK_J, AK_K, AK_L, AK_SEMICOLON, AK_QUOTE, AK_RET, ! 89: AK_NP4, AK_NP5, AK_NP6, AK_LSH, AK_Z, AK_X, AK_C, AK_V, ! 90: ! 91: AK_B, AK_N, AK_M, AK_COMMA, AK_PERIOD, AK_SLASH, AK_RSH, AK_UP, ! 92: AK_NP1, AK_NP2, AK_NP3, AK_ENT, AK_CTRL, AK_LAMI, AK_SPC, AK_RAMI, ! 93: ! 94: AK_RALT, AK_LF, AK_DN, AK_RT, AK_NP0, AK_NPDEL, AK_LALT, AK_RALT, ! 95: AK_LTGT, -1, -1, -1, -1, -1, -1, -1, ! 96: ! 97: -1, -1, -1, -1, -1, -1, -1, -1, ! 98: -1, -1, -1, -1, -1, -1, -1, -1 ! 99: }; ! 100: ! 101: ! 102: // Global variables ! 103: static bool reset_thyself = false; ! 104: ! 105: static key_info old_key_info; ! 106: static bool window_open; ! 107: static bool LEDs[4]; ! 108: ! 109: static int the_argc; ! 110: static char **the_argv; ! 111: ! 112: static BJoystick *joy; ! 113: ! 114: ! 115: /* ! 116: * A simple view class for blitting a bitmap on the screen ! 117: */ ! 118: ! 119: class BitmapView : public BView { ! 120: public: ! 121: BitmapView(BRect frame, BBitmap *bitmap); ! 122: virtual void Draw(BRect update); ! 123: virtual void MouseMoved(BPoint point, uint32 transit, const BMessage *message); ! 124: void Draw(BRect from, BRect to); ! 125: ! 126: private: ! 127: BBitmap *the_bitmap; ! 128: }; ! 129: ! 130: static BitmapView *bitmap_view; ! 131: ! 132: ! 133: /* ! 134: * The window in which the Amiga graphics are displayed, handles I/O ! 135: */ ! 136: ! 137: class UAEWindow : public BWindow { ! 138: public: ! 139: UAEWindow(BRect frame, BBitmap *bitmap); ! 140: virtual bool QuitRequested(void); ! 141: virtual void MessageReceived(BMessage *msg); ! 142: ! 143: private: ! 144: BMessenger this_messenger; ! 145: BitmapView *main_view; ! 146: BFilePanel *floppy_panel; ! 147: int panel_drive_num; ! 148: }; ! 149: ! 150: static UAEWindow *bitmap_window; ! 151: ! 152: ! 153: /* ! 154: * The BeOS application object ! 155: */ ! 156: ! 157: class UAE : public BApplication { ! 158: public: ! 159: UAE(); ! 160: virtual void ReadyToRun(void); ! 161: virtual bool QuitRequested(void); ! 162: ! 163: int GraphicsInit(void); ! 164: void GraphicsLeave(void); ! 165: ! 166: private: ! 167: static long thread_func(void *obj); ! 168: ! 169: BBitmap *the_bitmap; ! 170: UAEWindow *main_window; ! 171: thread_id the_thread; ! 172: }; ! 173: ! 174: static UAE *the_app; ! 175: ! 176: ! 177: /* ! 178: * LED ! 179: */ ! 180: ! 181: class LEDView : public BView { ! 182: public: ! 183: LEDView(BRect frame, rgb_color active, rgb_color idle); ! 184: virtual void Draw(BRect update); ! 185: void SetState(bool new_state); ! 186: ! 187: private: ! 188: BRect bounds; ! 189: rgb_color active_color; ! 190: rgb_color idle_color; ! 191: bool state; ! 192: }; ! 193: ! 194: static LEDView *PowerLED, *DriveLED[4]; ! 195: ! 196: ! 197: /* ! 198: * Create application object and start it ! 199: */ ! 200: ! 201: int main(int argc, char **argv) ! 202: { ! 203: // Copy command line arguments ! 204: the_argc = argc; ! 205: the_argv = new char *[argc]; ! 206: for (int i=0; i<argc; i++) ! 207: the_argv[i] = strdup(argv[i]); ! 208: ! 209: the_app = new UAE(); ! 210: the_app->Run(); ! 211: delete the_app; ! 212: return 0; ! 213: } ! 214: ! 215: ! 216: /* ! 217: * UAE Constructor: Initialize member variables ! 218: */ ! 219: ! 220: UAE::UAE() : BApplication('UAEm') ! 221: { ! 222: // Find application directory and cwd to it ! 223: app_info the_info; ! 224: GetAppInfo(&the_info); ! 225: BEntry the_file(&the_info.ref); ! 226: BEntry the_dir; ! 227: the_file.GetParent(&the_dir); ! 228: BPath the_path; ! 229: the_dir.GetPath(&the_path); ! 230: chdir(the_path.Path()); ! 231: ! 232: // Initialize other variables ! 233: the_bitmap = NULL; ! 234: main_window = NULL; ! 235: window_open = false; ! 236: } ! 237: ! 238: ! 239: /* ! 240: * Arguments processed, create and start emulation ! 241: */ ! 242: ! 243: void UAE::ReadyToRun(void) ! 244: { ! 245: // Start the emulation thread ! 246: the_thread = spawn_thread(thread_func, "UAE 68000", B_NORMAL_PRIORITY, this); ! 247: resume_thread(the_thread); ! 248: } ! 249: ! 250: ! 251: /* ! 252: * Quit requested (either by menu or by closing the window) ! 253: */ ! 254: ! 255: bool UAE::QuitRequested(void) ! 256: { ! 257: // Quit the thread ! 258: uae_quit(); ! 259: status_t l; ! 260: wait_for_thread(the_thread, &l); ! 261: return true; ! 262: } ! 263: ! 264: ! 265: /* ! 266: * The thread's main function ! 267: */ ! 268: ! 269: long UAE::thread_func(void *obj) ! 270: { ! 271: real_main(the_argc, the_argv); ! 272: return 0; ! 273: } ! 274: ! 275: ! 276: /* ! 277: * UAE Window constructor ! 278: */ ! 279: ! 280: UAEWindow::UAEWindow(BRect frame, BBitmap *bitmap) : BWindow(frame,"UAE", B_TITLED_WINDOW, B_NOT_RESIZABLE|B_NOT_ZOOMABLE), this_messenger(this) ! 281: { ! 282: int i; ! 283: ! 284: // Initialize xcolors ! 285: { ! 286: BScreen scr(this); ! 287: i = 0; ! 288: for (int r=0; r<16; r++) { ! 289: for (int g=0; g<16; g++) { ! 290: for (int b=0; b<16; b++) ! 291: xcolors[i++] = scr.IndexForColor(r<<4 | r, g<<4 | g, b<<4 | b); ! 292: } ! 293: } ! 294: } ! 295: ! 296: // Move window to right position ! 297: Lock(); ! 298: MoveTo(80, 80); ! 299: ! 300: // Set up menus ! 301: BRect bounds = Bounds(); ! 302: bounds.OffsetBy(0, bounds.IntegerHeight() + 1); ! 303: BMenuBar *bar = new BMenuBar(bounds, "menu"); ! 304: BMenu *menu = new BMenu("UAE"); ! 305: menu->AddItem(new BMenuItem("About UAE" B_UTF8_ELLIPSIS, new BMessage(MSG_ABOUT))); ! 306: menu->AddItem(new BSeparatorItem); ! 307: BMenu *submenu = new BMenu("Framerate"); ! 308: submenu->AddItem(new BMenuItem("1/1", new BMessage(MSG_FR1))); ! 309: submenu->AddItem(new BMenuItem("1/2", new BMessage(MSG_FR2))); ! 310: submenu->AddItem(new BMenuItem("1/3", new BMessage(MSG_FR3))); ! 311: submenu->AddItem(new BMenuItem("1/4", new BMessage(MSG_FR4))); ! 312: submenu->AddItem(new BMenuItem("1/5", new BMessage(MSG_FR5))); ! 313: submenu->AddItem(new BMenuItem("1/6", new BMessage(MSG_FR6))); ! 314: submenu->SetRadioMode(true); ! 315: menu->AddItem(submenu); ! 316: menu->AddItem(new BMenuItem("Reset", new BMessage(MSG_RESET))); ! 317: menu->AddItem(new BMenuItem("Debugger", new BMessage(MSG_DEBUG))); ! 318: menu->AddItem(new BSeparatorItem); ! 319: menu->AddItem(new BMenuItem("Quit", new BMessage(MSG_QUIT))); ! 320: bar->AddItem(menu); ! 321: menu = new BMenu("Floppy"); ! 322: submenu = new BMenu("DF0"); ! 323: submenu->AddItem(new BMenuItem("Insert" B_UTF8_ELLIPSIS, new BMessage(MSG_INSERT_DF0))); ! 324: submenu->AddItem(new BMenuItem("Eject", new BMessage(MSG_EJECT_DF0))); ! 325: menu->AddItem(submenu); ! 326: submenu = new BMenu("DF1"); ! 327: submenu->AddItem(new BMenuItem("Insert" B_UTF8_ELLIPSIS, new BMessage(MSG_INSERT_DF1))); ! 328: submenu->AddItem(new BMenuItem("Eject", new BMessage(MSG_EJECT_DF1))); ! 329: menu->AddItem(submenu); ! 330: submenu = new BMenu("DF2"); ! 331: submenu->AddItem(new BMenuItem("Insert" B_UTF8_ELLIPSIS, new BMessage(MSG_INSERT_DF2))); ! 332: submenu->AddItem(new BMenuItem("Eject", new BMessage(MSG_EJECT_DF2))); ! 333: menu->AddItem(submenu); ! 334: submenu = new BMenu("DF3"); ! 335: submenu->AddItem(new BMenuItem("Insert" B_UTF8_ELLIPSIS, new BMessage(MSG_INSERT_DF3))); ! 336: submenu->AddItem(new BMenuItem("Eject", new BMessage(MSG_EJECT_DF3))); ! 337: menu->AddItem(submenu); ! 338: bar->AddItem(menu); ! 339: AddChild(bar); ! 340: bar->ResizeBy(-5*4, 0); // Make room for LEDs ! 341: int mbar_height = bar->Frame().IntegerHeight() + 1; ! 342: ! 343: // Resize window to fit menu bar ! 344: ResizeBy(0, mbar_height); ! 345: ! 346: // Create LEDs ! 347: BRect PowerRect = bar->Frame(); ! 348: PowerRect.left = PowerRect.right+1; ! 349: PowerRect.right = PowerRect.left+3; ! 350: PowerLED = new LEDView(PowerRect, PowerLight, PowerDark); ! 351: AddChild(PowerLED); ! 352: ! 353: BRect DriveRect = PowerRect; ! 354: for (i=0; i<4; i++) { ! 355: DriveRect.left += 4; ! 356: DriveRect.right += 4; ! 357: DriveLED[i] = new LEDView(DriveRect, DriveLight, DriveDark); ! 358: AddChild(DriveLED[i]); ! 359: } ! 360: ! 361: // Create bitmap view ! 362: BRect BitmapRect = frame; ! 363: main_view = new BitmapView(BitmapRect, bitmap); ! 364: AddChild(main_view); ! 365: main_view->MakeFocus(); ! 366: get_key_info(&old_key_info); ! 367: ! 368: bitmap_view = main_view; ! 369: bitmap_window = this; ! 370: ! 371: // Create file panel ! 372: floppy_panel = new BFilePanel(B_OPEN_PANEL, &this_messenger, NULL, 0, false, new BMessage(MSG_FLOPPY_PANEL_RETURNED)); ! 373: panel_drive_num = 0; ! 374: ! 375: // Show window ! 376: Unlock(); ! 377: Show(); ! 378: window_open = true; ! 379: } ! 380: ! 381: ! 382: /* ! 383: * Message received ! 384: */ ! 385: ! 386: void UAEWindow::MessageReceived(BMessage *msg) ! 387: { ! 388: BMessage *msg2; ! 389: ! 390: switch(msg->what) { ! 391: case MSG_INSERT_DF0: ! 392: panel_drive_num = 0; ! 393: floppy_panel->Hide(); ! 394: floppy_panel->Window()->SetTitle("UAE: Insert floppy in DF0:"); ! 395: floppy_panel->Show(); ! 396: break; ! 397: ! 398: case MSG_EJECT_DF0: ! 399: disk_eject(0); ! 400: break; ! 401: ! 402: case MSG_INSERT_DF1: ! 403: panel_drive_num = 1; ! 404: floppy_panel->Hide(); ! 405: floppy_panel->Window()->SetTitle("UAE: Insert floppy in DF1:"); ! 406: floppy_panel->Show(); ! 407: break; ! 408: ! 409: case MSG_EJECT_DF1: ! 410: disk_eject(1); ! 411: break; ! 412: ! 413: case MSG_INSERT_DF2: ! 414: panel_drive_num = 2; ! 415: floppy_panel->Hide(); ! 416: floppy_panel->Window()->SetTitle("UAE: Insert floppy in DF2:"); ! 417: floppy_panel->Show(); ! 418: break; ! 419: ! 420: case MSG_EJECT_DF2: ! 421: disk_eject(2); ! 422: break; ! 423: ! 424: case MSG_INSERT_DF3: ! 425: panel_drive_num = 3; ! 426: floppy_panel->Hide(); ! 427: floppy_panel->Window()->SetTitle("UAE: Insert floppy in DF3:"); ! 428: floppy_panel->Show(); ! 429: break; ! 430: ! 431: case MSG_EJECT_DF3: ! 432: disk_eject(3); ! 433: break; ! 434: ! 435: case MSG_FLOPPY_PANEL_RETURNED: { ! 436: entry_ref the_ref; ! 437: BEntry the_entry; ! 438: if (msg->FindRef("refs", &the_ref) == B_NO_ERROR) ! 439: if (the_entry.SetTo(&the_ref) == B_NO_ERROR) { ! 440: BPath the_path; ! 441: the_entry.GetPath(&the_path); ! 442: disk_eject(panel_drive_num); ! 443: disk_insert(panel_drive_num, the_path.Path()); ! 444: } ! 445: break; ! 446: } ! 447: ! 448: case MSG_FR1: ! 449: currprefs.framerate = 1; ! 450: break; ! 451: case MSG_FR2: ! 452: currprefs.framerate = 2; ! 453: break; ! 454: case MSG_FR3: ! 455: currprefs.framerate = 3; ! 456: break; ! 457: case MSG_FR4: ! 458: currprefs.framerate = 4; ! 459: break; ! 460: case MSG_FR5: ! 461: currprefs.framerate = 5; ! 462: break; ! 463: case MSG_FR6: ! 464: currprefs.framerate = 6; ! 465: break; ! 466: ! 467: case MSG_RESET: ! 468: reset_thyself = true; ! 469: break; ! 470: ! 471: case MSG_DEBUG: ! 472: activate_debugger(); ! 473: break; ! 474: ! 475: case MSG_QUIT: ! 476: be_app->PostMessage(B_QUIT_REQUESTED); ! 477: break; ! 478: ! 479: case MSG_ABOUT: { ! 480: char str[256]; ! 481: sprintf(str, " Un*x Amiga Emulator V%d.%d.%d\n" ! 482: " by Bernd Schmidt\n" ! 483: " BeBox port by Christian Bauer\n" ! 484: "Additional porting by Patrick Hanevold", UAEMAJOR, UAEMINOR, UAEURSAMINOR); ! 485: BAlert *the_alert = new BAlert("", str, "OK"); ! 486: the_alert->Go(); ! 487: break; ! 488: } ! 489: ! 490: case MSG_REDRAW: ! 491: MessageQueue()->Lock(); ! 492: while ((msg2 = MessageQueue()->FindMessage(MSG_REDRAW, 0)) != NULL) { ! 493: MessageQueue()->RemoveMessage(msg2); ! 494: delete msg2; ! 495: } ! 496: MessageQueue()->Unlock(); ! 497: Lock(); ! 498: main_view->Draw(BRect(0, 0, currprefs.gfx_width-1, currprefs.gfx_height-1)); ! 499: Unlock(); ! 500: break; ! 501: ! 502: default: ! 503: BWindow::MessageReceived(msg); ! 504: break; ! 505: } ! 506: } ! 507: ! 508: ! 509: /* ! 510: * Closing the window quits UAE ! 511: */ ! 512: ! 513: bool UAEWindow::QuitRequested(void) ! 514: { ! 515: window_open = false; ! 516: be_app->PostMessage(B_QUIT_REQUESTED); ! 517: return false; ! 518: } ! 519: ! 520: ! 521: /* ! 522: * Bitmap view constructor ! 523: */ ! 524: ! 525: BitmapView::BitmapView(BRect frame, BBitmap *bitmap) : BView(frame, "", B_FOLLOW_NONE, B_WILL_DRAW) ! 526: { ! 527: the_bitmap = bitmap; ! 528: } ! 529: ! 530: ! 531: /* ! 532: * Blit the bitmap ! 533: */ ! 534: ! 535: void BitmapView::Draw(BRect update) ! 536: { ! 537: DrawBitmap(the_bitmap, update, update); ! 538: } ! 539: ! 540: void BitmapView::Draw(BRect from, BRect to) ! 541: { ! 542: DrawBitmap(the_bitmap, from, to); ! 543: } ! 544: ! 545: ! 546: /* ! 547: * Mouse moved ! 548: */ ! 549: ! 550: void BitmapView::MouseMoved(BPoint point, uint32 transit, const BMessage *message) ! 551: { ! 552: newmousecounters = 0; ! 553: switch (transit) { ! 554: case B_ENTERED_VIEW: ! 555: newmousecounters = 1; ! 556: lastmx = point.x; ! 557: lastmy = point.y; ! 558: break; ! 559: case B_EXITED_VIEW: ! 560: break; ! 561: case B_INSIDE_VIEW: ! 562: lastmx = point.x; ! 563: lastmy = point.y; ! 564: break; ! 565: } ! 566: } ! 567: ! 568: ! 569: /* ! 570: * LED ! 571: */ ! 572: ! 573: LEDView::LEDView(BRect frame, rgb_color active, rgb_color idle) : BView(frame, "", B_FOLLOW_NONE, B_WILL_DRAW) ! 574: { ! 575: active_color = active; ! 576: idle_color = idle; ! 577: state = false; ! 578: SetViewColor(idle_color); ! 579: SetHighColor(idle_color); ! 580: bounds = Bounds(); ! 581: } ! 582: ! 583: void LEDView::Draw(BRect update) ! 584: { ! 585: FillRect(bounds); ! 586: } ! 587: ! 588: void LEDView::SetState(bool new_state) ! 589: { ! 590: if (new_state != state) { ! 591: state = new_state; ! 592: Window()->Lock(); ! 593: if (state) { ! 594: SetViewColor(active_color); ! 595: SetHighColor(active_color); ! 596: } else { ! 597: SetViewColor(idle_color); ! 598: SetHighColor(idle_color); ! 599: } ! 600: Draw(bounds); ! 601: Window()->Unlock(); ! 602: } ! 603: } ! 604: ! 605: ! 606: /* ! 607: * Redraw a line ! 608: */ ! 609: ! 610: void flush_line(int y) ! 611: { ! 612: if (window_open) { ! 613: bitmap_window->Lock(); ! 614: bitmap_view->Draw(BRect(0, y, currprefs.gfx_width-1, y)); ! 615: bitmap_window->Unlock(); ! 616: } ! 617: } ! 618: ! 619: ! 620: /* ! 621: * Redraw a block ! 622: */ ! 623: ! 624: void flush_block(int ystart, int ystop) ! 625: { ! 626: } ! 627: ! 628: ! 629: /* ! 630: * Redraw the screen ! 631: */ ! 632: ! 633: void flush_screen(int ystart, int ystop) ! 634: { ! 635: if (window_open) ! 636: bitmap_window->PostMessage(new BMessage(MSG_REDRAW)); ! 637: } ! 638: ! 639: ! 640: /* ! 641: * Init graphics ! 642: */ ! 643: ! 644: int graphics_setup(void) ! 645: { ! 646: return 1; ! 647: } ! 648: ! 649: int graphics_init(void) ! 650: { ! 651: return the_app->GraphicsInit(); ! 652: } ! 653: ! 654: int UAE::GraphicsInit(void) ! 655: { ! 656: if (currprefs.color_mode > 5) ! 657: fprintf(stderr, "Bad color mode selected. Using default.\n"), currprefs.color_mode = 0; ! 658: ! 659: if (currprefs.gfx_width < 320) ! 660: currprefs.gfx_width = 320; ! 661: if (currprefs.gfx_height < 200) ! 662: currprefs.gfx_height = 200; ! 663: if (currprefs.gfx_height > 300 && ! currprefs.gfx_linedbl) ! 664: currprefs.gfx_height = 300; ! 665: if (currprefs.gfx_height > 600) ! 666: currprefs.gfx_height = 600; ! 667: ! 668: gfxvidinfo.width = currprefs.gfx_width; ! 669: gfxvidinfo.height = currprefs.gfx_height; ! 670: gfxvidinfo.can_double = 1; ! 671: ! 672: // Allocate bitmap ! 673: the_bitmap = new BBitmap(BRect(0, 0, currprefs.gfx_width-1, currprefs.gfx_height-1), B_COLOR_8_BIT); ! 674: ! 675: // Set up vidinfo ! 676: gfxvidinfo.pixbytes = 1; ! 677: gfxvidinfo.rowbytes = the_bitmap->BytesPerRow(); ! 678: gfxvidinfo.bufmem = (char *)the_bitmap->Bits(); ! 679: gfxvidinfo.linemem = NULL; ! 680: gfxvidinfo.maxblocklines = 100; /* whatever... */ ! 681: ! 682: // Open window ! 683: main_window = new UAEWindow(BRect(0, 0, currprefs.gfx_width-1, currprefs.gfx_height-1), the_bitmap); ! 684: ! 685: // Initialize mouse and keyboard variables ! 686: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0; ! 687: lastmx = lastmy = 0; ! 688: newmousecounters = 0; ! 689: ! 690: return true; ! 691: } ! 692: ! 693: ! 694: /* ! 695: * Exit graphics ! 696: */ ! 697: ! 698: void graphics_leave(void) ! 699: { ! 700: the_app->GraphicsLeave(); ! 701: } ! 702: ! 703: void UAE::GraphicsLeave(void) ! 704: { ! 705: // Deallocate bitmap ! 706: delete the_bitmap; ! 707: } ! 708: ! 709: ! 710: /* ! 711: * Poll mouse and keyboard ! 712: */ ! 713: ! 714: void handle_events(void) ! 715: { ! 716: key_info the_key_info; ! 717: int be_code, be_byte, be_bit, amiga_code; ! 718: BPoint mouse_point; ! 719: uint32 mouse_buttons; ! 720: ! 721: if (reset_thyself) { ! 722: uae_reset(); ! 723: reset_thyself = false; ! 724: } ! 725: ! 726: // Redraw drive LEDs ! 727: for (int i=0; i<4; i++) ! 728: DriveLED[i]->SetState(LEDs[i]); ! 729: ! 730: if (window_open && bitmap_window->IsActive()) { ! 731: ! 732: get_key_info(&the_key_info); ! 733: bitmap_window->Lock(); ! 734: bitmap_view->GetMouse(&mouse_point, &mouse_buttons, false); ! 735: bitmap_window->Unlock(); ! 736: ! 737: // Keyboard ! 738: if (memcmp(the_key_info.key_states, old_key_info.key_states, sizeof(the_key_info.key_states))) { ! 739: for (be_code=0; be_code<0x80; be_code++) { ! 740: be_byte = be_code >> 3; ! 741: be_bit = 1 << (~be_code & 7); ! 742: ! 743: // Key state changed? ! 744: if ((the_key_info.key_states[be_byte] & be_bit) ! 745: != (old_key_info.key_states[be_byte] & be_bit)) { ! 746: ! 747: amiga_code = keycode2amiga[be_code]; ! 748: if (the_key_info.key_states[be_byte] & be_bit) { ! 749: ! 750: // Key pressed ! 751: if (amiga_code == AK_mousestuff) ! 752: togglemouse(); ! 753: else ! 754: record_key(amiga_code << 1); ! 755: } else { ! 756: ! 757: // Key released ! 758: record_key((amiga_code << 1) | 1); ! 759: } ! 760: } ! 761: } ! 762: old_key_info = the_key_info; ! 763: } ! 764: ! 765: // "Affengriff" ! 766: if ((the_key_info.key_states[0x5c >> 3] & (1 << (~0x5c & 7))) ! 767: && (the_key_info.key_states[0x5d >> 3] & (1 << (~0x5d & 7))) ! 768: && (the_key_info.key_states[0x5f >> 3] & (1 << (~0x5f & 7)))) ! 769: m68k_reset(); ! 770: ! 771: // Scroll lock toggles inhibit_frame ! 772: if (inhibit_frame != 2) ! 773: inhibit_frame = the_key_info.key_states[0x0f >> 3] & (1 << (~0x0f & 7)); ! 774: ! 775: // Mouse buttons ! 776: if (mouse_point.x >= 0 && mouse_point.y >= 0 && mouse_point.x < currprefs.gfx_width && mouse_point.y < currprefs.gfx_height) { ! 777: buttonstate[0] = mouse_buttons & B_PRIMARY_MOUSE_BUTTON; ! 778: buttonstate[1] = mouse_buttons & B_TERTIARY_MOUSE_BUTTON; ! 779: buttonstate[2] = mouse_buttons & B_SECONDARY_MOUSE_BUTTON; ! 780: } ! 781: } ! 782: } ! 783: ! 784: ! 785: /* ! 786: * Joystick routines ! 787: */ ! 788: ! 789: extern "C" { ! 790: void init_joystick(void); ! 791: void close_joystick(void); ! 792: void read_joystick(int nr, unsigned int *dir, int *button); ! 793: }; ! 794: ! 795: int nr_joysticks; ! 796: ! 797: void read_joystick(int nr, unsigned int *dir, int *button) ! 798: { ! 799: static int joy_minx = 32767, joy_maxx = 0, ! 800: joy_miny = 32767, joy_maxy = 0; ! 801: int left = 0, right = 0, top = 0, bot = 0; ! 802: ! 803: *dir = 0; ! 804: *button = 0; ! 805: ! 806: if (nr >= nr_joysticks) ! 807: return; ! 808: ! 809: if (joy->Update() != B_ERROR) { ! 810: if (joy->horizontal > joy_maxx) ! 811: joy_maxx = joy->horizontal; ! 812: if (joy->horizontal < joy_minx) ! 813: joy_minx = joy->horizontal; ! 814: if (joy->vertical > joy_maxy) ! 815: joy_maxy = joy->vertical; ! 816: if (joy->vertical < joy_miny) ! 817: joy_miny = joy->vertical; ! 818: ! 819: if (joy_maxx-joy_minx < 100 || joy_maxy-joy_miny < 100) ! 820: return; ! 821: ! 822: if (joy->horizontal < (joy_minx + (joy_maxx-joy_minx)/3)) ! 823: right = 1; ! 824: else if (joy->horizontal > (joy_minx + 2*(joy_maxx-joy_minx)/3)) ! 825: left = 1; ! 826: ! 827: if (joy->vertical < (joy_miny + (joy_maxy-joy_miny)/3)) ! 828: bot = 1; ! 829: else if (joy->vertical > (joy_miny + 2*(joy_maxy-joy_miny)/3)) ! 830: top = 1; ! 831: ! 832: if (left) top = !top; ! 833: if (right) bot = !bot; ! 834: *dir = bot | (right << 1) | (top << 8) | (left << 9); ! 835: *button = !joy->button1; ! 836: } ! 837: } ! 838: ! 839: void init_joystick(void) ! 840: { ! 841: joy = new BJoystick(); ! 842: joy->Open("joystick1"); ! 843: nr_joysticks = 1; ! 844: } ! 845: ! 846: void close_joystick(void) ! 847: { ! 848: joy->Close(); ! 849: delete joy; ! 850: } ! 851: ! 852: ! 853: /* ! 854: * Sound routines ! 855: */ ! 856: ! 857: extern "C" { ! 858: extern int sound_available; ! 859: extern int smplcnt; ! 860: extern int init_sound(void); ! 861: extern int setup_sound(void); ! 862: extern void flush_sound_buffer(void); ! 863: extern void init_sound_table16(void); ! 864: extern void sample16_handler(void); ! 865: }; ! 866: ! 867: uae_u16 *sndbuffer; ! 868: uae_u16 *sndbufpt; ! 869: int sndbufsize; ! 870: ! 871: static uint8 *buffers[2] = {NULL, NULL}; ! 872: static int buf_num; ! 873: static BDACStream *the_stream; ! 874: static BSubscriber *the_sub; ! 875: static bool sound_ready = false; ! 876: static sem_id sound_sync_sem; ! 877: ! 878: bool stream_func(void *arg, char *buf, size_t count, void *header); ! 879: ! 880: int init_sound(void) ! 881: { ! 882: sound_sync_sem = create_sem(0, "UAE Sound Sync Semaphore"); ! 883: the_stream = new BDACStream(); ! 884: the_sub = new BSubscriber("UAE DAC subscriber"); ! 885: ! 886: if (!currprefs.produce_sound) ! 887: return 0; ! 888: sound_ready = the_sub->Subscribe(the_stream) == B_NO_ERROR; ! 889: if (!sound_ready) ! 890: return 0; ! 891: ! 892: sndbufsize = 44100 / 8 * 4; ! 893: buffers[0] = new uint8[sndbufsize]; ! 894: buffers[1] = new uint8[sndbufsize]; ! 895: memset(buffers[0], 0, sndbufsize); ! 896: memset(buffers[1], 0, sndbufsize); ! 897: buf_num = 0; ! 898: sndbufpt = sndbuffer = (uae_u16 *)buffers[buf_num]; ! 899: ! 900: init_sound_table16(); ! 901: eventtab[ev_sample].handler = sample16_handler; ! 902: sample_evtime = (long)maxhpos * maxvpos * 50 / 44100; ! 903: ! 904: sound_available = 1; ! 905: the_stream->SetSamplingRate(44100); ! 906: the_stream->SetStreamBuffers(sndbufsize, 4); ! 907: the_sub->EnterStream(NULL, true, NULL, stream_func, NULL, true); ! 908: return 1; ! 909: } ! 910: ! 911: int setup_sound(void) ! 912: { ! 913: sound_available = 1; ! 914: return 1; ! 915: } ! 916: ! 917: void close_sound(void) ! 918: { ! 919: if (sound_ready) { ! 920: the_sub->ExitStream(true); ! 921: the_stream->SetStreamBuffers(4096, 8); ! 922: the_sub->Unsubscribe(); ! 923: sound_ready = false; ! 924: } ! 925: delete the_sub; ! 926: delete the_stream; ! 927: ! 928: delete_sem(sound_sync_sem); ! 929: ! 930: delete buffers[0]; ! 931: delete buffers[1]; ! 932: } ! 933: ! 934: void flush_sound_buffer(void) ! 935: { ! 936: if (sound_ready) { ! 937: long l; ! 938: get_sem_count(sound_sync_sem, &l); ! 939: if (l > 0) ! 940: acquire_sem_etc(sound_sync_sem, l+1, 0, 0); ! 941: else ! 942: acquire_sem(sound_sync_sem); ! 943: } ! 944: ! 945: sndbufpt = sndbuffer = (uae_u16 *)buffers[buf_num]; ! 946: buf_num ^= 1; ! 947: } ! 948: ! 949: bool stream_func(void *arg, char *buf, size_t count, void *header) ! 950: { ! 951: memcpy(buf, buffers[buf_num], count); ! 952: release_sem(sound_sync_sem); ! 953: return true; ! 954: } ! 955: ! 956: ! 957: /* ! 958: * Misc routines ! 959: */ ! 960: ! 961: int debuggable(void) ! 962: { ! 963: return true; ! 964: } ! 965: ! 966: int needmousehack(void) ! 967: { ! 968: return true; ! 969: } ! 970: ! 971: void LED(int on) ! 972: { ! 973: PowerLED->SetState(!on); ! 974: } ! 975: ! 976: void setup_brkhandler(void) ! 977: { ! 978: } ! 979: ! 980: void gui_changesettings(void) ! 981: { ! 982: } ! 983: ! 984: void gui_led(int led, int on) ! 985: { ! 986: if (led > 0 && led < 5) ! 987: LEDs[led-1] = on; ! 988: } ! 989: ! 990: int gui_init(void) ! 991: { ! 992: LEDs[0] = LEDs[1] = LEDs[2] = LEDs[3] = false; ! 993: quit_program = 0; ! 994: return 0; ! 995: } ! 996: ! 997: void gui_exit(void) ! 998: { ! 999: } ! 1000: ! 1001: int gui_update(void) ! 1002: { ! 1003: return 0; ! 1004: } ! 1005: ! 1006: void gui_filename(int num, const char *name) ! 1007: { ! 1008: } ! 1009: ! 1010: static void getline(char *p) ! 1011: { ! 1012: } ! 1013: ! 1014: void gui_handle_events(void) ! 1015: { ! 1016: } ! 1017: ! 1018: void write_log (const char *buf) ! 1019: { ! 1020: fprintf (stderr, buf); ! 1021: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.