diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..1f0398c --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,120 @@ +name: Build and Release + +on: + push: + branches: + - master + +jobs: + build-ubuntu: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Install dependencies + run: | + sudo apt-get update && sudo apt-get install -y cmake libsfml-dev libudev-dev libopenal-dev libvorbis-dev libflac-dev libxrandr-dev libxcursor-dev + + - name: Configure and build + run: | + mkdir build && cd build + cmake .. + cmake --build . + + - name: Upload executable + uses: actions/upload-artifact@v2 + with: + name: ubuntu-executable + path: build/src/8ChocChip + + # build-windows: + # runs-on: ubuntu-latest + # strategy: + # matrix: + # arch: [x64, x86] # Target architectures for Windows EXE + + # steps: + # - uses: actions/checkout@v3 + + # - name: Install dependencies (SFML, build tools) + # run: | + # sudo apt-get update && sudo apt-get install -y \ + # build-essential \ + # cmake \ + # gcc-multilib \ + # g++-multilib \ + # libtool \ + # pkg-config \ + # libsfml-dev \ + # libudev-dev \ + # libopenal-dev \ + # libvorbis-dev \ + # libflac-dev \ + # libxrandr-dev \ + # libxcursor-dev + + # - name: Configure build environment for target architecture + # run: | + # export TARGET_ARCH=${{ matrix.arch }} + # case $TARGET_ARCH in + # x64) + # # Set compiler and linker for 64-bit Windows target + # export TOOLCHAIN=$(command -v x86_64-w64-mingw32-g++-posix) + # ;; + # x86) + # # Set compiler and linker for 32-bit Windows target + # export TOOLCHAIN=$(command -v i686-w64-mingw32-g++-posix) + # ;; + # *) + # echo "Unsupported architecture: $TARGET_ARCH" + # exit 1 + # ;; + # esac + # echo "Using compiler: $TOOLCHAIN" + + # - name: Create build directory + # run: mkdir build + + # - name: Configure CMake (cross-compiling) + # env: + # CMAKE_C_COMPILER: $TOOLCHAIN + # CMAKE_CXX_COMPILER: $TOOLCHAIN + # working-directory: build + # run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=Release -DSFML_DIR=/usr/lib/x86_64-linux-gnu/pkgconfig/SFML.pc # (or adjust for your SFML installation path) + + # - name: Build + # working-directory: build + # run: cmake --build . --config Release + + # - name: Archive Windows EXEs (recursive) + # if: success() # Only run if previous steps succeed + # uses: actions/upload-artifact@v3 + # with: + # name: windows-exe # Generic name (you can customize) + # path: build/**/*.exe # Capture all .exe files recursively + + + + # build-macos: + # runs-on: macos-latest + + # steps: + # - name: Checkout code + # uses: actions/checkout@v2 + + # - name: Install dependencies + # run: brew update && brew install cmake sfml + + # - name: Configure and build + # run: | + # mkdir build && cd build + # cmake .. + # cmake --build . + + # - name: Upload executable + # uses: actions/upload-artifact@v2 + # with: + # name: macos-executable + # path: build/src/8ChocChip diff --git a/CMakeLists.txt b/CMakeLists.txt index 44ee93a..7cadfde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,5 +3,10 @@ project(8ChocChip LANGUAGES CXX VERSION 0.1) +# Set the path to the vcpkg toolchain file for Windows +if(WIN32) + set(CMAKE_TOOLCHAIN_FILE "C:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "Vcpkg toolchain file") +endif() + add_subdirectory(dependencies) add_subdirectory(src) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d566ca9..e5c8a80 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,4 +7,15 @@ add_executable(8ChocChip main.cpp Renderer.h Cpu.cpp Cpu.h) -target_link_libraries(8ChocChip PRIVATE sfml-graphics sfml-audio) \ No newline at end of file +target_link_libraries(8ChocChip PRIVATE sfml-graphics sfml-audio) + +if (WIN32) + foreach (SFML_LIB ${SFML_LIBRARIES}) + get_filename_component(SFML_LIB_DIR ${SFML_LIB} DIRECTORY) + file(GLOB SFML_DLLS "${SFML_LIB_DIR}/*.dll") + foreach (SFML_DLL ${SFML_DLLS}) + add_custom_command(TARGET 8ChocChip POST_BUILD COMMAND + ${CMAKE_COMMAND} -E copy_if_different ${SFML_DLL} $) + endforeach() + endforeach() +endif() diff --git a/src/Cpu.cpp b/src/Cpu.cpp index b192094..4abe48a 100644 --- a/src/Cpu.cpp +++ b/src/Cpu.cpp @@ -20,7 +20,7 @@ Cpu::Cpu(Renderer* renderer, Keyboard* keyboard, Speaker* speaker) { } void Cpu::loadSpritesIntoMemory() { - std::vector sprites = { + const std::vector sprites = { 0xF0, 0x90, 0x90, 0x90, 0xF0, // 0 0x20, 0x60, 0x20, 0x20, 0x70, // 1 0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2 @@ -39,19 +39,18 @@ void Cpu::loadSpritesIntoMemory() { 0xF0, 0x80, 0xF0, 0x80, 0x80 // F }; - for (int i = 0; i < sprites.size(); i++) { - this->memory[i] = sprites[i]; + for (unsigned char sprite : sprites) { + this->memory.push_back(sprite); } } -void Cpu::loadProgramIntoMemory(const char *filename) { - std::ifstream file(filename, std::ios::binary | std::ios::ate); - if (file.is_open()) { - std::streampos size = file.tellg(); +void Cpu::loadProgramIntoMemory(std::ifstream* file) { + if (file->is_open()) { + std::streampos size = file->tellg(); std::vector buffer(size); - file.seekg(0, std::ios::beg); - file.read(buffer.data(), size); - file.close(); + file->seekg(0, std::ios::beg); + file->read(buffer.data(), size); + file->close(); // Load ROM into memory std::copy(buffer.begin(), buffer.end(), this->memory.begin() + 0x200); @@ -62,7 +61,7 @@ void Cpu::cycle() { for (int i = 0; i < this->speed; i++) { if (this->paused) continue; - u_int16_t opcode = (this->memory[this->pc] << 8 | this->memory[this->pc + 1]); + uint16_t opcode = (this->memory[this->pc] << 8 | this->memory[this->pc + 1]); runInstruction(opcode); } @@ -78,11 +77,11 @@ void Cpu::cycle() { } } -void Cpu::runInstruction(u_int16_t opcode) { +void Cpu::runInstruction(uint16_t opcode) { this->pc += 2; - u_int8_t x = (opcode & 0x0F00) >> 8; - u_int8_t y = (opcode & 0x00F0) >> 4; + uint8_t x = (opcode & 0x0F00) >> 8; + uint8_t y = (opcode & 0x00F0) >> 4; switch (opcode & 0xF000) { case 0x0000: @@ -143,7 +142,7 @@ void Cpu::runInstruction(u_int16_t opcode) { this->registers[x] ^= this->registers[y]; break; case 0x4: { - const u_int16_t sum = this->registers[x] += this->registers[y]; + const uint16_t sum = this->registers[x] += this->registers[y]; this->registers[0xF] = 0; @@ -199,12 +198,12 @@ void Cpu::runInstruction(u_int16_t opcode) { case 0xC000: { std::random_device rd; std::mt19937 gen(rd()); - std::uniform_int_distribution dis(0, 0xFF); + std::uniform_int_distribution dis(0, 0xFF); - // Generate a random number - const uint16_t rand_num = dis(gen); + int randInt = dis(gen); // Generate a random number + uint16_t rand = static_cast(randInt); - this->registers[x] = rand_num & (opcode & 0xFF); + this->registers[x] = rand & (opcode & 0xFF); break; } case 0xD000: { diff --git a/src/Cpu.h b/src/Cpu.h index 18bb5ae..de070cb 100644 --- a/src/Cpu.h +++ b/src/Cpu.h @@ -12,26 +12,27 @@ #include "Keyboard.h" #include "Speaker.h" #include "Renderer.h" +#include class Cpu { public: Cpu(Renderer* renderer, Keyboard* keyboard, Speaker* speaker); void loadSpritesIntoMemory(); - void loadProgramIntoMemory(const char *filename); + void loadProgramIntoMemory(std::ifstream* file); void cycle(); - void runInstruction(u_int16_t opcode); + void runInstruction(uint16_t opcode); void updateTimers(); private: - std::vector memory; - std::vector registers; - u_int16_t address; - u_int8_t delay; - u_int8_t soundTimer; - - u_int16_t pc; - std::vector stack; + std::vector memory; + std::vector registers; + uint16_t address; + uint8_t delay; + uint8_t soundTimer; + + uint16_t pc; + std::vector stack; bool paused; int8_t speed; diff --git a/src/Keyboard.h b/src/Keyboard.h index cdf3956..1c21e84 100644 --- a/src/Keyboard.h +++ b/src/Keyboard.h @@ -9,6 +9,7 @@ #include #include #include +#include class Keyboard { public: diff --git a/src/Renderer.h b/src/Renderer.h index 5a233f8..e6de206 100644 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -7,6 +7,7 @@ #include #include +#include class Renderer { public: diff --git a/src/main.cpp b/src/main.cpp index eb2c436..7982e4b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,7 @@ #include "Keyboard.h" #include "Renderer.h" #include "Speaker.h" +#include "fstream" int main(int argc, char** argv) { @@ -14,7 +15,8 @@ int main(int argc, char** argv) return 1; } - if (std::filesystem::exists(argv[1])) { + std::ifstream file(argv[1], std::ios::binary | std::ios::ate); + if (file.good()) { std::cout << argv[1] << std::endl; } else { std::cerr << "Can not find file" << std::endl; @@ -28,7 +30,7 @@ int main(int argc, char** argv) cpu.loadSpritesIntoMemory(); - cpu.loadProgramIntoMemory(argv[1]); + cpu.loadProgramIntoMemory(&file); sf::RenderWindow window(sf::VideoMode(renderer.getColumns() * renderer.getScale(), renderer.getRows() * renderer.getScale()), "CHIP-8 Emulator", sf::Style::Titlebar | sf::Style::Close); // TODO: Add icon - window.setIcon();