mirror of
https://github.com/coah80/LegacyVulkEdition.git
synced 2026-07-19 06:58:07 +00:00
389 lines
14 KiB
C++
389 lines
14 KiB
C++
#define NK_INCLUDE_FIXED_TYPES
|
|
#define NK_INCLUDE_STANDARD_IO
|
|
#define NK_INCLUDE_STANDARD_VARARGS
|
|
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
|
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
|
#define NK_INCLUDE_FONT_BAKING
|
|
#define NK_INCLUDE_DEFAULT_FONT
|
|
#include "nuklear.h"
|
|
|
|
#include "NkCoreMenus.h"
|
|
#include "NkCommon.h"
|
|
#include "MenuScreens.h"
|
|
#include "NuklearBridge.h"
|
|
#include <cmath>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <ctime>
|
|
|
|
namespace lve { namespace ui {
|
|
|
|
static const float BASE_W = 1280.0f;
|
|
static const float BASE_H = 720.0f;
|
|
|
|
static const float MAIN_BUTTON_W = 600.0f;
|
|
static const float MAIN_BUTTON_X = (BASE_W - MAIN_BUTTON_W) * 0.5f;
|
|
static const float MAIN_BUTTON_H = 40.0f;
|
|
static const float MAIN_BUTTON_Y_START = 250.0f;
|
|
static const float MAIN_BUTTON_Y_STEP = 50.0f;
|
|
|
|
static const float PAUSE_BUTTON_X = 440.0f;
|
|
static const float PAUSE_BUTTON_W = 400.0f;
|
|
static const float PAUSE_BUTTON_H = 40.0f;
|
|
static const float PAUSE_BUTTON_Y_START = 250.0f;
|
|
static const float PAUSE_BUTTON_Y_STEP = 50.0f;
|
|
|
|
static const float DEATH_TITLE_X = 440.0f;
|
|
static const float DEATH_TITLE_Y = 92.0f;
|
|
static const float DEATH_TITLE_W = 400.0f;
|
|
static const float DEATH_TITLE_H = 100.0f;
|
|
|
|
static const float DEATH_RESPAWN_X = 440.0f;
|
|
static const float DEATH_RESPAWN_Y = 400.0f;
|
|
static const float DEATH_RESPAWN_W = 400.0f;
|
|
static const float DEATH_RESPAWN_H = 40.0f;
|
|
|
|
static const float DEATH_EXIT_X = 440.0f;
|
|
static const float DEATH_EXIT_Y = 450.0f;
|
|
static const float DEATH_EXIT_W = 400.0f;
|
|
static const float DEATH_EXIT_H = 40.0f;
|
|
|
|
static const float LOGO_Y = 56.0f;
|
|
static const float LOGO_W = 1280.0f;
|
|
static const float LOGO_H = 138.0f;
|
|
|
|
static const int MAIN_MENU_BUTTON_COUNT = 6;
|
|
static const char *MAIN_MENU_LABELS[MAIN_MENU_BUTTON_COUNT] = {
|
|
"Play Game",
|
|
"Leaderboards",
|
|
"Achievements",
|
|
"Help & Options",
|
|
"Minecraft Store",
|
|
"Quit Game"
|
|
};
|
|
|
|
static const MenuAction MAIN_MENU_ACTIONS[MAIN_MENU_BUTTON_COUNT] = {
|
|
kMenuAction_PlayGame,
|
|
kMenuAction_Leaderboards,
|
|
kMenuAction_Achievements,
|
|
kMenuAction_HelpAndOptions,
|
|
kMenuAction_DLC,
|
|
kMenuAction_QuitGame
|
|
};
|
|
|
|
static const int PAUSE_MENU_BUTTON_COUNT = 6;
|
|
static const char *PAUSE_MENU_LABELS[PAUSE_MENU_BUTTON_COUNT] = {
|
|
"Resume Game",
|
|
"Help & Options",
|
|
"Leaderboards",
|
|
"Achievements",
|
|
"Save Game",
|
|
"Exit Game"
|
|
};
|
|
|
|
static const MenuAction PAUSE_MENU_ACTIONS[PAUSE_MENU_BUTTON_COUNT] = {
|
|
kMenuAction_ResumeGame,
|
|
kMenuAction_HelpAndOptions,
|
|
kMenuAction_Leaderboards,
|
|
kMenuAction_Achievements,
|
|
kMenuAction_SaveGame,
|
|
kMenuAction_ExitGame
|
|
};
|
|
|
|
|
|
static void drawEditionSubtitle(nk_context *ctx, int winW, int winH)
|
|
{
|
|
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
|
|
if (canvas == nullptr) return;
|
|
|
|
nk_font *smallNkFont = getSmallFont();
|
|
const struct nk_user_font *font = smallNkFont ? &smallNkFont->handle : ctx->style.font;
|
|
if (font == nullptr) return;
|
|
|
|
float scaleY = (float)winH / BASE_H;
|
|
float subtitleY = (LOGO_Y + LOGO_H + 4.0f) * scaleY;
|
|
|
|
const char *text = "WINDOWS EDITION";
|
|
int len = (int)strlen(text);
|
|
float textW = font->width(font->userdata, font->height, text, len);
|
|
float textX = ((float)winW - textW) * 0.5f;
|
|
|
|
float shadowOff = 1.0f;
|
|
nk_draw_text(canvas, nk_rect(textX + shadowOff, subtitleY + shadowOff, textW, font->height),
|
|
text, len, font,
|
|
nk_rgba(0, 0, 0, 0), nk_rgb(0x50, 0x50, 0x0F));
|
|
nk_draw_text(canvas, nk_rect(textX, subtitleY, textW, font->height),
|
|
text, len, font,
|
|
nk_rgba(0, 0, 0, 0), nk_rgb(0xEB, 0xEB, 0x0F));
|
|
}
|
|
|
|
static void drawCenteredText(nk_context *ctx, const char *text,
|
|
float x, float y, float w, float h,
|
|
struct nk_color color,
|
|
const struct nk_user_font *fontOverride = nullptr)
|
|
{
|
|
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
|
|
if (canvas == nullptr) return;
|
|
|
|
const struct nk_user_font *font = fontOverride ? fontOverride : ctx->style.font;
|
|
if (font == nullptr) return;
|
|
|
|
int len = (int)strlen(text);
|
|
float textW = font->width(font->userdata, font->height, text, len);
|
|
float textX = x + (w - textW) * 0.5f;
|
|
float textY = y + (h - font->height) * 0.5f;
|
|
nk_draw_text(canvas, nk_rect(textX, textY, textW, font->height),
|
|
text, len, font,
|
|
nk_rgba(0, 0, 0, 0), color);
|
|
}
|
|
|
|
static void drawCenteredTextWithShadow(nk_context *ctx, const char *text,
|
|
float x, float y, float w, float h,
|
|
struct nk_color color,
|
|
const struct nk_user_font *fontOverride = nullptr,
|
|
float shadowOffset = 2.0f)
|
|
{
|
|
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
|
|
if (canvas == nullptr) return;
|
|
|
|
const struct nk_user_font *font = fontOverride ? fontOverride : ctx->style.font;
|
|
if (font == nullptr) return;
|
|
|
|
int len = (int)strlen(text);
|
|
float textW = font->width(font->userdata, font->height, text, len);
|
|
float textX = x + (w - textW) * 0.5f;
|
|
float textY = y + (h - font->height) * 0.5f;
|
|
|
|
nk_draw_text(canvas, nk_rect(textX + shadowOffset, textY + shadowOffset, textW, font->height),
|
|
text, len, font,
|
|
nk_rgba(0, 0, 0, 0), nk_rgba(63, 21, 21, color.a));
|
|
nk_draw_text(canvas, nk_rect(textX, textY, textW, font->height),
|
|
text, len, font,
|
|
nk_rgba(0, 0, 0, 0), color);
|
|
}
|
|
|
|
static bool drawBtnWithShadow(nk_context *ctx, const char *label,
|
|
float x, float y, float w, float h,
|
|
bool isHovered, MenuTextures &tex)
|
|
{
|
|
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
|
|
if (canvas == nullptr) return false;
|
|
|
|
struct nk_rect btnRect = nk_rect(x, y, w, h);
|
|
|
|
if (tex.buttonNormal.w > 0) {
|
|
struct nk_image img = isHovered
|
|
? slotToNkImage(tex.buttonHover)
|
|
: slotToNkImage(tex.buttonNormal);
|
|
nk_draw_image(canvas, btnRect, &img, nk_rgb(255, 255, 255));
|
|
} else {
|
|
struct nk_color bg = isHovered ? nk_rgb(80, 80, 80) : nk_rgb(50, 50, 50);
|
|
nk_fill_rect(canvas, btnRect, 0, bg);
|
|
nk_stroke_rect(canvas, btnRect, 0, 1.0f, nk_rgb(100, 100, 100));
|
|
}
|
|
|
|
if (isHovered && tex.buttonOutline.w > 0) {
|
|
struct nk_image outlineImg = slotToNkImage(tex.buttonOutline);
|
|
float padX = w * 0.005f;
|
|
float padY = h * 0.05f;
|
|
struct nk_rect outlineRect = nk_rect(x - padX, y - padY,
|
|
w + padX * 2.0f, h + padY * 2.0f);
|
|
nk_draw_image(canvas, outlineRect, &outlineImg, nk_rgba(255, 255, 255, 100));
|
|
}
|
|
|
|
const struct nk_user_font *font = ctx->style.font;
|
|
if (font != nullptr) {
|
|
int len = (int)strlen(label);
|
|
float textW = font->width(font->userdata, font->height, label, len);
|
|
float textX = x + (w - textW) * 0.5f;
|
|
float textY = y + (h - font->height) * 0.5f;
|
|
nk_draw_text(canvas, nk_rect(textX + 1.0f, textY + 1.0f, textW, font->height),
|
|
label, len, font,
|
|
nk_rgba(0, 0, 0, 0), nk_rgba(56, 56, 56, 255));
|
|
nk_draw_text(canvas, nk_rect(textX, textY, textW, font->height),
|
|
label, len, font,
|
|
nk_rgba(0, 0, 0, 0), nk_rgb(255, 255, 255));
|
|
}
|
|
|
|
const struct nk_input *input = &ctx->input;
|
|
bool hovering = nk_input_is_mouse_hovering_rect(input, btnRect) != 0;
|
|
bool clicked = hovering && nk_input_is_mouse_released(input, NK_BUTTON_LEFT) != 0;
|
|
|
|
return clicked;
|
|
}
|
|
|
|
static void drawVersionStrings(nk_context *ctx, int winW, int winH)
|
|
{
|
|
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
|
|
if (canvas == nullptr) return;
|
|
|
|
nk_font *smallNkFont = getSmallFont();
|
|
const struct nk_user_font *font = smallNkFont ? &smallNkFont->handle : ctx->style.font;
|
|
if (font == nullptr) return;
|
|
|
|
const char *version = "TU75 / 1.83 - Legacy Vulk Edition";
|
|
int vlen = (int)strlen(version);
|
|
float versionW = font->width(font->userdata, font->height, version, vlen);
|
|
float versionX = (float)winW - versionW - 8.0f;
|
|
float versionY = (float)winH - font->height - 8.0f;
|
|
nk_draw_text(canvas, nk_rect(versionX, versionY, versionW, font->height),
|
|
version, vlen, font,
|
|
nk_rgba(0, 0, 0, 0), nk_rgba(255, 255, 255, 140));
|
|
|
|
const char *copyright = "Copyright Mojang AB. Do not distribute!";
|
|
int clen = (int)strlen(copyright);
|
|
float copyrightW = font->width(font->userdata, font->height, copyright, clen);
|
|
float copyrightX = 8.0f;
|
|
float copyrightY = (float)winH - font->height - 8.0f;
|
|
nk_draw_text(canvas, nk_rect(copyrightX, copyrightY, copyrightW, font->height),
|
|
copyright, clen, font,
|
|
nk_rgba(0, 0, 0, 0), nk_rgba(255, 255, 255, 100));
|
|
}
|
|
|
|
MenuAction renderMainMenu(nk_context *ctx, int winW, int winH, MenuTextures &tex)
|
|
{
|
|
MenuAction result = kMenuAction_None;
|
|
|
|
float scaleX = (float)winW / BASE_W;
|
|
float scaleY = (float)winH / BASE_H;
|
|
|
|
pushCleanStyle(ctx);
|
|
|
|
if (nk_begin(ctx, "CoreMainMenu", nk_rect(0, 0, (float)winW, (float)winH),
|
|
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_NO_INPUT | NK_WINDOW_BACKGROUND)) {
|
|
|
|
drawPanoramaBg(ctx, winW, winH, tex);
|
|
drawLogo(ctx, winW, winH, tex);
|
|
|
|
float btnW = MAIN_BUTTON_W * scaleX;
|
|
float btnH = MAIN_BUTTON_H * scaleY;
|
|
float btnX = MAIN_BUTTON_X * scaleX;
|
|
|
|
const struct nk_input *input = &ctx->input;
|
|
|
|
for (int i = 0; i < MAIN_MENU_BUTTON_COUNT; i++) {
|
|
float btnY = (MAIN_BUTTON_Y_START + (float)i * MAIN_BUTTON_Y_STEP) * scaleY;
|
|
struct nk_rect btnRect = nk_rect(btnX, btnY, btnW, btnH);
|
|
bool hovering = nk_input_is_mouse_hovering_rect(input, btnRect) != 0;
|
|
|
|
if (drawBtn(ctx, MAIN_MENU_LABELS[i], btnX, btnY, btnW, btnH, hovering, winH, tex)) {
|
|
result = MAIN_MENU_ACTIONS[i];
|
|
}
|
|
}
|
|
|
|
drawControllerPrompts(ctx, winW, winH, tex);
|
|
drawVersionStrings(ctx, winW, winH);
|
|
}
|
|
nk_end(ctx);
|
|
|
|
popCleanStyle(ctx);
|
|
|
|
return result;
|
|
}
|
|
|
|
MenuAction renderPauseMenu(nk_context *ctx, int winW, int winH, MenuTextures &tex)
|
|
{
|
|
MenuAction result = kMenuAction_None;
|
|
|
|
float scaleX = (float)winW / BASE_W;
|
|
float scaleY = (float)winH / BASE_H;
|
|
|
|
pushCleanStyle(ctx);
|
|
|
|
if (nk_begin(ctx, "CorePauseMenu", nk_rect(0, 0, (float)winW, (float)winH),
|
|
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_NO_INPUT | NK_WINDOW_BACKGROUND)) {
|
|
|
|
drawDirtBg(ctx, winW, winH, tex);
|
|
drawLogo(ctx, winW, winH, tex);
|
|
|
|
float btnW = PAUSE_BUTTON_W * scaleX;
|
|
float btnH = PAUSE_BUTTON_H * scaleY;
|
|
float btnX = PAUSE_BUTTON_X * scaleX;
|
|
|
|
const struct nk_input *input = &ctx->input;
|
|
|
|
for (int i = 0; i < PAUSE_MENU_BUTTON_COUNT; i++) {
|
|
float btnY = (PAUSE_BUTTON_Y_START + (float)i * PAUSE_BUTTON_Y_STEP) * scaleY;
|
|
struct nk_rect btnRect = nk_rect(btnX, btnY, btnW, btnH);
|
|
bool hovering = nk_input_is_mouse_hovering_rect(input, btnRect) != 0;
|
|
|
|
if (drawBtn(ctx, PAUSE_MENU_LABELS[i], btnX, btnY, btnW, btnH, hovering, winH, tex)) {
|
|
result = PAUSE_MENU_ACTIONS[i];
|
|
}
|
|
}
|
|
|
|
drawControllerPrompts(ctx, winW, winH, tex);
|
|
}
|
|
nk_end(ctx);
|
|
|
|
popCleanStyle(ctx);
|
|
|
|
return result;
|
|
}
|
|
|
|
MenuAction renderDeathMenu(nk_context *ctx, int winW, int winH, MenuTextures &tex)
|
|
{
|
|
MenuAction result = kMenuAction_None;
|
|
|
|
float scaleX = (float)winW / BASE_W;
|
|
float scaleY = (float)winH / BASE_H;
|
|
|
|
pushCleanStyle(ctx);
|
|
|
|
if (nk_begin(ctx, "CoreDeathMenu", nk_rect(0, 0, (float)winW, (float)winH),
|
|
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_NO_INPUT | NK_WINDOW_BACKGROUND)) {
|
|
|
|
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
|
|
|
|
drawDirtBg(ctx, winW, winH, tex);
|
|
|
|
if (canvas != nullptr) {
|
|
nk_fill_rect(canvas, nk_rect(0, 0, (float)winW, (float)winH),
|
|
0, nk_rgba(128, 0, 0, 100));
|
|
}
|
|
|
|
float titleX = DEATH_TITLE_X * scaleX;
|
|
float titleY = DEATH_TITLE_Y * scaleY;
|
|
float titleW = DEATH_TITLE_W * scaleX;
|
|
float titleH = DEATH_TITLE_H * scaleY;
|
|
nk_font *titleFont = getTitleFont();
|
|
const struct nk_user_font *titleUserFont = titleFont ? &titleFont->handle : nullptr;
|
|
drawCenteredTextWithShadow(ctx, "You Died!", titleX, titleY, titleW, titleH,
|
|
nk_rgb(255, 85, 85), titleUserFont, 2.0f);
|
|
|
|
float respawnX = DEATH_RESPAWN_X * scaleX;
|
|
float respawnY = DEATH_RESPAWN_Y * scaleY;
|
|
float respawnW = DEATH_RESPAWN_W * scaleX;
|
|
float respawnH = DEATH_RESPAWN_H * scaleY;
|
|
|
|
const struct nk_input *input = &ctx->input;
|
|
|
|
struct nk_rect respawnRect = nk_rect(respawnX, respawnY, respawnW, respawnH);
|
|
bool respawnHover = nk_input_is_mouse_hovering_rect(input, respawnRect) != 0;
|
|
if (drawBtnWithShadow(ctx, "Respawn", respawnX, respawnY, respawnW, respawnH, respawnHover, tex)) {
|
|
result = kMenuAction_Respawn;
|
|
}
|
|
|
|
float exitX = DEATH_EXIT_X * scaleX;
|
|
float exitY = DEATH_EXIT_Y * scaleY;
|
|
float exitW = DEATH_EXIT_W * scaleX;
|
|
float exitH = DEATH_EXIT_H * scaleY;
|
|
|
|
struct nk_rect exitRect = nk_rect(exitX, exitY, exitW, exitH);
|
|
bool exitHover = nk_input_is_mouse_hovering_rect(input, exitRect) != 0;
|
|
if (drawBtnWithShadow(ctx, "Exit Game", exitX, exitY, exitW, exitH, exitHover, tex)) {
|
|
result = kMenuAction_ExitGame;
|
|
}
|
|
|
|
drawControllerPrompts(ctx, winW, winH, tex);
|
|
}
|
|
nk_end(ctx);
|
|
|
|
popCleanStyle(ctx);
|
|
|
|
return result;
|
|
}
|
|
|
|
}}
|