Replace compile time determined options with a struct

This will allow to change these values at launch, or even runtime.
This commit is contained in:
KikooDX 2021-03-26 13:54:38 +01:00
parent 22d55942a8
commit 7f0b593498
13 changed files with 220 additions and 108 deletions

View File

@ -6,6 +6,7 @@ include_directories(include)
set(SOURCES
src/main.c
src/options.c
src/mouse.c
src/editing_area/main.c
src/editing_area/level.c

View File

@ -4,27 +4,24 @@
#include <raylib.h> /* for the color struct */
#define TILE_WIDTH 16 /* in pixels */
#define TILE_WIDTH 16
#define TILE_HEIGHT 16
#define TILESET_WIDTH 16 /* in tiles */
#define TILESET_HEIGHT 16
#define TILESET_MIN_WIDTH_PX (TILE_WIDTH * TILESET_WIDTH)
#define TILESET_MIN_HEIGHT_PX (TILE_HEIGHT * TILESET_HEIGHT)
static const int editor_target_fps = 60;
static const int picker_target_fps = 30;
static const Color unselected_tile_color = {80, 80, 80, 255};
static const Color overring_tile_color = {255, 255, 255, 80};
#define UNSELECTED_TILE_COLOR \
(Color) { 80, 80, 80, 255 }
#define OVERRING_TILE_COLOR \
(Color) { 255, 255, 255, 80 }
#define EDITOR_SCALE 1 /* don't change this yet! */
static const int editor_window_width = 396 * EDITOR_SCALE;
static const int editor_window_height = 224 * EDITOR_SCALE;
static const int draw_offset_x = -2 * EDITOR_SCALE;
static const int draw_offset_y = -8 * EDITOR_SCALE;
#define EDITOR_WINDOW_WIDTH 396
#define EDITOR_WINDOW_HEIGHT 224
#define EDITOR_TARGET_FPS 60
#define EDITOR_DRAW_OFFSET_X -2
#define EDITOR_DRAW_OFFSET_Y -8
#define PICKER_SCALE 1 /* don't change this yet! */
#define PICKER_TARGET_FPS 30
#define PICKER_PADDING 4
static const int picker_window_width =
(TILE_WIDTH + PICKER_PADDING) * TILESET_WIDTH + PICKER_PADDING;
static const int picker_window_height =
(TILE_HEIGHT + PICKER_PADDING) * TILESET_HEIGHT + PICKER_PADDING;
#define PICKER_WINDOW_WIDTH \
((TILE_WIDTH + PICKER_PADDING) * TILESET_WIDTH + PICKER_PADDING)
#define PICKER_WINDOW_HEIGHT \
((TILE_HEIGHT + PICKER_PADDING) * TILESET_HEIGHT + \
PICKER_PADDING)

View File

@ -3,7 +3,9 @@
#pragma once
#include "level.h"
#include "options.h"
#include <raylib.h>
void level_draw(struct Level level, Texture2D tileset);
void editor_mouse_draw(int x, int y);
void level_draw(struct Level level, struct Options options,
Texture2D tileset);
void editor_mouse_draw(struct Options options, int x, int y);

View File

@ -2,7 +2,8 @@
/* Copyright (C) 2021 KikooDX */
#pragma once
#include "options.h"
#include "shared_data.h"
int editing_area_main(char *level_path, char *tileset_path,
int editing_area_main(struct Options options,
struct SharedData *shared_data);

25
include/options.h Normal file
View File

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright (C) 2021 KikooDX */
#pragma once
#define BUFFER_SIZE 256
struct Options {
char tileset_path[BUFFER_SIZE];
char level_path[BUFFER_SIZE];
int tile_width;
int tile_height;
int tileset_width;
int tileset_height;
int editor_window_width;
int editor_window_height;
int editor_target_fps;
int editor_draw_offset_x;
int editor_draw_offset_y;
int picker_window_width;
int picker_window_height;
int picker_target_fps;
int picker_padding;
};
struct Options options_defaults(void);

View File

@ -2,6 +2,8 @@
/* Copyright (C) 2021 KikooDX */
#pragma once
#include "options.h"
#include <raylib.h>
void tileset_draw(Texture2D tileset, int selected_tile);
void tileset_draw(Texture2D tileset, struct Options options,
int selected_tile);

View File

@ -2,7 +2,8 @@
/* Copyright (C) 2021 KikooDX */
#pragma once
#include "options.h"
#include "shared_data.h"
int tile_picker_main(char *tileset_path,
int tile_picker_main(struct Options options,
struct SharedData *shared_data);

View File

@ -3,35 +3,50 @@
#include "conf.h"
#include "editing_area/level.h"
#include "options.h"
#include <raylib.h>
#include <stdlib.h>
void level_draw(struct Level level, Texture2D tileset)
void level_draw(struct Level level, struct Options options,
Texture2D tileset)
{
int x;
int y;
for (x = 0; x < level.width; x += 1) {
for (y = 0; y < level.height; y += 1) {
const int tile =
level.data[x + y * level.width];
const Rectangle tile_rect = {
(int)(tile % TILESET_WIDTH) * TILE_WIDTH,
(int)(tile / TILESET_HEIGHT) * TILE_WIDTH,
TILE_WIDTH, TILE_HEIGHT};
const Vector2 tile_pos = {
x * TILE_WIDTH + draw_offset_x,
y * TILE_HEIGHT + draw_offset_y};
if (tile)
const int tile_index = x + y * level.width;
if (tile_index &&
tile_index < options.tileset_width *
options.tileset_height) {
const int tile =
level.data[x + y * level.width];
const Rectangle tile_rect = {
(int)(tile %
options.tileset_width) *
options.tile_width,
(int)(tile /
options.tileset_height) *
options.tile_height,
options.tile_width,
options.tile_height};
const Vector2 tile_pos = {
x * options.tile_width +
options.editor_draw_offset_x,
y * options.tile_height +
options.editor_draw_offset_y};
DrawTextureRec(tileset, tile_rect,
tile_pos, WHITE);
}
}
}
}
void editor_mouse_draw(int x, int y)
void editor_mouse_draw(struct Options options, int x, int y)
{
const int tx = x * TILE_WIDTH + draw_offset_x;
const int ty = y * TILE_HEIGHT + draw_offset_y;
DrawRectangle(tx, ty, TILE_WIDTH, TILE_HEIGHT,
overring_tile_color);
const int tx =
x * options.tile_width + options.editor_draw_offset_x;
const int ty =
y * options.tile_height + options.editor_draw_offset_y;
DrawRectangle(tx, ty, options.tile_width, options.tile_height,
OVERRING_TILE_COLOR);
}

View File

@ -1,10 +1,10 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright (C) 2021 KikooDX */
#include "conf.h"
#include "editing_area/draw.h"
#include "editing_area/level.h"
#include "mouse.h"
#include "options.h"
#include "shared_data.h"
#include <raylib.h>
#include <stdbool.h>
@ -12,11 +12,11 @@
#include <stdlib.h>
#include <sys/wait.h>
static void init_mouse(void);
static void init_mouse(struct Options options);
static void update_mouse(int *mouse_x, int *mouse_y, struct Level level,
struct SharedData *shared_data);
int editing_area_main(char *level_path, char *tileset_path,
int editing_area_main(struct Options options,
struct SharedData *shared_data)
{
int mouse_x;
@ -27,26 +27,26 @@ int editing_area_main(char *level_path, char *tileset_path,
Texture2D tileset;
/* initialize raylib */
InitWindow(editor_window_width, editor_window_height,
"SLE main window");
SetTargetFPS(editor_target_fps);
init_mouse();
InitWindow(options.editor_window_width,
options.editor_window_height, "SLE main window");
SetTargetFPS(options.editor_target_fps);
init_mouse(options);
/* load textures */
tileset = LoadTexture(tileset_path);
tileset = LoadTexture(options.tileset_path);
/* only proceed if tileset is large enough */
if (tileset.width < TILESET_MIN_WIDTH_PX ||
tileset.height < TILESET_MIN_HEIGHT_PX) {
if (tileset.width < options.tile_width ||
tileset.height < options.tile_height) {
fprintf(stderr,
"ERROR: tileset size is invalid, expected at "
"least [%d ; %d], got [%d ; %d]\n",
TILESET_MIN_WIDTH_PX, TILESET_MIN_HEIGHT_PX,
options.tile_width, options.tile_height,
tileset.width, tileset.height);
goto panic;
}
/* load level */
if (level_read(&level, level_path))
if (level_read(&level, options.level_path))
goto panic;
while (!WindowShouldClose()) {
@ -57,14 +57,14 @@ int editing_area_main(char *level_path, char *tileset_path,
BeginDrawing();
ClearBackground(BLACK);
level_draw(level, tileset);
editor_mouse_draw(mouse_x, mouse_y);
level_draw(level, options, tileset);
editor_mouse_draw(options, mouse_x, mouse_y);
EndDrawing();
}
/* save level */
level_write(level, level_path);
level_write(level, options.level_path);
panic:
@ -84,11 +84,12 @@ panic:
return EXIT_SUCCESS;
}
static void init_mouse(void)
static void init_mouse(struct Options options)
{
SetMouseOffset(-draw_offset_x, -draw_offset_y);
SetMouseScale(1.0 / (TILE_WIDTH * EDITOR_SCALE),
1.0 / (TILE_HEIGHT * EDITOR_SCALE));
SetMouseOffset(-options.editor_draw_offset_x,
-options.editor_draw_offset_y);
SetMouseScale(1.0 / options.tile_width,
1.0 / options.tile_height);
}
static void update_mouse(int *mouse_x, int *mouse_y, struct Level level,

View File

@ -2,6 +2,7 @@
/* Copyright (C) 2021 KikooDX */
#include "editing_area/main.h"
#include "options.h"
#include "shared_data.h"
#include "tile_picker/main.h"
#include <getopt.h>
@ -14,33 +15,34 @@
#include <sys/types.h>
#include <unistd.h>
static const int buffer_size = 256;
static void *create_shared_memory(size_t size);
static void overflow_prevention(void); /* work on optarg */
static void process_arguments(int argc, char **argv,
char tileset_path[buffer_size],
char level_path[buffer_size]);
struct Options *options);
static void set_tileset_dimensions(struct Options *options);
/* The editor fork to create two windows. One will be the level editor
* and the other the tile selection. This is done to allow the user to
* organize these panels in the way they want to. */
int main(int argc, char **argv)
{
int error;
pid_t child_process;
char level_path[buffer_size] = "";
char tileset_path[buffer_size] = "";
struct SharedData *shared_data =
(struct SharedData *)create_shared_memory(
sizeof(struct SharedData));
struct SharedData *shared_data;
struct Options options = options_defaults();
shared_data = (struct SharedData *)create_shared_memory(
sizeof(struct SharedData));
shared_data->end_child = false;
shared_data->selected_tile = 69;
shared_data->selected_tile = 1;
/* set log level */
SetTraceLogLevel(LOG_ERROR);
/* process arguments */
process_arguments(argc, argv, tileset_path, level_path);
process_arguments(argc, argv, &options);
/* set non-user defined options */
set_tileset_dimensions(&options);
/* forking here */
child_process = fork();
@ -49,11 +51,10 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
} else if (child_process == 0) {
/* child process, start the tile picker */
return tile_picker_main(tileset_path, shared_data);
return tile_picker_main(options, shared_data);
} else {
/* main process, start the editing area */
editing_area_main(level_path, tileset_path,
shared_data);
editing_area_main(options, shared_data);
return EXIT_SUCCESS;
}
}
@ -71,18 +72,17 @@ static void *create_shared_memory(size_t size)
static void overflow_prevention(void)
{
/* make sure arguments won't overflow */
if (strlen(optarg) > buffer_size) {
if (strlen(optarg) > BUFFER_SIZE) {
fprintf(stderr,
"ERROR: option size %lu is "
"bigger than maximum %d\n",
strlen(optarg), buffer_size);
strlen(optarg), BUFFER_SIZE);
exit(EXIT_FAILURE);
}
}
static void process_arguments(int argc, char **argv,
char tileset_path[buffer_size],
char level_path[buffer_size])
struct Options *options)
{
int opt;
while (1) {
@ -103,11 +103,11 @@ static void process_arguments(int argc, char **argv,
switch (opt) {
case 'l':
overflow_prevention();
strcpy(level_path, optarg);
strcpy(options->level_path, optarg);
break;
case 't':
overflow_prevention();
strcpy(tileset_path, optarg);
strcpy(options->tileset_path, optarg);
break;
case '?':
/* getopt_long already printed an error message
@ -124,12 +124,12 @@ static void process_arguments(int argc, char **argv,
/* missing arguments? */
{
int error = 0;
if (level_path[0] == '\0') {
if (options->level_path[0] == '\0') {
fprintf(stderr, "ERROR: no level path "
"specified (-level <path>)\n");
error = 1;
}
if (tileset_path[0] == '\0') {
if (options->tileset_path[0] == '\0') {
fprintf(stderr,
"ERROR: no tileset path specified "
"(-tileset <path>)\n");
@ -139,3 +139,33 @@ static void process_arguments(int argc, char **argv,
exit(EXIT_FAILURE);
}
}
static void set_tileset_dimensions(struct Options *options)
{
const Image tileset = LoadImage(options->tileset_path);
if (tileset.width < 0 || tileset.height < 0) {
fprintf(stderr, "ERROR: can't load tileset '%s'\n",
options->tileset_path);
exit(EXIT_FAILURE);
}
/* set options */
/* tileset_width */
options->tileset_width = tileset.width / options->tile_width;
/* tileset_height */
options->tileset_height = tileset.height / options->tile_height;
/* picker_window_width */
options->picker_window_width =
(options->tile_width + options->picker_padding) *
options->tileset_width +
options->picker_padding;
/* picker_window_height */
options->picker_window_height =
(options->tile_height + options->picker_padding) *
options->tileset_height +
options->picker_padding;
/* free memory */
UnloadImage(tileset);
}

23
src/options.c Normal file
View File

@ -0,0 +1,23 @@
#include "options.h"
#include "conf.h"
struct Options options_defaults(void)
{
return (struct Options){
.tileset_path = "",
.level_path = "",
.tile_width = TILE_WIDTH,
.tile_height = TILE_HEIGHT,
.tileset_width = 0,
.tileset_height = 0,
.editor_window_width = EDITOR_WINDOW_WIDTH,
.editor_window_height = EDITOR_WINDOW_HEIGHT,
.editor_target_fps = EDITOR_TARGET_FPS,
.editor_draw_offset_x = EDITOR_DRAW_OFFSET_X,
.editor_draw_offset_y = EDITOR_DRAW_OFFSET_Y,
.picker_window_width = 0,
.picker_window_height = 0,
.picker_target_fps = PICKER_TARGET_FPS,
.picker_padding = PICKER_PADDING,
};
}

View File

@ -3,26 +3,32 @@
#include "tile_picker/draw.h"
#include "conf.h"
#include "options.h"
#include <raylib.h>
void tileset_draw(Texture2D tileset, int selected_tile)
void tileset_draw(Texture2D tileset, struct Options options,
int selected_tile)
{
int x;
int y;
/* draw tiles */
for (x = 0; x < TILESET_WIDTH; x += 1) {
for (y = 0; y < TILESET_HEIGHT; y += 1) {
for (x = 0; x < options.tileset_width; x += 1) {
for (y = 0; y < options.tileset_height; y += 1) {
const Rectangle tile_rect = {
x * TILE_WIDTH, y * TILE_HEIGHT, TILE_WIDTH,
TILE_HEIGHT};
x * options.tile_width,
y * options.tile_height, options.tile_width,
options.tile_height};
const Vector2 tile_pos = {
x * (TILE_WIDTH + PICKER_PADDING) +
PICKER_PADDING,
y * (TILE_HEIGHT + PICKER_PADDING) +
PICKER_PADDING};
x * (options.tile_width +
options.picker_padding) +
options.picker_padding,
y * (options.tile_height +
options.picker_padding) +
options.picker_padding};
/* apply tint if tile isn't selected */
Color tint = unselected_tile_color;
if (x + y * TILESET_WIDTH == selected_tile)
Color tint = UNSELECTED_TILE_COLOR;
if (x + y * options.tileset_width ==
selected_tile)
tint = WHITE;
/* draw the tile */
DrawTextureRec(tileset, tile_rect, tile_pos,

View File

@ -1,8 +1,8 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright (C) 2021 KikooDX */
#include "conf.h"
#include "mouse.h"
#include "options.h"
#include "shared_data.h"
#include "tile_picker/draw.h"
#include <raylib.h>
@ -10,35 +10,39 @@
#include <stdio.h>
#include <stdlib.h>
static void init_mouse(void);
static void init_mouse(struct Options options);
static void update_mouse(int *mouse_x, int *mouse_y,
struct Options options,
struct SharedData *shared_data);
int tile_picker_main(char *tileset_path, struct SharedData *shared_data)
int tile_picker_main(struct Options options,
struct SharedData *shared_data)
{
int mouse_x;
int mouse_y;
Texture2D tileset;
/* initialize raylib */
InitWindow(picker_window_width, picker_window_height,
InitWindow(options.picker_window_width,
options.picker_window_height,
"SLE secondary window");
SetTargetFPS(picker_target_fps);
init_mouse();
SetTargetFPS(options.picker_target_fps);
init_mouse(options);
/* load textures */
tileset = LoadTexture(tileset_path);
tileset = LoadTexture(options.tileset_path);
/* only proceed if tileset is well loaded */
if (tileset.width > 0) {
while (!shared_data->end_child) {
/* update */
update_mouse(&mouse_x, &mouse_y, shared_data);
update_mouse(&mouse_x, &mouse_y, options,
shared_data);
/* draw */
BeginDrawing();
ClearBackground(BLACK);
tileset_draw(tileset,
tileset_draw(tileset, options,
shared_data->selected_tile);
EndDrawing();
@ -53,15 +57,17 @@ int tile_picker_main(char *tileset_path, struct SharedData *shared_data)
return EXIT_SUCCESS;
}
static void init_mouse(void)
static void init_mouse(struct Options options)
{
SetMouseOffset(-PICKER_PADDING, -PICKER_PADDING);
SetMouseOffset(-options.picker_padding,
-options.picker_padding);
SetMouseScale(
1.0 / ((TILE_WIDTH + PICKER_PADDING) * PICKER_SCALE),
1.0 / ((TILE_HEIGHT + PICKER_PADDING) * PICKER_SCALE));
1.0 / (options.tile_width + options.picker_padding),
1.0 / (options.tile_height + options.picker_padding));
}
static void update_mouse(int *mouse_x, int *mouse_y,
struct Options options,
struct SharedData *shared_data)
{
const bool left_click = IsMouseButtonDown(0);
@ -69,11 +75,13 @@ static void update_mouse(int *mouse_x, int *mouse_y,
update_mouse_position(
mouse_x, mouse_y,
TILESET_MIN_WIDTH_PX + TILESET_WIDTH * PICKER_PADDING,
TILESET_MIN_HEIGHT_PX + TILESET_HEIGHT * PICKER_PADDING);
options.tileset_width *
(options.tileset_width + options.picker_padding),
options.tileset_height *
(options.tileset_height + options.picker_padding));
/* set left button tile */
if (left_click)
shared_data->selected_tile =
*mouse_x + *mouse_y * TILESET_WIDTH;
*mouse_x + *mouse_y * options.tileset_width;
}