Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
68ee3d7
wip doom
finger563 Mar 29, 2025
ba77ff3
wip
finger563 Mar 29, 2025
bb2c089
add doom which compiles
finger563 Apr 14, 2025
dd39274
fleshing out
finger563 Apr 14, 2025
5f13861
wip audio video
finger563 Apr 14, 2025
59a17a0
working gfx display
finger563 Apr 14, 2025
56c3345
fix inputs
finger563 Apr 15, 2025
9f0274c
wip moving doom over to shared memory
finger563 Apr 17, 2025
a648fe0
wip moving more into shared memory
finger563 Apr 17, 2025
6025ac2
add boxart
finger563 Apr 17, 2025
5a72c8f
add doom ultimate boxart
finger563 Apr 17, 2025
c2e506d
update to latest tool
finger563 Apr 17, 2025
1f4d965
continue moving doom to shared memory
finger563 Apr 17, 2025
1a5fb84
move more into shared memory
finger563 Apr 17, 2025
0ac9b42
wip
finger563 Apr 17, 2025
13c833d
reduce sd card overhead and allow palette access.
finger563 Apr 17, 2025
40e40c3
abort if error
finger563 Apr 18, 2025
d9e0cd1
WIP shared memory actually working again
finger563 Apr 19, 2025
d80bc52
fix sizeof issue
finger563 Apr 19, 2025
e673647
more WIP and working shared memory
finger563 Apr 19, 2025
7f7d9d3
increase shared memory again
finger563 Apr 19, 2025
350da33
enable doom
finger563 Apr 21, 2025
9d5c714
moving more and more into shared memory
finger563 Apr 21, 2025
d2fa01e
move lcd struct and bgdup into shared memory for gbc
finger563 Apr 21, 2025
a9dce59
fix gbc
finger563 Apr 21, 2025
7509cc1
update to better work across multiple emulators
finger563 Apr 22, 2025
61c814b
fix ppu issue with palette
finger563 Apr 22, 2025
231ce43
ensure doom cart frees memory
finger563 Apr 22, 2025
d6d6b8b
bump shared memory back to 150k for Genesis emulator
finger563 Apr 22, 2025
9a655da
145k for shared memory
finger563 Apr 22, 2025
a33b854
wip using pool allocator for better memory performance accross emulat…
finger563 Apr 30, 2025
28ef4f6
update log
finger563 Apr 30, 2025
0cb1b48
update readme
finger563 May 1, 2025
8938a75
update espp
finger563 May 1, 2025
e7e4c06
ignore prboom in sa
finger563 May 1, 2025
74e7b4d
fix audio memset issue
finger563 May 1, 2025
5b9ae33
fix sound emulation in doom; update to pause sound when doom is pause…
finger563 May 1, 2025
7a41159
better reliability and working save/load game in box-emu menu
finger563 May 1, 2025
ca66ce1
update readme and improve sound a little; also make it so the game sa…
finger563 May 1, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/static_analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ jobs:
esp_idf_version: release/v5.4

# (Optional) cppcheck args
cppcheck_args: -i$GITHUB_WORKSPACE/components/gbc/gnuboy -i$GITHUB_WORKSPACE/components/nes/nofrendo -i$GITHUB_WORKSPACE/components/msx/fmsx -i$GITHUB_WORKSPACE/components/sms/smsplus -i$GITHUB_WORKSPACE/components/genesis/gwenesis -i$GITHUB_WORKSPACE/components/gui/generated -i$GITHUB_WORKSPACE/components/menu/generated -i$GITHUB_WORKSPACE/components/jpegdec --check-level=exhaustive --force --enable=all --inline-suppr --inconclusive --platform=mips32 --std=c++17 --suppressions-list=$GITHUB_WORKSPACE/suppressions.txt
cppcheck_args: -i$GITHUB_WORKSPACE/components/gbc/gnuboy -i$GITHUB_WORKSPACE/components/nes/nofrendo -i$GITHUB_WORKSPACE/components/msx/fmsx -i$GITHUB_WORKSPACE/components/doom/prboom -i$GITHUB_WORKSPACE/components/sms/smsplus -i$GITHUB_WORKSPACE/components/genesis/gwenesis -i$GITHUB_WORKSPACE/components/gui/generated -i$GITHUB_WORKSPACE/components/menu/generated -i$GITHUB_WORKSPACE/components/jpegdec --check-level=exhaustive --force --enable=all --inline-suppr --inconclusive --platform=mips32 --std=c++17 --suppressions-list=$GITHUB_WORKSPACE/suppressions.txt
8 changes: 4 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ set(GBC_COMPONENTS "gbc")
### SMS ###
set(SMS_COMPONENTS "sms")

### SNES ###
# set(SNES_COMPONENTS "snes")

### MSX ###
set(MSX_COMPONENTS "msx")

### GENESIS ###
set(GENESIS_COMPONENTS "genesis")

### DOOM ###
# set(DOOM_COMPONENTS "doom")
set(DOOM_COMPONENTS "doom")

### SNES ###
# set(SNES_COMPONENTS "snes")

add_compile_definitions(BOARD_HAS_PSRAM)

