Creating generic term renderer.
This commit is contained in:
@@ -11,9 +11,16 @@ project(microrpg
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 99)
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
set(ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/assets" CACHE PATH "Path to the assets directory")
|
||||||
|
set(TOOLS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tools" CACHE PATH "Path to the tools directory")
|
||||||
|
|
||||||
# Executable
|
# Executable
|
||||||
add_executable(microrpg)
|
add_executable(microrpg)
|
||||||
|
|
||||||
|
# Tools
|
||||||
|
add_subdirectory(tools)
|
||||||
|
|
||||||
# Add sources
|
# Add sources
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
10
assets/8x8ascii-darkrose/README.md
Normal file
10
assets/8x8ascii-darkrose/README.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
This is a simple 32x32 bitmap font I made as a byproduct of messing about with Xlib. Because of its a power of 2 sizing, it should be able to be resized easily, even if you're writting your own render.
|
||||||
|
|
||||||
|
font.png is a screenshot of the output of my rendering text using font.c.
|
||||||
|
font.zip contains font.c, which is just a C array of 64bit unsigned integers, these are the original bitmaps for the 8x8 font which I resized 4x to get font.png.
|
||||||
|
|
||||||
|
Note the font.c is licensed GPLv3 or later only, the font.png is also licensed GPLv2 and CC-BY-SA.
|
||||||
|
Copyright/Attribution Notice:
|
||||||
|
To satisfy CC-BY-SA's attribution clause, just give a link back to OGA.
|
||||||
|
|
||||||
|
# Original URL: https://opengameart.org/content/8x8-ascii-bitmap-font-with-c-source
|
||||||
BIN
assets/8x8ascii-darkrose/font.png
Normal file
BIN
assets/8x8ascii-darkrose/font.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
61
cmake/Findraylib.cmake
Normal file
61
cmake/Findraylib.cmake
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# Findraylib.cmake — minimal: system paths → FetchContent
|
||||||
|
# Exposes: raylib::raylib, raylib_FOUND
|
||||||
|
|
||||||
|
include_guard(GLOBAL)
|
||||||
|
|
||||||
|
set(_RAYLIB_TAG "5.5")
|
||||||
|
set(_RAYLIB_URL "https://github.com/raysan5/raylib/archive/refs/tags/${_RAYLIB_TAG}.tar.gz")
|
||||||
|
set(_RAYLIB_ROOT "")
|
||||||
|
|
||||||
|
# Try system install first
|
||||||
|
find_path(_RAYLIB_INCLUDE_DIR raylib.h
|
||||||
|
HINTS "${_RAYLIB_ROOT}/include"
|
||||||
|
PATHS /usr/include /usr/local/include
|
||||||
|
PATH_SUFFIXES raylib
|
||||||
|
)
|
||||||
|
find_library(_RAYLIB_LIBRARY raylib
|
||||||
|
HINTS "${_RAYLIB_ROOT}/lib" "${_RAYLIB_ROOT}/lib64"
|
||||||
|
PATHS /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64
|
||||||
|
)
|
||||||
|
|
||||||
|
if (_RAYLIB_INCLUDE_DIR AND _RAYLIB_LIBRARY)
|
||||||
|
add_library(raylib UNKNOWN IMPORTED)
|
||||||
|
set_target_properties(raylib PROPERTIES
|
||||||
|
IMPORTED_LOCATION "${_RAYLIB_LIBRARY}"
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${_RAYLIB_INCLUDE_DIR}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
# Fix CMP0135 warning
|
||||||
|
if(POLICY CMP0135)
|
||||||
|
cmake_policy(SET CMP0135 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (DEFINED FETCHCONTENT_SOURCE_DIR_RAYLIB AND
|
||||||
|
NOT EXISTS "${FETCHCONTENT_SOURCE_DIR_RAYLIB}")
|
||||||
|
unset(FETCHCONTENT_SOURCE_DIR_RAYLIB CACHE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||||
|
set(BUILD_GAMES OFF CACHE BOOL "" FORCE)
|
||||||
|
set(RAYLIB_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||||
|
set(RAYLIB_BUILD_GAMES OFF CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
FetchContent_Declare(raylib
|
||||||
|
URL "${_RAYLIB_URL}"
|
||||||
|
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(raylib)
|
||||||
|
|
||||||
|
if (NOT TARGET raylib)
|
||||||
|
message(FATAL_ERROR "raylib target not defined after fetch.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Normalize exported target
|
||||||
|
if (NOT TARGET raylib::raylib)
|
||||||
|
add_library(raylib::raylib ALIAS raylib)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(raylib_FOUND TRUE)
|
||||||
@@ -8,6 +8,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "cutscene.h"
|
#include "cutscene.h"
|
||||||
|
|
||||||
|
static void testCutsceneTest() {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
cutsceneitem_t TEST_CUTSCENE_ITEMS[] = {
|
cutsceneitem_t TEST_CUTSCENE_ITEMS[] = {
|
||||||
{ .type = CUTSCENE_ITEM_TEXTBOX, .textbox = "Hello World" }
|
{ .type = CUTSCENE_ITEM_CALLBACK, .callback = testCutsceneTest }
|
||||||
};
|
};
|
||||||
@@ -10,10 +10,10 @@
|
|||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
gameInit();
|
gameInit();
|
||||||
platformInit();
|
if(platformInit() != PLATFORM_OK) return 1;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
platformUpdate();
|
if(platformUpdate() != PLATFORM_OK) break;
|
||||||
|
|
||||||
gameTick();
|
gameTick();
|
||||||
|
|
||||||
|
|||||||
@@ -13,3 +13,5 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef bool bool_t;
|
typedef bool bool_t;
|
||||||
|
typedef char char_t;
|
||||||
|
typedef float float_t;
|
||||||
@@ -3,5 +3,6 @@
|
|||||||
# 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
|
||||||
|
|
||||||
# Change inclusion to platform-specific
|
add_subdirectory(raylib)
|
||||||
add_subdirectory(term)
|
add_subdirectory(term)
|
||||||
|
#add_subdirectory(term)
|
||||||
@@ -8,15 +8,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "microrpg.h"
|
#include "microrpg.h"
|
||||||
|
|
||||||
|
#define PLATFORM_OK 0
|
||||||
|
#define PLATFORM_EXIT 1
|
||||||
|
#define PLATFORM_ERROR 2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the platform-specific subsystem.
|
* Initialize the platform-specific subsystem.
|
||||||
|
*
|
||||||
|
* @return 0 on success, non-zero on failure.
|
||||||
*/
|
*/
|
||||||
void platformInit(void);
|
uint8_t platformInit(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the platform-specific subsystem.
|
* Update the platform-specific subsystem.
|
||||||
|
*
|
||||||
|
* @return 0 to continue, 1 to exit, anything else for error.
|
||||||
*/
|
*/
|
||||||
void platformUpdate(void);
|
uint8_t platformUpdate(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the platform-specific subsystem.
|
* Render the platform-specific subsystem.
|
||||||
|
|||||||
27
src/platform/raylib/CMakeLists.txt
Normal file
27
src/platform/raylib/CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
find_package(raylib REQUIRED)
|
||||||
|
|
||||||
|
target_link_libraries(microrpg PRIVATE
|
||||||
|
raylib::raylib
|
||||||
|
)
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(microrpg PRIVATE
|
||||||
|
inputraylib.c
|
||||||
|
termraylib.c
|
||||||
|
platform.c
|
||||||
|
font.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Embed resources
|
||||||
|
embed_file(microrpg "${ASSETS_DIR}/8x8ascii-darkrose/font.png" "assets/font.h" FONT)
|
||||||
|
|
||||||
|
# Compiler flags
|
||||||
|
target_compile_definitions(microrpg PRIVATE
|
||||||
|
RPG_RAYLIB=1
|
||||||
|
)
|
||||||
89
src/platform/raylib/font.c
Normal file
89
src/platform/raylib/font.c
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "font.h"
|
||||||
|
#include "assets/font.h"
|
||||||
|
|
||||||
|
font_t FONT;
|
||||||
|
|
||||||
|
int32_t fontInit() {
|
||||||
|
memset(&FONT, 0, sizeof(FONT));
|
||||||
|
|
||||||
|
FONT.image = LoadImageFromMemory(".png", FONT_DATA, FONT_SIZE);
|
||||||
|
if(FONT.image.data == NULL) {
|
||||||
|
printf("Failed to load font image from memory.\n");
|
||||||
|
return -1; // Failed to load image
|
||||||
|
}
|
||||||
|
|
||||||
|
FONT.texture = LoadTextureFromImage(FONT.image);
|
||||||
|
if(FONT.texture.id == 0) {
|
||||||
|
printf("Failed to load font texture from image.\n");
|
||||||
|
UnloadImage(FONT.image);
|
||||||
|
return -1; // Failed to load texture
|
||||||
|
}
|
||||||
|
|
||||||
|
FONT.charWidthRaw = FONT.texture.width / FONT_COLUMN_COUNT;
|
||||||
|
FONT.charHeightRaw = FONT.texture.height / FONT_ROW_COUNT;
|
||||||
|
FONT.charWidth = FONT.charWidthRaw * FONT_SCALE;
|
||||||
|
FONT.charHeight = FONT.charHeightRaw * FONT_SCALE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fontDraw(
|
||||||
|
const char_t c, const float_t x, const float_t y, const Color color
|
||||||
|
) {
|
||||||
|
int32_t charAdjusted = (int32_t)c - 1;
|
||||||
|
if(c >= '`') charAdjusted += 1;// For some reason the font has empty slot?
|
||||||
|
|
||||||
|
int32_t col = (charAdjusted % FONT_COLUMN_COUNT);
|
||||||
|
int32_t row = (charAdjusted / FONT_COLUMN_COUNT);
|
||||||
|
|
||||||
|
Rectangle sourceRec = {
|
||||||
|
.x = (float_t)(col * FONT.charWidthRaw),
|
||||||
|
.y = (float_t)(row * FONT.charHeightRaw),
|
||||||
|
.width = (float_t)FONT.charWidthRaw,
|
||||||
|
.height = (float_t)FONT.charHeightRaw
|
||||||
|
};
|
||||||
|
Rectangle destRec = {
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
.width = (float_t)FONT.charWidth,
|
||||||
|
.height = (float_t)FONT.charHeight
|
||||||
|
};
|
||||||
|
|
||||||
|
DrawTexturePro(
|
||||||
|
FONT.texture, sourceRec, destRec, (Vector2){0, 0}, 0.0f, color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fontDrawString(
|
||||||
|
const char_t *str, const float_t x, const float_t y, const Color color
|
||||||
|
) {
|
||||||
|
float_t cx, cy;
|
||||||
|
cx = x;
|
||||||
|
cy = y;
|
||||||
|
|
||||||
|
const char_t *c = (char_t *)str;
|
||||||
|
while(*c) {
|
||||||
|
if(*c == '\n') {
|
||||||
|
cx = x;
|
||||||
|
cy += (float_t)(FONT.charHeight + FONT_CHAR_SPACING);
|
||||||
|
c++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fontDraw(*c, cx, cy, color);
|
||||||
|
cx += (float_t)(FONT.charWidth + FONT_CHAR_SPACING);
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fontDispose() {
|
||||||
|
UnloadTexture(FONT.texture);
|
||||||
|
UnloadImage(FONT.image);
|
||||||
|
}
|
||||||
60
src/platform/raylib/font.h
Normal file
60
src/platform/raylib/font.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "microrpg.h"
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
|
#define FONT_COLUMN_COUNT 16
|
||||||
|
#define FONT_ROW_COUNT 8
|
||||||
|
#define FONT_CHAR_SPACING 0// Font has built in spacing
|
||||||
|
#define FONT_SCALE 3.0f
|
||||||
|
|
||||||
|
typedef struct font_s {
|
||||||
|
Texture2D texture;
|
||||||
|
Image image;
|
||||||
|
int32_t charWidthRaw;
|
||||||
|
int32_t charHeightRaw;
|
||||||
|
int32_t charWidth;
|
||||||
|
int32_t charHeight;
|
||||||
|
} font_t;
|
||||||
|
|
||||||
|
extern font_t FONT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the font.
|
||||||
|
*/
|
||||||
|
int32_t fontInit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws a character at the specified position.
|
||||||
|
*
|
||||||
|
* @param c The character to draw.
|
||||||
|
* @param x The x position.
|
||||||
|
* @param y The y position.
|
||||||
|
* @param color The color to draw the character with.
|
||||||
|
*/
|
||||||
|
void fontDraw(
|
||||||
|
const char_t c, const float_t x, const float_t y, const Color color
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws a string at the specified position. No wrapping is performed.
|
||||||
|
*
|
||||||
|
* @param str The string to draw.
|
||||||
|
* @param x The x position.
|
||||||
|
* @param y The y position.
|
||||||
|
* @param color The color to draw the string with.
|
||||||
|
*/
|
||||||
|
void fontDrawString(
|
||||||
|
const char_t *str, const float_t x, const float_t y, const Color color
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes of the font.
|
||||||
|
*/
|
||||||
|
void fontDispose();
|
||||||
24
src/platform/raylib/inputraylib.c
Normal file
24
src/platform/raylib/inputraylib.c
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
bool_t inputDown(const uint8_t action) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t inputUp(const uint8_t action) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t inputWasDown(const uint8_t action) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t inputWasUp(const uint8_t action) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
44
src/platform/raylib/platform.c
Normal file
44
src/platform/raylib/platform.c
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "platform/platform.h"
|
||||||
|
#include <raylib.h>
|
||||||
|
#include "font.h"
|
||||||
|
#include "platform/term/term.h"
|
||||||
|
|
||||||
|
uint8_t platformInit(void) {
|
||||||
|
InitWindow(800, 600, "Micro JRPG");
|
||||||
|
SetTargetFPS(60);
|
||||||
|
|
||||||
|
if(fontInit() != 0) return PLATFORM_ERROR;
|
||||||
|
|
||||||
|
SetWindowSize(40 * FONT.charWidth, 30 * FONT.charHeight);
|
||||||
|
|
||||||
|
return PLATFORM_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t platformUpdate() {
|
||||||
|
if(WindowShouldClose()) {
|
||||||
|
return PLATFORM_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PLATFORM_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void platformDraw() {
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(BLACK);
|
||||||
|
|
||||||
|
termDraw();
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
void platformDispose() {
|
||||||
|
fontDispose();
|
||||||
|
CloseWindow();
|
||||||
|
}
|
||||||
84
src/platform/raylib/termraylib.c
Normal file
84
src/platform/raylib/termraylib.c
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "font.h"
|
||||||
|
#include "platform/term/term.h"
|
||||||
|
|
||||||
|
typedef struct termraylibcolormap_t {
|
||||||
|
termcolor_t termColor;
|
||||||
|
Color raylibColor;
|
||||||
|
} termraylibcolormap_t;
|
||||||
|
|
||||||
|
typedef struct termraylib_s {
|
||||||
|
Color currentColor;
|
||||||
|
float_t x, y;
|
||||||
|
} termraylib_t;
|
||||||
|
|
||||||
|
termraylibcolormap_t TERM_RAYLIB_COLORMAP[] = {
|
||||||
|
{ TERM_COLOR_BLACK, BLACK },
|
||||||
|
{ TERM_COLOR_RED, RED },
|
||||||
|
{ TERM_COLOR_GREEN, GREEN },
|
||||||
|
{ TERM_COLOR_YELLOW, YELLOW },
|
||||||
|
{ TERM_COLOR_BLUE, BLUE },
|
||||||
|
{ TERM_COLOR_MAGENTA, MAGENTA },
|
||||||
|
{ TERM_COLOR_CYAN, SKYBLUE },
|
||||||
|
{ TERM_COLOR_WHITE, WHITE }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TERM_RAYLIB_INITIAL_COLOR WHITE
|
||||||
|
|
||||||
|
termraylib_t TERM_RAYLIB;
|
||||||
|
|
||||||
|
void termClear() {
|
||||||
|
TERM_RAYLIB.currentColor = WHITE;
|
||||||
|
TERM_RAYLIB.x = 0.0f;
|
||||||
|
TERM_RAYLIB.y = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void termFlush() {
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t termGetColumnCount() {
|
||||||
|
// Get Window width
|
||||||
|
int32_t windowWidth = GetScreenWidth();
|
||||||
|
return (uint8_t)(windowWidth / FONT.charWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t termGetRowCount() {
|
||||||
|
// Get Window height
|
||||||
|
int32_t windowHeight = GetScreenHeight();
|
||||||
|
return (uint8_t)(windowHeight / FONT.charHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void termPushColor(termcolor_t color) {
|
||||||
|
// Find the corresponding raylib color
|
||||||
|
size_t colors = sizeof(TERM_RAYLIB_COLORMAP) / sizeof(termraylibcolormap_t);
|
||||||
|
for(size_t i = 0; i < colors; i++) {
|
||||||
|
if(TERM_RAYLIB_COLORMAP[i].termColor == color) {
|
||||||
|
TERM_RAYLIB.currentColor = TERM_RAYLIB_COLORMAP[i].raylibColor;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void termPushChar(char_t c) {
|
||||||
|
if(c == '\n') {
|
||||||
|
TERM_RAYLIB.x = 0.0f;
|
||||||
|
TERM_RAYLIB.y += (float_t)(FONT.charHeight + FONT_CHAR_SPACING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fontDraw(c, TERM_RAYLIB.x, TERM_RAYLIB.y, TERM_RAYLIB.currentColor);
|
||||||
|
TERM_RAYLIB.x += (float_t)(FONT.charWidth + FONT_CHAR_SPACING);
|
||||||
|
|
||||||
|
// Wrapping
|
||||||
|
if(TERM_RAYLIB.x + FONT.charWidth > (float_t)GetScreenWidth()) {
|
||||||
|
TERM_RAYLIB.x = 0.0f;
|
||||||
|
TERM_RAYLIB.y += (float_t)(FONT.charHeight + FONT_CHAR_SPACING);
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/platform/term/CMakeLists.txt
Executable file → Normal file
15
src/platform/term/CMakeLists.txt
Executable file → Normal file
@@ -3,24 +3,9 @@
|
|||||||
# 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
|
||||||
|
|
||||||
# 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
|
# Sources
|
||||||
target_sources(microrpg PRIVATE
|
target_sources(microrpg PRIVATE
|
||||||
term.c
|
term.c
|
||||||
inputterm.c
|
|
||||||
platform.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Compiler flags
|
# Compiler flags
|
||||||
|
|||||||
108
src/platform/term/term.c
Executable file → Normal file
108
src/platform/term/term.c
Executable file → Normal file
@@ -6,107 +6,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "term.h"
|
#include "term.h"
|
||||||
#include "input.h"
|
#include "game.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() {
|
void termDrawOverworld() {
|
||||||
// Draw map.
|
// Draw map.
|
||||||
|
|
||||||
// Draw entities.
|
|
||||||
attron(COLOR_PAIR(1));
|
|
||||||
termDrawEntity(&GAME.player);
|
termDrawEntity(&GAME.player);
|
||||||
|
|
||||||
entity_t *start = GAME.overworld.map.entities;
|
entity_t *start = GAME.overworld.map.entities;
|
||||||
@@ -138,9 +42,13 @@ void termDrawEntity(const entity_t *ent) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mvaddch(ent->position.y, ent->position.x, c);
|
termPushChar
|
||||||
}
|
}
|
||||||
|
|
||||||
void termDispose() {
|
void termDraw() {
|
||||||
endwin();
|
termClear();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
termFlush();
|
||||||
}
|
}
|
||||||
62
src/platform/term/term.h
Executable file → Normal file
62
src/platform/term/term.h
Executable file → Normal file
@@ -7,45 +7,51 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "microrpg.h"
|
#include "microrpg.h"
|
||||||
#include "game.h"
|
#include "termcolor.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.
|
* Common implementation to draw the game state to the terminal (whatever the
|
||||||
*/
|
* terminal implementation by the platform is).
|
||||||
void termInit();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the terminal prior to game update.
|
|
||||||
*/
|
|
||||||
void termUpdate();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draw the terminal game.
|
|
||||||
*/
|
*/
|
||||||
void termDraw();
|
void termDraw();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw the overworld scene.
|
* Clears the terminal screen and resets the cursor to the top left. Called at
|
||||||
|
* the start of each "frame". Should also reset any terminal state (e.g. color).
|
||||||
*/
|
*/
|
||||||
void termDrawOverworld();
|
void termClear();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw an entity to the terminal.
|
* Flushes any pending terminal operations. Called at the end of each "frame".
|
||||||
|
*/
|
||||||
|
void termFlush();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of columns in the terminal.
|
||||||
*
|
*
|
||||||
* @param ent The entity to draw.
|
* @return The number of columns.
|
||||||
*/
|
*/
|
||||||
void termDrawEntity(const entity_t *ent);
|
uint8_t termGetColumnCount();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispose of the terminal subsystem.
|
* Get the number of rows in the terminal.
|
||||||
|
*
|
||||||
|
* @return The number of rows.
|
||||||
*/
|
*/
|
||||||
void termDispose();
|
uint8_t termGetRowCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push a color onto the terminal color stack.
|
||||||
|
*
|
||||||
|
* @param color The color to push.
|
||||||
|
*/
|
||||||
|
void termPushColor(termcolor_t color);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push a character onto the terminal at the current cursor position. This will
|
||||||
|
* also advance the cursor position by 1 character. Wrapping will be handled by
|
||||||
|
* the terminal implementation.
|
||||||
|
*
|
||||||
|
* @param c The character to push.
|
||||||
|
*/
|
||||||
|
void termPushChar(char_t c);
|
||||||
20
src/platform/term/termcolor.h
Normal file
20
src/platform/term/termcolor.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "microrpg.h"
|
||||||
|
|
||||||
|
#define TERM_COLOR_WHITE 0
|
||||||
|
#define TERM_COLOR_RED 1
|
||||||
|
#define TERM_COLOR_GREEN 2
|
||||||
|
#define TERM_COLOR_YELLOW 3
|
||||||
|
#define TERM_COLOR_BLUE 4
|
||||||
|
#define TERM_COLOR_MAGENTA 5
|
||||||
|
#define TERM_COLOR_CYAN 6
|
||||||
|
#define TERM_COLOR_BLACK 7
|
||||||
|
|
||||||
|
typedef uint8_t termcolor_t;
|
||||||
29
src/platform/tty/CMakeLists.txt
Executable file
29
src/platform/tty/CMakeLists.txt
Executable 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
|
||||||
|
)
|
||||||
146
src/platform/tty/term.c
Executable file
146
src/platform/tty/term.c
Executable 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/tty/term.h
Executable file
51
src/platform/tty/term.h
Executable 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();
|
||||||
6
tools/CMakeLists.txt
Normal file
6
tools/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
add_subdirectory(embed)
|
||||||
22
tools/embed/CMakeLists.txt
Normal file
22
tools/embed/CMakeLists.txt
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
function(embed_file TARGET_NAME INPUT_FILE_ABS OUTPUT_FILE_HEADER C_VAR_NAME)
|
||||||
|
set(OUTPUT_FILE_ABS "${CMAKE_BINARY_DIR}/generated_headers/${OUTPUT_FILE_HEADER}")
|
||||||
|
|
||||||
|
# Create a custom target
|
||||||
|
add_custom_target(
|
||||||
|
"${INPUT_FILE}_embed"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/generated_headers"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -DINPUT_FILE="${INPUT_FILE_ABS}" -DOUTPUT_FILE="${OUTPUT_FILE_ABS}" -DC_VAR_NAME="${C_VAR_NAME}" -P "${TOOLS_DIR}/embed/embed.cmake"
|
||||||
|
DEPENDS "${INPUT_FILE_ABS}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add the generated header to the target's include directories
|
||||||
|
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/generated_headers")
|
||||||
|
|
||||||
|
# Make the target depend on the custom target
|
||||||
|
add_dependencies(${TARGET_NAME} "${INPUT_FILE}_embed")
|
||||||
|
endfunction()
|
||||||
21
tools/embed/embed.cmake
Normal file
21
tools/embed/embed.cmake
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2025 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# We are passed -DINPUT_FILE (absolute) and -DOUTPUT_FILE (absolute) and -DC_VAR_NAME (name of the C variable to hold the data)
|
||||||
|
|
||||||
|
file(READ "${INPUT_FILE}" RAW_DATA HEX)
|
||||||
|
string(LENGTH "${RAW_DATA}" DATA_LENGTH)
|
||||||
|
set(OUTPUT_CONTENT "/* This file is auto-generated. Do not edit directly. */\n")
|
||||||
|
set(OUTPUT_CONTENT "${OUTPUT_CONTENT}#pragma once\n#include \"microrpg.h\"\n\n")
|
||||||
|
set(OUTPUT_CONTENT "${OUTPUT_CONTENT}static const uint8_t ${C_VAR_NAME}_DATA[] = {\n ")
|
||||||
|
set(INDEX 0)
|
||||||
|
while(INDEX LESS DATA_LENGTH)
|
||||||
|
string(SUBSTRING "${RAW_DATA}" ${INDEX} 2 BYTE)
|
||||||
|
set(OUTPUT_CONTENT "${OUTPUT_CONTENT}0x${BYTE}, ")
|
||||||
|
math(EXPR INDEX "${INDEX} + 2")
|
||||||
|
endwhile()
|
||||||
|
set(OUTPUT_CONTENT "${OUTPUT_CONTENT}\n};\n\n")
|
||||||
|
set(OUTPUT_CONTENT "${OUTPUT_CONTENT}#define ${C_VAR_NAME}_SIZE ${DATA_LENGTH}u\n")
|
||||||
|
file(WRITE "${OUTPUT_FILE}" "${OUTPUT_CONTENT}")
|
||||||
Reference in New Issue
Block a user