diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 22c1def27..15d845c29 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -99,6 +99,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 lua_blockmaplib.c lua_hudlib.c lua_hudlib_drawlist.c + lua_colorlib.c lua_inputlib.c ) diff --git a/src/Sourcefile b/src/Sourcefile index 6ed1f3b4c..7beb98c9e 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -94,3 +94,4 @@ lua_blockmaplib.c lua_hudlib.c lua_hudlib_drawlist.c lua_inputlib.c +lua_colorlib.c diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 74c4ed7d2..b02f2824a 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -276,9 +276,6 @@ struct FSurfaceInfo }; typedef struct FSurfaceInfo FSurfaceInfo; -#define GL_DEFAULTMIX 0x00000000 -#define GL_DEFAULTFOG 0xFF000000 - //Hurdler: added for backward compatibility enum hwdsetspecialstate { diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3185affbd..2b51e3d05 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -185,8 +185,8 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col RGBA_t poly_color, tint_color, fade_color; poly_color.rgba = 0xFFFFFFFF; - tint_color.rgba = (colormap != NULL) ? (UINT32)colormap->rgba : GL_DEFAULTMIX; - fade_color.rgba = (colormap != NULL) ? (UINT32)colormap->fadergba : GL_DEFAULTFOG; + tint_color.rgba = (colormap != NULL) ? (UINT32)colormap->rgba : 0x00000000; + fade_color.rgba = (colormap != NULL) ? (UINT32)colormap->fadergba : 0xFF000000; // Crappy backup coloring if you can't do shaders if (!HWR_UseShader()) @@ -200,7 +200,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col blue = (float)poly_color.s.blue; // 48 is just an arbritrary value that looked relatively okay. - tint_alpha = (float)(sqrt(tint_color.s.alpha) * 48) / 255.0f; + tint_alpha = (float)(sqrt((float)tint_color.s.alpha / 10.2) * 48) / 255.0f; // 8 is roughly the brightness of the "close" color in Software, and 16 the brightness of the "far" color. // 8 is too bright for dark levels, and 16 is too dark for bright levels. @@ -243,7 +243,7 @@ UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if RGBA_t realcolor, surfcolor; INT32 alpha; - realcolor.rgba = (colormap != NULL) ? colormap->rgba : GL_DEFAULTMIX; + realcolor.rgba = (colormap != NULL) ? colormap->rgba : 0x00000000; if (cv_glshaders.value && gl_shadersavailable) { diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 0f8342135..3e080105c 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1140,9 +1140,6 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski Z_ChangeTag(newMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED); } -#define NORMALFOG 0x00000000 -#define FADEFOG 0x19000000 - static boolean HWR_AllowModel(mobj_t *mobj) { // Signpost overlay. Not needed. diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 71cb5ca70..6c0c90fc5 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -697,7 +697,7 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f}; #define GLSL_SOFTWARE_TINT_EQUATION \ "if (tint_color.a > 0.0) {\n" \ "float color_bright = sqrt((base_color.r * base_color.r) + (base_color.g * base_color.g) + (base_color.b * base_color.b));\n" \ - "float strength = sqrt(9.0 * tint_color.a);\n" \ + "float strength = sqrt(tint_color.a);\n" \ "final_color.r = clamp((color_bright * (tint_color.r * strength)) + (base_color.r * (1.0 - strength)), 0.0, 1.0);\n" \ "final_color.g = clamp((color_bright * (tint_color.g * strength)) + (base_color.g * (1.0 - strength)), 0.0, 1.0);\n" \ "final_color.b = clamp((color_bright * (tint_color.b * strength)) + (base_color.b * (1.0 - strength)), 0.0, 1.0);\n" \ diff --git a/src/lua_baselib.c b/src/lua_baselib.c index bdc5c4501..9c723353b 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -213,6 +213,8 @@ static const struct { {META_HUDINFO, "hudinfo_t"}, {META_PATCH, "patch_t"}, {META_COLORMAP, "colormap"}, + {META_EXTRACOLORMAP,"extracolormap_t"}, + {META_LIGHTTABLE, "lighttable_t"}, {META_CAMERA, "camera_t"}, {META_ACTION, "action"}, @@ -2022,6 +2024,30 @@ static int lib_pCeilingzAtPos(lua_State *L) return 1; } +static int lib_pGetSectorColormapAt(lua_State *L) +{ + boolean has_sector = false; + sector_t *sector = NULL; + if (!lua_isnoneornil(L, 1)) + { + has_sector = true; + sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); + } + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); + fixed_t z = luaL_checkfixed(L, 4); + INLEVEL + if (has_sector && !sector) + return LUA_ErrInvalid(L, "sector_t"); + extracolormap_t *exc; + if (sector) + exc = P_GetColormapFromSectorAt(sector, x, y, z); + else + exc = P_GetSectorColormapAt(x, y, z); + LUA_PushUserdata(L, exc, META_EXTRACOLORMAP); + return 1; +} + static int lib_pDoSpring(lua_State *L) { mobj_t *spring = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -4304,6 +4330,7 @@ static luaL_Reg lib[] = { {"P_RadiusAttack",lib_pRadiusAttack}, {"P_FloorzAtPos",lib_pFloorzAtPos}, {"P_CeilingzAtPos",lib_pCeilingzAtPos}, + {"P_GetSectorColormapAt",lib_pGetSectorColormapAt}, {"P_DoSpring",lib_pDoSpring}, {"P_TouchSpecialThing",lib_pTouchSpecialThing}, {"P_TryCameraMove", lib_pTryCameraMove}, diff --git a/src/lua_colorlib.c b/src/lua_colorlib.c new file mode 100644 index 000000000..1e6e82333 --- /dev/null +++ b/src/lua_colorlib.c @@ -0,0 +1,332 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2021-2022 by "Lactozilla". +// Copyright (C) 2014-2023 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file lua_colorlib.c +/// \brief color and colormap libraries for Lua scripting + +#include "doomdef.h" +#include "fastcmp.h" +#include "r_data.h" + +#include "lua_script.h" +#include "lua_libs.h" + +#define IS_HEX_CHAR(x) ((x >= '0' && x <= '9') || (x >= 'a' && x <= 'f') || (x >= 'A' && x <= 'F')) +#define ARE_HEX_CHARS(str, i) IS_HEX_CHAR(str[i]) && IS_HEX_CHAR(str[i + 1]) + +static UINT32 hex2int(char x) +{ + if (x >= '0' && x <= '9') + return x - '0'; + else if (x >= 'a' && x <= 'f') + return x - 'a' + 10; + else if (x >= 'A' && x <= 'F') + return x - 'A' + 10; + + return 0; +} + +static UINT8 ParseHTMLColor(const char *str, UINT8 *rgba, size_t numc) +{ + const char *hex = str; + + if (hex[0] == '#') + hex++; + else if (!IS_HEX_CHAR(hex[0])) + return 0; + + size_t len = strlen(hex); + + if (len == 3) + { + // Shorthand like #09C + for (unsigned i = 0; i < 3; i++) + { + if (!IS_HEX_CHAR(hex[i])) + return 0; + + UINT32 hx = hex2int(hex[i]); + *rgba++ = (hx * 16) + hx; + } + + return 3; + } + else if (len == 6 || len == 8) + { + if (numc != 4) + len = 6; + + // A triplet like #0099CC + for (unsigned i = 0; i < len; i += 2) + { + if (!ARE_HEX_CHARS(hex, i)) + return false; + + *rgba++ = (hex2int(hex[i]) * 16) + hex2int(hex[i + 1]); + } + + return len; + } + + return 0; +} + +///////////////////////// +// extracolormap userdata +///////////////////////// + +enum extracolormap_e { + extracolormap_red = 0, + extracolormap_green, + extracolormap_blue, + extracolormap_alpha, + extracolormap_color, + extracolormap_fade_red, + extracolormap_fade_green, + extracolormap_fade_blue, + extracolormap_fade_alpha, + extracolormap_fade_color, + extracolormap_fade_start, + extracolormap_fade_end, + extracolormap_colormap +}; + +static const char *const extracolormap_opt[] = { + "red", + "green", + "blue", + "alpha", + "color", + "fade_red", + "fade_green", + "fade_blue", + "fade_alpha", + "fade_color", + "fade_start", + "fade_end", + "colormap", + NULL}; + +static int extracolormap_get(lua_State *L) +{ + extracolormap_t *exc = *((extracolormap_t **)luaL_checkudata(L, 1, META_EXTRACOLORMAP)); + enum extracolormap_e field = luaL_checkoption(L, 2, NULL, extracolormap_opt); + + switch (field) + { + case extracolormap_red: + lua_pushinteger(L, R_GetRgbaR(exc->rgba)); + break; + case extracolormap_green: + lua_pushinteger(L, R_GetRgbaG(exc->rgba)); + break; + case extracolormap_blue: + lua_pushinteger(L, R_GetRgbaB(exc->rgba)); + break; + case extracolormap_alpha: + lua_pushinteger(L, R_GetRgbaA(exc->rgba)); + break; + case extracolormap_color: + lua_pushinteger(L, R_GetRgbaR(exc->rgba)); + lua_pushinteger(L, R_GetRgbaG(exc->rgba)); + lua_pushinteger(L, R_GetRgbaB(exc->rgba)); + lua_pushinteger(L, R_GetRgbaA(exc->rgba)); + return 4; + case extracolormap_fade_red: + lua_pushinteger(L, R_GetRgbaR(exc->fadergba)); + break; + case extracolormap_fade_green: + lua_pushinteger(L, R_GetRgbaG(exc->fadergba)); + break; + case extracolormap_fade_blue: + lua_pushinteger(L, R_GetRgbaB(exc->fadergba)); + break; + case extracolormap_fade_alpha: + lua_pushinteger(L, R_GetRgbaA(exc->fadergba)); + break; + case extracolormap_fade_color: + lua_pushinteger(L, R_GetRgbaR(exc->fadergba)); + lua_pushinteger(L, R_GetRgbaG(exc->fadergba)); + lua_pushinteger(L, R_GetRgbaB(exc->fadergba)); + lua_pushinteger(L, R_GetRgbaA(exc->fadergba)); + return 4; + case extracolormap_fade_start: + lua_pushinteger(L, exc->fadestart); + break; + case extracolormap_fade_end: + lua_pushinteger(L, exc->fadeend); + break; + case extracolormap_colormap: + LUA_PushUserdata(L, exc->colormap, META_LIGHTTABLE); + break; + } + return 1; +} + +static void GetExtraColormapRGBA(lua_State *L, UINT8 *rgba, int arg) +{ + if (lua_type(L, arg) == LUA_TSTRING) + { + const char *str = lua_tostring(L, arg); + UINT8 parsed = ParseHTMLColor(str, rgba, 4); + if (!parsed) + luaL_error(L, "Malformed HTML color '%s'", str); + } + else + { + UINT32 colors = lua_tointeger(L, arg); + if (colors > 0xFFFFFF) + { + rgba[0] = (colors >> 24) & 0xFF; + rgba[1] = (colors >> 16) & 0xFF; + rgba[2] = (colors >> 8) & 0xFF; + rgba[3] = colors & 0xFF; + } + else + { + rgba[0] = (colors >> 16) & 0xFF; + rgba[1] = (colors >> 8) & 0xFF; + rgba[2] = colors & 0xFF; + rgba[3] = 0xFF; + } + } +} + +static int extracolormap_set(lua_State *L) +{ + extracolormap_t *exc = *((extracolormap_t **)luaL_checkudata(L, 1, META_EXTRACOLORMAP)); + enum extracolormap_e field = luaL_checkoption(L, 2, NULL, extracolormap_opt); + + UINT8 r = R_GetRgbaR(exc->rgba); + UINT8 g = R_GetRgbaG(exc->rgba); + UINT8 b = R_GetRgbaB(exc->rgba); + UINT8 a = R_GetRgbaA(exc->rgba); + + UINT8 fr = R_GetRgbaR(exc->fadergba); + UINT8 fg = R_GetRgbaG(exc->fadergba); + UINT8 fb = R_GetRgbaB(exc->fadergba); + UINT8 fa = R_GetRgbaA(exc->fadergba); + + UINT8 rgba[4]; + + INT32 old_rgba = exc->rgba, old_fade_rgba = exc->fadergba; // It's not unsigned? + UINT8 old_fade_start = exc->fadestart, old_fade_end = exc->fadeend; + +#define val luaL_checkinteger(L, 3) + + switch(field) + { + case extracolormap_red: + exc->rgba = R_PutRgbaRGBA(val, g, b, a); + break; + case extracolormap_green: + exc->rgba = R_PutRgbaRGBA(r, val, b, a); + break; + case extracolormap_blue: + exc->rgba = R_PutRgbaRGBA(r, g, val, a); + break; + case extracolormap_alpha: + exc->rgba = R_PutRgbaRGBA(r, g, b, val); + break; + case extracolormap_color: + rgba[0] = r; + rgba[1] = g; + rgba[2] = b; + rgba[3] = a; + GetExtraColormapRGBA(L, rgba, 3); + exc->rgba = R_PutRgbaRGBA(rgba[0], rgba[1], rgba[2], rgba[3]); + break; + case extracolormap_fade_red: + exc->fadergba = R_PutRgbaRGBA(val, fg, fb, fa); + break; + case extracolormap_fade_green: + exc->fadergba = R_PutRgbaRGBA(fr, val, fb, fa); + break; + case extracolormap_fade_blue: + exc->fadergba = R_PutRgbaRGBA(fr, fg, val, fa); + break; + case extracolormap_fade_alpha: + exc->fadergba = R_PutRgbaRGBA(fr, fg, fb, val); + break; + case extracolormap_fade_color: + rgba[0] = fr; + rgba[1] = fg; + rgba[2] = fb; + rgba[3] = fa; + GetExtraColormapRGBA(L, rgba, 3); + exc->fadergba = R_PutRgbaRGBA(rgba[0], rgba[1], rgba[2], rgba[3]); + break; + case extracolormap_fade_start: + if (val > 31) + return luaL_error(L, "fade start %d out of range (0 - 31)", val); + exc->fadestart = val; + break; + case extracolormap_fade_end: + if (val > 31) + return luaL_error(L, "fade end %d out of range (0 - 31)", val); + exc->fadeend = val; + break; + case extracolormap_colormap: + return luaL_error(L, LUA_QL("extracolormap_t") " field " LUA_QS " should not be set directly.", extracolormap_opt[field]); + } + +#undef val + + if (exc->rgba != old_rgba + || exc->fadergba != old_fade_rgba + || exc->fadestart != old_fade_start + || exc->fadeend != old_fade_end) + R_GenerateLightTable(exc, true); + + return 0; +} + +static int lighttable_get(lua_State *L) +{ + void **userdata; + + lighttable_t *table = *((lighttable_t **)luaL_checkudata(L, 1, META_LIGHTTABLE)); + UINT32 row = luaL_checkinteger(L, 2); + if (row < 1 || row > 34) + return luaL_error(L, "lighttable row %d out of range (1 - %d)", row, 34); + + userdata = lua_newuserdata(L, sizeof(void *)); + *userdata = &table[256 * (row - 1)]; + luaL_getmetatable(L, META_COLORMAP); + lua_setmetatable(L, -2); + + return 1; +} + +static int lighttable_len(lua_State *L) +{ + lua_pushinteger(L, NUM_PALETTE_ENTRIES); + return 1; +} + +int LUA_ColorLib(lua_State *L) +{ + luaL_newmetatable(L, META_EXTRACOLORMAP); + lua_pushcfunction(L, extracolormap_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, extracolormap_set); + lua_setfield(L, -2, "__newindex"); + lua_pop(L, 1); + + luaL_newmetatable(L, META_LIGHTTABLE); + lua_pushcfunction(L, lighttable_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lighttable_len); + lua_setfield(L, -2, "__len"); + lua_pop(L, 1); + + return 0; +} diff --git a/src/lua_libs.h b/src/lua_libs.h index 2e3c70652..26f919ad8 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -85,6 +85,8 @@ extern boolean ignoregameinputs; #define META_HUDINFO "HUDINFO_T*" #define META_PATCH "PATCH_T*" #define META_COLORMAP "COLORMAP" +#define META_EXTRACOLORMAP "EXTRACOLORMAP_T*" +#define META_LIGHTTABLE "LIGHTTABLE_T*" #define META_CAMERA "CAMERA_T*" #define META_ACTION "ACTIONF_T*" @@ -112,4 +114,5 @@ int LUA_TagLib(lua_State *L); int LUA_PolyObjLib(lua_State *L); int LUA_BlockmapLib(lua_State *L); int LUA_HudLib(lua_State *L); +int LUA_ColorLib(lua_State *L); int LUA_InputLib(lua_State *L); diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 44224a8bc..603fc0d8f 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -57,6 +57,7 @@ enum sector_e { sector_ffloors, sector_fslope, sector_cslope, + sector_colormap, sector_flags, sector_specialflags, sector_damagetype, @@ -95,6 +96,7 @@ static const char *const sector_opt[] = { "ffloors", "f_slope", "c_slope", + "colormap", "flags", "specialflags", "damagetype", @@ -751,6 +753,9 @@ static int sector_get(lua_State *L) case sector_cslope: // c_slope LUA_PushUserdata(L, sector->c_slope, META_SLOPE); return 1; + case sector_colormap: // extra_colormap + LUA_PushUserdata(L, sector->extra_colormap, META_EXTRACOLORMAP); + return 1; case sector_flags: // flags lua_pushinteger(L, sector->flags); return 1; diff --git a/src/lua_script.c b/src/lua_script.c index 5cacc3f01..b0b6eeec7 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -58,6 +58,7 @@ static lua_CFunction liblist[] = { LUA_PolyObjLib, // polyobj_t LUA_BlockmapLib, // blockmap stuff LUA_HudLib, // HUD stuff + LUA_ColorLib, // general color functions LUA_InputLib, // inputs NULL }; diff --git a/src/m_misc.c b/src/m_misc.c index d4b272f1d..923a188c6 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2805,3 +2805,17 @@ boolean M_IsStringEmpty(const char *s) return true; } + +// Rounds off floating numbers and checks for 0 - 255 bounds +int M_RoundUp(double number) +{ + if (number > 255.0l) + return 255; + if (number < 0.0l) + return 0; + + if ((int)number <= (int)(number - 0.5f)) + return (int)number + 1; + + return (int)number; +} diff --git a/src/m_misc.h b/src/m_misc.h index 8cad7ba9a..753991e70 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -112,6 +112,9 @@ boolean M_IsStringEmpty(const char *s); // counting bits, for weapon ammo code, usually FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size); +// Rounds off floating numbers and checks for 0 - 255 bounds +int M_RoundUp(double number); + #include "w_wad.h" extern char configfile[MAX_WADPATH]; diff --git a/src/p_local.h b/src/p_local.h index 1f1548b86..ba033dc06 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -445,6 +445,10 @@ boolean PIT_PushableMoved(mobj_t *thing); boolean P_DoSpring(mobj_t *spring, mobj_t *object); +INT32 P_GetSectorLightAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z); +extracolormap_t *P_GetColormapFromSectorAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z); +extracolormap_t *P_GetSectorColormapAt(fixed_t x, fixed_t y, fixed_t z); + // // P_SETUP // diff --git a/src/p_map.c b/src/p_map.c index 667ce49ee..6a152c563 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -5071,3 +5071,35 @@ fixed_t P_CeilingzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) return ceilingz; } + +INT32 P_GetSectorLightAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z) +{ + if (!sector->numlights) + return -1; + + INT32 light = sector->numlights - 1; + + // R_GetPlaneLight won't work on sloped lights! + for (INT32 lightnum = 1; lightnum < sector->numlights; lightnum++) { + fixed_t h = P_GetLightZAt(§or->lightlist[lightnum], x, y); + if (h <= z) { + light = lightnum - 1; + break; + } + } + + return light; +} + +extracolormap_t *P_GetColormapFromSectorAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z) +{ + if (sector->numlights) + return *sector->lightlist[P_GetSectorLightAt(sector, x, y, z)].extra_colormap; + else + return sector->extra_colormap; +} + +extracolormap_t *P_GetSectorColormapAt(fixed_t x, fixed_t y, fixed_t z) +{ + return P_GetColormapFromSectorAt(R_PointInSubsector(x, y)->sector, x, y, z); +} diff --git a/src/r_data.c b/src/r_data.c index 4b7492f90..e2b74da40 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -438,7 +438,7 @@ extracolormap_t *R_CreateDefaultColormap(boolean lighttable) exc->fadeend = 31; exc->flags = 0; exc->rgba = 0; - exc->fadergba = 0x19000000; + exc->fadergba = 0xFF000000; exc->colormap = lighttable ? R_CreateLightTable(exc) : NULL; #ifdef EXTRACOLORMAPLUMPS exc->lump = LUMPERROR; @@ -553,7 +553,7 @@ boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, && !flags) ) && (!checkrgba ? true : rgba == 0) - && (!checkfadergba ? true : fadergba == 0x19000000) + && (!checkfadergba ? true : (unsigned)fadergba == 0xFF000000) #ifdef EXTRACOLORMAPLUMPS && lump == LUMPERROR && extra_colormap->lumpname[0] == 0 @@ -654,7 +654,7 @@ extracolormap_t *R_ColormapForName(char *name) if (lump == LUMPERROR) I_Error("R_ColormapForName: Cannot find colormap lump %.8s\n", name); - exc = R_GetColormapFromListByValues(0, 0x19000000, 0, 31, 0, lump); + exc = R_GetColormapFromListByValues(0, 0xFF000000, 0, 31, 0, lump); if (exc) return exc; @@ -674,7 +674,7 @@ extracolormap_t *R_ColormapForName(char *name) exc->fadeend = 31; exc->flags = 0; exc->rgba = 0; - exc->fadergba = 0x19000000; + exc->fadergba = 0xFF000000; R_AddColormapToList(exc); @@ -692,9 +692,26 @@ extracolormap_t *R_ColormapForName(char *name) // static double deltas[256][3], map[256][3]; -static int RoundUp(double number); +static colorlookup_t lighttable_lut; + +static UINT8 LightTableNearest(UINT8 r, UINT8 g, UINT8 b) +{ + return NearestColor(r, g, b); +} + +static UINT8 LightTableNearest_LUT(UINT8 r, UINT8 g, UINT8 b) +{ + return GetColorLUT(&lighttable_lut, r, g, b); +} lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) +{ + extra_colormap->colormap = Z_MallocAlign((256 * 34) + 10, PU_LEVEL, NULL, 8); + R_GenerateLightTable(extra_colormap, false); + return extra_colormap->colormap; +} + +void R_GenerateLightTable(extracolormap_t *extra_colormap, boolean uselookup) { double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb; double maskamt = 0, othermask = 0; @@ -711,7 +728,6 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) UINT8 fadestart = extra_colormap->fadestart, fadedist = extra_colormap->fadeend - extra_colormap->fadestart; - lighttable_t *lighttable = NULL; size_t i; ///////////////////// @@ -721,7 +737,7 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) cmaskg = cg; cmaskb = cb; - maskamt = (double)(ca/24.0l); + maskamt = (double)(ca/255.0l); othermask = 1 - maskamt; maskamt /= 0xff; @@ -737,7 +753,7 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) cdestb = cfb; // fade alpha unused in software - // maskamt = (double)(cfa/24.0l); + // maskamt = (double)(cfa/255.0l); // othermask = 1 - maskamt; // maskamt /= 0xff; @@ -753,6 +769,16 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) int p; char *colormap_p; + UINT8 (*NearestColorFunc)(UINT8, UINT8, UINT8); + + if (uselookup) + { + InitColorLUT(&lighttable_lut, pMasterPalette, false); + NearestColorFunc = LightTableNearest_LUT; + } + else + NearestColorFunc = LightTableNearest; + // Initialise the map and delta arrays // map[i] stores an RGB color (as double) for index i, // which is then converted to SRB2's palette later @@ -783,8 +809,7 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) // Now allocate memory for the actual colormap array itself! // aligned on 8 bit for asm code - colormap_p = Z_MallocAlign((256 * 34) + 10, PU_LEVEL, NULL, 8); - lighttable = (UINT8 *)colormap_p; + colormap_p = (char *)extra_colormap->colormap; // Calculate the palette index for each palette index, for each light level // (as well as the two unused colormap lines we inherited from Doom) @@ -792,9 +817,9 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) { for (i = 0; i < 256; i++) { - *colormap_p = NearestColor((UINT8)RoundUp(map[i][0]), - (UINT8)RoundUp(map[i][1]), - (UINT8)RoundUp(map[i][2])); + *colormap_p = NearestColorFunc((UINT8)M_RoundUp(map[i][0]), + (UINT8)M_RoundUp(map[i][1]), + (UINT8)M_RoundUp(map[i][2])); colormap_p++; if ((UINT32)p < fadestart) @@ -818,8 +843,6 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) } } } - - return lighttable; } extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3) @@ -828,7 +851,7 @@ extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3) UINT8 cr = 0, cg = 0, cb = 0, ca = 0, cfr = 0, cfg = 0, cfb = 0, cfa = 25; UINT32 fadestart = 0, fadeend = 31; UINT8 flags = 0; - INT32 rgba = 0, fadergba = 0x19000000; + INT32 rgba = 0, fadergba = 0xFF000000; #define HEX2INT(x) (UINT32)(x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0) #define ALPHA2INT(x) (x >= 'a' && x <= 'z' ? x - 'a' : x >= 'A' && x <= 'Z' ? x - 'A' : x >= '0' && x <= '9' ? 25 : 0) @@ -836,13 +859,13 @@ extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3) // Get base colormap value // First alpha-only, then full value if (p1[0] >= 'a' && p1[0] <= 'z' && !p1[1]) - ca = (p1[0] - 'a'); + ca = ((p1[0] - 'a') * 102) / 10; else if (p1[0] == '#' && p1[1] >= 'a' && p1[1] <= 'z' && !p1[2]) - ca = (p1[1] - 'a'); + ca = ((p1[1] - 'a') * 102) / 10; else if (p1[0] >= 'A' && p1[0] <= 'Z' && !p1[1]) - ca = (p1[0] - 'A'); + ca = ((p1[0] - 'A') * 102) / 10; else if (p1[0] == '#' && p1[1] >= 'A' && p1[1] <= 'Z' && !p1[2]) - ca = (p1[1] - 'A'); + ca = ((p1[1] - 'A') * 102) / 10; else if (p1[0] == '#') { // For each subsequent value, the value before it must exist @@ -858,20 +881,20 @@ extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3) cb = ((HEX2INT(p1[5]) * 16) + HEX2INT(p1[6])); if (p1[7] >= 'a' && p1[7] <= 'z') - ca = (p1[7] - 'a'); + ca = ((p1[7] - 'a') * 102) / 10; else if (p1[7] >= 'A' && p1[7] <= 'Z') - ca = (p1[7] - 'A'); + ca = ((p1[7] - 'A') * 102) / 10; else - ca = 25; + ca = 255; } else - ca = 25; + ca = 255; } else - ca = 25; + ca = 255; } else - ca = 25; + ca = 255; } #define NUMFROMCHAR(c) (c >= '0' && c <= '9' ? c - '0' : 0) @@ -901,13 +924,13 @@ extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3) // Get fade (dark) colormap value // First alpha-only, then full value if (p3[0] >= 'a' && p3[0] <= 'z' && !p3[1]) - cfa = (p3[0] - 'a'); + cfa = ((p3[0] - 'a') * 102) / 10; else if (p3[0] == '#' && p3[1] >= 'a' && p3[1] <= 'z' && !p3[2]) - cfa = (p3[1] - 'a'); + cfa = ((p3[1] - 'a') * 102) / 10; else if (p3[0] >= 'A' && p3[0] <= 'Z' && !p3[1]) - cfa = (p3[0] - 'A'); + cfa = ((p3[0] - 'A') * 102) / 10; else if (p3[0] == '#' && p3[1] >= 'A' && p3[1] <= 'Z' && !p3[2]) - cfa = (p3[1] - 'A'); + cfa = ((p3[1] - 'A') * 102) / 10; else if (p3[0] == '#') { // For each subsequent value, the value before it must exist @@ -923,20 +946,20 @@ extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3) cfb = ((HEX2INT(p3[5]) * 16) + HEX2INT(p3[6])); if (p3[7] >= 'a' && p3[7] <= 'z') - cfa = (p3[7] - 'a'); + cfa = ((p3[7] - 'a') * 102) / 10; else if (p3[7] >= 'A' && p3[7] <= 'Z') - cfa = (p3[7] - 'A'); + cfa = ((p3[7] - 'A') * 102) / 10; else - cfa = 25; + cfa = 255; } else - cfa = 25; + cfa = 255; } else - cfa = 25; + cfa = 255; } else - cfa = 25; + cfa = 255; } #undef ALPHA2INT #undef HEX2INT @@ -1133,20 +1156,6 @@ UINT8 NearestPaletteColor(UINT8 r, UINT8 g, UINT8 b, RGBA_t *palette) return (UINT8)bestcolor; } -// Rounds off floating numbers and checks for 0 - 255 bounds -static int RoundUp(double number) -{ - if (number > 255.0l) - return 255; - if (number < 0.0l) - return 0; - - if ((int)number <= (int)(number - 0.5f)) - return (int)number + 1; - - return (int)number; -} - #ifdef EXTRACOLORMAPLUMPS const char *R_NameForColormap(extracolormap_t *extra_colormap) { diff --git a/src/r_data.h b/src/r_data.h index ef5c967e5..364f85b6d 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -92,6 +92,7 @@ typedef enum TMCF_OVERRIDE = 1<<13, } textmapcolormapflags_t; +void R_GenerateLightTable(extracolormap_t *extra_colormap, boolean uselookup); lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap); extracolormap_t * R_CreateColormapFromLinedef(char *p1, char *p2, char *p3); extracolormap_t* R_CreateColormap(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags); diff --git a/src/r_defs.h b/src/r_defs.h index 3671b49d9..4cb8c1769 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -53,6 +53,9 @@ typedef struct // Could even use more than 32 levels. typedef UINT8 lighttable_t; +#define NUM_PALETTE_ENTRIES 256 +#define DEFAULT_STARTTRANSCOLOR 96 + #define CMF_FADEFULLBRIGHTSPRITES 1 #define CMF_FOG 4 diff --git a/src/r_draw.c b/src/r_draw.c index df9e1a460..671767b21 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -132,8 +132,6 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; #define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4) #define BLINK_TT_CACHE_INDEX (MAXSKINS + 5) #define DASHMODE_TT_CACHE_INDEX (MAXSKINS + 6) -#define DEFAULT_STARTTRANSCOLOR 96 -#define NUM_PALETTE_ENTRIES 256 static UINT8 **translationtablecache[MAXSKINS + 7] = {NULL}; UINT8 skincolor_modified[MAXSKINCOLORS]; diff --git a/src/r_things.c b/src/r_things.c index 699013602..557e16814 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1320,8 +1320,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, patch_t *patch; fixed_t xscale, yscale, shadowxscale, shadowyscale, shadowskew, x1, x2; INT32 heightsec, phs; - INT32 light = 0; - fixed_t scalemul; UINT8 trans; + fixed_t scalemul; + UINT8 trans; fixed_t floordiff; fixed_t groundz; pslope_t *groundslope; @@ -1437,27 +1437,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, if (thing->renderflags & RF_NOCOLORMAPS) shadow->extra_colormap = NULL; else - { - if (thing->subsector->sector->numlights) - { - INT32 lightnum; - light = thing->subsector->sector->numlights - 1; - - // R_GetPlaneLight won't work on sloped lights! - for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { - fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], interp.x, interp.y); - if (h <= shadow->gzt) { - light = lightnum - 1; - break; - } - } - } - - if (thing->subsector->sector->numlights) - shadow->extra_colormap = *thing->subsector->sector->lightlist[light].extra_colormap; - else - shadow->extra_colormap = thing->subsector->sector->extra_colormap; - } + shadow->extra_colormap = P_GetColormapFromSectorAt(thing->subsector->sector, interp.x, interp.y, shadow->gzt); shadow->transmap = R_GetTranslucencyTable(trans + 1); shadow->colormap = scalelight[0][0]; // full dark! @@ -2154,21 +2134,9 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->numlights) { - INT32 lightnum; - fixed_t top = (splat) ? gz : gzt; - light = thing->subsector->sector->numlights - 1; - - // R_GetPlaneLight won't work on sloped lights! - for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { - fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], interp.x, interp.y); - if (h <= top) { - light = lightnum - 1; - break; - } - } - //light = R_GetPlaneLight(thing->subsector->sector, gzt, false); - lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT); + light = P_GetSectorLightAt(thing->subsector->sector, interp.x, interp.y, splat ? gz : gzt); + INT32 lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT); if (lightnum < 0) spritelights = scalelight[0]; else if (lightnum >= LIGHTLEVELS)