Cleaned slate.

This commit is contained in:
2022-10-18 10:00:31 -07:00
parent 94914e2ebc
commit a9462a42cc
288 changed files with 1 additions and 132589 deletions

View File

@ -1,29 +0,0 @@
name: test
on:
push:
branches: [ master, main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v2.3.1
- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v1.9
with:
cmake-version: '3.13.x'
- name: Get Libraries
run: |
git submodule update --init --recursive
sudo apt install xorg-dev libglu1-mesa-dev
- name: Build
run: |
cmake -B build -DTARGET_TYPE=game -DTARGET_GAME=poker
cmake --build ./build
- name: Test
run: |
./build/test/tests

View File

@ -1,29 +0,0 @@
name: test
on:
pull_request:
branches: [ master, main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v2.3.1
- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v1.9
with:
cmake-version: '3.13.x'
- name: Get Libraries
run: |
git submodule update --init --recursive
sudo apt install xorg-dev libglu1-mesa-dev
- name: Build
run: |
cmake -B build -DTARGET_TYPE=test
cmake --build ./build
- name: Test
run: |
./build/test/tests

12
.gitmodules vendored
View File

@ -1,12 +0,0 @@
[submodule "lib/Unity"]
path = lib/Unity
url = https://github.com/ThrowTheSwitch/Unity.git
[submodule "lib/stb"]
path = lib/stb
url = https://github.com/nothings/stb
[submodule "lib/cglm"]
path = lib/cglm
url = https://github.com/recp/cglm
[submodule "lib/glfw"]
path = lib/glfw
url = https://github.com/glfw/glfw

View File

@ -1,86 +0,0 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Set up the base CMake stuff.
cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# Set some global flags
add_compile_definitions(
_CRT_SECURE_NO_WARNINGS=1
ASSET_PREFIX="../assets/"
)
# Do initial set up depending on the build target type.
if(TARGET_TYPE STREQUAL test)
set(TARGET_NAME test)
elseif(TARGET_TYPE STREQUAL game)
set(TARGET_NAME ${TARGET_GAME})
else()
message(FATAL_ERROR "Missing or invalid definition of TARGET_TYPE")
endif()
# Check game has been defined
if(NOT DEFINED TARGET_GAME)
message(FATAL_ERROR "Missing or invalid definition of TARGET_GAME")
endif()
# Set up the project
project(${TARGET_NAME} C)
add_executable(${PROJECT_NAME})
# Variables
set(ROOT_DIR "${CMAKE_SOURCE_DIR}")
set(BUILD_DIR "${CMAKE_BINARY_DIR}")
set(TOOLS_DIR "${ROOT_DIR}/tools")
set(ASSETS_SOURCE_DIR "${ROOT_DIR}/assets")
set(ASSETS_BUILD_DIR "${BUILD_DIR}/assets")
set(TEMP_DIR "${BUILD_DIR}/temp")
# Add global sources.
add_subdirectory(lib)
# Setup Platform specific libraries
set(LIBS_PLATFORM "")
if(NOT WIN32)
list(APPEND LIBS_PLATFORM m)
endif()
# Include tools
add_subdirectory(tools)
# Include the client or the test tools
if(TARGET_TYPE STREQUAL test)
add_subdirectory(test)
endif()
# Set up shared assets
tool_copy(shader_textured
${ASSETS_SOURCE_DIR}/shared/shaders/textured.vert shaders/textured.vert
${ASSETS_SOURCE_DIR}/shared/shaders/textured.frag shaders/textured.frag
)
tool_copy(shader_singlerenderlist
${ASSETS_SOURCE_DIR}/shared/shaders/singlerenderlist.vert shaders/singlerenderlist.vert
${ASSETS_SOURCE_DIR}/shared/shaders/singlerenderlist.frag shaders/singlerenderlist.frag
)
tool_copy(font_opensans
${ASSETS_SOURCE_DIR}/shared/fonts/opensans/OpenSans-Regular.ttf fonts/opensans/OpenSans-Regular.ttf
${ASSETS_SOURCE_DIR}/shared/fonts/opensans/OpenSans-Bold.ttf fonts/opensans/OpenSans-Bold.ttf
)
tool_texture(texture_test
${ASSETS_SOURCE_DIR}/shared/textures/test_texture.png textures/test_texture
)
tool_copy(locale_en
${ASSETS_SOURCE_DIR}/locale/language/en-US.csv locale/language/en-US.csv
)
# Add actual game sources
add_subdirectory(src)

View File

@ -1,6 +0,0 @@
- Create a better buffer means for the CSV variables.
- Determine what's using all the memory.
- Start writing the language, storyboard if I need to.
- UI time
- AI Poker
- Begin considering audio.

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2021 Dominic Msters Copyright (c) 2022 Dominic Msters
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,14 +0,0 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# add_subdirectory(Unity)
add_subdirectory(cglm)
add_subdirectory(glfw)
add_subdirectory(duktape)
add_subdirectory(glad)
# STB
add_library(stb INTERFACE)
target_include_directories(stb INTERFACE stb)

Submodule lib/Unity deleted from b19370cc2b

Submodule lib/cglm deleted from 87f561fb06

View File

@ -1,12 +0,0 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
cmake_minimum_required(VERSION 3.11)
project(duktape)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
add_library(${PROJECT_NAME} STATIC duktape.c)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
cmake_minimum_required(VERSION 3.11)
project(glad)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
add_library(${PROJECT_NAME}
src/glad.c
)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

View File

@ -1,290 +0,0 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are 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 Materials.
**
** THE MATERIALS ARE 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
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
# define KHRONOS_STATIC 1
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(KHRONOS_STATIC)
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
* header compatible with static linking. */
# define KHRONOS_APICALL
#elif defined(_WIN32)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# define KHRONOS_APICALL __attribute__((visibility("default")))
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef _WIN64
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Submodule lib/glfw deleted from fb0f2f92a3

View File

@ -1,12 +0,0 @@
{
"name": "dawn",
"version": "1.0.0",
"repository": "https://YourWishes@github.com/YourWishes/Dawn.git",
"author": "Dominic Masters <dominic@domsplace.com>",
"license": "MIT",
"private": true,
"dependencies": {
"pngjs": "^6.0.0",
"xml-js": "^1.6.11"
}
}

View File

@ -1,44 +0,0 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Dawn Libraries
target_link_libraries(${PROJECT_NAME}
PUBLIC
${LIBS_PLATFORM}
glad
cglm
stb
)
target_include_directories(${PROJECT_NAME}
PRIVATE
${LIBS_PLATFORM}
)
# Source H files
target_include_directories(${PROJECT_NAME}
PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
# Add in each part of the engine.
add_subdirectory(display)
add_subdirectory(engine)
add_subdirectory(epoch)
add_subdirectory(file)
add_subdirectory(input)
add_subdirectory(locale)
add_subdirectory(physics)
add_subdirectory(poker)
add_subdirectory(save)
add_subdirectory(scene)
add_subdirectory(util)
# add_subdirectory(vn)
# Add client and game
if(TARGET_TYPE STREQUAL game)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/games/${TARGET_GAME})
add_subdirectory(client)
endif()

View File

@ -1,30 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#define ASSERT_TRUE(x) assert(x)
#define ASSERT_FALSE(x) ASSERT_TRUE((x) == false)
#define ASSERT_NOT_NULL(x) ASSERT_FALSE(x == NULL)
#define ASSERT_IF(x, y) (x ? y : false)
#define ASSERT_EQUAL(x, y) ASSERT_TRUE(x == y)
#define ASSERT_NOT_EQUAL(x, y) ASSERT_TRUE(x != y)
#define ASSERT_LESS_THAN(x, y) ASSERT_TRUE(x < y)
#define ASSERT_LESS_THAN_EQUAL_TO(x, y) ASSERT_TRUE(x <= y)
#define ASSERT_GREATER_THAN(x, y) ASSERT_TRUE(x > y)
#define ASSERT_GREATER_THAN_EQUAL_TO(x, y) ASSERT_TRUE(x >= y)
#define ASSERT_FLAG_OFF(flags, flag) ASSERT_FALSE(flags & flag)
#define ASSERT_FLAG_ON(flags, flag) ASSERT_TRUE(flags & flag)
#define ASSERT_STRING_EQUALS(a, b) ASSERT_EQUAL(strcmp(a, b), 0)

View File

@ -1,6 +0,0 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
add_subdirectory(glfwclient)

View File

@ -1,16 +0,0 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Libraries
target_link_libraries(${PROJECT_NAME}
PUBLIC
glfw
glad
)
target_sources(${PROJECT_NAME}
PRIVATE
glfwclient.c
)

View File

@ -1,158 +0,0 @@
// Copyright (c) 2021 Dominic Msters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "glfwclient.h"
static game_t *GAME_STATE;
static GLFWwindow *window = NULL;
int32_t main() {
double time, newTime;
game_t *game;
input_t *input;
float fDelta;
// Attempt to init GLFW
if(!glfwInit()) return 1;
// Setup window hints
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, false);
// Create Window
window = glfwCreateWindow(
WINDOW_WIDTH_DEFAULT, WINDOW_HEIGHT_DEFAULT, "", NULL, NULL
);
if(!window) {
glfwTerminate();
return 1;
}
// Load GLAD
glfwMakeContextCurrent(window);
glfwSwapInterval(0);
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
// Setup window listeners
glfwSetWindowSizeCallback(window, &glfwOnResize);
glfwSetKeyCallback(window, &glfwOnKey);
glfwSetErrorCallback(&glfwOnError);
glfwSetCursorPosCallback(window, &glfwOnCursor);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
// Prepare the game
game = malloc(sizeof(game_t));
ASSERT_NOT_NULL(game);
GAME_STATE = game;
input = &game->engine.input;
printf("Game is %zu bytes.\n", sizeof(game_t));
// Init the render resolution
renderSetResolution(&game->engine.render,
WINDOW_WIDTH_DEFAULT, WINDOW_HEIGHT_DEFAULT
);
// Init the game
if(gameInit(game)) {
// Bind initial keys
inputBind(input, INPUT_NULL, glfwGetInputSourceForKey(GLFW_KEY_ESCAPE));
inputBind(input, INPUT_UP, glfwGetInputSourceForKey(GLFW_KEY_UP));
inputBind(input, INPUT_DOWN, glfwGetInputSourceForKey(GLFW_KEY_DOWN));
inputBind(input, INPUT_LEFT, glfwGetInputSourceForKey(GLFW_KEY_LEFT));
inputBind(input, INPUT_RIGHT, glfwGetInputSourceForKey(GLFW_KEY_RIGHT));
inputBind(input, INPUT_UP, glfwGetInputSourceForKey(GLFW_KEY_W));
inputBind(input, INPUT_DOWN, glfwGetInputSourceForKey(GLFW_KEY_S));
inputBind(input, INPUT_LEFT, glfwGetInputSourceForKey(GLFW_KEY_A));
inputBind(input, INPUT_RIGHT, glfwGetInputSourceForKey(GLFW_KEY_D));
inputBind(input, INPUT_ACCEPT, glfwGetInputSourceForKey(GLFW_KEY_E));
inputBind(input, INPUT_ACCEPT, glfwGetInputSourceForKey(GLFW_KEY_ENTER));
inputBind(input, INPUT_ACCEPT, glfwGetInputSourceForKey(GLFW_KEY_SPACE));
// Bind the fake inputs
inputBind(input, INPUT_MOUSE_X, GLFW_PLATFORM_INPUT_MOUSE_X);
inputBind(input, INPUT_MOUSE_Y, GLFW_PLATFORM_INPUT_MOUSE_Y);
// Set up some GLFW stuff
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
glfwSetWindowTitle(window, game->engine.name);
// Begin time.
time = 0;
// Main Render Loop
while(!glfwWindowShouldClose(window)) {
glfwPollEvents();
// Determine the delta.
newTime = glfwGetTime();
fDelta = (float)(newTime - time);
time = newTime;
// Tick the engine.
if(!gameUpdate(game, fDelta)) break;
glfwSwapBuffers(window);
sleep(0);//Fixes some weird high CPU bug, not actually necessary.
}
// Game has finished running, cleanup.
gameDispose(game);
}
free(game);
// Terminate the GLFW context.
glfwSetWindowSizeCallback(window, NULL);
glfwTerminate();
return 0;
}
void glfwOnResize(GLFWwindow *window, int32_t width, int32_t height) {
ASSERT_NOT_NULL(window);
ASSERT_GREATER_THAN(width, 0);
ASSERT_GREATER_THAN(height, 0);
renderSetResolution(&GAME_STATE->engine.render, (float)width, (float)height);
}
void glfwOnKey(GLFWwindow *window,
int32_t key, int32_t scancode, int32_t action, int32_t mods
) {
input_t *input;
ASSERT_NOT_NULL(window);
input = &GAME_STATE->engine.input;
if(action == GLFW_PRESS) {
inputStateSet(input, glfwGetInputSourceForKey(key), 1.0f);
} else if(action == GLFW_RELEASE) {
inputStateSet(input, glfwGetInputSourceForKey(key), 0.0f);
}
}
void glfwOnError(int error, const char* description) {
fputs(description, stderr);
}
void glfwOnCursor(GLFWwindow *window, double x, double y) {
input_t *input;
ASSERT_NOT_NULL(window);
input = &GAME_STATE->engine.input;
inputStateSet(input, GLFW_PLATFORM_INPUT_MOUSE_X, (float)x);
inputStateSet(input, GLFW_PLATFORM_INPUT_MOUSE_Y, (float)y);
}
inputsource_t glfwGetInputSourceForKey(int32_t key) {
return (inputsource_t)((
key <= GLFW_KEY_GRAVE_ACCENT ? key - GLFW_KEY_SPACE :
key <= GLFW_KEY_MENU ? key - GLFW_KEY_ESCAPE + GLFW_KEY_GRAVE_ACCENT :
key
) % INPUT_SOURCE_COUNT);
}
void glfwClientSetTitle(char *name) {
ASSERT_NOT_NULL(window);
glfwSetWindowTitle(window, name);
}

View File

@ -1,59 +0,0 @@
// 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 <GLFW/glfw3.h>
#include <libs.h>
#include "display/render.h"
#include "assert/assert.h"
#include "input/input.h"
#include "game/game.h"
#define WINDOW_WIDTH_DEFAULT 1280
#define WINDOW_HEIGHT_DEFAULT WINDOW_WIDTH_DEFAULT/16*9
#define GLFW_PLATFORM_INPUT_MOUSE_X (inputsource_t)0xFF
#define GLFW_PLATFORM_INPUT_MOUSE_Y (inputsource_t)0xFE
/**
* Entry of the program
* @return 0 if success, anything else for failure.
*/
int32_t main();
/**
* Resize callbacks.
*
* @param window Window that was resized.
* @param width New window width.
* @param height New window height.
*/
void glfwOnResize(GLFWwindow *window, int32_t width, int32_t height);
/**
* Keyboard Input callbacks.
*
* @param window Window that was resized.
*/
void glfwOnKey(GLFWwindow *window,
int32_t key, int32_t scancode, int32_t action, int32_t mods
);
void glfwOnError(int error, const char* description);
void glfwOnCursor(GLFWwindow *window, double x, double y);
/**
* Get the game engine specific input source for a given GLFW Key code.
*
* @param key Key to get the input source for.
* @return The input source.
*/
inputsource_t glfwGetInputSourceForKey(int32_t key);
/** GLFW Client Methods */
void glfwClientSetTitle(char *name);

View File

@ -1,26 +0,0 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${PROJECT_NAME}
PRIVATE
bitmapfont.c
camera.c
font.c
framebuffer.c
matrix.c
render.c
renderlist.c
shaderprogram.c
spritebatch.c
texture.c
tileset.c
)
# Subdirs
add_subdirectory(animation)
add_subdirectory(primitive)
add_subdirectory(shaders)
# add_subdirectory(ui)

View File

@ -1,13 +0,0 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${PROJECT_NAME}
PRIVATE
animation.c
easing.c
queue.c
timeline.c
)

View File

@ -1,20 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "animation.h"
float animForwardAndBackward(float t) {
return (t < 0.5 ? t : 1 - t);
}
float animForwardAndBackwardScaled(float t) {
return animForwardAndBackward(t) * 2.0f;
}
float animTimeScaleFromFrameTime(int32_t frames, float time) {
return 1.0f / (float)frames / time;
}

View File

@ -1,38 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../../libs.h"
/**
* Animation tool for converting 0-1 space into a 0-0.5 back to zero space. This
* is intended to make a "Forward then backwards" effect for animation. This
* method will not scale t.
* @param t Time in space to back and fourth on between 0 and 1.
* @returns Forward and backwards time. 0 to 0.5 are as such, 0.5 to 1 are from
* 0.5 to 0.
*/
float animForwardAndBackward(float t);
/**
* Animation tool for converting 0-1 space into a 0-1-0 space. Scaled version of
* animForwardAndBackward().
* @param t Time in space to back and fourth on between 0 and 1.
* @returns Forward and backwards time.
*/
float animForwardAndBackwardScaled(float t);
/**
* Returns the time scale (speed to multiply time range by) for a given frame
* time and frame count. E.g. 3 frames at 0.5 time each would have a time scale
* of 1.5.
*
* @param frames Frames to get the scale of.
* @param time Time to get the scale of.
* @return The time scale.
*/
float animTimeScaleFromFrameTime(int32_t frames, float time);

View File

@ -1,60 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "easing.h"
float easeLinear(float t) {
return t;
}
float easeInQuad(float t) {
return t * t;
}
float easeOutQuad(float t) {
return t * (2 - t);
}
float easeInOutQuad(float t) {
return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
}
float easeInCubic(float t) {
return t * t * t;
}
float easeOutCubic(float t) {
return (t - 1) * (t - 1) * (t - 1) + 1;
}
float easeInOutCubic(float t) {
return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
}
float easeInQuart(float t) {
return t * t * t * t;
}
float easeOutQuart(float t) {
return 1 - (t-1)*(t-1)*(t-1)*(t-1);
}
float easeInOutQuart(float t) {
return t < .5 ? 8*t*t*t*t : 1-8*(t-1)*(t-1)*(t-1)*(t-1);
}
float easeInQuint(float t) {
return t*t*t*t*t;
}
float easeOutQuint(float t) {
return 1 + (t-1)*(t-1)*(t-1)*(t-1)*(t-1);
}
float easeInOutQuint(float t) {
return t<.5 ? 16*t*t*t*t*t : 1+16*(t-1)*(t-1)*(t-1)*(t-1)*(t-1);
}

View File

@ -1,32 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
typedef float easefunction_t(float t);
/**
* Returns the ease time for a given real time duration span.
* @param start At what point in time the animation started
* @param current The current point in time the animation is at.
* @param duration The total duration on the animation.
* @returns The easing time (0-1 time) that the animation is at.
*/
#define easeTimeToEase(start, current, duration) ((current-start)/duration)
float easeLinear(float t);
float easeInQuad(float t);
float easeOutQuad(float t);
float easeInOutQuad(float t);
float easeInCubic(float t);
float easeOutCubic(float t);
float easeInOutCubic(float t);
float easeInQuart(float t);
float easeOutQuart(float t);
float easeInOutQuart(float t);
float easeInQuint(float t);
float easeOutQuint(float t);
float easeInOutQuint(float t);

View File

