Moved the platform stuff around

This commit is contained in:
2025-10-28 07:52:05 -05:00
parent f1db7de87c
commit 358fa9a493
25 changed files with 456 additions and 46 deletions

7
src/platform/CMakeLists.txt Executable file
View File

@@ -0,0 +1,7 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Change inclusion to platform-specific
add_subdirectory(term)

29
src/platform/platform.h Normal file
View File

@@ -0,0 +1,29 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "microrpg.h"
/**
* Initialize the platform-specific subsystem.
*/
void platformInit(void);
/**
* Update the platform-specific subsystem.
*/
void platformUpdate(void);
/**
* Render the platform-specific subsystem.
*/
void platformDraw(void);
/**
* Dispose of the platform-specific subsystem.
*/
void platformDispose(void);

View File

@@ -0,0 +1,29 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Libraries
find_package(Curses REQUIRED)
target_link_libraries(microrpg PRIVATE
${CURSES_LIBRARIES}
)
target_include_directories(microrpg PRIVATE
${CURSES_INCLUDE_DIR}
)
target_link_libraries(microrpg PRIVATE
${CURSES_LIBRARIES}
)
# Sources
target_sources(microrpg PRIVATE
term.c
inputterm.c
platform.c
)
# Compiler flags
target_compile_definitions(microrpg PRIVATE
RPG_TERM=1
)

24
src/platform/term/inputterm.c Executable file
View File

@@ -0,0 +1,24 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "term.h"
bool_t inputDown(const uint8_t action) {
return (TERM.inputCurrent & action) != 0;
}
bool_t inputUp(const uint8_t action) {
return (TERM.inputCurrent & action) == 0;
}
bool_t inputWasDown(const uint8_t action) {
return (TERM.inputPrevious & action) != 0;
}
bool_t inputWasUp(const uint8_t action) {
return (TERM.inputPrevious & action) == 0;
}

View File

@@ -0,0 +1,25 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "platform/platform.h"
#include "platform/term/term.h"
void platformInit() {
termInit();
}
void platformUpdate() {
termUpdate();
}
void platformDraw() {
termDraw();
}
void platformDispose() {
termDispose();
}

146
src/platform/term/term.c Executable file
View File

@@ -0,0 +1,146 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "term.h"
#include "input.h"
#include <time.h>
typedef struct terminputmap_s {
int key;
uint8_t action;
} terminputmap_t;
static const terminputmap_t TERM_INPUT_MAP[] = {
{ KEY_UP, INPUT_ACTION_UP },
{ 'w', INPUT_ACTION_UP },
{ KEY_DOWN, INPUT_ACTION_DOWN },
{ 's', INPUT_ACTION_DOWN },
{ KEY_LEFT, INPUT_ACTION_LEFT },
{ 'a', INPUT_ACTION_LEFT },
{ KEY_RIGHT, INPUT_ACTION_RIGHT },
{ 'd', INPUT_ACTION_RIGHT },
{ 'j', INPUT_ACTION_A },
{ 'e', INPUT_ACTION_A },
{ 'k', INPUT_ACTION_B },
{ 'q', INPUT_ACTION_B },
{ KEY_ENTER, INPUT_ACTION_START },
{ ' ', INPUT_ACTION_SELECT },
{ -1, 0 }
};
term_t TERM;
void termInit() {
memset(&TERM, 0, sizeof(TERM));
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
nodelay(stdscr, TRUE);
curs_set(0);
start_color();
use_default_colors();
init_pair(1, COLOR_GREEN, -1);
// Set in-game time to real world time.
time_t now = time(NULL);
struct tm *t = localtime(&now);
GAME.time.days = t->tm_wday;
GAME.time.hours = t->tm_hour;
GAME.time.minutes = t->tm_min;
GAME.time.seconds = t->tm_sec;
}
void termUpdate() {
TERM.inputPrevious = TERM.inputCurrent;
TERM.inputCurrent = 0;
int ch = getch();
if(ch == ERR) {
TERM.lastch = ERR;
return;
}
if(ch == TERM.lastch) {
return;
}
TERM.lastch = ch;
const terminputmap_t *map = TERM_INPUT_MAP;
while(map->key != -1) {
if(map->key == ch) {
TERM.inputCurrent |= map->action;
break;
}
map++;
}
}
void termDraw() {
clear();
switch(GAME.scene) {
case SCENE_OVERWORLD:
termDrawOverworld();
break;
default:
break;
}
attroff(COLOR_PAIR(1));
refresh();
// 16ms delay (60FPS)
napms(16);
}
void termDrawOverworld() {
// Draw map.
// Draw entities.
attron(COLOR_PAIR(1));
termDrawEntity(&GAME.player);
entity_t *start = GAME.overworld.map.entities;
entity_t *end = start + MAP_ENTITY_COUNT;
while(start < end) {
if(start->type != ENTITY_TYPE_NULL) termDrawEntity(start);
start++;
}
}
void termDrawEntity(const entity_t *ent) {
// Placeholder: Draw entity at its position
char c;
switch(ent->direction) {
case DIRECTION_NORTH:
c = '^';
break;
case DIRECTION_EAST:
c = '>';
break;
case DIRECTION_SOUTH:
c = 'v';
break;
case DIRECTION_WEST:
c = '<';
break;
default:
c = '@';
break;
}
mvaddch(ent->position.y, ent->position.x, c);
}
void termDispose() {
endwin();
}

51
src/platform/term/term.h Executable file
View File

@@ -0,0 +1,51 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "microrpg.h"
#include "game.h"
#include <ncurses.h>
typedef struct term_s {
uint8_t inputCurrent;
uint8_t inputPrevious;
int lastch;
} term_t;
extern term_t TERM;
/**
* Initialize the terminal subsystem.
*/
void termInit();
/**
* Update the terminal prior to game update.
*/
void termUpdate();
/**
* Draw the terminal game.
*/
void termDraw();
/**
* Draw the overworld scene.
*/
void termDrawOverworld();
/**
* Draw an entity to the terminal.
*
* @param ent The entity to draw.
*/
void termDrawEntity(const entity_t *ent);
/**
* Dispose of the terminal subsystem.
*/
void termDispose();