Misc.
[neverball] / ball / st_save.c
1 /*
2  * Copyright (C) 2003 Robert Kooima
3  *
4  * NEVERBALL is  free software; you can redistribute  it and/or modify
5  * it under the  terms of the GNU General  Public License as published
6  * by the Free  Software Foundation; either version 2  of the License,
7  * or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT  ANY  WARRANTY;  without   even  the  implied  warranty  of
11  * MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU
12  * General Public License for more details.
13  */
14
15 #include <string.h>
16
17 #include "gui.h"
18 #include "game.h"
19 #include "util.h"
20 #include "audio.h"
21 #include "config.h"
22 #include "demo.h"
23 #include "st_shared.h"
24
25 #include "st_save.h"
26
27 extern struct state st_save;
28 extern struct state st_clobber;
29 static char filename[MAXNAM];
30
31 /*---------------------------------------------------------------------------*/
32
33 static struct state *ok_state;
34 static struct state *cancel_state;
35
36 int goto_save(struct state *ok, struct state *cancel)
37 {
38     demo_unique(filename);
39     ok_state     = ok;
40     cancel_state = cancel;
41     return goto_state(&st_save);
42 }
43
44 /*---------------------------------------------------------------------------*/
45
46 #define SAVE_SAVE   2
47 #define SAVE_CANCEL 3
48
49 static int file_id;
50
51 static int save_action(int i)
52 {
53     size_t l = strlen(filename);
54
55     audio_play(AUD_MENU, 1.0f);
56
57     switch (i)
58     {
59     case SAVE_SAVE:
60         if (strcmp(filename, "") == 0)
61             return 1;
62         if (demo_exists(filename))
63             return goto_state(&st_clobber);
64         else
65         {
66             demo_play_save(filename);
67             return goto_state(ok_state);
68         }
69
70     case SAVE_CANCEL:
71         return goto_state(cancel_state);
72
73     case GUI_BS:
74         if (l > 0)
75         {
76             filename[l - 1] = 0;
77             gui_set_label(file_id, filename);
78         }
79         break;
80
81     default:
82         if (l < MAXNAM - 1)
83         {
84             filename[l + 0] = (char) i;
85             filename[l + 1] = 0;
86             gui_set_label(file_id, filename);
87         }
88     }
89     return 1;
90 }
91
92 static int enter_id;
93
94 static int save_enter(void)
95 {
96     int id, jd;
97
98     if ((id = gui_vstack(0)))
99     {
100         gui_label(id, _("Replay Name"), GUI_MED, GUI_ALL, 0, 0);
101
102         gui_space(id);
103         gui_space(id);
104
105         file_id = gui_label(id, filename, GUI_MED, GUI_ALL, gui_yel, gui_yel);
106
107         gui_space(id);
108
109         gui_keyboard(id);
110         if ((jd = gui_harray(id)))
111         {
112             enter_id = gui_start(jd, _("Save"), GUI_SML, SAVE_SAVE, 0);
113             gui_state(jd, _("Cancel"), GUI_SML, SAVE_CANCEL, 0);
114         }
115
116         gui_layout(id, 0, 0);
117     }
118
119     SDL_EnableUNICODE(1);
120
121     return id;
122 }
123
124 static void save_leave(int id)
125 {
126     SDL_EnableUNICODE(0);
127     gui_delete(id);
128 }
129
130 static int save_keybd(int c, int d)
131 {
132     if (d)
133         if ((c & 0xFF80) == 0)
134         {
135             gui_focus(enter_id);
136             c &= 0x7F;
137             if (c == '\b')
138                 return save_action(GUI_BS);
139             else if (c > ' ')
140                 return save_action(c);
141         }
142     return 1;
143 }
144
145 static int save_buttn(int b, int d)
146 {
147     if (d)
148     {
149         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
150             return save_action(gui_token(gui_click()));
151         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
152             return save_action(SAVE_CANCEL);
153     }
154     return 1;
155 }
156
157 /*---------------------------------------------------------------------------*/
158
159 static int clobber_action(int i)
160 {
161     audio_play(AUD_MENU, 1.0f);
162
163     if (i == SAVE_SAVE)
164     {
165         demo_play_save(filename);
166         return goto_state(ok_state);
167     }
168     return goto_state(&st_save);
169 }
170
171 static int clobber_enter(void)
172 {
173     int id, jd, kd;
174
175     if ((id = gui_vstack(0)))
176     {
177         kd = gui_label(id, _("Overwrite?"), GUI_MED, GUI_ALL, gui_red, gui_red);
178
179         gui_label(id, filename, GUI_MED, GUI_ALL, gui_yel, gui_yel);
180
181         if ((jd = gui_harray(id)))
182         {
183             gui_start(jd, _("No"),  GUI_SML, SAVE_CANCEL, 1);
184             gui_state(jd, _("Yes"), GUI_SML, SAVE_SAVE,   0);
185         }
186
187         gui_pulse(kd, 1.2f);
188         gui_layout(id, 0, 0);
189     }
190
191     return id;
192 }
193
194 static int clobber_buttn(int b, int d)
195 {
196     if (d)
197     {
198         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
199             return clobber_action(gui_token(gui_click()));
200         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
201             return clobber_action(SAVE_CANCEL);
202     }
203     return 1;
204 }
205
206 /*---------------------------------------------------------------------------*/
207
208 struct state st_save = {
209     save_enter,
210     save_leave,
211     shared_paint,
212     shared_timer,
213     shared_point,
214     shared_stick,
215     shared_click,
216     save_keybd,
217     save_buttn,
218     1, 0
219 };
220
221 struct state st_clobber = {
222     clobber_enter,
223     shared_leave,
224     shared_paint,
225     shared_timer,
226     shared_point,
227     shared_stick,
228     shared_click,
229     NULL,
230     clobber_buttn,
231     1, 0
232 };