Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/yabause/src/gtk/yuivdp2.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
23
#include "yuivdp2.h"
24
#include "../vdp2.h"
25
#include "../yabause.h"
26
#include "settings.h"
27
#include "../vdp2debug.h"
28
#include "yuiviewer.h"
29
30
static void yui_vdp2_sync(GtkAction * action, YuiVdp2 * yv);
31
static const char * yui_vdp2_action_names[] = { NULL, "toggle_nbg0", "toggle_nbg1", "toggle_nbg2", "toggle_nbg3", "toggle_rbg0" };
32
33
static void yui_vdp2_class_init (YuiVdp2Class * klass);
34
static void yui_vdp2_init (YuiVdp2 * yfe);
35
static void yui_vdp2_clear(YuiVdp2 * vdp2);
36
static void yui_vdp2_view_cursor_changed(GtkWidget * view, YuiVdp2 * vdp2);
37
static void yui_vdp2_draw(YuiVdp2 * vdp2, u32 * texture, int w, int h);
38
39
GType yui_vdp2_get_type (void) {
40
static GType yfe_type = 0;
41
42
if (!yfe_type)
43
{
44
static const GTypeInfo yfe_info =
45
{
46
sizeof (YuiVdp2Class),
47
NULL, /* base_init */
48
NULL, /* base_finalize */
49
(GClassInitFunc) yui_vdp2_class_init,
50
NULL, /* class_finalize */
51
NULL, /* class_data */
52
sizeof (YuiVdp2),
53
0,
54
(GInstanceInitFunc) yui_vdp2_init,
55
NULL,
56
};
57
58
yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiVdp2", &yfe_info, 0);
59
}
60
61
return yfe_type;
62
}
63
64
static void yui_vdp2_class_init (UNUSED YuiVdp2Class * klass) {
65
}
66
67
static void yui_vdp2_toggle(GtkCellRendererToggle * crt, const gchar * path, YuiVdp2 * yv) {
68
int val;
69
GtkAction * action = NULL;
70
71
sscanf(path, "%d", &val);
72
if (! yui_vdp2_action_names[val]) return;
73
74
action = gtk_action_group_get_action(yv->yui->action_group, yui_vdp2_action_names[val]);
75
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), ! gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)));
76
}
77
78
static void yui_vdp2_sync(GtkAction * action, YuiVdp2 * yv) {
79
GtkTreeIter iter;
80
const gchar * name;
81
82
name = gtk_action_get_name(action) + 7;
83
84
if (!strcmp("nbg0", name))
85
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "1");
86
else if (!strcmp("nbg1", name))
87
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "2");
88
else if (!strcmp("nbg2", name))
89
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "3");
90
else if (!strcmp("nbg3", name))
91
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "4");
92
else if (!strcmp("rbg0", name))
93
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "5");
94
95
gtk_list_store_set(yv->store, &iter, 1, gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)), -1);
96
}
97
98
static void yui_vdp2_init (YuiVdp2 * yv) {
99
GtkWidget * text;
100
GtkWidget * scroll;
101
GtkWidget * box, * box2;
102
GtkWidget * hpane;
103
GtkWidget * view;
104
const char * screens[] = { "General", "NBG0/RBG1", "NBG1", "NBG2", "NBG3", "RBG0" };
105
unsigned int i;
106
107
gtk_window_set_title(GTK_WINDOW(yv), "VDP2");
108
109
box = gtk_vbox_new(FALSE, 0);
110
gtk_container_set_border_width(GTK_CONTAINER(box), 0);
111
gtk_container_add(GTK_CONTAINER(yv), box);
112
113
yv->toolbar = gtk_toolbar_new();
114
gtk_toolbar_set_style(GTK_TOOLBAR(yv->toolbar), GTK_TOOLBAR_ICONS);
115
gtk_box_pack_start(GTK_BOX(box), yv->toolbar, FALSE, FALSE, 0);
116
117
hpane = gtk_hpaned_new();
118
gtk_container_add(GTK_CONTAINER(box), hpane);
119
120
yv->store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN);
121
view = gtk_tree_view_new_with_model(GTK_TREE_MODEL (yv->store));
122
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
123
{
124
GtkWidget * scroll;
125
GtkCellRenderer *renderer;
126
GtkTreeViewColumn *column;
127
128
scroll = gtk_scrolled_window_new(NULL, NULL);
129
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
130
131
renderer = gtk_cell_renderer_text_new();
132
column = gtk_tree_view_column_new_with_attributes("Command", renderer, "text", 0, NULL);
133
gtk_tree_view_append_column(GTK_TREE_VIEW (view), column);
134
135
renderer = gtk_cell_renderer_toggle_new();
136
gtk_cell_renderer_toggle_set_activatable(GTK_CELL_RENDERER_TOGGLE(renderer), TRUE);
137
g_signal_connect(renderer, "toggled", G_CALLBACK(yui_vdp2_toggle), yv);
138
column = gtk_tree_view_column_new_with_attributes("Command", renderer, "active", 1, NULL);
139
gtk_tree_view_append_column(GTK_TREE_VIEW (view), column);
140
141
gtk_container_add(GTK_CONTAINER(scroll), view);
142
gtk_paned_pack1(GTK_PANED(hpane), scroll, FALSE, TRUE);
143
}
144
g_signal_connect(view, "cursor-changed", G_CALLBACK(yui_vdp2_view_cursor_changed), yv);
145
146
scroll = gtk_scrolled_window_new(NULL, NULL);
147
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
148
gtk_paned_pack2(GTK_PANED(hpane), scroll, TRUE, TRUE);
149
box2 = gtk_vpaned_new();
150
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), box2);
151
152
for(i = 0;i < (sizeof(screens) / sizeof(screens[0]));i++) {
153
GtkTreeIter iter;
154
gtk_list_store_append(yv->store, &iter);
155
gtk_list_store_set(yv->store, &iter, 0, screens[i], -1);
156
}
157
158
text = gtk_text_view_new();
159
gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
160
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text), FALSE);
161
{
162
GtkWidget * scroll = gtk_scrolled_window_new(NULL, NULL);
163
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
164
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), text);
165
gtk_paned_pack1(GTK_PANED(box2), scroll, FALSE, TRUE);
166
}
167
168
yv->buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
169
170
yv->image = yui_viewer_new();
171
{
172
GtkWidget * scroll = gtk_scrolled_window_new(NULL, NULL);
173
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
174
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), yv->image);
175
gtk_paned_pack2(GTK_PANED(box2), scroll, TRUE, TRUE);
176
}
177
178
gtk_window_set_default_size(GTK_WINDOW(yv), 500, 450);
179
180
gtk_paned_set_position(GTK_PANED(hpane), 120);
181
182
g_signal_connect(G_OBJECT(yv), "delete-event", GTK_SIGNAL_FUNC(yui_vdp2_destroy), NULL);
183
}
184
185
GtkWidget * yui_vdp2_new(YuiWindow * y) {
186
GtkWidget * dialog;
187
YuiVdp2 * yv;
188
int i;
189
190
dialog = GTK_WIDGET(g_object_new(yui_vdp2_get_type(), NULL));
191
yv = YUI_VDP2(dialog);
192
193
yv->yui = y;
194
195
if (!( yv->yui->state & YUI_IS_INIT )) {
196
yui_window_run(yv->yui);
197
yui_window_pause(yv->yui);
198
}
199
200
{
201
GtkToolItem * play_button, * pause_button;
202
203
play_button = gtk_tool_button_new_from_stock("run");
204
gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "run"), GTK_WIDGET(play_button));
205
gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(play_button), -1);
206
207
pause_button = gtk_tool_button_new_from_stock("pause");
208
gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "pause"), GTK_WIDGET(pause_button));
209
gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(pause_button), -1);
210
}
211
yv->paused_handler = g_signal_connect_swapped(yv->yui, "paused", G_CALLBACK(yui_vdp2_update), yv);
212
yv->running_handler = g_signal_connect_swapped(yv->yui, "running", G_CALLBACK(yui_vdp2_clear), yv);
213
214
for(i = 0;i < (sizeof(yui_vdp2_action_names) / sizeof(yui_vdp2_action_names[0]));i++) {
215
GtkAction * action;
216
217
if (! yui_vdp2_action_names[i]) continue;
218
219
action = gtk_action_group_get_action(yv->yui->action_group, yui_vdp2_action_names[i]);
220
yui_vdp2_sync(action, yv);
221
g_signal_connect(action, "toggled", G_CALLBACK(yui_vdp2_sync), yv);
222
}
223
224
if ((yv->yui->state & (YUI_IS_RUNNING | YUI_IS_INIT)) == YUI_IS_INIT)
225
yui_vdp2_update(yv);
226
227
gtk_widget_show_all(GTK_WIDGET(yv));
228
229
return dialog;
230
}
231
232
void yui_vdp2_update(YuiVdp2 * vdp2) {
233
gchar nameTemp[VDP2_DEBUG_STRING_SIZE];
234
gboolean isscrenabled;
235
236
yui_viewer_clear(YUI_VIEWER(vdp2->image));
237
238
switch(vdp2->cursor) {
239
case 0:
240
Vdp2DebugStatsGeneral(nameTemp, &isscrenabled);
241
break;
242
case 1:
243
Vdp2DebugStatsNBG0(nameTemp, &isscrenabled);
244
break;
245
case 2:
246
Vdp2DebugStatsNBG1(nameTemp, &isscrenabled);
247
break;
248
case 3:
249
Vdp2DebugStatsNBG2(nameTemp, &isscrenabled);
250
break;
251
case 4:
252
Vdp2DebugStatsNBG3(nameTemp, &isscrenabled);
253
break;
254
case 5:
255
Vdp2DebugStatsRBG0(nameTemp, &isscrenabled);
256
break;
257
}
258
259
if (vdp2->cursor > 0) {
260
u32 * texture;
261
int w, h;
262
texture = Vdp2DebugTexture(vdp2->cursor - 1, &w, &h);
263
yui_vdp2_draw(vdp2, texture, w, h);
264
}
265
266
if (isscrenabled) {
267
gtk_text_buffer_set_text(vdp2->buffer, nameTemp, -1);
268
} else {
269
gtk_text_buffer_set_text(vdp2->buffer, "", -1);
270
}
271
}
272
273
void yui_vdp2_destroy(YuiVdp2 * vdp2) {
274
g_signal_handler_disconnect(vdp2->yui, vdp2->paused_handler);
275
g_signal_handler_disconnect(vdp2->yui, vdp2->running_handler);
276
gtk_widget_destroy(GTK_WIDGET(vdp2));
277
}
278
279
static void yui_vdp2_clear(YuiVdp2 * vdp2) {
280
gtk_text_buffer_set_text(vdp2->buffer, "", -1);
281
}
282
283
void yui_vdp2_view_cursor_changed(GtkWidget * view, YuiVdp2 * vdp2) {
284
GtkTreePath * path;
285
gchar * strpath;
286
int i;
287
288
gtk_tree_view_get_cursor(GTK_TREE_VIEW(view), &path, NULL);
289
290
if (path) {
291
strpath = gtk_tree_path_to_string(path);
292
293
sscanf(strpath, "%i", &i);
294
295
vdp2->cursor = i;
296
297
yui_vdp2_update(vdp2);
298
299
g_free(strpath);
300
gtk_tree_path_free(path);
301
}
302
}
303
304
static void yui_vdp2_draw(YuiVdp2 * vdp2, u32 * texture, int w, int h) {
305
GdkPixbuf * pixbuf;
306
int rowstride;
307
308
if ((texture != NULL) && (w > 0) && (h > 0)) {
309
rowstride = w * 4;
310
rowstride += (rowstride % 4)? (4 - (rowstride % 4)): 0;
311
pixbuf = gdk_pixbuf_new_from_data((const guchar *) texture, GDK_COLORSPACE_RGB, TRUE, 8,
312
w, h, rowstride, yui_texture_free, NULL);
313
314
yui_viewer_draw_pixbuf(YUI_VIEWER(vdp2->image), pixbuf, w, h);
315
316
g_object_unref(pixbuf);
317
}
318
}
319
320