Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forgot to locally switch from the SDL branch and delete it... #5

Merged
merged 29 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
beb9184
Basic SDL Port without menu
JustDoom Apr 6, 2024
13f0474
Remove SFML submodule
JustDoom Apr 6, 2024
a0edb78
Update README.md
JustDoom Apr 6, 2024
69de193
Mostly merge new changes
JustDoom Dec 11, 2024
c43847d
Well it runs again now
JustDoom Dec 13, 2024
f15e77a
Fix multiple windows crashing
JustDoom Dec 13, 2024
da6fa01
Mostly port to SDL
JustDoom Dec 15, 2024
87bc1ce
Fix button hovering on a window applying on all windows
JustDoom Dec 15, 2024
95542c0
Some better window shutdown
JustDoom Dec 16, 2024
34b925f
Update Cmake for SDl
JustDoom Dec 16, 2024
fb9da19
Try fix windows gameinput.h issue
JustDoom Dec 16, 2024
5e7685d
Maybe fix windows string error
JustDoom Dec 16, 2024
d207b6e
Stop libconfig building examples
JustDoom Dec 16, 2024
6302e0c
Update libconfig
JustDoom Dec 16, 2024
95fb101
Fix random colours, no idea why it happened though
JustDoom Dec 16, 2024
eb860ea
Handle multiple windows at 60fps
JustDoom Dec 17, 2024
c2bea12
FPS debugger
JustDoom Dec 17, 2024
dd56bae
Properly remove window on close
JustDoom Dec 17, 2024
98d9462
Clean up some code/style
JustDoom Dec 17, 2024
217a471
Reimplement sound
JustDoom Dec 17, 2024
0ebf0bb
Update readme
JustDoom Dec 17, 2024
3669ab1
Oops
JustDoom Dec 17, 2024
a847be8
Probably don't quit al of SDL when the audio shuts down
JustDoom Dec 17, 2024
4443886
Typo
JustDoom Dec 17, 2024
06d1156
Reimplement command line rom starting. Also cleans up SDL init
JustDoom Dec 17, 2024
a04a91c
Try fix windows not finding M_PI
JustDoom Dec 17, 2024
0a37fcd
Okay maybe now
JustDoom Dec 17, 2024
945b3c7
FINE
JustDoom Dec 17, 2024
48068af
Fix some more compatibility issues
JustDoom Dec 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- '.github/workflows/**'
branches:
- master
- sdl
workflow_dispatch:

jobs:
Expand Down Expand Up @@ -100,7 +101,7 @@ jobs:
run: |
mkdir -p build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake .. -DCMAKE_BUILD_TYPE=Release -D CMAKE_SYSTEM_VERSION=10.0.26100.0

- name: Build CMake
run: |
Expand Down
15 changes: 9 additions & 6 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
[submodule "dependencies/sfml"]
path = dependencies/sfml
url = https://github.com/SFML/SFML.git
[submodule "dependencies/libconfig"]
path = dependencies/libconfig
url = https://github.com/hyperrealm/libconfig.git
[submodule "dependencies/sdl"]
path = dependencies/sdl
url = git@github.com:libsdl-org/SDL.git
[submodule "dependencies/nativefiledialog"]
path = dependencies/nativefiledialog
url = git@github.com:btzy/nativefiledialog-extended.git
[submodule "dependencies/libconfig"]
path = dependencies/libconfig
url = https://github.com/hyperrealm/libconfig.git
[submodule "dependencies/sdl_ttf"]
path = dependencies/sdl_ttf
url = git@github.com:libsdl-org/SDL_ttf.git
32 changes: 2 additions & 30 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,11 @@ VERSION 0.1)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
option(SDL_VENDORED "Use vendored libraries" ON)

add_executable(8ChocChip)

#option(BUILD_SHARED_LIBS "Build shared libraries" OFF)

