diff --git a/bb/game.c b/bb/game.c index 8ff329c..5515d6a 100644 --- a/bb/game.c +++ b/bb/game.c @@ -34,7 +34,7 @@ void update_input() { static void do_title_screen() { const uint32_t timestamp = g_sys.get_timestamp() + 20 * 1000; load_img(g_res.amiga_data ? "blues.lbm" : "pres.sqz", GAME_SCREEN_W, g_options.cga_colors ? 0 : -1); - fade_in_palette(); + g_sys.fade_in_palette(); do { update_input(); if (g_sys.input.space || g_sys.input.quit) { @@ -51,7 +51,7 @@ static void do_demo_screens() { static const char *filenames[] = { "text1.sqz", "maq1.sqz", "maq2.sqz", "maq3.sqz", "maq4.sqz", "maq5.sqz", 0 }; for (int i = 0; filenames[i]; ++i) { load_img(filenames[i], GAME_SCREEN_W, -1); - fade_in_palette(); + g_sys.fade_in_palette(); while (1) { update_input(); if (g_sys.input.space) { @@ -197,7 +197,7 @@ static void do_select_player() { break; } if (!fade) { - fade_in_palette(); + g_sys.fade_in_palette(); fade = 1; for (int i = 0; i < colors_count; ++i) { screen_adjust_palette_color( 3, color_rgb, 1); @@ -205,7 +205,6 @@ static void do_select_player() { } continue; } - screen_redraw_sprites(); screen_flip(); screen_vsync(); const int diff = (timestamp + (1000 / 30)) - g_sys.get_timestamp(); @@ -220,7 +219,6 @@ static void do_select_player() { static void do_inter_screen_helper(int xpos, int ypos, int c) { for (int i = 0; i < 40; ++i) { screen_add_sprite(xpos + 20 - 1 - i, ypos - 20 + 1 + i, 125); - screen_redraw_sprites(); if (c != 0) { screen_vsync(); } @@ -228,7 +226,6 @@ static void do_inter_screen_helper(int xpos, int ypos, int c) { } for (int i = 0; i < 40; ++i) { screen_add_sprite(xpos - 20 + 1 + i, ypos - 20 + 1 + i, 125); - screen_redraw_sprites(); if (c != 0) { screen_vsync(); } @@ -249,7 +246,7 @@ static void do_inter_screen() { if (g_vars.level == MAX_LEVELS - 1) { do_inter_screen_helper(xpos[g_vars.level], ypos[g_vars.level], 0); } - fade_in_palette(); + g_sys.fade_in_palette(); if (g_vars.level > 0 && g_vars.level < MAX_LEVELS - 1) { do_inter_screen_helper(xpos[g_vars.level - 1], ypos[g_vars.level - 1], 1); } @@ -258,7 +255,6 @@ static void do_inter_screen() { if (g_vars.level < MAX_LEVELS - 1) { play_sound(SOUND_2); screen_add_sprite(xpos[g_vars.level], ypos[g_vars.level], 126); - screen_redraw_sprites(); } screen_flip(); const uint32_t timestamp = g_sys.get_timestamp() + 4 * 1000; diff --git a/bb/game.h b/bb/game.h index a1807b8..efc2ff6 100644 --- a/bb/game.h +++ b/bb/game.h @@ -221,8 +221,6 @@ extern void level_call_object_func(struct object_t *); extern void screen_init(); extern void screen_clear_sprites(); extern void screen_add_sprite(int x, int y, int frame); -extern void screen_redraw_sprites(); -extern void fade_in_palette(); extern void fade_out_palette(); extern void screen_adjust_palette_color(int color, int b, int c); extern void screen_vsync(); diff --git a/bb/level.c b/bb/level.c index 2e6d0e7..ba5fbdd 100644 --- a/bb/level.c +++ b/bb/level.c @@ -2130,7 +2130,6 @@ void do_level() { // demo do_level_update_scrolling2(); do_level_update_objects(); - screen_redraw_sprites(); if (!g_res.amiga_data) { draw_foreground_tiles(); } diff --git a/bb/screen.c b/bb/screen.c index 5644ca6..4dec4a9 100644 --- a/bb/screen.c +++ b/bb/screen.c @@ -66,10 +66,6 @@ void screen_add_sprite(int x, int y, int frame) { void screen_redraw_sprites() { } -void fade_in_palette() { - g_sys.fade_in_palette(); -} - void fade_out_palette() { // g_sys.fade_out_palette(); } diff --git a/ja/game.c b/ja/game.c index a5379d4..2a87b34 100644 --- a/ja/game.c +++ b/ja/game.c @@ -35,12 +35,12 @@ static void wait_input(int timeout) { static void do_splash_screen() { load_file("titus.eat"); video_copy_vga(0x7D00); - fade_in_palette(); - fade_out_palette(); + g_sys.fade_in_palette(); + g_sys.fade_out_palette(); load_file("tiny.eat"); video_copy_vga(0x7D00); - fade_in_palette(); - fade_out_palette(); + g_sys.fade_in_palette(); + g_sys.fade_out_palette(); } static void scroll_screen_palette() { @@ -90,7 +90,7 @@ static void do_select_screen_scroll_palette_pattern4() { static void do_select_screen() { load_file("select.eat"); video_copy_vga(0x7D00); - fade_in_palette(); + g_sys.fade_in_palette(); memcpy(g_vars.palette_buffer, g_res.tmp, 256 * 3); do_select_screen_scroll_palette_pattern2(); int bl = 2; @@ -129,7 +129,7 @@ static void do_select_screen() { assert(bl == 1 || bl == 2); g_sys.input.space = 0; g_vars.player = 1 - ((bl & 3) - 1); - fade_out_palette(); + g_sys.fade_out_palette(); break; } update_input(); @@ -142,9 +142,9 @@ void do_difficulty_screen() { snprintf(name, sizeof(name), "dif%02d.eat", (g_vars.level >> 3) + 1); load_file(name); video_copy_vga(0x7D00); - fade_in_palette(); + g_sys.fade_in_palette(); wait_input(560); - fade_out_palette(); + g_sys.fade_out_palette(); } void do_level_number_screen() { @@ -154,8 +154,8 @@ void do_level_number_screen() { snprintf(buf, sizeof(buf), "%02d", g_vars.level); video_draw_string(buf, 0x5E9B, 11); video_copy_vga(0x7D00); - fade_in_palette(); - fade_out_palette(); + g_sys.fade_in_palette(); + g_sys.fade_out_palette(); } static uint16_t rol16(uint16_t x, int c) { @@ -180,16 +180,16 @@ void do_level_password_screen() { video_draw_string("STAGE NUMBER", 0x7E96, 11); video_draw_string(str, 0xABB4, 20); video_copy_vga(0x7D00); - fade_in_palette(); + g_sys.fade_in_palette(); scroll_screen_palette(); wait_input(64000); - fade_out_palette(); + g_sys.fade_out_palette(); } static void do_password_screen() { load_file("password.eat"); video_draw_string("ENTER PASSWORD", 0x7E96, 11); - fade_in_palette(); + g_sys.fade_in_palette(); char str[5] = "0000"; video_draw_string(str, 0xABB4, 20); } @@ -197,18 +197,18 @@ static void do_password_screen() { static int do_menu_screen() { load_file("menu.eat"); video_copy_vga(0x7D00); - fade_in_palette(); + g_sys.fade_in_palette(); memset(g_vars.input_keystate, 0, sizeof(g_vars.input_keystate)); g_vars.level_time = 0; while (!g_sys.input.quit) { scroll_screen_palette(); if (g_vars.input_keystate[2] || g_vars.input_keystate[0x4F] || g_sys.input.space) { g_sys.input.space = 0; - fade_out_palette(); + g_sys.fade_out_palette(); return 1; } if (g_vars.input_keystate[3] || g_vars.input_keystate[0x50]) { - fade_out_palette(); + g_sys.fade_out_palette(); return 2; } if (g_vars.input_keystate[4] || g_vars.input_keystate[0x51]) { @@ -221,22 +221,22 @@ static int do_menu_screen() { } static int do_options_screen() { - fade_out_palette(); + g_sys.fade_out_palette(); load_file("fond.eat"); video_draw_string("GAME SPEED", 0x3EE9, 11); video_draw_string("1 FAST", 0x647E, 11); video_draw_string("2 NORMAL", 0x89FE, 11); video_copy_vga(0x7D00); - fade_in_palette(); + g_sys.fade_in_palette(); memset(g_vars.input_keystate, 0, sizeof(g_vars.input_keystate)); while (!g_sys.input.quit) { scroll_screen_palette(); if (g_vars.input_keystate[2] || g_vars.input_keystate[0x4F]) { - fade_out_palette(); + g_sys.fade_out_palette(); return 1; } if (g_vars.input_keystate[3] || g_vars.input_keystate[0x50]) { - fade_out_palette(); + g_sys.fade_out_palette(); return 2; } update_input(); @@ -249,16 +249,16 @@ void do_game_over_screen() { load_file("fond.eat"); video_draw_string("GAME OVER", 0x5E2E, 11); video_copy_vga(0x7D00); - fade_in_palette(); + g_sys.fade_in_palette(); wait_input(64000); - fade_out_palette(); + g_sys.fade_out_palette(); } void do_game_win_screen() { load_file("win.eat"); video_copy_vga(0x7D00); - fade_in_palette(); - fade_out_palette(); + g_sys.fade_in_palette(); + g_sys.fade_out_palette(); load_file("end.eat"); video_copy_vga(0xB500); static const int count = 5; @@ -299,9 +299,9 @@ void do_game_win_screen() { } ++i; video_copy_vga(0x7D00); - fade_in_palette(); + g_sys.fade_in_palette(); wait_input(64000); - fade_out_palette(); + g_sys.fade_out_palette(); memcpy(g_res.tmp + 768, g_res.background, 64000); } } diff --git a/ja/game.h b/ja/game.h index 4e748d0..34c3965 100644 --- a/ja/game.h +++ b/ja/game.h @@ -215,8 +215,6 @@ extern void video_draw_sprite(int num, int x, int y, int flag); extern void video_draw_string(const char *s, int offset, int hspace); extern void video_copy_vga(int size); extern void video_copy_backbuffer(int h); -extern void fade_in_palette(); -extern void fade_out_palette(); extern void ja_decode_spr(const uint8_t *src, int w, int h, uint8_t *dst, int dst_pitch, uint8_t pal_mask); extern void ja_decode_chr(const uint8_t *buffer, const int size, uint8_t *dst, int dst_pitch); extern void ja_decode_tile(const uint8_t *buffer, uint8_t pal_mask, uint8_t *dst, int dst_pitch, int x, int y); diff --git a/ja/level.c b/ja/level.c index a716a67..e3b101a 100644 --- a/ja/level.c +++ b/ja/level.c @@ -29,7 +29,7 @@ static void do_end_of_level() { g_sys.set_palette_color(color_index, white); g_sys.update_screen(g_res.vga, 1); g_sys.sleep(1000); - fade_out_palette(); + g_sys.fade_out_palette(); } static void level_player_die(struct player_t *player) { @@ -3026,7 +3026,7 @@ void do_level() { continue; } // player fell or no energy left - fade_out_palette(); + g_sys.fade_out_palette(); assert(g_vars.player != 2); if (g_vars.players_table[0].lifes_count != 0) { init_level(get_level()); // restart diff --git a/ja/screen.c b/ja/screen.c index edf9d4b..94defba 100644 --- a/ja/screen.c +++ b/ja/screen.c @@ -68,18 +68,6 @@ void video_copy_backbuffer(int h) { } } -void fade_in_palette() { - if (!g_sys.input.quit) { - g_sys.fade_in_palette(); - } -} - -void fade_out_palette() { - if (!g_sys.input.quit) { - g_sys.fade_out_palette(); - } -} - void ja_decode_spr(const uint8_t *src, int w, int h, uint8_t *dst, int dst_pitch, uint8_t pal_mask) { const int bitplane_size = w * h; for (int y = 0; y < h; ++y) { diff --git a/ja/unpack.c b/ja/unpack.c index a60df58..67c51be 100644 --- a/ja/unpack.c +++ b/ja/unpack.c @@ -4,6 +4,8 @@ #include "unpack.h" #include "util.h" +static const bool _crc = false; + struct unpack_eat_t { FILE *fp; uint8_t len; @@ -64,6 +66,33 @@ static int unpack_eat(struct unpack_eat_t *u, uint8_t *output_buffer, int output print_error("Invalid output buffer size %d, need %d", output_buffer_size, output_size); return 0; } + if (_crc) { /* CCITT */ + uint16_t tbl[256]; + for (int i = 0; i < 256; ++i) { + uint16_t b = i; + for (int j = 0; j < 8; ++j) { + if (b & 1) { + b = (b >> 1) ^ 0xA001; + } else { + b >>= 1; + } + } + tbl[i] = b; + } + uint16_t ax = 0; + while (1) { + const uint8_t b = fgetc(u->fp); + if (feof(u->fp)) { + break; + } + ax = (ax >> 8) ^ tbl[(ax ^ b) & 0xFF]; + } + if (ax != crc) { + print_error("Invalid CRC 0x%x, expected 0x%x", ax, crc); + return 0; + } + fseek(u->fp, 17, SEEK_SET); + } u->dst = output_buffer; u->len = 16; diff --git a/p2/game.c b/p2/game.c index dc46b8d..c807067 100644 --- a/p2/game.c +++ b/p2/game.c @@ -100,9 +100,9 @@ static void do_titus_screen() { if (data) { g_sys.set_screen_palette(data, 0, 256, 6); update_screen_img(data + 768); - fade_in_palette(); + g_sys.fade_in_palette(); wait_input(70); - fade_out_palette(); + g_sys.fade_out_palette(); free(data); } } @@ -112,7 +112,7 @@ static void do_present_screen() { if (data) { g_sys.set_screen_palette(data, 0, 256, 6); update_screen_img(data + 768); - fade_in_palette(); + g_sys.fade_in_palette(); free(data); } } @@ -125,18 +125,18 @@ static void do_menu() { if (data) { g_sys.set_screen_palette(data, 0, 256, 6); update_screen_img(data + 768); - fade_in_palette(); + g_sys.fade_in_palette(); free(data); memset(g_vars.input.keystate, 0, sizeof(g_vars.input.keystate)); while (!g_sys.input.quit) { update_input(); if (g_vars.input.keystate[2] || g_vars.input.keystate[0x4F] || g_sys.input.space) { g_sys.input.space = 0; - fade_out_palette(); + g_sys.fade_out_palette(); break; } if (g_vars.input.keystate[3] || g_vars.input.keystate[0x50]) { - fade_out_palette(); + g_sys.fade_out_palette(); break; } g_sys.sleep(30); diff --git a/p2/game.h b/p2/game.h index 244294e..5c7279a 100644 --- a/p2/game.h +++ b/p2/game.h @@ -220,7 +220,14 @@ struct vars_t { uint8_t counter; uint8_t unk8; struct boss_level5_proj_t proj_tbl[5]; - } boss_level5; + } boss_level5; /* tree */ + struct { + int16_t unk1; + uint8_t unk2; + uint8_t unk3; + const uint8_t *seq; + const uint16_t *anim; + } boss_level9; /* minotaur statue */ struct { int16_t x_pos, y_pos; uint16_t spr_num; @@ -263,6 +270,7 @@ extern const uint8_t cos_tbl[256]; extern const uint8_t sin_tbl[256]; extern const uint16_t monster_spr_tbl[48]; extern const uint8_t monster_anim_tbl[1100]; +extern const uint8_t boss_minotaur_seq_data[742]; /* game.c */ extern void update_input(); @@ -291,8 +299,6 @@ extern void video_draw_number(int offset, int num); extern void video_draw_tile(const uint8_t *src, int x, int y); extern void video_convert_tiles(uint8_t *data, int len); extern void video_load_front_tiles(); -extern void fade_in_palette(); -extern void fade_out_palette(); extern void video_wait_vbl(); extern void video_transition_close(); extern void video_transition_open(); diff --git a/p2/level.c b/p2/level.c index 882b1b1..3eec898 100644 --- a/p2/level.c +++ b/p2/level.c @@ -228,6 +228,19 @@ static void load_level_data(int num) { load_level_data_init_secret_bonus_tiles(); load_level_data_init_password_items(); g_res.restart = g_res.level; + int count = 0; + for (int i = 0; i < MAX_LEVEL_ITEMS; ++i) { + struct level_item_t *item = &g_res.level.items_tbl[i]; + const uint16_t spr_num = item->spr_num; + if (spr_num >= 110 && spr_num <= 219) { + if (spr_num >= 128 || spr_num <= 117) { + ++count; + } + } + } + static const uint8_t type_tbl[] = { 0xFF, 0x0C, 0x0B, 0x0A, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x0E }; + if (g_vars.level_num < 10 && type_tbl[g_vars.level_num] != 0xFF) { + } } static void level_draw_tile(int tile_num, int x, int y) { @@ -935,6 +948,7 @@ static void level_reset() { } memset(g_vars.boss_level5.proj_tbl, 0xFF, sizeof(g_vars.boss_level5.proj_tbl)); g_vars.player_energy = 3; + memset(&g_vars.boss_level9, 0, sizeof(g_vars.boss_level9)); g_vars.decor_tile0_offset = _undefined; g_vars.tilemap_yscroll_diff = 0; @@ -1208,20 +1222,30 @@ static bool level_handle_bonuses_found(struct object_t *obj, struct level_bonus_ if (bonus->count & 0x40) { if (bonus->count == 64) { bonus->count = 0; - if (g_vars.level_num == 7 || g_vars.level_num == 6) { + if (g_vars.level_num == 3) { + g_vars.current_bonus.spr_num = 306; + } else if (g_vars.level_num == 7 || g_vars.level_num == 6) { g_vars.current_bonus.spr_num = 300; - level_add_object23_bonus(32, -48, 2); - g_vars.current_bonus.spr_num = 229; - count = 4; + } else { + g_vars.current_bonus.spr_num = 308; + } + level_add_object23_bonus(32, -48, 2); + if (g_vars.level_num == 8) { + g_vars.current_bonus.spr_num = 310; + count = 2; } else { g_vars.current_bonus.spr_num = 229; - count = 1; + count = 4; } } else { - if (g_vars.level_num == 7 || g_vars.level_num == 6) { + if (g_vars.level_num == 3) { + g_vars.current_bonus.spr_num = 306; + } else if (g_vars.level_num == 7 || g_vars.level_num == 6) { g_vars.current_bonus.spr_num = 300; - level_add_object23_bonus(48, -96, 4); + } else { + g_vars.current_bonus.spr_num = 308; } + level_add_object23_bonus(48, -96, 4); goto decrement_bonus; } } else { @@ -1310,6 +1334,25 @@ static void level_update_objects_axe() { } } +static void level_clear_boss_objects(int count) { + if (count > 8) { + count = 8; + } + if (count != 0 && 0) { + play_music(13); + for (int i = 0; i < count; ++i) { + struct object_t *obj = &g_vars.objects_tbl[108 + i]; + obj->spr_num = 0x135; + obj->x_pos = 8 + i * 5; + obj->y_pos = 170; + } + } + for (int i = count; i < 8; ++i) { + struct object_t *obj = &g_vars.objects_tbl[108 + i]; + obj->spr_num = 0xFFFF; + } +} + static void level_update_objects_boss_level5_helper() { --g_vars.bonus_energy_counter; if (g_vars.bonus_energy_counter < 0) { @@ -1329,7 +1372,7 @@ static void level_update_objects_boss_level5_helper() { level_add_object23_bonus(x_vel, y_vel, 1); } -static void level_update_boss() { +static void level_update_boss_gorilla() { const int x = (g_vars.boss.x_pos >> 4) + g_res.level.end_x_pos; if (x >= 0) { if (g_res.level.boss_xmin <= x && g_res.level.boss_xmax >= x) { @@ -1369,7 +1412,8 @@ static void level_update_boss() { print_warning("level_update_boss unimplemented end_pos %d,%d", g_res.level.end_x_pos, g_res.level.end_y_pos); } -static void level_update_objects_boss_level5() { +static void level_update_boss_tree() { + level_clear_boss_objects((2 - g_vars.boss_level5.state) << 1); struct object_t *obj_player = &g_vars.objects_tbl[1]; for (int i = 0; i < 5; ++i) { struct boss_level5_proj_t *prj = &g_vars.boss_level5.proj_tbl[i]; @@ -1413,9 +1457,9 @@ static void level_update_objects_boss_level5() { g_vars.objects_tbl[104].spr_num = 0xFFFF; if (g_vars.boss_level5.state < 2) { static const uint16_t pos2_data[] = { - 0x3D5, 0x7C1, 0x1A3, 0x3FA, 0x7B6, 0x1A4, 0x3E8, 0x7A8, 0x1A5, - 0x3FF, 0x788, 0x1A6, 0x3D9, 0x79B, 0x1A7, 0x3FF, 0x7A8, 0x1A8, - 0x405, 0x7A9, 0x1B0, 0, 0, 0xFFFF + 0x3D5, 0x7C1, 0x1AA, 0x3FA, 0x7B6, 0x1AB, 0x3E8, 0x7A8, 0x1AC, + 0x3FF, 0x788, 0x1AD, 0x3D9, 0x79B, 0x1AE, 0x3FF, 0x7A8, 0x1AF, + 0x405, 0x7A9, 0x1B7, 0, 0, 0xFFFF }; const uint16_t *p = &pos2_data[g_vars.boss_level5.state * 6]; g_vars.objects_tbl[105].x_pos = p[0]; @@ -1426,9 +1470,9 @@ static void level_update_objects_boss_level5() { g_vars.objects_tbl[104].spr_num = p[5]; } static const uint16_t pos1_data[] = { - 0x3A9, 0x7D4, 0x19D, 0x3D1, 0x7B9, 0x19E, 0x3A2, 0x7A6, 0x19F, - 0x3B4, 0x79F, 0x1A0, 0x396, 0x78A, 0x1A1, 0x3B6, 0x79C, 0x1A2, - 0x3E0, 0x795, 0x1AF, 0, 0, 0xFFFF + 0x3A9, 0x7D4, 0x1A4, 0x3D1, 0x7B9, 0x1A5, 0x3A2, 0x7A6, 0x1A6, + 0x3B4, 0x79F, 0x1A7, 0x396, 0x78A, 0x1A8, 0x3B6, 0x79C, 0x1A9, + 0x3E0, 0x795, 0x1B6, 0, 0, 0xFFFF }; const uint16_t *p = &pos1_data[g_vars.boss_level5.unk5 * 6]; g_vars.objects_tbl[107].x_pos = p[0]; @@ -1438,7 +1482,7 @@ static void level_update_objects_boss_level5() { g_vars.objects_tbl[106].y_pos = p[4]; g_vars.objects_tbl[106].spr_num = p[5]; static const uint16_t pos3_data[] = { - 0x3E3, 0x773, 0x1A9, 0x3E4, 0x771, 0x1AA, 0x3E4, 0x773, 0x1AB + 0x3E3, 0x773, 0x1B0, 0x3E4, 0x771, 0x1B1, 0x3E4, 0x773, 0x1B2 }; const uint16_t *q = &pos3_data[g_vars.boss_level5.unk4 * 3]; g_vars.objects_tbl[103].x_pos = q[0]; @@ -1560,6 +1604,132 @@ static void level_update_objects_boss_level5() { } } +static void level_update_boss_minotaur_update_tiles(int count) { +} + +static void level_update_boss_minotaur_helper() { + g_vars.current_bonus.x_pos = 185; + g_vars.current_bonus.y_pos = 30; + g_vars.current_bonus.spr_num = 0x2137; + int x_vel = 32; + int y_vel = -160; + for (int i = 0; i < 4; ++i) { + level_add_object23_bonus(x_vel, y_vel, 1); + x_vel = -x_vel; + if (x_vel >= 0) { + x_vel -= 16; + y_vel -= 16; + } + } +} + +static void level_update_boss_minotaur_add_spr_0x1CA() { + for (int i = 0; i < 32; ++i) { + struct object_t *obj = &g_vars.objects_tbl[23 + i]; + if (obj->spr_num == 0xFFFF) { + continue; + } + obj->spr_num = 0x1CA; + obj->x_pos = 200; + obj->y_pos = 88; + obj->data.t.counter = 132; + obj->data.t.ref = 0; + obj->x_velocity = -((random_get_number() & 15) << 3); + obj->data.t.unkE = 0; + break; + } +} + +static void level_update_boss_minotaur_add_spr_0x1CB() { + for (int i = 0; i < 32; ++i) { + struct object_t *obj = &g_vars.objects_tbl[23 + i]; + if (obj->spr_num == 0xFFFF) { + continue; + } + obj->spr_num = 0x1CB; + obj->x_pos = (random_get_number() & 0x7F) - 16; + obj->y_pos = 0; + obj->data.t.counter = 66; + obj->data.t.ref = 0; + obj->x_velocity = 0; + obj->data.t.unkE = 0; + break; + } +} + +static void level_update_boss_minotaur() { + static const uint16_t data[] = { + 0xA70F, 5, 0xA74E, 1, 0xA70F, 3, 0xA74E, 2, 0xA70F, 2, 0xA734, 1, 0xFFFF, 0xFFE8 + }; + if (!g_vars.boss_level9.seq) { + g_vars.boss_level9.anim = data; + g_vars.boss_level9.unk1 = 24; + g_vars.boss_level9.unk2 = 0; + g_vars.boss_level9.unk3 = 3; + } + level_clear_boss_objects(g_vars.boss_level9.unk1 >> 2); + if (g_vars.boss_level9.unk1 == 0) { + level_update_boss_minotaur_update_tiles(2); + return; + } + if (g_vars.boss_level9.unk2 == 0) { + const uint16_t *p = g_vars.boss_level9.anim; + if (p[0] == 0xFFFF) { + p += (int16_t)p[1] / 2; + assert(p == data); + } + assert(p[0] >= 0xA70F); + g_vars.boss_level9.seq = &boss_minotaur_seq_data[p[0] - 0xA70F]; + g_vars.boss_level9.unk2 = p[1]; + g_vars.boss_level9.anim = p + 2; + } + for (int i = 0; i < 4; ++i) { + struct object_t *obj = &g_vars.objects_tbl[2 + i]; + if (obj->spr_num == 0xFFFF) { + continue; + } + if ((obj->x_pos >= 235) || obj->y_pos >= 80) { + continue; + } + g_vars.boss_level9.seq = &boss_minotaur_seq_data[0x19]; + if (g_vars.boss_level9.unk1 > 0) { + --g_vars.boss_level9.unk1; + } + if (g_vars.boss_level9.unk1 == 0) { + level_update_boss_minotaur_helper(); + } + ++g_vars.boss_level9.unk3; + g_vars.boss_level9.unk3 &= 3; + if (g_vars.boss_level9.unk3 == 0) { + g_vars.boss_level9.seq = &boss_minotaur_seq_data[0x25]; + } + break; + } + const uint8_t *p = g_vars.boss_level9.seq; + while (1) { + if (*p == 0xFF) { + level_update_boss_minotaur_add_spr_0x1CA(); + ++p; + } else if (*p == 0xFE) { + level_update_boss_minotaur_add_spr_0x1CB(); + ++p; + } else if (*p == 0xFD) { + play_sound(2); + ++p; + } else if ((*p & 0x80) == 0) { + ++g_vars.boss_level9.seq; + level_update_boss_minotaur_update_tiles(*p); + break; + } else { + if (g_vars.boss_level9.unk2 > 0) { + --g_vars.boss_level9.unk2; + } + p += (int8_t)*p; + g_vars.boss_level9.seq = p; + } + } +} + static int level_get_tile_monster_offset(uint8_t tile_num, struct object_t *obj) { const uint8_t attr = g_res.level.tile_attributes1[tile_num]; if ((attr & 0x30) == 0) { @@ -1610,7 +1780,8 @@ static void level_update_monster_pos(struct object_t *obj, struct level_monster_ al = g_res.level.tile_attributes1[dl]; if (al == 0) { obj->y_pos += 16; - al = g_res.level.tile_attributes1[dh]; + dl = dh; + al = g_res.level.tile_attributes1[dl]; if (al == 0) { if (obj->data.m.y_velocity < 256) { obj->data.m.y_velocity += 16; @@ -1627,6 +1798,8 @@ static void level_update_monster_pos(struct object_t *obj, struct level_monster_ y_vel = 0; } obj->data.m.y_velocity = y_vel; + } else { + obj->data.m.y_velocity = 0; } } } @@ -1636,10 +1809,13 @@ extern bool monster_func2(int type, struct level_monster_t *m); /* init */ static void level_update_objects_monsters() { if (g_res.level.boss_flag != 0xFF) { - level_update_boss(); + level_update_boss_gorilla(); } if (g_vars.level_num == 5 && (g_res.level.scrolling_mask & ~1) == 0) { - level_update_objects_boss_level5(); + level_update_boss_tree(); + } + if (g_vars.level_num == 9) { + level_update_boss_minotaur(); } for (int i = 0; i < MONSTERS_COUNT; ++i) { struct object_t *obj = &g_vars.objects_tbl[11 + i]; diff --git a/p2/monsters.c b/p2/monsters.c index 48def2d..538636d 100644 --- a/p2/monsters.c +++ b/p2/monsters.c @@ -723,6 +723,7 @@ static bool monster_func2_type5_6_7_8(struct level_monster_t *m) { } static bool monster_func2_type9(struct level_monster_t *m) { + m->type9.x_step = 0; uint8_t flags = m->flags; if (!monster_func2_type1(m)) { return false; diff --git a/p2/resource.c b/p2/resource.c index 8ea4eea..4275fb1 100644 --- a/p2/resource.c +++ b/p2/resource.c @@ -126,6 +126,7 @@ void load_leveldat(const uint8_t *p, struct level_t *level) { m->len = len; m->type = p[1]; m->spr_num = spr_num; + m->flags = p[4]; m->energy = p[5]; m->respawn_ticks = p[6]; m->current_tick = p[7]; diff --git a/p2/screen.c b/p2/screen.c index 893fdaa..c0a83f6 100644 --- a/p2/screen.c +++ b/p2/screen.c @@ -179,18 +179,6 @@ void video_load_front_tiles() { } } -void fade_in_palette() { - if (!g_sys.input.quit) { - g_sys.fade_in_palette(); - } -} - -void fade_out_palette() { - if (!g_sys.input.quit) { - g_sys.fade_out_palette(); - } -} - void video_wait_vbl() { } diff --git a/p2/staticres.c b/p2/staticres.c index ba16379..e329c4d 100644 --- a/p2/staticres.c +++ b/p2/staticres.c @@ -449,3 +449,52 @@ const uint8_t monster_anim_tbl[] = { 0x00,0x7D,0x2E,0x00,0xFE,0xFF,0x3E,0x00,0x3E,0x00,0x3F,0x00,0x3F,0x00,0xF8,0xFF, 0x00,0x7D,0x3E,0x00,0xFE,0xFF,0x57,0x00,0x57,0x00,0x58,0x00 }; +const uint8_t boss_minotaur_seq_data[] = { + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0xE8,0x03,0x03,0x03,0xFD,0x03,0x03,0x03, + 0x03,0x03,0x03,0x03,0xF1,0x00,0x00,0xFF,0x03,0x03,0xFE,0x03,0x00,0x00,0x00,0x03, + 0x03,0x03,0x03,0x00,0xFE,0x00,0x03,0x03,0x03,0x00,0x00,0x03,0x03,0x03,0xE7,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00, + 0xFF,0x00,0x00,0x00,0x00,0xEA,0xA2,0x01,0x9A,0x01,0x95,0x01,0x9F,0x01,0xA0,0x01, + 0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA2,0x01,0x9A,0x01,0x96,0x01, + 0x9D,0x01,0xA0,0x01,0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA2,0x01, + 0x9A,0x01,0x96,0x01,0x9C,0x01,0xA0,0x01,0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5, + 0x09,0xA6,0xA1,0x01,0x99,0x01,0x96,0x01,0x9D,0x01,0x9D,0x81,0x0F,0xA6,0x03,0xA6, + 0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA2,0x01,0x9B,0x01,0x96,0x01,0x9D,0x01,0x9D,0x81, + 0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA2,0x01,0x99,0x01,0x98,0x81, + 0x9E,0x01,0x9E,0x81,0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA2,0x01, + 0x9A,0x01,0x98,0x01,0x9C,0x01,0x9D,0x81,0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5, + 0x09,0xA6,0xA2,0x01,0x9A,0x01,0x95,0x01,0x9E,0x01,0x9E,0x81,0x0F,0xA6,0x03,0xA6, + 0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA2,0x01,0x99,0x01,0x95,0x01,0x9E,0x01,0x9D,0x81, + 0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA3,0x01,0x99,0x01,0x95,0x01, + 0x9E,0x01,0x9D,0x81,0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA2,0x01, + 0x99,0x01,0x95,0x01,0x9E,0x01,0xA0,0x01,0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5, + 0x09,0xA6,0xA3,0x01,0x99,0x01,0x95,0x01,0x9D,0x01,0xA0,0x01,0x0F,0xA6,0x03,0xA6, + 0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA3,0x01,0x9B,0x01,0x95,0x01,0x9E,0x01,0x9D,0x81, + 0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA3,0x01,0x9B,0x01,0x95,0x01, + 0x9D,0x01,0x9D,0x81,0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA3,0x01, + 0x9B,0x01,0x95,0x01,0x9D,0x01,0xA0,0x01,0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5, + 0x09,0xA6,0xA2,0x01,0x9A,0x01,0x98,0x01,0x9C,0x01,0x9D,0x81,0x0F,0xA6,0x03,0xA6, + 0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA2,0x01,0x9A,0x01,0x97,0x01,0x9E,0x01,0x9D,0x81, + 0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA2,0x01,0x9A,0x01,0x97,0x01, + 0x9D,0x01,0x9E,0x81,0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0xF7,0xA5,0x09,0xA6,0xA3,0x01, + 0x9A,0x01,0x95,0x01,0xA0,0x81,0x9D,0x81,0x0F,0xA6,0x03,0xA6,0xFD,0xA5,0x09,0xA6, + 0xF7,0xA5,0xA2,0x01,0x99,0x01,0xF8,0xE9,0xA2,0x01,0x9A,0x01,0xFB,0xEB,0xA2,0x01, + 0x9B,0x01,0xF6,0xE8,0xA1,0x01,0x99,0x01,0xF6,0xDB,0xA1,0x01,0x9A,0x01,0x01,0xDD, + 0xA1,0x01,0x9B,0x01,0xF3,0xDA,0xA3,0x01,0x99,0x01,0xED,0xF0,0xA3,0x01,0x9A,0x01, + 0xF0,0xF2,0xA3,0x01,0x9B,0x01,0xEB,0xF0,0x99,0x01,0x95,0x01,0xFF,0xE8,0x9A,0x01, + 0x95,0x01,0xFB,0xEA,0x9B,0x01,0x95,0x01,0xF8,0xF7,0x99,0x01,0x96,0x01,0xFF,0xE8, + 0x9A,0x01,0x96,0x01,0xFB,0xEA,0x9B,0x01,0x96,0x01,0xF8,0xF7,0x99,0x01,0x97,0x01, + 0xFF,0xE8,0x9A,0x01,0x97,0x01,0xFB,0xEA,0x9B,0x01,0x97,0x01,0xF8,0xF7,0x99,0x01, + 0x98,0x01,0xFF,0xE8,0x9A,0x01,0x98,0x01,0xFB,0xEA,0x9B,0x01,0x98,0x01,0xF8,0xF7, + 0x99,0x01,0x98,0x81,0xFF,0xE8,0x9A,0x01,0x98,0x81,0xFB,0xEA,0x9B,0x01,0x98,0x81, + 0xF8,0xF7,0x99,0x01,0x9C,0x01,0xE2,0xEC,0x99,0x01,0x9D,0x01,0xDD,0xF1,0x99,0x01, + 0x9E,0x01,0xD6,0xE9,0x99,0x01,0x9F,0x01,0xE8,0x0C,0x9A,0x01,0x9C,0x01,0xE2,0xEC, + 0x9A,0x01,0x9D,0x01,0xE0,0xF1,0x9A,0x01,0x9E,0x01,0xD4,0xEA,0x9A,0x01,0x9F,0x01, + 0xEA,0x0F,0x9B,0x01,0x9C,0x01,0xDE,0xF8,0x9B,0x01,0x9D,0x01,0xDC,0x02,0x9B,0x01, + 0x9E,0x01,0xCE,0xFB,0x9B,0x01,0x9F,0x01,0xE6,0x1D,0x99,0x01,0x9D,0x81,0x21,0xEB, + 0x99,0x01,0x9E,0x81,0x2C,0xE4,0x99,0x01,0xA0,0x01,0x12,0x10,0x9A,0x01,0x9D,0x81, + 0x18,0xEE,0x9A,0x01,0x9E,0x81,0x29,0xEA,0x9A,0x01,0xA0,0x01,0x09,0x13,0x9B,0x01, + 0x9D,0x81,0x1A,0xF9,0x9B,0x01,0x9E,0x81,0x29,0xF3,0x9B,0x01,0xA0,0x01,0x0C,0x1E, + 0x9A,0x01,0xA0,0x81,0xEC,0x16 +}; diff --git a/sys_sdl2.c b/sys_sdl2.c index 68c9d1f..98dd83b 100644 --- a/sys_sdl2.c +++ b/sys_sdl2.c @@ -215,11 +215,15 @@ static void fade_palette_helper(int in) { } static void sdl2_fade_in_palette() { - fade_palette_helper(1); + if (!g_sys.input.quit) { + fade_palette_helper(1); + } } static void sdl2_fade_out_palette() { - fade_palette_helper(0); + if (!g_sys.input.quit) { + fade_palette_helper(0); + } } static void sdl2_transition_screen(enum sys_transition_e type, bool open) {