sle/src/editing_area/main.c

151 lines
4.0 KiB
C

/* 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 "info.h"
#include "mouse.h"
#include "options.h"
#include "scale.h"
#include "shared_data.h"
#include <raylib.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
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(struct Options options,
struct SharedData *shared_data)
{
int mouse_x;
int mouse_y;
int error;
struct Level level;
level.data = NULL;
Texture2D tileset;
/* initialize raylib */
InitWindow(options.editor_width * options.editor_scale,
options.editor_height * options.editor_scale,
"SLE main window");
SetWindowState(FLAG_WINDOW_RESIZABLE);
SetTargetFPS(options.editor_target_fps);
/* load textures */
tileset = LoadTexture(options.tileset_path);
/* render targets used for upscaling */
const RenderTexture2D rend_target = LoadRenderTexture(
options.editor_width, options.editor_height);
const RenderTexture2D flip_target = LoadRenderTexture(
options.editor_width, options.editor_height);
/* only proceed if tileset is large enough */
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",
options.tile_width, options.tile_height,
tileset.width, tileset.height);
goto panic;
}
/* load level or create empty one */
if (options.level_create) {
if (level_create(&level, options))
goto panic;
} else if (level_read(&level, options.level_path))
goto panic;
while (!WindowShouldClose()) {
/* update */
init_mouse(options);
update_mouse(&mouse_x, &mouse_y, level, shared_data);
/* draw */
BeginDrawing();
BeginTextureMode(rend_target);
ClearBackground(options.editor_bg_color);
level_draw(level, options, tileset);
editor_mouse_draw(options, mouse_x, mouse_y);
EndTextureMode();
/* flip texture */
BeginTextureMode(flip_target);
DrawTexture(rend_target.texture, 0, 0, WHITE);
EndTextureMode();
/* draw upscaled render */
ClearBackground(BLACK);
DrawTextureEx(flip_target.texture,
offset_editor(options), 0,
scale_editor(options), WHITE);
EndDrawing();
}
/* save level */
level_write(level, options.level_path);
panic:
/* deinit */
level_free(&level);
/* unload raylib stuff */
UnloadTexture(tileset);
UnloadRenderTexture(rend_target);
UnloadRenderTexture(flip_target);
CloseWindow();
/* tell to the child process it can end */
shared_data->end_child = true;
/* wait for child process to exit */
wait(NULL);
return EXIT_SUCCESS;
}
static void init_mouse(struct Options options)
{
const float scaling = scale_editor(options);
const Vector2 off = offset_editor(options);
SetMouseOffset(-options.editor_draw_offset_x - off.x,
-options.editor_draw_offset_y - off.y);
SetMouseScale(1.0 / scaling / options.tile_width,
1.0 / scaling / options.tile_height);
}
static void update_mouse(int *mouse_x, int *mouse_y, struct Level level,
struct SharedData *shared_data)
{
const bool left_click = IsMouseButtonDown(0);
const bool right_click = IsMouseButtonDown(1);
const bool middle_click = IsMouseButtonPressed(2);
update_mouse_position(mouse_x, mouse_y, level.width - 1,
level.height - 1);
/* set tile */
if (left_click)
level.data[*mouse_x + *mouse_y * level.width] =
shared_data->selected_tile;
/* remove tile */
if (right_click)
level.data[*mouse_x + *mouse_y * level.width] = 0;
/* set tile to pointed cell (pick tile) */
if (middle_click) {
INFO_VAR("%d",
level.data[*mouse_x + *mouse_y * level.width]);
shared_data->selected_tile =
level.data[*mouse_x + *mouse_y * level.width];
}
}