Added input manager and license.

This commit is contained in:
2021-02-22 07:01:44 +11:00
parent 4d8f377d39
commit a456eb1008
16 changed files with 489 additions and 47 deletions

View File

@ -1,3 +1,8 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
#################################### CMAKE #####################################
cmake_minimum_required(VERSION 3.15)
set(CMAKE_C_STANDARD 99)

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Dominic Msters
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,3 +1,10 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "render.h"
render_t *RENDER_CURRENT = NULL;

View File

@ -1,3 +1,10 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include <stdio.h>
@ -32,8 +39,6 @@ extern render_t *RENDER_CURRENT;
/**
* Initialize the renderer.
*
* @param width Width (in pixels) of the window.
* @param height Height (in pixels) of the window.
* @param name String of the windows' name.
* @return Rendering Context information.
*/

View File

@ -1,3 +1,10 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "shader.h"
shader_t * shaderCompile(char *vertexShaderSource, char* fragmentShaderSource) {

View File

@ -1,4 +1,12 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include <glad/glad.h>
#include <stdio.h>
#include <stdbool.h>

47
src/engine/engine.c Normal file
View File

@ -0,0 +1,47 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "engine.h"
engine_t * engineInit(char *gameName) {
// Create the engine instance.
engine_t *engine = malloc(sizeof(engine_t));
if(engine == NULL) return NULL;
// Setup the renderer.
engine->render = renderInit(gameName);
if(engine->render == NULL) {
free(engine);
return NULL;
}
// Setup the input manager.
engine->input = inputInit(0);
if(engine->input == NULL) {
free(engine->render);
free(engine);
return NULL;
}
return engine;
}
void engineStart(engine_t *engine) {
while(!glfwWindowShouldClose(engine->render->window)) {
inputUpdate(engine->input);
renderFrame(engine->render);
glfwSwapBuffers(engine->render->window);
glfwPollEvents();
}
}
bool engineDispose(engine_t *engine) {
if(!renderDispose(engine->render)) return false;
free(engine);
return true;
}

46
src/engine/engine.h Normal file
View File

@ -0,0 +1,46 @@
// Copyright (c) 2021 Dominic Msters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include <stdbool.h>
#include "../display/render.h"
#include "../file/asset.h"
#include "../input/input.h"
/** Information about the current engine context. */
typedef struct {
/** Name of the game running. */
char *gameName;
/** Renderer for the engine. */
render_t *render;
/** Input Manager for the engine. */
input_t *input;
} engine_t;
/**
* Initialize the engine context.
*
* @param gameName Name of the game being initialized.
* @return The engine context.
*/
engine_t * engineInit(char *gameName);
/**
* Start the main engine loop.
*
* @param engine The game to start the loop for.
*/
void engineStart(engine_t *engine);
/**
* Cleanup a previously constructed game engine instance.
*
* @param engine The engine to cleanup.
* @return True if successful or not.
*/
bool engineDispose(engine_t *engine);

View File

@ -1,3 +1,10 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "asset.h"
char * assetStringLoad(char *assetName) {

View File

@ -1,3 +1,10 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include <stdbool.h>
#include <stdio.h>

View File

@ -1,40 +1,39 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "game.h"
game_t * gameInit(char *gameName) {
// Create the game instance
game_t *game = malloc(sizeof(game_t));
if(game == NULL) return NULL;
typedef struct {
engine_t *engine;
} dawngame_t;
// Setup the renderer
game->render = renderInit(gameName);
if(game->render == NULL) {
free(game);
game_t * gameInit(char *gameName) {
// Create the game
dawngame_t *dawn = malloc(sizeof(dawngame_t));
if(dawn == NULL) return NULL;
// Load the game engine
dawn->engine = engineInit("Dawn Game");
if(dawn->engine == NULL) {
free(dawn);
return NULL;
}
// Load a shader
shader_t *shader = assetShaderLoad("shaders/test.vert", "shaders/test.frag");
if(shader == NULL) {
printf("Shader loading failed\n");
} else {
printf("Shader loaded!\n");
}
return game;
// Pass to the main game to handle.
return (game_t *)dawn;
}
void gameStart(game_t *game) {
while(!glfwWindowShouldClose(game->render->window)) {
renderFrame(game->render);
glfwSwapBuffers(game->render->window);
glfwPollEvents();
}
dawngame_t *dawn = (dawngame_t *)game;
engineStart(dawn->engine);
}
bool gameDispose(game_t *game) {
if(!renderDispose(game->render)) return false;
free(game);
return true;
void gameDispose(game_t *game) {
dawngame_t *dawn = (dawngame_t *)game;
engineDispose(dawn->engine);
free(dawn);
}

View File

@ -1,21 +1,22 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include <stdbool.h>
#include "../display/render.h"
#include "../file/asset.h"
#include "../engine/engine.h"
/** Information about the current game context. */
typedef struct {
/** Renderer for the game */
render_t *render;
} game_t;
typedef void game_t;
/**
* Initialize the game context.
*
* @param gameName Name of the game being initialized.
* @return The game instance context.
*/
game_t * gameInit(char *gameName);
game_t * gameInit();
/**
* Start the main game loop.
@ -26,9 +27,6 @@ void gameStart(game_t *game);
/**
* Cleanup a previously constructed.
*
* @param game The game to cleanup.
* @return True if successful or not.
*/
bool gameDispose(game_t *game);
void gameDispose(game_t *game);

97
src/input/input.c Normal file
View File

@ -0,0 +1,97 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "input.h"
input_t * inputInit(uint32_t inputBindCount) {
input_t *input = malloc(sizeof(input_t));
if(!input) return NULL;
input->inputBindCount = inputBindCount;
input->inputsCurrent = malloc(sizeof(float) * inputBindCount);
if(input->inputsCurrent == NULL) {
free(input);
return NULL;
}
input->inputsPrevious = malloc(sizeof(float) * inputBindCount);
if(input->inputsPrevious == NULL) {
free(input->inputsCurrent);
free(input);
return NULL;
}
input->inputTime = malloc(sizeof(float) * inputBindCount);
if(input->inputTime == NULL) {
free(input->inputsPrevious);
free(input->inputsCurrent);
free(input);
return NULL;
}
return input;
}
void inputUpdate(input_t *input) {
// Flip the states to save memory.
float * currentCurrent = input->inputsCurrent;
input->inputsCurrent = input->inputsPrevious;
input->inputsPrevious = currentCurrent;
}
void inputDispose(input_t *input) {
free(input->inputTime);
free(input->inputsPrevious);
free(input->inputsCurrent);
free(input);
}
inputbindmap_t inputBind(input_t *input, inputbind_t bind,
inputsource_t *source
) {
return NULL;
}
float inputGetState(inputbind_t binding, inputsource_t *source) {
return 0;
}
bool inputIsDown(input_t *input, inputbind_t binding) {
return input->inputsCurrent[binding] != 0;
}
bool inputIsUp(input_t *input, inputbind_t binding) {
return input->inputsCurrent[binding] == 0;
}
bool inputIsPressed(input_t *input, inputbind_t binding) {
return (
input->inputsPrevious[binding] == 0 &&
input->inputsCurrent[binding] != 0
);
}
bool inputIsReleased(input_t *input, inputbind_t binding) {
return (
input->inputsCurrent[binding] == 0 &&
input->inputsPrevious[binding] != 0
);
}
float inputGetAxis(input_t *input, inputbind_t binding) {
return input->inputsCurrent[binding];
}
float inputGetFullAxis(input_t *input, inputbind_t positive,
inputbind_t negative
) {
return input->inputsCurrent[negative] + input->inputsCurrent[positive];
}
float inputGetAccuated(input_t *input, inputbind_t binding) {
return input->inputTime[binding];
}

176
src/input/input.h Normal file
View File

@ -0,0 +1,176 @@
// Copyright (c) 2021 Dominic Msters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <malloc.h>
/////////////////////////////// Type Definitions ///////////////////////////////
/**
* Input Source, can be a button or an axis. Currently a void type.
*/
typedef void inputsource_t;
/**
* Input Bind, a specific action bind reference for the game engine to use.
* e.g. "Jump" or "Walk Forward".
*/
typedef uint8_t inputbind_t;
/**
* Input Bind Map, contains the bound link between an inputsource_t and an
* inputbind_t. Bind Maps can be added and removed.
*/
typedef uint16_t inputbindmap_t;
/**
* Structure for the entire input mapping.
*/
typedef struct {
/** How many input bindings are in the input managers' scope */
uint32_t inputBindCount;
/** Float of the input between 0 and 1. For teh current frame */
float *inputsCurrent;
/** Float of the input between 0 and 1. For the last frame */
float *inputsPrevious;
/** Float of the GameTime that the input was actuated last. */
float *inputTime;
/**
* Array of pointers to all of the input sources. This must be set up by the
* platform to register each known input to poll on. Essentially the engine is
* going to query the platform for the current state of each input based on the
* entries within this list.
*/
inputsource_t **bindingSources;
/**
* Array of input bindings. This is the list of "possible actions" that the
* user can perform. This would contain "jump", "walk forward", "run"... etc.
*/
inputbind_t *INPUT_BINDING_BINDS;
} input_t;
//////////////////////////////////// Methods ///////////////////////////////////
/**
* Initializes the input manager.
*
* @param inputCount The input binding counts to allow for.
* @return The input manager
*/
input_t * inputInit(uint32_t inputBindCount);
/**
* Tick the input manager.
* @param input The input to update.
*/
void inputUpdate(input_t *input);
/**
* Destroy the input manager and cleanup.
* @param input The input to destroy.
*/
void inputDispose(input_t *input);
/**
* Binds the given input binding to the input source. Essentially allowing any
* time we fetch the state of bind, we will read the value from source.
*
* @param input The input manager to bind for.
* @param bind The binding to bind against
* @param source The source that is being bound.
* @return The map between the bind and the source, needed to unbind later.
*/
inputbindmap_t inputBind(input_t *input, inputbind_t bind,
inputsource_t *source
);
/**
* Platform-centric method. Method will be polled for each known input source to
* request the current state from the device. Values returned will be defined
* within the 0 to 1 range.
*
* @param binding The binding that has been created.
* @param source The input source, this was created when the binding was defined
* @return Input state between 0 and 1.
*/
float inputGetState(inputbind_t binding, inputsource_t *source);
/**
* Is the current input "down", not being pressed, being moved, not in a state
* of rest.
*
* @param state The input state to check against.
* @param binding The previously bound input binding.
* @return True if the input vector is non-zero.
*/
bool inputIsDown(input_t *state, inputbind_t binding);
/**
* Is the current input "up", in a state of rest, not being actioned, moved.
*
* @param state The input state to check against.
* @param binding The previously bound input binding.
* @return True if input vector is zero
*/
bool inputIsUp(input_t *state, inputbind_t binding);
/**
* Returns true on the first tick that an input was actioned/downed.
*
* @param input The input manager.
* @param binding The previously bound input binding.
* @return True if the input vector was non-zeroed this tick but not last.
*/
bool inputIsPressed(input_t *input, inputbind_t binding);
/**
* Returns true on the first tick that an input was released/upped.
*
* @param input The input manager.
* @param binding The previously bound input binding.
* @return True if the input vector was zeroed this tick but not last.
*/
bool inputIsReleased(input_t *input, inputbind_t binding);
/**
* Returns the raw input value as a float between 0 and 1. For digital (buttons)
* this will typicall be 0 or 1 only. Other analogue inputs will have anywhere
* within the range.
*
* @param input The input manager to check against.
* @param binding The previously bound input binding.
* @return A float between 0 and 1 representing the action force of the input.
*/
float inputGetAxis(input_t *input, inputbind_t binding);
/**
* Returns a raw input value between -1 and 1 between two axis. This would be
* indicitive of having an input with an axis that can be moved one direction
* for a positive input and another for a negative input, typically a game
* controller's analogue sticks.
*
* @param input The input manager to check against.
* @param postitive The positive axis binding.
* @param negative The negative axis binding.
* @return A float between -1 and 1 representing the result of both.
*/
float inputGetFullAxis(input_t *input, inputbind_t positive,
inputbind_t negative
);
/**
* Returns the time that an input was actuated at. Actuate would count as a
* non-zero input for analogue inputs.
*
* @param input The input manager to check against.
* @param binding The previously bound input binding.
* @return Game Engine time that an input was non-zeroed
*/
float inputGetAccuated(input_t *input, inputbind_t binding);

View File

@ -1,17 +1,22 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "main.h"
int32_t main() {
// Create the game instance
game_t *game = gameInit("Dawn");
game_t *game = gameInit();
if(game == NULL) return 1;
// Start running the game instance
gameStart(game);
// Game has finished running, cleanup.
if(!gameDispose(game)) {
return 1;
}
gameDispose(game);
return 0;
}

View File

@ -1,3 +1,10 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include <stdint.h>