]> git.sesse.net Git - pistorm/blob - platforms/amiga/pistorm-dev/pistorm_dev_amiga/gui_interact.c
3a6f1f10a9acef231c85422da3e62156ab503e32
[pistorm] / platforms / amiga / pistorm-dev / pistorm_dev_amiga / gui_interact.c
1 // SPDX-License-Identifier: MIT
2
3 #include <proto/intuition.h>
4 #include <proto/dos.h>
5 #include <intuition/intuition.h>
6 #include <proto/exec.h>
7 #include <proto/dos.h>
8 #include <workbench/startup.h>
9 #include <clib/expansion_protos.h>
10 #include <libraries/reqtools.h>
11 #include <clib/reqtools_protos.h>
12
13 #include "pistorm_dev.h"
14 #include "../pistorm-dev-enums.h"
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 extern unsigned int pistorm_base_addr;
20 struct ReqToolsBase *ReqToolsBase;
21
22 #define VERSION "v0.3.2"
23
24 #define button1w 54
25 #define button1h 11
26
27 #define button2w 87
28 #define button2h 11
29
30 #define button3w 100
31 #define button3h 11
32
33 #define tbox1w 130
34 #define tbox1h 10
35
36 #define statusbarw 507
37 #define statusbarh 10
38
39 SHORT SharedBordersPairs0[] =
40 {
41     0, 0, 0, button1h - 1, 1, button1h - 2, 1, 0, button1w - 2, 0
42 };
43 SHORT SharedBordersPairs1[] =
44 {
45     1, button1h - 1, button1w - 2, button1h - 1, button1w - 2, 1, button1w - 1, 0, button1w - 1, button1h - 1
46 };
47
48 SHORT SharedBordersPairs2[] =
49 {
50     0, 0, 0, button3h - 1, 1, button3h - 2, 1, 0, button3w - 2, 0
51 };
52 SHORT SharedBordersPairs3[] =
53 {
54     1, button3h - 1, button3w - 2, button3h - 1, button3w - 2, 1, button3w - 1, 0, button3w - 1, button3h - 1
55 };
56
57 SHORT SharedBordersPairs4[] =
58 {
59     0, 0, 0, button2h - 1, 1, button2h - 2, 1, 0, button2w - 2, 0
60 };
61 SHORT SharedBordersPairs5[] =
62 {
63     1, button2h - 1, button2w - 2, button2h - 1, button2w - 2, 1, button2w - 1, 0, button2w - 1, button2h - 1
64 };
65
66 SHORT SharedBordersPairs6[] =
67 {
68     -2, -1, -2, tbox1h - 1, -1, tbox1h - 2, -1, -1, tbox1w - 2, -1
69 };
70
71 SHORT SharedBordersPairs7[] =
72 {
73     -1, tbox1h - 1, tbox1w - 2, tbox1h - 1, tbox1w - 2, 0, tbox1w - 1, -1, tbox1w - 1, tbox1h - 1
74 };
75
76 SHORT SharedBordersPairs8[] =
77 {
78     0, 0, statusbarw - 2, 0, statusbarw - 2, 0, 0, 0, 0, 0
79 };
80
81 SHORT SharedBordersPairs9[] =
82 {
83     0, 0, 0, tbox1h - 1, 1, tbox1h - 2, 1, 0, tbox1w - 2, 0
84 };
85 SHORT SharedBordersPairs10[] =
86 {
87     1, tbox1h - 1, tbox1w - 2, tbox1h - 1, tbox1w - 2, 1, tbox1w - 1, 0, tbox1w - 1, tbox1h - 1
88 };
89
90
91 struct Border SharedBorders[] =
92 {
93     0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs0[0], &SharedBorders[1], // Button 1
94     0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs1[0], NULL,
95     0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs2[0], &SharedBorders[3], // Button 3
96     0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs3[0], NULL,
97     0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs4[0], &SharedBorders[5], // Button 2
98     0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs5[0], NULL,
99     0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs6[0], &SharedBorders[7], // TBox
100     0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs7[0], NULL,
101     0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs8[0], NULL, // Statusbar
102     0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs9[0], &SharedBorders[10], // TBox inverted
103     0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs10[0], NULL,
104 };
105
106 struct Border SharedBordersInvert[] =
107 {
108     0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs0[0], &SharedBordersInvert[1], // Button 1
109     0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs1[0], NULL,
110     0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs2[0], &SharedBordersInvert[3], // Button 3
111     0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs3[0], NULL,
112     0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs4[0], &SharedBordersInvert[5], // Button 2
113     0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs5[0], NULL,
114     0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs9[0], &SharedBordersInvert[7], // TBox inverted
115     0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs10[0], NULL,
116 };
117
118 struct IntuiText KickstartCommit_text =
119 {
120     1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Commit", NULL
121 };
122
123 #define GADKICKSTARTCOMMIT 14
124
125 struct Gadget KickstartCommit =
126 {
127     NULL, 406, 49, button1w, button1h,
128     GADGHIMAGE,
129     RELVERIFY,
130     BOOLGADGET,
131     (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
132     &KickstartCommit_text, 0, NULL, GADKICKSTARTCOMMIT, NULL
133 };
134
135
136 UBYTE KickstartFileValue_buf[255];
137
138 struct StringInfo KickstartFileValue =
139 {
140     KickstartFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
141 };
142
143 struct IntuiText KickstartFile_text =
144 {
145     1, 0, JAM2, 0, -10, NULL, "Kickstart file:", NULL
146 };
147
148 #define GADKICKSTARTFILE 13
149
150 struct Gadget KickstartFile =
151 {
152     &KickstartCommit, 266, 50, tbox1w, tbox1h,
153     GADGHIMAGE,
154     0,
155     STRGADGET,
156     (APTR) &SharedBorders[6], NULL,
157     &KickstartFile_text, 0, (APTR)&KickstartFileValue, GADKICKSTARTFILE, NULL
158 };
159
160 struct IntuiText ShutdownButton_text =
161 {
162     1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Shutdown Pi", NULL
163 };
164
165 #define GADSHUTDOWN 12
166
167 struct Gadget ShutdownButton =
168 {
169     &KickstartFile, 60, 166, button3w, button3h,
170     GADGHIMAGE,
171     RELVERIFY,
172     BOOLGADGET,
173     (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
174     &ShutdownButton_text, 0, NULL, GADSHUTDOWN, NULL
175 };
176
177
178 UBYTE DestinationValue_buf[255];
179
180 struct IntuiText Destination_text[] =
181 {
182     1, 0, JAM2, -97, 1, NULL, "Destination:", &Destination_text[1],
183     1, 0, JAM2, 1, 1, NULL, DestinationValue_buf, NULL,
184 };
185
186 #define GADGETDESTINATION 11
187
188 struct Gadget GetDestination =
189 {
190     &ShutdownButton, 106, 105, tbox1w, tbox1h,
191     GADGHIMAGE,
192     RELVERIFY,
193     BOOLGADGET,
194     (APTR) &SharedBorders[9], (APTR) &SharedBordersInvert[6],
195     Destination_text, 0, NULL, GADGETDESTINATION, NULL
196 };
197
198 struct IntuiText RebootButton_text =
199 {
200     1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Reboot", NULL
201 };
202
203 #define GADREBOOT 10
204
205 struct Gadget RebootButton =
206 {
207     &GetDestination, 4, 166, button1w, button1h,
208     GADGHIMAGE,
209     RELVERIFY,
210     BOOLGADGET,
211     (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
212     &RebootButton_text, 0, NULL, GADREBOOT, NULL
213 };
214
215 UBYTE StatusBar_buf[128] = "Reticulating splines...";
216
217 struct IntuiText StatusBar_text =
218 {
219     1, 0, JAM2, 4, 2, NULL, (UBYTE *)StatusBar_buf, NULL
220 };
221
222 #define GADSTATUSBAR 9
223
224 struct Gadget StatusBar =
225 {
226     &RebootButton, 3, 188, 508, 10,
227     GADGHIMAGE,
228     0,
229     BOOLGADGET,
230     (APTR) &SharedBorders[8], NULL,
231     &StatusBar_text, 0, NULL, GADSTATUSBAR, NULL
232 };
233
234
235 struct IntuiText RetrieveButton_text =
236 {
237     1, 0, JAM2, 10, 2, NULL, (UBYTE *)"Retrieve", NULL
238 };
239
240 #define GADRETRIEVEBUTTON 8
241
242 struct Gadget RetrieveButton =
243 {
244     &StatusBar, 244, 105, button2w, button2h,
245     GADGHIMAGE,
246     RELVERIFY,
247     BOOLGADGET,
248     (APTR) &SharedBorders[4], (APTR) &SharedBordersInvert[4],
249     &RetrieveButton_text, 0, NULL, GADRETRIEVEBUTTON, NULL
250 };
251
252 UBYTE GetFileValue_buf[255];
253
254 struct StringInfo GetFileValue =
255 {
256     GetFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
257 };
258
259 struct IntuiText GetFile_text[] =
260 {
261     1, 0, JAM2, -98, -10, NULL, "Get file from PiStorm:", &GetFile_text[1],
262     1, 0, JAM2, -59, 1, NULL, "Source:", NULL,
263 };
264
265 #define GADGETFILE 7
266
267 struct Gadget GetFile =
268 {
269     &RetrieveButton, 108, 93, tbox1w, tbox1h,
270     GADGHIMAGE,
271     0,
272     STRGADGET,
273     (APTR) &SharedBorders[6], NULL,
274     GetFile_text, 0, (APTR)&GetFileValue, GADGETFILE, NULL
275 };
276
277 struct IntuiText ConfigDefault_text =
278 {
279     1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Load Default", NULL
280 };
281
282 #define GADCONFIGDEFAULT 6
283
284 struct Gadget ConfigDefault =
285 {
286     &GetFile, 9, 62, button3w, button3h,
287     GADGHIMAGE,
288     RELVERIFY,
289     BOOLGADGET,
290     (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
291     &ConfigDefault_text, 0, NULL, GADCONFIGDEFAULT, NULL
292 };
293
294 struct IntuiText ConfigCommit_text =
295 {
296     1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Commit", NULL
297 };
298
299 #define GADCONFIGCOMMIT 5
300
301 struct Gadget ConfigCommit =
302 {
303     &ConfigDefault, 144, 49, button1w, button1h,
304     GADGHIMAGE,
305     RELVERIFY,
306     BOOLGADGET,
307     (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
308     &ConfigCommit_text, 0, NULL, GADCONFIGCOMMIT, NULL
309 };
310
311
312 UBYTE ConfigFileValue_buf[255];
313
314 struct StringInfo ConfigFileValue =
315 {
316     ConfigFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
317 };
318
319 struct IntuiText ConfigFile_text =
320 {
321     1, 0, JAM2, 0, -10, NULL, "Config file:", NULL
322 };
323
324 #define GADCONFIGFILE 4
325
326 struct Gadget ConfigFile =
327 {
328     &ConfigCommit, 10, 50, tbox1w, tbox1h,
329     GADGHIMAGE,
330     0,
331     STRGADGET,
332     (APTR) &SharedBorders[6], NULL,
333     &ConfigFile_text, 0, (APTR)&ConfigFileValue, GADCONFIGFILE, NULL
334 };
335
336 UBYTE RTGStatus_buf[64] = "RTG status";
337
338 struct IntuiText RTGStatus_text =
339 {
340     1, 0, JAM2, 1, 1, NULL, (UBYTE *)RTGStatus_buf, NULL
341 };
342
343 #define GADRTGSTATUS 3
344
345 struct Gadget RTGStatus =
346 {
347     &ConfigFile, 14, 15, tbox1w, tbox1h,
348     GADGHIMAGE,
349     0,
350     BOOLGADGET,
351     (APTR) &SharedBorders[6], NULL,
352     &RTGStatus_text, 0, NULL, GADRTGSTATUS, NULL
353 };
354
355 UBYTE RTG_buf[64] = "RTG Enable";
356
357 struct IntuiText RTG_text =
358 {
359     1, 0, JAM2, 8, 2, NULL, (UBYTE *)RTG_buf, NULL
360 };
361
362 #define GADRTGBUTTON 2
363
364 struct Gadget RTGButton =
365 {
366     &RTGStatus, 150, 14, button3w, button3h,
367     GADGHIMAGE,
368     RELVERIFY,
369     BOOLGADGET,
370     (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
371     &RTG_text, 0, NULL, GADRTGBUTTON, NULL
372 };
373
374 struct IntuiText AboutButton_text =
375 {
376     1, 0, JAM2, 8, 2, NULL, (UBYTE *)"About", NULL
377 };
378
379 #define GADABOUT 1
380
381 struct Gadget AboutButton =
382 {
383     &RTGButton, 356, 166, button1w, button1h,
384     GADGHIMAGE,
385     RELVERIFY,
386     BOOLGADGET,
387     (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
388     &AboutButton_text, 0, NULL, GADABOUT, NULL
389 };
390
391
392 struct IntuiText QuitButton_text =
393 {
394     1, 0, JAM2, 12, 2, NULL, (UBYTE *)"Quit", NULL
395 };
396
397 #define GADQUIT 0
398
399 struct Gadget QuitButton =
400 {
401     &AboutButton, 438, 166, button1w, button1h,
402     GADGHIMAGE,
403     RELVERIFY,
404     BOOLGADGET,
405     (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
406     &QuitButton_text, 0, NULL, GADQUIT, NULL
407 };
408
409
410 struct NewWindow winlayout =
411 {
412     0, 0,
413     512, 200,
414     -1, -1,
415     CLOSEWINDOW | GADGETUP | GADGETDOWN,
416     ACTIVATE | WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH,
417     &QuitButton, NULL,
418     (STRPTR)"PiStorm Interaction Tool",
419     NULL, NULL,
420     0, 0,
421     600, 400,
422     WBENCHSCREEN
423 };
424
425 // Pads what we are writing to screen with spaces, otherwise we get bits of
426 // old text still showing
427 static void WriteGadgetText(const char *text, UBYTE *buffer, struct Window *window, struct Gadget *gadget)
428 {
429     ULONG newlen = strlen(text);
430     ULONG oldlen = strlen((char *)buffer);
431
432     if (newlen < oldlen)
433     {
434         snprintf((char *)buffer, 64, "%s%*.*s", text, (int)(oldlen - newlen),
435                  (int)(oldlen - newlen), " ");
436     }
437     else
438     {
439         strncpy((char *)buffer, text, 64);
440     }
441
442     RefreshGadgets(gadget, window, NULL);
443 }
444 static void updateRTG(struct Window *window)
445 {
446     unsigned short rtg = pi_get_rtg_status();
447     if (rtg & 0x01)
448     {
449         WriteGadgetText("Disable RTG", RTG_buf, window, &RTGButton);
450         if (rtg & 0x02)
451         {
452             WriteGadgetText("RTG in use", RTGStatus_buf, window, &RTGStatus);
453         }
454         else
455         {
456             WriteGadgetText("RTG not in use", RTGStatus_buf, window, &RTGStatus);
457         }
458     }
459     else
460     {
461         WriteGadgetText("Enable RTG", RTG_buf, window, &RTGButton);
462         WriteGadgetText("RTG disabled", RTGStatus_buf, window, &RTGStatus);
463     }
464 }
465
466 static char *GetSavePath()
467 {
468     struct rtFileRequester *filereq;
469     char filename[128];
470     char *fullpath = malloc(256 * sizeof(char));
471     UBYTE *buf = NULL;
472
473     if ((filereq = (struct rtFileRequester*)rtAllocRequestA (RT_FILEREQ, NULL)))
474     {
475         filename[0] = 0;
476
477         if (!rtFileRequest(filereq, filename, "Pick a destination directory",
478                            RTFI_Flags, FREQF_NOFILES, TAG_END))
479         {
480             free(fullpath);
481             return NULL;
482         }
483
484     }
485     else
486     {
487         rtEZRequest("Out of memory!", "Oh no!", NULL, NULL);
488         return NULL;
489     }
490
491     strncpy(fullpath, (char*)filereq->Dir, 256);
492     rtFreeRequest((APTR)filereq);
493     return fullpath;
494 }
495
496 int questionReboot()
497 {
498     int res = rtEZRequest("This will restart the emulator, rebooting the Amiga\n"
499                           "Continue anyway?",
500                           "Yes|No", NULL, NULL);
501     return res;
502 }
503
504 int main()
505 {
506     struct Window *myWindow;
507
508     IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
509     if (IntuitionBase == NULL)
510     {
511         return RETURN_FAIL;
512     }
513
514     if (!(ReqToolsBase = (struct ReqToolsBase *)
515                          OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION)))
516     {
517         static struct IntuiText pos;
518         struct IntuiText msg[] =
519         {
520             1, 0, JAM2, 0, 0, NULL, "You need reqtools.library V38 or higher!.", &msg[1],
521             1, 0, JAM2, 0, 10, NULL, "Please install it in your Libs: drirectory.", NULL,
522         };
523         AutoRequest(NULL, msg, NULL, &pos, 0, 0, 0, 0);
524         return RETURN_FAIL;
525     }
526
527     pistorm_base_addr = pi_find_pistorm();
528     myWindow = OpenWindow(&winlayout);
529     BOOL no_board = FALSE;
530
531     if (pistorm_base_addr == 0xFFFFFFFF)
532     {
533         rtEZRequest("Unable to find PiStorm autoconf device.",
534                     "OK", NULL, NULL);
535         no_board = TRUE;
536         WriteGadgetText("PiStorm not found", StatusBar_buf, myWindow, &StatusBar);
537     }
538     else
539     {
540         WriteGadgetText("PiStorm found!", StatusBar_buf, myWindow, &StatusBar);
541     }
542     if (!no_board)
543     {
544         updateRTG(myWindow);
545     }
546
547     FOREVER
548     {
549         BOOL closewin = FALSE;
550         struct IntuiMessage *message;
551         Wait(1 << myWindow->UserPort->mp_SigBit);
552
553         while ((message = (struct IntuiMessage*)GetMsg(myWindow->UserPort)))
554         {
555             ULONG class = message->Class;
556             struct Gadget *address = (struct Gadget*)message->IAddress;
557             ReplyMsg((struct Message*)message);
558
559             if (class == CLOSEWINDOW)
560             {
561                 closewin = TRUE;
562             }
563             else if (class == GADGETUP)
564             {
565                 if (no_board && (address->GadgetID != GADQUIT) && (address->GadgetID != GADABOUT))
566                 {
567                     continue;
568                 }
569                 switch (address->GadgetID)
570                 {
571                     case GADQUIT:
572                         closewin = TRUE;
573                         break;
574                     case GADABOUT:
575                         {
576                             static struct IntuiText pos;
577                             char buf2[64], buf3[64];
578                             if (!no_board)
579                             {
580                                 unsigned short hw_rev = pi_get_hw_rev();
581                                 unsigned short sw_rev = pi_get_sw_rev();
582                                 snprintf(buf2, 64, "PiStorm hardware: %d.%d", (hw_rev >> 8), (hw_rev & 0xFF));
583                                 snprintf(buf3, 64, "PiStorm software: %d.%d", (sw_rev >> 8), (sw_rev & 0xFF));
584                             }
585                             else
586                             {
587                                 snprintf(buf2, 64, "PiStorm hardware not found!");
588                             }
589                             rtEZRequest("PiStorm Interaction Tool %s\n"
590                                         "Tool written by beeanyew and LinuxJedi\n"
591                                         "%s\n%s\n\n"
592                                         "Now with 53%% more Nibbles!",
593                                         "More Nibbles!", NULL, NULL, VERSION, buf2, buf3);
594                             break;
595                         }
596                     case GADRTGBUTTON:
597                         {
598                             unsigned short rtgStatus = pi_get_rtg_status() & 0x01;
599                             pi_enable_rtg(!rtgStatus);
600                             updateRTG(myWindow);
601                             break;
602                         }
603                     case GADCONFIGCOMMIT:
604                         {
605                             if (!questionReboot())
606                             {
607                                 break;
608                             }
609                             unsigned short ret = pi_handle_config(PICFG_LOAD, ConfigFileValue_buf);
610                             if (ret == PI_RES_FILENOTFOUND)
611                             {
612                                 rtEZRequest("PiStorm says: \"file not found\"",
613                                             "OK", NULL, NULL);
614                             }
615                             break;
616                         }
617                     case GADCONFIGDEFAULT:
618                         {
619                             if (!questionReboot())
620                             {
621                                 break;
622                             }
623                             pi_handle_config(PICFG_DEFAULT, NULL);
624                             break;
625                         }
626                     case GADRETRIEVEBUTTON:
627                         {
628                             unsigned int filesize = 0;
629                             char outpath[128];
630                             unsigned char *buf;
631
632                             if (pi_get_filesize(GetFileValue_buf, &filesize) == PI_RES_FILENOTFOUND)
633                             {
634                                 rtEZRequest("PiStorm says: \"file not found\"",
635                                             "OK", NULL, NULL);
636                                 break;
637                             }
638                             buf = malloc(filesize);
639                             if (buf == NULL)
640                             {
641                                 rtEZRequest("Could not allocate enough memory to transfer file",
642                                             "OK", NULL, NULL);
643                                 break;
644                             }
645                             WriteGadgetText("Retrieving file...", StatusBar_buf, myWindow, &StatusBar);
646                             if (pi_transfer_file(GetFileValue_buf, buf) != PI_RES_OK)
647                             {
648                                 rtEZRequest("PiStorm says: \"something went wrong with the file transfer\"",
649                                             "OK", NULL, NULL);
650                                 WriteGadgetText("File transfer failed", StatusBar_buf, myWindow, &StatusBar);
651                                 free(buf);
652                                 break;
653                             }
654                             char *fname = strrchr(GetFileValue_buf, '/');
655                             if (!fname)
656                             {
657                                 fname = GetFileValue_buf;
658                             }
659                             char *destfile = malloc(256);
660                             // Turns out WB doesn't like DF0:/filename.ext
661                             if (DestinationValue_buf[(strlen(DestinationValue_buf) - 1)] == ':')
662                             {
663                                 snprintf(destfile, 255, "%s%s", DestinationValue_buf, GetFileValue_buf);
664                             }
665                             else if (!strlen(DestinationValue_buf))
666                             {
667                                 snprintf(destfile, 255, "%s", GetFileValue_buf);
668                             }
669                             else
670                             {
671                                 snprintf(destfile, 255, "%s/%s", DestinationValue_buf, GetFileValue_buf);
672                             }
673                             BPTR fh = Open(destfile, MODE_NEWFILE);
674                             if (!fh)
675                             {
676                                 char errbuf[64];
677                                 snprintf(errbuf, 64, "Error code: %ld", IoErr());
678                                 rtEZRequest("Could not open file for writing\n"
679                                             "%s\n%s",
680                                             "OK", NULL, NULL, destfile, errbuf);
681                                 WriteGadgetText("File transfer failed", StatusBar_buf, myWindow, &StatusBar);
682                                 free(buf);
683                                 free(destfile);
684                                 break;
685                             }
686                             Write(fh, buf, filesize);
687                             Close(fh);
688                             free(destfile);
689                             WriteGadgetText("File transfer complete", StatusBar_buf, myWindow, &StatusBar);
690                             free(buf);
691                             break;
692                         }
693                     case GADREBOOT:
694                         {
695                             WriteGadgetText("Rebooting Amiga", StatusBar_buf, myWindow, &StatusBar);
696                             pi_reset_amiga(0);
697                             break;
698                         }
699                     case GADGETDESTINATION:
700                         {
701                             char *fileName = GetSavePath();
702                             if (fileName)
703                             {
704                                 WriteGadgetText(fileName, DestinationValue_buf, myWindow, &GetDestination);
705                                 free(fileName);
706                             }
707                             break;
708                         }
709                     case GADSHUTDOWN:
710                         {
711                             int res = rtEZRequest("This will shutdown the Pi and cause the Amiga to freeze\n"
712                                                   "Continue anyway?",
713                                                   "Yes|No", NULL, NULL);
714                             if (!res)
715                             {
716                                 break;
717                             }
718                             WriteGadgetText("Shuttting down PiStorm...", StatusBar_buf, myWindow, &StatusBar);
719                             int confirm = pi_shutdown_pi(0);
720                             pi_confirm_shutdown(confirm);
721                             break;
722                         }
723                     case GADKICKSTARTCOMMIT:
724                         {
725                             if (!questionReboot())
726                             {
727                                 break;
728                             }
729                             unsigned short ret = pi_remap_kickrom(KickstartFileValue_buf);
730                             if (ret == PI_RES_FILENOTFOUND)
731                             {
732                                 rtEZRequest("PiStorm says: \"file not found\"",
733                                             "OK", NULL, NULL);
734                             }
735                             break;
736                         }
737                 }
738             }
739             if (closewin)
740             {
741                 break;
742             }
743         }
744         if (closewin)
745         {
746             break;
747         }
748     };
749     if (myWindow) CloseWindow(myWindow);
750     CloseLibrary((struct Library*)ReqToolsBase);
751     return 0;
752 }