Import blues from c1e25536
This commit is contained in:
parent
140c6cdb1e
commit
9d70ca5872
|
@ -37,11 +37,11 @@ The data files of the DOS version, full game or [demo](http://cd.textfiles.com/c
|
|||
|
||||
## Changes
|
||||
|
||||
Compared to the original DOS executables, the rewritten engines feature :
|
||||
Compared to the original DOS executables, the rewritten engines feature:
|
||||
|
||||
- horizontal scrolling
|
||||
- configurable screen size
|
||||
- game cheats : unlimited lifes and energy, no hit
|
||||
- game cheats: unlimited lifes and energy, no hit
|
||||
|
||||
|
||||
## Running
|
||||
|
@ -66,4 +66,4 @@ Usage: blues [OPTIONS]...
|
|||
|
||||
## Downloads
|
||||
|
||||
[blues-sdl2-win32.zip](https://www.dropbox.com/s/vv8mh0vrk8l6xro/blues-gh-sdl2-win32.zip?dl=0) - Win32 executable
|
||||
[blues-sdl2-win32.zip](https://www.dropbox.com/s/rybnnn4s3rmicva/blues-gh-sdl2-win32.zip?dl=0) - Win32 executable
|
||||
|
|
28
bb/game.c
28
bb/game.c
|
@ -23,12 +23,12 @@ struct vars_t g_vars;
|
|||
|
||||
void update_input() {
|
||||
g_sys.process_events();
|
||||
g_vars.inp_key_left = ((g_sys.input.direction & INPUT_DIRECTION_LEFT) != 0) || g_vars.inp_keyboard[0x4B] || g_vars.inp_keyboard[0x7A];
|
||||
g_vars.inp_key_right = ((g_sys.input.direction & INPUT_DIRECTION_RIGHT) != 0) || g_vars.inp_keyboard[0x4D] || g_vars.inp_keyboard[0x79];
|
||||
g_vars.inp_key_up = ((g_sys.input.direction & INPUT_DIRECTION_UP) != 0) || g_vars.inp_keyboard[0x48] || g_vars.inp_keyboard[0x7C];
|
||||
g_vars.inp_key_down = ((g_sys.input.direction & INPUT_DIRECTION_DOWN) != 0) || g_vars.inp_keyboard[0x50] || g_vars.inp_keyboard[0x7B];
|
||||
g_vars.inp_key_space = g_sys.input.space || g_vars.inp_keyboard[0x39] || g_vars.inp_keyboard[0x77];
|
||||
// g_vars.inp_key_tab = g_vars.inp_keyboard[0xF] || g_vars.inp_keyboard[0x78];
|
||||
g_vars.inp_key_left = ((g_sys.input.direction & INPUT_DIRECTION_LEFT) != 0);
|
||||
g_vars.inp_key_right = ((g_sys.input.direction & INPUT_DIRECTION_RIGHT) != 0);
|
||||
g_vars.inp_key_up = ((g_sys.input.direction & INPUT_DIRECTION_UP) != 0);
|
||||
g_vars.inp_key_down = ((g_sys.input.direction & INPUT_DIRECTION_DOWN) != 0);
|
||||
g_vars.inp_key_space = g_sys.input.space;
|
||||
g_vars.inp_key_jump = g_sys.input.jump;
|
||||
}
|
||||
|
||||
static void do_title_screen() {
|
||||
|
@ -78,8 +78,8 @@ static void do_select_player() {
|
|||
if (g_res.spr_count <= SPRITES_COUNT) {
|
||||
screen_load_graphics(g_options.cga_colors ? g_res.cga_lut_sqv : 0, 0);
|
||||
}
|
||||
screen_clear_sprites();
|
||||
do {
|
||||
screen_clear_sprites(1);
|
||||
update_input();
|
||||
const uint32_t timestamp = g_sys.get_timestamp();
|
||||
switch (state) {
|
||||
|
@ -205,11 +205,10 @@ static void do_select_player() {
|
|||
}
|
||||
continue;
|
||||
}
|
||||
screen_flip();
|
||||
g_sys.update_screen();
|
||||
screen_vsync();
|
||||
const int diff = (timestamp + (1000 / 30)) - g_sys.get_timestamp();
|
||||
g_sys.sleep(diff < 10 ? 10 : diff);
|
||||
screen_clear_sprites();
|
||||
if (g_sys.input.space || g_vars.play_demo_flag) {
|
||||
quit = 1;
|
||||
}
|
||||
|
@ -222,14 +221,14 @@ static void do_inter_screen_helper(int xpos, int ypos, int c) {
|
|||
if (c != 0) {
|
||||
screen_vsync();
|
||||
}
|
||||
screen_clear_sprites();
|
||||
screen_clear_sprites(1);
|
||||
}
|
||||
for (int i = 0; i < 40; ++i) {
|
||||
screen_add_sprite(xpos - 20 + 1 + i, ypos - 20 + 1 + i, 125);
|
||||
if (c != 0) {
|
||||
screen_vsync();
|
||||
}
|
||||
screen_clear_sprites();
|
||||
screen_clear_sprites(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,7 +236,7 @@ static void do_inter_screen() {
|
|||
static const uint8_t xpos[] = { 0xFA, 0x50, 0xF0, 0xC8, 0x50, 0x50 };
|
||||
static const uint8_t ypos[] = { 0xAA, 0x37, 0x28, 0x5F, 0xA5, 0xAA };
|
||||
load_img(g_res.amiga_data ? "inter.lbm" : "inter.sqz", GAME_SCREEN_W, g_options.cga_colors ? 9 : -1);
|
||||
screen_clear_sprites();
|
||||
screen_clear_sprites(1);
|
||||
if (g_vars.level > 1) {
|
||||
for (int i = 0; i < g_vars.level - 1; ++i) {
|
||||
do_inter_screen_helper(xpos[i], ypos[i], 0);
|
||||
|
@ -251,12 +250,12 @@ static void do_inter_screen() {
|
|||
do_inter_screen_helper(xpos[g_vars.level - 1], ypos[g_vars.level - 1], 1);
|
||||
}
|
||||
// screen_do_transition2();
|
||||
screen_flip();
|
||||
g_sys.update_screen();
|
||||
if (g_vars.level < MAX_LEVELS - 1) {
|
||||
play_sound(SOUND_2);
|
||||
screen_add_sprite(xpos[g_vars.level], ypos[g_vars.level], 126);
|
||||
}
|
||||
screen_flip();
|
||||
g_sys.update_screen();
|
||||
const uint32_t timestamp = g_sys.get_timestamp() + 4 * 1000;
|
||||
do {
|
||||
update_input();
|
||||
|
@ -270,7 +269,6 @@ static void do_inter_screen() {
|
|||
void game_main() {
|
||||
play_music(0);
|
||||
screen_init();
|
||||
screen_flip();
|
||||
g_vars.start_level = 0;
|
||||
if (g_res.amiga_data) {
|
||||
load_spr("sprite", g_res.spr_sqv, 0);
|
||||
|
|
12
bb/game.h
12
bb/game.h
|
@ -152,15 +152,16 @@ struct vars_t {
|
|||
bool two_players_flag;
|
||||
bool switch_player_scrolling_flag;
|
||||
int music_num;
|
||||
uint8_t inp_keyboard[256];
|
||||
bool inp_key_jump;
|
||||
bool inp_key_jump_prev;
|
||||
bool inp_key_space;
|
||||
bool inp_key_space_prev;
|
||||
bool inp_key_up;
|
||||
bool inp_key_up_prev;
|
||||
bool inp_key_down;
|
||||
bool inp_key_down_prev;
|
||||
bool inp_key_right;
|
||||
bool inp_key_left;
|
||||
bool inp_key_up_prev;
|
||||
bool inp_key_down_prev;
|
||||
bool inp_key_space_prev;
|
||||
struct door_t doors[MAX_DOORS];
|
||||
struct object_t objects[MAX_OBJECTS];
|
||||
int vinyls_count;
|
||||
|
@ -219,13 +220,12 @@ extern void level_call_object_func(struct object_t *);
|
|||
|
||||
/* screen.c */
|
||||
extern void screen_init();
|
||||
extern void screen_clear_sprites();
|
||||
extern void screen_clear_sprites(int pos_flag);
|
||||
extern void screen_add_sprite(int x, int y, int frame);
|
||||
extern void fade_out_palette();
|
||||
extern void screen_adjust_palette_color(int color, int b, int c);
|
||||
extern void screen_vsync();
|
||||
extern void screen_draw_frame(const uint8_t *frame, int fh, int fw, int x, int y);
|
||||
extern void screen_flip();
|
||||
extern void screen_unk5();
|
||||
extern void screen_do_transition1(int a);
|
||||
extern void screen_do_transition2();
|
||||
|
|
48
bb/level.c
48
bb/level.c
|
@ -1162,7 +1162,8 @@ void do_level_enter_door(struct object_t *obj) {
|
|||
if (g_vars.two_players_flag) {
|
||||
do_level_update_panel_2nd_player();
|
||||
}
|
||||
screen_flip();
|
||||
g_sys.copy_bitmap(g_res.vga, GAME_SCREEN_W, GAME_SCREEN_H);
|
||||
g_sys.update_screen();
|
||||
screen_do_transition1(1);
|
||||
obj->unk3D = 0;
|
||||
obj->sprite_type = 0;
|
||||
|
@ -1224,9 +1225,9 @@ static void do_level_update_input(struct object_t *obj) {
|
|||
obj->direction_lr |= OBJECT_DIRECTION_LEFT;
|
||||
}
|
||||
_si = triggers_get_tile_type(obj->xpos16, obj->ypos16);
|
||||
if (g_vars.inp_key_up && !g_vars.inp_key_space) {
|
||||
if ((g_options.jump_button ? g_vars.inp_key_jump : g_vars.inp_key_up) && !g_vars.inp_key_space) {
|
||||
obj->direction_ud = OBJECT_DIRECTION_UP;
|
||||
if (!g_vars.inp_key_up_prev && obj->sprite_type != 0) {
|
||||
if ((g_options.jump_button ? !g_vars.inp_key_jump_prev : !g_vars.inp_key_up_prev) && obj->sprite_type != 0) {
|
||||
obj->yfriction = 0;
|
||||
_di = triggers_get_tile_type(obj->xpos16, obj->ypos16 - 2);
|
||||
if (_di == 10 && (_si == 0 || _si == 1)) {
|
||||
|
@ -1255,6 +1256,7 @@ static void do_level_update_input(struct object_t *obj) {
|
|||
}
|
||||
g_vars.inp_key_up_prev = g_vars.inp_key_up;
|
||||
g_vars.inp_key_down_prev = g_vars.inp_key_down;
|
||||
g_vars.inp_key_jump_prev = g_vars.inp_key_jump;
|
||||
if (obj->grab_state == 0) {
|
||||
if (obj->carry_crate_flag != 0 && _si == 5) { // crate
|
||||
obj->grab_type = 0;
|
||||
|
@ -1301,12 +1303,10 @@ static void do_level_update_scrolling(struct object_t *obj) {
|
|||
if ((g_vars.screen_scrolling_dirmask & 2) != 0 && obj->screen_xpos < TILEMAP_SCREEN_W / 2) {
|
||||
g_vars.screen_scrolling_dirmask &= ~2;
|
||||
g_vars.switch_player_scrolling_flag = 0;
|
||||
g_vars.inp_keyboard[0xC1] = 0;
|
||||
}
|
||||
if ((g_vars.screen_scrolling_dirmask & 1) != 0 && obj->screen_xpos > TILEMAP_SCREEN_W / 2) {
|
||||
g_vars.screen_scrolling_dirmask &= ~1;
|
||||
g_vars.switch_player_scrolling_flag = 0;
|
||||
g_vars.inp_keyboard[0xC1] = 0;
|
||||
}
|
||||
} else {
|
||||
int _si = (obj->xvelocity >> 3) + obj->unk1C;
|
||||
|
@ -1871,18 +1871,6 @@ static void do_level_update_objects() {
|
|||
obj->direction_lr = 0;
|
||||
obj->direction_ud = 0;
|
||||
if (obj->type < 2) {
|
||||
if (g_vars.inp_keyboard[0xC1] != 0) { // F7, change player
|
||||
if (!g_vars.switch_player_scrolling_flag && g_vars.two_players_flag) {
|
||||
if (!g_vars.player2_scrolling_flag && !g_vars.objects[OBJECT_NUM_PLAYER1].scrolling_lock_flag) {
|
||||
g_vars.player2_scrolling_flag = 1;
|
||||
g_vars.switch_player_scrolling_flag = 1;
|
||||
} else if (g_vars.player2_scrolling_flag && !g_vars.objects[OBJECT_NUM_PLAYER2].scrolling_lock_flag) {
|
||||
g_vars.player2_scrolling_flag = 1;
|
||||
g_vars.switch_player_scrolling_flag = 1;
|
||||
}
|
||||
}
|
||||
g_vars.inp_keyboard[0xC1] = 0;
|
||||
}
|
||||
if (obj->blinking_counter != 0) {
|
||||
--obj->blinking_counter;
|
||||
}
|
||||
|
@ -2099,7 +2087,7 @@ void do_level() {
|
|||
if (g_options.amiga_copper_bars) {
|
||||
g_sys.set_copper_bars(_copper_data + g_vars.level * 18);
|
||||
}
|
||||
g_vars.inp_keyboard[0xB9] = 0; // SPACE
|
||||
// g_vars.inp_keyboard[0xB9] = 0; // SPACE
|
||||
// g_vars.screen_draw_offset = TILEMAP_OFFSET_Y * 40;
|
||||
g_vars.update_objects_counter = 0;
|
||||
g_vars.game_over_flag = 0;
|
||||
|
@ -2110,25 +2098,9 @@ void do_level() {
|
|||
g_sys.render_set_sprites_clipping_rect(0, TILEMAP_OFFSET_Y, TILEMAP_SCREEN_W, TILEMAP_SCREEN_H);
|
||||
bool screen_transition_flag = true;
|
||||
do {
|
||||
screen_clear_sprites(0);
|
||||
const uint32_t timestamp = g_sys.get_timestamp();
|
||||
update_input();
|
||||
if (g_vars.inp_keyboard[0xBF] != 0) { // F5, quit game
|
||||
play_sound(SOUND_0);
|
||||
g_vars.inp_keyboard[0xBF] = 0;
|
||||
g_vars.quit_level_flag = 1;
|
||||
g_vars.play_level_flag = 0;
|
||||
g_vars.objects[OBJECT_NUM_PLAYER1].unk60 = 0;
|
||||
g_vars.objects[OBJECT_NUM_PLAYER2].unk60 = 0;
|
||||
g_vars.objects[OBJECT_NUM_PLAYER1].data5F = 0;
|
||||
g_vars.objects[OBJECT_NUM_PLAYER2].data5F = 0;
|
||||
if (!g_vars.play_demo_flag) {
|
||||
g_vars.start_level = 0;
|
||||
}
|
||||
} else if (g_vars.inp_keyboard[0xC4] != 0) { // F10
|
||||
play_sound(SOUND_0);
|
||||
while (g_vars.inp_keyboard[0xC4] != 0 && g_vars.inp_keyboard[0xB] == 0);
|
||||
while (g_vars.inp_keyboard[0xC4] != 0 && g_vars.inp_keyboard[0xB] != 0);
|
||||
}
|
||||
// demo
|
||||
do_level_update_scrolling2();
|
||||
do_level_update_objects();
|
||||
|
@ -2138,18 +2110,17 @@ void do_level() {
|
|||
++g_vars.level_loop_counter;
|
||||
draw_level_panel();
|
||||
|
||||
g_sys.copy_bitmap(g_res.vga, GAME_SCREEN_W, GAME_SCREEN_H);
|
||||
if (screen_transition_flag) {
|
||||
screen_transition_flag = false;
|
||||
g_sys.update_screen(g_res.vga, 0);
|
||||
screen_do_transition2();
|
||||
} else {
|
||||
g_sys.update_screen(g_res.vga, 1);
|
||||
g_sys.update_screen();
|
||||
}
|
||||
memset(g_res.vga, 0, GAME_SCREEN_W * GAME_SCREEN_H);
|
||||
|
||||
const int diff = (timestamp + (1000 / 30)) - g_sys.get_timestamp();
|
||||
g_sys.sleep(diff < 10 ? 10 : diff);
|
||||
screen_clear_sprites();
|
||||
|
||||
} while (!g_sys.input.quit && !g_vars.quit_level_flag);
|
||||
// g_vars.screen_draw_offset -= TILEMAP_OFFSET_Y * 40;
|
||||
|
@ -2158,5 +2129,4 @@ void do_level() {
|
|||
g_sys.set_copper_bars(0);
|
||||
}
|
||||
g_sys.render_set_sprites_clipping_rect(0, 0, GAME_SCREEN_W, GAME_SCREEN_H);
|
||||
g_vars.inp_keyboard[0xBF] = 0;
|
||||
}
|
||||
|
|
|
@ -314,11 +314,11 @@ void load_img(const char *filename, int screen_w, int dither_pattern) {
|
|||
size = read_compressed_file(filename, g_res.tmp);
|
||||
}
|
||||
assert(size <= 32000);
|
||||
load_iff(g_res.tmp, size, g_res.vga, screen_w, dither_pattern);
|
||||
load_iff(g_res.tmp, size, g_res.vga, 320, dither_pattern);
|
||||
g_sys.copy_bitmap(g_res.vga, 320, 200);
|
||||
if (dither_pattern < 0) {
|
||||
g_sys.set_screen_palette(g_res.palette, 0, 16, 8);
|
||||
}
|
||||
g_sys.update_screen(g_res.vga, 0);
|
||||
}
|
||||
|
||||
void load_m(const char *filename) {
|
||||
|
|
36
bb/screen.c
36
bb/screen.c
|
@ -8,15 +8,19 @@
|
|||
#define MAX_SPRITESHEET_W 512
|
||||
#define MAX_SPRITESHEET_H 512
|
||||
|
||||
static int _offset_x, _offset_y;
|
||||
static int _spr_pos_flag;
|
||||
|
||||
static int _offset_x_center, _offset_y_bottom, _offset_y_center;
|
||||
|
||||
void screen_init() {
|
||||
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
|
||||
_offset_x_center = (GAME_SCREEN_W > 320) ? (GAME_SCREEN_W - 320) / 2 : 0; // center horizontally
|
||||
_offset_y_center = (GAME_SCREEN_H > 200) ? (GAME_SCREEN_H - 200) / 2 : 0; // center vertically
|
||||
_offset_y_bottom = (GAME_SCREEN_H > 200) ? (GAME_SCREEN_H - 200) : 0; // align to bottom
|
||||
}
|
||||
|
||||
void screen_clear_sprites() {
|
||||
void screen_clear_sprites(int pos_flag) {
|
||||
_spr_pos_flag = pos_flag;
|
||||
g_sys.render_clear_sprites();
|
||||
}
|
||||
|
||||
|
@ -32,11 +36,6 @@ static void add_game_sprite(int x, int y, int frame, int xflip) {
|
|||
if (frame >= SPRITES_COUNT) {
|
||||
spr_type = RENDER_SPR_LEVEL;
|
||||
frame -= SPRITES_COUNT;
|
||||
} else {
|
||||
if (y >= 161 && frame >= 120) {
|
||||
x += _offset_x;
|
||||
y += _offset_y;
|
||||
}
|
||||
}
|
||||
g_sys.render_add_sprite(spr_type, frame, x - w / 2, y - h, xflip);
|
||||
}
|
||||
|
@ -60,6 +59,13 @@ void screen_add_sprite(int x, int y, int frame) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (_spr_pos_flag) { /* introduction screens */
|
||||
x += _offset_x_center;
|
||||
y += _offset_y_center;
|
||||
} else if ((frame >= 120 && frame < SPRITES_COUNT) && y >= 161) { /* bottom panel */
|
||||
x += _offset_x_center;
|
||||
y += _offset_y_bottom;
|
||||
}
|
||||
add_game_sprite(x, y, frame, 0);
|
||||
}
|
||||
|
||||
|
@ -82,9 +88,9 @@ void screen_vsync() {
|
|||
}
|
||||
|
||||
void screen_draw_frame(const uint8_t *frame, int fh, int fw, int x, int y) {
|
||||
x += _offset_x;
|
||||
x += _offset_x_center;
|
||||
if (y == 161) {
|
||||
y += _offset_y;
|
||||
y += _offset_y_bottom;
|
||||
}
|
||||
y += fh + 2;
|
||||
if (g_options.amiga_status_bar || g_res.amiga_data) {
|
||||
|
@ -104,10 +110,6 @@ void screen_draw_frame(const uint8_t *frame, int fh, int fw, int x, int y) {
|
|||
}
|
||||
}
|
||||
|
||||
void screen_flip() {
|
||||
g_sys.update_screen(g_res.vga, 1);
|
||||
}
|
||||
|
||||
void screen_unk5() {
|
||||
// screen_do_transition2();
|
||||
screen_clear(0);
|
||||
|
@ -183,8 +185,8 @@ static void draw_number_amiga(int digit, int x, int y) {
|
|||
|
||||
void screen_draw_number(int num, int x, int y, int color) {
|
||||
if (y >= 161) {
|
||||
x += _offset_x;
|
||||
y += _offset_y;
|
||||
x += _offset_x_center;
|
||||
y += _offset_y_bottom;
|
||||
}
|
||||
y += TILEMAP_OFFSET_Y;
|
||||
if (g_options.amiga_status_bar || g_res.amiga_data) {
|
||||
|
|
4
intern.h
4
intern.h
|
@ -11,7 +11,7 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
|
||||
#define SWAP(x, y) do { typeof(x) tmp = x; x = y; y = tmp; } while(0)
|
||||
#define SWAP(x, y) do { __typeof__(x) tmp = x; x = y; y = tmp; } while(0)
|
||||
|
||||
#undef MIN
|
||||
static inline int MIN(int a, int b) {
|
||||
|
@ -51,6 +51,7 @@ struct options_t {
|
|||
int screen_w;
|
||||
int screen_h;
|
||||
bool dos_scrolling;
|
||||
bool jump_button;
|
||||
// 'bb' only options
|
||||
bool amiga_copper_bars;
|
||||
bool amiga_colors;
|
||||
|
@ -62,7 +63,6 @@ struct options_t {
|
|||
|
||||
struct game_t {
|
||||
const char *name;
|
||||
//int (*detect)(const char *data_path);
|
||||
void (*run)(const char *data_path);
|
||||
};
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ void update_input() {
|
|||
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_key_jump = g_sys.input.jump ? 0xFF : 0;
|
||||
|
||||
g_vars.input_keystate[2] = g_sys.input.digit1;
|
||||
g_vars.input_keystate[3] = g_sys.input.digit2;
|
||||
|
@ -52,7 +53,8 @@ static void scroll_screen_palette() {
|
|||
for (int i = 0; i < count; ++i) {
|
||||
g_sys.set_palette_color(225 + i, g_res.tmp + (225 + g_vars.level_time + i) * 3);
|
||||
}
|
||||
g_sys.update_screen(g_res.vga, 1);
|
||||
g_sys.copy_bitmap(g_res.vga, 320, 200);
|
||||
g_sys.update_screen();
|
||||
}
|
||||
|
||||
static void do_select_screen_scroll_palette(int start, int end, int step, int count) {
|
||||
|
@ -66,7 +68,8 @@ static void do_select_screen_scroll_palette(int start, int end, int step, int co
|
|||
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.copy_bitmap(g_res.vga, 320, 200);
|
||||
g_sys.update_screen();
|
||||
g_sys.sleep(20);
|
||||
} while (--count != 0);
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ struct vars_t {
|
|||
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;
|
||||
uint8_t input_key_left, input_key_right, input_key_down, input_key_up, input_key_space, input_key_jump;
|
||||
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];
|
||||
|
|
14
ja/level.c
14
ja/level.c
|
@ -27,7 +27,8 @@ static void do_end_of_level() {
|
|||
ja_decode_motif(g_vars.level_num % 9, color_index);
|
||||
static const uint8_t white[] = { 0x3F, 0x3F, 0x3F };
|
||||
g_sys.set_palette_color(color_index, white);
|
||||
g_sys.update_screen(g_res.vga, 1);
|
||||
g_sys.copy_bitmap(g_res.vga, GAME_SCREEN_W, GAME_SCREEN_H);
|
||||
g_sys.update_screen();
|
||||
g_sys.sleep(1000);
|
||||
g_sys.fade_out_palette();
|
||||
}
|
||||
|
@ -398,7 +399,7 @@ static void level_update_player_anim_1(struct player_t *player) {
|
|||
static void level_update_player_anim_5(struct player_t *player) {
|
||||
level_player_update_hdirection(player);
|
||||
player->obj.spr_num = 5;
|
||||
if (player_jump_counter(&player->obj) != 0 && (player_flags2(&player->obj) & 1) == 0 && g_vars.input_key_up) {
|
||||
if (player_jump_counter(&player->obj) != 0 && (player_flags2(&player->obj) & 1) == 0 && (g_options.jump_button ? g_vars.input_key_jump : g_vars.input_key_up)) {
|
||||
--player_jump_counter(&player->obj);
|
||||
const int dy = (int8_t)player_anim_dy[player_jump_counter(&player->obj)] + player_y_delta(&player->obj);
|
||||
if (dy >= -70) {
|
||||
|
@ -550,7 +551,7 @@ static void level_update_player_anim_12(struct player_t *player) {
|
|||
static void level_update_player_anim_18(struct player_t *player) {
|
||||
level_player_update_hdirection(player);
|
||||
player->obj.spr_num = 18;
|
||||
if (player_jump_counter(&player->obj) != 0 && g_vars.input_key_up) {
|
||||
if (player_jump_counter(&player->obj) != 0 && (g_options.jump_button ? g_vars.input_key_jump : g_vars.input_key_up)) {
|
||||
--player_jump_counter(&player->obj);
|
||||
player_y_delta(&player->obj) += (int8_t)player_anim_dy[player_jump_counter(&player->obj)];
|
||||
}
|
||||
|
@ -594,7 +595,7 @@ static void level_update_player_anim_19(struct player_t *player) {
|
|||
static void level_update_player_anim_26(struct player_t *player) {
|
||||
level_player_update_hdirection(player);
|
||||
player->obj.spr_num = 26;
|
||||
if (player_jump_counter(&player->obj) == 0 || !g_vars.input_key_up) {
|
||||
if (player_jump_counter(&player->obj) == 0 || (g_options.jump_button ? !g_vars.input_key_jump : !g_vars.input_key_up)) {
|
||||
return;
|
||||
}
|
||||
--player_jump_counter(&player->obj);
|
||||
|
@ -737,7 +738,7 @@ static void level_update_player_from_input(struct player_t *player) {
|
|||
} else {
|
||||
mask <<= 4;
|
||||
if ((player_flags(&player->obj) & 0x10) == 0) {
|
||||
mask |= (g_vars.input_key_up & 8);
|
||||
mask |= (g_options.jump_button ? g_vars.input_key_jump : g_vars.input_key_up) & 8;
|
||||
}
|
||||
mask |= (g_vars.input_key_right & 4);
|
||||
if (player_jump_counter(&player->obj) == 7) {
|
||||
|
@ -2695,7 +2696,8 @@ static void level_sync() {
|
|||
--g_vars.level_time;
|
||||
}
|
||||
}
|
||||
g_sys.update_screen(g_res.vga, 1);
|
||||
g_sys.copy_bitmap(g_res.vga, GAME_SCREEN_W, GAME_SCREEN_H);
|
||||
g_sys.update_screen();
|
||||
g_sys.render_clear_sprites();
|
||||
const int diff = (g_vars.timestamp + (1000 / 30)) - g_sys.get_timestamp();
|
||||
g_sys.sleep(MAX(diff, 10));
|
||||
|
|
13
ja/screen.c
13
ja/screen.c
|
@ -46,17 +46,8 @@ void video_copy_vga(int size) {
|
|||
} else {
|
||||
assert(size == 0x7D00);
|
||||
g_sys.set_screen_palette(g_res.tmp, 0, 256, 6);
|
||||
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);
|
||||
memcpy(g_res.vga, g_res.tmp + 768, 64000);
|
||||
g_sys.copy_bitmap(g_res.vga, 320, 200);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
/* uncompress data packed with DIET by T.Matsumoto */
|
||||
/* uncompress data packed with DIET.EXE */
|
||||
|
||||
#include "unpack.h"
|
||||
#include "util.h"
|
||||
|
|
63
main.c
63
main.c
|
@ -28,43 +28,40 @@ static const char *USAGE =
|
|||
;
|
||||
|
||||
static struct game_t *detect_game(const char *data_path) {
|
||||
#if 0
|
||||
extern struct game_t bb_game;
|
||||
extern struct game_t ja_game;
|
||||
extern struct game_t p2_game;
|
||||
static struct game_t *games[] = {
|
||||
&bb_game,
|
||||
&ja_game,
|
||||
&p2_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
|
||||
}
|
||||
|
||||
#if defined(PSP)
|
||||
/* stubs */
|
||||
void sound_init() {
|
||||
}
|
||||
void sound_fini() {
|
||||
}
|
||||
void play_sound(int num) {
|
||||
}
|
||||
void play_music(int num) {
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
g_options.start_xpos16 = -1;
|
||||
g_options.start_ypos16 = -1;
|
||||
g_options.screen_w = 320;
|
||||
g_options.screen_h = 200;
|
||||
g_options.dos_scrolling = false;
|
||||
g_options.amiga_copper_bars = true;
|
||||
g_options.amiga_colors = true;
|
||||
// g_options.amiga_status_bar = true;
|
||||
g_options.cga_colors = false;
|
||||
g_options.hybrid_color = false;
|
||||
const char *data_path = DEFAULT_DATA_PATH;
|
||||
int scale_factor = DEFAULT_SCALE_FACTOR;
|
||||
const char *scale_filter = DEFAULT_SCALE_FILTER;
|
||||
bool fullscreen = false;
|
||||
g_options.start_xpos16 = -1;
|
||||
g_options.start_ypos16 = -1;
|
||||
g_options.amiga_copper_bars = true;
|
||||
g_options.amiga_colors = true;
|
||||
// g_options.amiga_status_bar = true;
|
||||
#if defined(PSP)
|
||||
g_options.screen_w = 480;
|
||||
g_options.screen_h = 272;
|
||||
g_options.jump_button = true;
|
||||
#else
|
||||
g_options.screen_w = 320;
|
||||
g_options.screen_h = 200;
|
||||
// g_options.jump_button = true;
|
||||
if (argc == 2) {
|
||||
struct stat st;
|
||||
if (stat(argv[1], &st) == 0 && S_ISDIR(st.st_mode)) {
|
||||
|
@ -121,7 +118,14 @@ int main(int argc, char *argv[]) {
|
|||
if (sscanf(optarg, "%dx%d", &g_options.screen_w, &g_options.screen_h) == 2) {
|
||||
// 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; // PANEL_H
|
||||
g_options.screen_h = ((g_options.screen_h + 15) & ~15) + 40; // PANEL_H;
|
||||
// do not allow lower resolution than the original
|
||||
if (g_options.screen_w < 320) {
|
||||
g_options.screen_w = 320;
|
||||
}
|
||||
if (g_options.screen_h < 200) {
|
||||
g_options.screen_h = 200;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
|
@ -138,6 +142,7 @@ int main(int argc, char *argv[]) {
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
struct game_t *game = detect_game(data_path);
|
||||
if (!game) {
|
||||
fprintf(stdout, "No data files found\n");
|
||||
|
|
27
p2/game.c
27
p2/game.c
|
@ -15,6 +15,7 @@ void update_input() {
|
|||
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.key_jump = g_sys.input.jump ? 0xFF : 0;
|
||||
|
||||
g_vars.input.keystate[2] = g_sys.input.digit1;
|
||||
g_vars.input.keystate[3] = g_sys.input.digit2;
|
||||
|
@ -51,7 +52,8 @@ static void do_programmed_in_1992_screen() {
|
|||
video_draw_string(offset, 1, "PROGRAMMED IN 1992 ON AT >286 12MHZ>");
|
||||
offset += 0x1E0;
|
||||
video_draw_string(offset, 3, "> > > ENJOY OLDIES<<");
|
||||
g_sys.update_screen(g_res.vga, 1);
|
||||
g_sys.copy_bitmap(g_res.vga, 320, 200);
|
||||
g_sys.update_screen();
|
||||
wait_input(100);
|
||||
video_clear();
|
||||
}
|
||||
|
@ -76,23 +78,14 @@ static void do_credits() {
|
|||
video_draw_string(offset, 2, "CRISTELLE> GIL ESPECHE AND CORINNE>");
|
||||
offset += 0x1E0;
|
||||
video_draw_string(offset, 0, "SEBASTIEN BECHET AND OLIVIER AKA DELTA>");
|
||||
g_sys.update_screen(g_res.vga, 1);
|
||||
g_sys.copy_bitmap(g_res.vga, 320, 200);
|
||||
g_sys.update_screen();
|
||||
}
|
||||
|
||||
static void update_screen_img(const uint8_t *src, int present) {
|
||||
const int size = GAME_SCREEN_W * GAME_SCREEN_H;
|
||||
if (size < 64000) {
|
||||
return;
|
||||
} else if (size == 64000) {
|
||||
g_sys.update_screen(src, present);
|
||||
} else {
|
||||
memset(g_res.vga, 0, size);
|
||||
const int y_offs = (GAME_SCREEN_H - 200) / 2;
|
||||
const int x_offs = (GAME_SCREEN_W - 320) / 2;
|
||||
for (int y = 0; y < 200; ++y) {
|
||||
memcpy(g_res.vga + (y_offs + y) * GAME_SCREEN_W + x_offs, src + y * 320, 320);
|
||||
}
|
||||
g_sys.update_screen(g_res.vga, present);
|
||||
g_sys.copy_bitmap(src, 320, 200);
|
||||
if (present) {
|
||||
g_sys.update_screen();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,8 +183,8 @@ void do_gameover_screen() {
|
|||
if (data) {
|
||||
video_copy_img(data);
|
||||
video_copy_background();
|
||||
g_sys.update_screen(g_res.vga, 0);
|
||||
g_sys.set_screen_palette(gameover_palette_data, 0, 16, 6);
|
||||
g_sys.copy_bitmap(g_res.vga, GAME_SCREEN_W, GAME_SCREEN_H);
|
||||
do_gameover_animation();
|
||||
g_sys.fade_out_palette();
|
||||
free(data);
|
||||
|
@ -205,8 +198,8 @@ static void do_menu2() {
|
|||
if (data) {
|
||||
video_copy_img(data);
|
||||
video_copy_background();
|
||||
g_sys.update_screen(g_res.vga, 0);
|
||||
g_sys.set_screen_palette(data + 32000, 0, 16, 6);
|
||||
g_sys.copy_bitmap(g_res.vga, GAME_SCREEN_W, GAME_SCREEN_H);
|
||||
g_sys.fade_in_palette();
|
||||
do_demo_animation();
|
||||
g_sys.fade_out_palette();
|
||||
|
|
|
@ -120,7 +120,7 @@ struct vars_t {
|
|||
} random;
|
||||
struct {
|
||||
bool keystate[128];
|
||||
uint8_t key_left, key_right, key_down, key_up, key_space;
|
||||
uint8_t key_left, key_right, key_down, key_up, key_space, key_jump;
|
||||
uint8_t key_vdir, key_hdir;
|
||||
uint16_t demo_offset;
|
||||
uint8_t demo_mask, demo_counter;
|
||||
|
|
|
@ -2446,7 +2446,7 @@ static void level_update_player() {
|
|||
mask <<= 1;
|
||||
mask |= g_vars.input.key_left & 1;
|
||||
mask <<= 1;
|
||||
mask |= g_vars.input.key_up & 1;
|
||||
mask |= (g_options.jump_button ? g_vars.input.key_jump : g_vars.input.key_up) & 1;
|
||||
mask <<= 1;
|
||||
mask |= g_vars.input.key_down & 1;
|
||||
mask <<= 1;
|
||||
|
@ -2664,7 +2664,7 @@ static void level_update_player_collision() {
|
|||
level_add_object75_score(obj_player, (int16_t)data[num >> 1]);
|
||||
}
|
||||
}
|
||||
g_vars.objects_tbl[1].data.p.y_velocity = (g_vars.input.key_up != 0) ? -224 : -64;
|
||||
g_vars.objects_tbl[1].data.p.y_velocity = (g_options.jump_button ? g_vars.input.key_jump : g_vars.input.key_up) ? -224 : -64;
|
||||
g_vars.player_jumping_counter = 0;
|
||||
g_vars.objects_tbl[1].y_pos -= g_vars.monster.collide_y_dist;
|
||||
} else if (g_vars.objects_tbl[1].data.p.y_velocity <= 32) {
|
||||
|
@ -3269,7 +3269,8 @@ static void level_update_light_palette() {
|
|||
|
||||
static void level_sync() {
|
||||
update_input();
|
||||
g_sys.update_screen(g_res.vga, 1);
|
||||
g_sys.copy_bitmap(g_res.vga, GAME_SCREEN_W, GAME_SCREEN_H);
|
||||
g_sys.update_screen();
|
||||
g_sys.render_clear_sprites();
|
||||
const int diff = (g_vars.timestamp + (1000 / 30)) - g_sys.get_timestamp();
|
||||
g_sys.sleep(MAX(diff, 10));
|
||||
|
|
|
@ -61,9 +61,7 @@ static void convert_planar_tile_4bpp(const uint8_t *src, uint8_t *dst, int dst_p
|
|||
|
||||
void video_draw_string(int offset, int hspace, const char *s) {
|
||||
offset += hspace;
|
||||
const int y = (offset * 8) / 320 + (GAME_SCREEN_H - 200) / 2;
|
||||
const int x = (offset * 8) % 320 + (GAME_SCREEN_W - 320) / 2;
|
||||
uint8_t *dst = g_res.vga + y * GAME_SCREEN_W + x;
|
||||
uint8_t *dst = g_res.vga + offset * 8;
|
||||
while (*s) {
|
||||
uint8_t code = *s++;
|
||||
if (code != 0x20) {
|
||||
|
@ -71,7 +69,7 @@ void video_draw_string(int offset, int hspace, const char *s) {
|
|||
if (code > 9) {
|
||||
code -= 2;
|
||||
}
|
||||
decode_planar(g_res.allfonts + code * 48, dst, GAME_SCREEN_W, 8, 12, 0);
|
||||
decode_planar(g_res.allfonts + code * 48, dst, 320, 8, 12, 0);
|
||||
}
|
||||
dst += 8;
|
||||
}
|
||||
|
|
8
sys.h
8
sys.h
|
@ -14,11 +14,13 @@
|
|||
#define RENDER_SPR_GAME 0 /* player sprites */
|
||||
#define RENDER_SPR_LEVEL 1 /* level sprites */
|
||||
#define RENDER_SPR_FG 2 /* foreground tiles */
|
||||
#define RENDER_SPR_COUNT 3
|
||||
|
||||
struct input_t {
|
||||
uint8_t direction;
|
||||
bool quit;
|
||||
bool space;
|
||||
bool jump;
|
||||
bool digit1, digit2, digit3;
|
||||
};
|
||||
|
||||
|
@ -36,7 +38,7 @@ enum sys_transition_e {
|
|||
|
||||
struct sys_t {
|
||||
struct input_t input;
|
||||
int (*init)();
|
||||
void (*init)();
|
||||
void (*fini)();
|
||||
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 offset, int count, int depth);
|
||||
|
@ -45,7 +47,8 @@ struct sys_t {
|
|||
void (*set_palette_color)(int i, const uint8_t *colors);
|
||||
void (*fade_in_palette)();
|
||||
void (*fade_out_palette)();
|
||||
void (*update_screen)(const uint8_t *p, int present);
|
||||
void (*copy_bitmap)(const uint8_t *p, int w, int h);
|
||||
void (*update_screen)();
|
||||
void (*shake_screen)(int dx, int dy);
|
||||
void (*transition_screen)(enum sys_transition_e type, bool open);
|
||||
void (*process_events)();
|
||||
|
@ -60,6 +63,7 @@ struct sys_t {
|
|||
void (*render_add_sprite)(int spr_type, int frame, int x, int y, int xflip);
|
||||
void (*render_clear_sprites)();
|
||||
void (*render_set_sprites_clipping_rect)(int x, int y, int w, int h);
|
||||
void (*print_log)(FILE *fp, const char *s);
|
||||
};
|
||||
|
||||
extern struct sys_t g_sys;
|
||||
|
|
|
@ -0,0 +1,428 @@
|
|||
|
||||
#include <pspaudio.h>
|
||||
#include <pspaudiolib.h>
|
||||
#include <pspctrl.h>
|
||||
#include <pspdisplay.h>
|
||||
#include <pspgu.h>
|
||||
#include <pspkernel.h>
|
||||
#include <pspsdk.h>
|
||||
#include <malloc.h>
|
||||
#include "sys.h"
|
||||
|
||||
PSP_MODULE_INFO("Blues Brothers", 0, 1, 0);
|
||||
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
|
||||
|
||||
static uint32_t _buttons;
|
||||
|
||||
static sys_audio_cb _audio_proc;
|
||||
static void *_audio_param;
|
||||
static int _audio_channel;
|
||||
static SceUID _audio_mutex;
|
||||
|
||||
static uint32_t _fb_offset;
|
||||
|
||||
// static const int AUDIO_FREQ = 44100;
|
||||
static const int AUDIO_SAMPLES_COUNT = 2048;
|
||||
|
||||
static const int SCREEN_W = 480;
|
||||
static const int SCREEN_H = 272;
|
||||
static const int SCREEN_PITCH = 512;
|
||||
|
||||
static uint32_t __attribute__((aligned(16))) _dlist[262144];
|
||||
static uint32_t __attribute__((aligned(16))) _clut[256];
|
||||
|
||||
#define MAX_SPRITES 256
|
||||
|
||||
struct vertex_t {
|
||||
int16_t u, v;
|
||||
int16_t x, y, z;
|
||||
};
|
||||
|
||||
struct spritetexture_t {
|
||||
int w, h;
|
||||
uint8_t *bitmap;
|
||||
int count;
|
||||
struct sys_rect_t *r;
|
||||
};
|
||||
|
||||
static struct spritetexture_t _spritetextures[RENDER_SPR_COUNT];
|
||||
|
||||
struct sprite_t {
|
||||
struct vertex_t v[2];
|
||||
int tex;
|
||||
};
|
||||
|
||||
static struct sprite_t _sprites[MAX_SPRITES];
|
||||
static int _sprites_count;
|
||||
|
||||
static void print_log(FILE *fp, const char *s) {
|
||||
static bool first_open = false;
|
||||
if (!first_open) {
|
||||
fp = fopen("stdout.txt", "w");
|
||||
first_open = true;
|
||||
} else {
|
||||
fp = fopen("stdout.txt", "a");
|
||||
}
|
||||
fprintf(fp, "%s\n", s);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static int exit_callback(int arg1, int arg2, void *common) {
|
||||
g_sys.input.quit = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int callback_thread(SceSize args, void *argp) {
|
||||
const int cb = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
|
||||
sceKernelRegisterExitCallback(cb);
|
||||
sceKernelSleepThreadCB();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void psp_init() {
|
||||
_buttons = 0;
|
||||
|
||||
memset(&_audio_proc, 0, sizeof(_audio_proc));
|
||||
_audio_channel = -1;
|
||||
_audio_mutex = 0;
|
||||
|
||||
const int th = sceKernelCreateThread("update_thread", callback_thread, 0x11, 0xFA0, 0, 0);
|
||||
if (th >= 0) {
|
||||
sceKernelStartThread(th, 0, 0);
|
||||
}
|
||||
|
||||
sceKernelDcacheWritebackAll();
|
||||
|
||||
sceCtrlSetSamplingCycle(0);
|
||||
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
|
||||
}
|
||||
|
||||
static void psp_fini() {
|
||||
sceGuTerm();
|
||||
sceKernelExitGame();
|
||||
}
|
||||
|
||||
static void psp_set_screen_size(int w, int h, const char *caption, int scale, const char *filter, bool fullscreen) {
|
||||
sceGuInit();
|
||||
sceGuStart(GU_DIRECT, _dlist);
|
||||
|
||||
const int fbSize = SCREEN_PITCH * SCREEN_H * sizeof(uint32_t); // rgba
|
||||
uint32_t vramOffset = 0;
|
||||
sceGuDrawBuffer(GU_PSM_8888, (void *)vramOffset, SCREEN_PITCH); vramOffset += fbSize;
|
||||
sceGuDispBuffer(SCREEN_W, SCREEN_H, (void *)vramOffset, SCREEN_PITCH); vramOffset += fbSize;
|
||||
|
||||
sceGuOffset(2048 - (SCREEN_W / 2), 2048 - (SCREEN_H / 2));
|
||||
sceGuViewport(2048, 2048, SCREEN_W, SCREEN_H);
|
||||
sceGuScissor(0, 0, SCREEN_W, SCREEN_H);
|
||||
sceGuEnable(GU_SCISSOR_TEST);
|
||||
sceGuEnable(GU_TEXTURE_2D);
|
||||
sceGuDisable(GU_DEPTH_TEST);
|
||||
|
||||
sceGuClearColor(0);
|
||||
sceGuClear(GU_COLOR_BUFFER_BIT);
|
||||
|
||||
sceGuFinish();
|
||||
sceGuSync(GU_SYNC_WHAT_DONE, GU_SYNC_FINISH);
|
||||
|
||||
sceDisplayWaitVblankStart();
|
||||
_fb_offset = (uint32_t)sceGuSwapBuffers();
|
||||
sceGuDisplay(GU_TRUE);
|
||||
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
_clut[i] = GU_RGBA(0, 0, 0, 255);
|
||||
}
|
||||
sceKernelDcacheWritebackRange(_clut, sizeof(_clut));
|
||||
}
|
||||
|
||||
static void psp_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) {
|
||||
int r = *colors++;
|
||||
int g = *colors++;
|
||||
int b = *colors++;
|
||||
if (shift != 0) {
|
||||
r = (r << shift) | (r >> (depth - shift));
|
||||
g = (g << shift) | (g >> (depth - shift));
|
||||
b = (b << shift) | (b >> (depth - shift));
|
||||
}
|
||||
_clut[offset + i] = GU_RGBA(r, g, b, 255);
|
||||
}
|
||||
sceKernelDcacheWritebackRange(_clut, sizeof(_clut));
|
||||
}
|
||||
|
||||
static uint32_t convert_amiga_color(uint16_t color) {
|
||||
uint8_t r = (color >> 8) & 15;
|
||||
r |= r << 4;
|
||||
uint8_t g = (color >> 4) & 15;
|
||||
g |= g << 4;
|
||||
uint8_t b = color & 15;
|
||||
b |= b << 4;
|
||||
return GU_RGBA(r, g, b, 255);
|
||||
}
|
||||
|
||||
static void psp_set_palette_amiga(const uint16_t *colors, int offset) {
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
_clut[offset + i] = convert_amiga_color(colors[i]);
|
||||
}
|
||||
sceKernelDcacheWritebackRange(_clut, sizeof(_clut));
|
||||
}
|
||||
|
||||
static void psp_set_copper_bars(const uint16_t *data) {
|
||||
}
|
||||
|
||||
static void psp_set_palette_color(int i, const uint8_t *colors) {
|
||||
_clut[i] = GU_RGBA(colors[0], colors[1], colors[2], 255);
|
||||
sceKernelDcacheWritebackRange(_clut, sizeof(_clut));
|
||||
}
|
||||
|
||||
static void psp_fade_in_palette() {
|
||||
sceDisplayWaitVblankStart();
|
||||
_fb_offset = (uint32_t)sceGuSwapBuffers();
|
||||
}
|
||||
|
||||
static void psp_fade_out_palette() {
|
||||
uint32_t *buffer = (uint32_t *)(((uint8_t *)sceGeEdramGetAddr()) + _fb_offset);
|
||||
for (int y = 0; y < SCREEN_H; ++y) {
|
||||
memset(buffer, 0, SCREEN_W * sizeof(uint32_t));
|
||||
buffer += SCREEN_PITCH;
|
||||
}
|
||||
}
|
||||
|
||||
static void psp_transition_screen(enum sys_transition_e type, bool open) {
|
||||
}
|
||||
|
||||
static void psp_copy_bitmap(const uint8_t *p, int w, int h) {
|
||||
const int dx = (SCREEN_W - w) / 2;
|
||||
const int dy = (SCREEN_H - h) / 2;
|
||||
uint32_t *buffer = (uint32_t *)(((uint8_t *)sceGeEdramGetAddr()) + _fb_offset);
|
||||
for (int y = 0; y < h; ++y) {
|
||||
for (int x = 0; x < w; ++x) {
|
||||
buffer[(dy + y) * SCREEN_PITCH + (dx + x)] = _clut[*p++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void psp_update_screen() {
|
||||
sceGuStart(GU_DIRECT, _dlist);
|
||||
|
||||
sceGuClutMode(GU_PSM_8888, 0, 0xFF, 0);
|
||||
sceGuClutLoad(256 / 8, _clut);
|
||||
sceGuTexMode(GU_PSM_T8, 0, 0, 0);
|
||||
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
|
||||
sceGuTexFilter(GU_NEAREST, GU_NEAREST);
|
||||
|
||||
sceGuEnable(GU_COLOR_TEST);
|
||||
sceGuColorFunc(GU_NOTEQUAL, _clut[0], 0xFFFFFF);
|
||||
|
||||
int prev_tex = -1;
|
||||
|
||||
for (int i = 0; i < _sprites_count; ++i) {
|
||||
struct sprite_t *spr = &_sprites[i];
|
||||
|
||||
if (prev_tex != spr->tex) {
|
||||
struct spritetexture_t *st = &_spritetextures[spr->tex];
|
||||
sceGuTexImage(0, st->w, st->h, st->w, st->bitmap);
|
||||
prev_tex = spr->tex;
|
||||
}
|
||||
|
||||
struct vertex_t *v = (struct vertex_t *)sceGuGetMemory(2 * sizeof(struct vertex_t));
|
||||
v[0] = spr->v[0];
|
||||
v[1] = spr->v[1];
|
||||
|
||||
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, 0, v);
|
||||
}
|
||||
|
||||
sceGuDisable(GU_COLOR_TEST);
|
||||
|
||||
sceGuFinish();
|
||||
sceGuSync(GU_SYNC_WHAT_DONE, GU_SYNC_FINISH);
|
||||
|
||||
sceDisplayWaitVblankStart();
|
||||
_fb_offset = (uint32_t)sceGuSwapBuffers();
|
||||
}
|
||||
|
||||
static void psp_shake_screen(int dx, int dy) {
|
||||
sceGuOffset(2048 - (SCREEN_W / 2) + dx, 2048 - (SCREEN_H / 2) + dy);
|
||||
}
|
||||
|
||||
static void psp_process_events() {
|
||||
|
||||
g_sys.input.direction = 0;
|
||||
|
||||
static const struct {
|
||||
int psp;
|
||||
int sys;
|
||||
} mapping[] = {
|
||||
{ PSP_CTRL_UP, INPUT_DIRECTION_UP },
|
||||
{ PSP_CTRL_RIGHT, INPUT_DIRECTION_RIGHT },
|
||||
{ PSP_CTRL_DOWN, INPUT_DIRECTION_DOWN },
|
||||
{ PSP_CTRL_LEFT, INPUT_DIRECTION_LEFT },
|
||||
{ 0, 0 }
|
||||
};
|
||||
SceCtrlData data;
|
||||
sceCtrlPeekBufferPositive(&data, 1);
|
||||
for (int i = 0; mapping[i].psp != 0; ++i) {
|
||||
if (data.Buttons & mapping[i].psp) {
|
||||
g_sys.input.direction |= mapping[i].sys;
|
||||
}
|
||||
}
|
||||
static const int lxMargin = 64;
|
||||
if (data.Lx < 127 - lxMargin) {
|
||||
g_sys.input.direction |= INPUT_DIRECTION_LEFT;
|
||||
} else if (data.Lx > 127 + lxMargin) {
|
||||
g_sys.input.direction |= INPUT_DIRECTION_RIGHT;
|
||||
}
|
||||
static const int lyMargin = 64;
|
||||
if (data.Ly < 127 - lyMargin) {
|
||||
g_sys.input.direction |= INPUT_DIRECTION_UP;
|
||||
} else if (data.Ly > 127 + lyMargin) {
|
||||
g_sys.input.direction |= INPUT_DIRECTION_DOWN;
|
||||
}
|
||||
|
||||
// PSP_CTRL_CROSS
|
||||
g_sys.input.space = (data.Buttons & PSP_CTRL_SQUARE) != 0;
|
||||
g_sys.input.jump = (data.Buttons & PSP_CTRL_CIRCLE) != 0;
|
||||
// PSP_CTRL_TRIANGLE
|
||||
|
||||
const uint32_t mask = data.Buttons ^ _buttons;
|
||||
if ((data.Buttons & PSP_CTRL_LTRIGGER) & mask) {
|
||||
}
|
||||
if ((data.Buttons & PSP_CTRL_RTRIGGER) & mask) {
|
||||
}
|
||||
_buttons = data.Buttons;
|
||||
}
|
||||
|
||||
static void psp_sleep(int duration) {
|
||||
sceKernelDelayThread(duration * 1000);
|
||||
}
|
||||
|
||||
static uint32_t psp_get_timestamp() {
|
||||
struct timeval tv;
|
||||
sceKernelLibcGettimeofday(&tv, 0);
|
||||
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
}
|
||||
|
||||
static void psp_lock_audio() {
|
||||
sceKernelWaitSema(_audio_mutex, 1, 0);
|
||||
}
|
||||
|
||||
static void psp_unlock_audio() {
|
||||
sceKernelSignalSema(_audio_mutex, 1);
|
||||
}
|
||||
|
||||
static void audio_callback(void *buf, unsigned int samples, void *param) { // 44100hz S16 stereo
|
||||
int16_t buf22khz[samples];
|
||||
memset(buf22khz, 0, sizeof(buf22khz));
|
||||
psp_lock_audio();
|
||||
_audio_proc(_audio_param, (uint8_t *)buf22khz, samples);
|
||||
psp_unlock_audio();
|
||||
uint32_t *buf44khz = (uint32_t *)buf;
|
||||
static int16_t prev;
|
||||
for (unsigned int i = 0; i < samples; ++i) {
|
||||
const int16_t current = buf22khz[i];
|
||||
buf44khz[i] = (current << 16) | (((prev + current) >> 1) & 0xFFFF);
|
||||
prev = current;
|
||||
}
|
||||
}
|
||||
|
||||
static void psp_start_audio(sys_audio_cb callback, void *param) {
|
||||
// sceAudioSetFrequency(AUDIO_FREQ);
|
||||
pspAudioInit();
|
||||
_audio_proc = callback;
|
||||
_audio_param = param;
|
||||
_audio_mutex = sceKernelCreateSema("audio_lock", 0, 1, 1, 0);
|
||||
_audio_channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, AUDIO_SAMPLES_COUNT, PSP_AUDIO_FORMAT_STEREO);
|
||||
pspAudioSetChannelCallback(_audio_channel, audio_callback, 0);
|
||||
}
|
||||
|
||||
static void psp_stop_audio() {
|
||||
sceAudioChRelease(_audio_channel);
|
||||
sceKernelDeleteSema(_audio_mutex);
|
||||
pspAudioEnd();
|
||||
}
|
||||
|
||||
static void render_load_sprites(int spr_type, int count, const struct sys_rect_t *r, const uint8_t *data, int w, int h, uint8_t color_key, bool update_pal) {
|
||||
struct spritetexture_t *st = &_spritetextures[spr_type];
|
||||
st->r = (struct sys_rect_t *)malloc(count * sizeof(struct sys_rect_t));
|
||||
if (st->r) {
|
||||
memcpy(st->r, r, count * sizeof(struct sys_rect_t));
|
||||
st->count = count;
|
||||
}
|
||||
st->bitmap = (uint8_t *)memalign(16, w * h);
|
||||
if (st->bitmap) {
|
||||
memcpy(st->bitmap, data, w * h);
|
||||
st->w = w;
|
||||
st->h = h;
|
||||
sceKernelDcacheWritebackRange(st->bitmap, w * h);
|
||||
}
|
||||
}
|
||||
|
||||
static void render_unload_sprites(int spr_type) {
|
||||
struct spritetexture_t *st = &_spritetextures[spr_type];
|
||||
if (st->r) {
|
||||
free(st->r);
|
||||
}
|
||||
if (st->bitmap) {
|
||||
free(st->bitmap);
|
||||
}
|
||||
memset(st, 0, sizeof(struct spritetexture_t));
|
||||
}
|
||||
|
||||
static void render_add_sprite(int spr_type, int frame, int x, int y, int xflip) {
|
||||
if (_sprites_count < MAX_SPRITES) {
|
||||
struct sprite_t *spr = &_sprites[_sprites_count];
|
||||
struct vertex_t *v = spr->v;
|
||||
|
||||
struct sys_rect_t *r = &_spritetextures[spr_type].r[frame];
|
||||
if (!xflip) {
|
||||
v[0].u = r->x; v[1].u = r->x + r->w;
|
||||
} else {
|
||||
v[0].u = r->x + r->w; v[1].u = r->x;
|
||||
}
|
||||
v[0].v = r->y; v[1].v = r->y + r->h;
|
||||
v[0].x = x; v[1].x = x + r->w;
|
||||
v[0].y = y; v[1].y = y + r->h;
|
||||
v[0].z = 0; v[1].z = 0;
|
||||
|
||||
spr->tex = spr_type;
|
||||
|
||||
++_sprites_count;
|
||||
}
|
||||
}
|
||||
|
||||
static void render_clear_sprites() {
|
||||
_sprites_count = 0;
|
||||
}
|
||||
|
||||
static void render_set_sprites_clipping_rect(int x, int y, int w, int h) {
|
||||
sceGuScissor(x, y, w, h);
|
||||
}
|
||||
|
||||
struct sys_t g_sys = {
|
||||
.init = psp_init,
|
||||
.fini = psp_fini,
|
||||
.set_screen_size = psp_set_screen_size,
|
||||
.set_screen_palette = psp_set_screen_palette,
|
||||
.set_palette_amiga = psp_set_palette_amiga,
|
||||
.set_copper_bars = psp_set_copper_bars,
|
||||
.set_palette_color = psp_set_palette_color,
|
||||
.fade_in_palette = psp_fade_in_palette,
|
||||
.fade_out_palette = psp_fade_out_palette,
|
||||
.copy_bitmap = psp_copy_bitmap,
|
||||
.update_screen = psp_update_screen,
|
||||
.shake_screen = psp_shake_screen,
|
||||
.transition_screen = psp_transition_screen,
|
||||
.process_events = psp_process_events,
|
||||
.sleep = psp_sleep,
|
||||
.get_timestamp = psp_get_timestamp,
|
||||
.start_audio = psp_start_audio,
|
||||
.stop_audio = psp_stop_audio,
|
||||
.lock_audio = psp_lock_audio,
|
||||
.unlock_audio = psp_unlock_audio,
|
||||
.render_load_sprites = render_load_sprites,
|
||||
.render_unload_sprites = render_unload_sprites,
|
||||
.render_add_sprite = render_add_sprite,
|
||||
.render_clear_sprites = render_clear_sprites,
|
||||
.render_set_sprites_clipping_rect = render_set_sprites_clipping_rect,
|
||||
.print_log = print_log,
|
||||
};
|
115
sys_sdl2.c
115
sys_sdl2.c
|
@ -5,7 +5,6 @@
|
|||
|
||||
#define COPPER_BARS_H 80
|
||||
#define MAX_SPRITES 256
|
||||
#define MAX_SPRITESHEETS 3
|
||||
|
||||
static const int FADE_STEPS = 16;
|
||||
|
||||
|
@ -16,7 +15,7 @@ struct spritesheet_t {
|
|||
SDL_Texture *texture;
|
||||
};
|
||||
|
||||
static struct spritesheet_t _spritesheets[MAX_SPRITESHEETS];
|
||||
static struct spritesheet_t _spritesheets[RENDER_SPR_COUNT];
|
||||
|
||||
struct sprite_t {
|
||||
int sheet;
|
||||
|
@ -44,7 +43,7 @@ static uint32_t _copper_palette[COPPER_BARS_H];
|
|||
static SDL_GameController *_controller;
|
||||
static SDL_Joystick *_joystick;
|
||||
|
||||
static int sdl2_init() {
|
||||
static void sdl2_init() {
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
_screen_w = _screen_h = 0;
|
||||
|
@ -72,7 +71,6 @@ static int sdl2_init() {
|
|||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sdl2_fini() {
|
||||
|
@ -188,9 +186,9 @@ static void sdl2_set_screen_palette(const uint8_t *colors, int offset, int count
|
|||
SDL_Color *palette_colors = &_palette->colors[offset];
|
||||
const int shift = 8 - depth;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int r = colors[0];
|
||||
int g = colors[1];
|
||||
int b = colors[2];
|
||||
int r = *colors++;
|
||||
int g = *colors++;
|
||||
int b = *colors++;
|
||||
if (depth != 8) {
|
||||
r = (r << shift) | (r >> (depth - shift));
|
||||
g = (g << shift) | (g >> (depth - shift));
|
||||
|
@ -200,7 +198,6 @@ static void sdl2_set_screen_palette(const uint8_t *colors, int offset, int count
|
|||
palette_colors[i].r = r;
|
||||
palette_colors[i].g = g;
|
||||
palette_colors[i].b = b;
|
||||
colors += 3;
|
||||
}
|
||||
for (int i = 0; i < ARRAYSIZE(_spritesheets); ++i) {
|
||||
struct spritesheet_t *sheet = &_spritesheets[i];
|
||||
|
@ -286,11 +283,21 @@ static void sdl2_transition_screen(enum sys_transition_e type, bool open) {
|
|||
} while (r.x > 0 && (type == TRANSITION_CURTAIN || r.y > 0));
|
||||
}
|
||||
|
||||
static void sdl2_update_screen(const uint8_t *p, int present) {
|
||||
if (_copper_color_key != -1) {
|
||||
static void sdl2_copy_bitmap(const uint8_t *p, int w, int h) {
|
||||
if (w != _screen_w || h != _screen_h) {
|
||||
memset(_screen_buffer, 0, _screen_w * _screen_h * sizeof(uint32_t));
|
||||
const int offset_x = (_screen_w - w) / 2;
|
||||
const int offset_y = (_screen_h - h) / 2;
|
||||
for (int j = 0; j < h; ++j) {
|
||||
for (int i = 0; i < w; ++i) {
|
||||
_screen_buffer[(offset_y + j) * _screen_w + (offset_x + i)] = _screen_palette[*p++];
|
||||
}
|
||||
}
|
||||
} else if (_copper_color_key != -1) {
|
||||
for (int j = 0; j < _screen_h; ++j) {
|
||||
if (j / 2 < COPPER_BARS_H) {
|
||||
const uint32_t line_color = _copper_palette[j / 2];
|
||||
const int color = (j * 200 / _screen_h) / 2;
|
||||
if (color < COPPER_BARS_H) {
|
||||
const uint32_t line_color = _copper_palette[color];
|
||||
for (int i = 0; i < _screen_w; ++i) {
|
||||
_screen_buffer[j * _screen_w + i] = (p[i] == _copper_color_key) ? line_color : _screen_palette[p[i]];
|
||||
}
|
||||
|
@ -307,38 +314,39 @@ static void sdl2_update_screen(const uint8_t *p, int present) {
|
|||
}
|
||||
}
|
||||
SDL_UpdateTexture(_texture, 0, _screen_buffer, _screen_w * sizeof(uint32_t));
|
||||
if (present) {
|
||||
SDL_Rect r;
|
||||
r.x = _shake_dx;
|
||||
r.y = _shake_dy;
|
||||
r.w = _screen_w;
|
||||
r.h = _screen_h;
|
||||
SDL_RenderClear(_renderer);
|
||||
SDL_RenderCopy(_renderer, _texture, 0, &r);
|
||||
}
|
||||
|
||||
// sprites
|
||||
SDL_RenderSetClipRect(_renderer, &_sprites_cliprect);
|
||||
for (int i = 0; i < _sprites_count; ++i) {
|
||||
const struct sprite_t *spr = &_sprites[i];
|
||||
struct spritesheet_t *sheet = &_spritesheets[spr->sheet];
|
||||
if (spr->num >= sheet->count) {
|
||||
continue;
|
||||
}
|
||||
SDL_Rect r;
|
||||
r.x = spr->x + _shake_dx;
|
||||
r.y = spr->y + _shake_dy;
|
||||
r.w = sheet->r[spr->num].w;
|
||||
r.h = sheet->r[spr->num].h;
|
||||
if (!spr->xflip) {
|
||||
SDL_RenderCopy(_renderer, sheet->texture, &sheet->r[spr->num], &r);
|
||||
} else {
|
||||
SDL_RenderCopyEx(_renderer, sheet->texture, &sheet->r[spr->num], &r, 0., 0, SDL_FLIP_HORIZONTAL);
|
||||
}
|
||||
static void sdl2_update_screen() {
|
||||
SDL_Rect r;
|
||||
r.x = _shake_dx;
|
||||
r.y = _shake_dy;
|
||||
r.w = _screen_w;
|
||||
r.h = _screen_h;
|
||||
SDL_RenderClear(_renderer);
|
||||
SDL_RenderCopy(_renderer, _texture, 0, &r);
|
||||
|
||||
// sprites
|
||||
SDL_RenderSetClipRect(_renderer, &_sprites_cliprect);
|
||||
for (int i = 0; i < _sprites_count; ++i) {
|
||||
const struct sprite_t *spr = &_sprites[i];
|
||||
struct spritesheet_t *sheet = &_spritesheets[spr->sheet];
|
||||
if (spr->num >= sheet->count) {
|
||||
continue;
|
||||
}
|
||||
SDL_Rect r;
|
||||
r.x = spr->x + _shake_dx;
|
||||
r.y = spr->y + _shake_dy;
|
||||
r.w = sheet->r[spr->num].w;
|
||||
r.h = sheet->r[spr->num].h;
|
||||
if (!spr->xflip) {
|
||||
SDL_RenderCopy(_renderer, sheet->texture, &sheet->r[spr->num], &r);
|
||||
} else {
|
||||
SDL_RenderCopyEx(_renderer, sheet->texture, &sheet->r[spr->num], &r, 0., 0, SDL_FLIP_HORIZONTAL);
|
||||
}
|
||||
SDL_RenderSetClipRect(_renderer, 0);
|
||||
|
||||
SDL_RenderPresent(_renderer);
|
||||
}
|
||||
SDL_RenderSetClipRect(_renderer, 0);
|
||||
|
||||
SDL_RenderPresent(_renderer);
|
||||
}
|
||||
|
||||
static void sdl2_shake_screen(int dx, int dy) {
|
||||
|
@ -380,6 +388,10 @@ static void handle_keyevent(int keysym, bool keydown, struct input_t *input, boo
|
|||
case SDLK_SPACE:
|
||||
input->space = keydown;
|
||||
break;
|
||||
case SDLK_LSHIFT:
|
||||
case SDLK_RSHIFT:
|
||||
input->jump = keydown;
|
||||
break;
|
||||
case SDLK_ESCAPE:
|
||||
if (keydown) {
|
||||
g_sys.input.quit = true;
|
||||
|
@ -437,13 +449,10 @@ static void handle_controlleraxis(int axis, int value, struct input_t *input) {
|
|||
static void handle_controllerbutton(int button, bool pressed, struct input_t *input, bool *paused) {
|
||||
switch (button) {
|
||||
case SDL_CONTROLLER_BUTTON_A:
|
||||
case SDL_CONTROLLER_BUTTON_B:
|
||||
case SDL_CONTROLLER_BUTTON_X:
|
||||
case SDL_CONTROLLER_BUTTON_Y:
|
||||
input->space = pressed;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_BACK:
|
||||
g_sys.input.quit = true;
|
||||
case SDL_CONTROLLER_BUTTON_B:
|
||||
input->jump = pressed;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_START:
|
||||
if (!pressed) {
|
||||
|
@ -520,8 +529,13 @@ static void handle_joystickaxismotion(int axis, int value, struct input_t *input
|
|||
}
|
||||
|
||||
static void handle_joystickbutton(int button, int pressed, struct input_t *input) {
|
||||
if (button == 0) {
|
||||
switch (button) {
|
||||
case 0:
|
||||
input->space = pressed;
|
||||
break;
|
||||
case 1:
|
||||
input->jump = pressed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -717,6 +731,9 @@ static void render_set_sprites_clipping_rect(int x, int y, int w, int h) {
|
|||
_sprites_cliprect.h = h;
|
||||
}
|
||||
|
||||
static void print_log(FILE *fp, const char *s) {
|
||||
}
|
||||
|
||||
struct sys_t g_sys = {
|
||||
.init = sdl2_init,
|
||||
.fini = sdl2_fini,
|
||||
|
@ -727,6 +744,7 @@ struct sys_t g_sys = {
|
|||
.set_palette_color = sdl2_set_palette_color,
|
||||
.fade_in_palette = sdl2_fade_in_palette,
|
||||
.fade_out_palette = sdl2_fade_out_palette,
|
||||
.copy_bitmap = sdl2_copy_bitmap,
|
||||
.update_screen = sdl2_update_screen,
|
||||
.shake_screen = sdl2_shake_screen,
|
||||
.transition_screen = sdl2_transition_screen,
|
||||
|
@ -741,5 +759,6 @@ struct sys_t g_sys = {
|
|||
.render_unload_sprites = render_unload_sprites,
|
||||
.render_add_sprite = render_add_sprite,
|
||||
.render_clear_sprites = render_clear_sprites,
|
||||
.render_set_sprites_clipping_rect = render_set_sprites_clipping_rect
|
||||
.render_set_sprites_clipping_rect = render_set_sprites_clipping_rect,
|
||||
.print_log = print_log,
|
||||
};
|
||||
|
|
8
util.c
8
util.c
|
@ -1,6 +1,8 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/unistd.h>
|
||||
#include "sys.h"
|
||||
#include "util.h"
|
||||
|
||||
int g_debug_mask = 0;
|
||||
|
@ -21,6 +23,7 @@ void string_upper(char *p) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void print_debug(int debug_channel, const char *msg, ...) {
|
||||
if (g_debug_mask & debug_channel) {
|
||||
char buf[256];
|
||||
|
@ -29,8 +32,10 @@ void print_debug(int debug_channel, const char *msg, ...) {
|
|||
vsprintf(buf, msg, va);
|
||||
va_end(va);
|
||||
fprintf(stdout, "%s\n", buf);
|
||||
g_sys.print_log(stdout, buf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void print_warning(const char *msg, ...) {
|
||||
char buf[256];
|
||||
|
@ -39,6 +44,7 @@ void print_warning(const char *msg, ...) {
|
|||
vsprintf(buf, msg, va);
|
||||
va_end(va);
|
||||
fprintf(stderr, "WARNING: %s\n", buf);
|
||||
g_sys.print_log(stderr, buf);
|
||||
}
|
||||
|
||||
void print_error(const char *msg, ...) {
|
||||
|
@ -48,6 +54,7 @@ void print_error(const char *msg, ...) {
|
|||
vsprintf(buf, msg, va);
|
||||
va_end(va);
|
||||
fprintf(stderr, "ERROR: %s!\n", buf);
|
||||
g_sys.print_log(stderr, buf);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
@ -58,6 +65,7 @@ void print_info(const char *msg, ...) {
|
|||
vsprintf(buf, msg, va);
|
||||
va_end(va);
|
||||
fprintf(stdout, "%s\n", buf);
|
||||
g_sys.print_log(stdout, buf);
|
||||
}
|
||||
|
||||
FILE *fopen_nocase(const char *path, const char *filename) {
|
||||
|
|
4
util.h
4
util.h
|
@ -22,6 +22,10 @@ extern void print_warning(const char *msg, ...);
|
|||
extern void print_error(const char *msg, ...);
|
||||
extern void print_info(const char *msg, ...);
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define print_debug(x, ...)
|
||||
#endif
|
||||
|
||||
extern FILE * fopen_nocase(const char *path, const char *filename);
|
||||
extern uint16_t fread_le16(FILE *fp);
|
||||
|
||||
|
|
Loading…
Reference in New Issue