Commit graph

16 commits

Author SHA1 Message Date
8c3128e29c WASM Python integration milestone - game.py runs in browser
Major milestone for issue #158 (Emscripten/WebAssembly build target):
- Python 3.14 successfully initializes and runs in WASM
- mcrfpy module loads and works correctly
- Game scripts execute with full level generation
- Entities (boulders, rats, cyclops, spawn points) placed correctly

Key changes:
- CMakeLists.txt: Add 2MB stack, Emscripten link options, preload files
- platform.h: Add WASM-specific implementations for executable paths
- HeadlessTypes.h: Make Texture/Font/Sound stubs return success
- CommandLineParser.cpp: Guard filesystem operations for WASM
- McRFPy_API.cpp: Add WASM path configuration, debug output
- game.py: Make 'code' module import optional (not available in WASM)
- wasm_stdlib/: Add minimal Python stdlib for WASM (~4MB)

Build with: emmake make (from build-emscripten/)
Test with: node mcrogueface.js

Next steps:
- Integrate VRSFML for actual WebGL rendering
- Create HTML page to host WASM build
- Test in actual browsers

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 05:15:11 -05:00
07fd12373d First successful Emscripten/WASM build for #158
Build produces mcrogueface.wasm (8.9MB) + mcrogueface.js (126KB):
- All 68 C++ source files compile with emcc
- Links Python 3.14 (wasm32-emscripten target)
- Links libtcod-headless (built for Emscripten)
- Uses Emscripten ports: zlib, bzip2, sqlite3
- Includes HACL crypto, expat, mpdec, ffi dependencies

CMakeLists.txt updates:
- Add HACL .o files (not included in libpython3.14.a)
- Add expat, mpdec, ffi static libraries from Python build
- Add libtcod WASM build with lodepng and utf8proc
- Add Emscripten port link options

libtcod-headless submodule updated with Emscripten build.

Next: Bundle Python stdlib into WASM filesystem.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 00:34:11 -05:00
3bd996f317 Add Emscripten Python 3.14 WASM integration to CMake
Major progress on Emscripten build:
- Built Python 3.14.2 for wasm32-emscripten using official Tools/wasm/emscripten
- Add EMSCRIPTEN detection with proper Python headers from cross-build
- Force MCRF_HEADLESS for Emscripten builds (no SFML yet)
- Link against libpython3.14.a (47MB WASM static lib)

Result: ALL 68 C++ source files compile successfully with emcc!
Only blocker remaining: libtcod needs WASM compilation

Build verified:
- Python LONG_BIT errors: FIXED (using wasm32-emscripten pyconfig.h)
- Source compilation: 100% success
- Link stage: fails on libtcod.so (next step)

Contributes to #158

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 00:23:28 -05:00
4c70aee020 Add proper CMake MCRF_HEADLESS option for headless builds
- Add option(MCRF_HEADLESS) to CMakeLists.txt for official headless support
- Conditional compilation: skip ImGui sources when headless
- Conditional linking: no SFML/OpenGL libraries in headless mode
- Auto-define MCRF_HEADLESS preprocessor flag

Verified:
- Zero SFML/OpenGL dynamic dependencies (ldd confirms)
- Python interpreter fully functional in headless mode
- Core mcrfpy types work: Vector, Color, Scene, Frame, Grid
- Binary size: 1.6 MB headless vs 2.5 MB normal (36% reduction)

Build with: cmake .. -DMCRF_HEADLESS=ON

