Add palette colors the main emulator view

This commit is contained in:
william 2024-08-13 17:32:54 -04:00
parent 0066e77455
commit d1ddcb1b0f
7 changed files with 59 additions and 54 deletions

View File

@ -1,4 +1,4 @@
set(HEADERS gui.h window.h main_window.h colors.h)
set(HEADERS gui.h window.h main_window.h)
set(SOURCE gui.c window.c main_window.c)
if (NES_DEBUG)

View File

@ -3,13 +3,12 @@
//
#include <string.h>
#include <stdio.h>
#include "dbg_palette.h"
#include "../include/ppu.h"
#include "colors.h"
#include "../ppu/colors.h"
DebugPaletteMemory palette_memory;
pixel color_list[0x40] = COLOR_LIST;
pixel dbg_color_list[0x40] = COLOR_LIST;
#define COPY_PALETTE(memory, dest) memcpy(&(dest), &(memory), sizeof(DebugPalette))
#define COPY_PALETTES(memory, base_addr, dest) \
@ -34,5 +33,5 @@ pixel dbg_get_background_color(byte palette, byte data) {
}
int color = palette_memory.background_palettes[palette][data - 1];
return color_list[color];
return dbg_color_list[color];
}

View File

@ -37,18 +37,18 @@ void main_window_render_delay(SDL_Renderer *renderer) {
void main_window_render(NesMainWindow *window, PPUPixel *pixels) {
SDL_RenderClear(window->sdl_context.renderer);
unsigned int frame_buffer[240 * 256];
for (int i = 0; i < 240 * 256; i++) {
PPUPixel pixel = pixels[i];
// unsigned int frame_buffer[240 * 256];
// for (int i = 0; i < 240 * 256; i++) {
// PPUPixel pixel = pixels[i];
//
// unsigned int *data = &frame_buffer[i];
// *data = 0xff000000;
// *data |= pixel.r << 16;
// *data |= pixel.g << 8;
// *data |= pixel.b;
// }
unsigned int *data = &frame_buffer[i];
*data = 0xff000000;
*data |= pixel.r << 16;
*data |= pixel.g << 8;
*data |= pixel.b;
}
SDL_UpdateTexture(window->texture, NULL, &frame_buffer, 240 * sizeof(unsigned int));
SDL_UpdateTexture(window->texture, NULL, pixels, 240 * sizeof(unsigned int));
SDL_RenderCopy(window->sdl_context.renderer, window->texture, NULL, NULL);
#if DEBUG

View File

@ -69,11 +69,12 @@ typedef struct ppu_tile_fetch {
byte pattern_table_tile_high;
} PPUTileFetch;
typedef struct ppu_pixel {
byte r;
byte g;
byte b;
} PPUPixel;
//typedef struct ppu_pixel {
// byte r;
// byte g;
// byte b;
//} PPUPixel;
typedef unsigned int PPUPixel;
typedef struct ppu_tile_queue {
PPUTileFetch first_fetch;
@ -105,8 +106,6 @@ typedef struct ppu {
PPUTileFetch fetch;
PPUTileQueue tile_queue;
// PPUTileFetch tile_fetch;
// PPUTileFetch fetch;
unsigned long frame;
unsigned int scanline;
unsigned int cycle;

View File

@ -1,4 +1,4 @@
set(HEADERS ppu.h palette.h)
set(HEADERS ppu.h palette.h colors.h)
set(SOURCE ppu.c palette.c)
add_library(nes_ppu ${SOURCE} ${HEADERS})

View File

@ -1,5 +1,5 @@
//
// Created by william on 7/29/24.
// Created by william on 8/6/24.
//
#ifndef NES_EMULATOR_COLORS_H

View File

@ -19,6 +19,7 @@
#include "../include/ppu.h"
#include "../cpu/cpu.h"
#include "../include/rom.h"
#include "colors.h"
#define PPU_VISIBLE_FRAME_END 240
#define PPU_POST_RENDER_LINE_START PPU_VISIBLE_FRAME_END
@ -27,7 +28,10 @@
#define PPU_LINE_END PPU_PRE_RENDER_LINE
#define PPU_LINE_WIDTH 340
#define NAMETABLE_TILE_SIZE 8
PPU ppu_state;
PPUPixel color_list[0x40] = COLOR_LIST;
void ppu_init() {
memset(&ppu_state, 0, sizeof(PPU));
@ -70,39 +74,42 @@ void ppu_trigger_vbl_nmi() {
88 `88. 88. 88 V888 88 .8D 88. 88 `88. .88. 88 V888 88. ~8~
88 YD Y88888P VP V8P Y8888D' Y88888P 88 YD Y888888P VP V8P Y888P
*/
static inline unsigned int ppu_pixel_get_index(unsigned int scanline, unsigned int cycle) {
return scanline * PPU_VISIBLE_FRAME_END + cycle;
static inline byte ppu_pixel_get_palette(byte attribute) {
unsigned int tile_x = ppu_state.cycle / NAMETABLE_TILE_SIZE;
unsigned int tile_y = ppu_state.scanline / NAMETABLE_TILE_SIZE;
// Attribute Data:
// 7654 3210
// |||| ||++- Color bits 3-2 for top left quadrant of this byte
// |||| ++--- Color bits 3-2 for top right quadrant of this byte
// ||++------ Color bits 3-2 for bottom left quadrant of this byte
// ++-------- Color bits 3-2 for bottom right quadrant of this byte
byte palette = attribute;
if (tile_y % 4 >= 2) {
palette >>= 4;
}
if (tile_x % 4 >= 2) {
palette >>= 2;
}
static inline byte ppu_pixel_get_mask(unsigned int tile_fine_x) {
return 1 << (8 - tile_fine_x - 1);
return palette & 0b11;
}
static inline void ppu_pixel_set_color(PPUPixel *pixel, byte pt_low, byte pt_high) {
static inline void ppu_pixel_set_color(PPUPixel *pixel, byte pt_low, byte pt_high, byte attribute) {
for (int i = 0; i < 8; i++) {
PPUPixel *spixel = pixel + i;
byte bitmask = ppu_pixel_get_mask(i);
byte pixel_offset = 8 - i - 1;
byte p1_byte = pt_low & bitmask;
byte p2_byte = pt_high & bitmask;
byte color_low = (pt_low >> pixel_offset) & 1;
byte color_high = (pt_high >> pixel_offset) & 1;
byte color_offset = (color_high << 1) | color_low;
if (p1_byte && p2_byte) {
spixel->r = 255;
spixel->g = 255;
spixel->b = 255;
} else if (p2_byte) {
spixel->r = 255;
spixel->g = 0;
spixel->b = 0;
} else if (p1_byte) {
spixel->r = 0;
spixel->g = 255;
spixel->b = 255;
} else {
spixel->r = 0;
spixel->g = 0;
spixel->b = 0;
address color_addr = 0x3f00 + color_offset;
if (color_offset != 0) { // The first color of a palette (0) is always the universal color
color_addr += ppu_pixel_get_palette(attribute) * 4;
}
byte color = ppu_read(color_addr);
*(pixel + i) = color_list[color];
}
}
@ -110,7 +117,7 @@ void ppu_draw_tile() {
PPUTileFetch fetch = ppu_state.tile_queue.displayed_fetch;
unsigned int y = ppu_state.scanline;
unsigned int x = ppu_state.cycle + 0;
unsigned int x = ppu_state.cycle;
// if (x > PPU_LINE_WIDTH) {
// x -= PPU_LINE_WIDTH;
@ -123,7 +130,7 @@ void ppu_draw_tile() {
unsigned int pixel_index = y * PPU_VISIBLE_FRAME_END + x;
PPUPixel *pixel = &ppu_state.pixels[pixel_index];
ppu_pixel_set_color(pixel, fetch.pattern_table_tile_low, fetch.pattern_table_tile_high);
ppu_pixel_set_color(pixel, fetch.pattern_table_tile_low, fetch.pattern_table_tile_high, fetch.attribute_table);
}
byte ppu_get_pattern(byte tile_index, byte high) {