2
* .þÛÛþ þ þ þÛÛþ. þ þ þÛÛÛþ. þÛÛÛþ .þÛÛþ. þ þ
3
* .þ Û Ûþ. Û Û þ. Û Û Û þ Û. Û. Û Ûþ. Û
4
* Û Û Û Û Û Û Û Û þ. Û. Û Û Û Û Û Û Û
5
* .þþÛÛÛÛþ Û Û Û þÛÛÛÛþþ. þþÛÛ. þþÛÛþ. þÛ Û Û Û Û Û
6
* .Û Û Û .þÛ Û Û. Û Û Û Û Û. þ. Û Û .þÛ
7
* þ. þ þ þ þ .þ þ .þ þ .þ þÛÛÛþ .þÛÛþ. þ þ
10
* Martin Stransky <stransky@anakreon.cz>
12
* This program is free software; you can redistribute it and/or modify
13
* it under the terms of the GNU General Public License as published by
14
* the Free Software Foundation; either version 2 of the License, or
15
* (at your option) any later version.
17
* This program is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* You should have received a copy of the GNU General Public License
23
* along with this program; if not, write to the Free Software
24
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30
#include "portability.h"
42
#include "berusky_gui.h"
46
// -------------------------------------------------------
48
// -------------------------------------------------------
50
game_gui::game_gui(ITEM_REPOSITORY *p_repo_, DIR_LIST *p_dir_)
51
: gui_base(), p_repo(p_repo_), p_dir(p_dir_)
53
// Create game main class
54
p_ber = new BERUSKY(p_repo_,p_dir);
57
window_set_title(GAME_TITLE);
60
game_gui::~game_gui(void)
65
// TODO -> dat to tam kde se to SDL inicializuje
84
void game_gui::menu_main(MENU_STATE state, int data, int data1)
90
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)(&game_gui::menu_main), data, data1);
92
p_grf->fill(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y, 0);
94
tpos width = p_grf->sprite_get_width(MENU_SPRIT_LOGO);
98
p_grf->draw(MENU_SPRIT_LOGO,(GAME_RESOLUTION_X-width)/2,LOGO_START);
100
#define MENU_X_START 250
101
#define MENU_Y_START 220
102
#define MENU_X_DIFF 0
103
#define MENU_Y_DIFF 35
105
static char *new_game = _("new game");
106
static char *password = _("password");
107
static char *help = _("help");
108
static char *editor = _("editor");
109
static char *quit = _("quit");
111
p_font->select(FONT_DEFAULT);
113
menu_item_set_pos(MENU_X_START, MENU_Y_START);
114
menu_item_set_diff(MENU_X_DIFF, MENU_Y_DIFF);
118
menu_item_draw(new_game, LEFT, TRUE, LEVEL_EVENT(GC_MENU_NEW_GAME));
119
menu_item_draw(password, LEFT, TRUE, LEVEL_EVENT(GC_MENU_PASSWORD));
120
menu_item_draw(help, LEFT, TRUE, LEVEL_EVENT(GC_MENU_HELP,FALSE));
121
menu_item_draw(editor, LEFT, TRUE, LEVEL_EVENT(GC_RUN_EDITOR));
122
menu_item_draw(quit, LEFT, TRUE, LEVEL_EVENT(GC_MENU_QUIT));
124
p_font->alignment_set(CENTER);
125
p_font->start_set(0, GAME_RESOLUTION_Y - 60);
126
p_font->print(_("berusky (C) Anakreon 1997-2007\n"));
127
p_font->print(_("distributed under GPL\n"));
129
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
134
input.mevent_clear();
147
void game_gui::menu_new_game(MENU_STATE state, int data, int data1)
153
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_new_game, data, data1);
155
p_grf->fill(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y, 0);
157
tpos width = p_grf->sprite_get_width(MENU_SPRIT_LOGO);
161
p_grf->draw(MENU_SPRIT_LOGO,(GAME_RESOLUTION_X-width)/2,LOGO_START);
163
#define MENU_X_START 250
164
#define MENU_Y_START 240
165
#define MENU_X_DIFF 0
166
#define MENU_Y_DIFF 35
168
p_font->select(FONT_DEFAULT);
169
p_font->alignment_set(CENTER);
170
p_font->start_set(0, MENU_Y_START - 50);
171
p_font->print(_("select difficulty of the new game:"));
173
static char *training = _("training");
174
static char *easy = _("easy");
175
static char *intermediate = _("intermediate");
176
static char *advanced = _("advanced");
177
static char *impossible = _("impossible");
178
static char *back = _("back");
180
menu_item_set_pos(MENU_X_START, MENU_Y_START);
181
menu_item_set_diff(MENU_X_DIFF, MENU_Y_DIFF);
183
// udelat na to ulozeni tady flag -> prejdi a uloz!! (Zprava -> menu_back_save)
185
menu_item_draw(training, LEFT, TRUE, LEVEL_EVENT(GC_MENU_RUN_LEVEL, 0, 0));
186
menu_item_draw(easy, LEFT, TRUE, LEVEL_EVENT(GC_MENU_RUN_LEVEL, 1, 0));
187
menu_item_draw(intermediate, LEFT, TRUE, LEVEL_EVENT(GC_MENU_RUN_LEVEL, 2, 0));
188
menu_item_draw(advanced, LEFT, TRUE, LEVEL_EVENT(GC_MENU_RUN_LEVEL, 3, 0));
189
menu_item_draw(impossible, LEFT, TRUE, LEVEL_EVENT(GC_MENU_RUN_LEVEL, 4, 0));
190
menu_item_draw(back, LEFT, FALSE, LEVEL_EVENT(GI_MENU_BACK_POP));
192
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
197
input.mevent_clear();
210
void game_gui::menu_password(MENU_STATE state, int data, int data1)
212
#define MAX_PASSWORD 10
213
static char password[MAX_PASSWORD] = "";
219
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_password, data, data1);
221
p_grf->fill(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y, 0);
223
tpos width = p_grf->sprite_get_width(MENU_SPRIT_LOGO);
227
p_grf->draw(MENU_SPRIT_LOGO,(GAME_RESOLUTION_X-width)/2,LOGO_START);
229
#define INSERT_START 200
230
p_font->select(FONT_DEFAULT);
231
p_font->alignment_set(CENTER);
232
p_font->start_set(0, INSERT_START);
233
p_font->print(_("please insert a password to level:"));
235
p_font->print(NULL, 0, INSERT_START+50, "_");
237
#define MENU_X_START 270
238
#define MENU_Y_START 400
239
#define MENU_X_DIFF 90
240
#define MENU_Y_DIFF 35
242
static char *play = _("play");
243
static char *back = _("back");
246
menu_item_draw(MENU_X_START + MENU_X_DIFF, MENU_Y_START, play, RIGHT, TRUE, LEVEL_EVENT(GC_MENU_PASSWORD_CHECK, password));
247
menu_item_draw(MENU_X_START, MENU_Y_START+MENU_Y_DIFF, back, LEFT, FALSE, LEVEL_EVENT(GI_MENU_BACK_POP));
249
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
252
menu_key_input.set((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_password);
258
bool character = key_to_ascii(data,&ascii_char);
259
int len = strlen(password);
261
if(character && ascii_char >= ' ') {
262
if(len < MAX_PASSWORD-2) {
263
password[len] = ascii_char;
264
password[len+1] = '\0';
271
password[--len] = '\0';
281
p_font->select(FONT_DEFAULT);
282
p_font->alignment_set(CENTER);
283
p_grf->fill(0,INSERT_START+50,GAME_RESOLUTION_X,20,0);
284
p_font->print(NULL, 0, INSERT_START+50, "%s_", password);
285
p_grf->redraw_add(0,INSERT_START+50,GAME_RESOLUTION_X,20);
290
input.mevent_clear();
291
menu_key_input.clear();
305
void game_gui::menu_password_check(MENU_STATE state, int data, int data1)
311
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_password_check, data, data1);
315
if(p_ber->levelset_search((char *)data, &set, &level)) {
316
menu_level_run(MENU_ENTER,set,level);
318
p_grf->fill(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y, 0);
320
tpos width = p_grf->sprite_get_width(MENU_SPRIT_LOGO);
324
p_grf->draw(MENU_SPRIT_LOGO,(GAME_RESOLUTION_X-width)/2,LOGO_START);
326
#define INSERT_START 200
327
p_font->select(FONT_DEFAULT);
328
p_font->alignment_set(CENTER);
329
p_font->start_set(0, INSERT_START);
330
p_font->print(_("Cha cha cha!!!\n"));
331
p_font->print(_("Would you like to cheat?\n"));
332
p_font->print(_("Try me again!"));
335
#define MENU_X_START 270
336
#define MENU_Y_START 400
337
#define MENU_X_DIFF 90
338
#define MENU_Y_DIFF 35
340
static char *back = _("back");
343
menu_item_draw(MENU_X_START, MENU_Y_START+MENU_Y_DIFF, back, LEFT, FALSE, LEVEL_EVENT(GI_MENU_BACK_POP));
345
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
351
input.mevent_clear();
365
data = bool from_game
367
void game_gui::menu_help(MENU_STATE state, int data, int data1)
373
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_help, data, data1);
375
p_grf->fill(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y, 0);
377
tpos width = p_grf->sprite_get_width(MENU_SPRIT_LOGO);
381
p_grf->draw(MENU_SPRIT_LOGO,(GAME_RESOLUTION_X-width)/2,LOGO_START);
383
#define MENU_X_START 240
384
#define MENU_Y_START 240
385
#define MENU_X_DIFF 0
386
#define MENU_Y_DIFF 35
388
bool from_game = (bool)data;
390
static char *hint = _("level hint");
391
static char *keys = _("game controls");
392
static char *rules = _("game rulez");
393
static char *credits = _("authors");
394
static char *back = _("back");
396
menu_item_set_pos(MENU_X_START, MENU_Y_START);
397
menu_item_set_diff(MENU_X_DIFF, MENU_Y_DIFF);
402
menu_item_draw(hint, LEFT, TRUE, LEVEL_EVENT(GC_MENU_LEVEL_HINT, FALSE));
405
menu_item_draw(keys, LEFT, TRUE, LEVEL_EVENT(GC_MENU_HELP_KEYS));
406
menu_item_draw(rules, LEFT, TRUE, LEVEL_EVENT(GC_MENU_HELP_RULES,0));
407
menu_item_draw(credits, LEFT, TRUE, LEVEL_EVENT(GC_MENU_HELP_CREDIT));
408
menu_item_draw(back, LEFT, FALSE, LEVEL_EVENT(from_game ? GC_RESTORE_LEVEL : GI_MENU_BACK_POP));
410
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
416
input.mevent_clear();
432
void game_gui::menu_help_rules(MENU_STATE state, int data, int data1)
438
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_help_rules, data, data1);
440
p_grf->fill(0,0,GAME_RESOLUTION_X,GAME_RESOLUTION_Y,0);
441
p_grf->draw(MENU_SPRIT_BACK,0,0);
442
p_font->alignment_set(LEFT);
443
p_font->select(FONT_DEFAULT);
449
int page_prev = page-1,
454
p_font->print(NULL, 80, 95, _("Basic rules and game elements"));
456
p_font->start_set(20, 140);
457
p_font->print(_("In order to leave each level it is\n\
458
necessary to own five keys and also\n\
459
to have a free way to the exit.\n\n\
460
You will be meeting miscellaneous game\n\
461
elements while completing individual\n\
462
missions, we will try to explain their\n\
465
p_font->print(NULL, 20, 310, _("box - it is possible to push it."));
468
variants = p_repo->variants_get(P_BOX);
469
for (i = 0; i < variants; i++) {
470
p_repo->draw(x, y, P_BOX, i, 0);
474
p_font->print(NULL, 20, 380, _("explosive - can destroy the boxes."));
477
variants = p_repo->variants_get(P_TNT);
478
for (i = 0; i < variants; i++) {
479
p_repo->draw(x, y, P_TNT, i, 0);
488
p_font->print(NULL, 160, 95, _("Active game elements"));
490
p_font->print(NULL, 20, 140, _("key - you need five of them."));
491
p_grf->draw(p_repo->sprite_get(P_KEY, 0, 0), 20, 165);
493
p_font->print(NULL, 20, 200, _("exit - a gate to next level."));
496
variants = p_repo->variants_get(P_EXIT);
497
for (i = 0; i < variants - 1; i += 2) {
498
p_repo->draw(x, y, P_EXIT, i, 0);
501
p_grf->draw(p_repo->sprite_get(P_EXIT, i - 1, 0), x, y);
503
p_font->print(NULL, 20, 270, _("stone - can be broken by a pickax."));
506
variants = p_repo->variants_get(P_STONE);
507
for (i = 0; i < variants; i++) {
508
p_repo->draw(x, y, P_STONE, i, 0);
512
p_font->print(NULL, 20, 340, _("pickax - a tool for stone crushing."));
515
variants = p_repo->variants_get(P_MATTOCK);
516
for (i = 0; i < variants; i++) {
517
p_repo->draw(x, y, P_MATTOCK, i, 0);
524
p_font->print(NULL, 160, 95, _("Active game elements"));
526
p_font->start_set(20, 140);
527
p_font->print(_("color key - used to unlock color door,\n\
528
only a bug with identical color can\n\
533
for (j = 0; j < 5; j++) {
534
variants = p_repo->variants_get(P_KEY1 + j);
535
for (i = 0; i < variants; i++) {
536
p_repo->draw(x, y, P_KEY1 + j, i, 0);
541
p_font->start_set(20, 250);
542
p_font->print(_("color door - can be opened by the\nrespective color key only"));
546
variants = p_repo->variants_get(P_DOOR1_V_Z);
547
for (i = 0; i < variants; i++) {
548
p_repo->draw(x, y, P_DOOR1_V_Z, i, 0);
552
p_font->start_set(20, 340);
553
p_font->print(_("color gate-way - only a bug with\n\
554
identical color is allowed to go\n\
555
through. Boxes cannot be pushed\n\
560
variants = p_repo->variants_get(P_ID_DOOR1_V_Z);
561
for (i = 0; i < variants; i++) {
562
p_repo->draw(x, y, P_ID_DOOR1_V_Z, i, 0);
569
p_font->print(NULL, 160, 95, _("Active game elements"));
571
p_font->start_set(20, 140);
572
p_font->print(_("one-pass door - can be used only once,\n\
573
then they close them off and there's no\n\
574
way to open them\n"));
578
variants = p_repo->variants_get(P_DV_V_O);
579
for (i = 0; i < variants; i++) {
580
p_repo->draw(x, y, P_DV_V_O, i, 0);
585
variants = p_repo->variants_get(P_DV_V_Z);
586
for (i = 0; i < variants; i++) {
587
p_repo->draw(x, y, P_DV_V_Z, i, 0);
591
p_font->start_set(20, 300);
592
p_font->print(_("Other elements not listed here are just\n\
593
walls, which have no interesting\n\
594
properties. They cannot be push away nor\n\
595
it is possible to break them anywise.\n"));
606
static char *prev = _("previous");
607
static char *next = _("next");
608
static char *back = _("back");
610
#define MENU_X_START 350
611
#define MENU_X_START_L MENU_X_START
612
#define MENU_X_START_R MENU_X_START_L + 250
613
#define MENU_X_START_B MENU_X_START_L + 50
614
#define MENU_Y_START 410
615
#define MENU_X_DIFF 0
616
#define MENU_Y_DIFF 30
619
menu_item_draw(MENU_X_START_L, MENU_Y_START+0*MENU_Y_DIFF, prev, LEFT, FALSE, LEVEL_EVENT(GC_MENU_HELP_RULES,page_prev));
620
menu_item_draw(MENU_X_START_R, MENU_Y_START+0*MENU_Y_DIFF, next, RIGHT, FALSE, LEVEL_EVENT(GC_MENU_HELP_RULES,page_next));
621
menu_item_draw(MENU_X_START_B, MENU_Y_START+1*MENU_Y_DIFF, back, LEFT, FALSE, LEVEL_EVENT(GI_MENU_BACK_POP));
623
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
629
input.mevent_clear();
643
void game_gui::menu_help_keys(MENU_STATE state, int data, int data1)
649
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_help_keys, data, data1);
651
p_grf->fill(0,0,GAME_RESOLUTION_X,GAME_RESOLUTION_Y,0);
652
p_grf->draw(MENU_SPRIT_BACK,0,0);
653
p_font->select(FONT_DEFAULT);
655
p_font->alignment_set(CENTER);
656
p_font->print(NULL, 220, 100, _("Game Controls"));
658
p_font->alignment_set(LEFT);
659
p_font->print(NULL, 20, 140, _("Up to five bugs are available,\n\
660
which can be controlled by these keys:"));
666
p_font->print(NULL, 20, start_y = Y_START, _("arrows"));
668
p_font->print(NULL, 20, start_y += Y_DIFF, _("Tab"));
669
p_font->print(NULL, 20, start_y += Y_DIFF, _("N"));
670
p_font->print(NULL, 20, start_y += Y_DIFF, _("D"));
671
p_font->print(NULL, 20, start_y += Y_DIFF, _("CTRL+X"));
672
p_font->print(NULL, 20, start_y += Y_DIFF, _("F1"));
673
p_font->print(NULL, 20, start_y += Y_DIFF, _("F2"));
674
p_font->print(NULL, 20, start_y += Y_DIFF, _("F3"));
676
p_font->print(NULL, 69, start_y = Y_START, _(" . . . . . . . move the bug"));
677
p_font->print(NULL, 86, start_y += Y_DIFF, _(". . . . . . . switch among the bugs"));
678
p_font->print(NULL, 60, start_y += Y_DIFF, _(". . . . . . . . change the music"));
679
p_font->print(NULL, 60, start_y += Y_DIFF, _(". . . . . . . . demo"));
680
p_font->print(NULL, 110, start_y += Y_DIFF, _(". . . . . . quit quickly"));
681
p_font->print(NULL, 60, start_y += Y_DIFF, _(". . . . . . . . Help"));
682
p_font->print(NULL, 60, start_y += Y_DIFF, _(". . . . . . . . Save level"));
683
p_font->print(NULL, 60, start_y += Y_DIFF, _(". . . . . . . . Load level"));
685
#define MENU_X_START 270
686
#define MENU_Y_START 400
687
#define MENU_X_DIFF 90
688
#define MENU_Y_DIFF 35
690
static char *back = _("back");
693
menu_item_draw(MENU_X_START, MENU_Y_START+MENU_Y_DIFF, back, LEFT, FALSE, LEVEL_EVENT(GI_MENU_BACK_POP));
695
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
701
input.mevent_clear();
714
#undef MENU_X_START_L
716
#define SCROLL_START_X 0
717
#define SCROLL_START_Y 180
718
#define SCROLL_LINES 12
720
void game_gui::menu_help_credits(MENU_STATE state, int data, int data1)
722
static char *p_text = NULL;
723
static int frame = 0;
730
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_help_credits, data, data1);
732
p_text = credit_text_load();
735
sprite::color_key_set(COLOR_KEY_GAME);
737
p_grf->fill(0,0,GAME_RESOLUTION_X,GAME_RESOLUTION_Y,0);
738
tpos width = p_grf->sprite_get_width(MENU_SPRIT_LOGO);
740
p_grf->draw(MENU_SPRIT_LOGO,(GAME_RESOLUTION_X-width)/2,LOGO_START);
741
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
744
input.keyset_set(&menu_keys);
746
menu_timer.set((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_help_credits, data, data1);
754
if((frame & 0x3) == 0x0) {
756
p_font->alignment_set(CENTER);
757
p_font->select(FONT_DEFAULT);
759
if(position >= p_font->height_get_new_line(p_text)) {
760
position -= p_font->height_get_new_line(p_text);
761
p_text = strchr(p_text+1,'\n');
765
p_grf->fill(0,SCROLL_START_Y,GAME_RESOLUTION_X,GAME_RESOLUTION_Y-SCROLL_START_Y,0);
766
p_font->print(NULL, SCROLL_START_X, SCROLL_START_Y-position, SCROLL_LINES, p_text);
770
#define MENU_X_START_L (320 - 17)
771
#define MENU_Y_START 440
773
static char *back_string = _("back");
776
menu_item_draw(MENU_X_START_L, MENU_Y_START, back_string, LEFT, FALSE, LEVEL_EVENT(GC_MENU_START));
779
p_grf->redraw_add(0,SCROLL_START_Y,GAME_RESOLUTION_X,GAME_RESOLUTION_Y-SCROLL_START_Y);
791
input.keyset_set(NULL);
792
input.mevent_clear();
810
void game_gui::menu_level_hint(MENU_STATE state, int data, int data1)
816
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_level_hint, data, data1);
818
p_grf->fill(0,0,GAME_RESOLUTION_X,GAME_RESOLUTION_Y,0);
819
p_grf->draw(MENU_SPRIT_BACK,0,0);
821
p_font->select(FONT_DEFAULT);
822
p_font->alignment_set(LEFT);
825
bool from_game = data;
827
if(!p_ber->levelset_is_custom()) {
828
int set = p_ber->levelset_get_set();
829
int level = p_ber->levelset_get_level();
831
// ... Load & print hint for level ...
832
p_hint = level_hint_load(set, level);
836
p_font->print(NULL, 20, 100, _("Level hint:"));
838
p_hint = _("\nSory dude, no hint available for this\nlevel.");
840
p_font->print(NULL, 20, 120, p_hint);
842
#define MENU_X_START 270
843
#define MENU_Y_START 400
844
#define MENU_X_DIFF 90
845
#define MENU_Y_DIFF 35
847
static char *back = _("back");
850
menu_item_draw(MENU_X_START, MENU_Y_START+MENU_Y_DIFF, back, LEFT, FALSE, LEVEL_EVENT(from_game ? GC_RESTORE_LEVEL : GI_MENU_BACK_POP));
852
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
858
input.mevent_clear();
871
#undef MENU_X_START_L
872
#undef MENU_X_START_R
874
void game_gui::menu_level_run(MENU_STATE state, int data, int data1)
880
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_level_run, data, data1);
885
bool ret = p_ber->levelset_load(set);
887
p_ber->levelset_set_level(level);
889
p_grf->fill(0,0,GAME_RESOLUTION_X,GAME_RESOLUTION_Y,0);
890
p_font->alignment_set(CENTER);
891
p_font->select(FONT_DEFAULT);
893
#define TEXT_START 250
897
p_grf->draw(MENU_SPRIT_START+0,0,50);
898
p_font->print(NULL, 0, 20,_("difficulty training"));
899
p_font->print(NULL, 0, TEXT_START+35, _("Level: %d"),level);
900
p_font->print(NULL, 0, TEXT_START+35+25, _("Password: %s"),p_ber->levelset_get_passwd(level));
903
p_grf->draw(MENU_SPRIT_START+1,0,25);
904
p_font->print(NULL, 0, 20, _("difficulty easy"));
905
p_font->print(NULL, 0, TEXT_START+35, _("Level: %d"),level);
906
p_font->print(NULL, 0, TEXT_START+35+25, _("Password: %s"),p_ber->levelset_get_passwd(level));
909
p_grf->draw(MENU_SPRIT_START+2,0,50);
910
p_font->print(NULL, 0, 20, _("difficulty intermediate"));
911
p_font->print(NULL, 0, TEXT_START+35, _("Level: %d"),level);
912
p_font->print(NULL, 0, TEXT_START+35+25, _("Password: %s"),p_ber->levelset_get_passwd(level));
915
p_grf->draw(MENU_SPRIT_START+3,0,50);
916
p_font->print(NULL, 0, 20, _("difficulty advanced"));
917
p_font->print(NULL, 0, TEXT_START+35, _("Level: %d"),level);
918
p_font->print(NULL, 0, TEXT_START+35+25, _("Password: %s"),p_ber->levelset_get_passwd(level));
921
p_grf->draw(MENU_SPRIT_START+3,0,50);
922
p_font->print(NULL, 0, 20, _("difficulty impossible"));
923
p_font->print(NULL, 0, TEXT_START+35, _("Level: %d"),level);
924
p_font->print(NULL, 0, TEXT_START+35+25, _("Password: %s"),p_ber->levelset_get_passwd(level));
931
#define MENU_X_START_L (320 - 17 - 60)
932
#define MENU_X_START_R (320 + 60)
933
#define MENU_Y_START 360
934
#define MENU_X_DIFF 0
935
#define MENU_Y_DIFF 35
937
static char *play_string = _("play level");
938
static char *level_hint = _("level hint");
939
static char *back_string = _("back");
942
menu_item_draw(MENU_X_START_R, MENU_Y_START+0*MENU_Y_DIFF, play_string, RIGHT, FALSE, LEVEL_EVENT(GC_RUN_LEVEL_SET, set, level));
943
menu_item_draw(MENU_X_START_R, MENU_Y_START+1*MENU_Y_DIFF, level_hint, RIGHT, TRUE, LEVEL_EVENT(GC_MENU_LEVEL_HINT, FALSE));
944
menu_item_draw(MENU_X_START_L, MENU_Y_START+2*MENU_Y_DIFF, back_string, LEFT, FALSE, LEVEL_EVENT(GI_MENU_BACK_POP));
946
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
952
input.mevent_clear();
960
/* Load a hint for given level */
962
#define MARK_START "~%d_%d"
965
char * game_gui::level_hint_load(int set, int level)
967
FHANDLE f = file_open(p_dir->gamedata_get(), LEVEL_HINTS_FILE, "r");
969
char start_mark[1000];
970
snprintf(start_mark,1000,MARK_START,set+1,level+1);
972
// Search a mark in the hint file
975
while(fgets(line,1000,f)) {
976
if((p_tmp = strstr(line,start_mark)) && p_tmp == line) {
982
if(!p_tmp || p_tmp != line) {
987
#define HINT_BUFFER_LENGHT 40000
988
static char hint_buffer[HINT_BUFFER_LENGHT];
992
p_tmp = fgets(p_tmp, HINT_BUFFER_LENGHT - (p_tmp - hint_buffer), f);
995
if(p_tmp[0] == MARK_END[0]) {
999
p_tmp = p_tmp + strlen(p_tmp);
1003
return(hint_buffer);
1006
/* Load end text for given episode */
1007
char * game_gui::level_end_text_load(int set)
1009
char file[MAX_FILENAME];
1010
snprintf(file,MAX_FILENAME,SET_END_FILE_TEXT,set);
1012
#define END_BUFFER_LENGHT 40000
1013
static char end_buffer[END_BUFFER_LENGHT];
1014
file_load_text(p_dir->gamedata_get(),file,end_buffer,END_BUFFER_LENGHT);
1019
/* Load text for credits */
1020
char * game_gui::credit_text_load(void)
1022
#define CREDITS_FILE "credits.dat"
1024
// Load the whole file
1025
#define END_BUFFER_LENGHT 40000
1026
static char cr_buffer[END_BUFFER_LENGHT];
1027
file_load_text(p_dir->gamedata_get(), CREDITS_FILE, cr_buffer, END_BUFFER_LENGHT);
1032
/* Load an external level from command line */
1033
bool game_gui::level_run(LEVEL_EVENT_QUEUE *p_queue, char *p_level)
1037
/* Quit if it fails */
1038
if(p_ber->level_load(p_level) && p_ber->level_play(p_queue, 0)) {
1040
input.keyset_set(&game_keys);
1043
menu_dialog_error(_("Unable to load level %s"),p_level);
1044
p_queue->add(LEVEL_EVENT(GC_MENU_QUIT));
1049
/* Load specified level from level set */
1050
bool game_gui::level_run(LEVEL_EVENT_QUEUE *p_queue, int set, int level)
1056
/* Run a menu if it fails */
1057
if(p_ber->levelset_load(set) && p_ber->level_play(p_queue, level)) {
1058
input.keyset_set(&game_keys);
1061
menu_dialog_error(_("Unable to load level %d from set %d"),level,set);
1062
p_queue->add(LEVEL_EVENT(GC_MENU_START));
1067
//void level_stop(LEVEL_EVENT_QUEUE *p_queue, bool resolved, bool levelset, int set, int level);
1068
void game_gui::level_stop(LEVEL_EVENT_QUEUE *p_queue, int cheat, int menu)
1072
input.keyset_set(NULL);
1074
LEVEL_STATUS *p_status = p_ber->level_stop(p_queue);
1077
int level = p_ber->levelset_get_level();
1078
int set = p_ber->levelset_get_set();
1081
p_status->bug_in_exit();
1083
if(p_status->resolved()) {
1084
if(p_ber->levelset_is_custom()) {
1085
p_queue->add(LEVEL_EVENT(GC_MENU_END_LEVEL_CUSTOM));
1087
if(level+1 < p_ber->levelset_get_levelnum()) {
1088
p_queue->add(LEVEL_EVENT(GC_MENU_END_LEVEL, set, level));
1090
p_queue->add(LEVEL_EVENT(GC_MENU_END_LEVEL_SET, set));
1094
if(p_ber->levelset_is_custom()) {
1095
/* if we run it from command line, stop it */
1096
p_queue->add(LEVEL_EVENT(GC_MENU_QUIT));
1098
/* if we run it from set, return to menu */
1099
p_queue->add(LEVEL_EVENT(GC_MENU_END_LEVEL, set, level));
1105
#undef MENU_X_START_L
1106
#undef MENU_X_START_R
1111
void game_gui::menu_level_end(MENU_STATE state, int data, int data1)
1117
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_level_end, data, data1);
1119
/* Some statistics here */
1120
p_grf->fill(0,0,GAME_RESOLUTION_X,GAME_RESOLUTION_Y,0);
1121
p_font->alignment_set(CENTER);
1122
p_font->select(FONT_DEFAULT);
1124
LEVEL_STATUS *p_status = p_ber->level_status_get();
1127
#define SMALL_LOGO_START 80
1128
p_grf->draw(MENU_SPRIT_LOGO_SMALL_2,p_grf->sprite_get_width_center(MENU_SPRIT_LOGO_SMALL_2),SMALL_LOGO_START);
1130
if(p_status->resolved()) {
1131
p_font->print(NULL,0,SMALL_LOGO_START+100,_("your bugs have survived!"));
1132
p_font->print(NULL,0,SMALL_LOGO_START+130,_("difficulty %s"), p_ber->levelset_get_difficulty());
1133
p_font->print(NULL,0,SMALL_LOGO_START+180,_("it takes %d steps"), p_status->steps_get());
1134
p_font->print(NULL,0,SMALL_LOGO_START+210,_("and %s."), p_status->time_get(tmp,100));
1136
p_font->print(NULL,0,SMALL_LOGO_START+100,_("your bugs have given it up!"));
1137
p_font->print(NULL,0,SMALL_LOGO_START+130,_("difficulty %s"), p_ber->levelset_get_difficulty());
1138
p_font->print(NULL,0,SMALL_LOGO_START+180,_("they made %d steps"), p_status->steps_get());
1139
p_font->print(NULL,0,SMALL_LOGO_START+210,_("and spent %s"), p_status->time_get(tmp,100));
1142
p_grf->draw(MENU_SPRIT_LOGO_SMALL_3,p_grf->sprite_get_width_center(MENU_SPRIT_LOGO_SMALL_3),SMALL_LOGO_START+240);
1144
#define MENU_X_START_L (320 - 17 - 120)
1145
#define MENU_X_START_R (320 + 120)
1146
#define MENU_Y_START 400
1147
#define MENU_X_DIFF 0
1148
#define MENU_Y_DIFF 30
1150
static char *play_string = _("play next level");
1151
static char *back_string = _("back to menu");
1155
if(p_status->resolved()) {
1158
menu_item_draw(MENU_X_START_R, MENU_Y_START+0*MENU_Y_DIFF, play_string, RIGHT, FALSE, LEVEL_EVENT(GC_MENU_RUN_LEVEL, set, level+1));
1161
menu_item_draw(MENU_X_START_L, MENU_Y_START+1*MENU_Y_DIFF, back_string, LEFT, FALSE, LEVEL_EVENT(GI_MENU_BACK_POP));
1163
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
1169
input.mevent_clear();
1177
void game_gui::menu_level_end_custom(MENU_STATE state, int data, int data1)
1183
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_level_end_custom, data, data1);
1185
/* Some statistics here */
1186
p_grf->fill(0,0,GAME_RESOLUTION_X,GAME_RESOLUTION_Y,0);
1187
p_font->alignment_set(CENTER);
1188
p_font->select(FONT_DEFAULT);
1190
#define SMALL_LOGO_START 80
1191
p_grf->draw(MENU_SPRIT_LOGO_SMALL_2,p_grf->sprite_get_width_center(MENU_SPRIT_LOGO_SMALL_2),SMALL_LOGO_START);
1193
p_font->print(NULL,0,SMALL_LOGO_START+100,_("your bugs have survived!"));
1194
p_font->print(NULL,0,SMALL_LOGO_START+130,_("custom level %s."), p_ber->levelset_get_name());
1196
LEVEL_STATUS *p_status = p_ber->level_status_get();
1197
p_font->print(NULL,0,SMALL_LOGO_START+180,_("it takes %d steps"), p_status->steps_get());
1199
p_font->print(NULL,0,SMALL_LOGO_START+210,_("and %s."), p_status->time_get(tmp,100));
1201
p_grf->draw(MENU_SPRIT_LOGO_SMALL_3,p_grf->sprite_get_width_center(MENU_SPRIT_LOGO_SMALL_3),SMALL_LOGO_START+240);
1203
#define MENU_X_START (320 - 35)
1204
#define MENU_Y_START 400
1205
#define MENU_X_DIFF 0
1206
#define MENU_Y_DIFF 30
1208
static char *back_string = _("quit");
1211
menu_item_draw(MENU_X_START, MENU_Y_START+0*MENU_Y_DIFF, back_string, LEFT, FALSE, LEVEL_EVENT(GC_MENU_QUIT));
1213
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
1219
input.mevent_clear();
1227
#undef MENU_X_START_L
1229
#undef SCROLL_START_X
1230
#undef SCROLL_START_Y
1236
void game_gui::menu_levelset_end(MENU_STATE state, int data, int data1)
1238
static char *p_text = NULL;
1239
static int frame = 0;
1240
static int position;
1246
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_levelset_end, data, data1);
1250
p_text = level_end_text_load(set);
1253
sprite::color_key_set(COLOR_KEY_GAME);
1254
p_grf->sprite_delete(MENU_SPRIT_END, 1);
1257
snprintf(line, 1000, SET_END_FILE_BACK, set+1);
1258
p_grf->sprite_insert(line, MENU_SPRIT_END, 1, NULL);
1260
input.keyset_set(&menu_keys);
1262
menu_timer.set((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_levelset_end, data, data1);
1270
if((frame & 0x3) == 0x0) {
1271
p_font->alignment_set(CENTER);
1272
p_font->select(FONT_DEFAULT);
1274
p_grf->draw(MENU_SPRIT_END,0,0);
1276
if(position >= p_font->height_get_new_line(p_text)) {
1277
position -= p_font->height_get_new_line(p_text);
1278
p_text = strchr(p_text+1,'\n');
1282
#define SCROLL_START_X 0
1283
#define SCROLL_START_Y 0
1284
#define SCROLL_LINES 20
1286
p_font->print(NULL, SCROLL_START_X, SCROLL_START_Y-position, SCROLL_LINES, p_text);
1290
#define MENU_X_START_L (320 - 17)
1291
#define MENU_Y_START 440
1293
static char *back_string = _("back");
1296
menu_item_draw(MENU_X_START_L, MENU_Y_START, back_string, LEFT, FALSE, LEVEL_EVENT(GC_MENU_START));
1299
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
1302
/* pokud jsem na konci -> odregistrovat timer, pridat <- back menu
1313
input.keyset_set(NULL);
1314
input.mevent_clear();
1328
void game_gui::menu_in_game(MENU_STATE state, int data, int data1)
1334
menu_enter((GUI_BASE *)this,(GUI_BASE_FUNC)&game_gui::menu_in_game, data, data1);
1336
p_grf->fill(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y, 0);
1338
tpos width = p_grf->sprite_get_width(MENU_SPRIT_LOGO);
1340
#define LOGO_START 0
1342
p_grf->draw(MENU_SPRIT_LOGO,(GAME_RESOLUTION_X-width)/2,LOGO_START);
1344
#define MENU_X_START 200
1345
#define MENU_Y_START 180
1346
#define MENU_X_DIFF 0
1347
#define MENU_Y_DIFF 35
1349
static char *back = _("return to game (ESC)");
1350
static char *rest = _("restart level (CTRL+R)");
1352
static char *save = _("save game (F2)");
1353
static char *load = _("load game (F3)");
1355
static char *hint = _("level hint (CTRL+F1)");
1356
static char *help = _("help (F1)");
1358
static char *menu = _("back to main menu");
1359
static char *quit = _("quit (CTRL+X)");
1361
menu_item_set_pos(MENU_X_START, MENU_Y_START);
1362
menu_item_set_diff(MENU_X_DIFF, MENU_Y_DIFF);
1366
menu_item_draw(back, LEFT, FALSE, LEVEL_EVENT(GC_RESTORE_LEVEL));
1367
menu_item_draw(rest, LEFT, FALSE, LEVEL_EVENT(GC_RESTART_LEVEL));
1369
menu_item_draw(save, LEFT, FALSE, LEVEL_EVENT(GC_SAVE_LEVEL));
1370
menu_item_draw(load, LEFT, FALSE, LEVEL_EVENT(GC_LOAD_LEVEL));
1372
menu_item_draw(hint, LEFT, TRUE, LEVEL_EVENT(GC_MENU_LEVEL_HINT, FALSE));
1373
menu_item_draw(help, LEFT, TRUE, LEVEL_EVENT(GC_MENU_HELP, FALSE));
1375
menu_item_draw(menu, LEFT, FALSE, LEVEL_EVENT(GC_STOP_LEVEL, FALSE, FALSE), LEVEL_EVENT(GC_MENU_START));
1376
menu_item_draw(quit, LEFT, FALSE, LEVEL_EVENT(GC_STOP_LEVEL, FALSE, FALSE), LEVEL_EVENT(GC_MENU_QUIT));
1378
p_grf->redraw_add(0, 0, GAME_RESOLUTION_X, GAME_RESOLUTION_Y);
1384
input.mevent_clear();
1391
void game_gui::level_suspend(LEVEL_EVENT_QUEUE *p_queue)
1393
input.keyset_set(&suspend_keys);
1394
p_ber->level_suspend(p_queue);
1397
void game_gui::level_restore(LEVEL_EVENT_QUEUE *p_queue)
1401
input.keyset_set(&game_keys);
1402
p_ber->level_restore(p_queue);
1405
void game_gui::level_restart(LEVEL_EVENT_QUEUE *p_queue)
1409
input.keyset_set(&game_keys);
1410
p_ber->level_restart(p_queue);
1413
void game_gui::level_save(LEVEL_EVENT_QUEUE *p_queue)
1416
p_ber->level_save();
1418
p_font->select(FONT_DEFAULT);
1419
p_font->alignment_set(LEFT);
1420
p_grf->fill(0,460,GAME_RESOLUTION_X,20,0);
1421
p_font->print(NULL,0,460,_("Level saved..."));
1422
p_grf->redraw_add(0,460,GAME_RESOLUTION_X,20);
1428
void game_gui::level_load(LEVEL_EVENT_QUEUE *p_queue)
1431
p_ber->level_load();
1433
p_font->select(FONT_DEFAULT);
1434
p_font->alignment_set(LEFT);
1435
p_grf->fill(0,460,GAME_RESOLUTION_X,20,0);
1436
p_font->print(NULL,0,460,_("Level loaded..."));
1437
p_grf->redraw_add(0,460,GAME_RESOLUTION_X,20);
1443
void game_gui::run_editor(void)
1448
bprintf("%s -e",p_dir->game_binary_get());
1449
int ret = execlp(p_dir->game_binary_get(),p_dir->game_binary_get(),"-e",NULL);
1451
bprintf("Error: %s",strerror(errno));
1456
bprintf("Waiting for %d",pid);
1457
waitpid(pid,&status,0);
1458
bprintf("Pid %d done",pid);
1461
bprintf("%s -e",p_dir->game_binary_get());
1462
int ret = _spawnl( _P_WAIT, p_dir->game_binary_get(),p_dir->game_binary_get(),"-e",NULL);
1464
bprintf("Error: %s",strerror(errno));
1469
bool game_gui::callback(LEVEL_EVENT_QUEUE *p_queue, int frame)
1471
/* If there's a timer function, call it! */
1472
if(menu_timer.valid()) {
1473
(this->*menu_timer.p_func)(MENU_TIMER, menu_timer.p1, menu_timer.p2);
1476
/* load events from system by SDL event handler */
1477
input.events_loop(p_queue);
1479
/* Scan the queue and do the propper action */
1480
static LEVEL_EVENT_QUEUE tmp_queue;
1482
while(!p_queue->empty()) {
1483
LEVEL_EVENT ev = p_queue->get();
1485
switch(ev.action_get()) {
1486
/* Start of the game
1487
* This is the firts event after start
1490
menu_main(MENU_ENTER);
1492
case GC_MENU_NEW_GAME:
1493
menu_new_game(MENU_ENTER);
1495
case GC_MENU_PASSWORD:
1496
menu_password(MENU_ENTER);
1498
case GC_MENU_PASSWORD_CHECK:
1499
menu_password_check(MENU_ENTER, ev.param_int_get(PARAM_0));
1502
menu_help(MENU_ENTER, ev.param_int_get(PARAM_0));
1507
case GC_MENU_HELP_KEYS:
1508
menu_help_keys(MENU_ENTER, ev.param_int_get(PARAM_0));
1510
case GC_MENU_HELP_RULES:
1511
menu_help_rules(MENU_ENTER, ev.param_int_get(PARAM_0), ev.param_int_get(PARAM_1));
1513
case GC_MENU_HELP_CREDIT:
1514
menu_help_credits(MENU_ENTER, ev.param_int_get(PARAM_0));
1516
case GC_MENU_LEVEL_HINT:
1517
menu_level_hint(MENU_ENTER, ev.param_int_get(PARAM_0));
1520
case GC_RUN_LEVEL_LINE:
1521
level_run(&tmp_queue, (char *)ev.param_point_get(PARAM_0));
1523
case GC_RUN_LEVEL_SET:
1524
level_run(&tmp_queue, ev.param_int_get(PARAM_0), ev.param_int_get(PARAM_1));
1527
level_stop(&tmp_queue, ev.param_int_get(PARAM_0), ev.param_int_get(PARAM_1));
1530
case GC_SUSPEND_LEVEL:
1531
level_suspend(&tmp_queue);
1533
case GC_RESTORE_LEVEL:
1534
level_restore(&tmp_queue);
1537
case GC_RESTART_LEVEL:
1538
level_restart(&tmp_queue);
1542
level_save(&tmp_queue);
1545
level_load(&tmp_queue);
1548
case GC_MENU_RUN_LEVEL:
1549
menu_level_run(MENU_ENTER, ev.param_int_get(PARAM_0), ev.param_int_get(PARAM_1));
1551
case GC_MENU_END_LEVEL:
1552
menu_level_end(MENU_ENTER, ev.param_int_get(PARAM_0), ev.param_int_get(PARAM_1));
1554
case GC_MENU_END_LEVEL_CUSTOM:
1555
menu_level_end_custom(MENU_ENTER, ev.param_int_get(PARAM_0), ev.param_int_get(PARAM_1));
1557
case GC_MENU_END_LEVEL_SET:
1558
menu_levelset_end(MENU_ENTER, ev.param_int_get(PARAM_0));
1561
case GC_MENU_IN_GAME:
1562
menu_in_game(MENU_ENTER);
1569
case GI_MENU_BACK_POP:
1572
case GI_MENU_BACK_PUSH:
1576
case GI_SPRITE_DRAW:
1577
case GI_STRING_DRAW:
1590
/* Commit all writes */
1591
p_queue->add(&tmp_queue);
1595
/* Call the game (if exists) */
1597
p_ber->level_callback(p_queue);
1603
void game_gui::menu_dialog_error(char *p_text,...)
1606
#define MAX_TEXT_LEN 2000
1608
char text[MAX_TEXT_LEN];
1611
va_start(arguments,p_text);
1612
vsnprintf(text,MAX_TEXT_LEN,p_text,arguments);
1615
GtkWidget *dialog = gtk_message_dialog_new(main_window_get(),
1616
GTK_DIALOG_DESTROY_WITH_PARENT,
1620
gtk_dialog_run (GTK_DIALOG (dialog));
1621
gtk_widget_destroy (dialog);