From f763376ee4db2d91fc27d809defdff6067b81181 Mon Sep 17 00:00:00 2001 From: pelya Date: Mon, 9 Jun 2014 15:54:16 +0300 Subject: [PATCH] OpenTyrian: merged upstream changes --- project/jni/application/opentyrian/CREDITS | 11 +- project/jni/application/opentyrian/README | 2 +- .../jni/application/opentyrian/src/animlib.c | 3 +- .../jni/application/opentyrian/src/animlib.h | 3 +- .../application/opentyrian/src/arg_parse.c | 2 +- .../application/opentyrian/src/arg_parse.h | 2 +- .../jni/application/opentyrian/src/backgrnd.c | 63 +- .../jni/application/opentyrian/src/backgrnd.h | 8 +- .../jni/application/opentyrian/src/config.c | 40 +- .../jni/application/opentyrian/src/config.h | 16 +- .../jni/application/opentyrian/src/destruct.c | 484 ++-- .../jni/application/opentyrian/src/destruct.h | 3 +- .../jni/application/opentyrian/src/editship.c | 3 +- .../jni/application/opentyrian/src/editship.h | 3 +- .../jni/application/opentyrian/src/episodes.c | 49 +- .../jni/application/opentyrian/src/episodes.h | 12 +- project/jni/application/opentyrian/src/file.c | 14 +- project/jni/application/opentyrian/src/file.h | 3 +- .../jni/application/opentyrian/src/fm_synth.c | 54 - .../jni/application/opentyrian/src/fm_synth.h | 35 - .../jni/application/opentyrian/src/fmopl.c | 2400 ----------------- .../jni/application/opentyrian/src/fmopl.h | 253 -- project/jni/application/opentyrian/src/font.c | 123 +- project/jni/application/opentyrian/src/font.h | 2 +- .../jni/application/opentyrian/src/fonthand.c | 3 +- .../jni/application/opentyrian/src/fonthand.h | 3 +- .../application/opentyrian/src/game_menu.c | 217 +- .../application/opentyrian/src/game_menu.h | 5 +- .../jni/application/opentyrian/src/helptext.c | 129 +- .../jni/application/opentyrian/src/helptext.h | 81 +- .../application/opentyrian/src/hg_revision.h | 2 +- .../jni/application/opentyrian/src/joystick.c | 5 +- .../jni/application/opentyrian/src/joystick.h | 3 +- .../jni/application/opentyrian/src/jukebox.c | 5 +- .../jni/application/opentyrian/src/jukebox.h | 3 +- .../jni/application/opentyrian/src/keyboard.c | 53 +- .../jni/application/opentyrian/src/keyboard.h | 10 +- .../jni/application/opentyrian/src/lds_play.c | 8 +- .../jni/application/opentyrian/src/lds_play.h | 5 +- .../jni/application/opentyrian/src/loudness.c | 12 +- .../jni/application/opentyrian/src/loudness.h | 9 +- .../jni/application/opentyrian/src/lvllib.c | 3 +- .../jni/application/opentyrian/src/lvllib.h | 3 +- .../jni/application/opentyrian/src/lvlmast.c | 3 +- .../jni/application/opentyrian/src/lvlmast.h | 16 +- project/jni/application/opentyrian/src/main.m | 5 +- .../jni/application/opentyrian/src/mainint.c | 431 ++- .../jni/application/opentyrian/src/mainint.h | 3 +- .../jni/application/opentyrian/src/menus.c | 40 +- .../jni/application/opentyrian/src/menus.h | 12 +- .../application/opentyrian/src/mingw_fixes.c | 2 +- .../application/opentyrian/src/mingw_fixes.h | 2 +- .../jni/application/opentyrian/src/mouse.c | 3 +- .../jni/application/opentyrian/src/mouse.h | 3 +- .../jni/application/opentyrian/src/mtrand.c | 1 - .../jni/application/opentyrian/src/mtrand.h | 3 +- .../jni/application/opentyrian/src/musmast.c | 3 +- .../jni/application/opentyrian/src/musmast.h | 3 +- .../jni/application/opentyrian/src/network.c | 152 +- .../jni/application/opentyrian/src/network.h | 25 +- .../jni/application/opentyrian/src/nortsong.c | 5 +- .../jni/application/opentyrian/src/nortsong.h | 3 +- .../jni/application/opentyrian/src/nortvars.c | 3 +- .../jni/application/opentyrian/src/nortvars.h | 3 +- .../jni/application/opentyrian/src/opentyr.c | 323 +-- .../jni/application/opentyrian/src/opentyr.h | 9 +- project/jni/application/opentyrian/src/opl.c | 1464 ++++++++++ project/jni/application/opentyrian/src/opl.h | 202 ++ .../jni/application/opentyrian/src/palette.c | 13 +- .../jni/application/opentyrian/src/palette.h | 3 +- .../jni/application/opentyrian/src/params.c | 6 +- .../jni/application/opentyrian/src/params.h | 3 +- .../jni/application/opentyrian/src/pcxload.c | 3 +- .../jni/application/opentyrian/src/pcxload.h | 3 +- .../jni/application/opentyrian/src/pcxmast.c | 3 +- .../jni/application/opentyrian/src/pcxmast.h | 3 +- .../jni/application/opentyrian/src/picload.c | 3 +- .../jni/application/opentyrian/src/picload.h | 3 +- .../jni/application/opentyrian/src/player.c | 2 +- .../jni/application/opentyrian/src/player.h | 2 +- .../jni/application/opentyrian/src/scroller.c | 17 +- .../jni/application/opentyrian/src/scroller.h | 3 +- .../jni/application/opentyrian/src/setup.c | 5 +- .../jni/application/opentyrian/src/setup.h | 3 +- .../jni/application/opentyrian/src/shots.c | 499 ++++ .../jni/application/opentyrian/src/shots.h | 58 + .../jni/application/opentyrian/src/sizebuf.c | 4 +- .../jni/application/opentyrian/src/sizebuf.h | 2 +- .../jni/application/opentyrian/src/sndmast.c | 3 +- .../jni/application/opentyrian/src/sndmast.h | 3 +- .../jni/application/opentyrian/src/sprite.c | 35 +- .../jni/application/opentyrian/src/sprite.h | 10 +- .../jni/application/opentyrian/src/starlib.c | 3 +- .../jni/application/opentyrian/src/starlib.h | 3 +- .../jni/application/opentyrian/src/tyrian2.c | 867 +++--- .../jni/application/opentyrian/src/tyrian2.h | 11 +- project/jni/application/opentyrian/src/varz.c | 256 +- project/jni/application/opentyrian/src/varz.h | 36 +- .../jni/application/opentyrian/src/vga256d.c | 3 +- .../jni/application/opentyrian/src/vga256d.h | 3 +- .../jni/application/opentyrian/src/video.c | 20 +- .../jni/application/opentyrian/src/video.h | 6 +- .../application/opentyrian/src/video_scale.c | 3 +- .../application/opentyrian/src/video_scale.h | 3 +- .../opentyrian/src/video_scale_hqNx.c | 2 +- project/jni/application/opentyrian/src/xmas.c | 2 +- project/jni/application/opentyrian/src/xmas.h | 3 +- 107 files changed, 3956 insertions(+), 4820 deletions(-) delete mode 100644 project/jni/application/opentyrian/src/fm_synth.c delete mode 100644 project/jni/application/opentyrian/src/fm_synth.h delete mode 100644 project/jni/application/opentyrian/src/fmopl.c delete mode 100644 project/jni/application/opentyrian/src/fmopl.h create mode 100644 project/jni/application/opentyrian/src/opl.c create mode 100644 project/jni/application/opentyrian/src/opl.h create mode 100644 project/jni/application/opentyrian/src/shots.c create mode 100644 project/jni/application/opentyrian/src/shots.h diff --git a/project/jni/application/opentyrian/CREDITS b/project/jni/application/opentyrian/CREDITS index da4b3f0b6..1ce39c65a 100644 --- a/project/jni/application/opentyrian/CREDITS +++ b/project/jni/application/opentyrian/CREDITS @@ -1,8 +1,8 @@ -OpenTyrian Classic Development Team +The OpenTyrian Development Team ================================================================================ Carl W. Reinke (Mindless) -Yuri K. Schlesner (yuriks) +Yuri K. Schlesner (yuriks) Casey A. McCann (syntaxglitch) == Contributors ================================================================ @@ -24,8 +24,9 @@ Jan "heftig" Steffens clean-up patches Jason Emery * Tyrian source code -MAME and DOSBox - * FM emulator code +DOSBox + * FM Sythesis emulator code AdPlug - * Loudness player + * Loudness player code + diff --git a/project/jni/application/opentyrian/README b/project/jni/application/opentyrian/README index 029d735fa..7f5fd5ba6 100644 --- a/project/jni/application/opentyrian/README +++ b/project/jni/application/opentyrian/README @@ -1,4 +1,4 @@ -OpenTyrian Classic +OpenTyrian ================================================================================ OpenTyrian is an open-source port of the DOS game Tyrian. diff --git a/project/jni/application/opentyrian/src/animlib.c b/project/jni/application/opentyrian/src/animlib.c index ba42513f8..7afeb4758 100644 --- a/project/jni/application/opentyrian/src/animlib.c +++ b/project/jni/application/opentyrian/src/animlib.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -428,4 +428,3 @@ int JE_playRunSkipDump( Uint8 *incomingBuffer, unsigned int IncomingBufferLength return(0); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/animlib.h b/project/jni/application/opentyrian/src/animlib.h index 298e3cfd6..502f002bc 100644 --- a/project/jni/application/opentyrian/src/animlib.h +++ b/project/jni/application/opentyrian/src/animlib.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -25,4 +25,3 @@ void JE_playAnim( const char *animfile, JE_byte startingframe, JE_byte speed ); #endif /* ANIMLIB_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/arg_parse.c b/project/jni/application/opentyrian/src/arg_parse.c index 4d7c2c487..cf932caa9 100644 --- a/project/jni/application/opentyrian/src/arg_parse.c +++ b/project/jni/application/opentyrian/src/arg_parse.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or diff --git a/project/jni/application/opentyrian/src/arg_parse.h b/project/jni/application/opentyrian/src/arg_parse.h index 0334f5be7..fe15fd8f9 100644 --- a/project/jni/application/opentyrian/src/arg_parse.h +++ b/project/jni/application/opentyrian/src/arg_parse.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or diff --git a/project/jni/application/opentyrian/src/backgrnd.c b/project/jni/application/opentyrian/src/backgrnd.c index 208f2a3ee..556e51967 100644 --- a/project/jni/application/opentyrian/src/backgrnd.c +++ b/project/jni/application/opentyrian/src/backgrnd.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -20,6 +20,7 @@ #include "backgrnd.h" #include "config.h" +#include "mtrand.h" #include "varz.h" #include "video.h" @@ -465,4 +466,62 @@ void blur_filter( SDL_Surface *dst, SDL_Surface *src ) } } -// kate: tab-width 4; vim: set noet: + +/* Background Starfield */ +typedef struct +{ + Uint8 color; + JE_word position; // relies on overflow wrap-around + int speed; +} StarfieldStar; + +#define MAX_STARS 100 +#define STARFIELD_HUE 0x90 +static StarfieldStar starfield_stars[MAX_STARS]; +int starfield_speed; + +void initialize_starfield( void ) +{ + for (int i = MAX_STARS-1; i >= 0; --i) + { + starfield_stars[i].position = mt_rand() % 320 + mt_rand() % 200 * VGAScreen->pitch; + starfield_stars[i].speed = mt_rand() % 3 + 2; + starfield_stars[i].color = mt_rand() % 16 + STARFIELD_HUE; + } +} + +void update_and_draw_starfield( SDL_Surface* surface, int move_speed ) +{ + Uint8* p = (Uint8*)surface->pixels; + + for (int i = MAX_STARS-1; i >= 0; --i) + { + StarfieldStar* star = &starfield_stars[i]; + + star->position += (star->speed + move_speed) * surface->pitch; + + if (star->position < 177 * surface->pitch) + { + if (p[star->position] == 0) + { + p[star->position] = star->color; + } + + // If star is bright enough, draw surrounding pixels + if (star->color - 4 >= STARFIELD_HUE) + { + if (p[star->position + 1] == 0) + p[star->position + 1] = star->color - 4; + + if (star->position > 0 && p[star->position - 1] == 0) + p[star->position - 1] = star->color - 4; + + if (p[star->position + surface->pitch] == 0) + p[star->position + surface->pitch] = star->color - 4; + + if (star->position >= surface->pitch && p[star->position - surface->pitch] == 0) + p[star->position - surface->pitch] = star->color - 4; + } + } + } +} diff --git a/project/jni/application/opentyrian/src/backgrnd.h b/project/jni/application/opentyrian/src/backgrnd.h index 9287ed76e..bb3970358 100644 --- a/project/jni/application/opentyrian/src/backgrnd.h +++ b/project/jni/application/opentyrian/src/backgrnd.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -34,6 +34,8 @@ extern JE_byte map1YDelay, map1YDelayMax, map2YDelay, map2YDelayMax; extern JE_boolean anySmoothies; // if yes, I want one :D extern JE_byte smoothie_data[9]; +extern int starfield_speed; + void JE_darkenBackground( JE_word neat ); void blit_background_row( SDL_Surface *surface, int x, int y, Uint8 **map ); @@ -54,6 +56,8 @@ void blur_filter( SDL_Surface *dst, SDL_Surface *src ); /*smoothies #5 is used for 3*/ /*smoothies #9 is a vertical flip*/ +void initialize_starfield( void ); +void update_and_draw_starfield( SDL_Surface* surface, int move_speed ); + #endif /* BACKGRND_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/config.c b/project/jni/application/opentyrian/src/config.c index 941120801..f33b08075 100644 --- a/project/jni/application/opentyrian/src/config.c +++ b/project/jni/application/opentyrian/src/config.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -138,14 +138,8 @@ const JE_EditorItemAvailType initialItemAvail = JE_boolean smoothies[9] = /* [1..9] */ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - JE_byte starShowVGASpecialCode; -/* Stars */ -StarDatType starDat[MAX_STARS]; /* [1..Maxstars] */ -JE_word starY; - - /* CubeData */ JE_word lastCubeMax, cubeMax; JE_word cubeList[4]; /* [1..4] */ @@ -326,19 +320,6 @@ bool save_opentyrian_config( void ) return true; } - -void JE_setupStars( void ) -{ - int z; - - for (z = MAX_STARS; z--; ) - { - starDat[z].sLoc = (mt_rand() % 320) + (mt_rand() % 200) * VGAScreen->pitch; - starDat[z].sMov = ((mt_rand() % 3) + 2) * VGAScreen->pitch; - starDat[z].sC = (mt_rand() % 16) + (9 * 16); - } -} - static void playeritems_to_pitems( JE_PItemsType pItems, PlayerItems *items, JE_byte initial_episode_num ) { pItems[0] = items->weapon[FRONT_WEAPON].id; @@ -403,7 +384,7 @@ void JE_saveGame( JE_byte slot, const char *name ) temp = episodeNum - 1; if (temp < 1) { - temp = 4; /* JE: {Episodemax is 4 for completion purposes} */ + temp = EPISODE_AVAILABLE; /* JE: {Episodemax is 4 for completion purposes} */ } saveFiles[slot-1].episode = temp; } @@ -430,8 +411,6 @@ void JE_saveGame( JE_byte slot, const char *name ) void JE_loadGame( JE_byte slot ) { - JE_byte temp5; - superTyrian = false; onePlayerAction = false; twoPlayerMode = false; @@ -489,22 +468,22 @@ void JE_loadGame( JE_byte slot ) player[twoPlayerMode ? port : 0].items.weapon[port].power = saveFiles[slot-1].power[port]; } - temp5 = saveFiles[slot-1].episode; + int episode = saveFiles[slot-1].episode; memcpy(&levelName, &saveFiles[slot-1].levelName, sizeof(levelName)); if (strcmp(levelName, "Completed") == 0) { - if (temp5 == 4) + if (episode == EPISODE_AVAILABLE) { - temp5 = 1; - } else if (temp5 < 4) { - temp5++; + episode = 1; + } else if (episode < EPISODE_AVAILABLE) { + episode++; } - /* Increment 1-3 to 2-4. Episode 4 goes to 1. Episode 5 stands still. */ + /* Increment episode. Episode EPISODE_AVAILABLE goes to 1. */ } - JE_initEpisode(temp5); + JE_initEpisode(episode); saveLevel = mainLevel; memcpy(&lastLevelName, &levelName, sizeof(levelName)); } @@ -1050,4 +1029,3 @@ void JE_saveConfiguration( void ) #endif } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/config.h b/project/jni/application/opentyrian/src/config.h index fca40f48d..f12af5df9 100644 --- a/project/jni/application/opentyrian/src/config.h +++ b/project/jni/application/opentyrian/src/config.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -28,8 +28,6 @@ #define SAVE_FILES_NUM (11 * 2) -#define MAX_STARS 100 - /* These are necessary because the size of the structure has changed from the original, but we need to know the original sizes in order to find things in TYRIAN.SAV */ #define SAVE_FILES_SIZE 2398 @@ -74,13 +72,6 @@ typedef struct typedef JE_SaveFileType JE_SaveFilesType[SAVE_FILES_NUM]; /* [1..savefilesnum] */ typedef JE_byte JE_SaveGameTemp[SAVE_FILES_SIZE + 4 + 100]; /* [1..sizeof(savefilestype) + 4 + 100] */ -typedef struct -{ - JE_byte sC; - JE_word sLoc; - JE_word sMov; -} StarDatType; - extern const JE_byte cryptKey[10]; extern const JE_KeySettingType defaultKeySettings; extern const char defaultHighScoreNames[34][23]; @@ -88,8 +79,6 @@ extern const char defaultTeamNames[22][25]; extern const JE_EditorItemAvailType initialItemAvail; extern JE_boolean smoothies[9]; extern JE_byte starShowVGASpecialCode; -extern StarDatType starDat[MAX_STARS]; -extern JE_word starY; extern JE_word lastCubeMax, cubeMax; extern JE_word cubeList[4]; extern JE_boolean gameHasRepeated; @@ -158,8 +147,6 @@ const char *get_user_directory( void ); void JE_loadConfiguration( void ); void JE_saveConfiguration( void ); -void JE_setupStars( void ); - void JE_saveGame( JE_byte slot, const char *name ); void JE_loadGame( JE_byte slot ); @@ -171,4 +158,3 @@ void save_json( cJSON *root, const char *filename ); #endif /* CONFIG_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/destruct.c b/project/jni/application/opentyrian/src/destruct.c index eb2f71230..2b91b7356 100644 --- a/project/jni/application/opentyrian/src/destruct.c +++ b/project/jni/application/opentyrian/src/destruct.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -58,13 +58,12 @@ #include "palette.h" #include "picload.h" #include "sprite.h" +#include "varz.h" #include "vga256d.h" #include "video.h" #include -extern JE_byte soundQueue[8]; - /*** Defines ***/ #define UNIT_HEIGHT 12 #define MAX_KEY_OPTIONS 4 @@ -205,100 +204,100 @@ struct destruct_world_s { /*** Function decs ***/ //Prep functions -void JE_destructMain( void ); -void JE_introScreen( void ); -enum de_mode_t JE_modeSelect( void ); -void JE_helpScreen( void ); -void JE_pauseScreen( void ); +static void JE_destructMain( void ); +static void JE_introScreen( void ); +static enum de_mode_t JE_modeSelect( void ); +static void JE_helpScreen( void ); +static void JE_pauseScreen( void ); //level generating functions -void JE_generateTerrain( void ); -void DE_generateBaseTerrain( unsigned int, unsigned int *); -void DE_drawBaseTerrain( unsigned int * ); -void DE_generateUnits( unsigned int * ); -void DE_generateWalls( struct destruct_world_s * ); -void DE_generateRings(SDL_Surface *, Uint8 ); -void DE_ResetLevel( void ); -unsigned int JE_placementPosition( unsigned int, unsigned int, unsigned int * ); +static void JE_generateTerrain( void ); +static void DE_generateBaseTerrain( unsigned int, unsigned int *); +static void DE_drawBaseTerrain( unsigned int * ); +static void DE_generateUnits( unsigned int * ); +static void DE_generateWalls( struct destruct_world_s * ); +static void DE_generateRings(SDL_Surface *, Uint8 ); +static void DE_ResetLevel( void ); +static unsigned int JE_placementPosition( unsigned int, unsigned int, unsigned int * ); //drawing functions -void JE_aliasDirt( SDL_Surface * ); -void DE_RunTickDrawCrosshairs( void ); -void DE_RunTickDrawHUD( void ); -void DE_GravityDrawUnit( enum de_player_t, struct destruct_unit_s * ); -void DE_RunTickAnimate( void ); -void DE_RunTickDrawWalls( void ); -void DE_DrawTrails( struct destruct_shot_s *, unsigned int, unsigned int, unsigned int ); -void JE_tempScreenChecking( void ); -void JE_superPixel( unsigned int, unsigned int ); -void JE_pixCool( unsigned int, unsigned int, Uint8 ); +static void JE_aliasDirt( SDL_Surface * ); +static void DE_RunTickDrawCrosshairs( void ); +static void DE_RunTickDrawHUD( void ); +static void DE_GravityDrawUnit( enum de_player_t, struct destruct_unit_s * ); +static void DE_RunTickAnimate( void ); +static void DE_RunTickDrawWalls( void ); +static void DE_DrawTrails( struct destruct_shot_s *, unsigned int, unsigned int, unsigned int ); +static void JE_tempScreenChecking( void ); +static void JE_superPixel( unsigned int, unsigned int ); +static void JE_pixCool( unsigned int, unsigned int, Uint8 ); //player functions -void DE_RunTickGetInput( void ); -void DE_ProcessInput( void ); -void DE_ResetPlayers( void ); -void DE_ResetAI( void ); -void DE_ResetActions( void ); -void DE_RunTickAI( void ); +static void DE_RunTickGetInput( void ); +static void DE_ProcessInput( void ); +static void DE_ResetPlayers( void ); +static void DE_ResetAI( void ); +static void DE_ResetActions( void ); +static void DE_RunTickAI( void ); //unit functions -void DE_RaiseAngle( struct destruct_unit_s * ); -void DE_LowerAngle( struct destruct_unit_s * ); -void DE_RaisePower( struct destruct_unit_s * ); -void DE_LowerPower( struct destruct_unit_s * ); -void DE_CycleWeaponUp( struct destruct_unit_s * ); -void DE_CycleWeaponDown( struct destruct_unit_s * ); -void DE_RunMagnet( enum de_player_t, struct destruct_unit_s * ); -void DE_GravityFlyUnit( struct destruct_unit_s * ); -void DE_GravityLowerUnit( struct destruct_unit_s * ); -void DE_DestroyUnit( enum de_player_t, struct destruct_unit_s * ); -void DE_ResetUnits( void ); +static void DE_RaiseAngle( struct destruct_unit_s * ); +static void DE_LowerAngle( struct destruct_unit_s * ); +static void DE_RaisePower( struct destruct_unit_s * ); +static void DE_LowerPower( struct destruct_unit_s * ); +static void DE_CycleWeaponUp( struct destruct_unit_s * ); +static void DE_CycleWeaponDown( struct destruct_unit_s * ); +static void DE_RunMagnet( enum de_player_t, struct destruct_unit_s * ); +static void DE_GravityFlyUnit( struct destruct_unit_s * ); +static void DE_GravityLowerUnit( struct destruct_unit_s * ); +static void DE_DestroyUnit( enum de_player_t, struct destruct_unit_s * ); +static void DE_ResetUnits( void ); static inline bool DE_isValidUnit( struct destruct_unit_s *); //weapon functions -void DE_ResetWeapons( void ); -void DE_RunTickShots( void ); -void DE_RunTickExplosions( void ); -void DE_TestExplosionCollision( unsigned int, unsigned int); -void JE_makeExplosion( unsigned int, unsigned int, enum de_shot_t ); -void DE_MakeShot( enum de_player_t, const struct destruct_unit_s *, int ); +static void DE_ResetWeapons( void ); +static void DE_RunTickShots( void ); +static void DE_RunTickExplosions( void ); +static void DE_TestExplosionCollision( unsigned int, unsigned int); +static void JE_makeExplosion( unsigned int, unsigned int, enum de_shot_t ); +static void DE_MakeShot( enum de_player_t, const struct destruct_unit_s *, int ); //gameplay functions -enum de_state_t DE_RunTick( void ); -void DE_RunTickCycleDeadUnits( void ); -void DE_RunTickGravity( void ); -bool DE_RunTickCheckEndgame( void ); -bool JE_stabilityCheck( unsigned int, unsigned int ); +static enum de_state_t DE_RunTick( void ); +static void DE_RunTickCycleDeadUnits( void ); +static void DE_RunTickGravity( void ); +static bool DE_RunTickCheckEndgame( void ); +static bool JE_stabilityCheck( unsigned int, unsigned int ); //sound -void DE_RunTickPlaySounds( void ); -void JE_eSound( unsigned int ); +static void DE_RunTickPlaySounds( void ); +static void JE_eSound( unsigned int ); /*** Weapon configurations ***/ /* Part of me wants to leave these as bytes to save space. */ -const bool demolish[MAX_SHOT_TYPES] = {false, false, false, false, false, true, true, true, false, false, false, false, true, false, true, false, true}; -//const int shotGr[MAX_SHOT_TYPES] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101}; -const int shotTrail[MAX_SHOT_TYPES] = {TRAILS_NONE, TRAILS_NONE, TRAILS_NONE, TRAILS_NORMAL, TRAILS_NORMAL, TRAILS_NORMAL, TRAILS_FULL, TRAILS_FULL, TRAILS_NONE, TRAILS_NONE, TRAILS_NONE, TRAILS_NORMAL, TRAILS_FULL, TRAILS_NORMAL, TRAILS_FULL, TRAILS_NORMAL, TRAILS_NONE}; -//const int shotFuse[MAX_SHOT_TYPES] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}; -const int shotDelay[MAX_SHOT_TYPES] = {10, 30, 80, 20, 60, 100, 140, 200, 20, 60, 5, 15, 50, 5, 80, 16, 0}; -const int shotSound[MAX_SHOT_TYPES] = {S_SELECT, S_WEAPON_2, S_WEAPON_1, S_WEAPON_7, S_WEAPON_7, S_EXPLOSION_9, S_EXPLOSION_22, S_EXPLOSION_22, S_WEAPON_5, S_WEAPON_13, S_WEAPON_10, S_WEAPON_15, S_WEAPON_15, S_WEAPON_26, S_WEAPON_14, S_WEAPON_7, S_WEAPON_7}; -const int exploSize[MAX_SHOT_TYPES] = {4, 20, 30, 14, 22, 16, 40, 60, 10, 30, 0, 5, 10, 3, 15, 7, 0}; -const bool shotBounce[MAX_SHOT_TYPES] = {false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, false, true}; -const int exploDensity[MAX_SHOT_TYPES] = { 2, 5, 10, 15, 20, 15, 25, 30, 40, 80, 0, 30, 30, 4, 30, 5, 0}; -const int shotDirt[MAX_SHOT_TYPES] = {EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_DIRT, EXPL_DIRT, EXPL_MAGNET, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NONE}; -const int shotColor[MAX_SHOT_TYPES] = {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 10, 10, 10, 10, 16, 0}; +static const bool demolish[MAX_SHOT_TYPES] = {false, false, false, false, false, true, true, true, false, false, false, false, true, false, true, false, true}; +//static const int shotGr[MAX_SHOT_TYPES] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101}; +static const int shotTrail[MAX_SHOT_TYPES] = {TRAILS_NONE, TRAILS_NONE, TRAILS_NONE, TRAILS_NORMAL, TRAILS_NORMAL, TRAILS_NORMAL, TRAILS_FULL, TRAILS_FULL, TRAILS_NONE, TRAILS_NONE, TRAILS_NONE, TRAILS_NORMAL, TRAILS_FULL, TRAILS_NORMAL, TRAILS_FULL, TRAILS_NORMAL, TRAILS_NONE}; +//static const int shotFuse[MAX_SHOT_TYPES] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}; +static const int shotDelay[MAX_SHOT_TYPES] = {10, 30, 80, 20, 60, 100, 140, 200, 20, 60, 5, 15, 50, 5, 80, 16, 0}; +static const int shotSound[MAX_SHOT_TYPES] = {S_SELECT, S_WEAPON_2, S_WEAPON_1, S_WEAPON_7, S_WEAPON_7, S_EXPLOSION_9, S_EXPLOSION_22, S_EXPLOSION_22, S_WEAPON_5, S_WEAPON_13, S_WEAPON_10, S_WEAPON_15, S_WEAPON_15, S_WEAPON_26, S_WEAPON_14, S_WEAPON_7, S_WEAPON_7}; +static const int exploSize[MAX_SHOT_TYPES] = {4, 20, 30, 14, 22, 16, 40, 60, 10, 30, 0, 5, 10, 3, 15, 7, 0}; +static const bool shotBounce[MAX_SHOT_TYPES] = {false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, false, true}; +static const int exploDensity[MAX_SHOT_TYPES] = { 2, 5, 10, 15, 20, 15, 25, 30, 40, 80, 0, 30, 30, 4, 30, 5, 0}; +static const int shotDirt[MAX_SHOT_TYPES] = {EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_DIRT, EXPL_DIRT, EXPL_MAGNET, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NORMAL, EXPL_NONE}; +static const int shotColor[MAX_SHOT_TYPES] = {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 10, 10, 10, 10, 16, 0}; -const int defaultWeapon[MAX_UNITS] = {SHOT_SMALL, SHOT_MICRO, SHOT_SMALLDIRT, SHOT_INVALID, SHOT_MAGNET, SHOT_MINILASER, SHOT_MICRO, SHOT_MINI}; -const int defaultCpuWeapon[MAX_UNITS] = {SHOT_SMALL, SHOT_MICRO, SHOT_DEMO, SHOT_INVALID, SHOT_MAGNET, SHOT_MINILASER, SHOT_MICRO, SHOT_MINI}; -const int defaultCpuWeaponB[MAX_UNITS] = {SHOT_DEMO, SHOT_SMALLNUKE, SHOT_DEMO, SHOT_INVALID, SHOT_MAGNET, SHOT_MEGALASER, SHOT_MICRO, SHOT_MINI}; -const int systemAngle[MAX_UNITS] = {true, true, true, false, false, true, false, false}; -const int baseDamage[MAX_UNITS] = {200, 120, 400, 300, 80, 150, 600, 40}; -const int systemAni[MAX_UNITS] = {false, false, false, true, false, false, false, true}; +static const int defaultWeapon[MAX_UNITS] = {SHOT_SMALL, SHOT_MICRO, SHOT_SMALLDIRT, SHOT_INVALID, SHOT_MAGNET, SHOT_MINILASER, SHOT_MICRO, SHOT_MINI}; +static const int defaultCpuWeapon[MAX_UNITS] = {SHOT_SMALL, SHOT_MICRO, SHOT_DEMO, SHOT_INVALID, SHOT_MAGNET, SHOT_MINILASER, SHOT_MICRO, SHOT_MINI}; +static const int defaultCpuWeaponB[MAX_UNITS] = {SHOT_DEMO, SHOT_SMALLNUKE, SHOT_DEMO, SHOT_INVALID, SHOT_MAGNET, SHOT_MEGALASER, SHOT_MICRO, SHOT_MINI}; +static const int systemAngle[MAX_UNITS] = {true, true, true, false, false, true, false, false}; +static const int baseDamage[MAX_UNITS] = {200, 120, 400, 300, 80, 150, 600, 40}; +static const int systemAni[MAX_UNITS] = {false, false, false, true, false, false, false, true}; -bool weaponSystems[MAX_UNITS][MAX_SHOT_TYPES] = +static bool weaponSystems[MAX_UNITS][MAX_SHOT_TYPES] = { {1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // normal {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // nuke @@ -312,10 +311,10 @@ bool weaponSystems[MAX_UNITS][MAX_SHOT_TYPES] = /* More constant configuration settings. */ /* Music that destruct will play. You can check out musmast.c to see what is what. */ -const JE_byte goodsel[14] /*[1..14]*/ = {1, 2, 6, 12, 13, 14, 17, 23, 24, 26, 28, 29, 32, 33}; +static const JE_byte goodsel[14] /*[1..14]*/ = {1, 2, 6, 12, 13, 14, 17, 23, 24, 26, 28, 29, 32, 33}; /* Unit creation. Need to move this later: Doesn't belong here */ -JE_byte basetypes[10][11] /*[1..8, 1..11]*/ = /* [0] is amount of units*/ +static JE_byte basetypes[10][11] /*[1..8, 1..11]*/ = /* [0] is amount of units*/ { {5, UNIT_TANK, UNIT_TANK, UNIT_NUKE, UNIT_DIRT, UNIT_DIRT, UNIT_SATELLITE, UNIT_MAGNET, UNIT_LASER, UNIT_JUMPER, UNIT_HELI}, /*Normal*/ {1, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK}, /*Traditional*/ @@ -328,26 +327,26 @@ JE_byte basetypes[10][11] /*[1..8, 1..11]*/ = /* [0] is amount of units*/ {1, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK}, /*Custom1, to be edited*/ {1, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK, UNIT_TANK} /*Custom2, to be edited*/ }; -const unsigned int baseLookup[MAX_PLAYERS][MAX_MODES] = +static const unsigned int baseLookup[MAX_PLAYERS][MAX_MODES] = { {0, 1, 3, 4, 6, 8}, {0, 1, 2, 5, 7, 9} }; -const JE_byte GraphicBase[MAX_PLAYERS][MAX_UNITS] = +static const JE_byte GraphicBase[MAX_PLAYERS][MAX_UNITS] = { { 1, 6, 11, 58, 63, 68, 96, 153}, { 20, 25, 30, 77, 82, 87, 115, 172} }; -const JE_byte ModeScore[MAX_PLAYERS][MAX_MODES] = +static const JE_byte ModeScore[MAX_PLAYERS][MAX_MODES] = { {1, 0, 0, 5, 0, 1}, {1, 0, 5, 0, 1, 1} }; -SDLKey defaultKeyConfig[MAX_PLAYERS][MAX_KEY][MAX_KEY_OPTIONS] = +static SDLKey defaultKeyConfig[MAX_PLAYERS][MAX_KEY][MAX_KEY_OPTIONS] = { #ifdef ANDROID { {SDLK_a}, @@ -392,18 +391,18 @@ SDLKey defaultKeyConfig[MAX_PLAYERS][MAX_KEY][MAX_KEY_OPTIONS] = /*** Globals ***/ -SDL_Surface *destructTempScreen; -JE_boolean destructFirstTime; +static SDL_Surface *destructTempScreen; +static JE_boolean destructFirstTime; static struct destruct_config_s config = { 40, 20, 20, 40, 10, false, false, {true, false}, {true, false} }; -static struct destruct_player_s player[MAX_PLAYERS]; +static struct destruct_player_s destruct_player[MAX_PLAYERS]; static struct destruct_world_s world; static struct destruct_shot_s * shotRec; static struct destruct_explo_s * exploRec; /*** Startup ***/ -enum de_unit_t string_to_unit_enum(const char * str) { +static enum de_unit_t string_to_unit_enum(const char * str) { // A config helper function. Probably not useful anywhere else. enum de_unit_t i; @@ -417,7 +416,7 @@ enum de_unit_t string_to_unit_enum(const char * str) { return(UNIT_NONE); } -bool write_default_destruct_config( void ) { +static bool write_default_destruct_config( void ) { #ifndef ANDROID cJSON * root; @@ -594,7 +593,7 @@ label_failure: #endif return(false); } -void load_destruct_config( void ) { +static void load_destruct_config( void ) { #ifndef ANDROID unsigned int j, k; @@ -727,13 +726,13 @@ void JE_destructGame( void ) for(i = 0; i < 10; i++) { config.max_installations = MAX(config.max_installations, basetypes[i][0]); } - player[PLAYER_LEFT ].unit = malloc(sizeof(struct destruct_unit_s) * config.max_installations); - player[PLAYER_RIGHT].unit = malloc(sizeof(struct destruct_unit_s) * config.max_installations); + destruct_player[PLAYER_LEFT ].unit = malloc(sizeof(struct destruct_unit_s) * config.max_installations); + destruct_player[PLAYER_RIGHT].unit = malloc(sizeof(struct destruct_unit_s) * config.max_installations); destructTempScreen = game_screen; world.VGAScreen = VGAScreen; - JE_loadCompShapes(&eShapes1, '~'); + JE_loadCompShapes(&eShapes[0], '~'); fade_black(1); JE_destructMain(); @@ -742,11 +741,11 @@ void JE_destructGame( void ) free(shotRec); free(exploRec); free(world.mapWalls); - free(player[PLAYER_LEFT ].unit); - free(player[PLAYER_RIGHT].unit); + free(destruct_player[PLAYER_LEFT ].unit); + free(destruct_player[PLAYER_RIGHT].unit); } -void JE_destructMain( void ) +static void JE_destructMain( void ) { enum de_state_t curState; @@ -756,8 +755,8 @@ void JE_destructMain( void ) DE_ResetPlayers(); - player[PLAYER_LEFT ].is_cpu = config.ai[PLAYER_LEFT]; - player[PLAYER_RIGHT].is_cpu = config.ai[PLAYER_RIGHT]; + destruct_player[PLAYER_LEFT ].is_cpu = config.ai[PLAYER_LEFT]; + destruct_player[PLAYER_RIGHT].is_cpu = config.ai[PLAYER_RIGHT]; while(1) { @@ -785,7 +784,7 @@ void JE_destructMain( void ) } } -void JE_introScreen( void ) +static void JE_introScreen( void ) { memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->h * VGAScreen2->pitch); JE_outText(VGAScreen, JE_fontCenter(specialName[7], TINY_FONT), 90, specialName[7], 12, 5); @@ -812,7 +811,7 @@ void JE_introScreen( void ) * The return value is the selected mode, or -1 (MODE_NONE) * if the user quits. */ -void DrawModeSelectMenu( enum de_mode_t mode ) { +static void DrawModeSelectMenu( enum de_mode_t mode ) { int i; @@ -826,7 +825,7 @@ void DrawModeSelectMenu( enum de_mode_t mode ) { JE_textShade(VGAScreen, JE_fontCenter("Custom", TINY_FONT), 82 + i * 12, "Custom", 12, (i == mode) * 4, FULL_SHADE); } } -enum de_mode_t JE_modeSelect( void ) +static enum de_mode_t JE_modeSelect( void ) { int mode; //enum de_mode_t mode; @@ -900,7 +899,7 @@ enum de_mode_t JE_modeSelect( void ) return(mode); } -void JE_generateTerrain( void ) +static void JE_generateTerrain( void ) { /* The unique modifiers: Altered generation (really tall) @@ -958,7 +957,7 @@ void JE_generateTerrain( void ) memcpy(destructTempScreen->pixels, VGAScreen->pixels, destructTempScreen->pitch * destructTempScreen->h); } -void DE_generateBaseTerrain( unsigned int mapFlags, unsigned int * baseWorld) +static void DE_generateBaseTerrain( unsigned int mapFlags, unsigned int * baseWorld) { unsigned int i; unsigned int newheight, HeightMul; @@ -1004,7 +1003,7 @@ void DE_generateBaseTerrain( unsigned int mapFlags, unsigned int * baseWorld) } /* The base world has been created. */ } -void DE_drawBaseTerrain( unsigned int * baseWorld) +static void DE_drawBaseTerrain( unsigned int * baseWorld) { unsigned int i; @@ -1015,7 +1014,7 @@ void DE_drawBaseTerrain( unsigned int * baseWorld) } } -void DE_generateUnits( unsigned int * baseWorld ) +static void DE_generateUnits( unsigned int * baseWorld ) { unsigned int i, j, numSatellites; @@ -1023,31 +1022,31 @@ void DE_generateUnits( unsigned int * baseWorld ) for (i = 0; i < MAX_PLAYERS; i++) { numSatellites = 0; - player[i].unitsRemaining = 0; + destruct_player[i].unitsRemaining = 0; for (j = 0; j < basetypes[baseLookup[i][world.destructMode]][0]; j++) { /* Not everything is the same between players */ if(i == PLAYER_LEFT) { - player[i].unit[j].unitX = (mt_rand() % 120) + 10; + destruct_player[i].unit[j].unitX = (mt_rand() % 120) + 10; } else { - player[i].unit[j].unitX = 320 - ((mt_rand() % 120) + 22); + destruct_player[i].unit[j].unitX = 320 - ((mt_rand() % 120) + 22); } - player[i].unit[j].unitY = JE_placementPosition(player[i].unit[j].unitX - 1, 14, baseWorld); - player[i].unit[j].unitType = basetypes[baseLookup[i][world.destructMode]][(mt_rand() % 10) + 1]; + destruct_player[i].unit[j].unitY = JE_placementPosition(destruct_player[i].unit[j].unitX - 1, 14, baseWorld); + destruct_player[i].unit[j].unitType = basetypes[baseLookup[i][world.destructMode]][(mt_rand() % 10) + 1]; /* Sats are special cases since they are useless. They don't count * as active units and we can't have a team of all sats */ - if (player[i].unit[j].unitType == UNIT_SATELLITE) + if (destruct_player[i].unit[j].unitType == UNIT_SATELLITE) { if (numSatellites == basetypes[baseLookup[i][world.destructMode]][0]) { - player[i].unit[j].unitType = UNIT_TANK; - player[i].unitsRemaining++; + destruct_player[i].unit[j].unitType = UNIT_TANK; + destruct_player[i].unitsRemaining++; } else { /* Place the satellite. Note: Earlier we cleared * space with JE_placementPosition. Now we are randomly @@ -1055,28 +1054,28 @@ void DE_generateUnits( unsigned int * baseWorld ) * and there is a clearing underneath it. This CAN * be fixed but won't be for classic. */ - player[i].unit[j].unitY = 30 + (mt_rand() % 40); + destruct_player[i].unit[j].unitY = 30 + (mt_rand() % 40); numSatellites++; } } else { - player[i].unitsRemaining++; + destruct_player[i].unitsRemaining++; } /* Now just fill in the rest of the unit's values. */ - player[i].unit[j].lastMove = 0; - player[i].unit[j].unitYMov = 0; - player[i].unit[j].isYInAir = false; - player[i].unit[j].angle = 0; - player[i].unit[j].power = (player[i].unit[j].unitType == UNIT_LASER) ? 6 : 3; - player[i].unit[j].shotType = defaultWeapon[player[i].unit[j].unitType]; - player[i].unit[j].health = baseDamage[player[i].unit[j].unitType]; - player[i].unit[j].ani_frame = 0; + destruct_player[i].unit[j].lastMove = 0; + destruct_player[i].unit[j].unitYMov = 0; + destruct_player[i].unit[j].isYInAir = false; + destruct_player[i].unit[j].angle = 0; + destruct_player[i].unit[j].power = (destruct_player[i].unit[j].unitType == UNIT_LASER) ? 6 : 3; + destruct_player[i].unit[j].shotType = defaultWeapon[destruct_player[i].unit[j].unitType]; + destruct_player[i].unit[j].health = baseDamage[destruct_player[i].unit[j].unitType]; + destruct_player[i].unit[j].ani_frame = 0; } } } -void DE_generateWalls( struct destruct_world_s * gameWorld ) +static void DE_generateWalls( struct destruct_world_s * gameWorld ) { unsigned int i, j, wallX; unsigned int wallHeight, remainWalls; @@ -1123,8 +1122,8 @@ void DE_generateWalls( struct destruct_world_s * gameWorld ) { for (j = 0; j < config.max_installations; j++) { - if ((wallX > player[i].unit[j].unitX - 12) - && (wallX < player[i].unit[j].unitX + 13)) + if ((wallX > destruct_player[i].unit[j].unitX - 12) + && (wallX < destruct_player[i].unit[j].unitX + 13)) { isGood = false; goto label_outer_break; /* I do feel that outer breaking is a legitimate goto use. */ @@ -1151,7 +1150,7 @@ label_outer_break: } while (remainWalls != 0); } -void DE_generateRings( SDL_Surface * screen, Uint8 pixel ) +static void DE_generateRings( SDL_Surface * screen, Uint8 pixel ) { unsigned int i, j, tempSize, rings; int tempPosX1, tempPosY1, tempPosX2, tempPosY2; @@ -1179,7 +1178,7 @@ void DE_generateRings( SDL_Surface * screen, Uint8 pixel ) } } -unsigned int __aliasDirtPixel(const SDL_Surface * screen, unsigned int x, unsigned int y, const Uint8 * s) { +static unsigned int aliasDirtPixel(const SDL_Surface * screen, unsigned int x, unsigned int y, const Uint8 * s) { //A helper function used when aliasing dirt. That's a messy process; //let's contain the mess here. @@ -1204,7 +1203,7 @@ unsigned int __aliasDirtPixel(const SDL_Surface * screen, unsigned int x, unsign return(PIXEL_BLACK); } -void JE_aliasDirt( SDL_Surface * screen ) +static void JE_aliasDirt( SDL_Surface * screen ) { /* This complicated looking function goes through the whole screen * looking for brown pixels which just happen to be next to non-brown @@ -1220,7 +1219,7 @@ void JE_aliasDirt( SDL_Surface * screen ) for (y = 12; y < (unsigned)screen->h; y++) { for (x = 0; x < screen->pitch; x++) { if (*s == PIXEL_BLACK) { - *s = __aliasDirtPixel(screen, x, y, s); + *s = aliasDirtPixel(screen, x, y, s); } s++; @@ -1228,7 +1227,7 @@ void JE_aliasDirt( SDL_Surface * screen ) } } -unsigned int JE_placementPosition( unsigned int passed_x, unsigned int width, unsigned int * world ) +static unsigned int JE_placementPosition( unsigned int passed_x, unsigned int width, unsigned int * world ) { unsigned int i, new_y; @@ -1255,7 +1254,7 @@ unsigned int JE_placementPosition( unsigned int passed_x, unsigned int width, un return new_y; } -bool JE_stabilityCheck( unsigned int x, unsigned int y ) +static bool JE_stabilityCheck( unsigned int x, unsigned int y ) { unsigned int i, numDirtPixels; Uint8 * s; @@ -1278,7 +1277,7 @@ bool JE_stabilityCheck( unsigned int x, unsigned int y ) return (numDirtPixels < 10); } -void JE_tempScreenChecking( void ) /*and copy to vgascreen*/ +static void JE_tempScreenChecking( void ) /*and copy to vgascreen*/ { Uint8 *s = (Uint8 *)VGAScreen->pixels; s += 12 * VGAScreen->pitch; @@ -1303,7 +1302,7 @@ void JE_tempScreenChecking( void ) /*and copy to vgascreen*/ // This block is for aliasing dirt. Computers are fast these days, // and it's fun. if (config.alwaysalias == true && *temps == PIXEL_BLACK) { - *temps = __aliasDirtPixel(VGAScreen, x, y, temps); + *temps = aliasDirtPixel(VGAScreen, x, y, temps); } /* This is copying from our temp screen to VGAScreen */ @@ -1315,7 +1314,7 @@ void JE_tempScreenChecking( void ) /*and copy to vgascreen*/ } } -void JE_makeExplosion( unsigned int tempPosX, unsigned int tempPosY, enum de_shot_t shottype ) +static void JE_makeExplosion( unsigned int tempPosX, unsigned int tempPosY, enum de_shot_t shottype ) { unsigned int i, tempExploSize; @@ -1367,7 +1366,7 @@ void JE_makeExplosion( unsigned int tempPosX, unsigned int tempPosY, enum de_sho } } -void JE_eSound( unsigned int sound ) +static void JE_eSound( unsigned int sound ) { static int exploSoundChannel = 0; @@ -1379,7 +1378,7 @@ void JE_eSound( unsigned int sound ) soundQueue[exploSoundChannel] = sound; } -void JE_superPixel( unsigned int tempPosX, unsigned int tempPosY ) +static void JE_superPixel( unsigned int tempPosX, unsigned int tempPosY ) { const unsigned int starPattern[5][5] = { { 0, 0, 246, 0, 0 }, @@ -1438,7 +1437,7 @@ void JE_superPixel( unsigned int tempPosX, unsigned int tempPosY ) } } -void JE_helpScreen( void ) +static void JE_helpScreen( void ) { unsigned int i, j; @@ -1475,7 +1474,7 @@ void JE_helpScreen( void ) } -void JE_pauseScreen( void ) +static void JE_pauseScreen( void ) { set_volume(tyrMusicVolume / 2, fxVolume); @@ -1502,34 +1501,34 @@ void JE_pauseScreen( void ) * * The reset functions clear the state of whatefer they are assigned to. */ -void DE_ResetUnits( void ) +static void DE_ResetUnits( void ) { unsigned int p, u; for (p = 0; p < MAX_PLAYERS; ++p) for (u = 0; u < config.max_installations; ++u) - player[p].unit[u].health = 0; + destruct_player[p].unit[u].health = 0; } -void DE_ResetPlayers( void ) +static void DE_ResetPlayers( void ) { unsigned int i; for (i = 0; i < MAX_PLAYERS; ++i) { - player[i].is_cpu = false; - player[i].unitSelected = 0; - player[i].shotDelay = 0; - player[i].score = 0; - player[i].aiMemory.c_Angle = 0; - player[i].aiMemory.c_Power = 0; - player[i].aiMemory.c_Fire = 0; - player[i].aiMemory.c_noDown = 0; - memcpy(player[i].keys.Config, defaultKeyConfig[i], sizeof(player[i].keys.Config)); + destruct_player[i].is_cpu = false; + destruct_player[i].unitSelected = 0; + destruct_player[i].shotDelay = 0; + destruct_player[i].score = 0; + destruct_player[i].aiMemory.c_Angle = 0; + destruct_player[i].aiMemory.c_Power = 0; + destruct_player[i].aiMemory.c_Fire = 0; + destruct_player[i].aiMemory.c_noDown = 0; + memcpy(destruct_player[i].keys.Config, defaultKeyConfig[i], sizeof(destruct_player[i].keys.Config)); } } -void DE_ResetWeapons( void ) +static void DE_ResetWeapons( void ) { unsigned int i; @@ -1540,7 +1539,7 @@ void DE_ResetWeapons( void ) for (i = 0; i < config.max_explosions; i++) exploRec[i].isAvailable = true; } -void DE_ResetLevel( void ) +static void DE_ResetLevel( void ) { /* Okay, let's prep the arena */ @@ -1549,7 +1548,7 @@ void DE_ResetLevel( void ) JE_generateTerrain(); DE_ResetAI(); } -void DE_ResetAI( void ) +static void DE_ResetAI( void ) { unsigned int i, j; struct destruct_unit_s * ptr; @@ -1557,8 +1556,8 @@ void DE_ResetAI( void ) for (i = PLAYER_LEFT; i < MAX_PLAYERS; i++) { - if (player[i].is_cpu == false) { continue; } - ptr = player[i].unit; + if (destruct_player[i].is_cpu == false) { continue; } + ptr = destruct_player[i].unit; for( j = 0; j < config.max_installations; j++, ptr++) { @@ -1579,14 +1578,14 @@ void DE_ResetAI( void ) } } } -void DE_ResetActions( void ) +static void DE_ResetActions( void ) { unsigned int i; for(i = 0; i < MAX_PLAYERS; i++) { /* Zero it all. A memset would do the trick */ - memset(&(player[i].moves), 0, sizeof(player[i].moves)); + memset(&(destruct_player[i].moves), 0, sizeof(destruct_player[i].moves)); } } /* DE_RunTick @@ -1596,7 +1595,7 @@ void DE_ResetActions( void ) * Returns true while the game is running or false if the game is * to be terminated. */ -enum de_state_t DE_RunTick( void ) +static enum de_state_t DE_RunTick( void ) { static unsigned int endDelay; @@ -1647,12 +1646,12 @@ enum de_state_t DE_RunTick( void ) /* The rest of this cruft needs to be put in appropriate sections */ if (keysactive[SDLK_F10]) { - player[PLAYER_LEFT].is_cpu = !player[PLAYER_LEFT].is_cpu; + destruct_player[PLAYER_LEFT].is_cpu = !destruct_player[PLAYER_LEFT].is_cpu; keysactive[SDLK_F10] = false; } if (keysactive[SDLK_F11]) { - player[PLAYER_RIGHT].is_cpu = !player[PLAYER_RIGHT].is_cpu; + destruct_player[PLAYER_RIGHT].is_cpu = !destruct_player[PLAYER_RIGHT].is_cpu; keysactive[SDLK_F11] = false; } if (keysactive[SDLK_p]) @@ -1689,7 +1688,7 @@ enum de_state_t DE_RunTick( void ) * Handles something that we do once per tick, such as * track ammo and move asplosions. */ -void DE_RunTickCycleDeadUnits( void ) +static void DE_RunTickCycleDeadUnits( void ) { unsigned int i; struct destruct_unit_s * unit; @@ -1699,23 +1698,23 @@ void DE_RunTickCycleDeadUnits( void ) * and skips over the useless satellite */ for (i = 0; i < MAX_PLAYERS; i++) { - if (player[i].unitsRemaining == 0) { continue; } + if (destruct_player[i].unitsRemaining == 0) { continue; } - unit = &(player[i].unit[player[i].unitSelected]); + unit = &(destruct_player[i].unit[destruct_player[i].unitSelected]); while(DE_isValidUnit(unit) == false || unit->shotType == SHOT_INVALID) { - player[i].unitSelected++; + destruct_player[i].unitSelected++; unit++; - if (player[i].unitSelected >= config.max_installations) + if (destruct_player[i].unitSelected >= config.max_installations) { - player[i].unitSelected = 0; - unit = player[i].unit; + destruct_player[i].unitSelected = 0; + unit = destruct_player[i].unit; } } } } -void DE_RunTickGravity( void ) +static void DE_RunTickGravity( void ) { unsigned int i, j; struct destruct_unit_s * unit; @@ -1724,7 +1723,7 @@ void DE_RunTickGravity( void ) for (i = 0; i < MAX_PLAYERS; i++) { - unit = player[i].unit; + unit = destruct_player[i].unit; for (j = 0; j < config.max_installations; j++, unit++) { if (DE_isValidUnit(unit) == false) /* invalid unit */ @@ -1753,7 +1752,7 @@ void DE_RunTickGravity( void ) } } } -void DE_GravityDrawUnit( enum de_player_t team, struct destruct_unit_s * unit ) +static void DE_GravityDrawUnit( enum de_player_t team, struct destruct_unit_s * unit ) { unsigned int anim_index; @@ -1772,9 +1771,9 @@ void DE_GravityDrawUnit( enum de_player_t team, struct destruct_unit_s * unit ) anim_index += floorf(unit->angle * 9.99f / M_PI); } - blit_sprite2(VGAScreen, unit->unitX, roundf(unit->unitY) - 13, eShapes1, anim_index); + blit_sprite2(VGAScreen, unit->unitX, roundf(unit->unitY) - 13, eShapes[0], anim_index); } -void DE_GravityLowerUnit( struct destruct_unit_s * unit ) +static void DE_GravityLowerUnit( struct destruct_unit_s * unit ) { /* units fall at a constant speed. The heli is an odd case though; * we simply give it a downward velocity, but due to a buggy implementation @@ -1803,7 +1802,7 @@ void DE_GravityLowerUnit( struct destruct_unit_s * unit ) } } } -void DE_GravityFlyUnit( struct destruct_unit_s * unit ) +static void DE_GravityFlyUnit( struct destruct_unit_s * unit ) { if (unit->unitY + unit->unitYMov > 199) /* would hit bottom of screen */ { @@ -1832,7 +1831,7 @@ void DE_GravityFlyUnit( struct destruct_unit_s * unit ) unit->isYInAir = false; } } -void DE_RunTickAnimate( void ) +static void DE_RunTickAnimate( void ) { unsigned int p, u; struct destruct_unit_s * ptr; @@ -1840,7 +1839,7 @@ void DE_RunTickAnimate( void ) for (p = 0; p < MAX_PLAYERS; ++p) { - ptr = player[p].unit; + ptr = destruct_player[p].unit; for (u = 0; u < config.max_installations; ++u, ++ptr) { /* Don't mess with any unit that is unallocated @@ -1855,7 +1854,7 @@ void DE_RunTickAnimate( void ) } } } -void DE_RunTickDrawWalls( void ) +static void DE_RunTickDrawWalls( void ) { unsigned int i; @@ -1864,11 +1863,11 @@ void DE_RunTickDrawWalls( void ) { if (world.mapWalls[i].wallExist) { - blit_sprite2(VGAScreen, world.mapWalls[i].wallX, world.mapWalls[i].wallY, eShapes1, 42); + blit_sprite2(VGAScreen, world.mapWalls[i].wallX, world.mapWalls[i].wallY, eShapes[0], 42); } } } -void DE_RunTickExplosions( void ) +static void DE_RunTickExplosions( void ) { unsigned int i, j; int tempPosX, tempPosY; @@ -1926,7 +1925,7 @@ void DE_RunTickExplosions( void ) } } } -void DE_TestExplosionCollision( unsigned int PosX, unsigned int PosY) +static void DE_TestExplosionCollision( unsigned int PosX, unsigned int PosY) { unsigned int i, j; struct destruct_unit_s * unit; @@ -1934,7 +1933,7 @@ void DE_TestExplosionCollision( unsigned int PosX, unsigned int PosY) for (i = PLAYER_LEFT; i < MAX_PLAYERS; i++) { - unit = player[i].unit; + unit = destruct_player[i].unit; for (j = 0; j < config.max_installations; j++, unit++) { if (DE_isValidUnit(unit) == true @@ -1950,7 +1949,7 @@ void DE_TestExplosionCollision( unsigned int PosX, unsigned int PosY) } } } -void DE_DestroyUnit( enum de_player_t playerID, struct destruct_unit_s * unit ) +static void DE_DestroyUnit( enum de_player_t playerID, struct destruct_unit_s * unit ) { /* This function call was an evil evil piece of brilliance before. Go on. * Look at the older revisions. It passed the result of a comparison. @@ -1959,12 +1958,12 @@ void DE_DestroyUnit( enum de_player_t playerID, struct destruct_unit_s * unit ) if (unit->unitType != UNIT_SATELLITE) /* increment score */ { /* todo: change when teams are created. Hacky kludge for now.*/ - player[playerID].unitsRemaining--; - player[((playerID == PLAYER_LEFT) ? PLAYER_RIGHT : PLAYER_LEFT)].score++; + destruct_player[playerID].unitsRemaining--; + destruct_player[((playerID == PLAYER_LEFT) ? PLAYER_RIGHT : PLAYER_LEFT)].score++; } } -void DE_RunTickShots( void ) +static void DE_RunTickShots( void ) { unsigned int i, j, k; unsigned int tempTrails; @@ -2030,7 +2029,7 @@ void DE_RunTickShots( void ) /*Check building hits*/ for(j = 0; j < MAX_PLAYERS; j++) { - unit = player[j].unit; + unit = destruct_player[j].unit; for(k = 0; k < config.max_installations; k++, unit++) { if (DE_isValidUnit(unit) == false) @@ -2108,7 +2107,7 @@ void DE_RunTickShots( void ) } } } -void DE_DrawTrails( struct destruct_shot_s * shot, unsigned int count, unsigned int decay, unsigned int startColor ) +static void DE_DrawTrails( struct destruct_shot_s * shot, unsigned int count, unsigned int decay, unsigned int startColor ) { int i; @@ -2137,7 +2136,7 @@ void DE_DrawTrails( struct destruct_shot_s * shot, unsigned int count, unsigned } } } -void DE_RunTickAI( void ) +static void DE_RunTickAI( void ) { unsigned int i, j; struct destruct_player_s * ptrPlayer, * ptrTarget; @@ -2146,7 +2145,7 @@ void DE_RunTickAI( void ) for (i = 0; i < MAX_PLAYERS; i++) { - ptrPlayer = &(player[i]); + ptrPlayer = &(destruct_player[i]); if (ptrPlayer->is_cpu == false) { continue; @@ -2155,14 +2154,14 @@ void DE_RunTickAI( void ) /* I've been thinking, purely hypothetically, about what it would take * to have multiple computer opponents. The answer? A lot of crap - * and a 'target' variable in the player struct. */ + * and a 'target' variable in the destruct_player struct. */ j = i + 1; if (j >= MAX_PLAYERS) { j = 0; } - ptrTarget = &(player[j]); + ptrTarget = &(destruct_player[j]); ptrCurUnit = &(ptrPlayer->unit[ptrPlayer->unitSelected]); @@ -2338,7 +2337,7 @@ void DE_RunTickAI( void ) } } } -void DE_RunTickDrawCrosshairs( void ) +static void DE_RunTickDrawCrosshairs( void ) { unsigned int i; int tempPosX, tempPosY; @@ -2352,7 +2351,7 @@ void DE_RunTickDrawCrosshairs( void ) for (i = 0; i < MAX_PLAYERS; i++) { direction = (i == PLAYER_LEFT) ? -1 : 1; - curUnit = &(player[i].unit[player[i].unitSelected]); + curUnit = &(destruct_player[i].unit[destruct_player[i].unitSelected]); if (curUnit->unitType == UNIT_HELI) { @@ -2383,7 +2382,7 @@ void DE_RunTickDrawCrosshairs( void ) } } } -void DE_RunTickDrawHUD( void ) +static void DE_RunTickDrawHUD( void ) { unsigned int i; unsigned int startX; @@ -2393,7 +2392,7 @@ void DE_RunTickDrawHUD( void ) for (i = 0; i < MAX_PLAYERS; i++) { - curUnit = &(player[i].unit[player[i].unitSelected]); + curUnit = &(destruct_player[i].unit[destruct_player[i].unitSelected]); startX = ((i == PLAYER_LEFT) ? 0 : 320 - 150); fill_rectangle_xy(VGAScreen, startX + 5, 3, startX + 14, 8, 241); @@ -2403,43 +2402,39 @@ void DE_RunTickDrawHUD( void ) JE_rectangle(VGAScreen, startX + 17, 2, startX + 143, 9, 242); JE_rectangle(VGAScreen, startX + 16, 1, startX + 144, 10, 240); - blit_sprite2(VGAScreen, startX + 4, 0, eShapes1, 191 + curUnit->shotType); + blit_sprite2(VGAScreen, startX + 4, 0, eShapes[0], 191 + curUnit->shotType); JE_outText (VGAScreen, startX + 20, 3, weaponNames[curUnit->shotType], 15, 2); sprintf (tempstr, "dmg~%d~", curUnit->health); JE_outText (VGAScreen, startX + 75, 3, tempstr, 15, 0); - sprintf (tempstr, "pts~%d~", player[i].score); + sprintf (tempstr, "pts~%d~", destruct_player[i].score); JE_outText (VGAScreen, startX + 110, 3, tempstr, 15, 0); } } -void DE_RunTickGetInput( void ) +static void DE_RunTickGetInput( void ) { unsigned int player_index, key_index, slot_index; SDLKey key; - /* player.keys holds our key config. Players will eventually be allowed - * to can change their key mappings. player.moves and player.keys - * line up; rather than manually checking left and right we can - * just loop through the indexes and set the actions as needed. */ + /* destruct_player.keys holds our key config. Players will eventually be + * allowed to can change their key mappings. destruct_player.moves and + * destruct_player.keys line up; rather than manually checking left and + * right we can just loop through the indexes and set the actions as + * needed. */ service_SDL_events(true); -#ifdef ANDROID - if( mouse_pressed[0] ) - player[1].moves.actions[KEY_FIRE] = true; -#endif - for(player_index = 0; player_index < MAX_PLAYERS; player_index++) { for(key_index = 0; key_index < MAX_KEY; key_index++) { for(slot_index = 0; slot_index < MAX_KEY_OPTIONS; slot_index++) { - key = player[player_index].keys.Config[key_index][slot_index]; + key = destruct_player[player_index].keys.Config[key_index][slot_index]; if(key == SDLK_UNKNOWN) { break; } if(keysactive[key] == true) { /* The right key was clearly pressed */ - player[player_index].moves.actions[key_index] = true; + destruct_player[player_index].moves.actions[key_index] = true; /* Some keys we want to toggle afterwards */ if(key_index == KEY_CHANGE || @@ -2454,7 +2449,7 @@ void DE_RunTickGetInput( void ) } } } -void DE_ProcessInput( void ) +static void DE_ProcessInput( void ) { int direction; @@ -2464,24 +2459,24 @@ void DE_ProcessInput( void ) for (player_index = 0; player_index < MAX_PLAYERS; player_index++) { - if (player[player_index].unitsRemaining <= 0) { continue; } + if (destruct_player[player_index].unitsRemaining <= 0) { continue; } direction = (player_index == PLAYER_LEFT) ? -1 : 1; - curUnit = &(player[player_index].unit[player[player_index].unitSelected]); + curUnit = &(destruct_player[player_index].unit[destruct_player[player_index].unitSelected]); if (systemAngle[curUnit->unitType] == true) /* selected unit may change shot angle */ { - if (player[player_index].moves.actions[MOVE_LEFT] == true) + if (destruct_player[player_index].moves.actions[MOVE_LEFT] == true) { (player_index == PLAYER_LEFT) ? DE_RaiseAngle(curUnit) : DE_LowerAngle(curUnit); } - if (player[player_index].moves.actions[MOVE_RIGHT] == true) + if (destruct_player[player_index].moves.actions[MOVE_RIGHT] == true) { (player_index == PLAYER_LEFT) ? DE_LowerAngle(curUnit) : DE_RaiseAngle(curUnit); } } else if (curUnit->unitType == UNIT_HELI) { - if (player[player_index].moves.actions[MOVE_LEFT] == true && curUnit->unitX > 5) + if (destruct_player[player_index].moves.actions[MOVE_LEFT] == true && curUnit->unitX > 5) if (JE_stabilityCheck(curUnit->unitX - 5, roundf(curUnit->unitY))) { if (curUnit->lastMove > -5) @@ -2494,7 +2489,7 @@ void DE_ProcessInput( void ) curUnit->isYInAir = true; } } - if (player[player_index].moves.actions[MOVE_RIGHT] == true && curUnit->unitX < 305) + if (destruct_player[player_index].moves.actions[MOVE_RIGHT] == true && curUnit->unitX < 305) { if (JE_stabilityCheck(curUnit->unitX + 5, roundf(curUnit->unitY))) { @@ -2514,7 +2509,7 @@ void DE_ProcessInput( void ) if (curUnit->unitType != UNIT_LASER) { /*increasepower*/ - if (player[player_index].moves.actions[MOVE_UP] == true) + if (destruct_player[player_index].moves.actions[MOVE_UP] == true) { if (curUnit->unitType == UNIT_HELI) { @@ -2531,7 +2526,7 @@ void DE_ProcessInput( void ) } } /*decreasepower*/ - if (player[player_index].moves.actions[MOVE_DOWN] == true) + if (destruct_player[player_index].moves.actions[MOVE_DOWN] == true) { if (curUnit->unitType == UNIT_HELI && curUnit->isYInAir == true) { @@ -2543,35 +2538,35 @@ void DE_ProcessInput( void ) } /*up/down weapon. These just cycle until a valid weapon is found */ - if (player[player_index].moves.actions[MOVE_CYUP] == true) + if (destruct_player[player_index].moves.actions[MOVE_CYUP] == true) { DE_CycleWeaponUp(curUnit); } - if (player[player_index].moves.actions[MOVE_CYDN] == true) + if (destruct_player[player_index].moves.actions[MOVE_CYDN] == true) { DE_CycleWeaponDown(curUnit); } /* Change. Since change would change out curUnit pointer, let's just do it last. * Validity checking is performed at the beginning of the tick. */ - if (player[player_index].moves.actions[MOVE_CHANGE] == true) + if (destruct_player[player_index].moves.actions[MOVE_CHANGE] == true) { - player[player_index].unitSelected++; - if (player[player_index].unitSelected >= config.max_installations) + destruct_player[player_index].unitSelected++; + if (destruct_player[player_index].unitSelected >= config.max_installations) { - player[player_index].unitSelected = 0; + destruct_player[player_index].unitSelected = 0; } } /*Newshot*/ - if (player[player_index].shotDelay > 0) + if (destruct_player[player_index].shotDelay > 0) { - player[player_index].shotDelay--; + destruct_player[player_index].shotDelay--; } - if (player[player_index].moves.actions[MOVE_FIRE] == true - && (player[player_index].shotDelay == 0)) + if (destruct_player[player_index].moves.actions[MOVE_FIRE] == true + && (destruct_player[player_index].shotDelay == 0)) { - player[player_index].shotDelay = shotDelay[curUnit->shotType]; + destruct_player[player_index].shotDelay = shotDelay[curUnit->shotType]; switch(shotDirt[curUnit->shotType]) { @@ -2594,7 +2589,7 @@ void DE_ProcessInput( void ) } } -void DE_CycleWeaponUp( struct destruct_unit_s * unit ) +static void DE_CycleWeaponUp( struct destruct_unit_s * unit ) { do { @@ -2605,7 +2600,7 @@ void DE_CycleWeaponUp( struct destruct_unit_s * unit ) } } while (weaponSystems[unit->unitType][unit->shotType] == 0); } -void DE_CycleWeaponDown( struct destruct_unit_s * unit ) +static void DE_CycleWeaponDown( struct destruct_unit_s * unit ) { do { @@ -2618,7 +2613,7 @@ void DE_CycleWeaponDown( struct destruct_unit_s * unit ) } -void DE_MakeShot( enum de_player_t curPlayer, const struct destruct_unit_s * curUnit, int direction ) +static void DE_MakeShot( enum de_player_t curPlayer, const struct destruct_unit_s * curUnit, int direction ) { unsigned int i; unsigned int shotIndex; @@ -2652,7 +2647,7 @@ void DE_MakeShot( enum de_player_t curPlayer, const struct destruct_unit_s * cur shotRec[shotIndex].xmov = 0.02f * curUnit->lastMove * curUnit->lastMove * curUnit->lastMove; /* If we are trying in vain to move up off the screen, act differently.*/ - if (player[curPlayer].moves.actions[MOVE_UP] && curUnit->unitY < 30) + if (destruct_player[curPlayer].moves.actions[MOVE_UP] && curUnit->unitY < 30) { shotRec[shotIndex].y = curUnit->unitY; shotRec[shotIndex].ymov = 0.1f; @@ -2725,7 +2720,7 @@ void DE_MakeShot( enum de_player_t curPlayer, const struct destruct_unit_s * cur shotRec[shotIndex].trailc[2] = 0; shotRec[shotIndex].trailc[3] = 0; } -void DE_RunMagnet( enum de_player_t curPlayer, struct destruct_unit_s * magnet ) +static void DE_RunMagnet( enum de_player_t curPlayer, struct destruct_unit_s * magnet ) { unsigned int i; enum de_player_t curEnemy; @@ -2749,15 +2744,15 @@ void DE_RunMagnet( enum de_player_t curPlayer, struct destruct_unit_s * magnet ) } } - enemyUnit = player[curEnemy].unit; + enemyUnit = destruct_player[curEnemy].unit; for (i = 0; i < config.max_installations; i++, enemyUnit++) /* magnets push coptors */ { if (DE_isValidUnit(enemyUnit) && enemyUnit->unitType == UNIT_HELI && enemyUnit->isYInAir == true) { - if ((curEnemy == PLAYER_RIGHT && player[curEnemy].unit[i].unitX + 11 < 318) - || (curEnemy == PLAYER_LEFT && player[curEnemy].unit[i].unitX > 1)) + if ((curEnemy == PLAYER_RIGHT && destruct_player[curEnemy].unit[i].unitX + 11 < 318) + || (curEnemy == PLAYER_LEFT && destruct_player[curEnemy].unit[i].unitX > 1)) { enemyUnit->unitX -= 2 * direction; } @@ -2765,7 +2760,7 @@ void DE_RunMagnet( enum de_player_t curPlayer, struct destruct_unit_s * magnet ) } magnet->ani_frame = 1; } -void DE_RaiseAngle( struct destruct_unit_s * unit ) +static void DE_RaiseAngle( struct destruct_unit_s * unit ) { unit->angle += 0.01f; if (unit->angle > M_PI_2 - 0.01f) @@ -2773,7 +2768,7 @@ void DE_RaiseAngle( struct destruct_unit_s * unit ) unit->angle = M_PI_2 - 0.01f; } } -void DE_LowerAngle( struct destruct_unit_s * unit ) +static void DE_LowerAngle( struct destruct_unit_s * unit ) { unit->angle -= 0.01f; if (unit->angle < 0) @@ -2781,7 +2776,7 @@ void DE_LowerAngle( struct destruct_unit_s * unit ) unit->angle = 0; } } -void DE_RaisePower( struct destruct_unit_s * unit ) +static void DE_RaisePower( struct destruct_unit_s * unit ) { unit->power += 0.05f; if (unit->power > 5) @@ -2789,7 +2784,7 @@ void DE_RaisePower( struct destruct_unit_s * unit ) unit->power = 5; } } -void DE_LowerPower( struct destruct_unit_s * unit ) +static void DE_LowerPower( struct destruct_unit_s * unit ) { unit->power -= 0.05f; if (unit->power < 1) @@ -2810,23 +2805,23 @@ static inline bool DE_isValidUnit( struct destruct_unit_s * unit ) } -bool DE_RunTickCheckEndgame( void ) +static bool DE_RunTickCheckEndgame( void ) { - if (player[PLAYER_LEFT].unitsRemaining == 0) + if (destruct_player[PLAYER_LEFT].unitsRemaining == 0) { - player[PLAYER_RIGHT].score += ModeScore[PLAYER_LEFT][world.destructMode]; + destruct_player[PLAYER_RIGHT].score += ModeScore[PLAYER_LEFT][world.destructMode]; soundQueue[7] = V_CLEARED_PLATFORM; return(true); } - if (player[PLAYER_RIGHT].unitsRemaining == 0) + if (destruct_player[PLAYER_RIGHT].unitsRemaining == 0) { - player[PLAYER_LEFT].score += ModeScore[PLAYER_RIGHT][world.destructMode]; + destruct_player[PLAYER_LEFT].score += ModeScore[PLAYER_RIGHT][world.destructMode]; soundQueue[7] = V_CLEARED_PLATFORM; return(true); } return(false); } -void DE_RunTickPlaySounds( void ) +static void DE_RunTickPlaySounds( void ) { unsigned int i, tempSampleIndex, tempVolume; @@ -2851,7 +2846,7 @@ void DE_RunTickPlaySounds( void ) } } -void JE_pixCool( unsigned int x, unsigned int y, Uint8 c ) +static void JE_pixCool( unsigned int x, unsigned int y, Uint8 c ) { JE_pix(VGAScreen, x, y, c); JE_pix(VGAScreen, x - 1, y, c - 2); @@ -2859,4 +2854,3 @@ void JE_pixCool( unsigned int x, unsigned int y, Uint8 c ) JE_pix(VGAScreen, x, y - 1, c - 2); JE_pix(VGAScreen, x, y + 1, c - 2); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/destruct.h b/project/jni/application/opentyrian/src/destruct.h index 9d1ab78aa..df7ff7108 100644 --- a/project/jni/application/opentyrian/src/destruct.h +++ b/project/jni/application/opentyrian/src/destruct.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -25,4 +25,3 @@ void JE_destructGame( void ); #endif /* DESTRUCT_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/editship.c b/project/jni/application/opentyrian/src/editship.c index e0c5bd06e..2815838c6 100644 --- a/project/jni/application/opentyrian/src/editship.c +++ b/project/jni/application/opentyrian/src/editship.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -89,4 +89,3 @@ void JE_loadExtraShapes( void ) } } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/editship.h b/project/jni/application/opentyrian/src/editship.h index 4496fecc9..210291241 100644 --- a/project/jni/application/opentyrian/src/editship.h +++ b/project/jni/application/opentyrian/src/editship.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -34,4 +34,3 @@ void JE_loadExtraShapes( void ); #endif /* EDITSHIP_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/episodes.c b/project/jni/application/opentyrian/src/episodes.c index f513281a3..796d53111 100644 --- a/project/jni/application/opentyrian/src/episodes.c +++ b/project/jni/application/opentyrian/src/episodes.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -26,7 +26,7 @@ /* MAIN Weapons Data */ JE_WeaponPortType weaponPort; -JE_WeaponType weapons; +JE_WeaponType weapons[WEAP_NUM + 1]; /* [0..weapnum] */ /* Items */ JE_PowerType powerSys; @@ -96,6 +96,12 @@ void JE_loadItemDat( void ) efread(&weapons[i].shipblastfilter, sizeof(JE_byte), 1, f); } +#ifdef TYRIAN2000 + if (episodeNum <= 3) fseek(f, 0x252A4, SEEK_SET); + if (episodeNum == 4) fseek(f, 0xC1F5E, SEEK_SET); + if (episodeNum == 5) fseek(f, 0x5C5B8, SEEK_SET); +#endif + for (int i = 0; i < PORT_NUM + 1; ++i) { fseek(f, 1, SEEK_CUR); /* skip string length */ @@ -111,7 +117,15 @@ void JE_loadItemDat( void ) efread(&weaponPort[i].poweruse, sizeof(JE_word), 1, f); } - for (int i = 0; i < SPECIAL_NUM + 1; ++i) + int specials_count = SPECIAL_NUM; +#ifdef TYRIAN2000 + if (episodeNum <= 3) fseek(f, 0x2662E, SEEK_SET); + if (episodeNum == 4) fseek(f, 0xC32E8, SEEK_SET); + if (episodeNum == 5) fseek(f, 0x5D942, SEEK_SET); + if (episodeNum >= 4) specials_count = SPECIAL_NUM + 8; /*this ugly hack will need a fix*/ +#endif + + for (int i = 0; i < specials_count + 1; ++i) { fseek(f, 1, SEEK_CUR); /* skip string length */ efread(&special[i].name, 1, 30, f); @@ -121,7 +135,13 @@ void JE_loadItemDat( void ) efread(&special[i].stype, sizeof(JE_byte), 1, f); efread(&special[i].wpn, sizeof(JE_word), 1, f); } - + +#ifdef TYRIAN2000 + if (episodeNum <= 3) fseek(f, 0x26E21, SEEK_SET); + if (episodeNum == 4) fseek(f, 0xC3ADB, SEEK_SET); + if (episodeNum == 5) fseek(f, 0x5E135, SEEK_SET); +#endif + for (int i = 0; i < POWER_NUM + 1; ++i) { fseek(f, 1, SEEK_CUR); /* skip string length */ @@ -132,6 +152,12 @@ void JE_loadItemDat( void ) efread(&powerSys[i].speed, sizeof(JE_byte), 1, f); efread(&powerSys[i].cost, sizeof(JE_word), 1, f); } + +#ifdef TYRIAN2000 + if (episodeNum <= 3) fseek(f, 0x26F24, SEEK_SET); + if (episodeNum == 4) fseek(f, 0xC3BDE, SEEK_SET); + if (episodeNum == 5) fseek(f, 0x5E238, SEEK_SET); +#endif for (int i = 0; i < SHIP_NUM + 1; ++i) { @@ -146,6 +172,12 @@ void JE_loadItemDat( void ) efread(&ships[i].cost, sizeof(JE_word), 1, f); efread(&ships[i].bigshipgraphic, sizeof(JE_byte), 1, f); } + +#ifdef TYRIAN2000 + if (episodeNum <= 3) fseek(f, 0x2722F, SEEK_SET); + if (episodeNum == 4) fseek(f, 0xC3EE9, SEEK_SET); + if (episodeNum == 5) fseek(f, 0x5E543, SEEK_SET); +#endif for (int i = 0; i < OPTION_NUM + 1; ++i) { @@ -166,7 +198,13 @@ void JE_loadItemDat( void ) efread(&options[i].stop, 1, 1, f); /* override sizeof(JE_boolean) */ efread(&options[i].icongr, sizeof(JE_byte), 1, f); } - + +#ifdef TYRIAN2000 + if (episodeNum <= 3) fseek(f, 0x27EF3, SEEK_SET); + if (episodeNum == 4) fseek(f, 0xC4BAD, SEEK_SET); + if (episodeNum == 5) fseek(f, 0x5F207, SEEK_SET); +#endif + for (int i = 0; i < SHIELD_NUM + 1; ++i) { fseek(f, 1, SEEK_CUR); /* skip string length */ @@ -264,4 +302,3 @@ unsigned int JE_findNextEpisode( void ) return newEpisode; } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/episodes.h b/project/jni/application/opentyrian/src/episodes.h index baf4bc60a..598e1ae18 100644 --- a/project/jni/application/opentyrian/src/episodes.h +++ b/project/jni/application/opentyrian/src/episodes.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -28,6 +28,11 @@ #define FIRST_LEVEL 1 #define EPISODE_MAX 5 +#ifdef TYRIAN2000 +#define EPISODE_AVAILABLE 5 +#else +#define EPISODE_AVAILABLE 4 +#endif typedef struct { @@ -46,7 +51,7 @@ typedef struct JE_byte sound; JE_byte trail; JE_byte shipblastfilter; -} JE_WeaponType[WEAP_NUM + 1]; /* [0..weapnum] */ +} JE_WeaponType; typedef struct { @@ -147,7 +152,7 @@ typedef struct } JE_EnemyDatType[ENEMY_NUM + 1]; /* [0..enemynum] */ extern JE_WeaponPortType weaponPort; -extern JE_WeaponType weapons; +extern JE_WeaponType weapons[WEAP_NUM + 1]; /* [0..weapnum] */ extern JE_PowerType powerSys; extern JE_ShipType ships; extern JE_OptionType options[OPTION_NUM + 1]; /* [0..optionnum] */ @@ -170,4 +175,3 @@ void JE_scanForEpisodes( void ); #endif /* EPISODES_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/file.c b/project/jni/application/opentyrian/src/file.c index cb3fe3f3a..78be0c099 100644 --- a/project/jni/application/opentyrian/src/file.c +++ b/project/jni/application/opentyrian/src/file.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -21,6 +21,8 @@ #include "SDL.h" #include +#include +#include const char *custom_data_dir = "."; @@ -76,11 +78,9 @@ FILE *dir_fopen( const char *dir, const char *file, const char *mode ) // warn when dir_fopen fails FILE *dir_fopen_warn( const char *dir, const char *file, const char *mode ) { - errno = 0; - FILE *f = dir_fopen(dir, file, mode); - if (!f) + if (f == NULL) fprintf(stderr, "warning: failed to open '%s': %s\n", file, strerror(errno)); return f; @@ -89,14 +89,12 @@ FILE *dir_fopen_warn( const char *dir, const char *file, const char *mode ) // die when dir_fopen fails FILE *dir_fopen_die( const char *dir, const char *file, const char *mode ) { - errno = 0; - FILE *f = dir_fopen(dir, file, mode); if (f == NULL) { fprintf(stderr, "error: failed to open '%s': %s\n", file, strerror(errno)); - fprintf(stderr, "error: One or more of the required Tyrian 2.1 data files could not be found.\n" + fprintf(stderr, "error: One or more of the required Tyrian " TYRIAN_VERSION " data files could not be found.\n" " Please read the README file.\n"); exit(1); } @@ -188,5 +186,3 @@ size_t efwrite( void *buffer, size_t size, size_t num, FILE *stream ) return f; } #endif - -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/file.h b/project/jni/application/opentyrian/src/file.h index 089f24837..735a73d06 100644 --- a/project/jni/application/opentyrian/src/file.h +++ b/project/jni/application/opentyrian/src/file.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -50,4 +50,3 @@ size_t efwrite( void *buffer, size_t size, size_t num, FILE *stream ); #endif // FILE_H -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/fm_synth.c b/project/jni/application/opentyrian/src/fm_synth.c deleted file mode 100644 index 6c2ba9adc..000000000 --- a/project/jni/application/opentyrian/src/fm_synth.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * OpenTyrian Classic: A modern cross-platform port of Tyrian - * Copyright (C) 2007-2009 The OpenTyrian Development Team - * - * This program 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 2 - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include "fmopl.h" -#include "fm_synth.h" -#include "loudness.h" -#include "opentyr.h" - -const unsigned char op_table[9] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12}; - -#define opl 0 - -void opl_update( OPLSAMPLE *buf, int samples ) -{ - YM3812UpdateOne(opl, buf, samples); -} - -void opl_init( void ) -{ - YM3812Init(1, 3579545, 11025 * OUTPUT_QUALITY); -} - -void opl_deinit( void ) -{ - YM3812Shutdown(); -} - -void opl_reset( void ) -{ - YM3812ResetChip(opl); -} - -void opl_write(int reg, int val) -{ - YM3812Write(opl, 0, reg); - YM3812Write(opl, 1, val); -} - -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/fm_synth.h b/project/jni/application/opentyrian/src/fm_synth.h deleted file mode 100644 index 835faee55..000000000 --- a/project/jni/application/opentyrian/src/fm_synth.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * OpenTyrian Classic: A modern cross-platform port of Tyrian - * Copyright (C) 2007-2009 The OpenTyrian Development Team - * - * This program 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 2 - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#ifndef FM_SYNTH_H -#define FM_SYNTH_H - -#include "fmopl.h" -#include "opentyr.h" - -extern const unsigned char op_table[9]; /* the 9 operators as expected by the OPL2 */ - -void opl_update( OPLSAMPLE *buf, int samples ); -void opl_init( void ); -void opl_deinit( void ); -void opl_reset( void ); -void opl_write( int, int ); - -#endif /* FM_SYNTH_H */ - -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/fmopl.c b/project/jni/application/opentyrian/src/fmopl.c deleted file mode 100644 index 6568973c4..000000000 --- a/project/jni/application/opentyrian/src/fmopl.c +++ /dev/null @@ -1,2400 +0,0 @@ -/* -** -** File: fmopl.c - software implementation of FM sound generator -** types OPL and OPL2 -** -** Copyright (C) 2002,2003 Jarek Burczynski (bujar at mame dot net) -** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmulator development -** -** Version 0.70 -** - -Revision History: - -14-06-2003 Jarek Burczynski: - - implemented all of the status register flags in Y8950 emulation - - renamed Y8950SetDeltaTMemory() parameters from _rom_ to _mem_ since - they can be either RAM or ROM - -08-10-2002 Jarek Burczynski (thanks to Dox for the YM3526 chip) - - corrected YM3526Read() to always set bit 2 and bit 1 - to HIGH state - identical to YM3812Read (verified on real YM3526) - -04-28-2002 Jarek Burczynski: - - binary exact Envelope Generator (verified on real YM3812); - compared to YM2151: the EG clock is equal to internal_clock, - rates are 2 times slower and volume resolution is one bit less - - modified interface functions (they no longer return pointer - - that's internal to the emulator now): - - new wrapper functions for OPLCreate: YM3526Init(), YM3812Init() and Y8950Init() - - corrected 'off by one' error in feedback calculations (when feedback is off) - - enabled waveform usage (credit goes to Vlad Romascanu and zazzal22) - - speeded up noise generator calculations (Nicola Salmoria) - -03-24-2002 Jarek Burczynski (thanks to Dox for the YM3812 chip) - Complete rewrite (all verified on real YM3812): - - corrected sin_tab and tl_tab data - - corrected operator output calculations - - corrected waveform_select_enable register; - simply: ignore all writes to waveform_select register when - waveform_select_enable == 0 and do not change the waveform previously selected. - - corrected KSR handling - - corrected Envelope Generator: attack shape, Sustain mode and - Percussive/Non-percussive modes handling - - Envelope Generator rates are two times slower now - - LFO amplitude (tremolo) and phase modulation (vibrato) - - rhythm sounds phase generation - - white noise generator (big thanks to Olivier Galibert for mentioning Berlekamp-Massey algorithm) - - corrected key on/off handling (the 'key' signal is ORed from three sources: FM, rhythm and CSM) - - funky details (like ignoring output of operator 1 in BD rhythm sound when connect == 1) - -12-28-2001 Acho A. Tang - - reflected Delta-T EOS status on Y8950 status port. - - fixed subscription range of attack/decay tables - - - To do: - add delay before key off in CSM mode (see CSMKeyControll) - verify volume of the FM part on the Y8950 -*/ - -#include -#include -#include -#include - -#include "fmopl.h" - -#ifndef PI -#define PI 3.14159265358979323846 -#endif - - - -/* output final shift */ -#if (OPL_SAMPLE_BITS==16) - #define FINAL_SH (0) - #define MAXOUT (+32767) - #define MINOUT (-32768) -#else - #define FINAL_SH (8) - #define MAXOUT (+127) - #define MINOUT (-128) -#endif - - -#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ -#define EG_SH 16 /* 16.16 fixed point (EG timing) */ -#define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */ -#define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */ - -#define FREQ_MASK ((1<=0) - { - if (value < 0x0200) - return (value & ~0); - if (value < 0x0400) - return (value & ~1); - if (value < 0x0800) - return (value & ~3); - if (value < 0x1000) - return (value & ~7); - if (value < 0x2000) - return (value & ~15); - if (value < 0x4000) - return (value & ~31); - return (value & ~63); - } - /*else value < 0*/ - if (value > -0x0200) - return (~abs(value) & ~0); - if (value > -0x0400) - return (~abs(value) & ~1); - if (value > -0x0800) - return (~abs(value) & ~3); - if (value > -0x1000) - return (~abs(value) & ~7); - if (value > -0x2000) - return (~abs(value) & ~15); - if (value > -0x4000) - return (~abs(value) & ~31); - return (~abs(value) & ~63); -} - - -static FILE *sample[1]; - #if 1 /*save to MONO file */ - #define SAVE_ALL_CHANNELS \ - { signed int pom = acc_calc(lt); \ - fputc((unsigned short)pom&0xff,sample[0]); \ - fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ - } - #else /*save to STEREO file */ - #define SAVE_ALL_CHANNELS \ - { signed int pom = lt; \ - fputc((unsigned short)pom&0xff,sample[0]); \ - fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ - pom = rt; \ - fputc((unsigned short)pom&0xff,sample[0]); \ - fputc(((unsigned short)pom>>8)&0xff,sample[0]); \ - } - #endif -#endif - -/* #define LOG_CYM_FILE */ -#ifdef LOG_CYM_FILE - FILE * cymfile = NULL; -#endif - - - -#define OPL_TYPE_WAVESEL 0x01 /* waveform select */ -#define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */ -#define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */ -#define OPL_TYPE_IO 0x08 /* I/O port */ - -/* ---------- Generic interface section ---------- */ -#define OPL_TYPE_YM3526 (0) -#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL) -#define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO) - - - -/* mapping of register number (offset) to slot number used by the emulator */ -static const int slot_array[32]= -{ - 0, 2, 4, 1, 3, 5,-1,-1, - 6, 8,10, 7, 9,11,-1,-1, - 12,14,16,13,15,17,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1 -}; - -/* key scale level */ -/* table is 3dB/octave , DV converts this into 6dB/octave */ -/* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */ -#define SC(x) ((UINT32)((x)/(0.1875/2.0))) -static const UINT32 ksl_tab[8*16]= -{ - /* OCT 0 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - /* OCT 1 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.750), SC(1.125), SC(1.500), - SC(1.875), SC(2.250), SC(2.625), SC(3.000), - /* OCT 2 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(1.125), SC(1.875), SC(2.625), - SC(3.000), SC(3.750), SC(4.125), SC(4.500), - SC(4.875), SC(5.250), SC(5.625), SC(6.000), - /* OCT 3 */ - SC(0.000), SC(0.000), SC(0.000), SC(1.875), - SC(3.000), SC(4.125), SC(4.875), SC(5.625), - SC(6.000), SC(6.750), SC(7.125), SC(7.500), - SC(7.875), SC(8.250), SC(8.625), SC(9.000), - /* OCT 4 */ - SC(0.000), SC(0.000), SC(3.000), SC(4.875), - SC(6.000), SC(7.125), SC(7.875), SC(8.625), - SC(9.000), SC(9.750),SC(10.125),SC(10.500), - SC(10.875),SC(11.250),SC(11.625),SC(12.000), - /* OCT 5 */ - SC(0.000), SC(3.000), SC(6.000), SC(7.875), - SC(9.000),SC(10.125),SC(10.875),SC(11.625), - SC(12.000),SC(12.750),SC(13.125),SC(13.500), - SC(13.875),SC(14.250),SC(14.625),SC(15.000), - /* OCT 6 */ - SC(0.000), SC(6.000), SC(9.000),SC(10.875), - SC(12.000),SC(13.125),SC(13.875),SC(14.625), - SC(15.000),SC(15.750),SC(16.125),SC(16.500), - SC(16.875),SC(17.250),SC(17.625),SC(18.000), - /* OCT 7 */ - SC(0.000), SC(9.000),SC(12.000),SC(13.875), - SC(15.000),SC(16.125),SC(16.875),SC(17.625), - SC(18.000),SC(18.750),SC(19.125),SC(19.500), - SC(19.875),SC(20.250),SC(20.625),SC(21.000) -}; -#undef SC - -/* sustain level table (3dB per step) */ -/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ -#define SC(db) (UINT32) ( db * (2.0/ENV_STEP) ) -static const UINT32 sl_tab[16]={ - SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7), - SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31) -}; -#undef SC - - -#define RATE_STEPS (8) -static const unsigned char eg_inc[15*RATE_STEPS]={ - -/*cycle:0 1 2 3 4 5 6 7*/ - -/* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */ -/* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..12 1 */ -/* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..12 2 */ -/* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..12 3 */ - -/* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 13 0 (increment by 1) */ -/* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 13 1 */ -/* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 13 2 */ -/* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 13 3 */ - -/* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 14 0 (increment by 2) */ -/* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 14 1 */ -/*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 14 2 */ -/*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 14 3 */ - -/*12 */ 4,4, 4,4, 4,4, 4,4, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 4) */ -/*13 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 2, 15 3 for attack */ -/*14 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */ -}; - - -#define O(a) (a*RATE_STEPS) - -/*note that there is no O(13) in this table - it's directly in the code */ -static const unsigned char eg_rate_select[16+64+16]={ /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ -/* 16 infinite time rates */ -O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), -O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), - -/* rates 00-12 */ -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), -O( 0),O( 1),O( 2),O( 3), - -/* rate 13 */ -O( 4),O( 5),O( 6),O( 7), - -/* rate 14 */ -O( 8),O( 9),O(10),O(11), - -/* rate 15 */ -O(12),O(12),O(12),O(12), - -/* 16 dummy rates (same as 15 3) */ -O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), -O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), - -}; -#undef O - -/*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */ -/*shift 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0 */ -/*mask 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0 */ - -#define O(a) (a*1) -static const unsigned char eg_rate_shift[16+64+16]={ /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ -/* 16 infinite time rates */ -O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), -O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), - -/* rates 00-12 */ -O(12),O(12),O(12),O(12), -O(11),O(11),O(11),O(11), -O(10),O(10),O(10),O(10), -O( 9),O( 9),O( 9),O( 9), -O( 8),O( 8),O( 8),O( 8), -O( 7),O( 7),O( 7),O( 7), -O( 6),O( 6),O( 6),O( 6), -O( 5),O( 5),O( 5),O( 5), -O( 4),O( 4),O( 4),O( 4), -O( 3),O( 3),O( 3),O( 3), -O( 2),O( 2),O( 2),O( 2), -O( 1),O( 1),O( 1),O( 1), -O( 0),O( 0),O( 0),O( 0), - -/* rate 13 */ -O( 0),O( 0),O( 0),O( 0), - -/* rate 14 */ -O( 0),O( 0),O( 0),O( 0), - -/* rate 15 */ -O( 0),O( 0),O( 0),O( 0), - -/* 16 dummy rates (same as 15 3) */ -O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), -O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), - -}; -#undef O - - -/* multiple table */ -#define SC(x) ((UINT32)((x)*2)) -static const UINT8 mul_tab[16]= { -/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */ - SC(0.50), SC(1.00), SC(2.00), SC(3.00), SC(4.00), SC(5.00), SC(6.00), SC(7.00), - SC(8.00), SC(9.00),SC(10.00),SC(10.00),SC(12.00),SC(12.00),SC(15.00),SC(15.00) -}; -#undef SC - -/* TL_TAB_LEN is calculated as: -* 12 - sinus amplitude bits (Y axis) -* 2 - sinus sign bit (Y axis) -* TL_RES_LEN - sinus resolution (X axis) -*/ -#define TL_TAB_LEN (12*2*TL_RES_LEN) -static signed int tl_tab[TL_TAB_LEN]; - -#define ENV_QUIET (TL_TAB_LEN>>4) - -/* sin waveform table in 'decibel' scale */ -/* four waveforms on OPL2 type chips */ -static unsigned int sin_tab[SIN_LEN * 4]; - - -/* LFO Amplitude Modulation table (verified on real YM3812) - 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples - - Length: 210 elements. - - Each of the elements has to be repeated - exactly 64 times (on 64 consecutive samples). - The whole table takes: 64 * 210 = 13440 samples. - - When AM = 1 data is used directly - When AM = 0 data is divided by 4 before being used (loosing precision is important) -*/ - -#define LFO_AM_TAB_ELEMENTS 210u - -static const UINT8 lfo_am_table[LFO_AM_TAB_ELEMENTS] = { -0,0,0,0,0,0,0, -1,1,1,1, -2,2,2,2, -3,3,3,3, -4,4,4,4, -5,5,5,5, -6,6,6,6, -7,7,7,7, -8,8,8,8, -9,9,9,9, -10,10,10,10, -11,11,11,11, -12,12,12,12, -13,13,13,13, -14,14,14,14, -15,15,15,15, -16,16,16,16, -17,17,17,17, -18,18,18,18, -19,19,19,19, -20,20,20,20, -21,21,21,21, -22,22,22,22, -23,23,23,23, -24,24,24,24, -25,25,25,25, -26,26,26, -25,25,25,25, -24,24,24,24, -23,23,23,23, -22,22,22,22, -21,21,21,21, -20,20,20,20, -19,19,19,19, -18,18,18,18, -17,17,17,17, -16,16,16,16, -15,15,15,15, -14,14,14,14, -13,13,13,13, -12,12,12,12, -11,11,11,11, -10,10,10,10, -9,9,9,9, -8,8,8,8, -7,7,7,7, -6,6,6,6, -5,5,5,5, -4,4,4,4, -3,3,3,3, -2,2,2,2, -1,1,1,1 -}; - -/* LFO Phase Modulation table (verified on real YM3812) */ -static const INT8 lfo_pm_table[8*8*2] = { - -/* FNUM2/FNUM = 00 0xxxxxxx (0x0000) */ -0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ -0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 00 1xxxxxxx (0x0080) */ -0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ -1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 01 0xxxxxxx (0x0100) */ -1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ -2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 01 1xxxxxxx (0x0180) */ -1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ -3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 10 0xxxxxxx (0x0200) */ -2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ -4, 2, 0,-2,-4,-2, 0, 2, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 10 1xxxxxxx (0x0280) */ -2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ -5, 2, 0,-2,-5,-2, 0, 2, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 11 0xxxxxxx (0x0300) */ -3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ -6, 3, 0,-3,-6,-3, 0, 3, /*LFO PM depth = 1*/ - -/* FNUM2/FNUM = 11 1xxxxxxx (0x0380) */ -3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ -7, 3, 0,-3,-7,-3, 0, 3 /*LFO PM depth = 1*/ -}; - - -/* lock level of common table */ -static int num_lock = 0; - - -static void *cur_chip = NULL; /* current chip pointer */ -static OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2; - -static signed int phase_modulation; /* phase modulation input (SLOT 2) */ -static signed int output[1]; - -#if BUILD_Y8950 -static INT32 output_deltat[4]; /* for Y8950 DELTA-T, chip is mono, that 4 here is just for safety */ -#endif - -static UINT32 LFO_AM; -static INT32 LFO_PM; - - - -inline int limit( int val, int max, int min ) { - if ( val > max ) - val = max; - else if ( val < min ) - val = min; - - return val; -} - - -/* status set and IRQ handling */ -inline void OPL_STATUS_SET(FM_OPL *OPL,int flag) -{ - /* set status flag */ - OPL->status |= flag; - if(!(OPL->status & 0x80)) - { - if(OPL->status & OPL->statusmask) - { /* IRQ on */ - OPL->status |= 0x80; - /* callback user interrupt handler (IRQ is OFF to ON) */ - if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1); - } - } -} - -/* status reset and IRQ handling */ -inline void OPL_STATUS_RESET(FM_OPL *OPL,int flag) -{ - /* reset status flag */ - OPL->status &=~flag; - if((OPL->status & 0x80)) - { - if (!(OPL->status & OPL->statusmask) ) - { - OPL->status &= 0x7f; - /* callback user interrupt handler (IRQ is ON to OFF) */ - if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0); - } - } -} - -/* IRQ mask set */ -inline void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag) -{ - OPL->statusmask = flag; - /* IRQ handling check */ - OPL_STATUS_SET(OPL,0); - OPL_STATUS_RESET(OPL,0); -} - - -/* advance LFO to next sample */ -inline void advance_lfo(FM_OPL *OPL) -{ - UINT8 tmp; - - /* LFO */ - OPL->lfo_am_cnt += OPL->lfo_am_inc; - if (OPL->lfo_am_cnt >= (LFO_AM_TAB_ELEMENTS<lfo_am_cnt -= (LFO_AM_TAB_ELEMENTS<lfo_am_cnt >> LFO_SH ]; - - if (OPL->lfo_am_depth) - LFO_AM = tmp; - else - LFO_AM = tmp>>2; - - OPL->lfo_pm_cnt += OPL->lfo_pm_inc; - LFO_PM = ((OPL->lfo_pm_cnt>>LFO_SH) & 7) | OPL->lfo_pm_depth_range; -} - -/* advance to next sample */ -inline void advance(FM_OPL *OPL) -{ - OPL_CH *CH; - OPL_SLOT *op; - int i; - - OPL->eg_timer += OPL->eg_timer_add; - - while (OPL->eg_timer >= OPL->eg_timer_overflow) - { - OPL->eg_timer -= OPL->eg_timer_overflow; - - OPL->eg_cnt++; - - for (i=0; i<9*2; i++) - { - CH = &OPL->P_CH[i/2]; - op = &CH->SLOT[i&1]; - - /* Envelope Generator */ - switch(op->state) - { - case EG_ATT: /* attack phase */ - if ( !(OPL->eg_cnt & ((1<eg_sh_ar)-1) ) ) - { - op->volume += (~op->volume * - (eg_inc[op->eg_sel_ar + ((OPL->eg_cnt>>op->eg_sh_ar)&7)]) - ) >>3; - - if (op->volume <= MIN_ATT_INDEX) - { - op->volume = MIN_ATT_INDEX; - op->state = EG_DEC; - } - - } - break; - - case EG_DEC: /* decay phase */ - if ( !(OPL->eg_cnt & ((1<eg_sh_dr)-1) ) ) - { - op->volume += eg_inc[op->eg_sel_dr + ((OPL->eg_cnt>>op->eg_sh_dr)&7)]; - - if ( op->volume >= (signed)op->sl ) - op->state = EG_SUS; - - } - break; - - case EG_SUS: /* sustain phase */ - - /* this is important behaviour: - one can change percusive/non-percussive modes on the fly and - the chip will remain in sustain phase - verified on real YM3812 */ - - if(op->eg_type) /* non-percussive mode */ - { - /* do nothing */ - } - else /* percussive mode */ - { - /* during sustain phase chip adds Release Rate (in percussive mode) */ - if ( !(OPL->eg_cnt & ((1<eg_sh_rr)-1) ) ) - { - op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)]; - - if ( op->volume >= MAX_ATT_INDEX ) - op->volume = MAX_ATT_INDEX; - } - /* else do nothing in sustain phase */ - } - break; - - case EG_REL: /* release phase */ - if ( !(OPL->eg_cnt & ((1<eg_sh_rr)-1) ) ) - { - op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)]; - - if ( op->volume >= MAX_ATT_INDEX ) - { - op->volume = MAX_ATT_INDEX; - op->state = EG_OFF; - } - - } - break; - - default: - break; - } - } - } - - for (i=0; i<9*2; i++) - { - CH = &OPL->P_CH[i/2]; - op = &CH->SLOT[i&1]; - - /* Phase Generator */ - if(op->vib) - { - UINT8 block; - unsigned int block_fnum = CH->block_fnum; - - unsigned int fnum_lfo = (block_fnum&0x0380) >> 7; - - signed int lfo_fn_table_index_offset = lfo_pm_table[LFO_PM + 16*fnum_lfo ]; - - if (lfo_fn_table_index_offset) /* LFO phase modulation active */ - { - block_fnum += lfo_fn_table_index_offset; - block = (block_fnum&0x1c00) >> 10; - op->Cnt += (OPL->fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul; - } - else /* LFO phase modulation = zero */ - { - op->Cnt += op->Incr; - } - } - else /* LFO phase modulation disabled for this operator */ - { - op->Cnt += op->Incr; - } - } - - /* The Noise Generator of the YM3812 is 23-bit shift register. - * Period is equal to 2^23-2 samples. - * Register works at sampling frequency of the chip, so output - * can change on every sample. - * - * Output of the register and input to the bit 22 is: - * bit0 XOR bit14 XOR bit15 XOR bit22 - * - * Simply use bit 22 as the noise output. - */ - - OPL->noise_p += OPL->noise_f; - i = OPL->noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */ - OPL->noise_p &= FREQ_MASK; - while (i) - { - /* - UINT32 j; - j = ( (OPL->noise_rng) ^ (OPL->noise_rng>>14) ^ (OPL->noise_rng>>15) ^ (OPL->noise_rng>>22) ) & 1; - OPL->noise_rng = (j<<22) | (OPL->noise_rng>>1); - */ - - /* - Instead of doing all the logic operations above, we - use a trick here (and use bit 0 as the noise output). - The difference is only that the noise bit changes one - step ahead. This doesn't matter since we don't know - what is real state of the noise_rng after the reset. - */ - - if (OPL->noise_rng & 1) OPL->noise_rng ^= 0x800302; - OPL->noise_rng >>= 1; - - i--; - } -} - - -inline signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) -{ - UINT32 p; - - p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm<<16))) >> FREQ_SH ) & SIN_MASK) ]; - - if (p >= TL_TAB_LEN) - return 0; - return tl_tab[p]; -} - -inline signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) -{ - UINT32 p; - - p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm )) >> FREQ_SH ) & SIN_MASK) ]; - - if (p >= TL_TAB_LEN) - return 0; - return tl_tab[p]; -} - - -#define volume_calc(OP) ((OP)->TLL + ((UINT32)(OP)->volume) + (LFO_AM & (OP)->AMmask)) - -/* calculate output */ -inline void OPL_CALC_CH( OPL_CH *CH ) -{ - OPL_SLOT *SLOT; - unsigned int env; - signed int out; - - phase_modulation = 0; - - /* SLOT 1 */ - SLOT = &CH->SLOT[SLOT1]; - env = volume_calc(SLOT); - out = SLOT->op1_out[0] + SLOT->op1_out[1]; - SLOT->op1_out[0] = SLOT->op1_out[1]; - *SLOT->connect1 += SLOT->op1_out[0]; - SLOT->op1_out[1] = 0; - if( env < ENV_QUIET ) - { - if (!SLOT->FB) - out = 0; - SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); - } - - /* SLOT 2 */ - SLOT++; - env = volume_calc(SLOT); - if( env < ENV_QUIET ) - output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable); -} - -/* - operators used in the rhythm sounds generation process: - - Envelope Generator: - -channel operator register number Bass High Snare Tom Top -/ slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal - 6 / 0 12 50 70 90 f0 + - 6 / 1 15 53 73 93 f3 + - 7 / 0 13 51 71 91 f1 + - 7 / 1 16 54 74 94 f4 + - 8 / 0 14 52 72 92 f2 + - 8 / 1 17 55 75 95 f5 + - - Phase Generator: - -channel operator register number Bass High Snare Tom Top -/ slot number MULTIPLE Drum Hat Drum Tom Cymbal - 6 / 0 12 30 + - 6 / 1 15 33 + - 7 / 0 13 31 + + + - 7 / 1 16 34 ----- n o t u s e d ----- - 8 / 0 14 32 + - 8 / 1 17 35 + + - -channel operator register number Bass High Snare Tom Top -number number BLK/FNUM2 FNUM Drum Hat Drum Tom Cymbal - 6 12,15 B6 A6 + - - 7 13,16 B7 A7 + + + - - 8 14,17 B8 A8 + + + - -*/ - -/* calculate rhythm */ - -inline void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) -{ - OPL_SLOT *SLOT; - signed int out; - unsigned int env; - - - /* Bass Drum (verified on real YM3812): - - depends on the channel 6 'connect' register: - when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out) - when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored - - output sample always is multiplied by 2 - */ - - phase_modulation = 0; - /* SLOT 1 */ - SLOT = &CH[6].SLOT[SLOT1]; - env = volume_calc(SLOT); - - out = SLOT->op1_out[0] + SLOT->op1_out[1]; - SLOT->op1_out[0] = SLOT->op1_out[1]; - - if (!SLOT->CON) - phase_modulation = SLOT->op1_out[0]; - /* else ignore output of operator 1 */ - - SLOT->op1_out[1] = 0; - if( env < ENV_QUIET ) - { - if (!SLOT->FB) - out = 0; - SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); - } - - /* SLOT 2 */ - SLOT++; - env = volume_calc(SLOT); - if( env < ENV_QUIET ) - output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable) * 2; - - - /* Phase generation is based on: */ - /* HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) */ - /* SD (16) channel 7->slot 1 */ - /* TOM (14) channel 8->slot 1 */ - /* TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) */ - - /* Envelope generation based on: */ - /* HH channel 7->slot1 */ - /* SD channel 7->slot2 */ - /* TOM channel 8->slot1 */ - /* TOP channel 8->slot2 */ - - - /* The following formulas can be well optimized. - I leave them in direct form for now (in case I've missed something). - */ - - /* High Hat (verified on real YM3812) */ - env = volume_calc(SLOT7_1); - if( env < ENV_QUIET ) - { - - /* high hat phase generation: - phase = d0 or 234 (based on frequency only) - phase = 34 or 2d0 (based on noise) - */ - - /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; - unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; - unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; - - unsigned char res1 = (bit2 ^ bit7) | bit3; - - /* when res1 = 0 phase = 0x000 | 0xd0; */ - /* when res1 = 1 phase = 0x200 | (0xd0>>2); */ - UINT32 phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; - - /* enable gate based on frequency of operator 2 in channel 8 */ - unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; - unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; - - unsigned char res2 = (bit3e ^ bit5e); - - /* when res2 = 0 pass the phase from calculation above (res1); */ - /* when res2 = 1 phase = 0x200 | (0xd0>>2); */ - if (res2) - phase = (0x200|(0xd0>>2)); - - - /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */ - /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */ - if (phase&0x200) - { - if (noise) - phase = 0x200|0xd0; - } - else - /* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */ - /* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */ - { - if (noise) - phase = 0xd0>>2; - } - - output[0] += op_calc(phase<wavetable) * 2; - } - - /* Snare Drum (verified on real YM3812) */ - env = volume_calc(SLOT7_2); - if( env < ENV_QUIET ) - { - /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit8 = ((SLOT7_1->Cnt>>FREQ_SH)>>8)&1; - - /* when bit8 = 0 phase = 0x100; */ - /* when bit8 = 1 phase = 0x200; */ - UINT32 phase = bit8 ? 0x200 : 0x100; - - /* Noise bit XOR'es phase by 0x100 */ - /* when noisebit = 0 pass the phase from calculation above */ - /* when noisebit = 1 phase ^= 0x100; */ - /* in other words: phase ^= (noisebit<<8); */ - if (noise) - phase ^= 0x100; - - output[0] += op_calc(phase<wavetable) * 2; - } - - /* Tom Tom (verified on real YM3812) */ - env = volume_calc(SLOT8_1); - if( env < ENV_QUIET ) - output[0] += op_calc(SLOT8_1->Cnt, env, 0, SLOT8_1->wavetable) * 2; - - /* Top Cymbal (verified on real YM3812) */ - env = volume_calc(SLOT8_2); - if( env < ENV_QUIET ) - { - /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; - unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; - unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; - - unsigned char res1 = (bit2 ^ bit7) | bit3; - - /* when res1 = 0 phase = 0x000 | 0x100; */ - /* when res1 = 1 phase = 0x200 | 0x100; */ - UINT32 phase = res1 ? 0x300 : 0x100; - - /* enable gate based on frequency of operator 2 in channel 8 */ - unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; - unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; - - unsigned char res2 = (bit3e ^ bit5e); - /* when res2 = 0 pass the phase from calculation above (res1); */ - /* when res2 = 1 phase = 0x200 | 0x100; */ - if (res2) - phase = 0x300; - - output[0] += op_calc(phase<wavetable) * 2; - } - -} - - -/* generic table initialize */ -static int init_tables(void) -{ - signed int i,x; - signed int n; - double o,m; - - - for (x=0; x>= 4; /* 12 bits here */ - if (n&1) /* round to nearest */ - n = (n>>1)+1; - else - n = n>>1; - /* 11 bits here (rounded) */ - n <<= 1; /* 12 bits here (as in real chip) */ - tl_tab[ x*2 + 0 ] = n; - tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ]; - - for (i=1; i<12; i++) - { - tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i; - tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ]; - } - #if 0 - logerror("tl %04i", x*2); - for (i=0; i<12; i++) - logerror(", [%02i] %5i", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ] ); - logerror("\n"); - #endif - } - /*logerror("FMOPL.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/ - - - for (i=0; i0.0) - o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */ - else - o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */ - - o = o / (ENV_STEP/4); - - n = (int)(2.0*o); - if (n&1) /* round to nearest */ - n = (n>>1)+1; - else - n = n>>1; - - sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 ); - - /*logerror("FMOPL.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, sin_tab[i], tl_tab[sin_tab[i]] );*/ - } - - for (i=0; i>1) ]; - - /* waveform 3: _ _ _ _ */ - /* / |_/ |_/ |_/ |_*/ - /* abs(output only first quarter of the sinus waveform) */ - - if (i & (1<<(SIN_BITS-2)) ) - sin_tab[3*SIN_LEN+i] = TL_TAB_LEN; - else - sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)]; - - /*logerror("FMOPL.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] ); - logerror("FMOPL.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] ); - logerror("FMOPL.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] );*/ - } - /*logerror("FMOPL.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/ - - -#ifdef SAVE_SAMPLE - sample[0]=fopen("sampsum.pcm","wb"); -#endif - - return 1; -} - -static void OPLCloseTable( void ) -{ -#ifdef SAVE_SAMPLE - fclose(sample[0]); -#endif -} - - - -static void OPL_initalize(FM_OPL *OPL) -{ - int i; - - /* frequency base */ - OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / 72.0) / OPL->rate : 0; -#if 0 - OPL->rate = (double)OPL->clock / 72.0; - OPL->freqbase = 1.0; -#endif - - /*logerror("freqbase=%f\n", OPL->freqbase);*/ - - /* Timer base time */ - OPL->TimerBase = 1.0 / ((double)OPL->clock / 72.0 ); - - /* make fnumber -> increment counter table */ - for( i=0 ; i < 1024 ; i++ ) - { - /* opn phase increment counter = 20bit */ - OPL->fn_tab[i] = (UINT32)( (double)i * 64 * OPL->freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ -#if 0 - logerror("FMOPL.C: fn_tab[%4i] = %08x (dec=%8i)\n", - i, OPL->fn_tab[i]>>6, OPL->fn_tab[i]>>6 ); -#endif - } - -#if 0 - for( i=0 ; i < 16 ; i++ ) - { - logerror("FMOPL.C: sl_tab[%i] = %08x\n", - i, sl_tab[i] ); - } - for( i=0 ; i < 8 ; i++ ) - { - int j; - logerror("FMOPL.C: ksl_tab[oct=%2i] =",i); - for (j=0; j<16; j++) - { - logerror("%08x ", ksl_tab[i*16+j] ); - } - logerror("\n"); - } -#endif - - - /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ - /* One entry from LFO_AM_TABLE lasts for 64 samples */ - OPL->lfo_am_inc = (UINT32)((1.0 / 64.0 ) * (1<freqbase); - - /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */ - OPL->lfo_pm_inc = (UINT32)((1.0 / 1024.0) * (1<freqbase); - - /*logerror ("OPL->lfo_am_inc = %8x ; OPL->lfo_pm_inc = %8x\n", OPL->lfo_am_inc, OPL->lfo_pm_inc);*/ - - /* Noise generator: a step takes 1 sample */ - OPL->noise_f = (UINT32)((1.0 / 1.0) * (1<freqbase); - - OPL->eg_timer_add = (UINT32)((1<freqbase); - OPL->eg_timer_overflow = ( 1 ) * (1<eg_timer_add, OPL->eg_timer_overflow);*/ - -} - -inline void FM_KEYON(OPL_SLOT *SLOT, UINT32 key_set) -{ - if( !SLOT->key ) - { - /* restart Phase Generator */ - SLOT->Cnt = 0; - /* phase -> Attack */ - SLOT->state = EG_ATT; - } - SLOT->key |= key_set; -} - -inline void FM_KEYOFF(OPL_SLOT *SLOT, UINT32 key_clr) -{ - if( SLOT->key ) - { - SLOT->key &= key_clr; - - if( !SLOT->key ) - { - /* phase -> Release */ - if (SLOT->state>EG_REL) - SLOT->state = EG_REL; - } - } -} - -/* update phase increment counter of operator (also update the EG rates if necessary) */ -inline void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) -{ - int ksr; - - /* (frequency) phase increment counter */ - SLOT->Incr = CH->fc * SLOT->mul; - ksr = CH->kcode >> SLOT->KSR; - - if( SLOT->ksr != ksr ) - { - SLOT->ksr = ksr; - - /* calculate envelope generator rates */ - if ((SLOT->ar + SLOT->ksr) < 16+62) - { - SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; - SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; - } - else - { - SLOT->eg_sh_ar = 0; - SLOT->eg_sel_ar = 13*RATE_STEPS; - } - SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; - SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; - SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; - SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; - } -} - -/* set multi,am,vib,EG-TYP,KSR,mul */ -inline void set_mul(FM_OPL *OPL,int slot,int v) -{ - OPL_CH *CH = &OPL->P_CH[slot/2]; - OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - - SLOT->mul = mul_tab[v&0x0f]; - SLOT->KSR = (v&0x10) ? 0 : 2; - SLOT->eg_type = (v&0x20); - SLOT->vib = (v&0x40); - SLOT->AMmask = (v&0x80) ? ~0 : 0; - CALC_FCSLOT(CH,SLOT); -} - -/* set ksl & tl */ -inline void set_ksl_tl(FM_OPL *OPL,int slot,int v) -{ - OPL_CH *CH = &OPL->P_CH[slot/2]; - OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - int ksl = v>>6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */ - - SLOT->ksl = ksl ? 3-ksl : 31; - SLOT->TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */ - - SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); -} - -/* set attack rate & decay rate */ -inline void set_ar_dr(FM_OPL *OPL,int slot,int v) -{ - OPL_CH *CH = &OPL->P_CH[slot/2]; - OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - - SLOT->ar = (v>>4) ? 16 + ((v>>4) <<2) : 0; - - if ((SLOT->ar + SLOT->ksr) < 16+62) - { - SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; - SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; - } - else - { - SLOT->eg_sh_ar = 0; - SLOT->eg_sel_ar = 13*RATE_STEPS; - } - - SLOT->dr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; - SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; - SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; -} - -/* set sustain level & release rate */ -inline void set_sl_rr(FM_OPL *OPL,int slot,int v) -{ - OPL_CH *CH = &OPL->P_CH[slot/2]; - OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - - SLOT->sl = sl_tab[ v>>4 ]; - - SLOT->rr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; - SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; - SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; -} - - -/* write a value v to register r on OPL chip */ -static void OPLWriteReg(FM_OPL *OPL, int r, int v) -{ - OPL_CH *CH; - int slot; - unsigned int block_fnum; - double interval; - - - /* adjust bus to 8 bits */ - r &= 0xff; - v &= 0xff; - -#ifdef LOG_CYM_FILE - if ((cymfile) && (r!=0) ) - { - fputc( (unsigned char)r, cymfile ); - fputc( (unsigned char)v, cymfile ); - } -#endif - - - switch(r&0xe0) - { - case 0x00: /* 00-1f:control */ - switch(r&0x1f) - { - case 0x01: /* waveform select enable */ - if(OPL->type&OPL_TYPE_WAVESEL) - { - OPL->wavesel = v&0x20; - /* do not change the waveform previously selected */ - } - break; - case 0x02: /* Timer 1 */ - OPL->T[0] = (256-v)*4; - break; - case 0x03: /* Timer 2 */ - OPL->T[1] = (256-v)*16; - break; - case 0x04: /* IRQ clear / mask and Timer enable */ - if(v&0x80) - { /* IRQ flag clear */ - OPL_STATUS_RESET(OPL,0x7f); - } - else - { /* set IRQ mask ,timer enable*/ - OPL->st[0] = v&1; - OPL->st[1] = (v>>1)&1; - - /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ - OPL_STATUS_RESET(OPL, v & 0x78 ); - OPL_STATUSMASK_SET(OPL, (~v) & 0x78 ); - - /* timer 1 */ - if(OPL->st[0]) - { - OPL->TC[0]=OPL->T[0]*20; - interval = (double)OPL->T[0]*OPL->TimerBase; - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval); - } - /* timer 2 */ - if(OPL->st[1]) - { - OPL->TC[1]=OPL->T[1]*20; - interval =(double)OPL->T[1]*OPL->TimerBase; - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval); - } - } - break; -#if BUILD_Y8950 - case 0x06: /* Key Board OUT */ - if(OPL->type&OPL_TYPE_KEYBOARD) - { - if(OPL->keyboardhandler_w) - OPL->keyboardhandler_w(OPL->keyboard_param,v); - else - logerror("Y8950: write unmapped KEYBOARD port\n"); - } - break; - case 0x07: /* DELTA-T control 1 : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */ - if(OPL->type&OPL_TYPE_ADPCM) - YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); - break; -#endif - case 0x08: /* MODE,DELTA-T control 2 : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */ - OPL->mode = v; -#if BUILD_Y8950 - if(OPL->type&OPL_TYPE_ADPCM) - YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v&0x0f); /* mask 4 LSBs in register 08 for DELTA-T unit */ -#endif - break; - -#if BUILD_Y8950 - case 0x09: /* START ADD */ - case 0x0a: - case 0x0b: /* STOP ADD */ - case 0x0c: - case 0x0d: /* PRESCALE */ - case 0x0e: - case 0x0f: /* ADPCM data write */ - case 0x10: /* DELTA-N */ - case 0x11: /* DELTA-N */ - case 0x12: /* ADPCM volume */ - if(OPL->type&OPL_TYPE_ADPCM) - YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); - break; - - case 0x15: /* DAC data high 8 bits (F7,F6...F2) */ - case 0x16: /* DAC data low 2 bits (F1, F0 in bits 7,6) */ - case 0x17: /* DAC data shift (S2,S1,S0 in bits 2,1,0) */ - logerror("FMOPL.C: DAC data register written, but not implemented reg=%02x val=%02x\n",r,v); - break; - - case 0x18: /* I/O CTRL (Direction) */ - if(OPL->type&OPL_TYPE_IO) - OPL->portDirection = v&0x0f; - break; - case 0x19: /* I/O DATA */ - if(OPL->type&OPL_TYPE_IO) - { - OPL->portLatch = v; - if(OPL->porthandler_w) - OPL->porthandler_w(OPL->port_param,v&OPL->portDirection); - } - break; -#endif - default: - printf("%s: write to unknown register: %02x\n", __FILE__, r); - break; - } - break; - case 0x20: /* am ON, vib ON, ksr, eg_type, mul */ - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_mul(OPL,slot,v); - break; - case 0x40: - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_ksl_tl(OPL,slot,v); - break; - case 0x60: - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_ar_dr(OPL,slot,v); - break; - case 0x80: - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_sl_rr(OPL,slot,v); - break; - case 0xa0: - if (r == 0xbd) /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */ - { - OPL->lfo_am_depth = v & 0x80; - OPL->lfo_pm_depth_range = (v&0x40) ? 8 : 0; - - OPL->rhythm = v&0x3f; - - if(OPL->rhythm&0x20) - { - /* BD key on/off */ - if(v&0x10) - { - FM_KEYON (&OPL->P_CH[6].SLOT[SLOT1], 2); - FM_KEYON (&OPL->P_CH[6].SLOT[SLOT2], 2); - } - else - { - FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2); - FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2); - } - /* HH key on/off */ - if(v&0x01) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT1], 2); - else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2); - /* SD key on/off */ - if(v&0x08) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT2], 2); - else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2); - /* TOM key on/off */ - if(v&0x04) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT1], 2); - else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2); - /* TOP-CY key on/off */ - if(v&0x02) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT2], 2); - else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2); - } - else - { - /* BD key off */ - FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2); - FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2); - /* HH key off */ - FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2); - /* SD key off */ - FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2); - /* TOM key off */ - FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2); - /* TOP-CY off */ - FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2); - } - return; - } - /* keyon,block,fnum */ - if( (r&0x0f) > 8) return; - CH = &OPL->P_CH[r&0x0f]; - if(!(r&0x10)) - { /* a0-a8 */ - block_fnum = (CH->block_fnum&0x1f00) | v; - } - else - { /* b0-b8 */ - block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff); - - if(v&0x20) - { - FM_KEYON (&CH->SLOT[SLOT1], 1); - FM_KEYON (&CH->SLOT[SLOT2], 1); - } - else - { - FM_KEYOFF(&CH->SLOT[SLOT1],~1); - FM_KEYOFF(&CH->SLOT[SLOT2],~1); - } - } - /* update */ - if(CH->block_fnum != block_fnum) - { - UINT8 block = block_fnum >> 10; - - CH->block_fnum = block_fnum; - - CH->ksl_base = ksl_tab[block_fnum>>6]; - CH->fc = OPL->fn_tab[block_fnum&0x03ff] >> (7-block); - - /* BLK 2,1,0 bits -> bits 3,2,1 of kcode */ - CH->kcode = (CH->block_fnum&0x1c00)>>9; - - /* the info below is actually opposite to what is stated in the Manuals (verifed on real YM3812) */ - /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */ - /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */ - if (OPL->mode&0x40) - CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */ - else - CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */ - - /* refresh Total Level in both SLOTs of this channel */ - CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); - CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); - - /* refresh frequency counter in both SLOTs of this channel */ - CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); - CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); - } - break; - case 0xc0: - /* FB,C */ - if( (r&0x0f) > 8) return; - CH = &OPL->P_CH[r&0x0f]; - CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; - CH->SLOT[SLOT1].CON = v&1; - CH->SLOT[SLOT1].connect1 = CH->SLOT[SLOT1].CON ? &output[0] : &phase_modulation; - break; - case 0xe0: /* waveform select */ - /* simply ignore write to the waveform select register if selecting not enabled in test register */ - if(OPL->wavesel) - { - slot = slot_array[r&0x1f]; - if(slot < 0) return; - CH = &OPL->P_CH[slot/2]; - - CH->SLOT[slot&1].wavetable = (v&0x03)*SIN_LEN; - } - break; - } -} - -#ifdef LOG_CYM_FILE -static void cymfile_callback (int n) -{ - if (cymfile) - { - fputc( (unsigned char)0, cymfile ); - } -} -#endif - -/* lock/unlock for common table */ -static int OPL_LockTable(void) -{ - num_lock++; - if(num_lock>1) return 0; - - /* first time */ - - cur_chip = NULL; - /* allocate total level table (128kb space) */ - if( !init_tables() ) - { - num_lock--; - return -1; - } - -#ifdef LOG_CYM_FILE - cymfile = fopen("3812_.cym","wb"); - if (cymfile) - timer_pulse ( TIME_IN_HZ(110), 0, cymfile_callback); /*110 Hz pulse timer*/ - else - logerror("Could not create file 3812_.cym\n"); -#endif - - return 0; -} - -static void OPL_UnLockTable(void) -{ - if(num_lock) num_lock--; - if(num_lock) return; - - /* last time */ - - cur_chip = NULL; - OPLCloseTable(); - -#ifdef LOG_CYM_FILE - fclose (cymfile); - cymfile = NULL; -#endif - -} - -static void OPLResetChip(FM_OPL *OPL) -{ - int c,s; - int i; - - OPL->eg_timer = 0; - OPL->eg_cnt = 0; - - OPL->noise_rng = 1; /* noise shift register */ - OPL->mode = 0; /* normal mode */ - OPL_STATUS_RESET(OPL,0x7f); - - /* reset with register write */ - OPLWriteReg(OPL,0x01,0); /* wavesel disable */ - OPLWriteReg(OPL,0x02,0); /* Timer1 */ - OPLWriteReg(OPL,0x03,0); /* Timer2 */ - OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */ - for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0); - - /* reset operator parameters */ - for( c = 0 ; c < 9 ; c++ ) - { - OPL_CH *CH = &OPL->P_CH[c]; - for(s = 0 ; s < 2 ; s++ ) - { - /* wave table */ - CH->SLOT[s].wavetable = 0; - CH->SLOT[s].state = EG_OFF; - CH->SLOT[s].volume = MAX_ATT_INDEX; - } - } -#if BUILD_Y8950 - if(OPL->type&OPL_TYPE_ADPCM) - { - YM_DELTAT *DELTAT = OPL->deltat; - - DELTAT->freqbase = OPL->freqbase; - DELTAT->output_pointer = &output_deltat[0]; - DELTAT->portshift = 5; - DELTAT->output_range = 1<<23; - YM_DELTAT_ADPCM_Reset(DELTAT,0); - } -#endif -} - -/* Create one of virtual YM3812/YM3526/Y8950 */ -/* 'clock' is chip clock in Hz */ -/* 'rate' is sampling rate */ -static FM_OPL *OPLCreate(int type, int clock, int rate) -{ - char *ptr; - FM_OPL *OPL; - int state_size; - - if (OPL_LockTable() ==-1) return NULL; - - /* calculate OPL state size */ - state_size = sizeof(FM_OPL); - -#if BUILD_Y8950 - if (type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT); -#endif - - /* allocate memory block */ - ptr = (char *)malloc(state_size); - - if (ptr==NULL) - return NULL; - - /* clear */ - memset(ptr,0,state_size); - - OPL = (FM_OPL *)ptr; - - ptr += sizeof(FM_OPL); - -#if BUILD_Y8950 - if (type&OPL_TYPE_ADPCM) - { - OPL->deltat = (YM_DELTAT *)ptr; - } - ptr += sizeof(YM_DELTAT); -#endif - - OPL->type = type; - OPL->clock = clock; - OPL->rate = rate; - - /* init global tables */ - OPL_initalize(OPL); - - return OPL; -} - -/* Destroy one of virtual YM3812 */ -static void OPLDestroy(FM_OPL *OPL) -{ - OPL_UnLockTable(); - free(OPL); -} - -/* Optional handlers */ - -static void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset) -{ - OPL->TimerHandler = TimerHandler; - OPL->TimerParam = channelOffset; -} -static void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param) -{ - OPL->IRQHandler = IRQHandler; - OPL->IRQParam = param; -} -static void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param) -{ - OPL->UpdateHandler = UpdateHandler; - OPL->UpdateParam = param; -} - -static int OPLWrite(FM_OPL *OPL,int a,int v) -{ - if( !(a&1) ) - { /* address port */ - OPL->address = v & 0xff; - } - else - { /* data port */ - if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); - OPLWriteReg(OPL,OPL->address,v); - } - return OPL->status>>7; -} - -static unsigned char OPLRead(FM_OPL *OPL,int a) -{ - if( !(a&1) ) - { - /* status port */ - - #if BUILD_Y8950 - - if(OPL->type&OPL_TYPE_ADPCM) /* Y8950 */ - { - return (OPL->status & (OPL->statusmask|0x80)) | (OPL->deltat->PCM_BSY&1); - } - - #endif - if (OPL->st[0]) { - if (OPL->TC[0]) OPL->TC[0]--; - else { - OPL->TC[0]=OPL->T[0]*20; - OPL_STATUS_SET(OPL,0x40); - } - } - if (OPL->st[1]) { - if (OPL->TC[1]) OPL->TC[1]--; - else { - OPL->TC[1]=OPL->T[1]*20; - OPL_STATUS_SET(OPL,0x40); - } - } - return OPL->status & (OPL->statusmask|0x80); - } - -#if BUILD_Y8950 - /* data port */ - switch(OPL->address) - { - case 0x05: /* KeyBoard IN */ - if(OPL->type&OPL_TYPE_KEYBOARD) - { - if(OPL->keyboardhandler_r) - return OPL->keyboardhandler_r(OPL->keyboard_param); - else - logerror("Y8950: read unmapped KEYBOARD port\n"); - } - return 0; - - case 0x0f: /* ADPCM-DATA */ - if(OPL->type&OPL_TYPE_ADPCM) - { - UINT8 val; - - val = YM_DELTAT_ADPCM_Read(OPL->deltat); - /*logerror("Y8950: read ADPCM value read=%02x\n",val);*/ - return val; - } - return 0; - - case 0x19: /* I/O DATA */ - if(OPL->type&OPL_TYPE_IO) - { - if(OPL->porthandler_r) - return OPL->porthandler_r(OPL->port_param); - else - logerror("Y8950:read unmapped I/O port\n"); - } - return 0; - case 0x1a: /* PCM-DATA */ - if(OPL->type&OPL_TYPE_ADPCM) - { - logerror("Y8950 A/D convertion is accessed but not implemented !\n"); - return 0x80; /* 2's complement PCM data - result from A/D convertion */ - } - return 0; - } -#endif - - return 0xff; -} - -/* CSM Key Controll */ -inline void CSMKeyControll(OPL_CH *CH) -{ - FM_KEYON (&CH->SLOT[SLOT1], 4); - FM_KEYON (&CH->SLOT[SLOT2], 4); - - /* The key off should happen exactly one sample later - not implemented correctly yet */ - - FM_KEYOFF(&CH->SLOT[SLOT1], ~4); - FM_KEYOFF(&CH->SLOT[SLOT2], ~4); -} - - -static int OPLTimerOver(FM_OPL *OPL,int c) -{ - if( c ) - { /* Timer B */ - OPL_STATUS_SET(OPL,0x20); - } - else - { /* Timer A */ - OPL_STATUS_SET(OPL,0x40); - /* CSM mode key,TL controll */ - if( OPL->mode & 0x80 ) - { /* CSM mode total level latch and auto key on */ - int ch; - if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); - for(ch=0; ch<9; ch++) - CSMKeyControll( &OPL->P_CH[ch] ); - } - } - /* reload timer */ -/* if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); */ - return OPL->status>>7; -} - - -#define MAX_OPL_CHIPS 1 - - -#if (BUILD_YM3812) - -static FM_OPL *OPL_YM3812[MAX_OPL_CHIPS]; /* array of pointers to the YM3812's */ -static int YM3812NumChips = 0; /* number of chips */ - -int YM3812Init(int num, int clock, int rate) -{ - int i; - - if (YM3812NumChips) - return -1; /* duplicate init. */ - - YM3812NumChips = num; - - for (i = 0;i < YM3812NumChips; i++) - { - /* emulator create */ - OPL_YM3812[i] = OPLCreate(OPL_TYPE_YM3812,clock,rate); - if(OPL_YM3812[i] == NULL) - { - /* it's really bad - we run out of memeory */ - YM3812NumChips = 0; - return -1; - } - /* reset */ - YM3812ResetChip(i); - } - - return 0; -} - -void YM3812Shutdown(void) -{ - int i; - - for (i = 0;i < YM3812NumChips; i++) - { - /* emulator shutdown */ - OPLDestroy(OPL_YM3812[i]); - OPL_YM3812[i] = NULL; - } - YM3812NumChips = 0; -} -void YM3812ResetChip(int which) -{ - OPLResetChip(OPL_YM3812[which]); -} - -int YM3812Write(int which, int a, int v) -{ - return OPLWrite(OPL_YM3812[which], a, v); -} - -unsigned char YM3812Read(int which, int a) -{ - /* YM3812 always returns bit2 and bit1 in HIGH state */ - return OPLRead(OPL_YM3812[which], a) | 0x06 ; -} -int YM3812TimerOver(int which, int c) -{ - return OPLTimerOver(OPL_YM3812[which], c); -} - -void YM3812SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) -{ - OPLSetTimerHandler(OPL_YM3812[which], TimerHandler, channelOffset); -} -void YM3812SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param) -{ - OPLSetIRQHandler(OPL_YM3812[which], IRQHandler, param); -} -void YM3812SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param) -{ - OPLSetUpdateHandler(OPL_YM3812[which], UpdateHandler, param); -} - - -/* -** Generate samples for one of the YM3812's -** -** 'which' is the virtual YM3812 number -** '*buffer' is the output buffer pointer -** 'length' is the number of samples that should be generated -*/ -void YM3812UpdateOne(int which, OPLSAMPLE *buffer, int length) -{ - FM_OPL *OPL = OPL_YM3812[which]; - UINT8 rhythm = OPL->rhythm&0x20; - OPLSAMPLE *buf = buffer; - int i; - - if( (void *)OPL != cur_chip ){ - cur_chip = (void *)OPL; - /* rhythm slots */ - SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1]; - SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2]; - SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1]; - SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2]; - } - for( i=0; i < length ; i++ ) - { - int lt; - - output[0] = 0; - - advance_lfo(OPL); - - /* FM part */ - OPL_CALC_CH(&OPL->P_CH[0]); - OPL_CALC_CH(&OPL->P_CH[1]); - OPL_CALC_CH(&OPL->P_CH[2]); - OPL_CALC_CH(&OPL->P_CH[3]); - OPL_CALC_CH(&OPL->P_CH[4]); - OPL_CALC_CH(&OPL->P_CH[5]); - - if(!rhythm) - { - OPL_CALC_CH(&OPL->P_CH[6]); - OPL_CALC_CH(&OPL->P_CH[7]); - OPL_CALC_CH(&OPL->P_CH[8]); - } - else /* Rhythm part */ - { - OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); - } - - lt = output[0]; - - lt >>= FINAL_SH; - - /* limit check */ - lt = limit( lt , MAXOUT, MINOUT ); - - #ifdef SAVE_SAMPLE - if (which==0) - { - SAVE_ALL_CHANNELS - } - #endif - - /* store to sound buffer */ - buf[i] = lt; - - advance(OPL); - } - -} -#endif /* BUILD_YM3812 */ - - - -#if (BUILD_YM3526) - -static FM_OPL *OPL_YM3526[MAX_OPL_CHIPS]; /* array of pointers to the YM3526's */ -static int YM3526NumChips = 0; /* number of chips */ - -int YM3526Init(int num, int clock, int rate) -{ - int i; - - if (YM3526NumChips) - return -1; /* duplicate init. */ - - YM3526NumChips = num; - - for (i = 0;i < YM3526NumChips; i++) - { - /* emulator create */ - OPL_YM3526[i] = OPLCreate(OPL_TYPE_YM3526,clock,rate); - if(OPL_YM3526[i] == NULL) - { - /* it's really bad - we run out of memeory */ - YM3526NumChips = 0; - return -1; - } - /* reset */ - YM3526ResetChip(i); - } - - return 0; -} - -void YM3526Shutdown(void) -{ - int i; - - for (i = 0;i < YM3526NumChips; i++) - { - /* emulator shutdown */ - OPLDestroy(OPL_YM3526[i]); - OPL_YM3526[i] = NULL; - } - YM3526NumChips = 0; -} -void YM3526ResetChip(int which) -{ - OPLResetChip(OPL_YM3526[which]); -} - -int YM3526Write(int which, int a, int v) -{ - return OPLWrite(OPL_YM3526[which], a, v); -} - -unsigned char YM3526Read(int which, int a) -{ - /* YM3526 always returns bit2 and bit1 in HIGH state */ - return OPLRead(OPL_YM3526[which], a) | 0x06 ; -} -int YM3526TimerOver(int which, int c) -{ - return OPLTimerOver(OPL_YM3526[which], c); -} - -void YM3526SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) -{ - OPLSetTimerHandler(OPL_YM3526[which], TimerHandler, channelOffset); -} -void YM3526SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param) -{ - OPLSetIRQHandler(OPL_YM3526[which], IRQHandler, param); -} -void YM3526SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param) -{ - OPLSetUpdateHandler(OPL_YM3526[which], UpdateHandler, param); -} - - -/* -** Generate samples for one of the YM3526's -** -** 'which' is the virtual YM3526 number -** '*buffer' is the output buffer pointer -** 'length' is the number of samples that should be generated -*/ -void YM3526UpdateOne(int which, INT16 *buffer, int length) -{ - FM_OPL *OPL = OPL_YM3526[which]; - UINT8 rhythm = OPL->rhythm&0x20; - OPLSAMPLE *buf = buffer; - int i; - - if( (void *)OPL != cur_chip ){ - cur_chip = (void *)OPL; - /* rhythm slots */ - SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1]; - SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2]; - SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1]; - SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2]; - } - for( i=0; i < length ; i++ ) - { - int lt; - - output[0] = 0; - - advance_lfo(OPL); - - /* FM part */ - OPL_CALC_CH(&OPL->P_CH[0]); - OPL_CALC_CH(&OPL->P_CH[1]); - OPL_CALC_CH(&OPL->P_CH[2]); - OPL_CALC_CH(&OPL->P_CH[3]); - OPL_CALC_CH(&OPL->P_CH[4]); - OPL_CALC_CH(&OPL->P_CH[5]); - - if(!rhythm) - { - OPL_CALC_CH(&OPL->P_CH[6]); - OPL_CALC_CH(&OPL->P_CH[7]); - OPL_CALC_CH(&OPL->P_CH[8]); - } - else /* Rhythm part */ - { - OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); - } - - lt = output[0]; - - lt >>= FINAL_SH; - - /* limit check */ - lt = limit( lt , MAXOUT, MINOUT ); - - #ifdef SAVE_SAMPLE - if (which==0) - { - SAVE_ALL_CHANNELS - } - #endif - - /* store to sound buffer */ - buf[i] = lt; - - advance(OPL); - } - -} -#endif /* BUILD_YM3526 */ - - - - -#if BUILD_Y8950 - -static FM_OPL *OPL_Y8950[MAX_OPL_CHIPS]; /* array of pointers to the Y8950's */ -static int Y8950NumChips = 0; /* number of chips */ - -static void Y8950_deltat_status_set(UINT8 which, UINT8 changebits) -{ - OPL_STATUS_SET(OPL_Y8950[which], changebits); -} -static void Y8950_deltat_status_reset(UINT8 which, UINT8 changebits) -{ - OPL_STATUS_RESET(OPL_Y8950[which], changebits); -} - -int Y8950Init(int num, int clock, int rate) -{ - int i; - - if (Y8950NumChips) - return -1; /* duplicate init. */ - - Y8950NumChips = num; - - for (i = 0;i < Y8950NumChips; i++) - { - /* emulator create */ - OPL_Y8950[i] = OPLCreate(OPL_TYPE_Y8950,clock,rate); - if(OPL_Y8950[i] == NULL) - { - /* it's really bad - we run out of memeory */ - Y8950NumChips = 0; - return -1; - } - OPL_Y8950[i]->deltat->status_set_handler = Y8950_deltat_status_set; - OPL_Y8950[i]->deltat->status_reset_handler = Y8950_deltat_status_reset; - OPL_Y8950[i]->deltat->status_change_which_chip = i; - OPL_Y8950[i]->deltat->status_change_EOS_bit = 0x10; /* status flag: set bit4 on End Of Sample */ - OPL_Y8950[i]->deltat->status_change_BRDY_bit = 0x08; /* status flag: set bit3 on BRDY (End Of: ADPCM analysis/synthesis, memory reading/writing) */ - /* reset */ - Y8950ResetChip(i); - } - - return 0; -} - -void Y8950Shutdown(void) -{ - int i; - - for (i = 0;i < Y8950NumChips; i++) - { - /* emulator shutdown */ - OPLDestroy(OPL_Y8950[i]); - OPL_Y8950[i] = NULL; - } - Y8950NumChips = 0; -} -void Y8950ResetChip(int which) -{ - OPLResetChip(OPL_Y8950[which]); -} - -int Y8950Write(int which, int a, int v) -{ - return OPLWrite(OPL_Y8950[which], a, v); -} - -unsigned char Y8950Read(int which, int a) -{ - return OPLRead(OPL_Y8950[which], a); -} -int Y8950TimerOver(int which, int c) -{ - return OPLTimerOver(OPL_Y8950[which], c); -} - -void Y8950SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) -{ - OPLSetTimerHandler(OPL_Y8950[which], TimerHandler, channelOffset); -} -void Y8950SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param) -{ - OPLSetIRQHandler(OPL_Y8950[which], IRQHandler, param); -} -void Y8950SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param) -{ - OPLSetUpdateHandler(OPL_Y8950[which], UpdateHandler, param); -} - -void Y8950SetDeltaTMemory(int which, void * deltat_mem_ptr, int deltat_mem_size ) -{ - FM_OPL *OPL = OPL_Y8950[which]; - OPL->deltat->memory = (UINT8 *)(deltat_mem_ptr); - OPL->deltat->memory_size = deltat_mem_size; -} - -/* -** Generate samples for one of the Y8950's -** -** 'which' is the virtual Y8950 number -** '*buffer' is the output buffer pointer -** 'length' is the number of samples that should be generated -*/ -void Y8950UpdateOne(int which, INT16 *buffer, int length) -{ - int i; - FM_OPL *OPL = OPL_Y8950[which]; - UINT8 rhythm = OPL->rhythm&0x20; - YM_DELTAT *DELTAT = OPL->deltat; - OPLSAMPLE *buf = buffer; - - if( (void *)OPL != cur_chip ){ - cur_chip = (void *)OPL; - /* rhythm slots */ - SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1]; - SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2]; - SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1]; - SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2]; - - } - for( i=0; i < length ; i++ ) - { - int lt; - - output[0] = 0; - output_deltat[0] = 0; - - advance_lfo(OPL); - - /* deltaT ADPCM */ - if( DELTAT->portstate&0x80 ) - YM_DELTAT_ADPCM_CALC(DELTAT); - - /* FM part */ - OPL_CALC_CH(&OPL->P_CH[0]); - OPL_CALC_CH(&OPL->P_CH[1]); - OPL_CALC_CH(&OPL->P_CH[2]); - OPL_CALC_CH(&OPL->P_CH[3]); - OPL_CALC_CH(&OPL->P_CH[4]); - OPL_CALC_CH(&OPL->P_CH[5]); - - if(!rhythm) - { - OPL_CALC_CH(&OPL->P_CH[6]); - OPL_CALC_CH(&OPL->P_CH[7]); - OPL_CALC_CH(&OPL->P_CH[8]); - } - else /* Rhythm part */ - { - OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); - } - - lt = output[0] + (output_deltat[0]>>11); - - lt >>= FINAL_SH; - - /* limit check */ - lt = limit( lt , MAXOUT, MINOUT ); - - #ifdef SAVE_SAMPLE - if (which==0) - { - SAVE_ALL_CHANNELS - } - #endif - - /* store to sound buffer */ - buf[i] = lt; - - advance(OPL); - } - -} - -void Y8950SetPortHandler(int which,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param) -{ - FM_OPL *OPL = OPL_Y8950[which]; - OPL->porthandler_w = PortHandler_w; - OPL->porthandler_r = PortHandler_r; - OPL->port_param = param; -} - -void Y8950SetKeyboardHandler(int which,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param) -{ - FM_OPL *OPL = OPL_Y8950[which]; - OPL->keyboardhandler_w = KeyboardHandler_w; - OPL->keyboardhandler_r = KeyboardHandler_r; - OPL->keyboard_param = param; -} - -#endif - -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/fmopl.h b/project/jni/application/opentyrian/src/fmopl.h deleted file mode 100644 index 9787e4a46..000000000 --- a/project/jni/application/opentyrian/src/fmopl.h +++ /dev/null @@ -1,253 +0,0 @@ -#ifndef __FMOPL_H_ -#define __FMOPL_H_ - -/* --- select emulation chips --- */ -#define BUILD_YM3812 1 /* (HAS_YM3812) */ -#define BUILD_YM3526 (HAS_YM3526) -#define BUILD_Y8950 (HAS_Y8950) - -/* select output bits size of output : 8 or 16 */ -#define OPL_SAMPLE_BITS 16 - -/* compiler dependence */ -#ifndef OSD_CPU_H -#define OSD_CPU_H -typedef unsigned char UINT8; /* unsigned 8bit */ -typedef unsigned short UINT16; /* unsigned 16bit */ -typedef unsigned int UINT32; /* unsigned 32bit */ -typedef signed char INT8; /* signed 8bit */ -typedef signed short INT16; /* signed 16bit */ -typedef signed int INT32; /* signed 32bit */ -#endif - -#if (OPL_SAMPLE_BITS==16) -typedef INT16 OPLSAMPLE; -#endif -#if (OPL_SAMPLE_BITS==8) -typedef INT8 OPLSAMPLE; -#endif - - -typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec); -typedef void (*OPL_IRQHANDLER)(int param,int irq); -typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us); -typedef void (*OPL_PORTHANDLER_W)(int param,unsigned char data); -typedef unsigned char (*OPL_PORTHANDLER_R)(int param); - - - -typedef struct{ - UINT32 ar; /* attack rate: AR<<2 */ - UINT32 dr; /* decay rate: DR<<2 */ - UINT32 rr; /* release rate:RR<<2 */ - UINT8 KSR; /* key scale rate */ - UINT8 ksl; /* keyscale level */ - UINT8 ksr; /* key scale rate: kcode>>KSR */ - UINT8 mul; /* multiple: mul_tab[ML] */ - - /* Phase Generator */ - UINT32 Cnt; /* frequency counter */ - UINT32 Incr; /* frequency counter step */ - UINT8 FB; /* feedback shift value */ - INT32 *connect1; /* slot1 output pointer */ - INT32 op1_out[2]; /* slot1 output for feedback */ - UINT8 CON; /* connection (algorithm) type */ - - /* Envelope Generator */ - UINT8 eg_type; /* percussive/non-percussive mode */ - UINT8 state; /* phase type */ - UINT32 TL; /* total level: TL << 2 */ - INT32 TLL; /* adjusted now TL */ - INT32 volume; /* envelope counter */ - UINT32 sl; /* sustain level: sl_tab[SL] */ - UINT8 eg_sh_ar; /* (attack state) */ - UINT8 eg_sel_ar; /* (attack state) */ - UINT8 eg_sh_dr; /* (decay state) */ - UINT8 eg_sel_dr; /* (decay state) */ - UINT8 eg_sh_rr; /* (release state) */ - UINT8 eg_sel_rr; /* (release state) */ - UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */ - - /* LFO */ - UINT32 AMmask; /* LFO Amplitude Modulation enable mask */ - UINT8 vib; /* LFO Phase Modulation enable flag (active high)*/ - - /* waveform select */ - unsigned int wavetable; -} OPL_SLOT; - -typedef struct{ - OPL_SLOT SLOT[2]; - /* phase generator state */ - UINT32 block_fnum; /* block+fnum */ - UINT32 fc; /* Freq. Increment base */ - UINT32 ksl_base; /* KeyScaleLevel Base step */ - UINT8 kcode; /* key code (for key scaling) */ -} OPL_CH; - -/* OPL state */ -typedef struct fm_opl_f { - /* FM channel slots */ - OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels*/ - - UINT32 eg_cnt; /* global envelope generator counter */ - UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/72 */ - UINT32 eg_timer_add; /* step of eg_timer */ - UINT32 eg_timer_overflow; /* envelope generator timer overlfows every 1 sample (on real chip) */ - - UINT8 rhythm; /* Rhythm mode */ - - UINT32 fn_tab[1024]; /* fnumber->increment counter */ - - /* LFO */ - UINT8 lfo_am_depth; - UINT8 lfo_pm_depth_range; - UINT32 lfo_am_cnt; - UINT32 lfo_am_inc; - UINT32 lfo_pm_cnt; - UINT32 lfo_pm_inc; - - UINT32 noise_rng; /* 23 bit noise shift register */ - UINT32 noise_p; /* current noise 'phase' */ - UINT32 noise_f; /* current noise period */ - - UINT8 wavesel; /* waveform select enable flag */ - - int T[2]; /* timer counters */ - int TC[2]; - UINT8 st[2]; /* timer enable */ - -#if BUILD_Y8950 - /* Delta-T ADPCM unit (Y8950) */ - - YM_DELTAT *deltat; - - /* Keyboard and I/O ports interface */ - UINT8 portDirection; - UINT8 portLatch; - OPL_PORTHANDLER_R porthandler_r; - OPL_PORTHANDLER_W porthandler_w; - int port_param; - OPL_PORTHANDLER_R keyboardhandler_r; - OPL_PORTHANDLER_W keyboardhandler_w; - int keyboard_param; -#endif - - /* external event callback handlers */ - OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ - int TimerParam; /* TIMER parameter */ - OPL_IRQHANDLER IRQHandler; /* IRQ handler */ - int IRQParam; /* IRQ parameter */ - OPL_UPDATEHANDLER UpdateHandler;/* stream update handler */ - int UpdateParam; /* stream update parameter */ - - UINT8 type; /* chip type */ - UINT8 address; /* address register */ - UINT8 status; /* status flag */ - UINT8 statusmask; /* status mask */ - UINT8 mode; /* Reg.08 : CSM,notesel,etc. */ - - int clock; /* master clock (Hz) */ - int rate; /* sampling rate (Hz) */ - double freqbase; /* frequency base */ - double TimerBase; /* Timer base time (==sampling time)*/ -} FM_OPL; - - - -#if BUILD_YM3812 - -int YM3812Init(int num, int clock, int rate); -void YM3812Shutdown(void); -void YM3812ResetChip(int which); -int YM3812Write(int which, int a, int v); -unsigned char YM3812Read(int which, int a); -int YM3812TimerOver(int which, int c); -void YM3812UpdateOne(int which, OPLSAMPLE *buffer, int length); - -void YM3812SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset); -void YM3812SetIRQHandler(int which, OPL_IRQHANDLER IRQHandler, int param); -void YM3812SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int param); - -#endif - - -#if BUILD_YM3526 - -/* -** Initialize YM3526 emulator(s). -** -** 'num' is the number of virtual YM3526's to allocate -** 'clock' is the chip clock in Hz -** 'rate' is sampling rate -*/ -int YM3526Init(int num, int clock, int rate); -/* shutdown the YM3526 emulators*/ -void YM3526Shutdown(void); -void YM3526ResetChip(int which); -int YM3526Write(int which, int a, int v); -unsigned char YM3526Read(int which, int a); -int YM3526TimerOver(int which, int c); -/* -** Generate samples for one of the YM3526's -** -** 'which' is the virtual YM3526 number -** '*buffer' is the output buffer pointer -** 'length' is the number of samples that should be generated -*/ -void YM3526UpdateOne(int which, INT16 *buffer, int length); - -void YM3526SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset); -void YM3526SetIRQHandler(int which, OPL_IRQHANDLER IRQHandler, int param); -void YM3526SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int param); - -#endif - - -#if BUILD_Y8950 - -#include "ymdeltat.h" - -/* Y8950 port handlers */ -void Y8950SetPortHandler(int which, OPL_PORTHANDLER_W PortHandler_w, OPL_PORTHANDLER_R PortHandler_r, int param); -void Y8950SetKeyboardHandler(int which, OPL_PORTHANDLER_W KeyboardHandler_w, OPL_PORTHANDLER_R KeyboardHandler_r, int param); -void Y8950SetDeltaTMemory(int which, void * deltat_mem_ptr, int deltat_mem_size ); - -int Y8950Init (int num, int clock, int rate); -void Y8950Shutdown (void); -void Y8950ResetChip (int which); -int Y8950Write (int which, int a, int v); -unsigned char Y8950Read (int which, int a); -int Y8950TimerOver (int which, int c); -void Y8950UpdateOne (int which, INT16 *buffer, int length); - -void Y8950SetTimerHandler (int which, OPL_TIMERHANDLER TimerHandler, int channelOffset); -void Y8950SetIRQHandler (int which, OPL_IRQHANDLER IRQHandler, int param); -void Y8950SetUpdateHandler (int which, OPL_UPDATEHANDLER UpdateHandler, int param); - -#endif - - -int limit( int val, int max, int min ); -void OPL_STATUS_SET(FM_OPL *OPL,int flag); -void OPL_STATUS_RESET(FM_OPL *OPL,int flag); -void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag); -void advance_lfo(FM_OPL *OPL); -void advance(FM_OPL *OPL); -signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab); -signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab); -void OPL_CALC_CH( OPL_CH *CH ); -void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ); -void FM_KEYON(OPL_SLOT *SLOT, UINT32 key_set); -void FM_KEYOFF(OPL_SLOT *SLOT, UINT32 key_clr); -void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT); -void set_mul(FM_OPL *OPL,int slot,int v); -void set_ksl_tl(FM_OPL *OPL,int slot,int v); -void set_ar_dr(FM_OPL *OPL,int slot,int v); -void set_sl_rr(FM_OPL *OPL,int slot,int v); -void CSMKeyControll(OPL_CH *CH); - - -#endif - -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/font.c b/project/jni/application/opentyrian/src/font.c index afc9001e8..64b1f618d 100644 --- a/project/jni/application/opentyrian/src/font.c +++ b/project/jni/application/opentyrian/src/font.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -20,10 +20,39 @@ #include "fonthand.h" #include "sprite.h" -// like JE_dString() if (black == false && shadow_dist == 2 && hue == 15) -// like JE_textShade() with PART_SHADE if (black == true && shadow_dist == 1) -// like JE_outTextAndDarken() if (black == false && shadow_dist == 1) -// like JE_outTextAdjust() with shadow if (black == false && shadow_dist == 2) +/** + * \file font.c + * \brief Text drawing routines. + */ + +/** + * \brief Draws text in a color specified by hue and value and with a drop + * shadow. + * + * A '~' in the text is not drawn but instead toggles highlighting which + * increases \c value by 4. + * + * \li like JE_dString() if (black == false && shadow_dist == 2 && hue == 15) + * \li like JE_textShade() with PART_SHADE if (black == true && shadow_dist == 1) + * \li like JE_outTextAndDarken() if (black == false && shadow_dist == 1) + * \li like JE_outTextAdjust() with shadow if (black == false && shadow_dist == 2) + * + * @param surface destination surface + * @param x initial x-position in pixels; which direction(s) the text is drawn + * from this position depends on the alignment + * @param y initial upper y-position in pixels + * @param text text to be drawn + * @param font style/size of text + * @param alignment left_aligned, centered, or right_aligned + * @param hue hue component of text color + * @param value value component of text color + * @param black if true the shadow is drawn as solid black, if false the shadow + * is drawn by darkening the pixels of the destination surface + * @param shadow_dist distance in pixels that the shadow will be drawn away from + * the text. (This is added to both the x and y positions, so a value of + * 1 causes the shadow to be drawn 1 pixel right and 1 pixel lower than + * the text.) + */ void draw_font_hv_shadow( SDL_Surface *surface, int x, int y, const char *text, Font font, FontAlignment alignment, Uint8 hue, Sint8 value, bool black, int shadow_dist ) { draw_font_dark(surface, x + shadow_dist, y + shadow_dist, text, font, alignment, black); @@ -31,7 +60,32 @@ void draw_font_hv_shadow( SDL_Surface *surface, int x, int y, const char *text, draw_font_hv(surface, x, y, text, font, alignment, hue, value); } -// like JE_textShade() with FULL_SHADE if (black == true && shadow_dist == 1) +/** + * \brief Draws text in a color specified by hue and value and with a + * surrounding shadow. + * + * A '~' in the text is not drawn but instead toggles highlighting which + * increases \c value by 4. + * + * \li like JE_textShade() with FULL_SHADE if (black == true && shadow_dist == 1) + * + * @param surface destination surface + * @param x initial x-position in pixels; which direction(s) the text is drawn + * from this position depends on the alignment + * @param y initial upper y-position in pixels + * @param text text to be drawn + * @param font style/size of text + * @param alignment left_aligned, centered, or right_aligned + * @param hue hue component of text color + * @param value value component of text color + * @param black if true the shadow is drawn as solid black, if false the shadow + * is drawn by darkening the pixels of the destination surface + * @param shadow_dist distance in pixels that the shadows will be drawn away + * from the text. (This distance is separately added to and subtracted + * from the x position and y position, resulting in four shadows -- one + * in each cardinal direction. If this shadow distance is small enough, + * this produces a shadow that outlines the text.) + */ void draw_font_hv_full_shadow( SDL_Surface *surface, int x, int y, const char *text, Font font, FontAlignment alignment, Uint8 hue, Sint8 value, bool black, int shadow_dist ) { draw_font_dark(surface, x, y - shadow_dist, text, font, alignment, black); @@ -42,8 +96,25 @@ void draw_font_hv_full_shadow( SDL_Surface *surface, int x, int y, const char *t draw_font_hv(surface, x, y, text, font, alignment, hue, value); } -// like JE_outText() with (brightness >= 0) -// like JE_outTextAdjust() without shadow +/** + * \brief Draws text in a color specified by hue and value. + * + * A '~' in the text is not drawn but instead toggles highlighting which + * increases \c value by 4. + * + * \li like JE_outText() with (brightness >= 0) + * \li like JE_outTextAdjust() without shadow + * + * @param surface destination surface + * @param x initial x-position in pixels; which direction(s) the text is drawn + * from this position depends on the alignment + * @param y initial upper y-position in pixels + * @param text text to be drawn + * @param font style/size of text + * @param alignment left_aligned, centered, or right_aligned + * @param hue hue component of text color + * @param value value component of text color + */ void draw_font_hv( SDL_Surface *surface, int x, int y, const char *text, Font font, FontAlignment alignment, Uint8 hue, Sint8 value ) { switch (alignment) @@ -90,7 +161,23 @@ void draw_font_hv( SDL_Surface *surface, int x, int y, const char *text, Font fo } } -// like JE_outTextModify() +/** + * \brief Draws blended text in a color specified by hue and value. + * + * Corresponds to blit_sprite_hv_blend() + * + * \li like JE_outTextModify() + * + * @param surface destination surface + * @param x initial x-position in pixels; which direction(s) the text is drawn + * from this position depends on the alignment + * @param y initial upper y-position in pixels + * @param text text to be drawn + * @param font style/size of text + * @param alignment left_aligned, centered, or right_aligned + * @param hue hue component of text color + * @param value value component of text color + */ void draw_font_hv_blend( SDL_Surface *surface, int x, int y, const char *text, Font font, FontAlignment alignment, Uint8 hue, Sint8 value ) { switch (alignment) @@ -130,7 +217,23 @@ void draw_font_hv_blend( SDL_Surface *surface, int x, int y, const char *text, F } } -// like JE_outText() with (brightness < 0) if (black == true) +/** + * \brief Draws darkened text. + * + * Corresponds to blit_sprite_dark() + * + * \li like JE_outText() with (brightness < 0) if (black == true) + * + * @param surface destination surface + * @param x initial x-position in pixels; which direction(s) the text is drawn + * from this position depends on the alignment + * @param y initial upper y-position in pixels + * @param text text to be drawn + * @param font style/size of text + * @param alignment left_aligned, centered, or right_aligned + * @param black if true text is drawn as solid black, if false text is drawn by + * darkening the pixels of the destination surface + */ void draw_font_dark( SDL_Surface *surface, int x, int y, const char *text, Font font, FontAlignment alignment, bool black ) { switch (alignment) diff --git a/project/jni/application/opentyrian/src/font.h b/project/jni/application/opentyrian/src/font.h index e1db04e92..08316a23a 100644 --- a/project/jni/application/opentyrian/src/font.h +++ b/project/jni/application/opentyrian/src/font.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or diff --git a/project/jni/application/opentyrian/src/fonthand.c b/project/jni/application/opentyrian/src/fonthand.c index a3e1e6a27..4a6369b8c 100644 --- a/project/jni/application/opentyrian/src/fonthand.c +++ b/project/jni/application/opentyrian/src/fonthand.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -330,4 +330,3 @@ void JE_outTextGlow( SDL_Surface * screen, int x, int y, const char *s ) textGlowBrightness = 6; } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/fonthand.h b/project/jni/application/opentyrian/src/fonthand.h index a858dfac8..190d3f19a 100644 --- a/project/jni/application/opentyrian/src/fonthand.h +++ b/project/jni/application/opentyrian/src/fonthand.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -57,4 +57,3 @@ void JE_outTextGlow( SDL_Surface * screen, int x, int y, const char *s ); #endif /* FONTHAND_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/game_menu.c b/project/jni/application/opentyrian/src/game_menu.c index 36619db03..d230cf752 100644 --- a/project/jni/application/opentyrian/src/game_menu.c +++ b/project/jni/application/opentyrian/src/game_menu.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -16,6 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "backgrnd.h" #include "config.h" #include "file.h" #include "fonthand.h" @@ -33,6 +34,7 @@ #include "pcxmast.h" #include "picload.h" #include "player.h" +#include "shots.h" #include "sprite.h" #include "tyrian2.h" #include "varz.h" @@ -66,7 +68,7 @@ static JE_MenuChoiceType menuChoices; static JE_integer col, colC; static JE_byte lastCurSel; static JE_integer curMenu; -static JE_byte curSel[MAX_MENU]; /* [1..maxmenu] */ +static JE_byte curSel[MENU_MAX]; /* [1..maxmenu] */ static JE_byte curItemType, curItem, cursor; static JE_boolean leftPower, rightPower, rightPowerAfford; static JE_byte currentCube; @@ -83,7 +85,7 @@ static PlayerItems old_items[2]; // TODO: should not be global if possible static struct cube_struct cube[4]; static const JE_MenuChoiceType menuChoicesDefault = { 7, 9, 8, 0, 0, 13, (SAVE_FILES_NUM / 2) + 2, 0, 0, 6, 4, 6, 7, 5 }; -static const JE_byte menuEsc[MAX_MENU] = { 0, 1, 1, 1, 2, 3, 3, 1, 8, 0, 0, 11, 3, 0 }; +static const JE_byte menuEsc[MENU_MAX] = { 0, 1, 1, 1, 2, 3, 3, 1, 8, 0, 0, 11, 3, 0 }; static const JE_byte itemAvailMap[7] = { 1, 2, 3, 9, 4, 6, 7 }; static const JE_word planetX[21] = { 200, 150, 240, 300, 270, 280, 320, 260, 220, 150, 160, 210, 80, 240, 220, 180, 310, 330, 150, 240, 200 }; static const JE_word planetY[21] = { 40, 90, 90, 80, 170, 30, 50, 130, 120, 150, 220, 200, 80, 50, 160, 10, 55, 55, 90, 90, 40 }; @@ -171,10 +173,8 @@ void JE_itemScreen( void ) cursor = 1; curItem = 0; - for (int x = 0; x < MAX_MENU; x++) - { - curSel[x] = 2; - } + for (unsigned int i = 0; i < COUNTOF(curSel); ++i) + curSel[i] = 2; curMenu = 0; @@ -546,7 +546,7 @@ void JE_itemScreen( void ) temp_cost = 0; } - temp4 = (temp_cost > player[0].cash) ? 4 : 0; // can player afford current weapon at all + int afford_shade = (temp_cost > player[0].cash) ? 4 : 0; // can player afford current weapon at all temp = itemAvail[itemAvailMap[curSel[1]-2]-1][tempW-1]; /* Item ID */ switch (curSel[1]-1) @@ -599,7 +599,7 @@ void JE_itemScreen( void ) { strcpy(tempStr, miscText[13]); } - JE_textShade(VGAScreen, 185, tempY, tempStr, temp2 / 16, temp2 % 16 -8-temp4, DARKEN); + JE_textShade(VGAScreen, 185, tempY, tempStr, temp2 / 16, temp2 % 16 - 8 - afford_shade, DARKEN); /* Draw icon if not DONE. NOTE: None is a normal item with a blank icon. */ if (tempW < menuChoices[curMenu]-1) @@ -616,7 +616,7 @@ void JE_itemScreen( void ) char buf[20]; snprintf(buf, sizeof buf, "Cost: %d", temp_cost); - JE_textShade(VGAScreen, 187, tempY+10, buf, temp2 / 16, temp2 % 16 - 8 - temp4, DARKEN); + JE_textShade(VGAScreen, 187, tempY+10, buf, temp2 / 16, temp2 % 16 - 8 - afford_shade, DARKEN); } } } /* /weapon upgrade */ @@ -673,8 +673,8 @@ void JE_itemScreen( void ) /* Changing the volume? */ if ((curMenu == 2) || (curMenu == 11)) { - JE_barDrawShadow(VGAScreen, 225, 70, 1, 16, tyrMusicVolume / 12, 3, 13); - JE_barDrawShadow(VGAScreen, 225, 86, 1, 16, fxVolume / 12, 3, 13); + JE_barDrawShadow(VGAScreen, 225, 70, 1, music_disabled ? 12 : 16, tyrMusicVolume / 12, 3, 13); + JE_barDrawShadow(VGAScreen, 225, 86, 1, samples_disabled ? 12 : 16, fxVolume / 12, 3, 13); } /* 7 is data cubes menu, 8 is reading a data cube, "firstmenu9" refers to menu 8 because of reindexing */ @@ -1132,34 +1132,34 @@ void JE_itemScreen( void ) if ((mouseY > 20) && (mouseX > 170) && (mouseX < 308) && (curMenu != 8)) { - const JE_byte mouseSelectionY[MAX_MENU] = { 16, 16, 16, 16, 26, 12, 11, 28, 0, 16, 16, 16, 8, 16 }; + const JE_byte mouseSelectionY[MENU_MAX] = { 16, 16, 16, 16, 26, 12, 11, 28, 0, 16, 16, 16, 8, 16 }; - tempI = (mouseY - 38) / mouseSelectionY[curMenu]+2; + int selection = (mouseY - 38) / mouseSelectionY[curMenu]+2; if (curMenu == 9) { - if (tempI > 5) - tempI--; - if (tempI > 3) - tempI--; + if (selection > 5) + selection--; + if (selection > 3) + selection--; } if (curMenu == 0) { - if (tempI > 7) - tempI = 7; + if (selection > 7) + selection = 7; } // is play next level screen? if (curMenu == 3) { - if (tempI == menuChoices[curMenu] + 1) - tempI = menuChoices[curMenu]; + if (selection == menuChoices[curMenu] + 1) + selection = menuChoices[curMenu]; } - if (tempI <= menuChoices[curMenu]) + if (selection <= menuChoices[curMenu]) { - if ((curMenu == 4) && (tempI == menuChoices[4])) + if ((curMenu == 4) && (selection == menuChoices[4])) { player[0].cash = JE_cashLeft(); curMenu = 1; @@ -1168,13 +1168,13 @@ void JE_itemScreen( void ) else { JE_playSampleNum(S_CLICK); - if (curSel[curMenu] == tempI) + if (curSel[curMenu] == selection) { JE_menuFunction(curSel[curMenu]); } else { - if ((curMenu == 5) && (JE_getCost(curSel[1], itemAvail[itemAvailMap[curSel[2]-1]][tempI-1]) > player[0].cash)) + if ((curMenu == 4) && (JE_getCost(curSel[1], itemAvail[itemAvailMap[curSel[2]-1]][selection-2]) > player[0].cash)) { JE_playSampleNum(S_CLINK); } @@ -1183,7 +1183,7 @@ void JE_itemScreen( void ) if (curSel[1] == 4) player[0].weapon_mode = 1; - curSel[curMenu] = tempI; + curSel[curMenu] = selection; } // in front or rear weapon upgrade screen? @@ -1584,6 +1584,7 @@ void JE_itemScreen( void ) } while (!(quit || gameLoaded || jumpSection)); +#ifdef WITH_NETWORK if (!quit && isNetworkGame) { JE_barShade(VGAScreen, 3, 3, 316, 196); @@ -1624,6 +1625,7 @@ void JE_itemScreen( void ) SDL_Delay(16); } } +#endif if (gameLoaded) fade_black(10); @@ -2250,7 +2252,7 @@ void JE_initWeaponView( void ) memset(shotRepeat, 1, sizeof(shotRepeat)); memset(shotMultiPos, 0, sizeof(shotMultiPos)); - JE_setupStars(); + initialize_starfield(); } void JE_computeDots( void ) @@ -2329,26 +2331,28 @@ void JE_drawMainMenuHelpText( void ) { int help[16] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 24, 11 }; memcpy(tempStr, mainMenuHelp[help[curSel[curMenu] - 2]], sizeof(tempStr)); - } else if (curMenu < 3 || curMenu == 9 || curMenu > 10) { - memcpy(tempStr, mainMenuHelp[(menuHelp[curMenu][temp])-1], sizeof(tempStr)); - } else { - if (curMenu == 5 && curSel[5] == 10) - { - memcpy(tempStr, mainMenuHelp[25-1], sizeof(tempStr)); - } - else if (leftPower || rightPower) - { - memcpy(tempStr, mainMenuHelp[24-1], sizeof(tempStr)); - } - else if ( (temp == menuChoices[curMenu] - 1) || ( (curMenu == 7) && (cubeMax == 0) ) ) - { - memcpy(tempStr, mainMenuHelp[12-1], sizeof(tempStr)); - } - else - { - memcpy(tempStr, mainMenuHelp[17 + curMenu - 3], sizeof(tempStr)); - } } + else if (curMenu < 3 || curMenu == 9 || curMenu > 10) + { + memcpy(tempStr, mainMenuHelp[(menuHelp[curMenu][temp])-1], sizeof(tempStr)); + } + else if (curMenu == 5 && curSel[5] == 10) + { + memcpy(tempStr, mainMenuHelp[25-1], sizeof(tempStr)); + } + else if (leftPower || rightPower) + { + memcpy(tempStr, mainMenuHelp[24-1], sizeof(tempStr)); + } + else if ( (temp == menuChoices[curMenu] - 1) || ( (curMenu == 7) && (cubeMax == 0) ) ) + { + memcpy(tempStr, mainMenuHelp[12-1], sizeof(tempStr)); + } + else + { + memcpy(tempStr, mainMenuHelp[17 + curMenu - 3], sizeof(tempStr)); + } + JE_textShade(VGAScreen, 10, 187, tempStr, 14, 1, DARKEN); } @@ -2453,6 +2457,7 @@ JE_boolean JE_quitRequest( void ) JE_playSampleNum(quit_selected ? S_SPRING : S_CLICK); +#ifdef WITH_NETWORK if (isNetworkGame && quit_selected) { network_prepare(PACKET_QUIT); @@ -2460,6 +2465,7 @@ JE_boolean JE_quitRequest( void ) network_tyrian_halt(0, true); } +#endif return quit_selected; } @@ -2730,8 +2736,6 @@ void JE_menuFunction( JE_byte select ) if (lastkey_sym != SDLK_ESCAPE && // reserved for menu lastkey_sym != SDLK_F11 && // reserved for gamma - lastkey_sym != SDLK_s && // reserved for sample mute - lastkey_sym != SDLK_m && // reserved for music mute lastkey_sym != SDLK_p) // reserved for pause { JE_playSampleNum(S_CLICK); @@ -3150,40 +3154,12 @@ void JE_weaponSimUpdate( void ) void JE_weaponViewFrame( void ) { - Uint8 *s; /* screen pointer, 8-bit specific */ - int i; - fill_rectangle_xy(VGAScreen, 8, 8, 143, 182, 0); /* JE: (* Port Configuration Display *) (* drawportconfigbuttons;*/ - /*===========================STARS==========================*/ - /*DRAWSTARS*/ - - for (i = MAX_STARS; i--;) - { - s = (Uint8 *)VGAScreen->pixels; - - starDat[i].sLoc += starDat[i].sMov + VGAScreen->pitch; - - if (starDat[i].sLoc < 177 * VGAScreen->pitch) - { - if (*(s + starDat[i].sLoc) == 0) - *(s + starDat[i].sLoc) = starDat[i].sC; - if (starDat[i].sC - 4 >= 9 * 16) - { - if (*(s + starDat[i].sLoc + 1) == 0) - *(s + starDat[i].sLoc + 1) = starDat[i].sC - 4; - if (starDat[i].sLoc > 0 && *(s + starDat[i].sLoc - 1) == 0) - *(s + starDat[i].sLoc - 1) = starDat[i].sC - 4; - if (*(s + starDat[i].sLoc + VGAScreen->pitch) == 0) - *(s + starDat[i].sLoc + VGAScreen->pitch) = starDat[i].sC - 4; - if (starDat[i].sLoc >= VGAScreen->pitch && *(s + starDat[i].sLoc - VGAScreen->pitch) == 0) - *(s + starDat[i].sLoc - VGAScreen->pitch) = starDat[i].sC - 4; - } - } - } + update_and_draw_starfield(VGAScreen, 1); mouseX = player[0].x; mouseY = player[0].y; @@ -3201,7 +3177,7 @@ void JE_weaponViewFrame( void ) item_power = player[0].items.weapon[i].power - 1, item_mode = (i == REAR_WEAPON) ? player[0].weapon_mode - 1 : 0; - JE_initPlayerShot(item, i, player[0].x, player[0].y, mouseX, mouseY, weaponPort[item].op[item_mode][item_power], 1); + b = player_shot_create(item, i, player[0].x, player[0].y, mouseX, mouseY, weaponPort[item].op[item_mode][item_power], 1); } } @@ -3217,7 +3193,7 @@ void JE_weaponViewFrame( void ) const int x = player[0].sidekick[LEFT_SIDEKICK].x, y = player[0].sidekick[LEFT_SIDEKICK].y; - JE_initPlayerShot(options[item].wport, SHOT_LEFT_SIDEKICK, x, y, mouseX, mouseY, options[item].wpnum, 1); + b = player_shot_create(options[item].wport, SHOT_LEFT_SIDEKICK, x, y, mouseX, mouseY, options[item].wpnum, 1); } } @@ -3244,87 +3220,11 @@ void JE_weaponViewFrame( void ) const int x = player[0].sidekick[RIGHT_SIDEKICK].x, y = player[0].sidekick[RIGHT_SIDEKICK].y; - JE_initPlayerShot(options[item].wport, SHOT_RIGHT_SIDEKICK, x, y, mouseX, mouseY, options[item].wpnum, 1); + b = player_shot_create(options[item].wport, SHOT_RIGHT_SIDEKICK, x, y, mouseX, mouseY, options[item].wpnum, 1); } } - /* Player Shot Images */ - for (int z = 0; z < MAX_PWEAPON; z++) - { - if (shotAvail[z] != 0) - { - shotAvail[z]--; - if (z != MAX_PWEAPON - 1) - { - playerShotData[z].shotXM += playerShotData[z].shotXC; - - if (playerShotData[z].shotXM <= 100) - playerShotData[z].shotX += playerShotData[z].shotXM; - - playerShotData[z].shotYM += playerShotData[z].shotYC; - playerShotData[z].shotY += playerShotData[z].shotYM; - - if (playerShotData[z].shotYM > 100) - { - playerShotData[z].shotY -= 120; - playerShotData[z].shotY += player[0].delta_y_shot_move; - } - - if (playerShotData[z].shotComplicated != 0) - { - playerShotData[z].shotDevX += playerShotData[z].shotDirX; - playerShotData[z].shotX += playerShotData[z].shotDevX; - - if (abs(playerShotData[z].shotDevX) == playerShotData[z].shotCirSizeX) - playerShotData[z].shotDirX = -playerShotData[z].shotDirX; - - playerShotData[z].shotDevY += playerShotData[z].shotDirY; - playerShotData[z].shotY += playerShotData[z].shotDevY; - - if (abs(playerShotData[z].shotDevY) == playerShotData[z].shotCirSizeY) - playerShotData[z].shotDirY = -playerShotData[z].shotDirY; - /*Double Speed Circle Shots - add a second copy of above loop*/ - } - - int tempShotX = playerShotData[z].shotX; - int tempShotY = playerShotData[z].shotY; - - if (playerShotData[z].shotX < 0 || playerShotData[z].shotX > 140 || - playerShotData[z].shotY < 0 || playerShotData[z].shotY > 170) - { - shotAvail[z] = 0; - goto draw_player_shot_loop_end; - } - -/* if (playerShotData[z].shotTrail != 255) - { - if (playerShotData[z].shotTrail == 98) - { - JE_setupExplosion(playerShotData[z].shotX - playerShotData[z].shotXM, playerShotData[z].shotY - playerShotData[z].shotYM, playerShotData[z].shotTrail); - } else { - JE_setupExplosion(playerShotData[z].shotX, playerShotData[z].shotY, playerShotData[z].shotTrail); - } - }*/ - - tempW = playerShotData[z].shotGr + playerShotData[z].shotAni; - if (++playerShotData[z].shotAni == playerShotData[z].shotAniMax) - playerShotData[z].shotAni = 0; - - if (tempW < 6000) - { - if (tempW > 1000) - tempW = tempW % 1000; - if (tempW > 500) - blit_sprite2(VGAScreen, tempShotX+1, tempShotY, shapesW2, tempW - 500); - else - blit_sprite2(VGAScreen, tempShotX+1, tempShotY, shapesC1, tempW); - } - } - -draw_player_shot_loop_end: - ; - } - } + simulate_player_shots(); blit_sprite(VGAScreenSeg, 0, 0, OPTION_SHAPES, 12); // upgrade interface @@ -3371,4 +3271,3 @@ draw_player_shot_loop_end: //JE_waitFrameCount(); TODO: didn't do anything? } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/game_menu.h b/project/jni/application/opentyrian/src/game_menu.h index 99734d85c..bbeb81b58 100644 --- a/project/jni/application/opentyrian/src/game_menu.h +++ b/project/jni/application/opentyrian/src/game_menu.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -22,7 +22,7 @@ #include "helptext.h" #include "opentyr.h" -typedef JE_byte JE_MenuChoiceType[MAX_MENU]; +typedef JE_byte JE_MenuChoiceType[MENU_MAX]; JE_longint JE_cashLeft( void ); void JE_itemScreen( void ); @@ -56,4 +56,3 @@ void JE_weaponViewFrame( void ); #endif // GAME_MENU_H -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/helptext.c b/project/jni/application/opentyrian/src/helptext.c index 030e14716..d903950ea 100644 --- a/project/jni/application/opentyrian/src/helptext.c +++ b/project/jni/application/opentyrian/src/helptext.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -29,7 +29,7 @@ #include -const JE_byte menuHelp[MAX_MENU][11] = /* [1..maxmenu, 1..11] */ +const JE_byte menuHelp[MENU_MAX][11] = /* [1..maxmenu, 1..11] */ { { 1, 34, 2, 3, 4, 5, 0, 0, 0, 0, 0 }, { 6, 7, 8, 9, 10, 11, 11, 12, 0, 0, 0 }, @@ -52,29 +52,29 @@ JE_byte helpBoxColor = 12; JE_byte helpBoxBrightness = 1; JE_byte helpBoxShadeType = FULL_SHADE; -char helpTxt[MAX_HELP_MESSAGE][231]; /* [1..maxhelpmessage] of string [230]; */ -char pName[21][16]; /* [1..21] of string [15] */ -char miscText[68][42]; /* [1..68] of string [41] */ -char miscTextB[5][11]; /* [1..5] of string [10] */ -char keyName[8][18]; /* [1..8] of string [17] */ -char menuText[7][21]; /* [1..7] of string [20] */ -char outputs[9][31]; /* [1..9] of string [30] */ -char topicName[6][21]; /* [1..6] of string [20] */ -char mainMenuHelp[34][66]; -char inGameText[6][21]; /* [1..6] of string [20] */ -char detailLevel[6][13]; /* [1..6] of string [12] */ -char gameSpeedText[5][13]; /* [1..5] of string [12] */ -char inputDevices[3][13]; /* [1..3] of string [12] */ -char networkText[4][22]; /* [1..4] of string [20] */ -char difficultyNameB[11][21]; /* [0..9] of string [20] */ -char joyButtonNames[5][21]; /* [1..5] of string [20] */ -char superShips[11][26]; /* [0..10] of string [25] */ -char specialName[9][10]; /* [1..9] of string [9] */ -char destructHelp[25][22]; -char weaponNames[17][17]; /* [1..17] of string [16] */ -char destructModeName[DESTRUCT_MODES][13]; /* [1..destructmodes] of string [12] */ -char shipInfo[13][2][256]; -char menuInt[MAX_MENU + 1][11][18]; /* [0..maxmenu, 1..11] of string [17] */ +char helpTxt[39][231]; /* [1..39] of string [230] */ +char pName[21][16]; /* [1..21] of string [15] */ +char miscText[HELPTEXT_MISCTEXT_COUNT][42]; /* [1..68] of string [41] */ +char miscTextB[HELPTEXT_MISCTEXTB_COUNT][HELPTEXT_MISCTEXTB_SIZE]; /* [1..5] of string [10] */ +char keyName[8][18]; /* [1..8] of string [17] */ +char menuText[7][HELPTEXT_MENUTEXT_SIZE]; /* [1..7] of string [20] */ +char outputs[9][31]; /* [1..9] of string [30] */ +char topicName[6][21]; /* [1..6] of string [20] */ +char mainMenuHelp[HELPTEXT_MAINMENUHELP_COUNT][66]; /* [1..34] of string [65] */ +char inGameText[6][21]; /* [1..6] of string [20] */ +char detailLevel[6][13]; /* [1..6] of string [12] */ +char gameSpeedText[5][13]; /* [1..5] of string [12] */ +char inputDevices[3][13]; /* [1..3] of string [12] */ +char networkText[HELPTEXT_NETWORKTEXT_COUNT][HELPTEXT_NETWORKTEXT_SIZE]; /* [1..4] of string [20] */ +char difficultyNameB[11][21]; /* [0..9] of string [20] */ +char joyButtonNames[5][21]; /* [1..5] of string [20] */ +char superShips[HELPTEXT_SUPERSHIPS_COUNT][26]; /* [0..10] of string [25] */ +char specialName[HELPTEXT_SPECIALNAME_COUNT][10]; /* [1..9] of string [9] */ +char destructHelp[25][22]; /* [1..25] of string [21] */ +char weaponNames[17][17]; /* [1..17] of string [16] */ +char destructModeName[DESTRUCT_MODES][13]; /* [1..destructmodes] of string [12] */ +char shipInfo[HELPTEXT_SHIPINFO_COUNT][2][256]; /* [1..13, 1..2] of string */ +char menuInt[MENU_MAX+1][11][18]; /* [0..14, 1..11] of string [17] */ void decrypt_pascal_string( char *s, int len ) @@ -174,210 +174,217 @@ void JE_HBox( SDL_Surface *screen, int x, int y, unsigned int messagenum, unsig void JE_loadHelpText( void ) { +#ifdef TYRIAN2000 + const unsigned int menuInt_entries[MENU_MAX + 1] = { -1, 7, 9, 9, -1, -1, 11, -1, -1, -1, 7, 4, 6, 7, 5 }; +#else + const unsigned int menuInt_entries[MENU_MAX + 1] = { -1, 7, 9, 8, -1, -1, 11, -1, -1, -1, 6, 4, 6, 7, 5 }; +#endif + FILE *f = dir_fopen_die(data_dir(), "tyrian.hdt", "rb"); efread(&episode1DataLoc, sizeof(JE_longint), 1, f); /*Online Help*/ skip_pascal_string(f); - for (int i = 0; i < MAX_HELP_MESSAGE; ++i) + for (unsigned int i = 0; i < COUNTOF(helpTxt); ++i) read_encrypted_pascal_string(helpTxt[i], sizeof(helpTxt[i]), f); skip_pascal_string(f); /*Planet names*/ skip_pascal_string(f); - for (int i = 0; i < 21; ++i) + for (unsigned int i = 0; i < COUNTOF(pName); ++i) read_encrypted_pascal_string(pName[i], sizeof(pName[i]), f); skip_pascal_string(f); /*Miscellaneous text*/ skip_pascal_string(f); - for (int i = 0; i < 68; ++i) + for (unsigned int i = 0; i < COUNTOF(miscText); ++i) read_encrypted_pascal_string(miscText[i], sizeof(miscText[i]), f); skip_pascal_string(f); /*Little Miscellaneous text*/ skip_pascal_string(f); - for (int i = 0; i < 5; ++i) + for (unsigned int i = 0; i < COUNTOF(miscTextB); ++i) read_encrypted_pascal_string(miscTextB[i], sizeof(miscTextB[i]), f); skip_pascal_string(f); /*Key names*/ skip_pascal_string(f); - for (int i = 0; i < 11; ++i) + for (unsigned int i = 0; i < menuInt_entries[6]; ++i) read_encrypted_pascal_string(menuInt[6][i], sizeof(menuInt[6][i]), f); skip_pascal_string(f); /*Main Menu*/ skip_pascal_string(f); - for (int i = 0; i < 7; ++i) + for (unsigned int i = 0; i < COUNTOF(menuText); ++i) read_encrypted_pascal_string(menuText[i], sizeof(menuText[i]), f); skip_pascal_string(f); /*Event text*/ skip_pascal_string(f); - for (int i = 0; i < 9; ++i) + for (unsigned int i = 0; i < COUNTOF(outputs); ++i) read_encrypted_pascal_string(outputs[i], sizeof(outputs[i]), f); skip_pascal_string(f); /*Help topics*/ skip_pascal_string(f); - for (int i = 0; i < 6; ++i) + for (unsigned int i = 0; i < COUNTOF(topicName); ++i) read_encrypted_pascal_string(topicName[i], sizeof(topicName[i]), f); skip_pascal_string(f); /*Main Menu Help*/ skip_pascal_string(f); - for (int i = 0; i < 34; ++i) + for (unsigned int i = 0; i < COUNTOF(mainMenuHelp); ++i) read_encrypted_pascal_string(mainMenuHelp[i], sizeof(mainMenuHelp[i]), f); skip_pascal_string(f); /*Menu 1 - Main*/ skip_pascal_string(f); - for (int i = 0; i < 7; ++i) + for (unsigned int i = 0; i < menuInt_entries[1]; ++i) read_encrypted_pascal_string(menuInt[1][i], sizeof(menuInt[1][i]), f); skip_pascal_string(f); /*Menu 2 - Items*/ skip_pascal_string(f); - for (int i = 0; i < 9; ++i) + for (unsigned int i = 0; i < menuInt_entries[2]; ++i) read_encrypted_pascal_string(menuInt[2][i], sizeof(menuInt[2][i]), f); skip_pascal_string(f); /*Menu 3 - Options*/ skip_pascal_string(f); - for (int i = 0; i < 8; ++i) + for (unsigned int i = 0; i < menuInt_entries[3]; ++i) read_encrypted_pascal_string(menuInt[3][i], sizeof(menuInt[3][i]), f); skip_pascal_string(f); /*InGame Menu*/ skip_pascal_string(f); - for (int i = 0; i < 6; ++i) + for (unsigned int i = 0; i < COUNTOF(inGameText); ++i) read_encrypted_pascal_string(inGameText[i], sizeof(inGameText[i]), f); skip_pascal_string(f); /*Detail Level*/ skip_pascal_string(f); - for (int i = 0; i < 6; ++i) + for (unsigned int i = 0; i < COUNTOF(detailLevel); ++i) read_encrypted_pascal_string(detailLevel[i], sizeof(detailLevel[i]), f); skip_pascal_string(f); /*Game speed text*/ skip_pascal_string(f); - for (int i = 0; i < 5; ++i) + for (unsigned int i = 0; i < COUNTOF(gameSpeedText); ++i) read_encrypted_pascal_string(gameSpeedText[i], sizeof(gameSpeedText[i]), f); skip_pascal_string(f); // episode names skip_pascal_string(f); - for (int i = 0; i <= 5; ++i) + for (unsigned int i = 0; i < COUNTOF(episode_name); ++i) read_encrypted_pascal_string(episode_name[i], sizeof(episode_name[i]), f); skip_pascal_string(f); // difficulty names skip_pascal_string(f); - for (int i = 0; i <= 6; ++i) + for (unsigned int i = 0; i < COUNTOF(difficulty_name); ++i) read_encrypted_pascal_string(difficulty_name[i], sizeof(difficulty_name[i]), f); skip_pascal_string(f); // gameplay mode names skip_pascal_string(f); - for (int i = 0; i <= 4; ++i) + for (unsigned int i = 0; i < COUNTOF(gameplay_name); ++i) read_encrypted_pascal_string(gameplay_name[i], sizeof(gameplay_name[i]), f); skip_pascal_string(f); /*Menu 10 - 2Player Main*/ skip_pascal_string(f); - for (int i = 0; i < 6; ++i) + for (unsigned int i = 0; i < menuInt_entries[10]; ++i) read_encrypted_pascal_string(menuInt[10][i], sizeof(menuInt[10][i]), f); skip_pascal_string(f); /*Input Devices*/ skip_pascal_string(f); - for (int i = 0; i < 3; ++i) + for (unsigned int i = 0; i < COUNTOF(inputDevices); ++i) read_encrypted_pascal_string(inputDevices[i], sizeof(inputDevices[i]), f); skip_pascal_string(f); /*Network text*/ skip_pascal_string(f); - for (int i = 0; i < 4; ++i) + for (unsigned int i = 0; i < COUNTOF(networkText); ++i) read_encrypted_pascal_string(networkText[i], sizeof(networkText[i]), f); skip_pascal_string(f); /*Menu 11 - 2Player Network*/ skip_pascal_string(f); - for (int i = 0; i < 4; ++i) + for (unsigned int i = 0; i < menuInt_entries[11]; ++i) read_encrypted_pascal_string(menuInt[11][i], sizeof(menuInt[11][i]), f); skip_pascal_string(f); /*HighScore Difficulty Names*/ skip_pascal_string(f); - for (int i = 0; i <= 10; ++i) + for (unsigned int i = 0; i < COUNTOF(difficultyNameB); ++i) read_encrypted_pascal_string(difficultyNameB[i], sizeof(difficultyNameB[i]), f); skip_pascal_string(f); /*Menu 12 - Network Options*/ skip_pascal_string(f); - for (int i = 0; i < 6; ++i) + for (unsigned int i = 0; i < menuInt_entries[12]; ++i) read_encrypted_pascal_string(menuInt[12][i], sizeof(menuInt[12][i]), f); skip_pascal_string(f); /*Menu 13 - Joystick*/ skip_pascal_string(f); - for (int i = 0; i < 7; ++i) + for (unsigned int i = 0; i < menuInt_entries[13]; ++i) read_encrypted_pascal_string(menuInt[13][i], sizeof(menuInt[13][i]), f); skip_pascal_string(f); /*Joystick Button Assignments*/ skip_pascal_string(f); - for (int i = 0; i < 5; ++i) + for (unsigned int i = 0; i < COUNTOF(joyButtonNames); ++i) read_encrypted_pascal_string(joyButtonNames[i], sizeof(joyButtonNames[i]), f); skip_pascal_string(f); /*SuperShips - For Super Arcade Mode*/ skip_pascal_string(f); - for (int i = 0; i <= 10; ++i) + for (unsigned int i = 0; i < COUNTOF(superShips); ++i) read_encrypted_pascal_string(superShips[i], sizeof(superShips[i]), f); skip_pascal_string(f); /*SuperShips - For Super Arcade Mode*/ skip_pascal_string(f); - for (int i = 0; i < 9; ++i) + for (unsigned int i = 0; i < COUNTOF(specialName); ++i) read_encrypted_pascal_string(specialName[i], sizeof(specialName[i]), f); skip_pascal_string(f); /*Secret DESTRUCT game*/ skip_pascal_string(f); - for (int i = 0; i < 25; ++i) + for (unsigned int i = 0; i < COUNTOF(destructHelp); ++i) read_encrypted_pascal_string(destructHelp[i], sizeof(destructHelp[i]), f); skip_pascal_string(f); /*Secret DESTRUCT weapons*/ skip_pascal_string(f); - for (int i = 0; i < 17; ++i) + for (unsigned int i = 0; i < COUNTOF(weaponNames); ++i) read_encrypted_pascal_string(weaponNames[i], sizeof(weaponNames[i]), f); skip_pascal_string(f); /*Secret DESTRUCT modes*/ skip_pascal_string(f); - for (int i = 0; i < DESTRUCT_MODES; ++i) + for (unsigned int i = 0; i < COUNTOF(destructModeName); ++i) read_encrypted_pascal_string(destructModeName[i], sizeof(destructModeName[i]), f); skip_pascal_string(f); /*NEW: Ship Info*/ skip_pascal_string(f); - for (int i = 0; i < 13; ++i) + for (unsigned int i = 0; i < COUNTOF(shipInfo); ++i) { read_encrypted_pascal_string(shipInfo[i][0], sizeof(shipInfo[i][0]), f); read_encrypted_pascal_string(shipInfo[i][1], sizeof(shipInfo[i][1]), f); } skip_pascal_string(f); - + +#ifndef TYRIAN2000 /*Menu 12 - Network Options*/ skip_pascal_string(f); - for (int i = 0; i < 5; ++i) + for (unsigned int i = 0; i < menuInt_entries[14]; ++i) read_encrypted_pascal_string(menuInt[14][i], sizeof(menuInt[14][i]), f); - +#endif + fclose(f); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/helptext.h b/project/jni/application/opentyrian/src/helptext.h index 8da69119b..9b4d88273 100644 --- a/project/jni/application/opentyrian/src/helptext.h +++ b/project/jni/application/opentyrian/src/helptext.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -21,38 +21,66 @@ #include "opentyr.h" +#include -#define MAX_HELP_MESSAGE 39 -#define MAX_MENU 14 +#define MENU_MAX 14 #define DESTRUCT_MODES 5 +extern const JE_byte menuHelp[MENU_MAX][11]; /* [1..14, 1..11] */ + extern JE_byte verticalHeight; extern JE_byte helpBoxColor, helpBoxBrightness, helpBoxShadeType; -extern char helpTxt[MAX_HELP_MESSAGE][231]; -extern char pName[21][16]; /* [1..21] of string [15] */ -extern char miscText[68][42]; /* [1..68] of string [41] */ -extern char miscTextB[5][11]; /* [1..5] of string [10] */ -extern char keyName[8][18]; /* [1..8] of string [17] */ -extern char menuText[7][21]; /* [1..7] of string [20] */ -extern char outputs[9][31]; /* [1..9] of string [30] */ -extern char topicName[6][21]; /* [1..6] of string [20] */ -extern char mainMenuHelp[34][66]; -extern char inGameText[6][21]; /* [1..6] of string [20] */ -extern char detailLevel[6][13]; /* [1..6] of string [12] */ -extern char gameSpeedText[5][13]; /* [1..5] of string [12] */ -extern char inputDevices[3][13]; /* [1..3] of string [12] */ -extern char networkText[4][22]; /* [1..4] of string [20] */ -extern char difficultyNameB[11][21]; /* [0..9] of string [20] */ -extern char joyButtonNames[5][21]; /* [1..5] of string [20] */ -extern char superShips[11][26]; /* [0..10] of string [25] */ -extern char specialName[9][10]; /* [1..9] of string [9] */ + +#ifdef TYRIAN2000 +#define HELPTEXT_MISCTEXT_COUNT 72 +#define HELPTEXT_MISCTEXTB_COUNT 8 +#define HELPTEXT_MISCTEXTB_SIZE 12 +#define HELPTEXT_MENUTEXT_SIZE 29 +#define HELPTEXT_MAINMENUHELP_COUNT 37 +#define HELPTEXT_NETWORKTEXT_COUNT 5 +#define HELPTEXT_NETWORKTEXT_SIZE 33 +#define HELPTEXT_SUPERSHIPS_COUNT 13 +#define HELPTEXT_SPECIALNAME_COUNT 11 +#define HELPTEXT_SHIPINFO_COUNT 20 +#define HELPTEXT_MENUINT3_COUNT 9 +#define HELPTEXT_MENUINT12_COUNT 7 +#else +#define HELPTEXT_MISCTEXT_COUNT 68 +#define HELPTEXT_MISCTEXTB_COUNT 5 +#define HELPTEXT_MISCTEXTB_SIZE 11 +#define HELPTEXT_MENUTEXT_SIZE 21 +#define HELPTEXT_MAINMENUHELP_COUNT 34 +#define HELPTEXT_NETWORKTEXT_COUNT 4 +#define HELPTEXT_NETWORKTEXT_SIZE 22 +#define HELPTEXT_SUPERSHIPS_COUNT 11 +#define HELPTEXT_SPECIALNAME_COUNT 9 +#define HELPTEXT_SHIPINFO_COUNT 13 +#endif + +extern char helpTxt[39][231]; +extern char pName[21][16]; +extern char miscText[HELPTEXT_MISCTEXT_COUNT][42]; +extern char miscTextB[HELPTEXT_MISCTEXTB_COUNT][HELPTEXT_MISCTEXTB_SIZE]; +extern char keyName[8][18]; +extern char menuText[7][HELPTEXT_MENUTEXT_SIZE]; +extern char outputs[9][31]; +extern char topicName[6][21]; +extern char mainMenuHelp[HELPTEXT_MAINMENUHELP_COUNT][66]; +extern char inGameText[6][21]; +extern char detailLevel[6][13]; +extern char gameSpeedText[5][13]; +extern char inputDevices[3][13]; +extern char networkText[HELPTEXT_NETWORKTEXT_COUNT][HELPTEXT_NETWORKTEXT_SIZE]; +extern char difficultyNameB[11][21]; +extern char joyButtonNames[5][21]; +extern char superShips[HELPTEXT_SUPERSHIPS_COUNT][26]; +extern char specialName[HELPTEXT_SPECIALNAME_COUNT][10]; extern char destructHelp[25][22]; -extern char weaponNames[17][17]; /* [1..17] of string [16] */ -extern char destructModeName[DESTRUCT_MODES][13]; /* [1..destructmodes] of string [12] */ -extern char shipInfo[13][2][256]; -extern char menuInt[MAX_MENU+1][11][18]; /* [0..maxmenu, 1..11] of string [17] */ -extern const JE_byte menuHelp[MAX_MENU][11]; /* [1..maxmenu, 1..11] */ +extern char weaponNames[17][17]; +extern char destructModeName[DESTRUCT_MODES][13]; +extern char shipInfo[HELPTEXT_SHIPINFO_COUNT][2][256]; +extern char menuInt[MENU_MAX+1][11][18]; void read_encrypted_pascal_string( char *s, int size, FILE *f ); void skip_pascal_string( FILE *f ); @@ -63,4 +91,3 @@ void JE_loadHelpText( void ); #endif /* HELPTEXT_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/hg_revision.h b/project/jni/application/opentyrian/src/hg_revision.h index b723bbd3a..bfce6b8ea 100644 --- a/project/jni/application/opentyrian/src/hg_revision.h +++ b/project/jni/application/opentyrian/src/hg_revision.h @@ -2,7 +2,7 @@ #define HG_REVISION_H #ifndef HG_REV -#define HG_REV "8e4c1be1b53f default" +#define HG_REV "0a06d5af473c default" #endif #endif // HG_REVISION_H diff --git a/project/jni/application/opentyrian/src/joystick.c b/project/jni/application/opentyrian/src/joystick.c index bc3671b93..d01cb6072 100644 --- a/project/jni/application/opentyrian/src/joystick.c +++ b/project/jni/application/opentyrian/src/joystick.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -28,6 +28,8 @@ #include "video.h" #include +#include +#include int joystick_axis_threshold( int j, int value ); int check_assigned( SDL_Joystick *joystick_handle, const Joystick_assignment assignment[2] ); @@ -656,4 +658,3 @@ bool joystick_assignment_cmp( const Joystick_assignment *a, const Joystick_assig return false; } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/joystick.h b/project/jni/application/opentyrian/src/joystick.h index e3e9bb92e..cf216a987 100644 --- a/project/jni/application/opentyrian/src/joystick.h +++ b/project/jni/application/opentyrian/src/joystick.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -95,4 +95,3 @@ bool joystick_assignment_cmp( const Joystick_assignment *, const Joystick_assign #endif /* JOYSTICK_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/jukebox.c b/project/jni/application/opentyrian/src/jukebox.c index e8add2a08..6df4620f2 100644 --- a/project/jni/application/opentyrian/src/jukebox.c +++ b/project/jni/application/opentyrian/src/jukebox.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -31,6 +31,8 @@ #include "vga_palette.h" #include "video.h" +#include + void jukebox( void ) { bool trigger_quit = false, // true when user wants to quit @@ -217,4 +219,3 @@ void jukebox( void ) set_volume(tyrMusicVolume, fxVolume); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/jukebox.h b/project/jni/application/opentyrian/src/jukebox.h index b858c5326..6dd9a8e08 100644 --- a/project/jni/application/opentyrian/src/jukebox.h +++ b/project/jni/application/opentyrian/src/jukebox.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -25,4 +25,3 @@ void jukebox( void ); #endif /* JUKEBOX_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/keyboard.c b/project/jni/application/opentyrian/src/keyboard.c index 13e27d54b..ee22f1eb3 100644 --- a/project/jni/application/opentyrian/src/keyboard.c +++ b/project/jni/application/opentyrian/src/keyboard.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -25,6 +25,7 @@ #include "video_scale.h" #include "SDL.h" +#include JE_boolean ESCPressed; @@ -38,15 +39,13 @@ Uint16 lastmouse_x, lastmouse_y; JE_boolean mouse_pressed[3] = {false, false, false}; Uint16 mouse_x, mouse_y; -int numkeys; -Uint8 *keysactive; +Uint8 keysactive[SDLK_LAST]; #ifdef NDEBUG -bool input_grab_enabled = true, +bool input_grab_enabled = true; #else -bool input_grab_enabled = false, +bool input_grab_enabled = false; #endif - input_grabbed = false; void flush_events_buffer( void ) @@ -65,8 +64,10 @@ void wait_input( JE_boolean keyboard, JE_boolean mouse, JE_boolean joystick ) push_joysticks_as_keyboard(); service_SDL_events(false); +#ifdef WITH_NETWORK if (isNetworkGame) network_check(); +#endif } } @@ -79,14 +80,15 @@ void wait_noinput( JE_boolean keyboard, JE_boolean mouse, JE_boolean joystick ) poll_joysticks(); service_SDL_events(false); +#ifdef WITH_NETWORK if (isNetworkGame) network_check(); +#endif } } void init_keyboard( void ) { - keysactive = SDL_GetKeyState(&numkeys); #ifndef ANDROID SDL_EnableKeyRepeat(500, 60); #endif @@ -97,17 +99,17 @@ void init_keyboard( void ) SDL_EnableUNICODE(1); } -void input_grab( void ) +void input_grab( bool enable ) { #if defined(TARGET_GP2X) || defined(TARGET_DINGUX) || defined(ANDROID) - input_grabbed = true; -#else - input_grabbed = input_grab_enabled || fullscreen_enabled; + enable = true; #endif - SDL_ShowCursor(input_grabbed ? SDL_DISABLE : SDL_ENABLE); + input_grab_enabled = enable || fullscreen_enabled; + + SDL_ShowCursor(input_grab_enabled ? SDL_DISABLE : SDL_ENABLE); #ifdef NDEBUG - SDL_WM_GrabInput(input_grabbed ? SDL_GRAB_ON : SDL_GRAB_OFF); + SDL_WM_GrabInput(input_grab_enabled ? SDL_GRAB_ON : SDL_GRAB_OFF); #endif } @@ -121,7 +123,7 @@ JE_word JE_mousePosition( JE_word *mouseX, JE_word *mouseY ) void set_mouse_position( int x, int y ) { - if (input_grabbed) + if (input_grab_enabled) { SDL_WarpMouse(x * scalers[scaler].width / vga_width, y * scalers[scaler].height / vga_height); mouse_x = x; @@ -144,6 +146,11 @@ void service_SDL_events( JE_boolean clear_new ) { switch (ev.type) { + case SDL_ACTIVEEVENT: + if (ev.active.state == SDL_APPINPUTFOCUS && !ev.active.gain) + input_grab(false); + break; + case SDL_MOUSEMOTION: mouse_x = ev.motion.x * vga_width / scalers[scaler].width; mouse_y = ev.motion.y * vga_height / scalers[scaler].height; @@ -170,8 +177,7 @@ void service_SDL_events( JE_boolean clear_new ) /* toggle input grab */ if (ev.key.keysym.sym == SDLK_F10) { - input_grab_enabled = !input_grab_enabled; - input_grab(); + input_grab(!input_grab_enabled); break; } } @@ -193,18 +199,19 @@ void service_SDL_events( JE_boolean clear_new ) /* disable input grab and fullscreen */ if (ev.key.keysym.sym == SDLK_TAB) { - input_grab_enabled = false; - input_grab(); - if (!init_scaler(scaler, false) && // try windowed !init_any_scaler(false) && // try any scaler windowed !init_scaler(scaler, fullscreen_enabled)) // revert on fail { exit(EXIT_FAILURE); } + + input_grab(false); break; } } + + keysactive[ev.key.keysym.sym] = 1; newkey = true; lastkey_sym = ev.key.keysym.sym; @@ -213,15 +220,16 @@ void service_SDL_events( JE_boolean clear_new ) keydown = true; return; case SDL_KEYUP: + keysactive[ev.key.keysym.sym] = 0; keydown = false; return; case SDL_MOUSEBUTTONDOWN: - if (!input_grabbed) + if (!input_grab_enabled) { - input_grab_enabled = !input_grab_enabled; - input_grab(); + input_grab(true); break; } + // intentional fall-though case SDL_MOUSEBUTTONUP: if (ev.type == SDL_MOUSEBUTTONDOWN) { @@ -258,4 +266,3 @@ void JE_clearKeyboard( void ) // /!\ Doesn't seems important. I think. D: } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/keyboard.h b/project/jni/application/opentyrian/src/keyboard.h index 74e4e44d7..6c07e29d0 100644 --- a/project/jni/application/opentyrian/src/keyboard.h +++ b/project/jni/application/opentyrian/src/keyboard.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -35,16 +35,15 @@ extern Uint8 lastmouse_but; extern Uint16 lastmouse_x, lastmouse_y; extern JE_boolean mouse_pressed[3]; extern Uint16 mouse_x, mouse_y; -extern int numkeys; -extern Uint8 *keysactive; +extern Uint8 keysactive[SDLK_LAST]; -extern bool input_grab_enabled, input_grabbed; +extern bool input_grab_enabled; void flush_events_buffer( void ); void wait_input( JE_boolean keyboard, JE_boolean mouse, JE_boolean joystick ); void wait_noinput( JE_boolean keyboard, JE_boolean mouse, JE_boolean joystick ); void init_keyboard( void ); -void input_grab( void ); +void input_grab( bool enable ); JE_word JE_mousePosition( JE_word *mouseX, JE_word *mouseY ); void set_mouse_position( int x, int y ); @@ -66,4 +65,3 @@ void JE_clearKeyboard( void ); #endif /* KEYBOARD_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/lds_play.c b/project/jni/application/opentyrian/src/lds_play.c index 38af271f8..652382ed1 100644 --- a/project/jni/application/opentyrian/src/lds_play.c +++ b/project/jni/application/opentyrian/src/lds_play.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -17,13 +17,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "file.h" -#include "fm_synth.h" #include "lds_play.h" #include "loudness.h" #include "opentyr.h" #include +const unsigned char op_table[9] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12}; + /* A substantial amount of this code has been copied and adapted from adplug. Thanks, guys! Adplug is awesome! :D */ @@ -207,7 +208,7 @@ void lds_rewind( void ) memset(fmchip, 0, sizeof(fmchip)); /* OPL2 init */ - opl_reset(); /* Reset OPL chip */ + opl_init(); /* Reset OPL chip */ opl_write(1, 0x20); opl_write(8, 0); opl_write(0xbd, regbd); @@ -765,4 +766,3 @@ void lds_playsound(int inst_number, int channel_number, int tunehigh) c->nextvol = c->glideto = c->finetune = c->vibcount = c->arp_pos = c->arp_count = 0; } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/lds_play.h b/project/jni/application/opentyrian/src/lds_play.h index e8239c989..b7fbe1cb6 100644 --- a/project/jni/application/opentyrian/src/lds_play.h +++ b/project/jni/application/opentyrian/src/lds_play.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -21,6 +21,8 @@ #include "opentyr.h" +#include + extern bool playing, songlooped; int lds_update( void ); @@ -70,4 +72,3 @@ void lds_setregs_adv(unsigned char reg, unsigned char mask, unsigned char val); #endif /* LDS_PLAY_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/loudness.c b/project/jni/application/opentyrian/src/loudness.c index bcfcf2bcc..49c24dbab 100644 --- a/project/jni/application/opentyrian/src/loudness.c +++ b/project/jni/application/opentyrian/src/loudness.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -17,7 +17,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "file.h" -#include "fm_synth.h" #include "lds_play.h" #include "loudness.h" #include "nortsong.h" @@ -61,7 +60,7 @@ bool init_audio( void ) ask.freq = freq; ask.format = (BYTES_PER_SAMPLE == 2) ? AUDIO_S16SYS : AUDIO_S8; ask.channels = 1; - ask.samples = 512; + ask.samples = 2048; ask.callback = audio_cb; printf("\trequested %d Hz, %d channels, %d samples\n", ask.freq, ask.channels, ask.samples); @@ -186,8 +185,6 @@ void deinit_audio( void ) channel_len[i] = 0; } - opl_deinit(); - lds_free(); } @@ -200,7 +197,7 @@ void load_music( void ) efread(&song_count, sizeof(song_count), 1, music_file); - song_offset = malloc((song_count + 1) * sizeof(song_offset)); + song_offset = malloc((song_count + 1) * sizeof(*song_offset)); efread(song_offset, 4, song_count, music_file); song_offset[song_count] = ftell_eof(music_file); @@ -252,7 +249,7 @@ void stop_song( void ) void fade_song( void ) { - printf("TODO: %s\n", __FUNCTION__); + /* STUB: we have no implementation of this to port */ } void set_volume( unsigned int music, unsigned int sample ) @@ -290,4 +287,3 @@ void JE_multiSamplePlay(JE_byte *buffer, JE_word size, JE_byte chan, JE_byte vol SDL_UnlockAudio(); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/loudness.h b/project/jni/application/opentyrian/src/loudness.h index f3a5c9317..f51a459ff 100644 --- a/project/jni/application/opentyrian/src/loudness.h +++ b/project/jni/application/opentyrian/src/loudness.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -19,8 +19,8 @@ #ifndef LOUDNESS_H #define LOUDNESS_H -#include "fmopl.h" #include "opentyr.h" +#include "opl.h" #include "SDL.h" @@ -33,8 +33,8 @@ #endif #define SAMPLE_SCALING OUTPUT_QUALITY -#define SAMPLE_TYPE OPLSAMPLE -#define BYTES_PER_SAMPLE (OPL_SAMPLE_BITS / 8) +#define SAMPLE_TYPE Bit16s +#define BYTES_PER_SAMPLE 2 extern float music_volume, sample_volume; @@ -57,4 +57,3 @@ void JE_multiSamplePlay(JE_byte *buffer, JE_word size, JE_byte chan, JE_byte vol #endif /* LOUDNESS_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/lvllib.c b/project/jni/application/opentyrian/src/lvllib.c index 06c780fe8..a09c0405c 100644 --- a/project/jni/application/opentyrian/src/lvllib.c +++ b/project/jni/application/opentyrian/src/lvllib.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -39,4 +39,3 @@ void JE_analyzeLevel( void ) fclose(f); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/lvllib.h b/project/jni/application/opentyrian/src/lvllib.h index d6e3a7a62..f22e3f5fd 100644 --- a/project/jni/application/opentyrian/src/lvllib.h +++ b/project/jni/application/opentyrian/src/lvllib.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -32,4 +32,3 @@ void JE_analyzeLevel( void ); #endif /* LVLLIB_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/lvlmast.c b/project/jni/application/opentyrian/src/lvlmast.c index 57ef4a469..074f0b11d 100644 --- a/project/jni/application/opentyrian/src/lvlmast.c +++ b/project/jni/application/opentyrian/src/lvlmast.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -171,4 +171,3 @@ TYPE 5: Shape Files M 1 2 3 4 episode */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/lvlmast.h b/project/jni/application/opentyrian/src/lvlmast.h index 1b0ef814b..764a7673f 100644 --- a/project/jni/application/opentyrian/src/lvlmast.h +++ b/project/jni/application/opentyrian/src/lvlmast.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -21,9 +21,19 @@ #include "opentyr.h" - #define EVENT_MAXIMUM 2500 +#ifdef TYRIAN2000 +#define WEAP_NUM 818 +#define PORT_NUM 60 +#define ARMOR_NUM 4 +#define POWER_NUM 6 +#define ENGINE_NUM 6 +#define OPTION_NUM 37 +#define SHIP_NUM 18 +#define SHIELD_NUM 11 +#define SPECIAL_NUM 46 +#else #define WEAP_NUM 780 #define PORT_NUM 42 #define ARMOR_NUM 4 @@ -33,6 +43,7 @@ #define SHIP_NUM 13 #define SHIELD_NUM 10 #define SPECIAL_NUM 46 +#endif #define ENEMY_NUM 850 @@ -46,4 +57,3 @@ extern const JE_char shapeFile[34]; /* [1..34] */ #endif /* LVLMAST_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/main.m b/project/jni/application/opentyrian/src/main.m index c931961df..95e9ce445 100644 --- a/project/jni/application/opentyrian/src/main.m +++ b/project/jni/application/opentyrian/src/main.m @@ -1,6 +1,5 @@ -/* vim: set noet: - * - * OpenTyrian Classic: A modern cross-platform port of Tyrian +/* + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2008 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or diff --git a/project/jni/application/opentyrian/src/mainint.c b/project/jni/application/opentyrian/src/mainint.c index 203b2001c..fec6b5a11 100644 --- a/project/jni/application/opentyrian/src/mainint.c +++ b/project/jni/application/opentyrian/src/mainint.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -42,6 +42,7 @@ #include "picload.h" #include "player.h" #include "setup.h" +#include "shots.h" #include "sndmast.h" #include "sprite.h" #include "varz.h" @@ -52,6 +53,7 @@ #include #include +#include bool button[4]; @@ -745,7 +747,7 @@ void JE_nextEpisode( void ) { strcpy(lastLevelName, "Completed"); - if (episodeNum == initial_episode_num && !gameHasRepeated && episodeNum != 4 && + if (episodeNum == initial_episode_num && !gameHasRepeated && episodeNum != EPISODE_AVAILABLE && !isNetworkGame && !constantPlay) { JE_highScoreCheck(); @@ -771,14 +773,14 @@ void JE_nextEpisode( void ) // randomly give player the SuperCarrot if ((mt_rand() % 6) == 0) { - player[0].items.ship = 2; - player[0].items.weapon[FRONT_WEAPON].id = 23; - player[0].items.weapon[REAR_WEAPON].id = 24; + player[0].items.ship = 2; // SuperCarrot + player[0].items.weapon[FRONT_WEAPON].id = 23; // Banana Blast + player[0].items.weapon[REAR_WEAPON].id = 24; // Banana Blast Rear for (uint i = 0; i < COUNTOF(player[0].items.weapon); ++i) player[0].items.weapon[i].power = 1; - player[1].items.weapon[REAR_WEAPON].id = 24; + player[1].items.weapon[REAR_WEAPON].id = 24; // Banana Blast Rear player[0].last_items = player[0].items; } @@ -917,14 +919,14 @@ void JE_highScoreScreen( void ) for (z = 0; z < 3; z++) { - temp5 = saveFiles[temp + z].highScoreDiff; - if (temp5 > 9) + int difficulty = saveFiles[temp + z].highScoreDiff; + if (difficulty > 9) { saveFiles[temp + z].highScoreDiff = 0; - temp5 = 0; + difficulty = 0; } sprintf(scoretemp, "~#%d:~ %d", z + 1, saveFiles[temp+z].highScore1); - JE_textShade(VGAScreen, 250, ((z+1) * 10) + 65 , difficultyNameB[temp5], 15, temp5 + ((JE_byte) (temp5 == 0)) - 1, FULL_SHADE); + JE_textShade(VGAScreen, 250, ((z+1) * 10) + 65 , difficultyNameB[difficulty], 15, difficulty + (difficulty == 0 ? 0 : -1), FULL_SHADE); JE_textShade(VGAScreen, 20, ((z+1) * 10) + 65 , scoretemp, 15, 0, FULL_SHADE); JE_textShade(VGAScreen, 110, ((z+1) * 10) + 65 , saveFiles[temp + z].highScoreName, 15, 2, FULL_SHADE); } @@ -939,14 +941,14 @@ void JE_highScoreScreen( void ) for (z = 0; z < 3; z++) { - temp5 = saveFiles[temp + z].highScoreDiff; - if (temp5 > 9) + int difficulty = saveFiles[temp + z].highScoreDiff; + if (difficulty > 9) { saveFiles[temp + z].highScoreDiff = 0; - temp5 = 0; + difficulty = 0; } sprintf(scoretemp, "~#%d:~ %d", z + 1, saveFiles[temp+z].highScore1); /* Not .highScore2 for some reason */ - JE_textShade(VGAScreen, 250, ((z+1) * 10) + 125 , difficultyNameB[temp5], 15, temp5 + ((JE_byte) (temp5 == 0)) - 1, FULL_SHADE); + JE_textShade(VGAScreen, 250, ((z+1) * 10) + 125 , difficultyNameB[difficulty], 15, difficulty + (difficulty == 0 ? 0 : -1), FULL_SHADE); JE_textShade(VGAScreen, 20, ((z+1) * 10) + 125 , scoretemp, 15, 0, FULL_SHADE); JE_textShade(VGAScreen, 110, ((z+1) * 10) + 125 , saveFiles[temp + z].highScoreName, 15, 2, FULL_SHADE); } @@ -1054,6 +1056,7 @@ void JE_doInGameSetup( void ) { haltGame = false; +#ifdef WITH_NETWORK if (isNetworkGame) { network_prepare(PACKET_GAME_MENU); @@ -1075,6 +1078,7 @@ void JE_doInGameSetup( void ) SDL_Delay(16); } } +#endif if (yourInGameMenuRequest) { @@ -1087,6 +1091,7 @@ void JE_doInGameSetup( void ) keysactive[SDLK_ESCAPE] = false; +#ifdef WITH_NETWORK if (isNetworkGame) { if (!playerEndLevel) @@ -1098,8 +1103,10 @@ void JE_doInGameSetup( void ) network_send(4); // PACKET_GAMEQUIT } } +#endif } +#ifdef WITH_NETWORK if (isNetworkGame) { SDL_Surface *temp_surface = VGAScreen; @@ -1157,6 +1164,7 @@ void JE_doInGameSetup( void ) VGAScreen = temp_surface; /* side-effect of game_screen */ } +#endif yourInGameMenuRequest = false; @@ -1165,9 +1173,9 @@ void JE_doInGameSetup( void ) JE_boolean JE_inGameSetup( void ) { - const JE_byte menu_top = 20, menu_spacing = 20; - const JE_shortint menu_items = 6; - JE_shortint sel = 1; + const int menu_top = 20, menu_spacing = 20; + const int menu_items = 6; + int sel = 1; SDL_Surface *temp_surface = VGAScreen; VGAScreen = VGAScreenSeg; /* side-effect of game_screen */ @@ -1196,8 +1204,7 @@ JE_boolean JE_inGameSetup( void ) JE_outTextAdjust(VGAScreen, 10, menu_top + x*menu_spacing, inGameText[x], 15, ((sel == x+1) << 1) - 4, SMALL_FONT_SHAPES, true); } - JE_outTextAdjust(VGAScreen, 120, 3 * 20, detailLevel[processorType-1], 15, ((sel == 3) << 1) - 4, SMALL_FONT_SHAPES, true); - JE_outTextAdjust(VGAScreen, 120, 4 * 20, gameSpeedText[gameSpeed-1], 15, ((sel == 4) << 1) - 4, SMALL_FONT_SHAPES, true); + JE_outTextAdjust(VGAScreen, 120, 3 * 20, detailLevel[processorType-1], 15, ((sel == 3) << 1) - 4, SMALL_FONT_SHAPES, true); JE_outTextAdjust(VGAScreen, 120, 4 * 20, gameSpeedText[gameSpeed-1], 15, ((sel == 4) << 1) - 4, SMALL_FONT_SHAPES, true); JE_outTextAdjust(VGAScreen, 10, 147, mainMenuHelp[help[sel-1]-1], 14, 6, TINY_FONT, true); @@ -1244,7 +1251,11 @@ JE_boolean JE_inGameSetup( void ) switch (sel) { case 1: + music_disabled = !music_disabled; + break; case 2: + samples_disabled = !samples_disabled; + break; case 3: case 4: sel = 5; @@ -2102,8 +2113,8 @@ void JE_playCredits( void ) shipx = 900; shipxwait = 1; } - tempI = shipxc * shipxc; - if (450 + tempI < 0 || 450 + tempI > 900) + int tmp_unknown = shipxc * shipxc; + if (450 + tmp_unknown < 0 || 450 + tmp_unknown > 900) { if (shipxca < 0 && shipxc < 0) shipxwait = 1; @@ -2536,7 +2547,7 @@ void JE_inGameDisplays( void ) /*Special Weapon?*/ if (player[0].items.special > 0) - blit_sprite2x2(VGAScreen, 25, 1, eShapes6, special[player[0].items.special].itemgraphic); + blit_sprite2x2(VGAScreen, 25, 1, eShapes[5], special[player[0].items.special].itemgraphic); /*Lives Left*/ if (onePlayerAction || twoPlayerMode) @@ -2545,21 +2556,21 @@ void JE_inGameDisplays( void ) { const uint extra_lives = *player[temp].lives - 1; - temp5 = (temp == 0 && player[0].items.special > 0) ? 35 : 15; + int y = (temp == 0 && player[0].items.special > 0) ? 35 : 15; tempW = (temp == 0) ? 30: 270; if (extra_lives >= 5) { - blit_sprite2(VGAScreen, tempW, temp5, shapes9, 285); + blit_sprite2(VGAScreen, tempW, y, shapes9, 285); tempW = (temp == 0) ? 45 : 250; sprintf(tempstr, "%d", extra_lives); - JE_textShade(VGAScreen, tempW, temp5 + 3, tempstr, 15, 1, FULL_SHADE); + JE_textShade(VGAScreen, tempW, y + 3, tempstr, 15, 1, FULL_SHADE); } else if (extra_lives >= 1) { for (uint i = 0; i < extra_lives; ++i) { - blit_sprite2(VGAScreen, tempW, temp5, shapes9, 285); + blit_sprite2(VGAScreen, tempW, y, shapes9, 285); tempW += (temp == 0) ? 12 : -12; } @@ -2572,7 +2583,7 @@ void JE_inGameDisplays( void ) } tempW = (temp == 0) ? 28 : (285 - JE_textWidth(stemp, TINY_FONT)); - JE_textShade(VGAScreen, tempW, temp5 - 7, stemp, 2, 6, FULL_SHADE); + JE_textShade(VGAScreen, tempW, y - 7, stemp, 2, 6, FULL_SHADE); } } @@ -2708,10 +2719,13 @@ void JE_mainKeyboardInput( void ) if (isNetworkGame) { nortShipRequest = true; - } else { - player[0].items.ship = 12; - player[0].items.special = 13; - player[0].items.weapon[REAR_WEAPON].id = 36; + } + else + { + player[0].items.ship = 12; // Nort Ship + player[0].items.special = 13; // Astral Zone + player[0].items.weapon[FRONT_WEAPON].id = 36; // NortShip Super Pulse + player[0].items.weapon[REAR_WEAPON].id = 37; // NortShip Spreader shipGr = 1; } } @@ -2725,7 +2739,7 @@ void JE_mainKeyboardInput( void ) keysactive[SDLK_F2] = false; } - if (keysactive[SDLK_F2] && keysactive[SDLK_F3] && (keysactive[SDLK_F4] || keysactive[SDLK_F5]) && !superTyrian) + if (keysactive[SDLK_F2] && keysactive[SDLK_F3] && (keysactive[SDLK_F4] || keysactive[SDLK_F5])) { for (uint i = 0; i < COUNTOF(player); ++i) player[i].armor = 0; @@ -2734,7 +2748,7 @@ void JE_mainKeyboardInput( void ) JE_drawTextWindow(miscText[63-1]); } - if (constantPlay && keysactive[SDLK_c] && !superTyrian && superArcadeMode == SA_NONE) + if (constantPlay && keysactive[SDLK_c]) { youAreCheating = !youAreCheating; keysactive[SDLK_c] = false; @@ -2782,28 +2796,6 @@ void JE_mainKeyboardInput( void ) /* in-game setup */ ingamemenu_pressed = ingamemenu_pressed || keysactive[SDLK_ESCAPE]; - /* {MUTE SOUND} */ - if (keysactive[SDLK_s]) - { - keysactive[SDLK_s] = false; - - samples_disabled = !samples_disabled; - - JE_drawTextWindow(samples_disabled ? miscText[17] : miscText[18]); - } - - /* {MUTE MUSIC} */ - if (keysactive[SDLK_m]) - { - keysactive[SDLK_m] = false; - - music_disabled = !music_disabled; - if (!music_disabled) - restart_song(); - - JE_drawTextWindow(music_disabled ? miscText[35] : miscText[36]); - } - if (keysactive[SDLK_BACKSPACE]) { /* toggle screenshot pause */ @@ -2886,6 +2878,7 @@ void JE_pauseGame( void ) JE_showVGA(); } +#ifdef WITH_NETWORK if (isNetworkGame) { network_prepare(PACKET_GAME_PAUSE); @@ -2907,6 +2900,7 @@ void JE_pauseGame( void ) SDL_Delay(16); } } +#endif wait_noinput(false, false, true); // TODO: should up the joystick repeat temporarily instead @@ -2921,14 +2915,17 @@ void JE_pauseGame( void ) if ((newkey && lastkey_sym != SDLK_LCTRL && lastkey_sym != SDLK_RCTRL && lastkey_sym != SDLK_LALT && lastkey_sym != SDLK_RALT) || JE_mousePosition(&mouseX, &mouseY) > 0) { +#ifdef WITH_NETWORK if (isNetworkGame) { network_prepare(PACKET_WAITING); network_send(4); // PACKET_WAITING } +#endif done = true; } +#ifdef WITH_NETWORK if (isNetworkGame) { network_check(); @@ -2941,11 +2938,13 @@ void JE_pauseGame( void ) } } else +#endif SDL_Delay(300); wait_delay(); } while (!done); +#ifdef WITH_NETWORK if (isNetworkGame) { while (!network_is_sync()) @@ -2956,6 +2955,7 @@ void JE_pauseGame( void ) SDL_Delay(16); } } +#endif #ifdef ANDROID music_disabled = saved_music_disabled; @@ -2987,11 +2987,13 @@ void JE_playerMovement( Player *this_player, this_player->weapon_mode = 1; } +#ifdef WITH_NETWORK if (isNetworkGame && thisPlayerNum == playerNum_) { network_state_prepare(); memset(&packet_state_out[0]->data[4], 0, 10); } +#endif redo: @@ -3027,10 +3029,10 @@ redo: else soundQueue[5] = S_EXPLOSION_11; } - tempW = this_player->x + (mt_rand() % 32) - 16; - tempW2 = this_player->y + (mt_rand() % 32) - 16; - JE_setupExplosionLarge(false, 0, this_player->x + (mt_rand() % 32) - 16, this_player->y + (mt_rand() % 32) - 16 + 7); + int explosion_x = this_player->x + (mt_rand() % 32) - 16; + int explosion_y = this_player->y + (mt_rand() % 32) - 16; + JE_setupExplosionLarge(false, 0, explosion_x, explosion_y + 7); JE_setupExplosionLarge(false, 0, this_player->x, this_player->y + 7); if (levelEnd > 0) @@ -3169,8 +3171,8 @@ redo: } else { - this_player->x += joystick[j].direction[3] ? -CURRENT_KEY_SPEED : 0 + joystick[j].direction[1] ? CURRENT_KEY_SPEED : 0; - this_player->y += joystick[j].direction[0] ? -CURRENT_KEY_SPEED : 0 + joystick[j].direction[2] ? CURRENT_KEY_SPEED : 0; + this_player->x += (joystick[j].direction[3] ? -CURRENT_KEY_SPEED : 0) + (joystick[j].direction[1] ? CURRENT_KEY_SPEED : 0); + this_player->y += (joystick[j].direction[0] ? -CURRENT_KEY_SPEED : 0) + (joystick[j].direction[2] ? CURRENT_KEY_SPEED : 0); } button[0] |= joystick[j].action[0]; @@ -3193,7 +3195,7 @@ redo: button[1] |= mouse_pressed[1]; button[2] |= mouse_has_three_buttons ? mouse_pressed[2] : mouse_pressed[1]; - if (input_grabbed) + if (input_grab_enabled) { mouseXC += mouse_x - 159; mouseYC += mouse_y - 100; @@ -3341,6 +3343,7 @@ redo: } /*endLevel*/ +#ifdef WITH_NETWORK if (isNetworkGame && playerNum_ == thisPlayerNum) { Uint16 buttons = 0; @@ -3367,12 +3370,14 @@ redo: accelXC = 0; accelYC = 0; } +#endif } /*isNetworkGame*/ /* --- Movement Routine Ending --- */ moveOk = true; +#ifdef WITH_NETWORK if (isNetworkGame && !network_state_is_reset()) { if (playerNum_ != thisPlayerNum) @@ -3407,6 +3412,7 @@ redo: accelYC = (Sint16)SDLNet_Read16(&packet_state_out[network_delay]->data[10]); } } +#endif /*Street-Fighter codes*/ JE_SFCodes(playerNum_, this_player->x, this_player->y, *mouseX_, *mouseY_); @@ -3484,37 +3490,38 @@ redo: if (this_player->y < -200) reallyEndLevel = true; - tempI = 1; - tempW2 = this_player->y; - tempI2 = abs(41 - levelEnd); - if (tempI2 > 20) - tempI2 = 20; + int trail_spacing = 1; + int trail_y = this_player->y; + int num_trails = abs(41 - levelEnd); + if (num_trails > 20) + num_trails = 20; - for (int z = 1; z <= tempI2; z++) + for (int i = 0; i < num_trails; i++) { - tempW2 += tempI; - tempI++; + trail_y += trail_spacing; + trail_spacing++; } - for (int z = 1; z <= tempI2; z++) + for (int i = 1; i < num_trails; i++) { - tempW2 -= tempI; - tempI--; - if (tempW2 > 0 && tempW2 < 170) + trail_y -= trail_spacing; + trail_spacing--; + + if (trail_y > 0 && trail_y < 170) { if (shipGr_ == 0) { - blit_sprite2x2(VGAScreen, this_player->x - 17, tempW2 - 7, *shapes9ptr_, 13); - blit_sprite2x2(VGAScreen, this_player->x + 7 , tempW2 - 7, *shapes9ptr_, 51); + blit_sprite2x2(VGAScreen, this_player->x - 17, trail_y - 7, *shapes9ptr_, 13); + blit_sprite2x2(VGAScreen, this_player->x + 7 , trail_y - 7, *shapes9ptr_, 51); } else if (shipGr_ == 1) { - blit_sprite2x2(VGAScreen, this_player->x - 17, tempW2 - 7, *shapes9ptr_, 220); - blit_sprite2x2(VGAScreen, this_player->x + 7 , tempW2 - 7, *shapes9ptr_, 222); + blit_sprite2x2(VGAScreen, this_player->x - 17, trail_y - 7, *shapes9ptr_, 220); + blit_sprite2x2(VGAScreen, this_player->x + 7 , trail_y - 7, *shapes9ptr_, 222); } else { - blit_sprite2x2(VGAScreen, this_player->x - 5, tempW2 - 7, *shapes9ptr_, shipGr_); + blit_sprite2x2(VGAScreen, this_player->x - 5, trail_y - 7, *shapes9ptr_, shipGr_); } } } @@ -3605,11 +3612,11 @@ redo: // turret direction marker/shield shotMultiPos[SHOT_MISC] = 0; - JE_initPlayerShot(0, SHOT_MISC, this_player->x + 1 + roundf(sinf(linkGunDirec + 0.2f) * 26), this_player->y + roundf(cosf(linkGunDirec + 0.2f) * 26), *mouseX_, *mouseY_, 148, playerNum_); + b = player_shot_create(0, SHOT_MISC, this_player->x + 1 + roundf(sinf(linkGunDirec + 0.2f) * 26), this_player->y + roundf(cosf(linkGunDirec + 0.2f) * 26), *mouseX_, *mouseY_, 148, playerNum_); shotMultiPos[SHOT_MISC] = 0; - JE_initPlayerShot(0, SHOT_MISC, this_player->x + 1 + roundf(sinf(linkGunDirec - 0.2f) * 26), this_player->y + roundf(cosf(linkGunDirec - 0.2f) * 26), *mouseX_, *mouseY_, 148, playerNum_); + b = player_shot_create(0, SHOT_MISC, this_player->x + 1 + roundf(sinf(linkGunDirec - 0.2f) * 26), this_player->y + roundf(cosf(linkGunDirec - 0.2f) * 26), *mouseX_, *mouseY_, 148, playerNum_); shotMultiPos[SHOT_MISC] = 0; - JE_initPlayerShot(0, SHOT_MISC, this_player->x + 1 + roundf(sinf(linkGunDirec) * 26), this_player->y + roundf(cosf(linkGunDirec) * 26), *mouseX_, *mouseY_, 147, playerNum_); + b = player_shot_create(0, SHOT_MISC, this_player->x + 1 + roundf(sinf(linkGunDirec) * 26), this_player->y + roundf(cosf(linkGunDirec) * 26), *mouseX_, *mouseY_, 147, playerNum_); if (shotRepeat[SHOT_REAR] > 0) { @@ -3618,38 +3625,8 @@ redo: else if (button[1-1]) { shotMultiPos[SHOT_REAR] = 0; - JE_initPlayerShot(0, SHOT_REAR, this_player->x + 1 + roundf(sinf(linkGunDirec) * 20), this_player->y + roundf(cosf(linkGunDirec) * 20), *mouseX_, *mouseY_, linkGunWeapons[this_player->items.weapon[REAR_WEAPON].id-1], playerNum_); - playerShotData[b].shotXM = -roundf(sinf(linkGunDirec) * playerShotData[b].shotYM); - playerShotData[b].shotYM = -roundf(cosf(linkGunDirec) * playerShotData[b].shotYM); - - switch (this_player->items.weapon[REAR_WEAPON].id) - { - case 27: - case 32: - case 10: - temp = roundf(linkGunDirec * (16 / (2 * M_PI))); /*16 directions*/ - playerShotData[b].shotGr = linkMultiGr[temp]; - break; - case 28: - case 33: - case 11: - temp = roundf(linkGunDirec * (16 / (2 * M_PI))); /*16 directions*/ - playerShotData[b].shotGr = linkSonicGr[temp]; - break; - case 30: - case 35: - case 14: - if (linkGunDirec > M_PI_2 && linkGunDirec < M_PI + M_PI_2) - { - playerShotData[b].shotYC = 1; - } - break; - case 38: - case 22: - temp = roundf(linkGunDirec * (16 / (2 * M_PI))); /*16 directions*/ - playerShotData[b].shotGr = linkMult2Gr[temp]; - break; - } + b = player_shot_create(0, SHOT_REAR, this_player->x + 1 + roundf(sinf(linkGunDirec) * 20), this_player->y + roundf(cosf(linkGunDirec) * 20), *mouseX_, *mouseY_, linkGunWeapons[this_player->items.weapon[REAR_WEAPON].id-1], playerNum_); + player_shot_set_direction(b, this_player->items.weapon[REAR_WEAPON].id, linkGunDirec); } } } @@ -3681,15 +3658,11 @@ redo: if (this_player->y < 10) this_player->y = 10; - tempI2 = this_player->x_velocity / 2; - tempI2 += (this_player->x - *mouseX_) / 6; + // Determines the ship banking sprite to display, depending on horizontal velocity and acceleration + int ship_banking = this_player->x_velocity / 2 + (this_player->x - *mouseX_) / 6; + ship_banking = MAX(-2, MIN(ship_banking, 2)); - if (tempI2 < -2) - tempI2 = -2; - else if (tempI2 > 2) - tempI2 = 2; - - tempI = tempI2 * 2 + shipGr_; + int ship_sprite = ship_banking * 2 + shipGr_; explosionFollowAmountX = this_player->x - this_player->last_x_explosion_follow; explosionFollowAmountY = this_player->y - this_player->last_y_explosion_follow; @@ -3704,12 +3677,12 @@ redo: { if (background2) { - blit_sprite2x2_darken(VGAScreen, this_player->x - 17 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, tempI + 13); - blit_sprite2x2_darken(VGAScreen, this_player->x + 7 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, tempI + 51); + blit_sprite2x2_darken(VGAScreen, this_player->x - 17 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, ship_sprite + 13); + blit_sprite2x2_darken(VGAScreen, this_player->x + 7 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, ship_sprite + 51); if (superWild) { - blit_sprite2x2_darken(VGAScreen, this_player->x - 16 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, tempI + 13); - blit_sprite2x2_darken(VGAScreen, this_player->x + 6 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, tempI + 51); + blit_sprite2x2_darken(VGAScreen, this_player->x - 16 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, ship_sprite + 13); + blit_sprite2x2_darken(VGAScreen, this_player->x + 6 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, ship_sprite + 51); } } } @@ -3725,10 +3698,10 @@ redo: { if (background2) { - blit_sprite2x2_darken(VGAScreen, this_player->x - 5 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, tempI); + blit_sprite2x2_darken(VGAScreen, this_player->x - 5 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, ship_sprite); if (superWild) { - blit_sprite2x2_darken(VGAScreen, this_player->x - 4 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, tempI); + blit_sprite2x2_darken(VGAScreen, this_player->x - 4 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, ship_sprite); } } } @@ -3739,8 +3712,8 @@ redo: if (shipGr_ == 0) { - blit_sprite2x2_blend(VGAScreen, this_player->x - 17, this_player->y - 7, *shapes9ptr_, tempI + 13); - blit_sprite2x2_blend(VGAScreen, this_player->x + 7 , this_player->y - 7, *shapes9ptr_, tempI + 51); + blit_sprite2x2_blend(VGAScreen, this_player->x - 17, this_player->y - 7, *shapes9ptr_, ship_sprite + 13); + blit_sprite2x2_blend(VGAScreen, this_player->x + 7 , this_player->y - 7, *shapes9ptr_, ship_sprite + 51); } else if (shipGr_ == 1) { @@ -3748,46 +3721,48 @@ redo: blit_sprite2x2_blend(VGAScreen, this_player->x + 7 , this_player->y - 7, *shapes9ptr_, 222); } else - blit_sprite2x2_blend(VGAScreen, this_player->x - 5, this_player->y - 7, *shapes9ptr_, tempI); + blit_sprite2x2_blend(VGAScreen, this_player->x - 5, this_player->y - 7, *shapes9ptr_, ship_sprite); } else { if (shipGr_ == 0) { - blit_sprite2x2(VGAScreen, this_player->x - 17, this_player->y - 7, *shapes9ptr_, tempI + 13); - blit_sprite2x2(VGAScreen, this_player->x + 7, this_player->y - 7, *shapes9ptr_, tempI + 51); + blit_sprite2x2(VGAScreen, this_player->x - 17, this_player->y - 7, *shapes9ptr_, ship_sprite + 13); + blit_sprite2x2(VGAScreen, this_player->x + 7, this_player->y - 7, *shapes9ptr_, ship_sprite + 51); } else if (shipGr_ == 1) { blit_sprite2x2(VGAScreen, this_player->x - 17, this_player->y - 7, *shapes9ptr_, 220); blit_sprite2x2(VGAScreen, this_player->x + 7, this_player->y - 7, *shapes9ptr_, 222); - switch (tempI) + + int ship_banking = 0; + switch (ship_sprite) { case 5: blit_sprite2(VGAScreen, this_player->x - 17, this_player->y + 7, *shapes9ptr_, 40); tempW = this_player->x - 7; - tempI2 = -2; + ship_banking = -2; break; case 3: blit_sprite2(VGAScreen, this_player->x - 17, this_player->y + 7, *shapes9ptr_, 39); tempW = this_player->x - 7; - tempI2 = -1; + ship_banking = -1; break; case 1: - tempI2 = 0; + ship_banking = 0; break; case -1: blit_sprite2(VGAScreen, this_player->x + 19, this_player->y + 7, *shapes9ptr_, 58); tempW = this_player->x + 9; - tempI2 = 1; + ship_banking = 1; break; case -3: blit_sprite2(VGAScreen, this_player->x + 19, this_player->y + 7, *shapes9ptr_, 59); tempW = this_player->x + 9; - tempI2 = 2; + ship_banking = 2; break; } - if (tempI2 != 0) // NortSparks + if (ship_banking != 0) // NortSparks { if (shotRepeat[SHOT_NORTSPARKS] > 0) { @@ -3795,32 +3770,34 @@ redo: } else { - JE_initPlayerShot(0, SHOT_NORTSPARKS, tempW + (mt_rand() % 8) - 4, this_player->y + (mt_rand() % 8) - 4, *mouseX_, *mouseY_, 671, 1); - shotRepeat[SHOT_NORTSPARKS] = abs(tempI2) - 1; + b = player_shot_create(0, SHOT_NORTSPARKS, tempW + (mt_rand() % 8) - 4, this_player->y + (mt_rand() % 8) - 4, *mouseX_, *mouseY_, 671, 1); + shotRepeat[SHOT_NORTSPARKS] = abs(ship_banking) - 1; } } } else - blit_sprite2x2(VGAScreen, this_player->x - 5, this_player->y - 7, *shapes9ptr_, tempI); + { + blit_sprite2x2(VGAScreen, this_player->x - 5, this_player->y - 7, *shapes9ptr_, ship_sprite); + } + } + + /*Options Location*/ + if (playerNum_ == 2 && shipGr_ == 0) // if dragonwing + { + if (this_player->sidekick[LEFT_SIDEKICK].style == 0) + { + this_player->sidekick[LEFT_SIDEKICK].x = this_player->x - 14 + ship_banking * 2; + this_player->sidekick[LEFT_SIDEKICK].y = this_player->y; + } + + if (this_player->sidekick[RIGHT_SIDEKICK].style == 0) + { + this_player->sidekick[RIGHT_SIDEKICK].x = this_player->x + 17 + ship_banking * 2; + this_player->sidekick[RIGHT_SIDEKICK].y = this_player->y; + } } } // !endLevel - /*Options Location*/ - if (playerNum_ == 2 && shipGr_ == 0) // if dragonwing - { - if (this_player->sidekick[LEFT_SIDEKICK].style == 0) - { - this_player->sidekick[LEFT_SIDEKICK].x = this_player->x - 14 + tempI; - this_player->sidekick[LEFT_SIDEKICK].y = this_player->y; - } - - if (this_player->sidekick[RIGHT_SIDEKICK].style == 0) - { - this_player->sidekick[RIGHT_SIDEKICK].x = this_player->x + 17 + tempI; - this_player->sidekick[RIGHT_SIDEKICK].y = this_player->y; - } - } - if (moveOk) { if (this_player->is_alive) @@ -3892,7 +3869,7 @@ redo: const uint item_power = galagaMode ? 0 : this_player->items.weapon[temp].power - 1, item_mode = (temp == REAR_WEAPON) ? this_player->weapon_mode - 1 : 0; - JE_initPlayerShot(item, temp, this_player->x, this_player->y, *mouseX_, *mouseY_, weaponPort[item].op[item_mode][item_power], playerNum_); + b = player_shot_create(item, temp, this_player->x, this_player->y, *mouseX_, *mouseY_, weaponPort[item].op[item_mode][item_power], playerNum_); } } } @@ -3903,7 +3880,7 @@ redo: { if (!twoPlayerLinked) - blit_sprite2(VGAScreen, this_player->x + (shipGr_ == 0) + 1, this_player->y - 13, eShapes6, 77 + chargeLevel + chargeGr * 19); + blit_sprite2(VGAScreen, this_player->x + (shipGr_ == 0) + 1, this_player->y - 13, eShapes[5], 77 + chargeLevel + chargeGr * 19); if (chargeGrWait > 0) { @@ -3946,7 +3923,7 @@ redo: else if (button[1-1] && (!twoPlayerLinked || chargeLevel > 0)) { shotMultiPos[SHOT_P2_CHARGE] = 0; - JE_initPlayerShot(16, SHOT_P2_CHARGE, this_player->x, this_player->y, *mouseX_, *mouseY_, chargeGunWeapons[player[1].items.weapon[REAR_WEAPON].id-1] + chargeLevel, playerNum_); + b = player_shot_create(16, SHOT_P2_CHARGE, this_player->x, this_player->y, *mouseX_, *mouseY_, chargeGunWeapons[player[1].items.weapon[REAR_WEAPON].id-1] + chargeLevel, playerNum_); if (chargeLevel > 0) fill_rectangle_xy(VGAScreenSeg, 269, 107 + (chargeLevel - 1) * 3, 275, 108 + (chargeLevel - 1) * 3, 193); @@ -3971,7 +3948,7 @@ redo: { --player[temp-1].superbombs; shotMultiPos[SHOT_P1_SUPERBOMB + temp-1] = 0; - JE_initPlayerShot(16, SHOT_P1_SUPERBOMB + temp-1, this_player->x, this_player->y, *mouseX_, *mouseY_, 535, playerNum_); + b = player_shot_create(16, SHOT_P1_SUPERBOMB + temp-1, this_player->x, this_player->y, *mouseX_, *mouseY_, 535, playerNum_); } } @@ -4126,7 +4103,7 @@ redo: if (button[1 + i] && this_player->sidekick[i].ammo > 0) { - JE_initPlayerShot(this_option->wport, shot_i, this_player->sidekick[i].x, this_player->sidekick[i].y, *mouseX_, *mouseY_, this_option->wpnum + this_player->sidekick[i].charge, playerNum_); + b = player_shot_create(this_option->wport, shot_i, this_player->sidekick[i].x, this_player->sidekick[i].y, *mouseX_, *mouseY_, this_option->wpnum + this_player->sidekick[i].charge, playerNum_); --this_player->sidekick[i].ammo; if (this_player->sidekick[i].charge > 0) @@ -4147,7 +4124,7 @@ redo: { if (button[0] || button[1 + i]) { - JE_initPlayerShot(this_option->wport, shot_i, this_player->sidekick[i].x, this_player->sidekick[i].y, *mouseX_, *mouseY_, this_option->wpnum + this_player->sidekick[i].charge, playerNum_); + b = player_shot_create(this_option->wport, shot_i, this_player->sidekick[i].x, this_player->sidekick[i].y, *mouseX_, *mouseY_, this_option->wpnum + this_player->sidekick[i].charge, playerNum_); if (this_player->sidekick[i].charge > 0) { @@ -4189,7 +4166,7 @@ redo: const uint sprite = this_option->gr[this_player->sidekick[i].animation_frame] + this_player->sidekick[i].charge; if (this_player->sidekick[i].style == 1 || this_player->sidekick[i].style == 2) - blit_sprite2x2(VGAScreen, x - 6, y, eShapes6, sprite); + blit_sprite2x2(VGAScreen, x - 6, y, eShapes[5], sprite); else blit_sprite2(VGAScreen, x, y, shapes9, sprite); } @@ -4283,14 +4260,14 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) { if (enemyAvail[z] != 1) { - tempI3 = enemy[z].ex + enemy[z].mapoffset; + int enemy_screen_x = enemy[z].ex + enemy[z].mapoffset; - if (abs(this_player->x - tempI3) < 12 && abs(this_player->y - enemy[z].ey) < 14) + if (abs(this_player->x - enemy_screen_x) < 12 && abs(this_player->y - enemy[z].ey) < 14) { /*Collide*/ - tempI4 = enemy[z].evalue; - if (tempI4 > 29999) + int evalue = enemy[z].evalue; + if (evalue > 29999) { - if (tempI4 == 30000) // spawn dragonwing in galaga mode, otherwise just a purple ball + if (evalue == 30000) // spawn dragonwing in galaga mode, otherwise just a purple ball { this_player->cash += 100; @@ -4312,12 +4289,12 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) enemyAvail[z] = 1; soundQueue[7] = S_POWERUP; } - else if (superArcadeMode != SA_NONE && tempI4 > 30000) + else if (superArcadeMode != SA_NONE && evalue > 30000) { shotMultiPos[SHOT_FRONT] = 0; shotRepeat[SHOT_FRONT] = 10; - tempW = SAWeapon[superArcadeMode-1][tempI4 - 30000-1]; + tempW = SAWeapon[superArcadeMode-1][evalue - 30000-1]; // if picked up already-owned weapon, power weapon up if (tempW == player[0].items.weapon[FRONT_WEAPON].id) @@ -4336,43 +4313,43 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) soundQueue[7] = S_POWERUP; enemyAvail[z] = 1; } - else if (tempI4 > 32100) + else if (evalue > 32100) { if (playerNum_ == 1) { this_player->cash += 250; - player[0].items.special = tempI4 - 32100; + player[0].items.special = evalue - 32100; shotMultiPos[SHOT_SPECIAL] = 0; shotRepeat[SHOT_SPECIAL] = 10; shotMultiPos[SHOT_SPECIAL2] = 0; shotRepeat[SHOT_SPECIAL2] = 0; if (isNetworkGame) - sprintf(tempStr, "%s %s %s", JE_getName(1), miscTextB[4-1], special[tempI4 - 32100].name); + sprintf(tempStr, "%s %s %s", JE_getName(1), miscTextB[4-1], special[evalue - 32100].name); else if (twoPlayerMode) - sprintf(tempStr, "%s %s", miscText[43-1], special[tempI4 - 32100].name); + sprintf(tempStr, "%s %s", miscText[43-1], special[evalue - 32100].name); else - sprintf(tempStr, "%s %s", miscText[64-1], special[tempI4 - 32100].name); + sprintf(tempStr, "%s %s", miscText[64-1], special[evalue - 32100].name); JE_drawTextWindow(tempStr); soundQueue[7] = S_POWERUP; enemyAvail[z] = 1; } } - else if (tempI4 > 32000) + else if (evalue > 32000) { if (playerNum_ == 2) { enemyAvail[z] = 1; if (isNetworkGame) - sprintf(tempStr, "%s %s %s", JE_getName(2), miscTextB[4-1], options[tempI4 - 32000].name); + sprintf(tempStr, "%s %s %s", JE_getName(2), miscTextB[4-1], options[evalue - 32000].name); else - sprintf(tempStr, "%s %s", miscText[44-1], options[tempI4 - 32000].name); + sprintf(tempStr, "%s %s", miscText[44-1], options[evalue - 32000].name); JE_drawTextWindow(tempStr); // if picked up a different sidekick than player already has, then reset sidekicks to least powerful, else power them up - if (tempI4 - 32000u != player[1].items.sidekick_series) + if (evalue - 32000u != player[1].items.sidekick_series) { - player[1].items.sidekick_series = tempI4 - 32000; + player[1].items.sidekick_series = evalue - 32000; player[1].items.sidekick_level = 101; } else if (player[1].items.sidekick_level < 103) @@ -4393,11 +4370,11 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) else if (onePlayerAction) { enemyAvail[z] = 1; - sprintf(tempStr, "%s %s", miscText[64-1], options[tempI4 - 32000].name); + sprintf(tempStr, "%s %s", miscText[64-1], options[evalue - 32000].name); JE_drawTextWindow(tempStr); for (uint i = 0; i < COUNTOF(player[0].items.sidekick); ++i) - player[0].items.sidekick[i] = tempI4 - 32000; + player[0].items.sidekick[i] = evalue - 32000; shotMultiPos[SHOT_LEFT_SIDEKICK] = 0; shotMultiPos[SHOT_RIGHT_SIDEKICK] = 0; @@ -4407,26 +4384,26 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) if (enemyAvail[z] == 1) this_player->cash += 250; } - else if (tempI4 > 31000) + else if (evalue > 31000) { this_player->cash += 250; if (playerNum_ == 2) { if (isNetworkGame) - sprintf(tempStr, "%s %s %s", JE_getName(2), miscTextB[4-1], weaponPort[tempI4 - 31000].name); + sprintf(tempStr, "%s %s %s", JE_getName(2), miscTextB[4-1], weaponPort[evalue - 31000].name); else - sprintf(tempStr, "%s %s", miscText[44-1], weaponPort[tempI4 - 31000].name); + sprintf(tempStr, "%s %s", miscText[44-1], weaponPort[evalue - 31000].name); JE_drawTextWindow(tempStr); - player[1].items.weapon[REAR_WEAPON].id = tempI4 - 31000; + player[1].items.weapon[REAR_WEAPON].id = evalue - 31000; shotMultiPos[SHOT_REAR] = 0; enemyAvail[z] = 1; soundQueue[7] = S_POWERUP; } else if (onePlayerAction) { - sprintf(tempStr, "%s %s", miscText[64-1], weaponPort[tempI4 - 31000].name); + sprintf(tempStr, "%s %s", miscText[64-1], weaponPort[evalue - 31000].name); JE_drawTextWindow(tempStr); - player[0].items.weapon[REAR_WEAPON].id = tempI4 - 31000; + player[0].items.weapon[REAR_WEAPON].id = evalue - 31000; shotMultiPos[SHOT_REAR] = 0; enemyAvail[z] = 1; soundQueue[7] = S_POWERUP; @@ -4435,25 +4412,25 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) player[0].items.weapon[REAR_WEAPON].power = 1; } } - else if (tempI4 > 30000) + else if (evalue > 30000) { if (playerNum_ == 1 && twoPlayerMode) { if (isNetworkGame) - sprintf(tempStr, "%s %s %s", JE_getName(1), miscTextB[4-1], weaponPort[tempI4 - 30000].name); + sprintf(tempStr, "%s %s %s", JE_getName(1), miscTextB[4-1], weaponPort[evalue - 30000].name); else - sprintf(tempStr, "%s %s", miscText[43-1], weaponPort[tempI4 - 30000].name); + sprintf(tempStr, "%s %s", miscText[43-1], weaponPort[evalue - 30000].name); JE_drawTextWindow(tempStr); - player[0].items.weapon[FRONT_WEAPON].id = tempI4 - 30000; + player[0].items.weapon[FRONT_WEAPON].id = evalue - 30000; shotMultiPos[SHOT_FRONT] = 0; enemyAvail[z] = 1; soundQueue[7] = S_POWERUP; } else if (onePlayerAction) { - sprintf(tempStr, "%s %s", miscText[64-1], weaponPort[tempI4 - 30000].name); + sprintf(tempStr, "%s %s", miscText[64-1], weaponPort[evalue - 30000].name); JE_drawTextWindow(tempStr); - player[0].items.weapon[FRONT_WEAPON].id = tempI4 - 30000; + player[0].items.weapon[FRONT_WEAPON].id = evalue - 30000; shotMultiPos[SHOT_FRONT] = 0; enemyAvail[z] = 1; soundQueue[7] = S_POWERUP; @@ -4461,7 +4438,7 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) if (enemyAvail[z] == 1) { - player[0].items.special = specialArcadeWeapon[tempI4 - 30000-1]; + player[0].items.special = specialArcadeWeapon[evalue - 30000-1]; if (player[0].items.special > 0) { shotMultiPos[SHOT_SPECIAL] = 0; @@ -4474,21 +4451,21 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) } } - else if (tempI4 > 20000) + else if (evalue > 20000) { if (twoPlayerLinked) { // share the armor evenly between linked players for (uint i = 0; i < COUNTOF(player); ++i) { - player[i].armor += (tempI4 - 20000) / COUNTOF(player); + player[i].armor += (evalue - 20000) / COUNTOF(player); if (player[i].armor > 28) player[i].armor = 28; } } else { - this_player->armor += tempI4 - 20000; + this_player->armor += evalue - 20000; if (this_player->armor > 28) this_player->armor = 28; } @@ -4498,13 +4475,13 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) VGAScreen = game_screen; /* side-effect of game_screen */ soundQueue[7] = S_POWERUP; } - else if (tempI4 > 10000 && enemyAvail[z] == 2) + else if (evalue > 10000 && enemyAvail[z] == 2) { if (!bonusLevel) { play_song(30); /*Zanac*/ bonusLevel = true; - nextLevel = tempI4 - 10000; + nextLevel = evalue - 10000; enemyAvail[z] = 1; displayTime = 150; } @@ -4513,12 +4490,12 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) { enemyAvail[z] = 1; soundQueue[7] = S_ITEM; - if (tempI4 == 1) + if (evalue == 1) { cubeMax++; soundQueue[3] = V_DATA_CUBE; } - else if (tempI4 == -1) // got front weapon powerup + else if (evalue == -1) // got front weapon powerup { if (isNetworkGame) sprintf(tempStr, "%s %s %s", JE_getName(1), miscTextB[4-1], miscText[45-1]); @@ -4531,7 +4508,7 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) power_up_weapon(&player[0], FRONT_WEAPON); soundQueue[7] = S_POWERUP; } - else if (tempI4 == -2) // got rear weapon powerup + else if (evalue == -2) // got rear weapon powerup { if (isNetworkGame) sprintf(tempStr, "%s %s %s", JE_getName(2), miscTextB[4-1], miscText[46-1]); @@ -4544,19 +4521,19 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) power_up_weapon(twoPlayerMode ? &player[1] : &player[0], REAR_WEAPON); soundQueue[7] = S_POWERUP; } - else if (tempI4 == -3) + else if (evalue == -3) { // picked up orbiting asteroid killer shotMultiPos[SHOT_MISC] = 0; - JE_initPlayerShot(0, SHOT_MISC, this_player->x, this_player->y, mouseX, mouseY, 104, playerNum_); + b = player_shot_create(0, SHOT_MISC, this_player->x, this_player->y, mouseX, mouseY, 104, playerNum_); shotAvail[z] = 0; } - else if (tempI4 == -4) + else if (evalue == -4) { if (player[playerNum_-1].superbombs < 10) ++player[playerNum_-1].superbombs; } - else if (tempI4 == -5) + else if (evalue == -5) { player[0].items.weapon[FRONT_WEAPON].id = 25; // HOT DOG! player[0].items.weapon[REAR_WEAPON].id = 26; @@ -4573,23 +4550,22 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) { // players get equal share of pick-up cash when linked for (uint i = 0; i < COUNTOF(player); ++i) - player[i].cash += tempI4 / COUNTOF(player); + player[i].cash += evalue / COUNTOF(player); } else { - this_player->cash += tempI4; + this_player->cash += evalue; } - JE_setupExplosion(tempI3, enemy[z].ey, 0, enemyDat[enemy[z].enemytype].explosiontype, true, false); + JE_setupExplosion(enemy_screen_x, enemy[z].ey, 0, enemyDat[enemy[z].enemytype].explosiontype, true, false); } else if (this_player->invulnerable_ticks == 0 && enemyAvail[z] == 0 && - enemyDat[enemy[z].enemytype].explosiontype % 2 == 0) + (enemyDat[enemy[z].enemytype].explosiontype & 1) == 0) // explosiontype & 1 == 0: not ground enemy { + int armorleft = enemy[z].armorleft; + if (armorleft > damageRate) + armorleft = damageRate; - tempI3 = enemy[z].armorleft; - if (tempI3 > damageRate) - tempI3 = damageRate; - - JE_playerDamage(tempI3, this_player); + JE_playerDamage(armorleft, this_player); // player ship gets push-back from collision if (enemy[z].armorleft > 0) @@ -4598,9 +4574,9 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) this_player->y_velocity += (enemy[z].eyc * enemy[z].armorleft) / 2; } - tempI = enemy[z].armorleft; - if (tempI == 255) - tempI = 30000; + int armorleft2 = enemy[z].armorleft; + if (armorleft2 == 255) + armorleft2 = 30000; temp = enemy[z].linknum; if (temp == 0) @@ -4608,14 +4584,16 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) b = z; - if (tempI > tempI2) + if (armorleft2 > armorleft) { + // damage enemy if (enemy[z].armorleft != 255) - enemy[z].armorleft -= tempI3; + enemy[z].armorleft -= armorleft; soundQueue[5] = S_ENEMY_HIT; } else { + // kill enemy for (temp2 = 0; temp2 < 100; temp2++) { if (enemyAvail[temp2] != 1) @@ -4626,7 +4604,7 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) (temp == temp3 || temp - 100 == temp3 || (temp3 > 40 && temp3 / 20 == temp / 20 && temp3 <= temp)))) { - tempI3 = enemy[temp2].ex + enemy[temp2].mapoffset; + int enemy_screen_x = enemy[temp2].ex + enemy[temp2].mapoffset; enemy[temp2].linknum = 0; @@ -4634,12 +4612,12 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) if (enemyDat[enemy[temp2].enemytype].esize == 1) { - JE_setupExplosionLarge(enemy[temp2].enemyground, enemy[temp2].explonum, tempI3, enemy[temp2].ey); + JE_setupExplosionLarge(enemy[temp2].enemyground, enemy[temp2].explonum, enemy_screen_x, enemy[temp2].ey); soundQueue[6] = S_EXPLOSION_9; } else { - JE_setupExplosion(tempI3, enemy[temp2].ey, 0, 1, false, false); + JE_setupExplosion(enemy_screen_x, enemy[temp2].ey, 0, 1, false, false); soundQueue[5] = S_EXPLOSION_4; } } @@ -4654,4 +4632,3 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) } } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/mainint.h b/project/jni/application/opentyrian/src/mainint.h index abb6504a1..d3714b087 100644 --- a/project/jni/application/opentyrian/src/mainint.h +++ b/project/jni/application/opentyrian/src/mainint.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -91,4 +91,3 @@ void JE_playerCollide( Player *this_player, JE_byte playerNum ); #endif /* MAININT_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/menus.c b/project/jni/application/opentyrian/src/menus.c index 231b986f5..4dc05e580 100644 --- a/project/jni/application/opentyrian/src/menus.c +++ b/project/jni/application/opentyrian/src/menus.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -29,10 +29,10 @@ #include "sprite.h" #include "video.h" -char episode_name[6][31], difficulty_name[7][21], gameplay_name[5][26]; +char episode_name[6][31], difficulty_name[7][21], gameplay_name[GAMEPLAY_NAME_COUNT][26]; bool -select_menuitem_by_touch(JE_byte menu_top, JE_byte menu_spacing, JE_shortint menu_item_count, JE_shortint *current_item) +select_menuitem_by_touch(int menu_top, int menu_spacing, int menu_item_count, int *current_item) { if (!mousedown) return false; @@ -56,16 +56,16 @@ bool select_gameplay( void ) JE_loadPic(VGAScreen, 2, false); JE_dString(VGAScreen, JE_fontCenter(gameplay_name[0], FONT_SHAPES), 20, gameplay_name[0], FONT_SHAPES); - const JE_byte menu_top = 30, menu_spacing = 24; - JE_shortint gameplay = 1, - gameplay_max = 4; + int menu_top = 30, menu_spacing = 24; + int gameplay = 1, + gameplay_max = GAMEPLAY_NAME_COUNT - 1; bool fade_in = true; for (; ; ) { for (int i = 1; i <= gameplay_max; i++) { - JE_outTextAdjust(VGAScreen, JE_fontCenter(gameplay_name[i], SMALL_FONT_SHAPES), i * menu_spacing + menu_top, gameplay_name[i], 15, - 4 + (i == gameplay ? 2 : 0) - (i == 4 ? 4 : 0), SMALL_FONT_SHAPES, true); + JE_outTextAdjust(VGAScreen, JE_fontCenter(gameplay_name[i], SMALL_FONT_SHAPES), i * menu_spacing + menu_top, gameplay_name[i], 15, -4 + (i == gameplay ? 2 : 0) - (i == (GAMEPLAY_NAME_COUNT - 1) ? 4 : 0), SMALL_FONT_SHAPES, true); } JE_showVGA(); @@ -87,8 +87,7 @@ bool select_gameplay( void ) { case SDLK_UP: case SDLK_LCTRL: - gameplay--; - if (gameplay < 1) + if (--gameplay < 1) { gameplay = gameplay_max; } @@ -96,8 +95,7 @@ bool select_gameplay( void ) break; case SDLK_DOWN: case SDLK_LALT: - gameplay++; - if (gameplay > gameplay_max) + if (++gameplay > gameplay_max) { gameplay = 1; } @@ -106,7 +104,7 @@ bool select_gameplay( void ) case SDLK_RETURN: case SDLK_SPACE: - if (gameplay == 4) + if (gameplay == GAMEPLAY_NAME_COUNT - 1) { JE_playSampleNum(S_SPRING); /* TODO: NETWORK */ @@ -117,7 +115,7 @@ bool select_gameplay( void ) fade_black(10); onePlayerAction = (gameplay == 2); - twoPlayerMode = (gameplay == 3); + twoPlayerMode = (gameplay == GAMEPLAY_NAME_COUNT - 2); return true; case SDLK_ESCAPE: @@ -139,9 +137,8 @@ bool select_episode( void ) JE_loadPic(VGAScreen, 2, false); JE_dString(VGAScreen, JE_fontCenter(episode_name[0], FONT_SHAPES), 20, episode_name[0], FONT_SHAPES); - const JE_byte menu_top = 20, menu_spacing = 30; - JE_shortint episode = 1, - episode_max = EPISODE_MAX - 1; + const int menu_top = 20, menu_spacing = 30; + int episode = 1, episode_max = EPISODE_AVAILABLE; bool fade_in = true; for (; ; ) @@ -220,9 +217,9 @@ bool select_difficulty( void ) JE_loadPic(VGAScreen, 2, false); JE_dString(VGAScreen, JE_fontCenter(difficulty_name[0], FONT_SHAPES), 20, difficulty_name[0], FONT_SHAPES); - const JE_byte menu_top = 30, menu_spacing = 24; + const int menu_top = 30, menu_spacing = 24; difficultyLevel = 2; - JE_shortint difficulty_max = 3; + int difficulty_max = 3; bool fade_in = true; for (; ; ) @@ -242,8 +239,12 @@ bool select_difficulty( void ) JE_word temp = 0; JE_textMenuWait(&temp, false); - if (select_menuitem_by_touch(menu_top, menu_spacing, difficulty_max, &difficultyLevel)) + int difficultyLevel_ = difficultyLevel; // Need to pass an int, difficultyLevel is short int + if (select_menuitem_by_touch(menu_top, menu_spacing, difficulty_max, &difficultyLevel_)) + { + difficultyLevel = difficultyLevel_; continue; + } if (SDL_GetModState() & KMOD_SHIFT) { @@ -307,4 +308,3 @@ bool select_difficulty( void ) } } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/menus.h b/project/jni/application/opentyrian/src/menus.h index c36427ca5..7d57b5e45 100644 --- a/project/jni/application/opentyrian/src/menus.h +++ b/project/jni/application/opentyrian/src/menus.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -21,13 +21,17 @@ #include "opentyr.h" -extern char episode_name[6][31], difficulty_name[7][21], gameplay_name[5][26]; +#ifdef TYRIAN2000 +#define GAMEPLAY_NAME_COUNT 6 +#else +#define GAMEPLAY_NAME_COUNT 5 +#endif +extern char episode_name[6][31], difficulty_name[7][21], gameplay_name[GAMEPLAY_NAME_COUNT][26]; bool select_gameplay( void ); bool select_episode( void ); bool select_difficulty( void ); -bool select_menuitem_by_touch(JE_byte menu_top, JE_byte menu_spacing, JE_shortint menu_item_count, JE_shortint *current_item); +bool select_menuitem_by_touch(int menu_top, int menu_spacing, int menu_item_count, int *current_item); #endif /* MENUS_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/mingw_fixes.c b/project/jni/application/opentyrian/src/mingw_fixes.c index bc3d34025..d73443815 100644 --- a/project/jni/application/opentyrian/src/mingw_fixes.c +++ b/project/jni/application/opentyrian/src/mingw_fixes.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or diff --git a/project/jni/application/opentyrian/src/mingw_fixes.h b/project/jni/application/opentyrian/src/mingw_fixes.h index cb70b8ccf..9be9615bc 100644 --- a/project/jni/application/opentyrian/src/mingw_fixes.h +++ b/project/jni/application/opentyrian/src/mingw_fixes.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or diff --git a/project/jni/application/opentyrian/src/mouse.c b/project/jni/application/opentyrian/src/mouse.c index b13180f6e..e8c373965 100644 --- a/project/jni/application/opentyrian/src/mouse.c +++ b/project/jni/application/opentyrian/src/mouse.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -115,4 +115,3 @@ void JE_mouseReplace( void ) JE_drawShapeTypeOne(lastMouseX, lastMouseY, mouseGrabShape); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/mouse.h b/project/jni/application/opentyrian/src/mouse.h index 5e208add9..12575c525 100644 --- a/project/jni/application/opentyrian/src/mouse.h +++ b/project/jni/application/opentyrian/src/mouse.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -41,4 +41,3 @@ void JE_mouseReplace( void ); #endif /* MOUSE_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/mtrand.c b/project/jni/application/opentyrian/src/mtrand.c index fa09d07c8..403ebeb5f 100644 --- a/project/jni/application/opentyrian/src/mtrand.c +++ b/project/jni/application/opentyrian/src/mtrand.c @@ -105,4 +105,3 @@ float mt_rand_lt1( void ) return ((float)mt_rand() / ((float)MT_RAND_MAX + 1.0f)); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/mtrand.h b/project/jni/application/opentyrian/src/mtrand.h index 08ea121a8..fcb2badfa 100644 --- a/project/jni/application/opentyrian/src/mtrand.h +++ b/project/jni/application/opentyrian/src/mtrand.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -28,4 +28,3 @@ float mt_rand_lt1( void ); #endif /* MTRAND_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/musmast.c b/project/jni/application/opentyrian/src/musmast.c index bfdb158ae..a1c826757 100644 --- a/project/jni/application/opentyrian/src/musmast.c +++ b/project/jni/application/opentyrian/src/musmast.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -114,4 +114,3 @@ const char musicTitle[MUSIC_NUM][48] = JE_boolean musicFade; -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/musmast.h b/project/jni/application/opentyrian/src/musmast.h index 9d1c65633..536f589f2 100644 --- a/project/jni/application/opentyrian/src/musmast.h +++ b/project/jni/application/opentyrian/src/musmast.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -39,4 +39,3 @@ extern JE_boolean musicFade; #endif /* MUSMAST_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/network.c b/project/jni/application/opentyrian/src/network.c index da72b1d6d..f4619e58b 100644 --- a/project/jni/application/opentyrian/src/network.c +++ b/project/jni/application/opentyrian/src/network.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -30,9 +30,6 @@ #include "varz.h" #include "video.h" -#include "SDL.h" -#include "SDL_net.h" - #include /* HERE BE DRAGONS! @@ -66,27 +63,29 @@ static char empty_string[] = ""; char *network_player_name = empty_string, *network_opponent_name = empty_string; -UDPsocket socket; -IPaddress ip; +#ifdef WITH_NETWORK +static UDPsocket socket; +static IPaddress ip; -UDPpacket *packet_out_temp, *packet_temp; +UDPpacket *packet_out_temp; +static UDPpacket *packet_temp; UDPpacket *packet_in[NET_PACKET_QUEUE] = { NULL }, *packet_out[NET_PACKET_QUEUE] = { NULL }; -Uint16 last_out_sync = 0, queue_in_sync = 0, queue_out_sync = 0, last_ack_sync = 0; -Uint32 last_in_tick = 0, last_out_tick = 0; +static Uint16 last_out_sync = 0, queue_in_sync = 0, queue_out_sync = 0, last_ack_sync = 0; +static Uint32 last_in_tick = 0, last_out_tick = 0; -UDPpacket *packet_state_in[NET_PACKET_QUEUE] = { NULL }, - *packet_state_in_xor[NET_PACKET_QUEUE] = { NULL }, - *packet_state_out[NET_PACKET_QUEUE] = { NULL }; +UDPpacket *packet_state_in[NET_PACKET_QUEUE] = { NULL }; +static UDPpacket *packet_state_in_xor[NET_PACKET_QUEUE] = { NULL }; +UDPpacket *packet_state_out[NET_PACKET_QUEUE] = { NULL }; -Uint16 last_state_in_sync = 0, last_state_out_sync = 0; -Uint32 last_state_in_tick = 0; +static Uint16 last_state_in_sync = 0, last_state_out_sync = 0; +static Uint32 last_state_in_tick = 0; -bool net_initialized = false; +static bool net_initialized = false; static bool connected = false, quit = false; - +#endif uint thisPlayerNum = 0; /* Player number on this PC (1 or 2) */ @@ -98,6 +97,41 @@ JE_boolean moveOk; JE_boolean pauseRequest, skipLevelRequest, helpRequest, nortShipRequest; JE_boolean yourInGameMenuRequest, inGameMenuRequest; +#ifdef WITH_NETWORK +static void packet_copy( UDPpacket *dst, UDPpacket *src ) +{ + void *temp = dst->data; + memcpy(dst, src, sizeof(*dst)); + dst->data = temp; + memcpy(dst->data, src->data, src->len); +} + +static void packets_shift_up( UDPpacket **packet, int max_packets ) +{ + if (packet[0]) + { + SDLNet_FreePacket(packet[0]); + } + for (int i = 0; i < max_packets - 1; i++) + { + packet[i] = packet[i + 1]; + } + packet[max_packets - 1] = NULL; +} + +static void packets_shift_down( UDPpacket **packet, int max_packets ) +{ + if (packet[max_packets - 1]) + { + SDLNet_FreePacket(packet[max_packets - 1]); + } + for (int i = max_packets - 1; i > 0; i--) + { + packet[i] = packet[i - 1]; + } + packet[0] = NULL; +} + // prepare new packet for sending void network_prepare( Uint16 type ) { @@ -105,6 +139,20 @@ void network_prepare( Uint16 type ) SDLNet_Write16(last_out_sync, &packet_out_temp->data[2]); } +// send packet but don't expect acknoledgment of delivery +static bool network_send_no_ack( int len ) +{ + packet_out_temp->len = len; + + if (!SDLNet_UDP_Send(socket, 0, packet_out_temp)) + { + printf("SDLNet_UDP_Send: %s\n", SDL_GetError()); + return false; + } + + return true; +} + // send packet and place it in queue to be acknowledged bool network_send( int len ) { @@ -129,18 +177,20 @@ bool network_send( int len ) return temp; } -// send packet but don't expect acknoledgment of delivery -bool network_send_no_ack( int len ) +// send acknowledgement packet +static int network_acknowledge( Uint16 sync ) { - packet_out_temp->len = len; + SDLNet_Write16(PACKET_ACKNOWLEDGE, &packet_out_temp->data[0]); + SDLNet_Write16(sync, &packet_out_temp->data[2]); + network_send_no_ack(4); - if (!SDLNet_UDP_Send(socket, 0, packet_out_temp)) - { - printf("SDLNet_UDP_Send: %s\n", SDL_GetError()); - return false; - } + return 0; +} - return true; +// activity lately? +static bool network_is_alive( void ) +{ + return (SDL_GetTicks() - last_in_tick < NET_TIME_OUT || SDL_GetTicks() - last_state_in_tick < NET_TIME_OUT); } // poll for new packets received, check that connection is alive, resend queued packets if necessary @@ -337,16 +387,6 @@ int network_check( void ) return 0; } -// send acknowledgement packet -int network_acknowledge( Uint16 sync ) -{ - SDLNet_Write16(PACKET_ACKNOWLEDGE, &packet_out_temp->data[0]); - SDLNet_Write16(sync, &packet_out_temp->data[2]); - network_send_no_ack(4); - - return 0; -} - // discard working packet, now processing next packet in queue bool network_update( void ) { @@ -368,12 +408,6 @@ bool network_is_sync( void ) return (queue_out_sync - last_ack_sync == 1); } -// activity lately? -bool network_is_alive( void ) -{ - return (SDL_GetTicks() - last_in_tick < NET_TIME_OUT || SDL_GetTicks() - last_state_in_tick < NET_TIME_OUT); -} - // prepare new state for sending void network_state_prepare( void ) @@ -741,40 +775,7 @@ int network_init( void ) return 0; } -void packet_copy( UDPpacket *dst, UDPpacket *src ) -{ - void *temp = dst->data; - memcpy(dst, src, sizeof(*dst)); - dst->data = temp; - memcpy(dst->data, src->data, src->len); -} - -void packets_shift_up( UDPpacket **packet, int max_packets ) -{ - if (packet[0]) - { - SDLNet_FreePacket(packet[0]); - } - for (int i = 0; i < max_packets - 1; i++) - { - packet[i] = packet[i + 1]; - } - packet[max_packets - 1] = NULL; -} - -void packets_shift_down( UDPpacket **packet, int max_packets ) -{ - if (packet[max_packets - 1]) - { - SDLNet_FreePacket(packet[max_packets - 1]); - } - for (int i = max_packets - 1; i > 0; i--) - { - packet[i] = packet[i - 1]; - } - packet[0] = NULL; -} - +#endif void JE_clearSpecialRequests( void ) { @@ -785,4 +786,3 @@ void JE_clearSpecialRequests( void ) nortShipRequest = false; } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/network.h b/project/jni/application/opentyrian/src/network.h index d6b075685..f9c32b0c7 100644 --- a/project/jni/application/opentyrian/src/network.h +++ b/project/jni/application/opentyrian/src/network.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -22,7 +22,9 @@ #include "opentyr.h" #include "SDL.h" -#include "SDL_net.h" +#ifdef WITH_NETWORK +# include "SDL_net.h" +#endif #define PACKET_ACKNOWLEDGE 0x00 // @@ -50,28 +52,26 @@ extern char *network_opponent_host; extern Uint16 network_player_port, network_opponent_port; extern char *network_player_name, *network_opponent_name; +#ifdef WITH_NETWORK extern UDPpacket *packet_out_temp; extern UDPpacket *packet_in[], *packet_out[], *packet_state_in[], *packet_state_out[]; +#endif extern uint thisPlayerNum; extern JE_boolean haltGame; extern JE_boolean moveOk; extern JE_boolean pauseRequest, skipLevelRequest, helpRequest, nortShipRequest; extern JE_boolean yourInGameMenuRequest, inGameMenuRequest; -extern JE_boolean portConfigChange, portConfigDone; - +#ifdef WITH_NETWORK void network_prepare( Uint16 type ); bool network_send( int len ); -bool network_send_no_ack( int len ); int network_check( void ); -int network_acknowledge( Uint16 sync ); bool network_update( void ); bool network_is_sync( void ); -bool network_is_alive( void ); void network_state_prepare( void ); int network_state_send( void ); @@ -84,17 +84,18 @@ void network_tyrian_halt( unsigned int err, bool attempt_sync ); int network_init( void ); -void packet_copy( UDPpacket *dst, UDPpacket *src ); -void packets_shift_up( UDPpacket **packet, int max_packets ); -void packets_shift_down( UDPpacket **packet, int max_packets ); - void JE_clearSpecialRequests( void ); #define NETWORK_KEEP_ALIVE() \ if (isNetworkGame) \ network_check(); +#else + +#define NETWORK_KEEP_ALIVE() + +#endif + #endif /* NETWORK_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/nortsong.c b/project/jni/application/opentyrian/src/nortsong.c index 359df6912..39283aff5 100644 --- a/project/jni/application/opentyrian/src/nortsong.c +++ b/project/jni/application/opentyrian/src/nortsong.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -117,7 +117,7 @@ void JE_loadSndFile( const char *effects_sndfile, const char *voices_sndfile ) efread(&sndPos[0][x], sizeof(sndPos[0][x]), 1, fi); } fseek(fi, 0, SEEK_END); - sndPos[1][sndNum] = ftell(fi); /* Store file size */ + sndPos[0][sndNum] = ftell(fi); /* Store file size */ for (z = 0; z < sndNum; z++) { @@ -222,4 +222,3 @@ void JE_changeVolume( JE_word *music, int music_delta, JE_word *sample, int samp set_volume(*music, *sample); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/nortsong.h b/project/jni/application/opentyrian/src/nortsong.h index 57d8502e7..4d0a88287 100644 --- a/project/jni/application/opentyrian/src/nortsong.h +++ b/project/jni/application/opentyrian/src/nortsong.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -62,4 +62,3 @@ void JE_playSampleNum( JE_byte samplenum ); #endif /* NORTSONG_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/nortvars.c b/project/jni/application/opentyrian/src/nortvars.c index 0c709b425..bed66cca6 100644 --- a/project/jni/application/opentyrian/src/nortvars.c +++ b/project/jni/application/opentyrian/src/nortvars.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -85,4 +85,3 @@ void JE_wipeKey( void ) // /!\ Doesn't seems to affect anything. } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/nortvars.h b/project/jni/application/opentyrian/src/nortvars.h index f4113d31d..cb371a777 100644 --- a/project/jni/application/opentyrian/src/nortvars.h +++ b/project/jni/application/opentyrian/src/nortvars.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -33,4 +33,3 @@ void JE_wipeKey( void ); #endif /* NORTVARS_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/opentyr.c b/project/jni/application/opentyrian/src/opentyr.c index 038add4ef..912e850b3 100644 --- a/project/jni/application/opentyrian/src/opentyr.c +++ b/project/jni/application/opentyrian/src/opentyr.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -52,39 +52,11 @@ #include #include #include +#include #include -#ifdef ANDROID -#include -#endif const char *opentyrian_str = "OpenTyrian", - *opentyrian_version = "Classic (" HG_REV ")"; -const char *opentyrian_menu_items[] = -{ - "About OpenTyrian", -#ifndef ANDROID - "Toggle Fullscreen", -#endif - "Scaler: None", - "Jukebox", -#ifdef ANDROID - "Play Destruct", -#endif - "Return to Main Menu" -}; - -#ifndef ANDROID -enum { - menu_item_scaler = 2, - menu_item_jukebox = 3 -}; -#else -enum { - menu_item_scaler = 1, - menu_item_jukebox = 2, - menu_item_destruct = 3 -}; -#endif + *opentyrian_version = HG_REV; /* zero-terminated strncpy */ char *strnztcpy( char *to, const char *from, size_t count ) @@ -95,13 +67,39 @@ char *strnztcpy( char *to, const char *from, size_t count ) void opentyrian_menu( void ) { - const JE_byte menu_top = 36, menu_spacing = 20; - JE_shortint sel = 0; - const int maxSel = COUNTOF(opentyrian_menu_items) - 1; - bool quit = false, fade_in = true; - - uint temp_scaler = scaler; + typedef enum + { + MENU_ABOUT = 0, + MENU_FULLSCREEN, + MENU_SCALER, + // MENU_DESTRUCT, + MENU_JUKEBOX, + MENU_RETURN, + MenuOptions_MAX + } MenuOptions; + + static const char *menu_items[] = + { + "About OpenTyrian", + "Toggle Fullscreen", + "Scaler: None", + // "Play Destruct", + "Jukebox", + "Return to Main Menu", + }; + bool menu_items_disabled[] = + { + false, + !can_init_any_scaler(false) || !can_init_any_scaler(true), + false, + // false, + false, + false, + }; + assert(COUNTOF(menu_items) == MenuOptions_MAX); + assert(COUNTOF(menu_items_disabled) == MenuOptions_MAX); + fade_black(10); JE_loadPic(VGAScreen, 13, false); @@ -113,25 +111,29 @@ void opentyrian_menu( void ) play_song(36); // A Field for Mag + MenuOptions sel = 0; + int menu_top = 32, menu_spacing = 16; + + uint temp_scaler = scaler; + + bool fade_in = true, quit = false; do { memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h); - for (int i = 0; i <= maxSel; i++) + for (MenuOptions i = 0; i < MenuOptions_MAX; i++) { - const char *text = opentyrian_menu_items[i]; + const char *text = menu_items[i]; char buffer[100]; - if (i == menu_item_scaler) /* Scaler */ + if (i == MENU_SCALER) { snprintf(buffer, sizeof(buffer), "Scaler: %s", scalers[temp_scaler].name); text = buffer; } - // Destruct is not adapted for touch input, so we show it only if keyboard is used: - if (i == menu_item_destruct && (mousedown || lastkey_sym == SDLK_ESCAPE)) - continue; - draw_font_hv_shadow(VGAScreen, VGAScreen->w / 2, (i != maxSel) ? i * menu_spacing + menu_top : 118, text, normal_font, centered, 15, (i != sel) ? -4 : -2, false, 2); + int y = i != MENU_RETURN ? i * 16 + 32 : 118; + draw_font_hv(VGAScreen, VGAScreen->w / 2, y, text, normal_font, centered, 15, menu_items_disabled[i] ? -8 : i != sel ? -4 : -2); } JE_showVGA(); @@ -146,132 +148,139 @@ void opentyrian_menu( void ) tempW = 0; JE_textMenuWait(&tempW, false); - if (select_menuitem_by_touch(menu_top, menu_spacing, maxSel, &sel)) + int sel_ = sel; // We need to pass int there, and sel is enum (yes that's also int, but compiler gives warning) + if (select_menuitem_by_touch(menu_top, menu_spacing, MenuOptions_MAX, &sel_)) + { + sel = sel_; continue; + } if (newkey) { switch (lastkey_sym) { - case SDLK_UP: - case SDLK_LCTRL: - sel--; - if (sel < 0) - { - sel = maxSel; - } - JE_playSampleNum(S_CURSOR); - break; - case SDLK_DOWN: - case SDLK_LALT: - sel++; - if (sel > maxSel) - { + case SDLK_UP: + case SDLK_LCTRL: + do + { + if (sel-- == 0) + sel = MenuOptions_MAX - 1; + } + while (menu_items_disabled[sel]); + + JE_playSampleNum(S_CURSOR); + break; + case SDLK_DOWN: + case SDLK_LALT: + do + { + if (++sel >= MenuOptions_MAX) sel = 0; + } + while (menu_items_disabled[sel]); + + JE_playSampleNum(S_CURSOR); + break; + + case SDLK_LEFT: + if (sel == MENU_SCALER) + { + do + { + if (temp_scaler == 0) + temp_scaler = scalers_count; + temp_scaler--; } + while (!can_init_scaler(temp_scaler, fullscreen_enabled)); + JE_playSampleNum(S_CURSOR); - break; - case SDLK_LEFT: - if (sel == menu_item_scaler) + } + break; + case SDLK_RIGHT: + if (sel == MENU_SCALER) + { + do { - do + temp_scaler++; + if (temp_scaler == scalers_count) + temp_scaler = 0; + } + while (!can_init_scaler(temp_scaler, fullscreen_enabled)); + + JE_playSampleNum(S_CURSOR); + } + break; + + case SDLK_RETURN: + case SDLK_SPACE: + switch (sel) + { + case MENU_ABOUT: + JE_playSampleNum(S_SELECT); + + scroller_sine(about_text); + + memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h); + JE_showVGA(); + fade_in = true; + break; + + case MENU_FULLSCREEN: + JE_playSampleNum(S_SELECT); + + if (!init_scaler(scaler, !fullscreen_enabled) && // try new fullscreen state + !init_any_scaler(!fullscreen_enabled) && // try any scaler in new fullscreen state + !init_scaler(scaler, fullscreen_enabled)) // revert on fail + { + exit(EXIT_FAILURE); + } + set_palette(colors, 0, 255); // for switching between 8 bpp scalers + break; + + case MENU_SCALER: + JE_playSampleNum(S_SELECT); + + if (scaler != temp_scaler) + { + if (!init_scaler(temp_scaler, fullscreen_enabled) && // try new scaler + !init_scaler(temp_scaler, !fullscreen_enabled) && // try other fullscreen state + !init_scaler(scaler, fullscreen_enabled)) // revert on fail { - if (temp_scaler == 0) - temp_scaler = scalers_count; - temp_scaler--; + exit(EXIT_FAILURE); } - while (!can_init_scaler(temp_scaler, fullscreen_enabled)); - JE_playSampleNum(S_CURSOR); + set_palette(colors, 0, 255); // for switching between 8 bpp scalers } break; - case SDLK_RIGHT: -#ifdef ANDROID - case SDLK_RETURN: -#endif - if (sel == menu_item_scaler) - { - do - { - temp_scaler++; - if (temp_scaler == scalers_count) - temp_scaler = 0; - } - while (!can_init_scaler(temp_scaler, fullscreen_enabled)); - JE_playSampleNum(S_CURSOR); - } -#ifndef ANDROID + + case MENU_JUKEBOX: + JE_playSampleNum(S_SELECT); + + fade_black(10); + jukebox(); + + memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h); + JE_showVGA(); + fade_in = true; break; - case SDLK_RETURN: -#endif - case SDLK_SPACE: - switch (sel) - { - case 0: /* About */ - JE_playSampleNum(S_SELECT); - - scroller_sine(about_text); - - memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h); - JE_showVGA(); - fade_in = true; - break; -#ifndef ANDROID - case 1: /* Fullscreen */ - JE_playSampleNum(S_SELECT); - - if (!init_scaler(scaler, !fullscreen_enabled) && // try new fullscreen state - !init_any_scaler(!fullscreen_enabled) && // try any scaler in new fullscreen state - !init_scaler(scaler, fullscreen_enabled)) // revert on fail - { - exit(EXIT_FAILURE); - } - set_palette(colors, 0, 255); // for switching between 8 bpp scalers - break; -#endif - case menu_item_scaler: /* Scaler */ - JE_playSampleNum(S_SELECT); - - if (scaler != temp_scaler) - { - if (!init_scaler(temp_scaler, fullscreen_enabled) && // try new scaler - !init_scaler(temp_scaler, !fullscreen_enabled) && // try other fullscreen state - !init_scaler(scaler, fullscreen_enabled)) // revert on fail - { - exit(EXIT_FAILURE); - } - set_palette(colors, 0, 255); // for switching between 8 bpp scalers - } - break; - case menu_item_jukebox: /* Jukebox */ - JE_playSampleNum(S_SELECT); - - fade_black(10); - jukebox(); - - memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h); - JE_showVGA(); - fade_in = true; - break; -#ifdef ANDROID - case menu_item_destruct: /* Destruct */ - JE_playSampleNum(S_SELECT); - loadDestruct = true; - fade_black(10); - quit = true; - break; -#endif - default: /* Return to main menu */ - quit = true; - JE_playSampleNum(S_SPRING); - break; - } - break; - case SDLK_ESCAPE: + + case MENU_RETURN: quit = true; JE_playSampleNum(S_SPRING); break; - default: + + case MenuOptions_MAX: + assert(false); break; + } + break; + + case SDLK_ESCAPE: + quit = true; + JE_playSampleNum(S_SPRING); + break; + + default: + break; } } } while (!quit); @@ -279,15 +288,11 @@ void opentyrian_menu( void ) int main( int argc, char *argv[] ) { - #ifdef ANDROID - __android_log_print(ANDROID_LOG_INFO, "OpenTyrian", "SDL_main() called" ); - #endif - mt_srand(time(NULL)); printf("\nWelcome to... >> %s %s <<\n\n", opentyrian_str, opentyrian_version); - printf("Copyright (C) 2007-2009 The OpenTyrian Development Team\n\n"); + printf("Copyright (C) 2007-2013 The OpenTyrian Development Team\n\n"); printf("This program comes with ABSOLUTELY NO WARRANTY.\n"); printf("This is free software, and you are welcome to redistribute it\n"); @@ -361,10 +366,15 @@ int main( int argc, char *argv[] ) if (isNetworkGame) { +#ifdef WITH_NETWORK if (network_init()) { network_tyrian_halt(3, false); } +#else + fprintf(stderr, "OpenTyrian was compiled without networking support."); + JE_tyrianHalt(5); +#endif } #ifdef NDEBUG @@ -396,4 +406,3 @@ int main( int argc, char *argv[] ) return 0; } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/opentyr.h b/project/jni/application/opentyrian/src/opentyr.h index 7244f406e..7be9f1b6b 100644 --- a/project/jni/application/opentyrian/src/opentyr.h +++ b/project/jni/application/opentyrian/src/opentyr.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -50,6 +50,12 @@ typedef bool JE_boolean; typedef char JE_char; typedef float JE_real; +#ifdef TYRIAN2000 +#define TYRIAN_VERSION "2000" +#else +#define TYRIAN_VERSION "2.1" +#endif + char *strnztcpy( char *to, const char *from, size_t count ); extern const char *opentyrian_str, *opentyrian_version; @@ -58,4 +64,3 @@ void opentyrian_menu( void ); #endif /* OPENTYR_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/opl.c b/project/jni/application/opentyrian/src/opl.c new file mode 100644 index 000000000..a4071c53a --- /dev/null +++ b/project/jni/application/opentyrian/src/opl.c @@ -0,0 +1,1464 @@ +/* + * Copyright (C) 2002-2010 The DOSBox Team + * OPL2/OPL3 emulation library + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +/* + * Originally based on ADLIBEMU.C, an AdLib/OPL2 emulation library by Ken Silverman + * Copyright (C) 1998-2001 Ken Silverman + * Ken Silverman's official web site: "http://www.advsys.net/ken" + */ + + +#include +#include // rand() +#include // memset() +#include "opl.h" + +static Bit32u generator_add; // should be a chip parameter + +static fltype recipsamp; // inverse of sampling rate +static Bit16s wavtable[WAVEPREC*3]; // wave form table + +// vibrato/tremolo tables +static Bit32s vib_table[VIBTAB_SIZE]; +static Bit32s trem_table[TREMTAB_SIZE*2]; + +static Bit32s vibval_const[BLOCKBUF_SIZE]; +static Bit32s tremval_const[BLOCKBUF_SIZE]; + +// vibrato value tables (used per-operator) +static Bit32s vibval_var1[BLOCKBUF_SIZE]; +static Bit32s vibval_var2[BLOCKBUF_SIZE]; +//static Bit32s vibval_var3[BLOCKBUF_SIZE]; +//static Bit32s vibval_var4[BLOCKBUF_SIZE]; + +// vibrato/trmolo value table pointers +static Bit32s *vibval1, *vibval2, *vibval3, *vibval4; +static Bit32s *tremval1, *tremval2, *tremval3, *tremval4; + + +// key scale level lookup table +static const fltype kslmul[4] = { + 0.0, 0.5, 0.25, 1.0 // -> 0, 3, 1.5, 6 dB/oct +}; + +// frequency multiplicator lookup table +static const fltype frqmul_tab[16] = { + 0.5,1,2,3,4,5,6,7,8,9,10,10,12,12,15,15 +}; +// calculated frequency multiplication values (depend on sampling rate) +static fltype frqmul[16]; + +// key scale levels +static Bit8u kslev[8][16]; + +// map a channel number to the register offset of the modulator (=register base) +static const Bit8u modulatorbase[9] = { + 0,1,2, + 8,9,10, + 16,17,18 +}; + +// map a register base to a modulator operator number or operator number +#if defined(OPLTYPE_IS_OPL3) +static const Bit8u regbase2modop[44] = { + 0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8, // first set + 18,19,20,18,19,20,0,0,21,22,23,21,22,23,0,0,24,25,26,24,25,26 // second set +}; +static const Bit8u regbase2op[44] = { + 0,1,2,9,10,11,0,0,3,4,5,12,13,14,0,0,6,7,8,15,16,17, // first set + 18,19,20,27,28,29,0,0,21,22,23,30,31,32,0,0,24,25,26,33,34,35 // second set +}; +#else +static const Bit8u regbase2modop[22] = { + 0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8 +}; +static const Bit8u regbase2op[22] = { + 0,1,2,9,10,11,0,0,3,4,5,12,13,14,0,0,6,7,8,15,16,17 +}; +#endif + + +// start of the waveform +static Bit32u waveform[8] = { + WAVEPREC, + WAVEPREC>>1, + WAVEPREC, + (WAVEPREC*3)>>2, + 0, + 0, + (WAVEPREC*5)>>2, + WAVEPREC<<1 +}; + +// length of the waveform as mask +static Bit32u wavemask[8] = { + WAVEPREC-1, + WAVEPREC-1, + (WAVEPREC>>1)-1, + (WAVEPREC>>1)-1, + WAVEPREC-1, + ((WAVEPREC*3)>>2)-1, + WAVEPREC>>1, + WAVEPREC-1 +}; + +// where the first entry resides +static Bit32u wavestart[8] = { + 0, + WAVEPREC>>1, + 0, + WAVEPREC>>2, + 0, + 0, + 0, + WAVEPREC>>3 +}; + +// envelope generator function constants +static fltype attackconst[4] = { + (fltype)(1/2.82624), + (fltype)(1/2.25280), + (fltype)(1/1.88416), + (fltype)(1/1.59744) +}; +static fltype decrelconst[4] = { + (fltype)(1/39.28064), + (fltype)(1/31.41608), + (fltype)(1/26.17344), + (fltype)(1/22.44608) +}; + + +void operator_advance(op_type* op_pt, Bit32s vib) { + op_pt->wfpos = op_pt->tcount; // waveform position + + // advance waveform time + op_pt->tcount += op_pt->tinc; + op_pt->tcount += (Bit32s)(op_pt->tinc)*vib/FIXEDPT; + + op_pt->generator_pos += generator_add; +} + +void operator_advance_drums(op_type* op_pt1, Bit32s vib1, op_type* op_pt2, Bit32s vib2, op_type* op_pt3, Bit32s vib3) { + Bit32u c1 = op_pt1->tcount/FIXEDPT; + Bit32u c3 = op_pt3->tcount/FIXEDPT; + Bit32u phasebit = (((c1 & 0x88) ^ ((c1<<5) & 0x80)) | ((c3 ^ (c3<<2)) & 0x20)) ? 0x02 : 0x00; + + Bit32u noisebit = rand()&1; + + Bit32u snare_phase_bit = (((Bitu)((op_pt1->tcount/FIXEDPT) / 0x100))&1); + + //Hihat + Bit32u inttm = (phasebit<<8) | (0x34<<(phasebit ^ (noisebit<<1))); + op_pt1->wfpos = inttm*FIXEDPT; // waveform position + // advance waveform time + op_pt1->tcount += op_pt1->tinc; + op_pt1->tcount += (Bit32s)(op_pt1->tinc)*vib1/FIXEDPT; + op_pt1->generator_pos += generator_add; + + //Snare + inttm = ((1+snare_phase_bit) ^ noisebit)<<8; + op_pt2->wfpos = inttm*FIXEDPT; // waveform position + // advance waveform time + op_pt2->tcount += op_pt2->tinc; + op_pt2->tcount += (Bit32s)(op_pt2->tinc)*vib2/FIXEDPT; + op_pt2->generator_pos += generator_add; + + //Cymbal + inttm = (1+phasebit)<<8; + op_pt3->wfpos = inttm*FIXEDPT; // waveform position + // advance waveform time + op_pt3->tcount += op_pt3->tinc; + op_pt3->tcount += (Bit32s)(op_pt3->tinc)*vib3/FIXEDPT; + op_pt3->generator_pos += generator_add; +} + + +// output level is sustained, mode changes only when operator is turned off (->release) +// or when the keep-sustained bit is turned off (->sustain_nokeep) +void operator_output(op_type* op_pt, Bit32s modulator, Bit32s trem) { + if (op_pt->op_state != OF_TYPE_OFF) { + op_pt->lastcval = op_pt->cval; + Bit32u i = (Bit32u)((op_pt->wfpos+modulator)/FIXEDPT); + + // wform: -16384 to 16383 (0x4000) + // trem : 32768 to 65535 (0x10000) + // step_amp: 0.0 to 1.0 + // vol : 1/2^14 to 1/2^29 (/0x4000; /1../0x8000) + + op_pt->cval = (Bit32s)(op_pt->step_amp*op_pt->vol*op_pt->cur_wform[i&op_pt->cur_wmask]*trem/16.0); + } +} + + +// no action, operator is off +void operator_off(op_type* op_pt) { + (void) op_pt; +} + +// output level is sustained, mode changes only when operator is turned off (->release) +// or when the keep-sustained bit is turned off (->sustain_nokeep) +void operator_sustain(op_type* op_pt) { + Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples + for (Bit32u ct=0; ctcur_env_step++; + } + op_pt->generator_pos -= num_steps_add*FIXEDPT; +} + +// operator in release mode, if output level reaches zero the operator is turned off +void operator_release(op_type* op_pt) { + // ??? boundary? + if (op_pt->amp > 0.00000001) { + // release phase + op_pt->amp *= op_pt->releasemul; + } + + Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples + for (Bit32u ct=0; ctcur_env_step++; // sample counter + if ((op_pt->cur_env_step & op_pt->env_step_r)==0) { + if (op_pt->amp <= 0.00000001) { + // release phase finished, turn off this operator + op_pt->amp = 0.0; + if (op_pt->op_state == OF_TYPE_REL) { + op_pt->op_state = OF_TYPE_OFF; + } + } + op_pt->step_amp = op_pt->amp; + } + } + op_pt->generator_pos -= num_steps_add*FIXEDPT; +} + +// operator in decay mode, if sustain level is reached the output level is either +// kept (sustain level keep enabled) or the operator is switched into release mode +void operator_decay(op_type* op_pt) { + if (op_pt->amp > op_pt->sustain_level) { + // decay phase + op_pt->amp *= op_pt->decaymul; + } + + Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples + for (Bit32u ct=0; ctcur_env_step++; + if ((op_pt->cur_env_step & op_pt->env_step_d)==0) { + if (op_pt->amp <= op_pt->sustain_level) { + // decay phase finished, sustain level reached + if (op_pt->sus_keep) { + // keep sustain level (until turned off) + op_pt->op_state = OF_TYPE_SUS; + op_pt->amp = op_pt->sustain_level; + } else { + // next: release phase + op_pt->op_state = OF_TYPE_SUS_NOKEEP; + } + } + op_pt->step_amp = op_pt->amp; + } + } + op_pt->generator_pos -= num_steps_add*FIXEDPT; +} + +// operator in attack mode, if full output level is reached, +// the operator is switched into decay mode +void operator_attack(op_type* op_pt) { + op_pt->amp = ((op_pt->a3*op_pt->amp + op_pt->a2)*op_pt->amp + op_pt->a1)*op_pt->amp + op_pt->a0; + + Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples + for (Bit32u ct=0; ctcur_env_step++; // next sample + if ((op_pt->cur_env_step & op_pt->env_step_a)==0) { // check if next step already reached + if (op_pt->amp > 1.0) { + // attack phase finished, next: decay + op_pt->op_state = OF_TYPE_DEC; + op_pt->amp = 1.0; + op_pt->step_amp = 1.0; + } + op_pt->step_skip_pos_a <<= 1; + if (op_pt->step_skip_pos_a==0) op_pt->step_skip_pos_a = 1; + if (op_pt->step_skip_pos_a & op_pt->env_step_skip_a) { // check if required to skip next step + op_pt->step_amp = op_pt->amp; + } + } + } + op_pt->generator_pos -= num_steps_add*FIXEDPT; +} + + +typedef void (*optype_fptr)(op_type*); + +optype_fptr opfuncs[6] = { + operator_attack, + operator_decay, + operator_release, + operator_sustain, // sustain phase (keeping level) + operator_release, // sustain_nokeep phase (release-style) + operator_off +}; + +void change_attackrate(Bitu regbase, op_type* op_pt) { + Bits attackrate = adlibreg[ARC_ATTR_DECR+regbase]>>4; + if (attackrate) { + fltype f = (fltype)(pow(FL2,(fltype)attackrate+(op_pt->toff>>2)-1)*attackconst[op_pt->toff&3]*recipsamp); + // attack rate coefficients + op_pt->a0 = (fltype)(0.0377*f); + op_pt->a1 = (fltype)(10.73*f+1); + op_pt->a2 = (fltype)(-17.57*f); + op_pt->a3 = (fltype)(7.42*f); + + Bits step_skip = attackrate*4 + op_pt->toff; + Bits steps = step_skip >> 2; + op_pt->env_step_a = (1<<(steps<=12?12-steps:0))-1; + + Bits step_num = (step_skip<=48)?(4-(step_skip&3)):0; + static Bit8u step_skip_mask[5] = {0xff, 0xfe, 0xee, 0xba, 0xaa}; + op_pt->env_step_skip_a = step_skip_mask[step_num]; + +#if defined(OPLTYPE_IS_OPL3) + if (step_skip>=60) { +#else + if (step_skip>=62) { +#endif + op_pt->a0 = (fltype)(2.0); // something that triggers an immediate transition to amp:=1.0 + op_pt->a1 = (fltype)(0.0); + op_pt->a2 = (fltype)(0.0); + op_pt->a3 = (fltype)(0.0); + } + } else { + // attack disabled + op_pt->a0 = 0.0; + op_pt->a1 = 1.0; + op_pt->a2 = 0.0; + op_pt->a3 = 0.0; + op_pt->env_step_a = 0; + op_pt->env_step_skip_a = 0; + } +} + +void change_decayrate(Bitu regbase, op_type* op_pt) { + Bits decayrate = adlibreg[ARC_ATTR_DECR+regbase]&15; + // decaymul should be 1.0 when decayrate==0 + if (decayrate) { + fltype f = (fltype)(-7.4493*decrelconst[op_pt->toff&3]*recipsamp); + op_pt->decaymul = (fltype)(pow(FL2,f*pow(FL2,(fltype)(decayrate+(op_pt->toff>>2))))); + Bits steps = (decayrate*4 + op_pt->toff) >> 2; + op_pt->env_step_d = (1<<(steps<=12?12-steps:0))-1; + } else { + op_pt->decaymul = 1.0; + op_pt->env_step_d = 0; + } +} + +void change_releaserate(Bitu regbase, op_type* op_pt) { + Bits releaserate = adlibreg[ARC_SUSL_RELR+regbase]&15; + // releasemul should be 1.0 when releaserate==0 + if (releaserate) { + fltype f = (fltype)(-7.4493*decrelconst[op_pt->toff&3]*recipsamp); + op_pt->releasemul = (fltype)(pow(FL2,f*pow(FL2,(fltype)(releaserate+(op_pt->toff>>2))))); + Bits steps = (releaserate*4 + op_pt->toff) >> 2; + op_pt->env_step_r = (1<<(steps<=12?12-steps:0))-1; + } else { + op_pt->releasemul = 1.0; + op_pt->env_step_r = 0; + } +} + +void change_sustainlevel(Bitu regbase, op_type* op_pt) { + Bits sustainlevel = adlibreg[ARC_SUSL_RELR+regbase]>>4; + // sustainlevel should be 0.0 when sustainlevel==15 (max) + if (sustainlevel<15) { + op_pt->sustain_level = (fltype)(pow(FL2,(fltype)sustainlevel * (-FL05))); + } else { + op_pt->sustain_level = 0.0; + } +} + +void change_waveform(Bitu regbase, op_type* op_pt) { +#if defined(OPLTYPE_IS_OPL3) + if (regbase>=ARC_SECONDSET) regbase -= (ARC_SECONDSET-22); // second set starts at 22 +#endif + // waveform selection + op_pt->cur_wmask = wavemask[wave_sel[regbase]]; + op_pt->cur_wform = &wavtable[waveform[wave_sel[regbase]]]; + // (might need to be adapted to waveform type here...) +} + +void change_keepsustain(Bitu regbase, op_type* op_pt) { + op_pt->sus_keep = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x20)>0; + if (op_pt->op_state==OF_TYPE_SUS) { + if (!op_pt->sus_keep) op_pt->op_state = OF_TYPE_SUS_NOKEEP; + } else if (op_pt->op_state==OF_TYPE_SUS_NOKEEP) { + if (op_pt->sus_keep) op_pt->op_state = OF_TYPE_SUS; + } +} + +// enable/disable vibrato/tremolo LFO effects +void change_vibrato(Bitu regbase, op_type* op_pt) { + op_pt->vibrato = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x40)!=0; + op_pt->tremolo = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x80)!=0; +} + +// change amount of self-feedback +void change_feedback(Bitu chanbase, op_type* op_pt) { + Bits feedback = adlibreg[ARC_FEEDBACK+chanbase]&14; + if (feedback) op_pt->mfbi = (Bit32s)(pow(FL2,(fltype)((feedback>>1)+8))); + else op_pt->mfbi = 0; +} + +void change_frequency(Bitu chanbase, Bitu regbase, op_type* op_pt) { + // frequency + Bit32u frn = ((((Bit32u)adlibreg[ARC_KON_BNUM+chanbase])&3)<<8) + (Bit32u)adlibreg[ARC_FREQ_NUM+chanbase]; + // block number/octave + Bit32u oct = ((((Bit32u)adlibreg[ARC_KON_BNUM+chanbase])>>2)&7); + op_pt->freq_high = (Bit32s)((frn>>7)&7); + + // keysplit + Bit32u note_sel = (adlibreg[8]>>6)&1; + op_pt->toff = ((frn>>9)&(note_sel^1)) | ((frn>>8)¬e_sel); + op_pt->toff += (oct<<1); + + // envelope scaling (KSR) + if (!(adlibreg[ARC_TVS_KSR_MUL+regbase]&0x10)) op_pt->toff >>= 2; + + // 20+a0+b0: + op_pt->tinc = (Bit32u)((((fltype)(frn<>6]*kslev[oct][frn>>6]); + op_pt->vol = (fltype)(pow(FL2,(fltype)(vol_in * -0.125 - 14))); + + // operator frequency changed, care about features that depend on it + change_attackrate(regbase,op_pt); + change_decayrate(regbase,op_pt); + change_releaserate(regbase,op_pt); +} + +void enable_operator(Bitu regbase, op_type* op_pt, Bit32u act_type) { + // check if this is really an off-on transition + if (op_pt->act_state == OP_ACT_OFF) { + Bits wselbase = regbase; + if (wselbase>=ARC_SECONDSET) wselbase -= (ARC_SECONDSET-22); // second set starts at 22 + + op_pt->tcount = wavestart[wave_sel[wselbase]]*FIXEDPT; + + // start with attack mode + op_pt->op_state = OF_TYPE_ATT; + op_pt->act_state |= act_type; + } +} + +void disable_operator(op_type* op_pt, Bit32u act_type) { + // check if this is really an on-off transition + if (op_pt->act_state != OP_ACT_OFF) { + op_pt->act_state &= (~act_type); + if (op_pt->act_state == OP_ACT_OFF) { + if (op_pt->op_state != OF_TYPE_OFF) op_pt->op_state = OF_TYPE_REL; + } + } +} + +void adlib_init(Bit32u samplerate) { + Bits i, j, oct; + + int_samplerate = samplerate; + + generator_add = (Bit32u)(INTFREQU*FIXEDPT/int_samplerate); + + + memset((void *)adlibreg,0,sizeof(adlibreg)); + memset((void *)op,0,sizeof(op_type)*MAXOPERATORS); + memset((void *)wave_sel,0,sizeof(wave_sel)); + + for (i=0;i=0;i--) { + frqmul[i] = (fltype)(frqmul_tab[i]*INTFREQU/(fltype)WAVEPREC*(fltype)FIXEDPT*recipsamp); + } + + status = 0; + opl_index = 0; + + + // create vibrato table + vib_table[0] = 8; + vib_table[1] = 4; + vib_table[2] = 0; + vib_table[3] = -4; + for (i=4; i -0.5/6 to 0) + for (i=14; i<41; i++) trem_table_int[i] = -i+14; // downwards (26 to 0 -> 0 to -1/6) + for (i=41; i<53; i++) trem_table_int[i] = i-40-26; // upwards (1 to 12 -> -1/6 to -0.5/6) + + for (i=0; i>1);i++) { + wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1) )*PI*2/WAVEPREC)); + wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1)+1)*PI*2/WAVEPREC)); + wavtable[i] = wavtable[(i<<1) +WAVEPREC]; + // alternative: (zero-less) +/* wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<2)+1)*PI/WAVEPREC)); + wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<2)+3)*PI/WAVEPREC)); + wavtable[i] = wavtable[(i<<1)-1+WAVEPREC]; */ + } + for (i=0;i<(WAVEPREC>>3);i++) { + wavtable[i+(WAVEPREC<<1)] = wavtable[i+(WAVEPREC>>3)]-16384; + wavtable[i+((WAVEPREC*17)>>3)] = wavtable[i+(WAVEPREC>>2)]+16384; + } + + // key scale level table verified ([table in book]*8/3) + kslev[7][0] = 0; kslev[7][1] = 24; kslev[7][2] = 32; kslev[7][3] = 37; + kslev[7][4] = 40; kslev[7][5] = 43; kslev[7][6] = 45; kslev[7][7] = 47; + kslev[7][8] = 48; + for (i=9;i<16;i++) kslev[7][i] = (Bit8u)(i+41); + for (j=6;j>=0;j--) { + for (i=0;i<16;i++) { + oct = (Bits)kslev[j+1][i]-8; + if (oct < 0) oct = 0; + kslev[j][i] = (Bit8u)oct; + } + } + } + +} + + + +void adlib_write(Bitu idx, Bit8u val) { + Bit32u second_set = idx&0x100; + adlibreg[idx] = val; + + switch (idx&0xf0) { + case ARC_CONTROL: + // here we check for the second set registers, too: + switch (idx) { + case 0x02: // timer1 counter + case 0x03: // timer2 counter + break; + case 0x04: + // IRQ reset, timer mask/start + if (val&0x80) { + // clear IRQ bits in status register + status &= ~0x60; + } else { + status = 0; + } + break; +#if defined(OPLTYPE_IS_OPL3) + case 0x04|ARC_SECONDSET: + // 4op enable/disable switches for each possible channel + op[0].is_4op = (val&1)>0; + op[3].is_4op_attached = op[0].is_4op; + op[1].is_4op = (val&2)>0; + op[4].is_4op_attached = op[1].is_4op; + op[2].is_4op = (val&4)>0; + op[5].is_4op_attached = op[2].is_4op; + op[18].is_4op = (val&8)>0; + op[21].is_4op_attached = op[18].is_4op; + op[19].is_4op = (val&16)>0; + op[22].is_4op_attached = op[19].is_4op; + op[20].is_4op = (val&32)>0; + op[23].is_4op_attached = op[20].is_4op; + break; + case 0x05|ARC_SECONDSET: + break; +#endif + case 0x08: + // CSW, note select + break; + default: + break; + } + break; + case ARC_TVS_KSR_MUL: + case ARC_TVS_KSR_MUL+0x10: { + // tremolo/vibrato/sustain keeping enabled; key scale rate; frequency multiplication + int num = idx&7; + Bitu base = (idx-ARC_TVS_KSR_MUL)&0xff; + if ((num<6) && (base<22)) { + Bitu modop = regbase2modop[second_set?(base+22):base]; + Bitu regbase = base+second_set; + Bitu chanbase = second_set?(modop-18+ARC_SECONDSET):modop; + + // change tremolo/vibrato and sustain keeping of this operator + op_type* op_ptr = &op[modop+((num<3) ? 0 : 9)]; + change_keepsustain(regbase,op_ptr); + change_vibrato(regbase,op_ptr); + + // change frequency calculations of this operator as + // key scale rate and frequency multiplicator can be changed +#if defined(OPLTYPE_IS_OPL3) + if ((adlibreg[0x105]&1) && (op[modop].is_4op_attached)) { + // operator uses frequency of channel + change_frequency(chanbase-3,regbase,op_ptr); + } else { + change_frequency(chanbase,regbase,op_ptr); + } +#else + change_frequency(chanbase,base,op_ptr); +#endif + } + } + break; + case ARC_KSL_OUTLEV: + case ARC_KSL_OUTLEV+0x10: { + // key scale level; output rate + int num = idx&7; + Bitu base = (idx-ARC_KSL_OUTLEV)&0xff; + if ((num<6) && (base<22)) { + Bitu modop = regbase2modop[second_set?(base+22):base]; + Bitu chanbase = second_set?(modop-18+ARC_SECONDSET):modop; + + // change frequency calculations of this operator as + // key scale level and output rate can be changed + op_type* op_ptr = &op[modop+((num<3) ? 0 : 9)]; +#if defined(OPLTYPE_IS_OPL3) + Bitu regbase = base+second_set; + if ((adlibreg[0x105]&1) && (op[modop].is_4op_attached)) { + // operator uses frequency of channel + change_frequency(chanbase-3,regbase,op_ptr); + } else { + change_frequency(chanbase,regbase,op_ptr); + } +#else + change_frequency(chanbase,base,op_ptr); +#endif + } + } + break; + case ARC_ATTR_DECR: + case ARC_ATTR_DECR+0x10: { + // attack/decay rates + int num = idx&7; + Bitu base = (idx-ARC_ATTR_DECR)&0xff; + if ((num<6) && (base<22)) { + Bitu regbase = base+second_set; + + // change attack rate and decay rate of this operator + op_type* op_ptr = &op[regbase2op[second_set?(base+22):base]]; + change_attackrate(regbase,op_ptr); + change_decayrate(regbase,op_ptr); + } + } + break; + case ARC_SUSL_RELR: + case ARC_SUSL_RELR+0x10: { + // sustain level; release rate + int num = idx&7; + Bitu base = (idx-ARC_SUSL_RELR)&0xff; + if ((num<6) && (base<22)) { + Bitu regbase = base+second_set; + + // change sustain level and release rate of this operator + op_type* op_ptr = &op[regbase2op[second_set?(base+22):base]]; + change_releaserate(regbase,op_ptr); + change_sustainlevel(regbase,op_ptr); + } + } + break; + case ARC_FREQ_NUM: { + // 0xa0-0xa8 low8 frequency + Bitu base = (idx-ARC_FREQ_NUM)&0xff; + if (base<9) { + Bits opbase = second_set?(base+18):base; +#if defined(OPLTYPE_IS_OPL3) + if ((adlibreg[0x105]&1) && op[opbase].is_4op_attached) break; +#endif + // regbase of modulator: + Bits modbase = modulatorbase[base]+second_set; + + Bitu chanbase = base+second_set; + + change_frequency(chanbase,modbase,&op[opbase]); + change_frequency(chanbase,modbase+3,&op[opbase+9]); +#if defined(OPLTYPE_IS_OPL3) + // for 4op channels all four operators are modified to the frequency of the channel + if ((adlibreg[0x105]&1) && op[second_set?(base+18):base].is_4op) { + change_frequency(chanbase,modbase+8,&op[opbase+3]); + change_frequency(chanbase,modbase+3+8,&op[opbase+3+9]); + } +#endif + } + } + break; + case ARC_KON_BNUM: { + if (idx == ARC_PERC_MODE) { +#if defined(OPLTYPE_IS_OPL3) + if (second_set) return; +#endif + + if ((val&0x30) == 0x30) { // BassDrum active + enable_operator(16,&op[6],OP_ACT_PERC); + change_frequency(6,16,&op[6]); + enable_operator(16+3,&op[6+9],OP_ACT_PERC); + change_frequency(6,16+3,&op[6+9]); + } else { + disable_operator(&op[6],OP_ACT_PERC); + disable_operator(&op[6+9],OP_ACT_PERC); + } + if ((val&0x28) == 0x28) { // Snare active + enable_operator(17+3,&op[16],OP_ACT_PERC); + change_frequency(7,17+3,&op[16]); + } else { + disable_operator(&op[16],OP_ACT_PERC); + } + if ((val&0x24) == 0x24) { // TomTom active + enable_operator(18,&op[8],OP_ACT_PERC); + change_frequency(8,18,&op[8]); + } else { + disable_operator(&op[8],OP_ACT_PERC); + } + if ((val&0x22) == 0x22) { // Cymbal active + enable_operator(18+3,&op[8+9],OP_ACT_PERC); + change_frequency(8,18+3,&op[8+9]); + } else { + disable_operator(&op[8+9],OP_ACT_PERC); + } + if ((val&0x21) == 0x21) { // Hihat active + enable_operator(17,&op[7],OP_ACT_PERC); + change_frequency(7,17,&op[7]); + } else { + disable_operator(&op[7],OP_ACT_PERC); + } + + break; + } + // regular 0xb0-0xb8 + Bitu base = (idx-ARC_KON_BNUM)&0xff; + if (base<9) { + Bits opbase = second_set?(base+18):base; +#if defined(OPLTYPE_IS_OPL3) + if ((adlibreg[0x105]&1) && op[opbase].is_4op_attached) break; +#endif + // regbase of modulator: + Bits modbase = modulatorbase[base]+second_set; + + if (val&32) { + // operator switched on + enable_operator(modbase,&op[opbase],OP_ACT_NORMAL); // modulator (if 2op) + enable_operator(modbase+3,&op[opbase+9],OP_ACT_NORMAL); // carrier (if 2op) +#if defined(OPLTYPE_IS_OPL3) + // for 4op channels all four operators are switched on + if ((adlibreg[0x105]&1) && op[opbase].is_4op) { + // turn on chan+3 operators as well + enable_operator(modbase+8,&op[opbase+3],OP_ACT_NORMAL); + enable_operator(modbase+3+8,&op[opbase+3+9],OP_ACT_NORMAL); + } +#endif + } else { + // operator switched off + disable_operator(&op[opbase],OP_ACT_NORMAL); + disable_operator(&op[opbase+9],OP_ACT_NORMAL); +#if defined(OPLTYPE_IS_OPL3) + // for 4op channels all four operators are switched off + if ((adlibreg[0x105]&1) && op[opbase].is_4op) { + // turn off chan+3 operators as well + disable_operator(&op[opbase+3],OP_ACT_NORMAL); + disable_operator(&op[opbase+3+9],OP_ACT_NORMAL); + } +#endif + } + + Bitu chanbase = base+second_set; + + // change frequency calculations of modulator and carrier (2op) as + // the frequency of the channel has changed + change_frequency(chanbase,modbase,&op[opbase]); + change_frequency(chanbase,modbase+3,&op[opbase+9]); +#if defined(OPLTYPE_IS_OPL3) + // for 4op channels all four operators are modified to the frequency of the channel + if ((adlibreg[0x105]&1) && op[second_set?(base+18):base].is_4op) { + // change frequency calculations of chan+3 operators as well + change_frequency(chanbase,modbase+8,&op[opbase+3]); + change_frequency(chanbase,modbase+3+8,&op[opbase+3+9]); + } +#endif + } + } + break; + case ARC_FEEDBACK: { + // 0xc0-0xc8 feedback/modulation type (AM/FM) + Bitu base = (idx-ARC_FEEDBACK)&0xff; + if (base<9) { + Bits opbase = second_set?(base+18):base; + Bitu chanbase = base+second_set; + change_feedback(chanbase,&op[opbase]); +#if defined(OPLTYPE_IS_OPL3) + // OPL3 panning + op[opbase].left_pan = ((val&0x10)>>4); + op[opbase].right_pan = ((val&0x20)>>5); +#endif + } + } + break; + case ARC_WAVE_SEL: + case ARC_WAVE_SEL+0x10: { + int num = idx&7; + Bitu base = (idx-ARC_WAVE_SEL)&0xff; + if ((num<6) && (base<22)) { +#if defined(OPLTYPE_IS_OPL3) + Bits wselbase = second_set?(base+22):base; // for easier mapping onto wave_sel[] + // change waveform + if (adlibreg[0x105]&1) wave_sel[wselbase] = val&7; // opl3 mode enabled, all waveforms accessible + else wave_sel[wselbase] = val&3; + op_type* op_ptr = &op[regbase2modop[wselbase]+((num<3) ? 0 : 9)]; + change_waveform(wselbase,op_ptr); +#else + if (adlibreg[0x01]&0x20) { + // wave selection enabled, change waveform + wave_sel[base] = val&3; + op_type* op_ptr = &op[regbase2modop[base]+((num<3) ? 0 : 9)]; + change_waveform(base,op_ptr); + } +#endif + } + } + break; + default: + break; + } +} + + +Bitu adlib_reg_read(Bitu port) { +#if defined(OPLTYPE_IS_OPL3) + // opl3-detection routines require ret&6 to be zero + if ((port&1)==0) { + return status; + } + return 0x00; +#else + // opl2-detection routines require ret&6 to be 6 + if ((port&1)==0) { + return status|6; + } + return 0xff; +#endif +} + +void adlib_write_index(Bitu port, Bit8u val) { + (void) port; + opl_index = val; +#if defined(OPLTYPE_IS_OPL3) + if ((port&3)!=0) { + // possibly second set + if (((adlibreg[0x105]&1)!=0) || (opl_index==5)) opl_index |= ARC_SECONDSET; + } +#endif +} + +OPL_INLINE static void clipit16(Bit32s ival, Bit16s* outval) { + if (ival<32768) { + if (ival>-32769) { + *outval=(Bit16s)ival; + } else { + *outval = -32768; + } + } else { + *outval = 32767; + } +} + + + +// be careful with this +// uses cptr and chanval, outputs into outbufl(/outbufr) +// for opl3 check if opl3-mode is enabled (which uses stereo panning) +#undef CHANVAL_OUT +#if defined(OPLTYPE_IS_OPL3) +#define CHANVAL_OUT \ + if (adlibreg[0x105]&1) { \ + outbufl[i] += chanval*cptr[0].left_pan; \ + outbufr[i] += chanval*cptr[0].right_pan; \ + } else { \ + outbufl[i] += chanval; \ + } +#else +#define CHANVAL_OUT \ + outbufl[i] += chanval; +#endif + +void adlib_getsample(Bit16s* sndptr, Bits numsamples) { + Bits i, endsamples; + op_type* cptr; + + Bit32s outbufl[BLOCKBUF_SIZE]; +#if defined(OPLTYPE_IS_OPL3) + // second output buffer (right channel for opl3 stereo) + Bit32s outbufr[BLOCKBUF_SIZE]; +#endif + + // vibrato/tremolo lookup tables (global, to possibly be used by all operators) + Bit32s vib_lut[BLOCKBUF_SIZE]; + Bit32s trem_lut[BLOCKBUF_SIZE]; + + Bits samples_to_process = numsamples; + + for (Bits cursmp=0; cursmpBLOCKBUF_SIZE) endsamples = BLOCKBUF_SIZE; + + memset((void*)&outbufl,0,endsamples*sizeof(Bit32s)); +#if defined(OPLTYPE_IS_OPL3) + // clear second output buffer (opl3 stereo) + if (adlibreg[0x105]&1) memset((void*)&outbufr,0,endsamples*sizeof(Bit32s)); +#endif + + // calculate vibrato/tremolo lookup tables + Bit32s vib_tshift = ((adlibreg[ARC_PERC_MODE]&0x40)==0) ? 1 : 0; // 14cents/7cents switching + for (i=0;i=VIBTAB_SIZE) vibtab_pos-=VIBTAB_SIZE*FIXEDPT_LFO; + vib_lut[i] = vib_table[vibtab_pos/FIXEDPT_LFO]>>vib_tshift; // 14cents (14/100 of a semitone) or 7cents + + // cycle through tremolo table + tremtab_pos += tremtab_add; + if (tremtab_pos/FIXEDPT_LFO>=TREMTAB_SIZE) tremtab_pos-=TREMTAB_SIZE*FIXEDPT_LFO; + if (adlibreg[ARC_PERC_MODE]&0x80) trem_lut[i] = trem_table[tremtab_pos/FIXEDPT_LFO]; + else trem_lut[i] = trem_table[TREMTAB_SIZE+tremtab_pos/FIXEDPT_LFO]; + } + + if (adlibreg[ARC_PERC_MODE]&0x20) { + //BassDrum + cptr = &op[6]; + if (adlibreg[ARC_FEEDBACK+6]&1) { + // additive synthesis + if (cptr[9].op_state != OF_TYPE_OFF) { + if (cptr[9].vibrato) { + vibval1 = vibval_var1; + for (i=0;i=0; cur_ch--) { + // skip drum/percussion operators + if ((adlibreg[ARC_PERC_MODE]&0x20) && (cur_ch >= 6) && (cur_ch < 9)) continue; + + Bitu k = cur_ch; +#if defined(OPLTYPE_IS_OPL3) + if (cur_ch < 9) { + cptr = &op[cur_ch]; + } else { + cptr = &op[cur_ch+9]; // second set is operator18-operator35 + k += (-9+256); // second set uses registers 0x100 onwards + } + // check if this operator is part of a 4-op + if ((adlibreg[0x105]&1) && cptr->is_4op_attached) continue; +#else + cptr = &op[cur_ch]; +#endif + + // check for FM/AM + if (adlibreg[ARC_FEEDBACK+k]&1) { +#if defined(OPLTYPE_IS_OPL3) + if ((adlibreg[0x105]&1) && cptr->is_4op) { + if (adlibreg[ARC_FEEDBACK+k+3]&1) { + // AM-AM-style synthesis (op1[fb] + (op2 * op3) + op4) + if (cptr[0].op_state != OF_TYPE_OFF) { + if (cptr[0].vibrato) { + vibval1 = vibval_var1; + for (i=0;iis_4op) { + if (adlibreg[ARC_FEEDBACK+k+3]&1) { + // FM-AM-style synthesis ((op1[fb] * op2) + (op3 * op4)) + if ((cptr[0].op_state != OF_TYPE_OFF) || (cptr[9].op_state != OF_TYPE_OFF)) { + if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { + vibval1 = vibval_var1; + for (i=0;i +#include +typedef uintptr_t Bitu; +typedef intptr_t Bits; +typedef uint32_t Bit32u; +typedef int32_t Bit32s; +typedef uint16_t Bit16u; +typedef int16_t Bit16s; +typedef uint8_t Bit8u; +typedef int8_t Bit8s; + + +/* + define attribution that inlines/forces inlining of a function (optional) +*/ +#define OPL_INLINE inline + + +#undef NUM_CHANNELS +#if defined(OPLTYPE_IS_OPL3) +#define NUM_CHANNELS 18 +#else +#define NUM_CHANNELS 9 +#endif + +#define MAXOPERATORS (NUM_CHANNELS*2) + + +#define FL05 ((fltype)0.5) +#define FL2 ((fltype)2.0) +#define PI ((fltype)3.1415926535897932384626433832795) + + +#define FIXEDPT 0x10000 // fixed-point calculations using 16+16 +#define FIXEDPT_LFO 0x1000000 // fixed-point calculations using 8+24 + +#define WAVEPREC 1024 // waveform precision (10 bits) + +#define INTFREQU ((fltype)(14318180.0 / 288.0)) // clocking of the chip + + +#define OF_TYPE_ATT 0 +#define OF_TYPE_DEC 1 +#define OF_TYPE_REL 2 +#define OF_TYPE_SUS 3 +#define OF_TYPE_SUS_NOKEEP 4 +#define OF_TYPE_OFF 5 + +#define ARC_CONTROL 0x00 +#define ARC_TVS_KSR_MUL 0x20 +#define ARC_KSL_OUTLEV 0x40 +#define ARC_ATTR_DECR 0x60 +#define ARC_SUSL_RELR 0x80 +#define ARC_FREQ_NUM 0xa0 +#define ARC_KON_BNUM 0xb0 +#define ARC_PERC_MODE 0xbd +#define ARC_FEEDBACK 0xc0 +#define ARC_WAVE_SEL 0xe0 + +#define ARC_SECONDSET 0x100 // second operator set for OPL3 + + +#define OP_ACT_OFF 0x00 +#define OP_ACT_NORMAL 0x01 // regular channel activated (bitmasked) +#define OP_ACT_PERC 0x02 // percussion channel activated (bitmasked) + +#define BLOCKBUF_SIZE 512 + + +// vibrato constants +#define VIBTAB_SIZE 8 +#define VIBFAC 70/50000 // no braces, integer mul/div + +// tremolo constants and table +#define TREMTAB_SIZE 53 +#define TREM_FREQ ((fltype)(3.7)) // tremolo at 3.7hz + + +/* operator struct definition + For OPL2 all 9 channels consist of two operators each, carrier and modulator. + Channel x has operators x as modulator and operators (9+x) as carrier. + For OPL3 all 18 channels consist either of two operators (2op mode) or four + operators (4op mode) which is determined through register4 of the second + adlib register set. + Only the channels 0,1,2 (first set) and 9,10,11 (second set) can act as + 4op channels. The two additional operators for a channel y come from the + 2op channel y+3 so the operatorss y, (9+y), y+3, (9+y)+3 make up a 4op + channel. +*/ +typedef struct operator_struct { + Bit32s cval, lastcval; // current output/last output (used for feedback) + Bit32u tcount, wfpos, tinc; // time (position in waveform) and time increment + fltype amp, step_amp; // and amplification (envelope) + fltype vol; // volume + fltype sustain_level; // sustain level + Bit32s mfbi; // feedback amount + fltype a0, a1, a2, a3; // attack rate function coefficients + fltype decaymul, releasemul; // decay/release rate functions + Bit32u op_state; // current state of operator (attack/decay/sustain/release/off) + Bit32u toff; + Bit32s freq_high; // highest three bits of the frequency, used for vibrato calculations + Bit16s* cur_wform; // start of selected waveform + Bit32u cur_wmask; // mask for selected waveform + Bit32u act_state; // activity state (regular, percussion) + bool sus_keep; // keep sustain level when decay finished + bool vibrato,tremolo; // vibrato/tremolo enable bits + + // variables used to provide non-continuous envelopes + Bit32u generator_pos; // for non-standard sample rates we need to determine how many samples have passed + Bits cur_env_step; // current (standardized) sample position + Bits env_step_a,env_step_d,env_step_r; // number of std samples of one step (for attack/decay/release mode) + Bit8u step_skip_pos_a; // position of 8-cyclic step skipping (always 2^x to check against mask) + Bits env_step_skip_a; // bitmask that determines if a step is skipped (respective bit is zero then) + +#if defined(OPLTYPE_IS_OPL3) + bool is_4op,is_4op_attached; // base of a 4op channel/part of a 4op channel + Bit32s left_pan,right_pan; // opl3 stereo panning amount +#endif +} op_type; + +// per-chip variables +Bitu chip_num; +op_type op[MAXOPERATORS]; + +Bits int_samplerate; + +Bit8u status; +Bit32u opl_index; +#if defined(OPLTYPE_IS_OPL3) +Bit8u adlibreg[512]; // adlib register set (including second set) +Bit8u wave_sel[44]; // waveform selection +#else +Bit8u adlibreg[256]; // adlib register set +Bit8u wave_sel[22]; // waveform selection +#endif + + +// vibrato/tremolo increment/counter +Bit32u vibtab_pos; +Bit32u vibtab_add; +Bit32u tremtab_pos; +Bit32u tremtab_add; + + +// enable an operator +void enable_operator(Bitu regbase, op_type* op_pt, Bit32u act_type); + +// functions to change parameters of an operator +void change_frequency(Bitu chanbase, Bitu regbase, op_type* op_pt); + +void change_attackrate(Bitu regbase, op_type* op_pt); +void change_decayrate(Bitu regbase, op_type* op_pt); +void change_releaserate(Bitu regbase, op_type* op_pt); +void change_sustainlevel(Bitu regbase, op_type* op_pt); +void change_waveform(Bitu regbase, op_type* op_pt); +void change_keepsustain(Bitu regbase, op_type* op_pt); +void change_vibrato(Bitu regbase, op_type* op_pt); +void change_feedback(Bitu chanbase, op_type* op_pt); + +// general functions +void adlib_init(Bit32u samplerate); +void adlib_write(Bitu idx, Bit8u val); +void adlib_getsample(Bit16s* sndptr, Bits numsamples); + +Bitu adlib_reg_read(Bitu port); +void adlib_write_index(Bitu port, Bit8u val); + +#endif /* OPL_H */ + +#define opl_init() adlib_init(OUTPUT_QUALITY * 11025) +#define opl_write(reg, val) adlib_write(reg, val) +#define opl_update(buf, num) adlib_getsample(buf, num) diff --git a/project/jni/application/opentyrian/src/palette.c b/project/jni/application/opentyrian/src/palette.c index 1a4b2d859..a28effa4a 100644 --- a/project/jni/application/opentyrian/src/palette.c +++ b/project/jni/application/opentyrian/src/palette.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -26,7 +26,13 @@ static Uint32 rgb_to_yuv( int r, int g, int b ); -Palette palettes[23]; +#ifdef TYRIAN2000 +#define PALETTE_COUNT 24 +#else +#define PALETTE_COUNT 23 +#endif + +Palette palettes[PALETTE_COUNT]; int palette_count; static Palette palette; @@ -39,7 +45,7 @@ void JE_loadPals( void ) FILE *f = dir_fopen_die(data_dir(), "palette.dat", "rb"); palette_count = ftell_eof(f) / (256 * 3); - assert(palette_count == 23); // game assumes 23 palettes + assert(palette_count == PALETTE_COUNT); for (int p = 0; p < palette_count; ++p) { @@ -211,4 +217,3 @@ static Uint32 rgb_to_yuv( int r, int g, int b ) return (y << 16) + (u << 8) + v; } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/palette.h b/project/jni/application/opentyrian/src/palette.h index fbeae7e03..7d62d8782 100644 --- a/project/jni/application/opentyrian/src/palette.h +++ b/project/jni/application/opentyrian/src/palette.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -49,4 +49,3 @@ void fade_white( int steps ); #endif /* PALETTE_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/params.c b/project/jni/application/opentyrian/src/params.c index 251f48f6e..99a10229d 100644 --- a/project/jni/application/opentyrian/src/params.c +++ b/project/jni/application/opentyrian/src/params.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -65,7 +65,8 @@ void JE_paramCheck( int argc, char *argv[] ) { 0, 0, NULL, false} }; - Option option = { 0, NULL, 0 }; + + Option option; for (; ; ) { @@ -263,4 +264,3 @@ void JE_paramCheck( int argc, char *argv[] ) } } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/params.h b/project/jni/application/opentyrian/src/params.h index 29640aebb..9bdca8906 100644 --- a/project/jni/application/opentyrian/src/params.h +++ b/project/jni/application/opentyrian/src/params.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -27,4 +27,3 @@ void JE_paramCheck( int argc, char *argv[] ); #endif /* PARAMS_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/pcxload.c b/project/jni/application/opentyrian/src/pcxload.c index 7d2560839..7f5795e58 100644 --- a/project/jni/application/opentyrian/src/pcxload.c +++ b/project/jni/application/opentyrian/src/pcxload.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -64,4 +64,3 @@ void JE_loadPCX( const char *file ) // this is only meant to load tshp2.pcx fclose(f); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/pcxload.h b/project/jni/application/opentyrian/src/pcxload.h index 77da856ab..c4bb8b731 100644 --- a/project/jni/application/opentyrian/src/pcxload.h +++ b/project/jni/application/opentyrian/src/pcxload.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -25,4 +25,3 @@ void JE_loadPCX( const char *file ); #endif /* PCXLOAD_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/pcxmast.c b/project/jni/application/opentyrian/src/pcxmast.c index 488a563b8..c492399d0 100644 --- a/project/jni/application/opentyrian/src/pcxmast.c +++ b/project/jni/application/opentyrian/src/pcxmast.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -46,4 +46,3 @@ const JE_byte facepal[12] = /* [1..12] */ JE_pcxpostype pcxpos; -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/pcxmast.h b/project/jni/application/opentyrian/src/pcxmast.h index 7881795e9..4ab96c071 100644 --- a/project/jni/application/opentyrian/src/pcxmast.h +++ b/project/jni/application/opentyrian/src/pcxmast.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -33,4 +33,3 @@ extern JE_pcxpostype pcxpos; #endif /* PCXMAST_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/picload.c b/project/jni/application/opentyrian/src/picload.c index 66243c191..f27cb6cc2 100644 --- a/project/jni/application/opentyrian/src/picload.c +++ b/project/jni/application/opentyrian/src/picload.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -84,4 +84,3 @@ void JE_loadPic(SDL_Surface *screen, JE_byte PCXnumber, JE_boolean storepal ) set_palette(colors, 0, 255); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/picload.h b/project/jni/application/opentyrian/src/picload.h index bd2745934..2cab83ffe 100644 --- a/project/jni/application/opentyrian/src/picload.h +++ b/project/jni/application/opentyrian/src/picload.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -25,4 +25,3 @@ void JE_loadPic(SDL_Surface *screen, JE_byte PCXnumber, JE_boolean storepal ); #endif /* PICLOAD_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/player.c b/project/jni/application/opentyrian/src/player.c index e8ab7f18d..bfaa1ff61 100644 --- a/project/jni/application/opentyrian/src/player.c +++ b/project/jni/application/opentyrian/src/player.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or diff --git a/project/jni/application/opentyrian/src/player.h b/project/jni/application/opentyrian/src/player.h index ef060f4e8..b74d2170b 100644 --- a/project/jni/application/opentyrian/src/player.h +++ b/project/jni/application/opentyrian/src/player.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or diff --git a/project/jni/application/opentyrian/src/scroller.c b/project/jni/application/opentyrian/src/scroller.c index 62e39c8a4..f01461e7a 100644 --- a/project/jni/application/opentyrian/src/scroller.c +++ b/project/jni/application/opentyrian/src/scroller.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -32,6 +32,8 @@ #include "vga256d.h" #include "video.h" +#include + const struct about_text_type about_text[] = { {0x30, "----- ~OpenTyrian~ -----"}, @@ -54,9 +56,9 @@ const struct about_text_type about_text[] = {0x0e, "the game and reporting bugs."}, {0x00, ""}, {0x00, ""}, - {0x05, "Thanks to ~MAME~ and ~DOSBox~"}, - {0x05, "for the FM emulator and"}, - {0x05, "~AdPlug~ for the Loudness code."}, + {0x05, "Thanks to ~DOSBox~ for the"}, + {0x05, "FM-Synthesis emulator and"}, + {0x05, "~AdPlug~ for the Loudness player."}, {0x00, ""}, {0x00, ""}, {0x32, "And special thanks to ~Jason Emery~"}, @@ -154,7 +156,7 @@ void scroller_sine( const struct about_text_type text[] ) for (int i = 0; i < MAX_COINS/2; i++) { struct coin_type *coin = &coins[i]; - blit_sprite2(VGAScreen, coin->x, coin->y, eShapes5, coin_defs[coin->type].shape_num + coin->cur_frame); + blit_sprite2(VGAScreen, coin->x, coin->y, eShapes[4], coin_defs[coin->type].shape_num + coin->cur_frame); } } @@ -210,7 +212,7 @@ void scroller_sine( const struct about_text_type text[] ) for (int i = MAX_COINS/2; i < MAX_COINS; i++) { struct coin_type *coin = &coins[i]; - blit_sprite2(VGAScreen, coin->x, coin->y, eShapes5, coin_defs[coin->type].shape_num + coin->cur_frame); + blit_sprite2(VGAScreen, coin->x, coin->y, eShapes[4], coin_defs[coin->type].shape_num + coin->cur_frame); } } @@ -289,7 +291,7 @@ void scroller_sine( const struct about_text_type text[] ) } beer[i].y += beer[i].vy; - blit_sprite2x2(VGAScreen, beer[i].x, beer[i].y, eShapes5, BEER_SHAPE); + blit_sprite2x2(VGAScreen, beer[i].x, beer[i].y, eShapes[4], BEER_SHAPE); } } @@ -310,4 +312,3 @@ void scroller_sine( const struct about_text_type text[] ) fade_black(10); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/scroller.h b/project/jni/application/opentyrian/src/scroller.h index e06702b99..89ef97666 100644 --- a/project/jni/application/opentyrian/src/scroller.h +++ b/project/jni/application/opentyrian/src/scroller.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -30,4 +30,3 @@ void scroller_sine( const struct about_text_type text[] ); #endif /* SCROLLER_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/setup.c b/project/jni/application/opentyrian/src/setup.c index d5fc0936d..2b8872bb0 100644 --- a/project/jni/application/opentyrian/src/setup.c +++ b/project/jni/application/opentyrian/src/setup.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -58,7 +58,7 @@ void JE_textMenuWait( JE_word *waitTime, JE_boolean doGamma ) lastkey_sym = SDLK_RETURN; } - if (has_mouse && input_grabbed) + if (has_mouse && input_grab_enabled) { #ifdef MENU_SELECT_BY_MOUSE_MOVE /* Whacky hack which changes menu selecton based on @@ -101,4 +101,3 @@ void JE_textMenuWait( JE_word *waitTime, JE_boolean doGamma ) } while (!(inputDetected || *waitTime == 1 || haltGame)); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/setup.h b/project/jni/application/opentyrian/src/setup.h index c40b9976d..a10fba854 100644 --- a/project/jni/application/opentyrian/src/setup.h +++ b/project/jni/application/opentyrian/src/setup.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -25,4 +25,3 @@ void JE_textMenuWait( JE_word *waitTime, JE_boolean doGamma ); #endif /* SETUP_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/shots.c b/project/jni/application/opentyrian/src/shots.c new file mode 100644 index 000000000..7aa6ac541 --- /dev/null +++ b/project/jni/application/opentyrian/src/shots.c @@ -0,0 +1,499 @@ +/* + * OpenTyrian: A modern cross-platform port of Tyrian + * Copyright (C) 2007-2013 The OpenTyrian Development Team + * + * This program 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 2 + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "player.h" +#include "shots.h" +#include "sprite.h" +#include "video.h" +#include "varz.h" + +// I'm pretty sure the last extra entry is never used. +PlayerShotDataType playerShotData[MAX_PWEAPON + 1]; /* [1..MaxPWeapon+1] */ +JE_byte shotAvail[MAX_PWEAPON]; /* [1..MaxPWeapon] */ /*0:Avail 1-255:Duration left*/ + +void simulate_player_shots( void ) +{ + /* Player Shot Images */ + for (int z = 0; z < MAX_PWEAPON; z++) + { + if (shotAvail[z] != 0) + { + shotAvail[z]--; + if (z != MAX_PWEAPON - 1) + { + PlayerShotDataType* shot = &playerShotData[z]; + + shot->shotXM += shot->shotXC; + + if (shot->shotXM <= 100) + shot->shotX += shot->shotXM; + + shot->shotYM += shot->shotYC; + shot->shotY += shot->shotYM; + + if (shot->shotYM > 100) + { + shot->shotY -= 120; + shot->shotY += player[0].delta_y_shot_move; + } + + if (shot->shotComplicated != 0) + { + shot->shotDevX += shot->shotDirX; + shot->shotX += shot->shotDevX; + + if (abs(shot->shotDevX) == shot->shotCirSizeX) + shot->shotDirX = -shot->shotDirX; + + shot->shotDevY += shot->shotDirY; + shot->shotY += shot->shotDevY; + + if (abs(shot->shotDevY) == shot->shotCirSizeY) + shot->shotDirY = -shot->shotDirY; + /*Double Speed Circle Shots - add a second copy of above loop*/ + } + + int tempShotX = shot->shotX; + int tempShotY = shot->shotY; + + if (shot->shotX < 0 || shot->shotX > 140 || + shot->shotY < 0 || shot->shotY > 170) + { + shotAvail[z] = 0; + goto draw_player_shot_loop_end; + } + +/* if (shot->shotTrail != 255) + { + if (shot->shotTrail == 98) + { + JE_setupExplosion(shot->shotX - shot->shotXM, shot->shotY - shot->shotYM, shot->shotTrail); + } else { + JE_setupExplosion(shot->shotX, shot->shotY, shot->shotTrail); + } + }*/ + + JE_word anim_frame = shot->shotGr + shot->shotAni; + if (++shot->shotAni == shot->shotAniMax) + shot->shotAni = 0; + + if (anim_frame < 6000) + { + if (anim_frame > 1000) + anim_frame = anim_frame % 1000; + if (anim_frame > 500) + blit_sprite2(VGAScreen, tempShotX+1, tempShotY, shapesW2, anim_frame - 500); + else + blit_sprite2(VGAScreen, tempShotX+1, tempShotY, shapesC1, anim_frame); + } + } + +draw_player_shot_loop_end: + ; + } + } +} + +static const JE_word linkMultiGr[17] /* [0..16] */ = + {77,221,183,301,1,282,164,202,58,201,163,281,39,300,182,220,77}; +static const JE_word linkSonicGr[17] /* [0..16] */ = + {85,242,131,303,47,284,150,223,66,224,149,283,9,302,130,243,85}; +static const JE_word linkMult2Gr[17] /* [0..16] */ = + {78,299,295,297,2,278,276,280,59,279,275,277,40,296,294,298,78}; + +void player_shot_set_direction( JE_integer shot_id, uint weapon_id, JE_real direction ) +{ + PlayerShotDataType* shot = &playerShotData[shot_id]; + + shot->shotXM = -roundf(sinf(direction) * shot->shotYM); + shot->shotYM = -roundf(cosf(direction) * shot->shotYM); + + // Some weapons have sprites for each direction, use those. + int rounded_dir; + + switch (weapon_id) + { + case 27: + case 32: + case 10: + rounded_dir = roundf(direction * (16 / (2 * M_PI))); /*16 directions*/ + shot->shotGr = linkMultiGr[rounded_dir]; + break; + case 28: + case 33: + case 11: + rounded_dir = roundf(direction * (16 / (2 * M_PI))); /*16 directions*/ + shot->shotGr = linkSonicGr[rounded_dir]; + break; + case 30: + case 35: + case 14: + if (direction > M_PI_2 && direction < M_PI + M_PI_2) + { + shot->shotYC = 1; + } + break; + case 38: + case 22: + rounded_dir = roundf(direction * (16 / (2 * M_PI))); /*16 directions*/ + shot->shotGr = linkMult2Gr[rounded_dir]; + break; + } +} + +bool player_shot_move_and_draw( + int shot_id, bool* out_is_special, + int* out_shotx, int* out_shoty, + JE_integer* out_shot_damage, JE_byte* out_blast_filter, + JE_byte* out_chain, JE_byte* out_playerNum, + JE_word* out_special_radiusw, JE_word* out_special_radiush ) +{ + PlayerShotDataType* shot = &playerShotData[shot_id]; + + shotAvail[shot_id]--; + if (shot_id != MAX_PWEAPON - 1) + { + shot->shotXM += shot->shotXC; + shot->shotX += shot->shotXM; + JE_integer tmp_shotXM = shot->shotXM; + + if (shot->shotXM > 100) + { + if (shot->shotXM == 101) + { + shot->shotX -= 101; + shot->shotX += player[shot->playerNumber-1].delta_x_shot_move; + shot->shotY += player[shot->playerNumber-1].delta_y_shot_move; + } + else + { + shot->shotX -= 120; + shot->shotX += player[shot->playerNumber-1].delta_x_shot_move; + } + } + + shot->shotYM += shot->shotYC; + shot->shotY += shot->shotYM; + + if (shot->shotYM > 100) + { + shot->shotY -= 120; + shot->shotY += player[shot->playerNumber-1].delta_y_shot_move; + } + + if (shot->shotComplicated != 0) + { + shot->shotDevX += shot->shotDirX; + shot->shotX += shot->shotDevX; + + if (abs(shot->shotDevX) == shot->shotCirSizeX) + shot->shotDirX = -shot->shotDirX; + + shot->shotDevY += shot->shotDirY; + shot->shotY += shot->shotDevY; + + if (abs(shot->shotDevY) == shot->shotCirSizeY) + shot->shotDirY = -shot->shotDirY; + + /*Double Speed Circle Shots - add a second copy of above loop*/ + } + + *out_shotx = shot->shotX; + *out_shoty = shot->shotY; + + if (shot->shotX < -34 || shot->shotX > 290 || + shot->shotY < -15 || shot->shotY > 190) + { + shotAvail[shot_id] = 0; + return false; + } + + if (shot->shotTrail != 255) + { + if (shot->shotTrail == 98) + JE_setupExplosion(shot->shotX - shot->shotXM, shot->shotY - shot->shotYM, 0, shot->shotTrail, false, false); + else + JE_setupExplosion(shot->shotX, shot->shotY, 0, shot->shotTrail, false, false); + } + + if (shot->aimAtEnemy != 0) + { + if (--shot->aimDelay == 0) + { + shot->aimDelay = shot->aimDelayMax; + + if (enemyAvail[shot->aimAtEnemy - 1] != 1) + { + if (shot->shotX < enemy[shot->aimAtEnemy - 1].ex) + shot->shotXM++; + else + shot->shotXM--; + + if (shot->shotY < enemy[shot->aimAtEnemy - 1].ey) + shot->shotYM++; + else + shot->shotYM--; + } + else + { + if (shot->shotXM > 0) + shot->shotXM++; + else + shot->shotXM--; + } + } + } + + JE_word sprite_frame = shot->shotGr + shot->shotAni; + if (++shot->shotAni == shot->shotAniMax) + shot->shotAni = 0; + + *out_shot_damage = shot->shotDmg; + *out_blast_filter = shot->shotBlastFilter; + *out_chain = shot->chainReaction; + *out_playerNum = shot->playerNumber; + + *out_is_special = sprite_frame > 60000; + + if (*out_is_special) + { + blit_sprite_blend(VGAScreen, *out_shotx+1, *out_shoty, OPTION_SHAPES, sprite_frame - 60001); + + *out_special_radiusw = sprite(OPTION_SHAPES, sprite_frame - 60001)->width / 2; + *out_special_radiush = sprite(OPTION_SHAPES, sprite_frame - 60001)->height / 2; + } + else + { + if (sprite_frame > 1000) + { + JE_doSP(*out_shotx+1 + 6, *out_shoty + 6, 5, 3, (sprite_frame / 1000) << 4); + sprite_frame = sprite_frame % 1000; + } + if (sprite_frame > 500) + { + if (background2 && *out_shoty + shadowYDist < 190 && tmp_shotXM < 100) + blit_sprite2_darken(VGAScreen, *out_shotx+1, *out_shoty + shadowYDist, shapesW2, sprite_frame - 500); + blit_sprite2(VGAScreen, *out_shotx+1, *out_shoty, shapesW2, sprite_frame - 500); + } + else + { + if (background2 && *out_shoty + shadowYDist < 190 && tmp_shotXM < 100) + blit_sprite2_darken(VGAScreen, *out_shotx+1, *out_shoty + shadowYDist, shapesC1, sprite_frame); + blit_sprite2(VGAScreen, *out_shotx+1, *out_shoty, shapesC1, sprite_frame); + } + } + } + + return true; +} + +JE_integer player_shot_create( JE_word portNum, uint bay_i, JE_word PX, JE_word PY, JE_word mouseX, JE_word mouseY, JE_word wpNum, JE_byte playerNum ) +{ + static const JE_byte soundChannel[11] /* [1..11] */ = {0, 2, 4, 4, 2, 2, 5, 5, 1, 4, 1}; + + // Bounds check + if (portNum > PORT_NUM || wpNum <= 0 || wpNum > WEAP_NUM) + return MAX_PWEAPON; + + const JE_WeaponType* weapon = &weapons[wpNum]; + + if (power < weaponPort[portNum].poweruse) + return MAX_PWEAPON; + power -= weaponPort[portNum].poweruse; + + if (weapon->sound > 0) + soundQueue[soundChannel[bay_i]] = weapon->sound; + + int shot_id = MAX_PWEAPON; + /*Rot*/ + for (int multi_i = 1; multi_i <= weapon->multi; multi_i++) + { + for (shot_id = 0; shot_id < MAX_PWEAPON; shot_id++) + if (shotAvail[shot_id] == 0) + break; + if (shot_id == MAX_PWEAPON) + return MAX_PWEAPON; + + if (shotMultiPos[bay_i] == weapon->max || shotMultiPos[bay_i] > 8) + shotMultiPos[bay_i] = 1; + else + shotMultiPos[bay_i]++; + + PlayerShotDataType* shot = &playerShotData[shot_id]; + shot->chainReaction = 0; + + shot->playerNumber = playerNum; + + shot->shotAni = 0; + + shot->shotComplicated = weapon->circlesize != 0; + + if (weapon->circlesize == 0) + { + shot->shotDevX = 0; + shot->shotDirX = 0; + shot->shotDevY = 0; + shot->shotDirY = 0; + shot->shotCirSizeX = 0; + shot->shotCirSizeY = 0; + } + else + { + JE_byte circsize = weapon->circlesize; + + if (circsize > 19) + { + JE_byte circsize_mod20 = circsize % 20; + shot->shotCirSizeX = circsize_mod20; + shot->shotDevX = circsize_mod20 >> 1; + + circsize = circsize / 20; + shot->shotCirSizeY = circsize; + shot->shotDevY = circsize >> 1; + } + else + { + shot->shotCirSizeX = circsize; + shot->shotCirSizeY = circsize; + shot->shotDevX = circsize >> 1; + shot->shotDevY = circsize >> 1; + } + shot->shotDirX = 1; + shot->shotDirY = -1; + } + + shot->shotTrail = weapon->trail; + + if (weapon->attack[shotMultiPos[bay_i]-1] > 99 && weapon->attack[shotMultiPos[bay_i]-1] < 250) + { + shot->chainReaction = weapon->attack[shotMultiPos[bay_i]-1] - 100; + shot->shotDmg = 1; + } + else + { + shot->shotDmg = weapon->attack[shotMultiPos[bay_i]-1]; + } + + shot->shotBlastFilter = weapon->shipblastfilter; + + JE_integer tmp_by = weapon->by[shotMultiPos[bay_i]-1]; + + /*Note: Only front selection used for player shots...*/ + + shot->shotX = PX + weapon->bx[shotMultiPos[bay_i]-1]; + + shot->shotY = PY + tmp_by; + shot->shotYC = -weapon->acceleration; + shot->shotXC = weapon->accelerationx; + + shot->shotXM = weapon->sx[shotMultiPos[bay_i]-1]; + + // Not sure what this field does exactly. + JE_byte del = weapon->del[shotMultiPos[bay_i]-1]; + + if (del == 121) + { + shot->shotTrail = 0; + del = 255; + } + + shot->shotGr = weapon->sg[shotMultiPos[bay_i]-1]; + if (shot->shotGr == 0) + shotAvail[shot_id] = 0; + else + shotAvail[shot_id] = del; + + if (del > 100 && del < 120) + shot->shotAniMax = (del - 100 + 1); + else + shot->shotAniMax = weapon->weapani + 1; + + if (del == 99 || del == 98) + { + tmp_by = PX - mouseX; + if (tmp_by < -5) + tmp_by = -5; + else if (tmp_by > 5) + tmp_by = 5; + shot->shotXM += tmp_by; + } + + if (del == 99 || del == 100) + { + tmp_by = PY - mouseY - weapon->sy[shotMultiPos[bay_i]-1]; + if (tmp_by < -4) + tmp_by = -4; + else if (tmp_by > 4) + tmp_by = 4; + shot->shotYM = tmp_by; + } + else if (weapon->sy[shotMultiPos[bay_i]-1] == 98) + { + shot->shotYM = 0; + shot->shotYC = -1; + } + else if (weapon->sy[shotMultiPos[bay_i]-1] > 100) + { + shot->shotYM = weapon->sy[shotMultiPos[bay_i]-1]; + shot->shotY -= player[shot->playerNumber-1].delta_y_shot_move; + } + else + { + shot->shotYM = -weapon->sy[shotMultiPos[bay_i]-1]; + } + + if (weapon->sx[shotMultiPos[bay_i]-1] > 100) + { + shot->shotXM = weapon->sx[shotMultiPos[bay_i]-1]; + shot->shotX -= player[shot->playerNumber-1].delta_x_shot_move; + if (shot->shotXM == 101) + shot->shotY -= player[shot->playerNumber-1].delta_y_shot_move; + } + + + if (weapon->aim > 5) /*Guided Shot*/ + { + uint best_dist = 65000; + JE_byte closest_enemy = 0; + /*Find Closest Enemy*/ + for (x = 0; x < 100; x++) + { + if (enemyAvail[x] != 1 && !enemy[x].scoreitem) + { + y = abs(enemy[x].ex - shot->shotX) + abs(enemy[x].ey - shot->shotY); + if (y < best_dist) + { + best_dist = y; + closest_enemy = x + 1; + } + } + } + shot->aimAtEnemy = closest_enemy; + shot->aimDelay = 5; + shot->aimDelayMax = weapon->aim - 5; + } + else + { + shot->aimAtEnemy = 0; + } + + shotRepeat[bay_i] = weapon->shotrepeat; + } + + return shot_id; +} diff --git a/project/jni/application/opentyrian/src/shots.h b/project/jni/application/opentyrian/src/shots.h new file mode 100644 index 000000000..ea4a11155 --- /dev/null +++ b/project/jni/application/opentyrian/src/shots.h @@ -0,0 +1,58 @@ +/* + * OpenTyrian: A modern cross-platform port of Tyrian + * Copyright (C) 2007-2013 The OpenTyrian Development Team + * + * This program 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 2 + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef SHOTS_H +#define SHOTS_H +#include "opentyr.h" + +typedef struct { + JE_integer shotX, shotY, shotXM, shotYM, shotXC, shotYC; + JE_boolean shotComplicated; + JE_integer shotDevX, shotDirX, shotDevY, shotDirY, shotCirSizeX, shotCirSizeY; + JE_byte shotTrail; + JE_word shotGr, shotAni, shotAniMax; + Uint8 shotDmg; + JE_byte shotBlastFilter, chainReaction, playerNumber, aimAtEnemy, aimDelay, aimDelayMax; +} PlayerShotDataType; + +#define MAX_PWEAPON 81 /* 81*/ +extern PlayerShotDataType playerShotData[MAX_PWEAPON + 1]; +extern JE_byte shotAvail[MAX_PWEAPON]; + +/** Used in the shop to show weapon previews. */ +void simulate_player_shots( void ); + +/** Points shot movement in the specified direction. Used for the turret gun. */ +void player_shot_set_direction( JE_integer shot_id, uint weapon_id, JE_real direction ); + +/** Moves and draws a shot. Does \b not collide it with enemies. + * \return False if the shot went offscreen, true otherwise. + */ +bool player_shot_move_and_draw( + int shot_id, bool* out_is_special, + int* out_shotx, int* out_shoty, + JE_integer* out_shot_damage, JE_byte* out_blast_filter, + JE_byte* out_chain, JE_byte* out_playerNum, + JE_word* out_special_radiusw, JE_word* out_special_radiush ); + +/** Creates a player shot. */ +JE_integer player_shot_create( JE_word portnum, uint shot_i, JE_word px, JE_word py, + JE_word mousex, JE_word mousey, + JE_word wpnum, JE_byte playernum ); + +#endif // SHOTS_H diff --git a/project/jni/application/opentyrian/src/sizebuf.c b/project/jni/application/opentyrian/src/sizebuf.c index b32c4f0dc..11191978b 100644 --- a/project/jni/application/opentyrian/src/sizebuf.c +++ b/project/jni/application/opentyrian/src/sizebuf.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -39,6 +39,8 @@ #include #include "SDL_endian.h" +#include +#include /* Construct buffer with the passed array and size */ void SZ_Init(sizebuf_t * sz, Uint8 * buf, unsigned int size) diff --git a/project/jni/application/opentyrian/src/sizebuf.h b/project/jni/application/opentyrian/src/sizebuf.h index f3d8003b4..b12f2cb76 100644 --- a/project/jni/application/opentyrian/src/sizebuf.h +++ b/project/jni/application/opentyrian/src/sizebuf.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or diff --git a/project/jni/application/opentyrian/src/sndmast.c b/project/jni/application/opentyrian/src/sndmast.c index 3fd7eb27b..81220fe8b 100644 --- a/project/jni/application/opentyrian/src/sndmast.c +++ b/project/jni/application/opentyrian/src/sndmast.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -75,4 +75,3 @@ const JE_byte windowTextSamples[9] = /* [1..9] */ V_ENEMIES }; -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/sndmast.h b/project/jni/application/opentyrian/src/sndmast.h index 74bb2920e..1f2e502ec 100644 --- a/project/jni/application/opentyrian/src/sndmast.h +++ b/project/jni/application/opentyrian/src/sndmast.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -73,4 +73,3 @@ extern const JE_byte windowTextSamples[9]; #endif /* SNDMAST_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/sprite.c b/project/jni/application/opentyrian/src/sprite.c index 08a2f388f..fa838845b 100644 --- a/project/jni/application/opentyrian/src/sprite.c +++ b/project/jni/application/opentyrian/src/sprite.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -22,10 +22,11 @@ #include "video.h" #include +#include Sprite_array sprite_table[SPRITE_TABLES_MAX]; -Sprite2_array eShapes1, eShapes2, eShapes3, eShapes4, eShapes5, eShapes6; +Sprite2_array eShapes[6]; Sprite2_array shapesC1, shapes6, shapes9, shapesW2; void load_sprites_file( unsigned int table, const char *filename ) @@ -48,6 +49,8 @@ void load_sprites( unsigned int table, FILE *f ) sprite_table[table].count = temp; + assert(sprite_table[table].count <= SPRITES_PER_TABLE_MAX); + for (unsigned int i = 0; i < sprite_table[table].count; ++i) { Sprite * const cur_sprite = sprite(table, i); @@ -665,7 +668,11 @@ void blit_sprite2x2_darken( SDL_Surface *surface, int x, int y, Sprite2_array sp void JE_loadMainShapeTables( const char *shpfile ) { +#ifdef TYRIAN2000 + const int SHP_NUM = 13; +#else const int SHP_NUM = 12; +#endif FILE *f = dir_fopen_die(data_dir(), shpfile, "rb"); @@ -673,14 +680,14 @@ void JE_loadMainShapeTables( const char *shpfile ) JE_longint shpPos[SHP_NUM + 1]; // +1 for storing file length efread(&shpNumb, sizeof(JE_word), 1, f); - assert(shpNumb + 1u <= COUNTOF(shpPos)); + assert(shpNumb + 1u == COUNTOF(shpPos)); - for (int i = 0; i < shpNumb; i++) - { + for (unsigned int i = 0; i < shpNumb; ++i) efread(&shpPos[i], sizeof(JE_longint), 1, f); - } + fseek(f, 0, SEEK_END); - shpPos[shpNumb] = ftell(f); + for (unsigned int i = shpNumb; i < COUNTOF(shpPos); ++i) + shpPos[i] = ftell(f); int i; // fonts, interface, option sprites @@ -701,13 +708,13 @@ void JE_loadMainShapeTables( const char *shpfile ) i++; // power-up sprites - eShapes6.size = shpPos[i + 1] - shpPos[i]; - JE_loadCompShapesB(&eShapes6, f); + eShapes[5].size = shpPos[i + 1] - shpPos[i]; + JE_loadCompShapesB(&eShapes[5], f); i++; // coins, datacubes, etc sprites - eShapes5.size = shpPos[i + 1] - shpPos[i]; - JE_loadCompShapesB(&eShapes5, f); + eShapes[4].size = shpPos[i + 1] - shpPos[i]; + JE_loadCompShapesB(&eShapes[4], f); i++; // more player shot sprites @@ -724,9 +731,7 @@ void free_main_shape_tables( void ) free_sprite2s(&shapesC1); free_sprite2s(&shapes9); - free_sprite2s(&eShapes6); - free_sprite2s(&eShapes5); + free_sprite2s(&eShapes[5]); + free_sprite2s(&eShapes[4]); free_sprite2s(&shapesW2); } - -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/sprite.h b/project/jni/application/opentyrian/src/sprite.h index da9c18aaf..16109181c 100644 --- a/project/jni/application/opentyrian/src/sprite.h +++ b/project/jni/application/opentyrian/src/sprite.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -23,6 +23,7 @@ #include "SDL.h" #include +#include #define FONT_SHAPES 0 #define SMALL_FONT_SHAPES 1 @@ -34,7 +35,11 @@ #define EXTRA_SHAPES 7 /*Used for Ending pics*/ #define SPRITE_TABLES_MAX 8 +#ifdef TYRIAN2000 +#define SPRITES_PER_TABLE_MAX 152 +#else #define SPRITES_PER_TABLE_MAX 151 +#endif typedef struct { @@ -91,7 +96,7 @@ typedef struct } Sprite2_array; -extern Sprite2_array eShapes1, eShapes2, eShapes3, eShapes4, eShapes5, eShapes6; +extern Sprite2_array eShapes[6]; extern Sprite2_array shapesC1, shapes6, shapes9, shapesW2; void JE_loadCompShapes( Sprite2_array *, JE_char s ); @@ -112,4 +117,3 @@ void free_main_shape_tables( void ); #endif // SPRITE_H -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/starlib.c b/project/jni/application/opentyrian/src/starlib.c index 3ce783610..79b9b5ebf 100644 --- a/project/jni/application/opentyrian/src/starlib.c +++ b/project/jni/application/opentyrian/src/starlib.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -429,4 +429,3 @@ void JE_newStar( void ) } } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/starlib.h b/project/jni/application/opentyrian/src/starlib.h index 20859bd69..bc529d735 100644 --- a/project/jni/application/opentyrian/src/starlib.h +++ b/project/jni/application/opentyrian/src/starlib.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -30,4 +30,3 @@ void JE_newStar( void ); #endif /* STARLIB_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/tyrian2.c b/project/jni/application/opentyrian/src/tyrian2.c index 85be3d9cf..49daf4fd5 100644 --- a/project/jni/application/opentyrian/src/tyrian2.c +++ b/project/jni/application/opentyrian/src/tyrian2.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -41,6 +41,7 @@ #include "pcxmast.h" #include "picload.h" #include "setup.h" +#include "shots.h" #include "sprite.h" #include "tyrian2.h" #include "vga256d.h" @@ -158,6 +159,12 @@ void JE_starShowVGA( void ) inline static void blit_enemy( SDL_Surface *surface, unsigned int i, signed int x_offset, signed int y_offset, signed int sprite_offset ) { + if (enemy[i].sprite2s == NULL) + { + fprintf(stderr, "warning: enemy %d sprite missing\n", i); + return; + } + const int x = enemy[i].ex + x_offset + tempMapXOfs, y = enemy[i].ey + y_offset; const unsigned int index = enemy[i].egr[enemy[i].enemycycle - 1] + sprite_offset; @@ -444,66 +451,64 @@ enemy_still_exists: soundQueue[temp] = weapons[temp3].sound; } - tempPos = weapons[temp3].max; - if (enemy[i].aniactive == 2) enemy[i].aniactive = 1; - if (++enemy[i].eshotmultipos[j-1] > tempPos) + if (++enemy[i].eshotmultipos[j-1] > weapons[temp3].max) enemy[i].eshotmultipos[j-1] = 1; - tempPos = enemy[i].eshotmultipos[j-1]; + int tempPos = enemy[i].eshotmultipos[j-1] - 1; if (j == 1) temp2 = 4; - enemyShot[b].sx = tempX + weapons[temp3].bx[tempPos-1] + tempMapXOfs; - enemyShot[b].sy = tempY + weapons[temp3].by[tempPos-1]; - enemyShot[b].sdmg = weapons[temp3].attack[tempPos-1]; + enemyShot[b].sx = tempX + weapons[temp3].bx[tempPos] + tempMapXOfs; + enemyShot[b].sy = tempY + weapons[temp3].by[tempPos]; + enemyShot[b].sdmg = weapons[temp3].attack[tempPos]; enemyShot[b].tx = weapons[temp3].tx; enemyShot[b].ty = weapons[temp3].ty; - enemyShot[b].duration = weapons[temp3].del[tempPos-1]; + enemyShot[b].duration = weapons[temp3].del[tempPos]; enemyShot[b].animate = 0; enemyShot[b].animax = weapons[temp3].weapani; - enemyShot[b].sgr = weapons[temp3].sg[tempPos-1]; + enemyShot[b].sgr = weapons[temp3].sg[tempPos]; switch (j) { case 1: enemyShot[b].syc = weapons[temp3].acceleration; enemyShot[b].sxc = weapons[temp3].accelerationx; - enemyShot[b].sxm = weapons[temp3].sx[tempPos-1]; - enemyShot[b].sym = weapons[temp3].sy[tempPos-1]; + enemyShot[b].sxm = weapons[temp3].sx[tempPos]; + enemyShot[b].sym = weapons[temp3].sy[tempPos]; break; case 3: enemyShot[b].sxc = -weapons[temp3].acceleration; enemyShot[b].syc = weapons[temp3].accelerationx; - enemyShot[b].sxm = -weapons[temp3].sy[tempPos-1]; - enemyShot[b].sym = -weapons[temp3].sx[tempPos-1]; + enemyShot[b].sxm = -weapons[temp3].sy[tempPos]; + enemyShot[b].sym = -weapons[temp3].sx[tempPos]; break; case 2: enemyShot[b].sxc = weapons[temp3].acceleration; enemyShot[b].syc = -weapons[temp3].acceleration; - enemyShot[b].sxm = weapons[temp3].sy[tempPos-1]; - enemyShot[b].sym = -weapons[temp3].sx[tempPos-1]; + enemyShot[b].sxm = weapons[temp3].sy[tempPos]; + enemyShot[b].sym = -weapons[temp3].sx[tempPos]; break; } if (weapons[temp3].aim > 0) { - temp4 = weapons[temp3].aim; + int aim = weapons[temp3].aim; /*DIF*/ if (difficultyLevel > 2) { - temp4 += difficultyLevel - 2; + aim += difficultyLevel - 2; } - tempX2 = player[0].x; - tempY2 = player[0].y; + JE_word target_x = player[0].x; + JE_word target_y = player[0].y; if (twoPlayerMode) { @@ -517,23 +522,20 @@ enemy_still_exists: if (temp == 1) { - tempX2 = player[1].x - 25; - tempY2 = player[1].y; + target_x = player[1].x - 25; + target_y = player[1].y; } } - tempI = (tempX2 + 25) - tempX - tempMapXOfs - 4; - if (tempI == 0) - tempI++; - tempI2 = tempY2 - tempY; - if (tempI2 == 0) - tempI2++; - if (abs(tempI) > abs(tempI2)) - tempI3 = abs(tempI); - else - tempI3 = abs(tempI2); - enemyShot[b].sxm = roundf(((float)tempI / tempI3) * temp4); - enemyShot[b].sym = roundf(((float)tempI2 / tempI3) * temp4); + int relative_x = (target_x + 25) - tempX - tempMapXOfs - 4; + if (relative_x == 0) + relative_x = 1; + int relative_y = target_y - tempY; + if (relative_y == 0) + relative_y = 1; + const int longest_side = MAX(abs(relative_x), abs(relative_y)); + enemyShot[b].sxm = roundf((float)relative_x / longest_side * aim); + enemyShot[b].sym = roundf((float)relative_y / longest_side * aim); } } break; @@ -565,38 +567,35 @@ enemy_still_exists: goto draw_enemy_end; tempW = enemy[i].launchtype; - JE_newEnemy(enemyOffset == 50 ? 75 : enemyOffset - 25); + b = JE_newEnemy(enemyOffset == 50 ? 75 : enemyOffset - 25, tempW, 0); /*Launch Enemy Placement*/ if (b > 0) { - tempI = tempX; - tempI2 = tempY + enemyDat[enemy[b-1].enemytype].startyc; - if (enemy[b-1].size == 0) + struct JE_SingleEnemyType* e = &enemy[b-1]; + + e->ex = tempX; + e->ey = tempY + enemyDat[e->enemytype].startyc; + if (e->size == 0) + e->ey -= 7; + + if (e->launchtype > 0 && e->launchfreq == 0) { - tempI -= 0; - tempI2 -= 7; - } - if (enemy[b-1].launchtype > 0 && enemy[b-1].launchfreq == 0) - { - if (enemy[b-1].launchtype > 90) + if (e->launchtype > 90) { - tempI += mt_rand() % ((enemy[b-1].launchtype - 90) * 4) - (enemy[b-1].launchtype - 90) * 2; + e->ex += mt_rand() % ((e->launchtype - 90) * 4) - (e->launchtype - 90) * 2; } else { - tempI4 = (player[0].x + 25) - tempX - tempMapXOfs - 4; - if (tempI4 == 0) - tempI4++; + int target_x = (player[0].x + 25) - tempX - tempMapXOfs - 4; + if (target_x == 0) + target_x = 1; int tempI5 = player[0].y - tempY; if (tempI5 == 0) - tempI5++; - if (abs(tempI4) > abs(tempI5)) - tempI3 = abs(tempI4); - else - tempI3 = abs(tempI5); - enemy[b-1].exc = roundf(((float)tempI4 / tempI3) * enemy[b-1].launchtype); - enemy[b-1].eyc = roundf(((float)tempI5 / tempI3) * enemy[b-1].launchtype); + tempI5 = 1; + const int longest_side = MAX(abs(target_x), abs(tempI5)); + e->exc = roundf(((float)target_x / longest_side) * e->launchtype); + e->eyc = roundf(((float)tempI5 / longest_side) * e->launchtype); } } @@ -608,11 +607,8 @@ enemy_still_exists: if (enemy[i].launchspecial == 1 && enemy[i].linknum < 100) { - enemy[b-1].linknum = enemy[i].linknum; + e->linknum = enemy[i].linknum; } - - enemy[b-1].ex = tempI; - enemy[b-1].ey = tempI2; } } } @@ -626,10 +622,6 @@ draw_enemy_end: void JE_main( void ) { - int i; - - Uint8 *s; /* screen pointer, 8-bit specific */ - char buffer[256]; int lastEnemyOnScreen; @@ -657,10 +649,10 @@ start_level: JE_clearKeyboard(); - free_sprite2s(&eShapes1); - free_sprite2s(&eShapes2); - free_sprite2s(&eShapes3); - free_sprite2s(&eShapes4); + free_sprite2s(&eShapes[0]); + free_sprite2s(&eShapes[1]); + free_sprite2s(&eShapes[2]); + free_sprite2s(&eShapes[3]); /* Normal speed */ if (fastPlay != 0) @@ -743,7 +735,7 @@ start_level_first: player[i].is_alive = true; oldDifficultyLevel = difficultyLevel; - if (episodeNum == 4) + if (episodeNum == EPISODE_AVAILABLE) difficultyLevel--; if (difficultyLevel < 1) difficultyLevel = 1; @@ -808,11 +800,10 @@ start_level_first: backPos2 = 0; backPos3 = 0; power = 0; - starY = VGAScreen->pitch; + starfield_speed = 1; /* Setup player ship graphics */ JE_getShipInfo(); - tempI = (((player[0].x - mouseX) / 2) * 2) * 168; // is this used for anything? for (uint i = 0; i < COUNTOF(player); ++i) { @@ -866,8 +857,6 @@ start_level_first: forceEvents = false; /*Force events to continue if background movement = 0*/ - uniqueEnemy = false; /*Look in MakeEnemy under shape bank*/ - superEnemy254Jump = 0; /*When Enemy with PL 254 dies*/ /* Filter Status */ @@ -920,13 +909,15 @@ start_level_first: newkey = false; +#ifdef WITH_NETWORK if (isNetworkGame) { JE_clearSpecialRequests(); mt_srand(32402394); } +#endif - JE_setupStars(); + initialize_starfield(); JE_setNewGameSpeed(); @@ -1306,42 +1297,9 @@ level_loop: } } - /*---------------------------STARS--------------------------*/ - /* DRAWSTARS */ if (starActive || astralDuration > 0) { - s = (Uint8 *)VGAScreen->pixels; - - for (i = MAX_STARS; i--; ) - { - starDat[i].sLoc += starDat[i].sMov + starY; - if (starDat[i].sLoc < 177 * VGAScreen->pitch) - { - if (*(s + starDat[i].sLoc) == 0) - { - *(s + starDat[i].sLoc) = starDat[i].sC; - } - if (starDat[i].sC - 4 >= 9 * 16) - { - if (*(s + starDat[i].sLoc + 1) == 0) - { - *(s + starDat[i].sLoc + 1) = starDat[i].sC - 4; - } - if (starDat[i].sLoc > 0 && *(s + starDat[i].sLoc - 1) == 0) - { - *(s + starDat[i].sLoc - 1) = starDat[i].sC - 4; - } - if (*(s + starDat[i].sLoc + VGAScreen->pitch) == 0) - { - *(s + starDat[i].sLoc + VGAScreen->pitch) = starDat[i].sC - 4; - } - if (starDat[i].sLoc >= VGAScreen->pitch && *(s + starDat[i].sLoc - VGAScreen->pitch) == 0) - { - *(s + starDat[i].sLoc - VGAScreen->pitch) = starDat[i].sC - 4; - } - } - } - } + update_and_draw_starfield(VGAScreen, starfield_speed); } if (processorType > 1 && smoothies[5-1]) @@ -1435,7 +1393,7 @@ level_loop: tempW = levelEnemy[mt_rand() % levelEnemyMax]; if (tempW == 2) soundQueue[3] = S_WEAPON_7; - JE_newEnemy(0); + b = JE_newEnemy(0, tempW, 0); } if (processorType > 1 && smoothies[3-1]) @@ -1483,140 +1441,14 @@ level_loop: { bool is_special = false; int tempShotX = 0, tempShotY = 0; - - shotAvail[z]--; - if (z != MAX_PWEAPON - 1) + JE_byte chain; + JE_byte playerNum; + JE_word tempX2, tempY2; + JE_integer damage; + + if (!player_shot_move_and_draw(z, &is_special, &tempShotX, &tempShotY, &damage, &temp2, &chain, &playerNum, &tempX2, &tempY2)) { - - playerShotData[z].shotXM += playerShotData[z].shotXC; - playerShotData[z].shotX += playerShotData[z].shotXM; - tempI4 = playerShotData[z].shotXM; - - if (playerShotData[z].shotXM > 100) - { - if (playerShotData[z].shotXM == 101) - { - playerShotData[z].shotX -= 101; - playerShotData[z].shotX += player[playerShotData[z].playerNumber-1].delta_x_shot_move; - playerShotData[z].shotY += player[playerShotData[z].playerNumber-1].delta_y_shot_move; - } - else - { - playerShotData[z].shotX -= 120; - playerShotData[z].shotX += player[playerShotData[z].playerNumber-1].delta_x_shot_move; - } - } - - playerShotData[z].shotYM += playerShotData[z].shotYC; - playerShotData[z].shotY += playerShotData[z].shotYM; - - if (playerShotData[z].shotYM > 100) - { - playerShotData[z].shotY -= 120; - playerShotData[z].shotY += player[playerShotData[z].playerNumber-1].delta_y_shot_move; - } - - if (playerShotData[z].shotComplicated != 0) - { - playerShotData[z].shotDevX += playerShotData[z].shotDirX; - playerShotData[z].shotX += playerShotData[z].shotDevX; - - if (abs(playerShotData[z].shotDevX) == playerShotData[z].shotCirSizeX) - playerShotData[z].shotDirX = -playerShotData[z].shotDirX; - - playerShotData[z].shotDevY += playerShotData[z].shotDirY; - playerShotData[z].shotY += playerShotData[z].shotDevY; - - if (abs(playerShotData[z].shotDevY) == playerShotData[z].shotCirSizeY) - playerShotData[z].shotDirY = -playerShotData[z].shotDirY; - - /*Double Speed Circle Shots - add a second copy of above loop*/ - } - - tempShotX = playerShotData[z].shotX; - tempShotY = playerShotData[z].shotY; - - if (playerShotData[z].shotX < -34 || playerShotData[z].shotX > 290 || - playerShotData[z].shotY < -15 || playerShotData[z].shotY > 190) - { - shotAvail[z] = 0; - goto draw_player_shot_loop_end; - } - - if (playerShotData[z].shotTrail != 255) - { - if (playerShotData[z].shotTrail == 98) - JE_setupExplosion(playerShotData[z].shotX - playerShotData[z].shotXM, playerShotData[z].shotY - playerShotData[z].shotYM, 0, playerShotData[z].shotTrail, false, false); - else - JE_setupExplosion(playerShotData[z].shotX, playerShotData[z].shotY, 0, playerShotData[z].shotTrail, false, false); - } - - if (playerShotData[z].aimAtEnemy != 0) - { - if (--playerShotData[z].aimDelay == 0) - { - playerShotData[z].aimDelay = playerShotData[z].aimDelayMax; - - if (enemyAvail[playerShotData[z].aimAtEnemy] != 1) - { - if (playerShotData[z].shotX < enemy[playerShotData[z].aimAtEnemy].ex) - playerShotData[z].shotXM++; - else - playerShotData[z].shotXM--; - - if (playerShotData[z].shotY < enemy[playerShotData[z].aimAtEnemy].ey) - playerShotData[z].shotYM++; - else - playerShotData[z].shotYM--; - } - else - { - if (playerShotData[z].shotXM > 0) - playerShotData[z].shotXM++; - else - playerShotData[z].shotXM--; - } - } - } - - tempW = playerShotData[z].shotGr + playerShotData[z].shotAni; - if (++playerShotData[z].shotAni == playerShotData[z].shotAniMax) - playerShotData[z].shotAni = 0; - - tempI2 = playerShotData[z].shotDmg; - temp2 = playerShotData[z].shotBlastFilter; - chain = playerShotData[z].chainReaction; - playerNum = playerShotData[z].playerNumber; - - is_special = tempW > 60000; - - if (is_special) - { - blit_sprite_blend(VGAScreen, tempShotX+1, tempShotY, OPTION_SHAPES, tempW - 60001); - - tempX2 = sprite(OPTION_SHAPES, tempW - 60001)->width / 2; - tempY2 = sprite(OPTION_SHAPES, tempW - 60001)->height / 2; - } - else - { - if (tempW > 1000) - { - JE_doSP(tempShotX+1 + 6, tempShotY + 6, 5, 3, (tempW / 1000) << 4); - tempW = tempW % 1000; - } - if (tempW > 500) - { - if (background2 && tempShotY + shadowYDist < 190 && tempI4 < 100) - blit_sprite2_darken(VGAScreen, tempShotX+1, tempShotY + shadowYDist, shapesW2, tempW - 500); - blit_sprite2(VGAScreen, tempShotX+1, tempShotY, shapesW2, tempW - 500); - } - else - { - if (background2 && tempShotY + shadowYDist < 190 && tempI4 < 100) - blit_sprite2_darken(VGAScreen, tempShotX+1, tempShotY + shadowYDist, shapesC1, tempW); - blit_sprite2(VGAScreen, tempShotX+1, tempShotY, shapesC1, tempW); - } - } + goto draw_player_shot_loop_end; } for (b = 0; b < 100; b++) @@ -1631,7 +1463,7 @@ level_loop: collided = abs(enemy[b].ex + enemy[b].mapoffset - (player[0].x + 7)) < temp; temp2 = 9; chain = 0; - tempI2 = 10; + damage = 10; } else if (is_special) { @@ -1655,30 +1487,30 @@ level_loop: if (chain > 0) { shotMultiPos[SHOT_MISC] = 0; - JE_initPlayerShot(0, SHOT_MISC, tempShotX, tempShotY, mouseX, mouseY, chain, playerNum); + b = player_shot_create(0, SHOT_MISC, tempShotX, tempShotY, mouseX, mouseY, chain, playerNum); shotAvail[z] = 0; goto draw_player_shot_loop_end; } infiniteShot = false; - if (tempI2 == 99) + if (damage == 99) { - tempI2 = 0; + damage = 0; doIced = 40; enemy[b].iced = 40; } else { doIced = 0; - if (tempI2 >= 250) + if (damage >= 250) { - tempI2 = tempI2 - 250; + damage = damage - 250; infiniteShot = true; } } - tempI = enemy[b].armorleft; + int armorleft = enemy[b].armorleft; temp = enemy[b].linknum; if (temp == 0) @@ -1706,24 +1538,24 @@ level_loop: } } - if (tempI > tempI2) + if (armorleft > damage) { if (z != MAX_PWEAPON - 1) { if (enemy[b].armorleft != 255) { - enemy[b].armorleft -= tempI2; + enemy[b].armorleft -= damage; JE_setupExplosion(tempShotX, tempShotY, 0, 0, false, false); } else { - JE_doSP(tempShotX + 6, tempShotY + 6, tempI2 / 2 + 3, tempI2 / 4 + 2, temp2); + JE_doSP(tempShotX + 6, tempShotY + 6, damage / 2 + 3, damage / 4 + 2, temp2); } } soundQueue[5] = S_ENEMY_HIT; - if ((tempI - tempI2 <= enemy[b].edlevel) && + if ((armorleft - damage <= enemy[b].edlevel) && ((!enemy[b].edamaged) ^ (enemy[b].edani < 0))) { @@ -1731,16 +1563,16 @@ level_loop: { if (enemyAvail[temp3] != 1) { - temp4 = enemy[temp3].linknum; + int linknum = enemy[temp3].linknum; if ( (temp3 == b) || ( (temp != 255) && ( - ((enemy[temp3].edlevel > 0) && (temp4 == temp)) || + ((enemy[temp3].edlevel > 0) && (linknum == temp)) || ( - (enemyContinualDamage && (temp - 100 == temp4)) || - ((temp4 > 40) && (temp4 / 20 == temp / 20) && (temp4 <= temp)) + (enemyContinualDamage && (temp - 100 == linknum)) || + ((linknum > 40) && (linknum / 20 == temp / 20) && (linknum <= temp)) ) ) ) @@ -1806,10 +1638,13 @@ level_loop: || ((temp3 > 40) && (temp3 / 20 == temp / 20) && (temp3 <= temp))))) { - tempI3 = enemy[temp2].ex + enemy[temp2].mapoffset; + int enemy_screen_x = enemy[temp2].ex + enemy[temp2].mapoffset; if (enemy[temp2].special) - globalFlags[enemy[temp2].flagnum] = enemy[temp2].setto; + { + assert((unsigned int) enemy[temp2].flagnum-1 < COUNTOF(globalFlags)); + globalFlags[enemy[temp2].flagnum-1] = enemy[temp2].setto; + } if ((enemy[temp2].enemydie > 0) && !((superArcadeMode != SA_NONE) && @@ -1817,12 +1652,12 @@ level_loop: { int temp_b = b; tempW = enemy[temp2].enemydie; - tempW2 = temp2 - (temp2 % 25); + int enemy_offset = temp2 - (temp2 % 25); if (enemyDat[tempW].value > 30000) { - tempW2 = 0; + enemy_offset = 0; } - JE_newEnemy(tempW2); + b = JE_newEnemy(enemy_offset, tempW, 0); if (b != 0) { if ((superArcadeMode != SA_NONE) && (enemy[b-1].evalue > 30000)) { @@ -1875,12 +1710,12 @@ level_loop: if (enemyDat[enemy[temp2].enemytype].esize == 1) { - JE_setupExplosionLarge(enemy[temp2].enemyground, enemy[temp2].explonum, tempI3, enemy[temp2].ey); + JE_setupExplosionLarge(enemy[temp2].enemyground, enemy[temp2].explonum, enemy_screen_x, enemy[temp2].ey); soundQueue[6] = S_EXPLOSION_9; } else { - JE_setupExplosion(tempI3, enemy[temp2].ey, 0, 1, false, false); + JE_setupExplosion(enemy_screen_x, enemy[temp2].ey, 0, 1, false, false); soundQueue[6] = S_SELECT; // S_EXPLOSION_8 } } @@ -1890,21 +1725,20 @@ level_loop: if (infiniteShot) { - tempI2 += 250; + damage += 250; } else if (z != MAX_PWEAPON - 1) { - if (tempI2 <= tempI) + if (damage <= armorleft) { shotAvail[z] = 0; goto draw_player_shot_loop_end; } else { - playerShotData[z].shotDmg -= tempI; + playerShotData[z].shotDmg -= armorleft; } } - } } } @@ -2157,7 +1991,7 @@ draw_player_shot_loop_end: if ((player[0].is_alive && player[0].armor < 6) || (twoPlayerMode && !galagaMode && player[1].is_alive && player[1].armor < 6)) { - tempW2 = (player[0].is_alive && player[0].armor < 6) ? player[0].armor : player[1].armor; + int armor_amount = (player[0].is_alive && player[0].armor < 6) ? player[0].armor : player[1].armor; if (armorShipDelay > 0) { @@ -2166,7 +2000,7 @@ draw_player_shot_loop_end: else { tempW = 560; - JE_newEnemy(50); + b = JE_newEnemy(50, tempW, 0); if (b > 0) { enemy[b-1].enemydie = 560 + (mt_rand() % 3) + 1; @@ -2180,7 +2014,7 @@ draw_player_shot_loop_end: (twoPlayerMode && player[1].is_alive && player[1].armor < 6 && (!isNetworkGame || thisPlayerNum == 2))) { - tempW = tempW2 * 4 + 8; + tempW = armor_amount * 4 + 8; if (warningSoundDelay > tempW) warningSoundDelay = tempW; @@ -2195,10 +2029,10 @@ draw_player_shot_loop_end: } warningCol += warningColChange; - if (warningCol > 113 + (14 - (tempW2 * 2))) + if (warningCol > 113 + (14 - (armor_amount * 2))) { warningColChange = -warningColChange; - warningCol = 113 + (14 - (tempW2 * 2)); + warningCol = 113 + (14 - (armor_amount * 2)); } else if (warningCol < 113) { @@ -2416,6 +2250,7 @@ draw_player_shot_loop_end: } /*Network Update*/ +#ifdef WITH_NETWORK if (isNetworkGame) { if (!reallyEndLevel) @@ -2461,10 +2296,10 @@ draw_player_shot_loop_end: } if (requests & 8) // nortship { - player[0].items.ship = 12; - player[0].items.special = 13; - player[0].items.weapon[FRONT_WEAPON].id = 36; - player[0].items.weapon[REAR_WEAPON].id = 37; + player[0].items.ship = 12; // Nort Ship + player[0].items.special = 13; // Astral Zone + player[0].items.weapon[FRONT_WEAPON].id = 36; // NortShip Super Pulse + player[0].items.weapon[REAR_WEAPON].id = 37; // NortShip Spreader shipGr = 1; } @@ -2483,6 +2318,7 @@ draw_player_shot_loop_end: JE_clearSpecialRequests(); } +#endif /** Test **/ JE_drawSP(); @@ -3171,6 +3007,18 @@ new_game: temp = atoi(strnztcpy(buffer, s + 3, 3)); play_song(temp - 1); break; + +#ifdef TYRIAN2000 + case 'T': + /* TODO: Timed Battle ]T[ 43 44 45 46 47 */ + printf("]T[ 43 44 45 46 47 handle timed battle!"); + break; + + case 'q': + /* TODO: Timed Battle end */ + printf("handle timed battle end flag!"); + break; +#endif } } @@ -3352,14 +3200,15 @@ new_game: bool JE_titleScreen( JE_boolean animate ) { bool quit = false; -#ifdef ANDROID - const JE_shortint menunum = 5; // Quit not possible, Android manages life cycle! - const JE_byte menu_top = 96, menu_spacing = 16; + +#ifdef TYRIAN2000 + const int menunum = 6; #else - const JE_shortint menunum = 6; - const JE_byte menu_top = 96, menu_spacing = 14; + const int menunum = 7; #endif + const int menu_top = 96, menu_spacing = 14; + #ifdef ANDROID // Show text input button in main menu, to make entering cheats possible SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, 1); @@ -3368,7 +3217,7 @@ bool JE_titleScreen( JE_boolean animate ) unsigned int arcade_code_i[SA_ENGAGE] = { 0 }; JE_word waitForDemo; - JE_shortint menu = 0; + int menu = 0; JE_boolean redraw = true, fadeIn = false; @@ -3383,6 +3232,7 @@ bool JE_titleScreen( JE_boolean animate ) gameLoaded = false; jumpSection = false; +#ifdef WITH_NETWORK if (isNetworkGame) { JE_loadPic(VGAScreen, 2, false); @@ -3449,7 +3299,7 @@ bool JE_titleScreen( JE_boolean animate ) for (uint i = 0; i < COUNTOF(player); ++i) player[i].cash = 0; - player[0].items.ship = 11; + player[0].items.ship = 11; // Silver Ship while (!network_is_sync()) { @@ -3461,6 +3311,7 @@ bool JE_titleScreen( JE_boolean animate ) } } else +#endif { do { @@ -3700,9 +3551,11 @@ bool JE_titleScreen( JE_boolean animate ) { case 0: /* New game */ fade_black(10); - if (select_gameplay() && select_episode() && select_difficulty()) + + if (select_gameplay()) { - gameLoaded = true; + if (select_episode() && select_difficulty()) + gameLoaded = true; initialDifficulty = difficultyLevel; @@ -3710,15 +3563,17 @@ bool JE_titleScreen( JE_boolean animate ) { player[0].cash = 0; - player[0].items.ship = 8; + player[0].items.ship = 8; // Stalker } else if (twoPlayerMode) { for (uint i = 0; i < COUNTOF(player); ++i) player[i].cash = 0; - - player[0].items.ship = 11; + + player[0].items.ship = 11; // Silver Ship + difficultyLevel++; + inputDevice[0] = 1; inputDevice[1] = 2; } @@ -3728,9 +3583,11 @@ bool JE_titleScreen( JE_boolean animate ) } else { - ulong initial_cash[] = { 10000, 15000, 20000, 30000 }; + // allows player to smuggle arcade/super-arcade ships into full game + + ulong initial_cash[] = { 10000, 15000, 20000, 30000, 35000 }; - assert(episodeNum >= 1 && episodeNum <= 4); + assert(episodeNum >= 1 && episodeNum <= EPISODE_AVAILABLE); player[0].cash = initial_cash[episodeNum-1]; } } @@ -3752,12 +3609,18 @@ bool JE_titleScreen( JE_boolean animate ) opentyrian_menu(); fadeIn = true; break; +#ifdef TYRIAN2000 + case 5: /* Quit */ + quit = true; + break; +#else case 5: /* Demo */ play_demo = true; break; case 6: /* Quit */ quit = true; break; +#endif } redraw = true; break; @@ -3889,73 +3752,53 @@ void JE_displayText( void ) levelWarningDisplay = false; } -void JE_newEnemy( int enemyOffset ) +Sint16 JE_newEnemy( int enemyOffset, Uint16 eDatI, Sint16 uniqueShapeTableI ) { - b = 0; // stupid global - - for (int i = enemyOffset; i < enemyOffset + 25; i++) + for (int i = enemyOffset; i < enemyOffset + 25; ++i) { if (enemyAvail[i] == 1) { - b = i+1; - enemyAvail[b-1] = JE_makeEnemy(&enemy[b-1]); - break; + enemyAvail[i] = JE_makeEnemy(&enemy[i], eDatI, uniqueShapeTableI); + return i + 1; } } + + return 0; } -uint JE_makeEnemy( struct JE_SingleEnemyType *enemy ) // tempW, uniqueEnemy, tempI2, b +uint JE_makeEnemy( struct JE_SingleEnemyType *enemy, Uint16 eDatI, Sint16 uniqueShapeTableI ) { - uint a; + uint avail; - JE_byte temp; - int t = 0; + JE_byte shapeTableI; - if (superArcadeMode != SA_NONE && tempW == 534) - tempW = 533; + if (superArcadeMode != SA_NONE && eDatI == 534) + eDatI = 533; enemyShapeTables[5-1] = 21; /*Coins&Gems*/ enemyShapeTables[6-1] = 26; /*Two-Player Stuff*/ - if (uniqueEnemy) + if (uniqueShapeTableI > 0) { - temp = tempI2; - uniqueEnemy = false; + shapeTableI = uniqueShapeTableI; } else { - temp = enemyDat[tempW].shapebank; + shapeTableI = enemyDat[eDatI].shapebank; } - + + Sprite2_array *sprite2s = NULL; for (uint i = 0; i < 6; ++i) - { - if (temp == enemyShapeTables[i]) - { - switch (i) - { - case 0: - enemy->sprite2s = &eShapes1; - break; - case 1: - enemy->sprite2s = &eShapes2; - break; - case 2: - enemy->sprite2s = &eShapes3; - break; - case 3: - enemy->sprite2s = &eShapes4; - break; - case 4: - enemy->sprite2s = &eShapes5; - break; - case 5: - enemy->sprite2s = &eShapes6; - break; - } - } - } + if (shapeTableI == enemyShapeTables[i]) + sprite2s = &eShapes[i]; + + if (sprite2s != NULL) + enemy->sprite2s = sprite2s; + else + // maintain buggy Tyrian behavior (use shape table value from previous enemy that occupied this index in the enemy array) + fprintf(stderr, "warning: ignoring sprite from unloaded shape table %d\n", shapeTableI); - enemy->enemydatofs = &enemyDat[tempW]; + enemy->enemydatofs = &enemyDat[eDatI]; enemy->mapoffset = 0; @@ -3964,17 +3807,16 @@ uint JE_makeEnemy( struct JE_SingleEnemyType *enemy ) // tempW, uniqueEnemy, tem enemy->eshotmultipos[i] = 0; } - temp4 = enemyDat[tempW].explosiontype; - enemy->enemyground = ((temp4 & 0x01) == 0); - enemy->explonum = temp4 / 2; + enemy->enemyground = (enemyDat[eDatI].explosiontype & 1) == 0; + enemy->explonum = enemyDat[eDatI].explosiontype >> 1; - enemy->launchfreq = enemyDat[tempW].elaunchfreq; - enemy->launchwait = enemyDat[tempW].elaunchfreq; - enemy->launchtype = enemyDat[tempW].elaunchtype % 1000; - enemy->launchspecial = enemyDat[tempW].elaunchtype / 1000; + enemy->launchfreq = enemyDat[eDatI].elaunchfreq; + enemy->launchwait = enemyDat[eDatI].elaunchfreq; + enemy->launchtype = enemyDat[eDatI].elaunchtype % 1000; + enemy->launchspecial = enemyDat[eDatI].elaunchtype / 1000; - enemy->xaccel = enemyDat[tempW].xaccel; - enemy->yaccel = enemyDat[tempW].yaccel; + enemy->xaccel = enemyDat[eDatI].xaccel; + enemy->yaccel = enemyDat[eDatI].yaccel; enemy->xminbounce = -10000; enemy->xmaxbounce = 10000; @@ -3984,13 +3826,13 @@ uint JE_makeEnemy( struct JE_SingleEnemyType *enemy ) // tempW, uniqueEnemy, tem for (uint i = 0; i < 3; ++i) { - enemy->tur[i] = enemyDat[tempW].tur[i]; + enemy->tur[i] = enemyDat[eDatI].tur[i]; } - enemy->ani = enemyDat[tempW].ani; + enemy->ani = enemyDat[eDatI].ani; enemy->animin = 1; - switch (enemyDat[tempW].animate) + switch (enemyDat[eDatI].animate) { case 0: enemy->enemycycle = 1; @@ -4012,20 +3854,20 @@ uint JE_makeEnemy( struct JE_SingleEnemyType *enemy ) // tempW, uniqueEnemy, tem break; } - if (enemyDat[tempW].startxc != 0) - enemy->ex = enemyDat[tempW].startx + (mt_rand() % (enemyDat[tempW].startxc * 2)) - enemyDat[tempW].startxc + 1; + if (enemyDat[eDatI].startxc != 0) + enemy->ex = enemyDat[eDatI].startx + (mt_rand() % (enemyDat[eDatI].startxc * 2)) - enemyDat[eDatI].startxc + 1; else - enemy->ex = enemyDat[tempW].startx + 1; + enemy->ex = enemyDat[eDatI].startx + 1; - if (enemyDat[tempW].startyc != 0) - enemy->ey = enemyDat[tempW].starty + (mt_rand() % (enemyDat[tempW].startyc * 2)) - enemyDat[tempW].startyc + 1; + if (enemyDat[eDatI].startyc != 0) + enemy->ey = enemyDat[eDatI].starty + (mt_rand() % (enemyDat[eDatI].startyc * 2)) - enemyDat[eDatI].startyc + 1; else - enemy->ey = enemyDat[tempW].starty + 1; + enemy->ey = enemyDat[eDatI].starty + 1; - enemy->exc = enemyDat[tempW].xmove; - enemy->eyc = enemyDat[tempW].ymove; - enemy->excc = enemyDat[tempW].xcaccel; - enemy->eycc = enemyDat[tempW].ycaccel; + enemy->exc = enemyDat[eDatI].xmove; + enemy->eyc = enemyDat[eDatI].ymove; + enemy->excc = enemyDat[eDatI].xcaccel; + enemy->eycc = enemyDat[eDatI].ycaccel; enemy->exccw = abs(enemy->excc); enemy->exccwmax = enemy->exccw; enemy->eyccw = abs(enemy->eycc); @@ -4035,24 +3877,24 @@ uint JE_makeEnemy( struct JE_SingleEnemyType *enemy ) // tempW, uniqueEnemy, tem enemy->special = false; enemy->iced = 0; - if (enemyDat[tempW].xrev == 0) + if (enemyDat[eDatI].xrev == 0) enemy->exrev = 100; - else if (enemyDat[tempW].xrev == -99) + else if (enemyDat[eDatI].xrev == -99) enemy->exrev = 0; else - enemy->exrev = enemyDat[tempW].xrev; + enemy->exrev = enemyDat[eDatI].xrev; - if (enemyDat[tempW].yrev == 0) + if (enemyDat[eDatI].yrev == 0) enemy->eyrev = 100; - else if (enemyDat[tempW].yrev == -99) + else if (enemyDat[eDatI].yrev == -99) enemy->eyrev = 0; else - enemy->eyrev = enemyDat[tempW].yrev; + enemy->eyrev = enemyDat[eDatI].yrev; enemy->exca = (enemy->xaccel > 0) ? 1 : -1; enemy->eyca = (enemy->yaccel > 0) ? 1 : -1; - enemy->enemytype = tempW; + enemy->enemytype = eDatI; for (uint i = 0; i < 3; ++i) { @@ -4064,125 +3906,126 @@ uint JE_makeEnemy( struct JE_SingleEnemyType *enemy ) // tempW, uniqueEnemy, tem enemy->eshotwait[i] = 255; } for (uint i = 0; i < 20; ++i) - enemy->egr[i] = enemyDat[tempW].egraphic[i]; - enemy->size = enemyDat[tempW].esize; + enemy->egr[i] = enemyDat[eDatI].egraphic[i]; + enemy->size = enemyDat[eDatI].esize; enemy->linknum = 0; - enemy->edamaged = enemyDat[tempW].dani < 0; - enemy->enemydie = enemyDat[tempW].eenemydie; + enemy->edamaged = enemyDat[eDatI].dani < 0; + enemy->enemydie = enemyDat[eDatI].eenemydie; - enemy->freq[1-1] = enemyDat[tempW].freq[1-1]; - enemy->freq[2-1] = enemyDat[tempW].freq[2-1]; - enemy->freq[3-1] = enemyDat[tempW].freq[3-1]; + enemy->freq[1-1] = enemyDat[eDatI].freq[1-1]; + enemy->freq[2-1] = enemyDat[eDatI].freq[2-1]; + enemy->freq[3-1] = enemyDat[eDatI].freq[3-1]; - enemy->edani = enemyDat[tempW].dani; - enemy->edgr = enemyDat[tempW].dgr; - enemy->edlevel = enemyDat[tempW].dlevel; + enemy->edani = enemyDat[eDatI].dani; + enemy->edgr = enemyDat[eDatI].dgr; + enemy->edlevel = enemyDat[eDatI].dlevel; enemy->fixedmovey = 0; enemy->filter = 0x00; - if (enemyDat[tempW].value > 1 && enemyDat[tempW].value < 10000) + int tempValue = 0; + if (enemyDat[eDatI].value > 1 && enemyDat[eDatI].value < 10000) { switch (difficultyLevel) { case -1: case 0: - t = enemyDat[tempW].value * 0.75f; + tempValue = enemyDat[eDatI].value * 0.75f; break; case 1: case 2: - t = enemyDat[tempW].value; + tempValue = enemyDat[eDatI].value; break; case 3: - t = enemyDat[tempW].value * 1.125f; + tempValue = enemyDat[eDatI].value * 1.125f; break; case 4: - t = enemyDat[tempW].value * 1.5f; + tempValue = enemyDat[eDatI].value * 1.5f; break; case 5: - t = enemyDat[tempW].value * 2; + tempValue = enemyDat[eDatI].value * 2; break; case 6: - t = enemyDat[tempW].value * 2.5f; + tempValue = enemyDat[eDatI].value * 2.5f; break; case 7: case 8: - t = enemyDat[tempW].value * 4; + tempValue = enemyDat[eDatI].value * 4; break; case 9: case 10: - t = enemyDat[tempW].value * 8; + tempValue = enemyDat[eDatI].value * 8; break; } - if (t > 10000) - t = 10000; - enemy->evalue = t; + if (tempValue > 10000) + tempValue = 10000; + enemy->evalue = tempValue; } else { - enemy->evalue = enemyDat[tempW].value; + enemy->evalue = enemyDat[eDatI].value; } - t = 1; - if (enemyDat[tempW].armor > 0) + int tempArmor = 1; + if (enemyDat[eDatI].armor > 0) { - if (enemyDat[tempW].armor != 255) + if (enemyDat[eDatI].armor != 255) { switch (difficultyLevel) { case -1: case 0: - t = enemyDat[tempW].armor * 0.5f + 1; + tempArmor = enemyDat[eDatI].armor * 0.5f + 1; break; case 1: - t = enemyDat[tempW].armor * 0.75f + 1; + tempArmor = enemyDat[eDatI].armor * 0.75f + 1; break; case 2: - t = enemyDat[tempW].armor; + tempArmor = enemyDat[eDatI].armor; break; case 3: - t = enemyDat[tempW].armor * 1.2f; + tempArmor = enemyDat[eDatI].armor * 1.2f; break; case 4: - t = enemyDat[tempW].armor * 1.5f; + tempArmor = enemyDat[eDatI].armor * 1.5f; break; case 5: - t = enemyDat[tempW].armor * 1.8f; + tempArmor = enemyDat[eDatI].armor * 1.8f; break; case 6: - t = enemyDat[tempW].armor * 2; + tempArmor = enemyDat[eDatI].armor * 2; break; case 7: - t = enemyDat[tempW].armor * 3; + tempArmor = enemyDat[eDatI].armor * 3; break; case 8: - t = enemyDat[tempW].armor * 4; + tempArmor = enemyDat[eDatI].armor * 4; break; case 9: case 10: - t = enemyDat[tempW].armor * 8; + tempArmor = enemyDat[eDatI].armor * 8; break; } - if (t > 254) + if (tempArmor > 254) { - t = 254; + tempArmor = 254; } } else { - t = 255; + tempArmor = 255; } - enemy->armorleft = t; + enemy->armorleft = tempArmor; - a = 0; + avail = 0; enemy->scoreitem = false; } else { - a = 2; + avail = 2; enemy->armorleft = 255; if (enemy->evalue != 0) enemy->scoreitem = true; @@ -4193,11 +4036,11 @@ uint JE_makeEnemy( struct JE_SingleEnemyType *enemy ) // tempW, uniqueEnemy, tem totalEnemy++; /*Destruction ratio*/ } - /*The returning A value indicates what to set ENEMYAVAIL to */ - return a; + /* indicates what to set ENEMYAVAIL to */ + return avail; } -void JE_createNewEventEnemy( JE_byte enemyTypeOfs, JE_word enemyOffset ) +void JE_createNewEventEnemy( JE_byte enemyTypeOfs, JE_word enemyOffset, Sint16 uniqueShapeTableI ) { int i; @@ -4219,7 +4062,7 @@ void JE_createNewEventEnemy( JE_byte enemyTypeOfs, JE_word enemyOffset ) tempW = eventRec[eventLoc-1].eventdat + enemyTypeOfs; - enemyAvail[b-1] = JE_makeEnemy(&enemy[b-1]); + enemyAvail[b-1] = JE_makeEnemy(&enemy[b-1], tempW, uniqueShapeTableI); if (eventRec[eventLoc-1].eventdat2 != -99) { @@ -4290,24 +4133,30 @@ void JE_eventJump( JE_word jump ) eventLoc = tempW - 1; } -JE_boolean JE_searchFor/*enemy*/( JE_byte PLType ) +bool JE_searchFor/*enemy*/( JE_byte PLType, JE_byte* out_index ) { - JE_boolean tempb = false; - JE_byte temp; + int found_id = -1; - for (temp = 0; temp < 100; temp++) + for (int i = 0; i < 100; i++) { - if (enemyAvail[temp] == 0 && enemy[temp].linknum == PLType) + if (enemyAvail[i] == 0 && enemy[i].linknum == PLType) { - temp5 = temp + 1; + found_id = i; if (galagaMode) { - enemy[temp].evalue += enemy[temp].evalue; + enemy[i].evalue += enemy[i].evalue; } - tempb = true; } } - return tempb; + + if (found_id != -1) { + if (out_index) { + *out_index = found_id; + } + return true; + } else { + return false; + } } void JE_eventSystem( void ) @@ -4315,7 +4164,7 @@ void JE_eventSystem( void ) switch (eventRec[eventLoc-1].eventtype) { case 1: - starY = eventRec[eventLoc-1].eventdat * VGAScreen->pitch; + starfield_speed = eventRec[eventLoc-1].eventdat; break; case 2: @@ -4365,68 +4214,40 @@ void JE_eventSystem( void ) } break; - case 5: - if (enemyShapeTables[1-1] != eventRec[eventLoc-1].eventdat) + case 5: // load enemy shape banks { - if (eventRec[eventLoc-1].eventdat > 0) + Uint8 newEnemyShapeTables[] = { - JE_loadCompShapes(&eShapes1, shapeFile[eventRec[eventLoc-1].eventdat -1]); /* Enemy Bank 1 */ - enemyShapeTables[1-1] = eventRec[eventLoc-1].eventdat; - } - else + eventRec[eventLoc-1].eventdat > 0 ? eventRec[eventLoc-1].eventdat : 0, + eventRec[eventLoc-1].eventdat2 > 0 ? eventRec[eventLoc-1].eventdat2 : 0, + eventRec[eventLoc-1].eventdat3 > 0 ? eventRec[eventLoc-1].eventdat3 : 0, + eventRec[eventLoc-1].eventdat4 > 0 ? eventRec[eventLoc-1].eventdat4 : 0, + }; + + for (unsigned int i = 0; i < COUNTOF(newEnemyShapeTables); ++i) { - free_sprite2s(&eShapes1); - enemyShapeTables[1-1] = 0; - } - } - if (enemyShapeTables[2-1] != eventRec[eventLoc-1].eventdat2) - { - if (eventRec[eventLoc-1].eventdat2 > 0) - { - JE_loadCompShapes(&eShapes2, shapeFile[eventRec[eventLoc-1].eventdat2-1]); /* Enemy Bank 2 */ - enemyShapeTables[2-1] = eventRec[eventLoc-1].eventdat2; - } - else - { - free_sprite2s(&eShapes2); - enemyShapeTables[2-1] = 0; - } - } - if (enemyShapeTables[3-1] != (unsigned char)eventRec[eventLoc-1].eventdat3) - { - if (eventRec[eventLoc-1].eventdat3 > 0) - { - JE_loadCompShapes(&eShapes3, shapeFile[eventRec[eventLoc-1].eventdat3-1]); /* Enemy Bank 3 */ - enemyShapeTables[3-1] = eventRec[eventLoc-1].eventdat3; - } - else - { - free_sprite2s(&eShapes3); - enemyShapeTables[3-1] = 0; - } - } - if (enemyShapeTables[4-1] != eventRec[eventLoc-1].eventdat4) - { - if (eventRec[eventLoc-1].eventdat4 > 0) - { - JE_loadCompShapes(&eShapes4, shapeFile[eventRec[eventLoc-1].eventdat4-1]); /* Enemy Bank 4 */ - enemyShapeTables[4-1] = eventRec[eventLoc-1].eventdat4; - enemyShapeTables[5-1] = 21; - } - else - { - free_sprite2s(&eShapes4); - enemyShapeTables[4-1] = 0; + if (enemyShapeTables[i] != newEnemyShapeTables[i]) + { + if (newEnemyShapeTables[i] > 0) + { + assert(newEnemyShapeTables[i] <= COUNTOF(shapeFile)); + JE_loadCompShapes(&eShapes[i], shapeFile[newEnemyShapeTables[i] - 1]); + } + else + free_sprite2s(&eShapes[i]); + + enemyShapeTables[i] = newEnemyShapeTables[i]; + } } } break; case 6: /* Ground Enemy */ - JE_createNewEventEnemy(0, 25); + JE_createNewEventEnemy(0, 25, 0); break; case 7: /* Top Enemy */ - JE_createNewEventEnemy(0, 50); + JE_createNewEventEnemy(0, 50, 0); break; case 8: @@ -4438,7 +4259,7 @@ void JE_eventSystem( void ) break; case 10: /* Ground Enemy 2 */ - JE_createNewEventEnemy(0, 75); + JE_createNewEventEnemy(0, 75, 0); break; case 11: @@ -4473,12 +4294,12 @@ void JE_eventSystem( void ) break; } eventRec[eventLoc-1].eventdat6 = 0; /* We use EVENTDAT6 for the background */ - JE_createNewEventEnemy(0, temp); - JE_createNewEventEnemy(1, temp); + JE_createNewEventEnemy(0, temp, 0); + JE_createNewEventEnemy(1, temp, 0); enemy[b-1].ex += 24; - JE_createNewEventEnemy(2, temp); + JE_createNewEventEnemy(2, temp, 0); enemy[b-1].ey -= 28; - JE_createNewEventEnemy(3, temp); + JE_createNewEventEnemy(3, temp, 0); enemy[b-1].ex += 24; enemy[b-1].ey -= 28; break; @@ -4492,7 +4313,7 @@ void JE_eventSystem( void ) break; case 15: /* Sky Enemy */ - JE_createNewEventEnemy(0, 0); + JE_createNewEventEnemy(0, 0, 0); break; case 16: @@ -4508,7 +4329,7 @@ void JE_eventSystem( void ) break; case 17: /* Ground Bottom */ - JE_createNewEventEnemy(0, 25); + JE_createNewEventEnemy(0, 25, 0); if (b > 0) { enemy[b-1].ey = 190 + eventRec[eventLoc-1].eventdat5; @@ -4516,7 +4337,7 @@ void JE_eventSystem( void ) break; case 18: /* Sky Enemy on Bottom */ - JE_createNewEventEnemy(0, 0); + JE_createNewEventEnemy(0, 0, 0); if (b > 0) { enemy[b-1].ey = 190 + eventRec[eventLoc-1].eventdat5; @@ -4524,11 +4345,15 @@ void JE_eventSystem( void ) break; case 19: /* Enemy Global Move */ + { + int initial_i = 0, max_i = 0; + bool all_enemies = false; + if (eventRec[eventLoc-1].eventdat3 > 79 && eventRec[eventLoc-1].eventdat3 < 90) { - temp2 = 1; - temp3 = 100; - temp4 = 0; + initial_i = 0; + max_i = 100; + all_enemies = false; eventRec[eventLoc-1].eventdat4 = newPL[eventRec[eventLoc-1].eventdat3 - 80]; } else @@ -4536,54 +4361,55 @@ void JE_eventSystem( void ) switch (eventRec[eventLoc-1].eventdat3) { case 0: - temp2 = 1; - temp3 = 100; - temp4 = 0; + initial_i = 0; + max_i = 100; + all_enemies = false; break; case 2: - temp2 = 1; - temp3 = 25; - temp4 = 1; + initial_i = 0; + max_i = 25; + all_enemies = true; break; case 1: - temp2 = 26; - temp3 = 50; - temp4 = 1; + initial_i = 25; + max_i = 50; + all_enemies = true; break; case 3: - temp2 = 51; - temp3 = 75; - temp4 = 1; + initial_i = 50; + max_i = 75; + all_enemies = true; break; case 99: - temp2 = 1; - temp3 = 100; - temp4 = 1; + initial_i = 0; + max_i = 100; + all_enemies = true; break; } } - for (temp = temp2-1; temp < temp3; temp++) + for (int i = initial_i; i < max_i; i++) { - if (temp4 == 1 || enemy[temp].linknum == eventRec[eventLoc-1].eventdat4) + if (all_enemies || enemy[i].linknum == eventRec[eventLoc-1].eventdat4) { if (eventRec[eventLoc-1].eventdat != -99) - enemy[temp].exc = eventRec[eventLoc-1].eventdat; + enemy[i].exc = eventRec[eventLoc-1].eventdat; if (eventRec[eventLoc-1].eventdat2 != -99) - enemy[temp].eyc = eventRec[eventLoc-1].eventdat2; + enemy[i].eyc = eventRec[eventLoc-1].eventdat2; if (eventRec[eventLoc-1].eventdat6 != 0) - enemy[temp].fixedmovey = eventRec[eventLoc-1].eventdat6; + enemy[i].fixedmovey = eventRec[eventLoc-1].eventdat6; if (eventRec[eventLoc-1].eventdat6 == -99) - enemy[temp].fixedmovey = 0; + enemy[i].fixedmovey = 0; if (eventRec[eventLoc-1].eventdat5 > 0) - enemy[temp].enemycycle = eventRec[eventLoc-1].eventdat5; + enemy[i].enemycycle = eventRec[eventLoc-1].eventdat5; } } break; + } case 20: /* Enemy Global Accel */ if (eventRec[eventLoc-1].eventdat3 > 79 && eventRec[eventLoc-1].eventdat3 < 90) @@ -4640,7 +4466,7 @@ void JE_eventSystem( void ) break; case 23: /* Sky Enemy on Bottom */ - JE_createNewEventEnemy(0, 50); + JE_createNewEventEnemy(0, 50, 0); if (b > 0) enemy[b-1].ey = 180 + eventRec[eventLoc-1].eventdat5; break; @@ -4756,7 +4582,7 @@ void JE_eventSystem( void ) break; case 32: // create enemy - JE_createNewEventEnemy(0, 50); + JE_createNewEventEnemy(0, 50, 0); if (b > 0) enemy[b-1].ey = 190; break; @@ -4817,15 +4643,15 @@ void JE_eventSystem( void ) case 38: curLoc = eventRec[eventLoc-1].eventdat; - tempW2 = 1; + int new_event_loc = 1; for (tempW = 0; tempW < maxEvent; tempW++) { if (eventRec[tempW].eventtime <= curLoc) { - tempW2 = tempW+1 - 1; + new_event_loc = tempW+1 - 1; } } - eventLoc = tempW2; + eventLoc = new_event_loc; break; case 39: /* Enemy Global Linknum Change */ @@ -4926,7 +4752,6 @@ void JE_eventSystem( void ) eventRec[eventLoc-1].eventdat3 = 0; tempDat3 = eventRec[eventLoc-1].eventdat6; eventRec[eventLoc-1].eventdat6 = 0; - tempI2 = tempDat; enemyDat[0].armor = tempDat3; enemyDat[0].egraphic[1-1] = tempDat2; switch (eventRec[eventLoc-1].eventtype - 48) @@ -4944,9 +4769,7 @@ void JE_eventSystem( void ) temp = 75; break; } - uniqueEnemy = true; - JE_createNewEventEnemy(0, temp); - uniqueEnemy = false; + JE_createNewEventEnemy(0, temp, tempDat); eventRec[eventLoc-1].eventdat = tempDat2; eventRec[eventLoc-1].eventdat3 = tempDat; eventRec[eventLoc-1].eventdat6 = tempDat3; @@ -4977,7 +4800,7 @@ void JE_eventSystem( void ) break; case 56: /* Ground2 Bottom */ - JE_createNewEventEnemy(0, 75); + JE_createNewEventEnemy(0, 75, 0); if (b > 0) enemy[b-1].ey = 190; break; @@ -4999,7 +4822,7 @@ void JE_eventSystem( void ) break; case 61: // if specific flag set to specific value, skip events - if (globalFlags[eventRec[eventLoc-1].eventdat] == eventRec[eventLoc-1].eventdat2) + if (globalFlags[eventRec[eventLoc-1].eventdat-1] == eventRec[eventLoc-1].eventdat2) eventLoc += eventRec[eventLoc-1].eventdat3; break; @@ -5053,14 +4876,14 @@ void JE_eventSystem( void ) bool found = false; for (temp = 1; temp <= 19; temp++) - found |= JE_searchFor(temp); + found = found || JE_searchFor(temp, NULL); if (!found) JE_eventJump(eventRec[eventLoc-1].eventdat); } - else if (!JE_searchFor(eventRec[eventLoc-1].eventdat2) - && (eventRec[eventLoc-1].eventdat3 == 0 || !JE_searchFor(eventRec[eventLoc-1].eventdat3)) - && (eventRec[eventLoc-1].eventdat4 == 0 || !JE_searchFor(eventRec[eventLoc-1].eventdat4))) + else if (!JE_searchFor(eventRec[eventLoc-1].eventdat2, NULL) + && (eventRec[eventLoc-1].eventdat3 == 0 || !JE_searchFor(eventRec[eventLoc-1].eventdat3, NULL)) + && (eventRec[eventLoc-1].eventdat4 == 0 || !JE_searchFor(eventRec[eventLoc-1].eventdat4, NULL))) { JE_eventJump(eventRec[eventLoc-1].eventdat); } @@ -5117,11 +4940,12 @@ void JE_eventSystem( void ) if (temp_no_clue) { + JE_byte enemy_i; do { temp = (mt_rand() % (eventRec[eventLoc-1].eventdat2 + 1 - eventRec[eventLoc-1].eventdat)) + eventRec[eventLoc-1].eventdat; } - while (!(JE_searchFor(temp) && enemy[temp5-1].eyc == 0)); + while (!(JE_searchFor(temp, &enemy_i) && enemy[enemy_i].eyc == 0)); newPL[eventRec[eventLoc-1].eventdat3 - 80] = temp; } @@ -5187,7 +5011,7 @@ void JE_eventSystem( void ) break; default: - fprintf(stderr, "warning: event %d: unhandled event\n", eventRec[eventLoc-1].eventtype); + fprintf(stderr, "warning: ignoring unknown event %d\n", eventRec[eventLoc-1].eventtype); break; } @@ -5325,4 +5149,3 @@ void draw_boss_bar( void ) } } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/tyrian2.h b/project/jni/application/opentyrian/src/tyrian2.h index 1361db7b9..74478b069 100644 --- a/project/jni/application/opentyrian/src/tyrian2.h +++ b/project/jni/application/opentyrian/src/tyrian2.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -39,11 +39,11 @@ extern boss_bar_t boss_bar[2]; extern char tempStr[31]; extern JE_byte itemAvail[9][10], itemAvailMax[9]; -void JE_createNewEventEnemy( JE_byte enemytypeofs, JE_word enemyoffset ); +void JE_createNewEventEnemy( JE_byte enemytypeofs, JE_word enemyoffset, Sint16 uniqueShapeTableI ); void JE_doNetwork( void ); -uint JE_makeEnemy( struct JE_SingleEnemyType *enemy ); +uint JE_makeEnemy( struct JE_SingleEnemyType *enemy, Uint16 eDatI, Sint16 uniqueShapeTableI ); void JE_eventJump( JE_word jump ); @@ -51,7 +51,7 @@ void JE_whoa( void ); void JE_barX ( JE_word x1, JE_word y1, JE_word x2, JE_word y2, JE_byte col ); -void JE_newEnemy( int enemyOffset ); +Sint16 JE_newEnemy( int enemyOffset, Uint16 eDatI, Sint16 uniqueShapeTableI ); void JE_drawEnemy( int enemyOffset ); void JE_starShowVGA( void ); @@ -61,11 +61,10 @@ bool JE_titleScreen( JE_boolean animate ); void JE_readTextSync( void ); void JE_displayText( void ); -JE_boolean JE_searchFor( JE_byte PLType ); +bool JE_searchFor( JE_byte PLType, JE_byte* out_index ); void JE_eventSystem( void ); void draw_boss_bar( void ); #endif /* TYRIAN2_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/varz.c b/project/jni/application/opentyrian/src/varz.c index dc6d4ca2a..d9bf4bb5e 100644 --- a/project/jni/application/opentyrian/src/varz.c +++ b/project/jni/application/opentyrian/src/varz.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -29,6 +29,7 @@ #include "nortsong.h" #include "nortvars.h" #include "opentyr.h" +#include "shots.h" #include "sprite.h" #include "varz.h" #include "vga256d.h" @@ -98,13 +99,6 @@ const JE_word chargeGunWeapons[38] /* [1..38] */ = 0,0,0,0,0,0,0,0,476,458,464,482,0,488,470,0,0,0,0,0,494,500,0,528,0,558, 458,458,458,458,458,458,458,458,458,458,458,458 }; -const JE_word linkMultiGr[17] /* [0..16] */ = - {77,221,183,301,1,282,164,202,58,201,163,281,39,300,182,220,77}; -const JE_word linkSonicGr[17] /* [0..16] */ = - {85,242,131,303,47,284,150,223,66,224,149,283,9,302,130,243,85}; -const JE_word linkMult2Gr[17] /* [0..16] */ = - {78,299,295,297,2,278,276,280,59,279,275,277,40,296,294,298,78}; - const JE_byte randomEnemyLaunchSounds[3] /* [1..3] */ = {13,6,26}; /* YKS: Twiddle cheat sheet: @@ -259,12 +253,11 @@ JE_boolean moveTyrianLogoUp; JE_boolean skipStarShowVGA; /*EnemyData*/ -JE_EnemyType enemy; -JE_EnemyAvailType enemyAvail; +JE_MultiEnemyType enemy; +JE_EnemyAvailType enemyAvail; /* values: 0: used, 1: free, 2: secret pick-up */ JE_word enemyOffset; JE_word enemyOnScreen; JE_byte enemyShapeTables[6]; /* [1..6] */ -JE_boolean uniqueEnemy; JE_word superEnemy254Jump; /*EnemyShotData*/ @@ -284,14 +277,9 @@ JE_boolean spraySpecial; JE_byte doIced; JE_boolean infiniteShot; -PlayerShotDataType playerShotData[MAX_PWEAPON + 1]; /* [1..MaxPWeapon+1] */ - -JE_byte chain; - /*PlayerData*/ JE_boolean allPlayersGone; /*Both players dead and finished exploding*/ -JE_byte shotAvail[MAX_PWEAPON]; /* [1..MaxPWeapon] */ /*0:Avail 1-255:Duration left*/ const uint shadowYDist = 10; JE_real optionSatelliteRotate; @@ -317,18 +305,14 @@ superpixel_type superpixels[MAX_SUPERPIXELS]; /* [0..MaxSP] */ unsigned int last_superpixel; /*Temporary Numbers*/ -JE_integer tempI, tempI2, tempI3, tempI4; -JE_longint tempL; - -JE_byte temp, temp2, temp3, temp4, temp5, tempPos; -JE_word tempX, tempY, tempX2, tempY2; -JE_word tempW, tempW2; +JE_byte temp, temp2, temp3; +JE_word tempX, tempY; +JE_word tempW; JE_boolean doNotSaveBackup; JE_word x, y; JE_integer b; -JE_byte playerNum; JE_byte **BKwrap1to, **BKwrap2to, **BKwrap3to, **BKwrap1, **BKwrap2, **BKwrap3; @@ -517,217 +501,6 @@ void JE_tyrianHalt( JE_byte code ) exit(code); } -void JE_initPlayerShot( JE_word portNum, uint shot_i, JE_word PX, JE_word PY, JE_word mouseX, JE_word mouseY, JE_word wpNum, JE_byte playerNum ) -{ - const JE_byte soundChannel[11] /* [1..11] */ = {0, 2, 4, 4, 2, 2, 5, 5, 1, 4, 1}; - - if (portNum <= PORT_NUM) - { - if (wpNum > 0 && wpNum <= WEAP_NUM) - { - if (power >= weaponPort[portNum].poweruse) - { - power -= weaponPort[portNum].poweruse; - - if (weapons[wpNum].sound > 0) - { - soundQueue[soundChannel[shot_i]] = weapons[wpNum].sound; - } - - /*Rot*/ - for (tempW = 1; tempW <= weapons[wpNum].multi; tempW++) - { - - for (b = 0; b < MAX_PWEAPON; b++) - { - if (shotAvail[b] == 0) - { - break; - } - } - if (b == MAX_PWEAPON) - { - return; - } - - if (shotMultiPos[shot_i] == weapons[wpNum].max || shotMultiPos[shot_i] > 8) - { - shotMultiPos[shot_i] = 1; - } else { - shotMultiPos[shot_i]++; - } - - playerShotData[b].chainReaction = 0; - - playerShotData[b].playerNumber = playerNum; - - playerShotData[b].shotAni = 0; - - playerShotData[b].shotComplicated = weapons[wpNum].circlesize != 0; - - if (weapons[wpNum].circlesize == 0) - { - playerShotData[b].shotDevX = 0; - playerShotData[b].shotDirX = 0; - playerShotData[b].shotDevY = 0; - playerShotData[b].shotDirY = 0; - playerShotData[b].shotCirSizeX = 0; - playerShotData[b].shotCirSizeY = 0; - } else { - temp2 = weapons[wpNum].circlesize; - - if (temp2 > 19) - { - temp3 = temp2 % 20; - playerShotData[b].shotCirSizeX = temp3; - playerShotData[b].shotDevX = temp3 >> 1; - - temp2 = temp2 / 20; - playerShotData[b].shotCirSizeY = temp2; - playerShotData[b].shotDevY = temp2 >> 1; - } else { - playerShotData[b].shotCirSizeX = temp2; - playerShotData[b].shotCirSizeY = temp2; - playerShotData[b].shotDevX = temp2 >> 1; - playerShotData[b].shotDevY = temp2 >> 1; - } - playerShotData[b].shotDirX = 1; - playerShotData[b].shotDirY = -1; - } - - playerShotData[b].shotTrail = weapons[wpNum].trail; - - if (weapons[wpNum].attack[shotMultiPos[shot_i]-1] > 99 && weapons[wpNum].attack[shotMultiPos[shot_i]-1] < 250) - { - playerShotData[b].chainReaction = weapons[wpNum].attack[shotMultiPos[shot_i]-1] - 100; - playerShotData[b].shotDmg = 1; - } else { - playerShotData[b].shotDmg = weapons[wpNum].attack[shotMultiPos[shot_i]-1]; - } - - playerShotData[b].shotBlastFilter = weapons[wpNum].shipblastfilter; - - tempI = weapons[wpNum].by[shotMultiPos[shot_i]-1]; - - /*Note: Only front selection used for player shots...*/ - - playerShotData[b].shotX = PX + weapons[wpNum].bx[shotMultiPos[shot_i]-1]; - - playerShotData[b].shotY = PY + tempI; - playerShotData[b].shotYC = -weapons[wpNum].acceleration; - playerShotData[b].shotXC = weapons[wpNum].accelerationx; - - playerShotData[b].shotXM = weapons[wpNum].sx[shotMultiPos[shot_i]-1]; - - temp2 = weapons[wpNum].del[shotMultiPos[shot_i]-1]; - - if (temp2 == 121) - { - playerShotData[b].shotTrail = 0; - temp2 = 255; - } - - playerShotData[b].shotGr = weapons[wpNum].sg[shotMultiPos[shot_i]-1]; - if (playerShotData[b].shotGr == 0) - { - shotAvail[b] = 0; - } else { - shotAvail[b] = temp2; - } - if (temp2 > 100 && temp2 < 120) - { - playerShotData[b].shotAniMax = (temp2 - 100 + 1); - } else { - playerShotData[b].shotAniMax = weapons[wpNum].weapani + 1; - } - - if (temp2 == 99 || temp2 == 98) - { - tempI = PX - mouseX; - if (tempI < -5) - { - tempI = -5; - } - if (tempI > 5) - { - tempI = 5; - } - playerShotData[b].shotXM += tempI; - } - - - if (temp2 == 99 || temp2 == 100) - { - tempI = PY - mouseY - weapons[wpNum].sy[shotMultiPos[shot_i]-1]; - if (tempI < -4) - { - tempI = -4; - } - if (tempI > 4) - { - tempI = 4; - } - playerShotData[b].shotYM = tempI; - } else { - if (weapons[wpNum].sy[shotMultiPos[shot_i]-1] == 98) - { - playerShotData[b].shotYM = 0; - playerShotData[b].shotYC = -1; - } else { - if (weapons[wpNum].sy[shotMultiPos[shot_i]-1] > 100) - { - playerShotData[b].shotYM = weapons[wpNum].sy[shotMultiPos[shot_i]-1]; - playerShotData[b].shotY -= player[playerShotData[b].playerNumber-1].delta_y_shot_move; - } else { - playerShotData[b].shotYM = -weapons[wpNum].sy[shotMultiPos[shot_i]-1]; - } - } - } - - if (weapons[wpNum].sx[shotMultiPos[shot_i]-1] > 100) - { - playerShotData[b].shotXM = weapons[wpNum].sx[shotMultiPos[shot_i]-1]; - playerShotData[b].shotX -= player[playerShotData[b].playerNumber-1].delta_x_shot_move; - if (playerShotData[b].shotXM == 101) - { - playerShotData[b].shotY -= player[playerShotData[b].playerNumber-1].delta_y_shot_move; - } - } - - - if (weapons[wpNum].aim > 5) /*Guided Shot*/ - { - uint best_dist = 65000; - temp3 = 0; - /*Find Closest Enemy*/ - for (x = 0; x < 100; x++) - { - if (enemyAvail[x] != 1 && !enemy[x].scoreitem) - { - y = abs(enemy[x].ex - playerShotData[b].shotX) + abs(enemy[x].ey - playerShotData[b].shotY); - if (y < best_dist) - { - best_dist = y; - temp3 = x + 1; - } - } - } - playerShotData[b].aimAtEnemy = temp3; - playerShotData[b].aimDelay = 5; - playerShotData[b].aimDelayMax = weapons[wpNum].aim - 5; - } - else - { - playerShotData[b].aimAtEnemy = 0; - } - - shotRepeat[shot_i] = weapons[wpNum].shotrepeat; - } - } - } - } -} - void JE_specialComplete( JE_byte playerNum, JE_byte specialType ) { nextSpecialWait = 0; @@ -736,9 +509,9 @@ void JE_specialComplete( JE_byte playerNum, JE_byte specialType ) /*Weapon*/ case 1: if (playerNum == 1) - JE_initPlayerShot(0, SHOT_SPECIAL2, player[0].x, player[0].y, mouseX, mouseY, special[specialType].wpn, playerNum); + b = player_shot_create(0, SHOT_SPECIAL2, player[0].x, player[0].y, mouseX, mouseY, special[specialType].wpn, playerNum); else - JE_initPlayerShot(0, SHOT_SPECIAL2, player[1].x, player[1].y, mouseX, mouseY, special[specialType].wpn, playerNum); + b = player_shot_create(0, SHOT_SPECIAL2, player[1].x, player[1].y, mouseX, mouseY, special[specialType].wpn, playerNum); shotRepeat[SHOT_SPECIAL] = shotRepeat[SHOT_SPECIAL2]; break; @@ -859,7 +632,7 @@ void JE_specialComplete( JE_byte playerNum, JE_byte specialType ) if (superArcadeMode > 0 && superArcadeMode <= SA) { shotRepeat[SHOT_SPECIAL] = 250; - JE_initPlayerShot(0, SHOT_SPECIAL2, player[0].x, player[0].y, mouseX, mouseY, 707, 1); + b = player_shot_create(0, SHOT_SPECIAL2, player[0].x, player[0].y, mouseX, mouseY, 707, 1); player[0].invulnerable_ticks = 100; } break; @@ -1036,21 +809,21 @@ void JE_doSpecialShot( JE_byte playerNum, uint *armor, uint *shield ) if ((signed)(mt_rand() % 6) < specialWeaponFreq) { - b = 0; + b = MAX_PWEAPON; if (linkToPlayer) { if (shotRepeat[SHOT_SPECIAL] == 0) { - JE_initPlayerShot(0, SHOT_SPECIAL, player[0].x, player[0].y, mouseX, mouseY, specialWeaponWpn, playerNum); + b = player_shot_create(0, SHOT_SPECIAL, player[0].x, player[0].y, mouseX, mouseY, specialWeaponWpn, playerNum); } } else { - JE_initPlayerShot(0, SHOT_SPECIAL, mt_rand() % 280, mt_rand() % 180, mouseX, mouseY, specialWeaponWpn, playerNum); + b = player_shot_create(0, SHOT_SPECIAL, mt_rand() % 280, mt_rand() % 180, mouseX, mouseY, specialWeaponWpn, playerNum); } - if (spraySpecial && b > 0) + if (spraySpecial && b != MAX_PWEAPON) { playerShotData[b].shotXM = (mt_rand() % 5) - 2; playerShotData[b].shotYM = (mt_rand() % 5) - 2; @@ -1409,4 +1182,3 @@ void JE_drawSP( void ) } } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/varz.h b/project/jni/application/opentyrian/src/varz.h index c7aa7fada..fad4114fe 100644 --- a/project/jni/application/opentyrian/src/varz.h +++ b/project/jni/application/opentyrian/src/varz.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -42,7 +42,6 @@ enum SA_ARCADE = 255 }; -#define MAX_PWEAPON 81 /* 81*/ #define ENEMY_SHOT_MAX 60 /* 60*/ #define CURRENT_KEY_SPEED 1 /*Keyboard/Joystick movement rate*/ @@ -168,7 +167,6 @@ struct JE_MegaDataType3 JE_byte tempdat3; }; -typedef JE_MultiEnemyType JE_EnemyType; typedef JE_byte JE_EnemyAvailType[100]; /* [1..100] */ typedef struct { @@ -184,16 +182,6 @@ typedef struct { JE_byte fill[12]; } EnemyShotType; -typedef struct { - JE_integer shotX, shotY, shotXM, shotYM, shotXC, shotYC; - JE_boolean shotComplicated; - JE_integer shotDevX, shotDirX, shotDevY, shotDirY, shotCirSizeX, shotCirSizeY; - JE_byte shotTrail; - JE_word shotGr, shotAni, shotAniMax; - Uint8 shotDmg; - JE_byte shotBlastFilter, chainReaction, playerNumber, aimAtEnemy, aimDelay, aimDelayMax; -} PlayerShotDataType; - typedef struct { unsigned int ttl; signed int x, y; @@ -228,9 +216,6 @@ extern const JE_word PGR[21]; extern const JE_byte PAni[21]; extern const JE_word linkGunWeapons[38]; extern const JE_word chargeGunWeapons[38]; -extern const JE_word linkMultiGr[17]; -extern const JE_word linkSonicGr[17]; -extern const JE_word linkMult2Gr[17]; extern const JE_byte randomEnemyLaunchSounds[3]; extern const JE_byte keyboardCombos[26][8]; extern const JE_byte shipCombosB[21]; @@ -293,12 +278,11 @@ extern JE_word mapOrigin, mapPNum; extern JE_byte mapPlanet[5], mapSection[5]; extern JE_boolean moveTyrianLogoUp; extern JE_boolean skipStarShowVGA; -extern JE_EnemyType enemy; +extern JE_MultiEnemyType enemy; extern JE_EnemyAvailType enemyAvail; extern JE_word enemyOffset; extern JE_word enemyOnScreen; extern JE_byte enemyShapeTables[6]; -extern JE_boolean uniqueEnemy; extern JE_word superEnemy254Jump; extern explosion_type explosions[MAX_EXPLOSIONS]; extern JE_integer explosionFollowAmountX, explosionFollowAmountY; @@ -315,10 +299,7 @@ extern JE_byte nextSpecialWait; extern JE_boolean spraySpecial; extern JE_byte doIced; extern JE_boolean infiniteShot; -extern PlayerShotDataType playerShotData[MAX_PWEAPON + 1]; -extern JE_byte chain; extern JE_boolean allPlayersGone; -extern JE_byte shotAvail[MAX_PWEAPON]; extern const uint shadowYDist; extern JE_real optionSatelliteRotate; extern JE_integer optionAttachmentMove; @@ -328,15 +309,12 @@ extern JE_word neat; extern rep_explosion_type rep_explosions[MAX_REPEATING_EXPLOSIONS]; extern superpixel_type superpixels[MAX_SUPERPIXELS]; extern unsigned int last_superpixel; -extern JE_integer tempI, tempI2, tempI3, tempI4; -extern JE_longint tempL; -extern JE_byte temp, temp2, temp3, temp4, temp5, tempPos; -extern JE_word tempX, tempY, tempX2, tempY2; -extern JE_word tempW, tempW2; +extern JE_byte temp, temp2, temp3; +extern JE_word tempX, tempY; +extern JE_word tempW; extern JE_boolean doNotSaveBackup; extern JE_word x, y; extern JE_integer b; -extern JE_byte playerNum; extern JE_byte **BKwrap1to, **BKwrap2to, **BKwrap3to, **BKwrap1, **BKwrap2, **BKwrap3; extern JE_shortint specialWeaponFilter, specialWeaponFreq; extern JE_word specialWeaponWpn; @@ -356,9 +334,6 @@ JE_word JE_SGr( JE_word ship, Sprite2_array **ptr ); void JE_drawOptions( void ); void JE_tyrianHalt( JE_byte code ); /* This ends the game */ -void JE_initPlayerShot( JE_word portnum, uint shot_i, JE_word px, JE_word py, - JE_word mousex, JE_word mousey, - JE_word wpnum, JE_byte playernum ); void JE_specialComplete( JE_byte playernum, JE_byte specialType ); void JE_doSpecialShot( JE_byte playernum, uint *armor, uint *shield ); @@ -382,4 +357,3 @@ void JE_drawOptionLevel( void ); #endif /* VARZ_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/vga256d.c b/project/jni/application/opentyrian/src/vga256d.c index a145bb4dd..b7e0d5766 100644 --- a/project/jni/application/opentyrian/src/vga256d.c +++ b/project/jni/application/opentyrian/src/vga256d.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -157,4 +157,3 @@ void draw_segmented_gauge( SDL_Surface *surface, int x, int y, Uint8 color, uint fill_rectangle_hw(surface, x, y, segment_width, segment_height, color + (12 * partial_segment / segment_value)); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/vga256d.h b/project/jni/application/opentyrian/src/vga256d.h index 80215d868..ad91b9175 100644 --- a/project/jni/application/opentyrian/src/vga256d.h +++ b/project/jni/application/opentyrian/src/vga256d.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -40,4 +40,3 @@ void draw_segmented_gauge( SDL_Surface *surface, int x, int y, Uint8 color, uint #endif /* VGA256D_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/video.c b/project/jni/application/opentyrian/src/video.c index 154aeddc9..490d1e818 100644 --- a/project/jni/application/opentyrian/src/video.c +++ b/project/jni/application/opentyrian/src/video.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -24,6 +24,7 @@ #include #include +#include bool fullscreen_enabled = false; @@ -56,6 +57,7 @@ void init_video( void ) !init_any_scaler(fullscreen_enabled) && // try any scaler in desired fullscreen state !init_any_scaler(!fullscreen_enabled)) // try any scaler in other fullscreen state { + fprintf(stderr, "error: failed to initialize any supported video mode\n"); exit(EXIT_FAILURE); } } @@ -105,7 +107,7 @@ bool init_scaler( unsigned int new_scaler, bool fullscreen ) if (surface == NULL) { - fprintf(stderr, "error: failed to initialize video mode %dx%dx%d: %s\n", w, h, bpp, SDL_GetError()); + fprintf(stderr, "error: failed to initialize %s video mode %dx%dx%d: %s\n", fullscreen ? "fullscreen" : "windowed", w, h, bpp, SDL_GetError()); return false; } @@ -113,7 +115,7 @@ bool init_scaler( unsigned int new_scaler, bool fullscreen ) h = surface->h; bpp = surface->format->BitsPerPixel; - printf("initialized video: %dx%dx%d\n", w, h, bpp); + printf("initialized video: %dx%dx%d %s\n", w, h, bpp, fullscreen ? "fullscreen" : "windowed"); scaler = new_scaler; fullscreen_enabled = fullscreen; @@ -140,13 +142,22 @@ bool init_scaler( unsigned int new_scaler, bool fullscreen ) return false; } - input_grab(); + input_grab(input_grab_enabled); JE_showVGA(); return true; } +bool can_init_any_scaler( bool fullscreen ) +{ + for (int i = scalers_count - 1; i >= 0; --i) + if (can_init_scaler(i, fullscreen) != 0) + return true; + + return false; +} + bool init_any_scaler( bool fullscreen ) { // attempts all scalers from last to first @@ -184,4 +195,3 @@ void scale_and_flip( SDL_Surface *src_surface ) SDL_Flip(dst_surface); } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/video.h b/project/jni/application/opentyrian/src/video.h index f0bb35f4a..7405084aa 100644 --- a/project/jni/application/opentyrian/src/video.h +++ b/project/jni/application/opentyrian/src/video.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -36,12 +36,14 @@ void init_video( void ); int can_init_scaler( unsigned int new_scaler, bool fullscreen ); bool init_scaler( unsigned int new_scaler, bool fullscreen ); +bool can_init_any_scaler( bool fullscreen ); bool init_any_scaler( bool fullscreen ); + void deinit_video( void ); + void JE_clr256( SDL_Surface * ); void JE_showVGA( void ); void scale_and_flip( SDL_Surface * ); #endif /* VIDEO_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/video_scale.c b/project/jni/application/opentyrian/src/video_scale.c index 7ab5879eb..216fa58f5 100644 --- a/project/jni/application/opentyrian/src/video_scale.c +++ b/project/jni/application/opentyrian/src/video_scale.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2010 The OpenTyrian Development Team * * Scale2x, Scale3x @@ -439,4 +439,3 @@ void scale3x_16( SDL_Surface *src_surface, SDL_Surface *dst_surface ) } } -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/video_scale.h b/project/jni/application/opentyrian/src/video_scale.h index 27a014bd7..19d4891eb 100644 --- a/project/jni/application/opentyrian/src/video_scale.h +++ b/project/jni/application/opentyrian/src/video_scale.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2010 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -40,4 +40,3 @@ void set_scaler_by_name( const char *name ); #endif /* VIDEO_SCALE_H */ -// kate: tab-width 4; vim: set noet: diff --git a/project/jni/application/opentyrian/src/video_scale_hqNx.c b/project/jni/application/opentyrian/src/video_scale_hqNx.c index 1baab8ed7..51836e61d 100644 --- a/project/jni/application/opentyrian/src/video_scale_hqNx.c +++ b/project/jni/application/opentyrian/src/video_scale_hqNx.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2010 The OpenTyrian Development Team * * hq2x, hq3x, hq4x diff --git a/project/jni/application/opentyrian/src/xmas.c b/project/jni/application/opentyrian/src/xmas.c index 94a64d64a..44a58cb0f 100644 --- a/project/jni/application/opentyrian/src/xmas.c +++ b/project/jni/application/opentyrian/src/xmas.c @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or diff --git a/project/jni/application/opentyrian/src/xmas.h b/project/jni/application/opentyrian/src/xmas.h index 2376cc81a..8e19c8823 100644 --- a/project/jni/application/opentyrian/src/xmas.h +++ b/project/jni/application/opentyrian/src/xmas.h @@ -1,5 +1,5 @@ /* - * OpenTyrian Classic: A modern cross-platform port of Tyrian + * OpenTyrian: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or @@ -28,4 +28,3 @@ bool xmas_prompt( void ); #endif /* XMAS_H */ -// kate: tab-width 4; vim: set noet: