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