1 /** \file settings_io.c
2 * \brief I/O extension settings that don't go/fit into subwidgets
3 *
4 * \author Bas Wassink <b.wassink@ziggo.nl>
5 */
6
7 /*
8 * $VICERES IOCollisionHandling -vsid
9 * $VICERES CartridgeReset -vsid
10 * $VICERES HummerADC x64dtv
11 */
12
13 /*
14 * This file is part of VICE, the Versatile Commodore Emulator.
15 * See README for copyright notice.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
30 * 02111-1307 USA.
31 *
32 */
33
34 #include "vice.h"
35 #include <gtk/gtk.h>
36
37 #include "machine.h"
38 #include "resources.h"
39 #include "debug_gtk3.h"
40 #include "basewidgets.h"
41 #include "widgethelpers.h"
42 #include "basedialogs.h"
43 #include "cartio.h"
44 #include "cartridge.h"
45 #include "resourcewidgetmanager.h"
46 #include "uisettings.h"
47
48 #include "settings_io.h"
49
50
51 /** \brief Methods of handling I/O collisions
52 */
53 static const vice_gtk3_radiogroup_entry_t io_collision_methods[] = {
54 { "Detach all", IO_COLLISION_METHOD_DETACH_ALL },
55 { "Detach last", IO_COLLISION_METHOD_DETACH_LAST },
56 { "AND values", IO_COLLISION_METHOD_AND_WIRES },
57 { NULL, -1 }
58 };
59
60
61 /** \brief Resource widget manager instance
62 */
63 static resource_widget_manager_t manager;
64
65
66 /** \brief Handler for the "destroy" event of the main widget
67 *
68 * \param[in] widget main widget (unused)
69 * \param[in] data extra even data (unused)
70 */
on_settings_io_destroy(GtkWidget * widget,gpointer data)71 static void on_settings_io_destroy(GtkWidget *widget, gpointer data)
72 {
73 debug_gtk3("calling vice_resource_widget_manager_exit()");
74 vice_resource_widget_manager_exit(&manager);
75 }
76
77
78 /** \brief Create widget to specify I/O collision handling method
79 *
80 * The \a desc is added as a label under the "I/O collision handling" label,
81 * in italics and surrounded with parenthesis.
82 *
83 * \param[in] desc description of the I/O areas involved
84 *
85 * \return GtkGrid
86 */
create_collision_widget(const char * desc)87 static GtkWidget *create_collision_widget(const char *desc)
88 {
89 GtkWidget *grid;
90 GtkWidget *label;
91 GtkWidget *group;
92 char buffer[256];
93
94 grid = gtk_grid_new();
95 gtk_grid_set_column_spacing(GTK_GRID(grid), 16);
96 gtk_grid_set_row_spacing(GTK_GRID(grid), 0);
97
98 label = gtk_label_new("I/O collision handling");
99 gtk_widget_set_halign(label, GTK_ALIGN_START);
100 g_object_set(label, "margin-left", 16, NULL);
101 gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1);
102
103 group = vice_gtk3_resource_radiogroup_new("IOCollisionHandling",
104 io_collision_methods, GTK_ORIENTATION_HORIZONTAL);
105 gtk_grid_set_column_spacing(GTK_GRID(group), 16);
106 gtk_grid_attach(GTK_GRID(grid), group, 1, 0, 1, 1);
107 vice_resource_widget_manager_add_widget(&manager, group, NULL,
108 NULL, NULL, NULL);
109
110 label = gtk_label_new(NULL);
111 g_snprintf(buffer, 256, "<i>(%s)</i>", desc);
112 gtk_label_set_markup(GTK_LABEL(label), buffer);
113
114 gtk_widget_set_halign(label, GTK_ALIGN_START);
115 g_object_set(label, "margin-left", 16, NULL);
116 gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);
117
118
119 gtk_widget_show_all(grid);
120 return grid;
121 }
122
123
124 /** \brief Create check button for "reset-on-cart-change"
125 *
126 * \return GtkCheckButton
127 */
create_cart_reset_widget(void)128 static GtkWidget *create_cart_reset_widget(void)
129 {
130 GtkWidget *check;
131
132 check = vice_gtk3_resource_check_button_new("CartridgeReset",
133 "Reset machine on cartridge change");
134 g_object_set(check, "margin-left", 16, NULL);
135 vice_resource_widget_manager_add_widget(&manager, check, NULL,
136 NULL, NULL, NULL);
137 return check;
138 }
139
140
141 /** \brief Create layout for x64/x64sc
142 *
143 * \param[in,out] grid grid to add widgets to
144 */
create_c64_layout(GtkWidget * grid)145 static void create_c64_layout(GtkWidget *grid)
146 {
147 GtkWidget *collision_widget;
148
149 collision_widget = create_collision_widget("$D000-$DFFF");
150 gtk_grid_attach(GTK_GRID(grid), collision_widget, 0, 1, 3, 1);
151 gtk_grid_attach(GTK_GRID(grid), create_cart_reset_widget(), 0, 2, 3, 1);
152 }
153
154
155 /** \brief Create layout for xscpu64
156 *
157 * \param[in,out] grid grid to add widgets to
158 */
create_scpu64_layout(GtkWidget * grid)159 static void create_scpu64_layout(GtkWidget *grid)
160 {
161 GtkWidget *collision_widget;
162
163 collision_widget = create_collision_widget("$D000-$DFFF");
164 gtk_grid_attach(GTK_GRID(grid), collision_widget, 0, 1, 3, 1);
165 gtk_grid_attach(GTK_GRID(grid), create_cart_reset_widget(), 0, 2, 3, 1);
166 }
167
168
169 /** \brief Create layout for x128
170 *
171 * \param[in,out] grid grid to add widgets to
172 */
create_c128_layout(GtkWidget * grid)173 static void create_c128_layout(GtkWidget *grid)
174 {
175 GtkWidget *collision_widget;
176
177 collision_widget = create_collision_widget("$D000-$DFFF");
178 gtk_grid_attach(GTK_GRID(grid), collision_widget, 0, 1, 3, 1);
179 gtk_grid_attach(GTK_GRID(grid), create_cart_reset_widget(), 0, 2, 3, 1);
180 }
181
182
183
184 /** \brief Create layout for x64dtv
185 *
186 * \param[in,out] grid grid to add widgets to
187 */
create_c64dtv_layout(GtkWidget * grid)188 static void create_c64dtv_layout(GtkWidget *grid)
189 {
190 GtkWidget *hummer;
191
192 hummer = vice_gtk3_resource_check_button_new("HummerADC",
193 "Enable Hummer ADC");
194 g_object_set(hummer, "margin-left", 16, NULL);
195 gtk_grid_attach(GTK_GRID(grid), hummer, 0, 1, 3, 1);
196 vice_resource_widget_manager_add_widget(&manager, hummer, NULL,
197 NULL, NULL, NULL);
198 }
199
200
201 /** \brief Create layout for xvic
202 *
203 * \param[in,out] grid grid to add widgets to
204 */
create_vic20_layout(GtkWidget * grid)205 static void create_vic20_layout(GtkWidget *grid)
206 {
207 GtkWidget *collision_widget;
208
209 collision_widget = create_collision_widget("$9000-$93FF, $9800-$9FFF");
210 gtk_grid_attach(GTK_GRID(grid), collision_widget, 0, 1, 3, 1);
211 gtk_grid_attach(GTK_GRID(grid), create_cart_reset_widget(), 0, 2, 3, 1);
212 }
213
214
215 /** \brief Create layout for xplus4
216 *
217 * \param[in,out] grid grid to add widgets to
218 */
create_plus4_layout(GtkWidget * grid)219 static void create_plus4_layout(GtkWidget *grid)
220 {
221 GtkWidget *collision_widget;
222
223 collision_widget = create_collision_widget("$FD00-$FEFF");
224 gtk_grid_attach(GTK_GRID(grid), collision_widget, 0, 1, 3, 1);
225 gtk_grid_attach(GTK_GRID(grid), create_cart_reset_widget(), 0, 2, 3, 1);
226 }
227
228
229
230 /** \brief Create layout for xpet
231 *
232 * \param[in,out] grid grid to add widgets to
233 */
create_pet_layout(GtkWidget * grid)234 static void create_pet_layout(GtkWidget *grid)
235 {
236 GtkWidget *collision_widget;
237
238 collision_widget = create_collision_widget("$8800-$8FFF, $E900-$EEFF");
239 gtk_grid_attach(GTK_GRID(grid), collision_widget, 0, 1, 3, 1);
240 }
241
242
243 /** \brief Create layout for xcbm5x0/xcbm2
244 *
245 * \param[in,out] grid grid to add widgets to
246 */
create_cbm5x0_layout(GtkWidget * grid)247 static void create_cbm5x0_layout(GtkWidget *grid)
248 {
249 GtkWidget *collision_widget;
250
251 collision_widget = create_collision_widget("$D800-$DFFF");
252 gtk_grid_attach(GTK_GRID(grid), collision_widget, 0, 1, 3, 1);
253 gtk_grid_attach(GTK_GRID(grid), create_cart_reset_widget(), 0, 2, 3, 1);
254 }
255
256
257
258 /** \brief Create widget for generic I/O extension settings
259 *
260 * Creates a widget for generic I/O extension settings and settings that don't
261 * make sense to create a separate widget for (ie stuff that has a single
262 * bool resource or a single "open file" dialog").
263 *
264 * \param[in] parent parent widget
265 *
266 * \return GtkGrid
267 */
settings_io_widget_create(GtkWidget * parent)268 GtkWidget *settings_io_widget_create(GtkWidget *parent)
269 {
270 GtkWidget *grid;
271
272 /*
273 * Initialize and register resource widget manager. The various widgets
274 * register themselves in the create_bla() calls.
275 */
276 vice_resource_widget_manager_init(&manager);
277 ui_settings_set_resource_widget_manager(&manager);
278
279 grid = uihelpers_create_grid_with_label(
280 "Generic I/O extension settings", 3);
281 gtk_grid_set_row_spacing(GTK_GRID(grid), 16);
282
283 switch (machine_class) {
284
285 case VICE_MACHINE_C64: /* fall through */
286 case VICE_MACHINE_C64SC:
287 create_c64_layout(grid);
288 break;
289
290 case VICE_MACHINE_SCPU64:
291 create_scpu64_layout(grid);
292 break;
293
294 case VICE_MACHINE_C128:
295 create_c128_layout(grid);
296 break;
297
298 case VICE_MACHINE_C64DTV:
299 create_c64dtv_layout(grid);
300 break;
301
302 case VICE_MACHINE_VIC20:
303 create_vic20_layout(grid);
304 break;
305
306 case VICE_MACHINE_PLUS4:
307 create_plus4_layout(grid);
308 break;
309
310 case VICE_MACHINE_PET:
311 create_pet_layout(grid);
312 break;
313
314 case VICE_MACHINE_CBM5x0: /* fall through */
315 case VICE_MACHINE_CBM6x0:
316 create_cbm5x0_layout(grid);
317 break;
318
319 default:
320 /* NOP */
321 break;
322 }
323
324 g_signal_connect(grid, "destroy", G_CALLBACK(on_settings_io_destroy),
325 NULL);
326
327 vice_resource_widget_manager_dump(&manager);
328
329 gtk_widget_show_all(grid);
330 return grid;
331 }
332