mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 12:47:58 +03:00
tr2: make water color customizable like in TR1X
Tackles #1619. While does not offer a simple toggle for the PS1 style, it is now possible to edit the game flow file by hand with those settings.
This commit is contained in:
parent
2aa0f2e161
commit
556702da1c
24 changed files with 197 additions and 95 deletions
|
@ -476,6 +476,9 @@
|
|||
"DETAIL_FOG_START": "Fog start",
|
||||
"DETAIL_INTEGER_FMT": "%d",
|
||||
"DETAIL_TITLE": "Graphic Options",
|
||||
"DETAIL_WATER_COLOR_B": "Water color (B)",
|
||||
"DETAIL_WATER_COLOR_G": "Water color (G)",
|
||||
"DETAIL_WATER_COLOR_R": "Water color (R)",
|
||||
"HEADING_GAME_OVER": "GAME OVER",
|
||||
"HEADING_INVENTORY": "INVENTORY",
|
||||
"HEADING_ITEMS": "ITEMS",
|
||||
|
|
|
@ -198,8 +198,8 @@ remains distinct for each game.
|
|||
<td>
|
||||
Water color (R, G, B). 1.0 means pass-through, 0.0 means no value at all.
|
||||
<ul>
|
||||
<li>[0.6, 0.7, 1.0] is the original DOS version filter.</li>
|
||||
<li>[0.45, 1.0, 1.0] is the default TombATI filter.</li>
|
||||
<li><code>[0.6, 0.7, 1.0]</code> is the original DOS version color.</li>
|
||||
<li><code>[0.45, 1.0, 1.0]</code> is the default TombATI color.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -331,12 +331,31 @@ remains distinct for each game.
|
|||
<a name="draw-distance-max"></a>
|
||||
<code>fog_end</code>
|
||||
</td>
|
||||
<td>Double<strong>*</strong></td>
|
||||
<td>Double</td>
|
||||
<td>
|
||||
The distance (in tiles) at which objects and the world are clipped away.
|
||||
The default value in OG TR2 is hardcoded to 20.
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<a name="water-color"></a>
|
||||
<code>water_color</code>
|
||||
</td>
|
||||
<td>Float array</td>
|
||||
<td>
|
||||
Water color (R, G, B). 1.0 means pass-through, 0.0 means no value at all.
|
||||
<ul>
|
||||
<li><code>[0.5, 0.75, 1.0]</code> is the default PC hardware renderer color.</li>
|
||||
<li><code>[0.66, 0.66, 1.0]</code> is the default PC software renderer color.</li>
|
||||
<li><code>[0.8, 1.0, 0.5]</code> is the PS1 color in the Venice, Bartoli's Hideout and Opera House levels.</li>
|
||||
<li><code>[0.8, 1.0, 0.6]</code> is the PS1 color for the Temple of Xian level.</li>
|
||||
<li><code>[0.8, 1.0, 0.8]</code> is the PS1 color for the Floating Islands and Dragon's Lair levels.</li>
|
||||
<li><code>[0.7, 0.9, 0.9]</code> is the PS1 color for The Great Wall and Tibetan Foothills levels.</li>
|
||||
<li><code>[0.5, 1.0, 1.0]</code> is the PS1 color for all other PS1 levels.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Game flow commands
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
- added support for The Golden Mask (#1621)
|
||||
- added sunglasses for graphic options (#1615)
|
||||
- added control over the fog distances for players and level builders (#1622)
|
||||
- added control over the water color for players and level builders (#1619)
|
||||
- added an installer for Windows (#2681)
|
||||
- added the bonus level game flow type, which allows for levels to be unlocked if all main game secrets are found (#2668)
|
||||
- added the ability for custom levels to have up to two of each secret type per level (#2674)
|
||||
|
|
|
@ -24,6 +24,7 @@ CFG_INT32(g_Config, visuals.fov, 80)
|
|||
CFG_BOOL(g_Config, visuals.use_pcx_fov, true)
|
||||
CFG_INT32(g_Config, visuals.fog_start, 22)
|
||||
CFG_INT32(g_Config, visuals.fog_end, 30)
|
||||
CFG_RGB888(g_Config, visuals.water_color, 127, 223, 255)
|
||||
CFG_DOUBLE(g_Config, ui.text_scale, 1.0)
|
||||
CFG_DOUBLE(g_Config, ui.bar_scale, 1.0)
|
||||
CFG_BOOL(g_Config, ui.enable_photo_mode_ui, true)
|
||||
|
|
|
@ -101,6 +101,26 @@ static void M_LoadCommonSettings(
|
|||
settings->fog_end.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
JSON_ARRAY *const tmp_arr = JSON_ObjectGetArray(obj, "water_color");
|
||||
if (tmp_arr != nullptr) {
|
||||
const RGB_F color = {
|
||||
JSON_ArrayGetDouble(tmp_arr, 0, JSON_INVALID_NUMBER),
|
||||
JSON_ArrayGetDouble(tmp_arr, 1, JSON_INVALID_NUMBER),
|
||||
JSON_ArrayGetDouble(tmp_arr, 2, JSON_INVALID_NUMBER),
|
||||
};
|
||||
if (color.r != JSON_INVALID_NUMBER && color.g != JSON_INVALID_NUMBER
|
||||
&& color.b != JSON_INVALID_NUMBER) {
|
||||
settings->water_color.is_present = true;
|
||||
settings->water_color.value = (RGB_888) {
|
||||
color.r * 255.0f,
|
||||
color.g * 255.0f,
|
||||
color.b * 255.0f,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void M_LoadCommonRoot(JSON_OBJECT *const obj, GAME_FLOW *const gf)
|
||||
|
|
|
@ -99,26 +99,6 @@ static void M_LoadSettings(
|
|||
JSON_OBJECT *const obj, GF_LEVEL_SETTINGS *const settings)
|
||||
{
|
||||
M_LoadCommonSettings(obj, settings);
|
||||
|
||||
{
|
||||
JSON_ARRAY *const tmp_arr = JSON_ObjectGetArray(obj, "water_color");
|
||||
if (tmp_arr != nullptr) {
|
||||
const RGB_F color = {
|
||||
JSON_ArrayGetDouble(tmp_arr, 0, JSON_INVALID_NUMBER),
|
||||
JSON_ArrayGetDouble(tmp_arr, 1, JSON_INVALID_NUMBER),
|
||||
JSON_ArrayGetDouble(tmp_arr, 2, JSON_INVALID_NUMBER),
|
||||
};
|
||||
if (color.r != JSON_INVALID_NUMBER && color.g != JSON_INVALID_NUMBER
|
||||
&& color.b != JSON_INVALID_NUMBER) {
|
||||
settings->water_color.is_present = true;
|
||||
settings->water_color.value = (RGB_888) {
|
||||
color.r * 255.0f,
|
||||
color.g * 255.0f,
|
||||
color.b * 255.0f,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void M_LoadLevelGameSpecifics(
|
||||
|
|
31
src/libtrx/game/level/settings.c
Normal file
31
src/libtrx/game/level/settings.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include "game/level/settings.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "game/game_flow.h"
|
||||
|
||||
RGB_888 Level_GetWaterColor(void)
|
||||
{
|
||||
const GF_LEVEL *const level = GF_GetCurrentLevel();
|
||||
if (level != nullptr && level->settings.water_color.is_present) {
|
||||
return level->settings.water_color.value;
|
||||
}
|
||||
return g_Config.visuals.water_color;
|
||||
}
|
||||
|
||||
float Level_GetFogStart(void)
|
||||
{
|
||||
const GF_LEVEL *const level = GF_GetCurrentLevel();
|
||||
if (level != nullptr && level->settings.fog_start.is_present) {
|
||||
return level->settings.fog_start.value;
|
||||
}
|
||||
return g_Config.visuals.fog_start;
|
||||
}
|
||||
|
||||
float Level_GetFogEnd(void)
|
||||
{
|
||||
const GF_LEVEL *const level = GF_GetCurrentLevel();
|
||||
if (level != nullptr && level->settings.fog_end.is_present) {
|
||||
return level->settings.fog_end.value;
|
||||
}
|
||||
return g_Config.visuals.fog_end;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../colors.h"
|
||||
#include "../game/input.h"
|
||||
#include "../game/sound/enum.h"
|
||||
#include "../gfx/common.h"
|
||||
|
@ -50,6 +51,8 @@ typedef struct {
|
|||
bool fix_item_rots;
|
||||
int32_t fov;
|
||||
bool use_pcx_fov;
|
||||
|
||||
RGB_888 water_color;
|
||||
int32_t fog_start;
|
||||
int32_t fog_end;
|
||||
} visuals;
|
||||
|
|
|
@ -82,12 +82,11 @@ typedef struct {
|
|||
bool is_present;
|
||||
float value;
|
||||
} fog_start, fog_end;
|
||||
#if TR_VERSION == 1
|
||||
struct {
|
||||
bool is_present;
|
||||
RGB_888 value;
|
||||
} water_color;
|
||||
#elif TR_VERSION == 2
|
||||
#if TR_VERSION == 2
|
||||
char *sfx_path;
|
||||
#endif
|
||||
} GF_LEVEL_SETTINGS;
|
||||
|
|
|
@ -132,3 +132,6 @@ GS_DEFINE(DETAIL_FLOAT_FMT, "%.1f")
|
|||
GS_DEFINE(DETAIL_TITLE, "Graphic Options")
|
||||
GS_DEFINE(DETAIL_FOG_START, "Fog start")
|
||||
GS_DEFINE(DETAIL_FOG_END, "Fog end")
|
||||
GS_DEFINE(DETAIL_WATER_COLOR_R, "Water color (R)")
|
||||
GS_DEFINE(DETAIL_WATER_COLOR_G, "Water color (G)")
|
||||
GS_DEFINE(DETAIL_WATER_COLOR_B, "Water color (B)")
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include "level/common.h"
|
||||
#include "level/settings.h"
|
||||
#include "level/types.h"
|
||||
|
|
7
src/libtrx/include/libtrx/game/level/settings.h
Normal file
7
src/libtrx/include/libtrx/game/level/settings.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../colors.h"
|
||||
|
||||
extern RGB_888 Level_GetWaterColor(void);
|
||||
extern float Level_GetFogStart(void);
|
||||
extern float Level_GetFogEnd(void);
|
|
@ -163,6 +163,7 @@ sources = [
|
|||
'game/lara/misc.c',
|
||||
'game/level/common.c',
|
||||
'game/level/faces.c',
|
||||
'game/level/settings.c',
|
||||
'game/math/trig.c',
|
||||
'game/math/util.c',
|
||||
'game/matrix.c',
|
||||
|
|
|
@ -8,9 +8,6 @@ GS_DEFINE(PASSPORT_MODE_NEW_GAME_PLUS, "New Game+")
|
|||
GS_DEFINE(PASSPORT_MODE_NEW_GAME_JP, "Japanese NG")
|
||||
GS_DEFINE(PASSPORT_MODE_NEW_GAME_JP_PLUS, "Japanese NG+")
|
||||
GS_DEFINE(DETAIL_FPS, "FPS")
|
||||
GS_DEFINE(DETAIL_WATER_COLOR_R, "Water color (R)")
|
||||
GS_DEFINE(DETAIL_WATER_COLOR_G, "Water color (G)")
|
||||
GS_DEFINE(DETAIL_WATER_COLOR_B, "Water color (B)")
|
||||
GS_DEFINE(DETAIL_TRAPEZOID_FILTER, "Trapezoid filter")
|
||||
GS_DEFINE(DETAIL_REFLECTIONS, "Reflections")
|
||||
GS_DEFINE(DETAIL_BILINEAR, "Bilinear")
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "game/carrier.h"
|
||||
#include "game/effects.h"
|
||||
#include "game/game.h"
|
||||
#include "game/game_flow.h"
|
||||
#include "game/inventory_ring/vars.h"
|
||||
#include "game/items.h"
|
||||
#include "game/lara/common.h"
|
||||
|
@ -333,33 +332,6 @@ void Level_Load(const GF_LEVEL *const level)
|
|||
Benchmark_End(&benchmark, nullptr);
|
||||
}
|
||||
|
||||
RGB_888 Level_GetWaterColor(void)
|
||||
{
|
||||
const GF_LEVEL *const level = GF_GetCurrentLevel();
|
||||
if (level != nullptr && level->settings.water_color.is_present) {
|
||||
return level->settings.water_color.value;
|
||||
}
|
||||
return g_Config.visuals.water_color;
|
||||
}
|
||||
|
||||
float Level_GetFogStart(void)
|
||||
{
|
||||
const GF_LEVEL *const level = GF_GetCurrentLevel();
|
||||
if (level != nullptr && level->settings.fog_start.is_present) {
|
||||
return level->settings.fog_start.value;
|
||||
}
|
||||
return g_Config.visuals.fog_start;
|
||||
}
|
||||
|
||||
float Level_GetFogEnd(void)
|
||||
{
|
||||
const GF_LEVEL *const level = GF_GetCurrentLevel();
|
||||
if (level != nullptr && level->settings.fog_end.is_present) {
|
||||
return level->settings.fog_end.value;
|
||||
}
|
||||
return g_Config.visuals.fog_end;
|
||||
}
|
||||
|
||||
void Level_Unload(void)
|
||||
{
|
||||
Output_ObserveLevelUnload();
|
||||
|
|
|
@ -2,11 +2,7 @@
|
|||
|
||||
#include "game/game_flow/types.h"
|
||||
|
||||
#include <libtrx/colors.h>
|
||||
#include <libtrx/game/level.h>
|
||||
|
||||
bool Level_Initialise(const GF_LEVEL *level, GF_SEQUENCE_CONTEXT seq_ctx);
|
||||
void Level_Load(const GF_LEVEL *level);
|
||||
|
||||
RGB_888 Level_GetWaterColor(void);
|
||||
float Level_GetFogStart(void);
|
||||
float Level_GetFogEnd(void);
|
||||
|
|
|
@ -387,7 +387,6 @@ void Output_SetWindowSize(int32_t width, int32_t height)
|
|||
|
||||
void Output_ApplyLevelSettings(void)
|
||||
{
|
||||
const RGB_888 color = Level_GetWaterColor();
|
||||
Output_SetWaterColor(Level_GetWaterColor());
|
||||
Output_SetFogStart(Level_GetFogStart() * WALL_L);
|
||||
Output_SetFogEnd(Level_GetFogEnd() * WALL_L);
|
||||
|
|
|
@ -410,21 +410,3 @@ void Level_Init(void)
|
|||
|
||||
Benchmark_End(&benchmark, nullptr);
|
||||
}
|
||||
|
||||
float Level_GetFogStart(void)
|
||||
{
|
||||
const GF_LEVEL *const level = GF_GetCurrentLevel();
|
||||
if (level != nullptr && level->settings.fog_start.is_present) {
|
||||
return level->settings.fog_start.value;
|
||||
}
|
||||
return g_Config.visuals.fog_start;
|
||||
}
|
||||
|
||||
float Level_GetFogEnd(void)
|
||||
{
|
||||
const GF_LEVEL *const level = GF_GetCurrentLevel();
|
||||
if (level != nullptr && level->settings.fog_end.is_present) {
|
||||
return level->settings.fog_end.value;
|
||||
}
|
||||
return g_Config.visuals.fog_end;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,9 @@
|
|||
|
||||
#include "game/game_flow/types.h"
|
||||
|
||||
#include <libtrx/game/level/common.h>
|
||||
#include <libtrx/game/level.h>
|
||||
|
||||
void Level_Init(void);
|
||||
bool Level_Initialise(const GF_LEVEL *level, GF_SEQUENCE_CONTEXT seq_ctx);
|
||||
bool Level_Load(const GF_LEVEL *level);
|
||||
void Level_Unload(void);
|
||||
|
||||
float Level_GetFogStart(void);
|
||||
float Level_GetFogEnd(void);
|
||||
|
|
|
@ -66,6 +66,7 @@ static BACKGROUND_TYPE m_BackgroundType = BK_TRANSPARENT;
|
|||
static XYZ_32 m_LsVectorView = {};
|
||||
|
||||
static int32_t m_FogEnd = 0;
|
||||
static RGB_F m_WaterColor = {};
|
||||
|
||||
static bool m_IsWaterEffect = false;
|
||||
static bool m_IsWibbleEffect = false;
|
||||
|
@ -411,6 +412,7 @@ static void M_CalcSkyboxLight(const OBJECT_MESH *const mesh)
|
|||
|
||||
void Output_ApplyLevelSettings(void)
|
||||
{
|
||||
Output_SetWaterColor(Level_GetWaterColor());
|
||||
Output_SetFogStart(Level_GetFogStart() * WALL_L);
|
||||
Output_SetFogEnd(Level_GetFogEnd() * WALL_L);
|
||||
Viewport_Reset();
|
||||
|
@ -940,6 +942,21 @@ int32_t Output_GetFarZ(void)
|
|||
return Output_GetFogEnd() << W2V_SHIFT;
|
||||
}
|
||||
|
||||
void Output_SetWaterColor(const RGB_888 color)
|
||||
{
|
||||
m_WaterColor.r = color.r / 255.0f;
|
||||
m_WaterColor.g = color.g / 255.0f;
|
||||
m_WaterColor.b = color.b / 255.0f;
|
||||
}
|
||||
|
||||
RGB_F Output_GetTint(void)
|
||||
{
|
||||
if (Output_IsShadeEffect()) {
|
||||
return m_WaterColor;
|
||||
}
|
||||
return (RGB_F) { 1.0f, 1.0f, 1.0f };
|
||||
}
|
||||
|
||||
int32_t Output_GetFogEnd(void)
|
||||
{
|
||||
return m_FogEnd;
|
||||
|
|
|
@ -91,3 +91,6 @@ void Output_SetSunsetTimer(int32_t timer);
|
|||
|
||||
int32_t Output_GetNearZ(void);
|
||||
int32_t Output_GetFarZ(void);
|
||||
|
||||
void Output_SetWaterColor(RGB_888 color);
|
||||
RGB_F Output_GetTint(void);
|
||||
|
|
|
@ -130,13 +130,10 @@ static void M_ShadeColor(
|
|||
GFX_3D_VERTEX *const target, uint32_t red, uint32_t green,
|
||||
const uint32_t blue, const uint8_t alpha)
|
||||
{
|
||||
if (Output_IsShadeEffect()) {
|
||||
red /= 2;
|
||||
green = green * 7 / 8;
|
||||
}
|
||||
target->r = red;
|
||||
target->g = green;
|
||||
target->b = blue;
|
||||
const RGB_F tint = Output_GetTint();
|
||||
target->r = red * tint.r;
|
||||
target->g = green * tint.g;
|
||||
target->b = blue * tint.b;
|
||||
target->a = alpha;
|
||||
}
|
||||
|
||||
|
|
|
@ -1439,8 +1439,11 @@ static void M_SetWet(RENDERER *const renderer, const bool is_wet)
|
|||
{
|
||||
M_PRIV *const priv = renderer->priv;
|
||||
if (is_wet) {
|
||||
const RGB_F tint = Output_GetTint();
|
||||
GFX_2D_Renderer_SetTint(
|
||||
priv->renderer_2d, (GFX_COLOR) { .r = 170, .g = 170, .b = 255 });
|
||||
priv->renderer_2d,
|
||||
(GFX_COLOR) {
|
||||
.r = tint.r * 255, .g = tint.g * 255, .b = tint.b * 255 });
|
||||
} else {
|
||||
GFX_2D_Renderer_SetTint(
|
||||
priv->renderer_2d, (GFX_COLOR) { .r = 255, .g = 255, .b = 255 });
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "game/ui/widgets/graphics_dialog.h"
|
||||
|
||||
#include <libtrx/config.h>
|
||||
#include <libtrx/debug.h>
|
||||
#include <libtrx/game/game_string.h>
|
||||
#include <libtrx/game/input.h>
|
||||
#include <libtrx/game/text.h>
|
||||
|
@ -19,6 +20,7 @@ typedef struct {
|
|||
void *target;
|
||||
int32_t min_value;
|
||||
int32_t max_value;
|
||||
int32_t misc;
|
||||
} M_OPTION;
|
||||
|
||||
typedef struct {
|
||||
|
@ -58,6 +60,7 @@ static M_OPTION m_Options[] = {
|
|||
.min_value = 1,
|
||||
.max_value = 100,
|
||||
},
|
||||
|
||||
{
|
||||
.option_type = COT_INT32,
|
||||
.label_id = GS_ID(DETAIL_FOG_END),
|
||||
|
@ -65,11 +68,40 @@ static M_OPTION m_Options[] = {
|
|||
.min_value = 1,
|
||||
.max_value = 100,
|
||||
},
|
||||
|
||||
{
|
||||
.option_type = COT_RGB888,
|
||||
.label_id = GS_ID(DETAIL_WATER_COLOR_R),
|
||||
.target = &g_Config.visuals.water_color,
|
||||
.min_value = 0,
|
||||
.max_value = 255,
|
||||
.misc = 0,
|
||||
},
|
||||
|
||||
{
|
||||
.option_type = COT_RGB888,
|
||||
.label_id = GS_ID(DETAIL_WATER_COLOR_G),
|
||||
.target = &g_Config.visuals.water_color,
|
||||
.min_value = 0,
|
||||
.max_value = 255,
|
||||
.misc = 1,
|
||||
},
|
||||
|
||||
{
|
||||
.option_type = COT_RGB888,
|
||||
.label_id = GS_ID(DETAIL_WATER_COLOR_B),
|
||||
.target = &g_Config.visuals.water_color,
|
||||
.min_value = 0,
|
||||
.max_value = 255,
|
||||
.misc = 2,
|
||||
},
|
||||
|
||||
{
|
||||
.target = nullptr,
|
||||
},
|
||||
};
|
||||
|
||||
static uint8_t *M_GetColorComponent(const M_OPTION *option);
|
||||
static void M_ClearRows(M_WIDGET *self);
|
||||
static char *M_FormatRowValue(int32_t row_idx);
|
||||
static bool M_CanChangeValue(int32_t row_idx, int32_t delta);
|
||||
|
@ -90,6 +122,21 @@ static void M_Control(M_WIDGET *self);
|
|||
static void M_Draw(M_WIDGET *self);
|
||||
static void M_Free(M_WIDGET *self);
|
||||
|
||||
static uint8_t *M_GetColorComponent(const M_OPTION *const option)
|
||||
{
|
||||
RGB_888 *const color = option->target;
|
||||
switch (option->misc) {
|
||||
case 0:
|
||||
return &color->r;
|
||||
case 1:
|
||||
return &color->g;
|
||||
case 2:
|
||||
return &color->b;
|
||||
}
|
||||
ASSERT_FAIL();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void M_ClearRows(M_WIDGET *const self)
|
||||
{
|
||||
for (int32_t i = 0; i < self->row_count; i++) {
|
||||
|
@ -115,6 +162,11 @@ static char *M_FormatRowValue(const int32_t row_idx)
|
|||
return String_Format(
|
||||
GS(DETAIL_INTEGER_FMT), *(int32_t *)option->target);
|
||||
break;
|
||||
case COT_RGB888: {
|
||||
const uint8_t *const component = M_GetColorComponent(option);
|
||||
return String_Format("%d", *component);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -132,6 +184,15 @@ static bool M_CanChangeValue(const int32_t row_idx, const int32_t delta)
|
|||
return *(int32_t *)option->target < option->max_value;
|
||||
}
|
||||
break;
|
||||
case COT_RGB888: {
|
||||
const uint8_t *const component = M_GetColorComponent(option);
|
||||
if (delta < 0) {
|
||||
return *component > option->min_value;
|
||||
} else if (delta > 0) {
|
||||
return *component < option->max_value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -160,6 +221,11 @@ static bool M_RequestChangeValue(
|
|||
case COT_INT32:
|
||||
*(int32_t *)option->target += delta;
|
||||
break;
|
||||
case COT_RGB888: {
|
||||
uint8_t *const component = M_GetColorComponent(option);
|
||||
*component += delta;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -197,13 +263,13 @@ static M_ROW *M_AddRow(
|
|||
M_ROW *const row = &self->rows[self->row_count - 1];
|
||||
|
||||
row->stack =
|
||||
UI_Stack_Create(UI_STACK_LAYOUT_HORIZONTAL, 200, UI_STACK_AUTO_SIZE);
|
||||
UI_Stack_Create(UI_STACK_LAYOUT_HORIZONTAL, 220, UI_STACK_AUTO_SIZE);
|
||||
UI_Stack_SetHAlign(row->stack, UI_STACK_H_ALIGN_DISTRIBUTE);
|
||||
|
||||
row->frame = UI_Frame_Create(row->stack, 0, 0);
|
||||
UI_Frame_SetFrameVisible(row->frame, false);
|
||||
|
||||
row->title_label = UI_Label_Create(left_text, 120, UI_LABEL_AUTO_SIZE);
|
||||
row->title_label = UI_Label_Create(left_text, 150, UI_LABEL_AUTO_SIZE);
|
||||
UI_Stack_AddChild(row->stack, row->title_label);
|
||||
|
||||
row->arrow_left_label = UI_Label_Create(
|
||||
|
@ -349,7 +415,6 @@ UI_WIDGET *UI_GraphicsDialog_Create(void)
|
|||
.free = (UI_WIDGET_FREE)M_Free,
|
||||
};
|
||||
|
||||
self->visible_rows = 2;
|
||||
self->outer_stack = UI_Stack_Create(
|
||||
UI_STACK_LAYOUT_VERTICAL, UI_STACK_AUTO_SIZE, UI_STACK_AUTO_SIZE);
|
||||
UI_Stack_SetHAlign(self->outer_stack, UI_STACK_H_ALIGN_CENTER);
|
||||
|
@ -361,6 +426,11 @@ UI_WIDGET *UI_GraphicsDialog_Create(void)
|
|||
self->listener = UI_Events_Subscribe(
|
||||
"canvas_resize", nullptr, M_HandleCanvasResize, self);
|
||||
|
||||
self->visible_rows = 0;
|
||||
for (int32_t i = 0; m_Options[i].target != nullptr; i++) {
|
||||
self->visible_rows++;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; m_Options[i].target != nullptr; i++) {
|
||||
char *value_text = M_FormatRowValue(i);
|
||||
M_AddRow(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue