GithubHelp home page GithubHelp logo

tofuengine / tofu Goto Github PK

View Code? Open in Web Editor NEW
65.0 3.0 1.0 37.84 MB

Multiplatform lightweight 2D game-engine, retro-game inspired. Uses OpenGL through GLFW3. Scripted in Lua. Aiming zero run-time dependencies.

Home Page: https://tofuengine.org

License: MIT License

Makefile 1.33% C 78.33% Lua 7.95% Python 8.23% GLSL 3.75% Dockerfile 0.17% Shell 0.24%
gamedev-framework gamedev opengl glfw lua c99 game-development game-engine raspberry-pi windows 2d cross-platform linux

tofu's Introduction

Tofu Engine
A 2D GAME ENGINE W/ AN ECO-FRIENDLY PIXEL-ART RETRO-SOUL

license site mastodon

version platforms

issues last-commit commit-activity

Introduction

Welcome to Tofu Engine!

Make yourself comfortable, and join for a ride through a mixture of old-fashioned and modern game development! :)

Highlights

  • Carefully crafted C99 code.
  • Self-contained, no additional runtime modules/libraries required ("standard" system-wide libraries excluded).
  • Multi-platform support through cross-compilation (Windows, Linux, Raspberry-Pi, and other ARM platforms as long they are running on Linux -- macOS currently not supported, possibly WebAssembly in the not-so-distant future).

For the courious ones, these are the current statistics of the game-engine codebase:

Language Files Blank Comment Code
C 80 3348 2496 16777
C/C++ Header 88 698 2408 2144
Lua 22 296 497 1708
GLSL 12 118 282 422
202 4460 5683 21051

Features

  • Fully scripted in Lua.
  • Straight multimedia support, no intermediate third-party libraries (OpenGL 2.1 required).
  • Windowed/fullscreen display with best-fit integer automatic scaling.
  • Array of predefined common/famous resolutions (e.g. C64, Capcom's arcades, Nintendo DS, Sony PSP, etc...).
  • Internal software renderer. OpenGL is used only to present the framebuffer to the user (and apply post-process effects).
  • Fixed- and variable-size Blitter OBjects drawing with rotation/scaling/flipping.
  • Support for both proportional and non-proportional bitmap-based fonts (alphabet subset can be specified, if required).
  • Sprite batching for optimized (ehm) batch drawing.
  • Tiles drawing with offset/scaling/flipping.
  • Palette-based graphics w/ 256 colors.
  • Predefined library of 8/16/32/64 colors palettes.
  • Banked palette support w/ color bias during VRAM transfer.
  • Automatic nearest-matching-color palette indexing of RGBA8888 images.
  • Per-color re-indexing (shifting) and transparency, affecting drawing operations (both per-draw and during VRAM transfer).
  • Multiple (offscreen) canvas w/ drawing state stack support.
  • SNES' Mode7-like transforms, with scanline based (HDMA) changes.
  • Amiga's Copper-like programs, with pixel-wide resolution.
  • Image programmable copy functions, to implement script-shaders.
  • Image stencil copy function, with used definable threshold function.
  • Image blend copy, with user definable blending function (repeat, add, sub, multiply, min, max).
  • Post-effect display-wise fragment shaders.
  • Library of "retro-feel" post-effects (LCD, CRT, color-blindness, etc...).
  • Audio support w/real-time sound streaming on a separate thread.
  • On-the-fly audio mixing w/ per voice looping/panning/balance/gain/speed control.
  • Static and streamed audio data playback (FLAC format).
  • Module playback support (MOD, S3M, XM, and IT).
  • Out-of-the-box timers support.
  • Ready-to-use 2D vector class and higher-order iterators.
  • 2D physics-engine.
  • Customizable application icon.
  • Support for archived games, via custom "packed" format (w/ optional encryption). Multiple archives are supported, with root directory override.
  • Resource manager w/ caching I/O and single instance object loading/reuse.
  • Multiple player support w/ up to 4 simultaneous game controllers. Mouse emulation is supported. Controllers #0 and #1 can be keyboard emulated.
  • Screen capture and recording.
  • Framebuffer offsetting (e.g. for screen-shaking effect).
  • Out-of-the-box 'tweening functions support (optimized Penner's set).
  • Noise generators (Perlin, simple, and cellular).
  • Logging facility (w/ selectable severity level).
  • Run-time signature check for Lua's API functions (debug build). Also, UDTs are typed-checked with a custom RTTI implementation.
  • Crash screen (debug build).
  • Game window focus detection (for game-pause).
  • Real-time performance statistics (FPS and frame times) and resource usage (memory).
  • User-dependent I/O functions to load/store game data.
  • Configuration override through command-line arguments.