@ -1,125 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "queue.h"
void queueInit(queue_t *queue) {
ASSERT_NOT_NULL(queue);
queue->timeline = 0;
queue->count = 0;
queue->current = ANIMATION_QUEUE_START;
}
queueaction_t * queueNext(queue_t *queue) {
queueaction_t *action;
ASSERT_NOT_NULL(queue);
// Is there a currently running action? If so, end it.
if(queue->current != ANIMATION_QUEUE_START) {
action = queue->items + queue->current;
if(action->onEnd != NULL) action->onEnd(queue, action, queue->current);
}
// Prepare to go to next action if there is a next action.
queue->current++;
queue->actionStarted = queue->timeline;
if(queue->current >= queue->count) return NULL;
// Go to next action, start it.
action = queue->items + queue->current;
if(action->onStart != NULL) action->onStart(queue, action, queue->current);
return action;
}
queueaction_t * queueAdd(queue_t *queue) {
queueaction_t *action;
ASSERT_NOT_NULL(queue);
ASSERT_LESS_THAN(queue->count, ANIMATION_QUEUE_ITEM_MAX);
action = queue->items + queue->count;
action->index = queue->count;
action->data = NULL;
action->onStart = NULL;
action->onUpdate = NULL;
action->onEnd = NULL;
queue->count++;
return action;
}
void queueUpdate(queue_t *queue, float delta) {
queueaction_t *action;
ASSERT_NOT_NULL(queue);
ASSERT_GREATER_THAN(delta, 0);
queue->timeline += delta;
if(queue->current >= queue->count) return;
action = queue->items + queue->current;
if(action->onUpdate != NULL) {
action->onUpdate(queue, action, queue->current);
}
}
void queueDispose(queue_t *queue) {
queueaction_t *action;
ASSERT_NOT_NULL(queue);
if(queue->current >= queue->count) return;
action = queue->items + queue->current;
if(action->onEnd != NULL) action->onEnd(queue, action, queue->current);
}
void queueRestack(queue_t *queue) {
uint8_t i;
ASSERT_NOT_NULL(queue);
// Rewind the array.
if(queue->current == 0) return;
arrayRewind(sizeof(queueaction_t), queue->items, ANIMATION_QUEUE_START,
queue->current, queue->count
);
// Now rewind the stack
queue->count -= queue->current;
queue->current = 0;
// Now fix indexes
for(i = 0; i < queue->count; i++) {
queue->items[i].index = i;
}
}
void _queueDelayUpdate(queue_t *queue, queueaction_t *action, uint8_t i) {
float n;
ASSERT_NOT_NULL(queue);
ASSERT_NOT_NULL(action);
ASSERT_GREATER_THAN_EQUAL_TO(i, 0);
n = queue->timeline - queue->actionStarted;
if(n < queue->delays[i]) return;
queueNext(queue);
}
queueaction_t * queueDelay(queue_t *queue, float delay) {
queueaction_t *action;
ASSERT_NOT_NULL(queue);
ASSERT_GREATER_THAN(delay, 0);
action = queueAdd(queue);
queue->delays[action->index] = delay;
action->onUpdate = &_queueDelayUpdate;
return action;
}

View File

@ -1,113 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../../libs.h"
#include "../../util/array.h"
#define ANIMATION_QUEUE_ITEM_MAX 128
#define ANIMATION_QUEUE_START 0xFF
typedef struct _queueaction_t queueaction_t;
typedef struct _queue_t queue_t;
/**
* Callback for queue events.
* @param conversation Conversation this text is attached to.
* @param text Text item that is being used in the callback
* @param i Index of the item in the queue.
*/
typedef void queuecallback_t(queue_t *queue, queueaction_t *action, uint8_t i);
typedef struct _queueaction_t {
/** Index that the action is within the queue */
uint8_t index;
/** Pointer to any custom user data */
void *data;
/** Callback to fire the moment the action is active in the queue */
queuecallback_t *onStart;
/** Callback to fire when this action has ended */
queuecallback_t *onEnd;
/** Callback to fire every update of this queue while action is active. */
queuecallback_t *onUpdate;
} queueaction_t;
typedef struct _queue_t {
/** Array of items within the queue. */
queueaction_t items[ANIMATION_QUEUE_ITEM_MAX];
uint8_t count;
/** Current index within the array of actions that is currently processing */
uint8_t current;
/** Internal timeline tracking */
float timeline;
/** Time that the current aciton started */
float actionStarted;
/** Delay Queue Item Storage */
float delays[ANIMATION_QUEUE_ITEM_MAX];
} queue_t;
/**
* Initialize the queue set.
* @param queue Queue to initialize.
*/
void queueInit(queue_t *queue);
/**
* Goes to the next action, or start the queue if this is the first action.
* @param queue Queue to skip to the next action.
* @returns Action that was just started.
*/
queueaction_t * queueNext(queue_t *queue);
/**
* Add a queue action to the queue.
* @param convo Queue to add to.
* @return Pointer to the queue action that was added.
*/
queueaction_t * queueAdd(queue_t *queue);
/**
* Updates the queue logic.
* @param convo Queue to update.
* @param delta Time delta to tick the queue by.
*/
void queueUpdate(queue_t *queue, float delta);
/**
* Dispose the queue when finished.
* @param queue Queue to dispose.
*/
void queueDispose(queue_t *queue);
/**
* Restacks the queue. The restack process essentially rewinds the queue so that
* the current items move back to position 0, and allows you to add more items
* to the queue again. Because the memory does shift, and the indexes do change
* a lot of your pointers will break, make sure you re-reference all your
* pointers.
*
* @param queue Queue to restack.
*/
void queueRestack(queue_t *queue);
/** Callbacks for Queue Delay Action */
void _queueDelayUpdate(queue_t *queue, queueaction_t *action, uint8_t i);
/**
* Adds a delay action to a queue.
* @param queue Queue to add to.
* @param delay Delay time (in seconds) to have.
* @return Pointer to the action added to the queue.
*/
queueaction_t * queueDelay(queue_t *queue, float delay);

View File

@ -1,184 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "timeline.h"
void _timelineActionDeltaUpdateStart(
timeline_t *timeline, timelineaction_t *action, uint8_t i
) {
ASSERT_NOT_NULL(timeline);
ASSERT_NOT_NULL(action);
ASSERT_GREATER_THAN_EQUAL_TO(i, 0);
ASSERT_LESS_THAN(i, TIMELINE_ACTION_COUNT_MAX);
if(action->data == NULL) return;
*((float *)action->data) = timeline->initials[i];
}
void _timelineActionDeltaUpdateDuration(
timeline_t *timeline, timelineaction_t *action, uint8_t i
) {
float n;
ASSERT_NOT_NULL(timeline);
ASSERT_NOT_NULL(action);
ASSERT_GREATER_THAN_EQUAL_TO(i, 0);
ASSERT_LESS_THAN(i, TIMELINE_ACTION_COUNT_MAX);
if(action->data == NULL) return;
n = timeline->easings[i](
timelineActionGetTimeRaw(timeline, action)
);
*((float *)action->data) = timeline->initials[i] + (timeline->deltas[i] * n);
}
void _timelineActionDeltaUpdateEnd(
timeline_t *timeline, timelineaction_t *action, uint8_t i
) {
ASSERT_NOT_NULL(timeline);
ASSERT_NOT_NULL(action);
ASSERT_GREATER_THAN_EQUAL_TO(i, 0);
ASSERT_LESS_THAN(i, TIMELINE_ACTION_COUNT_MAX);
if(action->data == NULL) return;
*((float *)action->data) = timeline->initials[i] + timeline->deltas[i];
}
void timelineInit(timeline_t *timeline) {
ASSERT_NOT_NULL(timeline);
timeline->current = 0;
timeline->diff = 0;
timeline->previous = 0;
timeline->user = 0;
timeline->actionCount = 0;
}
void timelineUpdate(timeline_t *timeline, float delta) {
uint8_t i;
timelineaction_t *action;
float full;
ASSERT_NOT_NULL(timeline);
ASSERT_GREATER_THAN(delta, 0);
timeline->diff = delta;
timeline->previous = timeline->current;
timeline->current = timeline->current + delta;
// Find all actions that would have started or ended in this timespan.
for(i = 0; i < timeline->actionCount; i++) {
action = timeline->actions +i;
// Has the action started yet?
if(action->start > timeline->current) continue;
// Did we start this frame?
if(action->start > timeline->previous && action->onStart != NULL) {
action->onStart(timeline, action, i);
}
// Durations of 0 only fire starts, never ends or durations.
if(action->duration == 0) continue;
// Is the end still in the future? Durations in negatives go forever
full = action->start+action->duration;
if(action->duration < 0 || full > timeline->current) {
if(action->onDuration != NULL) action->onDuration(timeline, action, i);
} else if(full > timeline->previous) {// Did we end this frame?
if(action->onEnd != NULL) action->onEnd(timeline, action, i);
if(action->loop) action->start = timeline->current;
}
}
}
bool timelineIsFinished(timeline_t *timeline) {
uint8_t i;
timelineaction_t *action;
ASSERT_NOT_NULL(timeline);
for(i = 0; i < timeline->actionCount; i++) {
action = timeline->actions +i;
if(action->start > timeline->current) return false;
if(action->duration < 0) return false;
if(action->duration == 0) continue;
if(action->start+action->duration > timeline->current) return false;
}
return true;
}
timelineaction_t * timelineAddAction(timeline_t *timeline, float start,
float duration
) {
timelineaction_t *action;
ASSERT_NOT_NULL(timeline);
ASSERT_LESS_THAN(timeline->actionCount, TIMELINE_ACTION_COUNT_MAX);
ASSERT_GREATER_THAN_EQUAL_TO(start, 0);
ASSERT_IF(duration < 0, ASSERT_EQUAL(duration, -1));
action = timeline->actions + (timeline->actionCount++);
action->loop = false;
action->start = start, action->duration = duration;
action->onStart = action->onEnd = action->onDuration = NULL;
return action;
}
timelineaction_t * timelineAddDeltaAction(timeline_t *timeline,
float start, float duration, float initial, float delta,
easefunction_t *easing, float *destination
) {
timelineaction_t *action;
ASSERT_NOT_NULL(timeline);
timeline->initials[timeline->actionCount] = initial;
timeline->deltas[timeline->actionCount] = delta;
timeline->easings[timeline->actionCount] = (
easing == NULL ? &easeLinear : easing
);
action = timelineAddAction(timeline, start, duration);
action->data = destination;
action->onStart = &_timelineActionDeltaUpdateStart;
action->onDuration = &_timelineActionDeltaUpdateDuration;
action->onEnd = &_timelineActionDeltaUpdateEnd;
return action;
}
timelineaction_t * timelineAddDeltaActionTo(timeline_t *timeline,
float start, float duration, float initial, float end,
easefunction_t *easing, float *destination
) {
ASSERT_NOT_NULL(timeline);
return timelineAddDeltaAction(
timeline, start, duration, initial, end-initial, easing, destination
);
}
float timelineActionGetTimeRaw(timeline_t *timeline, timelineaction_t *action) {
ASSERT_NOT_NULL(timeline);
ASSERT_NOT_NULL(action);
return (timeline->current - action->start) / action->duration;
}
float timelineActionGetTime(timeline_t *tl, timelineaction_t *at) {
ASSERT_NOT_NULL(tl);
ASSERT_NOT_NULL(at);
return mathClamp(timelineActionGetTimeRaw(tl, at), 0, 1);
}
void timelineClear(timeline_t *timeline) {
ASSERT_NOT_NULL(timeline);
timeline->actionCount = 0;
}

View File

@ -1,188 +0,0 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../../libs.h"
#include "../../assert/assert.h"
#include "../../util/math.h"
#include "easing.h"
/** Maximum number of actions a timeline can support, smaller than 0xFF */
#define TIMELINE_ACTION_COUNT_MAX 128
/** Type forwarders */
typedef struct _timeline_t timeline_t;
typedef struct _timelineaction_t timelineaction_t;
/**
* Callback for when a timeline event occurs
* @param timeline The timeline that fired this callback.
* @param action The action that this callback is attached to.
* @param i The index that this action is within the timeline.
*/
typedef void timelinecallback_t(timeline_t *timeline, timelineaction_t *action,
uint8_t i
);
typedef struct _timelineaction_t {
/** Pointer to any custom user data the timeline action wants to use. */
void *data;
/**
* The time that this action should occur within the timeline
* set to 0 or less to start immediately.
*/
float start;
/**
* The duration of the action, this will decide for how long onDuration will
* be called for, and when onEnd should be called.
* Set to a negative number to have this continue forever.
* Set to 0 to only fire the onStart.
* onStart can fire with either onDuration and onEnd on the same frame, but
* onEnd and onDuration cannot fire the same frame.
*/
float duration;
/**
* Enables animation looping. This works by forcing start to be equal to the
* current time at the point in time that onEnd is called. This will also stop
* onStart being called so ensure that your onStart and onEnd logic works.
*/
bool loop;
timelinecallback_t *onStart;
timelinecallback_t *onDuration;
timelinecallback_t *onEnd;
} timelineaction_t;
typedef struct _timeline_t {
/** The current time as far as the timeline is concerned */
float current;
/** The time of the last "frame" as far as the timeline is concerned */
float previous;
/** The frame time diff, essentially current = previous + diff */
float diff;
/** User pointer, allows you to point to some other data */
void *user;
/** Actions within the timeline */
timelineaction_t actions[TIMELINE_ACTION_COUNT_MAX];
/** For delta actions, storage of the initial values */
float initials[TIMELINE_ACTION_COUNT_MAX];
/** For delta actions, storage of their deltas. */
float deltas[TIMELINE_ACTION_COUNT_MAX];
/** Easing functions to use for delta functions */
easefunction_t *easings[TIMELINE_ACTION_COUNT_MAX];
uint8_t actionCount;
} timeline_t;
/**
* Initializes a timeline back to its default state.
*
* @param timeline Timeline to initialize.
*/
void timelineInit(timeline_t *timeline);
/**
* Ticks the timeline. This can be done using any delta.
*
* @param timeline Timeline to tick
* @param delta Delta to tick.
*/
void timelineUpdate(timeline_t *timeline, float delta);
/**
* Returns true if every action in the timeline has finished.
*
* @param timeline Timeline to check
* @return True if finished, otherwise false.
*/
bool timelineIsFinished(timeline_t *timeline);
/**
* Adds an action to the timeline. This will initialize the action callbacks to
* NULL, you will need to initialize your own callbacks.
*
* @param timeline Timeline to add to.
* @param start Start time.
* @param duration Duration time
* @return Pointer to the timeline action or NULL if the list is full.
*/
timelineaction_t * timelineAddAction(timeline_t *timeline, float start,
float duration
);
/**
* Add a special action kind that can treat delta style animations. These are
* animations that have a start, and an end value, that will be tracked for you
* and keep you up to date.
*
* @param timeline Timeline to add to.
* @param start Starting time.
* @param duration Animation duration.
* @param initial Initial value for the animation.
* @param delta Delta value for the animation.
* @param easing Pointer to an easing function to use, set to NULL for linear.
* @param destination A constant floating point to update.
* @return The queued timeline action.
*/
timelineaction_t * timelineAddDeltaAction(timeline_t *timeline,
float start, float duration, float initial, float delta,
easefunction_t *easing, float *destination
);
/**
* Shorthand for timelineAddDeltaAction that will calculate the delta based on
* and end position.
*
* @param timeline Timeline to add to.
* @param start Starting time.
* @param duration Animation duration.
* @param initial Initial value for the animation.
* @param end End value for the animation.
* @param easing Pointer to an easing function to use, set to NULL for linear.
* @param destination A constant floating point to update.
* @return The queued timeline action.
*/
timelineaction_t * timelineAddDeltaActionTo(timeline_t *timeline,
float start, float duration, float initial, float end,
easefunction_t *easing, float *destination
);
/**
* Gets the timeline action's animation time. This is a representation of
* 0 - 1 where 0 means the animation is at the start, and 1 meaning the
* animation is at full completion. This is not clamped and may exceed 1.
*
* @param timeline Timeline the action belongs to.
* @param action Action itself.
* @return 0 - 1+, where 0 = start, 1 = duration, >1 is time since duration.
*/
float timelineActionGetTimeRaw(timeline_t *timeline, timelineaction_t *action);
/**
* Gets the timeline action's animation time between 0 - 1, clamped.
*
* @param tl Timeline to get delta from.
* @param at Timeline action.
* @return 0 - 1, where 0 = start, 1 = duration.
*/
float timelineActionGetTime(timeline_t *tl, timelineaction_t *at);
/**
* Removes all actions from the timeline.
*
* @param timeline Timeline to clear.
*/
void timelineClear(timeline_t *timeline);

View File

@ -1,127 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "bitmapfont.h"
tilesetdiv_t * bitmapFontGetCharacterDivision(tileset_t *tileset,
char character
) {
int32_t i = ((int32_t)character) - BITMAP_FONT_CHAR_START;
ASSERT_NOT_NULL(tileset);
return tileset->divisions + i;
}
bitmapfontmeasure_t bitmapFontMeasure(char *string,
float charWidth, float charHeight
) {
int32_t i;
float x, y;
char c;
bitmapfontmeasure_t measure = {
.height = 0, .lines = 1, .width = 0
};
ASSERT_NOT_NULL(string);
ASSERT_GREATER_THAN(charWidth, 0);
ASSERT_GREATER_THAN(charHeight, 0);
i = 0;
y = 0;
x = 0;
while(true) {
c = string[i];
if(c == '\0') break;
i++;
if(c == '\n') {
measure.width = mathMax(x, measure.width);
x = 0;
y += charHeight;
measure.lines++;
continue;
} else if(c == ' ') {
x += charWidth;
continue;
}
x += charWidth;
}
measure.width = mathMax(x, measure.width);
measure.height = y + charHeight;
return measure;
}
bitmapfontmeasure_t bitmapFontSpriteBatchBuffer(
spritebatch_t *batch, tileset_t *tileset,
char *string, float x, float y, float z, float charWidth, float charHeight
) {
int32_t i;
char c;
tilesetdiv_t *div;
float cx, cy;
bitmapfontmeasure_t measure;
// Detect char dimensions
if(charWidth == -1) charWidth = tileset->divX * (charHeight / tileset->divY);
if(charHeight == -1) charHeight = tileset->divY * (charWidth / tileset->divX);
// Position the text.
if(x == BITMAP_FONT_CENTER_X ||
y == BITMAP_FONT_CENTER_Y ||
x == BITMAP_FONT_RIGHT_X
) {
measure = bitmapFontMeasure(string, charWidth, charHeight);
if(x == BITMAP_FONT_CENTER_X) {
x = -(measure.width/2);
} else if(x == BITMAP_FONT_RIGHT_X) {
x = -measure.width;
}
if(y == BITMAP_FONT_CENTER_Y) y = -(measure.height/2);
}
// Begin buffering the sprite batch
measure.width = 0;
measure.height = 0;
measure.lines = 1;
i = 0;
cx = x, cy = y;
while(true) {
c = string[i];
if(c == '\0') break;
i++;
// Special chars
if(c == '\n') {
measure.width = mathMax(cx-x, measure.width);
cx = x;
cy += charHeight;
measure.lines++;
continue;
} else if(c == ' ') {
cx += charWidth;
continue;
}
div = bitmapFontGetCharacterDivision(tileset, c);
spriteBatchQuad(batch, -1,
cx, cy, z, charWidth, charHeight,
div->x0, div->y1, div->x1, div->y0
);
cx += charWidth;
}
measure.width = mathMax(cx-x, measure.width);
measure.height = cy-y + charHeight;
return measure;
}

View File

@ -1,72 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "../assert/assert.h"
#include "spritebatch.h"
#include "tileset.h"
#include "../util/math.h"
/** Which is the first character within the font tilemap */
#define BITMAP_FONT_CHAR_START 33
/** Center a font along the X axis */
#define BITMAP_FONT_CENTER_X 9876543
/** Center a font along the Y axis */
#define BITMAP_FONT_CENTER_Y -BITMAP_FONT_CENTER_X
/** Align right edge of font to origin */
#define BITMAP_FONT_RIGHT_X (BITMAP_FONT_CENTER_X-1)
typedef struct {
float width, height;
int32_t lines;
} bitmapfontmeasure_t;
/**
* Get the division for a given character.
*
* @param tileset Tileset to get the division from.
* @param character Character to get the division for.
* @return The division from the tileset for the character.
*/
tilesetdiv_t * bitmapFontGetCharacterDivision(tileset_t *tileset,
char character
);
/**
* Measures a string's fully rendered size.
*
* @param string The string to measure
* @param charWidth The width of each character.
* @param charHeight The height of each character.
* @return The measured string.
*/
bitmapfontmeasure_t bitmapFontMeasure(char *string,
float charWidth, float charHeight
);
/**
* Renders a set of font characters to the sprite. Coordinates are anchored to
* the top left (0,0) origin.
*
* @param batch Sprite Batch to render to.
* @param tileset Tileset for the font.
* @param string String to render.
* @param x Position in X space.
* @param y Position in Y space.
* @param z Position in Z space.
* @param charWidth Width of each character. Set to -1 to use the height ratio.
* @param charHeight Height of each character. Set to -1 to be the width ratio.
* @returns The string measurement.
*/
bitmapfontmeasure_t bitmapFontSpriteBatchBuffer(
spritebatch_t *batch, tileset_t *tileset,
char *string, float x, float y, float z, float charWidth, float charHeight
);

