import: xrick-021212 from BigOrno

This commit is contained in:
dwsJason 2018-07-14 11:42:18 -04:00
parent 5eb305f468
commit 69a5982d6b
86 changed files with 58770 additions and 2 deletions

78
KeyCodes Normal file
View File

@ -0,0 +1,78 @@
BACKSPACE
TAB
CLEAR
RETURN
PAUSE
ESCAPE
SPACE
EXCLAIM
QUOTEDBL
HASH
DOLLAR
AMPERSAND
QUOTE
LEFTPAREN
RIGHTPAREN
ASTERISK
PLUS
COMMA
MINUS
PERIOD
SLASH
0 ... 9
COLON
SEMICOLON
LESS
EQUALS
GREATER
QUESTION
AT
LEFTBRACKET
BACKSLASH
RIGHTBRACKET
CARET
UNDERSCORE
BACKQUOTE
a ... z
DELETE
WORLD_0 ... WODLD_95
KP0 ... KP9
KP_PERIOD
KP_DIVIDE
KP_MULTIPLY
KP_MINUS
KP_PLUS
KP_ENTER
KP_EQUALS
UP
DOWN
RIGHT
LEFT
INSERT
HOME
END
PAGEUP
PAGEDOWN
F1 ... F15
NUMLOCK
CAPSLOCK
SCROLLOCK
RSHIFT
LSHIFT
RCTRL
LCTRL
RALT
LALT
RMETA
LMETA
LSUPER
RSUPER
MODE
COMPOSE
HELP
PRINT
SYSREQ
BREAK
MENU
POWER
EURO

89
Makefile Normal file
View File

@ -0,0 +1,89 @@
#
# xrick/Makefile
#
# Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
#
# The use and distribution terms for this software are contained in the file
# named README, which can be found in the root of this distribution. By
# using this software in any fashion, you are agreeing to be bound by the
# terms of this license.
#
# You must not remove this notice, or any other, from this software.
#
#
# Vars
#
SDLVERSION=$(shell sdl-config --version 2>/dev/null)
ROOTDIR=$(shell pwd)
TARGET=$(shell uname -s | tr [a-z] [A-Z])
#
# Config
#
ifeq ($(strip $(SDLVERSION)),)
$(error SDL is missing)
else
$(warning Detected SDL version $(SDLVERSION))
endif
ifeq ($(strip $(SDLVERSION)),)
$(error SDL is missing)
endif
SDL_MAJ=$(word 1,$(subst ., ,$(SDLVERSION)))
SDL_MIN=$(word 2,$(subst ., ,$(SDLVERSION)))
SDL_MIC=$(word 3,$(subst ., ,$(SDLVERSION)))
SDL_MAJ_REQ=1
SDL_MIN_REQ=2
SDL_MIC_REQ=1
SDL_CHKVER=$(shell if [ $(SDL_MAJ) -lt $(SDL_MAJ_REQ) ]; then echo "BAD"; fi)
ifeq ($(SDL_CHKVER),BAD)
$(error SDL version $(SDL_MAJ_REQ).$(SDL_MIN_REQ).$(SDL_MIC_REQ) is required)
endif
SDL_CHKVER=$(shell if [ $(SDL_MAJ) -eq $(SDL_MAJ_REQ) -a $(SDL_MIN) -lt $(SDL_MIN_REQ) ]; then echo "BAD"; fi)
ifeq ($(SDL_CHKVER),BAD)
$(error SDL version $(SDL_MAJ_REQ).$(SDL_MIN_REQ).$(SDL_MIC_REQ) is required)
endif
SDL_CHKVER=$(shell if [ $(SDL_MAJ) -eq $(SDL_MAJ_REQ) -a $(SDL_MIN) -eq $(SDL_MIN_REQ) -a $(SDL_MIC) -lt $(SDL_MIC_REQ) ]; then echo "BAD"; fi)
ifeq ($(SDL_CHKVER),BAD)
$(error SDL version $(SDL_MAJ_REQ).$(SDL_MIN_REQ).$(SDL_MIC_REQ) is required)
endif
ifneq (,$(findstring CYGWIN,$(TARGET)))
XOBJ=xrick.res
endif
ifneq (,$(findstring MINGW,$(TARGET)))
XOBJ=xrick.res
endif
#
# Rules
#
all:
@echo "ROOTDIR=$(ROOTDIR)" > Makefile.global
@echo "XOBJ=$(XOBJ)" >> Makefile.global
@echo "CFLAGS=-g -ansi -pedantic -Wall -W -O2 -I $(ROOTDIR)/include $(shell sdl-config --cflags)" >> Makefile.global
@echo "LDFLAGS=-lz $(shell sdl-config --libs)" >> Makefile.global
@echo "CC=gcc" >> Makefile.global
@echo "CPP=gcc -E" >> Makefile.global
$(MAKE) -C src all
clean:
for i in src include; do \
$(MAKE) -C $$i clean; \
done
rm -f *~ log.txt Makefile.global
depend:
$(MAKE) -C src depend
# eof

59
README Normal file
View File

@ -0,0 +1,59 @@
**
xrick - version #021212
Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net)
http://www.bigorno.net/xrick/
** LICENSE AGREEMENT & LEGAL BABLE
I have written the xrick code. However, graphics and maps and sounds
are by the authors of the original Rick Dangerous game, and "Rick
Dangerous" remains a trademark of its owner(s) -- maybe Core Design
(who wrote the game) or FireBird (who published it). As of today, I
have not been successful at contacting Core Design.
This makes it a bit difficult to formally release the whole code,
including data for graphics and maps and sounds, under the terms of
licences such as the GNU General Public Licence. So the code is
released "in the spirit" of the GNU GPL. Whatever that means.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.
** HOWTO
Build: ./config; make
Usage: 'xrick -help' will tell you all about command-line options.
Controls:
- left, right, up (jump) or down (crawl): arrow keys or Z, X, O and K.
- fire: SPACE, end: E, pause: P, exit: ESC.
- use left, right, up, down + fire to poke something with your stick,
lay a stick of dynamite, or fire a bullet.
- toggle fullscreen: F1 ; zoom in/out: F2, F3.
- mute: F4 ; volume up/down: F5, F6.
- cheat modes, "trainer": F7 ; "never die": F8 ; "expose": F9.
More details at http://www.bigorno.net/xrick/.
Report problems, or ask questions, to bigorno@bigorno.net.
Enjoy!
**

View File

@ -1,2 +0,0 @@
# xrick2gs
Apple IIgs port of Dangerous Rick

BIN
data.zip Normal file

Binary file not shown.

25
include/Makefile Normal file
View File

@ -0,0 +1,25 @@
#
# xrick/include/Makefile
#
# Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
#
# The use and distribution terms for this software are contained in the file
# named README, which can be found in the root of this distribution. By
# using this software in any fashion, you are agreeing to be bound by the
# terms of this license.
#
# You must not remove this notice, or any other, from this software.
#
#
# rules
#
#
clean:
rm -f *~
# eof

45
include/config.h Normal file
View File

@ -0,0 +1,45 @@
/*
* xrick/include/config.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _CONFIG_H
#define _CONFIG_H
/* version */
#define VERSION "021212"
/* graphics (choose one) */
#define GFXST
#undef GFXPC
/* joystick support */
#undef ENABLE_JOYSTICK
/* sound support */
#define ENABLE_SOUND
/* cheats support */
#define ENABLE_CHEATS
/* auto-defocus support */
/* does seem to cause all sorts of problems on BeOS, Windows... */
#undef ENABLE_FOCUS
/* development tools */
#undef ENABLE_DEVTOOLS
#undef DEBUG /* see include/debug.h */
#endif
/* eof */

34
include/control.h Normal file
View File

@ -0,0 +1,34 @@
/*
* xrick/include/control.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _CONTROL_H
#define _CONTROL_H
#define CONTROL_UP 0x08
#define CONTROL_DOWN 0x04
#define CONTROL_LEFT 0x02
#define CONTROL_RIGHT 0x01
#define CONTROL_PAUSE 0x80
#define CONTROL_END 0x40
#define CONTROL_EXIT 0x20
#define CONTROL_FIRE 0x10
extern U8 control_status;
extern U8 control_last;
extern U8 control_active;
#endif
/* eof */

35
include/data.h Normal file
View File

@ -0,0 +1,35 @@
/*
* xrick/include/data.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _DATA_H
#define _DATA_H
#include <stdio.h>
#include "system.h"
typedef void *data_file_t;
extern void data_setpath(char *);
extern void data_closepath();
extern data_file_t *data_file_open(char *);
extern int data_file_seek(data_file_t *file, long offset, int origin);
extern int data_file_tell(data_file_t *file);
extern int data_file_size(data_file_t *file);
extern int data_file_read(data_file_t *, void *, size_t, size_t);
extern void data_file_close(data_file_t *);
#endif
/* eof */

93
include/debug.h Normal file
View File

@ -0,0 +1,93 @@
/*
* xrick/include/debug.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _DEBUG_H
#define _DEBUG_H
/* enable/disable subsystem debug */
#undef DEBUG_ENTS
#undef DEBUG_SCROLLER
#undef DEBUG_MAPS
#undef DEBUG_JOYSTICK
#undef DEBUG_EVENTS
#undef DEBUG_AUDIO
#undef DEBUG_AUDIO2
#undef DEBUG_VIDEO
#undef DEBUG_VIDEO2
/* define global debug option */
#ifdef DEBUG
#define DEBUG_VIDEO
#define DEBUG_VIDEO2
#endif
/* define IFDEBUG macros */
#ifdef DEBUG_ENTS
#define IFDEBUG_ENTS(X); X
#else
#define IFDEBUG_ENTS(X);
#endif
#ifdef DEBUG_SCROLLER
#define IFDEBUG_SCROLLER(X); X
#else
#define IFDEBUG_SCROLLER(X);
#endif
#ifdef DEBUG_MAPS
#define IFDEBUG_MAPS(X); X
#else
#define IFDEBUG_MAPS(X);
#endif
#ifdef DEBUG_JOYSTICK
#define IFDEBUG_JOYSTICK(X); X
#else
#define IFDEBUG_JOYSTICK(X);
#endif
#ifdef DEBUG_EVENTS
#define IFDEBUG_EVENTS(X); X
#else
#define IFDEBUG_EVENTS(X);
#endif
#ifdef DEBUG_AUDIO
#define IFDEBUG_AUDIO(X); X
#else
#define IFDEBUG_AUDIO(X);
#endif
#ifdef DEBUG_AUDIO2
#define IFDEBUG_AUDIO2(X); X
#else
#define IFDEBUG_AUDIO2(X);
#endif
#ifdef DEBUG_VIDEO
#define IFDEBUG_VIDEO(X); X
#else
#define IFDEBUG_VIDEO(X);
#endif
#ifdef DEBUG_VIDEO2
#define IFDEBUG_VIDEO2(X); X
#else
#define IFDEBUG_VIDEO2(X);
#endif
#endif
/* eof */

23
include/devtools.h Normal file
View File

@ -0,0 +1,23 @@
/*
* xrick/include/devtools.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _DEVTOOLS_H
#define _DEVTOOLS_H
#include "system.h"
extern U8 devtools_run(void);
#endif
/* eof */

54
include/draw.h Normal file
View File

@ -0,0 +1,54 @@
/*
* xrick/include/draw.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _DRAW_H
#define _DRAW_H
#include "system.h"
#include "rects.h"
#include "img.h"
/* map coordinates of the screen */
#define DRAW_XYMAP_SCRLEFT (-0x0020)
#define DRAW_XYMAP_SCRTOP (0x0040)
/* map coordinates of the top of the hidden bottom of the map */
#define DRAW_XYMAP_HBTOP (0x0100)
extern U8 *draw_tllst;
#ifdef GFXPC
extern U16 draw_filter;
#endif
extern U8 draw_tilesBank;
extern rect_t draw_STATUSRECT;
extern rect_t draw_SCREENRECT;
extern void draw_setfb(U16, U16);
extern U8 draw_clipms(S16 *, S16 *, U16 *, U16 *);
extern void draw_tilesList(void);
extern void draw_tilesListImm(U8 *);
extern U8 draw_tilesSubList(void);
extern void draw_tile(register U8);
extern void draw_sprite(U8, U16, U16);
extern void draw_sprite2(U8, U16, U16, U8);
extern void draw_spriteBackground(U16, U16);
extern void draw_map(void);
extern void draw_drawStatus(void);
extern void draw_clearStatus(void);
extern void draw_pic(U16, U16, U16, U16, U32 *);
extern void draw_infos(void);
extern void draw_img(img_t *);
#endif
/* eof */

34
include/e_bomb.h Normal file
View File

@ -0,0 +1,34 @@
/*
* xrick/include/e_bomb.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _E_BOMB_H
#define _E_BOMB_H
#include "system.h"
#define E_BOMB_NO 3
#define E_BOMB_ENT ent_ents[E_BOMB_NO]
#define E_BOMB_TICKER (0x2D)
extern U8 e_bomb_lethal;
extern U8 e_bomb_ticker;
extern U8 e_bomb_xc;
extern U16 e_bomb_yc;
extern U8 e_bomb_hit(U8);
extern void e_bomb_init(U16, U16);
extern void e_bomb_action(U8);
#endif
/* eof */

23
include/e_bonus.h Normal file
View File

@ -0,0 +1,23 @@
/*
* xrick/include/e_bonus.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _E_BONUS_H
#define _E_BONUS_H
#include "system.h"
extern void e_bonus_action(U8);
#endif
/* eof */

23
include/e_box.h Normal file
View File

@ -0,0 +1,23 @@
/*
* xrick/include/e_box.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _E_BOX_H
#define _E_BOX_H
#include "system.h"
extern void e_box_action(U8);
#endif
/* eof */

30
include/e_bullet.h Normal file
View File

@ -0,0 +1,30 @@
/*
* xrick/include/e_bullet.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _E_BULLET_H
#define _E_BULLET_H
#include "system.h"
#define E_BULLET_NO 2
#define E_BULLET_ENT ent_ents[E_BULLET_NO]
extern S8 e_bullet_offsx;
extern S16 e_bullet_xc, e_bullet_yc;
extern void e_bullet_init(U16, U16);
extern void e_bullet_action(U8);
#endif
/* eof */

47
include/e_rick.h Normal file
View File

@ -0,0 +1,47 @@
/*
* xrick/include/e_rick.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _E_RICK_H
#define _E_RICK_H
#include "system.h"
#define E_RICK_NO 1
#define E_RICK_ENT ent_ents[E_RICK_NO]
extern U8 e_rick_state;
extern S16 e_rick_stop_x, e_rick_stop_y;
#define E_RICK_STSTOP 0x01
#define E_RICK_STSHOOT 0x02
#define E_RICK_STCLIMB 0x04
#define E_RICK_STJUMP 0x08
#define E_RICK_STZOMBIE 0x10
#define E_RICK_STDEAD 0x20
#define E_RICK_STCRAWL 0x40
#define E_RICK_STSET(X) e_rick_state |= (X)
#define E_RICK_STRST(X) e_rick_state &= ~(X)
#define E_RICK_STTST(X) (e_rick_state & (X))
extern void e_rick_save(void);
extern void e_rick_restore(void);
extern void e_rick_action(U8);
extern void e_rick_gozombie(void);
extern U8 e_rick_boxtest(U8);
#endif
/* eof */

28
include/e_sbonus.h Normal file
View File

@ -0,0 +1,28 @@
/*
* xrick/include/e_sbonus.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _E_SBONUS_H
#define _E_SBONUS_H
#include "system.h"
extern U8 e_sbonus_counting;
extern U8 e_sbonus_counter;
extern U16 e_sbonus_bonus;
extern void e_sbonus_start(U8);
extern void e_sbonus_stop(U8);
#endif
/* eof */

29
include/e_them.h Normal file
View File

@ -0,0 +1,29 @@
/*
* xrick/include/e_them.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _E_THEM_H
#define _E_THEM_H
#include "system.h"
extern U32 e_them_rndseed;
extern void e_them_t1a_action(U8);
extern void e_them_t1b_action(U8);
extern void e_them_t2_action(U8);
extern void e_them_t3_action(U8);
extern void e_them_z_action(U8);
#endif
/* eof */

113
include/ents.h Normal file
View File

@ -0,0 +1,113 @@
/*
* xrick/include/ents.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _ENTS_H
#define _ENTS_H
#include "system.h"
#include "rects.h"
#define ENT_XRICK ent_ents[1]
#define ENT_NBR_ENTDATA 0x4a
#define ENT_NBR_SPRSEQ 0x88
#define ENT_NBR_MVSTEP 0x310
#define ENT_ENTSNUM 0x0c
/*
* flags for ent_ents[e].n ("yes" when set)
*
* ENT_LETHAL: is entity lethal?
*/
#define ENT_LETHAL 0x80
/*
* flags for ent_ents[e].flag ("yes" when set)
*
* ENT_FLG_ONCE: should the entity run once only?
* ENT_FLG_STOPRICK: does the entity stops rick (and goes to slot zero)?
* ENT_FLG_LETHALR: is entity lethal when restarting?
* ENT_FLG_LETHALI: is entity initially lethal?
* ENT_FLG_TRIGBOMB: can entity be triggered by a bomb?
* ENT_FLG_TRIGBULLET: can entity be triggered by a bullet?
* ENT_FLG_TRIGSTOP: can entity be triggered by rick stop?
* ENT_FLG_TRIGRICK: can entity be triggered by rick?
*/
#define ENT_FLG_ONCE 0x01
#define ENT_FLG_STOPRICK 0x02
#define ENT_FLG_LETHALR 0x04
#define ENT_FLG_LETHALI 0x08
#define ENT_FLG_TRIGBOMB 0x10
#define ENT_FLG_TRIGBULLET 0x20
#define ENT_FLG_TRIGSTOP 0x40
#define ENT_FLG_TRIGRICK 0x80
typedef struct {
U8 n; /* b00 */
/*U8 b01;*/ /* b01 in ASM code but never used */
S16 x; /* b02 - position */
S16 y; /* w04 - position */
U8 sprite; /* b08 - sprite number */
/*U16 w0C;*/ /* w0C in ASM code but never used */
U8 w; /* b0E - width */
U8 h; /* b10 - height */
U16 mark; /* w12 - number of the mark that created the entity */
U8 flags; /* b14 */
S16 trig_x; /* b16 - position of trigger box */
S16 trig_y; /* w18 - position of trigger box */
S16 xsave; /* b1C */
S16 ysave; /* w1E */
U16 sprbase; /* w20 */
U16 step_no_i; /* w22 */
U16 step_no; /* w24 */
S16 c1; /* b26 */
S16 c2; /* b28 */
U8 ylow; /* b2A */
S16 offsy; /* w2C */
U8 latency; /* b2E */
U8 prev_n; /* new */
S16 prev_x; /* new */
S16 prev_y; /* new */
U8 prev_s; /* new */
U8 front; /* new */
U8 trigsnd; /* new */
} ent_t;
typedef struct {
U8 w, h;
U16 spr, sni;
U8 trig_w, trig_h;
U8 snd;
} entdata_t;
typedef struct {
U8 count;
S8 dx, dy;
} mvstep_t;
extern ent_t ent_ents[ENT_ENTSNUM + 1];
extern entdata_t ent_entdata[ENT_NBR_ENTDATA];
extern rect_t *ent_rects;
extern U8 ent_sprseq[ENT_NBR_SPRSEQ];
extern mvstep_t ent_mvstep[ENT_NBR_MVSTEP];
extern void ent_reset(void);
extern void ent_actvis(U8, U8);
extern void ent_draw(void);
extern void ent_clprev(void);
extern void ent_action(void);
#endif
/* eof */

94
include/game.h Normal file
View File

@ -0,0 +1,94 @@
/*
* xrick/include/game.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _GAME_H
#define _GAME_H
#include <stddef.h> /* NULL */
#include "system.h"
#include "config.h"
#include "rects.h"
#include "data.h"
#define LEFT 1
#define RIGHT 0
#define TRUE 1
#define FALSE 0
#define GAME_PERIOD 75
#define GAME_BOMBS_INIT 6
#define GAME_BULLETS_INIT 6
typedef struct {
U32 score;
U8 name[10];
} hscore_t;
extern U8 game_lives; /* lives counter */
extern U8 game_bombs; /* bombs counter */
extern U8 game_bullets; /* bullets counter */
extern U32 game_score; /* score */
extern hscore_t game_hscores[8]; /* highest scores (hall of fame) */
extern U16 game_map; /* current map */
extern U16 game_submap; /* current submap */
extern U8 game_dir; /* direction (LEFT, RIGHT) */
extern U8 game_chsm; /* change submap request (TRUE, FALSE) */
extern U8 game_waitevt; /* wait for events (TRUE, FALSE) */
extern U8 game_period; /* time between each frame, in millisecond */
extern rect_t *game_rects; /* rectangles to redraw at each frame */
extern void game_run(void);
extern void game_setmusic(char *name, U8 loop);
extern void game_stopmusic(void);
#ifdef ENABLE_CHEATS
extern U8 game_cheat1; /* infinite lives, bombs and bullets */
extern U8 game_cheat2; /* never die */
extern U8 game_cheat3; /* highlight sprites */
extern void game_toggleCheat(U8);
#endif
#ifdef ENABLE_SOUND
extern sound_t *WAV_GAMEOVER;
extern sound_t *WAV_SBONUS2;
extern sound_t *WAV_BULLET;
extern sound_t *WAV_BOMBSHHT;
extern sound_t *WAV_EXPLODE;
extern sound_t *WAV_STICK;
extern sound_t *WAV_WALK;
extern sound_t *WAV_CRAWL;
extern sound_t *WAV_JUMP;
extern sound_t *WAV_PAD;
extern sound_t *WAV_BOX;
extern sound_t *WAV_BONUS;
extern sound_t *WAV_SBONUS1;
extern sound_t *WAV_DIE;
extern sound_t *WAV_ENTITY[];
#endif
#endif
/* eof */

34
include/img.h Normal file
View File

@ -0,0 +1,34 @@
/*
* xrick/include/img.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _IMG_H
#define _IMG_H
#include "system.h"
typedef struct {
U8 r, g, b, nothing;
} img_color_t;
typedef struct {
U16 w, h;
U16 ncolors;
img_color_t *colors;
U8 *pixels;
} img_t;
img_t *IMG_SPLASH;
#endif
/* eof */

150
include/maps.h Normal file
View File

@ -0,0 +1,150 @@
/*
* xrick/include/maps.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _MAPS_H
#define _MAPS_H
#include "system.h"
#define MAP_NBR_MAPS 0x05
#define MAP_NBR_SUBMAPS 0x2F
#define MAP_NBR_CONNECT 0x99
#define MAP_NBR_BNUMS 0x1FD8
#define MAP_NBR_BLOCKS 0x0100
#define MAP_NBR_MARKS 0x020B
#define MAP_NBR_EFLGC 0x0020
/*
* map row definitions, for three zones : hidden top, screen, hidden bottom
* the three zones compose map_map, which contains the definition of the
* current portion of the submap.
*/
#define MAP_ROW_HTTOP 0x00
#define MAP_ROW_HTBOT 0x07
#define MAP_ROW_SCRTOP 0x08
#define MAP_ROW_SCRBOT 0x1F
#define MAP_ROW_HBTOP 0x20
#define MAP_ROW_HBBOT 0x27
extern U8 map_map[0x2c][0x20];
/*
* main maps
*/
typedef struct {
U16 x, y; /* initial position for rick */
U16 row; /* initial map_map top row within the submap */
U16 submap; /* initial submap */
char *tune; /* map tune */
} map_t;
extern map_t map_maps[MAP_NBR_MAPS];
/*
* sub maps
*/
typedef struct {
U16 page; /* tiles page */
U16 bnum; /* first block number */
U16 connect; /* first connection */
U16 mark; /* first entity mark */
} submap_t;
extern submap_t map_submaps[MAP_NBR_SUBMAPS];
/*
* connections
*/
typedef struct {
U8 dir;
U8 rowout;
U8 submap;
U8 rowin;
} connect_t;
extern connect_t map_connect[MAP_NBR_CONNECT];
/*
* blocks - one block is 4 by 4 tiles.
*/
typedef U8 block_t[0x10];
extern block_t map_blocks[MAP_NBR_BLOCKS];
/*
* flags for map_marks[].ent ("yes" when set)
*
* MAP_MARK_NACT: this mark is not active anymore.
*/
#define MAP_MARK_NACT (0x80)
/*
* mark structure
*/
typedef struct {
U8 row;
U8 ent;
U8 flags;
U8 xy; /* bits XXXX XYYY (from b03) with X->x, Y->y */
U8 lt; /* bits XXXX XNNN (from b04) with X->trig_x, NNN->lat & trig_y */
} mark_t;
extern mark_t map_marks[MAP_NBR_MARKS];
/*
* block numbers, i.e. array of rows of 8 blocks
*/
extern U8 map_bnums[MAP_NBR_BNUMS];
/*
* flags for map_eflg[map_map[row][col]] ("yes" when set)
*
* MAP_EFLG_VERT: vertical move only (usually on top of _CLIMB).
* MAP_EFLG_SOLID: solid block, can't go through.
* MAP_EFLG_SPAD: super pad. can't go through, but sends entities to the sky.
* MAP_EFLG_WAYUP: solid block, can't go through except when going up.
* MAP_EFLG_FGND: foreground (hides entities).
* MAP_EFLG_LETHAL: lethal (kill entities).
* MAP_EFLG_CLIMB: entities can climb here.
* MAP_EFLG_01:
*/
#define MAP_EFLG_VERT (0x80)
#define MAP_EFLG_SOLID (0x40)
#define MAP_EFLG_SPAD (0x20)
#define MAP_EFLG_WAYUP (0x10)
#define MAP_EFLG_FGND (0x08)
#define MAP_EFLG_LETHAL (0x04)
#define MAP_EFLG_CLIMB (0x02)
#define MAP_EFLG_01 (0x01)
extern U8 map_eflg_c[MAP_NBR_EFLGC]; /* compressed */
extern U8 map_eflg[0x100]; /* current */
/*
* map_map top row within the submap
*/
extern U8 map_frow;
/*
* tiles offset
*/
extern U8 map_tilesBank;
extern void map_expand(void);
extern void map_init(void);
extern U8 map_chain(void);
extern void map_resetMarks(void);
#endif
/* eof */

25
include/pics.h Normal file
View File

@ -0,0 +1,25 @@
/*
* xrick/include/pics.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _PICS_H
#define _PICS_H
extern U32 pic_haf[];
extern U32 pic_congrats[];
extern U32 pic_splash[];
#endif
/* eof */

30
include/rects.h Normal file
View File

@ -0,0 +1,30 @@
/*
* xrick/include/rects.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _RECTS_H
#define _RECTS_H
#include "system.h"
typedef struct rect_s {
U16 x, y;
U16 width, height;
struct rect_s *next;
} rect_t;
extern void rects_free(rect_t *);
extern rect_t *rects_new(U16, U16, U16, U16, rect_t *);
#endif
/* eof */

50
include/screens.h Normal file
View File

@ -0,0 +1,50 @@
/*
* xrick/include/screens.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _SCREENS_H
#define _SCREENS_H
#include "system.h"
#define SCREEN_TIMEOUT 4000
#define SCREEN_RUNNING 0
#define SCREEN_DONE 1
#define SCREEN_EXIT 2
typedef struct {
U16 count; /* number of loops */
U16 dx, dy; /* sprite x and y deltas */
U16 base; /* base for sprite numbers table */
} screen_imapsteps_t; /* description of one step */
extern U8 screen_imapsl[]; /* sprite lists */
extern screen_imapsteps_t screen_imapsteps[]; /* map intro steps */
extern U8 screen_imapsofs[]; /* first step for each map */
extern U8 *screen_imaptext[]; /* map intro texts */
extern U8 screen_imainhoft[]; /* hall of fame title */
extern U8 screen_imainrdt[]; /*rick dangerous title */
extern U8 screen_imaincdc[]; /* core design copyright text */
extern U8 screen_gameovertxt[]; /* game over */
extern U8 screen_pausedtxt[]; /* paused */
extern U8 screen_congrats[]; /* congratulations */
extern U8 screen_xrick(void); /* splash */
extern U8 screen_introMain(void); /* main intro */
extern U8 screen_introMap(void); /* map intro */
extern U8 screen_gameover(void); /* gameover */
extern U8 screen_getname(void); /* enter you name */
extern void screen_pause(U8); /* pause indicator */
#endif
/* eof */

29
include/scroller.h Normal file
View File

@ -0,0 +1,29 @@
/*
* xrick/include/scroller.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _SCROLLER_H
#define _SCROLLER_H
#define SCROLL_RUNNING 1
#define SCROLL_DONE 0
#define SCROLL_PERIOD 24
extern U8 scroll_up(void);
extern U8 scroll_down(void);
#endif
/* eof */

61
include/sprites.h Normal file
View File

@ -0,0 +1,61 @@
/*
* xrick/include/sprites.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
/*
* NOTES -- PC version
*
* A sprite consists in 4 columns and 0x15 rows of (U16 mask, U16 pict),
* each pair representing 8 pixels (cga encoding, two bits per pixels).
* Sprites are stored in 'sprites.bin' and are loaded by spr_init. Memory
* is freed by spr_shutdown.
*
* There are four sprites planes. Plane 0 is the raw content of 'sprites.bin',
* and planes 1, 2 and 3 contain copies of plane 0 with all sprites shifted
* 2, 4 and 6 pixels to the right.
*/
#ifndef _SPRITES_H_
#define _SPRITES_H_
#include "system.h"
#ifdef GFXPC
#define SPRITES_NBR_SPRITES (0x9b)
typedef struct {
U16 mask;
U16 pict;
} spriteX_t;
typedef spriteX_t sprite_t[4][0x15]; /* one sprite */
extern sprite_t sprites_data[SPRITES_NBR_SPRITES];
#endif
#ifdef GFXST
#define SPRITES_NBR_SPRITES (0xD5)
typedef U32 sprite_t[0x54]; /* 0x15 per 0x04 */
extern sprite_t sprites_data[SPRITES_NBR_SPRITES];
#endif
#endif
/* eof */

45
include/syssnd.h Normal file
View File

@ -0,0 +1,45 @@
/*
* xrick/include/syssnd.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _SYSSND_H
#define _SYSSND_H
#include "config.h"
#ifdef ENABLE_SOUND
#include "system.h"
/* 8-bit mono at 22050Hz */
#define SYSSND_FREQ 22050
#define SYSSND_CHANNELS 1
#define SYSSND_MAXVOL 10
#define SYSSND_MIXCHANNELS 8
/* MIXSAMPLES: 256 is too low on Windows. 512 means ~20 mix per second at 11025Hz */
/* MIXSAMPLES: ?? at 22050Hz */
#define SYSSND_MIXSAMPLES 1024
typedef struct {
sound_t *snd;
U8 *buf;
U32 len;
S8 loop;
} channel_t;
#endif /* ENABLE_SOUND */
#endif /* _SYSSND_H */
/* eof */

167
include/system.h Normal file
View File

@ -0,0 +1,167 @@
/*
* xrick/include/system.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _SYSTEM_H
#define _SYSTEM_H
#include "config.h"
/*
* If compiling w/gcc, then we can use attributes. UNUSED(x) flags a
* parameter or a variable as potentially being unused, so that gcc doesn't
* complain about it.
*
* Note: from OpenAL code: Darwin OS cc is based on gcc and has __GNUC__
* defined, yet does not support attributes. So in theory we should exclude
* Darwin target here.
*/
#ifdef __GNUC__
#define UNUSED(x) x __attribute((unused))
#else
#define UNUSED(x) x
#endif
/*
* Detect Microsoft Visual C
*/
#ifdef _MSC_VER
#define __MSVC__
/*
* FIXME disable "integral size mismatch in argument; conversion supplied" warning
* as long as the code has not been cleared -- there are so many of them...
*/
#pragma warning( disable : 4761 )
#endif
/*
* Detect Microsoft Windows
*/
#ifdef WIN32
#define __WIN32__
#endif
/* there are true at least on x86 platforms */
typedef unsigned char U8; /* 8 bits unsigned */
typedef unsigned short int U16; /* 16 bits unsigned */
typedef unsigned int U32; /* 32 bits unsigned */
typedef signed char S8; /* 8 bits signed */
typedef signed short int S16; /* 16 bits signed */
typedef signed int S32; /* 32 bits signed */
/* this must be after typedefs because it relies on types defined above */
#include "rects.h"
#include "img.h"
/*
* main section
*/
extern void sys_init(int, char **);
extern void sys_shutdown(void);
extern void sys_panic(char *, ...);
extern void sys_printf(char *, ...);
extern U32 sys_gettime(void);
extern void sys_sleep(int);
/*
* video section
*/
#define SYSVID_ZOOM 2
#define SYSVID_MAXZOOM 4
#define SYSVID_WIDTH 320
#define SYSVID_HEIGHT 200
extern void sysvid_init(void);
extern void sysvid_shutdown(void);
extern void sysvid_update(rect_t *);
extern void sysvid_clear(void);
extern void sysvid_zoom(S8);
extern void sysvid_toggleFullscreen(void);
extern void sysvid_setGamePalette(void);
extern void sysvid_setPalette(img_color_t *, U16);
/*
* events section
*/
extern void sysevt_poll(void);
extern void sysevt_wait(void);
/*
* keyboard section
*/
extern U8 syskbd_up;
extern U8 syskbd_down;
extern U8 syskbd_left;
extern U8 syskbd_right;
extern U8 syskbd_pause;
extern U8 syskbd_end;
extern U8 syskbd_xtra;
extern U8 syskbd_fire;
/*
* sound section
*/
#ifdef ENABLE_SOUND
typedef struct {
#ifdef DEBUG
char *name;
#endif
U8 *buf;
U32 len;
U8 dispose;
} sound_t;
extern void syssnd_init(void);
extern void syssnd_shutdown(void);
extern void syssnd_vol(S8);
extern void syssnd_toggleMute(void);
extern S8 syssnd_play(sound_t *, S8);
extern void syssnd_pause(U8, U8);
extern void syssnd_stopchan(S8);
extern void syssnd_stopsound(sound_t *);
extern void syssnd_stopall();
extern int syssnd_isplaying(sound_t *);
extern sound_t *syssnd_load(char *name);
extern void syssnd_free(sound_t *);
#endif
/*
* args section
*/
extern int sysarg_args_period;
extern int sysarg_args_map;
extern int sysarg_args_submap;
extern int sysarg_args_fullscreen;
extern int sysarg_args_zoom;
#ifdef ENABLE_SOUND
extern int sysarg_args_nosound;
extern int sysarg_args_vol;
#endif
extern char *sysarg_args_data;
extern void sysarg_init(int, char **);
/*
* joystick section
*/
#ifdef ENABLE_JOYSTICK
extern void sysjoy_init(void);
extern void sysjoy_shutdown(void);
#endif
#endif
/* eof */

25
include/sysvid.h Normal file
View File

@ -0,0 +1,25 @@
/*
* xrick/include/sysvid.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _VIDEOEX_H
#define _VIDEOEX_H
#include "system.h"
extern U8 *sysvid_fb; /* frame buffer */
#endif
/* eof */

68
include/tiles.h Normal file
View File

@ -0,0 +1,68 @@
/*
* xrick/include/tiles.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
/*
* NOTES
*
* A tile consists in one column and 8 rows of 8 U16 (cga encoding, two
* bits per pixel). The tl_tiles array contains all tiles, with the
* following structure:
*
* 0x0000 - 0x00FF tiles for main intro
* 0x0100 - 0x01FF tiles for map intro
* 0x0200 - 0x0327 unused
* 0x0328 - 0x0427 game tiles, page 0
* 0x0428 - 0x0527 game tiles, page 1
* 0x0527 - 0x05FF unused
*/
#ifndef _TILES_H
#define _TILES_H
#include "system.h"
#ifdef GFXPC
#define TILES_NBR_BANKS 4
#endif
#ifdef GFXST
#define TILES_NBR_BANKS 3
#endif
#define TILES_SIZEOF8 (0x10)
#define TILES_SIZEOF16 (0x08)
/*
* three special tile numbers
*/
#define TILES_BULLET 0x01
#define TILES_BOMB 0x02
#define TILES_RICK 0x03
/*
* one single tile
*/
#ifdef GFXPC
typedef U16 tile_t[TILES_SIZEOF16];
#endif
#ifdef GFXST
typedef U32 tile_t[0x08];
#endif
/*
* tiles banks (each bank is 0x100 tiles)
*/
extern tile_t tiles_data[TILES_NBR_BANKS][0x100];
#endif
/* eof */

277
include/unzip.h Normal file
View File

