Compare commits

...

11 Commits

47 changed files with 830 additions and 192 deletions

View File

@ -7,17 +7,21 @@
"${workspaceFolder}/src", "${workspaceFolder}/src",
"${workspaceFolder}/src/components", "${workspaceFolder}/src/components",
"${workspaceFolder}/core", "${workspaceFolder}/core",
"${workspaceFolder}/core/host/generic", "${workspaceFolder}/core/host/linux",
"/usr/include/lua5.4", "/usr/include/lua5.4",
"/usr/include/pipewire-0.3", "/usr/include/pipewire-0.3",
"/usr/include/spa-0.2", "/usr/include/spa-0.2",
"/usr/include/libdrm", "/usr/include/libdrm",
"/usr/include/libdecor-0", "/usr/include/libdecor-0",
"/usr/include/x86_64-linux-gnu" "/usr/include/x86_64-linux-gnu"//,
// "${env:HOME}/.local/share/fxsdk/sysroot/sh3eb-elf/include"
], ],
"compilerPath": "/usr/bin/gcc", "compilerPath": "/usr/bin/gcc",
"defines": [ "defines": [
"-D_REENTRANT" "_REENTRANT",
"FXCG50",
"TARGET_FXCG50",
"ASSET_FILE_NAME=\"game.data\""
], ],
"cStandard": "c17", "cStandard": "c17",
"browse": { "browse": {

View File

@ -4,6 +4,15 @@ SHELL = /usr/bin/env bash
ROOT := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) ROOT := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
# Import config
ifeq ($(filter clean-all,$(MAKECMDGOALS)),)
ifneq ($(realpath $(ROOT)/config.mk), $(ROOT)/config.mk)
$(error ERROR: Please run the configure script before building)
endif
include $(ROOT)/config.mk
endif
# #
# User settings # User settings
# #
@ -17,7 +26,6 @@ ASSET_BUILDER_DIR = asset_builder
OUTPUT = 2D_Engine OUTPUT = 2D_Engine
ASSET_OUTPUT = game.data ASSET_OUTPUT = game.data
ASSET_BUILDER_OUTPUT = asset_builder/asset_builder
ifneq ($(DEBUG),) ifneq ($(DEBUG),)
TARGET_HOST_CFLAGS += -O1 -g -DDEBUG=$(DEBUG) -Wextra -Wall --pedantic -Wno-missing-braces \ TARGET_HOST_CFLAGS += -O1 -g -DDEBUG=$(DEBUG) -Wextra -Wall --pedantic -Wno-missing-braces \
@ -39,15 +47,6 @@ endif
# End # End
# #
# Import config
ifeq ($(filter clean-all,$(MAKECMDGOALS)),)
ifneq ($(realpath $(ROOT)/config.mk), $(ROOT)/config.mk)
$(error ERROR: Please run the configure script before building)
endif
include $(ROOT)/config.mk
endif
# Relocate vars # Relocate vars
BUILD_DIR := $(ROOT)/$(BUILD_DIR)/$(TARGET_HOST) BUILD_DIR := $(ROOT)/$(BUILD_DIR)/$(TARGET_HOST)
@ -56,10 +55,10 @@ CORE_DIR := $(ROOT)/$(CORE_DIR)
ASSETS_DIR := $(ROOT)/$(ASSETS_DIR) ASSETS_DIR := $(ROOT)/$(ASSETS_DIR)
ASSET_BUILDER_DIR := $(ROOT)/$(ASSET_BUILDER_DIR) ASSET_BUILDER_DIR := $(ROOT)/$(ASSET_BUILDER_DIR)
OUTPUT := $(BUILD_DIR)/$(OUTPUT) OUTPUT := $(BUILD_DIR)/$(OUTPUT)$(OUTPUT_EXT)
LIBCORE := $(BUILD_DIR)/$(LIBCORE) LIBCORE := $(BUILD_DIR)/libcore$(STATIC_LIB_OUTPUT_EXT)
ASSET_OUTPUT := $(BUILD_DIR)/$(ASSET_OUTPUT) ASSET_OUTPUT := $(BUILD_DIR)/$(ASSET_OUTPUT)
ASSET_BUILDER_OUTPUT := $(BUILD_DIR)/$(ASSET_BUILDER_OUTPUT) ASSET_BUILDER_OUTPUT := $(BUILD_DIR)/asset_builder/asset_builder$(OUTPUT_EXT)
# Verbosity # Verbosity
export Q := @ export Q := @
@ -83,7 +82,6 @@ $(ASSET_OUTPUT): FORCE
FORCE: FORCE:
.PHONY: clean clean-all run print-var-%
clean: clean:
$(Q)rm -rf $(BUILD_DIR) $(Q)rm -rf $(BUILD_DIR)
@ -95,3 +93,5 @@ run: all
print-var-% : print-var-% :
@echo $($*) @echo $($*)
.PHONY: clean clean-all run print-var-%

View File

@ -17,14 +17,14 @@ endif
$(ASSET_BUILDER_OUTPUT): $(OBJECTS) $(ASSET_BUILDER_OUTPUT): $(OBJECTS)
$(Q)mkdir -p $(dir $@) $(Q)mkdir -p $(dir $@)
@echo $(ECHO_OPTION) "[100%] $(YELLOW)Linking $(notdir $(ASSET_BUILDER_OUTPUT))$(RESET)"
$(Q)$(HOST_CC) $(ASSET_BUILDER_CFLAGS) $(OBJECTS) -o $@ $(ASSET_BUILDER_LDFLAGS) $(Q)$(HOST_CC) $(ASSET_BUILDER_CFLAGS) $(OBJECTS) -o $@ $(ASSET_BUILDER_LDFLAGS)
@echo "[100%] $(YELLOW)Linking $(notdir $(ASSET_BUILDER_OUTPUT))$(RESET)"
$(BUILD_DIR)/$(notdir $(ASSET_BUILDER_DIR))/%.o: $(ASSET_BUILDER_DIR)/% $(BUILD_DIR)/$(notdir $(ASSET_BUILDER_DIR))/%.o: $(ASSET_BUILDER_DIR)/%
$(Q)mkdir -p $(dir $@) $(Q)mkdir -p $(dir $@)
$(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE)+1)))) $(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE)+1))))
$(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE)*100/$(TOTAL_BUILD_FILES))))) $(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE)*100/$(TOTAL_BUILD_FILES)))))
@echo $(ECHO_OPTION) "[$(PERCENTAGE)%] $(GREEN)Building C object $@$(RESET)"
$(Q)$(HOST_CC) $(ASSET_BUILDER_CFLAGS) $(INCLUDES:%=-I%) -MMD -MP -c $< -o $@ $(Q)$(HOST_CC) $(ASSET_BUILDER_CFLAGS) $(INCLUDES:%=-I%) -MMD -MP -c $< -o $@
@echo "[$(PERCENTAGE)%] $(GREEN)Building C object $@$(RESET)"
-include $(ASSET_BUILDER_OBJECTS:.o=.d) -include $(ASSET_BUILDER_OBJECTS:.o=.d)

View File

@ -19,14 +19,14 @@ TOTAL_BUILD_FILES := $(shell echo $$(($$($(MAKE) -n $(OBJECTS) TOTAL_BUILD_FILES
endif endif
$(ASSET_OUTPUT): $(OBJECTS) $(ASSET_BUILDER_OUTPUT) $(ASSET_OUTPUT): $(OBJECTS) $(ASSET_BUILDER_OUTPUT)
@echo "[100%] $(YELLOW)Building $(notdir $(ASSET_OUTPUT))$(RESET)" @echo $(ECHO_OPTION) "[100%] $(YELLOW)Building $(notdir $(ASSET_OUTPUT))$(RESET)"
$(Q)$(ASSET_BUILDER_OUTPUT) $@ $(OBJECTS) $(Q)$(ASSET_BUILDER_OUTPUT) $@ $(OBJECTS)
$(BUILD_DIR)/$(notdir $(ASSETS_DIR))/%.o: $(ASSETS_DIR)/% $(ASSET_BUILDER_OUTPUT) $(BUILD_DIR)/$(notdir $(ASSETS_DIR))/%.o: $(ASSETS_DIR)/% $(ASSET_BUILDER_OUTPUT)
$(Q)mkdir -p $(dir $@) $(Q)mkdir -p $(dir $@)
$(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE) + 1)))) $(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE) + 1))))
$(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE) * 100 / $(TOTAL_BUILD_FILES))))) $(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE) * 100 / $(TOTAL_BUILD_FILES)))))
@echo "[$(PERCENTAGE)%] $(GREEN)Building ASSET object $@$(RESET)" @echo $(ECHO_OPTION) "[$(PERCENTAGE)%] $(GREEN)Building ASSET object $@$(RESET)"
$(Q)$(ASSET_BUILDER_OUTPUT) $@ -c $< $(Q)$(ASSET_BUILDER_OUTPUT) $@ -c $<
$(ASSET_BUILDER_OUTPUT): FORCE $(ASSET_BUILDER_OUTPUT): FORCE