View File

@ -1,67 +0,0 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "camera.h"
void cameraLookAt(camera_t *camera,
float x, float y, float z,
float targetX, float targetY, float targetZ
) {
ASSERT_NOT_NULL(camera);
matrixIdentity(&camera->view);
matrixLookAt(&camera->view, x, y, z, targetX, targetY, targetZ, 0, 1, 0);
}
void cameraLookAtStruct(camera_t *camera, cameralookat_t look) {
ASSERT_NOT_NULL(camera);
cameraLookAt(camera,
look.x, look.y, look.z, look.lookX, look.lookY, look.lookZ
);
}
void cameraLook(camera_t *camera,
float x, float y, float z,
float pitch, float yaw, float roll
) {
ASSERT_NOT_NULL(camera);
matrixIdentity(&camera->view);
matrixLook(&camera->view, x, y, z, pitch, yaw, roll, 0, 1, 0);
}
void cameraPerspective(camera_t *camera,
float fov, float aspect, float camNear, float camFar
) {
ASSERT_NOT_NULL(camera);
matrixIdentity(&camera->projection);
matrixPerspective(&camera->projection,mathDeg2Rad(fov),aspect,camNear,camFar);
}
void cameraOrtho(camera_t *camera,
float left, float right, float bottom, float top, float camNear, float camFar
) {
ASSERT_NOT_NULL(camera);
matrixIdentity(&camera->projection);
matrixOrtho(&camera->projection, left, right, bottom, top, camNear, camFar);
}
void cameraOrbit(camera_t *camera,
float distance, float yaw, float pitch,
float targetX, float targetY, float targetZ
) {
float cy = cosf(pitch);
float x = distance * sinf(yaw) * cy;
float y = distance * sinf(pitch);
float z = distance * cosf(yaw) * cy;
ASSERT_NOT_NULL(camera);
cameraLookAt(camera, x, y, z, targetX, targetY, targetZ);
}

View File

@ -1,107 +0,0 @@
// Copyright (c) 2021 Dominic Msters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
#include "../assert/assert.h"
#include "../util/math.h"
#include "matrix.h"
/** The math for the camera is stored here. */
typedef struct {
/** View Matrix (Where the camera looks) */
matrix_t view;
/** Projection Matrix (How the camera looks) */
matrix_t projection;
} camera_t;
typedef struct {
float x, y, z, lookX, lookY, lookZ;
} cameralookat_t;
/**
* Make a camera look at a position in world space while itself being positioned
* within world space.
*
* @param camera The camera to position.
* @param x The X position in world space of the camera.
* @param y The Y position in world space of the camera.
* @param z The Z position in world space of the camera.
* @param targetX The Target X position in world space of the camera.
* @param targetY The Target Y position in world space of the camera.
* @param targetZ The Target Z position in world space of the camera.
*/
void cameraLookAt(camera_t *camera,
float x, float y, float z,
float targetX, float targetY, float targetZ
);
/**
* Shorthand for look at that uses the look struct.
*
* @param camera Camera to position.
* @param look Look vectors.
*/
void cameraLookAtStruct(camera_t *camera, cameralookat_t look);
/**
* Make a camera look in a direction based on a rotation direction.
*
* @param camera The camera to position.
* @param x The X position in world space of the camera.
* @param y The Y position in world space of the camera.
* @param z The Z position in world space of the camera.
* @param pitch The pitch of the camera.
* @param yaw The yaw of the camera.
* @param roll The roll of the camera.
*/
void cameraLook(camera_t *camera,
float x, float y, float z,
float pitch, float yaw, float roll
);
/**
* Make a camera's projection be a 3D Perspective view.
*
* @param camera The camera to project.
* @param fov The field of view of the camera (in degrees).
* @param aspect The aspect ratio of the camera (w / h)
* @param camNear The near plane clip.
* @param camFar the far plane clip.
*/
void cameraPerspective(camera_t *camera,
float fov, float aspect, float camNear, float camFar
);
/**
* Defines an orthorgonal camera matrix.
*
* @param camera Camera to position.
* @param left The left side of the viewport.
* @param right The right side of the viewport.
* @param bottom The bottom side of the viewport.
* @param camNear The near plane clip.
* @param camFar the far plane clip.
*/
void cameraOrtho(camera_t *camera,
float left, float right, float bottom, float top, float camNear, float camFar
);
/**
* Update a camera to orbit around a point.
*
* @param camera Camera to update
* @param distance Distance from the point
* @param yaw Yaw (Y axis) rotation.
* @param pitch Pitch (X/Z axis) rotation.
* @param targetX X point to orbit around.
* @param targetY Y point to orbit around.
* @param targetZ Z point to orbit around.
*/
void cameraOrbit(camera_t *camera,
float distance, float yaw, float pitch,
float targetX, float targetY, float targetZ
);

View File

@ -1,238 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "font.h"
// Due to some compiler bullshit, this is here.
#ifndef STB_TRUETYPE_IMPLEMENTATION
#define STB_TRUETYPE_IMPLEMENTATION
#include <stb_truetype.h>
#endif
void fontInit(font_t *font, char *data) {
int32_t i, s;
uint8_t *bitmapData;
pixel_t *pixels;
ASSERT_NOT_NULL(font);
ASSERT_NOT_NULL(data);
s = FONT_TEXTURE_WIDTH * FONT_TEXTURE_HEIGHT;
bitmapData = malloc(sizeof(uint8_t) * s);
ASSERT_NOT_NULL(bitmapData);
pixels = malloc(sizeof(pixel_t) * s);
ASSERT_NOT_NULL(pixels);
// STBTT Loads fonts as single channel values only.
stbtt_BakeFontBitmap(
data, 0, FONT_TEXTURE_SIZE, bitmapData,
FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT,
FONT_FIRST_CHAR, FONT_NUM_CHARS,
font->characterData
);
for(i = 0; i < FONT_TEXTURE_WIDTH * FONT_TEXTURE_HEIGHT; i++) {
pixels[i].r = 0xFF;
pixels[i].g = 0xFF;
pixels[i].b = 0xFF;
pixels[i].a = bitmapData[i];
}
textureInit(&font->texture, FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT, pixels);
free(bitmapData);
free(pixels);
}
void fontDispose(font_t *font) {
ASSERT_NOT_NULL(font);
textureDispose(&font->texture);
}
float fontGetScale(float fontSize) {
ASSERT_GREATER_THAN(fontSize, 0);
return fontSize / FONT_SIZE_DEFAULT * FONT_GLOBAL_SCALE;
}
bool _fontTextBufferAddLine(fonttextinfo_t *info, int32_t start, int32_t len) {
ASSERT_NOT_NULL(info);
ASSERT_GREATER_THAN_EQUAL_TO(start, 0);
ASSERT_GREATER_THAN(len, 0);
info->lineCount++;
if(info->lineCount >= FONT_TEXT_INFO_LINES_MAX) {
return false;
}
info->lines[info->lineCount].start = start;
info->lines[info->lineCount].length = len;
return true;
}
void fontTextBuffer(
font_t *font, primitive_t *primitive, fonttextinfo_t *info, char *text,
float maxWidth, float fontSize
) {
int32_t i, j, wordStart;
char c;
float x, y, wordX, scale;
stbtt_aligned_quad *quads;
stbtt_aligned_quad *quad;
ASSERT_NOT_NULL(font);
ASSERT_NOT_NULL(primitive);
ASSERT_NOT_NULL(info);
ASSERT_NOT_NULL(text);
ASSERT_GREATER_THAN(maxWidth, 0);
ASSERT_GREATER_THAN(fontSize, 0);
// Make some space
quads = malloc(sizeof(stbtt_aligned_quad) * strlen(text));
ASSERT_NOT_NULL(quads);
// Get the font scale
scale = fontGetScale(fontSize);
// Adjust the max width to match the scale, and allow "no max width".
maxWidth = maxWidth == -1 ? 9999999 : maxWidth * (1 / scale);
/** Which index in the original text var is the current word from */
wordStart = 0;
// Setup Scales
info->length = 0;
info->realLength = 0;
info->lineCount = 0;
// Prepare the line counters
info->lines[0].start = 0;
info->lines[0].length = 0;
// Reset Dimensions
info->width = 0, info->height = 0;
// Setup the initial loop state, and X/Y coords for the quad.
i = 0;
x = 0;
y = FONT_INITIAL_LINE;
wordX = 0;
while(c = text[i++]) {
if(info->lineCount >= FONT_TEXT_INFO_LINES_MAX) break;
info->length++;
// When space, start of new word about to begin
if(c == FONT_SPACE) {
x += FONT_SPACE_SIZE * scale;
// Did this space cause a newline?
if(x > maxWidth) {
_fontTextBufferAddLine(info, info->realLength, 0);
y += FONT_LINE_HEIGHT;
x = 0;
}
wordX = x;
wordStart = info->realLength;
continue;
}
// New line.
if(c == FONT_NEWLINE) {
_fontTextBufferAddLine(info, info->realLength, 0);
wordStart = info->realLength;
y += FONT_LINE_HEIGHT;
x = 0;
continue;
}
// Generate the quad.
quad = quads + info->realLength;
stbtt_GetBakedQuad(font->characterData,
FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT,
((int32_t)c)-FONT_FIRST_CHAR, &x, &y, quad, FONT_FILL_MODE
);
// Now measure the width of the line (take the right side of that quad)
if(quad->x1 > maxWidth) {
// We've exceeded the edge, go back to the start of the word and newline.
x = quad->x1 - wordX;
for(j = wordStart; j <= info->realLength; j++) {
quad = quads + j;
quad->x0 -= wordX;
quad->x1 -= wordX;
quad->y0 += FONT_LINE_HEIGHT;
quad->y1 += FONT_LINE_HEIGHT;
}
// Go back to the previous (still current) line and remove the chars
info->lines[info->lineCount].length -= info->realLength - wordStart;
// Next line begins with this word
y += FONT_LINE_HEIGHT;
if(!_fontTextBufferAddLine(info, wordStart, info->realLength-wordStart)) {
continue;
}
wordX = 0;
}
info->lines[info->lineCount].length++;
info->realLength++;
}
info->lineCount++;
// Initialize primitive
primitiveInit(primitive,
QUAD_VERTICE_COUNT * info->realLength,
QUAD_INDICE_COUNT * info->realLength
);
for(j = 0; j < info->realLength; j++) {
quad = quads + j;
// Scale the Quad
if(scale != 1.0) {
quad->x0 *= scale;
quad->x1 *= scale;
quad->y0 *= scale;
quad->y1 *= scale;
}
// Update the dimensions.
info->width = mathMax(info->width, quad->x1);
info->height = mathMax(info->height, quad->y1);
// Buffer the quad.
quadBuffer(primitive, 0,
quad->x0, quad->y0, quad->s0, quad->t0,
quad->x1, quad->y1, quad->s1, quad->t1,
j * QUAD_VERTICE_COUNT, j * QUAD_INDICE_COUNT
);
}
// Free up
free(quads);
}
int32_t fontGetLineCharCount(fonttextinfo_t *info,int32_t start,int32_t count) {
int32_t charCount, i, m;
ASSERT_NOT_NULL(info);
ASSERT_GREATER_THAN_EQUAL_TO(start, 0);
ASSERT_GREATER_THAN(count, 0);
m = mathMin(start+count, info->lineCount);
charCount = 0;
for(i = start; i < m; i++) {
charCount += info->lines[i].length;
}
return charCount;
}

View File

@ -1,139 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "texture.h"
#include "primitive/primitive.h"
#include "primitive/quad.h"
#include "../util/mem.h"
#include "../util/math.h"
#include "../assert/assert.h"
/** Which character (ASCII) to start the font from */
#define FONT_FIRST_CHAR 32
/** How many characters (after the first char) to generate */
#define FONT_NUM_CHARS 96
/** Width of the loaded font texture */
#define FONT_TEXTURE_WIDTH 1024
/** Height of the loaded font texture */
#define FONT_TEXTURE_HEIGHT FONT_TEXTURE_WIDTH
/** Refer to STBTT docs for OpenGL Fill Mode v d3d Fill Modes */
#define FONT_FILL_MODE 1
/** Passed to STBTT for scaling the font, essentially the font resolution */
#define FONT_TEXTURE_SIZE 64.0f
/** The global scale, just used to provide fine control of font sizes */
#define FONT_GLOBAL_SCALE 0.5f;
/** Default Font Size (on which all font scales are based) */
#define FONT_SIZE_DEFAULT 16.0f
// Chars
#define FONT_NEWLINE '\n'
#define FONT_SPACE ' '
// Heights
#define FONT_LINE_HEIGHT FONT_TEXTURE_SIZE * 0.75f
#define FONT_INITIAL_LINE FONT_LINE_HEIGHT * 0.75f
#define FONT_SPACE_SIZE FONT_TEXTURE_SIZE * 0.45f
/** Maximum number of newlines that a font text info can hold. */
#define FONT_TEXT_INFO_LINES_MAX 16
/** Representation of a font that can be used to render text */
typedef struct {
texture_t texture;
stbtt_bakedchar characterData[FONT_NUM_CHARS];
} font_t;
typedef struct {
/** What (real character) index the line starts at */
int32_t start;
/** How many (real) characters the line is in length */
int32_t length;
} fonttextinfoline_t;
typedef struct {
/** How many raw chars are in the string */
int32_t length;
/** How many real characters (non whitespace) are in the string */
int32_t realLength;
/** How many lines is the string? Trailing newlines will count */
int32_t lineCount;
/** The real character info for each line */
fonttextinfoline_t lines[FONT_TEXT_INFO_LINES_MAX];
/** Dimensions of the string */
float width, height;
} fonttextinfo_t;
/**
* Initializes Font from raw TTF data.
* @param font Font to initialize
* @param data Data to intialize for.
*/
void fontInit(font_t *font, char *data);
/**
* Clean up a previously loaded font
* @param font Loaded font.
*/
void fontDispose(font_t *Font);
/**
* Convert a Font's Size into a Font Scale. The scale is based on the font's
* default size for the given texture size (Refer to FONT_SIZE_DEFAULT).
*
* @param fontSize Font size to convert.
* @return The times scale that the font size is to the textured default.
*/
float fontGetScale(float fontSize);
/**
* Internal method that adds a line to the text buffer process.
*
* @param info Info to add to.
* @param start Start character index for the next line.
* @param len Length of the next line.
* @return True if added a line successfully, otherwise false.
*/
bool _fontTextBufferAddLine(fonttextinfo_t *info, int32_t start, int32_t len);
/**
* Clamps text to a max width, inserting newlines where possible.
*
* @param font Font to use
* @param primitive Primitive to buffer the text to.
* @param info Font text info to clamp into.
* @param text Text to clamp.
* @param maxWidth Max width (pixels) to clamp the text to, -1 for no max width.
* @param fontSize Font Size of the text.
*/
void fontTextBuffer(
font_t *font, primitive_t *primitive, fonttextinfo_t *info, char *text,
float maxWidth, float fontSize
);
/**
* Returns the number of real characters on the lines specified. Useful when
* attempting to clamp to a set of lines.
*
* @param info Info to get the character counts from.
* @param start Starting line index.
* @param count Count of lines, this method will clamp to info's line length.
* @returns The count of characters in those lines summed.
*/
int32_t fontGetLineCharCount(fonttextinfo_t *info, int32_t start,int32_t count);

View File

@ -1,76 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "framebuffer.h"
void frameBufferInit(framebuffer_t *fb, int32_t w, int32_t h) {
// At least one pixel
if(w <= 0) w = 1;
if(h <= 0) h = 1;
// Create Color Attachment texture.
textureInit(&fb->texture, w, h, NULL);
// Create Frame Buffer
glGenFramebuffers(1, &fb->fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fb->fboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, fb->texture.id, 0
);
// Render Buffer
glGenRenderbuffers(1, &fb->rboId);
glBindRenderbuffer(GL_RENDERBUFFER, fb->rboId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, fb->rboId
);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
uint32_t error;
error = 0;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void frameBufferUse(framebuffer_t *frameBuffer, bool clear) {
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer->fboId);
glViewport(0, 0, frameBuffer->texture.width, frameBuffer->texture.height);
if(clear) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
}
void frameBufferResize(framebuffer_t *frameBuffer,int32_t width,int32_t height){
if((
frameBuffer->texture.width == width &&
frameBuffer->texture.height == height
)) return;
frameBufferDispose(frameBuffer);
frameBufferInit(frameBuffer, width, height);
}
void frameBufferUnbind(float viewWidth, float viewHeight, bool clear) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, (GLsizei)viewWidth, (GLsizei)viewHeight);
if(clear) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
}
void frameBufferDispose(framebuffer_t *frameBuffer) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glDeleteRenderbuffers(1, &frameBuffer->rboId);
glDeleteFramebuffers(1, &frameBuffer->fboId);
textureDispose(&frameBuffer->texture);
}

View File

@ -1,59 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "texture.h"
typedef struct {
GLuint fboId;
GLuint rboId;
texture_t texture;
} framebuffer_t;
/**
* Initializes frame buffer that can be rendered to.
* @param frameBuffer Frame buffer to initialize.
* @param width Width of the frame buffer (in pixels).
* @param height Height of the frame buffer (in pixels).
* @return A renderable frame buffer.
*/
void frameBufferInit(framebuffer_t *buffer, int32_t width, int32_t height);
/**
* Use a given frame buffer as the current rendering context.
*
* @param frameBuffer Frame buffer to use.
* @param clear Whether or not to clear the frame buffer prior to rendering.
*/
void frameBufferUse(framebuffer_t *frameBuffer, bool clear);
/**
* Resize an existing frame buffer. This will do the check if resizing is even
* necessary for you.
*
* @param frameBuffer Frame buffer to resize.
* @param width New width of the frame buffer.
* @param height New height of the frame buffer.
*/
void frameBufferResize(framebuffer_t *frameBuffer,int32_t width,int32_t height);
/**
* Unbind the currently bound frame buffer.
*
* @param viewWidth Viewport width.
* @param viewHeight Viewport height.
* @param clear Whether or not to clear the back buffer.
*/
void frameBufferUnbind(float viewWidth, float viewHeight, bool clear);
/**
* Dispose/cleanup a previously created frame buffer.
*
* @param frameBuffer Frame Buffer to clean.
*/
void frameBufferDispose(framebuffer_t *frameBuffer);

View File

@ -1,90 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "matrix.h"
void matrixIdentity(matrix_t *matrix) {
ASSERT_NOT_NULL(matrix);
glm_mat4_identity(matrix->internalMatrix);
}
void matrixLookAt(matrix_t *matrix,
float x,float y,float z,
float tx,float ty, float tz,
float ux, float uy, float uz
) {
ASSERT_NOT_NULL(matrix);
glm_lookat(
(vec3){ x, y, z },
(vec3){ tx, ty, tz },
(vec3){ ux, uy, uz },
matrix->internalMatrix
);
}
void matrixLook(matrix_t *matrix,
float x, float y, float z,
float pitch, float yaw, float roll,
float ux, float uy, float uz
) {
ASSERT_NOT_NULL(matrix);
glm_look(
(vec3){ x, y, z },
(vec3){ pitch, yaw, roll },
(vec3){ ux, uy, uz },
matrix->internalMatrix
);
}
void matrixPerspective(matrix_t *matrix,
float fov, float aspect, float camNear, float camFar
) {
ASSERT_NOT_NULL(matrix);
glm_perspective(fov, aspect, camNear, camFar, matrix->internalMatrix);
}
void matrixOrtho(matrix_t *matrix,
float left, float right, float bottom, float top, float camNear, float camFar
) {
ASSERT_NOT_NULL(matrix);
glm_ortho(left, right, bottom, top, camNear, camFar, matrix->internalMatrix);
}
void matrixTranslate(matrix_t *matrix, float x, float y, float z) {
ASSERT_NOT_NULL(matrix);
glm_translate(matrix->internalMatrix, (vec3){ x, y, z });
}
void matrixRotate(matrix_t *matrix, float angle, float x, float y, float z) {
ASSERT_NOT_NULL(matrix);
glm_rotate(matrix->internalMatrix, angle, (vec3){ x, y, z });
}
void matrixScale(matrix_t *matrix, float x, float y, float z) {
ASSERT_NOT_NULL(matrix);
glm_scale(matrix->internalMatrix, (vec3){ x, y, z });
}
matrix_t matrixPositionAndScale(
float x, float y, float z,
float pitch, float yaw, float roll,
float scaleX, float scaleY, float scaleZ
) {
matrix_t matrix;
matrixIdentity(&matrix);
matrixTranslate(&matrix, x, y, z);
// Rotation (YZX order)
matrixRotate(&matrix, yaw, 0, 1, 0);
matrixRotate(&matrix, roll, 0, 0, 1);
matrixRotate(&matrix, pitch, 1, 0, 0);
matrixScale(&matrix, scaleX, scaleY, scaleZ);
return matrix;
}

