From a5a03e15b395ba1942c180d1cd0d3a4f43b87f56 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Thu, 10 Apr 1997 00:27:35 +0200 Subject: [PATCH] rocks_n_diamonds-1.0 --- CHANGES | 19 +- src/Makefile | 16 +- src/buttons.c | 204 +++---- src/buttons.h | 42 +- src/editor.c | 318 +++++++---- src/events.c | 503 ++++++++---------- src/events.h | 2 +- src/files.c | 92 +++- src/files.h | 8 +- src/game.c | 1401 +++++++++++++++++++++++++++---------------------- src/game.h | 44 +- src/init.c | 421 ++++++++++----- src/init.h | 1 + src/main.c | 34 +- src/main.h | 1078 +++++++++++++++++++------------------ src/misc.c | 107 +++- src/misc.h | 8 +- src/screens.c | 511 ++++++++++-------- src/screens.h | 12 +- src/tape.c | 230 ++++++++ src/tape.h | 34 ++ src/tools.c | 154 ++++-- src/tools.h | 13 +- 23 files changed, 3123 insertions(+), 2129 deletions(-) create mode 100644 src/tape.c create mode 100644 src/tape.h diff --git a/CHANGES b/CHANGES index 5ad2b64d..441f3d06 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,23 @@ +Release Version 1.0 [9 APR 97] +------------------------------ + - the game now contains many really playable levels, + not only a few levels for testing + - the game is now even better playable by keyboard + (now you have the same gameplay functionality + compared to playing with a joystick. Especially + there are diagonal directions with keyboard playing + and the fire buttons are mapped to the shift keys) + - a lot of new elements for better emulation of levels + from the games "Boulderdash", "Emerald Mine" and + "Sokoban". New elements to build "Dynablaster" style + levels. + - enhanced functionality of the level tape recorder + to make it possible to go on with a game at any tape + position + Prerelease Version 0.9b [4 NOV 95] ------------------------------------- +---------------------------------- - the game is now completely Freeware - the game is now better playable by keyboard (in the last version, the player was making more than diff --git a/src/Makefile b/src/Makefile index 7333fb28..273cecdd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -22,16 +22,15 @@ CONFIG = $(GAME_DIR) $(SOUNDS) $(JOYSTICK) \ $(SCORE_ENTRIES) $(XPM_INCLUDE_FILE) # DEBUG = -DDEBUG -g -ansi -pedantic -Wall -# DEBUG = -DDEBUG -g -Wall -DEBUG = -O6 +DEBUG = -DDEBUG -g -Wall +# DEBUG = -O6 # SYSTEM = -Aa -D_HPUX_SOURCE -Dhpux # for HP-UX (obsolete) # SYSTEM = -DSYSV -Ae # for HP-UX # SYSTEM = -DSYSV # for systems without 'usleep()' # INCL = -I/usr/include/X11R5 # for HP-UX and others -# LIBS = -lXpm -lX11 -lm # LIBS = -L/usr/lib/X11R5 -lXpm -lX11 -lm # for HP-UX and others -LIBS = -lXpm -lXpm -lXpm -lX11 -lm # triple -lXpm; else I got an error... +LIBS = -L/usr/X11R6/lib -lXpm -lX11 -lm # CFLAGS = -O2 $(CONFIG) $(SYSTEM) CFLAGS = $(DEBUG) $(CONFIG) $(SYSTEM) $(INCL) @@ -46,6 +45,7 @@ SRCS = main.c \ editor.c \ buttons.c \ files.c \ + tape.c \ sound.c OBJS = main.o \ @@ -58,6 +58,7 @@ OBJS = main.o \ editor.o \ buttons.o \ files.o \ + tape.o \ sound.o all: $(OBJS) @@ -68,10 +69,3 @@ all: $(OBJS) clean: $(RM) $(OBJS) - -depend: - for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend - -ifeq (.depend,$(wildcard .depend)) -include .depend -endif diff --git a/src/buttons.c b/src/buttons.c index 8b825451..7b0279ee 100644 --- a/src/buttons.c +++ b/src/buttons.c @@ -16,6 +16,7 @@ #include "tools.h" #include "misc.h" #include "editor.h" +#include "tape.h" /****************************************************************/ /********** drawing buttons and corresponding displays **********/ @@ -24,7 +25,7 @@ void DrawVideoDisplay(unsigned long state, unsigned long value) { int i; - int part1 = 0, part2 = 1; + int part_label = 0, part_symbol = 1; int xpos = 0, ypos = 1, xsize = 2, ysize = 3; static char *monatsname[12] = { @@ -33,55 +34,55 @@ void DrawVideoDisplay(unsigned long state, unsigned long value) }; static int video_pos[10][2][4] = { - VIDEO_PLAY_LABEL_XPOS, VIDEO_PLAY_LABEL_YPOS, - VIDEO_PLAY_LABEL_XSIZE,VIDEO_PLAY_LABEL_YSIZE, - VIDEO_PLAY_SYMBOL_XPOS, VIDEO_PLAY_SYMBOL_YPOS, - VIDEO_PLAY_SYMBOL_XSIZE,VIDEO_PLAY_SYMBOL_YSIZE, - - VIDEO_REC_LABEL_XPOS, VIDEO_REC_LABEL_YPOS, - VIDEO_REC_LABEL_XSIZE,VIDEO_REC_LABEL_YSIZE, - VIDEO_REC_SYMBOL_XPOS, VIDEO_REC_SYMBOL_YPOS, - VIDEO_REC_SYMBOL_XSIZE,VIDEO_REC_SYMBOL_YSIZE, - - VIDEO_PAUSE_LABEL_XPOS, VIDEO_PAUSE_LABEL_YPOS, - VIDEO_PAUSE_LABEL_XSIZE,VIDEO_PAUSE_LABEL_YSIZE, - VIDEO_PAUSE_SYMBOL_XPOS, VIDEO_PAUSE_SYMBOL_YPOS, - VIDEO_PAUSE_SYMBOL_XSIZE,VIDEO_PAUSE_SYMBOL_YSIZE, - - VIDEO_DATE_LABEL_XPOS, VIDEO_DATE_LABEL_YPOS, - VIDEO_DATE_LABEL_XSIZE,VIDEO_DATE_LABEL_YSIZE, - VIDEO_DATE_XPOS, VIDEO_DATE_YPOS, - VIDEO_DATE_XSIZE,VIDEO_DATE_YSIZE, - - 0,0, - 0,0, - VIDEO_TIME_XPOS, VIDEO_TIME_YPOS, - VIDEO_TIME_XSIZE,VIDEO_TIME_YSIZE, - - VIDEO_BUTTON_PLAY_XPOS, VIDEO_BUTTON_ANY_YPOS, - VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE, - 0,0, - 0,0, - - VIDEO_BUTTON_REC_XPOS, VIDEO_BUTTON_ANY_YPOS, - VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE, - 0,0, - 0,0, - - VIDEO_BUTTON_PAUSE_XPOS, VIDEO_BUTTON_ANY_YPOS, - VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE, - 0,0, - 0,0, - - VIDEO_BUTTON_STOP_XPOS, VIDEO_BUTTON_ANY_YPOS, - VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE, - 0,0, - 0,0, - - VIDEO_BUTTON_EJECT_XPOS, VIDEO_BUTTON_ANY_YPOS, - VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE, - 0,0, - 0,0 + {{ VIDEO_PLAY_LABEL_XPOS, VIDEO_PLAY_LABEL_YPOS, + VIDEO_PLAY_LABEL_XSIZE,VIDEO_PLAY_LABEL_YSIZE }, + { VIDEO_PLAY_SYMBOL_XPOS, VIDEO_PLAY_SYMBOL_YPOS, + VIDEO_PLAY_SYMBOL_XSIZE,VIDEO_PLAY_SYMBOL_YSIZE }}, + + {{ VIDEO_REC_LABEL_XPOS, VIDEO_REC_LABEL_YPOS, + VIDEO_REC_LABEL_XSIZE,VIDEO_REC_LABEL_YSIZE }, + { VIDEO_REC_SYMBOL_XPOS, VIDEO_REC_SYMBOL_YPOS, + VIDEO_REC_SYMBOL_XSIZE,VIDEO_REC_SYMBOL_YSIZE }}, + + {{ VIDEO_PAUSE_LABEL_XPOS, VIDEO_PAUSE_LABEL_YPOS, + VIDEO_PAUSE_LABEL_XSIZE,VIDEO_PAUSE_LABEL_YSIZE }, + { VIDEO_PAUSE_SYMBOL_XPOS, VIDEO_PAUSE_SYMBOL_YPOS, + VIDEO_PAUSE_SYMBOL_XSIZE,VIDEO_PAUSE_SYMBOL_YSIZE }}, + + {{ VIDEO_DATE_LABEL_XPOS, VIDEO_DATE_LABEL_YPOS, + VIDEO_DATE_LABEL_XSIZE,VIDEO_DATE_LABEL_YSIZE }, + { VIDEO_DATE_XPOS, VIDEO_DATE_YPOS, + VIDEO_DATE_XSIZE,VIDEO_DATE_YSIZE }}, + + {{ 0,0, + 0,0 }, + { VIDEO_TIME_XPOS, VIDEO_TIME_YPOS, + VIDEO_TIME_XSIZE,VIDEO_TIME_YSIZE }}, + + {{ VIDEO_BUTTON_PLAY_XPOS, VIDEO_BUTTON_ANY_YPOS, + VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE }, + { 0,0, + 0,0 }}, + + {{ VIDEO_BUTTON_REC_XPOS, VIDEO_BUTTON_ANY_YPOS, + VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE }, + { 0,0, + 0,0 }}, + + {{ VIDEO_BUTTON_PAUSE_XPOS, VIDEO_BUTTON_ANY_YPOS, + VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE }, + { 0,0, + 0,0 }}, + + {{ VIDEO_BUTTON_STOP_XPOS, VIDEO_BUTTON_ANY_YPOS, + VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE }, + { 0,0, + 0,0 }}, + + {{ VIDEO_BUTTON_EJECT_XPOS, VIDEO_BUTTON_ANY_YPOS, + VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE }, + { 0,0, + 0,0 }} }; for(i=0;i<20;i++) @@ -95,25 +96,38 @@ void DrawVideoDisplay(unsigned long state, unsigned long value) else cx = DOOR_GFX_PAGEX3; /* i gerade => STATE_OFF / PRESS_ON */ - if (video_pos[pos][part1][0]) + if (video_pos[pos][part_label][0] && value != VIDEO_DISPLAY_SYMBOL_ONLY) XCopyArea(display,pix[PIX_DOOR],drawto,gc, - cx + video_pos[pos][part1][xpos], - cy + video_pos[pos][part1][ypos], - video_pos[pos][part1][xsize], - video_pos[pos][part1][ysize], - VX + video_pos[pos][part1][xpos], - VY + video_pos[pos][part1][ypos]); - if (video_pos[pos][part2][0]) + cx + video_pos[pos][part_label][xpos], + cy + video_pos[pos][part_label][ypos], + video_pos[pos][part_label][xsize], + video_pos[pos][part_label][ysize], + VX + video_pos[pos][part_label][xpos], + VY + video_pos[pos][part_label][ypos]); + if (video_pos[pos][part_symbol][0] && value != VIDEO_DISPLAY_LABEL_ONLY) XCopyArea(display,pix[PIX_DOOR],drawto,gc, - cx + video_pos[pos][part2][xpos], - cy + video_pos[pos][part2][ypos], - video_pos[pos][part2][xsize], - video_pos[pos][part2][ysize], - VX + video_pos[pos][part2][xpos], - VY + video_pos[pos][part2][ypos]); + cx + video_pos[pos][part_symbol][xpos], + cy + video_pos[pos][part_symbol][ypos], + video_pos[pos][part_symbol][xsize], + video_pos[pos][part_symbol][ysize], + VX + video_pos[pos][part_symbol][xpos], + VY + video_pos[pos][part_symbol][ypos]); } } + if (state & VIDEO_STATE_FFWD_ON) + { + int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY2; + + XCopyArea(display,pix[PIX_DOOR],drawto,gc, + cx + VIDEO_PLAY_SYMBOL_XPOS, + cy + VIDEO_PLAY_SYMBOL_YPOS, + VIDEO_PLAY_SYMBOL_XSIZE - 2, + VIDEO_PLAY_SYMBOL_YSIZE, + VX + VIDEO_PLAY_SYMBOL_XPOS - 9, + VY + VIDEO_PLAY_SYMBOL_YPOS); + } + if (state & VIDEO_STATE_DATE_ON) { int tag = value % 100; @@ -161,7 +175,7 @@ void DrawCompleteVideoDisplay() if (tape.date && tape.length) { DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date); - DrawVideoDisplay(VIDEO_STATE_TIME_ON,0); + DrawVideoDisplay(VIDEO_STATE_TIME_ON,tape.length_seconds); } XCopyArea(display,drawto,pix[PIX_DB_DOOR],gc, @@ -174,7 +188,7 @@ void DrawSoundDisplay(unsigned long state) pos = (state & BUTTON_SOUND_MUSIC ? SOUND_BUTTON_MUSIC_XPOS : state & BUTTON_SOUND_LOOPS ? SOUND_BUTTON_LOOPS_XPOS : - SOUND_BUTTON_SOUND_XPOS); + SOUND_BUTTON_SIMPLE_XPOS); if (state & BUTTON_ON) cy -= SOUND_BUTTON_YSIZE; @@ -250,23 +264,23 @@ void DrawEditButton(unsigned long state) int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY2; static int edit_pos[6][4] = { - ED_BUTTON_CTRL_XPOS,ED_BUTTON_CTRL_YPOS, - ED_BUTTON_CTRL_XSIZE,ED_BUTTON_CTRL_YSIZE, + {ED_BUTTON_CTRL_XPOS,ED_BUTTON_CTRL_YPOS, + ED_BUTTON_CTRL_XSIZE,ED_BUTTON_CTRL_YSIZE}, - ED_BUTTON_FILL_XPOS,ED_BUTTON_FILL_YPOS, - ED_BUTTON_FILL_XSIZE,ED_BUTTON_FILL_YSIZE, + {ED_BUTTON_FILL_XPOS,ED_BUTTON_FILL_YPOS, + ED_BUTTON_FILL_XSIZE,ED_BUTTON_FILL_YSIZE}, - ED_BUTTON_LEFT_XPOS,ED_BUTTON_LEFT_YPOS, - ED_BUTTON_LEFT_XSIZE,ED_BUTTON_LEFT_YSIZE, + {ED_BUTTON_LEFT_XPOS,ED_BUTTON_LEFT_YPOS, + ED_BUTTON_LEFT_XSIZE,ED_BUTTON_LEFT_YSIZE}, - ED_BUTTON_UP_XPOS,ED_BUTTON_UP_YPOS, - ED_BUTTON_UP_XSIZE,ED_BUTTON_UP_YSIZE, + {ED_BUTTON_UP_XPOS,ED_BUTTON_UP_YPOS, + ED_BUTTON_UP_XSIZE,ED_BUTTON_UP_YSIZE}, - ED_BUTTON_DOWN_XPOS,ED_BUTTON_DOWN_YPOS, - ED_BUTTON_DOWN_XSIZE,ED_BUTTON_DOWN_YSIZE, + {ED_BUTTON_DOWN_XPOS,ED_BUTTON_DOWN_YPOS, + ED_BUTTON_DOWN_XSIZE,ED_BUTTON_DOWN_YSIZE}, - ED_BUTTON_RIGHT_XPOS,ED_BUTTON_RIGHT_YPOS, - ED_BUTTON_RIGHT_XSIZE,ED_BUTTON_RIGHT_YSIZE + {ED_BUTTON_RIGHT_XPOS,ED_BUTTON_RIGHT_YPOS, + ED_BUTTON_RIGHT_XSIZE,ED_BUTTON_RIGHT_YSIZE} }; if (state & ED_BUTTON_PRESSED) @@ -294,17 +308,17 @@ void DrawCtrlButton(unsigned long state) int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY1+80; static int edit_pos[4][4] = { - ED_BUTTON_EDIT_XPOS,ED_BUTTON_EDIT_YPOS, - ED_BUTTON_EDIT_XSIZE,ED_BUTTON_EDIT_YSIZE, + {ED_BUTTON_EDIT_XPOS,ED_BUTTON_EDIT_YPOS, + ED_BUTTON_EDIT_XSIZE,ED_BUTTON_EDIT_YSIZE}, - ED_BUTTON_CLEAR_XPOS,ED_BUTTON_CLEAR_YPOS, - ED_BUTTON_CLEAR_XSIZE,ED_BUTTON_CLEAR_YSIZE, + {ED_BUTTON_CLEAR_XPOS,ED_BUTTON_CLEAR_YPOS, + ED_BUTTON_CLEAR_XSIZE,ED_BUTTON_CLEAR_YSIZE}, - ED_BUTTON_UNDO_XPOS,ED_BUTTON_UNDO_YPOS, - ED_BUTTON_UNDO_XSIZE,ED_BUTTON_UNDO_YSIZE, + {ED_BUTTON_UNDO_XPOS,ED_BUTTON_UNDO_YPOS, + ED_BUTTON_UNDO_XSIZE,ED_BUTTON_UNDO_YSIZE}, - ED_BUTTON_EXIT_XPOS,ED_BUTTON_EXIT_YPOS, - ED_BUTTON_EXIT_XSIZE,ED_BUTTON_EXIT_YSIZE + {ED_BUTTON_EXIT_XPOS,ED_BUTTON_EXIT_YPOS, + ED_BUTTON_EXIT_XSIZE,ED_BUTTON_EXIT_YSIZE} }; if (state & ED_BUTTON_PRESSED) @@ -332,14 +346,14 @@ void DrawElemButton(int button_nr, int button_state) int from_x, from_y, to_x,to_y, size_x, size_y; static int edit_pos[3][4] = { - ED_BUTTON_EUP_XPOS,ED_BUTTON_EUP_YPOS, - ED_BUTTON_EUP_XSIZE,ED_BUTTON_EUP_YSIZE, + {ED_BUTTON_EUP_XPOS,ED_BUTTON_EUP_YPOS, + ED_BUTTON_EUP_XSIZE,ED_BUTTON_EUP_YSIZE}, - ED_BUTTON_EDOWN_XPOS,ED_BUTTON_EDOWN_YPOS, - ED_BUTTON_EDOWN_XSIZE,ED_BUTTON_EDOWN_YSIZE, + {ED_BUTTON_EDOWN_XPOS,ED_BUTTON_EDOWN_YPOS, + ED_BUTTON_EDOWN_XSIZE,ED_BUTTON_EDOWN_YSIZE}, - ED_BUTTON_ELEM_XPOS,ED_BUTTON_ELEM_YPOS, - ED_BUTTON_ELEM_XSIZE,ED_BUTTON_ELEM_YSIZE + {ED_BUTTON_ELEM_XPOS,ED_BUTTON_ELEM_YPOS, + ED_BUTTON_ELEM_XSIZE,ED_BUTTON_ELEM_YSIZE} }; if (button_nr=(DX+SOUND_CONTROL_XPOS) && \ (x)< (DX+SOUND_CONTROL_XPOS + \ @@ -171,17 +183,17 @@ /* values for sound control */ #define BUTTON_SOUND_MUSIC (1L<<0) #define BUTTON_SOUND_LOOPS (1L<<1) -#define BUTTON_SOUND_SOUND (1L<<2) +#define BUTTON_SOUND_SIMPLE (1L<<2) #define BUTTON_RELEASED 0 #define BUTTON_PRESSED (1L<<3) #define BUTTON_OFF 0 #define BUTTON_ON (1L<<4) -#define BUTTON_SOUND_MUSIC_OFF (BUTTON_SOUND_MUSIC | BUTTON_OFF) -#define BUTTON_SOUND_LOOPS_OFF (BUTTON_SOUND_LOOPS | BUTTON_OFF) -#define BUTTON_SOUND_SOUND_OFF (BUTTON_SOUND_SOUND | BUTTON_OFF) -#define BUTTON_SOUND_MUSIC_ON (BUTTON_SOUND_MUSIC | BUTTON_ON) -#define BUTTON_SOUND_LOOPS_ON (BUTTON_SOUND_LOOPS | BUTTON_ON) -#define BUTTON_SOUND_SOUND_ON (BUTTON_SOUND_SOUND | BUTTON_ON) +#define BUTTON_SOUND_MUSIC_OFF (BUTTON_SOUND_MUSIC | BUTTON_OFF) +#define BUTTON_SOUND_LOOPS_OFF (BUTTON_SOUND_LOOPS | BUTTON_OFF) +#define BUTTON_SOUND_SIMPLE_OFF (BUTTON_SOUND_SIMPLE | BUTTON_OFF) +#define BUTTON_SOUND_MUSIC_ON (BUTTON_SOUND_MUSIC | BUTTON_ON) +#define BUTTON_SOUND_LOOPS_ON (BUTTON_SOUND_LOOPS | BUTTON_ON) +#define BUTTON_SOUND_SIMPLE_ON (BUTTON_SOUND_SIMPLE | BUTTON_ON) /* some positions in the game control window */ diff --git a/src/editor.c b/src/editor.c index 7c497689..871eafa8 100644 --- a/src/editor.c +++ b/src/editor.c @@ -29,6 +29,61 @@ static int new_element3 = EL_ERDREICH; int element_shift; int editor_element[] = { + EL_CHAR_A + ('B' - 'A'), + EL_CHAR_A + ('O' - 'A'), + EL_CHAR_A + ('U' - 'A'), + EL_CHAR_A + ('L' - 'A'), + + EL_CHAR_MINUS, + EL_CHAR_A + ('D' - 'A'), + EL_CHAR_A + ('E' - 'A'), + EL_CHAR_A + ('R' - 'A'), + + EL_CHAR_A + ('D' - 'A'), + EL_CHAR_A + ('A' - 'A'), + EL_CHAR_A + ('S' - 'A'), + EL_CHAR_A + ('H' - 'A'), + + EL_SPIELFIGUR, + EL_LEERRAUM, + EL_ERDREICH, + EL_BETON, + + EL_FELSBODEN, + EL_SIEB2_LEER, + EL_AUSGANG_ZU, + EL_AUSGANG_AUF, + + EL_EDELSTEIN_BD, + EL_BUTTERFLY_O, + EL_FIREFLY_O, + EL_FELSBROCKEN, + + EL_BUTTERFLY_L, + EL_FIREFLY_L, + EL_BUTTERFLY_R, + EL_FIREFLY_R, + + EL_AMOEBE_BD, + EL_BUTTERFLY_U, + EL_FIREFLY_U, + EL_LEERRAUM, + + EL_CHAR_A + ('E' - 'A'), + EL_CHAR_A + ('M' - 'A'), + EL_CHAR_A + ('E' - 'A'), + EL_CHAR_MINUS, + + EL_CHAR_A + ('R' - 'A'), + EL_CHAR_A + ('A' - 'A'), + EL_CHAR_A + ('L' - 'A'), + EL_CHAR_A + ('D' - 'A'), + + EL_CHAR_A + ('M' - 'A'), + EL_CHAR_A + ('I' - 'A'), + EL_CHAR_A + ('N' - 'A'), + EL_CHAR_A + ('E' - 'A'), + EL_SPIELFIGUR, EL_LEERRAUM, EL_ERDREICH, @@ -36,70 +91,54 @@ int editor_element[] = EL_BETON, EL_MAUERWERK, - EL_MAUER_LEBT, EL_FELSBODEN, - EL_SIEB_LEER, - EL_SIEB2_LEER, - EL_KOKOSNUSS, - EL_BOMBE, EL_EDELSTEIN, EL_DIAMANT, - EL_EDELSTEIN2, - EL_EDELSTEIN3, + EL_KOKOSNUSS, + EL_BOMBE, + EL_ERZ_EDEL, + EL_ERZ_DIAM, EL_MORAST_LEER, EL_MORAST_VOLL, + + EL_DYNAMIT_AUS, + EL_DYNAMIT, EL_AUSGANG_ZU, EL_AUSGANG_AUF, - EL_KAEFER, - EL_FLIEGER, EL_MAMPFER, - EL_MAMPFER2, - + EL_KAEFER_O, + EL_FLIEGER_O, EL_ZOMBIE, - EL_PACMAN, - EL_DYNAMIT_AUS, - EL_DYNAMIT, + + EL_KAEFER_L, + EL_FLIEGER_L, + EL_KAEFER_R, + EL_FLIEGER_R, + + EL_ABLENK_AUS, + EL_KAEFER_U, + EL_FLIEGER_U, + EL_UNSICHTBAR, EL_BADEWANNE1, EL_SALZSAEURE, EL_BADEWANNE2, - EL_BADEWANNE, + EL_LEERRAUM, EL_BADEWANNE3, EL_BADEWANNE4, EL_BADEWANNE5, - EL_UNSICHTBAR, + EL_LEERRAUM, EL_TROPFEN, EL_AMOEBE_TOT, EL_AMOEBE_NASS, EL_AMOEBE_NORM, - EL_AMOEBE_VOLL, - EL_LIFE, - EL_LIFE_ASYNC, - EL_ABLENK_AUS, - - EL_ERZ_EDEL, - EL_ERZ_DIAM, - EL_ERZ_EDEL2, - EL_ERZ_EDEL3, - - EL_ZEIT_VOLL, - EL_ZEIT_LEER, - - EL_DYNABOMB_NR, - EL_DYNABOMB_SZ, - -/* - EL_BIRNE_AUS, - EL_BIRNE_EIN, -*/ - EL_SCHLUESSEL1, EL_SCHLUESSEL2, EL_SCHLUESSEL3, @@ -115,20 +154,72 @@ int editor_element[] = EL_PFORTE3X, EL_PFORTE4X, - EL_KAEFER_R, - EL_KAEFER_O, - EL_KAEFER_L, - EL_KAEFER_U, + EL_CHAR_A + ('M' - 'A'), + EL_CHAR_A + ('O' - 'A'), + EL_CHAR_A + ('R' - 'A'), + EL_CHAR_A + ('E' - 'A'), - EL_FLIEGER_R, - EL_FLIEGER_O, - EL_FLIEGER_L, - EL_FLIEGER_U, + EL_AMOEBE_VOLL, + EL_EDELSTEIN_GELB, + EL_EDELSTEIN_ROT, + EL_EDELSTEIN_LILA, - EL_PACMAN_R, + EL_ERZ_EDEL_BD, + EL_ERZ_EDEL_GELB, + EL_ERZ_EDEL_ROT, + EL_ERZ_EDEL_LILA, + + EL_LIFE, EL_PACMAN_O, + EL_ZEIT_VOLL, + EL_ZEIT_LEER, + EL_PACMAN_L, + EL_MAMPFER2, + EL_PACMAN_R, + EL_MAUER_LEBT, + + EL_LIFE_ASYNC, EL_PACMAN_U, + EL_BIRNE_AUS, + EL_BIRNE_EIN, + + EL_DYNABOMB_NR, + EL_DYNABOMB_SZ, + EL_DYNABOMB_XL, + EL_BADEWANNE, + + EL_CHAR_A + ('S' - 'A'), + EL_CHAR_A + ('O' - 'A'), + EL_CHAR_A + ('K' - 'A'), + EL_CHAR_A + ('O' - 'A'), + + EL_CHAR_MINUS, + EL_CHAR_A + ('B' - 'A'), + EL_CHAR_A + ('A' - 'A'), + EL_CHAR_A + ('N' - 'A'), + + EL_SOKOBAN_OBJEKT, + EL_SOKOBAN_FELD_LEER, + EL_SOKOBAN_FELD_VOLL, + EL_BETON, + +/* + EL_CHAR_A + ('D' - 'A'), + EL_CHAR_A + ('Y' - 'A'), + EL_CHAR_A + ('N' - 'A'), + EL_CHAR_A + ('A' - 'A'), + + EL_CHAR_A + ('B' - 'A'), + EL_CHAR_A + ('L' - 'A'), + EL_CHAR_A + ('A' - 'A'), + EL_CHAR_A + ('S' - 'A'), + + EL_CHAR_MINUS, + EL_CHAR_A + ('T' - 'A'), + EL_CHAR_A + ('E' - 'A'), + EL_CHAR_A + ('R' - 'A'), +*/ EL_CHAR_AUSRUF, EL_CHAR_ZOLL, @@ -490,7 +581,7 @@ void FloodFill(int from_x, int from_y, int fill_element) { int i,x,y; int old_element; - static int check[4][2] = { -1,0, 0,-1, 1,0, 0,1 }; + static int check[4][2] = { {-1,0}, {0,-1}, {1,0}, {0,1} }; static int safety = 0; safety++; @@ -558,69 +649,61 @@ void LevelEd(int mx, int my, int button) } else /********** EDIT/CTRL-FENSTER **********/ { + static long choice_delay = 0; int choice = CheckElemButtons(mx,my,button); int elem_pos = choice-ED_BUTTON_ELEM; - switch(choice) + if (((choice == ED_BUTTON_EUP && element_shift>0) || + (choice == ED_BUTTON_EDOWN && + element_shift0) || - (choice==ED_BUTTON_EDOWN && - element_shiftelements_in_list-MAX_ELEM_X*MAX_ELEM_Y) - element_shift = elements_in_list-MAX_ELEM_X*MAX_ELEM_Y; - if (element_shift % MAX_ELEM_X) - element_shift += MAX_ELEM_X-(element_shift % MAX_ELEM_X); - - for(i=0;i=0 && elem_poselements_in_list-MAX_ELEM_X*MAX_ELEM_Y) + element_shift = elements_in_list-MAX_ELEM_X*MAX_ELEM_Y; + if (element_shift % MAX_ELEM_X) + element_shift += MAX_ELEM_X-(element_shift % MAX_ELEM_X); + + for(i=0;i=0 && elem_pos=0) { + if (!DelayReached(&choice_delay,10)) + break; if (lev_fieldx<2*SCR_FIELDX-2) break; @@ -653,13 +738,13 @@ void LevelEd(int mx, int my, int button) ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_RIGHT); else DrawMiniLevel(level_xpos,level_ypos); - BackToFront(); - Delay(100000); } break; case ED_BUTTON_RIGHT: if (level_xpos<=lev_fieldx-2*SCR_FIELDX) { + if (!DelayReached(&choice_delay,10)) + break; if (lev_fieldx<2*SCR_FIELDX-2) break; @@ -670,13 +755,13 @@ void LevelEd(int mx, int my, int button) ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_LEFT); else DrawMiniLevel(level_xpos,level_ypos); - BackToFront(); - Delay(100000); } break; case ED_BUTTON_UP: if (level_ypos>=0) { + if (!DelayReached(&choice_delay,10)) + break; if (lev_fieldy<2*SCR_FIELDY-2) break; @@ -687,13 +772,13 @@ void LevelEd(int mx, int my, int button) ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_DOWN); else DrawMiniLevel(level_xpos,level_ypos); - BackToFront(); - Delay(100000); } break; case ED_BUTTON_DOWN: if (level_ypos<=lev_fieldy-2*SCR_FIELDY) { + if (!DelayReached(&choice_delay,10)) + break; if (lev_fieldy<2*SCR_FIELDY-2) break; @@ -704,8 +789,6 @@ void LevelEd(int mx, int my, int button) ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_UP); else DrawMiniLevel(level_xpos,level_ypos); - BackToFront(); - Delay(100000); } break; default: @@ -758,7 +841,6 @@ void LevelEd(int mx, int my, int button) } else /********** KONTROLL-FENSTER **********/ { - static long choice_delay = 0; int choice = CheckCountButtons(mx,my,button); int step = (button==1 ? 1 : button==2 ? 5 : button==3 ? 10 : 0); @@ -910,7 +992,8 @@ void LevelEd(int mx, int my, int button) } break; case ED_BUTTON_UNDO: - if (AreYouSure("Exit without saving ?",AYS_ASK | AYS_STAY_OPEN)) + if (leveldir[leveldir_nr].readonly || + AreYouSure("Exit without saving ?",AYS_ASK | AYS_STAY_OPEN)) { CloseDoor(DOOR_CLOSE_BOTH); game_status=MAINMENU; @@ -925,6 +1008,13 @@ void LevelEd(int mx, int my, int button) case ED_BUTTON_EXIT: { int figur_vorhanden = FALSE; + + if (leveldir[leveldir_nr].readonly) + { + AreYouSure("This level is read only !",AYS_CONFIRM); + break; + } + for(y=0;ykeycode; - KeySym new_key = XLookupKeysym(event,event->state); - int new_key_status = (event->type==KeyPress ? KEY_PRESSED : KEY_RELEASED); + int key_status = (event->type == KeyPress ? KEY_PRESSED : KEY_RELEASED); + unsigned int event_state = (game_status != PLAYING ? event->state : 0); + KeySym key = XLookupKeysym(event, event_state); - if (game_status==PLAYING && - (old_keycode!=new_keycode || key_status!=new_key_status)) - { - DigField(0,0,DF_NO_PUSH); - SnapField(0,0); - } - - if (event->type==KeyPress) - { - key_status = KEY_PRESSED; - HandleKey(new_key); - old_keycode = new_keycode; - } - else if (key_status==KEY_PRESSED && old_keycode==new_keycode) - key_status = KEY_RELEASED; + HandleKey(key, key_status); } void HandleFocusEvent(int focus_status) { + static int old_joystick_status = -1; + if (focus_status==FOCUS_OUT) + { XAutoRepeatOn(display); - else if (game_status==PLAYING) - XAutoRepeatOff(display); + old_joystick_status = joystick_status; + joystick_status = JOYSTICK_OFF; + } + else + { + if (game_status == PLAYING) + XAutoRepeatOff(display); + if (old_joystick_status != -1) + joystick_status = old_joystick_status; + } } void HandleButton(int mx, int my, int button) @@ -263,41 +258,128 @@ void HandleButton(int mx, int my, int button) HandleSetupScreen(mx,my,0,0,button); break; case PLAYING: - if (!LevelSolved) - { - switch(GameActions(mx,my,button)) - { - case ACT_GAME_OVER: - game_status = MAINMENU; - DrawMainMenu(); - BackToFront(); - break; - case ACT_NEW_GAME: - game_status = PLAYING; - InitGame(); - break; - case ACT_GO_ON: - break; - default: - break; - } - } - BackToFront(); - Delay(10000); + HandleGameActions(); break; default: break; } } -void HandleKey(KeySym key) +int Gamespeed = 4; +int Movemethod = 0; +int Movespeed[2] = { 10, 3 }; + +void HandleKey(KeySym key, int key_status) { - static KeySym old_key = 0; + int joy = 0; - if (!key) - key = old_key; - else - old_key = key; + /* Map cursor keys to joystick directions */ + + switch(key) + { + case XK_Left: /* normale Richtungen */ +#ifdef XK_KP_Left + case XK_KP_Left: +#endif + case XK_KP_4: + case XK_J: + case XK_j: + joy |= JOY_LEFT; + break; + case XK_Right: +#ifdef XK_KP_Right + case XK_KP_Right: +#endif + case XK_KP_6: + case XK_K: + case XK_k: + joy |= JOY_RIGHT; + break; + case XK_Up: +#ifdef XK_KP_Up + case XK_KP_Up: +#endif + case XK_KP_8: + case XK_I: + case XK_i: + joy |= JOY_UP; + break; + case XK_Down: +#ifdef XK_KP_Down + case XK_KP_Down: +#endif + case XK_KP_2: + case XK_M: + case XK_m: + joy |= JOY_DOWN; + break; +#ifdef XK_KP_Home + case XK_KP_Home: /* Diagonalrichtungen */ +#endif + case XK_KP_7: + joy |= JOY_UP | JOY_LEFT; + break; +#ifdef XK_KP_Page_Up + case XK_KP_Page_Up: +#endif + case XK_KP_9: + joy = JOY_UP | JOY_RIGHT; + break; +#ifdef XK_KP_End + case XK_KP_End: +#endif + case XK_KP_1: + joy |= JOY_DOWN | JOY_LEFT; + break; +#ifdef XK_KP_Page_Down + case XK_KP_Page_Down: +#endif + case XK_KP_3: + joy |= JOY_DOWN | JOY_RIGHT; + break; + case XK_S: /* Feld entfernen */ + case XK_s: + joy |= JOY_BUTTON_1 | JOY_LEFT; + break; + case XK_D: + case XK_d: + joy |= JOY_BUTTON_1 | JOY_RIGHT; + break; + case XK_E: + case XK_e: + joy |= JOY_BUTTON_1 | JOY_UP; + break; + case XK_X: + case XK_x: + joy |= JOY_BUTTON_1 | JOY_DOWN; + break; + case XK_Shift_L: /* Linker Feuerknopf */ + joy |= JOY_BUTTON_1; + break; + case XK_Shift_R: /* Rechter Feuerknopf */ + case XK_B: /* (Bombe legen) */ + case XK_b: + joy |= JOY_BUTTON_2; + break; + default: + break; + } + + if (joy) + { + if (key_status == KEY_PRESSED) + key_joystick_mapping |= joy; + else + key_joystick_mapping &= ~joy; + + HandleJoystick(); + + if (game_status != PLAYING) + key_joystick_mapping = 0; + } + + if (key_status == KEY_RELEASED) + return; if (key==XK_Escape && game_status!=MAINMENU) /* quick quit to MAINMENU */ { @@ -319,8 +401,6 @@ void HandleKey(KeySym key) case CHOOSELEVEL: case SETUP: { - int dx = 0, dy = 0; - switch(key) { case XK_Return: @@ -331,55 +411,9 @@ void HandleKey(KeySym key) else if (game_status==SETUP) HandleSetupScreen(0,0,0,0,MB_MENU_CHOICE); break; - case XK_Left: -#ifdef XK_KP_Left - case XK_KP_Left: -#endif - case XK_KP_4: - case XK_J: - case XK_j: - dx = -1; - break; - case XK_Right: -#ifdef XK_KP_Right - case XK_KP_Right: -#endif - case XK_KP_6: - case XK_K: - case XK_k: - dx = 1; - break; - case XK_Up: -#ifdef XK_KP_Up - case XK_KP_Up: -#endif - case XK_KP_8: - case XK_I: - case XK_i: - dy = -1; - break; - case XK_Down: -#ifdef XK_KP_Down - case XK_KP_Down: -#endif - case XK_KP_2: - case XK_M: - case XK_m: - dy = 1; - break; default: break; } - - if (dx || dy) - { - if (game_status==MAINMENU) - HandleMainMenu(0,0,dx,dy,MB_MENU_MARK); - else if (game_status==CHOOSELEVEL) - HandleChooseLevel(0,0,dx,dy,MB_MENU_MARK); - else if (game_status==SETUP) - HandleSetupScreen(0,0,dx,dy,MB_MENU_MARK); - } break; } case HELPSCREEN: @@ -402,128 +436,89 @@ void HandleKey(KeySym key) break; case PLAYING: { - int mvx = 0, mvy = 0; - int sbx = 0, sby = 0; - int joy = 0; - BOOL bomb = FALSE; - BOOL moved = FALSE, snapped = FALSE, bombed = FALSE; - switch(key) { - case XK_Left: /* normale Richtungen */ -#ifdef XK_KP_Left - case XK_KP_Left: -#endif - case XK_KP_4: - case XK_J: - case XK_j: - mvx = -1; - joy = JOY_LEFT; + +#ifdef DEBUG + case XK_0: + case XK_1: + case XK_2: + case XK_3: + case XK_4: + case XK_5: + case XK_6: + case XK_7: + case XK_8: + case XK_9: + Movespeed[Movemethod] = (Movemethod == 0 ? 4 : 0) + (key - XK_0); + printf("method == %d, speed == %d\n", + Movemethod, Movespeed[Movemethod]); break; - case XK_Right: -#ifdef XK_KP_Right - case XK_KP_Right: -#endif - case XK_KP_6: - case XK_K: - case XK_k: - mvx = 1; - joy = JOY_RIGHT; + + case XK_a: + Movemethod = !Movemethod; + printf("method == %d, speed == %d\n", + Movemethod, Movespeed[Movemethod]); break; - case XK_Up: -#ifdef XK_KP_Up - case XK_KP_Up: -#endif - case XK_KP_8: - case XK_I: - case XK_i: - mvy = -1; - joy = JOY_UP; + + case XK_f: + Gamespeed = 2; + printf("gamespeed == %d\n", Gamespeed); break; - case XK_Down: -#ifdef XK_KP_Down - case XK_KP_Down: -#endif - case XK_KP_2: - case XK_M: - case XK_m: - mvy = 1; - joy = JOY_DOWN; + case XK_g: + Gamespeed = 3; + printf("gamespeed == %d\n", Gamespeed); break; -#ifdef XK_KP_Home - case XK_KP_Home: /* Diagonalrichtungen */ -#endif - case XK_KP_7: - mvx = -1; - mvy = -1; - joy = JOY_UP | JOY_LEFT; + case XK_h: + Gamespeed = 4; + printf("gamespeed == %d\n", Gamespeed); break; -#ifdef XK_KP_Page_Up - case XK_KP_Page_Up: -#endif - case XK_KP_9: - mvx = 1; - mvy = -1; - joy = JOY_UP | JOY_RIGHT; + case XK_l: + Gamespeed = 10; + printf("gamespeed == %d\n", Gamespeed); break; -#ifdef XK_KP_End - case XK_KP_End: -#endif - case XK_KP_1: - mvx = -1; - mvy = 1; - joy = JOY_DOWN | JOY_LEFT; + + case XK_Q: + case XK_q: + Dynamite = 1000; break; -#ifdef XK_KP_Page_Down - case XK_KP_Page_Down: #endif - case XK_KP_3: - mvx = 1; - mvy = 1; - joy = JOY_DOWN | JOY_RIGHT; - break; - case XK_S: /* Feld entfernen */ - case XK_s: - sbx = -1; - joy = JOY_BUTTON_1 | JOY_LEFT; - break; - case XK_D: - case XK_d: - sbx = 1; - joy = JOY_BUTTON_1 | JOY_RIGHT; - break; - case XK_E: - case XK_e: - sby = -1; - joy = JOY_BUTTON_1 | JOY_UP; - break; - case XK_X: + case XK_x: - sby = 1; - joy = JOY_BUTTON_1 | JOY_DOWN; - break; - case XK_B: /* Bombe legen */ - case XK_b: - bomb = TRUE; - joy = JOY_BUTTON_2; - break; - case XK_Q: - Dynamite = 1000; + /* + { + int i,j,k, num_steps = 4, step_size = TILEX / num_steps; + + for(i=0;i<10;i++) + { + for(j=0;j> 24) & 0xff,file); fputc((tape.random_seed >> 16) & 0xff,file); fputc((tape.random_seed >> 8) & 0xff,file); @@ -545,6 +568,8 @@ void SaveLevelTape(int level_nr) chmod(filename, LEVREC_PERMS); + tape.changed = FALSE; + if (new_tape) AreYouSure("tape saved !",AYS_CONFIRM); } @@ -556,7 +581,7 @@ void SaveScore(int level_nr) FILE *file; sprintf(filename,"%s/%s/%s", - SCORE_PATH,leveldir[leveldir_nr].filename,SCORE_FILENAME); + level_directory,leveldir[leveldir_nr].filename,SCORE_FILENAME); if (!(file=fopen(filename,"r+"))) { @@ -585,10 +610,11 @@ void SavePlayerInfo(int mode) char cookie[MAX_FILENAME]; FILE *file; struct PlayerInfo default_player; + int version_10_file = FALSE; if (mode==PLAYER_LEVEL) sprintf(filename,"%s/%s/%s", - NAMES_PATH,leveldir[leveldir_nr].filename,NAMES_FILENAME); + level_directory,leveldir[leveldir_nr].filename,NAMES_FILENAME); else sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME); @@ -600,7 +626,9 @@ void SavePlayerInfo(int mode) } fgets(cookie,NAMES_COOKIE_LEN,file); - if (strcmp(cookie,NAMES_COOKIE)) /* ungültiges Format? */ + if (!strcmp(cookie,NAMES_COOKIE_10)) /* altes Format? */ + version_10_file = TRUE; + else if (strcmp(cookie,NAMES_COOKIE)) /* ungültiges Format? */ { fprintf(stderr,"%s: wrong format of names file '%s'!\n", progname,filename); @@ -617,17 +645,27 @@ void SavePlayerInfo(int mode) default_player.handicap = fgetc(file); default_player.setup = (fgetc(file)<<8) | fgetc(file); default_player.leveldir_nr = fgetc(file); + if (!version_10_file) + { + default_player.level_nr = fgetc(file); + for(i=0;i<10;i++) /* currently unused bytes */ + fgetc(file); + } + else + default_player.level_nr = default_player.handicap; if (feof(file)) /* Spieler noch nicht in Liste enthalten */ break; else /* prüfen, ob Spieler in Liste enthalten */ if (!strncmp(default_player.login_name,player.login_name,MAX_NAMELEN-1)) { - fseek(file,-(2*MAX_NAMELEN+1+2+1),SEEK_CUR); + fseek(file,-(2*MAX_NAMELEN+1+2+1+(version_10_file ? 0 : 11)),SEEK_CUR); break; } } + player.level_nr = level_nr; + for(i=0;i=MIDPOSX-1) scroll_x = @@ -151,6 +184,8 @@ void InitGame() scroll_y = (JY<=lev_fieldy-MIDPOSY ? JY-MIDPOSY : lev_fieldy-SCR_FIELDY+1); + CloseDoor(DOOR_CLOSE_1); + DrawLevel(); DrawLevelElement(JX,JY,EL_SPIELFIGUR); FadeToFront(); @@ -177,9 +212,9 @@ void InitGame() DrawGameButton(BUTTON_GAME_STOP); DrawGameButton(BUTTON_GAME_PAUSE); DrawGameButton(BUTTON_GAME_PLAY); - DrawSoundDisplay(BUTTON_SOUND_MUSIC | (BUTTON_ON * sound_music_on)); - DrawSoundDisplay(BUTTON_SOUND_LOOPS | (BUTTON_ON * sound_loops_on)); - DrawSoundDisplay(BUTTON_SOUND_SOUND | (BUTTON_ON * sound_on)); + DrawSoundDisplay(BUTTON_SOUND_MUSIC | (BUTTON_ON * sound_music_on)); + DrawSoundDisplay(BUTTON_SOUND_LOOPS | (BUTTON_ON * sound_loops_on)); + DrawSoundDisplay(BUTTON_SOUND_SIMPLE | (BUTTON_ON * sound_simple_on)); XCopyArea(display,drawto,pix[PIX_DB_DOOR],gc, DX+GAME_CONTROL_XPOS,DY+GAME_CONTROL_YPOS, GAME_CONTROL_XSIZE,2*GAME_CONTROL_YSIZE, @@ -199,15 +234,15 @@ void InitMovDir(int x, int y) int i, element = Feld[x][y]; static int xy[4][2] = { - 0,+1, - +1,0, - 0,-1, - -1,0 + { 0,+1 }, + { +1,0 }, + { 0,-1 }, + { -1,0 } }; static int direction[2][4] = { - MV_RIGHT, MV_UP, MV_LEFT, MV_DOWN, - MV_LEFT, MV_DOWN, MV_RIGHT, MV_UP + { MV_RIGHT, MV_UP, MV_LEFT, MV_DOWN }, + { MV_LEFT, MV_DOWN, MV_RIGHT, MV_UP } }; switch(element) @@ -226,6 +261,20 @@ void InitMovDir(int x, int y) Feld[x][y] = EL_FLIEGER; MovDir[x][y] = direction[0][element-EL_FLIEGER_R]; break; + case EL_BUTTERFLY_R: + case EL_BUTTERFLY_O: + case EL_BUTTERFLY_L: + case EL_BUTTERFLY_U: + Feld[x][y] = EL_BUTTERFLY; + MovDir[x][y] = direction[0][element-EL_BUTTERFLY_R]; + break; + case EL_FIREFLY_R: + case EL_FIREFLY_O: + case EL_FIREFLY_L: + case EL_FIREFLY_U: + Feld[x][y] = EL_FIREFLY; + MovDir[x][y] = direction[0][element-EL_FIREFLY_R]; + break; case EL_PACMAN_R: case EL_PACMAN_O: case EL_PACMAN_L: @@ -235,7 +284,10 @@ void InitMovDir(int x, int y) break; default: MovDir[x][y] = 1<0) + if (TimeLeft) { - for(;TimeLeft>=0;TimeLeft--) + if (sound_loops_on) + PlaySoundExt(SND_SIRR,PSND_MAX_VOLUME,PSND_MAX_RIGHT,PSND_LOOP); + + while(TimeLeft>0) { if (!sound_loops_on) PlaySoundStereo(SND_SIRR,PSND_MAX_RIGHT); if (TimeLeft && !(TimeLeft % 10)) RaiseScore(level.score[SC_ZEITBONUS]); + if (TimeLeft > 100 && !(TimeLeft % 10)) + TimeLeft -= 10; + else + TimeLeft--; DrawText(DX_TIME,DY_TIME,int2str(TimeLeft,3),FS_SMALL,FC_YELLOW); BackToFront(); Delay(10000); } + + if (sound_loops_on) + StopSound(SND_SIRR); } - if (sound_loops_on) - StopSound(SND_SIRR); FadeSounds(); + /* Hero disappears */ + DrawLevelElement(JX,JY,Feld[JX][JY]); + JX = JY = -1; + BackToFront(); + if (tape.playing) return; CloseDoor(DOOR_CLOSE_1); + if (tape.recording) + { + TapeStop(); + SaveLevelTape(tape.level_nr); /* Ask to save tape */ + } + if (level_nr==player.handicap && - level_nr6) - phase = 6; - if (Store[x][y]) { DrawGraphic(SCROLLX(x),SCROLLY(y),el2gfx(Store[x][y])); - if (PLAYER(x,y)) + if (IS_PLAYER(x,y)) DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR); } - else if (PLAYER(x,y)) + else if (IS_PLAYER(x,y)) DrawGraphic(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR); - if (Store[x][y] || PLAYER(x,y)) - DrawGraphicThruMask(SCROLLX(x),SCROLLY(y),GFX_DYNAMIT+phase); + if (Feld[x][y]==EL_DYNAMIT) + { + int phase = (48-MovDelay[x][y])/6; + + if (phase>6) + phase = 6; + + if (Store[x][y] || IS_PLAYER(x,y)) + DrawGraphicThruMask(SCROLLX(x),SCROLLY(y),GFX_DYNAMIT+phase); + else + DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_DYNAMIT+phase); + } else - DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_DYNAMIT+phase); + { + int phase = ((48-MovDelay[x][y])/3) % 8; + + if (phase>3) + phase = 7-phase; + + if (Store[x][y] || IS_PLAYER(x,y)) + DrawGraphicThruMask(SCROLLX(x),SCROLLY(y),GFX_DYNABOMB+phase); + else + DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_DYNABOMB+phase); + } } void CheckDynamite(int x, int y) { - CheckExploding = TRUE; - if (MovDelay[x][y]) /* neues Dynamit / in Wartezustand */ { MovDelay[x][y]--; if (MovDelay[x][y]) { if (!(MovDelay[x][y] % 6)) - { - DrawDynamite(x,y); PlaySoundLevel(x,y,SND_ZISCH); - } + + if (Feld[x][y]==EL_DYNAMIT && !(MovDelay[x][y] % 6)) + DrawDynamite(x,y); + else if (Feld[x][y]==EL_DYNABOMB && !(MovDelay[x][y] % 3)) + DrawDynamite(x,y); return; } @@ -555,8 +641,12 @@ void Explode(int ex, int ey, int phase, int mode) if (element==EL_EXPLODING) element = Store2[x][y]; - if (PLAYER(ex,ey) || center_element==EL_KAEFER) + if (IS_PLAYER(ex,ey)) + Store[x][y] = EL_EDELSTEIN_GELB; + else if (center_element==EL_KAEFER) Store[x][y] = ((x==ex && y==ey) ? EL_DIAMANT : EL_EDELSTEIN); + else if (center_element==EL_BUTTERFLY) + Store[x][y] = EL_EDELSTEIN_BD; else if (center_element==EL_MAMPFER) Store[x][y] = level.mampfer_inhalt[MampferNr][x-ex+1][y-ey+1]; else if (center_element==EL_AMOEBA2DIAM) @@ -565,18 +655,28 @@ void Explode(int ex, int ey, int phase, int mode) Store[x][y] = EL_EDELSTEIN; else if (element==EL_ERZ_DIAM) Store[x][y] = EL_DIAMANT; - else if (element==EL_ERZ_EDEL2) - Store[x][y] = EL_EDELSTEIN2; - else if (element==EL_ERZ_EDEL3) - Store[x][y] = EL_EDELSTEIN3; + else if (element==EL_ERZ_EDEL_BD) + Store[x][y] = EL_EDELSTEIN_BD; + else if (element==EL_ERZ_EDEL_GELB) + Store[x][y] = EL_EDELSTEIN_GELB; + else if (element==EL_ERZ_EDEL_ROT) + Store[x][y] = EL_EDELSTEIN_ROT; + else if (element==EL_ERZ_EDEL_LILA) + Store[x][y] = EL_EDELSTEIN_LILA; else if (!IS_PFORTE(Store[x][y])) Store[x][y] = EL_LEERRAUM; if (x!=ex || y!=ey || center_element==EL_AMOEBA2DIAM || mode==EX_BORDER) Store2[x][y] = element; - if (AmoebaNr[x][y] && (element==EL_AMOEBE_VOLL || element==EL_AMOEBING)) + if (AmoebaNr[x][y] && + (element==EL_AMOEBE_VOLL || + element==EL_AMOEBE_BD || + element==EL_AMOEBING)) + { AmoebaCnt[AmoebaNr[x][y]]--; + AmoebaCnt2[AmoebaNr[x][y]]--; + } RemoveMovingField(x,y); Feld[x][y] = EL_EXPLODING; @@ -604,12 +704,15 @@ void Explode(int ex, int ey, int phase, int mode) { int element = Store2[x][y]; - if (PLAYER(x,y)) + if (IS_PLAYER(x,y)) KillHero(); else if (element==EL_BOMBE || element==EL_DYNAMIT || element==EL_DYNAMIT_AUS || element==EL_DYNABOMB || + element==EL_DYNABOMB_NR || + element==EL_DYNABOMB_SZ || + element==EL_DYNABOMB_XL || element==EL_KAEFER) { Feld[x][y] = Store2[x][y]; @@ -638,8 +741,6 @@ void Explode(int ex, int ey, int phase, int mode) DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_EXPLOSION+(phase/delay-1)); } - - CheckExploding = TRUE; } void DynaExplode(int ex, int ey, int size) @@ -647,10 +748,10 @@ void DynaExplode(int ex, int ey, int size) int i,j; static int xy[4][2] = { - 0,-1, - -1,0, - +1,0, - 0,+1 + { 0,-1 }, + { -1,0 }, + { +1,0 }, + { 0,+1 } }; Explode(ex,ey,0,EX_CENTER); @@ -661,11 +762,19 @@ void DynaExplode(int ex, int ey, int size) { int x = ex+j*xy[i%4][0]; int y = ey+j*xy[i%4][1]; + int element; if (!IN_LEV_FIELD(x,y) || IS_MASSIV(Feld[x][y])) break; + element = Feld[x][y]; Explode(x,y,0,EX_BORDER); + + if (element != EL_LEERRAUM && + element != EL_ERDREICH && + element != EL_EXPLODING && + !DynaBombXL) + break; } } @@ -676,35 +785,35 @@ void Bang(int x, int y) { int element = Feld[x][y]; - CheckExploding = TRUE; PlaySoundLevel(x,y,SND_ROAAAR); switch(element) { case EL_KAEFER: - RaiseScore(level.score[SC_KAEFER]); - break; case EL_FLIEGER: - RaiseScore(level.score[SC_FLIEGER]); - break; + case EL_BUTTERFLY: + case EL_FIREFLY: case EL_MAMPFER: case EL_MAMPFER2: - RaiseScore(level.score[SC_MAMPFER]); - break; case EL_ZOMBIE: - RaiseScore(level.score[SC_ZOMBIE]); - break; case EL_PACMAN: - RaiseScore(level.score[SC_PACMAN]); + RaiseScoreElement(element); + Explode(x,y,0,EX_NORMAL); + break; + case EL_DYNABOMB: + case EL_DYNABOMB_NR: + case EL_DYNABOMB_SZ: + case EL_DYNABOMB_XL: + DynaExplode(x,y,DynaBombSize); + break; + case EL_BIRNE_AUS: + case EL_BIRNE_EIN: + Explode(x,y,0,EX_CENTER); break; default: + Explode(x,y,0,EX_NORMAL); break; } - - if (element==EL_DYNABOMB) - DynaExplode(x,y,DynaBombSize); - else - Explode(x,y,0,EX_NORMAL); } void Blurb(int x, int y) @@ -731,8 +840,6 @@ void Blurb(int x, int y) { int graphic = (element==EL_BLURB_LEFT ? GFX_BLURB_LEFT : GFX_BLURB_RIGHT); - CheckExploding = TRUE; - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ MovDelay[x][y] = 5; @@ -780,7 +887,7 @@ void Impact(int x, int y) /* Auftreffendes Element ist Säuretropfen */ if (element==EL_TROPFEN && (lastline || object_hit)) { - if (object_hit && PLAYER(x,y+1)) + if (object_hit && IS_PLAYER(x,y+1)) KillHero(); else { @@ -793,24 +900,36 @@ void Impact(int x, int y) /* Welches Element kriegt was auf die Rübe? */ if (!lastline && object_hit) { - int smashed = Feld[x][y+1]; + int smashed = MovingOrBlocked2Element(x,y+1); + + if (CAN_CHANGE(element) && + (smashed==EL_SIEB_LEER || smashed==EL_SIEB2_LEER) && !SiebAktiv) + SiebAktiv = level.dauer_sieb * FRAMES_PER_SECOND; - if (PLAYER(x,y+1)) + if (IS_PLAYER(x,y+1)) { KillHero(); return; } - else if (element==EL_FELSBROCKEN || - element==EL_EDELSTEIN2 || element==EL_EDELSTEIN3) + else if (element==EL_EDELSTEIN_BD) { - if (IS_ENEMY(MovingOrBlocked2Element(x,y+1))) + if (IS_ENEMY(smashed) && IS_BD_ELEMENT(smashed)) + { + Bang(x,y+1); + return; + } + } + else if (element==EL_FELSBROCKEN) + { + if (IS_ENEMY(smashed)) { Bang(x,y+1); return; } else if (!IS_MOVING(x,y+1)) { - if (smashed==EL_BOMBE) + if (smashed==EL_BOMBE || + smashed==EL_BIRNE_AUS || smashed==EL_BIRNE_EIN) { Bang(x,y+1); return; @@ -819,7 +938,7 @@ void Impact(int x, int y) { Feld[x][y+1] = EL_CRACKINGNUT; PlaySoundLevel(x,y,SND_KNACK); - RaiseScore(level.score[SC_KOKOSNUSS]); + RaiseScoreElement(EL_KOKOSNUSS); return; } else if (smashed==EL_DIAMANT) @@ -832,9 +951,12 @@ void Impact(int x, int y) } } - /* Kein Geräusch beim Durchqueren des Siebes */ + /* Geräusch beim Durchqueren des Siebes */ if (!lastline && (Feld[x][y+1]==EL_SIEB_LEER || Feld[x][y+1]==EL_SIEB2_LEER)) + { + PlaySoundLevel(x,y,SND_QUIRK); return; + } /* Geräusch beim Auftreffen */ if (lastline || object_hit) @@ -844,8 +966,10 @@ void Impact(int x, int y) switch(element) { case EL_EDELSTEIN: - case EL_EDELSTEIN2: - case EL_EDELSTEIN3: + case EL_EDELSTEIN_BD: + case EL_EDELSTEIN_GELB: + case EL_EDELSTEIN_ROT: + case EL_EDELSTEIN_LILA: case EL_DIAMANT: sound = SND_PLING; break; @@ -878,167 +1002,155 @@ void Impact(int x, int y) void TurnRound(int x, int y) { + static struct + { + int x,y; + } move_xy[] = + { + { 0,0 }, + {-1,0 }, + {+1,0 }, + { 0,0 }, + { 0,-1 }, + { 0,0 }, { 0,0 }, { 0,0 }, + { 0,+1 } + }; + static struct + { + int left,right,back; + } turn[] = + { + { 0, 0, 0 }, + { MV_DOWN, MV_UP, MV_RIGHT }, + { MV_UP, MV_DOWN, MV_LEFT }, + { 0, 0, 0 }, + { MV_LEFT, MV_RIGHT, MV_DOWN }, + { 0,0,0 }, { 0,0,0 }, { 0,0,0 }, + { MV_RIGHT, MV_LEFT, MV_UP } + }; + int element = Feld[x][y]; - int direction = MovDir[x][y]; + int old_move_dir = MovDir[x][y]; + int left_dir = turn[old_move_dir].left; + int right_dir = turn[old_move_dir].right; + int back_dir = turn[old_move_dir].back; + + int left_dx = move_xy[left_dir].x, left_dy = move_xy[left_dir].y; + int right_dx = move_xy[right_dir].x, right_dy = move_xy[right_dir].y; + int move_dx = move_xy[old_move_dir].x, move_dy = move_xy[old_move_dir].y; + + int left_x = x+left_dx, left_y = y+left_dy; + int right_x = x+right_dx, right_y = y+right_dy; + int move_x = x+move_dx, move_y = y+move_dy; - if (element==EL_KAEFER) + if (element==EL_KAEFER || element==EL_BUTTERFLY) { TestIfBadThingHitsOtherBadThing(x,y); - if (MovDir[x][y]==MV_LEFT) - { - if (IN_LEV_FIELD(x,y-1) && IS_FREE(x,y-1)) - MovDir[x][y]=MV_UP; - else if (!IN_LEV_FIELD(x-1,y) || !IS_FREE(x-1,y)) - MovDir[x][y]=MV_DOWN; - } - else if (MovDir[x][y]==MV_RIGHT) - { - if (IN_LEV_FIELD(x,y+1) && IS_FREE(x,y+1)) - MovDir[x][y]=MV_DOWN; - else if (!IN_LEV_FIELD(x+1,y) || !IS_FREE(x+1,y)) - MovDir[x][y]=MV_UP; - } - else if (MovDir[x][y]==MV_UP) - { - if (IN_LEV_FIELD(x+1,y) && IS_FREE(x+1,y)) - MovDir[x][y]=MV_RIGHT; - else if (!IN_LEV_FIELD(x,y-1) || !IS_FREE(x,y-1)) - MovDir[x][y]=MV_LEFT; - } - else if (MovDir[x][y]==MV_DOWN) - { - if (IN_LEV_FIELD(x-1,y) && IS_FREE(x-1,y)) - MovDir[x][y]=MV_LEFT; - else if (!IN_LEV_FIELD(x,y+1) || !IS_FREE(x,y+1)) - MovDir[x][y]=MV_RIGHT; - } + if (IN_LEV_FIELD(right_x,right_y) && + IS_FREE_OR_PLAYER(right_x,right_y)) + MovDir[x][y] = right_dir; + else if (!IN_LEV_FIELD(move_x,move_y) || + !IS_FREE_OR_PLAYER(move_x,move_y)) + MovDir[x][y] = left_dir; - if (direction!=MovDir[x][y]) - MovDelay[x][y]=5; + if (element==EL_KAEFER && MovDir[x][y] != old_move_dir) + MovDelay[x][y] = 5; + else if (element==EL_BUTTERFLY) /* && MovDir[x][y]==left_dir) */ + MovDelay[x][y] = 1; } - else if (element==EL_FLIEGER) + else if (element==EL_FLIEGER || element==EL_FIREFLY) { TestIfBadThingHitsOtherBadThing(x,y); - if (MovDir[x][y]==MV_LEFT) - { - if (IN_LEV_FIELD(x,y+1) && IS_FREE(x,y+1)) - MovDir[x][y]=MV_DOWN; - else if (!IN_LEV_FIELD(x-1,y) || !IS_FREE(x-1,y)) - MovDir[x][y]=MV_UP; - } - else if (MovDir[x][y]==MV_RIGHT) - { - if (IN_LEV_FIELD(x,y-1) && IS_FREE(x,y-1)) - MovDir[x][y]=MV_UP; - else if (!IN_LEV_FIELD(x+1,y) || !IS_FREE(x+1,y)) - MovDir[x][y]=MV_DOWN; - } - else if (MovDir[x][y]==MV_UP) - { - if (IN_LEV_FIELD(x-1,y) && IS_FREE(x-1,y)) - MovDir[x][y]=MV_LEFT; - else if (!IN_LEV_FIELD(x,y-1) || !IS_FREE(x,y-1)) - MovDir[x][y]=MV_RIGHT; - } - else if (MovDir[x][y]==MV_DOWN) - { - if (IN_LEV_FIELD(x+1,y) && IS_FREE(x+1,y)) - MovDir[x][y]=MV_RIGHT; - else if (!IN_LEV_FIELD(x,y+1) || !IS_FREE(x,y+1)) - MovDir[x][y]=MV_LEFT; - } + if (IN_LEV_FIELD(left_x,left_y) && + IS_FREE_OR_PLAYER(left_x,left_y)) + MovDir[x][y] = left_dir; + else if (!IN_LEV_FIELD(move_x,move_y) || + !IS_FREE_OR_PLAYER(move_x,move_y)) + MovDir[x][y] = right_dir; - if (direction!=MovDir[x][y]) - MovDelay[x][y]=5; + if (element==EL_FLIEGER && MovDir[x][y] != old_move_dir) + MovDelay[x][y] = 5; + else if (element==EL_FIREFLY) /* && MovDir[x][y]==right_dir) */ + MovDelay[x][y] = 1; } else if (element==EL_MAMPFER) { - if (MovDir[x][y]==MV_LEFT || MovDir[x][y]==MV_RIGHT) - { - MovDir[x][y]=(MovDir[x][y]==MV_LEFT ? MV_RIGHT : MV_LEFT); - if (IN_LEV_FIELD(x,y-1) && - (IS_FREE(x,y-1) || Feld[x][y-1]==EL_DIAMANT) && - RND(2)) - MovDir[x][y]=MV_UP; - if (IN_LEV_FIELD(x,y+1) && - (IS_FREE(x,y+1) || Feld[x][y+1]==EL_DIAMANT) && - RND(2)) - MovDir[x][y]=MV_DOWN; - } - else if (MovDir[x][y]==MV_UP || MovDir[x][y]==MV_DOWN) - { - MovDir[x][y]=(MovDir[x][y]==MV_UP ? MV_DOWN : MV_UP); - if (IN_LEV_FIELD(x-1,y) && - (IS_FREE(x-1,y) || Feld[x-1][y]==EL_DIAMANT) && - RND(2)) - MovDir[x][y]=MV_LEFT; - if (IN_LEV_FIELD(x+1,y) && - (IS_FREE(x+1,y) || Feld[x+1][y]==EL_DIAMANT) && - RND(2)) - MovDir[x][y]=MV_RIGHT; - } + BOOL can_turn_left = FALSE, can_turn_right = FALSE; + + if (IN_LEV_FIELD(left_x,left_y) && + (IS_FREE_OR_PLAYER(left_x,left_y) || + Feld[left_x][left_y] == EL_DIAMANT)) + can_turn_left = TRUE; + if (IN_LEV_FIELD(right_x,right_y) && + (IS_FREE_OR_PLAYER(right_x,right_y) || + Feld[right_x][right_y] == EL_DIAMANT)) + can_turn_right = TRUE; + + if (can_turn_left && can_turn_right) + MovDir[x][y] = (RND(3) ? (RND(2) ? left_dir : right_dir) : back_dir); + else if (can_turn_left) + MovDir[x][y] = (RND(2) ? left_dir : back_dir); + else if (can_turn_right) + MovDir[x][y] = (RND(2) ? right_dir : back_dir); + else + MovDir[x][y] = back_dir; - MovDelay[x][y]=8+8*RND(3); + MovDelay[x][y] = 8+8*RND(3); } else if (element==EL_MAMPFER2) { - if (MovDir[x][y]==MV_LEFT || MovDir[x][y]==MV_RIGHT) - { - MovDir[x][y]=(MovDir[x][y]==MV_LEFT ? MV_RIGHT : MV_LEFT); - if (IN_LEV_FIELD(x,y-1) && - (IS_FREE(x,y-1) || IS_MAMPF2(Feld[x][y-1])) && RND(2)) - MovDir[x][y]=MV_UP; - if (IN_LEV_FIELD(x,y+1) && - (IS_FREE(x,y+1) || IS_MAMPF2(Feld[x][y+1])) && RND(2)) - MovDir[x][y]=MV_DOWN; - } - else if (MovDir[x][y]==MV_UP || MovDir[x][y]==MV_DOWN) - { - MovDir[x][y]=(MovDir[x][y]==MV_UP ? MV_DOWN : MV_UP); - if (IN_LEV_FIELD(x-1,y) && - (IS_FREE(x-1,y) || IS_MAMPF2(Feld[x-1][y])) && RND(2)) - MovDir[x][y]=MV_LEFT; - if (IN_LEV_FIELD(x+1,y) && - (IS_FREE(x+1,y) || IS_MAMPF2(Feld[x+1][y])) && RND(2)) - MovDir[x][y]=MV_RIGHT; - } + BOOL can_turn_left = FALSE, can_turn_right = FALSE; + + if (IN_LEV_FIELD(left_x,left_y) && + (IS_FREE_OR_PLAYER(left_x,left_y) || + IS_MAMPF2(Feld[left_x][left_y]))) + can_turn_left = TRUE; + if (IN_LEV_FIELD(right_x,right_y) && + (IS_FREE_OR_PLAYER(right_x,right_y) || + IS_MAMPF2(Feld[right_x][right_y]))) + can_turn_right = TRUE; + + if (can_turn_left && can_turn_right) + MovDir[x][y] = (RND(3) ? (RND(2) ? left_dir : right_dir) : back_dir); + else if (can_turn_left) + MovDir[x][y] = (RND(2) ? left_dir : back_dir); + else if (can_turn_right) + MovDir[x][y] = (RND(2) ? right_dir : back_dir); + else + MovDir[x][y] = back_dir; - MovDelay[x][y]=8+8*RND(3); + MovDelay[x][y] = 8+8*RND(3); } else if (element==EL_PACMAN) { - if (MovDir[x][y]==MV_LEFT || MovDir[x][y]==MV_RIGHT) - { - MovDir[x][y]=(MovDir[x][y]==MV_LEFT ? MV_RIGHT : MV_LEFT); - if (IN_LEV_FIELD(x,y-1) && - (IS_FREE(x,y-1) || IS_AMOEBOID(Feld[x][y-1])) && - RND(2)) - MovDir[x][y]=MV_UP; - if (IN_LEV_FIELD(x,y+1) && - (IS_FREE(x,y+1) || IS_AMOEBOID(Feld[x][y+1])) && - RND(2)) - MovDir[x][y]=MV_DOWN; - } - else if (MovDir[x][y]==MV_UP || MovDir[x][y]==MV_DOWN) - { - MovDir[x][y]=(MovDir[x][y]==MV_UP ? MV_DOWN : MV_UP); - if (IN_LEV_FIELD(x-1,y) && - (IS_FREE(x-1,y) || IS_AMOEBOID(Feld[x-1][y])) && - RND(2)) - MovDir[x][y]=MV_LEFT; - if (IN_LEV_FIELD(x+1,y) && - (IS_FREE(x+1,y) || IS_AMOEBOID(Feld[x+1][y])) && - RND(2)) - MovDir[x][y]=MV_RIGHT; - } + BOOL can_turn_left = FALSE, can_turn_right = FALSE; + + if (IN_LEV_FIELD(left_x,left_y) && + (IS_FREE_OR_PLAYER(left_x,left_y) || + IS_AMOEBOID(Feld[left_x][left_y]))) + can_turn_left = TRUE; + if (IN_LEV_FIELD(right_x,right_y) && + (IS_FREE_OR_PLAYER(right_x,right_y) || + IS_AMOEBOID(Feld[right_x][right_y]))) + can_turn_right = TRUE; + + if (can_turn_left && can_turn_right) + MovDir[x][y] = (RND(3) ? (RND(2) ? left_dir : right_dir) : back_dir); + else if (can_turn_left) + MovDir[x][y] = (RND(2) ? left_dir : back_dir); + else if (can_turn_right) + MovDir[x][y] = (RND(2) ? right_dir : back_dir); + else + MovDir[x][y] = back_dir; - MovDelay[x][y]=3+RND(20); + MovDelay[x][y] = 3+RND(20); } else if (element==EL_ZOMBIE) { int attr_x = JX, attr_y = JY; + int newx, newy; if (ZX>=0 && ZY>=0) { @@ -1046,19 +1158,23 @@ void TurnRound(int x, int y) attr_y = ZY; } - MovDir[x][y]=MV_NO_MOVING; + MovDir[x][y] = MV_NO_MOVING; if (attr_xx) - MovDir[x][y]|=MV_RIGHT; + MovDir[x][y] |= (GameOver ? MV_LEFT : MV_RIGHT); if (attr_yy) - MovDir[x][y]|=MV_DOWN; + MovDir[x][y] |= (GameOver ? MV_UP : MV_DOWN); if ((MovDir[x][y]&(MV_LEFT|MV_RIGHT)) && (MovDir[x][y]&(MV_UP|MV_DOWN))) MovDir[x][y] &= (RND(2) ? (MV_LEFT|MV_RIGHT) : (MV_UP|MV_DOWN)); - MovDelay[x][y] = 8+8*RND(2); + Moving2Blocked(x,y,&newx,&newy); + if (IN_LEV_FIELD(newx,newy) && IS_FREE_OR_PLAYER(newx,newy)) + MovDelay[x][y] = 4+4*!RND(3); + else + MovDelay[x][y] = 8; } } @@ -1081,8 +1197,6 @@ void StartMoving(int x, int y) } else if (Feld[x][y+1]==EL_MORAST_LEER) { - CheckMoving = TRUE; - if (!MovDelay[x][y]) MovDelay[x][y] = 16; @@ -1120,14 +1234,13 @@ void StartMoving(int x, int y) Store[x][y] = EL_SIEB2_LEER; } } - else if (CAN_CHANGE(element) && + else if (SiebAktiv && CAN_CHANGE(element) && (Feld[x][y+1]==EL_SIEB_LEER || Feld[x][y+1]==EL_SIEB2_LEER)) { InitMovingField(x,y,MV_DOWN); Store[x][y] = (Feld[x][y+1]==EL_SIEB_LEER ? EL_SIEB_VOLL : EL_SIEB2_VOLL); Store2[x][y+1] = element; - SiebAktiv = 330; } else if (CAN_SMASH(element) && Feld[x][y+1]==EL_SALZSAEURE) { @@ -1150,15 +1263,16 @@ void StartMoving(int x, int y) } else if (IS_SLIPPERY(Feld[x][y+1]) && !Store[x][y+1]) { - int left = (x>0 && IS_FREE(x-1,y) && - (IS_FREE(x-1,y+1) || Feld[x-1][y+1]==EL_SALZSAEURE)); - int right = (x0 && IS_FREE(x-1,y) && + (IS_FREE(x-1,y+1) || Feld[x-1][y+1]==EL_SALZSAEURE)); + BOOL right = (x= 200 && element==EL_AMOEBE_BD) + { + AmoebeUmwandeln2(newax,neway,EL_FELSBROCKEN); + return; + } } } @@ -1638,8 +1801,6 @@ void Life(int ax, int ay) int life_time = 20; int element = Feld[ax][ay]; - CheckExploding = TRUE; - if (Stop[ax][ay]) return; @@ -1668,7 +1829,7 @@ void Life(int ax, int ay) if (!IN_LEV_FIELD(x,y) || (x==xx && y==yy)) continue; - if (((Feld[x][y]==element || (element==EL_LIFE && PLAYER(x,y))) && + if (((Feld[x][y]==element || (element==EL_LIFE && IS_PLAYER(x,y))) && !Stop[x][y]) || (IS_FREE(x,y) && Stop[x][y])) nachbarn++; @@ -1700,10 +1861,9 @@ void Life(int ax, int ay) void Ablenk(int x, int y) { - CheckExploding = TRUE; - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ - MovDelay[x][y] = 33*(level.dauer_ablenk/10); + MovDelay[x][y] = level.dauer_ablenk * FRAMES_PER_SECOND; + if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ { MovDelay[x][y]--; @@ -1717,16 +1877,14 @@ void Ablenk(int x, int y) } } - Feld[x][y]=EL_ABLENK_AUS; + Feld[x][y] = EL_ABLENK_AUS; DrawLevelField(x,y); if (ZX==x && ZY==y) - ZX=ZY=-1; + ZX = ZY = -1; } void Birne(int x, int y) { - CheckExploding = TRUE; - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ MovDelay[x][y] = 400; @@ -1756,26 +1914,11 @@ void Birne(int x, int y) void Blubber(int x, int y) { - CheckExploding = TRUE; - - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ - MovDelay[x][y] = 20; - - if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ - { - int blubber; - - MovDelay[x][y]--; - blubber = MovDelay[x][y]/5; - if (!(MovDelay[x][y]%5) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) - DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_GEBLUBBER+3-blubber); - } + DrawGraphicAnimation(x,y, GFX_GEBLUBBER, 4, 5, ANIM_NORMAL); } void NussKnacken(int x, int y) { - CheckExploding = TRUE; - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ MovDelay[x][y] = 4; @@ -1795,19 +1938,11 @@ void NussKnacken(int x, int y) void SiebAktivieren(int x, int y, int typ) { - CheckExploding = TRUE; - if (SiebAktiv>1) { if (SiebAktiv%2 && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) DrawGraphic(SCROLLX(x),SCROLLY(y), (typ==1 ? GFX_SIEB_VOLL : GFX_SIEB2_VOLL)+3-(SiebAktiv%8)/2); - -/* - if (!(SiebAktiv%4)) - PlaySoundLevel(x,y,SND_MIEP); -*/ - } else { @@ -1818,9 +1953,7 @@ void SiebAktivieren(int x, int y, int typ) void AusgangstuerPruefen(int x, int y) { - CheckExploding = TRUE; - - if (!Gems) + if (!Gems && !SokobanFields && !Lights) { Feld[x][y] = EL_AUSGANG_ACT; PlaySoundLevel(x,y,SND_OEFFNEN); @@ -1831,8 +1964,6 @@ void AusgangstuerOeffnen(int x, int y) { int speed = 3; - CheckExploding = TRUE; - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ MovDelay[x][y] = 5*speed; @@ -1855,44 +1986,59 @@ void AusgangstuerOeffnen(int x, int y) void AusgangstuerBlinken(int x, int y) { - CheckExploding = TRUE; + DrawGraphicAnimation(x,y, GFX_AUSGANG_AUF, 4, 2, ANIM_OSCILLATE); +} - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ - MovDelay[x][y] = 16; +void EdelsteinFunkeln(int x, int y) +{ + if (!IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)) || IS_MOVING(x,y)) + return; - if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ + if (Feld[x][y] == EL_EDELSTEIN_BD) { - int phase; + const int delay = 2; + const int frames = 4; + int phase = (FrameCounter % (delay*frames)) / delay; - MovDelay[x][y]--; - phase = (MovDelay[x][y] % 16)/2; - if (phase>3) - phase = 7-phase; - if (!(MovDelay[x][y]%2) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) - DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AUSGANG_AUF+phase); + if (!(FrameCounter % delay)) + DrawGraphic(SCROLLX(x),SCROLLY(y), GFX_EDELSTEIN_BD - phase); } -} + else + { + if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ + MovDelay[x][y] = 6*!SimpleRND(500); -void EdelsteinFunkeln(int x, int y) -{ - int speed = 2; + if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ + { + MovDelay[x][y]--; - CheckExploding = TRUE; + if (direct_draw_on && MovDelay[x][y]) + drawto_field = backbuffer; - if (IS_MOVING(x,y)) - return; + DrawGraphic(SCROLLX(x),SCROLLY(y), el2gfx(Feld[x][y])); - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ - MovDelay[x][y] = 4*speed; + if (MovDelay[x][y]) + { + int src_x,src_y, dest_x,dest_y; + int phase = MovDelay[x][y]-1; - if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ - { - int phase; + src_x = SX+GFX_PER_LINE*TILEX; + src_y = SY+(phase > 2 ? 4-phase : phase)*TILEY; + dest_x = SX+SCROLLX(x)*TILEX; + dest_y = SY+SCROLLY(y)*TILEY; - MovDelay[x][y]--; - phase = MovDelay[x][y]/speed; - if (!(MovDelay[x][y]%speed) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) - DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_EDELSTEIN2-phase); + XSetClipOrigin(display,clip_gc[PIX_BACK],dest_x-src_x,dest_y-src_y); + XCopyArea(display,pix[PIX_BACK],drawto_field,clip_gc[PIX_BACK], + src_x,src_y, TILEX,TILEY, dest_x,dest_y); + + if (direct_draw_on) + { + XCopyArea(display,backbuffer,window,gc, + dest_x,dest_y, TILEX,TILEY, dest_x,dest_y); + drawto_field = window; + } + } + } } } @@ -1900,8 +2046,6 @@ void MauerWaechst(int x, int y) { int speed = 3; - CheckExploding = TRUE; - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ MovDelay[x][y] = 3*speed; @@ -1940,8 +2084,6 @@ void MauerAbleger(int ax, int ay) BOOL links_frei = FALSE, rechts_frei = FALSE; BOOL links_massiv = FALSE, rechts_massiv = FALSE; - CheckExploding = TRUE; - if (!MovDelay[ax][ay]) /* neue Mauer / noch nicht gewartet */ MovDelay[ax][ay] = 3; @@ -1984,44 +2126,35 @@ void MauerAbleger(int ax, int ay) Feld[ax][ay] = EL_MAUERWERK; } -int GameActions(int mx, int my, int button) +void GameActions() { - static long time_delay=0, action_delay=0; - int Action; + static long action_delay=0; + long action_delay_value; - if (TimeLeft>0 && DelayReached(&time_delay,100) && !tape.pausing) - { - TimeLeft--; - - if (tape.recording || tape.playing) - DrawVideoDisplay(VIDEO_STATE_TIME_ON,level.time-TimeLeft); - - if (TimeLeft<=10) - PlaySoundStereo(SND_GONG,PSND_MAX_RIGHT); - - DrawText(DX_TIME,DY_TIME,int2str(TimeLeft,3),FS_SMALL,FC_YELLOW); - BackToFront(); - } - - if (!TimeLeft) - KillHero(); - - Action = (CheckMoving || CheckExploding || SiebAktiv); + if (game_status != PLAYING) + return; /* - if (Action && DelayReached(&action_delay,3)) + action_delay_value = + (tape.playing && tape.fast_forward ? FFWD_FRAME_DELAY : GAME_FRAME_DELAY); */ - if (DelayReached(&action_delay,3)) + action_delay_value = + (tape.playing && tape.fast_forward ? FFWD_FRAME_DELAY : Gamespeed); + + if (DelayReached(&action_delay, action_delay_value)) { int x,y,element; + int sieb_x = 0, sieb_y = 0; + + FrameCounter++; + TimeFrames++; if (tape.pausing || (tape.playing && !TapePlayDelay())) - return(ACT_GO_ON); + return; else if (tape.recording) TapeRecordDelay(); - CheckMoving = CheckExploding = FALSE; for(y=0;y0 && TimeFrames>=25 && !tape.pausing) + { + TimeFrames = 0; + TimeLeft--; + + if (tape.recording || tape.playing) + DrawVideoDisplay(VIDEO_STATE_TIME_ON,level.time-TimeLeft); + + if (TimeLeft<=10) + PlaySoundStereo(SND_GONG,PSND_MAX_RIGHT); + + DrawText(DX_TIME,DY_TIME,int2str(TimeLeft,3),FS_SMALL,FC_YELLOW); + + if (!TimeLeft) + KillHero(); } - return(ACT_GO_ON); + BackToFront(); } void ScrollLevel(int dx, int dy) @@ -2119,13 +2290,13 @@ void ScrollLevel(int dx, int dy) redraw_mask|=REDRAW_FIELD; } -BOOL MoveFigureOneStep(int dx, int dy) +BOOL MoveFigureOneStep(int dx, int dy, int real_dx, int real_dy) { int oldJX,oldJY, newJX = JX+dx,newJY = JY+dy; int element; int can_move; - if (!dx && !dy) + if (GameOver || (!dx && !dy)) return(MF_NO_ACTION); if (!IN_LEV_FIELD(newJX,newJY)) return(MF_NO_ACTION); @@ -2153,7 +2324,7 @@ BOOL MoveFigureOneStep(int dx, int dy) return(MF_MOVING); } - can_move = DigField(newJX,newJY,DF_DIG); + can_move = DigField(newJX,newJY, real_dx,real_dy, DF_DIG); if (can_move != MF_MOVING) return(can_move); @@ -2184,25 +2355,63 @@ BOOL MoveFigure(int dx, int dy) if (GameOver || (!dx && !dy)) return(FALSE); +/* + if (!DelayReached(&move_delay,8) && !tape.playing) + return(FALSE); +*/ + +/* if (!DelayReached(&move_delay,10) && !tape.playing) return(FALSE); +*/ + +/* + if (!FrameReached(&move_delay,2) && !tape.playing) + return(FALSE); +*/ - if (moved |= MoveFigureOneStep(dx,0)) - moved |= MoveFigureOneStep(0,dy); + if (Movemethod == 0) + { + if (!DelayReached(&move_delay,Movespeed[0]) && !tape.playing) + return(FALSE); + } else { - moved |= MoveFigureOneStep(0,dy); - moved |= MoveFigureOneStep(dx,0); + if (!FrameReached(&move_delay,Movespeed[1]) && !tape.playing) + return(FALSE); + } + + if (moved |= MoveFigureOneStep(dx,0, dx,dy)) + moved |= MoveFigureOneStep(0,dy, dx,dy); + else + { + moved |= MoveFigureOneStep(0,dy, dx,dy); + moved |= MoveFigureOneStep(dx,0, dx,dy); } if (moved & MF_MOVING) { int old_scroll_x=scroll_x, old_scroll_y=scroll_y; + int offset = (scroll_delay_on ? 3 : 0); +/* if (scroll_x!=JX-MIDPOSX && JX>=MIDPOSX-1 && JX<=lev_fieldx-MIDPOSX) scroll_x = JX-MIDPOSX; if (scroll_y!=JY-MIDPOSY && JY>=MIDPOSY-1 && JY<=lev_fieldy-MIDPOSY) scroll_y = JY-MIDPOSY; +*/ + +/* + printf("(scroll_x, scroll_y, JX, JY) == (%d, %d, %d, %d)\n", + scroll_x, scroll_y, JX, JY); +*/ + + if ((scroll_x < JX-MIDPOSX-offset || scroll_x > JX-MIDPOSX+offset) && + JX>=MIDPOSX-1-offset && JX<=lev_fieldx-(MIDPOSX-offset)) + scroll_x = JX-MIDPOSX + (scroll_x < JX-MIDPOSX ? -offset : offset); + if ((scroll_y < JY-MIDPOSY-offset || scroll_y > JY-MIDPOSY+offset) && + JY>=MIDPOSY-1-offset && JY<=lev_fieldy-(MIDPOSY-offset)) + scroll_y = JY-MIDPOSY + (scroll_y < JY-MIDPOSY ? -offset : offset); if (scroll_x!=old_scroll_x || scroll_y!=old_scroll_y) ScrollLevel(old_scroll_x-scroll_x,old_scroll_y-scroll_y); @@ -2217,8 +2426,10 @@ BOOL MoveFigure(int dx, int dy) BackToFront(); +/* if (LevelSolved) GameWon(); +*/ return(moved); } @@ -2228,10 +2439,10 @@ void TestIfHeroHitsBadThing() int i, killx = JX,killy = JY; static int xy[4][2] = { - 0,-1, - -1,0, - +1,0, - 0,+1 + { 0,-1 }, + { -1,0 }, + { +1,0 }, + { 0,+1 } }; static int harmless[4] = { @@ -2277,10 +2488,10 @@ void TestIfBadThingHitsOtherBadThing(int badx, int bady) int i, killx=badx, killy=bady; static int xy[4][2] = { - 0,-1, - -1,0, - +1,0, - 0,+1 + { 0,-1 }, + { -1,0 }, + { +1,0 }, + { 0,+1 } }; for(i=0;i<4;i++) @@ -2308,7 +2519,7 @@ void TestIfBadThingHitsOtherBadThing(int badx, int bady) void KillHero() { - if (PLAYER(-1,-1)) + if (IS_PLAYER(-1,-1)) return; if (IS_PFORTE(Feld[JX][JY])) @@ -2318,17 +2529,19 @@ void KillHero() PlaySoundLevel(JX,JY,SND_LACHEN); Bang(JX,JY); GameOver = TRUE; + ZX = JX; + ZY = JY; JX = JY = -1; } -int DigField(int x, int y, int mode) +int DigField(int x, int y, int real_dx, int real_dy, int mode) { int dx = x-JX, dy = y-JY; int element; static long push_delay = 0; - static int push_delay_value = 20; + static int push_delay_value = 5; - if (mode==DF_NO_PUSH) + if (mode == DF_NO_PUSH) { push_delay = 0; return(MF_NO_ACTION); @@ -2342,54 +2555,56 @@ int DigField(int x, int y, int mode) switch(element) { case EL_LEERRAUM: - CheckMoving = TRUE; break; case EL_ERDREICH: Feld[x][y] = EL_LEERRAUM; - CheckMoving = TRUE; break; case EL_EDELSTEIN: - case EL_EDELSTEIN2: - case EL_EDELSTEIN3: + case EL_EDELSTEIN_BD: + case EL_EDELSTEIN_GELB: + case EL_EDELSTEIN_ROT: + case EL_EDELSTEIN_LILA: Feld[x][y] = EL_LEERRAUM; - CheckMoving = TRUE; + MovDelay[x][y] = 0; /* wegen EDELSTEIN_BD-Funkeln! */ if (Gems>0) Gems--; - RaiseScore(level.score[SC_EDELSTEIN]); + RaiseScoreElement(EL_EDELSTEIN); DrawText(DX_EMERALDS,DY_EMERALDS,int2str(Gems,3),FS_SMALL,FC_YELLOW); PlaySoundLevel(x,y,SND_PONG); break; case EL_DIAMANT: Feld[x][y] = EL_LEERRAUM; - CheckMoving = TRUE; Gems -= 3; if (Gems<0) Gems=0; - RaiseScore(level.score[SC_DIAMANT]); + RaiseScoreElement(EL_DIAMANT); DrawText(DX_EMERALDS,DY_EMERALDS,int2str(Gems,3),FS_SMALL,FC_YELLOW); PlaySoundLevel(x,y,SND_PONG); break; case EL_DYNAMIT_AUS: Feld[x][y] = EL_LEERRAUM; - CheckMoving = TRUE; Dynamite++; - RaiseScore(level.score[SC_DYNAMIT]); + RaiseScoreElement(EL_DYNAMIT); DrawText(DX_DYNAMITE,DY_DYNAMITE,int2str(Dynamite,3),FS_SMALL,FC_YELLOW); PlaySoundLevel(x,y,SND_PONG); break; case EL_DYNABOMB_NR: Feld[x][y] = EL_LEERRAUM; - CheckMoving = TRUE; DynaBombCount++; DynaBombsLeft++; - RaiseScore(level.score[SC_DYNAMIT]); + RaiseScoreElement(EL_DYNAMIT); PlaySoundLevel(x,y,SND_PONG); break; case EL_DYNABOMB_SZ: Feld[x][y] = EL_LEERRAUM; - CheckMoving = TRUE; DynaBombSize++; - RaiseScore(level.score[SC_DYNAMIT]); + RaiseScoreElement(EL_DYNAMIT); + PlaySoundLevel(x,y,SND_PONG); + break; + case EL_DYNABOMB_XL: + Feld[x][y] = EL_LEERRAUM; + DynaBombXL = TRUE; + RaiseScoreElement(EL_DYNAMIT); PlaySoundLevel(x,y,SND_PONG); break; case EL_SCHLUESSEL1: @@ -2400,9 +2615,8 @@ int DigField(int x, int y, int mode) int key_nr = element-EL_SCHLUESSEL1; Feld[x][y] = EL_LEERRAUM; - CheckMoving = TRUE; Key[key_nr] = TRUE; - RaiseScore(level.score[SC_SCHLUESSEL]); + RaiseScoreElement(EL_SCHLUESSEL); DrawMiniGraphicExtHiRes(drawto,gc, DX_KEYS+key_nr*MINI_TILEX,DY_KEYS, GFX_SCHLUESSEL1+key_nr); @@ -2414,7 +2628,6 @@ int DigField(int x, int y, int mode) } case EL_ABLENK_AUS: Feld[x][y] = EL_ABLENK_EIN; - CheckExploding = TRUE; ZX=x; ZY=y; DrawLevelField(x,y); @@ -2426,18 +2639,25 @@ int DigField(int x, int y, int mode) case EL_ZEIT_LEER: if (mode==DF_SNAP) return(MF_NO_ACTION); - if (dy || !IN_LEV_FIELD(x+dx,y+dy) || Feld[x+dx][y+dy]!=EL_LEERRAUM) + if (dy || !IN_LEV_FIELD(x+dx,y+dy) || Feld[x+dx][y+dy] != EL_LEERRAUM) return(MF_NO_ACTION); - if (Counter() > push_delay+4*push_delay_value) - push_delay = Counter(); - if (!DelayReached(&push_delay,push_delay_value) && !tape.playing) + if (real_dy) + { + if (IN_LEV_FIELD(JX,JY+real_dy) && !IS_SOLID(Feld[JX][JY+real_dy])) + return(MF_NO_ACTION); + } + + if (push_delay == 0) + push_delay = FrameCounter; + if (!FrameReached(&push_delay,push_delay_value) && !tape.playing) return(MF_NO_ACTION); Feld[x][y] = EL_LEERRAUM; Feld[x+dx][y+dy] = element; - push_delay_value = 10+RND(30); - CheckMoving = TRUE; + + push_delay_value = 2+RND(8); + DrawLevelField(x+dx,y+dy); if (element==EL_FELSBROCKEN) PlaySoundLevel(x+dx,y+dy,SND_PUSCH); @@ -2466,10 +2686,6 @@ int DigField(int x, int y, int mode) return(MF_NO_ACTION); break; case EL_AUSGANG_AUF: -/* - if (mode==DF_SNAP || Gems>0) - return(MF_NO_ACTION); -*/ if (mode==DF_SNAP) return(MF_NO_ACTION); LevelSolved = GameOver = TRUE; @@ -2477,21 +2693,84 @@ int DigField(int x, int y, int mode) break; case EL_BIRNE_AUS: Feld[x][y] = EL_BIRNE_EIN; + Lights--; DrawLevelField(x,y); PlaySoundLevel(x,y,SND_DENG); return(MF_ACTION); break; case EL_ZEIT_VOLL: Feld[x][y] = EL_ZEIT_LEER; + TimeLeft += 10; + DrawText(DX_TIME,DY_TIME,int2str(TimeLeft,3),FS_SMALL,FC_YELLOW); DrawLevelField(x,y); PlaySoundStereo(SND_GONG,PSND_MAX_RIGHT); return(MF_ACTION); + break; + case EL_SOKOBAN_FELD_LEER: + break; + case EL_SOKOBAN_FELD_VOLL: + case EL_SOKOBAN_OBJEKT: + if (mode==DF_SNAP) + return(MF_NO_ACTION); + if (!IN_LEV_FIELD(x+dx,y+dy) + || (Feld[x+dx][y+dy] != EL_LEERRAUM + && Feld[x+dx][y+dy] != EL_SOKOBAN_FELD_LEER)) + return(MF_NO_ACTION); + + if (dx && real_dy) + { + if (IN_LEV_FIELD(JX,JY+real_dy) && !IS_SOLID(Feld[JX][JY+real_dy])) + return(MF_NO_ACTION); + } + else if (dy && real_dx) + { + if (IN_LEV_FIELD(JX+real_dx,JY) && !IS_SOLID(Feld[JX+real_dx][JY])) + return(MF_NO_ACTION); + } + + if (push_delay == 0) + push_delay = FrameCounter; + if (!FrameReached(&push_delay,push_delay_value) && !tape.playing) + return(MF_NO_ACTION); + + if (element == EL_SOKOBAN_FELD_VOLL) + { + Feld[x][y] = EL_SOKOBAN_FELD_LEER; + SokobanFields++; + } + else + Feld[x][y] = EL_LEERRAUM; + + if (Feld[x+dx][y+dy] == EL_SOKOBAN_FELD_LEER) + { + Feld[x+dx][y+dy] = EL_SOKOBAN_FELD_VOLL; + SokobanFields--; + if (element == EL_SOKOBAN_OBJEKT) + PlaySoundLevel(x,y,SND_DENG); + } + else + Feld[x+dx][y+dy] = EL_SOKOBAN_OBJEKT; + + push_delay_value = 2; + + DrawLevelField(x,y); + DrawLevelField(x+dx,y+dy); + PlaySoundLevel(x+dx,y+dy,SND_PUSCH); + + if (SokobanFields == 0 && game_emulation == EMU_SOKOBAN) + { + LevelSolved = GameOver = TRUE; + PlaySoundLevel(x,y,SND_BUING); + } + break; default: return(MF_NO_ACTION); break; } - push_delay=0; + + push_delay = 0; + return(MF_MOVING); } @@ -2512,7 +2791,7 @@ BOOL SnapField(int dx, int dy) if (snapped) return(FALSE); - if (!DigField(x,y,DF_SNAP)) + if (!DigField(x,y, 0,0, DF_SNAP)) return(FALSE); snapped = TRUE; @@ -2524,12 +2803,19 @@ BOOL SnapField(int dx, int dy) BOOL PlaceBomb(void) { + int element; + + if (GameOver) + return(FALSE); + + element = Feld[JX][JY]; + if ((Dynamite==0 && DynaBombsLeft==0) || - Feld[JX][JY]==EL_DYNAMIT || Feld[JX][JY]==EL_DYNABOMB) + element==EL_DYNAMIT || element==EL_DYNABOMB || element==EL_EXPLODING) return(FALSE); - if (Feld[JX][JY]!=EL_LEERRAUM) - Store[JX][JY] = Feld[JX][JY]; + if (element!=EL_LEERRAUM) + Store[JX][JY] = element; if (Dynamite) { @@ -2544,13 +2830,9 @@ BOOL PlaceBomb(void) Feld[JX][JY] = EL_DYNABOMB; MovDelay[JX][JY] = 48; DynaBombsLeft--; - - /* ändern, wenn Maske für DYNABOMB vorliegt! */ - - DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_DYNAMIT); + DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_DYNABOMB); } - CheckExploding = TRUE; return(TRUE); } @@ -2559,7 +2841,8 @@ void PlaySoundLevel(int x, int y, int sound_nr) int sx = SCROLLX(x), sy = SCROLLY(y); int volume, stereo; - if (!sound_loops_on && IS_LOOP_SOUND(sound_nr)) + if ((!sound_simple_on && !IS_LOOP_SOUND(sound_nr)) || + (!sound_loops_on && IS_LOOP_SOUND(sound_nr))) return; if (!IN_LEV_FIELD(x,y)) @@ -2586,196 +2869,44 @@ void RaiseScore(int value) BackToFront(); } -void TapeInitRecording() -{ - time_t zeit1 = time(NULL); - struct tm *zeit2 = localtime(&zeit1); - - if (tape.recording || tape.playing) - return; - - tape.level_nr = level_nr; - tape.recording = TRUE; - tape.pausing = TRUE; - tape.date = - 10000*(zeit2->tm_year%100) + 100*zeit2->tm_mon + zeit2->tm_mday; - - DrawVideoDisplay(VIDEO_STATE_REC_ON | VIDEO_STATE_PAUSE_ON,0); - DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date); - DrawVideoDisplay(VIDEO_STATE_TIME_ON,0); -} - -void TapeStartRecording() -{ - tape.length = 0; - tape.counter = 0; - tape.pos[tape.counter].delay = 0; - tape.recording = TRUE; - tape.playing = FALSE; - tape.pausing = FALSE; - tape.random_seed = InitRND(NEW_RANDOMIZE); - DrawVideoDisplay(VIDEO_STATE_REC_ON | VIDEO_STATE_PAUSE_OFF,0); -} - -void TapeStopRecording() -{ - if (!tape.recording) - return; - - tape.length = tape.counter; - tape.recording = FALSE; - tape.pausing = FALSE; - DrawVideoDisplay(VIDEO_STATE_REC_OFF,0); - - master_tape = tape; -} - -void TapeRecordAction(int joy) -{ - if (!tape.recording || tape.pausing) - return; - - if (tape.counter>=MAX_TAPELEN-1) - { - TapeStopRecording(); - return; - } - - if (joy) - { - tape.pos[tape.counter].joystickdata = joy; - tape.counter++; - tape.pos[tape.counter].delay = 0; - } -} - -void TapeRecordDelay() -{ - if (!tape.recording || tape.pausing) - return; - - if (tape.counter>=MAX_TAPELEN) - { - TapeStopRecording(); - return; - } - - tape.pos[tape.counter].delay++; - - if (tape.pos[tape.counter].delay>=255) - { - tape.pos[tape.counter].joystickdata = 0; - tape.counter++; - tape.pos[tape.counter].delay = 0; - } -} - -void TapeTogglePause() -{ - if (!tape.recording && !tape.playing) - return; - - if (tape.pausing) - { - tape.pausing = FALSE; - DrawVideoDisplay(VIDEO_STATE_PAUSE_OFF,0); - if (game_status==MAINMENU) - HandleMainMenu(SX+16,SY+7*32+16,0,0,MB_MENU_CHOICE); - } - else - { - tape.pausing = TRUE; - DrawVideoDisplay(VIDEO_STATE_PAUSE_ON,0); - } -} - -void TapeInitPlaying() -{ - if (tape.recording || tape.playing || TAPE_IS_EMPTY(tape)) - return; - - tape.playing = TRUE; - tape.pausing = TRUE; - DrawVideoDisplay(VIDEO_STATE_PLAY_ON | VIDEO_STATE_PAUSE_ON,0); - DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date); - DrawVideoDisplay(VIDEO_STATE_TIME_ON,0); -} - -void TapeStartPlaying() -{ - tape = master_tape; - - tape.counter = 0; - tape.recording = FALSE; - tape.playing = TRUE; - tape.pausing = FALSE; - InitRND(tape.random_seed); - DrawVideoDisplay(VIDEO_STATE_PLAY_ON | VIDEO_STATE_PAUSE_OFF,0); -} - -void TapeStopPlaying() -{ - if (!tape.playing) - return; - - tape.playing = FALSE; - tape.pausing = FALSE; - DrawVideoDisplay(VIDEO_STATE_PLAY_OFF,0); -} - -int TapePlayAction() +void RaiseScoreElement(int element) { - if (!tape.playing || tape.pausing) - return(0); - - if (tape.counter>=tape.length) - { - TapeStopPlaying(); - return(0); - } - - if (!tape.pos[tape.counter].delay) - { - tape.counter++; - return(tape.pos[tape.counter-1].joystickdata); - } - else - return(0); -} - -BOOL TapePlayDelay() -{ - if (!tape.playing || tape.pausing) - return(0); - - if (tape.counter>=tape.length) - { - TapeStopPlaying(); - return(TRUE); - } - - if (tape.pos[tape.counter].delay) - { - tape.pos[tape.counter].delay--; - return(TRUE); - } - else - return(FALSE); -} - -void TapeStop() -{ - TapeStopRecording(); - TapeStopPlaying(); - DrawVideoDisplay(VIDEO_ALL_OFF,0); - if (tape.date && tape.length) + switch(element) { - DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date); - DrawVideoDisplay(VIDEO_STATE_TIME_ON,0); + case EL_EDELSTEIN: + RaiseScore(level.score[SC_EDELSTEIN]); + break; + case EL_DIAMANT: + RaiseScore(level.score[SC_DIAMANT]); + break; + case EL_KAEFER: + case EL_BUTTERFLY: + RaiseScore(level.score[SC_KAEFER]); + break; + case EL_FLIEGER: + case EL_FIREFLY: + RaiseScore(level.score[SC_FLIEGER]); + break; + case EL_MAMPFER: + case EL_MAMPFER2: + RaiseScore(level.score[SC_MAMPFER]); + break; + case EL_ZOMBIE: + RaiseScore(level.score[SC_ZOMBIE]); + break; + case EL_PACMAN: + RaiseScore(level.score[SC_PACMAN]); + break; + case EL_KOKOSNUSS: + RaiseScore(level.score[SC_KOKOSNUSS]); + break; + case EL_DYNAMIT: + RaiseScore(level.score[SC_DYNAMIT]); + break; + case EL_SCHLUESSEL: + RaiseScore(level.score[SC_SCHLUESSEL]); + break; + default: + break; } } - -void TapeErase() -{ - tape.length = 0; -} diff --git a/src/game.h b/src/game.h index 56be763c..a0a21073 100644 --- a/src/game.h +++ b/src/game.h @@ -17,17 +17,23 @@ #include "main.h" -#define DF_DIG 0 -#define DF_SNAP 1 -#define DF_NO_PUSH 2 +#define DF_NO_PUSH 0 +#define DF_DIG 1 +#define DF_SNAP 2 -#define MF_NO_ACTION 0 -#define MF_MOVING 1 -#define MF_ACTION 2 +#define MF_NO_ACTION 0 +#define MF_MOVING 1 +#define MF_ACTION 2 -#define EX_NORMAL 0 -#define EX_CENTER 1 -#define EX_BORDER 2 +/* explosion position marks */ +#define EX_NORMAL 0 +#define EX_CENTER 1 +#define EX_BORDER 2 + +/* fundamental game speed */ +#define GAME_FRAME_DELAY 4 +#define FFWD_FRAME_DELAY 1 +#define FRAMES_PER_SECOND (100 / GAME_FRAME_DELAY) void GetPlayerConfig(void); void InitGame(void); @@ -52,6 +58,7 @@ void StartMoving(int, int); void ContinueMoving(int, int); int AmoebeNachbarNr(int, int); void AmoebeUmwandeln(int, int); +void AmoebeUmwandeln2(int, int, int); void AmoebeWaechst(int, int); void AmoebeAbleger(int, int); void Life(int, int); @@ -65,30 +72,19 @@ void AusgangstuerBlinken(int, int); void EdelsteinFunkeln(int, int); void MauerWaechst(int, int); void MauerAbleger(int, int); -int GameActions(int, int, int); +void GameActions(void); void ScrollLevel(int, int); +BOOL MoveFigureOneStep(int, int, int, int); BOOL MoveFigure(int, int); void TestIfHeroHitsBadThing(void); void TestIfBadThingHitsHero(void); void TestIfBadThingHitsOtherBadThing(int, int); void KillHero(void); -int DigField(int, int, int); +int DigField(int, int, int, int, int); BOOL SnapField(int, int); BOOL PlaceBomb(void); void PlaySoundLevel(int, int, int); void RaiseScore(int); -void TapeInitRecording(void); -void TapeStartRecording(void); -void TapeStopRecording(void); -void TapeRecordAction(int); -void TapeRecordDelay(void); -void TapeTogglePause(void); -void TapeInitPlaying(void); -void TapeStartPlaying(void); -void TapeStopPlaying(void); -int TapePlayAction(void); -BOOL TapePlayDelay(void); -void TapeStop(void); -void TapeErase(void); +void RaiseScoreElement(int); #endif diff --git a/src/init.c b/src/init.c index 251d32d6..2d9b3042 100644 --- a/src/init.c +++ b/src/init.c @@ -16,6 +16,7 @@ #include "misc.h" #include "sound.h" #include "screens.h" +#include "tools.h" #include "files.h" #include @@ -36,13 +37,14 @@ void OpenAll(int argc, char *argv[]) InitDisplay(argc, argv); InitWindow(argc, argv); + + XMapWindow(display, window); + XFlush(display); + InitGfx(); InitElementProperties(); DrawMainMenu(); - - XMapWindow(display, window); - XFlush(display); } void InitLevelAndPlayerInfo() @@ -191,8 +193,8 @@ void InitWindow(int argc, char *argv[]) XTextProperty windowName, iconName; XGCValues gc_values; unsigned long gc_valuemask; - char *window_name = "Rocks'n'Diamonds"; - char *icon_name = "Rocks'n'Diamonds"; + char *window_name = WINDOWTITLE_STRING; + char *icon_name = WINDOWTITLE_STRING; long window_event_mask; static struct PictureFile icon_pic = { @@ -277,105 +279,39 @@ void InitWindow(int argc, char *argv[]) gc = XCreateGC(display, window, gc_valuemask, &gc_values); } +void DrawInitText(char *text, int ypos, int color) +{ + if (display && window && pix[PIX_SMALLFONT]) + { + XFillRectangle(display,window,gc,0,ypos, WIN_XSIZE,FONT2_YSIZE); + DrawTextExt(window,gc,(WIN_XSIZE-strlen(text)*FONT2_XSIZE)/2, + ypos,text,FS_SMALL,color); + XFlush(display); + } +} + void InitGfx() { - int i,j,x,y; - int xpm_err, xbm_err; - unsigned int width,height; - int hot_x,hot_y; - XGCValues gc_values; - unsigned long gc_valuemask; + int i,j; XGCValues clip_gc_values; unsigned long clip_gc_valuemask; - char filename[256]; - Pixmap shapemask; - static struct PictureFile pic[NUM_PICTURES] = { - "RocksScreen.xpm", "RocksScreenMaske.xbm", - "RocksDoor.xpm", "RocksDoorMaske.xbm", - "RocksToons.xpm", "RocksToonsMaske.xbm", - "RocksFont.xpm", NULL, - "RocksFont2.xpm", NULL + { "RocksScreen.xpm", "RocksScreenMaske.xbm" }, + { "RocksDoor.xpm", "RocksDoorMaske.xbm" }, + { "RocksToons.xpm", "RocksToonsMaske.xbm" }, + { "RocksFont.xpm", NULL }, + { "RocksFont2.xpm", NULL } }; - for(i=0;ipicture_filename) + { + DrawInitText(pic->picture_filename,150,FC_YELLOW); + sprintf(filename,"%s/%s",GFX_PATH,pic->picture_filename); + + xpm_att[pos].valuemask = XpmCloseness; + xpm_att[pos].closeness = 20000; + xpm_err = XpmReadFileToPixmap(display,window,filename, + &pix[pos],&shapemask,&xpm_att[pos]); + switch(xpm_err) + { + case XpmOpenFailed: + fprintf(stderr,"Xpm file open failed on '%s' !\n",filename); + CloseAll(); + exit(-1); + case XpmFileInvalid: + fprintf(stderr,"Invalid Xpm file '%s'!\n",filename); + CloseAll(); + exit(-1); + case XpmNoMemory: + fprintf(stderr,"Not enough memory !\n"); + CloseAll(); + exit(1); + case XpmColorFailed: + fprintf(stderr,"Can`t get any colors...\n"); + CloseAll(); + exit(-1); + default: + break; + } + + if (!pix[pos]) + { + fprintf(stderr, "%s: cannot read Xpm file '%s'.\n", + progname,filename); + CloseAll(); + exit(-1); + } + } + + /* zugehörige Maske laden (wenn vorhanden) */ + if (pic->picturemask_filename) + { + DrawInitText(pic->picturemask_filename,150,FC_YELLOW); + sprintf(filename,"%s/%s",GFX_PATH,pic->picturemask_filename); + + xbm_err = XReadBitmapFile(display,window,filename, + &width,&height,&clipmask[pos],&hot_x,&hot_y); + switch(xbm_err) + { + case BitmapSuccess: + break; + case BitmapOpenFailed: + fprintf(stderr,"Bitmap file open failed on '%s' !\n",filename); + CloseAll(); + exit(-1); + break; + case BitmapFileInvalid: + fprintf(stderr,"Bitmap file invalid: '%s' !\n",filename); + CloseAll(); + exit(-1); + break; + case BitmapNoMemory: + fprintf(stderr,"No memory for file '%s' !\n",filename); + CloseAll(); + exit(-1); + break; + default: + break; + } + + if (!clipmask[pos]) + { + fprintf(stderr, "%s: cannot read X11 bitmap file '%s'.\n", + progname,filename); + CloseAll(); + exit(-1); + } + } +} + void InitElementProperties() { int i,j; @@ -441,7 +455,8 @@ void InitElementProperties() { EL_AMOEBE_NASS, EL_AMOEBE_NORM, - EL_AMOEBE_VOLL + EL_AMOEBE_VOLL, + EL_AMOEBE_BD }; static int ep_amoebalive_num = sizeof(ep_amoebalive)/sizeof(int); @@ -450,7 +465,8 @@ void InitElementProperties() EL_AMOEBE_TOT, EL_AMOEBE_NASS, EL_AMOEBE_NORM, - EL_AMOEBE_VOLL + EL_AMOEBE_VOLL, + EL_AMOEBE_BD }; static int ep_amoeboid_num = sizeof(ep_amoeboid)/sizeof(int); @@ -499,6 +515,7 @@ void InitElementProperties() EL_AMOEBE_NASS, EL_AMOEBE_NORM, EL_AMOEBE_VOLL, + EL_AMOEBE_BD, EL_MORAST_VOLL, EL_MORAST_LEER, EL_SIEB_VOLL, @@ -542,8 +559,10 @@ void InitElementProperties() EL_FELSBODEN, EL_FELSBROCKEN, EL_EDELSTEIN, - EL_EDELSTEIN2, - EL_EDELSTEIN3, + EL_EDELSTEIN_BD, + EL_EDELSTEIN_GELB, + EL_EDELSTEIN_ROT, + EL_EDELSTEIN_LILA, EL_DIAMANT, EL_BOMBE, EL_KOKOSNUSS, @@ -562,6 +581,8 @@ void InitElementProperties() { EL_KAEFER, EL_FLIEGER, + EL_BUTTERFLY, + EL_FIREFLY, EL_MAMPFER, EL_MAMPFER2, EL_ZOMBIE, @@ -594,8 +615,10 @@ void InitElementProperties() { EL_FELSBROCKEN, EL_EDELSTEIN, - EL_EDELSTEIN2, - EL_EDELSTEIN3, + EL_EDELSTEIN_BD, + EL_EDELSTEIN_GELB, + EL_EDELSTEIN_ROT, + EL_EDELSTEIN_LILA, EL_DIAMANT, EL_BOMBE, EL_KOKOSNUSS, @@ -612,8 +635,10 @@ void InitElementProperties() { EL_FELSBROCKEN, EL_EDELSTEIN, - EL_EDELSTEIN2, - EL_EDELSTEIN3, + EL_EDELSTEIN_BD, + EL_EDELSTEIN_GELB, + EL_EDELSTEIN_ROT, + EL_EDELSTEIN_LILA, EL_DIAMANT, EL_SCHLUESSEL1, EL_SCHLUESSEL2, @@ -631,8 +656,10 @@ void InitElementProperties() { EL_FELSBROCKEN, EL_EDELSTEIN, - EL_EDELSTEIN2, - EL_EDELSTEIN3, + EL_EDELSTEIN_BD, + EL_EDELSTEIN_GELB, + EL_EDELSTEIN_ROT, + EL_EDELSTEIN_LILA, EL_DIAMANT }; static int ep_can_change_num = sizeof(ep_can_change)/sizeof(int); @@ -641,6 +668,8 @@ void InitElementProperties() { EL_KAEFER, EL_FLIEGER, + EL_BUTTERFLY, + EL_FIREFLY, EL_MAMPFER, EL_MAMPFER2, EL_ZOMBIE, @@ -658,6 +687,14 @@ void InitElementProperties() EL_FLIEGER_O, EL_FLIEGER_L, EL_FLIEGER_U, + EL_BUTTERFLY_R, + EL_BUTTERFLY_O, + EL_BUTTERFLY_L, + EL_BUTTERFLY_U, + EL_FIREFLY_R, + EL_FIREFLY_O, + EL_FIREFLY_L, + EL_FIREFLY_U, EL_PACMAN_R, EL_PACMAN_O, EL_PACMAN_L, @@ -668,7 +705,9 @@ void InitElementProperties() static int ep_dont_touch[] = { EL_KAEFER, - EL_FLIEGER + EL_FLIEGER, + EL_BUTTERFLY, + EL_FIREFLY }; static int ep_dont_touch_num = sizeof(ep_dont_touch)/sizeof(int); @@ -676,6 +715,8 @@ void InitElementProperties() { EL_KAEFER, EL_FLIEGER, + EL_BUTTERFLY, + EL_FIREFLY, EL_MAMPFER, EL_MAMPFER2, EL_ZOMBIE, @@ -690,6 +731,8 @@ void InitElementProperties() EL_ERDREICH, EL_KAEFER, EL_FLIEGER, + EL_BUTTERFLY, + EL_FIREFLY, EL_MAMPFER, EL_ZOMBIE, EL_PACMAN, @@ -698,13 +741,117 @@ void InitElementProperties() EL_AMOEBE_NASS, EL_AMOEBE_NORM, EL_AMOEBE_VOLL, + EL_AMOEBE_BD, EL_EDELSTEIN, - EL_EDELSTEIN2, - EL_EDELSTEIN3, + EL_EDELSTEIN_BD, + EL_EDELSTEIN_GELB, + EL_EDELSTEIN_ROT, + EL_EDELSTEIN_LILA, EL_DIAMANT }; static int ep_mampf2_num = sizeof(ep_mampf2)/sizeof(int); + static int ep_bd_element[] = + { + EL_LEERRAUM, + EL_ERDREICH, + EL_FELSBODEN, + EL_FELSBROCKEN, + EL_EDELSTEIN_BD, + EL_SIEB2_LEER, + EL_AUSGANG_ZU, + EL_AUSGANG_AUF, + EL_BETON, + EL_SPIELFIGUR, + EL_FIREFLY, + EL_FIREFLY_1, + EL_FIREFLY_2, + EL_FIREFLY_3, + EL_FIREFLY_4, + EL_BUTTERFLY, + EL_BUTTERFLY_1, + EL_BUTTERFLY_2, + EL_BUTTERFLY_3, + EL_BUTTERFLY_4, + EL_AMOEBE_BD, + EL_CHAR_FRAGE + }; + static int ep_bd_element_num = sizeof(ep_bd_element)/sizeof(int); + + static int ep_sb_element[] = + { + EL_LEERRAUM, + EL_BETON, + EL_SOKOBAN_OBJEKT, + EL_SOKOBAN_FELD_LEER, + EL_SOKOBAN_FELD_VOLL, + EL_SPIELFIGUR + }; + static int ep_sb_element_num = sizeof(ep_sb_element)/sizeof(int); + + static int ep_gem[] = + { + EL_EDELSTEIN, + EL_EDELSTEIN_BD, + EL_EDELSTEIN_GELB, + EL_EDELSTEIN_ROT, + EL_EDELSTEIN_LILA, + EL_DIAMANT + }; + static int ep_gem_num = sizeof(ep_gem)/sizeof(int); + + static int ep_inactive[] = + { + EL_LEERRAUM, + EL_ERDREICH, + EL_MAUERWERK, + EL_FELSBODEN, + EL_SCHLUESSEL, + EL_BETON, + EL_AMOEBE_TOT, + EL_MORAST_LEER, + EL_BADEWANNE, + EL_ABLENK_AUS, + EL_SCHLUESSEL1, + EL_SCHLUESSEL2, + EL_SCHLUESSEL3, + EL_SCHLUESSEL4, + EL_PFORTE1, + EL_PFORTE2, + EL_PFORTE3, + EL_PFORTE4, + EL_PFORTE1X, + EL_PFORTE2X, + EL_PFORTE3X, + EL_PFORTE4X, + EL_DYNAMIT_AUS, + EL_UNSICHTBAR, + EL_BIRNE_AUS, + EL_BIRNE_EIN, + EL_ERZ_EDEL, + EL_ERZ_DIAM, + EL_ERZ_EDEL_BD, + EL_ERZ_EDEL_GELB, + EL_DYNABOMB_NR, + EL_DYNABOMB_SZ, + EL_DYNABOMB_XL, + EL_SOKOBAN_OBJEKT, + EL_SOKOBAN_FELD_LEER, + EL_SOKOBAN_FELD_VOLL, + EL_ERZ_EDEL_ROT, + EL_ERZ_EDEL_LILA, + EL_BADEWANNE1, + EL_BADEWANNE2, + EL_BADEWANNE3, + EL_BADEWANNE4, + EL_BADEWANNE5, + EL_SIEB_TOT, + EL_SIEB2_TOT, + EL_AMOEBA2DIAM, + EL_BLOCKED + }; + static int ep_inactive_num = sizeof(ep_inactive)/sizeof(int); + static long ep_bit[] = { EP_BIT_AMOEBALIVE, @@ -724,7 +871,11 @@ void InitElementProperties() EP_BIT_COULD_MOVE, EP_BIT_DONT_TOUCH, EP_BIT_DONT_GO_TO, - EP_BIT_MAMPF2 + EP_BIT_MAMPF2, + EP_BIT_BD_ELEMENT, + EP_BIT_SB_ELEMENT, + EP_BIT_GEM, + EP_BIT_INACTIVE }; static int *ep_array[] = { @@ -745,7 +896,11 @@ void InitElementProperties() ep_could_move, ep_dont_touch, ep_dont_go_to, - ep_mampf2 + ep_mampf2, + ep_bd_element, + ep_sb_element, + ep_gem, + ep_inactive }; static int *ep_num[] = { @@ -766,7 +921,11 @@ void InitElementProperties() &ep_could_move_num, &ep_dont_touch_num, &ep_dont_go_to_num, - &ep_mampf2_num + &ep_mampf2_num, + &ep_bd_element_num, + &ep_sb_element_num, + &ep_gem_num, + &ep_inactive_num }; static int num_properties = sizeof(ep_num)/sizeof(int *); @@ -777,7 +936,7 @@ void InitElementProperties() for(j=0;j<*(ep_num[i]);j++) Elementeigenschaften[(ep_array[i])[j]] |= ep_bit[i]; for(i=EL_CHAR_START;i1) + level_directory = argv[1]; + OpenAll(argc,argv); EventLoop(); CloseAll(); diff --git a/src/main.h b/src/main.h index 7d92afb4..6cf2bb23 100644 --- a/src/main.h +++ b/src/main.h @@ -66,10 +66,12 @@ typedef int BOOL; #define UNSCROLLY(a) ((a)+scroll_y) #define IN_SCR_FIELD(x,y) ((x)>=0 && (x)=0 &&(y)=0 && (x)=0 &&(y)=EL_BLOCKED) #define TIMESIZE (TimeLeft*100/level.time) -#define LEVELDIR_SIZE(x) ((x).num_ready + (x).num_free) #define TAPE_IS_EMPTY(x) ((x).length == 0) +#define TAPE_IS_STOPPED(x) (!(x).recording && !(x).playing &&!(x).pausing) /* Pixmaps with Xpm or X11 Bitmap files */ #define PIX_BACK 0 @@ -133,10 +144,9 @@ typedef int BOOL; /* Pixmaps without them */ #define PIX_DB_BACK 5 #define PIX_DB_DOOR 6 -#define PIX_FADEMASK 7 #define NUM_PICTURES 5 -#define NUM_PIXMAPS 8 +#define NUM_PIXMAPS 7 /* boundaries of arrays etc. */ #define MAX_NAMELEN (10+1) @@ -174,6 +184,7 @@ struct PlayerInfo int handicap; unsigned int setup; int leveldir_nr; + int level_nr; }; struct LevelInfo @@ -195,8 +206,8 @@ struct LevelDirInfo { char filename[MAX_LEVDIR_FILENAME]; char name[MAX_LEVDIR_NAME]; - int num_ready; - int num_free; + int levels; + int readonly; }; struct RecordingInfo @@ -206,7 +217,12 @@ struct RecordingInfo unsigned long date; unsigned long counter; unsigned long length; + unsigned long length_seconds; + unsigned int delay_played; + BOOL pause_before_death; + BOOL changed; BOOL recording, playing, pausing; + BOOL fast_forward; struct { unsigned char joystickdata; @@ -223,8 +239,7 @@ struct JoystickInfo extern Display *display; extern int screen; extern Window window; -extern GC gc, plane_gc; -extern GC clip_gc[]; +extern GC gc, clip_gc[]; extern XImage *image[]; extern Pixmap clipmask[]; extern Pixmap pix[]; @@ -237,18 +252,22 @@ extern int sound_device; extern char *sound_device_name; extern int joystick_device; extern char *joystick_device_name[2]; +extern char *level_directory; extern int width, height; extern unsigned long pen_fg, pen_bg; extern int game_status; +extern int game_emulation; extern int button_status, motion_status; -extern int key_status; +extern int key_joystick_mapping; extern int global_joystick_status, joystick_status; extern int sound_status, sound_on; extern int sound_loops_allowed, sound_loops_on; extern int sound_music_on; +extern int sound_simple_on; extern int toons_on; extern int direct_draw_on; +extern int scroll_delay_on; extern int fading_on; extern int autorecord_on; extern int joystick_nr; @@ -269,68 +288,69 @@ extern int Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern int Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern int JustHit[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern int AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; -extern int AmoebaCnt[MAX_NUM_AMOEBA]; +extern int AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA]; extern long Elementeigenschaften[MAX_ELEMENTS]; extern int level_nr, leveldir_nr, num_leveldirs; extern int lev_fieldx,lev_fieldy, scroll_x,scroll_y; extern int LevelSolved,GameOver, JX,JY, ZX,ZY; -extern int Gems,Dynamite,Key[4],TimeLeft,Score,MampferNr; -extern int DynaBombCount, DynaBombSize, DynaBombsLeft; -extern int CheckMoving,CheckExploding, SiebAktiv; +extern int FrameCounter,TimeFrames,TimeLeft,Score; +extern int Gems,SokobanFields,Lights,Dynamite,Key[4],MampferNr; +extern int DynaBombCount, DynaBombSize, DynaBombsLeft, DynaBombXL; +extern int SiebAktiv; extern struct LevelDirInfo leveldir[]; extern struct LevelInfo level; extern struct PlayerInfo player; extern struct HiScore highscore[]; -extern struct RecordingInfo tape, master_tape; +extern struct RecordingInfo tape; extern struct JoystickInfo joystick[]; extern int background_loop[]; extern int num_bg_loops; -extern char *progname; +extern char *progname; /* often used screen positions */ -#define SX 8 -#define SY 8 -#define REAL_SX (SX-2) -#define REAL_SY (SY-2) -#define DX 566 -#define DY 60 -#define VX DX -#define VY 400 -#define TILEX 32 -#define TILEY 32 -#define MINI_TILEX (TILEX/2) -#define MINI_TILEY (TILEY/2) -#define MICRO_TILEX (TILEX/8) -#define MICRO_TILEY (TILEY/8) -#define MIDPOSX (SCR_FIELDX/2) -#define MIDPOSY (SCR_FIELDY/2) -#define SXSIZE (SCR_FIELDX*TILEX) -#define SYSIZE (SCR_FIELDY*TILEY) -#define DXSIZE 100 -#define DYSIZE 280 -#define VXSIZE DXSIZE -#define VYSIZE 100 -#define FULL_SXSIZE (2+SXSIZE+2) -#define FULL_SYSIZE (2+SYSIZE+2) -#define MICROLEV_XPOS (SX+4*32+16) -#define MICROLEV_YPOS (SX+12*32) -#define MICROLEV_XSIZE (STD_LEV_FIELDX*MICRO_TILEX) -#define MICROLEV_YSIZE (STD_LEV_FIELDY*MICRO_TILEY) -#define MICROLABEL_YPOS (MICROLEV_YPOS+MICROLEV_YSIZE+12) -#define FONT1_XSIZE 32 -#define FONT1_YSIZE 32 -#define FONT2_XSIZE 14 -#define FONT2_YSIZE 14 -#define FONT3_XSIZE 11 -#define FONT3_YSIZE 14 -#define FONT4_XSIZE 16 -#define FONT4_YSIZE 16 +#define SX 8 +#define SY 8 +#define REAL_SX (SX-2) +#define REAL_SY (SY-2) +#define DX 566 +#define DY 60 +#define VX DX +#define VY 400 +#define TILEX 32 +#define TILEY 32 +#define MINI_TILEX (TILEX/2) +#define MINI_TILEY (TILEY/2) +#define MICRO_TILEX (TILEX/8) +#define MICRO_TILEY (TILEY/8) +#define MIDPOSX (SCR_FIELDX/2) +#define MIDPOSY (SCR_FIELDY/2) +#define SXSIZE (SCR_FIELDX*TILEX) +#define SYSIZE (SCR_FIELDY*TILEY) +#define DXSIZE 100 +#define DYSIZE 280 +#define VXSIZE DXSIZE +#define VYSIZE 100 +#define FULL_SXSIZE (2+SXSIZE+2) +#define FULL_SYSIZE (2+SYSIZE+2) +#define MICROLEV_XPOS (SX+4*32+16) +#define MICROLEV_YPOS (SX+12*32) +#define MICROLEV_XSIZE (STD_LEV_FIELDX*MICRO_TILEX) +#define MICROLEV_YSIZE (STD_LEV_FIELDY*MICRO_TILEY) +#define MICROLABEL_YPOS (MICROLEV_YPOS+MICROLEV_YSIZE+12) +#define FONT1_XSIZE 32 +#define FONT1_YSIZE 32 +#define FONT2_XSIZE 14 +#define FONT2_YSIZE 14 +#define FONT3_XSIZE 11 +#define FONT3_YSIZE 14 +#define FONT4_XSIZE 16 +#define FONT4_YSIZE 16 #define GFX_STARTX SX #define GFX_STARTY SY @@ -349,364 +369,413 @@ extern char *progname; ** 256 - 511: flag elements, only used at runtime */ /* "real" level elements */ -#define EL_LEERRAUM 0 -#define EL_ERDREICH 1 -#define EL_MAUERWERK 2 -#define EL_FELSBODEN 3 -#define EL_FELSBROCKEN 4 -#define EL_SCHLUESSEL 5 -#define EL_EDELSTEIN 6 -#define EL_AUSGANG_ZU 7 -#define EL_SPIELFIGUR 8 -#define EL_KAEFER 9 -#define EL_FLIEGER 10 -#define EL_MAMPFER 11 -#define EL_ZOMBIE 12 -#define EL_BETON 13 -#define EL_DIAMANT 14 -#define EL_AMOEBE_TOT 15 -#define EL_MORAST_LEER 16 -#define EL_MORAST_VOLL 17 -#define EL_TROPFEN 18 -#define EL_BOMBE 19 -#define EL_SIEB_LEER 20 -#define EL_SIEB_VOLL 21 -#define EL_SALZSAEURE 22 -#define EL_AMOEBE_NASS 23 -#define EL_AMOEBE_NORM 24 -#define EL_KOKOSNUSS 25 -#define EL_LIFE 26 -#define EL_LIFE_ASYNC 27 -#define EL_DYNAMIT 28 -#define EL_BADEWANNE 29 -#define EL_ABLENK_AUS 30 -#define EL_ABLENK_EIN 31 -#define EL_SCHLUESSEL1 32 -#define EL_SCHLUESSEL2 33 -#define EL_SCHLUESSEL3 34 -#define EL_SCHLUESSEL4 35 -#define EL_PFORTE1 36 -#define EL_PFORTE2 37 -#define EL_PFORTE3 38 -#define EL_PFORTE4 39 -#define EL_PFORTE1X 40 -#define EL_PFORTE2X 41 -#define EL_PFORTE3X 42 -#define EL_PFORTE4X 43 -#define EL_DYNAMIT_AUS 44 -#define EL_PACMAN 45 -#define EL_UNSICHTBAR 46 -#define EL_BIRNE_AUS 47 -#define EL_BIRNE_EIN 48 -#define EL_ERZ_EDEL 49 -#define EL_ERZ_DIAM 50 -#define EL_AMOEBE_VOLL 51 -#define EL_AMOEBA2DIAM 52 -#define EL_ZEIT_VOLL 53 -#define EL_ZEIT_LEER 54 -#define EL_MAUER_LEBT 55 -#define EL_EDELSTEIN2 56 -#define EL_EDELSTEIN3 57 -#define EL_ERZ_EDEL2 58 -#define EL_ERZ_EDEL3 59 -#define EL_MAMPFER2 60 -#define EL_SIEB2_LEER 61 -#define EL_SIEB2_VOLL 62 -#define EL_DYNABOMB 63 -#define EL_DYNABOMB_NR 64 -#define EL_DYNABOMB_SZ 65 - -#define EL_SPIELER1 80 -#define EL_SPIELER2 81 -#define EL_SPIELER3 82 -#define EL_SPIELER4 83 -#define EL_KAEFER_R 84 -#define EL_KAEFER_O 85 -#define EL_KAEFER_L 86 -#define EL_KAEFER_U 87 -#define EL_FLIEGER_R 88 -#define EL_FLIEGER_O 89 -#define EL_FLIEGER_L 90 -#define EL_FLIEGER_U 91 -#define EL_PACMAN_R 92 -#define EL_PACMAN_O 93 -#define EL_PACMAN_L 94 -#define EL_PACMAN_U 95 - -#define EL_BADEWANNE1 100 -#define EL_BADEWANNE2 101 -#define EL_BADEWANNE3 102 -#define EL_BADEWANNE4 103 -#define EL_BADEWANNE5 104 -#define EL_SIEB_TOT 105 -#define EL_AUSGANG_ACT 106 -#define EL_AUSGANG_AUF 107 -#define EL_SIEB2_TOT 108 - -#define EL_CHAR_START 120 -#define EL_CHAR_ASCII0 (EL_CHAR_START-32) -#define EL_CHAR_AUSRUF (EL_CHAR_ASCII0+33) -#define EL_CHAR_ZOLL (EL_CHAR_ASCII0+34) -#define EL_CHAR_DOLLAR (EL_CHAR_ASCII0+36) -#define EL_CHAR_PROZ (EL_CHAR_ASCII0+37) -#define EL_CHAR_APOSTR (EL_CHAR_ASCII0+39) -#define EL_CHAR_KLAMM1 (EL_CHAR_ASCII0+40) -#define EL_CHAR_KLAMM2 (EL_CHAR_ASCII0+41) -#define EL_CHAR_PLUS (EL_CHAR_ASCII0+43) -#define EL_CHAR_KOMMA (EL_CHAR_ASCII0+44) -#define EL_CHAR_MINUS (EL_CHAR_ASCII0+45) -#define EL_CHAR_PUNKT (EL_CHAR_ASCII0+46) -#define EL_CHAR_SLASH (EL_CHAR_ASCII0+47) -#define EL_CHAR_0 (EL_CHAR_ASCII0+48) -#define EL_CHAR_9 (EL_CHAR_ASCII0+57) -#define EL_CHAR_DOPPEL (EL_CHAR_ASCII0+58) -#define EL_CHAR_SEMIKL (EL_CHAR_ASCII0+59) -#define EL_CHAR_LT (EL_CHAR_ASCII0+60) -#define EL_CHAR_GLEICH (EL_CHAR_ASCII0+61) -#define EL_CHAR_GT (EL_CHAR_ASCII0+62) -#define EL_CHAR_FRAGE (EL_CHAR_ASCII0+63) -#define EL_CHAR_AT (EL_CHAR_ASCII0+64) -#define EL_CHAR_A (EL_CHAR_ASCII0+65) -#define EL_CHAR_Z (EL_CHAR_ASCII0+90) -#define EL_CHAR_AE (EL_CHAR_ASCII0+91) -#define EL_CHAR_OE (EL_CHAR_ASCII0+92) -#define EL_CHAR_UE (EL_CHAR_ASCII0+93) -#define EL_CHAR_COPY (EL_CHAR_ASCII0+94) -#define EL_CHAR_END (EL_CHAR_START+79) +#define EL_LEERRAUM 0 +#define EL_ERDREICH 1 +#define EL_MAUERWERK 2 +#define EL_FELSBODEN 3 +#define EL_FELSBROCKEN 4 +#define EL_SCHLUESSEL 5 +#define EL_EDELSTEIN 6 +#define EL_AUSGANG_ZU 7 +#define EL_SPIELFIGUR 8 +#define EL_KAEFER 9 +#define EL_FLIEGER 10 +#define EL_MAMPFER 11 +#define EL_ZOMBIE 12 +#define EL_BETON 13 +#define EL_DIAMANT 14 +#define EL_AMOEBE_TOT 15 +#define EL_MORAST_LEER 16 +#define EL_MORAST_VOLL 17 +#define EL_TROPFEN 18 +#define EL_BOMBE 19 +#define EL_SIEB_LEER 20 +#define EL_SIEB_VOLL 21 +#define EL_SALZSAEURE 22 +#define EL_AMOEBE_NASS 23 +#define EL_AMOEBE_NORM 24 +#define EL_KOKOSNUSS 25 +#define EL_LIFE 26 +#define EL_LIFE_ASYNC 27 +#define EL_DYNAMIT 28 +#define EL_BADEWANNE 29 +#define EL_ABLENK_AUS 30 +#define EL_ABLENK_EIN 31 +#define EL_SCHLUESSEL1 32 +#define EL_SCHLUESSEL2 33 +#define EL_SCHLUESSEL3 34 +#define EL_SCHLUESSEL4 35 +#define EL_PFORTE1 36 +#define EL_PFORTE2 37 +#define EL_PFORTE3 38 +#define EL_PFORTE4 39 +#define EL_PFORTE1X 40 +#define EL_PFORTE2X 41 +#define EL_PFORTE3X 42 +#define EL_PFORTE4X 43 +#define EL_DYNAMIT_AUS 44 +#define EL_PACMAN 45 +#define EL_UNSICHTBAR 46 +#define EL_BIRNE_AUS 47 +#define EL_BIRNE_EIN 48 +#define EL_ERZ_EDEL 49 +#define EL_ERZ_DIAM 50 +#define EL_AMOEBE_VOLL 51 +#define EL_AMOEBE_BD 52 +#define EL_ZEIT_VOLL 53 +#define EL_ZEIT_LEER 54 +#define EL_MAUER_LEBT 55 +#define EL_EDELSTEIN_BD 56 +#define EL_EDELSTEIN_GELB 57 +#define EL_ERZ_EDEL_BD 58 +#define EL_ERZ_EDEL_GELB 59 +#define EL_MAMPFER2 60 +#define EL_SIEB2_LEER 61 +#define EL_SIEB2_VOLL 62 +#define EL_DYNABOMB 63 +#define EL_DYNABOMB_NR 64 +#define EL_DYNABOMB_SZ 65 +#define EL_DYNABOMB_XL 66 +#define EL_SOKOBAN_OBJEKT 67 +#define EL_SOKOBAN_FELD_LEER 68 +#define EL_SOKOBAN_FELD_VOLL 69 +#define EL_BUTTERFLY_R 70 +#define EL_BUTTERFLY_O 71 +#define EL_BUTTERFLY_L 72 +#define EL_BUTTERFLY_U 73 +#define EL_FIREFLY_R 74 +#define EL_FIREFLY_O 75 +#define EL_FIREFLY_L 76 +#define EL_FIREFLY_U 77 +#define EL_BUTTERFLY_1 EL_BUTTERFLY_U +#define EL_BUTTERFLY_2 EL_BUTTERFLY_L +#define EL_BUTTERFLY_3 EL_BUTTERFLY_O +#define EL_BUTTERFLY_4 EL_BUTTERFLY_R +#define EL_FIREFLY_1 EL_FIREFLY_L +#define EL_FIREFLY_2 EL_FIREFLY_U +#define EL_FIREFLY_3 EL_FIREFLY_R +#define EL_FIREFLY_4 EL_FIREFLY_O +#define EL_BUTTERFLY 78 +#define EL_FIREFLY 79 +#define EL_SPIELER1 80 +#define EL_SPIELER2 81 +#define EL_SPIELER3 82 +#define EL_SPIELER4 83 +#define EL_KAEFER_R 84 +#define EL_KAEFER_O 85 +#define EL_KAEFER_L 86 +#define EL_KAEFER_U 87 +#define EL_FLIEGER_R 88 +#define EL_FLIEGER_O 89 +#define EL_FLIEGER_L 90 +#define EL_FLIEGER_U 91 +#define EL_PACMAN_R 92 +#define EL_PACMAN_O 93 +#define EL_PACMAN_L 94 +#define EL_PACMAN_U 95 +#define EL_EDELSTEIN_ROT 96 +#define EL_EDELSTEIN_LILA 97 +#define EL_ERZ_EDEL_ROT 98 +#define EL_ERZ_EDEL_LILA 99 +#define EL_BADEWANNE1 100 +#define EL_BADEWANNE2 101 +#define EL_BADEWANNE3 102 +#define EL_BADEWANNE4 103 +#define EL_BADEWANNE5 104 +#define EL_SIEB_TOT 105 +#define EL_AUSGANG_ACT 106 +#define EL_AUSGANG_AUF 107 +#define EL_SIEB2_TOT 108 +#define EL_AMOEBA2DIAM 109 + +#define EL_CHAR_START 120 +#define EL_CHAR_ASCII0 (EL_CHAR_START-32) +#define EL_CHAR_AUSRUF (EL_CHAR_ASCII0+33) +#define EL_CHAR_ZOLL (EL_CHAR_ASCII0+34) +#define EL_CHAR_DOLLAR (EL_CHAR_ASCII0+36) +#define EL_CHAR_PROZ (EL_CHAR_ASCII0+37) +#define EL_CHAR_APOSTR (EL_CHAR_ASCII0+39) +#define EL_CHAR_KLAMM1 (EL_CHAR_ASCII0+40) +#define EL_CHAR_KLAMM2 (EL_CHAR_ASCII0+41) +#define EL_CHAR_PLUS (EL_CHAR_ASCII0+43) +#define EL_CHAR_KOMMA (EL_CHAR_ASCII0+44) +#define EL_CHAR_MINUS (EL_CHAR_ASCII0+45) +#define EL_CHAR_PUNKT (EL_CHAR_ASCII0+46) +#define EL_CHAR_SLASH (EL_CHAR_ASCII0+47) +#define EL_CHAR_0 (EL_CHAR_ASCII0+48) +#define EL_CHAR_9 (EL_CHAR_ASCII0+57) +#define EL_CHAR_DOPPEL (EL_CHAR_ASCII0+58) +#define EL_CHAR_SEMIKL (EL_CHAR_ASCII0+59) +#define EL_CHAR_LT (EL_CHAR_ASCII0+60) +#define EL_CHAR_GLEICH (EL_CHAR_ASCII0+61) +#define EL_CHAR_GT (EL_CHAR_ASCII0+62) +#define EL_CHAR_FRAGE (EL_CHAR_ASCII0+63) +#define EL_CHAR_AT (EL_CHAR_ASCII0+64) +#define EL_CHAR_A (EL_CHAR_ASCII0+65) +#define EL_CHAR_Z (EL_CHAR_ASCII0+90) +#define EL_CHAR_AE (EL_CHAR_ASCII0+91) +#define EL_CHAR_OE (EL_CHAR_ASCII0+92) +#define EL_CHAR_UE (EL_CHAR_ASCII0+93) +#define EL_CHAR_COPY (EL_CHAR_ASCII0+94) +#define EL_CHAR_END (EL_CHAR_START+79) /* "unreal" runtime elements */ -#define EL_BLOCKED 300 -#define EL_EXPLODING 301 -#define EL_CRACKINGNUT 302 -#define EL_BLURB_LEFT 303 -#define EL_BLURB_RIGHT 304 -#define EL_AMOEBING 305 -#define EL_MAUERND 306 +#define EL_BLOCKED 300 +#define EL_EXPLODING 301 +#define EL_CRACKINGNUT 302 +#define EL_BLURB_LEFT 303 +#define EL_BLURB_RIGHT 304 +#define EL_AMOEBING 305 +#define EL_MAUERND 306 /* names for the graphic objects */ /* Zeile 0 (0) */ -#define GFX_LEERRAUM (-1) -#define GFX_ERDREICH 0 -#define GFX_ERDENRAND 1 -#define GFX_MORAST_LEER 2 -#define GFX_MORAST_VOLL 3 -#define GFX_BETON 4 -#define GFX_MAUERWERK 5 -#define GFX_FELSBODEN 6 -#define GFX_DYNABOMB 7 -#define GFX_DYNABOMB_NR GFX_DYNABOMB -#define GFX_EDELSTEIN 8 -#define GFX_DIAMANT 10 -#define GFX_FELSBROCKEN 12 +#define GFX_LEERRAUM (-1) +#define GFX_ERDREICH 0 +#define GFX_ERDENRAND 1 +#define GFX_MORAST_LEER 2 +#define GFX_MORAST_VOLL 3 +#define GFX_BETON 4 +#define GFX_MAUERWERK 5 +#define GFX_FELSBODEN 6 +#define GFX_EDELSTEIN 8 +#define GFX_DIAMANT 10 +#define GFX_FELSBROCKEN 12 /* Zeile 1 (16) */ -#define GFX_BADEWANNE1 16 -#define GFX_SALZSAEURE 17 -#define GFX_BADEWANNE2 18 -#define GFX_UNSICHTBAR 19 -#define GFX_SCHLUESSEL1 20 -#define GFX_SCHLUESSEL2 21 -#define GFX_SCHLUESSEL3 22 -#define GFX_SCHLUESSEL4 23 -#define GFX_LIFE 24 -#define GFX_LIFE_ASYNC 25 -#define GFX_BADEWANNE 26 -#define GFX_BOMBE 27 -#define GFX_KOKOSNUSS 28 -#define GFX_CRACKINGNUT 29 +#define GFX_BADEWANNE1 16 +#define GFX_SALZSAEURE 17 +#define GFX_BADEWANNE2 18 +#define GFX_UNSICHTBAR 19 +#define GFX_SCHLUESSEL1 20 +#define GFX_SCHLUESSEL2 21 +#define GFX_SCHLUESSEL3 22 +#define GFX_SCHLUESSEL4 23 +#define GFX_LIFE 24 +#define GFX_LIFE_ASYNC 25 +#define GFX_BADEWANNE 26 +#define GFX_BOMBE 27 +#define GFX_KOKOSNUSS 28 +#define GFX_CRACKINGNUT 29 /* Zeile 2 (32) */ -#define GFX_BADEWANNE3 32 -#define GFX_BADEWANNE4 33 -#define GFX_BADEWANNE5 34 -#define GFX_SPIELFIGUR 35 -#define GFX_PFORTE1 36 -#define GFX_PFORTE2 37 -#define GFX_PFORTE3 38 -#define GFX_PFORTE4 39 -#define GFX_PFORTE1X 40 -#define GFX_PFORTE2X 41 -#define GFX_PFORTE3X 42 -#define GFX_PFORTE4X 43 +#define GFX_BADEWANNE3 32 +#define GFX_BADEWANNE4 33 +#define GFX_BADEWANNE5 34 +#define GFX_SPIELFIGUR 35 +#define GFX_PFORTE1 36 +#define GFX_PFORTE2 37 +#define GFX_PFORTE3 38 +#define GFX_PFORTE4 39 +#define GFX_PFORTE1X 40 +#define GFX_PFORTE2X 41 +#define GFX_PFORTE3X 42 +#define GFX_PFORTE4X 43 /* Zeile 3 (48) */ -#define GFX_DYNAMIT_AUS 48 -#define GFX_DYNAMIT 49 -#define GFX_FLIEGER 56 -#define GFX_FLIEGER_R 56 -#define GFX_FLIEGER_O 57 -#define GFX_FLIEGER_L 58 -#define GFX_FLIEGER_U 59 +#define GFX_DYNAMIT_AUS 48 +#define GFX_DYNAMIT 49 +#define GFX_FLIEGER 56 +#define GFX_FLIEGER_R 56 +#define GFX_FLIEGER_O 57 +#define GFX_FLIEGER_L 58 +#define GFX_FLIEGER_U 59 /* Zeile 4 (64) */ -#define GFX_EXPLOSION 64 -#define GFX_KAEFER 72 -#define GFX_KAEFER_R 72 -#define GFX_KAEFER_O 73 -#define GFX_KAEFER_L 74 -#define GFX_KAEFER_U 75 +#define GFX_EXPLOSION 64 +#define GFX_KAEFER 72 +#define GFX_KAEFER_R 72 +#define GFX_KAEFER_O 73 +#define GFX_KAEFER_L 74 +#define GFX_KAEFER_U 75 /* Zeile 5 (80) */ -#define GFX_MAMPFER 80 -#define GFX_ZOMBIE 84 -#define GFX_PACMAN 88 -#define GFX_PACMAN_R 88 -#define GFX_PACMAN_O 89 -#define GFX_PACMAN_L 90 -#define GFX_PACMAN_U 91 +#define GFX_MAMPFER 80 +#define GFX_ZOMBIE 84 +#define GFX_PACMAN 88 +#define GFX_PACMAN_R 88 +#define GFX_PACMAN_O 89 +#define GFX_PACMAN_L 90 +#define GFX_PACMAN_U 91 /* Zeile 6 (96) */ -#define GFX_ABLENK 96 -#define GFX_ABLENK_EIN GFX_ABLENK -#define GFX_ABLENK_AUS GFX_ABLENK -#define GFX_AMOEBE_NASS 100 -#define GFX_TROPFEN 101 -#define GFX_AMOEBING GFX_TROPFEN -#define GFX_AMOEBE_LEBT 104 -#define GFX_AMOEBE_NORM GFX_AMOEBE_LEBT -#define GFX_AMOEBE_TOT 108 -#define GFX_AMOEBA2DIAM GFX_AMOEBE_TOT -#define GFX_BIRNE_AUS 112 -#define GFX_BIRNE_EIN 113 -#define GFX_ZEIT_VOLL 114 -#define GFX_ZEIT_LEER 115 +#define GFX_ABLENK 96 +#define GFX_ABLENK_EIN GFX_ABLENK +#define GFX_ABLENK_AUS GFX_ABLENK +#define GFX_AMOEBE_NASS 100 +#define GFX_TROPFEN 101 +#define GFX_AMOEBING GFX_TROPFEN +#define GFX_AMOEBE_LEBT 104 +#define GFX_AMOEBE_NORM GFX_AMOEBE_LEBT +#define GFX_AMOEBE_TOT 108 +#define GFX_AMOEBA2DIAM GFX_AMOEBE_TOT /* Zeile 7 (112) */ -#define GFX_GEBLUBBER 124 +#define GFX_BIRNE_AUS 112 +#define GFX_BIRNE_EIN 113 +#define GFX_ZEIT_VOLL 114 +#define GFX_ZEIT_LEER 115 +#define GFX_AMOEBE_VOLL 120 +#define GFX_AMOEBE_BD GFX_AMOEBE_VOLL +#define GFX_SOKOBAN_OBJEKT 121 +#define GFX_SOKOBAN_FELD_LEER 122 +#define GFX_SOKOBAN_FELD_VOLL 123 +#define GFX_GEBLUBBER 124 /* Zeile 8 (128) */ -#define GFX_SIEB_LEER 128 -#define GFX_SIEB_VOLL GFX_SIEB_LEER -#define GFX_SIEB_TOT GFX_SIEB_LEER -#define GFX_ERZ_EDEL 132 -#define GFX_ERZ_DIAM 133 -#define GFX_ERZ_EDEL2 134 -#define GFX_ERZ_EDEL3 135 -#define GFX_AMOEBE_VOLL 136 -#define GFX_KUGEL_ROT 140 -#define GFX_KUGEL_BLAU 141 -#define GFX_KUGEL_GELB 142 -#define GFX_KUGEL_GRAU 143 -#define GFX_DYNABOMB_SZ GFX_KUGEL_GRAU +#define GFX_SIEB_LEER 128 +#define GFX_SIEB_VOLL GFX_SIEB_LEER +#define GFX_SIEB_TOT GFX_SIEB_LEER +#define GFX_ERZ_EDEL 132 +#define GFX_ERZ_DIAM 133 +#define GFX_ERZ_EDEL_ROT 134 +#define GFX_ERZ_EDEL_LILA 135 +#define GFX_ERZ_EDEL_GELB 136 +#define GFX_ERZ_EDEL_BD 137 +#define GFX_EDELSTEIN_GELB 138 +#define GFX_KUGEL_ROT 140 +#define GFX_KUGEL_BLAU 141 +#define GFX_KUGEL_GELB 142 +#define GFX_KUGEL_GRAU 143 /* Zeile 9 (144) */ -#define GFX_BLURB_LEFT 144 -#define GFX_BLURB_RIGHT 148 -#define GFX_EDELSTEIN3 152 +#define GFX_BLURB_LEFT 144 +#define GFX_BLURB_RIGHT 148 +#define GFX_EDELSTEIN_ROT 152 +#define GFX_EDELSTEIN_LILA 154 +#define GFX_DYNABOMB_XL 156 /* Zeile 10 (160) */ -#define GFX_EDELSTEIN2 163 -#define GFX_MAUER_R1 165 -#define GFX_MAUER_R 167 -#define GFX_MAUER_L1 168 -#define GFX_MAUER_L 170 -#define GFX_MAUER_LEBT 171 -#define GFX_SIEB2_LEER 172 -#define GFX_SIEB2_VOLL GFX_SIEB2_LEER -#define GFX_SIEB2_TOT GFX_SIEB2_LEER +#define GFX_EDELSTEIN_BD 163 +#define GFX_MAUER_R1 165 +#define GFX_MAUER_R 167 +#define GFX_MAUER_L1 168 +#define GFX_MAUER_L 170 +#define GFX_MAUER_LEBT 171 +#define GFX_SIEB2_LEER 172 +#define GFX_SIEB2_VOLL GFX_SIEB2_LEER +#define GFX_SIEB2_TOT GFX_SIEB2_LEER /* Zeile 11 (176) */ -#define GFX_AUSGANG_ZU 176 -#define GFX_AUSGANG_ACT 177 -#define GFX_AUSGANG_AUF 180 -#define GFX_MAMPFER2 184 - -#define GFX_SCHLUESSEL GFX_SCHLUESSEL1 - -#define GFX_SPIELER1 116 -#define GFX_SPIELER2 117 -#define GFX_SPIELER3 118 -#define GFX_SPIELER4 119 +#define GFX_AUSGANG_ZU 176 +#define GFX_AUSGANG_ACT 177 +#define GFX_AUSGANG_AUF 180 +#define GFX_MAMPFER2 184 +#define GFX_DYNABOMB 188 +#define GFX_DYNABOMB_NR 188 +#define GFX_DYNABOMB_SZ 191 +/* Zeile 12 (192) */ +#define GFX_PFEIL_L 192 +#define GFX_PFEIL_R 193 +#define GFX_PFEIL_O 194 +#define GFX_PFEIL_U 195 +#define GFX_BUTTERFLY 196 +#define GFX_FIREFLY 198 +#define GFX_BUTTERFLY_R 200 +#define GFX_BUTTERFLY_O 201 +#define GFX_BUTTERFLY_L 202 +#define GFX_BUTTERFLY_U 203 +#define GFX_FIREFLY_R 204 +#define GFX_FIREFLY_O 205 +#define GFX_FIREFLY_L 206 +#define GFX_FIREFLY_U 207 + +#define GFX_SCHLUESSEL GFX_SCHLUESSEL1 + +#define GFX_SPIELER1 116 +#define GFX_SPIELER2 117 +#define GFX_SPIELER3 118 +#define GFX_SPIELER4 119 /* nicht in "RocksScreen" sondern woanders :) */ -#define GFX_CHAR_START 256 -#define GFX_CHAR_ASCII0 (GFX_CHAR_START-32) -#define GFX_CHAR_AUSRUF (GFX_CHAR_ASCII0+33) -#define GFX_CHAR_ZOLL (GFX_CHAR_ASCII0+34) -#define GFX_CHAR_DOLLAR (GFX_CHAR_ASCII0+36) -#define GFX_CHAR_PROZ (GFX_CHAR_ASCII0+37) -#define GFX_CHAR_APOSTR (GFX_CHAR_ASCII0+39) -#define GFX_CHAR_KLAMM1 (GFX_CHAR_ASCII0+40) -#define GFX_CHAR_KLAMM2 (GFX_CHAR_ASCII0+41) -#define GFX_CHAR_PLUS (GFX_CHAR_ASCII0+43) -#define GFX_CHAR_KOMMA (GFX_CHAR_ASCII0+44) -#define GFX_CHAR_MINUS (GFX_CHAR_ASCII0+45) -#define GFX_CHAR_PUNKT (GFX_CHAR_ASCII0+46) -#define GFX_CHAR_SLASH (GFX_CHAR_ASCII0+47) -#define GFX_CHAR_0 (GFX_CHAR_ASCII0+48) -#define GFX_CHAR_9 (GFX_CHAR_ASCII0+57) -#define GFX_CHAR_DOPPEL (GFX_CHAR_ASCII0+58) -#define GFX_CHAR_SEMIKL (GFX_CHAR_ASCII0+59) -#define GFX_CHAR_LT (GFX_CHAR_ASCII0+60) -#define GFX_CHAR_GLEICH (GFX_CHAR_ASCII0+61) -#define GFX_CHAR_GT (GFX_CHAR_ASCII0+62) -#define GFX_CHAR_FRAGE (GFX_CHAR_ASCII0+63) -#define GFX_CHAR_AT (GFX_CHAR_ASCII0+64) -#define GFX_CHAR_A (GFX_CHAR_ASCII0+65) -#define GFX_CHAR_Z (GFX_CHAR_ASCII0+90) -#define GFX_CHAR_AE (GFX_CHAR_ASCII0+91) -#define GFX_CHAR_OE (GFX_CHAR_ASCII0+92) -#define GFX_CHAR_UE (GFX_CHAR_ASCII0+93) -#define GFX_CHAR_COPY (GFX_CHAR_ASCII0+94) -#define GFX_CHAR_END (GFX_CHAR_START+79) +#define GFX_CHAR_START 256 +#define GFX_CHAR_ASCII0 (GFX_CHAR_START-32) +#define GFX_CHAR_AUSRUF (GFX_CHAR_ASCII0+33) +#define GFX_CHAR_ZOLL (GFX_CHAR_ASCII0+34) +#define GFX_CHAR_DOLLAR (GFX_CHAR_ASCII0+36) +#define GFX_CHAR_PROZ (GFX_CHAR_ASCII0+37) +#define GFX_CHAR_APOSTR (GFX_CHAR_ASCII0+39) +#define GFX_CHAR_KLAMM1 (GFX_CHAR_ASCII0+40) +#define GFX_CHAR_KLAMM2 (GFX_CHAR_ASCII0+41) +#define GFX_CHAR_PLUS (GFX_CHAR_ASCII0+43) +#define GFX_CHAR_KOMMA (GFX_CHAR_ASCII0+44) +#define GFX_CHAR_MINUS (GFX_CHAR_ASCII0+45) +#define GFX_CHAR_PUNKT (GFX_CHAR_ASCII0+46) +#define GFX_CHAR_SLASH (GFX_CHAR_ASCII0+47) +#define GFX_CHAR_0 (GFX_CHAR_ASCII0+48) +#define GFX_CHAR_9 (GFX_CHAR_ASCII0+57) +#define GFX_CHAR_DOPPEL (GFX_CHAR_ASCII0+58) +#define GFX_CHAR_SEMIKL (GFX_CHAR_ASCII0+59) +#define GFX_CHAR_LT (GFX_CHAR_ASCII0+60) +#define GFX_CHAR_GLEICH (GFX_CHAR_ASCII0+61) +#define GFX_CHAR_GT (GFX_CHAR_ASCII0+62) +#define GFX_CHAR_FRAGE (GFX_CHAR_ASCII0+63) +#define GFX_CHAR_AT (GFX_CHAR_ASCII0+64) +#define GFX_CHAR_A (GFX_CHAR_ASCII0+65) +#define GFX_CHAR_Z (GFX_CHAR_ASCII0+90) +#define GFX_CHAR_AE (GFX_CHAR_ASCII0+91) +#define GFX_CHAR_OE (GFX_CHAR_ASCII0+92) +#define GFX_CHAR_UE (GFX_CHAR_ASCII0+93) +#define GFX_CHAR_COPY (GFX_CHAR_ASCII0+94) +#define GFX_CHAR_END (GFX_CHAR_START+79) /* score for elements */ -#define SC_EDELSTEIN 0 -#define SC_DIAMANT 1 -#define SC_KAEFER 2 -#define SC_FLIEGER 3 -#define SC_MAMPFER 4 -#define SC_ZOMBIE 5 -#define SC_PACMAN 6 -#define SC_KOKOSNUSS 7 -#define SC_DYNAMIT 8 -#define SC_SCHLUESSEL 9 -#define SC_ZEITBONUS 10 +#define SC_EDELSTEIN 0 +#define SC_DIAMANT 1 +#define SC_KAEFER 2 +#define SC_FLIEGER 3 +#define SC_MAMPFER 4 +#define SC_ZOMBIE 5 +#define SC_PACMAN 6 +#define SC_KOKOSNUSS 7 +#define SC_DYNAMIT 8 +#define SC_SCHLUESSEL 9 +#define SC_ZEITBONUS 10 /* the names of the sounds */ -#define SND_ALCHEMY 0 -#define SND_AMOEBE 1 -#define SND_ANTIGRAV 2 -#define SND_AUTSCH 3 -#define SND_BLURB 4 -#define SND_BONG 5 -#define SND_BUING 6 -#define SND_CHASE 7 -#define SND_CZARDASZ 8 -#define SND_DENG 9 -#define SND_FUEL 10 -#define SND_GONG 11 -#define SND_HALLOFFAME 12 -#define SND_HOLZ 13 -#define SND_HUI 14 -#define SND_KABUMM 15 -#define SND_KINK 16 -#define SND_KLAPPER 17 -#define SND_KLING 18 -#define SND_KLOPF 19 -#define SND_KLUMPF 20 -#define SND_KNACK 21 -#define SND_KNURK 22 -#define SND_KRACH 23 -#define SND_LACHEN 24 -#define SND_LASER 25 -#define SND_MIEP 26 -#define SND_NETWORK 27 -#define SND_NJAM 28 -#define SND_OEFFNEN 29 -#define SND_PLING 30 -#define SND_PONG 31 -#define SND_PUSCH 32 -#define SND_QUIEK 33 -#define SND_QUIRK 34 -#define SND_RHYTHMLOOP 35 -#define SND_ROAAAR 36 -#define SND_ROEHR 37 -#define SND_RUMMS 38 -#define SND_SCHLOPP 39 -#define SND_SCHLURF 40 -#define SND_SCHRFF 41 -#define SND_SCHWIRR 42 -#define SND_SIRR 43 -#define SND_SLURP 44 -#define SND_SPROING 45 -#define SND_TWILIGHT 46 -#define SND_TYGER 47 -#define SND_VOYAGER 48 -#define SND_WARNTON 49 -#define SND_WHOOSH 50 -#define SND_ZISCH 51 - -#define NUM_SOUNDS 52 +#define SND_ALCHEMY 0 +#define SND_AMOEBE 1 +#define SND_ANTIGRAV 2 +#define SND_AUTSCH 3 +#define SND_BLURB 4 +#define SND_BONG 5 +#define SND_BUING 6 +#define SND_CHASE 7 +#define SND_CZARDASZ 8 +#define SND_DENG 9 +#define SND_FUEL 10 +#define SND_GONG 11 +#define SND_HALLOFFAME 12 +#define SND_HOLZ 13 +#define SND_HUI 14 +#define SND_KABUMM 15 +#define SND_KINK 16 +#define SND_KLAPPER 17 +#define SND_KLING 18 +#define SND_KLOPF 19 +#define SND_KLUMPF 20 +#define SND_KNACK 21 +#define SND_KNURK 22 +#define SND_KRACH 23 +#define SND_LACHEN 24 +#define SND_LASER 25 +#define SND_MIEP 26 +#define SND_NETWORK 27 +#define SND_NJAM 28 +#define SND_OEFFNEN 29 +#define SND_PLING 30 +#define SND_PONG 31 +#define SND_PUSCH 32 +#define SND_QUIEK 33 +#define SND_QUIRK 34 +#define SND_RHYTHMLOOP 35 +#define SND_ROAAAR 36 +#define SND_ROEHR 37 +#define SND_RUMMS 38 +#define SND_SCHLOPP 39 +#define SND_SCHLURF 40 +#define SND_SCHRFF 41 +#define SND_SCHWIRR 42 +#define SND_SIRR 43 +#define SND_SLURP 44 +#define SND_SPROING 45 +#define SND_TWILIGHT 46 +#define SND_TYGER 47 +#define SND_VOYAGER 48 +#define SND_WARNTON 49 +#define SND_WHOOSH 50 +#define SND_ZISCH 51 + +#define NUM_SOUNDS 52 #define IS_LOOP_SOUND(s) ((s)==SND_KLAPPER || (s)==SND_ROEHR || \ (s)==SND_NJAM || (s)==SND_MIEP) @@ -720,43 +789,44 @@ extern char *sound_name[NUM_SOUNDS]; extern struct SoundInfo Sound[NUM_SOUNDS]; /* directions for moving */ -#define MV_NO_MOVING 0 -#define MV_LEFT 1 -#define MV_RIGHT 2 -#define MV_UP 4 -#define MV_DOWN 8 +#define MV_NO_MOVING 0 +#define MV_LEFT 1 +#define MV_RIGHT 2 +#define MV_UP 4 +#define MV_DOWN 8 /* font types */ -#define FS_SMALL 0 -#define FS_BIG 1 +#define FS_SMALL 0 +#define FS_BIG 1 /* font colors */ -#define FC_RED 0 -#define FC_BLUE 1 -#define FC_GREEN 2 -#define FC_YELLOW 3 -#define FC_SPECIAL1 4 -#define FC_SPECIAL2 5 +#define FC_RED 0 +#define FC_BLUE 1 +#define FC_GREEN 2 +#define FC_YELLOW 3 +#define FC_SPECIAL1 4 +#define FC_SPECIAL2 5 /* values for game_status */ -#define MAINMENU 0 -#define PLAYING 1 -#define LEVELED 2 -#define HELPSCREEN 3 -#define CHOOSELEVEL 4 -#define TYPENAME 5 -#define HALLOFFAME 6 -#define SETUP 7 -#define EXITGAME 8 - -/* return values for GameActions */ -#define ACT_GO_ON 0 -#define ACT_GAME_OVER 1 -#define ACT_NEW_GAME 2 +#define MAINMENU 0 +#define PLAYING 1 +#define LEVELED 2 +#define HELPSCREEN 3 +#define CHOOSELEVEL 4 +#define TYPENAME 5 +#define HALLOFFAME 6 +#define SETUP 7 +#define EXITGAME 8 + +/* values for game_emulation */ +#define EMU_NONE 0 +#define EMU_BOULDERDASH 1 +#define EMU_SOKOBAN 2 /* values for the joystick */ #define JOYSTICK_OFF 0 #define JOYSTICK_AVAILABLE 1 #ifdef __FreeBSD__ +#include #define DEV_JOYSTICK_0 "/dev/joy0" #define DEV_JOYSTICK_1 "/dev/joy1" #else @@ -786,57 +856,60 @@ extern struct SoundInfo Sound[NUM_SOUNDS]; #define JOY_BUTTON_NEW_RELEASED 3 #ifdef NO_JOYSTICK -#define JOYSTICK_STATUS JOYSTICK_OFF +#define JOYSTICK_STATUS JOYSTICK_OFF #else -#define JOYSTICK_STATUS JOYSTICK_AVAILABLE +#define JOYSTICK_STATUS JOYSTICK_AVAILABLE #endif #ifndef GAME_DIR -#define GAME_DIR "." +#define GAME_DIR "." #endif #ifndef GFX_PATH -#define GFX_PATH GAME_DIR "/graphics" +#define GFX_PATH GAME_DIR "/graphics" #endif #ifndef SND_PATH -#define SND_PATH GAME_DIR "/sounds" +#define SND_PATH GAME_DIR "/sounds" #endif #ifndef LEVEL_PATH -#define LEVEL_PATH GAME_DIR "/levels" +#define LEVEL_PATH GAME_DIR "/levels" #endif #ifndef SCORE_PATH -#define SCORE_PATH LEVEL_PATH +#define SCORE_PATH LEVEL_PATH #endif #ifndef NAMES_PATH -#define NAMES_PATH LEVEL_PATH +#define NAMES_PATH LEVEL_PATH #endif #ifndef CONFIG_PATH -#define CONFIG_PATH GAME_DIR +#define CONFIG_PATH GAME_DIR #endif #ifndef JOYDAT_PATH -#define JOYDAT_PATH GAME_DIR +#define JOYDAT_PATH GAME_DIR #endif -#define SCORE_FILENAME "ROCKS.score" -#define NAMES_FILENAME "ROCKS.names" -#define LEVDIR_FILENAME "ROCKS.levelinfo" -#define JOYDAT_FILENAME "ROCKS.joystick" +#define SCORE_FILENAME "ROCKS.score" +#define NAMES_FILENAME "ROCKS.names" +#define LEVDIR_FILENAME "ROCKS.levelinfo" +#define JOYDAT_FILENAME "ROCKS.joystick" -#define JOYDAT_FILE JOYDAT_PATH "/" JOYDAT_FILENAME +#define JOYDAT_FILE JOYDAT_PATH "/" JOYDAT_FILENAME #define LEVEL_PERMS (S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | S_IROTH|S_IWOTH) -#define SCORE_PERMS LEVEL_PERMS -#define NAMES_PERMS LEVEL_PERMS -#define LEVDIR_PERMS LEVEL_PERMS -#define LEVREC_PERMS LEVEL_PERMS -#define JOYDAT_PERMS LEVEL_PERMS - -#define LEVEL_COOKIE "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_1.0" -#define SCORE_COOKIE "ROCKSNDIAMONDS_SCORE_FILE_VERSION_1.0" -#define NAMES_COOKIE "ROCKSNDIAMONDS_NAMES_FILE_VERSION_1.0" -#define LEVELDIR_COOKIE "ROCKSNDIAMONDS_LEVELDIR_FILE_VERSION_1.0" -#define LEVELREC_COOKIE "ROCKSNDIAMONDS_LEVELREC_FILE_VERSION_1.0" -#define JOYSTICK_COOKIE "ROCKSNDIAMONDS_JOYSTICK_FILE_VERSION_1.0" +#define SCORE_PERMS LEVEL_PERMS +#define NAMES_PERMS LEVEL_PERMS +#define LEVDIR_PERMS LEVEL_PERMS +#define LEVREC_PERMS LEVEL_PERMS +#define JOYDAT_PERMS LEVEL_PERMS + +/* old cookies */ +#define NAMES_COOKIE_10 "ROCKSNDIAMONDS_NAMES_FILE_VERSION_1.0" + +#define LEVEL_COOKIE "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_1.0" +#define SCORE_COOKIE "ROCKSNDIAMONDS_SCORE_FILE_VERSION_1.0" +#define NAMES_COOKIE "ROCKSNDIAMONDS_NAMES_FILE_VERSION_1.1" +#define LEVELDIR_COOKIE "ROCKSNDIAMONDS_LEVELDIR_FILE_VERSION_1.0" +#define LEVELREC_COOKIE "ROCKSNDIAMONDS_LEVELREC_FILE_VERSION_1.0" +#define JOYSTICK_COOKIE "ROCKSNDIAMONDS_JOYSTICK_FILE_VERSION_1.0" #define LEVEL_COOKIE_LEN (strlen(LEVEL_COOKIE)+1) #define SCORE_COOKIE_LEN (strlen(SCORE_COOKIE)+1) #define NAMES_COOKIE_LEN (strlen(NAMES_COOKIE)+1) @@ -844,69 +917,74 @@ extern struct SoundInfo Sound[NUM_SOUNDS]; #define LEVELREC_COOKIE_LEN (strlen(LEVELREC_COOKIE)+1) #define JOYSTICK_COOKIE_LEN (strlen(JOYSTICK_COOKIE)+1) +#define VERSION_STRING "1.1" +#define GAMETITLE_STRING "Rocks'n'Diamonds" +#define WINDOWTITLE_STRING GAMETITLE_STRING " " VERSION_STRING +#define COPYRIGHT_STRING "Copyright ^1995-97 by Holger Schemel" + /* Leerer Login- und Alias-Name */ -#define EMPTY_LOGIN "NO_LOGIN" -#define EMPTY_ALIAS "NO_NAME" +#define EMPTY_LOGIN "NO_LOGIN" +#define EMPTY_ALIAS "NO_NAME" /* values for button_status */ -#define MB_NOT_PRESSED FALSE -#define MB_RELEASED FALSE -#define MB_PRESSED TRUE -#define MB_MENU_CHOICE FALSE -#define MB_MENU_MARK TRUE -#define MB_LEFT 1 -#define MB_MIDDLE 2 -#define MB_RIGHT 3 +#define MB_NOT_PRESSED FALSE +#define MB_RELEASED FALSE +#define MB_PRESSED TRUE +#define MB_MENU_CHOICE FALSE +#define MB_MENU_MARK TRUE +#define MB_LEFT 1 +#define MB_MIDDLE 2 +#define MB_RIGHT 3 /* values for key_status */ -#define KEY_NOT_PRESSED FALSE -#define KEY_RELEASED FALSE -#define KEY_PRESSED TRUE +#define KEY_NOT_PRESSED FALSE +#define KEY_RELEASED FALSE +#define KEY_PRESSED TRUE /* values for focus_status */ -#define FOCUS_OUT FALSE -#define FOCUS_IN TRUE +#define FOCUS_OUT FALSE +#define FOCUS_IN TRUE /* values for redraw_mask */ -#define REDRAW_ALL (1L<<0) -#define REDRAW_FIELD (1L<<1) -#define REDRAW_TILES (1L<<2) -#define REDRAW_DOOR_1 (1L<<3) -#define REDRAW_VIDEO_1 (1L<<4) -#define REDRAW_VIDEO_2 (1L<<5) -#define REDRAW_VIDEO_3 (1L<<6) -#define REDRAW_MICROLEV (1L<<7) +#define REDRAW_ALL (1L<<0) +#define REDRAW_FIELD (1L<<1) +#define REDRAW_TILES (1L<<2) +#define REDRAW_DOOR_1 (1L<<3) +#define REDRAW_VIDEO_1 (1L<<4) +#define REDRAW_VIDEO_2 (1L<<5) +#define REDRAW_VIDEO_3 (1L<<6) +#define REDRAW_MICROLEV (1L<<7) #define REDRAW_DOOR_2 (REDRAW_VIDEO_1 | REDRAW_VIDEO_2 | REDRAW_VIDEO_3) #define REDRAW_DOORS (REDRAW_DOOR_1 | REDRAW_DOOR_2) #define REDRAW_MAIN (REDRAW_FIELD | REDRAW_TILES | REDRAW_MICROLEV) -#define REDRAWTILES_TH SCR_FIELDX*SCR_FIELDY/2 +#define REDRAWTILES_TH SCR_FIELDX*SCR_FIELDY/2 /* positions in the game control window */ -#define XX_LEVEL 37 -#define YY_LEVEL 20 -#define XX_EMERALDS 29 -#define YY_EMERALDS 54 -#define XX_DYNAMITE 29 -#define YY_DYNAMITE 89 -#define XX_KEYS 18 -#define YY_KEYS 123 -#define XX_SCORE 15 -#define YY_SCORE 159 -#define XX_TIME 29 -#define YY_TIME 194 - -#define DX_LEVEL (DX+XX_LEVEL) -#define DY_LEVEL (DY+YY_LEVEL) -#define DX_EMERALDS (DX+XX_EMERALDS) -#define DY_EMERALDS (DY+YY_EMERALDS) -#define DX_DYNAMITE (DX+XX_DYNAMITE) -#define DY_DYNAMITE (DY+YY_DYNAMITE) -#define DX_KEYS (DX+XX_KEYS) -#define DY_KEYS (DY+YY_KEYS) -#define DX_SCORE (DX+XX_SCORE) -#define DY_SCORE (DY+YY_SCORE) -#define DX_TIME (DX+XX_TIME) -#define DY_TIME (DY+YY_TIME) +#define XX_LEVEL 37 +#define YY_LEVEL 20 +#define XX_EMERALDS 29 +#define YY_EMERALDS 54 +#define XX_DYNAMITE 29 +#define YY_DYNAMITE 89 +#define XX_KEYS 18 +#define YY_KEYS 123 +#define XX_SCORE 15 +#define YY_SCORE 159 +#define XX_TIME 29 +#define YY_TIME 194 + +#define DX_LEVEL (DX+XX_LEVEL) +#define DY_LEVEL (DY+YY_LEVEL) +#define DX_EMERALDS (DX+XX_EMERALDS) +#define DY_EMERALDS (DY+YY_EMERALDS) +#define DX_DYNAMITE (DX+XX_DYNAMITE) +#define DY_DYNAMITE (DY+YY_DYNAMITE) +#define DX_KEYS (DX+XX_KEYS) +#define DY_KEYS (DY+YY_KEYS) +#define DX_SCORE (DX+XX_SCORE) +#define DY_SCORE (DY+YY_SCORE) +#define DX_TIME (DX+XX_TIME) +#define DY_TIME (DY+YY_TIME) /* Felder in PIX_DOOR */ /* Bedeutung in PIX_DB_DOOR: (3 PAGEs) diff --git a/src/misc.c b/src/misc.c index a17b1da5..61683e6c 100644 --- a/src/misc.c +++ b/src/misc.c @@ -41,31 +41,31 @@ long mainCounter(int mode) long counter_ms; gettimeofday(¤t_time,NULL); - if (mode==0 || current_time.tv_sec*counter_var+delay || actual_counter<*counter_var) + if (actual_counter >= *counter_var+delay || actual_counter < *counter_var) { *counter_var = actual_counter; return(TRUE); @@ -102,6 +102,20 @@ BOOL DelayReached(long *counter_var, int delay) return(FALSE); } +BOOL FrameReached(long *frame_counter_var, int frame_delay) +{ + long actual_frame_counter = FrameCounter; + + if (actual_frame_counter >= *frame_counter_var+frame_delay + || actual_frame_counter < *frame_counter_var) + { + *frame_counter_var = actual_frame_counter; + return(TRUE); + } + else + return(FALSE); +} + unsigned long be2long(unsigned long *be) /* big-endian -> longword */ { unsigned char *ptr = (unsigned char *)be; @@ -117,6 +131,16 @@ char *int2str(int ct, int nr) return(&str[strlen(str)-nr]); } +unsigned int SimpleRND(unsigned int max) +{ + static unsigned long root = 654321; + struct timeval current_time; + + gettimeofday(¤t_time,NULL); + root = root * 4253261 + current_time.tv_sec + current_time.tv_usec; + return(root % max); +} + unsigned int RND(unsigned int max) { return(rand() % max); @@ -171,22 +195,57 @@ void HandleAnimation(int mode) static BOOL anim_restart = TRUE; static BOOL reset_delay = TRUE; static int toon_nr = 0; + int draw_mode; +/* if (!toons_on || game_status==PLAYING) return; +*/ + +/* + if (!toons_on || tape.playing || tape.recording) + return; +*/ + + if (!toons_on) + return; switch(mode) { case ANIM_START: anim_restart = TRUE; reset_delay = TRUE; + + /* Fill empty backbuffer for animation functions */ + if (direct_draw_on && game_status==PLAYING) + { + int xx,yy; + + drawto_field = backbuffer; + + for(xx=0;xxposition==ANIMPOS_DOWN) pos_y = FULL_SYSIZE-anim->height; else if (anim->position==ANIMPOS_UPPER) - pos_y = RND((FULL_SYSIZE-anim->height)/2); + pos_y = SimpleRND((FULL_SYSIZE-anim->height)/2); else - pos_y = RND(FULL_SYSIZE-anim->height); + pos_y = SimpleRND(FULL_SYSIZE-anim->height); if (anim->direction==ANIMDIR_RIGHT) { @@ -319,7 +378,7 @@ BOOL AnimateToon(int toon_nr, BOOL restart) else if (anim->position==ANIMPOS_RIGHT) pos_x = FULL_SXSIZE-anim->width; else - pos_x = RND(FULL_SXSIZE-anim->width); + pos_x = SimpleRND(FULL_SXSIZE-anim->width); if (anim->direction==ANIMDIR_DOWN) { diff --git a/src/misc.h b/src/misc.h index dba38015..685c2b83 100644 --- a/src/misc.h +++ b/src/misc.h @@ -80,7 +80,11 @@ struct AnimInfo int position; }; -#define NEW_RANDOMIZE -1 +#define INIT_COUNTER 0 +#define READ_COUNTER_100 1 +#define READ_COUNTER_1000 2 + +#define NEW_RANDOMIZE -1 void microsleep(unsigned long); long mainCounter(int); @@ -91,8 +95,10 @@ void WaitCounter(long); void WaitCounter2(long); void Delay(long); BOOL DelayReached(long *, int); +BOOL FrameReached(long *, int); unsigned long be2long(unsigned long *); char *int2str(int, int); +unsigned int SimpleRND(unsigned int); unsigned int RND(unsigned int); unsigned int InitRND(long); char *GetLoginName(void); diff --git a/src/screens.c b/src/screens.c index f26a200b..3a8f0bb5 100644 --- a/src/screens.c +++ b/src/screens.c @@ -21,6 +21,18 @@ #include "misc.h" #include "files.h" #include "buttons.h" +#include "tape.h" + +void DrawHeadline() +{ + int x1 = SX+(SXSIZE - strlen(GAMETITLE_STRING) * FONT1_XSIZE) / 2; + int y1 = SY+8; + int x2 = SX+(SXSIZE - strlen(COPYRIGHT_STRING) * FONT2_XSIZE) / 2; + int y2 = SY+46; + + DrawText(x1,y1, GAMETITLE_STRING, FS_BIG,FC_YELLOW); + DrawText(x2,y2, COPYRIGHT_STRING, FS_SMALL,FC_RED); +} void DrawMainMenu() { @@ -31,14 +43,12 @@ void DrawMainMenu() LoadLevel(level_nr); ClearWindow(); - DrawText(SX+16, SY+8, "ROCKS'N'DIAMONDS",FS_BIG,FC_YELLOW); - DrawText(SX+25+16, SY+46, "Copyright ^1995 by Holger Schemel", - FS_SMALL,FC_RED); + DrawHeadline(); DrawText(SX+32, SY+64, "Name:",FS_BIG,FC_GREEN); DrawText(SX+192,SY+64, player.alias_name,FS_BIG,FC_RED); DrawText(SX+32, SY+96, "Level:",FS_BIG,FC_GREEN); DrawText(SX+352,SY+96, int2str(level_nr,3),FS_BIG, - (level_nr0) || - (x==15 && level_nrLEVELDIR_SIZE(leveldir[leveldir_nr])-1) - new_level_nr = LEVELDIR_SIZE(leveldir[leveldir_nr])-1; + if (new_level_nr>leveldir[leveldir_nr].levels-1) + new_level_nr = leveldir[leveldir_nr].levels-1; - if (old_level_nr==new_level_nr || !DelayReached(&level_delay,20)) + if (old_level_nr==new_level_nr || !DelayReached(&level_delay,15)) goto out; level_nr = new_level_nr; - if (level_nr>player.handicap && level_nrplayer.handicap) + level_nr = player.handicap; - DrawTextExt(drawto,gc,SX+352,SY+96, int2str(level_nr,3),FS_BIG, - (level_nr=3 && y<=10) { @@ -174,48 +182,48 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) if (num_leveldirs) { game_status = CHOOSELEVEL; + SavePlayerInfo(PLAYER_LEVEL); DrawChooseLevel(); - redraw = TRUE; } } else if (y==5) { game_status = HALLOFFAME; DrawHallOfFame(-1); - redraw = TRUE; } else if (y==6) { game_status = LEVELED; + if (leveldir[leveldir_nr].readonly) + AreYouSure("This level is read only !",AYS_CONFIRM); DrawLevelEd(); - redraw = TRUE; } else if (y==7) { game_status = HELPSCREEN; DrawHelpScreen(); - redraw = TRUE; } else if (y==8) { - if (autorecord_on && !tape.playing) - TapeInitRecording(); + if (autorecord_on) + TapeStartRecording(); game_status = PLAYING; InitGame(); - redraw = TRUE; } else if (y==9) { game_status = SETUP; DrawSetupScreen(); - redraw = TRUE; } else if (y==10) { + SavePlayerInfo(PLAYER_LEVEL); if (AreYouSure("Do you really want to quit ?",AYS_ASK|AYS_STAY_CLOSED)) game_status = EXITGAME; } + + redraw = TRUE; } } BackToFront(); @@ -249,22 +257,29 @@ static int helpscreen_action[] = GFX_CHAR_A,30,3, GFX_CHAR_AUSRUF,32,3, HA_NEXT, GFX_EDELSTEIN,2,5, HA_NEXT, GFX_DIAMANT,2,5, HA_NEXT, - GFX_EDELSTEIN2,2,5, HA_NEXT, - GFX_EDELSTEIN3,2,5, HA_NEXT, + GFX_EDELSTEIN_BD,2,5, HA_NEXT, + GFX_EDELSTEIN_GELB,2,5, GFX_EDELSTEIN_ROT,2,5, + GFX_EDELSTEIN_LILA,2,5, HA_NEXT, GFX_FELSBROCKEN,4,5, HA_NEXT, GFX_BOMBE,1,50, GFX_EXPLOSION,8,1, GFX_LEERRAUM,1,10, HA_NEXT, GFX_KOKOSNUSS,1,50, GFX_CRACKINGNUT,3,1, GFX_EDELSTEIN,1,10, HA_NEXT, GFX_ERZ_EDEL,1,50, GFX_EXPLOSION,8,1, GFX_EDELSTEIN,1,10, HA_NEXT, GFX_ERZ_DIAM,1,50, GFX_EXPLOSION,8,1, GFX_DIAMANT,1,10, HA_NEXT, - GFX_ERZ_EDEL2,1,50, GFX_EXPLOSION,8,1, GFX_EDELSTEIN2,1,10, HA_NEXT, - GFX_ERZ_EDEL3,1,50, GFX_EXPLOSION,8,1, GFX_EDELSTEIN3,1,10, HA_NEXT, + GFX_ERZ_EDEL_BD,1,50, GFX_EXPLOSION,8,1,GFX_EDELSTEIN_BD,1,10,HA_NEXT, + GFX_ERZ_EDEL_GELB,1,50, GFX_EXPLOSION,8,1, + GFX_EDELSTEIN_GELB,1,10, GFX_ERZ_EDEL_ROT,1,50, + GFX_EXPLOSION,8,1, GFX_EDELSTEIN_ROT,1,10, + GFX_ERZ_EDEL_LILA,1,50, GFX_EXPLOSION,8,1, + GFX_EDELSTEIN_LILA,1,10, HA_NEXT, GFX_GEBLUBBER,4,4, HA_NEXT, GFX_SCHLUESSEL1,4,33, HA_NEXT, GFX_PFORTE1,4,33, HA_NEXT, GFX_PFORTE1X,4,33, HA_NEXT, GFX_DYNAMIT_AUS,1,100, HA_NEXT, GFX_DYNAMIT,7,6, GFX_EXPLOSION,8,1, GFX_LEERRAUM,1,10, HA_NEXT, - GFX_DYNABOMB,1,33, GFX_EXPLOSION,8,1, GFX_LEERRAUM,1,10, HA_NEXT, + GFX_DYNABOMB+0,4,3, GFX_DYNABOMB+3,1,3, GFX_DYNABOMB+2,1,3, + GFX_DYNABOMB+1,1,3, GFX_DYNABOMB+0,1,3, GFX_EXPLOSION,8,1, + GFX_LEERRAUM,1,10, HA_NEXT, GFX_DYNABOMB_NR,1,100, HA_NEXT, GFX_DYNABOMB_SZ,1,100, HA_NEXT, GFX_FLIEGER+4,1,3, GFX_FLIEGER+0,1,3, GFX_FLIEGER+4,1,3, @@ -275,16 +290,18 @@ static int helpscreen_action[] = GFX_KAEFER+5,1,1, GFX_KAEFER+1,1,1, GFX_KAEFER+5,1,1, GFX_KAEFER+6,1,1, GFX_KAEFER+2,1,1, GFX_KAEFER+6,1,1, GFX_KAEFER+7,1,1, GFX_KAEFER+3,1,1, GFX_KAEFER+7,1,1, HA_NEXT, + GFX_BUTTERFLY,1,1, GFX_BUTTERFLY+1,1,1, HA_NEXT, + GFX_FIREFLY,1,1, GFX_FIREFLY+1,1,1, HA_NEXT, GFX_PACMAN+0,1,3, GFX_PACMAN+4,1,2, GFX_PACMAN+0,1,3, GFX_PACMAN+1,1,3, GFX_PACMAN+5,1,2, GFX_PACMAN+1,1,3, GFX_PACMAN+2,1,3, GFX_PACMAN+6,1,2, GFX_PACMAN+2,1,3, GFX_PACMAN+3,1,3, GFX_PACMAN+7,1,2, GFX_PACMAN+3,1,3, HA_NEXT, GFX_MAMPFER+0,4,0, GFX_MAMPFER+3,1,0, GFX_MAMPFER+2,1,0, - GFX_MAMPFER+1,1,0, HA_NEXT, + GFX_MAMPFER+1,1,0, GFX_MAMPFER+0,1,0, HA_NEXT, GFX_MAMPFER2+0,4,0, GFX_MAMPFER2+3,1,0, GFX_MAMPFER2+2,1,0, - GFX_MAMPFER2+1,1,0, HA_NEXT, + GFX_MAMPFER2+1,1,0, GFX_MAMPFER2+0,1,0, HA_NEXT, GFX_ZOMBIE+0,4,0, GFX_ZOMBIE+3,1,0, GFX_ZOMBIE+2,1,0, - GFX_ZOMBIE+1,1,0, HA_NEXT, + GFX_ZOMBIE+1,1,0, GFX_ZOMBIE+0,1,0, HA_NEXT, GFX_ABLENK,4,1, HA_NEXT, GFX_BIRNE_AUS,1,33, GFX_BIRNE_EIN,1,33, HA_NEXT, GFX_ZEIT_VOLL,1,33, GFX_ZEIT_LEER,1,33, HA_NEXT, @@ -307,68 +324,70 @@ static int helpscreen_action[] = }; static char *helpscreen_eltext[][2] = { - "THE HERO:", "(Is _this_ guy good old Rockford?)", - "Normal sand:", "You can dig through it", - "Empty field:", "You can walk through it", - "Quicksand: You cannot pass it,", "but rocks can fall though it", - "Massive Wall:", "Nothing can go through it", - "Normal Wall: You can't go through", "it, but you can bomb it away", - "Growing Wall: Grows to the left or", "right if there is an empty field", - "Invisible Wall: Behaves like normal","wall, but is invisible", - "Old Wall: Like normal wall, but", "some things can fall down from it", - "Letter Wall: Looks like a letter,", "behaves like a normal wall", - "Emerald: You must collect enough of","them to finish a level", - "Diamond: Counts as 3 emeralds, but", "can be destroyed by rocks", - "Diamond (BD style): Counts like one","emerald and behaves a bit different", - "Red emerald: Seems to behave like", "the BD style diamond", - "Rock: Smashes several things;", "Can be moved by the player", - "Bomb: You can move it, but be", "careful when dropping it", - "Nut: Throw a rock on it to open it;","Each nut contains an emerald", - "Wall with an emerald inside:", "Bomb the wall away to get it", - "Wall with a diamond inside:", "Bomb the wall away to get it", - "Wall with BD style diamond inside:", "Bomb the wall away to get it", - "Wall with red emerald inside:", "Bomb the wall away to get it", - "Acid: Things that fall in are gone", "forever (including our hero)", - "Key: Opens the door that has the", "same color (red/yellow/green/blue)", - "Door: Can be opened by the key", "with the same color", - "Door: You have to find out the", "right color of the key for it", - "Dynamite: Collect it and use it to", "destroy walls or kill enemies", - "Dynamite: This one explodes after", "a few seconds", - "Dyna Bomb: Explodes in 4 directions","with variable explosion size", - "Dyna Bomb: Increases the number of", "dyna bombs available at a time", - "Dyna Bomb: Increases the size of", "explosion of dyna bombs", - "Spaceship: Moves at the left side", "of walls; don't touch it!", - "Bug: Moves at the right side of", "walls; don't touch it!", - "Pacman: Eats the amoeba and you,", "if you're not careful", - "Cruncher: Eats diamonds and you,", "if you're not careful", - "Cruncher (BD style):", "Eats almost everything", - "Robot: Tries to kill the player", "", - "Magic Wheel: Touch it to get rid of","the robots for some seconds", - "Light Bulb: It seems to have no", "special function, but looks nice", - "Extra Time Orb: Adds some seconds", "to the time available for the level", - "Amoeba Drop: Grows to an amoeba on", "the ground - don't touch it", - "Dead Amoeba: Does not grow, but", "can still kill bugs and spaceships", - "Normal Amoeba: Grows through empty", "fields, sand and quicksand", - "Dropping Amoeba: This one makes", "drops that grow to a new amoeba", - "Living Amoeba (BD style): Contains", "other element, when surrounded", - "Game Of Life: Behaves like the well","known 'Game Of Life' (2333 style)", - "Biomaze: A bit like the 'Game Of", "Life', but builds crazy mazes", - "Magic Wall: Changes rocks, emeralds","and diamonds when they pass it", - "Magic Wall (BD style):", "Changes rocks and BD style diamonds", - "Exit door: Opens if you have enough","emeralds to finish the level", - "Open exit door: Enter here to leave","the level and exit the actual game", + {"THE HERO:", "(Is _this_ guy good old Rockford?)"}, + {"Normal sand:", "You can dig through it"}, + {"Empty field:", "You can walk through it"}, + {"Quicksand: You cannot pass it,", "but rocks can fall though it"}, + {"Massive Wall:", "Nothing can go through it"}, + {"Normal Wall: You can't go through", "it, but you can bomb it away"}, + {"Growing Wall: Grows to the left or", "right if there is an empty field"}, + {"Invisible Wall: Behaves like normal","wall, but is invisible"}, + {"Old Wall: Like normal wall, but", "some things can fall down from it"}, + {"Letter Wall: Looks like a letter,", "behaves like a normal wall"}, + {"Emerald: You must collect enough of","them to finish a level"}, + {"Diamond: Counts as 3 emeralds, but", "can be destroyed by rocks"}, + {"Diamond (BD style): Counts like one","emerald and behaves a bit different"}, + {"Colorful Gems:", "Seem to behave like Emeralds"}, + {"Rock: Smashes several things;", "Can be moved by the player"}, + {"Bomb: You can move it, but be", "careful when dropping it"}, + {"Nut: Throw a rock on it to open it;","Each nut contains an emerald"}, + {"Wall with an emerald inside:", "Bomb the wall away to get it"}, + {"Wall with a diamond inside:", "Bomb the wall away to get it"}, + {"Wall with BD style diamond inside:", "Bomb the wall away to get it"}, + {"Wall with colorful gem inside:", "Bomb the wall away to get it"}, + {"Acid: Things that fall in are gone", "forever (including our hero)"}, + {"Key: Opens the door that has the", "same color (red/yellow/green/blue)"}, + {"Door: Can be opened by the key", "with the same color"}, + {"Door: You have to find out the", "right color of the key for it"}, + {"Dynamite: Collect it and use it to", "destroy walls or kill enemies"}, + {"Dynamite: This one explodes after", "a few seconds"}, + {"Dyna Bomb: Explodes in 4 directions","with variable explosion size"}, + {"Dyna Bomb: Increases the number of", "dyna bombs available at a time"}, + {"Dyna Bomb: Increases the size of", "explosion of dyna bombs"}, + {"Spaceship: Moves at the left side", "of walls; don't touch it!"}, + {"Bug: Moves at the right side", "of walls; don't touch it!"}, + {"Butterfly: Moves at the right side", "of walls; don't touch it!"}, + {"Firefly: Moves at the left side", "of walls; don't touch it!"}, + {"Pacman: Eats the amoeba and you,", "if you're not careful"}, + {"Cruncher: Eats diamonds and you,", "if you're not careful"}, + {"Cruncher (BD style):", "Eats almost everything"}, + {"Robot: Tries to kill the player", ""}, + {"Magic Wheel: Touch it to get rid of","the robots for some seconds"}, + {"Light Bulb: All of them must be", "switched on to finish a level"}, + {"Extra Time Orb: Adds some seconds", "to the time available for the level"}, + {"Amoeba Drop: Grows to an amoeba on", "the ground - don't touch it"}, + {"Dead Amoeba: Does not grow, but", "can still kill bugs and spaceships"}, + {"Normal Amoeba: Grows through empty", "fields, sand and quicksand"}, + {"Dropping Amoeba: This one makes", "drops that grow to a new amoeba"}, + {"Living Amoeba (BD style): Contains", "other element, when surrounded"}, + {"Game Of Life: Behaves like the well","known 'Game Of Life' (2333 style)"}, + {"Biomaze: A bit like the 'Game Of", "Life', but builds crazy mazes"}, + {"Magic Wall: Changes rocks, emeralds","and diamonds when they pass it"}, + {"Magic Wall (BD style):", "Changes rocks and BD style diamonds"}, + {"Exit door: Opens if you have enough","emeralds to finish the level"}, + {"Open exit door: Enter here to leave","the level and exit the actual game"}, }; static int num_helpscreen_els = sizeof(helpscreen_eltext)/(2*sizeof(char *)); static char *helpscreen_music[][3] = { - "Alchemy", "Ian Boddy", "Drive", - "The Chase", "Propaganda", "A Secret Wish", - "Network 23", "Tangerine Dream", "Exit", - "Czardasz", "Robert Pieculewicz", "Czardasz", - "21st Century Common Man", "Tangerine Dream", "Tyger", - "Voyager", "The Alan Parsons Project","Pyramid", - "Twilight Painter", "Tangerine Dream", "Heartbreakers" + { "Alchemy", "Ian Boddy", "Drive" }, + { "The Chase", "Propaganda", "A Secret Wish" }, + { "Network 23", "Tangerine Dream", "Exit" }, + { "Czardasz", "Robert Pieculewicz", "Czardasz" }, + { "21st Century Common Man", "Tangerine Dream", "Tyger" }, + { "Voyager", "The Alan Parsons Project","Pyramid" }, + { "Twilight Painter", "Tangerine Dream", "Heartbreakers" } }; static int helpscreen_musicpos; @@ -443,9 +462,7 @@ void DrawHelpScreenElText(int start) char text[FULL_SXSIZE/FONT2_XSIZE+10]; ClearWindow(); - DrawText(SX+16, SY+8, "ROCKS'N'DIAMONDS",FS_BIG,FC_YELLOW); - DrawText(SX+25+16, SY+46, "Copyright ^1995 by Holger Schemel", - FS_SMALL,FC_RED); + DrawHeadline(); sprintf(text,"The game elements:"); DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+100, @@ -471,9 +488,7 @@ void DrawHelpScreenMusicText(int num) FadeSounds(); ClearWindow(); - DrawText(SX+16, SY+8, "ROCKS'N'DIAMONDS",FS_BIG,FC_YELLOW); - DrawText(SX+25+16, SY+46, "Copyright ^1995 by Holger Schemel", - FS_SMALL,FC_RED); + DrawHeadline(); sprintf(text,"The game background music loops:"); DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+100, @@ -512,9 +527,7 @@ void DrawHelpScreenCreditsText() FadeSounds(); ClearWindow(); - DrawText(SX+16, SY+8, "ROCKS'N'DIAMONDS",FS_BIG,FC_YELLOW); - DrawText(SX+25+16, SY+46, "Copyright ^1995 by Holger Schemel", - FS_SMALL,FC_RED); + DrawHeadline(); sprintf(text,"Program information:"); DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+100, @@ -631,7 +644,7 @@ void CheckCheat() int old_handicap = player.handicap; if (!strcmp(player.alias_name,"Artsoft")) - player.handicap = MAX(0,leveldir[leveldir_nr].num_ready-1); + player.handicap = leveldir[leveldir_nr].levels-1; if (player.handicap != old_handicap) { @@ -671,8 +684,8 @@ void HandleTypeName(int newxpos, KeySym key) } else if (key==XK_Delete && xpos>0) { - player.alias_name[xpos] = 0; xpos--; + player.alias_name[xpos] = 0; DrawGraphic(xpos+6,ypos,GFX_KUGEL_ROT); DrawGraphic(xpos+7,ypos,GFX_LEERRAUM); } @@ -684,7 +697,10 @@ void HandleTypeName(int newxpos, KeySym key) CheckCheat(); game_status = MAINMENU; +/* DrawMainMenu(); +*/ + } BackToFront(); } @@ -760,6 +776,9 @@ void HandleChooseLevel(int mx, int my, int dx, int dy, int button) SavePlayerInfo(PLAYER_SETUP); CheckCheat(); + TapeErase(); + LoadLevelTape(level_nr); + game_status = MAINMENU; DrawMainMenu(); redraw = TRUE; @@ -818,73 +837,51 @@ void HandleHallOfFame(int button) void DrawSetupScreen() { int i; + static struct setup + { + unsigned int bit; + char *text, *mode[2]; + int color[2]; + } setup[] = + { + {SETUP_SOUND, "Sound:", {"on", "off"}, {FC_YELLOW,FC_BLUE}}, + {SETUP_SOUND_LOOPS, " Sound Loops:",{"on", "off"}, {FC_YELLOW,FC_BLUE}}, + {SETUP_SOUND_MUSIC, " Game Music:", {"on", "off"}, {FC_YELLOW,FC_BLUE}}, + {SETUP_TOONS, "Toons:", {"on", "off"}, {FC_YELLOW,FC_BLUE}}, + {SETUP_DIRECT_DRAW, "Buffered gfx:",{"off","on" }, {FC_BLUE,FC_YELLOW}}, + {SETUP_SCROLL_DELAY,"Scroll Delay:",{"on", "off"}, {FC_YELLOW,FC_BLUE}}, + {SETUP_FADING, "Fading:", {"on", "off"}, {FC_YELLOW,FC_BLUE}}, + {SETUP_QUICK_DOORS, "Quick Doors:", {"on", "off"}, {FC_YELLOW,FC_BLUE}}, + {SETUP_AUTO_RECORD, "Auto-Record:", {"on", "off"}, {FC_YELLOW,FC_BLUE}}, + {SETUP_2ND_JOYSTICK,"Joystick:", {"2nd","1st"}, {FC_YELLOW,FC_YELLOW}}, + {0, "Cal. Joystick",{"", ""}, {0,0}}, + {0, "", {"", ""}, {0,0}}, + {0, "Exit", {"", ""}, {0,0}}, + {0, "Save and exit",{"", ""}, {0,0}} + }; CloseDoor(DOOR_CLOSE_2); - ClearWindow(); DrawText(SX+16, SY+16, "SETUP",FS_BIG,FC_YELLOW); - DrawText(SX+32, SY+2*32,"Sound:",FS_BIG,FC_GREEN); - DrawText(SX+32, SY+3*32,"Sound loops:",FS_BIG,FC_GREEN); - DrawText(SX+32, SY+4*32,"Game music:",FS_BIG,FC_GREEN); - DrawText(SX+32, SY+5*32,"Toons:",FS_BIG,FC_GREEN); - DrawText(SX+32, SY+6*32,"Buffered gfx:",FS_BIG,FC_GREEN); - DrawText(SX+32, SY+7*32,"Fading:",FS_BIG,FC_GREEN); - DrawText(SX+32, SY+8*32,"Quick Doors:",FS_BIG,FC_GREEN); - DrawText(SX+32, SY+9*32,"Auto-Record:",FS_BIG,FC_GREEN); - DrawText(SX+32, SY+10*32,"Joystick:",FS_BIG,FC_GREEN); - DrawText(SX+32, SY+11*32,"Cal. Joystick",FS_BIG,FC_GREEN); - - DrawText(SX+32, SY+13*32,"Exit",FS_BIG,FC_GREEN); - DrawText(SX+32, SY+14*32,"Save and exit",FS_BIG,FC_GREEN); - - if (SETUP_SOUND_ON(player.setup)) - DrawText(SX+14*32, SY+2*32,"on",FS_BIG,FC_YELLOW); - else - DrawText(SX+14*32, SY+2*32,"off",FS_BIG,FC_BLUE); - - if (SETUP_SOUND_LOOPS_ON(player.setup)) - DrawText(SX+14*32, SY+3*32,"on",FS_BIG,FC_YELLOW); - else - DrawText(SX+14*32, SY+3*32,"off",FS_BIG,FC_BLUE); - - if (SETUP_SOUND_MUSIC_ON(player.setup)) - DrawText(SX+14*32, SY+4*32,"on",FS_BIG,FC_YELLOW); - else - DrawText(SX+14*32, SY+4*32,"off",FS_BIG,FC_BLUE); - if (SETUP_TOONS_ON(player.setup)) - DrawText(SX+14*32, SY+5*32,"on",FS_BIG,FC_YELLOW); - else - DrawText(SX+14*32, SY+5*32,"off",FS_BIG,FC_BLUE); - - if (!SETUP_DIRECT_DRAW_ON(player.setup)) - DrawText(SX+14*32, SY+6*32,"on",FS_BIG,FC_YELLOW); - else - DrawText(SX+14*32, SY+6*32,"off",FS_BIG,FC_BLUE); - - if (SETUP_FADING_ON(player.setup)) - DrawText(SX+14*32, SY+7*32,"on",FS_BIG,FC_YELLOW); - else - DrawText(SX+14*32, SY+7*32,"off",FS_BIG,FC_BLUE); - - if (SETUP_QUICK_DOORS_ON(player.setup)) - DrawText(SX+14*32, SY+8*32,"on",FS_BIG,FC_YELLOW); - else - DrawText(SX+14*32, SY+8*32,"off",FS_BIG,FC_BLUE); - - if (SETUP_RECORD_EACH_GAME_ON(player.setup)) - DrawText(SX+14*32, SY+9*32,"on",FS_BIG,FC_YELLOW); - else - DrawText(SX+14*32, SY+9*32,"off",FS_BIG,FC_BLUE); - - if (SETUP_2ND_JOYSTICK_ON(player.setup)) - DrawText(SX+14*32, SY+10*32,"2nd",FS_BIG,FC_YELLOW); - else - DrawText(SX+14*32, SY+10*32,"1st",FS_BIG,FC_YELLOW); + for(i=SETUP_SCREEN_POS_START;i<=SETUP_SCREEN_POS_END;i++) + { + int base = i - SETUP_SCREEN_POS_START; - for(i=2;i<15;i++) - if (i!=12) + if (i != SETUP_SCREEN_POS_EMPTY) + { DrawGraphic(0,i,GFX_KUGEL_BLAU); + DrawText(SX+32,SY+i*32, setup[base].text, FS_BIG,FC_GREEN); + } + + if (i < SETUP_SCREEN_POS_EMPTY) + { + int setting_bit = setup[base].bit; + int setting_pos = ((player.setup & setting_bit) != 0 ? 0 : 1); + DrawText(SX+14*32, SY+i*32,setup[base].mode[setting_pos], + FS_BIG,setup[base].color[setting_pos]); + } + } FadeToFront(); InitAnimation(); @@ -896,6 +893,9 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button) static int choice = 3; static int redraw = TRUE; int x = (mx+32-SX)/32, y = (my+32-SY)/32; + int pos_start = SETUP_SCREEN_POS_START + 1; + int pos_empty = SETUP_SCREEN_POS_EMPTY + 1; + int pos_end = SETUP_SCREEN_POS_END + 1; if (redraw) { @@ -913,13 +913,13 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button) else x = y = 0; - if (y==13) - y = (dy>0 ? 14 : 12); + if (y == pos_empty) + y = (dy>0 ? pos_empty+1 : pos_empty-1); - if (y<3) - y = 3; - else if (y>15) - y = 15; + if (y < pos_start) + y = pos_start; + else if (y > pos_end) + y = pos_end; } if (!mx && !my && !dx && !dy) @@ -928,7 +928,7 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button) y = choice; } - if (x==1 && y>=3 && y<=15 && y!=13) + if (x==1 && y>=pos_start && y<=pos_end && y!=pos_empty) { if (button) { @@ -946,7 +946,13 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button) if (y==3 && sound_status==SOUND_AVAILABLE) { if (SETUP_SOUND_ON(player.setup)) + { DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE); + DrawText(SX+14*32, SY+(yy+1)*32,"off",FS_BIG,FC_BLUE); + DrawText(SX+14*32, SY+(yy+2)*32,"off",FS_BIG,FC_BLUE); + player.setup &= ~SETUP_SOUND_LOOPS; + player.setup &= ~SETUP_SOUND_MUSIC; + } else DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW); player.setup ^= SETUP_SOUND; @@ -956,7 +962,11 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button) if (SETUP_SOUND_LOOPS_ON(player.setup)) DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE); else + { DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW); + DrawText(SX+14*32, SY+(yy-1)*32,"on ",FS_BIG,FC_YELLOW); + player.setup |= SETUP_SOUND; + } player.setup ^= SETUP_SOUND_LOOPS; } else if (y==5 && sound_loops_allowed) @@ -964,7 +974,11 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button) if (SETUP_SOUND_MUSIC_ON(player.setup)) DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE); else + { DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW); + DrawText(SX+14*32, SY+(yy-2)*32,"on ",FS_BIG,FC_YELLOW); + player.setup |= SETUP_SOUND; + } player.setup ^= SETUP_SOUND_MUSIC; } else if (y==6) @@ -984,6 +998,14 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button) player.setup ^= SETUP_DIRECT_DRAW; } else if (y==8) + { + if (SETUP_SCROLL_DELAY_ON(player.setup)) + DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE); + else + DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW); + player.setup ^= SETUP_SCROLL_DELAY; + } + else if (y==9) { if (SETUP_FADING_ON(player.setup)) DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE); @@ -991,7 +1013,7 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button) DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW); player.setup ^= SETUP_FADING; } - else if (y==9) + else if (y==10) { if (SETUP_QUICK_DOORS_ON(player.setup)) DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE); @@ -999,15 +1021,15 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button) DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW); player.setup ^= SETUP_QUICK_DOORS; } - else if (y==10) + else if (y==11) { - if (SETUP_RECORD_EACH_GAME_ON(player.setup)) + if (SETUP_AUTO_RECORD_ON(player.setup)) DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE); else DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW); - player.setup ^= SETUP_RECORD_EACH_GAME; + player.setup ^= SETUP_AUTO_RECORD; } - else if (y==11) + else if (y==12) { if (SETUP_2ND_JOYSTICK_ON(player.setup)) DrawText(SX+14*32, SY+yy*32,"1st",FS_BIG,FC_YELLOW); @@ -1015,14 +1037,14 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button) DrawText(SX+14*32, SY+yy*32,"2nd",FS_BIG,FC_YELLOW); player.setup ^= SETUP_2ND_JOYSTICK; } - else if (y==12) + else if (y==13) { CalibrateJoystick(); redraw = TRUE; } - else if (y==14 || y==15) + else if (y==pos_end-1 || y==pos_end) { - if (y==15) + if (y==pos_end) { SavePlayerInfo(PLAYER_SETUP); SaveJoystickData(); @@ -1167,19 +1189,41 @@ void CalibrateJoystick() DrawSetupScreen(); } +void HandleGameActions() +{ + if (game_status != PLAYING) + return; + + if (LevelSolved) + GameWon(); + + if (GameOver && !TAPE_IS_STOPPED(tape)) + TapeStop(); + + GameActions(); +} + void HandleVideoButtons(int mx, int my, int button) { - if (game_status!=MAINMENU && game_status!=PLAYING) + if (game_status != MAINMENU && game_status != PLAYING) return; switch(CheckVideoButtons(mx,my,button)) { case BUTTON_VIDEO_EJECT: TapeStop(); - if (!TAPE_IS_EMPTY(tape)) - SaveLevelTape(tape.level_nr); + if (TAPE_IS_EMPTY(tape)) + { + LoadLevelTape(level_nr); + if (TAPE_IS_EMPTY(tape)) + AreYouSure("No tape for this level !",AYS_CONFIRM); + } else - AreYouSure("Tape is empty !",AYS_CONFIRM); + { + if (tape.changed) + SaveLevelTape(tape.level_nr); + TapeErase(); + } DrawCompleteVideoDisplay(); break; case BUTTON_VIDEO_STOP: @@ -1189,25 +1233,68 @@ void HandleVideoButtons(int mx, int my, int button) TapeTogglePause(); break; case BUTTON_VIDEO_REC: - if (tape.pausing) - TapeTogglePause(); - else if (game_status==MAINMENU) - TapeInitRecording(); + if (TAPE_IS_STOPPED(tape)) + { + TapeStartRecording(); + game_status = PLAYING; + InitGame(); + } + else if (tape.pausing) + { + if (tape.playing) /* PLAYING -> PAUSING -> RECORDING */ + { + tape.pos[tape.counter].delay = tape.delay_played; + tape.playing = FALSE; + tape.recording = TRUE; + + DrawVideoDisplay(VIDEO_STATE_PLAY_OFF | VIDEO_STATE_REC_ON,0); + } + else + TapeTogglePause(); + } break; case BUTTON_VIDEO_PLAY: - if (tape.pausing) - TapeTogglePause(); - else if (game_status==MAINMENU) - TapeInitPlaying(); + if (TAPE_IS_EMPTY(tape)) + break; + + if (TAPE_IS_STOPPED(tape)) + { + TapeStartPlaying(); + game_status = PLAYING; + InitGame(); + } + else if (tape.playing) + { + if (tape.pausing) /* PAUSE -> PLAY */ + TapeTogglePause(); + else if (!tape.fast_forward) /* PLAY -> FAST FORWARD PLAY */ + { + tape.fast_forward = TRUE; + DrawVideoDisplay(VIDEO_STATE_FFWD_ON, 0); + } + else if (!tape.pause_before_death) /* FFWD PLAY -> + AUTO PAUSE */ + { + tape.pause_before_death = TRUE; + DrawVideoDisplay(VIDEO_STATE_PAUSE_ON, VIDEO_DISPLAY_LABEL_ONLY); + } + else /* -> NORMAL PLAY */ + { + tape.fast_forward = FALSE; + tape.pause_before_death = FALSE; + DrawVideoDisplay(VIDEO_STATE_FFWD_OFF | VIDEO_STATE_PAUSE_OFF, 0); + } + } break; default: break; } + + BackToFront(); } void HandleSoundButtons(int mx, int my, int button) { - if (game_status!=PLAYING) + if (game_status != PLAYING) return; switch(CheckSoundButtons(mx,my,button)) @@ -1222,8 +1309,8 @@ void HandleSoundButtons(int mx, int my, int button) } else if (sound_loops_allowed) { - sound_music_on = TRUE; - player.setup |= SETUP_SOUND_MUSIC; + sound_on = sound_music_on = TRUE; + player.setup |= (SETUP_SOUND | SETUP_SOUND_MUSIC); PlaySoundLoop(background_loop[level_nr % num_bg_loops]); DrawSoundDisplay(BUTTON_SOUND_MUSIC_ON); } @@ -1239,42 +1326,52 @@ void HandleSoundButtons(int mx, int my, int button) } else if (sound_loops_allowed) { - sound_loops_on = TRUE; - player.setup |= SETUP_SOUND_LOOPS; + sound_on = sound_loops_on = TRUE; + player.setup |= (SETUP_SOUND | SETUP_SOUND_LOOPS); DrawSoundDisplay(BUTTON_SOUND_LOOPS_ON); } else DrawSoundDisplay(BUTTON_SOUND_LOOPS_OFF); break; - case BUTTON_SOUND_SOUND: - if (sound_on) + case BUTTON_SOUND_SIMPLE: + if (sound_simple_on) { - sound_on = FALSE; + sound_simple_on = FALSE; player.setup &= ~SETUP_SOUND; - DrawSoundDisplay(BUTTON_SOUND_SOUND_OFF); + DrawSoundDisplay(BUTTON_SOUND_SIMPLE_OFF); } else if (sound_status==SOUND_AVAILABLE) { - sound_on = TRUE; + sound_on = sound_simple_on = TRUE; player.setup |= SETUP_SOUND; - DrawSoundDisplay(BUTTON_SOUND_SOUND_ON); + DrawSoundDisplay(BUTTON_SOUND_SIMPLE_ON); } else - DrawSoundDisplay(BUTTON_SOUND_SOUND_OFF); + DrawSoundDisplay(BUTTON_SOUND_SIMPLE_OFF); break; default: break; } + + BackToFront(); } void HandleGameButtons(int mx, int my, int button) { - if (game_status!=PLAYING) + if (game_status != PLAYING) return; switch(CheckGameButtons(mx,my,button)) { case BUTTON_GAME_STOP: + if (GameOver) + { + CloseDoor(DOOR_CLOSE_1); + game_status = MAINMENU; + DrawMainMenu(); + break; + } + if (AreYouSure("Do you really want to quit the game ?", AYS_ASK | AYS_STAY_CLOSED)) { @@ -1306,4 +1403,6 @@ void HandleGameButtons(int mx, int my, int button) default: break; } + + BackToFront(); } diff --git a/src/screens.h b/src/screens.h index 32a58401..a9c5f72e 100644 --- a/src/screens.h +++ b/src/screens.h @@ -17,22 +17,28 @@ #include "main.h" -void DrawMainMenu(); +#define SETUP_SCREEN_POS_START 2 +#define SETUP_SCREEN_POS_END 15 +#define SETUP_SCREEN_POS_EMPTY (SETUP_SCREEN_POS_END - 2) + +void DrawHeadline(void); +void DrawMainMenu(void); void HandleMainMenu(int, int, int, int, int); void DrawHelpScreenElAction(int); void DrawHelpScreenElText(int); void DrawHelpScreenMusicText(int); void DrawHelpScreenCreditsText(void); -void DrawHelpScreen(); +void DrawHelpScreen(void); void HandleHelpScreen(int); void HandleTypeName(int, KeySym); void DrawChooseLevel(void); void HandleChooseLevel(int, int, int, int, int); void DrawHallOfFame(int); void HandleHallOfFame(int); -void DrawSetupScreen(); +void DrawSetupScreen(void); void HandleSetupScreen(int, int, int, int, int); void CalibrateJoystick(void); +void HandleGameActions(void); void HandleVideoButtons(int, int, int); void HandleSoundButtons(int, int, int); void HandleGameButtons(int, int, int); diff --git a/src/tape.c b/src/tape.c new file mode 100644 index 00000000..35929e88 --- /dev/null +++ b/src/tape.c @@ -0,0 +1,230 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* ©1997 Artsoft Development * +* Holger Schemel * +* 33604 Bielefeld * +* Telefon: (0521) 290471 * +* eMail: aeglos@valinor.owl.de * +* aeglos@uni-paderborn.de * +*----------------------------------------------------------* +* tape.c * +***********************************************************/ + +#include "tape.h" +#include "misc.h" +#include "game.h" +#include "buttons.h" + +void TapeStartRecording() +{ + time_t zeit1 = time(NULL); + struct tm *zeit2 = localtime(&zeit1); + + if (!TAPE_IS_STOPPED(tape)) + TapeStop(); + + tape.level_nr = level_nr; + tape.length = 0; + tape.counter = 0; + tape.pos[tape.counter].delay = 0; + tape.changed = TRUE; + tape.recording = TRUE; + tape.playing = FALSE; + tape.pausing = FALSE; + tape.date = 10000*(zeit2->tm_year%100) + 100*zeit2->tm_mon + zeit2->tm_mday; + tape.random_seed = InitRND(NEW_RANDOMIZE); + + DrawVideoDisplay(VIDEO_STATE_REC_ON,0); + DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date); + DrawVideoDisplay(VIDEO_STATE_TIME_ON,0); +} + +void TapeStopRecording() +{ + if (!tape.recording) + return; + + tape.pos[tape.counter].joystickdata = 0; + tape.counter++; + tape.length = tape.counter; + tape.length_seconds = GetTapeLength(); + tape.recording = FALSE; + tape.pausing = FALSE; + DrawVideoDisplay(VIDEO_STATE_REC_OFF,0); +} + +void TapeRecordAction(int joy) +{ + if (!tape.recording || tape.pausing) + return; + + if (tape.counter>=MAX_TAPELEN-1) + { + TapeStopRecording(); + return; + } + + if (joy) + { + tape.pos[tape.counter].joystickdata = joy; + tape.counter++; + tape.pos[tape.counter].delay = 0; + } +} + +void TapeRecordDelay() +{ + if (!tape.recording || tape.pausing) + return; + + if (tape.counter>=MAX_TAPELEN) + { + TapeStopRecording(); + return; + } + + tape.pos[tape.counter].delay++; + + if (tape.pos[tape.counter].delay>=255) + { + tape.pos[tape.counter].joystickdata = 0; + tape.counter++; + tape.pos[tape.counter].delay = 0; + } +} + +void TapeTogglePause() +{ + if (!tape.recording && !tape.playing) + return; + + tape.pausing = !tape.pausing; + tape.fast_forward = FALSE; + tape.pause_before_death = FALSE; + DrawVideoDisplay(tape.pausing ? + VIDEO_STATE_PAUSE_ON : + VIDEO_STATE_PAUSE_OFF,0); +} + +void TapeStartPlaying() +{ + if (TAPE_IS_EMPTY(tape)) + return; + + if (!TAPE_IS_STOPPED(tape)) + TapeStop(); + + tape.counter = 0; + tape.delay_played = 0; + tape.pause_before_death = FALSE; + tape.recording = FALSE; + tape.playing = TRUE; + tape.pausing = FALSE; + tape.fast_forward = FALSE; + InitRND(tape.random_seed); + + DrawVideoDisplay(VIDEO_STATE_PLAY_ON,0); + DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date); + DrawVideoDisplay(VIDEO_STATE_TIME_ON,0); +} + +void TapeStopPlaying() +{ + if (!tape.playing) + return; + + tape.playing = FALSE; + tape.pausing = FALSE; + DrawVideoDisplay(VIDEO_STATE_PLAY_OFF,0); +} + +int TapePlayAction() +{ + if (!tape.playing || tape.pausing) + return(0); + + if (tape.counter>=tape.length) + { + TapeStopPlaying(); + return(0); + } + + if (tape.delay_played == tape.pos[tape.counter].delay) + { + tape.delay_played = 0; + tape.counter++; + return(tape.pos[tape.counter-1].joystickdata); + } + else + return(0); +} + +BOOL TapePlayDelay() +{ + if (!tape.playing || tape.pausing) + return(FALSE); + + if (tape.pause_before_death) /* STOP 10s BEFORE PLAYER GETS KILLED... */ + { + if (!(FrameCounter % 5)) + { + if (2*(FrameCounter/10) == FrameCounter/5) + DrawVideoDisplay(VIDEO_STATE_PAUSE_ON, VIDEO_DISPLAY_LABEL_ONLY); + else + DrawVideoDisplay(VIDEO_STATE_PAUSE_OFF, VIDEO_DISPLAY_LABEL_ONLY); + } + + if (level.time-TimeLeft > tape.length_seconds - PAUSE_SECONDS_BEFORE_DEATH) + { + TapeTogglePause(); + return(FALSE); + } + } + + if (tape.counter>=tape.length) + { + TapeStopPlaying(); + return(TRUE); + } + + if (tape.delay_played < tape.pos[tape.counter].delay) + { + tape.delay_played++; + return(TRUE); + } + else + return(FALSE); +} + +void TapeStop() +{ + TapeStopRecording(); + TapeStopPlaying(); + + DrawVideoDisplay(VIDEO_STATE_PAUSE_OFF,0); + if (tape.date && tape.length) + { + DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date); + DrawVideoDisplay(VIDEO_STATE_TIME_ON,tape.length_seconds); + } +} + +void TapeErase() +{ + tape.length = 0; +} + +unsigned int GetTapeLength() +{ + unsigned int tape_length = 0; + int i; + + if (TAPE_IS_EMPTY(tape)) + return(0); + + for(i=0;ix; @@ -955,7 +986,6 @@ BOOL AreYouSure(char *text, unsigned int ays_state) break; } case KeyPress: - key_status = KEY_PRESSED; switch(XLookupKeysym((XKeyEvent *)&event, ((XKeyEvent *)&event)->state)) { @@ -977,7 +1007,7 @@ BOOL AreYouSure(char *text, unsigned int ays_state) break; } } - else if (JoystickButton()==JOY_BUTTON_NEW_PRESSED) + else if (JoystickButton() == JOY_BUTTON_NEW_PRESSED) { int joy=Joystick(); @@ -988,15 +1018,14 @@ BOOL AreYouSure(char *text, unsigned int ays_state) } } - if (game_status!=MAINMENU) + if (game_status != MAINMENU) StopAnimation(); if (!(ays_state & AYS_STAY_OPEN)) { CloseDoor(DOOR_CLOSE_1); - if (!(ays_state & AYS_STAY_CLOSED) && - (game_status==PLAYING || game_status==LEVELED)) + if (!(ays_state & AYS_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1)) { XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc, DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE, @@ -1008,8 +1037,10 @@ BOOL AreYouSure(char *text, unsigned int ays_state) return(result); } -void OpenDoor(unsigned int door_state) +unsigned int OpenDoor(unsigned int door_state) { + unsigned int new_door_state; + if (door_state & DOOR_COPY_BACK) { XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc, @@ -1018,27 +1049,47 @@ void OpenDoor(unsigned int door_state) door_state &= ~DOOR_COPY_BACK; } - MoveDoor(door_state); + new_door_state = MoveDoor(door_state); + +/* ClearEventQueue(); +*/ + + return(new_door_state); } -void CloseDoor(unsigned int door_state) +unsigned int CloseDoor(unsigned int door_state) { + unsigned int new_door_state; + XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc, DX,DY, DXSIZE,DYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1); XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc, VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2); - MoveDoor(door_state); + new_door_state = MoveDoor(door_state); + +/* ClearEventQueue(); +*/ + + return(new_door_state); } -void MoveDoor(unsigned int door_state) +unsigned int GetDoorState() { - static int door1 = DOOR_OPEN_1; - static int door2 = DOOR_CLOSE_2; + return(MoveDoor(DOOR_GET_STATE)); +} + +unsigned int MoveDoor(unsigned int door_state) +{ + static unsigned int door1 = DOOR_OPEN_1; + static unsigned int door2 = DOOR_CLOSE_2; int x, start, stepsize = 4, door_anim_delay = stepsize*5000; + if (door_state == DOOR_GET_STATE) + return(door1 | door2); + if (door1==DOOR_OPEN_1 && door_state & DOOR_OPEN_1) door_state &= ~DOOR_OPEN_1; else if (door1==DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1) @@ -1150,6 +1201,8 @@ void MoveDoor(unsigned int door_state) door1 = door_state & DOOR_ACTION_1; if (door_state & DOOR_ACTION_2) door2 = door_state & DOOR_ACTION_2; + + return(door1 | door2); } int ReadPixel(Drawable d, int x, int y) @@ -1320,6 +1373,16 @@ int el2gfx(int element) case EL_FLIEGER_O: return(GFX_FLIEGER_O); case EL_FLIEGER_L: return(GFX_FLIEGER_L); case EL_FLIEGER_U: return(GFX_FLIEGER_U); + case EL_BUTTERFLY: return(GFX_BUTTERFLY); + case EL_BUTTERFLY_R: return(GFX_BUTTERFLY_R); + case EL_BUTTERFLY_O: return(GFX_BUTTERFLY_O); + case EL_BUTTERFLY_L: return(GFX_BUTTERFLY_L); + case EL_BUTTERFLY_U: return(GFX_BUTTERFLY_U); + case EL_FIREFLY: return(GFX_FIREFLY); + case EL_FIREFLY_R: return(GFX_FIREFLY_R); + case EL_FIREFLY_O: return(GFX_FIREFLY_O); + case EL_FIREFLY_L: return(GFX_FIREFLY_L); + case EL_FIREFLY_U: return(GFX_FIREFLY_U); case EL_MAMPFER: return(GFX_MAMPFER); case EL_ZOMBIE: return(GFX_ZOMBIE); case EL_BETON: return(GFX_BETON); @@ -1336,6 +1399,7 @@ int el2gfx(int element) case EL_AMOEBE_NASS: return(GFX_AMOEBE_NASS); case EL_AMOEBE_NORM: return(GFX_AMOEBE_NORM); case EL_AMOEBE_VOLL: return(GFX_AMOEBE_VOLL); + case EL_AMOEBE_BD: return(GFX_AMOEBE_BD); case EL_AMOEBA2DIAM: return(GFX_AMOEBA2DIAM); case EL_KOKOSNUSS: return(GFX_KOKOSNUSS); case EL_LIFE: return(GFX_LIFE); @@ -1375,10 +1439,14 @@ int el2gfx(int element) case EL_ZEIT_VOLL: return(GFX_ZEIT_VOLL); case EL_ZEIT_LEER: return(GFX_ZEIT_LEER); case EL_MAUER_LEBT: return(GFX_MAUER_LEBT); - case EL_EDELSTEIN2: return(GFX_EDELSTEIN2); - case EL_EDELSTEIN3: return(GFX_EDELSTEIN3); - case EL_ERZ_EDEL2: return(GFX_ERZ_EDEL2); - case EL_ERZ_EDEL3: return(GFX_ERZ_EDEL3); + case EL_EDELSTEIN_BD: return(GFX_EDELSTEIN_BD); + case EL_EDELSTEIN_GELB: return(GFX_EDELSTEIN_GELB); + case EL_EDELSTEIN_ROT: return(GFX_EDELSTEIN_ROT); + case EL_EDELSTEIN_LILA: return(GFX_EDELSTEIN_LILA); + case EL_ERZ_EDEL_BD: return(GFX_ERZ_EDEL_BD); + case EL_ERZ_EDEL_GELB: return(GFX_ERZ_EDEL_GELB); + case EL_ERZ_EDEL_ROT: return(GFX_ERZ_EDEL_ROT); + case EL_ERZ_EDEL_LILA: return(GFX_ERZ_EDEL_LILA); case EL_MAMPFER2: return(GFX_MAMPFER2); case EL_SIEB2_LEER: return(GFX_SIEB2_LEER); case EL_SIEB2_VOLL: return(GFX_SIEB2_VOLL); @@ -1386,6 +1454,10 @@ int el2gfx(int element) case EL_DYNABOMB: return(GFX_DYNABOMB); case EL_DYNABOMB_NR: return(GFX_DYNABOMB_NR); case EL_DYNABOMB_SZ: return(GFX_DYNABOMB_SZ); + case EL_DYNABOMB_XL: return(GFX_DYNABOMB_XL); + case EL_SOKOBAN_OBJEKT: return(GFX_SOKOBAN_OBJEKT); + case EL_SOKOBAN_FELD_LEER: return(GFX_SOKOBAN_FELD_LEER); + case EL_SOKOBAN_FELD_VOLL: return(GFX_SOKOBAN_FELD_VOLL); default: { if (IS_CHAR(element)) diff --git a/src/tools.h b/src/tools.h index bec22056..ce4ab0f2 100644 --- a/src/tools.h +++ b/src/tools.h @@ -19,6 +19,10 @@ #include +/* für DrawGraphicAnimation */ +#define ANIM_NORMAL 0 +#define ANIM_OSCILLATE 1 + /* für DrawElementShifted */ #define CUT_NO_CUTTING 0 #define CUT_ABOVE 1 @@ -38,6 +42,7 @@ #define DOOR_ACTION (DOOR_ACTION_1 | DOOR_ACTION_2) #define DOOR_COPY_BACK 16 #define DOOR_NO_DELAY 32 +#define DOOR_GET_STATE 64 /* für AreYouSure */ #define AYS_ASK 1 @@ -52,6 +57,7 @@ void FadeToFront(); void ClearWindow(); void DrawText(int, int, char *, int, int); void DrawTextExt(Drawable, GC, int, int, char *, int, int); +void DrawGraphicAnimation(int, int, int, int, int, int); void DrawGraphic(int, int, int); void DrawGraphicExt(Drawable, GC, int, int, int); void DrawGraphicExtHiRes(Drawable, GC, int, int, int); @@ -74,9 +80,10 @@ void DrawLevel(void); void DrawMiniLevel(int, int); void DrawMicroLevel(int, int); BOOL AreYouSure(char *, unsigned int); -void OpenDoor(unsigned int); -void CloseDoor(unsigned int); -void MoveDoor(unsigned int); +unsigned int OpenDoor(unsigned int); +unsigned int CloseDoor(unsigned int); +unsigned int GetDoorState(void); +unsigned int MoveDoor(unsigned int); int ReadPixel(Drawable, int, int); void CheckJoystickData(void); int JoystickPosition(int, int, int); -- 2.34.1