aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/chip8.cpp47
-rw-r--r--src/chip8.hpp3
-rw-r--r--src/main.cpp4
-rw-r--r--src/platform.cpp30
-rw-r--r--src/platform.hpp5
5 files changed, 54 insertions, 35 deletions
diff --git a/src/chip8.cpp b/src/chip8.cpp
index 94573f0..485d061 100644
--- a/src/chip8.cpp
+++ b/src/chip8.cpp
@@ -168,9 +168,7 @@ void Chip8::OP_NULL() {}
// 00E0: CLS
// Clear the display
void Chip8::OP_00E0() {
- for (uint32_t i = 0; i < sizeof(video) / sizeof(video[0]); i++) {
- video[i] = 0;
- }
+ video.reset();
};
// 00EE: RET
@@ -385,29 +383,34 @@ void Chip8::OP_Cxkk() {
// Dxyn: DRW Vx, Vy, nibble
// Display n-byte sprite starting at memory location I at (Vx, Vy), set VF = collision
void Chip8::OP_Dxyn() {
- uint8_t Vx = (opcode & 0x0F00u) >> 8u;
- uint8_t Vy = (opcode & 0x00FFu) >> 4u;
- uint8_t height = opcode & 0x000Fu;
+ uint8_t Vx = (opcode & 0x0F00u) >> 8u;
+ uint8_t Vy = (opcode & 0x00F0u) >> 4u;
+ uint8_t height = opcode & 0x000Fu;
- // Wrap if going beyond screen boundaries
- uint8_t xPos = registers[Vx] % VIDEO_WIDTH;
- uint8_t yPos = registers[Vy] % VIDEO_HEIGHT;
+ // Wrap if going beyond screen boundaries
+ uint8_t xPos = registers[Vx] % VIDEO_WIDTH;
+ uint8_t yPos = registers[Vy] % VIDEO_HEIGHT;
- registers[0xF] = 0;
-
- for (uint32_t row = 0; row < height; ++row) {
- uint8_t spriteByte = memory[index + row];
- for (uint32_t col = 0; col < 8; ++col) {
- uint8_t spritePixel = spriteByte & (0x80u >> col);
- uint32_t* screenPixel = &video[(yPos + row) * VIDEO_WIDTH + (xPos + col)];
+ registers[0xF] = 0;
- if (spritePixel) {
- if(*screenPixel == 0xFFFFFFFF)
- registers[0xF] = 1;
- *screenPixel ^= 0xFFFFFFFF;
- }
+ for (uint32_t row = 0; row < height; ++row) {
+ uint8_t spriteByte = memory[index + row];
+ for (uint32_t col = 0; col < 8; ++col) {
+ uint8_t spritePixel = spriteByte & (0x80u >> col);
+
+ // Calculate the coordinates in the video bitset
+ int x = (xPos + col) % VIDEO_WIDTH;
+ int y = (yPos + row) % VIDEO_HEIGHT;
+
+ // Check collision and update the video bitset
+ if (spritePixel) {
+ if (video[y * VIDEO_WIDTH + x]) {
+ registers[0xF] = 1;
+ }
+ video[y * VIDEO_WIDTH + x].flip();
+ }
+ }
}
- }
}
// Ex9E: SKP Vx
diff --git a/src/chip8.hpp b/src/chip8.hpp
index f144341..a2c4bdf 100644
--- a/src/chip8.hpp
+++ b/src/chip8.hpp
@@ -3,6 +3,7 @@
#include <cstdint>
#include <random>
+#include <bitset>
const uint32_t VIDEO_HEIGHT = 32;
const uint32_t VIDEO_WIDTH = 64;
@@ -24,7 +25,7 @@ class Chip8 {
uint8_t soundTimer {};
uint8_t keypad[16] {};
- uint32_t video[VIDEO_WIDTH * VIDEO_HEIGHT] {};
+ std::bitset<4096> video;
uint16_t opcode;
diff --git a/src/main.cpp b/src/main.cpp
index b5f12df..0e60faa 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -24,7 +24,7 @@ int main(int argc, char** argv) {
Chip8 chip8;
chip8.LoadROM(filename);
- int videoPitch = sizeof(chip8.video[0]) * VIDEO_WIDTH;
+ int count = 0;
bool quit = false;
while (!quit) {
@@ -33,7 +33,7 @@ int main(int argc, char** argv) {
usleep(cycleDelay * 1000);
chip8.Cycle();
- platform.Update(chip8.video, videoPitch);
+ platform.Update(chip8.video, videoScale);
}
return 0;
diff --git a/src/platform.cpp b/src/platform.cpp
index c7d9ab3..2840fa1 100644
--- a/src/platform.cpp
+++ b/src/platform.cpp
@@ -1,25 +1,39 @@
+#include <bitset>
+
#include "platform.hpp"
Platform::Platform(const char* title, int windowWidth, int windowHeight, int textureWidth, int textureHeight) {
SDL_Init(SDL_INIT_VIDEO);
- window = SDL_CreateWindow(title, 0, 0, windowWidth, windowHeight, SDL_WINDOW_SHOWN);
+ window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, windowWidth, windowHeight, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
- texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, textureWidth, textureHeight);
}
Platform::~Platform() {
- SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
-void Platform::Update(const void* buffer, int pitch) {
- SDL_UpdateTexture(texture, nullptr, buffer, pitch);
- SDL_RenderClear(renderer);
- SDL_RenderCopy(renderer, texture, nullptr, nullptr);
- SDL_RenderPresent(renderer);
+void Platform::Update(const std::bitset<4096>& bitset, int videoScale) {
+ SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
+ SDL_RenderClear(renderer);
+
+ for (int y = 0; y < 32; ++y) {
+ for (int x = 0; x < 64; ++x) {
+ SDL_Rect pixelRect = {x * videoScale, y * videoScale, videoScale, videoScale};
+
+ if (bitset[y * 64 + x]) {
+ SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
+ } else {
+ SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
+ }
+
+ SDL_RenderFillRect(renderer, &pixelRect);
+ }
+ }
+
+ SDL_RenderPresent(renderer);
}
bool Platform::ProcessInput(uint8_t* keys) {
diff --git a/src/platform.hpp b/src/platform.hpp
index 55b91df..90df65d 100644
--- a/src/platform.hpp
+++ b/src/platform.hpp
@@ -2,6 +2,8 @@
#define PLATFORM_HPP_
#include <cstdint>
+#include <bitset>
+
#include <SDL.h>
class Platform {
@@ -12,13 +14,12 @@ class Platform {
~Platform();
public:
- void Update(const void* buffer, int pitch);
+ void Update(const std::bitset<4096>& bitset, int videoScale);
bool ProcessInput(uint8_t* keys);
private:
SDL_Window* window {};
SDL_Renderer* renderer {};
- SDL_Texture* texture {};
};
#endif