Import blues from 560ddc1f

This commit is contained in:
Gregory Montoir 2019-06-01 21:47:44 +08:00
parent 380a015ae8
commit bba624f9dd
6 changed files with 246 additions and 43 deletions

View File

@ -38,7 +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);
video_clear();
g_sys.set_screen_palette(credits_palette_data, 0, 16, 6);
int offset = 0x960;
video_draw_string(offset, 5, "YEAAA > > >");

View File

@ -37,7 +37,7 @@ struct club_projectile_t {
};
struct monster_t {
uint8_t unk5;
uint8_t flags;
void *ref;
int16_t x_velocity;
int16_t y_velocity;
@ -169,7 +169,7 @@ struct vars_t {
uint8_t level_xscroll_center_flag, level_yscroll_center_flag;
uint8_t level_force_x_scroll_flag;
bool tilemap_adjust_player_pos_flag;
uint8_t level_noscroll_flag;
uint8_t tilemap_noscroll_flag;
int16_t tilemap_yscroll_diff;
int16_t tilemap_x, tilemap_y;
int16_t tilemap_prev_x, tilemap_prev_y;
@ -234,7 +234,7 @@ extern const uint8_t vscroll_offsets_data[132];
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[];
extern const uint8_t monster_anim_tbl[1018];
/* game.c */
extern void update_input();

View File

@ -335,7 +335,7 @@ static bool level_adjust_hscroll_right() {
}
static void level_adjust_x_scroll() {
if (!g_options.dos_scrolling && g_vars.level_noscroll_flag == 0) {
if (!g_options.dos_scrolling && g_vars.tilemap_noscroll_flag == 0) {
const int x1 = TILEMAP_SCROLL_W * 2;
const int x2 = TILEMAP_SCREEN_W - TILEMAP_SCROLL_W * 2;
int tilemap_xpos = (g_vars.tilemap_x << 4) + g_vars.tilemap_scroll_dx;
@ -523,7 +523,7 @@ static void level_adjust_y_scroll() {
}
static void level_update_scrolling() {
if (g_vars.level_noscroll_flag != 0) {
if (g_vars.tilemap_noscroll_flag != 0) {
return;
}
if ((g_res.level.scrolling_mask & 2) == 0) {
@ -1105,7 +1105,7 @@ static void level_monster_die(struct object_t *obj, struct level_monster_t *m) {
dy = (-dy) << 3;
obj->data.m.y_velocity = dy;
int dx = dy >> 1;
if ((obj->data.m.unk5 & 0x80) == 0) {
if ((obj->data.m.flags & 0x80) == 0) {
dx = -dx;
}
obj->data.m.x_velocity = dx;
@ -1128,7 +1128,7 @@ static bool level_collide_axe_monsters(struct object_t *axe_obj) {
if (!level_objects_collide(axe_obj, obj)) {
continue;
}
obj->data.m.unk5 |= 0x40;
obj->data.m.flags |= 0x40;
obj->data.m.energy -= g_vars.player_club_power;
if (obj->data.m.energy < 0) {
level_monster_die(obj, m);
@ -1453,10 +1453,15 @@ static void level_update_objects_monsters() {
continue;
}
const uint8_t *p = monster_anim_tbl;
const uint8_t *end = &monster_anim_tbl[1018];
const int spr_num = m->spr_num - 305;
do {
p += 2;
} while (READ_LE_UINT16(p) != 0x7D01 || READ_LE_UINT16(p + 2) != m->type);
if (p >= end) {
print_warning("level_update_objects_monsters type %d spr %d not found", m->type, spr_num);
continue;
}
} while (READ_LE_UINT16(p) != 0x7D01 || READ_LE_UINT16(p + 2) != type);
p += 4;
while (READ_LE_UINT16(p) != spr_num) {
p += 2;
@ -1997,7 +2002,7 @@ static void level_update_player_anim_0(uint8_t al) {
if ((g_vars.input.key_right & g_vars.input.key_left) != 0) {
const uint8_t *anim = level_update_player_anim1_num(19, 38);
level_update_object_anim(anim);
if ((g_res.level.scrolling_mask & 2) == 0 && g_vars.level_noscroll_flag == 0) {
if ((g_res.level.scrolling_mask & 2) == 0 && g_vars.tilemap_noscroll_flag == 0) {
const int dx = (g_vars.objects_tbl[1].x_pos >> 4) - g_vars.tilemap_x;
if ((g_vars.objects_tbl[1].spr_num & 0x8000) == 0) {
if (dx > 2) {
@ -2743,7 +2748,7 @@ static void level_update_gates() {
}
}
g_res.level.tilemap_w = tmp;
g_vars.level_noscroll_flag = gate->scroll_flag;
g_vars.tilemap_noscroll_flag = gate->scroll_flag;
g_vars.player_action_counter = 0;
if (g_vars.level_num == 5) {
}

View File

@ -39,10 +39,10 @@ static void monster_func1_helper(struct object_t *obj, int16_t x_pos, int16_t y_
}
static bool monster_next_tick(struct level_monster_t *m) {
if (m->current_tick < 255) {
if (m->current_tick < UCHAR_MAX) {
++m->current_tick;
}
return ((m->current_tick >> 2) < m->total_ticks);
return ((m->current_tick >> 2) < m->respawn_ticks);
}
void monster_change_next_anim(struct object_t *obj) {
@ -130,6 +130,45 @@ static void monster_func1_type2(struct object_t *obj) {
}
}
static void monster_func1_type3(struct object_t *obj) {
monster_func1_helper(obj, obj->x_pos, obj->y_pos);
struct level_monster_t *m = obj->data.m.ref;
const uint8_t state = obj->data.m.state;
if (state == 0) {
if (monster_next_tick(m)) {
return;
}
const int dx = abs(m->x_pos - g_vars.objects_tbl[1].x_pos) >> 4;
if (m->type3.unkD < dx) {
return;
}
m->flags &= ~0x10;
obj->data.m.state = 1;
obj->data.m.y_velocity = 32;
monster_change_next_anim(obj);
} else if (state == 1) {
monster_rotate_tiles(m, 0, obj->y_pos - m->y_pos);
const uint16_t pos = ((obj->y_pos >> 4) << 8) | (obj->x_pos >> 4);
const uint8_t tile_num = g_res.leveldat[pos];
if (g_res.level.tile_attributes1[tile_num] == 0) {
return;
}
obj->y_pos &= ~15;
obj->data.m.y_velocity = 0;
obj->data.m.state = 2;
m->flags |= 0x48;
const int dx = (g_vars.objects_tbl[1].x_pos >= obj->x_pos) ? 48 : -48;
obj->data.m.x_velocity = dx;
monster_change_next_anim(obj);
} else if (state == 2) {
if (obj->x_pos < 0) {
obj->data.m.x_velocity = -obj->data.m.x_velocity;
}
} else if (state == 0xFF) {
monster_update_y_velocity(obj, m);
}
}
static void monster_func1_type4(struct object_t *obj) {
monster_func1_helper(obj, obj->x_pos, obj->y_pos);
struct level_monster_t *m = obj->data.m.ref;
@ -165,6 +204,31 @@ static void monster_func1_type4(struct object_t *obj) {
}
}
static void monster_func1_type7(struct object_t *obj) {
monster_func1_helper(obj, obj->x_pos, obj->y_pos);
struct level_monster_t *m = obj->data.m.ref;
const uint8_t state = obj->data.m.state;
if (state == 0) {
const int x_vel = (obj->x_pos <= g_vars.objects_tbl[1].x_pos) ? 1 : -1;
obj->data.m.x_velocity = x_vel;
const int dx = abs(g_vars.objects_tbl[1].x_pos - obj->x_pos) >> 4;
if (m->type7.unkD < dx) {
return;
}
obj->data.m.state = 10;
int x = m->type7.unkE << 4;
obj->data.m.y_velocity = x;
if (obj->data.m.x_velocity & 0x5000) {
x = -x;
}
obj->data.m.x_velocity = x;
monster_change_next_anim(obj);
} else if (state == 10) {
} else if (state == 0xFF) {
monster_update_y_velocity(obj, m);
}
}
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;
@ -229,22 +293,22 @@ static void monster_func1_type9(struct object_t *obj) {
}
const uint8_t state = obj->data.m.state;
if (state == 0) {
obj->data.m.x_velocity = m->type9.unk11;
const int x = m->type9.unk11 + 3;
if (x <= m->type9.unk12) {
m->type9.unk11 = x;
obj->data.m.x_velocity = m->type9.x_step;
const int x = m->type9.x_step + 3;
if (x <= m->type9.x_dist) {
m->type9.x_step = x;
}
if (m->type9.unkF < obj->x_pos) {
obj->data.m.state = 1;
}
} else if (state == 1) {
obj->data.m.x_velocity = m->type9.unk11;
const int x = m->type9.unk11 - 3;
if (x >= -m->type9.unk12) {
m->type9.unk11 = x;
obj->data.m.x_velocity = m->type9.x_step;
const int x = m->type9.x_step - 3;
if (x >= -m->type9.x_dist) {
m->type9.x_step = x;
}
if (m->type9.unkD >= obj->x_pos) {
obj->data.m.state = 1;
obj->data.m.state = 0;
}
} else if (state == 0xFF) {
monster_update_y_velocity(obj, m);
@ -300,7 +364,7 @@ static void monster_func1_type10(struct object_t *obj) {
}
monster_reset(obj, m);
} else if (state == 0xFF) {
if ((m->flags & 1) != 0 || (obj->data.m.unk5 & 0x20) != 0 || g_vars.objects_tbl[1].y_pos >= obj->y_pos) {
if ((m->flags & 1) != 0 || (obj->data.m.flags & 0x20) != 0 || g_vars.objects_tbl[1].y_pos >= obj->y_pos) {
if (obj->data.m.y_velocity < 240) {
obj->data.m.y_velocity += 15;
}
@ -310,6 +374,61 @@ static void monster_func1_type10(struct object_t *obj) {
}
}
static void monster_func1_type11(struct object_t *obj) {
monster_func1_helper(obj, obj->x_pos, obj->y_pos);
struct level_monster_t *m = obj->data.m.ref;
const uint8_t state = obj->data.m.state;
if (state == 0) {
if (g_vars.monster.hit_mask == 0) {
return;
}
obj->data.m.state = 1;
m->flags &= ~0x10;
int x_vel = m->type11.unkD << 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.y_velocity = -(m->type11.unkE << 4);
} else if (state == 1) {
if (obj->data.m.y_velocity < (m->type11.unkF << 4)) {
obj->data.m.y_velocity += 8;
}
} else if (state == 0xFF) {
if ((obj->data.m.flags & 0x20) != 0 || g_vars.objects_tbl[1].y_pos >= obj->y_pos) {
if (obj->data.m.y_velocity < 240) {
obj->data.m.y_velocity += 15;
}
} else {
monster_reset(obj, m);
}
}
}
static void monster_func1_type12(struct object_t *obj) {
struct level_monster_t *m = obj->data.m.ref;
const uint8_t state = obj->data.m.state;
if (state == 0) {
int x_vel = m->type12.unkD;
if (g_vars.objects_tbl[1].x_pos < obj->x_pos) {
x_vel = -x_vel;
}
obj->data.m.x_velocity = x_vel << 4;
obj->data.m.state = 1;
} else if (state == 1) {
if (obj->data.m.flags & 0x20) {
m->current_tick = 0;
} else {
++m->current_tick;
if (m->current_tick >= 154) {
obj->data.m.state = 0xFF;
}
}
} else if (state == 0xFF) {
monster_update_y_velocity(obj, m);
}
}
void monster_func1(int type, struct object_t *obj) {
switch (type) {
case 1:
@ -318,9 +437,15 @@ void monster_func1(int type, struct object_t *obj) {
case 2:
monster_func1_type2(obj);
break;
case 3:
monster_func1_type3(obj);
break;
case 4:
monster_func1_type4(obj);
break;
case 7:
monster_func1_type7(obj);
break;
case 8:
monster_func1_type8(obj);
break;
@ -330,6 +455,12 @@ void monster_func1(int type, struct object_t *obj) {
case 10:
monster_func1_type10(obj);
break;
case 11:
monster_func1_type11(obj);
break;
case 12:
monster_func1_type12(obj);
break;
default:
print_warning("monster_func1 unhandled monster type %d", type);
break;
@ -406,6 +537,14 @@ static bool monster_func2_type2(struct level_monster_t *m) {
return false;
}
static bool monster_func2_type3(struct level_monster_t *m) {
if (!monster_func2_type1(m)) {
return false;
}
m->flags = 0x37;
return true;
}
static bool monster_func2_type4(struct level_monster_t *m) {
if (!monster_func2_type1(m)) {
return false;
@ -441,10 +580,10 @@ static bool monster_func2_type10(struct level_monster_t *m) {
if (g_vars.level_num == 5 && g_vars.shake_screen_counter != 0) {
return false;
}
if (m->current_tick < 255) {
if (m->current_tick < UCHAR_MAX) {
++m->current_tick;
}
if (m->total_ticks > (m->current_tick >> 2)) {
if (m->respawn_ticks > (m->current_tick >> 2)) {
return false;
}
const uint16_t x = m->x_pos;
@ -475,19 +614,19 @@ static bool monster_func2_type10(struct level_monster_t *m) {
obj->data.m.x_velocity = 0;
uint8_t bh = (g_vars.objects_tbl[1].y_pos >> 4) + 4;
uint8_t bl = (obj->x_pos >> 4);
uint16_t bp = (bh << 8) | bl;
for (int i = 0; i < 10; ++i) {
if (bp < (g_vars.tilemap_h << 8)) {
uint16_t pos = (bh << 8) | bl;
for (int i = 0; i < 10 && pos >= 0x300; ++i, pos -= 0x100) {
if (pos < (g_vars.tilemap_h << 8)) {
bool init_spr = true;
for (int j = 0; j < 3; ++j) {
const uint8_t tile_num = g_res.leveldat[bp - j * 0x100];
const uint8_t tile_num = g_res.leveldat[pos - j * 0x100];
if (g_res.level.tile_attributes1[tile_num] != 0) {
init_spr = false;
break;
}
}
if (init_spr) {
obj->y_pos = bh << 4;
obj->y_pos = (pos >> 8) << 4;
obj->spr_num = m->spr_num;
obj->data.m.ref = m;
m->flags = 0x17;
@ -497,19 +636,15 @@ static bool monster_func2_type10(struct level_monster_t *m) {
return true;
}
}
bp -= 0x100;
if (bp < 0x300) {
return false;
}
}
return false;
}
static bool monster_func2_type11(struct level_monster_t *m) {
if (m->current_tick < 255) {
if (m->current_tick < UCHAR_MAX) {
++m->current_tick;
}
if (m->total_ticks > (m->current_tick >> 2) || !monster_func2_type1(m)) {
if (m->respawn_ticks > (m->current_tick >> 2) || !monster_func2_type1(m)) {
return false;
}
m->flags = 0x37;
@ -517,12 +652,42 @@ static bool monster_func2_type11(struct level_monster_t *m) {
return true;
}
static bool monster_func2_type12(struct level_monster_t *m) {
if (g_vars.objects_tbl[1].y_pos <= m->y_pos) {
return false;
}
const int dx = abs(m->x_pos - g_vars.objects_tbl[1].x_pos);
if (dx >= TILEMAP_SCREEN_W * 2) {
return false;
}
if (dx <= TILEMAP_SCREEN_W) {
const int dy = g_vars.objects_tbl[1].y_pos - m->y_pos;
if (dy >= 360 || dy <= 180) {
return false;
}
}
if (m->current_tick < UCHAR_MAX) {
++m->current_tick;
}
if (m->respawn_ticks > (m->current_tick >> 2)) {
return false;
}
if (!monster_init_object(m)) {
return false;
}
m->flags = 0x8F;
m->current_tick = 0;
return true;
}
bool monster_func2(int type, struct level_monster_t *m) {
switch (type) {
case 1:
return monster_func2_type1(m);
case 2:
return monster_func2_type2(m);
case 3:
return monster_func2_type3(m);
case 4:
return monster_func2_type4(m);
case 5:
@ -536,6 +701,8 @@ bool monster_func2(int type, struct level_monster_t *m) {
return monster_func2_type10(m);
case 11:
return monster_func2_type11(m);
case 12:
return monster_func2_type12(m);
default:
print_warning("monster_func2 unhandled monster type %d", type);
break;

View File

@ -124,7 +124,7 @@ void load_leveldat(const uint8_t *p, struct level_t *level) {
m->type = p[1];
m->spr_num = spr_num;
m->energy = p[5];
m->total_ticks = p[6];
m->respawn_ticks = p[6];
m->current_tick = p[7];
m->score = p[8];
m->x_pos = READ_LE_UINT16(p + 0x9);
@ -138,6 +138,9 @@ void load_leveldat(const uint8_t *p, struct level_t *level) {
m->type2.y_range = p[0xD];
m->type2.unkE = p[0xE];
break;
case 3:
m->type3.unkD = p[0xD];
break;
case 4: /* rotate (eg. spider) */
assert(len == 17);
m->type4.radius = p[0xD];
@ -145,7 +148,11 @@ void load_leveldat(const uint8_t *p, struct level_t *level) {
m->type4.angle = p[0xF];
m->type4.unk10 = p[0x10];
break;
case 8: /* jumps (eg. leopard) */
case 7:
m->type7.unkD = p[0xD];
m->type7.unkE = p[0xE];
break;
case 8: /* jump */
assert(len == 17);
m->type8.x_range = p[0xD];
m->type8.y_step = p[0xE];
@ -156,13 +163,22 @@ void load_leveldat(const uint8_t *p, struct level_t *level) {
assert(len == 19);
m->type9.unkD = READ_LE_UINT16(p + 0xD);
m->type9.unkF = READ_LE_UINT16(p + 0xF);
m->type9.unk11 = p[0x11];
m->type9.unk12 = p[0x12];
m->type9.x_step = p[0x11];
m->type9.x_dist = p[0x12];
break;
case 10: /* come out of the ground */
assert(len == 14);
m->type10.unkD = p[0xD];
break;
case 11:
m->type11.unkD = p[0xD];
m->type11.unkE = p[0xE];
m->type11.unkF = p[0xF];
break;
case 12:
assert(len == 14);
m->type12.unkD = p[0xD];
break;
default:
print_warning("Unhandled monster type %d len %d", type, len);
break;

View File

@ -64,7 +64,7 @@ struct level_monster_t {
uint16_t spr_num;
uint8_t flags;
uint8_t energy;
uint8_t total_ticks;
uint8_t respawn_ticks;
uint8_t current_tick;
uint8_t score;
uint16_t x_pos;
@ -74,12 +74,19 @@ struct level_monster_t {
uint8_t y_range;
int8_t unkE;
} type2;
struct {
uint8_t unkD;
} type3;
struct {
uint8_t radius;
uint8_t unkE;
uint8_t angle;
uint8_t unk10;
} type4;
struct {
uint8_t unkD;
uint8_t unkE;
} type7;
struct {
uint8_t x_range;
int8_t y_step;
@ -89,12 +96,20 @@ struct level_monster_t {
struct {
int16_t unkD;
int16_t unkF;
int8_t unk11;
uint8_t unk12;
int8_t x_step;
uint8_t x_dist;
} type9;
struct {
uint8_t unkD;
} type10;
struct {
uint8_t unkD;
uint8_t unkE;
uint8_t unkF;
} type11;
struct {
uint8_t unkD;
} type12;
};
};