#include "decode.h" #include "game.h" #include "resource.h" #include "sys.h" #include "util.h" #define MAX_SPRITESHEET_W 1024 #define MAX_SPRITESHEET_H 512 void screen_init() { } void screen_clear_sprites() { render_clear_sprites(); } static void add_game_sprite(int x, int y, int frame, int xflip) { const uint8_t *p = g_res.spr_frames[frame]; const int h = READ_LE_UINT16(p - 4); const int w = READ_LE_UINT16(p - 2); int spr_type = RENDER_SPR_GAME; if (frame >= SPRITES_COUNT) { spr_type = RENDER_SPR_LEVEL; frame -= SPRITES_COUNT; } render_add_sprite(spr_type, frame, x - w / 2, y - h, xflip); } void screen_add_sprite(int x, int y, int frame) { add_game_sprite(x, y, frame, 0); } void screen_clear_last_sprite() { } void screen_redraw_sprites() { } void fade_in_palette() { g_sys.fade_in_palette(); } void fade_out_palette() { // g_sys.fade_out_palette(); } void screen_adjust_palette_color(int color, int b, int c) { g_res.palette[color * 3 + b] += c; screen_vsync(); g_sys.set_screen_palette(g_res.palette, 16); } void screen_vsync() { } void screen_draw_frame(const uint8_t *frame, int a, int b, int c, int d) { const int h = READ_LE_UINT16(frame - 4); assert(a <= h); const int w = READ_LE_UINT16(frame - 2); assert(b <= w); const int x = c; const int y = d + a + 2; decode_ega_spr(frame, w, b, h, g_res.vga, GAME_SCREEN_W, x, y); } void screen_flip() { g_sys.update_screen(g_res.vga, 1); } void screen_unk4() { memcpy(g_res.vga, g_res.tmp + 32000, 64000); } void screen_unk5() { screen_clear(0); screen_do_transition2(); screen_clear(0); } void screen_unk6() { // g_vars.screen_draw_offset -= 12; // screen_do_transition2(); // g_vars.screen_draw_offset += 12; g_sys.update_screen(g_res.vga, 1); memset(g_res.vga, 0, GAME_SCREEN_W * GAME_SCREEN_H); } void screen_copy_tilemap2(int a, int b, int c, int d) { } void screen_copy_tilemap(int a) { } static void screen_unk13(int a) { } void screen_do_transition1(int a) { int i, count, increment; if (a != 0) { i = 11; count = 0; increment = -1; } else { screen_clear(0); i = 0; count = 11; increment = 1; } while (i != count) { screen_unk13(i); screen_unk13(19 - i); screen_vsync(); i += increment; } } void screen_clear(int a) { memset(g_res.vga, 0, GAME_SCREEN_W * GAME_SCREEN_H); } void screen_draw_tile(int tile, int dst, int type) { int y = (dst / 640) * 16 + TILEMAP_OFFSET_Y; int x = (dst % 640) / 2 * 16; const uint8_t *src = g_res.tiles + tile * 16; if (type == 4) { src += 320; } for (int i = 0; i < 16; ++i) { memcpy(g_res.vga + (y + i) * GAME_SCREEN_W + x, src, 16); src += 640; } } void screen_do_transition2() { print_warning("screen_do_transition2"); } void screen_draw_number(int num, int x, int y, int color) { extern const uint8_t font_data[]; y += TILEMAP_OFFSET_Y; decode_ega_spr(font_data + (num / 10) * 32, 8, 8, 8, g_res.vga, GAME_SCREEN_W, x - 8, y); decode_ega_spr(font_data + (num % 10) * 32, 8, 8, 8, g_res.vga, GAME_SCREEN_W, x, y); } void screen_add_game_sprite1(int x, int y, int frame) { add_game_sprite(x, y + TILEMAP_OFFSET_Y, frame, 0); } void screen_add_game_sprite2(int x, int y, int frame) { add_game_sprite(x, y + TILEMAP_OFFSET_Y, frame, 1); } void screen_add_game_sprite3(int x, int y, int frame, int blinking_counter) { // print_warning("screen_add_game_sprite3"); } void screen_add_game_sprite4(int x, int y, int frame, int blinking_counter) { // print_warning("screen_add_game_sprite4"); } 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]; 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; for (int i = start; i < end; ++i) { const uint8_t *ptr = g_res.spr_frames[i]; const int h = READ_LE_UINT16(ptr - 4); const int w = READ_LE_UINT16(ptr - 2); const int j = i - start; 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; 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); } r[j].x = current_x; 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 { decode_ega_spr(ptr, w, w, h, data, MAX_SPRITESHEET_W, current_x, current_y); } r[j].x = current_x; r[j].y = current_y; current_x += w; if (h > max_h) { max_h = h; } } r[j].w = w; r[j].h = h; } assert(max_w <= MAX_SPRITESHEET_W); assert(current_y + max_h <= MAX_SPRITESHEET_H); render_unload_sprites(spr_type); render_load_sprites(spr_type, end - start, r, data, MAX_SPRITESHEET_W, current_y + max_h); free(data); } } void screen_load_graphics() { if (g_res.spr_count <= SPRITES_COUNT) { decode_graphics(RENDER_SPR_GAME, 0, SPRITES_COUNT); } else { decode_graphics(RENDER_SPR_LEVEL, SPRITES_COUNT, g_res.spr_count); struct sys_rect_t r[MAX_SPR_FRAMES]; static const int FG_TILE_W = 16; static const int FG_TILE_H = 16; uint8_t *data = (uint8_t *)malloc(g_res.avt_count * FG_TILE_W * FG_TILE_H); if (data) { const int pitch = g_res.avt_count * FG_TILE_W; for (int i = 0; i < g_res.avt_count; ++i) { decode_ega_spr(g_res.avt[i], FG_TILE_W, FG_TILE_W, FG_TILE_H, data, pitch, i * FG_TILE_W, 0); r[i].x = i * FG_TILE_W; r[i].y = 0; r[i].w = FG_TILE_W; r[i].h = FG_TILE_H; } render_unload_sprites(RENDER_SPR_FG); render_load_sprites(RENDER_SPR_FG, g_res.avt_count, r, data, g_res.avt_count * FG_TILE_W, FG_TILE_H); free(data); } } }