Skip to content

Commit 6f2b4b6

Browse files
Implement PICO-8 emulator with shared memory and ESP32 optimizations
Co-authored-by: waemfinger <waemfinger@gmail.com>
1 parent a193278 commit 6f2b4b6

File tree

5 files changed

+1018
-309
lines changed

5 files changed

+1018
-309
lines changed

FORK_SETUP_GUIDE.md

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
# esp-cpp/femto8 Fork Setup Guide
2+
3+
This guide explains how to set up and manage the `esp-cpp/femto8` fork for PICO-8 emulator integration.
4+
5+
## Fork Creation
6+
7+
### 1. Create the Fork
8+
```bash
9+
# Fork benbaker76/femto8 to esp-cpp/femto8 via GitHub UI
10+
# Or use GitHub CLI:
11+
gh repo fork benbaker76/femto8 --org esp-cpp --fork-name femto8
12+
```
13+
14+
### 2. Clone and Setup Local Repository
15+
```bash
16+
git clone https://github.com/esp-cpp/femto8.git
17+
cd femto8
18+
git remote add upstream https://github.com/benbaker76/femto8.git
19+
```
20+
21+
### 3. Create ESP32 Integration Branch
22+
```bash
23+
# Create branch for ESP32-specific modifications
24+
git checkout -b esp32-integration
25+
git push -u origin esp32-integration
26+
27+
# Create branch for shared_memory integration
28+
git checkout -b shared-memory-integration
29+
git push -u origin shared-memory-integration
30+
31+
# Create branch specifically for esp-box-emu
32+
git checkout -b esp-box-emu-integration
33+
git push -u origin esp-box-emu-integration
34+
```
35+
36+
## Integration with esp-box-emu
37+
38+
### 1. Copy Source to Component
39+
```bash
40+
# From esp-box-emu root directory
41+
cd components/pico8
42+
43+
# Clone our fork temporarily
44+
git clone https://github.com/esp-cpp/femto8.git temp_femto8
45+
cd temp_femto8
46+
git checkout esp-box-emu-integration # Use our integration branch
47+
48+
# Copy source files
49+
cd ..
50+
mkdir -p femto8/src femto8/include
51+
cp -r temp_femto8/src/* femto8/src/
52+
cp -r temp_femto8/include/* femto8/include/
53+
54+
# Clean up
55+
rm -rf temp_femto8
56+
57+
# Add to git
58+
git add femto8/
59+
git commit -m "Add femto8 source for PICO-8 emulator"
60+
```
61+
62+
### 2. Apply ESP32-Specific Modifications
63+
64+
#### Memory Management Integration
65+
Create `femto8/src/pico8_esp32_memory.c`:
66+
```c
67+
#ifdef FEMTO8_SHARED_MEMORY
68+
#include "shared_memory.hpp"
69+
70+
static uint8_t* pico8_memory_pool = NULL;
71+
static size_t pico8_memory_pool_size = 0;
72+
73+
// Memory allocation hooks for SharedMemory integration
74+
void* pico8_malloc(size_t size, const char* tag) {
75+
return SharedMemory::get().allocate(size, tag);
76+
}
77+
78+
void pico8_free(void* ptr, const char* tag) {
79+
SharedMemory::get().deallocate((uint8_t*)ptr, tag);
80+
}
81+
82+
// Initialize memory system
83+
int pico8_init_memory_system(size_t total_size) {
84+
pico8_memory_pool = SharedMemory::get().allocate(total_size, "pico8_pool");
85+
if (!pico8_memory_pool) {
86+
return -1;
87+
}
88+
pico8_memory_pool_size = total_size;
89+
return 0;
90+
}
91+
92+
void pico8_deinit_memory_system(void) {
93+
if (pico8_memory_pool) {
94+
SharedMemory::get().deallocate(pico8_memory_pool, "pico8_pool");
95+
pico8_memory_pool = NULL;
96+
pico8_memory_pool_size = 0;
97+
}
98+
}
99+
#endif
100+
```
101+
102+
#### Performance Optimizations
103+
Modify critical functions in femto8 source files:
104+
```c
105+
// Add to femto8/src/pico8_cpu.c
106+
#ifdef FEMTO8_ESP32
107+
#include "esp_attr.h"
108+
#define PICO8_FAST_FUNC IRAM_ATTR
109+
#else
110+
#define PICO8_FAST_FUNC
111+
#endif
112+
113+
// Apply to performance-critical functions
114+
PICO8_FAST_FUNC void pico8_cpu_step(void) {
115+
// ... existing implementation
116+
}
117+
118+
PICO8_FAST_FUNC void pico8_render_scanline(int line) {
119+
// ... existing implementation
120+
}
121+
```
122+
123+
#### Configuration Header
124+
Create `femto8/include/pico8_esp32_config.h`:
125+
```c
126+
#ifndef PICO8_ESP32_CONFIG_H
127+
#define PICO8_ESP32_CONFIG_H
128+
129+
#ifdef FEMTO8_ESP32
130+
// ESP32-specific configuration
131+
#define PICO8_SAMPLE_RATE 22050
132+
#define PICO8_AUDIO_BUFFER_SIZE 512
133+
#define PICO8_MAX_CARTRIDGE_SIZE 32768
134+
#define PICO8_RAM_SIZE 32768
135+
#define PICO8_VRAM_SIZE 16384
136+
137+
// Use ESP32 timer functions
138+
#include "esp_timer.h"
139+
#define PICO8_GET_TIME_US() esp_timer_get_time()
140+
141+
// Use ESP32 memory functions
142+
#ifdef FEMTO8_SHARED_MEMORY
143+
#define PICO8_MALLOC(size, tag) pico8_malloc(size, tag)
144+
#define PICO8_FREE(ptr, tag) pico8_free(ptr, tag)
145+
#else
146+
#define PICO8_MALLOC(size, tag) malloc(size)
147+
#define PICO8_FREE(ptr, tag) free(ptr)
148+
#endif
149+
150+
#else
151+
// Default configuration for other platforms
152+
#define PICO8_SAMPLE_RATE 44100
153+
#define PICO8_AUDIO_BUFFER_SIZE 1024
154+
// ... other defaults
155+
#endif
156+
157+
#endif // PICO8_ESP32_CONFIG_H
158+
```
159+
160+
## Maintenance Strategy
161+
162+
### 1. Sync with Upstream
163+
```bash
164+
# Periodically sync with original femto8
165+
git checkout main
166+
git fetch upstream
167+
git merge upstream/main
168+
git push origin main
169+
170+
# Rebase our integration branches
171+
git checkout esp32-integration
172+
git rebase main
173+
git push --force-with-lease origin esp32-integration
174+
```
175+
176+
### 2. Update esp-box-emu Integration
177+
```bash
178+
# When femto8 changes, update the copied source
179+
cd components/pico8
180+
181+
# Get latest from our integration branch
182+
git clone https://github.com/esp-cpp/femto8.git temp_femto8
183+
cd temp_femto8
184+
git checkout esp-box-emu-integration
185+
186+
# Update source files
187+
cd ..
188+
rm -rf femto8/src/* femto8/include/*
189+
cp -r temp_femto8/src/* femto8/src/
190+
cp -r temp_femto8/include/* femto8/include/
191+
rm -rf temp_femto8
192+
193+
# Commit changes
194+
git add femto8/
195+
git commit -m "Update femto8 source to latest version"
196+
```
197+
198+
### 3. Branch Management
199+
- **main**: Sync with upstream benbaker76/femto8
200+
- **esp32-integration**: ESP32-specific optimizations
201+
- **shared-memory-integration**: SharedMemory component integration
202+
- **esp-box-emu-integration**: Final integration branch for esp-box-emu
203+
204+
## Modification Tracking
205+
206+
### Key Files to Modify
207+
1. **Memory Management**:
208+
- `src/pico8_memory.c` - Replace malloc/free calls
209+
- `src/pico8_lua.c` - Lua heap management
210+
- `include/pico8_config.h` - Memory configuration
211+
212+
2. **Performance**:
213+
- `src/pico8_cpu.c` - Add IRAM attributes
214+
- `src/pico8_gfx.c` - Graphics rendering optimizations
215+
- `src/pico8_sound.c` - Audio processing optimizations
216+
217+
3. **Integration**:
218+
- `include/pico8.h` - Main API header
219+
- `src/pico8_api.c` - Public API implementation
220+
- `include/pico8_esp32_config.h` - ESP32 configuration
221+
222+
### Documentation of Changes
223+
Maintain a `MODIFICATIONS.md` file in the fork:
224+
```markdown
225+
# ESP32 Modifications to femto8
226+
227+
## Memory Management
228+
- Replaced malloc/free with SharedMemory integration
229+
- Added configurable memory pool sizes
230+
- Implemented memory tracking and debugging
231+
232+
## Performance Optimizations
233+
- Added IRAM attributes to critical functions
234+
- Optimized memory copy operations for ESP32
235+
- Reduced dynamic allocations in hot paths
236+
237+
## ESP-IDF Integration
238+
- Added ESP32 timer support
239+
- Integrated with ESP-IDF build system
240+
- Added ESP32-specific configuration options
241+
```
242+
243+
## Testing the Fork
244+
245+
### 1. Basic Compilation Test
246+
```bash
247+
# Test compilation with ESP-IDF
248+
cd components/pico8
249+
idf.py build
250+
```
251+
252+
### 2. Memory Integration Test
253+
```cpp
254+
// Test SharedMemory integration
255+
#include "pico8.hpp"
256+
#include "shared_memory.hpp"
257+
258+
void test_pico8_memory() {
259+
// Initialize PICO-8 with test cartridge
260+
const uint8_t test_cart[] = { /* minimal PICO-8 cart */ };
261+
init_pico8("test.p8", test_cart, sizeof(test_cart));
262+
263+
// Verify memory allocations
264+
auto stats = SharedMemory::get().get_stats();
265+
// Check that pico8_ram, pico8_vram, etc. are allocated
266+
267+
deinit_pico8();
268+
269+
// Verify cleanup
270+
auto stats_after = SharedMemory::get().get_stats();
271+
// Check that memory was properly deallocated
272+
}
273+
```
274+
275+
### 3. Performance Test
276+
```cpp
277+
// Test frame rate performance
278+
void test_pico8_performance() {
279+
init_pico8("test.p8", test_cart, sizeof(test_cart));
280+
281+
auto start_time = esp_timer_get_time();
282+
for (int i = 0; i < 60; i++) {
283+
run_pico8_frame();
284+
}
285+
auto end_time = esp_timer_get_time();
286+
287+
uint32_t frame_time_us = (end_time - start_time) / 60;
288+
printf("Average frame time: %d us\n", frame_time_us);
289+
// Should be close to 16667 us (60 FPS)
290+
291+
deinit_pico8();
292+
}
293+
```
294+
295+
## Contributing Back to Upstream
296+
297+
### 1. Identify Generic Improvements
298+
Some modifications may be useful for the upstream project:
299+
- Bug fixes
300+
- Performance improvements that don't depend on ESP32
301+
- API enhancements
302+
303+
### 2. Create Upstream PRs
304+
```bash
305+
# Create branch for upstream contribution
306+
git checkout main
307+
git checkout -b feature/performance-improvements
308+
309+
# Cherry-pick generic improvements
310+
git cherry-pick <commit-hash>
311+
312+
# Push and create PR to benbaker76/femto8
313+
git push origin feature/performance-improvements
314+
```
315+
316+
## Conclusion
317+
318+
This fork management strategy provides:
319+
- **Full control** over femto8 source for ESP32 integration
320+
- **Easy maintenance** with clear branching strategy
321+
- **Upstream compatibility** for contributing improvements back
322+
- **Integration simplicity** with direct source copying
323+
- **Performance optimization** opportunities
324+
325+
The approach ensures we can make necessary modifications while maintaining the ability to sync with upstream improvements and contribute back to the femto8 project.

0 commit comments

Comments
 (0)