Contributes to #158

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 23:32:59 -05:00
a81430991c libtcod as SYSTEM include, to ignore deprecations 2026-01-11 20:44:46 -05:00
1438044c6a mingw toolchain and final fixes for Windows. Closes #162 2026-01-08 21:16:27 -05:00
1f002e820c long -> intptr_t for casts. WIP: mingw cross-compilation for Windows (see #162) 2026-01-08 10:41:24 -05:00
3f6ea4fe33 feat: Add ImGui-based developer console overlay
Integrates Dear ImGui for an in-game debug console that replaces the
blocking Python REPL. Press ~ (grave/tilde) to toggle the console.

Features:
- Python code execution without blocking the game loop
- Output capture with color coding (yellow=input, red=errors, gray=output)
- Expression results show repr() automatically
- Command history navigation with up/down arrows
- Word wrapping for long output lines
- Auto-scroll that doesn't fight manual scrolling
- mcrfpy.setDevConsole(bool) API to disable for shipping

Technical changes:
- Update imgui submodule to v1.89.9 (stable)
- Update imgui-sfml submodule to 2.6.x branch (SFML 2.x compatible)
- Add ImGui sources to CMakeLists.txt with OpenGL dependency
- Integrate ImGui lifecycle into GameEngine
- Add ImGuiConsole class for console overlay

closes #36, closes #65, closes #75

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 20:03:58 -05:00
28396b65c9 feat: Migrate to Python 3.14 (closes #135)
Replace deprecated Python C API calls with modern PyConfig-based initialization:
- PySys_SetArgvEx() -> PyConfig.argv (deprecated since 3.11)
- Py_InspectFlag -> PyConfig.inspect (deprecated since 3.12)

Fix critical memory safety bugs discovered during migration:
- PyColor::from_arg() and PyVector::from_arg() now return new references
  instead of borrowed references, preventing use-after-free when callers
  call Py_DECREF on the result
- GameEngine::testTimers() now holds a local shared_ptr copy during
  callback execution, preventing use-after-free when timer callbacks
  call delTimer() on themselves

Fix double script execution bug with --exec flag:
- Scripts were running twice because GameEngine constructor executed them,
  then main.cpp deleted and recreated the engine
- Now reuses existing engine and just sets auto_exit_after_exec flag

Update test syntax to use keyword arguments for Frame/Caption constructors.

Test results: 127/130 passing (97.7%)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 17:48:12 -05:00
8854d5b366 feat: Replace libtcod with libtcod-headless fork (closes #134)
Replace upstream libtcod with jmccardle/libtcod-headless fork that:
- Builds without SDL dependency (NO_SDL compile flag)
- Uses vendored dependencies (lodepng, utf8proc, stb)
- Provides all core algorithms (FOV, pathfinding, BSP, noise)

Changes:
- Update .gitmodules to use libtcod-headless (2.2.1-headless branch)
- Add NO_SDL compile definition to CMakeLists.txt
- Remove old libtcod submodule

Build instructions: deps/libtcod symlink should point to
modules/libtcod-headless/src/libtcod (configured during build setup)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 11:22:48 -05:00
1a143982e1 hotfix: Windows build, no longer console mode 2025-07-10 17:01:03 -04:00
234551b9fd hotfix: findows build 2025-07-10 16:50:42 -04:00
93a55c6468 hotfix: windows build fixes 2025-07-10 16:43:05 -04:00
167636ce8c Iterators, other Python C API improvements
closes #72
ref #69 - this resolves the "UICollection" (not "UIEntityCollection", perhaps renamed since the issue opened) and "UIEntityCollection" portion. The Grid point based iterators were not updated.
**RPATH updates**
Will this RPATH setting allow McRogueFace to execute using its included "lib" subdirectory after being unzipped on a new computer?

The change from "./lib" to "$ORIGIN/./lib" improves portability. The $ORIGIN token is a special Linux/Unix convention that refers to the directory containing the executable itself. This makes the path relative to the executable's location rather than the current working directory, which means McRogueFace will correctly find its libraries in the lib subdirectory regardless of where it's run from after being unzipped on a new computer.

**New standard object initialization**
PyColor, PyVector
  - Fixed all 15 PyTypeObject definitions to use proper designated initializer syntax
  - Replaced PyType_GenericAlloc usage in PyColor.cpp and PyVector.cpp
  - Updated PyObject_New usage in UIEntity.cpp
  - All object creation now uses module-based type lookups instead of static references
  - Created centralized utilities in PyObjectUtils.h

**RAII Wrappers**
automatic reference counting via C++ object lifecycle
  - Created PyRAII.h with PyObjectRef and PyTypeRef classes
  - These provide automatic reference counting management
  - Updated PyColor::from_arg() to demonstrate RAII usage
  - Prevents memory leaks and reference counting errors

**Python object base in type defs:**
`.ob_base = {.ob_base = {.ob_refcnt = 1, .ob_type = NULL}, .ob_size = 0}`
PyColor, PyTexture, PyVector, UICaption, UICollection, UIEntity, UIFrame, UIGrid

**convertDrawableToPython**
replace crazy macro to detect the correct Python type of a UIDrawable instance

  - Removed the problematic macro from UIDrawable.h
  - Created template-based functions in PyObjectUtils.h
  - Updated UICollection.cpp to use local helper function
  - The new approach is cleaner, more debuggable, and avoids static type references

**Iterator fixes**
tp_iter on UICollection, UIGrid, UIGridPoint, UISprite
UIGrid logic improved, standard

**List vs Vector usage analysis**
there are different use cases that weren't standardized:
  - UICollection (for Frame children) uses std::vector<std::shared_ptr<UIDrawable>>
  - UIEntityCollection (for Grid entities) uses std::list<std::shared_ptr<UIEntity>>

The rationale is currently connected to frequency of expected changes.
* A "UICollection" is likely either all visible or not; it's also likely to be created once and have a static set of contents. They should be contiguous in memory in hopes that this helps rendering speed.
* A "UIEntityCollection" is expected to be rendered as a subset within the visible rectangle of the UIGrid. Scrolling the grid or gameplay logic is likely to frequently create and destroy entities. In general I expect Entity collections to have a much higher common size than UICollections. For these reasons I've made them Lists in hopes that they never have to be reallocated or moved during a frame.
2025-05-31 09:11:51 -04:00
198ed337e3 Windows build 2024-02-25 15:38:38 -05:00
07b597d6f2 Refactor: Python 3.12, build libtcod & SFML from source. Cmake build. Directory cleanup
directories needed:
* build - for cmake output
* deps - stuff needed to compile McRogueface (headers)
	libtcod -> ../modules/libtcod/src/libtcod
	sfml -> ../modules/SFML/include/SFML
	python -> ../modules/cpython/Include
* lib - stuff needed to link McRogueFace (shared objects); also required at runtime
	libtcod -> `../modules/libtcod/buildsys/autotools/.libs/libtcod.so.1.0.24`
	sfml -> `../modules/SFML/build/lib/*`
	python -> `../modules/cpython/libpython3.12.so`; standard lib at ../modules/cpython/build/lib.linux-x86_64-3.12 & ../modules/cpython/Lib

You can get dependencies by:
 - Build from source (i.e. all submodules)
 - Go download them from each project's website
 - install packages from your distro and symlink them to deps/lib directories
2024-02-24 22:48:39 -05:00