259
configure vendored
View File

@ -7,26 +7,25 @@
# #
# #
# Project settings no matter current and target hosts # Project settings
# #
CONFIG_FILE="config.mk" CONFIG_FILE="config.mk"
#LUA_VERSION="5.5.1"
#LUA_CHECKSUM="1c4b4068d67061f2a2231ad2b5422e77acea1487ea9890f6320af614f4373dce"
# #
# Main # Main
# #
print_error() set -e
exit_error_message()
{ {
echo -e "\033[31merror\033[m: $1" echo -e "\033[31merror\033[m: $1"
exit 0 exit 0
} }
## Parse args ## Parse args
CURRENT_HOST="guess" HOST="guess"
TARGET_HOST="guess" TARGET_HOST="guess"
for i in "$@"; do for i in "$@"; do
@ -35,19 +34,23 @@ for i in "$@"; do
TARGET_HOST="${i#*=}" TARGET_HOST="${i#*=}"
shift shift
;; ;;
--current-host=*) --current-host=*)
CURRENT_HOST="${i#*=}" HOST="${i#*=}"
shift shift
;; ;;
--clean) --clean)
CLEAN=1 CLEAN=1
EXIT_AFTER_CLEAN=1 EXIT_AFTER_CLEAN=1
shift shift
;; ;;
--reconfigure) --reconfigure)
CLEAN=1 CLEAN=1
shift shift
;; ;;
-h|--help) -h|--help)
echo "Usage : ./configure [OPTION]..." echo "Usage : ./configure [OPTION]..."
echo "Add submodules depending on target host platform and" echo "Add submodules depending on target host platform and"
@ -67,9 +70,11 @@ for i in "$@"; do
echo -e "\tshow help and exit" echo -e "\tshow help and exit"
exit 0 exit 0
;; ;;
-*) -*)
print_error "Unknown option $i" exit_error_message "Unknown option $i"
;; ;;
*) *)
;; ;;
esac esac
@ -86,81 +91,209 @@ if [ -n "${EXIT_AFTER_CLEAN}" ]; then
fi fi
## Deduce current and target hosts ## Deduce current and target hosts
if [ "${CURRENT_HOST}" = "guess" ]; then if [ "${HOST}" = "guess" ]; then
case "${OSTYPE}" in case "${OSTYPE}" in
linux*) linux*)
CURRENT_HOST="linux" HOST="linux"
;;
msys*|cygwin*)
HOST="windows"
;; ;;
# msys*|cygwin*)
# CURRENT_HOST="windows"
# ;;
# darwin*) # darwin*)
# CURRENT_HOST="macos" # HOST="macos"
# ;; # ;;
*) *)
print_error "Current detected os is unsuppoted to build from: ${OSTYPE}\nUse --help for more informations." exit_error_message "Current detected os is unsuppoted to build from: ${OSTYPE}\nUse --help for more informations."
;; ;;
esac esac
fi fi
echo "Configuring for current host: ${CURRENT_HOST}" echo "Configuring for host: ${HOST}"
# If target host is guess then configure for host
if [ "${TARGET_HOST}" = "guess" ]; then if [ "${TARGET_HOST}" = "guess" ]; then
TARGET_HOST=${CURRENT_HOST} TARGET_HOST=${HOST}
fi fi
case "${CURRENT_HOST}" in # Set host compiler and asset builder flags
case "${HOST}" in
linux) linux)
HOST_CC="gcc" HOST_CC=gcc
HOST_AR="ar" HOST_PKG_CONFIG=pkg-config
ASSET_BUILDER_CFLAGS="--std=c17 -O2 \$(shell pkg-config --cflags libpng json-c)" ASSET_BUILDER_CFLAGS=(
ASSET_BUILDER_LDFLAGS="\$(shell pkg-config --libs libpng json-c)" "--std=c17"
"-O2"
)
ASSET_BUILDER_LDFLAGS=()
ASSET_BUILDER_LIBS=(
"libpng|1.6.34"
"json-c|0.11"
)
;;
windows)
HOST_CC=x86_64-w64-mingw32-gcc
HOST_PKG_CONFIG=x86_64-w64-mingw32-pkg-config
ASSET_BUILDER_CFLAGS=(
"--std=c17" "-O2"
)
ASSET_BUILDER_LDFLAGS=()
ASSET_BUILDER_LIBS=(
"libpng|1.6.34"
"json-c|0.11"
)
;; ;;
*) *)
print_error "Compiling from ${CURRENT_HOST} is not supported yet." exit_error_message "Compiling from ${HOST} is not supported yet."
;; ;;
esac esac
# Set target host compiler, outputs extensions and flags
case "${TARGET_HOST}" in case "${TARGET_HOST}" in
linux) linux)
echo "Configuring for target: ${TARGET_HOST}" echo "Configuring for target: ${TARGET_HOST}"
case "${CURRENT_HOST}" in case "${HOST}" in
linux) linux)
TARGET_HOST_CC="gcc" TARGET_HOST_CC=gcc
TARGET_HOST_AR="ar" TARGET_HOST_AR=ar
TARGET_HOST_CFLAGS="--std=c17 -Os -DASSET_FILE_NAME=\\\"\$(notdir \$(ASSET_OUTPUT))\\\" -D_GNU_SOURCE=1 \$(shell pkg-config --cflags sdl3 lua)" TARGET_HOST_PKG_CONFIG=pkg-config
TARGET_HOST_LDFLAGS="\$(shell pkg-config --libs sdl3 lua) -lm" TARGET_HOST_CFLAGS=(
TARGET_HOST_LIBCORE="libcore.a" "--std=c17" "-Os"
"-DASSET_FILE_NAME=\\\"\$(notdir \$(ASSET_OUTPUT))\\\""
)
TARGET_HOST_LDFLAGS=(
"-lm"
)
OUTPUT_EXT=""
DYNAMIC_LIB_OUTPUT_EXT=".so"
STATIC_LIB_OUTPUT_EXT=".a"
;; ;;
*) *)
print_error "Cross compiling from ${CURRENT_HOST} for ${TARGET_HOST} is not supported yet." exit_error_message "Cross compiling from ${HOST} for ${TARGET_HOST} is not supported yet."
;; ;;
esac esac
TARGET_HOST_LIBS=(
"sdl3|3.2.10"
)
;;
windows)
echo "Configuring for target: ${TARGET_HOST}"
case "${HOST}" in
windows|linux)
TARGET_HOST_CC=x86_64-w64-mingw32-gcc
TARGET_HOST_AR=x86_64-w64-mingw32-gcc-ar
TARGET_HOST_PKG_CONFIG=x86_64-w64-mingw32-pkg-config
TARGET_HOST_CFLAGS=(
"--std=c17" "-Os"
"-DASSET_FILE_NAME=\\\"\$(notdir \$(ASSET_OUTPUT))\\\"" "-D_GNU_SOURCE=1"
)
TARGET_HOST_LDFLAGS=()
OUTPUT_EXT=".exe"
DYNAMIC_LIB_OUTPUT_EXT=".dll"
STATIC_LIB_OUTPUT_EXT=".dll.a"
;;
*)
exit_error_message "Cross compiling from ${HOST} for ${TARGET_HOST} is not supported yet."
;;
esac
TARGET_HOST_LIBS=(
"sdl3|3.3.4"
)
;; ;;
fxcg50) fxcg50)
echo "Configuring for target: ${TARGET_HOST}" echo "Configuring for target: ${TARGET_HOST}"
case "${CURRENT_HOST}" in case "${HOST}" in
linux) linux)
TARGET_HOST_CC="sh-elf-gcc" TARGET_HOST_CC=sh-elf-gcc
TARGET_HOST_AR="sh-elf-ar" TARGET_HOST_AR=sh-elf-ar
TARGET_HOST_CFLAGS="--std=c17 -Os" TARGET_HOST_CFLAGS=(
TARGET_HOST_LDFLAGS="" "--std=c17" "-Os"
TARGET_HOST_LIBCORE="libcore.a" "-DASSET_FILE_NAME=\\\"\$(notdir \$(ASSET_OUTPUT))\\\"" "-DFXCG50" "-DTARGET_FXCG50"
"-mb" "-m4-nofpu"
"-ffreestanding" "-nostdlib" "-fstrict-volatile-bitfields"
)
TARGET_HOST_LDFLAGS="-T fxcg50.ld"
OUTPUT_EXT=""
DYNAMIC_LIB_OUTPUT_EXT=".so"
STATIC_LIB_OUTPUT_EXT=".a"
;; ;;
*) *)
print_error "Cross compiling from ${CURRENT_HOST} for ${TARGET_HOST} is not supported yet." exit_error_message "Cross compiling from ${HOST} for ${TARGET_HOST} is not supported yet."
;; ;;
esac esac
;; ;;
*) *)
print_error "Unsupported target host: ${TARGET_HOST}" exit_error_message "Unsupported target host: ${TARGET_HOST}"
esac esac
echo "Writing config file." #
# Checks
#
echo echo
echo "Checking host compiler \"${HOST_CC}\"."
if ${HOST_CC} --version &> /dev/null; then
echo " ${HOST_CC} OK."
else
exit_error_message "Compiler not working."
fi
echo "Checking asset builder libs."
for LIB in ${ASSET_BUILDER_LIBS[@]}; do
LIB_NAME="$(echo ${LIB} | cut -d "|" -f 1)"
LIB_MIN_VERSION="$(echo ${LIB} | cut -d "|" -f 2)"
if ${HOST_PKG_CONFIG} --atleast-version "${LIB_MIN_VERSION}" "${LIB_NAME}"; then
echo " ${LIB_NAME} OK."
else
exit_error_message "Library ${LIB_NAME} version >= ${LIB_MIN_VERSION} not found."
fi
done
echo "Checking target host compiler \"${TARGET_HOST_CC}\"."
if ${TARGET_HOST_CC} --version &> /dev/null; then
echo " ${TARGET_HOST_CC} OK."
else
exit_error_message "Compiler not working."
fi
echo "Checking target host archiver \"${TARGET_HOST_AR}\"."
if ${TARGET_HOST_AR} --version &> /dev/null; then
echo " ${TARGET_HOST_AR} OK."
else
exit_error_message "Compiler not working."
fi
echo "Checking target host libs."
for LIB in ${TARGET_HOST_LIBS[@]}; do
LIB_NAME="$(echo ${LIB} | cut -d "|" -f 1)"
LIB_MIN_VERSION="$(echo ${LIB} | cut -d "|" -f 2)"
if ${TARGET_HOST_PKG_CONFIG} --atleast-version "${LIB_MIN_VERSION}" "${LIB_NAME}"; then
echo " ${LIB_NAME} OK."
else
exit_error_message "Library ${LIB_NAME} version >= ${LIB_MIN_VERSION} not found."
fi
done
#
# Config file
#
echo
echo "Writing config file."
echo "${CONFIG_FILE}:" echo "${CONFIG_FILE}:"
echo "\`\`\`" echo "\`\`\`"
@ -168,43 +301,29 @@ tee "${CONFIG_FILE}" <<EOF
# This file was generated by the configure script. # This file was generated by the configure script.
TARGET_HOST = ${TARGET_HOST} TARGET_HOST = ${TARGET_HOST}
LIBCORE = ${TARGET_HOST_LIBCORE}
OUTPUT_EXT = ${OUTPUT_EXT}
DYNAMIC_LIB_OUTPUT_EXT = ${DYNAMIC_LIB_OUTPUT_EXT}
STATIC_LIB_OUTPUT_EXT = ${STATIC_LIB_OUTPUT_EXT}
TARGET_HOST_CC = ${TARGET_HOST_CC} TARGET_HOST_CC = ${TARGET_HOST_CC}
TARGET_HOST_AR = ${TARGET_HOST_AR} TARGET_HOST_AR = ${TARGET_HOST_AR}
TARGET_HOST_CFLAGS = ${TARGET_HOST_CFLAGS}
TARGET_HOST_LDFLAGS = ${TARGET_HOST_LDFLAGS} TARGET_HOST_CFLAGS = ${TARGET_HOST_CFLAGS[@]} $(${TARGET_HOST_PKG_CONFIG} --cflags $(echo ${TARGET_HOST_LIBS[@]} | tr " " "\n" | cut -d "|" -f 1))
TARGET_HOST_LDFLAGS = ${TARGET_HOST_LDFLAGS[@]} $(${TARGET_HOST_PKG_CONFIG} --libs $(echo ${TARGET_HOST_LIBS[@]} | tr " " "\n" | cut -d "|" -f 1))
HOST_CC = ${HOST_CC} HOST_CC = ${HOST_CC}
ASSET_BUILDER_CFLAGS = ${ASSET_BUILDER_CFLAGS} ASSET_BUILDER_CFLAGS = ${ASSET_BUILDER_CFLAGS[@]} $(${HOST_PKG_CONFIG} --cflags $(echo ${ASSET_BUILDER_LIBS[@]} | tr " " "\n" | cut -d "|" -f 1))
ASSET_BUILDER_LDFLAGS = ${ASSET_BUILDER_LDFLAGS} ASSET_BUILDER_LDFLAGS = ${ASSET_BUILDER_LDFLAGS[@]} $(${HOST_PKG_CONFIG} --libs $(echo ${ASSET_BUILDER_LIBS[@]} | tr " " "\n" | cut -d "|" -f 1))
EOF EOF
if [ "${HOST}" = "windows" ]; then
tee -a "${CONFIG_FILE}" <<EOF
# OS specific options
ECHO_OPTION = -e
EOF
fi
echo "\`\`\`" echo "\`\`\`"
#
### Download libs
#echo "===== downloading lua ====="
#
#LUA_TAR_GZ="${CACHE_DIR}/lua-${LUA_VERSION}.tar.gz"
#if [ ! -e "${LUA_TAR_GZ}" ]; then
# echo "Downloading lua source..."
# if ! curl --output "${LUA_TAR_GZ}" "https://www.lua.org/ftp/lua-${LUA_VERSION}.tar.gz"; then
# print_error "Failed to download lua source."
# fi
#fi
#
#echo "Checking lua source sum..."
#if ! echo "${LUA_CHECKSUM} ${LUA_TAR_GZ}" | sha256sum -c; then
# CHECKSUM="$(sha256sum "${LUA_TAR_GZ}" | cut -d " " -f 1)"
# rm "${LUA_TAR_GZ}"
# print_error "Lua zip checksum not valid.\nExpected: \"${LUA_CHECKSUM}\"\nGot: \"${CHECKSUM}\"\nPlease rerun command to retry downloading."
#fi
#
#echo "Extracting lua source"
#if ! tar -xzf "${LUA_TAR_GZ}" --directory "${LIB_DIR}"; then
# print_error "Failed to extract lua source."
#fi
#

