diff --git a/Makefile b/Makefile index 4b20b68..8bee84a 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,6 @@ pre2: main.o sys_sdl2.o util.o $(P2_SRCS:.c=.o) $(CC) $(LDFLAGS) -o $@ $^ $(SDL_LIBS) -lmodplug clean: - rm -f $(OBJS) $(DEPS) *.o + rm -f $(OBJS) $(DEPS) *.o *.d -include $(DEPS) diff --git a/p2/game.c b/p2/game.c index f85cac5..6ed1c02 100644 --- a/p2/game.c +++ b/p2/game.c @@ -4,8 +4,6 @@ #include "resource.h" #include "sys.h" -static const bool _logos = false; - struct vars_t g_vars; void update_input() { @@ -40,6 +38,7 @@ static void do_programmed_in_1992_screen() { if (t->tm_year + 1900 < 1996) { /* || t->tm_year + 1900 >= 2067 */ return; } + memset(g_res.vga, 0, GAME_SCREEN_W * GAME_SCREEN_H); g_sys.set_screen_palette(credits_palette_data, 0, 16, 6); int offset = 0x960; video_draw_string(offset, 5, "YEAAA > > >"); @@ -208,8 +207,8 @@ static void game_run(const char *data_path) { sound_init(); video_convert_tiles(g_res.uniondat, g_res.unionlen); g_vars.level_num = g_options.start_level; - if (_logos) { - do_programmed_in_1992_screen(); + do_programmed_in_1992_screen(); + if (!g_sys.input.space) { do_titus_screen(); play_music(3); do_present_screen(); diff --git a/p2/game.h b/p2/game.h index 424c1af..af9a2b8 100644 --- a/p2/game.h +++ b/p2/game.h @@ -43,8 +43,8 @@ struct monster_t { int16_t y_velocity; const uint8_t *anim; uint8_t state; - uint8_t energy; - uint8_t unk10; /* score */ + int8_t energy; + uint8_t hit_jump_counter; }; struct thing_t { @@ -178,7 +178,6 @@ struct vars_t { uint16_t tilemap_size; /* tilemap size h*256 */ uint16_t tilemap_start_x_pos, tilemap_start_y_pos; /* tilemap restart position */ uint8_t tile_attr2_flags; /* current tilemap tile types (eg. front) */ - uint8_t animated_tiles_flag; /* current tilemap has animated tiles */ uint8_t level_animated_tiles_counter; /* animated tiles update counter */ uint8_t *level_animated_tiles_current_tbl; /* pointer to current tile_tbl */ uint8_t tile_tbl1[256]; /* animated tile state 1 */ @@ -192,6 +191,7 @@ struct vars_t { struct object_t *current_object; uint8_t type10_dist; uint8_t hit_mask; + int16_t collide_y_dist; } monster; struct { int16_t x_pos, y_pos; diff --git a/p2/level.c b/p2/level.c index 450004f..2994ce0 100644 --- a/p2/level.c +++ b/p2/level.c @@ -70,7 +70,6 @@ static void load_level_data_init_animated_tiles() { g_vars.tile_tbl3[i] = i; g_vars.animated_tile_flag_tbl[i] = 0; } else { - g_vars.animated_tiles_flag = 1; int j = i; g_vars.tile_tbl1[i] = j; g_vars.tile_tbl2[i + 2] = j; @@ -240,9 +239,6 @@ static void level_draw_tile(int tile_num, int x, int y) { } static void level_update_tilemap() { - if (!_redraw_tilemap && g_vars.animated_tiles_flag == 0) { - return; - } const uint8_t mask = (g_vars.snow.value >= 20) ? 1 : 3; ++g_vars.level_animated_tiles_counter; if ((g_vars.level_animated_tiles_counter & mask) == 0) { @@ -269,14 +265,12 @@ static void level_update_tilemap() { } } g_vars.tile_attr2_flags = 0; - g_vars.animated_tiles_flag = 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) { 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) { - g_vars.animated_tiles_flag = 1; const uint8_t num = g_vars.level_animated_tiles_current_tbl[tile_num]; level_draw_tile(num, x, y); } @@ -561,6 +555,7 @@ 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(); } @@ -1053,6 +1048,8 @@ static bool level_objects_collide(const struct object_t *si, const struct object if (g_vars.player_using_club_flag == 0) { d -= a; if (g_vars.objects_tbl[1].data.p.y_velocity >= 128 || (d <= (b >> 1) && si != &g_vars.objects_tbl[1])) { + ++g_vars.player_jump_monster_flag; + g_vars.monster.collide_y_dist = d; } } d = si->x_pos - spr_offs_tbl[(si->spr_num & 0x1FFF) * 2]; @@ -1077,9 +1074,9 @@ static void level_monster_update_anim(struct object_t *obj) { } static void level_monster_die(struct object_t *obj, struct level_monster_t *m) { - const int num = m->unk8 + 74; + const int num = m->score + 74; static const uint8_t data[] = { 1, 2, 3, 4, 6, 8 }; - int count = data[obj->data.m.unk10 & 7]; + int count = data[(obj->data.m.hit_jump_counter >> 3) & 7]; const int x_pos = obj->x_pos; const int y_pos = obj->y_pos; do { @@ -1132,10 +1129,10 @@ static bool level_collide_axe_monsters(struct object_t *axe_obj) { continue; } obj->data.m.unk5 |= 0x40; - if (obj->data.m.energy < g_vars.player_club_power) { + obj->data.m.energy -= g_vars.player_club_power; + if (obj->data.m.energy < 0) { level_monster_die(obj, m); } else { - obj->data.m.energy -= g_vars.player_club_power; obj->x_pos -= obj->data.m.x_velocity >> 2; } obj->spr_num = 0xFFFF; @@ -1333,7 +1330,7 @@ static void level_update_monster_pos(struct object_t *obj, struct level_monster_ x_vel = -x_vel; } uint8_t al = level_get_tile(pos + x_vel - 0x100); - al = g_res.level.tile_attributes1[al]; + al = g_res.level.tile_attributes0[al]; if ((m->flags & 0x40) != 0 && (m->flags & 0x80) != 0) { if (al != 0) { obj->x_pos -= obj->data.m.x_velocity >> 4; @@ -1368,14 +1365,15 @@ static void level_update_monster_pos(struct object_t *obj, struct level_monster_ return; } } + const int dy = level_get_tile_monster_offset(dl, obj); obj->y_pos &= ~15; - obj->y_pos += level_get_tile_monster_offset(dl, obj); + obj->y_pos += dy; if ((m->flags & 0x20) == 0) { - int dy = (-obj->data.m.y_velocity) >> 1; - if (abs(dy) <= 32) { - dy = 0; + int y_vel = (-obj->data.m.y_velocity) >> 1; + if (abs(y_vel) <= 32) { + y_vel = 0; } - obj->data.m.y_velocity = dy; + obj->data.m.y_velocity = y_vel; } } } @@ -1604,11 +1602,12 @@ static bool level_update_objects_decors_helper(struct object_t *obj) { } const int prev_spr_num = g_vars.objects_tbl[1].spr_num; g_vars.objects_tbl[1].spr_num = 7; - if (!level_objects_collide(&g_vars.objects_tbl[1], obj)) { - return false; - } + const bool ret = level_objects_collide(&g_vars.objects_tbl[1], obj); g_vars.objects_tbl[1].y_pos = prev_y_pos; g_vars.objects_tbl[1].spr_num = prev_spr_num; + if (!ret) { + return false; + } g_vars.level_force_x_scroll_flag = 1; g_vars.objects_tbl[1].x_friction = 0; g_vars.objects_tbl[1].x_pos += g_vars.level_current_object_decor_x_pos; @@ -2418,24 +2417,26 @@ static void level_update_player_collision() { } return; } - if (g_vars.player_gravity_flag == 0) { - int num = obj->data.m.unk10 >> 2; + if (!g_vars.player_gravity_flag) { + /* jumping on a monster */ + int num = obj->data.m.hit_jump_counter >> 2; if (num != 11) { - obj->data.m.unk10 += 4; + obj->data.m.hit_jump_counter += 4; ++num; if ((num & 1) == 0) { static const uint16_t data[] = { 0xFF46, 0xE0, 0xE1, 0x12D, 0x12E, 0x12F }; - - level_add_object75_score(obj_player, data[num >> 1]); + level_add_object75_score(obj_player, (int16_t)data[num >> 1]); } } g_vars.objects_tbl[1].data.p.y_velocity = (g_vars.input.key_up != 0) ? -224 : -64; g_vars.player_jumping_counter = 0; + g_vars.objects_tbl[1].y_pos -= g_vars.monster.collide_y_dist; } else if (g_vars.objects_tbl[1].data.p.y_velocity <= 32) { g_vars.objects_tbl[1].data.p.y_velocity = -96; g_vars.player_jumping_counter = 0; + g_vars.objects_tbl[1].y_pos -= g_vars.monster.collide_y_dist; } else { - int num = (obj->data.m.unk10) & 3; + int num = (obj->data.m.hit_jump_counter) & 3; level_add_object75_score(obj_player, 82 + (num << 1)); obj->spr_num |= 0x4000; if (num == 2) { @@ -2449,9 +2450,10 @@ static void level_update_player_collision() { } obj->data.m.x_velocity = delta * 3; } else { - ++obj->data.m.unk10; + ++obj->data.m.hit_jump_counter; g_vars.objects_tbl[1].data.p.y_velocity = -96; g_vars.player_jumping_counter = 0; + g_vars.objects_tbl[1].y_pos -= g_vars.monster.collide_y_dist; } } return; @@ -3136,31 +3138,33 @@ static void level_completed_bonuses_animation() { g_vars.objects_tbl[1].data.p.anim = object_anim_tbl[1]; while (1) { level_update_object_anim(g_vars.objects_tbl[1].data.p.anim); - int _bx, _ax, flag = 0; + + bool flag = false; int x_pos = 60; - _bx = 2; - _ax = g_vars.objects_tbl[1].x_pos - x_pos; - if (_ax < 0) { - _bx = -_bx; + int x_offs = 2; + const int dx = g_vars.objects_tbl[1].x_pos - x_pos; + if (dx < 0) { + x_offs = -x_offs; } - if (_ax >= 2) { - x_pos = g_vars.objects_tbl[1].x_pos - _bx; - ++flag; + if (dx >= 2) { + x_pos = g_vars.objects_tbl[1].x_pos - x_offs; + flag = true; } g_vars.objects_tbl[1].x_pos = x_pos; int y_pos = 175; - _bx = 2; - _ax = g_vars.objects_tbl[1].y_pos - y_pos; - if (_ax < 0) { - _bx = -_bx; + int y_offs = 2; + const int dy = g_vars.objects_tbl[1].y_pos - y_pos; + if (dy < 0) { + y_offs = -y_offs; } - if (_ax >= 2) { - y_pos = g_vars.objects_tbl[1].y_pos - _bx; - ++flag; + if (dy >= 2) { + y_pos = g_vars.objects_tbl[1].y_pos - y_offs; + flag = true; } g_vars.objects_tbl[1].y_pos = y_pos; + video_clear(); level_completed_bonuses_animation_draw_score(); level_draw_objects(); diff --git a/p2/monsters.c b/p2/monsters.c index 9383a96..6c3228e 100644 --- a/p2/monsters.c +++ b/p2/monsters.c @@ -23,9 +23,9 @@ static void monster_func1_helper(struct object_t *obj, int16_t x_pos, int16_t y_ return; } const int dx = abs(x_pos - g_vars.objects_tbl[1].x_pos); - if (dx <= 320) { + if (dx <= TILEMAP_SCREEN_W) { const int dy = abs(y_pos - g_vars.objects_tbl[1].y_pos); - if (dy <= 300) { + if (dy <= TILEMAP_SCREEN_H + (300 - 176)) { return; } } @@ -165,15 +165,27 @@ static void monster_func1_type4(struct object_t *obj) { } } +static void monster_func1_type8_helper(struct object_t *obj, struct level_monster_t *m) { + obj->data.m.y_velocity = -(m->type8.y_step << 4); + int x_vel = m->type8.x_step << 4; + if (g_vars.objects_tbl[1].x_pos <= obj->x_pos) { + x_vel = -x_vel; + } + obj->data.m.x_velocity = x_vel; + obj->data.m.state = 10; + m->flags |= 0x2C; + monster_change_next_anim(obj); +} + static void monster_func1_type8(struct object_t *obj) { monster_func1_helper(obj, obj->x_pos, obj->y_pos); struct level_monster_t *m = obj->data.m.ref; - if (obj->data.m.x_velocity != 0) { + if (obj->data.m.x_velocity == 0) { const int dx = (obj->x_pos <= g_vars.objects_tbl[1].x_pos) ? 1 : -1; obj->data.m.x_velocity = dx; } const uint8_t state = obj->data.m.state; - if ((state == 0 && !monster_next_tick(m)) || (state == 12 && !monster_next_tick(m))) { + if (state == 0 && !monster_next_tick(m)) { const int dx = abs(g_vars.objects_tbl[1].x_pos - obj->x_pos); if (m->type8.x_range < (dx >> 4)) { return; @@ -182,15 +194,7 @@ static void monster_func1_type8(struct object_t *obj) { if (m->type8.y_range < (dy >> 4)) { return; } - obj->data.m.y_velocity = -(m->type8.unkE << 4); - int x_vel = m->type8.unkF << 4; - if (g_vars.objects_tbl[1].x_pos <= obj->x_pos) { - x_vel = -x_vel; - } - obj->data.m.x_velocity = x_vel; - obj->data.m.state = 10; - m->flags = (m->flags & ~0x2C) | 0x2C; - monster_change_next_anim(obj); + monster_func1_type8_helper(obj, m); } else if (state == 10) { if (obj->data.m.y_velocity < 0) { return; @@ -206,6 +210,8 @@ static void monster_func1_type8(struct object_t *obj) { monster_change_prev_anim(obj); obj->data.m.x_velocity = 0; m->current_tick = 0; + } else if (state == 12 && !monster_next_tick(m)) { + monster_func1_type8_helper(obj, m); } else if (state == 0xFF) { monster_update_y_velocity(obj, m); } @@ -343,7 +349,7 @@ static struct object_t *find_object_monster() { static bool monster_init_object(struct level_monster_t *m) { struct object_t *obj = find_object_monster(); if (obj) { - obj->data.m.unk10 = 0; + obj->data.m.hit_jump_counter = 0; g_vars.monster.current_object = obj; obj->x_pos = m->x_pos; obj->y_pos = m->y_pos; @@ -384,7 +390,7 @@ static bool monster_func2_type2(struct level_monster_t *m) { } struct object_t *obj = find_object_monster(); if (obj) { - obj->data.m.unk10 = 0; + obj->data.m.hit_jump_counter = 0; g_vars.monster.current_object = obj; obj->x_pos = m->x_pos; obj->y_pos = m->y_pos; @@ -461,7 +467,7 @@ static bool monster_func2_type10(struct level_monster_t *m) { if (!obj) { return false; } - obj->data.m.unk10 = 0; + obj->data.m.hit_jump_counter = 0; g_vars.monster.current_object = obj; static const int16_t dist_tbl[] = { 120, 100, -90, 110, -120, 40, 80, 60 }; obj->x_pos = g_vars.objects_tbl[1].x_pos + dist_tbl[g_vars.monster.type10_dist & 7]; diff --git a/p2/resource.c b/p2/resource.c index 532168c..4e84651 100644 --- a/p2/resource.c +++ b/p2/resource.c @@ -126,10 +126,13 @@ void load_leveldat(const uint8_t *p, struct level_t *level) { m->energy = p[5]; m->total_ticks = p[6]; m->current_tick = p[7]; - m->unk8 = p[8]; + m->score = p[8]; m->x_pos = READ_LE_UINT16(p + 0x9); m->y_pos = READ_LE_UINT16(p + 0xB); - switch (type) { + switch (type) { /* movement */ + case 1: + assert(len == 13); + break; case 2: /* vertical (eg. spider) */ assert(len == 15); m->type2.y_range = p[0xD]; @@ -145,8 +148,8 @@ void load_leveldat(const uint8_t *p, struct level_t *level) { case 8: /* jumps (eg. leopard) */ assert(len == 17); m->type8.x_range = p[0xD]; - m->type8.unkE = p[0xE]; - m->type8.unkF = p[0xF]; + m->type8.y_step = p[0xE]; + m->type8.x_step = p[0xF]; m->type8.y_range = p[0x10]; break; case 9: /* horizontal */ @@ -161,6 +164,7 @@ void load_leveldat(const uint8_t *p, struct level_t *level) { m->type10.unkD = p[0xD]; break; default: + print_warning("Unhandled monster type %d len %d", type, len); break; } p += len; diff --git a/p2/resource.h b/p2/resource.h index f5ae5f2..2be88ac 100644 --- a/p2/resource.h +++ b/p2/resource.h @@ -66,7 +66,7 @@ struct level_monster_t { uint8_t energy; uint8_t total_ticks; uint8_t current_tick; - uint8_t unk8; + uint8_t score; uint16_t x_pos; uint16_t y_pos; union { @@ -82,8 +82,8 @@ struct level_monster_t { } type4; struct { uint8_t x_range; - int8_t unkE; - int8_t unkF; + int8_t y_step; + int8_t x_step; uint8_t y_range; } type8; struct {