Dependencies

Although I have been known to take pleasure in reinventing the wheel at every possible opportunity, Tofu Engine leverages some awesome libraries:

Inspirations

Tofu Engine is an original software, result of the experience gained from ~30 years in programming on a broad range of platforms (some concept even stems back to ancient platforms like the Amiga and the SNES, and arcane languages like AMOS and Blitz BASIC 2). However, it has also been influenced by modern similar/other software in one way or another. Here's a brief list.

Credits

The lovely game-engine logo has been designed by Blort.

Compiling

In order to compile Tofu Engine, a Linux machine in required (either physical or virtual). A Debian-based distribution is suggested, although I've been using Ubuntu during the development. One can use the following commands to install all the required dependencies:

sudo apt install build-essential
sudo apt install mingw-w64

sudo apt install xorg-dev libx11-dev libwayland-dev libxkbcommon-dev wayland-protocols mesa-common-dev libgles2-mesa-dev

sudo apt install lua5.4 liblua5.4-dev luarocks

sudo luarocks --lua-version=5.4 install argparse
sudo luarocks --lua-version=5.4 install luafilesystem
sudo luarocks --lua-version=5.4 install luacheck
sudo luarocks --lua-version=5.4 install luazen

Please note that MinGW is required only to obtain the Windows build through cross-compilation. One can simply use MinGW on Windows to build the engine binary as it is.

Of course, git should also be installed to clone the repository.

sudo apt install git

Proceed in creating a local clone of the repository with the command

git clone https://github.com/tofuengine/tofu.git

into a suitable work directory. Move into the tofu directory you've just created and use make to build the executable. You can use the following command-line parameters to control the build process:

  • BUILD, can be either debug or release with the usual meaning. If not specified, the build is assumed in debug mode.
  • PLATFORM, can be either linux or windows. If not specified, the build is assumed for Linux platform.
  • WINDOWING, can be x11, wayland, gdi, or mesa. If not specified, the build assumes gd1 for the Windows platform, x11 otherwise for the Linux one. Please note that mesa is not really supported and wayland is experimental (but should work).
  • ARCHITECTURE, can be x64, x32, arm64 or armhf. If not specified the current host architecture is used as target.

The build artifacts will be placed in the build directory.

Alternatively, if you prefer not to tamper with your system, you can use a Docker container for the build process. For that purpose, a ready-to-use Dockerfile can be found in the extras/docker directory. Use the make docker-create command to build the container and make docker-launch to start it in the current folder.

Cross-Compiling

A note about cross-builds of the game-engine. The project has been designed with Linux as a development machine, with the distinct platform-dependent build archived through cross-compilation. As said, the Windows build is obtained thanks to MinGW, which includes all the required dependencies (i.e. development libraries). To obtain the ARM builds through cross-compilation, as well, Multiarch is to be used. The steps to add support are the following.

First and foremost the arm64 (for 64-bit ARM) and armhf (for 32-bit ARM) architectures need to be added

sudo dpkg --add-architecture arm64
sudo dpkg --add-architecture armhf

Then, the apt sources for this architecture need to be configured, by creating a new file /etc/apt/sources.list.d/arm64-sources.list with this content (which mirrors the sources.list file, minus the security sources which are not required):