@ -0,0 +1,277 @@
/* unzip.h -- IO for uncompress .zip files using zlib
Version 0.15 beta, Mar 19th, 1998,
Copyright (C) 1998 Gilles Vollant
This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
WinZip, InfoZip tools and compatible.
Encryption and multi volume ZipFile (span) are not supported.
Old compressions used by old PKZip 1.x are not supported
THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
CAN CHANGE IN FUTURE VERSION !!
I WAIT FEEDBACK at mail info@winimage.com
Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
Condition of use and distribution are the same than zlib :
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* for more info about .ZIP format, see
ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
PkWare has also a specification at :
ftp://ftp.pkware.com/probdesc.zip */
#ifndef _unz_H
#define _unz_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ZLIB_H
#include "zlib.h"
#endif
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
/* like the STRICT of WIN32, we define a pointer that cannot be converted
from (void*) without cast */
typedef struct TagunzFile__ { int unused; } unzFile__;
typedef unzFile__ *unzFile;
#else
typedef voidp unzFile;
#endif
#define UNZ_OK (0)
#define UNZ_END_OF_LIST_OF_FILE (-100)
#define UNZ_ERRNO (Z_ERRNO)
#define UNZ_EOF (0)
#define UNZ_PARAMERROR (-102)
#define UNZ_BADZIPFILE (-103)
#define UNZ_INTERNALERROR (-104)
#define UNZ_CRCERROR (-105)
/* tm_unz contain date/time info */
typedef struct tm_unz_s
{
uInt tm_sec; /* seconds after the minute - [0,59] */
uInt tm_min; /* minutes after the hour - [0,59] */
uInt tm_hour; /* hours since midnight - [0,23] */
uInt tm_mday; /* day of the month - [1,31] */
uInt tm_mon; /* months since January - [0,11] */
uInt tm_year; /* years - [1980..2044] */
} tm_unz;
/* unz_global_info structure contain global data about the ZIPfile
These data comes from the end of central dir */
typedef struct unz_global_info_s
{
uLong number_entry; /* total number of entries in
the central dir on this disk */
uLong size_comment; /* size of the global comment of the zipfile */
} unz_global_info;
/* unz_file_info contain information about a file in the zipfile */
typedef struct unz_file_info_s
{
uLong version; /* version made by 2 bytes */
uLong version_needed; /* version needed to extract 2 bytes */
uLong flag; /* general purpose bit flag 2 bytes */
uLong compression_method; /* compression method 2 bytes */
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
uLong crc; /* crc-32 4 bytes */
uLong compressed_size; /* compressed size 4 bytes */
uLong uncompressed_size; /* uncompressed size 4 bytes */
uLong size_filename; /* filename length 2 bytes */
uLong size_file_extra; /* extra field length 2 bytes */
uLong size_file_comment; /* file comment length 2 bytes */
uLong disk_num_start; /* disk number start 2 bytes */
uLong internal_fa; /* internal file attributes 2 bytes */
uLong external_fa; /* external file attributes 4 bytes */
tm_unz tmu_date;
} unz_file_info;
extern unzFile ZEXPORT unzDup OF ((unzFile file));
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
const char* fileName2,
int iCaseSensitivity));
/*
Compare two filename (fileName1,fileName2).
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
or strcasecmp)
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
(like 1 on Unix, 2 on Windows)
*/
extern unzFile ZEXPORT unzOpen OF((const char *path));
/*
Open a Zip file. path contain the full pathname (by example,
on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
"zlib/zlib111.zip".
If the zipfile cannot be opened (file don't exist or in not valid), the
return value is NULL.
Else, the return value is a unzFile Handle, usable with other function
of this unzip package.
*/
extern int ZEXPORT unzClose OF((unzFile file));
/*
Close a ZipFile opened with unzipOpen.
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
unz_global_info *pglobal_info));
/*
Write info about the ZipFile in the *pglobal_info structure.
No preparation of the structure is needed
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
char *szComment,
uLong uSizeBuf));
/*
Get the global comment string of the ZipFile, in the szComment buffer.
uSizeBuf is the size of the szComment buffer.
return the number of byte copied or an error code <0
*/
/***************************************************************************/
/* Unzip package allow you browse the directory of the zipfile */
extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
/*
Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem
*/
extern int ZEXPORT unzGoToNextFile OF((unzFile file));
/*
Set the current file of the zipfile to the next file.
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
extern int ZEXPORT unzLocateFile OF((unzFile file,
const char *szFileName,
int iCaseSensitivity));
/*
Try locate the file szFileName in the zipfile.
For the iCaseSensitivity signification, see unzStringFileNameCompare
return value :
UNZ_OK if the file is found. It becomes the current file.
UNZ_END_OF_LIST_OF_FILE if the file is not found
*/
extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
unz_file_info *pfile_info,
char *szFileName,
uLong fileNameBufferSize,
void *extraField,
uLong extraFieldBufferSize,
char *szComment,
uLong commentBufferSize));
/*
Get Info about the current file
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
the current file
if szFileName!=NULL, the filemane string will be copied in szFileName
(fileNameBufferSize is the size of the buffer)
if extraField!=NULL, the extra field information will be copied in extraField
(extraFieldBufferSize is the size of the buffer).
This is the Central-header version of the extra field
if szComment!=NULL, the comment string of the file will be copied in szComment
(commentBufferSize is the size of the buffer)
*/
/***************************************************************************/
/* for reading the content of the current zipfile, you can open it, read data
from it, and close it (you can close it before reading all the file)
*/
extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
/*
Open for reading data the current file in the zipfile.
If there is no error, the return value is UNZ_OK.
*/
extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
/*
Close the file in zip opened with unzOpenCurrentFile
Return UNZ_CRCERROR if all the file was read but the CRC is not good
*/
extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
voidp buf,
unsigned len));
/*
Read bytes from the current file (opened by unzOpenCurrentFile)
buf contain buffer where data must be copied
len the size of buf.
return the number of byte copied if somes bytes are copied
return 0 if the end of file was reached
return <0 with error code if there is an error
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
extern z_off_t ZEXPORT unztell OF((unzFile file));
/*
Give the current position in uncompressed data
*/
extern int ZEXPORT unzeof OF((unzFile file));
/*
return 1 if the end of file was reached, 0 elsewhere
*/
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
voidp buf,
unsigned len));
/*
Read extra field from the current file (opened by unzOpenCurrentFile)
This is the local-header version of the extra field (sometimes, there is
more info in the local-header version than in the central-header)
if buf==NULL, it return the size of the local extra field
if buf!=NULL, len is the size of the buffer, the extra header is copied in
buf.
the return value is the number of bytes copied in buf, or (if <0)
the error code
*/
#ifdef __cplusplus
}
#endif
#endif /* _unz_H */

24
include/util.h Normal file
View File

@ -0,0 +1,24 @@
/*
* xrick/include/util.h
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#ifndef _UTIL_H
#define _UTIL_H
extern void u_envtest(S16, S16, U8, U8 *, U8 *);
extern U8 u_boxtest(U8, U8);
extern U8 u_fboxtest(U8, S16, S16);
extern U8 u_trigbox(U8, S16, S16);
#endif
/* eof */

63
src/Makefile Normal file
View File

@ -0,0 +1,63 @@
#
# xrick/src/Makefile
#
# Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
#
# The use and distribution terms for this software are contained in the file
# named README, which can be found in the root of this distribution. By
# using this software in any fashion, you are agreeing to be bound by the
# terms of this license.
#
# You must not remove this notice, or any other, from this software.
#
#
# Includes
#
#
ifeq (.depend, $(wildcard .depend))
include .depend
endif
ifeq (../Makefile.global, $(wildcard ../Makefile.global))
include ../Makefile.global
else
$(error Oops)
endif
#
# Defs
#
#
TARGET = ../xrick
OBJECTS = unzip.o data.o scr_xrick.o scr_pause.o scr_imain.o scr_imap.o scr_gameover.o scr_getname.o dat_picsPC.o dat_picsST.o dat_screens.o dat_tilesPC.o dat_tilesST.o dat_maps.o dat_ents.o dat_spritesST.o dat_spritesPC.o ents.o e_bullet.o e_bomb.o e_rick.o e_sbonus.o e_them.o e_bonus.o e_box.o rects.o util.o game.o xrick.o draw.o maps.o sysvid.o syskbd.o control.o system.o scroller.o sysevt.o sysarg.o syssnd.o sysjoy.o dat_snd.o
#
# Rules
#
#
all: $(TARGET)
$(TARGET): $(OBJECTS) $(XOBJ)
$(CC) $(OBJECTS) $(XOBJ) $(LDFLAGS) -o $(TARGET)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
xrick.res: xrick.rc
windres $< -O coff -o $@
clean:
rm -f *~ *.o core .depend $(TARGET)
rm -f *.exe *.core *.res
rm -f $(LINKS)
depend:
for i in *.c; do $(CPP) $(CFLAGS) -I$(ROOTDIR)/include -MM $$i; done > .depend
# eof

24
src/control.c Normal file
View File

@ -0,0 +1,24 @@
/*
* xrick/src/control.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "config.h"
#include "system.h"
#include "game.h"
U8 control_status = 0;
U8 control_last = 0;
U8 control_active = TRUE;
/* eof */

907
src/dat_ents.c Normal file
View File

@ -0,0 +1,907 @@
/*
* xrick/data/dat_ents.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "system.h"
#include "ents.h"
entdata_t ent_entdata[ENT_NBR_ENTDATA] = {
{0000, 0000, 000000, 000000, 0000, 0000, 0x00},
{0x18, 0x15, 000000, 000000, 0000, 0000, 0x00},
{0000, 0000, 000000, 000000, 0000, 0000, 0x00},
{0x18, 0x15, 000000, 000000, 0000, 0000, 0x00},
{0x18, 0x15, 0x002f, 0x008e, 0000, 0000, 0x00},
{0x18, 0x15, 0x002f, 0x008e, 0000, 0000, 0x00},
{0x18, 0x15, 0x002f, 0x008e, 0000, 0000, 0x00},
{0x18, 0x15, 0x0037, 0x007e, 0000, 0000, 0x00},
{0x18, 0x15, 0x0037, 0x007e, 0000, 0000, 0x00},
{0x18, 0x15, 0x0037, 0x007e, 0000, 0000, 0x00},
{0x18, 0x15, 0x0041, 0x0086, 0000, 0000, 0x00},
{0x18, 0x15, 0x0041, 0x0086, 0000, 0000, 0x00},
{0x18, 0x15, 0x0041, 0x0086, 0000, 0000, 0x00},
{0x18, 0x15, 0x004b, 0x0086, 0000, 0000, 0x00},
{0x18, 0x15, 0x004b, 0x0086, 0000, 0000, 0x00},
{0x18, 0x15, 0x004b, 0x0086, 0000, 0000, 0x00},
{0x18, 0x15, 0x0029, 0x0029, 0000, 0000, 0x00},
{0x18, 0x15, 0x002a, 0x002a, 0000, 0000, 0x00},
{0x18, 0x15, 0x002b, 0x002b, 0000, 0000, 0x00},
{0x18, 0x15, 0x002c, 0x002c, 0000, 0000, 0x00},
{0x18, 0x15, 0x002e, 0x002e, 0000, 0000, 0x00},
{0x18, 0x15, 0x002d, 0x002d, 0000, 0000, 0x00},
{0x18, 0x15, 0x001e, 0x001e, 0x04, 0x04, 0x00},
{0x18, 0x15, 0x001f, 0x001f, 0x04, 0x04, 0x00},
{0x18, 0x10, 0x000c, 000000, 0x03, 0x03, 0x14},
{0x18, 0x06, 0x000e, 0x0005, 0x04, 0x04, 0x14},
{0x18, 0x06, 0x000e, 0x0007, 0x10, 0x04, 0x14},
{0x18, 0x12, 0x0011, 0x0009, 0x04, 0x04, 0x18},
{0x18, 0x10, 0x000c, 0x0007, 0x04, 0x04, 0x14},
{0x18, 0x15, 0x0014, 0x00a4, 0x04, 0x04, 0x15},
{0x18, 0x15, 0x0014, 0x00ca, 0x04, 0x04, 0x15},
{0x18, 0x10, 0x000c, 0x000d, 0x04, 0x04, 0x14},
{0x04, 0x15, 0x0018, 0x0012, 0x04, 0x07, 0x14},
{0x18, 0x10, 0x000c, 0x0014, 0x14, 0x04, 0x19},
{0x10, 0x10, 0x001b, 0x0028, 0x04, 0x04, 0x00},
{0x10, 0x10, 0x001e, 0x002a, 0x04, 0x04, 0x00},
{0x18, 0x10, 0x000c, 0x002d, 0x03, 0x03, 0x14},
{0x20, 0x08, 0x0020, 0x0009, 0x04, 0x04, 0x18},
{0x18, 0x10, 0x000c, 0x0034, 0x04, 0x04, 0x14},
{0x20, 0x0d, 0x0023, 0x0009, 0x04, 0x04, 0x18},
{0x18, 0x15, 0x0026, 0x003a, 0x04, 0x04, 0x18},
{0x18, 0x15, 0x0026, 0x003c, 0x04, 0x04, 0x18},
{0x18, 0x15, 0x002c, 0x003e, 0x04, 0x04, 0x14},
{0x18, 0x10, 0x0030, 0x0048, 0x04, 0x04, 0x14},
{0x20, 0x10, 0x0008, 0x0007, 0x04, 0x04, 0x14},
{0x18, 0x15, 0x000a, 0x004c, 0x14, 0x04, 0x14},
{0x18, 0x15, 0x0036, 0x0009, 0x03, 0x03, 0x17},
{0x18, 0x15, 0x0039, 0x0053, 0x04, 0x04, 0x16},
{0x20, 0x10, 0x0008, 0x0055, 0x04, 0x04, 0x14},
{0x18, 0x15, 0x000a, 0x0061, 0x04, 0x04, 0x14},
{0x12, 0x15, 0x003c, 0x0067, 0x04, 0x04, 0x1A},
{0x12, 0x15, 0x0041, 0x006a, 0x18, 0x04, 0x1A},
{0x18, 0x15, 0x000a, 0x006c, 0x04, 0x04, 0x14},
{0x18, 0x15, 0x0046, 0x0071, 0x04, 0x04, 0x1A},
{0x12, 0x10, 0x004b, 0x0074, 0x04, 0x04, 0x17},
{0x12, 0x10, 0x004f, 0x0074, 0x04, 0x04, 0x17},
{0x18, 0x15, 0x0053, 0x0076, 0x04, 0x04, 0x13},
{0x10, 0x08, 0x0057, 0x0007, 0x10, 0x04, 0x1C},
{0x18, 0x10, 0x005a, 0x007e, 0x04, 0x04, 0x00},
{0x18, 0x10, 0x005c, 0x0009, 0x03, 0x03, 0x9A},
{0x18, 0x11, 0x0068, 0x0088, 0x04, 0x04, 0x14},
{0x12, 0x15, 0x003c, 0x008e, 0x18, 0x04, 0x1A},
{0x18, 0x15, 0x006a, 0x0009, 0x04, 0x04, 0x1A},
{0x20, 0x08, 0x0075, 0x0090, 0x14, 0x04, 0x15},
{0x18, 0x10, 0x006d, 0x0009, 0x03, 0x03, 0x9A},
{0x18, 0x15, 0x0077, 0x0012, 0x04, 0x06, 0x15},
{0x18, 0x15, 0x0046, 0x0092, 0x1f, 0x04, 0x1A},
/*
{0x18, 0x15, 0xfff4, 0x0094, 0x04, 0x04},
{0x18, 0x15, 0xfff4, 0x00bf, 0x04, 0x04},
*/
{0x18, 0x15, 0x0080, 0x0094, 0x04, 0x04, 0x1B},
{0x18, 0x15, 0x0080, 0x00bf, 0x04, 0x04, 0X00},
{0x18, 0x11, 0x0068, 0x00e5, 0x04, 0x04, 0x14},
{0x18, 0x10, 0x005a, 0x00ea, 0x04, 0x04, 0x00},
{0x12, 0x15, 0x003c, 0x00f4, 0x18, 0x04, 0x1A},
{0x20, 0x10, 0x0008, 0x0005, 0x04, 0x04, 0x14},
{0x18, 0x10, 0x000c, 0x0005, 0x04, 0x04, 0x14},
};
U8 ent_sprseq[ENT_NBR_SPRSEQ] = {
0000, 0x01, 0000, 0x02, 0x05, 0x03, 0x04, 0x03,
0x65, 0xff, 0x66, 0xff, 0x55, 0xff, 0000, 0x56,
0xff, 0000, 0x57, 0xff, 0000, 0x58, 0x59, 0xff,
0000, 0x5a, 0xff, 0x5b, 0000, 0xff, 0x5c, 0xff,
0x5d, 0000, 0xff, 0000, 0x79, 0xff, 0000, 0x5e,
0x5f, 0x60, 0x5f, 0xff, 0000, 0x61, 0x69, 0xff,
0x64, 0x62, 0x62, 0x63, 0x63, 0xff, 0x67, 0x68,
0xff, 0000, 0000, 0xff, 0x6a, 0x6a, 0x6b, 0x6b,
0xff, 0x6b, 0x6b, 0x6a, 0x6a, 0xff, 0x6d, 0x6e,
0x6f, 0x70, 0xff, 0x71, 0000, 0000, 0xff, 0x72,
0000, 0000, 0xff, 0x73, 0x47, 0x48, 0xff, 0000,
0x74, 0xff, 0x75, 0xff, 0000, 0x7c, 0x7c, 0x7a,
0x7a, 0x7b, 0x7b, 0x7a, 0x7a, 0x7c, 0x7c, 0xff,
0x78, 0xff, 0x6d, 0x6e, 0xff, 0000, 0x7a, 0x7a,
0x7b, 0x7b, 0x7c, 0x7c, 0xff, 0x6c, 0xff, 0x2d,
0xff, 0x10, 0000, 0000, 0x0c, 0000, 0x04, 0xfa,
/* xtra */
0xff, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xff, 0x00,
};
mvstep_t ent_mvstep[ENT_NBR_MVSTEP] = {
{ 0x10, 0, 0 } ,
{ 0x0c, 0, 4 } ,
{ 0xfa, 0, 0 } ,
{ 0x30, 0, -1 } ,
{ 0xff, 0, 0 } ,
{ 0x46, 8, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x46, -8, 0 } ,
{ 0xff, 0, 0 } ,
{ 0xf8, 0, 0 } ,
{ 0xf8, 0, 0 } ,
{ 0xf8, 0, 0 } ,
{ 0xff, 0, 0 } ,
{ 0xfa, 0, 0 } ,
{ 0x08, 0, 4 } ,
{ 0x22, 0, 0 } ,
{ 0x08, 0, -4 } ,
{ 0xff, 0, 0 } ,
{ 0x46, 0, -8 } ,
{ 0xff, 0, 0 } ,
{ 0x09, 0, 0 } ,
{ 0x08, 0, 1 } ,
{ 0x05, 0, 0 } ,
{ 0x08, 0, 1 } ,
{ 0x05, 0, 0 } ,
{ 0x08, 0, 1 } ,
{ 0x05, 0, 0 } ,
{ 0x08, 0, 1 } ,
{ 0x05, 0, 0 } ,
{ 0x08, 0, 1 } ,
{ 0x05, 0, 0 } ,
{ 0x08, 0, 1 } ,
{ 0xfa, 0, 0 } ,
{ 0xfa, 0, 0 } ,
{ 0xfa, 0, 0 } ,
{ 0xfa, 0, 0 } ,
{ 0xfa, 0, 0 } ,
{ 0xfa, 0, 0 } ,
{ 0x06, 0, -8 } ,
{ 0xff, 0, 0 } ,
{ 0x01, 0, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x23, 0, 0 } ,
{ 0x46, 0, 8 } ,
{ 0xff, 0, 0 } ,
{ 0x10, 0, 0 } ,
{ 0x0c, 0, 4 } ,
{ 0xfa, 0, 0 } ,
{ 0x04, 0, 8 } ,
{ 0x19, 0, 0 } ,
{ 0x0a, 0, -8 } ,
{ 0xff, 0, 0 } ,
{ 0x22, 2, 0 } ,
{ 0x96, 0, 0 } ,
{ 0x22, 2, 0 } ,
{ 0x19, 0, 0 } ,
{ 0x11, -8, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x80, 2, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x80, 1, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x60, 2, 0 } ,
{ 0x08, 0, 4 } ,
{ 0x0c, 0, 8 } ,
{ 0x2c, -2, 0 } ,
{ 0x08, 0, 4 } ,
{ 0x20, -2, 0 } ,
{ 0x08, 0, 4 } ,
{ 0x0c, 0, 8 } ,
{ 0x46, -2, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x20, 1, 2 } ,
{ 0x19, 0, 0 } ,
{ 0x20, -1, -2 } ,
{ 0xff, 0, 0 } ,
{ 0x08, 0, 2 } ,
{ 0x04, 0, 4 } ,
{ 0x25, 0, 0 } ,
{ 0x04, 0, -4 } ,
{ 0x08, 0, -2 } ,
{ 0x0c, 0, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x18, 0, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x08, -4, 0 } ,
{ 0x08, 0, 4 } ,
{ 0x10, -8, 0 } ,
{ 0x19, 0, 0 } ,
{ 0x08, 8, 0 } ,
{ 0x04, 0, -4 } ,
{ 0x96, 0, 0 } ,
{ 0x08, 8, 0 } ,
{ 0xfa, 0, 0 } ,
{ 0x04, 0, -4 } ,
{ 0x08, 4, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x04, 0, 4 } ,
{ 0x04, 0, 8 } ,
{ 0x32, 0, 0 } ,
{ 0x30, 0, -1 } ,
{ 0x4b, 0, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x04, -4, 0 } ,
{ 0x1c, -2, 2 } ,
{ 0xff, 0, 0 } ,
{ 0x80, 3, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x20, 0, -1 } ,
{ 0x24, 0, 0 } ,
{ 0x04, 0, 4 } ,
{ 0x02, 0, 8 } ,
{ 0xff, 0, 0 } ,
{ 0x04, 0, 0 } ,
{ 0xfe, -2, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x08, 0, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x02, 0, -4 } ,
{ 0x02, 0, -2 } ,
{ 0x01, 0, -1 } ,
{ 0x01, 0, 1 } ,
{ 0x02, 0, 2 } ,
{ 0x04, 0, 4 } ,
{ 0xfe, 0, 8 } ,
{ 0xff, 0, 0 } ,
{ 0x0c, 4, 0 } ,
{ 0x04, 2, 0 } ,
{ 0x02, 0, 0 } ,
{ 0x04, -2, 0 } ,
{ 0x30, -4, 0 } ,
{ 0x04, -2, 0 } ,
{ 0x2e, 0, 0 } ,
{ 0x04, 2, 0 } ,
{ 0x23, 4, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x10, 0, 0 } ,
{ 0x20, 1, 0 } ,
{ 0x10, 3, 0 } ,
{ 0x2c, 2, 0 } ,
{ 0x2a, -4, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x80, -3, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x80, -12, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x46, -6, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x06, 0, 0 } ,
{ 0x01, 64, -64 } ,
{ 0x06, 0, 0 } ,
{ 0x01, -80, -32 } ,
{ 0x06, 0, 0 } ,
{ 0x01, -80, 8 } ,
{ 0x06, 0, 0 } ,
{ 0x01, 32, 32 } ,
{ 0x06, 0, 0 } ,
{ 0x01, 0, 88 } ,
{ 0x06, 0, 0 } ,
{ 0x01, 64, -96 } ,
{ 0x06, 0, 0 } ,
{ 0x46, 6, 3 } ,
{ 0x06, 0, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x03, -8, 0 } ,
{ 0x01, -10, -2 } ,
{ 0x01, -6, -2 } ,
{ 0x01, -6, -5 } ,
{ 0x01, -5, -6 } ,
{ 0x01, -2, -6 } ,
{ 0x01, -2, -10 } ,
{ 0x01, 2, -10 } ,
{ 0x01, 2, -6 } ,
{ 0x01, 5, -6 } ,
{ 0x01, 6, -5 } ,
{ 0x01, 6, -2 } ,
{ 0x01, 10, -2 } ,
{ 0x01, 10, 2 } ,
{ 0x01, 6, 2 } ,
{ 0x01, 6, 5 } ,
{ 0x01, 5, 6 } ,
{ 0x01, 2, 6 } ,
{ 0x01, 2, 10 } ,
{ 0x01, -2, 10 } ,
{ 0x01, -2, 6 } ,
{ 0x01, -5, 6 } ,
{ 0x01, -6, 5 } ,
{ 0x01, -6, 2 } ,
{ 0x01, -10, 2 } ,
{ 0x46, -8, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x06, 0, 0 } ,
{ 0x01, 0, -128 } ,
{ 0x06, 0, 0 } ,
{ 0x01, -64, 64 } ,
{ 0x06, 0, 0 } ,
{ 0x01, -128, -32 } ,
{ 0x06, 0, 0 } ,
{ 0x01, -32, -32 } ,
{ 0x06, 0, 0 } ,
{ 0x01, 112, 64 } ,
{ 0x06, 0, 0 } ,
{ 0x03, 8, 0 } ,
{ 0x01, 10, -2 } ,
{ 0x01, 6, -2 } ,
{ 0x01, 6, -5 } ,
{ 0x01, 5, -6 } ,
{ 0x01, 2, -6 } ,
{ 0x01, 2, -10 } ,
{ 0x01, -2, -10 } ,
{ 0x01, -2, -6 } ,
{ 0x01, -5, -6 } ,
{ 0x01, -6, -5 } ,
{ 0x01, -6, -2 } ,
{ 0x01, -10, -2 } ,
{ 0x01, -10, 2 } ,
{ 0x01, -6, 2 } ,
{ 0x01, -6, 5 } ,
{ 0x01, -5, 6 } ,
{ 0x01, -2, 6 } ,
{ 0x01, -2, 10 } ,
{ 0x01, 2, 10 } ,
{ 0x01, 2, 6 } ,
{ 0x01, 5, 6 } ,
{ 0x01, 6, 5 } ,
{ 0x01, 6, 2 } ,
{ 0x01, 10, 2 } ,
{ 0x46, 8, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x40, 2, 0 } ,
{ 0x20, -2, 0 } ,
{ 0x36, 2, 0 } ,
{ 0x56, -2, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x18, 0, 0 } ,
{ 0x04, -2, 0 } ,
{ 0x20, -4, 0 } ,
{ 0x04, -2, 0 } ,
{ 0x28, 0, 0 } ,
{ 0x04, 2, 0 } ,
{ 0x20, 4, 0 } ,
{ 0x04, 2, 0 } ,
{ 0x02, 0, 0 } ,
{ 0xff, 0, 0 } ,
{ 0x02, -1, 0 } ,
{ 0x34, -3, 0 } ,
{ 0x02, -1, 0 } ,
{ 0x02, 0, 0 } ,
{ 0x02, 1, 0 } ,
{ 0x34, 3, 0 } ,
{ 0x02, 1, 0 } ,
{ 0x02, 0, 0 } ,
{ 0x02, -1, 0 } ,
{ 0x34, -3, 0 } ,
{ 0x02, -1, 0 } ,
{ 0x02, 0, 0 } ,
{ 0x02, 1, 0 } ,
{ 0x34, 3, 0 } ,
{ 0x02, 1, 0 } ,
{ 0x02, 0, 0 } ,
{ 0xff, 0, 0 } ,
{ 0000, 0, -128 } ,
{ 0x42, -118, 118 } ,
{ 0x35, 121, 0 } ,
{ 0000, -8, 66 } ,
{ 0x97, 118, 78 } ,
{ 0x79, 0, 0 } ,
{ 0xd0, 67, -92 } ,
{ 0x76, -118, 121 } ,
{ 0000, 0, 24 } ,
{ 0x44, -79, 118 } ,
{ 0xad, 121, 0 } ,
{ 0000, 32, 69 } ,
{ 0xbe, 118, 12 } ,
{ 0x7a, 0, 0 } ,
{ 0xc8, 69, -53 } ,
{ 0x76, 62, 122 } ,
{ 0000, 0, 24 } ,
{ 0x46, -40, 118 } ,
{ 0x52, 122, 0 } ,
{ 0000, 40, 71 } ,
{ 0xe5, 118, -99 } ,
{ 0x7a, 0, 0 } ,
{ 0x38, 72, -14 } ,
{ 0x76, -24, 122 } ,
{ 0000, 0, -128 } ,
{ 0x4a, -1, 118 } ,
{ 0x2e, 123, 0 } ,
{ 0000, -128, 75 } ,
{ 0x0c, 119, -110 } ,
{ 0x7b, 0, 0 } ,
{ 0x48, 76, 25 } ,
{ 0x77, -45, 123 } ,
{ 0000, 0, -64 } ,
{ 0x4c, 38, 119 } ,
{ 0x0a, 124, 0 } ,
{ 0000, 40, 77 } ,
{ 0x33, 119, 60 } ,
{ 0x7c, 0, 0 } ,
{ 0x98, 77, 64 } ,
{ 0x77, 105, 124 } ,
{ 0000, 0, 104 } ,
{ 0x4e, 77, 119 } ,
{ 0xaa, 124, 0 } ,
{ 0000, 104, 79 } ,
{ 0x5a, 119, -6 } ,
{ 0x7c, 0, 0 } ,
{ 0x78, 80, 103 } ,
{ 0x77, 74, 125 } ,
{ 0000, 0, -8 } ,
{ 0x50, 116, 119 } ,
{ 0x6d, 125, 0 } ,
{ 0000, -40, 81 } ,
{ 0x81, 119, -82 } ,
{ 0x7d, 1, 0 } ,
{ 0xe0, 82, -114 } ,
{ 0x77, -17, 125 } ,
{ 0x01, 0, 112 } ,
{ 0x53, -101, 119 } ,
{ 0x17, 126, 1 } ,
{ 0000, -64, 83 } ,
{ 0xb4, 119, 68 } ,
{ 0x7e, 1, 0 } ,
{ 0x10, 84, -51 } ,
{ 0x77, 103, 126 } ,
{ 0x01, 0, -64 } ,
{ 0x54, -38, 119 } ,
{ 0xa8, 126, 1 } ,
{ 0000, 64, 85 } ,
{ 0xe7, 119, -33 } ,
{ 0x7e, 1, 0 } ,
{ 0x90, 85, -6 } ,
{ 0x77, 2, 127 } ,
{ 0x01, 0, 64 } ,
{ 0x56, 13, 120 } ,
{ 0x2f, 127, 1 } ,
{ 0000, -112, 86 } ,
{ 0x26, 120, 77 } ,
{ 0x7f, 1, 0 } ,
{ 0x40, 87, 63 } ,
{ 0x78, -114, 127 } ,
{ 0x01, 0, -112 } ,
{ 0x57, 82, 120 } ,
{ 0xac, 127, 1 } ,
{ 0000, 16, 88 } ,
{ 0x65, 120, -19 } ,
{ 0x7f, 1, 0 } ,
{ 0x60, 88, 114 } ,
{ 0x78, 16, -128 } ,
{ 0x01, 0, 16 } ,
{ 0x59, 127, 120 } ,
{ 0x47, -128, 1 } ,
{ 0000, -64, 89 } ,
{ 0x8c, 120, -125 } ,
{ 0x80, 1, 0 } ,
{ 0xd0, 90, -103 } ,
{ 0x78, -50, -128 } ,
{ 0x01, 0, -128 } ,
{ 0x5b, -90, 120 } ,
{ 0xf6, -128, 1 } ,
{ 0000, 48, 92 } ,
{ 0xb3, 120, 30 } ,
{ 0x81, 1, 0 } ,
{ 0x0a, 93, -64 } ,
{ 0x78, 85, -127 } ,
{ 0x01, 0, 106 } ,
{ 0x5d, -51, 120 } ,
{ 0x82, -127, 1 } ,
{ 0000, 74, 94 } ,
{ 0xda, 120, -41 } ,
{ 0x81, 1, 0 } ,
{ 0x9a, 94, -25 } ,
{ 0x78, -6, -127 } ,
{ 0x01, 0, 122 } ,
{ 0x5f, -12, 120 } ,
{ 0x54, -126, 1 } ,
{ 0000, -54, 95 } ,
{ 0x01, 121, -127 } ,
{ 0x82, 1, 0 } ,
{ 0xaa, 96, 14 } ,
{ 0x79, -52, -126 } ,
{ 0x01, 0, -6 } ,
{ 0x60, 27, 121 } ,
{ 0xea, -126, 1 } ,
{ 0000, -38, 97 } ,
{ 0x28, 121, 63 } ,
{ 0x83, 0, 24 } ,
{ 0xff, 0, 0 } ,
{ 0000, 1, 56 } ,
{ 0x1a, 117, 24 } ,
{ 0000, -1, 0 } ,
{ 0x18, 18, 117 } ,
{ 0x38, 0, 1 } ,
{ 0x68, 34, 117 } ,
{ 0x20, 0, -1 } ,
{ 0000, 32, 26 } ,
{ 0x75, 104, 0 } ,
{ 0x01, 24, 42 } ,
{ 0x75, 24, 0 } ,
{ 0xff, 0, 24 } ,
{ 0x22, 117, 24 } ,
{ 0000, 1, -128 } ,
{ 0x32, 117, 24 } ,
{ 0000, -1, 0 } ,
{ 0x18, 42, 117 } ,
{ 0x80, 0, 1 } ,
{ 0x50, 58, 117 } ,
{ 0x18, 0, -1 } ,
{ 0000, 24, 50 } ,
{ 0x75, 80, 0 } ,
{ 0x01, 32, 66 } ,
{ 0x75, -128, 0 } ,
{ 0xff, 1, 24 } ,
{ 0x4a, 117, -128 } ,
{ 0000, 0, -128 } ,
{ 0x3a, 117, 32 } ,
{ 0000, -1, 1 } ,
{ 0x18, 82, 117 } ,
{ 0x18, 0, 0 } ,
{ 0x80, 66, 117 } ,
{ 0x18, 0, -1 } ,
{ 0000, 24, 74 } ,
{ 0x75, 24, 0 } ,
{ 0x01, -128, -1 } ,
{ 0000, 0, 0 } ,
{ 0xff, 1, 24 } ,
{ 0x62, 117, 96 } ,
{ 0000, 0, 120 } ,
{ 0xff, 0, 0 } ,
{ 0000, -1, 1 } ,
{ 0x18, 106, 117 } ,
{ 0x30, 0, 0 } ,
{ 0x60, 90, 117 } ,
{ 0x18, 0, -1 } ,
{ 0x01, 24, 114 } ,
{ 0x75, 48, 0 } ,
{ 0000, 48, 98 } ,
{ 0x75, 24, 0 } ,
{ 0xff, 1, 48 } ,
{ 0x7a, 117, 24 } ,
{ 0000, 0, 48 } ,
{ 0x6a, 117, 24 } ,
{ 0000, -1, 0 } ,
{ 0x18, 114, 117 } ,
{ 0x30, 0, 1 } ,
{ 0x30, -126, 117 } ,
{ 0x18, 0, -1 } ,
{ 0000, 24, 122 } ,
{ 0x75, 48, 0 } ,
{ 0x01, 96, -118 } ,
{ 0x75, 24, 0 } ,
{ 0xff, 0, 24 } ,
{ 0x82, 117, 96 } ,
{ 0000, 1, 120 } ,
{ 0x92, 117, -128 } ,
{ 0000, -1, 1 } ,
{ 0x18, -102, 117 } ,
{ 0x18, 0, 0 } ,
{ 0x80, -118, 117 } ,
{ 0x78, 0, -1 } ,
{ 0000, 24, -110 } ,
{ 0x75, 24, 0 } ,
{ 0x01, 56, -86 } ,
{ 0x75, 104, 0 } ,
{ 0xff, 0, 24 } ,
{ 0x9a, 117, 56 } ,
{ 0000, 1, 104 } ,
{ 0xaa, 117, 104 } ,
{ 0000, -1, 1 } ,
{ 0x18, -1, 0 } ,
{ 0000, 0, 0 } ,
{ 0x68, -94, 117 } ,
{ 0x68, 0, -1 } ,
{ 0000, 32, -1 } ,
{ 0000, 0, 0 } ,
{ 0x01, 64, -70 } ,
{ 0x75, 24, 0 } ,
{ 0xff, 0, 24 } ,
{ 0xb2, 117, 64 } ,
{ 0000, 1, 24 } ,
{ 0xc2, 117, 24 } ,
{ 0000, 0, 32 } ,
{ 0xc2, 117, 24 } ,
{ 0000, 1, 32 } ,
{ 0xc2, 117, 32 } ,
{ 0000, -1, 1 } ,
{ 0x18, -70, 117 } ,
{ 0x20, 0, 0 } ,
{ 0x18, -70, 117 } ,
{ 0x18, 0, 1 } ,
{ 0x20, -54, 117 } ,
{ 0x20, 0, 0 } ,
{ 0x20, -70, 117 } ,
{ 0x20, 0, -1 } ,
{ 0000, 32, -62 } ,
{ 0x75, 32, 0 } ,
{ 0x01, 80, -46 } ,
{ 0x75, 24, 0 } ,
{ 0xff, 0, 24 } ,
{ 0xca, 117, 80 } ,
{ 0000, 1, 56 } ,
{ 0xda, 117, 24 } ,
{ 0000, -1, 0 } ,
{ 0x18, -46, 117 } ,
{ 0x38, 0, 1 } ,
{ 0x18, -46, 117 } ,
{ 0x20, 0, 1 } ,
{ 0x20, -30, 117 } ,
{ 0x18, 0, -1 } ,
{ 0000, 24, -38 } ,
{ 0x75, 32, 0 } ,
{ 0x01, 72, -22 } ,
{ 0x75, 32, 0 } ,
{ 0x01, 80, -38 } ,
{ 0x75, 32, 0 } ,
{ 0xff, 1, 24 } ,
{ 0xea, 117, 24 } ,
{ 0000, 0, 24 } ,
{ 0xea, 117, 24 } ,
{ 0000, 0, 32 } ,
{ 0xe2, 117, 72 } ,
{ 0000, 1, 32 } ,
{ 0xf2, 117, 48 } ,
{ 0000, -1, 0 } ,
{ 0x18, -30, 117 } ,
{ 0x18, 0, 0 } ,
{ 0x30, -22, 117 } ,
{ 0x20, 0, 1 } ,
{ 0x48, -6, 117 } ,
{ 0x20, 0, 1 } ,
{ 0x50, -38, 117 } ,
{ 0x20, 0, -1 } ,
{ 0x01, 24, -6 } ,
{ 0x75, 24, 0 } ,
{ 0000, 32, -14 } ,
{ 0x75, 72, 0 } ,
{ 0x01, 32, 2 } ,
{ 0x76, 24, 0 } ,
{ 0xff, 0, 24 } ,
{ 0xfa, 117, 32 } ,
{ 0000, 1, 24 } ,
{ 0xca, 117, 24 } ,
{ 0000, 1, 56 } ,
{ 0x0a, 118, 32 } ,
{ 0000, -1, 0 } ,
{ 0x20, 2, 118 } ,
{ 0x38, 0, 1 } ,
{ 0x20, 18, 118 } ,
{ 0x50, 0, -1 } ,
{ 0x01, 24, 26 } ,
{ 0x76, 80, 0 } ,
{ 0000, 80, 10 } ,
{ 0x76, 32, 0 } ,
{ 0xff, 1, 24 } ,
{ 0x22, 118, 24 } ,
{ 0000, 0, 80 } ,
{ 0x12, 118, 24 } ,
{ 0000, -1, 0 } ,
{ 0x18, 26, 118 } ,
{ 0x18, 0, 1 } ,
{ 0x80, 42, 118 } ,
{ 0x50, 0, -1 } ,
{ 0x01, 24, 50 } ,
{ 0x76, 80, 0 } ,
{ 0000, 80, 34 } ,
{ 0x76, -128, 0 } ,
{ 0xff, 1, 24 } ,
{ 0x3a, 118, 24 } ,
{ 0000, 0, 80 } ,
{ 0x2a, 118, 24 } ,
{ 0000, -1, 0 } ,
{ 0x18, 50, 118 } ,
{ 0x18, 0, 1 } ,
{ 0x50, -1, 0 } ,
{ 0000, 0, -1 } ,
{ 0000, 32, -1 } ,
{ 0000, 0, 0 } ,
{ 0x01, 40, 74 } ,
{ 0x76, 104, 0 } ,
{ 0xff, 1, 24 } ,
{ 0x52, 118, 24 } ,
{ 0000, 0, 104 } ,
{ 0x42, 118, 40 } ,
{ 0000, -1, 0 } ,
{ 0x18, 74, 118 } ,
{ 0x18, 0, 1 } ,
{ 0x20, 90, 118 } ,
{ 0x18, 0, -1 } ,
{ 0000, 24, 82 } ,
{ 0x76, 32, 0 } ,
{ 0x01, 104, 98 } ,
{ 0x76, 24, 0 } ,
{ 0xff, 0, 24 } ,
{ 0x5a, 118, 104 } ,
{ 0000, 1, 24 } ,
{ 0x6a, 118, 104 } ,
{ 0000, -1, 1 } ,
{ 0x18, 114, 118 } ,
{ 0x20, 0, 0 } ,
{ 0x68, 98, 118 } ,
{ 0x18, 0, -1 } ,
{ 0x01, 24, 122 } ,
{ 0x76, 24, 0 } ,
{ 0000, 32, 106 } ,
{ 0x76, 24, 0 } ,
{ 0xff, 0, 24 } ,
{ 0x72, 118, 24 } ,
{ 0000, 1, 96 } ,
{ 0x82, 118, 32 } ,
{ 0000, -1, 0 } ,
{ 0x20, 122, 118 } ,
{ 0x60, 0, 1 } ,
{ 0x24, -1, 0 } ,
{ 0000, 0, -1 } ,
{ 0x18, 22, 0 } ,
{ 0x08, 8, 24 } ,
{ 0x2a, -120, 1 } ,
{ 0x28, 56, 4 } ,
{ 0xf0, 21, 41 } ,
{ 0x38, 23, 1 } ,
{ 0xe0, -32, -1 } ,
{ 0000, 0, 0 } ,
{ 0000, 24, 18 } ,
{ 0000, -59, 0 } ,
{ 0x18, 25, -120 } ,
{ 0x95, -61, 32 } ,
{ 0x04, 0, 101 } ,
{ 0x71, 40, 4 } ,
{ 0xf0, -123, -126 } ,
{ 0x30, 4, 0 } ,
{ 0x45, 96, 56 } ,
{ 0x19, -120, 17 } ,
{ 0x63, 72, 18 } ,
{ 0000, 77, 0 } ,
{ 0x60, 27, -120 } ,
{ 0xc2, -62, 104 } ,
{ 0x04, -16, -75 } ,
{ 0x61, 104, 25 } ,
{ 0x88, 17, 34 } ,
{ 0x68, 18, 0 } ,
{ 0x55, 0, -1 } ,
{ 0000, 0, 0 } ,
{ 0000, 24, 5 } ,
{ 0000, 73, 3 } ,
{ 0x18, 5, -16 } ,
{ 0xc1, 1, 24 } ,
{ 0x06, 0, -119 } ,
{ 0000, 32, 22 } ,
{ 0x01, 36, 36 } ,
{ 0x20, 23, 1 } ,
{ 0xc4, -60, 32 } ,
{ 0x12, 0, 117 } ,
{ 0000, -1, 0 } ,
{ 0000, 0, 0 } ,
{ 0x18, 22, 0 } ,
{ 0000, 0, 24 } ,
{ 0x04, 0, -127 } ,
{ 0x40, 24, 17 } ,
{ 0000, -103, 0 } ,
{ 0x38, 47, -127 } ,
{ 0x2d, -115, 56 } ,
{ 0x1b, -120, 37 } ,
{ 0x25, 64, 45 } ,
{ 0x8c, 114, 116 } ,
{ 0x40, 45, -114 } ,
{ 0x8a, 116, 72 } ,
{ 0x2b, -4, 105 } ,
{ 0x69, 80, 4 } ,
{ 0000, -127, 40 } ,
{ 0x50, 25, -120 } ,
{ 0x11, 64, 96 } ,
{ 0x12, 0, 85 } ,
{ 0000, 104, 44 } ,
{ 0x1f, -122, -108 } ,
{ 0x78, 46, 21 } ,
{ 0x7a, 106, 120 } ,
{ 0x2e, 21, -118 } ,
{ 0x7a, -128, 23 } ,
{ 0x01, -32, -32 } ,
{ 0x80, 18, 0 } ,
{ 0x35, 0, -128 } ,
{ 0x04, -16, 53 } ,
{ 0x61, -128, 4 } ,
{ 0000, -123, 48 } ,
{ 0xff, 0, 0 } ,
{ 0000, 0, 24 } ,
{ 0x12, 0, -82 } ,
{ 0000, 48, 25 } ,
{ 0x88, 21, -124 } ,
{ 0x38, 49, -116 } ,
{ 0x80, -92, 64 } ,
{ 0x10, 0, 13 } ,
{ 0000, 64, 4 } ,
{ 0xf0, 85, 96 } ,
{ 0x48, 25, 72 } ,
{ 0x15, -60, 72 } ,
{ 0x04, 0, -123 } ,
{ 0x40, 72, 4 } ,
{ 0000, 117, 56 } ,
{ 0x50, 46, 21 } ,
{ 0xc6, -74, -1 } ,
{ 0000, 0, 0 } ,
{ 0000, 24, 37 } ,
{ 0x84, 99, -124 } ,
{ 0x18, 37, -124 } ,
{ 0xa3, 64, 32 } ,
{ 0x30, -114, -30 } ,
{ 0x44, -1, 0 } ,
{ 0000, 0, 0 } ,
{ 0x20, 16, 0 } ,
{ 0xa1, 0, 40 } ,
{ 0x48, 31, 98 } ,
{ 0x80, 48, 4 } ,
{ 0x80, 69, -128 } ,
{ 0x30, 17, 0 } ,
{ 0x65, 0, 56 } ,
{ 0x1a, -120, -27 } ,
{ 0x84, 64, 5 } ,
{ 0000, 101, 3 } ,
{ 0x50, 25, -120 } ,
{ 0x11, 32, 80 } ,
{ 0x05, -16, 33 } ,
{ 0x07, 88, 5 } ,
{ 0000, -127, 5 } ,
{ 0x68, 4, 0 } ,
{ 0xa5, 64, 112 } ,
{ 0x12, 0, -51 } ,
{ 0000, 112, 25 } ,
{ 0x88, 21, 100 } ,
{ 0x78, 4, -16 } ,
{ 0x45, 96, -128 } ,
{ 0x04, -16, 69 } ,
{ 0x80, -1, 0 } ,
{ 0000, 0, 0 } ,
{ 0x18, 44, 31 } ,
{ 0xe2, -64, 24 } ,
{ 0x19, -120, 21 } ,
{ 0x24, 40, 17 } ,
{ 0000, -59, 0 } ,
{ 0x28, 26, -120 } ,
{ 0xd1, 32, 56 } ,
{ 0x04, 0, 33 } ,
{ 0x70, 64, 4 } ,
{ 0xf0, -127, 96 } ,
{ 0x40, 27, -120 } ,
{ 0x25, 36, 80 } ,
{ 0x12, 0, 33 } ,
{ 0000, 80, 25 } ,
{ 0x88, 17, 96 } ,
{ 0x60, 26, -120 } ,
{ 0xe1, -96, 96 } ,
{ 0x19, -120, 21 } ,
{ 0xc4, 104, 4 } ,
{ 0000, 33, 96 } ,
{ 0x70, 25, -120 } ,
{ 0x15, -124, 120 } ,
{ 0x05, 0, 69 } ,
{ 0000, -1, 0 } ,
{ 0000, 0, 0 } ,
{ 0x18, 39, -120 } ,
{ 0x62, 96, 24 } ,
{ 0x1b, -120, 37 } ,
{ 0x24, 24, 27 } ,
{ 0x88, -123, -124 } ,
{ 0x30, 26, -120 } ,
{ 0xe1, 64, 48 } ,
{ 0x19, -120, 17 } ,
{ 0x40, 56, 4 } ,
{ 0xf0, 85, 96 } ,
{ 0x58, 27, -120 } ,
{ 0x81, -128, 88 } ,
{ 0x04, -16, -123 } ,
{ 0x40, 104, 39 } ,
{ 0x88, 98, 96 } ,
{ 0x68, 18, 0 } ,
{ 0x25, 0, 120 } ,
{ 0x1a, -120, -31 } ,
{ 0000, -128, 44 } ,
{ 0x1f, -124, -128 } ,
{ 0x80, 44, 29 } ,
{ 0xe2, -64, -1 } ,
{ 0000, 0, 0 } ,
{ 0000, 24, 23 } ,
{ 0x01, -32, -32 } ,
};
/* eof */

