ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/AcornGUI.cc
Revision: 1.5
Committed: 2005-06-27T19:55:48Z (18 years, 9 months ago) by cebix
Branch: MAIN
CVS Tags: VERSION_4_2, HEAD
Changes since 1.4: +1 -1 lines
Log Message:
updated copyright dates

File Contents

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