Bläddra i källkod

Render each scanline at a time; MMC3 mapper fixup; debug output fixup

master
Nathaniel Walizer 11 månader sedan
förälder
incheckning
464fe79ebd
7 ändrade filer med 380 tillägg och 60 borttagningar
  1. +6
    -2
      Makefile
  2. +18
    -13
      src/map/mmc3.c
  3. +4
    -2
      src/mapper.h
  4. +2
    -1
      src/nes.c
  5. +9
    -5
      src/ppu.c
  6. +25
    -8
      src/ppu.h
  7. +316
    -29
      src/sdl_render.c

+ 6
- 2
Makefile Visa fil

@@ -1,6 +1,10 @@
CC = gcc
LD = $(CC)
PFLAGS = -g #-DE6502_DEBUG
PFLAGS = -g
#PFLAGS += -DDEBUG_MAPPER
#PFLAGS += -DDEBUG_RENDER
#PFLAGS += -DDEBUG_PPU
#PFLAGS += -DE6502_DEBUG
CFLAGS = $(PFLAGS) -Wall -Werror -Wshadow -I..
LDFLAGS = $(PFLAGS)

@@ -22,7 +26,7 @@ SRC_SRCS_1 += sdl_render.c sdl_input.c
MAPDIR = src/map
MAP_SRCS_1 = nrom.c mmc1.c cnrom.c mmc3.c

EXT_SRCS_1 = e6502/e6502.c
EXT_SRCS_1 = e6502/e6502.c e6502/opcodes.c


SRCS_1 = $(SRC_SRCS_1:%=$(SRCDIR)/%)


+ 18
- 13
src/map/mmc3.c Visa fil

@@ -5,6 +5,7 @@
typedef enum {
mmc3_Flag_Horizontal = 0b00000001,
mmc3_Flag_IRQ_Enabled = 0b00000010,
mmc3_Flag_IRQ_Reload = 0b00000100,
mmc3_Flag_WRAM_Protect = 0b01000000,
mmc3_Flag_WRAM_Enabled = 0b10000000,
} mmc3_Flag;
@@ -69,8 +70,8 @@ static inline void mmc3_map_2k_chr(mmc3_mapper* map,
MAP_LOG("CHR ROM OOB: %d > %d", bank, map->chr_rom_banks);
bank = bank % map->chr_rom_banks;
}
MAP_LOG("CHR ROM: 2k $%04x <- bank %d + %d", reg << 10, bank & ~1, bank | 1);
map->chr_bank[reg + 0] = mmc3_chr_bank(map, bank & ~1);
MAP_LOG("CHR ROM: 2k $%04x <- bank %d + %d", reg << 10, bank, bank | 1);
map->chr_bank[reg + 0] = mmc3_chr_bank(map, bank);
map->chr_bank[reg + 1] = mmc3_chr_bank(map, bank | 1);
}