View File

@ -1,145 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "../assert/assert.h"
/**
* Representation for a matrix. Used as a highlevel wrapper for the math
* functions that sit underneath this API.
*/
typedef struct {
/** Internal Matrix API */
mat4 internalMatrix;
} matrix_t;
/**
* Makes matrix identity.
* @param matrix Matrix to identify.
*/
void matrixIdentity(matrix_t *matrix);
/**
* Applies a look at point vector to a matrix.
*
* @param matrix Matrix to apply to.
* @param x Camera source X.
* @param y Camera source Y.
* @param z Camera source Z.
* @param tx Camera target X.
* @param ty Camera target Y.
* @param tz Camera target Z.
* @param ux Camera up vector X.
* @param uy Camera up vector Y.
* @param uz Camera up vector Z.
*/
void matrixLookAt(matrix_t *matrix,
float x,float y,float z,
float tx,float ty, float tz,
float ux, float uy, float uz
);
/**
* Applies a look vector to a matrix.
*
* @param matrix Matrix to apply to.
* @param x Camera source X.
* @param y Camera source Y.
* @param z Camera source Z.
* @param pitch Camera pitch
* @param yaw Camera yaw.
* @param roll Camera roll.
* @param ux Camera up vector X.
* @param uy Camera up vector Y.
* @param uz Camera up vector Z.
*/
void matrixLook(matrix_t *matrix,
float x, float y, float z,
float pitch, float yaw, float roll,
float ux, float uy, float uz
);
/**
* Applies a perspective projection to a matrix.
*
* @param matrix Matrix to apply to.
* @param fov Field of View (in radians) to use.
* @param aspect Aspect ratio (w/h) of the viewport.
* @param camNear Near vector, > 0.
* @param camFar Far view vector.
*/
void matrixPerspective(matrix_t *matrix,
float fov,float aspect, float camNear, float camFar
);
/**
* Applies an orthogonal projection to a matrix.
*
* @param matrix Matrix to apply to.
* @param left Left view position.
* @param right Right view position.
* @param bottom Bottom view position.
* @param top Top view position.
* @param camNear Near vector, > 0.
* @param camFar Far view vector.
*/
void matrixOrtho(matrix_t *matrix,
float left, float right, float bottom, float top, float camNear, float camFar
);
/**
* Performs a matrix translation.
*
* @param matrix Matrix to translate.
* @param x X coordinate to translate on.
* @param y Y coordinate to translate on.
* @param z Z coordinate to translate on.
*/
void matrixTranslate(matrix_t *matrix, float x, float y, float z);
/**
* Applies a rotation vector to a matrix.
*
* @param matrix Matrix to rotate.
* @param angle Angle (in radians) to rotate.
* @param x X vector to rotate on.
* @param y Y vector to rotate on.
* @param z Z vector to rotate on.
*/
void matrixRotate(matrix_t *matrix, float angle, float x, float y, float z);
/**
* Scales a matrix.
*
* @param matrix Matrix to scale
* @param x X vector to scale.
* @param y Y vector to scale.
* @param z Z vector to scale.
*/
void matrixScale(matrix_t *matrix, float x, float y, float z);
/**
* Calculates a fairly standard position and scale matrix. Note that the matrix
* is calculated in the order of Translate, Yaw, Pitch, Roll, Scale.
*
* @param x X translation to apply.
* @param y Y translation to apply.
* @param z Z translation to apply.
* @param pitch Pitch rotation to apply.
* @param yaw Yaw rotation to apply.
* @param roll Roll rotation to apply.
* @param scaleX X scale factor.
* @param scaleY Y scale factor.
* @param scaleZ Z scale factor.
* @return A specially created transformation matrix.
*/
matrix_t matrixPositionAndScale(
float x, float y, float z,
float pitch, float yaw, float roll,
float scaleX, float scaleY, float scaleZ
);

View File

@ -1,13 +0,0 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${PROJECT_NAME}
PRIVATE
cube.c
primitive.c
quad.c
skywall.c
)

View File

@ -1,112 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "cube.h"
void cubeBuffer(primitive_t *prim,
float x, float y, float z,
float w, float h, float d,
int32_t verticeStart, int32_t indiceStart
) {
vertice_t vertices[CUBE_VERTICE_COUNT];
indice_t indices[CUBE_INDICE_COUNT];
ASSERT_GREATER_THAN(w, 0);
ASSERT_GREATER_THAN(h, 0);
ASSERT_GREATER_THAN(d, 0);
vertices[0].x = x, vertices[0].y = y, vertices[0].z = z;
vertices[0].u = 0, vertices[0].v = 0;
vertices[1].x = x+w, vertices[1].y = y, vertices[1].z = z;
vertices[1].u = 1, vertices[1].v = 0;
vertices[2].x = x, vertices[2].y = y+h, vertices[2].z = z;
vertices[2].u = 0, vertices[2].v = 1;
vertices[3].x = x+w, vertices[3].y = y+h, vertices[3].z = z;
vertices[3].u = 1, vertices[3].v = 1;
vertices[4].x = x, vertices[4].y = y, vertices[4].z = z+d;
vertices[4].u = 0, vertices[4].v = 0;
vertices[5].x = x+w, vertices[5].y = y, vertices[5].z = z+d;
vertices[5].u = 1, vertices[5].v = 0;
vertices[6].x = x, vertices[6].y = y+h, vertices[6].z = z+d;
vertices[6].u = 0, vertices[6].v = 1;
vertices[7].x = x+w, vertices[7].y = y+h, vertices[7].z = z+d;
vertices[7].u = 1, vertices[7].v = 1;
// Back
indices[ 0] = (indice_t)(verticeStart + 0);
indices[ 1] = (indice_t)(verticeStart + 1);
indices[ 2] = (indice_t)(verticeStart + 3);
indices[ 3] = (indice_t)(verticeStart + 0);
indices[ 4] = (indice_t)(verticeStart + 2);
indices[ 5] = (indice_t)(verticeStart + 3);
// Right
indices[ 6] = (indice_t)(verticeStart + 1);
indices[ 7] = (indice_t)(verticeStart + 5);
indices[ 8] = (indice_t)(verticeStart + 7);
indices[ 9] = (indice_t)(verticeStart + 1);
indices[10] = (indice_t)(verticeStart + 3);
indices[11] = (indice_t)(verticeStart + 7);
// Left
indices[12] = (indice_t)(verticeStart + 4);
indices[13] = (indice_t)(verticeStart + 0);
indices[14] = (indice_t)(verticeStart + 2);
indices[15] = (indice_t)(verticeStart + 4);
indices[16] = (indice_t)(verticeStart + 6);
indices[17] = (indice_t)(verticeStart + 2);
// Front
indices[18] = (indice_t)(verticeStart + 5);
indices[19] = (indice_t)(verticeStart + 4);
indices[20] = (indice_t)(verticeStart + 6);
indices[21] = (indice_t)(verticeStart + 5);
indices[22] = (indice_t)(verticeStart + 7);
indices[23] = (indice_t)(verticeStart + 6);
// Top
indices[24] = (indice_t)(verticeStart + 7);
indices[25] = (indice_t)(verticeStart + 2);
indices[26] = (indice_t)(verticeStart + 6);
indices[27] = (indice_t)(verticeStart + 7);
indices[28] = (indice_t)(verticeStart + 3);
indices[29] = (indice_t)(verticeStart + 2);
// Bottom
indices[30] = (indice_t)(verticeStart + 1);
indices[31] = (indice_t)(verticeStart + 0);
indices[32] = (indice_t)(verticeStart + 4);
indices[33] = (indice_t)(verticeStart + 1);
indices[34] = (indice_t)(verticeStart + 4);
indices[35] = (indice_t)(verticeStart + 5);
primitiveBufferVertices(prim, verticeStart, CUBE_VERTICE_COUNT, vertices);
primitiveBufferIndices(prim, indiceStart, CUBE_INDICE_COUNT, indices);
}
void cubeInit(primitive_t *primitive, float w, float h, float d) {
primitiveInit(primitive, CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT);
cubeBuffer(primitive,
-w/2, -h/2, -d/2,
w, h, d,
0, 0
);
}

View File

@ -1,38 +0,0 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../../libs.h"
#include "primitive.h"
#define CUBE_VERTICE_COUNT 8
#define CUBE_INDICE_COUNT 36
/**
* Buffer the vertices and indices of a cube onto a primitive.
* @param primitive Primitive to buffer to.
* @param x X position of the cube.
* @param y Y position of the cube.
* @param z Z position of the cube.
* @param w Width of cube.
* @param h Height of cube.
* @param d Depth of cube.
* @param verticeStart The position of the vertex buffer to buffer into.
* @param indiceStart The position of the index buffer to buffer into.
*/
void cubeBuffer(primitive_t *primitive,
float x, float y, float z,
float w, float h, float d,
int32_t verticeStart, int32_t indiceStart
);
/**
* Creates a cube primitive of given size.
* @param primitive Primitive to create into a cube.
* @param w Width of cube.
* @param h Height of cube.
* @param d Depth of cube.
*/
void cubeInit(primitive_t *primitive, float w, float h, float d);

View File

@ -1,154 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "primitive.h"
void primitiveInit(primitive_t *primitive,
int32_t verticeCount, int32_t indiceCount
) {
ASSERT_NOT_NULL(primitive);
ASSERT_GREATER_THAN(verticeCount, 0);
ASSERT_GREATER_THAN(indiceCount, 0);
primitive->verticeCount = verticeCount;
primitive->indiceCount = indiceCount;
// size_t sizeIndices = sizeof(uint32_t) * verticeCount;
size_t sizePositions = sizeof(float) * verticeCount * PRIMITIVE_POSITIONS_PER_VERTICE;
size_t sizeCoordinates = sizeof(float) * verticeCount * PRIMITIVE_COORDINATES_PER_VERTICE;
size_t sizeIndices = sizeof(indice_t) * indiceCount;
// Create some buffers, one for the vertex data, one for the indices
GLuint buffer[2];
glGenBuffers(2, buffer);
primitive->vertexBuffer = buffer[0];
primitive->indexBuffer = buffer[1];
// Buffer an empty set of data then buffer each component
glBindBuffer(GL_ARRAY_BUFFER, primitive->vertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, primitive->indexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizePositions+sizeCoordinates, 0, GL_DYNAMIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeIndices, 0, GL_DYNAMIC_DRAW);
size_t offset = 0;
// Setup the attrib pointers
glVertexAttribPointer(0, PRIMITIVE_POSITIONS_PER_VERTICE, GL_FLOAT,
GL_FALSE, 0, (void *)offset
);
glEnableVertexAttribArray(0);
offset += sizePositions;
glVertexAttribPointer(1, PRIMITIVE_COORDINATES_PER_VERTICE, GL_FLOAT,
GL_FALSE, 0, (void *)offset
);
glEnableVertexAttribArray(1);
}
void primitiveBufferVertices(primitive_t *primitive,
int32_t position, int32_t count, vertice_t *vertices
) {
// Memory
size_t lengthPositions, lengthCoordinates, offsetPositions, offsetCoordinates;
float *positions, *coordinates;
int32_t i;
ASSERT_NOT_NULL(primitive);
ASSERT_NOT_NULL(vertices);
ASSERT_GREATER_THAN_EQUAL_TO(position, 0);
ASSERT_GREATER_THAN(count, 0);
// Setup the size of the memory that the positions and coordinates will use
lengthPositions = sizeof(float) * PRIMITIVE_POSITIONS_PER_VERTICE * count;
offsetPositions = sizeof(float) * PRIMITIVE_POSITIONS_PER_VERTICE * position;
lengthCoordinates = sizeof(float) * PRIMITIVE_COORDINATES_PER_VERTICE * count;
offsetCoordinates = (
(sizeof(float) * PRIMITIVE_POSITIONS_PER_VERTICE * primitive->verticeCount)+
(sizeof(float) * PRIMITIVE_COORDINATES_PER_VERTICE * position)
);
// Create some memory
positions = malloc(lengthPositions);
ASSERT_NOT_NULL(positions);
coordinates = malloc(lengthCoordinates);
ASSERT_NOT_NULL(coordinates);
// Now copy the positions and coordinates from the vertices into the buffer
for(i = 0; i < count; i++) {
positions[i * PRIMITIVE_POSITIONS_PER_VERTICE] = vertices[i].x;
positions[i * PRIMITIVE_POSITIONS_PER_VERTICE + 1] = vertices[i].y;
positions[i * PRIMITIVE_POSITIONS_PER_VERTICE + 2] = vertices[i].z;
coordinates[i * PRIMITIVE_COORDINATES_PER_VERTICE] = vertices[i].u;
coordinates[i * PRIMITIVE_COORDINATES_PER_VERTICE + 1] = vertices[i].v;
}
// Buffer the data into the GPU
glBindBuffer(GL_ARRAY_BUFFER, primitive->vertexBuffer);
glBufferSubData(GL_ARRAY_BUFFER, offsetPositions, lengthPositions, positions);
glBufferSubData(GL_ARRAY_BUFFER, offsetCoordinates, lengthCoordinates, coordinates);
// Free the vertices.
free(positions);
free(coordinates);
}
void primitiveBufferIndices(primitive_t *primitive,
int32_t position, int32_t count, indice_t *indices
) {
size_t length, offset;
offset = position * sizeof(indice_t);
length = count * sizeof(indice_t);
ASSERT_NOT_NULL(primitive);
ASSERT_NOT_NULL(indices);
ASSERT_GREATER_THAN_EQUAL_TO(position, 0);
ASSERT_GREATER_THAN(count, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, primitive->indexBuffer);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, length, indices);
}
void primitiveDraw(primitive_t *primitive, int32_t start, int32_t count) {
ASSERT_NOT_NULL(primitive);
ASSERT_GREATER_THAN_EQUAL_TO(start, 0);
ASSERT_IF(count < 0, ASSERT_EQUAL(count, -1));
if(count == -1) count = primitive->indiceCount;
// Re-Bind the buffers
glBindBuffer(GL_ARRAY_BUFFER, primitive->vertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, primitive->indexBuffer);
// Re-Calculate the attrib pointers.
size_t offset = 0;
glVertexAttribPointer(0, PRIMITIVE_POSITIONS_PER_VERTICE, GL_FLOAT,
GL_FALSE, 0, (void *)offset
);
glEnableVertexAttribArray(0);
offset += sizeof(float) * primitive->verticeCount * PRIMITIVE_POSITIONS_PER_VERTICE;
glVertexAttribPointer(1, PRIMITIVE_COORDINATES_PER_VERTICE, GL_FLOAT,
GL_FALSE, 0, (void *)offset
);
glEnableVertexAttribArray(1);
// Render the elements.
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, (void *)(
sizeof(indice_t)*start
));
}
void primitiveDispose(primitive_t *primitive) {
ASSERT_NOT_NULL(primitive);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &primitive->vertexBuffer);
glDeleteBuffers(1, &primitive->indexBuffer);
}

View File

@ -1,83 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../../libs.h"
#include "../../assert/assert.h"
#define PRIMITIVE_POSITIONS_PER_VERTICE 3
#define PRIMITIVE_COORDINATES_PER_VERTICE 2
/** Structure containing information about a primitive */
typedef struct {
/** How many vertices are in the primitive */
int32_t verticeCount;
/** How many indices are in the primitive */
int32_t indiceCount;
/** Pointer to the vertex buffer on the GPU */
GLuint vertexBuffer;
/** Pointer to the index buffer on the GPU */
GLuint indexBuffer;
} primitive_t;
/** Structure containing vertice position information */
typedef struct {
/** Coordinates */
float x, y, z;
/** Texture UVs */
float u, v;
} vertice_t;
/** Indice that references a specific vertice */
typedef unsigned int indice_t;
/**
* Creates a new primitive.
* @param primitive Primitive to initialize.
* @param verticeCount How many vertices can the primitive hold.
* @param indiceCount How many indices can the primitive hold.
*/
void primitiveInit(primitive_t *primitive,
int32_t verticeCount, int32_t indiceCount
);
/**
* Buffer Vertices to a primitive for use in rendering.
* @param primitive The primitive to buffer vertices into.
* @param position The position (index) to overwrite the vertices of.
* @param count The count of vertices to buffer.
* @param vertices Array of vertices to buffer into the primitive.
*/
void primitiveBufferVertices(primitive_t *primitive,
int32_t position, int32_t count, vertice_t *vertices
);
/**
* Buffer Indices to a primitive for use in rendering.
* @param primitive The primitive to buffer indices into.
* @param position The position (index) to overwrite the indices of.
* @param count The count of indices to buffer.
* @param indices Array of indices to buffer into the primitive.
*/
void primitiveBufferIndices(primitive_t *primitive,
int32_t position, int32_t count, indice_t *indices
);
/**
* Draw a primitive. Primitives are drawn by their indices.
* @param primitive Primitive to draw.
* @param start Start indice (index) to draw.
* @param count Count of indices to draw. Use -1 to draw all.
*/
void primitiveDraw(primitive_t *primitive, int32_t start, int32_t count);
/**
* Cleanup a previously initialized primitive.
* @param primitive Primitive to cleanup.
*/
void primitiveDispose(primitive_t *primitive);

View File

@ -1,53 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "quad.h"
void quadBuffer(primitive_t *primitive, float z,
float x0, float y0, float u0, float v0,
float x1, float y1, float u1, float v1,
int32_t verticeStart, int32_t indiceStart
) {
vertice_t vertices[QUAD_VERTICE_COUNT];
indice_t indices[QUAD_INDICE_COUNT];
vertices[0].x = x0, vertices[0].y = y0, vertices[0].z = z;
vertices[0].u = u0, vertices[0].v = v0;
vertices[1].x = x1, vertices[1].y = y0, vertices[1].z = z;
vertices[1].u = u1, vertices[1].v = v0;
vertices[2].x = x0, vertices[2].y = y1, vertices[2].z = z;
vertices[2].u = u0, vertices[2].v = v1;
vertices[3].x = x1, vertices[3].y = y1, vertices[3].z = z;
vertices[3].u = u1, vertices[3].v = v1;
indices[0] = (indice_t)(verticeStart + 0);
indices[1] = (indice_t)(verticeStart + 1);
indices[2] = (indice_t)(verticeStart + 2);
indices[3] = (indice_t)(verticeStart + 1);
indices[4] = (indice_t)(verticeStart + 2);
indices[5] = (indice_t)(verticeStart + 3);
primitiveBufferVertices(primitive, verticeStart,QUAD_VERTICE_COUNT,vertices);
primitiveBufferIndices(primitive, indiceStart, QUAD_INDICE_COUNT, indices );
}
void quadInit(primitive_t *primitive, float z,
float x0, float y0, float u0, float v0,
float x1, float y1, float u1, float v1
) {
primitiveInit(primitive, QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT);
quadBuffer(primitive, z,
x0, y0, u0, v0,
x1, y1, u1, v1,
0, 0
);
}

View File

