|
|
|
@@ -0,0 +1,109 @@ |
|
|
|
#include <SDL/SDL.h> |
|
|
|
|
|
|
|
#include "render.h" |
|
|
|
#include "ppu.h" |
|
|
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
uint8_t r; |
|
|
|
uint8_t g; |
|
|
|
uint8_t b; |
|
|
|
} __attribute__ (( packed )) sPal; |
|
|
|
|
|
|
|
static struct sPal nes_palette[64] = { |
|
|
|
{0x80,0x80,0x80}, {0x00,0x00,0xBB}, {0x37,0x00,0xBF}, {0x84,0x00,0xA6}, |
|
|
|
{0xBB,0x00,0x6A}, {0xB7,0x00,0x1E}, {0xB3,0x00,0x00}, {0x91,0x26,0x00}, |
|
|
|
{0x7B,0x2B,0x00}, {0x00,0x3E,0x00}, {0x00,0x48,0x0D}, {0x00,0x3C,0x22}, |
|
|
|
{0x00,0x2F,0x66}, {0x00,0x00,0x00}, {0x05,0x05,0x05}, {0x05,0x05,0x05}, |
|
|
|
|
|
|
|
{0xC8,0xC8,0xC8}, {0x00,0x59,0xFF}, {0x44,0x3C,0xFF}, {0xB7,0x33,0xCC}, |
|
|
|
{0xFF,0x33,0xAA}, {0xFF,0x37,0x5E}, {0xFF,0x37,0x1A}, {0xD5,0x4B,0x00}, |
|
|
|
{0xC4,0x62,0x00}, {0x3C,0x7B,0x00}, {0x1E,0x84,0x15}, {0x00,0x95,0x66}, |
|
|
|
{0x00,0x84,0xC4}, {0x11,0x11,0x11}, {0x09,0x09,0x09}, {0x09,0x09,0x09}, |
|
|
|
|
|
|
|
{0xFF,0xFF,0xFF}, {0x00,0x95,0xFF}, {0x6F,0x84,0xFF}, {0xD5,0x6F,0xFF}, |
|
|
|
{0xFF,0x77,0xCC}, {0xFF,0x6F,0x99}, {0xFF,0x7B,0x59}, {0xFF,0x91,0x5F}, |
|
|
|
{0xFF,0xA2,0x33}, {0xA6,0xBF,0x00}, {0x51,0xD9,0x6A}, {0x4D,0xD5,0xAE}, |
|
|
|
{0x00,0xD9,0xFF}, {0x66,0x66,0x66}, {0x0D,0x0D,0x0D}, {0x0D,0x0D,0x0D}, |
|
|
|
|
|
|
|
{0xFF,0xFF,0xFF}, {0x84,0xBF,0xFF}, {0xBB,0xBB,0xFF}, {0xD0,0xBB,0xFF}, |
|
|
|
{0xFF,0xBF,0xEA}, {0xFF,0xBF,0xCC}, {0xFF,0xC4,0xB7}, {0xFF,0xCC,0xAE}, |
|
|
|
{0xFF,0xD9,0xA2}, {0xCC,0xE1,0x99}, {0xAE,0xEE,0xB7}, {0xAA,0xF7,0xEE}, |
|
|
|
{0xB3,0xEE,0xFF}, {0xDD,0xDD,0xDD}, {0x11,0x11,0x11}, {0x11,0x11,0x11} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
SDL_Surface* surface; |
|
|
|
uint8_t buffer[3 * nes_ppu_render_w * nes_ppu_render_h]; |
|
|
|
} sdl_render_data; |
|
|
|
|
|
|
|
static sdl_render_data the_render_data = {0}; |
|
|
|
|
|
|
|
|
|
|
|
static int filter(const SDL_Event* event) { |
|
|
|
return event->type == SDL_QUIT; |
|
|
|
} |
|
|
|
|
|
|
|
static int sdl_render_init(nes_Renderer* rend) { |
|
|
|
int status = SDL_Init(SDL_INIT_VIDEO); |
|
|
|
|
|
|
|
if (0 != status) { |
|
|
|
fprintf(stderr, "SDL: Failed to initialize\n"); |
|
|
|
|
|
|
|
} else { |
|
|
|
SDL_WM_SetCaption("NESe", "NESe"); |
|
|
|
|
|
|
|
if (NULL == SDL_SetVideoMode(nes_ppu_render_w, |
|
|
|
nes_ppu_render_h, |
|
|
|
24, SDL_HWSURFACE)) { |
|
|
|
fprintf(stderr, "SDL: Failed to set video mode\n"); |
|
|
|
status = -1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (0 == status) { |
|
|
|
the_render_data.surface = SDL_CreateRGBSurfaceFrom( |
|
|
|
the_render_data.buffer, nes_ppu_render_w, |
|
|
|
nes_ppu_render_h, 24, nes_ppu_render_w * 3, |
|
|
|
0xFFU, 0xFF00U, 0xFF0000U, 0 |
|
|
|
); |
|
|
|
|
|
|
|
SDL_SetEventFilter(filter); |
|
|
|
|
|
|
|
rend->data = &the_render_data; |
|
|
|
} |
|
|
|
|
|
|
|
return status; |
|
|
|
} |
|
|
|
|
|
|
|
static void sdl_render_done(nes_Renderer* rend) { |
|
|
|
sdl_render_data* data = (sdl_render_data*)rend->data; |
|
|
|
if (NULL != data->surface) { |
|
|
|
SDL_FreeSurface(data->surface); |
|
|
|
data->surface = NULL; |
|
|
|
} |
|
|
|
SDL_Quit(); |
|
|
|
} |
|
|
|
|
|
|
|
static int sdl_render(nes_Renderer* rend, nes_ppu* ppu) { |
|
|
|
sdl_render_data* data = (sdl_render_data*)rend->data; |
|
|
|
|
|
|
|
// TODO |
|
|
|
|
|
|
|
SDL_Surface* screen = SDL_GetVideoSurface(); |
|
|
|
if (0 == SDL_BlitSurface(data->surface, NULL, screen, NULL)) { |
|
|
|
SDL_UpdateRect(screen, 0, 0, 0, 0); |
|
|
|
} |
|
|
|
|
|
|
|
SDL_Event event = {0}; |
|
|
|
return (1 == SDL_PollEvent(&event) && event.type == SDL_QUIT) ? |
|
|
|
-1 : 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
nes_Renderer sdl_renderer = { |
|
|
|
.init = sdl_render_init, |
|
|
|
.done = sdl_render_done, |
|
|
|
.render = sdl_render, |
|
|
|
}; |