Import blues from fc8bfa4b
This commit is contained in:
parent
1b97da5894
commit
b7e5429ee0
|
@ -5,13 +5,13 @@ This is a rewrite of the [Blues Brothers](https://www.mobygames.com/game/blues-b
|
|||
|
||||
![Screenshot1](blues1.png) ![Screenshot2](bbja2.png)
|
||||
|
||||
There is also early support for [Prehistork 2](https://www.mobygames.com/game/prehistorik-2).
|
||||
There is also early support for [Prehistorik 2](https://www.mobygames.com/game/prehistorik-2).
|
||||
|
||||
## Requirements
|
||||
|
||||
### Blues Brothers
|
||||
|
||||
The game data files of the DOS or Amiga version are required.
|
||||
The data files of the Amiga or DOS version, full game or [demo](https://archive.org/details/TheBluesBrothers_1020), are required.
|
||||
|
||||
```
|
||||
*.BIN, *.CK1, *.CK2, *.SQL, *.SQV, *.SQZ
|
||||
|
@ -21,7 +21,7 @@ For sounds and music, the Amiga version files or the [ExoticA](https://www.exoti
|
|||
|
||||
### Jukebox Adventure
|
||||
|
||||
The game data files of the DOS version are required.
|
||||
The data files of the DOS version are required.
|
||||
|
||||
```
|
||||
*.EAT, *.MOD
|
||||
|
@ -29,7 +29,7 @@ The game data files of the DOS version are required.
|
|||
|
||||
### Prehistorik 2
|
||||
|
||||
The game data files of the DOS version are required.
|
||||
The data files of the DOS version, full game or [demo](http://cd.textfiles.com/ccbcurrsh1/demos/pre2.zip), are required.
|
||||
|
||||
```
|
||||
*.SQZ, *.TRK
|
||||
|
|
16
bb/game.h
16
bb/game.h
|
@ -87,16 +87,16 @@ struct object_t {
|
|||
int16_t unk2E;
|
||||
int8_t unk2F;
|
||||
uint8_t op;
|
||||
uint8_t grab_state; // 1:carry_crate
|
||||
uint8_t grab_state; /* 1:carry_crate */
|
||||
uint8_t grab_type;
|
||||
uint8_t special_anim; // 2:flying
|
||||
uint8_t special_anim; /* 2:flying */
|
||||
// uint8_t unk35;
|
||||
int16_t player_xdist;
|
||||
int16_t player_ydist;
|
||||
uint8_t sprite3_counter;
|
||||
uint8_t visible_flag;
|
||||
uint8_t moving_direction; // 0:right 1:left
|
||||
uint8_t unk3D; // 1:umbrella 2:balloon
|
||||
uint8_t moving_direction; /* 0:right 1:left */
|
||||
uint8_t unk3D; /* 1:umbrella 2:balloon */
|
||||
uint8_t carry_crate_flag;
|
||||
// int16_t unk3F;
|
||||
// uint8_t unk41;
|
||||
|
@ -105,12 +105,12 @@ struct object_t {
|
|||
uint8_t tile1_flags;
|
||||
uint8_t tile2_flags;
|
||||
int16_t tile012_xpos;
|
||||
int8_t elevator_direction; // -1,1
|
||||
int8_t elevator_direction; /* -1,1 */
|
||||
const uint8_t *trigger3;
|
||||
uint8_t trigger3_num;
|
||||
// int16_t unk4E;
|
||||
int16_t unk50;
|
||||
uint8_t data51; // health for obj39/40, horizontal direction for other objects
|
||||
uint8_t data51; /* health for obj39/40, horizontal direction for other objects */
|
||||
uint8_t scrolling_lock_flag;
|
||||
uint8_t unk54;
|
||||
uint8_t unk55;
|
||||
|
@ -121,10 +121,10 @@ struct object_t {
|
|||
// uint8_t unk5C; // never read
|
||||
uint8_t unk5D;
|
||||
uint8_t blinking_counter;
|
||||
uint8_t data5F; // music instrument number for obj39/40, counter for other objects
|
||||
uint8_t data5F; /* music instrument number for obj39/40, counter for other objects */
|
||||
uint8_t unk60;
|
||||
uint8_t lifes_count;
|
||||
uint8_t level_complete_flag; // set if music instrument was found
|
||||
uint8_t level_complete_flag; /* set if music instrument was found */
|
||||
uint8_t restart_level_flag;
|
||||
};
|
||||
|
||||
|
|
54
ja/game.h
54
ja/game.h
|
@ -18,17 +18,17 @@ extern struct options_t g_options;
|
|||
#define PANEL_H 24
|
||||
|
||||
#define SOUND_0 0
|
||||
#define SOUND_1 1 // monster knocked out
|
||||
#define SOUND_2 2 // bouncing mushroom
|
||||
#define SOUND_3 3 // decor hit
|
||||
#define SOUND_4 4 // player hit
|
||||
#define SOUND_5 5 // grab vinyl
|
||||
#define SOUND_8 8 // no vinyl
|
||||
#define SOUND_9 9 // throw vinyl
|
||||
#define SOUND_10 10 // "rock,rock,rock and roll"
|
||||
#define SOUND_1 1 /* monster knocked out */
|
||||
#define SOUND_2 2 /* bouncing mushroom */
|
||||
#define SOUND_3 3 /* decor hit */
|
||||
#define SOUND_4 4 /* player hit */
|
||||
#define SOUND_5 5 /* grab vinyl */
|
||||
#define SOUND_8 8 /* no vinyl */
|
||||
#define SOUND_9 9 /* throw vinyl */
|
||||
#define SOUND_10 10 /* "rock,rock,rock and roll" */
|
||||
#define SOUND_11 11
|
||||
#define SOUND_14 14 // player lost life
|
||||
#define SOUND_15 15 // running out time
|
||||
#define SOUND_14 14 /* player lost life */
|
||||
#define SOUND_15 15 /* running out time */
|
||||
|
||||
struct object_t {
|
||||
int16_t x_pos;
|
||||
|
@ -66,20 +66,20 @@ enum {
|
|||
|
||||
#define object_blinking_counter(obj) (obj)->data[6].b[1] // 0x13, shield, jump
|
||||
|
||||
// star
|
||||
/* star */
|
||||
#define object2_spr_count(obj) (obj)->data[0].b[0]
|
||||
#define object2_spr_tick(obj) (obj)->data[0].b[1]
|
||||
|
||||
// vinyl
|
||||
/* vinyl */
|
||||
#define object22_xvelocity(obj) (obj)->data[0].w
|
||||
#define object22_damage(obj) (obj)->data[1].w
|
||||
#define object22_player_num(obj) (obj)->data[2].w
|
||||
|
||||
// crate
|
||||
/* crate */
|
||||
#define object64_counter(obj) (obj)->data[1].w
|
||||
#define object64_yvelocity(obj) (obj)->data[2].w
|
||||
|
||||
// monster
|
||||
/* monster */
|
||||
#define object82_state(obj) (obj)->data[0].b[0]
|
||||
#define object82_type(obj) (obj)->data[0].b[1]
|
||||
#define object82_anim_data(obj) (obj)->data[1].p
|
||||
|
@ -111,16 +111,18 @@ struct player_t {
|
|||
#define TRIGGERS_COUNT 36
|
||||
#define LEVELS_COUNT 30
|
||||
#define OBJECTS_COUNT 165
|
||||
// offset | count | comment
|
||||
// 2 20 animated tiles/vinyls
|
||||
// 22 10 vinyls
|
||||
// 32 8 * 4 (rotating) platforms
|
||||
// 64 8 crates
|
||||
// 72 10 bonuses spr_num:190
|
||||
// 82 20 monsters
|
||||
// 102 10
|
||||
// 112 9 vertical bars
|
||||
// 121 8 dragon monster (level 26)
|
||||
/*
|
||||
offset count
|
||||
2 20 : animated tiles/vinyls
|
||||
22 10 : vinyls
|
||||
32 8*4 : (rotating) platforms
|
||||
64 8 : crates
|
||||
72 10 : bonuses spr_num:190
|
||||
82 20 : monsters
|
||||
102 10
|
||||
112 9 : vertical bars
|
||||
121 8 : dragon monster (level 26)
|
||||
*/
|
||||
|
||||
struct vars_t {
|
||||
int level;
|
||||
|
@ -128,7 +130,7 @@ struct vars_t {
|
|||
bool input_keystate[128];
|
||||
uint32_t timestamp;
|
||||
uint8_t input_key_left, input_key_right, input_key_down, input_key_up, input_key_space;
|
||||
uint16_t buffer[128 * 2]; // level objects state 0xFFFF, 0xFF20 or g_vars.objects_table index
|
||||
uint16_t buffer[128 * 2]; /* level objects state 0xFFFF, 0xFF20 or g_vars.objects_table index */
|
||||
int16_t dragon_coords[1 + 128];
|
||||
struct player_t players_table[2];
|
||||
int16_t player_xscroll, player_map_offset;
|
||||
|
@ -147,7 +149,7 @@ struct vars_t {
|
|||
uint8_t *tilemap_data;
|
||||
uint16_t level_pos_num;
|
||||
uint8_t tilemap_type, tilemap_flags;
|
||||
uint8_t tilemap_lut_type[0x100]; // type:0,1,2
|
||||
uint8_t tilemap_lut_type[0x100]; /* type:0,1,2 */
|
||||
uint8_t tilemap_lut_init[6 * 0x100];
|
||||
uint8_t tilemap_lut_init2[0x100];
|
||||
const uint8_t *tilemap_current_lut;
|
||||
|
|
23
p2/game.c
23
p2/game.c
|
@ -78,11 +78,28 @@ static void do_credits() {
|
|||
g_sys.update_screen(g_res.vga, 1);
|
||||
}
|
||||
|
||||
static void update_screen_img(const uint8_t *src) {
|
||||
const int size = GAME_SCREEN_W * GAME_SCREEN_H;
|
||||
if (size < 64000) {
|
||||
return;
|
||||
} else if (size == 64000) {
|
||||
g_sys.update_screen(src, 0);
|
||||
} else {
|
||||
memset(g_res.vga, 0, size);
|
||||
const int y_offs = (GAME_SCREEN_H - 200) / 2;
|
||||
const int x_offs = (GAME_SCREEN_W - 320) / 2;
|
||||
for (int y = 0; y < 200; ++y) {
|
||||
memcpy(g_res.vga + (y_offs + y) * GAME_SCREEN_W + x_offs, src + y * 320, 320);
|
||||
}
|
||||
g_sys.update_screen(g_res.vga, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_titus_screen() {
|
||||
uint8_t *data = load_file("TITUS.SQZ");
|
||||
if (data) {
|
||||
g_sys.set_screen_palette(data, 0, 256, 6);
|
||||
g_sys.update_screen(data + 768, 0);
|
||||
update_screen_img(data + 768);
|
||||
fade_in_palette();
|
||||
wait_input(70);
|
||||
fade_out_palette();
|
||||
|
@ -94,7 +111,7 @@ static void do_present_screen() {
|
|||
uint8_t *data = load_file("PRESENT.SQZ");
|
||||
if (data) {
|
||||
g_sys.set_screen_palette(data, 0, 256, 6);
|
||||
g_sys.update_screen(data + 768, 0);
|
||||
update_screen_img(data + 768);
|
||||
fade_in_palette();
|
||||
free(data);
|
||||
}
|
||||
|
@ -112,7 +129,7 @@ static void do_menu() {
|
|||
uint8_t *data = load_file("MENU.SQZ");
|
||||
if (data) {
|
||||
g_sys.set_screen_palette(data, 0, 256, 6);
|
||||
g_sys.update_screen(data + 768, 0);
|
||||
update_screen_img(data + 768);
|
||||
fade_in_palette();
|
||||
free(data);
|
||||
memset(g_vars.input.keystate, 0, sizeof(g_vars.input.keystate));
|
||||
|
|
74
p2/game.h
74
p2/game.h
|
@ -24,33 +24,33 @@ struct club_anim_t {
|
|||
};
|
||||
|
||||
struct player_t {
|
||||
int16_t hdir; /* left:-1 right:1 */ // 0x9
|
||||
uint8_t current_anim_num; // 0xB
|
||||
const uint8_t *anim; // 0xC
|
||||
int16_t y_velocity; // 0xE
|
||||
uint8_t special_anim_num; /* idle, exhausted */ // 0x10
|
||||
int16_t hdir; /* left:-1 right:1 */
|
||||
uint8_t current_anim_num;
|
||||
const uint8_t *anim;
|
||||
int16_t y_velocity;
|
||||
uint8_t special_anim_num; /* idle, exhausted */
|
||||
};
|
||||
|
||||
struct club_projectile_t {
|
||||
const uint8_t *anim; // 0xC
|
||||
int16_t y_velocity; // 0xE
|
||||
const uint8_t *anim;
|
||||
int16_t y_velocity;
|
||||
};
|
||||
|
||||
struct monster_t {
|
||||
uint8_t unk5;
|
||||
void *ref; // 0x6
|
||||
int16_t x_velocity; // 0x8
|
||||
int16_t y_velocity; // 0xA
|
||||
const uint8_t *anim; // 0xC
|
||||
uint8_t state; // 0xE
|
||||
uint8_t energy; // 0xF
|
||||
uint8_t unk10; // 0x10
|
||||
void *ref;
|
||||
int16_t x_velocity;
|
||||
int16_t y_velocity;
|
||||
const uint8_t *anim;
|
||||
uint8_t state;
|
||||
uint8_t energy;
|
||||
uint8_t unk10; /* score */
|
||||
};
|
||||
|
||||
struct thing_t {
|
||||
void *ref; // 0x9
|
||||
int16_t counter; // 0xC
|
||||
int16_t unkE; // 0xE
|
||||
void *ref;
|
||||
int16_t counter;
|
||||
int16_t unkE;
|
||||
};
|
||||
|
||||
struct object_t {
|
||||
|
@ -58,34 +58,36 @@ struct object_t {
|
|||
uint16_t spr_num;
|
||||
int16_t x_velocity;
|
||||
uint8_t x_friction;
|
||||
union { // 0x9 - 0x10
|
||||
union {
|
||||
struct player_t p; /* objects[1] */
|
||||
struct club_projectile_t c; /* objects[2..5] */
|
||||
struct monster_t m; /* objects[11..22] */
|
||||
struct thing_t t;
|
||||
} data;
|
||||
uint8_t hit_counter; // 0x11
|
||||
}; // sizeof == 18
|
||||
uint8_t hit_counter;
|
||||
};
|
||||
|
||||
#define MONSTERS_COUNT 12
|
||||
#define OBJECTS_COUNT 108
|
||||
// offset count
|
||||
// 0 1 : club
|
||||
// 1 1 : player
|
||||
// 2 4 : axe
|
||||
// 6 5 : club hitting decor frames
|
||||
// 11 12 : monsters
|
||||
// 23 32 : secret bonuses
|
||||
// 55 20 : items
|
||||
// 75 16 : bonus scores
|
||||
// 91 7 : decor
|
||||
/*
|
||||
offset count
|
||||
0 1 : club
|
||||
1 1 : player
|
||||
2 4 : axe
|
||||
6 5 : club hitting decor frames
|
||||
11 12 : monsters
|
||||
23 32 : secret bonuses
|
||||
55 20 : items
|
||||
75 16 : bonus scores
|
||||
91 7 : decor
|
||||
*/
|
||||
|
||||
struct rotation_t {
|
||||
uint16_t x_pos;
|
||||
uint16_t y_pos;
|
||||
uint8_t index_tbl; /* cos_/sin_tbl */
|
||||
uint8_t radius;
|
||||
}; // sizeof == 6
|
||||
};
|
||||
|
||||
struct collision_t {
|
||||
uint16_t x_pos;
|
||||
|
@ -94,7 +96,7 @@ struct collision_t {
|
|||
uint8_t unk5;
|
||||
uint8_t unk6;
|
||||
uint8_t unk7;
|
||||
}; // sizeof == 8
|
||||
};
|
||||
|
||||
struct vars_t {
|
||||
uint32_t starttime;
|
||||
|
@ -140,6 +142,8 @@ struct vars_t {
|
|||
uint8_t player_nojump_counter;
|
||||
uint8_t player_jumping_counter;
|
||||
uint8_t player_action_counter;
|
||||
int16_t player_hit_monster_counter;
|
||||
uint8_t player_jump_monster_flag;
|
||||
uint8_t player_club_type;
|
||||
uint8_t player_club_power;
|
||||
uint8_t player_club_powerup_duration;
|
||||
|
@ -186,6 +190,8 @@ struct vars_t {
|
|||
|
||||
struct {
|
||||
struct object_t *current_object;
|
||||
uint8_t type10_dist;
|
||||
uint8_t hit_mask;
|
||||
} monster;
|
||||
struct {
|
||||
int16_t x_pos, y_pos;
|
||||
|
@ -243,6 +249,10 @@ extern void game_main();
|
|||
/* level.c */
|
||||
extern void do_level();
|
||||
|
||||
/* monsters.c */
|
||||
extern void monster_change_next_anim(struct object_t *obj);
|
||||
extern void monster_change_prev_anim(struct object_t *obj);
|
||||
|
||||
/* screen.c */
|
||||
extern void video_draw_string(int offset, int hspace, const char *s);
|
||||
extern void video_clear();
|
||||
|
|
188
p2/level.c
188
p2/level.c
|
@ -258,7 +258,16 @@ static void level_update_tilemap() {
|
|||
return;
|
||||
}
|
||||
}
|
||||
memcpy(g_res.vga, g_res.background, 320 * 200);
|
||||
if (GAME_SCREEN_W * GAME_SCREEN_H == 64000) {
|
||||
memcpy(g_res.vga, g_res.background, 320 * 200);
|
||||
} else {
|
||||
memset(g_res.vga, 0, GAME_SCREEN_W * GAME_SCREEN_H);
|
||||
for (int y = 0; y < MIN(200, GAME_SCREEN_H); ++y) {
|
||||
for (int x = 0; x < GAME_SCREEN_W; x += 320) {
|
||||
memcpy(g_res.vga + y * GAME_SCREEN_W + x, g_res.background + y * 320, MIN(320, GAME_SCREEN_W - x));
|
||||
}
|
||||
}
|
||||
}
|
||||
g_vars.tile_attr2_flags = 0;
|
||||
g_vars.animated_tiles_flag = 0;
|
||||
uint16_t offset = (g_vars.tilemap_y << 8) | g_vars.tilemap_x;
|
||||
|
@ -896,8 +905,8 @@ static void level_reset_objects() {
|
|||
obj->spr_num = 0xFFFF;
|
||||
obj->hit_counter = 0;
|
||||
}
|
||||
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;
|
||||
g_vars.objects_tbl[1].x_pos = (g_options.start_xpos16 < 0) ? g_res.level.start_x_pos : (g_options.start_xpos16 << 4);
|
||||
g_vars.objects_tbl[1].y_pos = (g_options.start_ypos16 < 0) ? g_res.level.start_y_pos : (g_options.start_ypos16 << 4);
|
||||
}
|
||||
|
||||
static void level_reset() {
|
||||
|
@ -1059,6 +1068,14 @@ static bool level_objects_collide(const struct object_t *si, const struct object
|
|||
return (a + b > d);
|
||||
}
|
||||
|
||||
static void level_monster_update_anim(struct object_t *obj) {
|
||||
const uint8_t *p = obj->data.m.anim;
|
||||
do {
|
||||
p += 2;
|
||||
} while (READ_LE_UINT16(p) != 0x7D00);
|
||||
obj->data.m.anim = p + 2;
|
||||
}
|
||||
|
||||
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 };
|
||||
|
@ -1082,6 +1099,19 @@ static void level_monster_die(struct object_t *obj, struct level_monster_t *m) {
|
|||
g_vars.current_bonus.spr_num = 0x2046;
|
||||
level_add_object23_bonus(48, -128, 6);
|
||||
} else {
|
||||
level_monster_update_anim(obj);
|
||||
uint8_t al = m->flags & ~0x37;
|
||||
if (al != 0x88) {
|
||||
m->flags &= ~8;
|
||||
}
|
||||
int dy = MIN(g_vars.player_club_power, 25);
|
||||
dy = (-dy) << 3;
|
||||
obj->data.m.y_velocity = dy;
|
||||
int dx = dy >> 1;
|
||||
if ((obj->data.m.unk5 & 0x80) == 0) {
|
||||
dx = -dx;
|
||||
}
|
||||
obj->data.m.x_velocity = dx;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1280,6 +1310,76 @@ static void level_update_objects_axe() {
|
|||
static void level_update_monsters_state() {
|
||||
}
|
||||
|
||||
static int level_get_tile_monster_offset(uint8_t tile_num, struct object_t *obj) {
|
||||
const uint8_t attr = g_res.level.tile_attributes1[tile_num];
|
||||
if ((attr & 0x30) == 0) {
|
||||
return attr;
|
||||
}
|
||||
int x = (obj->x_pos & 15) / 3;
|
||||
if (attr & 0x10) {
|
||||
x = (attr & 15) + x;
|
||||
} else {
|
||||
x = (attr & 15) - x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static void level_update_monster_pos(struct object_t *obj, struct level_monster_t *m) {
|
||||
const uint16_t pos = ((obj->y_pos >> 4) << 8) | (obj->x_pos >> 4);
|
||||
uint8_t dl = level_get_tile(pos);
|
||||
uint8_t dh = level_get_tile(pos - 0x100);
|
||||
int x_vel = obj->data.m.x_velocity;
|
||||
if (x_vel != 0 && x_vel <= 1) {
|
||||
x_vel = -x_vel;
|
||||
}
|
||||
uint8_t al = level_get_tile(pos + x_vel - 0x100);
|
||||
al = g_res.level.tile_attributes1[al];
|
||||
if ((m->flags & 0x40) != 0 && (m->flags & 0x80) != 0) {
|
||||
if (al != 0) {
|
||||
obj->x_pos -= obj->data.m.x_velocity >> 4;
|
||||
} else {
|
||||
monster_change_prev_anim(obj);
|
||||
obj->data.m.y_velocity = 0;
|
||||
m->flags &= ~0x80;
|
||||
obj->y_pos -= 16;
|
||||
}
|
||||
} else {
|
||||
if (al != 0) {
|
||||
if (m->flags & 0x40) {
|
||||
monster_change_next_anim(obj);
|
||||
m->flags |= 0x80;
|
||||
obj->data.m.y_velocity &= ~15;
|
||||
obj->x_pos += obj->data.m.x_velocity >> 2;
|
||||
return;
|
||||
}
|
||||
obj->data.m.x_velocity = -obj->data.m.x_velocity;
|
||||
obj->x_pos += obj->data.m.x_velocity >> 4;
|
||||
}
|
||||
obj->y_pos -= 16;
|
||||
SWAP(dl, dh);
|
||||
al = g_res.level.tile_attributes1[dl];
|
||||
if (al == 0) {
|
||||
obj->y_pos += 16;
|
||||
al = g_res.level.tile_attributes1[dh];
|
||||
if (al == 0) {
|
||||
if (obj->data.m.y_velocity < 256) {
|
||||
obj->data.m.y_velocity += 16;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
obj->y_pos &= ~15;
|
||||
obj->y_pos += level_get_tile_monster_offset(dl, obj);
|
||||
if ((m->flags & 0x20) == 0) {
|
||||
int dy = (-obj->data.m.y_velocity) >> 1;
|
||||
if (abs(dy) <= 32) {
|
||||
dy = 0;
|
||||
}
|
||||
obj->data.m.y_velocity = dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern void monster_func1(int type, struct object_t *obj); /* update */
|
||||
extern bool monster_func2(int type, struct level_monster_t *m); /* init */
|
||||
|
||||
|
@ -1298,12 +1398,14 @@ static void level_update_objects_monsters() {
|
|||
if (obj->spr_num == 0xFFFF) {
|
||||
continue;
|
||||
}
|
||||
print_debug(DBG_GAME, "monster #%d pos %d,%d spr %d", i, obj->x_pos, obj->y_pos, obj->spr_num);
|
||||
obj->y_pos += obj->data.m.y_velocity >> 4;
|
||||
if (obj->data.m.x_velocity != -1) {
|
||||
obj->x_pos += obj->data.m.x_velocity >> 4;
|
||||
}
|
||||
struct level_monster_t *m = obj->data.m.ref;
|
||||
if (m->flags & 8) {
|
||||
level_update_monster_pos(obj, m);
|
||||
}
|
||||
const uint8_t *p = obj->data.m.anim;
|
||||
int16_t num;
|
||||
|
@ -1315,6 +1417,7 @@ static void level_update_objects_monsters() {
|
|||
p += num;
|
||||
}
|
||||
uint16_t dx = 305 + (num & 0x1FFF);
|
||||
g_vars.monster.hit_mask = ((num >> 8) & 0xE0) | g_vars.player_monsters_unk_counter;
|
||||
if (g_vars.player_monsters_unk_counter == 0) {
|
||||
obj->data.m.anim = p + 2;
|
||||
} else {
|
||||
|
@ -2030,6 +2133,13 @@ static void level_update_player_anim_5(uint8_t al) {
|
|||
level_update_player_club_power();
|
||||
}
|
||||
|
||||
static void level_update_player_anim_8(uint8_t al) {
|
||||
level_update_screen_x_velocity();
|
||||
level_update_player_x_velocity();
|
||||
const uint8_t *p = level_update_player_anim2_num(al, al * 2);
|
||||
level_update_object_anim(p);
|
||||
}
|
||||
|
||||
static void level_update_player_decor() {
|
||||
const int y_pos = (g_vars.objects_tbl[1].y_pos >> 4) - 1;
|
||||
const int spr_num = g_vars.objects_tbl[1].spr_num & 0x1FFF;
|
||||
|
@ -2216,6 +2326,9 @@ static void level_update_player() {
|
|||
case 5:
|
||||
level_update_player_anim_5(al);
|
||||
break;
|
||||
case 8:
|
||||
level_update_player_anim_8(al);
|
||||
break;
|
||||
default:
|
||||
print_warning("Unhandled anim_lut %d mask %d", al, mask);
|
||||
break;
|
||||
|
@ -2271,6 +2384,9 @@ static void level_update_player_collision() {
|
|||
if (obj->spr_num == 0xFFFF || (obj->spr_num & 0x2000) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (g_options.cheats & CHEATS_NO_HIT) {
|
||||
continue;
|
||||
}
|
||||
struct level_monster_t *m = obj->data.m.ref;
|
||||
if (m->flags & 0x10) {
|
||||
continue;
|
||||
|
@ -2281,7 +2397,64 @@ static void level_update_player_collision() {
|
|||
if (!level_objects_collide(obj_player, obj)) {
|
||||
continue;
|
||||
}
|
||||
print_warning("Unhandled level_update_player_collision 6A43");
|
||||
if (g_vars.player_hit_monster_counter != 0) {
|
||||
level_monster_die(obj, m);
|
||||
continue;
|
||||
}
|
||||
if (!g_vars.player_jump_monster_flag && g_vars.objects_tbl[1].data.p.y_velocity < 0) {
|
||||
m->flags &= ~1;
|
||||
g_vars.objects_tbl[1].hit_counter = 44;
|
||||
g_vars.player_anim_0x40_flag = 0;
|
||||
g_vars.objects_tbl[1].data.p.y_velocity = -128;
|
||||
g_vars.objects_tbl[1].x_velocity = -(g_vars.objects_tbl[1].x_velocity << 2);
|
||||
g_vars.player_gravity_flag = 0;
|
||||
if (g_vars.player_flying_flag != 0) {
|
||||
g_vars.player_flying_flag = 0;
|
||||
} else {
|
||||
--g_vars.player_energy;
|
||||
if (g_vars.player_energy < 0) {
|
||||
level_player_die();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (g_vars.player_gravity_flag == 0) {
|
||||
int num = obj->data.m.unk10 >> 2;
|
||||
if (num != 11) {
|
||||
obj->data.m.unk10 += 4;
|
||||
++num;
|
||||
if ((num & 1) == 0) {
|
||||
static const uint16_t data[] = { 0xFF46, 0xE0, 0xE1, 0x12D, 0x12E, 0x12F };
|
||||
|
||||
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.player_jumping_counter = 0;
|
||||
} else if (g_vars.objects_tbl[1].data.p.y_velocity <= 32) {
|
||||
g_vars.objects_tbl[1].data.p.y_velocity = -96;
|
||||
g_vars.player_jumping_counter = 0;
|
||||
} else {
|
||||
int num = (obj->data.m.unk10) & 3;
|
||||
level_add_object75_score(obj_player, 82 + (num << 1));
|
||||
obj->spr_num |= 0x4000;
|
||||
if (num == 2) {
|
||||
obj->data.m.state = 0xFF;
|
||||
level_monster_update_anim(obj);
|
||||
m->flags &= ~8;
|
||||
obj->data.m.y_velocity = -200;
|
||||
int delta = abs(g_vars.objects_tbl[1].data.p.y_velocity);
|
||||
if (obj->x_pos <= g_vars.objects_tbl[1].x_pos) {
|
||||
delta = -delta;
|
||||
}
|
||||
obj->data.m.x_velocity = delta * 3;
|
||||
} else {
|
||||
++obj->data.m.unk10;
|
||||
g_vars.objects_tbl[1].data.p.y_velocity = -96;
|
||||
g_vars.player_jumping_counter = 0;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* bonuses */
|
||||
|
@ -2430,10 +2603,14 @@ static void level_update_player_collision() {
|
|||
if (obj->spr_num == 0xFFFF) {
|
||||
continue;
|
||||
}
|
||||
struct level_monster_t *m = obj->data.m.ref;
|
||||
if (m->flags & 0x10) {
|
||||
continue;
|
||||
}
|
||||
if ((obj->spr_num & 0x2000) == 0) {
|
||||
continue;
|
||||
}
|
||||
print_warning("Unhandled bonus num 169");
|
||||
level_monster_die(obj, m);
|
||||
}
|
||||
g_vars.shake_screen_counter = 9;
|
||||
level_clear_item(obj);
|
||||
|
@ -3114,6 +3291,7 @@ void do_level() {
|
|||
level_clear_panel();
|
||||
level_draw_panel();
|
||||
level_sync();
|
||||
g_vars.monster.type10_dist = 0;
|
||||
random_reset();
|
||||
while (!g_sys.input.quit) {
|
||||
level_update_objects_hit_animation();
|
||||
|
|
162
p2/monsters.c
162
p2/monsters.c
|
@ -5,6 +5,15 @@
|
|||
#include "resource.h"
|
||||
#include "util.h"
|
||||
|
||||
static void monster_reset(struct object_t *obj, struct level_monster_t *m) {
|
||||
m->current_tick = 0;
|
||||
obj->spr_num = 0xFFFF;
|
||||
m->flags &= ~4;
|
||||
if ((m->flags & 2) == 0) {
|
||||
m->spr_num = 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
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.state == 0xFF) {
|
||||
|
@ -25,12 +34,7 @@ static void monster_func1_helper(struct object_t *obj, int16_t x_pos, int16_t y_
|
|||
m->flags &= ~4;
|
||||
m->current_tick = 0;
|
||||
} else {
|
||||
m->current_tick = 0;
|
||||
obj->spr_num = 0xFFFF;
|
||||
m->flags &= ~4;
|
||||
if ((m->flags & 2) == 0) {
|
||||
m->spr_num = 0xFFFF;
|
||||
}
|
||||
monster_reset(obj, m);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,7 +45,7 @@ static bool monster_next_tick(struct level_monster_t *m) {
|
|||
return ((m->current_tick >> 2) < m->total_ticks);
|
||||
}
|
||||
|
||||
static void monster_change_next_anim(struct object_t *obj) {
|
||||
void monster_change_next_anim(struct object_t *obj) {
|
||||
const uint8_t *p = obj->data.m.anim;
|
||||
while ((int16_t)READ_LE_UINT16(p) >= 0) {
|
||||
p += 2;
|
||||
|
@ -49,7 +53,7 @@ static void monster_change_next_anim(struct object_t *obj) {
|
|||
obj->data.m.anim = p + 2;
|
||||
}
|
||||
|
||||
static void monster_change_prev_anim(struct object_t *obj) {
|
||||
void monster_change_prev_anim(struct object_t *obj) {
|
||||
const uint8_t *p = obj->data.m.anim;
|
||||
do {
|
||||
p -= 2;
|
||||
|
@ -67,7 +71,7 @@ static struct rotation_t *find_rotation() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void monster_rotate_platform(struct level_monster_t *m, int index, int step) {
|
||||
static void monster_rotate_tiles(struct level_monster_t *m, int index, int step) {
|
||||
step >>= 2;
|
||||
uint8_t radius = step;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
|
@ -83,9 +87,9 @@ static void monster_rotate_platform(struct level_monster_t *m, int index, int st
|
|||
}
|
||||
|
||||
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);
|
||||
obj->x_pos = m->x_pos + ((m->type4.radius * (((int8_t)cos_tbl[m->type4.angle]) >> 2)) >> 4);
|
||||
obj->y_pos = m->y_pos + ((m->type4.radius * (((int8_t)sin_tbl[m->type4.angle]) >> 2)) >> 4);
|
||||
monster_rotate_tiles(m, m->type4.angle, m->type4.radius);
|
||||
}
|
||||
|
||||
static void monster_update_y_velocity(struct object_t *obj, struct level_monster_t *m) {
|
||||
|
@ -94,12 +98,7 @@ static void monster_update_y_velocity(struct object_t *obj, struct level_monster
|
|||
obj->data.m.y_velocity += 15;
|
||||
}
|
||||
} else {
|
||||
m->current_tick = 0;
|
||||
obj->spr_num = 0xFFFF;
|
||||
m->flags &= ~4;
|
||||
if ((m->flags & 2) == 0) {
|
||||
m->spr_num = 0xFFFF;
|
||||
}
|
||||
monster_reset(obj, m);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +107,7 @@ static void monster_func1_type2(struct object_t *obj) {
|
|||
struct level_monster_t *m = obj->data.m.ref;
|
||||
const uint8_t state = obj->data.m.state;
|
||||
if (state < 2) {
|
||||
monster_rotate_platform(m, 0, obj->y_pos - m->y_pos);
|
||||
monster_rotate_tiles(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;
|
||||
|
@ -118,7 +117,7 @@ static void monster_func1_type2(struct object_t *obj) {
|
|||
obj->data.m.state = 1;
|
||||
monster_change_next_anim(obj);
|
||||
} else if (state == 1) {
|
||||
obj->data.m.y_velocity = m->type2.unkE << 4;
|
||||
obj->data.m.y_velocity = -(m->type2.unkE << 4);
|
||||
const int dy = obj->y_pos - m->y_pos;
|
||||
if (dy >= 0) {
|
||||
return;
|
||||
|
@ -140,8 +139,8 @@ static void monster_func1_type4(struct object_t *obj) {
|
|||
return;
|
||||
}
|
||||
const int dy = obj->y_pos - m->y_pos;
|
||||
monster_rotate_platform(m, 0, dy);
|
||||
if (m->type4.unkD > dy) {
|
||||
monster_rotate_tiles(m, 0, dy);
|
||||
if (m->type4.radius > dy) {
|
||||
obj->y_pos += 2;
|
||||
} else {
|
||||
obj->data.m.state = 1;
|
||||
|
@ -154,6 +153,7 @@ static void monster_func1_type4(struct object_t *obj) {
|
|||
obj->data.m.state = 2;
|
||||
}
|
||||
} else if (state == 2) {
|
||||
monster_rotate_pos(obj, m);
|
||||
if (m->type4.angle & 0x80) {
|
||||
++m->type4.unk10;
|
||||
} else {
|
||||
|
@ -245,6 +245,65 @@ static void monster_func1_type9(struct object_t *obj) {
|
|||
}
|
||||
}
|
||||
|
||||
static void monster_func1_type10(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 (g_vars.level_num == 5 && g_vars.shake_screen_counter != 0 && state != 3 && state != 0xFF) {
|
||||
m->current_tick = 1;
|
||||
}
|
||||
if (state == 0) {
|
||||
m->flags |= 0x18;
|
||||
if (obj->data.m.y_velocity == 0) {
|
||||
obj->data.m.state = 1;
|
||||
}
|
||||
} else if (state == 1) {
|
||||
if (obj->data.m.y_velocity != 0) {
|
||||
obj->data.m.state = 0;
|
||||
} else {
|
||||
m->current_tick = 30;
|
||||
obj->data.m.state = 2;
|
||||
monster_change_next_anim(obj);
|
||||
}
|
||||
} else if (state == 2) {
|
||||
const int dx = abs(obj->data.m.x_velocity);
|
||||
if (dx < 16) {
|
||||
if (g_vars.monster.hit_mask == 0) {
|
||||
return;
|
||||
}
|
||||
m->flags = 0xF;
|
||||
int x_vel = m->type10.unkD;
|
||||
if (obj->x_pos >= g_vars.objects_tbl[1].x_pos) {
|
||||
x_vel = -x_vel;
|
||||
}
|
||||
obj->data.m.x_velocity = x_vel;
|
||||
}
|
||||
if ((g_vars.level_draw_counter & 3) == 0) {
|
||||
--m->current_tick;
|
||||
if (m->current_tick == 0) {
|
||||
obj->data.m.state = 3;
|
||||
obj->data.m.y_velocity = 0;
|
||||
obj->data.m.x_velocity >>= 15;
|
||||
m->flags = 0x36;
|
||||
monster_change_next_anim(obj);
|
||||
}
|
||||
}
|
||||
} else if (state == 3) {
|
||||
if (g_vars.monster.hit_mask == 0) {
|
||||
return;
|
||||
}
|
||||
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 (obj->data.m.y_velocity < 240) {
|
||||
obj->data.m.y_velocity += 15;
|
||||
}
|
||||
} else {
|
||||
monster_reset(obj, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void monster_func1(int type, struct object_t *obj) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
|
@ -262,6 +321,9 @@ void monster_func1(int type, struct object_t *obj) {
|
|||
case 9:
|
||||
monster_func1_type9(obj);
|
||||
break;
|
||||
case 10:
|
||||
monster_func1_type10(obj);
|
||||
break;
|
||||
default:
|
||||
print_warning("monster_func1 unhandled monster type %d", type);
|
||||
break;
|
||||
|
@ -310,9 +372,7 @@ static bool monster_is_visible(int x_pos, int y_pos) {
|
|||
}
|
||||
|
||||
static bool monster_func2_type1(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;
|
||||
}
|
||||
return monster_init_object(m);
|
||||
|
@ -345,6 +405,8 @@ static bool monster_func2_type4(struct level_monster_t *m) {
|
|||
return false;
|
||||
}
|
||||
m->flags = 5;
|
||||
m->type4.angle = 0;
|
||||
m->type4.unk10 = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -379,20 +441,62 @@ 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;
|
||||
const uint16_t x = m->x_pos;
|
||||
const uint16_t y = m->y_pos;
|
||||
const int dx = (g_vars.objects_tbl[1].x_pos >> 4) - (x & 255);
|
||||
if (dx < 0) {
|
||||
return false;
|
||||
}
|
||||
const int dy = (g_vars.objects_tbl[1].y_pos >> 4) - m->y_pos;
|
||||
if ((y & 255) < dx) {
|
||||
return false;
|
||||
}
|
||||
const int dy = (g_vars.objects_tbl[1].y_pos >> 4) - (x >> 8);
|
||||
if (dy < 0) {
|
||||
return false;
|
||||
}
|
||||
if ((y >> 8) < dy) {
|
||||
return false;
|
||||
}
|
||||
struct object_t *obj = find_object_monster();
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
print_warning("monster_func2_type10 6579");
|
||||
return true;
|
||||
obj->data.m.unk10 = 0;
|
||||
g_vars.monster.current_object = obj;
|
||||
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];
|
||||
++g_vars.monster.type10_dist;
|
||||
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)) {
|
||||
bool init_spr = true;
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
const uint8_t tile_num = g_res.leveldat[bp - j * 0x100];
|
||||
if (g_res.level.tile_attributes1[tile_num] != 0) {
|
||||
init_spr = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (init_spr) {
|
||||
obj->y_pos = bh << 4;
|
||||
obj->spr_num = m->spr_num;
|
||||
obj->data.m.ref = m;
|
||||
m->flags = 0x17;
|
||||
obj->data.m.state = 0;
|
||||
obj->data.m.y_velocity = 0;
|
||||
obj->data.m.energy = m->energy;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bp -= 0x100;
|
||||
if (bp < 0x300) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool monster_func2_type11(struct level_monster_t *m) {
|
||||
|
|
|
@ -130,26 +130,36 @@ void load_leveldat(const uint8_t *p, struct level_t *level) {
|
|||
m->x_pos = READ_LE_UINT16(p + 0x9);
|
||||
m->y_pos = READ_LE_UINT16(p + 0xB);
|
||||
switch (type) {
|
||||
case 2:
|
||||
case 2: /* vertical (eg. spider) */
|
||||
assert(len == 15);
|
||||
m->type2.y_range = p[0xD];
|
||||
m->type2.unkE = p[0xE];
|
||||
case 4:
|
||||
m->type4.unkD = p[0xD];
|
||||
break;
|
||||
case 4: /* rotate (eg. spider) */
|
||||
assert(len == 17);
|
||||
m->type4.radius = p[0xD];
|
||||
m->type4.unkE = p[0xE];
|
||||
m->type4.angle = p[0xF];
|
||||
m->type4.unk10 = p[0x10];
|
||||
break;
|
||||
case 8:
|
||||
case 8: /* jumps (eg. leopard) */
|
||||
assert(len == 17);
|
||||
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:
|
||||
case 9: /* horizontal */
|
||||
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];
|
||||
break;
|
||||
case 10: /* come out of the ground */
|
||||
assert(len == 14);
|
||||
m->type10.unkD = p[0xD];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
#include "intern.h"
|
||||
|
||||
struct level_gate_t {
|
||||
uint16_t enter_pos; // (y << 8) | x
|
||||
uint16_t enter_pos;
|
||||
uint16_t tilemap_pos;
|
||||
uint16_t dst_pos;
|
||||
uint8_t scroll_flag;
|
||||
}; // sizeof == 7
|
||||
};
|
||||
|
||||
struct level_platform_t {
|
||||
uint16_t tilemap_pos;
|
||||
|
@ -17,22 +17,22 @@ struct level_platform_t {
|
|||
uint8_t h;
|
||||
uint16_t unk4;
|
||||
uint16_t unk6;
|
||||
uint8_t unk8; // y_offs
|
||||
uint8_t unk8;
|
||||
uint8_t unk9;
|
||||
}; // sizeof == 10
|
||||
};
|
||||
|
||||
struct level_bonus_t {
|
||||
uint8_t tile_num0; /* new tile */
|
||||
uint8_t tile_num1; /* original tile */
|
||||
uint8_t count;
|
||||
uint16_t pos; // (y << 8) | x
|
||||
}; // sizeof == 5
|
||||
uint16_t pos;
|
||||
};
|
||||
|
||||
struct level_item_t {
|
||||
int16_t x_pos, y_pos;
|
||||
uint16_t spr_num;
|
||||
int8_t y_delta;
|
||||
}; // sizeof == 7
|
||||
};
|
||||
|
||||
struct level_trigger_t {
|
||||
uint16_t x_pos;
|
||||
|
@ -44,9 +44,9 @@ struct level_trigger_t {
|
|||
int8_t unk7;
|
||||
uint8_t unk8;
|
||||
uint8_t unk9;
|
||||
uint8_t state; // 0xA
|
||||
uint16_t y_delta; // 0xB
|
||||
uint8_t counter; // 0xD
|
||||
uint8_t state;
|
||||
uint16_t y_delta;
|
||||
uint8_t counter;
|
||||
} type8;
|
||||
struct {
|
||||
int16_t unk7;
|
||||
|
@ -56,42 +56,45 @@ struct level_trigger_t {
|
|||
} other;
|
||||
};
|
||||
uint8_t unkE;
|
||||
}; // sizeof == 15
|
||||
};
|
||||
|
||||
struct level_monster_t {
|
||||
uint8_t len;
|
||||
uint8_t type;
|
||||
uint16_t spr_num; // 0x2
|
||||
uint8_t flags; // 0x4
|
||||
uint8_t energy; // 0x5
|
||||
uint16_t spr_num;
|
||||
uint8_t flags;
|
||||
uint8_t energy;
|
||||
uint8_t total_ticks;
|
||||
uint8_t current_tick;
|
||||
uint8_t unk8;
|
||||
uint16_t x_pos; // 0x9
|
||||
uint16_t y_pos; // 0xB
|
||||
uint16_t x_pos;
|
||||
uint16_t y_pos;
|
||||
union {
|
||||
struct {
|
||||
uint8_t y_range; // 0xD
|
||||
int8_t unkE; // 0xE, cbw
|
||||
uint8_t y_range;
|
||||
int8_t unkE;
|
||||
} type2;
|
||||
struct {
|
||||
uint8_t unkD;
|
||||
uint8_t radius;
|
||||
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
|
||||
uint8_t x_range;
|
||||
int8_t unkE;
|
||||
int8_t unkF;
|
||||
uint8_t y_range;
|
||||
} type8;
|
||||
struct {
|
||||
int16_t unkD; // 0xD
|
||||
int16_t unkF; // 0xF
|
||||
int8_t unk11; // 0x11
|
||||
uint8_t unk12; // 0x12
|
||||
int16_t unkD;
|
||||
int16_t unkF;
|
||||
int8_t unk11;
|
||||
uint8_t unk12;
|
||||
} type9;
|
||||
struct {
|
||||
uint8_t unkD;
|
||||
} type10;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
12
p2/screen.c
12
p2/screen.c
|
@ -76,12 +76,16 @@ void video_draw_string(int offset, int hspace, const char *s) {
|
|||
|
||||
void video_draw_panel_number(int offset, int num) {
|
||||
const uint8_t *fnt = g_res.allfonts + 48 * 41 + 160 * 23;
|
||||
decode_planar(fnt + num * 96, g_res.vga + offset * 8, 320, 16, 12, 0);
|
||||
const int y = (offset * 8) / 320 + (GAME_SCREEN_H - 200);
|
||||
const int x = (offset * 8) % 320 + (GAME_SCREEN_W - 320) / 2;
|
||||
decode_planar(fnt + num * 96, g_res.vga + y * GAME_SCREEN_W + x, GAME_SCREEN_W, 16, 12, 0);
|
||||
}
|
||||
|
||||
void video_draw_number(int offset, int num) {
|
||||
const uint8_t *fnt = g_res.allfonts + 0x1C70;
|
||||
decode_planar(fnt + num * 88, g_res.vga + offset * 8, 320, 16, 11, 0);
|
||||
const int y = (offset * 8) / 320;
|
||||
const int x = (offset * 8) % 320;
|
||||
decode_planar(fnt + num * 88, g_res.vga + y * GAME_SCREEN_W + x, GAME_SCREEN_W, 16, 11, 0);
|
||||
}
|
||||
|
||||
void video_clear() {
|
||||
|
@ -93,7 +97,9 @@ void video_copy_img(const uint8_t *src) {
|
|||
}
|
||||
|
||||
void video_draw_panel(const uint8_t *src) {
|
||||
decode_planar(src, g_res.vga + TILEMAP_SCREEN_H * 320, 320, 320, 23, 0xFF);
|
||||
const int h = GAME_SCREEN_H - PANEL_H;
|
||||
const int x = (GAME_SCREEN_W - 320) / 2;
|
||||
decode_planar(src, g_res.vga + h * GAME_SCREEN_W + x, GAME_SCREEN_W, 320, 23, 0xFF);
|
||||
}
|
||||
|
||||
void video_draw_tile(const uint8_t *src, int x_offset, int y_offset) {
|
||||
|
|
Loading…
Reference in New Issue