Add psp
This commit is contained in:
@@ -7,9 +7,11 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
set(CMAKE_C_STANDARD 99)
|
set(CMAKE_C_STANDARD 99)
|
||||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
|
||||||
|
|
||||||
if(NOT DEFINED DUSK_TARGET_SYSTEM)
|
if(NOT DEFINED DUSK_TARGET_SYSTEM)
|
||||||
set(DUSK_TARGET_SYSTEM "raylib")
|
set(DUSK_TARGET_SYSTEM "linux")
|
||||||
|
# set(DUSK_TARGET_SYSTEM "psp")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Prep cache
|
# Prep cache
|
||||||
@@ -35,6 +37,11 @@ set(DUSK_ASSETS "" CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
|||||||
file(MAKE_DIRECTORY ${DUSK_GENERATED_HEADERS_DIR})
|
file(MAKE_DIRECTORY ${DUSK_GENERATED_HEADERS_DIR})
|
||||||
file(MAKE_DIRECTORY ${DUSK_ASSETS_BUILD_DIR})
|
file(MAKE_DIRECTORY ${DUSK_ASSETS_BUILD_DIR})
|
||||||
|
|
||||||
|
# Compilers
|
||||||
|
if(DUSK_TARGET_SYSTEM STREQUAL "psp")
|
||||||
|
find_package(pspsdk REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Init Project
|
# Init Project
|
||||||
project(${DUSK_TARGET_NAME}
|
project(${DUSK_TARGET_NAME}
|
||||||
VERSION 1.0.0
|
VERSION 1.0.0
|
||||||
@@ -55,3 +62,15 @@ target_include_directories(${DUSK_TARGET_NAME}
|
|||||||
PUBLIC
|
PUBLIC
|
||||||
${DUSK_GENERATED_HEADERS_DIR}
|
${DUSK_GENERATED_HEADERS_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Postbuild, create PBP file for PSP.
|
||||||
|
if(DUSK_TARGET_SYSTEM STREQUAL "psp")
|
||||||
|
create_pbp_file(
|
||||||
|
TARGET "${DUSK_TARGET_NAME}"
|
||||||
|
ICON_PATH NULL
|
||||||
|
BACKGROUND_PATH NULL
|
||||||
|
PREVIEW_PATH NULL
|
||||||
|
TITLE "${DUSK_TARGET_NAME}"
|
||||||
|
VERSION 01.00
|
||||||
|
)
|
||||||
|
endif()
|
99
cmake/modules/Findpspsdk.cmake
Normal file
99
cmake/modules/Findpspsdk.cmake
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
if(NOT TARGET pspsdk)
|
||||||
|
message(STATUS "Looking for PSPSDK...")
|
||||||
|
|
||||||
|
set(PSPSDK_FOUND FALSE CACHE INTERNAL "PSPSDK found")
|
||||||
|
set(PSPSDK_DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/_pspsdk")
|
||||||
|
set(PSPSDK_SEARCH_ROOTS
|
||||||
|
"${PSPSDK_ROOT}"
|
||||||
|
"$ENV{PSPDEV}"
|
||||||
|
"$ENV{HOME}/pspdev"
|
||||||
|
"/usr/local/pspdev"
|
||||||
|
"/opt/pspdev"
|
||||||
|
"/usr/pspdev"
|
||||||
|
"${PSPSDK_DOWNLOAD_DIR}/pspdev"
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach(root IN LISTS PSPSDK_SEARCH_ROOTS)
|
||||||
|
list(APPEND PSPSDK_BIN_HINTS "${root}/bin")
|
||||||
|
list(APPEND PSPSDK_INCLUDE_HINTS "${root}/include")
|
||||||
|
list(APPEND PSPSDK_LIB_HINTS "${root}/lib")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Find PSP GCC
|
||||||
|
find_program(PSPSDK_PSP_GCC NAMES psp-gcc HINTS ${PSPSDK_BIN_HINTS})
|
||||||
|
|
||||||
|
# If we did not find it, download it.
|
||||||
|
if(NOT PSPSDK_PSP_GCC)
|
||||||
|
message(STATUS "psp-gcc not found in system paths. Downloading PSPSDK tarball...")
|
||||||
|
file(DOWNLOAD
|
||||||
|
"https://github.com/pspdev/pspdev/releases/latest/download/pspdev-ubuntu-latest-x86_64.tar.gz"
|
||||||
|
"${CMAKE_BINARY_DIR}/pspsdk.tar.gz"
|
||||||
|
EXPECTED_HASH SHA256=afe338e92f6eeec21c56a64eeb65201e6b95ecbae938ae38688bbf0f17b69ead
|
||||||
|
SHOW_PROGRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
# Make output dir
|
||||||
|
file(MAKE_DIRECTORY "${PSPSDK_DOWNLOAD_DIR}")
|
||||||
|
|
||||||
|
# Extract the tarball
|
||||||
|
execute_process(
|
||||||
|
COMMAND
|
||||||
|
${CMAKE_COMMAND} -E tar xzf "${CMAKE_BINARY_DIR}/pspsdk.tar.gz"
|
||||||
|
WORKING_DIRECTORY
|
||||||
|
"${PSPSDK_DOWNLOAD_DIR}"
|
||||||
|
RESULT_VARIABLE
|
||||||
|
tar_result
|
||||||
|
)
|
||||||
|
if(NOT tar_result EQUAL 0)
|
||||||
|
message(FATAL_ERROR "Failed to extract PSPSDK tarball")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Retry discovery with extracted fallback
|
||||||
|
find_program(PSPSDK_PSP_GCC NAMES psp-gcc HINTS ${PSPSDK_BIN_HINTS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(PSPSDK_PSP_GCC)
|
||||||
|
get_filename_component(PSPSDK_BIN_ROOT "${PSPSDK_PSP_GCC}" DIRECTORY)
|
||||||
|
get_filename_component(PSPSDK_ROOT "${PSPSDK_BIN_ROOT}" DIRECTORY)
|
||||||
|
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||||
|
set(ENV{PSPDEV} "${PSPSDK_ROOT}")
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE "${PSPSDK_ROOT}/psp/share/pspdev.cmake")
|
||||||
|
set(BUILD_PRX ON CACHE BOOL "Build PRX modules")
|
||||||
|
|
||||||
|
include("${PSPSDK_ROOT}/psp/share/pspdev.cmake")
|
||||||
|
set(CMAKE_C_COMPILER ${PSPSDK_BIN_ROOT}/psp-gcc)
|
||||||
|
set(CMAKE_CXX_COMPILER ${PSPSDK_BIN_ROOT}/psp-g++)
|
||||||
|
|
||||||
|
if(NOT DEFINED PSP)
|
||||||
|
message(FATAL_ERROR "PSP environment variable is not set correctly.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(pspsdk INTERFACE IMPORTED)
|
||||||
|
set_target_properties(pspsdk PROPERTIES
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${PSPSDK_INCLUDE_DIR}"
|
||||||
|
INTERFACE_LINK_DIRECTORIES "${PSPSDK_LIB_DIR}"
|
||||||
|
)
|
||||||
|
target_include_directories(pspsdk
|
||||||
|
INTERFACE
|
||||||
|
${PSPDEV}/psp/include
|
||||||
|
${PSPDEV}/psp/sdk/include
|
||||||
|
)
|
||||||
|
target_link_directories(pspsdk
|
||||||
|
INTERFACE
|
||||||
|
${PSPDEV}/lib
|
||||||
|
${PSPDEV}/psp/lib
|
||||||
|
${PSPDEV}/psp/sdk/lib
|
||||||
|
)
|
||||||
|
target_link_libraries(pspsdk INTERFACE
|
||||||
|
pspdebug
|
||||||
|
pspdisplay
|
||||||
|
pspge
|
||||||
|
pspctrl
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
20
cmake/modules/Findraylib.cmake
Normal file
20
cmake/modules/Findraylib.cmake
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
include(FetchContent)
|
||||||
|
FetchContent_Declare(
|
||||||
|
raylib
|
||||||
|
URL https://github.com/raysan5/raylib/archive/refs/tags/5.5.tar.gz
|
||||||
|
URL_HASH MD5=61638c4c2c097fbca1d6a71e4da36c16
|
||||||
|
)
|
||||||
|
FetchContent_GetProperties(raylib)
|
||||||
|
FetchContent_MakeAvailable(raylib)
|
||||||
|
|
||||||
|
# Define expected target if not already defined
|
||||||
|
if(NOT TARGET raylib)
|
||||||
|
set(raylib_FOUND FALSE CACHE INTERNAL "Whether raylib was found")
|
||||||
|
else()
|
||||||
|
set(raylib_FOUND TRUE CACHE INTERNAL "Whether raylib was found")
|
||||||
|
endif()
|
@@ -5,6 +5,10 @@
|
|||||||
|
|
||||||
add_subdirectory(dusk)
|
add_subdirectory(dusk)
|
||||||
|
|
||||||
if(DUSK_TARGET_SYSTEM STREQUAL "raylib")
|
if(DUSK_TARGET_SYSTEM STREQUAL "linux")
|
||||||
add_subdirectory(duskraylib)
|
add_subdirectory(duskraylib)
|
||||||
|
elseif(DUSK_TARGET_SYSTEM STREQUAL "psp")
|
||||||
|
add_subdirectory(duskpsp)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unsupported target system: ${DUSK_TARGET_SYSTEM}")
|
||||||
endif()
|
endif()
|
@@ -10,19 +10,20 @@ target_link_libraries(${DUSK_TARGET_NAME}
|
|||||||
|
|
||||||
# Includes
|
# Includes
|
||||||
target_include_directories(${DUSK_TARGET_NAME}
|
target_include_directories(${DUSK_TARGET_NAME}
|
||||||
PUBLIC
|
PRIVATE
|
||||||
${CMAKE_CURRENT_LIST_DIR}
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Sources
|
# Sources
|
||||||
target_sources(${DUSK_TARGET_NAME}
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
main.c
|
game.c
|
||||||
input.c
|
input.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Subdirs
|
# Subdirs
|
||||||
add_subdirectory(assert)
|
add_subdirectory(assert)
|
||||||
|
add_subdirectory(console)
|
||||||
add_subdirectory(display)
|
add_subdirectory(display)
|
||||||
add_subdirectory(entity)
|
add_subdirectory(entity)
|
||||||
add_subdirectory(event)
|
add_subdirectory(event)
|
||||||
|
12
src/dusk/console/CMakeLists.txt
Normal file
12
src/dusk/console/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
console.c
|
||||||
|
consolecmd.c
|
||||||
|
consolevar.c
|
||||||
|
)
|
395
src/dusk/console/console.c
Normal file
395
src/dusk/console/console.c
Normal file
@@ -0,0 +1,395 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "console.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
console_t CONSOLE;
|
||||||
|
|
||||||
|
void consoleInit() {
|
||||||
|
memoryZero(&CONSOLE, sizeof(console_t));
|
||||||
|
pthread_mutex_init(&CONSOLE.lock, NULL); // Initialize the mutex
|
||||||
|
|
||||||
|
// Register the get and set command.
|
||||||
|
CONSOLE.cmdGet = consoleRegCmd("get", cmdGet);
|
||||||
|
CONSOLE.cmdSet = consoleRegCmd("set", cmdSet);
|
||||||
|
consoleRegCmd("echo", cmdEcho);
|
||||||
|
|
||||||
|
consolePrint(" = Dawn Console = ");
|
||||||
|
}
|
||||||
|
|
||||||
|
consolecmd_t * consoleRegCmd(const char_t *name, consolecmdfunc_t function) {
|
||||||
|
pthread_mutex_lock(&CONSOLE.lock); // Lock
|
||||||
|
consolecmd_t *cmd = &CONSOLE.commands[CONSOLE.commandCount++];
|
||||||
|
consoleCmdInit(cmd, name, function);
|
||||||
|
pthread_mutex_unlock(&CONSOLE.lock); // Unlock
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
consolevar_t * consoleRegVar(
|
||||||
|
const char_t *name,
|
||||||
|
const char_t *value,
|
||||||
|
consolevarchanged_t event
|
||||||
|
) {
|
||||||
|
pthread_mutex_lock(&CONSOLE.lock); // Lock
|
||||||
|
consolevar_t *var = &CONSOLE.variables[CONSOLE.variableCount++];
|
||||||
|
consoleVarInitListener(var, name, value, event);
|
||||||
|
pthread_mutex_unlock(&CONSOLE.lock); // Unlock
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
void consolePrint(const char_t *message, ...) {
|
||||||
|
char_t buffer[CONSOLE_LINE_MAX];
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
int32_t len = stringFormatVA(buffer, CONSOLE_LINE_MAX, message, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
// Move all lines back
|
||||||
|
memoryMove(
|
||||||
|
CONSOLE.line[0],
|
||||||
|
CONSOLE.line[1],
|
||||||
|
(CONSOLE_HISTORY_MAX - 1) * CONSOLE_LINE_MAX
|
||||||
|
);
|
||||||
|
|
||||||
|
// Copy the new line
|
||||||
|
memoryCopy(
|
||||||
|
CONSOLE.line[CONSOLE_HISTORY_MAX - 1],
|
||||||
|
buffer,
|
||||||
|
len + 1
|
||||||
|
);
|
||||||
|
printf("%s\n", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void consoleExec(const char_t *line) {
|
||||||
|
pthread_mutex_lock(&CONSOLE.lock); // Lock
|
||||||
|
assertNotNull(line, "line must not be NULL");
|
||||||
|
assertTrue(
|
||||||
|
CONSOLE.execBufferCount < CONSOLE_EXEC_BUFFER_MAX,
|
||||||
|
"Too many commands in the buffer."
|
||||||
|
);
|
||||||
|
|
||||||
|
char_t buffer[CONSOLE_LINE_MAX];
|
||||||
|
size_t i = 0, j = 0;
|
||||||
|
char_t c;
|
||||||
|
consoleexecstate_t state = CONSOLE_EXEC_STATE_INITIAL;
|
||||||
|
consolecmdexec_t *exec = NULL;
|
||||||
|
|
||||||
|
while(state != CONSOLE_EXEC_STATE_FULLY_PARSED) {
|
||||||
|
c = line[i];
|
||||||
|
|
||||||
|
switch(state) {
|
||||||
|
case CONSOLE_EXEC_STATE_INITIAL:
|
||||||
|
assertTrue(j == 0, "Buffer not empty?");
|
||||||
|
|
||||||
|
if(c == '\0') {
|
||||||
|
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stringIsWhitespace(c) || c == ';') {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = CONSOLE_EXEC_STATE_PARSE_CMD;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONSOLE_EXEC_STATE_PARSE_CMD:
|
||||||
|
if(stringIsWhitespace(c) || c == '\0' || c == ';') {
|
||||||
|
state = CONSOLE_EXEC_STATE_CMD_PARSED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c == '"') {
|
||||||
|
// Can't handle quotes within the command.
|
||||||
|
consolePrint("Invalid command");
|
||||||
|
while(c != '\0' && c != ';') c = line[++i];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[j++] = c;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if(j >= CONSOLE_LINE_MAX) {
|
||||||
|
consolePrint("Command too long");
|
||||||
|
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONSOLE_EXEC_STATE_CMD_PARSED:
|
||||||
|
if(j == 0) {
|
||||||
|
state = CONSOLE_EXEC_STATE_INITIAL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create exec
|
||||||
|
assertNull(exec, "Existing command parsing?");
|
||||||
|
|
||||||
|
exec = &CONSOLE.execBuffer[CONSOLE.execBufferCount];
|
||||||
|
memoryZero(exec, sizeof(consolecmdexec_t));
|
||||||
|
|
||||||
|
buffer[j] = '\0';
|
||||||
|
stringCopy(exec->command, buffer, CONSOLE_LINE_MAX);
|
||||||
|
state = CONSOLE_EXEC_STATE_FIND_ARG;
|
||||||
|
|
||||||
|
j = 0;// Free up buffer
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONSOLE_EXEC_STATE_FIND_ARG:
|
||||||
|
if(c == '\0' || c == ';') {
|
||||||
|
state = CONSOLE_EXEC_STATE_CMD_FINISHED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stringIsWhitespace(c)) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c == '"') {
|
||||||
|
state = CONSOLE_EXEC_STATE_PARSE_ARG_QUOTED;
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
state = CONSOLE_EXEC_STATE_PARSE_ARG;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONSOLE_EXEC_STATE_PARSE_ARG:
|
||||||
|
if(stringIsWhitespace(c) || c == '\0' || c == ';') {
|
||||||
|
state = CONSOLE_EXEC_STATE_ARG_PARSED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[j++] = c;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if(j >= CONSOLE_LINE_MAX) {
|
||||||
|
consolePrint("Arg too long");
|
||||||
|
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONSOLE_EXEC_STATE_PARSE_ARG_QUOTED:
|
||||||
|
if(c == '"') {
|
||||||
|
state = CONSOLE_EXEC_STATE_ARG_PARSED;
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c == '\0' || c == ';') {
|
||||||
|
consolePrint("Unterminated quote");
|
||||||
|
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c == '\\') {
|
||||||
|
c = line[++i];
|
||||||
|
|
||||||
|
if(c == '\0' || c == ';') {
|
||||||
|
consolePrint("Unterminated quote");
|
||||||
|
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[j++] = c;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if(j >= CONSOLE_LINE_MAX) {
|
||||||
|
consolePrint("Arg too long");
|
||||||
|
state = CONSOLE_EXEC_STATE_FULLY_PARSED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONSOLE_EXEC_STATE_ARG_PARSED:
|
||||||
|
buffer[j] = '\0';
|
||||||
|
stringCopy(exec->argv[exec->argc++], buffer, CONSOLE_LINE_MAX);
|
||||||
|
state = CONSOLE_EXEC_STATE_FIND_ARG;
|
||||||
|
j = 0;// Free up buffer
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONSOLE_EXEC_STATE_CMD_FINISHED:
|
||||||
|
assertNotNull(exec, "No command found?");
|
||||||
|
|
||||||
|
// Now, is there a command that matches?
|
||||||
|
for(uint32_t k = 0; k < CONSOLE.commandCount; k++) {
|
||||||
|
consolecmd_t *cmd = &CONSOLE.commands[k];
|
||||||
|
if(stringCompare(cmd->name, exec->command) != 0) continue;
|
||||||
|
exec->cmd = cmd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(exec->cmd == NULL) {
|
||||||
|
// Command wasn't found, is there a variable that matches?
|
||||||
|
for(uint32_t k = 0; k < CONSOLE.variableCount; k++) {
|
||||||
|
consolevar_t *var = &CONSOLE.variables[k];
|
||||||
|
if(stringCompare(var->name, exec->command) != 0) continue;
|
||||||
|
|
||||||
|
// Matching variable found, is this a GET or a SET?
|
||||||
|
if(exec->argc == 0) {
|
||||||
|
exec->cmd = CONSOLE.cmdGet;
|
||||||
|
stringCopy(exec->argv[0], exec->command, CONSOLE_LINE_MAX);
|
||||||
|
exec->argc = 1;
|
||||||
|
} else {
|
||||||
|
exec->cmd = CONSOLE.cmdSet;
|
||||||
|
stringCopy(exec->argv[1], exec->argv[0], CONSOLE_LINE_MAX);
|
||||||
|
stringCopy(exec->argv[0], exec->command, CONSOLE_LINE_MAX);
|
||||||
|
exec->argc = 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(exec->cmd == NULL) {
|
||||||
|
consolePrint("Command not found", exec->command);
|
||||||
|
exec = NULL;
|
||||||
|
state = CONSOLE_EXEC_STATE_INITIAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prep for next command.
|
||||||
|
exec = NULL;
|
||||||
|
state = CONSOLE_EXEC_STATE_INITIAL;
|
||||||
|
CONSOLE.execBufferCount++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assertUnreachable("Invalid state.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&CONSOLE.lock); // Unlock
|
||||||
|
}
|
||||||
|
|
||||||
|
void consoleProcess() {
|
||||||
|
pthread_mutex_lock(&CONSOLE.lock); // Lock
|
||||||
|
for(uint32_t i = 0; i < CONSOLE.execBufferCount; i++) {
|
||||||
|
consolecmdexec_t *exec = &CONSOLE.execBuffer[i];
|
||||||
|
|
||||||
|
assertNotNull(exec->cmd, "Command execution has no command.");
|
||||||
|
|
||||||
|
exec->cmd->function(exec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the exec buffer
|
||||||
|
CONSOLE.execBufferCount = 0;
|
||||||
|
pthread_mutex_unlock(&CONSOLE.lock); // Unlock
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmdGet(const consolecmdexec_t *exec) {
|
||||||
|
assertTrue(
|
||||||
|
exec->argc >= 1,
|
||||||
|
"Get command requires 1 argument."
|
||||||
|
);
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < CONSOLE.variableCount; i++) {
|
||||||
|
consolevar_t *var = &CONSOLE.variables[i];
|
||||||
|
if(stringCompare(var->name, exec->argv[0]) != 0) continue;
|
||||||
|
consolePrint("%s", var->value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
consolePrint("Error: Variable '%s' not found.", exec->argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmdSet(const consolecmdexec_t *exec) {
|
||||||
|
assertTrue(exec->argc >= 2, "set command requires 2 arguments.");
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < CONSOLE.variableCount; i++) {
|
||||||
|
consolevar_t *var = &CONSOLE.variables[i];
|
||||||
|
if(stringCompare(var->name, exec->argv[0]) != 0) continue;
|
||||||
|
consoleVarSetValue(var, exec->argv[1]);
|
||||||
|
consolePrint("%s %s", var->name, var->value);
|
||||||
|
for(i = 0; i < var->eventCount; i++) {
|
||||||
|
assertNotNull(var->events[i], "Event is NULL");
|
||||||
|
var->events[i](var);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
consolePrint("Error: Variable '%s' not found.", exec->argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmdEcho(const consolecmdexec_t *exec) {
|
||||||
|
assertTrue(
|
||||||
|
exec->argc >= 1,
|
||||||
|
"echo command requires 1 argument."
|
||||||
|
);
|
||||||
|
|
||||||
|
consolePrint("%s", exec->argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// May move these later
|
||||||
|
void consoleUpdate() {
|
||||||
|
if(inputIsPressed(INPUT_TOGGLE_CONSOLE)) {
|
||||||
|
CONSOLE.open = !CONSOLE.open;
|
||||||
|
} else if(CONSOLE.open) {
|
||||||
|
switch(INPUT.keyPressed) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_ENTER:
|
||||||
|
consoleExec(CONSOLE.inputBuffer);
|
||||||
|
CONSOLE.inputIndex = 0;
|
||||||
|
CONSOLE.inputBuffer[0] = '\0';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_BACKSPACE:
|
||||||
|
if(CONSOLE.inputIndex > 0) {
|
||||||
|
CONSOLE.inputIndex--;
|
||||||
|
CONSOLE.inputBuffer[CONSOLE.inputIndex] = '\0';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if(
|
||||||
|
INPUT.keyPressed >= 32 &&
|
||||||
|
INPUT.keyPressed <= 126 &&
|
||||||
|
CONSOLE.inputIndex < CONSOLE_LINE_MAX - 1
|
||||||
|
) {
|
||||||
|
CONSOLE.inputBuffer[CONSOLE.inputIndex++] = INPUT.charPressed;
|
||||||
|
CONSOLE.inputBuffer[CONSOLE.inputIndex] = '\0';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
consoleProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
void consoleDraw() {
|
||||||
|
if(!CONSOLE.open) return;
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
char_t *line;
|
||||||
|
int32_t fontSize = 10;
|
||||||
|
do {
|
||||||
|
line = CONSOLE.line[i];
|
||||||
|
if(line[0] == '\0') {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DrawText(line, 0, i*fontSize, fontSize, YELLOW);
|
||||||
|
i++;
|
||||||
|
} while(i < CONSOLE_HISTORY_MAX);
|
||||||
|
|
||||||
|
DrawText(
|
||||||
|
CONSOLE.inputBuffer, 0,
|
||||||
|
(CONSOLE_HISTORY_MAX + 1) * fontSize,
|
||||||
|
fontSize,
|
||||||
|
PINK
|
||||||
|
);
|
||||||
|
}
|
114
src/dusk/console/console.h
Normal file
114
src/dusk/console/console.h
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "consolevar.h"
|
||||||
|
#include "consolecmd.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CONSOLE_EXEC_STATE_INITIAL,
|
||||||
|
CONSOLE_EXEC_STATE_PARSE_CMD,
|
||||||
|
CONSOLE_EXEC_STATE_CMD_PARSED,
|
||||||
|
|
||||||
|
CONSOLE_EXEC_STATE_FIND_ARG,
|
||||||
|
CONSOLE_EXEC_STATE_PARSE_ARG,
|
||||||
|
CONSOLE_EXEC_STATE_PARSE_ARG_QUOTED,
|
||||||
|
CONSOLE_EXEC_STATE_ARG_PARSED,
|
||||||
|
|
||||||
|
CONSOLE_EXEC_STATE_CMD_FINISHED,
|
||||||
|
CONSOLE_EXEC_STATE_FULLY_PARSED
|
||||||
|
} consoleexecstate_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
consolecmd_t commands[CONSOLE_COMMANDS_MAX];
|
||||||
|
uint32_t commandCount;
|
||||||
|
|
||||||
|
consolevar_t variables[CONSOLE_VARIABLES_MAX];
|
||||||
|
uint32_t variableCount;
|
||||||
|
|
||||||
|
char_t line[CONSOLE_HISTORY_MAX][CONSOLE_LINE_MAX];
|
||||||
|
|
||||||
|
consolecmdexec_t execBuffer[CONSOLE_EXEC_BUFFER_MAX];
|
||||||
|
uint32_t execBufferCount;
|
||||||
|
|
||||||
|
consolecmd_t *cmdGet;
|
||||||
|
consolecmd_t *cmdSet;
|
||||||
|
pthread_mutex_t lock; // Mutex for thread safety
|
||||||
|
|
||||||
|
// May move these later
|
||||||
|
char_t inputBuffer[CONSOLE_LINE_MAX];
|
||||||
|
int32_t inputIndex;
|
||||||
|
|
||||||
|
bool_t open;
|
||||||
|
} console_t;
|
||||||
|
|
||||||
|
extern console_t CONSOLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the console.
|
||||||
|
*/
|
||||||
|
void consoleInit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a console command.
|
||||||
|
*
|
||||||
|
* @param name The name of the command.
|
||||||
|
* @param function The function to execute when the command is called.
|
||||||
|
* @return The registered command.
|
||||||
|
*/
|
||||||
|
consolecmd_t * consoleRegCmd(const char_t *name, consolecmdfunc_t function);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a console variable.
|
||||||
|
*
|
||||||
|
* @param name The name of the variable.
|
||||||
|
* @param value The initial value of the variable.
|
||||||
|
* @param event The event to register.
|
||||||
|
* @return The registered variable.
|
||||||
|
*/
|
||||||
|
consolevar_t * consoleRegVar(
|
||||||
|
const char_t *name,
|
||||||
|
const char_t *value,
|
||||||
|
consolevarchanged_t event
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of a console variable.
|
||||||
|
*
|
||||||
|
* @param name The name of the variable.
|
||||||
|
* @param value The new value of the variable.
|
||||||
|
*/
|
||||||
|
void consolePrint(
|
||||||
|
const char_t *message,
|
||||||
|
...
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a console command.
|
||||||
|
*
|
||||||
|
* @param line The line to execute.
|
||||||
|
*/
|
||||||
|
void consoleExec(const char_t *line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes the console's pending commands.
|
||||||
|
*/
|
||||||
|
void consoleProcess();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the console's input buffer and handles user input.
|
||||||
|
*/
|
||||||
|
void consoleUpdate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the console's output.
|
||||||
|
*/
|
||||||
|
void consoleDraw();
|
||||||
|
|
||||||
|
void cmdGet(const consolecmdexec_t *exec);
|
||||||
|
void cmdSet(const consolecmdexec_t *exec);
|
||||||
|
void cmdEcho(const consolecmdexec_t *exec);
|
27
src/dusk/console/consolecmd.c
Normal file
27
src/dusk/console/consolecmd.c
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "consolecmd.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
|
||||||
|
void consoleCmdInit(
|
||||||
|
consolecmd_t *cmd,
|
||||||
|
const char_t *name,
|
||||||
|
consolecmdfunc_t function
|
||||||
|
) {
|
||||||
|
assertNotNull(cmd, "Command is NULL.");
|
||||||
|
assertNotNull(name, "Name is NULL.");
|
||||||
|
assertNotNull(function, "Function is NULL.");
|
||||||
|
assertStrLenMin(name, 1, "Name is empty.");
|
||||||
|
assertStrLenMax(name, CONSOLE_CMD_NAME_MAX, "Name is too long.");
|
||||||
|
|
||||||
|
memoryZero(cmd, sizeof(consolecmd_t));
|
||||||
|
stringCopy(cmd->name, name, CONSOLE_CMD_NAME_MAX);
|
||||||
|
cmd->function = function;
|
||||||
|
}
|
39
src/dusk/console/consolecmd.h
Normal file
39
src/dusk/console/consolecmd.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
#include "consoledefs.h"
|
||||||
|
|
||||||
|
typedef struct consolecmd_s consolecmd_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
consolecmd_t *cmd;
|
||||||
|
char_t command[CONSOLE_LINE_MAX];
|
||||||
|
char_t argv[CONSOLE_CMD_ARGC_MAX][CONSOLE_LINE_MAX];
|
||||||
|
uint32_t argc;
|
||||||
|
} consolecmdexec_t;
|
||||||
|
|
||||||
|
typedef void (*consolecmdfunc_t)(const consolecmdexec_t *exec);
|
||||||
|
|
||||||
|
typedef struct consolecmd_s {
|
||||||
|
char_t name[CONSOLE_CMD_NAME_MAX];
|
||||||
|
consolecmdfunc_t function;
|
||||||
|
} consolecmd_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a console command.
|
||||||
|
*
|
||||||
|
* @param cmd Pointer to the console command.
|
||||||
|
* @param name The name of the command.
|
||||||
|
* @param function The function to execute when the command is called.
|
||||||
|
*/
|
||||||
|
void consoleCmdInit(
|
||||||
|
consolecmd_t *cmd,
|
||||||
|
const char_t *name,
|
||||||
|
consolecmdfunc_t function
|
||||||
|
);
|
21
src/dusk/console/consoledefs.h
Normal file
21
src/dusk/console/consoledefs.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define CONSOLE_CMD_NAME_MAX 32
|
||||||
|
#define CONSOLE_CMD_ARGC_MAX 16
|
||||||
|
|
||||||
|
#define CONSOLE_COMMANDS_MAX 128
|
||||||
|
#define CONSOLE_VARIABLES_MAX 128
|
||||||
|
#define CONSOLE_LINE_MAX 256
|
||||||
|
#define CONSOLE_HISTORY_MAX 32
|
||||||
|
#define CONSOLE_EXEC_BUFFER_MAX 16
|
||||||
|
|
||||||
|
#define CONSOLE_VAR_NAME_MAX 32
|
||||||
|
#define CONSOLE_VAR_VALUE_MAX 128
|
||||||
|
#define CONSOLE_VAR_EVENTS_MAX 8
|
64
src/dusk/console/consolevar.c
Normal file
64
src/dusk/console/consolevar.c
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "consolevar.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
|
||||||
|
void consoleVarInit(
|
||||||
|
consolevar_t *var,
|
||||||
|
const char_t *name,
|
||||||
|
const char_t *value
|
||||||
|
) {
|
||||||
|
assertNotNull(var, "var must not be NULL");
|
||||||
|
assertNotNull(name, "name must not be NULL");
|
||||||
|
assertNotNull(value, "value must not be NULL");
|
||||||
|
|
||||||
|
assertStrLenMin(name, 1, "name must not be empty");
|
||||||
|
assertStrLenMax(name, CONSOLE_VAR_NAME_MAX, "name is too long");
|
||||||
|
assertStrLenMax(value, CONSOLE_VAR_VALUE_MAX, "value is too long");
|
||||||
|
|
||||||
|
memoryZero(var, sizeof(consolevar_t));
|
||||||
|
stringCopy(var->name, name, CONSOLE_VAR_NAME_MAX);
|
||||||
|
stringCopy(var->value, value, CONSOLE_VAR_VALUE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void consoleVarInitListener(
|
||||||
|
consolevar_t *var,
|
||||||
|
const char_t *name,
|
||||||
|
const char_t *value,
|
||||||
|
consolevarchanged_t event
|
||||||
|
) {
|
||||||
|
consoleVarInit(var, name, value);
|
||||||
|
if(event) consoleVarListen(var, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void consoleVarSetValue(consolevar_t *var, const char_t *value) {
|
||||||
|
assertNotNull(var, "var must not be NULL");
|
||||||
|
assertNotNull(value, "value must not be NULL");
|
||||||
|
assertStrLenMax(value, CONSOLE_VAR_VALUE_MAX, "value is too long");
|
||||||
|
|
||||||
|
stringCopy(var->value, value, CONSOLE_VAR_VALUE_MAX);
|
||||||
|
|
||||||
|
uint8_t i = 0;
|
||||||
|
while (i < var->eventCount) {
|
||||||
|
var->events[i](var);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void consoleVarListen(consolevar_t *var, consolevarchanged_t event) {
|
||||||
|
assertNotNull(var, "var must not be NULL");
|
||||||
|
assertNotNull(event, "event must not be NULL");
|
||||||
|
assertTrue(
|
||||||
|
var->eventCount < CONSOLE_VAR_EVENTS_MAX,
|
||||||
|
"Event count is too high"
|
||||||
|
);
|
||||||
|
var->events[var->eventCount++] = event;
|
||||||
|
}
|
||||||
|
|
65
src/dusk/console/consolevar.h
Normal file
65
src/dusk/console/consolevar.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
#include "consoledefs.h"
|
||||||
|
|
||||||
|
typedef struct consolevar_s consolevar_t;
|
||||||
|
|
||||||
|
typedef void (*consolevarchanged_t)(const consolevar_t *var);
|
||||||
|
|
||||||
|
typedef struct consolevar_s {
|
||||||
|
char_t name[CONSOLE_VAR_NAME_MAX];
|
||||||
|
char_t value[CONSOLE_VAR_VALUE_MAX];
|
||||||
|
consolevarchanged_t events[CONSOLE_VAR_EVENTS_MAX];
|
||||||
|
uint8_t eventCount;
|
||||||
|
} consolevar_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a console variable.
|
||||||
|
*
|
||||||
|
* @param var Pointer to the console variable.
|
||||||
|
* @param name The name of the variable.
|
||||||
|
* @param value The initial value of the variable.
|
||||||
|
*/
|
||||||
|
void consoleVarInit(
|
||||||
|
consolevar_t *var,
|
||||||
|
const char_t *name,
|
||||||
|
const char_t *value
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a console variable with a listener.
|
||||||
|
*
|
||||||
|
* @param var Pointer to the console variable.
|
||||||
|
* @param name The name of the variable.
|
||||||
|
* @param value The initial value of the variable.
|
||||||
|
* @param event The event to register.
|
||||||
|
*/
|
||||||
|
void consoleVarInitListener(
|
||||||
|
consolevar_t *var,
|
||||||
|
const char_t *name,
|
||||||
|
const char_t *value,
|
||||||
|
consolevarchanged_t event
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of a console variable.
|
||||||
|
*
|
||||||
|
* @param var Pointer to the console variable.
|
||||||
|
* @param value The new value of the variable.
|
||||||
|
*/
|
||||||
|
void consoleVarSetValue(consolevar_t *var, const char_t *value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers an event to be called when the value of a console variable changes.
|
||||||
|
*
|
||||||
|
* @param var Pointer to the console variable.
|
||||||
|
* @param event The event to register.
|
||||||
|
*/
|
||||||
|
void consoleVarListen(consolevar_t *var, consolevarchanged_t event);
|
@@ -27,10 +27,3 @@ void renderDraw(void);
|
|||||||
* Disposes of the rendering system.
|
* Disposes of the rendering system.
|
||||||
*/
|
*/
|
||||||
void renderDispose(void);
|
void renderDispose(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the rendering system should exit.
|
|
||||||
*
|
|
||||||
* @return true if the rendering system should exit, false otherwise.
|
|
||||||
*/
|
|
||||||
bool_t renderShouldExit();
|
|
@@ -5,7 +5,7 @@
|
|||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "display/render.h"
|
#include "game.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "world/chunk.h"
|
#include "world/chunk.h"
|
||||||
#include "display/scene.h"
|
#include "display/scene.h"
|
||||||
@@ -14,28 +14,23 @@
|
|||||||
#include "event/event.h"
|
#include "event/event.h"
|
||||||
#include "ui/uitextbox.h"
|
#include "ui/uitextbox.h"
|
||||||
|
|
||||||
// Press F5 to compile and run the compiled game.gb in the Emulicous Emulator/Debugger
|
void gameInit(void) {
|
||||||
void main(void) {
|
|
||||||
renderInit();
|
|
||||||
inputInit();
|
inputInit();
|
||||||
eventInit();
|
eventInit();
|
||||||
uiTextboxInit();
|
uiTextboxInit();
|
||||||
|
|
||||||
overworldInit();
|
overworldInit();
|
||||||
|
|
||||||
SCENE_CURRENT = SCENE_OVERWORLD;
|
SCENE_CURRENT = SCENE_OVERWORLD;
|
||||||
|
}
|
||||||
while(!renderShouldExit()) {
|
|
||||||
RENDER_FRAME++;
|
void gameUpdate(void) {
|
||||||
renderDraw();
|
overworldUpdate();
|
||||||
|
uiTextboxUpdate();
|
||||||
overworldUpdate();
|
eventUpdate();
|
||||||
uiTextboxUpdate();
|
|
||||||
eventUpdate();
|
inputUpdate();
|
||||||
|
}
|
||||||
// Update input for next frame.
|
|
||||||
inputUpdate();
|
void gameDispose(void) {
|
||||||
}
|
|
||||||
|
|
||||||
renderDispose();
|
|
||||||
}
|
}
|
42
src/dusk/game.h
Normal file
42
src/dusk/game.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the game, this should be called before any other game functions.
|
||||||
|
* This should be called by the parent platform at a time that it deems
|
||||||
|
* appropriate. Any game systems cannot be used until this function has
|
||||||
|
* been called.
|
||||||
|
*
|
||||||
|
* By the point this is called, we expect;
|
||||||
|
* - Rendering has initialized and is ready to draw.
|
||||||
|
* - Input has been initialized and is ready to be read.
|
||||||
|
* - If your system handles time dynamically, it should be ready to be used.
|
||||||
|
*
|
||||||
|
* The systems called (in order) are;
|
||||||
|
* - Input system (Not the platforms input, but the game's input system).
|
||||||
|
* - Time system (if applicable).
|
||||||
|
* - Event System
|
||||||
|
* - UI Systems.
|
||||||
|
* - Gameplay systems.
|
||||||
|
*/
|
||||||
|
void gameInit(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks the game to update, this will not do any drawing and should be called
|
||||||
|
* in the main loop of the system, ideally either after or before the rendering
|
||||||
|
* has occured.
|
||||||
|
*/
|
||||||
|
void gameUpdate(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up resources used by the game, rendering really should still be
|
||||||
|
* available at this point because we want to cleanup nicely.
|
||||||
|
*/
|
||||||
|
void gameDispose(void);
|
@@ -8,4 +8,5 @@ target_sources(${DUSK_TARGET_NAME}
|
|||||||
PRIVATE
|
PRIVATE
|
||||||
fixed.c
|
fixed.c
|
||||||
memory.c
|
memory.c
|
||||||
|
string.c
|
||||||
)
|
)
|
127
src/dusk/util/string.c
Normal file
127
src/dusk/util/string.c
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "string.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
|
||||||
|
bool_t stringIsWhitespace(const char_t c) {
|
||||||
|
return isspace(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stringCopy(char_t *dest, const char_t *src, const size_t destSize) {
|
||||||
|
assertNotNull(dest, "dest must not be NULL");
|
||||||
|
assertNotNull(src, "src must not be NULL");
|
||||||
|
assertTrue(destSize > 0, "destSize must be greater than 0");
|
||||||
|
assertStrLenMax(src, destSize, "src is too long");
|
||||||
|
memoryCopy(dest, src, strlen(src) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int stringCompare(const char_t *str1, const char_t *str2) {
|
||||||
|
assertNotNull(str1, "str1 must not be NULL");
|
||||||
|
assertNotNull(str2, "str2 must not be NULL");
|
||||||
|
return strcmp(str1, str2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stringTrim(char_t *str) {
|
||||||
|
assertNotNull(str, "str must not be NULL");
|
||||||
|
|
||||||
|
// Trim leading whitespace
|
||||||
|
char_t *start = str;
|
||||||
|
while(stringIsWhitespace(*start)) start++;
|
||||||
|
|
||||||
|
// Trim trailing whitespace
|
||||||
|
char_t *end = start + strlen(start) - 1;
|
||||||
|
while (end >= start && stringIsWhitespace(*end)) end--;
|
||||||
|
|
||||||
|
// Null-terminate the string
|
||||||
|
*(end + 1) = '\0';
|
||||||
|
|
||||||
|
// Move trimmed string to the original buffer
|
||||||
|
if (start != str) memmove(str, start, end - start + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
char_t * stringToken(char_t *str, const char_t *delim) {
|
||||||
|
assertNotNull(str, "str must not be NULL");
|
||||||
|
assertNotNull(delim, "delim must not be NULL");
|
||||||
|
return strtok(str, delim);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t stringFormat(
|
||||||
|
char_t *dest,
|
||||||
|
const size_t destSize,
|
||||||
|
char_t *format,
|
||||||
|
...
|
||||||
|
) {
|
||||||
|
assertNotNull(dest, "dest must not be NULL");
|
||||||
|
assertNotNull(format, "format must not be NULL");
|
||||||
|
assertTrue(destSize > 0, "destSize must be greater than 0");
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
int32_t result = stringFormatVA(dest, destSize, format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t stringFormatVA(
|
||||||
|
char_t *dest,
|
||||||
|
const size_t destSize,
|
||||||
|
const char_t *format,
|
||||||
|
va_list args
|
||||||
|
) {
|
||||||
|
assertNotNull(dest, "dest must not be NULL");
|
||||||
|
assertNotNull(format, "format must not be NULL");
|
||||||
|
assertTrue(destSize > 0, "destSize must be greater than 0");
|
||||||
|
int32_t ret = vsnprintf(dest, destSize, format, args);
|
||||||
|
assertTrue(ret >= 0, "Failed to format string.");
|
||||||
|
assertTrue(ret < destSize, "Formatted string is too long.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t stringToI32(const char_t *str, int32_t *out) {
|
||||||
|
assertNotNull(str, "str must not be NULL");
|
||||||
|
assertNotNull(out, "out must not be NULL");
|
||||||
|
|
||||||
|
char_t *endptr;
|
||||||
|
errno = 0;
|
||||||
|
long int result = strtol(str, &endptr, 10);
|
||||||
|
if (errno != 0 || *endptr != '\0') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*out = (int32_t)result;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t stringToI64(const char_t *str, int64_t *out) {
|
||||||
|
assertNotNull(str, "str must not be NULL");
|
||||||
|
assertNotNull(out, "out must not be NULL");
|
||||||
|
|
||||||
|
char_t *endptr;
|
||||||
|
errno = 0;
|
||||||
|
long long int result = strtoll(str, &endptr, 10);
|
||||||
|
if (errno != 0 || *endptr != '\0') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*out = (int64_t)result;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t stringToU16(const char_t *str, uint16_t *out) {
|
||||||
|
assertNotNull(str, "str must not be NULL");
|
||||||
|
assertNotNull(out, "out must not be NULL");
|
||||||
|
|
||||||
|
char_t *endptr;
|
||||||
|
errno = 0;
|
||||||
|
unsigned long int result = strtoul(str, &endptr, 10);
|
||||||
|
if (errno != 0 || *endptr != '\0' || result > UINT16_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*out = (uint16_t)result;
|
||||||
|
return true;
|
||||||
|
}
|
109
src/dusk/util/string.h
Normal file
109
src/dusk/util/string.h
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a character is whitespace.
|
||||||
|
*
|
||||||
|
* @param c The character to check.
|
||||||
|
* @return TRUE if the character is whitespace, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
bool_t stringIsWhitespace(const char_t c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies a string from src to dest, ensuring the dest string is null-terminated
|
||||||
|
* and does not exceed the specified size.
|
||||||
|
*
|
||||||
|
* @param dest The destination string.
|
||||||
|
* @param src The source string.
|
||||||
|
* @param destSize The size of the destination string exc. null terminator.
|
||||||
|
*/
|
||||||
|
void stringCopy(char_t *dest, const char_t *src, const size_t destSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two strings.
|
||||||
|
*
|
||||||
|
* @param str1 The first string.
|
||||||
|
* @param str2 The second string.
|
||||||
|
* @return 0 if the strings are equal, -1 if str1 is less than str2, 1 if str1
|
||||||
|
* is greater than str2.
|
||||||
|
*/
|
||||||
|
int stringCompare(const char_t *str1, const char_t *str2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trims whitespace from the beginning and end of a string.
|
||||||
|
*
|
||||||
|
* @param str The string to trim.
|
||||||
|
*/
|
||||||
|
void stringTrim(char_t *str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the next token in a string using a delimiter.
|
||||||
|
* e.g. input: "Hello, World, Happy Monday!" with stringToken(input, ",") will
|
||||||
|
* return "Hello" then " World" then " Happy Monday!" on each subsequent call.
|
||||||
|
*
|
||||||
|
* @param str The string to split.
|
||||||
|
* @param delim The delimiter to split by.
|
||||||
|
* @return A pointer to the next token in the string.
|
||||||
|
*/
|
||||||
|
char_t * stringToken(char_t *str, const char_t *delim);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a string.
|
||||||
|
*
|
||||||
|
* @param dest The destination string.
|
||||||
|
* @param destSize The size of the destination string exc. null terminator.
|
||||||
|
* @param format The format string.
|
||||||
|
* @param ... The arguments to format.
|
||||||
|
* @return The number of characters written.
|
||||||
|
*/
|
||||||
|
int32_t stringFormat(char_t *dest, const size_t destSize, char_t *format, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a string using a va_list.
|
||||||
|
*
|
||||||
|
* @param dest The destination string.
|
||||||
|
* @param destSize The size of the destination string exc. null terminator.
|
||||||
|
* @param format The format string.
|
||||||
|
* @param args The va_list of arguments.
|
||||||
|
* @return The number of characters written.
|
||||||
|
*/
|
||||||
|
int32_t stringFormatVA(
|
||||||
|
char_t *dest,
|
||||||
|
const size_t destSize,
|
||||||
|
const char_t *format,
|
||||||
|
va_list args
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a string to an integer.
|
||||||
|
*
|
||||||
|
* @param str The string to convert.
|
||||||
|
* @param out The output integer.
|
||||||
|
* @return TRUE if the conversion was successful, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
bool_t stringToI32(const char_t *str, int32_t *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a string to a signed 16-bit integer.
|
||||||
|
*
|
||||||
|
* @param str The string to convert.
|
||||||
|
* @param out The output signed integer.
|
||||||
|
* @return TRUE if the conversion was successful, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
bool_t stringToI16(const char_t *str, int16_t *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a string to an unsigned 16-bit integer.
|
||||||
|
*
|
||||||
|
* @param str The string to convert.
|
||||||
|
* @param out The output unsigned integer.
|
||||||
|
* @return TRUE if the conversion was successful, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
bool_t stringToU16(const char_t *str, uint16_t *out);
|
29
src/duskpsp/CMakeLists.txt
Normal file
29
src/duskpsp/CMakeLists.txt
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Libs
|
||||||
|
find_package(pspsdk REQUIRED)
|
||||||
|
|
||||||
|
target_link_libraries(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
pspsdk
|
||||||
|
)
|
||||||
|
|
||||||
|
# Includes
|
||||||
|
target_include_directories(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
input.c
|
||||||
|
main.c
|
||||||
|
duskpsp.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Subdirs
|
||||||
|
add_subdirectory(display)
|
12
src/duskpsp/display/CMakeLists.txt
Normal file
12
src/duskpsp/display/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
render.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Subdirs
|
42
src/duskpsp/display/render.c
Normal file
42
src/duskpsp/display/render.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "render.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
void renderInit(void) {
|
||||||
|
pspDebugScreenInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderDraw(void) {
|
||||||
|
sceDisplayWaitVblankStart();
|
||||||
|
pspDebugScreenSetXY(0, 2);
|
||||||
|
|
||||||
|
pspDebugScreenPrintf("Checking buttons \n");
|
||||||
|
if(inputIsDown(INPUT_BIND_UP)) {
|
||||||
|
pspDebugScreenPrintf("Up pressed\n");
|
||||||
|
}
|
||||||
|
if(inputIsDown(INPUT_BIND_DOWN)) {
|
||||||
|
pspDebugScreenPrintf("Down pressed\n");
|
||||||
|
}
|
||||||
|
if(inputIsDown(INPUT_BIND_LEFT)) {
|
||||||
|
pspDebugScreenPrintf("Left pressed\n");
|
||||||
|
}
|
||||||
|
if(inputIsDown(INPUT_BIND_RIGHT)) {
|
||||||
|
pspDebugScreenPrintf("Right pressed\n");
|
||||||
|
}
|
||||||
|
if(inputIsDown(INPUT_BIND_ACTION)) {
|
||||||
|
pspDebugScreenPrintf("Action pressed\n");
|
||||||
|
}
|
||||||
|
if(inputIsDown(INPUT_BIND_CANCEL)) {
|
||||||
|
pspDebugScreenPrintf("Cancel pressed\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderDispose(void) {
|
||||||
|
|
||||||
|
}
|
10
src/duskpsp/display/render.h
Normal file
10
src/duskpsp/display/render.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "duskpsp.h"
|
||||||
|
#include "display/renderbase.h"
|
11
src/duskpsp/duskpsp.c
Normal file
11
src/duskpsp/duskpsp.c
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "duskpsp.h"
|
||||||
|
|
||||||
|
PSP_MODULE_INFO("Dusk", 0, 1, 0);
|
||||||
|
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | THREAD_ATTR_VFPU);
|
13
src/duskpsp/duskpsp.h
Normal file
13
src/duskpsp/duskpsp.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dusk.h"
|
||||||
|
#include <pspkernel.h>
|
||||||
|
#include <pspdebug.h>
|
||||||
|
#include <pspdisplay.h>
|
||||||
|
#include <pspctrl.h>
|
27
src/duskpsp/input.c
Normal file
27
src/duskpsp/input.c
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "duskpsp.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
uint8_t inputStateGet() {
|
||||||
|
SceCtrlData pad;
|
||||||
|
sceCtrlReadBufferPositive(&pad, 1);
|
||||||
|
|
||||||
|
if(pad.Buttons == 0) return 0;
|
||||||
|
|
||||||
|
uint8_t state = 0;
|
||||||
|
if(pad.Buttons & PSP_CTRL_UP) state |= INPUT_BIND_UP;
|
||||||
|
if(pad.Buttons & PSP_CTRL_DOWN) state |= INPUT_BIND_DOWN;
|
||||||
|
if(pad.Buttons & PSP_CTRL_LEFT) state |= INPUT_BIND_LEFT;
|
||||||
|
if(pad.Buttons & PSP_CTRL_RIGHT) state |= INPUT_BIND_RIGHT;
|
||||||
|
|
||||||
|
if(pad.Buttons & PSP_CTRL_CROSS) state |= INPUT_BIND_ACTION;
|
||||||
|
if(pad.Buttons & PSP_CTRL_CIRCLE) state |= INPUT_BIND_CANCEL;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
46
src/duskpsp/main.c
Normal file
46
src/duskpsp/main.c
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "display/render.h"
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
int_t exit_callback(int arg1, int arg2, void *common) {
|
||||||
|
sceKernelExitGame();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int_t callback_thread(SceSize args, void *argp) {
|
||||||
|
int cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
|
||||||
|
sceKernelRegisterExitCallback(cbid);
|
||||||
|
sceKernelSleepThreadCB();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int_t setup_callbacks(void) {
|
||||||
|
int thid = sceKernelCreateThread("update_thread", callback_thread, 0x11, 0xFA0, 0, 0);
|
||||||
|
if(thid >= 0) {
|
||||||
|
sceKernelStartThread(thid, 0, 0);
|
||||||
|
}
|
||||||
|
return thid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
setup_callbacks();
|
||||||
|
renderInit();
|
||||||
|
gameInit();
|
||||||
|
|
||||||
|
sceCtrlSetSamplingCycle(0);
|
||||||
|
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
gameUpdate();
|
||||||
|
renderDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
gameDispose();
|
||||||
|
renderDispose();
|
||||||
|
}
|
@@ -3,15 +3,8 @@
|
|||||||
# This software is released under the MIT License.
|
# This software is released under the MIT License.
|
||||||
# https://opensource.org/licenses/MIT
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
include(FetchContent)
|
|
||||||
|
|
||||||
# Libs
|
# Libs
|
||||||
FetchContent_Declare(
|
find_package(raylib REQUIRED)
|
||||||
raylib
|
|
||||||
URL https://github.com/raysan5/raylib/archive/refs/tags/5.5.tar.gz
|
|
||||||
URL_HASH MD5=61638c4c2c097fbca1d6a71e4da36c16
|
|
||||||
)
|
|
||||||
FetchContent_MakeAvailable(raylib)
|
|
||||||
|
|
||||||
target_link_libraries(${DUSK_TARGET_NAME}
|
target_link_libraries(${DUSK_TARGET_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
|
@@ -87,7 +87,3 @@ void renderDispose(void) {
|
|||||||
UnloadTexture(RENDER_ENTITIES_TEXTURE);
|
UnloadTexture(RENDER_ENTITIES_TEXTURE);
|
||||||
CloseWindow();
|
CloseWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t renderShouldExit() {
|
|
||||||
return WindowShouldClose();
|
|
||||||
}
|
|
21
src/duskraylib/main.c
Normal file
21
src/duskraylib/main.c
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "display/render.h"
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
gameInit();
|
||||||
|
|
||||||
|
while(!WindowShouldClose()) {
|
||||||
|
gameUpdate();
|
||||||
|
renderDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
gameDispose();
|
||||||
|
renderDispose();
|
||||||
|
}
|
Reference in New Issue
Block a user