SDL time
This commit is contained in:
@@ -94,6 +94,10 @@ if(NOT TARGET pspsdk)
|
||||
pspdisplay
|
||||
pspge
|
||||
pspctrl
|
||||
pspgu
|
||||
pspaudio
|
||||
pspaudiolib
|
||||
psputility
|
||||
)
|
||||
endif()
|
||||
endif()
|
@@ -1,20 +0,0 @@
|
||||
# Copyright (c) 2025 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
raylib
|
||||
URL https://github.com/raysan5/raylib/archive/refs/tags/5.5.tar.gz
|
||||
URL_HASH MD5=61638c4c2c097fbca1d6a71e4da36c16
|
||||
)
|
||||
FetchContent_GetProperties(raylib)
|
||||
FetchContent_MakeAvailable(raylib)
|
||||
|
||||
# Define expected target if not already defined
|
||||
if(NOT TARGET raylib)
|
||||
set(raylib_FOUND FALSE CACHE INTERNAL "Whether raylib was found")
|
||||
else()
|
||||
set(raylib_FOUND TRUE CACHE INTERNAL "Whether raylib was found")
|
||||
endif()
|
@@ -6,9 +6,10 @@
|
||||
add_subdirectory(dusk)
|
||||
|
||||
if(DUSK_TARGET_SYSTEM STREQUAL "linux")
|
||||
add_subdirectory(duskraylib)
|
||||
add_subdirectory(dusksdl2)
|
||||
elseif(DUSK_TARGET_SYSTEM STREQUAL "psp")
|
||||
add_subdirectory(duskpsp)
|
||||
add_subdirectory(dusksdl2)
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported target system: ${DUSK_TARGET_SYSTEM}")
|
||||
endif()
|
@@ -6,6 +6,7 @@
|
||||
# Libs
|
||||
target_link_libraries(${DUSK_TARGET_NAME}
|
||||
PUBLIC
|
||||
m
|
||||
)
|
||||
|
||||
# Includes
|
||||
@@ -25,6 +26,7 @@ target_sources(${DUSK_TARGET_NAME}
|
||||
add_subdirectory(assert)
|
||||
add_subdirectory(console)
|
||||
add_subdirectory(display)
|
||||
add_subdirectory(error)
|
||||
add_subdirectory(entity)
|
||||
add_subdirectory(event)
|
||||
add_subdirectory(item)
|
||||
|
@@ -6,24 +6,28 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
#include "error/error.h"
|
||||
|
||||
#define RENDER_WIDTH 320
|
||||
#define RENDER_HEIGHT 240
|
||||
#ifndef RENDER_WIDTH
|
||||
#define RENDER_WIDTH 320
|
||||
#endif
|
||||
#ifndef RENDER_HEIGHT
|
||||
#define RENDER_HEIGHT 240
|
||||
#endif
|
||||
|
||||
extern uint8_t RENDER_FRAME;
|
||||
|
||||
/**
|
||||
* Initializes the rendering system.
|
||||
*/
|
||||
void renderInit(void);
|
||||
errorret_t renderInit(void);
|
||||
|
||||
/**
|
||||
* Tells the rendering system to actually draw the frame.
|
||||
*/
|
||||
void renderDraw(void);
|
||||
errorret_t renderDraw(void);
|
||||
|
||||
/**
|
||||
* Disposes of the rendering system.
|
||||
*/
|
||||
void renderDispose(void);
|
||||
errorret_t renderDispose(void);
|
@@ -17,7 +17,7 @@ typedef struct {
|
||||
|
||||
#define PLAYER_ENTITY_ID (UINT32_MAX-1)
|
||||
#define PLAYER_MOVE_SPEED 1.0f
|
||||
#define PLAYER_MOVE_SPEED_XY 0.70710678118f
|
||||
#define PLAYER_MOVE_SPEED_XY 0.7f
|
||||
#define PLAYER_INTERACT_RANGE (TILE_WIDTH_HEIGHT + (TILE_WIDTH_HEIGHT / 3))
|
||||
#define PLAYER_INTERACT_ANGLE 0.68359375f
|
||||
|
||||
|
@@ -1,12 +1,10 @@
|
||||
# Copyright (c) 2025 Dominic Masters
|
||||
#
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DUSK_TARGET_NAME}
|
||||
PRIVATE
|
||||
render.c
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
error.c
|
||||
)
|
125
src/dusk/error/error.c
Normal file
125
src/dusk/error/error.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "assert/assert.h"
|
||||
#include "error.h"
|
||||
#include "util/memory.h"
|
||||
#include "util/string.h"
|
||||
|
||||
errorret_t errorThrowImpl(
|
||||
errorstate_t *state,
|
||||
errorcode_t code,
|
||||
const char_t *file,
|
||||
const char_t *function,
|
||||
const int32_t line,
|
||||
const char_t *message,
|
||||
...
|
||||
) {
|
||||
assertNotNull(state, "Error state cannot be NULL");
|
||||
assertTrue(code != ERROR_OK, "Error code must not be OK");
|
||||
assertNotNull(file, "File cannot be NULL");
|
||||
assertNotNull(function, "Function cannot be NULL");
|
||||
assertTrue(line >= 0, "File pointer must be valid");
|
||||
assertNotNull(message, "Message cannot be NULL");
|
||||
|
||||
memoryZero(state, sizeof(errorstate_t));
|
||||
state->code = code;
|
||||
|
||||
// Format args.
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
|
||||
// Get length of formatted message
|
||||
va_list argsCopy;
|
||||
va_copy(argsCopy, args);
|
||||
int32_t len = stringFormatVA(NULL, 0, message, argsCopy);
|
||||
va_end(argsCopy);
|
||||
|
||||
// Create string to hold the formatted message
|
||||
state->message = (char_t *)memoryAllocate(len + 1);
|
||||
stringFormatVA(state->message, len + 1, message, args);
|
||||
va_end(args);
|
||||
|
||||
// Format lines
|
||||
len = stringFormat(NULL, 0, ERROR_LINE_FORMAT, file, line, function);
|
||||
assertTrue(len >= 0, "Line formatting failed");
|
||||
state->lines = (char_t *)memoryAllocate(len + 1);
|
||||
stringFormat(state->lines, len + 1, ERROR_LINE_FORMAT, file, line, function);
|
||||
|
||||
return (errorret_t) {
|
||||
.code = code,
|
||||
.state = state
|
||||
};
|
||||
}
|
||||
|
||||
errorret_t errorOkImpl() {
|
||||
return (errorret_t) {
|
||||
.code = ERROR_OK,
|
||||
.state = NULL
|
||||
};
|
||||
}
|
||||
|
||||
errorret_t errorChainImpl(
|
||||
const errorret_t retval,
|
||||
const char_t *file,
|
||||
const char_t *function,
|
||||
const int32_t line
|
||||
) {
|
||||
if (retval.code == ERROR_OK) return retval;
|
||||
|
||||
assertNotNull(retval.state, "Error state cannot be NULL");
|
||||
assertNotNull(retval.state->message, "Message cannot be NULL");
|
||||
|
||||
// Create a new line string.
|
||||
int32_t newLineLen = snprintf(NULL, 0, ERROR_LINE_FORMAT, file, line, function);
|
||||
assertTrue(newLineLen >= 0, "Line formatting failed");
|
||||
char_t *newLine = (char_t *)memoryAllocate(newLineLen + 1);
|
||||
snprintf(newLine, newLineLen + 1, ERROR_LINE_FORMAT, file, line, function);
|
||||
|
||||
// Resize the existing lines to accommodate the new line
|
||||
size_t existingLen = strlen(retval.state->lines);
|
||||
memoryResize(
|
||||
(void**)&retval.state->lines,
|
||||
existingLen,
|
||||
existingLen + newLineLen + 1
|
||||
);
|
||||
|
||||
// Now append the new line to the existing lines
|
||||
memoryCopy(
|
||||
retval.state->lines + existingLen,
|
||||
newLine,
|
||||
newLineLen + 1
|
||||
);
|
||||
|
||||
// Cleanup the temporary new line
|
||||
memoryFree(newLine);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void errorCatch(const errorret_t retval) {
|
||||
if (retval.code == ERROR_OK) return;
|
||||
|
||||
assertNotNull(retval.state, "Error state cannot be NULL");
|
||||
assertNotNull(retval.state->message, "Message cannot be NULL");
|
||||
|
||||
memoryFree((void*)retval.state->message);
|
||||
}
|
||||
|
||||
errorret_t errorPrint(const errorret_t retval) {
|
||||
if (retval.code == ERROR_OK) return retval;
|
||||
|
||||
assertNotNull(retval.state, "Error state cannot be NULL");
|
||||
assertNotNull(retval.state->message, "Message cannot be NULL");
|
||||
|
||||
printf(
|
||||
ERROR_PRINT_FORMAT,
|
||||
retval.state->code,
|
||||
retval.state->message,
|
||||
retval.state->lines
|
||||
);
|
||||
return retval;
|
||||
}
|
137
src/dusk/error/error.h
Normal file
137
src/dusk/error/error.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* 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 errorcode_t;
|
||||
|
||||
typedef struct {
|
||||
errorcode_t code;
|
||||
char_t *message;
|
||||
char_t *lines;
|
||||
} errorstate_t;
|
||||
|
||||
typedef struct {
|
||||
errorcode_t code;
|
||||
errorstate_t *state;
|
||||
} errorret_t;
|
||||
|
||||
static const errorcode_t ERROR_OK = 0;
|
||||
static const errorcode_t ERROR_NOT_OK = 1;
|
||||
static const char_t *ERROR_PRINT_FORMAT = "Error (%d): %s\n%s";
|
||||
static const char_t *ERROR_LINE_FORMAT = " at %s:%d in function %s\n";
|
||||
static errorstate_t ERROR_STATE = {
|
||||
.code = ERROR_OK,
|
||||
.message = NULL,
|
||||
.lines = NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the error state with the provided code and message.
|
||||
*
|
||||
* @param state The error state to initialize.
|
||||
* @param code The error code to set.
|
||||
* @param file The file where the error occurred.
|
||||
* @param function The function where the error occurred.
|
||||
* @param line The line number where the error occurred.
|
||||
* @param message The error message.
|
||||
* @param args The arguments for the error message.
|
||||
* @return The error code.
|
||||
*/
|
||||
errorret_t errorThrowImpl(
|
||||
errorstate_t *state,
|
||||
errorcode_t code,
|
||||
const char_t *file,
|
||||
const char_t *function,
|
||||
const int32_t line,
|
||||
const char_t *message,
|
||||
...
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns an error state with no error.
|
||||
*
|
||||
* @return An error state with code ERROR_OK.
|
||||
*/
|
||||
errorret_t errorOkImpl();
|
||||
|
||||
/**
|
||||
* Chains an error state, allowing for error propagation.
|
||||
*
|
||||
* @param retval The return value containing the error state.
|
||||
* @param file The file where the error occurred.
|
||||
* @param function The function where the error occurred.
|
||||
* @param line The line number where the error occurred.
|
||||
* @return The error code if an error occurred, otherwise continues execution.
|
||||
*/
|
||||
errorret_t errorChainImpl(
|
||||
const errorret_t retval,
|
||||
const char_t *file,
|
||||
const char_t *function,
|
||||
const int32_t line
|
||||
);
|
||||
|
||||
/**
|
||||
* Catches an error and handles it.
|
||||
*
|
||||
* @param retval The return value containing the error state.
|
||||
*/
|
||||
void errorCatch(const errorret_t retval);
|
||||
|
||||
/**
|
||||
* Prints the error state to the console.
|
||||
*
|
||||
* @param retval The return value containing the error state.
|
||||
* @return Passed retval for chaining.
|
||||
*/
|
||||
errorret_t errorPrint(const errorret_t retval);
|
||||
|
||||
/**
|
||||
* Throws an error with a formatted message.
|
||||
*
|
||||
* @param code The error code to throw.
|
||||
* @param message The format string for the error message.
|
||||
* @param ... Additional arguments for the format string.
|
||||
* @return The error code.
|
||||
*/
|
||||
#define errorThrowWithCode(code, message, ... ) \
|
||||
return errorThrowImpl(\
|
||||
&ERROR_STATE, (code), __FILE__, __func__, __LINE__, (message), \
|
||||
__VA_ARGS__ \
|
||||
)
|
||||
|
||||
/**
|
||||
* Throws an error with a default error code of ERROR_NOT_OK.
|
||||
*
|
||||
* @param message The format string for the error message.
|
||||
* @param ... Additional arguments for the format string.
|
||||
* @return The error code.
|
||||
*/
|
||||
#define errorThrow(message, ...) \
|
||||
return errorThrowImpl(\
|
||||
&ERROR_STATE, ERROR_NOT_OK, __FILE__, __func__, __LINE__, (message), \
|
||||
__VA_ARGS__ \
|
||||
)
|
||||
|
||||
/**
|
||||
* Checks if a child method errored, and if it did, then send it up the chain.
|
||||
* @param retval The return value containing the error state.
|
||||
* @return The error code if an error occurred, otherwise continues execution.
|
||||
*/
|
||||
#define errorChain(retval) \
|
||||
if ((retval).code != ERROR_OK) { \
|
||||
return errorChainImpl(retval, __FILE__, __func__, __LINE__); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns without an error.
|
||||
*/
|
||||
#define errorOk() \
|
||||
return errorOkImpl()
|
||||
|
||||
// EOF
|
@@ -8,6 +8,19 @@
|
||||
#include "memory.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
void * memoryAllocate(const size_t size) {
|
||||
assertTrue(size > 0, "Cannot allocate 0 bytes of memory.");
|
||||
void *ptr = malloc(size);
|
||||
assertNotNull(ptr, "Memory allocation failed.");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void memoryFree(void *ptr) {
|
||||
assertNotNull(ptr, "Cannot free NULL memory.");
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
||||
void memoryCopy(void *dest, const void *src, const size_t size) {
|
||||
assertNotNull(dest, "Cannot copy to NULL memory.");
|
||||
assertNotNull(src, "Cannot copy from NULL memory.");
|
||||
@@ -57,4 +70,27 @@ int_t memoryCompare(
|
||||
assertNotNull(b, "Cannot compare NULL memory.");
|
||||
assertTrue(size > 0, "Cannot compare 0 bytes of memory.");
|
||||
return memcmp(a, b, size);
|
||||
}
|
||||
|
||||
void memoryReallocate(void **ptr, const size_t size) {
|
||||
assertNotNull(ptr, "Cannot reallocate NULL pointer.");
|
||||
assertTrue(size > 0, "Cannot reallocate to 0 bytes of memory.");
|
||||
void *newPointer = memoryAllocate(size);
|
||||
assertNotNull(newPointer, "Memory reallocation failed.");
|
||||
memoryFree(*ptr);
|
||||
*ptr = newPointer;
|
||||
}
|
||||
|
||||
void memoryResize(void **ptr, const size_t oldSize, const size_t newSize) {
|
||||
assertNotNull(ptr, "Cannot resize NULL pointer.");
|
||||
if(newSize == oldSize) return;
|
||||
if(oldSize == 0) return memoryReallocate(ptr, newSize);
|
||||
|
||||
assertTrue(newSize > oldSize, "New size must be greater than old size.");
|
||||
|
||||
void *newPointer = memoryAllocate(newSize);
|
||||
assertNotNull(newPointer, "Memory resizing failed.");
|
||||
memoryCopy(newPointer, *ptr, oldSize);
|
||||
memoryFree(*ptr);
|
||||
*ptr = newPointer;
|
||||
}
|
@@ -87,4 +87,21 @@ int_t memoryCompare(
|
||||
const void *a,
|
||||
const void *b,
|
||||
const size_t size
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
* Reallocates memory.
|
||||
*
|
||||
* @param ptr The pointer to the memory to reallocate.
|
||||
* @param size The new size of the memory.
|
||||
*/
|
||||
void memoryReallocate(void **ptr, const size_t size);
|
||||
|
||||
/**
|
||||
* Reallocates memory, but copies existing data to the new memory.
|
||||
*
|
||||
* @param ptr The pointer to the memory to resize.
|
||||
* @param oldSize The old size of the memory.
|
||||
* @param newSize The new size of the memory.
|
||||
*/
|
||||
void memoryResize(void **ptr, const size_t oldSize, const size_t newSize);
|
@@ -54,29 +54,30 @@ char_t * stringToken(char_t *str, const char_t *delim) {
|
||||
int32_t stringFormat(
|
||||
char_t *dest,
|
||||
const size_t destSize,
|
||||
char_t *format,
|
||||
const char_t *format,
|
||||
...
|
||||
) {
|
||||
assertNotNull(dest, "dest must not be NULL");
|
||||
assertNotNull(format, "format must not be NULL");
|
||||
assertTrue(destSize > 0, "destSize must be greater than 0");
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int32_t result = stringFormatVA(dest, destSize, format, args);
|
||||
int32_t len = stringFormatVA(dest, destSize, format, args);
|
||||
va_end(args);
|
||||
|
||||
return result;
|
||||
return len;
|
||||
}
|
||||
|
||||
int32_t stringFormatVA(
|
||||
char_t *dest,
|
||||
const size_t destSize,
|
||||
const char_t *format,
|
||||
va_list args
|
||||
const va_list args
|
||||
) {
|
||||
assertNotNull(dest, "dest must not be NULL");
|
||||
assertNotNull(format, "format must not be NULL");
|
||||
|
||||
if(dest == NULL) {
|
||||
int32_t ret = vsnprintf(NULL, 0, format, args);
|
||||
assertTrue(ret >= 0, "Failed to format string.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
assertTrue(destSize > 0, "destSize must be greater than 0");
|
||||
int32_t ret = vsnprintf(dest, destSize, format, args);
|
||||
assertTrue(ret >= 0, "Failed to format string.");
|
||||
|
@@ -57,19 +57,28 @@ char_t * stringToken(char_t *str, const char_t *delim);
|
||||
/**
|
||||
* Formats a string.
|
||||
*
|
||||
* @param dest The destination string.
|
||||
* @param destSize The size of the destination string exc. null terminator.
|
||||
* @param dest The destination string, or NULL to get the length of the
|
||||
* formatted string.
|
||||
* @param destSize The size of the destination string exc. null terminator, can
|
||||
* be anything if dest is NULL.
|
||||
* @param format The format string.
|
||||
* @param ... The arguments to format.
|
||||
* @return The number of characters written.
|
||||
*/
|
||||
int32_t stringFormat(char_t *dest, const size_t destSize, char_t *format, ...);
|
||||
int32_t stringFormat(
|
||||
char_t *dest,
|
||||
const size_t destSize,
|
||||
const char_t *format,
|
||||
...
|
||||
);
|
||||
|
||||
/**
|
||||
* Formats a string using a va_list.
|
||||
*
|
||||
* @param dest The destination string.
|
||||
* @param destSize The size of the destination string exc. null terminator.
|
||||
* @param dest The destination string, or NULL to get the length of the
|
||||
* formatted string.
|
||||
* @param destSize The size of the destination string exc. null terminator, can
|
||||
* be anything if dest is NULL.
|
||||
* @param format The format string.
|
||||
* @param args The va_list of arguments.
|
||||
* @return The number of characters written.
|
||||
@@ -78,7 +87,7 @@ int32_t stringFormatVA(
|
||||
char_t *dest,
|
||||
const size_t destSize,
|
||||
const char_t *format,
|
||||
va_list args
|
||||
const va_list args
|
||||
);
|
||||
|
||||
/**
|
||||
|
@@ -5,25 +5,34 @@
|
||||
|
||||
# Libs
|
||||
find_package(pspsdk REQUIRED)
|
||||
find_package(SDL2 REQUIRED)
|
||||
|
||||
target_link_libraries(${DUSK_TARGET_NAME}
|
||||
PRIVATE
|
||||
pspsdk
|
||||
# pspsdk
|
||||
${SDL2_LIBRARIES}
|
||||
)
|
||||
|
||||
# Compile definitions
|
||||
target_compile_definitions(${DUSK_TARGET_NAME}
|
||||
PRIVATE
|
||||
RENDER_WIDTH=480
|
||||
RENDER_HEIGHT=272
|
||||
RENDER_WINDOW_WIDTH_DEFAULT=480
|
||||
RENDER_WINDOW_HEIGHT_DEFAULT=272
|
||||
)
|
||||
|
||||
# Includes
|
||||
target_include_directories(${DUSK_TARGET_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
${SDL2_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
# Sources
|
||||
target_sources(${DUSK_TARGET_NAME}
|
||||
PRIVATE
|
||||
input.c
|
||||
main.c
|
||||
duskpsp.c
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(display)
|
||||
# Subdirs
|
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "render.h"
|
||||
#include "input.h"
|
||||
|
||||
void renderInit(void) {
|
||||
pspDebugScreenInit();
|
||||
}
|
||||
|
||||
void renderDraw(void) {
|
||||
sceDisplayWaitVblankStart();
|
||||
pspDebugScreenSetXY(0, 2);
|
||||
|
||||
pspDebugScreenPrintf("Checking buttons \n");
|
||||
if(inputIsDown(INPUT_BIND_UP)) {
|
||||
pspDebugScreenPrintf("Up pressed\n");
|
||||
}
|
||||
if(inputIsDown(INPUT_BIND_DOWN)) {
|
||||
pspDebugScreenPrintf("Down pressed\n");
|
||||
}
|
||||
if(inputIsDown(INPUT_BIND_LEFT)) {
|
||||
pspDebugScreenPrintf("Left pressed\n");
|
||||
}
|
||||
if(inputIsDown(INPUT_BIND_RIGHT)) {
|
||||
pspDebugScreenPrintf("Right pressed\n");
|
||||
}
|
||||
if(inputIsDown(INPUT_BIND_ACTION)) {
|
||||
pspDebugScreenPrintf("Action pressed\n");
|
||||
}
|
||||
if(inputIsDown(INPUT_BIND_CANCEL)) {
|
||||
pspDebugScreenPrintf("Cancel pressed\n");
|
||||
}
|
||||
}
|
||||
|
||||
void renderDispose(void) {
|
||||
|
||||
}
|
@@ -7,5 +7,5 @@
|
||||
|
||||
#include "duskpsp.h"
|
||||
|
||||
PSP_MODULE_INFO("Dusk", 0, 1, 0);
|
||||
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | THREAD_ATTR_VFPU);
|
||||
// PSP_MODULE_INFO("Dusk", 0, 1, 0);
|
||||
// PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | THREAD_ATTR_VFPU);
|
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "duskpsp.h"
|
||||
#include "input.h"
|
||||
|
||||
uint8_t inputStateGet() {
|
||||
SceCtrlData pad;
|
||||
sceCtrlReadBufferPositive(&pad, 1);
|
||||
|
||||
if(pad.Buttons == 0) return 0;
|
||||
|
||||
uint8_t state = 0;
|
||||
if(pad.Buttons & PSP_CTRL_UP) state |= INPUT_BIND_UP;
|
||||
if(pad.Buttons & PSP_CTRL_DOWN) state |= INPUT_BIND_DOWN;
|
||||
if(pad.Buttons & PSP_CTRL_LEFT) state |= INPUT_BIND_LEFT;
|
||||
if(pad.Buttons & PSP_CTRL_RIGHT) state |= INPUT_BIND_RIGHT;
|
||||
|
||||
if(pad.Buttons & PSP_CTRL_CROSS) state |= INPUT_BIND_ACTION;
|
||||
if(pad.Buttons & PSP_CTRL_CIRCLE) state |= INPUT_BIND_CANCEL;
|
||||
|
||||
return state;
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "display/render.h"
|
||||
#include "game.h"
|
||||
|
||||
int_t exit_callback(int arg1, int arg2, void *common) {
|
||||
sceKernelExitGame();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int_t callback_thread(SceSize args, void *argp) {
|
||||
int cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
|
||||
sceKernelRegisterExitCallback(cbid);
|
||||
sceKernelSleepThreadCB();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int_t setup_callbacks(void) {
|
||||
int thid = sceKernelCreateThread("update_thread", callback_thread, 0x11, 0xFA0, 0, 0);
|
||||
if(thid >= 0) {
|
||||
sceKernelStartThread(thid, 0, 0);
|
||||
}
|
||||
return thid;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
setup_callbacks();
|
||||
renderInit();
|
||||
gameInit();
|
||||
|
||||
sceCtrlSetSamplingCycle(0);
|
||||
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
|
||||
|
||||
while(true) {
|
||||
gameUpdate();
|
||||
renderDraw();
|
||||
}
|
||||
|
||||
gameDispose();
|
||||
renderDispose();
|
||||
}
|
@@ -1,13 +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
|
||||
drawscene.c
|
||||
drawoverworld.c
|
||||
drawui.c
|
||||
drawconsole.c
|
||||
)
|
@@ -1,33 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "drawconsole.h"
|
||||
#include "console/console.h"
|
||||
|
||||
void drawConsoleInit(void) {
|
||||
}
|
||||
|
||||
void drawConsoleDraw(void) {
|
||||
CONSOLE.visible = true; // Set console to visible by default
|
||||
if(!CONSOLE.visible) return;
|
||||
|
||||
BeginBlendMode(BLEND_ALPHA);
|
||||
size_t i = 0;
|
||||
char_t *line;
|
||||
int32_t fontSize = 10;
|
||||
do {
|
||||
line = CONSOLE.line[i];
|
||||
if(line[0] == '\0') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
DrawText(line, 0, i * fontSize, fontSize, ORANGE);
|
||||
i++;
|
||||
} while(i < CONSOLE_HISTORY_MAX);
|
||||
|
||||
EndBlendMode();
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "duskraylib.h"
|
||||
|
||||
/**
|
||||
* Initializes the console drawing system.
|
||||
*/
|
||||
void drawConsoleInit(void);
|
||||
|
||||
/**
|
||||
* Draws the console to the screen.
|
||||
*/
|
||||
void drawConsoleDraw(void);
|
@@ -1,132 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "drawoverworld.h"
|
||||
#include "world/chunk.h"
|
||||
#include "world/overworld.h"
|
||||
#include "display/render.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
Camera2D DRAW_OVERWORLD_CAMERA = { 0 };
|
||||
|
||||
void drawOverworldInit(void) {
|
||||
DRAW_OVERWORLD_CAMERA = (Camera2D){
|
||||
.offset = { 0, 0 },
|
||||
.target = { 0, 0 },
|
||||
.rotation = 0.0f,
|
||||
.zoom = 1.0f
|
||||
};
|
||||
}
|
||||
|
||||
void drawOverworldDraw(void) {
|
||||
if(OVERWORLD_CAMERA_X < RENDER_WIDTH / 2) {
|
||||
DRAW_OVERWORLD_CAMERA.target.x = 0;
|
||||
} else {
|
||||
DRAW_OVERWORLD_CAMERA.target.x = OVERWORLD_CAMERA_X - (RENDER_WIDTH / 2);
|
||||
}
|
||||
|
||||
if(OVERWORLD_CAMERA_Y < RENDER_HEIGHT / 2) {
|
||||
DRAW_OVERWORLD_CAMERA.target.y = 0;
|
||||
} else {
|
||||
DRAW_OVERWORLD_CAMERA.target.y = OVERWORLD_CAMERA_Y - (RENDER_HEIGHT / 2);
|
||||
}
|
||||
|
||||
BeginMode2D(DRAW_OVERWORLD_CAMERA);
|
||||
|
||||
// Bottom layer
|
||||
chunk_t *chunk = CHUNK_MAP.chunks;
|
||||
|
||||
Color colors[] = {
|
||||
RED, GREEN, BLUE, YELLOW, PURPLE, ORANGE, PINK, BROWN,
|
||||
DARKGRAY, LIGHTGRAY, DARKBLUE, DARKGREEN, DARKPURPLE,
|
||||
DARKBROWN
|
||||
};
|
||||
uint8_t colorCount = sizeof(colors) / sizeof(Color);
|
||||
|
||||
do {
|
||||
// Base layer
|
||||
for(uint8_t i = 0; i < CHUNK_TILE_COUNT; i++) {
|
||||
tile_t tile = chunk->tilesBase[i];
|
||||
if(tile == 0) continue; // Skip empty tiles
|
||||
|
||||
uint32_t tilemapIndex = tile - 1; // Convert to zero-based index
|
||||
uint32_t x = (uint32_t)chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT + (i % CHUNK_WIDTH) * TILE_WIDTH_HEIGHT;
|
||||
uint32_t y = (uint32_t)chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT + (i / CHUNK_WIDTH) * TILE_WIDTH_HEIGHT;
|
||||
uint32_t tilemapX = (tilemapIndex % (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH_HEIGHT)) * TILE_WIDTH_HEIGHT;
|
||||
uint32_t tilemapY = (tilemapIndex / (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH_HEIGHT)) * TILE_WIDTH_HEIGHT;
|
||||
|
||||
DrawTextureRec(
|
||||
RENDER_TILEMAP_TEXTURE,
|
||||
(Rectangle){
|
||||
tilemapX,
|
||||
tilemapY,
|
||||
TILE_WIDTH_HEIGHT,
|
||||
TILE_WIDTH_HEIGHT
|
||||
},
|
||||
(Vector2){ x, y },
|
||||
WHITE
|
||||
);
|
||||
}
|
||||
|
||||
// Base overlay layer
|
||||
for(uint8_t i = 0; i < CHUNK_TILE_COUNT; i++) {
|
||||
tile_t tile = chunk->tilesBaseOverlay[i];
|
||||
if(tile == 0) continue; // Skip empty tiles
|
||||
|
||||
uint32_t tilemapIndex = tile - 1; // Convert to zero-based index
|
||||
uint32_t x = (uint32_t)chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT + (i % CHUNK_WIDTH) * TILE_WIDTH_HEIGHT;
|
||||
uint32_t y = (uint32_t)chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT + (i / CHUNK_WIDTH) * TILE_WIDTH_HEIGHT;
|
||||
uint32_t tilemapX = (tilemapIndex % (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH_HEIGHT)) * TILE_WIDTH_HEIGHT;
|
||||
uint32_t tilemapY = (tilemapIndex / (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH_HEIGHT)) * TILE_WIDTH_HEIGHT;
|
||||
|
||||
DrawTextureRec(
|
||||
RENDER_TILEMAP_TEXTURE,
|
||||
(Rectangle){
|
||||
tilemapX,
|
||||
tilemapY,
|
||||
TILE_WIDTH_HEIGHT,
|
||||
TILE_WIDTH_HEIGHT
|
||||
},
|
||||
(Vector2){ x, y },
|
||||
WHITE
|
||||
);
|
||||
}
|
||||
|
||||
chunk++;
|
||||
} while(chunk < CHUNK_MAP.chunks + CHUNK_MAP_COUNT);
|
||||
|
||||
// Entities
|
||||
entity_t *entity = ENTITIES;
|
||||
do {
|
||||
drawOverworldDrawEntity(entity++);
|
||||
} while(entity < ENTITIES + ENTITY_COUNT_MAX);
|
||||
|
||||
EndMode2D();
|
||||
}
|
||||
|
||||
|
||||
void drawOverworldDrawEntity(const entity_t *entity) {
|
||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||
if(entity->type == ENTITY_TYPE_NULL) return; // Skip null entities
|
||||
|
||||
uint32_t x = (uint32_t)(entity->x);
|
||||
uint32_t y = (uint32_t)(entity->y);
|
||||
uint32_t row = 0;
|
||||
uint32_t col = entity->dir;
|
||||
|
||||
DrawTextureRec(
|
||||
RENDER_ENTITIES_TEXTURE,
|
||||
(Rectangle){
|
||||
col * TILE_WIDTH_HEIGHT,
|
||||
row * TILE_WIDTH_HEIGHT,
|
||||
TILE_WIDTH_HEIGHT,
|
||||
TILE_WIDTH_HEIGHT
|
||||
},
|
||||
(Vector2){ x, y },
|
||||
WHITE
|
||||
);
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "duskraylib.h"
|
||||
#include "entity/entity.h"
|
||||
|
||||
/**
|
||||
* Initializes the overworld drawing system.
|
||||
*/
|
||||
void drawOverworldInit(void);
|
||||
|
||||
/**
|
||||
* Renders the overworld, including map and characters.
|
||||
*/
|
||||
void drawOverworldDraw(void);
|
||||
|
||||
/**
|
||||
* Renders a specific entity in the overworld.
|
||||
*
|
||||
* @param entity The entity to render.
|
||||
*/
|
||||
void drawOverworldDrawEntity(const entity_t *entity);
|
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "drawscene.h"
|
||||
#include "display/scene.h"
|
||||
#include "assert/assert.h"
|
||||
#include "drawoverworld.h"
|
||||
|
||||
void drawScene(void) {
|
||||
switch(SCENE_CURRENT){
|
||||
case SCENE_INITIAL:
|
||||
break;
|
||||
|
||||
case SCENE_OVERWORLD:
|
||||
drawOverworldDraw();
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown scene in drawScene");
|
||||
}
|
||||
}
|
@@ -1,122 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "drawui.h"
|
||||
#include "ui/uitextbox.h"
|
||||
#include "util/memory.h"
|
||||
#include "assert/assert.h"
|
||||
#include "display/render.h"
|
||||
|
||||
void drawUIInit(void) {
|
||||
}
|
||||
|
||||
void drawUI() {
|
||||
drawUITextbox();
|
||||
}
|
||||
|
||||
void drawUITextbox() {
|
||||
if(!UI_TEXTBOX.visible) return;
|
||||
|
||||
// Semi-transparent dark blue
|
||||
Color background = (Color){ 0, 0, 128, 128 };
|
||||
|
||||
uint32_t x = 0;
|
||||
uint32_t y = RENDER_HEIGHT - UI_TEXTBOX_HEIGHT;
|
||||
|
||||
DrawRectangle(
|
||||
x, y,
|
||||
UI_TEXTBOX_WIDTH, UI_TEXTBOX_HEIGHT,
|
||||
background
|
||||
);
|
||||
|
||||
BeginBlendMode(BLEND_ALPHA);
|
||||
if(UI_TEXTBOX.charsRevealed > 0) {
|
||||
uint8_t charsRendered = 0;
|
||||
|
||||
// For each line
|
||||
for(uint8_t i = 0; i < UI_TEXTBOX_LINES_PER_PAGE; i++) {
|
||||
// Get count of chars in the line
|
||||
uint8_t lineLength = UI_TEXTBOX.lineLengths[
|
||||
i + (UI_TEXTBOX.page * UI_TEXTBOX_LINES_PER_PAGE)
|
||||
];
|
||||
if(lineLength == 0) continue;
|
||||
|
||||
// Determine how many chars left to render
|
||||
uint8_t lineChars = UI_TEXTBOX.charsRevealed - charsRendered;
|
||||
|
||||
// Don't render more than in line
|
||||
if(lineChars > lineLength) lineChars = lineLength;
|
||||
assertTrue(lineChars > 0, "Line chars must be greater than 0");
|
||||
|
||||
// Update how many rendered
|
||||
charsRendered += lineChars;
|
||||
|
||||
for(uint8_t j = 0; j < lineChars; j++) {
|
||||
drawUIChar(
|
||||
UI_TEXTBOX.text[
|
||||
(i * UI_TEXTBOX_CHARS_PER_LINE) + j +
|
||||
(UI_TEXTBOX.page * UI_TEXTBOX_CHARS_PER_PAGE)
|
||||
],
|
||||
x + UI_TEXTBOX_PADDING_X + UI_TEXTBOX_BORDER_WIDTH + (
|
||||
j * FONT_TILE_WIDTH
|
||||
),
|
||||
y + UI_TEXTBOX_PADDING_Y + UI_TEXTBOX_BORDER_HEIGHT + (
|
||||
i * FONT_TILE_HEIGHT
|
||||
),
|
||||
WHITE
|
||||
);
|
||||
}
|
||||
|
||||
// Check if we're done rendering text
|
||||
if(UI_TEXTBOX.charsRevealed - charsRendered == 0) break;
|
||||
}
|
||||
}
|
||||
EndBlendMode();
|
||||
}
|
||||
|
||||
void drawUIText(
|
||||
const uint8_t *text,
|
||||
const uint16_t length,
|
||||
const int32_t x,
|
||||
const int32_t y,
|
||||
const Color color
|
||||
) {
|
||||
assertNotNull(text, "Text to draw cannot be NULL");
|
||||
if(length == 0) return;
|
||||
|
||||
BeginBlendMode(BLEND_ALPHA);
|
||||
for(uint16_t i = 0; i < length; i++) {
|
||||
drawUIChar(text[i], x + (i * FONT_TILE_WIDTH), y, color);
|
||||
}
|
||||
EndBlendMode();
|
||||
}
|
||||
|
||||
void drawUIChar(
|
||||
const char_t c,
|
||||
const int32_t x,
|
||||
const int32_t y,
|
||||
const Color color
|
||||
) {
|
||||
if(c < ' ' || c > '~') return; // Only print printable ASCII characters
|
||||
|
||||
int32_t charIndex = TILE_INDEXES[c - FONT_CHAR_START];
|
||||
int32_t charX = (charIndex % FONT_COLUMN_COUNT) * FONT_TILE_WIDTH;
|
||||
int32_t charY = (charIndex / FONT_COLUMN_COUNT) * FONT_TILE_HEIGHT;
|
||||
|
||||
// FLip Y coordinate for raylib texture coordinates
|
||||
DrawTextureRec(
|
||||
RENDER_FONT_TEXTURE,
|
||||
(Rectangle) {
|
||||
(float) charX,
|
||||
(float) charY, // Flip Y by adding height
|
||||
(float) FONT_TILE_WIDTH,
|
||||
(float) FONT_TILE_HEIGHT // Negative height to flip the texture
|
||||
},
|
||||
(Vector2) { x, y }, // Add FONT_HEIGHT to flip Y
|
||||
color
|
||||
);
|
||||
}
|
@@ -1,56 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "duskraylib.h"
|
||||
|
||||
/**
|
||||
* Initializes the UI drawing system.
|
||||
*/
|
||||
void drawUIInit(void);
|
||||
|
||||
/**
|
||||
* Draws all the UI elements to the screen in the correct order.
|
||||
*/
|
||||
void drawUI(void);
|
||||
|
||||
/**
|
||||
* Draws the UI textbox to the screen.
|
||||
*/
|
||||
void drawUITextbox(void);
|
||||
|
||||
/**
|
||||
* Draws text to the screen at the specified position with the given color.
|
||||
*
|
||||
* @param text The text to draw.
|
||||
* @param length The length of the text to draw.
|
||||
* @param x The x-coordinate to draw the text at.
|
||||
* @param y The y-coordinate to draw the text at.
|
||||
* @param color The color of the text.
|
||||
*/
|
||||
void drawUIText(
|
||||
const uint8_t *text,
|
||||
const uint16_t length,
|
||||
const int32_t x,
|
||||
const int32_t y,
|
||||
const Color color
|
||||
);
|
||||
|
||||
/**
|
||||
* Draws a single character to the screen at the specified position with the given color.
|
||||
*
|
||||
* @param c The character to draw.
|
||||
* @param x The x-coordinate to draw the character at.
|
||||
* @param y The y-coordinate to draw the character at.
|
||||
* @param color The color of the character.
|
||||
*/
|
||||
void drawUIChar(
|
||||
const char_t c,
|
||||
const int32_t x,
|
||||
const int32_t y,
|
||||
const Color color
|
||||
);
|
@@ -1,92 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "render.h"
|
||||
#include "display/draw/drawscene.h"
|
||||
#include "display/draw/drawoverworld.h"
|
||||
#include "display/draw/drawui.h"
|
||||
#include "display/draw/drawconsole.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
RenderTexture2D RENDER_SCREEN_TEXTURE;
|
||||
Texture2D RENDER_TILEMAP_TEXTURE;
|
||||
Texture2D RENDER_ENTITIES_TEXTURE;
|
||||
Texture2D RENDER_FONT_TEXTURE;
|
||||
|
||||
void renderInit(void) {
|
||||
InitWindow(
|
||||
RENDER_WIDTH * 3,
|
||||
RENDER_HEIGHT * 3,
|
||||
"Dusk Raylib Render"
|
||||
);
|
||||
SetTargetFPS(60);
|
||||
SetWindowState(
|
||||
FLAG_WINDOW_RESIZABLE |
|
||||
FLAG_WINDOW_HIGHDPI |
|
||||
FLAG_VSYNC_HINT
|
||||
);
|
||||
|
||||
RENDER_SCREEN_TEXTURE = LoadRenderTexture(RENDER_WIDTH, RENDER_HEIGHT);
|
||||
RENDER_TILEMAP_TEXTURE = LoadTexture("../data/tilemap.png");
|
||||
RENDER_ENTITIES_TEXTURE = LoadTexture("../data/entities.png");
|
||||
RENDER_FONT_TEXTURE = LoadTexture("../data/minogram_6x10.png");
|
||||
|
||||
drawOverworldInit();
|
||||
drawUIInit();
|
||||
drawConsoleInit();
|
||||
}
|
||||
|
||||
void renderDraw(void) {
|
||||
// Draw the actual game.
|
||||
BeginBlendMode(BLEND_ALPHA_PREMULTIPLY);
|
||||
BeginTextureMode(RENDER_SCREEN_TEXTURE);
|
||||
ClearBackground(BLACK);
|
||||
|
||||
drawScene();
|
||||
drawUI();
|
||||
|
||||
EndTextureMode();
|
||||
|
||||
// Draw the render texture to the screen.
|
||||
BeginDrawing();
|
||||
ClearBackground(RED);
|
||||
// Keep aspect and center the render
|
||||
int32_t renderWidth, renderHeight, renderX, renderY;
|
||||
const int32_t width = GetScreenWidth();
|
||||
const int32_t height = GetScreenHeight();
|
||||
if(RENDER_WIDTH * height > RENDER_HEIGHT * width) {
|
||||
renderWidth = width;
|
||||
renderHeight = (RENDER_HEIGHT * width) / RENDER_WIDTH;
|
||||
renderX = 0;
|
||||
renderY = (height - renderHeight) / 2;
|
||||
} else {
|
||||
renderWidth = (RENDER_WIDTH * height) / RENDER_HEIGHT;
|
||||
renderHeight = height;
|
||||
renderX = (width - renderWidth) / 2;
|
||||
renderY = 0;
|
||||
}
|
||||
DrawTexturePro(
|
||||
RENDER_SCREEN_TEXTURE.texture,
|
||||
(Rectangle) { 0, 0, RENDER_WIDTH, -RENDER_HEIGHT },
|
||||
(Rectangle) { renderX, renderY, renderWidth, renderHeight },
|
||||
(Vector2) { 0, 0 },
|
||||
0.0f,
|
||||
WHITE
|
||||
);
|
||||
|
||||
drawConsoleDraw();
|
||||
|
||||
EndDrawing();
|
||||
EndBlendMode();
|
||||
}
|
||||
|
||||
void renderDispose(void) {
|
||||
UnloadRenderTexture(RENDER_SCREEN_TEXTURE);
|
||||
UnloadTexture(RENDER_TILEMAP_TEXTURE);
|
||||
UnloadTexture(RENDER_ENTITIES_TEXTURE);
|
||||
CloseWindow();
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "duskraylib.h"
|
||||
#include "display/renderbase.h"
|
||||
|
||||
extern RenderTexture2D RENDER_SCREEN_TEXTURE;
|
||||
extern Texture2D RENDER_TILEMAP_TEXTURE;
|
||||
extern Texture2D RENDER_ENTITIES_TEXTURE;
|
||||
extern Texture2D RENDER_FONT_TEXTURE;
|
@@ -1,89 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "duskraylib.h"
|
||||
#include "input.h"
|
||||
|
||||
typedef struct {
|
||||
int32_t key;
|
||||
uint8_t bind;
|
||||
} inputkbmap_t;
|
||||
|
||||
typedef struct {
|
||||
GamepadButton button;
|
||||
uint8_t bind;
|
||||
} inputgpmap_t;
|
||||
|
||||
typedef struct {
|
||||
int32_t key;
|
||||
uint32_t bind;
|
||||
} inputkeyboardmap_t;
|
||||
|
||||
inputkbmap_t INPUT_KB_MAP[] = {
|
||||
{ KEY_UP, INPUT_BIND_UP },
|
||||
{ KEY_W, INPUT_BIND_UP },
|
||||
{ KEY_DOWN, INPUT_BIND_DOWN },
|
||||
{ KEY_S, INPUT_BIND_DOWN },
|
||||
{ KEY_LEFT, INPUT_BIND_LEFT },
|
||||
{ KEY_A, INPUT_BIND_LEFT },
|
||||
{ KEY_RIGHT, INPUT_BIND_RIGHT },
|
||||
{ KEY_D, INPUT_BIND_RIGHT },
|
||||
|
||||
{ KEY_SPACE, INPUT_BIND_ACTION },
|
||||
{ KEY_E, INPUT_BIND_ACTION },
|
||||
{ KEY_ENTER, INPUT_BIND_ACTION },
|
||||
|
||||
{ KEY_ESCAPE, INPUT_BIND_CANCEL },
|
||||
{ KEY_Q, INPUT_BIND_CANCEL },
|
||||
{ KEY_BACKSPACE, INPUT_BIND_CANCEL },
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
inputgpmap_t INPUT_GP_MAP[] = {
|
||||
{ GAMEPAD_BUTTON_LEFT_FACE_UP, INPUT_BIND_UP },
|
||||
{ GAMEPAD_BUTTON_LEFT_FACE_DOWN, INPUT_BIND_DOWN },
|
||||
{ GAMEPAD_BUTTON_LEFT_FACE_LEFT, INPUT_BIND_LEFT },
|
||||
{ GAMEPAD_BUTTON_LEFT_FACE_RIGHT, INPUT_BIND_RIGHT },
|
||||
|
||||
{ GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, INPUT_BIND_ACTION },
|
||||
{ GAMEPAD_BUTTON_RIGHT_FACE_DOWN, INPUT_BIND_CANCEL },
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
uint8_t inputStateGet() {
|
||||
uint8_t state = 0;
|
||||
|
||||
inputkbmap_t *kbMap = INPUT_KB_MAP;
|
||||
do {
|
||||
if(IsKeyDown(kbMap->key)) state |= kbMap->bind;
|
||||
kbMap++;
|
||||
} while(kbMap->key != 0);
|
||||
|
||||
for(uint32_t i = 0; i < 32; i++) {
|
||||
if(!IsGamepadAvailable(i)) continue;
|
||||
|
||||
inputgpmap_t *gpMap = INPUT_GP_MAP;
|
||||
do {
|
||||
if(IsGamepadButtonDown(i, gpMap->button)) state |= gpMap->bind;
|
||||
gpMap++;
|
||||
} while(gpMap->button != 0);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
// uint32_t inputKeyboardPop(void) {
|
||||
// while(true) {
|
||||
// int32_t key = GetKeyPressed();
|
||||
// if(key == 0) return 0;
|
||||
// printf("Got key: %d\n", key);
|
||||
// return (uint32_t)key;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "display/render.h"
|
||||
#include "game.h"
|
||||
|
||||
void main(void) {
|
||||
renderInit();
|
||||
gameInit();
|
||||
|
||||
while(!WindowShouldClose()) {
|
||||
gameUpdate();
|
||||
renderDraw();
|
||||
}
|
||||
|
||||
gameDispose();
|
||||
renderDispose();
|
||||
}
|
@@ -10,11 +10,11 @@ target_compile_definitions(${DUSK_TARGET_NAME}
|
||||
)
|
||||
|
||||
# Libs
|
||||
find_package(raylib REQUIRED)
|
||||
find_package(SDL2 REQUIRED)
|
||||
|
||||
target_link_libraries(${DUSK_TARGET_NAME}
|
||||
PUBLIC
|
||||
raylib
|
||||
SDL2::SDL2
|
||||
)
|
||||
|
||||
|
@@ -10,4 +10,4 @@ target_sources(${DUSK_TARGET_NAME}
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(draw)
|
||||
# add_subdirectory(draw)
|
83
src/dusksdl2/display/render.c
Normal file
83
src/dusksdl2/display/render.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "render.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
SDL_Window *RENDER_WINDOW;
|
||||
SDL_Renderer *RENDER_RENDERER;
|
||||
bool_t RENDER_RUNNING;
|
||||
|
||||
errorret_t renderInit(void) {
|
||||
if(SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
errorThrow(
|
||||
"SDL Failed to Initialize: %s",
|
||||
SDL_GetError()
|
||||
);
|
||||
}
|
||||
|
||||
RENDER_WINDOW = SDL_CreateWindow(
|
||||
"DuskSDL2",
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
RENDER_WINDOW_WIDTH_DEFAULT,
|
||||
RENDER_WINDOW_HEIGHT_DEFAULT,
|
||||
SDL_WINDOW_SHOWN
|
||||
);
|
||||
|
||||
#if RENDER_USE_FRAMEBUFFER
|
||||
printf("Using framebuffer for rendering\n");
|
||||
#else
|
||||
printf("Using window for rendering\n");
|
||||
#endif
|
||||
|
||||
RENDER_RENDERER = SDL_CreateRenderer(
|
||||
RENDER_WINDOW,
|
||||
-1,
|
||||
SDL_RENDERER_ACCELERATED
|
||||
);
|
||||
|
||||
if(!RENDER_RENDERER) {
|
||||
errorThrow("SDL_CreateRenderer failed: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
RENDER_RUNNING = true;
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t renderDraw(void) {
|
||||
SDL_Event event;
|
||||
while(SDL_PollEvent(&event)) {
|
||||
if(event.type == SDL_QUIT) {
|
||||
RENDER_RUNNING = false;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(RENDER_RENDERER, 0, 0, 0, 255);
|
||||
SDL_RenderClear(RENDER_RENDERER);
|
||||
|
||||
// Draw red triangle
|
||||
SDL_SetRenderDrawColor(RENDER_RENDERER, 255, 0, 0, 255);
|
||||
SDL_RenderDrawLine(RENDER_RENDERER, 100, 100, 200, 100);
|
||||
SDL_RenderDrawLine(RENDER_RENDERER, 200, 100, 150, 50);
|
||||
SDL_RenderDrawLine(RENDER_RENDERER, 150, 50, 100, 100);
|
||||
|
||||
SDL_RenderPresent(RENDER_RENDERER);
|
||||
|
||||
RENDER_FRAME++;
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t renderDispose(void) {
|
||||
SDL_DestroyRenderer(RENDER_RENDERER);
|
||||
SDL_DestroyWindow(RENDER_WINDOW);
|
||||
SDL_Quit();
|
||||
|
||||
errorOk();
|
||||
}
|
27
src/dusksdl2/display/render.h
Normal file
27
src/dusksdl2/display/render.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "dusksdl2.h"
|
||||
#include "display/renderbase.h"
|
||||
|
||||
#ifndef RENDER_WINDOW_WIDTH_DEFAULT
|
||||
#define RENDER_WINDOW_WIDTH_DEFAULT RENDER_WIDTH * 3
|
||||
#endif
|
||||
#ifndef RENDER_WINDOW_HEIGHT_DEFAULT
|
||||
#define RENDER_WINDOW_HEIGHT_DEFAULT RENDER_HEIGHT * 3
|
||||
#endif
|
||||
|
||||
#if RENDER_WIDTH == RENDER_WINDOW_WIDTH_DEFAULT && RENDER_HEIGHT == RENDER_WINDOW_HEIGHT_DEFAULT
|
||||
#define RENDER_USE_FRAMEBUFFER 0
|
||||
#else
|
||||
#define RENDER_USE_FRAMEBUFFER 1
|
||||
#endif
|
||||
|
||||
extern SDL_Window *RENDER_WINDOW;
|
||||
extern SDL_Renderer *RENDER_RENDERER;
|
||||
extern bool_t RENDER_RUNNING;
|
35
src/dusksdl2/display/renderbackbuffer.c
Normal file
35
src/dusksdl2/display/renderbackbuffer.c
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "renderbackbuffer.h"
|
||||
|
||||
#if RENDER_USE_FRAMEBUFFER
|
||||
SDL_Texture *RENDER_BACKBUFFER;
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
void renderBackBufferInit(void) {
|
||||
#if RENDER_USE_FRAMEBUFFER
|
||||
RENDER_BACKBUFFER = SDL_CreateTexture(
|
||||
RENDER_RENDERER,
|
||||
SDL_PIXELFORMAT_RGBA8888,
|
||||
SDL_TEXTUREACCESS_TARGET,
|
||||
RENDER_WINDOW_WIDTH_DEFAULT,
|
||||
RENDER_WINDOW_HEIGHT_DEFAULT
|
||||
);
|
||||
|
||||
if(!RENDER_BACKBUFFER) {
|
||||
assertUnreachable("SDL_CreateTexture failed\n");
|
||||
return;
|
||||
}
|
||||
#else
|
||||
// No back buffer needed for window rendering
|
||||
#endif
|
||||
|
||||
|
||||
}
|
@@ -6,5 +6,4 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "duskpsp.h"
|
||||
#include "display/renderbase.h"
|
||||
#include "dusksdl2.h"
|
@@ -7,4 +7,4 @@
|
||||
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
#include <raylib.h>
|
||||
#include <SDL2/SDL.h>
|
@@ -5,10 +5,11 @@
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "duskraylib.h"
|
||||
#include "dusksdl2.h"
|
||||
#include "input.h"
|
||||
|
||||
/**
|
||||
* Draws the current scene to the screen.
|
||||
*/
|
||||
void drawScene(void);
|
||||
uint8_t inputStateGet() {
|
||||
uint8_t state = 0;
|
||||
|
||||
return state;
|
||||
}
|
32
src/dusksdl2/main.c
Normal file
32
src/dusksdl2/main.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "display/render.h"
|
||||
#include "game.h"
|
||||
|
||||
#define mainError(ret) \
|
||||
if((ret).code != ERROR_OK) { \
|
||||
errorPrint(ret); \
|
||||
return (ret).code; \
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
errorret_t ret;
|
||||
|
||||
mainError(renderInit());
|
||||
gameInit();
|
||||
|
||||
while(RENDER_RUNNING) {
|
||||
gameUpdate();
|
||||
mainError(renderDraw());
|
||||
}
|
||||
|
||||
gameDispose();
|
||||
mainError(renderDispose());
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user