Import blues from 3c41f366

This commit is contained in:
Gregory Montoir 2018-07-27 22:02:05 +08:00
parent d8c0b40e94
commit e46e90d22a
10 changed files with 71 additions and 70 deletions

29
game.c
View File

@ -42,20 +42,6 @@ void do_title_screen() {
g_sys.input.space = 0; g_sys.input.space = 0;
} }
static void check_cheat_code() {
static const uint8_t codes[] = { 0x14, 0x17, 0x27, 0x18, 0x14, 0x23, 0x12, 0x12 };
if ((g_vars.inp_code & 0x80) == 0 && g_vars.inp_code != 0) {
if (g_vars.inp_code == codes[g_vars.cheat_code_len]) {
++g_vars.cheat_code_len;
if (g_vars.cheat_code_len == ARRAYSIZE(codes)) {
g_vars.cheat_flag = 1;
}
} else {
g_vars.cheat_code_len = 0;
}
}
}
void do_select_player() { void do_select_player() {
int quit = 0; int quit = 0;
int fade = 0; int fade = 0;
@ -197,17 +183,6 @@ void do_select_player() {
} }
screen_clear_last_sprite(); screen_clear_last_sprite();
screen_redraw_sprites(); screen_redraw_sprites();
if (g_vars.cheat_flag) {
for (int i = 5; i >= 0; --i) {
if (g_vars.inp_keyboard[2 + i]) {
g_vars.level = i;
break;
}
}
// screen_draw_number_type1(_level + 1, 256, 148, 2);
} else {
check_cheat_code();
}
screen_flip(); screen_flip();
screen_vsync(); screen_vsync();
const int diff = (timestamp + (1000 / 30)) - g_sys.get_timestamp(); const int diff = (timestamp + (1000 / 30)) - g_sys.get_timestamp();
@ -276,7 +251,6 @@ static void do_inter_screen() {
} }
g_vars.screen_draw_offset = 0x2000; g_vars.screen_draw_offset = 0x2000;
screen_flip(); screen_flip();
g_vars.screen_h = TILEMAP_SCREEN_H;
const uint32_t timestamp = g_sys.get_timestamp() + 4 * 1000; const uint32_t timestamp = g_sys.get_timestamp() + 4 * 1000;
do { do {
update_input(); update_input();
@ -289,8 +263,6 @@ static void do_inter_screen() {
void game_main() { void game_main() {
play_music(0); play_music(0);
g_vars.screen_w = GAME_SCREEN_W;
g_vars.screen_h = GAME_SCREEN_H;
g_vars.screen_draw_offset = 0; g_vars.screen_draw_offset = 0;
screen_init(); screen_init();
screen_flip(); screen_flip();
@ -350,7 +322,6 @@ void game_main() {
do_title_screen(); do_title_screen();
while (!g_sys.input.quit) { while (!g_sys.input.quit) {
if (!g_vars.level_completed_flag) { if (!g_vars.level_completed_flag) {
// _level_cheat_code = 0;
g_vars.game_over_flag = 0; g_vars.game_over_flag = 0;
g_vars.play_level_flag = 1; g_vars.play_level_flag = 1;
if (!g_vars.play_demo_flag) { if (!g_vars.play_demo_flag) {

34
game.h
View File

@ -4,8 +4,8 @@
#include "intern.h" #include "intern.h"
#define GAME_SCREEN_W 320 #define GAME_SCREEN_W g_options.screen_w
#define GAME_SCREEN_H 200 #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
@ -33,13 +33,17 @@
#define SOUND_15 15 #define SOUND_15 15
#define SOUND_16 16 #define SOUND_16 16
#define CHEATS_NO_HIT (1 << 0) #define CHEATS_NO_HIT (1 << 0)
#define CHEATS_UNLIMITED_LIFES (1 << 1)
#define CHEATS_UNLIMITED_ENERGY (1 << 2)
struct options_t { struct options_t {
uint32_t cheats; uint32_t cheats;
int start_level; int start_level;
int start_xpos16; int start_xpos16;
int start_ypos16; int start_ypos16;
int screen_w;
int screen_h;
bool amiga_copper_bars; bool amiga_copper_bars;
bool amiga_colors; bool amiga_colors;
bool amiga_data; bool amiga_data;
@ -145,7 +149,6 @@ struct vars_t {
int start_level; int start_level;
int16_t level_xpos[MAX_OBJECTS]; int16_t level_xpos[MAX_OBJECTS];
int16_t level_ypos[MAX_OBJECTS]; int16_t level_ypos[MAX_OBJECTS];
int screen_w, screen_h;
int screen_tilemap_w, screen_tilemap_h; int screen_tilemap_w, screen_tilemap_h;
int screen_tilemap_w16, screen_tilemap_h16; int screen_tilemap_w16, screen_tilemap_h16;
int screen_tilemap_xorigin, screen_tilemap_yorigin; int screen_tilemap_xorigin, screen_tilemap_yorigin;
@ -154,18 +157,18 @@ struct vars_t {
int screen_scrolling_dirmask, screen_unk1; int screen_scrolling_dirmask, screen_unk1;
int screen_draw_h, screen_draw_offset; int screen_draw_h, screen_draw_offset;
int screen_tile_lut[256]; int screen_tile_lut[256];
int level_completed_flag; bool level_completed_flag;
int play_level_flag; bool play_level_flag;
int game_over_flag; bool game_over_flag;
int found_music_instrument_flag; bool found_music_instrument_flag;
int player2_dead_flag; bool player2_dead_flag;
int player1_dead_flag; bool player1_dead_flag;
int player2_scrolling_flag; bool player2_scrolling_flag;
int play_demo_flag; bool play_demo_flag;
int quit_level_flag; bool quit_level_flag;
bool two_players_flag;
int music_num; int music_num;
uint8_t inp_keyboard[256]; uint8_t inp_keyboard[256];
uint8_t inp_code;
int inp_key_space; int inp_key_space;
int inp_key_tab; int inp_key_tab;
int inp_key_up; int inp_key_up;
@ -176,10 +179,7 @@ struct vars_t {
int inp_key_down_prev; int inp_key_down_prev;
int inp_key_action; int inp_key_action;
struct door_t doors[MAX_DOORS]; struct door_t doors[MAX_DOORS];
int cheat_code_len;
int cheat_flag;
struct object_t objects[MAX_OBJECTS]; struct object_t objects[MAX_OBJECTS];
int two_players_flag;
int vinyls_count; int vinyls_count;
uint16_t level_loop_counter; uint16_t level_loop_counter;
int triggers_counter; int triggers_counter;

21
level.c
View File

@ -232,10 +232,9 @@ static void init_level() {
obj->data51 = 3; obj->data51 = 3;
obj->vinyls_count = 0; obj->vinyls_count = 0;
} }
if (g_vars.cheat_flag) { if (g_options.cheats & CHEATS_UNLIMITED_LIFES) {
obj->lifes_count = 3; obj->lifes_count = 3;
obj->data51 = 3; obj->data51 = 3;
obj->vinyls_count = 0;
} }
obj->unk63 = 0; obj->unk63 = 0;
obj->flag_end_level = 0; obj->flag_end_level = 0;
@ -646,7 +645,7 @@ static void do_level_add_sprite1_case4(struct object_t *obj) {
obj35->xpos16 = obj->xpos16; obj35->xpos16 = obj->xpos16;
obj35->ypos16 = obj->ypos16; obj35->ypos16 = obj->ypos16;
obj35->anim_num = 1; obj35->anim_num = 1;
obj37->animframes_ptr = animframes_059d + (obj37->type * 116 / 4); obj35->animframes_ptr = animframes_059d + (obj35->type * 116 / 4);
} else { } else {
obj35->unk2E = 0; obj35->unk2E = 0;
const int num = triggers_get_tile_type(obj35->xpos16, obj35->ypos16); const int num = triggers_get_tile_type(obj35->xpos16, obj35->ypos16);
@ -709,6 +708,8 @@ static void do_level_add_sprite1(struct object_t *obj) {
static void do_level_add_sprite2(struct object_t *obj) { static void do_level_add_sprite2(struct object_t *obj) {
print_debug(DBG_GAME, "add_sprite2 obj->type %d", obj->type); print_debug(DBG_GAME, "add_sprite2 obj->type %d", obj->type);
assert(obj->type == 2);
assert(obj->animframes_ptr);
const uint8_t *anim_data = obj->animframes_ptr[obj->grab_type]; const uint8_t *anim_data = obj->animframes_ptr[obj->grab_type];
if (obj->anim_num < anim_data[0]) { if (obj->anim_num < anim_data[0]) {
++obj->anim_num; ++obj->anim_num;
@ -812,7 +813,7 @@ void do_level_update_tile(int x, int y, int num) {
if ((g_vars.screen_tilemap_yorigin >> 4) > y) { if ((g_vars.screen_tilemap_yorigin >> 4) > y) {
return; return;
} }
if ((g_vars.screen_tilemap_xorigin >> 4) + (TILEMAP_SCREEN_H / 16) <= y) { if ((g_vars.screen_tilemap_yorigin >> 4) + (TILEMAP_SCREEN_H / 16) <= y) {
return; return;
} }
if (num >= 128) { if (num >= 128) {
@ -1381,15 +1382,15 @@ static void do_level_update_object_bounds(struct object_t *obj) {
int _si = g_vars.objects[OBJECT_NUM_PLAYER1].screen_xpos - obj->screen_xpos; int _si = g_vars.objects[OBJECT_NUM_PLAYER1].screen_xpos - obj->screen_xpos;
int _di = g_vars.objects[OBJECT_NUM_PLAYER1].screen_ypos - obj->screen_ypos; int _di = g_vars.objects[OBJECT_NUM_PLAYER1].screen_ypos - obj->screen_ypos;
if (g_vars.objects[OBJECT_NUM_PLAYER1].special_anim == 16) { if (g_vars.objects[OBJECT_NUM_PLAYER1].special_anim == 16) {
_si = 320; _si = GAME_SCREEN_W;
_di = 200; _di = GAME_SCREEN_H;
} }
if (g_vars.two_players_flag) { if (g_vars.two_players_flag) {
int tmp_dx = g_vars.objects[OBJECT_NUM_PLAYER2].screen_xpos - obj->screen_xpos; int tmp_dx = g_vars.objects[OBJECT_NUM_PLAYER2].screen_xpos - obj->screen_xpos;
int tmp_dy = g_vars.objects[OBJECT_NUM_PLAYER2].screen_ypos - obj->screen_ypos; int tmp_dy = g_vars.objects[OBJECT_NUM_PLAYER2].screen_ypos - obj->screen_ypos;
if (g_vars.objects[OBJECT_NUM_PLAYER2].special_anim == 16) { if (g_vars.objects[OBJECT_NUM_PLAYER2].special_anim == 16) {
tmp_dx = 320; tmp_dx = GAME_SCREEN_W;
tmp_dy = 200; tmp_dy = GAME_SCREEN_H;
} }
if (ABS(_si) >= ABS(tmp_dx) && ABS(_di) >= ABS(tmp_dy)) { if (ABS(_si) >= ABS(tmp_dx) && ABS(_di) >= ABS(tmp_dy)) {
obj->player_xdist = tmp_dx; obj->player_xdist = tmp_dx;
@ -1625,7 +1626,7 @@ static void do_level_handle_object_bonus_collision(struct object_t *obj, struct
void do_level_player_hit(struct object_t *obj) { void do_level_player_hit(struct object_t *obj) {
if (obj->blinking_counter == 0) { if (obj->blinking_counter == 0) {
g_vars.screen_draw_h = 172; g_vars.screen_draw_h = 172;
if (obj->data51 > 0) { if (obj->data51 > 0 && (g_options.cheats & CHEATS_UNLIMITED_ENERGY) == 0) {
--obj->data51; --obj->data51;
do_level_update_panel_lifes(obj); do_level_update_panel_lifes(obj);
} }
@ -2167,7 +2168,7 @@ void do_level() {
g_vars.player2_scrolling_flag = 0; g_vars.player2_scrolling_flag = 0;
g_vars.screen_draw_h = TILEMAP_SCREEN_H; g_vars.screen_draw_h = TILEMAP_SCREEN_H;
g_vars.found_music_instrument_flag = 0; g_vars.found_music_instrument_flag = 0;
render_set_sprites_clipping_rect(0, TILEMAP_OFFSET_Y, TILEMAP_SCREEN_W, TILEMAP_SCREEN_H - TILEMAP_OFFSET_Y); render_set_sprites_clipping_rect(0, TILEMAP_OFFSET_Y, TILEMAP_SCREEN_W, TILEMAP_SCREEN_H);
do { do {
const uint32_t timestamp = g_sys.get_timestamp(); const uint32_t timestamp = g_sys.get_timestamp();
update_input(); update_input();

18
main.c
View File

@ -20,11 +20,19 @@ static const char *USAGE =
"Usage: %s [OPTIONS]...\n" "Usage: %s [OPTIONS]...\n"
" --datapath=PATH Path to data files (default '.')\n" " --datapath=PATH Path to data files (default '.')\n"
" --level=NUM Start at level NUM\n" " --level=NUM Start at level NUM\n"
" --debug=MASK Debug mask\n"
" --startpos=XxY Start at position (X,Y)\n"
" --fullscreen Enable fullscreen\n"
" --scale Graphics scaling factor (default 2)\n"
" --filter Graphics scaling filter\n"
" --screensize=WxH Graphics screen size (default 320x200)\n"
; ;
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;
g_options.screen_w = 320;
g_options.screen_h = 200;
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_data = true; // g_options.amiga_data = true;
@ -49,6 +57,7 @@ int main(int argc, char *argv[]) {
{ "fullscreen", no_argument, 0, 6 }, { "fullscreen", no_argument, 0, 6 },
{ "scale", required_argument, 0, 7 }, { "scale", required_argument, 0, 7 },
{ "filter", required_argument, 0, 8 }, { "filter", required_argument, 0, 8 },
{ "screensize", required_argument, 0, 9 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 },
}; };
int index; int index;
@ -81,6 +90,12 @@ int main(int argc, char *argv[]) {
case 8: case 8:
scale_filter = strdup(optarg); scale_filter = strdup(optarg);
break; break;
case 9:
sscanf(optarg, "%dx%d", &g_options.screen_w, &g_options.screen_h);
// align to tile 16x16
g_options.screen_w = (g_options.screen_w + 15) & ~15;
g_options.screen_h = ((g_options.screen_h + 15) & ~15) + 40;
break;
default: default:
fprintf(stdout, USAGE, argv[0]); fprintf(stdout, USAGE, argv[0]);
return -1; return -1;
@ -99,5 +114,8 @@ int main(int argc, char *argv[]) {
if (data_path != DEFAULT_DATA_PATH) { if (data_path != DEFAULT_DATA_PATH) {
free((char *)data_path); free((char *)data_path);
} }
if (scale_filter != DEFAULT_SCALE_FILTER) {
free((char *)scale_filter);
}
return 0; return 0;
} }

View File

@ -168,11 +168,7 @@ static void object_func_op7(struct object_t *obj) {
obj->unk42 = 0; obj->unk42 = 0;
do_level_update_projectile(obj); do_level_update_projectile(obj);
} }
if (obj->player_xdist < 0) { obj->facing_left = (obj->player_xdist < 0) ? 1 : 0;
obj->facing_left = 1;
} else {
obj->facing_left = 0;
}
} }
} else { } else {
if (obj->anim_num == 16) { if (obj->anim_num == 16) {
@ -306,7 +302,7 @@ static void object_func_op14_helper(int x1, int y1, int x2, int y2, int color) {
static void object_func_op14(struct object_t *obj) { static void object_func_op14(struct object_t *obj) {
obj->special_anim = 2; obj->special_anim = 2;
object_func_op14_helper(obj->xpos, level_ypos_egou[obj->unk5D] - g_vars.screen_tilemap_yorigin, obj->xpos, obj->ypos - 5, 3); object_func_op14_helper(obj->screen_xpos, level_ypos_egou[obj->unk5D] - g_vars.screen_tilemap_yorigin, obj->screen_xpos, obj->screen_ypos - 5, 3);
if (obj->elevator_direction == 1) { if (obj->elevator_direction == 1) {
if (obj->moving_direction < 25) { if (obj->moving_direction < 25) {
++obj->moving_direction; ++obj->moving_direction;

View File

@ -32,6 +32,7 @@ void res_init(int vga_size) {
if (!g_res.vga) { if (!g_res.vga) {
print_error("Failed to allocate vga buffer, %d bytes", vga_size); print_error("Failed to allocate vga buffer, %d bytes", vga_size);
} }
g_res.vga_size = vga_size;
static const int TILES_SIZE = 640 * 200; static const int TILES_SIZE = 640 * 200;
g_res.tiles = (uint8_t *)malloc(TILES_SIZE); g_res.tiles = (uint8_t *)malloc(TILES_SIZE);
if (!g_res.tiles) { if (!g_res.tiles) {
@ -262,7 +263,7 @@ void load_img(const char *filename, int screen_w) {
load_iff(g_res.tmp, size, g_res.tmp + 32000, screen_w); load_iff(g_res.tmp, size, g_res.tmp + 32000, screen_w);
g_sys.set_screen_palette(g_res.palette, 16); g_sys.set_screen_palette(g_res.palette, 16);
g_sys.update_screen(g_res.tmp + 32000, 0); g_sys.update_screen(g_res.tmp + 32000, 0);
memcpy(g_res.vga, g_res.tmp + 32000, 64000); 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

@ -43,6 +43,7 @@ struct resource_data_t {
uint8_t palette[16 * 3]; uint8_t palette[16 * 3];
struct trigger_t triggers[MAX_TRIGGERS]; struct trigger_t triggers[MAX_TRIGGERS];
uint8_t *vga; uint8_t *vga;
int vga_size;
uint8_t *tiles; uint8_t *tiles;
uint8_t *snd; uint8_t *snd;
}; };

View File

@ -8,8 +8,12 @@
#define MAX_SPRITESHEET_W 512 #define MAX_SPRITESHEET_W 512
#define MAX_SPRITESHEET_H 512 #define MAX_SPRITESHEET_H 512
static int _offset_x, _offset_y;
void screen_init() { void screen_init() {
memset(g_res.vga, 0, GAME_SCREEN_W * GAME_SCREEN_H); memset(g_res.vga, 0, GAME_SCREEN_W * GAME_SCREEN_H);
_offset_x = (GAME_SCREEN_W > 320) ? (GAME_SCREEN_W - 320) / 2 : 0; // center horizontally
_offset_y = (GAME_SCREEN_H > 200) ? (GAME_SCREEN_H - 200) : 0; // align to bottom
} }
void screen_clear_sprites() { void screen_clear_sprites() {
@ -24,6 +28,11 @@ static void add_game_sprite(int x, int y, int frame, int xflip) {
if (frame >= SPRITES_COUNT) { if (frame >= SPRITES_COUNT) {
spr_type = RENDER_SPR_LEVEL; spr_type = RENDER_SPR_LEVEL;
frame -= SPRITES_COUNT; frame -= SPRITES_COUNT;
} else {
if (y >= 161 && frame >= 120) {
x += _offset_x;
y += _offset_y;
}
} }
render_add_sprite(spr_type, frame, x - w / 2, y - h, xflip); render_add_sprite(spr_type, frame, x - w / 2, y - h, xflip);
} }
@ -56,11 +65,9 @@ void screen_vsync() {
} }
void screen_draw_frame(const uint8_t *frame, int fh, int fw, int x, int y) { void screen_draw_frame(const uint8_t *frame, int fh, int fw, int x, int y) {
if (GAME_SCREEN_W > 320) { x += _offset_x;
x += (GAME_SCREEN_W - 320) / 2; if (y == 161) {
} y += _offset_y;
if (GAME_SCREEN_H > 200 && y == 161) { // align to the bottom
y += GAME_SCREEN_H - 200;
} }
y += fh + 2; y += fh + 2;
if (g_options.amiga_status_bar) { if (g_options.amiga_status_bar) {
@ -85,7 +92,7 @@ void screen_flip() {
} }
void screen_unk4() { void screen_unk4() {
memcpy(g_res.vga, g_res.tmp + 32000, 64000); memcpy(g_res.vga, g_res.tmp + 32000, GAME_SCREEN_W * GAME_SCREEN_H);
} }
void screen_unk5() { void screen_unk5() {
@ -162,6 +169,10 @@ static void draw_number_amiga(int digit, int x, int y) {
} }
void screen_draw_number(int num, int x, int y, int color) { void screen_draw_number(int num, int x, int y, int color) {
if (y >= 161) {
x += _offset_x;
y += _offset_y;
}
y += TILEMAP_OFFSET_Y; y += TILEMAP_OFFSET_Y;
if (g_options.amiga_status_bar) { if (g_options.amiga_status_bar) {
draw_number_amiga(num / 10, x - 8, y - 2); draw_number_amiga(num / 10, x - 8, y - 2);

View File

@ -4,6 +4,7 @@
#include "util.h" #include "util.h"
#define COPPER_BARS_H 80 #define COPPER_BARS_H 80
#define MAX_SPRITES 256
static const int FADE_STEPS = 16; static const int FADE_STEPS = 16;
@ -22,7 +23,7 @@ struct sprite_t {
bool xflip; bool xflip;
}; };
static struct sprite_t _sprites[128]; static struct sprite_t _sprites[MAX_SPRITES];
static int _sprites_count; static int _sprites_count;
static SDL_Rect _sprites_cliprect; static SDL_Rect _sprites_cliprect;

View File

@ -757,6 +757,7 @@ void triggers_update_tiles1(struct object_t *obj) {
return; return;
} }
p = t->op_table3; p = t->op_table3;
obj->trigger3 = p;
if (p[1] == 11) { if (p[1] == 11) {
if (obj->unk60 == 0) { if (obj->unk60 == 0) {
obj->unk60 = p[9]; obj->unk60 = p[9];