mirror of https://git.sr.ht/~kikoodx/sle
142 lines
3.7 KiB
C
142 lines
3.7 KiB
C
/* SPDX-License-Identifier: GPL-3.0-or-later */
|
|
/* Copyright (C) 2021 KikooDX */
|
|
|
|
#include "editing_area/main.h"
|
|
#include "shared_data.h"
|
|
#include "tile_picker/main.h"
|
|
#include <getopt.h>
|
|
#include <raylib.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/mman.h>
|
|
#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]);
|
|
|
|
/* 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)
|
|
{
|
|
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));
|
|
shared_data->end_child = false;
|
|
shared_data->selected_tile = 69;
|
|
|
|
/* set log level */
|
|
SetTraceLogLevel(LOG_ERROR);
|
|
|
|
/* process arguments */
|
|
process_arguments(argc, argv, tileset_path, level_path);
|
|
|
|
/* forking here */
|
|
child_process = fork();
|
|
if (child_process < 0) {
|
|
fprintf(stderr, "ERROR: process couldn't fork");
|
|
return EXIT_FAILURE;
|
|
} else if (child_process == 0) {
|
|
/* child process, start the tile picker */
|
|
return tile_picker_main(tileset_path, shared_data);
|
|
} else {
|
|
/* main process, start the editing area */
|
|
editing_area_main(level_path, tileset_path,
|
|
shared_data);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
}
|
|
|
|
static void *create_shared_memory(size_t size)
|
|
{
|
|
/* shared memory will be read & write */
|
|
int protection = PROT_READ | PROT_WRITE;
|
|
/* anonymous and shared, only child process will be able to
|
|
* access it */
|
|
int visibility = MAP_SHARED | MAP_ANONYMOUS;
|
|
return mmap(NULL, size, protection, visibility, -1, 0);
|
|
}
|
|
|
|
static void overflow_prevention(void)
|
|
{
|
|
/* make sure arguments won't overflow */
|
|
if (strlen(optarg) > buffer_size) {
|
|
fprintf(stderr,
|
|
"ERROR: option size %lu is "
|
|
"bigger than maximum %d\n",
|
|
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])
|
|
{
|
|
int opt;
|
|
while (1) {
|
|
static struct option long_options[] = {
|
|
{"level", required_argument, 0, 'l'},
|
|
{"tileset", required_argument, 0, 't'},
|
|
{0, 0, 0, 0},
|
|
};
|
|
/* getopt_long stores the option index here */
|
|
int option_index = 0;
|
|
|
|
opt = getopt_long_only(argc, argv, "", long_options,
|
|
&option_index);
|
|
/* detect the end of the options */
|
|
if (opt == -1)
|
|
break;
|
|
|
|
switch (opt) {
|
|
case 'l':
|
|
overflow_prevention();
|
|
strcpy(level_path, optarg);
|
|
break;
|
|
case 't':
|
|
overflow_prevention();
|
|
strcpy(tileset_path, optarg);
|
|
break;
|
|
case '?':
|
|
/* getopt_long already printed an error message
|
|
*/
|
|
exit(EXIT_FAILURE);
|
|
default:
|
|
fprintf(stderr,
|
|
"ERROR: option -%c non handled "
|
|
"(open an issue!)\n",
|
|
opt);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
/* missing arguments? */
|
|
{
|
|
int error = 0;
|
|
if (level_path[0] == '\0') {
|
|
fprintf(stderr, "ERROR: no level path "
|
|
"specified (-level <path>)\n");
|
|
error = 1;
|
|
}
|
|
if (tileset_path[0] == '\0') {
|
|
fprintf(stderr,
|
|
"ERROR: no tileset path specified "
|
|
"(-tileset <path>)\n");
|
|
error = 1;
|
|
}
|
|
if (error)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|