Import blues from 4bdd447a

This commit is contained in:
Gregory Montoir 2019-05-29 08:49:50 +08:00
parent cc17b87662
commit 1b97da5894
5 changed files with 211 additions and 56 deletions

View File

@ -42,9 +42,9 @@ struct monster_t {
int16_t x_velocity; // 0x8
int16_t y_velocity; // 0xA
const uint8_t *anim; // 0xC
uint8_t unkE; // 0xE
uint8_t unkF; // 0xF
uint8_t unk10;
uint8_t state; // 0xE
uint8_t energy; // 0xF
uint8_t unk10; // 0x10
};
struct thing_t {
@ -67,6 +67,7 @@ struct object_t {
uint8_t hit_counter; // 0x11
}; // sizeof == 18
#define MONSTERS_COUNT 12
#define OBJECTS_COUNT 108
// offset count
// 0 1 : club

View File

@ -1,4 +1,6 @@
/* level main loop */
#include "game.h"
#include "resource.h"
#include "sys.h"
@ -93,10 +95,12 @@ static void load_level_data_init_animated_tiles() {
}
static void load_level_data_init_transparent_tiles() {
const int tiles_offset = g_vars.tilemap_size + 512;
const int tiles_count = (g_res.levellen - tiles_offset) / 128;
int count = 1;
for (int i = 0; i < 256; ++i) {
for (int i = 0; i < tiles_count; ++i) {
const uint8_t num = i;
const uint8_t *tiledat = g_res.leveldat + g_vars.tilemap_size + 512 + num * 128;
const uint8_t *tiledat = g_res.leveldat + tiles_offset + num * 128;
uint8_t mask_opaque = 0xFF;
uint8_t mask_transparent = 0;
for (int j = 0; j < 128; ++j) {
@ -892,8 +896,8 @@ static void level_reset_objects() {
obj->spr_num = 0xFFFF;
obj->hit_counter = 0;
}
g_vars.objects_tbl[1].x_pos = g_res.level.start_x_pos;
g_vars.objects_tbl[1].y_pos = g_res.level.start_y_pos;
g_vars.objects_tbl[1].x_pos = (g_options.start_xpos16 < 0) ? g_res.level.start_x_pos : g_options.start_xpos16;
g_vars.objects_tbl[1].y_pos = (g_options.start_ypos16 < 0) ? g_res.level.start_y_pos : g_options.start_ypos16;
}
static void level_reset() {
@ -932,7 +936,7 @@ static uint16_t level_get_player_tile_pos() {
return (y << 8) | x;
}
static void level_add_object75_score(struct object_t *ref_obj, int num) {
static struct object_t *level_add_object75_score(struct object_t *ref_obj, int num) {
const int score_index = num - 74;
if (score_index >= 0 && score_index <= 16) {
g_vars.score += score_tbl[score_index];
@ -951,9 +955,10 @@ static void level_add_object75_score(struct object_t *ref_obj, int num) {
item->spr_num = 0xFFFF;
}
}
break;
return obj;
}
}
return 0;
}
static void level_update_object_anim(const uint8_t *anim) {
@ -1054,13 +1059,57 @@ static bool level_objects_collide(const struct object_t *si, const struct object
return (a + b > d);
}
static bool level_collide_axe_monsters(struct object_t *obj) {
for (int i = 0; i < 12; ++i) {
static void level_monster_die(struct object_t *obj, struct level_monster_t *m) {
const int num = m->unk8 + 74;
static const uint8_t data[] = { 1, 2, 3, 4, 6, 8 };
int count = data[obj->data.m.unk10 & 7];
const int x_pos = obj->x_pos;
const int y_pos = obj->y_pos;
do {
struct object_t *score_obj = level_add_object75_score(obj, num);
if (score_obj) {
score_obj->data.t.counter = count << 2;
}
obj->y_pos += 7;
obj->x_pos += 9;
} while (--count != 0);
obj->x_pos = x_pos;
obj->y_pos = y_pos;
obj->data.m.state = 0xFF;
if ((m->flags & 1) == 0) {
g_vars.current_bonus.x_pos = obj->x_pos;
g_vars.current_bonus.y_pos = obj->y_pos;
g_vars.current_bonus.spr_num = 0x2046;
level_add_object23_bonus(48, -128, 6);
} else {
}
}
static bool level_collide_axe_monsters(struct object_t *axe_obj) {
for (int i = 0; i < MONSTERS_COUNT; ++i) {
struct object_t *obj = &g_vars.objects_tbl[11 + i];
if (obj->spr_num == 0xFFFF) {
continue;
}
print_warning("Unhandled level_collide_axe_monsters object %d", 11 + i);
if (obj->data.m.state == 0xFF) {
continue;
}
struct level_monster_t *m = obj->data.m.ref;
if (m->flags & 0x10) {
continue;
}
if (!level_objects_collide(axe_obj, obj)) {
continue;
}
obj->data.m.unk5 |= 0x40;
if (obj->data.m.energy < g_vars.player_club_power) {
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;
return true;
}
return false;
}
@ -1235,12 +1284,16 @@ extern void monster_func1(int type, struct object_t *obj); /* update */
extern bool monster_func2(int type, struct level_monster_t *m); /* init */
static void level_update_objects_monsters() {
if (!g_res.dos_demo) {
/* different monsters logic/tables */
return;
}
if (g_res.level.monsters_state != 0xFF) {
level_update_monsters_state();
}
if (g_vars.level_num == 5 && (g_res.level.scrolling_mask & ~1) == 0) {
}
for (int i = 0; i < 12; ++i) {
for (int i = 0; i < MONSTERS_COUNT; ++i) {
struct object_t *obj = &g_vars.objects_tbl[11 + i];
if (obj->spr_num == 0xFFFF) {
continue;
@ -2213,7 +2266,7 @@ static void level_update_player_collision() {
struct object_t *obj_player = &g_vars.objects_tbl[1];
/* monsters */
if (g_vars.objects_tbl[1].hit_counter == 0) {
for (int i = 0; i < 12; ++i) {
for (int i = 0; i < MONSTERS_COUNT; ++i) {
struct object_t *obj = &g_vars.objects_tbl[11 + i];
if (obj->spr_num == 0xFFFF || (obj->spr_num & 0x2000) == 0) {
continue;
@ -2222,7 +2275,7 @@ static void level_update_player_collision() {
if (m->flags & 0x10) {
continue;
}
if (obj->data.m.unkE == 0xFF) {
if (obj->data.m.state == 0xFF) {
continue;
}
if (!level_objects_collide(obj_player, obj)) {
@ -2372,7 +2425,7 @@ static void level_update_player_collision() {
}
} else if (num == 169) {
play_sound(0);
for (int i = 0; i < 12; ++i) {
for (int i = 0; i < MONSTERS_COUNT; ++i) {
struct object_t *obj = &g_vars.objects_tbl[11 + i];
if (obj->spr_num == 0xFFFF) {
continue;
@ -2387,7 +2440,7 @@ static void level_update_player_collision() {
level_add_object75_score(obj, 230);
} else if (num == 170) { /* bomb */
play_sound(0);
for (int i = 0; i < 12; ++i) {
for (int i = 0; i < MONSTERS_COUNT; ++i) {
struct object_t *obj = &g_vars.objects_tbl[11 + i];
if (obj->spr_num == 0xFFFF) {
continue;
@ -2397,7 +2450,7 @@ static void level_update_player_collision() {
}
g_vars.current_bonus.x_pos = obj->x_pos;
g_vars.current_bonus.y_pos = obj->y_pos;
obj->data.m.unkE = 0xFF;
obj->data.m.state = 0xFF;
obj->spr_num = 0xFFFF;
int x_vel = 32;
int y_vel = -160;
@ -3054,6 +3107,7 @@ void do_level() {
set_level_palette();
video_load_sprites();
video_load_front_tiles();
video_clear();
level_reset();
level_reset_objects();
level_init_tilemap();

View File

@ -1,11 +1,13 @@
/* monsters logic */
#include "game.h"
#include "resource.h"
#include "util.h"
static void monster_func1_helper(struct object_t *obj, int16_t x_pos, int16_t y_pos) {
struct level_monster_t *m = obj->data.m.ref;
if (obj->data.m.unkE == 0xFF) {
if (obj->data.m.state == 0xFF) {
return;
}
if (obj->spr_num & 0x2000) {
@ -18,7 +20,7 @@ static void monster_func1_helper(struct object_t *obj, int16_t x_pos, int16_t y_
return;
}
}
if (obj->data.m.unkE < 10) {
if (obj->data.m.state < 10) {
obj->spr_num = 0xFFFF;
m->flags &= ~4;
m->current_tick = 0;
@ -65,7 +67,7 @@ static struct rotation_t *find_rotation() {
return 0;
}
static void monster_rotate_pos(struct level_monster_t *m, int index, int step) {
static void monster_rotate_platform(struct level_monster_t *m, int index, int step) {
step >>= 2;
uint8_t radius = step;
for (int i = 0; i < 3; ++i) {
@ -80,6 +82,12 @@ static void monster_rotate_pos(struct level_monster_t *m, int index, int step) {
}
}
static void monster_rotate_pos(struct object_t *obj, struct level_monster_t *m) {
obj->x_pos = m->x_pos + ((m->type4.unkD * (cos_tbl[m->type4.angle] >> 2)) >> 4);
obj->y_pos = m->y_pos + ((m->type4.unkD * (sin_tbl[m->type4.angle] >> 2)) >> 4);
monster_rotate_platform(m, m->type4.angle, m->type4.unkD);
}
static void monster_update_y_velocity(struct object_t *obj, struct level_monster_t *m) {
if ((m->flags & 1) != 0 && ((obj->spr_num & 0x2000) != 0 || g_vars.objects_tbl[1].y_pos >= obj->y_pos)) {
if (obj->data.m.y_velocity < 240) {
@ -98,27 +106,61 @@ static void monster_update_y_velocity(struct object_t *obj, struct level_monster
static void monster_func1_type2(struct object_t *obj) {
monster_func1_helper(obj, obj->x_pos, obj->y_pos);
struct level_monster_t *m = obj->data.m.ref;
uint8_t al = obj->data.m.unkE;
if (al < 2) {
monster_rotate_pos(m, 0, obj->y_pos - m->y_pos);
if (al == 0) {
const uint8_t state = obj->data.m.state;
if (state < 2) {
monster_rotate_platform(m, 0, obj->y_pos - m->y_pos);
if (state == 0) {
obj->data.m.y_velocity = m->type2.unkE << 4;
const int dy = obj->y_pos - m->y_pos;
if (m->type2.y_range >= dy) {
return;
}
obj->data.m.unkE = 1;
obj->data.m.state = 1;
monster_change_next_anim(obj);
} else if (al == 1) {
} else if (state == 1) {
obj->data.m.y_velocity = m->type2.unkE << 4;
const int dy = obj->y_pos - m->y_pos;
if (dy >= 0) {
return;
}
obj->data.m.unkE = 0;
obj->data.m.state = 0;
monster_change_prev_anim(obj);
}
} else if (al == 0xFF) {
} 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;
const uint8_t state = obj->data.m.state;
if (state == 0) {
if (monster_next_tick(m)) {
return;
}
const int dy = obj->y_pos - m->y_pos;
monster_rotate_platform(m, 0, dy);
if (m->type4.unkD > dy) {
obj->y_pos += 2;
} else {
obj->data.m.state = 1;
}
} else if (state == 1) {
monster_rotate_pos(obj, m);
m->type4.angle += 4;
if (m->type4.angle >= m->type4.unkE) {
m->type4.angle = m->type4.unkE;
obj->data.m.state = 2;
}
} else if (state == 2) {
if (m->type4.angle & 0x80) {
++m->type4.unk10;
} else {
--m->type4.unk10;
}
m->type4.angle = m->type4.unk10;
} else if (state == 0xFF) {
monster_update_y_velocity(obj, m);
}
}
@ -130,8 +172,8 @@ static void monster_func1_type8(struct object_t *obj) {
const int dx = (obj->x_pos <= g_vars.objects_tbl[1].x_pos) ? 1 : -1;
obj->data.m.x_velocity = dx;
}
uint8_t al = obj->data.m.unkE;
if ((al == 0 && !monster_next_tick(m)) || (al == 12 && !monster_next_tick(m))) {
const uint8_t state = obj->data.m.state;
if ((state == 0 && !monster_next_tick(m)) || (state == 12 && !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;
@ -146,40 +188,61 @@ static void monster_func1_type8(struct object_t *obj) {
x_vel = -x_vel;
}
obj->data.m.x_velocity = x_vel;
obj->data.m.unkE = 10;
obj->data.m.state = 10;
m->flags = (m->flags & ~0x2C) | 0x2C;
monster_change_next_anim(obj);
} else if (al == 10) {
} else if (state == 10) {
if (obj->data.m.y_velocity < 0) {
return;
}
obj->data.m.unkE = 11;
obj->data.m.state = 11;
monster_change_next_anim(obj);
} else if (al == 11) {
} else if (state == 11) {
if (obj->data.m.y_velocity > 0) {
return;
}
obj->data.m.unkE = 12;
obj->data.m.state = 12;
monster_change_prev_anim(obj);
monster_change_prev_anim(obj);
obj->data.m.x_velocity = 0;
m->current_tick = 0;
} else if (al == 0xFF) {
} else if (state == 0xFF) {
monster_update_y_velocity(obj, m);
}
}
static void monster_func1_type9(struct object_t *obj) {
struct level_monster_t *m = obj->data.m.ref;
if ((obj->spr_num & 0x2000) == 0 && obj->data.m.unkE != 0xFF) {
} else {
uint8_t al = obj->data.m.unkE;
if (al == 0) {
} else if (al == 1) {
} else if (al == 0xFF) {
monster_update_y_velocity(obj, m);
if ((obj->spr_num & 0x2000) == 0 && obj->data.m.state != 0xFF) {
const int dy = abs(obj->y_pos - g_vars.objects_tbl[1].y_pos);
if (dy >= 190 || (g_vars.objects_tbl[1].x_pos < m->type9.unkD && g_vars.objects_tbl[1].x_pos + 480 < m->type9.unkD) || (g_vars.objects_tbl[1].x_pos >= m->type9.unkD && m->type9.unkF + 480 <= g_vars.objects_tbl[1].x_pos)) {
obj->spr_num = 0xFFFF;
m->flags &= ~4;
return;
}
}
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;
}
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;
}
if (m->type9.unkD >= obj->x_pos) {
obj->data.m.state = 1;
}
} else if (state == 0xFF) {
monster_update_y_velocity(obj, m);
}
}
void monster_func1(int type, struct object_t *obj) {
@ -190,6 +253,9 @@ void monster_func1(int type, struct object_t *obj) {
case 2:
monster_func1_type2(obj);
break;
case 4:
monster_func1_type4(obj);
break;
case 8:
monster_func1_type8(obj);
break;
@ -203,7 +269,7 @@ void monster_func1(int type, struct object_t *obj) {
}
static struct object_t *find_object_monster() {
for (int i = 0; i < 12; ++i) {
for (int i = 0; i < MONSTERS_COUNT; ++i) {
struct object_t *obj = &g_vars.objects_tbl[11 + i];
if (obj->spr_num == 0xFFFF) {
return obj;
@ -224,8 +290,8 @@ static bool monster_init_object(struct level_monster_t *m) {
m->flags = 0x17;
obj->data.m.x_velocity = 0;
obj->data.m.y_velocity = 0;
obj->data.m.unkE = 0;
obj->data.m.unkF = m->unk5;
obj->data.m.state = 0;
obj->data.m.energy = m->energy;
return true;
}
return false;
@ -253,24 +319,22 @@ static bool monster_func2_type1(struct level_monster_t *m) {
}
static bool monster_func2_type2(struct level_monster_t *m) {
const int16_t x_pos = m->x_pos;
const int16_t y_pos = m->y_pos;
if (!monster_is_visible(x_pos, y_pos)) {
if (!monster_is_visible(m->x_pos, m->y_pos)) {
return false;
}
struct object_t *obj = find_object_monster();
if (obj) {
obj->data.m.unk10 = 0;
g_vars.monster.current_object = obj;
obj->x_pos = x_pos;
obj->y_pos = y_pos;
obj->x_pos = m->x_pos;
obj->y_pos = m->y_pos;
obj->spr_num = m->spr_num;
obj->data.m.ref = m;
m->flags = 5;
obj->data.m.y_velocity = 0;
obj->data.m.x_velocity = 0;
obj->data.m.unkE = 0;
obj->data.m.unkF = m->unk5;
obj->data.m.state = 0;
obj->data.m.energy = m->energy;
return true;
}
return false;
@ -315,6 +379,19 @@ static bool monster_func2_type10(struct level_monster_t *m) {
if (m->total_ticks > (m->current_tick >> 2)) {
return false;
}
const int dx = (g_vars.objects_tbl[1].x_pos >> 4) - m->x_pos;
if (dx < 0) {
return false;
}
const int dy = (g_vars.objects_tbl[1].y_pos >> 4) - m->y_pos;
if (dy < 0) {
return false;
}
struct object_t *obj = find_object_monster();
if (!obj) {
return false;
}
print_warning("monster_func2_type10 6579");
return true;
}

View File

@ -123,7 +123,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->unk5 = p[5];
m->energy = p[5];
m->total_ticks = p[6];
m->current_tick = p[7];
m->unk8 = p[8];
@ -133,12 +133,23 @@ void load_leveldat(const uint8_t *p, struct level_t *level) {
case 2:
m->type2.y_range = p[0xD];
m->type2.unkE = p[0xE];
case 4:
m->type4.unkD = p[0xD];
m->type4.unkE = p[0xE];
m->type4.angle = p[0xF];
m->type4.unk10 = p[0x10];
break;
case 8:
m->type8.x_range = p[0xD];
m->type8.unkE = p[0xE];
m->type8.unkF = p[0xF];
m->type8.y_range = p[0x10];
break;
case 9:
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];
default:
break;
}

View File

@ -63,7 +63,7 @@ struct level_monster_t {
uint8_t type;
uint16_t spr_num; // 0x2
uint8_t flags; // 0x4
uint8_t unk5;
uint8_t energy; // 0x5
uint8_t total_ticks;
uint8_t current_tick;
uint8_t unk8;
@ -74,12 +74,24 @@ struct level_monster_t {
uint8_t y_range; // 0xD
int8_t unkE; // 0xE, cbw
} type2;
struct {
uint8_t unkD;
uint8_t unkE;
uint8_t angle;
uint8_t unk10;
} type4;
struct {
uint8_t x_range; // 0xD
int8_t unkE; // 0xE, cbw
int8_t unkF; // 0xF, cbw
uint8_t y_range; // 0x10
} type8;
struct {
int16_t unkD; // 0xD
int16_t unkF; // 0xF
int8_t unk11; // 0x11
uint8_t unk12; // 0x12
} type9;
};
};