diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 350c1585fab2478bf4dfa438306215a510b330b2..05e19f9d538483bd4280051c5655c816336b0ee5 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -210,6 +210,9 @@ static const struct { {META_HUDINFO, "hudinfo_t"}, {META_PATCH, "patch_t"}, {META_COLORMAP, "colormap"}, + {META_TRANSLATION, "translation"}, + {META_EXTRACOLORMAP,"extracolormap_t"}, + {META_LIGHTTABLE, "lighttable_t"}, {META_CAMERA, "camera_t"}, {META_ACTION, "action"}, diff --git a/src/lua_colorlib.c b/src/lua_colorlib.c index 2365ffb440bb27bf5ccbd7ee4c7bbc5e9edf8f6f..41df3aaebff945fa70c7dee91db229b10674ccf7 100644 --- a/src/lua_colorlib.c +++ b/src/lua_colorlib.c @@ -31,6 +31,36 @@ #define GetNearestColor(r, g, b) NearestPaletteColor(r, g, b, pMasterPalette) #endif +/////////////////// +// Colormap library +/////////////////// + +UINT8* LUA_CheckColormap(lua_State *L, int ud) +{ + void *p = lua_touserdata(L, ud); + + if (p != NULL && lua_getmetatable(L, ud)) { + lua_getfield(L, LUA_REGISTRYINDEX, META_COLORMAP); + if (lua_rawequal(L, -1, -2)) { + lua_pop(L, 2); + return (*((colormap_t **)p))->map; + } + + lua_pop(L, 1); + + lua_getfield(L, LUA_REGISTRYINDEX, META_TRANSLATION); + if (lua_rawequal(L, -1, -2)) { + lua_pop(L, 2); + return *((UINT8 **)p); + } + + lua_pop(L, 2); + } + + luaL_typerror(L, ud, "colormap or translation"); + return NULL; +} + static int colormap_get(lua_State *L) { colormap_t *colormap = *((colormap_t **)luaL_checkudata(L, 1, META_COLORMAP)); @@ -45,8 +75,6 @@ static int colormap_set(lua_State *L) { colormap_t *colormap = *((colormap_t **)luaL_checkudata(L, 1, META_COLORMAP)); UINT32 i = luaL_checkinteger(L, 2); - if (colormap->flags & GTC_CACHE) - return luaL_error(L, "colormap is read-only"); if (i >= 256) return luaL_error(L, "colormap index %d out of range (0 - %d)", i, 255); colormap->map[i] = (UINT8)luaL_checkinteger(L, 3); @@ -55,8 +83,7 @@ static int colormap_set(lua_State *L) static int colormap_len(lua_State *L) { - colormap_t *colormap = *((colormap_t **)luaL_checkudata(L, 1, META_COLORMAP)); - lua_pushinteger(L, colormap->rows); + lua_pushinteger(L, NUM_PALETTE_ENTRIES); return 1; } @@ -67,6 +94,24 @@ static int colormap_free(lua_State *L) return 0; } +static int translation_get(lua_State *L) +{ + UINT8 *colormap = *((UINT8 **)luaL_checkudata(L, 1, META_TRANSLATION)); + UINT32 i = luaL_checkinteger(L, 2); + if (i >= 256) + return luaL_error(L, "colormap index %d out of range (0 - %d)", i, 255); + lua_pushinteger(L, colormap[i]); + return 1; +} + +// See colormap_len. I assume there isn't any problem with two metatables +// sharing the same metamethod, but I didn't want to risk it... +static int translation_len(lua_State *L) +{ + lua_pushinteger(L, NUM_PALETTE_ENTRIES); + return 1; +} + static void MakeRGBColormap(UINT8 *colormap, UINT8 cr, UINT8 cg, UINT8 cb, UINT8 ca, UINT16 start, UINT16 end) { double r, g, b, cbrightness; @@ -222,10 +267,7 @@ static int lib_colormapCreate(lua_State *L) GenerateColormap(L, generated_colormap); - colormap = Z_MallocAlign(sizeof(colormap_t) + NUM_PALETTE_ENTRIES, PU_STATIC, NULL, 8); - colormap->rows = 1; - colormap->flags = 0; - + colormap = Z_MallocAlign(sizeof(colormap_t), PU_STATIC, NULL, 8); M_Memcpy(colormap->map, generated_colormap, NUM_PALETTE_ENTRIES); userdata = lua_newuserdata(L, sizeof(void *)); @@ -241,9 +283,6 @@ static int lib_colormapGenerate(lua_State *L) { colormap_t *colormap = *((colormap_t **)luaL_checkudata(L, 1, META_COLORMAP)); - if (colormap->flags & GTC_CACHE) - return luaL_error(L, "colormap is read-only"); - lua_remove(L, 1); GenerateColormap(L, colormap->map); @@ -254,15 +293,12 @@ static int lib_colormapGenerate(lua_State *L) static int lib_colormapMix(lua_State *L) { colormap_t *colormapA = *((colormap_t **)luaL_checkudata(L, 1, META_COLORMAP)); - colormap_t *colormapB = *((colormap_t **)luaL_checkudata(L, 2, META_COLORMAP)); + UINT8 *colormapB = LUA_CheckColormap(L, 2); INT32 amt = luaL_checkinteger(L, 3); INT32 mode = luaL_optinteger(L, 4, AST_TRANSLUCENT); INT32 start = luaL_optinteger(L, 5, 0); INT32 end = luaL_optinteger(L, 6, NUM_PALETTE_ENTRIES) - 1, i; - if (colormapA->flags & GTC_CACHE) - return luaL_error(L, "colormap is read-only"); - if (amt < 0 || amt > 255) luaL_error(L, "blend amount %d out of range (0 - %d)", amt, 255); @@ -286,7 +322,7 @@ static int lib_colormapMix(lua_State *L) { RGBA_t texel; RGBA_t bg = V_GetMasterColor(colormapA->map[i]); - RGBA_t fg = V_GetMasterColor(colormapB->map[i]); + RGBA_t fg = V_GetMasterColor(colormapB[i]); texel.rgba = ASTBlendPixel(bg, fg, mode, amt); colormapA->map[i] = GetNearestColor(texel.s.red, texel.s.green, texel.s.blue); } @@ -303,9 +339,6 @@ static int lib_colormapBlend(lua_State *L) INT32 start = luaL_optinteger(L, 5, 0); INT32 end = luaL_optinteger(L, 6, NUM_PALETTE_ENTRIES) - 1, i; - if (colormap->flags & GTC_CACHE) - return luaL_error(L, "colormap is read-only"); - if (amt < 0 || amt > 255) luaL_error(L, "blend amount %d out of range (0 - %d)", amt, 255); @@ -349,9 +382,6 @@ static int lib_colormapBlendRGB(lua_State *L) RGBA_t fg; - if (colormap->flags & GTC_CACHE) - return luaL_error(L, "colormap is read-only"); - if (amt < 0 || amt > 255) luaL_error(L, "blend amount %d out of range (0 - %d)", amt, 255); @@ -395,9 +425,6 @@ static int lib_colormapTint(lua_State *L) INT32 start = luaL_optinteger(L, 4, 0); INT32 end = luaL_optinteger(L, 5, NUM_PALETTE_ENTRIES) - 1; - if (colormap->flags & GTC_CACHE) - return luaL_error(L, "colormap is read-only"); - if (amt < 0 || amt > 255) luaL_error(L, "tint amount %d out of range (0 - %d)", amt, 255); @@ -425,9 +452,6 @@ static int lib_colormapTintRGB(lua_State *L) INT32 start = luaL_optinteger(L, 6, 0); INT32 end = luaL_optinteger(L, 7, NUM_PALETTE_ENTRIES) - 1; - if (colormap->flags & GTC_CACHE) - return luaL_error(L, "colormap is read-only"); - if (amt < 0 || amt > 255) luaL_error(L, "tint amount %d out of range (0 - %d)", amt, 255); @@ -448,13 +472,10 @@ static int lib_colormapTintRGB(lua_State *L) static int lib_colormapCopy(lua_State *L) { colormap_t *colormapA = *((colormap_t **)luaL_checkudata(L, 1, META_COLORMAP)); - colormap_t *colormapB = *((colormap_t **)luaL_checkudata(L, 2, META_COLORMAP)); + UINT8 *colormapB = LUA_CheckColormap(L, 2); INT32 start = luaL_optinteger(L, 3, 0); INT32 end = luaL_optinteger(L, 4, NUM_PALETTE_ENTRIES) - 1, i; - if (colormapA->flags & GTC_CACHE) - return luaL_error(L, "colormap is read-only"); - if (start < 0 || start >= NUM_PALETTE_ENTRIES) luaL_error(L, "start index %d out of range (0 - %d)", start, NUM_PALETTE_ENTRIES-1); if (end <= 0) @@ -465,7 +486,7 @@ static int lib_colormapCopy(lua_State *L) end = NUM_PALETTE_ENTRIES - 1; for (i = start; i <= end; i++) - colormapA->map[i] = colormapB->map[i]; + colormapA->map[i] = colormapB[i]; return 0; } @@ -477,9 +498,6 @@ static int lib_colormapCopySkinColor(lua_State *L) INT32 start = luaL_optinteger(L, 3, DEFAULT_STARTTRANSCOLOR); INT32 end, i, j = 0; - if (colormap->flags & GTC_CACHE) - return luaL_error(L, "colormap is read-only"); - if (skincolor < 0 || skincolor >= numskincolors) luaL_error(L, "skin color %d out of range (0 - %d)", skincolor, numskincolors-1); @@ -496,7 +514,7 @@ static int lib_colormapCopySkinColor(lua_State *L) return 0; } -static luaL_Reg lib[] = { +static luaL_Reg colormap_lib[] = { {"create", lib_colormapCreate}, {"generate", lib_colormapGenerate}, {"mix", lib_colormapMix}, @@ -509,6 +527,246 @@ static luaL_Reg lib[] = { {NULL, NULL} }; +///////////////////////// +// extracolormap userdata +///////////////////////// + +enum extracolormap_e { + extracolormap_r = 0, + extracolormap_g, + extracolormap_b, + extracolormap_a, + extracolormap_rgba, + extracolormap_fade_r, + extracolormap_fade_g, + extracolormap_fade_b, + extracolormap_fade_a, + extracolormap_fade_rgba, + extracolormap_fade_start, + extracolormap_fade_end, + extracolormap_colormap +}; + +static const char *const extracolormap_opt[] = { + "r", + "g", + "b", + "a", + "rgba", + "fade_r", + "fade_g", + "fade_b", + "fade_a", + "fade_rgba", + "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_r: + lua_pushinteger(L, R_GetRgbaR(exc->rgba)); + break; + case extracolormap_g: + lua_pushinteger(L, R_GetRgbaG(exc->rgba)); + break; + case extracolormap_b: + lua_pushinteger(L, R_GetRgbaB(exc->rgba)); + break; + case extracolormap_a: + lua_pushinteger(L, R_GetRgbaA(exc->rgba)); + break; + case extracolormap_rgba: + 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_r: + lua_pushinteger(L, R_GetRgbaR(exc->fadergba)); + break; + case extracolormap_fade_g: + lua_pushinteger(L, R_GetRgbaG(exc->fadergba)); + break; + case extracolormap_fade_b: + lua_pushinteger(L, R_GetRgbaB(exc->fadergba)); + break; + case extracolormap_fade_a: + lua_pushinteger(L, R_GetRgbaA(exc->fadergba)); + break; + case extracolormap_fade_rgba: + 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, R_GetRgbaA(exc->fadestart)); + break; + case extracolormap_fade_end: + lua_pushinteger(L, R_GetRgbaA(exc->fadeend)); + break; + case extracolormap_colormap: + LUA_PushUserdata(L, exc->colormap, META_LIGHTTABLE); + break; + } + return 1; +} + +static void GetExtraColormapRGBA(lua_State *L, UINT8 *rgba) +{ + luaL_checktype(L, 3, LUA_TTABLE); + lua_remove(L, 1); + lua_remove(L, 1); + lua_settop(L, 1); + lua_pushnil(L); + + while (lua_next(L, 1)) { + lua_Integer i = 0; + const char *field = NULL; + if (lua_isnumber(L, 2)) + i = lua_tointeger(L, 2); + else + field = luaL_checkstring(L, 2); + +#define CHECKFIELD(p, c) (i == p || (field && fastcmp(field, c))) +#define RGBASET(p) rgba[p] = (UINT8)luaL_checkinteger(L, 3) + + if (CHECKFIELD(1, "r")) { + RGBASET(0); + } else if (CHECKFIELD(2, "g")) { + RGBASET(1); + } else if (CHECKFIELD(3, "b")) { + RGBASET(2); + } else if (CHECKFIELD(4, "a")) { + RGBASET(3); + } + +#undef CHECKFIELD +#undef RGBASET + + lua_pop(L, 1); + } +} + +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_r: + exc->rgba = R_PutRgbaRGBA(val, g, b, a); + break; + case extracolormap_g: + exc->rgba = R_PutRgbaRGBA(r, val, b, a); + break; + case extracolormap_b: + exc->rgba = R_PutRgbaRGBA(r, g, val, a); + break; + case extracolormap_a: + exc->rgba = R_PutRgbaRGBA(r, g, b, val); + break; + case extracolormap_rgba: + rgba[0] = r; + rgba[1] = g; + rgba[2] = b; + rgba[3] = a; + GetExtraColormapRGBA(L, rgba); + exc->rgba = R_PutRgbaRGBA(rgba[0], rgba[1], rgba[2], rgba[3]); + break; + case extracolormap_fade_r: + exc->fadergba = R_PutRgbaRGBA(val, fg, fb, fa); + break; + case extracolormap_fade_g: + exc->fadergba = R_PutRgbaRGBA(fr, val, fb, fa); + break; + case extracolormap_fade_b: + exc->fadergba = R_PutRgbaRGBA(fr, fg, val, fa); + break; + case extracolormap_fade_a: + exc->fadergba = R_PutRgbaRGBA(fr, fg, fb, val); + break; + case extracolormap_fade_rgba: + rgba[0] = fr; + rgba[1] = fg; + rgba[2] = fb; + rgba[3] = fa; + GetExtraColormapRGBA(L, rgba); + 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_TRANSLATION); + 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_COLORMAP); @@ -525,6 +783,30 @@ int LUA_ColorLib(lua_State *L) lua_setfield(L, -2, "__gc"); lua_pop(L, 1); - luaL_register(L, "colormap", lib); + luaL_newmetatable(L, META_TRANSLATION); + lua_pushcfunction(L, translation_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, translation_len); + lua_setfield(L, -2, "__len"); + lua_pop(L, 1); + + 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); + + luaL_register(L, "colormap", colormap_lib); return 0; } diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 5b3f622da14ed6967a6070782e5647b73f780bf7..2228d897424752e95715790866338ca02d7fce4d 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -645,7 +645,7 @@ static int libd_draw(lua_State *L) return LUA_ErrInvalid(L, "patch_t"); flags = luaL_optinteger(L, 4, 0); if (!lua_isnoneornil(L, 5)) - colormap = (*((colormap_t **)luaL_checkudata(L, 5, META_COLORMAP)))->map; + colormap = LUA_CheckColormap(L, 5); flags &= ~V_PARAMMASK; // Don't let crashes happen. @@ -671,7 +671,7 @@ static int libd_drawScaled(lua_State *L) return LUA_ErrInvalid(L, "patch_t"); flags = luaL_optinteger(L, 5, 0); if (!lua_isnoneornil(L, 6)) - colormap = (*((colormap_t **)luaL_checkudata(L, 6, META_COLORMAP)))->map; + colormap = LUA_CheckColormap(L, 6); flags &= ~V_PARAMMASK; // Don't let crashes happen. @@ -698,7 +698,7 @@ static int libd_drawStretched(lua_State *L) patch = *((patch_t **)luaL_checkudata(L, 5, META_PATCH)); flags = luaL_optinteger(L, 6, 0); if (!lua_isnoneornil(L, 7)) - colormap = (*((colormap_t **)luaL_checkudata(L, 7, META_COLORMAP)))->map; + colormap = LUA_CheckColormap(L, 7); flags &= ~V_PARAMMASK; // Don't let crashes happen. @@ -725,7 +725,7 @@ static int libd_drawCropped(lua_State *L) patch = *((patch_t **)luaL_checkudata(L, 5, META_PATCH)); flags = luaL_checkinteger(L, 6); if (!lua_isnoneornil(L, 7)) - colormap = (*((colormap_t **)luaL_checkudata(L, 7, META_COLORMAP)))->map; + colormap = LUA_CheckColormap(L, 7); sx = luaL_checkinteger(L, 8); if (sx < 0) // Don't crash. Now, we could do "x-=sx*FRACUNIT; sx=0;" here... return luaL_error(L, "negative crop sx"); @@ -1008,7 +1008,7 @@ static int libd_getColormap(lua_State *L) { INT32 skinnum = TC_DEFAULT; skincolornum_t color = luaL_optinteger(L, 2, 0); - colormap_t* colormap = NULL; + UINT8* colormap = NULL; HUDONLY if (lua_isnoneornil(L, 1)) ; // defaults to TC_DEFAULT @@ -1029,8 +1029,8 @@ static int libd_getColormap(lua_State *L) } // all was successful above, now we generate the colormap at last! - colormap = R_GetTranslationColormap(skinnum, color, GTC_CACHE); - LUA_PushUserdata(L, colormap, META_COLORMAP); // push as META_COLORMAP userdata, specifically for patches to use! + colormap = R_GetCachedTranslation(skinnum, color); + LUA_PushUserdata(L, colormap, META_TRANSLATION); // push as META_TRANSLATION userdata, specifically for patches to use! return 1; } @@ -1043,9 +1043,7 @@ static int libd_getStringColormap(lua_State *L) HUDONLY colormap = V_GetStringColormap(flags & V_CHARCOLORMASK); if (colormap) { - lua_colormap = Z_MallocAlign(sizeof(colormap_t) + NUM_PALETTE_ENTRIES, PU_STATIC, NULL, 8); - lua_colormap->rows = 1; - lua_colormap->flags = 0; + lua_colormap = Z_MallocAlign(sizeof(colormap_t), PU_STATIC, NULL, 8); M_Memcpy(lua_colormap->map, colormap, NUM_PALETTE_ENTRIES * sizeof(UINT8)); userdata = lua_newuserdata(L, sizeof(void *)); diff --git a/src/lua_libs.h b/src/lua_libs.h index 6c96eb2d752dd1620547e1a567d326e9a9008a80..bc37aab6efea1976cda8e2cd93be3e3df7b74bd0 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -81,9 +81,13 @@ extern boolean mousegrabbedbylua; #define META_BBOX "BOUNDING_BOX" +#define META_COLORMAP "COLORMAP" +#define META_TRANSLATION "TRANSLATION" +#define META_EXTRACOLORMAP "EXTRACOLORMAP_T" +#define META_LIGHTTABLE "LIGHTTABLE_T" + #define META_HUDINFO "HUDINFO_T*" #define META_PATCH "PATCH_T*" -#define META_COLORMAP "COLORMAP" #define META_CAMERA "CAMERA_T*" #define META_ACTION "ACTIONF_T*" diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 9031c99f13a981fc6c235caea12a0fbfb9201e49..688e6c4554135021b2d6a0ff2ff00842100b6187 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -44,7 +44,8 @@ enum sector_e { sector_lines, sector_ffloors, sector_fslope, - sector_cslope + sector_cslope, + sector_extracolormap }; static const char *const sector_opt[] = { @@ -64,6 +65,7 @@ static const char *const sector_opt[] = { "ffloors", "f_slope", "c_slope", + "extra_colormap", NULL}; enum subsector_e { @@ -617,6 +619,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_extracolormap: // extra_colormap + LUA_PushUserdata(L, sector->extra_colormap, META_EXTRACOLORMAP); + return 1; } return 0; } @@ -644,6 +649,7 @@ static int sector_set(lua_State *L) case sector_ffloors: // ffloors case sector_fslope: // f_slope case sector_cslope: // c_slope + case sector_extracolormap: // extra_colormap default: return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]); case sector_floorheight: { // floorheight diff --git a/src/lua_script.h b/src/lua_script.h index e882569414452951429a99986c313137cc9613e9..d736bb20121557a715752157f5e738b92bc1e123 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -96,6 +96,8 @@ void LUA_InvalidateLevel(void); void LUA_InvalidateMapthings(void); void LUA_InvalidatePlayer(player_t *player); +UINT8* LUA_CheckColormap(lua_State *L, int ud); + // Console wrapper void COM_Lua_f(void); diff --git a/src/r_data.c b/src/r_data.c index 22e556e7a83b0cbf79e9e7c062001d99d75ffcfb..6f97a0262e3750458234cfaa665060a14784d74b 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -692,19 +692,26 @@ extracolormap_t *R_ColormapForName(char *name) // static double deltas[256][3], map[256][3]; -lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) +static colorlookup_t lighttable_lut; + +static UINT8 LightTableNearest(UINT8 r, UINT8 g, UINT8 b) { - colormap_t *c = Z_MallocAlign(sizeof(colormap_t) + (256 * 34) + 10, PU_LEVEL, NULL, 8); - extra_colormap->colormap = (lighttable_t *)((UINT8 *)c + sizeof(colormap_t)); + return NearestColor(r, g, b); +} - c->rows = 34; - c->flags = GTC_CACHE; - R_GenerateLightTable(extra_colormap); +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) +void R_GenerateLightTable(extracolormap_t *extra_colormap, boolean uselookup) { double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb; double maskamt = 0, othermask = 0; @@ -762,6 +769,16 @@ void R_GenerateLightTable(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 @@ -800,7 +817,7 @@ void R_GenerateLightTable(extracolormap_t *extra_colormap) { for (i = 0; i < 256; i++) { - *colormap_p = NearestColor((UINT8)M_RoundUp(map[i][0]), + *colormap_p = NearestColorFunc((UINT8)M_RoundUp(map[i][0]), (UINT8)M_RoundUp(map[i][1]), (UINT8)M_RoundUp(map[i][2])); colormap_p++; diff --git a/src/r_data.h b/src/r_data.h index 8642a69fae60a7024cbd68d839b753f31e0088cc..be003c7ec2fd448621810bc9273b60a7aadd89f4 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -95,7 +95,7 @@ typedef enum TMCF_OVERRIDE = 1<<13, } textmapcolormapflags_t; -void R_GenerateLightTable(extracolormap_t *extra_colormap); +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 74779c120317fa3a7a32168897461ae79e2d614e..6130994560ef9498466e8151819778ead1a5011b 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -58,9 +58,7 @@ typedef UINT8 lighttable_t; typedef struct colormap_s { - UINT8 rows; - UINT8 flags; - UINT8 map[0]; + UINT8 map[NUM_PALETTE_ENTRIES]; } colormap_t; #define CMF_FADEFULLBRIGHTSPRITES 1 diff --git a/src/r_draw.c b/src/r_draw.c index b67acc6907b087cb2dcfdabaa868d4870384bab8..a1cad798d6a8bfab6b5cd636d66d959062fc9df1 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -133,7 +133,7 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; #define BLINK_TT_CACHE_INDEX (MAXSKINS + 5) #define DASHMODE_TT_CACHE_INDEX (MAXSKINS + 6) -static colormap_t **translationtablecache[MAXSKINS + 7] = {NULL}; +static UINT8 **translationtablecache[MAXSKINS + 7] = {NULL}; UINT8 skincolor_modified[MAXSKINCOLORS]; static INT32 SkinToCacheIndex(INT32 skinnum) @@ -577,9 +577,9 @@ void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, INT32 st \return Colormap. If not cached, caller should Z_Free. */ -colormap_t* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags) +UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags) { - colormap_t* ret; + UINT8* ret; INT32 skintableindex = SkinToCacheIndex(skinnum); // Adjust if we want the default colormap INT32 starttranscolor, i; @@ -587,7 +587,7 @@ colormap_t* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 { // Allocate table for skin if necessary if (!translationtablecache[skintableindex]) - translationtablecache[skintableindex] = Z_Calloc(MAXSKINCOLORS * sizeof(colormap_t**), PU_STATIC, NULL); + translationtablecache[skintableindex] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL); // Get colormap ret = translationtablecache[skintableindex][color]; @@ -600,7 +600,7 @@ colormap_t* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 { INT32 skin = CacheIndexToSkin(i); starttranscolor = (skin >= 0) ? skins[skin].starttranscolor : DEFAULT_STARTTRANSCOLOR; - R_GenerateTranslationColormap(translationtablecache[i][color]->map, skin, starttranscolor, color); + R_GenerateTranslationColormap(translationtablecache[i][color], skin, starttranscolor, color); } skincolor_modified[color] = false; @@ -611,12 +611,10 @@ colormap_t* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 // Generate the colormap if necessary if (!ret) { - ret = Z_MallocAlign(sizeof(colormap_t) + NUM_PALETTE_ENTRIES, (flags & GTC_CACHE) ? PU_LEVEL : PU_STATIC, NULL, 8); - ret->rows = 1; - ret->flags = flags; + ret = Z_MallocAlign(NUM_PALETTE_ENTRIES, (flags & GTC_CACHE) ? PU_LEVEL : PU_STATIC, NULL, 8); starttranscolor = (skinnum >= 0) ? skins[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR; - R_GenerateTranslationColormap(ret->map, skinnum, starttranscolor, color); + R_GenerateTranslationColormap(ret, skinnum, starttranscolor, color); // Cache the colormap if desired if (flags & GTC_CACHE) @@ -628,7 +626,7 @@ colormap_t* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 UINT8* R_GetCachedTranslation(INT32 skinnum, skincolornum_t color) { - return R_GetTranslationColormap(skinnum, color, GTC_CACHE)->map; + return R_GetTranslationColormap(skinnum, color, GTC_CACHE); } /** \brief Flushes cache of translation colormaps. @@ -645,7 +643,7 @@ void R_FlushTranslationColormapCache(void) for (i = 0; i < (INT32)(sizeof(translationtablecache) / sizeof(translationtablecache[0])); i++) if (translationtablecache[i]) - memset(translationtablecache[i], 0, MAXSKINCOLORS * sizeof(colormap_t**)); + memset(translationtablecache[i], 0, MAXSKINCOLORS * sizeof(UINT8**)); } UINT16 R_GetColorByName(const char *name) diff --git a/src/r_draw.h b/src/r_draw.h index 62dda0719113dad9308af7d3c22464269e97f0f5..057d2afb5045ac605aac83b364503cacc15573f3 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -120,7 +120,7 @@ enum // Custom player skin translation // Initialize color translation tables, for player rendering etc. -colormap_t* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags); +UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags); UINT8* R_GetCachedTranslation(INT32 skinnum, skincolornum_t color); void R_FlushTranslationColormapCache(void); void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, INT32 starttranscolor, UINT16 color);