Import blues from 8bc7cf4e

This commit is contained in:
Gregory Montoir 2018-07-12 21:17:33 +08:00
parent ec71a464eb
commit 627fa13e25
9 changed files with 113 additions and 31 deletions

View File

@ -28,3 +28,24 @@ void decode_ega_spr(const uint8_t *src, int src_pitch, int w, int h, uint8_t *ds
src += src_pitch - w; src += src_pitch - w;
} }
} }
void decode_amiga_planar8(const uint8_t *src, int w, int h, int depth, uint8_t *dst, int dst_pitch, int dst_x, int dst_y) {
dst += dst_y * dst_pitch + dst_x;
const int plane_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 < depth; ++bit) {
if (src[bit * plane_size] & mask) {
color |= 1 << bit;
}
}
dst[x * 8 + i] = color;
}
++src;
}
dst += dst_pitch;
}
}

View File

@ -5,5 +5,6 @@
#include "intern.h" #include "intern.h"
extern void decode_ega_spr(const uint8_t *src, int src_pitch, int w, int h, uint8_t *dst, int dst_pitch, int dst_x, int dst_y); extern void decode_ega_spr(const uint8_t *src, int src_pitch, int w, int h, uint8_t *dst, int dst_pitch, int dst_x, int dst_y);
extern void decode_amiga_planar8(const uint8_t *src, int w, int h, int depth, uint8_t *dst, int dst_pitch, int dst_x, int dst_y);
#endif /* DECODE_H__ */ #endif /* DECODE_H__ */

7
game.c
View File