2360
src/dat_maps.c Normal file

File diff suppressed because it is too large Load Diff

23
src/dat_picsPC.c Normal file
View File

@ -0,0 +1,23 @@
/*
* xrick/data/dat_picsPC.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "config.h"
#ifdef GFXPC
#include "system.h"
#include "pics.h"
#endif /* GFXPC */
/* eof */

10787
src/dat_picsST.c Normal file

File diff suppressed because it is too large Load Diff

252
src/dat_screens.c Normal file
View File

@ -0,0 +1,252 @@
/*
* xrick/src/scr_data.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "system.h"
#include "screens.h"
/*
* map intro, sprites lists
*/
U8 screen_imapsl[] = {
0x1b, 0x00,
0x1c, 0x1d, 0x00,
0x01, 0x00,
0x02, 0x03, 0x04, 0x05, 0x06, 0x00,
0x1e, 0x00,
0x0d, 0x00,
0x13, 0x14, 0x00,
0x1f, 0x00
};
/*
* map intro, steps
*/
screen_imapsteps_t screen_imapsteps[] = {
{ 0x0000, 0x0002, 0x0002, 0x0000 },
{ 0x000b, 0x0000, 0x0001, 0x0000 },
{ 0x0008, 0x0001, 0x0000, 0x0002 },
{ 0x0000, 0x0000, 0x000c, 0x0000 },
{ 0x000a, 0x0000, 0x0000, 0x0005 },
{ 0x0006, 0x0002, 0x0000, 0x0007 },
{ 0x0005, 0x0000, 0x0000, 0x0005 },
{ 0x0000, 0x0006, 0x0000, 0x0000 },
{ 0x000c, 0x0000, 0x0001, 0x0000 },
{ 0x0005, 0x0000, 0x0000, 0x000d },
{ 0x0000, 0x000c, 0x000c, 0x0000 },
{ 0x0005, 0x0000, 0x0000, 0x0005 },
{ 0x000a, 0x0000, 0x0000, 0x000f },
{ 0x000c, 0xffff, 0x0000, 0x0011 },
{ 0x0005, 0x0000, 0x0000, 0x000f },
{ 0x0000, 0x0006, 0x0001, 0x0000 },
{ 0x000a, 0x0000, 0x0000, 0x0014 },
{ 0x0006, 0x0000, 0x0001, 0x0014 },
{ 0x0005, 0x0000, 0x0000, 0x0014 },
{ 0x0003, 0x0001, 0x0000, 0x0014 },
{ 0x0006, 0xffff, 0x0000, 0x0014 },
{ 0x0003, 0x0000, 0xffff, 0x0014 },
{ 0x0000, 0x0000, 0x0000, 0x0000 }
};
/*
* map intro, step offset per map
*/
U8 screen_imapsofs[] = {
0x00, 0x03, 0x07, 0x0a, 0x0f
};
/*
* map intro, text
* (from ds + 0x8810 + 0x2000, 0x2138, 0x2251, 0x236a, 0x2464)
*
* \376=0xfe \377=0xff
*/
U8 screen_imaptext_amazon[] = "\
@@@@@SOUTH@AMERICA@1945@@@@@@@\377\
RICK@DANGEROUS@CRASH@LANDS@HIS\377\
@PLANE@OVER@THE@AMAZON@WHILE@@\377\
@SEARCHING@FOR@THE@LOST@GOOLU@\377\
@@@@@@@@@@@@TRIBE.@@@@@@@@@@@@\377\377\
@BUT,@BY@A@TERRIBLE@TWIST@OF@@\377\
FATE@HE@LANDS@IN@THE@MIDDLE@OF\377\
@@@A@BUNCH@OF@WILD@GOOLUS.@@@@\377\377\
@@CAN@RICK@ESCAPE@THESE@ANGRY@\377\
@@@AMAZONIAN@ANTAGONISTS@?@@@@\376";
U8 screen_imaptext_egypt[] = "\
@@@@EGYPT,@SOMETIMES@LATER@@@@\377\
RICK@HEADS@FOR@THE@PYRAMIDS@AT\377\
@@@@THE@REQUEST@OF@LONDON.@@@@\377\377\
HE@IS@TO@RECOVER@THE@JEWEL@OF@\377\
ANKHEL@THAT@HAS@BEEN@STOLEN@BY\377\
FANATICS@WHO@THREATEN@TO@SMASH\377\
@IT,@IF@A@RANSOM@IS@NOT@PAID.@\377\377\
CAN@RICK@SAVE@THE@GEM,@OR@WILL\377\
HE@JUST@GET@A@BROKEN@ANKHEL@?@\376";
U8 screen_imaptext_castle[] = "\
@@@@EUROPE,@LATER@THAT@WEEK@@@\377\
@@RICK@RECEIVES@A@COMMUNIQUE@@\377\
@@FROM@BRITISH@INTELLIGENCE@@@\377\
@@ASKING@HIM@TO@RESCUE@ALLIED@\377\
@PRISONERS@FROM@THE@NOTORIOUS@\377\
@@@@SCHWARZENDUMPF@CASTLE.@@@@\377\377\
@@RICK@ACCEPTS@THE@MISSION.@@@\377\377\
@@@BUT@CAN@HE@LIBERATE@THE@@@@\377\
@CRUELLY@CAPTURED@COOMANDOS@?@\376";
U8 screen_imaptext_missile[] = "\
@@@@@@EUROPE,@EVEN@LATER@@@@@@\377\
RICK@LEARNS@FROM@THE@PRISONERS\377\
@THAT@THE@ENEMY@ARE@TO@LAUNCH@\377\
AN@ATTACK@ON@LONDON@FROM@THEIR\377\
@@@@@SECRET@MISSILE@BASE.@@@@@\377\377\
WITHOUT@HESITATION,@HE@DECIDES\377\
@@@TO@INFILTRATE@THE@BASE.@@@@\377\377\
CAN@RICK@SAVE@LONDON@IN@TIME@?\376";
U8 screen_imaptext_muchlater[] = "\
@@@LONDON,@MUCH,@MUCH@LATER@@@\377\
@RICK@RETURNS@TO@A@TRIUMPHANT@\377\
@@WELCOME@HOME@HAVING@HELPED@@\377\
@@@@SECURE@ALLIED@VICTORY.@@@@\377\377\
BUT,@MEANWHILE,@IN@SPACE,@THE@\377\
@@@MASSED@STARSHIPS@OF@THE@@@@\377\
@@@BARFIAN@EMPIRE@ARE@POISED@@\377\
@@@@@TO@INVADE@THE@EARTH.@@@@@\377\377\
@WHAT@WILL@RICK@DO@NEXT@...@?@\376";
U8 *screen_imaptext[5] =
{ screen_imaptext_amazon,
screen_imaptext_egypt,
screen_imaptext_castle,
screen_imaptext_missile,
screen_imaptext_muchlater
};
/*
* main intro, hall of fame title
* (from ds + 0x8810 + 0x2642)
*/
U8 screen_imainhoft[] =
{ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0xd4, 0xb7, 0xb1,
0xac, 0xc6, 0x2f, 0xc6, 0x2f, 0x2f, 0xa4, 0xac,
0x9b, 0xc1, 0x2f, 0x9b, 0xc1, 0xb1, 0xac, 0xb6,
0xbd, 0x9b, 0xc1, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
0xff,
0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0xb2, 0xb3, 0xb2,
0xb3, 0xad, 0x2f, 0xad, 0x2f, 0x2f, 0xa6, 0xae,
0xc2, 0xc3, 0x2f, 0xc2, 0xc3, 0xb2, 0xb3, 0xbe,
0xbf, 0xc2, 0xc3, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
0xff,
0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x9f, 0xc0, 0xb4,
0xb5, 0xaf, 0xc4, 0xaf, 0xc4, 0x2f, 0xa7, 0xb0,
0xb4, 0x2f, 0x2f, 0xb4, 0x2f, 0xb4, 0xb5, 0xb4,
0xb5, 0xaf, 0xc4, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
0xfe
};
/*
* main intro, Rick Dangerous title
* (from ds + 0x8810 + 0x27a1)
*/
U8 screen_imainrdt[] =
{ 0x2f, 0x2f, 0x2f, 0x9b, 0x9c, 0xa1, 0xa4, 0xa5,
0xa9, 0xaa, 0x2f, 0x9b, 0xac, 0xb1, 0xac, 0xb6,
0xb7, 0xa4, 0xa5, 0x9b, 0xc1, 0x9b, 0x9c, 0xa4,
0xac, 0xc6, 0xc7, 0xc8, 0xc9, 0x2f, 0x2f, 0x2f,
0xff,
0x2f, 0x2f, 0x2f, 0x9d, 0x9e, 0xa2, 0xa6, 0x2f,
0x9d, 0xab, 0x2f, 0xad, 0xae, 0xb2, 0xb3, 0xb8,
0xb9, 0xa6, 0xbb, 0xc2, 0xc3, 0x9d, 0x9e, 0xa6,
0xae, 0xad, 0xae, 0xca, 0xcb, 0x2f, 0x2f, 0x2f,
0xff,
0x2f, 0x2f, 0x2f, 0x9f, 0xa0, 0xa3, 0xa7, 0xa8,
0x9f, 0xa0, 0x2f, 0xaf, 0xb0, 0xb4, 0xb5, 0x9f,
0xba, 0xa7, 0xbc, 0xaf, 0xc4, 0x9f, 0xa0, 0xa7,
0xb0, 0xc5, 0xb0, 0xcc, 0xb0, 0x2f, 0x2f, 0x2f,
0xfe
};
/*
* congratulations
* (from ds + 0x8810 + 0x257d)
*/
U8 screen_congrats[] =
{ 0xa4, 0xa5, 0xa4, 0xac, 0xb6, 0xb7, 0xa4, 0xa5,
0x9b, 0x9c, 0xb1, 0xac, 0xcd, 0xce, 0xc6, 0xc7,
0xd3, 0x2f, 0xb1, 0xac, 0xcd, 0xce, 0xa1, 0xa4,
0xac, 0xb6, 0xb7, 0xc8, 0xc9, 0x2f, 0xd5, 0xd6,
0xff,
0xa6, 0x2f, 0xa6, 0xae, 0xb8, 0xb9, 0xa6, 0xbb,
0x9d, 0x9e, 0xb2, 0xb3, 0xcf, 0xd0, 0xad, 0xae,
0xad, 0x2f, 0xb2, 0xb3, 0xcf, 0xd0, 0xa2, 0xa6,
0xae, 0xb8, 0xb9, 0xca, 0xcb, 0x2f, 0xd7, 0xd8,
0xff,
0xa7, 0xa8, 0xa7, 0xb0, 0x9f, 0xba, 0xa7, 0xbc,
0x9f, 0xa0, 0xb4, 0xb5, 0xd1, 0xd2, 0xc5, 0xb0,
0xaf, 0xc4, 0xb4, 0xb5, 0xd1, 0xd2, 0xa3, 0xa7,
0xb0, 0x9f, 0xba, 0xcc, 0xb0, 0x2f, 0xd9, 0xda,
0xfe
};
/*
* main intro, Core Design copyright text
* (from ds + 0x8810 + 0x2288)
*
* \376=0xfe \377=0xff
*/
U8 screen_imaincdc[] = "\
@@@@@@@@@@@@@@@@@@@\377\377\
(C)@1989@CORE@DESIGN\377\377\377\
@PRESS@SPACE@TO@START\376";
/*
* gameover
* (from ds + 0x8810 + 0x2864)
*
* \376=0xfe \377=0xff
*/
U8 screen_gameovertxt[] = "\
@@@@@@@@@@@\377\
@GAME@OVER@\377\
@@@@@@@@@@@\376";
/*
* paused
*
* \376=0xfe \377=0xff
*/
U8 screen_pausedtxt[] = "\
@@@@@@@@@@\377\
@@PAUSED@@\377\
@@@@@@@@@@\376";
/* eof */

34
src/dat_snd.c Normal file
View File

@ -0,0 +1,34 @@
/*
* xrick/data/dat_snd.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "config.h"
#ifdef ENABLE_SOUND
#include "system.h"
sound_t *WAV_WAA;
sound_t *WAV_BOMB;
sound_t *WAV_BULLET;
sound_t *WAV_WALK;
sound_t *WAV_JUMP;
sound_t *WAV_TING;
sound_t *WAV_BOMBSHHT;
sound_t *WAV_BONUS;
sound_t *WAV_SHHT;
sound_t *WAV_BOX;
sound_t *WAV_DDDING;
#endif /* ENABLE_SOUND */
/* eof */

14596
src/dat_spritesPC.c Normal file

File diff suppressed because it is too large Load Diff

4976
src/dat_spritesST.c Normal file

File diff suppressed because it is too large Load Diff

1606
src/dat_tilesPC.c Normal file

File diff suppressed because it is too large Load Diff

7716
src/dat_tilesST.c Normal file

File diff suppressed because it is too large Load Diff

238
src/data.c Normal file
View File

@ -0,0 +1,238 @@
/*
* xrick/src/data.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <stdlib.h> /* malloc */
#include <string.h>
#include "system.h"
#include "data.h"
#include "unzip.h"
/*
* Private typedefs
*/
typedef struct {
char *name;
unzFile zip;
} zipped_t;
typedef struct {
char *name;
unzFile zip;
} path_t;
/*
* Static variables
*/
static path_t path;
/*
* Prototypes
*/
static int str_zipext(char *);
static char *str_dup(char *);
static char *str_slash(char *);
/*
*
*/
void
data_setpath(char *name)
{
unzFile zip;
char *n;
if (str_zipext(name)) {
/* path has .zip extension */
n = str_slash(str_dup(name));
zip = unzOpen(n);
if (!zip) {
free(n);
sys_panic("(data) can not open data");
} else {
path.zip = zip;
path.name = n;
}
} else {
/* path has no .zip extension. it should be a directory */
/* FIXME check that it is a valid directory */
path.zip = NULL;
path.name = str_dup(name);
}
}
/*
*
*/
void
data_closepath()
{
if (path.zip) {
unzClose(path.zip);
path.zip = NULL;
}
free(path.name);
path.name = NULL;
}
/*
* Open a data file.
*/
data_file_t *
data_file_open(char *name)
{
char *n;
FILE *fh;
zipped_t *z;
if (path.zip) {
z = malloc(sizeof(zipped_t));
z->name = strdup(name);
z->zip = unzDup(path.zip);
if (unzLocateFile(z->zip, name, 0) != UNZ_OK ||
unzOpenCurrentFile(z->zip) != UNZ_OK) {
unzClose(z->zip);
z = NULL;
}
return (data_file_t *)z;
} else {
n = malloc(strlen(path.name) + strlen(name) + 2);
sprintf(n, "%s/%s", path.name, name);
str_slash(n);
fh = fopen(n, "rb");
return (data_file_t *)fh;
}
}
int
data_file_size(data_file_t *file)
{
int s;
if (path.zip) {
/* not implemented */
} else {
fseek((FILE *)file, 0, SEEK_END);
s = ftell((FILE *)file);
fseek((FILE *)file, 0, SEEK_SET);
}
return s;
}
/*
* Seek.
*/
int
data_file_seek(data_file_t *file, long offset, int origin)
{
if (path.zip) {
/* not implemented */
return -1;
} else {
return fseek((FILE *)file, offset, origin);
}
}
/*
* Tell.
*/
int
data_file_tell(data_file_t *file)
{
if (path.zip) {
/* not implemented */
return -1;
} else {
return ftell((FILE *)file);
}
}
/*
* Read a file within a data archive.
*/
int
data_file_read(data_file_t *file, void *buf, size_t size, size_t count)
{
if (path.zip) {
return unzReadCurrentFile(((zipped_t *)file)->zip, buf, size * count) / size;
} else {
return fread(buf, size, count, (FILE *)file);
}
}
/*
* Close a file within a data archive.
*/
void
data_file_close(data_file_t *file)
{
if (path.zip) {
unzClose(((zipped_t *)file)->zip);
((zipped_t *)file)->zip = NULL;
free(((zipped_t *)file)->name);
((zipped_t *)file)->name = NULL;
} else {
fclose((FILE *)file);
}
}
/*
* Returns 1 if filename has .zip extension.
*/
static int
str_zipext(char *name)
{
int i;
i = strlen(name) - 1;
if (i < 0 || name[i] != 'p' && name[i] != 'P') return 0;
i--;
if (i < 0 || name[i] != 'i' && name[i] != 'I') return 0;
i--;
if (i < 0 || name[i] != 'z' && name[i] != 'Z') return 0;
i--;
if (i < 0 || name[i] != '.') return 0;
i--;
if (i < 0) return 0;
return 1;
}
/*
*
*/
static char *
str_dup(char *s)
{
char *s1;
int i;
i = strlen(s) + 1;
s1 = malloc(i);
strncpy(s1, s, i);
return s1;
}
static char *
str_slash(char *s)
{
#ifdef __WIN32__
int i, l;
l = strlen(s);
for (i = 0; i < l; i++)
if (s[i] == '/') s[i] = '\\';
#endif
return s;
}
/* eof */

246
src/devtools.c Normal file
View File

@ -0,0 +1,246 @@
/*
* xrick/src/scr_devtools.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "config.h"
#ifdef ENABLE_DEVTOOLS
#include "system.h"
#include "game.h"
#include "control.h"
#include "screens.h"
#include "draw.h"
#include "sprites.h"
#include "maps.h"
/*
* DevTools
*/
U8
devtools_run(void)
{
static U8 seq = 0;
static U8 pos = 0;
static U8 pos2 = 0;
U8 i, j, k, l;
U8 s[128];
if (seq == 0) {
sysvid_clear();
game_rects = &draw_SCREENRECT;
#ifdef GFXPC
draw_filter = 0xffff;
#endif
seq = 1;
}
switch (seq) {
case 1: /* draw tiles */
sysvid_clear();
draw_tilesBank = 0;
sprintf(s, "TILES@BANK@%d\376", pos);
draw_setfb(4, 4);
draw_tilesListImm(s);
k = 0;
for (i = 0; i < 0x10; i++) {
draw_setfb(80 + i * 0x0a, 14);
draw_tile((i<10?0x30:'A'-10) + i);
draw_setfb(64, 30 + i * 0x0a);
draw_tile((i<10?0x30:'A'-10) + i);
}
draw_tilesBank = pos;
for (i = 0; i < 0x10; i++)
for (j = 0; j < 0x10; j++) {
draw_setfb(80 + j * 0x0a, 30 + i * 0x0a);
draw_tile(k++);
}
seq = 10;
break;
case 10: /* wait for key pressed */
if (control_status & CONTROL_FIRE)
seq = 98;
if (control_status & CONTROL_UP)
seq = 12;
if (control_status & CONTROL_DOWN)
seq = 13;
if (control_status & CONTROL_RIGHT)
seq = 11;
break;
case 11: /* wait for key released */
if (!(control_status & CONTROL_RIGHT)) {
pos = 0;
seq = 21;
}
break;
case 12: /* wait for key released */
if (!(control_status & CONTROL_UP)) {
if (pos < 4) pos++;
seq = 1;
}
break;
case 13: /* wait for key released */
if (!(control_status & CONTROL_DOWN)) {
if (pos > 0) pos--;
seq = 1;
}
break;
case 21: /* draw sprites */
sysvid_clear();
draw_tilesBank = 0;
sprintf(s, "SPRITES\376");
draw_setfb(4, 4);
draw_tilesListImm(s);
for (i = 0; i < 8; i++) {
draw_setfb(0x08 + 0x20 + i * 0x20, 0x30 - 26);
draw_tile((i<10?0x30:'A'-10) + i);
draw_setfb(0x08 + 0x20 + i * 0x20, 0x30 - 16);
draw_tile((i+8<10?0x30:'A'-10) + i+8);
}
for (i = 0; i < 4; i++) {
k = pos + i * 8;
draw_setfb(0x20 - 16, 0x08 + 0x30 + i * 0x20);
j = k%16;
k /= 16;
draw_tile((j<10?0x30:'A'-10) + j);
draw_setfb(0x20 - 26, 0x08 + 0x30 + i * 0x20);
j = k%16;
draw_tile((j<10?0x30:'A'-10) + j);
}
k = pos;
for (i = 0; i < 4; i++)
for (j = 0; j < 8; j++) {
draw_sprite(k++, 0x20 + j * 0x20, 0x30 + i * 0x20);
}
seq = 30;
break;
case 30: /* wait for key pressed */
if (control_status & CONTROL_FIRE)
seq = 98;
if (control_status & CONTROL_UP)
seq = 32;
if (control_status & CONTROL_DOWN)
seq = 33;
if (control_status & CONTROL_LEFT)
seq = 31;
if (control_status & CONTROL_RIGHT)
seq = 40;
break;
case 31: /* wait for key released */
if (!(control_status & CONTROL_LEFT)) {
pos = 0;
seq = 1;
}
break;
case 32: /* wait for key released */
if (!(control_status & CONTROL_UP)) {
if (pos < SPRITES_NBR_SPRITES - 32) pos += 32;
seq = 21;
}
break;
case 33: /* wait for key released */
if (!(control_status & CONTROL_DOWN)) {
if (pos > 0) pos -= 32;
seq = 21;
}
break;
case 40:
sysvid_clear();
#ifdef GFXPC
if (pos2 == 0) pos2 = 2;
#endif
#ifdef GFXST
if (pos2 == 0) pos2 = 1;
#endif
sprintf(s, "BLOCKS@%#04X@TO@%#04X@WITH@BANK@%d\376",
pos, pos + 4*8-1, pos2);
draw_setfb(4, 4);
draw_tilesBank = 0;
draw_tilesListImm(s);
draw_tilesBank = pos2;
for (l = 0; l < 8; l++)
for (k = 0; k < 4; k++)
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++) {
draw_setfb(20 + j * 8 + l * 36, 30 + i * 8 + k * 36);
draw_tile(map_blocks[pos + l + k * 8][i * 4 + j]);
}
seq = 41;
break;
case 41:
if (control_status & CONTROL_FIRE)
seq = 98;
if (control_status & CONTROL_UP)
seq = 42;
if (control_status & CONTROL_DOWN)
seq = 43;
if (control_status & CONTROL_LEFT)
seq = 44;
if (control_status & CONTROL_PAUSE)
seq = 45;
break;
case 42:
if (!(control_status & CONTROL_UP)) {
if (pos < MAP_NBR_BLOCKS - 8*4) pos += 8 * 4;
seq = 40;
}
break;
case 43:
if (!(control_status & CONTROL_DOWN)) {
if (pos > 0) pos -= 8 * 4;
seq = 40;
}
break;
case 44:
if (!(control_status & CONTROL_LEFT)) {
pos = 0;
pos2 = 0;
seq = 21;
}
break;
case 45:
if (!(control_status & CONTROL_PAUSE)) {
#ifdef GFXPC
if (pos2 == 2) pos2 = 3;
else pos2 = 2;
#endif
#ifdef GFXST
if (pos2 == 1) pos2 = 2;
else pos2 = 1;
#endif
seq = 40;
}
break;
case 98: /* wait for key released */
if (!(control_status & CONTROL_FIRE))
seq = 99;
break;
}
if (control_status & CONTROL_EXIT) /* check for exit request */
return SCREEN_EXIT;
if (seq == 99) { /* we're done */
sysvid_clear();
seq = 0;
return SCREEN_DONE;
}
return SCREEN_RUNNING;
}
#endif /* ENABLE_DEVTOOLS */
/* eof */

683
src/draw.c Normal file
View File