@ -1,53 +0,0 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../../libs.h"
#include "primitive.h"
#define QUAD_VERTICE_COUNT 4
#define QUAD_INDICE_COUNT 6
#define QUAD_INDICE_PER_QUAD 2
/**
* Buffers the vertices of a quad onto a primitive.
*
* @param primitive The primitive to buffer to.
* @param z The Z axis coordinate of the quad.
* @param x0 The X lower coordinate.
* @param y0 The Y lower coordinate.
* @param u0 The X lower texture coordinate.
* @param v0 The Y lower texture coordinate.
* @param x1 The X higher coordinate.
* @param y1 The Y higher coordinate.
* @param u1 The X higher texture coordinate.
* @param v1 The Y higher texture coordinate.
* @param verticeStart Start vertice to buffer to.
* @param indiceStart Start indice to buffer to.
*/
void quadBuffer(primitive_t *primitive, float z,
float x0, float y0, float u0, float v0,
float x1, float y1, float u1, float v1,
int32_t verticeStart, int32_t indiceStart
);
/**
* Creates a new quad primitive.
*
* @param primitive Primitive to turn into a quad.
* @param z The Z axis coordinate of the quad.
* @param x0 The X lower coordinate.
* @param y0 The Y lower coordinate.
* @param u0 The X lower texture coordinate.
* @param v0 The Y lower texture coordinate.
* @param x1 The X higher coordinate.
* @param y1 The Y higher coordinate.
* @param u1 The X higher texture coordinate.
* @param v1 The Y higher texture coordinate.
*/
void quadInit(primitive_t *primitive, float z,
float x0, float y0, float u0, float v0,
float x1, float y1, float u1, float v1
);

View File

@ -1,58 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "skywall.h"
void skywallInit(primitive_t *primitive) {
vertice_t vertices[SKYWALL_VERTICE_COUNT];
indice_t indices[SKYWALL_INDICE_COUNT];
int32_t n, i, j;
float x, y, z, p, r;
primitiveInit(primitive, SKYWALL_VERTICE_COUNT, SKYWALL_INDICE_COUNT);
// For each slice. We iterate slices+1 to do the wrapping mentioned below.
for(i = 0; i < SKYWALL_SLICE_COUNT+1; i++) {
// Get the "percentage" of the current slice, slice 0 is 0, slice n is 1
p = (float)i/(float)SKYWALL_SLICE_COUNT;
// Because we we are to "seal the cylinder" we wrap around back to 0 on the
// last slice to have the last vertice meet the first.
if(SKYWALL_SLICE_COUNT == i) {
r = 0;
} else {
r = p * MATH_PI * 2.0f;// Convert % to radians
}
r += mathDeg2Rad(90);
// Determine the X/Z for the given radian
x = SKYWALL_SIZE * (float)cos(r);
z = SKYWALL_SIZE * (float)sin(r);
y = SKYWALL_SIZE * 1;
// Get the start index for the ertices
n = i * SKYWALL_VERTICES_PER_SLICE;
vertices[n].x = x, vertices[n].y = -y, vertices[n].z = z;
vertices[n].u = p, vertices[n].v = 1;
vertices[n+1].x = x, vertices[n+1].y = y, vertices[n+1].z = z;
vertices[n+1].u = p, vertices[n+1].v = 0;
if(i == SKYWALL_SLICE_COUNT) continue;
j = i * SKYWALL_INDICES_PER_SLICE;
indices[j] = (indice_t)n;
indices[j+1] = (indice_t)n+1;
indices[j+2] = (indice_t)n+2;
indices[j+3] = (indice_t)n+3;
indices[j+4] = (indice_t)n+2;
indices[j+5] = (indice_t)n+1;
}
primitiveBufferVertices(primitive, 0, SKYWALL_VERTICE_COUNT, vertices);
primitiveBufferIndices(primitive, 0, SKYWALL_INDICE_COUNT, indices);
}

View File

@ -1,29 +0,0 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../../libs.h"
#include "../../util/math.h"
#include "primitive.h"
/** How many slices in each cylinder. */
#define SKYWALL_SLICE_COUNT 40
/** How many vertices per slice */
#define SKYWALL_VERTICES_PER_SLICE 2
/** How many indices per slice */
#define SKYWALL_INDICES_PER_SLICE 6
/** How many vertices in the cylinder, +1 to have the cylinder "wrap" */
#define SKYWALL_VERTICE_COUNT (SKYWALL_SLICE_COUNT+1)*SKYWALL_VERTICES_PER_SLICE
/** How many indices in the cylinder */
#define SKYWALL_INDICE_COUNT SKYWALL_INDICES_PER_SLICE*SKYWALL_SLICE_COUNT
/** How big the skywall cylinder is */
#define SKYWALL_SIZE 10
void skywallInit(primitive_t *primitive);

View File

@ -1,47 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "render.h"
void renderInit() {
// Enable GL things.
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
// Setup the alpha blend function.
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
glClearColor(0,0,0, 0.0);
}
void renderFrameStart(render_t *render) {
// Clear the frame buffer.
renderResetFramebuffer(render);
}
void renderDispose() {
}
void renderSetResolution(render_t *render, float width, float height) {
ASSERT_NOT_NULL(render);
ASSERT_GREATER_THAN(width, 0);
ASSERT_GREATER_THAN(height, 0);
render->width = width;
render->height = height;
}
void renderResetFramebuffer(render_t *render) {
ASSERT_NOT_NULL(render);
frameBufferUnbind(render->width, render->height, true);
}

View File

@ -1,51 +0,0 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
#include "../assert/assert.h"
#include "framebuffer.h"
/**
* Contains information about the current render state, can be used for querying
* how the renderer is currently set up.
*/
typedef struct {
/** Resolution (in pixels). Floats to allow subpixels in future. */
float width, height;
} render_t;
/**
* Initialize the renderer.
*/
void renderInit();
/**
* Render a single frame of the render loop. The renderer is not (currently)
* responsible for render looping.
* @param render The render manager
*/
void renderFrameStart(render_t *render);
/**
* Cleanup a render context.
*/
void renderDispose();
/**
* Sets the internal display resolution.
*
* @param render Render context to resize.
* @param width Width of the display (in pixels).
* @param height Height of the display (in pixels).
*/
void renderSetResolution(render_t *render, float width, float height);
/**
* Reset the framebuffer back to the original backbuffer.
*
* @param render Render to reset the backbuffer to.
*/
void renderResetFramebuffer(render_t *render);

View File

@ -1,107 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "renderlist.h"
void renderListInit(renderlist_t *list,int32_t width, int32_t height) {
frameBufferInit(&list->frame, width, height);
quadInit(&list->quad, 0, 0,0,0,0, 1,1,1,1);
list->passCount = 0;
}
renderpass_t * renderListGetPass(renderlist_t *list, uint8_t pass) {
return list->passes + pass;
}
uint8_t renderPassAdd(renderlist_t *list, shaderprogram_t *shader) {
uint8_t i;
renderpass_t *pass;
i = list->passCount++;
pass = renderListGetPass(list, i);
pass->shader = shader;
frameBufferInit(&pass->frame,
list->frame.texture.width, list->frame.texture.height
);
return i;
}
renderpass_t * renderListRenderPass(
renderlist_t *list, engine_t *engine, uint8_t pass
) {
renderpass_t *renderPass;
renderPass = renderListGetPass(list, pass);
// Bind the shader.
frameBufferUse(&renderPass->frame, true);
shaderUse(renderPass->shader);
return renderPass;
}
void renderListRender(renderlist_t *list, renderlistbackshader_t *backShader) {
camera_t camera;
int32_t i;
renderpass_t *pass;
matrix_t matrix;
// Setup the camera
cameraLookAt(&camera, 0,0,1, 0,0,0);
cameraOrtho(&camera, 0,1, 0,1, 0.5f, 1.5f);
// Bind the framebuffer
frameBufferUse(&list->frame, true);
// Set the shader
shaderUse(backShader->program);
shaderUseCamera(
backShader->program, backShader->uniformView,
backShader->uniformProjection, &camera
);
matrix = matrixPositionAndScale(0,0,0, 0,0,0, 1,1,1);
shaderUseMatrix(backShader->program, backShader->uniformPosition, &matrix);
// Render each pass.
for(i = 0; i < list->passCount; i++) {
pass = renderListGetPass(list, i);
textureBind(&pass->frame.texture, i);
shaderUseTexture(backShader->program, backShader->uniformTexture[i], i);
}
primitiveDraw(&list->quad, 0, -1);
}
void renderListResize(renderlist_t *list, int32_t width, int32_t height) {
uint8_t i;
if(
width == list->frame.texture.width &&
height == list->frame.texture.height
) return;
frameBufferDispose(&list->frame);
frameBufferInit(&list->frame, width, height);
for(i = 0; i < list->passCount; i++) {
frameBufferDispose(&list->passes[i].frame);
frameBufferInit(&list->passes[i].frame, width, height);
}
}
void renderListDispose(renderlist_t *list) {
uint8_t i;
for(i = 0; i < list->passCount; i++) {
frameBufferDispose(&list->passes[i].frame);
}
frameBufferDispose(&list->frame);
primitiveDispose(&list->quad);
}

View File

@ -1,109 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "framebuffer.h"
#include "primitive/primitive.h"
#include "shaderprogram.h"
#include "camera.h"
#include "../engine/engine.h"
#include "primitive/quad.h"
#include "../util/dynarray.h"
#include "render.h"
#define RENDER_PASSES_MAX 8
typedef struct {
framebuffer_t frame;
shaderprogram_t *shader;
} renderpass_t;
typedef struct {
framebuffer_t frame;
primitive_t quad;
renderpass_t passes[RENDER_PASSES_MAX];
uint8_t passCount;
} renderlist_t;
typedef struct {
shaderprogram_t *program;
shaderuniform_t uniformView;
shaderuniform_t uniformPosition;
shaderuniform_t uniformProjection;
shaderuniform_t uniformTexture[RENDER_PASSES_MAX];
} renderlistbackshader_t;
/**
* Initialize a render pass list.
*
* @param list List to initialize.
* @param width Width of the frame buffer(s).
* @param height Height of the frame buffer(s).
*/
void renderListInit(renderlist_t *list, int32_t width, int32_t height);
/**
* Retrieve the render pass at the given index.
*
* @param list List to get the pass from.
* @param pass Render pass index to get.
* @return The render pass at the given index.
*/
renderpass_t * renderListGetPass(renderlist_t *list, uint8_t pass);
/**
* Adds a render pass to the render list.
*
* @param list Render list to add the pass to.
* @param shader Shader to use for the render pass.
* @return The render pass index.
*/
uint8_t renderPassAdd(renderlist_t *list, shaderprogram_t *shader);
/**
* Prepare the rendering for a specific render pass. This will set up the
* render pass framebuffer, shader and prepare it for rendering.
*
* @param list List to get the render pass from.
* @param engine Game engine for the render pass.
* @param pass Pass index to render.
* @return The pointer to the render pass that is now active.
*/
renderpass_t * renderListRenderPass(
renderlist_t *list, engine_t *engine, uint8_t pass
);
/**
* Render a render list. The render list will provide the sum of the textures to
* the given shader as uniforms and then call a single render against a textured
* quad. The given shader will need to decide how to multiply the provided
* texture indexes.
*
* @param list List to render.
* @param backShader Shader to use while rendering.
*/
void renderListRender(renderlist_t *list, renderlistbackshader_t *backShader);
/**
* Resize an existing render list and all its render pass frame buffers. This
* will dispose (and clear) the existing frame buffers for both the list and
* each of the passes. Resizing to the same size won't cause an update to occur.
*
* @param list List to update.
* @param width New render list width.
* @param height New render list height.
*/
void renderListResize(renderlist_t *list, int32_t width, int32_t height);
/**
* Dispose a render list entirely.
*
* @param list Render list to dispose.
*/
void renderListDispose(renderlist_t *list);

View File

@ -1,142 +0,0 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "shaderprogram.h"
void shaderInit(shaderprogram_t *shader,
char *vertexShaderSource, char* fragmentShaderSource
) {
int isSuccess, maxLength;
char *error;
GLuint shaderVertex, shaderFragment, shaderProgram;
ASSERT_NOT_NULL(shader);
ASSERT_NOT_NULL(vertexShaderSource);
ASSERT_NOT_NULL(fragmentShaderSource);
// Load the vertex shader first
shaderVertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(shaderVertex, 1, &vertexShaderSource, 0);
glCompileShader(shaderVertex);
// Validate
glGetShaderiv(shaderVertex, GL_COMPILE_STATUS, &isSuccess);
if(!isSuccess) {
glGetShaderiv(shaderVertex, GL_INFO_LOG_LENGTH, &maxLength);
error = malloc(maxLength);
glGetShaderInfoLog(shaderVertex, maxLength, &maxLength, error);
printf("Failed to compile vertex shader %s\n", error);
free(error);
return;
}
// Now load the Frag shader
shaderFragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(shaderFragment, 1, &fragmentShaderSource, 0);
glCompileShader(shaderFragment);
glGetShaderiv(shaderFragment, GL_COMPILE_STATUS, &isSuccess);
if(!isSuccess) {
glGetShaderiv(shaderFragment, GL_INFO_LOG_LENGTH, &maxLength);
error = malloc(maxLength);
glGetShaderInfoLog(shaderFragment, maxLength, &maxLength, error);
printf("Failed to compile fragment shader %s\n", error);
free(error);
glDeleteShader(shaderVertex);
return;
}
// Now create the shader program.
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, shaderVertex);
glAttachShader(shaderProgram, shaderFragment);
//Bind, Verify & Use the shader program
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &isSuccess);
if(!isSuccess) {
glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &maxLength);
error = malloc(maxLength);
glGetProgramInfoLog(shaderProgram, maxLength, &maxLength, error);
printf("Failed to load shader program %s\n", error);
free(error);
glDeleteShader(shaderVertex);
glDeleteShader(shaderFragment);
return;
}
// Everything is okay, let's create the encapsulated shader.
shader->shaderVertex = shaderVertex;
shader->shaderFrag = shaderFragment;
shader->shaderProgram = shaderProgram;
// Bind the shader
shaderUse(shader);
}
void shaderDispose(shaderprogram_t *shader) {
ASSERT_NOT_NULL(shader);
glDeleteProgram(shader->shaderProgram);
glDeleteShader(shader->shaderVertex);
glDeleteShader(shader->shaderFrag);
}
void shaderUse(shaderprogram_t *shader) {
ASSERT_NOT_NULL(shader);
glUseProgram(shader->shaderProgram);
}
void shaderUseCamera(
shaderprogram_t *shader, shaderuniform_t uniformView,
shaderuniform_t uniformProjection, camera_t *camera
) {
ASSERT_NOT_NULL(shader);
ASSERT_NOT_NULL(camera);
ASSERT_GREATER_THAN_EQUAL_TO(uniformView, 0);
ASSERT_GREATER_THAN_EQUAL_TO(uniformProjection, 0);
shaderUseMatrix(shader, uniformView, &camera->view);
shaderUseMatrix(shader, uniformProjection, &camera->projection);
}
void shaderUseTexture(
shaderprogram_t *shader, shaderuniform_t uniform, textureslot_t slot
) {
ASSERT_NOT_NULL(shader);
ASSERT_GREATER_THAN_EQUAL_TO(uniform, 0);
ASSERT_GREATER_THAN_EQUAL_TO(slot, 0);
ASSERT_LESS_THAN(slot, TEXTURE_SLOTS_MAX);
glUniform1i(uniform, slot);
}
void shaderUseMatrix(
shaderprogram_t *shader, shaderuniform_t uniform, matrix_t *matrix
) {
ASSERT_NOT_NULL(shader);
ASSERT_NOT_NULL(matrix);
ASSERT_GREATER_THAN_EQUAL_TO(uniform, 0);
glUniformMatrix4fv(uniform, 1, GL_FALSE, matrix->internalMatrix[0]);
}
void shaderUseColor(
shaderprogram_t *shader, shaderuniform_t uniform, pixel_t color
) {
ASSERT_NOT_NULL(shader);
ASSERT_GREATER_THAN_EQUAL_TO(uniform, 0);
glUniform4f(uniform,
(float)color.r / 255.0f,
(float)color.g / 255.0f,
(float)color.b / 255.0f,
(float)color.a / 255.0f
);
}
shaderuniform_t shaderGetUniformByName(shaderprogram_t *sp, const char *name) {
ASSERT_NOT_NULL(sp);
ASSERT_NOT_NULL(name);
return glGetUniformLocation(sp->shaderProgram, name);
}

View File

@ -1,111 +0,0 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "../assert/assert.h"
#include "matrix.h"
#include "camera.h"
#include "texture.h"
/** Representation of a shader uniform */
typedef GLuint shaderuniform_t;
/**
* Structure containing information about an OpenGL Shader. For simplicity sake
* we demand certain uninforms to be present on the shader target.
*/
typedef struct {
/** Pointer to an uploaded vertex shader program */
shaderuniform_t shaderVertex;
/** Pointer to an uploaded fragment shader program */
shaderuniform_t shaderFrag;
/** Pointer to an uploaded shader program linked */
shaderuniform_t shaderProgram;
} shaderprogram_t;
/**
* Compiles a shader from vertex and fragment shader code.
*
* @param shader Shader to compile into.
* @param vertexShaderSource The raw vertex shader code.
* @param fragmentShaderSource The raw fragment shader code.
*/
void shaderInit(shaderprogram_t *shader,
char *vertexShaderSource, char* fragmentShaderSource
);
/**
* Cleanup and unload a previously loaded shader.
*
* @param shader The shader to unload
*/
void shaderDispose(shaderprogram_t *shader);
/**
* Attaches the supplied shader as the current shader.
*
* @param shader The shader to attach
*/
void shaderUse(shaderprogram_t *shader);
/**
* Attaches a camera to the shader.
*
* @param shader Shader to attach to.
* @param uniformView Uniform for the view matrix
* @param uniformProjection Uniform for the projection matrix.
* @param camera Camera to attach.
*/
void shaderUseCamera(
shaderprogram_t *shader, shaderuniform_t uniformView,
shaderuniform_t uniformProjection, camera_t *camera
);
/**
* Attaches a texture to the shader.
*
* @param shader Shader to attach to.
* @param uniform Uniform to set the texture on to.
* @param slot Which texture slot to bind to the uniform.
*/
void shaderUseTexture(
shaderprogram_t *shader, shaderuniform_t uniform, textureslot_t slot
);
/**
* Set's a specific shader uniform to a matrix.
*
* @param shader Shader to apply to.
* @param uniform Uniform on the shader to set.
* @param matrix Matrix to apply.
*/
void shaderUseMatrix(
shaderprogram_t *shader, shaderuniform_t uniform, matrix_t *matrix
);
/**
* Set a color on to the shader.
*
* @param shader Shader to set the color on to.
* @param uniform Uniform to set the color to.
* @param color Color to set.
*/
void shaderUseColor(
shaderprogram_t *shader, shaderuniform_t uniform, pixel_t color
);
/**
* Locate a shader uniform by its name.
*
* @param sp Shader program to get the uniform for.
* @param name Name of the uniform to get.
* @return The shader uniform.
*/
shaderuniform_t shaderGetUniformByName(shaderprogram_t *sp, const char *name);

View File

@ -1,10 +0,0 @@
# Copyright (c) 2022 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${PROJECT_NAME}
PRIVATE
standardshader.c
)

View File