View File

@ -5,7 +5,6 @@ SOURCES += \
event_bus.c \ event_bus.c \
ecs.c \ ecs.c \
asset_manager.c \ asset_manager.c \
inputs.c \
map.c map.c
INCLUDES += \ INCLUDES += \
@ -24,14 +23,14 @@ endif
$(LIBCORE): $(OBJECTS) $(LIBCORE): $(OBJECTS)
$(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE) + 1)))) $(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE) + 1))))
$(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE) * 100 / $(TOTAL_BUILD_FILES))))) $(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE) * 100 / $(TOTAL_BUILD_FILES)))))
@echo "[$(PERCENTAGE)%] $(YELLOW)Creating Static Lib $@$(RESET)" @echo $(ECHO_OPTION) "[$(PERCENTAGE)%] $(YELLOW)Creating Static Lib $@$(RESET)"
$(Q)$(TARGET_HOST_AR) rcs $@ $(OBJECTS) $(Q)$(TARGET_HOST_AR) rcs $@ $(OBJECTS)
$(BUILD_DIR)/$(notdir $(CORE_DIR))/%.o: $(CORE_DIR)/% $(BUILD_DIR)/$(notdir $(CORE_DIR))/%.o: $(CORE_DIR)/%
$(Q)mkdir -p $(dir $@) $(Q)mkdir -p $(dir $@)
$(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE) + 1)))) $(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE) + 1))))
$(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE) * 100 / $(TOTAL_BUILD_FILES))))) $(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE) * 100 / $(TOTAL_BUILD_FILES)))))
@echo "[$(PERCENTAGE)%] $(GREEN)Building C object $@$(RESET)" @echo $(ECHO_OPTION) "[$(PERCENTAGE)%] $(GREEN)Building C object $@$(RESET)"
$(Q)$(TARGET_HOST_CC) $(TARGET_HOST_CFLAGS) $(INCLUDES:%=-I%) -MMD -MP -c $< -o $@ $(Q)$(TARGET_HOST_CC) $(TARGET_HOST_CFLAGS) $(INCLUDES:%=-I%) -MMD -MP -c $< -o $@
-include $(OBJECTS:.o=.d) -include $(OBJECTS:.o=.d)

View File