@ -17,7 +17,7 @@ void update_input() {
void do_title_screen() { 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("pres.sqz"); load_img(g_options.amiga_lbms ? "blues.lbm" : "pres.sqz");
fade_in_palette(); fade_in_palette();
do { do {
update_input(); update_input();
@ -28,7 +28,6 @@ void do_title_screen() {
play_sound(SOUND_0); play_sound(SOUND_0);
fade_out_palette(); fade_out_palette();
g_sys.input.space = 0; g_sys.input.space = 0;
read_file("avtmag.sqv", g_res.avt_sqv);
} }
static void check_cheat_code() { static void check_cheat_code() {
@ -53,7 +52,7 @@ void do_select_player() {
int frame2 = 1; int frame2 = 1;
const int color_rgb = 2; const int color_rgb = 2;
const int colors_count = 25; const int colors_count = 25;
load_img("choix.sqz"); load_img(g_options.amiga_lbms ? "choix.lbm" : "choix.sqz");
screen_load_graphics(); screen_load_graphics();
screen_clear_sprites(); screen_clear_sprites();
do { do {
@ -239,7 +238,7 @@ static void do_inter_screen_helper(int xpos, int ypos, int c) {
static void do_inter_screen() { static void do_inter_screen() {
static const uint8_t xpos[] = { 0xFA, 0x50, 0xF0, 0xC8, 0x50, 0x50 }; static const uint8_t xpos[] = { 0xFA, 0x50, 0xF0, 0xC8, 0x50, 0x50 };
static const uint8_t ypos[] = { 0xAA, 0x37, 0x28, 0x5F, 0xA5, 0xAA }; static const uint8_t ypos[] = { 0xAA, 0x37, 0x28, 0x5F, 0xA5, 0xAA };
load_img("inter.sqz"); load_img(g_options.amiga_lbms ? "inter.lbm" : "inter.sqz");
g_vars.screen_h = 199; g_vars.screen_h = 199;
screen_clear_sprites(); screen_clear_sprites();
if (g_vars.level > 1) { if (g_vars.level > 1) {

3
game.h
View File

@ -42,6 +42,9 @@ struct options_t {
int start_ypos16; int start_ypos16;
bool amiga_copper_bars; bool amiga_copper_bars;
bool amiga_colors; bool amiga_colors;
bool amiga_sprites;
bool amiga_lbms;
bool amiga_data;
}; };
extern struct options_t g_options; extern struct options_t g_options;

24
level.c
View File

@ -29,7 +29,7 @@ static const uint16_t _colors_data[16 * MAX_LEVELS] = {
0x000,0x30b,0x747,0x446,0x006,0xfda,0x400,0xf87,0x37a,0x600,0xd63,0x000,0x000,0x800,0xdd0,0x98d 0x000,0x30b,0x747,0x446,0x006,0xfda,0x400,0xf87,0x37a,0x600,0xd63,0x000,0x000,0x800,0xdd0,0x98d
}; };
static const struct level_data_t { static const struct {
const char *ck1; const char *ck1;
const char *ck2; const char *ck2;
const char *sql; const char *sql;
@ -48,6 +48,18 @@ static const struct level_data_t {
{ "concert.ck1", "concert.ck2", "concert.sql", "concert.bin", "", "enemi6.sqv", level_xpos_concert, level_ypos_concert, 3 }, { "concert.ck1", "concert.ck2", "concert.sql", "concert.bin", "", "enemi6.sqv", level_xpos_concert, level_ypos_concert, 3 },
}; };
static const struct {
const char *m;
const char *bin;
} _levels_amiga[MAX_LEVELS] = {
{ "mag.m", "magasin.bin" },
{ "ent.m", "entrepo.bin" },
{ "pris.m", "prison.bin" },
{ "egou.m", "egout.bin" },
{ "ville.m", "ville.bin" },
{ 0, "concert.bin" },
};
static const char *_demo_filenames[] = { static const char *_demo_filenames[] = {
"demomag.ck1", "demomag.ck2", "demomag.sql" "demomag.ck1", "demomag.ck2", "demomag.sql"
}; };
@ -63,9 +75,19 @@ void load_level_data(int num) {
load_ck(_levels[num].ck2, 0x8000); load_ck(_levels[num].ck2, 0x8000);
load_sql(_levels[num].sql); load_sql(_levels[num].sql);
} }
if (g_options.amiga_data) {
load_bin(_levels_amiga[num].bin);
} else {
load_bin(_levels[num].bin); load_bin(_levels[num].bin);
}
load_avt(_levels[num].avt, g_res.avt_sqv, 0); load_avt(_levels[num].avt, g_res.avt_sqv, 0);
if (g_options.amiga_sprites) {
char name[16];
snprintf(name, sizeof(name), "ennemi%d", 1 + num);
load_spr(name, g_res.tmp, SPRITES_COUNT);
} else {
load_sqv(_levels[num].sqv, g_res.tmp, SPRITES_COUNT); load_sqv(_levels[num].sqv, g_res.tmp, SPRITES_COUNT);
}
memcpy(g_vars.level_xpos, _levels[num].xpos, MAX_OBJECTS * sizeof(int16_t)); memcpy(g_vars.level_xpos, _levels[num].xpos, MAX_OBJECTS * sizeof(int16_t));
memcpy(g_vars.level_ypos, _levels[num].ypos, MAX_OBJECTS * sizeof(int16_t)); memcpy(g_vars.level_ypos, _levels[num].ypos, MAX_OBJECTS * sizeof(int16_t));
if (g_vars.music_num != _levels[num].music) { if (g_vars.music_num != _levels[num].music) {

3
main.c
View File

@ -23,6 +23,9 @@ int main(int argc, char *argv[]) {
g_options.start_ypos16 = -1; g_options.start_ypos16 = -1;
g_options.amiga_copper_bars = true; g_options.amiga_copper_bars = true;
g_options.amiga_colors = true; g_options.amiga_colors = true;
// g_options.amiga_sprites = true;
// g_options.amiga_lbms = true;
// g_options.amiga_data = true;
const char *data_path = DEFAULT_DATA_PATH; const char *data_path = DEFAULT_DATA_PATH;
if (argc == 2) { if (argc == 2) {
struct stat st; struct stat st;

View File

@ -44,14 +44,7 @@ void res_init() {
if (!g_res.snd) { if (!g_res.snd) {
print_warning("Failed to allocate sound buffer, %d bytes", SOUND_SIZE); print_warning("Failed to allocate sound buffer, %d bytes", SOUND_SIZE);
} else { } else {
int f = fio_open(filename, 1); read_file(filename, g_res.snd, SOUND_SIZE);
const int filesize = fio_size(f);
if (filesize != SOUND_SIZE) {
print_warning("Unexpected '%s' file size %d", filename, filesize);
} else if (fio_read(f, g_res.snd, SOUND_SIZE) != SOUND_SIZE) {
print_error("Failed to read %d bytes from file '%s'", filesize, filename);
}
fio_close(f);
} }
} }
if (fio_exists("demomag.sql")) { if (fio_exists("demomag.sql")) {
@ -69,10 +62,12 @@ void res_fini() {
free(g_res.snd); free(g_res.snd);
} }
int read_file(const char *filename, uint8_t *dst) { int read_file(const char *filename, uint8_t *dst, int size) {
const int f = fio_open(filename, 1); const int f = fio_open(filename, 1);
const int filesize = fio_size(f); const int filesize = fio_size(f);
if (fio_read(f, dst, filesize) != filesize) { if (size > 0 && size != filesize) {
print_error("Unexpected '%s' file size %d (%d)", filename, filesize, size);
} else if (fio_read(f, dst, filesize) != filesize) {
print_error("Failed to read %d bytes from file '%s'", filesize, filename); print_error("Failed to read %d bytes from file '%s'", filesize, filename);
} }
fio_close(f); fio_close(f);
@ -210,8 +205,7 @@ static const uint8_t *trigger_lookup_table3(uint8_t num) {
void load_bin(const char *filename) { void load_bin(const char *filename) {
uint8_t bin[MAX_TRIGGERS * 10]; uint8_t bin[MAX_TRIGGERS * 10];
const int size = read_file(filename, bin); read_file(filename, bin, MAX_TRIGGERS * 10);
assert(size == MAX_TRIGGERS * 10);
const uint8_t *p = bin; const uint8_t *p = bin;
for (int i = 0; i < MAX_TRIGGERS; ++i) { for (int i = 0; i < MAX_TRIGGERS; ++i) {
struct trigger_t *t = &g_res.triggers[i]; struct trigger_t *t = &g_res.triggers[i];
@ -247,7 +241,13 @@ void load_ck(const char *filename, uint16_t offset) {
} }
void load_img(const char *filename) { void load_img(const char *filename) {
const int size = read_compressed_file(filename, g_res.tmp); int size;
const char *ext = strrchr(filename, '.');
if (ext && strcmp(ext + 1, "lbm") == 0) {
size = read_file(filename, g_res.tmp, 0);
} else {
size = read_compressed_file(filename, g_res.tmp);
}
assert(size <= 32000); assert(size <= 32000);
load_iff(g_res.tmp, size, g_res.tmp + 32000, 320); load_iff(g_res.tmp, size, g_res.tmp + 32000, 320);
g_sys.set_screen_palette(g_res.palette, 16); g_sys.set_screen_palette(g_res.palette, 16);
@ -255,21 +255,44 @@ void load_img(const char *filename) {
memcpy(g_res.vga, g_res.tmp + 32000, 64000); memcpy(g_res.vga, g_res.tmp + 32000, 64000);
} }
void load_sqv(const char *filename, uint8_t *dst, int offset) { static int load_spr_helper(int offset, const uint8_t *ptr, uint16_t (*read16)(const uint8_t *)) {
read_compressed_file(filename, dst); const int count = read16(ptr); ptr += 6;
const uint8_t *ptr = dst; print_debug(DBG_RESOURCE, "spr count %d", count);
const int count = READ_LE_UINT16(ptr); ptr += 6;
print_debug(DBG_RESOURCE, "sqv count %d", count);
assert(offset + count <= MAX_SPR_FRAMES); assert(offset + count <= MAX_SPR_FRAMES);
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
g_res.spr_frames[offset + i] = ptr; g_res.spr_frames[offset + i] = ptr;
const int h = READ_LE_UINT16(ptr - 4); const int h = read16(ptr - 4);
const int w = READ_LE_UINT16(ptr - 2); const int w = read16(ptr - 2);
assert((w & 3) == 0); assert((w & 3) == 0);
const int size = (w >> 1) * h + 4; const int size = (w >> 1) * h + 4;
print_debug(DBG_RESOURCE, "sprite %d, dim %d,%d size %d", i, w, h, size); print_debug(DBG_RESOURCE, "sprite %d, dim %d,%d size %d", i, w, h, size);
ptr += size; ptr += size;
} }
return count;
}
void load_spr(const char *filename, uint8_t *dst, int offset) {
read_file(filename, dst, 0);
const int count = load_spr_helper(offset, dst, READ_BE_UINT16);
g_res.spr_count = offset + count;
// convert to little endian
uint8_t *ptr = dst;
for (int i = 0; i < count; ++i) {
const int h = READ_BE_UINT16(ptr + 2);
ptr[2] = h;
ptr[3] = 0;
const int w = READ_BE_UINT16(ptr + 4);
ptr[4] = w;
ptr[5] = 0;
assert((w & 3) == 0);
const int size = (w >> 1) * h + 4;
ptr += size;
}
}
void load_sqv(const char *filename, uint8_t *dst, int offset) {
read_compressed_file(filename, dst);
const int count = load_spr_helper(offset, dst, READ_LE_UINT16);
g_res.spr_count = offset + count; g_res.spr_count = offset + count;
} }

View File

@ -50,13 +50,14 @@ extern struct resource_data_t g_res;
extern void res_init(); extern void res_init();
extern void res_fini(); extern void res_fini();
extern int read_file(const char *filename, uint8_t *dst); 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);
extern void load_avt(const char *filename, uint8_t *dst, int offset); extern void load_avt(const char *filename, uint8_t *dst, int offset);
extern void load_bin(const char *filename); extern void load_bin(const char *filename);
extern void load_ck(const char *filename, uint16_t offset); extern void load_ck(const char *filename, uint16_t offset);
extern void load_img(const char *filename); extern void load_img(const char *filename);
extern void load_sqv(const char *filename, uint8_t *dst, int size); extern void load_spr(const char *filename, uint8_t *dst, int offset);
extern void load_sqv(const char *filename, uint8_t *dst, int offset);
extern void load_sql(const char *filename); extern void load_sql(const char *filename);
extern uint8_t * lookup_sql(int x, int y); extern uint8_t * lookup_sql(int x, int y);

View File

@ -160,6 +160,7 @@ void screen_add_game_sprite4(int x, int y, int frame, int blinking_counter) {
} }
static void decode_graphics(int spr_type, int start, int end) { static void decode_graphics(int spr_type, int start, int end) {
const bool amiga = g_options.amiga_sprites && start != 0;
struct sys_rect_t r[MAX_SPR_FRAMES]; struct sys_rect_t r[MAX_SPR_FRAMES];
uint8_t *data = (uint8_t *)calloc(MAX_SPRITESHEET_W * MAX_SPRITESHEET_H, 1); uint8_t *data = (uint8_t *)calloc(MAX_SPRITESHEET_W * MAX_SPRITESHEET_H, 1);
if (data) { if (data) {
@ -179,11 +180,19 @@ static void decode_graphics(int spr_type, int start, int end) {
} }
current_x = 0; current_x = 0;
max_h = h; max_h = h;
if (amiga) {
decode_amiga_planar8(ptr, w / 8, h, 4, data, MAX_SPRITESHEET_W, current_x, current_y);
} else {
decode_ega_spr(ptr, w, w, h, data, MAX_SPRITESHEET_W, current_x, current_y); decode_ega_spr(ptr, w, w, h, data, MAX_SPRITESHEET_W, current_x, current_y);
}
r[j].x = current_x; r[j].x = current_x;
r[j].y = current_y; r[j].y = current_y;
} else {
if (amiga) {
decode_amiga_planar8(ptr, w / 8, h, 4, data, MAX_SPRITESHEET_W, current_x, current_y);
} else { } else {
decode_ega_spr(ptr, w, w, h, data, MAX_SPRITESHEET_W, current_x, current_y); decode_ega_spr(ptr, w, w, h, data, MAX_SPRITESHEET_W, current_x, current_y);
}
r[j].x = current_x; r[j].x = current_x;
r[j].y = current_y; r[j].y = current_y;
current_x += w; current_x += w;