Import blues from 19d0f8b0

This commit is contained in:
Gregory Montoir 2019-06-01 21:44:23 +08:00
parent b7e5429ee0
commit 380a015ae8
7 changed files with 85 additions and 72 deletions

View File

@ -27,6 +27,6 @@ pre2: main.o sys_sdl2.o util.o $(P2_SRCS:.c=.o)
$(CC) $(LDFLAGS) -o $@ $^ $(SDL_LIBS) -lmodplug $(CC) $(LDFLAGS) -o $@ $^ $(SDL_LIBS) -lmodplug
clean: clean:
rm -f $(OBJS) $(DEPS) *.o rm -f $(OBJS) $(DEPS) *.o *.d
-include $(DEPS) -include $(DEPS)

View File

@ -4,8 +4,6 @@
#include "resource.h" #include "resource.h"
#include "sys.h" #include "sys.h"
static const bool _logos = false;
struct vars_t g_vars; struct vars_t g_vars;
void update_input() { 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 */ if (t->tm_year + 1900 < 1996) { /* || t->tm_year + 1900 >= 2067 */
return; return;
} }
memset(g_res.vga, 0, GAME_SCREEN_W * GAME_SCREEN_H);
g_sys.set_screen_palette(credits_palette_data, 0, 16, 6); g_sys.set_screen_palette(credits_palette_data, 0, 16, 6);
int offset = 0x960; int offset = 0x960;
video_draw_string(offset, 5, "YEAAA > > >"); video_draw_string(offset, 5, "YEAAA > > >");
@ -208,8 +207,8 @@ static void game_run(const char *data_path) {
sound_init(); sound_init();
video_convert_tiles(g_res.uniondat, g_res.unionlen); video_convert_tiles(g_res.uniondat, g_res.unionlen);
g_vars.level_num = g_options.start_level; 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(); do_titus_screen();
play_music(3); play_music(3);
do_present_screen(); do_present_screen();

View File

@ -43,8 +43,8 @@ struct monster_t {
int16_t y_velocity; int16_t y_velocity;
const uint8_t *anim; const uint8_t *anim;
uint8_t state; uint8_t state;
uint8_t energy; int8_t energy;
uint8_t unk10; /* score */ uint8_t hit_jump_counter;
}; };
struct thing_t { struct thing_t {
@ -178,7 +178,6 @@ struct vars_t {
uint16_t tilemap_size; /* tilemap size h*256 */ uint16_t tilemap_size; /* tilemap size h*256 */
uint16_t tilemap_start_x_pos, tilemap_start_y_pos; /* tilemap restart position */ 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 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_counter; /* animated tiles update counter */
uint8_t *level_animated_tiles_current_tbl; /* pointer to current tile_tbl */ uint8_t *level_animated_tiles_current_tbl; /* pointer to current tile_tbl */
uint8_t tile_tbl1[256]; /* animated tile state 1 */ uint8_t tile_tbl1[256]; /* animated tile state 1 */
@ -192,6 +191,7 @@ struct vars_t {
struct object_t *current_object; struct object_t *current_object;
uint8_t type10_dist; uint8_t type10_dist;
uint8_t hit_mask; uint8_t hit_mask;
int16_t collide_y_dist;
} monster; } monster;
struct { struct {
int16_t x_pos, y_pos; int16_t x_pos, y_pos;

View File

@ -70,7 +70,6 @@ static void load_level_data_init_animated_tiles() {
g_vars.tile_tbl3[i] = i; g_vars.tile_tbl3[i] = i;
g_vars.animated_tile_flag_tbl[i] = 0; g_vars.animated_tile_flag_tbl[i] = 0;
} else { } else {
g_vars.animated_tiles_flag = 1;
int j = i; int j = i;
g_vars.tile_tbl1[i] = j; g_vars.tile_tbl1[i] = j;
g_vars.tile_tbl2[i + 2] = 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() { 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; const uint8_t mask = (g_vars.snow.value >= 20) ? 1 : 3;
++g_vars.level_animated_tiles_counter; ++g_vars.level_animated_tiles_counter;
if ((g_vars.level_animated_tiles_counter & mask) == 0) { 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.tile_attr2_flags = 0;
g_vars.animated_tiles_flag = 0;
uint16_t offset = (g_vars.tilemap_y << 8) | g_vars.tilemap_x; 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 y = 0; y < (TILEMAP_SCREEN_H / 16) + 1; ++y) {
for (int x = 0; x < (TILEMAP_SCREEN_W / 16) + 1; ++x) { for (int x = 0; x < (TILEMAP_SCREEN_W / 16) + 1; ++x) {
const uint8_t tile_num = level_get_tile(offset + x); const uint8_t tile_num = level_get_tile(offset + x);
g_vars.tile_attr2_flags |= g_res.level.tile_attributes2[tile_num]; g_vars.tile_attr2_flags |= g_res.level.tile_attributes2[tile_num];
if (_redraw_tilemap || g_vars.animated_tile_flag_tbl[tile_num] != 0) { 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]; const uint8_t num = g_vars.level_animated_tiles_current_tbl[tile_num];
level_draw_tile(num, x, y); level_draw_tile(num, x, y);
} }
@ -561,6 +555,7 @@ static void level_init_tilemap() {
} }
g_vars.tilemap_redraw_flag2 = 1; g_vars.tilemap_redraw_flag2 = 1;
g_vars.tilemap_prev_x = _undefined; g_vars.tilemap_prev_x = _undefined;
g_vars.tilemap_prev_y = _undefined;
level_draw_tilemap(); level_draw_tilemap();
video_transition_open(); 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) { if (g_vars.player_using_club_flag == 0) {
d -= a; d -= a;
if (g_vars.objects_tbl[1].data.p.y_velocity >= 128 || (d <= (b >> 1) && si != &g_vars.objects_tbl[1])) { 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]; 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) { 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 }; 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 x_pos = obj->x_pos;
const int y_pos = obj->y_pos; const int y_pos = obj->y_pos;
do { do {
@ -1132,10 +1129,10 @@ static bool level_collide_axe_monsters(struct object_t *axe_obj) {
continue; continue;
} }
obj->data.m.unk5 |= 0x40; 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); level_monster_die(obj, m);
} else { } else {
obj->data.m.energy -= g_vars.player_club_power;
obj->x_pos -= obj->data.m.x_velocity >> 2; obj->x_pos -= obj->data.m.x_velocity >> 2;
} }
obj->spr_num = 0xFFFF; 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; x_vel = -x_vel;
} }
uint8_t al = level_get_tile(pos + x_vel - 0x100); 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 ((m->flags & 0x40) != 0 && (m->flags & 0x80) != 0) {
if (al != 0) { if (al != 0) {
obj->x_pos -= obj->data.m.x_velocity >> 4; 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; return;
} }
} }
const int dy = level_get_tile_monster_offset(dl, obj);
obj->y_pos &= ~15; obj->y_pos &= ~15;
obj->y_pos += level_get_tile_monster_offset(dl, obj); obj->y_pos += dy;
if ((m->flags & 0x20) == 0) { if ((m->flags & 0x20) == 0) {
int dy = (-obj->data.m.y_velocity) >> 1; int y_vel = (-obj->data.m.y_velocity) >> 1;
if (abs(dy) <= 32) { if (abs(y_vel) <= 32) {
dy = 0; 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; const int prev_spr_num = g_vars.objects_tbl[1].spr_num;
g_vars.objects_tbl[1].spr_num = 7; g_vars.objects_tbl[1].spr_num = 7;
if (!level_objects_collide(&g_vars.objects_tbl[1], obj)) { const bool ret = level_objects_collide(&g_vars.objects_tbl[1], obj);
return false;
}
g_vars.objects_tbl[1].y_pos = prev_y_pos; g_vars.objects_tbl[1].y_pos = prev_y_pos;
g_vars.objects_tbl[1].spr_num = prev_spr_num; g_vars.objects_tbl[1].spr_num = prev_spr_num;
if (!ret) {
return false;
}
g_vars.level_force_x_scroll_flag = 1; g_vars.level_force_x_scroll_flag = 1;
g_vars.objects_tbl[1].x_friction = 0; g_vars.objects_tbl[1].x_friction = 0;
g_vars.objects_tbl[1].x_pos += g_vars.level_current_object_decor_x_pos; 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; return;
} }
if (g_vars.player_gravity_flag == 0) { if (!g_vars.player_gravity_flag) {
int num = obj->data.m.unk10 >> 2; /* jumping on a monster */
int num = obj->data.m.hit_jump_counter >> 2;
if (num != 11) { if (num != 11) {
obj->data.m.unk10 += 4; obj->data.m.hit_jump_counter += 4;
++num; ++num;
if ((num & 1) == 0) { if ((num & 1) == 0) {
static const uint16_t data[] = { 0xFF46, 0xE0, 0xE1, 0x12D, 0x12E, 0x12F }; static const uint16_t data[] = { 0xFF46, 0xE0, 0xE1, 0x12D, 0x12E, 0x12F };
level_add_object75_score(obj_player, (int16_t)data[num >> 1]);
level_add_object75_score(obj_player, data[num >> 1]);
} }
} }
g_vars.objects_tbl[1].data.p.y_velocity = (g_vars.input.key_up != 0) ? -224 : -64; 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.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) { } else if (g_vars.objects_tbl[1].data.p.y_velocity <= 32) {
g_vars.objects_tbl[1].data.p.y_velocity = -96; g_vars.objects_tbl[1].data.p.y_velocity = -96;
g_vars.player_jumping_counter = 0; g_vars.player_jumping_counter = 0;
g_vars.objects_tbl[1].y_pos -= g_vars.monster.collide_y_dist;
} else { } 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)); level_add_object75_score(obj_player, 82 + (num << 1));
obj->spr_num |= 0x4000; obj->spr_num |= 0x4000;
if (num == 2) { if (num == 2) {
@ -2449,9 +2450,10 @@ static void level_update_player_collision() {
} }
obj->data.m.x_velocity = delta * 3; obj->data.m.x_velocity = delta * 3;
} else { } else {
++obj->data.m.unk10; ++obj->data.m.hit_jump_counter;
g_vars.objects_tbl[1].data.p.y_velocity = -96; g_vars.objects_tbl[1].data.p.y_velocity = -96;
g_vars.player_jumping_counter = 0; g_vars.player_jumping_counter = 0;
g_vars.objects_tbl[1].y_pos -= g_vars.monster.collide_y_dist;
} }
} }
return; return;
@ -3136,31 +3138,33 @@ static void level_completed_bonuses_animation() {
g_vars.objects_tbl[1].data.p.anim = object_anim_tbl[1]; g_vars.objects_tbl[1].data.p.anim = object_anim_tbl[1];
while (1) { while (1) {
level_update_object_anim(g_vars.objects_tbl[1].data.p.anim); level_update_object_anim(g_vars.objects_tbl[1].data.p.anim);
int _bx, _ax, flag = 0;
bool flag = false;
int x_pos = 60; int x_pos = 60;
_bx = 2; int x_offs = 2;
_ax = g_vars.objects_tbl[1].x_pos - x_pos; const int dx = g_vars.objects_tbl[1].x_pos - x_pos;
if (_ax < 0) { if (dx < 0) {
_bx = -_bx; x_offs = -x_offs;
} }
if (_ax >= 2) { if (dx >= 2) {
x_pos = g_vars.objects_tbl[1].x_pos - _bx; x_pos = g_vars.objects_tbl[1].x_pos - x_offs;
++flag; flag = true;
} }
g_vars.objects_tbl[1].x_pos = x_pos; g_vars.objects_tbl[1].x_pos = x_pos;
int y_pos = 175; int y_pos = 175;
_bx = 2; int y_offs = 2;
_ax = g_vars.objects_tbl[1].y_pos - y_pos; const int dy = g_vars.objects_tbl[1].y_pos - y_pos;
if (_ax < 0) { if (dy < 0) {
_bx = -_bx; y_offs = -y_offs;
} }
if (_ax >= 2) { if (dy >= 2) {
y_pos = g_vars.objects_tbl[1].y_pos - _bx; y_pos = g_vars.objects_tbl[1].y_pos - y_offs;
++flag; flag = true;
} }
g_vars.objects_tbl[1].y_pos = y_pos; g_vars.objects_tbl[1].y_pos = y_pos;
video_clear(); video_clear();
level_completed_bonuses_animation_draw_score(); level_completed_bonuses_animation_draw_score();
level_draw_objects(); level_draw_objects();

View File

@ -23,9 +23,9 @@ static void monster_func1_helper(struct object_t *obj, int16_t x_pos, int16_t y_
return; return;
} }
const int dx = abs(x_pos - g_vars.objects_tbl[1].x_pos); 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); const int dy = abs(y_pos - g_vars.objects_tbl[1].y_pos);
if (dy <= 300) { if (dy <= TILEMAP_SCREEN_H + (300 - 176)) {
return; 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) { static void monster_func1_type8(struct object_t *obj) {
monster_func1_helper(obj, obj->x_pos, obj->y_pos); monster_func1_helper(obj, obj->x_pos, obj->y_pos);
struct level_monster_t *m = obj->data.m.ref; 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; const int dx = (obj->x_pos <= g_vars.objects_tbl[1].x_pos) ? 1 : -1;
obj->data.m.x_velocity = dx; obj->data.m.x_velocity = dx;
} }
const uint8_t state = obj->data.m.state; 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); const int dx = abs(g_vars.objects_tbl[1].x_pos - obj->x_pos);
if (m->type8.x_range < (dx >> 4)) { if (m->type8.x_range < (dx >> 4)) {
return; return;
@ -182,15 +194,7 @@ static void monster_func1_type8(struct object_t *obj) {
if (m->type8.y_range < (dy >> 4)) { if (m->type8.y_range < (dy >> 4)) {
return; return;
} }
obj->data.m.y_velocity = -(m->type8.unkE << 4); monster_func1_type8_helper(obj, m);
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);
} else if (state == 10) { } else if (state == 10) {
if (obj->data.m.y_velocity < 0) { if (obj->data.m.y_velocity < 0) {
return; return;
@ -206,6 +210,8 @@ static void monster_func1_type8(struct object_t *obj) {
monster_change_prev_anim(obj); monster_change_prev_anim(obj);
obj->data.m.x_velocity = 0; obj->data.m.x_velocity = 0;
m->current_tick = 0; m->current_tick = 0;
} else if (state == 12 && !monster_next_tick(m)) {
monster_func1_type8_helper(obj, m);
} else if (state == 0xFF) { } else if (state == 0xFF) {
monster_update_y_velocity(obj, m); 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) { static bool monster_init_object(struct level_monster_t *m) {
struct object_t *obj = find_object_monster(); struct object_t *obj = find_object_monster();
if (obj) { if (obj) {
obj->data.m.unk10 = 0; obj->data.m.hit_jump_counter = 0;
g_vars.monster.current_object = obj; g_vars.monster.current_object = obj;
obj->x_pos = m->x_pos; obj->x_pos = m->x_pos;
obj->y_pos = m->y_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(); struct object_t *obj = find_object_monster();
if (obj) { if (obj) {
obj->data.m.unk10 = 0; obj->data.m.hit_jump_counter = 0;
g_vars.monster.current_object = obj; g_vars.monster.current_object = obj;
obj->x_pos = m->x_pos; obj->x_pos = m->x_pos;
obj->y_pos = m->y_pos; obj->y_pos = m->y_pos;
@ -461,7 +467,7 @@ static bool monster_func2_type10(struct level_monster_t *m) {
if (!obj) { if (!obj) {
return false; return false;
} }
obj->data.m.unk10 = 0; obj->data.m.hit_jump_counter = 0;
g_vars.monster.current_object = obj; g_vars.monster.current_object = obj;
static const int16_t dist_tbl[] = { 120, 100, -90, 110, -120, 40, 80, 60 }; 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]; obj->x_pos = g_vars.objects_tbl[1].x_pos + dist_tbl[g_vars.monster.type10_dist & 7];

View File

@ -126,10 +126,13 @@ void load_leveldat(const uint8_t *p, struct level_t *level) {
m->energy = p[5]; m->energy = p[5];
m->total_ticks = p[6]; m->total_ticks = p[6];
m->current_tick = p[7]; m->current_tick = p[7];
m->unk8 = p[8]; m->score = p[8];
m->x_pos = READ_LE_UINT16(p + 0x9); m->x_pos = READ_LE_UINT16(p + 0x9);
m->y_pos = READ_LE_UINT16(p + 0xB); m->y_pos = READ_LE_UINT16(p + 0xB);
switch (type) { switch (type) { /* movement */
case 1:
assert(len == 13);
break;
case 2: /* vertical (eg. spider) */ case 2: /* vertical (eg. spider) */
assert(len == 15); assert(len == 15);
m->type2.y_range = p[0xD]; 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) */ case 8: /* jumps (eg. leopard) */
assert(len == 17); assert(len == 17);
m->type8.x_range = p[0xD]; m->type8.x_range = p[0xD];
m->type8.unkE = p[0xE]; m->type8.y_step = p[0xE];
m->type8.unkF = p[0xF]; m->type8.x_step = p[0xF];
m->type8.y_range = p[0x10]; m->type8.y_range = p[0x10];
break; break;
case 9: /* horizontal */ case 9: /* horizontal */
@ -161,6 +164,7 @@ void load_leveldat(const uint8_t *p, struct level_t *level) {
m->type10.unkD = p[0xD]; m->type10.unkD = p[0xD];
break; break;
default: default:
print_warning("Unhandled monster type %d len %d", type, len);
break; break;
} }
p += len; p += len;

View File

@ -66,7 +66,7 @@ struct level_monster_t {
uint8_t energy; uint8_t energy;
uint8_t total_ticks; uint8_t total_ticks;
uint8_t current_tick; uint8_t current_tick;
uint8_t unk8; uint8_t score;
uint16_t x_pos; uint16_t x_pos;
uint16_t y_pos; uint16_t y_pos;
union { union {
@ -82,8 +82,8 @@ struct level_monster_t {
} type4; } type4;
struct { struct {
uint8_t x_range; uint8_t x_range;
int8_t unkE; int8_t y_step;
int8_t unkF; int8_t x_step;
uint8_t y_range; uint8_t y_range;
} type8; } type8;
struct { struct {