echo "deb [arch=arm64,armhf] http://ports.ubuntu.com/ $(lsb_release -cs) main restricted" | sudo tee /etc/apt/sources.list.d/arm64-sources.list > /dev/null
echo "deb [arch=arm64,armhf] http://ports.ubuntu.com/ $(lsb_release -cs)-updates main restricted" | sudo tee -a /etc/apt/sources.list.d/arm64-sources.list >> /dev/null
echo "deb [arch=arm64,armhf] http://ports.ubuntu.com/ $(lsb_release -cs) universe" | sudo tee -a /etc/apt/sources.list.d/arm64-sources.list >> /dev/null
echo "deb [arch=arm64,armhf] http://ports.ubuntu.com/ $(lsb_release -cs)-updates universe" | sudo tee -a /etc/apt/sources.list.d/arm64-sources.list >> /dev/null
echo "deb [arch=arm64,armhf] http://ports.ubuntu.com/ $(lsb_release -cs) multiverse" | sudo tee -a /etc/apt/sources.list.d/arm64-sources.list >> /dev/null
echo "deb [arch=arm64,armhf] http://ports.ubuntu.com/ $(lsb_release -cs)-updates multiverse" | sudo tee -a /etc/apt/sources.list.d/arm64-sources.list >> /dev/null
echo "deb [arch=arm64,armhf] http://ports.ubuntu.com/ $(lsb_release -cs)-backports main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list.d/arm64-sources.list >> /dev/null

At the same time, the current content /etc/apt/sources.list file need to be patched so that it refers to the actual host architecture. If it isn't already configured as such you can use the following command to patch the file:

sudo sed -i "s/deb http/deb [arch=$(dpkg --print-architecture)] http/" /etc/apt/sources.list

Remember to issue a sudo apt update command to refresh the APT database and, finally, install GCC's backends and the library dependencies we need:

sudo apt install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu
sudo apt install gcc-arm-linux-gnueabihf binutils-arm-linux-gnueabihf
sudo apt install --no-install-recommends libx11-dev:arm64 libx11-dev:armhf

which will also install any required package.

Sample projects

Along with the game engine source, there are a bunch of (basic) demo projects. They are located in the demos sub-directory and can be launched using make, passing the name of the project as a target (e.g. make splash).

Addenda

Contributing

