1 /* libfsemu - a library with emulator support functions
2 * Copyright (C) 2011 Frode Solheim <frode-code@fengestad.no>
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2.1 of the License, or (at
7 * your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12 * License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "dialog.h"
24
25 #include <fs/emu.h>
26 #include <fs/glib.h>
27
28 #include <stdlib.h>
29
30 #ifdef USE_OPENGL
31 #include <fs/ml/opengl.h>
32 #endif
33
34 #include "font.h"
35 #include "menu.h"
36 #include "render.h"
37
38 static GList *g_dialog_stack = NULL;
39 int g_fs_emu_dialog_mode = 0;
40
41 #if 0
42 void fs_emu_dialog_init(void)
43 {
44 fs_log("initialize dialog module\n");
45 }
46 #endif
47
fs_emu_dialog_create(const char * title,const char * affirmative,const char * negative)48 fs_emu_dialog* fs_emu_dialog_create(const char *title,
49 const char *affirmative, const char *negative) {
50 fs_emu_dialog* dialog = g_malloc0(sizeof(fs_emu_dialog));
51 if (title) {
52 dialog->title = g_strdup(title);
53 }
54 if (affirmative) {
55 dialog->affirmative = g_strdup(affirmative);
56 }
57 if (negative) {
58 dialog->negative = g_strdup(negative);
59 }
60 return dialog;
61 }
62
fs_emu_dialog_destroy(fs_emu_dialog * dialog)63 void fs_emu_dialog_destroy(fs_emu_dialog *dialog) {
64 if (dialog->title) {
65 g_free(dialog->title);
66 }
67 if (dialog->affirmative) {
68 g_free(dialog->affirmative);
69 }
70 if (dialog->negative) {
71 g_free(dialog->negative);
72 }
73 for (int i = 0; i < DIALOG_MAX_LINES; i++) {
74 if (dialog->lines[i]) {
75 g_free(dialog->lines[i]);
76 }
77 }
78 g_free(dialog);
79 }
80
fs_emu_dialog_add_option(fs_emu_dialog * dialog,const char * option,int value)81 void fs_emu_dialog_add_option(fs_emu_dialog *dialog, const char *option,
82 int value) {
83 fs_emu_assert_gui_lock();
84 }
85
fs_emu_dialog_set_line(fs_emu_dialog * dialog,int line,const char * text)86 void fs_emu_dialog_set_line(fs_emu_dialog *dialog, int line,
87 const char *text) {
88 if (line < 0 || line >= DIALOG_MAX_LINES) {
89 fs_log("warning: invalid dialog line number");
90 return;
91 }
92 if (dialog->lines[line]) {
93 g_free(dialog->lines[line]);
94 }
95 dialog->lines[line] = g_strdup(text);
96 }
97
fs_emu_dialog_show(fs_emu_dialog * dialog)98 void fs_emu_dialog_show(fs_emu_dialog *dialog) {
99 fs_emu_assert_gui_lock();
100 g_dialog_stack = g_list_append(g_dialog_stack, dialog);
101 g_fs_emu_dialog_mode = 1;
102 }
103
fs_emu_dialog_result(fs_emu_dialog * dialog)104 int fs_emu_dialog_result(fs_emu_dialog *dialog) {
105 return dialog->result;
106 }
107
fs_emu_dialog_dismiss(fs_emu_dialog * dialog)108 void fs_emu_dialog_dismiss(fs_emu_dialog *dialog) {
109 fs_emu_assert_gui_lock();
110 GList* link = g_dialog_stack;
111 while (link) {
112 if (link->data == dialog) {
113 g_dialog_stack = g_list_delete_link(g_dialog_stack, link);
114 break;
115 }
116 link = link->next;
117 }
118 g_fs_emu_dialog_mode = (g_dialog_stack != NULL);
119 }
120
fs_emu_dialog_get_current()121 fs_emu_dialog *fs_emu_dialog_get_current() {
122 fs_emu_assert_gui_lock();
123 fs_emu_dialog *dialog = NULL;
124 GList* link = g_dialog_stack;
125 while (link) {
126 dialog = link->data;
127 link = link->next;
128 }
129 return dialog;
130 }
131
fs_emu_dialog_handle_action(int action,int state)132 void fs_emu_dialog_handle_action(int action, int state) {
133 //printf("dialog-action\n");
134 if (state == 0) {
135 return;
136 }
137 //printf("dialog-action\n");
138 fs_emu_dialog *dialog = fs_emu_dialog_get_current();
139 if (!dialog) {
140 return;
141 }
142
143 //printf("%d %d %d\n", action, ACTION_MENU_PRIMARY, ACTION_MENU_BACK);
144 if (dialog->affirmative && action == ACTION_MENU_PRIMARY) {
145 //printf("..\n");
146 dialog->result = DIALOG_RESULT_AFFIRMATIVE;
147 }
148 else if (dialog->negative && action == ACTION_MENU_BACK) {
149 //printf("...\n");
150 dialog->result = DIALOG_RESULT_NEGATIVE;
151 }
152 }
153
fs_emu_dialog_render()154 void fs_emu_dialog_render() {
155 fs_emu_dialog *dialog = fs_emu_dialog_get_current();
156 if (!dialog) {
157 return;
158 }
159
160 fs_gl_ortho_hd();
161 fs_gl_blending(1);
162 fs_gl_texturing(0);
163 fs_gl_color4f(0.0, 0.0, 0.0, 0.5);
164
165 #ifdef USE_GLES
166 GLfloat vert[] = {
167 0, 0,
168 1920, 0,
169 1920, 1080,
170 0, 1080
171 };
172
173 glEnableClientState(GL_VERTEX_ARRAY);
174 glVertexPointer(2, GL_FLOAT, 0, vert);
175 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
176 #else
177 glBegin(GL_QUADS);
178 glVertex2f(0, 0);
179 glVertex2f(1920, 0);
180 glVertex2f(1920, 1080);
181 glVertex2f(0, 1080);
182 glEnd();
183 #endif
184
185 fs_gl_blending(0);
186
187 int width = 1920 / 2;
188 int height = 480; //1080 / 2;
189 float x1 = (1920 - width) / 2.0;
190 float x2 = x1 + width;
191 float y1 = (1080 - height) / 2.0;
192 float y2 = y1 + height;
193
194 #ifdef USE_GLES
195 GLfloat color2[] = {
196 0.0, 0.4, 0.75, 1.0,
197 0.0, 0.4, 0.75, 1.0,
198 0.0, 0.2, 0.375, 1.0,
199 0.0, 0.2, 0.375, 1.0
200 };
201 GLfloat vert2[] = {
202 x1, y1,
203 x2, y1,
204 x2, y2,
205 x1, y2
206 };
207
208 glEnableClientState(GL_COLOR_ARRAY);
209
210 glColorPointer(4, GL_FLOAT, 0, color2);
211 glVertexPointer(2, GL_FLOAT, 0, vert2);
212 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
213
214 glDisableClientState(GL_COLOR_ARRAY);
215 glDisableClientState(GL_VERTEX_ARRAY);
216 #else
217 glBegin(GL_QUADS);
218 fs_gl_color4f(0.0, 0.4, 0.75, 1.0);
219 glVertex2f(x1, y1);
220 glVertex2f(x2, y1);
221 fs_gl_color4f(0.0, 0.2, 0.375, 1.0);
222 glVertex2f(x2, y2);
223 glVertex2f(x1, y2);
224 glEnd();
225 #endif
226
227 fs_emu_font *font = fs_emu_font_get_menu();
228 int tx = x1 + 50;
229 int ty = y2 - 80;
230 if (dialog->title) {
231 fs_emu_font_render(font, dialog->title,
232 tx, ty, 1.0, 1.0, 1.0, 1.0);
233 ty -= 50;
234 }
235
236 for (int i = 0; i < DIALOG_MAX_LINES; i++) {
237 if (dialog->lines[i]) {
238 fs_emu_font_render(font, dialog->lines[i],
239 tx, ty, 1.0, 1.0, 1.0, 1.0);
240 }
241 ty -= 50;
242 }
243
244 tx = x2;
245 ty = y1 - 50;
246 int tw;
247 if (dialog->affirmative) {
248 fs_emu_font_measure(font, dialog->affirmative, &tw, NULL);
249 tx -= tw;
250 fs_emu_font_render(font, dialog->affirmative,
251 tx, ty, 1.0, 1.0, 1.0, 1.0);
252 tx -= 20;
253 fs_emu_font_measure(font, "<OK>", &tw, NULL);
254 tx -= tw;
255 fs_emu_font_render(font, "<OK>", tx, ty, 1.0, 1.0, 1.0, 1.0);
256 //tx -= 40;
257 }
258 tx = x1;
259 if (dialog->negative) {
260 //fs_emu_font_measure(font, dialog->negative, &tw, NULL);
261 //tx -= tw;
262 tx += fs_emu_font_render(font, "<BK>", tx, ty, 1.0, 1.0, 1.0, 1.0);
263 tx += 20;
264 fs_emu_font_render(font, dialog->negative,
265 tx, ty, 1.0, 1.0, 1.0, 1.0);
266 //fs_emu_font_measure(font, "<BK>", &tw, NULL);
267 //tx -= tw;
268 //tx -= 40;
269 }
270 }
271