Expand Down
40 changes: 39 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,32 @@
</tr>
</table>

![image](https://github.com/user-attachments/assets/209ed9aa-22f0-4ee0-9868-65abb1b64bbc)

https://github.com/user-attachments/assets/2d3da6ea-2e80-42c3-bbd6-5a2c59601201

<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->
**Table of Contents**

- [esp-box-emu](#esp-box-emu)
- [Overview](#overview)
- [Images and Videos](#images-and-videos)
- [Parts](#parts)
- [Features](#features)
- [Cloning](#cloning)
- [Build and Flash](#build-and-flash)
- [Rom Setup and Configuration (uSD Card)](#rom-setup-and-configuration-usd-card)
- [ROM Images](#rom-images)
- [Metadata.csv format](#metadatacsv-format)
- [References and Inspiration:](#references-and-inspiration)
- [Other NES Emulators](#other-nes-emulators)
- [Other Genesis Emulators](#other-genesis-emulators)
- [Useful Background / Information](#useful-background--information)

<!-- markdown-toc end -->

## Overview

The ESP-BOX-EMU is a gameboy-inspired add-on for the ESP32-S3-BOX and
ESP32-S3-BOX-3 which provides:
- Game Controller (gamepad input with a/b/x/y, start/select, d-pad)
Expand All @@ -30,16 +56,27 @@ ESP32-S3-BOX-3 which provides:
- Unlocked mode (fastest execution), toggled with the X button
- Genesis emulator (gwenesis) - full speed / buttery smooth when muted; unmuted it runs a little slower but has nice sound
- Regular Controls (D-Pad/A/B/C/Start/Select) (note: A is mapped to B, B is mapped to A, and C is mapped to Y)
- Doom engine (prboom) - full speed with audio and control inputs. A is fire/enter, B is strafe/backspace, X is use, Y is weapontoggle, START is escape, and SELECT is map.
- LVGL main menu with rom select (including boxart display) and settings page
(all generated from Squareline Studio)
- LVGL emulation paused menu with save slot select, save slot image display,
and configuration (sound, brightness, display, etc.). (all generated from
Squareline Studio)

## Images and Videos

![image](https://github.com/user-attachments/assets/d867d5fa-4c22-42e3-b04f-1edd5288c5d2)
![image](https://github.com/user-attachments/assets/ad892905-37d4-4e16-8d5f-a7ff8d2a2c52)
![image](https://github.com/user-attachments/assets/b141daab-2cda-481c-98c2-980b012f177e)

![image](https://github.com/user-attachments/assets/d23659b6-10d4-4375-8017-675e156a1a4b)

https://github.com/esp-cpp/esp-box-emu/assets/213467/3b77f6bd-4c42-417a-9eb7-a648f31b4008

https://github.com/esp-cpp/esp-box-emu/assets/213467/a3d18d03-c6a1-4911-89d1-e18119e8cc03

## Parts

This project is designed to be in the same form factor as the Gameboy Color and
to reuse the same button plastics and membranes for a good play feel.

Expand Down Expand Up @@ -84,8 +121,9 @@ This project has the following features (still WIP):
- [x] Sega Master System (SMS) / GameGear (GG) emulator
- [x] MSX emulator
- [x] Sega Mega Drive / Genesis emulator
- [x] Doom
- [ ] Dark Forces (WIP)
- [ ] SNES emulator (WIP)
- [ ] Doom (WIP)
- [x] uSD card (FAT) filesystem over SPI
- [x] TinyUSB MSC device for optionally exposing the uSD to the attached USB host
- [x] Memory mapping of selected rom data from storage into raw data partition
Expand Down
Binary file added boxart/doom_2_boxart.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added boxart/doom_boxart.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added boxart/doom_ultimate_boxart.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added boxart/source/doom_2_boxart.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added boxart/source/doom_boxart.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added boxart/source/doom_ultimate_boxart.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion boxart/source/resize.bash
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#!/bin/bash
find . -maxdepth 1 -iname "*.jpg" | xargs -L1 -I{} convert -resize 100x "{}" ../"{}"
find . -maxdepth 1 -iname "*.jpg" | xargs -L1 -I{} magick -quiet "{}" -resize 100x ../"{}"
1 change: 1 addition & 0 deletions components/box-emu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ idf_component_register(
"statistics"
"max1704x"
"esp-box"
"pool_allocator"
)
4 changes: 3 additions & 1 deletion components/box-emu/include/box-emu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "video_setting.hpp"

#include "make_color.h"
#include "pool_allocator.h"

class BoxEmu : public espp::BaseComponent {
public:
Expand Down Expand Up @@ -126,6 +127,7 @@ class BoxEmu : public espp::BaseComponent {
/////////////////////////////////////////////////////////////////////////////

bool initialize_memory();
void deinitialize_memory();
size_t copy_file_to_romdata(const std::string& filename);
uint8_t *romdata() const;

Expand Down Expand Up @@ -154,6 +156,7 @@ class BoxEmu : public espp::BaseComponent {
void clear_screen();
void display_size(size_t width, size_t height);
void native_size(size_t width, size_t height, int pitch = -1);
const uint16_t *palette() const;
void palette(const uint16_t *palette, size_t size = 256);
void push_frame(const void* frame);
VideoSetting video_setting() const;
Expand Down Expand Up @@ -185,7 +188,6 @@ class BoxEmu : public espp::BaseComponent {
bool is_native() const;
int x_offset() const;
int y_offset() const;
const uint16_t *palette() const;
bool video_task_callback(std::mutex &m, std::condition_variable &cv, bool &task_notified);

class InputBase {
Expand Down
18 changes: 14 additions & 4 deletions components/box-emu/src/box-emu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ bool BoxEmu::initialize_sdcard() {
memset(&mount_config, 0, sizeof(mount_config));
mount_config.format_if_mount_failed = false;
mount_config.max_files = 5;
mount_config.allocation_unit_size = 16 * 1024;
mount_config.allocation_unit_size = 2 * 1024;

// Use settings defined above to initialize SD card and mount FAT filesystem.
// Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions.
Expand All @@ -136,7 +136,7 @@ bool BoxEmu::initialize_sdcard() {
bus_cfg.sclk_io_num = sdcard_sclk;
bus_cfg.quadwp_io_num = -1;
bus_cfg.quadhd_io_num = -1;
bus_cfg.max_transfer_sz = 8192;
bus_cfg.max_transfer_sz = 4096;
spi_host_device_t host_id = (spi_host_device_t)host.slot;
ret = spi_bus_initialize(host_id, &bus_cfg, SDSPI_DEFAULT_DMA);
if (ret != ESP_OK) {
Expand Down Expand Up @@ -182,6 +182,8 @@ sdmmc_card_t *BoxEmu::sdcard() const {
// Memory
/////////////////////////////////////////////////////////////////////////////

static constexpr size_t memory_size = 4*1024*1024;

extern "C" uint8_t *osd_getromdata() {
auto &emu = BoxEmu::get();
return emu.romdata();
Expand All @@ -195,7 +197,7 @@ bool BoxEmu::initialize_memory() {

logger_.info("Initializing memory (romdata)");
// allocate memory for the ROM and make sure it's on the SPIRAM
romdata_ = (uint8_t*)heap_caps_malloc(4*1024*1024, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
romdata_ = (uint8_t*)heap_caps_malloc(memory_size, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
if (romdata_ == nullptr) {
logger_.error("Couldn't allocate memory for ROM!");
return false;
Expand All @@ -204,6 +206,14 @@ bool BoxEmu::initialize_memory() {
return true;
}

void BoxEmu::deinitialize_memory() {
if (romdata_) {
logger_.info("Deinitializing memory (romdata)");
free(romdata_);
romdata_ = nullptr;
}
}

size_t BoxEmu::copy_file_to_romdata(const std::string& filename) {
// load the file data and iteratively copy it over
std::ifstream romfile(filename, std::ios::binary | std::ios::ate); //open file at end
Expand Down Expand Up @@ -648,7 +658,7 @@ bool BoxEmu::initialize_usb() {
.mount_config = {
.format_if_mount_failed = false,
.max_files = 5,
.allocation_unit_size = 16 * 1024, // sector size is 512 bytes, this should be between sector size and (128 * sector size). Larger means higher read/write performance and higher overhead for small files.
.allocation_unit_size = 2 * 1024, // sector size is 512 bytes, this should be between sector size and (128 * sector size). Larger means higher read/write performance and higher overhead for small files.
.disk_status_check_enable = false, // true if you see issues or are unmounted properly; slows down I/O
},
};
Expand Down
15 changes: 15 additions & 0 deletions components/doom/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
idf_component_register(
INCLUDE_DIRS "include"
SRC_DIRS "src" "prboom"
PRIV_INCLUDE_DIRS "." "prboom"
REQUIRES box-emu shared_memory
)
target_compile_options(${COMPONENT_LIB} PRIVATE
-Wno-error=address
-Wno-misleading-indentation
-Wno-format-overflow
-Wno-char-subscripts
-Wno-missing-field-initializers
-DHAVE_CONFIG_H
-O2
)
Binary file added components/doom/data/doom1.wad
Binary file not shown.
Binary file added components/doom/data/prboom.wad
Binary file not shown.
17 changes: 17 additions & 0 deletions components/doom/include/doom.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include <span>
#include <string>
#include <string_view>
#include <vector>

void reset_doom();
void init_doom(const std::string& rom_filename, uint8_t *romdata, size_t rom_data_size);
void doom_init_shared_memory();
void pause_doom_tasks();
void resume_doom_tasks();
void load_doom(std::string_view save_path, int save_slot);
void save_doom(std::string_view save_path, int save_slot);
void run_doom_rom();
void deinit_doom();
std::span<uint8_t> get_doom_video_buffer();
8 changes: 8 additions & 0 deletions components/doom/linker.lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Move gbc code into IRAM for perforamnce
[mapping:doom]
archive: libdoom.a
entries:
d_main (noflash_text)
r_draw (noflash_text)
g_game (noflash_text)
m_misc (noflash_text)
Loading