@ -0,0 +1,683 @@
/*
* xrick/src/draw.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
/*
* NOTES
*
* This is the only file which accesses the video. Anything calling d_*
* function should be video-independant.
*
* draw.c draws into a 320x200 or 0x0140x0xc8 8-bits depth frame buffer,
* using the CGA 2 bits color codes. It is up to the video to figure out
* how to display the frame buffer. Whatever draw.c does, does not show
* until the screen is explicitely refreshed.
*
* The "screen" is the whole 0x0140 by 0x00c8 screen, coordinates go from
* 0x0000,0x0000 to 0x013f,0x00c7.
*
* The "map" is a 0x0100 by 0x0140 rectangle that represents the active
* game area.
*
* Relative to the screen, the "map" is located at 0x0020,-0x0040 : the
* "map" is composed of two hidden 0x0100 by 0x0040 rectangles (one at the
* top and one at the bottom) and one visible 0x0100 by 0x00c0 rectangle (in
* the middle).
*
* The "map screen" is the visible rectangle ; it is a 0x0100 by 0xc0
* rectangle located at 0x0020,0x00.
*
* Coordinates can be relative to the screen, the map, or the map screen.
*
* Coordinates can be expressed in pixels. When relative to the map or the
* map screen, they can also be expressed in tiles, the map being composed
* of rows of 0x20 tiles of 0x08 by 0x08 pixels.
*/
#include "system.h"
#include "game.h"
#include "draw.h"
#include "sysvid.h"
#include "sprites.h"
#include "tiles.h"
#include "maps.h"
#include "rects.h"
#include "img.h"
/*
* counters positions (pixels, screen)
*/
#ifdef GFXPC
#define DRAW_STATUS_SCORE_X 0x28
#define DRAW_STATUS_LIVES_X 0xE8
#define DRAW_STATUS_Y 0x08
#endif
#define DRAW_STATUS_BULLETS_X 0x68
#define DRAW_STATUS_BOMBS_X 0xA8
#ifdef GFXST
#define DRAW_STATUS_SCORE_X 0x20
#define DRAW_STATUS_LIVES_X 0xF0
#define DRAW_STATUS_Y 0
#endif
/*
* public vars
*/
U8 *draw_tllst; /* pointer to tiles list */
#ifdef GFXPC
U16 draw_filter; /* CGA colors filter */
#endif
U8 draw_tilesBank; /* tile number offset */
rect_t draw_STATUSRECT = {
DRAW_STATUS_SCORE_X, DRAW_STATUS_Y,
DRAW_STATUS_LIVES_X + 6 * 8 - DRAW_STATUS_SCORE_X, 8,
NULL
};
rect_t draw_SCREENRECT = { 0, 0, SYSVID_WIDTH, SYSVID_HEIGHT, NULL };
/*
* private vars
*/
static U8 *fb; /* frame buffer pointer */
/*
* Set the frame buffer pointer
*
* x, y: position (pixels, screen)
*/
void
draw_setfb(U16 x, U16 y)
{
fb = sysvid_fb + x + y * SYSVID_WIDTH;
}
/*
* Clip to map screen
*
* x, y: position (pixels, map) CHANGED clipped
* width, height: dimension CHANGED clipped
* return: TRUE if fully clipped, FALSE if still (at least partly) visible
*/
U8
draw_clipms(S16 *x, S16 *y, U16 *width, U16 *height)
{
if (*x < 0) {
if (*x + *width < 0)
return TRUE;
else {
*width += *x;
*x = 0;
}
}
else {
if (*x > 0x0100)
return TRUE;
else if (*x + *width > 0x0100) {
*width = 0x0100 - *x;
}
}
if (*y < DRAW_XYMAP_SCRTOP) {
if ((*y + *height) < DRAW_XYMAP_SCRTOP)
return TRUE;
else {
*height += *y - DRAW_XYMAP_SCRTOP;
*y = DRAW_XYMAP_SCRTOP;
}
}
else {
if (*y >= DRAW_XYMAP_HBTOP)
return TRUE;
else if (*y + *height > DRAW_XYMAP_HBTOP)
*height = DRAW_XYMAP_HBTOP - *y;
}
return FALSE;
}
/*
* Draw a list of tiles onto the frame buffer
* start at position indicated by fb ; at the end of each (sub)list,
* perform a "carriage return + line feed" i.e. go back to the initial
* position then go down one tile row (8 pixels)
*
* ASM 1e33
* fb: CHANGED (see above)
* draw_tllst: CHANGED points to the element following 0xfe/0xff end code
*/
void
draw_tilesList(void)
{
U8 *t;
t = fb;
while (draw_tilesSubList() != 0xFE) { /* draw sub-list */
t += 8 * SYSVID_WIDTH; /* go down one tile i.e. 8 lines */
fb = t;
}
}
/*
* Draw a list of tiles onto the frame buffer -- same as draw_tilesList,
* but accept an immediate string as parameter. Note that the string needs
* to be properly terminated with 0xfe (\376) and 0xff (\377) chars.
*/
void
draw_tilesListImm(U8 *list)
{
draw_tllst = list;
draw_tilesList();
}
/*
* Draw a sub-list of tiles onto the frame buffer
* start at position indicated by fb ; leave fb pointing to the next
* tile to the right of the last tile drawn
*
* ASM 1e41
* fpb: CHANGED (see above)
* draw_tllst: CHANGED points to the element following 0xfe/0xff end code
* returns: end code (0xfe : end of list ; 0xff : end of sub-list)
*/
U8
draw_tilesSubList()
{
U8 i;
i = *(draw_tllst++);
while (i != 0xFF && i != 0xFE) { /* while not end */
draw_tile(i); /* draw tile */
i = *(draw_tllst++);
}
return i;
}
/*
* Draw a tile
* at position indicated by fb ; leave fb pointing to the next tile
* to the right of the tile drawn
*
* ASM 1e6c
* tlnbr: tile number
* draw_filter: CGA colors filter
* fb: CHANGED (see above)
*/
void
draw_tile(U8 tileNumber)
{
U8 i, k, *f;
#ifdef GFXPC
U16 x;
#endif
#ifdef GFXST
U32 x;
#endif
f = fb; /* frame buffer */
for (i = 0; i < 8; i++) { /* for all 8 pixel lines */
#ifdef GFXPC
x = tiles_data[draw_tilesBank][tileNumber][i] & draw_filter;
/*
* tiles / perform the transformation from CGA 2 bits
* per pixel to frame buffer 8 bits per pixels
*/
for (k = 8; k--; x >>= 2)
f[k] = x & 3;
f += SYSVID_WIDTH; /* next line */
#endif
#ifdef GFXST
x = tiles_data[draw_tilesBank][tileNumber][i];
/*
* tiles / perform the transformation from ST 4 bits
* per pixel to frame buffer 8 bits per pixels
*/
for (k = 8; k--; x >>= 4)
f[k] = x & 0x0F;
f += SYSVID_WIDTH; /* next line */
#endif
}
fb += 8; /* next tile */
}
/*
* Draw a sprite
*
* ASM 1a09
* nbr: sprite number
* x, y: sprite position (pixels, screen)
* fb: CHANGED
*/
#ifdef GFXPC
void
draw_sprite(U8 nbr, U16 x, U16 y)
{
U8 i, j, k, *f;
U16 xm = 0, xp = 0;
draw_setfb(x, y);
for (i = 0; i < 4; i++) { /* for each tile column */
f = fb; /* frame buffer */
for (j = 0; j < 0x15; j++) { /* for each pixel row */
xm = sprites_data[nbr][i][j].mask; /* mask */
xp = sprites_data[nbr][i][j].pict; /* picture */
/*
* sprites / perform the transformation from CGA 2 bits
* per pixel to frame buffer 8 bits per pixels
*/
for (k = 8; k--; xm >>= 2, xp >>= 2)
f[k] = (f[k] & (xm & 3)) | (xp & 3);
f += SYSVID_WIDTH;
}
fb += 8;
}
}
#endif
/*
* Draw a sprite
*
* foobar
*/
#ifdef GFXST
void
draw_sprite(U8 number, U16 x, U16 y)
{
U8 i, j, k, *f;
U16 g;
U32 d;
draw_setfb(x, y);
g = 0;
for (i = 0; i < 0x15; i++) { /* rows */
f = fb;
for (j = 0; j < 4; j++) { /* cols */
d = sprites_data[number][g++];
for (k = 8; k--; d >>= 4)
if (d & 0x0F) f[k] = (f[k] & 0xF0) | (d & 0x0F);
f += 8;
}
fb += SYSVID_WIDTH;
}
}
#endif
/*
* Draw a sprite
*
* NOTE re-using original ST graphics format
*/
#ifdef GFXST
void
draw_sprite2(U8 number, U16 x, U16 y, U8 front)
{
U32 d = 0; /* sprite data */
S16 x0, y0; /* clipped x, y */
U16 w, h; /* width, height */
S16 g, /* sprite data offset*/
r, c, /* row, column */
i, /* frame buffer shifter */
im; /* tile flag shifter */
U8 flg; /* tile flag */
x0 = x;
y0 = y;
w = 0x20;
h = 0x15;
if (draw_clipms(&x0, &y0, &w, &h)) /* return if not visible */
return;
g = 0;
draw_setfb(x0 - DRAW_XYMAP_SCRLEFT, y0 - DRAW_XYMAP_SCRTOP + 8);
for (r = 0; r < 0x15; r++) {
if (r >= h || y + r < y0) continue;
i = 0x1f;
im = x - (x & 0xfff8);
flg = map_eflg[map_map[(y + r) >> 3][(x + 0x1f)>> 3]];
#ifdef ENABLE_CHEATS
#define LOOP(N, C0, C1) \
d = sprites_data[number][g + N]; \
for (c = C0; c >= C1; c--, i--, d >>= 4, im--) { \
if (im == 0) { \
flg = map_eflg[map_map[(y + r) >> 3][(x + c) >> 3]]; \
im = 8; \
} \
if (c >= w || x + c < x0) continue; \
if (!front && !game_cheat3 && (flg & MAP_EFLG_FGND)) continue; \
if (d & 0x0F) fb[i] = (fb[i] & 0xF0) | (d & 0x0F); \
if (game_cheat3) fb[i] |= 0x10; \
}
#else
#define LOOP(N, C0, C1) \
d = sprites_data[number][g + N]; \
for (c = C0; c >= C1; c--, i--, d >>= 4, im--) { \
if (im == 0) { \
flg = map_eflg[map_map[(y + r) >> 3][(x + c) >> 3]]; \
im = 8; \
} \
if (!front && (flg & MAP_EFLG_FGND)) continue; \
if (c >= w || x + c < x0) continue; \
if (d & 0x0F) fb[i] = (fb[i] & 0xF0) | (d & 0x0F); \
}
#endif
LOOP(3, 0x1f, 0x18);
LOOP(2, 0x17, 0x10);
LOOP(1, 0x0f, 0x08);
LOOP(0, 0x07, 0x00);
#undef LOOP
fb += SYSVID_WIDTH;
g += 4;
}
}
#endif
/*
* Draw a sprite
* align to tile column, determine plane automatically, and clip
*
* nbr: sprite number
* x, y: sprite position (pixels, map).
* fb: CHANGED
*/
#ifdef GFXPC
void
draw_sprite2(U8 number, U16 x, U16 y, U8 front)
{
U8 k, *f, c, r, dx;
U16 cmax, rmax;
U16 xm = 0, xp = 0;
S16 xmap, ymap;
/* align to tile column, prepare map coordinate and clip */
xmap = x & 0xFFF8;
ymap = y;
cmax = 0x20; /* width, 4 tile columns, 8 pixels each */
rmax = 0x15; /* height, 15 pixels */
dx = (x - xmap) * 2;
if (draw_clipms(&xmap, &ymap, &cmax, &rmax)) /* return if not visible */
return;
/* get back to screen */
draw_setfb(xmap - DRAW_XYMAP_SCRLEFT, ymap - DRAW_XYMAP_SCRTOP);
xmap >>= 3;
cmax >>= 3;
/* draw */
for (c = 0; c < cmax; c++) { /* for each tile column */
f = fb;
for (r = 0; r < rmax; r++) { /* for each pixel row */
/* check that tile is not hidden behind foreground */
#ifdef ENABLE_CHEATS
if (front || game_cheat3 ||
!(map_eflg[map_map[(ymap + r) >> 3][xmap + c]] & MAP_EFLG_FGND)) {
#else
if (front ||
!(map_eflg[map_map[(ymap + r) >> 3][xmap + c]] & MAP_EFLG_FGND)) {
#endif
xp = xm = 0;
if (c > 0) {
xm |= sprites_data[number][c - 1][r].mask << (16 - dx);
xp |= sprites_data[number][c - 1][r].pict << (16 - dx);
}
else
xm |= 0xFFFF << (16 - dx);
if (c < cmax) {
xm |= sprites_data[number][c][r].mask >> dx;
xp |= sprites_data[number][c][r].pict >> dx;
}
else
xm |= 0xFFFF >> dx;
/*
* sprites / perform the transformation from CGA 2 bits
* per pixel to frame buffer 8 bits per pixels
*/
for (k = 8; k--; xm >>= 2, xp >>= 2) {
f[k] = ((f[k] & (xm & 3)) | (xp & 3));
#ifdef ENABLE_CHEATS
if (game_cheat3) f[k] |= 4;
#endif
}
}
f += SYSVID_WIDTH;
}
fb += 8;
}
}
#endif
/*
* Redraw the map behind a sprite
* align to tile column and row, and clip
*
* x, y: sprite position (pixels, map).
*/
void
draw_spriteBackground(U16 x, U16 y)
{
U8 r, c;
U16 rmax, cmax;
S16 xmap, ymap;
U16 xs, ys;
/* aligne to column and row, prepare map coordinate, and clip */
xmap = x & 0xFFF8;
ymap = y & 0xFFF8;
cmax = (x - xmap == 0 ? 0x20 : 0x28); /* width, 4 tl cols, 8 pix each */
rmax = (y & 0x04) ? 0x20 : 0x18; /* height, 3 or 4 tile rows */
if (draw_clipms(&xmap, &ymap, &cmax, &rmax)) /* don't draw if fully clipped */
return;
/* get back to screen */
xs = xmap - DRAW_XYMAP_SCRLEFT;
ys = ymap - DRAW_XYMAP_SCRTOP;
xmap >>= 3;
ymap >>= 3;
cmax >>= 3;
rmax >>= 3;
/* draw */
for (r = 0; r < rmax; r++) { /* for each row */
#ifdef GFXPC
draw_setfb(xs, ys + r * 8);
#endif
#ifdef GFXST
draw_setfb(xs, 8 + ys + r * 8);
#endif
for (c = 0; c < cmax; c++) { /* for each column */
draw_tile(map_map[ymap + r][xmap + c]);
}
}
}
/*
* Draw entire map screen background tiles onto frame buffer.
*
* ASM 0af5, 0a54
*/
void
draw_map(void)
{
U8 i, j;
draw_tilesBank = map_tilesBank;
for (i = 0; i < 0x18; i++) { /* 0x18 rows */
#ifdef GFXPC
draw_setfb(0x20, (i * 8));
#endif
#ifdef GFXST
draw_setfb(0x20, 8 + (i * 8));
#endif
for (j = 0; j < 0x20; j++) /* 0x20 tiles per row */
draw_tile(map_map[i + 8][j]);
}
}
/*
* Draw status indicators
*
* ASM 0309
*/
void
draw_drawStatus(void)
{
S8 i;
U32 sv;
static U8 s[7] = {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfe};
draw_tilesBank = 0;
for (i = 5, sv = game_score; i >= 0; i--) {
s[i] = 0x30 + (U8)(sv % 10);
sv /= 10;
}
draw_tllst = s;
draw_setfb(DRAW_STATUS_SCORE_X, DRAW_STATUS_Y);
draw_tilesList();
draw_setfb(DRAW_STATUS_BULLETS_X, DRAW_STATUS_Y);
for (i = 0; i < game_bullets; i++)
draw_tile(TILES_BULLET);
draw_setfb(DRAW_STATUS_BOMBS_X, DRAW_STATUS_Y);
for (i = 0; i < game_bombs; i++)
draw_tile(TILES_BOMB);
draw_setfb(DRAW_STATUS_LIVES_X, DRAW_STATUS_Y);
for (i = 0; i < game_lives; i++)
draw_tile(TILES_RICK);
}
/*
* Draw info indicators
*/
#ifdef ENABLE_CHEATS
void
draw_infos(void)
{
draw_tilesBank = 0;
#ifdef GFXPC
draw_filter = 0xffff;
#endif
draw_setfb(0x00, DRAW_STATUS_Y);
draw_tile(game_cheat1 ? 'T' : '@');
draw_setfb(0x08, DRAW_STATUS_Y);
draw_tile(game_cheat2 ? 'N' : '@');
draw_setfb(0x10, DRAW_STATUS_Y);
draw_tile(game_cheat3 ? 'V' : '@');
}
#endif
/*
* Clear status indicators
*/
void
draw_clearStatus(void)
{
U8 i;
#ifdef GFXPC
draw_tilesBank = map_tilesBank;
#endif
#ifdef GFXST
draw_tilesBank = 0;
#endif
draw_setfb(DRAW_STATUS_SCORE_X, DRAW_STATUS_Y);
for (i = 0; i < DRAW_STATUS_LIVES_X/8 + 6 - DRAW_STATUS_SCORE_X/8; i++) {
#ifdef GFXPC
draw_tile(map_map[MAP_ROW_SCRTOP + (DRAW_STATUS_Y / 8)][i]);
#endif
#ifdef GFXST
draw_tile('@');
#endif
}
}
/*
* Draw a picture
*/
#ifdef GFXST
void
draw_pic(U16 x, U16 y, U16 w, U16 h, U32 *pic)
{
U8 *f;
U16 i, j, k, pp;
U32 v;
draw_setfb(x, y);
pp = 0;
for (i = 0; i < h; i++) { /* rows */
f = fb;
for (j = 0; j < w; j += 8) { /* cols */
v = pic[pp++];
for (k = 8; k--; v >>=4)
f[k] = v & 0x0F;
f += 8;
}
fb += SYSVID_WIDTH;
}
}
#endif
/*
* Draw a bitmap
*/
void
draw_img(img_t *i)
{
U16 k;
draw_setfb(0, 0);
if (i->ncolors > 0)
sysvid_setPalette(i->colors, i->ncolors);
for (k = 0; k < SYSVID_WIDTH * SYSVID_HEIGHT; k++)
fb[k] = i->pixels[k];
}
/* eof */

153
src/e_bomb.c Normal file
View File

@ -0,0 +1,153 @@
/*
* xrick/src/e_bomb.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "system.h"
#include "game.h"
#include "ents.h"
#include "e_bomb.h"
#include "e_rick.h"
/*
* public vars (for performance reasons)
*/
U8 e_bomb_lethal;
U8 e_bomb_xc;
U16 e_bomb_yc;
/*
* private vars
*/
U8 e_bomb_ticker;
/*
* Bomb hit test
*
* ASM 11CD
* returns: TRUE/hit, FALSE/not
*/
U8 e_bomb_hit(U8 e)
{
if (ent_ents[e].x > (E_BOMB_ENT.x >= 0xE0 ? 0xFF : E_BOMB_ENT.x + 0x20))
return FALSE;
if (ent_ents[e].x + ent_ents[e].w < (E_BOMB_ENT.x > 0x04 ? E_BOMB_ENT.x - 0x04 : 0))
return FALSE;
if (ent_ents[e].y > (E_BOMB_ENT.y + 0x1D))
return FALSE;
if (ent_ents[e].y + ent_ents[e].h < (E_BOMB_ENT.y > 0x0004 ? E_BOMB_ENT.y - 0x0004 : 0))
return FALSE;
return TRUE;
}
/*
* Initialize bomb
*/
void e_bomb_init(U16 x, U16 y)
{
E_BOMB_ENT.n = 0x03;
E_BOMB_ENT.x = x;
E_BOMB_ENT.y = y;
e_bomb_ticker = E_BOMB_TICKER;
e_bomb_lethal = FALSE;
/*
* Atari ST dynamite sprites are not centered the
* way IBM PC sprites were ... need to adjust things a little bit
*/
#ifdef GFXST
E_BOMB_ENT.x += 4;
E_BOMB_ENT.y += 5;
#endif
}
/*
* Entity action
*
* ASM 18CA
*/
void
e_bomb_action(UNUSED(U8 e))
{
/* tick */
e_bomb_ticker--;
if (e_bomb_ticker == 0)
{
/*
* end: deactivate
*/
E_BOMB_ENT.n = 0;
e_bomb_lethal = FALSE;
}
else if (e_bomb_ticker >= 0x0A)
{
/*
* ticking
*/
#ifdef ENABLE_SOUND
if ((e_bomb_ticker & 0x03) == 0x02)
syssnd_play(WAV_BOMBSHHT, 1);
#endif
#ifdef GFXST
/* ST bomb sprites sequence is longer */
if (e_bomb_ticker < 40)
E_BOMB_ENT.sprite = 0x99 + 19 - (e_bomb_ticker >> 1);
else
#endif
E_BOMB_ENT.sprite = (e_bomb_ticker & 0x01) ? 0x23 : 0x22;
}
else if (e_bomb_ticker == 0x09)
{
/*
* explode
*/
#ifdef ENABLE_SOUND
syssnd_play(WAV_EXPLODE, 1);
#endif
#ifdef GFXPC
E_BOMB_ENT.sprite = 0x24 + 4 - (e_bomb_ticker >> 1);
#endif
#ifdef GFXST
/* See above: fixing alignment */
E_BOMB_ENT.x -= 4;
E_BOMB_ENT.y -= 5;
E_BOMB_ENT.sprite = 0xa8 + 4 - (e_bomb_ticker >> 1);
#endif
e_bomb_xc = E_BOMB_ENT.x + 0x0C;
e_bomb_yc = E_BOMB_ENT.y + 0x000A;
e_bomb_lethal = TRUE;
if (e_bomb_hit(E_RICK_NO))
e_rick_gozombie();
}
else
{
/*
* exploding
*/
#ifdef GFXPC
E_BOMB_ENT.sprite = 0x24 + 4 - (e_bomb_ticker >> 1);
#endif
#ifdef GFXST
E_BOMB_ENT.sprite = 0xa8 + 4 - (e_bomb_ticker >> 1);
#endif
/* exploding, hence lethal */
if (e_bomb_hit(E_RICK_NO))
e_rick_gozombie();
}
}
/* eof */

60
src/e_bonus.c Normal file
View File

@ -0,0 +1,60 @@
/*
* xrick/src/e_bonus.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "system.h"
#include "game.h"
#include "ents.h"
#include "e_bonus.h"
#include "e_rick.h"
#include "maps.h"
/*
* Entity action
*
* ASM 242C
*/
void
e_bonus_action(U8 e)
{
#define seq c1
if (ent_ents[e].seq == 0) {
if (e_rick_boxtest(e)) {
game_score += 500;
#ifdef ENABLE_SOUND
syssnd_play(WAV_BONUS, 1);
#endif
map_marks[ent_ents[e].mark].ent |= MAP_MARK_NACT;
ent_ents[e].seq = 1;
ent_ents[e].sprite = 0xad;
ent_ents[e].front = TRUE;
ent_ents[e].y -= 0x08;
}
}
else if (ent_ents[e].seq > 0 && ent_ents[e].seq < 10) {
ent_ents[e].seq++;
ent_ents[e].y -= 2;
}
else {
ent_ents[e].n = 0;
}
}
/* eof */

110
src/e_box.c Normal file
View File

@ -0,0 +1,110 @@
/*
* xrick/src/e_box.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "system.h"
#include "game.h"
#include "ents.h"
#include "e_box.h"
#include "e_bullet.h"
#include "e_bomb.h"
#include "e_rick.h"
#include "maps.h"
#include "util.h"
/*
* FIXME this is because the same structure is used
* for all entities. Need to replace this w/ an inheritance
* solution.
*/
#define cnt c1
/*
* Constants
*/
#define SEQ_INIT 0x0A
/*
* Prototypes
*/
static void explode(U8);
/*
* Entity action
*
* ASM 245A
*/
void
e_box_action(U8 e)
{
static U8 sp[] = {0x24, 0x25, 0x26, 0x27, 0x28}; /* explosion sprites sequence */
if (ent_ents[e].n & ENT_LETHAL) {
/*
* box is lethal i.e. exploding
* play sprites sequence then stop
*/
ent_ents[e].sprite = sp[ent_ents[e].cnt >> 1];
if (--ent_ents[e].cnt == 0) {
ent_ents[e].n = 0;
map_marks[ent_ents[e].mark].ent |= MAP_MARK_NACT;
}
} else {
/*
* not lethal: check to see if triggered
*/
if (e_rick_boxtest(e)) {
/* rick: collect bombs or bullets and stop */
#ifdef ENABLE_SOUND
syssnd_play(WAV_BOX, 1);
#endif
if (ent_ents[e].n == 0x10)
game_bombs = GAME_BOMBS_INIT;
else /* 0x11 */
game_bullets = GAME_BULLETS_INIT;
ent_ents[e].n = 0;
map_marks[ent_ents[e].mark].ent |= MAP_MARK_NACT;
}
else if (E_RICK_STTST(E_RICK_STSTOP) &&
u_fboxtest(e, e_rick_stop_x, e_rick_stop_y)) {
/* rick's stick: explode */
explode(e);
}
else if (E_BULLET_ENT.n && u_fboxtest(e, e_bullet_xc, e_bullet_yc)) {
/* bullet: explode (and stop bullet) */
E_BULLET_ENT.n = 0;
explode(e);
}
else if (e_bomb_lethal && e_bomb_hit(e)) {
/* bomb: explode */
explode(e);
}
}
}
/*
* Explode when
*/
static void explode(U8 e)
{
ent_ents[e].cnt = SEQ_INIT;
ent_ents[e].n |= ENT_LETHAL;
#ifdef ENABLE_SOUND
syssnd_play(WAV_EXPLODE, 1);
#endif
}
/* eof */

80
src/e_bullet.c Normal file
View File

@ -0,0 +1,80 @@
/*
* xrick/src/e_bullet.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "system.h"
#include "game.h"
#include "ents.h"
#include "e_bullet.h"
#include "maps.h"
/*
* public vars (for performance reasons)
*/
S8 e_bullet_offsx;
S16 e_bullet_xc, e_bullet_yc;
/*
* Initialize bullet
*/
void
e_bullet_init(U16 x, U16 y)
{
E_BULLET_ENT.n = 0x02;
E_BULLET_ENT.x = x;
E_BULLET_ENT.y = y + 0x0006;
if (game_dir == LEFT) {
e_bullet_offsx = -0x08;
E_BULLET_ENT.sprite = 0x21;
}
else {
e_bullet_offsx = 0x08;
E_BULLET_ENT.sprite = 0x20;
}
#ifdef ENABLE_SOUND
syssnd_play(WAV_BULLET, 1);
#endif
}
/*
* Entity action
*
* ASM 1883, 0F97
*/
void
e_bullet_action(UNUSED(U8 e))
{
/* move bullet */
E_BULLET_ENT.x += e_bullet_offsx;
if (E_BULLET_ENT.x <= -0x10 || E_BULLET_ENT.x > 0xe8) {
/* out: deactivate */
E_BULLET_ENT.n = 0;
}
else {
/* update bullet center coordinates */
e_bullet_xc = E_BULLET_ENT.x + 0x0c;
e_bullet_yc = E_BULLET_ENT.y + 0x05;
if (map_eflg[map_map[e_bullet_yc >> 3][e_bullet_xc >> 3]] &
MAP_EFLG_SOLID) {
/* hit something: deactivate */
E_BULLET_ENT.n = 0;
}
}
}
/* eof */

566
src/e_rick.c Normal file
View File

@ -0,0 +1,566 @@
/*
* xrick/src/e_rick.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "system.h"
#include "config.h"
#include "game.h"
#include "ents.h"
#include "e_rick.h"
#include "e_bullet.h"
#include "e_bomb.h"
#include "control.h"
#include "maps.h"
#include "util.h"
/*
* public vars
*/
S16 e_rick_stop_x = 0;
S16 e_rick_stop_y = 0;
U8 e_rick_state = 0;
/*
* local vars
*/
static U8 scrawl;
static U8 trigger = FALSE;
static S8 offsx;
static U8 ylow;
static S16 offsy;
static U8 seq;
static U8 save_crawl;
static U16 save_x, save_y;
/*
* Box test
*
* ASM 113E (based on)
*
* e: entity to test against (corresponds to SI in asm code -- here DI
* is assumed to point to rick).
* ret: TRUE/intersect, FALSE/not.
*/
U8
e_rick_boxtest(U8 e)
{
/*
* rick: x+0x05 to x+0x11, y+[0x08 if rick's crawling] to y+0x14
* entity: x to x+w, y to y+h
*/
if (E_RICK_ENT.x + 0x11 < ent_ents[e].x ||
E_RICK_ENT.x + 0x05 > ent_ents[e].x + ent_ents[e].w ||
E_RICK_ENT.y + 0x14 < ent_ents[e].y ||
E_RICK_ENT.y + (E_RICK_STTST(E_RICK_STCRAWL) ? 0x08 : 0x00) > ent_ents[e].y + ent_ents[e].h - 1)
return FALSE;
else
return TRUE;
}
/*
* Go zombie
*
* ASM 1851
*/
void
e_rick_gozombie(void)
{
#ifdef ENABLE_CHEATS
if (game_cheat2) return;
#endif
/* already zombie? */
if E_RICK_STTST(E_RICK_STZOMBIE) return;
#ifdef ENABLE_SOUND
syssnd_play(WAV_DIE, 1);
#endif
E_RICK_STSET(E_RICK_STZOMBIE);
offsy = -0x0400;
offsx = (E_RICK_ENT.x > 0x80 ? -3 : +3);
ylow = 0;
E_RICK_ENT.front = TRUE;
}
/*
* Action sub-function for e_rick when zombie
*
* ASM 17DC
*/
static void
e_rick_z_action(void)
{
U32 i;
/* sprite */
E_RICK_ENT.sprite = (E_RICK_ENT.x & 0x04) ? 0x1A : 0x19;
/* x */
E_RICK_ENT.x += offsx;
/* y */
i = (E_RICK_ENT.y << 8) + offsy + ylow;
E_RICK_ENT.y = i >> 8;
offsy += 0x80;
ylow = i;
/* dead when out of screen */
if (E_RICK_ENT.y < 0 || E_RICK_ENT.y > 0x0140)
E_RICK_STSET(E_RICK_STDEAD);
}
/*
* Action sub-function for e_rick.
*
* ASM 13BE
*/
void
e_rick_action2(void)
{
U8 env0, env1;
S16 x, y;
U32 i;
E_RICK_STRST(E_RICK_STSTOP|E_RICK_STSHOOT);
/* if zombie, run dedicated function and return */
if E_RICK_STTST(E_RICK_STZOMBIE) {
e_rick_z_action();
return;
}
/* climbing? */
if E_RICK_STTST(E_RICK_STCLIMB)
goto climbing;
/*
* NOT CLIMBING
*/
E_RICK_STRST(E_RICK_STJUMP);
/* calc y */
i = (E_RICK_ENT.y << 8) + offsy + ylow;
y = i >> 8;
/* test environment */
u_envtest(E_RICK_ENT.x, y, E_RICK_STTST(E_RICK_STCRAWL), &env0, &env1);
/* stand up, if possible */
if (E_RICK_STTST(E_RICK_STCRAWL) && !env0)
E_RICK_STRST(E_RICK_STCRAWL);
/* can move vertically? */
if (env1 & (offsy < 0 ?
MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD :
MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP))
goto vert_not;
/*
* VERTICAL MOVE
*/
E_RICK_STSET(E_RICK_STJUMP);
/* killed? */
if (env1 & MAP_EFLG_LETHAL) {
e_rick_gozombie();
return;
}
/* save */
E_RICK_ENT.y = y;
ylow = i;
/* climb? */
if ((env1 & MAP_EFLG_CLIMB) &&
(control_status & (CONTROL_UP|CONTROL_DOWN))) {
offsy = 0x0100;
E_RICK_STSET(E_RICK_STCLIMB);
return;
}
/* fall */
offsy += 0x0080;
if (offsy > 0x0800) {
offsy = 0x0800;
ylow = 0;
}
/*
* HORIZONTAL MOVE
*/
horiz:
/* should move? */
if (!(control_status & (CONTROL_LEFT|CONTROL_RIGHT))) {
seq = 2; /* no: reset seq and return */
return;
}
if (control_status & CONTROL_LEFT) { /* move left */
x = E_RICK_ENT.x - 2;
game_dir = LEFT;
if (x < 0) { /* prev submap */
game_chsm = TRUE;
E_RICK_ENT.x = 0xe2;
return;
}
} else { /* move right */
x = E_RICK_ENT.x + 2;
game_dir = RIGHT;
if (x >= 0xe8) { /* next submap */
game_chsm = TRUE;
E_RICK_ENT.x = 0x04;
return;
}
}
/* still within this map: test environment */
u_envtest(x, E_RICK_ENT.y, E_RICK_STTST(E_RICK_STCRAWL), &env0, &env1);
/* save x-position if it is possible to move */
if (!(env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP))) {
E_RICK_ENT.x = x;
if (env1 & MAP_EFLG_LETHAL) e_rick_gozombie();
}
/* end */
return;
/*
* NO VERTICAL MOVE
*/
vert_not:
if (offsy < 0) {
/* not climbing + trying to go _up_ not possible -> hit the roof */
E_RICK_STSET(E_RICK_STJUMP); /* fall back to the ground */
E_RICK_ENT.y &= 0xF8;
offsy = 0;
ylow = 0;
goto horiz;
}
/* else: not climbing + trying to go _down_ not possible -> standing */
/* align to ground */
E_RICK_ENT.y &= 0xF8;
E_RICK_ENT.y |= 0x03;
ylow = 0;
/* standing on a super pad? */
if ((env1 & MAP_EFLG_SPAD) && offsy >= 0X0200) {
offsy = (control_status & CONTROL_UP) ? 0xf800 : 0x00fe - offsy;
#ifdef ENABLE_SOUND
syssnd_play(WAV_PAD, 1);
#endif
goto horiz;
}
offsy = 0x0100; /* reset*/
/* standing. firing ? */
if (scrawl || !(control_status & CONTROL_FIRE))
goto firing_not;
/*
* FIRING
*/
if (control_status & (CONTROL_LEFT|CONTROL_RIGHT)) { /* stop */
if (control_status & CONTROL_RIGHT)
{
game_dir = RIGHT;
e_rick_stop_x = E_RICK_ENT.x + 0x17;
} else {
game_dir = LEFT;
e_rick_stop_x = E_RICK_ENT.x;
}
e_rick_stop_y = E_RICK_ENT.y + 0x000E;
E_RICK_STSET(E_RICK_STSTOP);
return;
}
if (control_status == (CONTROL_FIRE|CONTROL_UP)) { /* bullet */
E_RICK_STSET(E_RICK_STSHOOT);
/* not an automatic gun: shoot once only */
if (trigger)
return;
else
trigger = TRUE;
/* already a bullet in the air ... that's enough */
if (E_BULLET_ENT.n)
return;
/* else use a bullet, if any available */
if (!game_bullets)
return;
#ifdef ENABLE_CHEATS
if (!game_cheat1)
game_bullets--;
#endif
/* initialize bullet */
e_bullet_init(E_RICK_ENT.x, E_RICK_ENT.y);
return;
}
trigger = FALSE; /* not shooting means trigger is released */
seq = 0; /* reset */
if (control_status == (CONTROL_FIRE|CONTROL_DOWN)) { /* bomb */
/* already a bomb ticking ... that's enough */
if (E_BOMB_ENT.n)
return;
/* else use a bomb, if any available */
if (!game_bombs)
return;
#ifdef ENABLE_CHEATS
if (!game_cheat1)
game_bombs--;
#endif
/* initialize bomb */
e_bomb_init(E_RICK_ENT.x, E_RICK_ENT.y);
return;
}
return;
/*
* NOT FIRING
*/
firing_not:
if (control_status & CONTROL_UP) { /* jump or climb */
if (env1 & MAP_EFLG_CLIMB) { /* climb */
E_RICK_STSET(E_RICK_STCLIMB);
return;
}
offsy = -0x0580; /* jump */
ylow = 0;
#ifdef ENABLE_SOUND
syssnd_play(WAV_JUMP, 1);
#endif
goto horiz;
}
if (control_status & CONTROL_DOWN) { /* crawl or climb */
if ((env1 & MAP_EFLG_VERT) && /* can go down */
!(control_status & (CONTROL_LEFT|CONTROL_RIGHT)) && /* + not moving horizontaly */
(E_RICK_ENT.x & 0x1f) < 0x0a) { /* + aligned -> climb */
E_RICK_ENT.x &= 0xf0;
E_RICK_ENT.x |= 0x04;
E_RICK_STSET(E_RICK_STCLIMB);
}
else { /* crawl */
E_RICK_STSET(E_RICK_STCRAWL);
goto horiz;
}
}
goto horiz;
/*
* CLIMBING
*/
climbing:
/* should move? */
if (!(control_status & (CONTROL_UP|CONTROL_DOWN|CONTROL_LEFT|CONTROL_RIGHT))) {
seq = 0; /* no: reset seq and return */
return;
}
if (control_status & (CONTROL_UP|CONTROL_DOWN)) {
/* up-down: calc new y and test environment */
y = E_RICK_ENT.y + ((control_status & CONTROL_UP) ? -0x02 : 0x02);
u_envtest(E_RICK_ENT.x, y, E_RICK_STTST(E_RICK_STCRAWL), &env0, &env1);
if (env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP) &&
!(control_status & CONTROL_UP)) {
/* FIXME what? */
E_RICK_STRST(E_RICK_STCLIMB);
return;
}
if (!(env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP)) ||
(env1 & MAP_EFLG_WAYUP)) {
/* ok to move, save */
E_RICK_ENT.y = y;
if (env1 & MAP_EFLG_LETHAL) {
e_rick_gozombie();
return;
}
if (!(env1 & (MAP_EFLG_VERT|MAP_EFLG_CLIMB))) {
/* reached end of climb zone */
offsy = (control_status & CONTROL_UP) ? -0x0300 : 0x0100;
#ifdef ENABLE_SOUND
if (control_status & CONTROL_UP)
syssnd_play(WAV_JUMP, 1);
#endif
E_RICK_STRST(E_RICK_STCLIMB);
return;
}
}
}
if (control_status & (CONTROL_LEFT|CONTROL_RIGHT)) {
/* left-right: calc new x and test environment */
if (control_status & CONTROL_LEFT) {
x = E_RICK_ENT.x - 0x02;
if (x < 0) { /* (i.e. negative) prev submap */
game_chsm = TRUE;
/*6dbd = 0x00;*/
E_RICK_ENT.x = 0xe2;
return;
}
}
else {
x = E_RICK_ENT.x + 0x02;
if (x >= 0xe8) { /* next submap */
game_chsm = TRUE;
/*6dbd = 0x01;*/
E_RICK_ENT.x = 0x04;
return;
}
}
u_envtest(x, E_RICK_ENT.y, E_RICK_STTST(E_RICK_STCRAWL), &env0, &env1);
if (env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD)) return;
E_RICK_ENT.x = x;
if (env1 & MAP_EFLG_LETHAL) {
e_rick_gozombie();
return;
}
if (env1 & (MAP_EFLG_VERT|MAP_EFLG_CLIMB)) return;
E_RICK_STRST(E_RICK_STCLIMB);
if (control_status & CONTROL_UP)
offsy = -0x0300;
}
}
/*
* Action function for e_rick
*
* ASM 12CA
*/
void e_rick_action(UNUSED(U8 e))
{
static U8 stopped = FALSE; /* is this the most elegant way? */
e_rick_action2();
scrawl = E_RICK_STTST(E_RICK_STCRAWL);
if E_RICK_STTST(E_RICK_STZOMBIE)
return;
/*
* set sprite
*/
if E_RICK_STTST(E_RICK_STSTOP) {
E_RICK_ENT.sprite = (game_dir ? 0x17 : 0x0B);
#ifdef ENABLE_SOUND
if (!stopped)
{
syssnd_play(WAV_STICK, 1);
stopped = TRUE;
}
#endif
return;
}
stopped = FALSE;
if E_RICK_STTST(E_RICK_STSHOOT) {
E_RICK_ENT.sprite = (game_dir ? 0x16 : 0x0A);
return;
}
if E_RICK_STTST(E_RICK_STCLIMB) {
E_RICK_ENT.sprite = (((E_RICK_ENT.x ^ E_RICK_ENT.y) & 0x04) ? 0x18 : 0x0c);
#ifdef ENABLE_SOUND
seq = (seq + 1) & 0x03;
if (seq == 0) syssnd_play(WAV_WALK, 1);
#endif
return;
}
if E_RICK_STTST(E_RICK_STCRAWL)
{
E_RICK_ENT.sprite = (game_dir ? 0x13 : 0x07);
if (E_RICK_ENT.x & 0x04) E_RICK_ENT.sprite++;
#ifdef ENABLE_SOUND
seq = (seq + 1) & 0x03;
if (seq == 0) syssnd_play(WAV_CRAWL, 1);
#endif
return;
}
if E_RICK_STTST(E_RICK_STJUMP)
{
E_RICK_ENT.sprite = (game_dir ? 0x15 : 0x06);
return;
}
seq++;
if (seq >= 0x14)
{
#ifdef ENABLE_SOUND
syssnd_play(WAV_WALK, 1);
#endif
seq = 0x04;
}
#ifdef ENABLE_SOUND
else
if (seq == 0x0C)
syssnd_play(WAV_WALK, 1);
#endif
E_RICK_ENT.sprite = (seq >> 2) + 1 + (game_dir ? 0x0c : 0x00);
}
/*
* Save status
*
* ASM part of 0x0BBB
*/
void e_rick_save(void)
{
save_x = E_RICK_ENT.x;
save_y = E_RICK_ENT.y;
save_crawl = E_RICK_STTST(E_RICK_STCRAWL);
/* FIXME
* save_C0 = E_RICK_ENT.b0C;
* plus some 6DBC stuff?
*/
}
/*
* Restore status
*
* ASM part of 0x0BDC
*/
void e_rick_restore(void)
{
E_RICK_ENT.x = save_x;
E_RICK_ENT.y = save_y;
E_RICK_ENT.front = FALSE;
if (save_crawl)
E_RICK_STSET(E_RICK_STCRAWL);
else
E_RICK_STRST(E_RICK_STCRAWL);
/* FIXME
* E_RICK_ENT.b0C = save_C0;
* plus some 6DBC stuff?
*/
}
/* eof */

89
src/e_sbonus.c Normal file
View File

@ -0,0 +1,89 @@
/*
* xrick/src/e_sbonus.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "system.h"
#include "game.h"
#include "ents.h"
#include "e_sbonus.h"
#include "util.h"
#include "maps.h"
#include "e_rick.h"
/*
* public vars
*/
U8 e_sbonus_counting = FALSE;
U8 e_sbonus_counter = 0;
U16 e_sbonus_bonus = 0;
/*
* Entity action / start counting
*
* ASM 2182
*/
void
e_sbonus_start(U8 e)
{
ent_ents[e].sprite = 0; /* invisible */
if (u_trigbox(e, ENT_XRICK.x + 0x0C, ENT_XRICK.y + 0x0A)) {
/* rick is within trigger box */
ent_ents[e].n = 0;
e_sbonus_counting = TRUE; /* 6DD5 */
e_sbonus_counter = 0x1e; /* 6DDB */
e_sbonus_bonus = 2000; /* 291A-291D */
#ifdef ENABLE_SOUND
syssnd_play(WAV_SBONUS1, 1);
#endif
}
}
/*
* Entity action / stop counting
*
* ASM 2143
*/
void
e_sbonus_stop(U8 e)
{
ent_ents[e].sprite = 0; /* invisible */
if (!e_sbonus_counting)
return;
if (u_trigbox(e, ENT_XRICK.x + 0x0C, ENT_XRICK.y + 0x0A)) {
/* rick is within trigger box */
e_sbonus_counting = FALSE; /* stop counting */
ent_ents[e].n = 0; /* deactivate entity */
game_score += e_sbonus_bonus; /* add bonus to score */
#ifdef ENABLE_SOUND
syssnd_play(WAV_SBONUS2, 1);
#endif
/* make sure the entity won't be activated again */
map_marks[ent_ents[e].mark].ent |= MAP_MARK_NACT;
}
else {
/* keep counting */
if (--e_sbonus_counter == 0) {
e_sbonus_counter = 0x1e;
if (e_sbonus_bonus) e_sbonus_bonus--;
}
}
}
/* eof */

727
src/e_them.c Normal file
View File

