forked from mirrors/principia
Merge in featured-list-creator into utils/
Originally a C program (previously Python script) at https://github.com/principia-game/featured-list-creator for creating fl.cache files for the community site, merge into the main repository so it is with all the other util programs.
This commit is contained in:
parent
f564ba2e3f
commit
66923575b4
6 changed files with 170 additions and 1 deletions
5
.github/workflows/build_utils.yml
vendored
5
.github/workflows/build_utils.yml
vendored
|
|
@ -16,6 +16,11 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libjansson-dev
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
cd utils
|
cd utils
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
SUBDIRS := lvl-icon-extractor lvlbuf-decompressor lvledit progress-get
|
SUBDIRS := featured-list-creator lvl-icon-extractor lvlbuf-decompressor lvledit progress-get
|
||||||
|
|
||||||
.PHONY: all clean $(SUBDIRS)
|
.PHONY: all clean $(SUBDIRS)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ This directory contains utility scripts and programs used for Principia developm
|
||||||
## Programs
|
## Programs
|
||||||
Most of these programs rely on source files from the main Principia codebase and need to be compiled to run. Likely only works on Linux. You can use the `Makefile` in each directory or run `make` in the `utils` directory to build all of them.
|
Most of these programs rely on source files from the main Principia codebase and need to be compiled to run. Likely only works on Linux. You can use the `Makefile` in each directory or run `make` in the `utils` directory to build all of them.
|
||||||
|
|
||||||
|
- `featured-list-creator`: Generate a `fl.cache` file for use on the Principia community site
|
||||||
- `lvl-icon-extractor`: Extract the embedded level icon in a Principia level file
|
- `lvl-icon-extractor`: Extract the embedded level icon in a Principia level file
|
||||||
- `lvlbuf-decompressor`: Decompress the level buffer of a Principia level file
|
- `lvlbuf-decompressor`: Decompress the level buffer of a Principia level file
|
||||||
- `lvledit`: Edit metadata of Principia level files
|
- `lvledit`: Edit metadata of Principia level files
|
||||||
|
|
|
||||||
27
utils/featured-list-creator/Makefile
Normal file
27
utils/featured-list-creator/Makefile
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
BIN = ../bin
|
||||||
|
PRINCIPIA = ../..
|
||||||
|
PROGRAM = featured-list-creator
|
||||||
|
SRCS := main.c
|
||||||
|
|
||||||
|
# always static unless you do STATIC=0
|
||||||
|
STATIC ?= 1
|
||||||
|
|
||||||
|
CC ?= gcc
|
||||||
|
CFLAGS ?= -O2 -ffunction-sections -fdata-sections
|
||||||
|
LDFLAGS ?= -Wl,--gc-sections
|
||||||
|
ifeq ($(STATIC),1)
|
||||||
|
LDFLAGS += -l:libjansson.a
|
||||||
|
else
|
||||||
|
LDFLAGS += -ljansson
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: $(BIN)/$(PROGRAM)
|
||||||
|
|
||||||
|
$(BIN)/$(PROGRAM): $(SRCS)
|
||||||
|
@mkdir -p $(BIN)
|
||||||
|
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm $(BIN)/$(PROGRAM)
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
38
utils/featured-list-creator/README.md
Executable file
38
utils/featured-list-creator/README.md
Executable file
|
|
@ -0,0 +1,38 @@
|
||||||
|
# Featured List Creator
|
||||||
|
This is a C program that generates a featured list file (`fl.cache`) from JSON data and images, which is served by the Principia community site to display featured levels and getting started links in the main menu.
|
||||||
|
|
||||||
|
The program requires the jansson library for JSON parsing, and will attempt to statically link against it by default. You can do `make STATIC=0` to link dynamically instead.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
There are two optional arguments for specifying the input JSON file and output `fl.cache` file. The default values are below:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./featured-list-creator data/data.json fl.cache
|
||||||
|
```
|
||||||
|
|
||||||
|
## Format
|
||||||
|
The format of the input JSON file is as follows:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"featured_levels": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "Name",
|
||||||
|
"author": "Author",
|
||||||
|
"jpeg_image": "level_thumbnail.jpg"
|
||||||
|
}
|
||||||
|
[...]
|
||||||
|
],
|
||||||
|
|
||||||
|
"gettingstarted_list": [
|
||||||
|
{
|
||||||
|
"name": "Link 1",
|
||||||
|
"link": "https://example.org"
|
||||||
|
}
|
||||||
|
[...]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The paths to the JPEG images are relative to the current working directory when running the program.
|
||||||
98
utils/featured-list-creator/main.c
Normal file
98
utils/featured-list-creator/main.c
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <jansson.h>
|
||||||
|
|
||||||
|
void write_u32(FILE *f, uint32_t value) {
|
||||||
|
fwrite(&value, sizeof(uint32_t), 1, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(FILE *f, const char* value) {
|
||||||
|
fwrite(value, 1, strlen(value), f);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_JSON_INTEGER(obj, key) json_integer_value(json_object_get((obj), (key)))
|
||||||
|
#define GET_JSON_STRING(obj, key) json_string_value(json_object_get((obj), (key)))
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc < 3) {
|
||||||
|
printf("Usage: %s [data.json] [fl.cache]\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *input_filename = argv[1];
|
||||||
|
const char *output_filename = argv[2];
|
||||||
|
|
||||||
|
json_t *root; json_error_t error;
|
||||||
|
root = json_load_file(input_filename, 0, &error);
|
||||||
|
if (!root) {
|
||||||
|
printf("Error loading JSON file: %s\n", error.text);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_t *featured_levels = json_object_get(root, "featured_levels");
|
||||||
|
json_t *gettingstarted_list = json_object_get(root, "gettingstarted_list");
|
||||||
|
|
||||||
|
if (json_array_size(featured_levels) > 4 || json_array_size(gettingstarted_list) > 12)
|
||||||
|
printf("Array lengths are likely too large for Principia, but carry on.\n");
|
||||||
|
|
||||||
|
FILE *f = fopen(output_filename, "wb+");
|
||||||
|
if (!f) {
|
||||||
|
printf("Error opening output file\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t index;
|
||||||
|
json_t *feat_level, *gettingstarted;
|
||||||
|
|
||||||
|
write_u32(f, json_array_size(featured_levels)); // featured_level_count
|
||||||
|
json_array_foreach(featured_levels, index, feat_level) {
|
||||||
|
uint32_t id = GET_JSON_INTEGER(feat_level, "id");
|
||||||
|
const char *name = GET_JSON_STRING(feat_level, "name");
|
||||||
|
const char *author = GET_JSON_STRING(feat_level, "author");
|
||||||
|
const char *jpeg_image_path = GET_JSON_STRING(feat_level, "jpeg_image");
|
||||||
|
|
||||||
|
FILE *jpeg_file = fopen(jpeg_image_path, "rb");
|
||||||
|
if (!jpeg_file) {
|
||||||
|
printf("Error opening JPEG image file %s\n", jpeg_image_path);
|
||||||
|
fclose(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(jpeg_file, 0, SEEK_END);
|
||||||
|
long jpeg_size = ftell(jpeg_file);
|
||||||
|
fseek(jpeg_file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
unsigned char *jpeg_stream = malloc(jpeg_size);
|
||||||
|
fread(jpeg_stream, 1, jpeg_size, jpeg_file);
|
||||||
|
fclose(jpeg_file);
|
||||||
|
|
||||||
|
write_u32(f, id); // fl_id
|
||||||
|
write_u32(f, strlen(name)); // fl_name_size
|
||||||
|
write(f, name); // fl_name
|
||||||
|
write_u32(f, strlen(author)); // fl_author_size
|
||||||
|
write(f, author); // fl_author
|
||||||
|
write_u32(f, jpeg_size); // fl_jpegstream_size
|
||||||
|
fwrite(jpeg_stream, 1, jpeg_size, f); // fl_jpegstream
|
||||||
|
|
||||||
|
free(jpeg_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_u32(f, 0); // Number of contests (unused and slightly broken)
|
||||||
|
|
||||||
|
write_u32(f, json_array_size(gettingstarted_list)); // gettingstarted_list_count
|
||||||
|
json_array_foreach(gettingstarted_list, index, gettingstarted) {
|
||||||
|
const char *name = GET_JSON_STRING(gettingstarted, "name");
|
||||||
|
const char *link = GET_JSON_STRING(gettingstarted, "link");
|
||||||
|
|
||||||
|
write_u32(f, strlen(name)); // gs_name_size
|
||||||
|
write(f, name); // gs_name
|
||||||
|
write_u32(f, strlen(link)); // gs_link_size
|
||||||
|
write(f, link); // gs_link
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue