From a7e9311fa0f5d9c2364105c2ea676d9bfb201610 Mon Sep 17 00:00:00 2001 From: Lars Poeschel Date: Mon, 31 May 2021 22:29:15 +0200 Subject: [PATCH 1/2] .gitignore: Ignore *.swp (vim) and tags files Now *.swp files that are used by vim and tags file used by ctags are ignored. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 045dba1..75271df 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ bin/ *.exe opentitus *.dge +*.swp +tags From 72743cf1e279c8dcc179f5f3e49cda0430ec93b7 Mon Sep 17 00:00:00 2001 From: Lars Poeschel Date: Mon, 31 May 2021 22:31:54 +0200 Subject: [PATCH 2/2] Fix compiler errors and warnings (gcc 10) This involves declaring shared (included) variables as extern in headers and defining them somewhere. The same for functions. Also define missing return types on functions. And this required some reordering of functions inside of the source files so that they appear before they are used. No code is changed with this commit. Code / Variables are only moved. --- include/audio.h | 4 +- include/backbuffer.h | 4 +- include/draw.h | 1 + include/enemies.h | 2 + include/engine.h | 3 + include/fonts.h | 3 - include/gates.h | 2 + include/globals.h | 83 +--- include/level.h | 2 + include/objects.h | 5 +- include/original.h | 46 +-- include/player.h | 28 +- include/reset.h | 3 + include/scroll.h | 16 + include/settings.h | 62 +-- include/sprites.h | 1 + include/tile_animation.h | 28 ++ include/tituserror.h | 4 +- opentitus.c | 119 +++--- src/audio.c | 89 ++--- src/draw.c | 252 ++++++------ src/elevators.c | 19 +- src/enemies.c | 265 ++++++------- src/engine.c | 182 ++++----- src/fonts.c | 4 + src/gates.c | 77 ++-- src/level.c | 3 + src/menu.c | 271 ++++++------- src/objects.c | 97 ++--- src/original.c | 28 ++ src/player.c | 822 ++++++++++++++++++++------------------- src/reset.c | 203 +++++----- src/scroll.c | 60 +-- src/settings.c | 34 ++ src/sprites.c | 65 ++-- src/tile_animation.c | 3 +- src/viewimage.c | 1 + 37 files changed, 1543 insertions(+), 1348 deletions(-) create mode 100644 include/tile_animation.h diff --git a/include/audio.h b/include/audio.h index 2f7988b..9ea60d1 100644 --- a/include/audio.h +++ b/include/audio.h @@ -33,13 +33,13 @@ //#include "SDL/SDL_mixer.h" int initaudio(); -int freeaudio(); +void freeaudio(); int SELECT_MUSIC(int song_number); int WAIT_SONG(); int FX_START(int fx_number); int RETURN_MUSIC(); int startmusic(); -int refreshaudio(); +void refreshaudio(); /* diff --git a/include/backbuffer.h b/include/backbuffer.h index bfa627d..fb30499 100644 --- a/include/backbuffer.h +++ b/include/backbuffer.h @@ -31,7 +31,7 @@ #include "SDL/SDL.h" -SDL_Surface *screen; //Backbuffer -SDL_Surface *tilescreen; //Tile screen +extern SDL_Surface *screen; //Backbuffer +extern SDL_Surface *tilescreen; //Tile screen #endif diff --git a/include/draw.h b/include/draw.h index 159dc0f..5f51909 100644 --- a/include/draw.h +++ b/include/draw.h @@ -52,6 +52,7 @@ int view_password(TITUS_level *level, uint8 level_index); int loadpixelformat(SDL_PixelFormat **pixelformat); int loadpixelformat_font(SDL_PixelFormat **pixelformat); int freepixelformat(SDL_PixelFormat **pixelformat); +void DISPLAY_SPRITES(TITUS_level *level); #endif diff --git a/include/enemies.h b/include/enemies.h index 4069566..d1282ed 100644 --- a/include/enemies.h +++ b/include/enemies.h @@ -37,9 +37,11 @@ #include "SDL/SDL.h" #include "level.h" +extern uint8 INVULNERABLE_FLAG; //When non-zero, boss is invulnerable int MOVE_NMI(TITUS_level *level); int SET_NMI(TITUS_level *level); int MOVE_TRASH(TITUS_level *level); +int updateenemysprite(TITUS_level *level, TITUS_enemy *enemy, int16 number, bool clearflags); #endif diff --git a/include/engine.h b/include/engine.h index b26ca45..40a9f7d 100644 --- a/include/engine.h +++ b/include/engine.h @@ -31,6 +31,9 @@ #include "SDL/SDL.h" +extern bool GAMEOVER_FLAG; //triggers a game over +extern uint16 IMAGE_COUNTER; //Increased every loop in game loop (0 to 0x0FFF) + int playtitus(int firstlevel); #endif diff --git a/include/fonts.h b/include/fonts.h index 5d06800..3396897 100644 --- a/include/fonts.h +++ b/include/fonts.h @@ -53,9 +53,6 @@ struct _TITUS_font { void *sub[256]; //May be malloced }; -TITUS_font *font; //Malloced -SDL_Surface *font_undefined; //Pointer - int loadfonts(void); int freefonts(void); diff --git a/include/gates.h b/include/gates.h index 729d8e0..f0d4dbd 100644 --- a/include/gates.h +++ b/include/gates.h @@ -32,6 +32,8 @@ #include "SDL/SDL.h" #include "level.h" +extern int16 XLIMIT; //The engine will not scroll past this tile before the player have crossed the line (X) + int CROSSING_GATE(TITUS_level *level); //Check and handle level completion, and if the player does a kneestand on a secret entrance int CLOSE_SCREEN(); int OPEN_SCREEN(); diff --git a/include/globals.h b/include/globals.h index 97cb331..6f92d65 100644 --- a/include/globals.h +++ b/include/globals.h @@ -149,88 +149,31 @@ #define int16 signed short int -uint8 RESETLEVEL_FLAG; -bool GAMEOVER_FLAG; //triggers a game over -uint8 BAR_FLAG; //timer for health bar -bool X_FLAG; //true if left or right key is pressed -bool Y_FLAG; //true if up or down key is pressed -uint8 CHOC_FLAG; //headache timer -uint8 action; //player sprite array -uint8 KICK_FLAG; //hit/burn timer -bool GRANDBRULE_FLAG; //If set, player will be "burned" when hit (fireballs) -bool LADDER_FLAG; //True if in a ladder -bool PRIER_FLAG; //True if player is forced into kneestanding because of low ceiling -uint8 SAUT_FLAG; //6 if free fall or in the middle of a jump, decremented if on solid surface. Must be 0 to initiate a jump. -uint8 LAST_ORDER; //Last action (kneestand + jump = silent walk) -uint8 FURTIF_FLAG; //Silent walk timer -bool DROP_FLAG; //True if an object is throwed forward -bool DROPREADY_FLAG; -bool CARRY_FLAG; //true if carrying something (add 16 to player sprite) -bool POSEREADY_FLAG; -uint8 ACTION_TIMER; //Frames since last action change -//TITUS_sprite sprite; //Player sprite -//TITUS_sprite sprite2; //Secondary player sprite (throwed objects, "hit" when object hits an enemy, smoke when object hits the floor) -uint8 INVULNERABLE_FLAG; //When non-zero, boss is invulnerable -uint8 TAPISFLY_FLAG; //When non-zero, the flying carpet is flying -uint8 CROSS_FLAG; //When non-zero, fall through certain floors (after key down) -uint8 GRAVITY_FLAG; //When zero, skip object gravity function -uint8 FUME_FLAG; //Smoke when object hits the floor -Uint8 *keystate; //Keyboard state -uint8 LIFE; //Lives -uint8 YFALL; -bool POCKET_FLAG; -bool PERMUT_FLAG; //If false, there are no animated tiles on the screen? -uint8 loop_cycle; //Increased every loop in game loop -uint8 tile_anim; //Current tile animation (0-1-2), changed every 4th game loop cycle -uint8 BITMAP_X; //Screen offset (X) in tiles -uint8 BITMAP_XM; //Point to the left tile in the tile screen (0 to 19) -uint8 BITMAP_Y; //Screen offset (Y) in tiles -uint8 BITMAP_YM; //Point to the top tile in the tile screen (0 to 11) -bool XSCROLL_CENTER; //If true, the screen will scroll in X -int16 XLIMIT_SCROLL; //If scrolling: scroll until player is in this tile (X) -int16 XLIMIT; //The engine will not scroll past this tile before the player have crossed the line (X) -bool YSCROLL_CENTER; //If true, the screen will scroll in Y -uint8 YLIMIT_SCROLL; //If scrolling: scroll until player is in this tile (Y) -uint8 ALTITUDE_ZERO; //The engine will not scroll below this tile before the player have gone below (Y) -int LAST_CLOCK; //Used for fixed framerate -uint16 IMAGE_COUNTER; //Increased every loop in game loop (0 to 0x0FFF) -int8 SENSX; //1: walk right, 0: stand still, -1: walk left, triggers the ACTION_TIMER if it changes -uint8 SAUT_COUNT; //Incremented from 0 to 3 when accelerating while jumping, stop acceleration upwards if >= 3 -bool NOSCROLL_FLAG; -bool NEWLEVEL_FLAG; //Finish a level -uint8 BIGNMI_NBR; //Number of bosses that needs to be killed to finish -uint8 TAUPE_FLAG; //Used for enemies walking and popping up -uint8 TAPISWAIT_FLAG; //Flying carpet state -uint8 SEECHOC_FLAG; //Counter when hit -bool NFC_FLAG; //Skip NO_FAST_CPU -uint8 BIGNMI_POWER; //Lives of the boss -bool boss_alive; //True if the boss is alive -uint8 AUDIOMODE; - -bool GODMODE; //If true, the player will not interfere with the enemies -bool NOCLIP; //If true, the player will move noclip -bool DISPLAYLOOPTIME; //If true, display loop time in milliseconds -uint8 LOOPTIME; //Loop time -uint8 SUBTIME[16]; //Sub time -uint16 FPS; //Frames pr second -uint16 FPS_LAST; //Frames pr second -uint16 LAST_CLOCK_CORR; //Correction to LAST_CLOCK +extern bool NOSCROLL_FLAG; +extern uint8 TAUPE_FLAG; //Used for enemies walking and popping up +extern uint8 TAPISWAIT_FLAG; //Flying carpet state +extern uint8 SEECHOC_FLAG; //Counter when hit +extern uint8 BIGNMI_POWER; //Lives of the boss +extern bool boss_alive; //True if the boss is alive +extern uint8 AUDIOMODE; + +extern bool GODMODE; //If true, the player will not interfere with the enemies +extern bool NOCLIP; //If true, the player will move noclip +extern bool DISPLAYLOOPTIME; //If true, display loop time in milliseconds typedef struct { bool enabled; uint16 NUM; } SPRITE; -SPRITE sprites[256]; +//SPRITE sprites[256]; typedef struct { bool enabled; uint16 NUM; } SPRITEDATA; -SPRITEDATA spritedata[256]; - -uint16 level_code[16]; +//SPRITEDATA spritedata[256]; #endif diff --git a/include/level.h b/include/level.h index bb5fe05..b313009 100644 --- a/include/level.h +++ b/include/level.h @@ -231,6 +231,8 @@ struct _TITUS_level { }; +extern uint8 ALTITUDE_ZERO; //The engine will not scroll below this tile before the player have gone below (Y) + int loadlevel(TITUS_level *level, unsigned char *leveldata, int leveldatasize, TITUS_spritedata **spritedata, TITUS_spritecache *spritecache, TITUS_objectdata **objectdata); int freelevel(TITUS_level *level); uint8 get_horizflag(TITUS_level *level, int16 tileY, int16 tileX); diff --git a/include/objects.h b/include/objects.h index 369f1fb..98c3662 100644 --- a/include/objects.h +++ b/include/objects.h @@ -32,7 +32,10 @@ #include "SDL/SDL.h" #include "level.h" -int move_objects(TITUS_level *level); +extern uint8 TAPISFLY_FLAG; //When non-zero, the flying carpet is flying +extern uint8 GRAVITY_FLAG; //When zero, skip object gravity function + +void move_objects(TITUS_level *level); bool SPRITES_VS_SPRITES (TITUS_level *level, TITUS_sprite *sprite1, TITUS_sprite *sprite1ref, TITUS_object **object2); //check if there is an object below that can support the input object int updateobjectsprite(TITUS_level *level, TITUS_object *obj, int16 number, bool clearflags); int loadobjects(TITUS_objectdata ***objects, uint16 *count); diff --git a/include/original.h b/include/original.h index 57b87b2..b51d628 100644 --- a/include/original.h +++ b/include/original.h @@ -44,32 +44,32 @@ int initoriginal(); int16 getlevelid(int16 levelnumber); -SDL_Color orig_palette_colour[16]; -SDL_Color orig_palette_level_colour[16]; -SDL_Color orig_palette_font_colour[16]; +extern SDL_Color orig_palette_colour[16]; +extern SDL_Color orig_palette_level_colour[16]; +extern SDL_Color orig_palette_font_colour[16]; -uint8 spritewidth[SPRITECOUNT]; -uint8 spriteheight[SPRITECOUNT]; -uint8 spritecollwidth[SPRITECOUNT]; -uint8 spritecollheight[SPRITECOUNT]; -uint8 spriterefwidth[SPRITECOUNT]; -uint8 spriterefheight[SPRITECOUNT]; +extern uint8 spritewidth[SPRITECOUNT]; +extern uint8 spriteheight[SPRITECOUNT]; +extern uint8 spritecollwidth[SPRITECOUNT]; +extern uint8 spritecollheight[SPRITECOUNT]; +extern uint8 spriterefwidth[SPRITECOUNT]; +extern uint8 spriterefheight[SPRITECOUNT]; -int16 anim_player[ANIM_PLAYER_COUNT][ANIM_PLAYER_MAX]; -int16 anim_enemy[NMI_ANIM_TABLE_COUNT]; -uint8 NMI_POWER[ORIG_LEVEL_COUNT]; -uint8 LEVEL_MUSIC[ORIG_LEVEL_COUNT]; +extern int16 anim_player[ANIM_PLAYER_COUNT][ANIM_PLAYER_MAX]; +extern int16 anim_enemy[NMI_ANIM_TABLE_COUNT]; +extern uint8 NMI_POWER[ORIG_LEVEL_COUNT]; +extern uint8 LEVEL_MUSIC[ORIG_LEVEL_COUNT]; -int16 anim_zoubida[ORIG_ANIM_MAX]; -int16 anim_moktar[ORIG_ANIM_MAX]; -int16 anim_smoke[ORIG_ANIM_MAX]; -int16 COEUR_POS[ORIG_ANIM_MAX * 2]; +extern int16 anim_zoubida[ORIG_ANIM_MAX]; +extern int16 anim_moktar[ORIG_ANIM_MAX]; +extern int16 anim_smoke[ORIG_ANIM_MAX]; +extern int16 COEUR_POS[ORIG_ANIM_MAX * 2]; -uint8 object_maxspeedY[ORIG_OBJECT_COUNT]; -bool object_support[ORIG_OBJECT_COUNT]; //not support/support -bool object_bounce[ORIG_OBJECT_COUNT]; //not bounce/bounce against floor + player bounces (ball, all spring, yellow stone, squeezed ball, skateboard) -bool object_gravity[ORIG_OBJECT_COUNT]; //no gravity on throw/gravity (ball, all carpet, trolley, squeezed ball, garbage, grey stone, scooter, yellow bricks between the statues, skateboard, cage) -bool object_droptobottom[ORIG_OBJECT_COUNT]; //on drop, lands on ground/continue below ground(cave spikes, rolling rock, ambolt, safe, dead man with helicopter) -bool object_no_damage[ORIG_OBJECT_COUNT]; //weapon/not weapon(cage) +extern uint8 object_maxspeedY[ORIG_OBJECT_COUNT]; +extern bool object_support[ORIG_OBJECT_COUNT]; //not support/support +extern bool object_bounce[ORIG_OBJECT_COUNT]; //not bounce/bounce against floor + player bounces (ball, all spring, yellow stone, squeezed ball, skateboard) +extern bool object_gravity[ORIG_OBJECT_COUNT]; //no gravity on throw/gravity (ball, all carpet, trolley, squeezed ball, garbage, grey stone, scooter, yellow bricks between the statues, skateboard, cage) +extern bool object_droptobottom[ORIG_OBJECT_COUNT]; //on drop, lands on ground/continue below ground(cave spikes, rolling rock, ambolt, safe, dead man with helicopter) +extern bool object_no_damage[ORIG_OBJECT_COUNT]; //weapon/not weapon(cage) #endif diff --git a/include/player.h b/include/player.h index fc8a5cd..497ee9d 100644 --- a/include/player.h +++ b/include/player.h @@ -32,9 +32,35 @@ #include "SDL/SDL.h" #include "level.h" +extern uint8 RESETLEVEL_FLAG; +extern uint8 BAR_FLAG; //timer for health bar +extern bool X_FLAG; //true if left or right key is pressed +extern bool Y_FLAG; //true if up or down key is pressed +extern uint8 CHOC_FLAG; //headache timer +extern uint8 action; //player sprite array +extern uint8 KICK_FLAG; //hit/burn timer +extern bool GRANDBRULE_FLAG; //If set, player will be "burned" when hit (fireballs) +extern bool LADDER_FLAG; //True if in a ladder +extern bool PRIER_FLAG; //True if player is forced into kneestanding because of low ceiling +extern uint8 SAUT_FLAG; //6 if free fall or in the middle of a jump, decremented if on solid surface. Must be 0 to initiate a jump. +extern uint8 LAST_ORDER; //Last action (kneestand + jump = silent walk) +extern uint8 FURTIF_FLAG; //Silent walk timer +extern bool DROP_FLAG; //True if an object is throwed forward +extern bool DROPREADY_FLAG; +extern bool CARRY_FLAG; //true if carrying something (add 16 to player sprite) +extern bool POSEREADY_FLAG; +extern uint8 ACTION_TIMER; //Frames since last action change +extern uint8 CROSS_FLAG; //When non-zero, fall through certain floors (after key down) +extern uint8 FUME_FLAG; //Smoke when object hits the floor +extern Uint8 *keystate; //Keyboard state +extern uint8 YFALL; +extern bool POCKET_FLAG; +extern int8 SENSX; //1: walk right, 0: stand still, -1: walk left, triggers the ACTION_TIMER if it changes +extern uint8 SAUT_COUNT; //Incremented from 0 to 3 when accelerating while jumping, stop acceleration upwards if >= 3 + int move_player(TITUS_level *level); TITUS_object *FORCE_POSE(TITUS_level *level); - +void DEC_ENERGY(TITUS_level *level); #endif diff --git a/include/reset.h b/include/reset.h index 26e0368..8280de1 100644 --- a/include/reset.h +++ b/include/reset.h @@ -32,8 +32,11 @@ #include "SDL/SDL.h" #include "level.h" +extern bool NEWLEVEL_FLAG; + int INIT_SCREENM(TITUS_level *level); int CLEAR_DATA(TITUS_level *level); +uint8 RESET_LEVEL(TITUS_level *level); #endif diff --git a/include/scroll.h b/include/scroll.h index d70a07a..7be0cf0 100644 --- a/include/scroll.h +++ b/include/scroll.h @@ -31,8 +31,24 @@ #include "SDL/SDL.h" +extern bool PERMUT_FLAG; //If false, there are no animated tiles on the screen? +extern uint8 loop_cycle; //Increased every loop in game loop +extern uint8 tile_anim; //Current tile animation (0-1-2), changed every 4th game loop cycle +extern uint8 BITMAP_X; //Screen offset (X) in tiles +extern uint8 BITMAP_XM; //Point to the left tile in the tile screen (0 to 19) +extern uint8 BITMAP_Y; //Screen offset (Y) in tiles +extern uint8 BITMAP_YM; //Point to the top tile in the tile screen (0 to 11) +extern bool XSCROLL_CENTER; //If true, the screen will scroll in X +extern int16 XLIMIT_SCROLL; //If scrolling: scroll until player is in this tile (X) +extern bool YSCROLL_CENTER; //If true, the screen will scroll in Y +extern uint8 YLIMIT_SCROLL; //If scrolling: scroll until player is in this tile (Y) + int scroll(TITUS_level *level); int DISPLAY_CHAR(TITUS_level *level, uint8 tile, uint8 y, uint8 x); +bool L_SCROLL(TITUS_level *level); +bool R_SCROLL(TITUS_level *level); +bool U_SCROLL(TITUS_level *level); +bool D_SCROLL(TITUS_level *level); #endif diff --git a/include/settings.h b/include/settings.h index 7f3fcba..6a1214a 100644 --- a/include/settings.h +++ b/include/settings.h @@ -45,38 +45,38 @@ int initcodes(); int initleveltitles(); -char spritefile[256]; -char levelfiles[16][256]; //16 levels in moktar, 15 levels in titus -char tituslogofile[256]; -int tituslogoformat; -char titusintrofile[256]; -int titusintroformat; -char titusmenufile[256]; -int titusmenuformat; -char titusfinishfile[256]; -int titusfinishformat; -char fontfile[256]; -int levelcount; -int devmode; -int reswidth; -int resheight; -int bitdepth; -int ingamewidth; -int ingameheight; -int videomode; -int game; +extern char spritefile[256]; +extern char levelfiles[16][256]; //16 levels in moktar, 15 levels in titus +extern char tituslogofile[256]; +extern int tituslogoformat; +extern char titusintrofile[256]; +extern int titusintroformat; +extern char titusmenufile[256]; +extern int titusmenuformat; +extern char titusfinishfile[256]; +extern int titusfinishformat; +extern char fontfile[256]; +extern int levelcount; +extern int devmode; +extern int reswidth; +extern int resheight; +extern int bitdepth; +extern int ingamewidth; +extern int ingameheight; +extern int videomode; +extern int game; -char levelcode[16][5]; -char leveltitle[16][41]; +extern char levelcode[16][5]; +extern char leveltitle[16][41]; -char moduleintrofile[256]; //.mod file -int moduleintrofileloop; //loop info -char moduleprelevelfile[256]; -int moduleprelevelfileloop; -char modulelevelfile[6][256]; //6 different level files -int modulelevelfileloop[6]; -char modulegameoverfile[256]; -int modulegameoverfileloop; -char modulelevel[16]; //Link to modulelevelfiles +extern char moduleintrofile[256]; //.mod file +extern int moduleintrofileloop; //loop info +extern char moduleprelevelfile[256]; +extern int moduleprelevelfileloop; +extern char modulelevelfile[6][256]; //6 different level files +extern int modulelevelfileloop[6]; +extern char modulegameoverfile[256]; +extern int modulegameoverfileloop; +extern char modulelevel[16]; //Link to modulelevelfiles #endif diff --git a/include/sprites.h b/include/sprites.h index a8fcfcc..0225f57 100644 --- a/include/sprites.h +++ b/include/sprites.h @@ -43,6 +43,7 @@ int updatesprite(TITUS_level *level, TITUS_sprite *spr, int16 number, bool clear int copysprite(TITUS_level *level, TITUS_sprite *dest, TITUS_sprite *src); int initspritecache(TITUS_spritecache *spritecache, uint16 count, uint16 tmpcount); int freespritecache(TITUS_spritecache *spritecache); +void SPRITES_ANIMATION(TITUS_level *level); #endif diff --git a/include/tile_animation.h b/include/tile_animation.h new file mode 100644 index 0000000..1b53755 --- /dev/null +++ b/include/tile_animation.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2008 - 2011 The OpenTitus team + * + * Authors: + * Eirik Stople + * + * "Titus the Fox: To Marrakech and Back" (1992) and + * "Lagaf': Les Aventures de Moktar - Vol 1: La Zoubida" (1991) + * was developed by, and is probably copyrighted by Titus Software, + * which, according to Wikipedia, stopped buisness in 2005. + * + * OpenTitus is not affiliated with Titus Software. + * + * OpenTitus is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 3 of the License, + * or (at your option) any later version. + * + * 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. See the GNU + * General Public License for more details. + */ +#ifndef TILE_ANIMATION +#define TILE_ANIMATION + +void BLOC_ANIMATION(TITUS_level *level); +#endif diff --git a/include/tituserror.h b/include/tituserror.h index 687ce25..f069144 100644 --- a/include/tituserror.h +++ b/include/tituserror.h @@ -36,8 +36,8 @@ #define TITUS_ERROR_SDL_ERROR -5 #define TITUS_ERROR_AUDIO_ERROR -6 #define TITUS_ERROR_INVALID_UTF8 -4 -char lasterror[200]; -int lasterrornr; //Only to be used when needed, f.ex. when return value is not int (f.ex. in function SDL_Text) (maybe this always should be used?) +extern char lasterror[200]; +extern int lasterrornr; //Only to be used when needed, f.ex. when return value is not int (f.ex. in function SDL_Text) (maybe this always should be used?) void checkerror(void); #endif diff --git a/opentitus.c b/opentitus.c index 9ed5d0d..b054461 100644 --- a/opentitus.c +++ b/opentitus.c @@ -66,64 +66,8 @@ #include "original.h" #include "objects.h" -int main(int argc, char *argv[]) { - - int retval; - int state = 1; //View the menu when the main loop starts - retval = init(); - if (retval < 0) - state = 0; - - if (state) { - retval = viewintrotext(); - if (retval < 0) - state = 0; - } - - if (state) { - retval = viewimage(tituslogofile, tituslogoformat, 0, 4000); - if (retval < 0) - state = 0; - } - -#ifdef AUDIO_ENABLED - SELECT_MUSIC(15); -#endif - - if (state) { - retval = viewimage(titusintrofile, titusintroformat, 0, 6500); - if (retval < 0) - state = 0; - } - - while (state) { - retval = viewmenu(titusmenufile, titusmenuformat); - - if (retval <= 0) - state = 0; - - if (state && (retval <= levelcount)) { - retval = playtitus(retval - 1); - if (retval < 0) - state = 0; - } - } - - freefonts(); - -#ifdef AUDIO_ENABLED - freeaudio(); -#endif - - SDL_Quit(); - - checkerror(); - - if (retval == -1) - retval = 0; - - return retval; -} +char lasterror[200]; +int lasterrornr; //Only to be used when needed, f.ex. when return value is not int (f.ex. in function SDL_Text) (maybe this always should be used?) int init() { @@ -208,6 +152,65 @@ int init() { } +int main(int argc, char *argv[]) { + + int retval; + int state = 1; //View the menu when the main loop starts + retval = init(); + if (retval < 0) + state = 0; + + if (state) { + retval = viewintrotext(); + if (retval < 0) + state = 0; + } + + if (state) { + retval = viewimage(tituslogofile, tituslogoformat, 0, 4000); + if (retval < 0) + state = 0; + } + +#ifdef AUDIO_ENABLED + SELECT_MUSIC(15); +#endif + + if (state) { + retval = viewimage(titusintrofile, titusintroformat, 0, 6500); + if (retval < 0) + state = 0; + } + + while (state) { + retval = viewmenu(titusmenufile, titusmenuformat); + + if (retval <= 0) + state = 0; + + if (state && (retval <= levelcount)) { + retval = playtitus(retval - 1); + if (retval < 0) + state = 0; + } + } + + freefonts(); + +#ifdef AUDIO_ENABLED + freeaudio(); +#endif + + SDL_Quit(); + + checkerror(); + + if (retval == -1) + retval = 0; + + return retval; +} + void checkerror(void) { printf("%s\n", lasterror); } diff --git a/src/audio.c b/src/audio.c index 275426b..ce44434 100644 --- a/src/audio.c +++ b/src/audio.c @@ -35,6 +35,7 @@ #include "tituserror.h" #include "opl.h" #include "common.h" +#include "player.h" #define ADLIB_DATA_COUNT 10 @@ -50,6 +51,7 @@ #define ADLIB_PORT 0x388 +uint8_t AUDIOMODE; char playing; int rate; @@ -132,7 +134,6 @@ int SELECT_MUSIC(int song_number); void all_vox_zero(); void TimerCallback(void *data); -int FX_DRIVER(); int FX_STOP(); void updatechip(int reg, int val) @@ -140,6 +141,21 @@ void updatechip(int reg, int val) OPL_WriteRegister(reg, val); } +void FX_DRIVER() { + ADLIB_DATA *aad = &(sdl_player_data.aad); + if (!FX_ON) return; + updatechip(0xBD, 0xEF & aad->perc_stat); + updatechip(0xA6, 0x57); + updatechip(0xB6, 1); + updatechip(0xB6, 5); + updatechip(0xBD, 0x10 | aad->perc_stat); + FX_TIME--; + if (FX_TIME == 0) { + FX_STOP(); + } + return; +} + int fillchip(ADLIB_DATA *aad) { int i; @@ -552,14 +568,14 @@ int startmusic() { return 0; } -int refreshaudio() { +void refreshaudio() { if (AUDIOMODE != 1) { return; } int tick = SDL_GetTicks(); if (tick - lastaudiotick < audiodelay) { - return 0; + return; } //Update the chip! lastaudiotick += audiodelay; @@ -570,7 +586,30 @@ int refreshaudio() { audiodelay--; } sdl_player_data.playing = fillchip(&(sdl_player_data.aad)); - return 0; + return; +} + +int initsfx() { + ADLIB_DATA *aad = &(sdl_player_data.aad); + unsigned char *raw_data = aad->data; + FX_ON = false; + FX_TIME = 0; + uint16 tmp1; + int i, k; + + tmp1 = SFX_OFFSET; + + for (i = 0; i < ADLIB_SFX_COUNT; i++) { + for (k = 0; k < 5; k++) + aad->sfx[i].op[0][k] = raw_data[tmp1++]; + + for (k = 0; k < 5; k++) + aad->sfx[i].op[1][k] = raw_data[tmp1++]; + + aad->sfx[i].fb_alg = raw_data[tmp1++]; + } + + return 0; } int initaudio(){ @@ -644,7 +683,7 @@ int initaudio(){ return 0; } -int freeaudio(){ +void freeaudio(){ free (sdl_player_data.aad.data); OPL_Shutdown(); @@ -653,30 +692,7 @@ int freeaudio(){ SDL_CloseAudio(); - return 0; -} - -int initsfx() { - ADLIB_DATA *aad = &(sdl_player_data.aad); - unsigned char *raw_data = aad->data; - FX_ON = false; - FX_TIME = 0; - uint16 tmp1; - int i, k; - - tmp1 = SFX_OFFSET; - - for (i = 0; i < ADLIB_SFX_COUNT; i++) { - for (k = 0; k < 5; k++) - aad->sfx[i].op[0][k] = raw_data[tmp1++]; - - for (k = 0; k < 5; k++) - aad->sfx[i].op[1][k] = raw_data[tmp1++]; - - aad->sfx[i].fb_alg = raw_data[tmp1++]; - } - - return 0; + return; } int WAIT_SONG(){ @@ -724,21 +740,6 @@ int FX_START(int fx_number){ return 0; } -int FX_DRIVER() { - ADLIB_DATA *aad = &(sdl_player_data.aad); - if (!FX_ON) return; - updatechip(0xBD, 0xEF & aad->perc_stat); - updatechip(0xA6, 0x57); - updatechip(0xB6, 1); - updatechip(0xB6, 5); - updatechip(0xBD, 0x10 | aad->perc_stat); - FX_TIME--; - if (FX_TIME == 0) { - FX_STOP(); - } - return 0; -} - int FX_STOP() { unsigned char tmpins1[] = {0xF5, 0x7F, 0x00, 0x11, 0x00}; unsigned char tmpins2[] = {0xF8, 0xFF, 0x04, 0x30, 0x00}; diff --git a/src/draw.c b/src/draw.c index c3ea8fb..a4d72fd 100644 --- a/src/draw.c +++ b/src/draw.c @@ -46,6 +46,20 @@ #include "common.h" #include "tituserror.h" #include "original.h" +#include "scroll.h" +#include "player.h" +#include "audio.h" +#include "gates.h" +#include "keyboard.h" +#include "fonts.h" + +bool DISPLAYLOOPTIME; //If true, display loop time in milliseconds +static uint8_t LOOPTIME; //Loop time +static uint8_t SUBTIME[16]; //Sub time +static uint16_t FPS; //Frames pr second +static uint16_t FPS_LAST; //Frames pr second +static uint16_t LAST_CLOCK_CORR; //Correction to LAST_CLOCK +static int LAST_CLOCK; //Used for fixed framerate SDL_Surface *sprite_from_cache(TITUS_level *level, TITUS_sprite *spr); @@ -114,71 +128,7 @@ int TFR_SCREENM() { //Draw tiles on the backbuffer (copy from the tile screen) SDL_BlitSurface(tilescreen, &src, screen, &dest); } - -//Loop through all sprites, and draw the sprites that should be visible on the screen (NOT by using the visible flag, it uses the coordinates) -//If the flash bit is set, the first 3 planes will be 0, the last plane will be normal (colour & 0x01, odd colors gets white, even colours gets black) - - -DISPLAY_SPRITES(TITUS_level *level) { - int16 i; - char buffer[7]; //xxx ms - - for (i = level->elevatorcount - 1; i >= 0; i--) { - display_sprite(level, &(level->elevator[i].sprite)); - } - - for (i = level->trashcount - 1; i >= 0; i--) { - display_sprite(level, &(level->trash[i])); - } - - for (i = level->enemycount - 1; i >= 0; i--) { - display_sprite(level, &(level->enemy[i].sprite)); - } - - for (i = level->objectcount - 1; i >= 0; i--) { - display_sprite(level, &(level->object[i].sprite)); - } - - display_sprite(level, &(level->player.sprite3)); - display_sprite(level, &(level->player.sprite2)); - display_sprite(level, &(level->player.sprite)); - - if (GODMODE) { - SDL_Print_Text("GODMODE", 30 * 8, 0 * 12); - } - if (NOCLIP) { - SDL_Print_Text("NOCLIP", 30 * 8, 1 * 12); - } - -#ifdef DEBUG_VERSION - if (DISPLAYLOOPTIME) { - sprintf(buffer, "%3u ms", LOOPTIME); - SDL_Print_Text(buffer, 30 * 8, 2 * 12); //Loop time in ms - - sprintf(buffer, "FPS %u", FPS_LAST); - SDL_Print_Text(buffer, 30 * 8, 4 * 12); //Last second's FPS count - - sprintf(buffer, "CL %d", LAST_CLOCK); - SDL_Print_Text(buffer, 30 * 8, 6 * 12); //Clock - - sprintf(buffer, "CORR %d", LAST_CLOCK_CORR); - SDL_Print_Text(buffer, 30 * 8, 8 * 12); //Correction to the clock - - - for (i = 0; i <= 15; i++) { - sprintf(buffer, "%d %3u", i, SUBTIME[i]); - SDL_Print_Text(buffer, 0 * 8, i * 12); //Sub times from main loop in ms - } - - sprintf(buffer, "%d %3u", i, SUBTIME[i]); - SDL_Print_Text(buffer, 0 * 8, i * 12); - } - -#endif - -} - -display_sprite(TITUS_level *level, TITUS_sprite *spr) { +void display_sprite(TITUS_level *level, TITUS_sprite *spr) { SDL_Surface *image; SDL_Rect src, dest; if (!spr->enabled) { @@ -248,6 +198,68 @@ display_sprite(TITUS_level *level, TITUS_sprite *spr) { } +//Loop through all sprites, and draw the sprites that should be visible on the screen (NOT by using the visible flag, it uses the coordinates) +//If the flash bit is set, the first 3 planes will be 0, the last plane will be normal (colour & 0x01, odd colors gets white, even colours gets black) + +void DISPLAY_SPRITES(TITUS_level *level) { + int16 i; + char buffer[7]; //xxx ms + + for (i = level->elevatorcount - 1; i >= 0; i--) { + display_sprite(level, &(level->elevator[i].sprite)); + } + + for (i = level->trashcount - 1; i >= 0; i--) { + display_sprite(level, &(level->trash[i])); + } + + for (i = level->enemycount - 1; i >= 0; i--) { + display_sprite(level, &(level->enemy[i].sprite)); + } + + for (i = level->objectcount - 1; i >= 0; i--) { + display_sprite(level, &(level->object[i].sprite)); + } + + display_sprite(level, &(level->player.sprite3)); + display_sprite(level, &(level->player.sprite2)); + display_sprite(level, &(level->player.sprite)); + + if (GODMODE) { + SDL_Print_Text("GODMODE", 30 * 8, 0 * 12); + } + if (NOCLIP) { + SDL_Print_Text("NOCLIP", 30 * 8, 1 * 12); + } + +#ifdef DEBUG_VERSION + if (DISPLAYLOOPTIME) { + sprintf(buffer, "%3u ms", LOOPTIME); + SDL_Print_Text(buffer, 30 * 8, 2 * 12); //Loop time in ms + + sprintf(buffer, "FPS %u", FPS_LAST); + SDL_Print_Text(buffer, 30 * 8, 4 * 12); //Last second's FPS count + + sprintf(buffer, "CL %d", LAST_CLOCK); + SDL_Print_Text(buffer, 30 * 8, 6 * 12); //Clock + + sprintf(buffer, "CORR %d", LAST_CLOCK_CORR); + SDL_Print_Text(buffer, 30 * 8, 8 * 12); //Correction to the clock + + + for (i = 0; i <= 15; i++) { + sprintf(buffer, "%d %3u", i, SUBTIME[i]); + SDL_Print_Text(buffer, 0 * 8, i * 12); //Sub times from main loop in ms + } + + sprintf(buffer, "%d %3u", i, SUBTIME[i]); + SDL_Print_Text(buffer, 0 * 8, i * 12); + } + +#endif + +} + SDL_Surface *sprite_from_cache(TITUS_level *level, TITUS_sprite *spr) { TITUS_spritecache *cache = level->spritecache; TITUS_spritedata *spritedata = level->spritedata[spr->number]; @@ -298,53 +310,7 @@ SDL_Surface *sprite_from_cache(TITUS_level *level, TITUS_sprite *spr) { } } - -int flip_screen(bool slow) { - int tick = SDL_GetTicks(); - SDL_Flip(screen); - int oldtick = tick; - tick = SDL_GetTicks(); - SUBTIME[14] = tick - oldtick; - - //if (slow) { - NO_FAST_CPU(slow); //TODO: - //} -} - -/* -NO_FAST_CPU(bool slow) { - int tick, duration, delay, tick2; - tick = SDL_GetTicks(); - if (slow) { - delay = 29; //28.53612, fps: 70.09Hz/2 - } else { - delay = 10; - } - LOOPTIME = (tick - LAST_CLOCK); - delay = delay - (tick - LAST_CLOCK); - if ((delay < 0) || (delay > 40)) { - delay = 1; - } - SDL_Delay(delay); - //do { - //SDL_Delay(1); - // tick = SDL_GetTicks(); - // duration = abs(LAST_CLOCK - tick); - //} while (duration < delay); - tick2 = SDL_GetTicks(); - if ((tick2 / 1000) != (LAST_CLOCK / 1000)) { - FPS_LAST = FPS; - FPS = 0; - } - FPS++; - LAST_CLOCK_CORR = tick2 - tick - delay; - - LAST_CLOCK = tick2; - SUBTIME[15] = LAST_CLOCK - tick; -} -*/ - -NO_FAST_CPU(bool slow) { +void NO_FAST_CPU(bool slow) { int tick, duration, delay, tick2; tick = SDL_GetTicks(); if (slow) { @@ -402,7 +368,51 @@ NO_FAST_CPU(bool slow) { SUBTIME[15] = LAST_CLOCK - tick; } + +int flip_screen(bool slow) { + int tick = SDL_GetTicks(); + SDL_Flip(screen); + int oldtick = tick; + tick = SDL_GetTicks(); + SUBTIME[14] = tick - oldtick; + + //if (slow) { + NO_FAST_CPU(slow); //TODO: + //} +} +/* +NO_FAST_CPU(bool slow) { + int tick, duration, delay, tick2; + tick = SDL_GetTicks(); + if (slow) { + delay = 29; //28.53612, fps: 70.09Hz/2 + } else { + delay = 10; + } + LOOPTIME = (tick - LAST_CLOCK); + delay = delay - (tick - LAST_CLOCK); + if ((delay < 0) || (delay > 40)) { + delay = 1; + } + SDL_Delay(delay); + //do { + //SDL_Delay(1); + // tick = SDL_GetTicks(); + // duration = abs(LAST_CLOCK - tick); + //} while (duration < delay); + tick2 = SDL_GetTicks(); + if ((tick2 / 1000) != (LAST_CLOCK / 1000)) { + FPS_LAST = FPS; + FPS = 0; + } + FPS++; + LAST_CLOCK_CORR = tick2 - tick - delay; + + LAST_CLOCK = tick2; + SUBTIME[15] = LAST_CLOCK - tick; +} +*/ int viewstatus(TITUS_level *level, bool countbonus){ int retval, i, j; @@ -486,15 +496,7 @@ int INIT_SCREENM(TITUS_level *level) { } -int DISPLAY_COUNT(TITUS_level *level) { - subto0(&(BAR_FLAG)); - if (BAR_FLAG != 0) { - DISPLAY_ENERGY(level); - } -} - - -DISPLAY_ENERGY(TITUS_level *level) { +void DISPLAY_ENERGY(TITUS_level *level) { uint8 offset = 96; uint8 i; SDL_Rect dest; @@ -516,6 +518,14 @@ DISPLAY_ENERGY(TITUS_level *level) { } } +int DISPLAY_COUNT(TITUS_level *level) { + subto0(&(BAR_FLAG)); + if (BAR_FLAG != 0) { + DISPLAY_ENERGY(level); + } +} + + int fadeout() { SDL_Surface *image; int activedelay = 1; diff --git a/src/elevators.c b/src/elevators.c index 62410fb..058ff92 100644 --- a/src/elevators.c +++ b/src/elevators.c @@ -36,6 +36,16 @@ #include "globals.h" #include "definitions.h" #include "elevators.h" +#include "scroll.h" + +void MTSBR(TITUS_elevator *elevator) { + elevator->counter++; + if (elevator->counter >= elevator->range) { + elevator->counter = 0; + elevator->sprite.speedX = 0 - elevator->sprite.speedX; + elevator->sprite.speedY = 0 - elevator->sprite.speedY; + } +} int MOVE_TRP(TITUS_level *level) { TITUS_elevator *elevator = level->elevator; @@ -58,12 +68,3 @@ int MOVE_TRP(TITUS_level *level) { } } } - -MTSBR(TITUS_elevator *elevator) { - elevator->counter++; - if (elevator->counter >= elevator->range) { - elevator->counter = 0; - elevator->sprite.speedX = 0 - elevator->sprite.speedX; - elevator->sprite.speedY = 0 - elevator->sprite.speedY; - } -} diff --git a/src/enemies.c b/src/enemies.c index 1ca1cc4..08e4f72 100644 --- a/src/enemies.c +++ b/src/enemies.c @@ -41,12 +41,104 @@ #include "common.h" #include "player.h" #include "settings.h" +#include "engine.h" +#include "scroll.h" +#include "objects.h" +#include "audio.h" +#include "sprites.h" -int updateenemysprite(TITUS_level *level, TITUS_enemy *enemy, int16 number, bool clearflags); +uint8 INVULNERABLE_FLAG; //When non-zero, boss is invulnerable +uint8 TAUPE_FLAG; //Used for enemies walking and popping up +uint8 BIGNMI_POWER; //Lives of the boss +bool boss_alive; //True if the boss is alive bool NMI_VS_DROP(TITUS_sprite *enemysprite, TITUS_sprite *sprite); int KICK_ASH(TITUS_level *level, TITUS_sprite *enemysprite, int16 power); bool FIND_TRASH(TITUS_level *level, TITUS_sprite **trash); +void PUT_BULLET(TITUS_level *level, TITUS_enemy *enemy, TITUS_sprite *bullet) { + bullet->x = enemy->sprite.x; + bullet->y = enemy->sprite.y - (int8)(*(enemy->sprite.animation - 1) & 0x00FF); + updatesprite(level, bullet, (*(enemy->sprite.animation - 2) & 0x1FFF) + FIRST_OBJET, true); + if (enemy->sprite.x < level->player.sprite.x) { + bullet->speedX = 16*11; + bullet->flipped = true; + } else { + bullet->speedX = -16*11; + bullet->flipped = false; + } + bullet->speedY = 0; + bullet->x += bullet->speedX >> 4; +} + +void UP_ANIMATION(TITUS_sprite *sprite) { + do { + sprite->animation++; + } while (*sprite->animation >= 0); + sprite->animation++; +} + +void DOWN_ANIMATION(TITUS_sprite *sprite) { + do { + sprite->animation--; + } while (*sprite->animation >= 0); + sprite->animation--; +} + +void GAL_FORM(TITUS_level *level, TITUS_enemy *enemy) { //Enemy animation + int16 *image; + enemy->sprite.invisible = false; + if ((enemy->dying & 0x03) != 0) { + enemy->sprite.visible = false; + enemy->visible = true; + return; + } + enemy->trigger = false; + image = enemy->sprite.animation; //Animation pointer + while (*image < 0) { + image += (*image >> 1); //jump back to start of animation + } + if (*image == 0x55AA) { + enemy->sprite.invisible = true; + return; + } + enemy->trigger = *image & 0x2000; + updateenemysprite(level, enemy, (*image & 0x00FF) + FIRST_NMI, true); + enemy->sprite.flipped = (enemy->sprite.speedX < 0) ? true : false; + image++; + if (*image < 0) { + image += (*image >> 1); //jump back to start of animation + } + enemy->sprite.animation = image; + enemy->visible = true; +} + +void DEAD1(TITUS_level *level, TITUS_enemy *enemy) { + if (((enemy->dying & 0x01) != 0) || //00000001 or 00000011 + (enemy->dead_sprite == -1)) { + if ((enemy->dying & 0x01) == 0) { + enemy->dying = enemy->dying | 0x01; + enemy->sprite.speedY = -10; + enemy->phase = 0; + } + if (enemy->phase != 0xFF) { + enemy->sprite.y += enemy->sprite.speedY; + if (SEECHOC_FLAG != 0) { + level->player.sprite2.y += enemy->sprite.speedY; + } + if (enemy->sprite.speedY < MAX_SPEED_DEAD) { + enemy->sprite.speedY++; + } + } + } else { + enemy->dying = enemy->dying | 0x01; + updateenemysprite(level, enemy, enemy->dead_sprite, false); + enemy->sprite.flash = false; + enemy->sprite.visible = false; + enemy->sprite.speedY = 0; + enemy->phase = -1; + } +} + int MOVE_NMI(TITUS_level *level) { TITUS_sprite *bullet; int i, j; @@ -1006,33 +1098,6 @@ int MOVE_NMI(TITUS_level *level) { } //for (i = 0; i < NMI_BY_LEVEL; i++) } -DEAD1(TITUS_level *level, TITUS_enemy *enemy) { - if (((enemy->dying & 0x01) != 0) || //00000001 or 00000011 - (enemy->dead_sprite == -1)) { - if ((enemy->dying & 0x01) == 0) { - enemy->dying = enemy->dying | 0x01; - enemy->sprite.speedY = -10; - enemy->phase = 0; - } - if (enemy->phase != 0xFF) { - enemy->sprite.y += enemy->sprite.speedY; - if (SEECHOC_FLAG != 0) { - level->player.sprite2.y += enemy->sprite.speedY; - } - if (enemy->sprite.speedY < MAX_SPEED_DEAD) { - enemy->sprite.speedY++; - } - } - } else { - enemy->dying = enemy->dying | 0x01; - updateenemysprite(level, enemy, enemy->dead_sprite, false); - enemy->sprite.flash = false; - enemy->sprite.visible = false; - enemy->sprite.speedY = 0; - enemy->phase = -1; - } -} - int updateenemysprite(TITUS_level *level, TITUS_enemy *enemy, int16 number, bool clearflags){ updatesprite(level, &(enemy->sprite), number, clearflags); @@ -1084,6 +1149,48 @@ int updateenemysprite(TITUS_level *level, TITUS_enemy *enemy, int16 number, bool return (0); } +void SEE_CHOC(TITUS_level *level) { + updatesprite(level, &(level->player.sprite2), FIRST_OBJET + 15, true); //Hit (a throw hits an enemy) + level->player.sprite2.speedX = 0; + level->player.sprite2.speedY = 0; + SEECHOC_FLAG = 5; +} + +void ACTIONC_NMI(TITUS_level *level, TITUS_enemy *enemy) { + switch (enemy->type) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 18: + if (NMI_VS_DROP(&(enemy->sprite), &(level->player.sprite))) { + if (enemy->type != 11) { //Walk and shoot + if (enemy->sprite.number != 178) { //Periscope + enemy->sprite.speedX = 0 - enemy->sprite.speedX; + } + } + if ((enemy->sprite.number >= FIRST_NMI + 53) && + (enemy->sprite.number <= FIRST_NMI + 55)) { //Fireball + GRANDBRULE_FLAG = 1; + } + if (enemy->power != 0) { + KICK_ASH(level, &(enemy->sprite), enemy->power); + } + } + break; + } +} int SET_NMI(TITUS_level *level) { //Clear enemy sprites @@ -1182,72 +1289,6 @@ int SET_NMI(TITUS_level *level) { } -GAL_FORM(TITUS_level *level, TITUS_enemy *enemy) { //Enemy animation - int16 *image; - enemy->sprite.invisible = false; - if ((enemy->dying & 0x03) != 0) { - enemy->sprite.visible = false; - enemy->visible = true; - return; - } - enemy->trigger = false; - image = enemy->sprite.animation; //Animation pointer - while (*image < 0) { - image += (*image >> 1); //jump back to start of animation - } - if (*image == 0x55AA) { - enemy->sprite.invisible = true; - return; - } - enemy->trigger = *image & 0x2000; - updateenemysprite(level, enemy, (*image & 0x00FF) + FIRST_NMI, true); - enemy->sprite.flipped = (enemy->sprite.speedX < 0) ? true : false; - image++; - if (*image < 0) { - image += (*image >> 1); //jump back to start of animation - } - enemy->sprite.animation = image; - enemy->visible = true; -} - - -ACTIONC_NMI(TITUS_level *level, TITUS_enemy *enemy) { - switch (enemy->type) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 18: - if (NMI_VS_DROP(&(enemy->sprite), &(level->player.sprite))) { - if (enemy->type != 11) { //Walk and shoot - if (enemy->sprite.number != 178) { //Periscope - enemy->sprite.speedX = 0 - enemy->sprite.speedX; - } - } - if ((enemy->sprite.number >= FIRST_NMI + 53) && - (enemy->sprite.number <= FIRST_NMI + 55)) { //Fireball - GRANDBRULE_FLAG = 1; - } - if (enemy->power != 0) { - KICK_ASH(level, &(enemy->sprite), enemy->power); - } - } - break; - } -} - - int KICK_ASH(TITUS_level *level, TITUS_sprite *enemysprite, int16 power) { #ifdef AUDIO_ENABLED FX_START(4); @@ -1299,13 +1340,6 @@ bool NMI_VS_DROP(TITUS_sprite *enemysprite, TITUS_sprite *sprite) { } -SEE_CHOC(TITUS_level *level) { - updatesprite(level, &(level->player.sprite2), FIRST_OBJET + 15, true); //Hit (a throw hits an enemy) - level->player.sprite2.speedX = 0; - level->player.sprite2.speedY = 0; - SEECHOC_FLAG = 5; -} - int MOVE_TRASH(TITUS_level *level) { int16 i, tmp; for (i = 0; i < level->trashcount; i++) { @@ -1345,32 +1379,3 @@ bool FIND_TRASH(TITUS_level *level, TITUS_sprite **trash) { } return false; } - -PUT_BULLET(TITUS_level *level, TITUS_enemy *enemy, TITUS_sprite *bullet) { - bullet->x = enemy->sprite.x; - bullet->y = enemy->sprite.y - (int8)(*(enemy->sprite.animation - 1) & 0x00FF); - updatesprite(level, bullet, (*(enemy->sprite.animation - 2) & 0x1FFF) + FIRST_OBJET, true); - if (enemy->sprite.x < level->player.sprite.x) { - bullet->speedX = 16*11; - bullet->flipped = true; - } else { - bullet->speedX = -16*11; - bullet->flipped = false; - } - bullet->speedY = 0; - bullet->x += bullet->speedX >> 4; -} - -UP_ANIMATION(TITUS_sprite *sprite) { - do { - sprite->animation++; - } while (*sprite->animation >= 0); - sprite->animation++; -} - -DOWN_ANIMATION(TITUS_sprite *sprite) { - do { - sprite->animation--; - } while (*sprite->animation >= 0); - sprite->animation--; -} diff --git a/src/engine.c b/src/engine.c index 81515ba..6f8453d 100644 --- a/src/engine.c +++ b/src/engine.c @@ -50,6 +50,8 @@ #include "elevators.h" #include "objects.h" #include "enemies.h" +#include "tile_animation.h" +#include "viewimage.h" //Probably not the best way, but it works... #define HAVE_CONFIG_H 1 @@ -62,6 +64,10 @@ #include "audio.h" #endif +SDL_Surface *tilescreen; //Tile screen +bool GAMEOVER_FLAG; //triggers a game over +uint16 IMAGE_COUNTER; //Increased every loop in game loop (0 to 0x0FFF) + static int playlevel(TITUS_level *level); static int displaylevel(TITUS_level *level); static int movescreen(TITUS_level *level); @@ -71,6 +77,95 @@ static int collision_detection_player(TITUS_level *level); static int getpolarity(int number); int gettick(int *tick, uint8 index); +int SCREEN_5C() { + uint16 key; + int retval; + if (keystate[SDLK_LCTRL] && //LCtrl + keystate[SDLK_LALT] && //LAlt + keystate[SDLK_e]) { //E + for (key = SDLK_FIRST; key <= SDLK_LAST; key++) { + if (key == SDLK_LCTRL) continue; + if (key == SDLK_LALT) continue; + if (key == SDLK_e) continue; + if (keystate[key]) return 0; + } + if (game == 0) { //Titus + retval = viewimage(titusfinishfile, titusfinishformat, 1, 0); + if (retval < 0) + return retval; + } +#ifdef AUDIO_ENABLED + SELECT_MUSIC(9); +#endif + } + + return 0; +} + +int gameover(TITUS_level *level) { + TITUS_player *player = &(level->player); + int i, retval; +#ifdef AUDIO_ENABLED + SELECT_MUSIC(2); +#endif + updatesprite(level, &(player->sprite), 13, true); //Death + updatesprite(level, &(player->sprite2), 333, true); //Game + player->sprite2.x = (BITMAP_X << 4) - (120-2); + player->sprite2.y = (BITMAP_Y << 4) + 100; + //over + updatesprite(level, &(player->sprite3), 334, true); //Over + player->sprite3.x = (BITMAP_X << 4) + (320+120-2); + player->sprite3.y = (BITMAP_Y << 4) + 100; + for (i = 0; i < 31; i++) { + TFR_SCREENM(); + DISPLAY_SPRITES(level); + flip_screen(true); + player->sprite2.x += 8; + player->sprite3.x -= 8; + } + SCREEN_5C(); //Secret: display picture if LCtrl+LAlt+E is pressed + retval = waitforbutton(); + if (retval < 0) + return retval; + + fadeout(); +} + +int death(TITUS_level *level) { + TITUS_player *player = &(level->player); + int i; +#ifdef AUDIO_ENABLED + SELECT_MUSIC(1); +#endif + FORCE_POSE(level); + updatesprite(level, &(player->sprite), 13, true); //Death + player->sprite.speedY = 15; + for (i = 0; i < 60; i++) { + TFR_SCREENM(); + //TODO! GRAVITY(); + DISPLAY_SPRITES(level); + flip_screen(true); + player->sprite.speedY--; + if (player->sprite.speedY < -16) { + player->sprite.speedY = -16; + } + player->sprite.y -= player->sprite.speedY; + } + +#ifdef AUDIO_ENABLED + WAIT_SONG(); + SELECT_MUSIC(0); +#endif + + /* TODO: remove because REPLACED + SCREEN_1(); + //TODO: SELECT_MUSIC(LEVEL_MUSIC[FNAMEB]); + INIT_SCREENM(level); + return 3; //Do not break main loop + */ + CLOSE_SCREEN(); +} + int playtitus(int firstlevel){ int startx, starty; int retval; @@ -374,90 +469,3 @@ static int getpolarity(int number){ return (1); return (0); } - -int death(TITUS_level *level) { - TITUS_player *player = &(level->player); - int i; -#ifdef AUDIO_ENABLED - SELECT_MUSIC(1); -#endif - FORCE_POSE(level); - updatesprite(level, &(player->sprite), 13, true); //Death - player->sprite.speedY = 15; - for (i = 0; i < 60; i++) { - TFR_SCREENM(); - //TODO! GRAVITY(); - DISPLAY_SPRITES(level); - flip_screen(true); - player->sprite.speedY--; - if (player->sprite.speedY < -16) { - player->sprite.speedY = -16; - } - player->sprite.y -= player->sprite.speedY; - } - -#ifdef AUDIO_ENABLED - WAIT_SONG(); - SELECT_MUSIC(0); -#endif - - /* TODO: remove because REPLACED - SCREEN_1(); - //TODO: SELECT_MUSIC(LEVEL_MUSIC[FNAMEB]); - INIT_SCREENM(level); - return 3; //Do not break main loop - */ - CLOSE_SCREEN(); -} - -int gameover(TITUS_level *level) { - TITUS_player *player = &(level->player); - int i, retval; -#ifdef AUDIO_ENABLED - SELECT_MUSIC(2); -#endif - updatesprite(level, &(player->sprite), 13, true); //Death - updatesprite(level, &(player->sprite2), 333, true); //Game - player->sprite2.x = (BITMAP_X << 4) - (120-2); - player->sprite2.y = (BITMAP_Y << 4) + 100; - //over - updatesprite(level, &(player->sprite3), 334, true); //Over - player->sprite3.x = (BITMAP_X << 4) + (320+120-2); - player->sprite3.y = (BITMAP_Y << 4) + 100; - for (i = 0; i < 31; i++) { - TFR_SCREENM(); - DISPLAY_SPRITES(level); - flip_screen(true); - player->sprite2.x += 8; - player->sprite3.x -= 8; - } - SCREEN_5C(); //Secret: display picture if LCtrl+LAlt+E is pressed - retval = waitforbutton(); - if (retval < 0) - return retval; - - fadeout(); -} - -int SCREEN_5C() { - uint16 key; - int retval; - if (keystate[SDLK_LCTRL] && //LCtrl - keystate[SDLK_LALT] && //LAlt - keystate[SDLK_e]) { //E - for (key = SDLK_FIRST; key <= SDLK_LAST; key++) { - if (key == SDLK_LCTRL) continue; - if (key == SDLK_LALT) continue; - if (key == SDLK_e) continue; - if (keystate[key]) return; - } - if (game == 0) { //Titus - retval = viewimage(titusfinishfile, titusfinishformat, 1, 0); - if (retval < 0) - return retval; - } -#ifdef AUDIO_ENABLED - SELECT_MUSIC(9); -#endif - } -} diff --git a/src/fonts.c b/src/fonts.c index d1b08f0..214b582 100644 --- a/src/fonts.c +++ b/src/fonts.c @@ -38,6 +38,10 @@ #include "keyboard.h" #include "draw.h" #include +#include "sprites.h" + +TITUS_font *font; //Malloced +SDL_Surface *font_undefined; //Pointer SDL_Surface * SDL_LoadChar(unsigned char * fontdata, int offset, SDL_PixelFormat * pixelformat); int freesubfont(TITUS_font *f_sub); diff --git a/src/gates.c b/src/gates.c index 251cec9..ec7e4c7 100644 --- a/src/gates.c +++ b/src/gates.c @@ -33,43 +33,19 @@ #include "backbuffer.h" #include "sprites.h" #include "settings.h" +#include "draw.h" +#include "gates.h" +#include "scroll.h" +#include "audio.h" +#include "reset.h" +#include "level.h" +#include "player.h" -int copytiles(int16 destX, int16 destY, int16 width, int16 height); +int16 XLIMIT; //The engine will not scroll past this tile before the player have crossed the line (X) -int CROSSING_GATE(TITUS_level *level) { //Check and handle level completion, and if the player does a kneestand on a secret entrance - check_finish(level); - check_gates(level); -} - - -check_finish(TITUS_level *level) { - TITUS_player *player = &(level->player); - if (boss_alive) { //There is still a boss that needs to be killed! - return; - } - if (level->levelid == 9) { //The level with a cage - if ((level->player.sprite2.number != FIRST_OBJET + 26) && - (level->player.sprite2.number != FIRST_OBJET + 27)) { - return; - } - } - if (((player->sprite.x & 0xFFF0) != level->finishX) && - ((player->sprite.x & 0xFFF0) - 16 != level->finishX)) { - return; - } - if (((player->sprite.y & 0xFFF0) != level->finishY) && - ((player->sprite.y & 0xFFF0) - 16 != level->finishY)) { - return; - } -#ifdef AUDIO_ENABLED - SELECT_MUSIC(4); - WAIT_SONG(); -#endif - CLOSE_SCREEN(); - NEWLEVEL_FLAG = true; -} +int copytiles(int16 destX, int16 destY, int16 width, int16 height); -check_gates(TITUS_level *level) { +void check_gates(TITUS_level *level) { TITUS_player *player = &(level->player); uint8 i; if ((CROSS_FLAG == 0) || //not kneestanding @@ -110,6 +86,39 @@ check_gates(TITUS_level *level) { OPEN_SCREEN(); } +void check_finish(TITUS_level *level) { + TITUS_player *player = &(level->player); + if (boss_alive) { //There is still a boss that needs to be killed! + return; + } + if (level->levelid == 9) { //The level with a cage + if ((level->player.sprite2.number != FIRST_OBJET + 26) && + (level->player.sprite2.number != FIRST_OBJET + 27)) { + return; + } + } + if (((player->sprite.x & 0xFFF0) != level->finishX) && + ((player->sprite.x & 0xFFF0) - 16 != level->finishX)) { + return; + } + if (((player->sprite.y & 0xFFF0) != level->finishY) && + ((player->sprite.y & 0xFFF0) - 16 != level->finishY)) { + return; + } +#ifdef AUDIO_ENABLED + SELECT_MUSIC(4); + WAIT_SONG(); +#endif + CLOSE_SCREEN(); + NEWLEVEL_FLAG = true; +} + +int CROSSING_GATE(TITUS_level *level) { //Check and handle level completion, and if the player does a kneestand on a secret entrance + check_finish(level); + check_gates(level); +} + + int CLOSE_SCREEN() { SDL_Rect dest; diff --git a/src/level.c b/src/level.c index f2aa0d7..9ac1057 100644 --- a/src/level.c +++ b/src/level.c @@ -40,7 +40,10 @@ #include "sprites.h" #include "level.h" #include "globals.h" +#include "gates.h" +#include "scroll.h" +uint8 ALTITUDE_ZERO; //The engine will not scroll below this tile before the player have gone below (Y) unsigned int loaduint16(unsigned char c1, unsigned char c2); int loadint16(unsigned char c1, unsigned char c2); diff --git a/src/menu.c b/src/menu.c index 9d5ae04..d9cfd35 100644 --- a/src/menu.c +++ b/src/menu.c @@ -38,6 +38,7 @@ #include "audio.h" #include "globals.h" #include "common.h" +#include "keyboard.h" //Probably not the best way, but it works... #define HAVE_CONFIG_H 1 @@ -50,6 +51,142 @@ #include "audio.h" #endif +SDL_Surface *screen; //Backbuffer + +int enterpassword(){ + int retval; + char code[] = "____"; + int i; + SDL_Event event; + char tmpchar; + + SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); + SDL_Flip(screen); + + SDL_Print_Text("CODE", 111, 80); + +#ifdef _DINGUX + int index = 0; + int counter = 0; +#endif + + for (i = 0; i < 4; ) { + while(SDL_PollEvent(&event)) { //Check all events + if (event.type == SDL_QUIT) { + return (-1); + } + + if (event.type == SDL_KEYDOWN) { + if (event.key.keysym.sym == SDLK_ESCAPE) { + return (-1); + } +#ifdef _DINGUX + if (event.key.keysym.sym == KEY_UP) { + index++; + if (index > 15) { + index = 0; + } + } else if (event.key.keysym.sym == KEY_DOWN) { + index--; + if (index < 0) { + index = 15; + } + } else if (event.key.keysym.sym == KEY_SPACE) { + if (index < 10) { + code[i] = index + CHAR_0; + } else { + code[i] = index - 10 + CHAR_A; + } + i++; + index = 0; + } +#else + + if ((event.key.keysym.unicode & 0xFF80) == 0) { + tmpchar = (char)(event.key.keysym.unicode & 0x007F); + + if ((tmpchar >= CHAR_0) && (tmpchar <= CHAR_9)) + code[i++] = tmpchar; + + if ((tmpchar >= CHAR_a) && (tmpchar <= CHAR_f)) + tmpchar -= (CHAR_a - CHAR_A); + + if ((tmpchar >= CHAR_A) && (tmpchar <= CHAR_F)) + code[i++] = tmpchar; + + } +#endif + +#ifdef AUDIO_ENABLED + if (event.key.keysym.sym == KEY_MUSIC) { + AUDIOMODE++; + if (AUDIOMODE > 1) { + AUDIOMODE = 0; + } + if (AUDIOMODE == 1) { + startmusic(); + } + } +#endif + } + } +#ifdef _DINGUX + if (i < 4) { + counter++; + if (counter > 10) { + counter = 0; + } else if (counter > 5) { + code[i] = *"_"; + } else { + if (index < 10) { + code[i] = index + CHAR_0; + } else { + code[i] = index - 10 + CHAR_A; + } + } + } +#endif + SDL_Print_Text(code, 159, 80); + SDL_Flip(screen); + titus_sleep(); + +#ifdef AUDIO_MIKMOD_SINGLETHREAD + checkmodule(); +#endif + +#ifdef AUDIO_SDL_MIXER + checkaudio(); +#endif + + } + + for (i = 0; i < levelcount; i++) { + if (strcmp (code, levelcode[i]) == 0) { + SDL_Print_Text("LEVEL", 103, 104); + sprintf(code, "%d", i + 1); + SDL_Print_Text(code, 199 - 8 * strlen(code), 104); + SDL_Flip(screen); + retval = waitforbutton(); + + if (retval < 0) + return retval; + + SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); + SDL_Flip(screen); + + return (i + 1); + } + } + + SDL_Print_Text("! WRONG CODE !", 87, 104); + SDL_Flip(screen); + retval = waitforbutton(); + + SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); + SDL_Flip(screen); + return (retval); +} + int viewmenu(char * menufile, int menuformat) { SDL_Surface *surface; SDL_Palette *palette; @@ -332,137 +469,3 @@ int viewmenu(char * menufile, int menuformat) { return (curlevel); } - -int enterpassword(){ - int retval; - char code[] = "____"; - int i; - SDL_Event event; - char tmpchar; - - SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); - SDL_Flip(screen); - - SDL_Print_Text("CODE", 111, 80); - -#ifdef _DINGUX - int index = 0; - int counter = 0; -#endif - - for (i = 0; i < 4; ) { - while(SDL_PollEvent(&event)) { //Check all events - if (event.type == SDL_QUIT) { - return (-1); - } - - if (event.type == SDL_KEYDOWN) { - if (event.key.keysym.sym == SDLK_ESCAPE) { - return (-1); - } -#ifdef _DINGUX - if (event.key.keysym.sym == KEY_UP) { - index++; - if (index > 15) { - index = 0; - } - } else if (event.key.keysym.sym == KEY_DOWN) { - index--; - if (index < 0) { - index = 15; - } - } else if (event.key.keysym.sym == KEY_SPACE) { - if (index < 10) { - code[i] = index + CHAR_0; - } else { - code[i] = index - 10 + CHAR_A; - } - i++; - index = 0; - } -#else - - if ((event.key.keysym.unicode & 0xFF80) == 0) { - tmpchar = (char)(event.key.keysym.unicode & 0x007F); - - if ((tmpchar >= CHAR_0) && (tmpchar <= CHAR_9)) - code[i++] = tmpchar; - - if ((tmpchar >= CHAR_a) && (tmpchar <= CHAR_f)) - tmpchar -= (CHAR_a - CHAR_A); - - if ((tmpchar >= CHAR_A) && (tmpchar <= CHAR_F)) - code[i++] = tmpchar; - - } -#endif - -#ifdef AUDIO_ENABLED - if (event.key.keysym.sym == KEY_MUSIC) { - AUDIOMODE++; - if (AUDIOMODE > 1) { - AUDIOMODE = 0; - } - if (AUDIOMODE == 1) { - startmusic(); - } - } -#endif - } - } -#ifdef _DINGUX - if (i < 4) { - counter++; - if (counter > 10) { - counter = 0; - } else if (counter > 5) { - code[i] = *"_"; - } else { - if (index < 10) { - code[i] = index + CHAR_0; - } else { - code[i] = index - 10 + CHAR_A; - } - } - } -#endif - SDL_Print_Text(code, 159, 80); - SDL_Flip(screen); - titus_sleep(); - -#ifdef AUDIO_MIKMOD_SINGLETHREAD - checkmodule(); -#endif - -#ifdef AUDIO_SDL_MIXER - checkaudio(); -#endif - - } - - for (i = 0; i < levelcount; i++) { - if (strcmp (code, levelcode[i]) == 0) { - SDL_Print_Text("LEVEL", 103, 104); - sprintf(code, "%d", i + 1); - SDL_Print_Text(code, 199 - 8 * strlen(code), 104); - SDL_Flip(screen); - retval = waitforbutton(); - - if (retval < 0) - return retval; - - SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); - SDL_Flip(screen); - - return (i + 1); - } - } - - SDL_Print_Text("! WRONG CODE !", 87, 104); - SDL_Flip(screen); - retval = waitforbutton(); - - SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); - SDL_Flip(screen); - return (retval); -} diff --git a/src/objects.c b/src/objects.c index 9fb6358..1c6a010 100644 --- a/src/objects.c +++ b/src/objects.c @@ -34,8 +34,59 @@ #include "objects.h" #include "tituserror.h" #include "settings.h" +#include "engine.h" +#include "audio.h" +#include "sprites.h" -int move_objects(TITUS_level *level) { +uint8 TAPISFLY_FLAG; //When non-zero, the flying carpet is flying +uint8 GRAVITY_FLAG; //When zero, skip object gravity function +uint8 TAPISWAIT_FLAG; //Flying carpet state + +void shock(TITUS_level *level, TITUS_object *object) { //Falling object versus player + + TITUS_player *player = &(level->player); + + //Quick test + if (object->mass < 10) return; + if (player->sprite.speedY >= MAX_Y*16) return; + if (abs(player->sprite.y - object->sprite.y) >= 32) { + return; + } + if (abs(player->sprite.x - object->sprite.x) >= 32) { + return; + } + + //Test X + if (object->sprite.x > player->sprite.x) { //Object center is right for player + if (object->sprite.x > player->sprite.x + 24) return; //Object is too far right + } else { //Object center is left for center + if (object->sprite.x + object->sprite.spritedata->collwidth < player->sprite.x) return; //Return if object is too far left + } + + //Test Y + + if (object->sprite.y < player->sprite.y) { //Object bottom is above player bottom + if (object->sprite.y <= player->sprite.y - 32) return; //Return if object is completely above the player + } else { //Object bottom is below player bottom + if (object->sprite.y - object->sprite.spritedata->collheight + 1 >= player->sprite.y) return; //Return if object is completely below the player + } + + //Hit! + +#ifdef AUDIO_ENABLED + FX_START(5); //Sound effect +#endif + CHOC_FLAG = 24; + if (object->sprite.killing) { + if (!GODMODE) { + DEC_ENERGY(level); + } + object->sprite.killing = false; + } +} + + +void move_objects(TITUS_level *level) { if (GRAVITY_FLAG == 0) return; //Skip execution if there are no active objects @@ -318,50 +369,6 @@ int move_objects(TITUS_level *level) { } } -int shock(TITUS_level *level, TITUS_object *object) { //Falling object versus player - - TITUS_player *player = &(level->player); - - //Quick test - if (object->mass < 10) return; - if (player->sprite.speedY >= MAX_Y*16) return; - if (abs(player->sprite.y - object->sprite.y) >= 32) { - return; - } - if (abs(player->sprite.x - object->sprite.x) >= 32) { - return; - } - - //Test X - if (object->sprite.x > player->sprite.x) { //Object center is right for player - if (object->sprite.x > player->sprite.x + 24) return; //Object is too far right - } else { //Object center is left for center - if (object->sprite.x + object->sprite.spritedata->collwidth < player->sprite.x) return; //Return if object is too far left - } - - //Test Y - - if (object->sprite.y < player->sprite.y) { //Object bottom is above player bottom - if (object->sprite.y <= player->sprite.y - 32) return; //Return if object is completely above the player - } else { //Object bottom is below player bottom - if (object->sprite.y - object->sprite.spritedata->collheight + 1 >= player->sprite.y) return; //Return if object is completely below the player - } - - //Hit! - -#ifdef AUDIO_ENABLED - FX_START(5); //Sound effect -#endif - CHOC_FLAG = 24; - if (object->sprite.killing) { - if (!GODMODE) { - DEC_ENERGY(level); - } - object->sprite.killing = false; - } -} - - bool SPRITES_VS_SPRITES (TITUS_level *level, TITUS_sprite *sprite1, TITUS_sprite *sprite1ref, TITUS_object **object2) { //check if there is an object below that can support the input object uint8 i; diff --git a/src/original.c b/src/original.c index 33835d2..7f4f316 100644 --- a/src/original.c +++ b/src/original.c @@ -34,6 +34,34 @@ #include "settings.h" #include "definitions.h" +SDL_Color orig_palette_colour[16]; +SDL_Color orig_palette_level_colour[16]; +SDL_Color orig_palette_font_colour[16]; + +uint8 spritewidth[SPRITECOUNT]; +uint8 spriteheight[SPRITECOUNT]; +uint8 spritecollwidth[SPRITECOUNT]; +uint8 spritecollheight[SPRITECOUNT]; +uint8 spriterefwidth[SPRITECOUNT]; +uint8 spriterefheight[SPRITECOUNT]; + +int16 anim_player[ANIM_PLAYER_COUNT][ANIM_PLAYER_MAX]; +int16 anim_enemy[NMI_ANIM_TABLE_COUNT]; +uint8 NMI_POWER[ORIG_LEVEL_COUNT]; +uint8 LEVEL_MUSIC[ORIG_LEVEL_COUNT]; + +int16 anim_zoubida[ORIG_ANIM_MAX]; +int16 anim_moktar[ORIG_ANIM_MAX]; +int16 anim_smoke[ORIG_ANIM_MAX]; +int16 COEUR_POS[ORIG_ANIM_MAX * 2]; + +uint8 object_maxspeedY[ORIG_OBJECT_COUNT]; +bool object_support[ORIG_OBJECT_COUNT]; //not support/support +bool object_bounce[ORIG_OBJECT_COUNT]; //not bounce/bounce against floor + player bounces (ball, all spring, yellow stone, squeezed ball, skateboard) +bool object_gravity[ORIG_OBJECT_COUNT]; //no gravity on throw/gravity (ball, all carpet, trolley, squeezed ball, garbage, grey stone, scooter, yellow bricks between the statues, skateboard, cage) +bool object_droptobottom[ORIG_OBJECT_COUNT]; //on drop, lands on ground/continue below ground(cave spikes, rolling rock, ambolt, safe, dead man with helicopter) +bool object_no_damage[ORIG_OBJECT_COUNT]; //weapon/not weapon(cage) + int initoriginal() { int i, j; diff --git a/src/player.c b/src/player.c index 264f329..d2101a7 100644 --- a/src/player.c +++ b/src/player.c @@ -38,13 +38,49 @@ #include "original.h" #include "common.h" #include "settings.h" - -static int TAKE_BLK_AND_YTEST(TITUS_level *level, int16 tileY, uint8 tileX); +#include "scroll.h" +#include "audio.h" +#include "objects.h" +#include "sprites.h" +#include "reset.h" +#include "enemies.h" +#include "engine.h" + +uint8 RESETLEVEL_FLAG; +uint8 BAR_FLAG; //timer for health bar +bool X_FLAG; //true if left or right key is pressed +bool Y_FLAG; //true if up or down key is pressed +uint8 CHOC_FLAG; //headache timer +uint8 action; //player sprite array +uint8 KICK_FLAG; //hit/burn timer +bool GRANDBRULE_FLAG; //If set, player will be "burned" when hit (fireballs) +bool LADDER_FLAG; //True if in a ladder +bool PRIER_FLAG; //True if player is forced into kneestanding because of low ceiling +uint8 SAUT_FLAG; //6 if free fall or in the middle of a jump, decremented if on solid surface. Must be 0 to initiate a jump. +uint8 LAST_ORDER; //Last action (kneestand + jump = silent walk) +uint8 FURTIF_FLAG; //Silent walk timer +bool DROP_FLAG; //True if an object is throwed forward +bool DROPREADY_FLAG; +bool CARRY_FLAG; //true if carrying something (add 16 to player sprite) +bool POSEREADY_FLAG; +uint8 ACTION_TIMER; //Frames since last action change +uint8 CROSS_FLAG; //When non-zero, fall through certain floors (after key down) +uint8 FUME_FLAG; //Smoke when object hits the floor +Uint8 *keystate; //Keyboard state +uint8 YFALL; +bool POCKET_FLAG; +uint8 SEECHOC_FLAG; //Counter when hit +bool GODMODE; //If true, the player will not interfere with the enemies +bool NOCLIP; //If true, the player will move noclip +uint8 SAUT_COUNT; +int8 SENSX; //1: walk right, 0: stand still, -1: walk left, triggers the ACTION_TIMER if it changes + +static void TAKE_BLK_AND_YTEST(TITUS_level *level, int16 tileY, uint8 tileX); static int BLOCK_YYPRGD(TITUS_level *level, uint8 ceil, uint8 tileY, uint8 tileX); static int BLOCK_XXPRG(TITUS_level *level, uint8 horiz, uint8 tileY, uint8 tileX); static int XACCELERATION(TITUS_player *player, int16 maxspeed); static int YACCELERATION(TITUS_player *player, int16 maxspeed); -static int BLOCK_YYPRG(TITUS_level *level, uint8 floor, uint8 floor_above, uint8 tileY, uint8 tileX); +static void BLOCK_YYPRG(TITUS_level *level, uint8 floor, uint8 floor_above, uint8 tileY, uint8 tileX); static int CASE_BONUS(TITUS_level *level, uint8 tileY, uint8 tileX); static int CASE_PASS(TITUS_level *level, uint8 viewlevel, uint8 tileY, uint8 tileX); static int CASE_SECU(TITUS_level *level, uint8 tileY, uint8 tileX); @@ -54,6 +90,327 @@ static int YACCELERATION_NEG(TITUS_player *player, int16 maxspeed); static int ACTION_PRG(TITUS_level *level, uint8 action); int16 add_carry(); +void ARAB_TOMBE(TITUS_level *level) { + //No wall under the player; fall down! + TITUS_player *player = &(level->player); + SAUT_FLAG = 6; + if (KICK_FLAG != 0) { + return; + } + XACCELERATION(player, MAX_X*16); + YACCELERATION(player, MAX_Y*16); + if (CHOC_FLAG != 0) { + updatesprite(level, &(player->sprite), 15, true); //sprite when hit + } else if (CARRY_FLAG == 0) { + updatesprite(level, &(player->sprite), 10, true); //position while falling (jump sprite?) + } else { + updatesprite(level, &(player->sprite), 21, true); //position falling and carry (jump and carry sprite?) + } + player->sprite.flipped = (SENSX < 0); +} + +void COLLISION_TRP(TITUS_level *level) { + //Player versus elevators + //Change player's location according to the elevator + uint8 i; + TITUS_player *player = &(level->player); + TITUS_elevator *elevator = level->elevator; + if ((player->sprite.speedY >= 0) && (CROSS_FLAG == 0)) { + for (i = 0; i < level->elevatorcount; i++) { + //Quick test + if (!(elevator[i].enabled) || + !(elevator[i].sprite.visible) || + (abs(elevator[i].sprite.x - player->sprite.x) >= 64) || + (abs(elevator[i].sprite.y - player->sprite.y) >= 16)) { + continue; + } + + //Real test + if (player->sprite.x - level->spritedata[0]->refwidth < elevator[i].sprite.x) { //The elevator is right + if (player->sprite.x - level->spritedata[0]->refwidth + level->spritedata[0]->collwidth <= elevator[i].sprite.x) { //player->sprite must be 0 + continue; //The elevator is too far right + } + } else { //The elevator is left + if (player->sprite.x - level->spritedata[0]->refwidth >= elevator[i].sprite.x + elevator[i].sprite.spritedata->collwidth) { + continue; //The elevator is too far left + } + } + + if (player->sprite.y - 6 < elevator[i].sprite.y) { //The elevator is below + if (player->sprite.y - 6 + 8 <= elevator[i].sprite.y) { + continue; //The elevator is too far below + } + } else { //The elevator is above + if (player->sprite.y - 6 >= elevator[i].sprite.y + elevator[i].sprite.spritedata->collheight) { + continue; //The elevator is too far above + } + } + + //Skip fall-through-tile action (ACTION_TIMER == 15) + if (ACTION_TIMER == 14) { + ACTION_TIMER = 16; + } + + YFALL = 0; + player->sprite.y = elevator[i].sprite.y; + + player->sprite.speedY = 0; + subto0(&(SAUT_FLAG)); + SAUT_COUNT = 0; + YFALL = 2; + + player->sprite.x += elevator[i].sprite.speedX; + if (elevator[i].sprite.speedY > 0) { //Going down + player->sprite.y += elevator[i].sprite.speedY; + } + return; + } + } +} + +void COLLISION_OBJET(TITUS_level *level) { + //Player versus objects + //Collision, spring state, speed up carpet/scooter/skateboard, bounce bouncy objects + TITUS_player *player = &(level->player); + TITUS_object *off_object; + if (player->sprite.speedY < 0) { + return; + } + //Collision with a sprite + if (!(SPRITES_VS_SPRITES(level, &(player->sprite), &(level->spritedata[0]), &off_object))) { //check if player stands on an object, use sprite[0] (rest) as collision size (first player tile) + return; + } + player->sprite.y = off_object->sprite.y - off_object->sprite.spritedata->collheight; + //If the foot is placed on a spring, it must be soft! + if ((off_object->sprite.number == FIRST_OBJET + 24) || (off_object->sprite.number == FIRST_OBJET + 25)) { + off_object->sprite.UNDER = off_object->sprite.UNDER | 0x02; + off_object->sprite.ONTOP = &(player->sprite); + } + //If we jump on the flying carpet, let it fly + if ((off_object->sprite.number == FIRST_OBJET + 21) || (off_object->sprite.number == FIRST_OBJET + 22)) { //Flying carpet + if (!(player->sprite.flipped)) { + off_object->sprite.speedX = 6 * 16; + } else { + off_object->sprite.speedX = 0 - 6 * 16; + } + off_object->sprite.flipped = player->sprite.flipped; + GRAVITY_FLAG = 4; + TAPISWAIT_FLAG = 0; + } else if ((ACTION_TIMER > 10) && //delay + ((LAST_ORDER & 0x0F) == 0) && //Player rests + (player->sprite.speedY == 0) && //stable Y + ((off_object->sprite.number == 83) || //scooter + (off_object->sprite.number == 94))) { //skateboard + + //If you put your foot on a scooter or a skateboard + if (!(player->sprite.flipped)) { + off_object->sprite.speedX = 16 * 3; + } else { + off_object->sprite.speedX = 0 - 16 * 3; + } + off_object->sprite.flipped = player->sprite.flipped; + GRAVITY_FLAG = 4; + } + + if (off_object->sprite.speedX < 0) { + player->sprite.speedX = off_object->sprite.speedX; + } else if (off_object->sprite.speedX > 0) { + player->sprite.speedX = off_object->sprite.speedX + 16; + } + + //If we want to CROSS (cross) it does not bounce + if ((CROSS_FLAG == 0) && //No long kneestand + (player->sprite.speedY > (16 * 3)) && + (off_object->objectdata->bounce)) { + //Bounce on a ball if no long kneestand (down key) + if (keystate[KEY_DOWN]) { + player->sprite.speedY = 0; + } else { + if (keystate[KEY_UP] || keystate[KEY_JUMP]) { + player->sprite.speedY += 16 * 3; //increase speed + } else { + player->sprite.speedY -= 16; //reduce speed + } + player->sprite.speedY = 0 - player->sprite.speedY; + if (player->sprite.speedY > 0) { + player->sprite.speedY = 0; + } + } + ACTION_TIMER = 0; + + //If the ball lies on the ground + if (off_object->sprite.speedY == 0) { +#ifdef AUDIO_ENABLED + FX_START(12); //Sound effect +#endif + off_object->sprite.speedY = 0 - player->sprite.speedY; + off_object->sprite.y -= off_object->sprite.speedY >> 4; + GRAVITY_FLAG = 4; + } + } else { + if (off_object->sprite.speedY != 0) { + player->sprite.speedY = off_object->sprite.speedY; + } else { + player->sprite.speedY = 0; + } + subto0(&(SAUT_FLAG)); + SAUT_COUNT = 0; + YFALL = 2; + } +} + +void DEC_LIFE (TITUS_level *level) { + //Kill the player, check for gameover, hide the energy bar + RESETLEVEL_FLAG = 10; + BAR_FLAG = 0; + if (level->lives == 0) { + GAMEOVER_FLAG = true; + } +} + +void CASE_DEAD_IM (TITUS_level *level) { + //Kill the player immediately (spikes/water/flames etc. + //Sets RESET_FLAG to 2, in opposite to being killed as a result of 0 HP (then RESET_FLAG is 10) + DEC_LIFE(level); + RESETLEVEL_FLAG = 2; +} + +void BRK_COLLISION(TITUS_level *level) { //Collision detection between player and tiles/objects/elevators + //Point the foot on the block! + TITUS_player *player = &(level->player); + int16 changeX; + int16 height; + int16 initY; + uint8 tileX; + int16 tileY; + int16 colltest; + uint8 left_tileX; + bool first; + uint8 hflag; + + tileX = (player->sprite.x >> 4); + tileY = (player->sprite.y >> 4) - 1; + initY = tileY; + + //if too low then die! + if ((player->sprite.y > ((level->height + 1) << 4)) && !NOCLIP) { + CASE_DEAD_IM(level); + } + + + //Test under the feet of the hero and on his head! (In y) + YFALL = 0; + //Find the left tile + //colltest can be 0 to 15 +- 8 (-1 to -8 will change into 255 to 248) + colltest = player->sprite.x & 0x0F; + if (colltest < TEST_ZONE) { + colltest += 256; + tileX--; + } + colltest -= TEST_ZONE; + + left_tileX = tileX; + TAKE_BLK_AND_YTEST(level, tileY, tileX); //Test the tile for vertical blocking + if (YFALL == 1) { //Have the fall stopped? + //No! Is it necessary to test the right tile? + colltest += TEST_ZONE * 2; //4 * 2 +// if (colltest > 255) { +// colltest -= 256; +// tileX++; +// } elseif + if (colltest > 15) { + tileX++; + } + if (tileX != left_tileX) { + TAKE_BLK_AND_YTEST(level, tileY, tileX); //Also test the left tile + } + if (YFALL == 1) { + if ((CROSS_FLAG == 0) && (CHOC_FLAG == 0)) { + COLLISION_TRP(level); //Player versus elevators + if (YFALL == 1) { + COLLISION_OBJET(level); //Player versus objects + if (YFALL == 1) { + ARAB_TOMBE(level); //No wall/elevator/object under the player; fall down! + } else { + player->GLISSE = 0; + } + } + } else { + ARAB_TOMBE(level); //Fall down! + } + } + } + + //How will the player move in X? + changeX = TEST_ZONE + MAX_X; //4 + 4 ??? + max_speed_x + if (player->sprite.speedX < 0) { + changeX = 0 - changeX; + } else if (player->sprite.speedX == 0) { + changeX = 0; + } + + //Test the hero (in x) + height = player->sprite.spritedata->collheight; + if ((player->sprite.y > MAP_LIMIT_Y + 1) && (initY >= 0) && (initY < level->height)) { + tileX = ((player->sprite.x + changeX) >> 4); + tileY = initY; + first = true; + do { + hflag = get_horizflag(level, tileY, tileX); + if (first) { + BLOCK_XXPRG(level, hflag, tileY, tileX); + first = false; + } else if ((hflag == HFLAG_CODE) || (hflag == HFLAG_BONUS)) { //level code or HP + BLOCK_XXPRG(level, hflag, tileY, tileX); + } + if (tileY == 0) { + return; + } + tileY--; + height -= 16; + } while (height > 0); + } +} + +int t_pause (TITUS_level *level) { + bool pass; + TITUS_player *player = &(level->player); + SDL_Event event; + TITUS_sprite tmp; + //tmp.buffer = NULL; + + TFR_SCREENM(); //Draw tiles + copysprite(level, &(tmp), &(player->sprite)); + updatesprite(level, &(player->sprite), 29, true); //Pause tile + DISPLAY_SPRITES(level); //Draw sprites + flip_screen(true); //Display it + copysprite(level, &(player->sprite), &(tmp)); //Reset player sprite + //SDL_FreeSurface(tmp.buffer); + do { + titus_sleep(); + keystate = SDL_GetKeyState(NULL); + while(SDL_PollEvent(&event)) { //Check all events + if (event.type == SDL_QUIT) { + return TITUS_ERROR_QUIT; + } else if (event.type == SDL_KEYDOWN) { + if (event.key.keysym.sym == KEY_ESC) { + return TITUS_ERROR_QUIT; + } else if (event.key.keysym.sym == KEY_MUSIC) { + AUDIOMODE++; + if (AUDIOMODE > 1) { + AUDIOMODE = 0; + } + if (AUDIOMODE == 1) { + startmusic(); + } + } else if (event.key.keysym.sym == KEY_P) { + return 0; + } + } + } + } while (1); +} + int move_player(TITUS_level *level) { //Part 1: Check keyboard input //Part 2: Determine the player's action, and execute action dependent code @@ -141,11 +498,11 @@ int move_player(TITUS_level *level) { if (keystate[KEY_F1] && (RESETLEVEL_FLAG == 0)) { //F1 = suicide CASE_DEAD_IM(level); RESETLEVEL_FLAG--; - return; + return 0; } if (keystate[KEY_F2]) { //F2 = game over GAMEOVER_FLAG = true; - return; + return 0; } if (keystate[KEY_E]) { //E = display energy BAR_FLAG = 50; @@ -187,7 +544,7 @@ int move_player(TITUS_level *level) { } player->sprite.x += (player->sprite.speedX >> 4); player->sprite.y += (player->sprite.speedY >> 4); - return; + return 0; } if (CHOC_FLAG != 0) { @@ -363,160 +720,8 @@ int move_player(TITUS_level *level) { } } -CASE_DEAD_IM (TITUS_level *level) { - //Kill the player immediately (spikes/water/flames etc. - //Sets RESET_FLAG to 2, in opposite to being killed as a result of 0 HP (then RESET_FLAG is 10) - DEC_LIFE(level); - RESETLEVEL_FLAG = 2; -} - - -DEC_LIFE (TITUS_level *level) { - //Kill the player, check for gameover, hide the energy bar - RESETLEVEL_FLAG = 10; - BAR_FLAG = 0; - if (level->lives == 0) { - GAMEOVER_FLAG = true; - } -} - -t_pause (TITUS_level *level) { - bool pass; - TITUS_player *player = &(level->player); - SDL_Event event; - TITUS_sprite tmp; - //tmp.buffer = NULL; - TFR_SCREENM(); //Draw tiles - copysprite(level, &(tmp), &(player->sprite)); - updatesprite(level, &(player->sprite), 29, true); //Pause tile - DISPLAY_SPRITES(level); //Draw sprites - flip_screen(true); //Display it - copysprite(level, &(player->sprite), &(tmp)); //Reset player sprite - //SDL_FreeSurface(tmp.buffer); - do { - titus_sleep(); - keystate = SDL_GetKeyState(NULL); - while(SDL_PollEvent(&event)) { //Check all events - if (event.type == SDL_QUIT) { - return TITUS_ERROR_QUIT; - } else if (event.type == SDL_KEYDOWN) { - if (event.key.keysym.sym == KEY_ESC) { - return TITUS_ERROR_QUIT; - } else if (event.key.keysym.sym == KEY_MUSIC) { - AUDIOMODE++; - if (AUDIOMODE > 1) { - AUDIOMODE = 0; - } - if (AUDIOMODE == 1) { - startmusic(); - } - } else if (event.key.keysym.sym == KEY_P) { - return 0; - } - } - } - } while (1); -} - -BRK_COLLISION(TITUS_level *level) { //Collision detection between player and tiles/objects/elevators - //Point the foot on the block! - TITUS_player *player = &(level->player); - int16 changeX; - int16 height; - int16 initY; - uint8 tileX; - int16 tileY; - int16 colltest; - uint8 left_tileX; - bool first; - uint8 hflag; - - tileX = (player->sprite.x >> 4); - tileY = (player->sprite.y >> 4) - 1; - initY = tileY; - - //if too low then die! - if ((player->sprite.y > ((level->height + 1) << 4)) && !NOCLIP) { - CASE_DEAD_IM(level); - } - - - //Test under the feet of the hero and on his head! (In y) - YFALL = 0; - //Find the left tile - //colltest can be 0 to 15 +- 8 (-1 to -8 will change into 255 to 248) - colltest = player->sprite.x & 0x0F; - if (colltest < TEST_ZONE) { - colltest += 256; - tileX--; - } - colltest -= TEST_ZONE; - - left_tileX = tileX; - TAKE_BLK_AND_YTEST(level, tileY, tileX); //Test the tile for vertical blocking - if (YFALL == 1) { //Have the fall stopped? - //No! Is it necessary to test the right tile? - colltest += TEST_ZONE * 2; //4 * 2 -// if (colltest > 255) { -// colltest -= 256; -// tileX++; -// } elseif - if (colltest > 15) { - tileX++; - } - if (tileX != left_tileX) { - TAKE_BLK_AND_YTEST(level, tileY, tileX); //Also test the left tile - } - if (YFALL == 1) { - if ((CROSS_FLAG == 0) && (CHOC_FLAG == 0)) { - COLLISION_TRP(level); //Player versus elevators - if (YFALL == 1) { - COLLISION_OBJET(level); //Player versus objects - if (YFALL == 1) { - ARAB_TOMBE(level); //No wall/elevator/object under the player; fall down! - } else { - player->GLISSE = 0; - } - } - } else { - ARAB_TOMBE(level); //Fall down! - } - } - } - - //How will the player move in X? - changeX = TEST_ZONE + MAX_X; //4 + 4 ??? + max_speed_x - if (player->sprite.speedX < 0) { - changeX = 0 - changeX; - } else if (player->sprite.speedX == 0) { - changeX = 0; - } - - //Test the hero (in x) - height = player->sprite.spritedata->collheight; - if ((player->sprite.y > MAP_LIMIT_Y + 1) && (initY >= 0) && (initY < level->height)) { - tileX = ((player->sprite.x + changeX) >> 4); - tileY = initY; - first = true; - do { - hflag = get_horizflag(level, tileY, tileX); - if (first) { - BLOCK_XXPRG(level, hflag, tileY, tileX); - first = false; - } else if ((hflag == HFLAG_CODE) || (hflag == HFLAG_BONUS)) { //level code or HP - BLOCK_XXPRG(level, hflag, tileY, tileX); - } - if (tileY == 0) { - return; - } - tileY--; - height -= 16; - } while (height > 0); - } -} - -static int TAKE_BLK_AND_YTEST(TITUS_level *level, int16 tileY, uint8 tileX) { +static void TAKE_BLK_AND_YTEST(TITUS_level *level, int16 tileY, uint8 tileX) { //Test the current tile for vertical blocking TITUS_player *player = &(level->player); @@ -633,6 +838,17 @@ static int BLOCK_YYPRGD(TITUS_level *level, uint8 ceil, uint8 tileY, uint8 tileX } } +void ARAB_BLOCKX(TITUS_level *level) { + TITUS_player *player = &(level->player); + //Horizontal hit (wall), stop the player + player->sprite.x -= player->sprite.speedX >> 4; + player->sprite.speedX = 0; + if ((KICK_FLAG != 0) && (SAUT_FLAG != 6)) { + CHOC_FLAG = 20; + KICK_FLAG = 0; + } +} + static int BLOCK_XXPRG(TITUS_level *level, uint8 horiz, uint8 tileY, uint8 tileX) { //Action on different horizontal flags switch (horiz) { @@ -660,23 +876,12 @@ static int BLOCK_XXPRG(TITUS_level *level, uint8 horiz, uint8 tileY, uint8 tileX break; case 5: //Padlock - CASE_SECU(level, tileY, tileX); - break; - - case 6: //Level 14 code - CASE_PASS(level, 14 - 1, tileY, tileX); - break; - } -} - -ARAB_BLOCKX(TITUS_level *level) { - TITUS_player *player = &(level->player); - //Horizontal hit (wall), stop the player - player->sprite.x -= player->sprite.speedX >> 4; - player->sprite.speedX = 0; - if ((KICK_FLAG != 0) && (SAUT_FLAG != 6)) { - CHOC_FLAG = 20; - KICK_FLAG = 0; + CASE_SECU(level, tileY, tileX); + break; + + case 6: //Level 14 code + CASE_PASS(level, 14 - 1, tileY, tileX); + break; } } @@ -722,27 +927,6 @@ TITUS_object *FORCE_POSE(TITUS_level *level) { } } - - -ARAB_TOMBE(TITUS_level *level) { - //No wall under the player; fall down! - TITUS_player *player = &(level->player); - SAUT_FLAG = 6; - if (KICK_FLAG != 0) { - return; - } - XACCELERATION(player, MAX_X*16); - YACCELERATION(player, MAX_Y*16); - if (CHOC_FLAG != 0) { - updatesprite(level, &(player->sprite), 15, true); //sprite when hit - } else if (CARRY_FLAG == 0) { - updatesprite(level, &(player->sprite), 10, true); //position while falling (jump sprite?) - } else { - updatesprite(level, &(player->sprite), 21, true); //position falling and carry (jump and carry sprite?) - } - player->sprite.flipped = (SENSX < 0); -} - static int XACCELERATION(TITUS_player *player, int16 maxspeed) { //Sideway acceleration int16 changeX; @@ -771,7 +955,27 @@ static int YACCELERATION(TITUS_player *player, int16 maxspeed) { } -static int BLOCK_YYPRG(TITUS_level *level, uint8 floor, uint8 floor_above, uint8 tileY, uint8 tileX) { +void ARAB_BLOCK_YU(TITUS_player *player) { + //Floor; the player will not fall through + POCKET_FLAG = true; + player->GLISSE = 0; + if (player->sprite.speedY < 0) { + YFALL = YFALL | 0x01; + return; + } + player->sprite.y = player->sprite.y & 0xFFF0; + player->sprite.speedY = 0; + subto0(&SAUT_FLAG); + SAUT_COUNT = 0; + YFALL = 2; +} + +void ARAB_TOMBE_F() { + //Player free fall (doesn't touch floor) + YFALL = YFALL | 0x01; +} + +static void BLOCK_YYPRG(TITUS_level *level, uint8 floor, uint8 floor_above, uint8 tileY, uint8 tileX) { //Action on different floor flags TITUS_player *player = &(level->player); uint8 order; @@ -875,24 +1079,14 @@ static int BLOCK_YYPRG(TITUS_level *level, uint8 floor, uint8 floor_above, uint8 } } -ARAB_TOMBE_F() { - //Player free fall (doesn't touch floor) - YFALL = YFALL | 0x01; -} - -ARAB_BLOCK_YU(TITUS_player *player) { - //Floor; the player will not fall through - POCKET_FLAG = true; - player->GLISSE = 0; - if (player->sprite.speedY < 0) { - YFALL = YFALL | 0x01; - return; +void INC_ENERGY(TITUS_level *level) { + TITUS_player *player = &(level->player); + BAR_FLAG = 50; + player->hp++; + if (player->hp > MAXIMUM_ENERGY) { + player->hp = MAXIMUM_ENERGY; + level->extrabonus++; } - player->sprite.y = player->sprite.y & 0xFFF0; - player->sprite.speedY = 0; - subto0(&SAUT_FLAG); - SAUT_COUNT = 0; - YFALL = 2; } static int CASE_BONUS(TITUS_level *level, uint8 tileY, uint8 tileX) { @@ -949,17 +1143,7 @@ static int CASE_SECU(TITUS_level *level, uint8 tileY, uint8 tileX) { } } -INC_ENERGY(TITUS_level *level) { - TITUS_player *player = &(level->player); - BAR_FLAG = 50; - player->hp++; - if (player->hp > MAXIMUM_ENERGY) { - player->hp = MAXIMUM_ENERGY; - level->extrabonus++; - } -} - -DEC_ENERGY(TITUS_level *level) { +void DEC_ENERGY(TITUS_level *level) { TITUS_player *player = &(level->player); BAR_FLAG = 50; if (RESETLEVEL_FLAG == 0) { @@ -971,6 +1155,24 @@ DEC_ENERGY(TITUS_level *level) { } } +void DECELERATION(TITUS_player *player) { + //Stop acceleration + uint8 friction = (3 * 4) >> player->GLISSE; + int16 speed; + if (player->sprite.speedX < 0) { + speed = player->sprite.speedX + friction; + if (speed > 0) { + speed = 0; + } + } else { + speed = player->sprite.speedX - friction; + if (speed < 0) { + speed = 0; + } + } + player->sprite.speedX = speed; +} + static int ACTION_PRG(TITUS_level *level, uint8 action) { //Action dependent code TITUS_player *player = &(level->player); @@ -1419,24 +1621,6 @@ static int ACTION_PRG(TITUS_level *level, uint8 action) { } -DECELERATION(TITUS_player *player) { - //Stop acceleration - uint8 friction = (3 * 4) >> player->GLISSE; - int16 speed; - if (player->sprite.speedX < 0) { - speed = player->sprite.speedX + friction; - if (speed > 0) { - speed = 0; - } - } else { - speed = player->sprite.speedX - friction; - if (speed < 0) { - speed = 0; - } - } - player->sprite.speedX = speed; -} - static int NEW_FORM(TITUS_player *player, uint8 action) { //if the order is changed, change player animation if ((LAST_ORDER != action) || (player->sprite.animation == NULL)) { @@ -1477,153 +1661,3 @@ int16 add_carry() { return 0; } } - -COLLISION_TRP(TITUS_level *level) { - //Player versus elevators - //Change player's location according to the elevator - uint8 i; - TITUS_player *player = &(level->player); - TITUS_elevator *elevator = level->elevator; - if ((player->sprite.speedY >= 0) && (CROSS_FLAG == 0)) { - for (i = 0; i < level->elevatorcount; i++) { - //Quick test - if (!(elevator[i].enabled) || - !(elevator[i].sprite.visible) || - (abs(elevator[i].sprite.x - player->sprite.x) >= 64) || - (abs(elevator[i].sprite.y - player->sprite.y) >= 16)) { - continue; - } - - //Real test - if (player->sprite.x - level->spritedata[0]->refwidth < elevator[i].sprite.x) { //The elevator is right - if (player->sprite.x - level->spritedata[0]->refwidth + level->spritedata[0]->collwidth <= elevator[i].sprite.x) { //player->sprite must be 0 - continue; //The elevator is too far right - } - } else { //The elevator is left - if (player->sprite.x - level->spritedata[0]->refwidth >= elevator[i].sprite.x + elevator[i].sprite.spritedata->collwidth) { - continue; //The elevator is too far left - } - } - - if (player->sprite.y - 6 < elevator[i].sprite.y) { //The elevator is below - if (player->sprite.y - 6 + 8 <= elevator[i].sprite.y) { - continue; //The elevator is too far below - } - } else { //The elevator is above - if (player->sprite.y - 6 >= elevator[i].sprite.y + elevator[i].sprite.spritedata->collheight) { - continue; //The elevator is too far above - } - } - - //Skip fall-through-tile action (ACTION_TIMER == 15) - if (ACTION_TIMER == 14) { - ACTION_TIMER = 16; - } - - YFALL = 0; - player->sprite.y = elevator[i].sprite.y; - - player->sprite.speedY = 0; - subto0(&(SAUT_FLAG)); - SAUT_COUNT = 0; - YFALL = 2; - - player->sprite.x += elevator[i].sprite.speedX; - if (elevator[i].sprite.speedY > 0) { //Going down - player->sprite.y += elevator[i].sprite.speedY; - } - return; - } - } -} - -COLLISION_OBJET(TITUS_level *level) { - //Player versus objects - //Collision, spring state, speed up carpet/scooter/skateboard, bounce bouncy objects - TITUS_player *player = &(level->player); - TITUS_object *off_object; - if (player->sprite.speedY < 0) { - return; - } - //Collision with a sprite - if (!(SPRITES_VS_SPRITES(level, &(player->sprite), &(level->spritedata[0]), &off_object))) { //check if player stands on an object, use sprite[0] (rest) as collision size (first player tile) - return; - } - player->sprite.y = off_object->sprite.y - off_object->sprite.spritedata->collheight; - //If the foot is placed on a spring, it must be soft! - if ((off_object->sprite.number == FIRST_OBJET + 24) || (off_object->sprite.number == FIRST_OBJET + 25)) { - off_object->sprite.UNDER = off_object->sprite.UNDER | 0x02; - off_object->sprite.ONTOP = &(player->sprite); - } - //If we jump on the flying carpet, let it fly - if ((off_object->sprite.number == FIRST_OBJET + 21) || (off_object->sprite.number == FIRST_OBJET + 22)) { //Flying carpet - if (!(player->sprite.flipped)) { - off_object->sprite.speedX = 6 * 16; - } else { - off_object->sprite.speedX = 0 - 6 * 16; - } - off_object->sprite.flipped = player->sprite.flipped; - GRAVITY_FLAG = 4; - TAPISWAIT_FLAG = 0; - } else if ((ACTION_TIMER > 10) && //delay - ((LAST_ORDER & 0x0F) == 0) && //Player rests - (player->sprite.speedY == 0) && //stable Y - ((off_object->sprite.number == 83) || //scooter - (off_object->sprite.number == 94))) { //skateboard - - //If you put your foot on a scooter or a skateboard - if (!(player->sprite.flipped)) { - off_object->sprite.speedX = 16 * 3; - } else { - off_object->sprite.speedX = 0 - 16 * 3; - } - off_object->sprite.flipped = player->sprite.flipped; - GRAVITY_FLAG = 4; - } - - if (off_object->sprite.speedX < 0) { - player->sprite.speedX = off_object->sprite.speedX; - } else if (off_object->sprite.speedX > 0) { - player->sprite.speedX = off_object->sprite.speedX + 16; - } - - //If we want to CROSS (cross) it does not bounce - if ((CROSS_FLAG == 0) && //No long kneestand - (player->sprite.speedY > (16 * 3)) && - (off_object->objectdata->bounce)) { - //Bounce on a ball if no long kneestand (down key) - if (keystate[KEY_DOWN]) { - player->sprite.speedY = 0; - } else { - if (keystate[KEY_UP] || keystate[KEY_JUMP]) { - player->sprite.speedY += 16 * 3; //increase speed - } else { - player->sprite.speedY -= 16; //reduce speed - } - player->sprite.speedY = 0 - player->sprite.speedY; - if (player->sprite.speedY > 0) { - player->sprite.speedY = 0; - } - } - ACTION_TIMER = 0; - - //If the ball lies on the ground - if (off_object->sprite.speedY == 0) { -#ifdef AUDIO_ENABLED - FX_START(12); //Sound effect -#endif - off_object->sprite.speedY = 0 - player->sprite.speedY; - off_object->sprite.y -= off_object->sprite.speedY >> 4; - GRAVITY_FLAG = 4; - } - } else { - if (off_object->sprite.speedY != 0) { - player->sprite.speedY = off_object->sprite.speedY; - } else { - player->sprite.speedY = 0; - } - subto0(&(SAUT_FLAG)); - SAUT_COUNT = 0; - YFALL = 2; - } -} diff --git a/src/reset.c b/src/reset.c index 5c99e2e..a8cd9e2 100644 --- a/src/reset.c +++ b/src/reset.c @@ -41,6 +41,23 @@ #include "player.h" #include "objects.h" #include "enemies.h" +#include "tile_animation.h" +#include "engine.h" +#include "audio.h" +#include "keyboard.h" + +bool NOSCROLL_FLAG; +bool NEWLEVEL_FLAG; //Finish a level +bool NFC_FLAG; //Skip NO_FAST_CPU + +void MOVE_HIM(TITUS_level *level, TITUS_sprite *spr) { + int16 *pointer = spr->animation + 1; + while (*pointer < 0) { + pointer += (*pointer / 2); //End of animation, jump back + } + updatesprite(level, spr, *pointer, true); + spr->animation = pointer; +} //Possible return states: @@ -49,7 +66,6 @@ //2 - Game over //3 - Death - uint8 RESET_LEVEL(TITUS_level *level) { TITUS_player *player = &(level->player); bool pass; @@ -179,102 +195,7 @@ uint8 RESET_LEVEL(TITUS_level *level) { return 0; } - -MOVE_HIM(TITUS_level *level, TITUS_sprite *spr) { - int16 *pointer = spr->animation + 1; - while (*pointer < 0) { - pointer += (*pointer / 2); //End of animation, jump back - } - updatesprite(level, spr, *pointer, true); - spr->animation = pointer; -} - - -int CLEAR_DATA(TITUS_level *level) { - loop_cycle = 0; - tile_anim = 0; - BIGNMI_NBR = 0; - IMAGE_COUNTER = 0; - TAUPE_FLAG = 0; - GRANDBRULE_FLAG = 0; - NOSCROLL_FLAG = 0; - TAPISWAIT_FLAG = 0; - TAPISFLY_FLAG = 0; - FUME_FLAG = 0; - BAR_FLAG = 0; - X_FLAG = 0; - Y_FLAG = 0; - CARRY_FLAG = 0; - DROP_FLAG = 0; - DROPREADY_FLAG = 0; - POSEREADY_FLAG = 0; - LADDER_FLAG = 0; - PRIER_FLAG = 0; - SAUT_FLAG = 0; - CROSS_FLAG = 0; - GRAVITY_FLAG = 0; - FURTIF_FLAG = 0; - CHOC_FLAG = 0; - KICK_FLAG = 0; - SEECHOC_FLAG = 0; - RESETLEVEL_FLAG = 0; - GAMEOVER_FLAG = false; - NEWLEVEL_FLAG = false; - NFC_FLAG = false; - INVULNERABLE_FLAG = 0; - POCKET_FLAG = 0; - SAUT_COUNT = 0; - ACTION_TIMER = 0; - XSCROLL_CENTER = 0; - YSCROLL_CENTER = 0; - XLIMIT_SCROLL = 0; - YLIMIT_SCROLL = 0; - YFALL = 0; - - TAPISFLY_FLAG = 0; - CROSS_FLAG = 0; - GRAVITY_FLAG = 4; - LADDER_FLAG = 0; - FURTIF_FLAG = 0; - KICK_FLAG = 0; - CHOC_FLAG = 0; - FUME_FLAG = 0; - DROP_FLAG = 0; - CARRY_FLAG = 0; - NOSCROLL_FLAG = 0; - GAMEOVER_FLAG = 0; - NEWLEVEL_FLAG = false; - RESETLEVEL_FLAG = 0; - INVULNERABLE_FLAG = 0; - TAUPE_FLAG = 0; - SENSX = 0; - LAST_ORDER = 0; - - SET_ALL_SPRITES(level); - - SET_DATA_NMI(level); - -} - - -SET_DATA_NMI(TITUS_level *level) { - boss_alive = false; - int i, anim; - for (i = 0; i < level->enemycount; i++) { - anim = -1; - if (!level->enemy[i].init_enabled) continue; - do { - anim++; - } while (anim_enemy[anim] + FIRST_NMI != level->enemy[i].sprite.number); - level->enemy[i].sprite.animation = &(anim_enemy[anim]); - if (level->enemy[i].boss) { - boss_alive = true; - } - } - BIGNMI_POWER = NMI_POWER[level->levelid]; -} - -clearsprite(TITUS_sprite *spr){ +void clearsprite(TITUS_sprite *spr){ //SDL_FreeSurface(spr->buffer); //spr->buffer = NULL; spr->enabled = false; @@ -295,11 +216,9 @@ clearsprite(TITUS_sprite *spr){ spr->droptobottom = false; spr->killing = false; spr->invisible = false; - return (0); } - -SET_ALL_SPRITES(TITUS_level *level) { +void SET_ALL_SPRITES(TITUS_level *level) { int16 i; TITUS_player *player = &(level->player); @@ -369,3 +288,87 @@ SET_ALL_SPRITES(TITUS_level *level) { level->player.animcycle = 0; updatesprite(level, &(level->player.sprite), 0, true); } + +void SET_DATA_NMI(TITUS_level *level) { + boss_alive = false; + int i, anim; + for (i = 0; i < level->enemycount; i++) { + anim = -1; + if (!level->enemy[i].init_enabled) continue; + do { + anim++; + } while (anim_enemy[anim] + FIRST_NMI != level->enemy[i].sprite.number); + level->enemy[i].sprite.animation = &(anim_enemy[anim]); + if (level->enemy[i].boss) { + boss_alive = true; + } + } + BIGNMI_POWER = NMI_POWER[level->levelid]; +} + +int CLEAR_DATA(TITUS_level *level) { + loop_cycle = 0; + tile_anim = 0; + IMAGE_COUNTER = 0; + TAUPE_FLAG = 0; + GRANDBRULE_FLAG = 0; + NOSCROLL_FLAG = 0; + TAPISWAIT_FLAG = 0; + TAPISFLY_FLAG = 0; + FUME_FLAG = 0; + BAR_FLAG = 0; + X_FLAG = 0; + Y_FLAG = 0; + CARRY_FLAG = 0; + DROP_FLAG = 0; + DROPREADY_FLAG = 0; + POSEREADY_FLAG = 0; + LADDER_FLAG = 0; + PRIER_FLAG = 0; + SAUT_FLAG = 0; + CROSS_FLAG = 0; + GRAVITY_FLAG = 0; + FURTIF_FLAG = 0; + CHOC_FLAG = 0; + KICK_FLAG = 0; + SEECHOC_FLAG = 0; + RESETLEVEL_FLAG = 0; + GAMEOVER_FLAG = false; + NEWLEVEL_FLAG = false; + NFC_FLAG = false; + INVULNERABLE_FLAG = 0; + POCKET_FLAG = 0; + SAUT_COUNT = 0; + ACTION_TIMER = 0; + XSCROLL_CENTER = 0; + YSCROLL_CENTER = 0; + XLIMIT_SCROLL = 0; + YLIMIT_SCROLL = 0; + YFALL = 0; + + TAPISFLY_FLAG = 0; + CROSS_FLAG = 0; + GRAVITY_FLAG = 4; + LADDER_FLAG = 0; + FURTIF_FLAG = 0; + KICK_FLAG = 0; + CHOC_FLAG = 0; + FUME_FLAG = 0; + DROP_FLAG = 0; + CARRY_FLAG = 0; + NOSCROLL_FLAG = 0; + GAMEOVER_FLAG = 0; + NEWLEVEL_FLAG = false; + RESETLEVEL_FLAG = 0; + INVULNERABLE_FLAG = 0; + TAUPE_FLAG = 0; + SENSX = 0; + LAST_ORDER = 0; + + SET_ALL_SPRITES(level); + + SET_DATA_NMI(level); + +} + + diff --git a/src/scroll.c b/src/scroll.c index 68cc897..b0730fa 100644 --- a/src/scroll.c +++ b/src/scroll.c @@ -34,35 +34,26 @@ #include "definitions.h" #include "backbuffer.h" #include "scroll.h" +#include "level.h" +#include "gates.h" +#include "player.h" +bool PERMUT_FLAG; //If false, there are no animated tiles on the screen? +uint8 loop_cycle; //Increased every loop in game loop +uint8 tile_anim; //Current tile animation (0-1-2), changed every 4th game loop cycle +uint8 BITMAP_X; //Screen offset (X) in tiles +uint8 BITMAP_XM; //Point to the left tile in the tile screen (0 to 19) +uint8 BITMAP_Y; //Screen offset (Y) in tiles +uint8 BITMAP_YM; //Point to the top tile in the tile screen (0 to 11) +bool XSCROLL_CENTER; //If true, the screen will scroll in X +int16 XLIMIT_SCROLL; //If scrolling: scroll until player is in this tile (X) +bool YSCROLL_CENTER; //If true, the screen will scroll in Y +uint8 YLIMIT_SCROLL; //If scrolling: scroll until player is in this tile (Y) static uint8 BARRYCENTRE(TITUS_level *level); static int REFRESH_COLUMNS(TITUS_level *level, int8 column); static int REFRESH_LINE(TITUS_level *level, int8 line); -bool L_SCROLL(TITUS_level *level); -bool R_SCROLL(TITUS_level *level); -bool U_SCROLL(TITUS_level *level); -bool D_SCROLL(TITUS_level *level); - -int scroll(TITUS_level *level) { - //Scroll screen and update tile animation - loop_cycle++; //Cycle from 0 to 3 - if (loop_cycle > 3) { - loop_cycle = 0; - } - if (loop_cycle == 0) { //Every 4th call - tile_anim++; //Cycle tile animation (0-1-2) - if (tile_anim > 2) { - tile_anim = 0; - } - } - //Scroll - if (!NOSCROLL_FLAG) { - X_ADJUST(level); - Y_ADJUST(level); - } -} -X_ADJUST(TITUS_level *level) { +void X_ADJUST(TITUS_level *level) { bool block; TITUS_player *player = &(level->player); int16 pstileX = (player->sprite.x >> 4) - BITMAP_X; //Player screen tile X (0 to 19) @@ -133,7 +124,7 @@ X_ADJUST(TITUS_level *level) { } } -Y_ADJUST(TITUS_level *level) { +void Y_ADJUST(TITUS_level *level) { TITUS_player *player = &(level->player); if (player->sprite.speedY == 0) { YSCROLL_CENTER = false; @@ -189,6 +180,25 @@ Y_ADJUST(TITUS_level *level) { } } +int scroll(TITUS_level *level) { + //Scroll screen and update tile animation + loop_cycle++; //Cycle from 0 to 3 + if (loop_cycle > 3) { + loop_cycle = 0; + } + if (loop_cycle == 0) { //Every 4th call + tile_anim++; //Cycle tile animation (0-1-2) + if (tile_anim > 2) { + tile_anim = 0; + } + } + //Scroll + if (!NOSCROLL_FLAG) { + X_ADJUST(level); + Y_ADJUST(level); + } +} + static uint8 BARRYCENTRE(TITUS_level *level) { //If an enemy is behind the player, max. 12.5 tiles away horizontally, scroll until player is in the middle diff --git a/src/settings.c b/src/settings.c index a606475..16b6941 100644 --- a/src/settings.c +++ b/src/settings.c @@ -38,6 +38,40 @@ #include "config.h" #endif +char spritefile[256]; +char levelfiles[16][256]; //16 levels in moktar, 15 levels in titus +char tituslogofile[256]; +int tituslogoformat; +char titusintrofile[256]; +int titusintroformat; +char titusmenufile[256]; +int titusmenuformat; +char titusfinishfile[256]; +int titusfinishformat; +char fontfile[256]; +int levelcount; +int devmode; +int reswidth; +int resheight; +int bitdepth; +int ingamewidth; +int ingameheight; +int videomode; +int game; + +char levelcode[16][5]; +char leveltitle[16][41]; + +char moduleintrofile[256]; //.mod file +int moduleintrofileloop; //loop info +char moduleprelevelfile[256]; +int moduleprelevelfileloop; +char modulelevelfile[6][256]; //6 different level files +int modulelevelfileloop[6]; +char modulegameoverfile[256]; +int modulegameoverfileloop; +char modulelevel[16]; //Link to modulelevelfiles + int readconfig(char *configfile) { char line[300], tmp[256]; int retval, i, j, tmpcount = 0; diff --git a/src/sprites.c b/src/sprites.c index 6368766..64c4fb6 100644 --- a/src/sprites.c +++ b/src/sprites.c @@ -36,6 +36,9 @@ #include "tituserror.h" #include "globals.h" #include "definitions.h" +#include "engine.h" +#include "player.h" +#include "objects.h" SDL_Surface * copysurface(SDL_Surface * original, bool flip, bool flash){ int i, j; @@ -244,37 +247,7 @@ int copypixelformat(SDL_PixelFormat * destformat, SDL_PixelFormat * srcformat) { return 0; } -SPRITES_ANIMATION(TITUS_level *level) { - int16 i; - //Animate player - if ((LAST_ORDER == 0) && - (POCKET_FLAG) && - (ACTION_TIMER >= 35*4)) { - updatesprite(level, &(level->player.sprite), 29, false); //"Pause"-sprite - if (ACTION_TIMER >= 35*5) { - updatesprite(level, &(level->player.sprite), 0, false); //Normal player sprite - ACTION_TIMER = 0; - } - } - //Animate other objects - - animate_sprite(level, &(level->player.sprite2)); - animate_sprite(level, &(level->player.sprite3)); - - for (i = 0; i < level->objectcount; i++) { - animate_sprite(level, &(level->object[i].sprite)); - } - - for (i = 0; i < level->enemycount; i++) { - animate_sprite(level, &(level->enemy[i].sprite)); - } - - for (i = 0; i < level->elevatorcount; i++) { - animate_sprite(level, &(level->elevator[i].sprite)); - } -} - -animate_sprite(TITUS_level *level, TITUS_sprite *spr) { +void animate_sprite(TITUS_level *level, TITUS_sprite *spr) { if (!spr->visible) return; //Not on screen? if (!spr->enabled) return; if (spr->number == (FIRST_OBJET+26)) { //Cage @@ -319,6 +292,36 @@ animate_sprite(TITUS_level *level, TITUS_sprite *spr) { } } +void SPRITES_ANIMATION(TITUS_level *level) { + int16 i; + //Animate player + if ((LAST_ORDER == 0) && + (POCKET_FLAG) && + (ACTION_TIMER >= 35*4)) { + updatesprite(level, &(level->player.sprite), 29, false); //"Pause"-sprite + if (ACTION_TIMER >= 35*5) { + updatesprite(level, &(level->player.sprite), 0, false); //Normal player sprite + ACTION_TIMER = 0; + } + } + //Animate other objects + + animate_sprite(level, &(level->player.sprite2)); + animate_sprite(level, &(level->player.sprite3)); + + for (i = 0; i < level->objectcount; i++) { + animate_sprite(level, &(level->object[i].sprite)); + } + + for (i = 0; i < level->enemycount; i++) { + animate_sprite(level, &(level->enemy[i].sprite)); + } + + for (i = 0; i < level->elevatorcount; i++) { + animate_sprite(level, &(level->elevator[i].sprite)); + } +} + int updatesprite(TITUS_level *level, TITUS_sprite *spr, int16 number, bool clearflags){ spr->number = number; diff --git a/src/tile_animation.c b/src/tile_animation.c index 093bf0f..674cdc7 100644 --- a/src/tile_animation.c +++ b/src/tile_animation.c @@ -32,8 +32,9 @@ #include "level.h" #include "globals.h" #include "definitions.h" +#include "scroll.h" -BLOC_ANIMATION(TITUS_level *level) { +void BLOC_ANIMATION(TITUS_level *level) { //Draw animated sprites on OFS_SCREENM uint8 tmp_ym, curY, tmp_xm, curX; uint8 i, j; diff --git a/src/viewimage.c b/src/viewimage.c index a49c774..c89b076 100644 --- a/src/viewimage.c +++ b/src/viewimage.c @@ -35,6 +35,7 @@ #include "backbuffer.h" #include "globals.h" #include "common.h" +#include "keyboard.h" //Probably not the best way, but it works... #define HAVE_CONFIG_H 1