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