@ -1,116 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "standardshader.h"
void _standardShaderUpdateUniforms(standardshader_t *stds) {
shaderprogram_t *sp;
ASSERT_NOT_NULL(stds);
sp = STANDARD_SHADER_SHADER(stds);
stds->uniformView = shaderGetUniformByName(
sp, STANDARD_SHADER_UNIFORM_NAME_VIEW
);
stds->uniformProjection = shaderGetUniformByName(
sp, STANDARD_SHADER_UNIFORM_NAME_PROJ
);
stds->uniformTexture = shaderGetUniformByName(
sp, STANDARD_SHADER_UNIFORM_NAME_TEXT
);
stds->uniformColor = shaderGetUniformByName(
sp, STANDARD_SHADER_UNIFORM_NAME_COLOR
);
stds->uniformPosition = shaderGetUniformByName(
sp, STANDARD_SHADER_UNIFORM_NAME_MODEL
);
}
bool _standardShaderOnAssetItemLoaded(
void *u, event_t e, const void *s[], const int32_t c
) {
standardshader_t *ss = (standardshader_t *)u;
ASSERT_NOT_NULL(ss);
ASSERT_EQUAL(e, ASSET_MANAGER_EVENT_ITEM_LOADED);
ASSERT_NOT_NULL(s);
ASSERT_EQUAL(c, 2);
if(s[1] != ss->shaderProgram) return true;
eventManagerUnsubscribe(&((assetmanager_t *)s[0])->events, ss->onItemLoaded);
_standardShaderUpdateUniforms(ss);
return true;
}
void standardShaderInit(standardshader_t *stds, assetmanager_t *assetManager) {
ASSERT_NOT_NULL(stds);
ASSERT_NOT_NULL(assetManager);
// Begin loading the shader.
stds->holder = assetManagerHolderCreate(assetManager);
stds->shaderProgram = assetManagerLoadShader(
assetManager, stds->holder,
STANDARD_SHARER_FILE_VERTEX, STANDARD_SHADER_FILE_FRAGMENT
);
// Update uniforms
if(assetManagerItemIsFinished(stds->shaderProgram)) {
_standardShaderUpdateUniforms(stds);
} else {
stds->onItemLoaded = eventManagerSubscribe(
&assetManager->events, ASSET_MANAGER_EVENT_ITEM_LOADED,
stds, &_standardShaderOnAssetItemLoaded
);
}
}
void standardShaderUse(standardshader_t *stds) {
ASSERT_NOT_NULL(stds);
if(!assetManagerItemIsFinished(stds->shaderProgram)) return;
shaderUse(STANDARD_SHADER_SHADER(stds));
}
void standardShaderSetCamera(standardshader_t *stds, camera_t *camera) {
ASSERT_NOT_NULL(stds);
ASSERT_NOT_NULL(camera);
if(!assetManagerItemIsFinished(stds->shaderProgram)) return;
shaderUseCamera(STANDARD_SHADER_SHADER(stds),
stds->uniformView, stds->uniformProjection, camera
);
}
void standardShaderSetTexture(standardshader_t *stds, texture_t *texture) {
ASSERT_NOT_NULL(stds);
ASSERT_NOT_NULL(texture);
if(!assetManagerItemIsFinished(stds->shaderProgram)) return;
textureBind(texture, 0);
shaderUseTexture(STANDARD_SHADER_SHADER(stds), stds->uniformTexture, 0);
}
void standardShaderSetColor(standardshader_t *stds, pixel_t color) {
ASSERT_NOT_NULL(stds);
if(!assetManagerItemIsFinished(stds->shaderProgram)) return;
shaderUseColor(STANDARD_SHADER_SHADER(stds), stds->uniformColor, color);
}
void standardShaderSetPosition(standardshader_t *stds, matrix_t *matrix) {
ASSERT_NOT_NULL(stds);
ASSERT_NOT_NULL(matrix);
if(!assetManagerItemIsFinished(stds->shaderProgram)) return;
shaderUseMatrix(STANDARD_SHADER_SHADER(stds), stds->uniformPosition, matrix);
}
void standardShaderDispose(standardshader_t *stds, assetmanager_t *assMan) {
ASSERT_NOT_NULL(stds);
ASSERT_NOT_NULL(assMan);
assetManagerHolderRelease(assMan, stds->holder);
}

View File

@ -1,91 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../../libs.h"
#include "../../assert/assert.h"
#include "../../engine/event.h"
#include "../shaderprogram.h"
#include "../../file/assetmanager.h"
#define STANDARD_SHADER_UNIFORM_NAME_VIEW "u_View"
#define STANDARD_SHADER_UNIFORM_NAME_PROJ "u_Proj"
#define STANDARD_SHADER_UNIFORM_NAME_TEXT "u_Text"
#define STANDARD_SHADER_UNIFORM_NAME_MODEL "u_Model"
#define STANDARD_SHADER_UNIFORM_NAME_COLOR "u_Color"
#define STANDARD_SHARER_FILE_VERTEX "shaders/textured.vert"
#define STANDARD_SHADER_FILE_FRAGMENT "shaders/textured.frag"
#define STANDARD_SHADER_SHADER(ss) (&ss->shaderProgram->data.shader.shader)
typedef struct {
assetmanageritem_t *shaderProgram;
assetmanagerholder_t holder;
eventlistener_t *onItemLoaded;
shaderuniform_t uniformView;
shaderuniform_t uniformProjection;
shaderuniform_t uniformPosition;
shaderuniform_t uniformTexture;
shaderuniform_t uniformColor;
} standardshader_t;
/**
* Initialize the standard shader.
*
* @param stds Standard Shader Instance.
* @param assetManager Asset Manager to load the shaders' assets.
*/
void standardShaderInit(standardshader_t *stds, assetmanager_t *assetManager);
/**
* Bind the standard shader as the currently active shader.
*
* @param stds Standard shader to bind.
*/
void standardShaderUse(standardshader_t *stds);
/**
* Set the camera for the standard shader.
*
* @param stds Standard shader instance.
* @param camera Camera to bind.
*/
void standardShaderSetCamera(standardshader_t *stds, camera_t *camera);
/**
* Set the texture for the standard shader.
*
* @param stds Standard shader instance.
* @param texture Texture to bind.
*/
void standardShaderSetTexture(standardshader_t *stds, texture_t *texture);
/**
* Set the color for the standard shader.
*
* @param stds Standard shader instance.
* @param color Color to bind.
*/
void standardShaderSetColor(standardshader_t *stds, pixel_t color);
/**
* Set the position matrix for the standard shader.
*
* @param stds Standard shader to use.
* @param matrix Matrix to use.
*/
void standardShaderSetPosition(standardshader_t *stds, matrix_t *matrix);
/**
* Dispose/cleanup the standard shader.
*
* @param stds Standard shader instance.
* @param assMan Asset manager instance.
*/
void standardShaderDispose(standardshader_t *stds, assetmanager_t *assMan);

View File

@ -1,49 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "spritebatch.h"
void spriteBatchInit(spritebatch_t *batch, int32_t maxSprites) {
batch->maxSprites = maxSprites;
batch->currentSprite = 0;
primitiveInit(&batch->primitive,
maxSprites*QUAD_VERTICE_COUNT, maxSprites*QUAD_INDICE_COUNT
);
}
void spriteBatchQuad(spritebatch_t *spriteBatch, int32_t index,
float x, float y, float z, float width, float height,
float u0, float v0, float u1, float v1
) {
if(index == -1) {
index = spriteBatch->currentSprite++;
} else {
spriteBatch->currentSprite = mathMax(index, spriteBatch->currentSprite);
}
quadBuffer(&spriteBatch->primitive, z,
x, y, u0, v0,
x+width, y+height, u1, v1,
index*QUAD_VERTICE_COUNT, index*QUAD_INDICE_COUNT
);
}
void spriteBatchFlush(spritebatch_t *spriteBatch) {
spriteBatch->currentSprite = 0;
}
void spriteBatchDraw(spritebatch_t *spriteBatch, int32_t index, int32_t count) {
if(count == -1) count = spriteBatch->currentSprite;
primitiveDraw(&spriteBatch->primitive,
index*QUAD_INDICE_COUNT, count*QUAD_INDICE_COUNT
);
}
void spriteBatchDispose(spritebatch_t *spriteBatch) {
primitiveDispose(&spriteBatch->primitive);
}

View File

@ -1,71 +0,0 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
#include "../util/math.h"
#include "primitive/primitive.h"
#include "primitive/quad.h"
/** Definition of a Sprite Batch. */
typedef struct {
/** Maximum sprites the batch can hold. */
int32_t maxSprites;
/** The current/next sprite index. */
int32_t currentSprite;
/** Internal primitive */
primitive_t primitive;
} spritebatch_t;
/**
* Creates a new Sprite Batch made of standard quads.
*
* @param batch Sprite batch to init.
* @param maxSprites The maxiumum number of sprites the batch can hold.
*/
void spriteBatchInit(spritebatch_t *batch, int32_t maxSprites);
/**
* Renders a sprite onto a given Sprite Batch.
*
* @param spriteBatch The sprite batch to render to.
* @param index The index within the sprite batch. Set to -1 to select "next".
* @param x X coordinate of the sprite.
* @param y Y coordinate of the sprite.
* @param width Width of the sprite.
* @param height Height of the sprite.
* @param u0 Texture U coordinate (min).
* @param v0 Texture V coordinate (min).
* @param u1 Texture U coordinate (max).
* @param v1 Texture V coordinate (max).
*/
void spriteBatchQuad(spritebatch_t *spriteBatch, int32_t index,
float x, float y, float z, float width, float height,
float u0, float v0, float u1, float v1
);
/**
* Flushes a sprite batch to reset the indexes.
* @param spriteBatch The batch.
*/
void spriteBatchFlush(spritebatch_t *spriteBatch);
/**
* Draws the Sprite Batch.
*
* @param spriteBatch The sprite batch to render.
* @param start Start index to render from.
* @param count Count of sprites to render. Set to -1 to render to the current.
*/
void spriteBatchDraw(spritebatch_t *spriteBatch, int32_t start, int32_t count);
/**
* Disposes a previously created Sprite Batch.
*
* @param spriteBatch The sprite batch to dispose.
*/
void spriteBatchDispose(spritebatch_t *spriteBatch);

View File

@ -1,87 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "texture.h"
// Due to some compiler bullshit, this is here.
#ifndef STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#endif
void textureInit(texture_t *texture, int32_t width, int32_t height,
pixel_t *pixels
) {
ASSERT_NOT_NULL(texture);
ASSERT_GREATER_THAN(width, 0);
ASSERT_GREATER_THAN(height, 0);
texture->width = width;
texture->height = height;
// Generate a texture ID and bind.
glGenTextures(1, &texture->id);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->id);
// Setup our preferred texture params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Start by buffering all transparent black pixels.
if(pixels == NULL) {
// TODO: I can optimize this, I think the GPU can default this somehow
pixels = calloc(width * height, sizeof(pixel_t));
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, pixels
);
free(pixels);
} else {
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, pixels
);
}
textureBind(texture, 0x00);
}
void textureBind(texture_t *texture, textureslot_t slot) {
ASSERT_NOT_NULL(texture);
ASSERT_GREATER_THAN_EQUAL_TO(slot, 0);
ASSERT_LESS_THAN(slot, TEXTURE_SLOTS_MAX);
glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(GL_TEXTURE_2D, texture->id);
}
void textureBufferPixels(texture_t *texture,
int32_t x, int32_t y, int32_t width, int32_t height, pixel_t *pixels
) {
ASSERT_NOT_NULL(texture);
ASSERT_NOT_NULL(pixels);
ASSERT_GREATER_THAN_EQUAL_TO(x, 0);
ASSERT_GREATER_THAN_EQUAL_TO(y, 0);
ASSERT_GREATER_THAN(width, 0);
ASSERT_GREATER_THAN(height, 0);
ASSERT_LESS_THAN_EQUAL_TO(width, texture->width);
ASSERT_LESS_THAN_EQUAL_TO(height, texture->height);
glBindTexture(GL_TEXTURE_2D, texture->id);
glTexSubImage2D(GL_TEXTURE_2D, 0,
x, y, width, height,
GL_RGBA, GL_UNSIGNED_BYTE, pixels
);
}
void textureDispose(texture_t *texture) {
ASSERT_NOT_NULL(texture);
glDeleteTextures(1, &texture->id);
}

View File

@ -1,83 +0,0 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
#include "../assert/assert.h"
#define TEXTURE_SLOTS_MAX 8
#define TEXTURE_CHANNELS 4
/** Texture slot that a texture can be bound to */
typedef GLuint textureslot_t;
/**
* Structure detailing information about a texture.
* Because we plan to upload the pixels of a texture into the GPU, we don't
* store the pixels in memory because we don't need to!
*/
typedef struct {
/** Width (in pixels) of the texture */
int32_t width;
/** Height (in pixels) of the texture */
int32_t height;
/** Texture ID on the GPU */
GLuint id;
} texture_t;
/** Information about a single pixel. */
typedef struct {
/** RGBA Color values */
uint8_t r, g, b, a;
} pixel_t;
#define PIXEL_COLOR_WHITE ((pixel_t){ .r = 255, .g = 255, .b = 255, .a = 255 })
#define PIXEL_COLOR_RED ((pixel_t){ .r = 255, .g = 0, .b = 0, .a = 255 })
#define PIXEL_COLOR_GREEN ((pixel_t){ .r = 0, .g = 255, .b = 0, .a = 255 })
#define PIXEL_COLOR_BLUE ((pixel_t){ .r = 0, .g = 0, .b = 255, .a = 255 })
#define PIXEL_COLOR_BLACK ((pixel_t){ .r = 0, .g = 0, .b = 0, .a = 255 })
#define PIXEL_COLOR_TRANSPARENT ((pixel_t){ .r = 0, .g = 0, .b = 0, .a = 0 })
/**
* Initializes a texture that can be written in to.
*
* @param texture Texture to initialize.
* @param width Width of the texture (in pixels).
* @param height Height of the texture (in pixels).
* @param pixels Default pixel array, set to NULL to set all pixel data to 0.
*/
void textureInit(texture_t *texture, int32_t width, int32_t height,
pixel_t *pixels
);
/**
* Bind a texture on to a given texture slot.
*
* @param texture Texture to bind.
* @param slot Slot to bind the texture to.
*/
void textureBind(texture_t *texture, textureslot_t slot);
/**
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so avoid
* doing this too often.
*
* @param texture Texture to buffer in to.
* @param x X coordinate in texture space to render to.
* @param y Y coordinate in texture space to render to.
* @param width Width of the pixel region you're buffering.
* @param height Height of the pixel region you're buffering.
* @param pixels Array of pixels to buffer onto the GPU.
*/
void textureBufferPixels(texture_t *texture,
int32_t x, int32_t y, int32_t width, int32_t height, pixel_t *pixels
);
/**
* Clean a previously created texture.
*
* @param texture Texture to clean up.
*/
void textureDispose(texture_t *texture);

View File

@ -1,29 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "texture.h"
#define MANAGED_TEXTURE_SCALE_MAX 5
typedef struct {
int16_t width;
int16_t height;
uint8_t scale;
} texturescalescale_t;
typedef struct {
uint8_t channels;
const char *file;
const char *path;
int16_t baseWidth;
int16_t baseHeight;
texturescalescale_t scales[MANAGED_TEXTURE_SCALE_MAX];
uint8_t scaleCount;
} texturescale_t;

View File

@ -1,62 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "tileset.h"
void tilesetInit(tileset_t *tileset,
int32_t columns, int32_t rows,
int32_t width, int32_t height,
int32_t gapX, int32_t gapY,
int32_t borderX, int32_t borderY
) {
float tdivX, tdivY;
int32_t x, y, i;
tileset->count = rows * columns;
tileset->divisions = malloc(sizeof(tilesetdiv_t) * tileset->count);
tileset->columns = columns;
tileset->rows = rows;
// Calculate division sizes (pixels)
tileset->divX = (
(float)width - ((float)borderX * 2.0f) - ((float)gapX * ((float)columns-1))
) / columns;
tileset->divY = (
(float)height - ((float)borderY * 2.0f) - ((float)gapY * ((float)rows - 1))
) / rows;
// Calculate the division sizes (units)
tdivX = tileset->divX / width;
tdivY = tileset->divY / height;
// Calculate the divisions (in units)
i = -1;
for(y = 0; y < rows; y++) {
for(x = 0; x < columns; x++) {
tileset->divisions[++i].x0 = (
borderX + (tileset->divX * x) + (gapX * x)
) / width;
tileset->divisions[i].x1 = tileset->divisions[i].x0 + tdivX;
tileset->divisions[i].y0 = (
borderY + (tileset->divY * y) + (gapY * y)
) / height;
tileset->divisions[i].y1 = tileset->divisions[i].y0 + tdivY;
}
}
}
tilesetdiv_t tilesetGetDivision(tileset_t *tileset,int32_t column,int32_t row) {
return tileset->divisions[
(column % tileset->columns) + (row * tileset->columns)
];
}
void tilesetDispose(tileset_t *tileset) {
free(tileset->divisions);
}

View File

@ -1,64 +0,0 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
/** Division of a texture */
typedef struct {
float x0, y0, x1, y1;
} tilesetdiv_t;
/** Definition of a Tileset */
typedef struct {
/** Count of X/Y divisions */
int32_t columns, rows;
/** Size of each divison (in pixels) */
float divX, divY;
/** Count of divisions (unused) */
int32_t count;
/** Division information */
tilesetdiv_t *divisions;
} tileset_t;
/**
* Create a tileset. Tilesets will be pre-divided to save performance later.
*
* @param tileset Tileset to init into.
* @param columns Count of columns.
* @param rows Count of rows.
* @param width Width of the tileset.
* @param height Height of the tileset.
* @param gapX Space between each column.
* @param gapY Space between each row.
* @param borderX Space around the edge of the tileset.
* @param borderY Space around the edge of the tileset.
*/
void tilesetInit(tileset_t *tileset,
int32_t columns, int32_t rows,
int32_t width, int32_t height,
int32_t gapX, int32_t gapY,
int32_t borderX, int32_t borderY
);
/**
* Retreive the division for a given tileset coordinate.
*
* @param tileset Tileset to retreive from.
* @param column X axis of the tileset.
* @param row Y axis of the tileset.
* @returns The Tileset division.
*/
tilesetdiv_t tilesetGetDivision(tileset_t *tileset,int32_t column, int32_t row);
/**
* Cleans a previously created tileset
*
* @param tileset Cleanup the tileset.
*/
void tilesetDispose(tileset_t *tileset);

View File

@ -1,19 +0,0 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${PROJECT_NAME}
PRIVATE
align.c
breakpoint.c
frame.c
framedtextmenu.c
grid.c
image.c
label.c
menu.c
rectangle.c
textmenu.c
)

View File

@ -1,78 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "align.h"
void alignmentGetAxis(
uint8_t align,
float containerSize, float childSize, float childPos,
float *outSize, float *outPos
) {
if(align & ALIGN_SIZE_FILL) {
*outSize = containerSize;
} else if(align & ALIGN_SIZE_ORIGINAL) {
*outSize = childSize;
}
if(align & ALIGN_POS_START) {
*outPos = 0;
} else if(align & ALIGN_POS_CENTER) {
*outPos = (containerSize/2.0f) - ((*outSize) / 2.0f);
} else if(align & ALIGN_POS_END) {
*outPos = containerSize - (*outSize);
}
}
align_t alignmentGet(
uint8_t alignX, uint8_t alignY,
float containerWidth, float containerHeight,
float childWidth, float childHeight,
float childX, float childY
) {
align_t out = {
.x = 0,
.y = 0,
.width = 0,
.height = 0
};
if(alignX & ALIGN_SIZE_RATIO) {
// Work out Y size and alignment first, then we base off that.
alignmentGetAxis(
alignY, containerHeight, childHeight, childY, &out.height, &out.y
);
// Now work out ratio
out.width = out.height * (childWidth / childHeight);
// Now do X
alignmentGetAxis(
alignX, containerWidth, childWidth, childX, &out.width, &out.x
);
} else {
alignmentGetAxis(
alignX, containerWidth, childWidth, childX, &out.width, &out.x
);
}
// Same as above but inverted for Y axis.
if(alignY & ALIGN_SIZE_RATIO) {
alignmentGetAxis(
alignX, containerWidth, childWidth, childX, &out.width, &out.x
);
out.height = out.width * (childHeight / childWidth);
alignmentGetAxis(
alignY, containerHeight, childHeight, childY, &out.height, &out.y
);
} else {
alignmentGetAxis(
alignY, containerHeight, childHeight, childY, &out.height, &out.y
);
}
return out;
}

View File

@ -1,60 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../../libs.h"
#include "../../util/flags.h"
#define ALIGN_POS_CENTER flagDefine(0)
#define ALIGN_POS_START flagDefine(1)
#define ALIGN_POS_END flagDefine(2)
#define ALIGN_SIZE_FILL flagDefine(3)
#define ALIGN_SIZE_ORIGINAL flagDefine(4)
#define ALIGN_SIZE_RATIO flagDefine(5)
typedef struct {
float x, y;
float width, height;
} align_t;
/**
* Return the alignment for a specific access, really this doesn't need to be
* used. Does not support the ALIGN_SIZE_RATIO alignment method.
*
* @param align Alignment flags to get.
* @param containerSize Size of the container.
* @param childSize Size of the child.
* @param childPos Currently unused.
* @param outSize Pointer to a float for the size output.
* @param outPos Poitner to a float for the position output.
*/
void alignmentGetAxis(
uint8_t align,
float containerSize, float childSize, float childPos,
float *outSize, float *outPos
);
/**
* Get the alignment set for a given set of options.
*
* @param alignX Alignment options for the X axis.
* @param alignY Alignment options for the Y axis.
* @param containerWidth Width of the container.
* @param containerHeight Height of the container.
* @param childWidth Width of the child
* @param childHeight Height of the child.
* @param childX Currently unused.
* @param childY Currently unused.
* @return The alignment calculation.
*/
align_t alignmentGet(
uint8_t alignX, uint8_t alignY,
float containerWidth, float containerHeight,
float childWidth, float childHeight,
float childX, float childY
);

