Import blues from aa9d33d3

This commit is contained in:
Gregory Montoir 2019-06-02 08:35:19 +08:00
parent 9a76b82910
commit 1592f7ef80
5 changed files with 139 additions and 135 deletions

View File

@ -61,3 +61,7 @@ Usage: blues [OPTIONS]...
--screensize=WxH Graphics screen size (default 320x200) --screensize=WxH Graphics screen size (default 320x200)
--cga Enable CGA colors --cga Enable CGA colors
``` ```
## Downloads
[blues-sdl2-win32.zip](https://www.dropbox.com/s/vv8mh0vrk8l6xro/blues-gh-sdl2-win32.zip?dl=0) - Win32 executable

View File

@ -38,7 +38,7 @@ struct object_t {
uint8_t b[2]; uint8_t b[2];
int16_t w; int16_t w;
const uint8_t *p; const uint8_t *p;
} data[11]; // 0x6..0x1C } data[11];
}; };
enum { enum {
@ -49,22 +49,22 @@ enum {
PLAYER_FLAGS_JAKE = 0x80 PLAYER_FLAGS_JAKE = 0x80
}; };
#define player_obj_num(obj) (obj)->data[0].w // 0x6 #define player_obj_num(obj) (obj)->data[0].w
#define player_prev_spr_num(obj) (obj)->data[1].w // 0x8 #define player_prev_spr_num(obj) (obj)->data[1].w
#define player_anim_data(obj) (obj)->data[2].p // 0xA #define player_anim_data(obj) (obj)->data[2].p
#define player_idle_counter(obj) (obj)->data[3].b[0] // 0xC #define player_idle_counter(obj) (obj)->data[3].b[0]
#define player_power(obj) (obj)->data[3].b[1] // 0xD #define player_power(obj) (obj)->data[3].b[1]
#define player_x_delta(obj) (obj)->data[4].w // 0xE #define player_x_delta(obj) (obj)->data[4].w
#define player_y_delta(obj) (obj)->data[5].w // 0x10 #define player_y_delta(obj) (obj)->data[5].w
#define player_flags(obj) (obj)->data[6].b[0] // 0x12 #define player_flags(obj) (obj)->data[6].b[0]
#define player_jump_counter(obj) (obj)->data[6].b[1] // 0x13 #define player_jump_counter(obj) (obj)->data[6].b[1]
#define player_bounce_counter(obj) (obj)->data[7].b[0] // 0x14 #define player_bounce_counter(obj) (obj)->data[7].b[0]
#define player_tilemap_offset(obj) (obj)->data[8].w // 0x16 #define player_tilemap_offset(obj) (obj)->data[8].w
#define player_hit_counter(obj) (obj)->data[9].b[0] // 0x18 #define player_hit_counter(obj) (obj)->data[9].b[0]
#define player_throw_counter(obj) (obj)->data[9].b[1] // 0x19 #define player_throw_counter(obj) (obj)->data[9].b[1]
#define player_flags2(obj) (obj)->data[10].b[0] // 0x1A, 8:dead 1:blocked #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 */ /* star */
#define object2_spr_count(obj) (obj)->data[0].b[0] #define object2_spr_count(obj) (obj)->data[0].b[0]
@ -99,13 +99,13 @@ enum {
struct player_t { struct player_t {
struct object_t obj; struct object_t obj;
int16_t unk_counter; // 0x1D always zero int16_t unk_counter;
int16_t change_hdir_counter; int16_t change_hdir_counter;
uint8_t lifes_count; uint8_t lifes_count;
int16_t vinyls_count; int16_t vinyls_count;
int8_t energy; int8_t energy;
uint8_t dir_mask; // 0x25 uint8_t dir_mask;
uint8_t ticks_counter; // 0x26 uint8_t ticks_counter;
}; };
#define TRIGGERS_COUNT 36 #define TRIGGERS_COUNT 36

View File

@ -126,10 +126,10 @@ static void load_level_data_fix_items_spr_num() {
g_res.level.items_tbl[i].spr_num = num - offset + 53; g_res.level.items_tbl[i].spr_num = num - offset + 53;
} }
} }
for (int i = 0; i < MAX_LEVEL_TRIGGERS; ++i) { for (int i = 0; i < MAX_LEVEL_PLATFORMS; ++i) {
const uint16_t num = g_res.level.triggers_tbl[i].spr_num; const uint16_t num = g_res.level.platforms_tbl[i].spr_num;
if (num != 0xFFFF) { 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) { for (int i = count; i < 8; ++i) {
struct object_t *obj = &g_vars.objects_tbl[108 + i]; g_vars.objects_tbl[108 + i].spr_num = 0xFFFF;
obj->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) { if (g_vars.boss.unk_counter < 0) {
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(); level_update_objects_boss_hit_player();
obj_player->hit_counter = 44; obj_player->hit_counter = 44;
g_vars.player_anim_0x40_flag = 0; 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; g_vars.level_force_x_scroll_flag = 0;
int count = 7; int count = 7;
struct object_t *obj = &g_vars.objects_tbl[91]; struct object_t *obj = &g_vars.objects_tbl[91];
for (int i = 0; i < MAX_LEVEL_TRIGGERS; ++i) { for (int i = 0; i < MAX_LEVEL_PLATFORMS; ++i) {
struct level_trigger_t *trigger = &g_res.level.triggers_tbl[i]; struct level_platform_t *platform = &g_res.level.platforms_tbl[i];
if (trigger->spr_num == 0xFFFF) { if (platform->spr_num == 0xFFFF) {
continue; continue;
} }
if ((trigger->flags & 15) == 8) { if ((platform->flags & 15) == 8) {
g_vars.level_current_object_decor_x_pos = 0; g_vars.level_current_object_decor_x_pos = 0;
trigger->y_pos -= trigger->type8.y_delta; platform->y_pos -= platform->type8.y_delta;
if (trigger->type8.state == 0) { if (platform->type8.state == 0) {
int a = trigger->type8.y_delta - 8; int a = platform->type8.y_delta - 8;
if (a < 0) { if (a < 0) {
a = 0; a = 0;
trigger->type8.y_velocity = 0; platform->type8.y_velocity = 0;
} }
trigger->type8.y_delta = a; platform->type8.y_delta = a;
if (trigger->flags & 0x40) { if (platform->flags & 0x40) {
if (trigger->type8.y_velocity != 0 && --trigger->type8.counter == 0) { if (platform->type8.y_velocity != 0 && --platform->type8.counter == 0) {
trigger->type8.state = 1; platform->type8.state = 1;
trigger->type8.y_velocity = 0; platform->type8.y_velocity = 0;
} }
} }
} else if (trigger->type8.state == 1) { } else if (platform->type8.state == 1) {
int y = trigger->type8.y_velocity; int y = platform->type8.y_velocity;
if (y < 192) { if (y < 192) {
trigger->type8.y_velocity += 8; platform->type8.y_velocity += 8;
} }
y >>= 4; y >>= 4;
g_vars.level_current_object_decor_y_pos = y; g_vars.level_current_object_decor_y_pos = y;
trigger->type8.y_delta += y; platform->type8.y_delta += y;
const int tile_x = trigger->x_pos >> 4; const int tile_x = platform->x_pos >> 4;
const int tile_y = (trigger->y_pos + trigger->type8.y_delta) >> 4; const int tile_y = (platform->y_pos + platform->type8.y_delta) >> 4;
const int y2 = g_vars.tilemap.h - 1 - tile_y; const int y2 = g_vars.tilemap.h - 1 - tile_y;
if (y2 < 0) { if (y2 < 0) {
if ((-y2) >= 3) { if ((-y2) >= 3) {
trigger->type8.state = 2; platform->type8.state = 2;
trigger->type8.counter = 22; platform->type8.counter = 22;
} }
} else { } else {
const uint8_t tile_num = level_get_tile((tile_y << 8) | tile_x); 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]; const uint8_t tile_attr1 = g_res.level.tile_attributes1[tile_num];
if (tile_attr1 != 0 && tile_attr1 != 6) { if (tile_attr1 != 0 && tile_attr1 != 6) {
trigger->type8.state = 2; platform->type8.state = 2;
trigger->type8.counter = 22; platform->type8.counter = 22;
} }
} }
} else if (trigger->type8.state == 2) { } else if (platform->type8.state == 2) {
if ((trigger->flags & 0x40) == 0 && --trigger->type8.counter == 0) { if ((platform->flags & 0x40) == 0 && --platform->type8.counter == 0) {
trigger->type8.state = 0; platform->type8.state = 0;
trigger->type8.counter = trigger->type8.unk9; platform->type8.counter = platform->type8.unk9;
} }
} }
trigger->y_pos += trigger->type8.y_delta; platform->y_pos += platform->type8.y_delta;
} else { } else {
g_vars.level_current_object_decor_x_pos = 0; g_vars.level_current_object_decor_x_pos = 0;
g_vars.level_current_object_decor_y_pos = 0; g_vars.level_current_object_decor_y_pos = 0;
if (trigger->unkE != 0 || trigger->other.unk7 < 0 || (trigger->flags & 0xC0) != 0) { if (platform->other.velocity != 0 || platform->other.max_velocity < 0 || (platform->flags & 0xC0) != 0) {
if (trigger->other.unk7 > trigger->unkE) { if (platform->other.max_velocity > platform->other.velocity) {
++trigger->unkE; ++platform->other.velocity;
} else if (trigger->other.unk7 < trigger->unkE) { } else if (platform->other.max_velocity < platform->other.velocity) {
--trigger->unkE; --platform->other.velocity;
} }
int al = trigger->unkE; int al = platform->other.velocity;
int ah = trigger->unkE; int ah = platform->other.velocity;
int dl = trigger->flags & 7; const int type = platform->flags & 7;
if (dl == 0) { if (type == 0) {
al = 0; al = 0;
ah = -ah; ah = -ah;
} else if (dl == 1) { } else if (type == 1) {
ah = -ah; ah = -ah;
} else if (dl == 2) { } else if (type == 2) {
ah = 0; ah = 0;
} } else if (type == 4) {
if (dl != 3) {
if (dl == 4) {
al = 0; al = 0;
} else if (dl == 5) { } else if (type == 5) {
al = -al; al = -al;
} else if (dl == 6) { } else if (type == 6) {
al = -al; al = -al;
ah = 0; ah = 0;
} else if (dl == 7) { } else if (type == 7) {
al = -al; al = -al;
ah = -ah; ah = -ah;
} }
} g_vars.level_current_object_decor_x_pos = al;
dl = ah; platform->x_pos += al;
g_vars.level_current_object_decor_x_pos = (int8_t)al; g_vars.level_current_object_decor_y_pos = ah;
trigger->x_pos += al; platform->y_pos += ah;
g_vars.level_current_object_decor_y_pos = (int8_t)dl; if (platform->other.max_velocity == platform->other.velocity) {
trigger->y_pos += dl; uint16_t ax = platform->other.counter + 1;
if (trigger->other.unk7 == trigger->unkE) { if (platform->other.unkA == ax) {
int16_t ax = trigger->other.unkC + 1; platform->other.max_velocity = -platform->other.max_velocity;
if (trigger->other.unkA == ax) {
trigger->other.unk7 = -trigger->other.unk7;
ax = 0; 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) { if (x_pos >= TILEMAP_SCREEN_W + 32 || x_pos <= -32) {
continue; 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) { if (y_pos >= TILEMAP_SCREEN_H + 32 || y_pos <= -32) {
continue; continue;
} }
obj->x_pos = trigger->x_pos; obj->x_pos = platform->x_pos;
obj->y_pos = trigger->y_pos; obj->y_pos = platform->y_pos;
obj->spr_num = trigger->spr_num; obj->spr_num = platform->spr_num;
obj->data.t.ref = trigger; obj->data.t.ref = platform;
if (g_vars.objects_tbl[1].data.p.y_velocity > -16) { if (g_vars.objects_tbl[1].data.p.y_velocity > -16) {
trigger->flags |= 0x40; platform->flags |= 0x40;
if (level_update_objects_decors_helper(obj)) { if (level_update_objects_decors_helper(obj)) {
++obj; ++obj;
--count; --count;
@ -2616,7 +2614,7 @@ static void level_update_objects_decors() {
continue; continue;
} }
} }
trigger->flags &= ~0x40; platform->flags &= ~0x40;
obj->y_pos -= 2; obj->y_pos -= 2;
++obj; ++obj;
--count; --count;

View File

@ -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->dst_pos = READ_LE_UINT16(p); p += 2;
gate->scroll_flag = *p++; gate->scroll_flag = *p++;
} }
for (int i = 0; i < MAX_LEVEL_PLATFORMS; ++i) { for (int i = 0; i < MAX_LEVEL_UNKS; ++i) {
struct level_platform_t *platform = &g_res.level.platforms_tbl[i]; struct level_unk_t *unk = &g_res.level.unks_tbl[i];
platform->tilemap_pos = READ_LE_UINT16(p); p += 2; unk->tilemap_pos = READ_LE_UINT16(p); p += 2;
platform->w = *p++; unk->w = *p++;
platform->h = *p++; unk->h = *p++;
platform->unk4 = READ_LE_UINT16(p); p += 2; unk->unk4 = READ_LE_UINT16(p); p += 2;
platform->unk6 = READ_LE_UINT16(p); p += 2; unk->unk6 = READ_LE_UINT16(p); p += 2;
platform->unk8 = *p++; unk->unk8 = *p++;
platform->unk9 = *p++; unk->unk9 = *p++;
} }
const uint8_t *monster_attr = p; const uint8_t *monster_attr = p;
int monsters_count = 0; 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->spr_num = READ_LE_UINT16(p); p += 2;
item->y_delta = *p++; item->y_delta = *p++;
} }
for (int i = 0; i < MAX_LEVEL_TRIGGERS; ++i) { for (int i = 0; i < MAX_LEVEL_PLATFORMS; ++i) {
struct level_trigger_t *trigger = &g_res.level.triggers_tbl[i]; struct level_platform_t *platform = &g_res.level.platforms_tbl[i];
trigger->x_pos = READ_LE_UINT16(p); p += 2; platform->x_pos = READ_LE_UINT16(p); p += 2;
trigger->y_pos = READ_LE_UINT16(p); p += 2; platform->y_pos = READ_LE_UINT16(p); p += 2;
trigger->spr_num = READ_LE_UINT16(p); p += 2; platform->spr_num = READ_LE_UINT16(p); p += 2;
trigger->flags = *p++; platform->flags = *p++;
const int type = trigger->flags & 15; const int type = platform->flags & 15;
if (type == 8) { if (type == 8) {
trigger->type8.y_velocity = *p++; platform->type8.y_velocity = *p++;
trigger->type8.unk8 = *p++; platform->type8.unk8 = *p++;
trigger->type8.unk9 = *p++; platform->type8.unk9 = *p++;
trigger->type8.state = *p++; platform->type8.state = *p++;
trigger->type8.y_delta = READ_LE_UINT16(p); p += 2; platform->type8.y_delta = READ_LE_UINT16(p); p += 2;
trigger->type8.counter = *p++; platform->type8.counter = *p++;
++p;
} else { } else {
trigger->other.unk7 = READ_LE_UINT16(p); p += 2; platform->other.max_velocity = *p++;
trigger->other.unk9 = *p++; ++p;
trigger->other.unkA = READ_LE_UINT16(p); p += 2; platform->other.unk9 = *p++;
trigger->other.unkC = READ_LE_UINT16(p); p += 2; 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_xmin = READ_LE_UINT16(p); p += 2;
g_res.level.boss_xmax = READ_LE_UINT16(p); p += 2; g_res.level.boss_xmax = READ_LE_UINT16(p); p += 2;

View File

@ -11,7 +11,7 @@ struct level_gate_t {
uint8_t scroll_flag; uint8_t scroll_flag;
}; };
struct level_platform_t { struct level_unk_t {
uint16_t tilemap_pos; uint16_t tilemap_pos;
uint8_t w; uint8_t w;
uint8_t h; uint8_t h;
@ -34,7 +34,7 @@ struct level_item_t {
int8_t y_delta; int8_t y_delta;
}; };
struct level_trigger_t { struct level_platform_t {
uint16_t x_pos; uint16_t x_pos;
uint16_t y_pos; uint16_t y_pos;
uint16_t spr_num; uint16_t spr_num;
@ -49,13 +49,13 @@ struct level_trigger_t {
uint8_t counter; uint8_t counter;
} type8; } type8;
struct { struct {
int16_t unk7; int8_t max_velocity;
uint8_t unk9; uint8_t unk9;
int16_t unkA; uint16_t unkA;
int16_t unkC; uint16_t counter;
int8_t velocity;
} other; } other;
}; };
uint8_t unkE;
}; };
struct level_monster_t { struct level_monster_t {
@ -123,10 +123,10 @@ struct level_monster_t {
}; };
#define MAX_LEVEL_GATES 20 #define MAX_LEVEL_GATES 20
#define MAX_LEVEL_PLATFORMS 15 #define MAX_LEVEL_UNKS 15
#define MAX_LEVEL_BONUSES 80 #define MAX_LEVEL_BONUSES 80
#define MAX_LEVEL_ITEMS 70 #define MAX_LEVEL_ITEMS 70
#define MAX_LEVEL_TRIGGERS 16 #define MAX_LEVEL_PLATFORMS 16
#define MAX_LEVEL_MONSTERS 150 #define MAX_LEVEL_MONSTERS 150
struct level_t { struct level_t {
@ -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 scrolling_mask; /* 4: screen scroll down 1 line, 2: no horizontal scrolling, 1: wider vertical scrolling */
uint16_t front_tiles_lut[256]; uint16_t front_tiles_lut[256];
struct level_gate_t gates_tbl[MAX_LEVEL_GATES]; 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]; struct level_monster_t monsters_tbl[MAX_LEVEL_MONSTERS];
uint8_t monsters_count; uint8_t monsters_count;
uint16_t items_spr_num_offset; uint16_t items_spr_num_offset;
@ -148,7 +148,7 @@ struct level_t {
struct level_bonus_t bonuses_tbl[MAX_LEVEL_BONUSES]; struct level_bonus_t bonuses_tbl[MAX_LEVEL_BONUSES];
uint8_t tile_attributes3[256]; uint8_t tile_attributes3[256];
struct level_item_t items_tbl[MAX_LEVEL_ITEMS]; 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_xmin;
uint16_t boss_xmax; uint16_t boss_xmax;
uint8_t boss_counter; uint8_t boss_counter;