Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/yabause/src/gtk/yuimem.c
2 views
1
/* Copyright 2006 Guillaume Duhamel
2
Copyright 2005-2006 Fabien Coulon
3
4
This file is part of Yabause.
5
6
Yabause is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
11
Yabause is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
15
16
You should have received a copy of the GNU General Public License
17
along with Yabause; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
*/
20
21
#include <gtk/gtk.h>
22
#include <gdk/gdkkeysyms.h>
23
24
#include "yuimem.h"
25
#include "settings.h"
26
27
static void yui_mem_class_init (YuiMemClass * klass);
28
static void yui_mem_init (YuiMem * yfe);
29
static void yui_mem_clear (YuiMem * vdp1);
30
static void yui_mem_address_changed (GtkWidget * w, YuiMem * ym);
31
static void yui_mem_content_changed ( GtkCellRendererText *cellrenderertext, gchar *arg1, gchar *arg2, YuiMem *ym);
32
static gboolean yui_mem_pagedown_pressed (GtkWidget *w, gpointer func, gpointer data, gpointer data2, YuiMem *ym);
33
static gboolean yui_mem_pageup_pressed (GtkWidget *w, gpointer func, gpointer data, gpointer data2, YuiMem *ym);
34
static void yui_mem_update (YuiMem * ym);
35
static void yui_mem_combo_changed(GtkWidget * w, YuiMem * ym);
36
static void yui_mem_pagedown_clicked (GtkToolButton * button, YuiMem * ym);
37
static void yui_mem_pageup_clicked (GtkToolButton * button, YuiMem * ym);
38
39
struct { gchar* name; u32 address; } quickAddress[] =
40
{ {"VDP2_VRAM_A0", 0x25E00000 },
41
{"VDP2_VRAM_A1", 0x25E20000 },
42
{"VDP2_VRAM_B0", 0x25E40000 },
43
{"VDP2_VRAM_B1", 0x25E60000 },
44
{"VDP2_CRAM", 0x25F00000 },
45
{"LWRAM", 0x20200000 },
46
{"HWRAM", 0x26000000 },
47
{"SpriteVRAM", 0x25C00000 },
48
{0, 0 } };
49
50
GType yui_mem_get_type (void) {
51
static GType yfe_type = 0;
52
53
if (!yfe_type)
54
{
55
static const GTypeInfo yfe_info =
56
{
57
sizeof (YuiMemClass),
58
NULL, /* base_init */
59
NULL, /* base_finalize */
60
(GClassInitFunc) yui_mem_class_init,
61
NULL, /* class_finalize */
62
NULL, /* class_data */
63
sizeof (YuiMem),
64
0,
65
(GInstanceInitFunc) yui_mem_init,
66
NULL,
67
};
68
69
yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiMem", &yfe_info, 0);
70
}
71
72
return yfe_type;
73
}
74
75
static void yui_mem_class_init (UNUSED YuiMemClass * klass) {
76
}
77
78
static void yui_mem_init (YuiMem * yv) {
79
GtkWidget * view;
80
GtkCellRenderer * renderer;
81
GtkTreeViewColumn * column;
82
GtkAccelGroup *accelGroup;
83
GtkToolItem * comboItem, * upbutton, * downbutton;
84
GtkWidget * testbox, * vbox;
85
gint i;
86
87
gtk_window_set_title(GTK_WINDOW(yv), "Memory dump");
88
89
vbox = gtk_vbox_new(FALSE, 0);
90
gtk_container_add(GTK_CONTAINER(yv), vbox);
91
92
yv->toolbar = gtk_toolbar_new();
93
gtk_toolbar_set_style(GTK_TOOLBAR(yv->toolbar), GTK_TOOLBAR_ICONS);
94
gtk_box_pack_start(GTK_BOX(vbox), yv->toolbar, FALSE, FALSE, 0);
95
96
gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), gtk_separator_tool_item_new(), 0);
97
98
comboItem = gtk_tool_item_new();
99
gtk_tool_item_set_expand(comboItem, FALSE);
100
gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), comboItem, 1);
101
102
downbutton = gtk_tool_button_new_from_stock(GTK_STOCK_GO_DOWN);
103
g_signal_connect(downbutton, "clicked", G_CALLBACK(yui_mem_pagedown_clicked), yv);
104
gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), downbutton, 2);
105
106
upbutton = gtk_tool_button_new_from_stock(GTK_STOCK_GO_UP);
107
g_signal_connect(upbutton, "clicked", G_CALLBACK(yui_mem_pageup_clicked), yv);
108
gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), upbutton, 3);
109
110
yv->quickCombo = gtk_combo_box_entry_new_text();
111
112
gtk_entry_set_width_chars(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(yv->quickCombo))), 8);
113
114
for ( i = 0 ; quickAddress[i].name ; i++ )
115
gtk_combo_box_insert_text( GTK_COMBO_BOX( yv->quickCombo ), i, quickAddress[i].name );
116
gtk_combo_box_set_active( GTK_COMBO_BOX(yv->quickCombo), 0 );
117
g_signal_connect(yv->quickCombo, "changed", G_CALLBACK(yui_mem_combo_changed), yv );
118
g_signal_connect(gtk_bin_get_child(GTK_BIN(yv->quickCombo)), "activate", G_CALLBACK(yui_mem_address_changed), yv );
119
120
testbox = gtk_vbox_new(FALSE, 0);
121
gtk_box_pack_start(GTK_BOX(testbox), yv->quickCombo, TRUE, FALSE, 0);
122
gtk_container_add(GTK_CONTAINER(comboItem), testbox);
123
124
yv->store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
125
view = gtk_tree_view_new_with_model(GTK_TREE_MODEL (yv->store));
126
127
renderer = gtk_cell_renderer_text_new();
128
column = gtk_tree_view_column_new_with_attributes("Address", renderer, "text", 0, NULL);
129
gtk_tree_view_append_column(GTK_TREE_VIEW (view), column);
130
renderer = gtk_cell_renderer_text_new();
131
column = gtk_tree_view_column_new_with_attributes("Dump", renderer, "text", 1, NULL);
132
gtk_tree_view_append_column(GTK_TREE_VIEW (view), column);
133
g_object_set(G_OBJECT(renderer), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL );
134
g_signal_connect(G_OBJECT(renderer), "edited", GTK_SIGNAL_FUNC(yui_mem_content_changed), yv );
135
gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0);
136
137
g_signal_connect(G_OBJECT(yv), "delete-event", GTK_SIGNAL_FUNC(yui_mem_destroy), NULL);
138
139
accelGroup = gtk_accel_group_new ();
140
gtk_accel_group_connect( accelGroup, GDK_Page_Up, 0, 0,
141
g_cclosure_new (G_CALLBACK(yui_mem_pageup_pressed), yv, NULL) );
142
gtk_accel_group_connect( accelGroup, GDK_Page_Down, 0, 0,
143
g_cclosure_new (G_CALLBACK(yui_mem_pagedown_pressed), yv, NULL) );
144
gtk_window_add_accel_group( GTK_WINDOW( yv ), accelGroup );
145
146
yv->address = 0;
147
yv->wLine = 8;
148
149
gtk_window_set_default_size(GTK_WINDOW(yv), 300, -1);
150
}
151
152
GtkWidget * yui_mem_new(YuiWindow * y) {
153
GtkWidget * dialog;
154
YuiMem * yv;
155
156
dialog = GTK_WIDGET(g_object_new(yui_mem_get_type(), NULL));
157
yv = YUI_MEM(dialog);
158
159
yv->yui = y;
160
161
if (!( yv->yui->state & YUI_IS_INIT )) {
162
yui_window_run(yv->yui);
163
yui_window_pause(yv->yui);
164
}
165
166
{
167
GtkToolItem * play_button, * pause_button;
168
169
play_button = gtk_tool_button_new_from_stock("run");
170
gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "run"), GTK_WIDGET(play_button));
171
gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(play_button), 0);
172
173
pause_button = gtk_tool_button_new_from_stock("pause");
174
gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "pause"), GTK_WIDGET(pause_button));
175
gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(pause_button), 1);
176
}
177
178
yv->paused_handler = g_signal_connect_swapped(yv->yui, "paused", G_CALLBACK(yui_mem_update), yv);
179
yv->running_handler = g_signal_connect_swapped(yv->yui, "running", G_CALLBACK(yui_mem_clear), yv);
180
181
if ((yv->yui->state & (YUI_IS_RUNNING | YUI_IS_INIT)) == YUI_IS_INIT)
182
yui_mem_update(yv);
183
184
gtk_widget_show_all(GTK_WIDGET(yv));
185
186
return dialog;
187
}
188
189
void yui_mem_destroy(YuiMem * ym) {
190
g_signal_handler_disconnect(ym->yui, ym->running_handler);
191
g_signal_handler_disconnect(ym->yui, ym->paused_handler);
192
193
gtk_widget_destroy(GTK_WIDGET(ym));
194
}
195
196
static void yui_mem_clear(YuiMem * vdp1) {
197
}
198
199
static void yui_mem_address_changed(GtkWidget * w, YuiMem * ym) {
200
sscanf(gtk_entry_get_text(GTK_ENTRY(w)), "%x", &ym->address);
201
yui_mem_update(ym);
202
}
203
204
static void yui_mem_combo_changed(GtkWidget * w, YuiMem * ym) {
205
206
gint i = gtk_combo_box_get_active( GTK_COMBO_BOX(w) );
207
208
if (i > -1) {
209
ym->address = quickAddress[i].address;
210
yui_mem_update(ym);
211
}
212
}
213
214
static gint hexaDigitToInt( gchar c ) {
215
216
if (( c >= '0' )&&( c <= '9' )) return c-'0';
217
if (( c >= 'a' )&&( c <= 'f' )) return c-'a' + 0xA;
218
if (( c >= 'A' )&&( c <= 'F' )) return c-'A' + 0xA;
219
return -1;
220
}
221
222
static gboolean yui_mem_pageup_pressed(GtkWidget *w, gpointer func, gpointer data, gpointer data2, YuiMem *ym) {
223
224
ym->address -= 2*ym->wLine;
225
yui_mem_update(ym);
226
227
return TRUE;
228
}
229
230
static gboolean yui_mem_pagedown_pressed(GtkWidget *w, gpointer func, gpointer data, gpointer data2, YuiMem *ym) {
231
232
ym->address += 2*ym->wLine;
233
yui_mem_update(ym);
234
235
return TRUE;
236
}
237
238
static void yui_mem_pagedown_clicked (GtkToolButton * button, YuiMem * ym) {
239
ym->address += 2*ym->wLine;
240
yui_mem_update(ym);
241
}
242
243
static void yui_mem_pageup_clicked (GtkToolButton * button, YuiMem * ym) {
244
ym->address -= 2*ym->wLine;
245
yui_mem_update(ym);
246
}
247
248
static void yui_mem_content_changed( GtkCellRendererText *cellrenderertext,
249
gchar *arg1,
250
gchar *arg2,
251
YuiMem *ym) {
252
/* dump line <arg1> has been modified - new content is <arg2> */
253
254
GtkTreeIter iter;
255
gint i = atoi(arg1);
256
gint j,k;
257
gchar *curs;
258
u32 addr = ym->address + i*ym->wLine;
259
260
gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( ym->store ), &iter, arg1 );
261
262
/* check the format : wLine*2 hexa digits */
263
for ( curs = arg2, j=0 ; *curs ; curs++ )
264
if ( hexaDigitToInt( *curs ) != -1 ) j++;
265
266
if ( j != ym->wLine * 2 ) return;
267
268
/* convert */
269
for ( curs = arg2, k=-1 ; *curs ; curs++ ) {
270
271
if ( hexaDigitToInt( *curs )!=-1 ) {
272
273
if ( k==-1 ) k = hexaDigitToInt( *curs );
274
else { MappedMemoryWriteByte( addr++, 16*k + hexaDigitToInt( *curs ) ); k = -1;
275
}
276
}
277
}
278
yui_window_invalidate(ym->yui);
279
}
280
281
static void yui_mem_update(YuiMem * ym) {
282
int i, j;
283
GtkTreeIter iter;
284
char address[10];
285
char dump[30];
286
287
gtk_list_store_clear(ym->store);
288
289
for(i = 0;i < 6;i++) {
290
sprintf(address, "%08x", ym->address + (8 * i));
291
for(j = 0;j < 8;j++) {
292
sprintf(dump + (j * 3), "%02x ", MappedMemoryReadByte(ym->address + (8 * i) + j));
293
}
294
295
gtk_list_store_append(ym->store, &iter);
296
gtk_list_store_set(GTK_LIST_STORE(ym->store ), &iter, 0, address, 1, dump, -1);
297
}
298
299
sprintf( address, "%08X", ym->address );
300
gtk_entry_set_text( GTK_ENTRY(gtk_bin_get_child(GTK_BIN(ym->quickCombo))), address );
301
}
302
303