1 /*
2 * AcornGUI.cc
3 *
4 * Frodo's Graphical User Interface for Acorn RISC OS machines (WIMP)
5 * (C) 1997 Andreas Dehmel
6 *
7 */
8
9
10
11 #include "sysdeps.h"
12
13 #include "C64.h"
14 #include "VIC.h"
15 #include "Display.h"
16 #include "Prefs.h"
17 #include "main.h"
18 #include "ROlib.h"
19 #include "AcornGUI.h"
20 #include "Version.h"
21
22
23
24 #define CUSTOM_SPRITES "FrodoRsrc:Sprites"
25 #define TEMPLATES_FILE "FrodoRsrc:Templates"
26 #define WIMP_SCRAP_FILE "<Wimp$Scrap>"
27
28
29 #define FileType_Data 0xffd
30 #define FileType_Text 0xfff
31 #define FileType_C64File 0x064
32 #define FileType_D64File 0x164
33
34 #define IconSpriteSize 68 // OS units of an icon sprite (for dragging)
35 #define EstimatedPrefsSize 1024 // can't say how big it'll be before saving...
36 #define EstimatedConfSize 256
37 #define EstimatedRAMSize 0x10400
38 #define EstimatedSnapSize 0x11000
39
40
41
42
43 // For the scanning of the joystick keys in the SysConfig window
44 #define IntKey_ScanFrom 3
45 // This key gets translated to 0xff, i.e. none (joystick inactive)
46 #define IntKey_Void 44
47
48
49 #define Key_Return 13
50
51
52
53
54 // LED number to Icon number translation:
55 char LEDtoIcon[4] = {Icon_Pane_LED0, Icon_Pane_LED1, Icon_Pane_LED2, Icon_Pane_LED3};
56 // Drive number to Icon number (Pane) translation:
57 char PDrvToIcon[4] = {Icon_Pane_Drive0, Icon_Pane_Drive1, Icon_Pane_Drive2, Icon_Pane_Drive3};
58 // Drive number to Icon number (Prefs) translation:
59 #define IconsPerDrive 4
60 char DriveToIcon[16] = {
61 Icon_Prefs_Dr8DIR, Icon_Prefs_Dr8D64, Icon_Prefs_Dr8T64, Icon_Prefs_Dr8Path,
62 Icon_Prefs_Dr9DIR, Icon_Prefs_Dr9D64, Icon_Prefs_Dr9T64, Icon_Prefs_Dr9Path,
63 Icon_Prefs_Dr10DIR, Icon_Prefs_Dr10D64, Icon_Prefs_Dr10T64, Icon_Prefs_Dr10Path,
64 Icon_Prefs_Dr11DIR, Icon_Prefs_Dr11D64, Icon_Prefs_Dr11T64, Icon_Prefs_Dr11Path
65 };
66 // SID type to Icon number translation:
67 char SIDtoIcon[3] = {
68 Icon_Prefs_SIDNone, Icon_Prefs_SIDDigi, Icon_Prefs_SIDCard
69 };
70 // REU type to Icon number translation:
71 char REUtoIcon[4] = {
72 Icon_Prefs_REUNone, Icon_Prefs_REU128, Icon_Prefs_REU256, Icon_Prefs_REU512
73 };
74 char KJoyToIcon[2][5] = {
75 {Icon_Conf_Joy1Up, Icon_Conf_Joy1Down, Icon_Conf_Joy1Left, Icon_Conf_Joy1Right, Icon_Conf_Joy1Fire},
76 {Icon_Conf_Joy2Up, Icon_Conf_Joy2Down, Icon_Conf_Joy2Left, Icon_Conf_Joy2Right, Icon_Conf_Joy2Fire}
77 };
78
79
80
81
82
83 // Internal keynumbers lookup table
84 // Single characters are represented by single chars, others by pointers to strings
85 int IntKeyTable[128] = {
86 (int)"Shft", (int)"Ctrl", (int)"Alt", (int)"ShftL",
87 (int)"CtrlL", (int)"AltL", (int)"ShftR", (int)"CtrlR",
88 (int)"AltR", (int)"Slct", (int)"Menu", (int)"Adjst",
89 0, 0, 0, 0,
90 'q', '3', '4', '5',
91 (int)"F4", '8', (int)"F7", '-',
92 '6', (int)"Left", (int)"num6", (int)"num7",
93 (int)"F11", (int)"F12", (int)"F10", (int)"ScLck",
94 (int)"Prnt", 'w', 'e', 't',
95 '7', 'i', '9', '0',
96 '-', (int)"Down", (int)"num8", (int)"num9",
97 (int)"Brk", '`', '�', (int)"Del",
98 '1', '2', 'd', 'r',
99 '6', 'u', 'o', 'p',
100 '[', (int)"Up", (int)"num+", (int)"num-",
101 (int)"nmEnt", (int)"Isrt", (int)"Home", (int)"PgUp",
102 (int)"CpLck", 'a', 'x', 'f',
103 'y', 'j', 'k', '2',
104 ';', (int)"Ret", (int)"num/", 0,
105 (int)"num.", (int)"nmLck", (int)"PgDwn", '\'',
106 0, 's', 'c', 'g',
107 'h', 'n', 'l', ';',
108 ']', (int)"Del", (int)"num#", (int)"num*",
109 0, '=', (int)"Extra", 0,
110 (int)"Tab", 'z', (int)"Space", 'v',
111 'b', 'm', ',', '.',
112 '/', (int)"Copy", (int)"num0", (int)"num1",
113 (int)"num3", 0, 0, 0,
114 (int)"Esc", (int)"F1", (int)"F2", (int)"F3",
115 (int)"F5", (int)"F6", (int)"F8", (int)"F9",
116 '\\', (int)"Right", (int)"num4", (int)"num5",
117 (int)"num2", 0, 0, 0
118 };
119
120
121
122
123
124 // The icon bar icon
125 RO_IconDesc IBarIcon = {
126 -1, 0, 0, 68, 68, 0x301a,
127 #ifdef FRODO_SC
128 "!frodosc"
129 #else
130 # ifdef FRODO_PC
131 "!frodopc"
132 # else
133 "!frodo"
134 # endif
135 #endif
136 };
137
138
139
140
141
142 // The menus
143
144 char *MIBTextPrefs = "Preferences...";
145 char *MIBTextConf = "Configuration...";
146
147
148 struct MenuIconBar {
149 RO_MenuHead head;
150 RO_MenuItem item[Menu_IBar_Items];
151 } MenuIconBar = {
152 {
153 #ifdef FRODO_SC
154 "FrodoSC",
155 #else
156 # ifdef FRODO_PC
157 "FrodoPC",
158 # else
159 "Frodo",
160 # endif
161 #endif
162 7, 2, 7, 0, Menu_IBar_Width, Menu_Height, 0},
163 {
164 {0, (RO_MenuHead*)-1, Menu_Flags, "Info"},
165 {0, (RO_MenuHead*)-1, Menu_Flags + IFlg_Indir, ""},
166 {0, (RO_MenuHead*)-1, Menu_Flags + IFlg_Indir, ""},
167 {0, (RO_MenuHead*)-1, Menu_Flags, "Sound"},
168 {MFlg_LastItem, (RO_MenuHead*)-1, Menu_Flags, "Quit"}
169 }
170 };
171
172 struct MenuEmuWindow {
173 RO_MenuHead head;
174 RO_MenuItem item[Menu_EWind_Items];
175 } MenuEmuWindow = {
176 {
177 #ifdef FRODO_SC
178 "FrodoSC Job",
179 #else
180 # ifdef FRODO_PC
181 "FrodoPC Job",
182 # else
183 "Frodo Job",
184 # endif
185 #endif
186 7, 2, 7, 0, Menu_EWind_Width, Menu_Height, 0},
187 {
188 {0, (RO_MenuHead*)-1, Menu_Flags, "Info"},
189 {0, (RO_MenuHead*)-1, Menu_Flags, "Sound"},
190 {MFlg_Warning, (RO_MenuHead*)-1, Menu_Flags, "Save RAM"},
191 {MFlg_LastItem | MFlg_Warning, (RO_MenuHead*)-1, Menu_Flags, "Snapshot"}
192 }
193 };
194
195
196
197
198 // For less writing in LoadATemplate...
199 #define wic(base,no,off) base[RO_WINDOW_WORDS + no*RO_ICON_WORDS + off]
200
201 // For less writing in WindowToThePrefs...
202 #define pread_opt(var,icn) PrefsWindow->GetIconState(Icon_Prefs_##icn,AuxBlock);\
203 prefs->##var = ((AuxBlock[IconB_Flags] & IFlg_Slct) == 0) ? false : true;
204
205
206
207 //
208 // WIMP member-functions
209 //
210
WIMP(C64 * my_c64)211 WIMP::WIMP(C64 *my_c64)
212 {
213 int x,y,i;
214 WIdata *wid;
215
216 CMOS_DragType = ReadDragType();
217
218 // Determine the dimensions of the icon bar sprite first.
219 if (Wimp_SpriteInfo((char*)(&IBarIcon.dat),&x,&y,&i) == NULL)
220 {
221 IBarIcon.maxx = x << OS_ReadModeVariable(i,4);
222 IBarIcon.maxy = y << OS_ReadModeVariable(i,5);
223 }
224
225 IBicon = new Icon(0,&IBarIcon); Mask = 0x00000830;
226 LastMenu = LastClick = LastDrag = MenuType = DragType = 0;
227 UseScrap = false; EmuPaused = false; UseNULL = 0; // one NULL client - the emulator
228 the_c64 = my_c64;
229 EmuZoom = 1;
230
231 // Read the customized sprite area (LEDs etc)
232 if ((ReadCatalogueInfo(CUSTOM_SPRITES,AuxBlock) & 1) != 0) // (image) file
233 {
234 int i;
235 FILE *fp;
236
237 i = AuxBlock[2]; SpriteArea = (int*)(new char[i+16]); // allocate space for sprite
238 fp = fopen(CUSTOM_SPRITES,"rb");
239 i = fread(SpriteArea+1,1,i,fp); SpriteArea[0] = i+4;
240 fclose(fp);
241 }
242 else
243 {
244 WimpError.errnum = 0; sprintf(WimpError.errmess,"Can't read sprites!!!");
245 Wimp_ReportError(&WimpError,1,TASKNAME);
246 }
247
248 // Read Template and create windows
249 if (Wimp_OpenTemplate(TEMPLATES_FILE) == NULL)
250 {
251 // Load Pane first
252 LoadATemplate("EmuPane",&EmuPane);
253 LoadATemplate("EmuWindow",&EmuWindow);
254 LoadATemplate("ThePrefs",&PrefsWindow);
255 LoadATemplate("ConfigWind",&ConfigWindow);
256 LoadATemplate("InfoWindow",&InfoWindow);
257 LoadATemplate("SoundWindow",&SoundWindow);
258 LoadATemplate("SaveBox",&SaveBox);
259 }
260 else
261 {
262 Wimp_ReportError(&WimpError,1,TASKNAME);
263 WimpError.errnum = 0; sprintf(WimpError.errmess,"Error in Templates!!!");
264 }
265 Wimp_CloseTemplate();
266
267 // Add info window to icon bar menu
268 MenuIconBar.item[Menu_IBar_Info].submenu =
269 MenuEmuWindow.item[Menu_EWind_Info].submenu = (RO_MenuHead*)InfoWindow->MyHandle();
270 MenuIconBar.item[Menu_IBar_Sound].submenu =
271 MenuEmuWindow.item[Menu_EWind_Sound].submenu = (RO_MenuHead*)SoundWindow->MyHandle();
272 MenuEmuWindow.item[Menu_EWind_SaveRAM].submenu =
273 MenuEmuWindow.item[Menu_EWind_Snapshot].submenu = (RO_MenuHead*)SaveBox->MyHandle();
274 // I couldn't find ONE FUCKING WAY to do this in the initialisation directly and I'm
275 // REALLY PISSED OFF!
276 wid = &(MenuIconBar.item[Menu_IBar_Prefs].dat);
277 wid->ind.tit = (int*)MIBTextPrefs; wid->ind.val = NULL; wid->ind.len = sizeof(MIBTextPrefs);
278 wid = &(MenuIconBar.item[Menu_IBar_Config].dat);
279 wid->ind.tit = (int*)MIBTextConf; wid->ind.val = NULL; wid->ind.len = sizeof(MIBTextConf);
280
281 // Write default path into config window
282 ConfigWindow->WriteIconText(Icon_Conf_ConfPath,DEFAULT_SYSCONF);
283
284 // Set up the contents of the prefs window and init with the default prefs path
285 ThePrefsToWindow();
286 PrefsWindow->WriteIconText(Icon_Prefs_PrefPath,DEFAULT_PREFS);
287 // Grey out SID card icon -- not supported!
288 PrefsWindow->SetIconState(Icon_Prefs_SIDCard,IFlg_Grey,IFlg_Grey);
289
290 // Open Emulator window + pane in the center of the screen and give it the input focus
291 Wimp_GetCaretPosition(&LastCaret);
292 OpenEmuWindow();
293 Wimp_SetCaretPosition(EmuWindow->MyHandle(),-1,-100,100,-1,-1); // emu window gets input focus
294
295 // Init export files
296 sprintf(RAMFile+44,"C64_RAM"); sprintf(SnapFile+44,"FrodoSnap");
297 }
298
299
~WIMP(void)300 WIMP::~WIMP(void)
301 {
302 delete IBicon;
303 delete EmuWindow; delete EmuPane; delete PrefsWindow; delete ConfigWindow;
304 delete InfoWindow; delete SoundWindow; delete SaveBox;
305 }
306
307
LoadATemplate(char * Name,Window ** Which)308 bool WIMP::LoadATemplate(char *Name, Window **Which)
309 {
310 char *Buffer, *Indirect, *Desc;
311 int IndSize, Pos;
312 char TempName[12];
313
314 strncpy((char*)TempName,Name,12);
315 Buffer = NULL; Pos = 0;
316 if (Wimp_LoadTemplate(&Buffer,&Indirect,0,(char*)-1,TempName,&Pos) != NULL) {return(false);}
317 Buffer = new char[(int)Buffer + 4];
318 IndSize = (int)Indirect; Indirect = new char[IndSize];
319 Pos = 0; Desc = Buffer+4;
320 Wimp_LoadTemplate(&Desc,&Indirect,Indirect+IndSize,(char*)-1,TempName,&Pos);
321 if (Which == &EmuWindow)
322 {
323 int eigen, dx, dy;
324 RO_Window *row = (RO_Window*)Buffer;
325 RORes res;
326
327 // Center emulator window on screen
328 eigen = (res.eigx < res.eigy) ? res.eigx : res.eigy;
329 dx = (DISPLAY_X << eigen); dy = (DISPLAY_Y << eigen);
330 row->vminx = res.resx/2 - dx/2; row->vmaxx = row->vminx + dx;
331 row->vminy = res.resy/2 - dy/2; row->vmaxy = row->vminy + dy;
332 row->wminy = -dy; row->wmaxx = dx;
333 Indirect = (char*)VERSION_STRING;
334 }
335 else
336 {
337 if (Which == &EmuPane) // EmuPane needs customized sprites
338 {
339 register RO_Window *row = (RO_Window*)Buffer;
340 register int *b = (int*)Buffer;
341
342 // Insert sprite pointer in window and icon definitions
343 row->SpriteAreaPtr = (int)SpriteArea;
344 wic(b,Icon_Pane_LED0,RawIB_Data1) = wic(b,Icon_Pane_LED1,RawIB_Data1) =
345 wic(b,Icon_Pane_LED2,RawIB_Data1) = wic(b,Icon_Pane_LED3,RawIB_Data1) = (int)SpriteArea;
346 sprintf((char*)wic(b,Icon_Pane_Pause,RawIB_Data0),PANE_TEXT_PAUSE);
347 sprintf((char*)wic(b,Icon_Pane_Toggle,RawIB_Data0),PANE_TEXT_ZOOM2);
348 }
349 else if (Which == &SoundWindow) // ditto
350 {
351 register RO_Window *row = (RO_Window*)Buffer;
352 register int *b = (int*)Buffer;
353 register int orr;
354
355 row->SpriteAreaPtr = (int)SpriteArea;
356 // if sound emulation off grey out notes
357 if (ThePrefs.SIDType == SIDTYPE_NONE) {orr = IFlg_Grey;} else {orr = 0;}
358 wic(b,Icon_Sound_Notes,RawIB_Flags)=(wic(b,Icon_Sound_Notes,RawIB_Flags)&~IFlg_Grey)|orr;
359 }
360 else if (Which == &InfoWindow) // ditto
361 {
362 register RO_Window *row = (RO_Window*)Buffer;
363
364 row->SpriteAreaPtr = (int)SpriteArea;
365 }
366 Indirect = NULL;
367 }
368 *Which = new Window((int*)Buffer,Indirect);
369 return(true);
370 }
371
372
373 // All changes in position of the Emulator window have to be treated seperately
374 // to keep the pane attached to it at all times!
OpenEmuWindow(void)375 void WIMP::OpenEmuWindow(void)
376 {
377 RO_Window *wind;
378 int work[WindowB_WFlags], i;
379
380 wind = EmuWindow->Descriptor();
381 EmuPane->GetWorkArea(&work[WindowB_VMinX]); i = work[WindowB_VMaxX] - work[WindowB_VMinX];
382 if ((work[WindowB_VMinX] = wind->vminx - EmuPaneSpace - i) < 0)
383 {
384 // if main window still on screen then keep pane on screen as well
385 if (wind->vminx >= 0) {work[WindowB_VMinX] = 0;}
386 // otherwise align pane and main window on the left
387 else {work[WindowB_VMinX] = wind->vminx;}
388 }
389 work[WindowB_VMaxX] = work[WindowB_VMinX] + i;
390 work[WindowB_VMinY] = wind->vmaxy - (work[WindowB_VMaxY]-work[WindowB_VMinY]);
391 work[WindowB_VMaxY] = wind->vmaxy;
392 work[WindowB_Handle] = EmuPane->MyHandle();
393 work[WindowB_ScrollX] = work[WindowB_ScrollY] = 0;
394 work[WindowB_Stackpos] = -1; // open on top of stack
395 // open the pane first
396 EmuPane->open(work);
397 wind->stackpos = EmuPane->MyHandle(); // open window behind pane.
398 EmuWindow->open();
399 }
400
401
OpenEmuWindow(int * Where)402 void WIMP::OpenEmuWindow(int *Where)
403 {
404 int work[WindowB_WFlags], i;
405
406 EmuPane->GetWorkArea(&work[WindowB_VMinX]); i = work[WindowB_VMaxX] - work[WindowB_VMinX];
407 if ((work[WindowB_VMinX] = Where[WindowB_VMinX] - EmuPaneSpace - i) < 0)
408 {
409 if (Where[WindowB_VMinX] >= 0) {work[WindowB_VMinX] = 0;}
410 else {work[WindowB_VMinX] = Where[WindowB_VMinX];}
411 }
412 work[WindowB_VMaxX] = work[WindowB_VMinX] + i;
413 work[WindowB_VMinY] = Where[WindowB_VMaxY] - (work[WindowB_VMaxY]-work[WindowB_VMinY]);
414 work[WindowB_VMaxY] = Where[WindowB_VMaxY];
415 work[WindowB_Handle] = EmuPane->MyHandle();
416 work[WindowB_ScrollX] = work[WindowB_ScrollY] = 0;
417 work[WindowB_Stackpos] = Where[WindowB_Stackpos];
418 // open the pane first
419 EmuPane->open(work);
420 Where[WindowB_Stackpos] = EmuPane->MyHandle(); // open window behind pane
421 EmuWindow->open(Where);
422 }
423
424
CloseEmuWindow(void)425 void WIMP::CloseEmuWindow(void)
426 {
427 EmuWindow->close(); EmuPane->close();
428 }
429
430
UpdateEmuWindow(void)431 void WIMP::UpdateEmuWindow(void)
432 {
433 C64Display *disp = the_c64->TheDisplay;
434
435 EmuWindow->update(disp->BitmapBase(),disp);
436 }
437
438
439 // Write the values given in ThePrefs into the Prefs Window
ThePrefsToWindow(void)440 void WIMP::ThePrefsToWindow(void)
441 {
442 int i, j, k;
443
444 // Update the data for each of the drives
445 for (i=0; i<4; i++)
446 {
447 switch(ThePrefs.DriveType[i])
448 {
449 case DRVTYPE_D64: j=1; break;
450 case DRVTYPE_T64: j=2; break;
451 default: j=0; break; // otherwise type 0 = DIR
452 }
453 // unselect all but other icons
454 for (k=0; k<3; k++)
455 {
456 if (k != j) {PrefsWindow->SetIconState(DriveToIcon[i*IconsPerDrive + k],0,IFlg_Slct);}
457 }
458 // and select the correct one.
459 PrefsWindow->SetIconState(DriveToIcon[i*IconsPerDrive + j],IFlg_Slct,IFlg_Slct);
460 // Now update the path name (buffer won't change, i.e. use original data)
461 PrefsWindow->WriteIconText(DriveToIcon[i*IconsPerDrive + 3],ThePrefs.DrivePath[i]);
462 }
463 if (ThePrefs.Emul1541Proc) {i = IFlg_Slct;} else {i = 0;}
464 PrefsWindow->SetIconState(Icon_Prefs_Emul1541,i,IFlg_Slct);
465 SetLEDIcons(ThePrefs.Emul1541Proc);
466 if (ThePrefs.MapSlash) {i = IFlg_Slct;} else {i = 0;}
467 PrefsWindow->SetIconState(Icon_Prefs_MapSlash,i,IFlg_Slct);
468
469 // SID prefs
470 switch (ThePrefs.SIDType)
471 {
472 case SIDTYPE_DIGITAL: i = 1; break;
473 case SIDTYPE_SIDCARD: i = 2; break;
474 default: i = 0; break; // includes NONE
475 }
476 for (j=0; j<3; j++)
477 {
478 if (j != i) {PrefsWindow->SetIconState(SIDtoIcon[j],0,IFlg_Slct);}
479 }
480 PrefsWindow->SetIconState(SIDtoIcon[i],IFlg_Slct,IFlg_Slct);
481 PrefsWindow->SetIconState(Icon_Prefs_SIDFilter,(ThePrefs.SIDFilters)?IFlg_Slct:0,IFlg_Slct);
482
483 // REU prefs
484 switch (ThePrefs.REUSize)
485 {
486 case REU_128K: i=1; break;
487 case REU_256K: i=2; break;
488 case REU_512K: i=3; break;
489 default: i=0; break;
490 }
491 for (j=0; j<4; j++)
492 {
493 if (j != i) {PrefsWindow->SetIconState(REUtoIcon[j],0,IFlg_Slct);}
494 }
495 PrefsWindow->SetIconState(REUtoIcon[i],IFlg_Slct,IFlg_Slct);
496
497 // Skip Frames
498 PrefsWindow->WriteIconNumber(Icon_Prefs_SkipFText,ThePrefs.SkipFrames);
499
500 // Sprites
501 PrefsWindow->SetIconState(Icon_Prefs_SprOn,(ThePrefs.SpritesOn)?IFlg_Slct:0,IFlg_Slct);
502 PrefsWindow->SetIconState(Icon_Prefs_SprColl,(ThePrefs.SpriteCollisions)?IFlg_Slct:0,IFlg_Slct);
503 // Joystick
504 PrefsWindow->SetIconState(Icon_Prefs_Joy1On,(ThePrefs.Joystick1On)?IFlg_Slct:0,IFlg_Slct);
505 PrefsWindow->SetIconState(Icon_Prefs_Joy2On,(ThePrefs.Joystick2On)?IFlg_Slct:0,IFlg_Slct);
506 PrefsWindow->SetIconState(Icon_Prefs_JoySwap,(ThePrefs.JoystickSwap)?IFlg_Slct:0,IFlg_Slct);
507
508 // Misc
509 SetSpeedLimiter(ThePrefs.LimitSpeed);
510 PrefsWindow->SetIconState(Icon_Prefs_FastReset,(ThePrefs.FastReset)?IFlg_Slct:0,IFlg_Slct);
511 PrefsWindow->SetIconState(Icon_Prefs_CIAHack,(ThePrefs.CIAIRQHack)?IFlg_Slct:0,IFlg_Slct);
512
513 // Cycles
514 PrefsWindow->WriteIconNumber(Icon_Prefs_CycleNorm,ThePrefs.NormalCycles);
515 PrefsWindow->WriteIconNumber(Icon_Prefs_CycleBad,ThePrefs.BadLineCycles);
516 PrefsWindow->WriteIconNumber(Icon_Prefs_CycleCIA,ThePrefs.CIACycles);
517 PrefsWindow->WriteIconNumber(Icon_Prefs_CycleFloppy,ThePrefs.FloppyCycles);
518 }
519
520
521 // Update ThePrefs according to the values given in the Prefs Window
WindowToThePrefs(void)522 void WIMP::WindowToThePrefs(void)
523 {
524 int i, j, k;
525 Prefs *prefs = new Prefs(ThePrefs);
526
527 for (i=0; i<4; i++)
528 {
529 // find out which of the drive type icons is selected
530 j = -1;
531 do
532 {
533 ++j; PrefsWindow->GetIconState(DriveToIcon[i*IconsPerDrive + j],AuxBlock);
534 }
535 while ((j < 3) && ((AuxBlock[IconB_Flags] & IFlg_Slct) == 0));
536 switch (j)
537 {
538 case 1: prefs->DriveType[i] = DRVTYPE_D64; break;
539 case 2: prefs->DriveType[i] = DRVTYPE_T64; break;
540 default: prefs->DriveType[i] = DRVTYPE_DIR; break;
541 }
542 strcpy(prefs->DrivePath[i],PrefsWindow->ReadIconText(DriveToIcon[i*IconsPerDrive + 3]));
543 }
544 // Emulation of the 1541 processor is a special case as it also affects LED1-3
545 pread_opt(Emul1541Proc,Emul1541);
546 SetLEDIcons(prefs->Emul1541Proc);
547 pread_opt(MapSlash,MapSlash);
548
549 // SID
550 j = -1;
551 do
552 {
553 ++j; PrefsWindow->GetIconState(SIDtoIcon[j],AuxBlock);
554 }
555 while ((j < 3) && ((AuxBlock[IconB_Flags] & IFlg_Slct) == 0));
556 switch (j)
557 {
558 case 1: prefs->SIDType = SIDTYPE_DIGITAL; break;
559 case 2: prefs->SIDType = SIDTYPE_SIDCARD; break;
560 default: prefs->SIDType = SIDTYPE_NONE; break;
561 }
562 pread_opt(SIDFilters,SIDFilter);
563 SoundWindow->SetIconState(Icon_Sound_Notes,(prefs->SIDType==SIDTYPE_NONE)?IFlg_Grey:0,IFlg_Grey);
564
565 // REU
566 j = -1;
567 do
568 {
569 ++j; PrefsWindow->GetIconState(REUtoIcon[j],AuxBlock);
570 }
571 while ((j < 4) && ((AuxBlock[IconB_Flags] & IFlg_Slct) == 0));
572 switch (j)
573 {
574 case 1: prefs->REUSize = REU_128K; break;
575 case 2: prefs->REUSize = REU_256K; break;
576 case 3: prefs->REUSize = REU_512K; break;
577 default: prefs->REUSize = REU_NONE; break;
578 }
579
580 // Skip Frames
581 prefs->SkipFrames = PrefsWindow->ReadIconNumber(Icon_Prefs_SkipFText);
582
583 // Sprites
584 pread_opt(SpritesOn,SprOn); pread_opt(SpriteCollisions,SprColl);
585
586 // Joystick
587 pread_opt(Joystick1On,Joy1On); pread_opt(Joystick2On,Joy2On); pread_opt(JoystickSwap,JoySwap);
588
589 // Misc
590 pread_opt(LimitSpeed,LimSpeed); pread_opt(FastReset,FastReset); pread_opt(CIAIRQHack,CIAHack);
591
592 // Cycles
593 prefs->NormalCycles = PrefsWindow->ReadIconNumber(Icon_Prefs_CycleNorm);
594 prefs->BadLineCycles = PrefsWindow->ReadIconNumber(Icon_Prefs_CycleBad);
595 prefs->CIACycles = PrefsWindow->ReadIconNumber(Icon_Prefs_CycleCIA);
596 prefs->FloppyCycles = PrefsWindow->ReadIconNumber(Icon_Prefs_CycleFloppy);
597
598 // Finally make the changes known to the system:
599 the_c64->NewPrefs(prefs);
600 ThePrefs = *prefs;
601 delete prefs;
602 }
603
604
605 // Update the SysConfig window according to the values used
SysConfToWindow(void)606 void WIMP::SysConfToWindow(void)
607 {
608 int i, j, k;
609 Joy_Keys *jk;
610 char OneChar[2], *b;
611
612 OneChar[1] = 0;
613
614 // Write timings
615 the_c64->ReadTimings(&i,&j,&k);
616 ConfigWindow->WriteIconNumber(Icon_Conf_PollAfter, i);
617 ConfigWindow->WriteIconNumber(Icon_Conf_SpeedAfter, j);
618 ConfigWindow->WriteIconNumber(Icon_Conf_SoundAfter, k);
619
620 // Write joystick keys
621 for (i=0; i<2; i++)
622 {
623 jk = &(the_c64->TheDisplay->JoystickKeys[i]); NewJoyKeys[i] = *jk;
624 if ((j = jk->up) >= 128) {j = 127;}
625 j = IntKeyTable[j]; if (j < 256) {OneChar[0] = j; b = OneChar;} else {b = (char*)j;}
626 ConfigWindow->WriteIconText(KJoyToIcon[i][0], b);
627 if ((j = jk->down) >= 128) {j = 127;}
628 j = IntKeyTable[j]; if (j < 256) {OneChar[0] = j; b = OneChar;} else {b = (char*)j;}
629 ConfigWindow->WriteIconText(KJoyToIcon[i][1], b);
630 if ((j = jk->left) >= 128) {j = 127;}
631 j = IntKeyTable[j]; if (j < 256) {OneChar[0] = j; b = OneChar;} else {b = (char*)j;}
632 ConfigWindow->WriteIconText(KJoyToIcon[i][2], b);
633 if ((j = jk->right) >= 128) {j = 127;}
634 j = IntKeyTable[j]; if (j < 256) {OneChar[0] = j; b = OneChar;} else {b = (char*)j;}
635 ConfigWindow->WriteIconText(KJoyToIcon[i][3], b);
636 if ((j = jk->fire) >= 128) {j = 127;}
637 j = IntKeyTable[j]; if (j < 256) {OneChar[0] = j; b = OneChar;} else {b = (char*)j;}
638 ConfigWindow->WriteIconText(KJoyToIcon[i][4], b);
639 }
640 }
641
642
643 // Update SysConfig according to the values in the window
WindowToSysConf(void)644 void WIMP::WindowToSysConf(void)
645 {
646 int i, j, k;
647 Joy_Keys *jk;
648
649 // Read timings
650 i = ConfigWindow->ReadIconNumber(Icon_Conf_PollAfter);
651 j = ConfigWindow->ReadIconNumber(Icon_Conf_SpeedAfter);
652 k = ConfigWindow->ReadIconNumber(Icon_Conf_SoundAfter);
653 the_c64->WriteTimings(i,j,k);
654
655 // Read joystick keys
656 for (i=0; i<2; i++)
657 {
658 jk = &(the_c64->TheDisplay->JoystickKeys[i]); *jk = NewJoyKeys[i];
659 }
660 }
661
662
663 // Low-level keyboard scan in SysConfig Window
PollSysConfWindow(void)664 void WIMP::PollSysConfWindow(void)
665 {
666 Wimp_GetPointerInfo(Block);
667 if (Block[MouseB_Window] == ConfigWindow->MyHandle())
668 {
669 int i, j;
670
671 for (i=0; i<2; i++)
672 {
673 for (j=0; j<5; j++)
674 {
675 if (Block[MouseB_Icon] == KJoyToIcon[i][j])
676 {
677 int key;
678
679 // Gain caret (to window, but none of its icons!)
680 Wimp_GetCaretPosition(&LastCaret);
681 Wimp_SetCaretPosition(ConfigWindow->MyHandle(),-1,0,0,-1,-1);
682 if ((key = ScanKeys(IntKey_ScanFrom)) != 0xff)
683 {
684 char OneChar[2], *b;
685
686 if (key == IntKey_Void) {key = 0xff;}
687 switch (j)
688 {
689 case 0: NewJoyKeys[i].up = key; break;
690 case 1: NewJoyKeys[i].down = key; break;
691 case 2: NewJoyKeys[i].left = key; break;
692 case 3: NewJoyKeys[i].right = key; break;
693 case 4: NewJoyKeys[i].fire = key; break;
694 }
695 if (key >= 128) {key = 127;}
696 key = IntKeyTable[key];
697 if (key < 256) {OneChar[0]=key; OneChar[1]=0; b=OneChar;} else {b=(char*)key;}
698 ConfigWindow->WriteIconText(KJoyToIcon[i][j], b);
699 }
700 }
701 }
702 }
703 }
704 }
705
706
707 // Start a drag operation on the icon <number> in the window <host>
DragIconSprite(Window * host,unsigned int number)708 void WIMP::DragIconSprite(Window *host, unsigned int number)
709 {
710 host->GetIconState(number,AuxBlock);
711 if ((AuxBlock[IconB_Flags] & IFlg_Sprite) != 0) // it needs to have a sprite, of course
712 {
713 char spritename[16] = "\0";
714
715 if ((AuxBlock[IconB_Flags] & IFlg_Indir) == 0) // not indirected
716 {
717 strncpy(spritename,((char*)AuxBlock+IconB_Data0),15);
718 }
719 else
720 {
721 if ((AuxBlock[IconB_Flags] & IFlg_Text) == 0)
722 {
723 strncpy(spritename,(char*)AuxBlock[IconB_Data0],15);
724 }
725 else // this necessitates parsing the validation string
726 {
727 register char *b, *d, *s, c;
728
729 s = spritename;
730 if ((b = (char*)AuxBlock[IconB_Data1]) != NULL) // pointer to val str
731 {
732 do
733 {
734 c = *b++;
735 if ((c == 's') || (c == 'S')) // sprite command
736 {
737 c = *b++; while ((c != ';') && (c >= 32)) {*s++ = c; c = *b++;}
738 c = 0; *s++ = c; // we can stop now
739 }
740 else if (c >= 32) // some other command ==> skip to next.
741 {
742 c = *b++;
743 while ((c != ';') && (c >= 32)) {if (c == '\\') {b++;} c = *b++;}
744 }
745 }
746 while (c >= 32);
747 }
748 }
749 }
750 // we should now have the spritename
751 if (spritename[0] != '\0')
752 {
753 LastDrag = host->MyHandle(); LastIcon = number;
754 if (CMOS_DragType == 0) // Drag outline
755 {
756 ROScreen *screen = the_c64->TheDisplay->screen;
757
758 AuxBlock[DragB_Handle] = LastDrag; AuxBlock[DragB_Type] = 5;
759 Wimp_GetPointerInfo(AuxBlock + DragB_IMinX);
760 // Drag fixed sized box of this size:
761 AuxBlock[DragB_IMinX] -= IconSpriteSize/2;
762 AuxBlock[DragB_IMaxX] = AuxBlock[DragB_IMinX] + IconSpriteSize;
763 AuxBlock[DragB_IMinY] -= IconSpriteSize/2;
764 AuxBlock[DragB_IMaxY] = AuxBlock[DragB_IMinY] + IconSpriteSize;
765 // Parent box is whole screen
766 AuxBlock[DragB_BBMinX] = AuxBlock[DragB_BBMinY] = 0;
767 AuxBlock[DragB_BBMaxX] = screen->resx; AuxBlock[DragB_BBMaxY] = screen->resy;
768 Wimp_DragBox(AuxBlock);
769 }
770 else // DragASprite
771 {
772 Wimp_GetPointerInfo(AuxBlock);
773 AuxBlock[DASB_MinX] -= IconSpriteSize/2;
774 AuxBlock[DASB_MaxX] = AuxBlock[DASB_MinX] + IconSpriteSize;
775 AuxBlock[DASB_MinY] -= IconSpriteSize/2;
776 AuxBlock[DASB_MaxY] = AuxBlock[DASB_MinY] + IconSpriteSize;
777 DragASprite_Start(0xc5,1,spritename,AuxBlock,NULL);
778 }
779 }
780 }
781 }
782
783
784 // Blk is a block as in MouseClick or PointerInfo
CalculateVolume(int * Blk)785 int WIMP::CalculateVolume(int *Blk)
786 {
787 int orgx, vol;
788
789 SoundWindow->getstate(AuxBlock);
790 orgx = AuxBlock[WindowB_VMinX] - AuxBlock[WindowB_ScrollX];
791 SoundWindow->GetIconState(Icon_Sound_Volume, AuxBlock);
792 vol = (MaximumVolume*((Blk[MouseB_PosX] - orgx) - AuxBlock[IconB_MinX] - WellBorder)) / (AuxBlock[IconB_MaxX] - AuxBlock[IconB_MinX] - 2*WellBorder);
793 if (vol < 0) {vol = 0;} if (vol > MaximumVolume) {vol = MaximumVolume;}
794 return(vol);
795 }
796
797
798 // Check whether a filename contains a full pathname and reports an error if not.
CheckFilename(char * name)799 int WIMP::CheckFilename(char *name)
800 {
801 bool OK = false;
802 register char *b, *d, c;
803
804 b = d = name; c = *b++;
805 while (c > 32)
806 {
807 // valid path must contain '$' or ':'
808 if ((c == '$') || (c == ':')) {OK = true; d = b;}
809 if (c == '.') {d = b;}
810 c = *b++;
811 }
812 if ((b - d) == 1) {OK = false;} // filename mustn't end with '$', ':' or '.'
813 if (OK) {return(0);}
814
815 WimpError.errnum = 0; sprintf(WimpError.errmess,"Bad filename %s",name);
816 Wimp_ReportError(&WimpError,1,TASKNAME);
817 return(-1);
818 }
819
820
SnapshotSaved(bool OK)821 void WIMP::SnapshotSaved(bool OK)
822 {
823 if (OK)
824 {
825 int *b = (int*)SnapFile;
826
827 if (b[MsgB_Sender] != 0)
828 {
829 b[MsgB_YourRef] = b[MsgB_MyRef]; b[MsgB_Action] = Message_DataLoad;
830 Wimp_SendMessage(18,b,b[MsgB_Sender],b[6]);
831 }
832 else {Wimp_CreateMenu((int*)-1,0,0);}
833 SaveType = 0;
834 }
835 }
836
837
IssueSnapshotRequest(void)838 void WIMP::IssueSnapshotRequest(void)
839 {
840 if (EmuPaused)
841 {
842 EmuPane->WriteIconTextU(Icon_Pane_Pause, PANE_TEXT_PAUSE);
843 EmuPaused = false;
844 }
845 the_c64->RequestSnapshot();
846 }
847
848
849 // Sets the Emu pane's LEDs according to the floppy emulation state
SetLEDIcons(bool FloppyEmulation)850 void WIMP::SetLEDIcons(bool FloppyEmulation)
851 {
852 int i, eor;
853
854 if (FloppyEmulation) {eor = IFlg_Grey;} else {eor = 0;}
855 for (i=1; i<4; i++)
856 {
857 EmuPane->SetIconState(LEDtoIcon[i],eor,IFlg_Grey);
858 }
859 }
860
861
862
863 // Doesn't open window, just resizes...
SetEmuWindowSize(void)864 void WIMP::SetEmuWindowSize(void)
865 {
866 register int i;
867 register C64Display *disp = the_c64->TheDisplay;
868
869 i = (disp->screen->eigx < disp->screen->eigy) ? disp->screen->eigx : disp->screen->eigy;
870 if (EmuZoom == 2) {i++;}
871 EmuWindow->extent(0,-(DISPLAY_Y << i),(DISPLAY_X << i),0);
872 }
873
874
875
876 // switch between zoom 1 and zoom 2
ToggleEmuWindowSize(void)877 void WIMP::ToggleEmuWindowSize(void)
878 {
879 int x,y;
880
881 // Icon in pane shows _alternative_ zoom mode
882 if (EmuZoom == 1)
883 {
884 EmuZoom = 2;
885 EmuPane->WriteIconText(Icon_Pane_Toggle,"1 x");
886 }
887 else
888 {
889 EmuZoom = 1;
890 EmuPane->WriteIconText(Icon_Pane_Toggle,"2 x");
891 }
892 SetEmuWindowSize();
893 EmuWindow->GetWorkArea(AuxBlock);
894 x = AuxBlock[2] - AuxBlock[0]; y = AuxBlock[3] - AuxBlock[1];
895 EmuWindow->getstate(AuxBlock);
896 AuxBlock[WindowB_VMaxX] = AuxBlock[WindowB_VMinX] + x;
897 AuxBlock[WindowB_VMinY] = AuxBlock[WindowB_VMaxY] - y;
898 // Open emu window alone to get the dimensions set by the WIMP
899 Wimp_OpenWindow(AuxBlock);
900 // Then open with the pane at the correct position
901 EmuWindow->getstate(AuxBlock); OpenEmuWindow(AuxBlock); UpdateEmuWindow();
902 }
903
904
905
ReadEmuWindowSize(void)906 int WIMP::ReadEmuWindowSize(void)
907 {
908 return EmuZoom;
909 }
910
911
912
913 // Set a new drive path for drive DrNum. MsgBlock is the DataLoad MessageBlock.
NewDriveImage(int DrNum,int * MsgBlock,bool SetNow)914 void WIMP::NewDriveImage(int DrNum, int *MsgBlock, bool SetNow)
915 {
916 int type, j = -1, map = -1;
917
918 // determine currently selected type
919 do
920 {
921 ++j; PrefsWindow->GetIconState(DriveToIcon[DrNum*IconsPerDrive + j], AuxBlock);
922 }
923 while ((j < 3) && ((AuxBlock[6] & IFlg_Slct) == 0));
924 if (j >= 3) {j = 0;}
925 // Check the type and set the drive type accordingly
926 type = ReadCatalogueInfo(((char*)Block)+44,AuxBlock);
927 // New path is directory but DRVTYPE != DIR ==> set DIR
928 if ((type == 2) && (j != 0)) {map = 0;}
929 // New path is not directory/image but DRVTYPE == DIR ==> remap to D64
930 if (((type & 2) == 0) && (j == 0)) {map = 1;}
931 // Filetype indicated D64 image?
932 if (((type = AuxBlock[0]) & 0xfff00000) == 0xfff00000) // typed file
933 {
934 type = (type >> 8) & 0xfff;
935 // D64 image can also be used in DIR mode (-> D64ImageFS). Only remap from T64!
936 if ((type == FileType_D64File) && (j == 2)) {map = 1;}
937 }
938 // Do we need to remap?
939 if (map >= 0)
940 {
941 PrefsWindow->SetIconState(DriveToIcon[DrNum*IconsPerDrive+j],0,IFlg_Slct);
942 PrefsWindow->SetIconState(DriveToIcon[DrNum*IconsPerDrive+map],IFlg_Slct,IFlg_Slct);
943 j = map;
944 }
945 // j is the number of the emulation mode (DIR (0), D64 (1), T64 (2))
946 PrefsWindow->WriteIconText(DriveToIcon[DrNum*IconsPerDrive+3],((char*)Block)+44);
947 // Send acknowledge message
948 Block[MsgB_YourRef] = Block[MsgB_MyRef]; Block[MsgB_Action] = Message_DataLoadAck;
949 Wimp_SendMessage(17,Block,Block[MsgB_Sender],Block[6]);
950
951 // Set this drive path immediately?
952 if (SetNow)
953 {
954 Prefs *prefs = new Prefs(ThePrefs);
955
956 prefs->DriveType[DrNum] = j; strcpy(prefs->DrivePath[DrNum],((char*)Block)+44);
957 the_c64->NewPrefs(prefs);
958 ThePrefs = *prefs;
959 delete prefs;
960 }
961 }
962
963
964
SetSpeedLimiter(bool LimitSpeed)965 void WIMP::SetSpeedLimiter(bool LimitSpeed)
966 {
967 RO_Icon *roi;
968 char *b, c;
969
970 PrefsWindow->SetIconState(Icon_Prefs_LimSpeed,(LimitSpeed) ? IFlg_Slct : 0, IFlg_Slct);
971 roi = EmuPane->GetIcon(Icon_Pane_Speed);
972 if ((b = (char*)roi->dat.ind.val) != NULL)
973 {
974 do
975 {
976 c = *b++;
977 if ((c == 'r') || (c == 'R')) // boRder command?
978 {
979 if (LimitSpeed) {*b++ = '1';} else {*b++ = '2';}
980 c = 0; // stop now
981 }
982 else if (c >= 32) // skip to next command
983 {
984 c = *b++;
985 while ((c >= 32) && (c != ';')) {if (c == '\\') {b++;} c = *b++;}
986 }
987 }
988 while (c >= 32);
989 EmuPane->UpdateIcon(Icon_Pane_Speed);
990 }
991 }
992
993
994
995
996
Poll(bool Paused)997 void WIMP::Poll(bool Paused)
998 {
999 int event;
1000 bool LastPause;
1001
1002 LastPause = EmuPaused; EmuPaused = Paused;
1003
1004 // If emulator is paused disable null events
1005 if ((!EmuPaused) || (UseNULL > 0)) {Mask &= 0xfffffffe;} else {Mask |= 1;}
1006
1007 do
1008 {
1009 // Loop until a null event is received, then continue the emulation.
1010 // (this looks best)
1011 do
1012 {
1013 event = Wimp_Poll(Mask,Block,NULL);
1014 switch (event)
1015 {
1016 case 1: Redraw(); break;
1017 case 2: OpenWindow(); break;
1018 case 3: CloseWindow(); break;
1019 case 6: MouseClick(); break;
1020 case 7: UserDrag(); break;
1021 case 8: if ((EmuPaused) && (Block[KeyPB_Window] == EmuWindow->MyHandle()))
1022 {
1023 if (the_c64->TheDisplay->CheckForUnpause(!LastPause)) {EmuPaused = false;}
1024 }
1025 KeyPressed(); break;
1026 case 9: MenuSelection(); break;
1027 case 17:
1028 case 18: UserMessage(); break;
1029 case 19: UserMessageAck(); break;
1030 default: break;
1031 }
1032 // This is important
1033 if ((!EmuPaused) || (UseNULL > 0)) {Mask &= 0xfffffffe;} else {Mask |= 1;}
1034 LastPause = EmuPaused;
1035 }
1036 while (event != 0);
1037 if (UseNULL > 0) {PollSysConfWindow();}
1038 // This should probably become a new member-function one day...
1039 if (DragType == DRAG_VolumeWell)
1040 {
1041 Wimp_GetPointerInfo(Block);
1042 if (Block[MouseB_Icon] == Icon_Sound_Volume) // should always be the case (BBox)!
1043 {
1044 the_c64->HostVolume = CalculateVolume(Block);
1045 SoundWindow->ForceIconRedraw(Icon_Sound_Volume);
1046 }
1047 }
1048 }
1049 while (EmuPaused);
1050 }
1051
1052
Redraw(void)1053 void WIMP::Redraw(void)
1054 {
1055 if (Block[RedrawB_Handle] == EmuWindow->MyHandle()) // emulator main window
1056 {
1057 C64Display *disp = the_c64->TheDisplay;
1058
1059 EmuWindow->redraw(Block,disp->BitmapBase(),disp);
1060 }
1061 else if (Block[RedrawB_Handle] == SoundWindow->MyHandle()) // sound window
1062 {
1063 int more;
1064 int minx, miny, maxx, maxy, thresh;
1065
1066 more = Wimp_RedrawWindow(Block);
1067 // compute screen coordinates of work (0,0)
1068 minx = Block[RedrawB_VMinX] - Block[RedrawB_ScrollX];
1069 maxy = Block[RedrawB_VMaxY] - Block[RedrawB_ScrollY];
1070 // get volume well bounding box
1071 SoundWindow->GetIconState(Icon_Sound_Volume, AuxBlock);
1072 maxx = minx + AuxBlock[IconB_MaxX] - WellBorder; minx += AuxBlock[IconB_MinX] + WellBorder;
1073 miny = maxy + AuxBlock[IconB_MinY] + WellBorder; maxy += AuxBlock[IconB_MaxY] - WellBorder;
1074 thresh = minx + (the_c64->HostVolume * (maxx - minx))/ MaximumVolume;
1075 while (more != 0)
1076 {
1077 // clip
1078 if ((minx <= Block[RedrawB_CMaxX]) && (maxx >= Block[RedrawB_CMinX]) &&
1079 (miny <= Block[RedrawB_CMaxY]) && (maxy >= Block[RedrawB_CMinY]))
1080 {
1081 if (Block[RedrawB_CMinX] < thresh)
1082 {
1083 ColourTrans_SetGCOL(0x00ff0000,0,0); // green
1084 OS_Plot(0x04,minx,miny); OS_Plot(0x65,thresh,maxy);
1085 }
1086 if (Block[RedrawB_CMaxX] > thresh)
1087 {
1088 ColourTrans_SetGCOL(0xffffff00,0,0); // white
1089 OS_Plot(0x04,thresh,miny); OS_Plot(0x65,maxx,maxy);
1090 }
1091 }
1092 more = Wimp_GetRectangle(Block);
1093 }
1094 }
1095 else // Dummy redraw loop
1096 {
1097 int more;
1098
1099 more = Wimp_RedrawWindow(Block);
1100 while (more != 0)
1101 {
1102 more = Wimp_GetRectangle(Block);
1103 }
1104 }
1105 }
1106
1107
OpenWindow(void)1108 void WIMP::OpenWindow(void)
1109 {
1110 if (Block[WindowB_Handle] == EmuWindow->MyHandle()) {OpenEmuWindow(Block);}
1111 else if (Block[WindowB_Handle] != EmuPane->MyHandle())
1112 {
1113 Wimp_OpenWindow(Block);
1114 }
1115 }
1116
1117
CloseWindow(void)1118 void WIMP::CloseWindow(void)
1119 {
1120 if (Block[WindowB_Handle] == EmuWindow->MyHandle()) {CloseEmuWindow();}
1121 else if (Block[WindowB_Handle] != EmuPane->MyHandle())
1122 {
1123 if (Block[WindowB_Handle] == ConfigWindow->MyHandle()) {UseNULL--;}
1124 Wimp_CloseWindow(Block);
1125 }
1126 }
1127
1128
MouseClick(void)1129 void WIMP::MouseClick(void)
1130 {
1131 if ((Block[MouseB_Window] == -2) && (Block[MouseB_Icon] == IBicon->IHandle)) // Icon Bar icon
1132 {
1133 if (Block[MouseB_Buttons] == 2) // Menu
1134 {
1135 Wimp_CreateMenu((int*)&MenuIconBar,Block[MouseB_PosX]-MenuIconBar.head.width/2,96+Menu_Height*Menu_IBar_Items);
1136 LastMenu = Menu_IBar;
1137 }
1138 else // Some other click
1139 {
1140 if (!EmuWindow->OpenStatus(Block)) {Block[WindowB_Stackpos] = -1; OpenEmuWindow(Block);}
1141 }
1142 }
1143 else if (Block[MouseB_Window] == EmuWindow->MyHandle()) // Emulator window
1144 {
1145 if (Block[MouseB_Buttons] >= 256) // click
1146 {
1147 Wimp_GetCaretPosition(&LastCaret);
1148 Wimp_SetCaretPosition(Block[MouseB_Window],-1,-100,100,-1,-1); // gain input focus
1149 }
1150 if (Block[MouseB_Buttons] == 2) // menu
1151 {
1152 Wimp_CreateMenu((int*)&MenuEmuWindow,Block[MouseB_PosX]-MenuEmuWindow.head.width/2,Block[MouseB_PosY]);
1153 LastMenu = Menu_Emulator;
1154 }
1155 }
1156 else if (Block[MouseB_Window] == EmuPane->MyHandle()) // Emulator pane
1157 {
1158 if ((Block[MouseB_Buttons] == 1) || (Block[MouseB_Buttons] == 4))
1159 {
1160 switch (Block[MouseB_Icon])
1161 {
1162 case Icon_Pane_Pause: // Pause icon
1163 if (EmuPaused)
1164 {
1165 EmuPane->WriteIconText(Icon_Pane_Pause,PANE_TEXT_PAUSE);
1166 the_c64->Resume(); EmuPaused = false;
1167 }
1168 else
1169 {
1170 EmuPane->WriteIconText(Icon_Pane_Pause,PANE_TEXT_RESUME);
1171 the_c64->Pause(); EmuPaused = true;
1172 // Update the window now!
1173 UpdateEmuWindow();
1174 }
1175 break;
1176 case Icon_Pane_Reset: the_c64->Reset(); break;
1177 case Icon_Pane_Toggle: ToggleEmuWindowSize(); break;
1178 case Icon_Pane_Speed:
1179 ThePrefs.LimitSpeed = !ThePrefs.LimitSpeed; SetSpeedLimiter(ThePrefs.LimitSpeed);
1180 break;
1181 default: break;
1182 }
1183 }
1184 }
1185 else if (Block[MouseB_Window] == PrefsWindow->MyHandle()) // Prefs window
1186 {
1187 if ((Block[MouseB_Buttons] == 1) || (Block[MouseB_Buttons] == 4)) // normal click
1188 {
1189 register int i;
1190
1191 switch(Block[MouseB_Icon])
1192 {
1193 case Icon_Prefs_SkipFLeft:
1194 i = PrefsWindow->ReadIconNumber(Icon_Prefs_SkipFText);
1195 if (i > 0)
1196 {
1197 PrefsWindow->WriteIconNumber(Icon_Prefs_SkipFText,--i);
1198 ThePrefs.SkipFrames = i; // instant update
1199 }
1200 break;
1201 case Icon_Prefs_SkipFRight:
1202 i = PrefsWindow->ReadIconNumber(Icon_Prefs_SkipFText);
1203 PrefsWindow->WriteIconNumber(Icon_Prefs_SkipFText,++i);
1204 ThePrefs.SkipFrames = i; // instant update
1205 break;
1206 case Icon_Prefs_Cancel: ThePrefsToWindow(); break; // restore current settings
1207 case Icon_Prefs_OK: WindowToThePrefs();
1208 if (Block[MouseB_Buttons] == 4) {PrefsWindow->close();}
1209 break; // use new prefs
1210 case Icon_Prefs_Save:
1211 WindowToThePrefs();
1212 if (CheckFilename(PrefsWindow->ReadIconText(Icon_Prefs_PrefPath)) == 0)
1213 {
1214 ThePrefs.Save(PrefsWindow->ReadIconText(Icon_Prefs_PrefPath));
1215 }
1216 break;
1217 default: break;
1218 }
1219 }
1220 else if ((Block[MouseB_Buttons] == 16) || (Block[MouseB_Buttons] == 64))
1221 // drag (only the sprite)
1222 {
1223 if (Block[MouseB_Icon] == Icon_Prefs_PrefSprite)
1224 {
1225 DragIconSprite(PrefsWindow, Icon_Prefs_PrefSprite);
1226 DragType = DRAG_PrefsSprite;
1227 }
1228 }
1229 }
1230 else if (Block[MouseB_Window] == ConfigWindow->MyHandle()) // sys config window
1231 {
1232 if ((Block[MouseB_Buttons] == 1) || (Block[MouseB_Buttons] == 4))
1233 {
1234 if (Block[MouseB_Icon] == Icon_Conf_OK)
1235 {
1236 WindowToSysConf(); UseNULL--;
1237 if (Block[MouseB_Buttons] == 4) {ConfigWindow->close();}
1238 }
1239 else if (Block[MouseB_Icon] == Icon_Conf_Save)
1240 {
1241 if (CheckFilename(ConfigWindow->ReadIconText(Icon_Conf_ConfPath)) == 0)
1242 {
1243 WindowToSysConf(); UseNULL--; ConfigWindow->close();
1244 the_c64->SaveSystemConfig(ConfigWindow->ReadIconText(Icon_Conf_ConfPath));
1245 }
1246 }
1247 }
1248 else if ((Block[MouseB_Buttons] == 16) || (Block[MouseB_Buttons] == 64))
1249 {
1250 if (Block[MouseB_Icon] == Icon_Conf_ConfSprite)
1251 {
1252 DragIconSprite(ConfigWindow, Icon_Conf_ConfSprite);
1253 DragType = DRAG_ConfSprite;
1254 }
1255 }
1256 }
1257 else if (Block[MouseB_Window] == SoundWindow->MyHandle()) // sound window
1258 {
1259 if (Block[MouseB_Icon] == Icon_Sound_Volume)
1260 {
1261 if ((Block[MouseB_Buttons] == 1) || (Block[MouseB_Buttons] == 4)) // click
1262 {
1263 the_c64->HostVolume = CalculateVolume(Block); Sound_Volume(the_c64->HostVolume);
1264 SoundWindow->ForceIconRedraw(Icon_Sound_Volume);
1265 }
1266 else if ((Block[MouseB_Buttons] == 16) || (Block[MouseB_Buttons] == 64)) // drag
1267 {
1268 int orgx, orgy;
1269
1270 SoundWindow->getstate(AuxBlock);
1271 orgx = AuxBlock[WindowB_VMinX] - AuxBlock[WindowB_ScrollX];
1272 orgy = AuxBlock[WindowB_VMaxY] - AuxBlock[WindowB_ScrollY];
1273 SoundWindow->GetIconState(Icon_Sound_Volume, &AuxBlock[DragB_BBMinX - IconB_MinX]);
1274 AuxBlock[DragB_BBMinX] += orgx; AuxBlock[DragB_BBMinY] += orgy;
1275 AuxBlock[DragB_BBMaxX] += orgx; AuxBlock[DragB_BBMaxY] += orgy;
1276 AuxBlock[DragB_Type] = 7;
1277 Wimp_DragBox(AuxBlock);
1278 DragType = DRAG_VolumeWell; UseNULL++;
1279 }
1280 }
1281 }
1282 else if (Block[MouseB_Window] == SaveBox->MyHandle())
1283 {
1284 if ((Block[MouseB_Buttons] == 1) || (Block[MouseB_Buttons] == 4))
1285 {
1286 if (Block[MouseB_Icon] == Icon_Save_OK)
1287 {
1288 if (CheckFilename(SaveBox->ReadIconText(Icon_Save_Path)) == 0)
1289 {
1290 if (SaveType == SAVE_RAM)
1291 {
1292 strcpy(RAMFile+44,SaveBox->ReadIconText(Icon_Save_Path));
1293 the_c64->SaveRAM(RAMFile+44);
1294 Wimp_CreateMenu((int*)-1,0,0);
1295 SaveType = 0;
1296 }
1297 else if (SaveType == SAVE_Snapshot)
1298 {
1299 *(((int*)SnapFile) + MsgB_Sender) = 0;
1300 strcpy(SnapFile+44,SaveBox->ReadIconText(Icon_Save_Path));
1301 IssueSnapshotRequest();
1302 }
1303 }
1304 }
1305 }
1306 else if ((Block[MouseB_Buttons] == 16) || (Block[MouseB_Buttons] == 64))
1307 {
1308 if (Block[MouseB_Icon] == Icon_Save_Sprite)
1309 {
1310 DragIconSprite(SaveBox, Icon_Save_Sprite);
1311 DragType = DRAG_SaveSprite;
1312 }
1313 }
1314 }
1315 }
1316
1317
1318 // A drag operation has terminated
UserDrag(void)1319 void WIMP::UserDrag(void)
1320 {
1321 char *b = NULL;
1322 int filetype, size;
1323
1324 if ((CMOS_DragType == 0) || (DragType == DRAG_VolumeWell))
1325 {
1326 Wimp_DragBox(NULL);
1327 }
1328 else
1329 {
1330 DragASprite_Stop();
1331 }
1332
1333 if (DragType == DRAG_VolumeWell)
1334 {
1335 UseNULL--; DragType = 0; Sound_Volume(the_c64->HostVolume); // just set the new volume.
1336 }
1337
1338 // Drag of the path sprite
1339 if (DragType == DRAG_PrefsSprite)
1340 {
1341 b = PrefsWindow->ReadIconText(Icon_Prefs_PrefPath); filetype = FileType_Text;
1342 size = EstimatedPrefsSize; // can't say how large it's gonna be
1343 }
1344 else if (DragType == DRAG_ConfSprite)
1345 {
1346 b = ConfigWindow->ReadIconText(Icon_Conf_ConfPath); filetype = FileType_Text;
1347 size = EstimatedConfSize;
1348 }
1349 else if (DragType == DRAG_SaveSprite)
1350 {
1351 b = SaveBox->ReadIconText(Icon_Save_Path); filetype = FileType_Data;
1352 if (SaveType == SAVE_RAM) {size = EstimatedRAMSize;}
1353 else if (SaveType == SAVE_Snapshot) {size = EstimatedSnapSize;}
1354 else {size = 0;}
1355 }
1356
1357 // now b should point to the path and filetype should contain the type
1358 if (b != NULL)
1359 {
1360 Wimp_GetPointerInfo(Block);
1361 // Not on background and not on my own icon bar icon
1362 if ((Block[MouseB_Window] != -1) && ((Block[MouseB_Window] != -2) || (Block[MouseB_Icon] != IBicon->IHandle)))
1363 {
1364 int handle = Block[MouseB_Window];
1365
1366 // None of my windows
1367 if ((handle != EmuWindow->MyHandle()) && (handle != EmuPane->MyHandle()) &&
1368 (handle != PrefsWindow->MyHandle()) && (handle != ConfigWindow->MyHandle()) &&
1369 (handle != InfoWindow->MyHandle()) && (handle != SaveBox->MyHandle()))
1370 {
1371 char *d, c;
1372
1373 d = b; c = *b++;
1374 // get pointer to leafname in d
1375 while (c > 32) {if ((c == '.') || (c == ':')) {d = b;} c = *b++;}
1376 // Build message block
1377 Block[5] = Block[MouseB_Window]; Block[6] = Block[MouseB_Icon];
1378 Block[7] = Block[MouseB_PosX]; Block[8] = Block[MouseB_PosY];
1379 Block[9] = size; Block[10] = filetype;
1380 Block[MsgB_YourRef] = 0; Block[MsgB_Action] = Message_DataSave;
1381 b = ((char*)Block) + 44; c = *d++;
1382 while (c > 32) {*b++ = c; c = *d++;}
1383 *b++ = 0; Block[MsgB_Size] = (((int)(b - (char*)Block)) + 3) & 0xfffffffc;
1384 Wimp_SendMessage(18,Block,Block[5],Block[6]);
1385 }
1386 }
1387 }
1388 else {DragType = 0;}
1389 LastDrag = 0;
1390 }
1391
1392
KeyPressed(void)1393 void WIMP::KeyPressed(void)
1394 {
1395 register int key = Block[KeyPB_Key];
1396
1397 if (Block[KeyPB_Window] == EmuWindow->MyHandle())
1398 {
1399 if ((key >= 0x180) && (key <= 0x1fd)) // special keys (incl. FKeys)
1400 {
1401 key -= 0x180;
1402 if ((((key & 0x4f) >= 0x05) && ((key & 0x4f) <= 0x09)) || // F5 -F9 [shift|ctrl]
1403 (((key & 0x4f) >= 0x4a) && ((key & 0x4f) <= 0x4c))) // F10-F12 [shift|ctrl]
1404 {
1405 if ((key != 0x06) && (key != 0x07) && (key != 0x08))
1406 {
1407 Wimp_ProcessKey(Block[KeyPB_Key]);
1408 }
1409 }
1410 }
1411 return;
1412 }
1413 else if (Block[KeyPB_Window] == PrefsWindow->MyHandle())
1414 {
1415 if (key == Key_Return)
1416 {
1417 WindowToThePrefs();
1418 if (Block[KeyPB_Icon] == Icon_Prefs_PrefPath) // return pressed in path string icon?
1419 {
1420 if (CheckFilename(PrefsWindow->ReadIconText(Icon_Prefs_PrefPath)) == 0)
1421 {
1422 ThePrefs.Save(PrefsWindow->ReadIconText(Icon_Prefs_PrefPath));
1423 }
1424 }
1425 return;
1426 }
1427 }
1428 else if (Block[KeyPB_Window] == ConfigWindow->MyHandle())
1429 {
1430 if ((key == Key_Return) && (Block[KeyPB_Icon] != -1))
1431 {
1432 WindowToSysConf(); UseNULL--; ConfigWindow->close();
1433 if (Block[KeyPB_Icon] == Icon_Conf_ConfPath) // return pressed in path string icon?
1434 {
1435 if (CheckFilename(ConfigWindow->ReadIconText(Icon_Conf_ConfPath)) == 0)
1436 {
1437 the_c64->SaveSystemConfig(ConfigWindow->ReadIconText(Icon_Conf_ConfPath));
1438 }
1439 }
1440 return;
1441 }
1442 }
1443 else if (Block[KeyPB_Window] == SaveBox->MyHandle())
1444 {
1445 if (key == Key_Return)
1446 {
1447 if (Block[KeyPB_Icon] == Icon_Save_Path)
1448 {
1449 if (CheckFilename(SaveBox->ReadIconText(Icon_Save_Path)) == 0)
1450 {
1451 if (SaveType == SAVE_RAM)
1452 {
1453 strcpy(RAMFile+44,SaveBox->ReadIconText(Icon_Save_Path));
1454 the_c64->SaveRAM(RAMFile+44);
1455 Wimp_CreateMenu((int*)-1,0,0);
1456 SaveType = 0;
1457 }
1458 else if (SaveType == SAVE_Snapshot)
1459 {
1460 *(((int*)SnapFile) + MsgB_Sender) = 0;
1461 strcpy(SnapFile+44,SaveBox->ReadIconText(Icon_Save_Path));
1462 IssueSnapshotRequest();
1463 }
1464 }
1465 }
1466 return;
1467 }
1468 }
1469 Wimp_ProcessKey(Block[KeyPB_Key]);
1470 }
1471
1472
MenuSelection(void)1473 void WIMP::MenuSelection(void)
1474 {
1475 int Buttons;
1476
1477 Wimp_GetPointerInfo(AuxBlock); Buttons = AuxBlock[MouseB_Buttons];
1478
1479 switch (LastMenu)
1480 {
1481 case Menu_IBar:
1482 if (Block[0] == Menu_IBar_Quit) {EmuPaused = false; the_c64->Quit();}
1483 else if (Block[0] == Menu_IBar_Prefs)
1484 {
1485 // Is it already open? Then don't do anything
1486 if (!PrefsWindow->OpenStatus())
1487 {
1488 int y;
1489
1490 // Open Prefs window with top left corner in top left corner of screen
1491 PrefsWindow->getstate(AuxBlock);
1492 y = the_c64->TheDisplay->screen->resy;
1493 AuxBlock[WindowB_VMaxX] -= AuxBlock[WindowB_VMinX]; AuxBlock[WindowB_VMinX] = 0;
1494 AuxBlock[WindowB_VMinY] = y - (AuxBlock[WindowB_VMaxY] - AuxBlock[WindowB_VMinY]);
1495 AuxBlock[WindowB_VMaxY] = y;
1496 // Open Prefs window on top
1497 AuxBlock[WindowB_Stackpos] = -1;
1498 PrefsWindow->open(AuxBlock);
1499 }
1500 else
1501 {
1502 PrefsWindow->getstate(AuxBlock);
1503 AuxBlock[WindowB_Stackpos] = -1; PrefsWindow->open(AuxBlock);
1504 }
1505 }
1506 else if (Block[0] == Menu_IBar_Config)
1507 {
1508 if (!ConfigWindow->OpenStatus())
1509 {
1510 int x, y;
1511
1512 // Update window contents
1513 SysConfToWindow();
1514 // Open config window in top right corner of screen
1515 ConfigWindow->getstate(AuxBlock);
1516 x = the_c64->TheDisplay->screen->resx; y = the_c64->TheDisplay->screen->resy;
1517 AuxBlock[WindowB_VMinX] = x - (AuxBlock[WindowB_VMaxX] - AuxBlock[WindowB_VMinX]);
1518 AuxBlock[WindowB_VMaxX] = x;
1519 AuxBlock[WindowB_VMinY] = y - (AuxBlock[WindowB_VMaxY] - AuxBlock[WindowB_VMinY]);
1520 AuxBlock[WindowB_VMaxY] = y;
1521 AuxBlock[WindowB_Stackpos] = -1;
1522 ConfigWindow->open(AuxBlock);
1523 // We need NULL-events for the low-level keyboard scan.
1524 UseNULL++;
1525 }
1526 else
1527 {
1528 ConfigWindow->getstate(AuxBlock);
1529 AuxBlock[WindowB_Stackpos] = -1; ConfigWindow->open(AuxBlock);
1530 }
1531 }
1532 if (Buttons == 1) {Wimp_CreateMenu((int*)&MenuIconBar,0,0);}
1533 break;
1534 case Menu_Emulator:
1535 if (Buttons == 1) {Wimp_CreateMenu((int*)&MenuEmuWindow,0,0);}
1536 break;
1537 default: break;
1538 }
1539 }
1540
1541
1542 // Handle regular messages
UserMessage(void)1543 void WIMP::UserMessage(void)
1544 {
1545 C64Display *disp = the_c64->TheDisplay;
1546 int i;
1547
1548 switch (Block[MsgB_Action]) // Message Action
1549 {
1550 case Message_Quit:
1551 EmuPaused = false; the_c64->Quit(); break;
1552 case Message_ModeChange:
1553 disp->ModeChange(); the_c64->TheVIC->ReInitColors(); SetEmuWindowSize();
1554 // The window could have changed position ==> reposition pane as well!
1555 // we have to force the window to the screen manually
1556 EmuWindow->getstate(AuxBlock);
1557 if ((AuxBlock[WindowB_WFlags] & (1<<16)) != 0) // is it open anyway?
1558 {
1559 i = AuxBlock[WindowB_VMaxY] - AuxBlock[WindowB_VMinY];
1560 if (AuxBlock[WindowB_VMaxY] > disp->screen->resy - TitleBarHeight)
1561 {
1562 AuxBlock[WindowB_VMaxY] = disp->screen->resy - TitleBarHeight;
1563 if ((AuxBlock[WindowB_VMinY] = AuxBlock[WindowB_VMaxY] - i) < TitleBarHeight)
1564 {
1565 AuxBlock[WindowB_VMinY] = TitleBarHeight;
1566 }
1567 }
1568 i = AuxBlock[WindowB_VMaxX] - AuxBlock[WindowB_VMinX];
1569 if (AuxBlock[WindowB_VMaxX] > disp->screen->resx - TitleBarHeight)
1570 {
1571 AuxBlock[WindowB_VMaxX] = disp->screen->resx - TitleBarHeight;
1572 if ((AuxBlock[WindowB_VMinX] = AuxBlock[WindowB_VMaxX] - i) < 0)
1573 {
1574 AuxBlock[WindowB_VMinX] = 0;
1575 }
1576 }
1577 // Don't you just love it -- you can't open the window directly, you need
1578 // a delay... like for instance by sending yourself an OpenWindow message...
1579 Wimp_SendMessage(2,AuxBlock,TaskHandle,0);
1580 }
1581 break;
1582 case Message_PaletteChange:
1583 // Updating EmuWindow is pointless since the bitmap still contains data for another mode
1584 disp->ModeChange(); the_c64->TheVIC->ReInitColors();
1585 break;
1586 case Message_DataSave:
1587 i = -1; // indicator whether file is accepted
1588 if ((Block[5] == EmuWindow->MyHandle()) && (Block[10] == FileType_C64File)) {i=0;}
1589 else if ((Block[5] == EmuWindow->MyHandle()) && (Block[10] == FileType_Data)) {i=0;}
1590 else if ((Block[5] == PrefsWindow->MyHandle()) && (Block[10] == FileType_Text)) {i=0;}
1591 else if ((Block[5] == ConfigWindow->MyHandle()) && (Block[10] == FileType_Text)) {i=0;}
1592 if (i >= 0)
1593 {
1594 Block[9] = -1; // file unsafe
1595 strcpy(((char*)Block)+44,WIMP_SCRAP_FILE);
1596 Block[MsgB_Size] = (48 + strlen(WIMP_SCRAP_FILE)) & 0xfffffffc;
1597 Block[MsgB_YourRef] = Block[MsgB_MyRef]; Block[MsgB_Action] = Message_DataSaveAck;
1598 Wimp_SendMessage(17,Block,Block[MsgB_Sender],Block[6]);
1599 UseScrap = true;
1600 }
1601 break;
1602 case Message_DataLoad:
1603 if (Block[5] == EmuWindow->MyHandle()) // Emulator window: load file?
1604 {
1605 if (Block[10] == FileType_C64File) // Load only files with type &64 this way
1606 {
1607 FILE *fp;
1608
1609 if ((fp = fopen(((char*)Block)+44,"rb")) != NULL)
1610 {
1611 uint8 lo, hi, *mem = the_c64->RAM;
1612 int length;
1613
1614 lo = fgetc(fp); hi = fgetc(fp); length = lo + (hi<<8);
1615 length += fread(mem+length,1,0x10000-length,fp);
1616 // length is now end-address
1617 fclose(fp);
1618 mem[0xc3] = lo; mem[0xc4] = hi; // Load-address
1619 lo = length & 0xff; hi = (length >> 8) & 0xff;
1620 mem[0xae] = mem[0x2d] = mem[0x2f] = mem[0x31] = mem[0x33] = lo;
1621 mem[0xaf] = mem[0x2e] = mem[0x30] = mem[0x32] = mem[0x34] = hi;
1622 Block[MsgB_YourRef] = Block[MsgB_MyRef]; Block[MsgB_Action] = Message_DataLoadAck;
1623 Wimp_SendMessage(17,Block,Block[MsgB_Sender],Block[6]);
1624 }
1625 }
1626 else if (Block[10] == FileType_Data)
1627 {
1628 if (the_c64->LoadSnapshot(((char*)Block)+44))
1629 {
1630 Block[MsgB_YourRef] = Block[MsgB_MyRef]; Block[MsgB_Action] = Message_DataLoadAck;
1631 Wimp_SendMessage(17,Block,Block[MsgB_Sender],Block[6]);
1632 }
1633 }
1634 }
1635 else if (Block[5] == PrefsWindow->MyHandle()) // Prefs window?
1636 {
1637 if (Block[10] == FileType_Text) // load a prefs file?
1638 {
1639 Prefs *prefs = new Prefs(ThePrefs);
1640
1641 prefs->Load(((char*)Block)+44);
1642 the_c64->NewPrefs(prefs);
1643 ThePrefs = *prefs;
1644 delete prefs;
1645 PrefsWindow->WriteIconText(Icon_Prefs_PrefPath,((char*)Block)+44);
1646 ThePrefsToWindow();
1647 Block[MsgB_YourRef] = Block[MsgB_MyRef]; Block[MsgB_Action] = Message_DataLoadAck;
1648 Wimp_SendMessage(17,Block,Block[MsgB_Sender],Block[6]);
1649 }
1650 else // interpret as drive path (if dragged on one of the drive path icons)
1651 {
1652 switch (Block[6])
1653 {
1654 case Icon_Prefs_Dr8Path: i = 0; break;
1655 case Icon_Prefs_Dr9Path: i = 1; break;
1656 case Icon_Prefs_Dr10Path: i = 2; break;
1657 case Icon_Prefs_Dr11Path: i = 3; break;
1658 default: -1; break;
1659 }
1660 if (i >= 0) {NewDriveImage(i,Block,false);}
1661 }
1662 }
1663 else if (Block[5] == ConfigWindow->MyHandle()) // load sys config file
1664 {
1665 if (Block[10] == FileType_Text)
1666 {
1667 the_c64->LoadSystemConfig(((char*)Block)+44);
1668 SysConfToWindow();
1669 ConfigWindow->WriteIconText(Icon_Conf_ConfPath,((char*)Block)+44);
1670 Block[MsgB_YourRef] = Block[MsgB_MyRef]; Block[MsgB_Action] = Message_DataLoadAck;
1671 Wimp_SendMessage(17,Block,Block[MsgB_Sender],Block[6]);
1672 }
1673 }
1674 else if (Block[5] == EmuPane->MyHandle()) // emulator pane
1675 {
1676 switch (Block[6])
1677 {
1678 case Icon_Pane_Drive0:
1679 case Icon_Pane_LED0: i = 0; break;
1680 case Icon_Pane_Drive1:
1681 case Icon_Pane_LED1: i = 1; break;
1682 case Icon_Pane_Drive2:
1683 case Icon_Pane_LED2: i = 2; break;
1684 case Icon_Pane_Drive3:
1685 case Icon_Pane_LED3: i = 3; break;
1686 default: i = -1; break;
1687 }
1688 if (i >= 0) {NewDriveImage(i,Block,true);}
1689 }
1690 // Clean up if necessary
1691 if (UseScrap) {DeleteFile(WIMP_SCRAP_FILE); UseScrap = false;}
1692 break;
1693 case Message_DataSaveAck:
1694 if (DragType == DRAG_PrefsSprite)
1695 {
1696 WindowToThePrefs(); // read window entries
1697 ThePrefs.Save(((char*)Block)+44);
1698 if (Block[9] != -1) // we're talking to the filer ==> set new pathname
1699 {
1700 PrefsWindow->WriteIconText(Icon_Prefs_PrefPath,((char*)Block)+44);
1701 }
1702 Block[MsgB_YourRef] = Block[MsgB_MyRef]; Block[MsgB_Action] = Message_DataLoad;
1703 Wimp_SendMessage(18,Block,Block[MsgB_Sender],Block[6]);
1704 }
1705 else if (DragType == DRAG_ConfSprite)
1706 {
1707 WindowToSysConf(); // read window entries
1708 the_c64->SaveSystemConfig(((char*)Block)+44);
1709 if (Block[9] != -1)
1710 {
1711 ConfigWindow->WriteIconText(Icon_Conf_ConfPath,((char*)Block)+44);
1712 }
1713 Block[MsgB_YourRef] = Block[MsgB_MyRef]; Block[MsgB_Action] = Message_DataLoad;
1714 Wimp_SendMessage(18,Block,Block[MsgB_Sender],Block[6]);
1715 }
1716 else if (DragType == DRAG_SaveSprite)
1717 {
1718 if (SaveType == SAVE_RAM)
1719 {
1720 memcpy(RAMFile,(char*)Block,256); the_c64->SaveRAM(RAMFile+44);
1721 Block[MsgB_YourRef] = Block[MsgB_MyRef]; Block[MsgB_Action] = Message_DataLoad;
1722 Wimp_SendMessage(18,Block,Block[MsgB_Sender],Block[6]);
1723 }
1724 else if (SaveType == SAVE_Snapshot)
1725 {
1726 memcpy(SnapFile,(char*)Block,256);
1727 IssueSnapshotRequest();
1728 }
1729 }
1730 break;
1731 case Message_DataLoadAck:
1732 if (DragType == DRAG_ConfSprite)
1733 {
1734 UseNULL--; ConfigWindow->close();
1735 }
1736 if (DragType == DRAG_SaveSprite)
1737 {
1738 Wimp_CreateMenu((int*)-1,0,0);
1739 }
1740 DragType = SaveType = 0; break;
1741 case Message_MenuWarning:
1742 if (LastMenu == Menu_Emulator)
1743 {
1744 if (Block[8] == Menu_EWind_SaveRAM)
1745 {
1746 SaveType = SAVE_RAM; SaveBox->WriteIconText(Icon_Save_Path,RAMFile+44);
1747 }
1748 else if (Block[8] == Menu_EWind_Snapshot)
1749 {
1750 SaveType = SAVE_Snapshot; SaveBox->WriteIconText(Icon_Save_Path,SnapFile+44);
1751 }
1752 else {SaveType = 0;}
1753 Wimp_CreateSubMenu((int*)Block[5],Block[6],Block[7]);
1754 }
1755 break;
1756 default: break;
1757 }
1758 }
1759
1760
1761 // If a recorded message was not answered, i.e. something went wrong.
UserMessageAck(void)1762 void WIMP::UserMessageAck(void)
1763 {
1764 switch(Block[MsgB_Action])
1765 {
1766 case Message_DataSave:
1767 sprintf(WimpError.errmess,"Can't save data."); break;
1768 case Message_DataLoad:
1769 sprintf(WimpError.errmess,"Receiver couldn't load data."); break;
1770 default:
1771 sprintf(WimpError.errmess,"Some error occurred..."); break;
1772 }
1773 WimpError.errnum = 0; Wimp_ReportError(&WimpError,1,TASKNAME);
1774 }
1775