mirror of
https://github.com/MadeOfJelly/MushMachine.git
synced 2025-08-23 16:06:40 +02:00
initial import, >900commits predate this
This commit is contained in:
96
docs/basic_game.md
Normal file
96
docs/basic_game.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# Basic Engine Usage
|
||||
|
||||
## General Headers
|
||||
|
||||
```c++
|
||||
#include <mm/engine.hpp>
|
||||
// or
|
||||
#include <mm/engine_fwd.hpp> // forward header
|
||||
```
|
||||
|
||||
# Engine Example Setup
|
||||
|
||||
```c++
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
// Services you want to use:
|
||||
// I recommend to do this in a seperate translation unit, for good mesure.
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
#include <mm/services/filesystem.hpp> // requires SDL2 if not headless.
|
||||
#include <mm/services/opengl_renderer.hpp> // requires sdl_service.
|
||||
#include <mm/services/imgui_s.hpp> // every one <3 DearImGui!
|
||||
#include <mm/services/simple_scene.hpp> // a simple ECS using EnTT.
|
||||
#include <mm/services/sound_service.hpp> // SoLoud for Sound!
|
||||
#include <mm/services/screen_director_simple.hpp> // you want this, go to screen director doc for more info.
|
||||
|
||||
MM::Engine engine; // at global scope, only required for emscripten.
|
||||
|
||||
// adds Screens, definition at EOF.
|
||||
void add_screens(MM::Engine& engine, MM::Services::ScreenDirectorSimple& sds);
|
||||
|
||||
// argc, argv required for sdl2 on windows.
|
||||
int main(int argc, char** argv) {
|
||||
{ // setup ALL Services ever used during runtime.
|
||||
// 1. setup SDL
|
||||
// this adds the SDLService to the engine, also returns a ref to the Service.
|
||||
auto& sdl_ss = engine.addService<MM::Services::SDLService>(
|
||||
SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS | SDL_INIT_GAMECONTROLLER
|
||||
); // emscripten does not like haptic ...
|
||||
|
||||
// this Enables the Service (calles service.enable()), THIS also returns if the enable was successfull!!, for simplicity omitted...
|
||||
engine.enableService<MM::Services::SDLService>();
|
||||
|
||||
// this creates a OpenGL(3.3) ready Window.
|
||||
sdl_ss.createGLWindow("My MM Game", 1280, 720);
|
||||
// set icon here if needed.
|
||||
|
||||
|
||||
// 2. filesystem, can be 1. too.
|
||||
// the Construction of the fs Service takes in to arguments:
|
||||
// - the path to the executable, it should be the first string in argv, but can be left empty.
|
||||
// - the name of the application, of sorts. it is used for the folder to write into, so saves and configs edited by the player get written to this directory. it is not located relative to the exe/install.
|
||||
engine.addService<MM::Services::FilesystemService>(argv[0], "my_mm_game");
|
||||
|
||||
// and immediatly enable.
|
||||
engine.enableService<MM::Services::FilesystemService>();
|
||||
|
||||
// 3. add the the remaining Services, which get enabled, disabled during runtime, by eg. ScreenDirector.
|
||||
engine.addService<MM::Services::ImGuiService>();
|
||||
engine.addService<MM::Services::SimpleSceneService>();
|
||||
engine.addService<MM::Services::SoundService>(); // we also could just enable this at setup
|
||||
engine.addService<MM::Services::OpenGLRenderer>();
|
||||
|
||||
// 4. and not add a ScreenDirector, which manages Screens, which enable/disable a set of Services.
|
||||
auto& sds = engine.addService<MM::Services::ScreenDirectorSimple>();
|
||||
|
||||
// add/setup screens, i really recommend doing this somewhere else.
|
||||
add_screens(engine, sds);
|
||||
|
||||
// also queue the first Screen to be enabled.
|
||||
sds.queued_screen_id = "MM::Screens::mm_logo";
|
||||
|
||||
// and enable, this also switches to the queued screen, if there is one.
|
||||
engine.enableService<MM::Services::ScreenDirectorSimple>();
|
||||
}
|
||||
|
||||
// run Engine
|
||||
engine.run(); // blocks
|
||||
// you can also call engine.update() and engine.fixedUpdate() by hand.
|
||||
|
||||
// calling engine.stop() from anywhere will make engine.run() return.
|
||||
|
||||
engine.cleanup(); // required for global scope engine. don't do this for emscripten, bc emsripten will leave main() on startup, since you can't have blocking JavaSript...
|
||||
return 0;
|
||||
}
|
||||
|
||||
void add_screens(MM::Engine& engine, MM::Services::ScreenDirectorSimple& sds) {
|
||||
// add built-in MM-Logo-Splash-Screen
|
||||
MM::Screens::create_mm_logo(
|
||||
engine,
|
||||
sds.screens["MM::Screens::mm_logo"],
|
||||
"MM::Screens::mm_logo", // mm_logo specific: a Screen to play after mm_logo has finished. (we loop in this example)
|
||||
);
|
||||
|
||||
// add additional Screens here.
|
||||
}
|
||||
```
|
36
docs/framework/common_components/common_components.md
Normal file
36
docs/framework/common_components/common_components.md
Normal file
@@ -0,0 +1,36 @@
|
||||
(draft)
|
||||
# Common Components
|
||||
|
||||
This is a collection of commonly used (ECS) `Components`.
|
||||
|
||||
Json serialization is provided for all `Components`.
|
||||
|
||||
## Name
|
||||
|
||||
Contains a string. For debugging.
|
||||
|
||||
It's special, since the entity widget will try to get the Name and display it in `ImGui`.
|
||||
|
||||
## Transform
|
||||
|
||||
Contians Positon, Rotation and Scale.
|
||||
2D and 3D variants.
|
||||
|
||||
Might get replaced with a Unity3D style transform system...
|
||||
|
||||
## Velocity
|
||||
|
||||
Contians Velocity(Position and Rotation).
|
||||
2D and 3D variants.
|
||||
|
||||
## View_Dir
|
||||
|
||||
In almost every Project I had the need for this `Component`, so it's here.
|
||||
2D and 3D variants.
|
||||
|
||||
|
||||
## Color
|
||||
|
||||
I use this a lot. I probably shouldn't.
|
||||
Hase 4 color channels.
|
||||
|
75
docs/framework/engine/engine.md
Normal file
75
docs/framework/engine/engine.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Engine
|
||||
|
||||
The Engine is the heart of the MushMachine framework.
|
||||
It holds the Storage of all [`MM::Service`](services.md)s, update callbacks and is responsible for calling them.
|
||||
|
||||
# Usage
|
||||
|
||||
Provides a forwarding header `<mm/engine_fwd.hpp>`.
|
||||
|
||||
## Construction
|
||||
|
||||
The `MM::Engine` provides a Constructor which accepts a time interval, in which `.fixedUpdate()` is called. The Default is 1/60.
|
||||
|
||||
## Starting
|
||||
```cpp
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
MM::Engine engine;
|
||||
|
||||
// add and enable MM::Services here
|
||||
|
||||
engine.run();
|
||||
```
|
||||
|
||||
The `MM::Engine` disables all enabled `MM::Service`s in reverse order on destruction or `.cleanup()`.
|
||||
|
||||
## Managing [`MM::Service`](services.md)s
|
||||
|
||||
### Adding a `MM::Service`
|
||||
|
||||
Before a `MM::Service` can be enabled, it needs to be added to the engine.
|
||||
`.addService<MyService>(my, args)` adds a service and forwards args to its constructor.
|
||||
There is currently no way of removing a `MM::Service`.
|
||||
|
||||
### Getting a `MM::Service`
|
||||
|
||||
You can get a Pointer via `.tryService<MyService>()` and an asserted reference via `.getService<MyService>()`. If the `MM::Service` does not exist, it returns a `nullptr. "Enablement Status" makes no difference.
|
||||
|
||||
### Provide a `MM::Service` (Interfaces)
|
||||
|
||||
`.provide<MyServiceInterface, MyService>()` registers `MyService` also as `MyServiceInterface`, so `MyService` becomes getable via `MyServiceInterface`. `MyService` needs to be added beforehand.
|
||||
|
||||
### Enabling/Disabling a `MM::Service`
|
||||
|
||||
`MM::Service`s can be Enabled/Disabled during `.run()` as a deferred operation (see `.addFixedDefer(...)`)
|
||||
|
||||
* `.enableService<MyService>()` calles the `.enable()` of `MyService`. Also returns `true` on success.
|
||||
* `.disableService<MyService>()` calles the `.disable()` of `MyService`.
|
||||
There are also overloads, which accept a type id.
|
||||
|
||||
## Update / FixedUpdate
|
||||
|
||||
FixedUpdates are called with update interval (default 1/60, set on engine ctr), while Updates are called "as fast as possible". Since Rendering is usually done using Update and blocks on VSync, this is as fast as VSync.
|
||||
|
||||
Since fixedUpdate callbacks don't get a time delta, querying `.getFixedDeltaTime()` is mandatory.
|
||||
|
||||
### adding Update callbacks
|
||||
|
||||
`.addUpdate(MyFn)` and `.addFixedUpdate(MyFn)` add `MyFn` as an update and fixedUpdate respectively and return a `FunctionDataHandle`(ptr) to remove them again.
|
||||
|
||||
### removing Update callbacks
|
||||
|
||||
`.removeUpdate(myHandle)` and `.removeFixedUpdate(myHandle)` remove those callbacks again.
|
||||
|
||||
### `.run()`
|
||||
|
||||
`.run()` is a blocking call, which calles `.fixedUpdate()` in a fixed interval with an accumulator. Inbetween those `.fixedUpdate()`s, `.update()` gets called "as fast as possible".
|
||||
|
||||
You don't need to call `.run()`, instead you can call `.update()` and `.fixedUpdate()` yourself.
|
||||
|
||||
### `.stop()`
|
||||
|
||||
Stops the Engine...
|
||||
Actually quits the loop in `.run()`.
|
||||
|
23
docs/framework/engine/interfaces.md
Normal file
23
docs/framework/engine/interfaces.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Default Shipped Interfaces
|
||||
|
||||
### Index
|
||||
|
||||
* `MM::Services::SceneServiceInterface`
|
||||
|
||||
|
||||
## SceneServiceInterface
|
||||
|
||||
Not very stable. But I use it all over the place.
|
||||
|
||||
It uses [`EnTT`](https://github.com/skypjack/entt).
|
||||
|
||||
### interface
|
||||
|
||||
Use `.getScene()` to get current `MM::Scene`.
|
||||
|
||||
Use `.changeScene(newScene)` to queue `.changeSceneNow(newScene)`.
|
||||
|
||||
Use `.changeSceneNow(newScene)` to change currently held `MM::Scene`.
|
||||
|
||||
Use `.addSystemToScene(fn)` to add a `MM::System` to the `MM::Scene`.
|
||||
|
18
docs/framework/engine/services.md
Normal file
18
docs/framework/engine/services.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Services
|
||||
|
||||
`MM::Service`s are the Components that get added to the `MM::Engine`.
|
||||
|
||||
They need to extend `MM::Service` (included in `<mm/engine.hpp>`) and implement the following Interface:
|
||||
|
||||
* Destructor (since it is virtual)
|
||||
* `bool enable(MM::Engine& engine)`
|
||||
* `void disable(MM::Engine& engine)`
|
||||
|
||||
and optionally
|
||||
|
||||
* `const char* name(void)`
|
||||
|
||||
Not implementing `name()` does not impact functionality, but it is not good practise.
|
||||
|
||||
Update and FixedUpdate callbacks should only be added in `enable()` and should be removed in `disable()`.
|
||||
|
7
docs/framework/filesystem/filesystem.md
Normal file
7
docs/framework/filesystem/filesystem.md
Normal file
@@ -0,0 +1,7 @@
|
||||
(draft)
|
||||
# Filesystem
|
||||
|
||||
Provides a Virtual Filesystem. Implemented using [PhysFS](https://icculus.org/physfs/).
|
||||
|
||||
# Usage
|
||||
|
33
docs/framework/logger/logger.md
Normal file
33
docs/framework/logger/logger.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Logger
|
||||
|
||||
The Logger is the [`spdlog`](https://github.com/gabime/spdlog) logging library, with some extras. Like a `Sink` for [`Tracy`](https://github.com/wolfpld/tracy) the Profiler.
|
||||
|
||||
# Usage
|
||||
|
||||
Each "Section" is ment to have its own "Logger".
|
||||
|
||||
To Initialize a section logger with its `sink`s, do `MM::Logger::initSectionLogger("MySection");`.
|
||||
Can be placed in the `.enable()` or even the Constructor of your `Service`s.
|
||||
|
||||
```cpp
|
||||
#include <mm/logger.hpp> // include logger
|
||||
|
||||
// here are the macros
|
||||
#define LOG_CRIT(...) __LOG_CRIT( "MySection", __VA_ARGS__)
|
||||
#define LOG_ERROR(...) __LOG_ERROR("MySection", __VA_ARGS__)
|
||||
#define LOG_WARN(...) __LOG_WARN( "MySection", __VA_ARGS__)
|
||||
#define LOG_INFO(...) __LOG_INFO( "MySection", __VA_ARGS__)
|
||||
#define LOG_DEBUG(...) __LOG_DEBUG("MySection", __VA_ARGS__)
|
||||
#define LOG_TRACE(...) __LOG_TRACE("MySection", __VA_ARGS__)
|
||||
|
||||
// code goes here ......
|
||||
|
||||
// only if in header
|
||||
//#undef LOG_CRIT
|
||||
//#undef LOG_ERROR
|
||||
//#undef LOG_WARN
|
||||
//#undef LOG_INFO
|
||||
//#undef LOG_DEBUG
|
||||
//#undef LOG_TRACE
|
||||
```
|
||||
|
5
docs/framework/opengl_primitives/opengl_primitives.md
Normal file
5
docs/framework/opengl_primitives/opengl_primitives.md
Normal file
@@ -0,0 +1,5 @@
|
||||
(draft)
|
||||
## OpenGL Primitives
|
||||
|
||||
Mostly Classes wrapping the OpenGL library.
|
||||
|
7
docs/framework/opengl_renderer/opengl_renderer.md
Normal file
7
docs/framework/opengl_renderer/opengl_renderer.md
Normal file
@@ -0,0 +1,7 @@
|
||||
(draft)
|
||||
# OpenGL Renderer
|
||||
|
||||
This is a "Renderer" implementation. It hosts a `OpenGL::RenderTask` list, which get executed in order.
|
||||
|
||||
For `OpenGL::RenderTask`s see the [render_tasks folder](render_tasks/).
|
||||
|
6
docs/framework/opengl_renderer/render_tasks/blit_fb.md
Normal file
6
docs/framework/opengl_renderer/render_tasks/blit_fb.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# `OpenGL::RenderTask` Blit FB
|
||||
|
||||
This `RenderTask` Blits(copys) the contents of one `FrameBuffer` to another.
|
||||
|
||||
There are options available for source and destination rectangle, color flags and filter mode.
|
||||
|
6
docs/framework/opengl_renderer/render_tasks/clear.md
Normal file
6
docs/framework/opengl_renderer/render_tasks/clear.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# `OpenGL::RenderTask` Clear
|
||||
|
||||
This `RenderTask` calles glClear().
|
||||
|
||||
There are options available for clear color and color mask.
|
||||
|
4
docs/framework/opengl_renderer/render_tasks/imgui.md
Normal file
4
docs/framework/opengl_renderer/render_tasks/imgui.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# `OpenGL::RenderTask` ImGuiRT
|
||||
|
||||
This `RenderTask` renders the ImGui render data.
|
||||
|
7
docs/framework/resource_manager/resource_manager.md
Normal file
7
docs/framework/resource_manager/resource_manager.md
Normal file
@@ -0,0 +1,7 @@
|
||||
(draft)
|
||||
# Resource Manager
|
||||
|
||||
This is nothing more than a glorified Singelton and will be replace in the future.
|
||||
|
||||
Based on https://github.com/skypjack/entt/blob/master/src/entt/resource/cache.hpp.
|
||||
|
31
docs/framework/screen_director/screen_director.md
Normal file
31
docs/framework/screen_director/screen_director.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Screen Director
|
||||
|
||||
Orchistrates `Screen`s.
|
||||
|
||||
The `Screen Director` lets you define "States"(`Screen`s) which activate/deactivate `MM::Service`s on Entering and Leaving the `Screen`.
|
||||
|
||||
# Usage
|
||||
|
||||
The current implementation is very open and does not really use encapsulation ...
|
||||
|
||||
## Adding `Screen`s
|
||||
|
||||
Due to the open nature of this implementation, one does access members directly:
|
||||
```
|
||||
auto& my_screen = screen_director.screens["my_screen"];
|
||||
|
||||
// filling in start_disable, start_enable, start_provide, end_disable and end_enable
|
||||
// and optionally start_fn and end_fn which are called upon entering and leaving the screen.
|
||||
my_screen.start_enable.push_back(engine.type<MyService>());
|
||||
// [...]
|
||||
```
|
||||
|
||||
## Changing to a Screen
|
||||
|
||||
Changing to a `Screen` can either be done on call with `.changeScreenTo(engine, "my_screen_id")` or qued via `.queueChangeScreenTo("my_screen")`. The former should only be used when the `Engine` is not running or in a `fixedDeferUpdate`.
|
||||
|
||||
## Service Enablement
|
||||
|
||||
Enabling the ScreenDirector causes a queued `Screen` to be started.
|
||||
|
||||
|
9
docs/framework/sdl_service/sdl_service.md
Normal file
9
docs/framework/sdl_service/sdl_service.md
Normal file
@@ -0,0 +1,9 @@
|
||||
(draft)
|
||||
## SDL Service
|
||||
|
||||
This is a `Service` which manages Windows, OpenGL Contexts and Events.
|
||||
|
||||
The current implementation limits it to one Window and OpenGL Context.
|
||||
|
||||
Support for Vulkan is planned.
|
||||
|
5
docs/framework/simple_scene/simple_scene.md
Normal file
5
docs/framework/simple_scene/simple_scene.md
Normal file
@@ -0,0 +1,5 @@
|
||||
(draft)
|
||||
# Simple Scene
|
||||
|
||||
This is a simple `MM::SceneServiceInterface` implementation.
|
||||
|
68
docs/setup.md
Normal file
68
docs/setup.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Setting up MushMachine
|
||||
|
||||
## Game development
|
||||
|
||||
First add MM as a git submodule if in git repo:
|
||||
```bash
|
||||
git submodule add --init --recursive <url>
|
||||
```
|
||||
else just git clone
|
||||
|
||||
add to cmake as subdirectory
|
||||
```cmake
|
||||
add_subdirectory(MushMachine)
|
||||
```
|
||||
|
||||
The Engine is intended to be linked statically, but you can explore dynamic-linking of course.
|
||||
|
||||
## Engine development
|
||||
* clone repo
|
||||
* install dependencies
|
||||
|
||||
### GNU/LiNUX
|
||||
* install dependencies
|
||||
- libsdl2
|
||||
|
||||
* navigate to (out of tree) build directory (prefer just "build" in repo-dir)
|
||||
* `cmake ..`
|
||||
|
||||
### OSX
|
||||
never tested before. be the first one :) .
|
||||
|
||||
### Windows
|
||||
* install dependencies
|
||||
- using install vcpkg
|
||||
- install SDL2 (non static)
|
||||
- or by hand
|
||||
- download libSDL2 and put it somewere, and set the "SDL2" environment variable to that location (set SDL2="path/to/folder")
|
||||
|
||||
#### Visual Studio (GUI)
|
||||
* open cmake project with visual studio (vs2019; vs2017 may work)
|
||||
- if using vcpkg and vs2017: set vcpkg cmake toolchain (vs2019 does this automaticly)
|
||||
|
||||
#### Visual Studio (MSVC dev cmd)
|
||||
* open dev cmd (search start menu)
|
||||
* navigate to (out of tree) build directory (prefer just "build" in repo-dir)
|
||||
- if using vcpkg
|
||||
- `cmake .. -DCMAKE_TOOLCHAIN_FILE="<path-to-vcpkg-install>\scripts\buildsystems\vcpkg.cmake" -G Ninja`
|
||||
- else
|
||||
- `cmake .. -G Ninja`
|
||||
|
||||
#### CLion
|
||||
TODO
|
||||
(look at cmake in this doc)
|
||||
|
||||
## Additional Notes
|
||||
|
||||
### CMake
|
||||
* to specify build type on console use `-DCMAKE_BUILD_TYPE=<build-type>` eg. `Release`. the engine cmake defaults to `Debug` if not set.
|
||||
* the engine has cmake-level defines that can be set (via cmd eg. `-DMM_HEADLESS=ON`):
|
||||
- `MM_HEADLESS` (disables sdl2 and opengl usage)
|
||||
- `MM_NETWORKING` (depricated)
|
||||
- `MM_OPENGL_3` (disabled if `MM_HEADLESS`)
|
||||
- `MM_OPENGL_3_GLES` (disabled if `MM_HEADLESS`, `MM_OPENGL_3` supplement, makes the openglrenderer use gles3 instead of gl3)
|
||||
|
||||
### Emscripten
|
||||
* version 2.0.1 works
|
||||
* version 1.39.18 does not (webgl errors)
|
||||
|
20
docs/terminology.md
Normal file
20
docs/terminology.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Terminology
|
||||
|
||||
### Engine
|
||||
is defined as [`MM::Engine`](framework/engine/engine.md).
|
||||
|
||||
### Service
|
||||
is defined as [`MM::Services::Service`](framework/engine/services.md), the Service's base class, which was previously known as `ServiceSystem` and `SubSystem`.
|
||||
|
||||
### Scene
|
||||
is defined as a ECS-style EnTT::registry. It contains Entities, Components and Systems.
|
||||
|
||||
### Entity
|
||||
is defined as a ECS Entity, see [`EnTT`](https://github.com/skypjack/entt).
|
||||
|
||||
### System
|
||||
is defined as a ECS-style System. In this case, it's a free function.
|
||||
|
||||
### Screen
|
||||
is defined as a State of enabled and disabled `Service`s. (see [`ScreenDirector`](framework/screen_director/screen_director.md))
|
||||
|
Reference in New Issue
Block a user