@@ -145,9 +146,6 @@ static inline void mmc3_update_vram(mmc3_mapper* map) {

static void mmc3_reset(nes_mapper* nes_map) {
mmc3_mapper* map = (mmc3_mapper*)nes_map->data;
map->flags = 0;
map->bank_select = mmc3_Bank_Select_PRG |
mmc3_Bank_Select_CHR;
map->irq_count = 0;
map->irq_latch = 0;
mmc3_update_rom_mode(map, 0);
@@ -165,6 +163,8 @@ static int mmc3_init(nes_mapper* nes_map, nes_cart* cart) {
map->chr_rom_banks = cart->chr_rom_banks * 4;
map->flags = (cart->flags & Cart_Flag_Horizontal) ?
mmc3_Flag_Horizontal : 0;
map->bank_select = mmc3_Bank_Select_PRG |
mmc3_Bank_Select_CHR;
mmc3_reset(nes_map);
}
return (NULL == map ? -1 : 0);
@@ -251,7 +251,8 @@ static void mmc3_write(nes_mapper* nes_map,
} else if (addr < 0xE000U) {
if (addr & 1) {
MAP_LOG("IRQ Reload");
map->irq_count = 0;
map->flags |= mmc3_Flag_IRQ_Reload;
// map->irq_count = 0;
} else {
MAP_LOG("IRQ Latch: %d", val);
map->irq_latch = val;
@@ -271,17 +272,21 @@ static void mmc3_write(nes_mapper* nes_map,
static void mmc3_scanline(nes_mapper* nes_map) {
mmc3_mapper* map = (mmc3_mapper*)nes_map->data;

if (map->irq_count == 0) {
if ( map->irq_count <= 0 ||
(map->flags & mmc3_Flag_IRQ_Reload)) {
map->irq_count = map->irq_latch;
map->flags &= ~mmc3_Flag_IRQ_Reload;
} else {
map->irq_count--;
if ( map->irq_count <= 0 &&
(map->flags & mmc3_Flag_IRQ_Enabled)) {
MAP_LOG("IRQ Trigger");
nes_map_trigger_irq(nes_map, 1);
}
}

if ( map->irq_count <= 0 &&
(map->flags & mmc3_Flag_IRQ_Enabled)) {
MAP_LOG("IRQ Trigger");
nes_map_trigger_irq(nes_map, 1);
map->irq_count = 0;
}

}

static uint8_t* mmc3_chr_addr(nes_mapper* nes_map,


+ 4
- 2
src/mapper.h Visa fil

@@ -3,9 +3,11 @@

#include <stdint.h>

#ifdef DEBUG_MAPPER
#define MAP_LOG(fmt, ...) printf("MAP: " fmt "\n" __VA_OPT__(,) __VA_ARGS__)

#else
#define MAP_LOG(...) do {} while (0)
#endif

struct nes_cart_t;



+ 2
- 1
src/nes.c Visa fil

@@ -40,8 +40,9 @@ void nes_mem_write(nes* sys, uint16_t addr, uint8_t val) {

} else if (nes_ppu_dma_reg == addr) {
OAM_LOG("PPU: OAM DMA $%02x00 > $%02x\n", val, sys->ppu.oam_addr);
uint8_t* buf = (uint8_t*)sys->ppu.oam;
for (int i = 0; i < nes_ppu_oam_size; ++i) {
sys->ppu.oam[(uint8_t)(i + sys->ppu.oam_addr)] =
buf[(uint8_t)(i + sys->ppu.oam_addr)] =
nes_mem_read(sys, ((uint16_t)val << 8) + i);
}
sys->cpu.cycle += 513U;


+ 9
- 5
src/ppu.c Visa fil

@@ -28,7 +28,7 @@ uint8_t nes_ppu_read(nes_ppu* ppu, uint16_t addr) {

} else if (oam_reg_data == addr) {
OAM_LOG("PPU: OAM READ %02x > %02x\n", ppu->oam_addr, val);
val = ppu->oam[ppu->oam_addr];
val = ((uint8_t*)ppu->oam)[ppu->oam_addr];

} else if (ppu_reg_data == addr) {
if (ppu->addr >= nes_ppu_mem_pal_start) {
@@ -82,7 +82,7 @@ void nes_ppu_write(nes_ppu* ppu, uint16_t addr, uint8_t val) {

} else if (oam_reg_data == addr) {
OAM_LOG("PPU: OAM %02x < %02x\n", ppu->oam_addr, val);
ppu->oam[ppu->oam_addr++] = val;
((uint8_t*)ppu->oam)[ppu->oam_addr++] = val;

} else if (ppu_reg_mask == addr) {
ppu->mask = val;
@@ -119,6 +119,7 @@ void nes_ppu_write(nes_ppu* ppu, uint16_t addr, uint8_t val) {
ppu->scroll_y &= 0b00111000;
ppu->scroll_y |= (val & 0b11) << 6;
ppu->scroll_y |= (val & 0b110000) >> 4;

}
ppu->latch = !ppu->latch;

@@ -232,15 +233,18 @@ int nes_ppu_run(nes_ppu* ppu, int cycles) {
result = ppu_Result_VBlank_On;
}

} else if (ppu->scanline % 8 == 1) {
} else /*if (ppu->scanline % 8 == 1)*/ {
result = ppu_Result_Ready;
}
}

if ( 0 != ppu->hit_line &&
if ( ppu->hit_line > 0 &&
ppu->scanline > ppu->hit_line &&
ppu->cycle >= ppu->hit_dot) {
// if (!(ppu->status & ppu_Status_Hit)) printf("PPU: Hit @ %d, %d\n", ppu->hit_line + 1, ppu->hit_dot);
if (!(ppu->status & ppu_Status_Hit)) {
PPU_LOG("PPU: Hit @ %d, %d\n", ppu->hit_line + 1, ppu->hit_dot);
PPU_LOG("(Currently @ %d, %d)\n", ppu->scanline, ppu->cycle);
}
ppu->status |= ppu_Status_Hit;
}



+ 25
- 8
src/ppu.h Visa fil

@@ -66,13 +66,6 @@ struct nes_cart_t;
#define nes_ppu_mem_pal_start (0x3F00U)
#define nes_ppu_mem_pal_size (0x0020U)


#define nes_ppu_oam_size (256U)

#define nes_ppu_oam_sprite_size (4U)
#define nes_ppu_oam_sprite_count (nes_ppu_oam_size / \
nes_ppu_oam_sprite_size)

typedef enum {
ppu_Control_Nametable_Mask = 0b00000011,
ppu_Control_Scroll_Page_X = 0b00000001,
@@ -103,10 +96,34 @@ typedef enum {
ppu_Mask_More_Blue = 0b10000000,
} nes_ppu_Mask;


typedef struct {
uint8_t y;
uint8_t index;
uint8_t attr;
uint8_t x;
} oam_sprite;

typedef enum {
oam_Attr_Pal_Mask = 0b00000011,
oam_Attr_Background = 0b00100000,
oam_Attr_Flip_X = 0b01000000,
oam_Attr_Flip_Y = 0b10000000,
} oam_Attribute;

typedef enum {
oam_Index_Bank = 0b00000001,
oam_Index_Tile_Mask = 0b11111110,
} oam_Index;

#define nes_ppu_oam_sprite_count (64U)
#define nes_ppu_oam_size (nes_ppu_oam_sprite_count * 4U)


typedef struct {
// Memory
struct nes_mapper_t* mapper;
uint8_t oam[nes_ppu_oam_size];
oam_sprite oam[nes_ppu_oam_sprite_count];
uint8_t palette[nes_ppu_mem_pal_size];

// Timing


+ 316
- 29
src/sdl_render.c Visa fil

@@ -39,6 +39,7 @@ typedef struct {
SDL_Renderer* renderer;
SDL_Surface* background;
SDL_Surface* background_line;
SDL_Surface* foreground;
SDL_Surface* sprite;
SDL_Surface* target;
} sdl_render_data;
@@ -110,12 +111,30 @@ static int sdl_render_init(nes_Renderer* rend) {
}
}

if (0 == status) {
data->foreground = SDL_CreateRGBSurfaceWithFormat(
0, nes_ppu_render_w, nes_ppu_render_h,
8, SDL_PIXELFORMAT_INDEX8
);

if (NULL == data->foreground) {
fprintf(stderr, "SDL: Failed to create foreground\n");
SDL_FreeSurface(data->background_line);
SDL_FreeSurface(data->background);
SDL_DestroyRenderer(data->renderer);
SDL_DestroyWindow(data->window);
SDL_Quit();
status = -1;
}
}

if (0 == status) {
data->sprite = SDL_CreateRGBSurfaceWithFormat(
0, 8, 16, 8, SDL_PIXELFORMAT_INDEX8
);
if (NULL == data->sprite) {
fprintf(stderr, "SDL: Failed to create sprite\n");
SDL_FreeSurface(data->foreground);
SDL_FreeSurface(data->background_line);
SDL_FreeSurface(data->background);
SDL_DestroyRenderer(data->renderer);
@@ -133,6 +152,7 @@ static int sdl_render_init(nes_Renderer* rend) {
if (NULL == data->target) {
fprintf(stderr, "SDL: Failed to create target\n");
SDL_FreeSurface(data->sprite);
SDL_FreeSurface(data->foreground);
SDL_FreeSurface(data->background_line);
SDL_FreeSurface(data->background);
SDL_DestroyRenderer(data->renderer);
@@ -147,6 +167,10 @@ static int sdl_render_init(nes_Renderer* rend) {
nes_palette, 0U, 64U);
SDL_SetColorKey(data->background, SDL_TRUE, 0xFFU);

SDL_SetPaletteColors(data->foreground->format->palette,
nes_palette, 0U, 64U);
SDL_SetColorKey(data->foreground, SDL_TRUE, 0xFFU);

SDL_SetPaletteColors(data->sprite->format->palette,
nes_palette, 0U, 64U);
SDL_SetColorKey(data->sprite, SDL_TRUE, 0xFFU);
@@ -161,6 +185,7 @@ static void sdl_render_done(nes_Renderer* rend) {
sdl_render_data* data = (sdl_render_data*)rend->data;
SDL_FreeSurface(data->target);
SDL_FreeSurface(data->sprite);
SDL_FreeSurface(data->foreground);
SDL_FreeSurface(data->background_line);
SDL_FreeSurface(data->background);
SDL_DestroyRenderer(data->renderer);
@@ -168,6 +193,52 @@ static void sdl_render_done(nes_Renderer* rend) {
SDL_Quit();
}

static inline void render_sprite_line(
const nes_ppu* ppu, int index, int y, const uint8_t* pal,
uint8_t* dst, int start, int end) {
uint8_t* sprite = chr_mem(ppu, index * 16U);
uint8_t lo = sprite[0U + y] << start;
uint8_t hi = sprite[8U + y] << start;
for (int x = start; x < end; ++x) {
int pal_idx = (((hi & 0x80) >> 6) | ((lo & 0x80) >> 7));
if (pal_idx) *dst = pal[pal_idx];
dst++;
hi <<= 1;
lo <<= 1;
}
}

static inline void render_sprite_line_flip(
const nes_ppu* ppu, int index, int y, const uint8_t* pal,
uint8_t* dst, int start, int end) {
uint8_t* sprite = chr_mem(ppu, index * 16U);
uint8_t lo = sprite[0U + y] >> start;
uint8_t hi = sprite[8U + y] >> start;
for (int x = start; x < end; ++x) {
int pal_idx = (((hi & 1) << 1) | (lo & 1));
if (pal_idx) *dst = pal[pal_idx];
dst++;
hi >>= 1;
lo >>= 1;
}
}

static inline void render_bg_sprite_line(
const nes_ppu* ppu, int index, int y, const uint8_t* pal,
uint8_t* dst, int start, int end) {
uint8_t* sprite = chr_mem(ppu, index * 16U);
uint8_t lo = sprite[0U + y] << (start % 8);
uint8_t hi = sprite[8U + y] << (start % 8);
for (int x = start; x < end; ++x) {
int pal_idx = (((hi & 0x80) >> 6) | ((lo & 0x80) >> 7));
*dst = (pal_idx ? pal[pal_idx] : 0xFFU);
dst++;
hi <<= 1;
lo <<= 1;
}
}

/*
static void render_bg_sprite(const nes_ppu* ppu, int index,
const uint8_t* pal,
void* loc, int pitch) {
@@ -216,7 +287,62 @@ static void render_background_area(const nes_ppu* ppu, int page,
index_line += nes_ppu_blocks_w;
}
}
*/

static inline void render_bg_scanline_area(
const nes_ppu* ppu, int page,
uint8_t* dst, int x, int y, int w) {
int block_x = x / 8;
int line_end = x + w;
int block_y = y / 8;
y = y % 8;
int bank = (ppu->control & ppu_Control_Back_Bank) ? 0x100 : 0;
const uint8_t* indexes = nes_map_vram_addr(ppu->mapper,
page << 10);
const uint8_t* attrs = indexes + 960U;
const uint8_t* index = indexes +
(block_y * nes_ppu_blocks_w) +
block_x;

while (x < line_end) {
int attr_idx = ((block_y / 4) * 8) + (block_x / 4);
int shift = 2 * ((block_y & 0b10) |
((block_x & 0b10) >> 1));
int pal_idx = (attrs[attr_idx] >> shift) & 3;
const uint8_t* pal = &ppu->palette[pal_idx * 4];

int end = (x + 8) & ~7;
if (end > line_end) end = line_end;

render_bg_sprite_line(ppu, bank + *index, y,
pal, dst, x, end);

++index;
++block_x;
dst += (end - x);
x = end;
}
}

static void render_bg_scanline(const nes_ppu* ppu, int scanline,
uint8_t* dst) {
// TODO: Handle column 0 flag

int page = (ppu->control & ppu_Control_Nametable_Mask);
int x = ppu->scroll_x;
int y = ppu->scroll_y + scanline;

if (y >= nes_ppu_render_h) {
y -= nes_ppu_render_h;
page ^= 0b10;
}

int w = (nes_ppu_render_w - x);
render_bg_scanline_area(ppu, page, dst, x, y, w);
render_bg_scanline_area(ppu, page ^ 1, dst + w, 0, y, x);
}

/*
static void render_background_line(const nes_ppu* ppu, int line,
void* buffer, int pitch) {
// TODO: Handle column 0 flag
@@ -246,27 +372,6 @@ static void render_background_line(const nes_ppu* ppu, int line,
);
}


typedef struct {
uint8_t y;
uint8_t index;
uint8_t attr;
uint8_t x;
} oam_sprite;

typedef enum {
oam_Attr_Pal_Mask = 0b00000011,
oam_Attr_Background = 0b00100000,
oam_Attr_Flip_X = 0b01000000,
oam_Attr_Flip_Y = 0b10000000,
} oam_Attribute;

typedef enum {
oam_Index_Bank = 0b00000001,
oam_Index_Tile_Mask = 0b11111110,
} oam_Index;


static void render_sprite(nes_ppu* ppu, int index,
const uint8_t* pal, uint8_t attr,
void* loc, int pitch) {
@@ -299,7 +404,62 @@ static void render_sprite(nes_ppu* ppu, int index,
++sprite;
}
}
*/

static void render_line_sprites(nes_ppu* ppu, uint8_t* dst_line,
int scanline, int background) {
int bank = (ppu->control & ppu_Control_Sprite_Bank) ?
0x100 : 0;
for ( int i_sprite = nes_ppu_oam_sprite_count - 1;
i_sprite >= 0; --i_sprite) {
const oam_sprite* sprite = &ppu->oam[i_sprite];
if ((sprite->attr & oam_Attr_Background) ^ background) {
continue;
}
if ( !(ppu->mask & ppu_Mask_Left_Sprite) &&
sprite->x < 8) {
continue;
}
int y_pos = (sprite->y + 1);
int y = scanline - y_pos;
if (0 > y) continue;
int h = (ppu->control & ppu_Control_Sprite_Size) ? 16 : 8;
if (y >= h) continue;

int index = sprite->index;
if (ppu->control & ppu_Control_Sprite_Size) {
bank = (index & 1) ? 0x100 : 0;
index &= 0xFEU;
}
index += bank;

if (ppu->control & ppu_Control_Sprite_Size) {
if (y >= 8) {
index ^= 1;
y -= 8;
}
if (sprite->attr & oam_Attr_Flip_Y) {
index ^= 1;
}
}

int pal_idx = (sprite->attr & oam_Attr_Pal_Mask);
const uint8_t* pal = &ppu->palette[16 + (pal_idx * 4)];

if (sprite->attr & oam_Attr_Flip_Y) y = 7 - y;
int end = nes_ppu_render_w - sprite->x;
if (end > 8) end = 8;
if (sprite->attr & oam_Attr_Flip_X) {
render_sprite_line_flip(ppu, index, y, pal,
dst_line + sprite->x, 0, end);
} else {
render_sprite_line(ppu, index, y, pal,
dst_line + sprite->x, 0, end);
}
}
}

/*
static void render_sprites(nes_ppu* ppu,
SDL_Surface* buffer,
SDL_Surface* target,
@@ -363,30 +523,30 @@ static void render_sprites(nes_ppu* ppu,
target, &target_rect);
}
}
*/

// Check sprite (0 only) collision on a scanline
// This assumes that we've verified that this sprite
// intersects with this scanline.
// Scanline is 0-239 from inside the rendering window
// (though we should never see this called with 0).
static int eval_sprite_line(const nes_ppu* ppu, int line,
static int eval_sprite_line(const nes_ppu* ppu, int y,
const oam_sprite* sprite,
const uint8_t* chr,
const uint8_t* back) {
int hit_pos = -1;

int y = line - (sprite->y + 1);

if (sprite->attr & oam_Attr_Flip_Y) y = 7 - y;
uint8_t lo = chr[0U + y];
uint8_t hi = chr[8U + y];

back += sprite->x;
for (int x = sprite->x; x < nes_ppu_render_w; ++x) {
int end = nes_ppu_render_w;
if (end > sprite->x + 8) end = sprite->x + 8;
for (int x = sprite->x; x < end; ++x) {
int pal_idx = (sprite->attr & oam_Attr_Flip_X) ?
(((hi & 1) << 1) | (lo & 1)) :
( ((hi & 0x80) >> 6) |
((lo & 0x80) >> 7));
(((hi & 0x80) >> 6) | ((lo & 0x80) >> 7));
if (pal_idx && *back != 0xFFU) {
hit_pos = x;
break;
@@ -404,6 +564,7 @@ static int eval_sprite_line(const nes_ppu* ppu, int line,
return hit_pos;
}

#if 0
static void update_sprite_hit(nes_ppu* ppu, int block_line,
const void* back_pixels,
int back_pitch) {
@@ -498,6 +659,102 @@ static void render_block_line(nes_ppu* ppu, int line,
data->background, &render_rect);
*/
}
#endif

static void update_scanline_hit(nes_ppu* ppu, uint8_t* back_line,
int scanline) {
const oam_sprite* sprite = &ppu->oam[0];
int bank = (ppu->control & ppu_Control_Sprite_Bank) ?
0x100 : 0;

if ( !(ppu->mask & ppu_Mask_Left_Sprite) &&
sprite->x < 8) {
return;
}
int y_pos = (sprite->y + 1);
int y = scanline - y_pos;
if (0 > y) return;
int h = (ppu->control & ppu_Control_Sprite_Size) ? 16 : 8;
if (y >= h) return;

int index = sprite->index;
if (ppu->control & ppu_Control_Sprite_Size) {
bank = (index & 1) ? 0x100 : 0;
index &= 0xFEU;
}
index += bank;

if (ppu->control & ppu_Control_Sprite_Size) {
if (y >= 8) {
index ^= 1;
y -= 8;
}
if (sprite->attr & oam_Attr_Flip_Y) {
index ^= 1;
}
}

const uint8_t* chr = chr_mem(ppu, index * 16U);
int hit = eval_sprite_line(ppu, y, sprite, chr, back_line);

if (hit >= 0) {
REND_LOG("Upcoming hit @ %d, %d\n", scanline + 1, hit);
REND_LOG("(Currently @ %d, %d)\n", ppu->scanline, ppu->cycle);
ppu->hit_line = scanline;
ppu->hit_dot = hit;
}
}

static void render_scanline(nes_ppu* ppu, int line,
sdl_render_data* data) {
if (!(ppu->mask & (ppu_Mask_Sprite | ppu_Mask_Back))) {
// Do nothing if BOTH are disabled.
return;
}

SDL_Rect src_rect = {
.x = 0,
.y = 0,
.w = nes_ppu_render_w,
.h = 1,
};

SDL_Rect dst_rect = {
.x = 0,
.y = line,
.w = nes_ppu_render_w,
.h = 1,
};

uint8_t* foreground = data->foreground->pixels;
uint8_t* background = data->background->pixels;

if (ppu->mask & ppu_Mask_Sprite) {
memset(foreground, 0xFFU, nes_ppu_render_w);
render_line_sprites(ppu, foreground, line,
oam_Attr_Background);
SDL_BlitSurface(data->foreground, &src_rect,
data->target, &dst_rect);
}

// We check for hits if EITHER layer is enabled.
render_bg_scanline(ppu, line, background);
if (ppu->hit_line <= 0) {
update_scanline_hit(ppu, background, line);
}

if (ppu->mask & ppu_Mask_Back) {
SDL_BlitSurface(data->background, &src_rect,
data->target, &dst_rect);
}

if (ppu->mask & ppu_Mask_Sprite) {
memset(foreground, 0xFFU, nes_ppu_render_w);
render_line_sprites(ppu, foreground, line, 0);
SDL_BlitSurface(data->foreground, &src_rect,
data->target, &dst_rect);
}
}

static int sdl_render(nes_Renderer* rend, nes_ppu* ppu) {
int status = 0;
@@ -513,9 +770,21 @@ static int sdl_render(nes_Renderer* rend, nes_ppu* ppu) {
SDL_FillRect(data->target, NULL, ((int)ext.r << 16) |
((int)ext.g << 8) |
ext.b);
/*
memset(data->foreground->pixels, 0xFFU,
data->foreground->pitch * data->foreground->h);

if (ppu->mask & ppu_Mask_Sprite) {
render_sprites(ppu, data->sprite, data->target,
oam_Attr_Background);

render_sprites(ppu, data->sprite, data->foreground, 0);
}
*/

} else if (ppu->scanline < nes_ppu_prerender +
nes_ppu_height) {
/*
int line = (ppu->scanline - (int)nes_ppu_prerender) / 8;

REND_LOG("Scanline %3d -> Line %2d @ X %d\n", ppu->scanline, line, ppu->scroll_x);
@@ -524,26 +793,44 @@ static int sdl_render(nes_Renderer* rend, nes_ppu* ppu) {
if (ppu->mask & ppu_Mask_Back) {
render_block_line(ppu, line, data);
}
*/
REND_LOG("Scanline %3d : X %d Y %d\n", ppu->scanline, ppu->scroll_x, ppu->scroll_y);
int line = ppu->scanline - (int)nes_ppu_prerender;
render_scanline(ppu, line, data);

} else {
REND_LOG("Scanline %3d -> Postrender\n", ppu->scanline);

/*
if (ppu->mask & ppu_Mask_Sprite) {
render_sprites(ppu, data->sprite, data->target,
oam_Attr_Background);
}
*/
/*
if (ppu->mask & ppu_Mask_Back) {
// Render final partial line
if (0 != (ppu->scroll_y % 8)) {
render_block_line(ppu, nes_ppu_blocks_h, data);
if (ppu->mask & ppu_Mask_Sprite) {
// TODO: Render background sprites that start this block
}
if (ppu->mask & ppu_Mask_Back) {
render_block_line(ppu, nes_ppu_blocks_h, data);
}
if (ppu->mask & ppu_Mask_Sprite) {
// TODO: Render foreground sprites that end this block
}
}

SDL_BlitSurface(data->background, NULL,
data->target, NULL);
}

if (ppu->mask & ppu_Mask_Sprite) {
render_sprites(ppu, data->sprite, data->target, 0);
SDL_BlitSurface(data->foreground, NULL,
data->target, NULL);
}
*/
SDL_Texture* texture = SDL_CreateTextureFromSurface(
data->renderer, data->target
);


Laddar…
Avbryt
Spara