From d4b94bbc15d04273b3aa7d04f320c9a60c5c1e0e Mon Sep 17 00:00:00 2001 From: Gregory Montoir Date: Sun, 13 Mar 2022 06:53:43 +0800 Subject: [PATCH] Import blues from 436ab46f --- Makefile | 2 +- bb/game.c | 14 +++----- bb/game.h | 1 - bb/sound.c | 66 +++---------------------------------- intern.h | 6 +++- ja/game.c | 16 ++++----- ja/game.h | 1 - ja/sound.c | 87 ++++++++++--------------------------------------- main.c | 27 +++++++-------- mixer.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++ mixer.h | 18 ++++++++++ p2/game.c | 28 +++++++--------- p2/game.h | 4 +-- p2/level.c | 86 +++++++++++++++--------------------------------- p2/screen.c | 17 ++++++++++ p2/sound.c | 86 ++++-------------------------------------------- util.c | 16 +++++---- util.h | 1 + 18 files changed, 234 insertions(+), 336 deletions(-) create mode 100644 mixer.c create mode 100644 mixer.h diff --git a/Makefile b/Makefile index 89d75f3..a215e21 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ game_p2.o: $(P2_SRCS:.c=.o) ld -r -o $@ $^ objcopy --localize-hidden $@ -blues: main.o sys_sdl2.o util.o game_bb.o game_ja.o game_p2.o +blues: main.o mixer.o sys_sdl2.o util.o game_bb.o game_ja.o game_p2.o $(CC) $(LDFLAGS) -o $@ $^ $(SDL_LIBS) $(MODPLUG_LIBS) clean: diff --git a/bb/game.c b/bb/game.c index b1fd306..82f0e3b 100644 --- a/bb/game.c +++ b/bb/game.c @@ -266,7 +266,7 @@ static void do_inter_screen() { fade_out_palette(); } -void game_main() { +static void game_run() { play_music(0); screen_init(); g_vars.start_level = 0; @@ -351,15 +351,11 @@ void game_main() { } } -static void game_run(const char *data_path) { - res_init(data_path, GAME_SCREEN_W * GAME_SCREEN_H); - sound_init(); - game_main(); - sound_fini(); - res_fini(); -} - EXPORT_SYMBOL struct game_t game_bb = { "Blues Brothers", + res_init, + res_fini, + sound_init, + sound_fini, game_run }; diff --git a/bb/game.h b/bb/game.h index 88bdd02..64a1411 100644 --- a/bb/game.h +++ b/bb/game.h @@ -203,7 +203,6 @@ extern uint8_t *level_tilesdata_1e8c[]; /* game.c */ extern void update_input(); -extern void game_main(); /* level.c */ extern void load_level_data(int num); diff --git a/bb/sound.c b/bb/sound.c index 31b6801..3f950fc 100644 --- a/bb/sound.c +++ b/bb/sound.c @@ -1,11 +1,9 @@ #include "game.h" #include "resource.h" -#include "sys.h" +#include "mixer.h" #include "util.h" -#include - #define PAULA_FREQ 3546897 static const struct { @@ -40,17 +38,6 @@ static const char *_modules[] = { "shot", "mod.shot" }; -struct mixerchannel_t { - uint8_t *data; - uint32_t pos; - uint32_t step; - uint32_t size; -}; - -static const int _rate = SYS_AUDIO_FREQ; -static struct mixerchannel_t _channel; -static ModPlugFile *_mpf; - static uint8_t *load_file(const char *filename, int *size, uint8_t *buffer) { FILE *fp = fopen_nocase(g_res.datapath, filename); if (!fp) { @@ -76,63 +63,19 @@ static uint8_t *load_file(const char *filename, int *size, uint8_t *buffer) { return buffer; } -static void mix(void *param, uint8_t *buf, int len) { - memset(buf, 0, len); - if (_mpf) { - const int count = ModPlug_Read(_mpf, buf, len); - if (count == 0) { - ModPlug_SeekOrder(_mpf, 0); - } - } - if (_channel.data) { - for (int i = 0; i < len; i += sizeof(int16_t)) { - const int pos = _channel.pos >> 16; - if (pos >= _channel.size) { - _channel.data = 0; - break; - } - const int sample = *(int16_t *)(buf + i) + ((int8_t)_channel.data[pos]) * 256; - *(int16_t *)(buf + i) = (sample < -32768 ? -32768 : (sample > 32767 ? 32767 : sample)); - _channel.pos += _channel.step; - } - } -} - void sound_init() { - ModPlug_Settings mp_settings; - memset(&mp_settings, 0, sizeof(mp_settings)); - ModPlug_GetSettings(&mp_settings); - mp_settings.mFlags = MODPLUG_ENABLE_OVERSAMPLING | MODPLUG_ENABLE_NOISE_REDUCTION; - mp_settings.mChannels = 1; - mp_settings.mBits = 16; - mp_settings.mFrequency = _rate; - mp_settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; - mp_settings.mLoopCount = -1; - ModPlug_SetSettings(&mp_settings); - g_sys.start_audio(mix, 0); } void sound_fini() { - g_sys.stop_audio(); } void play_sound(int num) { if (g_res.snd) { - g_sys.lock_audio(); - _channel.data = g_res.snd + _sounds_amiga[num].offset * 2; - _channel.pos = 0; - _channel.step = ((PAULA_FREQ / 0x358) << 16) / _rate; - _channel.size = _sounds_amiga[num].size; - g_sys.unlock_audio(); + g_mix.play_sound(g_res.snd + _sounds_amiga[num].offset * 2, _sounds_amiga[num].size, PAULA_FREQ / 0x358, 0); } } void play_music(int num) { - g_sys.lock_audio(); - if (_mpf) { - ModPlug_Unload(_mpf); - _mpf = 0; - } const char *filename = _modules[num * 2]; // Amiga int size = 0; uint8_t *buf = load_file(filename, &size, 0); @@ -167,16 +110,15 @@ void play_music(int num) { size += samples[i].size; } } - _mpf = ModPlug_Load(buf, size); + g_mix.play_music(buf, size); free(buf); } } else { // ExoticA filename = _modules[num * 2 + 1]; buf = load_file(filename, &size, 0); if (buf) { - _mpf = ModPlug_Load(buf, size); + g_mix.play_music(buf, size); free(buf); } } - g_sys.unlock_audio(); } diff --git a/intern.h b/intern.h index 8ff5559..c68fe10 100644 --- a/intern.h +++ b/intern.h @@ -63,7 +63,11 @@ struct options_t { struct game_t { const char *name; - void (*run)(const char *data_path); + void (*res_init)(const char *data_path, int vga_size); + void (*res_fini)(); + void (*snd_init)(); + void (*snd_fini)(); + void (*run)(); }; #ifdef _WIN32 diff --git a/ja/game.c b/ja/game.c index ac38876..5a25ce1 100644 --- a/ja/game.c +++ b/ja/game.c @@ -309,7 +309,7 @@ void do_game_win_screen() { } } -void game_main() { +static void game_run() { play_music(0); do_splash_screen(); g_sys.set_screen_palette(common_palette_data, 0, 128, 6); @@ -343,15 +343,11 @@ void game_main() { } } -static void game_run(const char *data_path) { - res_init(data_path, GAME_SCREEN_W * GAME_SCREEN_H); - sound_init(); - game_main(); - sound_fini(); - res_fini(); -} - EXPORT_SYMBOL struct game_t game_ja = { - "Blues Brothers : Jukebox Adventure", + "Blues Brothers: Jukebox Adventure", + res_init, + res_fini, + sound_init, + sound_fini, game_run }; diff --git a/ja/game.h b/ja/game.h index 548a9d3..1b1aa43 100644 --- a/ja/game.h +++ b/ja/game.h @@ -199,7 +199,6 @@ extern const uint8_t *player_anim_table[]; /* game.c */ extern void update_input(); -extern void game_main(); extern void do_game_over_screen(); extern void do_game_win_screen(); extern void do_difficulty_screen(); diff --git a/ja/sound.c b/ja/sound.c index 428adfc..a8dee7a 100644 --- a/ja/sound.c +++ b/ja/sound.c @@ -1,11 +1,9 @@ #include "game.h" #include "resource.h" -#include "sys.h" +#include "mixer.h" #include "util.h" -#include - #define MAX_SOUNDS 16 static const char *_modules[] = { @@ -16,63 +14,25 @@ static const char *_modules[] = { "shoot.mod" }; -struct mixerchannel_t { - uint8_t *data; - uint32_t pos; - uint32_t step; - uint32_t size; - const int8_t *seq; -}; - static struct { uint16_t offset; uint16_t size; } _samples[MAX_SOUNDS]; -static const int _rate = SYS_AUDIO_FREQ; -static struct mixerchannel_t _channel; -static ModPlugFile *_mpf; +static const int8_t *_seq; -static void mix(void *param, uint8_t *buf, int len) { - memset(buf, 0, len); - if (_mpf) { - const int count = ModPlug_Read(_mpf, buf, len); - if (count == 0) { - ModPlug_SeekOrder(_mpf, 0); - } - } - if (_channel.data) { - for (int i = 0; i < len; i += sizeof(int16_t)) { - int pos = _channel.pos >> 16; - if (pos >= _channel.size) { - const int next = _channel.seq ? *_channel.seq++ : -1; - if (next < 0) { - _channel.data = 0; - break; - } - _channel.data = g_res.samples + _samples[next].offset; - _channel.pos = pos = 0; - _channel.size = _samples[next].size; - } - const int sample = *(int16_t *)(buf + i) + ((int8_t)_channel.data[pos]) * 256; - *(int16_t *)(buf + i) = (sample < -32768 ? -32768 : (sample > 32767 ? 32767 : sample)); - _channel.pos += _channel.step; - } +static void repeat_sound_cb(const uint8_t **data, uint32_t *size) { + const int next = _seq ? *_seq++ : -1; + if (next < 0) { + *data = 0; + *size = 0; + } else { + *data = g_res.samples + _samples[next].offset; + *size = _samples[next].size; } } void sound_init() { - ModPlug_Settings mp_settings; - memset(&mp_settings, 0, sizeof(mp_settings)); - ModPlug_GetSettings(&mp_settings); - mp_settings.mFlags = MODPLUG_ENABLE_OVERSAMPLING | MODPLUG_ENABLE_NOISE_REDUCTION; - mp_settings.mChannels = 1; - mp_settings.mBits = 16; - mp_settings.mFrequency = _rate; - mp_settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; - mp_settings.mLoopCount = -1; - ModPlug_SetSettings(&mp_settings); - g_sys.start_audio(mix, 0); uint16_t offset = 0; for (int i = 0; i < MAX_SOUNDS; ++i) { const int num = i; @@ -83,41 +43,28 @@ void sound_init() { } void sound_fini() { - g_sys.stop_audio(); } void play_sound(int num) { assert(num < MAX_SOUNDS); const int sample_offset = _samples[num].offset; const int sample_size = _samples[num].size; - print_debug(DBG_MIXER, "sample num %d offset 0x%x size %d", num, sample_offset, sample_size); + print_debug(DBG_SOUND, "sample num %d offset 0x%x size %d", num, sample_offset, sample_size); if (sample_size == 0) { return; } - g_sys.lock_audio(); - _channel.data = g_res.samples + sample_offset; - _channel.pos = 0; - _channel.step = (8000 << 16) / _rate; - _channel.size = sample_size; - if (num == 10) { + if (num == 10) { static const int8_t seq[] = { 10, 10, 10, 6, -1 }; - _channel.seq = seq + 1; + _seq = seq + 1; } else { - _channel.seq = 0; + _seq = 0; } - g_sys.unlock_audio(); + g_mix.play_sound(g_res.samples + sample_offset, sample_size, 8000, _seq ? repeat_sound_cb : 0); } void play_music(int num) { - g_sys.lock_audio(); - if (_mpf) { - ModPlug_Unload(_mpf); - _mpf = 0; - } const int size = load_file(_modules[num]); - _mpf = ModPlug_Load(g_res.tmp, size); - if (_mpf) { - print_debug(DBG_MIXER, "Loaded module '%s'", ModPlug_GetName(_mpf)); + if (size != 0) { + g_mix.play_music(g_res.tmp, size); } - g_sys.unlock_audio(); } diff --git a/main.c b/main.c index 444ef3f..d9ff767 100644 --- a/main.c +++ b/main.c @@ -2,6 +2,7 @@ #include #include #include "sys.h" +#include "mixer.h" #include "util.h" struct options_t g_options; @@ -36,9 +37,9 @@ static struct game_t *detect_game(const char *data_path) { const char *filename; uint16_t size; } games[] = { - { &game_bb, "AVTMAG.SQV", 3069 }, - { &game_ja, "JARDIN.EAT", 24876 }, - { &game_p2, "MOTIF.SQZ", 9396 }, + { &game_bb, "MAGASIN.BIN", 2560 }, + { &game_ja, "JARDIN.EAT", 24876 }, + { &game_p2, "MOTIF.SQZ", 9396 }, { 0, 0, 0 } }; for (int i = 0; games[i].game; ++i) { @@ -51,18 +52,6 @@ static struct game_t *detect_game(const char *data_path) { return 0; } -#if defined(PSP) -/* stubs */ -void sound_init() { -} -void sound_fini() { -} -void play_sound(int num) { -} -void play_music(int num) { -} -#endif - int main(int argc, char *argv[]) { const char *data_path = DEFAULT_DATA_PATH; int scale_factor = DEFAULT_SCALE_FACTOR; @@ -168,7 +157,13 @@ int main(int argc, char *argv[]) { } else { g_sys.init(); g_sys.set_screen_size(GAME_SCREEN_W, GAME_SCREEN_H, game->name, scale_factor, scale_filter, fullscreen); - game->run(data_path); + game->res_init(data_path, GAME_SCREEN_W * GAME_SCREEN_H); + game->snd_init(); + g_mix.init(); + game->run(); + g_mix.fini(); + game->snd_fini(); + game->res_fini(); g_sys.fini(); } if (data_path != DEFAULT_DATA_PATH) { diff --git a/mixer.c b/mixer.c new file mode 100644 index 0000000..a0e4ca3 --- /dev/null +++ b/mixer.c @@ -0,0 +1,94 @@ + +#include "mixer.h" +#include "sys.h" +#include "util.h" + +#include + +struct mixerchannel_t { + const uint8_t *data; + uint32_t pos; + uint32_t step; + uint32_t size; + mix_repeat_sound_cb repeat_cb; +}; + +static const int _rate = SYS_AUDIO_FREQ; +static struct mixerchannel_t _channel; +static ModPlugFile *_mpf; + +static void mix(void *param, uint8_t *buf, int len) { + memset(buf, 0, len); + if (_mpf) { + const int count = ModPlug_Read(_mpf, buf, len); + if (count == 0) { + ModPlug_SeekOrder(_mpf, 0); + } + } + if (_channel.data) { + for (int i = 0; i < len; i += sizeof(int16_t)) { + int pos = _channel.pos >> 16; + if (pos >= _channel.size) { + _channel.data = 0; + if (_channel.repeat_cb) { + _channel.repeat_cb(&_channel.data, &_channel.size); + } + if (!_channel.data) { + break; + } + _channel.pos = pos = 0; + } + const int sample = *(int16_t *)(buf + i) + ((int8_t)_channel.data[pos]) * 256; + *(int16_t *)(buf + i) = (sample < -32768 ? -32768 : (sample > 32767 ? 32767 : sample)); + _channel.pos += _channel.step; + } + } +} + +static void mixer_init() { + ModPlug_Settings mp_settings; + memset(&mp_settings, 0, sizeof(mp_settings)); + ModPlug_GetSettings(&mp_settings); + mp_settings.mFlags = MODPLUG_ENABLE_OVERSAMPLING | MODPLUG_ENABLE_NOISE_REDUCTION; + mp_settings.mChannels = 1; + mp_settings.mBits = 16; + mp_settings.mFrequency = _rate; + mp_settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; + mp_settings.mLoopCount = -1; + ModPlug_SetSettings(&mp_settings); + g_sys.start_audio(mix, 0); +} + +static void mixer_fini() { + g_sys.stop_audio(); +} + +static void play_sound(const uint8_t *data, uint32_t size, int freq, mix_repeat_sound_cb repeat_cb) { + g_sys.lock_audio(); + _channel.data = data; + _channel.pos = 0; + _channel.step = (freq << 16) / _rate; + _channel.size = size; + _channel.repeat_cb = repeat_cb; + g_sys.unlock_audio(); +} + +static void play_music(const uint8_t *data, uint32_t size) { + g_sys.lock_audio(); + if (_mpf) { + ModPlug_Unload(_mpf); + _mpf = 0; + } + _mpf = ModPlug_Load(data, size); + if (_mpf) { + print_debug(DBG_MIXER, "Loaded module '%s'", ModPlug_GetName(_mpf)); + } + g_sys.unlock_audio(); +} + +struct mixer_t g_mix = { + .init = mixer_init, + .fini = mixer_fini, + .play_sound = play_sound, + .play_music = play_music, +}; diff --git a/mixer.h b/mixer.h new file mode 100644 index 0000000..bc95474 --- /dev/null +++ b/mixer.h @@ -0,0 +1,18 @@ + +#ifndef MIXER_H__ +#define MIXER_H__ + +#include "intern.h" + +typedef void (*mix_repeat_sound_cb)(const uint8_t **data, uint32_t *size); + +struct mixer_t { + void (*init)(); + void (*fini)(); + void (*play_sound)(const uint8_t *data, uint32_t size, int freq, mix_repeat_sound_cb repeat_cb); + void (*play_music)(const uint8_t *data, uint32_t size); +}; + +extern struct mixer_t g_mix; + +#endif diff --git a/p2/game.c b/p2/game.c index e795d80..6facdb3 100644 --- a/p2/game.c +++ b/p2/game.c @@ -16,10 +16,6 @@ void update_input() { g_vars.input.key_down = (g_sys.input.direction & INPUT_DIRECTION_DOWN) != 0 ? 0xFF : 0; g_vars.input.key_space = g_sys.input.space ? 0xFF : 0; g_vars.input.key_jump = g_sys.input.jump ? 0xFF : 0; - - g_vars.input.keystate[2] = g_sys.input.digit1; - g_vars.input.keystate[3] = g_sys.input.digit2; - g_vars.input.keystate[4] = g_sys.input.digit3; } static void wait_input(int timeout) { @@ -182,9 +178,8 @@ void do_gameover_screen() { uint8_t *data = load_file("GAMEOVER.SQZ"); if (data) { video_copy_img(data); - video_copy_background(); g_sys.set_screen_palette(gameover_palette_data, 0, 16, 6); - g_sys.copy_bitmap(g_res.vga, GAME_SCREEN_W, GAME_SCREEN_H); + update_screen_img(g_res.background, 0); do_gameover_animation(); g_sys.fade_out_palette(); free(data); @@ -214,16 +209,15 @@ static bool do_menu() { update_screen_img(data + 768, 0); g_sys.fade_in_palette(); free(data); - memset(g_vars.input.keystate, 0, sizeof(g_vars.input.keystate)); const uint32_t start = g_sys.get_timestamp(); while (!g_sys.input.quit) { update_input(); - if (g_vars.input.keystate[2] || g_vars.input.keystate[0x4F] || g_sys.input.space) { + if (g_sys.input.digit1 || g_sys.input.space) { g_sys.input.space = 0; g_sys.fade_out_palette(); break; } - if (g_vars.input.keystate[3] || g_vars.input.keystate[0x50]) { + if (g_sys.input.digit2 || g_vars.input.key_down) { g_sys.fade_out_palette(); break; } @@ -241,13 +235,13 @@ static void do_photos_screen() { } void input_check_ctrl_alt_e() { - if (g_vars.input.keystate[0x1D] && g_vars.input.keystate[0x38] && g_vars.input.keystate[0x12]) { + if (0) { do_photos_screen(); } } void input_check_ctrl_alt_w() { - if (g_vars.input.keystate[0x1D] && g_vars.input.keystate[0x38] && g_vars.input.keystate[0x11]) { + if (0) { do_credits(); wait_input(60); } @@ -318,9 +312,8 @@ uint16_t random_get_number3(uint16_t x) { return rol16(x, 3); } -static void game_run(const char *data_path) { - res_init(data_path, GAME_SCREEN_W * GAME_SCREEN_H); - sound_init(); +static void game_run() { + video_init(); video_convert_tiles(g_res.uniondat, g_res.unionlen); g_vars.level_num = g_options.start_level; do_programmed_in_1992_screen(); @@ -359,12 +352,13 @@ static void game_run(const char *data_path) { print_debug(DBG_GAME, "previous level %d current %d", level_num, g_vars.level_num); } while (!g_res.dos_demo && g_vars.level_num != level_num); } - sound_fini(); - res_fini(); } EXPORT_SYMBOL struct game_t game_p2 = { "Prehistorik 2", + res_init, + res_fini, + sound_init, + sound_fini, game_run }; - diff --git a/p2/game.h b/p2/game.h index 452f39f..5936ba6 100644 --- a/p2/game.h +++ b/p2/game.h @@ -119,7 +119,6 @@ struct vars_t { uint16_t d, e; } random; struct { - bool keystate[128]; uint8_t key_left, key_right, key_down, key_up, key_space, key_jump; uint8_t key_vdir, key_hdir; uint16_t demo_offset; @@ -322,7 +321,6 @@ extern void random_reset(); extern uint8_t random_get_number(); extern uint16_t random_get_number2(); extern uint16_t random_get_number3(uint16_t x); -extern void game_main(); /* level.c */ extern void do_level(); @@ -337,6 +335,7 @@ extern void monster_change_next_anim(struct object_t *obj); extern void monster_change_prev_anim(struct object_t *obj); /* screen.c */ +extern void video_init(); extern void video_draw_string(int offset, int hspace, const char *s); extern void video_clear(); extern void video_copy_img(const uint8_t *src); @@ -352,6 +351,7 @@ extern void video_load_front_tiles(); extern void video_transition_close(); extern void video_transition_open(); extern void video_load_sprites(); +extern void video_set_sprite_pos_flags(int flag); extern void video_draw_sprite(int num, int x, int y, int flag); extern void video_put_pixel(int x, int y, uint8_t color); diff --git a/p2/level.c b/p2/level.c index 1bfb954..e1646a3 100644 --- a/p2/level.c +++ b/p2/level.c @@ -12,7 +12,6 @@ static const bool _demo_inputs = false; static const bool _expert = true; -static const bool _redraw_tilemap = true; static const bool _redraw_panel = true; static const uint16_t _undefined = 0x55AA; @@ -323,51 +322,23 @@ static void level_update_tilemap() { } else if (g_vars.level_animated_tiles_current_tbl == g_vars.tile_tbl3) { g_vars.level_animated_tiles_current_tbl = g_vars.tile_tbl1; } - } else { - if (!_redraw_tilemap) { - return; - } } video_copy_background(); g_vars.tile_attr2_flags = 0; uint16_t offset = (g_vars.tilemap.y << 8) | g_vars.tilemap.x; - for (int y = 0; y < (TILEMAP_SCREEN_H / 16) + 1; ++y) { - for (int x = 0; x < (TILEMAP_SCREEN_W / 16) + 1; ++x) { + int tilemap_w = (TILEMAP_SCREEN_W / 16) + 1; + int tilemap_h = (TILEMAP_SCREEN_H / 16) + 1; + if (g_vars.level_num == 9) { /* minotaur boss expects original screen resolution */ + offset = 0; + tilemap_w = 320 / 16; + tilemap_h = (200 - PANEL_H) / 16; + } + for (int y = 0; y < tilemap_h; ++y) { + for (int x = 0; x < tilemap_w; ++x) { const uint8_t tile_num = level_get_tile(offset + x); g_vars.tile_attr2_flags |= g_res.level.tile_attributes2[tile_num]; - if (_redraw_tilemap || g_vars.animated_tile_flag_tbl[tile_num] != 0) { - const uint8_t num = g_vars.level_animated_tiles_current_tbl[tile_num]; - level_draw_tile(num, x, y); - } - } - offset += 256; - } -} - -static void level_draw_tilemap() { - if (_redraw_tilemap) { - return; - } - if (g_vars.tilemap.redraw_flag1 == 0) { - const bool changed = (g_vars.tilemap.x != g_vars.tilemap.prev_x) || (g_vars.tilemap.y != g_vars.tilemap.prev_y); - if (!changed) { - return; - } - g_vars.tilemap.prev_x = g_vars.tilemap.x; - g_vars.tilemap.prev_y = g_vars.tilemap.y; - if (g_vars.tilemap.redraw_flag2 == 0) { - return; - } - } - g_vars.tilemap.redraw_flag1 = 0; - g_vars.tilemap.redraw_flag2 = 0; - g_vars.tile_attr2_flags = 0; - uint16_t offset = (g_vars.tilemap.y << 8) | g_vars.tilemap.x; - for (int y = 0; y < (TILEMAP_SCREEN_H / 16) + 1; ++y) { - for (int x = 0; x < TILEMAP_SCREEN_W / 16; ++x) { - const uint8_t tile_num = level_get_tile(offset + x); - g_vars.tile_attr2_flags |= g_res.level.tile_attributes2[tile_num]; - level_draw_tile(tile_num, x, y); + const uint8_t num = g_vars.level_animated_tiles_current_tbl[tile_num]; + level_draw_tile(num, x, y); } offset += 256; } @@ -621,7 +592,6 @@ static void level_init_tilemap() { g_vars.tilemap.redraw_flag2 = 1; g_vars.tilemap.prev_x = _undefined; g_vars.tilemap.prev_y = _undefined; - level_draw_tilemap(); video_transition_open(); } @@ -2388,17 +2358,6 @@ static void level_update_player_flying() { static void level_update_player() { g_vars.objects_tbl[0].spr_num = 0xFFFF; - if (g_vars.input.keystate[0x3B]) { - if (g_vars.restart_level_flag == 0) { - level_player_die(); - g_vars.restart_level_flag = 1; - return; - } - } - if (g_vars.input.keystate[0x3C]) { - g_vars.player_death_flag = 1; - return; - } input_check_ctrl_alt_w(); if (_demo_inputs) { if (g_vars.input.demo_offset < g_res.keyblen) { @@ -3014,7 +2973,6 @@ static void level_update_gates() { g_vars.boss_level5.idle_counter = 8; memset(&g_vars.objects_tbl[91], 0xFF, sizeof(struct object_t) * 6); } - level_draw_tilemap(); level_update_objects_decors(); level_update_objects_items(); level_update_objects_monsters(); @@ -3267,16 +3225,20 @@ static void level_update_light_palette() { } } -static void level_sync() { +static void level_wait() { update_input(); - g_sys.copy_bitmap(g_res.vga, GAME_SCREEN_W, GAME_SCREEN_H); - g_sys.update_screen(); - g_sys.render_clear_sprites(); const int diff = (g_vars.timestamp + (1000 / 30)) - g_sys.get_timestamp(); g_sys.sleep(MAX(diff, 10)); g_vars.timestamp = g_sys.get_timestamp(); } +static void level_sync() { + g_sys.copy_bitmap(g_res.vga, GAME_SCREEN_W, GAME_SCREEN_H); + g_sys.update_screen(); + g_sys.render_clear_sprites(); + level_wait(); +} + static void level_draw_objects() { ++g_vars.level_draw_counter; for (int i = OBJECTS_COUNT - 1; i >= 0; --i) { @@ -3482,7 +3444,6 @@ static void level_player_death_animation() { level_update_objects_bonuses(); level_update_objects_bonus_scores(); level_update_tilemap(); - level_draw_tilemap(); level_draw_panel(); level_draw_orbs(); level_draw_objects(); @@ -3572,6 +3533,7 @@ static int level_completed_bonuses_animation_helper() { } static void level_completed_bonuses_animation() { + video_set_sprite_pos_flags(1); /* center */ if (g_vars.light.state != 0) { g_vars.light.palette_flag1 = 0; g_vars.light.palette_flag2 = 1; @@ -3728,6 +3690,7 @@ static void level_completed_bonuses_animation() { g_vars.objects_tbl[1].x_pos += 2; } } while (g_vars.objects_tbl[2].x_pos > -52); + video_set_sprite_pos_flags(0); } static void update_object_demo_animation(struct object_t *obj) { @@ -3868,6 +3831,7 @@ void do_gameover_animation() { g_vars.objects_tbl[i].spr_num = 0xFFFF; } video_load_sprites(); + video_set_sprite_pos_flags(1); /* center */ g_vars.tilemap.x = g_vars.tilemap.scroll_dx = 0; g_vars.tilemap.y = g_vars.tilemap.scroll_dy = 0; static const char *gameover = "GAMEOVER"; @@ -3909,11 +3873,14 @@ void do_gameover_animation() { do_gameover_animation_helper(); level_draw_objects(); level_update_panel(); - level_sync(); + g_sys.update_screen(); + g_sys.render_clear_sprites(); + level_wait(); if (g_sys.input.quit) { return; } } while (timer_counter < 630 && !g_sys.input.space); + video_set_sprite_pos_flags(0); } void do_level() { @@ -3949,7 +3916,6 @@ void do_level() { g_vars.tilemap_adjust_player_pos_flag = false; level_update_scrolling(); level_update_tilemap(); - level_draw_tilemap(); level_draw_panel(); level_draw_orbs(); level_draw_objects(); diff --git a/p2/screen.c b/p2/screen.c index 7c91b53..890c64b 100644 --- a/p2/screen.c +++ b/p2/screen.c @@ -11,6 +11,15 @@ #define MAX_SPRITESHEET_H 1024 #define MAX_FRONT_TILES 168 +static int _spr_pos_flags; + +static int _offset_x_center, _offset_y_center; + +void video_init() { + _offset_x_center = (GAME_SCREEN_W > 320) ? (GAME_SCREEN_W - 320) / 2 : 0; + _offset_y_center = (GAME_SCREEN_H > 200) ? (GAME_SCREEN_H - 200) / 2 : 0; +} + static void decode_planar(const uint8_t *src, uint8_t *dst, int dst_pitch, int w, int h, uint8_t transparent_color) { const int plane_size = h * w / 8; for (int y = 0; y < h; ++y) { @@ -279,7 +288,15 @@ void video_load_sprites() { } } +void video_set_sprite_pos_flags(int flags) { + _spr_pos_flags = flags; +} + void video_draw_sprite(int num, int x, int y, int flag) { + if (_spr_pos_flags) { + x += _offset_x_center; + y += _offset_y_center; + } g_sys.render_add_sprite(RENDER_SPR_GAME, num, x, y, flag != 0); } diff --git a/p2/sound.c b/p2/sound.c index 2c6f0da..545ca55 100644 --- a/p2/sound.c +++ b/p2/sound.c @@ -1,31 +1,16 @@ #include "game.h" #include "resource.h" -#include "sys.h" +#include "mixer.h" #include "util.h" -#include - #define MAX_SOUNDS 11 -static const bool _volume = false; - static const uint16_t sound_sizes_tbl[] = { 0x188E, 0x1C80, 0x235E, 0x19E6, 0x0AB2, 0x0912, 0x0000, 0x35D2, 0x06C4, 0x1C86, 0x0E2E }; -static const uint8_t sound_volume_tbl[] = { - 0x3F,0x37,0x32,0x2F,0x2C,0x2A,0x28,0x27,0x26,0x24,0x23,0x22,0x21,0x21,0x20,0x1F, - 0x1E,0x1E,0x1D,0x1C,0x1C,0x1B,0x1B,0x1A,0x1A,0x19,0x19,0x19,0x18,0x18,0x17,0x17, - 0x17,0x16,0x16,0x16,0x15,0x15,0x15,0x15,0x14,0x14,0x14,0x14,0x13,0x13,0x13,0x13, - 0x12,0x12,0x12,0x12,0x11,0x11,0x11,0x11,0x11,0x10,0x10,0x10,0x10,0x10,0x0F,0x0F, - 0x0F,0x0F,0x0F,0x0F,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D, - 0x0D,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B, - 0x0B,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x09,0x09,0x09,0x09,0x09,0x09, - 0x09,0x09,0x09,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x07,0x07 -}; - static const char *trk_names_tbl[] = { "PRES.TRK", "CODE.TRK", @@ -47,85 +32,35 @@ static const char *trk_names_tbl[] = { "BOULA.TRK" }; -struct mixerchannel_t { - uint8_t *data; - uint32_t pos; - uint32_t step; - uint32_t size; -}; - -static const int _rate = SYS_AUDIO_FREQ; -static struct mixerchannel_t _channel; -static ModPlugFile *_mpf; static int _music_num; static uint16_t sound_offsets_tbl[MAX_SOUNDS]; -static void mix(void *param, uint8_t *buf, int len) { - memset(buf, 0, len); - if (_mpf) { - const int count = ModPlug_Read(_mpf, buf, len); - if (count == 0) { - ModPlug_SeekOrder(_mpf, 0); - } - } - if (_channel.data) { - for (int i = 0; i < len; i += sizeof(int16_t)) { - const int pos = _channel.pos >> 16; - if (pos >= _channel.size) { - _channel.data = 0; - break; - } - const int8_t pcm = _volume ? sound_volume_tbl[(_channel.data[pos] ^ 0x80) >> 1] : _channel.data[pos]; - const int sample = *(int16_t *)(buf + i) + pcm * 256; - *(int16_t *)(buf + i) = (sample < -32768 ? -32768 : (sample > 32767 ? 32767 : sample)); - _channel.pos += _channel.step; - } - } -} - void sound_init() { - ModPlug_Settings mp_settings; - memset(&mp_settings, 0, sizeof(mp_settings)); - ModPlug_GetSettings(&mp_settings); - mp_settings.mFlags = MODPLUG_ENABLE_OVERSAMPLING | MODPLUG_ENABLE_NOISE_REDUCTION; - mp_settings.mChannels = 1; - mp_settings.mBits = 16; - mp_settings.mFrequency = _rate; - mp_settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; - mp_settings.mLoopCount = -1; - ModPlug_SetSettings(&mp_settings); uint16_t offset = 0; for (int i = 0; i < MAX_SOUNDS; ++i) { sound_offsets_tbl[i] = offset; offset += sound_sizes_tbl[i]; } _music_num = -1; - g_sys.start_audio(mix, 0); } void sound_fini() { - g_sys.stop_audio(); } void play_sound(int num) { assert(num < MAX_SOUNDS); - print_debug(DBG_MIXER, "play_sound %d", num); + print_debug(DBG_SOUND, "play_sound %d", num); if (!g_res.samples) { /* no SAMPLE. file with demo */ return; } const int sample_offset = sound_offsets_tbl[num]; const int sample_size = sound_sizes_tbl[num]; - print_debug(DBG_MIXER, "sample num %d offset 0x%x size %d", num, sample_offset, sample_size); + print_debug(DBG_SOUND, "sample num %d offset 0x%x size %d", num, sample_offset, sample_size); if (sample_size == 0) { return; } - g_sys.lock_audio(); - _channel.data = g_res.samples + sample_offset; - _channel.pos = 0; - _channel.step = (8000 << 16) / _rate; - _channel.size = sample_size; - g_sys.unlock_audio(); + g_mix.play_sound(g_res.samples + sample_offset, sample_size, 8000, 0); } void play_music(int num) { @@ -137,21 +72,12 @@ void play_music(int num) { } const char *filename = trk_names_tbl[num]; if (filename) { - print_debug(DBG_MIXER, "play_music '%s'", filename); - g_sys.lock_audio(); - if (_mpf) { - ModPlug_Unload(_mpf); - _mpf = 0; - } + print_debug(DBG_SOUND, "play_music '%s'", filename); uint8_t *data = load_file(filename); if (data) { - _mpf = ModPlug_Load(data, g_uncompressed_size); - if (_mpf) { - print_debug(DBG_MIXER, "Loaded module '%s'", ModPlug_GetName(_mpf)); - } + g_mix.play_music(data, g_uncompressed_size); free(data); _music_num = num; } - g_sys.unlock_audio(); } } diff --git a/util.c b/util.c index 65d3715..eb622f3 100644 --- a/util.c +++ b/util.c @@ -73,13 +73,17 @@ FILE *fopen_nocase(const char *path, const char *filename) { snprintf(buf, sizeof(buf), "%s/%s", path, filename); FILE *fp = fopen(buf, "rb"); if (!fp) { + static void (*const str[3])(char *) = { + string_upper, + string_lower, + 0 + }; char *p = buf + strlen(path) + 1; - string_upper(p); - fp = fopen(buf, "rb"); - if (!fp) { - char *p = buf + strlen(path) + 1; - string_lower(p); - fp = fopen(buf, "rb"); + for (int i = 0; str[i] && !fp; ++i) { + (str[i])(p); + if (strcmp(filename, p) != 0) { + fp = fopen(buf, "rb"); + } } } return fp; diff --git a/util.h b/util.h index f5c06c7..257056f 100644 --- a/util.h +++ b/util.h @@ -11,6 +11,7 @@ #define DBG_SYSTEM (1 << 4) #define DBG_UNPACK (1 << 5) #define DBG_SCREEN (1 << 6) +#define DBG_SOUND (1 << 7) extern int g_debug_mask;