1
2 #include "../nx.h"
3 #include "../game.fdh"
4 #include "title.fdh"
5
6 // music and character selections for the different Counter times
7 static struct
8 {
9 uint32_t timetobeat;
10 int sprite;
11 int songtrack;
12 } titlescreens[] =
13 {
14 (3*3000), SPR_CS_SUE, 2, // 3 mins - Sue & Safety
15 (4*3000), SPR_CS_KING, 41, // 4 mins - King & White
16 (5*3000), SPR_CS_TOROKO, 40, // 5 mins - Toroko & Toroko's Theme
17 (6*3000), SPR_CS_CURLY, 36, // 6 mins - Curly & Running Hell
18 0xFFFFFFFF, SPR_CS_MYCHAR, 24 // default
19 };
20
21 // artifical fake "loading" delay between selecting an option and it being executed,
22 // because it actually doesn't look good if we respond instantly.
23 #define SELECT_DELAY 30
24 #define SELECT_LOAD_DELAY 20 // delay when leaving the multisave Load dialog
25 #define SELECT_MENU_DELAY 8 // delay from Load to load menu
26
27 static struct
28 {
29 int sprite;
30 int cursel;
31 int selframe, seltimer;
32 int selchoice, seldelay;
33 int kc_pos;
34 bool in_multiload;
35
36 uint32_t besttime; // Nikumaru display
37 } title;
38
39
title_init(int param)40 bool title_init(int param)
41 {
42 memset(&title, 0, sizeof(title));
43 game.switchstage.mapno = 0;
44 game.switchstage.eventonentry = 0;
45 game.showmapnametime = 0;
46 textbox.SetVisible(false);
47
48 if (niku_load(&title.besttime))
49 title.besttime = 0xffffffff;
50
51 // select a title screen based on Nikumaru time
52 int t;
53 for(t=0;;t++)
54 {
55 if (title.besttime < titlescreens[t].timetobeat || \
56 titlescreens[t].timetobeat == 0xffffffff)
57 {
58 break;
59 }
60 }
61
62 title.sprite = titlescreens[t].sprite;
63 music(titlescreens[t].songtrack);
64
65 if (AnyProfileExists())
66 title.cursel = 1; // Load Game
67 else
68 title.cursel = 0; // New Game
69
70 return 0;
71 }
72
title_tick()73 void title_tick()
74 {
75 if (!title.in_multiload)
76 {
77 if (title.seldelay > 0)
78 {
79 ClearScreen(BLACK);
80
81 title.seldelay--;
82 if (!title.seldelay)
83 selectoption(title.selchoice);
84
85 return;
86 }
87
88 handle_input();
89 draw_title();
90 }
91 else
92 {
93 ClearScreen(BLACK);
94
95 if (!textbox.SaveSelect.IsVisible())
96 { // selection was made, and settings.last_save_slot is now set appropriately
97
98 sound(SND_MENU_SELECT);
99
100 textbox.SetVisible(false);
101 title.selchoice = 1;
102 title.seldelay = SELECT_LOAD_DELAY;
103 title.in_multiload = false;
104 }
105 else
106 {
107 textbox.Draw();
108 }
109 }
110 }
111
112
113 /*
114 void c------------------------------() {}
115 */
116
selectoption(int index)117 static void selectoption(int index)
118 {
119 switch(index)
120 {
121 case 0: // New
122 {
123 music(0);
124
125 game.switchstage.mapno = NEW_GAME_FROM_MENU;
126 game.setmode(GM_NORMAL);
127 }
128 break;
129
130 case 1: // Load
131 {
132 music(0);
133
134 game.switchstage.mapno = LOAD_GAME_FROM_MENU;
135 game.setmode(GM_NORMAL);
136 }
137 break;
138
139 case 2: // Load Menu (multisave)
140 {
141 textbox.SetVisible(true);
142 textbox.SaveSelect.SetVisible(true, SS_LOADING);
143 title.in_multiload = true;
144 }
145 break;
146 }
147 }
148
149
handle_input()150 static void handle_input()
151 {
152 if (justpushed(DOWNKEY))
153 {
154 sound(SND_MENU_MOVE);
155 if (++title.cursel >= sprites[SPR_MENU].nframes)
156 title.cursel = 0;
157 }
158 else if (justpushed(UPKEY))
159 {
160 sound(SND_MENU_MOVE);
161 if (--title.cursel < 0)
162 title.cursel = sprites[SPR_MENU].nframes - 1;
163 }
164
165 if (buttonjustpushed())
166 {
167 sound(SND_MENU_SELECT);
168 int choice = title.cursel;
169
170 // handle case where user selects Load but there is no savefile,
171 // or the last_save_file is deleted.
172 if (title.cursel == 1)
173 {
174 if (!ProfileExists(settings->last_save_slot))
175 {
176 bool foundslot = false;
177 for(int i=0;i<MAX_SAVE_SLOTS;i++)
178 {
179 if (ProfileExists(i))
180 {
181 NX_WARN("Last save file %d missing. Defaulting to %d instead.\n", settings->last_save_slot, i);
182 settings->last_save_slot = i;
183 foundslot = true;
184 }
185 }
186
187 // there are no save files. Start a new game instead.
188 if (!foundslot)
189 {
190 NX_WARN("No save files found. Starting new game instead.\n");
191 choice = 0;
192 }
193 }
194 }
195
196 if (choice == 1 && settings->multisave)
197 {
198 title.selchoice = 2;
199 title.seldelay = SELECT_MENU_DELAY;
200 }
201 else
202 {
203 title.selchoice = choice;
204 title.seldelay = SELECT_DELAY;
205 music(0);
206 }
207 }
208
209 run_konami_code();
210 }
211
draw_title()212 static void draw_title()
213 {
214 // background is dk grey, not pure black
215 ClearScreen(0x20, 0x20, 0x20);
216 map_draw_backdrop();
217
218 // top logo
219 int tx = (SCREEN_WIDTH / 2) - (sprites[SPR_TITLE].w / 2) - 2;
220 draw_sprite(tx, 40, SPR_TITLE);
221
222 // draw menu
223 int cx = (SCREEN_WIDTH / 2) - (sprites[SPR_MENU].w / 2) - 8;
224 int cy = (SCREEN_HEIGHT / 2) + 8;
225 for(int i=0;i<sprites[SPR_MENU].nframes;i++)
226 {
227 draw_sprite(cx, cy, SPR_MENU, i);
228 if (i == title.cursel)
229 {
230 draw_sprite(cx - 16, cy - 1, title.sprite, title.selframe);
231 }
232
233 cy += (sprites[SPR_MENU].h + 4);
234 }
235
236 // animate character
237 if (++title.seltimer > 8)
238 {
239 title.seltimer = 0;
240 if (++title.selframe >= sprites[title.sprite].nframes)
241 title.selframe = 0;
242 }
243
244 // accreditation
245 cx = (SCREEN_WIDTH / 2) - (sprites[SPR_PIXEL_FOREVER].w / 2);
246 int acc_y = SCREEN_HEIGHT - 48;
247 draw_sprite(cx, acc_y, SPR_PIXEL_FOREVER);
248
249 // version
250 static const char *VERSION = "NXEngine v. 1.0.0.6";
251 static const int SPACING = 5;
252 int wd = GetFontWidth(VERSION, SPACING);
253 cx = (SCREEN_WIDTH / 2) - (wd / 2);
254 font_draw(cx, acc_y + sprites[SPR_PIXEL_FOREVER].h + 4, VERSION, SPACING);
255 font_draw(cx, acc_y + sprites[SPR_PIXEL_FOREVER].h + 16, "Libretro v. 1.0", SPACING);
256
257 // draw Nikumaru display
258 if (title.besttime != 0xffffffff)
259 niku_draw(title.besttime, true);
260 }
261
262
263
264 static int kc_table[] = { UPKEY, UPKEY, DOWNKEY, DOWNKEY,
265 LEFTKEY, RIGHTKEY, LEFTKEY, RIGHTKEY, -1 };
266
run_konami_code()267 void run_konami_code()
268 {
269 if (justpushed(UPKEY) || justpushed(DOWNKEY) || \
270 justpushed(LEFTKEY) || justpushed(RIGHTKEY))
271 {
272 if (justpushed(kc_table[title.kc_pos]))
273 {
274 title.kc_pos++;
275 if (kc_table[title.kc_pos] == -1)
276 {
277 sound(SND_MENU_SELECT);
278 title.kc_pos = 0;
279 }
280 }
281 else
282 {
283 title.kc_pos = 0;
284 }
285 }
286 }
287
288
289
290
291
292
293
294
295
296
297
298
299