diff --git a/Makefile b/Makefile index ba094e3..4b20b68 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ SDL_LIBS := `sdl2-config --libs` BB := decode.c fileio.c game.c level.c objects.c resource.c screen.c sound.c staticres.c tiles.c unpack.c JA := game.c level.c resource.c screen.c sound.c staticres.c unpack.c -P2 := game.c level.c resource.c screen.c sound.c staticres.c unpack.c +P2 := game.c level.c monsters.c resource.c screen.c sound.c staticres.c unpack.c BB_SRCS := $(foreach f,$(BB),bb/$f) JA_SRCS := $(foreach f,$(JA),ja/$f) diff --git a/p2/game.h b/p2/game.h index 9c56d27..b31cdd2 100644 --- a/p2/game.h +++ b/p2/game.h @@ -37,8 +37,14 @@ struct club_projectile_t { }; 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 unkE; // 0xE + uint8_t unkF; // 0xF + uint8_t unk10; }; struct thing_t { @@ -177,6 +183,9 @@ struct vars_t { uint8_t tilemap_redraw_flag2; /* tilemap needs redraw */ uint8_t tilemap_redraw_flag1; /* force redraw even if tilemap origin did not change */ + struct { + struct object_t *current_object; + } monster; struct { int16_t x_pos, y_pos; uint16_t spr_num; @@ -217,6 +226,8 @@ extern const uint8_t player_anim_data[100]; extern const uint8_t vscroll_offsets_data[132]; extern const uint8_t cos_tbl[256]; extern const uint8_t sin_tbl[256]; +extern const uint16_t monster_spr_tbl[48]; +extern const uint8_t monster_anim_tbl[]; /* game.c */ extern void update_input(); diff --git a/p2/level.c b/p2/level.c index dff2bd0..5984e61 100644 --- a/p2/level.c +++ b/p2/level.c @@ -131,22 +131,19 @@ static void load_level_data_fix_items_spr_num() { static void load_level_data_fix_monsters_spr_num() { if (g_res.level.items_spr_num_offset != 0xFFFF) { - uint8_t *p = g_res.level.monsters_attributes; - while (*p <= 50) { - int16_t num = READ_LE_UINT16(p + 2); - if (num != -1) { + for (int i = 0; i < g_res.level.monsters_count; ++i) { + uint16_t num = g_res.level.monsters_tbl[i].spr_num; + if (num != 0xFFFF) { if (num >= g_res.level.monsters_spr_num_offset) { num -= g_res.level.monsters_spr_num_offset; num += 305; - WRITE_LE_UINT16(p + 2, num); + g_res.level.monsters_tbl[i].spr_num = num; } else if (num >= g_res.level.items_spr_num_offset) { num -= g_res.level.items_spr_num_offset; num += 53; - WRITE_LE_UINT16(p + 2, num); + g_res.level.monsters_tbl[i].spr_num = num; } } - const int8_t len = *p; - p += len; } } g_res.level.items_spr_num_offset = 53; @@ -900,6 +897,12 @@ static void level_reset_objects() { } static void level_reset() { + g_vars.player_nojump_counter = 0; + g_vars.player_action_counter = 0; + g_vars.restart_level_flag = 0; + g_vars.player_death_flag = 0; + g_vars.level_completed_flag = 0; + g_vars.objects_tbl[1].data.p.special_anim_num = 0; g_vars.tilemap_prev_x = _undefined; g_vars.current_hit_object = &g_vars.objects_tbl[6]; @@ -1228,6 +1231,9 @@ static void level_update_objects_axe() { static void level_update_monsters_state() { } +extern void monster_func1(int type, struct object_t *obj); /* update */ +extern bool monster_func2(int type, struct level_monster_t *m); /* init */ + static void level_update_objects_monsters() { if (g_res.level.monsters_state != 0xFF) { level_update_monsters_state(); @@ -1239,14 +1245,70 @@ static void level_update_objects_monsters() { if (obj->spr_num == 0xFFFF) { continue; } - print_warning("Unhandled level_update_objects_monsters object %d", 11 + i); - } - const uint8_t *p = g_res.level.monsters_attributes; - while (*p < 50) { - if (READ_LE_UINT16(p + 2) != 0xFFFF && (p[4] & 4) == 0) { + 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) { + } + const uint8_t *p = obj->data.m.anim; + int16_t num; + while (1) { + num = READ_LE_UINT16(p); + if (num >= 0) { + break; + } + p += num; + } + uint16_t dx = 305 + (num & 0x1FFF); + if (g_vars.player_monsters_unk_counter == 0) { + obj->data.m.anim = p + 2; + } else { + if (g_vars.player_monsters_unk_counter == 7) { + g_vars.shake_screen_counter = 9; + } + const uint16_t *q = monster_spr_tbl; + dx &= 0x1FFF; + while (1) { + if (dx < q[0]) { + obj->data.m.anim = p + 2; + break; + } + if (dx <= q[1]) { + dx = q[2] + 53; + break; + } + q += 3; + } + } + dx &= 0x1FFF; + if (obj->data.m.x_velocity < 0) { + dx |= 0x8000; + } + obj->spr_num &= 0x6000; + obj->spr_num |= dx; + const int type = (m->type & 0x7F); + monster_func1(type, obj); + } + for (int i = 0; i < g_res.level.monsters_count; ++i) { + struct level_monster_t *m = &g_res.level.monsters_tbl[i]; + if (m->spr_num != 0xFFFF && (m->flags & 4) == 0) { + const int type = m->type & 0x7F; + if (!monster_func2(type, m)) { + continue; + } + const uint8_t *p = monster_anim_tbl; + const int spr_num = m->spr_num - 305; + do { + p += 2; + } while (READ_LE_UINT16(p) != 0x7D01 || READ_LE_UINT16(p + 2) != m->type); + p += 4; + while (READ_LE_UINT16(p) != spr_num) { + p += 2; + } + g_vars.monster.current_object->data.m.anim = p; } - const uint8_t len = p[0]; - p += len; } } @@ -2149,26 +2211,35 @@ static void level_clear_item(struct object_t *obj) { static void level_update_player_collision() { struct object_t *obj_player = &g_vars.objects_tbl[1]; + /* monsters */ if (g_vars.objects_tbl[1].hit_counter == 0) { for (int i = 0; i < 12; ++i) { struct object_t *obj = &g_vars.objects_tbl[11 + i]; if (obj->spr_num == 0xFFFF || (obj->spr_num & 0x2000) == 0) { continue; } - print_warning("Unhandled level_update_player_collision 6A2F"); + struct level_monster_t *m = obj->data.m.ref; + if (m->flags & 0x10) { + continue; + } + if (obj->data.m.unkE == 0xFF) { + continue; + } + if (!level_objects_collide(obj_player, obj)) { + continue; + } + print_warning("Unhandled level_update_player_collision 6A43"); } } + /* bonuses */ for (int i = 0; i < 52; ++i) { struct object_t *obj = &g_vars.objects_tbl[23 + i]; - if (obj->spr_num == 0xFFFF) { + if (obj->spr_num == 0xFFFF || (obj->spr_num & 0x2000) == 0) { continue; } if (obj->data.t.counter > 188) { continue; } - if ((obj->spr_num & 0x2000) == 0) { - continue; - } if (!level_objects_collide(obj, obj_player)) { continue; } diff --git a/p2/monsters.c b/p2/monsters.c new file mode 100644 index 0000000..e172dcd --- /dev/null +++ b/p2/monsters.c @@ -0,0 +1,357 @@ + +#include "game.h" +#include "resource.h" +#include "util.h" + +static void monster_func1_helper(struct object_t *obj, int16_t x_pos, int16_t y_pos) { + struct level_monster_t *m = obj->data.m.ref; + if (obj->data.m.unkE == 0xFF) { + return; + } + if (obj->spr_num & 0x2000) { + return; + } + const int dx = abs(x_pos - g_vars.objects_tbl[1].x_pos); + if (dx <= 320) { + const int dy = abs(y_pos - g_vars.objects_tbl[1].y_pos); + if (dy <= 300) { + return; + } + } + if (obj->data.m.unkE < 10) { + obj->spr_num = 0xFFFF; + 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; + } + } +} + +static bool monster_next_tick(struct level_monster_t *m) { + if (m->current_tick < 255) { + ++m->current_tick; + } + return ((m->current_tick >> 2) < m->total_ticks); +} + +static 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; + } + obj->data.m.anim = p + 2; +} + +static void monster_change_prev_anim(struct object_t *obj) { + const uint8_t *p = obj->data.m.anim; + do { + p -= 2; + } while ((int16_t)READ_LE_UINT16(p) >= 0); + obj->data.m.anim = p; +} + +static struct rotation_t *find_rotation() { + for (int i = 0; i < 20; ++i) { + struct rotation_t *r = &g_vars.rotation_tbl[i]; + if (r->x_pos == 0xFFFF) { + return r; + } + } + return 0; +} + +static void monster_rotate_pos(struct level_monster_t *m, int index, int step) { + step >>= 2; + uint8_t radius = step; + for (int i = 0; i < 3; ++i) { + struct rotation_t *r = find_rotation(); + if (r) { + r->x_pos = m->x_pos; + r->y_pos = m->y_pos - 24; + r->radius = radius; + r->index_tbl = index; + radius += step; + } + } +} + +static void monster_update_y_velocity(struct object_t *obj, struct level_monster_t *m) { + if ((m->flags & 1) != 0 && ((obj->spr_num & 0x2000) != 0 || g_vars.objects_tbl[1].y_pos >= obj->y_pos)) { + if (obj->data.m.y_velocity < 240) { + 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; + } + } +} + +static void monster_func1_type2(struct object_t *obj) { + monster_func1_helper(obj, obj->x_pos, obj->y_pos); + struct level_monster_t *m = obj->data.m.ref; + uint8_t al = obj->data.m.unkE; + if (al < 2) { + monster_rotate_pos(m, 0, obj->y_pos - m->y_pos); + if (al == 0) { + obj->data.m.y_velocity = m->type2.unkE << 4; + const int dy = obj->y_pos - m->y_pos; + if (m->type2.y_range >= dy) { + return; + } + obj->data.m.unkE = 1; + monster_change_next_anim(obj); + } else if (al == 1) { + obj->data.m.y_velocity = m->type2.unkE << 4; + const int dy = obj->y_pos - m->y_pos; + if (dy >= 0) { + return; + } + obj->data.m.unkE = 0; + monster_change_prev_anim(obj); + } + } else if (al == 0xFF) { + monster_update_y_velocity(obj, m); + } +} + +static void monster_func1_type8(struct object_t *obj) { + monster_func1_helper(obj, obj->x_pos, obj->y_pos); + struct level_monster_t *m = obj->data.m.ref; + if (obj->data.m.x_velocity != 0) { + const int dx = (obj->x_pos <= g_vars.objects_tbl[1].x_pos) ? 1 : -1; + obj->data.m.x_velocity = dx; + } + uint8_t al = obj->data.m.unkE; + if ((al == 0 && !monster_next_tick(m)) || (al == 12 && !monster_next_tick(m))) { + const int dx = abs(g_vars.objects_tbl[1].x_pos - obj->x_pos); + if (m->type8.x_range < (dx >> 4)) { + return; + } + const int dy = abs(g_vars.objects_tbl[1].y_pos - obj->y_pos); + if (m->type8.y_range < (dy >> 4)) { + return; + } + obj->data.m.y_velocity = -(m->type8.unkE << 4); + int x_vel = m->type8.unkF << 4; + if (g_vars.objects_tbl[1].x_pos <= obj->x_pos) { + x_vel = -x_vel; + } + obj->data.m.x_velocity = x_vel; + obj->data.m.unkE = 10; + m->flags = (m->flags & ~0x2C) | 0x2C; + monster_change_next_anim(obj); + } else if (al == 10) { + if (obj->data.m.y_velocity < 0) { + return; + } + obj->data.m.unkE = 11; + monster_change_next_anim(obj); + } else if (al == 11) { + if (obj->data.m.y_velocity > 0) { + return; + } + obj->data.m.unkE = 12; + monster_change_prev_anim(obj); + monster_change_prev_anim(obj); + obj->data.m.x_velocity = 0; + m->current_tick = 0; + } else if (al == 0xFF) { + monster_update_y_velocity(obj, m); + } +} + +static void monster_func1_type9(struct object_t *obj) { + struct level_monster_t *m = obj->data.m.ref; + if ((obj->spr_num & 0x2000) == 0 && obj->data.m.unkE != 0xFF) { + } else { + uint8_t al = obj->data.m.unkE; + if (al == 0) { + } else if (al == 1) { + } else if (al == 0xFF) { + monster_update_y_velocity(obj, m); + } + } +} + +void monster_func1(int type, struct object_t *obj) { + switch (type) { + case 1: + monster_func1_helper(obj, obj->x_pos, obj->y_pos); + break; + case 2: + monster_func1_type2(obj); + break; + case 8: + monster_func1_type8(obj); + break; + case 9: + monster_func1_type9(obj); + break; + default: + print_warning("monster_func1 unhandled monster type %d", type); + break; + } +} + +static struct object_t *find_object_monster() { + for (int i = 0; i < 12; ++i) { + struct object_t *obj = &g_vars.objects_tbl[11 + i]; + if (obj->spr_num == 0xFFFF) { + return obj; + } + } + return 0; +} + +static bool monster_init_object(struct level_monster_t *m) { + struct object_t *obj = find_object_monster(); + if (obj) { + obj->data.m.unk10 = 0; + g_vars.monster.current_object = obj; + obj->x_pos = m->x_pos; + obj->y_pos = m->y_pos; + obj->spr_num = m->spr_num; + obj->data.m.ref = m; + m->flags = 0x17; + obj->data.m.x_velocity = 0; + obj->data.m.y_velocity = 0; + obj->data.m.unkE = 0; + obj->data.m.unkF = m->unk5; + return true; + } + return false; +} + +static bool monster_is_visible(int x_pos, int y_pos) { + const int dx = (x_pos >> 4) - g_vars.tilemap_x; + if (dx < -2 || dx > (TILEMAP_SCREEN_W + 2)) { + return false; + } + const int dy = (y_pos >> 4) - g_vars.tilemap_y; + if (dy < -2 || dy > (TILEMAP_SCREEN_H + 2)) { + return false; + } + return true; +} + +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)) { + return false; + } + return monster_init_object(m); +} + +static bool monster_func2_type2(struct level_monster_t *m) { + const int16_t x_pos = m->x_pos; + const int16_t y_pos = m->y_pos; + if (!monster_is_visible(x_pos, y_pos)) { + return false; + } + struct object_t *obj = find_object_monster(); + if (obj) { + obj->data.m.unk10 = 0; + g_vars.monster.current_object = obj; + obj->x_pos = x_pos; + obj->y_pos = y_pos; + obj->spr_num = m->spr_num; + obj->data.m.ref = m; + m->flags = 5; + obj->data.m.y_velocity = 0; + obj->data.m.x_velocity = 0; + obj->data.m.unkE = 0; + obj->data.m.unkF = m->unk5; + return true; + } + return false; +} + +static bool monster_func2_type4(struct level_monster_t *m) { + if (!monster_func2_type1(m)) { + return false; + } + m->flags = 5; + return true; +} + +static bool monster_func2_type5_6_7_8(struct level_monster_t *m) { + if (!monster_func2_type1(m)) { + return false; + } + m->flags = 5; + return true; +} + +static bool monster_func2_type9(struct level_monster_t *m) { + uint8_t flags = m->flags; + if (!monster_func2_type1(m)) { + return false; + } + flags |= 5; + if (g_vars.level_num == 6) { + flags |= 0x80; + } + m->flags = flags; + return true; +} + +static bool monster_func2_type10(struct level_monster_t *m) { + if (g_vars.level_num == 5 && g_vars.shake_screen_counter != 0) { + return false; + } + if (m->current_tick < 255) { + ++m->current_tick; + } + if (m->total_ticks > (m->current_tick >> 2)) { + return false; + } + return true; +} + +static bool monster_func2_type11(struct level_monster_t *m) { + if (m->current_tick < 255) { + ++m->current_tick; + } + if (m->total_ticks > (m->current_tick >> 2) || !monster_func2_type1(m)) { + return false; + } + m->flags = 0x37; + g_vars.monster.current_object->y_pos -= (random_get_number() & 0x3F); + return true; +} + +bool monster_func2(int type, struct level_monster_t *m) { + switch (type) { + case 1: + return monster_func2_type1(m); + case 2: + return monster_func2_type2(m); + case 4: + return monster_func2_type4(m); + case 5: + case 6: + case 7: + case 8: + return monster_func2_type5_6_7_8(m); + case 9: + return monster_func2_type9(m); + case 10: + return monster_func2_type10(m); + case 11: + return monster_func2_type11(m); + default: + print_warning("monster_func2 unhandled monster type %d", type); + break; + } + return false; +} diff --git a/p2/resource.c b/p2/resource.c index f46a313..aa3f45e 100644 --- a/p2/resource.c +++ b/p2/resource.c @@ -3,8 +3,6 @@ #include "unpack.h" #include "util.h" -static const bool _dump_data = true; - static const int BACKGROUND_SIZE = 320 * 200; static const char *_datapath; @@ -113,17 +111,41 @@ void load_leveldat(const uint8_t *p, struct level_t *level) { platform->unk8 = *p++; platform->unk9 = *p++; } - memcpy(g_res.level.monsters_attributes, p, 0x800); p += 0x800; - if (_dump_data) { - const uint8_t *p = g_res.level.monsters_attributes; - for (int i = 0; *p < 50; ++i) { - const uint8_t len = p[0]; - const uint8_t type = p[1] & 0x7F; - const uint16_t spr_num = READ_LE_UINT16(p + 2); - print_debug(DBG_RESOURCE, "monster %d len %d type %d spr %d", i, len, type, spr_num); - p += len; + const uint8_t *monster_attr = p; + int monsters_count = 0; + while (*p < 50) { + const uint8_t len = p[0]; + const uint8_t type = p[1] & 0x7F; + const uint16_t spr_num = READ_LE_UINT16(p + 2); + print_debug(DBG_RESOURCE, "monster %d len %d type %d spr %d", monsters_count, len, type, spr_num); + assert(monsters_count < MAX_LEVEL_MONSTERS); + struct level_monster_t *m = &g_res.level.monsters_tbl[monsters_count++]; + m->len = len; + m->type = p[1]; + m->spr_num = spr_num; + m->unk5 = p[5]; + m->total_ticks = p[6]; + m->current_tick = p[7]; + m->unk8 = p[8]; + m->x_pos = READ_LE_UINT16(p + 0x9); + m->y_pos = READ_LE_UINT16(p + 0xB); + switch (type) { + case 2: + m->type2.y_range = p[0xD]; + m->type2.unkE = p[0xE]; + case 8: + m->type8.x_range = p[0xD]; + m->type8.unkE = p[0xE]; + m->type8.unkF = p[0xF]; + m->type8.y_range = p[0x10]; + break; + default: + break; } + p += len; } + g_res.level.monsters_count = monsters_count; + p = monster_attr + 0x800; g_res.level.items_spr_num_offset = READ_LE_UINT16(p); p += 2; g_res.level.monsters_spr_num_offset = READ_LE_UINT16(p); p += 2; for (int i = 0; i < MAX_LEVEL_BONUSES; ++i) { diff --git a/p2/resource.h b/p2/resource.h index c8a5587..d8fc296 100644 --- a/p2/resource.h +++ b/p2/resource.h @@ -58,11 +58,37 @@ struct level_trigger_t { 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 unk5; + uint8_t total_ticks; + uint8_t current_tick; + uint8_t unk8; + uint16_t x_pos; // 0x9 + uint16_t y_pos; // 0xB + union { + struct { + uint8_t y_range; // 0xD + int8_t unkE; // 0xE, cbw + } type2; + struct { + uint8_t x_range; // 0xD + int8_t unkE; // 0xE, cbw + int8_t unkF; // 0xF, cbw + uint8_t y_range; // 0x10 + } type8; + }; +}; + #define MAX_LEVEL_GATES 20 #define MAX_LEVEL_PLATFORMS 15 #define MAX_LEVEL_BONUSES 80 #define MAX_LEVEL_ITEMS 70 #define MAX_LEVEL_TRIGGERS 16 +#define MAX_LEVEL_MONSTERS 150 struct level_t { uint8_t tile_attributes0[256]; @@ -76,7 +102,8 @@ struct level_t { uint16_t front_tiles_lut[256]; struct level_gate_t gates_tbl[MAX_LEVEL_GATES]; struct level_platform_t platforms_tbl[MAX_LEVEL_PLATFORMS]; - uint8_t monsters_attributes[0x800]; + struct level_monster_t monsters_tbl[MAX_LEVEL_MONSTERS]; + uint8_t monsters_count; uint16_t items_spr_num_offset; uint16_t monsters_spr_num_offset; struct level_bonus_t bonuses_tbl[MAX_LEVEL_BONUSES]; diff --git a/p2/staticres.c b/p2/staticres.c index 5479db4..da81c20 100644 --- a/p2/staticres.c +++ b/p2/staticres.c @@ -369,3 +369,74 @@ const uint8_t sin_tbl[] = { 0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x36,0x37,0x38,0x39,0x39,0x3A, 0x3B,0x3B,0x3C,0x3C,0x3D,0x3D,0x3E,0x3E,0x3E,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F }; +const uint16_t monster_spr_tbl[] = { + 0x0131,0x0135,0x0056,0x0137,0x0142,0x006F,0x0143,0x014C,0x006D,0x014D,0x014E,0x005D,0x014F,0x0151,0x005C,0x0152, + 0x0155,0x0068,0x0156,0x015B,0x0064,0x015C,0x015F,0x007D,0x0160,0x0166,0x006C,0x0167,0x016A,0x006F,0x016B,0x0173, + 0x006B,0x0174,0x0176,0x0056,0x0177,0x017A,0x005A,0x017B,0x0184,0x0051,0x0185,0x018A,0x005E,0x018B,0x018D,0x00A1 +}; +const uint8_t monster_anim_tbl[] = { + 0xFF,0xFF,0x01,0x7D,0x00,0x00,0x28,0x00,0xFE,0xFF,0x26,0x00,0x26,0x00,0x26,0x00, + 0x26,0x00,0x25,0x00,0x25,0x00,0x25,0x00,0x25,0x00,0x27,0x00,0x27,0x00,0x27,0x00, + 0x27,0x00,0x25,0x00,0x25,0x00,0x25,0x00,0x25,0x00,0xE0,0xFF,0x00,0x7D,0x2A,0x00, + 0xFE,0xFF,0x01,0x7D,0x01,0x00,0x05,0x00,0xFE,0xFF,0x01,0x7D,0x02,0x00,0x06,0x00, + 0x07,0x00,0xFE,0xFF,0x06,0x00,0xFE,0xFF,0x00,0x7D,0x11,0x00,0xFE,0xFF,0x01,0x7D, + 0x03,0x00,0x36,0x00,0x36,0x00,0x37,0x00,0x37,0x00,0x38,0x00,0x38,0x00,0x39,0x00, + 0x39,0x00,0x06,0x00,0xFE,0xFF,0x07,0x00,0xFE,0xFF,0x08,0x00,0x08,0x00,0x09,0x00, + 0x09,0x00,0x0A,0x00,0x0A,0x00,0x0B,0x00,0x0B,0x00,0xF0,0xFF,0x10,0x00,0x10,0x00, + 0x0C,0x00,0x0C,0x00,0x0D,0x00,0x0D,0x00,0x0E,0x00,0x0E,0x00,0x0F,0x00,0x0F,0x00, + 0xF0,0xFF,0x00,0x7D,0x11,0x00,0xFE,0xFF,0x01,0x7D,0x04,0x00,0x06,0x00,0x07,0x00, + 0xFE,0xFF,0x00,0x7D,0x11,0x00,0xFE,0xFF,0x01,0x7D,0x05,0x00,0x12,0x00,0x13,0x00, + 0xFC,0xFF,0x14,0x00,0x15,0x00,0xFC,0xFF,0x00,0x7D,0x16,0x00,0xFE,0xFF,0x5C,0x00, + 0x5C,0x00,0x5C,0x00,0x5C,0x00,0x5A,0x00,0x5A,0x00,0x5A,0x00,0x5A,0x00,0x5B,0x00, + 0x5B,0x00,0x5B,0x00,0x5B,0x00,0xE8,0xFF,0x5C,0x00,0x5C,0x00,0x5C,0x00,0x5A,0x00, + 0x5A,0x00,0x5A,0x00,0x5B,0x00,0x5B,0x00,0x5B,0x00,0xEE,0xFF,0x00,0x7D,0x5B,0x00, + 0xFE,0xFF,0x01,0x7D,0x06,0x00,0x12,0x00,0x13,0x00,0xFC,0xFF,0x00,0x7D,0x16,0x00, + 0xFE,0xFF,0x01,0x7D,0x07,0x00,0x12,0x00,0x13,0x00,0xFC,0xFF,0x12,0x00,0x13,0x00, + 0xFC,0xFF,0x00,0x7D,0x16,0x00,0xFE,0xFF,0x5C,0x00,0x5C,0x00,0x5C,0x00,0x5C,0x00, + 0x5A,0x00,0x5A,0x00,0x5A,0x00,0x5A,0x00,0x5B,0x00,0x5B,0x00,0x5B,0x00,0x5B,0x00, + 0xE8,0xFF,0x5C,0x00,0xFE,0xFF,0x00,0x7D,0x5A,0x00,0xFE,0xFF,0x01,0x7D,0x08,0x00, + 0x21,0x00,0xFE,0xFF,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x24,0x00,0xFE,0xFF, + 0x24,0x00,0x24,0x00,0x24,0x00,0x24,0x00,0x23,0x00,0xFE,0xFF,0x00,0x7D,0x22,0x00, + 0xFE,0xFF,0x1D,0x00,0xFE,0xFF,0x1C,0x00,0xFE,0xFF,0x1D,0x00,0xFE,0xFF,0x00,0x7D, + 0x1C,0x00,0xFE,0xFF,0x1E,0x00,0xFE,0xFF,0x1F,0x00,0x1F,0x00,0x20,0x00,0x20,0x00, + 0x1E,0x00,0x1E,0x00,0xF4,0xFF,0x1F,0x00,0x1F,0x00,0x20,0x00,0x20,0x00,0x1E,0x00, + 0x1E,0x00,0xF4,0xFF,0x00,0x7D,0x1E,0x00,0xFE,0xFF,0x25,0x00,0xFE,0xFF,0x28,0x00, + 0x28,0x00,0x29,0x00,0xFE,0xFF,0x28,0x00,0xFE,0xFF,0x00,0x7D,0x2A,0x00,0xFE,0xFF, + 0x54,0x00,0x54,0x00,0x54,0x00,0x54,0x00,0x54,0x00,0x54,0x00,0x55,0x00,0x55,0x00, + 0x55,0x00,0x55,0x00,0x55,0x00,0x55,0x00,0xE8,0xFF,0x57,0x00,0xFE,0xFF,0x58,0x00, + 0xFE,0xFF,0x00,0x7D,0x59,0x00,0xFE,0xFF,0x01,0x7D,0x09,0x00,0x17,0x00,0x17,0x00, + 0x18,0x00,0x18,0x00,0xF8,0xFF,0x00,0x7D,0x1B,0x00,0xFE,0xFF,0x46,0x00,0x46,0x00, + 0x47,0x00,0x47,0x00,0x48,0x00,0x48,0x00,0xF4,0xFF,0x00,0x7D,0x49,0x00,0xFE,0xFF, + 0x2B,0x00,0x2B,0x00,0x2C,0x00,0x2C,0x00,0x2D,0x00,0x2D,0x00,0xF4,0xFF,0x00,0x7D, + 0x2E,0x00,0xFE,0xFF,0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x03,0x00, + 0xF4,0xFF,0x00,0x7D,0x04,0x00,0xFE,0xFF,0x5A,0x00,0x5A,0x00,0x5B,0x00,0x5B,0x00, + 0x5C,0x00,0x5C,0x00,0xF4,0xFF,0x00,0x7D,0x5A,0x00,0xFE,0xFF,0x81,0x00,0x81,0x00, + 0x81,0x00,0x82,0x00,0x82,0x00,0x82,0x00,0x83,0x00,0x83,0x00,0x83,0x00,0xEE,0xFF, + 0x00,0x7D,0x84,0x00,0x84,0x00,0x85,0x00,0x85,0x00,0x86,0x00,0x86,0x00,0x8A,0x00, + 0x8A,0x00,0x8B,0x00,0x8B,0x00,0x87,0x00,0x87,0x00,0xEC,0xFF,0x01,0x7D,0x0A,0x00, + 0x45,0x00,0xFE,0xFF,0x44,0x00,0x44,0x00,0x44,0x00,0x44,0x00,0x43,0x00,0x43,0x00, + 0x43,0x00,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00, + 0x03,0x00,0x03,0x40,0x01,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x02,0x00, + 0x03,0x00,0x03,0x00,0x03,0x00,0xEE,0xFF,0x00,0x00,0x00,0x00,0x43,0x00,0x43,0x00, + 0x44,0x00,0x44,0x00,0x45,0x40,0x45,0x00,0xFE,0xFF,0x00,0x7D,0x04,0x00,0xFE,0xFF, + 0x4A,0x00,0xFE,0xFF,0x4B,0x00,0x4B,0x00,0x4B,0x00,0x4C,0x00,0x4C,0x00,0x4C,0x00, + 0x4D,0x00,0x4D,0x00,0x4D,0x00,0x4E,0x00,0x4E,0x00,0x4E,0x40,0x4F,0x00,0x4F,0x00, + 0x4F,0x00,0x50,0x00,0x50,0x00,0x50,0x00,0x51,0x00,0x51,0x00,0x51,0x00,0x52,0x00, + 0x52,0x00,0x52,0x00,0xE8,0xFF,0x4E,0x00,0x4E,0x00,0x4D,0x00,0x4D,0x00,0x4C,0x00, + 0x4C,0x00,0x4B,0x00,0x4B,0x00,0x4A,0x40,0x4A,0x00,0xFE,0xFF,0x00,0x7D,0x53,0x00, + 0xFE,0xFF,0x3A,0x00,0xFE,0xFF,0x3A,0x00,0x3A,0x00,0x3A,0x00,0x3B,0x00,0x3B,0x00, + 0x3B,0x00,0x3C,0x00,0x3C,0x00,0x3C,0x00,0x3D,0x00,0x3D,0x00,0x3D,0x40,0x3E,0x00, + 0x3E,0x00,0x3E,0x00,0x3F,0x00,0x3F,0x00,0x3F,0x00,0xF4,0xFF,0x3F,0x00,0x3F,0x00, + 0x3F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00, + 0x42,0x00,0x42,0x40,0x42,0x00,0xFE,0xFF,0x00,0x7D,0x3F,0x00,0xFE,0xFF,0x01,0x7D, + 0x0B,0x00,0x2F,0x00,0x2F,0x00,0x2F,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x2F,0x00, + 0x2F,0x00,0x2F,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x2F,0x00,0x2F,0x00,0x2F,0x00, + 0x30,0x00,0x30,0x00,0x30,0x00,0x31,0x00,0x31,0x00,0x32,0x00,0x32,0x40,0x33,0x00, + 0x33,0x00,0x34,0x00,0x34,0x00,0xF8,0xFF,0x00,0x7D,0x35,0x00,0xFE,0xFF,0x01,0x7D, + 0x0C,0x00,0x80,0x00,0x88,0x00,0x89,0x00,0xFC,0xFF,0x00,0x7D,0x84,0x00,0x84,0x00, + 0x85,0x00,0x85,0x00,0x86,0x00,0x86,0x00,0x8A,0x00,0x8A,0x00,0x8B,0x00,0x8B,0x00, + 0x87,0x00,0x87,0x00,0xEC,0xFF,0x2B,0x00,0x2B,0x00,0x2C,0x00,0x2C,0x00,0x2D,0x00, + 0x2D,0x00,0xF4,0xFF,0x00,0x7D,0x2E,0x00,0xFE,0xFF,0x3E,0x00,0x3E,0x00,0x3F,0x00, + 0x3F,0x00,0xF8,0xFF,0x00,0x7D,0x3E,0x00,0xFE,0xFF,0x57,0x00,0x57,0x00,0x58,0x00, + 0x58,0x00,0xF8,0xFF,0x00,0x7D,0x59,0x00,0xFE,0xFF +};