View File

@ -1,44 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "breakpoint.h"
void breakpointListInit(breakpointlist_t *list) {
list->breakpointCount = 0;
list->user = NULL;
list->onBreakpoint = NULL;
list->breakpointCurrent = 0x00;
}
uint8_t breakpointGet(breakpointlist_t *list, float width) {
uint8_t bp, i;
bp = 0xFF;
for(i = 0; i < list->breakpointCount; i++) {
if(list->breakpoints[i] > width) break;
bp = i;
}
if(bp == 0xFF) bp = 0;
return bp;
}
void breakpointAdd(breakpointlist_t *list, float width) {
list->breakpoints[list->breakpointCount++] = width;
}
void breakpointResize(breakpointlist_t *list, float width) {
uint8_t bp;
// Determine breakpoint
bp = breakpointGet(list, width);
if(list->breakpointCurrent == bp) return;
list->breakpointCurrent = bp;
// Fire event.
if(list->onBreakpoint != NULL) {
list->onBreakpoint(list->user, bp, list->breakpoints[bp]);
}
}

View File

@ -1,60 +0,0 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../../libs.h"
/** Maximum breakpoints that the list can support. */
#define BREAKPOINT_COUNT_MAX 0x04
/** Callback for when a new breakpint is reached. */
typedef void breakpointcallback_t(void *user, uint8_t i, float breakpoint);
typedef struct {
/** List of breakpoints */
float breakpoints[BREAKPOINT_COUNT_MAX];
uint8_t breakpointCount;
/** Which breakpoint is current */
uint8_t breakpointCurrent;
/** Pointer to any custom user data. */
void *user;
/** Callback for when a breakpoint is reached */
breakpointcallback_t *onBreakpoint;
} breakpointlist_t;
/**
* Initialize a breakpoint.
*
* @param list List to initialize.
*/
void breakpointInit(breakpointlist_t *list);
/**
* Get the breakpoint for a given width set.
*
* @param list List to get from.
* @param width Width to use.
* @return The breakpoint (index) for this screen size.
*/
uint8_t breakpointGet(breakpointlist_t *list, float width);
/**
* Add a breakpoint definition to a breakpoint list.
*
* @param list List to add to.
* @param width Width of the breakpoint.
*/
void breakpointAdd(breakpointlist_t *list, float width);
/**
* Resize a breakpoint list, which (in turn) will fire the necessary events.
*
* @param list List to resize.
* @param width Width to use.
*/
void breakpointResize(breakpointlist_t *list, float width);

View File

@ -1,112 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "frame.h"
void frameInit(frame_t *frame) {
frame->texture = NULL;
primitiveInit(
&frame->primitive,
QUAD_VERTICE_COUNT * FRAME_PRIMITIVE_COUNT,
QUAD_INDICE_COUNT * FRAME_PRIMITIVE_COUNT
);
frameSetInnerSize(frame, FRAME_BORDER_SIZE, FRAME_BORDER_SIZE);
}
void frameSetSize(frame_t *frame, float width, float height) {
frameSetInnerSize(frame,
width - FRAME_BORDER_SIZE_FULL, height - FRAME_BORDER_SIZE_FULL
);
}
void frameSetInnerSize(frame_t *frame, float width, float height) {
float rightStart = FRAME_BORDER_SIZE + width;
float rightEnd = rightStart + FRAME_BORDER_SIZE;
float bottomStart = FRAME_BORDER_SIZE + height;
float bottomEnd = bottomStart + FRAME_BORDER_SIZE;
float tw = 1.0f / 3.0f;
float th = tw;
// Buffer the top left edge
quadBuffer(&frame->primitive, 0,
0, 0, 0, 0,
FRAME_BORDER_SIZE, FRAME_BORDER_SIZE, tw, th,
0, 0
);
// Buffer the top edge.
quadBuffer(&frame->primitive, 0,
FRAME_BORDER_SIZE, 0, tw, 0,
rightStart, FRAME_BORDER_SIZE, tw*2, th,
QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT
);
// Buffer the top right edge.
quadBuffer(&frame->primitive, 0,
rightStart, 0, tw*2, 0,
rightEnd, FRAME_BORDER_SIZE, tw*3, th,
QUAD_VERTICE_COUNT*2, QUAD_INDICE_COUNT*2
);
// Buffer the left edge
quadBuffer(&frame->primitive, 0,
0, FRAME_BORDER_SIZE, 0, th,
FRAME_BORDER_SIZE, bottomStart, tw, th*2,
QUAD_VERTICE_COUNT*3, QUAD_INDICE_COUNT*3
);
// Buffer the center
quadBuffer(&frame->primitive, 0,
FRAME_BORDER_SIZE, FRAME_BORDER_SIZE, tw, th,
rightStart, bottomStart, tw*2, th*2,
QUAD_VERTICE_COUNT*4, QUAD_INDICE_COUNT*4
);
// Buffer the right edge.
quadBuffer(&frame->primitive, 0,
rightStart, FRAME_BORDER_SIZE, tw*2, th,
rightEnd, bottomStart, tw*3, th*2,
QUAD_VERTICE_COUNT*5, QUAD_INDICE_COUNT*5
);
// Buffer the bottom left edge.
quadBuffer(&frame->primitive, 0,
0, bottomStart, 0, th*2,
FRAME_BORDER_SIZE, bottomEnd, tw, th*3,
QUAD_VERTICE_COUNT*6, QUAD_INDICE_COUNT*6
);
// Buffer the bottom edge.
quadBuffer(&frame->primitive, 0,
FRAME_BORDER_SIZE, bottomStart, tw, th*2,
rightStart, bottomEnd, tw*2, th*3,
QUAD_VERTICE_COUNT*7, QUAD_INDICE_COUNT*7
);
// Buffer the bottom right edge.
quadBuffer(&frame->primitive, 0,
rightStart, bottomStart, tw*2, th*2,
rightEnd, bottomEnd, tw*3, th*3,
QUAD_VERTICE_COUNT*8, QUAD_INDICE_COUNT*8
);
}
void frameRender(frame_t *frame, shaderprogram_t *shader, float x, float y) {
if(frame->texture == NULL) return;
shaderUsePosition(shader, x, y, 0, 0, 0, 0);
shaderUseTexture(shader, frame->texture);
primitiveDraw(&frame->primitive, 0, -1);
}
void frameDispose(frame_t *frame) {
primitiveDispose(&frame->primitive);
}

View File

@ -1,67 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../../libs.h"
#include "../shaderprogram.h"
#include "../primitive/primitive.h"
#include "../primitive/quad.h"
#include "../font.h"
/** Size of the border (in pixels) on each edge */
#define FRAME_BORDER_SIZE 16
/** Total border size for a given frame on each axis */
#define FRAME_BORDER_SIZE_FULL FRAME_BORDER_SIZE * 2
/** How many quads are within the frame */
#define FRAME_PRIMITIVE_COUNT 9
typedef struct {
texture_t *texture;
primitive_t primitive;
} frame_t;
/**
* Initialize a GUI Frame.
*
* @param frame Frame to initialize.
*/
void frameInit(frame_t *frame);
/**
* Set the size of the frame (including the size of the border).
*
* @param frame Frame to set the size of.
* @param width Width of the frame.
* @param height Height of the frame
*/
void frameSetSize(frame_t *frame, float width, float height);
/**
* Set the size of the frame's innards (size excluding the borders).
*
* @param frame Frame to set the size of
* @param width Width of the inner frame.
* @param height Height of the inner frame.
*/
void frameSetInnerSize(frame_t *frame, float width, float height);
/**
* Render a game frame.
*
* @param frame Frame to render.
* @param shader Shader to use while rendering.
* @param x X position.
* @param y Y position.
*/
void frameRender(frame_t *frame, shaderprogram_t *shader, float x, float y);
/**
* Cleanup a previously initialized frame.
*
* @param frame Frame to dispose.
*/
void frameDispose(frame_t *frame);

View File

@ -1,42 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "framedtextmenu.h"
void framedTextMenuInit(framedtextmenu_t *menu, font_t *font, texture_t *text) {
frameInit(&menu->frame);
textMenuInit(&menu->menu, font);
menu->frame.texture = text;
menu->menu.grid.borderX = FRAME_BORDER_SIZE;
menu->menu.grid.borderY = FRAME_BORDER_SIZE;
menu->menu.grid.gutterX = FRAMED_TEXT_MENU_GUTTER_DEFAULT;
menu->menu.grid.gutterY = FRAMED_TEXT_MENU_GUTTER_DEFAULT;
}
void framedTextMenuResize(framedtextmenu_t *menu, float width, float height) {
if(menu->menu.grid.width == width && menu->menu.grid.height == height) {
return;
}
gridResize(&menu->menu.grid, width, height);
frameSetSize(&menu->frame, width, height);
}
void framedTextMenuUpdate(framedtextmenu_t *menu, engine_t *engine) {
menuUpdate(&menu->menu.menu, engine);
}
void framedTextMenuRender(
framedtextmenu_t *menu, shaderprogram_t *shader, float x, float y
) {
frameRender(&menu->frame, shader, x, y);
textMenuRender(&menu->menu, shader, x, y);
}
void framedTextMenuDispose(framedtextmenu_t *menu) {
textMenuDispse(&menu->menu);
frameDispose(&menu->frame);
}

View File

@ -1,67 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../engine/engine.h"
#include "../libs.h"
#include "frame.h"
#include "textmenu.h"
#include "grid.h"
#include "menu.h"
/** The default gutter for the grid of a framed text menu */
#define FRAMED_TEXT_MENU_GUTTER_DEFAULT 8.0f
typedef struct {
frame_t frame;
textmenu_t menu;
} framedtextmenu_t;
/**
* Initialize a framed text ui element.
*
* @param menu Menu to initialize.
* @param font Font to use for the text.
* @param text Texture for the frame.
*/
void framedTextMenuInit(framedtextmenu_t *menu, font_t *font, texture_t *text);
/**
* Resize a framed text menu.
*
* @param menu Menu to resize.
* @param width Width of the menu.
* @param height Height of the menu.
*/
void framedTextMenuResize(framedtextmenu_t *menu, float width, float height);
/**
* Update a framed text menu.
*
* @param menu Menu to update.
* @param engine Engine to use when updating.
*/
void framedTextMenuUpdate(framedtextmenu_t *menu, engine_t *engine);
/**
* Render a framed text menu.
*
* @param menu Menu to render.
* @param shader Shader to use.
* @param x X Position.
* @param y Y Position.
*/
void framedTextMenuRender(
framedtextmenu_t *menu, shaderprogram_t *shader, float x, float y
);
/**
* Dispose a previously created framed text menu.
*
* @param menu Menu to dispose.
*/
void framedTextMenuDispose(framedtextmenu_t *menu);

View File

@ -1,138 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "grid.h"
void gridInit(grid_t *grid) {
uint8_t i;
grid->columns = 1;
grid->rows = 1;
grid->gutterX = 0;
grid->gutterY = 0;
grid->borderX = 0;
grid->borderY = 0;
grid->width = 1;
grid->height = 1;
for(i = 0; i < GRID_COLUMN_COUNT_MAX; i++) {
grid->columnDefinitions[i] = GRID_CEL_SIZE_AUTO;
}
for(i = 0; i < GRID_ROW_COUNT_MAX; i++) {
grid->rowDefinitions[i] = GRID_CEL_SIZE_AUTO;
}
}
void gridRecalculate(grid_t *grid) {
uint8_t i, countFlexiColumns, countFlexiRows;
float flexiWidth, flexiHeight, s, p, totalFlexiWidth, totalFlexiHeight;
// Pass 1, determine the "flexible width size"
countFlexiColumns = 0;
countFlexiRows = 0;
totalFlexiWidth = (
grid->width -
(grid->gutterX * mathMax(grid->columns-1, 0)) -
(grid->borderX * 2.0f)
);
totalFlexiHeight = (
grid->height -
(grid->gutterY * mathMax(grid->rows-1, 0)) -
(grid->borderY * 2.0f)
);
for(i = 0; i < grid->columns; i++) {
if(grid->columnDefinitions[i] == GRID_CEL_SIZE_AUTO) {
countFlexiColumns++;
} else {
totalFlexiWidth -= grid->columnDefinitions[i];
}
}
for(i = 0; i < grid->rows; i++) {
if(grid->rowDefinitions[i] == GRID_CEL_SIZE_AUTO) {
countFlexiRows++;
} else {
totalFlexiHeight -= grid->rowDefinitions[i];
}
}
// Determine the "flexi size for each flexi cell"
flexiWidth = totalFlexiWidth / countFlexiColumns;
flexiHeight = totalFlexiHeight / countFlexiRows;
// Now set up the positions and sizes for each cell.
p = grid->borderX;
for(i = 0; i < grid->columns; i++) {
s = grid->columnDefinitions[i];
if(s == GRID_CEL_SIZE_AUTO) s = flexiWidth;
grid->columnPositions[i] = p;
grid->columnSizes[i] = s;
p += s + grid->gutterX;
}
p = grid->borderY;
for(i = 0; i < grid->rows; i++) {
s = grid->rowDefinitions[i];
if(s == GRID_CEL_SIZE_AUTO) s = flexiHeight;
grid->rowPositions[i] = p;
grid->rowSizes[i] = s;
p += s + grid->gutterY;
}
}
void gridResize(grid_t *grid, float width, float height) {
if(grid->width == width && grid->height == height) return;
grid->width = width;
grid->height = height;
gridRecalculate(grid);
}
void gridGetChild(
grid_t *grid, uint8_t col, uint8_t row, uint8_t columns, uint8_t rows,
float *x, float *y, float *width, float *height
) {
uint8_t i;
float s;
// Set positions
*x = grid->columnPositions[col];
*y = grid->rowPositions[row];
// Calculate width.
s = 0;
for(i = col; i < col+columns; i++) {
s += grid->columnSizes[i];
}
*width = s;
// Calculate height
s = 0;
for(i = row; i < row+rows; i++) {
s += grid->rowSizes[i];
}
*height = s;
}
align_t gridGetAndAlignChild(
grid_t *grid, uint8_t col, uint8_t row, uint8_t columns, uint8_t rows,
uint8_t alignX, uint8_t alignY, float width, float height
) {
float gx, gy, gw, gh;
// Get the size of the child first
gridGetChild(grid, col, row, columns, rows, &gx, &gy, &gw, &gh);
// Now align
align_t align = alignmentGet(alignX, alignY, gw, gh, width, height, -1,-1);
align.x += gx;
align.y += gy;
return align;
}

View File

@ -1,102 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "../util/math.h"
#include "align.h"
/** Maximum number of columns a grid can have */
#define GRID_COLUMN_COUNT_MAX 16
/** Maximum number of rows a grid can have */
#define GRID_ROW_COUNT_MAX GRID_COLUMN_COUNT_MAX
/** Cell size for "auto", basically to fill the remaining space evenly */
#define GRID_CEL_SIZE_AUTO -1
/** Definitio of a grid */
typedef struct {
/** Count of columns/rows in the grid */
uint8_t columns, rows;
/** Cell Definitions, used to control how the cells will size themselves */
float columnDefinitions[GRID_COLUMN_COUNT_MAX];
float rowDefinitions[GRID_COLUMN_COUNT_MAX];
/** Settings to control gutters (space between cells) and border (of grid) */
float gutterX, gutterY;
float borderX, borderY;
/** Calculated sizes and positions for each cell */
float columnSizes[GRID_COLUMN_COUNT_MAX];
float columnPositions[GRID_COLUMN_COUNT_MAX];
float rowSizes[GRID_ROW_COUNT_MAX];
float rowPositions[GRID_COLUMN_COUNT_MAX];
/** Cached size of the grid */
float width, height;
} grid_t;
/**
* Initialize a grid system.
*
* @param grid Grid system to initialize.
*/
void gridInit(grid_t *grid);
/**
* Recalculate the cell size and positions.
*
* @param grid Grid to recalculate for.
*/
void gridRecalculate(grid_t *grid);
/**
* Resize (and recalculate) a grid.
*
* @param grid Grid to resize.
* @param width Width to use.
* @param height Height to use.
*/
void gridResize(grid_t *grid, float width, float height);
/**
* Get the dimensions of a particular cell and span.
*
* @param grid Grid to get from.
* @param col Starting column.
* @param row Starting row.
* @param columns Count of columns the cell spans.
* @param rows Count of rows the cell spans.
* @param x Pointer to output X float.
* @param y Pointer to output Y float
* @param width Pointer to output width float.
* @param height Pointer to output height float.
*/
void gridGetChild(
grid_t *grid, uint8_t col, uint8_t row, uint8_t columns, uint8_t rows,
float *x, float *y, float *width, float *height
);
/**
* Align a child within its set cell.
*
* @param grid Grid to use when aligning.
* @param col Starting column.
* @param row Starting row.
* @param columns Count of columns the cell spans.
* @param rows Count of rows the cell spans.
* @param alignX Alignment flags for the X axis.
* @param alignY Alignment flags for the Y axis.
* @param width Current width of the child.
* @param height Current height of the child.
* @return The alignment information to align the child within the cell.
*/
align_t gridGetAndAlignChild(
grid_t *grid, uint8_t col, uint8_t row, uint8_t columns, uint8_t rows,
uint8_t alignX, uint8_t alignY, float width, float height
);

View File

@ -1,62 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "image.h"
void imageInit(image_t *image) {
image->quad.verticeCount = -1;
image->width = 1;
image->height = 1;
imageSetTexture(image, NULL);
}
void imageSetTexture(image_t *image, texture_t *texture) {
imageSetTextureAndCrop(image, texture,
0, 0,
texture == NULL ? 0 : (float)texture->width,
texture == NULL ? 0 : (float)texture->height
);
}
void imageSetTextureAndCrop(image_t *image, texture_t *texture,
float x, float y, float width, float height
) {
float u0, u1, v0, v1;
if(image->quad.verticeCount != -1) {
primitiveDispose(&image->quad);
image->quad.verticeCount = -1;
}
if(texture == NULL) return;
u0 = x / texture->width;
u1 = u0 + (width / texture->width);
v0 = y / texture->height;
v1 = v0 + (height / texture->height);
image->texture = texture;
image->width = width;
image->height = height;
quadInit(&image->quad, 0,
0,0,u0,v0,
1,1,u1,v1
);
}
void imageRender(image_t *image, shaderprogram_t *shader, float x, float y) {
if(image->texture == NULL) return;
shaderUsePositionAndScale(shader,
x,y,0,
0,0,0,
image->width, image->height, 1
);
shaderUseTexture(shader, image->texture);
primitiveDraw(&image->quad, 0, -1);
}
void imageDispose(image_t *image) {
if(image->quad.verticeCount != -1) primitiveDispose(&image->quad);
}

View File

@ -1,66 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "../display/primitive/primitive.h"
#include "../display/primitive/quad.h"
#include "../display/texture.h"
#include "../display/shaderprogram.h"
typedef struct {
texture_t *texture;
primitive_t quad;
float width, height;
} image_t;
/**
* Initialize an image.
*
* @param image Image to initialize.
*/
void imageInit(image_t *image);
/**
* Set the texture for an image. This will also initialize the underlying quad.
*
* @param image Image to set the texture for.
* @param texture Texture to use.
*/
void imageSetTexture(image_t *image, texture_t *texture);
/**
* Set the texture for an image. This will also initialize the underlying quad.
* Also allows cropping of the texture image.
*
* @param image Image to set the texture for.
* @param texture Texture to use.
* @param x X position of the crop.
* @param y Y position of the crop.
* @param width Width of the crop.
* @param height Height of the crop.
*/
void imageSetTextureAndCrop(image_t *image, texture_t *texture,
float x, float y, float width, float height
);
/**
* Render an image
*
* @param image Image to render.
* @param shader Shader to use while rendering.
* @param x X position.
* @param y Y position.
*/
void imageRender(image_t *image, shaderprogram_t *shader, float x, float y);
/**
* Cleanup a previously initialized image.
*
* @param image Image to dispose.
*/
void imageDispose(image_t *image);

