diff --git a/src/Graphics.h b/src/Graphics.h index e46811fa1..5c5b6ccef 100644 --- a/src/Graphics.h +++ b/src/Graphics.h @@ -9,6 +9,7 @@ Copyright 2014-2023 ClassiCube | Licensed under BSD-3 struct Bitmap; struct Stream; struct IGameComponent; +struct MenuOptionsScreen; extern struct IGameComponent Gfx_Component; typedef enum VertexFormat_ { @@ -238,6 +239,7 @@ cc_result Gfx_TakeScreenshot(struct Stream* output); /* Warns in chat if the backend has problems with the user's GPU */ /* Returns whether legacy rendering mode for borders/sky/clouds is needed */ cc_bool Gfx_WarnIfNecessary(void); +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s); /* Sets up state for rendering a new frame */ void Gfx_BeginFrame(void); /* Finishes rendering a frame, and swaps it with the back buffer */ diff --git a/src/Graphics_3DS.c b/src/Graphics_3DS.c index 00c396145..99f1d0dc6 100644 --- a/src/Graphics_3DS.c +++ b/src/Graphics_3DS.c @@ -901,6 +901,7 @@ void Gfx_DisableTextureOffset(void) { *---------------------------------------------------------Drawing---------------------------------------------------------* *#########################################################################################################################*/ cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } static void UpdateAttribFormat(VertexFormat fmt) { C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); diff --git a/src/Graphics_D3D11.c b/src/Graphics_D3D11.c index 8eccfa6cf..3833278f2 100644 --- a/src/Graphics_D3D11.c +++ b/src/Graphics_D3D11.c @@ -1145,6 +1145,7 @@ void Gfx_EndFrame(void) { } cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } void Gfx_GetApiInfo(cc_string* info) { int pointerSize = sizeof(void*) * 8; diff --git a/src/Graphics_D3D9.c b/src/Graphics_D3D9.c index f22336645..069ccb8e1 100644 --- a/src/Graphics_D3D9.c +++ b/src/Graphics_D3D9.c @@ -850,6 +850,8 @@ void Gfx_EndFrame(void) { } cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } + static const char* D3D9_StrFlags(void) { if (createFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) return "Hardware"; if (createFlags & D3DCREATE_MIXED_VERTEXPROCESSING) return "Mixed"; diff --git a/src/Graphics_Dreamcast.c b/src/Graphics_Dreamcast.c index 23e8cd133..b420a54b0 100644 --- a/src/Graphics_Dreamcast.c +++ b/src/Graphics_Dreamcast.c @@ -498,9 +498,8 @@ static void Gfx_RestoreState(void) { gfx_format = -1; } -cc_bool Gfx_WarnIfNecessary(void) { - return false; -} +cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } /*########################################################################################################################* diff --git a/src/Graphics_GCWii.c b/src/Graphics_GCWii.c index 610c976f7..c34ba3092 100644 --- a/src/Graphics_GCWii.c +++ b/src/Graphics_GCWii.c @@ -323,6 +323,7 @@ void Gfx_SetScissor(int x, int y, int w, int h) { } cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } /*########################################################################################################################* diff --git a/src/Graphics_GL1.c b/src/Graphics_GL1.c index 9ad323335..14f730455 100644 --- a/src/Graphics_GL1.c +++ b/src/Graphics_GL1.c @@ -500,6 +500,7 @@ cc_bool Gfx_WarnIfNecessary(void) { } return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } /*########################################################################################################################* diff --git a/src/Graphics_GL2.c b/src/Graphics_GL2.c index d8874c190..21a2dae63 100644 --- a/src/Graphics_GL2.c +++ b/src/Graphics_GL2.c @@ -7,6 +7,7 @@ #include "_GraphicsBase.h" #include "Errors.h" #include "Window.h" +#include "Menus.h" /* OpenGL 2.0 backend (alternative modern-ish backend) */ #include "../misc/opengl/GLCommon.h" @@ -22,7 +23,7 @@ #define GL_FUNC(_retType, name) static _retType (APIENTRY *name) #include "../misc/opengl/GL2Funcs.h" -#define GLSym(sym) { DYNAMICLIB_QUOTE(sym), (void**)& ## sym } +#define GLSym(sym) { DYNAMICLIB_QUOTE(sym), (void**)&sym } static const struct DynamicLibSym core_funcs[] = { GLSym(glBindBuffer), GLSym(glDeleteBuffers), GLSym(glGenBuffers), GLSym(glBufferData), GLSym(glBufferSubData), @@ -47,6 +48,9 @@ static const struct DynamicLibSym core_funcs[] = { #include "_GLShared.h" static GfxResourceID white_square; +static int postProcess; +enum PostProcess { POSTPROCESS_NONE, POSTPROCESS_GRAYSCALE }; +static const char* const postProcess_Names[2] = { "NONE", "GRAYSCALE" }; /*########################################################################################################################* @@ -223,6 +227,15 @@ static void GenVertexShader(const struct GLShader* shader, cc_string* dst) { String_AppendConst(dst, "}"); } +static void AddPostProcessing(cc_string* dst) { + switch (postProcess) { + case POSTPROCESS_GRAYSCALE: + String_AppendConst(dst, " float gray = 0.21 * col.r + 0.71 * col.g + 0.07 * col.b;\n"); + String_AppendConst(dst, " col = vec4(gray, gray, gray, col.a);\n"); + break; + } +} + /* Generates source code for a GLSL fragment shader, based on shader's flags */ static void GenFragmentShader(const struct GLShader* shader, cc_string* dst) { int uv = shader->features & FTR_TEXTURE_UV; @@ -252,6 +265,8 @@ static void GenFragmentShader(const struct GLShader* shader, cc_string* dst) { if (fl) String_AppendConst(dst, " float f = clamp((fogEnd - depth) / fogEnd, 0.0, 1.0);\n"); if (fd) String_AppendConst(dst, " float f = clamp(exp(fogDensity * depth), 0.0, 1.0);\n"); if (fm) String_AppendConst(dst, " col.rgb = mix(fogCol, col.rgb, f);\n"); + + if (fl || fd || fm) AddPostProcessing(dst); String_AppendConst(dst, " gl_FragColor = col;\n"); String_AppendConst(dst, "}"); } @@ -547,15 +562,19 @@ static void GLBackend_Init(void) { #endif } -static void Gfx_FreeState(void) { +static void DeleteShaders(void) { int i; - FreeDefaultResources(); gfx_activeShader = NULL; for (i = 0; i < Array_Elems(shaders); i++) { glDeleteProgram(shaders[i].program); shaders[i].program = 0; } +} + +static void Gfx_FreeState(void) { + FreeDefaultResources(); + DeleteShaders(); Gfx_DeleteTexture(&white_square); } @@ -578,6 +597,21 @@ static void Gfx_RestoreState(void) { } cc_bool Gfx_WarnIfNecessary(void) { return false; } +static int GetPostProcess(void) { return postProcess; } +static void SetPostProcess(int v) { + postProcess = v; + DeleteShaders(); + SwitchProgram(); + DirtyUniform(UNI_MASK_ALL); +} + +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { + MenuOptionsScreen_AddEnum(s, "Post process", + postProcess_Names, Array_Elems(postProcess_Names), + GetPostProcess, SetPostProcess); + return false; +} + /*########################################################################################################################* *----------------------------------------------------------Drawing--------------------------------------------------------* @@ -655,7 +689,7 @@ void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { GL_SetupVbTextured(); } else { /* ICOUNT(startVertex) * 2 = startVertex * 3 */ - glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, (void*)(startVertex * 3)); + glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, uint_to_ptr(startVertex * 3)); } } #endif diff --git a/src/Graphics_N64.c b/src/Graphics_N64.c index 3a09e6271..f43a0b237 100644 --- a/src/Graphics_N64.c +++ b/src/Graphics_N64.c @@ -256,6 +256,7 @@ static void Gfx_RestoreState(void) { } cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } /*########################################################################################################################* diff --git a/src/Graphics_NDS.c b/src/Graphics_NDS.c index 4e69204ba..002e3d4c2 100644 --- a/src/Graphics_NDS.c +++ b/src/Graphics_NDS.c @@ -192,6 +192,7 @@ static void Gfx_RestoreState(void) { } cc_bool Gfx_WarnIfNecessary(void) { return true; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } /*########################################################################################################################* diff --git a/src/Graphics_PS1.c b/src/Graphics_PS1.c index 2b00cae73..315747006 100644 --- a/src/Graphics_PS1.c +++ b/src/Graphics_PS1.c @@ -855,9 +855,8 @@ cc_result Gfx_TakeScreenshot(struct Stream* output) { return ERR_NOT_SUPPORTED; } -cc_bool Gfx_WarnIfNecessary(void) { - return false; -} +cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } void Gfx_BeginFrame(void) { lastPoly = NULL; diff --git a/src/Graphics_PS2.c b/src/Graphics_PS2.c index 2a5f0b51e..39fc17fe3 100644 --- a/src/Graphics_PS2.c +++ b/src/Graphics_PS2.c @@ -738,9 +738,8 @@ cc_result Gfx_TakeScreenshot(struct Stream* output) { return ERR_NOT_SUPPORTED; } -cc_bool Gfx_WarnIfNecessary(void) { - return false; -} +cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } void Gfx_BeginFrame(void) { //Platform_LogConst("--- Frame ---"); diff --git a/src/Graphics_PS3.c b/src/Graphics_PS3.c index 22b65e53a..54e8e219c 100644 --- a/src/Graphics_PS3.c +++ b/src/Graphics_PS3.c @@ -246,6 +246,7 @@ void Gfx_Free(void) { Gfx_FreeState(); } cc_bool Gfx_TryRestoreContext(void) { return true; } cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } void Gfx_RestoreState(void) { InitDefaultResources(); diff --git a/src/Graphics_PSP.c b/src/Graphics_PSP.c index 13240a81d..1d0896f2e 100644 --- a/src/Graphics_PSP.c +++ b/src/Graphics_PSP.c @@ -419,6 +419,7 @@ void Gfx_DisableTextureOffset(void) { *---------------------------------------------------------Drawing---------------------------------------------------------* *#########################################################################################################################*/ cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } void Gfx_SetVertexFormat(VertexFormat fmt) { if (fmt == gfx_format) return; diff --git a/src/Graphics_PSVita.c b/src/Graphics_PSVita.c index c05f0cf5b..7463b6aa2 100644 --- a/src/Graphics_PSVita.c +++ b/src/Graphics_PSVita.c @@ -1062,6 +1062,7 @@ void Gfx_DisableTextureOffset(void) { *---------------------------------------------------------Drawing---------------------------------------------------------* *#########################################################################################################################*/ cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } void Gfx_SetVertexFormat(VertexFormat fmt) { if (fmt == gfx_format) return; diff --git a/src/Graphics_Saturn.c b/src/Graphics_Saturn.c index 3a4f70c73..55012136f 100644 --- a/src/Graphics_Saturn.c +++ b/src/Graphics_Saturn.c @@ -617,9 +617,8 @@ cc_result Gfx_TakeScreenshot(struct Stream* output) { return ERR_NOT_SUPPORTED; } -cc_bool Gfx_WarnIfNecessary(void) { - return false; -} +cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } void Gfx_BeginFrame(void) { Platform_LogConst("FRAME BEG"); diff --git a/src/Graphics_SoftGPU.c b/src/Graphics_SoftGPU.c index 94177474b..862c8d278 100644 --- a/src/Graphics_SoftGPU.c +++ b/src/Graphics_SoftGPU.c @@ -914,9 +914,8 @@ cc_result Gfx_TakeScreenshot(struct Stream* output) { return Png_Encode(&bmp, output, CB_GetRow, false, NULL); } -cc_bool Gfx_WarnIfNecessary(void) { - return false; -} +cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } void Gfx_BeginFrame(void) { } diff --git a/src/Graphics_WiiU.c b/src/Graphics_WiiU.c index 8a73442b7..60c96e4aa 100644 --- a/src/Graphics_WiiU.c +++ b/src/Graphics_WiiU.c @@ -455,6 +455,7 @@ void Gfx_EndFrame(void) { } cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } void Gfx_GetApiInfo(cc_string* info) { String_AppendConst(info, "-- Using Wii U --\n"); diff --git a/src/Graphics_Xbox.c b/src/Graphics_Xbox.c index 43502ef38..8a340bd78 100644 --- a/src/Graphics_Xbox.c +++ b/src/Graphics_Xbox.c @@ -606,6 +606,7 @@ void Gfx_SetScissor(int x, int y, int w, int h) { *---------------------------------------------------------Drawing---------------------------------------------------------* *#########################################################################################################################*/ cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } static uint32_t* PushAttrib(uint32_t* p, int index, int format, int size, int stride) { return pb_push1(p, NV097_SET_VERTEX_DATA_ARRAY_FORMAT + index * 4, diff --git a/src/Graphics_Xbox360.c b/src/Graphics_Xbox360.c index 8f5f3ef15..c0918cf4f 100644 --- a/src/Graphics_Xbox360.c +++ b/src/Graphics_Xbox360.c @@ -391,6 +391,7 @@ void Gfx_EndFrame(void) { } cc_bool Gfx_WarnIfNecessary(void) { return false; } +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } void Gfx_GetApiInfo(cc_string* info) { String_AppendConst(info, "-- Using XBox 360 --\n"); diff --git a/src/MenuOptions.c b/src/MenuOptions.c index 49d8a43a9..beaf53b90 100644 --- a/src/MenuOptions.c +++ b/src/MenuOptions.c @@ -39,8 +39,6 @@ typedef void (*Button_GetText)(struct ButtonWidget* btn, cc_string* raw); typedef void (*Button_SetText)(struct ButtonWidget* btn, const cc_string* raw); -typedef cc_bool (*Button_GetBool)(void); -typedef void (*Button_SetBool)(cc_bool value); struct MenuOptionMetaBool { Button_GetText GetText; Button_SetText SetText; @@ -48,8 +46,6 @@ struct MenuOptionMetaBool { Button_SetBool SetValue; }; -typedef int (*Button_GetEnum)(void); -typedef void (*Button_SetEnum)(int value); struct MenuOptionMetaEnum { Button_GetText GetText; Button_SetText SetText; @@ -59,8 +55,6 @@ struct MenuOptionMetaEnum { int count; }; -typedef PackedCol (*Button_GetHex)(void); -typedef void (*Button_SetHex)(PackedCol value); struct MenuOptionMetaHex { Button_GetText GetText; Button_SetText SetText; @@ -69,8 +63,6 @@ struct MenuOptionMetaHex { struct MenuInputDesc desc; }; -typedef int (*Button_GetInt)(void); -typedef void (*Button_SetInt)(int value); struct MenuOptionMetaInt { Button_GetText GetText; Button_SetText SetText; @@ -79,8 +71,6 @@ struct MenuOptionMetaInt { struct MenuInputDesc desc; }; -typedef void (*Button_GetNum)(cc_string* v); -typedef void (*Button_SetNum)(const cc_string* v); struct MenuOptionMetaNum { Button_GetText GetText; Button_SetText SetText; @@ -257,13 +247,15 @@ static int MenuOptionsScreen_AddButton(struct MenuOptionsScreen* s, const char* static void MenuOptionsScreen_EndButtons(struct MenuOptionsScreen* s, Widget_LeftClick backClick) { struct ButtonWidget* btn; int i, col, row, half = s->numButtons / 2; - int begRow = max(-3, 2 - half); + int begRow = 2 - half; + if (s->numButtons & 1) begRow--; + begRow = max(-3, begRow); for (i = 0; i < s->numButtons; i++) { btn = &s->buttons[i]; col = i < half ? -160 : 160; - row = 50 * (begRow + i % half); + row = 50 * (begRow + (i < half ? i : (i - half))); Widget_SetLocation(btn, ANCHOR_CENTRE, ANCHOR_CENTRE, col, row); } ButtonWidget_Add(s, &s->done, 400, backClick); @@ -287,7 +279,7 @@ static void MenuOptionsScreen_BoolClick(void* screen, void* widget) { MenuOptionsScreen_Update(s, btn); } -static void MenuOptionsScreen_AddBool(struct MenuOptionsScreen* s, const char* name, +void MenuOptionsScreen_AddBool(struct MenuOptionsScreen* s, const char* name, Button_GetBool getValue, Button_SetBool setValue) { int i = MenuOptionsScreen_AddButton(s, name, MenuOptionsScreen_BoolClick, MenuOptionsScreen_BoolGet, NULL); @@ -316,7 +308,7 @@ static void MenuOptionsScreen_EnumClick(void* screen, void* widget) { MenuOptionsScreen_Update(s, btn); } -static void MenuOptionsScreen_AddEnum(struct MenuOptionsScreen* s, const char* name, +void MenuOptionsScreen_AddEnum(struct MenuOptionsScreen* s, const char* name, const char* const* names, int namesCount, Button_GetEnum getValue, Button_SetEnum setValue) { int i = MenuOptionsScreen_AddButton(s, name, MenuOptionsScreen_EnumClick, @@ -368,7 +360,7 @@ static void MenuOptionsScreen_HexSet(struct ButtonWidget* btn, const cc_string* meta->SetValue(PackedCol_Make(rgb[0], rgb[1], rgb[2], 255)); } -static void MenuOptionsScreen_AddHex(struct MenuOptionsScreen* s, const char* name, PackedCol defaultValue, +void MenuOptionsScreen_AddHex(struct MenuOptionsScreen* s, const char* name, PackedCol defaultValue, Button_GetHex getValue, Button_SetHex setValue) { int i = MenuOptionsScreen_AddButton(s, name, MenuOptionsScreen_InputClick, MenuOptionsScreen_HexGet, MenuOptionsScreen_HexSet); @@ -392,7 +384,7 @@ static void MenuOptionsScreen_IntSet(struct ButtonWidget* btn, const cc_string* meta->SetValue(value); } -static void MenuOptionsScreen_AddInt(struct MenuOptionsScreen* s, const char* name, +void MenuOptionsScreen_AddInt(struct MenuOptionsScreen* s, const char* name, int minValue, int maxValue, int defaultValue, Button_GetInt getValue, Button_SetInt setValue) { int i = MenuOptionsScreen_AddButton(s, name, MenuOptionsScreen_InputClick, @@ -415,7 +407,7 @@ static void MenuOptionsScreen_NumSet(struct ButtonWidget* btn, const cc_string* meta->SetValue(v); } -static void MenuOptionsScreen_AddNum(struct MenuOptionsScreen* s, const char* name, +void MenuOptionsScreen_AddNum(struct MenuOptionsScreen* s, const char* name, float minValue, float maxValue, float defaultValue, Button_GetNum getValue, Button_SetNum setValue) { int i = MenuOptionsScreen_AddButton(s, name, MenuOptionsScreen_InputClick, @@ -771,18 +763,9 @@ static void GrO_SetMipmaps(cc_bool v) { TexturePack_ExtractCurrent(true); } -static void GrO_GetCameraMass(cc_string* v) { String_AppendFloat(v, Camera.Mass, 2); } -static void GrO_SetCameraMass(const cc_string* c) { - Camera.Mass = Menu_Float(c); - Options_Set(OPT_CAMERA_MASS, c); -} - static void GraphicsOptionsScreen_InitWidgets(struct MenuOptionsScreen* s) { MenuOptionsScreen_BeginButtons(s); { - MenuOptionsScreen_AddNum(s, "Camera Mass", - 1, 100, 20, - GrO_GetCameraMass, GrO_SetCameraMass); MenuOptionsScreen_AddEnum(s, "FPS mode", FpsLimit_Names, FPS_LIMIT_COUNT, MeO_GetFPS, MeO_SetFPS); MenuOptionsScreen_AddInt(s, "View distance", @@ -793,19 +776,16 @@ static void GraphicsOptionsScreen_InitWidgets(struct MenuOptionsScreen* s) { MenuOptionsScreen_AddEnum(s, "Lighting mode", LightingMode_Names, LIGHTING_MODE_COUNT, GrO_GetLighting, GrO_SetLighting); - MenuOptionsScreen_AddBool(s, "Smooth camera", - GrO_GetCamera, GrO_SetCamera); MenuOptionsScreen_AddEnum(s, "Names", NameMode_Names, NAME_MODE_COUNT, GrO_GetNames, GrO_SetNames); MenuOptionsScreen_AddEnum(s, "Shadows", ShadowMode_Names, SHADOW_MODE_COUNT, GrO_GetShadows, GrO_SetShadows); -#ifdef CC_BUILD_N64 - MenuOptionsScreen_AddBool(s, "Filtering", - GrO_GetMipmaps, GrO_SetMipmaps); -#else + + if (!Gfx_GetUIOptions(s)) { MenuOptionsScreen_AddBool(s, "Mipmaps", GrO_GetMipmaps, GrO_SetMipmaps); -#endif + } + MenuOptionsScreen_AddBool(s, "3D anaglyph", ClO_GetAnaglyph, ClO_SetAnaglyph); }; @@ -1134,6 +1114,12 @@ void HacksSettingsScreen_Show(void) { /*########################################################################################################################* *----------------------------------------------------MiscOptionsScreen----------------------------------------------------* *#########################################################################################################################*/ +static void MiO_GetCameraMass(cc_string* v) { String_AppendFloat(v, Camera.Mass, 2); } +static void MiO_SetCameraMass(const cc_string* c) { + Camera.Mass = Menu_Float(c); + Options_Set(OPT_CAMERA_MASS, c); +} + static void MiO_GetReach(cc_string* v) { String_AppendFloat(v, Entities.CurPlayer->ReachDistance, 2); } static void MiO_SetReach(const cc_string* v) { Entities.CurPlayer->ReachDistance = Menu_Float(v); } @@ -1155,6 +1141,12 @@ static void MiO_SetViewBob(cc_bool v) { Options_SetBool(OPT_VIEW_BOBBING, v); } +static cc_bool MiO_GetCamera(void) { return Camera.Smooth; } +static void MiO_SetCamera(cc_bool v) { + Camera.Smooth = v; + Options_SetBool(OPT_CAMERA_SMOOTH, v); +} + static cc_bool MiO_GetPhysics(void) { return Physics.Enabled; } static void MiO_SetPhysics(cc_bool v) { Physics_SetEnabled(v); @@ -1176,6 +1168,9 @@ static void MiO_SetSensitivity(int v) { static void MiscSettingsScreen_InitWidgets(struct MenuOptionsScreen* s) { MenuOptionsScreen_BeginButtons(s); { + MenuOptionsScreen_AddNum(s, "Camera Mass", + 1, 100, 20, + MiO_GetCameraMass, MiO_SetCameraMass); MenuOptionsScreen_AddNum(s, "Reach distance", 1, 1024, 5, MiO_GetReach, MiO_SetReach); @@ -1185,9 +1180,11 @@ static void MiscSettingsScreen_InitWidgets(struct MenuOptionsScreen* s) { MenuOptionsScreen_AddInt(s, "Sounds volume", 0, 100, DEFAULT_SOUNDS_VOLUME, MiO_GetSounds, MiO_SetSounds); + MenuOptionsScreen_AddBool(s, "Smooth camera", + MiO_GetCamera, MiO_SetCamera); + MenuOptionsScreen_AddBool(s, "View bobbing", MiO_GetViewBob, MiO_SetViewBob); - MenuOptionsScreen_AddBool(s, "Block physics", MiO_GetPhysics, MiO_SetPhysics); MenuOptionsScreen_AddBool(s, "Invert mouse", diff --git a/src/Menus.h b/src/Menus.h index c7896a22c..63282326e 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -1,6 +1,7 @@ #ifndef CC_MENUS_H #define CC_MENUS_H #include "Gui.h" +#include "PackedCol.h" /* Contains all 2D menu screen implementations. Copyright 2014-2023 ClassiCube | Licensed under BSD-3 @@ -10,6 +11,7 @@ struct MenuInputDesc; struct FontDesc; struct ButtonWidget; struct InputDevice; +struct MenuOptionsScreen; int Menu_InputDown(void* screen, int key, struct InputDevice* device); int Menu_PointerDown(void* screen, int id, int x, int y); @@ -69,4 +71,33 @@ void MenuScreen_Render2(void* screen, float delta); typedef void (*MenuInputDone)(const cc_string* value, cc_bool valid); void MenuInputOverlay_Show(struct MenuInputDesc* desc, const cc_string* value, MenuInputDone onDone, cc_bool screenMode); void MenuInputOverlay_Close(cc_bool valid); + + +typedef cc_bool (*Button_GetBool)(void); +typedef void (*Button_SetBool)(cc_bool value); +void MenuOptionsScreen_AddBool(struct MenuOptionsScreen* s, const char* name, + Button_GetBool getValue, Button_SetBool setValue); + +typedef int (*Button_GetEnum)(void); +typedef void (*Button_SetEnum)(int value); +void MenuOptionsScreen_AddEnum(struct MenuOptionsScreen* s, const char* name, + const char* const* names, int namesCount, + Button_GetEnum getValue, Button_SetEnum setValue); + +typedef PackedCol (*Button_GetHex)(void); +typedef void (*Button_SetHex)(PackedCol value); +void MenuOptionsScreen_AddHex(struct MenuOptionsScreen* s, const char* name, PackedCol defaultValue, + Button_GetHex getValue, Button_SetHex setValue); + +typedef int (*Button_GetInt)(void); +typedef void (*Button_SetInt)(int value); +void MenuOptionsScreen_AddInt(struct MenuOptionsScreen* s, const char* name, + int minValue, int maxValue, int defaultValue, + Button_GetInt getValue, Button_SetInt setValue); + +typedef void (*Button_GetNum)(cc_string* v); +typedef void (*Button_SetNum)(const cc_string* v); +void MenuOptionsScreen_AddNum(struct MenuOptionsScreen* s, const char* name, + float minValue, float maxValue, float defaultValue, + Button_GetNum getValue, Button_SetNum setValue); #endif