If Tofu Engine appeals you and

  • you are experiencing some issues (hopefully not too much of them!),
  • you are seeing some unexpected behaviour (d'oh!),
  • you have some cool ideas do you want to share,
  • you feel the urge to implement a feature from the "desiderata" below, or
  • you want to write some examples and/or documentation

please don't hold you back and contribute! :)

Desiderata

Follows a brief (and incomplete) list of additional features somewhen in the future I'd like to implement.

Core

  • Boot splash-screen w/ resource preloading support (much like older consoles).
  • On-screen overlay w/ performance information (FPS, graph, frame-time, etc...).
  • Logging to file.
  • Asynchronous resource loading/decoding with callback (maybe just some kind of pre-loading? With coroutines?)
  • Webassembly build via Emscripten to HTML5.
  • Use a custom memory-management allocator.
  • Multi-threaded parallel rendering (w/ double/triple buffering).
  • Framebuffer rotations? Or does Mode7 suffices? But copperlists are not rendered on canvases...
  • (Script-level) game state/screen transitions, something similar to the concept of "rooms" that many engines offer.
  • Tweakable game-time management, to control the actual real-time game speed (speed up, slow down, pause, etc...)

Graphics

  • Move to full GPU use (beware of the diamond-exit-rule and ensure pixel-perfect positioning).
  • Adopt another (more simple to merge into) pixel font.
  • Switch to Vulkan API (through GLFW).
  • Animation support w/ frameset DSL (i.e. compiling a string where each token can be a single frame, a range or a "keep-current-frame for some time" command). Each frameset can have its one update period, and will be most likely based upon a timer.
  • Tiled-map support w/ camera support (zoom and scrolling).
  • Custom "raw" graphics and sound formats, with on-the-fly LZ4 (stream?) compression.

Audio

  • On-the-fly (could pre-cache it for later usage) sound synthesizer, similar to srfx.
  • Audio channels support -- each source is to associated to a channel.
  • Real-time audio effects (noise, reverb, filters, spatialization, etc...).

Input

  • Rumble and force feedback support -- this might be implemented with a specific library as GLFW doesn't support it (perhaps taken from SDL_syshaptic?).
  • Analogue support for shoulder and trigger axes.
  • Better input handling by leveraging an event-driver approach -- this should reduce the current sub-system complexity (as it polled).
  • Apply filtering for the analogs, either with a low pass filter (page 591) or moving average.
  • Implement buttons state check with XOR (page 594)
  • chords and gestures detection, for example for Street Fighter II-like combos.

Profiling

make bunnymark BUILD=profile
gprof ./tofu  gmon.out > analysys.txt
gprof ./tofu  gmon.out | ./extras/gprof2dot.py | dot -Tpng -o analysys.png

tofu's People

Contributors

marcolizza avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

meowboy326

tofu's Issues

mallinfo is deprecated

glibc 2.33 deprecated mallinfo in favor of mallinfo2.
More info here

This usage:

struct mallinfo mi = mallinfo();

Trigger a deprecation and an error.

src/core/environment.c: In function ‘Environment_process’:
src/core/environment.c:170:16: error: ‘mallinfo’ is deprecated [-Werror=deprecated-declarations]
  170 |         struct mallinfo mi = mallinfo();
      |                ^~~~~~~~
In file included from external/stb/stb_leakcheck.h:140,
                 from src/libs/stb.h:29,
                 from src/core/environment.c:29:
/usr/include/malloc.h:118:24: note: declared here
  118 | extern struct mallinfo mallinfo (void) __THROW __MALLOC_DEPRECATED;
      |                        ^~~~~~~~
cc1: all warnings being treated as errors
make: *** [Makefile:105: src/core/environment.o] Errore 1

References to `tofu.controller:controller breaks two demos

Hi, this is an interesting project, thank you for sharing!

I found (old?) references to the (changed?) tofu.controller:controller table in two demos, causing errors. Changing the refs to tofu.input.controller fixes them:

diff --git a/demos/scroller/main.lua b/demos/scroller/main.lua
index 38c8c6f3..f300d691 100644
--- a/demos/scroller/main.lua
+++ b/demos/scroller/main.lua
@@ -24,7 +24,7 @@ SOFTWARE.
 
 local Class = require("tofu.core.class")
 local System = require("tofu.core.system")
-local Controller = require("tofu.controller:controller")
+local Controller = require("tofu.input.controller")
 local Canvas = require("tofu.graphics.canvas")
 local Display = require("tofu.graphics.display")
 local Font = require("tofu.graphics.font")
diff --git a/demos/shades/main.lua b/demos/shades/main.lua
index 0b42e669..9c736473 100644
--- a/demos/shades/main.lua
+++ b/demos/shades/main.lua
@@ -24,7 +24,7 @@ SOFTWARE.
 
 local Class = require("tofu.core.class")
 local System = require("tofu.core.system")
-local Controller = require("tofu.controller:controller")
+local Controller = require("tofu.input.controller")
 local Canvas = require("tofu.graphics.canvas")
 local Display = require("tofu.graphics.display")
 local Font = require("tofu.graphics.font")

Hope this helps,
Cheers!

tiled-map demo fails to start

I'm getting a guru meditation (nice Amiga callback! 😆 ) error when starting the tiled-map demo, this is the exception I'm getting:

[E/log] lib/map.lua:71: [src/modules/canvas.c:135] signature failure for argument #1 (wrong actual type, got `string`)
stack traceback:
	[C]: in function 'tofu.graphics.canvas.new'
	lib/map.lua:71: in function 'lib/map.from_file'
	main.lua:43: in function 'main.__ctor'
	tofu/core/class.lua:33: in function 'main.new'
	boot-debug.lua:43: in function <boot-debug.lua:41>
	[C]: in function 'xpcall'
	boot-debug.lua:175: in method 'call'
	boot-debug.lua:163: in method 'switch_if_needed'
	boot-debug.lua:135: in function <boot-debug.lua:134>

Apparently the canvas creator expects an object (LUAX_SIGNATURE_REQUIRED(LUA_TOBJECT)) and is getting a string. Unfortunately I'm not familiar enough with the internals of the engine, or with how the demo is supposed to work to figure out what's wrong. All other demos work great instead, great work!

tofu segfaults in a log at startup

I'm getting a crash anytime I start the tofu executable, both on its own and in the context of a demo. The gdb backtrace is the following:

(gdb) bt
#0  0x00007ffff7ce8ffd in __strlen_avx2 () from /lib64/libc.so.6
#1  0x00007ffff7bf2858 in __vfprintf_internal () from /lib64/libc.so.6
#2  0x00007ffff7bf2f05 in buffered_vfprintf () from /lib64/libc.so.6
#3  0x000000000047cf4f in _write (level=LOG_LEVELS_DEBUG, 
    context=0x59c60d "storage", 
    text=0x59c720 "storage cache %p for context %p created for path `%s`", 
    args=0x7fffffff62b8) at src/libs/log.c:87
#4  0x000000000047d0b3 in Log_write (level=LOG_LEVELS_DEBUG, 
    context=0x59c60d "storage", 
    text=0x59c720 "storage cache %p for context %p created for path `%s`")
    at src/libs/log.c:116
#5  0x00000000004d054e in Storage_create (configuration=0x7fffffffd4c0)
    at src/systems/storage.c:95
#6  0x0000000000407aff in Engine_create (options=0x7fffffffd560)
    at src/core/engine.c:133
#7  0x000000000040647d in main (argc=1, argv=0x7fffffffd698) at src/main.c:88

Looks like the problem is here:

#5  0x00000000004d054e in Storage_create (configuration=0x7fffffffd4c0)
    at src/systems/storage.c:95
95	    LOG_D(LOG_CONTEXT, "storage cache %p for context %p created for path `%s`", storage->cache, storage->context);

as there's three printf format specifiers, but only two argument (missing path). Adding path as an argument fixes the segfault for me.

Is it possible to make resizable windows ?

I have discovered this game engine recently and it seems quite interesenting, it is the engine that I was looking for! There is no much documentation, but the examples are very useful. Now I wonder if there is a way to make resizable windows that scale and keep content ratio since I couldn't realize how to do this. Thank you so much for your engine, btw. Keep it up!

Compilation issues on Fedora 36

I realize the instructions are for Debian, but I wanted to try and build the engine on my Fedora too, to see if/what changes may be needed. Dependencies-wise everything seems correct, as I didn't encounter problems there: I didn't have to install anything new, make just "worked", so I'm afraid I can't provide names for the packages that should be installed via dnf there (I know they're different since the ones listed for Debian don't exist on Fedora, even with a s/dev/devel).

The problem seem more on the Lua/packer side of things. Initially, make complained about not being able to find ./extras/pakgen.lua, which is there though. Looking at the Makefile, I realized the cause was an attempt to run that Lua script as an executable. Inspecting the file, it starts like this:

#!/usr/bin/lua5.3

which is an interpreter that doesn't exist on Fedora, while /usr/bin/lua does (5.4 is installed). Not sure if Debian and other distros only provide the numbered executables, but otherwise setting just lua may help pass that part.

I had a different issue with luazen, which ended up being installed by luarocks in a folder that Lua itself couldn't find. Just linking the .so to one of the "good" places was enough to get it working (this is very likely a local issue, and so not something you should address in the repo, so it's just an FYI!).

Finally, make stumbled here which is where I stopped since I'm not sure how this can be fixed:

[lminiero@lminiero tofu]$ make
Linking complete!
Total: 0 warnings / 0 errors in 22 files
PakGen v0.4.1
=============
Fetching files from folder `./src/kernal`
Optimizing...
Creating encrypted archive `./build/kernal.pak` w/ 43 entries
/usr/bin/lua: ./extras/pakgen.lua:175: attempt to index a nil value (global 'bit32')
stack traceback:
	./extras/pakgen.lua:175: in upvalue 'compile_flags'
	./extras/pakgen.lua:195: in upvalue 'emit_header'
	./extras/pakgen.lua:314: in upvalue 'emit'
	./extras/pakgen.lua:350: in local 'main'
	./extras/pakgen.lua:359: in main chunk
	[C]: in ?
make: *** [Makefile:252: build/kernal.pak] Error 1

Googling around, it looks like bit32 was removed in Lua 5.3 (since bitwise operations are now supported), but since 5.4.4 is recommended in the README, that may be incorrect. As such, not sure if it's something only missing in Fedora, or something it should indeed be able to find somewhere else.

Hope this is helpful, keep up the great work!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.