View File

@ -1,39 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "label.h"
void labelInit(label_t *label) {
label->fontSize = FONT_SIZE_DEFAULT;
label->font = NULL;
label->maxWidth = -1;
label->primitive.verticeCount = 0;
}
void labelSetText(label_t *label, font_t *font, char *text) {
if(label->primitive.verticeCount != 0) {
primitiveDispose(&label->primitive);
label->primitive.verticeCount = 0;
}
label->font = font;
fontTextBuffer(
font, &label->primitive, &label->info, text,
label->maxWidth, label->fontSize
);
}
void labelRender(label_t *label, shaderprogram_t *shader, float x, float y) {
if(label->primitive.verticeCount == 0) return;
shaderUsePosition(shader, x,y,0, 0,0,0);
shaderUseTexture(shader, &label->font->texture);
primitiveDraw(&label->primitive, 0, -1);
}
void labelDispose(label_t *label) {
primitiveDispose(&label->primitive);
}

View File

@ -1,51 +0,0 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
#include "../display/shaderprogram.h"
#include "../display/primitive/primitive.h"
#include "../display/font.h"
/** Representation of a Label UI Element */
typedef struct {
font_t *font;
float fontSize;
float maxWidth;
fonttextinfo_t info;
primitive_t primitive;
} label_t;
/**
* Initialize a Label UI Element.
* @param label Label to initialize.
*/
void labelInit(label_t *label);
/**
* Sets the text for a given label.
*
* @param label Label to update.
* @param font Font to use.
* @param text Text to set.
*/
void labelSetText(label_t *label, font_t *font, char *text);
/**
* Render a label UI element.
*
* @param label Label to render.
* @param shader Shader to use while rendering.
* @param x X position.
* @param y Y position.
*/
void labelRender(label_t *label, shaderprogram_t *shader, float x, float y);
/**
* Dispose a previously created label.
*
* @param label Label to dispose.
*/
void labelDispose(label_t *label);

View File

@ -1,97 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "menu.h"
void menuInit(menu_t *menu) {
menu->itemCount = 0;
menu->selected = 0;
menu->cursorX = 0;
menu->cursorY = 0;
menu->user = NULL;
menu->onSelect = NULL;
}
void menuUpdate(menu_t *menu, engine_t *engine) {
menuitem_t *current;
menuitem_t *item;
uint8_t x, y, i, j;
current = menu->items + menu->selected;
if(inputIsPressed(&engine->input, INPUT_ACCEPT)) {
if(menu->onSelect != NULL) {
menu->onSelect(menu->user, menu->selected);
}
return;
}
// Handle press binds.
if(inputIsPressed(&engine->input, INPUT_DOWN)) {
x = 0;
y = 1;
} else if(inputIsPressed(&engine->input, INPUT_UP)) {
x = 0;
y = -1;
} else if(inputIsPressed(&engine->input, INPUT_LEFT)) {
x = -1;
y = 0;
} else if(inputIsPressed(&engine->input, INPUT_RIGHT)) {
x = 1;
y = 0;
} else {
x = 0;
y = 0;
}
// Update cursor positions
if(x != 0 || y != 0) {
if(x > 0) {
menu->cursorX = (current->x + current->width - 1) + x;
} else if(x < 0) {
menu->cursorX = current->x + x;
}
if(y > 0) {
menu->cursorY = (current->y + current->height - 1) + y;
} else if(y < 0) {
menu->cursorY = current->y + y;
}
// Get the item selected
j = MENU_ITEMS_MAX;
for(i = 0; i < menu->itemCount; i++) {
if(i == menu->selected) continue;
item = menu->items + i;
if(
item->x > menu->cursorX || (item->x+item->width-1) < menu->cursorX ||
item->y > menu->cursorY || (item->y+item->height-1) < menu->cursorY
) continue;
j = i;
break;
}
// Was a target found?
if(j == MENU_ITEMS_MAX) return;
menu->selected = j;
}
}
menuitem_t * menuAdd(menu_t *menu) {
menuitem_t *item;
if(menu->itemCount >= MENU_ITEMS_MAX) return NULL;
item = menu->items + menu->itemCount++;
item->x = 0;
item->y = 0;
item->width = 1;
item->height = 1;
return item;
}

View File

@ -1,62 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "../input/input.h"
#include "../epoch/epoch.h"
#include "../util/array.h"
#include "../engine/engine.h"
/** The maximum number of items a menu can hold */
#define MENU_ITEMS_MAX 32
/** Callback for when menu events are fired. */
typedef void menucallback_t(void *user, uint8_t i);
typedef struct {
uint8_t x;
uint8_t y;
uint8_t width;
uint8_t height;
} menuitem_t;
typedef struct {
menuitem_t items[MENU_ITEMS_MAX];
uint8_t itemCount;
uint8_t selected;
uint8_t cursorX;
uint8_t cursorY;
void *user;
menucallback_t *onSelect;
} menu_t;
/**
* Initialize a menu.
*
* @param menu Menu to initialize.
* @param columns Count of rows.
* @param rows Count of columns.
*/
void menuInit(menu_t *menu);
/**
* Updates the menu to handle inputs.
*
* @param menu Menu to update.
* @param engine Engine to update from.
*/
void menuUpdate(menu_t *menu, engine_t *engine);
/**
* Add an item to the menu
*
* @param menu Menu to add to.
* @return Item to add to.
*/
menuitem_t * menuAdd(menu_t *menu);

View File

@ -1,38 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "rectangle.h"
void rectangleInit(rectangle_t *rectangle) {
rectangle->width = 32;
rectangle->height = 32;
textureInit(&rectangle->texture, 1, 1, NULL);
quadInit(&rectangle->quad, 0, 0,0,0,0, 1,1,1,1);
}
void rectangleSetColor(rectangle_t *rectangle, pixel_t color) {
textureBufferPixels(&rectangle->texture,
0, 0, 1, 1, &color
);
}
void rectangleRender(
rectangle_t *rect, shaderprogram_t *shader, float x, float y
) {
shaderUsePositionAndScale(shader,
x, y, 0,
0, 0, 0,
rect->width, rect->height, 1
);
shaderUseTexture(shader, &rect->texture);
primitiveDraw(&rect->quad, 0, -1);
}
void rectangleDispose(rectangle_t *rectangle) {
primitiveDispose(&rectangle->quad);
textureDispose(&rectangle->texture);
}

View File

@ -1,30 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "../display/texture.h"
#include "../display/shaderprogram.h"
#include "../display/primitive/primitive.h"
#include "../display/primitive/quad.h"
typedef struct {
float width, height;
texture_t texture;
primitive_t quad;
} rectangle_t;
void rectangleInit(rectangle_t *rectangle);
void rectangleSetColor(rectangle_t *rectangle, pixel_t color);
void rectangleRender(
rectangle_t *rect, shaderprogram_t *shader,
float x, float y
);
void rectangleDispose(rectangle_t *rectangle);

View File

@ -1,79 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "textmenu.h"
void _textMenuOnSelect(void *user, uint8_t i) {
textmenu_t *textMenu = (textmenu_t *)user;
if(textMenu->onSelect != NULL) {
textMenu->onSelect(textMenu->user, i, textMenu->texts[i]);
}
}
void textMenuInit(textmenu_t *menu, font_t *font) {
menuInit(&menu->menu);
gridInit(&menu->grid);
rectangleInit(&menu->rectangle);
rectangleSetColor(&menu->rectangle, TEXTMENU_SELECTION_COLOR);
menu->menu.user = menu;
menu->menu.onSelect = &_textMenuOnSelect;
menu->font = font;
menu->onSelect = NULL;
}
menuitem_t * textMenuAdd(textmenu_t *menu, char *item) {
menu->texts[menu->menu.itemCount] = item;
labelInit(menu->labels + menu->menu.itemCount);
labelSetText(menu->labels + menu->menu.itemCount, menu->font, item);
(menu->labels + menu->menu.itemCount)->font = menu->font;
return menuAdd(&menu->menu);
}
void textMenuRender(
textmenu_t *menu, shaderprogram_t *shader, float x, float y
) {
uint8_t i;
label_t *label;
menuitem_t *item;
align_t align;
float gx, gy;
// Render selection box.
item = menu->menu.items + menu->menu.selected;
gridGetChild(
&menu->grid, item->x, item->y, item->width, item->height,
&gx, &gy, &menu->rectangle.width, &menu->rectangle.height
);
rectangleRender(
&menu->rectangle, shader, x + gx, y + gy
);
// Render labels
for(i = 0; i < menu->menu.itemCount; i++) {
item = menu->menu.items + i;
label = menu->labels + i;
align = gridGetAndAlignChild(
&menu->grid, item->x, item->y, item->width, item->height,
ALIGN_POS_START | ALIGN_SIZE_ORIGINAL,
ALIGN_POS_START | ALIGN_SIZE_ORIGINAL,
label->info.width, label->info.height
);
labelRender(
label, shader, align.x + x, align.y + y
);
}
}
void textMenuDispse(textmenu_t *menu) {
uint8_t i;
rectangleDispose(&menu->rectangle);
for(i = 0; i < menu->menu.itemCount; i++) {
labelDispose(menu->labels + i);
}
}

View File

@ -1,69 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "menu.h"
#include "grid.h"
#include "label.h"
#include "rectangle.h"
/** Colour of the selection box for the text menu */
#define TEXTMENU_SELECTION_COLOR ((pixel_t){.r=0xFF,.g=0xFF,.b=0xFF,.a=0x64})
/** Callback type for when an item is selected */
typedef void textmenucallback_t(void *user, uint8_t i, char *text);
typedef struct {
menu_t menu;
grid_t grid;
font_t *font;
rectangle_t rectangle;
char *texts[MENU_ITEMS_MAX];
label_t labels[MENU_ITEMS_MAX];
textmenucallback_t *onSelect;
void *user;
} textmenu_t;
/** Callback to be notified from the menu when the menu items are selected. */
void _textMenuOnSelect(void *user, uint8_t i);
/**
* Initialize a text menu item.
*
* @param menu Menu to initialize.
* @param font Font to use during initialization.
*/
void textMenuInit(textmenu_t *menu, font_t *font);
/**
* Add text to a menu list.
*
* @param menu Menu to add to.
* @param item Text to add (must be a constant value).
* @return The grid subsystem item.
*/
menuitem_t * textMenuAdd(textmenu_t *menu, char *item);
/**
* Render a text menu list.
*
* @param menu Menu to render.
* @param shader Shader to use.
* @param x X position of the menu.
* @param y Y position of the menu.
*/
void textMenuRender(textmenu_t *menu, shaderprogram_t *shader,float x, float y);
/**
* Dispose/Cleanup a text menu.
*
* @param menu Text menu to dispose.
*/
void textMenuDispse(textmenu_t *menu);

View File

@ -1,12 +0,0 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${PROJECT_NAME}
PRIVATE
engine.c
thread.c
event.c
)

View File

@ -1,57 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "engine.h"
void engineInit(engine_t *engine) {
ASSERT_NOT_NULL(engine);
randSeed(123);
#if defined(GAME_NAME)
engine->name = GAME_NAME;
#else
engine->name = "Dawn";
#endif
epochInit(&engine->time);
saveManagerInit(&engine->save);
inputInit(&engine->input);
assetManagerInit(&engine->assetManager, &engine->save);
renderInit();
assetManagerStart(&engine->assetManager);
}
void engineUpdateStart(engine_t *engine, float delta) {
ASSERT_NOT_NULL(engine);
ASSERT_GREATER_THAN(delta, 0);
epochUpdate(&engine->time, delta);
inputUpdate(&engine->input);
assetManagerUpdate(&engine->assetManager);
renderFrameStart(&engine->render);
}
bool engineUpdateEnd(engine_t *engine) {
ASSERT_NOT_NULL(engine);
if(inputIsPressed(&engine->input, INPUT_NULL)) {
printf("Game exit requested\n");
return false;
}
return true;
}
void engineDispose(engine_t *engine) {
ASSERT_NOT_NULL(engine);
assetManagerDispose(&engine->assetManager);
inputDispose(&engine->input);
renderDispose();
}

View File

@ -1,70 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "../assert/assert.h"
#include "../util/rand.h"
#include "../input/input.h"
#include "../epoch/epoch.h"
#include "../display/render.h"
#include "../file/assetmanager.h"
#include "../save/save.h"
#include "scene/scenemanager.h"
typedef struct {
/** Name of the game */
char *name;
/** Time Manager for the game */
epoch_t time;
/** Render Manager for the game */
render_t render;
/** Asset Manager for the game */
assetmanager_t assetManager;
/** Input Manager for the game */
input_t input;
/** Save Manager for the game */
savemanager_t save;
/** Scene Manager for the game */
scenemanager_t scene;
} engine_t;
/**
* Initializes the provided engine. This will initialize all of the various
* managers for the game to use.
*
* @param engine Engine to initialize.
*/
void engineInit(engine_t *engine);
/**
* Updates the given engine at the start of a frame.
*
* @param engine Engine that is being updated
* @param delta Delta tick provided by the game's platform.
*/
void engineUpdateStart(engine_t *engine, float delta);
/**
* Updates the given engine at the end of a frame.
*
* @param engine Engine to update.
*/
bool engineUpdateEnd(engine_t *engine);
/**
* Cleanup the engine context.
*
* @param engine Engine to clean up.
*/
void engineDispose(engine_t *engine);

View File

@ -1,81 +0,0 @@
/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "event.h"
void eventManagerInit(eventmanager_t *manager) {
uint8_t i;
ASSERT_NOT_NULL(manager);
for(i = 0; i < EVENT_LISTENER_COUNT_MAX; i++) {
manager->listeners[i].callback = NULL;
}
}
bool _eventManagerFindFree(int32_t i, void *item) {
return ((eventlistener_t *) item)->callback == NULL;
}
eventlistener_t * eventManagerSubscribe(
eventmanager_t *man, event_t event, void *user, eventcallback_t *callback
) {
int32_t first;
eventlistener_t *listener;
ASSERT_NOT_NULL(man);
ASSERT_NOT_NULL(callback);
// Find the first available space.
first = arrayFindCallback(
sizeof(eventmanager_t), man->listeners,
EVENT_LISTENER_COUNT_MAX, _eventManagerFindFree
);
ASSERT_LESS_THAN(first, EVENT_LISTENER_COUNT_MAX);
ASSERT_GREATER_THAN_EQUAL_TO(first, 0);
// Insert
listener = man->listeners + first;
listener->callback = callback;
listener->user = user;
listener->event = event;
return listener;
}
void eventManagerUnsubscribe(eventmanager_t *man, eventlistener_t *listener) {
ASSERT_NOT_NULL(man);
ASSERT_NOT_NULL(listener);
listener->callback = NULL;
}
bool eventManagerTrigger(
eventmanager_t *manager, event_t event, const void *args[], const int32_t argc
) {
uint8_t i;
eventlistener_t *listener;
bool result;
ASSERT_GREATER_THAN_EQUAL_TO(argc, 0);
ASSERT_IF(
argc > 0,
ASSERT_NOT_NULL(args)
);
for(i = 0; i < EVENT_LISTENER_COUNT_MAX; i++) {
listener = manager->listeners + i;
if(listener->callback == NULL) continue;
if(listener->event != event) continue;
result = listener->callback(listener->user, event, args, argc);
if(!result) return false;
}
return true;
}

View File

@ -1,68 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
#include "../assert/assert.h"
#include "../util/array.h"
#define EVENT_LISTENER_COUNT_MAX 128
typedef uint8_t event_t;
typedef bool eventcallback_t(
void *user, event_t event, const void *args[], const int32_t argc
);
typedef struct {
void *user;
event_t event;
eventcallback_t *callback;
} eventlistener_t;
typedef struct {
eventlistener_t listeners[EVENT_LISTENER_COUNT_MAX];
} eventmanager_t;
/**
* Initialize the event manager.
*
* @param manager Event manager to initialize.
*/
void eventManagerInit(eventmanager_t *manager);
/**
* Subscribe to an event on a given event manager.
*
* @param man Event manager to subscribe to.
* @param event Event to subscribe to.
* @param user Any custom user data to provide to the event callback.
* @param callback Callback to fire when the event is triggered.
* @return The event listener that was subscribed to.
*/
eventlistener_t * eventManagerSubscribe(
eventmanager_t *man, event_t event, void *user, eventcallback_t *callback
);
/**
* Unsubscribe an event listener that was previously subscribed.
*
* @param listener Listener to unsubscribe.
*/
void eventManagerUnsubscribe(eventmanager_t *man, eventlistener_t *listener);
/**
* Trigger a specific event on the event manager.
*
* @param manager Manager to trigger the event on.
* @param event Event to trigger
* @param args Array of pointers for event arguments.
* @param argc Count of event arguments.
* @return True if no events are subscribed, otherwise only returns true if all
* event listeners also return true.
*/
bool eventManagerTrigger(
eventmanager_t *manager, event_t event, const void *args[], const int32_t argc
);

View File

@ -1,62 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "thread.h"
void threadInit(thread_t *thread, threadfunction_t *call) {
ASSERT_NOT_NULL(thread);
ASSERT_NOT_NULL(call);
thread->call = call;
thread->user = NULL;
thread->state = 0x00;
}
void threadStart(thread_t *thread) {
ASSERT_NOT_NULL(thread);
ASSERT_FLAG_OFF(thread->state, THREAD_FLAG_RUNNING);
ASSERT_FLAG_OFF(thread->state, THREAD_FLAG_QUEUED);
thread->state |= THREAD_FLAG_QUEUED;
sysThreadCreate(&_threadWrappedCallback, thread->pt, thread);
}
void threadJoin(thread_t *thread) {
ASSERT_NOT_NULL(thread);
ASSERT_FLAG_ON(thread->state, THREAD_FLAG_RUNNING);
sysThreadJoin(thread->pt);
}
void threadCancel(thread_t *thread) {
ASSERT_NOT_NULL(thread);
ASSERT_FLAG_ON(thread->state, THREAD_FLAG_RUNNING);
sysThreadCancel(thread->pt, 1);
}
void threadSleep(float time) {
ASSERT_GREATER_THAN(time, 0);
sleep((unsigned long)(time * 1000.0f));
}
int32_t _threadWrappedCallback(thread_t *thread) {
int32_t response;
ASSERT_NOT_NULL(thread);
thread->state |= THREAD_FLAG_RUNNING;
thread->state = flagOff(thread->state, THREAD_FLAG_QUEUED);
response = thread->call(thread);
thread->state |= THREAD_FLAG_HAS_RUN;
thread->state = flagOff(thread->state, THREAD_FLAG_RUNNING);
return response;
}

View File

@ -1,73 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "../assert/assert.h"
#include "../util/flags.h"
typedef struct _thread_t thread_t;
#define THREAD_FLAG_RUNNING flagDefine(0)
#define THREAD_FLAG_QUEUED flagDefine(1)
#define THREAD_FLAG_HAS_RUN flagDefine(2)
/**
* Thread function itself.
*
* @param thread Thread that was called.
* @return The exit code, try to ensure only 0 is possible.
*/
typedef int32_t threadfunction_t(thread_t *thread);
typedef struct _thread_t {
threadhandle_t pt;
void *user;
uint8_t state;
threadfunction_t *call;
} thread_t;
/**
* Initialize a thread, prepare it to be started. You need to manually start it
* yourself.
*
* @param thread Thread pointer to maintain.
* @param call User callback to fire when the thread is started.
*/
void threadInit(thread_t *thread, threadfunction_t *call);
/**
* Start a previously prepared thread.
*
* @param thread Thread to start.
*/
void threadStart(thread_t *thread);
/**
* Wait for the given thread to finish execution.
*
* @param thread Thread to join.
*/
void threadJoin(thread_t *thread);
/**
* Cancel a running thread, avoid using where possible incase of any undefined
* behaviour.
*
* @param thread Thread to cancel.
*/
void threadCancel(thread_t *thread);
/**
* Sleep the current thread.
*
* @param time Time in seconds to sleep for.
*/
void threadSleep(float time);
/** Managing function for thread to help update the state */
int32_t _threadWrappedCallback(thread_t *thread);

View File

@ -1,10 +0,0 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${PROJECT_NAME}
PRIVATE
epoch.c
)

Some files were not shown because too many files have changed in this diff Show More