@ -0,0 +1,727 @@
/*
* xrick/src/e_them.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "system.h"
#include "game.h"
#include "ents.h"
#include "e_them.h"
#include "e_rick.h"
#include "e_bomb.h"
#include "e_bullet.h"
#include "maps.h"
#include "util.h"
#define TYPE_1A (0x00)
#define TYPE_1B (0xff)
/*
* public vars
*/
U32 e_them_rndseed = 0;
/*
* local vars
*/
static U16 e_them_rndnbr = 0;
/*
* Check if entity boxtests with a lethal e_them i.e. something lethal
* in slot 0 and 4 to 8.
*
* ASM 122E
*
* e: entity slot number.
* ret: TRUE/boxtests, FALSE/not
*/
U8
u_themtest(U8 e)
{
U8 i;
if ((ent_ents[0].n & ENT_LETHAL) && u_boxtest(e, 0))
return TRUE;
for (i = 4; i < 9; i++)
if ((ent_ents[i].n & ENT_LETHAL) && u_boxtest(e, i))
return TRUE;
return FALSE;
}
/*
* Go zombie
*
* ASM 237B
*/
void
e_them_gozombie(U8 e)
{
#define offsx c1
ent_ents[e].n = 0x47; /* zombie entity */
ent_ents[e].front = TRUE;
ent_ents[e].offsy = -0x0400;
#ifdef ENABLE_SOUND
syssnd_play(WAV_DIE, 1);
#endif
game_score += 50;
if (ent_ents[e].flags & ENT_FLG_ONCE) {
/* make sure entity won't be activated again */
map_marks[ent_ents[e].mark].ent |= MAP_MARK_NACT;
}
ent_ents[e].offsx = (ent_ents[e].x >= 0x80 ? -0x02 : 0x02);
#undef offsx
}
/*
* Action sub-function for e_them _t1a and _t1b
*
* Those two types move horizontally, and fall if they have to.
* Type 1a moves horizontally over a given distance and then
* u-turns and repeats; type 1b is more subtle as it does u-turns
* in order to move horizontally towards rick.
*
* ASM 2242
*/
void
e_them_t1_action2(U8 e, U8 type)
{
#define offsx c1
#define step_count c2
U32 i;
S16 x, y;
U8 env0, env1;
/* by default, try vertical move. calculate new y */
i = (ent_ents[e].y << 8) + ent_ents[e].offsy + ent_ents[e].ylow;
y = i >> 8;
/* deactivate if outside vertical boundaries */
/* no need to test zero since e_them _t1a/b don't go up */
/* FIXME what if they got scrolled out ? */
if (y > 0x140) {
ent_ents[e].n = 0;
return;
}
/* test environment */
u_envtest(ent_ents[e].x, y, FALSE, &env0, &env1);
if (!(env1 & (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP))) {
/* vertical move possible: falling */
if (env1 & MAP_EFLG_LETHAL) {
/* lethal entities kill e_them */
e_them_gozombie(e);
return;
}
/* save, cleanup and return */
ent_ents[e].y = y;
ent_ents[e].ylow = i;
ent_ents[e].offsy += 0x0080;
if (ent_ents[e].offsy > 0x0800)
ent_ents[e].offsy = 0x0800;
return;
}
/* vertical move not possible. calculate new sprite */
ent_ents[e].sprite = ent_ents[e].sprbase
+ ent_sprseq[(ent_ents[e].x & 0x1c) >> 3]
+ (ent_ents[e].offsx < 0 ? 0x03 : 0x00);
/* reset offsy */
ent_ents[e].offsy = 0x0080;
/* align to ground */
ent_ents[e].y &= 0xfff8;
ent_ents[e].y |= 0x0003;
/* latency: if not zero then decrease and return */
if (ent_ents[e].latency > 0) {
ent_ents[e].latency--;
return;
}
/* horizontal move. calculate new x */
if (ent_ents[e].offsx == 0) /* not supposed to move -> don't */
return;
x = ent_ents[e].x + ent_ents[e].offsx;
if (ent_ents[e].x < 0 || ent_ents[e].x > 0xe8) {
/* U-turn and return if reaching horizontal boundaries */
ent_ents[e].step_count = 0;
ent_ents[e].offsx = -ent_ents[e].offsx;
return;
}
/* test environment */
u_envtest(x, ent_ents[e].y, FALSE, &env0, &env1);
if (env1 & (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP)) {
/* horizontal move not possible: u-turn and return */
ent_ents[e].step_count = 0;
ent_ents[e].offsx = -ent_ents[e].offsx;
return;
}
/* horizontal move possible */
if (env1 & MAP_EFLG_LETHAL) {
/* lethal entities kill e_them */
e_them_gozombie(e);
return;
}
/* save */
ent_ents[e].x = x;
/* depending on type, */
if (type == TYPE_1B) {
/* set direction to move horizontally towards rick */
if ((ent_ents[e].x & 0x1e) != 0x10) /* prevents too frequent u-turns */
return;
ent_ents[e].offsx = (ent_ents[e].x < E_RICK_ENT.x) ? 0x02 : -0x02;
return;
}
else {
/* set direction according to step counter */
ent_ents[e].step_count++;
/* FIXME why trig_x (b16) ?? */
if ((ent_ents[e].trig_x >> 1) > ent_ents[e].step_count)
return;
}
/* type is 1A and step counter reached its limit: u-turn */
ent_ents[e].step_count = 0;
ent_ents[e].offsx = -ent_ents[e].offsx;
#undef offsx
#undef step_count
}
/*
* ASM 21CF
*/
void
e_them_t1_action(U8 e, U8 type)
{
e_them_t1_action2(e, type);
/* lethal entities kill them */
if (u_themtest(e)) {
e_them_gozombie(e);
return;
}
/* bullet kills them */
if (E_BULLET_ENT.n &&
u_fboxtest(e, E_BULLET_ENT.x + (e_bullet_offsx < 0 ? 0 : 0x18),
E_BULLET_ENT.y)) {
E_BULLET_ENT.n = 0;
e_them_gozombie(e);
return;
}
/* bomb kills them */
if (e_bomb_lethal && e_bomb_hit(e)) {
e_them_gozombie(e);
return;
}
/* rick stops them */
if (E_RICK_STTST(E_RICK_STSTOP) &&
u_fboxtest(e, e_rick_stop_x, e_rick_stop_y))
ent_ents[e].latency = 0x14;
/* they kill rick */
if (e_rick_boxtest(e))
e_rick_gozombie();
}
/*
* Action function for e_them _t1a type (stays within boundaries)
*
* ASM 2452
*/
void
e_them_t1a_action(U8 e)
{
e_them_t1_action(e, TYPE_1A);
}
/*
* Action function for e_them _t1b type (runs for rick)
*
* ASM 21CA
*/
void
e_them_t1b_action(U8 e)
{
e_them_t1_action(e, TYPE_1B);
}
/*
* Action function for e_them _z (zombie) type
*
* ASM 23B8
*/
void
e_them_z_action(U8 e)
{
#define offsx c1
U32 i;
/* calc new sprite */
ent_ents[e].sprite = ent_ents[e].sprbase
+ ((ent_ents[e].x & 0x04) ? 0x07 : 0x06);
/* calc new y */
i = (ent_ents[e].y << 8) + ent_ents[e].offsy + ent_ents[e].ylow;
/* deactivate if out of vertical boundaries */
if (ent_ents[e].y < 0 || ent_ents[e].y > 0x0140) {
ent_ents[e].n = 0;
return;
}
/* save */
ent_ents[e].offsy += 0x0080;
ent_ents[e].ylow = i;
ent_ents[e].y = i >> 8;
/* calc new x */
ent_ents[e].x += ent_ents[e].offsx;
/* must stay within horizontal boundaries */
if (ent_ents[e].x < 0)
ent_ents[e].x = 0;
if (ent_ents[e].x > 0xe8)
ent_ents[e].x = 0xe8;
#undef offsx
}
/*
* Action sub-function for e_them _t2.
*
* Must document what it does.
*
* ASM 2792
*/
void
e_them_t2_action2(U8 e)
{
#define flgclmb c1
#define offsx c2
U32 i;
S16 x, y, yd;
U8 env0, env1;
/*
* vars required by the Black Magic (tm) performance at the
* end of this function.
*/
static U16 bx;
static U8 *bl = (U8 *)&bx;
static U8 *bh = (U8 *)&bx + 1;
static U16 cx;
static U8 *cl = (U8 *)&cx;
static U8 *ch = (U8 *)&cx + 1;
static U16 *sl = (U16 *)&e_them_rndseed;
static U16 *sh = (U16 *)&e_them_rndseed + 2;
/*sys_printf("e_them_t2 ------------------------------\n");*/
/* latency: if not zero then decrease */
if (ent_ents[e].latency > 0) ent_ents[e].latency--;
/* climbing? */
if (ent_ents[e].flgclmb != TRUE) goto climbing_not;
/* CLIMBING */
/*sys_printf("e_them_t2 climbing\n");*/
/* latency: if not zero then return */
if (ent_ents[e].latency > 0) return;
/* calc new sprite */
ent_ents[e].sprite = ent_ents[e].sprbase + 0x08 +
(((ent_ents[e].x ^ ent_ents[e].y) & 0x04) ? 1 : 0);
/* reached rick's level? */
if ((ent_ents[e].y & 0xfe) != (E_RICK_ENT.y & 0xfe)) goto ymove;
xmove:
/* calc new x and test environment */
ent_ents[e].offsx = (ent_ents[e].x < E_RICK_ENT.x) ? 0x02 : -0x02;
x = ent_ents[e].x + ent_ents[e].offsx;
u_envtest(x, ent_ents[e].y, FALSE, &env0, &env1);
if (env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP))
return;
if (env1 & MAP_EFLG_LETHAL) {
e_them_gozombie(e);
return;
}
ent_ents[e].x = x;
if (env1 & (MAP_EFLG_VERT|MAP_EFLG_CLIMB)) /* still climbing */
return;
goto climbing_not; /* not climbing anymore */
ymove:
/* calc new y and test environment */
yd = ent_ents[e].y < E_RICK_ENT.y ? 0x02 : -0x02;
y = ent_ents[e].y + yd;
if (y < 0 || y > 0x0140) {
ent_ents[e].n = 0;
return;
}
u_envtest(ent_ents[e].x, y, FALSE, &env0, &env1);
if (env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP)) {
if (yd < 0)
goto xmove; /* can't go up */
else
goto climbing_not; /* can't go down */
}
/* can move */
ent_ents[e].y = y;
if (env1 & (MAP_EFLG_VERT|MAP_EFLG_CLIMB)) /* still climbing */
return;
/* NOT CLIMBING */
climbing_not:
/*sys_printf("e_them_t2 climbing NOT\n");*/
ent_ents[e].flgclmb = FALSE; /* not climbing */
/* calc new y (falling) and test environment */
i = (ent_ents[e].y << 8) + ent_ents[e].offsy + ent_ents[e].ylow;
y = i >> 8;
u_envtest(ent_ents[e].x, y, FALSE, &env0, &env1);
if (!(env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP))) {
/*sys_printf("e_them_t2 y move OK\n");*/
/* can go there */
if (env1 & MAP_EFLG_LETHAL) {
e_them_gozombie(e);
return;
}
if (y > 0x0140) { /* deactivate if outside */
ent_ents[e].n = 0;
return;
}
if (!(env1 & MAP_EFLG_VERT)) {
/* save */
ent_ents[e].y = y;
ent_ents[e].ylow = i;
ent_ents[e].offsy += 0x0080;
if (ent_ents[e].offsy > 0x0800)
ent_ents[e].offsy = 0x0800;
return;
}
if (((ent_ents[e].x & 0x07) == 0x04) && (y < E_RICK_ENT.y)) {
/*sys_printf("e_them_t2 climbing00\n");*/
ent_ents[e].flgclmb = TRUE; /* climbing */
return;
}
}
/*sys_printf("e_them_t2 ymove nok or ...\n");*/
/* can't go there, or ... */
ent_ents[e].y = (ent_ents[e].y & 0xf8) | 0x03; /* align to ground */
ent_ents[e].offsy = 0x0100;
if (ent_ents[e].latency != 00)
return;
if ((env1 & MAP_EFLG_CLIMB) &&
((ent_ents[e].x & 0x0e) == 0x04) &&
(ent_ents[e].y > E_RICK_ENT.y)) {
/*sys_printf("e_them_t2 climbing01\n");*/
ent_ents[e].flgclmb = TRUE; /* climbing */
return;
}
/* calc new sprite */
ent_ents[e].sprite = ent_ents[e].sprbase +
ent_sprseq[(ent_ents[e].offsx < 0 ? 4 : 0) +
((ent_ents[e].x & 0x0e) >> 3)];
/*sys_printf("e_them_t2 sprite %02x\n", ent_ents[e].sprite);*/
/* */
if (ent_ents[e].offsx == 0)
ent_ents[e].offsx = 2;
x = ent_ents[e].x + ent_ents[e].offsx;
/*sys_printf("e_them_t2 xmove x=%02x\n", x);*/
if (x < 0xe8) {
u_envtest(x, ent_ents[e].y, FALSE, &env0, &env1);
if (!(env1 & (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP))) {
ent_ents[e].x = x;
if ((x & 0x1e) != 0x08)
return;
/*
* Black Magic (tm)
*
* this is obviously some sort of randomizer to define a direction
* for the entity. it is an exact copy of what the assembler code
* does but I can't explain.
*/
bx = e_them_rndnbr + *sh + *sl + 0x0d;
cx = *sh;
*bl ^= *ch;
*bl ^= *cl;
*bl ^= *bh;
e_them_rndnbr = bx;
ent_ents[e].offsx = (*bl & 0x01) ? -0x02 : 0x02;
/* back to normal */
return;
}
}
/* U-turn */
/*sys_printf("e_them_t2 u-turn\n");*/
if (ent_ents[e].offsx == 0)
ent_ents[e].offsx = 2;
else
ent_ents[e].offsx = -ent_ents[e].offsx;
#undef offsx
}
/*
* Action function for e_them _t2 type
*
* ASM 2718
*/
void
e_them_t2_action(U8 e)
{
e_them_t2_action2(e);
/* they kill rick */
if (e_rick_boxtest(e))
e_rick_gozombie();
/* lethal entities kill them */
if (u_themtest(e)) {
e_them_gozombie(e);
return;
}
/* bullet kills them */
if (E_BULLET_ENT.n &&
u_fboxtest(e, E_BULLET_ENT.x + (e_bullet_offsx < 0 ? 00 : 0x18),
E_BULLET_ENT.y)) {
E_BULLET_ENT.n = 0;
e_them_gozombie(e);
return;
}
/* bomb kills them */
if (e_bomb_lethal && e_bomb_hit(e)) {
e_them_gozombie(e);
return;
}
/* rick stops them */
if (E_RICK_STTST(E_RICK_STSTOP) &&
u_fboxtest(e, e_rick_stop_x, e_rick_stop_y))
ent_ents[e].latency = 0x14;
}
/*
* Action sub-function for e_them _t3
*
* FIXME always starts asleep??
*
* Waits until triggered by something, then execute move steps from
* ent_mvstep with sprite from ent_sprseq. When done, either restart
* or disappear.
*
* Not always lethal ... but if lethal, kills rick.
*
* ASM: 255A
*/
void
e_them_t3_action2(U8 e)
{
#define sproffs c1
#define step_count c2
U8 i;
S16 x, y;
while (1) {
/* calc new sprite */
i = ent_sprseq[ent_ents[e].sprbase + ent_ents[e].sproffs];
if (i == 0xff)
i = ent_sprseq[ent_ents[e].sprbase];
ent_ents[e].sprite = i;
if (ent_ents[e].sproffs != 0) { /* awake */
/* rotate sprseq */
if (ent_sprseq[ent_ents[e].sprbase + ent_ents[e].sproffs] != 0xff)
ent_ents[e].sproffs++;
if (ent_sprseq[ent_ents[e].sprbase + ent_ents[e].sproffs] == 0xff)
ent_ents[e].sproffs = 1;
if (ent_ents[e].step_count < ent_mvstep[ent_ents[e].step_no].count) {
/*
* still running this step: try to increment x and y while
* checking that they remain within boudaries. if so, return.
* else switch to next step.
*/
ent_ents[e].step_count++;
x = ent_ents[e].x + ent_mvstep[ent_ents[e].step_no].dx;
/* check'n save */
if (x > 0 && x < 0xe8) {
ent_ents[e].x = x;
/*FIXME*/
/*
y = ent_mvstep[ent_ents[e].step_no].dy;
if (y < 0)
y += 0xff00;
y += ent_ents[e].y;
*/
y = ent_ents[e].y + ent_mvstep[ent_ents[e].step_no].dy;
if (y > 0 && y < 0x0140) {
ent_ents[e].y = y;
return;
}
}
}
/*
* step is done, or x or y is outside boundaries. try to
* switch to next step
*/
ent_ents[e].step_no++;
if (ent_mvstep[ent_ents[e].step_no].count != 0xff) {
/* there is a next step: init and loop */
ent_ents[e].step_count = 0;
}
else {
/* there is no next step: restart or deactivate */
if (!E_RICK_STTST(E_RICK_STZOMBIE) &&
!(ent_ents[e].flags & ENT_FLG_ONCE)) {
/* loop this entity */
ent_ents[e].sproffs = 0;
ent_ents[e].n &= ~ENT_LETHAL;
if (ent_ents[e].flags & ENT_FLG_LETHALR)
ent_ents[e].n |= ENT_LETHAL;
ent_ents[e].x = ent_ents[e].xsave;
ent_ents[e].y = ent_ents[e].ysave;
if (ent_ents[e].y < 0 || ent_ents[e].y > 0x140) {
ent_ents[e].n = 0;
return;
}
}
else {
/* deactivate this entity */
ent_ents[e].n = 0;
return;
}
}
}
else { /* ent_ents[e].sprseq1 == 0 -- waiting */
/* ugly GOTOs */
if (ent_ents[e].flags & ENT_FLG_TRIGRICK) { /* reacts to rick */
/* wake up if triggered by rick */
if (u_trigbox(e, E_RICK_ENT.x + 0x0C, E_RICK_ENT.y + 0x0A))
goto wakeup;
}
if (ent_ents[e].flags & ENT_FLG_TRIGSTOP) { /* reacts to rick "stop" */
/* wake up if triggered by rick "stop" */
if (E_RICK_STTST(E_RICK_STSTOP) &&
u_trigbox(e, e_rick_stop_x, e_rick_stop_y))
goto wakeup;
}
if (ent_ents[e].flags & ENT_FLG_TRIGBULLET) { /* reacts to bullets */
/* wake up if triggered by bullet */
if (E_BULLET_ENT.n && u_trigbox(e, e_bullet_xc, e_bullet_yc)) {
E_BULLET_ENT.n = 0;
goto wakeup;
}
}
if (ent_ents[e].flags & ENT_FLG_TRIGBOMB) { /* reacts to bombs */
/* wake up if triggered by bomb */
if (e_bomb_lethal && u_trigbox(e, e_bomb_xc, e_bomb_yc))
goto wakeup;
}
/* not triggered: keep waiting */
return;
/* something triggered the entity: wake up */
/* initialize step counter */
wakeup:
if E_RICK_STTST(E_RICK_STZOMBIE)
return;
#ifdef ENABLE_SOUND
/*
* FIXME the sound should come from a table, there are 10 of them
* but I dont have the table yet. must rip the data off the game...
* FIXME is it 8 of them, not 10?
* FIXME testing below...
*/
syssnd_play(WAV_ENTITY[(ent_ents[e].trigsnd & 0x1F) - 0x14], 1);
/*syssnd_play(WAV_ENTITY[0], 1);*/
#endif
ent_ents[e].n &= ~ENT_LETHAL;
if (ent_ents[e].flags & ENT_FLG_LETHALI)
ent_ents[e].n |= ENT_LETHAL;
ent_ents[e].sproffs = 1;
ent_ents[e].step_count = 0;
ent_ents[e].step_no = ent_ents[e].step_no_i;
return;
}
}
#undef step_count
}
/*
* Action function for e_them _t3 type
*
* ASM 2546
*/
void
e_them_t3_action(U8 e)
{
e_them_t3_action2(e);
/* if lethal, can kill rick */
if ((ent_ents[e].n & ENT_LETHAL) &&
!E_RICK_STTST(E_RICK_STZOMBIE) && e_rick_boxtest(e)) { /* CALL 1130 */
e_rick_gozombie();
}
}
/* eof */

520
src/ents.c Normal file
View File

