Add palette colors the main emulator view
This commit is contained in:
parent
0066e77455
commit
d1ddcb1b0f
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Created by william on 7/29/24.
|
||||
// Created by william on 8/6/24.
|
||||
//
|
||||
|
||||
#ifndef NES_EMULATOR_COLORS_H
|
65
ppu/ppu.c
65
ppu/ppu.c
|
@ -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;
|
||||
}
|
||||
|
||||
return palette & 0b11;
|
||||
}
|
||||
|
||||
static inline byte ppu_pixel_get_mask(unsigned int tile_fine_x) {
|
||||
return 1 << (8 - tile_fine_x - 1);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue