Import blues from c39a5c48

This commit is contained in:
Gregory Montoir 2018-12-16 22:28:52 +08:00
parent 75a4b6508c
commit 9ec6c6d7b0
15 changed files with 177 additions and 134 deletions

View File

@ -32,18 +32,6 @@ void fio_init(const char *data_path) {
void fio_fini() { void fio_fini() {
} }
static FILE *fio_open_no_case(const char *filename) {
char buf[MAXPATHLEN];
snprintf(buf, sizeof(buf), "%s/%s", _data_path, filename);
FILE *fp = fopen(buf, "rb");
if (!fp) {
char *p = buf + strlen(_data_path) + 1;
string_upper(p);
fp = fopen(buf, "rb");
}
return fp;
}
int fio_open(const char *filename, int error_flag) { int fio_open(const char *filename, int error_flag) {
int slot = find_free_slot(); int slot = find_free_slot();
if (slot < 0) { if (slot < 0) {
@ -51,7 +39,7 @@ int fio_open(const char *filename, int error_flag) {
} else { } else {
struct fileio_slot_t *file_slot = &_fileio_slots_table[slot]; struct fileio_slot_t *file_slot = &_fileio_slots_table[slot];
memset(file_slot, 0, sizeof(fileio_slot_t)); memset(file_slot, 0, sizeof(fileio_slot_t));
file_slot->fp = fio_open_no_case(filename); file_slot->fp = fopen_nocase(_data_path, filename);
if (!file_slot->fp) { if (!file_slot->fp) {
if (error_flag) { if (error_flag) {
print_error("Unable to open file '%s'", filename); print_error("Unable to open file '%s'", filename);
@ -98,7 +86,7 @@ int fio_read(int slot, void *data, int len) {
} }
int fio_exists(const char *filename) { int fio_exists(const char *filename) {
FILE *fp = fio_open_no_case(filename); FILE *fp = fopen_nocase(_data_path, filename);
if (fp) { if (fp) {
fclose(fp); fclose(fp);
return 1; return 1;

View File

@ -2073,7 +2073,7 @@ static void draw_foreground_tiles() {
if (avt_num != 255) { if (avt_num != 255) {
const int tile_y = g_vars.screen_tilemap_yoffset + j * 16 + TILEMAP_OFFSET_Y; const int tile_y = g_vars.screen_tilemap_yoffset + j * 16 + TILEMAP_OFFSET_Y;
const int tile_x = g_vars.screen_tilemap_xoffset + i * 16; const int tile_x = g_vars.screen_tilemap_xoffset + i * 16;
render_add_sprite(RENDER_SPR_FG, avt_num, tile_x, tile_y, 0); g_sys.render_add_sprite(RENDER_SPR_FG, avt_num, tile_x, tile_y, 0);
} }
} }
++y; ++y;
@ -2105,7 +2105,7 @@ void do_level() {
g_vars.quit_level_flag = 0; g_vars.quit_level_flag = 0;
g_vars.player2_scrolling_flag = 0; g_vars.player2_scrolling_flag = 0;
g_vars.found_music_instrument_flag = 0; g_vars.found_music_instrument_flag = 0;
render_set_sprites_clipping_rect(0, TILEMAP_OFFSET_Y, TILEMAP_SCREEN_W, TILEMAP_SCREEN_H); g_sys.render_set_sprites_clipping_rect(0, TILEMAP_OFFSET_Y, TILEMAP_SCREEN_W, TILEMAP_SCREEN_H);
bool screen_transition_flag = true; bool screen_transition_flag = true;
do { do {
const uint32_t timestamp = g_sys.get_timestamp(); const uint32_t timestamp = g_sys.get_timestamp();
@ -2156,6 +2156,6 @@ void do_level() {
if (g_options.amiga_copper_bars) { if (g_options.amiga_copper_bars) {
g_sys.set_copper_bars(0); g_sys.set_copper_bars(0);
} }
render_set_sprites_clipping_rect(0, 0, GAME_SCREEN_W, GAME_SCREEN_H); g_sys.render_set_sprites_clipping_rect(0, 0, GAME_SCREEN_W, GAME_SCREEN_H);
g_vars.inp_keyboard[0xBF] = 0; g_vars.inp_keyboard[0xBF] = 0;
} }

View File

@ -17,11 +17,15 @@ void screen_init() {
} }
void screen_clear_sprites() { void screen_clear_sprites() {
render_clear_sprites(); g_sys.render_clear_sprites();
} }
static void add_game_sprite(int x, int y, int frame, int xflip) { static void add_game_sprite(int x, int y, int frame, int xflip) {
const uint8_t *p = g_res.spr_frames[frame]; const uint8_t *p = g_res.spr_frames[frame];
if (!p) {
print_warning("add_game_sprite missing frame %d", frame);
return;
}
const int h = READ_LE_UINT16(p - 4); const int h = READ_LE_UINT16(p - 4);
const int w = READ_LE_UINT16(p - 2); const int w = READ_LE_UINT16(p - 2);
int spr_type = RENDER_SPR_GAME; int spr_type = RENDER_SPR_GAME;
@ -34,7 +38,7 @@ static void add_game_sprite(int x, int y, int frame, int xflip) {
y += _offset_y; y += _offset_y;
} }
} }
render_add_sprite(spr_type, frame, x - w / 2, y - h, xflip); g_sys.render_add_sprite(spr_type, frame, x - w / 2, y - h, xflip);
} }
void screen_add_sprite(int x, int y, int frame) { void screen_add_sprite(int x, int y, int frame) {
@ -256,9 +260,9 @@ static void decode_graphics(int spr_type, int start, int end, const uint8_t *dit
} }
assert(max_w <= MAX_SPRITESHEET_W); assert(max_w <= MAX_SPRITESHEET_W);
assert(current_y + max_h <= MAX_SPRITESHEET_H); assert(current_y + max_h <= MAX_SPRITESHEET_H);
render_unload_sprites(spr_type); g_sys.render_unload_sprites(spr_type);
const int palette_offset = (g_res.amiga_data && start == 0) ? 16 : 0; const int palette_offset = (g_res.amiga_data && start == 0) ? 16 : 0;
render_load_sprites(spr_type, end - start, r, data, MAX_SPRITESHEET_W, current_y + max_h, palette_offset, color_key); g_sys.render_load_sprites(spr_type, end - start, r, data, MAX_SPRITESHEET_W, current_y + max_h, palette_offset, color_key);
free(data); free(data);
} }
} }
@ -286,8 +290,8 @@ void screen_load_graphics(const uint8_t *dither_lut_sqv, const uint8_t *dither_l
if (dither_lut_avt) { if (dither_lut_avt) {
dither_graphics(data, FG_TILE_W * g_res.avt_count, FG_TILE_W * g_res.avt_count, FG_TILE_H, dither_lut_avt, color_key); dither_graphics(data, FG_TILE_W * g_res.avt_count, FG_TILE_W * g_res.avt_count, FG_TILE_H, dither_lut_avt, color_key);
} }
render_unload_sprites(RENDER_SPR_FG); g_sys.render_unload_sprites(RENDER_SPR_FG);
render_load_sprites(RENDER_SPR_FG, g_res.avt_count, r, data, g_res.avt_count * FG_TILE_W, FG_TILE_H, 0, color_key); g_sys.render_load_sprites(RENDER_SPR_FG, g_res.avt_count, r, data, g_res.avt_count * FG_TILE_W, FG_TILE_H, 0, color_key);
free(data); free(data);
} }
// background tiles (Amiga) - re-arrange to match DOS .ck1/.ck2 layout // background tiles (Amiga) - re-arrange to match DOS .ck1/.ck2 layout

View File

@ -96,7 +96,6 @@ static void do_select_screen() {
int bl = 2; int bl = 2;
while (!g_sys.input.quit) { while (!g_sys.input.quit) {
int bh = bl; int bh = bl;
video_vsync(60);
if (g_sys.input.direction & INPUT_DIRECTION_RIGHT) { if (g_sys.input.direction & INPUT_DIRECTION_RIGHT) {
g_sys.input.direction &= ~INPUT_DIRECTION_RIGHT; g_sys.input.direction &= ~INPUT_DIRECTION_RIGHT;
++bl; ++bl;
@ -104,7 +103,6 @@ static void do_select_screen() {
if (bl == 0) { if (bl == 0) {
bl = 1; bl = 1;
} }
video_vsync(60);
} }
if (g_sys.input.direction & INPUT_DIRECTION_LEFT) { if (g_sys.input.direction & INPUT_DIRECTION_LEFT) {
g_sys.input.direction &= ~INPUT_DIRECTION_LEFT; g_sys.input.direction &= ~INPUT_DIRECTION_LEFT;
@ -113,7 +111,6 @@ static void do_select_screen() {
if (bl == 0) { if (bl == 0) {
bl = 3; bl = 3;
} }
video_vsync(60);
} }
bh ^= bl; bh ^= bl;
if (bh & 1) { if (bh & 1) {
@ -316,7 +313,7 @@ void game_main() {
do_splash_screen(); do_splash_screen();
g_sys.set_screen_palette(common_palette_data, 0, 128, 6); g_sys.set_screen_palette(common_palette_data, 0, 128, 6);
video_load_sprites(); video_load_sprites();
render_set_sprites_clipping_rect(0, 0, TILEMAP_SCREEN_W, TILEMAP_SCREEN_H); g_sys.render_set_sprites_clipping_rect(0, 0, TILEMAP_SCREEN_W, TILEMAP_SCREEN_H);
while (!g_sys.input.quit) { while (!g_sys.input.quit) {
update_input(); update_input();
g_vars.level = g_options.start_level; g_vars.level = g_options.start_level;

View File

@ -4,9 +4,10 @@
#include "intern.h" #include "intern.h"
#define CHEATS_OBJECT_NO_HIT (1 << 0) #define CHEATS_OBJECT_NO_HIT (1 << 0)
#define CHEATS_ONE_HIT_VINYL (1 << 1) #define CHEATS_ONE_HIT_VINYL (1 << 1)
#define CHEATS_DECOR_NO_HIT (1 << 2) #define CHEATS_DECOR_NO_HIT (1 << 2)
#define CHEATS_UNLIMITED_VINYLS (1 << 3)
extern struct options_t g_options; extern struct options_t g_options;
@ -129,7 +130,6 @@ struct vars_t {
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]; int16_t dragon_coords[1 + 128];
struct player_t players_table[2]; struct player_t players_table[2];
uint8_t player_hit_counter;
int16_t player_xscroll, player_map_offset; int16_t player_xscroll, player_map_offset;
struct object_t objects_table[OBJECTS_COUNT]; struct object_t objects_table[OBJECTS_COUNT];
int level_start_1p_x_pos, level_start_1p_y_pos; int level_start_1p_x_pos, level_start_1p_y_pos;
@ -172,7 +172,6 @@ extern const uint8_t monster_spr_anim_data0[];
extern const uint8_t monster_spr_anim_data1[]; extern const uint8_t monster_spr_anim_data1[];
extern const uint8_t monster_spr_anim_data2[]; extern const uint8_t monster_spr_anim_data2[];
extern const uint8_t monster_spr_anim_data3[]; extern const uint8_t monster_spr_anim_data3[];
extern const uint8_t monster_spr_anim_data4[];
extern const uint8_t monster_spr_anim_data6[]; extern const uint8_t monster_spr_anim_data6[];
extern const uint8_t monster_spr_anim_data8[]; extern const uint8_t monster_spr_anim_data8[];
extern const uint8_t monster_spr_anim_data9[]; extern const uint8_t monster_spr_anim_data9[];
@ -208,12 +207,12 @@ extern void video_draw_dot_pattern(int offset);
extern void video_draw_sprite(int num, int x, int y, int flag); extern void video_draw_sprite(int num, int x, int y, int flag);
extern void video_draw_string(const char *s, int offset, int hspace); extern void video_draw_string(const char *s, int offset, int hspace);
extern void video_copy_vga(int size); extern void video_copy_vga(int size);
extern void video_vsync(int delay);
extern void fade_in_palette(); extern void fade_in_palette();
extern void fade_out_palette(); extern void fade_out_palette();
extern void ja_decode_spr(const uint8_t *src, int w, int h, uint8_t *dst, int dst_pitch, uint8_t pal_mask); extern void ja_decode_spr(const uint8_t *src, int w, int h, uint8_t *dst, int dst_pitch, uint8_t pal_mask);
extern void ja_decode_chr(const uint8_t *buffer, const int size, uint8_t *dst, int dst_pitch); extern void ja_decode_chr(const uint8_t *buffer, const int size, uint8_t *dst, int dst_pitch);
extern void ja_decode_tile(const uint8_t *buffer, uint8_t pal_mask, uint8_t *dst, int dst_pitch, int x, int y); extern void ja_decode_tile(const uint8_t *buffer, uint8_t pal_mask, uint8_t *dst, int dst_pitch, int x, int y);
extern void ja_decode_motif(int num, uint8_t color);
extern void video_load_sprites(); extern void video_load_sprites();
/* sound.c */ /* sound.c */

View File

@ -22,6 +22,16 @@ static void level_player_draw_powerdown_animation(struct player_t *player);
static void level_player_draw_powerup_animation(struct player_t *player, struct object_t *obj); static void level_player_draw_powerup_animation(struct player_t *player, struct object_t *obj);
static void level_update_tiles(struct object_t *obj, int ax, int dx, int bp); static void level_update_tiles(struct object_t *obj, int ax, int dx, int bp);
static void do_end_of_level() {
static const uint8_t color_index = 127;
ja_decode_motif(g_vars.level_num % 9, color_index);
static const uint8_t white[] = { 0x3F, 0x3F, 0x3F };
g_sys.set_palette_color(color_index, white);
g_sys.update_screen(g_res.vga, 1);
g_sys.sleep(1000);
fade_out_palette();
}
static void level_player_die(struct player_t *player) { static void level_player_die(struct player_t *player) {
g_vars.player_xscroll = 0; g_vars.player_xscroll = 0;
player_flags2(&player->obj) |= 8; player_flags2(&player->obj) |= 8;
@ -81,8 +91,8 @@ static void level_update_palette() {
} }
static uint8_t level_lookup_tile(uint8_t num) { static uint8_t level_lookup_tile(uint8_t num) {
uint8_t _al = g_vars.tilemap_lut_type[num]; const uint8_t type = g_vars.tilemap_lut_type[num];
if (_al == 2) { if (type == 2) {
if ((g_vars.tilemap_flags & 2) != 0 && (g_vars.level_loop_counter & 0x20) != 0) { if ((g_vars.tilemap_flags & 2) != 0 && (g_vars.level_loop_counter & 0x20) != 0) {
return 0; return 0;
} }
@ -93,11 +103,11 @@ static uint8_t level_lookup_tile(uint8_t num) {
} }
} }
} }
_al = g_vars.tilemap_current_lut[num]; num = g_vars.tilemap_current_lut[num];
if (_al == 248 && (g_vars.tilemap_flags & 1) != 0) { if (num == 248 && (g_vars.tilemap_flags & 1) != 0) {
++_al; ++num;
} }
return _al; return num;
} }
static uint8_t level_get_tile(int offset) { static uint8_t level_get_tile(int offset) {
@ -218,7 +228,6 @@ static void level_hit_player(struct player_t *p) {
player_flags(&g_vars.players_table[1].obj) &= ~0x40; player_flags(&g_vars.players_table[1].obj) &= ~0x40;
player_flags2(&g_vars.players_table[0].obj) &= ~1; player_flags2(&g_vars.players_table[0].obj) &= ~1;
player_flags2(&g_vars.players_table[1].obj) &= ~1; player_flags2(&g_vars.players_table[1].obj) &= ~1;
g_vars.player_hit_counter = 7;
} }
static void level_player_hit_object(struct player_t *p, struct object_t *obj) { static void level_player_hit_object(struct player_t *p, struct object_t *obj) {
@ -483,9 +492,13 @@ static void level_update_player_anim_6(struct player_t *player) {
int ax = ((player_flags(&player->obj) & PLAYER_FLAGS_POWERUP) != 0) ? 0x200 : 0x100; int ax = ((player_flags(&player->obj) & PLAYER_FLAGS_POWERUP) != 0) ? 0x200 : 0x100;
if (player_power(&player->obj) >= 33) { if (player_power(&player->obj) >= 33) {
ax = 0x4000; ax = 0x4000;
player->vinyls_count -= 4; if ((g_options.cheats & CHEATS_UNLIMITED_VINYLS) == 0) {
player->vinyls_count -= 4;
}
}
if ((g_options.cheats & CHEATS_UNLIMITED_VINYLS) == 0) {
--player->vinyls_count;
} }
--player->vinyls_count;
object22_damage(obj) = ax; object22_damage(obj) = ax;
player_flags(&player->obj) |= PLAYER_FLAGS_THROW_VINYL; player_flags(&player->obj) |= PLAYER_FLAGS_THROW_VINYL;
player_power(&player->obj) = 0; player_power(&player->obj) = 0;
@ -606,7 +619,6 @@ static void level_update_player_anim_26(struct player_t *player) {
} }
static void level_update_player_anim_27(struct player_t *player) { static void level_update_player_anim_27(struct player_t *player) {
g_vars.player_hit_counter = 7;
player->obj.spr_num = 27; player->obj.spr_num = 27;
level_player_update_xvelocity(player, 0); level_player_update_xvelocity(player, 0);
if (player_throw_counter(&player->obj) == 0) { if (player_throw_counter(&player->obj) == 0) {
@ -1299,7 +1311,7 @@ static void level_update_object82_type3(struct object_t *obj) {
if (al == 0) { if (al == 0) {
if (level_get_closest_player(obj, 160)) { if (level_get_closest_player(obj, 160)) {
object82_state(obj) = 1; object82_state(obj) = 1;
object82_anim_data(obj) = monster_spr_anim_data4; object82_anim_data(obj) = monster_spr_anim_data3 + 4;
object82_counter(obj) = 40; object82_counter(obj) = 40;
} }
} else if (al == 1) { } else if (al == 1) {
@ -1346,7 +1358,7 @@ static void level_update_object82_type2(struct object_t *obj) {
obj->data[5].w = -56; obj->data[5].w = -56;
obj->data[4].b[0] = obj->data[4].b[1]; obj->data[4].b[0] = obj->data[4].b[1];
obj->data[4].b[1] = -obj->data[4].b[1]; obj->data[4].b[1] = -obj->data[4].b[1];
obj->data[1].b[0] += 2; object82_anim_data(obj) += 2;
object82_counter(obj) = 4; object82_counter(obj) = 4;
} }
} else { } else {
@ -1600,7 +1612,7 @@ static void level_update_triggers() {
if (num == 21) { if (num == 21) {
obj->spr_num = 228; // closed trap obj->spr_num = 228; // closed trap
type = 3; type = 3;
object82_anim_data(obj) = monster_spr_anim_data4 + 18; object82_anim_data(obj) = monster_spr_anim_data3 + 24;
} else { } else {
obj->spr_num = 225; // open trap obj->spr_num = 225; // open trap
object82_anim_data(obj) = monster_spr_anim_data3; object82_anim_data(obj) = monster_spr_anim_data3;
@ -1921,6 +1933,8 @@ static void level_update_triggers() {
} }
if (player_bounce_counter(&g_vars.players_table[0].obj) != 0) { if (player_bounce_counter(&g_vars.players_table[0].obj) != 0) {
--player_bounce_counter(&g_vars.players_table[0].obj); --player_bounce_counter(&g_vars.players_table[0].obj);
}
if (player_bounce_counter(&g_vars.players_table[0].obj) != 0) {
level_update_bouncing_tiles(&g_vars.players_table[0]); level_update_bouncing_tiles(&g_vars.players_table[0]);
} }
assert(g_vars.player != 2); assert(g_vars.player != 2);
@ -1937,7 +1951,7 @@ static void level_update_triggers() {
} }
p += num << 1; // loop p += num << 1; // loop
} }
obj->spr_num = num | ((object82_hflip(obj) & 0x80) << 8); // hflip obj->spr_num = num | ((object82_hflip(obj) & 0x80) << 8);
object82_anim_data(obj) = p + 2; object82_anim_data(obj) = p + 2;
switch (object82_type(obj)) { switch (object82_type(obj)) {
case 0: case 0:
@ -1982,7 +1996,7 @@ static void level_update_triggers() {
if (object82_type(obj) == 5) { // jukebox for end of level if (object82_type(obj) == 5) { // jukebox for end of level
if ((player_flags2(&player->obj) & 8) == 0) { if ((player_flags2(&player->obj) & 8) == 0) {
if (level_collide_objects(obj, &g_vars.objects_table[0])) { if (level_collide_objects(obj, &g_vars.objects_table[0])) {
// do_end_of_level(); do_end_of_level();
g_vars.change_next_level_flag = 1; g_vars.change_next_level_flag = 1;
continue; continue;
} }
@ -2028,7 +2042,7 @@ static void level_update_player(struct player_t *player) {
continue; continue;
} else { // rotating platforms } else { // rotating platforms
if (player_y_delta(&player->obj) < 0) { if (player_y_delta(&player->obj) < 0) {
break; // 10D51 goto bonus_objects;
} }
if (obj->y_pos < player_obj->y_pos) { if (obj->y_pos < player_obj->y_pos) {
continue; continue;
@ -2042,7 +2056,7 @@ static void level_update_player(struct player_t *player) {
player_y_delta(&player->obj) = 0; player_y_delta(&player->obj) = 0;
player_flags(&player->obj) |= 1; player_flags(&player->obj) |= 1;
player_jump_counter(&player->obj) = 7; player_jump_counter(&player->obj) = 7;
goto bonus_objects; // 10D51 goto bonus_objects;
} }
} }
if (player_y_delta(&player->obj) >= 0) { if (player_y_delta(&player->obj) >= 0) {
@ -2073,7 +2087,7 @@ static void level_update_player(struct player_t *player) {
if (object64_counter(obj) != 0) { if (object64_counter(obj) != 0) {
--object64_counter(obj); --object64_counter(obj);
} }
goto bonus_objects; // 10D51; goto bonus_objects;
} }
} }
player_obj->y_pos -= 8; player_obj->y_pos -= 8;
@ -2232,15 +2246,15 @@ static void level_draw_objects() {
} else { } else {
// video_set_palette_index(sprite_palettes[num]); // video_set_palette_index(sprite_palettes[num]);
} }
const int spr_flag = ((obj->spr_num & 0x8000) != 0) ? 1 : 0; const int spr_hflip = ((obj->spr_num & 0x8000) != 0) ? 1 : 0;
const int spr_y_pos = obj->y_pos - ((g_vars.tilemap_y << 4) + g_vars.tilemap_scroll_dy) - (sprite_offsets[num] >> 8); const int spr_y_pos = obj->y_pos - ((g_vars.tilemap_y << 4) + g_vars.tilemap_scroll_dy) - (sprite_offsets[num] >> 8);
int _dx = obj->x_pos - ((g_vars.tilemap_x << 4) + (g_vars.tilemap_scroll_dx << 2)); int spr_x_pos = obj->x_pos - ((g_vars.tilemap_x << 4) + (g_vars.tilemap_scroll_dx << 2));
int _cl = (sprite_sizes[num] & 255); int spr_w = (sprite_sizes[num] & 255);
if (spr_flag) { if (spr_hflip) {
_cl = (sprite_offsets[num] & 255) - _cl; spr_w = (sprite_offsets[num] & 255) - spr_w;
} }
const int spr_x_pos = _dx - _cl; spr_x_pos -= spr_w;
video_draw_sprite(num, spr_x_pos, spr_y_pos, spr_flag); video_draw_sprite(num, spr_x_pos, spr_y_pos, spr_hflip);
} }
} }
@ -2613,14 +2627,14 @@ static void level_update_tiles(struct object_t *obj, int ax, int dx, int bp) {
level_tile_func(tile_funcs3[_al], obj, bp, _al * 2); level_tile_func(tile_funcs3[_al], obj, bp, _al * 2);
} }
static bool sub_15D99(struct player_t *player, int ax, int dx) { static bool level_adjust_player_spr_num_helper(struct player_t *player, int ax, int dx) {
if ((player_flags2(&player->obj) & 1) == 0) { if ((player_flags2(&player->obj) & 1) == 0) {
return false; return false;
} }
if (player->change_hdir_counter < 30) { if (player->change_hdir_counter < 30) {
const int offset = (dx >> 4) * g_vars.tilemap_w + (ax >> 4); const int offset = (dx >> 4) * g_vars.tilemap_w + (ax >> 4);
uint8_t _al = level_get_tile(offset - g_vars.tilemap_w); const uint8_t num = level_get_tile(offset - g_vars.tilemap_w);
if (tile_funcs3[_al] != 0x5E58) { if (tile_funcs3[num] != 0x5E58) {
return true; return true;
} }
} }
@ -2628,7 +2642,7 @@ static bool sub_15D99(struct player_t *player, int ax, int dx) {
return true; return true;
} }
static void sub_15BA5(struct player_t *player) { static void level_adjust_player_spr_num(struct player_t *player) {
struct object_t *obj = &g_vars.objects_table[player_obj_num(&player->obj)]; struct object_t *obj = &g_vars.objects_table[player_obj_num(&player->obj)];
obj->x_pos = player->obj.x_pos; obj->x_pos = player->obj.x_pos;
obj->y_pos = player->obj.y_pos; obj->y_pos = player->obj.y_pos;
@ -2655,7 +2669,7 @@ static void sub_15BA5(struct player_t *player) {
} }
} }
player_flags(&player->obj) &= ~PLAYER_FLAGS_STAIRS; player_flags(&player->obj) &= ~PLAYER_FLAGS_STAIRS;
if (!sub_15D99(player, player->obj.x_pos, player->obj.y_pos)) { if (!level_adjust_player_spr_num_helper(player, player->obj.x_pos, player->obj.y_pos)) {
level_update_tiles(&player->obj, player->obj.x_pos, player->obj.y_pos, 0); level_update_tiles(&player->obj, player->obj.x_pos, player->obj.y_pos, 0);
} }
} }
@ -2674,10 +2688,7 @@ static void sub_15BA5(struct player_t *player) {
} }
static void level_adjust_player_position() { static void level_adjust_player_position() {
if (g_vars.player_hit_counter != 0) { level_adjust_player_spr_num(&g_vars.players_table[0]);
--g_vars.player_hit_counter;
}
sub_15BA5(&g_vars.players_table[0]);
assert(g_vars.player < 2); assert(g_vars.player < 2);
} }
@ -2688,7 +2699,7 @@ static void level_sync() {
--g_vars.level_time; --g_vars.level_time;
} }
g_sys.update_screen(g_res.vga, 1); g_sys.update_screen(g_res.vga, 1);
render_clear_sprites(); g_sys.render_clear_sprites();
const int diff = (g_vars.timestamp + (1000 / 30)) - g_sys.get_timestamp(); const int diff = (g_vars.timestamp + (1000 / 30)) - g_sys.get_timestamp();
g_sys.sleep(MAX(diff, 10)); g_sys.sleep(MAX(diff, 10));
g_vars.timestamp = g_sys.get_timestamp(); g_vars.timestamp = g_sys.get_timestamp();
@ -2840,7 +2851,6 @@ static void load_level_data(uint16_t level) {
static void reset_level_data() { static void reset_level_data() {
memset(g_vars.objects_table, 0xFF, sizeof(g_vars.objects_table)); memset(g_vars.objects_table, 0xFF, sizeof(g_vars.objects_table));
g_vars.change_next_level_flag = 0; g_vars.change_next_level_flag = 0;
g_vars.player_hit_counter = 0;
g_vars.player_xscroll = 0; g_vars.player_xscroll = 0;
g_vars.player_map_offset = 0; g_vars.player_map_offset = 0;
g_vars.throw_vinyl_counter = 0; g_vars.throw_vinyl_counter = 0;
@ -2889,12 +2899,12 @@ static void level_init_tilemap() {
g_vars.tilemap_scroll_dx = 0; g_vars.tilemap_scroll_dx = 0;
g_vars.tilemap_scroll_dy = 0; g_vars.tilemap_scroll_dy = 0;
while (1) { while (1) {
const int current_y = g_vars.tilemap_y; const int bottom_y = g_vars.tilemap_y + 11;
const int _dx = g_vars.tilemap_y + 11; const int player_y = g_vars.players_table[0].obj.y_pos >> 4;
const int _ax = g_vars.players_table[0].obj.y_pos >> 4; if (bottom_y > player_y) {
if (_dx > _ax) {
break; break;
} }
const int current_y = g_vars.tilemap_y;
level_adjust_vscroll_down(16); level_adjust_vscroll_down(16);
if (g_vars.tilemap_y == current_y) { if (g_vars.tilemap_y == current_y) {
break; break;
@ -2902,15 +2912,15 @@ static void level_init_tilemap() {
} }
level_adjust_vscroll_down(16); level_adjust_vscroll_down(16);
level_adjust_vscroll_down(16); level_adjust_vscroll_down(16);
int bp = _undefined; int prev_x = _undefined;
while (1) { while (1) {
const int _dx = g_vars.tilemap_x + 10; const int right_x = g_vars.tilemap_x + 10;
const int _ax = g_vars.players_table[0].obj.x_pos >> 4; const int player_x = g_vars.players_table[0].obj.x_pos >> 4;
if (_dx >= _ax || bp == _dx) { if (right_x >= player_x || prev_x == right_x) {
break; break;
} }
level_adjust_hscroll_right(4); level_adjust_hscroll_right(4);
bp = _dx; prev_x = right_x;
} }
} }

View File

@ -33,6 +33,14 @@ void res_init(const char *path, int vga_size) {
snprintf(filepath, sizeof(filepath), "%s/board.eat", _datapath); snprintf(filepath, sizeof(filepath), "%s/board.eat", _datapath);
unpack(filepath, g_res.board, BOARD_SIZE); unpack(filepath, g_res.board, BOARD_SIZE);
static const int MOTIF_SIZE = 320 * 25 * 9;
g_res.motif = (uint8_t *)malloc(MOTIF_SIZE);
if (!g_res.motif) {
print_error("Failed to allocate motif buffer, %d bytes", MOTIF_SIZE);
}
snprintf(filepath, sizeof(filepath), "%s/motif.eat", _datapath);
unpack(filepath, g_res.motif, MOTIF_SIZE);
static const int SPRITES_SIZE = 108044; static const int SPRITES_SIZE = 108044;
g_res.sprites = (uint8_t *)malloc(SPRITES_SIZE); g_res.sprites = (uint8_t *)malloc(SPRITES_SIZE);
if (!g_res.sprites) { if (!g_res.sprites) {
@ -70,6 +78,8 @@ void res_fini() {
g_res.font = 0; g_res.font = 0;
free(g_res.board); free(g_res.board);
g_res.board = 0; g_res.board = 0;
free(g_res.motif);
g_res.motif = 0;
free(g_res.sprites); free(g_res.sprites);
g_res.sprites = 0; g_res.sprites = 0;
free(g_res.tmp); free(g_res.tmp);

View File

@ -7,6 +7,7 @@
struct resource_t { struct resource_t {
uint8_t *font; uint8_t *font;
uint8_t *board; uint8_t *board;
uint8_t *motif;
uint8_t *sprites; uint8_t *sprites;
uint8_t *samples; uint8_t *samples;
uint8_t *tmp; uint8_t *tmp;

View File

@ -22,7 +22,7 @@ void video_draw_dot_pattern(int offset) {
} }
void video_draw_sprite(int num, int x, int y, int flag) { void video_draw_sprite(int num, int x, int y, int flag) {
render_add_sprite(RENDER_SPR_GAME, num, x, y, flag != 0); g_sys.render_add_sprite(RENDER_SPR_GAME, num, x, y, flag != 0);
} }
void video_draw_string(const char *s, int offset, int hspace) { void video_draw_string(const char *s, int offset, int hspace) {
@ -44,8 +44,8 @@ void video_copy_vga(int size) {
if (size == 0xB500) { if (size == 0xB500) {
memcpy(g_res.background, g_res.tmp + 768, 64000); memcpy(g_res.background, g_res.tmp + 768, 64000);
} else { } else {
g_sys.set_screen_palette(g_res.tmp, 0, 256, 6);
assert(size == 0x7D00); assert(size == 0x7D00);
g_sys.set_screen_palette(g_res.tmp, 0, 256, 6);
const uint8_t *src = g_res.tmp + 768; const uint8_t *src = g_res.tmp + 768;
if (GAME_SCREEN_W * GAME_SCREEN_H == 64000) { if (GAME_SCREEN_W * GAME_SCREEN_H == 64000) {
memcpy(g_res.vga, src, 64000); memcpy(g_res.vga, src, 64000);
@ -60,9 +60,6 @@ void video_copy_vga(int size) {
} }
} }
void video_vsync(int delay) {
}
void fade_in_palette() { void fade_in_palette() {
if (!g_sys.input.quit) { if (!g_sys.input.quit) {
g_sys.fade_in_palette(); g_sys.fade_in_palette();
@ -167,6 +164,28 @@ void ja_decode_tile(const uint8_t *buffer, uint8_t pal_mask, uint8_t *dst, int d
} }
} }
static void decode_motif(const uint8_t *src, uint8_t *dst, uint8_t color) {
for (int x = 0; x < 40; ++x) {
for (int b = 0; b < 8; ++b) {
const uint8_t mask = 1 << (7 - b);
if (src[x] & mask) {
dst[x * 8 + b] = color;
}
}
}
}
void ja_decode_motif(int num, uint8_t color) {
const uint8_t *src = g_res.motif + 25 * 320 * num;
int y = 0;
for (int j = 0; j < 25; ++j) {
for (int i = 0; i < 8; ++i) {
decode_motif(src + i * 40 + j * 320, g_res.vga + y * GAME_SCREEN_W, color);
++y;
}
}
}
void video_load_sprites() { void video_load_sprites() {
struct sys_rect_t r[MAX_SPRITES]; struct sys_rect_t r[MAX_SPRITES];
uint8_t *data = (uint8_t *)calloc(MAX_SPRITESHEET_W * MAX_SPRITESHEET_H, 1); uint8_t *data = (uint8_t *)calloc(MAX_SPRITESHEET_W * MAX_SPRITESHEET_H, 1);
@ -211,15 +230,12 @@ void video_load_sprites() {
r[i].w = w; r[i].w = w;
r[i].h = h; r[i].h = h;
current_x += w; current_x += w;
if (h > max_h) {
max_h = h;
}
} }
assert(count <= MAX_SPRITES); assert(count <= MAX_SPRITES);
assert(max_w <= MAX_SPRITESHEET_W); assert(max_w <= MAX_SPRITESHEET_W);
assert(current_y + max_h <= MAX_SPRITESHEET_H); assert(current_y + max_h <= MAX_SPRITESHEET_H);
render_unload_sprites(RENDER_SPR_GAME); g_sys.render_unload_sprites(RENDER_SPR_GAME);
render_load_sprites(RENDER_SPR_GAME, count, r, data, MAX_SPRITESHEET_W, current_y + max_h, 0, 0x0); g_sys.render_load_sprites(RENDER_SPR_GAME, count, r, data, MAX_SPRITESHEET_W, current_y + max_h, 0, 0x0);
free(data); free(data);
} }
} }

View File

@ -268,11 +268,8 @@ const uint8_t monster_spr_anim_data2[] = {
0xDA,0x00,0xF7,0xFF,0x00,0x7D,0xDC,0x00,0xFF,0xFF 0xDA,0x00,0xF7,0xFF,0x00,0x7D,0xDC,0x00,0xFF,0xFF
}; };
const uint8_t monster_spr_anim_data3[] = { const uint8_t monster_spr_anim_data3[] = {
0xE1,0x00,0xFF,0xFF 0xE1,0x00,0xFF,0xFF,0xE1,0x00,0xE1,0x00,0xE2,0x00,0xE3,0x00,0xE3,0x00,0xE2,0x00,
}; 0xE1,0x00,0xE1,0x00,0xF8,0xFF,0xE4,0x00,0xFF,0xFF,0x00,0x7D,0xE5,0x00,0xFF,0xFF
const uint8_t monster_spr_anim_data4[] = {
0xE1,0x00,0xE1,0x00,0xE2,0x00,0xE3,0x00,0xE3,0x00,0xE2,0x00,0xE1,0x00,0xE1,0x00,
0xF8,0xFF,0xE4,0x00,0xFF,0xFF,0x00,0x7D,0xE5,0x00,0xFF,0xFF
}; };
const uint8_t monster_spr_anim_data6[] = { const uint8_t monster_spr_anim_data6[] = {
0xEC,0x00,0xEC,0x00,0xED,0x00,0xED,0x00,0xFC,0xFF,0xEE,0x00,0xFF,0xFF,0x00,0x7D, 0xEC,0x00,0xEC,0x00,0xED,0x00,0xED,0x00,0xFC,0xFF,0xEE,0x00,0xFF,0xFF,0x00,0x7D,

View File

@ -13,11 +13,6 @@ struct unpack_eat_t {
static struct unpack_eat_t g_unpack; static struct unpack_eat_t g_unpack;
static uint16_t fread_le16(FILE *fp) {
const uint16_t val = fgetc(fp);
return val | (fgetc(fp) << 8);
}
static int next_bit(struct unpack_eat_t *u) { static int next_bit(struct unpack_eat_t *u) {
const int bit = (u->bits & (1 << (16 - u->len))) != 0; const int bit = (u->bits & (1 << (16 - u->len))) != 0;
--u->len; --u->len;

19
sys.h
View File

@ -11,6 +11,10 @@
#define SYS_AUDIO_FREQ 22050 #define SYS_AUDIO_FREQ 22050
#define RENDER_SPR_GAME 0 /* player sprites */
#define RENDER_SPR_LEVEL 1 /* level sprites */
#define RENDER_SPR_FG 2 /* foreground tiles */
struct input_t { struct input_t {
uint8_t direction; uint8_t direction;
bool quit; bool quit;
@ -51,18 +55,13 @@ struct sys_t {
void (*stop_audio)(); void (*stop_audio)();
void (*lock_audio)(); void (*lock_audio)();
void (*unlock_audio)(); void (*unlock_audio)();
void (*render_load_sprites)(int spr_type, int count, const struct sys_rect_t *r, const uint8_t *data, int w, int h, int palette_offset, uint8_t color_key);
void (*render_unload_sprites)(int spr_type);
void (*render_add_sprite)(int spr_type, int frame, int x, int y, int xflip);
void (*render_clear_sprites)();
void (*render_set_sprites_clipping_rect)(int x, int y, int w, int h);
}; };
extern struct sys_t g_sys; extern struct sys_t g_sys;
#define RENDER_SPR_GAME 0 /* player sprites */
#define RENDER_SPR_LEVEL 1 /* level sprites */
#define RENDER_SPR_FG 2 /* foreground tiles */
extern void render_load_sprites(int spr_type, int count, const struct sys_rect_t *r, const uint8_t *data, int w, int h, int palette_offset, uint8_t color_key);
extern void render_unload_sprites(int spr_type);
extern void render_add_sprite(int spr_type, int frame, int x, int y, int xflip);
extern void render_clear_sprites();
extern void render_set_sprites_clipping_rect(int x, int y, int w, int h);
#endif /* SYS_H__ */ #endif /* SYS_H__ */

View File

@ -511,28 +511,7 @@ static void sdl2_unlock_audio() {
SDL_UnlockAudio(); SDL_UnlockAudio();
} }
struct sys_t g_sys = { static void render_load_sprites(int spr_type, int count, const struct sys_rect_t *r, const uint8_t *data, int w, int h, int palette_offset, uint8_t color_key) {
.init = sdl2_init,
.fini = sdl2_fini,
.set_screen_size = sdl2_set_screen_size,
.set_screen_palette = sdl2_set_screen_palette,
.set_palette_amiga = sdl2_set_palette_amiga,
.set_copper_bars = sdl2_set_copper_bars,
.set_palette_color = sdl2_set_palette_color,
.fade_in_palette = sdl2_fade_in_palette,
.fade_out_palette = sdl2_fade_out_palette,
.update_screen = sdl2_update_screen,
.transition_screen = sdl2_transition_screen,
.process_events = sdl2_process_events,
.sleep = sdl2_sleep,
.get_timestamp = sdl2_get_timestamp,
.start_audio = sdl2_start_audio,
.stop_audio = sdl2_stop_audio,
.lock_audio = sdl2_lock_audio,
.unlock_audio = sdl2_unlock_audio,
};
void render_load_sprites(int spr_type, int count, const struct sys_rect_t *r, const uint8_t *data, int w, int h, int palette_offset, uint8_t color_key) {
assert(spr_type < ARRAYSIZE(_spritesheets)); assert(spr_type < ARRAYSIZE(_spritesheets));
struct spritesheet_t *spr_sheet = &_spritesheets[spr_type]; struct spritesheet_t *spr_sheet = &_spritesheets[spr_type];
spr_sheet->count = count; spr_sheet->count = count;
@ -558,7 +537,7 @@ void render_load_sprites(int spr_type, int count, const struct sys_rect_t *r, co
} }
} }
void render_unload_sprites(int spr_type) { static void render_unload_sprites(int spr_type) {
struct spritesheet_t *spr_sheet = &_spritesheets[spr_type]; struct spritesheet_t *spr_sheet = &_spritesheets[spr_type];
free(spr_sheet->r); free(spr_sheet->r);
if (spr_sheet->texture) { if (spr_sheet->texture) {
@ -567,7 +546,7 @@ void render_unload_sprites(int spr_type) {
memset(spr_sheet, 0, sizeof(struct spritesheet_t)); memset(spr_sheet, 0, sizeof(struct spritesheet_t));
} }
void render_add_sprite(int spr_type, int frame, int x, int y, int xflip) { static void render_add_sprite(int spr_type, int frame, int x, int y, int xflip) {
assert(_sprites_count < ARRAYSIZE(_sprites)); assert(_sprites_count < ARRAYSIZE(_sprites));
struct sprite_t *spr = &_sprites[_sprites_count]; struct sprite_t *spr = &_sprites[_sprites_count];
spr->sheet = spr_type; spr->sheet = spr_type;
@ -578,13 +557,39 @@ void render_add_sprite(int spr_type, int frame, int x, int y, int xflip) {
++_sprites_count; ++_sprites_count;
} }
void render_clear_sprites() { static void render_clear_sprites() {
_sprites_count = 0; _sprites_count = 0;
} }
void render_set_sprites_clipping_rect(int x, int y, int w, int h) { static void render_set_sprites_clipping_rect(int x, int y, int w, int h) {
_sprites_cliprect.x = x; _sprites_cliprect.x = x;
_sprites_cliprect.y = y; _sprites_cliprect.y = y;
_sprites_cliprect.w = w; _sprites_cliprect.w = w;
_sprites_cliprect.h = h; _sprites_cliprect.h = h;
} }
struct sys_t g_sys = {
.init = sdl2_init,
.fini = sdl2_fini,
.set_screen_size = sdl2_set_screen_size,
.set_screen_palette = sdl2_set_screen_palette,
.set_palette_amiga = sdl2_set_palette_amiga,
.set_copper_bars = sdl2_set_copper_bars,
.set_palette_color = sdl2_set_palette_color,
.fade_in_palette = sdl2_fade_in_palette,
.fade_out_palette = sdl2_fade_out_palette,
.update_screen = sdl2_update_screen,
.transition_screen = sdl2_transition_screen,
.process_events = sdl2_process_events,
.sleep = sdl2_sleep,
.get_timestamp = sdl2_get_timestamp,
.start_audio = sdl2_start_audio,
.stop_audio = sdl2_stop_audio,
.lock_audio = sdl2_lock_audio,
.unlock_audio = sdl2_unlock_audio,
.render_load_sprites = render_load_sprites,
.render_unload_sprites = render_unload_sprites,
.render_add_sprite = render_add_sprite,
.render_clear_sprites = render_clear_sprites,
.render_set_sprites_clipping_rect = render_set_sprites_clipping_rect
};

18
util.c
View File

@ -1,5 +1,6 @@
#include <stdarg.h> #include <stdarg.h>
#include <sys/param.h>
#include "util.h" #include "util.h"
int g_debug_mask = 0; int g_debug_mask = 0;
@ -58,3 +59,20 @@ void print_info(const char *msg, ...) {
va_end(va); va_end(va);
fprintf(stdout, "%s\n", buf); fprintf(stdout, "%s\n", buf);
} }
FILE *fopen_nocase(const char *path, const char *filename) {
char buf[MAXPATHLEN];
snprintf(buf, sizeof(buf), "%s/%s", path, filename);
FILE *fp = fopen(buf, "rb");
if (!fp) {
char *p = buf + strlen(path) + 1;
string_upper(p);
fp = fopen(buf, "rb");
}
return fp;
}
uint16_t fread_le16(FILE *fp) {
const uint16_t val = fgetc(fp);
return val | (fgetc(fp) << 8);
}

4
util.h
View File

@ -16,9 +16,13 @@ extern int g_debug_mask;
extern void string_lower(char *p); extern void string_lower(char *p);
extern void string_upper(char *p); extern void string_upper(char *p);
extern void print_debug(int debug_channel, const char *msg, ...); extern void print_debug(int debug_channel, const char *msg, ...);
extern void print_warning(const char *msg, ...); extern void print_warning(const char *msg, ...);
extern void print_error(const char *msg, ...); extern void print_error(const char *msg, ...);
extern void print_info(const char *msg, ...); extern void print_info(const char *msg, ...);
extern FILE * fopen_nocase(const char *path, const char *filename);
extern uint16_t fread_le16(FILE *fp);
#endif /* UTIL_H__ */ #endif /* UTIL_H__ */