From e46e90d22a17037f186e3db963d100b109d70054 Mon Sep 17 00:00:00 2001 From: Gregory Montoir Date: Fri, 27 Jul 2018 22:02:05 +0800 Subject: [PATCH] Import blues from 3c41f366 --- game.c | 29 ----------------------------- game.h | 34 +++++++++++++++++----------------- level.c | 21 +++++++++++---------- main.c | 18 ++++++++++++++++++ opcodes.c | 8 ++------ resource.c | 3 ++- resource.h | 1 + screen.c | 23 +++++++++++++++++------ sys_sdl2.c | 3 ++- triggers.c | 1 + 10 files changed, 71 insertions(+), 70 deletions(-) diff --git a/game.c b/game.c index 389cc1c..de26590 100644 --- a/game.c +++ b/game.c @@ -42,20 +42,6 @@ void do_title_screen() { g_sys.input.space = 0; } -static void check_cheat_code() { - static const uint8_t codes[] = { 0x14, 0x17, 0x27, 0x18, 0x14, 0x23, 0x12, 0x12 }; - if ((g_vars.inp_code & 0x80) == 0 && g_vars.inp_code != 0) { - if (g_vars.inp_code == codes[g_vars.cheat_code_len]) { - ++g_vars.cheat_code_len; - if (g_vars.cheat_code_len == ARRAYSIZE(codes)) { - g_vars.cheat_flag = 1; - } - } else { - g_vars.cheat_code_len = 0; - } - } -} - void do_select_player() { int quit = 0; int fade = 0; @@ -197,17 +183,6 @@ void do_select_player() { } screen_clear_last_sprite(); screen_redraw_sprites(); - if (g_vars.cheat_flag) { - for (int i = 5; i >= 0; --i) { - if (g_vars.inp_keyboard[2 + i]) { - g_vars.level = i; - break; - } - } -// screen_draw_number_type1(_level + 1, 256, 148, 2); - } else { - check_cheat_code(); - } screen_flip(); screen_vsync(); const int diff = (timestamp + (1000 / 30)) - g_sys.get_timestamp(); @@ -276,7 +251,6 @@ static void do_inter_screen() { } g_vars.screen_draw_offset = 0x2000; screen_flip(); - g_vars.screen_h = TILEMAP_SCREEN_H; const uint32_t timestamp = g_sys.get_timestamp() + 4 * 1000; do { update_input(); @@ -289,8 +263,6 @@ static void do_inter_screen() { void game_main() { play_music(0); - g_vars.screen_w = GAME_SCREEN_W; - g_vars.screen_h = GAME_SCREEN_H; g_vars.screen_draw_offset = 0; screen_init(); screen_flip(); @@ -350,7 +322,6 @@ void game_main() { do_title_screen(); while (!g_sys.input.quit) { if (!g_vars.level_completed_flag) { -// _level_cheat_code = 0; g_vars.game_over_flag = 0; g_vars.play_level_flag = 1; if (!g_vars.play_demo_flag) { diff --git a/game.h b/game.h index 903c895..e09e178 100644 --- a/game.h +++ b/game.h @@ -4,8 +4,8 @@ #include "intern.h" -#define GAME_SCREEN_W 320 -#define GAME_SCREEN_H 200 +#define GAME_SCREEN_W g_options.screen_w +#define GAME_SCREEN_H g_options.screen_h #define TILEMAP_OFFSET_Y 14 #define TILEMAP_SCREEN_W GAME_SCREEN_W @@ -33,13 +33,17 @@ #define SOUND_15 15 #define SOUND_16 16 -#define CHEATS_NO_HIT (1 << 0) +#define CHEATS_NO_HIT (1 << 0) +#define CHEATS_UNLIMITED_LIFES (1 << 1) +#define CHEATS_UNLIMITED_ENERGY (1 << 2) struct options_t { uint32_t cheats; int start_level; int start_xpos16; int start_ypos16; + int screen_w; + int screen_h; bool amiga_copper_bars; bool amiga_colors; bool amiga_data; @@ -145,7 +149,6 @@ struct vars_t { int start_level; int16_t level_xpos[MAX_OBJECTS]; int16_t level_ypos[MAX_OBJECTS]; - int screen_w, screen_h; int screen_tilemap_w, screen_tilemap_h; int screen_tilemap_w16, screen_tilemap_h16; int screen_tilemap_xorigin, screen_tilemap_yorigin; @@ -154,18 +157,18 @@ struct vars_t { int screen_scrolling_dirmask, screen_unk1; int screen_draw_h, screen_draw_offset; int screen_tile_lut[256]; - int level_completed_flag; - int play_level_flag; - int game_over_flag; - int found_music_instrument_flag; - int player2_dead_flag; - int player1_dead_flag; - int player2_scrolling_flag; - int play_demo_flag; - int quit_level_flag; + bool level_completed_flag; + bool play_level_flag; + bool game_over_flag; + bool found_music_instrument_flag; + bool player2_dead_flag; + bool player1_dead_flag; + bool player2_scrolling_flag; + bool play_demo_flag; + bool quit_level_flag; + bool two_players_flag; int music_num; uint8_t inp_keyboard[256]; - uint8_t inp_code; int inp_key_space; int inp_key_tab; int inp_key_up; @@ -176,10 +179,7 @@ struct vars_t { int inp_key_down_prev; int inp_key_action; struct door_t doors[MAX_DOORS]; - int cheat_code_len; - int cheat_flag; struct object_t objects[MAX_OBJECTS]; - int two_players_flag; int vinyls_count; uint16_t level_loop_counter; int triggers_counter; diff --git a/level.c b/level.c index a78a5bb..9219bd0 100644 --- a/level.c +++ b/level.c @@ -232,10 +232,9 @@ static void init_level() { obj->data51 = 3; obj->vinyls_count = 0; } - if (g_vars.cheat_flag) { + if (g_options.cheats & CHEATS_UNLIMITED_LIFES) { obj->lifes_count = 3; obj->data51 = 3; - obj->vinyls_count = 0; } obj->unk63 = 0; obj->flag_end_level = 0; @@ -646,7 +645,7 @@ static void do_level_add_sprite1_case4(struct object_t *obj) { obj35->xpos16 = obj->xpos16; obj35->ypos16 = obj->ypos16; obj35->anim_num = 1; - obj37->animframes_ptr = animframes_059d + (obj37->type * 116 / 4); + obj35->animframes_ptr = animframes_059d + (obj35->type * 116 / 4); } else { obj35->unk2E = 0; const int num = triggers_get_tile_type(obj35->xpos16, obj35->ypos16); @@ -709,6 +708,8 @@ static void do_level_add_sprite1(struct object_t *obj) { static void do_level_add_sprite2(struct object_t *obj) { print_debug(DBG_GAME, "add_sprite2 obj->type %d", obj->type); + assert(obj->type == 2); + assert(obj->animframes_ptr); const uint8_t *anim_data = obj->animframes_ptr[obj->grab_type]; if (obj->anim_num < anim_data[0]) { ++obj->anim_num; @@ -812,7 +813,7 @@ void do_level_update_tile(int x, int y, int num) { if ((g_vars.screen_tilemap_yorigin >> 4) > y) { return; } - if ((g_vars.screen_tilemap_xorigin >> 4) + (TILEMAP_SCREEN_H / 16) <= y) { + if ((g_vars.screen_tilemap_yorigin >> 4) + (TILEMAP_SCREEN_H / 16) <= y) { return; } if (num >= 128) { @@ -1381,15 +1382,15 @@ static void do_level_update_object_bounds(struct object_t *obj) { int _si = g_vars.objects[OBJECT_NUM_PLAYER1].screen_xpos - obj->screen_xpos; int _di = g_vars.objects[OBJECT_NUM_PLAYER1].screen_ypos - obj->screen_ypos; if (g_vars.objects[OBJECT_NUM_PLAYER1].special_anim == 16) { - _si = 320; - _di = 200; + _si = GAME_SCREEN_W; + _di = GAME_SCREEN_H; } if (g_vars.two_players_flag) { int tmp_dx = g_vars.objects[OBJECT_NUM_PLAYER2].screen_xpos - obj->screen_xpos; int tmp_dy = g_vars.objects[OBJECT_NUM_PLAYER2].screen_ypos - obj->screen_ypos; if (g_vars.objects[OBJECT_NUM_PLAYER2].special_anim == 16) { - tmp_dx = 320; - tmp_dy = 200; + tmp_dx = GAME_SCREEN_W; + tmp_dy = GAME_SCREEN_H; } if (ABS(_si) >= ABS(tmp_dx) && ABS(_di) >= ABS(tmp_dy)) { obj->player_xdist = tmp_dx; @@ -1625,7 +1626,7 @@ static void do_level_handle_object_bonus_collision(struct object_t *obj, struct void do_level_player_hit(struct object_t *obj) { if (obj->blinking_counter == 0) { g_vars.screen_draw_h = 172; - if (obj->data51 > 0) { + if (obj->data51 > 0 && (g_options.cheats & CHEATS_UNLIMITED_ENERGY) == 0) { --obj->data51; do_level_update_panel_lifes(obj); } @@ -2167,7 +2168,7 @@ void do_level() { g_vars.player2_scrolling_flag = 0; g_vars.screen_draw_h = TILEMAP_SCREEN_H; g_vars.found_music_instrument_flag = 0; - render_set_sprites_clipping_rect(0, TILEMAP_OFFSET_Y, TILEMAP_SCREEN_W, TILEMAP_SCREEN_H - TILEMAP_OFFSET_Y); + render_set_sprites_clipping_rect(0, TILEMAP_OFFSET_Y, TILEMAP_SCREEN_W, TILEMAP_SCREEN_H); do { const uint32_t timestamp = g_sys.get_timestamp(); update_input(); diff --git a/main.c b/main.c index 5edb5f1..d61f48a 100644 --- a/main.c +++ b/main.c @@ -20,11 +20,19 @@ static const char *USAGE = "Usage: %s [OPTIONS]...\n" " --datapath=PATH Path to data files (default '.')\n" " --level=NUM Start at level NUM\n" + " --debug=MASK Debug mask\n" + " --startpos=XxY Start at position (X,Y)\n" + " --fullscreen Enable fullscreen\n" + " --scale Graphics scaling factor (default 2)\n" + " --filter Graphics scaling filter\n" + " --screensize=WxH Graphics screen size (default 320x200)\n" ; int main(int argc, char *argv[]) { g_options.start_xpos16 = -1; g_options.start_ypos16 = -1; + g_options.screen_w = 320; + g_options.screen_h = 200; g_options.amiga_copper_bars = true; g_options.amiga_colors = true; // g_options.amiga_data = true; @@ -49,6 +57,7 @@ int main(int argc, char *argv[]) { { "fullscreen", no_argument, 0, 6 }, { "scale", required_argument, 0, 7 }, { "filter", required_argument, 0, 8 }, + { "screensize", required_argument, 0, 9 }, { 0, 0, 0, 0 }, }; int index; @@ -81,6 +90,12 @@ int main(int argc, char *argv[]) { case 8: scale_filter = strdup(optarg); break; + case 9: + sscanf(optarg, "%dx%d", &g_options.screen_w, &g_options.screen_h); + // align to tile 16x16 + g_options.screen_w = (g_options.screen_w + 15) & ~15; + g_options.screen_h = ((g_options.screen_h + 15) & ~15) + 40; + break; default: fprintf(stdout, USAGE, argv[0]); return -1; @@ -99,5 +114,8 @@ int main(int argc, char *argv[]) { if (data_path != DEFAULT_DATA_PATH) { free((char *)data_path); } + if (scale_filter != DEFAULT_SCALE_FILTER) { + free((char *)scale_filter); + } return 0; } diff --git a/opcodes.c b/opcodes.c index f3a98b1..4792a43 100644 --- a/opcodes.c +++ b/opcodes.c @@ -168,11 +168,7 @@ static void object_func_op7(struct object_t *obj) { obj->unk42 = 0; do_level_update_projectile(obj); } - if (obj->player_xdist < 0) { - obj->facing_left = 1; - } else { - obj->facing_left = 0; - } + obj->facing_left = (obj->player_xdist < 0) ? 1 : 0; } } else { if (obj->anim_num == 16) { @@ -306,7 +302,7 @@ static void object_func_op14_helper(int x1, int y1, int x2, int y2, int color) { static void object_func_op14(struct object_t *obj) { obj->special_anim = 2; - object_func_op14_helper(obj->xpos, level_ypos_egou[obj->unk5D] - g_vars.screen_tilemap_yorigin, obj->xpos, obj->ypos - 5, 3); + object_func_op14_helper(obj->screen_xpos, level_ypos_egou[obj->unk5D] - g_vars.screen_tilemap_yorigin, obj->screen_xpos, obj->screen_ypos - 5, 3); if (obj->elevator_direction == 1) { if (obj->moving_direction < 25) { ++obj->moving_direction; diff --git a/resource.c b/resource.c index 1cb7463..b0af510 100644 --- a/resource.c +++ b/resource.c @@ -32,6 +32,7 @@ void res_init(int vga_size) { if (!g_res.vga) { print_error("Failed to allocate vga buffer, %d bytes", vga_size); } + g_res.vga_size = vga_size; static const int TILES_SIZE = 640 * 200; g_res.tiles = (uint8_t *)malloc(TILES_SIZE); if (!g_res.tiles) { @@ -262,7 +263,7 @@ void load_img(const char *filename, int screen_w) { load_iff(g_res.tmp, size, g_res.tmp + 32000, screen_w); g_sys.set_screen_palette(g_res.palette, 16); g_sys.update_screen(g_res.tmp + 32000, 0); - memcpy(g_res.vga, g_res.tmp + 32000, 64000); + memcpy(g_res.vga, g_res.tmp + 32000, g_res.vga_size); } void load_m(const char *filename) { diff --git a/resource.h b/resource.h index cf0e1b1..c94b2e2 100644 --- a/resource.h +++ b/resource.h @@ -43,6 +43,7 @@ struct resource_data_t { uint8_t palette[16 * 3]; struct trigger_t triggers[MAX_TRIGGERS]; uint8_t *vga; + int vga_size; uint8_t *tiles; uint8_t *snd; }; diff --git a/screen.c b/screen.c index 34fa192..8a1d48e 100644 --- a/screen.c +++ b/screen.c @@ -8,8 +8,12 @@ #define MAX_SPRITESHEET_W 512 #define MAX_SPRITESHEET_H 512 +static int _offset_x, _offset_y; + void screen_init() { memset(g_res.vga, 0, GAME_SCREEN_W * GAME_SCREEN_H); + _offset_x = (GAME_SCREEN_W > 320) ? (GAME_SCREEN_W - 320) / 2 : 0; // center horizontally + _offset_y = (GAME_SCREEN_H > 200) ? (GAME_SCREEN_H - 200) : 0; // align to bottom } void screen_clear_sprites() { @@ -24,6 +28,11 @@ static void add_game_sprite(int x, int y, int frame, int xflip) { if (frame >= SPRITES_COUNT) { spr_type = RENDER_SPR_LEVEL; frame -= SPRITES_COUNT; + } else { + if (y >= 161 && frame >= 120) { + x += _offset_x; + y += _offset_y; + } } render_add_sprite(spr_type, frame, x - w / 2, y - h, xflip); } @@ -56,11 +65,9 @@ void screen_vsync() { } void screen_draw_frame(const uint8_t *frame, int fh, int fw, int x, int y) { - if (GAME_SCREEN_W > 320) { - x += (GAME_SCREEN_W - 320) / 2; - } - if (GAME_SCREEN_H > 200 && y == 161) { // align to the bottom - y += GAME_SCREEN_H - 200; + x += _offset_x; + if (y == 161) { + y += _offset_y; } y += fh + 2; if (g_options.amiga_status_bar) { @@ -85,7 +92,7 @@ void screen_flip() { } void screen_unk4() { - memcpy(g_res.vga, g_res.tmp + 32000, 64000); + memcpy(g_res.vga, g_res.tmp + 32000, GAME_SCREEN_W * GAME_SCREEN_H); } void screen_unk5() { @@ -162,6 +169,10 @@ static void draw_number_amiga(int digit, int x, int y) { } void screen_draw_number(int num, int x, int y, int color) { + if (y >= 161) { + x += _offset_x; + y += _offset_y; + } y += TILEMAP_OFFSET_Y; if (g_options.amiga_status_bar) { draw_number_amiga(num / 10, x - 8, y - 2); diff --git a/sys_sdl2.c b/sys_sdl2.c index 31e96c7..9db7a0a 100644 --- a/sys_sdl2.c +++ b/sys_sdl2.c @@ -4,6 +4,7 @@ #include "util.h" #define COPPER_BARS_H 80 +#define MAX_SPRITES 256 static const int FADE_STEPS = 16; @@ -22,7 +23,7 @@ struct sprite_t { bool xflip; }; -static struct sprite_t _sprites[128]; +static struct sprite_t _sprites[MAX_SPRITES]; static int _sprites_count; static SDL_Rect _sprites_cliprect; diff --git a/triggers.c b/triggers.c index 33791fb..fa10362 100644 --- a/triggers.c +++ b/triggers.c @@ -757,6 +757,7 @@ void triggers_update_tiles1(struct object_t *obj) { return; } p = t->op_table3; + obj->trigger3 = p; if (p[1] == 11) { if (obj->unk60 == 0) { obj->unk60 = p[9];