mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-24 18:13:15 -05:00
Port MenuOptionsScreen to C.
This commit is contained in:
parent
dfe3acb785
commit
783b4e0360
26 changed files with 359 additions and 94 deletions
|
@ -39,7 +39,7 @@ namespace ClassicalSharp.Gui.Screens {
|
|||
}
|
||||
|
||||
protected override void ContextRecreated() {
|
||||
ClickHandler onClick = OnButtonClick;
|
||||
ClickHandler onClick = OnInputClick;
|
||||
ClickHandler onEnum = OnEnumClick;
|
||||
|
||||
widgets = new Widget[] {
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace ClassicalSharp.Gui.Screens {
|
|||
}
|
||||
|
||||
protected override void ContextRecreated() {
|
||||
ClickHandler onClick = OnButtonClick;
|
||||
ClickHandler onClick = OnInputClick;
|
||||
ClickHandler onEnum = OnEnumClick;
|
||||
ClickHandler onBool = OnBoolClick;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace ClassicalSharp.Gui.Screens {
|
|||
}
|
||||
|
||||
protected override void ContextRecreated() {
|
||||
ClickHandler onClick = OnButtonClick;
|
||||
ClickHandler onClick = OnInputClick;
|
||||
ClickHandler onBool = OnBoolClick;
|
||||
|
||||
widgets = new Widget[] {
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace ClassicalSharp.Gui.Screens {
|
|||
}
|
||||
|
||||
protected override void ContextRecreated() {
|
||||
ClickHandler onClick = OnButtonClick;
|
||||
ClickHandler onClick = OnInputClick;
|
||||
ClickHandler onBool = OnBoolClick;
|
||||
|
||||
widgets = new Widget[] {
|
||||
|
|
|
@ -11,10 +11,10 @@ namespace ClassicalSharp.Gui.Screens {
|
|||
|
||||
protected MenuInputValidator[] validators;
|
||||
protected string[][] descriptions;
|
||||
protected TextGroupWidget extendedHelp;
|
||||
protected InputWidget input;
|
||||
protected string[] defaultValues;
|
||||
protected int activeI = -1, selectedI = -1;
|
||||
TextGroupWidget extHelp;
|
||||
InputWidget input;
|
||||
|
||||
public override void Init() {
|
||||
base.Init();
|
||||
|
@ -24,14 +24,14 @@ namespace ClassicalSharp.Gui.Screens {
|
|||
static FastColour tableCol = new FastColour(20, 20, 20, 200);
|
||||
public override void Render(double delta) {
|
||||
base.Render(delta);
|
||||
if (extendedHelp == null) return;
|
||||
if (extHelp == null) return;
|
||||
|
||||
int x = extendedHelp.X - 5, y = extendedHelp.Y - 5;
|
||||
int width = extendedHelp.Width, height = extendedHelp.Height;
|
||||
int x = extHelp.X - 5, y = extHelp.Y - 5;
|
||||
int width = extHelp.Width, height = extHelp.Height;
|
||||
game.Graphics.Draw2DQuad(x, y, width + 10, height + 10, tableCol);
|
||||
|
||||
game.Graphics.Texturing = true;
|
||||
extendedHelp.Render(delta);
|
||||
extHelp.Render(delta);
|
||||
game.Graphics.Texturing = false;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ namespace ClassicalSharp.Gui.Screens {
|
|||
|
||||
public override void OnResize(int width, int height) {
|
||||
base.OnResize(width, height);
|
||||
if (extendedHelp == null) return;
|
||||
if (extHelp == null) return;
|
||||
RepositionExtendedHelp();
|
||||
}
|
||||
|
||||
|
@ -111,26 +111,26 @@ namespace ClassicalSharp.Gui.Screens {
|
|||
string[] desc = descriptions[idx];
|
||||
if (desc == null) return;
|
||||
|
||||
extendedHelp = new TextGroupWidget(game, desc.Length, textFont, null)
|
||||
extHelp = new TextGroupWidget(game, desc.Length, textFont, null)
|
||||
.SetLocation(Anchor.Min, Anchor.Min, 0, 0);
|
||||
extendedHelp.Init();
|
||||
extHelp.Init();
|
||||
|
||||
for (int i = 0; i < desc.Length; i++) {
|
||||
extendedHelp.SetText(i, desc[i]);
|
||||
extHelp.SetText(i, desc[i]);
|
||||
}
|
||||
RepositionExtendedHelp();
|
||||
}
|
||||
|
||||
void RepositionExtendedHelp() {
|
||||
extendedHelp.XOffset = game.Width / 2 - extendedHelp.Width / 2;
|
||||
extendedHelp.YOffset = game.Height / 2 + 100;
|
||||
extendedHelp.Reposition();
|
||||
extHelp.XOffset = game.Width / 2 - extHelp.Width / 2;
|
||||
extHelp.YOffset = game.Height / 2 + 100;
|
||||
extHelp.Reposition();
|
||||
}
|
||||
|
||||
void DisposeExtendedHelp() {
|
||||
if (extendedHelp == null) return;
|
||||
extendedHelp.Dispose();
|
||||
extendedHelp = null;
|
||||
if (extHelp == null) return;
|
||||
extHelp.Dispose();
|
||||
extHelp = null;
|
||||
}
|
||||
|
||||
void SetButtonValue(int index, string text) {
|
||||
|
@ -159,26 +159,25 @@ namespace ClassicalSharp.Gui.Screens {
|
|||
MenuInputValidator validator = validators[index];
|
||||
Type type = ((EnumValidator)validator).EnumType;
|
||||
|
||||
string rawName = button.GetValue(game);
|
||||
int value = (int)Enum.Parse(type, rawName, true) + 1;
|
||||
// go back to first value
|
||||
if (!Enum.IsDefined(type, value)) value = 0;
|
||||
string value = button.GetValue(game);
|
||||
int raw = (int)Enum.Parse(type, value, true) + 1;
|
||||
if (!Enum.IsDefined(type, raw)) raw = 0; // go back to first value
|
||||
|
||||
SetButtonValue(index, Enum.GetName(type, value));
|
||||
SetButtonValue(index, Enum.GetName(type, raw));
|
||||
}
|
||||
|
||||
protected void OnButtonClick(Game game, Widget widget) {
|
||||
protected void OnInputClick(Game game, Widget widget) {
|
||||
ButtonWidget button = (ButtonWidget)widget;
|
||||
activeI = IndexWidget(button);
|
||||
SelectExtendedHelp(activeI);
|
||||
|
||||
DisposeInput();
|
||||
MenuInputValidator validator = validators[activeI];
|
||||
MenuInputValidator validator = validators[activeI];
|
||||
input = MenuInputWidget.Create(game, 400, 30, button.GetValue(game), textFont, validator)
|
||||
.SetLocation(Anchor.Centre, Anchor.Centre, 0, 110);
|
||||
input.ShowCaret = true;
|
||||
|
||||
widgets[widgets.Length - 1] = input;
|
||||
widgets[widgets.Length - 1] = input;
|
||||
widgets[widgets.Length - 2] = ButtonWidget.Create(game, 40, "OK", titleFont, OKButtonClick)
|
||||
.SetLocation(Anchor.Centre, Anchor.Centre, 240, 110);
|
||||
widgets[widgets.Length - 3] = ButtonWidget.Create(game, 200, "Default value", titleFont, DefaultButtonClick)
|
||||
|
@ -188,7 +187,7 @@ namespace ClassicalSharp.Gui.Screens {
|
|||
void OKButtonClick(Game game, Widget widget) { EnterInput(); }
|
||||
|
||||
void DefaultButtonClick(Game game, Widget widget) {
|
||||
string defValue = defaultValues[activeI];
|
||||
string defValue = defaultValues[activeI];
|
||||
input.Clear();
|
||||
input.Append(defValue);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace ClassicalSharp.Gui.Screens {
|
|||
|
||||
protected override void ContextRecreated() {
|
||||
bool multi = !game.Server.IsSinglePlayer;
|
||||
ClickHandler onClick = OnButtonClick;
|
||||
ClickHandler onClick = OnInputClick;
|
||||
ClickHandler onBool = OnBoolClick;
|
||||
|
||||
widgets = new Widget[] {
|
||||
|
|
|
@ -241,8 +241,7 @@ bool Animations_IsDefaultZip(void) {
|
|||
String texPack = String_InitAndClearArray(texPackBuffer);
|
||||
|
||||
Options_Get(OPTION_DEFAULT_TEX_PACK, &texPack);
|
||||
String defaultZip = String_FromConst("default.zip");
|
||||
return texPack.length == 0 || String_CaselessEquals(&texPack, &defaultZip);
|
||||
return texPack.length == 0 || String_CaselessEqualsConst(&texPack, "default.zip");
|
||||
}
|
||||
|
||||
void Animations_Clear(void) {
|
||||
|
@ -316,21 +315,14 @@ void Animations_PackChanged(void* obj) {
|
|||
}
|
||||
|
||||
void Animations_FileChanged(void* obj, Stream* stream) {
|
||||
String animPng = String_FromConst("animation.png");
|
||||
String animsPng = String_FromConst("animations.png");
|
||||
String animTxt = String_FromConst("animation.txt");
|
||||
String animsTxt = String_FromConst("animations.txt");
|
||||
String lavaAnim = String_FromConst("uselavaanim");
|
||||
String waterAnim = String_FromConst("usewateranim");
|
||||
|
||||
String* name = &stream->Name;
|
||||
if (String_CaselessEquals(name, &animPng) || String_CaselessEquals(name, &animsPng)) {
|
||||
if (String_CaselessEqualsConst(name, "animation.png") || String_CaselessEqualsConst(name, "animations.png")) {
|
||||
Bitmap_DecodePng(&anims_bmp, stream);
|
||||
} else if (String_CaselessEquals(name, &animTxt) || String_CaselessEquals(name, &animsTxt)) {
|
||||
} else if (String_CaselessEqualsConst(name, "animation.txt") || String_CaselessEqualsConst(name, "animations.txt")) {
|
||||
Animations_ReadDescription(stream);
|
||||
} else if (String_CaselessEquals(name, &lavaAnim)) {
|
||||
} else if (String_CaselessEqualsConst(name, "uselavaanim")) {
|
||||
anims_useLavaAnim = true;
|
||||
} else if (String_CaselessEquals(name, &waterAnim)) {
|
||||
} else if (String_CaselessEqualsConst(name, "usewateranim")) {
|
||||
anims_useWaterAnim = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -371,8 +371,7 @@ bool cuboid_persist = false;
|
|||
|
||||
bool CuboidCommand_ParseBlock(STRING_PURE String* args, UInt32 argsCount) {
|
||||
if (argsCount == 1) return true;
|
||||
String yes = String_FromConst("yes");
|
||||
if (String_CaselessEquals(&args[1], &yes)) { cuboid_persist = true; return true; }
|
||||
if (String_CaselessEqualsConst(&args[1], "yes")) { cuboid_persist = true; return true; }
|
||||
|
||||
Int32 temp = Block_FindID(&args[1]);
|
||||
BlockID block = 0;
|
||||
|
@ -447,8 +446,7 @@ void CuboidCommand_Execute(STRING_PURE String* args, UInt32 argsCount) {
|
|||
cuboid_persist = false;
|
||||
|
||||
if (!CuboidCommand_ParseBlock(args, argsCount)) return;
|
||||
String yes = String_FromConst("yes");
|
||||
if (argsCount > 2 && String_CaselessEquals(&args[2], &yes)) {
|
||||
if (argsCount > 2 && String_CaselessEqualsConst(&args[2], "yes")) {
|
||||
cuboid_persist = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "MapRenderer.h"
|
||||
#include "Platform.h"
|
||||
#include "TerrainAtlas.h"
|
||||
#include "Vectors.h"
|
||||
#include "World.h"
|
||||
#include "Builder.h"
|
||||
#include "Utils.h"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <d3d9caps.h>
|
||||
#include <d3d9types.h>
|
||||
|
||||
Int32 Gfx_strideSizes[2] = GFX_STRIDE_SIZES;
|
||||
D3DFORMAT d3d9_depthFormats[6] = { D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D16, D3DFMT_D15S1 };
|
||||
D3DFORMAT d3d9_viewFormats[4] = { D3DFMT_X8R8G8B8, D3DFMT_R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 };
|
||||
D3DBLEND d3d9_blendFuncs[6] = { D3DBLEND_ZERO, D3DBLEND_ONE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA, D3DBLEND_DESTALPHA, D3DBLEND_INVDESTALPHA };
|
||||
|
|
|
@ -134,8 +134,7 @@ void Entity_SetModel(Entity* entity, STRING_PURE String* model) {
|
|||
}
|
||||
|
||||
/* 'giant' model kept for backwards compatibility */
|
||||
String giant = String_FromConst("giant");
|
||||
if (String_CaselessEquals(model, &giant)) {
|
||||
if (String_CaselessEqualsConst(model, "giant")) {
|
||||
String_AppendConst(&entModel, "humanoid");
|
||||
entity->ModelScale = Vector3_Create1(2.0f);
|
||||
} else if (Convert_TryParseUInt8(model, &entity->ModelBlock)) {
|
||||
|
|
|
@ -275,10 +275,7 @@ void EnvRenderer_ResetAllEnv(void* obj) {
|
|||
}
|
||||
|
||||
void EnvRenderer_FileChanged(void* obj, Stream* src) {
|
||||
String cloud = String_FromConst("cloud.png");
|
||||
String clouds = String_FromConst("clouds.png");
|
||||
|
||||
if (String_CaselessEquals(&src->Name, &cloud) || String_CaselessEquals(&src->Name, &clouds)) {
|
||||
if (String_CaselessEqualsConst(&src->Name, "cloud.png") || String_CaselessEqualsConst(&src->Name, "clouds.png")) {
|
||||
Game_UpdateTexture(&env_cloudsTex, src, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ Real32 Game_MaxViewDistance;
|
|||
Real32 Game_UserViewDistance;
|
||||
Int32 Game_Fov;
|
||||
Int32 Game_DefaultFov, Game_ZoomFov;
|
||||
UInt8 FpsLimit;
|
||||
FpsLimit Game_FpsLimit;
|
||||
bool Game_ShowAxisLines;
|
||||
bool Game_SimpleArmsAnim;
|
||||
bool Game_ClassicArmModel;
|
||||
|
@ -81,11 +81,11 @@ void Game_SetCursorVisible(bool visible);
|
|||
bool Game_ChangeTerrainAtlas(Bitmap* atlas);
|
||||
void Game_UpdateProjection(void);
|
||||
void Game_UpdateBlock(Int32 x, Int32 y, Int32 z, BlockID block);
|
||||
void Game_SetFpsLimitMethod(FpsLimit method);
|
||||
bool Game_UpdateTexture(GfxResourceID* texId, Stream* src, bool setSkinType);
|
||||
bool Game_ValidateBitmap(STRING_PURE String* file, Bitmap* bmp);
|
||||
void Game_SetViewDistance(Real32 distance, bool userDist);
|
||||
bool Game_CanPick(BlockID block);
|
||||
|
||||
static void Game_LimitFPS(void);
|
||||
void Game_Free(void);
|
||||
#endif
|
|
@ -48,6 +48,7 @@ Matrix Gfx_View, Gfx_Projection;
|
|||
|
||||
#define GFX_MAX_INDICES (65536 / 4 * 6)
|
||||
#define GFX_MAX_VERTICES 65536
|
||||
#define GFX_STRIDE_SIZES { 16, 24 }
|
||||
|
||||
/* Callback invoked when the current context is lost, and is repeatedly invoked until the context can be retrieved. */
|
||||
ScheduledTaskCallback LostContextFunction;
|
||||
|
@ -97,7 +98,6 @@ void Gfx_DrawVb_Lines(Int32 verticesCount);
|
|||
void Gfx_DrawVb_IndexedTris_Range(Int32 verticesCount, Int32 startVertex);
|
||||
void Gfx_DrawVb_IndexedTris(Int32 verticesCount);
|
||||
void Gfx_DrawIndexedVb_TrisT2fC4b(Int32 verticesCount, Int32 startVertex);
|
||||
static Int32 Gfx_strideSizes[2] = { 16, 24 };
|
||||
|
||||
void Gfx_SetMatrixMode(Int32 matrixType);
|
||||
void Gfx_LoadMatrix(Matrix* matrix);
|
||||
|
|
|
@ -83,15 +83,11 @@ bool Gui_Contains(Int32 recX, Int32 recY, Int32 width, Int32 height, Int32 x, In
|
|||
}
|
||||
|
||||
void Gui_FileChanged(void* obj, Stream* stream) {
|
||||
String gui = String_FromConst("gui.png");
|
||||
String guiClassic = String_FromConst("gui_classic.png");
|
||||
String icons = String_FromConst("icons.png");
|
||||
|
||||
if (String_CaselessEquals(&stream->Name, &gui)) {
|
||||
if (String_CaselessEqualsConst(&stream->Name, "gui.png")) {
|
||||
Game_UpdateTexture(&Gui_GuiTex, stream, false);
|
||||
} else if (String_CaselessEquals(&stream->Name, &guiClassic)) {
|
||||
} else if (String_CaselessEqualsConst(&stream->Name, "gui_classic.png")) {
|
||||
Game_UpdateTexture(&Gui_GuiClassicTex, stream, false);
|
||||
} else if (String_CaselessEquals(&stream->Name, &icons)) {
|
||||
} else if (String_CaselessEqualsConst(&stream->Name, "icons.png")) {
|
||||
Game_UpdateTexture(&Gui_IconsTex, stream, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,21 @@ typedef struct SaveLevelScreen_ {
|
|||
UInt8 TextPathBuffer[String_BufferSize(FILENAME_SIZE)];
|
||||
} SaveLevelScreen;
|
||||
|
||||
#define MENUOPTIONS_MAX_DESC 5
|
||||
typedef struct MenuOptionsScreen_ {
|
||||
MenuScreen_Layout
|
||||
MenuInputValidator* Validators;
|
||||
const UInt8** Descriptions;
|
||||
const UInt8** DefaultValues;
|
||||
ButtonWidget* Buttons;
|
||||
Int32 ActiveI, SelectedI, DescriptionsCount;
|
||||
ButtonWidget OK, Default;
|
||||
MenuInputWidget Input;
|
||||
TextGroupWidget ExtHelp;
|
||||
Texture ExtHelp_Textures[MENUOPTIONS_MAX_DESC];
|
||||
UInt8 ExtHelp_Buffer[String_BufferSize(MENUOPTIONS_MAX_DESC * TEXTGROUPWIDGET_LEN)];
|
||||
} MenuOptionsScreen;
|
||||
|
||||
|
||||
void Menu_FreeWidgets(Widget** widgets, Int32 widgetsCount) {
|
||||
if (widgets == NULL) return;
|
||||
|
@ -1435,8 +1450,7 @@ void HotkeyListScreen_EntryClick(GuiElement* screenElem, GuiElement* w) {
|
|||
String text = ListScreen_UNSAFE_GetCur(screen, w);
|
||||
HotkeyData original = { 0 };
|
||||
|
||||
String empty = String_FromConst(LIST_SCREEN_EMPTY);
|
||||
if (String_CaselessEquals(&text, &empty)) {
|
||||
if (String_CaselessEqualsConst(&text, LIST_SCREEN_EMPTY)) {
|
||||
Gui_SetNewScreen(EditHotkeyScreen_MakeInstance(original)); return;
|
||||
}
|
||||
|
||||
|
@ -1837,4 +1851,262 @@ Screen* MouseKeyBindingsScreen_MakeInstance(void) {
|
|||
screen->LeftPage = KeyBindingsScreen_Other;
|
||||
screen->WidgetsCount++; /* Extra text widget for 'right click' message */
|
||||
return (Screen*)screen;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------MenuOptionsScreen------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void MenuOptionsScreen_Init(GuiElement* elem) {
|
||||
MenuScreen_Init(elem);
|
||||
Key_KeyRepeat = true;
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_Render(GuiElement* elem, Real64 delta) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)elem;
|
||||
MenuScreen_Render(elem, delta);
|
||||
if (screen->ExtHelp.LinesCount == 0) return;
|
||||
|
||||
TextGroupWidget* extHelp = &screen->ExtHelp;
|
||||
Int32 x = extHelp->X - 5, y = extHelp->Y - 5;
|
||||
Int32 width = extHelp->Width, height = extHelp->Height;
|
||||
PackedCol tableCol = PACKEDCOL_CONST(20, 20, 20, 200);
|
||||
GfxCommon_Draw2DFlat(x, y, width + 10, height + 10, tableCol);
|
||||
|
||||
Gfx_SetTexturing(true);
|
||||
Elem_Render(&screen->ExtHelp, delta);
|
||||
Gfx_SetTexturing(false);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_Free(GuiElement* elem) {
|
||||
MenuScreen_Free(elem);
|
||||
Key_KeyRepeat = false;
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_OnResize(GuiElement* elem) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)elem;
|
||||
MenuScreen_OnResize(elem);
|
||||
if (screen->ExtHelp.LinesCount == 0) return;
|
||||
RepositionExtendedHelp();
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_ContextLost(void* obj) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)obj;
|
||||
MenuScreen_ContextLost(obj);
|
||||
screen->ActiveI = -1;
|
||||
MenuOptionsScreen_FreeExtHelp(screen);
|
||||
}
|
||||
|
||||
bool MenuOptionsScreen_HandlesKeyPress(GuiElement* elem, UInt8 key) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)elem;
|
||||
if (screen->ActiveI == -1) return true;
|
||||
return Elem_HandlesKeyPress(&screen->Input.Base, key);
|
||||
}
|
||||
|
||||
bool MenuOptionsScreen_HandlesKeyDown(GuiElement* elem, Key key) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)elem;
|
||||
if (screen->ActiveI >= 0) {
|
||||
if (Elem_HandlesKeyDown(&screen->Input.Base, key)) return true;
|
||||
if (key == Key_Enter || key == Key_KeypadEnter) {
|
||||
EnterInput(); return true;
|
||||
}
|
||||
}
|
||||
return MenuScreen_HandlesKeyDown(elem, key);
|
||||
}
|
||||
|
||||
bool MenuOptionsScreen_HandlesKeyUp(GuiElement* elem, Key key) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)elem;
|
||||
if (screen->ActiveI == -1) return true;
|
||||
return Elem_HandlesKeyUp(&screen->Input.Base, key);
|
||||
}
|
||||
|
||||
bool MenuOptionsScreen_HandlesMouseMove(GuiElement* elem, Int32 x, Int32 y) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)elem;
|
||||
Int32 i = Menu_HandleMouseMove(screen->WidgetsPtr, screen->WidgetsCount, x, y);
|
||||
if (i == -1 || i == screen->SelectedI) return true;
|
||||
if (screen->Descriptions == NULL || i >= screen->DescriptionsCount) return true;
|
||||
|
||||
screen->SelectedI = i;
|
||||
if (screen->ActiveI == -1) SelectExtendedHelp(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_Make(MenuOptionsScreen* screen, Int32 i, Int32 dir, Int32 y, const UInt8* optName, Widget_LeftClick onClick, ButtonWidget_Get getter, ButtonWidget_Set setter) {
|
||||
UInt8 titleBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String title = String_InitAndClearArray(titleBuffer);
|
||||
String_AppendConst(&title, optName);
|
||||
String_AppendConst(&title, ": ");
|
||||
getter(&title);
|
||||
|
||||
ButtonWidget* btn = &screen->Buttons[i];
|
||||
screen->WidgetsPtr[i] = (Widget*)btn;
|
||||
ButtonWidget_Create(btn, 300, &title, &screen->TitleFont, onClick);
|
||||
Widget_SetLocation((Widget*)btn, ANCHOR_CENTRE, ANCHOR_CENTRE, 160 * dir, y);
|
||||
|
||||
btn->OptName = optName;
|
||||
btn->GetValue = getter;
|
||||
btn->SetValue = setter;
|
||||
return btn;
|
||||
}
|
||||
|
||||
void Menu_GetBool(bool v, STRING_TRANSIENT String* raw) {
|
||||
String_AppendConst(raw, v ? "ON" : "OFF");
|
||||
}
|
||||
bool Menu_SetBool(STRING_PURE String* raw, const UInt8* key) {
|
||||
bool isOn = String_CaselessEqualsConst(raw, "ON");
|
||||
Options_SetBool(key, isOn); return isOn;
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_GetFPS(STRING_TRANSIENT String* raw) {
|
||||
String_AppendConst(raw, FpsLimit_Names[Game_FpsLimit]);
|
||||
}
|
||||
void MenuOptionsScreen_SetFPS(STRING_PURE String* raw) {
|
||||
UInt32 method = Utils_ParseEnum(raw, FpsLimit_VSync, FpsLimit_Names, Array_Elems(FpsLimit_Names));
|
||||
Game_SetFpsLimitMethod(method);
|
||||
Options_Set(OPTION_FPS_LIMIT, FpsLimit_Names[method]);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_SelectExtHelp(MenuOptionsScreen* screen, Int32 idx) {
|
||||
MenuOptionsScreen_FreeExtHelp(screen);
|
||||
if (screen->Descriptions == NULL || screen->ActiveI >= 0) return;
|
||||
const UInt8* desc = screen->Descriptions[idx];
|
||||
if (desc == NULL) return;
|
||||
|
||||
String descRaw = String_FromReadonly(desc);
|
||||
String descLines[5];
|
||||
UInt32 descLinesCount = Array_Elems(descLines);
|
||||
String_UNSAFE_Split(&descRaw, '%', &descLines, &descLinesCount);
|
||||
|
||||
TextGroupWidget_Create(&screen->ExtHelp, descLinesCount, &screen->TextFont, NULL, &screen->ExtHelp_Textures, &screen->ExtHelp_Buffer);
|
||||
Widget_SetLocation((Widget*)(&screen->ExtHelp), ANCHOR_MIN, ANCHOR_MIN, 0, 0);
|
||||
Elem_Init(&screen->ExtHelp);
|
||||
|
||||
Int32 i;
|
||||
for (i = 0; i < descLinesCount; i++) {
|
||||
TextGroupWidget_SetText(&screen->ExtHelp, i, &descLines[i]);
|
||||
}
|
||||
MenuOptionsScreen_RepositionExtHelp(screen);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_RepositionExtHelp(MenuOptionsScreen* screen) {
|
||||
screen->ExtHelp.XOffset = Game_Width / 2 - screen->ExtHelp.Width / 2;
|
||||
screen->ExtHelp.YOffset = Game_Height / 2 + 100;
|
||||
Widget_Reposition(&screen->ExtHelp);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_FreeExtHelp(MenuOptionsScreen* screen) {
|
||||
if (screen->ExtHelp.LinesCount == 0) return;
|
||||
Elem_Free(&screen->ExtHelp);
|
||||
screen->ExtHelp.LinesCount = 0;
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_Set(MenuOptionsScreen* screen, Int32 i, STRING_PURE String* text) {
|
||||
screen->Buttons[i].SetValue(text);
|
||||
/* need to get btn again here (e.g. changing FPS invalidates all widgets) */
|
||||
|
||||
UInt8 titleBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String title = String_InitAndClearArray(titleBuffer);
|
||||
String_AppendConst(&title, screen->Buttons[i].OptName);
|
||||
String_AppendConst(&title, ": ");
|
||||
screen->Buttons[i].GetValue(&title);
|
||||
ButtonWidget_SetText(&screen->Buttons[i], &title);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_Bool(GuiElement* screenElem, GuiElement* widget) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)screenElem;
|
||||
ButtonWidget* button = (ButtonWidget*)widget;
|
||||
Int32 index = MenuScreen_Index((MenuScreen*)screen, (Widget*)widget);
|
||||
SelectExtendedHelp(index);
|
||||
|
||||
UInt8 valueBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String value = String_InitAndClearArray(valueBuffer);
|
||||
button->GetValue(&value);
|
||||
|
||||
bool isOn = String_CaselessEqualsConst(&value, "ON");
|
||||
String newValue = String_FromReadonly(isOn ? "ON" : "OFF");
|
||||
MenuOptionsScreen_Set(screen, index, &newValue);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_Enum(GuiElement* screenElem, GuiElement* widget) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)screenElem;
|
||||
ButtonWidget* button = (ButtonWidget*)widget;
|
||||
Int32 index = MenuScreen_Index((MenuScreen*)screen, (Widget*)widget);
|
||||
SelectExtendedHelp(index);
|
||||
|
||||
MenuInputValidator* validator = &screen->Validators[index];
|
||||
const UInt8** names = (const UInt8**)validator->Meta_Ptr[0];
|
||||
UInt32 count = (UInt32)validator->Meta_Ptr[1];
|
||||
|
||||
UInt8 valueBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String value = String_InitAndClearArray(valueBuffer);
|
||||
button->GetValue(&value);
|
||||
|
||||
UInt32 raw = (Utils_ParseEnum(&value, 0, names, count) + 1) % count;
|
||||
String newValue = String_FromReadonly(names[raw]);
|
||||
MenuOptionsScreen_Set(screen, index, &newValue);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_Input(GuiElement* screenElem, GuiElement* widget) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)screenElem;
|
||||
ButtonWidget* button = (ButtonWidget*)widget;
|
||||
screen->ActiveI = MenuScreen_Index((MenuScreen*)screen, (Widget*)widget);
|
||||
SelectExtendedHelp(screen->ActiveI);
|
||||
|
||||
MenuOptionsScreen_FreeInput(screen);
|
||||
UInt8 valueBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String value = String_InitAndClearArray(valueBuffer);
|
||||
button->GetValue(&value);
|
||||
|
||||
MenuInputValidator* validator = &screen->Validators[screen->ActiveI];
|
||||
MenuInputWidget_Create(&screen->Input, 400, 30, &value, &screen->TextFont, validator);
|
||||
Widget_SettLocation((Widget*)(&screen->Input), ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 110);
|
||||
screen->Input.Base.ShowCaret = true;
|
||||
|
||||
String okMsg = String_FromConst("OK");
|
||||
ButtonWidget_Create(&screen->OK, 40, &okMsg, &screen->TitleFont, MenuOptionsScreen_OK);
|
||||
Widget_SetLocation((Widget*)(&screen->OK), ANCHOR_CENTRE, ANCHOR_CENTRE, 240, 110);
|
||||
|
||||
String defMsg = String_FromConst("Default value")
|
||||
ButtonWidget_Create(&screen->Default, 200, &defMsg, &screen->TitleFont, MenuOptionsScreen_Default);
|
||||
Widget_SetLocation((Widget*)(&screen->Default), ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 150);
|
||||
|
||||
Widget** widgets = screen->WidgetsPtr;
|
||||
widgets[screen->WidgetsCount - 1] = (Widget*)(&screen->Input);
|
||||
widgets[screen->WidgetsCount - 2] = (Widget*)(&screen->OK);
|
||||
widgets[screen->WidgetsCount - 3] = (Widget*)(&screen->Default);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_OK(GuiElement* screenElem, GuiElement* widget) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)screenElem;
|
||||
MenuOptionsScreen_EnterInput(screen);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_Default(GuiElement* screenElem, GuiElement* widget) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)screenElem;
|
||||
String text = String_FromReadonly(screen->DefaultValues[screen->ActiveI]);
|
||||
InputWidget_Clear(&screen->Input.Base);
|
||||
InputWidget_AppendString(&screen->Input.Base, &text);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_EnterInput(MenuOptionsScreen* screen) {
|
||||
String text = screen->Input.Base.Text;
|
||||
MenuInputValidator* validator = &screen->Input.Validator;
|
||||
|
||||
if (validator->IsValidValue(validator, &text)) {
|
||||
MenuOptionsScreen_Set(screen, screen->ActiveI, &text);
|
||||
}
|
||||
|
||||
MenuOptionsScreen_SelectExtHelp(screen, screen->ActiveI);
|
||||
screen->ActiveI = -1;
|
||||
MenuOptionsScreen_FreeInput(screen);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_FreeInput(MenuOptionsScreen* screen) {
|
||||
if (screen->ActiveI == -1) return;
|
||||
|
||||
Int32 i;
|
||||
for (i = screen->WidgetsCount - 3; i < screen->WidgetsCount; i++) {
|
||||
Elem_Free(screen->WidgetsPtr[i]);
|
||||
screen->WidgetsPtr[i] = NULL;
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ FN_GLGENBUFFERS glGenBuffers;
|
|||
FN_GLBUFFERDATA glBufferData;
|
||||
FN_GLBUFFERSUBDATA glBufferSubData;
|
||||
|
||||
Int32 Gfx_strideSizes[2] = GFX_STRIDE_SIZES;
|
||||
bool gl_lists = false;
|
||||
Int32 gl_activeList = -1;
|
||||
#define gl_DYNAMICLISTID 1234567891
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
#include "Platform.h"
|
||||
#include "Stream.h"
|
||||
|
||||
const UInt8* FpsLimit_Names[FpsLimit_Count] = {
|
||||
"LimitVSync", "Limit30FPS", "Limit60FPS", "Limit120FPS", "LimitNone",
|
||||
};
|
||||
#define OPT_NOT_FOUND UInt32_MaxValue
|
||||
StringsBuffer Options_Changed;
|
||||
|
||||
|
@ -117,6 +120,14 @@ Int32 Options_Insert(STRING_PURE String* key, STRING_PURE String* value) {
|
|||
return Options_Keys.Count;
|
||||
}
|
||||
|
||||
void Options_SetBool(const UInt8* keyRaw, bool value) {
|
||||
if (value) {
|
||||
String str = String_FromConst("True"); Options_Set(keyRaw, &str);
|
||||
} else {
|
||||
String str = String_FromConst("False"); Options_Set(keyRaw, &str);
|
||||
}
|
||||
}
|
||||
|
||||
void Options_SetInt32(const UInt8* keyRaw, Int32 value) {
|
||||
UInt8 numBuffer[String_BufferSize(STRING_INT32CHARS)];
|
||||
String numStr = String_InitAndClearArray(numBuffer);
|
||||
|
|
|
@ -5,11 +5,10 @@
|
|||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
||||
#define FPS_LIMIT_VSYNC 0
|
||||
#define FPS_LIMIT_30FPS 1
|
||||
#define FPS_LIMIT_60FPS 2
|
||||
#define FPS_LIMIT_120FPS 3
|
||||
#define FPS_LIMIT_NONE 4
|
||||
typedef enum FpsLimit_ {
|
||||
FpsLimit_VSync, FpsLimit_30FPS, FpsLimit_60FPS, FpsLimit_120FPS, FpsLimit_None, FpsLimit_Count,
|
||||
} FpsLimit;
|
||||
extern const UInt8* FpsLimit_Names[FpsLimit_Count];
|
||||
|
||||
#define OPTION_USE_MUSIC "usemusic"
|
||||
#define OPTION_USE_SOUND "usesound"
|
||||
|
@ -81,6 +80,7 @@ bool Options_GetBool(const UInt8* key, bool defValue);
|
|||
Real32 Options_GetFloat(const UInt8* key, Real32 min, Real32 max, Real32 defValue);
|
||||
UInt32 Options_GetEnum(const UInt8* key, UInt32 defValue, const UInt8** names, UInt32 namesCount);
|
||||
|
||||
void Options_SetBool(const UInt8* keyRaw, bool value);
|
||||
void Options_SetInt32(const UInt8* keyRaw, Int32 value);
|
||||
void Options_Set(const UInt8* keyRaw, STRING_PURE String* value);
|
||||
void Options_Load(void);
|
||||
|
|
|
@ -172,8 +172,7 @@ UInt16 Terrain_1DIndices[ATLAS1D_MAX_ATLASES_COUNT];
|
|||
Random rnd;
|
||||
|
||||
void Particles_FileChanged(void* obj, Stream* stream) {
|
||||
String particlesPng = String_FromConst("particles.png");
|
||||
if (String_CaselessEquals(&stream->Name, &particlesPng)) {
|
||||
if (String_CaselessEqualsConst(&stream->Name, "particles.png")) {
|
||||
Game_UpdateTexture(&Particles_TexId, stream, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ GfxResourceID skybox_tex, skybox_vb;
|
|||
#define SKYBOX_COUNT (6 * 4)
|
||||
|
||||
bool SkyboxRenderer_ShouldRender(void) {
|
||||
return skybox_tex > 0 && !EnvRenderer_Minimal;
|
||||
return skybox_tex != NULL && !EnvRenderer_Minimal;
|
||||
}
|
||||
|
||||
void SkyboxRenderer_TexturePackChanged(void* obj) {
|
||||
|
@ -24,12 +24,9 @@ void SkyboxRenderer_TexturePackChanged(void* obj) {
|
|||
}
|
||||
|
||||
void SkyboxRenderer_FileChanged(void* obj, Stream* src) {
|
||||
String skybox = String_FromConst("skybox.png");
|
||||
String useclouds = String_FromConst("useclouds");
|
||||
|
||||
if (String_CaselessEquals(&src->Name, &skybox)) {
|
||||
if (String_CaselessEqualsConst(&src->Name, "skybox.png")) {
|
||||
Game_UpdateTexture(&skybox_tex, src, false);
|
||||
} else if (String_CaselessEquals(&src->Name, &useclouds)) {
|
||||
} else if (String_CaselessEqualsConst(&src->Name, "useclouds")) {
|
||||
WorldEnv_SkyboxClouds = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,6 +110,18 @@ bool String_CaselessEquals(STRING_PURE String* a, STRING_PURE String* b) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool String_CaselessEqualsConst(STRING_PURE String* a, STRING_PURE const UInt8* b) {
|
||||
Int32 i;
|
||||
|
||||
for (i = 0; i < a->length; i++) {
|
||||
UInt8 aCur = a->buffer[i]; Char_MakeLower(aCur);
|
||||
UInt8 bCur = b[i]; Char_MakeLower(bCur);
|
||||
if (aCur != bCur || bCur == NULL) return false;
|
||||
}
|
||||
/* ensure at end of string */
|
||||
return b[a->length] == NULL;
|
||||
}
|
||||
|
||||
|
||||
bool String_Append(STRING_TRANSIENT String* str, UInt8 c) {
|
||||
if (str->length == str->capacity) return false;
|
||||
|
@ -502,16 +514,12 @@ bool Convert_TryParseReal32(STRING_PURE String* str, Real32* value) {
|
|||
}
|
||||
|
||||
bool Convert_TryParseBool(STRING_PURE String* str, bool* value) {
|
||||
String trueStr = String_FromConst("True");
|
||||
if (String_CaselessEquals(str, &trueStr)) {
|
||||
if (String_CaselessEqualsConst(str, "True")) {
|
||||
*value = true; return true;
|
||||
}
|
||||
|
||||
String falseStr = String_FromConst("False");
|
||||
if (String_CaselessEquals(str, &falseStr)) {
|
||||
if (String_CaselessEqualsConst(str, "False")) {
|
||||
*value = false; return true;
|
||||
}
|
||||
|
||||
*value = false; return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ void String_UNSAFE_Split(STRING_REF String* str, UInt8 c, STRING_TRANSIENT Strin
|
|||
|
||||
bool String_Equals(STRING_PURE String* a, STRING_PURE String* b);
|
||||
bool String_CaselessEquals(STRING_PURE String* a, STRING_PURE String* b);
|
||||
bool String_CaselessEqualsConst(STRING_PURE String* a, STRING_PURE const UInt8* b);
|
||||
Int32 String_MakeInt32(Int32 num, UInt8* numBuffer);
|
||||
|
||||
bool String_Append(STRING_TRANSIENT String* str, UInt8 c);
|
||||
|
|
|
@ -40,8 +40,7 @@ Int64 DateTime_MsBetween(DateTime* start, DateTime* end) {
|
|||
UInt32 Utils_ParseEnum(STRING_PURE String* text, UInt32 defValue, const UInt8** names, UInt32 namesCount) {
|
||||
UInt32 i;
|
||||
for (i = 0; i < namesCount; i++) {
|
||||
String name = String_FromReadonly(names[i]);
|
||||
if (String_CaselessEquals(text, &name)) return i;
|
||||
if (String_CaselessEqualsConst(text, names[i])) return i;
|
||||
}
|
||||
return defValue;
|
||||
}
|
||||
|
|
|
@ -182,12 +182,9 @@ void WeatherRenderer_Render(Real64 deltaTime) {
|
|||
}
|
||||
|
||||
void WeatherRenderer_FileChanged(void* obj, Stream* stream) {
|
||||
String snow = String_FromConst("snow.png");
|
||||
String rain = String_FromConst("rain.png");
|
||||
|
||||
if (String_CaselessEquals(&stream->Name, &snow)) {
|
||||
if (String_CaselessEqualsConst(&stream->Name, "snow.png")) {
|
||||
Game_UpdateTexture(&weather_snowTex, stream, false);
|
||||
} else if (String_CaselessEquals(&stream->Name, &rain)) {
|
||||
} else if (String_CaselessEqualsConst(&stream->Name, "rain.png")) {
|
||||
Game_UpdateTexture(&weather_rainTex, stream, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,8 @@ void TextWidget_Create(TextWidget* widget, STRING_PURE String* text, FontDesc* f
|
|||
void TextWidget_SetText(TextWidget* widget, STRING_PURE String* text);
|
||||
|
||||
|
||||
typedef void (*ButtonWidget_Set)(STRING_TRANSIENT String* raw);
|
||||
typedef void (*ButtonWidget_Get)(STRING_TRANSIENT String* raw);
|
||||
|
||||
typedef void (*ButtonWidget_Set)(STRING_PURE String* raw);
|
||||
typedef struct ButtonWidget_ {
|
||||
Widget_Layout
|
||||
Texture Texture;
|
||||
|
|
Loading…
Add table
Reference in a new issue