@ -0,0 +1,520 @@
/*
* xrick/src/ents.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <stdlib.h>
#include "system.h"
#include "config.h"
#include "game.h"
#include "ents.h"
#include "debug.h"
#include "e_bullet.h"
#include "e_bomb.h"
#include "e_rick.h"
#include "e_them.h"
#include "e_bonus.h"
#include "e_box.h"
#include "e_sbonus.h"
#include "rects.h"
#include "maps.h"
#include "draw.h"
/*
* global vars
*/
ent_t ent_ents[ENT_ENTSNUM + 1];
rect_t *ent_rects = NULL;
/*
* prototypes
*/
static void ent_addrect(S16, S16, U16, U16);
static U8 ent_creat1(U8 *);
static U8 ent_creat2(U8 *, U16);
/*
* Reset entities
*
* ASM 2520
*/
void
ent_reset(void)
{
U8 i;
E_RICK_STRST(E_RICK_STSTOP);
e_bomb_lethal = FALSE;
ent_ents[0].n = 0;
for (i = 2; ent_ents[i].n != 0xff; i++)
ent_ents[i].n = 0;
}
/*
* Create an entity on slots 4 to 8 by using the first slot available.
* Entities of type e_them on slots 4 to 8, when lethal, can kill
* other e_them (on slots 4 to C) as well as rick.
*
* ASM 209C
*
* e: anything, CHANGED to the allocated entity number.
* return: TRUE/OK FALSE/not
*/
static U8
ent_creat1(U8 *e)
{
/* look for a slot */
for (*e = 0x04; *e < 0x09; (*e)++)
if (ent_ents[*e].n == 0) { /* if slot available, use it */
ent_ents[*e].c1 = 0;
return TRUE;
}
return FALSE;
}
/*
* Create an entity on slots 9 to C by using the first slot available.
* Entities of type e_them on slots 9 to C can kill rick when lethal,
* but they can never kill other e_them.
*
* ASM 20BC
*
* e: anything, CHANGED to the allocated entity number.
* m: number of the mark triggering the creation of the entity.
* ret: TRUE/OK FALSE/not
*/
static U8
ent_creat2(U8 *e, U16 m)
{
/* make sure the entity created by this mark is not active already */
for (*e = 0x09; *e < 0x0c; (*e)++)
if (ent_ents[*e].n != 0 && ent_ents[*e].mark == m)
return FALSE;
/* look for a slot */
for (*e = 0x09; *e < 0x0c; (*e)++)
if (ent_ents[*e].n == 0) { /* if slot available, use it */
ent_ents[*e].c1 = 2;
return TRUE;
}
return FALSE;
}
/*
* Process marks that are within the visible portion of the map,
* and create the corresponding entities.
*
* absolute map coordinate means that they are not relative to
* map_frow, as any other coordinates are.
*
* ASM 1F40
*
* frow: first visible row of the map -- absolute map coordinate
* lrow: last visible row of the map -- absolute map coordinate
*/
void
ent_actvis(U8 frow, U8 lrow)
{
U16 m;
U8 e;
U16 y;
/*
* go through the list and find the first mark that
* is visible, i.e. which has a row greater than the
* first row (marks being ordered by row number).
*/
for (m = map_submaps[game_submap].mark;
map_marks[m].row != 0xff && map_marks[m].row < frow;
m++);
if (map_marks[m].row == 0xff) /* none found */
return;
/*
* go through the list and process all marks that are
* visible, i.e. which have a row lower than the last
* row (marks still being ordered by row number).
*/
for (;
map_marks[m].row != 0xff && map_marks[m].row < lrow;
m++) {
/* ignore marks that are not active */
if (map_marks[m].ent & MAP_MARK_NACT)
continue;
/*
* allocate a slot to the new entity
*
* slot type
* 0 available for e_them (lethal to other e_them, and stops entities
* i.e. entities can't move over them. E.g. moving blocks. But they
* can move over entities and kill them!).
* 1 xrick
* 2 bullet
* 3 bomb
* 4-8 available for e_them, e_box, e_bonus or e_sbonus (lethal to
* other e_them, identified by their number being >= 0x10)
* 9-C available for e_them, e_box, e_bonus or e_sbonus (not lethal to
* other e_them, identified by their number being < 0x10)
*
* the type of an entity is determined by its .n as detailed below.
*
* 1 xrick
* 2 bullet
* 3 bomb
* 4, 7, a, d e_them, type 1a
* 5, 8, b, e e_them, type 1b
* 6, 9, c, f e_them, type 2
* 10, 11 box
* 12, 13, 14, 15 bonus
* 16, 17 speed bonus
* >17 e_them, type 3
* 47 zombie
*/
if (!(map_marks[m].flags & ENT_FLG_STOPRICK)) {
if (map_marks[m].ent >= 0x10) {
/* boxes, bonuses and type 3 e_them go to slot 4-8 */
/* (c1 set to 0 -> all type 3 e_them are sleeping) */
if (!ent_creat1(&e)) continue;
}
else {
/* type 1 and 2 e_them go to slot 9-c */
/* (c1 set to 2) */
if (!ent_creat2(&e, m)) continue;
}
}
else {
/* entities stopping rick (e.g. blocks) go to slot 0 */
if (ent_ents[0].n) continue;
e = 0;
ent_ents[0].c1 = 0;
}
/*
* initialize the entity
*/
ent_ents[e].mark = m;
ent_ents[e].flags = map_marks[m].flags;
ent_ents[e].n = map_marks[m].ent;
/*
* if entity is to be already running (i.e. not asleep and waiting
* for some trigger to move), then use LETHALR i.e. restart flag, right
* from the beginning
*/
if (ent_ents[e].flags & ENT_FLG_LETHALR)
ent_ents[e].n |= ENT_LETHAL;
ent_ents[e].x = map_marks[m].xy & 0xf8;
y = (map_marks[m].xy & 0x07) + (map_marks[m].row & 0xf8) - map_frow;
y <<= 3;
if (!(ent_ents[e].flags & ENT_FLG_STOPRICK))
y += 3;
ent_ents[e].y = y;
ent_ents[e].xsave = ent_ents[e].x;
ent_ents[e].ysave = ent_ents[e].y;
/*ent_ents[e].w0C = 0;*/ /* in ASM code but never used */
ent_ents[e].w = ent_entdata[map_marks[m].ent].w;
ent_ents[e].h = ent_entdata[map_marks[m].ent].h;
ent_ents[e].sprbase = ent_entdata[map_marks[m].ent].spr;
ent_ents[e].sprite = (U8)ent_entdata[map_marks[m].ent].spr;
ent_ents[e].step_no_i = ent_entdata[map_marks[m].ent].sni;
ent_ents[e].trigsnd = (U8)ent_entdata[map_marks[m].ent].snd;
/*
* FIXME what is this? when all trigger flags are up, then
* use .sni for sprbase. Why? What is the point? (This is
* for type 1 and 2 e_them, ...)
*
* This also means that as long as sprite has not been
* recalculated, a wrong value is used. This is normal, see
* what happens to the falling guy on the right on submap 3:
* it changes when hitting the ground.
*/
#define ENT_FLG_TRIGGERS \
(ENT_FLG_TRIGBOMB|ENT_FLG_TRIGBULLET|ENT_FLG_TRIGSTOP|ENT_FLG_TRIGRICK)
if ((ent_ents[e].flags & ENT_FLG_TRIGGERS) == ENT_FLG_TRIGGERS
&& e >= 0x09)
ent_ents[e].sprbase = (U8)(ent_entdata[map_marks[m].ent].sni & 0x00ff);
#undef ENT_FLG_TRIGGERS
ent_ents[e].trig_x = map_marks[m].lt & 0xf8;
ent_ents[e].latency = (map_marks[m].lt & 0x07) << 5; /* <<5 eq *32 */
ent_ents[e].trig_y = 3 + 8 * ((map_marks[m].row & 0xf8) - map_frow +
(map_marks[m].lt & 0x07));
ent_ents[e].c2 = 0;
ent_ents[e].offsy = 0;
ent_ents[e].ylow = 0;
ent_ents[e].front = FALSE;
}
}
/*
* Add a tile-aligned rectangle containing the given rectangle (indicated
* by its MAP coordinates) to the list of rectangles. Clip the rectangle
* so it fits into the display zone.
*/
static void
ent_addrect(S16 x, S16 y, U16 width, U16 height)
{
S16 x0, y0;
U16 w0, h0;
/*sys_printf("rect %#04x,%#04x %#04x %#04x ", x, y, width, height);*/
/* align to tiles */
x0 = x & 0xfff8;
y0 = y & 0xfff8;
w0 = width;
h0 = height;
if (x - x0) w0 = (w0 + (x - x0)) | 0x0007;
if (y - y0) h0 = (h0 + (y - y0)) | 0x0007;
/* clip */
if (draw_clipms(&x0, &y0, &w0, &h0)) { /* do not add if fully clipped */
/*sys_printf("-> [clipped]\n");*/
return;
}
/*sys_printf("-> %#04x,%#04x %#04x %#04x\n", x0, y0, w0, h0);*/
#ifdef GFXST
y0 += 8;
#endif
/* get to screen */
x0 -= DRAW_XYMAP_SCRLEFT;
y0 -= DRAW_XYMAP_SCRTOP;
/* add rectangle to the list */
ent_rects = rects_new(x0, y0, w0, h0, ent_rects);
}
/*
* Draw all entities onto the frame buffer.
*
* ASM 07a4
*
* NOTE This may need to be part of draw.c. Also needs better comments,
* NOTE and probably better rectangles management.
*/
void
ent_draw(void)
{
U8 i;
#ifdef ENABLE_CHEATS
static U8 ch3 = FALSE;
#endif
S16 dx, dy;
draw_tilesBank = map_tilesBank;
/* reset rectangles list */
rects_free(ent_rects);
ent_rects = NULL;
/*sys_printf("\n");*/
/*
* background loop : erase all entities that were visible
*/
for (i = 0; ent_ents[i].n != 0xff; i++) {
#ifdef ENABLE_CHEATS
if (ent_ents[i].prev_n && (ch3 || ent_ents[i].prev_s))
#else
if (ent_ents[i].prev_n && ent_ents[i].prev_s)
#endif
/* if entity was active, then erase it (redraw the map) */
draw_spriteBackground(ent_ents[i].prev_x, ent_ents[i].prev_y);
}
/*
* foreground loop : draw all entities that are visible
*/
for (i = 0; ent_ents[i].n != 0xff; i++) {
/*
* If entity is active now, draw the sprite. If entity was
* not active before, add a rectangle for the sprite.
*/
#ifdef ENABLE_CHEATS
if (ent_ents[i].n && (game_cheat3 || ent_ents[i].sprite))
#else
if (ent_ents[i].n && ent_ents[i].sprite)
#endif
/* If entitiy is active, draw the sprite. */
draw_sprite2(ent_ents[i].sprite,
ent_ents[i].x, ent_ents[i].y,
ent_ents[i].front);
}
/*
* rectangles loop : figure out which parts of the screen have been
* impacted and need to be refreshed, then save state
*/
for (i = 0; ent_ents[i].n != 0xff; i++) {
#ifdef ENABLE_CHEATS
if (ent_ents[i].prev_n && (ch3 || ent_ents[i].prev_s)) {
#else
if (ent_ents[i].prev_n && ent_ents[i].prev_s) {
#endif
/* (1) if entity was active and has been drawn ... */
#ifdef ENABLE_CHEATS
if (ent_ents[i].n && (game_cheat3 || ent_ents[i].sprite)) {
#else
if (ent_ents[i].n && ent_ents[i].sprite) {
#endif
/* (1.1) ... and is still active now and still needs to be drawn, */
/* then check if rectangles intersect */
dx = abs(ent_ents[i].x - ent_ents[i].prev_x);
dy = abs(ent_ents[i].y - ent_ents[i].prev_y);
if (dx < 0x20 && dy < 0x16) {
/* (1.1.1) if they do, then create one rectangle */
ent_addrect((ent_ents[i].prev_x < ent_ents[i].x)
? ent_ents[i].prev_x : ent_ents[i].x,
(ent_ents[i].prev_y < ent_ents[i].y)
? ent_ents[i].prev_y : ent_ents[i].y,
dx + 0x20, dy + 0x15);
}
else {
/* (1.1.2) else, create two rectangles */
ent_addrect(ent_ents[i].x, ent_ents[i].y, 0x20, 0x15);
ent_addrect(ent_ents[i].prev_x, ent_ents[i].prev_y, 0x20, 0x15);
}
}
else
/* (1.2) ... and is not active anymore or does not need to be drawn */
/* then create one single rectangle */
ent_addrect(ent_ents[i].prev_x, ent_ents[i].prev_y, 0x20, 0x15);
}
#ifdef ENABLE_CHEATS
else if (ent_ents[i].n && (game_cheat3 || ent_ents[i].sprite)) {
#else
else if (ent_ents[i].n && ent_ents[i].sprite) {
#endif
/* (2) if entity is active and needs to be drawn, */
/* then create one rectangle */
ent_addrect(ent_ents[i].x, ent_ents[i].y, 0x20, 0x15);
}
/* save state */
ent_ents[i].prev_x = ent_ents[i].x;
ent_ents[i].prev_y = ent_ents[i].y;
ent_ents[i].prev_n = ent_ents[i].n;
ent_ents[i].prev_s = ent_ents[i].sprite;
}
#ifdef ENABLE_CHEATS
ch3 = game_cheat3;
#endif
}
/*
* Clear entities previous state
*
*/
void
ent_clprev(void)
{
U8 i;
for (i = 0; ent_ents[i].n != 0xff; i++)
ent_ents[i].prev_n = 0;
}
/*
* Table containing entity action function pointers.
*/
void (*ent_actf[])(U8) = {
NULL, /* 00 - zero means that the slot is free */
e_rick_action, /* 01 - 12CA */
e_bullet_action, /* 02 - 1883 */
e_bomb_action, /* 03 - 18CA */
e_them_t1a_action, /* 04 - 2452 */
e_them_t1b_action, /* 05 - 21CA */
e_them_t2_action, /* 06 - 2718 */
e_them_t1a_action, /* 07 - 2452 */
e_them_t1b_action, /* 08 - 21CA */
e_them_t2_action, /* 09 - 2718 */
e_them_t1a_action, /* 0A - 2452 */
e_them_t1b_action, /* 0B - 21CA */
e_them_t2_action, /* 0C - 2718 */
e_them_t1a_action, /* 0D - 2452 */
e_them_t1b_action, /* 0E - 21CA */
e_them_t2_action, /* 0F - 2718 */
e_box_action, /* 10 - 245A */
e_box_action, /* 11 - 245A */
e_bonus_action, /* 12 - 242C */
e_bonus_action, /* 13 - 242C */
e_bonus_action, /* 14 - 242C */
e_bonus_action, /* 15 - 242C */
e_sbonus_start, /* 16 - 2182 */
e_sbonus_stop /* 17 - 2143 */
};
/*
* Run entities action function
*
*/
void
ent_action(void)
{
U8 i, k;
IFDEBUG_ENTS(
sys_printf("xrick/ents: --------- action ----------------\n");
for (i = 0; ent_ents[i].n != 0xff; i++)
if (ent_ents[i].n) {
sys_printf("xrick/ents: slot %#04x, entity %#04x", i, ent_ents[i].n);
sys_printf(" (%#06x, %#06x), sprite %#04x.\n",
ent_ents[i].x, ent_ents[i].y, ent_ents[i].sprite);
}
);
for (i = 0; ent_ents[i].n != 0xff; i++) {
if (ent_ents[i].n) {
k = ent_ents[i].n & 0x7f;
if (k == 0x47)
e_them_z_action(i);
else if (k >= 0x18)
e_them_t3_action(i);
else
ent_actf[k](i);
}
}
}
/* eof */

789
src/game.c Normal file
View File

@ -0,0 +1,789 @@
/*
* xrick/src/game.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <stdlib.h>
#include "system.h"
#include "config.h"
#include "game.h"
#include "draw.h"
#include "maps.h"
#include "ents.h"
#include "e_rick.h"
#include "e_sbonus.h"
#include "e_them.h"
#include "screens.h"
#include "rects.h"
#include "scroller.h"
#include "control.h"
#include "data.h"
#ifdef ENABLE_DEVTOOLS
#include "devtools.h"
#endif
/*
* local typedefs
*/
typedef enum {
#ifdef ENABLE_DEVTOOLS
DEVTOOLS,
#endif
XRICK,
INIT_GAME, INIT_BUFFER,
INTRO_MAIN, INTRO_MAP,
PAUSE_PRESSED1, PAUSE_PRESSED1B, PAUSED, PAUSE_PRESSED2,
PLAY0, PLAY1, PLAY2, PLAY3,
CHAIN_SUBMAP, CHAIN_MAP, CHAIN_END,
SCROLL_UP, SCROLL_DOWN,
RESTART, GAMEOVER, GETNAME, EXIT
} game_state_t;
/*
* global vars
*/
U8 game_period = 0;
U8 game_waitevt = FALSE;
rect_t *game_rects = NULL;
U8 game_lives = 0;
U8 game_bombs = 0;
U8 game_bullets = 0;
U32 game_score = 0;
U16 game_map = 0;
U16 game_submap = 0;
U8 game_dir = 0;
U8 game_chsm = FALSE;
U8 game_cheat1 = 0;
U8 game_cheat2 = 0;
U8 game_cheat3 = 0;
#ifdef GFXST
hscore_t game_hscores[8] = {
{ 8000, "SIMES@@@@@" },
{ 7000, "JAYNE@@@@@" },
{ 6000, "DANGERSTU@" },
{ 5000, "KEN@@@@@@@" },
{ 4000, "ROB@N@BOB@" },
{ 3000, "TELLY@@@@@" },
{ 2000, "NOBBY@@@@@" },
{ 1000, "JEZEBEL@@@" }
};
#endif
#ifdef GFXPC
hscore_t game_hscores[8] = {
{ 8000, "DANGERSTU@" },
{ 7000, "SIMES@@@@@" },
{ 6000, "KEN@T@ZEN@" },
{ 5000, "BOBBLE@@@@" },
{ 4000, "GREG@LAA@@" },
{ 3000, "TELLY@@@@@" },
{ 2000, "CHIGLET@@@" },
{ 1000, "ANDYSPLEEN" }
};
#endif
#ifdef ENABLE_SOUND
sound_t *WAV_GAMEOVER;
sound_t *WAV_SBONUS2;
sound_t *WAV_BULLET;
sound_t *WAV_BOMBSHHT;
sound_t *WAV_EXPLODE;
sound_t *WAV_STICK;
sound_t *WAV_WALK;
sound_t *WAV_CRAWL;
sound_t *WAV_JUMP;
sound_t *WAV_PAD;
sound_t *WAV_BOX;
sound_t *WAV_BONUS;
sound_t *WAV_SBONUS1;
sound_t *WAV_DIE;
sound_t *WAV_ENTITY[10];
#endif
/*
* local vars
*/
static U8 isave_frow;
static game_state_t game_state;
#ifdef ENABLE_SOUND
static sound_t *music_snd;
#endif
/*
* prototypes
*/
static void frame(void);
static void init(void);
static void play0(void);
static void play3(void);
static void restart(void);
static void isave(void);
static void irestore(void);
static void loaddata(void);
static void freedata(void);
/*
* Cheats
*/
#ifdef ENABLE_CHEATS
void
game_toggleCheat(U8 nbr)
{
if (game_state != INTRO_MAIN && game_state != INTRO_MAP &&
game_state != GAMEOVER && game_state != GETNAME &&
#ifdef ENABLE_DEVTOOLS
game_state != DEVTOOLS &&
#endif
game_state != XRICK && game_state != EXIT) {
switch (nbr) {
case 1:
game_cheat1 = ~game_cheat1;
game_lives = 6;
game_bombs = 6;
game_bullets = 6;
break;
case 2:
game_cheat2 = ~game_cheat2;
break;
case 3:
game_cheat3 = ~game_cheat3;
break;
}
draw_infos();
/* FIXME this should probably only raise a flag ... */
/* plus we only need to update INFORECT not the whole screen */
sysvid_update(&draw_SCREENRECT);
}
}
#endif
#ifdef ENABLE_SOUND
/*
* Music
*/
void
game_setmusic(char *name, U8 loop)
{
U8 channel;
if (music_snd)
game_stopmusic();
music_snd = syssnd_load(name);
if (music_snd)
{
music_snd->dispose = TRUE; /* music is always "fire and forget" */
channel = syssnd_play(music_snd, loop);
}
}
void
game_stopmusic(void)
{
syssnd_stopsound(music_snd);
music_snd = NULL;
}
#endif
/*
* Main loop
*/
void
game_run(void)
{
U32 tm, tmx;
loaddata(); /* load cached data */
game_period = sysarg_args_period ? sysarg_args_period : GAME_PERIOD;
tm = sys_gettime();
game_state = XRICK;
/* main loop */
while (game_state != EXIT) {
/* timer */
tmx = tm; tm = sys_gettime(); tmx = tm - tmx;
if (tmx < game_period) sys_sleep(game_period - tmx);
/* video */
/*DEBUG*//*game_rects=&draw_SCREENRECT;*//*DEBUG*/
sysvid_update(game_rects);
draw_STATUSRECT.next = NULL; /* FIXME freerects should handle this */
/* sound */
/*snd_mix();*/
/* events */
if (game_waitevt)
sysevt_wait(); /* wait for an event */
else
sysevt_poll(); /* process events (non-blocking) */
/* frame */
frame();
}
freedata(); /* free cached data */
}
/*
* Prepare frame
*
* This function loops forever: use 'return' when a frame is ready.
* When returning, game_rects must contain every parts of the buffer
* that have been modified.
*/
static void
frame(void)
{
while (1) {
switch (game_state) {
#ifdef ENABLE_DEVTOOLS
case DEVTOOLS:
switch (devtools_run()) {
case SCREEN_RUNNING:
return;
case SCREEN_DONE:
game_state = INIT_GAME;
break;
case SCREEN_EXIT:
game_state = EXIT;
return;
}
break;
#endif
case XRICK:
switch(screen_xrick()) {
case SCREEN_RUNNING:
return;
case SCREEN_DONE:
#ifdef ENABLE_DEVTOOLS
game_state = DEVTOOLS;
#else
game_state = INIT_GAME;
#endif
break;
case SCREEN_EXIT:
game_state = EXIT;
return;
}
break;
case INIT_GAME:
init();
game_state = INTRO_MAIN;
break;
case INTRO_MAIN:
switch (screen_introMain()) {
case SCREEN_RUNNING:
return;
case SCREEN_DONE:
game_state = INTRO_MAP;
break;
case SCREEN_EXIT:
game_state = EXIT;
return;
}
break;
case INTRO_MAP:
switch (screen_introMap()) {
case SCREEN_RUNNING:
return;
case SCREEN_DONE:
game_waitevt = FALSE;
game_state = INIT_BUFFER;
break;
case SCREEN_EXIT:
game_state = EXIT;
return;
}
break;
case INIT_BUFFER:
sysvid_clear(); /* clear buffer */
draw_map(); /* draw the map onto the buffer */
draw_drawStatus(); /* draw the status bar onto the buffer */
#ifdef ENABLE_CHEATS
draw_infos(); /* draw the info bar onto the buffer */
#endif
game_rects = &draw_SCREENRECT; /* request full buffer refresh */
game_state = PLAY0;
return;
case PAUSE_PRESSED1:
screen_pause(TRUE);
game_state = PAUSE_PRESSED1B;
break;
case PAUSE_PRESSED1B:
if (control_status & CONTROL_PAUSE)
return;
game_state = PAUSED;
break;
case PAUSED:
if (control_status & CONTROL_PAUSE)
game_state = PAUSE_PRESSED2;
if (control_status & CONTROL_EXIT)
game_state = EXIT;
return;
case PAUSE_PRESSED2:
if (!(control_status & CONTROL_PAUSE)) {
game_waitevt = FALSE;
screen_pause(FALSE);
#ifdef ENABLE_SOUND
syssnd_pause(FALSE, FALSE);
#endif
game_state = PLAY2;
}
return;
case PLAY0:
play0();
break;
case PLAY1:
if (control_status & CONTROL_PAUSE) {
#ifdef ENABLE_SOUND
syssnd_pause(TRUE, FALSE);
#endif
game_waitevt = TRUE;
game_state = PAUSE_PRESSED1;
}
else if (control_active == FALSE) {
#ifdef ENABLE_SOUND
syssnd_pause(TRUE, FALSE);
#endif
game_waitevt = TRUE;
screen_pause(TRUE);
game_state = PAUSED;
}
else
game_state = PLAY2;
break;
case PLAY2:
if E_RICK_STTST(E_RICK_STDEAD) { /* rick is dead */
if (game_cheat1 || --game_lives) {
game_state = RESTART;
} else {
game_state = GAMEOVER;
}
}
else if (game_chsm) /* request to chain to next submap */
game_state = CHAIN_SUBMAP;
else
game_state = PLAY3;
break;
case PLAY3:
play3();
return;
case CHAIN_SUBMAP:
if (map_chain())
game_state = CHAIN_END;
else {
game_bullets = 0x06;
game_bombs = 0x06;
game_map++;
if (game_map == 0x04) {
/* reached end of game */
/* FIXME @292?*/
}
game_state = CHAIN_MAP;
}
break;
case CHAIN_MAP: /* CHAIN MAP */
switch (screen_introMap()) {
case SCREEN_RUNNING:
return;
case SCREEN_DONE:
if (game_map >= 0x04) { /* reached end of game */
sysarg_args_map = 0;
sysarg_args_submap = 0;
game_state = GAMEOVER;
}
else { /* initialize game */
ent_ents[1].x = map_maps[game_map].x;
ent_ents[1].y = map_maps[game_map].y;
map_frow = (U8)map_maps[game_map].row;
game_submap = map_maps[game_map].submap;
game_state = CHAIN_END;
}
break;
case SCREEN_EXIT:
game_state = EXIT;
return;
}
break;
case CHAIN_END:
map_init(); /* initialize the map */
isave(); /* save data in case of a restart */
ent_clprev(); /* cleanup entities */
draw_map(); /* draw the map onto the buffer */
draw_drawStatus(); /* draw the status bar onto the buffer */
game_rects = &draw_SCREENRECT; /* request full screen refresh */
game_state = PLAY3;
return;
case SCROLL_UP:
switch (scroll_up()) {
case SCROLL_RUNNING:
return;
case SCROLL_DONE:
game_state = PLAY0;
break;
}
break;
case SCROLL_DOWN:
switch (scroll_down()) {
case SCROLL_RUNNING:
return;
case SCROLL_DONE:
game_state = PLAY0;
break;
}
break;
case RESTART:
restart();
game_state = PLAY0;
return;
case GAMEOVER:
switch (screen_gameover()) {
case SCREEN_RUNNING:
return;
case SCREEN_DONE:
game_state = GETNAME;
break;
case SCREEN_EXIT:
game_state = EXIT;
break;
}
break;
case GETNAME:
switch (screen_getname()) {
case SCREEN_RUNNING:
return;
case SCREEN_DONE:
game_state = INIT_GAME;
return;
case SCREEN_EXIT:
game_state = EXIT;
break;
}
break;
case EXIT:
return;
}
}
}
/*
* Initialize the game
*/
static void
init(void)
{
U8 i;
E_RICK_STRST(0xff);
game_lives = 6;
game_bombs = 6;
game_bullets = 6;
game_score = 0;
game_map = sysarg_args_map;
if (sysarg_args_submap == 0) {
game_submap = map_maps[game_map].submap;
map_frow = (U8)map_maps[game_map].row;
}
else {
/* dirty hack to determine frow */
game_submap = sysarg_args_submap;
i = 0;
while (i < MAP_NBR_CONNECT &&
(map_connect[i].submap != game_submap ||
map_connect[i].dir != RIGHT))
i++;
map_frow = map_connect[i].rowin - 0x10;
ent_ents[1].y = 0x10 << 3;
}
ent_ents[1].x = map_maps[game_map].x;
ent_ents[1].y = map_maps[game_map].y;
ent_ents[1].w = 0x18;
ent_ents[1].h = 0x15;
ent_ents[1].n = 0x01;
ent_ents[1].sprite = 0x01;
ent_ents[1].front = FALSE;
ent_ents[ENT_ENTSNUM].n = 0xFF;
map_resetMarks();
map_init();
isave();
}
/*
* play0
*
*/
static void
play0(void)
{
if (control_status & CONTROL_END) { /* request to end the game */
game_state = GAMEOVER;
return;
}
if (control_last == CONTROL_EXIT) { /* request to exit the game */
game_state = EXIT;
return;
}
ent_action(); /* run entities */
e_them_rndseed++; /* (0270) */
game_state = PLAY1;
}
/*
* play3
*
*/
static void
play3(void)
{
static rect_t *r;
draw_clearStatus(); /* clear the status bar */
ent_draw(); /* draw all entities onto the buffer */
/* sound */
draw_drawStatus(); /* draw the status bar onto the buffer*/
r = &draw_STATUSRECT; r->next = ent_rects; /* refresh status bar too */
game_rects = r; /* take care to cleanup draw_STATUSRECT->next later! */
if (!E_RICK_STTST(E_RICK_STZOMBIE)) { /* need to scroll ? */
if (ent_ents[1].y >= 0xCC) {
game_state = SCROLL_UP;
return;
}
if (ent_ents[1].y <= 0x60) {
game_state = SCROLL_DOWN;
return;
}
}
game_state = PLAY0;
}
/*
* restart
*
*/
static void
restart(void)
{
E_RICK_STRST(E_RICK_STDEAD|E_RICK_STZOMBIE);
game_bullets = 6;
game_bombs = 6;
ent_ents[1].n = 1;
irestore();
map_init();
isave();
ent_clprev();
draw_map();
draw_drawStatus();
game_rects = &draw_SCREENRECT;
}
/*
* isave (0bbb)
*
*/
static void
isave(void)
{
e_rick_save();
isave_frow = map_frow;
}
/*
* irestore (0bdc)
*
*/
static void
irestore(void)
{
e_rick_restore();
map_frow = isave_frow;
}
/*
*
*/
static void
loaddata()
{
#ifdef ENABLE_SOUND
/*
* Cache sounds
*
* tune[0-5].wav not cached
*/
WAV_GAMEOVER = syssnd_load("sounds/gameover.wav");
WAV_SBONUS2 = syssnd_load("sounds/sbonus2.wav");
WAV_BULLET = syssnd_load("sounds/bullet.wav");
WAV_BOMBSHHT = syssnd_load("sounds/bombshht.wav");
WAV_EXPLODE = syssnd_load("sounds/explode.wav");
WAV_STICK = syssnd_load("sounds/stick.wav");
WAV_WALK = syssnd_load("sounds/walk.wav");
WAV_CRAWL = syssnd_load("sounds/crawl.wav");
WAV_JUMP = syssnd_load("sounds/jump.wav");
WAV_PAD = syssnd_load("sounds/pad.wav");
WAV_BOX = syssnd_load("sounds/box.wav");
WAV_BONUS = syssnd_load("sounds/bonus.wav");
WAV_SBONUS1 = syssnd_load("sounds/sbonus1.wav");
WAV_DIE = syssnd_load("sounds/die.wav");
WAV_ENTITY[0] = syssnd_load("sounds/ent0.wav");
WAV_ENTITY[1] = syssnd_load("sounds/ent1.wav");
WAV_ENTITY[2] = syssnd_load("sounds/ent2.wav");
WAV_ENTITY[3] = syssnd_load("sounds/ent3.wav");
WAV_ENTITY[4] = syssnd_load("sounds/ent4.wav");
WAV_ENTITY[5] = syssnd_load("sounds/ent5.wav");
WAV_ENTITY[6] = syssnd_load("sounds/ent6.wav");
WAV_ENTITY[7] = syssnd_load("sounds/ent7.wav");
WAV_ENTITY[8] = syssnd_load("sounds/ent8.wav");
#endif
}
/*
*
*/
static void
freedata()
{
#ifdef ENABLE_SOUND
syssnd_stopall();
syssnd_free(WAV_GAMEOVER);
syssnd_free(WAV_SBONUS2);
syssnd_free(WAV_BULLET);
syssnd_free(WAV_BOMBSHHT);
syssnd_free(WAV_EXPLODE);
syssnd_free(WAV_STICK);
syssnd_free(WAV_WALK);
syssnd_free(WAV_CRAWL);
syssnd_free(WAV_JUMP);
syssnd_free(WAV_PAD);
syssnd_free(WAV_BOX);
syssnd_free(WAV_BONUS);
syssnd_free(WAV_SBONUS1);
syssnd_free(WAV_DIE);
syssnd_free(WAV_ENTITY[0]);
syssnd_free(WAV_ENTITY[1]);
syssnd_free(WAV_ENTITY[2]);
syssnd_free(WAV_ENTITY[3]);
syssnd_free(WAV_ENTITY[4]);
syssnd_free(WAV_ENTITY[5]);
syssnd_free(WAV_ENTITY[6]);
syssnd_free(WAV_ENTITY[7]);
syssnd_free(WAV_ENTITY[8]);
#endif
}
/* eof */

79
src/img_icon.e Normal file
View File

@ -0,0 +1,79 @@
static U8 IMG_ICON_PIXELS[] = {
0,0,0,0,0,0,0,0,0,
211,108,211,108,52,52,52,52,52,52,52,52,52,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,174,
92,15,188,130,130,121,148,197,197,197,148,148,177,105,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,92,
12,104,192,143,195,56,7,72,72,72,7,7,85,14,105,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,122,32,
186,7,7,104,143,195,65,7,186,7,104,56,195,51,174,52,
0,0,0,0,0,0,0,0,0,0,0,0,0,105,38,115,
134,149,149,149,13,13,13,149,166,83,31,120,13,72,168,14,
105,0,0,0,0,0,0,0,0,105,174,174,52,77,72,69,
126,21,126,126,21,21,21,126,159,195,84,139,21,12,30,122,
52,174,174,174,105,0,0,0,105,77,201,193,193,193,186,7,
104,42,42,104,104,104,42,104,104,78,42,104,104,186,193,193,
24,24,24,30,5,105,0,0,9,181,51,188,188,188,20,20,
73,73,73,73,73,73,73,73,20,73,20,20,20,73,20,20,
32,32,32,163,117,9,0,0,0,9,14,14,14,52,164,72,
72,72,72,72,72,72,72,164,12,72,164,72,72,164,164,72,
174,174,52,0,9,0,0,0,0,0,0,0,0,52,135,196,
23,193,6,23,23,23,23,23,202,193,23,23,23,23,196,135,
14,0,0,0,0,0,0,0,0,0,0,0,0,52,137,203,
151,6,127,84,98,43,19,84,159,46,127,127,127,127,162,128,
9,0,0,0,0,0,0,0,0,0,0,0,0,52,151,84,
84,84,151,151,165,170,183,208,139,126,7,7,7,7,182,174,
0,0,0,0,0,0,0,0,0,0,0,0,0,52,90,90,
90,74,88,84,165,1,93,116,91,132,161,62,96,17,204,175,
0,0,0,0,0,0,0,0,0,0,0,0,122,181,72,2,
74,157,54,88,53,176,152,50,4,140,67,133,33,95,34,0,
0,0,0,0,0,0,0,0,0,0,0,14,5,72,2,192,
143,111,74,12,87,145,11,35,94,165,84,84,84,7,148,58,
0,0,0,0,0,0,0,0,0,0,0,52,197,72,104,195,
195,65,193,72,98,137,142,158,138,142,84,84,84,39,59,52,
0,0,0,0,0,0,0,0,0,0,105,181,163,72,193,83,
195,143,192,101,44,68,87,151,84,84,84,208,114,86,178,52,
0,0,0,0,0,0,0,0,0,118,52,164,72,72,184,112,
111,195,56,104,72,69,21,84,151,151,151,139,21,12,197,52,
0,0,0,0,0,0,0,0,0,118,174,72,72,12,72,184,
193,18,171,104,72,22,114,180,129,145,110,53,81,181,122,0,
0,0,0,0,0,0,0,0,0,89,52,12,12,72,164,12,
12,193,7,7,90,150,84,87,141,136,131,28,122,52,0,0,
0,0,0,0,0,0,0,0,0,89,174,72,72,72,72,72,
164,54,57,7,208,84,151,151,159,186,7,74,164,117,0,0,
0,0,0,0,0,0,0,0,0,118,14,154,115,113,92,92,
92,72,54,153,84,84,84,84,88,2,2,190,30,30,27,0,
0,0,0,0,0,0,0,0,0,187,52,24,149,126,141,82,
179,72,184,107,172,47,47,23,22,72,80,66,70,30,197,160,
211,52,0,0,0,0,0,0,0,0,187,177,85,134,21,21,
21,164,74,104,143,13,126,72,30,191,35,152,11,211,102,176,
124,160,14,0,0,0,0,0,0,0,0,118,17,80,71,71,
71,92,200,10,41,97,205,12,209,165,125,35,1,173,11,35,
165,124,75,105,0,0,0,0,0,0,0,0,118,52,52,52,
108,108,173,176,11,11,165,72,109,165,11,94,123,64,35,35,
11,165,3,174,0,0,0,0,0,0,0,0,0,0,14,160,
124,64,183,26,170,94,11,14,102,165,165,165,94,35,100,106,
124,191,14,0,0,0,0,0,0,0,0,0,0,105,206,36,
11,183,147,76,152,49,3,105,105,167,11,165,165,189,199,165,
3,211,0,0,0,0,0,0,0,0,0,0,52,211,124,165,
156,26,103,123,48,174,52,0,118,52,167,165,11,165,165,191,
52,0,0,0,0,0,0,0,0,0,0,211,211,155,11,125,
123,35,125,165,52,58,0,0,0,89,52,3,124,165,167,14,
0,0,0,0,0,0,0,0,0,0,0,0,70,167,165,199,
45,103,16,125,75,48,58,0,0,0,89,14,191,191,52,58,
0,0,0,0,0,0,0,0,0,0,0,0,0,14,11,11,
1,147,103,123,11,167,52,0,0,0,0,194,14,52,194,0,
0,0,0,0,0,0,0,};
static img_color_t IMG_ICON_COLORS[] = {
{0,0,0,0},{90,94,92,0},{94,46,4,0},{46,50,44,0},{138,142,140,0},{50,34,20,0},{178,98,36,0},{142,70,4,0},{198,122,100,0},{0,0,0,0},{98,74,44,0},{74,74,76,0},{74,38,4,0},{198,106,44,0},{30,38,28,0},{74,50,20,0},{114,118,116,0},{50,42,28,0},{166,82,4,0},{214,142,116,0},{118,58,4,0},{178,110,108,0},{146,82,44,0},{222,130,92,0},{134,70,4,0},{138,94,84,0},{174,178,172,0},{42,38,20,0},{74,70,52,0},{0,0,0,0},{66,34,4,0},{190,102,44,0},{98,58,12,0},{174,142,132,0},{38,30,20,0},{102,106,100,0},{58,62,60,0},{82,86,84,0},{66,42,12,0},{170,98,76,0},{202,114,68,0},{126,86,44,0},{150,78,12,0},{202,130,108,0},{90,50,20,0},{130,130,132,0},{154,82,36,0},{238,138,100,0},{42,46,44,0},{54,58,52,0},{154,158,156,0},{58,34,12,0},{30,34,28,0},{110,86,76,0},{86,42,4,0},{38,38,28,0},{178,90,4,0},{130,66,4,0},{18,22,20,0},{102,66,52,0},{0,0,0,0},{122,94,84,0},{158,146,132,0},{174,98,52,0},{78,82,76,0},{210,106,4,0},{58,42,28,0},{198,170,156,0},{190,114,92,0},{122,70,52,0},{42,42,36,0},{86,62,60,0},{70,34,4,0},{114,58,4,0},{110,54,4,0},{54,54,52,0},{146,150,148,0},{50,38,20,0},{150,74,4,0},{214,122,68,0},{78,46,12,0},{74,58,52,0},{50,46,36,0},{174,86,4,0},{246,142,100,0},{122,66,4,0},{150,90,76,0},{230,134,100,0},{166,94,52,0},{18,18,20,0},{106,58,20,0},{170,154,148,0},{46,34,20,0},{110,114,108,0},{90,90,92,0},{66,46,20,0},{142,130,116,0},{118,86,68,0},{190,118,92,0},{0,0,0,0},{98,102,100,0},{102,50,4,0},{50,54,52,0},{142,146,140,0},{146,74,4,0},{26,30,28,0},{74,78,76,0},{82,42,4,0},{34,38,28,0},{70,54,36,0},{146,118,100,0},{170,86,4,0},{126,62,4,0},{142,82,68,0},{226,134,100,0},{134,70,20,0},{190,174,164,0},{46,38,20,0},{14,18,12,0},{62,38,4,0},{194,106,44,0},{102,62,20,0},{38,34,28,0},{106,110,108,0},{66,66,68,0},{86,90,84,0},{174,106,100,0},{214,118,68,0},{126,82,76,0},{158,106,92,0},{118,70,20,0},{110,102,84,0},{150,138,140,0},{186,158,148,0},{158,90,52,0},{162,98,92,0},{86,70,60,0},{198,118,100,0},{210,130,100,0},{214,126,100,0},{122,122,124,0},{134,86,84,0},{206,126,100,0},{218,110,4,0},{130,70,36,0},{118,90,84,0},{150,86,52,0},{178,182,180,0},{86,54,20,0},{158,86,44,0},{178,102,60,0},{250,146,108,0},{94,98,92,0},{98,50,4,0},{122,62,4,0},{62,66,60,0},{134,134,132,0},{90,46,4,0},{214,134,100,0},{198,110,52,0},{38,42,36,0},{170,158,140,0},{170,102,76,0},{58,38,12,0},{70,38,4,0},{70,70,68,0},{166,86,20,0},{50,50,52,0},{54,34,12,0},{26,26,28,0},{106,106,108,0},{154,78,4,0},{242,138,92,0},{58,58,60,0},{34,34,28,0},{10,10,12,0},{82,82,84,0},{46,42,28,0},{90,62,52,0},{54,46,44,0},{194,118,100,0},{42,34,20,0},{90,54,12,0},{142,142,140,0},{78,38,4,0},{54,42,28,0},{138,70,4,0},{14,14,12,0},{102,58,12,0},{86,86,84,0},{70,42,12,0},{46,46,44,0},{182,90,4,0},{134,66,4,0},{22,22,20,0},{214,106,4,0},{194,114,92,0},{54,38,20,0},{0,0,0,0},{78,78,76,0},{74,54,36,0},{66,38,4,0},{178,98,44,0},{222,130,100,0},{42,38,28,0},{110,86,84,0},{38,38,36,0},{174,98,60,0},{246,142,108,0},{66,46,28,0},{146,74,12,0},{34,38,36,0},{194,106,52,0},{154,78,12,0},{242,138,100,0},{34,34,36,0},};
static img_t IMG_ICON_OBJECT = {
32, 32,
216,
IMG_ICON_COLORS,
IMG_ICON_PIXELS
};
img_t *IMG_ICON = &IMG_ICON_OBJECT;

4015
src/img_splash.e Normal file

File diff suppressed because it is too large Load Diff

216
src/maps.c Normal file
View File

@ -0,0 +1,216 @@
/*
* xrick/src/maps.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
/*
* NOTES
*
* A map is composed of submaps, which in turn are composed of rows of
* 0x20 tiles. map_map contains the tiles for the current portion of the
* current submap, i.e. a little bit more than what appear on the screen,
* but not the whole submap.
*
* map_frow is map_map top row within the submap.
*
* Submaps are stored as arrays of blocks, each block being a 4x4 tile
* array. map_submaps[].bnum points to the first block of the array.
*
* Before a submap can be played, it needs to be expanded from blocks
* to map_map.
*/
#include "system.h"
#include "game.h"
#include "maps.h"
#include "debug.h"
#include "ents.h"
#include "draw.h"
#include "screens.h"
#include "e_sbonus.h"
/*
* global vars
*/
U8 map_map[0x2C][0x20];
U8 map_eflg[0x100];
U8 map_frow;
U8 map_tilesBank;
/*
* prototypes
*/
static void map_eflg_expand(U8);
/*
* Fill in map_map with tile numbers by expanding blocks.
*
* add map_submaps[].bnum to map_frow to find out where to start from.
* We need to /4 map_frow to convert from tile rows to block rows, then
* we need to *8 to convert from block rows to block numbers (there
* are 8 blocks per block row). This is achieved by *2 then &0xfff8.
*/
void
map_expand(void)
{
U8 i, j, k, l;
U8 row, col;
U16 pbnum;
pbnum = map_submaps[game_submap].bnum + ((2 * map_frow) & 0xfff8);
row = col = 0;
for (i = 0; i < 0x0b; i++) { /* 0x0b rows of blocks */
for (j = 0; j < 0x08; j++) { /* 0x08 blocks per row */
for (k = 0, l = 0; k < 0x04; k++) { /* expand one block */
map_map[row][col++] = map_blocks[map_bnums[pbnum]][l++];
map_map[row][col++] = map_blocks[map_bnums[pbnum]][l++];
map_map[row][col++] = map_blocks[map_bnums[pbnum]][l++];
map_map[row][col] = map_blocks[map_bnums[pbnum]][l++];
row += 1; col -= 3;
}
row -= 4; col += 4;
pbnum++;
}
row += 4; col = 0;
}
}
/*
* Initialize a new submap
*
* ASM 0cc3
*/
void
map_init(void)
{
/*sys_printf("xrick/map_init: map=%#04x submap=%#04x\n", g_map, game_submap);*/
#ifdef GFXPC
draw_filter = 0xffff;
map_tilesBank = (map_submaps[game_submap].page == 1) ? 3 : 2;
#endif
#ifdef GFXST
map_tilesBank = (map_submaps[game_submap].page == 1) ? 2 : 1;
#endif
map_eflg_expand((map_submaps[game_submap].page == 1) ? 0x10 : 0x00);
map_expand();
ent_reset();
ent_actvis(map_frow + MAP_ROW_SCRTOP, map_frow + MAP_ROW_SCRBOT);
ent_actvis(map_frow + MAP_ROW_HTTOP, map_frow + MAP_ROW_HTBOT);
ent_actvis(map_frow + MAP_ROW_HBTOP, map_frow + MAP_ROW_HBBOT);
}
/*
* Expand entity flags for this map
*
* ASM 1117
*/
void
map_eflg_expand(U8 offs)
{
U8 i, j, k;
for (i = 0, k = 0; i < 0x10; i++) {
j = map_eflg_c[offs + i++];
while (j--) map_eflg[k++] = map_eflg_c[offs + i];
}
}
/*
* Chain (sub)maps
*
* ASM 0c08
* return: TRUE/next submap OK, FALSE/map finished
*/
U8
map_chain(void)
{
U16 c, t;
game_chsm = 0;
e_sbonus_counting = FALSE;
/* find connection */
c = map_submaps[game_submap].connect;
t = 3;
IFDEBUG_MAPS(
sys_printf("xrick/maps: chain submap=%#04x frow=%#04x .connect=%#04x %s\n",
game_submap, map_frow, c,
(game_dir == LEFT ? "-> left" : "-> right"));
);
/*
* look for the first connector with compatible row number. if none
* found, then panic
*/
for (c = map_submaps[game_submap].connect; ; c++) {
if (map_connect[c].dir == 0xff)
sys_panic("(map_chain) can not find connector\n");
if (map_connect[c].dir != game_dir) continue;
t = (ent_ents[1].y >> 3) + map_frow - map_connect[c].rowout;
if (t < 3) break;
}
/* got it */
IFDEBUG_MAPS(
sys_printf("xrick/maps: chain frow=%#04x y=%#06x\n",
map_frow, ent_ents[1].y);
sys_printf("xrick/maps: chain connect=%#04x rowout=%#04x - ",
c, map_connect[c].rowout);
);
if (map_connect[c].submap == 0xff) {
/* no next submap - request next map */
IFDEBUG_MAPS(
sys_printf("chain to next map\n");
);
return FALSE;
}
else {
/* next submap */
IFDEBUG_MAPS(
sys_printf("chain to submap=%#04x rowin=%#04x\n",
map_connect[c].submap, map_connect[c].rowin);
);
map_frow = map_frow - map_connect[c].rowout + map_connect[c].rowin;
game_submap = map_connect[c].submap;
IFDEBUG_MAPS(
sys_printf("xrick/maps: chain frow=%#04x\n",
map_frow);
);
return TRUE;
}
}
/*
* Reset all marks, i.e. make them all active again.
*
* ASM 0025
*
*/
void
map_resetMarks(void)
{
U16 i;
for (i = 0; i < MAP_NBR_MARKS; i++)
map_marks[i].ent &= ~MAP_MARK_NACT;
}
/* eof */

51
src/rects.c Normal file
View File

@ -0,0 +1,51 @@
/*
* xrick/src/rects.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <stdlib.h> /* malloc */
#include "system.h"
#include "rects.h"
/*
* Free a list of rectangles and set the pointer to NULL.
*
* p: rectangle list CHANGED to NULL
*/
void
rects_free(rect_t *r) {
if (r) {
rects_free(r->next);
free(r);
}
}
/*
* Add a rectangle to a list of rectangles
*/
rect_t *
rects_new(U16 x, U16 y, U16 width, U16 height, rect_t *next)
{
rect_t *r;
r = malloc(sizeof *r);
r->x = x;
r->y = y;
r->width = width;
r->height = height;
r->next = next;
return r;
}
/* eof */

15
src/resource.h Normal file
View File

@ -0,0 +1,15 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by xrick.rc
//
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

101
src/scr_gameover.c Normal file
View File

@ -0,0 +1,101 @@
/*
* xrick/src/scr_gameover.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "stddef.h" /* NULL */
#include "system.h"
#include "game.h"
#include "screens.h"
#include "draw.h"
#include "control.h"
/*
* Display the game over screen
*
* return: SCREEN_RUNNING, SCREEN_DONE, SCREEN_EXIT
*/
U8
screen_gameover(void)
{
static U8 seq = 0;
static U8 period = 0;
#ifdef GFXST
static U32 tm = 0;
#endif
#ifdef ENABLE_SOUND
static sound_t *snd;
static U8 chan;
#endif
if (seq == 0) {
draw_tilesBank = 0;
seq = 1;
period = game_period; /* save period, */
game_period = 50; /* and use our own */
#ifdef ENABLE_SOUND
game_setmusic("sounds/gameover.wav", 1);
#endif
}
switch (seq) {
case 1: /* display banner */
#ifdef GFXST
sysvid_clear();
tm = sys_gettime();
#endif
draw_tllst = screen_gameovertxt;
draw_setfb(120, 80);
#ifdef GFXPC
draw_filter = 0xAAAA;
#endif
draw_tilesList();
game_rects = &draw_SCREENRECT;
seq = 2;
break;
case 2: /* wait for key pressed */
if (control_status & CONTROL_FIRE)
seq = 3;
#ifdef GFXST
else if (sys_gettime() - tm > SCREEN_TIMEOUT)
seq = 4;
#endif
else
sys_sleep(50);
break;
case 3: /* wait for key released */
if (!(control_status & CONTROL_FIRE))
seq = 4;
else
sys_sleep(50);
break;
}
if (control_status & CONTROL_EXIT) /* check for exit request */
return SCREEN_EXIT;
if (seq == 4) { /* we're done */
sysvid_clear();
seq = 0;
game_period = period;
return SCREEN_DONE;
}
return SCREEN_RUNNING;
}
/* eof */

275
src/scr_getname.c Normal file
View File

@ -0,0 +1,275 @@
/*
* xrick/src/scr_getname.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "system.h"
#include "game.h"
#include "screens.h"
#include "draw.h"
#include "control.h"
/*
* local vars
*/
static U8 seq = 0;
static U8 x, y, p;
static U8 name[10];
#define TILE_POINTER '\072'
#define TILE_CURSOR '\073'
#define TOPLEFT_X 116
#define TOPLEFT_Y 64
#define NAMEPOS_X 120
#define NAMEPOS_Y 160
#define AUTOREPEAT_TMOUT 100
/*
* prototypes
*/
static void pointer_show(U8);
static void name_update(void);
static void name_draw(void);
/*
* Get name
*
* return: 0 while running, 1 when finished.
*/
U8
screen_getname(void)
{
static U32 tm = 0;
U8 i, j;
if (seq == 0) {
/* figure out if this is a high score */
if (game_score < game_hscores[7].score)
return SCREEN_DONE;
/* prepare */
draw_tilesBank = 0;
#ifdef GFXPC
draw_filter = 0xffff;
#endif
for (i = 0; i < 10; i++)
name[i] = '@';
x = y = p = 0;
game_rects = &draw_SCREENRECT;
seq = 1;
}
switch (seq) {
case 1: /* prepare screen */
sysvid_clear();
#ifdef GFXPC
draw_setfb(32, 8);
draw_filter = 0xaaaa; /* red */
draw_tilesListImm(screen_congrats);
#endif
draw_setfb(76, 40);
#ifdef GFXPC
draw_filter = 0xffff; /* yellow */
#endif
draw_tilesListImm((U8 *)"PLEASE@ENTER@YOUR@NAME\376");
#ifdef GFXPC
draw_filter = 0x5555; /* green */
#endif
for (i = 0; i < 6; i++)
for (j = 0; j < 4; j++) {
draw_setfb(TOPLEFT_X + i * 8 * 2, TOPLEFT_Y + j * 8 * 2);
draw_tile('A' + i + j * 6);
}
draw_setfb(TOPLEFT_X, TOPLEFT_Y + 64);
#ifdef GFXST
draw_tilesListImm((U8 *)"Y@Z@.@@@\074\373\374\375\376");
#endif
#ifdef GFXPC
draw_tilesListImm((U8 *)"Y@Z@.@@@\074@\075@\376");
#endif
name_draw();
pointer_show(TRUE);
seq = 2;
break;
case 2: /* wait for key pressed */
if (control_status & CONTROL_FIRE)
seq = 3;
if (control_status & CONTROL_UP) {
if (y > 0) {
pointer_show(FALSE);
y--;
pointer_show(TRUE);
tm = sys_gettime();
}
seq = 4;
}
if (control_status & CONTROL_DOWN) {
if (y < 4) {
pointer_show(FALSE);
y++;
pointer_show(TRUE);
tm = sys_gettime();
}
seq = 5;
}
if (control_status & CONTROL_LEFT) {
if (x > 0) {
pointer_show(FALSE);
x--;
pointer_show(TRUE);
tm = sys_gettime();
}
seq = 6;
}
if (control_status & CONTROL_RIGHT) {
if (x < 5) {
pointer_show(FALSE);
x++;
pointer_show(TRUE);
tm = sys_gettime();
}
seq = 7;
}
if (seq == 2)
sys_sleep(50);
break;
case 3: /* wait for FIRE released */
if (!(control_status & CONTROL_FIRE)) {
if (x == 5 && y == 4) { /* end */
i = 0;
while (game_score < game_hscores[i].score)
i++;
j = 7;
while (j > i) {
game_hscores[j].score = game_hscores[j - 1].score;
for (x = 0; x < 10; x++)
game_hscores[j].name[x] = game_hscores[j - 1].name[x];
j--;
}
game_hscores[i].score = game_score;
for (x = 0; x < 10; x++)
game_hscores[i].name[x] = name[x];
seq = 99;
}
else {
name_update();
name_draw();
seq = 2;
}
}
else
sys_sleep(50);
break;
case 4: /* wait for UP released */
if (!(control_status & CONTROL_UP) ||
sys_gettime() - tm > AUTOREPEAT_TMOUT)
seq = 2;
else
sys_sleep(50);
break;
case 5: /* wait for DOWN released */
if (!(control_status & CONTROL_DOWN) ||
sys_gettime() - tm > AUTOREPEAT_TMOUT)
seq = 2;
else
sys_sleep(50);
break;
case 6: /* wait for LEFT released */
if (!(control_status & CONTROL_LEFT) ||
sys_gettime() - tm > AUTOREPEAT_TMOUT)
seq = 2;
else
sys_sleep(50);
break;
case 7: /* wait for RIGHT released */
if (!(control_status & CONTROL_RIGHT) ||
sys_gettime() - tm > AUTOREPEAT_TMOUT)
seq = 2;
else
sys_sleep(50);
break;
}
if (control_status & CONTROL_EXIT) /* check for exit request */
return SCREEN_EXIT;
if (seq == 99) { /* seq 99, we're done */
sysvid_clear();
seq = 0;
return SCREEN_DONE;
}
else
return SCREEN_RUNNING;
}
static void
pointer_show(U8 show)
{
draw_setfb(TOPLEFT_X + x * 8 * 2, TOPLEFT_Y + y * 8 * 2 + 8);
#ifdef GFXPC
draw_filter = 0xaaaa; /* red */
#endif
draw_tile((show == TRUE)?TILE_POINTER:'@');
}
static void
name_update(void)
{
U8 i;
i = x + y * 6;
if (i < 26 && p < 10)
name[p++] = 'A' + i;
if (i == 26 && p < 10)
name[p++] = '.';
if (i == 27 && p < 10)
name[p++] = '@';
if (i == 28 && p > 0) {
p--;
}
}
static void
name_draw(void)
{
U8 i;
draw_setfb(NAMEPOS_X, NAMEPOS_Y);
#ifdef GFXPC
draw_filter = 0xaaaa; /* red */
#endif
for (i = 0; i < p; i++)
draw_tile(name[i]);
for (i = p; i < 10; i++)
draw_tile(TILE_CURSOR);
#ifdef GFXST
draw_setfb(NAMEPOS_X, NAMEPOS_Y + 8);
for (i = 0; i < 10; i++)
draw_tile('@');
draw_setfb(NAMEPOS_X + 8 * (p < 9 ? p : 9), NAMEPOS_Y + 8);
draw_tile(TILE_POINTER);
#endif
}
/* eof */

164
src/scr_imain.c Normal file
View File

@ -0,0 +1,164 @@
/*
* xrick/src/scr_imain.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <stdio.h> /* sprintf */
#include "system.h"
#include "game.h"
#include "screens.h"
#include "draw.h"
#include "pics.h"
#include "control.h"
/*
* Main introduction
*
* return: SCREEN_RUNNING, SCREEN_DONE, SCREEN_EXIT
*/
U8
screen_introMain(void)
{
static U8 seq = 0;
static U8 seen = 0;
static U8 first = TRUE;
static U8 period = 0;
static U32 tm = 0;
U8 i, s[32];
if (seq == 0) {
draw_tilesBank = 0;
if (first == TRUE)
seq = 1;
else
seq = 4;
period = game_period;
game_period = 50;
game_rects = &draw_SCREENRECT;
#ifdef ENABLE_SOUND
game_setmusic("sounds/tune5.wav", -1);
#endif
}
switch (seq) {
case 1: /* dispay hall of fame */
sysvid_clear();
tm = sys_gettime();
#ifdef GFXPC
/* Rick Dangerous title */
draw_tllst = (U8 *)screen_imainrdt;
draw_setfb(32, 16);
draw_filter = 0xaaaa;
draw_tilesList();
/* Core Design copyright + press space to start */
draw_tllst = (U8 *)screen_imaincdc;
draw_setfb(64, 80);
draw_filter = 0x5555;
draw_tilesList();
#endif
#ifdef GFXST
draw_pic(0, 0, 0x140, 0xc8, pic_splash);
#endif
seq = 2;
break;
case 2: /* wait for key pressed or timeout */
if (control_status & CONTROL_FIRE)
seq = 3;
else if (sys_gettime() - tm > SCREEN_TIMEOUT) {
seen++;
seq = 4;
}
break;
case 3: /* wait for key released */
if (!(control_status & CONTROL_FIRE)) {
if (seen++ == 0)
seq = 4;
else
seq = 7;
}
break;
case 4: /* display Rick Dangerous title and Core Design copyright */
sysvid_clear();
tm = sys_gettime();
/* hall of fame title */
#ifdef GFXPC
draw_tllst = (U8 *)screen_imainhoft;
draw_setfb(32, 0);
draw_filter = 0xaaaa;
draw_tilesList();
#endif
#ifdef GFXST
draw_pic(0, 0, 0x140, 0x20, pic_haf);
#endif
/* hall of fame content */
draw_setfb(56, 40);
#ifdef GFXPC
draw_filter = 0x5555;
#endif
for (i = 0; i < 8; i++) {
sprintf((char *)s, "%06d@@@....@@@%s",
game_hscores[i].score, game_hscores[i].name);
s[26] = '\377'; s[27] = '\377'; s[28] = '\376';
draw_tllst = s;
draw_tilesList();
}
seq = 5;
break;
case 5: /* wait for key pressed or timeout */
if (control_status & CONTROL_FIRE)
seq = 6;
else if (sys_gettime() - tm > SCREEN_TIMEOUT) {
seen++;
seq = 1;
}
break;
case 6: /* wait for key released */
if (!(control_status & CONTROL_FIRE)) {
if (seen++ == 0)
seq = 1;
else
seq = 7;
}
break;
}
if (control_status & CONTROL_EXIT) /* check for exit request */
return SCREEN_EXIT;
if (seq == 7) { /* we're done */
sysvid_clear();
seq = 0;
seen = 0;
first = FALSE;
game_period = period;
return SCREEN_DONE;
}
else
return SCREEN_RUNNING;
}
/* eof */

299
src/scr_imap.c Normal file
View File

@ -0,0 +1,299 @@
/*
* xrick/src/scr_imap.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <stdio.h>
#include "system.h"
#include "game.h"
#include "screens.h"
#include "rects.h"
#include "draw.h"
#include "control.h"
#include "maps.h"
/*
* local vars
*/
static U16 step; /* current step */
static U16 count; /* number of loops for current step */
static U16 run; /* 1 = run, 0 = no more step */
static U8 flipflop; /* flipflop for top, bottom, left, right */
static U16 spnum; /* sprite number */
static U16 spx, spdx; /* sprite x position and delta */
static U16 spy, spdy; /* sprite y position and delta */
static U16 spbase, spoffs; /* base, offset for sprite numbers table */
static U8 seq = 0; /* anim sequence */
static rect_t anim_rect = { 120, 16, 64, 64, NULL }; /* anim rectangle */
/*
* prototypes
*/
static void drawtb(void);
static void drawlr(void);
static void drawsprite(void);
static void drawcenter(void);
static void nextstep(void);
static void anim(void);
static void init(void);
/*
* Map introduction
*
* ASM: 1948
*
* return: SCREEN_RUNNING, SCREEN_DONE, SCREEN_EXIT
*/
U8
screen_introMap(void)
{
switch (seq) {
case 0:
sysvid_clear();
#ifdef GFXPC
draw_tilesBank = 1;
draw_filter = 0xAAAA;
#endif
#ifdef GFXST
draw_tilesBank = 0;
#endif
draw_tllst = screen_imaptext[game_map];
draw_setfb(32, 0);
draw_tilesSubList();
draw_setfb(32, 96);
#ifdef GFXPC
draw_filter = 0x5555;
#endif
draw_tilesList();
game_rects = NULL;
#ifdef GFXPC
draw_filter = 0xFFFF;
#endif
init();
nextstep();
drawcenter();
drawtb();
drawlr();
drawsprite();
control_last = 0;
game_rects = &draw_SCREENRECT;
#ifdef ENABLE_SOUND
game_setmusic(map_maps[game_map].tune, 1);
#endif
seq = 1;
break;
case 1: /* top and bottom borders */
drawtb();
game_rects = &anim_rect;
seq = 2;
break;
case 2: /* background and sprite */
anim();
drawcenter();
drawsprite();
game_rects = &anim_rect;
seq = 3;
break;
case 3: /* all borders */
drawtb();
drawlr();
game_rects = &anim_rect;
seq = 1;
break;
case 4: /* wait for key release */
if (!(control_status & CONTROL_FIRE))
seq = 5;
else
sys_sleep(50); /* .5s */
break;
}
if (control_status & CONTROL_FIRE) { /* end as soon as key pressed */
seq = 4;
}
if (control_status & CONTROL_EXIT) /* check for exit request */
return SCREEN_EXIT;
if (seq == 5) { /* end as soon as key pressed */
sysvid_clear();
seq = 0;
return SCREEN_DONE;
}
else
return SCREEN_RUNNING;
}
/*
* Display top and bottom borders (0x1B1F)
*
*/
static void
drawtb(void)
{
U8 i;
flipflop++;
if (flipflop & 0x01) {
draw_setfb(128, 16);
for (i = 0; i < 6; i++)
draw_tile(0x40);
draw_setfb(128, 72);
for (i = 0; i < 6; i++)
draw_tile(0x06);
}
else {
draw_setfb(128, 16);
for (i = 0; i < 6; i++)
draw_tile(0x05);
draw_setfb(128, 72);
for (i = 0; i < 6; i++)
draw_tile(0x40);
}
}
/*
* Display left and right borders (0x1B7C)
*
*/
static void
drawlr(void)
{
U8 i;
if (flipflop & 0x02) {
for (i = 0; i < 8; i++) {
draw_setfb(120, 16 + i * 8);
draw_tile(0x04);
draw_setfb(176, 16 + i * 8);
draw_tile(0x04);
}
}
else {
for (i = 0; i < 8; i++) {
draw_setfb(120, 16 + i * 8);
draw_tile(0x2B);
draw_setfb(176, 16 + i * 8);
draw_tile(0x2B);
}
}
}
/*
* Draw the sprite (0x19C6)
*
*/
static void
drawsprite(void)
{
draw_sprite(spnum, 128 + ((spx << 1) & 0x1C), 24 + (spy << 1));
}
/*
* Draw the background (0x1AF1)
*
*/
static void
drawcenter(void)
{
static U8 tn0[] = { 0x07, 0x5B, 0x7F, 0xA3, 0xC7 };
U8 i, j, tn;
tn = tn0[game_map];
for (i = 0; i < 6; i++) {
draw_setfb(128, (24 + 8 * i));
for (j = 0; j < 6; j++)
draw_tile(tn++);
}
}
/*
* Next Step (0x1A74)
*
*/
static void
nextstep(void)
{
if (screen_imapsteps[step].count) {
count = screen_imapsteps[step].count;
spdx = screen_imapsteps[step].dx;
spdy = screen_imapsteps[step].dy;
spbase = screen_imapsteps[step].base;
spoffs = 0;
step++;
}
else {
run = 0;
}
}
/*
* Anim (0x1AA8)
*
*/
static void
anim(void)
{
U16 i;
if (run) {
i = screen_imapsl[spbase + spoffs];
if (i == 0) {
spoffs = 0;
i = screen_imapsl[spbase];
}
spnum = i;
spoffs++;
spx += spdx;
spy += spdy;
count--;
if (count == 0)
nextstep();
}
}
/*
* Initialize (0x1A43)
*
*/
static void
init(void)
{
run = 0; run--;
step = screen_imapsofs[game_map];
spx = screen_imapsteps[step].dx;
spy = screen_imapsteps[step].dy;
step++;
spnum = 0; /* NOTE spnum in [8728] is never initialized ? */
}
/* eof */

53
src/scr_pause.c Normal file
View File

@ -0,0 +1,53 @@
/*
* xrick/src/scr_pause.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <stddef.h> /* NULL */
#include "system.h"
#include "game.h"
#include "screens.h"
#include "draw.h"
#include "control.h"
#include "ents.h"
/*
* Display the pause indicator
*/
void
screen_pause(U8 pause)
{
if (pause == TRUE) {
draw_tilesBank = 0;
draw_tllst = screen_pausedtxt;
draw_setfb(120, 80);
#ifdef GFXPC
draw_filter = 0xAAAA;
#endif
draw_tilesList();
}
else {
#ifdef GFXPC
draw_filter = 0xFFFF;
#endif
draw_map();
ent_draw();
draw_drawStatus();
}
game_rects = &draw_SCREENRECT;
}
/* eof */

74
src/scr_xrick.c Normal file
View File

@ -0,0 +1,74 @@
/*
* xrick/src/scr_xrick.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "system.h"
#include "game.h"
#include "screens.h"
#include "draw.h"
#include "control.h"
#include "img.h"
#include "img_splash.e"
/*
* Display XRICK splash screen
*
* return: SCREEN_RUNNING, SCREEN_DONE, SCREEN_EXIT
*/
U8
screen_xrick(void)
{
static U8 seq = 0;
static U8 wait = 0;
if (seq == 0) {
sysvid_clear();
draw_img(IMG_SPLASH);
game_rects = &draw_SCREENRECT;
seq = 1;
}
switch (seq) {
case 1: /* wait */
if (wait++ > 0x2) {
#ifdef ENABLE_SOUND
game_setmusic("sounds/bullet.wav", 1);
#endif
seq = 2;
wait = 0;
}
break;
case 2: /* wait */
if (wait++ > 0x20) {
seq = 99;
wait = 0;
}
}
if (control_status & CONTROL_EXIT) /* check for exit request */
return SCREEN_EXIT;
if (seq == 99) { /* we're done */
sysvid_clear();
sysvid_setGamePalette();
seq = 0;
return SCREEN_DONE;
}
return SCREEN_RUNNING;
}
/* eof */

163
src/scroller.c Normal file
View File

@ -0,0 +1,163 @@
/*
* xrick/src/scroller.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <stdlib.h>
#include "system.h"
#include "game.h"
#include "scroller.h"
#include "debug.h"
#include "draw.h"
#include "maps.h"
#include "ents.h"
static U8 period;
/*
* Scroll up
*
*/
U8
scroll_up(void)
{
U8 i, j;
static U8 n = 0;
/* last call: restore */
if (n == 8) {
n = 0;
game_period = period;
return SCROLL_DONE;
}
/* first call: prepare */
if (n == 0) {
period = game_period;
game_period = SCROLL_PERIOD;
}
/* translate map */
for (i = MAP_ROW_SCRTOP; i < MAP_ROW_HBBOT; i++)
for (j = 0x00; j < 0x20; j++)
map_map[i][j] = map_map[i + 1][j];
/* translate entities */
for (i = 0; ent_ents[i].n != 0xFF; i++) {
if (ent_ents[i].n) {
ent_ents[i].ysave -= 8;
ent_ents[i].trig_y -= 8;
ent_ents[i].y -= 8;
if (ent_ents[i].y & 0x8000) { /* map coord. from 0x0000 to 0x0140 */
IFDEBUG_SCROLLER(
sys_printf("xrick/scroller: entity %#04X is gone\n", i);
);
ent_ents[i].n = 0;
}
}
}
/* display */
draw_map();
ent_draw();
draw_drawStatus();
map_frow++;
/* loop */
if (n++ == 7) {
/* activate visible entities */
ent_actvis(map_frow + MAP_ROW_HBTOP, map_frow + MAP_ROW_HBBOT);
/* prepare map */
map_expand();
/* display */
draw_map();
ent_draw();
draw_drawStatus();
}
game_rects = &draw_SCREENRECT;
return SCROLL_RUNNING;
}
/*
* Scroll down
*
*/
U8
scroll_down(void)
{
U8 i, j;
static U8 n = 0;
/* last call: restore */
if (n == 8) {
n = 0;
game_period = period;
return SCROLL_DONE;
}
/* first call: prepare */
if (n == 0) {
period = game_period;
game_period = SCROLL_PERIOD;
}
/* translate map */
for (i = MAP_ROW_SCRBOT; i > MAP_ROW_HTTOP; i--)
for (j = 0x00; j < 0x20; j++)
map_map[i][j] = map_map[i - 1][j];
/* translate entities */
for (i = 0; ent_ents[i].n != 0xFF; i++) {
if (ent_ents[i].n) {
ent_ents[i].ysave += 8;
ent_ents[i].trig_y += 8;
ent_ents[i].y += 8;
if (ent_ents[i].y > 0x0140) { /* map coord. from 0x0000 to 0x0140 */
IFDEBUG_SCROLLER(
sys_printf("xrick/scroller: entity %#04X is gone\n", i);
);
ent_ents[i].n = 0;
}
}
}
/* display */
draw_map();
ent_draw();
draw_drawStatus();
map_frow--;
/* loop */
if (n++ == 7) {
/* activate visible entities */
ent_actvis(map_frow + MAP_ROW_HTTOP, map_frow + MAP_ROW_HTBOT);
/* prepare map */
map_expand();
/* display */
draw_map();
ent_draw();
draw_drawStatus();
}
game_rects = &draw_SCREENRECT;
return SCROLL_RUNNING;
}
/* eof */

232
src/sdlcodes.e Normal file
View File

@ -0,0 +1,232 @@
{"BACKSPACE" , SDLK_BACKSPACE},
{"TAB" , SDLK_TAB},
{"CLEAR" , SDLK_CLEAR},
{"RETURN" , SDLK_RETURN},
{"PAUSE" , SDLK_PAUSE},
{"ESCAPE" , SDLK_ESCAPE},
{"SPACE" , SDLK_SPACE},
{"EXCLAIM" , SDLK_EXCLAIM},
{"QUOTEDBL" , SDLK_QUOTEDBL},
{"HASH" , SDLK_HASH},
{"DOLLAR" , SDLK_DOLLAR},
{"AMPERSAND" , SDLK_AMPERSAND},
{"QUOTE" , SDLK_QUOTE},
{"LEFTPAREN" , SDLK_LEFTPAREN},
{"RIGHTPAREN" , SDLK_RIGHTPAREN},
{"ASTERISK" , SDLK_ASTERISK},
{"PLUS" , SDLK_PLUS},
{"COMMA" , SDLK_COMMA},
{"MINUS" , SDLK_MINUS},
{"PERIOD" , SDLK_PERIOD},
{"SLASH" , SDLK_SLASH},
{"0" , SDLK_0},
{"1" , SDLK_1},
{"2" , SDLK_2},
{"3" , SDLK_3},
{"4" , SDLK_4},
{"5" , SDLK_5},
{"6" , SDLK_6},
{"7" , SDLK_7},
{"8" , SDLK_8},
{"9" , SDLK_9},
{"COLON" , SDLK_COLON},
{"SEMICOLON" , SDLK_SEMICOLON},
{"LESS" , SDLK_LESS},
{"EQUALS" , SDLK_EQUALS},
{"GREATER" , SDLK_GREATER},
{"QUESTION" , SDLK_QUESTION},
{"AT" , SDLK_AT},
{"LEFTBRACKET" , SDLK_LEFTBRACKET},
{"BACKSLASH" , SDLK_BACKSLASH},
{"RIGHTBRACKET" , SDLK_RIGHTBRACKET},
{"CARET" , SDLK_CARET},
{"UNDERSCORE" , SDLK_UNDERSCORE},
{"BACKQUOTE" , SDLK_BACKQUOTE},
{"a" , SDLK_a},
{"b" , SDLK_b},
{"c" , SDLK_c},
{"d" , SDLK_d},
{"e" , SDLK_e},
{"f" , SDLK_f},
{"g" , SDLK_g},
{"h" , SDLK_h},
{"i" , SDLK_i},
{"j" , SDLK_j},
{"k" , SDLK_k},
{"l" , SDLK_l},
{"m" , SDLK_m},
{"n" , SDLK_n},
{"o" , SDLK_o},
{"p" , SDLK_p},
{"q" , SDLK_q},
{"r" , SDLK_r},
{"s" , SDLK_s},
{"t" , SDLK_t},
{"u" , SDLK_u},
{"v" , SDLK_v},
{"w" , SDLK_w},
{"x" , SDLK_x},
{"y" , SDLK_y},
{"z" , SDLK_z},
{"DELETE" , SDLK_DELETE},
{"WORLD_0" , SDLK_WORLD_0},
{"WORLD_1" , SDLK_WORLD_1},
{"WORLD_2" , SDLK_WORLD_2},
{"WORLD_3" , SDLK_WORLD_3},
{"WORLD_4" , SDLK_WORLD_4},
{"WORLD_5" , SDLK_WORLD_5},
{"WORLD_6" , SDLK_WORLD_6},
{"WORLD_7" , SDLK_WORLD_7},
{"WORLD_8" , SDLK_WORLD_8},
{"WORLD_9" , SDLK_WORLD_9},
{"WORLD_10" , SDLK_WORLD_10},
{"WORLD_11" , SDLK_WORLD_11},
{"WORLD_12" , SDLK_WORLD_12},
{"WORLD_13" , SDLK_WORLD_13},
{"WORLD_14" , SDLK_WORLD_14},
{"WORLD_15" , SDLK_WORLD_15},
{"WORLD_16" , SDLK_WORLD_16},
{"WORLD_17" , SDLK_WORLD_17},
{"WORLD_18" , SDLK_WORLD_18},
{"WORLD_19" , SDLK_WORLD_19},
{"WORLD_20" , SDLK_WORLD_20},
{"WORLD_21" , SDLK_WORLD_21},
{"WORLD_22" , SDLK_WORLD_22},
{"WORLD_23" , SDLK_WORLD_23},
{"WORLD_24" , SDLK_WORLD_24},
{"WORLD_25" , SDLK_WORLD_25},
{"WORLD_26" , SDLK_WORLD_26},
{"WORLD_27" , SDLK_WORLD_27},
{"WORLD_28" , SDLK_WORLD_28},
{"WORLD_29" , SDLK_WORLD_29},
{"WORLD_30" , SDLK_WORLD_30},
{"WORLD_31" , SDLK_WORLD_31},
{"WORLD_32" , SDLK_WORLD_32},
{"WORLD_33" , SDLK_WORLD_33},
{"WORLD_34" , SDLK_WORLD_34},
{"WORLD_35" , SDLK_WORLD_35},
{"WORLD_36" , SDLK_WORLD_36},
{"WORLD_37" , SDLK_WORLD_37},
{"WORLD_38" , SDLK_WORLD_38},
{"WORLD_39" , SDLK_WORLD_39},
{"WORLD_40" , SDLK_WORLD_40},
{"WORLD_41" , SDLK_WORLD_41},
{"WORLD_42" , SDLK_WORLD_42},
{"WORLD_43" , SDLK_WORLD_43},
{"WORLD_44" , SDLK_WORLD_44},
{"WORLD_45" , SDLK_WORLD_45},
{"WORLD_46" , SDLK_WORLD_46},
{"WORLD_47" , SDLK_WORLD_47},
{"WORLD_48" , SDLK_WORLD_48},
{"WORLD_49" , SDLK_WORLD_49},
{"WORLD_50" , SDLK_WORLD_50},
{"WORLD_51" , SDLK_WORLD_51},
{"WORLD_52" , SDLK_WORLD_52},
{"WORLD_53" , SDLK_WORLD_53},
{"WORLD_54" , SDLK_WORLD_54},
{"WORLD_55" , SDLK_WORLD_55},
{"WORLD_56" , SDLK_WORLD_56},
{"WORLD_57" , SDLK_WORLD_57},
{"WORLD_58" , SDLK_WORLD_58},
{"WORLD_59" , SDLK_WORLD_59},
{"WORLD_60" , SDLK_WORLD_60},
{"WORLD_61" , SDLK_WORLD_61},
{"WORLD_62" , SDLK_WORLD_62},
{"WORLD_63" , SDLK_WORLD_63},
{"WORLD_64" , SDLK_WORLD_64},
{"WORLD_65" , SDLK_WORLD_65},
{"WORLD_66" , SDLK_WORLD_66},
{"WORLD_67" , SDLK_WORLD_67},
{"WORLD_68" , SDLK_WORLD_68},
{"WORLD_69" , SDLK_WORLD_69},
{"WORLD_70" , SDLK_WORLD_70},
{"WORLD_71" , SDLK_WORLD_71},
{"WORLD_72" , SDLK_WORLD_72},
{"WORLD_73" , SDLK_WORLD_73},
{"WORLD_74" , SDLK_WORLD_74},
{"WORLD_75" , SDLK_WORLD_75},
{"WORLD_76" , SDLK_WORLD_76},
{"WORLD_77" , SDLK_WORLD_77},
{"WORLD_78" , SDLK_WORLD_78},
{"WORLD_79" , SDLK_WORLD_79},
{"WORLD_80" , SDLK_WORLD_80},
{"WORLD_81" , SDLK_WORLD_81},
{"WORLD_82" , SDLK_WORLD_82},
{"WORLD_83" , SDLK_WORLD_83},
{"WORLD_84" , SDLK_WORLD_84},
{"WORLD_85" , SDLK_WORLD_85},
{"WORLD_86" , SDLK_WORLD_86},
{"WORLD_87" , SDLK_WORLD_87},
{"WORLD_88" , SDLK_WORLD_88},
{"WORLD_89" , SDLK_WORLD_89},
{"WORLD_90" , SDLK_WORLD_90},
{"WORLD_91" , SDLK_WORLD_91},
{"WORLD_92" , SDLK_WORLD_92},
{"WORLD_93" , SDLK_WORLD_93},
{"WORLD_94" , SDLK_WORLD_94},
{"WORLD_95" , SDLK_WORLD_95},
{"KP0" , SDLK_KP0},
{"KP1" , SDLK_KP1},
{"KP2" , SDLK_KP2},
{"KP3" , SDLK_KP3},
{"KP4" , SDLK_KP4},
{"KP5" , SDLK_KP5},
{"KP6" , SDLK_KP6},
{"KP7" , SDLK_KP7},
{"KP8" , SDLK_KP8},
{"KP9" , SDLK_KP9},
{"KP_PERIOD" , SDLK_KP_PERIOD},
{"KP_DIVIDE" , SDLK_KP_DIVIDE},
{"KP_MULTIPLY" , SDLK_KP_MULTIPLY},
{"KP_MINUS" , SDLK_KP_MINUS},
{"KP_PLUS" , SDLK_KP_PLUS},
{"KP_ENTER" , SDLK_KP_ENTER},
{"KP_EQUALS" , SDLK_KP_EQUALS},
{"UP" , SDLK_UP},
{"DOWN" , SDLK_DOWN},
{"RIGHT" , SDLK_RIGHT},
{"LEFT" , SDLK_LEFT},
{"INSERT" , SDLK_INSERT},
{"HOME" , SDLK_HOME},
{"END" , SDLK_END},
{"PAGEUP" , SDLK_PAGEUP},
{"PAGEDOWN" , SDLK_PAGEDOWN},
{"F1" , SDLK_F1},
{"F2" , SDLK_F2},
{"F3" , SDLK_F3},
{"F4" , SDLK_F4},
{"F5" , SDLK_F5},
{"F6" , SDLK_F6},
{"F7" , SDLK_F7},
{"F8" , SDLK_F8},
{"F9" , SDLK_F9},
{"F10" , SDLK_F10},
{"F11" , SDLK_F11},
{"F12" , SDLK_F12},
{"F13" , SDLK_F13},
{"F14" , SDLK_F14},
{"F15" , SDLK_F15},
{"NUMLOCK" , SDLK_NUMLOCK},
{"CAPSLOCK" , SDLK_CAPSLOCK},
{"SCROLLOCK" , SDLK_SCROLLOCK},
{"RSHIFT" , SDLK_RSHIFT},
{"LSHIFT" , SDLK_LSHIFT},
{"RCTRL" , SDLK_RCTRL},
{"LCTRL" , SDLK_LCTRL},
{"RALT" , SDLK_RALT},
{"LALT" , SDLK_LALT},
{"RMETA" , SDLK_RMETA},
{"LMETA" , SDLK_LMETA},
{"LSUPER" , SDLK_LSUPER},
{"RSUPER" , SDLK_RSUPER},
{"MODE" , SDLK_MODE},
{"COMPOSE" , SDLK_COMPOSE},
{"HELP" , SDLK_HELP},
{"PRINT" , SDLK_PRINT},
{"SYSREQ" , SDLK_SYSREQ},
{"BREAK" , SDLK_BREAK},
{"MENU" , SDLK_MENU},
{"POWER" , SDLK_POWER},
{"EURO" , SDLK_EURO},
{"NULL", 0}

234
src/sysarg.c Normal file
View File

@ -0,0 +1,234 @@
/*
* xrick/src/sysarg.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
/*
* 20021010 added test to prevent buffer overrun in -keys parsing.
*/
#include <stdlib.h> /* atoi */
#include <string.h> /* strcasecmp */
#include <SDL.h>
#include "system.h"
#include "config.h"
#include "game.h"
#include "maps.h"
#include "syssnd.h"
/* handle Microsoft Visual C (must come after system.h!) */
#ifdef __MSVC__
#define strcasecmp stricmp
#endif
typedef struct {
char name[16];
int code;
} sdlcodes_t;
static sdlcodes_t sdlcodes[SDLK_LAST] = {
#include "sdlcodes.e"
};
int sysarg_args_period = 0;
int sysarg_args_map = 0;
int sysarg_args_submap = 0;
int sysarg_args_fullscreen = 0;
int sysarg_args_zoom = 0;
int sysarg_args_nosound = 0;
int sysarg_args_vol = 0;
char *sysarg_args_data = NULL;
/*
* Fail
*/
void
sysarg_fail(char *msg)
{
#ifdef ENABLE_SOUND
printf("xrick [version #%s]: %s\nusage: xrick [<options>]\n<option> =\n -h, -help : Display this information. -fullscreen : Run in fullscreen mode.\n The default is to run in a window.\n -speed <speed> : Run at speed <speed>. Speed must be an integer between 1\n (fast) and 100 (slow). The default is %d\n -zoom <zoom> : Display with zoom factor <zoom>. <zoom> must be an integer\n between 1 (320x200) and %d (%d times bigger). The default is 2.\n -map <map> : Start at map number <map>. <map> must be an integer between\n 1 and %d. The default is to start at map number 1\n -submap <submap> : Start at submap <submap>. <submap> must be an integer\n between 1 and %d. The default is to start at submap number 1 or, if a map\n was specified, at the first submap of that map.\n -keys <left>-<right>-<up>-<down>-<fire> : Override the default key\n bindings (cf. KeyCodes)\n -nosound : Disable sounds. The default is to play with sounds enabled.\n -vol <vol> : Play sounds at volume <vol>. <vol> must be an integer\n between 0 (silence) and %d (max). The default is to play sounds\n at maximal volume (%d).\n", VERSION, msg, GAME_PERIOD, SYSVID_MAXZOOM, SYSVID_MAXZOOM, MAP_NBR_MAPS-1, MAP_NBR_SUBMAPS, SYSSND_MAXVOL, SYSSND_MAXVOL);
#else
printf("xrick [version #%s]: %s\nusage: xrick [<options>]\n<option> =\n -h, -help : Display this information. -fullscreen : Run in fullscreen mode.\n The default is to run in a window.\n -speed <speed> : Run at speed <speed>. Speed must be an integer between 1\n (fast) and 100 (slow). The default is %d\n -zoom <zoom> : Display with zoom factor <zoom>. <zoom> must be an integer\n between 1 (320x200) and %d (%d times bigger). The default is 2.\n -map <map> : Start at map number <map>. <map> must be an integer between\n 1 and %d. The default is to start at map number 1\n -submap <submap> : Start at submap <submap>. <submap> must be an integer\n between 1 and %d. The default is to start at submap number 1 or, if a map\n was specified, at the first submap of that map.\n -keys <left>-<right>-<up>-<down>-<fire> : Override the default key\n bindings (cf. KeyCodes)\n", VERSION, msg, GAME_PERIOD, SYSVID_MAXZOOM, SYSVID_MAXZOOM, MAP_NBR_MAPS-1, MAP_NBR_SUBMAPS);
#endif
exit(1);
}
/*
* Get SDL key code
*/
static int
sysarg_sdlcode(char *k)
{
int i, result;
i = 0;
result = 0;
while (sdlcodes[i].code) {
if (!strcasecmp(sdlcodes[i].name, k)) {
result = sdlcodes[i].code;
break;
}
i++;
}
return result;
}
/*
* Scan key codes sequence
*/
int
sysarg_scankeys(char *keys)
{
char k[16];
int i, j;
i = 0;
j = 0;
while (keys[i] != '\0' && keys[i] != '-' && j + 1 < sizeof k) k[j++] = keys[i++];
if (keys[i++] == '\0') return -1;
k[j] = '\0';
syskbd_left = sysarg_sdlcode(k);
if (!syskbd_left) return -1;
j = 0;
while (keys[i] != '\0' && keys[i] != '-' && j + 1 < sizeof k) k[j++] = keys[i++];
if (keys[i++] == '\0') return -1;
k[j] = '\0';
syskbd_right = sysarg_sdlcode(k);
if (!syskbd_right) return -1;
j = 0;
while (keys[i] != '\0' && keys[i] != '-' && j + 1 < sizeof k) k[j++] = keys[i++];
if (keys[i++] == '\0') return -1;
k[j] = '\0';
syskbd_up = sysarg_sdlcode(k);
if (!syskbd_up) return -1;
j = 0;
while (keys[i] != '\0' && keys[i] != '-' && j + 1 < sizeof k) k[j++] = keys[i++];
if (keys[i++] == '\0') return -1;
k[j] = '\0';
syskbd_down = sysarg_sdlcode(k);
if (!syskbd_down) return -1;
j = 0;
while (keys[i] != '\0' && keys[i] != '-' && j + 1 < sizeof k) k[j++] = keys[i++];
if (keys[i] != '\0') return -1;
k[j] = '\0';
syskbd_fire = sysarg_sdlcode(k);
if (!syskbd_fire) return -1;
return 0;
}
/*
* Read and process arguments
*/
void
sysarg_init(int argc, char **argv)
{
int i;
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-fullscreen")) {
sysarg_args_fullscreen = 1;
}
else if (!strcmp(argv[i], "-help") ||
!strcmp(argv[i], "-h")) {
sysarg_fail("help");
}
else if (!strcmp(argv[i], "-speed")) {
if (++i == argc) sysarg_fail("missing speed value");
sysarg_args_period = atoi(argv[i]) - 1;
if (sysarg_args_period < 0 || sysarg_args_period > 99)
sysarg_fail("invalid speed value");
}
else if (!strcmp(argv[i], "-keys")) {
if (++i == argc) sysarg_fail("missing key codes");
if (sysarg_scankeys(argv[i]) == -1)
sysarg_fail("invalid key codes");
}
else if (!strcmp(argv[i], "-zoom")) {
if (++i == argc) sysarg_fail("missing zoom value");
sysarg_args_zoom = atoi(argv[i]);
if (sysarg_args_zoom < 1 || sysarg_args_zoom > SYSVID_MAXZOOM)
sysarg_fail("invalid zoom value");
}
else if (!strcmp(argv[i], "-map")) {
if (++i == argc) sysarg_fail("missing map number");
sysarg_args_map = atoi(argv[i]) - 1;
if (sysarg_args_map < 0 || sysarg_args_map >= MAP_NBR_MAPS-1)
sysarg_fail("invalid map number");
}
else if (!strcmp(argv[i], "-submap")) {
if (++i == argc) sysarg_fail("missing submap number");
sysarg_args_submap = atoi(argv[i]) - 1;
if (sysarg_args_submap < 0 || sysarg_args_submap >= MAP_NBR_SUBMAPS)
sysarg_fail("invalid submap number");
}
#ifdef ENABLE_SOUND
else if (!strcmp(argv[i], "-vol")) {
if (++i == argc) sysarg_fail("missing volume");
sysarg_args_vol = atoi(argv[i]) - 1;
if (sysarg_args_submap < 0 || sysarg_args_submap >= SYSSND_MAXVOL)
sysarg_fail("invalid volume");
}
else if (!strcmp(argv[i], "-nosound")) {
sysarg_args_nosound = 1;
}
#endif
else if (!strcmp(argv[i], "-data")) {
if (++i == argc) sysarg_fail("missing data");
sysarg_args_data = argv[i];
}
else {
sysarg_fail("invalid argument(s)");
}
}
/* this is dirty (sort of) */
if (sysarg_args_submap > 0 && sysarg_args_submap < 9)
sysarg_args_map = 0;
if (sysarg_args_submap >= 9 && sysarg_args_submap < 20)
sysarg_args_map = 1;
if (sysarg_args_submap >= 20 && sysarg_args_submap < 38)
sysarg_args_map = 2;
if (sysarg_args_submap >= 38)
sysarg_args_map = 3;
if (sysarg_args_submap == 9 ||
sysarg_args_submap == 20 ||
sysarg_args_submap == 38)
sysarg_args_submap = 0;
}
/* eof */

234
src/sysevt.c Normal file
View File

@ -0,0 +1,234 @@
/*
* xrick/src/sysevt.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
/*
* 20021010 SDLK_n replaced by SDLK_Fn because some non-US keyboards
* requires that SHIFT be pressed to input numbers.
*/
#include <SDL.h>
#include "system.h"
#include "config.h"
#include "game.h"
#include "debug.h"
#include "control.h"
#include "draw.h"
#define SYSJOY_RANGE 3280
#define SETBIT(x,b) x |= (b)
#define CLRBIT(x,b) x &= ~(b)
static SDL_Event event;
/*
* Process an event
*/
static void
processEvent()
{
U16 key;
#ifdef ENABLE_FOCUS
SDL_ActiveEvent *aevent;
#endif
switch (event.type) {
case SDL_KEYDOWN:
key = event.key.keysym.sym;
if (key == syskbd_up || key == SDLK_UP) {
SETBIT(control_status, CONTROL_UP);
control_last = CONTROL_UP;
}
else if (key == syskbd_down || key == SDLK_DOWN) {
SETBIT(control_status, CONTROL_DOWN);
control_last = CONTROL_DOWN;
}
else if (key == syskbd_left || key == SDLK_LEFT) {
SETBIT(control_status, CONTROL_LEFT);
control_last = CONTROL_LEFT;
}
else if (key == syskbd_right || key == SDLK_RIGHT) {
SETBIT(control_status, CONTROL_RIGHT);
control_last = CONTROL_RIGHT;
}
else if (key == syskbd_pause) {
SETBIT(control_status, CONTROL_PAUSE);
control_last = CONTROL_PAUSE;
}
else if (key == syskbd_end) {
SETBIT(control_status, CONTROL_END);
control_last = CONTROL_END;
}
else if (key == syskbd_xtra) {
SETBIT(control_status, CONTROL_EXIT);
control_last = CONTROL_EXIT;
}
else if (key == syskbd_fire) {
SETBIT(control_status, CONTROL_FIRE);
control_last = CONTROL_FIRE;
}
else if (key == SDLK_F1) {
sysvid_toggleFullscreen();
}
else if (key == SDLK_F2) {
sysvid_zoom(-1);
}
else if (key == SDLK_F3) {
sysvid_zoom(+1);
}
#ifdef ENABLE_SOUND
else if (key == SDLK_F4) {
syssnd_toggleMute();
}
else if (key == SDLK_F5) {
syssnd_vol(-1);
}
else if (key == SDLK_F6) {
syssnd_vol(+1);
}
#endif
#ifdef ENABLE_CHEATS
else if (key == SDLK_F7) {
game_toggleCheat(1);
}
else if (key == SDLK_F8) {
game_toggleCheat(2);
}
else if (key == SDLK_F9) {
game_toggleCheat(3);
}
#endif
break;
case SDL_KEYUP:
key = event.key.keysym.sym;
if (key == syskbd_up || key == SDLK_UP) {
CLRBIT(control_status, CONTROL_UP);
control_last = CONTROL_UP;
}
else if (key == syskbd_down || key == SDLK_DOWN) {
CLRBIT(control_status, CONTROL_DOWN);
control_last = CONTROL_DOWN;
}
else if (key == syskbd_left || key == SDLK_LEFT) {
CLRBIT(control_status, CONTROL_LEFT);
control_last = CONTROL_LEFT;
}
else if (key == syskbd_right || key == SDLK_RIGHT) {
CLRBIT(control_status, CONTROL_RIGHT);
control_last = CONTROL_RIGHT;
}
else if (key == syskbd_pause) {
CLRBIT(control_status, CONTROL_PAUSE);
control_last = CONTROL_PAUSE;
}
else if (key == syskbd_end) {
CLRBIT(control_status, CONTROL_END);
control_last = CONTROL_END;
}
else if (key == syskbd_xtra) {
CLRBIT(control_status, CONTROL_EXIT);
control_last = CONTROL_EXIT;
}
else if (key == syskbd_fire) {
CLRBIT(control_status, CONTROL_FIRE);
control_last = CONTROL_FIRE;
}
break;
case SDL_QUIT:
/* player tries to close the window -- this is the same as pressing ESC */
SETBIT(control_status, CONTROL_EXIT);
control_last = CONTROL_EXIT;
break;
#ifdef ENABLE_FOCUS
case SDL_ACTIVEEVENT: {
aevent = (SDL_ActiveEvent *)&event;
IFDEBUG_EVENTS(
printf("xrick/events: active %x %x\n", aevent->gain, aevent->state);
);
if (aevent->gain == 1)
control_active = TRUE;
else
control_active = FALSE;
}
break;
#endif
#ifdef ENABLE_JOYSTICK
case SDL_JOYAXISMOTION:
IFDEBUG_EVENTS(sys_printf("xrick/events: joystick\n"););
if (event.jaxis.axis == 0) { /* left-right */
if (event.jaxis.value < -SYSJOY_RANGE) { /* left */
SETBIT(control_status, CONTROL_LEFT);
CLRBIT(control_status, CONTROL_RIGHT);
}
else if (event.jaxis.value > SYSJOY_RANGE) { /* right */
SETBIT(control_status, CONTROL_RIGHT);
CLRBIT(control_status, CONTROL_LEFT);
}
else { /* center */
CLRBIT(control_status, CONTROL_RIGHT);
CLRBIT(control_status, CONTROL_LEFT);
}
}
if (event.jaxis.axis == 1) { /* up-down */
if (event.jaxis.value < -SYSJOY_RANGE) { /* up */
SETBIT(control_status, CONTROL_UP);
CLRBIT(control_status, CONTROL_DOWN);
}
else if (event.jaxis.value > SYSJOY_RANGE) { /* down */
SETBIT(control_status, CONTROL_DOWN);
CLRBIT(control_status, CONTROL_UP);
}
else { /* center */
CLRBIT(control_status, CONTROL_DOWN);
CLRBIT(control_status, CONTROL_UP);
}
}
break;
case SDL_JOYBUTTONDOWN:
SETBIT(control_status, CONTROL_FIRE);
break;
case SDL_JOYBUTTONUP:
CLRBIT(control_status, CONTROL_FIRE);
break;
#endif
default:
break;
}
}
/*
* Process events, if any, then return
*/
void
sysevt_poll(void)
{
while (SDL_PollEvent(&event))
processEvent();
}
/*
* Wait for an event, then process it and return
*/
void
sysevt_wait(void)
{
SDL_WaitEvent(&event);
processEvent();
}
/* eof */

64
src/sysjoy.c Normal file
View File

@ -0,0 +1,64 @@
/*
* xrick/src/sysjoy.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <SDL.h>
#include "config.h"
#ifdef ENABLE_JOYSTICK
#include "system.h"
#include "debug.h"
static SDL_Joystick *j = NULL;
void
sysjoy_init(void)
{
U8 i, jcount;
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) {
IFDEBUG_JOYSTICK(
sys_printf("xrick/joystick: can not initialize joystick subsystem\n");
);
return;
}
jcount = SDL_NumJoysticks();
if (!jcount) { /* no joystick on this system */
IFDEBUG_JOYSTICK(sys_printf("xrick/joystick: no joystick available\n"););
return;
}
/* use the first joystick that we can open */
for (i = 0; i < jcount; i++) {
j = SDL_JoystickOpen(i);
if (j)
break;
}
/* enable events */
SDL_JoystickEventState(SDL_ENABLE);
}
void
sysjoy_shutdown(void)
{
if (j)
SDL_JoystickClose(j);
}
#endif /* ENABLE_JOYSTICK */
/* eof */

