Import blues from e49bacb8

This commit is contained in:
Gregory Montoir 2018-12-16 20:34:03 +08:00
parent 6348a0b0c3
commit 75a4b6508c
34 changed files with 5145 additions and 154 deletions

View File

@ -2,16 +2,26 @@
SDL_CFLAGS := `sdl2-config --cflags` SDL_CFLAGS := `sdl2-config --cflags`
SDL_LIBS := `sdl2-config --libs` SDL_LIBS := `sdl2-config --libs`
SRCS := decode.c fileio.c game.c level.c main.c opcodes.c resource.c screen.c sound.c staticres.c sys_sdl2.c triggers.c unpack.c util.c 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
BB_SRCS := $(foreach f,$(BB),bb/$f)
JA_SRCS := $(foreach f,$(JA),ja/$f)
SRCS := $(BB_SRCS) $(JA_SRCS)
OBJS := $(SRCS:.c=.o) OBJS := $(SRCS:.c=.o)
DEPS := $(SRCS:.c=.d) DEPS := $(SRCS:.c=.d)
CPPFLAGS := -Wall -Wpedantic -MMD $(SDL_CFLAGS) -g CPPFLAGS := -Wall -Wpedantic -MMD $(SDL_CFLAGS) -I. -g
blues: $(OBJS) all: blues bbja
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(SDL_LIBS) -lmodplug
blues: main.o sys_sdl2.o util.o $(BB_SRCS:.c=.o)
$(CC) $(LDFLAGS) -o $@ $^ $(SDL_LIBS) -lmodplug
bbja: main.o sys_sdl2.o util.o $(JA_SRCS:.c=.o)
$(CC) $(LDFLAGS) -o $@ $^ $(SDL_LIBS) -lmodplug
clean: clean:
rm -f *.o *.d rm -f $(OBJS) $(DEPS)
-include $(DEPS) -include $(DEPS)

View File

