1 /*
2 * Abuse - dark 2D side-scrolling platform game
3 * Copyright (c) 1995 Crack dot Com
4 * Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5 *
6 * This software was released into the Public Domain. As with most public
7 * domain software, no warranty is made or implied by Crack dot Com, by
8 * Jonathan Clark, or by Sam Hocevar.
9 */
10
11 #if defined HAVE_CONFIG_H
12 # include "config.h"
13 #endif
14
15 #include <string.h>
16
17 #include "common.h"
18
19 #include "game.h"
20
21 #include "specs.h"
22 #include "jwindow.h"
23 #include "id.h"
24 #include "input.h"
25 #include "fonts.h"
26 #include "lisp.h"
27 #include "dprint.h"
28 #include "cache.h"
29 #include "gui.h"
30 #include "dev.h"
31 #include "id.h"
32 #include "demo.h"
33
34 extern void *save_order; // load from "saveordr.lsp", contains a list ordering the save games
35
36 extern JCFont *console_font;
37
38 #define MAX_SAVE_GAMES 15
39 #define MAX_SAVE_LINES 5
40 int last_save_game_number=0;
41
42 int save_buts[MAX_SAVE_GAMES * 3];
43
44
load_number_icons()45 void load_number_icons()
46 {
47 for (int i = 0; i < MAX_SAVE_GAMES * 3; i++)
48 {
49 char name[100];
50 sprintf(name, "nums%04d.pcx", i + 1);
51 save_buts[i] = cache.reg("art/icons.spe", name, SPEC_IMAGE, 1);
52 }
53 }
54
55
last_savegame_name(char * buf)56 void last_savegame_name(char *buf)
57 {
58 printf( "last_savegame_name()\n" );
59 sprintf(buf,"%ssave%04d.spe",get_save_filename_prefix(), (last_save_game_number+MAX_SAVE_GAMES-1)%MAX_SAVE_GAMES+1);
60 }
61
create_num_window(int mx,int total_saved,int lines,image ** thumb_nails)62 Jwindow *create_num_window(int mx, int total_saved, int lines, image **thumb_nails)
63 {
64 ico_button *buts[MAX_SAVE_GAMES];
65 int y = 0, x = 0, i;
66 int iw=cache.img(save_buts[0])->Size().x;
67 int ih=cache.img(save_buts[0])->Size().y;
68 int maxih = ih, maxiw = iw;
69 int n=0;
70 for (i=0; i<total_saved; i++,y+=ih)
71 {
72 maxih = Max(ih, maxih);
73 maxiw = Max(iw, maxiw);
74 if (y >= lines * ih)
75 {
76 y = 0;
77 x += iw;
78 }
79 if (thumb_nails) { while (!thumb_nails[n]) n++; }
80 buts[i]=new ico_button(x, y, ID_LOAD_GAME_NUMBER + n,
81 save_buts[n*3+0],save_buts[n*3+0],save_buts[n*3+1],save_buts[n*3+2],NULL);
82 buts[i]->set_act_id(ID_LOAD_GAME_PREVIEW+n);
83 n++;
84 }
85
86 for (i=0; i<total_saved-1; i++)
87 buts[i]->next=buts[i+1];
88
89 return wm->new_window(mx,yres/2-(Jwindow::top_border()+maxih*5)/2,-1,-1,buts[0]);
90 }
91
get_save_spot()92 int get_save_spot()
93 {
94 int i=MAX_SAVE_GAMES,last_free=0;
95 for (; i>0; )
96 {
97 char name[20];
98 sprintf(name,"%ssave%04d.spe", get_save_filename_prefix(),i);
99 FILE *fp=open_FILE(name,"rb");
100 if (fp)
101 i=0;
102 else { last_free=i; i--; }
103 fclose(fp);
104 }
105
106 if (last_free) return last_free; // if there are any slots not created yet...
107
108 int w=cache.img(save_buts[0])->Size().x;
109 int mx=last_demo_mx-w/2;
110 if(mx + w + 10 > xres) mx = xres - w - 10;
111 if(mx < 0) mx = 0;
112
113 Jwindow *l_win=create_num_window(mx,MAX_SAVE_GAMES,MAX_SAVE_LINES,NULL);
114 event ev;
115 int got_level=0;
116 int quit=0;
117 do
118 {
119 wm->flush_screen();
120 wm->get_event(ev);
121 if (ev.type==EV_MESSAGE && ev.message.id>=ID_LOAD_GAME_NUMBER && ev.message.id<ID_LOAD_GAME_PREVIEW)
122 got_level=ev.message.id-ID_LOAD_GAME_NUMBER+1;
123
124
125 if (ev.type==EV_CLOSE_WINDOW && ev.window==l_win)
126 quit=1;
127 } while (!got_level && !quit);
128
129 wm->close_window(l_win);
130 the_game->reset_keymap();
131 return got_level;
132 }
133
get_savegame_name(char * buf)134 void get_savegame_name(char *buf) // buf should be at least 50 bytes
135 {
136 sprintf(buf,"save%04d.spe",(last_save_game_number++)%MAX_SAVE_GAMES+1);
137 /* FILE *fp=open_FILE("lastsave.lsp","wb");
138 if (fp)
139 {
140 fprintf(fp,"(setq last_save_game %d)\n",last_save_game_number%MAX_SAVE_GAMES);
141 fclose(fp);
142 } else dprintf("Warning unable to open lastsave.lsp for writing\n"); */
143 }
144
show_load_icon()145 int show_load_icon()
146 {
147 int i;
148 for( i = 0; i < MAX_SAVE_GAMES; i++ )
149 {
150 char nm[255];
151 sprintf( nm, "%ssave%04d.spe", get_save_filename_prefix(), i + 1 );
152 bFILE *fp = open_file( nm, "rb" );
153 if( fp->open_failure() )
154 {
155 delete fp;
156 }
157 else
158 {
159 delete fp;
160 return 1;
161 }
162 }
163 return 0;
164 }
165
load_game(int show_all,char const * title)166 int load_game(int show_all, char const *title) // return 0 if the player escapes, else return the number of the game to load
167 {
168 int total_saved=0;
169 image *thumb_nails[MAX_SAVE_GAMES];
170 int start_num=0;
171 int max_w=160,max_h=100;
172 memset(thumb_nails,0,sizeof(thumb_nails));
173
174 image *first=NULL;
175
176 for (start_num=0; start_num<MAX_SAVE_GAMES; start_num++)
177 {
178 char name[255];
179 int fail=0;
180
181 sprintf(name,"%ssave%04d.spe", get_save_filename_prefix(), start_num+1);
182 bFILE *fp=open_file(name,"rb");
183 if (fp->open_failure())
184 {
185 fail=1;
186 }
187 else
188 {
189 spec_directory sd(fp);
190 spec_entry *se=sd.find("thumb nail");
191 if (se && se->type==SPEC_IMAGE)
192 {
193 thumb_nails[start_num] = new image(fp, se);
194 if (thumb_nails[start_num]->Size().x>max_w) max_w=thumb_nails[start_num]->Size().x;
195 if (thumb_nails[start_num]->Size().y>max_h) max_h=thumb_nails[start_num]->Size().y;
196 if (!first) first=thumb_nails[start_num];
197 total_saved++;
198 }
199 else
200 fail=1;
201 }
202 if (fail && show_all)
203 {
204 thumb_nails[start_num] = new image(vec2i(160, 100));
205 thumb_nails[start_num]->clear();
206 console_font->put_string(thumb_nails[start_num],0,0,symbol_str("no_saved"));
207 total_saved++;
208 if (!first) first=thumb_nails[start_num];
209 }
210 delete fp;
211 }
212
213 if (!total_saved) return 0;
214 if (total_saved>MAX_SAVE_GAMES)
215 total_saved=MAX_SAVE_GAMES;
216
217 int i;
218 /* int ih=cache.img(save_buts[0])->Size().y;
219 ico_button *buts[MAX_SAVE_GAMES];
220 int y=0;
221
222
223 for (i=0; i<total_saved; i++,y+=ih)
224 {
225 buts[i]=new ico_button(0,y,ID_LOAD_GAME_NUMBER+i,
226 save_buts[i*3+1],save_buts[i*3+1],save_buts[i*3+0],save_buts[i*3+2],NULL);
227 buts[i]->set_act_id(ID_LOAD_GAME_PREVIEW+i);
228 }
229
230 for (i=0; i<total_saved-1; i++)
231 buts[i]->next=buts[i+1];
232 */
233
234
235 Jwindow *l_win=create_num_window(0,total_saved,MAX_SAVE_LINES,thumb_nails);
236 Jwindow *preview=wm->new_window(l_win->x+l_win->l+5,l_win->y,max_w,max_h,NULL,title);
237
238 first->put_image(preview->screen,preview->x1(),preview->y1());
239
240 event ev;
241 int got_level=0;
242 int quit=0;
243 do
244 {
245 wm->flush_screen();
246 wm->get_event(ev);
247 if (ev.type==EV_MESSAGE && ev.message.id>=ID_LOAD_GAME_NUMBER && ev.message.id<ID_LOAD_GAME_PREVIEW)
248 got_level=ev.message.id-ID_LOAD_GAME_NUMBER+1;
249
250 if (ev.type==EV_MESSAGE && ev.message.id>=ID_LOAD_GAME_PREVIEW && ev.message.id<ID_LOAD_PLAYER_GAME)
251 {
252 int draw_num=ev.message.id-ID_LOAD_GAME_PREVIEW;
253 preview->clear();
254 thumb_nails[draw_num]->put_image(preview->screen,preview->x1(),preview->y1());
255 }
256
257 if ((ev.type==EV_CLOSE_WINDOW) || (ev.type==EV_KEY && ev.key==JK_ESC))
258 quit=1;
259 } while (!got_level && !quit);
260
261 wm->close_window(l_win);
262 wm->close_window(preview);
263
264 for (i=0; i<total_saved; i++)
265 if (thumb_nails[i])
266 delete thumb_nails[i];
267
268 return got_level;
269 }
270