New basic console
This commit is contained in:
		@@ -3,6 +3,5 @@
 | 
				
			|||||||
# 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_subdirectory(dusk)
 | 
					add_subdirectory(dusktest)
 | 
				
			||||||
add_subdirectory(duskgl)
 | 
					add_subdirectory(dusk)
 | 
				
			||||||
add_subdirectory(duskglfw)
 | 
					 | 
				
			||||||
@@ -17,12 +17,10 @@ target_include_directories(${DUSK_TARGET_NAME}
 | 
				
			|||||||
# Sources
 | 
					# Sources
 | 
				
			||||||
target_sources(${DUSK_TARGET_NAME}
 | 
					target_sources(${DUSK_TARGET_NAME}
 | 
				
			||||||
  PRIVATE
 | 
					  PRIVATE
 | 
				
			||||||
    game.c
 | 
					 | 
				
			||||||
    input.c
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Subdirs
 | 
					# Subdirs
 | 
				
			||||||
add_subdirectory(assert)
 | 
					add_subdirectory(assert)
 | 
				
			||||||
add_subdirectory(display)
 | 
					add_subdirectory(console)
 | 
				
			||||||
add_subdirectory(overworld)
 | 
					add_subdirectory(error)
 | 
				
			||||||
add_subdirectory(util)
 | 
					add_subdirectory(util)
 | 
				
			||||||
@@ -122,7 +122,7 @@ void assertMemoryRangeMatchesImpl(
 | 
				
			|||||||
#define assertDeprecated(message) \
 | 
					#define assertDeprecated(message) \
 | 
				
			||||||
  assertDeprecatedImpl(__FILE__, __LINE__, message)
 | 
					  assertDeprecatedImpl(__FILE__, __LINE__, message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define assertStrLen(str, len, message) \
 | 
					#define assertStrLenMax(str, len, message) \
 | 
				
			||||||
  assertTrue(strlen(str) <= len, message)
 | 
					  assertTrue(strlen(str) <= len, message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define assertStrLenMin(str, len, message) \
 | 
					#define assertStrLenMin(str, len, message) \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,8 +6,7 @@
 | 
				
			|||||||
# Sources
 | 
					# Sources
 | 
				
			||||||
target_sources(${DUSK_TARGET_NAME}
 | 
					target_sources(${DUSK_TARGET_NAME}
 | 
				
			||||||
  PRIVATE
 | 
					  PRIVATE
 | 
				
			||||||
    scene.c
 | 
					    console.c
 | 
				
			||||||
    tileset.c
 | 
					    consolecmd.c
 | 
				
			||||||
)
 | 
					    consolevar.c
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
# Subdirs
 | 
					 | 
				
			||||||
							
								
								
									
										224
									
								
								src/dusk/console/console.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								src/dusk/console/console.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,224 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 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"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					console_t CONSOLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void consoleInit() {
 | 
				
			||||||
 | 
					  memoryZero(&CONSOLE, sizeof(console_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Register the get and set command.
 | 
				
			||||||
 | 
					  CONSOLE.cmdGet = consoleRegCmd("get", consoleCmdGet);
 | 
				
			||||||
 | 
					  CONSOLE.cmdSet = consoleRegCmd("set", consoleCmdSet);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					consolecmd_t * consoleRegCmd(const char_t *name, consolecmdfunc_t function) {
 | 
				
			||||||
 | 
					  consolecmd_t *cmd = &CONSOLE.commands[CONSOLE.commandCount++];
 | 
				
			||||||
 | 
					  consoleCmdInit(cmd, name, function);
 | 
				
			||||||
 | 
					  return cmd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					consolevar_t * consoleRegVar(
 | 
				
			||||||
 | 
					  const char_t *name,
 | 
				
			||||||
 | 
					  const char_t *value,
 | 
				
			||||||
 | 
					  consolevarchanged_t event
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					  consolevar_t *var = &CONSOLE.variables[CONSOLE.variableCount++];
 | 
				
			||||||
 | 
					  consoleVarInitListener(var, name, value, event);
 | 
				
			||||||
 | 
					  return var;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void consolePrint(const char_t *message, ...) {
 | 
				
			||||||
 | 
					  char_t buffer[CONSOLE_LINE_MAX];
 | 
				
			||||||
 | 
					  va_list args;
 | 
				
			||||||
 | 
					  va_start(args, message);
 | 
				
			||||||
 | 
					  size_t len = vsnprintf(buffer, CONSOLE_LINE_MAX, message, args);
 | 
				
			||||||
 | 
					  va_end(args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assertTrue(len < CONSOLE_LINE_MAX, "Message is too long.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 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) {
 | 
				
			||||||
 | 
					  assertNotNull(line, "line must not be NULL");
 | 
				
			||||||
 | 
					  assertTrue(
 | 
				
			||||||
 | 
					    CONSOLE.execBufferCount < CONSOLE_EXEC_BUFFER_MAX,
 | 
				
			||||||
 | 
					    "Too many commands in the buffer."
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(line[0] == '\0') return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char_t buffer[CONSOLE_LINE_MAX + 1];
 | 
				
			||||||
 | 
					  size_t i = 0, j = 0;
 | 
				
			||||||
 | 
					  char_t c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  do {
 | 
				
			||||||
 | 
					    c = line[i++];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Handle command separation by semicolon or end of line
 | 
				
			||||||
 | 
					    if(c == ';' || c == '\0') {
 | 
				
			||||||
 | 
					      // Null-terminate the current command and trim whitespace
 | 
				
			||||||
 | 
					      buffer[j] = '\0';
 | 
				
			||||||
 | 
					      stringTrim(buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Skip empty commands
 | 
				
			||||||
 | 
					      if(buffer[0] == '\0') {
 | 
				
			||||||
 | 
					        j = 0;
 | 
				
			||||||
 | 
					        continue;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Ensure the exec buffer is not full
 | 
				
			||||||
 | 
					      assertTrue(
 | 
				
			||||||
 | 
					        CONSOLE.execBufferCount < CONSOLE_EXEC_BUFFER_MAX,
 | 
				
			||||||
 | 
					        "Too many commands in the buffer."
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Create a new command execution
 | 
				
			||||||
 | 
					      consolecmdexec_t *exec = &CONSOLE.execBuffer[CONSOLE.execBufferCount++];
 | 
				
			||||||
 | 
					      memoryZero(exec, sizeof(consolecmdexec_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Parse command and arguments
 | 
				
			||||||
 | 
					      char_t *token = strtok(buffer, " ");
 | 
				
			||||||
 | 
					      while(token != NULL) {
 | 
				
			||||||
 | 
					        assertTrue(
 | 
				
			||||||
 | 
					          exec->argc < CONSOLE_CMD_ARGC_MAX,
 | 
				
			||||||
 | 
					          "Too many arguments in the command."
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        stringCopy(exec->argv[exec->argc++], token, CONSOLE_LINE_MAX);
 | 
				
			||||||
 | 
					        token = strtok(NULL, " ");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // First, see if there's a matching command.
 | 
				
			||||||
 | 
					      for(uint32_t k = 0; k < CONSOLE.commandCount; k++) {
 | 
				
			||||||
 | 
					        if(stringCompare(CONSOLE.commands[k].name, exec->argv[0]) != 0) {
 | 
				
			||||||
 | 
					          continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        exec->cmd = &CONSOLE.commands[k];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // If match found continue
 | 
				
			||||||
 | 
					      if(exec->cmd != NULL) {
 | 
				
			||||||
 | 
					        j = 0;
 | 
				
			||||||
 | 
					        continue;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // If no match found, see if there's a matching variable.
 | 
				
			||||||
 | 
					      consolevar_t *var = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      for(uint32_t k = 0; k < CONSOLE.variableCount; k++) {
 | 
				
			||||||
 | 
					        if(stringCompare(CONSOLE.variables[k].name, exec->argv[0]) != 0) {
 | 
				
			||||||
 | 
					          continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var = &CONSOLE.variables[k];
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // If no variable found, error out.
 | 
				
			||||||
 | 
					      if(!var) {
 | 
				
			||||||
 | 
					        consolePrint("Error: Command/Variable '%s' not found.", exec->argv[0]);
 | 
				
			||||||
 | 
					        CONSOLE.execBufferCount--;
 | 
				
			||||||
 | 
					        j = 0;
 | 
				
			||||||
 | 
					        continue;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Found a matching variable, we basically change this entire command
 | 
				
			||||||
 | 
					      // to a get or a set. Arguments are reversed so they aren't stepped over
 | 
				
			||||||
 | 
					      if(exec->argc == 1) {
 | 
				
			||||||
 | 
					        exec->cmd = CONSOLE.cmdGet;
 | 
				
			||||||
 | 
					        exec->argc = 2;
 | 
				
			||||||
 | 
					        stringCopy(exec->argv[1], var->name, CONSOLE_LINE_MAX);
 | 
				
			||||||
 | 
					        stringCopy(exec->argv[0], CONSOLE.cmdGet->name, CONSOLE_LINE_MAX);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        exec->cmd = CONSOLE.cmdSet;
 | 
				
			||||||
 | 
					        exec->argc = 3;
 | 
				
			||||||
 | 
					        stringCopy(exec->argv[2], exec->argv[1], CONSOLE_LINE_MAX);
 | 
				
			||||||
 | 
					        stringCopy(exec->argv[1], var->name, CONSOLE_LINE_MAX);
 | 
				
			||||||
 | 
					        stringCopy(exec->argv[0], CONSOLE.cmdSet->name, CONSOLE_LINE_MAX);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      j = 0;
 | 
				
			||||||
 | 
					      continue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(j >= CONSOLE_LINE_MAX) {
 | 
				
			||||||
 | 
					      assertTrue(false, "Command exceeds maximum length.");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buffer[j++] = c; // Accumulate characters into the buffer
 | 
				
			||||||
 | 
					  } while(c != '\0');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void consoleProcess() {
 | 
				
			||||||
 | 
					  for(uint32_t i = 0; i < CONSOLE.execBufferCount; i++) {
 | 
				
			||||||
 | 
					    consolecmdexec_t *exec = &CONSOLE.execBuffer[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assertTrue(
 | 
				
			||||||
 | 
					      exec->argc > 0,
 | 
				
			||||||
 | 
					      "Command execution has no arguments."
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    assertNotNull(
 | 
				
			||||||
 | 
					      exec->cmd,
 | 
				
			||||||
 | 
					      "Command execution has no command."
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    exec->cmd->function(exec);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Clear the exec buffer
 | 
				
			||||||
 | 
					  CONSOLE.execBufferCount = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void consoleCmdGet(const consolecmdexec_t *exec) {
 | 
				
			||||||
 | 
					  assertTrue(
 | 
				
			||||||
 | 
					    exec->argc >= 2,
 | 
				
			||||||
 | 
					    "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[1]) != 0) continue;
 | 
				
			||||||
 | 
					    consolePrint("%s", var->value);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  consolePrint("Error: Variable '%s' not found.", exec->argv[1]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void consoleCmdSet(const consolecmdexec_t *exec) {
 | 
				
			||||||
 | 
					  assertTrue(
 | 
				
			||||||
 | 
					    exec->argc >= 3,
 | 
				
			||||||
 | 
					    "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[1]) != 0) continue;
 | 
				
			||||||
 | 
					    consoleVarSetValue(var, exec->argv[2]);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  consolePrint("Error: Variable '%s' not found.", exec->argv[1]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										95
									
								
								src/dusk/console/console.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/dusk/console/console.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 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 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;
 | 
				
			||||||
 | 
					} 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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Gets the value of a console variable.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @param name The name of the variable.
 | 
				
			||||||
 | 
					 * @return The value of the variable.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void consoleCmdGet(const consolecmdexec_t *exec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Sets the value of a console variable.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @param name The name of the variable.
 | 
				
			||||||
 | 
					 * @param value The new value of the variable.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void consoleCmdSet(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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								src/dusk/console/consolecmd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/dusk/console/consolecmd.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 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 {
 | 
				
			||||||
 | 
					  const consolecmd_t *cmd;
 | 
				
			||||||
 | 
					  uint32_t argc;
 | 
				
			||||||
 | 
					  char_t argv[CONSOLE_CMD_ARGC_MAX][CONSOLE_LINE_MAX];
 | 
				
			||||||
 | 
					} consolecmdexec_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void (*consolecmdfunc_t)(const consolecmdexec_t *exec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct consolecmd_s {
 | 
				
			||||||
 | 
					  char_t name[CONSOLE_CMD_NAME_MAX + 1];
 | 
				
			||||||
 | 
					  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 + 1];
 | 
				
			||||||
 | 
					  char_t value[CONSOLE_VAR_VALUE_MAX + 1];
 | 
				
			||||||
 | 
					  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);
 | 
				
			||||||
@@ -1,9 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SCREEN_WIDTH 320
 | 
					 | 
				
			||||||
#define SCREEN_HEIGHT 240
 | 
					 | 
				
			||||||
@@ -1,65 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "scene.h"
 | 
					 | 
				
			||||||
#include "assert/assert.h"
 | 
					 | 
				
			||||||
#include "util/memory.h"
 | 
					 | 
				
			||||||
#include "overworld/overworld.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
scenetypecallback_t SCENE_CALLBACKS[] = {
 | 
					 | 
				
			||||||
  // SCENE_TYPE_INITIAL
 | 
					 | 
				
			||||||
  { NULL, NULL, NULL, NULL, NULL },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // SCENE_TYPE_OVERWORLD
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    overworldInit,
 | 
					 | 
				
			||||||
    overworldSceneInit,
 | 
					 | 
				
			||||||
    overworldSceneDeinit,
 | 
					 | 
				
			||||||
    overworldUpdate,
 | 
					 | 
				
			||||||
    overworldRender
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
scene_t SCENE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void sceneInit() {
 | 
					 | 
				
			||||||
  memoryZero(&SCENE, sizeof(scene_t));
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  for(uint8_t i = 0; i < SCENE_TYPE_COUNT; i++) {
 | 
					 | 
				
			||||||
    if(SCENE_CALLBACKS[i].onInit) SCENE_CALLBACKS[i].onInit();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  sceneSet(SCENE_TYPE_OVERWORLD);// Testing
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void sceneUpdate() {
 | 
					 | 
				
			||||||
  assertTrue(SCENE.current < SCENE_TYPE_COUNT, "Invalid Scene Type");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if(SCENE.next != SCENE.current) {
 | 
					 | 
				
			||||||
    SCENE.current = SCENE.next;
 | 
					 | 
				
			||||||
    if(SCENE_CALLBACKS[SCENE.current].onActive) {
 | 
					 | 
				
			||||||
      SCENE_CALLBACKS[SCENE.current].onActive();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if(SCENE_CALLBACKS[SCENE.current].onUpdate) {
 | 
					 | 
				
			||||||
    SCENE_CALLBACKS[SCENE.current].onUpdate();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void sceneRender() {
 | 
					 | 
				
			||||||
  assertTrue(SCENE.current < SCENE_TYPE_COUNT, "Invalid Scene Type");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if(SCENE_CALLBACKS[SCENE.current].onRender) {
 | 
					 | 
				
			||||||
    SCENE_CALLBACKS[SCENE.current].onRender();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void sceneSet(const scenetype_t scene) {
 | 
					 | 
				
			||||||
  assertTrue(SCENE.next < SCENE_TYPE_COUNT, "Invalid Scene Type");
 | 
					 | 
				
			||||||
  SCENE.next = scene;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,58 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "dusk.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum {
 | 
					 | 
				
			||||||
  SCENE_TYPE_INITIAL,
 | 
					 | 
				
			||||||
  SCENE_TYPE_OVERWORLD,
 | 
					 | 
				
			||||||
} scenetype_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SCENE_TYPE_COUNT 2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
  scenetype_t current;
 | 
					 | 
				
			||||||
  scenetype_t next;
 | 
					 | 
				
			||||||
} scene_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
  void (*onInit)();
 | 
					 | 
				
			||||||
  void (*onActive)();
 | 
					 | 
				
			||||||
  void (*onInactive)();
 | 
					 | 
				
			||||||
  void (*onUpdate)();
 | 
					 | 
				
			||||||
  void (*onRender)();
 | 
					 | 
				
			||||||
} scenetypecallback_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern scene_t SCENE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Initializes the scene system.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void sceneInit();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Updates the scene system.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void sceneUpdate();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Renders the scene system.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * Scene rendering is really just an abstraction meant to simplify things for
 | 
					 | 
				
			||||||
 * the render host. It is not REQUIRED to be called at all and is not actually
 | 
					 | 
				
			||||||
 * implemented in the dusk dir itself, it is overriden somewhere within the
 | 
					 | 
				
			||||||
 * render host.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void sceneRender();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Sets the current scene. This will happen at the start of the next tick.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param scene The scene to set.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void sceneSet(const scenetype_t scene);
 | 
					 | 
				
			||||||
@@ -1,34 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "tileset.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
tileset_t TILESETS[TILESET_COUNT] = {
 | 
					 | 
				
			||||||
  // TILESET_NULL
 | 
					 | 
				
			||||||
  { 0, 0 },
 | 
					 | 
				
			||||||
  // TILESET_FONT
 | 
					 | 
				
			||||||
  { 16, 14 }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
tilesetid_t TILESET_SLOTS[TILESET_SLOT_COUNT] = {
 | 
					 | 
				
			||||||
  TILESET_NULL,
 | 
					 | 
				
			||||||
  TILESET_NULL,
 | 
					 | 
				
			||||||
  TILESET_NULL,
 | 
					 | 
				
			||||||
  TILESET_NULL
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint8_t tilesetGetSlot(const tilesetid_t id) {
 | 
					 | 
				
			||||||
  uint8_t i = 0;
 | 
					 | 
				
			||||||
  do {
 | 
					 | 
				
			||||||
    if(TILESET_SLOTS[i] == id) return i;
 | 
					 | 
				
			||||||
  } while(++i < TILESET_SLOT_COUNT);
 | 
					 | 
				
			||||||
  return 0xFF;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool_t tilesetIsBound(const tilesetid_t id) {
 | 
					 | 
				
			||||||
  return tilesetGetSlot(id) != 0xFF;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,53 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "dusk.h"
 | 
					 | 
				
			||||||
#include "tilesetdefs.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum {
 | 
					 | 
				
			||||||
  TILESET_NULL,
 | 
					 | 
				
			||||||
  TILESET_FONT
 | 
					 | 
				
			||||||
} tilesetid_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TILESET_COUNT 2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
  uint8_t columns;
 | 
					 | 
				
			||||||
  uint8_t rows;
 | 
					 | 
				
			||||||
} tileset_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern tileset_t TILESETS[];
 | 
					 | 
				
			||||||
extern tilesetid_t TILESET_SLOTS[];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Binds a tileset to a slot. The host can also use this to say load a texture,
 | 
					 | 
				
			||||||
 * or upload to VRAM.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This does not guarantee anything on the game side, rendering is responsible
 | 
					 | 
				
			||||||
 * for handling anything visual.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param id The tileset to bind.
 | 
					 | 
				
			||||||
 * @param slot The slot to bind the tileset to.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void tilesetBind(const tilesetid_t id, const uint8_t slot);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Gets the slot that a tileset is bound to, or 0xFF if not bound.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param id The tileset to check.
 | 
					 | 
				
			||||||
 * @return The slot the tileset is bound to, or 0xFF if not bound.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
uint8_t tilesetGetSlot(const tilesetid_t id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Checks if a tileset is bound to a slot.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param id The tileset to check.
 | 
					 | 
				
			||||||
 * @return TRUE if the tileset is bound, FALSE otherwise.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
bool_t tilesetIsBound(const tilesetid_t id);
 | 
					 | 
				
			||||||
@@ -1,17 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TILESET_SLOT_0 0
 | 
					 | 
				
			||||||
#define TILESET_SLOT_1 1
 | 
					 | 
				
			||||||
#define TILESET_SLOT_2 2
 | 
					 | 
				
			||||||
#define TILESET_SLOT_3 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TILESET_SLOT_UI TILESET_SLOT_0
 | 
					 | 
				
			||||||
#define TILESET_SLOT_ENTITIES TILESET_SLOT_1
 | 
					 | 
				
			||||||
#define TILESET_SLOT_MAP TILESET_SLOT_2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TILESET_SLOT_COUNT 4
 | 
					 | 
				
			||||||
@@ -14,6 +14,7 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdarg.h>
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include <ctype.h>
 | 
				
			||||||
typedef bool bool_t;
 | 
					typedef bool bool_t;
 | 
				
			||||||
typedef char char_t;
 | 
					typedef char char_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,8 +6,5 @@
 | 
				
			|||||||
# Sources
 | 
					# Sources
 | 
				
			||||||
target_sources(${DUSK_TARGET_NAME}
 | 
					target_sources(${DUSK_TARGET_NAME}
 | 
				
			||||||
  PRIVATE
 | 
					  PRIVATE
 | 
				
			||||||
    tile.c
 | 
					    error.c
 | 
				
			||||||
    map.c
 | 
					)
 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Subdirs
 | 
					 | 
				
			||||||
							
								
								
									
										45
									
								
								src/dusk/error/error.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/dusk/error/error.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright (c) 2025 Dominic Masters
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This software is released under the MIT License.
 | 
				
			||||||
 | 
					 * https://opensource.org/licenses/MIT
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "error.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					errorstack_t ERROR_STACK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					errorret_t error(const char_t *message, ...) {
 | 
				
			||||||
 | 
					  return errorCode(1, message);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					errorret_t errorCode(const errorret_t code, const char_t *message, ...) {
 | 
				
			||||||
 | 
					  if(ERROR_STACK.code != ERROR_OK) {
 | 
				
			||||||
 | 
					    snprintf(
 | 
				
			||||||
 | 
					      ERROR_STACK.message,
 | 
				
			||||||
 | 
					      ERROR_STACK_SIZE,
 | 
				
			||||||
 | 
					      "Multiple errors encountered."
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    errorPrint();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  va_list args;
 | 
				
			||||||
 | 
					  va_start(args, message);
 | 
				
			||||||
 | 
					  vsnprintf(ERROR_STACK.message, ERROR_STACK_SIZE, message, args);
 | 
				
			||||||
 | 
					  va_end(args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return ERROR_STACK.code = code;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool_t errorCheck() {
 | 
				
			||||||
 | 
					  return ERROR_STACK.code != ERROR_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					errorret_t errorPrint() {
 | 
				
			||||||
 | 
					  if(ERROR_STACK.code == ERROR_OK) return ERROR_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("Error: %s\n", ERROR_STACK.message);
 | 
				
			||||||
 | 
					  errorret_t code = ERROR_STACK.code;
 | 
				
			||||||
 | 
					  ERROR_STACK.code = ERROR_OK;
 | 
				
			||||||
 | 
					  return code;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										50
									
								
								src/dusk/error/error.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/dusk/error/error.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright (c) 2025 Dominic Masters
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This software is released under the MIT License.
 | 
				
			||||||
 | 
					 * https://opensource.org/licenses/MIT
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include "dusk.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef int32_t errorret_t;
 | 
				
			||||||
 | 
					#define ERROR_OK 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ERROR_STACK_SIZE 256
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  char_t message[ERROR_STACK_SIZE + 1];
 | 
				
			||||||
 | 
					  errorret_t code;
 | 
				
			||||||
 | 
					} errorstack_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern errorstack_t ERROR_STACK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Pushes an error message to the error stack.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @param message Message to push to the error stack.
 | 
				
			||||||
 | 
					 * @param ... Arguments to format the message with.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					errorret_t error(const char_t *message, ...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Pushes an error message to the error stack with a given error code.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @param code Error code to push to the error stack.
 | 
				
			||||||
 | 
					 * @param message Message to push to the error stack.
 | 
				
			||||||
 | 
					 * @param ... Arguments to format the message with.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					errorret_t errorCode(const errorret_t code, const char_t *message, ...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Checks if an error has been pushed to the error stack.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @return True if an error has been pushed to the error stack.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool_t errorCheck();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Prints the error stack to the console. This also clears the error stack.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					errorret_t errorPrint();
 | 
				
			||||||
@@ -1,31 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "game.h"
 | 
					 | 
				
			||||||
#include "input.h"
 | 
					 | 
				
			||||||
#include "display/scene.h"
 | 
					 | 
				
			||||||
#include "util/memory.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
game_t GAME;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void gameInit() {
 | 
					 | 
				
			||||||
  memoryZero(&GAME, sizeof(game_t));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  inputInit();
 | 
					 | 
				
			||||||
  sceneInit();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void gameUpdate() {
 | 
					 | 
				
			||||||
  GAME.tick++;
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  inputUpdate();
 | 
					 | 
				
			||||||
  sceneUpdate();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void gameDispose() {
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,35 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "dusk.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define GAME_TICK_RATE 60
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
  uint32_t tick;
 | 
					 | 
				
			||||||
} game_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern game_t GAME;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Initializes the game.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void gameInit();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Updates the game. The game is setup to handle "frames", aka 1/60th of a 
 | 
					 | 
				
			||||||
 * second. Typically more modern engines would use floats to tick game engine
 | 
					 | 
				
			||||||
 * by a semi random delta time, but this engine is intended to work on really
 | 
					 | 
				
			||||||
 * weak machines so we take the simple approach.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void gameUpdate();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Disposes the game.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void gameDispose();
 | 
					 | 
				
			||||||
@@ -1,37 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "input.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
inputstate_t INPUT_CURRENT;
 | 
					 | 
				
			||||||
inputstate_t INPUT_LAST_FRAME;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void inputInit() {
 | 
					 | 
				
			||||||
  INPUT_CURRENT = 0;
 | 
					 | 
				
			||||||
  INPUT_LAST_FRAME = 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void inputUpdate() {
 | 
					 | 
				
			||||||
  INPUT_LAST_FRAME = INPUT_CURRENT;
 | 
					 | 
				
			||||||
  INPUT_CURRENT = inputPlatformState();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool_t inputWasPressed(const inputstate_t state) {
 | 
					 | 
				
			||||||
  return (INPUT_LAST_FRAME & state) == 0 && (INPUT_CURRENT & state) != 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool_t inputWasReleased(const inputstate_t state) {
 | 
					 | 
				
			||||||
  return (INPUT_LAST_FRAME & state) != 0 && (INPUT_CURRENT & state) == 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool_t inputIsDown(const inputstate_t state) {
 | 
					 | 
				
			||||||
  return (INPUT_CURRENT & state) != 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool_t inputIsUp(const inputstate_t state) {
 | 
					 | 
				
			||||||
  return (INPUT_CURRENT & state) == 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,71 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "dusk.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef uint16_t inputstate_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define INPUT_MENU (1 << 0)
 | 
					 | 
				
			||||||
#define INPUT_UP (1 << 1)
 | 
					 | 
				
			||||||
#define INPUT_DOWN (1 << 2)
 | 
					 | 
				
			||||||
#define INPUT_LEFT (1 << 3)
 | 
					 | 
				
			||||||
#define INPUT_RIGHT (1 << 4)
 | 
					 | 
				
			||||||
#define INPUT_ACCEPT (1 << 5)
 | 
					 | 
				
			||||||
#define INPUT_BACK (1 << 6)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern inputstate_t INPUT_CURRENT;
 | 
					 | 
				
			||||||
extern inputstate_t INPUT_LAST_FRAME;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Initializes the input system
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void inputInit();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Updates the input system for this tick.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void inputUpdate();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Requests the platform let us know the current state of each input.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @return Current input state.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
inputstate_t inputPlatformState();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns true if the input was pressed this frame, but not last frame.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param state Inputs to check, typically a single input.
 | 
					 | 
				
			||||||
 * @return True if input was pressed this frame but not last frame.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
bool_t inputWasPressed(const inputstate_t state);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns true if the input was released this frame, but pressed last frame.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param state Inputs to check, typically a single input.
 | 
					 | 
				
			||||||
 * @return True if input was released this frame but was pressed last frame.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
bool_t inputWasReleased(const inputstate_t state);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns true if the input is currently pressed.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param state Inputs to check, typically a single input.
 | 
					 | 
				
			||||||
 * @return True if input is currently pressed.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
bool_t inputIsDown(const inputstate_t state);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns true if the input is currently released.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param state Inputs to check, typically a single input.
 | 
					 | 
				
			||||||
 * @return True if input is currently released.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
bool_t inputIsUp(const inputstate_t state);
 | 
					 | 
				
			||||||
@@ -1,14 +0,0 @@
 | 
				
			|||||||
# 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
 | 
					 | 
				
			||||||
    overworld.c
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Subdirs
 | 
					 | 
				
			||||||
add_subdirectory(entity)
 | 
					 | 
				
			||||||
add_subdirectory(map)
 | 
					 | 
				
			||||||
@@ -1,150 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "entity.h"
 | 
					 | 
				
			||||||
#include "assert/assert.h"
 | 
					 | 
				
			||||||
#include "util/memory.h"
 | 
					 | 
				
			||||||
#include "overworld/overworld.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = {
 | 
					 | 
				
			||||||
  { NULL, NULL, NULL },
 | 
					 | 
				
			||||||
  { playerInit, playerUpdate, NULL },
 | 
					 | 
				
			||||||
  { npcInit, npcUpdate, npcInteract }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
entity_t ENTITY_TEST;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void entityInit(
 | 
					 | 
				
			||||||
  entity_t *ent,
 | 
					 | 
				
			||||||
  const entitytype_t type
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  assertNotNull(ent, "Entity cannot be NULL");
 | 
					 | 
				
			||||||
  assertTrue(type < ENTITY_TYPE_COUNT, "Invalid entity type");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Init values
 | 
					 | 
				
			||||||
  memoryZero(ent, sizeof(entity_t));
 | 
					 | 
				
			||||||
  ent->type = type;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Call init
 | 
					 | 
				
			||||||
  assertNotNull(ENTITY_CALLBACKS[type].init, "Entity type init callback err.");
 | 
					 | 
				
			||||||
  ENTITY_CALLBACKS[type].init(ent);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  entityTurn(ent, FACING_DIRECTION_SOUTH);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void entityUpdate(entity_t *ent) {
 | 
					 | 
				
			||||||
  assertNotNull(ent, "Entity cannot be NULL");
 | 
					 | 
				
			||||||
  assertTrue(ent->type < ENTITY_TYPE_COUNT, "Invalid entity type");
 | 
					 | 
				
			||||||
  assertNotNull(ENTITY_CALLBACKS[ent->type].update, "Entity type update err.");
 | 
					 | 
				
			||||||
  ENTITY_CALLBACKS[ent->type].update(ent);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Handle moving
 | 
					 | 
				
			||||||
  if(ent->subX > 0) {
 | 
					 | 
				
			||||||
    ent->subX -= ENTITY_MOVE_SPEED;
 | 
					 | 
				
			||||||
    if(ent->subX < 0) ent->subX = 0;
 | 
					 | 
				
			||||||
  } else if(ent->subX < 0) {
 | 
					 | 
				
			||||||
    ent->subX += ENTITY_MOVE_SPEED;
 | 
					 | 
				
			||||||
    if(ent->subX > 0) ent->subX = 0;
 | 
					 | 
				
			||||||
  } else if(ent->subY > 0) {
 | 
					 | 
				
			||||||
    ent->subY -= ENTITY_MOVE_SPEED;
 | 
					 | 
				
			||||||
    if(ent->subY < 0) ent->subY = 0;
 | 
					 | 
				
			||||||
  } else if(ent->subY < 0) {
 | 
					 | 
				
			||||||
    ent->subY += ENTITY_MOVE_SPEED;
 | 
					 | 
				
			||||||
    if(ent->subY > 0) ent->subY = 0;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void entityTurn(entity_t *ent, const facingdir_t dir) {
 | 
					 | 
				
			||||||
  assertNotNull(ent, "Entity cannot be NULL");
 | 
					 | 
				
			||||||
  assertTrue(dir < FACING_DIRECTION_COUNT, "Invalid facing direction");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ent->direction = dir;
 | 
					 | 
				
			||||||
  switch(dir) {
 | 
					 | 
				
			||||||
    case FACING_DIRECTION_SOUTH:
 | 
					 | 
				
			||||||
      ent->frame = 25;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    case FACING_DIRECTION_NORTH:
 | 
					 | 
				
			||||||
      ent->frame = 24;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    case FACING_DIRECTION_EAST:
 | 
					 | 
				
			||||||
      ent->frame = 26;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    case FACING_DIRECTION_WEST:
 | 
					 | 
				
			||||||
      ent->frame = 27;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void entityMove(entity_t *ent, const facingdir_t dir) {
 | 
					 | 
				
			||||||
  assertNotNull(ent, "Entity cannot be NULL");
 | 
					 | 
				
			||||||
  if(entityIsMoving(ent)) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  entityTurn(ent, dir);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  uint8_t targetX = ent->x, targetY = ent->y;
 | 
					 | 
				
			||||||
  facingDirAdd(ent->direction, &targetX, &targetY);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Check oob
 | 
					 | 
				
			||||||
  if(targetX < 0 || targetX >= OVERWORLD.map.width) return;
 | 
					 | 
				
			||||||
  if(targetY < 0 || targetY >= OVERWORLD.map.height) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Check tile at target
 | 
					 | 
				
			||||||
  uint8_t i = 0;
 | 
					 | 
				
			||||||
  tileid_t tileId;
 | 
					 | 
				
			||||||
  for(i = 0; i < OVERWORLD.map.layerCount; i++) {
 | 
					 | 
				
			||||||
    tileId = mapGetTileIdAtPosition(&OVERWORLD.map, i, targetX, targetY);
 | 
					 | 
				
			||||||
    if(tileIsSolid(tileId)) return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Check for entity at target
 | 
					 | 
				
			||||||
  entity_t *atPos = overworldEntityGetAtPosition(targetX, targetY);
 | 
					 | 
				
			||||||
  if(atPos != NULL) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Commit to move
 | 
					 | 
				
			||||||
  ent->x = targetX;
 | 
					 | 
				
			||||||
  ent->y = targetY;
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  switch(dir) {
 | 
					 | 
				
			||||||
    case FACING_DIRECTION_EAST:
 | 
					 | 
				
			||||||
      ent->subX = -OVERWORLD_ENTITY_WIDTH;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    case FACING_DIRECTION_WEST:
 | 
					 | 
				
			||||||
      ent->subX = OVERWORLD_ENTITY_WIDTH;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    case FACING_DIRECTION_NORTH:
 | 
					 | 
				
			||||||
      ent->subY = -OVERWORLD_ENTITY_HEIGHT;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    case FACING_DIRECTION_SOUTH:
 | 
					 | 
				
			||||||
      ent->subY = OVERWORLD_ENTITY_HEIGHT;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool_t entityIsMoving(const entity_t *ent) {
 | 
					 | 
				
			||||||
  assertNotNull(ent, "Entity cannot be NULL");
 | 
					 | 
				
			||||||
  return ent->subX != 0 || ent->subY != 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool_t entityInteract(entity_t *ent) {
 | 
					 | 
				
			||||||
  assertNotNull(ent, "Entity cannot be NULL.");
 | 
					 | 
				
			||||||
  assertTrue(ent->type == ENTITY_TYPE_PLAYER, "Entity should be player.");
 | 
					 | 
				
			||||||
  if(entityIsMoving(ent)) return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  uint8_t targetX = ent->x, targetY = ent->y;
 | 
					 | 
				
			||||||
  facingDirAdd(ent->direction, &targetX, &targetY);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  entity_t *target = overworldEntityGetAtPosition(targetX, targetY);
 | 
					 | 
				
			||||||
  assertFalse(target == ent, "Cannot interact with self.");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if(target == NULL) return false;
 | 
					 | 
				
			||||||
  assertTrue(target->type < ENTITY_TYPE_COUNT, "Invalid entity type.");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if(ENTITY_CALLBACKS[target->type].interact == NULL) return false;
 | 
					 | 
				
			||||||
  ENTITY_CALLBACKS[target->type].interact(ent, target);
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,89 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "facing.h"
 | 
					 | 
				
			||||||
#include "player.h"
 | 
					 | 
				
			||||||
#include "npc.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum {
 | 
					 | 
				
			||||||
  ENTITY_TYPE_NULL,
 | 
					 | 
				
			||||||
  ENTITY_TYPE_PLAYER,
 | 
					 | 
				
			||||||
  ENTITY_TYPE_NPC
 | 
					 | 
				
			||||||
} entitytype_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define ENTITY_TYPE_COUNT 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
  void (*init)(entity_t *);
 | 
					 | 
				
			||||||
  void (*update)(entity_t *);
 | 
					 | 
				
			||||||
  void (*interact)(entity_t *, entity_t *);
 | 
					 | 
				
			||||||
} entitycallback_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct _entity_t {
 | 
					 | 
				
			||||||
  uint8_t x, y;
 | 
					 | 
				
			||||||
  int8_t subX, subY;
 | 
					 | 
				
			||||||
  uint8_t frame;
 | 
					 | 
				
			||||||
  facingdir_t direction;
 | 
					 | 
				
			||||||
  entitytype_t type;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  union {
 | 
					 | 
				
			||||||
    player_t player;
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
} entity_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define ENTITY_MOVE_SPEED 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Initializes an entity.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param entity The entity to initialize.
 | 
					 | 
				
			||||||
 * @param type The type of entity to initialize.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void entityInit(
 | 
					 | 
				
			||||||
  entity_t *entity,
 | 
					 | 
				
			||||||
  const entitytype_t type
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Updates an entity.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param entity The entity to update.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void entityUpdate(entity_t *entity);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Turns an entity in a given direction.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param entity The entity to turn.
 | 
					 | 
				
			||||||
 * @param dir The direction to turn the entity.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void entityTurn(entity_t *entity, const facingdir_t dir);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Moves an entity in a given direction.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param entity The entity to move.
 | 
					 | 
				
			||||||
 * @param dir The direction to move the entity.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void entityMove(entity_t *entity, const facingdir_t dir);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Checks if an entity is moving.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param entity The entity to check.
 | 
					 | 
				
			||||||
 * @return TRUE if the entity is moving, FALSE otherwise.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
bool_t entityIsMoving(const entity_t *entity);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Make this entity attempt to interact with the world.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param entity The entity that is doing the interaction.
 | 
					 | 
				
			||||||
 * @return TRUE if an entity was interacted with, FALSE otherwise.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
bool_t entityInteract(entity_t *entity);
 | 
					 | 
				
			||||||
@@ -1,65 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "facing.h"
 | 
					 | 
				
			||||||
#include "assert/assert.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void facingDirGetRelative(const facingdir_t dir, int8_t *x, int8_t *y) {
 | 
					 | 
				
			||||||
  assertNotNull(x, "X cannot be NULL");
 | 
					 | 
				
			||||||
  assertNotNull(y, "Y cannot be NULL");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  switch(dir) {
 | 
					 | 
				
			||||||
    case FACING_DIRECTION_SOUTH:
 | 
					 | 
				
			||||||
      *x = 0;
 | 
					 | 
				
			||||||
      *y = -1;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case FACING_DIRECTION_EAST:
 | 
					 | 
				
			||||||
      *x = 1;
 | 
					 | 
				
			||||||
      *y = 0;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case FACING_DIRECTION_NORTH:
 | 
					 | 
				
			||||||
      *x = 0;
 | 
					 | 
				
			||||||
      *y = 1;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case FACING_DIRECTION_WEST:
 | 
					 | 
				
			||||||
      *x = -1;
 | 
					 | 
				
			||||||
      *y = 0;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
      assertUnreachable("Invalid facing direction.");
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void facingDirAdd(const facingdir_t dir, uint8_t *x, uint8_t *y) {
 | 
					 | 
				
			||||||
  assertNotNull(x, "X cannot be NULL");
 | 
					 | 
				
			||||||
  assertNotNull(y, "Y cannot be NULL");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  int8_t dx, dy;
 | 
					 | 
				
			||||||
  facingDirGetRelative(dir, &dx, &dy);
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  *x += dx;
 | 
					 | 
				
			||||||
  *y += dy;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
facingdir_t facingDirFace(
 | 
					 | 
				
			||||||
  const uint8_t x1, const uint8_t y1,
 | 
					 | 
				
			||||||
  const uint8_t x2, const uint8_t y2
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  if(x1 == x2) {
 | 
					 | 
				
			||||||
    if(y1 < y2) return FACING_DIRECTION_SOUTH;
 | 
					 | 
				
			||||||
    if(y1 > y2) return FACING_DIRECTION_NORTH;
 | 
					 | 
				
			||||||
  } else if(y1 == y2) {
 | 
					 | 
				
			||||||
    if(x1 < x2) return FACING_DIRECTION_WEST;
 | 
					 | 
				
			||||||
    if(x1 > x2) return FACING_DIRECTION_EAST;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return FACING_DIRECTION_SOUTH;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,50 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "dusk.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum {
 | 
					 | 
				
			||||||
  FACING_DIRECTION_SOUTH,
 | 
					 | 
				
			||||||
  FACING_DIRECTION_EAST,
 | 
					 | 
				
			||||||
  FACING_DIRECTION_NORTH,
 | 
					 | 
				
			||||||
  FACING_DIRECTION_WEST
 | 
					 | 
				
			||||||
} facingdir_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define FACING_DIRECTION_COUNT 4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Converts a facing direction to a directional vector.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param dir The direction to convert.
 | 
					 | 
				
			||||||
 * @param x The x component of the vector.
 | 
					 | 
				
			||||||
 * @param y The y component of the vector.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void facingDirGetRelative(const facingdir_t dir, int8_t *x, int8_t *y);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Adds a facing direction to a position.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param dir The direction to add.
 | 
					 | 
				
			||||||
 * @param x The x position to add to.
 | 
					 | 
				
			||||||
 * @param y The y position to add to.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void facingDirAdd(const facingdir_t dir, uint8_t *x, uint8_t *y);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns the facing direction to face from one position to another.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param x1 The x position to face from.
 | 
					 | 
				
			||||||
 * @param y1 The y position to face from.
 | 
					 | 
				
			||||||
 * @param x2 The x position to face to.
 | 
					 | 
				
			||||||
 * @param y2 The y position to face to.
 | 
					 | 
				
			||||||
 * @return The facing direction to face from one position to another.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
facingdir_t facingDirFace(
 | 
					 | 
				
			||||||
  const uint8_t x1, const uint8_t y1,
 | 
					 | 
				
			||||||
  const uint8_t x2, const uint8_t y2
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
@@ -1,19 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "entity.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void npcInit(entity_t *ent) {
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void npcUpdate(entity_t *ent) {
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void npcInteract(entity_t *player, entity_t *ent) {
 | 
					 | 
				
			||||||
  printf("Interact\n");
 | 
					 | 
				
			||||||
  entityTurn(ent, facingDirFace(player->x, player->y, ent->x, ent->y));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,37 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "dusk.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct _entity_t entity_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
  int32_t nothing;
 | 
					 | 
				
			||||||
} npc_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Handles initialization of an NPC.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param ent The entity to initialize as an NPC.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void npcInit(entity_t *ent);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Handles updating an NPC.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param ent The entity to update as an NPC.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void npcUpdate(entity_t *ent);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Handles interaction with an NPC.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param player The player entity interacting.
 | 
					 | 
				
			||||||
 * @param ent The entity to interact with.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void npcInteract(entity_t *player, entity_t *ent);
 | 
					 | 
				
			||||||
@@ -1,33 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "overworld/overworld.h"
 | 
					 | 
				
			||||||
#include "assert/assert.h"
 | 
					 | 
				
			||||||
#include "input.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void playerInit(entity_t *ent) {
 | 
					 | 
				
			||||||
  assertNotNull(ent, "Entity cannot be NULL");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  printf("Initializing player entity\n");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void playerUpdate(entity_t *ent) {
 | 
					 | 
				
			||||||
  assertNotNull(ent, "Entity cannot be NULL");
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  if(inputIsDown(INPUT_RIGHT)) {
 | 
					 | 
				
			||||||
    entityMove(ent, FACING_DIRECTION_EAST);
 | 
					 | 
				
			||||||
  } else if(inputIsDown(INPUT_LEFT)) {
 | 
					 | 
				
			||||||
    entityMove(ent, FACING_DIRECTION_WEST);
 | 
					 | 
				
			||||||
  } else if(inputIsDown(INPUT_UP)) {
 | 
					 | 
				
			||||||
    entityMove(ent, FACING_DIRECTION_NORTH);
 | 
					 | 
				
			||||||
  } else if(inputIsDown(INPUT_DOWN)) {
 | 
					 | 
				
			||||||
    entityMove(ent, FACING_DIRECTION_SOUTH);
 | 
					 | 
				
			||||||
  } else if(inputWasPressed(INPUT_ACCEPT)) {
 | 
					 | 
				
			||||||
    entityInteract(ent);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,29 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "dusk.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct _entity_t entity_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
  int32_t nothing;
 | 
					 | 
				
			||||||
} player_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Handles initialization of the player.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param ent The entity to initialize as a player.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void playerInit(entity_t *ent);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Handles updating the player.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param ent The entity to update as a player.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void playerUpdate(entity_t *ent);
 | 
					 | 
				
			||||||
@@ -1,69 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "map.h"
 | 
					 | 
				
			||||||
#include "assert/assert.h"
 | 
					 | 
				
			||||||
#include "util/memory.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void mapInit(map_t *map) {
 | 
					 | 
				
			||||||
  memoryZero(map, sizeof(map_t));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Test
 | 
					 | 
				
			||||||
  map->width = 16;
 | 
					 | 
				
			||||||
  map->height = 16;
 | 
					 | 
				
			||||||
  map->layerCount = 1;
 | 
					 | 
				
			||||||
  memorySet(&map->tileIds, 0x01, sizeof(map->tileIds));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Test size
 | 
					 | 
				
			||||||
  assertTrue(
 | 
					 | 
				
			||||||
    (map->width * map->height * map->layerCount) <= OVERWORLD_TILE_COUNT_MAX,
 | 
					 | 
				
			||||||
    "Map size exceeds tile count."
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint32_t mapGetTileIndex(
 | 
					 | 
				
			||||||
  const map_t *map,
 | 
					 | 
				
			||||||
  const uint8_t layer,
 | 
					 | 
				
			||||||
  const uint8_t x,
 | 
					 | 
				
			||||||
  const uint8_t y
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  assertNotNull(map, "Map cannot be NULL");
 | 
					 | 
				
			||||||
  assertTrue(layer < map->layerCount, "Invalid layer");
 | 
					 | 
				
			||||||
  assertTrue(x < map->width, "Invalid x");
 | 
					 | 
				
			||||||
  assertTrue(y < map->height, "Invalid y");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return (layer * map->width * map->height) + (y * map->width) + x;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
tileid_t mapGetTileId(
 | 
					 | 
				
			||||||
  const map_t *map,
 | 
					 | 
				
			||||||
  const uint32_t tileIndex
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  assertNotNull(map, "Map cannot be NULL");
 | 
					 | 
				
			||||||
  assertMapIndexValid(map, tileIndex);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return map->tileIds[tileIndex];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
tileid_t mapGetTileIdAtPosition(
 | 
					 | 
				
			||||||
  const map_t *map,
 | 
					 | 
				
			||||||
  const uint8_t layer,
 | 
					 | 
				
			||||||
  const uint8_t x,
 | 
					 | 
				
			||||||
  const uint8_t y
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  return mapGetTileId(map, mapGetTileIndex(map, layer, x, y));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
tiledata_t mapGetTileData(
 | 
					 | 
				
			||||||
  const map_t *map,
 | 
					 | 
				
			||||||
  const uint32_t tileIndex
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  assertNotNull(map, "Map cannot be NULL");
 | 
					 | 
				
			||||||
  assertMapIndexValid(map, tileIndex);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return map->tileData[tileIndex];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,82 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "tile.h"
 | 
					 | 
				
			||||||
#include "overworld/overworlddefs.h"
 | 
					 | 
				
			||||||
#include "assert/assert.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define assertMapIndexValid(map, index) \
 | 
					 | 
				
			||||||
  assertTrue( \
 | 
					 | 
				
			||||||
    index < (map->layerCount * map->width * map->height), \
 | 
					 | 
				
			||||||
    "Invalid tile index" \
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
  tileid_t tileIds[OVERWORLD_TILE_COUNT_MAX];
 | 
					 | 
				
			||||||
  tiledata_t tileData[OVERWORLD_TILE_COUNT_MAX];
 | 
					 | 
				
			||||||
  uint8_t width, height, layerCount;
 | 
					 | 
				
			||||||
} map_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void mapInit(map_t *map);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns the index of the tile at the given position.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param map The map to get the tile index from.
 | 
					 | 
				
			||||||
 * @param layer The layer to get the tile from.
 | 
					 | 
				
			||||||
 * @param x The x position of the tile.
 | 
					 | 
				
			||||||
 * @param y The y position of the tile.
 | 
					 | 
				
			||||||
 * @return The index of the tile at the given position.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
uint32_t mapGetTileIndex(
 | 
					 | 
				
			||||||
  const map_t *map,
 | 
					 | 
				
			||||||
  const uint8_t layer,
 | 
					 | 
				
			||||||
  const uint8_t x,
 | 
					 | 
				
			||||||
  const uint8_t y
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns the tile ID at the given index.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param map The map to get the tile ID from.
 | 
					 | 
				
			||||||
 * @param tileIndex The index of the tile to get.
 | 
					 | 
				
			||||||
 * @return The tile ID at the given index.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
tileid_t mapGetTileId(
 | 
					 | 
				
			||||||
  const map_t *map,
 | 
					 | 
				
			||||||
  const uint32_t tileIndex
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns the tile ID at the given position. Shorthand for both getting the 
 | 
					 | 
				
			||||||
 * map index and the tile ID.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param map The map to get the tile ID from.
 | 
					 | 
				
			||||||
 * @param layer The layer to get the tile from.
 | 
					 | 
				
			||||||
 * @param x The x position of the tile.
 | 
					 | 
				
			||||||
 * @param y The y position of the tile.
 | 
					 | 
				
			||||||
 * @return The tile ID at the given position.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
tileid_t mapGetTileIdAtPosition(
 | 
					 | 
				
			||||||
  const map_t *map,
 | 
					 | 
				
			||||||
  const uint8_t layer,
 | 
					 | 
				
			||||||
  const uint8_t x,
 | 
					 | 
				
			||||||
  const uint8_t y
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns the tile data at the given index.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param map The map to get the tile data from.
 | 
					 | 
				
			||||||
 * @param tileIndex The index of the tile to get.
 | 
					 | 
				
			||||||
 * @return The tile data at the given index.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
tiledata_t mapGetTileData(
 | 
					 | 
				
			||||||
  const map_t *map,
 | 
					 | 
				
			||||||
  const uint32_t tileIndex
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
@@ -1,19 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "tile.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool_t tileIsSolid(const tileid_t id) {
 | 
					 | 
				
			||||||
  switch(id) {
 | 
					 | 
				
			||||||
    case TILE_ID_NULL:
 | 
					 | 
				
			||||||
    case TILE_ID_GRASS:
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
      return true;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "dusk.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef uint8_t tileid_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
  uint32_t nothing;
 | 
					 | 
				
			||||||
} tiledata_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TILE_ID_NULL 0
 | 
					 | 
				
			||||||
#define TILE_ID_GRASS 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns whether or not the tile is solid.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param id The tile id to check.
 | 
					 | 
				
			||||||
 * @return Whether or not the tile is solid.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
bool_t tileIsSolid(const tileid_t id);
 | 
					 | 
				
			||||||
@@ -1,49 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "overworld.h"
 | 
					 | 
				
			||||||
#include "util/memory.h"
 | 
					 | 
				
			||||||
#include "assert/assert.h"
 | 
					 | 
				
			||||||
#include "display/tileset.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
overworld_t OVERWORLD;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void overworldInit() {
 | 
					 | 
				
			||||||
  memoryZero(&OVERWORLD, sizeof(overworld_t));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  mapInit(&OVERWORLD.map);
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  entityInit(OVERWORLD.entities + OVERWORLD.entityCount++, ENTITY_TYPE_PLAYER);
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  entityInit(OVERWORLD.entities + OVERWORLD.entityCount++, ENTITY_TYPE_NPC);
 | 
					 | 
				
			||||||
  OVERWORLD.entities[1].x = 2;
 | 
					 | 
				
			||||||
  OVERWORLD.entities[1].y = 2;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void overworldSceneInit() {
 | 
					 | 
				
			||||||
  tilesetBind(TILESET_FONT, TILESET_SLOT_ENTITIES);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void overworldSceneDeinit() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void overworldUpdate() {
 | 
					 | 
				
			||||||
  uint8_t i = 0;
 | 
					 | 
				
			||||||
  while(i < OVERWORLD.entityCount) {
 | 
					 | 
				
			||||||
    entityUpdate(OVERWORLD.entities + i++);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
entity_t * overworldEntityGetAtPosition(const uint8_t x, const uint8_t y) {
 | 
					 | 
				
			||||||
  uint8_t i = 0;
 | 
					 | 
				
			||||||
  while(i < OVERWORLD.entityCount) {
 | 
					 | 
				
			||||||
    entity_t * entity = OVERWORLD.entities + i++;
 | 
					 | 
				
			||||||
    if(entity->x == x && entity->y == y) return entity;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,57 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "overworlddefs.h"
 | 
					 | 
				
			||||||
#include "overworld/entity/entity.h"
 | 
					 | 
				
			||||||
#include "overworld/map/map.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
  entity_t entities[OVERWORLD_ENTITY_COUNT_MAX];
 | 
					 | 
				
			||||||
  uint8_t entityCount;
 | 
					 | 
				
			||||||
  map_t map;
 | 
					 | 
				
			||||||
} overworld_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern overworld_t OVERWORLD;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Initializes the overworld.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void overworldInit();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Called by the scene system when the overworld scene is made to be the 
 | 
					 | 
				
			||||||
 * active scene.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void overworldSceneInit();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Called by the scene system when the overworld scene is made to be inactive.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void overworldSceneDeinit();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Called by the scene system when the overworld scene is to perform a tick.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void overworldUpdate();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Platform level render method. Refer to sceneRender for information.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void overworldRender();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns the entity at the given position.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param x The x position of the entity.
 | 
					 | 
				
			||||||
 * @param y The y position of the entity.
 | 
					 | 
				
			||||||
 * @return The entity at the given position.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
entity_t * overworldEntityGetAtPosition(
 | 
					 | 
				
			||||||
  const uint8_t x,
 | 
					 | 
				
			||||||
  const uint8_t y
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
@@ -1,16 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define OVERWORLD_ENTITY_COUNT_MAX 8
 | 
					 | 
				
			||||||
#define OVERWORLD_ENTITY_WIDTH 32
 | 
					 | 
				
			||||||
#define OVERWORLD_ENTITY_HEIGHT 32
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define OVERWORLD_TILE_LAYER_COUNT_MAX 2
 | 
					 | 
				
			||||||
#define OVERWORLD_TILE_COUNT_PER_LAYER 256
 | 
					 | 
				
			||||||
#define OVERWORLD_TILE_COUNT_MAX (OVERWORLD_TILE_COUNT_PER_LAYER * OVERWORLD_TILE_LAYER_COUNT_MAX)
 | 
					 | 
				
			||||||
#define OVERWORLD_TILE_WIDTH OVERWORLD_ENTITY_WIDTH
 | 
					 | 
				
			||||||
#define OVERWORLD_TILE_HEIGHT OVERWORLD_ENTITY_HEIGHT
 | 
					 | 
				
			||||||
							
								
								
									
										19
									
								
								src/dusk/server/server.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/dusk/server/server.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright (c) 2025 Dominic Masters
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This software is released under the MIT License.
 | 
				
			||||||
 | 
					 * https://opensource.org/licenses/MIT
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include "dusk.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} server_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern server_t SERVER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void serverInit();
 | 
				
			||||||
 | 
					void serverStart();
 | 
				
			||||||
 | 
					void serverDispose();
 | 
				
			||||||
@@ -1,55 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "uimenu.h"
 | 
					 | 
				
			||||||
#include "util/memory.h"
 | 
					 | 
				
			||||||
#include "assert/assert.h"
 | 
					 | 
				
			||||||
#include "input.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void uiMenuInit(
 | 
					 | 
				
			||||||
  uimenu_t *menu,
 | 
					 | 
				
			||||||
  const uint8_t columns,
 | 
					 | 
				
			||||||
  const uint8_t rows
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  assertNotNull(menu, "Menu cannot be NULL.");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  memoryZero(menu, sizeof(uimenu_t));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  menu->columns = columns;
 | 
					 | 
				
			||||||
  menu->rows = rows;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void uiMenuSetCursor(
 | 
					 | 
				
			||||||
  uimenu_t *menu,
 | 
					 | 
				
			||||||
  const uint8_t x,
 | 
					 | 
				
			||||||
  const uint8_t y
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  assertNotNull(menu, "Menu cannot be NULL.");
 | 
					 | 
				
			||||||
  assert(x < menu->columns, "X position out of bounds.");
 | 
					 | 
				
			||||||
  assert(y < menu->rows, "Y position out of bounds.");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  menu->x = x;
 | 
					 | 
				
			||||||
  menu->y = y;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void uiMenuMoveCursor(
 | 
					 | 
				
			||||||
  uimenu_t *menu,
 | 
					 | 
				
			||||||
  const int8_t x,
 | 
					 | 
				
			||||||
  const int8_t y
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  assertNotNull(menu, "Menu cannot be NULL.");
 | 
					 | 
				
			||||||
  uiMenuSetCursor(
 | 
					 | 
				
			||||||
    menu,
 | 
					 | 
				
			||||||
    (menu->x + x) % menu->columns,
 | 
					 | 
				
			||||||
    (menu->y + y) % menu->rows
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uimenuaction_t uiMenuUpdate(uimenu_t *menu) {
 | 
					 | 
				
			||||||
  assertNotNull(menu, "Menu cannot be NULL.");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,69 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2025 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "dusk.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum {
 | 
					 | 
				
			||||||
  UI_MENU_ACTION_NOTHING,
 | 
					 | 
				
			||||||
  UI_MENU_ACTION_CURSOR_MOVE,
 | 
					 | 
				
			||||||
  UI_MENU_ACTION_CURSOR_ACCEPT,
 | 
					 | 
				
			||||||
  UI_MENU_ACTION_CURSOR_CANCEL
 | 
					 | 
				
			||||||
} uimenuaction_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
  uint8_t columns;
 | 
					 | 
				
			||||||
  uint8_t rows;
 | 
					 | 
				
			||||||
  uint8_t x;
 | 
					 | 
				
			||||||
  uint8_t y;
 | 
					 | 
				
			||||||
} uimenu_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Initializes a menu.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param menu The menu to initialize.
 | 
					 | 
				
			||||||
 * @param columns The amount of columns in the menu.
 | 
					 | 
				
			||||||
 * @param rows The amount of rows in the menu.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void uiMenuInit(
 | 
					 | 
				
			||||||
  uimenu_t *menu,
 | 
					 | 
				
			||||||
  const uint8_t columns,
 | 
					 | 
				
			||||||
  const uint8_t rows
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Sets the cursor of a menu.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param menu The menu to set the cursor of.
 | 
					 | 
				
			||||||
 * @param x The x position of the cursor.
 | 
					 | 
				
			||||||
 * @param y The y position of the cursor.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void uiMenuSetCursor(
 | 
					 | 
				
			||||||
  uimenu_t *menu,
 | 
					 | 
				
			||||||
  const uint8_t x,
 | 
					 | 
				
			||||||
  const uint8_t y
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Moves the cursor of a menu.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param menu The menu to move the cursor of.
 | 
					 | 
				
			||||||
 * @param x The amount to move the cursor on the x axis.
 | 
					 | 
				
			||||||
 * @param y The amount to move the cursor on the y axis.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void uiMenuMoveCursor(
 | 
					 | 
				
			||||||
  uimenu_t *menu,
 | 
					 | 
				
			||||||
  const int8_t x,
 | 
					 | 
				
			||||||
  const int8_t y
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Handles updating of a menu, this will accept input basically.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param menu The menu to update.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
uimenuaction_t uiMenuUpdate(uimenu_t *menu);
 | 
					 | 
				
			||||||
@@ -1,12 +1,11 @@
 | 
				
			|||||||
# Copyright (c) 2023 Dominic Masters
 | 
					# Copyright (c) 2025 Dominic Masters
 | 
				
			||||||
# 
 | 
					# 
 | 
				
			||||||
# 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Sources
 | 
					# Sources
 | 
				
			||||||
target_sources(${DUSK_TARGET_NAME}
 | 
					target_sources(${DUSK_TARGET_NAME}
 | 
				
			||||||
  PRIVATE
 | 
					  PRIVATE
 | 
				
			||||||
    math.c
 | 
					 | 
				
			||||||
    random.c
 | 
					 | 
				
			||||||
    memory.c
 | 
					    memory.c
 | 
				
			||||||
 | 
					    string.c
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -1,24 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2023 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "math.h"
 | 
					 | 
				
			||||||
#include "assert/assert.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int32_t mathClampi32(
 | 
					 | 
				
			||||||
  const int32_t value,
 | 
					 | 
				
			||||||
  const int32_t min,
 | 
					 | 
				
			||||||
  const int32_t max
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  assertTrue(max >= min, "mathClampi32: Max must be >= Min");
 | 
					 | 
				
			||||||
  if(value < min) return min;
 | 
					 | 
				
			||||||
  if(value > max) return max;
 | 
					 | 
				
			||||||
  return value;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int32_t mathModi32(int32_t value, int32_t modulo) {
 | 
					 | 
				
			||||||
  return ((value % modulo) + modulo) % modulo;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,48 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2023 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "dusk.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns the minimum of two values.
 | 
					 | 
				
			||||||
 * @param a First value.
 | 
					 | 
				
			||||||
 * @param b Second value.
 | 
					 | 
				
			||||||
 * @return The minimum of the two values.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define mathMin(a, b) ((a) < (b) ? (a) : (b))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns the maximum of two values.
 | 
					 | 
				
			||||||
 * @param a First value.
 | 
					 | 
				
			||||||
 * @param b Second value.
 | 
					 | 
				
			||||||
 * @return The maximum of the two values.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define mathMax(a, b) ((a) > (b) ? (a) : (b))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Clamps a value between a min and max.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param value Value to clamp.
 | 
					 | 
				
			||||||
 * @param min Minimum value to clamp value to.
 | 
					 | 
				
			||||||
 * @param max Maximum value to clamp value to.
 | 
					 | 
				
			||||||
 * @return The clamped value.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int32_t mathClampi32(
 | 
					 | 
				
			||||||
  const int32_t value,
 | 
					 | 
				
			||||||
  const int32_t min,
 | 
					 | 
				
			||||||
  const int32_t max
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns the modulo of a value. For 32 bit integers.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param value Value to modulo.
 | 
					 | 
				
			||||||
 * @param modulo Modulo value.
 | 
					 | 
				
			||||||
 * @return The modulo of the value.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int32_t mathModi32(int32_t value, int32_t modulo);
 | 
					 | 
				
			||||||
@@ -49,4 +49,12 @@ void memoryCopyRangeSafe(
 | 
				
			|||||||
  size_t copy = (size_t)end - (size_t)start;
 | 
					  size_t copy = (size_t)end - (size_t)start;
 | 
				
			||||||
  assertTrue(copy <= sizeMax, "Size of memory to copy is too large.");
 | 
					  assertTrue(copy <= sizeMax, "Size of memory to copy is too large.");
 | 
				
			||||||
  memoryCopy(dest, start, copy);
 | 
					  memoryCopy(dest, start, copy);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void memoryMove(void *dest, const void *src, const size_t size) {
 | 
				
			||||||
 | 
					  assertNotNull(dest, "Cannot move to NULL memory.");
 | 
				
			||||||
 | 
					  assertNotNull(src, "Cannot move from NULL memory.");
 | 
				
			||||||
 | 
					  assertTrue(size > 0, "Cannot move 0 bytes of memory.");
 | 
				
			||||||
 | 
					  assertTrue(dest != src, "Cannot move memory to itself.");
 | 
				
			||||||
 | 
					  memmove(dest, src, size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -64,4 +64,13 @@ void memoryCopyRangeSafe(
 | 
				
			|||||||
  const void *start,
 | 
					  const void *start,
 | 
				
			||||||
  const void *end,
 | 
					  const void *end,
 | 
				
			||||||
  const size_t sizeMax
 | 
					  const size_t sizeMax
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Moves memory.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @param dest The destination to move to.
 | 
				
			||||||
 | 
					 * @param src The source to move from.
 | 
				
			||||||
 | 
					 * @param size The size of the memory to move.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void memoryMove(void *dest, const void *src, const size_t size);
 | 
				
			||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2024 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "random.h"
 | 
					 | 
				
			||||||
#include "assert/assert.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool_t RANDOM_IS_INITIALIZED = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void randomInit() {
 | 
					 | 
				
			||||||
  assertFalse(RANDOM_IS_INITIALIZED, "Random already initialized.");
 | 
					 | 
				
			||||||
  srand(1234567890);
 | 
					 | 
				
			||||||
  RANDOM_IS_INITIALIZED = true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int32_t randomInt32() {
 | 
					 | 
				
			||||||
  assertTrue(RANDOM_IS_INITIALIZED, "Random not initialized.");
 | 
					 | 
				
			||||||
  return rand();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int32_t randomInt32Range(int32_t min, int32_t max) {
 | 
					 | 
				
			||||||
  return min + (rand() % (max - min));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,32 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
 * Copyright (c) 2024 Dominic Masters
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This software is released under the MIT License.
 | 
					 | 
				
			||||||
 * https://opensource.org/licenses/MIT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "dusk.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern bool_t RANDOM_IS_INITIALIZED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Initializes the random number generator, and seeds it.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void randomInit();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns a random 32-bit integer.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @return Random 32-bit integer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int32_t randomInt32();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Returns a random 32-bit integer within a given range.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @param min Minimum value.
 | 
					 | 
				
			||||||
 * @param max Maximum value (exclusive).
 | 
					 | 
				
			||||||
 * @return Random 32-bit integer within the given range.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int32_t randomInt32Range(int32_t min, int32_t max);
 | 
					 | 
				
			||||||
							
								
								
									
										50
									
								
								src/dusk/util/string.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/dusk/util/string.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 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"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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");
 | 
				
			||||||
 | 
					  assertStrLenMax(src, destSize, "src is too long");
 | 
				
			||||||
 | 
					  strncpy(dest, src, destSize);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										55
									
								
								src/dusk/util/string.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/dusk/util/string.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 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);
 | 
				
			||||||
@@ -1,15 +1,23 @@
 | 
				
			|||||||
# Copyright (c) 2025 Dominic Masters
 | 
					# Copyright (c) 2025 Dominic Masters
 | 
				
			||||||
# 
 | 
					#
 | 
				
			||||||
# 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Libs
 | 
				
			||||||
 | 
					target_link_libraries(${DUSK_TARGET_NAME}
 | 
				
			||||||
 | 
					  PUBLIC
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Includes
 | 
				
			||||||
 | 
					target_include_directories(${DUSK_TARGET_NAME}
 | 
				
			||||||
 | 
					  PUBLIC
 | 
				
			||||||
 | 
					    ${CMAKE_CURRENT_LIST_DIR}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Sources
 | 
					# Sources
 | 
				
			||||||
target_sources(${DUSK_TARGET_NAME}
 | 
					target_sources(${DUSK_TARGET_NAME}
 | 
				
			||||||
  PRIVATE
 | 
					  PRIVATE
 | 
				
			||||||
    entity.c
 | 
					    main.c
 | 
				
			||||||
    facing.c
 | 
					 | 
				
			||||||
    player.c
 | 
					 | 
				
			||||||
    npc.c
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Subdirs
 | 
					# Subdirs
 | 
				
			||||||
							
								
								
									
										39
									
								
								src/dusktest/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/dusktest/main.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright (c) 2025 Dominic Masters
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This software is released under the MIT License.
 | 
				
			||||||
 | 
					 * https://opensource.org/licenses/MIT
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dusk.h"
 | 
				
			||||||
 | 
					#include "error/error.h"
 | 
				
			||||||
 | 
					#include "console/console.h"
 | 
				
			||||||
 | 
					#include "util/string.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool_t exitRequested = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cmdExit(const consolecmdexec_t *exec) {
 | 
				
			||||||
 | 
					  exitRequested = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void testChange(const consolevar_t *var) {
 | 
				
			||||||
 | 
					  consolePrint("Variable '%s' changed to '%s'.", var->name, var->value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
					  consoleInit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  consoleRegCmd("exit", cmdExit);
 | 
				
			||||||
 | 
					  consoleRegVar("test", "Hello", testChange);
 | 
				
			||||||
 | 
					  consolePrint(" = Dusk Console = ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char_t buffer[CONSOLE_LINE_MAX];
 | 
				
			||||||
 | 
					  while(fgets(buffer, sizeof(buffer), stdin)) {
 | 
				
			||||||
 | 
					    consoleExec(buffer);
 | 
				
			||||||
 | 
					    consoleProcess();
 | 
				
			||||||
 | 
					    if(exitRequested) break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  printf("Goodbye!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0;  
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user