@ -1,33 +1,36 @@
# Blues Brothers # Blues Brothers
This is a rewrite of the game [Blues Brothers](https://www.mobygames.com/game/blues-brothers) developed by [Titus](https://www.mobygames.com/company/titus-interactive-sa). This is a rewrite of the [Blues Brothers](https://www.mobygames.com/game/blues-brothers) and [Blues Brothers: Jukebox Adventure](https://www.mobygames.com/game/blues-brothers-jukebox-adventure) game engines developed by [Titus Interactive](https://www.mobygames.com/company/titus-interactive-sa).
![Screenshot1](blues1.png) ![Screenshot2](blues2.png) ![Screenshot1](blues1.png) ![Screenshot2](bbja2.png)
## Requirements ## Requirements
### Blues Brothers
The game data files of the DOS or Amiga version are required. The game data files of the DOS or Amiga version are required.
``` ```
*.BIN, *.CK1, *.CK2, *.SQL, *.SQV, *.SQZ *.BIN, *.CK1, *.CK2, *.SQL, *.SQV, *.SQZ
``` ```
For sounds and music, the Amiga version files need to be copied. For sounds and music, the Amiga version files or the [ExoticA](https://www.exotica.org.uk/wiki/The_Blues_Brothers) set need to be copied.
### Jukebox Adventure
The game data files of the DOS version are required.
``` ```
SOUND, ALMOST, GUNN, EVERY, SHOT *.EAT, *.MOD
``` ```
The [ExoticA](https://www.exotica.org.uk/wiki/The_Blues_Brothers) modules set can also be used.
## Running ## Running
By default, the executable loads the data files from the current directory. By default, the executable loads the data files from the current directory.
This can be changed using command line switches.
This can be changed by using command line switch.
``` ```
Usage: blues [OPTIONS]... Usage: blues [OPTIONS]...
@ -36,8 +39,8 @@ Usage: blues [OPTIONS]...
--cheats=MASK Cheats bitmask --cheats=MASK Cheats bitmask
--startpos=XxY Start at position (X,Y) --startpos=XxY Start at position (X,Y)
--fullscreen Enable fullscreen --fullscreen Enable fullscreen
--scale Graphics scaling factor (default 2) --scale=N Graphics scaling factor (default 2)
--filter Graphics scaling filter --filter=NAME Graphics scaling filter (default 'nearest')
--screensize=WxH Graphics screen size (default 320x200) --screensize=WxH Graphics screen size (default 320x200)
--cga Enable CGA colors --cga Enable CGA colors
``` ```

View File

@ -31,7 +31,7 @@ void update_input() {
// g_vars.inp_key_tab = g_vars.inp_keyboard[0xF] || g_vars.inp_keyboard[0x78]; // g_vars.inp_key_tab = g_vars.inp_keyboard[0xF] || g_vars.inp_keyboard[0x78];
} }
void do_title_screen() { static void do_title_screen() {
const uint32_t timestamp = g_sys.get_timestamp() + 20 * 1000; const uint32_t timestamp = g_sys.get_timestamp() + 20 * 1000;
load_img(g_res.amiga_data ? "blues.lbm" : "pres.sqz", GAME_SCREEN_W, g_options.cga_colors ? 0 : -1); load_img(g_res.amiga_data ? "blues.lbm" : "pres.sqz", GAME_SCREEN_W, g_options.cga_colors ? 0 : -1);
fade_in_palette(); fade_in_palette();
@ -40,13 +40,33 @@ void do_title_screen() {
if (g_sys.input.space || g_sys.input.quit) { if (g_sys.input.space || g_sys.input.quit) {
break; break;
} }
g_sys.sleep(10);
} while (g_sys.get_timestamp() < timestamp); } while (g_sys.get_timestamp() < timestamp);
play_sound(SOUND_0); play_sound(SOUND_0);
fade_out_palette(); fade_out_palette();
g_sys.input.space = 0; g_sys.input.space = 0;
} }
void do_select_player() { static void do_demo_screens() {
static const char *filenames[] = { "text1.sqz", "maq1.sqz", "maq2.sqz", "maq3.sqz", "maq4.sqz", "maq5.sqz", 0 };
for (int i = 0; filenames[i]; ++i) {
load_img(filenames[i], GAME_SCREEN_W, -1);
fade_in_palette();
while (1) {
update_input();
if (g_sys.input.space) {
break;
}
if (g_sys.input.quit) {
return;
}
g_sys.sleep(10);
}
fade_out_palette();
}
}
static void do_select_player() {
int quit = 0; int quit = 0;
int fade = 0; int fade = 0;
int state = 0; int state = 0;
@ -58,7 +78,6 @@ void do_select_player() {
screen_load_graphics(g_options.cga_colors ? g_res.cga_lut_sqv : 0, 0); screen_load_graphics(g_options.cga_colors ? g_res.cga_lut_sqv : 0, 0);
screen_clear_sprites(); screen_clear_sprites();
do { do {
screen_copy_img();
update_input(); update_input();
const uint32_t timestamp = g_sys.get_timestamp(); const uint32_t timestamp = g_sys.get_timestamp();
switch (state) { switch (state) {
@ -300,7 +319,7 @@ void game_main() {
g_res.spr_frames[144] = icon778e; g_res.spr_frames[144] = icon778e;
} }
if (g_options.cga_colors) { if (g_options.cga_colors) {
g_sys.set_screen_palette(_colors_cga, 4); g_sys.set_screen_palette(_colors_cga, 0, 4, 8);
} else if (g_options.amiga_colors) { } else if (g_options.amiga_colors) {
uint16_t palette[16]; uint16_t palette[16];
for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
@ -328,6 +347,23 @@ void game_main() {
} }
load_level_data(g_vars.level); load_level_data(g_vars.level);
do_level(); do_level();
if (g_res.dos_demo && g_vars.level > 0) {
do_demo_screens();
return;
} }
} }
} }
}
static void game_run(const char *data_path) {
res_init(data_path, GAME_SCREEN_W * GAME_SCREEN_H);
sound_init();
game_main();
sound_fini();
res_fini();
}
struct game_t game = {
"Blues Brothers",
game_run
};

View File

@ -4,9 +4,6 @@
#include "intern.h" #include "intern.h"
#define GAME_SCREEN_W g_options.screen_w
#define GAME_SCREEN_H g_options.screen_h
#define TILEMAP_OFFSET_Y 14 #define TILEMAP_OFFSET_Y 14
#define TILEMAP_SCREEN_W GAME_SCREEN_W #define TILEMAP_SCREEN_W GAME_SCREEN_W
#define TILEMAP_SCREEN_H (GAME_SCREEN_H - 40) #define TILEMAP_SCREEN_H (GAME_SCREEN_H - 40)
@ -38,20 +35,6 @@
#define CHEATS_UNLIMITED_LIFES (1 << 1) #define CHEATS_UNLIMITED_LIFES (1 << 1)
#define CHEATS_UNLIMITED_ENERGY (1 << 2) #define CHEATS_UNLIMITED_ENERGY (1 << 2)
struct options_t {
uint32_t cheats;
int start_level;
int start_xpos16;
int start_ypos16;
int screen_w;
int screen_h;
bool amiga_copper_bars;
bool amiga_colors;
bool amiga_status_bar;
bool dos_scrolling;
bool cga_colors;
};
extern struct options_t g_options; extern struct options_t g_options;
struct door_t { struct door_t {
@ -134,15 +117,15 @@ struct object_t {
uint8_t unk56; uint8_t unk56;
int16_t vinyls_count; int16_t vinyls_count;
uint8_t collide_flag; uint8_t collide_flag;
int16_t unk5A; // always zero // int16_t unk5A; // always zero
uint8_t unk5C; // uint8_t unk5C; // never read
uint8_t unk5D; uint8_t unk5D;
uint8_t blinking_counter; 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 unk60;
uint8_t lifes_count; uint8_t lifes_count;
uint8_t flag_end_level; // level flag, set if music instrument was found uint8_t level_complete_flag; // set if music instrument was found
uint8_t unk63; // restart_level_flag uint8_t restart_level_flag;
}; };
struct vars_t { struct vars_t {
@ -220,8 +203,6 @@ extern uint8_t *level_tilesdata_1e8c[];
/* game.c */ /* game.c */
extern void update_input(); extern void update_input();
extern void game_main(); extern void game_main();
extern void do_title_screen();
extern void do_select_player();
/* level.c */ /* level.c */
extern void load_level_data(int num); extern void load_level_data(int num);
@ -233,7 +214,7 @@ extern void do_level_drop_grabbed_object(struct object_t *);
extern void do_level_update_projectile(struct object_t *obj); extern void do_level_update_projectile(struct object_t *obj);
extern void do_level(); extern void do_level();
/* opcodes.c */ /* objects.c */
extern void level_call_object_func(struct object_t *); extern void level_call_object_func(struct object_t *);
/* screen.c */ /* screen.c */
@ -247,7 +228,6 @@ extern void screen_adjust_palette_color(int color, int b, int c);
extern void screen_vsync(); extern void screen_vsync();
extern void screen_draw_frame(const uint8_t *frame, int fh, int fw, int x, int y); extern void screen_draw_frame(const uint8_t *frame, int fh, int fw, int x, int y);
extern void screen_flip(); extern void screen_flip();
extern void screen_copy_img();
extern void screen_unk5(); extern void screen_unk5();
extern void screen_do_transition1(int a); extern void screen_do_transition1(int a);
extern void screen_do_transition2(); extern void screen_do_transition2();
@ -266,14 +246,14 @@ extern void sound_fini();
extern void play_sound(int num); extern void play_sound(int num);
extern void play_music(int num); extern void play_music(int num);
/* triggers.c */ /* tiles.c */
extern uint16_t triggers_get_tile_type(int x, int y); extern uint16_t triggers_get_tile_type(int x, int y);
extern uint16_t triggers_get_next_tile_flags(int x, int y); extern uint16_t triggers_get_next_tile_flags(int x, int y);
extern uint16_t triggers_get_tile_data(struct object_t *obj); extern uint16_t triggers_get_tile_data(struct object_t *obj);
extern uint16_t triggers_get_next_tile_num(int x, int y); extern uint16_t triggers_get_next_tile_num(int x, int y);
extern void level_call_trigger_func(struct object_t *obj, int y); extern void level_call_trigger_func(struct object_t *obj, int y);
extern void triggers_update_tiles1(struct object_t *obj); extern void triggers_update_tiles1(struct object_t *obj);
extern int16_t triggers_get_dy(struct object_t *obj); extern int16_t triggers_tile_get_yoffset(struct object_t *obj);
extern void triggers_update_tiles2(struct object_t *obj); extern void triggers_update_tiles2(struct object_t *obj);
#endif /* GAME_H__ */ #endif /* GAME_H__ */

View File

@ -94,6 +94,8 @@ void load_level_data(int num) {
if (g_options.cga_colors) { if (g_options.cga_colors) {
} else if (g_options.amiga_colors) { } else if (g_options.amiga_colors) {
g_sys.set_palette_amiga(_colors_data + g_vars.level * 16, 0); g_sys.set_palette_amiga(_colors_data + g_vars.level * 16, 0);
} else {
g_sys.set_screen_palette(g_res.palette, 0, 16, 8);
} }
screen_load_graphics(g_options.cga_colors ? g_res.cga_lut_sqv : 0, g_options.cga_colors ? g_res.cga_lut_avt : 0); screen_load_graphics(g_options.cga_colors ? g_res.cga_lut_sqv : 0, g_options.cga_colors ? g_res.cga_lut_avt : 0);
} }
@ -229,13 +231,13 @@ static void init_level() {
obj->trigger3 = 0; obj->trigger3 = 0;
obj->unk50 = 0; obj->unk50 = 0;
// obj->unk4E = 0; // obj->unk4E = 0;
if (obj->unk63 == 0 && obj->flag_end_level == 0 && (g_vars.level == 0 || g_vars.play_demo_flag)) { if (obj->restart_level_flag == 0 && obj->level_complete_flag == 0 && (g_vars.level == 0 || g_vars.play_demo_flag)) {
g_vars.player1_dead_flag = 0; g_vars.player1_dead_flag = 0;
g_vars.player2_scrolling_flag = 0; g_vars.player2_scrolling_flag = 0;
obj->lifes_count = 3; obj->lifes_count = 3;
obj->data51 = 3; obj->data51 = 3;
obj->vinyls_count = 0; obj->vinyls_count = 0;
} else if (obj->unk63 != 0) { } else if (obj->restart_level_flag != 0) {
--obj->lifes_count; --obj->lifes_count;
obj->data51 = 3; obj->data51 = 3;
obj->vinyls_count = 0; obj->vinyls_count = 0;
@ -244,15 +246,15 @@ static void init_level() {
obj->lifes_count = 3; obj->lifes_count = 3;
obj->data51 = 3; obj->data51 = 3;
} }
obj->unk63 = 0; obj->restart_level_flag = 0;
obj->flag_end_level = 0; obj->level_complete_flag = 0;
obj->unk53 = 0; obj->unk53 = 0;
obj->unk54 = 0; obj->unk54 = 0;
obj->unk55 = 0; obj->unk55 = 0;
obj->unk56 = 0; obj->unk56 = 0;
obj->collide_flag = 0; obj->collide_flag = 0;
obj->unk5A = 0; // obj->unk5A = 0;
obj->unk5C = 1; // obj->unk5C = 1;
obj->unk5D = 0; obj->unk5D = 0;
if (obj->ypos > g_vars.screen_tilemap_h) { if (obj->ypos > g_vars.screen_tilemap_h) {
obj->unk53 = 1; obj->unk53 = 1;
@ -789,17 +791,17 @@ static void do_level_add_sprite3(struct object_t *obj) {
obj->anim_num = 1; obj->anim_num = 1;
obj->special_anim = 0; obj->special_anim = 0;
obj->sprite3_counter = 0; obj->sprite3_counter = 0;
} else if (obj->unk5A != 0) { // } else if (obj->unk5A != 0) {
obj->unk5C = 4; // obj->unk5C = 4;
} }
} }
if (obj->special_anim == 18 && obj->anim_num > 8 && (g_vars.inp_key_up != 0 /* || g_inp_key_T != 0*/)) { if (obj->special_anim == 18 && obj->anim_num > 8 && (g_vars.inp_key_up != 0 /* || g_inp_key_T != 0*/)) {
obj->anim_num = 1; obj->anim_num = 1;
obj->special_anim = 0; obj->special_anim = 0;
obj->sprite3_counter = 0; obj->sprite3_counter = 0;
if (obj->unk5A != 0) { // if (obj->unk5A != 0) {
obj->unk5C = 4; // obj->unk5C = 4;
} // }
} }
} }
if (obj->type != 100) { if (obj->type != 100) {
@ -998,7 +1000,7 @@ void do_level_update_panel_lifes(struct object_t *obj) {
} }
if (obj->data51 == 0) { // health if (obj->data51 == 0) { // health
if (!g_vars.two_players_flag) { if (!g_vars.two_players_flag) {
obj->unk63 = 1; obj->restart_level_flag = 1;
g_vars.game_over_flag = 1; g_vars.game_over_flag = 1;
} else { } else {
if (obj->lifes_count != 1) { if (obj->lifes_count != 1) {
@ -1151,12 +1153,6 @@ void do_level_enter_door(struct object_t *obj) {
} }
obj->screen_xpos = obj->xpos - g_vars.screen_tilemap_xorigin; obj->screen_xpos = obj->xpos - g_vars.screen_tilemap_xorigin;
obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin; obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin;
draw_level_panel();
do_level_update_panel_vinyls(obj);
if (g_vars.two_players_flag) {
do_level_update_panel_2nd_player();
}
screen_flip();
do_level_redraw_tilemap(g_vars.screen_tilemap_xorigin, g_vars.screen_tilemap_yorigin); do_level_redraw_tilemap(g_vars.screen_tilemap_xorigin, g_vars.screen_tilemap_yorigin);
do_level_update_scrolling2(); do_level_update_scrolling2();
draw_level_panel(); draw_level_panel();
@ -1164,8 +1160,8 @@ void do_level_enter_door(struct object_t *obj) {
if (g_vars.two_players_flag) { if (g_vars.two_players_flag) {
do_level_update_panel_2nd_player(); do_level_update_panel_2nd_player();
} }
screen_do_transition1(1);
screen_flip(); screen_flip();
screen_do_transition1(1);
obj->unk3D = 0; obj->unk3D = 0;
obj->sprite_type = 0; obj->sprite_type = 0;
obj->yacc = 2; obj->yacc = 2;
@ -1456,7 +1452,7 @@ static void do_level_fixup_object_position(struct object_t *obj) {
switch (num) { switch (num) {
case 2: case 2:
case 14: case 14:
ret = triggers_get_dy(obj); ret = triggers_tile_get_yoffset(obj);
obj->ypos = ret + (obj->ypos & ~15); obj->ypos = ret + (obj->ypos & ~15);
obj->ypos16 = obj->ypos >> 4; obj->ypos16 = obj->ypos >> 4;
obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin; obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin;
@ -1464,7 +1460,7 @@ static void do_level_fixup_object_position(struct object_t *obj) {
case 3: case 3:
case 15: case 15:
--obj->ypos16; --obj->ypos16;
ret = triggers_get_dy(obj); ret = triggers_tile_get_yoffset(obj);
obj->ypos = ret + (obj->ypos & ~15) - 16; obj->ypos = ret + (obj->ypos & ~15) - 16;
obj->ypos16 = obj->ypos >> 4; obj->ypos16 = obj->ypos >> 4;
obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin; obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin;
@ -1909,7 +1905,6 @@ static void do_level_update_objects() {
} }
} else if (g_vars.two_players_flag) { } else if (g_vars.two_players_flag) {
if (!g_vars.player1_dead_flag) { if (!g_vars.player1_dead_flag) {
// sub_176D7(obj);
do_level_update_object_unk2E(obj); do_level_update_object_unk2E(obj);
do_level_update_panel_2nd_player(); do_level_update_panel_2nd_player();
} }
@ -1918,8 +1913,8 @@ static void do_level_update_objects() {
} }
} }
} else if (obj->type > 2 && obj->collide_flag == 0) { } else if (obj->type > 2 && obj->collide_flag == 0) {
const int x = g_vars.level_xpos[i]; // _si const int x = g_vars.level_xpos[i];
const int y = g_vars.level_ypos[i]; // _di const int y = g_vars.level_ypos[i];
if (obj->type == 32) { if (obj->type == 32) {
obj->unk5D = i; obj->unk5D = i;
} }
@ -1992,16 +1987,16 @@ static void do_level_update_objects() {
} }
} }
} }
if (!g_vars.two_players_flag && g_vars.objects[OBJECT_NUM_PLAYER1].flag_end_level != 0) { if (!g_vars.two_players_flag && g_vars.objects[OBJECT_NUM_PLAYER1].level_complete_flag != 0) {
g_vars.level_completed_flag = 1; g_vars.level_completed_flag = 1;
} else { } else {
if (g_vars.objects[OBJECT_NUM_PLAYER1].flag_end_level != 0 && g_vars.objects[OBJECT_NUM_PLAYER2].flag_end_level != 0) { if (g_vars.objects[OBJECT_NUM_PLAYER1].level_complete_flag != 0 && g_vars.objects[OBJECT_NUM_PLAYER2].level_complete_flag != 0) {
g_vars.level_completed_flag = 1; g_vars.level_completed_flag = 1;
} }
if (g_vars.objects[OBJECT_NUM_PLAYER1].flag_end_level != 0 && g_vars.player1_dead_flag) { if (g_vars.objects[OBJECT_NUM_PLAYER1].level_complete_flag != 0 && g_vars.player1_dead_flag) {
g_vars.level_completed_flag = 1; g_vars.level_completed_flag = 1;
} }
if (g_vars.objects[OBJECT_NUM_PLAYER2].flag_end_level != 0 && g_vars.player2_dead_flag) { if (g_vars.objects[OBJECT_NUM_PLAYER2].level_complete_flag != 0 && g_vars.player2_dead_flag) {
g_vars.level_completed_flag = 1; g_vars.level_completed_flag = 1;
} }
} }
@ -2019,8 +2014,8 @@ static void do_level_update_objects() {
g_vars.objects[OBJECT_NUM_PLAYER2].unk60 = 0; g_vars.objects[OBJECT_NUM_PLAYER2].unk60 = 0;
g_vars.objects[OBJECT_NUM_PLAYER1].data5F = 0; g_vars.objects[OBJECT_NUM_PLAYER1].data5F = 0;
g_vars.objects[OBJECT_NUM_PLAYER2].data5F = 0; g_vars.objects[OBJECT_NUM_PLAYER2].data5F = 0;
g_vars.objects[OBJECT_NUM_PLAYER1].flag_end_level = 0; g_vars.objects[OBJECT_NUM_PLAYER1].level_complete_flag = 0;
g_vars.objects[OBJECT_NUM_PLAYER2].flag_end_level = 0; g_vars.objects[OBJECT_NUM_PLAYER2].level_complete_flag = 0;
// g_vars.screen_draw_offset -= TILEMAP_OFFSET_Y * 40; // g_vars.screen_draw_offset -= TILEMAP_OFFSET_Y * 40;
screen_unk5(); screen_unk5();
// g_vars.screen_draw_offset += TILEMAP_OFFSET_Y * 40; // g_vars.screen_draw_offset += TILEMAP_OFFSET_Y * 40;
@ -2034,10 +2029,10 @@ static void do_level_update_objects() {
g_vars.objects[OBJECT_NUM_PLAYER2].unk60 = 0; g_vars.objects[OBJECT_NUM_PLAYER2].unk60 = 0;
g_vars.objects[OBJECT_NUM_PLAYER1].data5F = 0; g_vars.objects[OBJECT_NUM_PLAYER1].data5F = 0;
g_vars.objects[OBJECT_NUM_PLAYER2].data5F = 0; g_vars.objects[OBJECT_NUM_PLAYER2].data5F = 0;
g_vars.objects[OBJECT_NUM_PLAYER1].unk63 = 0; g_vars.objects[OBJECT_NUM_PLAYER1].restart_level_flag = 0;
g_vars.objects[OBJECT_NUM_PLAYER2].unk63 = 0; g_vars.objects[OBJECT_NUM_PLAYER2].restart_level_flag = 0;
g_vars.objects[OBJECT_NUM_PLAYER1].flag_end_level = 0; g_vars.objects[OBJECT_NUM_PLAYER1].level_complete_flag = 0;
g_vars.objects[OBJECT_NUM_PLAYER2].flag_end_level = 0; g_vars.objects[OBJECT_NUM_PLAYER2].level_complete_flag = 0;
screen_vsync(); screen_vsync();
} }
if (g_vars.objects[35].screen_ypos > 90) { if (g_vars.objects[35].screen_ypos > 90) {

View File

@ -7,7 +7,8 @@
struct resource_data_t g_res; struct resource_data_t g_res;
void res_init(int vga_size) { void res_init(const char *datapath, int vga_size) {
fio_init(datapath);
static const int SQL_SIZE = 640 * 25; static const int SQL_SIZE = 640 * 25;
g_res.sql = (uint8_t *)malloc(SQL_SIZE); g_res.sql = (uint8_t *)malloc(SQL_SIZE);
if (!g_res.sql) { if (!g_res.sql) {
@ -56,6 +57,7 @@ void res_init(int vga_size) {
} }
void res_fini() { void res_fini() {
fio_fini();
free(g_res.sql); free(g_res.sql);
g_res.sql = 0; g_res.sql = 0;
free(g_res.spr_sqv); free(g_res.spr_sqv);
@ -102,7 +104,7 @@ static void copy_cga(uint8_t *dst, int dst_pitch, uint8_t *dither_lut) {
for (int y = 0; y < 200; ++y) { for (int y = 0; y < 200; ++y) {
const uint8_t *p = dither_lut + (y & 1) * 0x10; const uint8_t *p = dither_lut + (y & 1) * 0x10;
for (int x = 0; x < 320; ++x) { for (int x = 0; x < 320; ++x) {
dst[x] = p[dst[x]] & 3; dst[x] = p[dst[x]];
} }
dst += dst_pitch; dst += dst_pitch;
} }
@ -280,9 +282,6 @@ void load_ck(const char *filename, uint16_t offset, int dither_pattern) {
break; break;
} }
load_iff(g_res.tmp, size, g_res.tiles + offset, 640, dither_pattern); load_iff(g_res.tmp, size, g_res.tiles + offset, 640, dither_pattern);
if (dither_pattern < 0) {
g_sys.set_screen_palette(g_res.palette, 16);
}
} }
void load_img(const char *filename, int screen_w, int dither_pattern) { void load_img(const char *filename, int screen_w, int dither_pattern) {
@ -294,12 +293,11 @@ void load_img(const char *filename, int screen_w, int dither_pattern) {
size = read_compressed_file(filename, g_res.tmp); size = read_compressed_file(filename, g_res.tmp);
} }
assert(size <= 32000); assert(size <= 32000);
load_iff(g_res.tmp, size, g_res.tmp + 32000, screen_w, dither_pattern); load_iff(g_res.tmp, size, g_res.vga, screen_w, dither_pattern);
if (dither_pattern < 0) { if (dither_pattern < 0) {
g_sys.set_screen_palette(g_res.palette, 16); g_sys.set_screen_palette(g_res.palette, 0, 16, 8);
} }
g_sys.update_screen(g_res.tmp + 32000, 0); g_sys.update_screen(g_res.vga, 0);
memcpy(g_res.vga, g_res.tmp + 32000, g_res.vga_size);
} }
void load_m(const char *filename) { void load_m(const char *filename) {

View File

@ -12,7 +12,7 @@ struct trigger_t {
int16_t tile_type; int16_t tile_type;
int16_t tile_flags; int16_t tile_flags;
uint8_t op_func; uint8_t op_func;
const uint8_t *op_table1; // dy for (x&15) const uint8_t *op_table1; // tile_yoffset
const uint8_t *op_table2; // tile_animation const uint8_t *op_table2; // tile_animation
int16_t unk10; int16_t unk10;
const uint8_t *op_table3; // tile_trigger const uint8_t *op_table3; // tile_trigger
@ -51,7 +51,7 @@ struct resource_data_t {
extern struct resource_data_t g_res; extern struct resource_data_t g_res;
extern void res_init(int vga_size); extern void res_init(const char *datapath, int vga_size);
extern void res_fini(); extern void res_fini();
extern int read_file(const char *filename, uint8_t *dst, int size); extern int read_file(const char *filename, uint8_t *dst, int size);
extern int read_compressed_file(const char *filename, uint8_t *dst); extern int read_compressed_file(const char *filename, uint8_t *dst);

View File

@ -56,7 +56,7 @@ void screen_adjust_palette_color(int color, int b, int c) {
if (!g_options.cga_colors) { if (!g_options.cga_colors) {
g_res.palette[color * 3 + b] += c; g_res.palette[color * 3 + b] += c;
screen_vsync(); screen_vsync();
g_sys.set_screen_palette(g_res.palette, 16); g_sys.set_screen_palette(g_res.palette, 0, 16, 8);
} }
} }
@ -90,24 +90,20 @@ void screen_flip() {
g_sys.update_screen(g_res.vga, 1); g_sys.update_screen(g_res.vga, 1);
} }
void screen_copy_img() {
memcpy(g_res.vga, g_res.tmp + 32000, GAME_SCREEN_W * GAME_SCREEN_H);
}
void screen_unk5() { void screen_unk5() {
// screen_do_transition2(); // screen_do_transition2();
screen_clear(0); screen_clear(0);
} }
void screen_do_transition1(int a) { void screen_do_transition1(int a) {
print_warning("screen_do_transition1 %d", a); // print_warning("screen_do_transition1 %d", a);
if (a) { if (a) {
g_sys.transition_screen(TRANSITION_CURTAIN, true); g_sys.transition_screen(TRANSITION_CURTAIN, true);
} }
} }
void screen_do_transition2() { void screen_do_transition2() {
print_warning("screen_do_transition2"); // print_warning("screen_do_transition2");
g_sys.transition_screen(TRANSITION_SQUARE, true); g_sys.transition_screen(TRANSITION_SQUARE, true);
} }
@ -207,7 +203,7 @@ static void dither_graphics(uint8_t *dst, int dst_pitch, int w, int h, const uin
if (color == 0) { if (color == 0) {
dst[x] = color_key; dst[x] = color_key;
} else { } else {
dst[x] = p[color] & 3; dst[x] = p[color];
} }
} }
dst += dst_pitch; dst += dst_pitch;
@ -232,7 +228,6 @@ static void decode_graphics(int spr_type, int start, int end, const uint8_t *dit
} }
const int h = READ_LE_UINT16(ptr - 4); const int h = READ_LE_UINT16(ptr - 4);
const int w = READ_LE_UINT16(ptr - 2); const int w = READ_LE_UINT16(ptr - 2);
const int j = i - start;
if (current_x + w > MAX_SPRITESHEET_W) { if (current_x + w > MAX_SPRITESHEET_W) {
current_y += max_h; current_y += max_h;
if (current_x > max_w) { if (current_x > max_w) {
@ -249,6 +244,7 @@ static void decode_graphics(int spr_type, int start, int end, const uint8_t *dit
if (dither_lut) { if (dither_lut) {
dither_graphics(data + current_y * MAX_SPRITESHEET_W + current_x, MAX_SPRITESHEET_W, w, h, dither_lut, color_key); dither_graphics(data + current_y * MAX_SPRITESHEET_W + current_x, MAX_SPRITESHEET_W, w, h, dither_lut, color_key);
} }
const int j = i - start;
r[j].x = current_x; r[j].x = current_x;
r[j].y = current_y; r[j].y = current_y;
r[j].w = w; r[j].w = w;

View File

@ -145,9 +145,9 @@ void play_music(int num) {
} }
} }
_mpf = ModPlug_Load(buf, size); _mpf = ModPlug_Load(buf, size);
}
free(buf); free(buf);
} }
}
fio_close(slot); fio_close(slot);
} else { // ExoticA } else { // ExoticA
filename = _modules[num * 2 + 1]; filename = _modules[num * 2 + 1];

View File

@ -12,9 +12,7 @@ uint16_t triggers_get_tile_type(int x, int y) {
} }
uint16_t triggers_get_next_tile_flags(int x, int y) { uint16_t triggers_get_next_tile_flags(int x, int y) {
const uint8_t *p = lookup_sql(x, y); const int num = triggers_get_next_tile_num(x, y);
int num = p[0];
num = g_res.triggers[num].unk16;
return g_res.triggers[num].tile_flags; return g_res.triggers[num].tile_flags;
} }
@ -470,7 +468,7 @@ static void trigger_func_op30(struct object_t *obj) {
static void trigger_func_op31(struct object_t *obj) { static void trigger_func_op31(struct object_t *obj) {
if (obj->yvelocity > 0 && obj->unk2B == 0) { if (obj->yvelocity > 0 && obj->unk2B == 0) {
obj->yvelocity = 0; obj->yvelocity = 0;
obj->ypos = (obj->ypos & ~15) + triggers_get_dy(obj); obj->ypos = (obj->ypos & ~15) + triggers_tile_get_yoffset(obj);
obj->ypos16 = obj->ypos >> 4; obj->ypos16 = obj->ypos >> 4;
obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin; obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin;
obj->sprite_type = 1; obj->sprite_type = 1;
@ -482,7 +480,7 @@ static void trigger_func_op31(struct object_t *obj) {
static void trigger_func_op32(struct object_t *obj) { static void trigger_func_op32(struct object_t *obj) {
if (obj->yvelocity > 0 && obj->unk2B == 0) { if (obj->yvelocity > 0 && obj->unk2B == 0) {
obj->yvelocity = 0; obj->yvelocity = 0;
obj->ypos = (obj->ypos & ~15) + triggers_get_dy(obj); obj->ypos = (obj->ypos & ~15) + triggers_tile_get_yoffset(obj);
obj->ypos16 = obj->ypos >> 4; obj->ypos16 = obj->ypos >> 4;
obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin; obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin;
obj->sprite_type = 1; obj->sprite_type = 1;
@ -508,7 +506,7 @@ static void trigger_func_op33(struct object_t *obj) {
static void trigger_func_op34(struct object_t *obj) { static void trigger_func_op34(struct object_t *obj) {
if (obj->yvelocity > 0 && obj->unk2B == 0) { if (obj->yvelocity > 0 && obj->unk2B == 0) {
obj->yvelocity = 0; obj->yvelocity = 0;
obj->ypos = (obj->ypos & ~15) + triggers_get_dy(obj); obj->ypos = (obj->ypos & ~15) + triggers_tile_get_yoffset(obj);
obj->ypos16 = obj->ypos >> 4; obj->ypos16 = obj->ypos >> 4;
obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin; obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin;
obj->sprite_type = 1; obj->sprite_type = 1;
@ -534,7 +532,7 @@ static void trigger_func_op35(struct object_t *obj) {
static void trigger_func_op36(struct object_t *obj) { static void trigger_func_op36(struct object_t *obj) {
if (obj->yvelocity > 0 && obj->unk2B == 0) { if (obj->yvelocity > 0 && obj->unk2B == 0) {
obj->yvelocity = 0; obj->yvelocity = 0;
obj->ypos = (obj->ypos & ~15) + triggers_get_dy(obj); obj->ypos = (obj->ypos & ~15) + triggers_tile_get_yoffset(obj);
obj->ypos16 = obj->ypos >> 4; obj->ypos16 = obj->ypos >> 4;
obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin; obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin;
obj->sprite_type = 4; obj->sprite_type = 4;
@ -556,7 +554,7 @@ static void trigger_func_op37(struct object_t *obj) {
static void trigger_func_op38(struct object_t *obj) { static void trigger_func_op38(struct object_t *obj) {
if (obj->yvelocity > 0 && obj->unk2B == 0) { if (obj->yvelocity > 0 && obj->unk2B == 0) {
obj->yvelocity = 0; obj->yvelocity = 0;
obj->ypos = (obj->ypos & ~15) + triggers_get_dy(obj); obj->ypos = (obj->ypos & ~15) + triggers_tile_get_yoffset(obj);
obj->ypos16 = obj->ypos >> 4; obj->ypos16 = obj->ypos >> 4;
obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin; obj->screen_ypos = obj->ypos - g_vars.screen_tilemap_yorigin;
obj->sprite_type = 4; obj->sprite_type = 4;
@ -599,7 +597,7 @@ static void trigger_func_op40(struct object_t *obj) {
if (counter == 400) { if (counter == 400) {
if (!g_vars.two_players_flag) { if (!g_vars.two_players_flag) {
g_vars.level_completed_flag = 1; g_vars.level_completed_flag = 1;
} else if (g_vars.objects[OBJECT_NUM_PLAYER1].flag_end_level != 0 && g_vars.objects[OBJECT_NUM_PLAYER2].flag_end_level != 0) { } else if (g_vars.objects[OBJECT_NUM_PLAYER1].level_complete_flag != 0 && g_vars.objects[OBJECT_NUM_PLAYER2].level_complete_flag != 0) {
g_vars.level_completed_flag = 1; g_vars.level_completed_flag = 1;
} }
} }
@ -764,9 +762,9 @@ void triggers_update_tiles1(struct object_t *obj) {
} }
if (p[8] != 0) { if (p[8] != 0) {
if (obj->data5F == g_vars.level + 1) { // music instrument must have been found to complete the level if (obj->data5F == g_vars.level + 1) { // music instrument must have been found to complete the level
if (obj->flag_end_level == 0) { if (obj->level_complete_flag == 0) {
play_sound(SOUND_13); play_sound(SOUND_13);
obj->flag_end_level = 1; obj->level_complete_flag = 1;
if (_di == 0) { if (_di == 0) {
do_level_update_tile(obj->xpos16, obj->ypos16, p[2]); do_level_update_tile(obj->xpos16, obj->ypos16, p[2]);
} else { } else {
@ -784,10 +782,8 @@ void triggers_update_tiles1(struct object_t *obj) {
} }
g_vars.triggers_counter = 0; g_vars.triggers_counter = 0;
} }
} else if (g_vars.triggers_counter == 0) { } else if (g_vars.triggers_counter == 0) {
g_vars.triggers_counter = 1; g_vars.triggers_counter = 1;
} }
} else { } else {
if (_di == 0) { if (_di == 0) {
@ -890,7 +886,7 @@ void triggers_update_tiles1(struct object_t *obj) {
} }
} }
int16_t triggers_get_dy(struct object_t *obj) { int16_t triggers_tile_get_yoffset(struct object_t *obj) {
const uint8_t *p = lookup_sql(obj->xpos16, obj->ypos16); const uint8_t *p = lookup_sql(obj->xpos16, obj->ypos16);
const int num = p[0]; const int num = p[0];
return g_res.triggers[num].op_table1[obj->xpos & 15] - 1; return g_res.triggers[num].op_table1[obj->xpos & 15] - 1;

BIN
bbja1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
bbja2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -9,20 +9,58 @@
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#ifndef ARRAYSIZE
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
#endif #define SWAP(x, y) do { typeof(x) tmp = x; x = y; y = tmp; } while(0)
static inline uint16_t READ_BE_UINT16(const uint8_t *p) { #undef MIN
return (p[0] << 8) | p[1]; static inline int MIN(int a, int b) {
return (a < b) ? a : b;
}
#undef MAX
static inline int MAX(int a, int b) {
return (a > b) ? a : b;
} }
static inline uint32_t READ_BE_UINT32(const uint8_t *p) { static inline uint32_t READ_BE_UINT32(const uint8_t *p) {
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
} }
static inline uint16_t READ_BE_UINT16(const uint8_t *p) {
return (p[0] << 8) | p[1];
}
static inline uint16_t READ_LE_UINT16(const uint8_t *p) { static inline uint16_t READ_LE_UINT16(const uint8_t *p) {
return p[0] | (p[1] << 8); return p[0] | (p[1] << 8);
} }
static inline void WRITE_LE_UINT16(uint8_t *p, uint16_t value) {
p[0] = value & 0xFF;
p[1] = value >> 8;
}
#define GAME_SCREEN_W g_options.screen_w
#define GAME_SCREEN_H g_options.screen_h
struct options_t {
uint32_t cheats;
int start_level;
int start_xpos16;
int start_ypos16;
int screen_w;
int screen_h;
// 'bb' only options
bool amiga_copper_bars;
bool amiga_colors;
bool amiga_status_bar;
bool dos_scrolling;
bool cga_colors;
};
struct game_t {
const char *name;
//int (*detect)(const char *data_path);
void (*run)(const char *data_path);
};
#endif #endif

361
ja/game.c Normal file
View File

@ -0,0 +1,361 @@
/* game screens */
#include "game.h"
#include "resource.h"
#include "sys.h"
struct vars_t g_vars;
void update_input() {
g_sys.process_events();
g_vars.input_key_left = (g_sys.input.direction & INPUT_DIRECTION_LEFT) != 0 ? 0xFF : 0;
g_vars.input_key_right = (g_sys.input.direction & INPUT_DIRECTION_RIGHT) != 0 ? 0xFF : 0;
g_vars.input_key_up = (g_sys.input.direction & INPUT_DIRECTION_UP) != 0 ? 0xFF : 0;
g_vars.input_key_down = (g_sys.input.direction & INPUT_DIRECTION_DOWN) != 0 ? 0xFF : 0;
g_vars.input_key_space = g_sys.input.space ? 0xFF : 0;
g_vars.input_keystate[2] = g_sys.input.digit1;
g_vars.input_keystate[3] = g_sys.input.digit2;
g_vars.input_keystate[4] = g_sys.input.digit3;
}
static void wait_input(int timeout) {
const uint32_t end = g_sys.get_timestamp() + timeout * 10;
while (g_sys.get_timestamp() < end) {
g_sys.process_events();
if (g_sys.input.quit || g_sys.input.space) {
break;
}
g_sys.sleep(20);
}
}
static void do_splash_screen() {
load_file("titus.eat");
video_copy_vga(0x7D00);
fade_in_palette();
fade_out_palette();
load_file("tiny.eat");
video_copy_vga(0x7D00);
fade_in_palette();
fade_out_palette();
}
static void scroll_screen_palette() {
g_vars.level_time += 3;
if (g_vars.level_time >= 90) {
g_vars.level_time = 0;
}
const int count = 90 - g_vars.level_time;
for (int i = 0; i < count; i += 3) {
g_sys.set_palette_color(225 + i / 3, g_res.tmp + 225 * 3 + g_vars.level_time + i);
}
g_sys.update_screen(g_res.vga, 1);
}
static void do_select_screen_scroll_palette(int start, int end, int step, int count) {
uint8_t *palette_buffer = g_res.tmp;
do {
for (int i = start * 3; i < end * 3; ++i) {
int color = g_vars.palette_buffer[i];
if ((step > 0 && color != palette_buffer[i]) || (step < 0 && color != 0)) {
color += step;
}
g_vars.palette_buffer[i] = color;
}
g_sys.set_screen_palette(g_vars.palette_buffer + start * 3, start, end - start + 1, 6);
g_sys.update_screen(g_res.vga, 1);
g_sys.sleep(20);
} while (--count != 0);
}
static void do_select_screen_scroll_palette_pattern1() {
do_select_screen_scroll_palette(0x10, 0x4F, -1, 0x19);
}
static void do_select_screen_scroll_palette_pattern2() {
do_select_screen_scroll_palette(0x60, 0x9F, -1, 0x19);
}
static void do_select_screen_scroll_palette_pattern3() {
do_select_screen_scroll_palette(0x10, 0x4F, 1, 0x19);
}
static void do_select_screen_scroll_palette_pattern4() {
do_select_screen_scroll_palette(0x60, 0x9F, 1, 0x19);
}
static void do_select_screen() {
load_file("select.eat");
video_copy_vga(0x7D00);
fade_in_palette();
memcpy(g_vars.palette_buffer, g_res.tmp, 256 * 3);
do_select_screen_scroll_palette_pattern2();
int bl = 2;
while (!g_sys.input.quit) {
int bh = bl;
video_vsync(60);
if (g_sys.input.direction & INPUT_DIRECTION_RIGHT) {
g_sys.input.direction &= ~INPUT_DIRECTION_RIGHT;
++bl;
bl &= 3;
if (bl == 0) {
bl = 1;
}
video_vsync(60);
}
if (g_sys.input.direction & INPUT_DIRECTION_LEFT) {
g_sys.input.direction &= ~INPUT_DIRECTION_LEFT;
--bl;
bl &= 3;
if (bl == 0) {
bl = 3;
}
video_vsync(60);
}
bh ^= bl;
if (bh & 1) {
if (bl & 1) {
do_select_screen_scroll_palette_pattern4();
} else {
do_select_screen_scroll_palette_pattern2();
}
}
if (bh & 2) {
if (bl & 2) {
do_select_screen_scroll_palette_pattern3();
} else {
do_select_screen_scroll_palette_pattern1();
}
}
if (g_sys.input.space) {
assert(bl == 1 || bl == 2);
g_sys.input.space = 0;
g_vars.player = 1 - ((bl & 3) - 1);
fade_out_palette();
break;
}
update_input();
g_sys.sleep(30);
}
}
void do_difficulty_screen() {
char name[16];
snprintf(name, sizeof(name), "dif%02d.eat", (g_vars.level >> 3) + 1);
load_file(name);
video_copy_vga(0x7D00);
fade_in_palette();
wait_input(560);
fade_out_palette();
}
void do_level_number_screen() {
load_file("fond.eat");
video_draw_string("LEVEL NUMBER", 0x5E0C, 11);
char buf[8];
snprintf(buf, sizeof(buf), "%02d", g_vars.level);
video_draw_string(buf, 0x5E9B, 11);
video_copy_vga(0x7D00);
fade_in_palette();
fade_out_palette();
}
static uint16_t get_password(uint16_t ax) {
// ax = read(0xF000:0xFFFF, 16) // bios
ax ^= 0xAA31;
// rol ax, cpu_speed
return ax;
}
void do_level_password_screen() {
load_file("password.eat");
uint16_t ax = get_password(g_vars.player * 50 + g_vars.level - 1);
char str[5];
for (int i = 0; i < 4; ++i, ax <<= 4) {
static const uint8_t rev_bits[] = {
0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE, 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF
};
const uint8_t dx = rev_bits[(ax >> 15) & 15] + '0';
str[i] = (dx <= '9') ? dx : (dx + 7);
}
str[4] = 0;
video_draw_string("STAGE NUMBER", 0x7E96, 11);
video_draw_string(str, 0xABB4, 20);
video_copy_vga(0x7D00);
fade_in_palette();
scroll_screen_palette();
wait_input(64000);
fade_out_palette();
}
static void do_password_screen() {
load_file("password.eat");
video_draw_string("ENTER PASSWORD", 0x7E96, 11);
fade_in_palette();
char str[5] = "0000";
video_draw_string(str, 0xABB4, 20);
}
static int do_menu_screen() {
load_file("menu.eat");
video_copy_vga(0x7D00);
fade_in_palette();
memset(g_vars.input_keystate, 0, sizeof(g_vars.input_keystate));
g_vars.level_time = 0;
while (!g_sys.input.quit) {
scroll_screen_palette();
if (g_vars.input_keystate[2] || g_vars.input_keystate[0x4F] || g_sys.input.space) {
g_sys.input.space = 0;
fade_out_palette();
return 1;
}
if (g_vars.input_keystate[3] || g_vars.input_keystate[0x50]) {
fade_out_palette();
return 2;
}
if (g_vars.input_keystate[4] || g_vars.input_keystate[0x51]) {
return 3;
}
update_input();
g_sys.sleep(30);
}
return 0;
}
static int do_options_screen() {
fade_out_palette();
load_file("fond.eat");
video_draw_string("GAME SPEED", 0x3EE9, 11);
video_draw_string("1 FAST", 0x647E, 11);
video_draw_string("2 NORMAL", 0x89FE, 11);
video_copy_vga(0x7D00);
fade_in_palette();
memset(g_vars.input_keystate, 0, sizeof(g_vars.input_keystate));
while (!g_sys.input.quit) {
scroll_screen_palette();
if (g_vars.input_keystate[2] || g_vars.input_keystate[0x4F]) {
fade_out_palette();
return 1;
}
if (g_vars.input_keystate[3] || g_vars.input_keystate[0x50]) {
fade_out_palette();
return 2;
}
update_input();
g_sys.sleep(30);
}
return 0;
}
void do_game_over_screen() {
load_file("fond.eat");
video_draw_string("GAME OVER", 0x5E2E, 11);
video_copy_vga(0x7D00);
fade_in_palette();
wait_input(64000);
fade_out_palette();
}
void do_game_win_screen() {
load_file("win.eat");
video_copy_vga(0x7D00);
fade_in_palette();
fade_out_palette();
load_file("end.eat");
video_copy_vga(0x7D00);
static const int count = 5;
static const struct {
uint16_t offset;
const char *str;
} text[] = {
{ 0x0F68, "CONGRATULATION" },
{ 0x3B34, "YOU HAVE BEATEN" },
{ 0x5CE8, "THE EVIL JUKEBOXE" },
{ 0x7EB1, "NOW YOU ARE FREE" },
{ 0xA072, "AND YOUR CONCERT" },
{ 0xC22D, "WILL BE A SUCCESS" },
{ 0xFFFF, 0 },
{ 0x33BE, "PC CONVERSION" },
{ 0x5590, "ERIC ZMIRO" },
{ 0x864D, "PC GRAPHICS" },
{ 0xA7FC, "DIDIER CARRERE" },
{ 0xFFFF, 0 },
{ 0x33AF, "ORIGINAL VERSION" },
{ 0x5594, "ERIC CAEN" },
{ 0x862B, "ORIGINAL GRAPHICS" },
{ 0xA835, "BOB" },
{ 0xFFFF, 0 },
{ 0x33B1, "ORIGINAL MUSICS" },
{ 0x559A, "DIMITRI" },
{ 0x8653, "PC MUSICS" },
{ 0xA7F2, "MICHAEL KNAEPEN" },
{ 0xFFFF, 0 },
{ 0x5A8F, "THANK YOU" },
{ 0x8008, "FOR PLAYING" },
{ 0xFFFF, 0 }
};
int i = 0;
for (int j = 0; j < count; ++j) {
for (; text[i].str; ++i) {
video_draw_string(text[i].str, text[i].offset, 11);
}
++i;
video_copy_vga(0x7D00);
fade_in_palette();
wait_input(64000);
fade_out_palette();
video_copy_vga(0x7D00);
}
}
void game_main() {
play_music(0);
do_splash_screen();
g_sys.set_screen_palette(common_palette_data, 0, 128, 6);
video_load_sprites();
render_set_sprites_clipping_rect(0, 0, TILEMAP_SCREEN_W, TILEMAP_SCREEN_H);
while (!g_sys.input.quit) {
update_input();
g_vars.level = g_options.start_level;
if (g_vars.level == 0) {
g_vars.level = 1;
}
const int ret = do_menu_screen();
g_vars.players_table[0].lifes_count = 3;
g_vars.players_table[1].lifes_count = 3;
if (ret == 0) {
break;
} else if (ret == 1) {
do_select_screen();
do_difficulty_screen();
} else if (ret == 2) {
g_vars.level = -1;
do_password_screen();
if (g_vars.level < 0) {
continue;
}
++g_vars.level;
do_difficulty_screen();
} else {
do_options_screen();
continue;
}
do_level();
}
}
static void game_run(const char *data_path) {
res_init(data_path, GAME_SCREEN_W * GAME_SCREEN_H);
sound_init();
game_main();
sound_fini();
res_fini();
}
struct game_t game = {
"Blues Brothers : Jukebox Adventure",
game_run
};

225
ja/game.h Normal file
View File

@ -0,0 +1,225 @@
#ifndef GAME_H__
#define GAME_H__
#include "intern.h"
#define CHEATS_OBJECT_NO_HIT (1 << 0)
#define CHEATS_ONE_HIT_VINYL (1 << 1)
#define CHEATS_DECOR_NO_HIT (1 << 2)
extern struct options_t g_options;
#define TILEMAP_SCREEN_W GAME_SCREEN_W
#define TILEMAP_SCREEN_H (GAME_SCREEN_H - PANEL_H)
#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_11 11
#define SOUND_14 14 // player lost life
#define SOUND_15 15 // running out time
struct object_t {
int16_t x_pos;
int16_t y_pos;
uint16_t spr_num;
union {
uint8_t b[2];
int16_t w;
const uint8_t *p;
} data[11]; // 0x6..0x1C
};
enum {
PLAYER_FLAGS_STAIRS = 2,
PLAYER_FLAGS_FACING_LEFT = 4,
PLAYER_FLAGS_THROW_VINYL = 8,
PLAYER_FLAGS_POWERUP = 0x20,
PLAYER_FLAGS_JAKE = 0x80
};
#define player_obj_num(obj) (obj)->data[0].w // 0x6
#define player_prev_spr_num(obj) (obj)->data[1].w // 0x8
#define player_anim_data(obj) (obj)->data[2].p // 0xA
#define player_idle_counter(obj) (obj)->data[3].b[0] // 0xC
#define player_power(obj) (obj)->data[3].b[1] // 0xD
#define player_x_delta(obj) (obj)->data[4].w // 0xE
#define player_y_delta(obj) (obj)->data[5].w // 0x10
#define player_flags(obj) (obj)->data[6].b[0] // 0x12
#define player_jump_counter(obj) (obj)->data[6].b[1] // 0x13
#define player_bounce_counter(obj) (obj)->data[7].b[0] // 0x14
#define player_tilemap_offset(obj) (obj)->data[8].w // 0x16
#define player_hit_counter(obj) (obj)->data[9].b[0] // 0x18
#define player_throw_counter(obj) (obj)->data[9].b[1] // 0x19
#define player_flags2(obj) (obj)->data[10].b[0] // 0x1A, 8:dead 1:blocked
#define object_blinking_counter(obj) (obj)->data[6].b[1] // 0x13, shield, jump
// star
#define object2_spr_count(obj) (obj)->data[0].b[0]
#define object2_spr_tick(obj) (obj)->data[0].b[1]
// 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
#define object64_counter(obj) (obj)->data[1].w
#define object64_yvelocity(obj) (obj)->data[2].w
// 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
#define object82_hflip(obj) (obj)->data[3].b[0]
#define object82_counter(obj) (obj)->data[3].b[1]
#define object82_x_delta(obj) (obj)->data[4].w
#define object82_y_delta(obj) (obj)->data[5].w
#define object82_energy(obj) (obj)->data[8].w
#define object82_type0_init_data(obj) (obj)->data[4].p
#define object82_type0_player_num(obj) (obj)->data[5].w
#define object82_type0_x_delta(obj) (obj)->data[6].b[0] // signed
#define object82_type0_y_delta(obj) (obj)->data[7].b[0] // signed
#define object82_type1_hdir(obj) (obj)->data[6].b[0] // signed
#define object102_x_delta(obj) (obj)->data[0].w
#define object102_y_delta(obj) (obj)->data[1].w
struct player_t {
struct object_t obj;
int16_t unk_counter; // 0x1D always zero
int16_t change_hdir_counter;
uint8_t lifes_count;
int16_t vinyls_count;
int8_t energy;
uint8_t dir_mask; // 0x25
uint8_t ticks_counter; // 0x26
};
#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)
struct vars_t {
int level;
int player;
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
int16_t dragon_coords[1 + 128];
struct player_t players_table[2];
uint8_t player_hit_counter;
int16_t player_xscroll, player_map_offset;
struct object_t objects_table[OBJECTS_COUNT];
int level_start_1p_x_pos, level_start_1p_y_pos;
int level_start_2p_player1_x_pos, level_start_2p_player1_y_pos, level_start_2p_player2_x_pos, level_start_2p_player2_y_pos;
int level_loop_counter;
int throw_vinyl_counter;
uint8_t level_num;
uint16_t level_time, level_time2;
uint8_t level_time_counter;
uint8_t triggers_table[19 + TRIGGERS_COUNT * 16];
int tilemap_x, tilemap_y, tilemap_w, tilemap_h;
int tilemap_end_x, tilemap_end_y;
int tilemap_scroll_dx, tilemap_scroll_dy, tilemap_scroll_xoffset, tilemap_scroll_yoffset;
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_init[6 * 0x100];
uint8_t tilemap_lut_init2[0x100];
const uint8_t *tilemap_current_lut;
uint8_t tile_palette_table[0x100];
const uint8_t *level_tiles_lut;
uint8_t palette_buffer[256 * 3];
bool change_next_level_flag;
bool reset_palette_flag;
};
extern struct vars_t g_vars;
/* staticres.c */
extern const uint16_t sound_offsets[];
extern const uint16_t sprite_offsets[];
extern const uint16_t sprite_sizes[];
extern const uint8_t sprite_palettes[];
extern const uint8_t level_data1p[];
extern const uint8_t level_data2p[];
extern const uint8_t level_data3[];
extern const uint8_t level_data4[];
extern const uint8_t monster_spr_anim_data0[];
extern const uint8_t monster_spr_anim_data1[];
extern const uint8_t monster_spr_anim_data2[];
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_data8[];
extern const uint8_t monster_spr_anim_data9[];
extern const uint8_t common_palette_data[];
extern const uint8_t levels_palette_data[];
extern const uint8_t tile_lut_data0[];
extern const uint8_t tile_lut_data1[];
extern const uint8_t tile_lut_data2[];
extern const uint8_t tile_lut_data3[];
extern const uint16_t tile_funcs0[];
extern const uint16_t tile_funcs1[];
extern const uint16_t tile_funcs2[];
extern const uint16_t tile_funcs3[];
extern const uint8_t level_data_tiles_lut[];
extern const uint8_t player_anim_dy[];
extern const uint8_t player_anim_lut[];
extern const uint8_t *player_anim_table[];
/* game.c */
extern void update_input();
extern void game_main();
extern void do_game_over_screen();
extern void do_game_win_screen();
extern void do_difficulty_screen();
extern void do_level_password_screen();
extern void do_level_number_screen();
/* level.c */
extern void do_level();
/* screen.c */
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_string(const char *s, int offset, int hspace);
extern void video_copy_vga(int size);
extern void video_vsync(int delay);
extern void fade_in_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_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 video_load_sprites();
/* sound.c */
extern void sound_init();
extern void sound_fini();
extern void play_sound(int num);
extern void play_music(int num);
#endif /* GAME_H__ */

3039
ja/level.c Normal file

File diff suppressed because it is too large Load Diff

88
ja/resource.c Normal file
View File

@ -0,0 +1,88 @@
#include <sys/param.h>
#include "resource.h"
#include "unpack.h"
#include "util.h"
static const int TMP_SIZE = 72728;
static const int BACKGROUND_SIZE = 320 * 200;
static const char *_datapath;
struct resource_t g_res;
void res_init(const char *path, int vga_size) {
_datapath = path;
char filepath[MAXPATHLEN];
static const int FONT_SIZE = 7264;
g_res.font = (uint8_t *)malloc(FONT_SIZE);
if (!g_res.font) {
print_error("Failed to allocate font buffer, %d bytes", FONT_SIZE);
}
snprintf(filepath, sizeof(filepath), "%s/font256.eat", _datapath);
unpack(filepath, g_res.font, FONT_SIZE);
static const int BOARD_SIZE = 12800;
g_res.board = (uint8_t *)malloc(BOARD_SIZE);
if (!g_res.board) {
print_error("Failed to allocate board buffer, %d bytes", BOARD_SIZE);
}
snprintf(filepath, sizeof(filepath), "%s/board.eat", _datapath);
unpack(filepath, g_res.board, BOARD_SIZE);
static const int SPRITES_SIZE = 108044;
g_res.sprites = (uint8_t *)malloc(SPRITES_SIZE);
if (!g_res.sprites) {
print_error("Failed to allocate sprites buffer, %d bytes", SPRITES_SIZE);
}
snprintf(filepath, sizeof(filepath), "%s/sprites.eat", _datapath);
unpack(filepath, g_res.sprites, SPRITES_SIZE);
static const int SAMPLES_SIZE = 49398;
g_res.samples = (uint8_t *)malloc(SAMPLES_SIZE);
if (!g_res.samples) {
print_error("Failed to allocate samples buffer, %d bytes", SAMPLES_SIZE);
}
snprintf(filepath, sizeof(filepath), "%s/samples.eat", _datapath);
unpack(filepath, g_res.samples, SAMPLES_SIZE);
g_res.tmp = (uint8_t *)malloc(TMP_SIZE);
if (!g_res.tmp) {
print_error("Failed to allocate tmp buffer, %d bytes", TMP_SIZE);
}
g_res.background = (uint8_t *)malloc(BACKGROUND_SIZE);
if (!g_res.background) {
print_error("Failed to allocate tmp buffer, %d bytes", BACKGROUND_SIZE);
}
g_res.vga = (uint8_t *)malloc(vga_size);
if (!g_res.vga) {
print_error("Failed to allocate vga buffer, %d bytes", vga_size);
}
}
void res_fini() {
free(g_res.font);
g_res.font = 0;
free(g_res.board);
g_res.board = 0;
free(g_res.sprites);
g_res.sprites = 0;
free(g_res.tmp);
g_res.tmp = 0;
free(g_res.background);
g_res.background = 0;
free(g_res.vga);
g_res.vga = 0;
}
int load_file(const char *filename) {
char filepath[MAXPATHLEN];
snprintf(filepath, sizeof(filepath), "%s/%s", _datapath, filename);
print_debug(DBG_RESOURCE, "load_file '%s'", filepath);
return unpack(filepath, g_res.tmp, TMP_SIZE);
}

23
ja/resource.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef RESOURCE_H__
#define RESOURCE_H__
#include "intern.h"
struct resource_t {
uint8_t *font;
uint8_t *board;
uint8_t *sprites;
uint8_t *samples;
uint8_t *tmp;
uint8_t *background;
uint8_t *vga;
};
extern struct resource_t g_res;
extern void res_init(const char *datapath, int vga_size);
extern void res_fini();
extern int load_file(const char *filename);
#endif

225
ja/screen.c Normal file
View File

@ -0,0 +1,225 @@
/* screen drawing */
#include "game.h"
#include "resource.h"
#include "sys.h"
#include "util.h"
#define MAX_SPRITES 288
#define MAX_SPRITESHEET_W 1024
#define MAX_SPRITESHEET_H 512
void video_draw_dot_pattern(int offset) {
static const int W = 144;
uint8_t *dst = g_res.vga + (GAME_SCREEN_H - PANEL_H) * GAME_SCREEN_W + offset;
for (int y = 0; y < PANEL_H; ++y) {
for (int x = 0; x < W; x += 2) {
dst[x + (y & 1)] = 0;
}
dst += GAME_SCREEN_W;
}
}
void video_draw_sprite(int num, int x, int y, int flag) {
render_add_sprite(RENDER_SPR_GAME, num, x, y, flag != 0);
}
void video_draw_string(const char *s, int offset, int hspace) {
while (*s) {
uint8_t code = *s++;
if (code != 0x20) {
if (code >= 0x41) {
code -= 0x41;
} else {
code -= 0x16;
}
ja_decode_chr(g_res.font + code * 200, 200, g_res.tmp + 768 + offset, 320);
}
offset += hspace;
}
}
void video_copy_vga(int size) {
if (size == 0xB500) {
memcpy(g_res.background, g_res.tmp + 768, 64000);
} else {
g_sys.set_screen_palette(g_res.tmp, 0, 256, 6);
assert(size == 0x7D00);
const uint8_t *src = g_res.tmp + 768;
if (GAME_SCREEN_W * GAME_SCREEN_H == 64000) {
memcpy(g_res.vga, src, 64000);
} else {
memset(g_res.vga, 0, GAME_SCREEN_W * GAME_SCREEN_H);
for (int y = 0; y < MIN(200, GAME_SCREEN_H); ++y) {
memcpy(g_res.vga + y * GAME_SCREEN_W, src, MIN(320, GAME_SCREEN_W));
src += 320;
}
}
g_sys.update_screen(g_res.vga, 0);
}
}
void video_vsync(int delay) {
}
void fade_in_palette() {
if (!g_sys.input.quit) {
g_sys.fade_in_palette();
}
}
void fade_out_palette() {
if (!g_sys.input.quit) {
g_sys.fade_out_palette();
}
}
void ja_decode_spr(const uint8_t *src, int w, int h, uint8_t *dst, int dst_pitch, uint8_t pal_mask) {
const int bitplane_size = w * h;
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; ++x) {
for (int i = 0; i < 8; ++i) {
int color = 0;
const int mask = 1 << (7 - i);
for (int bit = 0; bit < 4; ++bit) {
if (src[bit * bitplane_size] & mask) {
color |= 1 << bit;
}
}
if (color != 0) {
dst[x * 8 + i] = pal_mask | color;
}
}
++src;
}
dst += dst_pitch;
}
}
void ja_decode_chr(const uint8_t *buffer, const int size, uint8_t *dst, int dst_pitch) {
for (int y = 0; y < 25; ++y) {
const int offset = y * 2;
const uint16_t p[] = {
READ_BE_UINT16(buffer + offset),
READ_BE_UINT16(buffer + offset + 50),
READ_BE_UINT16(buffer + offset + 100),
READ_BE_UINT16(buffer + offset + 150)
};
for (int x = 0; x < 16; ++x) {
const uint16_t mask = 1 << (15 - x);
uint8_t color = 0;
for (int b = 0; b < 4; ++b) {
if (p[b] & mask) {
color |= (1 << b);
}
}
if (color != 0) {
dst[x] = 0xD0 | color;
}
}
dst += dst_pitch;
}
}
void ja_decode_tile(const uint8_t *buffer, uint8_t pal_mask, uint8_t *dst, int dst_pitch, int x_offset, int y_offset) {
int tile_w = 16;
if (x_offset < 0) {
tile_w += x_offset;
buffer -= x_offset / 2;
x_offset = 0;
}
if (x_offset + tile_w > TILEMAP_SCREEN_W) {
tile_w = TILEMAP_SCREEN_W - x_offset;
}
if (tile_w <= 0) {
return;
}
int tile_h = 16;
if (y_offset < 0) {
tile_h += y_offset;
buffer -= y_offset * 8;
y_offset = 0;
}
if (y_offset + tile_h > TILEMAP_SCREEN_H) {
tile_h = TILEMAP_SCREEN_H - y_offset;
}
if (tile_h <= 0) {
return;
}
dst += y_offset * dst_pitch + x_offset;
for (int y = 0; y < tile_h; ++y) {
uint8_t *p = dst;
for (int x = 0; x < tile_w / 2; ++x) {
const uint8_t color1 = buffer[x] >> 4;
const uint8_t color2 = buffer[x] & 15;
if (color1 != 0) {
*p = pal_mask | color1;
}
++p;
if (color2 != 0) {
*p = pal_mask | color2;
}
++p;
}
buffer += 8;
dst += dst_pitch;
}
}
void video_load_sprites() {
struct sys_rect_t r[MAX_SPRITES];
uint8_t *data = (uint8_t *)calloc(MAX_SPRITESHEET_W * MAX_SPRITESHEET_H, 1);
if (data) {
int current_x = 0;
int max_w = 0;
int current_y = 0;
int max_h = 0;
int total_size = 0;
int count = 0;
uint8_t value;
for (int i = 0; (value = sprite_offsets[i] & 255) != 0; ++i, ++count) {
value = (value >> 3) | ((value & 7) << 5);
if ((value & 0xE0) != 0) {
value &= ~0xE0;
++value;
}
const int h = sprite_offsets[i] >> 8;
const int w = value * 8;
assert((sprite_offsets[i] & 255) == w);
const int size = (h * value) * 4;
if (current_x + w > MAX_SPRITESHEET_W) {
current_y += max_h;
if (current_x > max_w) {
max_w = current_x;
}
current_x = 0;
max_h = h;
} else {
if (h > max_h) {
max_h = h;
}
}
ja_decode_spr(g_res.sprites + total_size, w / 8, h, data + current_y * MAX_SPRITESHEET_W + current_x, MAX_SPRITESHEET_W, sprite_palettes[i] * 0x10);
total_size += size;
r[i].x = current_x;
r[i].y = current_y;
r[i].w = w;
r[i].h = h;
current_x += w;
if (h > max_h) {
max_h = h;
}
}
assert(count <= MAX_SPRITES);
assert(max_w <= MAX_SPRITESHEET_W);
assert(current_y + max_h <= MAX_SPRITESHEET_H);
render_unload_sprites(RENDER_SPR_GAME);
render_load_sprites(RENDER_SPR_GAME, count, r, data, MAX_SPRITESHEET_W, current_y + max_h, 0, 0x0);
free(data);
}
}

123
ja/sound.c Normal file
View File

@ -0,0 +1,123 @@
#include "game.h"
#include "resource.h"
#include "sys.h"
#include "util.h"
#include <libmodplug/modplug.h>
#define MAX_SOUNDS 16
static const char *_modules[] = {
"almost.mod",
"every.mod",
"bartende.mod",
"petergun.mod",
"shoot.mod"
};
struct mixerchannel_t {
uint8_t *data;
uint32_t pos;
uint32_t step;
uint32_t size;
const int8_t *seq;
};
static struct {
uint16_t offset;
uint16_t size;
} _samples[MAX_SOUNDS];
static const int _rate = SYS_AUDIO_FREQ;
static struct mixerchannel_t _channel;
static ModPlugFile *_mpf;
static void mix(void *param, uint8_t *buf, int len) {
memset(buf, 0, len);
if (_mpf) {
const int count = ModPlug_Read(_mpf, buf, len);
if (count == 0) {
ModPlug_SeekOrder(_mpf, 0);
}
}
if (_channel.data) {
for (int i = 0; i < len; i += sizeof(int16_t)) {
int pos = _channel.pos >> 16;
if (pos >= _channel.size) {
const int next = _channel.seq ? *_channel.seq++ : -1;
if (next < 0) {
_channel.data = 0;
break;
}
_channel.data = g_res.samples + _samples[next].offset;
_channel.pos = pos = 0;
_channel.size = _samples[next].size;
}
const int sample = *(int16_t *)(buf + i) + ((int8_t)_channel.data[pos]) * 256;
*(int16_t *)(buf + i) = (sample < -32768 ? -32768 : (sample > 32767 ? 32767 : sample));
_channel.pos += _channel.step;
}
}
}
void sound_init() {
ModPlug_Settings mp_settings;
memset(&mp_settings, 0, sizeof(mp_settings));
ModPlug_GetSettings(&mp_settings);
mp_settings.mFlags = MODPLUG_ENABLE_OVERSAMPLING | MODPLUG_ENABLE_NOISE_REDUCTION;
mp_settings.mChannels = 1;
mp_settings.mBits = 16;
mp_settings.mFrequency = _rate;
mp_settings.mResamplingMode = MODPLUG_RESAMPLE_FIR;
mp_settings.mLoopCount = -1;
ModPlug_SetSettings(&mp_settings);
g_sys.start_audio(mix, 0);
uint16_t offset = 0;
for (int i = 0; i < MAX_SOUNDS; ++i) {
const int num = i;
_samples[i].size = sound_offsets[num];
_samples[i].offset = offset;
offset += _samples[i].size;
}
}
void sound_fini() {
g_sys.stop_audio();
}
void play_sound(int num) {
assert(num < MAX_SOUNDS);
const int sample_offset = _samples[num].offset;
const int sample_size = _samples[num].size;
print_debug(DBG_MIXER, "sample num %d offset 0x%x size %d", num, sample_offset, sample_size);
if (sample_size == 0) {
return;
}
g_sys.lock_audio();
_channel.data = g_res.samples + sample_offset;
_channel.pos = 0;
_channel.step = (8000 << 16) / _rate;
_channel.size = sample_size;
if (num == 10) {
static const int8_t seq[] = { 10, 10, 10, 6, -1 };
_channel.seq = seq + 1;
} else {
_channel.seq = 0;
}
g_sys.unlock_audio();
}
void play_music(int num) {
g_sys.lock_audio();
if (_mpf) {
ModPlug_Unload(_mpf);
_mpf = 0;
}
const int size = load_file(_modules[num]);
_mpf = ModPlug_Load(g_res.tmp, size);
if (_mpf) {
print_debug(DBG_MIXER, "Loaded module '%s'", ModPlug_GetName(_mpf));
}
g_sys.unlock_audio();
}

670
ja/staticres.c Normal file
View File

@ -0,0 +1,670 @@
#include "intern.h"
const uint16_t sound_offsets[] = {
0x04CA,0x185C,0x0F4C,0x05EC,0x0762,0x0898,0x1188,0x0000,0x0CC4,0x1378,0x089C,0x0606,0x0000,0x0000,0x1254,0x2BE4
};
const uint16_t sprite_offsets[] = {
0x2510,0x2420,0x2518,0x2518,0x2420,0x2518,0x1C18,0x1528,0x1528,0x1420,0x2618,0x2620,0x2420,0x2818,0x2318,0x2320,
0x1F28,0x2418,0x2320,0x2128,0x2418,0x2418,0x2418,0x1820,0x1E20,0x2620,0x2720,0x2718,0x2618,0x2718,0x2720,0x2520,
0x2A18,0x2020,0x1A20,0x2820,0x2820,0x1E20,0x2520,0x2520,0x2520,0x1C28,0x1010,0x1010,0x1010,0x1010,0x1010,0x0F10,
0x0808,0x0A08,0x2018,0x2010,0x1F18,0x2010,0x2018,0x1E20,0x1620,0x1720,0x1620,0x1620,0x2218,0x1E18,0x1F18,0x2218,
0x1E18,0x1E20,0x1E28,0x1F20,0x1C18,0x2220,0x1F18,0x1F18,0x1F18,0x1420,0x1820,0x2018,0x2118,0x2120,0x2020,0x2120,
0x2118,0x2120,0x2518,0x1C20,0x1B20,0x2420,0x2220,0x1B20,0x2120,0x2120,0x2120,0x1D20,0x0F10,0x1018,0x1010,0x1010,
0x0A10,0x0610,0x0608,0x0808,0x0910,0x0B10,0x0B10,0x0A08,0x0C10,0x0C10,0x0C10,0x0D10,0x0E10,0x0D10,0x0C10,0x0D10,
0x0E10,0x0E10,0x0E10,0x0C10,0x2D20,0x2D28,0x3330,0x2F38,0x2A30,0x2328,0x2128,0x2420,0x2320,0x2418,0x2528,0x2720,
0x2D30,0x2D30,0x2D30,0x2A30,0x2028,0x1D28,0x1F20,0x2020,0x1F18,0x2028,0x2320,0x1E18,0x2218,0x2318,0x2318,0x2220,
0x2318,0x2318,0x2518,0x2418,0x2220,0x1C18,0x2218,0x2218,0x2218,0x2718,0x2818,0x2820,0x2720,0x2820,0x2818,0x2920,
0x2920,0x2120,0x2820,0x2820,0x2720,0x1918,0x1A18,0x1A18,0x1918,0x1A18,0x1A18,0x1C18,0x1C18,0x1818,0x1720,0x1A18,
0x1A18,0x1A18,0x2020,0x2120,0x2120,0x2018,0x2120,0x2120,0x2420,0x2220,0x1D20,0x2120,0x2120,0x2220,0x0F10,0x0C10,
0x0610,0x0F10,0x0D10,0x1010,0x1010,0x1010,0x3028,0x2030,0x2020,0x0E08,0x0D10,0x2010,0x1010,0x1040,0x1D20,0x1B30,
0x1A20,0x1920,0x1D20,0x1D20,0x1F28,0x1D20,0x1718,0x1518,0x1518,0x1828,0x1628,0x1628,0x2828,0x0828,0x0A28,0x0A28,
0x2020,0x0B30,0x1830,0x1F20,0x1F10,0x1828,0x2428,0x2528,0x1F28,0x1010,0x0D10,0x0808,0x1D30,0x1E30,0x2030,0x2030,
0x1618,0x1718,0x1040,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F08,0x0F10,0x0F10,0x0F10,0x0F10,
0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F08,0x0F10,0x0408,
0x0410,0x0F10,0x0F08,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0F10,0x0000
};
const uint16_t sprite_sizes[] = {
0x2508,0x2410,0x250C,0x250C,0x2410,0x250C,0x1C0C,0x1514,0x1514,0x1410,0x260C,0x2610,0x2410,0x280C,0x270D,0x2310,
0x1F14,0x240E,0x2316,0x2114,0x240C,0x240C,0x240C,0x1810,0x1E10,0x2610,0x2710,0x270C,0x260C,0x270C,0x2710,0x2510,
0x2A0C,0x2010,0x1A10,0x2810,0x2810,0x1E10,0x2510,0x2510,0x2510,0x1C14,0x1008,0x1008,0x1008,0x1008,0x1008,0x0F08,
0x0804,0x0A04,0x200C,0x2008,0x1F0C,0x2008,0x200C,0x1E10,0x1610,0x1710,0x1610,0x1610,0x220C,0x1E0C,0x1F0C,0x220C,
0x1E0C,0x1E10,0x1E14,0x1F10,0x1C0C,0x2210,0x1F0C,0x1F0C,0x1F0C,0x1410,0x1810,0x200C,0x210C,0x2110,0x2010,0x2110,
0x210C,0x2110,0x250C,0x1C10,0x1B10,0x2410,0x2210,0x1B10,0x2110,0x2110,0x2110,0x1D10,0x0F08,0x100C,0x1008,0x1008,
0x0A08,0x0608,0x0604,0x0804,0x0908,0x0B08,0x0B08,0x0A04,0x0C08,0x0C08,0x0C08,0x0D08,0x0E08,0x0D08,0x0C08,0x0D08,
0x0E08,0x0E08,0x0E08,0x0C08,0x2D10,0x2D14,0x3118,0x2F1C,0x2C18,0x2A14,0x2A14,0x2A10,0x2910,0x290C,0x2913,0x2B10,
0x2E18,0x2C18,0x3019,0x2B17,0x2714,0x2714,0x2710,0x2710,0x270C,0x2714,0x2310,0x1E0C,0x220C,0x230C,0x230C,0x2210,
0x230C,0x230C,0x250C,0x240C,0x2210,0x1C0C,0x220C,0x220C,0x220C,0x270C,0x280C,0x2810,0x2710,0x2810,0x280C,0x2910,
0x2910,0x2110,0x2810,0x2810,0x2710,0x190C,0x1A0C,0x1A0C,0x190C,0x1A0C,0x1A0C,0x1C0C,0x1C0C,0x180C,0x1710,0x1A0C,
0x1A0C,0x1A0C,0x2010,0x2110,0x2110,0x200C,0x2110,0x2110,0x2410,0x2210,0x1D10,0x2110,0x2110,0x2210,0x0F08,0x0C08,
0x0608,0x0F08,0x0D08,0x1008,0x1008,0x1008,0x3014,0x2018,0x2010,0x0E04,0x0D08,0x2008,0x1008,0x1020,0x1D10,0x1B18,
0x1A10,0x1910,0x1D10,0x1D10,0x1F14,0x1D10,0x170C,0x150C,0x150C,0x1814,0x1614,0x1614,0x2814,0x0814,0x0A14,0x0A14,
0x2010,0x0B18,0x1818,0x1F10,0x1F08,0x1814,0x120D,0x120E,0x120F,0x0608,0x0507,0x0304,0x1D18,0x1E18,0x2018,0x2018,
0x160C,0x170C,0x1020,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F04,0x0F08,0x0F08,0x0F08,0x0F08,
0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F04,0x0F08,0x0404,
0x0408,0x0F08,0x0F04,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0F08,0x0000
};
const uint8_t sprite_palettes[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x03,
0x03,0x03,0x03,0x03,0x03,0x03,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x05,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
0x07,0x07,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
const uint8_t level_data1p[] = {
0x00,0x02,0x00,0x05,0x01,0x00,0x01,0x06,0x02,0x00,0x02,0x01,0x00,0x00,0x01,0x07,
0x02,0x02,0x03,0x01,0x00,0x04,0x00,0x03,0x01,0x01,0x01,0x03,0x02,0x03,0x02,0x04,
0x03,0x06,0x03,0x05,0x00,0x06,0x00,0x08,0x00,0x07,0x01,0x04,0x01,0x05,0x02,0x05,
0x02,0x06,0x02,0x07,0x02,0x08,0x03,0x02,0x03,0x03,0x03,0x04,0x01,0x08,0xFF,0xFF
};
const uint8_t level_data2p[] = {
0x00,0x02,0x00,0x05,0x01,0x00,0x01,0x06,0x02,0x00,0x02,0x01,0x00,0x00,0x01,0x07,
0x02,0x02,0x03,0x01,0x00,0x04,0x00,0x03,0x01,0x01,0x01,0x03,0x02,0x03,0x02,0x04,
0x03,0x06,0x03,0x05,0x00,0x08,0x00,0x07,0x01,0x04,0x01,0x05,0x02,0x05,0x02,0x06,
0x02,0x08,0x03,0x02,0x03,0x03,0x03,0x04,0x01,0x08,0xFF,0xFF
};
const uint8_t level_data3[] = {
0x09,0x09,0x09,0x07,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00
};
const uint8_t level_data4[] = {
0x2D,0x2D,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x30,0x2D,0x2D,0x2D,0x2D,
0x41,0x2D,0x45,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x41,0x2D,
0x44,0x46,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x43,0x2D,
0x42,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x37,0x38,0x39,0x2D,0x34,0x35,0x36,0x2D,0x31,
0x32,0x33,0x30,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
0x05,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x08,0x08,
0x08,0x09,0x09,0x09,0x0A,0x0A,0x0B,0x0B,0x0C,0x0D,0x0E,0x10,0x10,0x10,0x10,0x10,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x01,0xFF,0x01,0xFF,
0x01,0xFF,0x01,0xFF,0x02,0xFF,0x02,0xFF,0x03,0xFF,0x04,0xFF,0x05,0xFF,0x07,0xFF,
0x08,0xFF,0x0A,0xFF,0x0C,0xFF,0x0D,0xFF,0x0F,0xFF,0x12,0xFF,0x14,0xFF,0x16,0xFF,
0x19,0xFF,0x1C,0xFF,0x1F,0xFF,0x22,0xFF,0x25,0xFF,0x28,0xFF,0x2C,0xFF,0x2F,0xFF,
0x33,0xFF,0x37,0xFF,0x3B,0xFF,0x3F,0xFF,0x43,0xFF,0x47,0xFF,0x4B,0xFF,0x50,0xFF,
0x55,0xFF,0x59,0xFF,0x5E,0xFF,0x63,0xFF,0x68,0xFF,0x6D,0xFF,0x72,0xFF,0x78,0xFF,
0x7D,0xFF,0x82,0xFF,0x88,0xFF,0x8D,0xFF,0x93,0xFF,0x99,0xFF,0x9F,0xFF,0xA4,0xFF,
0xAA,0xFF,0xB0,0xFF,0xB6,0xFF,0xBC,0xFF,0xC2,0xFF,0xC8,0xFF,0xCF,0xFF,0xD5,0xFF,
0xDB,0xFF,0xE1,0xFF,0xE7,0xFF,0xEE,0xFF,0xF4,0xFF,0xFA,0xFF,0x00,0x00,0x00,0x00,
0x06,0x00,0x0C,0x00,0x12,0x00,0x19,0x00,0x1F,0x00,0x25,0x00,0x2B,0x00,0x31,0x00,
0x38,0x00,0x3E,0x00,0x44,0x00,0x4A,0x00,0x50,0x00,0x56,0x00,0x5C,0x00,0x61,0x00,
0x67,0x00,0x6D,0x00,0x73,0x00,0x78,0x00,0x7E,0x00,0x83,0x00,0x88,0x00,0x8E,0x00,
0x93,0x00,0x98,0x00,0x9D,0x00,0xA2,0x00,0xA7,0x00,0xAB,0x00,0xB0,0x00,0xB5,0x00,
0xB9,0x00,0xBD,0x00,0xC1,0x00,0xC5,0x00,0xC9,0x00,0xCD,0x00,0xD1,0x00,0xD4,0x00,
0xD8,0x00,0xDB,0x00,0xDE,0x00,0xE1,0x00,0xE4,0x00,0xE7,0x00,0xEA,0x00,0xEC,0x00,
0xEE,0x00,0xF1,0x00,0xF3,0x00,0xF4,0x00,0xF6,0x00,0xF8,0x00,0xF9,0x00,0xFB,0x00,
0xFC,0x00,0xFD,0x00,0xFE,0x00,0xFE,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFE,0x00,0xFE,0x00,0xFD,0x00,0xFC,0x00,0xFB,0x00,
0xF9,0x00,0xF8,0x00,0xF6,0x00,0xF4,0x00,0xF3,0x00,0xF1,0x00,0xEE,0x00,0xEC,0x00,
0xEA,0x00,0xE7,0x00,0xE4,0x00,0xE1,0x00,0xDE,0x00,0xDB,0x00,0xD8,0x00,0xD4,0x00,
0xD1,0x00,0xCD,0x00,0xC9,0x00,0xC5,0x00,0xC1,0x00,0xBD,0x00,0xB9,0x00,0xB5,0x00,
0xB0,0x00,0xAB,0x00,0xA7,0x00,0xA2,0x00,0x9D,0x00,0x98,0x00,0x93,0x00,0x8E,0x00,
0x88,0x00,0x83,0x00,0x7E,0x00,0x78,0x00,0x73,0x00,0x6D,0x00,0x67,0x00,0x61,0x00,
0x5C,0x00,0x56,0x00,0x50,0x00,0x4A,0x00,0x44,0x00,0x3E,0x00,0x38,0x00,0x31,0x00,
0x2B,0x00,0x25,0x00,0x1F,0x00,0x19,0x00,0x12,0x00,0x0C,0x00,0x06,0x00,0x00,0x00,
0xFA,0xFF,0xF4,0xFF,0xEE,0xFF,0xE7,0xFF,0xE1,0xFF,0xDB,0xFF,0xD5,0xFF,0xCF,0xFF,
0xC8,0xFF,0xC2,0xFF,0xBC,0xFF,0xB6,0xFF,0xB0,0xFF,0xAA,0xFF,0xA4,0xFF,0x9F,0xFF,
0x99,0xFF,0x93,0xFF,0x8D,0xFF,0x88,0xFF,0x82,0xFF,0x7D,0xFF,0x78,0xFF,0x72,0xFF,
0x6D,0xFF,0x68,0xFF,0x63,0xFF,0x5E,0xFF,0x59,0xFF,0x55,0xFF,0x50,0xFF,0x4B,0xFF,
0x47,0xFF,0x43,0xFF,0x3F,0xFF,0x3B,0xFF,0x37,0xFF,0x33,0xFF,0x2F,0xFF,0x2C,0xFF,
0x28,0xFF,0x25,0xFF,0x22,0xFF,0x1F,0xFF,0x1C,0xFF,0x19,0xFF,0x16,0xFF,0x14,0xFF,
0x12,0xFF,0x0F,0xFF,0x0D,0xFF,0x0C,0xFF,0x0A,0xFF,0x08,0xFF,0x07,0xFF,0x05,0xFF,
0x04,0xFF,0x03,0xFF,0x02,0xFF,0x02,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,0x01,0xFF,
0x01,0xFF,0x01,0xFF,0x01,0xFF,0x02,0xFF,0x02,0xFF,0x03,0xFF,0x04,0xFF,0x05,0xFF,
0x07,0xFF,0x08,0xFF,0x0A,0xFF,0x0C,0xFF,0x0D,0xFF,0x0F,0xFF,0x12,0xFF,0x14,0xFF,
0x16,0xFF,0x19,0xFF,0x1C,0xFF,0x1F,0xFF,0x22,0xFF,0x25,0xFF,0x28,0xFF,0x2C,0xFF,
0x2F,0xFF,0x33,0xFF,0x37,0xFF,0x3B,0xFF,0x3F,0xFF,0x43,0xFF,0x47,0xFF,0x4B,0xFF,
0x50,0xFF,0x55,0xFF,0x59,0xFF,0x5E,0xFF,0x63,0xFF,0x68,0xFF,0x6D,0xFF,0x72,0xFF,
0x78,0xFF,0x7D,0xFF,0x82,0xFF,0x88,0xFF,0x8D,0xFF,0x93,0xFF,0x99,0xFF,0x9F,0xFF,
0xA4,0xFF,0xAA,0xFF,0xB0,0xFF,0xB6,0xFF,0xBC,0xFF,0xC2,0xFF,0xC8,0xFF,0xCF,0xFF,
0xD5,0xFF,0xDB,0xFF,0xE1,0xFF,0xE7,0xFF,0xEE,0xFF,0xF4,0xFF,0xFA,0xFF,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,
0x05,0x00,0x06,0x00,0x07,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,
0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,
0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,
0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,
0x09,0x09,0x08,0x08,0x08,0x07,0x07,0x07,0x06,0x06,0x06,0x05,0x05,0x05,0x04,0x04,
0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x09,0x09,
0x04,0x03,0x03,0x03,0x02,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x0F,0x0F,0x0F,0x0E,
0x0E,0x0E,0x0D,0x0D,0x0D,0x0C,0x0C,0x0C,0x0B,0x0B,0x0B,0x0A,0x0A,0x0A,0x09,0x09,
0x09,0x09,0x0A,0x0A,0x0A,0x0B,0x0B,0x0B,0x0C,0x0C,0x0C,0x0D,0x0D,0x0D,0x0E,0x0E,
0x0E,0x0F,0x0F,0x0F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
0x00,0x00,0x00,0x00,0x00,0x1D,0x1E,0x00,0x04,0x01,0x01,0x01,0x00,0x00,0x00,0x0B,
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x1B,0x05,0x00,0x05,0x00,0x01,0x01,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x00,0x07,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x05,0x1C,0x1A,0x05,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x0B,0x0C,0x0D,0x0E,0x0F,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x00,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x22,0x21,0x22,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x2A,0x2A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x00,0x1F,0x20,0x00,0x00,0x1D,0x1E,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1A,
0x19,0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x06,0x06,0x06,0x06,0x06,0x06,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,
0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x00,
0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,
0x00,0x02,0x02,0x00,0x02,0x02,0x02,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,
0x00,0x02,0x02,0x00,0x00,0x02,0x02,0x00,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x02,0x02,0x02,0x02,0x00,0x00,0x24,0x24,0x24,0x25,0x25,0x25,0x02,0x00,0x00,
0x00,0x00,0x00,0x00,0x0A,0x0A,0x0A,0x02,0x02,0x00,0x00,0x21,0x22,0x21,0x22,0x0A,
0x0A,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x02,0x02,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,
0x01,0x01,0x08,0x01,0x01,0x26,0x26,0x26,0x27,0x27,0x27,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x06,0x06,0x06,0x06,0x06,0x06,
0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x08,0x01,0x02,0x02,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x23,0x23,0x00,0x08,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,
0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x23,0x23,0x02,0x08,0x02,0x02,0x00,
0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x23,0x08,
0x08,0x02,0x02,0x00,0x00,0x02,0x00,0x00,0x23,0x23,0x23,0x23,0x00,0x00,0x00,0x00,
0x24,0x24,0x24,0x25,0x25,0x25,0x02,0x26,0x26,0x26,0x27,0x27,0x27,0x28,0x28,0x28,
0x00,0x00,0x08,0x00,0x02,0x02,0x00,0x23,0x00,0x00,0x00,0x21,0x22,0x21,0x22,0x08,
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,
0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,
0x22,0x21,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x02,0x02,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02,0x02,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x02,0x23,0x23,0x23,0x23,0x23,0x23,
0x23,0x23,0x23,0x23,0x02,0x02,0x02,0x02,0x23,0x00,0x00,0x00,0x00,0x02,0x02,0x02,
0x02,0x02,0x02,0x02,0x23,0x02,0x02,0x02,0x02,0x02,0x23,0x02,0x23,0x00,0x00,0x00,
0x02,0x02,0x23,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,
0xAA,0x5D,0x83,0x5E,0x83,0x5E,0xAA,0x5D,0x73,0x5F,0xAA,0x5D,0xAA,0x5D,0x78,0x5F,
0xAA,0x5D,0x83,0x5E,0x83,0x5E,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,
0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,
0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,
0x7B,0x5F,0x0E,0x5F,0x0E,0x5F,0x83,0x5E,0xAA,0x5D,0xAA,0x5D,0xAA,0x5D,0xAA,0x5D,
0xAA,0x5D,0xAA,0x5D,0x0E,0x5F,0xAA,0x5D,0x83,0x5E,0x83,0x5E,0xAA,0x5D,0x73,0x5F,
0xAA,0x5D,0xEC,0x5E,0x78,0x5F,0x3E,0x5D,0x83,0x5E,0x83,0x5E,0x7B,0x5F,0x7B,0x5F,
0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,
0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,
0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x16,0x5F,0x16,0x5F,0xA7,0x5F,0x94,0x5F,
0x94,0x5F,0x94,0x5F,0x94,0x5F,0x94,0x5F,0x94,0x5F,0x0E,0x5F,0xC8,0x5D,0xC8,0x5D,
0xC9,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC9,0x5D,
0xC9,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,
0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,
0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,
0xC8,0x5D,0x9E,0x5F,0x94,0x5F,0x94,0x5F,0x94,0x5F,0x94,0x5F,0x94,0x5F,0x94,0x5F,
0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0x58,0x5E,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,0xC8,0x5D,
0xC8,0x5D,0xC8,0x5D,0x58,0x5E,0x58,0x5E,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,
0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,
0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,0x7B,0x5F,
0x7B,0x5F,0x7B,0x5F,0xC8,0x5D,0xC8,0x5D,0x9E,0x5F,0x94,0x5F,0x94,0x5F,0x94,0x5F,
0x94,0x5F,0x94,0x5F,0x94,0x5F,0xC8,0x5D
};
const uint8_t monster_spr_anim_data0[] = {
0xE6,0x00,0xFF,0xFF
};
const uint8_t monster_spr_anim_data1[] = {
0xD6,0x00,0xD7,0x00,0xFE,0xFF,0x00,0x7D,0xD8,0x00,0xFF,0xFF
};
const uint8_t monster_spr_anim_data2[] = {
0xD9,0x00,0xD9,0x00,0xD9,0x00,0xDB,0x00,0xDB,0x00,0xDB,0x00,0xDA,0x00,0xDA,0x00,
0xDA,0x00,0xF7,0xFF,0x00,0x7D,0xDC,0x00,0xFF,0xFF
};
const uint8_t monster_spr_anim_data3[] = {
0xE1,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[] = {
0xEC,0x00,0xEC,0x00,0xED,0x00,0xED,0x00,0xFC,0xFF,0xEE,0x00,0xFF,0xFF,0x00,0x7D,
0xEF,0x00,0xFF,0xFF
};
const uint8_t monster_spr_anim_data8[] = {
0xCE,0x00,0xCE,0x00,0xCE,0x00,0xCF,0x00,0xCF,0x00,0xCF,0x00,0xD0,0x00,0xD0,0x00,
0xD0,0x00,0xD1,0x00,0xD1,0x00,0xD1,0x00,0xF4,0xFF,0xCE,0x00,0xCE,0x00,0xCF,0x00,
0xCF,0x00,0xD0,0x00,0xD0,0x00,0xD1,0x00,0xD1,0x00,0xF8,0xFF,0x00,0x7D,0xD4,0x00,
0xFF,0xFF
};
const uint8_t monster_spr_anim_data9[] = {
0xC6,0x00,0xFF,0xFF
};
const uint8_t common_palette_data[] = {
0x00,0x00,0x00,0x0C,0x14,0x10,0x04,0x0C,0x08,0x3C,0x3C,0x3C,0x1C,0x20,0x28,0x10,
0x14,0x20,0x0C,0x10,0x1C,0x08,0x0C,0x18,0x04,0x08,0x14,0x04,0x04,0x04,0x3C,0x38,
0x30,0x3C,0x30,0x24,0x30,0x24,0x1C,0x24,0x14,0x0C,0x20,0x28,0x24,0x10,0x18,0x14,
0x3F,0x3F,0x3F,0x08,0x08,0x18,0x18,0x10,0x20,0x18,0x18,0x30,0x20,0x20,0x38,0x38,
0x38,0x38,0x3F,0x3E,0x00,0x2F,0x2E,0x00,0x30,0x18,0x10,0x20,0x10,0x00,0x18,0x00,
0x00,0x1C,0x00,0x00,0x27,0x00,0x00,0x33,0x00,0x00,0x3F,0x10,0x10,0x00,0x00,0x00,
0x04,0x28,0x00,0x20,0x1C,0x20,0x1C,0x14,0x1C,0x18,0x0C,0x18,0x10,0x08,0x10,0x0C,
0x04,0x0C,0x08,0x00,0x08,0x04,0x00,0x04,0x24,0x10,0x04,0x1C,0x0C,0x04,0x18,0x08,
0x04,0x14,0x04,0x00,0x0C,0x00,0x00,0x08,0x00,0x00,0x00,0x04,0x08,0x00,0x00,0x00,
0x06,0x07,0x08,0x3C,0x3C,0x3C,0x24,0x2C,0x28,0x2C,0x14,0x10,0x24,0x10,0x0C,0x1C,
0x0C,0x08,0x14,0x08,0x08,0x0C,0x04,0x04,0x04,0x00,0x00,0x0C,0x14,0x10,0x3C,0x38,
0x30,0x3C,0x30,0x24,0x30,0x24,0x1C,0x24,0x14,0x0C,0x20,0x28,0x24,0x10,0x18,0x14,
0x14,0x10,0x0C,0x3C,0x3C,0x3C,0x1C,0x20,0x28,0x10,0x14,0x20,0x0C,0x10,0x1C,0x08,
0x0C,0x18,0x04,0x08,0x14,0x04,0x04,0x10,0x18,0x10,0x18,0x18,0x20,0x1C,0x20,0x18,
0x20,0x0C,0x14,0x10,0x08,0x10,0x0C,0x2C,0x28,0x2C,0x04,0x0C,0x08,0x00,0x08,0x04,
0x14,0x00,0x14,0x10,0x3C,0x3C,0x10,0x34,0x34,0x0C,0x30,0x30,0x0C,0x28,0x28,0x08,
0x24,0x24,0x08,0x1C,0x1C,0x08,0x18,0x18,0x04,0x10,0x10,0x04,0x0C,0x0C,0x00,0x04,
0x04,0x00,0x00,0x00,0x24,0x24,0x24,0x14,0x14,0x14,0x0C,0x0C,0x0C,0x30,0x34,0x34,
0x14,0x14,0x14,0x24,0x1C,0x1C,0x20,0x18,0x18,0x1C,0x14,0x14,0x18,0x10,0x10,0x14,
0x0C,0x0C,0x10,0x08,0x08,0x08,0x04,0x04,0x18,0x18,0x14,0x04,0x04,0x04,0x10,0x10,
0x0C,0x00,0x30,0x00,0x00,0x24,0x00,0x00,0x14,0x00,0x3C,0x3C,0x3C,0x2C,0x1C,0x28,
0x14,0x1C,0x0C,0x3C,0x3C,0x3C,0x28,0x1C,0x1C,0x20,0x14,0x14,0x1C,0x0C,0x0C,0x18,
0x08,0x08,0x10,0x04,0x04,0x0C,0x0C,0x04,0x14,0x14,0x10,0x18,0x18,0x1C,0x18,0x18,
0x14,0x14,0x14,0x18,0x10,0x10,0x14,0x10,0x10,0x08,0x08,0x0C,0x10,0x00,0x08,0x04
};
const uint8_t levels_palette_data[] = {
0x00,0x34,0x38,0x20,0x28,0x10,0x1C,0x28,0x00,0x18,0x20,0x0C,0x10,0x14,0x04,0x08,
0x0C,0x04,0x14,0x18,0x10,0x14,0x14,0x08,0x00,0x08,0x00,0x04,0x0C,0x14,0x08,0x10,
0x18,0x0C,0x14,0x24,0x10,0x1C,0x28,0x14,0x2C,0x34,0x0C,0x20,0x00,0x10,0x24,0x00,
0x00,0x34,0x38,0x30,0x34,0x2C,0x38,0x20,0x10,0x38,0x24,0x20,0x0C,0x20,0x00,0x10,
0x24,0x00,0x14,0x2C,0x00,0x18,0x34,0x00,0x3C,0x30,0x14,0x38,0x10,0x10,0x2D,0x00,
0x2D,0x21,0x00,0x21,0x16,0x00,0x16,0x00,0x10,0x38,0x28,0x3C,0x10,0x28,0x3C,0x10,
0x00,0x34,0x38,0x00,0x28,0x38,0x38,0x2C,0x20,0x34,0x24,0x18,0x2C,0x20,0x18,0x20,
0x18,0x08,0x1C,0x14,0x08,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x14,0x00,0x00,0x18,
0x00,0x00,0x20,0x00,0x1C,0x2C,0x00,0x3C,0x38,0x20,0x28,0x38,0x10,0x20,0x2C,0x00,
0x00,0x34,0x38,0x38,0x3C,0x38,0x00,0x14,0x00,0x00,0x18,0x00,0x00,0x20,0x00,0x08,
0x2C,0x00,0x00,0x00,0x00,0x3C,0x38,0x20,0x18,0x0C,0x08,0x20,0x10,0x08,0x20,0x14,
0x08,0x28,0x18,0x10,0x34,0x20,0x14,0x3C,0x28,0x0C,0x3C,0x2C,0x08,0x00,0x34,0x38,
0x00,0x34,0x38,0x28,0x2C,0x30,0x28,0x00,0x04,0x1C,0x00,0x04,0x00,0x18,0x04,0x00,
0x2C,0x04,0x34,0x38,0x3C,0x10,0x28,0x34,0x28,0x30,0x34,0x34,0x00,0x04,0x20,0x20,
0x24,0x1C,0x1C,0x20,0x14,0x14,0x18,0x10,0x10,0x14,0x0C,0x0C,0x10,0x3C,0x3C,0x3C,
0x00,0x24,0x26,0x14,0x10,0x0C,0x10,0x0C,0x08,0x0C,0x08,0x04,0x08,0x04,0x00,0x00,
0x00,0x00,0x22,0x07,0x00,0x2B,0x17,0x04,0x35,0x29,0x0A,0x3F,0x3F,0x12,0x00,0x00,
0x06,0x03,0x04,0x11,0x0B,0x0C,0x1D,0x18,0x18,0x28,0x29,0x29,0x33,0x3F,0x3F,0x3F,
0x00,0x24,0x26,0x2C,0x1C,0x14,0x2A,0x18,0x0C,0x26,0x16,0x10,0x20,0x12,0x06,0x1B,
0x10,0x03,0x16,0x0C,0x01,0x12,0x08,0x00,0x04,0x00,0x00,0x3C,0x3C,0x3C,0x1E,0x22,
0x26,0x17,0x1C,0x20,0x11,0x16,0x1B,0x0C,0x10,0x15,0x08,0x0C,0x10,0x04,0x08,0x0C,
0x38,0x2E,0x3F,0x3A,0x3C,0x3E,0x35,0x38,0x3E,0x31,0x35,0x3D,0x2E,0x30,0x3F,0x28,
0x2E,0x3C,0x24,0x2B,0x3C,0x20,0x28,0x3B,0x1C,0x25,0x3B,0x17,0x22,0x3B,0x13,0x1F,
0x3A,0x10,0x1C,0x3A,0x0C,0x19,0x39,0x38,0x32,0x3F,0x32,0x2C,0x3F,0x32,0x2E,0x3F,
0x3F,0x38,0x34,0x3B,0x38,0x31,0x3B,0x37,0x30,0x3B,0x36,0x2F,0x3F,0x35,0x2E,0x3F,
0x33,0x2C,0x3E,0x31,0x2A,0x3D,0x2F,0x29,0x3D,0x2D,0x28,0x3C,0x2C,0x27,0x3C,0x2A,
0x25,0x3B,0x28,0x24,0x3B,0x27,0x23,0x3F,0x37,0x39,0x3F,0x33,0x2E,0x3F,0x35,0x2E,
0x00,0x34,0x38,0x20,0x28,0x10,0x1C,0x28,0x00,0x18,0x20,0x0C,0x10,0x14,0x04,0x08,
0x0C,0x04,0x14,0x18,0x10,0x14,0x14,0x08,0x00,0x08,0x00,0x04,0x0C,0x14,0x08,0x10,
0x18,0x0C,0x14,0x24,0x10,0x1C,0x28,0x14,0x2C,0x34,0x0C,0x20,0x00,0x10,0x24,0x00,
0x1C,0x0C,0x24,0x38,0x3C,0x28,0x1C,0x20,0x00,0x08,0x10,0x00,0x3C,0x3C,0x3C,0x0C,
0x04,0x0C,0x08,0x00,0x08,0x04,0x00,0x04,0x28,0x22,0x1E,0x1C,0x18,0x14,0x14,0x10,
0x0C,0x10,0x0C,0x08,0x0C,0x08,0x04,0x00,0x00,0x00,0x00,0x04,0x08,0x00,0x00,0x00,
0x1C,0x0C,0x24,0x3E,0x36,0x30,0x3E,0x20,0x00,0x32,0x00,0x00,0x3C,0x3C,0x3C,0x0C,
0x04,0x0C,0x08,0x04,0x00,0x00,0x00,0x00,0x28,0x22,0x1E,0x1C,0x18,0x14,0x14,0x10,
0x0C,0x10,0x0C,0x08,0x0C,0x08,0x04,0x00,0x00,0x00,0x00,0x04,0x08,0x00,0x00,0x00,
0x00,0x20,0x00,0x10,0x1C,0x20,0x0C,0x18,0x1C,0x08,0x14,0x18,0x04,0x10,0x14,0x04,
0x0C,0x10,0x00,0x08,0x0C,0x00,0x04,0x08,0x30,0x28,0x0C,0x28,0x1E,0x08,0x22,0x16,
0x04,0x1C,0x0E,0x02,0x14,0x08,0x00,0x0E,0x06,0x00,0x08,0x04,0x00,0x00,0x00,0x00,
0x24,0x34,0x38,0x24,0x10,0x04,0x1C,0x0C,0x04,0x18,0x08,0x04,0x14,0x04,0x00,0x0C,
0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x18,0x14,0x10,0x14,
0x10,0x0C,0x10,0x0C,0x08,0x0C,0x08,0x04,0x08,0x04,0x00,0x04,0x00,0x00,0x00,0x00,
0x00,0x24,0x26,0x14,0x10,0x0C,0x10,0x0C,0x08,0x0C,0x08,0x04,0x08,0x04,0x00,0x00,
0x00,0x00,0x22,0x06,0x00,0x2A,0x16,0x04,0x34,0x28,0x0A,0x3E,0x3E,0x12,0x00,0x00,
0x06,0x02,0x04,0x10,0x0A,0x0C,0x1C,0x18,0x18,0x28,0x28,0x28,0x32,0x3E,0x3E,0x3E,
0x00,0x24,0x26,0x30,0x28,0x0C,0x28,0x1E,0x08,0x22,0x16,0x04,0x1C,0x0E,0x02,0x14,
0x08,0x00,0x0E,0x06,0x00,0x08,0x04,0x00,0x0E,0x18,0x18,0x0C,0x14,0x14,0x0A,0x10,
0x10,0x08,0x0E,0x0C,0x06,0x0A,0x0A,0x04,0x06,0x06,0x02,0x02,0x02,0x00,0x00,0x00,
0x00,0x00,0x00,0x0A,0x07,0x0A,0x0D,0x0A,0x0E,0x10,0x0E,0x12,0x14,0x12,0x16,0x17,
0x1A,0x1D,0x1B,0x1C,0x1F,0x21,0x1B,0x16,0x1B,0x15,0x11,0x17,0x0F,0x0D,0x12,0x0A,
0x09,0x0D,0x08,0x08,0x3A,0x00,0x34,0x3A,0x00,0x34,0x3A,0x00,0x34,0x3A,0x00,0x34,
0x00,0x00,0x00,0x06,0x0C,0x10,0x09,0x10,0x17,0x0E,0x13,0x1D,0x10,0x14,0x1F,0x16,
0x19,0x25,0x12,0x15,0x21,0x24,0x18,0x20,0x1D,0x13,0x1A,0x16,0x0D,0x15,0x0C,0x0C,
0x11,0x0A,0x0A,0x0E,0x3A,0x00,0x34,0x3A,0x00,0x34,0x3A,0x00,0x34,0x3A,0x00,0x34,
0x00,0x24,0x26,0x14,0x10,0x0C,0x10,0x0C,0x08,0x0C,0x08,0x04,0x08,0x04,0x00,0x00,
0x00,0x00,0x22,0x07,0x00,0x2B,0x17,0x04,0x35,0x29,0x0A,0x3F,0x3F,0x12,0x00,0x00,
0x06,0x03,0x04,0x11,0x0B,0x0C,0x1D,0x18,0x18,0x28,0x29,0x29,0x33,0x3F,0x3F,0x3F,
0x1C,0x0C,0x24,0x38,0x3C,0x28,0x1C,0x20,0x00,0x08,0x10,0x00,0x3C,0x3C,0x3C,0x0C,
0x04,0x0C,0x08,0x00,0x08,0x04,0x00,0x04,0x28,0x22,0x1E,0x1C,0x18,0x14,0x14,0x10,
0x0C,0x10,0x0C,0x08,0x0C,0x08,0x04,0x00,0x00,0x00,0x00,0x04,0x08,0x00,0x00,0x00,
0x0C,0x2C,0x04,0x28,0x22,0x1E,0x20,0x28,0x1C,0x20,0x24,0x1C,0x18,0x20,0x14,0x14,
0x18,0x0C,0x00,0x18,0x10,0x00,0x00,0x00,0x20,0x1C,0x18,0x1C,0x18,0x14,0x18,0x14,
0x10,0x14,0x10,0x0C,0x10,0x0C,0x08,0x0C,0x08,0x04,0x00,0x00,0x00,0x38,0x38,0x3C,
0x00,0x1C,0x00,0x16,0x14,0x00,0x12,0x11,0x00,0x0F,0x0E,0x00,0x0B,0x0A,0x00,0x07,
0x07,0x00,0x04,0x03,0x00,0x00,0x00,0x00,0x0A,0x08,0x03,0x11,0x0E,0x06,0x19,0x13,
0x09,0x18,0x14,0x0A,0x1E,0x1A,0x10,0x1A,0x1E,0x08,0x24,0x20,0x12,0x2E,0x26,0x1E,
0x24,0x34,0x38,0x20,0x10,0x04,0x18,0x0C,0x04,0x14,0x08,0x04,0x10,0x04,0x00,0x08,
0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x1C,0x20,0x0C,0x18,
0x1C,0x08,0x14,0x18,0x04,0x10,0x14,0x04,0x0C,0x10,0x00,0x08,0x0C,0x00,0x04,0x08,
0x24,0x34,0x38,0x10,0x3C,0x3C,0x10,0x34,0x34,0x0C,0x30,0x30,0x0C,0x28,0x28,0x08,
0x24,0x24,0x08,0x1C,0x1C,0x08,0x18,0x18,0x04,0x10,0x10,0x04,0x0C,0x0C,0x00,0x04,
0x04,0x00,0x00,0x00,0x24,0x24,0x24,0x14,0x14,0x14,0x0C,0x0C,0x0C,0x30,0x34,0x34,
0x3F,0x3F,0x3F,0x3A,0x3D,0x3E,0x36,0x3C,0x3E,0x32,0x3A,0x3E,0x2E,0x39,0x3E,0x2A,
0x37,0x3E,0x26,0x36,0x3F,0x22,0x35,0x3F,0x1E,0x33,0x3F,0x1A,0x32,0x3F,0x16,0x31,
0x3F,0x12,0x2F,0x3F,0x0E,0x2E,0x3F,0x0A,0x2C,0x3F,0x06,0x2B,0x3F,0x02,0x2A,0x3F,
0x00,0x00,0x00,0x0A,0x03,0x03,0x0F,0x05,0x03,0x14,0x07,0x03,0x1A,0x0B,0x03,0x1F,
0x10,0x02,0x23,0x16,0x00,0x0F,0x0B,0x07,0x14,0x11,0x0B,0x1A,0x19,0x10,0x1E,0x1F,
0x15,0x22,0x25,0x1C,0x01,0x3D,0x00,0x01,0x3D,0x00,0x01,0x3D,0x00,0x01,0x3D,0x00,
0x00,0x00,0x00,0x03,0x03,0x05,0x07,0x08,0x0D,0x09,0x0A,0x10,0x0C,0x0D,0x14,0x0F,
0x0F,0x17,0x12,0x12,0x1A,0x0D,0x03,0x00,0x10,0x06,0x00,0x14,0x09,0x00,0x18,0x0D,
0x00,0x1C,0x12,0x00,0x01,0x3D,0x00,0x01,0x3D,0x00,0x01,0x3D,0x00,0x01,0x3D,0x00,
0x00,0x18,0x00,0x20,0x1C,0x18,0x1C,0x18,0x14,0x18,0x14,0x10,0x14,0x10,0x0C,0x10,
0x0C,0x08,0x0C,0x08,0x04,0x08,0x04,0x00,0x00,0x00,0x00,0x18,0x1C,0x18,0x14,0x18,
0x14,0x10,0x14,0x10,0x0C,0x10,0x0C,0x08,0x0C,0x08,0x04,0x08,0x04,0x00,0x04,0x00,
0x00,0x00,0x00,0x1C,0x14,0x14,0x18,0x10,0x10,0x14,0x0C,0x0C,0x10,0x08,0x08,0x0C,
0x04,0x04,0x08,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x1C,0x20,0x1C,0x18,0x1C,
0x18,0x14,0x18,0x14,0x10,0x14,0x10,0x0C,0x10,0x0C,0x08,0x0C,0x08,0x04,0x08,0x04,
0x00,0x00,0x00,0x20,0x1C,0x18,0x1C,0x18,0x14,0x18,0x14,0x10,0x14,0x10,0x0C,0x10,
0x0C,0x08,0x0C,0x08,0x04,0x08,0x04,0x00,0x00,0x00,0x00,0x08,0x08,0x18,0x18,0x18,
0x28,0x1C,0x20,0x30,0x24,0x28,0x3C,0x00,0x08,0x00,0x00,0x28,0x28,0x38,0x38,0x34,
0x00,0x00,0x00,0x3D,0x3F,0x2E,0x3A,0x3F,0x27,0x38,0x3F,0x1F,0x34,0x3F,0x17,0x31,
0x3F,0x10,0x2D,0x3F,0x08,0x28,0x3F,0x00,0x00,0x00,0x00,0x07,0x08,0x17,0x06,0x07,
0x13,0x04,0x05,0x0F,0x03,0x04,0x0B,0x02,0x02,0x08,0x01,0x01,0x04,0x00,0x00,0x00,
0x00,0x18,0x00,0x08,0x08,0x18,0x18,0x10,0x20,0x18,0x18,0x30,0x20,0x20,0x38,0x38,
0x38,0x38,0x28,0x28,0x28,0x23,0x1F,0x1F,0x1E,0x18,0x18,0x1A,0x11,0x11,0x15,0x0C,
0x0C,0x10,0x07,0x07,0x0C,0x04,0x04,0x20,0x2A,0x20,0x38,0x38,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x14,0x10,0x0C,0x10,0x0C,0x08,0x0C,0x08,0x04,0x08,0x04,0x00,0x00,
0x00,0x00,0x22,0x07,0x00,0x2B,0x17,0x04,0x35,0x29,0x0A,0x3F,0x3F,0x12,0x00,0x00,
0x06,0x03,0x04,0x11,0x0B,0x0C,0x1D,0x18,0x18,0x28,0x29,0x29,0x33,0x3F,0x3F,0x3F,
0x37,0x00,0x00,0x37,0x00,0x00,0x37,0x00,0x00,0x37,0x00,0x00,0x37,0x00,0x00,0x37,
0x00,0x00,0x37,0x00,0x00,0x37,0x00,0x00,0x37,0x00,0x00,0x37,0x00,0x00,0x37,0x00,
0x00,0x37,0x00,0x00,0x37,0x00,0x00,0x37,0x00,0x00,0x37,0x00,0x00,0x37,0x00,0x00,
0x00,0x00,0x00,0x31,0x24,0x10,0x0B,0x0A,0x12,0x2C,0x1D,0x12,0x25,0x12,0x0E,0x1F,
0x0B,0x0D,0x19,0x08,0x0E,0x12,0x05,0x0D,0x0C,0x03,0x0B,0x37,0x2D,0x1E,0x1A,0x1C,
0x18,0x07,0x14,0x1D,0x0F,0x12,0x12,0x0B,0x0D,0x11,0x0B,0x08,0x10,0x04,0x1F,0x23,
0x00,0x00,0x00,0x14,0x23,0x17,0x12,0x0E,0x0D,0x14,0x20,0x17,0x11,0x1C,0x18,0x0F,
0x19,0x18,0x0D,0x13,0x15,0x0A,0x0D,0x12,0x08,0x08,0x0B,0x1D,0x23,0x17,0x19,0x1E,
0x11,0x19,0x14,0x13,0x08,0x12,0x04,0x08,0x0D,0x0A,0x04,0x09,0x04,0x22,0x1B,0x1A
};
const uint8_t tile_lut_data0[] = {
0x01,0xFA,0x06,0x00
};
const uint8_t tile_lut_data1[] = {
0x05,0xFA,0x06,0x00,0x87,0x03,0x01,0x8A,0x03,0x02,0xD5,0x03,0x01,0xD8,0x03,0x02
};
const uint8_t tile_lut_data2[] = {
0x06,0xFA,0x06,0x00,0x80,0x03,0x01,0x83,0x03,0x02,0x87,0x03,0x02,0x8A,0x03,0x01,
0x8D,0x03,0x02
};
const uint8_t tile_lut_data3[] = {
0x01,0xFA,0x06,0x00
};
const uint16_t tile_funcs0[] = {
0x5DAA,0x5E83,0x5E83,0x5DAA,0x5F73,0x5DAA,0x5DAA,0x5F78,0x5DAA,0x5E83,0x5E83,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,
0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,
0x5F7B,0x5F0E,0x5F0E,0x5E83,0x5DAA,0x5DAA,0x5DAA,0x5DAA,0x5DAA,0x5DAA,0x5F0E
};
const uint16_t tile_funcs1[] = {
0x5DAA,0x5E83,0x5E83,0x5DAA,0x5F73,0x5DAA,0x5EEC,0x5F78,0x5D3E,0x5E83,0x5E83,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,
0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,
0x5F7B,0x5F16,0x5F16,0x5FA7,0x5F94,0x5F94,0x5F94,0x5F94,0x5F94,0x5F94,0x5F0E
};
const uint16_t tile_funcs2[] = {
0x5DC8,0x5DC8,0x5DC9,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC9,0x5DC9,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,
0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,
0x5DC8,0x5DC8,0x5DC8,0x5F9E,0x5F94,0x5F94,0x5F94,0x5F94,0x5F94,0x5F94,0x5DC8
};
const uint16_t tile_funcs3[] = {
0x5DC8,0x5DC8,0x5E58,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5DC8,0x5E58,0x5E58,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,
0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,0x5F7B,
0x5F7B,0x5DC8,0x5DC8,0x5F9E,0x5F94,0x5F94,0x5F94,0x5F94,0x5F94,0x5F94,0x5DC8
};
const uint8_t level_data_tiles_lut[] = {
0x00,0x00,0x00,0x00,0x00,0x1D,0x1E,0x00,0x04,0x01,0x01,0x01,0x00,0x00,0x00,0x0B,
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x1B,0x05,0x00,0x05,0x00,0x01,0x01,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x00,0x07,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x05,0x1C,0x1A,0x05,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x0B,0x0C,0x0D,0x0E,0x0F,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x00,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x22,0x21,0x22,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x2A,0x2A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x00,0x1F,0x20,0x00,0x00,0x1D,0x1E,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1A,
0x19,0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x06,0x06,0x06,0x06,0x06,0x06,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,
0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x00,
0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,
0x00,0x02,0x02,0x00,0x02,0x02,0x02,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,
0x00,0x02,0x02,0x00,0x00,0x02,0x02,0x00,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x02,0x02,0x02,0x02,0x00,0x00,0x24,0x24,0x24,0x25,0x25,0x25,0x02,0x00,0x00,
0x00,0x00,0x00,0x00,0x0A,0x0A,0x0A,0x02,0x02,0x00,0x00,0x21,0x22,0x21,0x22,0x0A,
0x0A,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x02,0x02,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,
0x01,0x01,0x08,0x01,0x01,0x26,0x26,0x26,0x27,0x27,0x27,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x06,0x06,0x06,0x06,0x06,0x06,
0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x08,0x01,0x02,0x02,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x23,0x23,0x00,0x08,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,
0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x23,0x23,0x02,0x08,0x02,0x02,0x00,
0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x23,0x08,
0x08,0x02,0x02,0x00,0x00,0x02,0x00,0x00,0x23,0x23,0x23,0x23,0x00,0x00,0x00,0x00,
0x24,0x24,0x24,0x25,0x25,0x25,0x02,0x26,0x26,0x26,0x27,0x27,0x27,0x28,0x28,0x28,
0x00,0x00,0x08,0x00,0x02,0x02,0x00,0x23,0x00,0x00,0x00,0x21,0x22,0x21,0x22,0x08,
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,
0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,
0x22,0x21,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x02,0x02,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02,0x02,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x02,0x23,0x23,0x23,0x23,0x23,0x23,
0x23,0x23,0x23,0x23,0x02,0x02,0x02,0x02,0x23,0x00,0x00,0x00,0x00,0x02,0x02,0x02,
0x02,0x02,0x02,0x02,0x23,0x02,0x02,0x02,0x02,0x02,0x23,0x02,0x23,0x00,0x00,0x00,
0x02,0x02,0x23,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06
};
const uint8_t player_anim_dy[] = {
0xFF,0xFE,0xFC,0xF9,0xF2,0xEA,0xDA,0x00
};
const uint8_t player_anim_lut[] = {
0x00,0x02,0x04,0x03,0x02,0x00,0x03,0x00,0x05,0x05,0x00,0x00,0x05,0x00,0x00,0x00,
0x06,0x06,0x07,0x07,0x06,0x06,0x07,0x00,0x06,0x06,0x00,0x00,0x06,0x00,0x00,0x00,
0x0D,0x0F,0x11,0x11,0x0F,0x0D,0x11,0x0D,0x12,0x12,0x0D,0x0D,0x12,0x0D,0x0D,0x0D,
0x13,0x13,0x14,0x14,0x13,0x13,0x14,0x0D,0x13,0x13,0x0D,0x0D,0x13,0x0D,0x0D,0x0D,
0x15,0x17,0x19,0x19,0x17,0x15,0x19,0x15,0x1A,0x1A,0x15,0x15,0x1A,0x15,0x15,0x15,
0x1B,0x1B,0x1C,0x1C,0x1B,0x1B,0x1C,0x15,0x1B,0x1B,0x15,0x15,0x1B,0x15,0x15,0x15,
0x15,0x17,0x19,0x19,0x17,0x15,0x19,0x15,0x1A,0x1A,0x15,0x15,0x1A,0x15,0x15,0x15,
0x1B,0x1B,0x1C,0x1C,0x1B,0x1B,0x1C,0x15,0x1B,0x1B,0x15,0x15,0x1B,0x15,0x15,0x15,
0x09,0x0B,0x0A,0x0A,0x0C,0x09,0x0A,0x0A,0x08,0x05,0x09,0x09,0x05,0x08,0x09,0x09,
0x06,0x06,0x06,0x06,0x06,0x09,0x06,0x09,0x06,0x06,0x09,0x09,0x06,0x09,0x09,0x09,
0x1E,0x20,0x1F,0x1F,0x21,0x1E,0x1F,0x1F,0x1D,0x12,0x1E,0x1E,0x12,0x1D,0x1E,0x1E,
0x13,0x13,0x13,0x13,0x13,0x1E,0x13,0x1E,0x13,0x13,0x1E,0x1E,0x13,0x1E,0x1E,0x1E
};
static const uint8_t tab6278[] = {
0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,
0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,
0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x00,
0x14,0x00,0x15,0x00,0x15,0x00,0x15,0x00,0x15,0x00,0x15,0x00,0x16,0x00,0x16,0x00,
0x16,0x00,0x16,0x00,0x16,0x00,0xF1,0xFF
};
static const uint8_t tab62c0[] = {
0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x12,0x00,0x12,0x00,
0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,
0x11,0x00,0x11,0x00,0x11,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x11,0x00,0x11,0x00,
0x11,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x40,0x12,0x40,0x12,0x40,0x12,0x40,
0x12,0x40,0x12,0x40,0x11,0x40,0x11,0x40,0x11,0x40,0x11,0x40,0x11,0x40,0x11,0x40,
0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,
0x12,0x00,0x12,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x12,0x00,0x12,0x00,0x12,0x00,
0x11,0x00,0x11,0x00,0x11,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x11,0x40,0x11,0x40,
0x11,0x40,0x11,0x40,0x11,0x40,0x11,0x40,0x12,0x40,0x12,0x40,0x12,0x40,0x12,0x40,
0x12,0x40,0x12,0x40,0x11,0x40,0x11,0x40,0x11,0x40,0x11,0x40,0x11,0x40,0x11,0x40,
0x12,0x40,0x12,0x40,0x12,0x40,0x12,0x40,0x12,0x40,0x12,0x40,0x11,0x40,0x11,0x40,
0x11,0x40,0x11,0x40,0x11,0x40,0x11,0x40,0x12,0x40,0x12,0x40,0x12,0x40,0x11,0x40,
0x11,0x40,0x11,0x40,0x12,0x40,0x12,0x40,0x12,0x40,0x11,0x00,0x11,0x00,0x11,0x00,
0x11,0x00,0x11,0x00,0x11,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,
0x12,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x12,0x00,
0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x11,0x00,0x11,0x00,0x11,0x00,
0x11,0x00,0x11,0x00,0x11,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,
0x12,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x11,0x00,0x12,0x00,
0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x14,0x20,0xFF,0xFF
};
static const uint8_t tab63ee[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,
0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,
0xE8,0xFF
};
static const uint8_t tab6420[] = {
0x06,0x00,0x06,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
0x09,0x00,0x09,0x00,0x09,0x00,0xF7,0xFF
};
static const uint8_t tab6438[] = {
0x06,0x00,0xFF,0xFF
};
static const uint8_t tab643c[] = {
0x0A,0x00,0xFF,0xFF
};
static const uint8_t tab6440[] = {
0x10,0x00,0x10,0x20,0x10,0x00,0xFD,0xFF
};
static const uint8_t tab6448[] = {
0x17,0x00,0x17,0x20,0x17,0x00,0xFD,0xFF
};
static const uint8_t tab6266[] = {
0x0D,0x00,0x0D,0x00,0x0E,0x00,0x0E,0x00,0x0D,0x40,0x0D,0x40,0x0E,0x40,0x0E,0x40,
0xF8,0xFF
};
static const uint8_t tab6262[] = {
0x0D,0x00,0xFF,0xFF
};
static const uint8_t tab6450[] = {
0x26,0x00,0x26,0x00,0x26,0x00,0x26,0x00,0x26,0x00,0x26,0x00,0x26,0x00,0x27,0x00,
0x27,0x00,0x27,0x00,0x27,0x00,0x27,0x00,0x27,0x00,0x27,0x00,0x28,0x00,0x28,0x00,
0x28,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0x27,0x00,0x27,0x00,0x27,0x00,
0x27,0x00,0x27,0x00,0x27,0x00,0x27,0x00,0xE4,0xFF
};
static const uint8_t tab648a[] = {
0x19,0x00,0x19,0x00,0x19,0x00,0x19,0x00,0x1A,0x00,0x1A,0x00,0x1A,0x00,0x1A,0x00,
0x1B,0x00,0x1B,0x00,0x1B,0x00,0x1B,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,
0x1D,0x00,0x1D,0x00,0x1D,0x00,0x1D,0x00,0x1E,0x00,0x1E,0x00,0x1E,0x00,0x1E,0x00,
0xE8,0xFF
};
static const uint8_t tab64bc[] = {
0x21,0x00,0xFF,0xFF
};
static const uint8_t tab64c0[] = {
0x23,0x00,0xFF,0xFF
};
static const uint8_t tab64c4[] = {
0x29,0x00,0x29,0x20,0xFF,0xFF
};
static const uint8_t tab64ca[] = {
0x22,0x00,0x22,0x20,0xFF,0xFF
};
static const uint8_t tab64e6[] = {
0x96,0x00,0x96,0x00,0x96,0x00,0x96,0x00,0x96,0x00,0x96,0x00,0x96,0x00,0x97,0x00,
0x97,0x00,0x97,0x00,0x97,0x00,0x97,0x00,0x97,0x00,0x97,0x00,0x98,0x00,0x98,0x00,
0x98,0x00,0x98,0x00,0x98,0x00,0x98,0x00,0x98,0x00,0x97,0x00,0x97,0x00,0x97,0x00,
0x97,0x00,0x97,0x00,0x97,0x00,0x97,0x00,0xE4,0xFF
};
static const uint8_t tab6520[] = {
0x8C,0x00,0x8C,0x00,0x8C,0x00,0x8C,0x00,0x8D,0x00,0x8D,0x00,0x8D,0x00,0x8D,0x00,
0x8E,0x00,0x8E,0x00,0x8E,0x00,0x8E,0x00,0x8F,0x00,0x8F,0x00,0x8F,0x00,0x8F,0x00,
0x90,0x00,0x90,0x00,0x90,0x00,0x90,0x00,0x91,0x00,0x91,0x00,0x91,0x00,0x91,0x00,
0xE8,0xFF
};
static const uint8_t tab6552[] = {
0x95,0x00,0xFF,0xFF
};
static const uint8_t tab6556[] = {
0x92,0x00,0xFF,0xFF
};
static const uint8_t tab655a[] = {
0x18,0x20,0xFF,0xFF
};
static const uint8_t tab655e[] = {
0x17,0x20,0xFF,0xFF
};
static const uint8_t tab64d4[] = {
0x1F,0x00,0x1F,0x00,0x20,0x00,0x20,0x00,0x1F,0x40,0x1F,0x40,0x20,0x40,0x20,0x40,
0xF8,0xFF
};
static const uint8_t tab64d0[] = {
0x1F,0x00,0xFF,0xFF
};
static const uint8_t tab625e[] = {
0x8A,0x00,0xFF,0xFF
};
static const uint8_t tab6562[] = {
0x25,0x00,0xFF,0xFF
};
const uint8_t *player_anim_table[] = {
tab6278,tab62c0,tab63ee,tab6420,
tab6438,tab643c,tab6440,tab6448,
tab6266,tab6262,tab6266,tab6266,
tab6266,tab6450, 0,tab648a,
0,tab64bc,tab64c0,tab64c4,
tab64ca,tab64e6, 0,tab6520,
0,tab6552,tab6556,tab655a,
tab655e,tab64d4,tab64d0,tab64d4,
tab64d4,tab64d4,tab625e,tab6562,
};

129
ja/unpack.c Normal file
View File

@ -0,0 +1,129 @@
/* uncompress data packed with DIET by T.Matsumoto */
#include "unpack.h"
#include "util.h"
struct unpack_eat_t {
FILE *fp;
uint8_t len;
uint16_t bits;
uint8_t *dst;
};
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) {
const int bit = (u->bits & (1 << (16 - u->len))) != 0;
--u->len;
if (u->len == 0) {
u->bits = fread_le16(u->fp);
u->len = 16;
}
return bit;
}
static int zero_bits(struct unpack_eat_t *u, int count) {
int i = 0;
for (; i < count; ++i) {
if (next_bit(u)) {
break;
}
}
return i;
}
static uint8_t get_bits(struct unpack_eat_t *u, int count) {
assert(count < 8);
uint8_t val = 0;
for (int i = 0; i < count; ++i) {
val = (val << 1) | next_bit(u);
}
return val;
}
static void copy_reference(struct unpack_eat_t *u, int count, int offset_hi, int offset_lo) {
const int16_t offset = offset_hi * 256 + offset_lo;
for (int i = 0; i < count; ++i) {
const uint8_t value = u->dst[offset];
*u->dst++ = value;
}
}
static int unpack_eat(struct unpack_eat_t *u, uint8_t *output_buffer, int output_buffer_size) {
uint8_t buffer[17];
const int header_size = fread(buffer, 1, sizeof(buffer), u->fp);
if (header_size != 17 || READ_LE_UINT16(buffer + 4) != 0x899D || READ_LE_UINT16(buffer + 6) != 0x6C64) {
print_error("Unexpected signature for .eat file");
return 0;
}
const uint16_t crc = READ_LE_UINT16(buffer + 12);
const int output_size = (buffer[14] << 14) + READ_LE_UINT16(buffer + 15);
print_debug(DBG_UNPACK, "uncompressed size %d crc 0x%04x", output_size, crc);
if (output_size > output_buffer_size) {
print_error("Invalid output buffer size %d, need %d", output_buffer_size, output_size);
return 0;
}
u->dst = output_buffer;
u->len = 16;
u->bits = fread_le16(u->fp);
while (1) {
while (next_bit(u)) {
*u->dst++ = fgetc(u->fp);
}
const int b = next_bit(u);
const int offset_lo = fgetc(u->fp);
if (b) {
int offset_hi = 0xFE | next_bit(u);
if (!next_bit(u)) {
int i = 1;
for (; i < 4 && !next_bit(u); ++i) {
offset_hi = (offset_hi << 1) | next_bit(u);
}
offset_hi -= (1 << i);
}
const int n = zero_bits(u, 4);
if (n != 4) {
copy_reference(u, n + 3, offset_hi, offset_lo);
} else if (next_bit(u)) {
copy_reference(u, next_bit(u) + 7, offset_hi, offset_lo);
} else if (!next_bit(u)) {
copy_reference(u, get_bits(u, 3) + 9, offset_hi, offset_lo);
} else {
copy_reference(u, fgetc(u->fp) + 17, offset_hi, offset_lo);
}
} else {
if (next_bit(u)) {
const int offset_hi = (0xF8 | get_bits(u, 3)) - 1;
copy_reference(u, 2, offset_hi, offset_lo);
} else if (offset_lo == 0xFF) {
break;
} else {
copy_reference(u, 2, 0xFF, offset_lo);
}
}
}
assert((u->dst - output_buffer) == output_size);
return output_size;
}
int unpack(const char *filename, uint8_t *dst, int size) {
int uncompressed_size = 0;
FILE *fp = fopen(filename, "rb");
if (fp) {
memset(&g_unpack, 0, sizeof(struct unpack_eat_t));
g_unpack.fp = fp;
uncompressed_size = unpack_eat(&g_unpack, dst, size);
fclose(fp);
} else {
print_error("Unable to open '%s'", filename);
}
return uncompressed_size;
}

9
ja/unpack.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef UNPACK_H__
#define UNPACK_H__
#include "intern.h"
extern int unpack(const char *filename, uint8_t *dst, int size);
#endif /* UNPACK_H__ */

46
main.c
View File

@ -1,10 +1,6 @@
#include <getopt.h> #include <getopt.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "fileio.h"
#include "game.h"
#include "resource.h"
#include "sys.h" #include "sys.h"
#include "util.h" #include "util.h"
@ -23,12 +19,33 @@ static const char *USAGE =
" --cheats=MASK Cheats mask\n" " --cheats=MASK Cheats mask\n"
" --startpos=XxY Start at position (X,Y)\n" " --startpos=XxY Start at position (X,Y)\n"
" --fullscreen Enable fullscreen\n" " --fullscreen Enable fullscreen\n"
" --scale Graphics scaling factor (default 2)\n" " --scale=N Graphics scaling factor (default 2)\n"
" --filter Graphics scaling filter\n" " --filter=NAME Graphics scaling filter (default 'nearest')\n"
" --screensize=WxH Graphics screen size (default 320x200)\n" " --screensize=WxH Graphics screen size (default 320x200)\n"
" --cga Enable CGA colors\n" " --cga Enable CGA colors\n"
; ;
static struct game_t *detect_game(const char *data_path) {
#if 0
extern struct game_t bb_game;
extern struct game_t ja_game;
static struct game_t *games[] = {
&bb_game,
&ja_game,
0
};
for (int i = 0; games[i]; ++i) {
if (games[i]->detect(data_path)) {
return games[i];
}
}
return 0;
#else
extern struct game_t game;
return &game;
#endif
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
g_options.start_xpos16 = -1; g_options.start_xpos16 = -1;
g_options.start_ypos16 = -1; g_options.start_ypos16 = -1;
@ -97,7 +114,7 @@ int main(int argc, char *argv[]) {
if (sscanf(optarg, "%dx%d", &g_options.screen_w, &g_options.screen_h) == 2) { if (sscanf(optarg, "%dx%d", &g_options.screen_w, &g_options.screen_h) == 2) {
// align to tile 16x16 // align to tile 16x16
g_options.screen_w = (g_options.screen_w + 15) & ~15; g_options.screen_w = (g_options.screen_w + 15) & ~15;
g_options.screen_h = ((g_options.screen_h + 15) & ~15) + 40; g_options.screen_h = ((g_options.screen_h + 15) & ~15) + 40; // PANEL_H
} }
break; break;
case 10: case 10:
@ -108,16 +125,15 @@ int main(int argc, char *argv[]) {
return -1; return -1;
} }
} }
fio_init(data_path); struct game_t *game = detect_game(data_path);
res_init(GAME_SCREEN_W * GAME_SCREEN_H); if (!game) {
fprintf(stdout, "No data files found\n");
} else {
g_sys.init(); g_sys.init();
g_sys.set_screen_size(GAME_SCREEN_W, GAME_SCREEN_H, "Blues Brothers", scale_factor, scale_filter, fullscreen); g_sys.set_screen_size(GAME_SCREEN_W, GAME_SCREEN_H, game->name, scale_factor, scale_filter, fullscreen);
sound_init(); game->run(data_path);
game_main();
sound_fini();
g_sys.fini(); g_sys.fini();
res_fini(); }
fio_fini();
if (data_path != DEFAULT_DATA_PATH) { if (data_path != DEFAULT_DATA_PATH) {
free((char *)data_path); free((char *)data_path);
} }

4
sys.h
View File

@ -16,6 +16,7 @@ struct input_t {
bool quit; bool quit;
bool escape; bool escape;
bool space; bool space;
bool digit1, digit2, digit3;
}; };
typedef void (*sys_audio_cb)(void *, uint8_t *data, int len); typedef void (*sys_audio_cb)(void *, uint8_t *data, int len);
@ -35,9 +36,10 @@ struct sys_t {
int (*init)(); int (*init)();
void (*fini)(); void (*fini)();
void (*set_screen_size)(int w, int h, const char *caption, int scale, const char *filter, bool fullscreen); void (*set_screen_size)(int w, int h, const char *caption, int scale, const char *filter, bool fullscreen);
void (*set_screen_palette)(const uint8_t *colors, int); void (*set_screen_palette)(const uint8_t *colors, int offset, int count, int depth);
void (*set_palette_amiga)(const uint16_t *colors, int offset); void (*set_palette_amiga)(const uint16_t *colors, int offset);
void (*set_copper_bars)(const uint16_t *data); void (*set_copper_bars)(const uint16_t *data);
void (*set_palette_color)(int i, const uint8_t *colors);
void (*fade_in_palette)(); void (*fade_in_palette)();
void (*fade_out_palette)(); void (*fade_out_palette)();
void (*update_screen)(const uint8_t *p, int present); void (*update_screen)(const uint8_t *p, int present);

View File

@ -33,7 +33,7 @@ static SDL_Window *_window;
static SDL_Renderer *_renderer; static SDL_Renderer *_renderer;
static SDL_Texture *_texture; static SDL_Texture *_texture;
static SDL_PixelFormat *_fmt; static SDL_PixelFormat *_fmt;
static uint32_t _screen_palette[48]; static uint32_t _screen_palette[256];
static uint32_t *_screen_buffer; static uint32_t *_screen_buffer;
static struct input_t *_input = &g_sys.input; static struct input_t *_input = &g_sys.input;
static int _copper_color; static int _copper_color;
@ -158,22 +158,41 @@ static void sdl2_set_copper_bars(const uint16_t *data) {
} }
} }
static void sdl2_set_screen_palette(const uint8_t *colors, int count) { static void sdl2_set_screen_palette(const uint8_t *colors, int offset, int count, int depth) {
const int shift = 8 - depth;
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
_screen_palette[i] = SDL_MapRGB(_fmt, colors[0], colors[1], colors[2]); int r = colors[0];
int g = colors[1];
int b = colors[2];
if (depth != 8) {
r = (r << shift) | (r >> (depth - shift));
g = (g << shift) | (g >> (depth - shift));
b = (b << shift) | (b >> (depth - shift));
}
_screen_palette[offset + i] = SDL_MapRGB(_fmt, r, g, b);
colors += 3; colors += 3;
} }
} }
static void sdl2_set_palette_color(int i, const uint8_t *colors) {
int r = colors[0];
r = (r << 2) | (r >> 4);
int g = colors[1];
g = (g << 2) | (g >> 4);
int b = colors[2];
b = (b << 2) | (b >> 4);
_screen_palette[i] = SDL_MapRGB(_fmt, r, g, b);
}
static void fade_palette_helper(int in) { static void fade_palette_helper(int in) {
SDL_SetRenderDrawBlendMode(_renderer, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawBlendMode(_renderer, SDL_BLENDMODE_BLEND);
SDL_Rect r; SDL_Rect r;
r.x = r.y = 0; r.x = r.y = 0;
SDL_GetRendererOutputSize(_renderer, &r.w, &r.h); SDL_GetRendererOutputSize(_renderer, &r.w, &r.h);
for (int i = 1; i <= FADE_STEPS; ++i) { for (int i = 0; i <= FADE_STEPS; ++i) {
int alpha = 256 * i / FADE_STEPS; int alpha = 255 * i / FADE_STEPS;
if (in) { if (in) {
alpha = 256 - alpha; alpha = 255 - alpha;
} }
SDL_SetRenderDrawColor(_renderer, 0, 0, 0, alpha); SDL_SetRenderDrawColor(_renderer, 0, 0, 0, alpha);
SDL_RenderClear(_renderer); SDL_RenderClear(_renderer);
@ -313,6 +332,15 @@ static void handle_keyevent(int keysym, bool keydown) {
case SDLK_ESCAPE: case SDLK_ESCAPE:
_input->escape = keydown; _input->escape = keydown;
break; break;
case SDLK_1:
_input->digit1 = keydown;
break;
case SDLK_2:
_input->digit2 = keydown;
break;
case SDLK_3:
_input->digit3 = keydown;
break;
} }
} }
@ -490,6 +518,7 @@ struct sys_t g_sys = {
.set_screen_palette = sdl2_set_screen_palette, .set_screen_palette = sdl2_set_screen_palette,
.set_palette_amiga = sdl2_set_palette_amiga, .set_palette_amiga = sdl2_set_palette_amiga,
.set_copper_bars = sdl2_set_copper_bars, .set_copper_bars = sdl2_set_copper_bars,
.set_palette_color = sdl2_set_palette_color,
.fade_in_palette = sdl2_fade_in_palette, .fade_in_palette = sdl2_fade_in_palette,
.fade_out_palette = sdl2_fade_out_palette, .fade_out_palette = sdl2_fade_out_palette,
.update_screen = sdl2_update_screen, .update_screen = sdl2_update_screen,