Several changes either directly or indirectly related to the recording
[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 #include <ctype.h>
17
18 #include "gui.h"
19 #include "game.h"
20 #include "util.h"
21 #include "audio.h"
22 #include "config.h"
23 #include "demo.h"
24 #include "levels.h"
25
26 #include "st_shared.h"
27 #include "st_save.h"
28
29 extern struct state st_save;
30 extern struct state st_clobber;
31
32 static char filename[MAXNAM];
33
34 /*---------------------------------------------------------------------------*/
35
36 static struct state *ok_state;
37 static struct state *cancel_state;
38
39 int goto_save(struct state *ok, struct state *cancel)
40 {
41     demo_unique(filename);
42
43     ok_state     = ok;
44     cancel_state = cancel;
45
46     return goto_state(&st_save);
47 }
48
49 /*---------------------------------------------------------------------------*/
50
51 static int file_id;
52
53 #define SAVE_SAVE   1
54 #define SAVE_CANCEL 2
55
56 static int save_action(int i)
57 {
58     size_t l = strlen(filename);
59
60     audio_play(AUD_MENU, 1.0f);
61
62     switch (i)
63     {
64     case SAVE_SAVE:
65         if (strlen(filename) == 0)
66             return 1;
67
68         if (demo_exists(filename))
69             return goto_state(&st_clobber);
70         else
71         {
72             demo_rename(filename);
73             return goto_state(ok_state);
74         }
75
76     case SAVE_CANCEL:
77         return goto_state(cancel_state);
78
79     case GUI_CL:
80         gui_keyboard_lock();
81         break;
82
83     case GUI_BS:
84         if (l > 0)
85         {
86             filename[l - 1] = 0;
87             gui_set_label(file_id, filename);
88         }
89         break;
90
91     default:
92         if (l < MAXNAM - 1)
93         {
94             filename[l + 0] = (char) i;
95             filename[l + 1] = 0;
96             gui_set_label(file_id, filename);
97         }
98     }
99     return 1;
100 }
101
102 static int enter_id;
103
104 static int save_enter(void)
105 {
106     int id, jd;
107
108     if ((id = gui_vstack(0)))
109     {
110         gui_label(id, _("Replay Name"), GUI_MED, GUI_ALL, 0, 0);
111
112         gui_space(id);
113
114         file_id = gui_label(id, filename, GUI_MED, GUI_ALL, gui_yel, gui_yel);
115
116         gui_space(id);
117
118         gui_keyboard(id);
119
120         if ((jd = gui_harray(id)))
121         {
122             enter_id = gui_start(jd, _("Save"), GUI_SML, SAVE_SAVE, 0);
123             gui_state(jd, _("Cancel"), GUI_SML, SAVE_CANCEL, 0);
124         }
125
126         gui_layout(id, 0, 0);
127     }
128
129     SDL_EnableUNICODE(1);
130
131     return id;
132 }
133
134 static void save_leave(int id)
135 {
136     SDL_EnableUNICODE(0);
137     gui_delete(id);
138 }
139
140 static int save_keybd(int c, int d)
141 {
142     if (d && (c & 0xFF80) == 0)
143     {
144         gui_focus(enter_id);
145
146         if (c == '\b' || c == 0x7F)
147             return save_action(GUI_BS);
148         if (c > ' ')
149             return save_action(c);
150     }
151     return 1;
152 }
153
154 static int save_buttn(int b, int d)
155 {
156     if (d)
157     {
158         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
159         {
160             int c = gui_token(gui_click());
161
162             /* Ugh.  This is such a hack. */
163
164             return save_action(isupper(c) ? gui_keyboard_char(c) : c);
165         }
166         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
167             return save_action(SAVE_CANCEL);
168     }
169     return 1;
170 }
171
172 /*---------------------------------------------------------------------------*/
173
174 static int clobber_action(int i)
175 {
176     audio_play(AUD_MENU, 1.0f);
177
178     if (i == SAVE_SAVE)
179     {
180         demo_rename(filename);
181         return goto_state(ok_state);
182     }
183     return goto_state(&st_save);
184 }
185
186 static int clobber_enter(void)
187 {
188     int id, jd, kd;
189
190     if ((id = gui_vstack(0)))
191     {
192         kd = gui_label(id, _("Overwrite?"), GUI_MED, GUI_ALL, gui_red, gui_red);
193
194         gui_label(id, filename, GUI_MED, GUI_ALL, gui_yel, gui_yel);
195
196         if ((jd = gui_harray(id)))
197         {
198             gui_start(jd, _("No"),  GUI_SML, SAVE_CANCEL, 1);
199             gui_state(jd, _("Yes"), GUI_SML, SAVE_SAVE,   0);
200         }
201
202         gui_pulse(kd, 1.2f);
203         gui_layout(id, 0, 0);
204     }
205
206     return id;
207 }
208
209 static int clobber_buttn(int b, int d)
210 {
211     if (d)
212     {
213         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_A, b))
214             return clobber_action(gui_token(gui_click()));
215         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
216             return clobber_action(SAVE_CANCEL);
217     }
218     return 1;
219 }
220
221 /*---------------------------------------------------------------------------*/
222
223 struct state st_save = {
224     save_enter,
225     save_leave,
226     shared_paint,
227     shared_timer,
228     shared_point,
229     shared_stick,
230     shared_click,
231     save_keybd,
232     save_buttn,
233     1, 0
234 };
235
236 struct state st_clobber = {
237     clobber_enter,
238     shared_leave,
239     shared_paint,
240     shared_timer,
241     shared_point,
242     shared_stick,
243     shared_click,
244     NULL,
245     clobber_buttn,
246     1, 0
247 };