#file(GLOB ASSETS "${CMAKE_SOURCE_DIR}/assets/*")
#
#foreach(ASSET ${ASSETS})
# configure_file(${ASSET} ${CMAKE_BINARY_DIR}/assets COPYONLY)
#endforeach()

add_subdirectory(dependencies)
add_subdirectory(src)

Expand All @@ -27,33 +19,13 @@ else()
set(libname "config")
endif()

target_link_libraries(8ChocChip PRIVATE sfml-graphics sfml-audio sfml-window sfml-system nfd ${libname}++)
target_link_libraries(8ChocChip PRIVATE SDL3::SDL3 SDL3_ttf::SDL3_ttf nfd ${libname}++)

# Set the RPATH of the executable to include the directory where SFML libraries are located
set_target_properties(8ChocChip PROPERTIES
INSTALL_RPATH "$ORIGIN"
BUILD_RPATH "$ORIGIN"
)

# Copy DLLs needed for runtime on Windows
if(WIN32)
add_custom_command(
TARGET 8ChocChip
COMMENT "Copy OpenAL DLL"
PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${SFML_SOURCE_DIR}/extlibs/bin/$<IF:$<EQUAL:${CMAKE_SIZEOF_VOID_P},8>,x64,x86>/openal32.dll $<TARGET_FILE_DIR:${PROJECT_NAME}>
VERBATIM)

if (BUILD_SHARED_LIBS)
add_custom_command(TARGET 8ChocChip POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:sfml-graphics>
$<TARGET_FILE:sfml-window>
$<TARGET_FILE:sfml-system>
$<TARGET_FILE:sfml-audio>
$<TARGET_FILE_DIR:8ChocChip>)
endif()
endif()

# Copy nfd and config++ libraries to the executable directory
if (UNIX AND NOT APPLE)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
Expand Down
19 changes: 9 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
# 8ChocChip

