ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/Prefs_Be.h
Revision: 1.3
Committed: 2003-07-09T13:51:13Z (20 years, 9 months ago) by cebix
Content type: text/plain
Branch: MAIN
Changes since 1.2: +56 -34 lines
Log Message:
- BeOS: added support for digital joysticks connected to the GeekPort
- open_close_joysticks() takes ints instead of bools

File Contents

# Content
1 /*
2 * Prefs_Be.h - Global preferences, Be specific stuff
3 *
4 * Frodo (C) 1994-1997,2002-2003 Christian Bauer
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <InterfaceKit.h>
22 #include <StorageKit.h>
23 #include <Path.h>
24
25
26 // Special colors
27 const rgb_color light_color = {255, 255, 255, 0};
28 const rgb_color fill_color = {216, 216, 216, 0};
29 const rgb_color dark_color = {184, 184, 184, 0};
30
31
32 // Window thread messages
33 const uint32 MSG_OK = 'okok';
34 const uint32 MSG_CANCEL = 'cncl';
35 const uint32 MSG_SPRITES_ON = 'spon';
36 const uint32 MSG_SPRITE_COLLISIONS = 'scol';
37 const uint32 MSG_JOYSTICK_1_PORT = 'joy1';
38 const uint32 MSG_JOYSTICK_2_PORT = 'joy2';
39 const uint32 MSG_JOYSTICK_SWAP = 'jswp';
40 const uint32 MSG_LIMIT_SPEED = 'lmit';
41 const uint32 MSG_FAST_RESET = 'frst';
42 const uint32 MSG_CIA_IRQ_HACK = 'cirq';
43 const uint32 MSG_SID_FILTERS = 'filt';
44 const uint32 MSG_DOUBLE_SCAN = 'dbls';
45 const uint32 MSG_MAP_SLASH = 'mpsl';
46 const uint32 MSG_EMUL_1541_PROC = '15pr';
47 const uint32 MSG_DRVTYPE_8 = 'drt8';
48 const uint32 MSG_DRVTYPE_9 = 'drt9';
49 const uint32 MSG_DRVTYPE_10 = 'drt:';
50 const uint32 MSG_DRVTYPE_11 = 'drt;';
51 const uint32 MSG_GETDRIVE_8 = 'gtd8';
52 const uint32 MSG_GETDRIVE_9 = 'gtd9';
53 const uint32 MSG_GETDRIVE_10 = 'gtd:';
54 const uint32 MSG_GETDRIVE_11 = 'gtd;';
55 const uint32 MSG_DRIVE_PANEL_RETURNED = 'gdr8';
56 const uint32 MSG_SID_TYPE = 'sidt';
57 const uint32 MSG_REU_SIZE = 'reus';
58 const uint32 MSG_DISPLAY_TYPE = 'dspt';
59
60 const uint32 MSG_OPEN = 'open';
61 const uint32 MSG_SAVE = 'save';
62 const uint32 MSG_SAVE_AS = 'svas';
63 const uint32 MSG_REVERT = 'rvrt';
64 const uint32 MSG_OPEN_PANEL_RETURNED = 'oprt';
65 const uint32 MSG_SAVE_PANEL_RETURNED = 'svrt';
66
67
68 /*
69 * Preferences window class
70 */
71
72 class NumberControl;
73 class PathControl;
74
75 class PrefsWindow : public BWindow {
76 public:
77 PrefsWindow(Prefs *p, bool start, char *path);
78 virtual void MessageReceived(BMessage *msg);
79 virtual bool QuitRequested(void);
80 virtual bool FilterKeyDown(uint32 *aChar, BView **target);
81
82 private:
83 BCheckBox *make_checkbox(BRect frame, char *label, uint32 what, BView *parent);
84 NumberControl *make_number_entry(BRect frame, char *label_text, BView *parent);
85 BPopUpMenu *make_drvtype_popup(BRect frame, uint32 what, BView *parent);
86 PathControl *make_path_entry(BRect frame, char *label, BView *parent);
87 BPopUpMenu *make_sidtype_popup(BRect frame, char *label_text, uint32 what, BView *parent);
88 BPopUpMenu *make_reusize_popup(BRect frame, char *label_text, uint32 what, BView *parent);
89 BPopUpMenu *make_disptype_popup(BRect frame, char *label_text, uint32 what, BView *parent);
90 BPopUpMenu *make_joystick_popup(BRect frame, char *label_text, uint32 what, BView *parent);
91 void set_values(void);
92 void get_values(void);
93 void ghost_controls(void);
94
95 Prefs *prefs;
96
97 BMessenger this_messenger;
98 BFilePanel *open_panel; // For opening prefs
99 BFilePanel *save_panel; // For saving prefs
100 BFilePanel *file_panel; // For D64/T64 drives
101 BFilePanel *dir_panel; // For directory drives
102 int panel_drive_num; // Drive number (0..3) of the file panel
103
104 BButton *g_ok;
105 BButton *g_cancel;
106 NumberControl *g_normal_cycles;
107 NumberControl *g_bad_line_cycles;
108 NumberControl *g_cia_cycles;
109 NumberControl *g_floppy_cycles;
110 NumberControl *g_skip_frames;
111 PathControl *g_drive_path[4];
112 BPopUpMenu *g_drive_type[4];
113 BPopUpMenu *g_sid_type;
114 BPopUpMenu *g_reu_size;
115 BPopUpMenu *g_display_type;
116 BPopUpMenu *g_joystick_1_port;
117 BPopUpMenu *g_joystick_2_port;
118 BCheckBox *g_sprites_on;
119 BCheckBox *g_sprite_collisions;
120 BCheckBox *g_joystick_swap;
121 BCheckBox *g_limit_speed;
122 BCheckBox *g_fast_reset;
123 BCheckBox *g_cia_irq_hack;
124 BCheckBox *g_sid_filters;
125 BCheckBox *g_double_scan;
126 BCheckBox *g_map_slash;
127 BCheckBox *g_emul_1541_proc;
128
129 char *prefs_path;
130 bool startup;
131 };
132
133
134 /*
135 * Start preferences editor (asynchronously)
136 * startup = false: Send MSG_PREFS_DONE to application on close
137 * startup = true : Send MSG_STARTUP to application on close if not canceled,
138 * B_QUIT_REQUESTED otherwise
139 * prefs_name points to the file name of the preferences (which may be changed)
140 */
141
142 bool Prefs::ShowEditor(bool startup, char *prefs_name)
143 {
144 PrefsWindow *win = new PrefsWindow(this, startup, prefs_name);
145 win->Show();
146 return true;
147 }
148
149
150 /*
151 * Number-only BTextControl
152 */
153
154 // Class definition
155 class NumberControl : public BTextControl {
156 public:
157 NumberControl(BRect frame, float divider, const char *name, const char *label, const char *text, BMessage *message);
158 void SetValue(long value);
159 long Value(void);
160 };
161
162 // Constructor: Allow only digits
163 NumberControl::NumberControl(BRect frame, float divider, const char *name, const char *label, const char *text, BMessage *message)
164 : BTextControl(frame, name, label, text, message, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE)
165 {
166 SetDivider(divider);
167 for (int c=0; c<256; c++)
168 if (!isdigit(c) && c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW)
169 ((BTextView *)ChildAt(0))->DisallowChar(c);
170 }
171
172 // Set integer value
173 void NumberControl::SetValue(long value)
174 {
175 char str[32];
176 sprintf(str, "%ld", value);
177 SetText(str);
178 }
179
180 // Get integer value
181 long NumberControl::Value(void)
182 {
183 return atol(Text());
184 }
185
186
187 /*
188 * Path-entry BTextControl
189 */
190
191 // Class definition
192 class PathControl : public BTextControl {
193 public:
194 PathControl(BRect frame, float divider, const char *name, const char *label, const char *text, BMessage *message);
195 virtual void MessageReceived(BMessage *msg);
196 };
197
198 // Constructor: Disable some keys
199 PathControl::PathControl(BRect frame, float divider, const char *name, const char *label, const char *text, BMessage *message)
200 : BTextControl(frame, name, label, text, message, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE)
201 {
202 SetDivider(divider);
203 for (int c=0; c<' '; c++)
204 if (c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW)
205 ((BTextView *)ChildAt(0))->DisallowChar(c);
206 }
207
208 // Message received: Look out for dropped refs
209 void PathControl::MessageReceived(BMessage *msg)
210 {
211 if (msg->what == B_SIMPLE_DATA) {
212 entry_ref the_ref;
213 BEntry the_entry;
214
215 // First look for refs
216 if (msg->FindRef("refs", &the_ref) == B_NO_ERROR) {
217 if (the_entry.SetTo(&the_ref) == B_NO_ERROR) {
218 BPath the_path;
219 the_entry.GetPath(&the_path);
220 SetText(the_path.Path());
221 }
222 } else
223 BTextControl::MessageReceived(msg);
224
225 MakeFocus();
226 } else
227 BTextControl::MessageReceived(msg);
228 }
229
230
231 /*
232 * Open preferences window
233 */
234
235 PrefsWindow::PrefsWindow(Prefs *p, bool start, char *path) : BWindow(BRect(0, 0, 400, 349), "Frodo Preferences", B_TITLED_WINDOW, B_NOT_CLOSABLE | B_NOT_RESIZABLE | B_NOT_ZOOMABLE), this_messenger(this)
236 {
237 int i;
238 prefs = p;
239 startup = start;
240 prefs_path = path;
241
242 // Move window to right position
243 Lock();
244 MoveTo(80, 80);
245
246 // Set up menus
247 BMenuBar *bar = new BMenuBar(Bounds(), "");
248 BMenu *menu = new BMenu("Preferences");
249 BMenuItem *item;
250 menu->AddItem(item = new BMenuItem("About Frodo" B_UTF8_ELLIPSIS, new BMessage(B_ABOUT_REQUESTED)));
251 item->SetTarget(be_app);
252 menu->AddItem(new BSeparatorItem);
253 menu->AddItem(new BMenuItem("Open" B_UTF8_ELLIPSIS, new BMessage(MSG_OPEN), 'O'));
254 menu->AddItem(new BMenuItem("Save", new BMessage(MSG_SAVE), 'S'));
255 menu->AddItem(new BMenuItem("Save As" B_UTF8_ELLIPSIS, new BMessage(MSG_SAVE_AS), 'A'));
256 menu->AddItem(new BMenuItem("Revert", new BMessage(MSG_REVERT)));
257 menu->AddItem(new BSeparatorItem);
258 menu->AddItem(item = new BMenuItem("Quit Frodo", new BMessage(B_QUIT_REQUESTED), 'Q'));
259 item->SetTarget(be_app);
260 bar->AddItem(menu);
261 AddChild(bar);
262 SetKeyMenuBar(bar);
263 int mbar_height = int(bar->Frame().bottom) + 1;
264
265 // Resize window to fit menu bar
266 ResizeBy(0, mbar_height);
267
268 // Light gray background
269 BRect b = Bounds();
270 BView *top = new BView(BRect(0, mbar_height, b.right, b.bottom), "top", B_FOLLOW_NONE, B_WILL_DRAW);
271 AddChild(top);
272 top->SetViewColor(fill_color);
273
274 // Checkboxes
275 g_sprites_on = make_checkbox(BRect(10, 10, 180, 21), "Sprite display", MSG_SPRITES_ON, top);
276 g_sprite_collisions = make_checkbox(BRect(10, 25, 180, 36), "Sprite collisions", MSG_SPRITE_COLLISIONS, top);
277 g_limit_speed = make_checkbox(BRect(10, 40, 180, 51), "Limit speed", MSG_LIMIT_SPEED, top);
278 g_fast_reset = make_checkbox(BRect(10, 55, 180, 66), "Fast reset", MSG_FAST_RESET, top);
279 g_cia_irq_hack = make_checkbox(BRect(10, 70, 180, 81), "Clear CIA ICR on write", MSG_CIA_IRQ_HACK, top);
280 g_sid_filters = make_checkbox(BRect(10, 85, 180, 96), "SID filters", MSG_SID_FILTERS, top);
281 g_double_scan = make_checkbox(BRect(10, 100, 180, 111), "Doublescan lines", MSG_DOUBLE_SCAN, top);
282 g_joystick_swap = make_checkbox(BRect(10, 115, 180, 126), "Swap joysticks", MSG_JOYSTICK_SWAP, top);
283 g_joystick_1_port = make_joystick_popup(BRect(10, 130, 180, 145), "Joystick 1", MSG_JOYSTICK_1_PORT, top);
284 g_joystick_2_port = make_joystick_popup(BRect(10, 150, 180, 165), "Joystick 2", MSG_JOYSTICK_2_PORT, top);
285
286 // Number entry fields
287 g_normal_cycles = make_number_entry(BRect(180, 10, 390, 26), "Cycles per line (CPU)", top);
288 g_bad_line_cycles = make_number_entry(BRect(180, 30, 390, 46), "Cycles per Bad Line (CPU)", top);
289 g_cia_cycles = make_number_entry(BRect(180, 50, 390, 66), "Cycles per line (CIA)", top);
290 g_floppy_cycles = make_number_entry(BRect(180, 70, 390, 86), "Cycles per line (1541)", top);
291 g_skip_frames = make_number_entry(BRect(180, 90, 390, 106), "Draw every n-th frame", top);
292
293 // Popup fields
294 g_display_type = make_disptype_popup(BRect(180, 110, 390, 126), "Display type", MSG_DISPLAY_TYPE, top);
295 g_sid_type = make_sidtype_popup(BRect(180, 130, 390, 146), "SID emulation type", MSG_SID_TYPE, top);
296 g_reu_size = make_reusize_popup(BRect(180, 150, 390, 166), "REU size", MSG_REU_SIZE, top);
297
298 // Prepare on/off pictures for file panel buttons
299 BView *view = new BView(BRect(0, 0, 19, 15), "", B_FOLLOW_NONE, 0);
300 AddChild(view);
301 view->SetViewColor(fill_color);
302
303 view->BeginPicture(new BPicture);
304 view->SetHighColor(fill_color);
305 view->FillRect(BRect(0, 0, 19, 15));
306 view->SetHighColor(light_color);
307 view->StrokeRect(BRect(0, 0, 18, 0));
308 view->StrokeRect(BRect(0, 0, 0, 14));
309 view->SetHighColor(dark_color);
310 view->StrokeRect(BRect(0, 15, 19, 15));
311 view->StrokeRect(BRect(19, 0, 19, 15));
312 view->SetFont(be_plain_font);
313 view->SetHighColor(0, 0, 0);
314 view->SetLowColor(fill_color);
315 view->MovePenTo(7, 11);
316 view->DrawString("B");
317 BPicture *on = view->EndPicture();
318
319 view->BeginPicture(new BPicture);
320 view->SetHighColor(dark_color);
321 view->FillRect(BRect(0, 0, 19, 15));
322 view->SetHighColor(128, 128, 128);
323 view->StrokeRect(BRect(0, 0, 18, 0));
324 view->StrokeRect(BRect(0, 0, 0, 14));
325 view->SetHighColor(light_color);
326 view->StrokeRect(BRect(0, 15, 19, 15));
327 view->StrokeRect(BRect(19, 0, 19, 15));
328 view->SetFont(be_plain_font);
329 view->SetHighColor(0, 0, 0);
330 view->SetLowColor(dark_color);
331 view->MovePenTo(7, 11);
332 view->DrawString("B");
333 BPicture *off = view->EndPicture();
334
335 RemoveChild(view);
336 delete view;
337
338 // Drive settings
339 BBox *drvbox = new BBox(BRect(10, 173, 390, 304));
340 top->AddChild(drvbox);
341 drvbox->SetViewColor(fill_color);
342 drvbox->SetLowColor(fill_color);
343 drvbox->SetLabel("Drives");
344
345 for (i=0; i<4; i++) {
346 char str[4];
347 sprintf(str, "%d", i+8);
348 g_drive_path[i] = make_path_entry(BRect(10, 14+i*20, 299, 30+i*20), str, drvbox);
349 drvbox->AddChild(new BPictureButton(BRect(304, 16+i*20, 323, 31+i*20), "", new BPicture(*on), new BPicture(*off), new BMessage(MSG_GETDRIVE_8 + i)));
350 g_drive_type[i] = make_drvtype_popup(BRect(329, 14+i*20, 373, 30+i*20), MSG_DRVTYPE_8 + i, drvbox);
351 }
352
353 g_map_slash = make_checkbox(BRect(10, 94, 300, 110), "Map '/'<->'\\' in filenames", MSG_MAP_SLASH, drvbox);
354 g_emul_1541_proc = make_checkbox(BRect(10, 109, 300, 125), "Enable 1541 processor emulation", MSG_EMUL_1541_PROC, drvbox);
355
356 // "OK" button
357 top->AddChild(g_ok = new BButton(BRect(20, 315, 90, 340), "", startup ? "Start" : "OK", new BMessage(MSG_OK)));
358 SetDefaultButton(g_ok);
359
360 // "Cancel" button
361 top->AddChild(g_cancel = new BButton(BRect(b.right-90, 315, b.right-20, 340), "", startup ? "Quit" : "Cancel", new BMessage(MSG_CANCEL)));
362
363 // Set the values of all controls to reflect the preferences
364 set_values();
365 g_normal_cycles->MakeFocus();
366
367 // Create file panels
368 open_panel = new BFilePanel(B_OPEN_PANEL, &this_messenger, NULL, 0, false, new BMessage(MSG_OPEN_PANEL_RETURNED));
369 open_panel->Window()->SetTitle("Frodo: Open preferences");
370 save_panel = new BFilePanel(B_SAVE_PANEL, &this_messenger, NULL, 0, false, new BMessage(MSG_SAVE_PANEL_RETURNED));
371 save_panel->Window()->SetTitle("Frodo: Save preferences");
372 file_panel = new BFilePanel(B_OPEN_PANEL, &this_messenger, NULL, 0, false, new BMessage(MSG_DRIVE_PANEL_RETURNED));
373 file_panel->SetPanelDirectory(&AppDirectory);
374 dir_panel = new BFilePanel(B_OPEN_PANEL, &this_messenger, NULL, B_DIRECTORY_NODE, false, new BMessage(MSG_DRIVE_PANEL_RETURNED));
375 dir_panel->SetPanelDirectory(&AppDirectory);
376 dir_panel->Window()->SetTitle("Frodo: Select directory");
377 dir_panel->SetButtonLabel(B_DEFAULT_BUTTON, "Select");
378
379 Unlock();
380 }
381
382
383 /*
384 * Create checkbox
385 */
386
387 BCheckBox *PrefsWindow::make_checkbox(BRect frame, char *label, uint32 what, BView *parent)
388 {
389 BCheckBox *checkbox = new BCheckBox(frame, "", label, new BMessage(what));
390 parent->AddChild(checkbox);
391 return checkbox;
392 }
393
394
395 /*
396 * Create number entry field
397 */
398
399 NumberControl *PrefsWindow::make_number_entry(BRect frame, char *label_text, BView *parent)
400 {
401 NumberControl *num = new NumberControl(frame, frame.right-frame.left-55, "", label_text, NULL, NULL);
402 parent->AddChild(num);
403
404 num->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_RIGHT);
405 num->SetFont(be_plain_font);
406 num->ChildAt(0)->SetFont(be_plain_font);
407
408 return num;
409 }
410
411
412 /*
413 * Create drive type popup menu
414 */
415
416 BPopUpMenu *PrefsWindow::make_drvtype_popup(BRect frame, uint32 what, BView *parent)
417 {
418 BPopUpMenu *popup = new BPopUpMenu("drive_type popup", true, true);
419 popup->AddItem(new BMenuItem("Dir", new BMessage(what)));
420 popup->AddItem(new BMenuItem("D64", new BMessage(what)));
421 popup->AddItem(new BMenuItem("T64", new BMessage(what)));
422 popup->SetTargetForItems(this);
423 BMenuField *menu_field = new BMenuField(frame, "drive_type", NULL, popup);
424 menu_field->SetDivider(0);
425 parent->AddChild(menu_field);
426 return popup;
427 }
428
429
430 /*
431 * Create path entry field
432 */
433
434 PathControl *PrefsWindow::make_path_entry(BRect frame, char *label, BView *parent)
435 {
436 PathControl *path = new PathControl(frame, 16, "", label, NULL, NULL);
437 parent->AddChild(path);
438
439 path->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
440 path->SetFont(be_plain_font);
441 path->ChildAt(0)->SetFont(be_plain_font);
442 ((BTextView *)(path->ChildAt(0)))->SetMaxBytes(255);
443
444 return path;
445 }
446
447
448 /*
449 * Create display type popup
450 */
451
452 BPopUpMenu *PrefsWindow::make_disptype_popup(BRect frame, char *label_text, uint32 what, BView *parent)
453 {
454 BPopUpMenu *popup = new BPopUpMenu("display_type popup", true, true);
455 popup->AddItem(new BMenuItem("Window", new BMessage(what)));
456 popup->AddItem(new BMenuItem("Screen", new BMessage(what)));
457 popup->SetTargetForItems(this);
458 BMenuField *menu_field = new BMenuField(frame, "display_type", label_text, popup);
459 menu_field->SetDivider(frame.Width()-75);
460 menu_field->SetAlignment(B_ALIGN_RIGHT);
461 parent->AddChild(menu_field);
462 return popup;
463 }
464
465
466 /*
467 * Create SID type popup
468 */
469
470 BPopUpMenu *PrefsWindow::make_sidtype_popup(BRect frame, char *label_text, uint32 what, BView *parent)
471 {
472 BPopUpMenu *popup = new BPopUpMenu("sid_type popup", true, true);
473 popup->AddItem(new BMenuItem("None", new BMessage(what)));
474 popup->AddItem(new BMenuItem("Digital", new BMessage(what)));
475 popup->SetTargetForItems(this);
476 BMenuField *menu_field = new BMenuField(frame, "sid_type", label_text, popup);
477 menu_field->SetDivider(frame.Width()-75);
478 menu_field->SetAlignment(B_ALIGN_RIGHT);
479 parent->AddChild(menu_field);
480 return popup;
481 }
482
483
484 /*
485 * Create REU size popup
486 */
487
488 BPopUpMenu *PrefsWindow::make_reusize_popup(BRect frame, char *label_text, uint32 what, BView *parent)
489 {
490 BPopUpMenu *popup = new BPopUpMenu("reu_size popup", true, true);
491 popup->AddItem(new BMenuItem("None", new BMessage(what)));
492 popup->AddItem(new BMenuItem("128K", new BMessage(what)));
493 popup->AddItem(new BMenuItem("256K", new BMessage(what)));
494 popup->AddItem(new BMenuItem("512K", new BMessage(what)));
495 popup->SetTargetForItems(this);
496 BMenuField *menu_field = new BMenuField(frame, "reu_size", label_text, popup);
497 menu_field->SetDivider(frame.Width()-75);
498 menu_field->SetAlignment(B_ALIGN_RIGHT);
499 parent->AddChild(menu_field);
500 return popup;
501 }
502
503
504 /*
505 * Create joystick port popup
506 */
507
508 BPopUpMenu *PrefsWindow::make_joystick_popup(BRect frame, char *label_text, uint32 what, BView *parent)
509 {
510 BPopUpMenu *popup = new BPopUpMenu("joystick popup", true, true);
511 popup->AddItem(new BMenuItem("None", new BMessage(what)));
512 popup->AddItem(new BMenuItem("Joystick Port 1", new BMessage(what)));
513 popup->AddItem(new BMenuItem("Joystick Port 2", new BMessage(what)));
514 popup->AddItem(new BMenuItem("GeekPort A", new BMessage(what)));
515 popup->AddItem(new BMenuItem("GeekPort B", new BMessage(what)));
516 popup->SetTargetForItems(this);
517 BMenuField *menu_field = new BMenuField(frame, "joystick", label_text, popup);
518 menu_field->SetDivider(60);
519 menu_field->SetAlignment(B_ALIGN_RIGHT);
520 parent->AddChild(menu_field);
521 return popup;
522 }
523
524
525 /*
526 * Set the values of the controls
527 */
528
529 void PrefsWindow::set_values(void)
530 {
531 prefs->Check();
532
533 g_normal_cycles->SetValue(prefs->NormalCycles);
534 g_bad_line_cycles->SetValue(prefs->BadLineCycles);
535 g_cia_cycles->SetValue(prefs->CIACycles);
536 g_floppy_cycles->SetValue(prefs->FloppyCycles);
537 g_skip_frames->SetValue(prefs->SkipFrames);
538
539 for (int i=0; i<4; i++) {
540 g_drive_type[i]->ItemAt(prefs->DriveType[i])->SetMarked(true);
541 g_drive_path[i]->SetText(prefs->DrivePath[i]);
542 }
543
544 g_sid_type->ItemAt(prefs->SIDType)->SetMarked(true);
545 g_reu_size->ItemAt(prefs->REUSize)->SetMarked(true);
546 g_display_type->ItemAt(prefs->DisplayType)->SetMarked(true);
547
548 g_sprites_on->SetValue(prefs->SpritesOn ? B_CONTROL_ON : B_CONTROL_OFF);
549 g_sprite_collisions->SetValue(prefs->SpriteCollisions ? B_CONTROL_ON : B_CONTROL_OFF);
550 g_joystick_1_port->ItemAt(prefs->Joystick1Port)->SetMarked(true);
551 g_joystick_2_port->ItemAt(prefs->Joystick2Port)->SetMarked(true);
552 g_joystick_swap->SetValue(prefs->JoystickSwap ? B_CONTROL_ON : B_CONTROL_OFF);
553 g_limit_speed->SetValue(prefs->LimitSpeed ? B_CONTROL_ON : B_CONTROL_OFF);
554 g_fast_reset->SetValue(prefs->FastReset ? B_CONTROL_ON : B_CONTROL_OFF);
555 g_cia_irq_hack->SetValue(prefs->CIAIRQHack ? B_CONTROL_ON : B_CONTROL_OFF);
556 g_sid_filters->SetValue(prefs->SIDFilters ? B_CONTROL_ON : B_CONTROL_OFF);
557 g_double_scan->SetValue(prefs->DoubleScan ? B_CONTROL_ON : B_CONTROL_OFF);
558
559 g_map_slash->SetValue(prefs->MapSlash ? B_CONTROL_ON : B_CONTROL_OFF);
560 g_emul_1541_proc->SetValue(prefs->Emul1541Proc ? B_CONTROL_ON : B_CONTROL_OFF);
561
562 ghost_controls();
563 }
564
565
566 /*
567 * Get the values of the controls
568 */
569
570 void PrefsWindow::get_values(void)
571 {
572 prefs->NormalCycles = g_normal_cycles->Value();
573 prefs->BadLineCycles = g_bad_line_cycles->Value();
574 prefs->CIACycles = g_cia_cycles->Value();
575 prefs->FloppyCycles = g_floppy_cycles->Value();
576 prefs->SkipFrames = g_skip_frames->Value();
577
578 for (int i=0; i<4; i++)
579 strcpy(prefs->DrivePath[i], g_drive_path[i]->Text());
580
581 prefs->Check();
582 }
583
584
585 /*
586 * Enable/disable certain controls
587 */
588
589 void PrefsWindow::ghost_controls(void)
590 {
591 g_normal_cycles->SetEnabled(!IsFrodoSC);
592 g_bad_line_cycles->SetEnabled(!IsFrodoSC);
593 g_cia_cycles->SetEnabled(!IsFrodoSC);
594 g_floppy_cycles->SetEnabled(!IsFrodoSC);
595 g_cia_irq_hack->SetEnabled(!IsFrodoSC);
596 g_double_scan->SetEnabled(prefs->DisplayType == DISPTYPE_SCREEN);
597 }
598
599
600 /*
601 * Message from controls/menus received
602 */
603
604 void PrefsWindow::MessageReceived(BMessage *msg)
605 {
606 switch (msg->what) {
607 case MSG_OK:
608 get_values();
609 if (startup)
610 be_app->PostMessage(MSG_STARTUP);
611 else {
612 BMessage msg(MSG_PREFS_DONE);
613 msg.AddBool("canceled", false);
614 msg.AddPointer("prefs", prefs);
615 be_app->PostMessage(&msg);
616 }
617 PostMessage(B_QUIT_REQUESTED);
618 break;
619
620 case MSG_CANCEL:
621 if (startup)
622 be_app->PostMessage(B_QUIT_REQUESTED);
623 else {
624 BMessage msg(MSG_PREFS_DONE);
625 msg.AddBool("canceled", true);
626 msg.AddPointer("prefs", prefs);
627 be_app->PostMessage(&msg);
628 }
629 PostMessage(B_QUIT_REQUESTED);
630 break;
631
632 case MSG_SPRITES_ON:
633 prefs->SpritesOn = !prefs->SpritesOn;
634 break;
635
636 case MSG_SPRITE_COLLISIONS:
637 prefs->SpriteCollisions = !prefs->SpriteCollisions;
638 break;
639
640 case MSG_JOYSTICK_1_PORT:
641 prefs->Joystick1Port = msg->FindInt32("index");
642 break;
643
644 case MSG_JOYSTICK_2_PORT:
645 prefs->Joystick2Port = msg->FindInt32("index");
646 break;
647
648 case MSG_JOYSTICK_SWAP:
649 prefs->JoystickSwap = !prefs->JoystickSwap;
650 break;
651
652 case MSG_LIMIT_SPEED:
653 prefs->LimitSpeed = !prefs->LimitSpeed;
654 break;
655
656 case MSG_FAST_RESET:
657 prefs->FastReset = !prefs->FastReset;
658 break;
659
660 case MSG_CIA_IRQ_HACK:
661 prefs->CIAIRQHack = !prefs->CIAIRQHack;
662 break;
663
664 case MSG_SID_FILTERS:
665 prefs->SIDFilters = !prefs->SIDFilters;
666 break;
667
668 case MSG_DOUBLE_SCAN:
669 prefs->DoubleScan = !prefs->DoubleScan;
670 break;
671
672 case MSG_SID_TYPE:
673 prefs->SIDType = msg->FindInt32("index");
674 break;
675
676 case MSG_REU_SIZE:
677 prefs->REUSize = msg->FindInt32("index");
678 break;
679
680 case MSG_DISPLAY_TYPE:
681 prefs->DisplayType = msg->FindInt32("index");
682 g_double_scan->SetEnabled(prefs->DisplayType == DISPTYPE_SCREEN);
683 break;
684
685 case MSG_MAP_SLASH:
686 prefs->MapSlash = !prefs->MapSlash;
687 break;
688
689 case MSG_EMUL_1541_PROC:
690 prefs->Emul1541Proc = !prefs->Emul1541Proc;
691 break;
692
693 case MSG_DRVTYPE_8:
694 case MSG_DRVTYPE_9:
695 case MSG_DRVTYPE_10:
696 case MSG_DRVTYPE_11:
697 prefs->DriveType[msg->what & 3] = msg->FindInt32("index");
698 break;
699
700 case MSG_GETDRIVE_8:
701 case MSG_GETDRIVE_9:
702 case MSG_GETDRIVE_10:
703 case MSG_GETDRIVE_11:
704 panel_drive_num = msg->what & 3;
705 file_panel->Hide();
706 dir_panel->Hide();
707 if (prefs->DriveType[panel_drive_num] == DRVTYPE_D64) {
708 file_panel->Window()->SetTitle("Frodo: Select disk image file");
709 file_panel->Show();
710 } else if (prefs->DriveType[panel_drive_num] == DRVTYPE_T64) {
711 file_panel->Window()->SetTitle("Frodo: Select archive file");
712 file_panel->Show();
713 } else
714 dir_panel->Show();
715 break;
716
717 case MSG_DRIVE_PANEL_RETURNED: { // Drive path file panel returned
718 entry_ref the_ref;
719 BEntry the_entry;
720 if (msg->FindRef("refs", &the_ref) == B_NO_ERROR)
721 if (the_entry.SetTo(&the_ref) == B_NO_ERROR) {
722 BPath the_path;
723 the_entry.GetPath(&the_path);
724 strncpy(prefs->DrivePath[panel_drive_num], the_path.Path(), 255);
725 prefs->DrivePath[panel_drive_num][255] = 0;
726 set_values();
727 }
728 break;
729 }
730
731 case MSG_OPEN:
732 open_panel->Show();
733 break;
734
735 case MSG_OPEN_PANEL_RETURNED: { // Open file panel returned
736 get_values(); // Useful if Load() is unsuccessful
737
738 entry_ref the_ref;
739 BEntry the_entry;
740 if (msg->FindRef("refs", &the_ref) == B_NO_ERROR)
741 if (the_entry.SetTo(&the_ref) == B_NO_ERROR)
742 if (the_entry.IsFile()) {
743 BPath the_path;
744 the_entry.GetPath(&the_path);
745 strncpy(prefs_path, the_path.Path(), 1023);
746 prefs_path[1023] = 0;
747 prefs->Load(prefs_path);
748 set_values();
749 }
750 }
751
752 case MSG_SAVE:
753 get_values();
754 prefs->Save(prefs_path);
755 break;
756
757 case MSG_SAVE_AS:
758 save_panel->Show();
759 break;
760
761 case MSG_SAVE_PANEL_RETURNED: { // Save file panel returned
762 entry_ref the_ref;
763 BEntry the_entry;
764 if (msg->FindRef("directory", &the_ref) == B_NO_ERROR)
765 if (the_entry.SetTo(&the_ref) == B_NO_ERROR) {
766 BPath the_path;
767 the_entry.GetPath(&the_path);
768 strncpy(prefs_path, the_path.Path(), 1023);
769 strncat(prefs_path, "/", 1023);
770 strncat(prefs_path, msg->FindString("name"), 1023);
771 prefs_path[1023] = 0;
772 get_values();
773 if (!prefs->Save(prefs_path))
774 ShowRequester("Couldn't save preferences.", "Too bad");
775 }
776 break;
777 }
778
779 case MSG_REVERT:
780 get_values(); // Useful if Load() is unsuccessful
781 prefs->Load(prefs_path);
782 set_values();
783 break;
784
785 default:
786 BWindow::MessageReceived(msg);
787 }
788 }
789
790
791 /*
792 * Intercept ESC key (works as clicking the Cancel button)
793 */
794
795 bool PrefsWindow::FilterKeyDown(uint32 *aChar, BView **target)
796 {
797 if (*aChar == B_ESCAPE) {
798 // Flash Cancel button
799 g_cancel->SetValue(B_CONTROL_ON);
800 snooze(100000);
801 PostMessage(MSG_CANCEL);
802 }
803 return true;
804 }
805
806
807 /*
808 * Quit requested
809 */
810
811 bool PrefsWindow::QuitRequested(void)
812 {
813 delete open_panel;
814 delete save_panel;
815 delete file_panel;
816 delete dir_panel;
817 return true;
818 }