diff --git a/Makefile b/Makefile index 26b84b1..d393f3d 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,11 @@ -pokegb: pokegb.cc - $(CC) -O2 -Wall -Wno-return-type -Wno-misleading-indentation -Wno-parentheses -o $@ $< -lSDL2 +CXXFLAGS := -Os -s -Wall -Wno-return-type -Wno-misleading-indentation -Wno-parentheses +override CXXFLAGS += $(shell pkg-config sdl2 --cflags) +override LDLIBS += $(shell pkg-config sdl2 --libs) + +all: pokegb deobfuscated rom.sav: empty.sav cp $< $@ clean: - rm -f pokegb rom.sav + $(RM) pokegb rom.sav diff --git a/deobfuscated.cc b/deobfuscated.cc index 3328b26..7cfd654 100644 --- a/deobfuscated.cc +++ b/deobfuscated.cc @@ -1,8 +1,4 @@ -#include -#include -#include -#include -#include +#include "SDL.h" #define OPCREL(_) opcrel = (opcode - _) / 8 @@ -28,27 +24,29 @@ #define OP9_IMM_PTR(_) \ OP8_REL(_) case _ + 70 : operand = opcode & 64 ? mem8(PC++) : tmp8; -uint8_t opcode, opcrel, tmp8, operand, carry, neg, *rom0, *rom1, io[512], +Uint8 opcode, opcrel, tmp8, operand, carry, neg, *rom0, *rom1, io[512], video_ram[8192], work_ram[16384], *extram, *extrambank, reg8[] = {19, 0, 216, 0, 77, 1, 176, 1}, &F = reg8[6], &A = reg8[7], *reg8_group[] = {reg8 + 1, reg8, reg8 + 3, reg8 + 2, reg8 + 5, reg8 + 4, &F, &A}, &IF = io[271], &LCDC = io[320], &LY = io[324], IME, halt; -uint8_t const *key_state; +Uint8 const *key_state; -uint16_t PC = 256, *reg16 = (uint16_t *)reg8, &HL = reg16[2], SP = 65534, - &DIV = (uint16_t &)io[259], ppu_dot = 32, +Uint16 PC = 256, *reg16 = (Uint16 *)reg8, &HL = reg16[2], SP = 65534, + &DIV = (Uint16 &)io[259], ppu_dot = 32, *reg16_group1[] = {reg16, reg16 + 1, &HL, &SP}, *reg16_group2[] = {reg16, reg16 + 1, &HL, &HL}, prev_cycles, cycles; -int tmp, tmp2, F_mask[] = {128, 128, 16, 16}, frame_buffer[23040], +int tmp, delay, F_mask[] = {128, 128, 16, 16}, frame_buffer[23040], palette[] = {-1, -23197, -65536, -1 << 24, -1, -8092417, -12961132, -1 << 24}; +double comp; +Uint64 ot, nt; void tick() { cycles += 4; } -uint8_t mem8(uint16_t addr = HL, uint8_t val = 0, int write = 0) { +Uint8 mem8(Uint16 addr = HL, Uint8 val = 0, int write = 0) { tick(); switch (addr >> 13) { case 1: @@ -110,50 +108,46 @@ uint8_t mem8(uint16_t addr = HL, uint8_t val = 0, int write = 0) { } } -void set_flags(uint8_t mask, int Z, int N, int H, int C) { +void set_flags(Uint8 mask, int Z, int N, int H, int C) { F = F & mask | !Z << 7 | N << 6 | H << 5 | C << 4; } -uint16_t read16(uint16_t &addr = PC) { +Uint16 read16(Uint16 &addr = PC) { tmp8 = mem8(addr++); return mem8(addr++) << 8 | tmp8; } -void push(uint16_t val) { +void push(Uint16 val) { mem8(--SP, val >> 8, 1); mem8(--SP, val, 1); tick(); } -uint8_t reg8_access(uint8_t val, int write = 1, uint8_t o = opcrel) { +Uint8 reg8_access(Uint8 val, int write = 1, Uint8 o = opcrel) { return (o &= 7) == 6 ? mem8(HL, val, write) : write ? *reg8_group[o] = val : *reg8_group[o]; } -uint8_t get_color(int tile, int y_offset, int x_offset) { - uint8_t *tile_data = &video_ram[tile * 16 + y_offset * 2]; +Uint8 get_color(int tile, int y_offset, int x_offset) { + Uint8 *tile_data = &video_ram[tile * 16 + y_offset * 2]; return (tile_data[1] >> x_offset) % 2 * 2 + (*tile_data >> x_offset) % 2; } -int main() { - rom1 = (rom0 = (uint8_t *)mmap(0, 1 << 20, PROT_READ, MAP_SHARED, - open("rom.gb", O_RDONLY), 0)) + - 32768; - tmp = open("rom.sav", O_CREAT|O_RDWR, 0666); - ftruncate(tmp, 32768); - extrambank = extram = - (uint8_t *)mmap(0, 32768, PROT_READ | PROT_WRITE, MAP_SHARED, tmp, 0); +int main(int, char**) { + rom1 = (rom0 = (Uint8 *)SDL_LoadFile("rom.gb", NULL)) + 32768; + extrambank = extram = (Uint8 *)SDL_realloc(SDL_LoadFile("rom.sav", NULL), 32768); LCDC = 145; DIV = 44032; SDL_Init(SDL_INIT_VIDEO); SDL_Renderer *renderer = SDL_CreateRenderer( - SDL_CreateWindow("pokegb", 0, 0, 800, 720, SDL_WINDOW_SHOWN), -1, - SDL_RENDERER_PRESENTVSYNC); + SDL_CreateWindow("pokegb", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + 800, 720, SDL_WINDOW_SHOWN), -1, SDL_RENDERER_PRESENTVSYNC); SDL_Texture *texture = SDL_CreateTexture( renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, 160, 144); key_state = SDL_GetKeyboardState(0); + ot = SDL_GetTicks64(); while (1) { prev_cycles = cycles; if (IME & IF & io[511]) { @@ -208,7 +202,7 @@ int main() { OP5_FLAG(32, 24) // JR i8 / JR , i8 tmp8 = mem8(PC++); if (carry) - PC += (int8_t)tmp8, tick(); + PC += (Sint8)tmp8, tick(); break; case 39: // DAA @@ -325,7 +319,7 @@ int main() { OP8_REL(56) // SRL r8 / SRL (HL) carry = tmp8 & 1; tmp8 = (opcode & 48) == 32 - ? (int8_t)tmp8 >> 1 + ? (Sint8)tmp8 >> 1 : tmp8 / 2 + (opcode & 32 ? 0 : opcode & 16 ? (F * 8 & 128) : carry * 128); @@ -368,8 +362,8 @@ int main() { break; case 248: // LD HL, SP + i8 - HL = SP + (int8_t)(tmp8 = mem8(PC++)); - set_flags(0, 1, 0, SP % 16 + tmp8 % 16 > 15, (uint8_t)SP + tmp8 > 255); + HL = SP + (Sint8)(tmp8 = mem8(PC++)); + set_flags(0, 1, 0, SP % 16 + tmp8 % 16 > 15, (Uint8)SP + tmp8 > 255); tick(); break; @@ -383,20 +377,20 @@ int main() { if (++ppu_dot == 456) { if (LY < 144) for (tmp = 160; --tmp >= 0;) { - uint8_t is_window = + Uint8 is_window = LCDC & 32 && LY >= io[330] && tmp >= io[331] - 7, x_offset = is_window ? tmp - io[331] + 7 : tmp + io[323], y_offset = is_window ? LY - io[330] : LY + io[322]; - uint16_t + Uint16 palette_index = 0, tile = video_ram[(LCDC & (is_window ? 64 : 8) ? 7 : 6) << 10 | y_offset / 8 * 32 + x_offset / 8], - color = get_color(LCDC & 16 ? tile : 256 + (int8_t)tile, + color = get_color(LCDC & 16 ? tile : 256 + (Sint8)tile, y_offset & 7, 7 - x_offset & 7); if (LCDC & 2) - for (uint8_t *sprite = io; sprite < io + 160; sprite += 4) { - uint8_t sprite_x = tmp - sprite[1] + 8, + for (Uint8 *sprite = io; sprite < io + 160; sprite += 4) { + Uint8 sprite_x = tmp - sprite[1] + 8, sprite_y = LY - *sprite + 16, sprite_color = get_color( sprite[2], sprite_y ^ (sprite[3] & 64 ? 7 : 0), @@ -422,8 +416,19 @@ int main() { SDL_RenderPresent(renderer); SDL_Event event; while (SDL_PollEvent(&event)) - if (event.type == SDL_QUIT) + if (event.type == SDL_QUIT) { + SDL_RWops *sav = SDL_RWFromFile("rom.sav", "wb"); + SDL_RWwrite(sav, extram, 1, 32768); + SDL_RWclose(sav); return 0; + } + nt = SDL_GetTicks64(); + comp -= delay = comp += 16.7427 - (nt - ot); + ot = nt; + if(delay > 0) { + SDL_Delay(delay); + ot = SDL_GetTicks64(); + } } LY = (LY + 1) % 154;