diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/editor.c | 324 | ||||
| -rw-r--r-- | src/editor.h | 30 | ||||
| -rw-r--r-- | src/main.c | 2 | ||||
| -rw-r--r-- | src/screens.c | 2 |
4 files changed, 356 insertions, 2 deletions
diff --git a/src/editor.c b/src/editor.c index 65f6a32..118b1f9 100644 --- a/src/editor.c +++ b/src/editor.c @@ -1,8 +1,17 @@ #include "editor.h" +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> + +#include "raygui.h" #include "raylib.h" #include "xd.h" +const char *EDITOR_MAIN_TABS[] = {"Build"}; +const int EDITOR_MAIN_TABS_SIZE = + sizeof(EDITOR_MAIN_TABS) / sizeof(EDITOR_MAIN_TABS[0]); + void SE_DrawEditor(Editor *editor, Camera2D *camera) { Vector2 mousePos = GetScreenToWorld2D(GetMousePosition(), *camera); float zoom = camera->zoom; @@ -28,3 +37,318 @@ void SE_DrawEditor(Editor *editor, Camera2D *camera) { } } } + +void drawBuildTab(Editor *editor, int x, int y, int width, int height) { + int padding = 20; + GuiPanel((Rectangle){x, y + 24.0f, width, height}, NULL); + + if (IsFileDropped() && editor->state.createBlockState == NULL) { + EditorCreateBlockState *state = malloc(sizeof(EditorCreateBlockState)); + + FilePathList droppedFiles = LoadDroppedFiles(); + + if (!IsFileExtension(droppedFiles.paths[0], ".png")) { + free(state); + UnloadDroppedFiles(droppedFiles); + return; + } + + state->upFilePath = droppedFiles.paths[0]; + UnloadDroppedFiles(droppedFiles); + + // loading textures + Image image = LoadImage(state->upFilePath); + if (image.width != TEXTURE_WIDTH || image.height != TEXTURE_HEIGHT) { + ImageResize(&image, TEXTURE_WIDTH, TEXTURE_HEIGHT); + } + state->upTexture = LoadTextureFromImage(image); + + editor->state.createBlockState = state; + + UnloadImage(image); + } + + // Rendering + Rectangle controlBounds = {x + padding, y + padding + 20.0f, 200, 200}; + Rectangle contentSize = {x + padding, y + padding, 10 * TEXTURE_WIDTH, 1000}; + + GuiScrollPanel(controlBounds, NULL, contentSize, &editor->state.panelScroll, + &editor->state.panelView); + + BeginScissorMode(editor->state.panelView.x, editor->state.panelView.y, + editor->state.panelView.width, + editor->state.panelView.height); + + Vector2 mousePos = GetMousePosition(); + + // rendering floor tiles in grid + int row = 0, column = 0, texturesPerRow = 10; + for (int i = 0; i < sizeof(editor->state.cache.tiles) / + sizeof(editor->state.cache.tiles[0]); + i++) { + EditorTile *tile = editor->state.cache.tiles[i]; + if (tile == NULL) continue; + + row = i / texturesPerRow; + column = i % texturesPerRow; + + int x = controlBounds.x + 5 + TEXTURE_WIDTH * column; + int y = + controlBounds.y + editor->state.panelScroll.y + TEXTURE_HEIGHT * row; + + DrawTexture(tile->texture, x, y, WHITE); + + bool isHovered = (x <= mousePos.x && mousePos.x <= x + TEXTURE_WIDTH) && + (y <= mousePos.y && mousePos.y <= y + TEXTURE_HEIGHT); + + bool sameTile = editor->state.selectedTile != NULL && + editor->state.selectedTile->data.id == tile->data.id; + + // hover event + if (isHovered || sameTile) { + DrawRectangleLines(x, y, TEXTURE_WIDTH, TEXTURE_HEIGHT, YELLOW); + } + + // select tile + if (isHovered && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { + editor->state.selectedTile = tile; + } + } + + EndScissorMode(); +} + +void drawTextures(EditorCreateBlockState *state, int wx, int wy, int ww, int wh, + int pad) { + if (state->isFloor) { + GuiLabel((Rectangle){wx + pad, wy + pad + 24.0f * 2.0f, ww, 24.0f}, "UP"); + DrawTexture(state->upTexture, wx + pad, wy + pad + 24.0f * 3.0f, WHITE); + } else { + GuiLabel((Rectangle){wx + pad, wy + pad + 24.0f * 2.0f, ww, 24.0f}, + "UP (2D)"); + DrawTexture(state->upTexture, wx + pad, wy + pad + 24.0f * 3.0f, WHITE); + + GuiLabel((Rectangle){wx + pad + 24.0f * 3.0f, wy + pad + 24.0f * 2.0f, ww, + 24.0f}, + "CORNER (2D)"); + DrawTexture(state->cornerTexture, wx + pad + 24.0f * 3.0f, + wy + pad + 24.0f * 3.0f, WHITE); + + GuiLabel((Rectangle){wx + pad + 24.0f * 7.0f, wy + pad + 24.0f * 2.0f, ww, + 24.0f}, + "SIDE (3D)"); + DrawTexture(state->sideTexture, wx + pad + 24.0f * 7.0f, + wy + pad + 24.0f * 3.0f, WHITE); + } +} + +void loadWallTextures(EditorCreateBlockState *state, int wx, int wy, int ww, + int wh, int pad) { + if (state->sideFilePath == NULL) { + int box = GuiMessageBox((Rectangle){wx - 20, wy + 100, ww + 40, 200}, + "Waiting for side texture", + "Drop side texture here", "No"); + + if (box >= 1) { + state->isWall = false; + state->isFloor = true; + } + + if (IsFileDropped()) { + FilePathList droppedFiles = LoadDroppedFiles(); + + if (!IsFileExtension(droppedFiles.paths[0], ".png")) { + UnloadDroppedFiles(droppedFiles); + return; + } + + state->sideFilePath = droppedFiles.paths[0]; + UnloadDroppedFiles(droppedFiles); + + Image image = LoadImage(state->sideFilePath); + if (image.width != TEXTURE_WIDTH || image.height != TEXTURE_HEIGHT) { + ImageResize(&image, TEXTURE_WIDTH, TEXTURE_HEIGHT); + } + state->sideTexture = LoadTextureFromImage(image); + } + + return; + } + + if (state->cornerFilePath == NULL) { + int box = GuiMessageBox((Rectangle){wx - 20, wy + 100, ww + 40, 200}, + "Waiting for corner texture", + "Drop corner texture here", "No"); + + if (box >= 1) { + UnloadTexture(state->sideTexture); + free(state->sideFilePath); + state->sideFilePath = NULL; + state->isWall = false; + state->isFloor = true; + } + + if (IsFileDropped()) { + FilePathList droppedFiles = LoadDroppedFiles(); + + if (!IsFileExtension(droppedFiles.paths[0], ".png")) { + UnloadDroppedFiles(droppedFiles); + return; + } + + state->cornerFilePath = droppedFiles.paths[0]; + UnloadDroppedFiles(droppedFiles); + + Image image = LoadImage(state->cornerFilePath); + if (image.width != TEXTURE_WIDTH || image.height != TEXTURE_HEIGHT) { + ImageResize(&image, TEXTURE_WIDTH, TEXTURE_HEIGHT); + } + state->cornerTexture = LoadTextureFromImage(image); + } + + return; + } +} + +void drawPreview(EditorCreateBlockState *state, int wx, int wy, int ww, int wh, + int pad) { + GuiLabel((Rectangle){wx + pad, wy + pad + 24.0f * 4.0f, ww, 24.0f}, + "2D PREVIEW"); + for (int x = 0; x < 10; x++) { + for (int y = 0; y < 5; y++) { + if (state->isFloor) { + DrawTexture(state->upTexture, wx + pad + x * TEXTURE_WIDTH, + wy + pad + 24.0f * 5.0f + y * TEXTURE_HEIGHT, WHITE); + } else { + Vector2 position = {x * TEXTURE_WIDTH, y * TEXTURE_HEIGHT}; + position.x += wx + pad; + position.y += wy + pad + 24.0f * 5.0f; + + // --- CORNERS --- + // top left + if (x == 0 && y == 0) { + DrawTextureEx(state->cornerTexture, position, 0.0f, 1.0f, WHITE); + } + // top right + else if (x == 9 && y == 0) { + DrawTextureEx(state->cornerTexture, position, 90.0f, 1.0f, WHITE); + } + // bottom left + else if (x == 0 && y == 4) { + DrawTextureEx(state->cornerTexture, position, 270.0f, 1.0f, WHITE); + } + // bottom right + else if (x == 9 && y == 4) { + DrawTextureEx(state->cornerTexture, position, 180.0f, 1.0f, WHITE); + } + + // --- SIDES --- + // top + else if (y == 0) { + DrawTextureEx(state->upTexture, position, 0.0f, 1.0f, WHITE); + } + // left + else if (x == 0 && y > 1) { + DrawTextureEx(state->upTexture, position, 270.0f, 1.0f, WHITE); + } + // right + else if (x == 9) { + DrawTextureEx(state->upTexture, position, 90.0f, 1.0f, WHITE); + } + // bottom + else if (y == 4 && x > 1) { + DrawTextureEx(state->upTexture, position, 180.0f, 1.0f, WHITE); + } + } + } + } +} + +void drawCreatingNewBlock(Editor *editor) { + EditorCreateBlockState *state = editor->state.createBlockState; + + int ww = 300; + int wh = 280; + + int wx = GetScreenWidth() / 2.0f - ww / 2.0f; + int wy = GetScreenHeight() / 2.0f - wh / 2.0f; + int pad = 20; + + int close = GuiWindowBox((Rectangle){wx, wy, ww, wh}, "Creating a new block"); + + // --- Block type --- + GuiLabel((Rectangle){wx + pad, wy + pad, ww - pad * 2, 24.0f}, "Select type"); + + GuiCheckBox((Rectangle){wx + pad, wy + pad + 24.0f, 24.0f, 24.0f}, "Floor", + &state->isFloor); + if (state->isFloor) state->isWall = false; + + GuiCheckBox( + (Rectangle){wx + pad * 4.0f + 24.0f, wy + pad + 24.0f, 24.0f, 24.0f}, + "Wall", &state->isWall); + if (state->isWall) state->isFloor = false; + if (!state->isWall && !state->isFloor) state->isFloor = true; + + // --- Texture loading --- + // Up texture + drawTextures(state, wx, wy, ww, wh, pad); + + // Side texture + if (state->isWall) { + loadWallTextures(state, wx, wy, ww, wh, pad); + } + + drawPreview(state, wx, wy, ww, wh, pad); + + int createButton = GuiButton( + (Rectangle){wx + pad, wy + wh - pad * 2.0f, ww - pad * 2.0f, 32.0f}, + "Create"); + + if (createButton) { + close = true; + + if (state->isFloor) { + int id = editor->state.cache.tileCacheSize; + + EditorTile *tile = malloc(sizeof(EditorTile)); + editor->state.cache.tiles[id] = tile; + + tile->data = (XdTileData){}; + tile->data.id = id; + tile->data.type = TILE_FLOOR; + + tile->texture = state->upTexture; + + editor->state.cache.tileCacheSize++; + } + } + + if (close) { + // free(state); + editor->state.createBlockState = NULL; + } +} + +void SE_DrawEditorToolkit(Editor *editor) { + float width = 400.0f; + float height = GetScreenHeight(); + float x = GetScreenWidth() - width; + float y = 0; + + switch (editor->state.activeMainTab) { + case 0: { + drawBuildTab(editor, x, y, width, height); + break; + } + default: + break; + } + + GuiTabBar((Rectangle){x, y, 100.0, 24.0f}, EDITOR_MAIN_TABS, + EDITOR_MAIN_TABS_SIZE, &editor->state.activeMainTab); + + // Creating new block + if (editor->state.createBlockState != NULL) { + drawCreatingNewBlock(editor); + } +}
\ No newline at end of file diff --git a/src/editor.h b/src/editor.h index e1981cf..02966f1 100644 --- a/src/editor.h +++ b/src/editor.h @@ -1,11 +1,37 @@ #ifndef __EDITOR_H__ #define __EDITOR_H__ #include <raylib.h> +#include <stdbool.h> #include "xd.h" +#define TEXTURE_WIDTH 16.0f +#define TEXTURE_HEIGHT 16.0f + +typedef struct { + bool isFloor, isWall; + char *upFilePath, *sideFilePath, *cornerFilePath; + Texture2D upTexture, sideTexture, cornerTexture; +} EditorCreateBlockState; + +typedef struct { + XdTileData data; + Texture2D texture; +} EditorTile; + +typedef struct { + int tileCacheSize; + EditorTile *tiles[200]; + Texture2D *textureCache[]; +} EditorCache; + typedef struct { - int currentLevel, currentLayer; + int currentLevel, currentLayer, activeMainTab; + EditorCreateBlockState *createBlockState; + Rectangle panelView; + Vector2 panelScroll; + EditorCache cache; + EditorTile *selectedTile; } EditorState; typedef struct { @@ -14,4 +40,6 @@ typedef struct { } Editor; void SE_DrawEditor(Editor *editor, Camera2D *camera); +void SE_DrawEditorToolkit(Editor *editor); +void SE_RebuildEditorCache(Editor *editor); #endif @@ -25,7 +25,7 @@ int main() { UnloadDirectoryFiles(list); XdData* data = NULL; - Editor editor = {data, {0, 0}}; + Editor editor = {data, {0, 0, 0, NULL, {0, 0, 0, 0}, {0, 0}, NULL, {}}}; Camera2D camera = {0}; camera.target = (Vector2){0.0f, 0.0f}; diff --git a/src/screens.c b/src/screens.c index 03b1441..0d18079 100644 --- a/src/screens.c +++ b/src/screens.c @@ -73,5 +73,7 @@ void SE_DrawEditorScreen(GameScreen *currentScreen, Editor *editor, SE_DrawEditor(editor, camera); EndMode2D(); + SE_DrawEditorToolkit(editor); + EndDrawing(); } |
