diff --git a/README.md b/README.md index 51eaae7..7e363f2 100644 --- a/README.md +++ b/README.md @@ -61,3 +61,7 @@ Usage: blues [OPTIONS]... --screensize=WxH Graphics screen size (default 320x200) --cga Enable CGA colors ``` + +## Downloads + +[blues-sdl2-win32.zip](https://www.dropbox.com/s/vv8mh0vrk8l6xro/blues-gh-sdl2-win32.zip?dl=0) - Win32 executable diff --git a/ja/game.h b/ja/game.h index 34c3965..02965b9 100644 --- a/ja/game.h +++ b/ja/game.h @@ -38,7 +38,7 @@ struct object_t { uint8_t b[2]; int16_t w; const uint8_t *p; - } data[11]; // 0x6..0x1C + } data[11]; }; enum { @@ -49,22 +49,22 @@ enum { PLAYER_FLAGS_JAKE = 0x80 }; -#define player_obj_num(obj) (obj)->data[0].w // 0x6 -#define player_prev_spr_num(obj) (obj)->data[1].w // 0x8 -#define player_anim_data(obj) (obj)->data[2].p // 0xA -#define player_idle_counter(obj) (obj)->data[3].b[0] // 0xC -#define player_power(obj) (obj)->data[3].b[1] // 0xD -#define player_x_delta(obj) (obj)->data[4].w // 0xE -#define player_y_delta(obj) (obj)->data[5].w // 0x10 -#define player_flags(obj) (obj)->data[6].b[0] // 0x12 -#define player_jump_counter(obj) (obj)->data[6].b[1] // 0x13 -#define player_bounce_counter(obj) (obj)->data[7].b[0] // 0x14 -#define player_tilemap_offset(obj) (obj)->data[8].w // 0x16 -#define player_hit_counter(obj) (obj)->data[9].b[0] // 0x18 -#define player_throw_counter(obj) (obj)->data[9].b[1] // 0x19 -#define player_flags2(obj) (obj)->data[10].b[0] // 0x1A, 8:dead 1:blocked +#define player_obj_num(obj) (obj)->data[0].w +#define player_prev_spr_num(obj) (obj)->data[1].w +#define player_anim_data(obj) (obj)->data[2].p +#define player_idle_counter(obj) (obj)->data[3].b[0] +#define player_power(obj) (obj)->data[3].b[1] +#define player_x_delta(obj) (obj)->data[4].w +#define player_y_delta(obj) (obj)->data[5].w +#define player_flags(obj) (obj)->data[6].b[0] +#define player_jump_counter(obj) (obj)->data[6].b[1] +#define player_bounce_counter(obj) (obj)->data[7].b[0] +#define player_tilemap_offset(obj) (obj)->data[8].w +#define player_hit_counter(obj) (obj)->data[9].b[0] +#define player_throw_counter(obj) (obj)->data[9].b[1] +#define player_flags2(obj) (obj)->data[10].b[0] -#define object_blinking_counter(obj) (obj)->data[6].b[1] // 0x13, shield, jump +#define object_blinking_counter(obj) (obj)->data[6].b[1] /* star */ #define object2_spr_count(obj) (obj)->data[0].b[0] @@ -99,13 +99,13 @@ enum { struct player_t { struct object_t obj; - int16_t unk_counter; // 0x1D always zero + int16_t unk_counter; int16_t change_hdir_counter; uint8_t lifes_count; int16_t vinyls_count; int8_t energy; - uint8_t dir_mask; // 0x25 - uint8_t ticks_counter; // 0x26 + uint8_t dir_mask; + uint8_t ticks_counter; }; #define TRIGGERS_COUNT 36 diff --git a/p2/level.c b/p2/level.c index 280e695..1823ba0 100644 --- a/p2/level.c +++ b/p2/level.c @@ -126,10 +126,10 @@ static void load_level_data_fix_items_spr_num() { g_res.level.items_tbl[i].spr_num = num - offset + 53; } } - for (int i = 0; i < MAX_LEVEL_TRIGGERS; ++i) { - const uint16_t num = g_res.level.triggers_tbl[i].spr_num; + for (int i = 0; i < MAX_LEVEL_PLATFORMS; ++i) { + const uint16_t num = g_res.level.platforms_tbl[i].spr_num; if (num != 0xFFFF) { - g_res.level.triggers_tbl[i].spr_num = num - offset + 53; + g_res.level.platforms_tbl[i].spr_num = num - offset + 53; } } } @@ -1364,8 +1364,7 @@ static void level_update_objects_boss_energy(int count) { } } for (int i = count; i < 8; ++i) { - struct object_t *obj = &g_vars.objects_tbl[108 + i]; - obj->spr_num = 0xFFFF; + g_vars.objects_tbl[108 + i].spr_num = 0xFFFF; } } @@ -1399,6 +1398,9 @@ static void level_update_boss_gorilla_collide_proj(struct object_t *obj_player, if (g_vars.boss.unk_counter < 0) { g_vars.boss.unk_counter = 0; } + if (g_options.cheats & CHEATS_NO_HIT) { + return; + } level_update_objects_boss_hit_player(); obj_player->hit_counter = 44; g_vars.player_anim_0x40_flag = 0; @@ -2493,120 +2495,116 @@ static void level_update_objects_decors() { g_vars.level_force_x_scroll_flag = 0; int count = 7; struct object_t *obj = &g_vars.objects_tbl[91]; - for (int i = 0; i < MAX_LEVEL_TRIGGERS; ++i) { - struct level_trigger_t *trigger = &g_res.level.triggers_tbl[i]; - if (trigger->spr_num == 0xFFFF) { + for (int i = 0; i < MAX_LEVEL_PLATFORMS; ++i) { + struct level_platform_t *platform = &g_res.level.platforms_tbl[i]; + if (platform->spr_num == 0xFFFF) { continue; } - if ((trigger->flags & 15) == 8) { + if ((platform->flags & 15) == 8) { g_vars.level_current_object_decor_x_pos = 0; - trigger->y_pos -= trigger->type8.y_delta; - if (trigger->type8.state == 0) { - int a = trigger->type8.y_delta - 8; + platform->y_pos -= platform->type8.y_delta; + if (platform->type8.state == 0) { + int a = platform->type8.y_delta - 8; if (a < 0) { a = 0; - trigger->type8.y_velocity = 0; + platform->type8.y_velocity = 0; } - trigger->type8.y_delta = a; - if (trigger->flags & 0x40) { - if (trigger->type8.y_velocity != 0 && --trigger->type8.counter == 0) { - trigger->type8.state = 1; - trigger->type8.y_velocity = 0; + platform->type8.y_delta = a; + if (platform->flags & 0x40) { + if (platform->type8.y_velocity != 0 && --platform->type8.counter == 0) { + platform->type8.state = 1; + platform->type8.y_velocity = 0; } } - } else if (trigger->type8.state == 1) { - int y = trigger->type8.y_velocity; + } else if (platform->type8.state == 1) { + int y = platform->type8.y_velocity; if (y < 192) { - trigger->type8.y_velocity += 8; + platform->type8.y_velocity += 8; } y >>= 4; g_vars.level_current_object_decor_y_pos = y; - trigger->type8.y_delta += y; - const int tile_x = trigger->x_pos >> 4; - const int tile_y = (trigger->y_pos + trigger->type8.y_delta) >> 4; + platform->type8.y_delta += y; + const int tile_x = platform->x_pos >> 4; + const int tile_y = (platform->y_pos + platform->type8.y_delta) >> 4; const int y2 = g_vars.tilemap.h - 1 - tile_y; if (y2 < 0) { if ((-y2) >= 3) { - trigger->type8.state = 2; - trigger->type8.counter = 22; + platform->type8.state = 2; + platform->type8.counter = 22; } } else { const uint8_t tile_num = level_get_tile((tile_y << 8) | tile_x); const uint8_t tile_attr1 = g_res.level.tile_attributes1[tile_num]; if (tile_attr1 != 0 && tile_attr1 != 6) { - trigger->type8.state = 2; - trigger->type8.counter = 22; + platform->type8.state = 2; + platform->type8.counter = 22; } } - } else if (trigger->type8.state == 2) { - if ((trigger->flags & 0x40) == 0 && --trigger->type8.counter == 0) { - trigger->type8.state = 0; - trigger->type8.counter = trigger->type8.unk9; + } else if (platform->type8.state == 2) { + if ((platform->flags & 0x40) == 0 && --platform->type8.counter == 0) { + platform->type8.state = 0; + platform->type8.counter = platform->type8.unk9; } } - trigger->y_pos += trigger->type8.y_delta; + platform->y_pos += platform->type8.y_delta; } else { g_vars.level_current_object_decor_x_pos = 0; g_vars.level_current_object_decor_y_pos = 0; - if (trigger->unkE != 0 || trigger->other.unk7 < 0 || (trigger->flags & 0xC0) != 0) { - if (trigger->other.unk7 > trigger->unkE) { - ++trigger->unkE; - } else if (trigger->other.unk7 < trigger->unkE) { - --trigger->unkE; + if (platform->other.velocity != 0 || platform->other.max_velocity < 0 || (platform->flags & 0xC0) != 0) { + if (platform->other.max_velocity > platform->other.velocity) { + ++platform->other.velocity; + } else if (platform->other.max_velocity < platform->other.velocity) { + --platform->other.velocity; } - int al = trigger->unkE; - int ah = trigger->unkE; - int dl = trigger->flags & 7; - if (dl == 0) { + int al = platform->other.velocity; + int ah = platform->other.velocity; + const int type = platform->flags & 7; + if (type == 0) { al = 0; ah = -ah; - } else if (dl == 1) { + } else if (type == 1) { ah = -ah; - } else if (dl == 2) { + } else if (type == 2) { ah = 0; + } else if (type == 4) { + al = 0; + } else if (type == 5) { + al = -al; + } else if (type == 6) { + al = -al; + ah = 0; + } else if (type == 7) { + al = -al; + ah = -ah; } - if (dl != 3) { - if (dl == 4) { - al = 0; - } else if (dl == 5) { - al = -al; - } else if (dl == 6) { - al = -al; - ah = 0; - } else if (dl == 7) { - al = -al; - ah = -ah; - } - } - dl = ah; - g_vars.level_current_object_decor_x_pos = (int8_t)al; - trigger->x_pos += al; - g_vars.level_current_object_decor_y_pos = (int8_t)dl; - trigger->y_pos += dl; - if (trigger->other.unk7 == trigger->unkE) { - int16_t ax = trigger->other.unkC + 1; - if (trigger->other.unkA == ax) { - trigger->other.unk7 = -trigger->other.unk7; + g_vars.level_current_object_decor_x_pos = al; + platform->x_pos += al; + g_vars.level_current_object_decor_y_pos = ah; + platform->y_pos += ah; + if (platform->other.max_velocity == platform->other.velocity) { + uint16_t ax = platform->other.counter + 1; + if (platform->other.unkA == ax) { + platform->other.max_velocity = -platform->other.max_velocity; ax = 0; } - trigger->other.unkC = ax; + platform->other.counter = ax; } } } - const int x_pos = trigger->x_pos - (g_vars.tilemap.x << 4); + const int x_pos = platform->x_pos - (g_vars.tilemap.x << 4); if (x_pos >= TILEMAP_SCREEN_W + 32 || x_pos <= -32) { continue; } - const int y_pos = trigger->y_pos - (g_vars.tilemap.y << 4); + const int y_pos = platform->y_pos - (g_vars.tilemap.y << 4); if (y_pos >= TILEMAP_SCREEN_H + 32 || y_pos <= -32) { continue; } - obj->x_pos = trigger->x_pos; - obj->y_pos = trigger->y_pos; - obj->spr_num = trigger->spr_num; - obj->data.t.ref = trigger; + obj->x_pos = platform->x_pos; + obj->y_pos = platform->y_pos; + obj->spr_num = platform->spr_num; + obj->data.t.ref = platform; if (g_vars.objects_tbl[1].data.p.y_velocity > -16) { - trigger->flags |= 0x40; + platform->flags |= 0x40; if (level_update_objects_decors_helper(obj)) { ++obj; --count; @@ -2616,7 +2614,7 @@ static void level_update_objects_decors() { continue; } } - trigger->flags &= ~0x40; + platform->flags &= ~0x40; obj->y_pos -= 2; ++obj; --count; diff --git a/p2/resource.c b/p2/resource.c index c0653d1..bc50d99 100644 --- a/p2/resource.c +++ b/p2/resource.c @@ -104,15 +104,15 @@ void load_leveldat(const uint8_t *p, struct level_t *level) { gate->dst_pos = READ_LE_UINT16(p); p += 2; gate->scroll_flag = *p++; } - for (int i = 0; i < MAX_LEVEL_PLATFORMS; ++i) { - struct level_platform_t *platform = &g_res.level.platforms_tbl[i]; - platform->tilemap_pos = READ_LE_UINT16(p); p += 2; - platform->w = *p++; - platform->h = *p++; - platform->unk4 = READ_LE_UINT16(p); p += 2; - platform->unk6 = READ_LE_UINT16(p); p += 2; - platform->unk8 = *p++; - platform->unk9 = *p++; + for (int i = 0; i < MAX_LEVEL_UNKS; ++i) { + struct level_unk_t *unk = &g_res.level.unks_tbl[i]; + unk->tilemap_pos = READ_LE_UINT16(p); p += 2; + unk->w = *p++; + unk->h = *p++; + unk->unk4 = READ_LE_UINT16(p); p += 2; + unk->unk6 = READ_LE_UINT16(p); p += 2; + unk->unk8 = *p++; + unk->unk9 = *p++; } const uint8_t *monster_attr = p; int monsters_count = 0; @@ -225,27 +225,29 @@ void load_leveldat(const uint8_t *p, struct level_t *level) { item->spr_num = READ_LE_UINT16(p); p += 2; item->y_delta = *p++; } - for (int i = 0; i < MAX_LEVEL_TRIGGERS; ++i) { - struct level_trigger_t *trigger = &g_res.level.triggers_tbl[i]; - trigger->x_pos = READ_LE_UINT16(p); p += 2; - trigger->y_pos = READ_LE_UINT16(p); p += 2; - trigger->spr_num = READ_LE_UINT16(p); p += 2; - trigger->flags = *p++; - const int type = trigger->flags & 15; + for (int i = 0; i < MAX_LEVEL_PLATFORMS; ++i) { + struct level_platform_t *platform = &g_res.level.platforms_tbl[i]; + platform->x_pos = READ_LE_UINT16(p); p += 2; + platform->y_pos = READ_LE_UINT16(p); p += 2; + platform->spr_num = READ_LE_UINT16(p); p += 2; + platform->flags = *p++; + const int type = platform->flags & 15; if (type == 8) { - trigger->type8.y_velocity = *p++; - trigger->type8.unk8 = *p++; - trigger->type8.unk9 = *p++; - trigger->type8.state = *p++; - trigger->type8.y_delta = READ_LE_UINT16(p); p += 2; - trigger->type8.counter = *p++; + platform->type8.y_velocity = *p++; + platform->type8.unk8 = *p++; + platform->type8.unk9 = *p++; + platform->type8.state = *p++; + platform->type8.y_delta = READ_LE_UINT16(p); p += 2; + platform->type8.counter = *p++; + ++p; } else { - trigger->other.unk7 = READ_LE_UINT16(p); p += 2; - trigger->other.unk9 = *p++; - trigger->other.unkA = READ_LE_UINT16(p); p += 2; - trigger->other.unkC = READ_LE_UINT16(p); p += 2; + platform->other.max_velocity = *p++; + ++p; + platform->other.unk9 = *p++; + platform->other.unkA = READ_LE_UINT16(p); p += 2; + platform->other.counter = READ_LE_UINT16(p); p += 2; + platform->other.velocity = *p++; } - trigger->unkE = *p++; } g_res.level.boss_xmin = READ_LE_UINT16(p); p += 2; g_res.level.boss_xmax = READ_LE_UINT16(p); p += 2; diff --git a/p2/resource.h b/p2/resource.h index 089e2b3..52bdd79 100644 --- a/p2/resource.h +++ b/p2/resource.h @@ -11,7 +11,7 @@ struct level_gate_t { uint8_t scroll_flag; }; -struct level_platform_t { +struct level_unk_t { uint16_t tilemap_pos; uint8_t w; uint8_t h; @@ -34,7 +34,7 @@ struct level_item_t { int8_t y_delta; }; -struct level_trigger_t { +struct level_platform_t { uint16_t x_pos; uint16_t y_pos; uint16_t spr_num; @@ -49,13 +49,13 @@ struct level_trigger_t { uint8_t counter; } type8; struct { - int16_t unk7; + int8_t max_velocity; uint8_t unk9; - int16_t unkA; - int16_t unkC; + uint16_t unkA; + uint16_t counter; + int8_t velocity; } other; }; - uint8_t unkE; }; struct level_monster_t { @@ -122,12 +122,12 @@ struct level_monster_t { }; }; -#define MAX_LEVEL_GATES 20 -#define MAX_LEVEL_PLATFORMS 15 -#define MAX_LEVEL_BONUSES 80 -#define MAX_LEVEL_ITEMS 70 -#define MAX_LEVEL_TRIGGERS 16 -#define MAX_LEVEL_MONSTERS 150 +#define MAX_LEVEL_GATES 20 +#define MAX_LEVEL_UNKS 15 +#define MAX_LEVEL_BONUSES 80 +#define MAX_LEVEL_ITEMS 70 +#define MAX_LEVEL_PLATFORMS 16 +#define MAX_LEVEL_MONSTERS 150 struct level_t { uint8_t tile_attributes0[256]; @@ -140,7 +140,7 @@ struct level_t { uint16_t scrolling_mask; /* 4: screen scroll down 1 line, 2: no horizontal scrolling, 1: wider vertical scrolling */ uint16_t front_tiles_lut[256]; struct level_gate_t gates_tbl[MAX_LEVEL_GATES]; - struct level_platform_t platforms_tbl[MAX_LEVEL_PLATFORMS]; + struct level_unk_t unks_tbl[MAX_LEVEL_UNKS]; struct level_monster_t monsters_tbl[MAX_LEVEL_MONSTERS]; uint8_t monsters_count; uint16_t items_spr_num_offset; @@ -148,7 +148,7 @@ struct level_t { struct level_bonus_t bonuses_tbl[MAX_LEVEL_BONUSES]; uint8_t tile_attributes3[256]; struct level_item_t items_tbl[MAX_LEVEL_ITEMS]; - struct level_trigger_t triggers_tbl[MAX_LEVEL_TRIGGERS]; + struct level_platform_t platforms_tbl[MAX_LEVEL_PLATFORMS]; uint16_t boss_xmin; uint16_t boss_xmax; uint8_t boss_counter;