Files
coah80-LegacyVulkEdition/Minecraft.Client/CrossPlatform/NkBrowseMenus2.cpp

699 lines
26 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 "NkBrowseMenus.h"
#include "NkCommon.h"
#include "MenuScreens.h"
#include "NuklearBridge.h"
#include <cstring>
#include <cstdio>
namespace lve { namespace ui {
static const float BASE_W = 1280.0f;
static const float BASE_H = 720.0f;
static const float TITLE_Y_POS = 30.0f;
static const float TITLE_H_POS = 40.0f;
static const float BTN_H = 32.0f;
static const float SHADOW_OFF = 2.0f;
static const float LB_HEADER_Y = 80.0f;
static const float LB_HEADER_H = 36.0f;
static const float LB_FILTER_Y = 120.0f;
static const float LB_FILTER_H = 28.0f;
static const float LB_LIST_Y = 160.0f;
static const float LB_ROW_H = 32.0f;
static const float LB_ICON_SIZE = 24.0f;
static const float LB_COL_RANK_W = 80.0f;
static const float LB_COL_NAME_W = 200.0f;
static const float LB_COL_STAT_W = 80.0f;
static const float DLC_LIST_X = 40.0f;
static const float DLC_LIST_Y = 120.0f;
static const float DLC_LIST_W = 400.0f;
static const float DLC_ROW_H = 40.0f;
static const float DLC_PREVIEW_X = 500.0f;
static const float DLC_PREVIEW_Y = 120.0f;
static const float DLC_PREVIEW_W = 720.0f;
static const float DLC_PREVIEW_H = 400.0f;
static const float DLC_PRICE_Y = 540.0f;
static const float DLC_PRICE_H = 30.0f;
static const float DLC_DESC_Y = 530.0f;
static const float DLC_DESC_H = 140.0f;
static const float CTRL_IMAGE_X = 290.0f;
static const float CTRL_IMAGE_Y = 160.0f;
static const float CTRL_IMAGE_W = 700.0f;
static const float CTRL_IMAGE_H = 400.0f;
static const float CTRL_CHECKBOX_X = 40.0f;
static const float CTRL_CHECKBOX_Y = 580.0f;
static const float CTRL_CHECKBOX_W = 250.0f;
static const float CTRL_CHECKBOX_H = 30.0f;
static const float CTRL_LAYOUT_X = 415.0f;
static const float CTRL_LAYOUT_Y = 120.0f;
static const float CTRL_LAYOUT_W = 140.0f;
static const float CTRL_LAYOUT_H = 36.0f;
static const float CTRL_LAYOUT_STEP = 8.0f;
static void drawShadowedText(nk_context *ctx, const char *text,
float x, float y, float w, float h,
struct nk_color color, bool centered)
{
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
if (canvas == nullptr) return;
const struct nk_user_font *font = ctx->style.font;
if (font == nullptr) return;
int len = (int)strlen(text);
float textW = font->width(font->userdata, font->height, text, len);
float textX = centered ? x + (w - textW) * 0.5f : x;
float textY = y + (h - font->height) * 0.5f;
nk_draw_text(canvas, nk_rect(textX + SHADOW_OFF, textY + SHADOW_OFF, textW, font->height),
text, len, font,
nk_rgba(0, 0, 0, 0), nk_rgba(0x0F, 0x0F, 0x0F, 200));
nk_draw_text(canvas, nk_rect(textX, textY, textW, font->height),
text, len, font,
nk_rgba(0, 0, 0, 0), color);
}
static void drawShadowedTitle(nk_context *ctx, const char *title, int winW, int winH)
{
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
if (canvas == nullptr) return;
nk_font *titleNkFont = getTitleFont();
const struct nk_user_font *font = titleNkFont ? &titleNkFont->handle : ctx->style.font;
if (font == nullptr) return;
float scaleY = (float)winH / BASE_H;
float y = TITLE_Y_POS * scaleY;
float h = TITLE_H_POS * scaleY;
int len = (int)strlen(title);
float textW = font->width(font->userdata, font->height, title, len);
float textX = ((float)winW - textW) * 0.5f;
float textY = y + (h - font->height) * 0.5f;
nk_draw_text(canvas, nk_rect(textX + SHADOW_OFF, textY + SHADOW_OFF, textW, font->height),
title, len, font,
nk_rgba(0, 0, 0, 0), nk_rgba(0x0F, 0x0F, 0x0F, 200));
nk_draw_text(canvas, nk_rect(textX, textY, textW, font->height),
title, len, font,
nk_rgba(0, 0, 0, 0), nk_rgb(255, 255, 255));
}
static bool drawTabButton(nk_context *ctx, const char *label,
float x, float y, float w, float h,
bool selected, BrowseMenuTextures &btex)
{
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
if (canvas == nullptr) return false;
struct nk_rect r = nk_rect(x, y, w, h);
const struct nk_input *input = &ctx->input;
bool hovering = nk_input_is_mouse_hovering_rect(input, r) != 0;
if (btex.loaded) {
const MenuTextureSlot *slot;
if (selected) {
slot = hovering ? &btex.tabOverSelected : &btex.tabNormalSelected;
} else {
slot = hovering ? &btex.tabOver : &btex.tabNormal;
}
struct nk_image img = slotToNkImage(*slot);
nk_draw_image(canvas, r, &img, nk_rgb(255, 255, 255));
} else {
struct nk_color bg = selected ? nk_rgb(60, 60, 80) : nk_rgb(40, 40, 40);
if (hovering) bg = nk_rgb(80, 80, 100);
nk_fill_rect(canvas, r, 0, bg);
nk_stroke_rect(canvas, r, 0, 1.0f, nk_rgb(100, 100, 100));
}
drawShadowedText(ctx, label, x, y, w, h, nk_rgb(255, 255, 255), true);
bool clicked = hovering && nk_input_is_mouse_released(input, NK_BUTTON_LEFT) != 0;
return clicked;
}
static bool drawListRow(nk_context *ctx, const char *label,
float x, float y, float w, float h,
bool selected, bool hasTick,
BrowseMenuTextures &btex)
{
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
if (canvas == nullptr) return false;
struct nk_rect r = nk_rect(x, y, w, h);
const struct nk_input *input = &ctx->input;
bool hovering = nk_input_is_mouse_hovering_rect(input, r) != 0;
if (btex.loaded) {
const MenuTextureSlot *slot;
if (selected || hovering)
slot = &btex.listBtnOver;
else
slot = &btex.listBtnNorm;
struct nk_image img = slotToNkImage(*slot);
nk_draw_image(canvas, r, &img, nk_rgb(255, 255, 255));
} else {
struct nk_color bg = (selected || hovering) ? nk_rgb(70, 70, 70) : nk_rgb(40, 40, 40);
nk_fill_rect(canvas, r, 0, bg);
nk_stroke_rect(canvas, r, 0, 1.0f, nk_rgb(80, 80, 80));
}
if (hasTick && btex.loaded) {
float tickS = h * 0.6f;
float tickX = x + w - tickS - 4.0f;
float tickY = y + (h - tickS) * 0.5f;
struct nk_image tickImg = slotToNkImage(btex.dlcTickSmall);
nk_draw_image(canvas, nk_rect(tickX, tickY, tickS, tickS),
&tickImg, nk_rgb(255, 255, 255));
}
drawShadowedText(ctx, label, x + 8.0f, y, w - 16.0f, h, nk_rgb(255, 255, 255), false);
bool clicked = hovering && nk_input_is_mouse_released(input, NK_BUTTON_LEFT) != 0;
return clicked;
}
static bool drawCheckbox(nk_context *ctx, const char *label,
float x, float y, float w, float h,
bool checked, MenuTextures &tex)
{
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
if (canvas == nullptr) return false;
const struct nk_input *input = &ctx->input;
struct nk_rect fullRect = nk_rect(x, y, w, h);
bool hovering = nk_input_is_mouse_hovering_rect(input, fullRect) != 0;
float boxSize = h * 0.7f;
float boxX = x;
float boxY = y + (h - boxSize) * 0.5f;
if (tex.checkboxBackground.w > 0) {
struct nk_image bgImg = slotToNkImage(hovering ? tex.checkboxHover : tex.checkboxBackground);
nk_draw_image(canvas, nk_rect(boxX, boxY, boxSize, boxSize), &bgImg, nk_rgb(255, 255, 255));
} else {
nk_fill_rect(canvas, nk_rect(boxX, boxY, boxSize, boxSize), 0, nk_rgb(40, 40, 40));
nk_stroke_rect(canvas, nk_rect(boxX, boxY, boxSize, boxSize), 0, 1.0f,
hovering ? nk_rgb(180, 180, 200) : nk_rgb(120, 120, 120));
}
if (checked) {
if (tex.checkboxTick.w > 0) {
struct nk_image tickImg = slotToNkImage(tex.checkboxTick);
nk_draw_image(canvas, nk_rect(boxX, boxY, boxSize, boxSize), &tickImg, nk_rgb(255, 255, 255));
} else {
float inset = boxSize * 0.2f;
nk_fill_rect(canvas, nk_rect(boxX + inset, boxY + inset,
boxSize - 2.0f * inset, boxSize - 2.0f * inset),
0, nk_rgb(255, 255, 255));
}
}
float labelX = boxX + boxSize + 8.0f;
drawShadowedText(ctx, label, labelX, y, w - boxSize - 8.0f, h, nk_rgb(255, 255, 255), false);
bool clicked = hovering && nk_input_is_mouse_released(input, NK_BUTTON_LEFT) != 0;
return clicked;
}
static const char *CTRL_SCHEME_LABELS[] = {
"1", "2", "3"
};
static const int CTRL_SCHEME_COUNT = 3;
static const char *CTRL_SCHEME_NAMES[] = {
"Default", "Lefty", "Legacy"
};
struct ControlBinding {
const char *label;
float x;
float y;
};
void renderControlsMenu(nk_context *ctx, int winW, int winH,
MenuTextures &tex, BrowseMenuTextures &btex)
{
static int currentScheme = 0;
static bool invertLook = false;
static bool southpaw = false;
float scaleX = (float)winW / BASE_W;
float scaleY = (float)winH / BASE_H;
pushCleanStyle(ctx);
if (nk_begin(ctx, "ControlsMenu", nk_rect(0, 0, (float)winW, (float)winH),
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_NO_INPUT | NK_WINDOW_BACKGROUND)) {
drawPanoramaBg(ctx, winW, winH, tex);
drawShadowedTitle(ctx, "Controls", winW, winH);
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
const struct nk_input *input = &ctx->input;
float layoutX = CTRL_LAYOUT_X * scaleX;
float layoutY = CTRL_LAYOUT_Y * scaleY;
float layoutW = CTRL_LAYOUT_W * scaleX;
float layoutH = CTRL_LAYOUT_H * scaleY;
for (int i = 0; i < CTRL_SCHEME_COUNT; i++) {
float bx = layoutX + (float)i * (layoutW + CTRL_LAYOUT_STEP * scaleX);
bool selected = (currentScheme == i);
if (drawTabButton(ctx, CTRL_SCHEME_LABELS[i], bx, layoutY, layoutW, layoutH, selected, btex)) {
currentScheme = i;
}
}
char currentLabel[128];
snprintf(currentLabel, sizeof(currentLabel), "Current Layout : %s", CTRL_SCHEME_NAMES[currentScheme]);
float clY = layoutY + layoutH + 8.0f * scaleY;
drawShadowedText(ctx, currentLabel, 0, clY, (float)winW, 24.0f * scaleY, nk_rgb(255, 255, 200), true);
float imgX = CTRL_IMAGE_X * scaleX;
float imgY = CTRL_IMAGE_Y * scaleY;
float imgW = CTRL_IMAGE_W * scaleX;
float imgH = CTRL_IMAGE_H * scaleY;
if (canvas != nullptr) {
nk_fill_rect(canvas, nk_rect(imgX, imgY, imgW, imgH), 0, nk_rgba(0, 0, 0, 100));
}
ControlBinding bindings[] = {
{ "Jump", 0.15f, 0.30f },
{ "Inventory", 0.15f, 0.45f },
{ "Sneak", 0.15f, 0.60f },
{ "Move", 0.15f, 0.75f },
{ "Use", 0.80f, 0.30f },
{ "Attack", 0.80f, 0.45f },
{ "Look", 0.80f, 0.60f },
{ "Held Item", 0.80f, 0.75f },
};
int bindingCount = 8;
if (southpaw) {
bindings[3].label = "Look";
bindings[6].label = "Move";
}
const struct nk_user_font *font = ctx->style.font;
if (font != nullptr && canvas != nullptr) {
for (int i = 0; i < bindingCount; i++) {
float bx = imgX + bindings[i].x * imgW;
float by = imgY + bindings[i].y * imgH;
int len = (int)strlen(bindings[i].label);
float tw = font->width(font->userdata, font->height, bindings[i].label, len);
float tx = bx - tw * 0.5f;
nk_draw_text(canvas, nk_rect(tx + SHADOW_OFF, by + SHADOW_OFF, tw, font->height),
bindings[i].label, len, font,
nk_rgba(0, 0, 0, 0), nk_rgba(0x0F, 0x0F, 0x0F, 200));
nk_draw_text(canvas, nk_rect(tx, by, tw, font->height),
bindings[i].label, len, font,
nk_rgba(0, 0, 0, 0), nk_rgb(255, 255, 255));
}
}
float cbX = CTRL_CHECKBOX_X * scaleX;
float cbY = CTRL_CHECKBOX_Y * scaleY;
float cbW = CTRL_CHECKBOX_W * scaleX;
float cbH = CTRL_CHECKBOX_H * scaleY;
if (drawCheckbox(ctx, "Invert Look", cbX, cbY, cbW, cbH, invertLook, tex))
invertLook = !invertLook;
float spY = cbY + cbH + 8.0f * scaleY;
if (drawCheckbox(ctx, "Southpaw", cbX, spY, cbW, cbH, southpaw, tex))
southpaw = !southpaw;
drawControllerPrompts(ctx, winW, winH, tex);
}
nk_end(ctx);
popCleanStyle(ctx);
}
static const int LB_CATEGORY_COUNT = 4;
static const char *LB_CATEGORY_LABELS[LB_CATEGORY_COUNT] = {
"Travelling", "Mining", "Farming", "Kills"
};
static const int LB_DIFFICULTY_COUNT = 4;
static const char *LB_DIFFICULTY_LABELS[LB_DIFFICULTY_COUNT] = {
"Peaceful", "Easy", "Normal", "Hard"
};
static const char *LB_FILTER_LABELS[] = {
"Friends", "My Score", "Overall"
};
static const int LB_FILTER_COUNT = 3;
struct LbColumnIcon {
const char *name;
MenuTextureSlot *icon;
};
void renderLeaderboardsMenu(nk_context *ctx, int winW, int winH,
MenuTextures &tex, BrowseMenuTextures &btex)
{
static int currentCategory = 0;
static int currentDifficulty = 2;
static int currentFilter = 0;
static int selectedRow = 0;
float scaleX = (float)winW / BASE_W;
float scaleY = (float)winH / BASE_H;
pushCleanStyle(ctx);
if (nk_begin(ctx, "LeaderboardsMenu", nk_rect(0, 0, (float)winW, (float)winH),
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_NO_INPUT | NK_WINDOW_BACKGROUND)) {
drawPanoramaBg(ctx, winW, winH, tex);
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
const struct nk_input *input = &ctx->input;
float headerY = LB_HEADER_Y * scaleY;
float headerH = LB_HEADER_H * scaleY;
float catTabW = 140.0f * scaleX;
float totalCatW = (float)LB_CATEGORY_COUNT * catTabW + (float)(LB_CATEGORY_COUNT - 1) * 4.0f * scaleX;
float catStartX = ((float)winW - totalCatW) * 0.5f;
for (int i = 0; i < LB_CATEGORY_COUNT; i++) {
float tx = catStartX + (float)i * (catTabW + 4.0f * scaleX);
bool selected = (currentCategory == i);
if (drawTabButton(ctx, LB_CATEGORY_LABELS[i], tx, headerY, catTabW, headerH, selected, btex)) {
currentCategory = i;
if (currentCategory == 3 && currentDifficulty == 0)
currentDifficulty = 1;
}
}
float diffY = headerY + headerH + 4.0f * scaleY;
float diffTabW = 100.0f * scaleX;
float diffH = 28.0f * scaleY;
float totalDiffW = (float)LB_DIFFICULTY_COUNT * diffTabW + (float)(LB_DIFFICULTY_COUNT - 1) * 4.0f * scaleX;
float diffStartX = ((float)winW - totalDiffW) * 0.5f;
for (int i = 0; i < LB_DIFFICULTY_COUNT; i++) {
if (currentCategory == 3 && i == 0) continue;
float dx = diffStartX + (float)i * (diffTabW + 4.0f * scaleX);
bool selected = (currentDifficulty == i);
if (drawTabButton(ctx, LB_DIFFICULTY_LABELS[i], dx, diffY, diffTabW, diffH, selected, btex)) {
currentDifficulty = i;
}
}
float filterY = LB_FILTER_Y * scaleY + headerH;
float filterH = LB_FILTER_H * scaleY;
char filterBuf[64];
snprintf(filterBuf, sizeof(filterBuf), "Filter: %s", LB_FILTER_LABELS[currentFilter]);
float filterBtnW = 200.0f * scaleX;
float filterBtnX = ((float)winW - filterBtnW) * 0.5f;
struct nk_rect filterRect = nk_rect(filterBtnX, filterY, filterBtnW, filterH);
bool filterHover = nk_input_is_mouse_hovering_rect(input, filterRect) != 0;
if (drawBtn(ctx, filterBuf, filterBtnX, filterY, filterBtnW, filterH, filterHover, winH, tex)) {
currentFilter = (currentFilter + 1) % LB_FILTER_COUNT;
}
float listY = LB_LIST_Y * scaleY + headerH;
float rowH = LB_ROW_H * scaleY;
float listX = 40.0f * scaleX;
float listW = (float)winW - 80.0f * scaleX;
float rankW = LB_COL_RANK_W * scaleX;
float nameW = LB_COL_NAME_W * scaleX;
if (canvas != nullptr) {
drawShadowedText(ctx, "Rank", listX, listY, rankW, rowH, nk_rgb(200, 200, 200), false);
drawShadowedText(ctx, "Gamertag", listX + rankW, listY, nameW, rowH, nk_rgb(200, 200, 200), false);
}
LbColumnIcon travelIcons[] = {
{ "Walked", &btex.lbIconWalkedSmall },
{ "Fallen", &btex.lbIconFallenSmall },
};
static const char *travelExtraHeaders[] = { "Minecart", "Boat" };
static const int travelExtraCount = 2;
LbColumnIcon killIcons[] = {
{ "Zombie", &btex.lbIconZombieSmall },
{ "Skeleton", &btex.lbIconSkeletonSmall },
{ "Creeper", &btex.lbIconCreeperSmall },
{ "Spider", &btex.lbIconSpiderSmall },
{ "Sp.Jockey", &btex.lbIconSpiderJockeySmall },
{ "Z.Pigman", &btex.lbIconZombiePigmanSmall },
{ "Slime", &btex.lbIconSlimeSmall },
};
static const char *miningHeaders[] = {
"Dirt", "Stone", "Sand", "Rock", "Gravel", "Clay", "Obsidian"
};
static const int miningHeaderCount = 7;
static const char *farmingHeaders[] = {
"Eggs", "Wheat", "Shroom", "Reeds", "Milk", "Pumpkin"
};
static const int farmingHeaderCount = 6;
int iconCount = 0;
LbColumnIcon *icons = nullptr;
if (currentCategory == 0) { icons = travelIcons; iconCount = 2; }
else if (currentCategory == 3) { icons = killIcons; iconCount = 7; }
float iconStartX = listX + rankW + nameW;
float iconSize = LB_ICON_SIZE * scaleY;
float colStatW = LB_COL_STAT_W * scaleX;
if (canvas != nullptr && icons != nullptr && btex.loaded) {
for (int i = 0; i < iconCount; i++) {
float ix = iconStartX + (float)i * colStatW;
float iy = listY + (rowH - iconSize) * 0.5f;
struct nk_image iconImg = slotToNkImage(*icons[i].icon);
nk_draw_image(canvas, nk_rect(ix, iy, iconSize, iconSize),
&iconImg, nk_rgb(255, 255, 255));
}
}
if (canvas != nullptr && currentCategory == 0) {
for (int i = 0; i < travelExtraCount; i++) {
float hx = iconStartX + (float)(iconCount + i) * colStatW;
drawShadowedText(ctx, travelExtraHeaders[i], hx, listY, colStatW, rowH,
nk_rgb(200, 200, 200), true);
}
}
if (canvas != nullptr && currentCategory == 1) {
for (int i = 0; i < miningHeaderCount; i++) {
float hx = iconStartX + (float)i * colStatW;
drawShadowedText(ctx, miningHeaders[i], hx, listY, colStatW, rowH,
nk_rgb(200, 200, 200), true);
}
}
if (canvas != nullptr && currentCategory == 2) {
for (int i = 0; i < farmingHeaderCount; i++) {
float hx = iconStartX + (float)i * colStatW;
drawShadowedText(ctx, farmingHeaders[i], hx, listY, colStatW, rowH,
nk_rgb(200, 200, 200), true);
}
}
float dataY = listY + rowH + 2.0f * scaleY;
int visibleRows = 10;
drawShadowedText(ctx, "Loading...",
listX, dataY, listW, rowH * (float)visibleRows,
nk_rgb(180, 180, 180), true);
float entriesY = (float)winH - 40.0f * scaleY;
drawShadowedText(ctx, "Entries: 0", listX, entriesY, 200.0f * scaleX, 24.0f * scaleY,
nk_rgb(180, 180, 180), false);
drawControllerPrompts(ctx, winW, winH, tex);
}
nk_end(ctx);
popCleanStyle(ctx);
}
static const int DLC_MAIN_BUTTON_COUNT = 3;
static const char *DLC_MAIN_LABELS[DLC_MAIN_BUTTON_COUNT] = {
"Skin Packs",
"Texture Packs",
"Mash-up Packs"
};
void renderDLCMainMenu(nk_context *ctx, int winW, int winH,
MenuTextures &tex, BrowseMenuTextures &btex)
{
static int selectedItem = -1;
float scaleX = (float)winW / BASE_W;
float scaleY = (float)winH / BASE_H;
pushCleanStyle(ctx);
if (nk_begin(ctx, "DLCMainMenu", nk_rect(0, 0, (float)winW, (float)winH),
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_NO_INPUT | NK_WINDOW_BACKGROUND)) {
drawPanoramaBg(ctx, winW, winH, tex);
drawShadowedTitle(ctx, "Downloadable Content", winW, winH);
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
float labelY = 80.0f * scaleY;
float labelH = 28.0f * scaleY;
drawShadowedText(ctx, "Downloadable Content Offers",
0, labelY, (float)winW, labelH, nk_rgb(200, 200, 200), true);
float listX = DLC_LIST_X * scaleX;
float listY = DLC_LIST_Y * scaleY;
float listW = DLC_LIST_W * scaleX;
float rowH = DLC_ROW_H * scaleY;
const struct nk_input *input = &ctx->input;
for (int i = 0; i < DLC_MAIN_BUTTON_COUNT; i++) {
float by = listY + (float)i * (rowH + 4.0f * scaleY);
bool selected = (selectedItem == i);
if (drawListRow(ctx, DLC_MAIN_LABELS[i], listX, by, listW, rowH, selected, false, btex)) {
selectedItem = i;
}
}
if (canvas != nullptr && btex.loaded) {
float bgX = DLC_PREVIEW_X * scaleX;
float bgY = DLC_PREVIEW_Y * scaleY;
float bgW = DLC_PREVIEW_W * scaleX;
float bgH = DLC_PREVIEW_H * scaleY;
struct nk_image dlcBgImg = slotToNkImage(btex.dlcBg);
nk_draw_image(canvas, nk_rect(bgX, bgY, bgW, bgH),
&dlcBgImg, nk_rgb(255, 255, 255));
}
drawControllerPrompts(ctx, winW, winH, tex);
}
nk_end(ctx);
popCleanStyle(ctx);
}
void renderDLCOffersMenu(nk_context *ctx, int winW, int winH,
MenuTextures &tex, BrowseMenuTextures &btex)
{
static int selectedOffer = 0;
float scaleX = (float)winW / BASE_W;
float scaleY = (float)winH / BASE_H;
pushCleanStyle(ctx);
if (nk_begin(ctx, "DLCOffersMenu", nk_rect(0, 0, (float)winW, (float)winH),
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_NO_INPUT | NK_WINDOW_BACKGROUND)) {
drawPanoramaBg(ctx, winW, winH, tex);
drawShadowedTitle(ctx, "Downloadable Content Offers", winW, winH);
struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
float listX = DLC_LIST_X * scaleX;
float listY = DLC_LIST_Y * scaleY;
float listW = DLC_LIST_W * scaleX;
float rowH = DLC_ROW_H * scaleY;
const struct nk_input *input = &ctx->input;
const char *placeholderOffers[] = {
"Skin Pack 1 (Trial)",
"Battle & Beasts Skin Pack",
"Natural Texture Pack",
"City Texture Pack",
"Greek Mythology Mash-up",
"Festive Skin Pack"
};
int offerCount = 6;
bool purchased[] = { false, true, false, false, true, false };
for (int i = 0; i < offerCount; i++) {
float by = listY + (float)i * (rowH + 4.0f * scaleY);
bool selected = (selectedOffer == i);
if (drawListRow(ctx, placeholderOffers[i], listX, by, listW, rowH, selected, purchased[i], btex)) {
selectedOffer = i;
}
}
if (canvas != nullptr && btex.loaded) {
float bgX = DLC_PREVIEW_X * scaleX;
float bgY = DLC_PREVIEW_Y * scaleY;
float bgW = DLC_PREVIEW_W * scaleX;
float bgH = DLC_PREVIEW_H * scaleY;
struct nk_image dlcBgImg2 = slotToNkImage(btex.dlcBg);
nk_draw_image(canvas, nk_rect(bgX, bgY, bgW, bgH),
&dlcBgImg2, nk_rgb(255, 255, 255));
}
float descX = DLC_PREVIEW_X * scaleX;
float descY = DLC_DESC_Y * scaleY;
float descW = DLC_PREVIEW_W * scaleX;
float descH = DLC_DESC_H * scaleY;
if (selectedOffer >= 0 && selectedOffer < offerCount) {
drawShadowedText(ctx, placeholderOffers[selectedOffer],
descX, descY, descW, 24.0f * scaleY, nk_rgb(255, 255, 255), false);
}
float priceY = DLC_PRICE_Y * scaleY;
float priceH = DLC_PRICE_H * scaleY;
if (selectedOffer >= 0 && selectedOffer < offerCount) {
const char *price = purchased[selectedOffer] ? "Purchased" : "Free";
drawShadowedText(ctx, price, descX, priceY + descH, descW, priceH, nk_rgb(100, 255, 100), false);
}
float installBtnW = 160.0f * scaleX;
float installBtnH = BTN_H * scaleY;
float installBtnX = descX + descW - installBtnW;
float installBtnY = priceY + descH + priceH + 8.0f * scaleY;
if (selectedOffer >= 0 && selectedOffer < offerCount) {
const char *installLabel = purchased[selectedOffer] ? "Reinstall" : "Install";
struct nk_rect installRect = nk_rect(installBtnX, installBtnY, installBtnW, installBtnH);
bool installHover = nk_input_is_mouse_hovering_rect(input, installRect) != 0;
drawBtn(ctx, installLabel, installBtnX, installBtnY, installBtnW, installBtnH, installHover, winH, tex);
}
drawControllerPrompts(ctx, winW, winH, tex);
}
nk_end(ctx);
popCleanStyle(ctx);
}
}}