1 /*
2 Hatari - dlgFloppy.c
3
4 This file is distributed under the GNU General Public License, version 2
5 or at your option any later version. Read the file gpl.txt for details.
6 */
7 const char DlgFloppy_fileid[] = "Hatari dlgFloppy.c : " __DATE__ " " __TIME__;
8
9 #include <assert.h>
10 #include "main.h"
11 #include "configuration.h"
12 #include "dialog.h"
13 #include "sdlgui.h"
14 #include "file.h"
15 #include "floppy.h"
16
17 #include "gui-retro.h"
18
19 #define FLOPPYDLG_ENABLE_A 3
20 #define FLOPPYDLG_HEADS_DS_A 4
21 #define FLOPPYDLG_EJECTA 5
22 #define FLOPPYDLG_BROWSEA 6
23 #define FLOPPYDLG_DISKA 7
24
25 #define FLOPPYDLG_ENABLE_B 9
26 #define FLOPPYDLG_HEADS_DS_B 10
27 #define FLOPPYDLG_EJECTB 11
28 #define FLOPPYDLG_BROWSEB 12
29 #define FLOPPYDLG_DISKB 13
30
31 #define FLOPPYDLG_IMGDIR 15
32 #define FLOPPYDLG_BROWSEIMG 16
33 #define FLOPPYDLG_AUTOB 17
34 #define FLOPPYDLG_FASTFLOPPY 18
35 #define FLOPPYDLG_CREATEIMG 19
36 #define FLOPPYDLG_PROTOFF 21
37 #define FLOPPYDLG_PROTON 22
38 #define FLOPPYDLG_PROTAUTO 23
39 #define FLOPPYDLG_EXIT 24
40
41 /* The floppy disks dialog: */
42 static SGOBJ floppydlg[] =
43 {
44 { SGBOX, 0, 0, 0,0, 64,20, NULL },
45 { SGTEXT, 0, 0, 25,1, 12,1, "Floppy disks" },
46
47 { SGTEXT, 0, 0, 2,3, 8,1, "Drive A:" },
48 { SGCHECKBOX, 0, 0, 12,3, 9,1, "Enabled" },
49 { SGCHECKBOX, 0, 0, 23,3, 14,1, "Double Sided" },
50 { SGBUTTON, SG_EXIT/*0*/, 0, 46,3, 7,1, "Eject" },
51 { SGBUTTON, SG_EXIT/*0*/, 0, 54,3, 8,1, "Browse" },
52 { SGTEXT, 0, 0, 3,4, 58,1, NULL },
53
54 { SGTEXT, 0, 0, 2,6, 8,1, "Drive B:" },
55 { SGCHECKBOX, 0, 0, 12,6, 9,1, "Enabled" },
56 { SGCHECKBOX, 0, 0, 23,6, 14,1, "Double Sided" },
57 { SGBUTTON, SG_EXIT/*0*/, 0, 46,6, 7,1, "Eject" },
58 { SGBUTTON, SG_EXIT/*0*/, 0, 54,6, 8,1, "Browse" },
59 { SGTEXT, 0, 0, 3,7, 58,1, NULL },
60
61 { SGTEXT, 0, 0, 2,9, 32,1, "Default floppy images directory:" },
62 { SGTEXT, 0, 0, 3,10, 58,1, NULL },
63 { SGBUTTON, SG_EXIT/*0*/, 0, 54, 9, 8,1, "Browse" },
64 { SGCHECKBOX, 0, 0, 2,12, 15,1, "Auto insert B" },
65 { SGCHECKBOX, 0, 0, 2,14, 20,1, "Fast floppy access" },
66 { SGBUTTON, SG_EXIT/*0*/, 0, 42,14, 20,1, "Create blank image" },
67 { SGTEXT, 0, 0, 2,16, 17,1, "Write protection:" },
68 { SGRADIOBUT, 0, 0, 21,16, 5,1, "Off" },
69 { SGRADIOBUT, 0, 0, 28,16, 4,1, "On" },
70 { SGRADIOBUT, 0, 0, 34,16, 6,1, "Auto" },
71 { SGBUTTON, SG_EXIT/*SG_DEFAULT*/, 0, 22,18, 20,1, "Back to main menu" },
72 { -1, 0, 0, 0,0, 0,0, NULL }
73 };
74
75
76 #define DLGMOUNT_A 2
77 #define DLGMOUNT_B 3
78 #define DLGMOUNT_CANCEL 4
79
80 /* The "Alert"-dialog: */
81 static SGOBJ alertdlg[] =
82 {
83 { SGBOX, 0, 0, 0,0, 40,6, NULL },
84 { SGTEXT, 0, 0, 3,1, 30,1, "Insert last created disk to?" },
85 { SGBUTTON, SG_EXIT/*0*/, 0, 3,4, 10,1, "Drive A:" },
86 { SGBUTTON, SG_EXIT/*0*/, 0, 15,4, 10,1, "Drive B:" },
87 { SGBUTTON, SG_EXIT/*SG_CANCEL*/, 0, 27,4, 10,1, "Cancel" },
88 { -1, 0, 0, 0,0, 0,0, NULL }
89 };
90
91
92 /**
93 * Let user browse given disk, insert disk if one selected.
94 */
DlgDisk_BrowseDisk(char * dlgname,int drive,int diskid)95 static void DlgDisk_BrowseDisk(char *dlgname, int drive, int diskid)
96 {
97 char *selname, *zip_path;
98 const char *tmpname, *realname;
99
100 assert(drive >= 0 && drive < MAX_FLOPPYDRIVES);
101 if (ConfigureParams.DiskImage.szDiskFileName[drive][0])
102 tmpname = ConfigureParams.DiskImage.szDiskFileName[drive];
103 else
104 tmpname = ConfigureParams.DiskImage.szDiskImageDirectory;
105
106 selname = SDLGui_FileSelect("NULL",tmpname, &zip_path, false);
107 if (!selname)
108 return;
109
110 if (File_Exists(selname))
111 {
112 realname = Floppy_SetDiskFileName(drive, selname, zip_path);
113 if (realname)
114 File_ShrinkName(dlgname, realname, floppydlg[diskid].w);
115 }
116 else
117 {
118 Floppy_SetDiskFileNameNone(drive);
119 dlgname[0] = '\0';
120 }
121 if (zip_path)
122 free(zip_path);
123 free(selname);
124 }
125
126
127 /**
128 * Let user browse given directory, set directory if one selected.
129 */
DlgDisk_BrowseDir(char * dlgname,char * confname,int maxlen)130 static void DlgDisk_BrowseDir(char *dlgname, char *confname, int maxlen)
131 {
132 char *str, *selname;
133
134 selname = SDLGui_FileSelect("NULL",confname, NULL, false);
135 if (!selname)
136 return;
137
138 strcpy(confname, selname);
139 free(selname);
140
141 str = strrchr(confname, PATHSEP);
142 if (str != NULL)
143 str[1] = 0;
144 File_CleanFileName(confname);
145 File_ShrinkName(dlgname, confname, maxlen);
146 }
147
148
149 /**
150 * Ask whether new disk should be inserted to A: or B: and if yes, insert.
151 */
DlgFloppy_QueryInsert(char * namea,int ida,char * nameb,int idb,const char * path)152 static void DlgFloppy_QueryInsert(char *namea, int ida, char *nameb, int idb, const char *path)
153 {
154 const char *realname;
155 int diskid, dlgid;
156 char *dlgname;
157
158 SDLGui_CenterDlg(alertdlg);
159 switch (SDLGui_DoDialog(alertdlg, NULL))
160 {
161 case DLGMOUNT_A:
162 dlgname = namea;
163 dlgid = ida;
164 diskid = 0;
165 break;
166 case DLGMOUNT_B:
167 dlgname = nameb;
168 dlgid = idb;
169 diskid = 1;
170 break;
171 default:
172 return;
173 }
174
175 realname = Floppy_SetDiskFileName(diskid, path, NULL);
176 if (realname)
177 File_ShrinkName(dlgname, realname, floppydlg[dlgid].w);
178 }
179
180
181 /**
182 * Show and process the floppy disk image dialog.
183 */
DlgFloppy_Main(void)184 void DlgFloppy_Main(void)
185 {
186 int but, i;
187 char *newdisk;
188 char dlgname[MAX_FLOPPYDRIVES][64], dlgdiskdir[64];
189
190 SDLGui_CenterDlg(floppydlg);
191
192 /* Set up dialog to actual values: */
193
194 /* Disk name A: */
195 if (EmulationDrives[0].bDiskInserted)
196 File_ShrinkName(dlgname[0], ConfigureParams.DiskImage.szDiskFileName[0],
197 floppydlg[FLOPPYDLG_DISKA].w);
198 else
199 dlgname[0][0] = '\0';
200 floppydlg[FLOPPYDLG_DISKA].txt = dlgname[0];
201
202 /* Disk name B: */
203 if (EmulationDrives[1].bDiskInserted)
204 File_ShrinkName(dlgname[1], ConfigureParams.DiskImage.szDiskFileName[1],
205 floppydlg[FLOPPYDLG_DISKB].w);
206 else
207 dlgname[1][0] = '\0';
208 floppydlg[FLOPPYDLG_DISKB].txt = dlgname[1];
209
210 /* Default image directory: */
211 File_ShrinkName(dlgdiskdir, ConfigureParams.DiskImage.szDiskImageDirectory,
212 floppydlg[FLOPPYDLG_IMGDIR].w);
213 floppydlg[FLOPPYDLG_IMGDIR].txt = dlgdiskdir;
214
215 /* Auto insert disk B: */
216 if (ConfigureParams.DiskImage.bAutoInsertDiskB)
217 floppydlg[FLOPPYDLG_AUTOB].state |= SG_SELECTED;
218 else
219 floppydlg[FLOPPYDLG_AUTOB].state &= ~SG_SELECTED;
220
221 /* Write protection */
222 for (i = FLOPPYDLG_PROTOFF; i <= FLOPPYDLG_PROTAUTO; i++)
223 {
224 floppydlg[i].state &= ~SG_SELECTED;
225 }
226 floppydlg[FLOPPYDLG_PROTOFF+ConfigureParams.DiskImage.nWriteProtection].state |= SG_SELECTED;
227
228 /* Fast floppy access */
229 if (ConfigureParams.DiskImage.FastFloppy)
230 floppydlg[FLOPPYDLG_FASTFLOPPY].state |= SG_SELECTED;
231 else
232 floppydlg[FLOPPYDLG_FASTFLOPPY].state &= ~SG_SELECTED;
233
234 /* Enable/disable drives A: and B: */
235 if (ConfigureParams.DiskImage.EnableDriveA)
236 floppydlg[FLOPPYDLG_ENABLE_A].state |= SG_SELECTED;
237 else
238 floppydlg[FLOPPYDLG_ENABLE_A].state &= ~SG_SELECTED;
239
240 if (ConfigureParams.DiskImage.EnableDriveB)
241 floppydlg[FLOPPYDLG_ENABLE_B].state |= SG_SELECTED;
242 else
243 floppydlg[FLOPPYDLG_ENABLE_B].state &= ~SG_SELECTED;
244
245 /* Set drives to single sided or double sided */
246 if (ConfigureParams.DiskImage.DriveA_NumberOfHeads == 2)
247 floppydlg[FLOPPYDLG_HEADS_DS_A].state |= SG_SELECTED;
248 else
249 floppydlg[FLOPPYDLG_HEADS_DS_A].state &= ~SG_SELECTED;
250
251 if (ConfigureParams.DiskImage.DriveB_NumberOfHeads == 2)
252 floppydlg[FLOPPYDLG_HEADS_DS_B].state |= SG_SELECTED;
253 else
254 floppydlg[FLOPPYDLG_HEADS_DS_B].state &= ~SG_SELECTED;
255
256 /* Draw and process the dialog */
257 do
258 {
259 but = SDLGui_DoDialog(floppydlg, NULL);
260 switch (but)
261 {
262 case FLOPPYDLG_EJECTA: /* Eject disk in drive A: */
263 Floppy_SetDiskFileNameNone(0);
264 dlgname[0][0] = '\0';
265 break;
266 case FLOPPYDLG_BROWSEA: /* Choose a new disk A: */
267 DlgDisk_BrowseDisk(dlgname[0], 0, FLOPPYDLG_DISKA);
268 break;
269 case FLOPPYDLG_EJECTB: /* Eject disk in drive B: */
270 Floppy_SetDiskFileNameNone(1);
271 dlgname[1][0] = '\0';
272 break;
273 case FLOPPYDLG_BROWSEB: /* Choose a new disk B: */
274 DlgDisk_BrowseDisk(dlgname[1], 1, FLOPPYDLG_DISKB);
275 break;
276 case FLOPPYDLG_BROWSEIMG:
277 DlgDisk_BrowseDir(dlgdiskdir,
278 ConfigureParams.DiskImage.szDiskImageDirectory,
279 floppydlg[FLOPPYDLG_IMGDIR].w);
280 break;
281 case FLOPPYDLG_CREATEIMG:
282 newdisk = DlgNewDisk_Main();
283 if (newdisk)
284 {
285 DlgFloppy_QueryInsert(dlgname[0], FLOPPYDLG_DISKA,
286 dlgname[1], FLOPPYDLG_DISKB,
287 newdisk);
288 free(newdisk);
289 }
290 break;
291 }
292 if (gui_poll_events()) break;
293 }
294 while (but != FLOPPYDLG_EXIT && but != SDLGUI_QUIT
295 && but != SDLGUI_ERROR && !bQuitProgram);
296
297 /* Read values from dialog: */
298
299 for (i = FLOPPYDLG_PROTOFF; i <= FLOPPYDLG_PROTAUTO; i++)
300 {
301 if (floppydlg[i].state & SG_SELECTED)
302 {
303 ConfigureParams.DiskImage.nWriteProtection = i-FLOPPYDLG_PROTOFF;
304 break;
305 }
306 }
307
308 ConfigureParams.DiskImage.bAutoInsertDiskB = (floppydlg[FLOPPYDLG_AUTOB].state & SG_SELECTED);
309 ConfigureParams.DiskImage.FastFloppy = (floppydlg[FLOPPYDLG_FASTFLOPPY].state & SG_SELECTED);
310 ConfigureParams.DiskImage.EnableDriveA = (floppydlg[FLOPPYDLG_ENABLE_A].state & SG_SELECTED);
311 ConfigureParams.DiskImage.EnableDriveB = (floppydlg[FLOPPYDLG_ENABLE_B].state & SG_SELECTED);
312 ConfigureParams.DiskImage.DriveA_NumberOfHeads = ( (floppydlg[FLOPPYDLG_HEADS_DS_A].state & SG_SELECTED) ? 2 : 1 );
313 ConfigureParams.DiskImage.DriveB_NumberOfHeads = ( (floppydlg[FLOPPYDLG_HEADS_DS_B].state & SG_SELECTED) ? 2 : 1 );
314 }
315