Render test

This commit is contained in:
YourWishes committed 2025-06-10 17:09:33 -05:00
1 parent a2fd58fda7
commit 1b6db0c643
47 files changed
+219 -370

No files matched your search

+3 -25
View File
@@ -1,29 +1,7 @@
# Copyright (c) 2025 Dominic Masters
#
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Libs
target_link_libraries(${DUSK_TARGET_NAME}
PUBLIC
m
)
# Includes
target_include_directories(${DUSK_TARGET_NAME}
PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
main.c
input.c
)
# Subdirs
add_subdirectory(assert)
add_subdirectory(display)
add_subdirectory(rpg)
add_subdirectory(util)
add_subdirectory(dusk)
add_subdirectory(duskraylib)
-22
View File
@@ -1,22 +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 {
COLOR_BLACK,
COLOR_RED,
COLOR_GREEN,
COLOR_YELLOW,
COLOR_BLUE,
COLOR_MAGENTA,
COLOR_CYAN,
COLOR_WHITE,
} color_t;
#define COLOR_COUNT (COLOR_WHITE + 1)
-71
View File
@@ -1,71 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assert/assert.h"
#include "render.h"
#include "term.h"
#include "rpg/entity/entity.h"
void renderInit() {
termInit();
}
void renderUpdate() {
char_t c;
color_t color, colorCurrent;
entity_t *ent;
termUpdate();
termClear();
colorCurrent = COLOR_WHITE;
termPushColor(colorCurrent);
for(int32_t y = 0; y < TERM.height; y++) {
for(int32_t x = 0; x < TERM.width; x++) {
color = COLOR_WHITE;
c = ' ';
ent = entityGetAt(x, y);
if(ent) {
color = COLOR_RED;
switch(ent->dir) {
case ENTITY_DIR_UP:
c = '^';
color = COLOR_GREEN;
break;
case ENTITY_DIR_DOWN:
c = 'v';
color = COLOR_RED;
break;
case ENTITY_DIR_LEFT:
c = '<';
color = COLOR_YELLOW;
break;
case ENTITY_DIR_RIGHT:
c = '>';
color = COLOR_BLUE;
break;
default:
assertUnreachable("Invalid entity direction");
break;
}
}
if(c == ' ') {
termPushChar(' ');
continue;
}
if(color != colorCurrent) termPushColor((colorCurrent = color));
termPushChar(c);
}
}
termFlush();
}
-59
View File
@@ -1,59 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assert/assert.h"
#include "term.h"
#include "util/memory.h"
#include <sys/ioctl.h>
term_t TERM;
const char_t* TERM_COLORS[COLOR_COUNT] = {
[COLOR_BLACK] = "\033[30m",
[COLOR_RED] = "\033[31m",
[COLOR_GREEN] = "\033[32m",
[COLOR_YELLOW] = "\033[33m",
[COLOR_BLUE] = "\033[34m",
[COLOR_MAGENTA] = "\033[35m",
[COLOR_CYAN] = "\033[36m",
[COLOR_WHITE] = "\033[37m"
};
void termInit() {
memoryZero(&TERM, sizeof(term_t));
struct winsize w;
if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0) {
TERM.width = w.ws_col;
TERM.height = w.ws_row;
}
}
void termUpdate() {
struct winsize w;
if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0) {
TERM.width = w.ws_col;
TERM.height = w.ws_row;
}
}
void termClear() {
printf("\033[2J\033[H");
}
void termPushColor(const color_t color) {
assertTrue(color < COLOR_COUNT, "Invalid color index");
printf("%s", TERM_COLORS[color]);
}
void termPushChar(const char_t c) {
putchar(c);
}
void termFlush() {
fflush(stdout);
}
-48
View File
@@ -1,48 +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 "display/color.h"
typedef struct {
int32_t width;
int32_t height;
} term_t;
extern term_t TERM;
extern const char_t* TERM_COLORS[COLOR_COUNT];
/**
* Initialize the terminal system.
*/
void termInit();
/**
* Update the terminal system, typically called each frame.
*/
void termUpdate();
/**
* Clear the terminal screen and reset cursor position.
*/
void termClear();
void termPushColor(const color_t color);
/**
* Push a character to the terminal output buffer.
*
* @param c The character to push.
*/
void termPushChar(const char_t c);
/**
* Flush the terminal output buffer to the terminal.
*/
void termFlush();
+29
View File
@@ -0,0 +1,29 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Libs
target_link_libraries(${DUSK_TARGET_NAME}
PUBLIC
m
)
# Includes
target_include_directories(${DUSK_TARGET_NAME}
PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
main.c
input.c
)
# Subdirs
add_subdirectory(assert)
add_subdirectory(display)
add_subdirectory(rpg)
add_subdirectory(util)
File renamed without changes.
File renamed without changes.
File renamed without changes.
+9
View File
@@ -0,0 +1,9 @@
# 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
)
@@ -8,6 +8,9 @@
#pragma once
#include "dusk.h"
extern const uint16_t RENDER_WIDTH;
extern const uint16_t RENDER_HEIGHT;
/**
* Init the render system.
*/
@@ -16,4 +19,9 @@ void renderInit();
/**
* Update the render system.
*/
void renderUpdate();
bool_t renderUpdate();
/**
* Dispose of the render system.
*/
void renderDispose();
View File
File renamed without changes.
+29
View File
@@ -0,0 +1,29 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "input.h"
#include "assert/assert.h"
input_t INPUT;
bool_t inputIsDown(const uint8_t key) {
assertTrue(key < INPUT_COUNT, "Invalid input key");
return (INPUT.current & key) != 0;
}
bool_t inputWasDown(const uint8_t key) {
assertTrue(key < INPUT_COUNT, "Invalid input key");
return (INPUT.previous & key) != 0;
}
bool_t inputWasPressed(const uint8_t key) {
return inputIsDown(key) && !inputWasDown(key);
}
bool_t inputWasReleased(const uint8_t key) {
return !inputIsDown(key) && inputWasDown(key);
}
+6 -9
View File
@@ -15,25 +15,17 @@
#define INPUT_RIGHT (1 << 3)
#define INPUT_ACTION (1 << 4)
#define INPUT_CANCEL (1 << 5)
#define INPUT_COUNT (INPUT_CANCEL + 1)
#define INPUT_BUFFER_SIZE 128
typedef struct {
uint8_t current;
uint8_t previous;
bool_t isRawMode;
struct termios origin;
} input_t;
extern input_t INPUT;
typedef struct {
char_t *key;
uint8_t value;
} inputmap_t;
extern inputmap_t INPUT_MAP[];
/**
* Initializes the input system.
*/
@@ -44,6 +36,11 @@ void inputInit();
*/
void inputUpdate();
/**
* Disposes of the input system, restoring terminal settings.
*/
void inputDispose();
/**
* Returns true if the specified key is currently pressed down.
*
+1 -8
View File
@@ -33,14 +33,7 @@ int32_t main(const int32_t argc, const char **argv) {
entityUpdate(ent++);
} while(ent < (ENTITIES + ENTITY_COUNT));
if(inputIsDown(INPUT_DOWN)) {
printf("Input down pressed\n");
} else {
printf("Input down not pressed\n");
}
// renderUpdate();
usleep(16 * 1000); // Sleep for 16 milliseconds (60 FPS)
if(!renderUpdate()) break;
}
return EXIT_SUCCESS;
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -8,7 +8,9 @@
#pragma once
#include "player.h"
#define ENTITY_MOVE_SUBPIXEL 4
#define ENTITY_WIDTH 16
#define ENTITY_HEIGHT 16
#define ENTITY_MOVE_SUBPIXEL ENTITY_WIDTH
typedef enum {
ENTITY_DIR_UP = 0,
@@ -31,7 +33,7 @@ typedef enum {
typedef struct _entity_t {
entitytype_t type;
uint8_t x, y;
uint8_t subX, subY;
int8_t subX, subY;
entitydir_t dir;
// Per type data
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+34
View File
@@ -0,0 +1,34 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
include(FetchContent)
# Libs
FetchContent_Declare(
raylib
URL https://github.com/raysan5/raylib/archive/refs/tags/5.5.tar.gz
URL_HASH MD5=61638c4c2c097fbca1d6a71e4da36c16
)
FetchContent_MakeAvailable(raylib)
target_link_libraries(${DUSK_TARGET_NAME}
PUBLIC
raylib
)
# Includes
target_include_directories(${DUSK_TARGET_NAME}
PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
input.c
)
# Subdirs
add_subdirectory(display)
@@ -7,5 +7,4 @@
target_sources(${DUSK_TARGET_NAME}
PRIVATE
render.c
term.c
)
+53
View File
@@ -0,0 +1,53 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assert/assert.h"
#include "display/render.h"
#include "raylib.h"
#include "rpg/entity/entity.h"
const uint16_t RENDER_WIDTH = 800;
const uint16_t RENDER_HEIGHT = 600;
void renderInit() {
InitWindow(RENDER_WIDTH, RENDER_HEIGHT, "Dusk");
SetTargetFPS(60);
}
bool_t renderUpdate() {
// End rendering?
if(WindowShouldClose()) return false;
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("Hello, Dusk!", 10, 10, 20, BLACK);
entity_t *ent = ENTITIES;
do {
if(ent->type == ENTITY_TYPE_NULL) {
ent++;
continue;
}
DrawRectangle(
(ent->x * ENTITY_WIDTH) + ent->subX,
(ent->y * ENTITY_HEIGHT) + ent->subY,
ENTITY_WIDTH,
ENTITY_HEIGHT,
RED
);
ent++;
} while(ent < (ENTITIES + ENTITY_COUNT));
EndDrawing();
return true;
}
void renderDispose() {
CloseWindow();
}
+47
View File
@@ -0,0 +1,47 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "input.h"
#include "raylib.h"
typedef struct {
int32_t key;
uint8_t flag;
} inputmap_t;
const inputmap_t INPUT_MAP[] = {
{ KEY_W, INPUT_UP },
{ KEY_S, INPUT_DOWN },
{ KEY_A, INPUT_LEFT },
{ KEY_D, INPUT_RIGHT },
{ KEY_SPACE, INPUT_ACTION },
{ KEY_ESCAPE, INPUT_CANCEL },
{ 0, 0 }
};
void inputInit() {
}
void inputUpdate() {
uint8_t state = 0;
inputmap_t *map = INPUT_MAP;
do {
if(IsKeyDown(map->key)) {
state |= map->flag;
}
map++;
} while(map->key != 0);
INPUT.previous = INPUT.current;
INPUT.current = state;
}
void inputDispose() {
}
-120
View File
@@ -1,120 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "input.h"
#include "util/memory.h"
#include "assert/assert.h"
#include <fcntl.h>
input_t INPUT;
inputmap_t INPUT_MAP[] = {
{"w", INPUT_UP},
{"s", INPUT_DOWN},
{"a", INPUT_LEFT},
{"d", INPUT_RIGHT},
{" ", INPUT_ACTION},
{"e", INPUT_ACTION},
{"\n", INPUT_ACTION}, // Enter key
{"\x1B", INPUT_CANCEL}, // Escape key
{"\033[A", INPUT_UP}, // Up arrow
{"\033[B", INPUT_DOWN}, // Down arrow
{"\033[C", INPUT_RIGHT}, // Right arrow
{"\033[D", INPUT_LEFT}, // Left arrow
{ 0 }
};
void inputEnableRawMode() {
if (INPUT.isRawMode) return;
tcgetattr(STDIN_FILENO, &INPUT.origin);
struct termios raw = INPUT.origin;
raw.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &raw);
INPUT.isRawMode = 1;
}
void inputDisableRawMode() {
if(!INPUT.isRawMode) return;
tcsetattr(STDIN_FILENO, TCSANOW, &INPUT.origin);
INPUT.isRawMode = 0;
}
void inputSetNonBlocking() {
int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
}
void inputInit() {
memoryZero(&INPUT, sizeof(input_t));
inputEnableRawMode();
inputSetNonBlocking();
}
void inputUpdate() {
char_t buffer[INPUT_BUFFER_SIZE];
ssize_t n = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);
if(n < 0) {
INPUT.previous = INPUT.current;
INPUT.current = 0;
return;
}
assertTrue(n < INPUT_BUFFER_SIZE, "Input buffer overflow");
uint8_t val = 0;
inputmap_t *map;
uint8_t len;
char_t *c;
for(uint8_t i = 0; i < n; i++) {
map = INPUT_MAP;
do {
len = strlen(map->key);
if(i + len > n) {
map++;
continue;
}
c = buffer + i;
if(memoryCompare(c, map->key, len) != 0) {
map++;
continue;
}
// Button was pressed
val |= map->value;
i += len - 1;
break;
} while(map->key);
}
INPUT.previous = INPUT.current;
INPUT.current = val;
}
bool_t inputIsDown(const uint8_t key) {
return (INPUT.current & key) != 0;
}
bool_t inputWasDown(const uint8_t key) {
return (INPUT.previous & key) != 0;
}
bool_t inputWasPressed(const uint8_t key) {
return inputIsDown(key) && !inputWasDown(key);
}
bool_t inputWasReleased(const uint8_t key) {
return !inputIsDown(key) && inputWasDown(key);
}
void inputDispose() {
inputDisableRawMode();
}