8ChocChip is an emulator for the [Chip8](https://en.wikipedia.org/wiki/CHIP-8) software that I am working on to learn the basics around emulation.
I decided to program this in C++ because I wanted to do more in it and improve my skills.
8ChocChip is an emulator for the Chip8 software that I am working on to learn the basics around emulation.

The graphics and only library used in this is SFML which handles the window, inputs and sounds.
This uses SDL to handle graphics, input, audio and some other small things.
libconfig is used to manage config and save data files, and NativeFileDialog-extended is used for basic popup windows like the file/directory selector.

## TODO

There are a couple of things left to do until I would say it works well enough
- [x] ~~Fix some of the instructions that result in most programs failing except for `BLINKY`~~ Should be done but the test suite has issues I can not figure out how to fix. But is better than before and should work with most stuff
- [x] Proper flag compatibility unlike many out there
- [ ] Cleaner/more optimised code
- [x] Windows Support
- [ ] MacOS Support (Builds, but unable to test)
- [ ] Switch to SDL from SFML
- [x] Switch to SDL from SFML

## Usage

Expand All @@ -37,17 +36,17 @@ Some parts are just setting up ssh or installing dependencies which you may have

### Requirements

To build this it requires C++, CMake and whatever SFML and SFML Audio requires on your platform. Check build file above.
To build this it requires C++, CMake and whatever SDL/dependencies need. Check build file above.

# Credits

Thanks to these two blogs that helped me through creating this emulator
[How to Create Your Very Own Chip-8 Emulator](https://www.freecodecamp.org/news/creating-your-very-own-chip-8-emulator/)
[Guide to making a CHIP-8 emulator ](https://tobiasvl.github.io/blog/write-a-chip-8-emulator/)
Thanks to these two blogs that helped me through creating this emulator. These are actually based on a "broken" emulator guide so not everything will work. But it is good as a base and learning how to do your own research into the functionality of the emulator.
- [How to Create Your Very Own Chip-8 Emulator](https://www.freecodecamp.org/news/creating-your-very-own-chip-8-emulator/)
- [Guide to making a CHIP-8 emulator ](https://tobiasvl.github.io/blog/write-a-chip-8-emulator/)

## Libraries

Currently, three libraries are being used
- [SFML](https://github.com/SFML/SFML) - UI, graphics, input and sounds
- [SDL](https://github.com/libsdl-org/SDL) - UI, graphics, input and sounds
- [NativeFileDialog-extended](https://github.com/btzy/nativefiledialog-extended) - Handles file dialogs for selecting files/directories. Fork of [nativefiledialog](https://github.com/mlabbe/nativefiledialog) which I used a fork of that added only CMake support, this new one adds that plus new fixes/features
- [libconfig](https://github.com/hyperrealm/libconfig) - Library to manage save data (like directories that hold ROMs) and possible future config files
Binary file added assets/icon.bmp
Binary file not shown.
17 changes: 11 additions & 6 deletions dependencies/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/sfml/CMakeLists.txt")
message("${CMAKE_CURRENT_SOURCE_DIR}/sfml/CMakeLists.txt")
message(FATAL_ERROR "Please initialize submodules using:\n git submodule update --init --recursive")
add_subdirectory(nativefiledialog)

set(BUILD_EXAMPLES OFF CACHE BOOL "Disable examples for libconfig" FORCE)
set(BUILD_TESTS ON CACHE BOOL "Disable tests for libconfig" FORCE)
add_subdirectory(libconfig EXCLUDE_FROM_ALL)

if(SDL_VENDORED)
add_subdirectory(sdl EXCLUDE_FROM_ALL)
else()
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3-shared)
endif()

add_subdirectory(sfml)
add_subdirectory(nativefiledialog)
add_subdirectory(libconfig)
add_subdirectory(sdl_ttf)
2 changes: 1 addition & 1 deletion dependencies/libconfig
1 change: 1 addition & 0 deletions dependencies/sdl
Submodule sdl added at 78cc5c
1 change: 1 addition & 0 deletions dependencies/sdl_ttf
Submodule sdl_ttf added at a90b69
1 change: 0 additions & 1 deletion dependencies/sfml
Submodule sfml deleted from 69ea0c
5 changes: 2 additions & 3 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
add_subdirectory(sfml)
add_subdirectory(sdl)
add_subdirectory(util)
add_subdirectory(emulator)

target_sources(8ChocChip PUBLIC main.cpp)

target_sources(8ChocChip PUBLIC main.cpp Timer.cpp Timer.h)
67 changes: 67 additions & 0 deletions src/Timer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "Timer.h"

#include <SDL3/SDL.h>

Timer::Timer() {
this->startTicks = 0;
this->pausedTicks = 0;

this->paused = false;
this->started = false;
}

void Timer::start() {
this->started = true;
this->paused = false;

this->startTicks = SDL_GetTicks();
this->pausedTicks = 0;
}

void Timer::stop() {
this->started = false;
this->paused = false;
this->startTicks = 0;
this->pausedTicks = 0;
}

void Timer::pause() {
if(this->started && !this->paused) {
this->paused = true;

this->pausedTicks = SDL_GetTicks() - this->startTicks;
this->startTicks = 0;
}
}

void Timer::unpause() {
if(this->started && this->paused) {
this->paused = false;

this->startTicks = SDL_GetTicks() - this->pausedTicks;

this->pausedTicks = 0;
}
}

uint64_t Timer::getTicks() const {
uint64_t time = 0;

if(this->started) {
if(this->paused) {
time = this->pausedTicks;
} else {
time = SDL_GetTicks() - this->startTicks;
}
}

return time;
}

bool Timer::isStarted() const {
return this->started;
}

bool Timer::isPaused() const {
return this->paused && this->started;
}
28 changes: 28 additions & 0 deletions src/Timer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef TIMER_H
#define TIMER_H

#include <stdint.h>

class Timer {
public:
Timer();

void start();
void stop();
void pause();
void unpause();

uint64_t getTicks() const;

bool isStarted() const;
bool isPaused() const;

private:
uint64_t startTicks;
uint64_t pausedTicks;

bool paused;
bool started;
};

#endif
12 changes: 7 additions & 5 deletions src/emulator/Cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,19 +205,21 @@ void Cpu::runInstruction(const uint16_t opcode) {
break;
}
case 0xD000: {
const uint16_t width = 8;
const uint16_t height = (opcode & 0xF);

const uint8_t uX = this->registers[x];
const uint8_t uY = this->registers[y];
this->registers[0xF] = 0;

for (uint16_t row = 0; row < height; row++) {
constexpr uint16_t width = 8;
uint8_t sprite = this->memory[this->address + row];

for (uint16_t col = 0; col < width; col++) {
// If the bit (sprite) is not 0, render/erase the pixel
if ((sprite & 0x80) > 0) {
// If setPixel returns 1, which means a pixel was erased, set VF to 1
if (this->renderer->setPixel(this->registers[x] + col, this->registers[y] + row)) {
if (this->renderer->setPixel(uX + col, uY + row)) {
this->registers[0xF] = 1;
}
}
Expand All @@ -232,12 +234,12 @@ void Cpu::runInstruction(const uint16_t opcode) {
case 0xE000:
switch (opcode & 0xFF) {
case 0x9E:
if (this->keyboard->isKeyPressed(this->registers[x])) {
if (this->keyboard->isKeyPressed(this->registers[x] & 0xF)) {
this->pc += 2;
}
break;
case 0xA1:
if (!this->keyboard->isKeyPressed(this->registers[x])) {
if (!this->keyboard->isKeyPressed(this->registers[x] & 0xF)) {
this->pc += 2;
}
break;
Expand Down Expand Up @@ -269,7 +271,7 @@ void Cpu::runInstruction(const uint16_t opcode) {
this->address += this->registers[x];
break;
case 0x29:
this->address = 0x50 + this->registers[x] * 5;
this->address = 0x50 + (this->registers[x] & 0xF) * 5;
break;
case 0x33: {
uint8_t value = this->registers[x];
Expand Down
2 changes: 1 addition & 1 deletion src/emulator/Cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ class Cpu {
Speaker* speaker;
};

#endif //CPU_H
#endif
36 changes: 17 additions & 19 deletions src/emulator/Keyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ class Keyboard {
std::unordered_map<uint8_t, bool> keysPressed;
std::function<void(unsigned char)> onNextKeyPress;
std::unordered_map<uint8_t, unsigned char> KEYMAP = {
{27, 0x1}, // 1
{28, 0x2}, // 2
{29, 0x3}, // 3
{30, 0xc}, // 4
{16, 0x4}, // Q
{22, 0x5}, // W
{4, 0x6}, // E
{17, 0xD}, // R
{0, 0x7}, // A
{18, 0x8}, // S
{3, 0x9}, // D
{5, 0xE}, // F
{25, 0xA}, // Z
{23, 0x0}, // X
{2, 0xB}, // C
{21, 0xF} // V
{30, 0x1}, // 1
{31, 0x2}, // 2
{32, 0x3}, // 3
{33, 0xc}, // 4
{20, 0x4}, // Q
{26, 0x5}, // W
{8, 0x6}, // E
{21, 0xD}, // R
{4, 0x7}, // A
{22, 0x8}, // S
{7, 0x9}, // D
{9, 0xE}, // F
{29, 0xA}, // Z
{27, 0x0}, // X
{6, 0xB}, // C
{25, 0xF} // V
};

void setOnNextKeyPress(std::function<void(unsigned char)> callback);
Expand All @@ -34,6 +34,4 @@ class Keyboard {
bool isKeyPressed(int keyCode);
};



#endif //KEYBOARD_H
#endif
Loading
Loading