@ -42,6 +42,14 @@ int destroy_asset(asset_t *asset)
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
// No args
int create_asset_header_def(asset_header_def_t *asset_header_def, va_list args)
{
asset_header_def->name = NULL;
return EXIT_SUCCESS;
}
int destroy_asset_header_def(asset_header_def_t *asset_header_def) int destroy_asset_header_def(asset_header_def_t *asset_header_def)
{ {
free(asset_header_def->name); free(asset_header_def->name);
@ -52,7 +60,7 @@ int destroy_asset_header_def(asset_header_def_t *asset_header_def)
int asset_manager_init(void) int asset_manager_init(void)
{ {
linked_list_init(&game.asset_manager.assets, sizeof(asset_t), (allocator_t)create_asset, (deleter_t)destroy_asset); linked_list_init(&game.asset_manager.assets, sizeof(asset_t), (allocator_t)create_asset, (deleter_t)destroy_asset);
linked_list_init(&game.asset_manager.assets_header_defs, sizeof(asset_header_def_t), NULL, (deleter_t)destroy_asset_header_def); linked_list_init(&game.asset_manager.assets_header_defs, sizeof(asset_header_def_t), (allocator_t)create_asset_header_def, (deleter_t)destroy_asset_header_def);
game.asset_manager.asset_file = fopen(ASSET_FILE_NAME, "rb"); game.asset_manager.asset_file = fopen(ASSET_FILE_NAME, "rb");
if(!game.asset_manager.asset_file) if(!game.asset_manager.asset_file)
@ -64,7 +72,7 @@ int asset_manager_init(void)
uint32_t nb_assets; uint32_t nb_assets;
if(fread(&nb_assets, sizeof(nb_assets), 1, game.asset_manager.asset_file) != 1) if(fread(&nb_assets, sizeof(nb_assets), 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read asset file."); error_printf("Failed to read asset file : %d", ferror(game.asset_manager.asset_file));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -76,17 +84,33 @@ int asset_manager_init(void)
if(!asset_header_def_elem) return_failure_int; if(!asset_header_def_elem) return_failure_int;
asset_header_def_t *asset_header_def = asset_header_def_elem->data; asset_header_def_t *asset_header_def = asset_header_def_elem->data;
size_t cap = 0;
if(getdelim(&asset_header_def->name, &cap, '\0', game.asset_manager.asset_file) == -1)
{ {
error_printf("Failed to read asset file."); size_t name_size = 0;
return EXIT_FAILURE; int ch = EOF;
do
{
name_size++;
asset_header_def->name = realloc(asset_header_def->name, name_size);
ch = fgetc(game.asset_manager.asset_file);
if(ch == EOF)
{
error_printf("Failed to read asset file : %d", ferror(game.asset_manager.asset_file));
return EXIT_FAILURE;
}
asset_header_def->name[name_size - 1] = ch;
}
while(ch != '\0');
asset_header_def->name[name_size] = '\0';
} }
if(fread(&asset_header_def->start, sizeof(asset_header_def->start), 1, game.asset_manager.asset_file) != 1) if(fread(&asset_header_def->start, sizeof(asset_header_def->start), 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read asset file."); error_printf("Failed to read asset file : %d", ferror(game.asset_manager.asset_file));
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@ -29,6 +29,7 @@ typedef struct asset_header_def_t {
uint32_t start; uint32_t start;
} asset_header_def_t; } asset_header_def_t;
int create_asset_header_def(asset_header_def_t *asset_header_def, va_list args);
int destroy_asset_header_def(asset_header_def_t *asset_header_def); int destroy_asset_header_def(asset_header_def_t *asset_header_def);
typedef struct asset_manager_t { typedef struct asset_manager_t {

View File

@ -0,0 +1,5 @@
SOURCES += $(addprefix host/$(TARGET_HOST)/, \
vector2d.c \
inputs.c \
update_time.c \
)

View File

@ -0,0 +1,23 @@
#ifndef DISPLAY_H
#define DISPLAY_H
#include <gint/display.h>
#include "texture.h"
#include "vector2d.h"
#define DISPLAY_WIDTH DWIDTH
#define DISPLAY_HEIGHT DHEIGHT
typedef struct display_t {
} display_t;
int display_init(void);
void display_exit(void);
int display_clear(void);
int display_update(void);
int display_draw_texture(texture_t *texture, const rect_t *src_rect, const rect_t *dst_rect, bool flip);
int display_draw_frect(const frect_t *frect, unsigned int r, unsigned int g, unsigned int b, unsigned int a);
#endif // DISPLAY_H

16
core/host/fxcg50/inputs.c Normal file
View File

@ -0,0 +1,16 @@
#include "inputs.h"
#include <gint/keyboard.h>
inline int poll_event(input_event_t *event)
{
key_event_t gint_event = pollevent();
if(gint_event.type = KEYEV_NONE)
return 0;
event->type = gint_event.type;
event->key = gint_event.key;
return 1;
}

View File

@ -1,16 +1,11 @@
#ifndef KEYBOARD_H #ifndef KEYBOARD_H
#define KEYBOARD_H #define KEYBOARD_H
#include <SDL3/SDL_events.h>
#include "keycodes.h" #include "keycodes.h"
#define INPUT_EVENT_KEY_UP SDL_EVENT_KEY_UP
#define INPUT_EVENT_KEY_DOWN SDL_EVENT_KEY_DOWN
#define INPUT_EVENT_QUIT SDL_EVENT_QUIT
typedef struct input_event_t { typedef struct input_event_t {
uint32_t type; uint32_t type;
SDL_Scancode key; int key;
} input_event_t; } input_event_t;
int poll_event(input_event_t *event); int poll_event(input_event_t *event);

View File

@ -0,0 +1,15 @@
#ifndef KEYCODES_H
#define KEYCODES_H
#include <gint/keyboard.h>
#define MAX_KEYCODES 0xB0
#define KEY_MOD KEY_SHIFT
#define KEY_INTERACT KEY_ALPHA
#define INPUT_EVENT_KEY_UP KEYEV_UP
#define INPUT_EVENT_KEY_DOWN KEYEV_DOWN
#define INPUT_EVENT_QUIT 0xFF
#endif // KEYCODES_H

View File

@ -1,12 +1,14 @@
#ifndef TEXTURE_H #ifndef TEXTURE_H
#define TEXTURE_H #define TEXTURE_H
#include <gint/display.h>
#define TEXTURE_TRANSPARENT_COLOR 0x0001 #define TEXTURE_TRANSPARENT_COLOR 0x0001
typedef struct texture_t texture_t; typedef bopti_image_t texture_t;
#define get_width(T) 1 #define get_width(T) T->width
#define get_height(T) 1 #define get_height(T) T->height
texture_t *load_texture(void); texture_t *load_texture(void);
void destroy_texture(texture_t *texture); void destroy_texture(texture_t *texture);

View File

@ -0,0 +1,13 @@
#include "update_time.h"
#include <time.h>
#include "game.h"
inline void update_time(void)
{
static clock_t last_clock_state = 0;
clock_t start_clock = clock();
game.delta_time_ms = (float)(start_clock - last_clock_state) / (float)CLOCKS_PER_SEC;
if(game.delta_time_ms > 100.0f) game.delta_time_ms = 100.0f;
last_clock_state = start_clock;
}

View File

@ -0,0 +1,6 @@
#ifndef TIME_H
#define TIME_H
void update_time(void);
#endif // TIME_H

View File

@ -1,7 +1,7 @@
#ifndef VECTOR2D_H #ifndef VECTOR2D_H
#define VECTOR2D_H #define VECTOR2D_H
#include <SDL3/SDL_rect.h> #include <stdbool.h>
#include <math.h> #include <math.h>
/** /**

View File

@ -2,4 +2,6 @@ SOURCES += $(addprefix host/$(TARGET_HOST)/, \
display.c \ display.c \
vector2d.c \ vector2d.c \
texture.c \ texture.c \
inputs.c \
update_time.c \
) )

View File

@ -7,6 +7,8 @@
#include "texture.h" #include "texture.h"
#include "errors.h" #include "errors.h"
#define DRIVERS "vulkan,gpu,software"
inline int display_init(void) inline int display_init(void)
{ {
if(!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) if(!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS))
@ -29,13 +31,13 @@ inline int display_init(void)
} }
#ifdef DRIVERS #ifdef DRIVERS
warning_printf("This build of 2D_Engine_C only innitialize for the following drivers : %s", DRIVERS);
debug_printf("Listing available render drivers."); debug_printf("Listing available render drivers.");
const int NB_DRIVERS = SDL_GetNumRenderDrivers(); const int NB_DRIVERS = SDL_GetNumRenderDrivers();
for(int i = 0; i < NB_DRIVERS; i++) for(int i = 0; i < NB_DRIVERS; i++)
debug_printf("%d : %s", i, SDL_GetRenderDriver(i)); debug_printf("%d : %s", i, SDL_GetRenderDriver(i));
warning_printf("This build of 2D_Engine_C only support the following drivers : %s", DRIVERS);
game.display.renderer = SDL_CreateRenderer(game.display.window, DRIVERS); game.display.renderer = SDL_CreateRenderer(game.display.window, DRIVERS);
#else #else
game.display.renderer = SDL_CreateRenderer(game.display.window, NULL); game.display.renderer = SDL_CreateRenderer(game.display.window, NULL);

View File

@ -14,8 +14,6 @@
#define DISPLAY_WIDTH 720 #define DISPLAY_WIDTH 720
#define DISPLAY_HEIGHT 480 #define DISPLAY_HEIGHT 480
#define DRIVERS "vulkan,gpu,software"
typedef struct display_t { typedef struct display_t {
SDL_Window *window; SDL_Window *window;
SDL_Renderer *renderer; SDL_Renderer *renderer;

17
core/host/linux/inputs.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef KEYBOARD_H
#define KEYBOARD_H
#include "keycodes.h"
typedef struct input_event_t {
uint32_t type;
int key;
} input_event_t;
int poll_event(input_event_t *event);
typedef struct inputs_t {
bool keys[MAX_KEYCODES];
} inputs_t;
#endif // KEYBOARD_H

View File

@ -12,4 +12,8 @@
#define KEY_MOD SDL_SCANCODE_LCTRL #define KEY_MOD SDL_SCANCODE_LCTRL
#define KEY_INTERACT SDL_SCANCODE_E #define KEY_INTERACT SDL_SCANCODE_E
#define INPUT_EVENT_KEY_UP SDL_EVENT_KEY_UP
#define INPUT_EVENT_KEY_DOWN SDL_EVENT_KEY_DOWN
#define INPUT_EVENT_QUIT SDL_EVENT_QUIT
#endif // KEYCODES_H #endif // KEYCODES_H

View File

@ -11,13 +11,13 @@ texture_t *load_texture(void)
if(fread(&width, sizeof(width), 1, game.asset_manager.asset_file) != 1) if(fread(&width, sizeof(width), 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file."); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
if(fread(&height, sizeof(height), 1, game.asset_manager.asset_file) != 1) if(fread(&height, sizeof(height), 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file."); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
@ -36,7 +36,7 @@ texture_t *load_texture(void)
if(fread(tmp_surface->pixels, sizeof(uint16_t), width * height, game.asset_manager.asset_file) != (size_t)width * (size_t)height) if(fread(tmp_surface->pixels, sizeof(uint16_t), width * height, game.asset_manager.asset_file) != (size_t)width * (size_t)height)
{ {
error_printf("Failed to read asset file."); error_printf("Failed to read asset file : %d", ferror(game.asset_manager.asset_file));
goto_failure; goto_failure;
} }

View File

@ -7,8 +7,8 @@
typedef SDL_Texture texture_t; typedef SDL_Texture texture_t;
#define get_width(T) T->w #define texture_get_width(T) T->w
#define get_height(T) T->h #define texture_get_height(T) T->h
texture_t *load_texture(void); texture_t *load_texture(void);
void destroy_texture(texture_t *texture); void destroy_texture(texture_t *texture);

View File

@ -0,0 +1,13 @@
#include "update_time.h"
#include <SDL3/SDL.h>
#include "game.h"
inline void update_time(void)
{
static uint64_t last_clock_state = 0;
uint64_t start_clock = SDL_GetTicksNS();
game.delta_time_ms = SDL_NS_TO_MS((float)(start_clock - last_clock_state));
if(game.delta_time_ms > 100.0f) game.delta_time_ms = 100.0f;
last_clock_state = start_clock;
}

View File

@ -0,0 +1,6 @@
#ifndef TIME_H
#define TIME_H
void update_time(void);
#endif // TIME_H

View File

@ -0,0 +1,7 @@
SOURCES += $(addprefix host/$(TARGET_HOST)/, \
display.c \
vector2d.c \
texture.c \
inputs.c \
update_time.c \
)

193
core/host/windows/display.c Normal file
View File

@ -0,0 +1,193 @@
#include "display.h"
#include <SDL3/SDL.h>
#include <stdlib.h>
#include "asset_manager.h"
#include "game.h"
#include "texture.h"
#include "errors.h"
inline int display_init(void)
{
if(!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS))
{
error_printf("Failed to initialise SDL3 : %s", SDL_GetError());
return EXIT_FAILURE;
}
if(!SDL_SetAppMetadata("2D_Engine_SDL3_Core", "1.0", "2D_Engine"))
{
error_printf("Failed to set app metadata : %s", SDL_GetError());
return EXIT_FAILURE;
}
game.display.window = SDL_CreateWindow("2D_Engine", DISPLAY_WIDTH, DISPLAY_HEIGHT, 0);
if(!game.display.window)
{
error_printf("Failed to create window : %s", SDL_GetError());
return EXIT_FAILURE;
}
#ifdef DRIVERS
debug_printf("Listing available render drivers.");
const int NB_DRIVERS = SDL_GetNumRenderDrivers();
for(int i = 0; i < NB_DRIVERS; i++)
debug_printf("%d : %s", i, SDL_GetRenderDriver(i));
warning_printf("This build of 2D_Engine_C only support the following drivers : %s", DRIVERS);
game.display.renderer = SDL_CreateRenderer(game.display.window, DRIVERS);
#else
game.display.renderer = SDL_CreateRenderer(game.display.window, NULL);
#endif // DRIVERS
if(!game.display.renderer)
{
error_printf("Failed to create renderer : %s", SDL_GetError());
return EXIT_FAILURE;
}
/*
if(!SDL_SetRenderVSync(game.display.renderer, SDL_RENDERER_VSYNC_ADAPTIVE))
{
error_printf("Failed to activate adaptative vsync : %s", SDL_GetError());
return EXIT_FAILURE;
}
*/
if(!SDL_SetRenderDrawBlendMode(game.display.renderer, SDL_BLENDMODE_BLEND))
{
error_printf("Failed to set renderer draw blend mode : %s", SDL_GetError());
return EXIT_FAILURE;
}
if(!SDL_SetDefaultTextureScaleMode(game.display.renderer, SDL_SCALEMODE_NEAREST))
{
error_printf("Failed to set default texture scale mode : %s", SDL_GetError());
return EXIT_FAILURE;
}
debug_printf("Initialized display.");
return EXIT_SUCCESS;
}
inline void display_exit(void)
{
if(game.display.renderer) SDL_DestroyRenderer(game.display.renderer);
if(game.display.window) SDL_DestroyWindow(game.display.window);
SDL_Quit();
debug_printf("Exited display.");
}
inline int display_clear(void)
{
if(!SDL_SetRenderDrawColor(game.display.renderer, C_WHITE, 255))
{
error_printf("Failed to change renderer draw color : %s", SDL_GetError());
return EXIT_FAILURE;
}
if(!SDL_RenderClear(game.display.renderer))
{
error_printf("Failed to clear renderer : %s", SDL_GetError());
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
inline int display_update(void)
{
if(!SDL_RenderPresent(game.display.renderer))
{
error_printf("Failed to present renderer : %s", SDL_GetError());
return EXIT_FAILURE;
}
#if DEBUG >= 1
float fps = 1000.0f / game.delta_time_ms;
static float max_fps_10s = 0.0f;
static float low_fps_10s = 10000000.0f;
if(fps > max_fps_10s) max_fps_10s = fps;
if(fps < low_fps_10s) low_fps_10s = fps;
static float fps_update_delta_time = 0.0f;
fps_update_delta_time += game.delta_time_ms;
if(fps_update_delta_time >= 100.0f)
{
fps_update_delta_time = 0.0f;
char title[100];
if(sprintf(title, "2D_Engine | cur: %.2ffps | max: %.2ffps | low: %.2ffps", fps, max_fps_10s, low_fps_10s) == -1)
{
error_printf("Sprintf failed : %d", errno);
return EXIT_FAILURE;
}
if(!SDL_SetWindowTitle(game.display.window, title))
{
error_printf("Failed to set window title : %s", SDL_GetError());
return EXIT_FAILURE;
}
}
static float fps_max_low_update_delta_time = 0.0f;
fps_max_low_update_delta_time += game.delta_time_ms;
if(fps_max_low_update_delta_time > 10000.0f)
{
fps_max_low_update_delta_time = 0.0f;
max_fps_10s = 0.0f;
low_fps_10s = 10000000.0f;
}
#endif // DEBUG >= 1
return EXIT_SUCCESS;
}
int display_draw_texture(texture_t *texture, const rect_t *src_rect, const rect_t *dst_rect, bool flip)
{
frect_t src_frect;
if(src_rect) rect_to_frect(src_rect, &src_frect);
frect_t dst_frect;
if(dst_rect)
dst_frect = (frect_t) {
.x = (dst_rect->x - game.camera.view_rect.x) * (DISPLAY_WIDTH / game.camera.view_rect.w),
.y = (dst_rect->y - game.camera.view_rect.y) * (DISPLAY_HEIGHT / game.camera.view_rect.h),
.w = dst_rect->w * (DISPLAY_WIDTH / game.camera.view_rect.w),
.h = dst_rect->h * (DISPLAY_HEIGHT / game.camera.view_rect.h)
};
if(!SDL_RenderTextureRotated(game.display.renderer, texture, src_rect ? &src_frect : NULL, dst_rect ? &dst_frect : NULL, 0, NULL, flip))
{
error_printf("Failed to copy texture to renderer : %s", SDL_GetError());
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int display_draw_frect(const frect_t *frect, unsigned int r, unsigned int g, unsigned int b, unsigned int a)
{
if(!SDL_SetRenderDrawColor(game.display.renderer, r, g, b, a))
{
error_printf("Failed to change renderer draw color : %s", SDL_GetError());
return EXIT_FAILURE;
}
frect_t display_frect = {
.x = (frect->x - game.camera.view_rect.x) * (DISPLAY_WIDTH / game.camera.view_rect.w),
.y = (frect->y - game.camera.view_rect.y) * (DISPLAY_HEIGHT / game.camera.view_rect.h),
.w = frect->w * (DISPLAY_WIDTH / game.camera.view_rect.w),
.h = frect->h * (DISPLAY_HEIGHT / game.camera.view_rect.h)
};
if(!SDL_RenderRect(game.display.renderer, &display_frect))
{
error_printf("Failed to draw rectangle to renderer : %s", SDL_GetError());
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View File

@ -1,6 +1,7 @@
#ifndef DISPLAY_H #ifndef DISPLAY_H
#define DISPLAY_H #define DISPLAY_H
#include <SDL3/SDL_render.h>
#include "texture.h" #include "texture.h"
#include "vector2d.h" #include "vector2d.h"
@ -13,10 +14,9 @@
#define DISPLAY_WIDTH 720 #define DISPLAY_WIDTH 720
#define DISPLAY_HEIGHT 480 #define DISPLAY_HEIGHT 480
//#define DRIVERS NULL
#define DRIVERS "vulkan,gpu,software"
typedef struct display_t { typedef struct display_t {
SDL_Window *window;
SDL_Renderer *renderer;
} display_t; } display_t;
int display_init(void); int display_init(void);
@ -28,4 +28,4 @@ int display_update(void);
int display_draw_texture(texture_t *texture, const rect_t *src_rect, const rect_t *dst_rect, bool flip); int display_draw_texture(texture_t *texture, const rect_t *src_rect, const rect_t *dst_rect, bool flip);
int display_draw_frect(const frect_t *frect, unsigned int r, unsigned int g, unsigned int b, unsigned int a); int display_draw_frect(const frect_t *frect, unsigned int r, unsigned int g, unsigned int b, unsigned int a);
#endif // DISPLAY_H #endif // DISPLAY_H

View File

@ -0,0 +1,14 @@
#include "inputs.h"
#include <SDL3/SDL_events.h>
inline int poll_event(input_event_t *event)
{
SDL_Event sdl_event;
int ret = SDL_PollEvent(&sdl_event);
event->type = sdl_event.type;
event->key = sdl_event.key.scancode;
return ret;
}

View File

@ -0,0 +1,17 @@
#ifndef KEYBOARD_H
#define KEYBOARD_H
#include "keycodes.h"
typedef struct input_event_t {
uint32_t type;
int key;
} input_event_t;
int poll_event(input_event_t *event);
typedef struct inputs_t {
bool keys[MAX_KEYCODES];
} inputs_t;
#endif // KEYBOARD_H

View File

@ -0,0 +1,19 @@
#ifndef KEYCODES_H
#define KEYCODES_H
#include <SDL3/SDL_events.h>
#define MAX_KEYCODES SDL_SCANCODE_COUNT
#define KEY_UP SDL_SCANCODE_W
#define KEY_DOWN SDL_SCANCODE_S
#define KEY_LEFT SDL_SCANCODE_A
#define KEY_RIGHT SDL_SCANCODE_D
#define KEY_MOD SDL_SCANCODE_LCTRL
#define KEY_INTERACT SDL_SCANCODE_E
#define INPUT_EVENT_KEY_UP SDL_EVENT_KEY_UP
#define INPUT_EVENT_KEY_DOWN SDL_EVENT_KEY_DOWN
#define INPUT_EVENT_QUIT SDL_EVENT_QUIT
#endif // KEYCODES_H

View File

@ -0,0 +1,6 @@
#ifndef MEMORY_ALLOC_H
#define MEMORY_ALLOC_H
#include <stdlib.h>
#endif // MEMORY_ALLOC_H

View File

@ -0,0 +1,67 @@
#include "texture.h"
#include "asset_manager.h"
#include "game.h"
#include "display.h"
#include "errors.h"
texture_t *load_texture(void)
{
uint16_t width, height;
if(fread(&width, sizeof(width), 1, game.asset_manager.asset_file) != 1)
{
error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL;
}
if(fread(&height, sizeof(height), 1, game.asset_manager.asset_file) != 1)
{
error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL;
}
SDL_Surface *tmp_surface = SDL_CreateSurface(width, height, SDL_PIXELFORMAT_RGB565);
if(!tmp_surface)
{
error_printf("Failed to create temporary surface : %s", SDL_GetError());
return NULL;
}
if(!SDL_LockSurface(tmp_surface))
{
error_printf("Failed to lock temporary surface : %s", SDL_GetError());
goto_failure;
}
if(fread(tmp_surface->pixels, sizeof(uint16_t), width * height, game.asset_manager.asset_file) != (size_t)width * (size_t)height)
{
error_printf("Failed to read asset file : %d", ferror(game.asset_manager.asset_file));
goto_failure;
}
if(!SDL_SetSurfaceColorKey(tmp_surface, true, TEXTURE_TRANSPARENT_COLOR))
{
error_printf("Failed to set color key of temporary surface : %s", SDL_GetError());
goto_failure;
}
texture_t *texture = SDL_CreateTextureFromSurface(game.display.renderer, tmp_surface);
if(!texture)
{
error_printf("Failed to create texture from temporary surface : %s", SDL_GetError());
goto_failure;
}
SDL_DestroySurface(tmp_surface);
return texture;
failure:
SDL_DestroySurface(tmp_surface);
return NULL;
}
void destroy_texture(texture_t *texture)
{
SDL_DestroyTexture(texture);
}

View File

@ -0,0 +1,16 @@
#ifndef TEXTURE_H
#define TEXTURE_H
#include <SDL3/SDL_render.h>
#define TEXTURE_TRANSPARENT_COLOR 0x0001
typedef SDL_Texture texture_t;
#define texture_get_width(T) T->w
#define texture_get_height(T) T->h
texture_t *load_texture(void);
void destroy_texture(texture_t *texture);
#endif // TEXTURE_H

View File

@ -0,0 +1,13 @@
#include "update_time.h"
#include <SDL3/SDL.h>
#include "game.h"
inline void update_time(void)
{
static uint64_t last_clock_state = 0;
uint64_t start_clock = SDL_GetTicksNS();
game.delta_time_ms = SDL_NS_TO_MS((float)(start_clock - last_clock_state));
if(game.delta_time_ms > 100.0f) game.delta_time_ms = 100.0f;
last_clock_state = start_clock;
}

View File

@ -0,0 +1,6 @@
#ifndef TIME_H
#define TIME_H
void update_time(void);
#endif // TIME_H

View File

@ -0,0 +1,19 @@
#include "vector2d.h"
void frect_to_rect(const frect_t *frect, rect_t *rect)
{
rect->x = (int)frect->x;
rect->y = (int)frect->y;
rect->w = (int)frect->w;
rect->h = (int)frect->h;
}
inline float lerp(float a, float b, float s)
{
return a * (1 - s) + b * s;
}
inline float lerp_time(float a, float b, float s, float t)
{
return lerp(a, b, 1 - powf(1 - s, t * 60.0f));
}

View File

@ -10,9 +10,7 @@
* @param x X pos * @param x X pos
* @param y Y pos * @param y Y pos
*/ */
typedef struct vector2d_t { typedef SDL_Point vector2d_t;
int x, y;
} vector2d_t;
/** /**
* @brief Point struct. (float) * @brief Point struct. (float)
@ -20,9 +18,7 @@ typedef struct vector2d_t {
* @param x X pos * @param x X pos
* @param y Y pos * @param y Y pos
*/ */
typedef struct fvector2d_t { typedef SDL_FPoint fvector2d_t;
float x, y;
} fvector2d_t;
/** /**
* @brief Rectangle struct. (int) * @brief Rectangle struct. (int)
@ -32,10 +28,7 @@ typedef struct fvector2d_t {
* @param w Width * @param w Width
* @param h Height * @param h Height
*/ */
typedef struct rect_t { typedef SDL_Rect rect_t;
int x, y;
int w, h;
} rect_t;
/** /**
* @brief Rectangle struct. (float) * @brief Rectangle struct. (float)
@ -45,10 +38,7 @@ typedef struct rect_t {
* @param w Width * @param w Width
* @param h Height * @param h Height
*/ */
typedef struct frect_t { typedef SDL_FRect frect_t;
float x, y;
float w, h;
} frect_t;
#define EPSILON 0.0f #define EPSILON 0.0f
@ -56,47 +46,47 @@ typedef struct frect_t {
#define f_is_not_zero(X) (fabsf(X) > EPSILON) #define f_is_not_zero(X) (fabsf(X) > EPSILON)
void rect_to_frect(const rect_t *rect, frect_t *frect); #define rect_to_frect(R, FR) SDL_RectToFRect(R, FR)
void frect_to_rect(const frect_t *frect, rect_t *rect); void frect_to_rect(const frect_t *frect, rect_t *rect);
/** /**
* @brief Verify if a point is in a rectangle. (int) * @brief Verify if a point is in a rectangle. (int)
* *
* @param p Vector2d * @param P Vector2d
* @param r Rectangle * @param R Rectangle
* *
* @return True if the point is in the rectangle, else false. * @return True if the point is in the rectangle, else false.
*/ */
bool point_in_rect(const vector2d_t *p, const rect_t *r); #define point_in_rect(P, R) SDL_PointInRect(P, R)
/** /**
* @brief Verify if a point is in a rectangle. (float) * @brief Verify if a point is in a rectangle. (float)
* *
* @param p Vector2d * @param P Vector2d
* @param r Rectangle * @param R Rectangle
* *
* @return True if the point is in the rectangle, else false. * @return True if the point is in the rectangle, else false.
*/ */
bool fpoint_in_rect(const fvector2d_t *p, const frect_t *r); #define fpoint_in_frect(P, R) SDL_PointInRectF(P, R)
/** /**
* @brief Verify if a rectangle is empty * @brief Verify if a rectangle is empty
* *
* @param r Rectangle * @param R Rectangle
* *
* @return True if the rectangle is empty, else false. * @return True if the rectangle is empty, else false.
*/ */
bool rect_empty(const rect_t *r); #define rect_empty(R) SDL_RectEmpty(R)
/** /**
* @brief Verify if a rectangle is empty * @brief Verify if a rectangle is empty
* *
* @param r Rectangle * @param R Rectangle
* *
* @return True if the rectangle is empty, else false. * @return True if the rectangle is empty, else false.
*/ */
bool frect_empty(const frect_t *r); #define frect_empty(R) SDL_FRectEmpty(R)
/** /**
* @brief Verify if there is a intersction between two rectangles. (int) * @brief Verify if there is a intersction between two rectangles. (int)
@ -106,7 +96,7 @@ bool frect_empty(const frect_t *r);
* *
* @return True if there is an intersection, else false. * @return True if there is an intersection, else false.
*/ */
bool has_intersection(const rect_t *a, const rect_t *b); #define has_intersection(A, B) SDL_HasRectIntersection(A, B)
/** /**
* @brief Verify if there is a intersction between two rectangles. (float) * @brief Verify if there is a intersction between two rectangles. (float)
@ -116,7 +106,7 @@ bool has_intersection(const rect_t *a, const rect_t *b);
* *
* @return True if there is an intersection, else false. * @return True if there is an intersection, else false.
*/ */
bool fhas_intersection(const frect_t *a, const frect_t *b); #define fhas_intersection(A, B) SDL_HasRectIntersectionFloat(A, B)
/** /**
* @brief Verify if there is an intersection between two rectangles and get the intersection rectangle. (int) * @brief Verify if there is an intersection between two rectangles and get the intersection rectangle. (int)
@ -127,7 +117,7 @@ bool fhas_intersection(const frect_t *a, const frect_t *b);
* *
* @return True if there is an intersection, else false. * @return True if there is an intersection, else false.
*/ */
bool intersect_rect(const rect_t *a, const rect_t *b, rect_t *result); #define intersect_rect(A, B, result) SDL_GetRectIntersection(A, B, result)
/** /**
* @brief Verify if there is an intersection between two rectangles and get the intersection rectangle. (float) * @brief Verify if there is an intersection between two rectangles and get the intersection rectangle. (float)
@ -138,7 +128,7 @@ bool intersect_rect(const rect_t *a, const rect_t *b, rect_t *result);
* *
* @return True if there is an intersection, else false. * @return True if there is an intersection, else false.
*/ */
bool intersect_frect(const frect_t *a, const frect_t *b, frect_t *result); #define intersect_frect(A, B, result) SDL_GetRectIntersectionFloat(A, B, result)
/** /**
* @brief Lerp a to b with smoothing factor s. * @brief Lerp a to b with smoothing factor s.

View File

@ -1,20 +1,11 @@
#include "game.h" #include "game.h"
#include <SDL3/SDL.h>
#include <stdlib.h> #include <stdlib.h>
#include "update_time.h"
#include "errors.h" #include "errors.h"
game_t game; game_t game;
static inline void update_time(void)
{
static uint64_t last_clock_state = 0;
uint64_t start_clock = SDL_GetTicksNS();
game.delta_time_ms = SDL_NS_TO_MS((float)(start_clock - last_clock_state));
if(game.delta_time_ms > 100.0f) game.delta_time_ms = 100.0f;
last_clock_state = start_clock;
}
int main(void) int main(void)
{ {
if(game_init()) goto_failure; if(game_init()) goto_failure;

View File

@ -15,19 +15,19 @@ map_t *load_map(void)
if(fread(&map->width, sizeof(map->width), 1, game.asset_manager.asset_file) != 1) if(fread(&map->width, sizeof(map->width), 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
if(fread(&map->height, sizeof(map->height), 1, game.asset_manager.asset_file) != 1) if(fread(&map->height, sizeof(map->height), 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
if(fread(&map->backgroundlayernb, sizeof(map->backgroundlayernb), 1, game.asset_manager.asset_file) != 1) if(fread(&map->backgroundlayernb, sizeof(map->backgroundlayernb), 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
@ -42,7 +42,7 @@ map_t *load_map(void)
uint16_t *backgroundlayer = backgroundlayer_elem->data; uint16_t *backgroundlayer = backgroundlayer_elem->data;
if(fread(backgroundlayer, sizeof(*backgroundlayer), map->width * map->height, game.asset_manager.asset_file) != (size_t)map->width * (size_t)map->height) if(fread(backgroundlayer, sizeof(*backgroundlayer), map->width * map->height, game.asset_manager.asset_file) != (size_t)map->width * (size_t)map->height)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
@ -52,20 +52,20 @@ map_t *load_map(void)
map->foregroundlayer = malloc(map->width * map->height * sizeof(*map->foregroundlayer)); map->foregroundlayer = malloc(map->width * map->height * sizeof(*map->foregroundlayer));
if(fread(map->foregroundlayer, sizeof(*map->foregroundlayer), map->width * map->height, game.asset_manager.asset_file) != (size_t)map->width * (size_t)map->height) if(fread(map->foregroundlayer, sizeof(*map->foregroundlayer), map->width * map->height, game.asset_manager.asset_file) != (size_t)map->width * (size_t)map->height)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
map->hitboxes = malloc(map->width * map->height * sizeof(*map->hitboxes)); map->hitboxes = malloc(map->width * map->height * sizeof(*map->hitboxes));
if(fread(map->hitboxes, sizeof(*map->hitboxes), map->width * map->height, game.asset_manager.asset_file) != (size_t)map->width * (size_t)map->height) if(fread(map->hitboxes, sizeof(*map->hitboxes), map->width * map->height, game.asset_manager.asset_file) != (size_t)map->width * (size_t)map->height)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
if(fread(&map->entities_nb, sizeof(map->entities_nb), 1, game.asset_manager.asset_file) != 1) if(fread(&map->entities_nb, sizeof(map->entities_nb), 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
@ -77,13 +77,13 @@ map_t *load_map(void)
if(fread(&entity_def->id, sizeof(entity_def->id), 1, game.asset_manager.asset_file) != 1) if(fread(&entity_def->id, sizeof(entity_def->id), 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
if(fread(&entity_def->components_nb, sizeof(entity_def->components_nb), 1, game.asset_manager.asset_file) != 1) if(fread(&entity_def->components_nb, sizeof(entity_def->components_nb), 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
@ -95,7 +95,7 @@ map_t *load_map(void)
if(fread(&component_def->type, sizeof(component_def->type), 1, game.asset_manager.asset_file) != 1) if(fread(&component_def->type, sizeof(component_def->type), 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
@ -109,19 +109,35 @@ map_t *load_map(void)
component_def->attributes = malloc(data_size); component_def->attributes = malloc(data_size);
if(fread(component_def->attributes, data_size, 1, game.asset_manager.asset_file) != 1) if(fread(component_def->attributes, data_size, 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
break; break;
case SPRITE_COMPONENT: case SPRITE_COMPONENT:
{ {
size_t cap = 0; size_t name_size = 0;
if(getdelim((char **)&component_def->attributes, &cap, '\0', game.asset_manager.asset_file) == -1) int ch = EOF;
do
{ {
error_printf("Failed to read in asset file : %d", errno); name_size++;
return NULL;
component_def->attributes = realloc(component_def->attributes, name_size);
ch = fgetc(game.asset_manager.asset_file);
if(ch == EOF)
{
error_printf("Failed to read asset file : %d", ferror(game.asset_manager.asset_file));
return NULL;
}
((uint8_t *)component_def->attributes)[name_size - 1] = ch;
} }
while(ch != '\0');
((uint8_t *)component_def->attributes)[name_size] = '\0';
break; break;
} }
@ -130,7 +146,7 @@ map_t *load_map(void)
component_def->attributes = malloc(data_size); component_def->attributes = malloc(data_size);
if(fread(component_def->attributes, data_size, 1, game.asset_manager.asset_file) != 1) if(fread(component_def->attributes, data_size, 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
break; break;
@ -140,7 +156,7 @@ map_t *load_map(void)
component_def->attributes = malloc(data_size); component_def->attributes = malloc(data_size);
if(fread(component_def->attributes, data_size, 1, game.asset_manager.asset_file) != 1) if(fread(component_def->attributes, data_size, 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
break; break;
@ -150,7 +166,7 @@ map_t *load_map(void)
component_def->attributes = malloc(data_size); component_def->attributes = malloc(data_size);
if(fread(component_def->attributes, data_size, 1, game.asset_manager.asset_file) != 1) if(fread(component_def->attributes, data_size, 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
break; break;
@ -160,7 +176,7 @@ map_t *load_map(void)
component_def->attributes = malloc(data_size); component_def->attributes = malloc(data_size);
if(fread(component_def->attributes, data_size, 1, game.asset_manager.asset_file) != 1) if(fread(component_def->attributes, data_size, 1, game.asset_manager.asset_file) != 1)
{ {
error_printf("Failed to read in asset file : %d", errno); error_printf("Failed to read in asset file : %d", ferror(game.asset_manager.asset_file));
return NULL; return NULL;
} }
break; break;
@ -406,8 +422,8 @@ static inline int draw_tile(uint16_t tile_x, uint16_t tile_y, uint16_t tile_id)
if(!tile_id) return EXIT_SUCCESS; if(!tile_id) return EXIT_SUCCESS;
rect_t src_frect = { rect_t src_frect = {
.x = tile_id * TILE_SIZE % get_width(game.map->tileset), .x = tile_id * TILE_SIZE % texture_get_width(game.map->tileset),
.y = tile_id * TILE_SIZE / get_width(game.map->tileset) * TILE_SIZE, .y = tile_id * TILE_SIZE / texture_get_width(game.map->tileset) * TILE_SIZE,
.w = TILE_SIZE, .w = TILE_SIZE,
.h = TILE_SIZE .h = TILE_SIZE
}; };

View File

@ -8,7 +8,7 @@ SOURCES += \
components/animation_system.c \ components/animation_system.c \
components/player_system.c \ components/player_system.c \
components/lever_component.c \ components/lever_component.c \
components/door_component.c \ components/door_component.c# \
components/lua_component.c components/lua_component.c
INCLUDES += \ INCLUDES += \
@ -23,14 +23,14 @@ TOTAL_BUILD_FILES := $(shell echo $$(($$($(MAKE) -n $(OBJECTS) TOTAL_BUILD_FILES
endif endif
$(OUTPUT): $(OBJECTS) $(LIBCORE) $(OUTPUT): $(OBJECTS) $(LIBCORE)
@echo "[100%] $(YELLOW)Linking $(notdir $(OUTPUT))$(RESET)" @echo $(ECHO_OPTION) "[100%] $(YELLOW)Linking $(notdir $(OUTPUT))$(RESET)"
$(Q)$(TARGET_HOST_CC) $(TARGET_HOST_CFLAGS) $(OBJECTS) -o $@ -L$(BUILD_DIR) -lcore $(TARGET_HOST_LDFLAGS) $(Q)$(TARGET_HOST_CC) $(TARGET_HOST_CFLAGS) $(OBJECTS) -o $@ -L$(BUILD_DIR) -lcore $(TARGET_HOST_LDFLAGS)
$(BUILD_DIR)/$(notdir $(SOURCE_DIR))/%.o: $(SOURCE_DIR)/% $(BUILD_DIR)/$(notdir $(SOURCE_DIR))/%.o: $(SOURCE_DIR)/%
$(Q)mkdir -p $(dir $@) $(Q)mkdir -p $(dir $@)
$(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE) + 1)))) $(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE) + 1))))
$(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE) * 100 / $(TOTAL_BUILD_FILES))))) $(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE) * 100 / $(TOTAL_BUILD_FILES)))))
@echo "[$(PERCENTAGE)%] $(GREEN)Building C object $@$(RESET)" @echo $(ECHO_OPTION) "[$(PERCENTAGE)%] $(GREEN)Building C object $@$(RESET)"
$(Q)$(TARGET_HOST_CC) $(TARGET_HOST_CFLAGS) $(INCLUDES:%=-I%) -MMD -MP -c $< -o $@ $(Q)$(TARGET_HOST_CC) $(TARGET_HOST_CFLAGS) $(INCLUDES:%=-I%) -MMD -MP -c $< -o $@
$(LIBCORE): FORCE $(LIBCORE): FORCE

View File

@ -6,12 +6,12 @@
COMPONENT(TRANSFORM_COMPONENT, transform_component, DRAW) COMPONENT(TRANSFORM_COMPONENT, transform_component, DRAW)
COMPONENT(HITBOX_COMPONENT, hitbox_component, DRAW) COMPONENT(HITBOX_COMPONENT, hitbox_component, DRAW)
COMPONENT(INTERACT_COMPONENT, interact_component, DRAW) COMPONENT(INTERACT_COMPONENT, interact_component, DRAW)
COMPONENT(LUA_COMPONENT, lua_component, DRAW) //COMPONENT(LUA_COMPONENT, lua_component, DRAW)
#else #else
COMPONENT(TRANSFORM_COMPONENT, transform_component, NO_DRAW) COMPONENT(TRANSFORM_COMPONENT, transform_component, NO_DRAW)
COMPONENT(HITBOX_COMPONENT, hitbox_component, NO_DRAW) COMPONENT(HITBOX_COMPONENT, hitbox_component, NO_DRAW)
COMPONENT(INTERACT_COMPONENT, interact_component, NO_DRAW) COMPONENT(INTERACT_COMPONENT, interact_component, NO_DRAW)
COMPONENT(LUA_COMPONENT, lua_component, NO_DRAW) //COMPONENT(LUA_COMPONENT, lua_component, NO_DRAW)
#endif // DEBUG >= 2 #endif // DEBUG >= 2
COMPONENT(PHYSICS_SYSTEM, physics_system, NO_DRAW) COMPONENT(PHYSICS_SYSTEM, physics_system, NO_DRAW)

View File

@ -10,7 +10,7 @@
#include "player_system.h" #include "player_system.h"
#include "lever_component.h" #include "lever_component.h"
#include "door_component.h" #include "door_component.h"
#include "lua_component.h" //#include "lua_component.h"
// Add new components header file here // Add new components header file here
#endif // COMPONENTS_H #endif // COMPONENTS_H

View File

@ -21,7 +21,7 @@ int game_init(void)
entity_manager_init(); entity_manager_init();
if(asset_manager_init()) return_failure_int; if(asset_manager_init()) return_failure_int;
asset_t *map_asset = asset_manager_load_asset("dungeon_entry", ASSET_MAP); asset_t *map_asset = asset_manager_load_asset("dungeon_room_1", ASSET_MAP);
if(!map_asset) return_failure_int; if(!map_asset) return_failure_int;
game.map = map_asset->data; game.map = map_asset->data;