implement game configuration file
this integrates https://github.com/cktan/tomlc99 into the repo as a dependency
This commit is contained in:
parent
ec15d8ec4b
commit
57fe5e8946
@ -86,6 +86,7 @@ endif()
|
|||||||
set(TWN_THIRD_PARTY_SOURCE_FILES
|
set(TWN_THIRD_PARTY_SOURCE_FILES
|
||||||
third-party/physfs/extras/physfsrwops.c
|
third-party/physfs/extras/physfsrwops.c
|
||||||
third-party/stb/stb_vorbis.c
|
third-party/stb/stb_vorbis.c
|
||||||
|
third-party/tomlc99/toml.c
|
||||||
$<$<NOT:$<BOOL:${EMSCRIPTEN}>>:third-party/glad/src/glad.c>)
|
$<$<NOT:$<BOOL:${EMSCRIPTEN}>>:third-party/glad/src/glad.c>)
|
||||||
|
|
||||||
set(TWN_SOURCE_FILES
|
set(TWN_SOURCE_FILES
|
||||||
@ -135,10 +136,6 @@ target_precompile_headers(${TWN_TARGET} PRIVATE
|
|||||||
third-party/stb/stb_ds.h)
|
third-party/stb/stb_ds.h)
|
||||||
|
|
||||||
# distribution definitions, set them with -DX=X in cli
|
# distribution definitions, set them with -DX=X in cli
|
||||||
set(ORGANIZATION_NAME "wanp" CACHE STRING
|
|
||||||
"App developer/publisher's identifier")
|
|
||||||
set(APP_NAME "townengine" CACHE STRING
|
|
||||||
"App identifier")
|
|
||||||
set(PACKAGE_EXTENSION "btw" CACHE STRING
|
set(PACKAGE_EXTENSION "btw" CACHE STRING
|
||||||
"File extension used to look for data archives")
|
"File extension used to look for data archives")
|
||||||
|
|
||||||
@ -226,6 +223,7 @@ function(include_deps target)
|
|||||||
third-party/libxm/include
|
third-party/libxm/include
|
||||||
third-party/stb
|
third-party/stb
|
||||||
third-party/x-watcher
|
third-party/x-watcher
|
||||||
|
third-party/tomlc99
|
||||||
$<$<NOT:$<BOOL:${EMSCRIPTEN}>>:third-party/glad/include>)
|
$<$<NOT:$<BOOL:${EMSCRIPTEN}>>:third-party/glad/include>)
|
||||||
|
|
||||||
list(TRANSFORM THIRD_PARTY_INCLUDES PREPEND ${TWN_ROOT_DIR}/)
|
list(TRANSFORM THIRD_PARTY_INCLUDES PREPEND ${TWN_ROOT_DIR}/)
|
||||||
|
@ -18,7 +18,7 @@ static void title_tick(State *state) {
|
|||||||
|
|
||||||
|
|
||||||
m_sprite("/assets/title.png", ((Rect) {
|
m_sprite("/assets/title.png", ((Rect) {
|
||||||
((float)RENDER_BASE_WIDTH / 2) - ((float)320 / 2), 64, 320, 128 }));
|
((float)ctx.base_draw_w / 2) - ((float)320 / 2), 64, 320, 128 }));
|
||||||
|
|
||||||
|
|
||||||
/* draw the tick count as an example of dynamic text */
|
/* draw the tick count as an example of dynamic text */
|
||||||
|
@ -16,7 +16,7 @@ static void title_tick(State *state) {
|
|||||||
|
|
||||||
|
|
||||||
m_sprite("/assets/title.png", ((Rect) {
|
m_sprite("/assets/title.png", ((Rect) {
|
||||||
((float)RENDER_BASE_WIDTH / 2) - ((float)320 / 2), 64, 320, 128 }));
|
((float)ctx.base_draw_w / 2) - ((float)320 / 2), 64, 320, 128 }));
|
||||||
|
|
||||||
|
|
||||||
/* draw the tick count as an example of dynamic text */
|
/* draw the tick count as an example of dynamic text */
|
||||||
|
27
data/twn.toml
Normal file
27
data/twn.toml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# This file contains everything about the engine and your game that can be
|
||||||
|
# configured before it runs.
|
||||||
|
#
|
||||||
|
# Optional settings are commented out, with their default values shown.
|
||||||
|
# Invalid values in these settings will be ignored.
|
||||||
|
|
||||||
|
# Data about your game as an application
|
||||||
|
[about]
|
||||||
|
title = "It's TownEngine!"
|
||||||
|
developer = "Somebody"
|
||||||
|
app_id = "townengine"
|
||||||
|
dev_id = "somebody"
|
||||||
|
|
||||||
|
# Game runtime details
|
||||||
|
[game]
|
||||||
|
base_render_width = 640
|
||||||
|
base_render_height = 360
|
||||||
|
#debug = true
|
||||||
|
|
||||||
|
# Engine tweaks. You probably don't need to change these
|
||||||
|
[engine]
|
||||||
|
#ticks_per_second = 60 # minimum of 8
|
||||||
|
#keybind_slots = 3 # minimum of 1
|
||||||
|
#texture_atlas_size = 2048 # minimum of 32
|
||||||
|
#font_texture_size = 2048 # minimum of 1024
|
||||||
|
#font_oversampling = 4 # minimum of 0
|
||||||
|
#font_filtering = "linear" # possible values: "nearest", "linear"
|
@ -1,35 +1,25 @@
|
|||||||
#ifndef TWN_CONFIG_H
|
#ifndef TWN_CONFIG_H
|
||||||
#define TWN_CONFIG_H
|
#define TWN_CONFIG_H
|
||||||
|
|
||||||
/*
|
/* TODO: consider if it's still necessary to keep these in one place */
|
||||||
* this file is for configuration values which are to be set at
|
|
||||||
* compile time. generally speaking, it's for things that would be unwise to
|
|
||||||
* change mid-development without considering the work it might take to
|
|
||||||
* adapt the game logic.
|
|
||||||
*
|
|
||||||
* if you're looking for distribution-related definitions like
|
|
||||||
* APP_NAME, you should know that they are set from CMake.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define TICKS_PER_SECOND 60
|
#define TICKS_PER_SECOND_DEFAULT 60
|
||||||
#define FIXED_DELTA_TIME (1.0 / TICKS_PER_SECOND)
|
|
||||||
|
|
||||||
#define RENDER_BASE_WIDTH 640
|
#define BASE_RENDER_WIDTH_DEFAULT 640
|
||||||
#define RENDER_BASE_HEIGHT 360
|
#define BASE_RENDER_HEIGHT_DEFAULT 360
|
||||||
#define RENDER_BASE_RATIO ((float)RENDER_BASE_WIDTH / (float)RENDER_BASE_HEIGHT)
|
|
||||||
|
|
||||||
#define TEXTURE_ATLAS_SIZE 2048
|
#define TEXTURE_ATLAS_SIZE_DEFAULT 2048
|
||||||
#define TEXTURE_ATLAS_BIT_DEPTH 32
|
#define TEXTURE_ATLAS_BIT_DEPTH 32
|
||||||
#define TEXTURE_ATLAS_FORMAT SDL_PIXELFORMAT_RGBA32
|
#define TEXTURE_ATLAS_FORMAT SDL_PIXELFORMAT_RGBA32
|
||||||
|
|
||||||
#define NUM_KEYBIND_SLOTS 8
|
#define KEYBIND_SLOTS_DEFAULT 3
|
||||||
|
|
||||||
#define AUDIO_FREQUENCY 48000
|
#define AUDIO_FREQUENCY 48000
|
||||||
#define AUDIO_N_CHANNELS 2
|
#define AUDIO_N_CHANNELS 2
|
||||||
|
|
||||||
#define TEXT_FONT_TEXTURE_SIZE 1024
|
#define TEXT_FONT_TEXTURE_SIZE_DEFAULT 2048
|
||||||
#define TEXT_FONT_OVERSAMPLING 4
|
#define TEXT_FONT_OVERSAMPLING_DEFAULT 4
|
||||||
#define TEXT_FONT_FILTERING TEXTURE_FILTER_LINEAR
|
#define TEXT_FONT_FILTERING_DEFAULT TEXTURE_FILTER_LINEAR
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef struct Context {
|
typedef struct Context {
|
||||||
struct InputState input;
|
InputState input;
|
||||||
|
|
||||||
int64_t delta_time; /* preserves real time frame delta with no manipilation */
|
int64_t delta_time; /* preserves real time frame delta with no manipilation */
|
||||||
uint64_t tick_count;
|
uint64_t tick_count;
|
||||||
@ -17,12 +17,14 @@ typedef struct Context {
|
|||||||
/* set just once on startup */
|
/* set just once on startup */
|
||||||
uint64_t random_seed;
|
uint64_t random_seed;
|
||||||
|
|
||||||
/* this should be a multiple of TICKS_PER_SECOND */
|
/* this should be a multiple of the current ticks per second */
|
||||||
/* use it to simulate low framerate (e.g. at 60 tps, set to 2 for 30 fps) */
|
/* use it to simulate low framerate (e.g. at 60 tps, set to 2 for 30 fps) */
|
||||||
/* it can be changed at runtime; any resulting logic anomalies are bugs */
|
/* it can be changed at runtime; any resulting logic anomalies are bugs */
|
||||||
unsigned int update_multiplicity;
|
unsigned int update_multiplicity;
|
||||||
int window_w;
|
int window_w;
|
||||||
int window_h;
|
int window_h;
|
||||||
|
int base_draw_w;
|
||||||
|
int base_draw_h;
|
||||||
|
|
||||||
/* you may read from and write to these from game code */
|
/* you may read from and write to these from game code */
|
||||||
void *udata;
|
void *udata;
|
||||||
|
@ -41,9 +41,9 @@ typedef struct Button {
|
|||||||
typedef struct Action {
|
typedef struct Action {
|
||||||
size_t num_bindings;
|
size_t num_bindings;
|
||||||
|
|
||||||
/* if you bind more than NUM_KEYBIND_SLOTS (set in config.h) */
|
/* if you bind more than the number set in the configuration file */
|
||||||
/* it forgets the first Button to add the new one at the end */
|
/* it forgets the first Button to add the new one at the end */
|
||||||
Button bindings[NUM_KEYBIND_SLOTS];
|
Button *bindings;
|
||||||
|
|
||||||
Vec2 position; /* set if applicable, e.g. mouse click */
|
Vec2 position; /* set if applicable, e.g. mouse click */
|
||||||
bool is_pressed;
|
bool is_pressed;
|
||||||
|
@ -104,7 +104,7 @@ void use_2d_pipeline(void) {
|
|||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glOrtho(0, RENDER_BASE_WIDTH, RENDER_BASE_HEIGHT, 0, -1, 1);
|
glOrtho(0, (double)ctx.base_render_width, (double)ctx.base_render_height, 0, -1, 1);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
@ -106,9 +106,9 @@ void render(void) {
|
|||||||
|
|
||||||
/* fit rendering context onto the resizable screen */
|
/* fit rendering context onto the resizable screen */
|
||||||
if (ctx.game.window_size_has_changed) {
|
if (ctx.game.window_size_has_changed) {
|
||||||
if ((float)ctx.game.window_w / (float)ctx.game.window_h > RENDER_BASE_RATIO) {
|
if ((float)ctx.game.window_w / (float)ctx.game.window_h > (float)(ctx.base_render_width / ctx.base_render_height)) {
|
||||||
float ratio = (float)ctx.game.window_h / (float)RENDER_BASE_HEIGHT;
|
float ratio = (float)ctx.game.window_h / (float)ctx.base_render_height;
|
||||||
int w = (int)((float)RENDER_BASE_WIDTH * ratio);
|
int w = (int)((float)ctx.base_render_width * ratio);
|
||||||
setup_viewport(
|
setup_viewport(
|
||||||
ctx.game.window_w / 2 - w / 2,
|
ctx.game.window_w / 2 - w / 2,
|
||||||
0,
|
0,
|
||||||
@ -116,8 +116,8 @@ void render(void) {
|
|||||||
ctx.game.window_h
|
ctx.game.window_h
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
float ratio = (float)ctx.game.window_w / (float)RENDER_BASE_WIDTH;
|
float ratio = (float)ctx.game.window_w / (float)ctx.base_render_width;
|
||||||
int h = (int)((float)RENDER_BASE_HEIGHT * ratio);
|
int h = (int)((float)ctx.base_render_height * ratio);
|
||||||
setup_viewport(
|
setup_viewport(
|
||||||
0,
|
0,
|
||||||
ctx.game.window_h / 2 - h / 2,
|
ctx.game.window_h / 2 - h / 2,
|
||||||
|
@ -99,7 +99,7 @@ static FontData *text_load_font_data(const char *path, int height_px) {
|
|||||||
font_data->file_path = path;
|
font_data->file_path = path;
|
||||||
font_data->height_px = height_px;
|
font_data->height_px = height_px;
|
||||||
|
|
||||||
unsigned char* bitmap = ccalloc(TEXT_FONT_TEXTURE_SIZE * TEXT_FONT_TEXTURE_SIZE, 1);
|
unsigned char* bitmap = ccalloc(ctx.font_texture_size * ctx.font_texture_size, 1);
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned char *buf = NULL;
|
unsigned char *buf = NULL;
|
||||||
@ -121,19 +121,19 @@ static FontData *text_load_font_data(const char *path, int height_px) {
|
|||||||
font_data->line_gap = (int)((float)font_data->line_gap * font_data->scale_factor);
|
font_data->line_gap = (int)((float)font_data->line_gap * font_data->scale_factor);
|
||||||
|
|
||||||
stbtt_pack_context pctx;
|
stbtt_pack_context pctx;
|
||||||
stbtt_PackBegin(&pctx, bitmap, TEXT_FONT_TEXTURE_SIZE, TEXT_FONT_TEXTURE_SIZE, 0, 1, NULL);
|
stbtt_PackBegin(&pctx, bitmap, (int)ctx.font_texture_size, (int)ctx.font_texture_size, 0, 1, NULL);
|
||||||
stbtt_PackSetOversampling(&pctx, TEXT_FONT_OVERSAMPLING, TEXT_FONT_OVERSAMPLING);
|
stbtt_PackSetOversampling(&pctx, (unsigned int)ctx.font_oversampling, (unsigned int)ctx.font_oversampling);
|
||||||
stbtt_PackFontRange(&pctx, buf, 0, (float)height_px, ASCII_START, NUM_DISPLAY_ASCII, font_data->char_data);
|
stbtt_PackFontRange(&pctx, buf, 0, (float)height_px, ASCII_START, NUM_DISPLAY_ASCII, font_data->char_data);
|
||||||
stbtt_PackEnd(&pctx);
|
stbtt_PackEnd(&pctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
font_data->texture = create_gpu_texture(TEXT_FONT_FILTERING, true);
|
font_data->texture = create_gpu_texture(ctx.font_filtering, true);
|
||||||
upload_gpu_texture(
|
upload_gpu_texture(
|
||||||
font_data->texture,
|
font_data->texture,
|
||||||
bitmap,
|
bitmap,
|
||||||
1,
|
1,
|
||||||
TEXT_FONT_TEXTURE_SIZE,
|
(int)ctx.font_texture_size,
|
||||||
TEXT_FONT_TEXTURE_SIZE
|
(int)ctx.font_texture_size
|
||||||
);
|
);
|
||||||
SDL_free(bitmap);
|
SDL_free(bitmap);
|
||||||
|
|
||||||
@ -169,8 +169,8 @@ static void text_draw_with(FontData* font_data, char* text, Vec2 position, Color
|
|||||||
stbtt_aligned_quad quad;
|
stbtt_aligned_quad quad;
|
||||||
stbtt_GetPackedQuad(
|
stbtt_GetPackedQuad(
|
||||||
font_data->char_data,
|
font_data->char_data,
|
||||||
TEXT_FONT_TEXTURE_SIZE,
|
(int)ctx.font_texture_size,
|
||||||
TEXT_FONT_TEXTURE_SIZE,
|
(int)ctx.font_texture_size,
|
||||||
c - ASCII_START,
|
c - ASCII_START,
|
||||||
&position.x,
|
&position.x,
|
||||||
&position.y,
|
&position.y,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "twn_camera.h"
|
#include "twn_camera.h"
|
||||||
#include "twn_config.h"
|
#include "twn_config.h"
|
||||||
|
#include "twn_engine_context_c.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ Matrix4 camera_perspective(const Camera *const camera) {
|
|||||||
/* from cglm */
|
/* from cglm */
|
||||||
Matrix4 result = {0};
|
Matrix4 result = {0};
|
||||||
|
|
||||||
const float aspect = RENDER_BASE_RATIO;
|
const float aspect = (float)(ctx.base_render_width / ctx.base_render_height);
|
||||||
|
|
||||||
const float f = 1.0f / tanf(camera->fov * 0.5f);
|
const float f = 1.0f / tanf(camera->fov * 0.5f);
|
||||||
const float fn = 1.0f / (CAMERA_NEAR_Z - CAMERA_FAR_Z);
|
const float fn = 1.0f / (CAMERA_NEAR_Z - CAMERA_FAR_Z);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "rendering/twn_rendering_c.h"
|
#include "rendering/twn_rendering_c.h"
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
#include <toml.h>
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -21,11 +22,24 @@ typedef struct EngineContext {
|
|||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
|
|
||||||
struct Primitive2D *render_queue_2d;
|
/* configuration */
|
||||||
|
toml_table_t *config_table;
|
||||||
|
int64_t base_render_width;
|
||||||
|
int64_t base_render_height;
|
||||||
|
int64_t ticks_per_second;
|
||||||
|
int64_t keybind_slots;
|
||||||
|
int64_t texture_atlas_size;
|
||||||
|
int64_t font_texture_size;
|
||||||
|
int64_t font_oversampling;
|
||||||
|
TextureFilter font_filtering;
|
||||||
|
|
||||||
|
/* rendering */
|
||||||
|
Primitive2D *render_queue_2d;
|
||||||
MeshBatchItem *uncolored_mesh_batches;
|
MeshBatchItem *uncolored_mesh_batches;
|
||||||
struct TextCache text_cache;
|
TextCache text_cache;
|
||||||
TextureCache texture_cache;
|
TextureCache texture_cache;
|
||||||
|
|
||||||
|
/* audio */
|
||||||
AudioChannelItem *audio_channels;
|
AudioChannelItem *audio_channels;
|
||||||
SDL_AudioDeviceID audio_device;
|
SDL_AudioDeviceID audio_device;
|
||||||
int audio_stream_frequency;
|
int audio_stream_frequency;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "twn_input_c.h"
|
#include "twn_input_c.h"
|
||||||
#include "twn_util.h"
|
#include "twn_util.h"
|
||||||
|
#include "twn_engine_context_c.h"
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <stb_ds.h>
|
#include <stb_ds.h>
|
||||||
@ -9,7 +10,7 @@
|
|||||||
|
|
||||||
|
|
||||||
static void update_action_pressed_state(InputState *input, Action *action) {
|
static void update_action_pressed_state(InputState *input, Action *action) {
|
||||||
for (size_t i = 0; i < SDL_arraysize(action->bindings); ++i) {
|
for (size_t i = 0; i < (uint64_t)ctx.keybind_slots; ++i) {
|
||||||
switch (action->bindings[i].source) {
|
switch (action->bindings[i].source) {
|
||||||
case BUTTON_SOURCE_NOT_SET:
|
case BUTTON_SOURCE_NOT_SET:
|
||||||
break;
|
break;
|
||||||
@ -74,7 +75,7 @@ static void input_bind_code_to_action(InputState *input,
|
|||||||
Action *action = &action_item->value;
|
Action *action = &action_item->value;
|
||||||
|
|
||||||
/* check every binding to make sure this code isn't already bound */
|
/* check every binding to make sure this code isn't already bound */
|
||||||
for (size_t i = 0; i < SDL_arraysize(action->bindings); ++i) {
|
for (size_t i = 0; i < (uint64_t)ctx.keybind_slots; ++i) {
|
||||||
Button *binding = &action->bindings[i];
|
Button *binding = &action->bindings[i];
|
||||||
|
|
||||||
if (binding->source != source)
|
if (binding->source != source)
|
||||||
@ -105,7 +106,7 @@ static void input_bind_code_to_action(InputState *input,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* if we're at max bindings, forget the first element and shift the rest */
|
/* if we're at max bindings, forget the first element and shift the rest */
|
||||||
if (action->num_bindings == SDL_arraysize(action->bindings)) {
|
if (action->num_bindings == (uint64_t)ctx.keybind_slots) {
|
||||||
--action->num_bindings;
|
--action->num_bindings;
|
||||||
size_t shifted_size = (sizeof action->bindings) - (sizeof action->bindings[0]);
|
size_t shifted_size = (sizeof action->bindings) - (sizeof action->bindings[0]);
|
||||||
SDL_memmove(action->bindings, action->bindings + 1, shifted_size);
|
SDL_memmove(action->bindings, action->bindings + 1, shifted_size);
|
||||||
@ -133,7 +134,7 @@ static void input_unbind_code_from_action(InputState *input,
|
|||||||
/* check every binding to make sure this code is bound */
|
/* check every binding to make sure this code is bound */
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
bool is_bound = false;
|
bool is_bound = false;
|
||||||
for (index = 0; index < SDL_arraysize(action->bindings); ++index) {
|
for (index = 0; index < (uint64_t)ctx.keybind_slots; ++index) {
|
||||||
Button *binding = &action->bindings[index];
|
Button *binding = &action->bindings[index];
|
||||||
|
|
||||||
if (binding->source != source)
|
if (binding->source != source)
|
||||||
@ -249,13 +250,21 @@ void input_add_action(InputState *input, char *action_name) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
shput(input->action_hash, action_name, (Action) { 0 });
|
Action new_action = { 0 };
|
||||||
|
new_action.bindings = ccalloc(ctx.keybind_slots, sizeof *new_action.bindings);
|
||||||
|
shput(input->action_hash, action_name, new_action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void input_delete_action(InputState *input, char *action_name) {
|
void input_delete_action(InputState *input, char *action_name) {
|
||||||
if (shdel(input->action_hash, action_name) == 0)
|
ActionHashItem *action = shgetp_null(input->action_hash, action_name);
|
||||||
|
if (action == NULL) {
|
||||||
log_warn("(%s) Action \"%s\" is not registered.", __func__, action_name);
|
log_warn("(%s) Action \"%s\" is not registered.", __func__, action_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_free(action->value.bindings);
|
||||||
|
shdel(input->action_hash, action_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -314,5 +323,10 @@ bool input_is_mouse_captured(InputState *input) {
|
|||||||
|
|
||||||
|
|
||||||
void input_reset_state(InputState *input) {
|
void input_reset_state(InputState *input) {
|
||||||
|
for (size_t i = 0; i < shlenu(input->action_hash); ++i) {
|
||||||
|
Action *action = &input->action_hash[i].value;
|
||||||
|
SDL_free(action->bindings);
|
||||||
|
}
|
||||||
|
|
||||||
stbds_shfree(input->action_hash);
|
stbds_shfree(input->action_hash);
|
||||||
}
|
}
|
||||||
|
255
src/twn_loop.c
255
src/twn_loop.c
@ -9,6 +9,7 @@
|
|||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <physfs.h>
|
#include <physfs.h>
|
||||||
#include <stb_ds.h>
|
#include <stb_ds.h>
|
||||||
|
#include <toml.h>
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
#ifdef EMSCRIPTEN
|
||||||
#include <GLES2/gl2.h>
|
#include <GLES2/gl2.h>
|
||||||
@ -193,14 +194,78 @@ static bool initialize(void) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* debug mode defaults to being enabled on debug builds. */
|
/* first things first, most things here will be loaded from the config file */
|
||||||
/* pass --debug to enable it on release builds */
|
/* it's expected to be present in the data directory, no matter what */
|
||||||
/* or, on debug builds, pass --release to disable it */
|
/* that is why PhysicsFS is initialized before anything else */
|
||||||
#ifndef NDEBUG
|
toml_set_memutil(SDL_malloc, SDL_free);
|
||||||
|
|
||||||
|
/* load the config file into an opaque table */
|
||||||
|
{
|
||||||
|
char *config_file = file_to_str("/twn.toml");
|
||||||
|
if (config_file == NULL) {
|
||||||
|
CRY_PHYSFS("Configuration file loading failed");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
char errbuf[256]; /* tomlc99 example implies that this is enough... */
|
||||||
|
ctx.config_table = toml_parse(config_file, errbuf, sizeof errbuf);
|
||||||
|
SDL_free(config_file);
|
||||||
|
|
||||||
|
if (ctx.config_table == NULL) {
|
||||||
|
CRY("Configuration file loading failed", errbuf);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* at this point we can save references to the tables within the parent one for later */
|
||||||
|
toml_table_t *about = toml_table_in(ctx.config_table, "about");
|
||||||
|
if (about == NULL) {
|
||||||
|
CRY("Initialization failed", "[about] table expected in configuration file");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_table_t *game = toml_table_in(ctx.config_table, "game");
|
||||||
|
if (game == NULL) {
|
||||||
|
CRY("Initialization failed", "[game] table expected in configuration file");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_table_t *engine = toml_table_in(ctx.config_table, "engine");
|
||||||
|
if (engine == NULL) {
|
||||||
|
CRY("Initialization failed", "[engine] table expected in configuration file");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* configure physicsfs write dir */
|
||||||
|
{
|
||||||
|
toml_datum_t datum_dev_id = toml_string_in(about, "dev_id");
|
||||||
|
if (!datum_dev_id.ok) {
|
||||||
|
CRY("Initialization failed", "Valid about.dev_id expected in configuration file");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
toml_datum_t datum_app_id = toml_string_in(about, "app_id");
|
||||||
|
if (!datum_app_id.ok) {
|
||||||
|
CRY("Initialization failed", "Valid about.app_id expected in configuration file");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PHYSFS_setSaneConfig(datum_dev_id.u.s, datum_app_id.u.s, PACKAGE_EXTENSION, false, true)) {
|
||||||
|
CRY_PHYSFS("Filesystem initialization failed");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_free(datum_dev_id.u.s);
|
||||||
|
SDL_free(datum_app_id.u.s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* debug mode defaults to being enabled */
|
||||||
|
/* pass --debug or --release to force a mode, ignoring configuration */
|
||||||
|
toml_datum_t datum_debug = toml_bool_in(game, "debug");
|
||||||
|
if (!datum_debug.ok) {
|
||||||
ctx.game.debug = true;
|
ctx.game.debug = true;
|
||||||
#else
|
} else {
|
||||||
ctx.game.debug = false;
|
ctx.game.debug = datum_debug.u.b;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
#ifdef EMSCRIPTEN
|
||||||
/* emscripten interpretes those as GL ES version against WebGL */
|
/* emscripten interpretes those as GL ES version against WebGL */
|
||||||
@ -225,14 +290,48 @@ static bool initialize(void) {
|
|||||||
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
|
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
|
||||||
|
|
||||||
/* init got far enough to create a window */
|
/* init got far enough to create a window */
|
||||||
ctx.window = SDL_CreateWindow("townengine",
|
{
|
||||||
|
toml_datum_t datum_title = toml_string_in(about, "title");
|
||||||
|
if (!datum_title.ok) {
|
||||||
|
CRY("Initialization failed", "Valid about.title expected in configuration file");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
/* not yet used
|
||||||
|
toml_datum_t datum_developer = toml_string_in(about, "developer");
|
||||||
|
if (!datum_developer.ok) {
|
||||||
|
CRY("Initialization failed", "Valid about.developer expected in configuration file");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
toml_datum_t datum_base_render_width = toml_int_in(game, "base_render_width");
|
||||||
|
if (!datum_base_render_width.ok) {
|
||||||
|
CRY("Initialization failed", "Valid game.base_render_width expected in configuration file");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
ctx.base_render_width = datum_base_render_width.u.i;
|
||||||
|
ctx.game.base_draw_w = (int)ctx.base_render_width;
|
||||||
|
|
||||||
|
toml_datum_t datum_base_render_height = toml_int_in(game, "base_render_height");
|
||||||
|
if (!datum_base_render_height.ok) {
|
||||||
|
CRY("Initialization failed", "Valid game.base_render_height expected in configuration file");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
ctx.base_render_height = datum_base_render_height.u.i;
|
||||||
|
ctx.game.base_draw_h = (int)ctx.base_render_height;
|
||||||
|
|
||||||
|
ctx.window = SDL_CreateWindow(datum_title.u.s,
|
||||||
SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED,
|
||||||
SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED,
|
||||||
RENDER_BASE_WIDTH,
|
(int)datum_base_render_width.u.i,
|
||||||
RENDER_BASE_HEIGHT,
|
(int)datum_base_render_height.u.i,
|
||||||
// SDL_WINDOW_ALLOW_HIGHDPI |
|
//SDL_WINDOW_ALLOW_HIGHDPI |
|
||||||
SDL_WINDOW_RESIZABLE |
|
SDL_WINDOW_RESIZABLE |
|
||||||
SDL_WINDOW_OPENGL);
|
SDL_WINDOW_OPENGL);
|
||||||
|
|
||||||
|
SDL_free(datum_title.u.s);
|
||||||
|
//SDL_free(datum_developer.u.s);
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx.window == NULL) {
|
if (ctx.window == NULL) {
|
||||||
CRY_SDL("Window creation failed.");
|
CRY_SDL("Window creation failed.");
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -270,12 +369,12 @@ static bool initialize(void) {
|
|||||||
/* might need this to have multiple windows */
|
/* might need this to have multiple windows */
|
||||||
ctx.window_id = SDL_GetWindowID(ctx.window);
|
ctx.window_id = SDL_GetWindowID(ctx.window);
|
||||||
|
|
||||||
glViewport(0, 0, RENDER_BASE_WIDTH, RENDER_BASE_HEIGHT);
|
glViewport(0, 0, ctx.base_render_width, ctx.base_render_height);
|
||||||
|
|
||||||
/* TODO: */
|
/* TODO: */
|
||||||
// SDL_GetRendererOutputSize(ctx.renderer, &ctx.window_w, &ctx.window_h);
|
// SDL_GetRendererOutputSize(ctx.renderer, &ctx.window_w, &ctx.window_h);
|
||||||
ctx.game.window_w = RENDER_BASE_WIDTH;
|
ctx.game.window_w = (int)ctx.base_render_width;
|
||||||
ctx.game.window_h = RENDER_BASE_HEIGHT;
|
ctx.game.window_h = (int)ctx.base_render_height;
|
||||||
|
|
||||||
/* audio initialization */
|
/* audio initialization */
|
||||||
{
|
{
|
||||||
@ -297,15 +396,6 @@ static bool initialize(void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* filesystem time */
|
|
||||||
/* TODO: ANDROID: see the warning in physicsfs PHYSFS_init docs/header */
|
|
||||||
if (!PHYSFS_init(ctx.argv[0]) ||
|
|
||||||
!PHYSFS_setSaneConfig(ORGANIZATION_NAME, APP_NAME, PACKAGE_EXTENSION, false, true))
|
|
||||||
{
|
|
||||||
CRY_PHYSFS("Filesystem initialization failed.");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* you could change this at runtime if you wanted */
|
/* you could change this at runtime if you wanted */
|
||||||
ctx.game.update_multiplicity = 1;
|
ctx.game.update_multiplicity = 1;
|
||||||
|
|
||||||
@ -325,11 +415,22 @@ static bool initialize(void) {
|
|||||||
stbds_rand_seed(ctx.game.random_seed);
|
stbds_rand_seed(ctx.game.random_seed);
|
||||||
|
|
||||||
/* main loop machinery */
|
/* main loop machinery */
|
||||||
|
toml_datum_t datum_ticks_per_second = toml_int_in(engine, "ticks_per_second");
|
||||||
|
if (!datum_ticks_per_second.ok) {
|
||||||
|
ctx.ticks_per_second = TICKS_PER_SECOND_DEFAULT;
|
||||||
|
} else {
|
||||||
|
if (datum_ticks_per_second.u.i < 8) {
|
||||||
|
ctx.ticks_per_second = TICKS_PER_SECOND_DEFAULT;
|
||||||
|
} else {
|
||||||
|
ctx.ticks_per_second = datum_ticks_per_second.u.i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ctx.game.is_running = true;
|
ctx.game.is_running = true;
|
||||||
ctx.resync_flag = true;
|
ctx.resync_flag = true;
|
||||||
ctx.clocks_per_second = SDL_GetPerformanceFrequency();
|
ctx.clocks_per_second = SDL_GetPerformanceFrequency();
|
||||||
ctx.prev_frame_time = SDL_GetPerformanceCounter();
|
ctx.prev_frame_time = SDL_GetPerformanceCounter();
|
||||||
ctx.desired_frametime = ctx.clocks_per_second / TICKS_PER_SECOND;
|
ctx.desired_frametime = ctx.clocks_per_second / ctx.ticks_per_second;
|
||||||
ctx.frame_accumulator = 0;
|
ctx.frame_accumulator = 0;
|
||||||
ctx.game.tick_count = 0;
|
ctx.game.tick_count = 0;
|
||||||
|
|
||||||
@ -340,6 +441,56 @@ static bool initialize(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* rendering */
|
/* rendering */
|
||||||
|
/* configuration */
|
||||||
|
{
|
||||||
|
toml_datum_t datum_texture_atlas_size = toml_int_in(engine, "texture_atlas_size");
|
||||||
|
if (!datum_texture_atlas_size.ok) {
|
||||||
|
ctx.texture_atlas_size = TEXTURE_ATLAS_SIZE_DEFAULT;
|
||||||
|
} else {
|
||||||
|
if (datum_texture_atlas_size.u.i < 32) {
|
||||||
|
ctx.texture_atlas_size = TEXTURE_ATLAS_SIZE_DEFAULT;
|
||||||
|
} else {
|
||||||
|
ctx.texture_atlas_size = datum_texture_atlas_size.u.i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_datum_t datum_font_texture_size = toml_int_in(engine, "font_texture_size");
|
||||||
|
if (!datum_font_texture_size.ok) {
|
||||||
|
ctx.font_texture_size = TEXT_FONT_TEXTURE_SIZE_DEFAULT;
|
||||||
|
} else {
|
||||||
|
if (datum_font_texture_size.u.i < 1024) {
|
||||||
|
ctx.font_texture_size = TEXT_FONT_TEXTURE_SIZE_DEFAULT;
|
||||||
|
} else {
|
||||||
|
ctx.font_texture_size = datum_font_texture_size.u.i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_datum_t datum_font_oversampling = toml_int_in(engine, "font_oversampling");
|
||||||
|
if (!datum_font_oversampling.ok) {
|
||||||
|
ctx.font_oversampling = TEXT_FONT_OVERSAMPLING_DEFAULT;
|
||||||
|
} else {
|
||||||
|
if (datum_font_oversampling.u.i < 0) {
|
||||||
|
ctx.font_oversampling = TEXT_FONT_OVERSAMPLING_DEFAULT;
|
||||||
|
} else {
|
||||||
|
ctx.font_oversampling = datum_font_oversampling.u.i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_datum_t datum_font_filtering = toml_string_in(engine, "font_filtering");
|
||||||
|
if (!datum_font_filtering.ok) {
|
||||||
|
ctx.font_filtering = TEXT_FONT_FILTERING_DEFAULT;
|
||||||
|
} else {
|
||||||
|
if (SDL_strcmp(datum_font_filtering.u.s, "nearest") == 0) {
|
||||||
|
ctx.font_filtering = TEXTURE_FILTER_NEAREAST;
|
||||||
|
} else if (SDL_strcmp(datum_font_filtering.u.s, "linear") == 0) {
|
||||||
|
ctx.font_filtering = TEXTURE_FILTER_LINEAR;
|
||||||
|
} else {
|
||||||
|
ctx.font_filtering = TEXT_FONT_FILTERING_DEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_free(datum_font_filtering.u.s);
|
||||||
|
}
|
||||||
|
|
||||||
/* these are dynamic arrays and will be allocated lazily by stb_ds */
|
/* these are dynamic arrays and will be allocated lazily by stb_ds */
|
||||||
ctx.render_queue_2d = NULL;
|
ctx.render_queue_2d = NULL;
|
||||||
ctx.uncolored_mesh_batches = NULL;
|
ctx.uncolored_mesh_batches = NULL;
|
||||||
@ -348,6 +499,16 @@ static bool initialize(void) {
|
|||||||
text_cache_init(&ctx.text_cache);
|
text_cache_init(&ctx.text_cache);
|
||||||
|
|
||||||
/* input */
|
/* input */
|
||||||
|
toml_datum_t datum_keybind_slots = toml_int_in(engine, "keybind_slots");
|
||||||
|
if (!datum_keybind_slots.ok) {
|
||||||
|
ctx.keybind_slots = KEYBIND_SLOTS_DEFAULT;
|
||||||
|
} else {
|
||||||
|
if (datum_keybind_slots.u.i < 1) {
|
||||||
|
ctx.keybind_slots = KEYBIND_SLOTS_DEFAULT;
|
||||||
|
} else {
|
||||||
|
ctx.keybind_slots = datum_keybind_slots.u.i;
|
||||||
|
}
|
||||||
|
}
|
||||||
input_state_init(&ctx.game.input);
|
input_state_init(&ctx.game.input);
|
||||||
|
|
||||||
/* scripting */
|
/* scripting */
|
||||||
@ -377,6 +538,7 @@ static void clean_up(void) {
|
|||||||
|
|
||||||
arrfree(ctx.render_queue_2d);
|
arrfree(ctx.render_queue_2d);
|
||||||
|
|
||||||
|
toml_free(ctx.config_table);
|
||||||
PHYSFS_deinit();
|
PHYSFS_deinit();
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
@ -392,11 +554,35 @@ int enter_loop(int argc, char **argv) {
|
|||||||
ctx.argc = argc;
|
ctx.argc = argc;
|
||||||
ctx.argv = argv;
|
ctx.argv = argv;
|
||||||
|
|
||||||
|
/* needs to be done before anything else so config can be loaded */
|
||||||
if (!initialize())
|
/* TODO: ANDROID: see the warning in physicsfs PHYSFS_init docs/header */
|
||||||
|
if (!PHYSFS_init(ctx.argv[0]) || !PHYSFS_mount(PHYSFS_getBaseDir(), NULL, true)) {
|
||||||
|
CRY_PHYSFS("Filesystem initialization failed");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
/* base dir is fine, but we'd like to look into all the data archives, too */
|
||||||
|
char **files_here = PHYSFS_enumerateFiles("/");
|
||||||
|
if (files_here == NULL) {
|
||||||
|
CRY_PHYSFS("Filesystem initialization failed");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
for (char **ptr = files_here; *ptr != NULL; ++ptr) {
|
||||||
|
char *file = *ptr;
|
||||||
|
|
||||||
|
if (!strends(file, "." PACKAGE_EXTENSION)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PHYSFS_mount(file, "/", true)) {
|
||||||
|
CRY_PHYSFS("Filesystem initialization failed");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PHYSFS_freeList(files_here);
|
||||||
|
|
||||||
/* process arguments */
|
/* process arguments */
|
||||||
|
bool force_debug = false;
|
||||||
|
bool force_release = false;
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
/* override data directory */
|
/* override data directory */
|
||||||
if (SDL_strcmp(argv[i], "--data-dir") == 0) {
|
if (SDL_strcmp(argv[i], "--data-dir") == 0) {
|
||||||
@ -415,17 +601,29 @@ int enter_loop(int argc, char **argv) {
|
|||||||
|
|
||||||
/* force debug mode */
|
/* force debug mode */
|
||||||
if (SDL_strcmp(argv[i], "--debug") == 0) {
|
if (SDL_strcmp(argv[i], "--debug") == 0) {
|
||||||
ctx.game.debug = true;
|
force_debug = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* force release mode */
|
/* force release mode */
|
||||||
if (SDL_strcmp(argv[i], "--release") == 0) {
|
if (SDL_strcmp(argv[i], "--release") == 0) {
|
||||||
ctx.game.debug = false;
|
force_release = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!initialize())
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
/* good time to override anything that was set in initialize() */
|
||||||
|
if (force_debug) {
|
||||||
|
ctx.game.debug = true;
|
||||||
|
}
|
||||||
|
if (force_release) {
|
||||||
|
ctx.game.debug = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now we can actually start doing stuff */
|
||||||
game_object_load();
|
game_object_load();
|
||||||
|
|
||||||
ctx.was_successful = true;
|
ctx.was_successful = true;
|
||||||
@ -440,6 +638,7 @@ int enter_loop(int argc, char **argv) {
|
|||||||
main_loop();
|
main_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* loop is over */
|
||||||
game_object_unload();
|
game_object_unload();
|
||||||
|
|
||||||
clean_up();
|
clean_up();
|
||||||
|
@ -132,7 +132,7 @@ static SDL_Surface *create_surface(int width, int height) {
|
|||||||
|
|
||||||
/* adds a new, blank atlas surface to the cache */
|
/* adds a new, blank atlas surface to the cache */
|
||||||
static void add_new_atlas(TextureCache *cache) {
|
static void add_new_atlas(TextureCache *cache) {
|
||||||
SDL_Surface *new_atlas = create_surface(TEXTURE_ATLAS_SIZE, TEXTURE_ATLAS_SIZE);
|
SDL_Surface *new_atlas = create_surface((int)ctx.texture_atlas_size, (int)ctx.texture_atlas_size);
|
||||||
arrput(cache->atlas_surfaces, new_atlas);
|
arrput(cache->atlas_surfaces, new_atlas);
|
||||||
arrput(cache->atlas_textures, create_gpu_texture(TEXTURE_FILTER_NEAREAST, true));
|
arrput(cache->atlas_textures, create_gpu_texture(TEXTURE_FILTER_NEAREAST, true));
|
||||||
}
|
}
|
||||||
@ -269,7 +269,7 @@ void textures_cache_init(TextureCache *cache, SDL_Window *window) {
|
|||||||
cache->window = window;
|
cache->window = window;
|
||||||
sh_new_arena(cache->hash);
|
sh_new_arena(cache->hash);
|
||||||
|
|
||||||
cache->node_buffer = SDL_calloc(TEXTURE_ATLAS_SIZE, sizeof *cache->node_buffer);
|
cache->node_buffer = SDL_calloc(ctx.texture_atlas_size, sizeof *cache->node_buffer);
|
||||||
|
|
||||||
add_new_atlas(cache);
|
add_new_atlas(cache);
|
||||||
recreate_current_atlas_texture(cache);
|
recreate_current_atlas_texture(cache);
|
||||||
@ -341,7 +341,7 @@ static TextureKey textures_load(TextureCache *cache, const char *path) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* it's a "loner texture," it doesn't fit in an atlas so it's not in one */
|
/* it's a "loner texture," it doesn't fit in an atlas so it's not in one */
|
||||||
if (surface->w >= TEXTURE_ATLAS_SIZE || surface->h >= TEXTURE_ATLAS_SIZE) {
|
if (surface->w >= ctx.texture_atlas_size || surface->h >= ctx.texture_atlas_size) {
|
||||||
if (ctx.game.debug) {
|
if (ctx.game.debug) {
|
||||||
if (surface->w > 2048 || surface->h > 2048)
|
if (surface->w > 2048 || surface->h > 2048)
|
||||||
log_warn("Unportable texture dimensions for %s, use 2048x2048 at max", path);
|
log_warn("Unportable texture dimensions for %s, use 2048x2048 at max", path);
|
||||||
@ -368,10 +368,10 @@ void textures_update_atlas(TextureCache *cache) {
|
|||||||
/* this function makes a lot more sense if you read stb_rect_pack.h */
|
/* this function makes a lot more sense if you read stb_rect_pack.h */
|
||||||
stbrp_context pack_ctx; /* target info */
|
stbrp_context pack_ctx; /* target info */
|
||||||
stbrp_init_target(&pack_ctx,
|
stbrp_init_target(&pack_ctx,
|
||||||
TEXTURE_ATLAS_SIZE,
|
ctx.texture_atlas_size,
|
||||||
TEXTURE_ATLAS_SIZE,
|
ctx.texture_atlas_size,
|
||||||
cache->node_buffer,
|
cache->node_buffer,
|
||||||
TEXTURE_ATLAS_SIZE);
|
ctx.texture_atlas_size);
|
||||||
|
|
||||||
stbrp_rect *rects = create_rects_from_cache(cache);
|
stbrp_rect *rects = create_rects_from_cache(cache);
|
||||||
|
|
||||||
@ -493,7 +493,7 @@ Rect textures_get_dims(const TextureCache *cache, TextureKey key) {
|
|||||||
if (cache->hash[key.id].value.loner_texture != 0)
|
if (cache->hash[key.id].value.loner_texture != 0)
|
||||||
return cache->hash[key.id].value.srcrect;
|
return cache->hash[key.id].value.srcrect;
|
||||||
else
|
else
|
||||||
return (Rect){ .w = TEXTURE_ATLAS_SIZE, .h = TEXTURE_ATLAS_SIZE };
|
return (Rect){ .w = ctx.texture_atlas_size, .h = ctx.texture_atlas_size };
|
||||||
} else {
|
} else {
|
||||||
CRY("Texture lookup failed.",
|
CRY("Texture lookup failed.",
|
||||||
"Tried to get texture that isn't loaded.");
|
"Tried to get texture that isn't loaded.");
|
||||||
|
14
third-party/tomlc99/.editorconfig
vendored
Normal file
14
third-party/tomlc99/.editorconfig
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = false
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.{c,h}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
38
third-party/tomlc99/.gitignore
vendored
Normal file
38
third-party/tomlc99/.gitignore
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
*~
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
||||||
|
toml_cat
|
||||||
|
toml_json
|
||||||
|
toml_sample
|
||||||
|
|
||||||
|
# Debug files
|
||||||
|
*.dSYM/
|
||||||
|
*.su
|
53
third-party/tomlc99/Makefile
vendored
Normal file
53
third-party/tomlc99/Makefile
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
prefix ?= /usr/local
|
||||||
|
HFILES = toml.h
|
||||||
|
CFILES = toml.c
|
||||||
|
OBJ = $(CFILES:.c=.o)
|
||||||
|
EXEC = toml_json toml_cat toml_sample
|
||||||
|
PCFILE = libtoml.pc
|
||||||
|
|
||||||
|
CFLAGS = -std=c99 -Wall -Wextra -fpic
|
||||||
|
LIB_VERSION = 1.0
|
||||||
|
LIB = libtoml.a
|
||||||
|
LIB_SHARED = libtoml.so.$(LIB_VERSION)
|
||||||
|
|
||||||
|
# to compile for debug: make DEBUG=1
|
||||||
|
# to compile for no debug: make
|
||||||
|
ifdef DEBUG
|
||||||
|
CFLAGS += -O0 -g
|
||||||
|
else
|
||||||
|
CFLAGS += -O2 -DNDEBUG
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
all: $(LIB) $(LIB_SHARED) $(EXEC)
|
||||||
|
|
||||||
|
*.o: $(HFILES)
|
||||||
|
|
||||||
|
libtoml.a: toml.o
|
||||||
|
ar -rcs $@ $^
|
||||||
|
|
||||||
|
libtoml.so.$(LIB_VERSION): toml.o
|
||||||
|
$(CC) -shared -o $@ $^
|
||||||
|
|
||||||
|
$(EXEC): $(LIB)
|
||||||
|
|
||||||
|
install: all
|
||||||
|
install -d ${prefix}/include ${prefix}/lib
|
||||||
|
install toml.h ${prefix}/include
|
||||||
|
install $(LIB) ${prefix}/lib
|
||||||
|
install $(LIB_SHARED) ${prefix}/lib
|
||||||
|
ifeq "$(prefix)" "/usr/local"
|
||||||
|
ifneq ("$(wildcard $(PCFILE))","")
|
||||||
|
install $(PCFILE) /usr/local/lib/pkgconfig
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(EXEC) $(LIB) $(LIB_SHARED)
|
||||||
|
|
||||||
|
|
||||||
|
format:
|
||||||
|
clang-format -i $(shell find . -name '*.[ch]')
|
||||||
|
|
||||||
|
.PHONY: all clean install format
|
194
third-party/tomlc99/README.md
vendored
Normal file
194
third-party/tomlc99/README.md
vendored
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
# tomlc99
|
||||||
|
|
||||||
|
TOML in c99; v1.0 compliant.
|
||||||
|
|
||||||
|
If you are looking for a C++ library, you might try this wrapper: [https://github.com/cktan/tomlcpp](https://github.com/cktan/tomlcpp).
|
||||||
|
|
||||||
|
* Compatible with [TOML v1.0.0](https://toml.io/en/v1.0.0).
|
||||||
|
* Tested with multiple test suites, including
|
||||||
|
[toml-lang/toml-test](https://github.com/toml-lang/toml-test) and
|
||||||
|
[iarna/toml-spec-tests](https://github.com/iarna/toml-spec-tests).
|
||||||
|
* Provides very simple and intuitive interface.
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Please see the `toml.h` file for details. The following is a simple example that
|
||||||
|
parses this config file:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[server]
|
||||||
|
host = "www.example.com"
|
||||||
|
port = [ 8080, 8181, 8282 ]
|
||||||
|
```
|
||||||
|
|
||||||
|
These are the usual steps for getting values from a file:
|
||||||
|
|
||||||
|
1. Parse the TOML file.
|
||||||
|
2. Traverse and locate a table in TOML.
|
||||||
|
3. Extract values from the table.
|
||||||
|
4. Free up allocated memory.
|
||||||
|
|
||||||
|
Below is an example of parsing the values from the example table.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "toml.h"
|
||||||
|
|
||||||
|
static void error(const char* msg, const char* msg1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: %s%s\n", msg, msg1?msg1:"");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
FILE* fp;
|
||||||
|
char errbuf[200];
|
||||||
|
|
||||||
|
// 1. Read and parse toml file
|
||||||
|
fp = fopen("sample.toml", "r");
|
||||||
|
if (!fp) {
|
||||||
|
error("cannot open sample.toml - ", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_table_t* conf = toml_parse_file(fp, errbuf, sizeof(errbuf));
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if (!conf) {
|
||||||
|
error("cannot parse - ", errbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Traverse to a table.
|
||||||
|
toml_table_t* server = toml_table_in(conf, "server");
|
||||||
|
if (!server) {
|
||||||
|
error("missing [server]", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Extract values
|
||||||
|
toml_datum_t host = toml_string_in(server, "host");
|
||||||
|
if (!host.ok) {
|
||||||
|
error("cannot read server.host", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_array_t* portarray = toml_array_in(server, "port");
|
||||||
|
if (!portarray) {
|
||||||
|
error("cannot read server.port", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("host: %s\n", host.u.s);
|
||||||
|
printf("port: ");
|
||||||
|
for (int i = 0; ; i++) {
|
||||||
|
toml_datum_t port = toml_int_at(portarray, i);
|
||||||
|
if (!port.ok) break;
|
||||||
|
printf("%d ", (int)port.u.i);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// 4. Free memory
|
||||||
|
free(host.u.s);
|
||||||
|
toml_free(conf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Accessing Table Content
|
||||||
|
|
||||||
|
TOML tables are dictionaries where lookups are done using string keys. In
|
||||||
|
general, all access functions on tables are named `toml_*_in(...)`.
|
||||||
|
|
||||||
|
In the normal case, you know the key and its content type, and retrievals can be done
|
||||||
|
using one of these functions:
|
||||||
|
```c
|
||||||
|
toml_string_in(tab, key);
|
||||||
|
toml_bool_in(tab, key);
|
||||||
|
toml_int_in(tab, key);
|
||||||
|
toml_double_in(tab, key);
|
||||||
|
toml_timestamp_in(tab, key);
|
||||||
|
toml_table_in(tab, key);
|
||||||
|
toml_array_in(tab, key);
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also interrogate the keys in a table using an integer index:
|
||||||
|
```c
|
||||||
|
toml_table_t* tab = toml_parse_file(...);
|
||||||
|
for (int i = 0; ; i++) {
|
||||||
|
const char* key = toml_key_in(tab, i);
|
||||||
|
if (!key) break;
|
||||||
|
printf("key %d: %s\n", i, key);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Accessing Array Content
|
||||||
|
|
||||||
|
TOML arrays can be deref-ed using integer indices. In general, all access methods on arrays are named `toml_*_at()`.
|
||||||
|
|
||||||
|
To obtain the size of an array:
|
||||||
|
```c
|
||||||
|
int size = toml_array_nelem(arr);
|
||||||
|
```
|
||||||
|
|
||||||
|
To obtain the content of an array, use a valid index and call one of these functions:
|
||||||
|
```c
|
||||||
|
toml_string_at(arr, idx);
|
||||||
|
toml_bool_at(arr, idx);
|
||||||
|
toml_int_at(arr, idx);
|
||||||
|
toml_double_at(arr, idx);
|
||||||
|
toml_timestamp_at(arr, idx);
|
||||||
|
toml_table_at(arr, idx);
|
||||||
|
toml_array_at(arr, idx);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### toml_datum_t
|
||||||
|
|
||||||
|
Some `toml_*_at` and `toml_*_in` functions return a toml_datum_t
|
||||||
|
structure. The `ok` flag in the structure indicates if the function
|
||||||
|
call was successful. If so, you may proceed to read the value
|
||||||
|
corresponding to the type of the content.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
```
|
||||||
|
toml_datum_t host = toml_string_in(tab, "host");
|
||||||
|
if (host.ok) {
|
||||||
|
printf("host: %s\n", host.u.s);
|
||||||
|
free(host.u.s); /* FREE applies to string and timestamp types only */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
** IMPORTANT: if the accessed value is a string or a timestamp, you must call `free(datum.u.s)` or `free(datum.u.ts)` respectively after usage. **
|
||||||
|
|
||||||
|
## Building and installing
|
||||||
|
|
||||||
|
A normal *make* suffices. You can also simply include the
|
||||||
|
`toml.c` and `toml.h` files in your project.
|
||||||
|
|
||||||
|
Invoking `make install` will install the header and library files into
|
||||||
|
/usr/local/{include,lib}.
|
||||||
|
|
||||||
|
Alternatively, specify `make install prefix=/a/file/path` to install into
|
||||||
|
/a/file/path/{include,lib}.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
To test against the standard test set provided by toml-lang/toml-test:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
% make
|
||||||
|
% cd test1
|
||||||
|
% bash build.sh # do this once
|
||||||
|
% bash run.sh # this will run the test suite
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
To test against the standard test set provided by iarna/toml:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
% make
|
||||||
|
% cd test2
|
||||||
|
% bash build.sh # do this once
|
||||||
|
% bash run.sh # this will run the test suite
|
||||||
|
```
|
11
third-party/tomlc99/libtoml.pc.sample
vendored
Normal file
11
third-party/tomlc99/libtoml.pc.sample
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
prefix=/usr/local
|
||||||
|
exec_prefix=${prefix}
|
||||||
|
libdir=${exec_prefix}/lib
|
||||||
|
includedir=${prefix}/include
|
||||||
|
|
||||||
|
Name: libtoml
|
||||||
|
URL: https://github.com/cktan/tomlc99/
|
||||||
|
Description: TOML C library in c99.
|
||||||
|
Version: v1.0
|
||||||
|
Libs: -L${libdir} -ltoml
|
||||||
|
Cflags: -I${includedir}
|
3
third-party/tomlc99/sample.toml
vendored
Normal file
3
third-party/tomlc99/sample.toml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[server]
|
||||||
|
host = "example.com"
|
||||||
|
port = [ 8080, 8181, 8282 ]
|
1
third-party/tomlc99/stdex/.gitignore
vendored
Normal file
1
third-party/tomlc99/stdex/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/*.out
|
15
third-party/tomlc99/stdex/RUN.sh
vendored
Normal file
15
third-party/tomlc99/stdex/RUN.sh
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
rm -f *.out
|
||||||
|
for i in *.toml; do
|
||||||
|
echo -n $i
|
||||||
|
../toml_cat $i >& $i.out
|
||||||
|
if [ -f $i.res ]; then
|
||||||
|
if $(diff $i.out $i.res >& /dev/null); then
|
||||||
|
echo " [OK]"
|
||||||
|
else
|
||||||
|
echo " [FAILED]"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo " [?????]"
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
13
third-party/tomlc99/stdex/arr1.toml
vendored
Normal file
13
third-party/tomlc99/stdex/arr1.toml
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
integers = [ 1, 2, 3 ]
|
||||||
|
colors = [ "red", "yellow", "green" ]
|
||||||
|
nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
|
||||||
|
nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
|
||||||
|
string_array = [ "all", 'strings', """are the same""", '''type''' ]
|
||||||
|
|
||||||
|
# Mixed-type arrays are allowed
|
||||||
|
numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
|
||||||
|
contributors = [
|
||||||
|
"Foo Bar <foo@example.com>",
|
||||||
|
{ name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
|
||||||
|
]
|
||||||
|
|
56
third-party/tomlc99/stdex/arr1.toml.res
vendored
Normal file
56
third-party/tomlc99/stdex/arr1.toml.res
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
integers = [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
colors = [
|
||||||
|
"red",
|
||||||
|
"yellow",
|
||||||
|
"green",
|
||||||
|
],
|
||||||
|
nested_arrays_of_ints = [
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
nested_mixed_array = [
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"a",
|
||||||
|
"b",
|
||||||
|
"c",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
string_array = [
|
||||||
|
"all",
|
||||||
|
"strings",
|
||||||
|
"are the same",
|
||||||
|
"type",
|
||||||
|
],
|
||||||
|
numbers = [
|
||||||
|
0.100000,
|
||||||
|
0.200000,
|
||||||
|
0.500000,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
5,
|
||||||
|
],
|
||||||
|
contributors = [
|
||||||
|
"Foo Bar <foo@example.com>",
|
||||||
|
{
|
||||||
|
name = "Baz Qux",
|
||||||
|
email = "bazqux@example.com",
|
||||||
|
url = "https://example.com/bazqux",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
8
third-party/tomlc99/stdex/arr2.toml
vendored
Normal file
8
third-party/tomlc99/stdex/arr2.toml
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
integers2 = [
|
||||||
|
1, 2, 3
|
||||||
|
]
|
||||||
|
|
||||||
|
integers3 = [
|
||||||
|
1,
|
||||||
|
2, # this is ok
|
||||||
|
]
|
11
third-party/tomlc99/stdex/arr2.toml.res
vendored
Normal file
11
third-party/tomlc99/stdex/arr2.toml.res
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
integers2 = [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
integers3 = [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
}
|
11
third-party/tomlc99/stdex/arrtab1.toml
vendored
Normal file
11
third-party/tomlc99/stdex/arrtab1.toml
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[[products]]
|
||||||
|
name = "Hammer"
|
||||||
|
sku = 738594937
|
||||||
|
|
||||||
|
[[products]] # empty table within the array
|
||||||
|
|
||||||
|
[[products]]
|
||||||
|
name = "Nail"
|
||||||
|
sku = 284758393
|
||||||
|
|
||||||
|
color = "gray"
|
15
third-party/tomlc99/stdex/arrtab1.toml.res
vendored
Normal file
15
third-party/tomlc99/stdex/arrtab1.toml.res
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
products = [
|
||||||
|
{
|
||||||
|
name = "Hammer",
|
||||||
|
sku = 738594937,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "Nail",
|
||||||
|
sku = 284758393,
|
||||||
|
color = "gray",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
19
third-party/tomlc99/stdex/arrtab2.toml
vendored
Normal file
19
third-party/tomlc99/stdex/arrtab2.toml
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
[[fruits]]
|
||||||
|
name = "apple"
|
||||||
|
|
||||||
|
[fruits.physical] # subtable
|
||||||
|
color = "red"
|
||||||
|
shape = "round"
|
||||||
|
|
||||||
|
[[fruits.varieties]] # nested array of tables
|
||||||
|
name = "red delicious"
|
||||||
|
|
||||||
|
[[fruits.varieties]]
|
||||||
|
name = "granny smith"
|
||||||
|
|
||||||
|
|
||||||
|
[[fruits]]
|
||||||
|
name = "banana"
|
||||||
|
|
||||||
|
[[fruits.varieties]]
|
||||||
|
name = "plantain"
|
27
third-party/tomlc99/stdex/arrtab2.toml.res
vendored
Normal file
27
third-party/tomlc99/stdex/arrtab2.toml.res
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
fruits = [
|
||||||
|
{
|
||||||
|
name = "apple",
|
||||||
|
varieties = [
|
||||||
|
{
|
||||||
|
name = "red delicious",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "granny smith",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
physical = {
|
||||||
|
color = "red",
|
||||||
|
shape = "round",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "banana",
|
||||||
|
varieties = [
|
||||||
|
{
|
||||||
|
name = "plantain",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
8
third-party/tomlc99/stdex/arrtab3.toml
vendored
Normal file
8
third-party/tomlc99/stdex/arrtab3.toml
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# INVALID TOML DOC
|
||||||
|
[fruit.physical] # subtable, but to which parent element should it belong?
|
||||||
|
color = "red"
|
||||||
|
shape = "round"
|
||||||
|
|
||||||
|
[[fruit]] # parser must throw an error upon discovering that "fruit" is
|
||||||
|
# an array rather than a table
|
||||||
|
name = "apple"
|
1
third-party/tomlc99/stdex/arrtab3.toml.res
vendored
Normal file
1
third-party/tomlc99/stdex/arrtab3.toml.res
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ERROR: line 6: key exists
|
4
third-party/tomlc99/stdex/arrtab4.toml
vendored
Normal file
4
third-party/tomlc99/stdex/arrtab4.toml
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# INVALID TOML DOC
|
||||||
|
fruits = []
|
||||||
|
|
||||||
|
[[fruits]] # Not allowed
|
1
third-party/tomlc99/stdex/arrtab4.toml.res
vendored
Normal file
1
third-party/tomlc99/stdex/arrtab4.toml.res
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ERROR: line 4: array mismatch
|
11
third-party/tomlc99/stdex/arrtab5.toml
vendored
Normal file
11
third-party/tomlc99/stdex/arrtab5.toml
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# INVALID TOML DOC
|
||||||
|
[[fruits]]
|
||||||
|
name = "apple"
|
||||||
|
|
||||||
|
[[fruits.varieties]]
|
||||||
|
name = "red delicious"
|
||||||
|
|
||||||
|
# INVALID: This table conflicts with the previous array of tables
|
||||||
|
[fruits.varieties]
|
||||||
|
name = "granny smith"
|
||||||
|
|
1
third-party/tomlc99/stdex/arrtab5.toml.res
vendored
Normal file
1
third-party/tomlc99/stdex/arrtab5.toml.res
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ERROR: line 9: key exists
|
14
third-party/tomlc99/stdex/arrtab6.toml
vendored
Normal file
14
third-party/tomlc99/stdex/arrtab6.toml
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# INVALID TOML DOC
|
||||||
|
[[fruits]]
|
||||||
|
name = "apple"
|
||||||
|
|
||||||
|
[[fruits.varieties]]
|
||||||
|
name = "red delicious"
|
||||||
|
|
||||||
|
[fruits.physical]
|
||||||
|
color = "red"
|
||||||
|
shape = "round"
|
||||||
|
|
||||||
|
# INVALID: This array of tables conflicts with the previous table
|
||||||
|
[[fruits.physical]]
|
||||||
|
color = "green"
|
1
third-party/tomlc99/stdex/arrtab6.toml.res
vendored
Normal file
1
third-party/tomlc99/stdex/arrtab6.toml.res
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ERROR: line 13: key exists
|
3
third-party/tomlc99/stdex/arrtab7.toml
vendored
Normal file
3
third-party/tomlc99/stdex/arrtab7.toml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
points = [ { x = 1, y = 2, z = 3 },
|
||||||
|
{ x = 7, y = 8, z = 9 },
|
||||||
|
{ x = 2, y = 4, z = 8 } ]
|
19
third-party/tomlc99/stdex/arrtab7.toml.res
vendored
Normal file
19
third-party/tomlc99/stdex/arrtab7.toml.res
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
points = [
|
||||||
|
{
|
||||||
|
x = 1,
|
||||||
|
y = 2,
|
||||||
|
z = 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
x = 7,
|
||||||
|
y = 8,
|
||||||
|
z = 9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
x = 2,
|
||||||
|
y = 4,
|
||||||
|
z = 8,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
3
third-party/tomlc99/stdex/bool1.toml
vendored
Normal file
3
third-party/tomlc99/stdex/bool1.toml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
bool1 = true
|
||||||
|
bool2 = false
|
||||||
|
|
4
third-party/tomlc99/stdex/bool1.toml.res
vendored
Normal file
4
third-party/tomlc99/stdex/bool1.toml.res
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
bool1 = true,
|
||||||
|
bool2 = false,
|
||||||
|
}
|
3
third-party/tomlc99/stdex/comment.toml
vendored
Normal file
3
third-party/tomlc99/stdex/comment.toml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This is a full-line comment
|
||||||
|
key = "value" # This is a comment at the end of a line
|
||||||
|
another = "# This is not a comment"
|
4
third-party/tomlc99/stdex/comment.toml.res
vendored
Normal file
4
third-party/tomlc99/stdex/comment.toml.res
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
key = "value",
|
||||||
|
another = "# This is not a comment",
|
||||||
|
}
|
13
third-party/tomlc99/stdex/float1.toml
vendored
Normal file
13
third-party/tomlc99/stdex/float1.toml
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# fractional
|
||||||
|
flt1 = +1.0
|
||||||
|
flt2 = 3.1415
|
||||||
|
flt3 = -0.01
|
||||||
|
|
||||||
|
# exponent
|
||||||
|
flt4 = 5e+22
|
||||||
|
flt5 = 1e06
|
||||||
|
flt6 = -2E-2
|
||||||
|
|
||||||
|
# both
|
||||||
|
flt7 = 6.626e-34
|
||||||
|
|
9
third-party/tomlc99/stdex/float1.toml.res
vendored
Normal file
9
third-party/tomlc99/stdex/float1.toml.res
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
flt1 = 1.000000,
|
||||||
|
flt2 = 3.141500,
|
||||||
|
flt3 = -0.010000,
|
||||||
|
flt4 = 49999999999999995805696.000000,
|
||||||
|
flt5 = 1000000.000000,
|
||||||
|
flt6 = -0.020000,
|
||||||
|
flt7 = 0.000000,
|
||||||
|
}
|
1
third-party/tomlc99/stdex/float2.toml
vendored
Normal file
1
third-party/tomlc99/stdex/float2.toml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
invalid_float_1 = .7
|
2
third-party/tomlc99/stdex/float2.toml.res
vendored
Normal file
2
third-party/tomlc99/stdex/float2.toml.res
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{
|
||||||
|
ERROR: unable to decode value in table
|
2
third-party/tomlc99/stdex/float3.toml
vendored
Normal file
2
third-party/tomlc99/stdex/float3.toml
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
invalid_float_2 = 7.
|
||||||
|
|
2
third-party/tomlc99/stdex/float3.toml.res
vendored
Normal file
2
third-party/tomlc99/stdex/float3.toml.res
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{
|
||||||
|
ERROR: unable to decode value in table
|
1
third-party/tomlc99/stdex/float4.toml
vendored
Normal file
1
third-party/tomlc99/stdex/float4.toml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
invalid_float_3 = 3.e+20
|
2
third-party/tomlc99/stdex/float4.toml.res
vendored
Normal file
2
third-party/tomlc99/stdex/float4.toml.res
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{
|
||||||
|
ERROR: unable to decode value in table
|
1
third-party/tomlc99/stdex/float5.toml
vendored
Normal file
1
third-party/tomlc99/stdex/float5.toml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
flt8 = 224_617.445_991_228
|
3
third-party/tomlc99/stdex/float5.toml.res
vendored
Normal file
3
third-party/tomlc99/stdex/float5.toml.res
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
flt8 = 224617.445991,
|
||||||
|
}
|
10
third-party/tomlc99/stdex/float6.toml
vendored
Normal file
10
third-party/tomlc99/stdex/float6.toml
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# infinity
|
||||||
|
sf1 = inf # positive infinity
|
||||||
|
sf2 = +inf # positive infinity
|
||||||
|
sf3 = -inf # negative infinity
|
||||||
|
|
||||||
|
# not a number
|
||||||
|
sf4 = nan # actual sNaN/qNaN encoding is implementation-specific
|
||||||
|
sf5 = +nan # same as `nan`
|
||||||
|
sf6 = -nan # valid, actual encoding is implementation-specific
|
||||||
|
|
8
third-party/tomlc99/stdex/float6.toml.res
vendored
Normal file
8
third-party/tomlc99/stdex/float6.toml.res
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
sf1 = inf,
|
||||||
|
sf2 = inf,
|
||||||
|
sf3 = -inf,
|
||||||
|
sf4 = nan,
|
||||||
|
sf5 = nan,
|
||||||
|
sf6 = nan,
|
||||||
|
}
|
3
third-party/tomlc99/stdex/inlinetab1.toml
vendored
Normal file
3
third-party/tomlc99/stdex/inlinetab1.toml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
name = { first = "Tom", last = "Preston-Werner" }
|
||||||
|
point = { x = 1, y = 2 }
|
||||||
|
animal = { type.name = "pug" }
|
15
third-party/tomlc99/stdex/inlinetab1.toml.res
vendored
Normal file
15
third-party/tomlc99/stdex/inlinetab1.toml.res
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
name = {
|
||||||
|
first = "Tom",
|
||||||
|
last = "Preston-Werner",
|
||||||
|
},
|
||||||
|
point = {
|
||||||
|
x = 1,
|
||||||
|
y = 2,
|
||||||
|
},
|
||||||
|
animal = {
|
||||||
|
type = {
|
||||||
|
name = "pug",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
3
third-party/tomlc99/stdex/inlinetab2.toml
vendored
Normal file
3
third-party/tomlc99/stdex/inlinetab2.toml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[product]
|
||||||
|
type = { name = "Nail" }
|
||||||
|
type.edible = false # INVALID
|
1
third-party/tomlc99/stdex/inlinetab2.toml.res
vendored
Normal file
1
third-party/tomlc99/stdex/inlinetab2.toml.res
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ERROR: line 3: cannot insert new entry into existing table
|
3
third-party/tomlc99/stdex/inlinetab3.toml
vendored
Normal file
3
third-party/tomlc99/stdex/inlinetab3.toml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[product]
|
||||||
|
type.name = "Nail"
|
||||||
|
type = { edible = false } # INVALID
|
1
third-party/tomlc99/stdex/inlinetab3.toml.res
vendored
Normal file
1
third-party/tomlc99/stdex/inlinetab3.toml.res
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ERROR: line 3: key exists
|
9
third-party/tomlc99/stdex/int0.toml
vendored
Normal file
9
third-party/tomlc99/stdex/int0.toml
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
int1 = +99
|
||||||
|
int2 = 42
|
||||||
|
int3 = 0
|
||||||
|
int4 = -17
|
||||||
|
int5 = 1_000
|
||||||
|
int6 = 5_349_221
|
||||||
|
int7 = 53_49_221 # Indian number system grouping
|
||||||
|
int8 = 1_2_3_4_5 # VALID but discouraged
|
||||||
|
|
10
third-party/tomlc99/stdex/int0.toml.res
vendored
Normal file
10
third-party/tomlc99/stdex/int0.toml.res
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
int1 = 99,
|
||||||
|
int2 = 42,
|
||||||
|
int3 = 0,
|
||||||
|
int4 = -17,
|
||||||
|
int5 = 1000,
|
||||||
|
int6 = 5349221,
|
||||||
|
int7 = 5349221,
|
||||||
|
int8 = 12345,
|
||||||
|
}
|
12
third-party/tomlc99/stdex/int1.toml
vendored
Normal file
12
third-party/tomlc99/stdex/int1.toml
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# hexadecimal with prefix `0x`
|
||||||
|
hex1 = 0xDEADBEEF
|
||||||
|
hex2 = 0xdeadbeef
|
||||||
|
hex3 = 0xdead_beef
|
||||||
|
|
||||||
|
# octal with prefix `0o`
|
||||||
|
oct1 = 0o01234567
|
||||||
|
oct2 = 0o755 # useful for Unix file permissions
|
||||||
|
|
||||||
|
# binary with prefix `0b`
|
||||||
|
bin1 = 0b11010110
|
||||||
|
|
8
third-party/tomlc99/stdex/int1.toml.res
vendored
Normal file
8
third-party/tomlc99/stdex/int1.toml.res
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
hex1 = 3735928559,
|
||||||
|
hex2 = 3735928559,
|
||||||
|
hex3 = 3735928559,
|
||||||
|
oct1 = 342391,
|
||||||
|
oct2 = 493,
|
||||||
|
bin1 = 214,
|
||||||
|
}
|
4
third-party/tomlc99/stdex/keys00.toml
vendored
Normal file
4
third-party/tomlc99/stdex/keys00.toml
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
key = "value"
|
||||||
|
bare_key = "value"
|
||||||
|
bare-key = "value"
|
||||||
|
1234 = "value"
|
6
third-party/tomlc99/stdex/keys00.toml.res
vendored
Normal file
6
third-party/tomlc99/stdex/keys00.toml.res
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
key = "value",
|
||||||
|
bare_key = "value",
|
||||||
|
bare-key = "value",
|
||||||
|
1234 = "value",
|
||||||
|
}
|
5
third-party/tomlc99/stdex/keys01.toml
vendored
Normal file
5
third-party/tomlc99/stdex/keys01.toml
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
"127.0.0.1" = "value"
|
||||||
|
"character encoding" = "value"
|
||||||
|
"ʎǝʞ" = "value"
|
||||||
|
'key2' = "value"
|
||||||
|
'quoted "value"' = "value"
|
7
third-party/tomlc99/stdex/keys01.toml.res
vendored
Normal file
7
third-party/tomlc99/stdex/keys01.toml.res
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
127.0.0.1 = "value",
|
||||||
|
character encoding = "value",
|
||||||
|
ʎǝʞ = "value",
|
||||||
|
key2 = "value",
|
||||||
|
quoted "value" = "value",
|
||||||
|
}
|
1
third-party/tomlc99/stdex/keys02.toml
vendored
Normal file
1
third-party/tomlc99/stdex/keys02.toml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
= "no key name" # INVALID
|
1
third-party/tomlc99/stdex/keys02.toml.res
vendored
Normal file
1
third-party/tomlc99/stdex/keys02.toml.res
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ERROR: line 1: syntax error
|
1
third-party/tomlc99/stdex/keys03.toml
vendored
Normal file
1
third-party/tomlc99/stdex/keys03.toml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
"" = "blank" # VALID but discouraged
|
3
third-party/tomlc99/stdex/keys03.toml.res
vendored
Normal file
3
third-party/tomlc99/stdex/keys03.toml.res
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
= "blank",
|
||||||
|
}
|
4
third-party/tomlc99/stdex/keys04.toml
vendored
Normal file
4
third-party/tomlc99/stdex/keys04.toml
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
name = "Orange"
|
||||||
|
physical.color = "orange"
|
||||||
|
physical.shape = "round"
|
||||||
|
site."google.com" = true
|
10
third-party/tomlc99/stdex/keys04.toml.res
vendored
Normal file
10
third-party/tomlc99/stdex/keys04.toml.res
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
name = "Orange",
|
||||||
|
physical = {
|
||||||
|
color = "orange",
|
||||||
|
shape = "round",
|
||||||
|
},
|
||||||
|
site = {
|
||||||
|
google.com = true,
|
||||||
|
},
|
||||||
|
}
|
3
third-party/tomlc99/stdex/keys05.toml
vendored
Normal file
3
third-party/tomlc99/stdex/keys05.toml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fruit.name = "banana" # this is best practice
|
||||||
|
fruit. color = "yellow" # same as fruit.color
|
||||||
|
fruit . flavor = "banana" # same as fruit.flavor
|
7
third-party/tomlc99/stdex/keys05.toml.res
vendored
Normal file
7
third-party/tomlc99/stdex/keys05.toml.res
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
fruit = {
|
||||||
|
name = "banana",
|
||||||
|
color = "yellow",
|
||||||
|
flavor = "banana",
|
||||||
|
},
|
||||||
|
}
|
3
third-party/tomlc99/stdex/keys06.toml
vendored
Normal file
3
third-party/tomlc99/stdex/keys06.toml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# DO NOT DO THIS
|
||||||
|
name = "Tom"
|
||||||
|
name = "Pradyun"
|
1
third-party/tomlc99/stdex/keys06.toml.res
vendored
Normal file
1
third-party/tomlc99/stdex/keys06.toml.res
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ERROR: line 3: key exists
|
3
third-party/tomlc99/stdex/keys07.toml
vendored
Normal file
3
third-party/tomlc99/stdex/keys07.toml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# THIS WILL NOT WORK
|
||||||
|
spelling = "favorite"
|
||||||
|
"spelling" = "favourite"
|
1
third-party/tomlc99/stdex/keys07.toml.res
vendored
Normal file
1
third-party/tomlc99/stdex/keys07.toml.res
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ERROR: line 3: key exists
|
5
third-party/tomlc99/stdex/keys08.toml
vendored
Normal file
5
third-party/tomlc99/stdex/keys08.toml
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# This makes the key "fruit" into a table.
|
||||||
|
fruit.apple.smooth = true
|
||||||
|
|
||||||
|
# So then you can add to the table "fruit" like so:
|
||||||
|
fruit.orange = 2
|
8
third-party/tomlc99/stdex/keys08.toml.res
vendored
Normal file
8
third-party/tomlc99/stdex/keys08.toml.res
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
fruit = {
|
||||||
|
orange = 2,
|
||||||
|
apple = {
|
||||||
|
smooth = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
8
third-party/tomlc99/stdex/keys09.toml
vendored
Normal file
8
third-party/tomlc99/stdex/keys09.toml
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# THE FOLLOWING IS INVALID
|
||||||
|
|
||||||
|
# This defines the value of fruit.apple to be an integer.
|
||||||
|
fruit.apple = 1
|
||||||
|
|
||||||
|
# But then this treats fruit.apple like it's a table.
|
||||||
|
# You can't turn an integer into a table.
|
||||||
|
fruit.apple.smooth = true
|
1
third-party/tomlc99/stdex/keys09.toml.res
vendored
Normal file
1
third-party/tomlc99/stdex/keys09.toml.res
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ERROR: line 8: key exists
|
10
third-party/tomlc99/stdex/keys10.toml
vendored
Normal file
10
third-party/tomlc99/stdex/keys10.toml
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# VALID BUT DISCOURAGED
|
||||||
|
|
||||||
|
apple.type = "fruit"
|
||||||
|
orange.type = "fruit"
|
||||||
|
|
||||||
|
apple.skin = "thin"
|
||||||
|
orange.skin = "thick"
|
||||||
|
|
||||||
|
apple.color = "red"
|
||||||
|
orange.color = "orange"
|
12
third-party/tomlc99/stdex/keys10.toml.res
vendored
Normal file
12
third-party/tomlc99/stdex/keys10.toml.res
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
apple = {
|
||||||
|
type = "fruit",
|
||||||
|
skin = "thin",
|
||||||
|
color = "red",
|
||||||
|
},
|
||||||
|
orange = {
|
||||||
|
type = "fruit",
|
||||||
|
skin = "thick",
|
||||||
|
color = "orange",
|
||||||
|
},
|
||||||
|
}
|
9
third-party/tomlc99/stdex/keys11.toml
vendored
Normal file
9
third-party/tomlc99/stdex/keys11.toml
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# RECOMMENDED
|
||||||
|
|
||||||
|
apple.type = "fruit"
|
||||||
|
apple.skin = "thin"
|
||||||
|
apple.color = "red"
|
||||||
|
|
||||||
|
orange.type = "fruit"
|
||||||
|
orange.skin = "thick"
|
||||||
|
orange.color = "orange"
|
12
third-party/tomlc99/stdex/keys11.toml.res
vendored
Normal file
12
third-party/tomlc99/stdex/keys11.toml.res
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
apple = {
|
||||||
|
type = "fruit",
|
||||||
|
skin = "thin",
|
||||||
|
color = "red",
|
||||||
|
},
|
||||||
|
orange = {
|
||||||
|
type = "fruit",
|
||||||
|
skin = "thick",
|
||||||
|
color = "orange",
|
||||||
|
},
|
||||||
|
}
|
1
third-party/tomlc99/stdex/keys12.toml
vendored
Normal file
1
third-party/tomlc99/stdex/keys12.toml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
3.14159 = "pi"
|
5
third-party/tomlc99/stdex/keys12.toml.res
vendored
Normal file
5
third-party/tomlc99/stdex/keys12.toml.res
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
3 = {
|
||||||
|
14159 = "pi",
|
||||||
|
},
|
||||||
|
}
|
1
third-party/tomlc99/stdex/kvpair0.toml
vendored
Normal file
1
third-party/tomlc99/stdex/kvpair0.toml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
key = "value"
|
3
third-party/tomlc99/stdex/kvpair0.toml.res
vendored
Normal file
3
third-party/tomlc99/stdex/kvpair0.toml.res
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
key = "value",
|
||||||
|
}
|
1
third-party/tomlc99/stdex/kvpair1.toml
vendored
Normal file
1
third-party/tomlc99/stdex/kvpair1.toml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
key = # INVALID
|
1
third-party/tomlc99/stdex/kvpair1.toml.res
vendored
Normal file
1
third-party/tomlc99/stdex/kvpair1.toml.res
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ERROR: line 1: syntax error
|
1
third-party/tomlc99/stdex/kvpair2.toml
vendored
Normal file
1
third-party/tomlc99/stdex/kvpair2.toml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
first = "Tom" last = "Preston-Werner" # INVALID
|
1
third-party/tomlc99/stdex/kvpair2.toml.res
vendored
Normal file
1
third-party/tomlc99/stdex/kvpair2.toml.res
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ERROR: line 1: extra chars after value
|
1
third-party/tomlc99/stdex/string0.toml
vendored
Normal file
1
third-party/tomlc99/stdex/string0.toml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user