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