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