Import blues from fd9efcd2

This commit is contained in:
Gregory Montoir 2019-06-09 08:43:49 +08:00
parent 2345fb7fe4
commit 40ec27ef16
6 changed files with 230 additions and 32 deletions

View File

@ -59,6 +59,7 @@ static void level_update_boss_gorilla_collide_proj(struct object_t *obj_player,
return; return;
} }
level_update_objects_boss_hit_player(); level_update_objects_boss_hit_player();
play_sound(1);
obj_player->hit_counter = 44; obj_player->hit_counter = 44;
g_vars.player_anim_0x40_flag = 0; g_vars.player_anim_0x40_flag = 0;
obj_player->data.p.y_velocity = -128; obj_player->data.p.y_velocity = -128;
@ -75,7 +76,12 @@ static void level_update_boss_gorilla_hit_player() {
level_update_boss_gorilla_collide_proj(&g_vars.objects_tbl[1], g_vars.boss.obj1); level_update_boss_gorilla_collide_proj(&g_vars.objects_tbl[1], g_vars.boss.obj1);
if (level_objects_collide(&g_vars.objects_tbl[1], g_vars.boss.obj3)) { if (level_objects_collide(&g_vars.objects_tbl[1], g_vars.boss.obj3)) {
if (g_vars.player_jump_monster_flag != 0) { if (g_vars.player_jump_monster_flag != 0) {
g_vars.objects_tbl[1].data.p.y_velocity = (g_vars.input.key_up != 0) ? -128 : -64; int y_vel = -64;
if (g_vars.input.key_up != 0) {
play_sound(3);
y_vel = -128;
}
g_vars.objects_tbl[1].data.p.y_velocity = y_vel;
} }
} }
} }
@ -182,6 +188,7 @@ static void level_update_boss_gorilla_helper2() {
if (abs(g_vars.level_draw_counter - g_vars.boss.draw_counter) <= 22) { if (abs(g_vars.level_draw_counter - g_vars.boss.draw_counter) <= 22) {
break; break;
} }
play_sound(8);
g_vars.boss.draw_counter = g_vars.level_draw_counter; g_vars.boss.draw_counter = g_vars.level_draw_counter;
for (int j = 103; j <= 107; ++j) { for (int j = 103; j <= 107; ++j) {
g_vars.objects_tbl[j].spr_num |= 0x4000; g_vars.objects_tbl[j].spr_num |= 0x4000;

View File

@ -117,7 +117,33 @@ static void do_present_screen() {
} }
} }
static const uint8_t joystick_palette_data[] = {
0x08,0x14,0x22,0x10,0x00,0x00,0x18,0x00,0x00,0x20,0x00,0x08,0x06,0x0F,0x1A,0x28,
0x10,0x08,0x28,0x18,0x08,0x30,0x20,0x08,0x30,0x28,0x08,0x38,0x30,0x10,0x38,0x30,
0x18,0x38,0x30,0x20,0x38,0x30,0x28,0x38,0x30,0x30,0x38,0x38,0x38,0x00,0x00,0x00
};
static void do_demo_screen() { static void do_demo_screen() {
uint8_t *data = load_file("JOYSTICK.SQZ");
if (data) {
video_copy_img(data);
g_sys.set_screen_palette(joystick_palette_data, 0, 16, 6);
update_screen_img(g_res.background);
g_sys.fade_in_palette();
free(data);
wait_input(1000);
}
}
static void do_castle_screen() {
uint8_t *data = load_file("CASTLE.SQZ");
if (data) {
g_sys.set_screen_palette(data, 0, 256, 6);
update_screen_img(data + 768);
g_sys.fade_in_palette();
free(data);
wait_input(1000);
}
} }
static void do_menu() { static void do_menu() {
@ -144,6 +170,15 @@ static void do_menu() {
} }
} }
static void do_photos_screen() {
}
void input_check_ctrl_alt_e() {
if (g_vars.input.keystate[0x1D] && g_vars.input.keystate[0x38] && g_vars.input.keystate[0x12]) {
do_photos_screen();
}
}
void input_check_ctrl_alt_w() { void input_check_ctrl_alt_w() {
if (g_vars.input.keystate[0x1D] && g_vars.input.keystate[0x38] && g_vars.input.keystate[0x11]) { if (g_vars.input.keystate[0x1D] && g_vars.input.keystate[0x38] && g_vars.input.keystate[0x11]) {
do_credits(); do_credits();
@ -151,6 +186,24 @@ void input_check_ctrl_alt_w() {
} }
} }
void do_theend_screen() {
uint8_t *data = load_file("THEEND.SQZ");
if (data) {
g_sys.set_screen_palette(data, 0, 256, 6);
update_screen_img(data + 768);
g_sys.fade_in_palette();
free(data);
wait_input(1000);
}
time_t now;
time(&now);
struct tm *t = localtime(&now);
if (t->tm_year + 1900 < 1994) {
return;
}
do_photos_screen();
}
uint32_t timer_get_counter() { uint32_t timer_get_counter() {
const uint32_t current = g_sys.get_timestamp(); const uint32_t current = g_sys.get_timestamp();
return ((current - g_vars.starttime) * 1193182 / 0x4000) / 1000; return ((current - g_vars.starttime) * 1193182 / 0x4000) / 1000;
@ -204,7 +257,7 @@ static void game_run(const char *data_path) {
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;
do_programmed_in_1992_screen(); do_programmed_in_1992_screen();
if (!g_sys.input.space) { if (!g_sys.input.space && !g_sys.input.quit) {
do_titus_screen(); do_titus_screen();
play_music(3); play_music(3);
do_present_screen(); do_present_screen();
@ -226,6 +279,10 @@ static void game_run(const char *data_path) {
uint8_t level_num; uint8_t level_num;
do { do {
level_num = g_vars.level_num; level_num = g_vars.level_num;
if (g_vars.level_num >= 8 && g_vars.level_num < 10 && 0 /* !g_vars.level_expert_flag */ ) {
do_castle_screen();
break;
}
do_level(); do_level();
print_debug(DBG_GAME, "previous level %d current %d", level_num, g_vars.level_num); print_debug(DBG_GAME, "previous level %d current %d", level_num, g_vars.level_num);
} while (!g_res.dos_demo && g_vars.level_num != level_num); } while (!g_res.dos_demo && g_vars.level_num != level_num);

View File

@ -15,6 +15,7 @@ extern struct options_t g_options;
#define CHEATS_NO_HIT (1 << 0) #define CHEATS_NO_HIT (1 << 0)
#define CHEATS_UNLIMITED_LIFES (1 << 1) #define CHEATS_UNLIMITED_LIFES (1 << 1)
#define CHEATS_UNLIMITED_ENERGY (1 << 2) #define CHEATS_UNLIMITED_ENERGY (1 << 2)
#define CHEATS_NO_WIND (1 << 3)
struct club_anim_t { struct club_anim_t {
const uint8_t *anim; /* uint16_t[4] : player spr, club spr, x, y */ const uint8_t *anim; /* uint16_t[4] : player spr, club spr, x, y */
@ -257,8 +258,9 @@ struct vars_t {
uint16_t spr_num; uint16_t spr_num;
} current_bonus; /* bonus added */ } current_bonus; /* bonus added */
struct { struct {
uint16_t value; uint16_t value; /* wind */
uint16_t counter; uint16_t counter;
const uint16_t *pattern;
uint16_t random_tbl[256]; uint16_t random_tbl[256];
} snow; } snow;
struct { struct {
@ -288,7 +290,7 @@ extern const uint8_t score_spr_lut[110];
extern const uint8_t *object_anim_tbl[]; extern const uint8_t *object_anim_tbl[];
extern const struct club_anim_t club_anim_tbl[4]; extern const struct club_anim_t club_anim_tbl[4];
extern const uint8_t player_anim_lut[32]; extern const uint8_t player_anim_lut[32];
extern const uint8_t player_anim_data[100]; extern const uint8_t player_flying_anim_data[100]; /* uint16_t: player_spr_num, uint16_t: flying_spr_num, int8_t: dx, int8_t: dy */
extern const uint8_t vscroll_offsets_data[132]; extern const uint8_t vscroll_offsets_data[132];
extern const uint8_t cos_tbl[256]; extern const uint8_t cos_tbl[256];
extern const uint8_t sin_tbl[256]; extern const uint8_t sin_tbl[256];
@ -296,11 +298,15 @@ extern const uint16_t monster_spr_tbl[48];
extern const uint8_t monster_anim_tbl[1100]; extern const uint8_t monster_anim_tbl[1100];
extern const uint8_t boss_minotaur_seq_data[86]; extern const uint8_t boss_minotaur_seq_data[86];
extern const uint16_t boss_gorilla_data[19 * 10]; extern const uint16_t boss_gorilla_data[19 * 10];
extern const uint16_t boss_gorilla_spr_tbl[46 * 3]; /* uint16_t: spr1_num, uint16_t: spr2_num, uint8_t: dx, uint8_t: dy */ extern const uint16_t boss_gorilla_spr_tbl[46 * 3]; /* uint16_t: spr1_num, uint16_t: spr2_num, int8_t: dx, int8_t: dy */
extern const uint16_t snow_pattern1_data[11];
extern const uint16_t snow_pattern2_data[10];
/* game.c */ /* game.c */
extern void update_input(); extern void update_input();
extern void input_check_ctrl_alt_e();
extern void input_check_ctrl_alt_w(); extern void input_check_ctrl_alt_w();
extern void do_theend_screen();
extern uint32_t timer_get_counter(); extern uint32_t timer_get_counter();
extern void random_reset(); extern void random_reset();
extern uint8_t random_get_number(); extern uint8_t random_get_number();

View File

@ -262,6 +262,7 @@ static void load_level_data(int num) {
print_debug(DBG_GAME, "start_pos %d,%d", g_res.level.start_x_pos, g_res.level.start_y_pos); print_debug(DBG_GAME, "start_pos %d,%d", g_res.level.start_x_pos, g_res.level.start_y_pos);
load_level_data_init_animated_tiles(); load_level_data_init_animated_tiles();
load_level_data_init_transparent_tiles(); load_level_data_init_transparent_tiles();
g_vars.snow.pattern = (g_vars.level_num != 15) ? snow_pattern1_data : snow_pattern2_data;
g_vars.snow.counter = 0; g_vars.snow.counter = 0;
g_vars.tilemap_start_x_pos = g_res.level.start_x_pos; g_vars.tilemap_start_x_pos = g_res.level.start_x_pos;
g_vars.tilemap_start_y_pos = g_res.level.start_y_pos; g_vars.tilemap_start_y_pos = g_res.level.start_y_pos;
@ -667,6 +668,10 @@ static void level_init_object_hit_from_xy_pos(int16_t x_pos, int16_t y_pos) {
} }
static void level_update_tile_type_2() { static void level_update_tile_type_2() {
if (g_vars.level_num == 14) {
g_vars.player_death_flag = 0xFF;
return;
}
if (g_options.cheats & CHEATS_NO_HIT) { if (g_options.cheats & CHEATS_NO_HIT) {
return; return;
} }
@ -974,11 +979,14 @@ static void level_reset_objects() {
} }
static void level_reset() { static void level_reset() {
g_vars.tilemap_noscroll_flag = 0;
g_vars.player_nojump_counter = 0; g_vars.player_nojump_counter = 0;
g_vars.player_action_counter = 0; g_vars.player_action_counter = 0;
g_vars.restart_level_flag = 0; g_vars.restart_level_flag = 0;
g_vars.player_death_flag = 0; g_vars.player_death_flag = 0;
g_vars.level_completed_flag = 0; g_vars.level_completed_flag = 0;
g_vars.light.palette_flag1 = 0;
g_vars.light.palette_flag2 = 0;
g_vars.objects_tbl[1].data.p.special_anim_num = 0; g_vars.objects_tbl[1].data.p.special_anim_num = 0;
g_vars.tilemap.prev_x = _undefined; g_vars.tilemap.prev_x = _undefined;
@ -1203,6 +1211,7 @@ static bool level_collide_axe_monsters(struct object_t *axe_obj) {
obj->data.m.flags |= 0x40; obj->data.m.flags |= 0x40;
obj->data.m.energy -= g_vars.player_club_power; obj->data.m.energy -= g_vars.player_club_power;
if (obj->data.m.energy < 0) { if (obj->data.m.energy < 0) {
play_sound(2);
level_monster_die(obj, m, axe_obj); level_monster_die(obj, m, axe_obj);
} else { } else {
obj->x_pos -= obj->data.m.x_velocity >> 2; obj->x_pos -= obj->data.m.x_velocity >> 2;
@ -1901,7 +1910,9 @@ static void level_update_player_hdir_x_velocity(int x_vel) {
} }
static void level_update_screen_x_velocity() { static void level_update_screen_x_velocity() {
g_vars.objects_tbl[1].x_velocity -= g_vars.snow.value >> 3; if ((g_options.cheats & CHEATS_NO_WIND) == 0) {
g_vars.objects_tbl[1].x_velocity -= g_vars.snow.value >> 3;
}
if (g_vars.objects_tbl[1].x_velocity < -96) { if (g_vars.objects_tbl[1].x_velocity < -96) {
g_vars.objects_tbl[1].x_velocity = -96; g_vars.objects_tbl[1].x_velocity = -96;
} }
@ -1990,6 +2001,13 @@ static void level_update_player_anim_3_6_7(uint8_t al) {
g_vars.player_anim_0x40_flag = (g_vars.player_current_anim_type & 0x40) ^ 0x40; g_vars.player_anim_0x40_flag = (g_vars.player_current_anim_type & 0x40) ^ 0x40;
if (g_vars.player_anim_0x40_flag == 0) { if (g_vars.player_anim_0x40_flag == 0) {
g_vars.player_club_anim_duration = club_anim_tbl[g_vars.player_club_type].a; g_vars.player_club_anim_duration = club_anim_tbl[g_vars.player_club_type].a;
if (g_vars.player_club_type == 0) {
play_sound(5);
} else if (g_vars.player_club_type == 1) {
play_sound(0);
} else {
play_sound(10);
}
int16_t dy = 0; int16_t dy = 0;
al = g_vars.objects_tbl[1].data.p.current_anim_num; al = g_vars.objects_tbl[1].data.p.current_anim_num;
if (al != 6) { if (al != 6) {
@ -2302,7 +2320,51 @@ static void level_update_player_flying() {
if (g_vars.player_flying_flag == 0) { if (g_vars.player_flying_flag == 0) {
return; return;
} }
print_warning("Unimplemented level_update_player_flying"); if (g_vars.player_gravity_flag != 0) {
g_vars.objects_tbl[1].spr_num &= 0x8000;
const int x_vel = abs(g_vars.objects_tbl[1].x_velocity);
int num = 48;
if (x_vel < 64) {
++num;
if (x_vel < 32) {
++num;
}
}
if (g_vars.player_flying_anim_index < 3) {
num = 51 - g_vars.player_flying_anim_index;
}
g_vars.objects_tbl[1].spr_num |= num;
}
const uint8_t *p = &player_flying_anim_data[14];
if ((g_vars.input.key_up | g_vars.input.key_down) == 0 && g_vars.player_flying_anim_index != 3) {
if (g_vars.player_flying_anim_index < 3) {
++g_vars.player_flying_anim_index;
} else {
--g_vars.player_flying_anim_index;
}
}
const uint16_t player_spr_num = g_vars.objects_tbl[1].spr_num;
for (uint16_t num; (num = READ_LE_UINT16(p)) != 0; p += 6) {
if (num != (player_spr_num & 0x1FFF)) {
continue;
}
int x_delta = (int8_t)p[4];
int spr_num = READ_LE_UINT16(p + 2);
if (spr_num >= 121) {
spr_num = READ_LE_UINT16(player_flying_anim_data + g_vars.player_flying_anim_index * 2);
}
if (player_spr_num & 0x8000) {
spr_num |= 0x8000;
x_delta = -x_delta;
}
if (g_vars.player_unk_counter1 > 24 && (spr_num & 0x1FFF) < 121) {
++spr_num;
}
g_vars.objects_tbl[0].spr_num = spr_num;
g_vars.objects_tbl[0].x_pos += x_delta;
g_vars.objects_tbl[0].y_pos += (int8_t)p[5];
break;
}
} }
static void level_update_player() { static void level_update_player() {
@ -2514,6 +2576,7 @@ static void level_update_player_collision() {
continue; continue;
} }
if (!g_vars.player_jump_monster_flag || g_vars.objects_tbl[1].data.p.y_velocity < 0) { if (!g_vars.player_jump_monster_flag || g_vars.objects_tbl[1].data.p.y_velocity < 0) {
play_sound(9);
m->flags &= ~1; m->flags &= ~1;
g_vars.objects_tbl[1].hit_counter = 44; g_vars.objects_tbl[1].hit_counter = 44;
g_vars.player_anim_0x40_flag = 0; g_vars.player_anim_0x40_flag = 0;
@ -2534,6 +2597,7 @@ static void level_update_player_collision() {
} }
if (!g_vars.player_gravity_flag) { if (!g_vars.player_gravity_flag) {
/* jumping on a monster */ /* jumping on a monster */
play_sound(3);
int num = obj->data.m.hit_jump_counter >> 2; int num = obj->data.m.hit_jump_counter >> 2;
if (num != 11) { if (num != 11) {
obj->data.m.hit_jump_counter += 4; obj->data.m.hit_jump_counter += 4;
@ -2973,9 +3037,8 @@ static bool level_update_objects_anim() {
if (g_vars.level_completed_flag == 1) { if (g_vars.level_completed_flag == 1) {
if (g_vars.level_num < 10) { if (g_vars.level_num < 10) {
level_completed_bonuses_animation(); level_completed_bonuses_animation();
} else {
++g_vars.level_num;
} }
++g_vars.level_num;
level_reset(); level_reset();
return false; return false;
} else if (g_vars.level_completed_flag & 0x80) { } else if (g_vars.level_completed_flag & 0x80) {
@ -3027,9 +3090,14 @@ static bool level_update_objects_anim() {
} }
} else if (g_vars.player_death_flag == 1) { } else if (g_vars.player_death_flag == 1) {
level_player_death_animation(); level_player_death_animation();
} else if (g_vars.player_death_flag == 0xFF) {
do_theend_screen();
return false;
} else { } else {
return true; return true;
} }
input_check_ctrl_alt_e();
play_music(17);
g_vars.objects_tbl[1].spr_num = 13; g_vars.objects_tbl[1].spr_num = 13;
g_vars.level_num = 0; g_vars.level_num = 0;
g_vars.score = 0; g_vars.score = 0;
@ -3109,28 +3177,25 @@ static void level_update_light_palette() {
if ((g_vars.light.palette_flag1 | g_vars.light.palette_flag2) != 0) { if ((g_vars.light.palette_flag1 | g_vars.light.palette_flag2) != 0) {
++g_vars.light.palette_counter; ++g_vars.light.palette_counter;
uint8_t palette[16 * 3]; uint8_t palette[16 * 3];
const uint8_t *si = palettes_tbl[g_vars.level_num]; const uint8_t *src_pal = palettes_tbl[g_vars.level_num];
const uint8_t *bx = light_palette_data; const uint8_t *dst_pal = light_palette_data;
bool changed = false; bool changed = false;
if (g_vars.light.palette_flag2 != 0) { if (g_vars.light.palette_flag2 != 0) {
SWAP(si, bx); SWAP(src_pal, dst_pal);
} }
for (int i = 0; i < 16 * 3; ++i) { for (int i = 0; i < 16 * 3; ++i) {
int al = *si++; int diff = src_pal[i] - dst_pal[i];
const int ah = *bx++; int step = g_vars.light.palette_counter;
int dh = g_vars.light.palette_counter; if (diff < 0) {
al -= ah; diff = -diff;
if (al < 0) { step = -step;
al = -al;
dh = -dh;
} }
if (al <= g_vars.light.palette_counter) { if (diff <= g_vars.light.palette_counter) {
al = ah; palette[i] = dst_pal[i];
} else { } else {
al = si[-1] - dh; palette[i] = src_pal[i] - step;
changed = true; changed = true;
} }
palette[i] = al;
} }
if (!changed) { if (!changed) {
g_vars.light.palette_flag1 = 0; g_vars.light.palette_flag1 = 0;
@ -3268,6 +3333,16 @@ static void level_draw_flies() {
static void level_draw_snow() { static void level_draw_snow() {
++g_vars.snow.counter; ++g_vars.snow.counter;
if ((g_vars.level_draw_counter & 3) == 0) { if ((g_vars.level_draw_counter & 3) == 0) {
const uint16_t *p = g_vars.snow.pattern;
if (p[0] != 0xFFFF) {
if (p[0] < g_vars.snow.counter) {
g_vars.snow.value += p[1];
if (p[3] < g_vars.snow.counter) {
g_vars.snow.counter += 3;
}
}
g_vars.snow.value = MIN(g_vars.snow.value, p[2]);
}
} }
if (g_vars.snow.value == 0) { if (g_vars.snow.value == 0) {
return; return;
@ -3276,12 +3351,18 @@ static void level_draw_snow() {
uint16_t *p = g_vars.snow.random_tbl; uint16_t *p = g_vars.snow.random_tbl;
for (int i = 0; i < g_vars.snow.value; ++i) { for (int i = 0; i < g_vars.snow.value; ++i) {
p[i] += 79; p[i] += 79;
uint8_t al = p[i];
uint8_t cl = ((al << 1) | (al >> 7)) & 3;
uint16_t pos = (p[i] - g_vars.tilemap.x) & 0x1FFF; uint16_t pos = (p[i] - g_vars.tilemap.x) & 0x1FFF;
if (pos >= 7000) { if (pos >= 7000) {
pos -= 7000; pos -= 7000;
p[i] = pos; p[i] = pos;
} }
const int y_pos = (pos / 40);
const int x_pos = (pos % 40) * 8 + cl * 2;
video_put_pixel(x_pos, y_pos, 15);
if ((g_vars.snow.value - i) > half) { if ((g_vars.snow.value - i) > half) {
video_put_pixel(x_pos, y_pos + 1, 15);
} }
} }
const uint8_t num = random_get_number(); const uint8_t num = random_get_number();
@ -3321,6 +3402,7 @@ static void level_shake_screen() {
} }
static void level_player_death_animation() { static void level_player_death_animation() {
play_sound(7);
g_vars.objects_tbl[1].hit_counter = 0; g_vars.objects_tbl[1].hit_counter = 0;
g_vars.objects_tbl[1].spr_num = 33; g_vars.objects_tbl[1].spr_num = 33;
g_vars.objects_tbl[1].data.p.y_velocity = 15; g_vars.objects_tbl[1].data.p.y_velocity = 15;

View File

@ -317,7 +317,7 @@ const uint8_t player_anim_lut[] = {
0x00,0x03,0x05,0x07,0x02,0x06,0x00,0x00,0x01,0x03,0x04,0x07,0x02,0x06,0x01,0x00, 0x00,0x03,0x05,0x07,0x02,0x06,0x00,0x00,0x01,0x03,0x04,0x07,0x02,0x06,0x01,0x00,
0x01,0x03,0x04,0x07,0x02,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 0x01,0x03,0x04,0x07,0x02,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
}; };
const uint8_t player_anim_data[] = { const uint8_t player_flying_anim_data[] = {
0x7C,0x00,0x7B,0x00,0x7A,0x00,0x79,0x00,0x7D,0x00,0x7E,0x00,0x7F,0x00,0x27,0x00, 0x7C,0x00,0x7B,0x00,0x7A,0x00,0x79,0x00,0x7D,0x00,0x7E,0x00,0x7F,0x00,0x27,0x00,
0x77,0x00,0xFE,0xEF,0x28,0x00,0x77,0x00,0x00,0xF0,0x29,0x00,0x77,0x00,0x00,0xEF, 0x77,0x00,0xFE,0xEF,0x28,0x00,0x77,0x00,0x00,0xF0,0x29,0x00,0x77,0x00,0x00,0xEF,
0x2A,0x00,0x77,0x00,0x01,0xF0,0x2B,0x00,0x77,0x00,0x00,0xF1,0x2C,0x00,0x77,0x00, 0x2A,0x00,0x77,0x00,0x01,0xF0,0x2B,0x00,0x77,0x00,0x00,0xF1,0x2C,0x00,0x77,0x00,
@ -482,3 +482,9 @@ const uint16_t boss_gorilla_spr_tbl[] = {
0x819E,0xE42C,0x0199,0x01A0,0x1012,0x019A,0x819D,0xEE18,0x019A,0x819E,0xEA29,0x019A,0x01A0,0x1309,0x019B,0x819D, 0x819E,0xE42C,0x0199,0x01A0,0x1012,0x019A,0x819D,0xEE18,0x019A,0x819E,0xEA29,0x019A,0x01A0,0x1309,0x019B,0x819D,
0xF91A,0x019B,0x819E,0xF329,0x019B,0x01A0,0x1E0C,0x019A,0x81A0,0x16EC 0xF91A,0x019B,0x819E,0xF329,0x019B,0x01A0,0x1E0C,0x019A,0x81A0,0x16EC
}; };
const uint16_t snow_pattern1_data[] = {
0xFFFF
};
const uint16_t snow_pattern2_data[] = {
0x01B8,0x0001,0x0028,0x0370,0x0006,0x0064,0x0528,0x0001,0x00FF,0xFFFF
};

View File

@ -234,6 +234,7 @@ static int unpack_sqv(FILE *in, struct unpack_sqv_t *u) {
const int uncompressed_size = (READ_LE_UINT16(u->rd) << 16) + READ_LE_UINT16(u->rd + 2); const int uncompressed_size = (READ_LE_UINT16(u->rd) << 16) + READ_LE_UINT16(u->rd + 2);
const int dict_len = READ_LE_UINT16(u->rd + 4); const int dict_len = READ_LE_UINT16(u->rd + 4);
print_debug(DBG_UNPACK, "SQV uncompressed size %d dict_len %d", uncompressed_size, dict_len); print_debug(DBG_UNPACK, "SQV uncompressed size %d dict_len %d", uncompressed_size, dict_len);
assert(dict_len <= 0x400);
fread(u->dict_buf, 1, dict_len, in); fread(u->dict_buf, 1, dict_len, in);
uint8_t *output_buffer = (uint8_t *)malloc(uncompressed_size); uint8_t *output_buffer = (uint8_t *)malloc(uncompressed_size);
@ -245,13 +246,16 @@ static int unpack_sqv(FILE *in, struct unpack_sqv_t *u) {
uint8_t *dst = output_buffer; uint8_t *dst = output_buffer;
const uint8_t *src = u->rd; const uint8_t *src = u->rd;
int len = 1; int bits_count = 1;
int bytes_count = 2; int bytes_count = 2;
int state = 0;
int count = 0;
uint8_t code, prev;
uint16_t bits = 0; uint16_t bits = 0;
uint16_t val = 0; uint16_t val = 0;
while ((dst - output_buffer) < uncompressed_size) { while ((dst - output_buffer) < uncompressed_size) {
--len; --bits_count;
if (len == 0) { if (bits_count == 0) {
bytes_count -= 2; bytes_count -= 2;
if (bytes_count == 0) { if (bytes_count == 0) {
bytes_count = fread(u->rd, 1, 0x1000, in); bytes_count = fread(u->rd, 1, 0x1000, in);
@ -262,20 +266,56 @@ static int unpack_sqv(FILE *in, struct unpack_sqv_t *u) {
src = u->rd; src = u->rd;
} }
bits = READ_BE_UINT16(src); src += 2; bits = READ_BE_UINT16(src); src += 2;
len = 17; bits_count = 16;
continue;
} }
const int carry = (bits & 0x8000) != 0; const bool carry = (bits & 0x8000) != 0;
bits <<= 1; bits <<= 1;
if (carry) { if (carry) {
val += 2; val += 2;
} }
assert(val < 0x400); assert((val & 1) == 0);
assert(val < dict_len);
val = READ_LE_UINT16(u->dict_buf + val); val = READ_LE_UINT16(u->dict_buf + val);
if ((val & 0x8000) == 0) { if ((val & 0x8000) == 0) {
continue; continue;
} }
*dst++ = val & 255; val &= ~0x8000;
switch (state) {
case 0:
code = val & 255;
if (val >> 8) {
switch (code) {
case 0:
state = 1;
break;
case 1:
state = 2;
break;
default:
memset(dst, prev, code);
dst += code;
break;
}
} else {
*dst++ = prev = code;
}
break;
case 1:
memset(dst, prev, val);
dst += val;
state = 0;
break;
case 2:
count = (val & 255) << 8;
state = 3;
break;
case 3:
count |= val & 255;
memset(dst, prev, count);
dst += count;
state = 0;
break;
}
val = 0; val = 0;
} }
assert((dst - output_buffer) == uncompressed_size); assert((dst - output_buffer) == uncompressed_size);