29
src/syskbd.c Normal file
View File

@ -0,0 +1,29 @@
/*
* xrick/src/syskbd.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <SDL.h>
#include "system.h"
U8 syskbd_up = SDLK_o;
U8 syskbd_down = SDLK_k;
U8 syskbd_left = SDLK_z;
U8 syskbd_right = SDLK_x;
U8 syskbd_pause = SDLK_p;
U8 syskbd_end = SDLK_e;
U8 syskbd_xtra = SDLK_ESCAPE;
U8 syskbd_fire = SDLK_SPACE;
/* eof */

433
src/syssnd.c Normal file
View File

@ -0,0 +1,433 @@
/*
* xrick/src/syssnd.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <SDL.h>
#include <stdlib.h>
#include <memory.h>
#include "config.h"
#ifdef ENABLE_SOUND
#include "system.h"
#include "game.h"
#include "syssnd.h"
#include "debug.h"
#include "data.h"
#define ADJVOL(S) (((S)*sndVol)/SDL_MIX_MAXVOLUME)
static U8 isAudioActive = FALSE;
static channel_t channel[SYSSND_MIXCHANNELS];
static U8 sndVol = SDL_MIX_MAXVOLUME; /* internal volume */
static U8 sndUVol = SYSSND_MAXVOL; /* user-selected volume */
static U8 sndMute = FALSE; /* mute flag */
static SDL_mutex *sndlock;
/*
* prototypes
*/
static int sdlRWops_open(SDL_RWops *context, char *name);
static int sdlRWops_seek(SDL_RWops *context, int offset, int whence);
static int sdlRWops_read(SDL_RWops *context, void *ptr, int size, int maxnum);
static int sdlRWops_write(SDL_RWops *context, const void *ptr, int size, int num);
static int sdlRWops_close(SDL_RWops *context);
static void end_channel(U8);
/*
* Callback -- this is also where all sound mixing is done
*
* Note: it may not be that much a good idea to do all the mixing here ; it
* may be more efficient to mix samples every frame, or maybe everytime a
* new sound is sent to be played. I don't know.
*/
void syssnd_callback(UNUSED(void *userdata), U8 *stream, int len)
{
U8 c;
S16 s;
U32 i;
SDL_mutexP(sndlock);
for (i = 0; i < (U32)len; i++) {
s = 0;
for (c = 0; c < SYSSND_MIXCHANNELS; c++) {
if (channel[c].loop != 0) { /* channel is active */
if (channel[c].len > 0) { /* not ending */
s += ADJVOL(*channel[c].buf - 0x80);
channel[c].buf++;
channel[c].len--;
}
else { /* ending */
if (channel[c].loop > 0) channel[c].loop--;
if (channel[c].loop) { /* just loop */
IFDEBUG_AUDIO2(sys_printf("xrick/audio: channel %d - loop\n", c););
channel[c].buf = channel[c].snd->buf;
channel[c].len = channel[c].snd->len;
s += ADJVOL(*channel[c].buf - 0x80);
channel[c].buf++;
channel[c].len--;
}
else { /* end for real */
IFDEBUG_AUDIO2(sys_printf("xrick/audio: channel %d - end\n", c););
end_channel(c);
}
}
}
}
if (sndMute)
stream[i] = 0x80;
else {
s += 0x80;
if (s > 0xff) s = 0xff;
if (s < 0x00) s = 0x00;
stream[i] = (U8)s;
}
}
memcpy(stream, stream, len);
SDL_mutexV(sndlock);
}
static void
end_channel(U8 c)
{
channel[c].loop = 0;
if (channel[c].snd->dispose)
syssnd_free(channel[c].snd);
channel[c].snd = NULL;
}
void
syssnd_init(void)
{
SDL_AudioSpec desired, obtained;
U16 c;
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
IFDEBUG_AUDIO(
sys_printf("xrick/audio: can not initialize audio subsystem\n");
);
return;
}
desired.freq = SYSSND_FREQ;
desired.format = AUDIO_U8;
desired.channels = SYSSND_CHANNELS;
desired.samples = SYSSND_MIXSAMPLES;
desired.callback = syssnd_callback;
desired.userdata = NULL;
if (SDL_OpenAudio(&desired, &obtained) < 0) {
IFDEBUG_AUDIO(
sys_printf("xrick/audio: can not open audio (%s)\n", SDL_GetError());
);
return;
}
sndlock = SDL_CreateMutex();
if (sndlock == NULL) {
IFDEBUG_AUDIO(sys_printf("xrick/audio: can not create lock\n"););
SDL_CloseAudio();
return;
}
if (sysarg_args_vol != 0) {
sndUVol = sysarg_args_vol;
sndVol = SDL_MIX_MAXVOLUME * sndUVol / SYSSND_MAXVOL;
}
for (c = 0; c < SYSSND_MIXCHANNELS; c++)
channel[c].loop = 0; /* deactivate */
isAudioActive = TRUE;
SDL_PauseAudio(0);
}
/*
* Shutdown
*/
void
syssnd_shutdown(void)
{
if (!isAudioActive) return;
SDL_CloseAudio();
SDL_DestroyMutex(sndlock);
isAudioActive = FALSE;
}
/*
* Toggle mute
*
* When muted, sounds are still managed but not sent to the dsp, hence
* it is possible to un-mute at any time.
*/
void
syssnd_toggleMute(void)
{
SDL_mutexP(sndlock);
sndMute = !sndMute;
SDL_mutexV(sndlock);
}
void
syssnd_vol(S8 d)
{
if ((d < 0 && sndUVol > 0) ||
(d > 0 && sndUVol < SYSSND_MAXVOL)) {
sndUVol += d;
SDL_mutexP(sndlock);
sndVol = SDL_MIX_MAXVOLUME * sndUVol / SYSSND_MAXVOL;
SDL_mutexV(sndlock);
}
}
/*
* Play a sound
*
* loop: number of times the sound should be played, -1 to loop forever
* returns: channel number, or -1 if none was available
*
* NOTE if sound is already playing, simply reset it (i.e. can not have
* twice the same sound playing -- tends to become noisy when too many
* bad guys die at the same time).
*/
S8
syssnd_play(sound_t *sound, S8 loop)
{
S8 c;
if (!isAudioActive) return -1;
if (sound == NULL) return -1;
c = 0;
SDL_mutexP(sndlock);
while ((channel[c].snd != sound || channel[c].loop == 0) &&
channel[c].loop != 0 &&
c < SYSSND_MIXCHANNELS)
c++;
if (c == SYSSND_MIXCHANNELS)
c = -1;
IFDEBUG_AUDIO(
if (channel[c].snd == sound && channel[c].loop != 0)
sys_printf("xrick/sound: already playing %s on channel %d - resetting\n",
sound->name, c);
else if (c >= 0)
sys_printf("xrick/sound: playing %s on channel %d\n", sound->name, c);
);
if (c >= 0) {
channel[c].loop = loop;
channel[c].snd = sound;
channel[c].buf = sound->buf;
channel[c].len = sound->len;
}
SDL_mutexV(sndlock);
return c;
}
/*
* Pause
*
* pause: TRUE or FALSE
* clear: TRUE to cleanup all sounds and make sure we start from scratch
*/
void
syssnd_pause(U8 pause, U8 clear)
{
U8 c;
if (!isAudioActive) return;
if (clear == TRUE) {
SDL_mutexP(sndlock);
for (c = 0; c < SYSSND_MIXCHANNELS; c++)
channel[c].loop = 0;
SDL_mutexV(sndlock);
}
if (pause == TRUE)
SDL_PauseAudio(1);
else
SDL_PauseAudio(0);
}
/*
* Stop a channel
*/
void
syssnd_stopchan(S8 chan)
{
if (chan < 0 || chan > SYSSND_MIXCHANNELS)
return;
SDL_mutexP(sndlock);
if (channel[chan].snd) end_channel(chan);
SDL_mutexV(sndlock);
}
/*
* Stop a sound
*/
void
syssnd_stopsound(sound_t *sound)
{
U8 i;
if (!sound) return;
SDL_mutexP(sndlock);
for (i = 0; i < SYSSND_MIXCHANNELS; i++)
if (channel[i].snd == sound) end_channel(i);
SDL_mutexV(sndlock);
}
/*
* See if a sound is playing
*/
int
syssnd_isplaying(sound_t *sound)
{
U8 i, playing;
playing = 0;
SDL_mutexP(sndlock);
for (i = 0; i < SYSSND_MIXCHANNELS; i++)
if (channel[i].snd == sound) playing = 1;
SDL_mutexV(sndlock);
return playing;
}
/*
* Stops all channels.
*/
void
syssnd_stopall(void)
{
U8 i;
SDL_mutexP(sndlock);
for (i = 0; i < SYSSND_MIXCHANNELS; i++)
if (channel[i].snd) end_channel(i);
SDL_mutexV(sndlock);
}
/*
* Load a sound.
*/
sound_t *
syssnd_load(char *name)
{
sound_t *s;
SDL_RWops *context;
SDL_AudioSpec audiospec;
/* alloc context */
context = malloc(sizeof(SDL_RWops));
context->seek = sdlRWops_seek;
context->read = sdlRWops_read;
context->write = sdlRWops_write;
context->close = sdlRWops_close;
/* open */
if (sdlRWops_open(context, name) == -1)
return NULL;
/* alloc sound */
s = malloc(sizeof(sound_t));
#ifdef DEBUG
s->name = malloc(strlen(name) + 1);
strncpy(s->name, name, strlen(name) + 1);
#endif
/* read */
/* second param == 1 -> close source once read */
if (!SDL_LoadWAV_RW(context, 1, &audiospec, &(s->buf), &(s->len)))
{
free(s);
return NULL;
}
s->dispose = FALSE;
return s;
}
/*
*
*/
void
syssnd_free(sound_t *s)
{
if (!s) return;
if (s->buf) SDL_FreeWAV(s->buf);
s->buf = NULL;
s->len = 0;
}
/*
*
*/
static int
sdlRWops_open(SDL_RWops *context, char *name)
{
data_file_t *f;
f = data_file_open(name);
if (!f) return -1;
context->hidden.unknown.data1 = (void *)f;
return 0;
}
static int
sdlRWops_seek(SDL_RWops *context, int offset, int whence)
{
return data_file_seek((data_file_t *)(context->hidden.unknown.data1), offset, whence);
}
static int
sdlRWops_read(SDL_RWops *context, void *ptr, int size, int maxnum)
{
return data_file_read((data_file_t *)(context->hidden.unknown.data1), ptr, size, maxnum);
}
static int
sdlRWops_write(SDL_RWops *context, const void *ptr, int size, int num)
{
/* not implemented */
return -1;
}
static int
sdlRWops_close(SDL_RWops *context)
{
if (context)
{
data_file_close((data_file_t *)(context->hidden.unknown.data1));
free(context);
}
return 0;
}
#endif /* ENABLE_SOUND */
/* eof */

