]> git.sesse.net Git - pistorm/blob - platforms/amiga/pistorm-dev/pistorm_dev_amiga/gui_interact.c
A whole bunch of GUI changes
[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"
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] = "PiStorm...";
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     20, 20,
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     }
489
490     strncpy(fullpath, (char*)filereq->Dir, 256);
491     return fullpath;
492 }
493
494 int questionReboot()
495 {
496     int res = rtEZRequest("This will restart the emulator, rebooting the Amiga\n"
497                           "Continue anyway?",
498                           "Yes|No", NULL, NULL);
499     return res;
500 }
501
502 int main()
503 {
504     struct Window *myWindow;
505
506     IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
507     if (IntuitionBase == NULL)
508     {
509         return RETURN_FAIL;
510     }
511
512     if (!(ReqToolsBase = (struct ReqToolsBase *)
513                          OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION)))
514     {
515         static struct IntuiText pos;
516         struct IntuiText msg[] =
517         {
518             1, 0, JAM2, 0, 0, NULL, "You need reqtools.library V38 or higher!.", &msg[1],
519             1, 0, JAM2, 0, 10, NULL, "Please install it in your Libs: drirectory.", NULL,
520         };
521         AutoRequest(NULL, msg, NULL, &pos, 0, 0, 0, 0);
522         return RETURN_FAIL;
523     }
524
525     pistorm_base_addr = pi_find_pistorm();
526     myWindow = OpenWindow(&winlayout);
527     BOOL no_board = FALSE;
528
529     if (pistorm_base_addr == 0xFFFFFFFF)
530     {
531         rtEZRequest("Unable to find PiStorm autoconf device.",
532                     "OK", NULL, NULL);
533         no_board = TRUE;
534         WriteGadgetText("PiStorm not found", StatusBar_buf, myWindow, &StatusBar);
535     }
536     if (!no_board)
537     {
538         updateRTG(myWindow);
539     }
540
541     FOREVER
542     {
543         BOOL closewin = FALSE;
544         struct IntuiMessage *message;
545         Wait(1 << myWindow->UserPort->mp_SigBit);
546
547         while ((message = (struct IntuiMessage*)GetMsg(myWindow->UserPort)))
548         {
549             ULONG class = message->Class;
550             struct Gadget *address = (struct Gadget*)message->IAddress;
551             ReplyMsg((struct Message*)message);
552
553             if (class == CLOSEWINDOW)
554             {
555                 closewin = TRUE;
556             }
557             else if (class == GADGETUP)
558             {
559                 if (no_board && (address->GadgetID != GADQUIT) && (address->GadgetID != GADABOUT))
560                 {
561                     continue;
562                 }
563                 switch (address->GadgetID)
564                 {
565                     case GADQUIT:
566                         closewin = TRUE;
567                         break;
568                     case GADABOUT:
569                         {
570                             static struct IntuiText pos;
571                             char buf2[64], buf3[64];
572                             if (!no_board)
573                             {
574                                 unsigned short hw_rev = pi_get_hw_rev();
575                                 unsigned short sw_rev = pi_get_sw_rev();
576                                 snprintf(buf2, 64, "PiStorm hardware: %d.%d", (hw_rev >> 8), (hw_rev & 0xFF));
577                                 snprintf(buf3, 64, "PiStorm software: %d.%d", (sw_rev >> 8), (sw_rev & 0xFF));
578                             }
579                             else
580                             {
581                                 snprintf(buf2, 64, "PiStorm hardware not found!");
582                             }
583                             rtEZRequest("PiStorm Interaction Tool %s\n"
584                                         "Tool written by beeanyew and LinuxJedi\n"
585                                         "%s\n%s\n\n"
586                                         "Now with 53%% more Nibbles!",
587                                         "More Nibbles!", NULL, NULL, VERSION, buf2, buf3);
588                             break;
589                         }
590                     case GADRTGBUTTON:
591                         {
592                             unsigned short rtgStatus = pi_get_rtg_status() & 0x01;
593                             pi_enable_rtg(!rtgStatus);
594                             updateRTG(myWindow);
595                             break;
596                         }
597                     case GADCONFIGCOMMIT:
598                         {
599                             if (!questionReboot())
600                             {
601                                 break;
602                             }
603                             unsigned short ret = pi_handle_config(PICFG_LOAD, ConfigFileValue_buf);
604                             if (ret == PI_RES_FILENOTFOUND)
605                             {
606                                 rtEZRequest("PiStorm says: \"file not found\"",
607                                             "OK", NULL, NULL);
608                             }
609                             break;
610                         }
611                     case GADCONFIGDEFAULT:
612                         {
613                             if (!questionReboot())
614                             {
615                                 break;
616                             }
617                             pi_handle_config(PICFG_DEFAULT, NULL);
618                             break;
619                         }
620                     case GADRETRIEVEBUTTON:
621                         {
622                             unsigned int filesize = 0;
623                             char outpath[128];
624                             unsigned char *buf;
625
626                             if (pi_get_filesize(GetFileValue_buf, &filesize) == PI_RES_FILENOTFOUND)
627                             {
628                                 rtEZRequest("PiStorm says: \"file not found\"",
629                                             "OK", NULL, NULL);
630                                 break;
631                             }
632                             buf = malloc(filesize);
633                             if (buf == NULL)
634                             {
635                                 rtEZRequest("Could not allocate enough memory to transfer file",
636                                             "OK", NULL, NULL);
637                                 break;
638                             }
639                             WriteGadgetText("Retrieving file...", StatusBar_buf, myWindow, &StatusBar);
640                             if (pi_transfer_file(GetFileValue_buf, buf) != PI_RES_OK)
641                             {
642                                 rtEZRequest("PiStorm says: \"something went wrong with the file transfer\"",
643                                             "OK", NULL, NULL);
644                                 WriteGadgetText("File transfer failed", StatusBar_buf, myWindow, &StatusBar);
645                                 free(buf);
646                                 break;
647                             }
648                             char *fname = strrchr(GetFileValue_buf, '/');
649                             if (!fname)
650                             {
651                                 fname = GetFileValue_buf;
652                             }
653                             char *destfile = malloc(256);
654                             // Turns out WB doesn't like DF0:/filename.ext
655                             if (DestinationValue_buf[(strlen(DestinationValue_buf) - 1)] == ':')
656                             {
657                                 snprintf(destfile, 255, "%s%s", DestinationValue_buf, GetFileValue_buf);
658                             }
659                             else if (!strlen(DestinationValue_buf))
660                             {
661                                 snprintf(destfile, 255, "%s", GetFileValue_buf);
662                             }
663                             else
664                             {
665                                 snprintf(destfile, 255, "%s/%s", DestinationValue_buf, GetFileValue_buf);
666                             }
667                             BPTR fh = Open(destfile, MODE_NEWFILE);
668                             if (!fh)
669                             {
670                                 char errbuf[64];
671                                 snprintf(errbuf, 64, "Error code: %ld", IoErr());
672                                 rtEZRequest("Could not open file for writing\n"
673                                             "%s\n%s",
674                                             "OK", NULL, NULL, destfile, errbuf);
675                                 WriteGadgetText("File transfer failed", StatusBar_buf, myWindow, &StatusBar);
676                                 free(buf);
677                                 free(destfile);
678                                 break;
679                             }
680                             Write(fh, buf, filesize);
681                             Close(fh);
682                             free(destfile);
683                             WriteGadgetText("File transfer complete", StatusBar_buf, myWindow, &StatusBar);
684                             free(buf);
685                             break;
686                         }
687                     case GADREBOOT:
688                         {
689                             WriteGadgetText("Rebooting Amiga", StatusBar_buf, myWindow, &StatusBar);
690                             pi_reset_amiga(0);
691                             break;
692                         }
693                     case GADGETDESTINATION:
694                         {
695                             char *fileName = GetSavePath();
696                             if (fileName)
697                             {
698                                 WriteGadgetText(fileName, DestinationValue_buf, myWindow, &GetDestination);
699                                 free(fileName);
700                             }
701                             break;
702                         }
703                     case GADSHUTDOWN:
704                         {
705                             int res = rtEZRequest("This will shutdown the Pi and cause the Amiga to freeze\n"
706                                                   "Continue anyway?",
707                                                   "Yes|No", NULL, NULL);
708                             if (!res)
709                             {
710                                 break;
711                             }
712                             WriteGadgetText("Shuttting down PiStorm...", StatusBar_buf, myWindow, &StatusBar);
713                             int confirm = pi_shutdown_pi(0);
714                             pi_confirm_shutdown(confirm);
715                             break;
716                         }
717                     case GADKICKSTARTCOMMIT:
718                         {
719                             if (!questionReboot())
720                             {
721                                 break;
722                             }
723                             unsigned short ret = pi_remap_kickrom(KickstartFileValue_buf);
724                             if (ret == PI_RES_FILENOTFOUND)
725                             {
726                                 rtEZRequest("PiStorm says: \"file not found\"",
727                                             "OK", NULL, NULL);
728                             }
729                             break;
730                         }
731                 }
732             }
733             if (closewin)
734             {
735                 break;
736             }
737         }
738         if (closewin)
739         {
740             break;
741         }
742     };
743     if (myWindow) CloseWindow(myWindow);
744     CloseLibrary((struct Library*)ReqToolsBase);
745     return 0;
746 }