ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/Prefs_Be.h
Revision: 1.2
Committed: 2003-07-01T17:51:17Z (20 years, 9 months ago) by cebix
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
updated copyright date

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