131
src/system.c Normal file
View File

@ -0,0 +1,131 @@
/*
* xrick/src/system.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <SDL.h>
#include <stdarg.h> /* args for sys_panic */
#include <fcntl.h> /* fcntl in sys_panic */
#include <stdio.h> /* printf */
#include <stdlib.h>
#include <signal.h>
#include "system.h"
/*
* Panic
*/
void
sys_panic(char *err, ...)
{
va_list argptr;
char s[1024];
/* change stdin to non blocking */
/*fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);*/
/* NOTE HPUX: use ... is it OK on Linux ? */
/* fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NDELAY); */
/* prepare message */
va_start(argptr, err);
vsprintf(s, err, argptr);
va_end(argptr);
/* print message and die */
printf("%s\npanic!\n", s);
exit(1);
}
/*
* Print a message
*/
void
sys_printf(char *msg, ...)
{
va_list argptr;
char s[1024];
/* change stdin to non blocking */
/*fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);*/
/* NOTE HPUX: use ... is it OK on Linux ? */
/* fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NDELAY); */
/* prepare message */
va_start(argptr, msg);
vsprintf(s, msg, argptr);
va_end(argptr);
printf(s);
}
/*
* Return number of microseconds elapsed since first call
*/
U32
sys_gettime(void)
{
static U32 ticks_base = 0;
U32 ticks;
ticks = SDL_GetTicks();
if (!ticks_base)
ticks_base = ticks;
return ticks - ticks_base;
}
/*
* Sleep a number of microseconds
*/
void
sys_sleep(int s)
{
SDL_Delay(s);
}
/*
* Initialize system
*/
void
sys_init(int argc, char **argv)
{
sysarg_init(argc, argv);
sysvid_init();
#ifdef ENABLE_JOYSTICK
sysjoy_init();
#endif
#ifdef ENABLE_SOUND
if (sysarg_args_nosound == 0)
syssnd_init();
#endif
atexit(sys_shutdown);
signal(SIGINT, exit);
signal(SIGTERM, exit);
}
/*
* Shutdown system
*/
void
sys_shutdown(void)
{
#ifdef ENABLE_SOUND
syssnd_shutdown();
#endif
#ifdef ENABLE_JOYSTICK
sysjoy_shutdown();
#endif
sysvid_shutdown();
}
/* eof */

381
src/sysvid.c Normal file
View File

@ -0,0 +1,381 @@
/*
* xrick/src/sysvid.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <stdlib.h> /* malloc */
#include <SDL.h>
#include "system.h"
#include "game.h"
#include "img.h"
#include "debug.h"
#ifdef __MSVC__
#include <memory.h> /* memset */
#endif
U8 *sysvid_fb; /* frame buffer */
rect_t SCREENRECT = {0, 0, SYSVID_WIDTH, SYSVID_HEIGHT, NULL}; /* whole fb */
static SDL_Color palette[256];
static SDL_Surface *screen;
static U32 videoFlags;
static U8 zoom = SYSVID_ZOOM; /* actual zoom level */
static U8 szoom = 0; /* saved zoom level */
static U8 fszoom = 0; /* fullscreen zoom level */
#include "img_icon.e"
/*
* color tables
*/
#ifdef GFXPC
static U8 RED[] = { 0x00, 0x50, 0xf0, 0xf0, 0x00, 0x50, 0xf0, 0xf0 };
static U8 GREEN[] = { 0x00, 0xf8, 0x50, 0xf8, 0x00, 0xf8, 0x50, 0xf8 };
static U8 BLUE[] = { 0x00, 0x50, 0x50, 0x50, 0x00, 0xf8, 0xf8, 0xf8 };
#endif
#ifdef GFXST
static U8 RED[] = { 0x00, 0xd8, 0xb0, 0xf8,
0x20, 0x00, 0x00, 0x20,
0x48, 0x48, 0x90, 0xd8,
0x48, 0x68, 0x90, 0xb0,
/* cheat colors */
0x50, 0xe0, 0xc8, 0xf8,
0x68, 0x50, 0x50, 0x68,
0x80, 0x80, 0xb0, 0xe0,
0x80, 0x98, 0xb0, 0xc8
};
static U8 GREEN[] = { 0x00, 0x00, 0x6c, 0x90,
0x24, 0x48, 0x6c, 0x48,
0x6c, 0x24, 0x48, 0x6c,
0x48, 0x6c, 0x90, 0xb4,
/* cheat colors */
0x54, 0x54, 0x9c, 0xb4,
0x6c, 0x84, 0x9c, 0x84,
0x9c, 0x6c, 0x84, 0x9c,
0x84, 0x9c, 0xb4, 0xcc
};
static U8 BLUE[] = { 0x00, 0x00, 0x68, 0x68,
0x20, 0xb0, 0xd8, 0x00,
0x20, 0x00, 0x00, 0x00,
0x48, 0x68, 0x90, 0xb0,
/* cheat colors */
0x50, 0x50, 0x98, 0x98,
0x68, 0xc8, 0xe0, 0x50,
0x68, 0x50, 0x50, 0x50,
0x80, 0x98, 0xb0, 0xc8};
#endif
/*
* Initialize screen
*/
static
SDL_Surface *initScreen(U16 w, U16 h, U8 bpp, U32 flags)
{
return SDL_SetVideoMode(w, h, bpp, flags);
}
void
sysvid_setPalette(img_color_t *pal, U16 n)
{
U16 i;
for (i = 0; i < n; i++) {
palette[i].r = pal[i].r;
palette[i].g = pal[i].g;
palette[i].b = pal[i].b;
}
SDL_SetColors(screen, (SDL_Color *)&palette, 0, n);
}
void
sysvid_restorePalette()
{
SDL_SetColors(screen, (SDL_Color *)&palette, 0, 256);
}
void
sysvid_setGamePalette()
{
U8 i;
img_color_t pal[256];
for (i = 0; i < 32; ++i) {
pal[i].r = RED[i];
pal[i].g = GREEN[i];
pal[i].b = BLUE[i];
}
sysvid_setPalette(pal, 32);
}
/*
* Initialize video modes
*/
void
sysvid_chkvm(void)
{
SDL_Rect **modes;
U8 i, mode = 0;
IFDEBUG_VIDEO(sys_printf("xrick/video: checking video modes\n"););
modes = SDL_ListModes(NULL, videoFlags|SDL_FULLSCREEN);
if (modes == (SDL_Rect **)0)
sys_panic("xrick/video: SDL can not find an appropriate video mode\n");
if (modes == (SDL_Rect **)-1) {
/* can do what you want, everything is possible */
IFDEBUG_VIDEO(sys_printf("xrick/video: SDL says any video mode is OK\n"););
fszoom = 1;
}
else {
IFDEBUG_VIDEO(sys_printf("xrick/video: SDL says, use these modes:\n"););
for (i = 0; modes[i]; i++) {
IFDEBUG_VIDEO(sys_printf(" %dx%d\n", modes[i]->w, modes[i]->h););
if (modes[i]->w <= modes[mode]->w && modes[i]->w >= SYSVID_WIDTH &&
modes[i]->h * SYSVID_WIDTH >= modes[i]->w * SYSVID_HEIGHT) {
mode = i;
fszoom = modes[mode]->w / SYSVID_WIDTH;
}
}
if (fszoom != 0) {
IFDEBUG_VIDEO(
sys_printf("xrick/video: fullscreen at %dx%d w/zoom=%d\n",
modes[mode]->w, modes[mode]->h, fszoom);
);
}
else {
IFDEBUG_VIDEO(
sys_printf("xrick/video: can not compute fullscreen zoom, use 1\n");
);
fszoom = 1;
}
}
}
/*
* Initialise video
*/
void
sysvid_init(void)
{
SDL_Surface *s;
U8 *mask, tpix;
U32 len, i;
IFDEBUG_VIDEO(printf("xrick/video: start\n"););
/* SDL */
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0)
sys_panic("xrick/video: could not init SDL\n");
/* various WM stuff */
SDL_WM_SetCaption("xrick", "xrick");
SDL_ShowCursor(SDL_DISABLE);
s = SDL_CreateRGBSurfaceFrom(IMG_ICON->pixels, IMG_ICON->w, IMG_ICON->h, 8, IMG_ICON->w, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
SDL_SetColors(s, (SDL_Color *)IMG_ICON->colors, 0, IMG_ICON->ncolors);
tpix = *(IMG_ICON->pixels);
IFDEBUG_VIDEO(
sys_printf("xrick/video: icon is %dx%d\n",
IMG_ICON->w, IMG_ICON->h);
sys_printf("xrick/video: icon transp. color is #%d (%d,%d,%d)\n", tpix,
IMG_ICON->colors[tpix].r,
IMG_ICON->colors[tpix].g,
IMG_ICON->colors[tpix].b);
);
/*
* old dirty stuff to implement transparency. SetColorKey does it
* on Windows w/out problems. Linux? FIXME!
len = IMG_ICON->w * IMG_ICON->h;
mask = (U8 *)malloc(len/8);
memset(mask, 0, len/8);
for (i = 0; i < len; i++)
if (IMG_ICON->pixels[i] != tpix) mask[i/8] |= (0x80 >> (i%8));
*/
/*
* FIXME
* Setting a mask produces strange results depending on the
* Window Manager. On fvwm2 it is shifted to the right ...
*/
/*SDL_WM_SetIcon(s, mask);*/
SDL_SetColorKey(s,
SDL_SRCCOLORKEY,
SDL_MapRGB(s->format,IMG_ICON->colors[tpix].r,IMG_ICON->colors[tpix].g,IMG_ICON->colors[tpix].b));
SDL_WM_SetIcon(s, NULL);
/* video modes and screen */
videoFlags = SDL_HWSURFACE|SDL_HWPALETTE;
sysvid_chkvm(); /* check video modes */
if (sysarg_args_zoom)
zoom = sysarg_args_zoom;
if (sysarg_args_fullscreen) {
videoFlags |= SDL_FULLSCREEN;
szoom = zoom;
zoom = fszoom;
}
screen = initScreen(SYSVID_WIDTH * zoom,
SYSVID_HEIGHT * zoom,
8, videoFlags);
/*
* create v_ frame buffer
*/
sysvid_fb = malloc(SYSVID_WIDTH * SYSVID_HEIGHT);
if (!sysvid_fb)
sys_panic("xrick/video: sysvid_fb malloc failed\n");
IFDEBUG_VIDEO(printf("xrick/video: ready\n"););
}
/*
* Shutdown video
*/
void
sysvid_shutdown(void)
{
free(sysvid_fb);
sysvid_fb = NULL;
SDL_Quit();
}
/*
* Update screen
* NOTE errors processing ?
*/
void
sysvid_update(rect_t *rects)
{
static SDL_Rect area;
U16 x, y, xz, yz;
U8 *p, *q, *p0, *q0;
if (rects == NULL)
return;
if (SDL_LockSurface(screen) == -1)
sys_panic("xrick/panic: SDL_LockSurface failed\n");
while (rects) {
p0 = sysvid_fb;
p0 += rects->x + rects->y * SYSVID_WIDTH;
q0 = (U8 *)screen->pixels;
q0 += (rects->x + rects->y * SYSVID_WIDTH * zoom) * zoom;
for (y = rects->y; y < rects->y + rects->height; y++) {
for (yz = 0; yz < zoom; yz++) {
p = p0;
q = q0;
for (x = rects->x; x < rects->x + rects->width; x++) {
for (xz = 0; xz < zoom; xz++) {
*q = *p;
q++;
}
p++;
}
q0 += SYSVID_WIDTH * zoom;
}
p0 += SYSVID_WIDTH;
}
IFDEBUG_VIDEO2(
for (y = rects->y; y < rects->y + rects->height; y++)
for (yz = 0; yz < zoom; yz++) {
p = (U8 *)screen->pixels + rects->x * zoom + (y * zoom + yz) * SYSVID_WIDTH * zoom;
*p = 0x01;
*(p + rects->width * zoom - 1) = 0x01;
}
for (x = rects->x; x < rects->x + rects->width; x++)
for (xz = 0; xz < zoom; xz++) {
p = (U8 *)screen->pixels + x * zoom + xz + rects->y * zoom * SYSVID_WIDTH * zoom;
*p = 0x01;
*(p + ((rects->height * zoom - 1) * zoom) * SYSVID_WIDTH) = 0x01;
}
);
area.x = rects->x * zoom;
area.y = rects->y * zoom;
area.h = rects->height * zoom;
area.w = rects->width * zoom;
SDL_UpdateRects(screen, 1, &area);
rects = rects->next;
}
SDL_UnlockSurface(screen);
}
/*
* Clear screen
* (077C)
*/
void
sysvid_clear(void)
{
memset(sysvid_fb, 0, SYSVID_WIDTH * SYSVID_HEIGHT);
}
/*
* Zoom
*/
void
sysvid_zoom(S8 z)
{
if (!(videoFlags & SDL_FULLSCREEN) &&
((z < 0 && zoom > 1) ||
(z > 0 && zoom < SYSVID_MAXZOOM))) {
zoom += z;
screen = initScreen(SYSVID_WIDTH * zoom,
SYSVID_HEIGHT * zoom,
screen->format->BitsPerPixel, videoFlags);
sysvid_restorePalette();
sysvid_update(&SCREENRECT);
}
}
/*
* Toggle fullscreen
*/
void
sysvid_toggleFullscreen(void)
{
videoFlags ^= SDL_FULLSCREEN;
if (videoFlags & SDL_FULLSCREEN) { /* go fullscreen */
szoom = zoom;
zoom = fszoom;
}
else { /* go window */
zoom = szoom;
}
screen = initScreen(SYSVID_WIDTH * zoom,
SYSVID_HEIGHT * zoom,
screen->format->BitsPerPixel, videoFlags);
sysvid_restorePalette();
sysvid_update(&SCREENRECT);
}
/* eof */

1320
src/unzip.c Normal file

File diff suppressed because it is too large Load Diff

209
src/util.c Normal file
View File

@ -0,0 +1,209 @@
/*
* xrick/src/util.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include <stdlib.h> /* NULL */
#include "system.h"
#include "config.h"
#include "game.h"
#include "util.h"
#include "ents.h"
#include "e_rick.h"
#include "maps.h"
/*
* Full box test.
*
* ASM 1199
*
* e: entity to test against.
* x,y: coordinates to test.
* ret: TRUE/(x,y) is within e's space, FALSE/not.
*/
U8
u_fboxtest(U8 e, S16 x, S16 y)
{
if (ent_ents[e].x >= x ||
ent_ents[e].x + ent_ents[e].w < x ||
ent_ents[e].y >= y ||
ent_ents[e].y + ent_ents[e].h < y)
return FALSE;
else
return TRUE;
}
/*
* Box test (then whole e2 is checked agains the center of e1).
*
* ASM 113E
*
* e1: entity to test against (corresponds to DI in asm code).
* e2: entity to test (corresponds to SI in asm code).
* ret: TRUE/intersect, FALSE/not.
*/
U8
u_boxtest(U8 e1, U8 e2)
{
/* rick is special (may be crawling) */
if (e1 == E_RICK_NO)
return e_rick_boxtest(e2);
/*
* entity 1: x+0x05 to x+0x011, y to y+0x14
* entity 2: x to x+ .w, y to y+ .h
*/
if (ent_ents[e1].x + 0x11 < ent_ents[e2].x ||
ent_ents[e1].x + 0x05 > ent_ents[e2].x + ent_ents[e2].w ||
ent_ents[e1].y + 0x14 < ent_ents[e2].y ||
ent_ents[e1].y > ent_ents[e2].y + ent_ents[e2].h - 1)
return FALSE;
else
return TRUE;
}
/*
* Compute the environment flag.
*
* ASM 0FBC if !crawl, else 103E
*
* x, y: coordinates where to compute the environment flag
* crawl: is rick crawling?
* rc0: anything CHANGED to the environment flag for crawling (6DBA)
* rc1: anything CHANGED to the environment flag (6DAD)
*/
void
u_envtest(S16 x, S16 y, U8 crawl, U8 *rc0, U8 *rc1)
{
U8 i, xx;
/* prepare for ent #0 test */
ent_ents[ENT_ENTSNUM].x = x;
ent_ents[ENT_ENTSNUM].y = y;
i = 1;
if (!crawl) i++;
if (y & 0x0004) i++;
x += 4;
xx = (U8)x; /* FIXME? */
x = x >> 3; /* from pixels to tiles */
y = y >> 3; /* from pixels to tiles */
*rc0 = *rc1 = 0;
if (xx & 0x07) { /* tiles columns alignment */
if (crawl) {
*rc0 |= (map_eflg[map_map[y][x]] &
(MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
*rc0 |= (map_eflg[map_map[y][x + 1]] &
(MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
*rc0 |= (map_eflg[map_map[y][x + 2]] &
(MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
y++;
}
do {
*rc1 |= (map_eflg[map_map[y][x]] &
(MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
MAP_EFLG_LETHAL|MAP_EFLG_01));
*rc1 |= (map_eflg[map_map[y][x + 1]] &
(MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
MAP_EFLG_LETHAL|MAP_EFLG_CLIMB|MAP_EFLG_01));
*rc1 |= (map_eflg[map_map[y][x + 2]] &
(MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
MAP_EFLG_LETHAL|MAP_EFLG_01));
y++;
} while (--i > 0);
*rc1 |= (map_eflg[map_map[y][x]] &
(MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP|MAP_EFLG_FGND|
MAP_EFLG_LETHAL|MAP_EFLG_01));
*rc1 |= (map_eflg[map_map[y][x + 1]]);
*rc1 |= (map_eflg[map_map[y][x + 2]] &
(MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP|MAP_EFLG_FGND|
MAP_EFLG_LETHAL|MAP_EFLG_01));
}
else {
if (crawl) {
*rc0 |= (map_eflg[map_map[y][x]] &
(MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
*rc0 |= (map_eflg[map_map[y][x + 1]] &
(MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP));
y++;
}
do {
*rc1 |= (map_eflg[map_map[y][x]] &
(MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
MAP_EFLG_LETHAL|MAP_EFLG_CLIMB|MAP_EFLG_01));
*rc1 |= (map_eflg[map_map[y][x + 1]] &
(MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_FGND|
MAP_EFLG_LETHAL|MAP_EFLG_CLIMB|MAP_EFLG_01));
y++;
} while (--i > 0);
*rc1 |= (map_eflg[map_map[y][x]]);
*rc1 |= (map_eflg[map_map[y][x + 1]]);
}
/*
* If not lethal yet, and there's an entity on slot zero, and (x,y)
* boxtests this entity, then raise SOLID flag. This is how we make
* sure that no entity can move over the entity that is on slot zero.
*
* Beware! When game_cheat2 is set, this means that a block can
* move over rick without killing him -- but then rick is trapped
* because the block is solid.
*/
if (!(*rc1 & MAP_EFLG_LETHAL)
&& ent_ents[0].n
&& u_boxtest(ENT_ENTSNUM, 0)) {
*rc1 |= MAP_EFLG_SOLID;
}
/* When game_cheat2 is set, the environment can not be lethal. */
#ifdef ENABLE_CHEATS
if (game_cheat2) *rc1 &= ~MAP_EFLG_LETHAL;
#endif
}
/*
* Check if x,y is within e trigger box.
*
* ASM 126F
* return: FALSE if not in box, TRUE if in box.
*/
U8
u_trigbox(U8 e, S16 x, S16 y)
{
U16 xmax, ymax;
xmax = ent_ents[e].trig_x + (ent_entdata[ent_ents[e].n & 0x7F].trig_w << 3);
ymax = ent_ents[e].trig_y + (ent_entdata[ent_ents[e].n & 0x7F].trig_h << 3);
if (xmax > 0xFF) xmax = 0xFF;
if (x <= ent_ents[e].trig_x || x > xmax ||
y <= ent_ents[e].trig_y || y > ymax)
return FALSE;
else
return TRUE;
}
/* eof */

36
src/xrick.c Normal file
View File

@ -0,0 +1,36 @@
/*
* xrick/src/xrick.c
*
* Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
*
* The use and distribution terms for this software are contained in the file
* named README, which can be found in the root of this distribution. By
* using this software in any fashion, you are agreeing to be bound by the
* terms of this license.
*
* You must not remove this notice, or any other, from this software.
*/
#include "system.h"
#include "game.h"
#include <SDL.h>
/*
* main
*/
int
main(int argc, char *argv[])
{
sys_init(argc, argv);
if (sysarg_args_data)
data_setpath(sysarg_args_data);
else
data_setpath("data.zip");
game_run();
data_closepath();
sys_shutdown();
return 0;
}
/* eof */

23
src/xrick.rc Normal file
View File

@ -0,0 +1,23 @@
// xrick/src/xrick.rc
//
// Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
//
// The use and distribution terms for this software are contained in the file
// named README, which can be found in the root of this distribution. By
// using this software in any fashion, you are agreeing to be bound by the
// terms of this license.
//
// You must not remove this notice, or any other, from this software.
//
#include "..\include\config.h"
#ifdef GFXST
XRICK_ICON ICON DISCARDABLE "xrickST.ico"
#endif
#ifdef GFXPC
XRICK_ICON ICON DISCARDABLE "xrickPC.ico"
#endif
// eof

BIN
src/xrickPC.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

BIN
src/xrickST.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
xrick.6.gz Normal file

Binary file not shown.

393
xrick.dsp Normal file
View File

@ -0,0 +1,393 @@
# Microsoft Developer Studio Project File - Name="xrick" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=xrick - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "xrick.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "xrick.mak" CFG="xrick - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "xrick - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "xrick - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "xrick - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "NDEBUG"
# ADD RSC /l 0x40c /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "xrick - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "_DEBUG"
# ADD RSC /l 0x40c /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "xrick - Win32 Release"
# Name "xrick - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\src\control.c
# End Source File
# Begin Source File
SOURCE=.\src\dat_ents.c
# End Source File
# Begin Source File
SOURCE=.\src\dat_maps.c
# End Source File
# Begin Source File
SOURCE=.\src\dat_picsPC.c
# End Source File
# Begin Source File
SOURCE=.\src\dat_picsST.c
# End Source File
# Begin Source File
SOURCE=.\src\dat_screens.c
# End Source File
# Begin Source File
SOURCE=.\src\dat_snd.c
# End Source File
# Begin Source File
SOURCE=.\src\dat_spritesPC.c
# End Source File
# Begin Source File
SOURCE=.\src\dat_spritesST.c
# End Source File
# Begin Source File
SOURCE=.\src\dat_tilesPC.c
# End Source File
# Begin Source File
SOURCE=.\src\dat_tilesST.c
# End Source File
# Begin Source File
SOURCE=.\src\data.c
# End Source File
# Begin Source File
SOURCE=.\src\devtools.c
# End Source File
# Begin Source File
SOURCE=.\src\draw.c
# End Source File
# Begin Source File
SOURCE=.\src\e_bomb.c
# End Source File
# Begin Source File
SOURCE=.\src\e_bonus.c
# End Source File
# Begin Source File
SOURCE=.\src\e_box.c
# End Source File
# Begin Source File
SOURCE=.\src\e_bullet.c
# End Source File
# Begin Source File
SOURCE=.\src\e_rick.c
# End Source File
# Begin Source File
SOURCE=.\src\e_sbonus.c
# End Source File
# Begin Source File
SOURCE=.\src\e_them.c
# End Source File
# Begin Source File
SOURCE=.\src\ents.c
# End Source File
# Begin Source File
SOURCE=.\src\game.c
# End Source File
# Begin Source File
SOURCE=.\src\maps.c
# End Source File
# Begin Source File
SOURCE=.\src\rects.c
# End Source File
# Begin Source File
SOURCE=.\src\scr_gameover.c
# End Source File
# Begin Source File
SOURCE=.\src\scr_getname.c
# End Source File
# Begin Source File
SOURCE=.\src\scr_imain.c
# End Source File
# Begin Source File
SOURCE=.\src\scr_imap.c
# End Source File
# Begin Source File
SOURCE=.\src\scr_pause.c
# End Source File
# Begin Source File
SOURCE=.\src\scr_xrick.c
# End Source File
# Begin Source File
SOURCE=.\src\scroller.c
# End Source File
# Begin Source File
SOURCE=.\src\sysarg.c
# End Source File
# Begin Source File
SOURCE=.\src\sysevt.c
# End Source File
# Begin Source File
SOURCE=.\src\sysjoy.c
# End Source File
# Begin Source File
SOURCE=.\src\syskbd.c
# End Source File
# Begin Source File
SOURCE=.\src\syssnd.c
# End Source File
# Begin Source File
SOURCE=.\src\system.c
# End Source File
# Begin Source File
SOURCE=.\src\sysvid.c
# End Source File
# Begin Source File
SOURCE=.\src\unzip.c
# End Source File
# Begin Source File
SOURCE=.\src\util.c
# End Source File
# Begin Source File
SOURCE=.\src\xrick.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\include\config.h
# End Source File
# Begin Source File
SOURCE=.\include\control.h
# End Source File
# Begin Source File
SOURCE=.\include\data.h
# End Source File
# Begin Source File
SOURCE=.\include\debug.h
# End Source File
# Begin Source File
SOURCE=.\include\devtools.h
# End Source File
# Begin Source File
SOURCE=.\include\draw.h
# End Source File
# Begin Source File
SOURCE=.\include\e_bomb.h
# End Source File
# Begin Source File
SOURCE=.\include\e_bonus.h
# End Source File
# Begin Source File
SOURCE=.\include\e_box.h
# End Source File
# Begin Source File
SOURCE=.\include\e_bullet.h
# End Source File
# Begin Source File
SOURCE=.\include\e_rick.h
# End Source File
# Begin Source File
SOURCE=.\include\e_sbonus.h
# End Source File
# Begin Source File
SOURCE=.\include\e_them.h
# End Source File
# Begin Source File
SOURCE=.\include\ents.h
# End Source File
# Begin Source File
SOURCE=.\include\game.h
# End Source File
# Begin Source File
SOURCE=.\include\img.h
# End Source File
# Begin Source File
SOURCE=.\include\maps.h
# End Source File
# Begin Source File
SOURCE=.\include\pics.h
# End Source File
# Begin Source File
SOURCE=.\include\rects.h
# End Source File
# Begin Source File
SOURCE=.\include\screens.h
# End Source File
# Begin Source File
SOURCE=.\include\scroller.h
# End Source File
# Begin Source File
SOURCE=.\include\sprites.h
# End Source File
# Begin Source File
SOURCE=.\include\syssnd.h
# End Source File
# Begin Source File
SOURCE=.\include\system.h
# End Source File
# Begin Source File
SOURCE=.\include\sysvid.h
# End Source File
# Begin Source File
SOURCE=.\include\tiles.h
# End Source File
# Begin Source File
SOURCE=.\include\unzip.h
# End Source File
# Begin Source File
SOURCE=.\include\util.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\src\xrick.rc
# End Source File
# Begin Source File
SOURCE=.\src\xrickPC.ico
# End Source File
# Begin Source File
SOURCE=.\src\xrickST.ico
# End Source File
# End Group
# End Target
# End Project