Initial commit.
This commit is contained in:
33
.gitignore
vendored
Executable file
33
.gitignore
vendored
Executable file
@@ -0,0 +1,33 @@
|
|||||||
|
# C/C++ build artifacts
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.so
|
||||||
|
*.dll
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
*.lo
|
||||||
|
*.dep
|
||||||
|
|
||||||
|
# CMake files
|
||||||
|
CMakeFiles/
|
||||||
|
CMakeCache.txt
|
||||||
|
cmake_install.cmake
|
||||||
|
Makefile
|
||||||
|
CMakeLists.txt.user
|
||||||
|
CMakeConfigureLog.yaml
|
||||||
|
|
||||||
|
# Editor files
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# CMake build directories
|
||||||
|
build/
|
||||||
19
CMakeLists.txt
Executable file
19
CMakeLists.txt
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
project(microrpg
|
||||||
|
VERSION 0.1.0
|
||||||
|
DESCRIPTION "A tiny JRPG game written in C"
|
||||||
|
LANGUAGES C
|
||||||
|
)
|
||||||
|
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
|
||||||
|
# Executable
|
||||||
|
add_executable(microrpg)
|
||||||
|
|
||||||
|
# Add sources
|
||||||
|
add_subdirectory(src)
|
||||||
2
README.md
Executable file
2
README.md
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
# Micro JRPG
|
||||||
|
Small JRPG game/engine that is designed to run on "just about" anything.
|
||||||
21
src/CMakeLists.txt
Executable file
21
src/CMakeLists.txt
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Include directories
|
||||||
|
target_include_directories(microrpg PRIVATE ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(microrpg PRIVATE
|
||||||
|
main.c
|
||||||
|
game.c
|
||||||
|
input.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Subdirs
|
||||||
|
add_subdirectory(entity)
|
||||||
|
add_subdirectory(scene)
|
||||||
|
add_subdirectory(world)
|
||||||
|
|
||||||
|
add_subdirectory(term)
|
||||||
10
src/entity/CMakeLists.txt
Executable file
10
src/entity/CMakeLists.txt
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(microrpg PRIVATE
|
||||||
|
entity.c
|
||||||
|
player.c
|
||||||
|
)
|
||||||
21
src/entity/direction.h
Executable file
21
src/entity/direction.h
Executable 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
|
||||||
|
#include "microrpg.h"
|
||||||
|
|
||||||
|
#define DIRECTION_UP 0
|
||||||
|
#define DIRECTION_RIGHT 1
|
||||||
|
#define DIRECTION_DOWN 2
|
||||||
|
#define DIRECTION_LEFT 3
|
||||||
|
|
||||||
|
#define DIRECTION_NORTH DIRECTION_UP
|
||||||
|
#define DIRECTION_EAST DIRECTION_RIGHT
|
||||||
|
#define DIRECTION_SOUTH DIRECTION_DOWN
|
||||||
|
#define DIRECTION_WEST DIRECTION_LEFT
|
||||||
|
|
||||||
|
typedef uint8_t direction_t;
|
||||||
48
src/entity/entity.c
Executable file
48
src/entity/entity.c
Executable file
@@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "entity.h"
|
||||||
|
|
||||||
|
void entityInit(entity_t *entity, const entitytype_t type) {
|
||||||
|
memset(entity, 0, sizeof(entity_t));
|
||||||
|
|
||||||
|
entity->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entityTick(entity_t *entity) {
|
||||||
|
if(entity->type == ENTITY_TYPE_NULL) return;
|
||||||
|
|
||||||
|
// Let entities move (if they do)
|
||||||
|
if(entity->type == ENTITY_TYPE_PLAYER) {
|
||||||
|
playerTickInput(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void entityTurn(entity_t *entity, const direction_t direction) {
|
||||||
|
// TODO: animation/delay.
|
||||||
|
entity->direction = direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entityWalk(entity_t *entity, const direction_t direction) {
|
||||||
|
// TODO: Animation, delay, colission, result, etc.
|
||||||
|
entity->direction = direction;
|
||||||
|
|
||||||
|
switch(direction) {
|
||||||
|
case DIRECTION_NORTH:
|
||||||
|
entity->position.y--;
|
||||||
|
break;
|
||||||
|
case DIRECTION_EAST:
|
||||||
|
entity->position.x++;
|
||||||
|
break;
|
||||||
|
case DIRECTION_SOUTH:
|
||||||
|
entity->position.y++;
|
||||||
|
break;
|
||||||
|
case DIRECTION_WEST:
|
||||||
|
entity->position.x--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
52
src/entity/entity.h
Executable file
52
src/entity/entity.h
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "entity/direction.h"
|
||||||
|
#include "entity/entitytype.h"
|
||||||
|
#include "player.h"
|
||||||
|
|
||||||
|
typedef struct entity_s {
|
||||||
|
struct {
|
||||||
|
// Relative to top-left of the map
|
||||||
|
uint8_t x, y;
|
||||||
|
} position;
|
||||||
|
|
||||||
|
direction_t direction;
|
||||||
|
entitytype_t type;
|
||||||
|
} entity_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize an entity.
|
||||||
|
*
|
||||||
|
* @param entity Pointer to the entity to initialize.
|
||||||
|
* @param type The type of the entity.
|
||||||
|
*/
|
||||||
|
void entityInit(entity_t *entity, const entitytype_t type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update an entity for one tick.
|
||||||
|
*
|
||||||
|
* @param entity Pointer to the entity to update.
|
||||||
|
*/
|
||||||
|
void entityTick(entity_t *entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn an entity to face a new direction.
|
||||||
|
*
|
||||||
|
* @param entity Pointer to the entity to turn.
|
||||||
|
* @param direction The direction to face.
|
||||||
|
*/
|
||||||
|
void entityTurn(entity_t *entity, const direction_t direction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make an entity walk in a direction.
|
||||||
|
*
|
||||||
|
* @param entity Pointer to the entity to make walk.
|
||||||
|
* @param direction The direction to walk in.
|
||||||
|
*/
|
||||||
|
void entityWalk(entity_t *entity, const direction_t direction);
|
||||||
14
src/entity/entitytype.h
Executable file
14
src/entity/entitytype.h
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "microrpg.h"
|
||||||
|
|
||||||
|
#define ENTITY_TYPE_NULL 0
|
||||||
|
#define ENTITY_TYPE_PLAYER 1
|
||||||
|
|
||||||
|
typedef uint8_t entitytype_t;
|
||||||
21
src/entity/player.c
Executable file
21
src/entity/player.c
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "entity.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
void playerTickInput(entity_t *entity) {
|
||||||
|
if(inputPressed(INPUT_ACTION_UP)) {
|
||||||
|
entityWalk(entity, DIRECTION_NORTH);
|
||||||
|
} else if(inputPressed(INPUT_ACTION_DOWN)) {
|
||||||
|
entityWalk(entity, DIRECTION_SOUTH);
|
||||||
|
} else if(inputPressed(INPUT_ACTION_LEFT)) {
|
||||||
|
entityWalk(entity, DIRECTION_WEST);
|
||||||
|
} else if(inputPressed(INPUT_ACTION_RIGHT)) {
|
||||||
|
entityWalk(entity, DIRECTION_EAST);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/entity/player.h
Executable file
18
src/entity/player.h
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "microrpg.h"
|
||||||
|
|
||||||
|
typedef struct entity_s entity_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ticks player input logic.
|
||||||
|
*
|
||||||
|
* @param entity Pointer to the player entity.
|
||||||
|
*/
|
||||||
|
void playerTickInput(entity_t *entity);
|
||||||
22
src/game.c
Executable file
22
src/game.c
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
game_t GAME;
|
||||||
|
|
||||||
|
void gameInit() {
|
||||||
|
memset(&GAME, 0, sizeof(GAME));
|
||||||
|
|
||||||
|
entityInit(&GAME.player, ENTITY_TYPE_PLAYER);
|
||||||
|
|
||||||
|
GAME.scene = SCENE_OVERWORLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gameTick() {
|
||||||
|
sceneTick();
|
||||||
|
}
|
||||||
37
src/game.h
Executable file
37
src/game.h
Executable file
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "entity/entity.h"
|
||||||
|
#include "world/map.h"
|
||||||
|
#include "scene/scene.h"
|
||||||
|
|
||||||
|
#define GAME_SCENE_INITIAL 0
|
||||||
|
#define GAME_SCENE_OVERWORLD 1
|
||||||
|
|
||||||
|
typedef struct game_s {
|
||||||
|
scene_t scene;
|
||||||
|
entity_t player;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
map_t map;
|
||||||
|
} overworld;
|
||||||
|
};
|
||||||
|
} game_t;
|
||||||
|
|
||||||
|
extern game_t GAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the game state.
|
||||||
|
*/
|
||||||
|
void gameInit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advance the game state by one tick. Should be called at 60Hz.
|
||||||
|
*/
|
||||||
|
void gameTick();
|
||||||
16
src/input.c
Executable file
16
src/input.c
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
bool_t inputPressed(const uint8_t action) {
|
||||||
|
return inputDown(action) && inputWasUp(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t inputReleased(const uint8_t action) {
|
||||||
|
return inputUp(action) && inputWasDown(action);
|
||||||
|
}
|
||||||
66
src/input.h
Executable file
66
src/input.h
Executable file
@@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "microrpg.h"
|
||||||
|
|
||||||
|
#define INPUT_ACTION_UP (1 << 0)
|
||||||
|
#define INPUT_ACTION_DOWN (1 << 1)
|
||||||
|
#define INPUT_ACTION_LEFT (1 << 2)
|
||||||
|
#define INPUT_ACTION_RIGHT (1 << 3)
|
||||||
|
#define INPUT_ACTION_A (1 << 4)
|
||||||
|
#define INPUT_ACTION_B (1 << 5)
|
||||||
|
#define INPUT_ACTION_START (1 << 6)
|
||||||
|
#define INPUT_ACTION_SELECT (1 << 7)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an input action is currently held down.
|
||||||
|
*
|
||||||
|
* @param action The action to check.
|
||||||
|
* @return true if the action is held down, false otherwise.
|
||||||
|
*/
|
||||||
|
bool_t inputDown(const uint8_t action);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an input action is not currently held down.
|
||||||
|
*
|
||||||
|
* @param action The action to check.
|
||||||
|
* @return true if the action is not held down, false otherwise.
|
||||||
|
*/
|
||||||
|
bool_t inputUp(const uint8_t action);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an input action was held down in the previous tick.
|
||||||
|
*
|
||||||
|
* @param action The action to check.
|
||||||
|
* @return true if the action was down last tick, false otherwise.
|
||||||
|
*/
|
||||||
|
bool_t inputWasDown(const uint8_t action);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an input action was not held down in the previous tick.
|
||||||
|
*
|
||||||
|
* @param action The action to check.
|
||||||
|
* @return true if the action was up last tick, false otherwise.
|
||||||
|
*/
|
||||||
|
bool_t inputWasUp(const uint8_t action);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an input action was just pressed this tick.
|
||||||
|
*
|
||||||
|
* @param action The action to check.
|
||||||
|
* @return true if the action was just pressed, false otherwise.
|
||||||
|
*/
|
||||||
|
bool_t inputPressed(const uint8_t action);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an input action was just released this tick.
|
||||||
|
*
|
||||||
|
* @param action The action to check.
|
||||||
|
* @return true if the action was just released, false otherwise.
|
||||||
|
*/
|
||||||
|
bool_t inputReleased(const uint8_t action);
|
||||||
37
src/main.c
Executable file
37
src/main.c
Executable file
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "game.h"
|
||||||
|
#if RPG_TERM == 1
|
||||||
|
#include "term/term.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
gameInit();
|
||||||
|
|
||||||
|
#if RPG_TERM == 1
|
||||||
|
termInit();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
#if RPG_TERM == 1
|
||||||
|
termUpdate();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gameTick();
|
||||||
|
|
||||||
|
#if RPG_TERM == 1
|
||||||
|
termDraw();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if RPG_TERM == 1
|
||||||
|
termDispose();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
15
src/microrpg.h
Executable file
15
src/microrpg.h
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef bool bool_t;
|
||||||
9
src/scene/CMakeLists.txt
Executable file
9
src/scene/CMakeLists.txt
Executable 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(microrpg PRIVATE
|
||||||
|
scene.c
|
||||||
|
)
|
||||||
23
src/scene/scene.c
Executable file
23
src/scene/scene.c
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "scene.h"
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
void sceneTick() {
|
||||||
|
switch(GAME.scene) {
|
||||||
|
case SCENE_INITIAL: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCENE_OVERWORLD: {
|
||||||
|
mapTick(&GAME.overworld.map);
|
||||||
|
entityTick(&GAME.player);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/scene/scene.h
Executable file
16
src/scene/scene.h
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "microrpg.h"
|
||||||
|
|
||||||
|
#define SCENE_INITIAL 0
|
||||||
|
#define SCENE_OVERWORLD 1
|
||||||
|
|
||||||
|
typedef uint8_t scene_t;
|
||||||
|
|
||||||
|
void sceneTick();
|
||||||
28
src/term/CMakeLists.txt
Executable file
28
src/term/CMakeLists.txt
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
# 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
|
||||||
|
)
|
||||||
|
|
||||||
|
# Compiler flags
|
||||||
|
target_compile_definitions(microrpg PRIVATE
|
||||||
|
RPG_TERM=1
|
||||||
|
)
|
||||||
24
src/term/inputterm.c
Executable file
24
src/term/inputterm.c
Executable 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;
|
||||||
|
}
|
||||||
95
src/term/term.c
Executable file
95
src/term/term.c
Executable file
@@ -0,0 +1,95 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "term.h"
|
||||||
|
#include "input.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
attron(COLOR_PAIR(1));
|
||||||
|
|
||||||
|
termDrawEntity(&GAME.player);
|
||||||
|
|
||||||
|
attroff(COLOR_PAIR(1));
|
||||||
|
refresh();
|
||||||
|
|
||||||
|
// 16ms delay (60FPS)
|
||||||
|
napms(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void termDrawEntity(const entity_t *ent) {
|
||||||
|
// Placeholder: Draw entity at its position
|
||||||
|
mvaddch(ent->position.y, ent->position.x, '@');
|
||||||
|
}
|
||||||
|
|
||||||
|
void termDispose() {
|
||||||
|
endwin();
|
||||||
|
}
|
||||||
46
src/term/term.h
Executable file
46
src/term/term.h
Executable file
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* 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 an entity to the terminal.
|
||||||
|
*
|
||||||
|
* @param ent The entity to draw.
|
||||||
|
*/
|
||||||
|
void termDrawEntity(const entity_t *ent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispose of the terminal subsystem.
|
||||||
|
*/
|
||||||
|
void termDispose();
|
||||||
9
src/world/CMakeLists.txt
Executable file
9
src/world/CMakeLists.txt
Executable 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(microrpg PRIVATE
|
||||||
|
map.c
|
||||||
|
)
|
||||||
17
src/world/chunk.h
Executable file
17
src/world/chunk.h
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "world/tile.h"
|
||||||
|
|
||||||
|
#define CHUNK_WIDTH_IN_TILES 16
|
||||||
|
#define CHUNK_HEIGHT_IN_TILES 16
|
||||||
|
#define CHUNK_TILE_COUNT (CHUNK_WIDTH_IN_TILES * CHUNK_HEIGHT_IN_TILES)
|
||||||
|
|
||||||
|
typedef struct chunk_s {
|
||||||
|
tile_t tiles[CHUNK_TILE_COUNT];
|
||||||
|
} chunk_t;
|
||||||
14
src/world/map.c
Executable file
14
src/world/map.c
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "map.h"
|
||||||
|
|
||||||
|
void mapTick(map_t *map) {
|
||||||
|
for(int i = 0; i < MAP_ENTITY_COUNT; i++) {
|
||||||
|
entityTick(&map->entities[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/world/map.h
Executable file
35
src/world/map.h
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "world/chunk.h"
|
||||||
|
#include "entity/entity.h"
|
||||||
|
|
||||||
|
#define MAP_ENTITY_COUNT 8
|
||||||
|
#define MAP_WIDTH_IN_CHUNKS 3
|
||||||
|
#define MAP_HEIGHT_IN_CHUNKS 3
|
||||||
|
#define MAP_CHUNK_COUNT (MAP_WIDTH_IN_CHUNKS * MAP_HEIGHT_IN_CHUNKS)
|
||||||
|
|
||||||
|
typedef struct map_s {
|
||||||
|
// Loaded chunks.
|
||||||
|
chunk_t chunks[MAP_CHUNK_COUNT];
|
||||||
|
chunk_t *order[MAP_CHUNK_COUNT];
|
||||||
|
int8_t firstChunk;
|
||||||
|
|
||||||
|
// Map entities
|
||||||
|
entity_t entities[MAP_ENTITY_COUNT];
|
||||||
|
|
||||||
|
// Size of map (in chunks)
|
||||||
|
uint8_t width, height;
|
||||||
|
} map_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the map for one tick.
|
||||||
|
*
|
||||||
|
* @param map Pointer to the map to update.
|
||||||
|
*/
|
||||||
|
void mapTick(map_t *map);
|
||||||
13
src/world/tile.h
Executable file
13
src/world/tile.h
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "microrpg.h"
|
||||||
|
|
||||||
|
#define TILE_NULL 0x00
|
||||||
|
|
||||||
|
typedef uint8_t tile_t;
|
||||||
Reference in New Issue
Block a user