1 /*
2     XorGramana Copyright 2009 James W. Morris, james@jwm-art.net
3 
4     This file is part of XorGramana.
5 
6     XorGramana is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10 
11     XorGramana is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with XorGramana.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "level_menu.h"
20 
21 #include "map.h"
22 #include "scores.h"
23 
24 #include "input.h"
25 #include "version.h"
26 
27 #include <string.h>
28 #include <stdlib.h>
29 
30 struct gfx_win* level_win=0;
31 struct xg_key** menu_keys=0;
32 
33 void menu_splash();
34 
level_win_create()35 void level_win_create()
36 {
37     /* utilizing int's loss of fractions */
38     int rx=main_win->win_w;
39     int by=main_win->win_h;
40     int flags=GFX_CENTER_X|GFX_CENTER_Y;
41     if(main_win->win_w>GFX_MIN_WIDTH){
42         rx= ((main_win->win_w/ICON_WIDTH)
43             - (2*(main_win->win_w/GFX_MIN_WIDTH))
44             ) * ICON_WIDTH;
45         flags|=GFX_BLK_ALIGN_X;
46     }
47     if(main_win->win_h>GFX_MIN_HEIGHT){
48         by= ((main_win->win_h/ICON_HEIGHT)
49             - (2*(main_win->win_h/GFX_MIN_HEIGHT))
50             ) * ICON_HEIGHT;
51         flags|=GFX_BLK_ALIGN_Y;
52     }
53     level_win=gfx_new_win(flags,0,0,rx,by,ICON_WIDTH,ICON_HEIGHT);
54     if(!(menu_keys=create_key_list_array(MENU_KEYS_XXX)))
55         return;
56     menu_keys[MENU_UP]->key=            SDLK_UP;
57     menu_keys[MENU_DOWN]->key=          SDLK_DOWN;
58     menu_keys[MENU_PLAY]->key=          SDLK_RETURN;
59     menu_keys[MENU_LOAD_REPLAY]->key=   SDLK_l;
60     menu_keys[MENU_OPTIONS]->key=       SDLK_o;
61     menu_keys[MENU_SWITCH_GAME]->key=   SDLK_x;
62 }
63 
level_win_destroy()64 void level_win_destroy()
65 {
66     free(level_win);
67     #ifdef MISC_DEBUG
68     printf("about to destroy menu_keys\n");
69     #endif
70     destroy_key_list_array(menu_keys);
71     menu_keys=0;
72 }
73 
level_menu(lvl_t level)74 lvl_t level_menu(lvl_t level)
75 {
76     int i,lvl;
77     int first_level=-1;
78     int last_level=0;
79     int level_count=0;
80     int show=8;
81     int show_from;
82     unsigned int flimit=SDL_GetTicks()+TICK_COUNT;
83     set_keys(menu_keys);
84     for(i=MIN_LEVEL;i<=MAX_LEVEL;i++){
85         if(map_name[i]){
86             if(first_level==-1)
87                 first_level=i;
88             else
89                 last_level=i;
90         }
91     }
92     #ifdef MISC_DEBUG
93     printf("level=%d\n",level);
94     printf("first_level:%d last_level:%d\n",first_level,last_level);
95     #endif
96     level_count=last_level-first_level;
97     if(show>level_count)
98         show=level_count+1;
99     show_from=level-show/2;
100     #ifdef MISC_DEBUG
101         printf("show_from:%d(initialised to)\n",show_from);
102     #endif
103     if(show_from<first_level)
104         show_from=first_level;
105     else if(show_from+show>=last_level)
106         show_from=last_level-(show-1);
107     #ifdef MISC_DEBUG
108         printf("show_from:%d(set to)\n",show_from);
109     #endif
110     menu_splash();
111     for(i=0;i<show;i++){
112         gfx_mv_cur(0,4+i);
113         lvl=show_from+i;
114         if(level==lvl)
115             gfx_printf("-%s-",map_name[lvl]);
116         else
117             gfx_printf(" %s",map_name[lvl]);
118     }
119     SDL_Flip(screen);
120     do{
121         if(simple_poll_event()){
122             if(xginput.quit)
123                 xginput.exit=1;
124             if(xginput.exit)
125                 return -1;
126             if(menu_keys[MENU_UP]->pressed){
127                 if(level>first_level){
128                     level--;
129                     if((level==show_from)&&(show_from>first_level))
130                         show_from--;
131                 }
132             }
133             else if(menu_keys[MENU_DOWN]->pressed){
134                 if(level<last_level){
135                     level++;
136                     if((level==show_from+show)&&(show_from+show<=last_level))
137                         show_from++;
138                 }
139             }
140             else if(menu_keys[MENU_PLAY]->pressed)
141                 return level;
142             else if(menu_keys[MENU_SWITCH_GAME]->pressed){
143                 set_game(options->game^1);
144                 for(i=MIN_LEVEL;i<=MAX_LEVEL;i++){
145                     if(map_name[i]){
146                         if(first_level==-1)
147                             first_level=i;
148                         else
149                             last_level=i;
150                     }
151                 }
152                 level=show_from=first_level;
153                 level_count=last_level-first_level;
154                 if(level_count>7)
155                     show=8;
156                 else
157                     show=level_count+1;
158                 #ifdef MISC_DEBUG
159                 printf("first_level:%d last_level:%d\n",first_level,last_level);
160                 #endif
161             }
162             #ifdef MISC_DEBUG
163             printf("level:%d\n",level);
164             #endif
165             menu_splash();
166             for(i=0;i<show;i++){
167                 gfx_mv_cur(0,4+i);
168                 lvl=show_from+i;
169                 if(level==lvl)
170                     gfx_printf("-%s-",map_name[lvl]);
171                 else
172                     gfx_printf(" %s",map_name[lvl]);
173             }
174             SDL_Flip(screen);
175         }
176         delay(flimit);
177         flimit=SDL_GetTicks()+TICK_COUNT;
178     }while(1);
179 }
180 
menu_splash()181 void menu_splash()
182 {
183     char spc[80];
184     int gx=(options->game?3:12);
185     int x;
186     int n;
187     init_wall(1,TRUE);
188     for(n=0;n<80;spc[n++]=' ');
189     spc[main_win->blk_count_x]='\0';
190     gfx_set_win(main_win);
191     gfx_mv_cur(0,0);
192     gfx_win_full_size();
193     set_space_icon(SPC_FLOOR);
194     for(n=0;n<main_win->blk_count_y;n++)
195         gfx_printf("%s",spc);
196     gfx_set_win(level_win);
197     gfx_win_full_size();
198     x=(level_win->blk_count_x-gx)/2;
199     gfx_mv_cur(x,0);
200     gfx_printf((options->game?"Xor":"XorGramana"));
201     if(options->game)
202         x=0;
203     gfx_mv_cur(0,1);
204     gfx_win_half_size();
205     spc[main_win->blk_count_x]='_';
206     spc[level_win->blk_count_x]='\0';
207     for(n=0;n<level_win->blk_count_y-2;n++)
208         gfx_printf("%s",spc);
209     if(options->game){
210         gfx_mv_cur(x+1,2);
211         gfx_printf("remake by jwm-art.net");
212     }
213     else{
214         gfx_mv_cur(x+2,2);
215         gfx_printf("%s by jwm-art.net",verstr);
216     }
217     gfx_mv_cur(x,level_win->blk_count_y-3);
218     gfx_printf("x-switch game");
219     gfx_mv_cur(x,level_win->blk_count_y-2);
220     gfx_printf("l-load replay");
221     gfx_mv_cur(x,level_win->blk_count_y-1);
222     gfx_printf("o-options");
223 }
224 
help()225 void help()
226 {
227     /*
228     char* hf;
229     FILE* fp;
230     char help[120][43];
231     xy_t r,maxrows;
232     xy_t row=0;
233     int key;
234     if(!(hf=options_file_path("xorcurseshelp.txt",options->data_dir)))
235         return;
236     if((fp=fopen(hf, "r"))){
237         while(fgets(help[row++], 42, fp)&&row<120);
238         free(hf);
239         fclose(fp);
240         maxrows=row-1;
241     }
242     else{
243         free(hf);
244         icon_help();
245         return;
246     }
247     row=0;
248     wclear(game_win);
249     wattrset(game_win,COLOR_PAIR(0));
250     do{
251         for(r=0;r<24;r++)
252             mvwprintw(game_win,r,0,help[r+row]);
253         switch((key=wgetch(game_win)))
254         {
255             case KEY_UP:    if(row>0)row--;break;
256             case KEY_DOWN:  if(row+24<maxrows)row++;break;
257             case 'q':
258             case 'Q':
259                 return;
260         }
261     }while(key!='h'&&key!='H');
262     icon_help();
263     */
264 }
265 
icon_help()266 void icon_help()
267 {
268     /*
269     char* hf;
270     FILE* fp;
271     char help[50][43];
272     xy_t row=0;
273     xy_t irow=0;
274     xy_t r,maxrows;
275     int key;
276     su_t i;
277     if(!(hf=options_file_path("xorcursesiconhelp.txt",options->data_dir)))
278         return;
279     if((fp=fopen(hf, "r"))){
280         while(fgets(help[row++], 42, fp)&&row<50);
281         free(hf);
282         fclose(fp);
283         maxrows=row-1;
284     }
285     else{
286         free(hf);
287         return;
288     }
289     wclear(game_win);
290     row=0;
291     do{
292         wattrset(game_win,COLOR_PAIR(0));
293         for(r=0;r<24;r++)
294             mvwprintw(game_win,r,0,help[r+row]);
295         for(i=0;i<12;i++){
296             game_win_icon_dump(0,i*4-row,i+ICON_H_FIELD);
297         }
298         irow=(row+1)/4;
299         switch((key=wgetch(game_win)))
300         {
301             case KEY_UP:    if(row>0)row--;break;
302             case KEY_DOWN:  if(row+24<maxrows)row++;break;
303             case 'q': case 'Q': case 'h': case 'H':
304                 return;
305         }
306     }while(key!='q'&&key!='Q');
307     */
308 }
309