+++ /dev/null
-THIS_IS_NOW_FREEWARE
\ No newline at end of file
# SCORE_ENTRIES = -DONE_PER_NAME # only one score entry per name
SCORE_ENTRIES = -DMANY_PER_NAME # many score entries per name
-# the XPM-Library is needed to build this program:
-XPM_INCLUDE_FILE = -DXPM_INCLUDE_FILE="<X11/xpm.h>"
+# The XPM-Library is no longer needed to build this program,
+# but is used to load graphics if XPM_INCLUDE_FILE is defined,
+# because the GIF loading routines are still a bit beta.
+# If you use the Xpm library, convert the GIF files to Xpm
+# files (and the mask files ('*Maske.gif') to xbm files).
+# XPM_INCLUDE_FILE = -DXPM_INCLUDE_FILE="<X11/xpm.h>"
CONFIG = $(GAME_DIR) $(SOUNDS) $(JOYSTICK) \
$(SCORE_ENTRIES) $(XPM_INCLUDE_FILE)
# 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 = -L/usr/lib/X11R5 -lXpm -lX11 -lm # for HP-UX and others
-LIBS = -L/usr/X11R6/lib -lXpm -lX11 -lm
+# INCL = -I/usr/local/X11/include # for SunOS and others
+# LIBS = -L/usr/lib/X11R5 -lXpm -lX11 -lm
+# # for HP-UX and others
+# LIBS = -L/usr/local/X11/lib -lXpm -lX11 -lm -lsocket -R/usr/local/X11/lib
+# # for SunOS and others
+
+# LIBS = -L/usr/X11R6/lib -lXpm -lX11 -lm
+LIBS = -L/usr/X11R6/lib -lX11 -lm
# CFLAGS = -O2 $(CONFIG) $(SYSTEM)
CFLAGS = $(DEBUG) $(CONFIG) $(SYSTEM) $(INCL)
buttons.c \
files.c \
tape.c \
- sound.c
+ sound.c \
+ joystick.c \
+ cartoons.c \
+ gfxloader.c \
+ random.c
OBJS = main.o \
init.o \
buttons.o \
files.o \
tape.o \
- sound.o
+ sound.o \
+ joystick.o \
+ cartoons.o \
+ gfxloader.o \
+ random.o
all: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) $(LIBS) -o $(PROGNAME)
clean:
$(RM) $(OBJS)
+
+backup:
+ @echo "tar cvzf /usr/AEGLOS/BACKUP/rnd-`date +%Y%m%d | cut -b 3-8`.tgz *.c *.h Makefile"
+ @tar cvzf /usr/AEGLOS/BACKUP/rnd-`date +%Y%m%d | cut -b 3-8`.tgz *.c *.h Makefile
+
+depend:
+ for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* ©1995 Artsoft Development *
+* Holger Schemel *
+* 33659 Bielefeld-Senne *
+* Telefon: (0521) 493245 *
+* eMail: aeglos@valinor.owl.de *
+* aeglos@uni-paderborn.de *
+* q99492@pbhrzx.uni-paderborn.de *
+*----------------------------------------------------------*
+* cartoons.c *
+***********************************************************/
+
+#include "cartoons.h"
+#include "main.h"
+#include "misc.h"
+#include "tools.h"
+
+static void HandleAnimation(int);
+static BOOL AnimateToon(int, BOOL);
+static void DrawAnim(Pixmap, GC, int, int, int, int, int, int, int, int);
+
+struct AnimInfo
+{
+ int width, height;
+ int src_x, src_y;
+ int frames;
+ int frames_per_second;
+ int stepsize;
+ BOOL pingpong;
+ int direction;
+ int position;
+};
+
+/* values for cartoon figures */
+#define NUM_TOONS 18
+
+#define DWARF_XSIZE 40
+#define DWARF_YSIZE 48
+#define DWARF_X 2
+#define DWARF_Y 72
+#define DWARF2_Y 186
+#define DWARF_FRAMES 8
+#define DWARF_FPS 10
+#define DWARF_STEPSIZE 4
+#define JUMPER_XSIZE 48
+#define JUMPER_YSIZE 56
+#define JUMPER_X 2
+#define JUMPER_Y 125
+#define JUMPER_FRAMES 8
+#define JUMPER_FPS 10
+#define JUMPER_STEPSIZE 4
+#define CLOWN_XSIZE 80
+#define CLOWN_YSIZE 110
+#define CLOWN_X 327
+#define CLOWN_Y 10
+#define CLOWN_FRAMES 1
+#define CLOWN_FPS 10
+#define CLOWN_STEPSIZE 4
+#define BIRD_XSIZE 32
+#define BIRD_YSIZE 30
+#define BIRD1_X 2
+#define BIRD1_Y 2
+#define BIRD2_X 2
+#define BIRD2_Y 37
+#define BIRD_FRAMES 8
+#define BIRD_FPS 20
+#define BIRD_STEPSIZE 4
+
+#define GAMETOON_XSIZE TILEX
+#define GAMETOON_YSIZE TILEY
+#define GAMETOON_FRAMES_4 4
+#define GAMETOON_FRAMES_8 8
+#define GAMETOON_FPS 20
+#define GAMETOON_STEPSIZE 4
+
+#define ANIMDIR_LEFT 1
+#define ANIMDIR_RIGHT 2
+#define ANIMDIR_UP 4
+#define ANIMDIR_DOWN 8
+
+#define ANIMPOS_ANY 0
+#define ANIMPOS_LEFT 1
+#define ANIMPOS_RIGHT 2
+#define ANIMPOS_UP 4
+#define ANIMPOS_DOWN 8
+#define ANIMPOS_UPPER 16
+
+#define ANIM_START 0
+#define ANIM_CONTINUE 1
+#define ANIM_STOP 2
+
+void InitAnimation()
+{
+ HandleAnimation(ANIM_START);
+}
+
+void StopAnimation()
+{
+ HandleAnimation(ANIM_STOP);
+}
+
+void DoAnimation()
+{
+ HandleAnimation(ANIM_CONTINUE);
+}
+
+void HandleAnimation(int mode)
+{
+ static long animstart_delay = -1;
+ static long animstart_delay_value = 0;
+ static BOOL anim_restart = TRUE;
+ static BOOL reset_delay = TRUE;
+ static int toon_nr = 0;
+ int draw_mode;
+
+ 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;xx<SCR_FIELDX;xx++)
+ for(yy=0;yy<SCR_FIELDY;yy++)
+ DrawScreenField(xx,yy);
+ DrawPlayerField();
+
+ drawto_field = window;
+ }
+
+ return;
+ break;
+ case ANIM_CONTINUE:
+ break;
+ case ANIM_STOP:
+ redraw_mask |= REDRAW_FIELD;
+
+ /* Redraw background even when in direct drawing mode */
+ draw_mode = direct_draw_on;
+ direct_draw_on = FALSE;
+
+ BackToFront();
+
+ direct_draw_on = draw_mode;
+
+ return;
+ break;
+ default:
+ break;
+ }
+
+ if (reset_delay)
+ {
+ animstart_delay = Counter();
+ animstart_delay_value = SimpleRND(500);
+ reset_delay = FALSE;
+ }
+
+ if (anim_restart)
+ {
+ if (!DelayReached(&animstart_delay,animstart_delay_value))
+ return;
+
+ toon_nr = SimpleRND(NUM_TOONS);
+ }
+
+ anim_restart = reset_delay = AnimateToon(toon_nr,anim_restart);
+}
+
+BOOL AnimateToon(int toon_nr, BOOL restart)
+{
+ static pos_x = 0, pos_y = 0;
+ static delta_x = 0, delta_y = 0;
+ static int frame = 0, frame_step = 1;
+ static BOOL horiz_move, vert_move;
+ static long anim_delay = 0;
+ static int anim_delay_value = 0;
+ static int width,height;
+ static int pad_x,pad_y;
+ static int cut_x,cut_y;
+ static int src_x, src_y;
+ static int dest_x, dest_y;
+ static struct AnimInfo toon[NUM_TOONS] =
+ {
+ {
+ DWARF_XSIZE, DWARF_YSIZE,
+ DWARF_X, DWARF_Y,
+ DWARF_FRAMES,
+ DWARF_FPS,
+ DWARF_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_RIGHT,
+ ANIMPOS_DOWN
+ },
+ {
+ DWARF_XSIZE, DWARF_YSIZE,
+ DWARF_X, DWARF2_Y,
+ DWARF_FRAMES,
+ DWARF_FPS,
+ DWARF_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_LEFT,
+ ANIMPOS_DOWN
+ },
+ {
+ JUMPER_XSIZE, JUMPER_YSIZE,
+ JUMPER_X, JUMPER_Y,
+ JUMPER_FRAMES,
+ JUMPER_FPS,
+ JUMPER_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_LEFT,
+ ANIMPOS_DOWN
+ },
+ {
+ CLOWN_XSIZE, CLOWN_YSIZE,
+ CLOWN_X, CLOWN_Y,
+ CLOWN_FRAMES,
+ CLOWN_FPS,
+ CLOWN_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_UP,
+ ANIMPOS_ANY
+ },
+ {
+ BIRD_XSIZE, BIRD_YSIZE,
+ BIRD1_X, BIRD1_Y,
+ BIRD_FRAMES,
+ BIRD_FPS,
+ BIRD_STEPSIZE,
+ ANIM_OSCILLATE,
+ ANIMDIR_RIGHT,
+ ANIMPOS_UPPER
+ },
+ {
+ BIRD_XSIZE, BIRD_YSIZE,
+ BIRD2_X, BIRD2_Y,
+ BIRD_FRAMES,
+ BIRD_FPS,
+ BIRD_STEPSIZE,
+ ANIM_OSCILLATE,
+ ANIMDIR_LEFT,
+ ANIMPOS_UPPER
+ },
+ {
+ GAMETOON_XSIZE, GAMETOON_YSIZE,
+ ((GFX_SPIELER_LEFT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
+ ((GFX_SPIELER_LEFT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
+ GAMETOON_FRAMES_4,
+ GAMETOON_FPS,
+ GAMETOON_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_LEFT,
+ ANIMPOS_DOWN
+ },
+ {
+ GAMETOON_XSIZE, GAMETOON_YSIZE,
+ ((GFX_SPIELER_RIGHT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
+ ((GFX_SPIELER_RIGHT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
+ GAMETOON_FRAMES_4,
+ GAMETOON_FPS,
+ GAMETOON_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_RIGHT,
+ ANIMPOS_DOWN
+ },
+ {
+ GAMETOON_XSIZE, GAMETOON_YSIZE,
+ ((GFX_PINGUIN_LEFT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
+ ((GFX_PINGUIN_LEFT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
+ GAMETOON_FRAMES_4,
+ GAMETOON_FPS,
+ GAMETOON_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_LEFT,
+ ANIMPOS_DOWN
+ },
+ {
+ GAMETOON_XSIZE, GAMETOON_YSIZE,
+ ((GFX_PINGUIN_RIGHT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
+ ((GFX_PINGUIN_RIGHT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
+ GAMETOON_FRAMES_4,
+ GAMETOON_FPS,
+ GAMETOON_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_RIGHT,
+ ANIMPOS_DOWN
+ },
+ {
+ GAMETOON_XSIZE, GAMETOON_YSIZE,
+ ((GFX_MAULWURF_LEFT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
+ ((GFX_MAULWURF_LEFT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
+ GAMETOON_FRAMES_4,
+ GAMETOON_FPS,
+ GAMETOON_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_LEFT,
+ ANIMPOS_DOWN
+ },
+ {
+ GAMETOON_XSIZE, GAMETOON_YSIZE,
+ ((GFX_MAULWURF_RIGHT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
+ ((GFX_MAULWURF_RIGHT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
+ GAMETOON_FRAMES_4,
+ GAMETOON_FPS,
+ GAMETOON_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_RIGHT,
+ ANIMPOS_DOWN
+ },
+ {
+ GAMETOON_XSIZE, GAMETOON_YSIZE,
+ ((GFX_SCHWEIN_LEFT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
+ ((GFX_SCHWEIN_LEFT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
+ GAMETOON_FRAMES_4,
+ GAMETOON_FPS,
+ GAMETOON_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_LEFT,
+ ANIMPOS_DOWN
+ },
+ {
+ GAMETOON_XSIZE, GAMETOON_YSIZE,
+ ((GFX_SCHWEIN_RIGHT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
+ ((GFX_SCHWEIN_RIGHT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
+ GAMETOON_FRAMES_4,
+ GAMETOON_FPS,
+ GAMETOON_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_RIGHT,
+ ANIMPOS_DOWN
+ },
+ {
+ GAMETOON_XSIZE, GAMETOON_YSIZE,
+ ((GFX_DRACHE_LEFT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
+ ((GFX_DRACHE_LEFT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
+ GAMETOON_FRAMES_4,
+ GAMETOON_FPS,
+ GAMETOON_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_LEFT,
+ ANIMPOS_DOWN
+ },
+ {
+ GAMETOON_XSIZE, GAMETOON_YSIZE,
+ ((GFX_DRACHE_RIGHT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
+ ((GFX_DRACHE_RIGHT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
+ GAMETOON_FRAMES_4,
+ GAMETOON_FPS,
+ GAMETOON_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_RIGHT,
+ ANIMPOS_DOWN
+ },
+ {
+ GAMETOON_XSIZE, GAMETOON_YSIZE,
+ ((GFX_SONDE - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
+ ((GFX_SONDE - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
+ GAMETOON_FRAMES_8,
+ GAMETOON_FPS,
+ GAMETOON_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_LEFT,
+ ANIMPOS_ANY
+ },
+ {
+ GAMETOON_XSIZE, GAMETOON_YSIZE,
+ ((GFX_SONDE - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
+ ((GFX_SONDE - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
+ GAMETOON_FRAMES_8,
+ GAMETOON_FPS,
+ GAMETOON_STEPSIZE,
+ ANIM_NORMAL,
+ ANIMDIR_RIGHT,
+ ANIMPOS_ANY
+ },
+ };
+ struct AnimInfo *anim = &toon[toon_nr];
+ Pixmap anim_pixmap = (toon_nr < 6 ? pix[PIX_TOONS] : pix[PIX_HEROES]);
+ GC anim_clip_gc = (toon_nr < 6 ? clip_gc[PIX_TOONS] : clip_gc[PIX_HEROES]);
+
+ if (restart)
+ {
+ horiz_move = (anim->direction & (ANIMDIR_LEFT | ANIMDIR_RIGHT));
+ vert_move = (anim->direction & (ANIMDIR_UP | ANIMDIR_DOWN));
+ anim_delay_value = 100/anim->frames_per_second;
+ frame = 0;
+
+ if (horiz_move)
+ {
+ if (anim->position==ANIMPOS_UP)
+ pos_y = 0;
+ else if (anim->position==ANIMPOS_DOWN)
+ pos_y = FULL_SYSIZE-anim->height;
+ else if (anim->position==ANIMPOS_UPPER)
+ pos_y = SimpleRND((FULL_SYSIZE-anim->height)/2);
+ else
+ pos_y = SimpleRND(FULL_SYSIZE-anim->height);
+
+ if (anim->direction==ANIMDIR_RIGHT)
+ {
+ delta_x = anim->stepsize;
+ pos_x = -anim->width+delta_x;
+ }
+ else
+ {
+ delta_x = -anim->stepsize;
+ pos_x = FULL_SXSIZE+delta_x;
+ }
+ delta_y = 0;
+ }
+ else
+ {
+ if (anim->position==ANIMPOS_LEFT)
+ pos_x = 0;
+ else if (anim->position==ANIMPOS_RIGHT)
+ pos_x = FULL_SXSIZE-anim->width;
+ else
+ pos_x = SimpleRND(FULL_SXSIZE-anim->width);
+
+ if (anim->direction==ANIMDIR_DOWN)
+ {
+ delta_y = anim->stepsize;
+ pos_y = -anim->height+delta_y;
+ }
+ else
+ {
+ delta_y = -anim->stepsize;
+ pos_y = FULL_SYSIZE+delta_y;
+ }
+ delta_x = 0;
+ }
+ }
+
+ if (pos_x <= -anim->width - anim->stepsize ||
+ pos_x >= FULL_SXSIZE + anim->stepsize ||
+ pos_y <= -anim->height - anim->stepsize ||
+ pos_y >= FULL_SYSIZE + anim->stepsize)
+ return(TRUE);
+
+ if (!DelayReached(&anim_delay,anim_delay_value))
+ {
+ if (game_status==HELPSCREEN && !restart)
+ DrawAnim(anim_pixmap,anim_clip_gc,
+ src_x+cut_x,src_y+cut_y, width,height,
+ REAL_SX+dest_x,REAL_SY+dest_y, pad_x,pad_y);
+
+ return(FALSE);
+ }
+
+ if (pos_x<-anim->width)
+ pos_x = -anim->width;
+ else if (pos_x>FULL_SXSIZE)
+ pos_x = FULL_SXSIZE;
+ if (pos_y<-anim->height)
+ pos_y = -anim->height;
+ else if (pos_y>FULL_SYSIZE)
+ pos_y = FULL_SYSIZE;
+
+ pad_x = (horiz_move ? anim->stepsize : 0);
+ pad_y = (vert_move ? anim->stepsize : 0);
+ src_x = anim->src_x + frame * anim->width;
+ src_y = anim->src_y;
+ dest_x = pos_x;
+ dest_y = pos_y;
+ cut_x = cut_y = 0;
+ width = anim->width;
+ height = anim->height;
+
+ if (pos_x<0)
+ {
+ dest_x = 0;
+ width += pos_x;
+ cut_x = -pos_x;
+ }
+ else if (pos_x>FULL_SXSIZE-anim->width)
+ width -= (pos_x - (FULL_SXSIZE-anim->width));
+
+ if (pos_y<0)
+ {
+ dest_y = 0;
+ height += pos_y;
+ cut_y = -pos_y;
+ }
+ else if (pos_y>FULL_SYSIZE-anim->height)
+ height -= (pos_y - (FULL_SYSIZE-anim->height));
+
+ DrawAnim(anim_pixmap,anim_clip_gc,
+ src_x+cut_x,src_y+cut_y, width,height,
+ REAL_SX+dest_x,REAL_SY+dest_y, pad_x,pad_y);
+
+ pos_x += delta_x;
+ pos_y += delta_y;
+ frame += frame_step;
+
+ if (frame<0 || frame>=anim->frames)
+ {
+ if (anim->pingpong)
+ {
+ frame_step *= -1;
+ frame = (frame<0 ? 1 : anim->frames-2);
+ }
+ else
+ frame = (frame<0 ? anim->frames-1 : 0);
+ }
+
+ return(FALSE);
+}
+
+void DrawAnim(Pixmap toon_pixmap, GC toon_clip_gc,
+ int src_x, int src_y, int width, int height,
+ int dest_x, int dest_y, int pad_x, int pad_y)
+{
+ int buf_x = DOOR_GFX_PAGEX3, buf_y = DOOR_GFX_PAGEY1;
+
+#if 1
+ /* special method to avoid flickering interference with BackToFront() */
+ XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,dest_x-pad_x,dest_y-pad_y,
+ width+2*pad_x,height+2*pad_y, buf_x,buf_y);
+ XSetClipOrigin(display,toon_clip_gc,dest_x-src_x,dest_y-src_y);
+ XCopyArea(display,toon_pixmap,backbuffer,toon_clip_gc,
+ src_x,src_y, width,height, dest_x,dest_y);
+ XCopyArea(display,backbuffer,window,gc, dest_x-pad_x,dest_y-pad_y,
+ width+2*pad_x,height+2*pad_y, dest_x-pad_x,dest_y-pad_y);
+ BackToFront();
+ XCopyArea(display,pix[PIX_DB_DOOR],backbuffer,gc, buf_x,buf_y,
+ width+2*pad_x,height+2*pad_y, dest_x-pad_x,dest_y-pad_y);
+#else
+ /* normal method, causing flickering interference with BackToFront() */
+ XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,dest_x-pad_x,dest_y-pad_y,
+ width+2*pad_x,height+2*pad_y, buf_x,buf_y);
+ XSetClipOrigin(display,toon_clip_gc,
+ buf_x-src_x+pad_x,buf_y-src_y+pad_y);
+ XCopyArea(display,toon_pixmap,pix[PIX_DB_DOOR],toon_clip_gc,
+ src_x,src_y, width,height, buf_x+pad_x,buf_y+pad_y);
+ XCopyArea(display,pix[PIX_DB_DOOR],window,gc, buf_x,buf_y,
+ width+2*pad_x,height+2*pad_y, dest_x-pad_x,dest_y-pad_y);
+#endif
+
+ XFlush(display);
+}
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* ©1995 Artsoft Development *
+* Holger Schemel *
+* 33659 Bielefeld-Senne *
+* Telefon: (0521) 493245 *
+* eMail: aeglos@valinor.owl.de *
+* aeglos@uni-paderborn.de *
+* q99492@pbhrzx.uni-paderborn.de *
+*----------------------------------------------------------*
+* cartoons.h *
+***********************************************************/
+
+#ifndef CARTOONS_H
+#define CARTOONS_H
+
+void InitAnimation(void);
+void StopAnimation(void);
+void DoAnimation(void);
+
+#endif
EL_MAMPFER,
EL_KAEFER_O,
EL_FLIEGER_O,
- EL_ZOMBIE,
+ EL_ROBOT,
EL_KAEFER_L,
EL_FLIEGER_L,
EL_CHAR_A + ('R' - 'A'),
EL_CHAR_A + ('E' - 'A'),
+ EL_PFEIL_L,
+ EL_PFEIL_R,
+ EL_PFEIL_O,
+ EL_PFEIL_U,
+
EL_AMOEBE_VOLL,
EL_EDELSTEIN_GELB,
EL_EDELSTEIN_ROT,
EL_DYNABOMB_XL,
EL_BADEWANNE,
+ EL_MAULWURF,
+ EL_PINGUIN,
+ EL_SCHWEIN,
+ EL_DRACHE,
+
+ EL_SONDE,
+ EL_LEERRAUM,
+ EL_LEERRAUM,
+ EL_LEERRAUM,
+
EL_CHAR_A + ('S' - 'A'),
EL_CHAR_A + ('O' - 'A'),
EL_CHAR_A + ('K' - 'A'),
EL_CHAR_A + ('R' - 'A'),
*/
+ EL_LEERRAUM,
+ EL_LEERRAUM,
+ EL_LEERRAUM,
+ EL_LEERRAUM,
+
EL_CHAR_AUSRUF,
EL_CHAR_ZOLL,
EL_CHAR_DOLLAR,
ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
"<",FS_SMALL,FC_RED);
}
- else if (key==XK_Delete && len>0)
+ else if ((key==XK_Delete || key==XK_BackSpace) && len>0)
{
level.name[len-1] = 0;
len--;
#include "editor.h"
#include "misc.h"
#include "tape.h"
+#include "joystick.h"
void EventLoop(void)
{
SleepWhileUnmapped();
break;
case ButtonPress:
- HandleButtonEvent((XButtonEvent *) &event);
- break;
case ButtonRelease:
HandleButtonEvent((XButtonEvent *) &event);
break;
HandleMotionEvent((XMotionEvent *) &event);
break;
case KeyPress:
- HandleKeyEvent((XKeyEvent *) &event);
- break;
case KeyRelease:
HandleKeyEvent((XKeyEvent *) &event);
break;
case FocusIn:
- HandleFocusEvent(FOCUS_IN);
- break;
case FocusOut:
- HandleFocusEvent(FOCUS_OUT);
+ HandleFocusEvent((XFocusChangeEvent *) &event);
break;
default:
break;
key_joystick_mapping = 0;
break;
case FocusIn:
- HandleFocusEvent(FOCUS_IN);
- break;
case FocusOut:
- HandleFocusEvent(FOCUS_OUT);
+ HandleFocusEvent((XFocusChangeEvent *) &event);
break;
default:
break;
int x = event->x, y = event->y;
int width = event->width, height = event->height;
- XCopyArea(display,drawto,window,gc, x,y, width,height, x,y);
-
if (direct_draw_on && game_status==PLAYING)
{
int xx,yy;
int x1 = (x-SX)/TILEX, y1 = (y-SY)/TILEY;
int x2 = (x-SX+width)/TILEX, y2 = (y-SY+height)/TILEY;
+ drawto_field = backbuffer;
+
for(xx=0;xx<SCR_FIELDX;xx++)
for(yy=0;yy<SCR_FIELDY;yy++)
if (xx>=x1 && xx<=x2 && yy>=y1 && yy<=y2)
DrawScreenField(xx,yy);
- DrawLevelElement(JX,JY,EL_SPIELFIGUR);
+ DrawPlayerField();
+
+ drawto_field = window;
}
+ XCopyArea(display,drawto,window,gc, x,y, width,height, x,y);
+
XFlush(display);
}
HandleKey(key, key_status);
}
-void HandleFocusEvent(int focus_status)
+void HandleFocusEvent(XFocusChangeEvent *event)
{
static int old_joystick_status = -1;
- if (focus_status==FOCUS_OUT)
+ if (event->type == FocusOut)
{
XAutoRepeatOn(display);
old_joystick_status = joystick_status;
joystick_status = JOYSTICK_OFF;
}
- else
+ else if (event->type == FocusIn)
{
if (game_status == PLAYING)
XAutoRepeatOff(display);
if (key_status == KEY_RELEASED)
return;
+ if (key==XK_Return && game_status==PLAYING && GameOver)
+ {
+ CloseDoor(DOOR_CLOSE_1);
+ game_status = MAINMENU;
+ DrawMainMenu();
+ return;
+ }
+
if (key==XK_Escape && game_status!=MAINMENU) /* quick quit to MAINMENU */
{
CloseDoor(DOOR_CLOSE_1 | DOOR_NO_DELAY);
int dx = (left ? -1 : right ? 1 : 0);
int dy = (up ? -1 : down ? 1 : 0);
+ if (game_status==PLAYING && (tape.playing || keyboard))
+ newbutton = ((joy & JOY_BUTTON) != 0);
+
switch(game_status)
{
case MAINMENU:
static long joystickmove_delay = 0;
if (joystick && !button && !DelayReached(&joystickmove_delay,15))
- break;
+ newbutton = dx = dy = 0;
if (game_status==MAINMENU)
HandleMainMenu(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
{
BOOL moved = FALSE, snapped = FALSE, bombed = FALSE;
- if (tape.pausing)
- joy = 0;
-
- if (!joy)
- {
- DigField(0,0,0,0,DF_NO_PUSH);
- SnapField(0,0);
- break;
- }
-
if (GameOver && newbutton)
{
CloseDoor(DOOR_CLOSE_1);
return;
}
- if (button1)
- snapped = SnapField(dx,dy);
+ if (tape.pausing || PlayerGone)
+ joy = 0;
+
+ if (joy)
+ {
+ if (button1)
+ snapped = SnapField(dx,dy);
+ else
+ {
+ if (button2)
+ bombed = PlaceBomb();
+ moved = MoveFigure(dx,dy);
+ }
+
+ if (tape.recording && (moved || snapped || bombed))
+ {
+ if (bombed && !moved)
+ joy &= JOY_BUTTON;
+ TapeRecordAction(joy);
+ }
+ else if (tape.playing && snapped)
+ SnapField(0,0); /* stop snapping */
+ }
else
{
- if (button2)
- bombed = PlaceBomb();
- moved = MoveFigure(dx,dy);
+ DigField(0,0,0,0,DF_NO_PUSH);
+ SnapField(0,0);
+ PlayerFrame = 0;
}
- if (tape.recording && (moved || snapped || bombed))
+ if (tape.playing && !tape.pausing && !joy && tape.counter<tape.length)
{
- if (bombed && !moved)
- joy &= JOY_BUTTON;
- TapeRecordAction(joy);
+ int next_joy =
+ tape.pos[tape.counter].joystickdata & (JOY_LEFT|JOY_RIGHT);
+
+ if (next_joy == JOY_LEFT || next_joy == JOY_RIGHT)
+ {
+ int dx = (next_joy == JOY_LEFT ? -1 : +1);
+
+ if (IN_LEV_FIELD(JX+dx,JY) && IS_PUSHABLE(Feld[JX+dx][JY]))
+ {
+ int el = Feld[JX+dx][JY];
+ int push_delay = (IS_SB_ELEMENT(el) || el==EL_SONDE ? 2 : 10);
+
+ if (tape.delay_played + push_delay >= tape.pos[tape.counter].delay)
+ {
+ PlayerMovDir = next_joy;
+ PlayerFrame = FrameCounter % 4;
+ PlayerPushing = TRUE;
+ }
+ }
+ }
}
- else if (tape.playing && snapped)
- SnapField(0,0); /* stop snapping */
+
+ DrawPlayerField();
break;
}
void HandleButtonEvent(XButtonEvent *);
void HandleMotionEvent(XMotionEvent *);
void HandleKeyEvent(XKeyEvent *);
-void HandleFocusEvent(int);
+void HandleFocusEvent(XFocusChangeEvent *);
void HandleNoXEvent(void);
void HandleButton(int, int, int);
#include "tools.h"
#include "misc.h"
#include "tape.h"
+#include "joystick.h"
BOOL CreateNewScoreFile()
{
#include "buttons.h"
#include "files.h"
#include "tape.h"
+#include "joystick.h"
extern int Gamespeed;
extern int Movemethod;
Dynamite = Score = 0;
Gems = level.edelsteine;
- SokobanFields = Lights = 0;
+ SokobanFields = Lights = Friends = 0;
DynaBombCount = DynaBombSize = DynaBombsLeft = 0;
DynaBombXL = FALSE;
Key[0] = Key[1] = Key[2] = Key[3] = FALSE;
FrameCounter = 0;
TimeFrames = 0;
TimeLeft = level.time;
- LevelSolved = GameOver = SiebAktiv = FALSE;
+ PlayerMovDir = MV_NO_MOVING;
+ PlayerFrame = 0;
+ PlayerPushing = FALSE;
+ PlayerGone = LevelSolved = GameOver = SiebAktiv = FALSE;
JX = JY = 0;
ZX = ZY = -1;
case EL_PACMAN_U:
case EL_MAMPFER:
case EL_MAMPFER2:
- case EL_ZOMBIE:
+ case EL_ROBOT:
case EL_PACMAN:
InitMovDir(x,y);
break;
case EL_SOKOBAN_FELD_LEER:
SokobanFields++;
break;
+ case EL_MAULWURF:
+ case EL_PINGUIN:
+ Friends++;
+ break;
+ case EL_SCHWEIN:
+ case EL_DRACHE:
+ MovDir[x][y] = 1<<RND(4);
+ break;
default:
break;
}
FadeSounds();
/* Hero disappears */
- DrawLevelElement(JX,JY,Feld[JX][JY]);
- JX = JY = -1;
+ DrawLevelElement(ExitX,ExitY,Feld[ExitX][ExitY]);
BackToFront();
if (tape.playing)
void RemoveMovingField(int x, int y)
{
- int oldx=x,oldy=y, newx=x,newy=y;
+ int oldx = x,oldy = y, newx = x,newy = y;
- if (Feld[x][y]!=EL_BLOCKED && !IS_MOVING(x,y))
+ if (Feld[x][y] != EL_BLOCKED && !IS_MOVING(x,y))
return;
if (IS_MOVING(x,y))
{
Moving2Blocked(x,y,&newx,&newy);
- if (Feld[newx][newy]!=EL_BLOCKED)
+ if (Feld[newx][newy] != EL_BLOCKED)
return;
}
else if (Feld[x][y]==EL_BLOCKED)
return;
}
- Feld[oldx][oldy] = EL_LEERRAUM;
+ if (Feld[x][y]==EL_BLOCKED &&
+ (Store[oldx][oldy]==EL_MORAST_LEER ||
+ Store[oldx][oldy]==EL_SIEB_LEER ||
+ Store[oldx][oldy]==EL_SIEB2_LEER ||
+ Store[oldx][oldy]==EL_AMOEBE_NASS))
+ {
+ Feld[oldx][oldy] = Store[oldx][oldy];
+ Store[oldx][oldy] = Store2[oldx][oldy] = 0;
+ }
+ else
+ Feld[oldx][oldy] = EL_LEERRAUM;
+
Feld[newx][newy] = EL_LEERRAUM;
MovPos[oldx][oldy] = MovDir[oldx][oldy] = MovDelay[oldx][oldy] = 0;
MovPos[newx][newy] = MovDir[newx][newy] = MovDelay[newx][newy] = 0;
+
DrawLevelField(oldx,oldy);
DrawLevelField(newx,newy);
}
void DrawDynamite(int x, int y)
{
- if (!IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
+ int sx = SCROLLX(x), sy = SCROLLY(y);
+ int graphic = el2gfx(Feld[x][y]);
+ int phase;
+
+ if (!IN_SCR_FIELD(sx,sy) || IS_PLAYER(x,y))
return;
if (Store[x][y])
- {
- DrawGraphic(SCROLLX(x),SCROLLY(y),el2gfx(Store[x][y]));
- if (IS_PLAYER(x,y))
- DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR);
- }
- else if (IS_PLAYER(x,y))
- DrawGraphic(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR);
+ DrawGraphic(sx,sy, el2gfx(Store[x][y]));
if (Feld[x][y]==EL_DYNAMIT)
{
- int phase = (48-MovDelay[x][y])/6;
-
- if (phase>6)
+ if ((phase = (48-MovDelay[x][y])/6) > 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
{
- int phase = ((48-MovDelay[x][y])/3) % 8;
-
- if (phase>3)
+ if ((phase = ((48-MovDelay[x][y])/3) % 8) > 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);
}
+
+ if (Store[x][y])
+ DrawGraphicThruMask(sx,sy, graphic + phase);
+ else
+ DrawGraphic(sx,sy, graphic + phase);
}
void CheckDynamite(int x, int y)
{
int center_element = Feld[ex][ey];
- if (center_element==EL_BLOCKED)
+ if (IS_MOVING(ex,ey) || IS_BLOCKED(ex,ey))
+ {
center_element = MovingOrBlocked2Element(ex,ey);
+ RemoveMovingField(ex,ey);
+ }
for(y=ey-1;y<ey+2;y++) for(x=ex-1;x<ex+2;x++)
{
int element = Feld[x][y];
- if (!IN_LEV_FIELD(x,y) || IS_MASSIV(element))
+ if (IS_MOVING(x,y) || IS_BLOCKED(x,y))
+ {
+ element = MovingOrBlocked2Element(x,y);
+ RemoveMovingField(x,y);
+ }
+
+ if (!IN_LEV_FIELD(x,y) || IS_MASSIV(element) || element==EL_BURNING)
continue;
if ((mode!=EX_NORMAL || center_element==EL_AMOEBA2DIAM) &&
if (IS_PLAYER(ex,ey))
Store[x][y] = EL_EDELSTEIN_GELB;
+ else if (center_element==EL_MAULWURF)
+ Store[x][y] = EL_EDELSTEIN_ROT;
+ else if (center_element==EL_PINGUIN)
+ Store[x][y] = EL_EDELSTEIN_LILA;
else if (center_element==EL_KAEFER)
Store[x][y] = ((x==ex && y==ey) ? EL_DIAMANT : EL_EDELSTEIN);
else if (center_element==EL_BUTTERFLY)
AmoebaCnt2[AmoebaNr[x][y]]--;
}
- RemoveMovingField(x,y);
Feld[x][y] = EL_EXPLODING;
MovDir[x][y] = MovPos[x][y] = 0;
AmoebaNr[x][y] = 0;
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)
+ else if (IS_EXPLOSIVE(element))
{
Feld[x][y] = Store2[x][y];
Store2[x][y] = 0;
case EL_FIREFLY:
case EL_MAMPFER:
case EL_MAMPFER2:
- case EL_ZOMBIE:
+ case EL_ROBOT:
case EL_PACMAN:
RaiseScoreElement(element);
Explode(x,y,0,EX_NORMAL);
BOOL lastline = (y==lev_fieldy-1);
BOOL object_hit = FALSE;
int element = Feld[x][y];
+ int smashed = 0;
/* Element darunter berührt? */
if (!lastline)
+ {
object_hit = (!IS_FREE(x,y+1) && (!IS_MOVING(x,y+1) ||
MovDir[x][y+1]!=MV_DOWN ||
MovPos[x][y+1]<=TILEY/2));
+ if (object_hit)
+ smashed = MovingOrBlocked2Element(x,y+1);
+ }
/* Auftreffendes Element fällt in Salzsäure */
- if (!lastline && Feld[x][y+1]==EL_SALZSAEURE)
+ if (!lastline && smashed==EL_SALZSAEURE)
{
Blurb(x,y);
return;
{
if (object_hit && IS_PLAYER(x,y+1))
KillHero();
+ else if (object_hit && (smashed==EL_MAULWURF || smashed==EL_PINGUIN))
+ Bang(x,y+1);
else
{
Feld[x][y] = EL_AMOEBING;
/* Welches Element kriegt was auf die Rübe? */
if (!lastline && object_hit)
{
- 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;
KillHero();
return;
}
+ else if (smashed==EL_MAULWURF || smashed==EL_PINGUIN)
+ {
+ Bang(x,y+1);
+ return;
+ }
else if (element==EL_EDELSTEIN_BD)
{
if (IS_ENEMY(smashed) && IS_BD_ELEMENT(smashed))
}
else if (element==EL_FELSBROCKEN)
{
- if (IS_ENEMY(smashed))
+ if (IS_ENEMY(smashed) || smashed==EL_BOMBE || smashed==EL_SONDE ||
+ smashed==EL_SCHWEIN || smashed==EL_DRACHE)
{
Bang(x,y+1);
return;
}
else if (!IS_MOVING(x,y+1))
{
- if (smashed==EL_BOMBE ||
- smashed==EL_BIRNE_AUS || smashed==EL_BIRNE_EIN)
+ if (smashed==EL_BIRNE_AUS || smashed==EL_BIRNE_EIN)
{
Bang(x,y+1);
return;
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 back_dx = move_xy[back_dir].x, back_dy = move_xy[back_dir].y;
int left_x = x+left_dx, left_y = y+left_dy;
int right_x = x+right_dx, right_y = y+right_dy;
MovDelay[x][y] = 3+RND(20);
}
- else if (element==EL_ZOMBIE)
+ else if (element==EL_SCHWEIN)
+ {
+ BOOL can_turn_left = FALSE, can_turn_right = FALSE, can_move_on = FALSE;
+ BOOL should_turn_left = FALSE, should_turn_right = FALSE;
+ BOOL should_move_on = FALSE;
+ int rnd_value = 24;
+ int rnd = RND(rnd_value);
+
+ if (IN_LEV_FIELD(left_x,left_y) &&
+ (IS_FREE(left_x,left_y) || IS_GEM(Feld[left_x][left_y])))
+ can_turn_left = TRUE;
+ if (IN_LEV_FIELD(right_x,right_y) &&
+ (IS_FREE(right_x,right_y) || IS_GEM(Feld[right_x][right_y])))
+ can_turn_right = TRUE;
+ if (IN_LEV_FIELD(move_x,move_y) &&
+ (IS_FREE(move_x,move_y) || IS_GEM(Feld[move_x][move_y])))
+ can_move_on = TRUE;
+
+ if (can_turn_left &&
+ (!can_move_on ||
+ (IN_LEV_FIELD(x+back_dx+left_dx,y+back_dy+left_dy) &&
+ !IS_FREE(x+back_dx+left_dx,y+back_dy+left_dy))))
+ should_turn_left = TRUE;
+ if (can_turn_right &&
+ (!can_move_on ||
+ (IN_LEV_FIELD(x+back_dx+right_dx,y+back_dy+right_dy) &&
+ !IS_FREE(x+back_dx+right_dx,y+back_dy+right_dy))))
+ should_turn_right = TRUE;
+ if (can_move_on &&
+ (!can_turn_left || !can_turn_right ||
+ (IN_LEV_FIELD(x+move_dx+left_dx,y+move_dy+left_dy) &&
+ !IS_FREE(x+move_dx+left_dx,y+move_dy+left_dy)) ||
+ (IN_LEV_FIELD(x+move_dx+right_dx,y+move_dy+right_dy) &&
+ !IS_FREE(x+move_dx+right_dx,y+move_dy+right_dy))))
+ should_move_on = TRUE;
+
+ if (should_turn_left || should_turn_right || should_move_on)
+ {
+ if (should_turn_left && should_turn_right && should_move_on)
+ MovDir[x][y] = (rnd < rnd_value/3 ? left_dir :
+ rnd < 2*rnd_value/3 ? right_dir :
+ old_move_dir);
+ else if (should_turn_left && should_turn_right)
+ MovDir[x][y] = (rnd < rnd_value/2 ? left_dir : right_dir);
+ else if (should_turn_left && should_move_on)
+ MovDir[x][y] = (rnd < rnd_value/2 ? left_dir : old_move_dir);
+ else if (should_turn_right && should_move_on)
+ MovDir[x][y] = (rnd < rnd_value/2 ? right_dir : old_move_dir);
+ else if (should_turn_left)
+ MovDir[x][y] = left_dir;
+ else if (should_turn_right)
+ MovDir[x][y] = right_dir;
+ else if (should_move_on)
+ MovDir[x][y] = old_move_dir;
+ }
+ else if (can_move_on && rnd > rnd_value/8)
+ MovDir[x][y] = old_move_dir;
+ else if (can_turn_left && can_turn_right)
+ MovDir[x][y] = (rnd < rnd_value/2 ? left_dir : right_dir);
+ else if (can_turn_left && rnd > rnd_value/8)
+ MovDir[x][y] = left_dir;
+ else if (can_turn_right && rnd > rnd_value/8)
+ MovDir[x][y] = right_dir;
+ else
+ MovDir[x][y] = back_dir;
+
+ if (!IS_FREE(x+move_xy[MovDir[x][y]].x,y+move_xy[MovDir[x][y]].y) &&
+ !IS_GEM(Feld[x+move_xy[MovDir[x][y]].x][y+move_xy[MovDir[x][y]].y]))
+ MovDir[x][y] = old_move_dir;
+
+ MovDelay[x][y] = 0;
+ }
+ else if (element==EL_DRACHE)
+ {
+ BOOL can_turn_left = FALSE, can_turn_right = FALSE, can_move_on = FALSE;
+ int rnd_value = 24;
+ int rnd = RND(rnd_value);
+
+ if (IN_LEV_FIELD(left_x,left_y) && IS_FREE(left_x,left_y))
+ can_turn_left = TRUE;
+ if (IN_LEV_FIELD(right_x,right_y) && IS_FREE(right_x,right_y))
+ can_turn_right = TRUE;
+ if (IN_LEV_FIELD(move_x,move_y) && IS_FREE(move_x,move_y))
+ can_move_on = TRUE;
+
+ if (can_move_on && rnd > rnd_value/8)
+ MovDir[x][y] = old_move_dir;
+ else if (can_turn_left && can_turn_right)
+ MovDir[x][y] = (rnd < rnd_value/2 ? left_dir : right_dir);
+ else if (can_turn_left && rnd > rnd_value/8)
+ MovDir[x][y] = left_dir;
+ else if (can_turn_right && rnd > rnd_value/8)
+ MovDir[x][y] = right_dir;
+ else
+ MovDir[x][y] = back_dir;
+
+ if (!IS_FREE(x+move_xy[MovDir[x][y]].x,y+move_xy[MovDir[x][y]].y))
+ MovDir[x][y] = old_move_dir;
+
+ MovDelay[x][y] = 0;
+ }
+ else if (element==EL_ROBOT || element==EL_SONDE ||
+ element==EL_MAULWURF || element==EL_PINGUIN)
{
int attr_x = JX, attr_y = JY;
int newx, newy;
- if (ZX>=0 && ZY>=0)
+ if (PlayerGone)
+ {
+ attr_x = ExitX;
+ attr_y = ExitY;
+ }
+
+ if (element==EL_ROBOT && ZX>=0 && ZY>=0)
{
attr_x = ZX;
attr_y = ZY;
}
+ if (element==EL_MAULWURF || element==EL_PINGUIN)
+ {
+ int i;
+ static int xy[4][2] =
+ {
+ { 0,-1 },
+ { -1,0 },
+ { +1,0 },
+ { 0,+1 }
+ };
+
+ for(i=0;i<4;i++)
+ {
+ int ex = x+xy[i%4][0];
+ int ey = y+xy[i%4][1];
+
+ if (IN_LEV_FIELD(ex,ey) && Feld[ex][ey] == EL_AUSGANG_AUF)
+ {
+ attr_x = ex;
+ attr_y = ey;
+ break;
+ }
+ }
+ }
+
MovDir[x][y] = MV_NO_MOVING;
if (attr_x<x)
MovDir[x][y] |= (GameOver ? MV_RIGHT : MV_LEFT);
MovDir[x][y] |= (GameOver ? MV_DOWN : MV_UP);
else if (attr_y>y)
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));
- Moving2Blocked(x,y,&newx,&newy);
- if (IN_LEV_FIELD(newx,newy) && IS_FREE_OR_PLAYER(newx,newy))
- MovDelay[x][y] = 4+4*!RND(3);
+ if (element==EL_ROBOT)
+ {
+ 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));
+ 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;
+ }
else
- MovDelay[x][y] = 8;
+ {
+ MovDelay[x][y] = 1;
+
+ if ((MovDir[x][y]&(MV_LEFT|MV_RIGHT)) && (MovDir[x][y]&(MV_UP|MV_DOWN)))
+ {
+ BOOL first_horiz = RND(2);
+ int new_move_dir = MovDir[x][y];
+
+ MovDir[x][y] =
+ new_move_dir & (first_horiz ? (MV_LEFT|MV_RIGHT) : (MV_UP|MV_DOWN));
+ Moving2Blocked(x,y,&newx,&newy);
+
+ if (IN_LEV_FIELD(newx,newy) &&
+ (IS_FREE(newx,newy) ||
+ Feld[newx][newy] == EL_SALZSAEURE ||
+ ((element == EL_MAULWURF || element==EL_PINGUIN) &&
+ (Feld[newx][newy] == EL_AUSGANG_AUF ||
+ IS_MAMPF3(Feld[newx][newy])))))
+ return;
+
+ MovDir[x][y] =
+ new_move_dir & (!first_horiz ? (MV_LEFT|MV_RIGHT) : (MV_UP|MV_DOWN));
+ Moving2Blocked(x,y,&newx,&newy);
+
+ if (IN_LEV_FIELD(newx,newy) &&
+ (IS_FREE(newx,newy) ||
+ Feld[newx][newy] == EL_SALZSAEURE ||
+ ((element == EL_MAULWURF || element==EL_PINGUIN) &&
+ (Feld[newx][newy] == EL_AUSGANG_AUF ||
+ IS_MAMPF3(Feld[newx][newy])))))
+ return;
+
+ MovDir[x][y] = old_move_dir;
+ return;
+ }
+ }
}
}
Feld[x][y] = EL_CHANGED(Store2[x][y]);
Store[x][y] = EL_SIEB_LEER;
}
+ else if (Feld[x][y+1]==EL_SIEB_LEER)
+ {
+ if (!MovDelay[x][y])
+ MovDelay[x][y] = 2;
+
+ if (MovDelay[x][y])
+ {
+ MovDelay[x][y]--;
+ if (MovDelay[x][y])
+ return;
+ }
+
+ Feld[x][y] = EL_SIEB_LEER;
+ Feld[x][y+1] = EL_SIEB_VOLL;
+ Store2[x][y+1] = EL_CHANGED(Store2[x][y]);
+ Store2[x][y] = 0;
+ }
}
else if (element==EL_SIEB2_VOLL)
{
Feld[x][y] = EL_CHANGED2(Store2[x][y]);
Store[x][y] = EL_SIEB2_LEER;
}
+ else if (Feld[x][y+1]==EL_SIEB2_LEER)
+ {
+ if (!MovDelay[x][y])
+ MovDelay[x][y] = 2;
+
+ if (MovDelay[x][y])
+ {
+ MovDelay[x][y]--;
+ if (MovDelay[x][y])
+ return;
+ }
+
+ Feld[x][y] = EL_SIEB2_LEER;
+ Feld[x][y+1] = EL_SIEB2_VOLL;
+ Store2[x][y+1] = EL_CHANGED2(Store2[x][y]);
+ Store2[x][y] = 0;
+ }
}
else if (SiebAktiv && CAN_CHANGE(element) &&
(Feld[x][y+1]==EL_SIEB_LEER || Feld[x][y+1]==EL_SIEB2_LEER))
if (!MovDelay[x][y]) /* neuer Schritt / noch nicht gewartet */
{
- if (element==EL_ZOMBIE || element==EL_KAEFER || element==EL_FLIEGER ||
- element==EL_BUTTERFLY || element==EL_FIREFLY)
+ /* Alle Figuren, die nach jeden Schritt die Richtung wechseln können.
+ * (MAMPFER, MAMPFER2 und PACMAN laufen bis zur nächsten Wand.)
+ */
+
+ if (element!=EL_MAMPFER && element!=EL_MAMPFER2 && element!=EL_PACMAN)
{
TurnRound(x,y);
if (MovDelay[x][y] && (element == EL_KAEFER || element == EL_FLIEGER))
{
MovDelay[x][y]--;
- if (element==EL_ZOMBIE || element==EL_MAMPFER || element==EL_MAMPFER2)
+ if (element==EL_ROBOT || element==EL_MAMPFER || element==EL_MAMPFER2)
{
int phase = MovDelay[x][y] % 8;
&& MovDelay[x][y]%4==3)
PlaySoundLevel(x,y,SND_NJAM);
}
- else if (element==EL_BUTTERFLY || element==EL_FIREFLY)
+ else if (element==EL_DRACHE)
{
- int phase = (FrameCounter % 4) / 2;
+ int i;
+ int dir = MovDir[x][y];
+ int dx = (dir == MV_LEFT ? -1 : dir == MV_RIGHT ? +1 : 0);
+ int dy = (dir == MV_UP ? -1 : dir == MV_DOWN ? +1 : 0);
+ int graphic = (dir == MV_LEFT ? GFX_FLAMMEN_LEFT :
+ dir == MV_RIGHT ? GFX_FLAMMEN_RIGHT :
+ dir == MV_UP ? GFX_FLAMMEN_UP :
+ dir == MV_DOWN ? GFX_FLAMMEN_DOWN : GFX_LEERRAUM);
+ int phase = FrameCounter % 2;
+
+ for(i=1;i<=3;i++)
+ {
+ int xx = x + i*dx, yy = y + i*dy;
+ int sx = SCROLLX(xx), sy = SCROLLY(yy);
- if (IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
- DrawGraphic(SCROLLX(x),SCROLLY(y), el2gfx(element)+phase);
+ if (!IN_LEV_FIELD(xx,yy) ||
+ IS_SOLID(Feld[xx][yy]) || Feld[xx][yy]==EL_EXPLODING)
+ break;
+
+ if (MovDelay[x][y])
+ {
+ int flamed = MovingOrBlocked2Element(xx,yy);
+
+ if (IS_ENEMY(flamed) || IS_EXPLOSIVE(flamed))
+ Bang(xx,yy);
+ else
+ RemoveMovingField(xx,yy);
+
+ Feld[xx][yy] = EL_BURNING;
+ if (IN_SCR_FIELD(sx,sy))
+ DrawGraphic(sx,sy, graphic + phase*3 + i-1);
+ }
+ else
+ {
+ if (Feld[xx][yy] == EL_BURNING)
+ Feld[xx][yy] = EL_LEERRAUM;
+ DrawLevelField(xx,yy);
+ }
+ }
}
if (MovDelay[x][y])
Moving2Blocked(x,y,&newx,&newy); /* wohin soll's gehen? */
- if (IS_PLAYER(newx,newy)) /* Spieler erwischt */
+ if (IS_ENEMY(element) && IS_PLAYER(newx,newy))
{
+ /* Spieler erwischt */
MovDir[x][y] = 0;
KillHero();
return;
}
+ else if ((element == EL_MAULWURF || element == EL_PINGUIN ||
+ element==EL_ROBOT || element==EL_SONDE) &&
+ IN_LEV_FIELD(newx,newy) &&
+ MovDir[x][y]==MV_DOWN && Feld[newx][newy]==EL_SALZSAEURE)
+ {
+ Blurb(x,y);
+ Store[x][y] = EL_SALZSAEURE;
+ }
+ else if ((element == EL_MAULWURF || element == EL_PINGUIN) &&
+ IN_LEV_FIELD(newx,newy))
+ {
+ if (Feld[newx][newy] == EL_AUSGANG_AUF)
+ {
+ Feld[x][y] = EL_LEERRAUM;
+ DrawLevelField(x,y);
+
+ PlaySoundLevel(newx,newy,SND_BUING);
+ if (IN_SCR_FIELD(SCROLLX(newx),SCROLLY(newy)))
+ DrawGraphicThruMask(SCROLLX(newx),SCROLLY(newy),el2gfx(element));
+
+ Friends--;
+ if (!Friends && PlayerGone && !GameOver)
+ LevelSolved = GameOver = TRUE;
+
+ return;
+ }
+ else if (IS_MAMPF3(Feld[newx][newy]))
+ {
+ if (DigField(newx,newy, 0,0, DF_DIG) == MF_MOVING)
+ DrawLevelField(newx,newy);
+ else
+ MovDir[x][y] = MV_NO_MOVING;
+ }
+ else if (!IS_FREE(newx,newy))
+ {
+ if (IS_PLAYER(x,y))
+ DrawPlayerField();
+ else
+ DrawLevelField(x,y);
+ return;
+ }
+ }
+ else if (element == EL_SCHWEIN && IN_LEV_FIELD(newx,newy))
+ {
+ if (IS_GEM(Feld[newx][newy]))
+ {
+ if (IS_MOVING(newx,newy))
+ RemoveMovingField(newx,newy);
+ else
+ {
+ Feld[newx][newy] = EL_LEERRAUM;
+ DrawLevelField(newx,newy);
+ }
+ }
+ else if (!IS_FREE(newx,newy))
+ {
+ if (IS_PLAYER(x,y))
+ DrawPlayerField();
+ else
+ DrawLevelField(x,y);
+ return;
+ }
+ }
+ else if (element==EL_DRACHE && IN_LEV_FIELD(newx,newy))
+ {
+ if (!IS_FREE(newx,newy))
+ {
+ if (IS_PLAYER(x,y))
+ DrawPlayerField();
+ else
+ DrawLevelField(x,y);
+ return;
+ }
+ else
+ {
+ BOOL wanna_flame = !RND(10);
+ int dx = newx - x, dy = newy - y;
+ int newx1 = newx+1*dx, newy1 = newy+1*dy;
+ int newx2 = newx+2*dx, newy2 = newy+2*dy;
+ int element1 = (IN_LEV_FIELD(newx1,newy1) ?
+ MovingOrBlocked2Element(newx1,newy1) : EL_BETON);
+ int element2 = (IN_LEV_FIELD(newx2,newy2) ?
+ MovingOrBlocked2Element(newx2,newy2) : EL_BETON);
+
+ if ((wanna_flame || IS_ENEMY(element1) || IS_ENEMY(element2)) &&
+ element1 != EL_DRACHE && element2 != EL_DRACHE &&
+ element1 != EL_BURNING && element2 != EL_BURNING)
+ {
+ if (IS_PLAYER(x,y))
+ DrawPlayerField();
+ else
+ DrawLevelField(x,y);
+
+ MovDelay[x][y] = 25;
+ Feld[newx][newy] = EL_BURNING;
+ if (IN_LEV_FIELD(newx1,newy1) && Feld[newx1][newy1] == EL_LEERRAUM)
+ Feld[newx1][newy1] = EL_BURNING;
+ if (IN_LEV_FIELD(newx2,newy2) && Feld[newx2][newy2] == EL_LEERRAUM)
+ Feld[newx2][newy2] = EL_BURNING;
+ return;
+ }
+ }
+ }
else if (element==EL_MAMPFER && IN_LEV_FIELD(newx,newy) &&
Feld[newx][newy]==EL_DIAMANT)
{
Feld[newx][newy] = EL_LEERRAUM;
DrawLevelField(newx,newy);
}
- else if (element==EL_ZOMBIE && IN_LEV_FIELD(newx,newy) &&
- MovDir[x][y]==MV_DOWN && Feld[newx][newy]==EL_SALZSAEURE)
- {
- Blurb(x,y);
- Store[x][y] = EL_SALZSAEURE;
- }
else if (!IN_LEV_FIELD(newx,newy) || !IS_FREE(newx,newy))
{ /* gegen Wand gelaufen */
TurnRound(x,y);
- if (MovDelay[x][y] && (element == EL_KAEFER || element == EL_FLIEGER))
+
+ if (element == EL_KAEFER || element == EL_FLIEGER)
DrawLevelField(x,y);
+ else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
+ DrawGraphicAnimation(x,y, el2gfx(element), 2, 2, ANIM_NORMAL);
+ else if (element==EL_SONDE)
+ DrawGraphicAnimation(x,y, GFX_SONDE_START, 8, 1, ANIM_NORMAL);
+
return;
}
- if (element==EL_ZOMBIE)
+ if (element==EL_ROBOT && IN_SCR_FIELD(x,y))
PlaySoundLevel(x,y,SND_SCHLURF);
InitMovingField(x,y,MovDir[x][y]);
if (DONT_TOUCH(element)) /* Käfer oder Flieger */
{
TestIfBadThingHitsHero();
+ TestIfBadThingHitsFriend(newx,newy);
TestIfBadThingHitsOtherBadThing(newx,newy);
}
+ else if (element == EL_PINGUIN)
+ TestIfFriendHitsBadThing(newx,newy);
if (CAN_SMASH(element) && direction==MV_DOWN &&
(newy==lev_fieldy-1 || !IS_FREE(x,newy+1)))
void SiebAktivieren(int x, int y, int typ)
{
- 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);
- }
- else
- {
- Feld[x][y] = (typ==1 ? EL_SIEB_TOT : EL_SIEB2_TOT);
- DrawLevelField(x,y);
- }
+ 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);
}
void AusgangstuerPruefen(int x, int y)
Feld[ax][ay] = EL_MAUERWERK;
}
+void CheckForDragon(int x, int y)
+{
+ int i,j;
+ BOOL dragon_found = FALSE;
+ static int xy[4][2] =
+ {
+ { 0,-1 },
+ { -1,0 },
+ { +1,0 },
+ { 0,+1 }
+ };
+
+ for(i=0;i<4;i++)
+ {
+ for(j=0;j<4;j++)
+ {
+ int xx = x + j*xy[i][0], yy = y + j*xy[i][1];
+
+ if (IN_LEV_FIELD(xx,yy) &&
+ (Feld[xx][yy] == EL_BURNING || Feld[xx][yy] == EL_DRACHE))
+ {
+ if (Feld[xx][yy] == EL_DRACHE)
+ dragon_found = TRUE;
+ }
+ else
+ break;
+ }
+ }
+
+ if (!dragon_found)
+ {
+ for(i=0;i<4;i++)
+ {
+ for(j=0;j<3;j++)
+ {
+ int xx = x + j*xy[i][0], yy = y + j*xy[i][1];
+
+ if (IN_LEV_FIELD(xx,yy) && Feld[xx][yy] == EL_BURNING)
+ {
+ Feld[xx][yy] = EL_LEERRAUM;
+ DrawLevelField(xx,yy);
+ }
+ else
+ break;
+ }
+ }
+ }
+}
+
void GameActions()
{
static long action_delay=0;
int x,y,element;
int sieb_x = 0, sieb_y = 0;
- FrameCounter++;
- TimeFrames++;
-
if (tape.pausing || (tape.playing && !TapePlayDelay()))
return;
else if (tape.recording)
TapeRecordDelay();
+ FrameCounter++;
+ TimeFrames++;
+
for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
{
Stop[x][y] = FALSE;
if (JustHit[x][y]>0)
JustHit[x][y]--;
+
+#if DEBUG
+ if (IS_BLOCKED(x,y))
+ {
+ int oldx,oldy;
+
+ Blocked2Moving(x,y,&oldx,&oldy);
+ if (!IS_MOVING(oldx,oldy))
+ {
+ printf("GameActions(): (BLOCKED=>MOVING) context corrupted!\n");
+ printf("GameActions(): BLOCKED: x = %d, y = %d\n",x,y);
+ printf("GameActions(): !MOVING: oldx = %d, oldy = %d\n",oldx,oldy);
+ printf("GameActions(): This should never happen!\n");
+ }
+ }
+#endif
+
}
for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
if (IS_INACTIVE(element))
continue;
-/*
- if (element==EL_LEERRAUM || element==EL_ERDREICH)
- continue;
-*/
-
if (!IS_MOVING(x,y) && (CAN_FALL(element) || CAN_MOVE(element)))
{
StartMoving(x,y);
MauerWaechst(x,y);
else if (element==EL_MAUER_LEBT)
MauerAbleger(x,y);
+ else if (element==EL_BURNING)
+ CheckForDragon(x,y);
if (SiebAktiv)
{
if (!(SiebAktiv%4))
PlaySoundLevel(sieb_x,sieb_y,SND_MIEP);
SiebAktiv--;
+ if (!SiebAktiv)
+ {
+ for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
+ {
+ element = Feld[x][y];
+ if (element==EL_SIEB_LEER || element==EL_SIEB_VOLL)
+ {
+ Feld[x][y] = EL_SIEB_TOT;
+ DrawLevelField(x,y);
+ }
+ else if (element==EL_SIEB2_LEER || element==EL_SIEB2_VOLL)
+ {
+ Feld[x][y] = EL_SIEB2_TOT;
+ DrawLevelField(x,y);
+ }
+ }
+ }
}
}
if (dx)
{
- x = dx==1 ? 0 : SCR_FIELDX-1;
+ x = (dx==1 ? 0 : SCR_FIELDX-1);
for(y=0;y<SCR_FIELDY;y++)
DrawScreenField(x,y);
}
if (dy)
{
- y = dy==1 ? 0 : SCR_FIELDY-1;
- for(x=0;x<SCR_FIELDY;x++)
+ y = (dy==1 ? 0 : SCR_FIELDY-1);
+ for(x=0;x<SCR_FIELDX;x++)
DrawScreenField(x,y);
}
int element;
int can_move;
- if (GameOver || (!dx && !dy))
+/*
+ int old_move_dir = PlayerMovDir;
+*/
+
+ if (PlayerGone || (!dx && !dy))
return(MF_NO_ACTION);
+
+ PlayerMovDir = (dx < 0 ? MV_LEFT :
+ dx > 0 ? MV_RIGHT :
+ dy < 0 ? MV_UP :
+ dy > 0 ? MV_DOWN : MV_NO_MOVING);
+/*
+ if (old_move_dir != PlayerMovDir)
+ PlayerFrame = 0;
+ else
+ PlayerFrame = (PlayerFrame + 1) % 4;
+*/
+
if (!IN_LEV_FIELD(newJX,newJY))
return(MF_NO_ACTION);
InitMovingField(JX,JY,MV_DOWN);
Store[JX][JY] = EL_SALZSAEURE;
ContinueMoving(JX,JY);
-
- PlaySoundLevel(JX,JY,SND_AUTSCH);
- PlaySoundLevel(JX,JY,SND_LACHEN);
- GameOver = TRUE;
- JX = JY = -1;
+ BuryHero();
}
else
KillHero();
{
static long move_delay = 0;
int moved = MF_NO_ACTION;
+ int oldJX = JX, oldJY = JY;
- if (GameOver || (!dx && !dy))
+ if (PlayerGone || (!dx && !dy))
return(FALSE);
/*
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_x!=old_scroll_x || scroll_y!=old_scroll_y)
ScrollLevel(old_scroll_x-scroll_x,old_scroll_y-scroll_y);
+ }
- if (Feld[JX][JY]==EL_LEERRAUM)
- DrawLevelElement(JX,JY,EL_SPIELFIGUR);
- else
- DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR);
+ if (!(moved & MF_MOVING) && !PlayerPushing)
+ PlayerFrame = 0;
+ else
+ PlayerFrame = (PlayerFrame + 1) % 4;
+
+ if (moved & MF_MOVING)
+ {
+ if (oldJX != JX && oldJY == JY)
+ PlayerMovDir = (oldJX < JX ? MV_RIGHT : MV_LEFT);
+ else if (oldJX == JX && oldJY != JY)
+ PlayerMovDir = (oldJY < JY ? MV_DOWN : MV_UP);
+
+ DrawLevelField(JX,JY); /* für "ErdreichAnbroeckeln()" */
}
TestIfHeroHitsBadThing();
BackToFront();
-/*
- if (LevelSolved)
- GameWon();
-*/
+ if (PlayerGone)
+ RemoveHero();
return(moved);
}
-void TestIfHeroHitsBadThing()
+void TestIfGoodThingHitsBadThing(int goodx, int goody)
{
- int i, killx = JX,killy = JY;
+ int i, killx = goodx, killy = goody;
static int xy[4][2] =
{
{ 0,-1 },
{
int x,y,element;
- x = JX+xy[i][0];
- y = JY+xy[i][1];
+ x = goodx+xy[i][0];
+ y = goody+xy[i][1];
if (!IN_LEV_FIELD(x,y))
continue;
}
}
- if (killx!=JX || killy!=JY)
- KillHero();
+ if (killx!=goodx || killy!=goody)
+ {
+ if (IS_PLAYER(goodx,goody))
+ KillHero();
+ else
+ Bang(goodx,goody);
+ }
+}
+
+void TestIfBadThingHitsGoodThing(int badx, int bady)
+{
+ int i, killx = badx, killy = bady;
+ static int xy[4][2] =
+ {
+ { 0,-1 },
+ { -1,0 },
+ { +1,0 },
+ { 0,+1 }
+ };
+ static int harmless[4] =
+ {
+ MV_UP,
+ MV_LEFT,
+ MV_RIGHT,
+ MV_DOWN
+ };
+
+ for(i=0;i<4;i++)
+ {
+ int x,y,element;
+
+ x = badx+xy[i][0];
+ y = bady+xy[i][1];
+ if (!IN_LEV_FIELD(x,y))
+ continue;
+
+ element = Feld[x][y];
+
+ if (element==EL_PINGUIN)
+ {
+ if (MovDir[x][y]==harmless[i] && IS_MOVING(x,y))
+ continue;
+
+ killx = x;
+ killy = y;
+ break;
+ }
+ }
+
+ if (killx!=badx || killy!=bady)
+ Bang(killx,killy);
+}
+
+void TestIfHeroHitsBadThing()
+{
+ TestIfGoodThingHitsBadThing(JX,JY);
}
void TestIfBadThingHitsHero()
{
- TestIfHeroHitsBadThing();
+ TestIfGoodThingHitsBadThing(JX,JY);
+ /* (no typo!) */
+}
+
+void TestIfFriendHitsBadThing(int x, int y)
+{
+ TestIfGoodThingHitsBadThing(x,y);
+}
+
+void TestIfBadThingHitsFriend(int x, int y)
+{
+ TestIfBadThingHitsGoodThing(x,y);
}
void TestIfBadThingHitsOtherBadThing(int badx, int bady)
void KillHero()
{
- if (IS_PLAYER(-1,-1))
+ if (PlayerGone)
return;
if (IS_PFORTE(Feld[JX][JY]))
Feld[JX][JY] = EL_LEERRAUM;
+ Bang(JX,JY);
+ BuryHero();
+}
+
+void BuryHero()
+{
+ if (PlayerGone)
+ return;
+
PlaySoundLevel(JX,JY,SND_AUTSCH);
PlaySoundLevel(JX,JY,SND_LACHEN);
- Bang(JX,JY);
+
GameOver = TRUE;
- ZX = JX;
- ZY = JY;
+ RemoveHero();
+}
+
+void RemoveHero()
+{
+ PlayerGone = TRUE;
+
+ ExitX = ZX = JX;
+ ExitY = ZY = JY;
JX = JY = -1;
}
static long push_delay = 0;
static int push_delay_value = 5;
+ PlayerPushing = FALSE;
+
if (mode == DF_NO_PUSH)
{
push_delay = 0;
{
case EL_LEERRAUM:
break;
+
case EL_ERDREICH:
Feld[x][y] = EL_LEERRAUM;
break;
+
case EL_EDELSTEIN:
case EL_EDELSTEIN_BD:
case EL_EDELSTEIN_GELB:
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;
Gems -= 3;
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;
Dynamite++;
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;
DynaBombCount++;
PlaySoundLevel(x,y,SND_PONG);
break;
case EL_DYNABOMB_SZ:
+
Feld[x][y] = EL_LEERRAUM;
DynaBombSize++;
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:
case EL_SCHLUESSEL2:
case EL_SCHLUESSEL3:
PlaySoundLevel(x,y,SND_PONG);
break;
}
+
case EL_ABLENK_AUS:
Feld[x][y] = EL_ABLENK_EIN;
- ZX=x;
- ZY=y;
+ ZX = x;
+ ZY = y;
DrawLevelField(x,y);
return(MF_ACTION);
break;
+
case EL_FELSBROCKEN:
case EL_BOMBE:
case EL_KOKOSNUSS:
case EL_ZEIT_LEER:
- if (mode==DF_SNAP)
+ if (dy || mode==DF_SNAP)
return(MF_NO_ACTION);
- if (dy || !IN_LEV_FIELD(x+dx,y+dy) || Feld[x+dx][y+dy] != EL_LEERRAUM)
+
+ PlayerPushing = TRUE;
+
+ if (!IN_LEV_FIELD(x+dx,y+dy) || Feld[x+dx][y+dy] != EL_LEERRAUM)
return(MF_NO_ACTION);
if (real_dy)
else
PlaySoundLevel(x+dx,y+dy,SND_KLOPF);
break;
+
case EL_PFORTE1:
case EL_PFORTE2:
case EL_PFORTE3:
if (!Key[element-EL_PFORTE1])
return(MF_NO_ACTION);
break;
+
case EL_PFORTE1X:
case EL_PFORTE2X:
case EL_PFORTE3X:
if (!Key[element-EL_PFORTE1X])
return(MF_NO_ACTION);
break;
+
case EL_AUSGANG_ZU:
case EL_AUSGANG_ACT:
/* Tür ist (noch) nicht offen! */
return(MF_NO_ACTION);
break;
+
case EL_AUSGANG_AUF:
if (mode==DF_SNAP)
return(MF_NO_ACTION);
- LevelSolved = GameOver = TRUE;
+
+ PlayerGone = TRUE;
PlaySoundLevel(x,y,SND_BUING);
+
+ if (!Friends)
+ LevelSolved = GameOver = TRUE;
+
break;
+
case EL_BIRNE_AUS:
Feld[x][y] = EL_BIRNE_EIN;
Lights--;
PlaySoundLevel(x,y,SND_DENG);
return(MF_ACTION);
break;
+
case EL_ZEIT_VOLL:
Feld[x][y] = EL_ZEIT_LEER;
TimeLeft += 10;
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:
+ case EL_SONDE:
if (mode==DF_SNAP)
return(MF_NO_ACTION);
+
+ PlayerPushing = TRUE;
+
if (!IN_LEV_FIELD(x+dx,y+dy)
|| (Feld[x+dx][y+dy] != EL_LEERRAUM
- && Feld[x+dx][y+dy] != EL_SOKOBAN_FELD_LEER))
+ && (Feld[x+dx][y+dy] != EL_SOKOBAN_FELD_LEER
+ || !IS_SB_ELEMENT(element))))
return(MF_NO_ACTION);
if (dx && real_dy)
if (!FrameReached(&push_delay,push_delay_value) && !tape.playing)
return(MF_NO_ACTION);
- if (element == EL_SOKOBAN_FELD_VOLL)
+ if (IS_SB_ELEMENT(element))
{
- Feld[x][y] = EL_SOKOBAN_FELD_LEER;
- SokobanFields++;
+ 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;
}
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);
+ Feld[x][y] = EL_LEERRAUM;
+ Feld[x+dx][y+dy] = element;
}
- else
- Feld[x+dx][y+dy] = EL_SOKOBAN_OBJEKT;
push_delay_value = 2;
DrawLevelField(x+dx,y+dy);
PlaySoundLevel(x+dx,y+dy,SND_PUSCH);
- if (SokobanFields == 0 && game_emulation == EMU_SOKOBAN)
+ if (IS_SB_ELEMENT(element) &&
+ SokobanFields == 0 && game_emulation == EMU_SOKOBAN)
{
LevelSolved = GameOver = TRUE;
PlaySoundLevel(x,y,SND_BUING);
}
break;
+
+ case EL_MAULWURF:
+ case EL_PINGUIN:
+ case EL_SCHWEIN:
+ case EL_DRACHE:
+ break;
+
default:
return(MF_NO_ACTION);
break;
int x = JX+dx, y = JY+dy;
static int snapped = FALSE;
- if (GameOver || !IN_LEV_FIELD(x,y))
+ if (PlayerGone || !IN_LEV_FIELD(x,y))
return(FALSE);
if (dx && dy)
return(FALSE);
if (snapped)
return(FALSE);
+ PlayerMovDir = (dx < 0 ? MV_LEFT :
+ dx > 0 ? MV_RIGHT :
+ dy < 0 ? MV_UP :
+ dy > 0 ? MV_DOWN : MV_NO_MOVING);
+
if (!DigField(x,y, 0,0, DF_SNAP))
return(FALSE);
{
int element;
- if (GameOver)
+ if (PlayerGone)
return(FALSE);
element = Feld[JX][JY];
element==EL_DYNAMIT || element==EL_DYNABOMB || element==EL_EXPLODING)
return(FALSE);
- if (element!=EL_LEERRAUM)
+ if (element != EL_LEERRAUM)
Store[JX][JY] = element;
if (Dynamite)
{
int sx = SCROLLX(x), sy = SCROLLY(y);
int volume, stereo;
+ int silence_distance = 8;
if ((!sound_simple_on && !IS_LOOP_SOUND(sound_nr)) ||
(!sound_loops_on && IS_LOOP_SOUND(sound_nr)))
return;
- if (!IN_LEV_FIELD(x,y))
+ if (!IN_LEV_FIELD(x,y) ||
+ sx < -silence_distance || sx >= SCR_FIELDX+silence_distance ||
+ sy < -silence_distance || sy >= SCR_FIELDY+silence_distance)
return;
volume = PSND_MAX_VOLUME;
if (!IN_SCR_FIELD(sx,sy))
{
- if (sx<0 || sx>=SCR_FIELDX)
- volume = PSND_MAX_VOLUME - 2*ABS(sx-SCR_FIELDX/2);
- else
- volume = PSND_MAX_VOLUME - 2*ABS(sy-SCR_FIELDY/2);
+ int dx = ABS(sx-SCR_FIELDX/2)-SCR_FIELDX/2;
+ int dy = ABS(sy-SCR_FIELDY/2)-SCR_FIELDY/2;
+
+ volume -= volume*(dx > dy ? dx : dy)/silence_distance;
}
PlaySoundExt(sound_nr, volume, stereo, PSND_NO_LOOP);
case EL_MAMPFER2:
RaiseScore(level.score[SC_MAMPFER]);
break;
- case EL_ZOMBIE:
- RaiseScore(level.score[SC_ZOMBIE]);
+ case EL_ROBOT:
+ RaiseScore(level.score[SC_ROBOT]);
break;
case EL_PACMAN:
RaiseScore(level.score[SC_PACMAN]);
void ScrollLevel(int, int);
BOOL MoveFigureOneStep(int, int, int, int);
BOOL MoveFigure(int, int);
+void TestIfGoodThingHitsBadThing(int, int);
+void TestIfBadThingHitsGoodThing(int, int);
void TestIfHeroHitsBadThing(void);
void TestIfBadThingHitsHero(void);
+void TestIfFriendHitsBadThing(int, int);
+void TestIfBadThingHitsFriend(int, int);
void TestIfBadThingHitsOtherBadThing(int, int);
void KillHero(void);
+void BuryHero(void);
+void RemoveHero(void);
int DigField(int, int, int, int, int);
BOOL SnapField(int, int);
BOOL PlaceBomb(void);
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* ©1995 Artsoft Development *
+* Holger Schemel *
+* 33659 Bielefeld-Senne *
+* Telefon: (0521) 493245 *
+* eMail: aeglos@valinor.owl.de *
+* aeglos@uni-paderborn.de *
+* q99492@pbhrzx.uni-paderborn.de *
+*----------------------------------------------------------*
+* gfxloader.c *
+***********************************************************/
+
+#include "gfxloader.h"
+
+#ifdef DEBUG
+/*
+#define DEBUG_GIF
+#define DEBUG_ILBM
+*/
+#endif
+
+struct IFF_ILBM_FORM_big_endian
+{
+ char magic_FORM[4];
+ unsigned char chunk_size[4];
+ char magic_ILBM[4];
+};
+
+struct IFF_ILBM_BMHD_big_endian
+{
+ char Width[2], Height[2];
+ char LeftEdge[2], TopEdge[2];
+ char Depth;
+ char Mask;
+ char Compression;
+ char pad1;
+ char transparentColor[2];
+ char xAspect, yAspect;
+ char pageWidth[2], pageHeight[2];
+};
+
+struct IFF_ILBM_BMHD
+{
+ unsigned int Width, Height;
+ int LeftEdge, TopEdge;
+ unsigned int Depth;
+ unsigned int Mask;
+ unsigned int Compression;
+ unsigned char pad1;
+ unsigned int transparentColor;
+ unsigned int xAspect, yAspect;
+ int pageWidth, pageHeight;
+};
+
+static int ConvertXImageDepth(Display *, XImage **);
+static int Read_GIF_to_Pixmap_or_Bitmap(Display *, char *, Pixmap *, int);
+
+#define READ_GIF_TO_BITMAP 0
+#define READ_GIF_TO_PIXMAP 1
+
+
+int Read_GIF_to_Bitmap(Display *display, char *filename, Pixmap *pixmap)
+{
+ return(Read_GIF_to_Pixmap_or_Bitmap(display, filename,
+ pixmap, READ_GIF_TO_BITMAP));
+}
+
+int Read_GIF_to_Pixmap(Display *display, char *filename, Pixmap *pixmap)
+{
+ return(Read_GIF_to_Pixmap_or_Bitmap(display, filename,
+ pixmap, READ_GIF_TO_PIXMAP));
+}
+
+int Read_GIF_to_Pixmap_or_Bitmap(Display *display, char *filename,
+ Pixmap *pixmap, int mode)
+{
+ XImage *image = NULL;
+ Pixmap new_pixmap = 0;
+ int return_code;
+
+ *pixmap = 0;
+ return_code = Read_GIF_to_XImage(display, filename, &image);
+ if (return_code != GIF_Success)
+ return(return_code);
+
+ if (image)
+ {
+ int screen = DefaultScreen(display);
+ Drawable root = RootWindow(display,screen);
+ int depth = DefaultDepth(display, screen);
+ int width = image->width;
+ int height = image->height;
+
+ if (mode == READ_GIF_TO_BITMAP)
+ {
+ int i,x,y;
+ unsigned long black_pixel = BlackPixel(display,screen);
+ int bytes_per_line = (width+7) / 8;
+ int size = bytes_per_line * height;
+ char *data, *ptr;
+
+ data = (char *)malloc(size);
+ if (!data)
+ return(GIF_NoMemory);
+
+ ptr = data;
+ for(i=0;i<size;i++)
+ *ptr++ = 0;
+
+ for(y=0;y<height;y++)
+ {
+ for(x=0;x<width;x++)
+ {
+ if (XGetPixel(image,x,y) == black_pixel)
+ data[y * bytes_per_line + x/8] |= (1 << (x%8));
+ }
+ }
+
+ new_pixmap = XCreateBitmapFromData(display,root,data,width,height);
+ free(data);
+
+ if (!new_pixmap)
+ return(GIF_NoMemory);
+ }
+ else
+ {
+ GC gc;
+ XGCValues gcv;
+
+ if (ConvertXImageDepth(display, &image) != GIF_Success)
+ return(GIF_ColorFailed);
+
+ new_pixmap = XCreatePixmap(display,root,width,height,depth);
+
+ if (!new_pixmap)
+ return(GIF_NoMemory);
+
+ gcv.foreground = BlackPixel(display,screen);
+ gcv.background = WhitePixel(display,screen);
+ gc = XCreateGC(display, root, GCForeground | GCBackground, &gcv);
+ XPutImage(display,new_pixmap,gc,image,0,0,0,0,width,height);
+ XFreeGC(display, gc);
+ }
+
+ XDestroyImage(image);
+ }
+
+ *pixmap = new_pixmap;
+ return(return_code);
+}
+
+
+/*
+ * Read_GIF_to_XImage() - based strongly on...
+ *
+ * xgifload.c - based strongly on...
+ *
+ * gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image.
+ *
+ * Copyright (c) 1988, 1989 by Patrick J. Naughton
+ *
+ * Author: Patrick J. Naughton
+ * naughton@wind.sun.com
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind. The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof. In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ *
+ */
+
+typedef int boolean;
+typedef unsigned char byte;
+
+static int ReadCode(void);
+static void AddToPixel(byte);
+static int ColorDicking(Display *);
+
+#define NEXTBYTE (*ptr++)
+#define IMAGESEP 0x2c
+#define INTERLACEMASK 0x40
+#define COLORMAPMASK 0x80
+
+static
+int BitOffset, /* Bit Offset of next code */
+ XC, YC, /* Output X and Y coords of current pixel */
+ Pass, /* Used by output routine if interlaced pic */
+ OutCount, /* Decompressor output 'stack count' */
+ RWidth, RHeight, /* screen dimensions */
+ Width, Height, /* image dimensions */
+ LeftOfs, TopOfs, /* image offset */
+ BitsPerPixel, /* Bits per pixel, read from GIF header */
+ BytesPerScanline, /* bytes per scanline in output raster */
+ ColorMapSize, /* number of colors */
+ Background, /* background color */
+ CodeSize, /* Code size, read from GIF header */
+ InitCodeSize, /* Starting code size, used during Clear */
+ Code, /* Value returned by ReadCode */
+ MaxCode, /* limiting value for current code size */
+ ClearCode, /* GIF clear code */
+ EOFCode, /* GIF end-of-information code */
+ CurCode, OldCode, InCode, /* Decompressor variables */
+ FirstFree, /* First free code, generated per GIF spec */
+ FreeCode, /* Decompressor, next free slot in hash table*/
+ FinChar, /* Decompressor variable */
+ BitMask, /* AND mask for data size */
+ ReadMask; /* Code AND mask for current code size */
+
+static boolean Interlace, HasColormap;
+
+static byte *ImageData; /* The result array */
+static byte *RawGIF; /* The heap array to hold it, raw */
+static byte *Raster; /* The raster data stream, unblocked */
+
+/* The color map, read from the GIF header */
+static byte Red[256], Green[256], Blue[256], used[256];
+static int numused;
+
+extern char *progname;
+
+static int numcols;
+static unsigned long cols[256];
+static XColor defs[256];
+
+int Read_GIF_to_XImage(Display *display, char *filename, XImage **image)
+{
+ int filesize;
+ register byte ch, ch1;
+ register byte *ptr, *ptr1;
+ register int i;
+ int screen = DefaultScreen(display);
+ Visual *visual = DefaultVisual(display,screen);
+ XImage *new_image = NULL;
+ char *id = "GIF87a";
+ FILE *file;
+ int Prefix[4096]; /* The hash table used by the decompressor */
+ int Suffix[4096];
+ int OutCode[1025]; /* An output array used by the decompressor */
+
+ BitOffset = XC = YC = Pass = OutCount = 0;
+ *image = NULL;
+
+ if (strcmp(filename,"-")==0)
+ {
+ file = stdin;
+ filename = "<stdin>";
+ }
+ else
+ file = fopen(filename,"r");
+
+ if (!file)
+ return(GIF_OpenFailed);
+
+ /* find the size of the file */
+ fseek(file, 0L, 2);
+ filesize = ftell(file);
+ fseek(file, 0L, 0);
+
+ if (!(ptr = RawGIF = (byte *) malloc(filesize)))
+ return(GIF_NoMemory);
+
+ if (!(Raster = (byte *) malloc(filesize)))
+ return(GIF_NoMemory);
+
+ if (fread(ptr, filesize, 1, file) != 1)
+ return(GIF_ReadFailed);
+
+ if (strncmp(ptr, id, 6))
+ return(GIF_FileInvalid);
+
+ ptr += 6;
+
+ /* Get variables from the GIF screen descriptor */
+
+ ch = NEXTBYTE;
+ RWidth = ch + 0x100 * NEXTBYTE; /* screen dimensions... not used. */
+ ch = NEXTBYTE;
+ RHeight = ch + 0x100 * NEXTBYTE;
+
+ ch = NEXTBYTE;
+ HasColormap = ((ch & COLORMAPMASK) ? True : False);
+
+ BitsPerPixel = (ch & 7) + 1;
+ numcols = ColorMapSize = 1 << BitsPerPixel;
+ BitMask = ColorMapSize - 1;
+
+ Background = NEXTBYTE; /* background color... not used. */
+
+ if (NEXTBYTE) /* supposed to be NULL */
+ return(GIF_FileInvalid);
+
+ /* Read in global colormap. */
+
+ if (HasColormap)
+ {
+ for (i = 0; i < ColorMapSize; i++)
+ {
+ Red[i] = NEXTBYTE;
+ Green[i] = NEXTBYTE;
+ Blue[i] = NEXTBYTE;
+ used[i] = 0;
+ }
+ numused = 0;
+ }
+ else
+ {
+ /* no colormap in GIF file */
+ fprintf(stderr,"%s: warning! no colortable in this file. Winging it.\n",
+ progname);
+ if (!numcols)
+ numcols=256;
+ for (i=0; i<numcols; i++)
+ cols[i] = (unsigned long) i;
+ }
+
+ /* Check for image seperator */
+
+ if (NEXTBYTE != IMAGESEP)
+ return(GIF_FileInvalid);
+
+ /* Now read in values from the image descriptor */
+
+ ch = NEXTBYTE;
+ LeftOfs = ch + 0x100 * NEXTBYTE;
+ ch = NEXTBYTE;
+ TopOfs = ch + 0x100 * NEXTBYTE;
+ ch = NEXTBYTE;
+ Width = ch + 0x100 * NEXTBYTE;
+ ch = NEXTBYTE;
+ Height = ch + 0x100 * NEXTBYTE;
+ Interlace = ((NEXTBYTE & INTERLACEMASK) ? True : False);
+
+#ifdef DEBUG_GIF
+ fprintf(stderr, "%s:\n", filename);
+ fprintf(stderr, " %dx%d, %d bpp / %d colors, %sinterlaced\n",
+ Width,Height, BitsPerPixel,ColorMapSize,(Interlace ? "" : "non-"));
+ fprintf(stderr, " Reading file... ");
+#endif
+
+ /* Note that I ignore the possible existence of a local color map.
+ * I'm told there aren't many files around that use them, and the spec
+ * says it's defined for future use. This could lead to an error
+ * reading some files.
+ */
+
+ /* Start reading the raster data. First we get the intial code size
+ * and compute decompressor constant values, based on this code size.
+ */
+
+ CodeSize = NEXTBYTE;
+ ClearCode = (1 << CodeSize);
+ EOFCode = ClearCode + 1;
+ FreeCode = FirstFree = ClearCode + 2;
+
+ /* The GIF spec has it that the code size is the code size used to
+ * compute the above values is the code size given in the file, but the
+ * code size used in compression/decompression is the code size given in
+ * the file plus one. (thus the ++).
+ */
+
+ CodeSize++;
+ InitCodeSize = CodeSize;
+ MaxCode = (1 << CodeSize);
+ ReadMask = MaxCode - 1;
+
+ /* Read the raster data. Here we just transpose it from the GIF array
+ * to the Raster array, turning it from a series of blocks into one long
+ * data stream, which makes life much easier for ReadCode().
+ */
+
+ ptr1 = Raster;
+ do
+ {
+ ch = ch1 = NEXTBYTE;
+ while (ch--) *ptr1++ = NEXTBYTE;
+ if ((Raster - ptr1) > filesize)
+ return(GIF_FileInvalid);
+ }
+ while(ch1);
+
+ free(RawGIF); /* We're done with the raw data now... */
+
+#ifdef DEBUG_GIF
+ fprintf(stderr, "done\n");
+ fprintf(stderr, " Decompressing... ");
+#endif
+
+ /* Allocate the X Image */
+ ImageData = (byte *) malloc(Width*Height);
+ if (!ImageData)
+ return(GIF_NoMemory);
+
+ new_image = XCreateImage(display,visual,8,ZPixmap,0,ImageData,
+ Width,Height,8,Width);
+ if (!new_image)
+ return(GIF_NoMemory);
+
+ BytesPerScanline = Width;
+
+
+ /* Decompress the file, continuing until you see the GIF EOF code.
+ * One obvious enhancement is to add checking for corrupt files here.
+ */
+
+ Code = ReadCode();
+ while (Code != EOFCode)
+ {
+ /* Clear code sets everything back to its initial value, then reads the
+ * immediately subsequent code as uncompressed data.
+ */
+
+ if (Code == ClearCode)
+ {
+ CodeSize = InitCodeSize;
+ MaxCode = (1 << CodeSize);
+ ReadMask = MaxCode - 1;
+ FreeCode = FirstFree;
+ CurCode = OldCode = Code = ReadCode();
+ FinChar = CurCode & BitMask;
+ AddToPixel(FinChar);
+ }
+ else
+ {
+ /* If not a clear code, then must be data:
+ * save same as CurCode and InCode
+ */
+
+ CurCode = InCode = Code;
+
+ /* If greater or equal to FreeCode, not in the hash table yet;
+ * repeat the last character decoded
+ */
+
+ if (CurCode >= FreeCode)
+ {
+ CurCode = OldCode;
+ OutCode[OutCount++] = FinChar;
+ }
+
+ /* Unless this code is raw data, pursue the chain pointed to by CurCode
+ * through the hash table to its end; each code in the chain puts its
+ * associated output code on the output queue.
+ */
+
+ while (CurCode > BitMask)
+ {
+ if (OutCount > 1024)
+ return(GIF_FileInvalid);
+
+ OutCode[OutCount++] = Suffix[CurCode];
+ CurCode = Prefix[CurCode];
+ }
+
+ /* The last code in the chain is treated as raw data. */
+
+ FinChar = CurCode & BitMask;
+ OutCode[OutCount++] = FinChar;
+
+ /* Now we put the data out to the Output routine.
+ * It's been stacked LIFO, so deal with it that way...
+ */
+
+ for (i = OutCount - 1; i >= 0; i--)
+ AddToPixel(OutCode[i]);
+ OutCount = 0;
+
+ /* Build the hash table on-the-fly. No table is stored in the file. */
+
+ Prefix[FreeCode] = OldCode;
+ Suffix[FreeCode] = FinChar;
+ OldCode = InCode;
+
+ /* Point to the next slot in the table. If we exceed the current
+ * MaxCode value, increment the code size unless it's already 12. If it
+ * is, do nothing: the next code decompressed better be CLEAR
+ */
+
+ FreeCode++;
+ if (FreeCode >= MaxCode)
+ {
+ if (CodeSize < 12)
+ {
+ CodeSize++;
+ MaxCode *= 2;
+ ReadMask = (1 << CodeSize) - 1;
+ }
+ }
+ }
+ Code = ReadCode();
+ }
+
+ free(Raster);
+
+#ifdef DEBUG_GIF
+ fprintf(stderr, "done\n");
+ fprintf(stderr," %d colors used\n",numused);
+#endif
+
+ if (file != stdin)
+ fclose(file);
+
+ if (ColorDicking(display) != GIF_Success)
+ return(GIF_ColorFailed);
+
+ *image = new_image;
+ return(GIF_Success);
+}
+
+
+/* Fetch the next code from the raster data stream. The codes can be
+ * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to
+ * maintain our location in the Raster array as a BIT Offset. We compute
+ * the byte Offset into the raster array by dividing this by 8, pick up
+ * three bytes, compute the bit Offset into our 24-bit chunk, shift to
+ * bring the desired code to the bottom, then mask it off and return it.
+ */
+
+static int ReadCode()
+{
+ int RawCode, ByteOffset;
+
+ ByteOffset = BitOffset / 8;
+ RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]);
+ if (CodeSize >= 8)
+ RawCode += (0x10000 * Raster[ByteOffset + 2]);
+ RawCode >>= (BitOffset % 8);
+ BitOffset += CodeSize;
+ return(RawCode & ReadMask);
+}
+
+
+static void AddToPixel(byte Index)
+{
+ if (YC<Height)
+ *(ImageData + YC * BytesPerScanline + XC) = Index;
+
+ if (!used[Index])
+ {
+ used[Index]=1;
+ numused++;
+ }
+
+ /* Update the X-coordinate, and if it overflows, update the Y-coordinate */
+
+ if (++XC == Width)
+ {
+ /* If a non-interlaced picture, just increment YC to the next scan line.
+ * If it's interlaced, deal with the interlace as described in the GIF
+ * spec. Put the decoded scan line out to the screen if we haven't gone
+ * past the bottom of it
+ */
+
+ XC = 0;
+ if (!Interlace)
+ YC++;
+ else
+ {
+ switch (Pass)
+ {
+ case 0:
+ YC += 8;
+ if (YC >= Height)
+ {
+ Pass++;
+ YC = 4;
+ }
+ break;
+
+ case 1:
+ YC += 8;
+ if (YC >= Height)
+ {
+ Pass++;
+ YC = 2;
+ }
+ break;
+
+ case 2:
+ YC += 4;
+ if (YC >= Height)
+ {
+ Pass++;
+ YC = 1;
+ }
+ break;
+
+ case 3:
+ YC += 2;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+}
+
+
+static int ColorDicking(Display *display)
+{
+ /* we've got the picture loaded, we know what colors are needed. get 'em */
+
+ register int i,j;
+ static byte lmasks[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};
+ byte lmask, *ptr;
+ int screen = DefaultScreen(display);
+ Colormap cmap = DefaultColormap(display,screen);
+ int dispcells = DisplayCells(display,screen);
+
+ int strip = 0;
+ int nostrip = 0;
+
+ if (!HasColormap)
+ return(GIF_Success);
+ /* no need to allocate any colors if no colormap in GIF file */
+
+ /* Allocate the X colors for this picture */
+
+ if (nostrip)
+ {
+ /* nostrip was set. try REAL hard to do it */
+ for (i=j=0; i<numcols; i++)
+ {
+ if (used[i])
+ {
+ defs[i].red = Red[i]<<8;
+ defs[i].green = Green[i]<<8;
+ defs[i].blue = Blue[i]<<8;
+ defs[i].flags = DoRed | DoGreen | DoBlue;
+ if (!XAllocColor(display,cmap,&defs[i]))
+ {
+ j++;
+ defs[i].pixel = 0xffff;
+ }
+ cols[i] = defs[i].pixel;
+ }
+ }
+
+ if (j)
+ {
+ /* failed to pull it off */
+
+ XColor ctab[256];
+ int dc;
+
+ dc = (dispcells<256) ? dispcells : 256;
+
+ fprintf(stderr,
+ "failed to allocate %d out of %d colors. Trying extra hard.\n",
+ j,numused);
+
+ /* read in the color table */
+ for (i=0; i<dc; i++)
+ ctab[i].pixel = i;
+ XQueryColors(display,cmap,ctab,dc);
+
+ /* run through the used colors. any used color that has a pixel
+ value of 0xffff wasn't allocated. for such colors, run through
+ the entire X colormap and pick the closest color */
+
+ for (i=0; i<numcols; i++)
+ if (used[i] && cols[i]==0xffff)
+ {
+ /* an unallocated pixel */
+
+ int d, mdist, close;
+ unsigned long r,g,b;
+
+ mdist = 100000; close = -1;
+ r = Red[i];
+ g = Green[i];
+ b = Blue[i];
+ for (j=0; j<dc; j++)
+ {
+ d = abs(r - (ctab[j].red>>8)) +
+ abs(g - (ctab[j].green>>8)) +
+ abs(b - (ctab[j].blue>>8));
+ if (d<mdist)
+ {
+ mdist=d;
+ close=j;
+ }
+ }
+
+ if (close<0)
+ return(GIF_ColorFailed);
+
+ bcopy(&defs[close],&defs[i],sizeof(XColor));
+ cols[i] = ctab[close].pixel;
+ }
+ } /* end 'failed to pull it off' */
+ }
+ else
+ {
+ /* strip wasn't set, do the best auto-strip */
+
+ j = 0;
+ while (strip<8)
+ {
+ lmask = lmasks[strip];
+ for (i=0; i<numcols; i++)
+ {
+ if (used[i])
+ {
+ defs[i].red = (Red[i] &lmask)<<8;
+ defs[i].green = (Green[i]&lmask)<<8;
+ defs[i].blue = (Blue[i] &lmask)<<8;
+ defs[i].flags = DoRed | DoGreen | DoBlue;
+ if (!XAllocColor(display,cmap,&defs[i]))
+ break;
+ cols[i] = defs[i].pixel;
+ }
+ }
+
+ if (i<numcols)
+ {
+ /* failed */
+ strip++;
+ j++;
+ for (i--; i>=0; i--)
+ if (used[i])
+ XFreeColors(display,cmap,cols+i,1,0L);
+ }
+ else
+ break;
+ }
+
+#ifdef DEBUG_GIF
+ if (j && strip<8)
+ fprintf(stderr,"%s: stripped %d bits\n",progname,strip);
+#endif
+
+ if (strip==8)
+ {
+ fprintf(stderr,"UTTERLY failed to allocate the desired colors.\n");
+ for (i=0; i<numcols; i++) cols[i]=i;
+ }
+ }
+
+ ptr = ImageData;
+ for (i=0; i<Height; i++)
+ for (j=0; j<Width; j++,ptr++)
+ *ptr = (byte) cols[*ptr];
+
+ return(GIF_Success);
+}
+
+
+/******************************************************************************
+ * This makes sure the display's depth is the same as the
+ * depth of the default 8 bit image. If not, we build a new image
+ * that has the correct depth. This works on the fact that
+ * the color mapper has already changed every pixel value in the
+ * image into the proper number of bits (to fit into the pallet)
+ * so we can just chop down the number of bits.
+ * This changes the global variable 'expImage' if necessary.
+ */
+
+static int ConvertXImageDepth(Display *display, XImage **image)
+{
+ int screen = DefaultScreen(display);
+ int depth = DefaultDepth(display, screen);
+
+ if ((*image)->depth != depth)
+ {
+ XImage *old_image, *new_image;
+ Visual *visual = DefaultVisual(display,screen);
+ int width = (*image)->width;
+ int height = (*image)->height;
+ register int dwx, dwy;
+ byte *data;
+
+ data = (byte *)malloc(width * height);
+ old_image = *image;
+ new_image = XCreateImage(display,visual,depth,
+ ZPixmap,0,data,width,height,8,0);
+ if (!new_image)
+ return(GIF_NoMemory);
+
+ if (old_image->depth == 8 && new_image->depth == 4)
+ {
+ /* speedup for the most common format change */
+
+ register byte *sptr = (byte *)old_image->data;
+ register byte *dptr = (byte *)new_image->data;
+
+ for (dwy=1; dwy<=height; dwy++)
+ {
+ for (dwx=1; dwx<width; dwx+=2)
+ {
+ *dptr = (*sptr) | (*(sptr+1)<<4);
+ dptr++;
+ sptr+=2;
+ }
+ if (width & 1)
+ {
+ /* if extra pixal at end of line, just move it */
+ *dptr = *sptr;
+ sptr++; dptr++;
+ }
+ }
+ }
+ else /* other format change than 8 bit -> 4 bit */
+ {
+ register unsigned long pixel_value;
+
+ for (dwx=0; dwx<width; dwx++)
+ {
+ for (dwy=0; dwy<height; dwy++)
+ {
+ pixel_value = XGetPixel(old_image, dwx, dwy);
+ XPutPixel(new_image, dwx, dwy, pixel_value);
+ }
+ }
+ }
+
+ free(old_image->data);
+ old_image->data = NULL;
+ XDestroyImage(old_image);
+
+ *image = new_image;
+ }
+
+ return(GIF_Success);
+}
+
+
+static unsigned long be2long(unsigned char *be) /* big-endian -> long int */
+{
+ return((be[0]<<24) | (be[1]<<16) | (be[2]<<8) | be[3]);
+}
+
+static unsigned short be2short(unsigned char *be) /* big-endian -> short int */
+{
+ return((be[0]<<8) | be[1]);
+}
+
+static struct IFF_ILBM_BMHD *ConvertBMHD(unsigned char *header_data)
+{
+ struct IFF_ILBM_BMHD_big_endian *bmhd_be;
+ struct IFF_ILBM_BMHD *bmhd;
+
+ bmhd_be = (struct IFF_ILBM_BMHD_big_endian *)header_data;
+ bmhd = (struct IFF_ILBM_BMHD *)malloc(sizeof(struct IFF_ILBM_BMHD));
+ if (!bmhd)
+ return(NULL);
+
+ bmhd->Width = be2short(bmhd_be->Width);
+ bmhd->Height = be2short(bmhd_be->Height);
+ bmhd->LeftEdge = be2short(bmhd_be->LeftEdge);
+ bmhd->TopEdge = be2short(bmhd_be->TopEdge);
+ bmhd->Depth = (int)bmhd_be->Depth;
+ bmhd->Mask = (int)bmhd_be->Mask;
+ bmhd->Compression = (int)bmhd_be->Compression;
+ bmhd->pad1 = bmhd_be->pad1;
+ bmhd->transparentColor = be2short(bmhd_be->transparentColor);
+ bmhd->xAspect = (int)bmhd_be->xAspect;
+ bmhd->yAspect = (int)bmhd_be->yAspect;
+ bmhd->pageWidth = be2short(bmhd_be->pageWidth);
+ bmhd->pageHeight = be2short(bmhd_be->pageHeight);
+
+ return(bmhd);
+}
+
+static unsigned char MSBitFirst2LSBitFirst(unsigned char msb_byte)
+{
+ unsigned char lsb_byte = 0;
+ int i;
+
+ for(i=7;i>=0;i--)
+ {
+ lsb_byte |= (msb_byte & 1) << i;
+ msb_byte >>= 1;
+ }
+
+ return(lsb_byte);
+}
+
+int Read_ILBM_to_Bitmap(Display *display, char *filename, Pixmap *pixmap)
+{
+ Pixmap new_pixmap = 0;
+ int screen = DefaultScreen(display);
+ Drawable root = RootWindow(display,screen);
+ struct IFF_ILBM_FORM_big_endian *form_header;
+ struct IFF_ILBM_BMHD *bitmap_header;
+ unsigned long file_len, body_len;
+ unsigned char *file_data, *bitmap_data;
+ unsigned char *file_ptr, *bitmap_ptr, *body_ptr;
+ unsigned char byte_count, byte_value;
+ int i,x,y,z;
+ int width, height, depth;
+ int bytes_per_line, bitmap_size;
+ FILE *file;
+
+ if (!(file = fopen(filename,"r")))
+ return(ILBM_OpenFailed);
+
+ if (fseek(file,0,SEEK_END) < 0)
+ {
+ fclose(file);
+ return(ILBM_ReadFailed);
+ }
+
+ file_len = ftell(file);
+ rewind(file);
+
+ if (!(file_data = (unsigned char *)malloc(file_len)))
+ {
+ fclose(file);
+ return(ILBM_NoMemory);
+ }
+
+ if (fread(file_data,1,file_len,file) != file_len)
+ {
+ free(file_data);
+ fclose(file);
+ return(ILBM_ReadFailed);
+ }
+
+ fclose(file);
+
+ form_header = (struct IFF_ILBM_FORM_big_endian *)file_data;
+
+ if (strncmp(form_header->magic_FORM,"FORM",4) ||
+ file_len != be2long(form_header->chunk_size)+8 ||
+ strncmp(form_header->magic_ILBM,"ILBM",4))
+ {
+#ifdef DEBUG_ILBM
+ printf("%s: IFF chunk 'FORM' and/or 'ILBM' not found.\n",filename);
+#endif
+ free(file_data);
+ return(ILBM_FileInvalid);
+ }
+
+ bitmap_header = NULL;
+ body_ptr = NULL;
+ file_ptr = file_data + 12;
+
+ while(file_ptr < (unsigned char *)(file_data + file_len))
+ {
+ if (!strncmp(file_ptr,"BMHD",4))
+ {
+#ifdef DEBUG_ILBM
+ printf("%s: IFF chunk 'BMHD' found.\n",filename);
+#endif
+ bitmap_header = ConvertBMHD(file_ptr + 8);
+ file_ptr += be2long(file_ptr + 4) + 8;
+ continue;
+ }
+ else if (!strncmp(file_ptr,"BODY",4))
+ {
+#ifdef DEBUG_ILBM
+ printf("%s: IFF chunk 'BODY' found.\n",filename);
+#endif
+ body_ptr = file_ptr + 8;
+ body_len = be2long(file_ptr + 4);
+ file_ptr += be2long(file_ptr + 4) + 8;
+ continue;
+ }
+ else
+ {
+#ifdef DEBUG_ILBM
+ printf("%s: IFF chunk '%c%c%c%c' found (but not used).\n",filename,
+ file_ptr[0],file_ptr[1],file_ptr[2],file_ptr[3]);
+#endif
+ /* other chunk not recognized here */
+ file_ptr += be2long(file_ptr + 4) + 8;
+ continue;
+ }
+ }
+
+ if (!bitmap_header || !body_ptr)
+ {
+#ifdef DEBUG_ILBM
+ printf("%s: IFF chunk 'BMHD' and/or 'BODY' not found.\n",filename);
+#endif
+ free(file_data);
+ return(ILBM_FileInvalid);
+ }
+
+ width = bitmap_header->Width;
+ height = bitmap_header->Height;
+ depth = bitmap_header->Depth;
+
+#ifdef DEBUG_ILBM
+ if (depth > 1)
+ printf("%s: %d bitplanes found; using only the first plane.\n",
+ filename,depth);
+#endif
+
+ bytes_per_line = ((width + 15) / 16) * 2;
+ bitmap_size = bytes_per_line * height;
+
+ bitmap_data = (char *)malloc(bitmap_size);
+ if (!bitmap_data)
+ {
+ free(file_data);
+ free(bitmap_header);
+ return(ILBM_NoMemory);
+ }
+
+ bitmap_ptr = bitmap_data;
+ for(i=0;i<bitmap_size;i++)
+ *bitmap_ptr++ = 0;
+
+ for(y=0;y<height;y++)
+ {
+ /* we only read the first bitplane here to create a black/white bitmap */
+
+ for(z=0;z<depth;z++)
+ {
+ bitmap_ptr = bitmap_data + y * bytes_per_line;
+ x = 0;
+
+ if (!bitmap_header->Compression)
+ {
+ while(x++ < bytes_per_line)
+ *bitmap_ptr++ |= MSBitFirst2LSBitFirst(*body_ptr++);
+ }
+ else
+ {
+ while(x < bytes_per_line)
+ {
+ byte_count = *body_ptr++;
+
+ if (byte_count <= 128)
+ {
+ for(i=0;i<byte_count+1;i++)
+ *bitmap_ptr++ |= MSBitFirst2LSBitFirst(*body_ptr++);
+ x += byte_count + 1;
+ }
+ else
+ {
+ byte_value = *body_ptr++;
+ for(i=0;i<257-byte_count;i++)
+ *bitmap_ptr++ |= MSBitFirst2LSBitFirst(byte_value);
+ x += 257 - byte_count;
+ }
+ }
+ }
+ }
+ }
+
+ bitmap_ptr = bitmap_data;
+ for(i=0;i<bitmap_size;i++)
+ *bitmap_ptr++ ^= 0xff;
+
+ new_pixmap = XCreateBitmapFromData(display,root,bitmap_data,width,height);
+
+ free(file_data);
+ free(bitmap_data);
+ free(bitmap_header);
+
+ if (!new_pixmap)
+ return(ILBM_NoMemory);
+
+ *pixmap = new_pixmap;
+ return(ILBM_Success);
+}
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* ©1995 Artsoft Development *
+* Holger Schemel *
+* 33659 Bielefeld-Senne *
+* Telefon: (0521) 493245 *
+* eMail: aeglos@valinor.owl.de *
+* aeglos@uni-paderborn.de *
+* q99492@pbhrzx.uni-paderborn.de *
+*----------------------------------------------------------*
+* gfxloader.h *
+***********************************************************/
+
+#ifndef GFXLOADER_H
+#define GFXLOADER_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#define GIF_Success 0
+#define GIF_OpenFailed -1
+#define GIF_ReadFailed -2
+#define GIF_FileInvalid -3
+#define GIF_NoMemory -4
+#define GIF_ColorFailed -5
+
+#define ILBM_Success 0
+#define ILBM_OpenFailed -1
+#define ILBM_ReadFailed -2
+#define ILBM_FileInvalid -3
+#define ILBM_NoMemory -4
+#define ILBM_ColorFailed -5
+
+int Read_ILBM_to_Bitmap(Display *, char *, Pixmap *);
+int Read_GIF_to_Bitmap(Display *, char *, Pixmap *);
+int Read_GIF_to_Pixmap(Display *, char *, Pixmap *);
+int Read_GIF_to_XImage(Display *, char *, XImage **);
+
+#endif
#include "screens.h"
#include "tools.h"
#include "files.h"
+#include "joystick.h"
+#include "gfxloader.h"
+
#include <signal.h>
+#ifdef DEBUG
+/*
+#define DEBUG_TIMING
+*/
+#endif
+
+struct PictureFileInfo
+{
+ char *picture_filename;
+ BOOL picture_with_mask;
+};
+
+struct IconFileInfo
+{
+ char *picture_filename;
+ char *picturemask_filename;
+};
+
static int sound_process_id = 0;
+static void InitLevelAndPlayerInfo(void);
+static void InitDisplay(int, char **);
+static void InitSound(void);
+static void InitSoundProcess(void);
+static void InitWindow(int, char **);
+static void InitGfx(void);
+static void LoadGfx(int, struct PictureFileInfo *);
+static void InitElementProperties(void);
+
void OpenAll(int argc, char *argv[])
{
InitLevelAndPlayerInfo();
char *window_name = WINDOWTITLE_STRING;
char *icon_name = WINDOWTITLE_STRING;
long window_event_mask;
- static struct PictureFile icon_pic =
+ static struct IconFileInfo icon_pic =
{
"rocks_icon.xbm",
"rocks_iconmask.xbm"
int i,j;
XGCValues clip_gc_values;
unsigned long clip_gc_valuemask;
- static struct PictureFile pic[NUM_PICTURES] =
+ static struct PictureFileInfo pic[NUM_PICTURES] =
{
- { "RocksScreen.xpm", "RocksScreenMaske.xbm" },
- { "RocksDoor.xpm", "RocksDoorMaske.xbm" },
- { "RocksToons.xpm", "RocksToonsMaske.xbm" },
- { "RocksFont.xpm", NULL },
- { "RocksFont2.xpm", NULL }
+ { "RocksScreen", TRUE },
+ { "RocksDoor", TRUE },
+ { "RocksHeroes", TRUE },
+ { "RocksToons", TRUE },
+ { "RocksFont", FALSE },
+ { "RocksFont2", FALSE }
};
+#ifdef DEBUG_TIMING
+ long count1, count2;
+ count1 = Counter();
+#endif
+
LoadGfx(PIX_SMALLFONT,&pic[PIX_SMALLFONT]);
DrawInitText(WINDOWTITLE_STRING,20,FC_YELLOW);
DrawInitText(COPYRIGHT_STRING,50,FC_RED);
if (i!=PIX_SMALLFONT)
LoadGfx(i,&pic[i]);
+#ifdef DEBUG_TIMING
+ count2 = Counter();
+ printf("SUMMARY: %.2f SECONDS LOADING TIME\n",(float)(count2-count1)/100.0);
+#endif
+
+
pix[PIX_DB_BACK] = XCreatePixmap(display, window,
WIN_XSIZE,WIN_YSIZE,
XDefaultDepth(display,screen));
redraw_mask=REDRAW_ALL;
}
-void LoadGfx(int pos, struct PictureFile *pic)
+void LoadGfx(int pos, struct PictureFileInfo *pic)
{
+ char basefilename[256];
+ char filename[256];
+
+#ifdef XPM_INCLUDE_FILE
int xpm_err, xbm_err;
unsigned int width,height;
int hot_x,hot_y;
- char filename[256];
Pixmap shapemask;
+ char *picture_ext = ".xpm";
+ char *picturemask_ext = "Mask.xbm";
+#else
+ int gif_err, ilbm_err;
+ char *picture_ext = ".gif";
+ char *picturemask_ext = "Mask.ilbm";
+#endif
+
+#ifdef DEBUG_TIMING
+ long count1, count2;
+#endif
/* Grafik laden */
if (pic->picture_filename)
{
- DrawInitText(pic->picture_filename,150,FC_YELLOW);
- sprintf(filename,"%s/%s",GFX_PATH,pic->picture_filename);
+ sprintf(basefilename,"%s%s",pic->picture_filename,picture_ext);
+ DrawInitText(basefilename,150,FC_YELLOW);
+ sprintf(filename,"%s/%s",GFX_PATH,basefilename);
+
+#ifdef DEBUG_TIMING
+ count1 = Counter();
+#endif
+
+#ifdef XPM_INCLUDE_FILE
xpm_att[pos].valuemask = XpmCloseness;
xpm_att[pos].closeness = 20000;
switch(xpm_err)
{
case XpmOpenFailed:
- fprintf(stderr,"Xpm file open failed on '%s' !\n",filename);
+ fprintf(stderr,"Cannot open Xpm file '%s' !\n",filename);
CloseAll();
exit(-1);
case XpmFileInvalid:
CloseAll();
exit(-1);
case XpmNoMemory:
- fprintf(stderr,"Not enough memory !\n");
+ fprintf(stderr,"Not enough memory for Xpm file '%s'!\n",filename);
CloseAll();
exit(1);
case XpmColorFailed:
- fprintf(stderr,"Can`t get any colors...\n");
+ fprintf(stderr,"Can't get colors for Xpm file '%s'!\n",filename);
CloseAll();
exit(-1);
default:
break;
}
+#else
+
+ gif_err = Read_GIF_to_Pixmap(display,filename,&pix[pos]);
+
+ switch(gif_err)
+ {
+ case GIF_Success:
+ break;
+ case GIF_OpenFailed:
+ fprintf(stderr,"Cannot open GIF file '%s' !\n",filename);
+ CloseAll();
+ exit(-1);
+ case GIF_ReadFailed:
+ fprintf(stderr,"Cannot read GIF file '%s' !\n",filename);
+ CloseAll();
+ exit(-1);
+ case GIF_FileInvalid:
+ fprintf(stderr,"Invalid GIF file '%s'!\n",filename);
+ CloseAll();
+ exit(-1);
+ case GIF_NoMemory:
+ fprintf(stderr,"Not enough memory for GIF file '%s'!\n",filename);
+ CloseAll();
+ exit(1);
+ case GIF_ColorFailed:
+ fprintf(stderr,"Can't get colors for GIF file '%s'!\n",filename);
+ CloseAll();
+ exit(-1);
+ default:
+ break;
+ }
+
+#endif
+
+#ifdef DEBUG_TIMING
+ count2 = Counter();
+ printf("LOADING %s IN %.2f SECONDS\n",
+ filename,(float)(count2-count1)/100.0);
+#endif
+
if (!pix[pos])
{
- fprintf(stderr, "%s: cannot read Xpm file '%s'.\n",
+ fprintf(stderr, "%s: cannot read graphics file '%s'.\n",
progname,filename);
CloseAll();
exit(-1);
}
/* zugehörige Maske laden (wenn vorhanden) */
- if (pic->picturemask_filename)
+ if (pic->picture_with_mask)
{
- DrawInitText(pic->picturemask_filename,150,FC_YELLOW);
- sprintf(filename,"%s/%s",GFX_PATH,pic->picturemask_filename);
+ sprintf(basefilename,"%s%s",pic->picture_filename,picturemask_ext);
+ DrawInitText(basefilename,150,FC_YELLOW);
+ sprintf(filename,"%s/%s",GFX_PATH,basefilename);
+
+#ifdef DEBUG_TIMING
+ count1 = Counter();
+#endif
+
+#ifdef XPM_INCLUDE_FILE
xbm_err = XReadBitmapFile(display,window,filename,
&width,&height,&clipmask[pos],&hot_x,&hot_y);
break;
}
+#else
+
+ ilbm_err = Read_ILBM_to_Bitmap(display,filename,&clipmask[pos]);
+
+ switch(ilbm_err)
+ {
+ case ILBM_Success:
+ break;
+ case ILBM_OpenFailed:
+ fprintf(stderr,"Cannot open ILBM file '%s' !\n",filename);
+ CloseAll();
+ exit(-1);
+ case ILBM_ReadFailed:
+ fprintf(stderr,"Cannot read ILBM file '%s' !\n",filename);
+ CloseAll();
+ exit(-1);
+ case ILBM_FileInvalid:
+ fprintf(stderr,"Invalid ILBM file '%s'!\n",filename);
+ CloseAll();
+ exit(-1);
+ case ILBM_NoMemory:
+ fprintf(stderr,"Not enough memory for ILBM file '%s'!\n",filename);
+ CloseAll();
+ exit(1);
+ default:
+ break;
+ }
+
+#endif
+
+#ifdef DEBUG_TIMING
+ count2 = Counter();
+ printf("LOADING %s IN %.2f SECONDS\n",
+ filename,(float)(count2-count1)/100.0);
+#endif
+
if (!clipmask[pos])
{
- fprintf(stderr, "%s: cannot read X11 bitmap file '%s'.\n",
+ fprintf(stderr, "%s: cannot read graphics file '%s'.\n",
progname,filename);
CloseAll();
exit(-1);
};
static int ep_amoeboid_num = sizeof(ep_amoeboid)/sizeof(int);
- static int ep_badewannoid[] =
- {
- EL_BADEWANNE1,
- EL_BADEWANNE2,
- EL_BADEWANNE3,
- EL_BADEWANNE4,
- EL_BADEWANNE5
- };
- static int ep_badewannoid_num = sizeof(ep_badewannoid)/sizeof(int);
-
static int ep_schluessel[] =
{
EL_SCHLUESSEL1,
EL_BIRNE_EIN,
EL_BIRNE_AUS,
EL_BADEWANNE1,
- EL_BADEWANNE2
+ EL_BADEWANNE2,
+ EL_SONDE
};
static int ep_slippery_num = sizeof(ep_slippery)/sizeof(int);
EL_FIREFLY,
EL_MAMPFER,
EL_MAMPFER2,
- EL_ZOMBIE,
+ EL_ROBOT,
EL_PACMAN
};
static int ep_enemy_num = sizeof(ep_enemy)/sizeof(int);
EL_FIREFLY,
EL_MAMPFER,
EL_MAMPFER2,
- EL_ZOMBIE,
- EL_PACMAN
+ EL_ROBOT,
+ EL_PACMAN,
+ EL_MAULWURF,
+ EL_PINGUIN,
+ EL_SCHWEIN,
+ EL_DRACHE,
+ EL_SONDE
};
static int ep_can_move_num = sizeof(ep_can_move)/sizeof(int);
EL_FIREFLY,
EL_MAMPFER,
EL_MAMPFER2,
- EL_ZOMBIE,
+ EL_ROBOT,
EL_PACMAN,
EL_TROPFEN,
EL_SALZSAEURE
EL_BUTTERFLY,
EL_FIREFLY,
EL_MAMPFER,
- EL_ZOMBIE,
+ EL_ROBOT,
EL_PACMAN,
EL_TROPFEN,
EL_AMOEBE_TOT,
};
static int ep_inactive_num = sizeof(ep_inactive)/sizeof(int);
+ static int ep_explosive[] =
+ {
+ EL_BOMBE,
+ EL_DYNAMIT,
+ EL_DYNAMIT_AUS,
+ EL_DYNABOMB,
+ EL_DYNABOMB_NR,
+ EL_DYNABOMB_SZ,
+ EL_DYNABOMB_XL,
+ EL_KAEFER,
+ EL_MAULWURF,
+ EL_PINGUIN,
+ EL_SCHWEIN,
+ EL_DRACHE,
+ EL_SONDE
+ };
+ static int ep_explosive_num = sizeof(ep_explosive)/sizeof(int);
+
+ static int ep_mampf3[] =
+ {
+ EL_EDELSTEIN,
+ EL_EDELSTEIN_BD,
+ EL_EDELSTEIN_GELB,
+ EL_EDELSTEIN_ROT,
+ EL_EDELSTEIN_LILA,
+ EL_DIAMANT
+ };
+ static int ep_mampf3_num = sizeof(ep_mampf3)/sizeof(int);
+
+ static int ep_pushable[] =
+ {
+ EL_FELSBROCKEN,
+ EL_BOMBE,
+ EL_KOKOSNUSS,
+ EL_ZEIT_LEER,
+ EL_SOKOBAN_FELD_VOLL,
+ EL_SOKOBAN_OBJEKT,
+ EL_SONDE
+ };
+ static int ep_pushable_num = sizeof(ep_pushable)/sizeof(int);
+
static long ep_bit[] =
{
EP_BIT_AMOEBALIVE,
EP_BIT_AMOEBOID,
- EP_BIT_BADEWANNOID,
EP_BIT_SCHLUESSEL,
EP_BIT_PFORTE,
EP_BIT_SOLID,
EP_BIT_BD_ELEMENT,
EP_BIT_SB_ELEMENT,
EP_BIT_GEM,
- EP_BIT_INACTIVE
+ EP_BIT_INACTIVE,
+ EP_BIT_EXPLOSIVE,
+ EP_BIT_MAMPF3,
+ EP_BIT_PUSHABLE
};
static int *ep_array[] =
{
ep_amoebalive,
ep_amoeboid,
- ep_badewannoid,
ep_schluessel,
ep_pforte,
ep_solid,
ep_bd_element,
ep_sb_element,
ep_gem,
- ep_inactive
+ ep_inactive,
+ ep_explosive,
+ ep_mampf3,
+ ep_pushable
};
static int *ep_num[] =
{
&ep_amoebalive_num,
&ep_amoeboid_num,
- &ep_badewannoid_num,
&ep_schluessel_num,
&ep_pforte_num,
&ep_solid_num,
&ep_bd_element_num,
&ep_sb_element_num,
&ep_gem_num,
- &ep_inactive_num
+ &ep_inactive_num,
+ &ep_explosive_num,
+ &ep_mampf3_num,
+ &ep_pushable_num
};
static int num_properties = sizeof(ep_num)/sizeof(int *);
{
if (pix[i])
{
+#ifdef XPM_INCLUDE_FILE
if (i<NUM_PICTURES) /* XPM pictures */
{
XFreeColors(display,DefaultColormap(display,screen),
xpm_att[i].pixels,xpm_att[i].npixels,0);
XpmFreeAttributes(&xpm_att[i]);
}
+#endif
XFreePixmap(display,pix[i]);
}
if (clipmask[i])
#include "main.h"
void OpenAll(int, char **);
-void InitLevelAndPlayerInfo(void);
-void InitDisplay(int, char **);
-void InitSound(void);
-void InitSoundProcess(void);
-void InitJoystick(void);
-void InitWindow(int, char **);
-void InitGfx(void);
-void LoadGfx(int, struct PictureFile *);
-void InitElementProperties(void);
void CloseAll();
+void InitJoystick(void);
#endif
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* ©1995 Artsoft Development *
+* Holger Schemel *
+* 33604 Bielefeld *
+* Telefon: (0521) 290471 *
+* eMail: aeglos@valinor.owl.de *
+* aeglos@uni-paderborn.de *
+*----------------------------------------------------------*
+* joystick.c *
+***********************************************************/
+
+#ifdef __FreeBSD__
+#include <machine/joystick.h>
+#endif
+
+#include "joystick.h"
+
+/*
+#include "tools.h"
+#include "game.h"
+#include "events.h"
+#include "sound.h"
+#include "misc.h"
+#include "buttons.h"
+#include <math.h>
+*/
+
+void CheckJoystickData()
+{
+ int i;
+ int distance = 100;
+
+ for(i=0;i<2;i++)
+ {
+ if (joystick[i].xmiddle <= distance)
+ joystick[i].xmiddle = distance;
+ if (joystick[i].ymiddle <= distance)
+ joystick[i].ymiddle = distance;
+
+ if (joystick[i].xleft >= joystick[i].xmiddle)
+ joystick[i].xleft = joystick[i].xmiddle-distance;
+ if (joystick[i].xright <= joystick[i].xmiddle)
+ joystick[i].xright = joystick[i].xmiddle+distance;
+
+ if (joystick[i].yupper >= joystick[i].ymiddle)
+ joystick[i].yupper = joystick[i].ymiddle-distance;
+ if (joystick[i].ylower <= joystick[i].ymiddle)
+ joystick[i].ylower = joystick[i].ymiddle+distance;
+ }
+}
+
+int JoystickPosition(int middle, int margin, int actual)
+{
+ long range, pos;
+ int percentage;
+
+ if (margin<middle && actual>middle)
+ return(0);
+ if (margin>middle && actual<middle)
+ return(0);
+
+ range = ABS(margin-middle);
+ pos = ABS(actual-middle);
+ percentage = (int)(pos*100/range);
+ if (percentage>100)
+ percentage = 100;
+
+ return(percentage);
+}
+
+int Joystick()
+{
+#ifdef __FreeBSD__
+ struct joystick joy_ctrl;
+#else
+ struct joystick_control
+ {
+ int buttons;
+ int x;
+ int y;
+ } joy_ctrl;
+#endif
+
+ int js_x,js_y, js_b1,js_b2;
+ int left, right, up, down;
+ int result=0;
+
+ if (joystick_status==JOYSTICK_OFF)
+ return(0);
+
+ if (read(joystick_device, &joy_ctrl, sizeof(joy_ctrl)) != sizeof(joy_ctrl))
+ {
+ fprintf(stderr,"%s: cannot read joystick settings - no joystick support\n",
+ progname);
+ joystick_status = JOYSTICK_OFF;
+ return(0);
+ }
+
+ js_x = joy_ctrl.x;
+ js_y = joy_ctrl.y;
+#ifdef __FreeBSD__
+ js_b1 = joy_ctrl.b1;
+ js_b2 = joy_ctrl.b2;
+#else
+ js_b1 = joy_ctrl.buttons & 1;
+ js_b2 = joy_ctrl.buttons & 2;
+#endif
+
+ left = JoystickPosition(joystick[joystick_nr].xmiddle,
+ joystick[joystick_nr].xleft, js_x);
+ right = JoystickPosition(joystick[joystick_nr].xmiddle,
+ joystick[joystick_nr].xright, js_x);
+ up = JoystickPosition(joystick[joystick_nr].ymiddle,
+ joystick[joystick_nr].yupper, js_y);
+ down = JoystickPosition(joystick[joystick_nr].ymiddle,
+ joystick[joystick_nr].ylower, js_y);
+
+ if (left>JOYSTICK_PERCENT)
+ result |= JOY_LEFT;
+ else if (right>JOYSTICK_PERCENT)
+ result |= JOY_RIGHT;
+ if (up>JOYSTICK_PERCENT)
+ result |= JOY_UP;
+ else if (down>JOYSTICK_PERCENT)
+ result |= JOY_DOWN;
+ if (js_b1)
+ result |= JOY_BUTTON_1;
+ if (js_b2)
+ result |= JOY_BUTTON_2;
+
+ return(result);
+}
+
+int JoystickButton()
+{
+ static int last_joy_button = 0;
+ int joy_button = (Joystick() & JOY_BUTTON);
+ int result;
+
+ if (joy_button)
+ {
+ if (last_joy_button)
+ result = JOY_BUTTON_PRESSED;
+ else
+ result = JOY_BUTTON_NEW_PRESSED;
+ }
+ else
+ {
+ if (last_joy_button)
+ result = JOY_BUTTON_NEW_RELEASED;
+ else
+ result = JOY_BUTTON_NOT_PRESSED;
+ }
+
+ last_joy_button = joy_button;
+ return(result);
+}
--- /dev/null
+/***********************************************************
+* 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 *
+*----------------------------------------------------------*
+* joystick.h *
+***********************************************************/
+
+#ifndef JOYSTICK_H
+#define JOYSTICK_H
+
+#include "main.h"
+
+/* values for the joystick */
+#define JOYSTICK_OFF 0
+#define JOYSTICK_AVAILABLE 1
+#ifdef __FreeBSD__
+#include <machine/joystick.h>
+#define DEV_JOYSTICK_0 "/dev/joy0"
+#define DEV_JOYSTICK_1 "/dev/joy1"
+#else
+#define DEV_JOYSTICK_0 "/dev/js0"
+#define DEV_JOYSTICK_1 "/dev/js1"
+#endif
+
+/* get these values from the program 'js' from the joystick package, */
+/* set JOYSTICK_PERCENT to a threshold appropriate for your joystick */
+#define JOYSTICK_XLEFT 30
+#define JOYSTICK_XRIGHT 1250
+#define JOYSTICK_XMIDDLE 530
+#define JOYSTICK_YUPPER 40
+#define JOYSTICK_YLOWER 1440
+#define JOYSTICK_YMIDDLE 680
+#define JOYSTICK_PERCENT 25
+#define JOY_LEFT MV_LEFT
+#define JOY_RIGHT MV_RIGHT
+#define JOY_UP MV_UP
+#define JOY_DOWN MV_DOWN
+#define JOY_BUTTON_1 16
+#define JOY_BUTTON_2 32
+#define JOY_BUTTON (JOY_BUTTON_1 | JOY_BUTTON_2)
+#define JOY_BUTTON_NOT_PRESSED 0
+#define JOY_BUTTON_PRESSED 1
+#define JOY_BUTTON_NEW_PRESSED 2
+#define JOY_BUTTON_NEW_RELEASED 3
+
+#ifdef NO_JOYSTICK
+#define JOYSTICK_STATUS JOYSTICK_OFF
+#else
+#define JOYSTICK_STATUS JOYSTICK_AVAILABLE
+#endif
+
+
+void CheckJoystickData(void);
+int JoystickPosition(int, int, int);
+int Joystick(void);
+int JoystickButton(void);
+
+#endif
#include "init.h"
#include "events.h"
#include "sound.h"
+#include "joystick.h"
Display *display;
int screen;
GC gc, clip_gc[NUM_PIXMAPS];
Pixmap pix[NUM_PIXMAPS];
Pixmap clipmask[NUM_PIXMAPS];
+
+#ifdef XPM_INCLUDE_FILE
XpmAttributes xpm_att[NUM_PICTURES];
+#endif
+
Drawable drawto, drawto_field, backbuffer;
Colormap cmap;
int level_nr, leveldir_nr, num_leveldirs;
int lev_fieldx,lev_fieldy, scroll_x,scroll_y;
-int LevelSolved,GameOver, JX,JY, ZX,ZY;
+int JX,JY, ZX,ZY, ExitX,ExitY;
+int PlayerMovDir, PlayerFrame, PlayerPushing;
+int PlayerGone,LevelSolved,GameOver;
int FrameCounter,TimeFrames,TimeLeft,Score;
-int Gems,SokobanFields,Lights,Dynamite,Key[4],MampferNr;
+int Gems,SokobanFields,Lights,Friends;
+int Dynamite,Key[4],MampferNr;
int DynaBombCount, DynaBombSize, DynaBombsLeft, DynaBombXL;
int SiebAktiv;
#ifdef XPM_INCLUDE_FILE
#include XPM_INCLUDE_FILE
-#else
-#include "YOU HAVE TO SET 'XPM_INCLUDE_FILE' IN THE 'Makefile'!!!"
#endif
#include <sys/types.h>
#define EP_BIT_AMOEBALIVE (1<<0)
#define EP_BIT_AMOEBOID (1<<1)
-#define EP_BIT_BADEWANNOID (1<<2)
-#define EP_BIT_SCHLUESSEL (1<<3)
-#define EP_BIT_PFORTE (1<<4)
-#define EP_BIT_SOLID (1<<5)
-#define EP_BIT_MASSIV (1<<6)
-#define EP_BIT_SLIPPERY (1<<7)
-#define EP_BIT_ENEMY (1<<8)
-#define EP_BIT_MAUER (1<<9)
-#define EP_BIT_CAN_FALL (1<<10)
-#define EP_BIT_CAN_SMASH (1<<11)
-#define EP_BIT_CAN_CHANGE (1<<12)
-#define EP_BIT_CAN_MOVE (1<<13)
-#define EP_BIT_COULD_MOVE (1<<14)
-#define EP_BIT_DONT_TOUCH (1<<15)
-#define EP_BIT_DONT_GO_TO (1<<16)
-#define EP_BIT_MAMPF2 (1<<17)
-#define EP_BIT_CHAR (1<<18)
-#define EP_BIT_BD_ELEMENT (1<<19)
-#define EP_BIT_SB_ELEMENT (1<<20)
-#define EP_BIT_GEM (1<<21)
-#define EP_BIT_INACTIVE (1<<22)
+#define EP_BIT_SCHLUESSEL (1<<2)
+#define EP_BIT_PFORTE (1<<3)
+#define EP_BIT_SOLID (1<<4)
+#define EP_BIT_MASSIV (1<<5)
+#define EP_BIT_SLIPPERY (1<<6)
+#define EP_BIT_ENEMY (1<<7)
+#define EP_BIT_MAUER (1<<8)
+#define EP_BIT_CAN_FALL (1<<9)
+#define EP_BIT_CAN_SMASH (1<<10)
+#define EP_BIT_CAN_CHANGE (1<<11)
+#define EP_BIT_CAN_MOVE (1<<12)
+#define EP_BIT_COULD_MOVE (1<<13)
+#define EP_BIT_DONT_TOUCH (1<<14)
+#define EP_BIT_DONT_GO_TO (1<<15)
+#define EP_BIT_MAMPF2 (1<<16)
+#define EP_BIT_CHAR (1<<17)
+#define EP_BIT_BD_ELEMENT (1<<18)
+#define EP_BIT_SB_ELEMENT (1<<19)
+#define EP_BIT_GEM (1<<20)
+#define EP_BIT_INACTIVE (1<<21)
+#define EP_BIT_EXPLOSIVE (1<<22)
+#define EP_BIT_MAMPF3 (1<<23)
+#define EP_BIT_PUSHABLE (1<<24)
#define IS_AMOEBALIVE(e) (Elementeigenschaften[e] & EP_BIT_AMOEBALIVE)
#define IS_AMOEBOID(e) (Elementeigenschaften[e] & EP_BIT_AMOEBOID)
-#define IS_BADEWANNOID(e) (Elementeigenschaften[e] & EP_BIT_BADEWANNOID)
#define IS_SCHLUESSEL(e) (Elementeigenschaften[e] & EP_BIT_SCHLUESSEL)
#define IS_PFORTE(e) (Elementeigenschaften[e] & EP_BIT_PFORTE)
#define IS_SOLID(e) (Elementeigenschaften[e] & EP_BIT_SOLID)
#define IS_SB_ELEMENT(e) (Elementeigenschaften[e] & EP_BIT_SB_ELEMENT)
#define IS_GEM(e) (Elementeigenschaften[e] & EP_BIT_GEM)
#define IS_INACTIVE(e) (Elementeigenschaften[e] & EP_BIT_INACTIVE)
+#define IS_EXPLOSIVE(e) (Elementeigenschaften[e] & EP_BIT_EXPLOSIVE)
+#define IS_MAMPF3(e) (Elementeigenschaften[e] & EP_BIT_MAMPF3)
+#define IS_PUSHABLE(e) (Elementeigenschaften[e] & EP_BIT_PUSHABLE)
#define EL_CHANGED(e) ((e)==EL_FELSBROCKEN ? EL_EDELSTEIN : \
(e)==EL_EDELSTEIN ? EL_DIAMANT : \
/* Pixmaps with Xpm or X11 Bitmap files */
#define PIX_BACK 0
#define PIX_DOOR 1
-#define PIX_TOONS 2
-#define PIX_BIGFONT 3
-#define PIX_SMALLFONT 4
+#define PIX_HEROES 2
+#define PIX_TOONS 3
+#define PIX_BIGFONT 4
+#define PIX_SMALLFONT 5
/* Pixmaps without them */
-#define PIX_DB_BACK 5
-#define PIX_DB_DOOR 6
+#define PIX_DB_BACK 6
+#define PIX_DB_DOOR 7
-#define NUM_PICTURES 5
-#define NUM_PIXMAPS 7
+#define NUM_PICTURES 6
+#define NUM_PIXMAPS 8
/* boundaries of arrays etc. */
#define MAX_NAMELEN (10+1)
#define MAX_NUM_AMOEBA 100
#define MAX_ELEMENTS 512
-struct PictureFile
-{
- char *picture_filename;
- char *picturemask_filename;
-};
-
struct HiScore
{
char Name[MAX_NAMELEN];
unsigned long length_seconds;
unsigned int delay_played;
BOOL pause_before_death;
- BOOL changed;
BOOL recording, playing, pausing;
BOOL fast_forward;
+ BOOL changed;
struct
{
unsigned char joystickdata;
extern XImage *image[];
extern Pixmap clipmask[];
extern Pixmap pix[];
+
+#ifdef XPM_INCLUDE_FILE
extern XpmAttributes xpm_att[];
+#endif
+
extern Drawable drawto, drawto_field, backbuffer;
extern Colormap cmap;
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 JX,JY, ZX,ZY, ExitX,ExitY;
+extern int PlayerMovDir, PlayerFrame, PlayerPushing;
+extern int PlayerGone,LevelSolved,GameOver;
extern int FrameCounter,TimeFrames,TimeLeft,Score;
-extern int Gems,SokobanFields,Lights,Dynamite,Key[4],MampferNr;
+extern int Gems,SokobanFields,Lights,Friends;
+extern int Dynamite,Key[4],MampferNr;
extern int DynaBombCount, DynaBombSize, DynaBombsLeft, DynaBombXL;
extern int SiebAktiv;
extern struct PlayerInfo player;
extern struct HiScore highscore[];
extern struct RecordingInfo tape;
+extern struct SoundInfo Sound[];
extern struct JoystickInfo joystick[];
+extern char *sound_name[];
extern int background_loop[];
extern int num_bg_loops;
#define GFX_PER_LINE 16
#define MINI_GFX_PER_LINE 32
#define MICRO_GFX_PER_LINE 128
+#define HEROES_PER_LINE 16
#define FONT_CHARS_PER_LINE 16
#define FONT_LINES_PER_FONT 4
#define EL_KAEFER 9
#define EL_FLIEGER 10
#define EL_MAMPFER 11
-#define EL_ZOMBIE 12
+#define EL_ROBOT 12
#define EL_BETON 13
#define EL_DIAMANT 14
#define EL_AMOEBE_TOT 15
#define EL_AUSGANG_AUF 107
#define EL_SIEB2_TOT 108
#define EL_AMOEBA2DIAM 109
+#define EL_MAULWURF 110
+#define EL_PINGUIN 111
+#define EL_SONDE 112
+#define EL_PFEIL_L 113
+#define EL_PFEIL_R 114
+#define EL_PFEIL_O 115
+#define EL_PFEIL_U 116
+#define EL_SCHWEIN 117
+#define EL_DRACHE 118
+
+#define EL_UNUSED_119 119
#define EL_CHAR_START 120
#define EL_CHAR_ASCII0 (EL_CHAR_START-32)
#define EL_CHAR_COPY (EL_CHAR_ASCII0+94)
#define EL_CHAR_END (EL_CHAR_START+79)
+#define EL_UNUSED_200 200
+/* ... */
+#define EL_UNUSED_255 255
+
/* "unreal" runtime elements */
#define EL_BLOCKED 300
#define EL_EXPLODING 301
#define EL_BLURB_RIGHT 304
#define EL_AMOEBING 305
#define EL_MAUERND 306
+#define EL_BURNING 307
+
+/* game graphics:
+** 0 - 255: graphics from "RocksScreen"
+** 256 - 511: graphics from "RocksFont"
+** 512 - 767: graphics from "RocksHeroes"
+*/
-/* names for the graphic objects */
+#define GFX_START_ROCKSSCREEN 0
+#define GFX_END_ROCKSSCREEN 255
+#define GFX_START_ROCKSFONT 256
+#define GFX_END_ROCKSFONT 511
+#define GFX_START_ROCKSHEROES 512
+#define GFX_END_ROCKSHEROES 767
+
+/* graphics from "RocksScreen" */
/* Zeile 0 (0) */
#define GFX_LEERRAUM (-1)
#define GFX_ERDREICH 0
#define GFX_BADEWANNE3 32
#define GFX_BADEWANNE4 33
#define GFX_BADEWANNE5 34
-#define GFX_SPIELFIGUR 35
+#define GFX_SMILEY 35
#define GFX_PFORTE1 36
#define GFX_PFORTE2 37
#define GFX_PFORTE3 38
#define GFX_KAEFER_U 75
/* Zeile 5 (80) */
#define GFX_MAMPFER 80
-#define GFX_ZOMBIE 84
+#define GFX_ROBOT 84
#define GFX_PACMAN 88
#define GFX_PACMAN_R 88
#define GFX_PACMAN_O 89
#define GFX_BIRNE_EIN 113
#define GFX_ZEIT_VOLL 114
#define GFX_ZEIT_LEER 115
+#define GFX_SPIELER1 116
+#define GFX_SPIELER2 117
+#define GFX_SPIELER3 118
+#define GFX_SPIELER4 119
#define GFX_AMOEBE_VOLL 120
#define GFX_AMOEBE_BD GFX_AMOEBE_VOLL
#define GFX_SOKOBAN_OBJEKT 121
#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_PINGUIN 144
+#define GFX_MAULWURF 145
+#define GFX_SCHWEIN 146
+#define GFX_DRACHE 147
#define GFX_EDELSTEIN_ROT 152
#define GFX_EDELSTEIN_LILA 154
#define GFX_DYNABOMB_XL 156
+#define GFX_SONDE 159
/* Zeile 10 (160) */
#define GFX_EDELSTEIN_BD 163
#define GFX_MAUER_R1 165
#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_SCHLUESSEL GFX_SCHLUESSEL1
+#define GFX_SPIELFIGUR GFX_SPIELER1
+
+
+/* graphics from "RocksHeroes" */
+
+#define GFX_SPIELER_DOWN (GFX_START_ROCKSHEROES + 0*HEROES_PER_LINE + 0)
+#define GFX_SPIELER_UP (GFX_START_ROCKSHEROES + 0*HEROES_PER_LINE + 4)
+#define GFX_SPIELER_LEFT (GFX_START_ROCKSHEROES + 1*HEROES_PER_LINE + 0)
+#define GFX_SPIELER_RIGHT (GFX_START_ROCKSHEROES + 1*HEROES_PER_LINE + 4)
+#define GFX_SPIELER_PUSH_RIGHT (GFX_START_ROCKSHEROES + 2*HEROES_PER_LINE + 0)
+#define GFX_SPIELER_PUSH_LEFT (GFX_START_ROCKSHEROES + 2*HEROES_PER_LINE + 4)
+#define GFX_SONDE_START (GFX_START_ROCKSHEROES + 7*HEROES_PER_LINE + 0)
+#define GFX_SCHWEIN_DOWN (GFX_START_ROCKSHEROES + 0*HEROES_PER_LINE + 8)
+#define GFX_SCHWEIN_UP (GFX_START_ROCKSHEROES + 0*HEROES_PER_LINE +12)
+#define GFX_SCHWEIN_LEFT (GFX_START_ROCKSHEROES + 1*HEROES_PER_LINE + 8)
+#define GFX_SCHWEIN_RIGHT (GFX_START_ROCKSHEROES + 1*HEROES_PER_LINE +12)
+#define GFX_DRACHE_DOWN (GFX_START_ROCKSHEROES + 2*HEROES_PER_LINE + 8)
+#define GFX_DRACHE_UP (GFX_START_ROCKSHEROES + 2*HEROES_PER_LINE +12)
+#define GFX_DRACHE_LEFT (GFX_START_ROCKSHEROES + 3*HEROES_PER_LINE + 8)
+#define GFX_DRACHE_RIGHT (GFX_START_ROCKSHEROES + 3*HEROES_PER_LINE +12)
+#define GFX_MAULWURF_DOWN (GFX_START_ROCKSHEROES + 4*HEROES_PER_LINE + 8)
+#define GFX_MAULWURF_UP (GFX_START_ROCKSHEROES + 4*HEROES_PER_LINE +12)
+#define GFX_MAULWURF_LEFT (GFX_START_ROCKSHEROES + 5*HEROES_PER_LINE + 8)
+#define GFX_MAULWURF_RIGHT (GFX_START_ROCKSHEROES + 5*HEROES_PER_LINE +12)
+#define GFX_PINGUIN_DOWN (GFX_START_ROCKSHEROES + 7*HEROES_PER_LINE + 8)
+#define GFX_PINGUIN_UP (GFX_START_ROCKSHEROES + 7*HEROES_PER_LINE +12)
+#define GFX_PINGUIN_LEFT (GFX_START_ROCKSHEROES + 8*HEROES_PER_LINE + 8)
+#define GFX_PINGUIN_RIGHT (GFX_START_ROCKSHEROES + 8*HEROES_PER_LINE +12)
+#define GFX_BLURB_LEFT (GFX_START_ROCKSHEROES + 9*HEROES_PER_LINE + 8)
+#define GFX_BLURB_RIGHT (GFX_START_ROCKSHEROES + 9*HEROES_PER_LINE +12)
+#define GFX_FLAMMEN_LEFT (GFX_START_ROCKSHEROES + 8*HEROES_PER_LINE + 0)
+#define GFX_FLAMMEN_RIGHT (GFX_START_ROCKSHEROES + 9*HEROES_PER_LINE + 0)
+#define GFX_FLAMMEN_UP (GFX_START_ROCKSHEROES +10*HEROES_PER_LINE + 0)
+#define GFX_FLAMMEN_DOWN (GFX_START_ROCKSHEROES +11*HEROES_PER_LINE + 0)
+
+/* graphics from "RocksFont" */
+#define GFX_CHAR_START (GFX_START_ROCKSFONT)
#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 SC_KAEFER 2
#define SC_FLIEGER 3
#define SC_MAMPFER 4
-#define SC_ZOMBIE 5
+#define SC_ROBOT 5
#define SC_PACMAN 6
#define SC_KOKOSNUSS 7
#define SC_DYNAMIT 8
(s)==SND_NETWORK || (s)==SND_CZARDASZ || \
(s)==SND_TYGER || (s)==SND_VOYAGER || \
(s)==SND_TWILIGHT)
-extern char *sound_name[NUM_SOUNDS];
-/* this structure contains the sound data for the sound server */
-extern struct SoundInfo Sound[NUM_SOUNDS];
/* directions for moving */
#define MV_NO_MOVING 0
#define EMU_BOULDERDASH 1
#define EMU_SOKOBAN 2
-/* values for the joystick */
-#define JOYSTICK_OFF 0
-#define JOYSTICK_AVAILABLE 1
-#ifdef __FreeBSD__
-#include <machine/joystick.h>
-#define DEV_JOYSTICK_0 "/dev/joy0"
-#define DEV_JOYSTICK_1 "/dev/joy1"
-#else
-#define DEV_JOYSTICK_0 "/dev/js0"
-#define DEV_JOYSTICK_1 "/dev/js1"
-#endif
-
-/* get these values from the program 'js' from the joystick package, */
-/* set JOYSTICK_PERCENT to a threshold appropriate for your joystick */
-#define JOYSTICK_XLEFT 30
-#define JOYSTICK_XRIGHT 1250
-#define JOYSTICK_XMIDDLE 530
-#define JOYSTICK_YUPPER 40
-#define JOYSTICK_YLOWER 1440
-#define JOYSTICK_YMIDDLE 680
-#define JOYSTICK_PERCENT 25
-#define JOY_LEFT MV_LEFT
-#define JOY_RIGHT MV_RIGHT
-#define JOY_UP MV_UP
-#define JOY_DOWN MV_DOWN
-#define JOY_BUTTON_1 16
-#define JOY_BUTTON_2 32
-#define JOY_BUTTON (JOY_BUTTON_1 | JOY_BUTTON_2)
-#define JOY_BUTTON_NOT_PRESSED 0
-#define JOY_BUTTON_PRESSED 1
-#define JOY_BUTTON_NEW_PRESSED 2
-#define JOY_BUTTON_NEW_RELEASED 3
-
-#ifdef NO_JOYSTICK
-#define JOYSTICK_STATUS JOYSTICK_OFF
-#else
-#define JOYSTICK_STATUS JOYSTICK_AVAILABLE
-#endif
#ifndef GAME_DIR
#define GAME_DIR "."
#define MB_PRESSED TRUE
#define MB_MENU_CHOICE FALSE
#define MB_MENU_MARK TRUE
+#define MB_MENU_INITIALIZE (-1)
#define MB_LEFT 1
#define MB_MIDDLE 2
#define MB_RIGHT 3
#define KEY_RELEASED FALSE
#define KEY_PRESSED TRUE
-/* values for focus_status */
-#define FOCUS_OUT FALSE
-#define FOCUS_IN TRUE
-
/* values for redraw_mask */
#define REDRAW_ALL (1L<<0)
#define REDRAW_FIELD (1L<<1)
#define DOOR_GFX_PAGEY1 0
#define DOOR_GFX_PAGEY2 DYSIZE
+/* für DrawGraphicAnimation (tools.c) und AnimateToon (cartoons.c) */
+#define ANIM_NORMAL 0
+#define ANIM_OSCILLATE 1
+
#endif
#include "misc.h"
#include "tools.h"
#include "sound.h"
+#include "random.h"
+
#include <pwd.h>
#include <unistd.h>
#include <time.h>
return(FALSE);
}
-unsigned long be2long(unsigned long *be) /* big-endian -> longword */
-{
- unsigned char *ptr = (unsigned char *)be;
-
- return(ptr[0]<<24 | ptr[1]<<16 | ptr[2]<<8 | ptr[3]);
-}
-
char *int2str(int ct, int nr)
{
static char str[20];
unsigned int RND(unsigned int max)
{
- return(rand() % max);
+ return(random_linux_libc() % max);
}
unsigned int InitRND(long seed)
if (seed==NEW_RANDOMIZE)
{
gettimeofday(¤t_time,NULL);
- srand((unsigned int) current_time.tv_usec);
+ srandom_linux_libc((unsigned int) current_time.tv_usec);
return((unsigned int) current_time.tv_usec);
}
else
{
- srand((unsigned int) seed);
+ srandom_linux_libc((unsigned int) seed);
return((unsigned int) seed);
}
}
else
return(pwd->pw_name);
}
-
-void InitAnimation()
-{
- HandleAnimation(ANIM_START);
-}
-
-void StopAnimation()
-{
- HandleAnimation(ANIM_STOP);
-}
-
-void DoAnimation()
-{
- HandleAnimation(ANIM_CONTINUE);
-}
-
-void HandleAnimation(int mode)
-{
- static long animstart_delay = -1;
- static long animstart_delay_value = 0;
- 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;xx<SCR_FIELDX;xx++)
- for(yy=0;yy<SCR_FIELDY;yy++)
- DrawScreenField(xx,yy);
- DrawLevelElement(JX,JY,EL_SPIELFIGUR);
-
- drawto_field = window;
- }
-
- return;
- break;
- case ANIM_CONTINUE:
- break;
- case ANIM_STOP:
- redraw_mask |= REDRAW_FIELD;
-
- /* Redraw background even when in direct drawing mode */
- draw_mode = direct_draw_on;
- direct_draw_on = FALSE;
-
- BackToFront();
-
- direct_draw_on = draw_mode;
-
- return;
- break;
- default:
- break;
- }
-
- if (reset_delay)
- {
- animstart_delay = Counter();
- animstart_delay_value = SimpleRND(500);
- reset_delay = FALSE;
- }
-
- if (anim_restart)
- {
- if (!DelayReached(&animstart_delay,animstart_delay_value))
- return;
-
- toon_nr = SimpleRND(NUM_TOONS);
- }
-
- anim_restart = reset_delay = AnimateToon(toon_nr,anim_restart);
-}
-
-BOOL AnimateToon(int toon_nr, BOOL restart)
-{
- static pos_x = 0, pos_y = 0;
- static delta_x = 0, delta_y = 0;
- static int frame = 0, frame_step = 1;
- static BOOL horiz_move, vert_move;
- static long anim_delay = 0;
- static int anim_delay_value = 0;
- static int width,height;
- static int pad_x,pad_y;
- static int cut_x,cut_y;
- static int src_x, src_y;
- static int dest_x, dest_y;
- static struct AnimInfo toon[NUM_TOONS] =
- {
- {DWARF_XSIZE, DWARF_YSIZE,
- DWARF_X, DWARF_Y,
- DWARF_FRAMES,
- DWARF_FPS,
- DWARF_STEPSIZE,
- FALSE,
- ANIMDIR_RIGHT,
- ANIMPOS_DOWN},
-
- {DWARF_XSIZE, DWARF_YSIZE,
- DWARF_X, DWARF2_Y,
- DWARF_FRAMES,
- DWARF_FPS,
- DWARF_STEPSIZE,
- FALSE,
- ANIMDIR_LEFT,
- ANIMPOS_DOWN},
-
- {JUMPER_XSIZE, JUMPER_YSIZE,
- JUMPER_X, JUMPER_Y,
- JUMPER_FRAMES,
- JUMPER_FPS,
- JUMPER_STEPSIZE,
- FALSE,
- ANIMDIR_LEFT,
- ANIMPOS_DOWN},
-
- {CLOWN_XSIZE, CLOWN_YSIZE,
- CLOWN_X, CLOWN_Y,
- CLOWN_FRAMES,
- CLOWN_FPS,
- CLOWN_STEPSIZE,
- FALSE,
- ANIMDIR_UP,
- ANIMPOS_ANY},
-
- {BIRD_XSIZE, BIRD_YSIZE,
- BIRD1_X, BIRD1_Y,
- BIRD_FRAMES,
- BIRD_FPS,
- BIRD_STEPSIZE,
- TRUE,
- ANIMDIR_RIGHT,
- ANIMPOS_UPPER},
-
- {BIRD_XSIZE, BIRD_YSIZE,
- BIRD2_X, BIRD2_Y,
- BIRD_FRAMES,
- BIRD_FPS,
- BIRD_STEPSIZE,
- TRUE,
- ANIMDIR_LEFT,
- ANIMPOS_UPPER}
- };
- struct AnimInfo *anim = &toon[toon_nr];
-
- if (restart)
- {
- horiz_move = (anim->direction & (ANIMDIR_LEFT | ANIMDIR_RIGHT));
- vert_move = (anim->direction & (ANIMDIR_UP | ANIMDIR_DOWN));
- anim_delay_value = 100/anim->frames_per_second;
- frame = 0;
-
- if (horiz_move)
- {
- if (anim->position==ANIMPOS_UP)
- pos_y = 0;
- else if (anim->position==ANIMPOS_DOWN)
- pos_y = FULL_SYSIZE-anim->height;
- else if (anim->position==ANIMPOS_UPPER)
- pos_y = SimpleRND((FULL_SYSIZE-anim->height)/2);
- else
- pos_y = SimpleRND(FULL_SYSIZE-anim->height);
-
- if (anim->direction==ANIMDIR_RIGHT)
- {
- delta_x = anim->stepsize;
- pos_x = -anim->width+delta_x;
- }
- else
- {
- delta_x = -anim->stepsize;
- pos_x = FULL_SXSIZE+delta_x;
- }
- delta_y = 0;
- }
- else
- {
- if (anim->position==ANIMPOS_LEFT)
- pos_x = 0;
- else if (anim->position==ANIMPOS_RIGHT)
- pos_x = FULL_SXSIZE-anim->width;
- else
- pos_x = SimpleRND(FULL_SXSIZE-anim->width);
-
- if (anim->direction==ANIMDIR_DOWN)
- {
- delta_y = anim->stepsize;
- pos_y = -anim->height+delta_y;
- }
- else
- {
- delta_y = -anim->stepsize;
- pos_y = FULL_SYSIZE+delta_y;
- }
- delta_x = 0;
- }
- }
-
- if (pos_x <= -anim->width - anim->stepsize ||
- pos_x >= FULL_SXSIZE + anim->stepsize ||
- pos_y <= -anim->height - anim->stepsize ||
- pos_y >= FULL_SYSIZE + anim->stepsize)
- return(TRUE);
-
- if (!DelayReached(&anim_delay,anim_delay_value))
- {
- if (game_status==HELPSCREEN && !restart)
- DrawAnim(src_x+cut_x,src_y+cut_y, width,height,
- REAL_SX+dest_x,REAL_SY+dest_y, pad_x,pad_y);
-
- return(FALSE);
- }
-
- if (pos_x<-anim->width)
- pos_x = -anim->width;
- else if (pos_x>FULL_SXSIZE)
- pos_x = FULL_SXSIZE;
- if (pos_y<-anim->height)
- pos_y = -anim->height;
- else if (pos_y>FULL_SYSIZE)
- pos_y = FULL_SYSIZE;
-
- pad_x = (horiz_move ? anim->stepsize : 0);
- pad_y = (vert_move ? anim->stepsize : 0);
- src_x = anim->src_x + frame * anim->width;
- src_y = anim->src_y;
- dest_x = pos_x;
- dest_y = pos_y;
- cut_x = cut_y = 0;
- width = anim->width;
- height = anim->height;
-
- if (pos_x<0)
- {
- dest_x = 0;
- width += pos_x;
- cut_x = -pos_x;
- }
- else if (pos_x>FULL_SXSIZE-anim->width)
- width -= (pos_x - (FULL_SXSIZE-anim->width));
-
- if (pos_y<0)
- {
- dest_y = 0;
- height += pos_y;
- cut_y = -pos_y;
- }
- else if (pos_y>FULL_SYSIZE-anim->height)
- height -= (pos_y - (FULL_SYSIZE-anim->height));
-
- DrawAnim(src_x+cut_x,src_y+cut_y, width,height,
- REAL_SX+dest_x,REAL_SY+dest_y, pad_x,pad_y);
-
- pos_x += delta_x;
- pos_y += delta_y;
- frame += frame_step;
-
- if (frame<0 || frame>=anim->frames)
- {
- if (anim->pingpong)
- {
- frame_step *= -1;
- frame = (frame<0 ? 1 : anim->frames-2);
- }
- else
- frame = (frame<0 ? anim->frames-1 : 0);
- }
-
- return(FALSE);
-}
-
-void DrawAnim(int src_x, int src_y, int width, int height,
- int dest_x, int dest_y, int pad_x, int pad_y)
-{
- int buf_x = DOOR_GFX_PAGEX3, buf_y = DOOR_GFX_PAGEY1;
-
-#if 1
- /* special method to avoid flickering interference with BackToFront() */
- XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,dest_x-pad_x,dest_y-pad_y,
- width+2*pad_x,height+2*pad_y, buf_x,buf_y);
- XSetClipOrigin(display,clip_gc[PIX_TOONS],dest_x-src_x,dest_y-src_y);
- XCopyArea(display,pix[PIX_TOONS],backbuffer,clip_gc[PIX_TOONS],
- src_x,src_y, width,height, dest_x,dest_y);
- XCopyArea(display,backbuffer,window,gc, dest_x-pad_x,dest_y-pad_y,
- width+2*pad_x,height+2*pad_y, dest_x-pad_x,dest_y-pad_y);
- BackToFront();
- XCopyArea(display,pix[PIX_DB_DOOR],backbuffer,gc, buf_x,buf_y,
- width+2*pad_x,height+2*pad_y, dest_x-pad_x,dest_y-pad_y);
-#else
- /* normal method, causing flickering interference with BackToFront() */
- XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,dest_x-pad_x,dest_y-pad_y,
- width+2*pad_x,height+2*pad_y, buf_x,buf_y);
- XSetClipOrigin(display,clip_gc[PIX_TOONS],
- buf_x-src_x+pad_x,buf_y-src_y+pad_y);
- XCopyArea(display,pix[PIX_TOONS],pix[PIX_DB_DOOR],clip_gc[PIX_TOONS],
- src_x,src_y, width,height, buf_x+pad_x,buf_y+pad_y);
- XCopyArea(display,pix[PIX_DB_DOOR],window,gc, buf_x,buf_y,
- width+2*pad_x,height+2*pad_y, dest_x-pad_x,dest_y-pad_y);
-#endif
-
- XFlush(display);
-}
#include "main.h"
-/* values for cartoon figures */
-#define NUM_TOONS 6
-
-#define DWARF_XSIZE 40
-#define DWARF_YSIZE 48
-#define DWARF_X 2
-#define DWARF_Y 72
-#define DWARF2_Y 186
-#define DWARF_FRAMES 8
-#define DWARF_FPS 10
-#define DWARF_STEPSIZE 4
-#define JUMPER_XSIZE 48
-#define JUMPER_YSIZE 56
-#define JUMPER_X 2
-#define JUMPER_Y 125
-#define JUMPER_FRAMES 8
-#define JUMPER_FPS 10
-#define JUMPER_STEPSIZE 4
-#define CLOWN_XSIZE 80
-#define CLOWN_YSIZE 110
-#define CLOWN_X 327
-#define CLOWN_Y 10
-#define CLOWN_FRAMES 1
-#define CLOWN_FPS 10
-#define CLOWN_STEPSIZE 4
-#define BIRD_XSIZE 32
-#define BIRD_YSIZE 30
-#define BIRD1_X 2
-#define BIRD1_Y 2
-#define BIRD2_X 2
-#define BIRD2_Y 37
-#define BIRD_FRAMES 8
-#define BIRD_FPS 20
-#define BIRD_STEPSIZE 4
-
-#define ANIMDIR_LEFT 1
-#define ANIMDIR_RIGHT 2
-#define ANIMDIR_UP 4
-#define ANIMDIR_DOWN 8
-
-#define ANIMPOS_ANY 0
-#define ANIMPOS_LEFT 1
-#define ANIMPOS_RIGHT 2
-#define ANIMPOS_UP 4
-#define ANIMPOS_DOWN 8
-#define ANIMPOS_UPPER 16
-
-#define ANIM_START 0
-#define ANIM_CONTINUE 1
-#define ANIM_STOP 2
-
-struct AnimInfo
-{
- int width, height;
- int src_x, src_y;
- int frames;
- int frames_per_second;
- int stepsize;
- BOOL pingpong;
- int direction;
- int position;
-};
-
#define INIT_COUNTER 0
#define READ_COUNTER_100 1
#define READ_COUNTER_1000 2
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);
-void InitAnimation(void);
-void StopAnimation(void);
-void DoAnimation(void);
-void HandleAnimation(int);
-BOOL AnimateToon(int, BOOL);
-void DrawAnim(int, int, int, int, int, int, int, int);
-
#endif
--- /dev/null
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * This is derived from the Berkeley source:
+ * @(#)random.c 5.5 (Berkeley) 7/6/88
+ * It was reworked for the GNU C Library by Roland McGrath.
+ */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "random.h"
+
+
+/* An improved random number generation package. In addition to the standard
+ rand()/srand() like interface, this package also has a special state info
+ interface. The initstate() routine is called with a seed, an array of
+ bytes, and a count of how many bytes are being passed in; this array is
+ then initialized to contain information for random number generation with
+ that much state information. Good sizes for the amount of state
+ information are 32, 64, 128, and 256 bytes. The state can be switched by
+ calling the setstate() function with the same array as was initiallized
+ with initstate(). By default, the package runs with 128 bytes of state
+ information and generates far better random numbers than a linear
+ congruential generator. If the amount of state information is less than
+ 32 bytes, a simple linear congruential R.N.G. is used. Internally, the
+ state information is treated as an array of longs; the zeroeth element of
+ the array is the type of R.N.G. being used (small integer); the remainder
+ of the array is the state information for the R.N.G. Thus, 32 bytes of
+ state information will give 7 longs worth of state information, which will
+ allow a degree seven polynomial. (Note: The zeroeth word of state
+ information also has some other information stored in it; see setstate
+ for details). The random number generation technique is a linear feedback
+ shift register approach, employing trinomials (since there are fewer terms
+ to sum up that way). In this approach, the least significant bit of all
+ the numbers in the state table will act as a linear feedback shift register,
+ and will have period 2^deg - 1 (where deg is the degree of the polynomial
+ being used, assuming that the polynomial is irreducible and primitive).
+ The higher order bits will have longer periods, since their values are
+ also influenced by pseudo-random carries out of the lower bits. The
+ total period of the generator is approximately deg*(2**deg - 1); thus
+ doubling the amount of state information has a vast influence on the
+ period of the generator. Note: The deg*(2**deg - 1) is an approximation
+ only good for large deg, when the period of the shift register is the
+ dominant factor. With deg equal to seven, the period is actually much
+ longer than the 7*(2**7 - 1) predicted by this formula. */
+
+
+
+/* For each of the currently supported random number generators, we have a
+ break value on the amount of state information (you need at least thi
+ bytes of state info to support this random number generator), a degree for
+ the polynomial (actually a trinomial) that the R.N.G. is based on, and
+ separation between the two lower order coefficients of the trinomial. */
+
+/* Linear congruential. */
+#define TYPE_0 0
+#define BREAK_0 8
+#define DEG_0 0
+#define SEP_0 0
+
+/* x**7 + x**3 + 1. */
+#define TYPE_1 1
+#define BREAK_1 32
+#define DEG_1 7
+#define SEP_1 3
+
+/* x**15 + x + 1. */
+#define TYPE_2 2
+#define BREAK_2 64
+#define DEG_2 15
+#define SEP_2 1
+
+/* x**31 + x**3 + 1. */
+#define TYPE_3 3
+#define BREAK_3 128
+#define DEG_3 31
+#define SEP_3 3
+
+/* x**63 + x + 1. */
+#define TYPE_4 4
+#define BREAK_4 256
+#define DEG_4 63
+#define SEP_4 1
+
+
+/* Array versions of the above information to make code run faster.
+ Relies on fact that TYPE_i == i. */
+
+#define MAX_TYPES 5 /* Max number of types above. */
+
+
+
+/* Initially, everything is set up as if from:
+ initstate(1, randtbl, 128);
+ Note that this initialization takes advantage of the fact that srandom
+ advances the front and rear pointers 10*rand_deg times, and hence the
+ rear pointer which starts at 0 will also end up at zero; thus the zeroeth
+ element of the state information, which contains info about the current
+ position of the rear pointer is just
+ (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */
+
+static long int randtbl[DEG_3 + 1] =
+{
+ TYPE_3,
+ -851904987, -43806228, -2029755270, 1390239686, -1912102820,
+ -485608943, 1969813258, -1590463333, -1944053249, 455935928, 508023712,
+ -1714531963, 1800685987, -2015299881, 654595283, -1149023258,
+ -1470005550, -1143256056, -1325577603, -1568001885, 1275120390,
+ -607508183, -205999574, -1696891592, 1492211999, -1528267240,
+ -952028296, -189082757, 362343714, 1424981831, 2039449641,
+};
+
+/* FPTR and RPTR are two pointers into the state info, a front and a rear
+ pointer. These two pointers are always rand_sep places aparts, as they
+ cycle through the state information. (Yes, this does mean we could get
+ away with just one pointer, but the code for random is more efficient
+ this way). The pointers are left positioned as they would be from the call:
+ initstate(1, randtbl, 128);
+ (The position of the rear pointer, rptr, is really 0 (as explained above
+ in the initialization of randtbl) because the state table pointer is set
+ to point to randtbl[1] (as explained below).) */
+
+static long int *fptr = &randtbl[SEP_3 + 1];
+static long int *rptr = &randtbl[1];
+
+
+
+/* The following things are the pointer to the state information table,
+ the type of the current generator, the degree of the current polynomial
+ being used, and the separation between the two pointers.
+ Note that for efficiency of random, we remember the first location of
+ the state information, not the zeroeth. Hence it is valid to access
+ state[-1], which is used to store the type of the R.N.G.
+ Also, we remember the last location, since this is more efficient than
+ indexing every time to find the address of the last element to see if
+ the front and rear pointers have wrapped. */
+
+static long int *state = &randtbl[1];
+
+static int rand_type = TYPE_3;
+static int rand_deg = DEG_3;
+static int rand_sep = SEP_3;
+
+static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
+
+/* Initialize the random number generator based on the given seed. If the
+ type is the trivial no-state-information type, just remember the seed.
+ Otherwise, initializes state[] based on the given "seed" via a linear
+ congruential generator. Then, the pointers are set to known locations
+ that are exactly rand_sep places apart. Lastly, it cycles the state
+ information a given number of times to get rid of any initial dependencies
+ introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
+ for default usage relies on values produced by this routine. */
+
+void srandom_linux_libc(unsigned int x)
+{
+ state[0] = x;
+ if (rand_type != TYPE_0)
+ {
+ register long int i;
+ for (i = 1; i < rand_deg; ++i)
+ state[i] = (1103515145 * state[i - 1]) + 12345;
+ fptr = &state[rand_sep];
+ rptr = &state[0];
+ for (i = 0; i < 10 * rand_deg; ++i)
+ (void) random_linux_libc();
+ }
+}
+
+/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
+ congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
+ same in all ther other cases due to all the global variables that have been
+ set up. The basic operation is to add the number at the rear pointer into
+ the one at the front pointer. Then both pointers are advanced to the next
+ location cyclically in the table. The value returned is the sum generated,
+ reduced to 31 bits by throwing away the "least random" low bit.
+ Note: The code takes advantage of the fact that both the front and
+ rear pointers can't wrap on the same call by not testing the rear
+ pointer if the front one has wrapped. Returns a 31-bit random number. */
+
+long int random_linux_libc()
+{
+ if (rand_type == TYPE_0)
+ {
+ state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX;
+ return state[0];
+ }
+ else
+ {
+ long int i;
+ *fptr += *rptr;
+ /* Chucking least random bit. */
+ i = (*fptr >> 1) & LONG_MAX;
+ ++fptr;
+ if (fptr >= end_ptr)
+ {
+ fptr = state;
+ ++rptr;
+ }
+ else
+ {
+ ++rptr;
+ if (rptr >= end_ptr)
+ rptr = state;
+ }
+ return i;
+ }
+}
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* ©1995 Artsoft Development *
+* Holger Schemel *
+* 33659 Bielefeld-Senne *
+* Telefon: (0521) 493245 *
+* eMail: aeglos@valinor.owl.de *
+* aeglos@uni-paderborn.de *
+* q99492@pbhrzx.uni-paderborn.de *
+*----------------------------------------------------------*
+* random.h *
+***********************************************************/
+
+#ifndef RANDOM_H
+#define RANDOM_H
+
+void srandom_linux_libc(unsigned int);
+long int random_linux_libc(void);
+
+#endif
#include "files.h"
#include "buttons.h"
#include "tape.h"
+#include "joystick.h"
+#include "cartoons.h"
void DrawHeadline()
{
FadeToFront();
InitAnimation();
- HandleMainMenu(0,0,0,0,MB_MENU_MARK);
+ HandleMainMenu(0,0,0,0,MB_MENU_INITIALIZE);
TapeStop();
if (TAPE_IS_EMPTY(tape))
OpenDoor(DOOR_CLOSE_1 | DOOR_OPEN_2);
+ ClearEventQueue();
XAutoRepeatOn(display);
}
static int redraw = TRUE;
int x = (mx+32-SX)/32, y = (my+32-SY)/32;
- if (redraw || (!mx && !my && !dx && !dy))
+ if (redraw || button == MB_MENU_INITIALIZE)
{
DrawGraphic(0,choice-1,GFX_KUGEL_ROT);
redraw = FALSE;
}
+ if (button == MB_MENU_INITIALIZE)
+ return;
+
if (dx || dy)
{
if (dx && choice==4)
game_status = EXITGAME;
}
- redraw = TRUE;
+ if (!button)
+ redraw = TRUE;
}
}
BackToFront();
static int helpscreen_delay[MAX_HELPSCREEN_ELS];
static int helpscreen_action[] =
{
- GFX_SPIELFIGUR,1,100, HA_NEXT,
+ GFX_SPIELER_DOWN,4,2,
+ GFX_SPIELER_UP,4,2,
+ GFX_SPIELER_LEFT,4,2,
+ GFX_SPIELER_RIGHT,4,2,
+ GFX_SPIELER_PUSH_LEFT,4,2,
+ GFX_SPIELER_PUSH_RIGHT,4,2, HA_NEXT,
GFX_ERDREICH,1,100, HA_NEXT,
GFX_LEERRAUM,1,100, HA_NEXT,
GFX_MORAST_LEER,1,100, HA_NEXT,
GFX_MAUER_L1,3,4, GFX_MAUERWERK,1,20, GFX_LEERRAUM,1,10, HA_NEXT,
GFX_UNSICHTBAR,1,100, HA_NEXT,
GFX_FELSBODEN,1,100, HA_NEXT,
- GFX_CHAR_A,30,3, GFX_CHAR_AUSRUF,32,3, HA_NEXT,
+ GFX_CHAR_A,30,4, GFX_CHAR_AUSRUF,32,4, HA_NEXT,
GFX_EDELSTEIN,2,5, HA_NEXT,
GFX_DIAMANT,2,5, HA_NEXT,
GFX_EDELSTEIN_BD,2,5, HA_NEXT,
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_SCHLUESSEL1,4,25, HA_NEXT,
+ GFX_PFORTE1,4,25, HA_NEXT,
+ GFX_PFORTE1X,4,25, 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+0,4,3, GFX_DYNABOMB+3,1,3, GFX_DYNABOMB+2,1,3,
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_BUTTERFLY,2,2, HA_NEXT,
+ GFX_FIREFLY,2,2, 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, 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, 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, GFX_ZOMBIE+0,1,0, HA_NEXT,
+ GFX_MAMPFER+0,4,1, GFX_MAMPFER+3,1,1, GFX_MAMPFER+2,1,1,
+ GFX_MAMPFER+1,1,1, GFX_MAMPFER+0,1,1, HA_NEXT,
+ GFX_MAMPFER2+0,4,1, GFX_MAMPFER2+3,1,1, GFX_MAMPFER2+2,1,1,
+ GFX_MAMPFER2+1,1,1, GFX_MAMPFER2+0,1,1, HA_NEXT,
+ GFX_ROBOT+0,4,1, GFX_ROBOT+3,1,1, GFX_ROBOT+2,1,1,
+ GFX_ROBOT+1,1,1, GFX_ROBOT+0,1,1, HA_NEXT,
+ GFX_MAULWURF_DOWN,4,2,
+ GFX_MAULWURF_UP,4,2,
+ GFX_MAULWURF_LEFT,4,2,
+ GFX_MAULWURF_RIGHT,4,2, HA_NEXT,
+ GFX_PINGUIN_DOWN,4,2,
+ GFX_PINGUIN_UP,4,2,
+ GFX_PINGUIN_LEFT,4,2,
+ GFX_PINGUIN_RIGHT,4,2, HA_NEXT,
+ GFX_SCHWEIN_DOWN,4,2,
+ GFX_SCHWEIN_UP,4,2,
+ GFX_SCHWEIN_LEFT,4,2,
+ GFX_SCHWEIN_RIGHT,4,2, HA_NEXT,
+ GFX_DRACHE_DOWN,4,2,
+ GFX_DRACHE_UP,4,2,
+ GFX_DRACHE_LEFT,4,2,
+ GFX_DRACHE_RIGHT,4,2, HA_NEXT,
+ GFX_SONDE_START,8,1, 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,
- GFX_TROPFEN,1,33, GFX_AMOEBING,4,1, GFX_AMOEBE_LEBT,1,10, HA_NEXT,
+ GFX_BIRNE_AUS,1,25, GFX_BIRNE_EIN,1,25, HA_NEXT,
+ GFX_ZEIT_VOLL,1,25, GFX_ZEIT_LEER,1,25, HA_NEXT,
+ GFX_TROPFEN,1,25, GFX_AMOEBING,4,1, GFX_AMOEBE_LEBT,1,10, HA_NEXT,
GFX_AMOEBE_TOT+2,2,50, GFX_AMOEBE_TOT,2,50, HA_NEXT,
GFX_AMOEBE_LEBT,4,40, HA_NEXT,
GFX_AMOEBE_LEBT,1,10, GFX_AMOEBING,4,2, HA_NEXT,
- GFX_AMOEBE_LEBT,1,33, GFX_AMOEBE_TOT,1,33, GFX_EXPLOSION,8,1,
+ GFX_AMOEBE_LEBT,1,25, GFX_AMOEBE_TOT,1,25, GFX_EXPLOSION,8,1,
GFX_DIAMANT,1,10, HA_NEXT,
GFX_LIFE,1,100, HA_NEXT,
GFX_LIFE_ASYNC,1,100, HA_NEXT,
GFX_SIEB_LEER,4,2, HA_NEXT,
GFX_SIEB2_LEER,4,2, HA_NEXT,
GFX_AUSGANG_ZU,1,100, GFX_AUSGANG_ACT,4,2,
- GFX_AUSGANG_AUF+0,4,1, GFX_AUSGANG_AUF+3,1,1,
- GFX_AUSGANG_AUF+2,1,1, GFX_AUSGANG_AUF+1,1,1, HA_NEXT,
- GFX_AUSGANG_AUF+0,4,1, GFX_AUSGANG_AUF+3,1,1,
- GFX_AUSGANG_AUF+2,1,1, GFX_AUSGANG_AUF+1,1,1, HA_NEXT,
+ GFX_AUSGANG_AUF+0,4,2, GFX_AUSGANG_AUF+3,1,2,
+ GFX_AUSGANG_AUF+2,1,2, GFX_AUSGANG_AUF+1,1,2, HA_NEXT,
+ GFX_AUSGANG_AUF+0,4,2, GFX_AUSGANG_AUF+3,1,2,
+ GFX_AUSGANG_AUF+2,1,2, GFX_AUSGANG_AUF+1,1,2, HA_NEXT,
HA_END
};
static char *helpscreen_eltext[][2] =
{"Cruncher: Eats diamonds and you,", "if you're not careful"},
{"Cruncher (BD style):", "Eats almost everything"},
{"Robot: Tries to kill the player", ""},
+ {"The mole: You must guide him savely","to the exit; he will follow you"},
+ {"The penguin: Guide him to the exit,","but keep him away from monsters!"},
+ {"The Pig: Harmless, but eats all", "gems it can get"},
+ {"The Dragon: Breathes fire,", "especially to some monsters"},
+ {"Sonde: Follows you everywhere;", "harmless, but may block your way"},
{"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"},
void DrawHelpScreenElAction(int start)
{
int i = 0, j = 0;
- int frame, delay, graphic;
+ int frame, graphic;
int xstart = SX+16, ystart = SY+64+2*32, ystep = TILEY+4;
while(helpscreen_action[j] != HA_END)
helpscreen_frame[i-start] = helpscreen_action[j++]-1;
}
- delay = helpscreen_action[j++];
- helpscreen_delay[i-start] = delay;
+ helpscreen_delay[i-start] = helpscreen_action[j++] - 1;
if (helpscreen_action[j] == HA_NEXT)
{
}
else
{
- if (DelayReached(&hs_delay,3))
+ if (DelayReached(&hs_delay,GAME_FRAME_DELAY))
{
if (helpscreen_state<num_helpscreen_els_pages)
DrawHelpScreenElAction(helpscreen_state*MAX_HELPSCREEN_ELS);
player.alias_name,FS_BIG,FC_YELLOW);
DrawGraphic(xpos+6,ypos,GFX_KUGEL_ROT);
}
- else if (key==XK_Delete && xpos>0)
+ else if ((key==XK_Delete || key==XK_BackSpace) && xpos>0)
{
xpos--;
player.alias_name[xpos] = 0;
FadeToFront();
InitAnimation();
- HandleChooseLevel(0,0,0,0,MB_MENU_MARK);
+ HandleChooseLevel(0,0,0,0,MB_MENU_INITIALIZE);
}
void HandleChooseLevel(int mx, int my, int dx, int dy, int button)
static int redraw = TRUE;
int x = (mx+32-SX)/32, y = (my+32-SY)/32;
+ if (button == MB_MENU_INITIALIZE)
+ {
+ redraw = TRUE;
+ choice = leveldir_nr + 3;
+ }
+
if (redraw)
{
DrawGraphic(0,choice-1,GFX_KUGEL_ROT);
redraw = FALSE;
}
+ if (button == MB_MENU_INITIALIZE)
+ return;
+
if (dx || dy)
{
if (dy)
FadeToFront();
InitAnimation();
- HandleSetupScreen(0,0,0,0,MB_MENU_MARK);
+ HandleSetupScreen(0,0,0,0,MB_MENU_INITIALIZE);
}
void HandleSetupScreen(int mx, int my, int dx, int dy, int button)
int pos_empty = SETUP_SCREEN_POS_EMPTY + 1;
int pos_end = SETUP_SCREEN_POS_END + 1;
+ if (button == MB_MENU_INITIALIZE)
+ redraw = TRUE;
+
if (redraw)
{
DrawGraphic(0,choice-1,GFX_KUGEL_ROT);
redraw = FALSE;
}
+ if (button == MB_MENU_INITIALIZE)
+ return;
+
if (dx || dy)
{
if (dy)
if (LevelSolved)
GameWon();
- if (GameOver && !TAPE_IS_STOPPED(tape))
+ if (PlayerGone && !TAPE_IS_STOPPED(tape))
TapeStop();
GameActions();
tape.pos[tape.counter].delay = tape.delay_played;
tape.playing = FALSE;
tape.recording = TRUE;
+ tape.changed = TRUE;
DrawVideoDisplay(VIDEO_STATE_PLAY_OFF | VIDEO_STATE_REC_ON,0);
}
/*** THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS ***/
+static unsigned long be2long(unsigned long *be) /* big-endian -> longword */
+{
+ unsigned char *ptr = (unsigned char *)be;
+
+ return(ptr[0]<<24 | ptr[1]<<16 | ptr[2]<<8 | ptr[3]);
+}
+
BOOL LoadSound(struct SoundInfo *snd_info)
{
FILE *file;
char filename[256];
char *sound_ext = "8svx";
- struct SoundHeader_8SVX *snd_hdr;
+ struct SoundHeader_8SVX *sound_header;
unsigned char *ptr;
sprintf(filename,"%s/%s.%s",SND_PATH,snd_info->name,sound_ext);
fclose(file);
- snd_hdr = (struct SoundHeader_8SVX *)snd_info->file_ptr;
+ sound_header = (struct SoundHeader_8SVX *)snd_info->file_ptr;
- if (strncmp(snd_hdr->magic_FORM,"FORM",4) ||
- snd_info->file_len!=be2long(&snd_hdr->chunk_size)+8 ||
- strncmp(snd_hdr->magic_8SVX,"8SVX",4))
+ if (strncmp(sound_header->magic_FORM,"FORM",4) ||
+ snd_info->file_len != be2long(&sound_header->chunk_size)+8 ||
+ strncmp(sound_header->magic_8SVX,"8SVX",4))
{
fprintf(stderr,"%s: '%s' is not an IFF/8SVX file or broken- no sounds\n",
progname,filename);
return(FALSE);
}
- ptr = (unsigned char *)snd_info->file_ptr;
+ ptr = snd_info->file_ptr + 12;
- while(ptr<(unsigned char *)snd_info->file_ptr+snd_info->file_len)
+ while(ptr < (unsigned char *)(snd_info->file_ptr + snd_info->file_len))
{
if (!strncmp(ptr,"VHDR",4))
{
- ptr+=be2long((unsigned long *)(ptr+4));
+ ptr += be2long((unsigned long *)(ptr + 4)) + 8;
+ continue;
}
- if (!strncmp(ptr,"ANNO",4))
+ else if (!strncmp(ptr,"ANNO",4))
{
- ptr+=be2long((unsigned long *)(ptr+4));
+ ptr += be2long((unsigned long *)(ptr + 4)) + 8;
+ continue;
}
- if (!strncmp(ptr,"CHAN",4))
+ else if (!strncmp(ptr,"CHAN",4))
{
- ptr+=be2long((unsigned long *)(ptr+4));
+ ptr += be2long((unsigned long *)(ptr + 4)) + 8;
+ continue;
}
- if (!strncmp(ptr,"BODY",4))
+ else if (!strncmp(ptr,"BODY",4))
{
- snd_info->data_ptr = ptr+8;
- snd_info->data_len = be2long((unsigned long *)(ptr+4));
+ snd_info->data_ptr = ptr + 8;
+ snd_info->data_len = be2long((unsigned long *)(ptr + 4));
return(TRUE);
}
- ptr++;
+ else
+ {
+ /* other chunk not recognized here */
+ ptr += be2long((unsigned long *)(ptr + 4)) + 8;
+ continue;
+ }
}
return(FALSE);
struct SoundInfo
{
- char *name;
- char *file_ptr, *data_ptr;
+ unsigned char *name;
+ unsigned char *file_ptr;
+ char *data_ptr;
long file_len, data_len;
};
char *data_ptr;
};
-/* function from "misc.c" */
-unsigned long be2long(unsigned long *);
-
/* sound server functions */
void SoundServer(void);
void SoundServer_InsertNewSound(struct SoundControl);
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.changed = TRUE;
tape.date = 10000*(zeit2->tm_year%100) + 100*zeit2->tm_mon + zeit2->tm_mday;
tape.random_seed = InitRND(NEW_RANDOMIZE);
if (tape.counter>=tape.length)
{
- TapeStopPlaying();
+ TapeStop();
return(0);
}
if (tape.counter>=tape.length)
{
- TapeStopPlaying();
+ TapeStop();
return(TRUE);
}
#include "sound.h"
#include "misc.h"
#include "buttons.h"
+#include "joystick.h"
+#include "cartoons.h"
+
#include <math.h>
void BackToFront()
}
}
+void DrawPlayerField()
+{
+ int x = JX, y = JY;
+ int sx = SCROLLX(x), sy = SCROLLY(y);
+ int element = Feld[x][y];
+ int graphic, phase;
+ BOOL draw_thru_mask = FALSE;
+
+ if (PlayerGone)
+ return;
+
+#if DEBUG
+ if (!IN_LEV_FIELD(x,y) || !IN_SCR_FIELD(sx,sy))
+ {
+ printf("DrawPlayerField(): x = %d, y = %d\n",x,y);
+ printf("DrawPlayerField(): This should never happen!\n");
+ return;
+ }
+#endif
+
+ if (element == EL_EXPLODING)
+ return;
+
+ if (direct_draw_on)
+ drawto_field = backbuffer;
+
+ /* draw things behind the player (EL_PFORTE* || mole/penguin/pig/dragon) */
+
+ if (Store[x][y])
+ {
+ DrawGraphic(sx,sy, el2gfx(Store[x][y]));
+ draw_thru_mask = TRUE;
+ }
+ else if (element!=EL_LEERRAUM && element!=EL_DYNAMIT && element!=EL_DYNABOMB)
+ {
+ DrawLevelField(x,y);
+ draw_thru_mask = TRUE;
+ }
+
+ /* draw player himself */
+
+ if (PlayerMovDir==MV_LEFT)
+ graphic = (PlayerPushing ? GFX_SPIELER_PUSH_LEFT : GFX_SPIELER_LEFT);
+ else if (PlayerMovDir==MV_RIGHT)
+ graphic = (PlayerPushing ? GFX_SPIELER_PUSH_RIGHT : GFX_SPIELER_RIGHT);
+ else if (PlayerMovDir==MV_UP)
+ graphic = GFX_SPIELER_UP;
+ else /* MV_DOWN || MV_NO_MOVING */
+ graphic = GFX_SPIELER_DOWN;
+
+ graphic += PlayerFrame;
+
+ if (draw_thru_mask)
+ DrawGraphicThruMask(sx,sy, graphic);
+ else
+ DrawGraphic(sx,sy, graphic);
+
+ /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */
+
+ if (element == EL_DYNAMIT || element == EL_DYNABOMB)
+ {
+ graphic = el2gfx(element);
+
+ if (element == EL_DYNAMIT)
+ {
+ if ((phase = (48-MovDelay[x][y])/6) > 6)
+ phase = 6;
+ }
+ else
+ {
+ if ((phase = ((48-MovDelay[x][y])/3) % 8) > 3)
+ phase = 7-phase;
+ }
+
+ DrawGraphicThruMask(sx,sy, graphic + phase);
+ }
+
+ if (direct_draw_on)
+ {
+ int dest_x = SX+SCROLLX(x)*TILEX;
+ int dest_y = SY+SCROLLY(y)*TILEY;
+
+ XCopyArea(display,backbuffer,window,gc,
+ dest_x,dest_y, TILEX,TILEY, dest_x,dest_y);
+ drawto_field = window;
+ }
+}
+
+static int getGraphicAnimationPhase(int frames, int delay, int mode)
+{
+ int phase;
+
+ if (mode == ANIM_OSCILLATE)
+ {
+ int max_anim_frames = frames*2 - 2;
+ phase = (FrameCounter % (delay * max_anim_frames)) / delay;
+ phase = (phase < frames ? phase : max_anim_frames - phase);
+ }
+ else
+ phase = (FrameCounter % (delay * frames)) / delay;
+
+ return(phase);
+}
+
void DrawGraphicAnimation(int x, int y, int graphic,
int frames, int delay, int mode)
{
+ int phase = getGraphicAnimationPhase(frames, delay, mode);
+
+/*
int phase;
if (mode == ANIM_OSCILLATE)
}
else
phase = (FrameCounter % (delay * frames)) / delay;
+*/
if (!(FrameCounter % delay) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
DrawGraphic(SCROLLX(x),SCROLLY(y), graphic + phase);
void DrawGraphic(int x, int y, int graphic)
{
+
+#if DEBUG
+ if (!IN_SCR_FIELD(x,y))
+ {
+ printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
+ printf("DrawGraphic(): This should never happen!\n");
+ return;
+ }
+#endif
+
DrawGraphicExt(drawto_field, gc, x, y, graphic);
redraw_tiles++;
redraw[x][y] = TRUE;
void DrawGraphicExtHiRes(Drawable d, GC gc, int x, int y, int graphic)
{
- if (graphic<0)
- XFillRectangle(display,d,gc, x,y, TILEX,TILEY);
- else if (graphic<256)
+ if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
+ {
+ graphic -= GFX_START_ROCKSSCREEN;
XCopyArea(display,pix[PIX_BACK],d,gc,
SX+(graphic % GFX_PER_LINE)*TILEX,
SY+(graphic / GFX_PER_LINE)*TILEY,
TILEX,TILEY, x,y);
- else
+ }
+ else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
{
- graphic -= 256;
+ graphic -= GFX_START_ROCKSHEROES;
+ XCopyArea(display,pix[PIX_HEROES],d,gc,
+ (graphic % HEROES_PER_LINE)*TILEX,
+ (graphic / HEROES_PER_LINE)*TILEY,
+ TILEX,TILEY, x,y);
+ }
+ else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
+ {
+ graphic -= GFX_START_ROCKSFONT;
XCopyArea(display,pix[PIX_BIGFONT],d,gc,
(graphic % FONT_CHARS_PER_LINE)*TILEX,
(graphic / FONT_CHARS_PER_LINE)*TILEY +
FC_SPECIAL1*TILEY*FONT_LINES_PER_FONT,
TILEX,TILEY, x,y);
}
+ else
+ XFillRectangle(display,d,gc, x,y, TILEX,TILEY);
}
void DrawGraphicThruMask(int x, int y, int graphic)
{
int src_x,src_y, dest_x,dest_y;
- if (graphic<0 || graphic>255)
+#if DEBUG
+ if (!IN_SCR_FIELD(x,y))
{
- DrawGraphic(x,y,graphic);
+ printf("DrawGraphicThruMask(): x = %d, y = %d\n",x,y);
+ printf("DrawGraphicThruMask(): This should never happen!\n");
return;
}
+#endif
- src_x = SX+(graphic % GFX_PER_LINE)*TILEX;
- src_y = SY+(graphic / GFX_PER_LINE)*TILEY;
- dest_x = SX+x*TILEX;
- dest_y = SY+y*TILEY;
-
- 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 (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
+ {
+ graphic -= GFX_START_ROCKSSCREEN;
+ src_x = SX+(graphic % GFX_PER_LINE)*TILEX;
+ src_y = SY+(graphic / GFX_PER_LINE)*TILEY;
+ dest_x = SX+x*TILEX;
+ dest_y = SY+y*TILEY;
+
+ 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);
+ }
+ else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
+ {
+ graphic -= GFX_START_ROCKSHEROES;
+ src_x = (graphic % HEROES_PER_LINE)*TILEX;
+ src_y = (graphic / HEROES_PER_LINE)*TILEY;
+ dest_x = SX+x*TILEX;
+ dest_y = SY+y*TILEY;
+
+ XSetClipOrigin(display,clip_gc[PIX_HEROES],dest_x-src_x,dest_y-src_y);
+ XCopyArea(display,pix[PIX_HEROES],drawto_field,clip_gc[PIX_HEROES],
+ src_x,src_y, TILEX,TILEY, dest_x,dest_y);
+ }
+ else
+ {
+ DrawGraphic(x,y,graphic);
+ return;
+ }
redraw_tiles++;
redraw[x][y]=TRUE;
void DrawMiniGraphicExtHiRes(Drawable d, GC gc, int x, int y, int graphic)
{
- if (graphic<0)
- XFillRectangle(display,d,gc, x,y, MINI_TILEX,MINI_TILEY);
- else if (graphic<256)
+ if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
+ {
+ graphic -= GFX_START_ROCKSSCREEN;
XCopyArea(display,pix[PIX_BACK],d,gc,
MINI_GFX_STARTX+(graphic % MINI_GFX_PER_LINE)*MINI_TILEX,
MINI_GFX_STARTY+(graphic / MINI_GFX_PER_LINE)*MINI_TILEY,
MINI_TILEX,MINI_TILEY, x,y);
- else
+ }
+ else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
{
- graphic -= 256;
+ graphic -= GFX_START_ROCKSFONT;
XCopyArea(display,pix[PIX_SMALLFONT],d,gc,
(graphic % FONT_CHARS_PER_LINE)*FONT4_XSIZE,
(graphic / FONT_CHARS_PER_LINE)*FONT4_YSIZE +
FC_SPECIAL2*FONT2_YSIZE*FONT_LINES_PER_FONT,
MINI_TILEX,MINI_TILEY, x,y);
}
+ else
+ XFillRectangle(display,d,gc, x,y, MINI_TILEX,MINI_TILEY);
}
void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic, int cut_mode)
redraw[x][y+SIGN(dy)]=TRUE;
}
- XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
- SX+(graphic % GFX_PER_LINE)*TILEX+cx,
- SY+(graphic / GFX_PER_LINE)*TILEY+cy,
- width,height, SX+x*TILEX+dx,SY+y*TILEY+dy);
+ if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
+ {
+ graphic -= GFX_START_ROCKSSCREEN;
+ XCopyArea(display,pix[PIX_BACK],drawto_field,gc,
+ SX+(graphic % GFX_PER_LINE)*TILEX+cx,
+ SY+(graphic / GFX_PER_LINE)*TILEY+cy,
+ width,height, SX+x*TILEX+dx,SY+y*TILEY+dy);
+ }
+ else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
+ {
+ graphic -= GFX_START_ROCKSHEROES;
+ XCopyArea(display,pix[PIX_HEROES],drawto_field,gc,
+ (graphic % HEROES_PER_LINE)*TILEX+cx,
+ (graphic / HEROES_PER_LINE)*TILEY+cy,
+ width,height, SX+x*TILEX+dx,SY+y*TILEY+dy);
+ }
+
+#if DEBUG
+ if (!IN_SCR_FIELD(x,y))
+ {
+ printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
+ printf("DrawGraphicShifted(): This should never happen!\n");
+ return;
+ }
+#endif
redraw_tiles++;
redraw[x][y]=TRUE;
{
int ux = UNSCROLLX(x), uy = UNSCROLLY(y);
int graphic = el2gfx(element);
- int phase = ABS(MovPos[ux][uy])/(TILEX/2);
+ int phase4 = ABS(MovPos[ux][uy])/(TILEX/4);
+ int phase = phase4 / 2;
int dir = MovDir[ux][uy];
-/*
- int horiz_move = (dir==MV_LEFT || dir==MV_RIGHT);
-*/
-
- if (element==EL_PACMAN ||
- element==EL_KAEFER ||
- element==EL_FLIEGER ||
- element==EL_BUTTERFLY ||
- element==EL_FIREFLY)
+ if (element==EL_PACMAN || element==EL_KAEFER || element==EL_FLIEGER)
{
- if (element==EL_BUTTERFLY || element==EL_FIREFLY)
- graphic += !phase;
+ graphic += 4*!phase;
+
+ if (dir==MV_UP)
+ graphic += 1;
+ else if (dir==MV_LEFT)
+ graphic += 2;
+ else if (dir==MV_DOWN)
+ graphic += 3;
+ }
+ else if (element==EL_MAULWURF || element==EL_PINGUIN ||
+ element==EL_SCHWEIN || element==EL_DRACHE)
+ {
+ if (dir==MV_LEFT)
+ graphic = (element==EL_MAULWURF ? GFX_MAULWURF_LEFT :
+ element==EL_PINGUIN ? GFX_PINGUIN_LEFT :
+ element==EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
+ else if (dir==MV_RIGHT)
+ graphic = (element==EL_MAULWURF ? GFX_MAULWURF_RIGHT :
+ element==EL_PINGUIN ? GFX_PINGUIN_RIGHT :
+ element==EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
+ else if (dir==MV_UP)
+ graphic = (element==EL_MAULWURF ? GFX_MAULWURF_UP :
+ element==EL_PINGUIN ? GFX_PINGUIN_UP :
+ element==EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
else
- {
- graphic += 4*!phase;
-
- if (dir==MV_UP)
- graphic += 1;
- else if (dir==MV_LEFT)
- graphic += 2;
- else if (dir==MV_DOWN)
- graphic += 3;
- }
+ graphic = (element==EL_MAULWURF ? GFX_MAULWURF_DOWN :
+ element==EL_PINGUIN ? GFX_PINGUIN_DOWN :
+ element==EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
+
+ graphic += phase4;
+ }
+ else if (element==EL_SONDE)
+ {
+ graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
+ }
+ else if (element==EL_BUTTERFLY || element==EL_FIREFLY)
+ {
+ graphic += !phase;
}
else if ((element==EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
{
}
break;
case FocusIn:
- HandleFocusEvent(FOCUS_IN);
- break;
case FocusOut:
- HandleFocusEvent(FOCUS_OUT);
+ HandleFocusEvent((XFocusChangeEvent *) &event);
break;
default:
break;
return(XGetPixel(pixelimage,0,0));
}
-void CheckJoystickData()
-{
- int i;
- int distance = 100;
-
- for(i=0;i<2;i++)
- {
- if (joystick[i].xmiddle <= distance)
- joystick[i].xmiddle = distance;
- if (joystick[i].ymiddle <= distance)
- joystick[i].ymiddle = distance;
-
- if (joystick[i].xleft >= joystick[i].xmiddle)
- joystick[i].xleft = joystick[i].xmiddle-distance;
- if (joystick[i].xright <= joystick[i].xmiddle)
- joystick[i].xright = joystick[i].xmiddle+distance;
-
- if (joystick[i].yupper >= joystick[i].ymiddle)
- joystick[i].yupper = joystick[i].ymiddle-distance;
- if (joystick[i].ylower <= joystick[i].ymiddle)
- joystick[i].ylower = joystick[i].ymiddle+distance;
- }
-}
-
-int JoystickPosition(int middle, int margin, int actual)
-{
- long range, pos;
- int percentage;
-
- if (margin<middle && actual>middle)
- return(0);
- if (margin>middle && actual<middle)
- return(0);
-
- range = ABS(margin-middle);
- pos = ABS(actual-middle);
- percentage = (int)(pos*100/range);
- if (percentage>100)
- percentage = 100;
-
- return(percentage);
-}
-
-int Joystick()
-{
-#ifdef __FreeBSD__
- struct joystick joy_ctrl;
-#else
- struct joystick_control
- {
- int buttons;
- int x;
- int y;
- } joy_ctrl;
-#endif
-
- int js_x,js_y, js_b1,js_b2;
- int left, right, up, down;
- int result=0;
-
- if (joystick_status==JOYSTICK_OFF)
- return(0);
-
- if (read(joystick_device, &joy_ctrl, sizeof(joy_ctrl)) != sizeof(joy_ctrl))
- {
- fprintf(stderr,"%s: cannot read joystick settings - no joystick support\n",
- progname);
- joystick_status = JOYSTICK_OFF;
- return(0);
- }
-
- js_x = joy_ctrl.x;
- js_y = joy_ctrl.y;
-#ifdef __FreeBSD__
- js_b1 = joy_ctrl.b1;
- js_b2 = joy_ctrl.b2;
-#else
- js_b1 = joy_ctrl.buttons & 1;
- js_b2 = joy_ctrl.buttons & 2;
-#endif
-
- left = JoystickPosition(joystick[joystick_nr].xmiddle,
- joystick[joystick_nr].xleft, js_x);
- right = JoystickPosition(joystick[joystick_nr].xmiddle,
- joystick[joystick_nr].xright, js_x);
- up = JoystickPosition(joystick[joystick_nr].ymiddle,
- joystick[joystick_nr].yupper, js_y);
- down = JoystickPosition(joystick[joystick_nr].ymiddle,
- joystick[joystick_nr].ylower, js_y);
-
- if (left>JOYSTICK_PERCENT)
- result |= JOY_LEFT;
- else if (right>JOYSTICK_PERCENT)
- result |= JOY_RIGHT;
- if (up>JOYSTICK_PERCENT)
- result |= JOY_UP;
- else if (down>JOYSTICK_PERCENT)
- result |= JOY_DOWN;
- if (js_b1)
- result |= JOY_BUTTON_1;
- if (js_b2)
- result |= JOY_BUTTON_2;
-
- return(result);
-}
-
-int JoystickButton()
-{
- static int last_joy_button = 0;
- int joy_button = (Joystick() & JOY_BUTTON);
- int result;
-
- if (joy_button)
- {
- if (last_joy_button)
- result = JOY_BUTTON_PRESSED;
- else
- result = JOY_BUTTON_NEW_PRESSED;
- }
- else
- {
- if (last_joy_button)
- result = JOY_BUTTON_NEW_RELEASED;
- else
- result = JOY_BUTTON_NOT_PRESSED;
- }
-
- last_joy_button = joy_button;
- return(result);
-}
-
int el2gfx(int element)
{
switch(element)
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_ROBOT: return(GFX_ROBOT);
case EL_BETON: return(GFX_BETON);
case EL_DIAMANT: return(GFX_DIAMANT);
case EL_MORAST_LEER: return(GFX_MORAST_LEER);
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);
+ case EL_MAULWURF: return(GFX_MAULWURF);
+ case EL_PINGUIN: return(GFX_PINGUIN);
+ case EL_SCHWEIN: return(GFX_SCHWEIN);
+ case EL_DRACHE: return(GFX_DRACHE);
+ case EL_SONDE: return(GFX_SONDE);
+ case EL_PFEIL_L: return(GFX_PFEIL_L);
+ case EL_PFEIL_R: return(GFX_PFEIL_R);
+ case EL_PFEIL_O: return(GFX_PFEIL_O);
+ case EL_PFEIL_U: return(GFX_PFEIL_U);
default:
{
if (IS_CHAR(element))
#include <sys/time.h>
-/* für DrawGraphicAnimation */
-#define ANIM_NORMAL 0
-#define ANIM_OSCILLATE 1
-
/* für DrawElementShifted */
#define CUT_NO_CUTTING 0
#define CUT_ABOVE 1
void ClearWindow();
void DrawText(int, int, char *, int, int);
void DrawTextExt(Drawable, GC, int, int, char *, int, int);
+void DrawPlayerField(void);
void DrawGraphicAnimation(int, int, int, int, int, int);
void DrawGraphic(int, int, int);
void DrawGraphicExt(Drawable, GC, int, int, int);
unsigned int GetDoorState(void);
unsigned int MoveDoor(unsigned int);
int ReadPixel(Drawable, int, int);
-void CheckJoystickData(void);
-int JoystickPosition(int, int, int);
-int Joystick(void);
-int JoystickButton(void);
int el2gfx(int);
#endif