|
|
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;
1.1.1.3 ! root 902: scaled_sample_evtime = (unsigned long)maxhpos * maxvpos * vblank_hz * CYCLE_UNIT / 44100;
! 903: scaled_sample_evtime_ok = 1;
1.1 root 904:
905: sound_available = 1;
906: the_stream->SetSamplingRate(44100);
907: the_stream->SetStreamBuffers(sndbufsize, 4);
908: the_sub->EnterStream(NULL, true, NULL, stream_func, NULL, true);
909: return 1;
910: }
911:
912: int setup_sound(void)
913: {
914: sound_available = 1;
915: return 1;
916: }
917:
918: void close_sound(void)
919: {
920: if (sound_ready) {
921: the_sub->ExitStream(true);
922: the_stream->SetStreamBuffers(4096, 8);
923: the_sub->Unsubscribe();
924: sound_ready = false;
925: }
926: delete the_sub;
927: delete the_stream;
928:
929: delete_sem(sound_sync_sem);
930:
931: delete buffers[0];
932: delete buffers[1];
933: }
934:
935: void flush_sound_buffer(void)
936: {
937: if (sound_ready) {
938: long l;
939: get_sem_count(sound_sync_sem, &l);
940: if (l > 0)
941: acquire_sem_etc(sound_sync_sem, l+1, 0, 0);
942: else
943: acquire_sem(sound_sync_sem);
944: }
945:
946: sndbufpt = sndbuffer = (uae_u16 *)buffers[buf_num];
947: buf_num ^= 1;
948: }
949:
950: bool stream_func(void *arg, char *buf, size_t count, void *header)
951: {
952: memcpy(buf, buffers[buf_num], count);
953: release_sem(sound_sync_sem);
954: return true;
955: }
956:
957:
958: /*
959: * Misc routines
960: */
961:
962: int debuggable(void)
963: {
964: return true;
965: }
966:
967: int needmousehack(void)
968: {
969: return true;
970: }
971:
972: void LED(int on)
973: {
974: PowerLED->SetState(!on);
975: }
976:
977: void setup_brkhandler(void)
978: {
979: }
980:
981: void gui_changesettings(void)
982: {
983: }
984:
985: void gui_led(int led, int on)
986: {
987: if (led > 0 && led < 5)
988: LEDs[led-1] = on;
989: }
990:
991: int gui_init(void)
992: {
993: LEDs[0] = LEDs[1] = LEDs[2] = LEDs[3] = false;
994: quit_program = 0;
995: return 0;
996: }
997:
998: void gui_exit(void)
999: {
1000: }
1001:
1002: int gui_update(void)
1003: {
1004: return 0;
1005: }
1006:
1007: void gui_filename(int num, const char *name)
1008: {
1009: }
1010:
1011: static void getline(char *p)
1012: {
1013: }
1014:
1015: void gui_handle_events(void)
1016: {
1017: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.