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, 10 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

# User Rev Content
1 cebix 1.1 /*
2     * AcornGUI.cc - Frodo's Graphical User Interface for Acorn RISC OS machines
3     *
4     * (C) 1997 Andreas Dehmel
5     *
6 cebix 1.5 * Frodo (C) 1994-1997,2002-2005 Christian Bauer
7 cebix 1.1 *
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 cebix 1.3
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 cebix 1.1 }
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 cebix 1.3 #ifdef SUPPORT_XROM
617     // XROM
618     pread_opt(XPandROMOn,XROMOn);
619     strcpy(prefs->XPandROMFile,PrefsWindow->ReadIconText(Icon_Prefs_XROMPath));
620     #endif
621    
622 cebix 1.1 // 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 cebix 1.3 else if ((Block[5] == PrefsWindow->MyHandle()) && ((Block[10] == FileType_Text) || (Block[10] == FileType_C64File))) {i=0;}
1615 cebix 1.1 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 cebix 1.3 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 cebix 1.1 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 cebix 1.3 default: i = -1; break;
1689 cebix 1.1 }
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     }