Compare commits
3 Commits
dde228ca72
...
8c14e56846
Author | SHA1 | Date |
---|---|---|
|
8c14e56846 | |
|
f080e38244 | |
|
c56b462203 |
|
@ -1,2 +1,4 @@
|
|||
build
|
||||
2D_Engine_Casio_Tool
|
||||
GameData.bin
|
||||
assets/maps/__pycache__
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"fxconv": "python",
|
||||
"*.MIT": "markdown",
|
||||
"complex": "cpp",
|
||||
"string": "cpp",
|
||||
"iterator": "cpp",
|
||||
|
@ -15,6 +17,62 @@
|
|||
"system_error": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"iostream": "cpp",
|
||||
"ios": "cpp"
|
||||
"ios": "cpp",
|
||||
"vector2d.hpp": "c",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"bitset": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"ratio": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ranges": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"span": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"thread": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp"
|
||||
}
|
||||
}
|
|
@ -6,9 +6,9 @@
|
|||
"detail": "Build project",
|
||||
"type": "shell",
|
||||
"command": "make",
|
||||
"args": [
|
||||
"-j$(nproc)"
|
||||
],
|
||||
//"args": [
|
||||
// "-j$(nproc)"
|
||||
//],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
|
@ -33,9 +33,27 @@
|
|||
"reveal": "never",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false,
|
||||
"clear": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build Verbose",
|
||||
"detail": "Build project with verbosity on",
|
||||
"type": "shell",
|
||||
"command": "make",
|
||||
"args": [
|
||||
"VERBOSE=1"
|
||||
],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": true,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
"clear": true
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
//---
|
||||
// gint:image - Image manipulation
|
||||
//
|
||||
// Note: this module is currently only available on fx-CG.
|
||||
//
|
||||
// This module supports 3 bit depths: full-color 16-bit (RGB565), indexed 8-bit
|
||||
// (P8) and indexed 4-bit (P4). All three have an "alpha" variation where one
|
||||
// color is treated as transparent, leading to 6 total formats.
|
||||
//---
|
||||
|
||||
#ifndef GINT_IMAGE
|
||||
#define GINT_IMAGE
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//---
|
||||
// Image structures
|
||||
//---
|
||||
|
||||
/* Image formats. Note that transparency really only indicates the default
|
||||
rendering method, as a transparent background can always be added or removed
|
||||
by a dynamic effect on any image. */
|
||||
enum {
|
||||
IMAGE_RGB565 = 0, /* RGB565 without alpha */
|
||||
IMAGE_RGB565A = 1, /* RGB565 with one transparent color */
|
||||
IMAGE_P8_RGB565 = 4, /* 8-bit palette, all opaque colors */
|
||||
IMAGE_P8_RGB565A = 5, /* 8-bit with one transparent color */
|
||||
IMAGE_P4_RGB565 = 6, /* 4-bit palette, all opaque colors */
|
||||
IMAGE_P4_RGB565A = 3, /* 4-bit with one transparent color */
|
||||
|
||||
IMAGE_DEPRECATED_P8 = 2,
|
||||
};
|
||||
|
||||
/* Quick macros to compare formats by storage size */
|
||||
#define IMAGE_IS_RGB16(format) \
|
||||
((format) == IMAGE_RGB565 || (format) == IMAGE_RGB565A)
|
||||
#define IMAGE_IS_P8(format) \
|
||||
((format) == IMAGE_P8_RGB565 || (format) == IMAGE_P8_RGB565A)
|
||||
#define IMAGE_IS_P4(format) \
|
||||
((format) == IMAGE_P4_RGB565 || (format) == IMAGE_P4_RGB565A)
|
||||
/* Check whether image format has an alpha color */
|
||||
#define IMAGE_IS_ALPHA(format) \
|
||||
((format) == IMAGE_RGB565A || \
|
||||
(format) == IMAGE_P8_RGB565A || \
|
||||
(format) == IMAGE_P4_RGB565A)
|
||||
/* Check whether image format uses a palette */
|
||||
#define IMAGE_IS_INDEXED(format) \
|
||||
(IMAGE_IS_P8(format) || IMAGE_IS_P4(format))
|
||||
|
||||
/* Image flags. These are used for memory management, mostly. */
|
||||
enum {
|
||||
IMAGE_FLAGS_DATA_RO = 0x01, /* Data is read-only */
|
||||
IMAGE_FLAGS_PALETTE_RO = 0x02, /* Palette is read-only */
|
||||
IMAGE_FLAGS_DATA_ALLOC = 0x04, /* Data is malloc()'d */
|
||||
IMAGE_FLAGS_PALETTE_ALLOC = 0x08, /* Palette is malloc()'d */
|
||||
};
|
||||
|
||||
/* image_t: gint's native bitmap image format
|
||||
Images of this format can be created through this header's API but also by
|
||||
using the fxSDK's built-in image converters with fxconv. */
|
||||
typedef struct
|
||||
{
|
||||
/* Color format, one of the IMAGE_* values defined above */
|
||||
uint8_t format;
|
||||
/* Additional flags, a combination of IMAGE_FLAGS_* values */
|
||||
uint8_t flags;
|
||||
/* Number of colors in the palette; this includes alpha for transparent
|
||||
images, as alpha is always the first entry.
|
||||
RGB16: 0
|
||||
P8: Ranges between 1 and 256
|
||||
P4: 16 */
|
||||
int16_t color_count;
|
||||
/* Full width and height, in pixels */
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
/* Byte stride between lines */
|
||||
uint32_t stride;
|
||||
|
||||
/* Pixel data in row-major order, left to right.
|
||||
- RGB16: 2 bytes per entry, each row padded to 4 bytes for alignment.
|
||||
Each 2-byte value is an RGB565 color.
|
||||
- P8: 1 signed byte per entry. Each byte is a palette index shifted by
|
||||
128 (to access the color, use palette[<value>+128]).
|
||||
- P4: 4 bits per entry, each row padded to a full byte. Each entry is a
|
||||
direct palette index between 0 and 15. */
|
||||
void *data;
|
||||
|
||||
/* For P8 and P4, color palette. The number of entries allocated in the
|
||||
array is equal to the color_count attribute. */
|
||||
uint16_t *palette;
|
||||
|
||||
} __attribute__((packed, aligned(4))) bopti_image_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // GINT_IMAGE
|
26
Makefile
|
@ -3,26 +3,35 @@ BUILD_DIR = build
|
|||
|
||||
# Source files
|
||||
SOURCES := \
|
||||
src/test.cpp
|
||||
# src/main.cpp \
|
||||
# src/game_data.cpp
|
||||
src/main.cpp \
|
||||
src/game_data/game_data.cpp \
|
||||
src/game_data/maps.cpp \
|
||||
src/game_data/textures.cpp
|
||||
|
||||
# Assets files
|
||||
ASSETS := \
|
||||
assets/tileset/tileset.png \
|
||||
assets/player-sheets/player_idle_sheet.png \
|
||||
assets/player-sheets/player_walk_sheet.png \
|
||||
assets/tileset/tileset.png
|
||||
assets/player-sheets/player_run_sheet.png \
|
||||
assets/props-sheets/barred_door_sheet.png \
|
||||
assets/props-sheets/lever_sheet.png \
|
||||
assets/props-sheets/small_chest_sheet.png \
|
||||
assets/props-sheets/big_chest_sheet.png \
|
||||
assets/maps/example.json
|
||||
|
||||
# Output target name
|
||||
OUTPUT := 2D_Engine_Casio_Tool
|
||||
|
||||
# Compiler and flags
|
||||
CXX = ccache g++
|
||||
CXXFLAGS = -Wall -Wextra -std=c++17 -O2 -I. -no-pie
|
||||
CXXFLAGS = -Wall -Wextra -std=c++17 -O2 -no-pie
|
||||
INCLUDE_DIRS = 3rd_party
|
||||
LDFLAGS = -no-pie
|
||||
|
||||
# Converter flags
|
||||
FXCONVFLAGS = --cg --toolchain= --arch=x86-64 --outputtarget=elf64-x86-64
|
||||
FXCONV_FLAGS = --cg --toolchain= --arch=x86-64 --outputtarget=elf64-x86-64
|
||||
FXCONV_CONVERTERS = assets/maps/map_converter.py
|
||||
|
||||
# Change output location
|
||||
OUTPUT := $(BUILD_DIR)/$(OUTPUT)
|
||||
|
@ -62,15 +71,14 @@ $(BUILD_DIR)/%.o: %.cpp
|
|||
$(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE)+1))))
|
||||
$(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE)*100/$(TOTAL_FILES)))))
|
||||
@echo "[$(PERCENTAGE)%] $(GREEN)Building CXX object $@$(RESET)"
|
||||
$(Q)mkdir -p $(dir $@)
|
||||
$(Q)$(CXX) $(CXXFLAGS) -MMD -MP -c $< -o $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(INCLUDE_DIRS:%=-I%) -MMD -MP -c $< -o $@
|
||||
|
||||
# Convert .*.o from .* (png files for example)
|
||||
$(BUILD_DIR)/%.o: %
|
||||
$(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE)+1))))
|
||||
$(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE)*100/$(TOTAL_FILES)))))
|
||||
@echo "[$(PERCENTAGE)%] $(GREEN)Building FXCONV object $@$(RESET)"
|
||||
$(Q)fxconv $(FXCONVFLAGS) $< -o $@
|
||||
$(Q)fxconv $(FXCONV_FLAGS) --converter=$(FXCONV_CONVERTERS) $< -o $@
|
||||
$(Q)objcopy --add-section .note.GNU-stack=/dev/null $@
|
||||
|
||||
# Source files dependencies
|
||||
|
|
|
@ -6,13 +6,15 @@ This tool is used to make game data for the 2D_Engine_Casio [Gitea](https://gite
|
|||
|
||||
## Licences and Credits
|
||||
- This program is open-source : you can redistribute and/or modify it under the term of the **GNU GPLv3**.
|
||||
Copyright (C) 2025 Ulysse Cura. See [LICENSE](LICENSE) or [gnu.org/licenses/gpl-3.0.html](https://www.gnu.org/licenses/gpl-3.0.html).
|
||||
Copyright (c) 2025 Ulysse Cura.
|
||||
See [LICENSE](LICENSE) or [gnu.org/licenses/gpl-3.0.html](https://www.gnu.org/licenses/gpl-3.0.html).
|
||||
|
||||
- Files from the gint project are used in directory [gint](gint).
|
||||
- Files from the gint project are used and modified in directory [gint](gint).
|
||||
[Git](https://git.planet-casio.com/Lephenixnoir/gint)
|
||||
|
||||
- Folder [src/nlohmann/json](src/nlohmann/json) contains code under **MIT license** :
|
||||
Copyright (c) 2013-2025 Niels Lohmann. See [LICENSE.MIT](src/nlohmann/json/LICENSE.MIT).
|
||||
Copyright (c) 2013-2025 Niels Lohmann.
|
||||
See [LICENSE.MIT](src/nlohmann/json/LICENSE.MIT).
|
||||
[GitHub](https://github.com/nlohmann/json)
|
||||
|
||||
- Assets are taken from the free pack offered by [Anokolisa](https://anokolisa.itch.io/).
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,1483,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,1532,0,0,0,794,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,1581,0,904,905,1046,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,2176,2177,2178,2179,2180,2181,2182,0,1543,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,2225,2226,2227,2228,2229,2230,2231,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,1729,2326,2327,2274,2275,2276,2277,2278,2279,2280,2176,2177,2178,2179,2180,2181,2182,0,0,0,0,0,0,
|
||||
0,0,0,0,2176,2177,2178,2180,2181,1778,2375,2376,0,0,0,0,0,0,0,2225,2226,2227,2228,2229,2230,2231,0,0,0,0,0,0,
|
||||
0,0,0,0,2225,2226,2227,2229,2230,2231,0,0,0,0,0,0,0,0,0,2274,2275,2276,2277,2278,2279,2280,0,0,0,0,0,0,
|
||||
0,0,0,0,2274,2275,2276,2278,2279,2280,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;
|
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
"MapWidth": 3,
|
||||
"MapHeight": 2,
|
||||
|
||||
"BackgroundLayer1": [
|
||||
1,0,
|
||||
0,0
|
||||
],
|
||||
"BackgroundLayer2": [
|
||||
0,2,
|
||||
0,0
|
||||
],
|
||||
"BackgroundLayer3": [
|
||||
0,0,
|
||||
3,0
|
||||
],
|
||||
"Foreground": [
|
||||
0,0,
|
||||
0,4
|
||||
],
|
||||
|
||||
"Entities": [
|
||||
{
|
||||
"ID": 2034,
|
||||
"Components": [
|
||||
{
|
||||
"Type": "TransformComponent",
|
||||
"x": 128,
|
||||
"y": 96,
|
||||
"w": 32,
|
||||
"h": 48,
|
||||
"Speed": 0
|
||||
},
|
||||
{
|
||||
"Type": "SpriteComponent",
|
||||
"TextureName": "barred_door_sheet"
|
||||
},
|
||||
{
|
||||
"Type": "AnimationSystem",
|
||||
"NbFrames": 8,
|
||||
"ActualFrame": 0,
|
||||
"FrameDelayMs": 100,
|
||||
"Play": false,
|
||||
"Loop": false,
|
||||
"Reverse": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": 2034,
|
||||
"Components": [
|
||||
{
|
||||
"Type": "TransformComponent",
|
||||
"x": 256,
|
||||
"y": 192,
|
||||
"w": 48,
|
||||
"h": 32,
|
||||
"Speed": 0
|
||||
},
|
||||
{
|
||||
"Type": "SpriteComponent",
|
||||
"TextureName": "lever_sheet"
|
||||
},
|
||||
{
|
||||
"Type": "AnimationSystem",
|
||||
"NbFrames": 3,
|
||||
"ActualFrame": 0,
|
||||
"FrameDelayMs": 300,
|
||||
"Play": false,
|
||||
"Loop": false,
|
||||
"Reverse": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
*.json:
|
||||
custom-type: map
|
||||
name_regex: (.*)\.json map_\1
|
|
@ -0,0 +1,71 @@
|
|||
import fxconv
|
||||
from fxconv import u16, u32, ref, string
|
||||
import json
|
||||
|
||||
def convert(input, output, params, target):
|
||||
if params["custom-type"] == "map":
|
||||
convert_map(input, output, params, target)
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
|
||||
def convert_map(input, output, params, target):
|
||||
with open(input, "r") as fp:
|
||||
map = json.load(fp)
|
||||
|
||||
TRANSFORM_COMPONENT = 0
|
||||
SPRITE_COMPONENT = 1
|
||||
ANIMATION_SYSTEM = 2
|
||||
|
||||
entities = fxconv.Structure()
|
||||
|
||||
for entity in map["Entities"]:
|
||||
e = fxconv.Structure()
|
||||
e += u16(entity["ID"])
|
||||
e += u32(len(entity["Components"]))
|
||||
|
||||
for component in entity["Components"]:
|
||||
c = fxconv.Structure()
|
||||
c_data = fxconv.Structure()
|
||||
|
||||
match component["Type"]:
|
||||
case "TransformComponent":
|
||||
c += u32(TRANSFORM_COMPONENT)
|
||||
c_data += u32(component["x"])
|
||||
c_data += u32(component["y"])
|
||||
c_data += u32(component["w"])
|
||||
c_data += u32(component["h"])
|
||||
c_data += u32(component["Speed"])
|
||||
|
||||
case "SpriteComponent":
|
||||
c += u32(SPRITE_COMPONENT)
|
||||
c_data += string(component["TextureName"])
|
||||
|
||||
case "AnimationSystem":
|
||||
c += u32(SPRITE_COMPONENT)
|
||||
c_data += u32(component["NbFrames"])
|
||||
c_data += u32(component["ActualFrame"])
|
||||
c_data += u32(component["FrameDelayMs"])
|
||||
c_data += u32(component["Play"])
|
||||
c_data += u32(component["Loop"])
|
||||
c_data += u32(component["Reverse"])
|
||||
|
||||
case _:
|
||||
raise fxconv.FxconvError(f"unknown component type {component['Type']}")
|
||||
|
||||
c += ref(c_data)
|
||||
e += ref(c)
|
||||
|
||||
entities += e
|
||||
|
||||
o = fxconv.ObjectData()
|
||||
o += string(params["name"])
|
||||
o += u32(map["MapWidth"]) + u32(map["MapHeight"])
|
||||
o += bytes(map["BackgroundLayer1"])
|
||||
o += bytes(map["BackgroundLayer2"])
|
||||
o += bytes(map["BackgroundLayer3"])
|
||||
o += bytes(map["Foreground"])
|
||||
o += u32(len(map["Entities"]))
|
||||
o += ref(entities)
|
||||
|
||||
fxconv.elf(o, output, params["name"], **target)
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/bash
|
||||
|
||||
echo "Creating \"~/.tiled\" directory"
|
||||
mkdir -p $HOME/.tiled/
|
||||
|
||||
echo "Copying extension to tiled directory"
|
||||
cp "json_export_tool.py" "$HOME/.tiled/"
|
||||
|
||||
echo ""
|
||||
echo "Don't forget to activate python in tiled !"
|
|
@ -1,13 +1,14 @@
|
|||
from tiled import *
|
||||
import json
|
||||
|
||||
class Example(Plugin):
|
||||
class Json_Export_Tool(Plugin):
|
||||
@classmethod
|
||||
def nameFilter(cls):
|
||||
return "Example files (*.example)"
|
||||
return "Json files (*.json)"
|
||||
|
||||
@classmethod
|
||||
def shortName(cls):
|
||||
return "example"
|
||||
return "json"
|
||||
|
||||
@classmethod
|
||||
def write(cls, tileMap, fileName):
|
||||
|
@ -28,6 +29,11 @@ class Example(Plugin):
|
|||
else:
|
||||
line += ','
|
||||
print(line, file=fileHandle)
|
||||
|
||||
|
||||
return True
|
||||
|
||||
def write(cls, tileMap, fileName):
|
||||
map = {}
|
||||
with open(fileName, 'w') as fileHandle:
|
||||
for i in tileMap.layerCount():
|
||||
tileLayer = tileLayerAt(tileMap, i)
|
||||
print("caca", file=fileHandle)
|
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 832 B |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 719 B |
After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 947 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 928 B |
|
@ -0,0 +1,3 @@
|
|||
*.png:
|
||||
type: bopti-image
|
||||
name_regex: (.*)\.png img_\1
|
After Width: | Height: | Size: 1004 B |
After Width: | Height: | Size: 670 B |
|
@ -1,83 +0,0 @@
|
|||
//---
|
||||
// config - Compile-time generate configuration
|
||||
//---
|
||||
|
||||
#ifndef GINT_CONFIG
|
||||
#define GINT_CONFIG
|
||||
|
||||
/* GINT_VERSION: Latest tag and number of additional commits
|
||||
"2.1.0" = Release 2.1.0
|
||||
"2.1.1-5" = 5 commits after release 2.1.1 */
|
||||
#define GINT_VERSION "2.11.0"
|
||||
|
||||
/* GINT_HASH: Commit hash with 7 digits
|
||||
0x03f7c0a0 = Commit 3f7c0a0 */
|
||||
#define GINT_HASH 0xbadbd0f
|
||||
|
||||
/* GINT_HW_{FX,CG}: Identifies the type of hardware running the program. */
|
||||
#if defined(FX9860G)
|
||||
# define GINT_HW_FX 1
|
||||
# define GINT_HW_CG 0
|
||||
# define GINT_HW_CP 0
|
||||
# define GINT_HW_SWITCH(FX,CG,CP) (FX)
|
||||
#elif defined(FXCG50)
|
||||
# define GINT_HW_FX 0
|
||||
# define GINT_HW_CG 1
|
||||
# define GINT_HW_CP 0
|
||||
# define GINT_HW_SWITCH(FX,CG,CP) (CG)
|
||||
#elif defined(FXCP)
|
||||
# define GINT_HW_FX 0
|
||||
# define GINT_HW_CG 0
|
||||
# define GINT_HW_CP 1
|
||||
# define GINT_HW_SWITCH(FX,CG,CP) (CP)
|
||||
#endif
|
||||
|
||||
/* Shorthand to simplify definitions below. Won't be needed for long. */
|
||||
#if defined(FX9860G_G3A)
|
||||
# define GINT_FX9860G_G3A 1
|
||||
#else
|
||||
# define GINT_FX9860G_G3A 0
|
||||
#endif
|
||||
|
||||
/* GINT_OS_{FX,CG}: Identifies the type of OS API we're assuming. Currently I
|
||||
see no reason this would be different from hardware, but who knows. */
|
||||
#define GINT_OS_FX GINT_HW_FX
|
||||
#define GINT_OS_CG GINT_HW_CG
|
||||
#define GINT_OS_CP GINT_HW_CP
|
||||
#define GINT_OS_SWITCH GINT_HW_SWITCH
|
||||
|
||||
/* GINT_NO_OS_STACK: Disables using a chunk of the OS stack as a heap. The top
|
||||
section covering 355/512 ko is otherwise used. (fx-CG 50) */
|
||||
/* #undef GINT_NO_OS_STACK */
|
||||
|
||||
/* GINT_USER_VRAM: Selects whether to store VRAMs in the user stack or in the
|
||||
OS stack. Deprecated, now controlled by GINT_NO_OS_STACK. (fx-CG 50) */
|
||||
/* #undef GINT_USER_VRAM */
|
||||
|
||||
#ifdef GINT_USER_VRAM
|
||||
# define GINT_NO_OS_STACK
|
||||
#endif
|
||||
|
||||
/* GINT_STATIC_GRAY: Selects whether additional gray VRAMs are allocated
|
||||
statically or in the system heap (fx-9860G) */
|
||||
/* #undef GINT_STATIC_GRAY */
|
||||
|
||||
/* GINT_KMALLOC_DEBUG: Selects whether kmalloc debug functions are enabled
|
||||
(these are mainly data structure integrity checks and information that make
|
||||
sense for a developer). This is independent from statistics, which can be
|
||||
enabled or disabled at runtime. */
|
||||
/* #undef GINT_KMALLOC_DEBUG */
|
||||
|
||||
/* GINT_USB_DEBUG: Selects whether USB debug functions are enabled */
|
||||
/* #undef GINT_USB_DEBUG */
|
||||
|
||||
/* GINT_RENDER_DMODE: Selects whether the dmode override is available on
|
||||
rendering functions. */
|
||||
#define GINT_RENDER_DMODE (GINT_HW_FX || GINT_FX9860G_G3A)
|
||||
|
||||
/* GINT_RENDER_{MONO,RGB}: Enable the mono/rgb rendering API.
|
||||
Currently these are exclusive. */
|
||||
#define GINT_RENDER_MONO (GINT_HW_FX || GINT_FX9860G_G3A)
|
||||
#define GINT_RENDER_RGB ((GINT_HW_CG || GINT_HW_CP) && !GINT_FX9860G_G3A)
|
||||
|
||||
#endif /* GINT_CONFIG */
|
|
@ -1,50 +0,0 @@
|
|||
//---
|
||||
// gint:defs:attributes - Macros for compiler-specific attributes
|
||||
//---
|
||||
|
||||
#ifndef GINT_DEFS_ATTRIBUTES
|
||||
#define GINT_DEFS_ATTRIBUTES
|
||||
|
||||
/* Objects from specific sections */
|
||||
#define GSECTION(x) __attribute__((section(x)))
|
||||
/* Objects from the gint's uninitialized BSS section */
|
||||
#define GBSS __attribute__((section(".gint.bss")))
|
||||
/* Additional sections that are only needed on SH3 */
|
||||
#define GRODATA3 __attribute__((section(".gint.rodata.sh3")))
|
||||
#define GDATA3 __attribute__((section(".gint.data.sh3")))
|
||||
#define GBSS3 __attribute__((section(".gint.bss.sh3")))
|
||||
/* Objects for the ILRAM, XRAM and YRAM regions */
|
||||
#define GILRAM __attribute__((section(".ilram")))
|
||||
#define GXRAM __attribute__((section(".xyram")))
|
||||
#define GYRAM __attribute__((section(".xyram")))
|
||||
|
||||
/* Unused parameters or variables */
|
||||
#define GUNUSED __attribute__((unused))
|
||||
/* Functions that *must* be inlined */
|
||||
#define GINLINE __attribute__((always_inline)) inline
|
||||
|
||||
/* Aligned variables */
|
||||
#define GALIGNED(x) __attribute__((aligned(x)))
|
||||
/* Packed structures. I require explicit alignment because if it's unspecified,
|
||||
GCC cannot optimize access size, and reads to memory-mapped I/O with invalid
|
||||
access sizes silently fail - honestly you don't want this to happen */
|
||||
#define GPACKED(x) __attribute__((packed, aligned(x)))
|
||||
/* Packed enumerations */
|
||||
#define GPACKEDENUM __attribute__((packed))
|
||||
/* Transparent unions */
|
||||
#define GTRANSPARENT __attribute__((transparent_union))
|
||||
|
||||
/* Functions and globals that are visible through whole-program optimization */
|
||||
#define GVISIBLE __attribute__((externally_visible))
|
||||
|
||||
/* Weak symbols */
|
||||
#define GWEAK __attribute__((weak))
|
||||
|
||||
/* Constructors */
|
||||
#define GCONSTRUCTOR __attribute__((constructor))
|
||||
#define GDESTRUCTOR __attribute__((destructor))
|
||||
|
||||
/* Functions that do not return */
|
||||
#define GNORETURN __attribute__((noreturn))
|
||||
|
||||
#endif /* GINT_DEFS_ATTRIBUTES */
|
|
@ -1,68 +0,0 @@
|
|||
//---
|
||||
// gint:defs:types - Type definitions
|
||||
//---
|
||||
|
||||
#ifndef GINT_DEFS_TYPES
|
||||
#define GINT_DEFS_TYPES
|
||||
|
||||
#include "attributes.h"
|
||||
|
||||
/* For size_t, mainly */
|
||||
#include <stddef.h>
|
||||
/* For all fixed-width integer types */
|
||||
#include <stdint.h>
|
||||
/* For human-readable boolean types */
|
||||
#include <stdbool.h>
|
||||
/* Common system types: ssize_t, off_t, etc. */
|
||||
#include <sys/types.h>
|
||||
/* For va_list */
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Fixed-width types for bit fields are quite meaningless */
|
||||
typedef unsigned int uint;
|
||||
|
||||
//---
|
||||
// Short types
|
||||
//---
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
typedef int8_t i8;
|
||||
typedef int16_t i16;
|
||||
typedef int32_t i32;
|
||||
typedef int64_t i64;
|
||||
|
||||
//---
|
||||
// Structure elements
|
||||
//----
|
||||
|
||||
/* Giving a type to padding bytes is misguiding, let's hide it in a macro */
|
||||
#define pad_nam2(c) _ ## c
|
||||
#define pad_name(c) pad_nam2(c)
|
||||
#define pad(bytes) uint8_t pad_name(__COUNTER__)[bytes]
|
||||
|
||||
/* byte_union() - union between an uint8_t 'byte' element and a bit field */
|
||||
#define byte_union(name, fields) \
|
||||
union { \
|
||||
uint8_t byte; \
|
||||
struct { fields } GPACKED(1); \
|
||||
} GPACKED(1) name
|
||||
|
||||
/* word_union() - union between an uint16_t 'word' element and a bit field */
|
||||
#define word_union(name, fields) \
|
||||
union { \
|
||||
uint16_t word; \
|
||||
struct { fields } GPACKED(2); \
|
||||
} GPACKED(2) name
|
||||
|
||||
/* lword_union() - union between an uint32_t 'lword' element and a bit field */
|
||||
#define lword_union(name, fields) \
|
||||
union { \
|
||||
uint32_t lword; \
|
||||
struct { fields } GPACKED(4); \
|
||||
} GPACKED(4) name
|
||||
|
||||
#endif /* GINT_DEFS_TYPES */
|
|
@ -1,143 +0,0 @@
|
|||
//---
|
||||
// gint:display-cg - fx-CG 50 rendering functions
|
||||
//
|
||||
// This module covers rendering functions specific to the fx-CG 50. In addition
|
||||
// to triple-buffering management, this mainly includes image manipulation
|
||||
// tools as well as the very versatile dimage_effect() and dsubimage_effect()
|
||||
// functions that support high-performance image rendering with a number of
|
||||
// geometric and color effects.
|
||||
//
|
||||
// The fx-CG OS restricts the display to a 384x216 rectangle rougly around the
|
||||
// center, leaving margins on three sides. However, gint configures the display
|
||||
// to use the full 396x224 surface!
|
||||
//---
|
||||
|
||||
#ifndef GINT_DISPLAY_CG
|
||||
#define GINT_DISPLAY_CG
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "defs/types.h"
|
||||
#include "image.h"
|
||||
|
||||
/* Dimensions of the VRAM */
|
||||
#if GINT_HW_CG
|
||||
#define DWIDTH 396
|
||||
#define DHEIGHT 224
|
||||
#elif GINT_HW_CP
|
||||
#define DWIDTH 320
|
||||
#define DHEIGHT 528
|
||||
#endif
|
||||
|
||||
/* gint VRAM address. This value must always point to a 32-aligned buffer of
|
||||
size 177408. Any function can use it freely to perform rendering or store
|
||||
data when not drawing. Triple buffering is already implemented in gint, see
|
||||
the dvram() function below.
|
||||
|
||||
In this module, colors are in the 16-bit big-endian R5G6B5 format, as it is
|
||||
the format used by the display controller. */
|
||||
extern uint16_t *gint_vram;
|
||||
|
||||
/* Provide a platform-agnostic definition of color_t.
|
||||
Some functions also support transparency, in which case they take an [int]
|
||||
as argument and recognize negative values as transparent. */
|
||||
typedef uint16_t color_t;
|
||||
|
||||
enum {
|
||||
/* Compatibility with fx9860g color names */
|
||||
C_WHITE = 0xffff,
|
||||
C_LIGHT = 0xad55,
|
||||
C_DARK = 0x528a,
|
||||
C_BLACK = 0x0000,
|
||||
|
||||
/* Other colors */
|
||||
C_RED = 0xf800,
|
||||
C_GREEN = 0x07e0,
|
||||
C_BLUE = 0x001f,
|
||||
|
||||
C_NONE = -1,
|
||||
C_INVERT = -2,
|
||||
};
|
||||
|
||||
/* RGB color maker. Takes three channels of value 0..31 each (the extra bit of
|
||||
green is not used). */
|
||||
#define C_RGB(r,g,b) (((r) << 11) | ((g) << 6) | (b))
|
||||
|
||||
/* See <gint/image.h> for the details on image manipulation. */
|
||||
typedef image_t bopti_image_t;
|
||||
|
||||
|
||||
//---
|
||||
// Video RAM management
|
||||
//---
|
||||
|
||||
/* dsetvram(): Control video RAM address and triple buffering
|
||||
|
||||
Normal rendering under gint uses double-buffering: there is one image
|
||||
displayed on the screen and one in memory, in a region called the video RAM
|
||||
(VRAM). The application draws frames in the VRAM then sends them to the
|
||||
screen only when they are finished, using dupdate().
|
||||
|
||||
On fx-CG, sending frames with dupdate() is a common bottleneck because it
|
||||
takes about 11 ms. Fortunately, while the DMA is sending the frame to the
|
||||
display, the CPU is available to do work in parallel. This function sets up
|
||||
triple buffering (ie. a second VRAM) so that the CPU can start working on
|
||||
the next frame while the DMA is sending the current one.
|
||||
|
||||
However, experience shows minimal performance improvements, because writing
|
||||
to main RAM does not parallelize with DMA transfers. Since gint 2.8, this
|
||||
is no longer the default, and the memory for the extra VRAM is instead
|
||||
available via malloc().
|
||||
|
||||
VRAMs must be contiguous, 32-aligned, (2*396*224)-byte buffers with 32 bytes
|
||||
of extra data on each side (ie. 32 bytes into a 32-aligned buffer of size
|
||||
177472).
|
||||
|
||||
@main Main VRAM area, used alone if [secondary] is NULL
|
||||
@secondary Additional VRAM area, enables triple buffering if non-NULL */
|
||||
// TODO: In gint 3 the triple buffering mechanism will be removed. Applications
|
||||
// that want to change VRAMs in-between every frame will be able to do so by
|
||||
// talking directly to the video interface to set VRAM, and wrapping dupdate.
|
||||
// Basically it will just no longer be handled by gint itself.
|
||||
void dsetvram(uint16_t *main, uint16_t *secondary);
|
||||
|
||||
/* dgetvram() - Get VRAM addresses
|
||||
Returns the VRAM buffer addresses used to render on fx-CG 50. */
|
||||
void dgetvram(uint16_t **main, uint16_t **secondary);
|
||||
|
||||
|
||||
//---
|
||||
// VRAM backup
|
||||
// On the fx-CP gint backs up the VRAM when loading and restores it when
|
||||
// leaving. While this is a transparent mechanism, the following parts of the
|
||||
// implementation are exposed at the internal API level.
|
||||
//---
|
||||
|
||||
/* Encode the VRAM contents between [in_start] and [in_end] at [output]. While
|
||||
[*in_end] is excluded from the encoding, it will be modified temporarily to
|
||||
serve as bounds check, so it must not be accessed asynchronously during the
|
||||
encoding. The size of the output is not known but is at most the distance
|
||||
between in_end and in_start in bytes. Setting output = in_start to compress
|
||||
in-place is supported. Returns the end pointer after encoding. */
|
||||
uint8_t *gint_vrambackup_encode(
|
||||
uint8_t *output, uint16_t *in_start, uint16_t *in_end);
|
||||
|
||||
/* Predefine palette based on the GUI at the Hollyhock loading screen. Contains
|
||||
109 entries plus a 110th dummy entry used internally as bounds check. */
|
||||
extern uint16_t gint_vrambackup_palette[110];
|
||||
|
||||
/* Get the pointer to the encoded VRAM backup created at load time. If [size]
|
||||
is not NULL, sets the size in [*size]. The pointer is heap allocated and
|
||||
remains owned by gint. */
|
||||
void *gint_vrambackup_get(int *size);
|
||||
|
||||
/* Decode the load-time VRAM backup back to VRAM. */
|
||||
void gint_vrambackup_show(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GINT_DISPLAY_CG */
|
846
gint/image.h
|
@ -1,846 +0,0 @@
|
|||
//---
|
||||
// gint:image - Image manipulation and rendering
|
||||
//
|
||||
// Note: this module is currently only available on fx-CG.
|
||||
//
|
||||
// This header provides image manipulation functions. This mainly consists of a
|
||||
// reference-based image format, various access and modification functions, and
|
||||
// a number of high-performance transformations and rendering effects. If you
|
||||
// find yourself limited by rendering time, note that RAM writing speed is
|
||||
// often the bottleneck, and image rendering is much faster in Azur (which is
|
||||
// what the renderer was initially designed for).
|
||||
//
|
||||
// This module supports 3 bit depths: full-color 16-bit (RGB565), indexed 8-bit
|
||||
// (P8) and indexed 4-bit (P4). All three have an "alpha" variation where one
|
||||
// color is treated as transparent, leading to 6 total formats.
|
||||
//
|
||||
// The image renderers support so-called *dynamic effects*, which are image
|
||||
// transformations performed on-the-fly while rendering, without generating an
|
||||
// intermediate image. They comprise straightforward transformations that
|
||||
// achieve similar performance to straight rendering and can be combined to
|
||||
// some extent, which makes them reliable whenever applicable.
|
||||
//
|
||||
// For images of the RGB16 and P8 bit depths, the module supports a rich API
|
||||
// with image subsurfaces and a fairly large sets of geometric and color
|
||||
// transforms, including some in-place. P4 is not supported in most of these
|
||||
// functions because the dense bit packing is both impractical and slower for
|
||||
// these applications.
|
||||
//---
|
||||
|
||||
#ifndef GINT_IMAGE
|
||||
#define GINT_IMAGE
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "defs/attributes.h"
|
||||
#include <stdint.h>
|
||||
|
||||
struct dwindow;
|
||||
|
||||
//---
|
||||
// Image structures
|
||||
//---
|
||||
|
||||
/* Image formats. Note that transparency really only indicates the default
|
||||
rendering method, as a transparent background can always be added or removed
|
||||
by a dynamic effect on any image. */
|
||||
enum {
|
||||
IMAGE_RGB565 = 0, /* RGB565 without alpha */
|
||||
IMAGE_RGB565A = 1, /* RGB565 with one transparent color */
|
||||
IMAGE_P8_RGB565 = 4, /* 8-bit palette, all opaque colors */
|
||||
IMAGE_P8_RGB565A = 5, /* 8-bit with one transparent color */
|
||||
IMAGE_P4_RGB565 = 6, /* 4-bit palette, all opaque colors */
|
||||
IMAGE_P4_RGB565A = 3, /* 4-bit with one transparent color */
|
||||
|
||||
IMAGE_DEPRECATED_P8 = 2,
|
||||
};
|
||||
|
||||
/* Quick macros to compare formats by storage size */
|
||||
#define IMAGE_IS_RGB16(format) \
|
||||
((format) == IMAGE_RGB565 || (format) == IMAGE_RGB565A)
|
||||
#define IMAGE_IS_P8(format) \
|
||||
((format) == IMAGE_P8_RGB565 || (format) == IMAGE_P8_RGB565A)
|
||||
#define IMAGE_IS_P4(format) \
|
||||
((format) == IMAGE_P4_RGB565 || (format) == IMAGE_P4_RGB565A)
|
||||
/* Check whether image format has an alpha color */
|
||||
#define IMAGE_IS_ALPHA(format) \
|
||||
((format) == IMAGE_RGB565A || \
|
||||
(format) == IMAGE_P8_RGB565A || \
|
||||
(format) == IMAGE_P4_RGB565A)
|
||||
/* Check whether image format uses a palette */
|
||||
#define IMAGE_IS_INDEXED(format) \
|
||||
(IMAGE_IS_P8(format) || IMAGE_IS_P4(format))
|
||||
|
||||
/* Image flags. These are used for memory management, mostly. */
|
||||
enum {
|
||||
IMAGE_FLAGS_DATA_RO = 0x01, /* Data is read-only */
|
||||
IMAGE_FLAGS_PALETTE_RO = 0x02, /* Palette is read-only */
|
||||
IMAGE_FLAGS_DATA_ALLOC = 0x04, /* Data is malloc()'d */
|
||||
IMAGE_FLAGS_PALETTE_ALLOC = 0x08, /* Palette is malloc()'d */
|
||||
};
|
||||
|
||||
/* image_t: gint's native bitmap image format
|
||||
Images of this format can be created through this header's API but also by
|
||||
using the fxSDK's built-in image converters with fxconv. */
|
||||
typedef struct
|
||||
{
|
||||
/* Color format, one of the IMAGE_* values defined above */
|
||||
uint8_t format;
|
||||
/* Additional flags, a combination of IMAGE_FLAGS_* values */
|
||||
uint8_t flags;
|
||||
/* Number of colors in the palette; this includes alpha for transparent
|
||||
images, as alpha is always the first entry.
|
||||
RGB16: 0
|
||||
P8: Ranges between 1 and 256
|
||||
P4: 16 */
|
||||
int16_t color_count;
|
||||
/* Full width and height, in pixels */
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
/* Byte stride between lines */
|
||||
int stride;
|
||||
|
||||
/* Pixel data in row-major order, left to right.
|
||||
- RGB16: 2 bytes per entry, each row padded to 4 bytes for alignment.
|
||||
Each 2-byte value is an RGB565 color.
|
||||
- P8: 1 signed byte per entry. Each byte is a palette index shifted by
|
||||
128 (to access the color, use palette[<value>+128]).
|
||||
- P4: 4 bits per entry, each row padded to a full byte. Each entry is a
|
||||
direct palette index between 0 and 15. */
|
||||
void *data;
|
||||
|
||||
/* For P8 and P4, color palette. The number of entries allocated in the
|
||||
array is equal to the color_count attribute. */
|
||||
uint16_t *palette;
|
||||
|
||||
} GPACKED(4) image_t;
|
||||
|
||||
/* Dynamic effects: these transformations can be applied on images while
|
||||
rendering. Not all effects can be combined; unless specified otherwise:
|
||||
- HFLIP and VFLIP can both be added regardless of any other effect
|
||||
- At most one color effect can be applied */
|
||||
enum {
|
||||
/* Value 0x01 is reserved, because it is DIMAGE_NOCLIP, which although
|
||||
part of the old API still needs to be supported. */
|
||||
|
||||
/* [Any]: Skip clipping the command against the source image */
|
||||
IMAGE_NOCLIP_INPUT = 0x04,
|
||||
/* [Any]: Skip clipping the command against the output VRAM */
|
||||
IMAGE_NOCLIP_OUTPUT = 0x08,
|
||||
/* [Any]: Skip clipping both */
|
||||
IMAGE_NOCLIP = IMAGE_NOCLIP_INPUT | IMAGE_NOCLIP_OUTPUT,
|
||||
|
||||
// Geometric effects. These values should remain at exactly bit 8 and
|
||||
// following, or change gint_image_mkcmd() along with it.
|
||||
|
||||
/* [Any]: Flip image vertically */
|
||||
IMAGE_VFLIP = 0x0100,
|
||||
/* [Any]: Flip image horizontally */
|
||||
IMAGE_HFLIP = 0x0200,
|
||||
|
||||
// Color effects
|
||||
|
||||
/* [RGB565, P8_RGB565, P4_RGB565]: Make a color transparent
|
||||
Adds one argument:
|
||||
* Color to clear (RGB16: 16-bit value; P8/P4: palette index) */
|
||||
IMAGE_CLEARBG = 0x10,
|
||||
/* [RGB565, P8_RGB565, P4_RGB565]: Turn a color into another
|
||||
Adds two arguments:
|
||||
* Color to replace (RGB16: 16-bit value; P8/P4: palette index)
|
||||
* Replacement color (16-bit value) */
|
||||
IMAGE_SWAPCOLOR = 0x20,
|
||||
/* [RGB565A, P8_RGB565A, P4_RGB565A]: Add a background
|
||||
Adds one argument:
|
||||
* Background color (16-bit value) */
|
||||
IMAGE_ADDBG = 0x40,
|
||||
/* [RGB565A, P8_RGB565A, P4_RGB565A]: Dye all non-transparent pixels
|
||||
Adds one argument:
|
||||
* Dye color (16-bit value) */
|
||||
IMAGE_DYE = 0x80,
|
||||
};
|
||||
|
||||
//---
|
||||
// Image creation and destruction
|
||||
//---
|
||||
|
||||
#if GINT_RENDER_RGB
|
||||
|
||||
/* image_alloc(): Create a new (uninitialized) image
|
||||
|
||||
This function allocates a new image of the specified dimensions and format.
|
||||
It always allocates a new data array; if you need to reuse a data array, use
|
||||
the lower-level image_create() or image_create_sub().
|
||||
|
||||
The first parameters [width] and [height] specify the dimensions of the new
|
||||
image in pixels. The [format] should be one of the IMAGE_* formats, for
|
||||
example IMAGE_RGB565A or IMAGE_P4_RGB565.
|
||||
|
||||
This function does not specify or initialize the palette of the new image;
|
||||
use image_set_palette(), image_alloc_palette() or image_copy_palette()
|
||||
after calling this function.
|
||||
|
||||
The returned image structure must be freed with image_free() after use.
|
||||
|
||||
@width Width of the new image
|
||||
@height Height of the new image
|
||||
@format Pixel format; one of the IMAGE_* formats defined above */
|
||||
image_t *image_alloc(int width, int height, int format);
|
||||
|
||||
/* image_set_palette(): Specify an external palette for an image
|
||||
|
||||
This function sets the image's palette to the provided address. The number
|
||||
of entries allocated must be specified in size. It is also the caller's
|
||||
responsibility to ensure that the palette covers all the indices used in the
|
||||
image data.
|
||||
|
||||
The old palette, if owned by the image, is freed. If [owns=true] the
|
||||
palette's ownership is given to the image, otherwise it is kept external. */
|
||||
void image_set_palette(image_t *img, uint16_t *palette, int size, bool owns);
|
||||
|
||||
/* image_alloc_palette(): Allocate a new palette for an image
|
||||
|
||||
This function allocates a new palette for an image. The number of entries is
|
||||
specified in size; for P8 it can vary between 1 and 256, for P4 it is
|
||||
ignored (P4 images always have 16 colors).
|
||||
|
||||
The old palette, if owned by the image, is freed. The entries of the new
|
||||
palette are all initialized to 0. If size is -1, the format's default
|
||||
palette size is used. Returns true on success. */
|
||||
bool image_alloc_palette(image_t *img, int size);
|
||||
|
||||
/* image_copy_palette(): Copy another image's palette
|
||||
|
||||
This function allocates a new palette for an image, and initializes it with
|
||||
a copy of another image's palette. For P8 the palette can be resized by
|
||||
specifying a value other than -1 as the size; by default, the source image's
|
||||
palette size is used (within the limits of the new format). Retuns true on
|
||||
success. */
|
||||
bool image_copy_palette(image_t const *src, image_t *dst, int size);
|
||||
|
||||
/* image_create(): Create a bare image with no data/palette
|
||||
|
||||
This function allocates a new image structure but without data or palette.
|
||||
The [data] and [palette] members are NULL, [color_count] and [stride] are 0.
|
||||
|
||||
This function is useful to create images that reuse externally-provided
|
||||
information. It is intended that the user of this function sets the [data]
|
||||
and [stride] fields themselves, along with the IMAGE_FLAGS_DATA_ALLOC flag
|
||||
if the image should own its data.
|
||||
|
||||
The [palette] and [color_count] members can be set with image_set_palette(),
|
||||
image_alloc_palette(), image_copy_palette(), or manually.
|
||||
|
||||
The returned image structure must be freed with image_free() after use. */
|
||||
image_t *image_create(int width, int height, int format);
|
||||
|
||||
/* image_create_vram(): Create a reference to gint_vram
|
||||
|
||||
This function creates a new RGB565 image that references gint_vram. Using
|
||||
this image as target for transformation functions can effectively render
|
||||
transformed images to VRAM.
|
||||
|
||||
The value of gint_vram is captured when this function is called, and does
|
||||
not update after dupdate() when triple-buffering is used. The user should
|
||||
account for this option. (Using this function twice then replacing one of
|
||||
the [data] pointers is allowed.)
|
||||
|
||||
The VRAM image owns no data but it does own its own structure so it must
|
||||
still be freed with image_free() after use. */
|
||||
image_t *image_create_vram(void);
|
||||
|
||||
/* image_free(): Free and image and the data it owns
|
||||
|
||||
This function frees the provided image structure and the data that it owns.
|
||||
Images converted by fxconv should not be freed; nonetheless, this functions
|
||||
distinguishes them and should work. Images are not expected to be created on
|
||||
the stack.
|
||||
|
||||
If the image has the IMAGE_FLAGS_DATA_ALLOC flag, the data pointer is also
|
||||
freed. Similarly, the image has the IMAGE_FLAGS_PALETTE_ALLOC flag, the
|
||||
palette is freed. Make sure to not free images when references to them still
|
||||
exist, as this could cause the reference's pointers to become dangling. */
|
||||
void image_free(image_t *img);
|
||||
|
||||
//---
|
||||
// Basic image access and information
|
||||
//---
|
||||
|
||||
/* image_valid(): Check if an image is valid
|
||||
An image is considered valid if it has a valid profile, a non-NULL data
|
||||
pointer, and for palette formats a valid palette pointer. */
|
||||
bool image_valid(image_t const *img);
|
||||
|
||||
/* image_alpha(): Get the alpha value for an image format
|
||||
|
||||
This function returns the alpha value for any specific image format:
|
||||
* RGB16: 0x0001
|
||||
* P8: -128 (0x80)
|
||||
* P4: 0
|
||||
For non-transparent formats, it returns a value that is different from all
|
||||
valid pixel values of the format, which means it is always safe to compare a
|
||||
pixel value to the image_alpha() of the format. */
|
||||
int image_alpha(int format);
|
||||
|
||||
/* image_get_pixel(): Read a pixel from the data array
|
||||
|
||||
This function reads a pixel from the image's data array at position (x,y).
|
||||
It returns the pixel's value, which is either a full-color value (RGB16) or
|
||||
a possibly-negative palette index (P8/P4). See the description of the [data]
|
||||
field of image_t for more details. The value of the pixel can be decoded
|
||||
into a 16-bit color either manually or by using the image_decode_pixel()
|
||||
function.
|
||||
|
||||
Note that reading large amounts of image data with this function will be
|
||||
slow; if you need reasonable performance, consider iterating on the data
|
||||
array manually. */
|
||||
int image_get_pixel(image_t const *img, int x, int y);
|
||||
|
||||
/* image_decode_pixel(): Decode a pixel value
|
||||
|
||||
This function decodes a pixel's value obtained from the data array (for
|
||||
instance with image_get_pixel()). For RGB16 formats this does nothing, but
|
||||
for palette formats this accesses the palette at a suitable position.
|
||||
|
||||
Note that reading large amounts of data with this function will be slow; if
|
||||
you need reasonable performance, consider inlining the format-specific
|
||||
method or iterating on the data array manually. */
|
||||
int image_decode_pixel(image_t const *img, int pixel);
|
||||
|
||||
/* image_data_size(): Compute the size of the [data] array
|
||||
This function returns the size of the data array, in bytes. This can be used
|
||||
to duplicate it. Note that for sub-images this is a subsection of another
|
||||
image's data array, and might be much larger than the sub-image. */
|
||||
int image_data_size(image_t const *img);
|
||||
|
||||
//---
|
||||
// Basic image modifications
|
||||
//---
|
||||
|
||||
/* image_set_pixel(): Set a pixel in the data array
|
||||
|
||||
This function writes a pixel into the image's data array at position (x,y).
|
||||
The pixel value must be of the proper format, as specified in the definition
|
||||
of the [data] field of image_t.
|
||||
|
||||
Formats: RGB16, P8, P4 */
|
||||
void image_set_pixel(image_t const *img, int x, int y, int value);
|
||||
|
||||
/* image_copy(): Convert and copy an image
|
||||
|
||||
This function copies an image into another image while converting certain
|
||||
formats. Unlike transforms, this function does clip, so there are no
|
||||
conditions on the size of the target.
|
||||
|
||||
If [copy_alpha] is true, transparent pixels are copied verbatim, which
|
||||
effectively replaces the top-left corner of [dst] with [src]. If it's false,
|
||||
transparent pixels of [src] are skipped, effectively rendering [src] over
|
||||
the top-left corner of [src].
|
||||
|
||||
This function converts between all formats except from RGB16 to P8/P4, since
|
||||
this requires generating a palette (which is a complex endeavour).
|
||||
Conversions from P8/P4 to RGB16 simply decode the palette. Conversions
|
||||
between P8/P4 preserve the contents but renumber the palette entries. From
|
||||
P4 to P8, the image is always preserved. From P8 to P4, the image is only
|
||||
preserved if it has less than 16 colors (this is intended to allow P4 images
|
||||
to be converted to P8 for edition by this library, and then back to P4). The
|
||||
following table summarizes the conversions:
|
||||
|
||||
Source format → RGB16 P8 P4
|
||||
Target format ↓ +-----------+----------------+------------------+
|
||||
RGB16 | Copy Decode palette Decode palette |
|
||||
P8 | - Copy Enlarge palette |
|
||||
P4 | - Narrow palette Copy |
|
||||
+-----------+----------------+------------------+
|
||||
|
||||
Note that conversions to RGB16 are not lossless because RGB565, P8 and P4
|
||||
can represent any color; if a color equal to image_alpha(IMAGE_RGB565A) is
|
||||
found during conversion, this function transforms it slightly to look
|
||||
similar instead of erroneously generating a transparent pixel.
|
||||
|
||||
Formats: RGB16 → RGB16, P8 → Anything, P4 → Anything
|
||||
Size requirement: none (clipping is performed)
|
||||
Supports in-place: No (useless) */
|
||||
void image_copy(image_t const *src, image_t *dst, bool copy_alpha);
|
||||
|
||||
/* image_copy_alloc(): Convert and copy into a new image
|
||||
This function is similar to image_copy(), but it allocates a target image of
|
||||
the desired format before copying. */
|
||||
image_t *image_copy_alloc(image_t const *src, int new_format);
|
||||
|
||||
/* image_fill(): Fill an image with a single pixel value */
|
||||
void image_fill(image_t *img, int value);
|
||||
|
||||
/* image_clear(): Fill a transparent image with its transparent value */
|
||||
void image_clear(image_t *img);
|
||||
|
||||
//---
|
||||
// Sub-image extraction
|
||||
//---
|
||||
|
||||
/* image_sub(): Build a reference to a sub-image
|
||||
|
||||
This function is used to create references to sub-images of RGB16 and P8
|
||||
images. The [data] pointer of the sub-image points somewhere within the data
|
||||
array of the source, and its [palette] pointer is identical to the source's.
|
||||
|
||||
The last parameter is a pointer to a preallocated image_t structure (usually
|
||||
on the stack) that gets filled with the data. Doing this instead of
|
||||
allocating a new object with malloc() means that there is no need to
|
||||
image_free() the sub-image, and thus it can be used inline:
|
||||
|
||||
image_t tmp;
|
||||
image_hflip(src, image_sub(dst, x, y, w, h, &tmp));
|
||||
|
||||
A preprocessor macro is used to make the last parameter optional. If it's
|
||||
not specified, a pointer to a static image_t will be returned instead. This
|
||||
is useful in inline calls as shown above, which then simplify to:
|
||||
|
||||
image_hflip(src, image_sub(dst, x, y, w, h));
|
||||
|
||||
However, another call to image_sub() or image_at() will override the
|
||||
sub-image, so you should only use this in such temporary settings. If you
|
||||
need multiple image_sub() or image_at() calls in the same statement, only
|
||||
one can use the short form.
|
||||
|
||||
If the requested rectangle does not intersect the source, the sub-image will
|
||||
be of dimension 0x0. If the image format does not support sub-images (P4),
|
||||
the sub-image will test invalid with image_valid(). */
|
||||
image_t *image_sub(image_t const *src, int x, int y, int w, int h,
|
||||
image_t *dst);
|
||||
|
||||
/* Make the last parameter optional */
|
||||
#define image_sub1(src, x, y, w, h, dst, ...) image_sub(src, x, y, w, h, dst)
|
||||
#define image_sub(...) image_sub1(__VA_ARGS__, NULL)
|
||||
|
||||
/* image_at(): Build a reference to a position within a sub-image */
|
||||
#define image_at(img, x, y) image_sub(img, x, y, -1, -1)
|
||||
|
||||
//---
|
||||
// Geometric image transforms
|
||||
//
|
||||
// All geometric transforms render to position (0,0) of the target image and
|
||||
// fail if the target image is not large enough to hold the transformed result
|
||||
// (unlike the rendering functions which render only the visible portion).
|
||||
//
|
||||
// To render at position (x,y) of the target image, use img_at(). For instance:
|
||||
// image_hflip(src, image_at(dst, x, y));
|
||||
//
|
||||
// Each transform function has an [_alloc] variant which does the same
|
||||
// transform but allocates the target image on the fly and returns it. Remember
|
||||
// that allocation can fail, so you need to check whether the returned image is
|
||||
// valid.
|
||||
//
|
||||
// (You can still pass invalid images to transform functions. The invalid image
|
||||
// will be ignored or returned unchanged, so you can chain calls and check for
|
||||
// validity at the end of the chain.)
|
||||
//
|
||||
// Some functions support in-place transforms. This means they can be called
|
||||
// with the source as destination, and will transform the image without needing
|
||||
// new memory. For instance, image_hflip(src, src) flips in-place and replaces
|
||||
// src with a flipped version of itself.
|
||||
//
|
||||
// (However, it is not possible to transform in-place if the source and
|
||||
// destination intersect in non-trivial ways. The result will be incorrect.)
|
||||
//
|
||||
// When transforming to a new image, transparent pixels are ignored, so if the
|
||||
// destination already has some data, it will not be erased automatically. Use
|
||||
// image_clear() beforehand to achieve that effect. This allows alpha blending
|
||||
// while transforming, which is especially useful on the VRAM.
|
||||
//---
|
||||
|
||||
/* image_hflip(): Flip horizontally
|
||||
Formats: RGB16, P8
|
||||
Size requirement: destination at least as large as source (no clipping)
|
||||
Supports in-place: Yes */
|
||||
void image_hflip(image_t const *src, image_t *dst, bool copy_alpha);
|
||||
image_t *image_hflip_alloc(image_t const *src);
|
||||
|
||||
/* image_vflip(): Flip vertically
|
||||
Formats: RGB16, P8
|
||||
Size requirement: destination at least as large as source (no clipping)
|
||||
Supports in-place: Yes */
|
||||
void image_vflip(image_t const *src, image_t *dst, bool copy_alpha);
|
||||
image_t *image_vflip_alloc(image_t const *src);
|
||||
|
||||
/* image_linear(): Linear transformation
|
||||
|
||||
This function implements a generic linear transformation. This is a powerful
|
||||
function that can perform any combination of rotation, mirroring and scaling
|
||||
with nearest-neighbor sampling.
|
||||
|
||||
The [image_linear_map] structure defines the settings for the transform.
|
||||
Users familiar with linear algebra might want to use it directly, but they
|
||||
are most conveniently generated with the rotation and scaling functions
|
||||
listed below.
|
||||
|
||||
Note: Currently the structure for the transform is modified by the
|
||||
operation and cannot be reused.
|
||||
|
||||
The image_linear_alloc() variant allocates a new image in addition to
|
||||
performing the transform. The image is created with size (map->dst_w,
|
||||
map->dst_h) which is always a reasonable default. If a target image of
|
||||
smaller size is supplied to image_linear(), clipping is performed; only the
|
||||
top-left corner of the full output is actually rendered.
|
||||
|
||||
Formats: RGB16, P8
|
||||
Size requirement: none (clipping is performed)
|
||||
Supports in-place: No */
|
||||
|
||||
struct image_linear_map {
|
||||
/* Dimensions of the source and destination */
|
||||
int src_w, src_h, dst_w, dst_h;
|
||||
/* Input and output stride in bytes */
|
||||
int src_stride, dst_stride;
|
||||
|
||||
/* The following parameters define the linear transformation as a mapping
|
||||
from coordinates in the destination image (x and y) into coordinates in
|
||||
the source image (u and v).
|
||||
- (u, v) indicate where the top-left corner of the destination lands in
|
||||
the source image.
|
||||
- (dx_u, dx_v) indicate the source-image movement for each movement of
|
||||
x += 1 in the destination.
|
||||
- (dy_u, dy_v) indicate the source-image movement for each movement of
|
||||
y += 1 in the destination.
|
||||
All of these values are specified as 16:16 fixed-point, ie. they encode
|
||||
decimal values by multiplying them by 65536. */
|
||||
int u, v, dx_u, dx_v, dy_u, dy_v;
|
||||
};
|
||||
|
||||
void image_linear(image_t const *src, image_t *dst,
|
||||
struct image_linear_map *map);
|
||||
image_t *image_linear_alloc(image_t const *src,
|
||||
struct image_linear_map *map);
|
||||
|
||||
/* image_scale(): Upscale or downscale an image
|
||||
|
||||
This function generates a linear map to be used in image_linear() to scale
|
||||
the input image. The scaling factor gamma can be specified independently for
|
||||
the x and y dimensions. It is expressed as 16:16 fixed-point; you can set
|
||||
any decimal value multiplied by 65536, for instance 1.5*65536 to increase
|
||||
the width and height by 50%. */
|
||||
void image_scale(image_t const *src, int gamma_x, int gamma_y,
|
||||
struct image_linear_map *map);
|
||||
|
||||
/* image_rotate(): Rotate an image around its center
|
||||
|
||||
This function generates a linear map to be used in image_linear() to perform
|
||||
a rotation around the center of an image. If [resize=true], the target is
|
||||
enlarged to make sure all the rotated pixels can be represented. This can
|
||||
increase the final surface by a factor of up to 2. If the original image
|
||||
doesn't extend to its corners, it is recommended to leave [resize=false] as
|
||||
it noticeably affects performance. */
|
||||
void image_rotate(image_t const *src, float angle, bool resize,
|
||||
struct image_linear_map *map);
|
||||
|
||||
/* image_rotate_around(): Rotate an image around any point
|
||||
|
||||
This function generalizes image_rotate() by allowing rotations around any
|
||||
center, even a point not within the image. The center is specified through
|
||||
two coordinates (*center_x, *center_y). If the center is near the side of
|
||||
the image, a normal rotation would move most of the pixels out of frame;
|
||||
this function moves the frame to make sure the whole image remains visible.
|
||||
*center_x and *center_y are updated to indicate the position of the center
|
||||
of rotation within the new frame (the target image). */
|
||||
void image_rotate_around(image_t const *src, float angle, bool resize,
|
||||
int *center_x, int *center_y, struct image_linear_map *map);
|
||||
|
||||
/* image_rotate_around_scale(): Rotate an image around any point and scale it
|
||||
|
||||
This function generalizes image_rotate_around() by adding a scaling factor
|
||||
to the transformation. The scaling factor gamma is expressed as 16:16
|
||||
fixed-point. If [resize=true] the image is further extended to make sure no
|
||||
parts are cut out, as in other rotation functions. */
|
||||
void image_rotate_around_scale(
|
||||
image_t const *src, float angle, int gamma,
|
||||
bool resize, int *center_x, int *center_y,
|
||||
struct image_linear_map *map);
|
||||
|
||||
//---
|
||||
// Color transforms
|
||||
//---
|
||||
|
||||
/* TODO: Color transforms */
|
||||
|
||||
//---
|
||||
// Image rendering functions
|
||||
//
|
||||
// The following functions extend dimage() and dsubimage(). The [effects]
|
||||
// parameter takes a combination of IMAGE_* flags and effects, limited to the
|
||||
// combinations previously described, with additional arguments depending on
|
||||
// the color effect being applied.
|
||||
//
|
||||
// dimage_effect(x, y, img, effects, ...)
|
||||
// dsubimage_effect(x, y, img, left, top, w, h, effects, ...)
|
||||
//
|
||||
// However if you use these super-generic functions you will link the code for
|
||||
// all effects and all formats into your add-in, which takes a fair amount of
|
||||
// space. If that's a problem, you can use the more specific functions below:
|
||||
//
|
||||
// * dimage_<FORMAT>_<EFFECT>() for one particular format (rgb16, p8, p4) along
|
||||
// with one particular color effect (clearbg, swapcolor, addbg, dye).
|
||||
// * dimage_<FORMAT>() is like the above when no color effect is applied.
|
||||
//
|
||||
// All of them support the HFLIP and VFLIP flags. For effect-specific functions
|
||||
// the corresponding effect flag can be omitted (fi. IMAGE_CLEARBG is implicit
|
||||
// when using dimage_p8_clearbg()).
|
||||
//---
|
||||
|
||||
/* dimage_effect(): Generalized dimage() supporting dynamic effects */
|
||||
#define dimage_effect(x, y, img, eff, ...) \
|
||||
dsubimage_effect(x, y, img, 0, 0, (img)->width, (img)->height, eff, \
|
||||
##__VA_ARGS__)
|
||||
/* dsubimage_effect(): Generalized dsubimage() supporting dynamic effects */
|
||||
void dsubimage_effect(int x, int y, image_t const *img,
|
||||
int left, int top, int w, int h, int effects, ...);
|
||||
|
||||
/* Specific versions for each format */
|
||||
#define DIMAGE_SIG1(NAME, ...) \
|
||||
void dimage_ ## NAME(int x, int y, image_t const *img,##__VA_ARGS__); \
|
||||
void dsubimage_ ## NAME(int x, int y, image_t const *img, \
|
||||
int left, int top, int w, int h, ##__VA_ARGS__);
|
||||
#define DIMAGE_SIG(NAME, ...) \
|
||||
DIMAGE_SIG1(rgb16 ## NAME, ##__VA_ARGS__) \
|
||||
DIMAGE_SIG1(p8 ## NAME, ##__VA_ARGS__) \
|
||||
DIMAGE_SIG1(p4 ## NAME, ##__VA_ARGS__)
|
||||
|
||||
/* d[sub]image_{rgb16,p8,p4}_effect(..., effects, <extra arguments>) */
|
||||
DIMAGE_SIG(_effect, int effects, ...)
|
||||
/* d[sub]image_{rgb16,p8,p4}(..., effects) (no color effect, like dimage()) */
|
||||
DIMAGE_SIG(, int effects)
|
||||
/* d[sub]image_{rgb16,p8,p4}_clearbg(..., effects, bg_color_or_index) */
|
||||
DIMAGE_SIG(_clearbg, int effects, int bg_color_or_index)
|
||||
/* d[sub]image_{rgb16,p8,p4}_swapcolor(..., effects, source, replacement) */
|
||||
DIMAGE_SIG(_swapcolor, int effects, int source, int replacement)
|
||||
/* d[sub]image_{rgb16,p8,p4}_addbg(..., effects, bg_color) */
|
||||
DIMAGE_SIG(_addbg, int effects, int bg_color)
|
||||
/* d[sub]image_{rgb16,p8,p4}_dye(..., effects, dye_color) */
|
||||
DIMAGE_SIG(_dye, int effects, int dye_color)
|
||||
|
||||
/* d[sub]image_p4_clearbg_alt(..., effects, bg_index)
|
||||
This is functionally identical to CLEARBG, but it uses an alternative
|
||||
rendering method that is faster for larger images with wide transparent
|
||||
areas. You can swap it with the normal CLEARBG freely. */
|
||||
DIMAGE_SIG1(p4_clearbg_alt, int effects, int bg_index)
|
||||
|
||||
#define dimage_rgb16_effect(x, y, img, eff, ...) \
|
||||
dsubimage_rgb16_effect(x, y, img, 0, 0, (img)->width, (img)->height, \
|
||||
eff, ##__VA_ARGS__)
|
||||
#define dimage_p8_effect(x, y, img, eff, ...) \
|
||||
dsubimage_p8_effect(x, y, img, 0, 0, (img)->width, (img)->height, \
|
||||
eff, ##__VA_ARGS__)
|
||||
#define dimage_p4_effect(x, y, img, eff, ...) \
|
||||
dsubimage_p4_effect(x, y, img, 0, 0, (img)->width, (img)->height, \
|
||||
eff, ##__VA_ARGS__)
|
||||
|
||||
#undef DIMAGE_SIG
|
||||
#undef DIMAGE_SIG1
|
||||
|
||||
//---
|
||||
// Clipping utilities
|
||||
//---
|
||||
|
||||
/* Double box specifying both a source and target area */
|
||||
struct gint_image_box
|
||||
{
|
||||
/* Target location of top-left corner */
|
||||
int x, y;
|
||||
/* Width and height of rendered sub-image */
|
||||
int w, h;
|
||||
/* Source bounding box (low included, high excluded) */
|
||||
int left, top;
|
||||
};
|
||||
|
||||
/* Clip the provided box against the input. If, after clipping, the box no
|
||||
longer intersects the output window, returns false. Otherwise, returns
|
||||
true. */
|
||||
bool gint_image_clip_input(image_t const *img, struct gint_image_box *box,
|
||||
struct dwindow const *window);
|
||||
|
||||
/* Clip the provided box against the output. */
|
||||
void gint_image_clip_output(struct gint_image_box *b,
|
||||
struct dwindow const *window);
|
||||
|
||||
//---
|
||||
// Internal image rendering routines
|
||||
//
|
||||
// The following functions (or non-functions) are implemented in assembler and
|
||||
// make up the internal interface of the image renderer. If you just want to
|
||||
// display images, use dimage() and variations; these are only useful if you
|
||||
// have a different rendering system and wish to use image rendering with
|
||||
// dynamic effects in it.
|
||||
//---
|
||||
|
||||
/* Renderer command. This structure includes most of the information used by
|
||||
the image renderer to perform blits. Some of the information on the target
|
||||
is also passed as direct arguments, which is more convenient and slightly
|
||||
faster.
|
||||
|
||||
Most of the values here can be set with gint_image_mkcmd(). The last two
|
||||
members, along with the return values of the gint_image_FORMAT_loop()
|
||||
functions, are used to update the command if one needs to draw *parts* of
|
||||
the image and resume the rendering later. This is used in Azur. */
|
||||
struct gint_image_cmd
|
||||
{
|
||||
/* Shader ID. This is used in Azur, and ignored in gint */
|
||||
uint8_t shader_id;
|
||||
/* Dynamic effects not already dispatched by renderer
|
||||
Bit 0: VFLIP
|
||||
Bit 1: HFLIP */
|
||||
uint8_t effect;
|
||||
|
||||
/* Number of pixels to render per line. For formats that force either x
|
||||
or width alignment (most of them), this is already adjusted to a
|
||||
suitable multiple (usually a multiple of 2). */
|
||||
int16_t columns;
|
||||
|
||||
/* Stride of the input image (number of pixels between each row), in
|
||||
pixels, without subtracting the number of columns */
|
||||
int16_t input_stride;
|
||||
|
||||
/* Number of lines in the command. This can be adjusted freely, and is
|
||||
particularly useful in Azur for fragmented rendering. */
|
||||
uint8_t lines;
|
||||
|
||||
/* [Any effect]: Offset of first edge */
|
||||
int8_t edge_1;
|
||||
|
||||
/* Core loop; this is an internal label of the renderer */
|
||||
void const *loop;
|
||||
/* Output pixel array, offset by target x/y */
|
||||
void const *output;
|
||||
/* Input pixel array, offset by source x/y. For formats that force x
|
||||
alignment, this is already adjusted. */
|
||||
void const *input;
|
||||
/* Palette, when applicable */
|
||||
uint16_t const *palette;
|
||||
|
||||
/* [Any effect]: Offset of right edge */
|
||||
int16_t edge_2;
|
||||
/* [CLEARBG, SWAPCOLOR]: Source color */
|
||||
uint16_t color_1;
|
||||
/* [SWAPCOLOR]: Destination color */
|
||||
uint16_t color_2;
|
||||
|
||||
/* Remaining height (for updates between fragments) */
|
||||
int16_t height;
|
||||
/* Local x position (for updates between fragments) */
|
||||
int16_t x;
|
||||
};
|
||||
|
||||
/* gint_image_mkcmd(): Prepare a rendering command with dynamic effects
|
||||
|
||||
This function crafts an image renderer command. It loads all the settings
|
||||
except for effect-dependent parameters: the [.loop] label, the color section
|
||||
of [.effect], and color effect settings. See the effect-specific functions
|
||||
to see how they are defined.
|
||||
|
||||
The benefit of this approach is that the rendering code does not need to be
|
||||
linked in unless an effect is actually used, which avoids blowing up the
|
||||
size of the add-in as the number of support dynamic effects increases.
|
||||
|
||||
@box Requested on-screen box (will be clipped depending on effects)
|
||||
@img Source image
|
||||
@effects Set of dynamic effects to be applied, as an [IMAGE_*] bitmask
|
||||
@left_edge Whether to force 2-alignment on the input (box->left)
|
||||
@right_edge Whether to force 2-alignment on the width
|
||||
@cmd Command to be filled
|
||||
@window Rendering window (usually {0, 0, DWIDTH, DHEIGHT})
|
||||
|
||||
Returns false if there is nothing to render because of clipping (in which
|
||||
case [cmd] is unchanged), true otherwise. [*box] is also updated to reflect
|
||||
the final box after clipping but not accounting for edges. */
|
||||
bool gint_image_mkcmd(struct gint_image_box *box, image_t const *img,
|
||||
int effects, bool left_edge, bool right_edge,
|
||||
struct gint_image_cmd *cmd, struct dwindow const *window);
|
||||
|
||||
/* Entry point of the renderers. These functions can be called normally as long
|
||||
as you can build the commands (eg. by using gint_image_mkcmd() then filling
|
||||
the effect-specific information). */
|
||||
void *gint_image_rgb16_loop (int output_width, struct gint_image_cmd *cmd);
|
||||
void *gint_image_p8_loop (int output_width, struct gint_image_cmd *cmd);
|
||||
void *gint_image_p4_loop (int output_width, struct gint_image_cmd *cmd);
|
||||
|
||||
/* Renderer fragments. The following can absolutely not be called from C code
|
||||
as they aren't full functions (and this isn't their prototype). These are
|
||||
continuations to be specified in the [.loop] field of a command before using
|
||||
one of the functions above. */
|
||||
|
||||
void gint_image_rgb16_normal(void);
|
||||
void gint_image_rgb16_clearbg(void);
|
||||
void gint_image_rgb16_swapcolor(void);
|
||||
void gint_image_rgb16_dye(void);
|
||||
|
||||
void gint_image_p8_normal(void);
|
||||
void gint_image_p8_clearbg(void);
|
||||
void gint_image_p8_swapcolor(void);
|
||||
void gint_image_p8_dye(void);
|
||||
|
||||
void gint_image_p4_normal(void);
|
||||
void gint_image_p4_clearbg(void);
|
||||
void gint_image_p4_clearbg_alt(void);
|
||||
void gint_image_p4_swapcolor(void);
|
||||
void gint_image_p4_dye(void);
|
||||
|
||||
//---
|
||||
// Image library utilities
|
||||
//
|
||||
// The following functions and macros are mostly internal utilities; they are
|
||||
// exposed here in case user applications want to extend the set of image
|
||||
// transforms with custom additions.
|
||||
//---
|
||||
|
||||
/* image_target(): Check if an image can be used as target for a transform
|
||||
|
||||
This function is used to quickly check whether a transform from [src] to
|
||||
[dst] is possible. It requires image_valid(src) and image_valid(dst), plus
|
||||
any optional constraints specified as variadic arguments. These constraints
|
||||
can be:
|
||||
|
||||
* NOT_P4: fails if [dst] is P4.
|
||||
* DATA_RW: fails if [dst] is not data-writable.
|
||||
* PALETTE_RW: fails if [dst] is not palette-writable.
|
||||
* SAME_SIZE: fails if [dst] is not at least as large as [src].
|
||||
|
||||
For example, in image_hflip(), we write:
|
||||
if(!image_target(src, dst, NOT_P4, DATA_RW, SAME_SIZE)) return; */
|
||||
|
||||
enum {
|
||||
IMAGE_TARGET_NONE,
|
||||
IMAGE_TARGET_NOT_P4,
|
||||
IMAGE_TARGET_DATA_RW,
|
||||
IMAGE_TARGET_PALETTE_RW,
|
||||
IMAGE_TARGET_SAME_SIZE,
|
||||
IMAGE_TARGET_SAME_FORMAT,
|
||||
IMAGE_TARGET_SAME_DEPTH,
|
||||
};
|
||||
bool image_target(image_t const *src, image_t *dst, ...);
|
||||
|
||||
#define image_target(src, dst, ...) \
|
||||
image_target(src, dst, image_target_arg1(__VA_ARGS__ __VA_OPT__(,) NONE))
|
||||
#define image_target_arg1(c, ...) \
|
||||
IMAGE_TARGET_ ## c __VA_OPT__(, image_target_arg2(__VA_ARGS__))
|
||||
#define image_target_arg2(c, ...) \
|
||||
IMAGE_TARGET_ ## c __VA_OPT__(, image_target_arg3(__VA_ARGS__))
|
||||
#define image_target_arg3(c, ...) \
|
||||
IMAGE_TARGET_ ## c __VA_OPT__(, image_target_arg4(__VA_ARGS__))
|
||||
#define image_target_arg4(c, ...) \
|
||||
IMAGE_TARGET_ ## c __VA_OPT__(, image_target_arg5(__VA_ARGS__))
|
||||
#define image_target_arg5(c, ...) \
|
||||
IMAGE_TARGET_ ## c __VA_OPT__(, image_target_arg6(__VA_ARGS__))
|
||||
#define image_target_arg6(c, ...) \
|
||||
IMAGE_TARGET_ ## c __VA_OPT__(, image_target_too_many_args(__VA_ARGS__))
|
||||
|
||||
/* image_alpha_2(): Conditional alpha */
|
||||
#define image_alpha_2(fmt, copy_alpha) \
|
||||
((copy_alpha) ? 0x10000 : image_alpha(fmt))
|
||||
|
||||
#endif /* GINT_RENDER_RGB */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GINT_IMAGE */
|
|
@ -1,23 +0,0 @@
|
|||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
#include "game_data.hpp"
|
||||
|
||||
struct texture_t builtin_textures[NB_TEXTURES] = {
|
||||
{"player_idle_sheet", &img_player_idle_sheet},
|
||||
{"player_walk_sheet", &img_player_walk_sheet}
|
||||
};
|
||||
|
||||
void load_json_into_game_data(json *json_input, game_data_t *bin_output)
|
||||
{
|
||||
}
|
||||
|
||||
void write_game_data_as_bin_into_file(game_data_t *game_data, std::ofstream *bin_output_file)
|
||||
{
|
||||
}
|
||||
|
||||
void free_game_data(game_data_t *game_data)
|
||||
{
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef GAME_DATA_HPP
|
||||
#define GAME_DATA_HPP
|
||||
|
||||
#include <fstream>
|
||||
#include <gint/display-cg.h>
|
||||
#include "nlohmann/json/json.hpp"
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
extern bopti_image_t img_player_idle_sheet;
|
||||
extern bopti_image_t img_player_walk_sheet;
|
||||
|
||||
typedef struct texture_t {
|
||||
const char *name;
|
||||
bopti_image_t *image;
|
||||
} texture_t;
|
||||
|
||||
#define NB_TEXTURES 2
|
||||
extern struct texture_t builtin_textures[];
|
||||
|
||||
typedef struct game_data_t {
|
||||
texture_t *textures;
|
||||
} game_data_t;
|
||||
|
||||
void load_json_into_game_data(json *json_input, game_data_t *game_data);
|
||||
|
||||
void write_game_data_as_bin_into_file(game_data_t *game_data, std::ofstream *bin_output_file);
|
||||
|
||||
void free_game_data(game_data_t *game_data);
|
||||
|
||||
#endif // GAME_DATA_HPP
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef ANIMATION_SYSTEM_H
|
||||
#define ANIMATION_SYSTEM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct animation_system_data_t {
|
||||
bool play :1;
|
||||
bool loop :1;
|
||||
bool reverse :1;
|
||||
|
||||
float frame_delay_ms;
|
||||
uint32_t actual_frame_nb;
|
||||
uint32_t nb_frames;
|
||||
} animation_system_data_t;
|
||||
|
||||
#endif // SPRITE_COMPONENT_H
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef COMPONENTS_H
|
||||
#define COMPONENTS_H
|
||||
|
||||
#include "transform_component.hpp"
|
||||
#include "sprite_component.hpp"
|
||||
#include "animation_system.hpp"
|
||||
// Add new components header file here
|
||||
|
||||
#endif // COMPONENTS_H
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef ECS_H
|
||||
#define ECS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "components.hpp"
|
||||
|
||||
typedef enum component_type_t {
|
||||
TRANSFORM_COMPONENT,
|
||||
SPRITE_COMPONENT,
|
||||
ANIMATION_SYSTEM
|
||||
} component_type_t;
|
||||
|
||||
typedef struct component_t {
|
||||
component_type_t component_type;
|
||||
|
||||
union {
|
||||
transform_component_data_t *transform_component_data;
|
||||
sprite_component_data_t *sprite_component_data;
|
||||
animation_system_data_t *animation_system_data;
|
||||
} component_data;
|
||||
} component_t;
|
||||
|
||||
typedef struct entity_t {
|
||||
uint16_t id;
|
||||
|
||||
unsigned long nb_component;
|
||||
component_t *components;
|
||||
} entity_t;
|
||||
|
||||
#endif // ECS_H
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef SPRITE_COMPONENT_H
|
||||
#define SPRITE_COMPONENT_H
|
||||
|
||||
typedef struct sprite_component_data_t {
|
||||
const char *texture_name;
|
||||
} sprite_component_data_t;
|
||||
|
||||
#endif // SPRITE_COMPONENT_H
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef TRANSFORM_COMPONENT_H
|
||||
#define TRANSFORM_COMPONENT_H
|
||||
|
||||
typedef struct transform_component_data_t {
|
||||
uint32_t x, y;
|
||||
uint32_t w, h;
|
||||
float speed;
|
||||
} transform_component_data_t;
|
||||
|
||||
#endif // TRANSFORM_COMPONENT_H
|
|
@ -0,0 +1,22 @@
|
|||
#include <iosfwd>
|
||||
|
||||
#include "game_data.hpp"
|
||||
|
||||
game_data_t game_data {};
|
||||
|
||||
static inline void verify_integrity(void)
|
||||
{
|
||||
verify_textures_integrity();
|
||||
verify_maps_integrity();
|
||||
}
|
||||
|
||||
void write_game_data_as_bin_into_file(void)
|
||||
{
|
||||
std::ofstream bin_output_file {"GameData.bin", std::ios::binary};
|
||||
if(!bin_output_file)
|
||||
{
|
||||
throw std::runtime_error("Couldn't create output file");
|
||||
}
|
||||
|
||||
verify_integrity();
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef GAME_DATA_HPP
|
||||
#define GAME_DATA_HPP
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "textures.hpp"
|
||||
#include "maps.hpp"
|
||||
|
||||
typedef struct game_data_t {
|
||||
const uint32_t nb_textures = NB_TEXTURES;
|
||||
const texture_t *textures = textures;
|
||||
|
||||
const uint32_t nb_maps = NB_MAPS;
|
||||
const map_t **maps = maps;
|
||||
} game_data_t;
|
||||
|
||||
void write_game_data_as_bin_into_file(void);
|
||||
|
||||
#endif // GAME_DATA_HPP
|
|
@ -0,0 +1,84 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "maps.hpp"
|
||||
|
||||
static inline void verify_layers_integrity(void)
|
||||
{
|
||||
for(uint32_t map_index = 0; map_index < NB_MAPS; map_index++)
|
||||
{
|
||||
std::cout << "Map " << map_index + 1 << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void verify_entities_integrity(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void verify_maps_integrity(void)
|
||||
{
|
||||
std::cout << "Nb Maps : " << NB_MAPS << std::endl;
|
||||
|
||||
for(uint32_t map_index = 0; map_index < NB_MAPS; map_index++)
|
||||
{
|
||||
const uint32_t NB_ENTITIES = maps[map_index]->nb_entities;
|
||||
const entity_t *ENTITIES = maps[map_index]->entities;
|
||||
|
||||
std::cout << "Map " << map_index + 1 << std::endl;
|
||||
std::cout << " - MapName : " << maps[map_index]->map_name << std::endl;
|
||||
std::cout << " - MapWidth : " << maps[map_index]->map_width << std::endl;
|
||||
std::cout << " - MapHeight : " << maps[map_index]->map_width << std::endl;
|
||||
std::cout << " - Nb Entities : " << NB_ENTITIES << std::endl;
|
||||
|
||||
for(uint32_t entity_index = 0; entity_index < NB_ENTITIES; entity_index++)
|
||||
{
|
||||
const uint32_t NB_COMPONENTS = ENTITIES->nb_component;
|
||||
const component_t *COMPONENTS = ENTITIES->components;
|
||||
|
||||
std::cout << " - Nb Components : " << NB_COMPONENTS << std::endl;
|
||||
|
||||
for(uint32_t component_index = 0; component_index < NB_COMPONENTS; component_index++)
|
||||
{
|
||||
const component_t *COMPONENT = &COMPONENTS[component_index];
|
||||
|
||||
std::cout << " Component " << component_index << std::endl;
|
||||
|
||||
switch(COMPONENT->component_type)
|
||||
{
|
||||
case TRANSFORM_COMPONENT:
|
||||
{
|
||||
const transform_component_data_t *component_data = COMPONENT->component_data.transform_component_data;
|
||||
std::cout << " - TransformComponent :" << std::endl;
|
||||
std::cout << " - x : " << component_data->x << std::endl;
|
||||
std::cout << " - y : " << component_data->y << std::endl;
|
||||
std::cout << " - w : " << component_data->w << std::endl;
|
||||
std::cout << " - h : " << component_data->h << std::endl;
|
||||
std::cout << " - Speed : " << component_data->speed << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case SPRITE_COMPONENT:
|
||||
{
|
||||
const sprite_component_data_t *component_data = COMPONENT->component_data.sprite_component_data;
|
||||
std::cout << " - SpriteComponent :" << std::endl;
|
||||
std::cout << " - TextureName : " << component_data->texture_name << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case ANIMATION_SYSTEM:
|
||||
{
|
||||
const animation_system_data_t *system_data = COMPONENT->component_data.animation_system_data;
|
||||
std::cout << " - AnimationSystem :" << std::endl;
|
||||
std::cout << " - NbFrames : " << system_data->nb_frames;
|
||||
std::cout << " - FrameNb : " << system_data->actual_frame_nb;
|
||||
std::cout << " - FrameDelay : " << system_data->frame_delay_ms;
|
||||
std::cout << " - Play : " << system_data->play;
|
||||
std::cout << " - Loop : " << system_data->loop;
|
||||
std::cout << " - Reverse : " << system_data->reverse;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef MAP_HPP
|
||||
#define MAP_HPP
|
||||
|
||||
#include "ecs/ecs.hpp"
|
||||
|
||||
typedef struct map_t {
|
||||
const char *map_name;
|
||||
|
||||
const uint32_t map_width;
|
||||
const uint32_t map_height;
|
||||
|
||||
const uint16_t *map_background_layer1;
|
||||
const uint16_t *map_background_layer2;
|
||||
const uint16_t *map_background_layer3;
|
||||
const uint16_t *map_foreground;
|
||||
|
||||
const uint32_t nb_entities;
|
||||
const entity_t *entities;
|
||||
} __attribute__((packed, aligned(4))) map_t;
|
||||
|
||||
extern map_t map_example;
|
||||
|
||||
static map_t *maps[] = {
|
||||
&map_example
|
||||
};
|
||||
|
||||
#define NB_MAPS 1
|
||||
|
||||
// Throw an exception if maps integrity is not complete
|
||||
void verify_maps_integrity(void);
|
||||
|
||||
#endif // MAP_HPP
|
|
@ -0,0 +1,6 @@
|
|||
#include "textures.hpp"
|
||||
|
||||
void verify_textures_integrity(void)
|
||||
{
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef TEXTURES_HPP
|
||||
#define TEXTURES_HPP
|
||||
|
||||
#include <gint/image.h>
|
||||
|
||||
typedef struct texture_t {
|
||||
const char *name;
|
||||
const bopti_image_t *image;
|
||||
} __attribute__((packed, aligned(4))) texture_t;
|
||||
|
||||
extern bopti_image_t img_tileset;
|
||||
extern bopti_image_t img_player_idle_sheet;
|
||||
extern bopti_image_t img_player_walk_sheet;
|
||||
extern bopti_image_t img_player_run_sheet;
|
||||
extern bopti_image_t img_barred_door_sheet;
|
||||
extern bopti_image_t img_lever_sheet;
|
||||
extern bopti_image_t img_small_chest_sheet;
|
||||
extern bopti_image_t img_big_chest_sheet;
|
||||
|
||||
static texture_t textures[] = {
|
||||
{"tileset", &img_tileset},
|
||||
{"player_idle_sheet", &img_player_idle_sheet},
|
||||
{"player_walk_sheet", &img_player_walk_sheet},
|
||||
{"player_run_sheet", &img_player_run_sheet},
|
||||
{"barred_door_sheet", &img_barred_door_sheet},
|
||||
{"lever_sheet", &img_lever_sheet},
|
||||
{"small_chest_sheet", &img_small_chest_sheet},
|
||||
{"big_chest_sheet", &img_big_chest_sheet}
|
||||
};
|
||||
|
||||
#define NB_TEXTURES 8
|
||||
|
||||
// Throw an exception if textures integrity is not complete
|
||||
void verify_textures_integrity(void);
|
||||
|
||||
#endif // TEXTURE_HPP
|
33
src/main.cpp
|
@ -1,40 +1,21 @@
|
|||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "game_data.hpp"
|
||||
#include "game_data/game_data.hpp"
|
||||
|
||||
void error(std::string error);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(void)
|
||||
{
|
||||
if(argc != 3)
|
||||
try
|
||||
{
|
||||
error("You need to give an input and output file");
|
||||
return EXIT_FAILURE;
|
||||
write_game_data_as_bin_into_file();
|
||||
}
|
||||
|
||||
std::ifstream json_input_file {argv[1]};
|
||||
if(!json_input_file)
|
||||
catch(std::exception const &exception)
|
||||
{
|
||||
error("Couldn't open input file");
|
||||
return EXIT_FAILURE;
|
||||
error(static_cast<std::string>(exception.what()));
|
||||
}
|
||||
|
||||
std::ofstream bin_output_file {argv[2], std::ios::binary};
|
||||
if(!bin_output_file)
|
||||
{
|
||||
error("Couldn't create output file");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
json json_input = json::parse(json_input_file);
|
||||
game_data_t game_data;
|
||||
|
||||
load_json_into_game_data(&json_input, &game_data);
|
||||
|
||||
write_game_data_as_bin_into_file(&game_data, &bin_output_file);
|
||||
|
||||
free_game_data(&game_data);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
14
src/test.cpp
|
@ -1,14 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <gint/display-cg.h>
|
||||
|
||||
extern bopti_image_t img_tileset;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int16_t value = 0;
|
||||
printf("colorcount:%d, value:%d\n", img_tileset.color_count, value);
|
||||
printf("width:%d, height:%d\n", img_tileset.width, img_tileset.height);
|
||||
printf("totalsize:%ld\n", sizeof(img_tileset) + img_tileset.width * img_tileset.height);
|
||||
|
||||
return 0;
|
||||
}
|