1 /* Hey EMACS -*- linux-c -*- */
2 /* $Id: fs_misc.c 2840 2009-05-08 20:43:47Z kevinkofler $ */
3
4 /* TiEmu - Tiemu Is an EMUlator
5 *
6 * Copyright (c) 2000-2001, Thomas Corvazier, Romain Lievin
7 * Copyright (c) 2001-2003, Romain Lievin
8 * Copyright (c) 2003, Julien Blache
9 * Copyright (c) 2004, Romain Li�vin
10 * Copyright (c) 2005-2009, Romain Li�vin, Kevin Kofler
11 * Copyright (c) 2005, Christian Walther (patches for Mac OS-X port)
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
24 */
25
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif /* */
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <glib.h>
33 #include <gtk/gtk.h>
34
35 #include "intl.h"
36 #include "filesel.h"
37 #include "skinops.h"
38 #include "refresh.h"
39 #include "paths.h"
40 #include "struct.h"
41 #include "ti68k_int.h"
42 #include "dboxes.h"
43 #include "calc.h"
44 #include "rcfile.h"
45 #include "pbars.h"
46 #include "tie_error.h"
47 #include "dbg_all.h"
48 #include "files.h"
49 #include "ti68k_err.h"
50 //"fs_misc.h"
51
display_skin_dbox(void)52 gint display_skin_dbox(void)
53 {
54 const gchar *filename;
55
56 filename = (char *)create_fsel(inst_paths.skin_dir, NULL, "*.skn", FALSE);
57 if (!filename)
58 {
59 return 0;
60 }
61
62 // Load new skin
63 g_free(options.skin_file);
64 options.skin_file = g_strdup(filename);
65
66 hid_change_skin(options.skin_file);
67
68 return 0;
69 }
70
fs_load_state(const char * filename)71 int fs_load_state(const char *filename)
72 {
73 int err;
74
75 g_free(params.sav_file);
76 params.sav_file = g_strdup(filename);
77
78 err = ti68k_state_load(params.sav_file);
79 if(err == ERR_STATE_MATCH)
80 {
81 gchar *rf, *tf;
82 int ret = msg_box2(_("Warning"),
83 _("The state image you are attempting to load does not match the current running image. Press OK if you want TiEmu to automatically load the corresponding image or Cancel to abort."));
84
85 if(ret == BUTTON2) //cancel
86 return 0;
87
88 ti68k_state_parse(filename, &rf, &tf);
89
90 if(!ti68k_is_a_img_file(rf))
91 return 0;
92
93 // Set tib file and image
94 g_free(params.tib_file);
95 params.tib_file = tf;
96
97 g_free(params.rom_file);
98 params.rom_file = rf;
99
100 // Restart engine by exiting the GTK loop
101 while(gtk_events_pending()) gtk_main_iteration();
102 gtk_main_quit();
103 }
104 else
105 handle_error();
106
107 return 0;
108 }
109
display_load_state_dbox(void)110 gint display_load_state_dbox(void)
111 {
112 const gchar *filename;
113
114 // get filename
115 filename = create_fsel(inst_paths.img_dir, NULL, "*.sav", FALSE);
116 if (!filename)
117 return 0;
118
119 fs_load_state(filename);
120
121 return 0;
122 }
123
display_save_state_dbox(void)124 gint display_save_state_dbox(void)
125 {
126 const gchar *filename;
127 int err;
128 gchar *basename;
129 gchar *dot;
130 gchar *pattern;
131
132 // get filename
133 basename = g_path_get_basename(params.rom_file);
134 dot = strrchr(basename, '.');
135 if(dot != NULL)
136 *dot = '\0';
137 pattern = g_strconcat(basename, ".sav", NULL);
138 g_free(basename);
139
140 filename = create_fsel(inst_paths.img_dir, pattern, "*.sav", TRUE);
141 g_free(pattern);
142 if (!filename)
143 return 0;
144
145 g_free(params.sav_file);
146 params.sav_file = g_strdup(filename);
147 err = ti68k_state_save(params.sav_file);
148 handle_error();
149
150 if(!rcfile_exist())
151 {
152 rcfile_write();
153
154 #ifdef __WIN32__
155 msg_box1(_("Information"),
156 _("You do not seem to have saved your settings. Configuration file saved (in tiemu.ini)."));
157 #else
158 msg_box1(_("Information"),
159 _("You do not seem to have saved your settings. Configuration file saved (in ~/.tiemu)."));
160 #endif
161 }
162
163 return 0;
164 }
165
fs_send_file(const gchar * filename)166 void fs_send_file(const gchar *filename)
167 {
168 int err;
169
170 // set pbar title
171 if(tifiles_file_is_flash(filename))
172 {
173 create_pbar_(FNCT_SEND_APP, _("Sending app(s)"));
174 }
175 else if(tifiles_file_is_group(filename))
176 {
177 create_pbar_(FNCT_SEND_VAR, _("Sending var(s)"));
178 }
179 else if(tifiles_file_is_backup(filename))
180 {
181 create_pbar_(FNCT_SEND_BACKUP, _("Restoring"));
182 }
183 else if(tifiles_file_is_single(filename))
184 {
185 create_pbar_(FNCT_SEND_VAR, _("Sending var(s)"));
186 }
187 else if(tifiles_file_is_tigroup(filename))
188 {
189 create_pbar_type5(_("Restoring"));
190 }
191
192 // note that core is currently not bkpt-interruptible when
193 // transferring file
194 GTK_REFRESH();
195 err = ti68k_linkport_send_file(filename);
196 handle_error();
197 destroy_pbar();
198 }
199
fs_send_files(gchar ** filenames)200 int fs_send_files(gchar **filenames)
201 {
202 gchar **ptr;
203 int i, l;
204
205 // check extension and send
206 for(ptr = filenames, l = 0; *ptr; ptr++, l++);
207 for(ptr = filenames, i = 0; *ptr; ptr++, i++)
208 {
209 if(!tifiles_file_is_ti(*ptr) || (!tifiles_calc_is_ti9x(tifiles_file_get_model(*ptr)) &&
210 !tifiles_file_is_tigroup(*ptr)))
211 {
212 msg_box1(_("Error"), _("This file is not a valid TI file."));
213 g_strfreev(filenames);
214 return -1;
215 }
216
217 fs_send_file(*ptr);
218 }
219
220 return 0;
221 }
222
display_send_files_dbox(void)223 gint display_send_files_dbox(void)
224 {
225 const gchar *ext;
226 gchar **filenames;
227 static gchar *folder = NULL;
228 int ret = 0;
229
230 // Check for null cable
231 if(linkp.cable_model != CABLE_ILP)
232 {
233 int ret, err;
234 gchar *str;
235
236 str = g_strdup_printf(_("The current link cable <%s> port <%s> does not allow direct file loading. Do you let me change link port settings to allow direct file loading?"),
237 ticables_model_to_string(linkp.cable_model), ticables_port_to_string(linkp.cable_port));
238
239 ret= msg_box2(_("Warning"), str);
240 g_free(str);
241
242 if(ret == BUTTON2)
243 return -1;
244
245 // reconfigure link port
246 ti68k_linkport_unconfigure();
247
248 linkp.cable_model = CABLE_ILP;
249 linkp.cable_port = PORT_0;
250
251 err = ti68k_linkport_reconfigure();
252 handle_error();
253 }
254
255 // set mask
256 switch(tihw.calc_type)
257 {
258 case TI92:
259 ext = "*.92?";
260 break;
261 default:
262 ext = "*.89?;*.92?;*.9x?;*.9X?;*.v2?;*.V2?;*.tig";
263 break;
264 }
265
266 // get filename
267 if(folder == NULL)
268 folder = g_strdup(inst_paths.base_dir);
269
270 filenames = create_fsels(folder, NULL, (char *)ext);
271 if(!filenames)
272 return 0;
273
274 // keep folder
275 g_free(folder);
276 folder = g_path_get_dirname(filenames[0]);
277
278 ret = fs_send_files(filenames);
279 g_strfreev(filenames);
280
281 return ret;
282 }
283
display_recv_files_dbox(const char * src,const char * dst)284 int display_recv_files_dbox(const char *src, const char *dst)
285 {
286 const gchar *fn;
287 gchar *src_folder;
288 gchar *dst_folder;
289 gchar *basename;
290 gchar *ext;
291
292 // get file components
293 src_folder = g_path_get_dirname(src);
294 dst_folder = inst_paths.home_dir;
295 basename = g_path_get_basename(dst);
296
297 // set mask
298 switch(tihw.calc_type)
299 {
300 case TI92:
301 ext = "*.92?";
302 break;
303 default:
304 ext = "*.89?;*.92?;*.9x?;*.9X?;*.v2?;*.V2?";
305 break;
306 }
307
308 fn = create_fsel(dst_folder, basename, ext, TRUE);
309 if (fn)
310 tiemu_file_move_with_check(src, fn);
311 else
312 tiemu_file_delete(src);
313
314 g_free(src_folder);
315 g_free(basename);
316
317 return 0;
318 }
319
320 #ifndef NO_GDB
fs_send_file_and_debug_info(const gchar * filename)321 void fs_send_file_and_debug_info(const gchar *filename)
322 {
323 const gchar *ext;
324 FileContent *metadata;
325
326 fs_send_file(filename);
327
328 ext = strrchr(filename, '.');
329 if (ext)
330 {
331 gchar *temp;
332 *(char *)ext = 0;
333 temp = g_strconcat(filename, ".dbg", NULL);
334 #ifdef WIN32
335 symfile = g_locale_from_utf8(temp,-1,NULL,NULL,NULL);
336 g_free(temp);
337 #else
338 symfile = temp;
339 #endif
340 *(char *)ext = '.';
341 }
342
343 metadata = tifiles_content_create_regular(CALC_TI89);
344 if (!tifiles_file_read_regular(filename, metadata))
345 {
346 if (metadata->num_entries > 0)
347 {
348 int handle = sym_find_handle (metadata->entries[0]->folder, metadata->entries[0]->name);
349 if (handle)
350 ti68k_bkpt_add_pgmentry (handle);
351 }
352 }
353 tifiles_content_delete_regular(metadata);
354 }
355
display_debug_dbox(void)356 gint display_debug_dbox(void)
357 {
358 const gchar *filename;
359 const gchar *ext;
360 static gchar *folder = NULL;
361
362 // set mask
363 switch(tihw.calc_type)
364 {
365 case TI92:
366 ext = "*.92?";
367 break;
368 default:
369 ext = "*.89?;*.92?;*.9x?;*.v2?";
370 break;
371 }
372
373 // get filename
374 if(folder == NULL)
375 folder = g_strdup(inst_paths.base_dir);
376
377 filename = (char *)create_fsel(folder, NULL, (char *)ext, FALSE);
378 if (!filename)
379 {
380 return 0;
381 }
382
383 // keep folder
384 g_free(folder);
385 folder = g_path_get_dirname(filename);
386
387 // check extension
388 if(!tifiles_file_is_ti(filename) ||
389 !tifiles_calc_is_ti9x(tifiles_file_get_model(filename)))
390 {
391 msg_box1(_("Error"), _("This file is not a valid TI file."));
392 return -1;
393 }
394
395 fs_send_file_and_debug_info(filename);
396
397 return 0;
398 }
399 #else
fs_send_file_and_debug_info(const gchar * filename)400 void fs_send_file_and_debug_info(const gchar *filename)
401 {
402 fs_send_file(filename);
403 }
404 #endif
405
406 extern int dbgromcall_refresh_window(void);
407
display_set_tib_dbox(void)408 gint display_set_tib_dbox(void)
409 {
410 const gchar *filename;
411 gchar *path, *name;
412 int err;
413
414 // get filename
415 filename = create_fsel(inst_paths.base_dir, NULL, "*.89u;*.9xu;*.v2u;*.tib", FALSE);
416 if (!filename)
417 return 0;
418
419 if(!ti68k_is_a_tib_file(filename))
420 {
421 msg_box1(_("Error"), _("Does not seem to be an upgrade."));
422 return -1;
423 }
424
425 path = g_path_get_dirname(filename);
426 name = g_path_get_basename(filename);
427
428 // set tib file
429 g_free(params.tib_file);
430 params.tib_file = g_strconcat(path, G_DIR_SEPARATOR_S, name, NULL);
431 g_free(path); g_free(name);
432
433 err = ti68k_load_upgrade(params.tib_file);
434 handle_error();
435 if(err)
436 {
437 msg_box1(_("Error"), _("Cannot load the upgrade."));
438 return -1;
439 }
440
441 // update ROM calls list
442 dbgromcall_refresh_window();
443
444 // simply reset, don't restart
445 ti68k_reset();
446
447 return 0;
448 }
449
import_romversion(const char * filename)450 int import_romversion(const char *filename)
451 {
452 char *dstname;
453 int err;
454
455 if(ti68k_is_a_rom_file(filename))
456 {
457 err = ti68k_convert_rom_to_image(filename, inst_paths.img_dir, &dstname);
458 handle_error();
459 g_free(dstname);
460 }
461 else if(ti68k_is_a_tib_file(filename))
462 {
463 #ifdef _MSC_VER
464 IMG_INFO infos = {0};
465 #else
466 IMG_INFO infos = {};
467 #endif
468 int err = ti68k_get_tib_infos(filename, &infos, 0);
469 int hw_type = HW2;
470
471 if(infos.calc_type == TI92p || infos.calc_type == TI89)
472 {
473 int ret = msg_box3(_("HW type"),
474 _("The FLASH upgrade can be imported as HW1 or HW2. Please choose..."),
475 "HW1", "HW2", "Default");
476 if(ret == BUTTON1)
477 hw_type = HW1;
478 else if(ret == BUTTON2)
479 hw_type = HW2;
480 }
481 else if(infos.calc_type == TI89t)
482 {
483 int ret = msg_box3(_("HW type"),
484 _("The FLASH upgrade can be imported as HW3 or HW4. Please choose..."),
485 "HW3", "HW4", "Default");
486
487 hw_type = HW3; // default is HW3 for the Titanium, there's no Titanium HW2
488
489 if(ret == BUTTON1)
490 hw_type = HW3;
491 else if(ret == BUTTON2)
492 hw_type = HW4;
493 }
494
495 // fake rom
496 err = ti68k_convert_tib_to_image(filename, inst_paths.img_dir, &dstname, hw_type);
497 handle_error();
498 g_free(dstname);
499 }
500 else
501 {
502 msg_box1(_("Error"), _("This is not a valid file"));
503 return -1;
504 }
505
506 return 0;
507 }
508
display_import_romversion_dbox(void)509 gint display_import_romversion_dbox(void)
510 {
511 const gchar *filename;
512
513 // get filename
514 filename = create_fsel(inst_paths.base_dir, NULL, "*.rom;*.89u;*.9xu;*.v2u;*.tib", FALSE);
515 if (!filename)
516 return 0;
517
518 return import_romversion(filename);;
519 }
520
521
522