mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 14:51:46 +00:00
- Split off the entire translation code from r_draw.cpp into r_translate.cpp.
- Moved the common code of ACS and DECORATE translation generation into the FRemapTable class. - Fixed: The DECORATE translation code was not changed for the new data structures. - Expanded range of ACS and DECORATE translations to 65535. - Fixed: R_CopyTranslation was not altered for the new functionality. I removed the function and replaced the one use with a simple assignment. SVN r644 (trunk)
This commit is contained in:
parent
6804e66208
commit
0535d15df3
39 changed files with 862 additions and 779 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
December 26, 2007 (Changes by Graf Zahl)
|
||||||
|
- Split off the entire translation code from r_draw.cpp into r_translate.cpp.
|
||||||
|
- Moved the common code of ACS and DECORATE translation generation into the
|
||||||
|
FRemapTable class.
|
||||||
|
- Fixed: The DECORATE translation code was not changed for the new data structures.
|
||||||
|
- Expanded range of ACS and DECORATE translations to 65535.
|
||||||
|
- Fixed: R_CopyTranslation was not altered for the new functionality.
|
||||||
|
I removed the function and replaced the one use with a simple assignment.
|
||||||
|
|
||||||
December 25, 2007
|
December 25, 2007
|
||||||
- Fixed: The fullscreen console crashed when opened before starting a game.
|
- Fixed: The fullscreen console crashed when opened before starting a game.
|
||||||
- Discovered that Shader Model 1.4 clamps my constants, so I can't use
|
- Discovered that Shader Model 1.4 clamps my constants, so I can't use
|
||||||
|
|
|
@ -714,7 +714,7 @@ public:
|
||||||
|
|
||||||
BYTE FloatBobPhase;
|
BYTE FloatBobPhase;
|
||||||
BYTE FriendPlayer; // [RH] Player # + 1 this friendly monster works for (so 0 is no player, 1 is player 0, etc)
|
BYTE FriendPlayer; // [RH] Player # + 1 this friendly monster works for (so 0 is no player, 1 is player 0, etc)
|
||||||
WORD Translation;
|
DWORD Translation;
|
||||||
|
|
||||||
// [RH] Stuff that used to be part of an Actor Info
|
// [RH] Stuff that used to be part of an Actor Info
|
||||||
WORD SeeSound;
|
WORD SeeSound;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
#include "a_sharedglobal.h"
|
#include "a_sharedglobal.h"
|
||||||
#include "statnums.h"
|
#include "statnums.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
#include "m_cheat.h"
|
#include "m_cheat.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
#include "thingdef/thingdef.h"
|
#include "thingdef/thingdef.h"
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "dobject.h"
|
#include "dobject.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
// [SO] Just the way Randy said to do it :)
|
// [SO] Just the way Randy said to do it :)
|
||||||
// [RH] Made this CVAR_SERVERINFO
|
// [RH] Made this CVAR_SERVERINFO
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "teaminfo.h"
|
#include "teaminfo.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
static FRandom pr_pickteam ("PickRandomTeam");
|
static FRandom pr_pickteam ("PickRandomTeam");
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "r_draw.h"
|
#include "r_draw.h"
|
||||||
#include "a_sharedglobal.h"
|
#include "a_sharedglobal.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
FDecalLib DecalLibrary;
|
FDecalLib DecalLibrary;
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ public:
|
||||||
|
|
||||||
fixed_t ScaleX, ScaleY;
|
fixed_t ScaleX, ScaleY;
|
||||||
DWORD ShadeColor;
|
DWORD ShadeColor;
|
||||||
WORD Translation;
|
DWORD Translation;
|
||||||
BYTE RenderStyle;
|
BYTE RenderStyle;
|
||||||
WORD PicNum;
|
WORD PicNum;
|
||||||
WORD RenderFlags;
|
WORD RenderFlags;
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "a_strifeglobal.h"
|
#include "a_strifeglobal.h"
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "c_bind.h"
|
#include "c_bind.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
static void FadePic ();
|
static void FadePic ();
|
||||||
static void GetFinaleText (const char *msgLumpName);
|
static void GetFinaleText (const char *msgLumpName);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "a_doomglobal.h"
|
#include "a_doomglobal.h"
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
#define MARINE_PAIN_CHANCE 160
|
#define MARINE_PAIN_CHANCE 160
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "a_keys.h"
|
#include "a_keys.h"
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
|
|
||||||
#define ST_EVILGRINCOUNT (2*TICRATE)
|
#define ST_EVILGRINCOUNT (2*TICRATE)
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
#include "a_keys.h"
|
#include "a_keys.h"
|
||||||
#include "a_artifacts.h"
|
#include "a_artifacts.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
|
@ -1399,7 +1400,7 @@ static void G_QueueBody (AActor *body)
|
||||||
if (GetTranslationType(body->Translation) == TRANSLATION_Players ||
|
if (GetTranslationType(body->Translation) == TRANSLATION_Players ||
|
||||||
GetTranslationType(body->Translation) == TRANSLATION_PlayersExtra)
|
GetTranslationType(body->Translation) == TRANSLATION_PlayersExtra)
|
||||||
{
|
{
|
||||||
R_CopyTranslation (TRANSLATION(TRANSLATION_PlayerCorpses,modslot), body->Translation);
|
translationtables[TRANSLATION_PlayerCorpses][modslot] = TranslationToTable(body->Translation);
|
||||||
body->Translation = TRANSLATION(TRANSLATION_PlayerCorpses,modslot);
|
body->Translation = TRANSLATION(TRANSLATION_PlayerCorpses,modslot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
#include "p_enemy.h"
|
#include "p_enemy.h"
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
static FRandom pr_sap ("StaffAtkPL1");
|
static FRandom pr_sap ("StaffAtkPL1");
|
||||||
static FRandom pr_sap2 ("StaffAtkPL2");
|
static FRandom pr_sap2 ("StaffAtkPL2");
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "r_draw.h"
|
#include "r_draw.h"
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "a_keys.h"
|
#include "a_keys.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
|
|
||||||
static FRandom pr_chainwiggle;
|
static FRandom pr_chainwiggle;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "a_hexenglobal.h"
|
#include "a_hexenglobal.h"
|
||||||
#include "a_keys.h"
|
#include "a_keys.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
|
|
||||||
class FManaBar : public FTexture
|
class FManaBar : public FTexture
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
#include "statnums.h"
|
#include "statnums.h"
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "sbarinfo.h"
|
#include "sbarinfo.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
|
|
||||||
|
@ -2688,58 +2689,37 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
|
||||||
|
|
||||||
// Does this level have custom translations?
|
// Does this level have custom translations?
|
||||||
FRemapTable *trans;
|
FRemapTable *trans;
|
||||||
|
WORD w;
|
||||||
if (arc.IsStoring ())
|
if (arc.IsStoring ())
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < translationtables[TRANSLATION_LevelScripted].Size(); ++i)
|
for (unsigned int i = 0; i < translationtables[TRANSLATION_LevelScripted].Size(); ++i)
|
||||||
{
|
{
|
||||||
trans = translationtables[TRANSLATION_LevelScripted][i];
|
trans = translationtables[TRANSLATION_LevelScripted][i];
|
||||||
int j;
|
if (trans != NULL && !trans->IsIdentity())
|
||||||
for (j = 0; j < 256; ++j)
|
|
||||||
{
|
{
|
||||||
if (trans->Remap[j] != j)
|
w = WORD(i);
|
||||||
{
|
arc << w;
|
||||||
break;
|
trans->Serialize(arc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j < 256)
|
w = 0xffff;
|
||||||
{
|
arc << w;
|
||||||
t = i;
|
|
||||||
arc << t;
|
|
||||||
arc.Write (trans->Remap, 256);
|
|
||||||
for (j = 0; j < 256; ++j)
|
|
||||||
{
|
|
||||||
arc << trans->Palette[j].r
|
|
||||||
<< trans->Palette[j].g
|
|
||||||
<< trans->Palette[j].b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t = 255;
|
|
||||||
arc << t;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arc << t;
|
while (arc << w, w != 0xffff)
|
||||||
while (t != 255)
|
|
||||||
{
|
{
|
||||||
if (t >= MAX_ACS_TRANSLATIONS)
|
if (w >= MAX_ACS_TRANSLATIONS)
|
||||||
{ // hack hack to avoid crashing
|
{ // hack hack to avoid crashing
|
||||||
t = 0;
|
w = 0;
|
||||||
}
|
}
|
||||||
trans = translationtables[TRANSLATION_LevelScripted].GetVal(t);
|
trans = translationtables[TRANSLATION_LevelScripted].GetVal(w);
|
||||||
if (trans == NULL)
|
if (trans == NULL)
|
||||||
{
|
{
|
||||||
trans = new FRemapTable;
|
trans = new FRemapTable;
|
||||||
translationtables[TRANSLATION_LevelScripted].SetVal(t, trans);
|
translationtables[TRANSLATION_LevelScripted].SetVal(t, trans);
|
||||||
}
|
}
|
||||||
arc.Read (trans->Remap, 256);
|
trans->Serialize(arc);
|
||||||
for (int j = 0; j < 256; ++j)
|
|
||||||
{
|
|
||||||
arc << trans->Palette[j].r
|
|
||||||
<< trans->Palette[j].g
|
|
||||||
<< trans->Palette[j].b;
|
|
||||||
}
|
|
||||||
arc << t;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "sbarinfo.h"
|
#include "sbarinfo.h"
|
||||||
#include "sc_man.h"
|
#include "sc_man.h"
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
static FRandom pr_chainwiggle; //use the same method of chain wiggling as heretic.
|
static FRandom pr_chainwiggle; //use the same method of chain wiggling as heretic.
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "a_strifeglobal.h"
|
#include "a_strifeglobal.h"
|
||||||
#include "doomdata.h"
|
#include "doomdata.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
void A_BeShadowyFoe (AActor *);
|
void A_BeShadowyFoe (AActor *);
|
||||||
void A_AcolyteBits (AActor *);
|
void A_AcolyteBits (AActor *);
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "p_lnspec.h"
|
#include "p_lnspec.h"
|
||||||
#include "c_console.h"
|
#include "c_console.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
// [RH] Actually handle the cheat. The cheat code in st_stuff.c now just
|
// [RH] Actually handle the cheat. The cheat code in st_stuff.c now just
|
||||||
// writes some bytes to the network data stream, and the network code
|
// writes some bytes to the network data stream, and the network code
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
#include "p_tick.h"
|
#include "p_tick.h"
|
||||||
#include "st_start.h"
|
#include "st_start.h"
|
||||||
#include "teaminfo.h"
|
#include "teaminfo.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
#include "sc_man.h"
|
#include "sc_man.h"
|
||||||
#include "c_bind.h"
|
#include "c_bind.h"
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
extern FILE *Logfile;
|
extern FILE *Logfile;
|
||||||
|
|
||||||
|
@ -4691,31 +4692,10 @@ int DLevelScript::RunScript ()
|
||||||
int end = STACK(3);
|
int end = STACK(3);
|
||||||
int pal1 = STACK(2);
|
int pal1 = STACK(2);
|
||||||
int pal2 = STACK(1);
|
int pal2 = STACK(1);
|
||||||
fixed_t palcol, palstep;
|
|
||||||
sp -= 4;
|
sp -= 4;
|
||||||
|
|
||||||
if (translation == NULL)
|
if (translation != NULL)
|
||||||
{
|
translation->AddIndexRange(start, end, pal1, pal2);
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (start > end)
|
|
||||||
{
|
|
||||||
swap (start, end);
|
|
||||||
swap (pal1, pal2);
|
|
||||||
}
|
|
||||||
else if (start == end)
|
|
||||||
{
|
|
||||||
translation->Remap[start] = pal1;
|
|
||||||
translation->Palette[start] = GPalette.BaseColors[pal1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
palcol = pal1 << FRACBITS;
|
|
||||||
palstep = ((pal2 << FRACBITS) - palcol) / (end - start);
|
|
||||||
for (int i = start; i <= end; palcol += palstep, ++i)
|
|
||||||
{
|
|
||||||
translation->Remap[i] = palcol >> FRACBITS;
|
|
||||||
translation->Palette[i] = GPalette.BaseColors[palcol >> FRACBITS];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -4724,58 +4704,16 @@ int DLevelScript::RunScript ()
|
||||||
// (would HSV be a good idea too?)
|
// (would HSV be a good idea too?)
|
||||||
int start = STACK(8);
|
int start = STACK(8);
|
||||||
int end = STACK(7);
|
int end = STACK(7);
|
||||||
fixed_t r1 = STACK(6) << FRACBITS;
|
int r1 = STACK(6);
|
||||||
fixed_t g1 = STACK(5) << FRACBITS;
|
int g1 = STACK(5);
|
||||||
fixed_t b1 = STACK(4) << FRACBITS;
|
int b1 = STACK(4);
|
||||||
fixed_t r2 = STACK(3) << FRACBITS;
|
int r2 = STACK(3);
|
||||||
fixed_t g2 = STACK(2) << FRACBITS;
|
int g2 = STACK(2);
|
||||||
fixed_t b2 = STACK(1) << FRACBITS;
|
int b2 = STACK(1);
|
||||||
fixed_t r, g, b;
|
|
||||||
fixed_t rs, gs, bs;
|
|
||||||
sp -= 8;
|
sp -= 8;
|
||||||
|
|
||||||
if (translation == NULL)
|
if (translation != NULL)
|
||||||
{
|
translation->AddColorRange(start, end, r1, g1, b1, r2, g2, b2);
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (start > end)
|
|
||||||
{
|
|
||||||
swap (start, end);
|
|
||||||
r = r2;
|
|
||||||
g = g2;
|
|
||||||
b = b2;
|
|
||||||
rs = r1 - r2;
|
|
||||||
gs = g1 - g2;
|
|
||||||
bs = b1 - b2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
r = r1;
|
|
||||||
g = g1;
|
|
||||||
b = b1;
|
|
||||||
rs = r2 - r1;
|
|
||||||
gs = g2 - g1;
|
|
||||||
bs = b2 - b1;
|
|
||||||
}
|
|
||||||
if (start == end)
|
|
||||||
{
|
|
||||||
translation->Remap[start] = ColorMatcher.Pick
|
|
||||||
(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
|
||||||
translation->Palette[start] = PalEntry(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
rs /= (end - start);
|
|
||||||
gs /= (end - start);
|
|
||||||
bs /= (end - start);
|
|
||||||
for (int i = start; i <= end; ++i)
|
|
||||||
{
|
|
||||||
translation->Remap[i] = ColorMatcher.Pick
|
|
||||||
(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
|
||||||
translation->Palette[i] = PalEntry(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
|
||||||
r += rs;
|
|
||||||
g += gs;
|
|
||||||
b += bs;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "p_conversation.h"
|
#include "p_conversation.h"
|
||||||
#include "a_strifeglobal.h"
|
#include "a_strifeglobal.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
#define FUNC(a) static int a (line_t *ln, AActor *it, bool backSide, \
|
#define FUNC(a) static int a (line_t *ln, AActor *it, bool backSide, \
|
||||||
int arg0, int arg1, int arg2, int arg3, int arg4)
|
int arg0, int arg1, int arg2, int arg3, int arg4)
|
||||||
|
@ -1505,7 +1506,7 @@ FUNC(LS_Thing_SetTranslation)
|
||||||
}
|
}
|
||||||
else if (arg1 >= 1 && arg1 < MAX_ACS_TRANSLATIONS)
|
else if (arg1 >= 1 && arg1 < MAX_ACS_TRANSLATIONS)
|
||||||
{
|
{
|
||||||
range = (TRANSLATION_LevelScripted<<8)|(arg1-1);
|
range = TRANSLATION(TRANSLATION_LevelScripted, (arg1-1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
#include "a_sharedglobal.h"
|
#include "a_sharedglobal.h"
|
||||||
#include "a_doomglobal.h"
|
#include "a_doomglobal.h"
|
||||||
#include "p_conversation.h"
|
#include "p_conversation.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
#define WATER_SINK_FACTOR 3
|
#define WATER_SINK_FACTOR 3
|
||||||
#define WATER_SINK_SMALL_FACTOR 4
|
#define WATER_SINK_SMALL_FACTOR 4
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#include "thingdef/thingdef.h"
|
#include "thingdef/thingdef.h"
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
#include "teaminfo.h"
|
#include "teaminfo.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#include "s_sndseq.h"
|
#include "s_sndseq.h"
|
||||||
#include "sbar.h"
|
#include "sbar.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
extern void P_SpawnMapThing (mapthing2_t *mthing, int position);
|
extern void P_SpawnMapThing (mapthing2_t *mthing, int position);
|
||||||
extern bool P_LoadBuildMap (BYTE *mapdata, size_t len, mapthing2_t **things, int *numthings);
|
extern bool P_LoadBuildMap (BYTE *mapdata, size_t len, mapthing2_t **things, int *numthings);
|
||||||
|
|
|
@ -862,7 +862,7 @@ struct vissprite_t
|
||||||
fixed_t floorclip;
|
fixed_t floorclip;
|
||||||
FTexture *pic;
|
FTexture *pic;
|
||||||
short renderflags;
|
short renderflags;
|
||||||
WORD Translation; // [RH] for color translation
|
DWORD Translation; // [RH] for color translation
|
||||||
BYTE RenderStyle;
|
BYTE RenderStyle;
|
||||||
BYTE FakeFlatStat; // [RH] which side of fake/floor ceiling sprite is on
|
BYTE FakeFlatStat; // [RH] which side of fake/floor ceiling sprite is on
|
||||||
BYTE bSplitSprite; // [RH] Sprite was split by a drawseg
|
BYTE bSplitSprite; // [RH] Sprite was split by a drawseg
|
||||||
|
|
498
src/r_draw.cpp
498
src/r_draw.cpp
|
@ -37,6 +37,7 @@
|
||||||
#include "a_hexenglobal.h"
|
#include "a_hexenglobal.h"
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
|
@ -132,7 +133,6 @@ cycle_t DetailDoubleCycles;
|
||||||
|
|
||||||
int dc_fillcolor;
|
int dc_fillcolor;
|
||||||
BYTE *dc_translation;
|
BYTE *dc_translation;
|
||||||
TAutoGrowArray<FRemapTable *> translationtables[NUM_TRANSLATION_TABLES];
|
|
||||||
BYTE shadetables[NUMCOLORMAPS*16*256];
|
BYTE shadetables[NUMCOLORMAPS*16*256];
|
||||||
|
|
||||||
/************************************/
|
/************************************/
|
||||||
|
@ -1406,502 +1406,7 @@ void tmvline4_addclamp ()
|
||||||
} while (--count);
|
} while (--count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************/
|
|
||||||
/****************************************************/
|
|
||||||
|
|
||||||
FRemapTable::FRemapTable(int count)
|
|
||||||
{
|
|
||||||
assert(count <= 256);
|
|
||||||
|
|
||||||
Alloc(count);
|
|
||||||
|
|
||||||
// Note that the tables are left uninitialized. It is assumed that
|
|
||||||
// the caller will do that next, if only by calling MakeIdentity().
|
|
||||||
}
|
|
||||||
|
|
||||||
FRemapTable::~FRemapTable()
|
|
||||||
{
|
|
||||||
Free();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FRemapTable::Alloc(int count)
|
|
||||||
{
|
|
||||||
Remap = (BYTE *)M_Malloc(count*sizeof(*Remap) + count*sizeof(*Palette));
|
|
||||||
assert (Remap != NULL);
|
|
||||||
Palette = (PalEntry *)(Remap + count*(sizeof(*Remap)));
|
|
||||||
Native = NULL;
|
|
||||||
NumEntries = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FRemapTable::Free()
|
|
||||||
{
|
|
||||||
KillNative();
|
|
||||||
if (Remap != NULL)
|
|
||||||
{
|
|
||||||
free(Remap);
|
|
||||||
Remap = NULL;
|
|
||||||
Palette = NULL;
|
|
||||||
NumEntries = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FRemapTable::FRemapTable(const FRemapTable &o)
|
|
||||||
{
|
|
||||||
Remap = NULL;
|
|
||||||
Native = NULL;
|
|
||||||
NumEntries = 0;
|
|
||||||
operator= (o);
|
|
||||||
}
|
|
||||||
|
|
||||||
FRemapTable &FRemapTable::operator=(const FRemapTable &o)
|
|
||||||
{
|
|
||||||
if (&o == this)
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
if (o.NumEntries != NumEntries)
|
|
||||||
{
|
|
||||||
Free();
|
|
||||||
}
|
|
||||||
if (Remap == NULL)
|
|
||||||
{
|
|
||||||
Alloc(o.NumEntries);
|
|
||||||
}
|
|
||||||
memcpy(Remap, o.Remap, NumEntries*sizeof(*Remap) + NumEntries*sizeof(*Palette));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FRemapTable::MakeIdentity()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < NumEntries; ++i)
|
|
||||||
{
|
|
||||||
Remap[i] = i;
|
|
||||||
}
|
|
||||||
for (i = 0; i < NumEntries; ++i)
|
|
||||||
{
|
|
||||||
Palette[i] = GPalette.BaseColors[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FRemapTable::KillNative()
|
|
||||||
{
|
|
||||||
if (Native != NULL)
|
|
||||||
{
|
|
||||||
delete Native;
|
|
||||||
Native = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FRemapTable::UpdateNative()
|
|
||||||
{
|
|
||||||
if (Native != NULL)
|
|
||||||
{
|
|
||||||
Native->Update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FNativeTexture *FRemapTable::GetNative()
|
|
||||||
{
|
|
||||||
if (Native == NULL)
|
|
||||||
{
|
|
||||||
Native = screen->CreatePalette(this);
|
|
||||||
}
|
|
||||||
return Native;
|
|
||||||
}
|
|
||||||
|
|
||||||
FRemapTable *TranslationToTable(int translation)
|
|
||||||
{
|
|
||||||
unsigned int type = (translation & 0xFF00) >> 8;
|
|
||||||
unsigned int index = (translation & 0x00FF);
|
|
||||||
TAutoGrowArray<FRemapTable *> *slots;
|
|
||||||
|
|
||||||
if (type <= 0 || type >= NUM_TRANSLATION_TABLES)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
slots = &translationtables[type];
|
|
||||||
if (index >= slots->Size())
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return slots->operator[](index);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void PushIdentityTable(int slot)
|
|
||||||
{
|
|
||||||
FRemapTable *table = new FRemapTable;
|
|
||||||
table->MakeIdentity();
|
|
||||||
translationtables[slot].Push(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// R_InitTranslationTables
|
|
||||||
// Creates the translation tables to map the green color ramp to gray,
|
|
||||||
// brown, red. Assumes a given structure of the PLAYPAL.
|
|
||||||
//
|
|
||||||
void R_InitTranslationTables ()
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
// Each player gets two translations. Doom and Strife don't use the
|
|
||||||
// extra ones, but Heretic and Hexen do. These are set up during
|
|
||||||
// netgame arbitration and as-needed, so they just get to be identity
|
|
||||||
// maps until then so they won't be invalid.
|
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
|
||||||
{
|
|
||||||
PushIdentityTable(TRANSLATION_Players);
|
|
||||||
PushIdentityTable(TRANSLATION_PlayersExtra);
|
|
||||||
}
|
|
||||||
// The menu player also gets a separate translation table
|
|
||||||
PushIdentityTable(TRANSLATION_Players);
|
|
||||||
|
|
||||||
// The three standard translations from Doom or Heretic (seven for Strife),
|
|
||||||
// plus the generic ice translation.
|
|
||||||
for (i = 0; i < 8; ++i)
|
|
||||||
{
|
|
||||||
PushIdentityTable(TRANSLATION_Standard);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Each player corpse has its own translation so they won't change
|
|
||||||
// color if the player who created them changes theirs.
|
|
||||||
for (i = 0; i < BODYQUESIZE; ++i)
|
|
||||||
{
|
|
||||||
PushIdentityTable(TRANSLATION_PlayerCorpses);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the standard translation tables
|
|
||||||
if (gameinfo.gametype == GAME_Doom)
|
|
||||||
{
|
|
||||||
for (i = 0x70; i < 0x80; i++)
|
|
||||||
{ // map green ramp to gray, brown, red
|
|
||||||
translationtables[TRANSLATION_Standard][0]->Remap[i] = 0x60 + (i&0xf);
|
|
||||||
translationtables[TRANSLATION_Standard][1]->Remap[i] = 0x40 + (i&0xf);
|
|
||||||
translationtables[TRANSLATION_Standard][2]->Remap[i] = 0x20 + (i&0xf);
|
|
||||||
|
|
||||||
translationtables[TRANSLATION_Standard][0]->Palette[i] = GPalette.BaseColors[0x60 + (i&0xf)];
|
|
||||||
translationtables[TRANSLATION_Standard][1]->Palette[i] = GPalette.BaseColors[0x40 + (i&0xf)];
|
|
||||||
translationtables[TRANSLATION_Standard][2]->Palette[i] = GPalette.BaseColors[0x20 + (i&0xf)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (gameinfo.gametype == GAME_Heretic)
|
|
||||||
{
|
|
||||||
for (i = 225; i <= 240; i++)
|
|
||||||
{
|
|
||||||
translationtables[TRANSLATION_Standard][0]->Remap[i] = 114+(i-225); // yellow
|
|
||||||
translationtables[TRANSLATION_Standard][1]->Remap[i] = 145+(i-225); // red
|
|
||||||
translationtables[TRANSLATION_Standard][2]->Remap[i] = 190+(i-225); // blue
|
|
||||||
|
|
||||||
translationtables[TRANSLATION_Standard][0]->Palette[i] = GPalette.BaseColors[114+(i-225)];
|
|
||||||
translationtables[TRANSLATION_Standard][1]->Palette[i] = GPalette.BaseColors[145+(i-225)];
|
|
||||||
translationtables[TRANSLATION_Standard][2]->Palette[i] = GPalette.BaseColors[190+(i-225)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (gameinfo.gametype == GAME_Strife)
|
|
||||||
{
|
|
||||||
for (i = 0x20; i <= 0x3F; ++i)
|
|
||||||
{
|
|
||||||
translationtables[TRANSLATION_Standard][0]->Remap[i] = i - 0x20;
|
|
||||||
translationtables[TRANSLATION_Standard][1]->Remap[i] = i - 0x20;
|
|
||||||
translationtables[TRANSLATION_Standard][2]->Remap[i] = 0xD0 + (i&0xf);
|
|
||||||
translationtables[TRANSLATION_Standard][3]->Remap[i] = 0xD0 + (i&0xf);
|
|
||||||
translationtables[TRANSLATION_Standard][4]->Remap[i] = i - 0x20;
|
|
||||||
translationtables[TRANSLATION_Standard][5]->Remap[i] = i - 0x20;
|
|
||||||
translationtables[TRANSLATION_Standard][6]->Remap[i] = i - 0x20;
|
|
||||||
}
|
|
||||||
for (i = 0x50; i <= 0x5F; ++i)
|
|
||||||
{
|
|
||||||
// Merchant hair
|
|
||||||
translationtables[TRANSLATION_Standard][4]->Remap[i] = 0x80 + (i&0xf);
|
|
||||||
translationtables[TRANSLATION_Standard][5]->Remap[i] = 0x10 + (i&0xf);
|
|
||||||
translationtables[TRANSLATION_Standard][6]->Remap[i] = 0x40 + (i&0xf);
|
|
||||||
}
|
|
||||||
for (i = 0x80; i <= 0x8F; ++i)
|
|
||||||
{
|
|
||||||
translationtables[TRANSLATION_Standard][0]->Remap[i] = 0x40 + (i&0xf); // red
|
|
||||||
translationtables[TRANSLATION_Standard][1]->Remap[i] = 0xB0 + (i&0xf); // rust
|
|
||||||
translationtables[TRANSLATION_Standard][2]->Remap[i] = 0x10 + (i&0xf); // gray
|
|
||||||
translationtables[TRANSLATION_Standard][3]->Remap[i] = 0x30 + (i&0xf); // dark green
|
|
||||||
translationtables[TRANSLATION_Standard][4]->Remap[i] = 0x50 + (i&0xf); // gold
|
|
||||||
translationtables[TRANSLATION_Standard][5]->Remap[i] = 0x60 + (i&0xf); // bright green
|
|
||||||
translationtables[TRANSLATION_Standard][6]->Remap[i] = 0x90 + (i&0xf); // blue
|
|
||||||
}
|
|
||||||
for (i = 0xC0; i <= 0xCF; ++i)
|
|
||||||
{
|
|
||||||
translationtables[TRANSLATION_Standard][4]->Remap[i] = 0xA0 + (i&0xf);
|
|
||||||
translationtables[TRANSLATION_Standard][5]->Remap[i] = 0x20 + (i&0xf);
|
|
||||||
translationtables[TRANSLATION_Standard][6]->Remap[i] = (i&0xf);
|
|
||||||
}
|
|
||||||
translationtables[TRANSLATION_Standard][6]->Remap[0xC0] = 1;
|
|
||||||
for (i = 0xD0; i <= 0xDF; ++i)
|
|
||||||
{
|
|
||||||
translationtables[TRANSLATION_Standard][4]->Remap[i] = 0xB0 + (i&0xf);
|
|
||||||
translationtables[TRANSLATION_Standard][5]->Remap[i] = 0x30 + (i&0xf);
|
|
||||||
translationtables[TRANSLATION_Standard][6]->Remap[i] = 0x10 + (i&0xf);
|
|
||||||
}
|
|
||||||
for (i = 0xF1; i <= 0xF6; ++i)
|
|
||||||
{
|
|
||||||
translationtables[TRANSLATION_Standard][0]->Remap[i] = 0xDF + (i&0xf);
|
|
||||||
}
|
|
||||||
for (i = 0xF7; i <= 0xFB; ++i)
|
|
||||||
{
|
|
||||||
translationtables[TRANSLATION_Standard][0]->Remap[i] = i - 6;
|
|
||||||
}
|
|
||||||
for (i = 0; i < 7; ++i)
|
|
||||||
{
|
|
||||||
for (int j = 0x20; j <= 0xFB; ++j)
|
|
||||||
{
|
|
||||||
translationtables[TRANSLATION_Standard][i]->Palette[j] =
|
|
||||||
GPalette.BaseColors[translationtables[TRANSLATION_Standard][i]->Remap[j]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the ice translation table, based on Hexen's. Alas, the standard
|
|
||||||
// Doom palette has no good substitutes for these bluish-tinted grays, so
|
|
||||||
// they will just look gray unless you use a different PLAYPAL with Doom.
|
|
||||||
|
|
||||||
static const BYTE IcePalette[16][3] =
|
|
||||||
{
|
|
||||||
{ 10, 8, 18 },
|
|
||||||
{ 15, 15, 26 },
|
|
||||||
{ 20, 16, 36 },
|
|
||||||
{ 30, 26, 46 },
|
|
||||||
{ 40, 36, 57 },
|
|
||||||
{ 50, 46, 67 },
|
|
||||||
{ 59, 57, 78 },
|
|
||||||
{ 69, 67, 88 },
|
|
||||||
{ 79, 77, 99 },
|
|
||||||
{ 89, 87,109 },
|
|
||||||
{ 99, 97,120 },
|
|
||||||
{ 109,107,130 },
|
|
||||||
{ 118,118,141 },
|
|
||||||
{ 128,128,151 },
|
|
||||||
{ 138,138,162 },
|
|
||||||
{ 148,148,172 }
|
|
||||||
};
|
|
||||||
BYTE IcePaletteRemap[16];
|
|
||||||
for (i = 0; i < 16; ++i)
|
|
||||||
{
|
|
||||||
IcePaletteRemap[i] = ColorMatcher.Pick (IcePalette[i][0], IcePalette[i][1], IcePalette[i][2]);
|
|
||||||
}
|
|
||||||
FRemapTable *remap = translationtables[TRANSLATION_Standard][7];
|
|
||||||
for (i = 0; i < 256; ++i)
|
|
||||||
{
|
|
||||||
int r = GPalette.BaseColors[i].r;
|
|
||||||
int g = GPalette.BaseColors[i].g;
|
|
||||||
int b = GPalette.BaseColors[i].b;
|
|
||||||
int v = (r*77 + g*143 + b*37) >> 12;
|
|
||||||
remap->Remap[i] = IcePaletteRemap[v];
|
|
||||||
remap->Palette[i] = PalEntry(IcePalette[v][0], IcePalette[v][1], IcePalette[v][2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set up shading tables for shaded columns
|
|
||||||
// 16 colormap sets, progressing from full alpha to minimum visible alpha
|
|
||||||
|
|
||||||
BYTE *table = shadetables;
|
|
||||||
|
|
||||||
// Full alpha
|
|
||||||
for (i = 0; i < 16; ++i)
|
|
||||||
{
|
|
||||||
for (j = 0; j < NUMCOLORMAPS; ++j)
|
|
||||||
{
|
|
||||||
int a = (NUMCOLORMAPS - j) * 256 / NUMCOLORMAPS * (16-i);
|
|
||||||
for (int k = 0; k < 256; ++k)
|
|
||||||
{
|
|
||||||
BYTE v = (((k+2) * a) + 256) >> 14;
|
|
||||||
table[k] = MIN<BYTE> (v, 64);
|
|
||||||
}
|
|
||||||
table += 256;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_DeinitTranslationTables()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < NUM_TRANSLATION_TABLES; ++i)
|
|
||||||
{
|
|
||||||
for (unsigned int j = 0; j < translationtables[i].Size(); ++j)
|
|
||||||
{
|
|
||||||
if (translationtables[i][j] != NULL)
|
|
||||||
{
|
|
||||||
delete translationtables[i][j];
|
|
||||||
translationtables[i][j] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// [RH] Create a player's translation table based on a given mid-range color.
|
|
||||||
// [GRB] Split to 2 functions (because of player setup menu)
|
|
||||||
static void SetRemap(FRemapTable *table, int i, float r, float g, float b)
|
|
||||||
{
|
|
||||||
int ir = clamp (int(r * 255.f), 0, 255);
|
|
||||||
int ig = clamp (int(g * 255.f), 0, 255);
|
|
||||||
int ib = clamp (int(b * 255.f), 0, 255);
|
|
||||||
table->Remap[i] = ColorMatcher.Pick (ir, ig, ib);
|
|
||||||
table->Palette[i] = PalEntry(ir, ig, ib);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *skin, FRemapTable *table, FRemapTable *alttable)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
BYTE start = skin->range0start;
|
|
||||||
BYTE end = skin->range0end;
|
|
||||||
float r, g, b;
|
|
||||||
float bases, basev;
|
|
||||||
float sdelta, vdelta;
|
|
||||||
float range;
|
|
||||||
|
|
||||||
// Set up the base translation for this skin. If the skin was created
|
|
||||||
// for the current game, then this is just an identity translation.
|
|
||||||
// Otherwise, it remaps the colors from the skin's original palette to
|
|
||||||
// the current one.
|
|
||||||
if (skin->othergame)
|
|
||||||
{
|
|
||||||
memcpy (table->Remap, OtherGameSkinRemap, 256);
|
|
||||||
memcpy (table->Palette, OtherGameSkinPalette, sizeof(table->Palette));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i < 256; ++i)
|
|
||||||
{
|
|
||||||
table->Remap[i] = i;
|
|
||||||
}
|
|
||||||
memcpy(table->Palette, GPalette.BaseColors, sizeof(table->Palette));
|
|
||||||
}
|
|
||||||
|
|
||||||
// [GRB] Don't translate skins with color range 0-0 (APlayerPawn default)
|
|
||||||
if (start == 0 && end == 0)
|
|
||||||
{
|
|
||||||
table->UpdateNative();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
range = (float)(end-start+1);
|
|
||||||
|
|
||||||
bases = s;
|
|
||||||
basev = v;
|
|
||||||
|
|
||||||
if (gameinfo.gametype == GAME_Doom || gameinfo.gametype == GAME_Strife)
|
|
||||||
{
|
|
||||||
// Build player sprite translation
|
|
||||||
s -= 0.23f;
|
|
||||||
v += 0.1f;
|
|
||||||
sdelta = 0.23f / range;
|
|
||||||
vdelta = -0.94112f / range;
|
|
||||||
|
|
||||||
for (i = start; i <= end; i++)
|
|
||||||
{
|
|
||||||
float uses, usev;
|
|
||||||
uses = clamp (s, 0.f, 1.f);
|
|
||||||
usev = clamp (v, 0.f, 1.f);
|
|
||||||
HSVtoRGB (&r, &g, &b, h, uses, usev);
|
|
||||||
SetRemap(table, i, r, g, b);
|
|
||||||
s += sdelta;
|
|
||||||
v += vdelta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (gameinfo.gametype == GAME_Heretic)
|
|
||||||
{
|
|
||||||
float vdelta = 0.418916f / range;
|
|
||||||
|
|
||||||
// Build player sprite translation
|
|
||||||
for (i = start; i <= end; i++)
|
|
||||||
{
|
|
||||||
v = vdelta * (float)(i - start) + basev - 0.2352937f;
|
|
||||||
v = clamp (v, 0.f, 1.f);
|
|
||||||
HSVtoRGB (&r, &g, &b, h, s, v);
|
|
||||||
SetRemap(table, i, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build rain/lifegem translation
|
|
||||||
if (alttable)
|
|
||||||
{
|
|
||||||
bases = MIN (bases*1.3f, 1.f);
|
|
||||||
basev = MIN (basev*1.3f, 1.f);
|
|
||||||
for (i = 145; i <= 168; i++)
|
|
||||||
{
|
|
||||||
s = MIN (bases, 0.8965f - 0.0962f*(float)(i - 161));
|
|
||||||
v = MIN (1.f, (0.2102f + 0.0489f*(float)(i - 144)) * basev);
|
|
||||||
HSVtoRGB (&r, &g, &b, h, s, v);
|
|
||||||
SetRemap(alttable, i, r, g, b);
|
|
||||||
}
|
|
||||||
alttable->UpdateNative();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (gameinfo.gametype == GAME_Hexen)
|
|
||||||
{
|
|
||||||
if (memcmp (sprites[skin->sprite].name, "PLAY", 4) == 0)
|
|
||||||
{ // The fighter is different! He gets a brown hairy loincloth, but the other
|
|
||||||
// two have blue capes.
|
|
||||||
float vs[9] = { .28f, .32f, .38f, .42f, .47f, .5f, .58f, .71f, .83f };
|
|
||||||
|
|
||||||
// Build player sprite translation
|
|
||||||
//h = 45.f;
|
|
||||||
v = MAX (0.1f, v);
|
|
||||||
|
|
||||||
for (i = start; i <= end; i++)
|
|
||||||
{
|
|
||||||
HSVtoRGB (&r, &g, &b, h, s, vs[(i-start)*9/(int)range]*basev);
|
|
||||||
SetRemap(table, i, r, g, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float ms[18] = { .95f, .96f, .89f, .97f, .97f, 1.f, 1.f, 1.f, .97f, .99f, .87f, .77f, .69f, .62f, .57f, .47f, .43f };
|
|
||||||
float mv[18] = { .16f, .19f, .22f, .25f, .31f, .35f, .38f, .41f, .47f, .54f, .60f, .65f, .71f, .77f, .83f, .89f, .94f, 1.f };
|
|
||||||
|
|
||||||
// Build player sprite translation
|
|
||||||
v = MAX (0.1f, v);
|
|
||||||
|
|
||||||
for (i = start; i <= end; i++)
|
|
||||||
{
|
|
||||||
HSVtoRGB (&r, &g, &b, h, ms[(i-start)*18/(int)range]*bases, mv[(i-start)*18/(int)range]*basev);
|
|
||||||
SetRemap(table, i, r, g, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build lifegem translation
|
|
||||||
if (alttable)
|
|
||||||
{
|
|
||||||
for (i = 164; i <= 185; ++i)
|
|
||||||
{
|
|
||||||
const PalEntry *base = &GPalette.BaseColors[i];
|
|
||||||
float dummy;
|
|
||||||
|
|
||||||
RGBtoHSV (base->r/255.f, base->g/255.f, base->b/255.f, &dummy, &s, &v);
|
|
||||||
HSVtoRGB (&r, &g, &b, h, s*bases, v*basev);
|
|
||||||
SetRemap(alttable, i, r, g, b);
|
|
||||||
}
|
|
||||||
alttable->UpdateNative();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
table->UpdateNative();
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_BuildPlayerTranslation (int player)
|
|
||||||
{
|
|
||||||
float h, s, v;
|
|
||||||
|
|
||||||
D_GetPlayerColor (player, &h, &s, &v);
|
|
||||||
|
|
||||||
R_CreatePlayerTranslation (h, s, v,
|
|
||||||
&skins[players[player].userinfo.skin],
|
|
||||||
translationtables[TRANSLATION_Players][player],
|
|
||||||
translationtables[TRANSLATION_PlayersExtra][player]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_GetPlayerTranslation (int color, FPlayerSkin *skin, FRemapTable *table)
|
|
||||||
{
|
|
||||||
float h, s, v;
|
|
||||||
|
|
||||||
RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f,
|
|
||||||
&h, &s, &v);
|
|
||||||
|
|
||||||
R_CreatePlayerTranslation (h, s, v, skin, table, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_DrawBorder (int x1, int y1, int x2, int y2)
|
void R_DrawBorder (int x1, int y1, int x2, int y2)
|
||||||
{
|
{
|
||||||
|
@ -1926,7 +1431,6 @@ void R_DrawBorder (int x1, int y1, int x2, int y2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
=
|
=
|
||||||
|
|
69
src/r_draw.h
69
src/r_draw.h
|
@ -201,82 +201,13 @@ extern "C" const BYTE* ds_source;
|
||||||
|
|
||||||
extern "C" int ds_color; // [RH] For flat color (no texturing)
|
extern "C" int ds_color; // [RH] For flat color (no texturing)
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
TRANSLATION_Invalid,
|
|
||||||
TRANSLATION_Players,
|
|
||||||
TRANSLATION_PlayersExtra,
|
|
||||||
TRANSLATION_Standard,
|
|
||||||
TRANSLATION_LevelScripted,
|
|
||||||
TRANSLATION_Decals,
|
|
||||||
TRANSLATION_PlayerCorpses,
|
|
||||||
TRANSLATION_Decorate,
|
|
||||||
TRANSLATION_Blood,
|
|
||||||
TRANSLATION_Dim,
|
|
||||||
|
|
||||||
NUM_TRANSLATION_TABLES
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FRemapTable
|
|
||||||
{
|
|
||||||
FRemapTable(int count=256);
|
|
||||||
FRemapTable(const FRemapTable &o);
|
|
||||||
~FRemapTable();
|
|
||||||
|
|
||||||
FRemapTable &operator= (const FRemapTable &o);
|
|
||||||
void MakeIdentity();
|
|
||||||
void KillNative();
|
|
||||||
void UpdateNative();
|
|
||||||
FNativeTexture *GetNative();
|
|
||||||
|
|
||||||
BYTE *Remap; // For the software renderer
|
|
||||||
PalEntry *Palette; // The ideal palette this maps to
|
|
||||||
FNativeTexture *Native; // The Palette stored in a HW texture
|
|
||||||
int NumEntries; // # of elements in this table (usually 256)
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Free();
|
|
||||||
void Alloc(int count);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern TAutoGrowArray<FRemapTable *> translationtables[NUM_TRANSLATION_TABLES];
|
|
||||||
extern BYTE shadetables[NUMCOLORMAPS*16*256];
|
extern BYTE shadetables[NUMCOLORMAPS*16*256];
|
||||||
extern BYTE *dc_translation;
|
extern BYTE *dc_translation;
|
||||||
|
|
||||||
inline WORD TRANSLATION(BYTE a, BYTE b)
|
|
||||||
{
|
|
||||||
return (a<<8) | b;
|
|
||||||
}
|
|
||||||
inline int GetTranslationType(WORD trans)
|
|
||||||
{
|
|
||||||
return trans >> 8;
|
|
||||||
}
|
|
||||||
// Retrieve the FRemapTable that an actor's translation value maps to.
|
|
||||||
FRemapTable *TranslationToTable(int translation);
|
|
||||||
|
|
||||||
#define DIM_MAP TRANSLATION(TRANSLATION_Dim, 0)
|
|
||||||
|
|
||||||
const int MAX_ACS_TRANSLATIONS = 255;
|
|
||||||
const int MAX_DECORATE_TRANSLATIONS = 255;
|
|
||||||
|
|
||||||
inline void R_CopyTranslation (WORD to, WORD from)
|
|
||||||
{
|
|
||||||
memcpy (&translationtables[to>>8][(to&255)*256],
|
|
||||||
&translationtables[from>>8][(from&255)*256], 256);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// [RH] Double view pixels by detail mode
|
// [RH] Double view pixels by detail mode
|
||||||
void R_DetailDouble (void);
|
void R_DetailDouble (void);
|
||||||
|
|
||||||
|
|
||||||
// Initialize color translation tables, for player rendering etc.
|
|
||||||
void R_InitTranslationTables (void);
|
|
||||||
void R_DeinitTranslationTables();
|
|
||||||
|
|
||||||
// [RH] Actually create a player's translation table.
|
|
||||||
void R_BuildPlayerTranslation (int player);
|
|
||||||
|
|
||||||
|
|
||||||
// If the view size is not full screen, draws a border around it.
|
// If the view size is not full screen, draws a border around it.
|
||||||
void R_DrawViewBorder (void);
|
void R_DrawViewBorder (void);
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "a_sharedglobal.h"
|
#include "a_sharedglobal.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
670
src/r_translate.cpp
Normal file
670
src/r_translate.cpp
Normal file
|
@ -0,0 +1,670 @@
|
||||||
|
/*
|
||||||
|
** r_translate.cpp
|
||||||
|
** Translatioo table handling
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 1998-2006 Randy Heit
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "templates.h"
|
||||||
|
#include "m_alloc.h"
|
||||||
|
#include "r_draw.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "g_game.h"
|
||||||
|
|
||||||
|
#include "gi.h"
|
||||||
|
#include "stats.h"
|
||||||
|
|
||||||
|
TAutoGrowArray<FRemapTable *> translationtables[NUM_TRANSLATION_TABLES];
|
||||||
|
|
||||||
|
/****************************************************/
|
||||||
|
/****************************************************/
|
||||||
|
|
||||||
|
FRemapTable::FRemapTable(int count)
|
||||||
|
{
|
||||||
|
assert(count <= 256);
|
||||||
|
|
||||||
|
Alloc(count);
|
||||||
|
|
||||||
|
// Note that the tables are left uninitialized. It is assumed that
|
||||||
|
// the caller will do that next, if only by calling MakeIdentity().
|
||||||
|
}
|
||||||
|
|
||||||
|
FRemapTable::~FRemapTable()
|
||||||
|
{
|
||||||
|
Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FRemapTable::Alloc(int count)
|
||||||
|
{
|
||||||
|
Remap = (BYTE *)M_Malloc(count*sizeof(*Remap) + count*sizeof(*Palette));
|
||||||
|
assert (Remap != NULL);
|
||||||
|
Palette = (PalEntry *)(Remap + count*(sizeof(*Remap)));
|
||||||
|
Native = NULL;
|
||||||
|
NumEntries = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FRemapTable::Free()
|
||||||
|
{
|
||||||
|
KillNative();
|
||||||
|
if (Remap != NULL)
|
||||||
|
{
|
||||||
|
free(Remap);
|
||||||
|
Remap = NULL;
|
||||||
|
Palette = NULL;
|
||||||
|
NumEntries = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FRemapTable::FRemapTable(const FRemapTable &o)
|
||||||
|
{
|
||||||
|
Remap = NULL;
|
||||||
|
Native = NULL;
|
||||||
|
NumEntries = 0;
|
||||||
|
operator= (o);
|
||||||
|
}
|
||||||
|
|
||||||
|
FRemapTable &FRemapTable::operator=(const FRemapTable &o)
|
||||||
|
{
|
||||||
|
if (&o == this)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (o.NumEntries != NumEntries)
|
||||||
|
{
|
||||||
|
Free();
|
||||||
|
}
|
||||||
|
if (Remap == NULL)
|
||||||
|
{
|
||||||
|
Alloc(o.NumEntries);
|
||||||
|
}
|
||||||
|
memcpy(Remap, o.Remap, NumEntries*sizeof(*Remap) + NumEntries*sizeof(*Palette));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FRemapTable::operator==(const FRemapTable &o)
|
||||||
|
{
|
||||||
|
// Two translations are identical when they have the same amount of colors
|
||||||
|
// and the palette values for both are identical.
|
||||||
|
if (&o == this) return true;
|
||||||
|
if (o.NumEntries != NumEntries) return false;
|
||||||
|
return !memcmp(o.Palette, Palette, NumEntries * sizeof(*Palette));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FRemapTable::Serialize(FArchive &arc)
|
||||||
|
{
|
||||||
|
int n = NumEntries;
|
||||||
|
|
||||||
|
arc << NumEntries;
|
||||||
|
if (arc.IsStoring())
|
||||||
|
{
|
||||||
|
arc.Write (Remap, NumEntries);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (n != NumEntries)
|
||||||
|
{
|
||||||
|
Free();
|
||||||
|
Alloc(NumEntries);
|
||||||
|
}
|
||||||
|
arc.Read (Remap, NumEntries);
|
||||||
|
}
|
||||||
|
for (int j = 0; j < NumEntries; ++j)
|
||||||
|
{
|
||||||
|
arc << Palette[j].r
|
||||||
|
<< Palette[j].g
|
||||||
|
<< Palette[j].b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FRemapTable::MakeIdentity()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NumEntries; ++i)
|
||||||
|
{
|
||||||
|
Remap[i] = i;
|
||||||
|
}
|
||||||
|
for (i = 0; i < NumEntries; ++i)
|
||||||
|
{
|
||||||
|
Palette[i] = GPalette.BaseColors[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FRemapTable::IsIdentity() const
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 256; ++j)
|
||||||
|
{
|
||||||
|
if (Remap[j] != j)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FRemapTable::KillNative()
|
||||||
|
{
|
||||||
|
if (Native != NULL)
|
||||||
|
{
|
||||||
|
delete Native;
|
||||||
|
Native = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FRemapTable::UpdateNative()
|
||||||
|
{
|
||||||
|
if (Native != NULL)
|
||||||
|
{
|
||||||
|
Native->Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FNativeTexture *FRemapTable::GetNative()
|
||||||
|
{
|
||||||
|
if (Native == NULL)
|
||||||
|
{
|
||||||
|
Native = screen->CreatePalette(this);
|
||||||
|
}
|
||||||
|
return Native;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2)
|
||||||
|
{
|
||||||
|
fixed_t palcol, palstep;
|
||||||
|
|
||||||
|
if (start > end)
|
||||||
|
{
|
||||||
|
swap (start, end);
|
||||||
|
swap (pal1, pal2);
|
||||||
|
}
|
||||||
|
else if (start == end)
|
||||||
|
{
|
||||||
|
Remap[start] = pal1;
|
||||||
|
Palette[start] = GPalette.BaseColors[pal1];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
palcol = pal1 << FRACBITS;
|
||||||
|
palstep = ((pal2 << FRACBITS) - palcol) / (end - start);
|
||||||
|
for (int i = start; i <= end; palcol += palstep, ++i)
|
||||||
|
{
|
||||||
|
Remap[i] = palcol >> FRACBITS;
|
||||||
|
Palette[i] = GPalette.BaseColors[palcol >> FRACBITS];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FRemapTable::AddColorRange(int start, int end, int _r1,int _g1, int _b1, int _r2, int _g2, int _b2)
|
||||||
|
{
|
||||||
|
fixed_t r1 = _r1 << FRACBITS;
|
||||||
|
fixed_t g1 = _g1 << FRACBITS;
|
||||||
|
fixed_t b1 = _b1 << FRACBITS;
|
||||||
|
fixed_t r2 = _r2 << FRACBITS;
|
||||||
|
fixed_t g2 = _g2 << FRACBITS;
|
||||||
|
fixed_t b2 = _b2 << FRACBITS;
|
||||||
|
fixed_t r, g, b;
|
||||||
|
fixed_t rs, gs, bs;
|
||||||
|
|
||||||
|
if (start > end)
|
||||||
|
{
|
||||||
|
swap (start, end);
|
||||||
|
r = r2;
|
||||||
|
g = g2;
|
||||||
|
b = b2;
|
||||||
|
rs = r1 - r2;
|
||||||
|
gs = g1 - g2;
|
||||||
|
bs = b1 - b2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = r1;
|
||||||
|
g = g1;
|
||||||
|
b = b1;
|
||||||
|
rs = r2 - r1;
|
||||||
|
gs = g2 - g1;
|
||||||
|
bs = b2 - b1;
|
||||||
|
}
|
||||||
|
if (start == end)
|
||||||
|
{
|
||||||
|
Remap[start] = ColorMatcher.Pick
|
||||||
|
(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
||||||
|
Palette[start] = PalEntry(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rs /= (end - start);
|
||||||
|
gs /= (end - start);
|
||||||
|
bs /= (end - start);
|
||||||
|
for (int i = start; i <= end; ++i)
|
||||||
|
{
|
||||||
|
Remap[i] = ColorMatcher.Pick
|
||||||
|
(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
||||||
|
Palette[i] = PalEntry(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
||||||
|
r += rs;
|
||||||
|
g += gs;
|
||||||
|
b += bs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FRemapTable *TranslationToTable(int translation)
|
||||||
|
{
|
||||||
|
unsigned int type = GetTranslationType(translation);
|
||||||
|
unsigned int index = GetTranslationIndex(translation);
|
||||||
|
TAutoGrowArray<FRemapTable *> *slots;
|
||||||
|
|
||||||
|
if (type <= 0 || type >= NUM_TRANSLATION_TABLES)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
slots = &translationtables[type];
|
||||||
|
if (index >= slots->Size())
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return slots->operator[](index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PushIdentityTable(int slot)
|
||||||
|
{
|
||||||
|
FRemapTable *table = new FRemapTable;
|
||||||
|
table->MakeIdentity();
|
||||||
|
translationtables[slot].Push(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// R_InitTranslationTables
|
||||||
|
// Creates the translation tables to map the green color ramp to gray,
|
||||||
|
// brown, red. Assumes a given structure of the PLAYPAL.
|
||||||
|
//
|
||||||
|
void R_InitTranslationTables ()
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
// Each player gets two translations. Doom and Strife don't use the
|
||||||
|
// extra ones, but Heretic and Hexen do. These are set up during
|
||||||
|
// netgame arbitration and as-needed, so they just get to be identity
|
||||||
|
// maps until then so they won't be invalid.
|
||||||
|
for (i = 0; i < MAXPLAYERS; ++i)
|
||||||
|
{
|
||||||
|
PushIdentityTable(TRANSLATION_Players);
|
||||||
|
PushIdentityTable(TRANSLATION_PlayersExtra);
|
||||||
|
}
|
||||||
|
// The menu player also gets a separate translation table
|
||||||
|
PushIdentityTable(TRANSLATION_Players);
|
||||||
|
|
||||||
|
// The three standard translations from Doom or Heretic (seven for Strife),
|
||||||
|
// plus the generic ice translation.
|
||||||
|
for (i = 0; i < 8; ++i)
|
||||||
|
{
|
||||||
|
PushIdentityTable(TRANSLATION_Standard);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each player corpse has its own translation so they won't change
|
||||||
|
// color if the player who created them changes theirs.
|
||||||
|
for (i = 0; i < BODYQUESIZE; ++i)
|
||||||
|
{
|
||||||
|
PushIdentityTable(TRANSLATION_PlayerCorpses);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the standard translation tables
|
||||||
|
if (gameinfo.gametype == GAME_Doom)
|
||||||
|
{
|
||||||
|
for (i = 0x70; i < 0x80; i++)
|
||||||
|
{ // map green ramp to gray, brown, red
|
||||||
|
translationtables[TRANSLATION_Standard][0]->Remap[i] = 0x60 + (i&0xf);
|
||||||
|
translationtables[TRANSLATION_Standard][1]->Remap[i] = 0x40 + (i&0xf);
|
||||||
|
translationtables[TRANSLATION_Standard][2]->Remap[i] = 0x20 + (i&0xf);
|
||||||
|
|
||||||
|
translationtables[TRANSLATION_Standard][0]->Palette[i] = GPalette.BaseColors[0x60 + (i&0xf)];
|
||||||
|
translationtables[TRANSLATION_Standard][1]->Palette[i] = GPalette.BaseColors[0x40 + (i&0xf)];
|
||||||
|
translationtables[TRANSLATION_Standard][2]->Palette[i] = GPalette.BaseColors[0x20 + (i&0xf)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (gameinfo.gametype == GAME_Heretic)
|
||||||
|
{
|
||||||
|
for (i = 225; i <= 240; i++)
|
||||||
|
{
|
||||||
|
translationtables[TRANSLATION_Standard][0]->Remap[i] = 114+(i-225); // yellow
|
||||||
|
translationtables[TRANSLATION_Standard][1]->Remap[i] = 145+(i-225); // red
|
||||||
|
translationtables[TRANSLATION_Standard][2]->Remap[i] = 190+(i-225); // blue
|
||||||
|
|
||||||
|
translationtables[TRANSLATION_Standard][0]->Palette[i] = GPalette.BaseColors[114+(i-225)];
|
||||||
|
translationtables[TRANSLATION_Standard][1]->Palette[i] = GPalette.BaseColors[145+(i-225)];
|
||||||
|
translationtables[TRANSLATION_Standard][2]->Palette[i] = GPalette.BaseColors[190+(i-225)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (gameinfo.gametype == GAME_Strife)
|
||||||
|
{
|
||||||
|
for (i = 0x20; i <= 0x3F; ++i)
|
||||||
|
{
|
||||||
|
translationtables[TRANSLATION_Standard][0]->Remap[i] = i - 0x20;
|
||||||
|
translationtables[TRANSLATION_Standard][1]->Remap[i] = i - 0x20;
|
||||||
|
translationtables[TRANSLATION_Standard][2]->Remap[i] = 0xD0 + (i&0xf);
|
||||||
|
translationtables[TRANSLATION_Standard][3]->Remap[i] = 0xD0 + (i&0xf);
|
||||||
|
translationtables[TRANSLATION_Standard][4]->Remap[i] = i - 0x20;
|
||||||
|
translationtables[TRANSLATION_Standard][5]->Remap[i] = i - 0x20;
|
||||||
|
translationtables[TRANSLATION_Standard][6]->Remap[i] = i - 0x20;
|
||||||
|
}
|
||||||
|
for (i = 0x50; i <= 0x5F; ++i)
|
||||||
|
{
|
||||||
|
// Merchant hair
|
||||||
|
translationtables[TRANSLATION_Standard][4]->Remap[i] = 0x80 + (i&0xf);
|
||||||
|
translationtables[TRANSLATION_Standard][5]->Remap[i] = 0x10 + (i&0xf);
|
||||||
|
translationtables[TRANSLATION_Standard][6]->Remap[i] = 0x40 + (i&0xf);
|
||||||
|
}
|
||||||
|
for (i = 0x80; i <= 0x8F; ++i)
|
||||||
|
{
|
||||||
|
translationtables[TRANSLATION_Standard][0]->Remap[i] = 0x40 + (i&0xf); // red
|
||||||
|
translationtables[TRANSLATION_Standard][1]->Remap[i] = 0xB0 + (i&0xf); // rust
|
||||||
|
translationtables[TRANSLATION_Standard][2]->Remap[i] = 0x10 + (i&0xf); // gray
|
||||||
|
translationtables[TRANSLATION_Standard][3]->Remap[i] = 0x30 + (i&0xf); // dark green
|
||||||
|
translationtables[TRANSLATION_Standard][4]->Remap[i] = 0x50 + (i&0xf); // gold
|
||||||
|
translationtables[TRANSLATION_Standard][5]->Remap[i] = 0x60 + (i&0xf); // bright green
|
||||||
|
translationtables[TRANSLATION_Standard][6]->Remap[i] = 0x90 + (i&0xf); // blue
|
||||||
|
}
|
||||||
|
for (i = 0xC0; i <= 0xCF; ++i)
|
||||||
|
{
|
||||||
|
translationtables[TRANSLATION_Standard][4]->Remap[i] = 0xA0 + (i&0xf);
|
||||||
|
translationtables[TRANSLATION_Standard][5]->Remap[i] = 0x20 + (i&0xf);
|
||||||
|
translationtables[TRANSLATION_Standard][6]->Remap[i] = (i&0xf);
|
||||||
|
}
|
||||||
|
translationtables[TRANSLATION_Standard][6]->Remap[0xC0] = 1;
|
||||||
|
for (i = 0xD0; i <= 0xDF; ++i)
|
||||||
|
{
|
||||||
|
translationtables[TRANSLATION_Standard][4]->Remap[i] = 0xB0 + (i&0xf);
|
||||||
|
translationtables[TRANSLATION_Standard][5]->Remap[i] = 0x30 + (i&0xf);
|
||||||
|
translationtables[TRANSLATION_Standard][6]->Remap[i] = 0x10 + (i&0xf);
|
||||||
|
}
|
||||||
|
for (i = 0xF1; i <= 0xF6; ++i)
|
||||||
|
{
|
||||||
|
translationtables[TRANSLATION_Standard][0]->Remap[i] = 0xDF + (i&0xf);
|
||||||
|
}
|
||||||
|
for (i = 0xF7; i <= 0xFB; ++i)
|
||||||
|
{
|
||||||
|
translationtables[TRANSLATION_Standard][0]->Remap[i] = i - 6;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 7; ++i)
|
||||||
|
{
|
||||||
|
for (int j = 0x20; j <= 0xFB; ++j)
|
||||||
|
{
|
||||||
|
translationtables[TRANSLATION_Standard][i]->Palette[j] =
|
||||||
|
GPalette.BaseColors[translationtables[TRANSLATION_Standard][i]->Remap[j]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the ice translation table, based on Hexen's. Alas, the standard
|
||||||
|
// Doom palette has no good substitutes for these bluish-tinted grays, so
|
||||||
|
// they will just look gray unless you use a different PLAYPAL with Doom.
|
||||||
|
|
||||||
|
static const BYTE IcePalette[16][3] =
|
||||||
|
{
|
||||||
|
{ 10, 8, 18 },
|
||||||
|
{ 15, 15, 26 },
|
||||||
|
{ 20, 16, 36 },
|
||||||
|
{ 30, 26, 46 },
|
||||||
|
{ 40, 36, 57 },
|
||||||
|
{ 50, 46, 67 },
|
||||||
|
{ 59, 57, 78 },
|
||||||
|
{ 69, 67, 88 },
|
||||||
|
{ 79, 77, 99 },
|
||||||
|
{ 89, 87,109 },
|
||||||
|
{ 99, 97,120 },
|
||||||
|
{ 109,107,130 },
|
||||||
|
{ 118,118,141 },
|
||||||
|
{ 128,128,151 },
|
||||||
|
{ 138,138,162 },
|
||||||
|
{ 148,148,172 }
|
||||||
|
};
|
||||||
|
BYTE IcePaletteRemap[16];
|
||||||
|
for (i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
IcePaletteRemap[i] = ColorMatcher.Pick (IcePalette[i][0], IcePalette[i][1], IcePalette[i][2]);
|
||||||
|
}
|
||||||
|
FRemapTable *remap = translationtables[TRANSLATION_Standard][7];
|
||||||
|
for (i = 0; i < 256; ++i)
|
||||||
|
{
|
||||||
|
int r = GPalette.BaseColors[i].r;
|
||||||
|
int g = GPalette.BaseColors[i].g;
|
||||||
|
int b = GPalette.BaseColors[i].b;
|
||||||
|
int v = (r*77 + g*143 + b*37) >> 12;
|
||||||
|
remap->Remap[i] = IcePaletteRemap[v];
|
||||||
|
remap->Palette[i] = PalEntry(IcePalette[v][0], IcePalette[v][1], IcePalette[v][2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up shading tables for shaded columns
|
||||||
|
// 16 colormap sets, progressing from full alpha to minimum visible alpha
|
||||||
|
|
||||||
|
BYTE *table = shadetables;
|
||||||
|
|
||||||
|
// Full alpha
|
||||||
|
for (i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
for (j = 0; j < NUMCOLORMAPS; ++j)
|
||||||
|
{
|
||||||
|
int a = (NUMCOLORMAPS - j) * 256 / NUMCOLORMAPS * (16-i);
|
||||||
|
for (int k = 0; k < 256; ++k)
|
||||||
|
{
|
||||||
|
BYTE v = (((k+2) * a) + 256) >> 14;
|
||||||
|
table[k] = MIN<BYTE> (v, 64);
|
||||||
|
}
|
||||||
|
table += 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_DeinitTranslationTables()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_TRANSLATION_TABLES; ++i)
|
||||||
|
{
|
||||||
|
for (unsigned int j = 0; j < translationtables[i].Size(); ++j)
|
||||||
|
{
|
||||||
|
if (translationtables[i][j] != NULL)
|
||||||
|
{
|
||||||
|
delete translationtables[i][j];
|
||||||
|
translationtables[i][j] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// [RH] Create a player's translation table based on a given mid-range color.
|
||||||
|
// [GRB] Split to 2 functions (because of player setup menu)
|
||||||
|
static void SetRemap(FRemapTable *table, int i, float r, float g, float b)
|
||||||
|
{
|
||||||
|
int ir = clamp (int(r * 255.f), 0, 255);
|
||||||
|
int ig = clamp (int(g * 255.f), 0, 255);
|
||||||
|
int ib = clamp (int(b * 255.f), 0, 255);
|
||||||
|
table->Remap[i] = ColorMatcher.Pick (ir, ig, ib);
|
||||||
|
table->Palette[i] = PalEntry(ir, ig, ib);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *skin, FRemapTable *table, FRemapTable *alttable)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
BYTE start = skin->range0start;
|
||||||
|
BYTE end = skin->range0end;
|
||||||
|
float r, g, b;
|
||||||
|
float bases, basev;
|
||||||
|
float sdelta, vdelta;
|
||||||
|
float range;
|
||||||
|
|
||||||
|
// Set up the base translation for this skin. If the skin was created
|
||||||
|
// for the current game, then this is just an identity translation.
|
||||||
|
// Otherwise, it remaps the colors from the skin's original palette to
|
||||||
|
// the current one.
|
||||||
|
if (skin->othergame)
|
||||||
|
{
|
||||||
|
memcpy (table->Remap, OtherGameSkinRemap, 256);
|
||||||
|
memcpy (table->Palette, OtherGameSkinPalette, sizeof(table->Palette));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < 256; ++i)
|
||||||
|
{
|
||||||
|
table->Remap[i] = i;
|
||||||
|
}
|
||||||
|
memcpy(table->Palette, GPalette.BaseColors, sizeof(table->Palette));
|
||||||
|
}
|
||||||
|
|
||||||
|
// [GRB] Don't translate skins with color range 0-0 (APlayerPawn default)
|
||||||
|
if (start == 0 && end == 0)
|
||||||
|
{
|
||||||
|
table->UpdateNative();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
range = (float)(end-start+1);
|
||||||
|
|
||||||
|
bases = s;
|
||||||
|
basev = v;
|
||||||
|
|
||||||
|
if (gameinfo.gametype == GAME_Doom || gameinfo.gametype == GAME_Strife)
|
||||||
|
{
|
||||||
|
// Build player sprite translation
|
||||||
|
s -= 0.23f;
|
||||||
|
v += 0.1f;
|
||||||
|
sdelta = 0.23f / range;
|
||||||
|
vdelta = -0.94112f / range;
|
||||||
|
|
||||||
|
for (i = start; i <= end; i++)
|
||||||
|
{
|
||||||
|
float uses, usev;
|
||||||
|
uses = clamp (s, 0.f, 1.f);
|
||||||
|
usev = clamp (v, 0.f, 1.f);
|
||||||
|
HSVtoRGB (&r, &g, &b, h, uses, usev);
|
||||||
|
SetRemap(table, i, r, g, b);
|
||||||
|
s += sdelta;
|
||||||
|
v += vdelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (gameinfo.gametype == GAME_Heretic)
|
||||||
|
{
|
||||||
|
float vdelta = 0.418916f / range;
|
||||||
|
|
||||||
|
// Build player sprite translation
|
||||||
|
for (i = start; i <= end; i++)
|
||||||
|
{
|
||||||
|
v = vdelta * (float)(i - start) + basev - 0.2352937f;
|
||||||
|
v = clamp (v, 0.f, 1.f);
|
||||||
|
HSVtoRGB (&r, &g, &b, h, s, v);
|
||||||
|
SetRemap(table, i, r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build rain/lifegem translation
|
||||||
|
if (alttable)
|
||||||
|
{
|
||||||
|
bases = MIN (bases*1.3f, 1.f);
|
||||||
|
basev = MIN (basev*1.3f, 1.f);
|
||||||
|
for (i = 145; i <= 168; i++)
|
||||||
|
{
|
||||||
|
s = MIN (bases, 0.8965f - 0.0962f*(float)(i - 161));
|
||||||
|
v = MIN (1.f, (0.2102f + 0.0489f*(float)(i - 144)) * basev);
|
||||||
|
HSVtoRGB (&r, &g, &b, h, s, v);
|
||||||
|
SetRemap(alttable, i, r, g, b);
|
||||||
|
}
|
||||||
|
alttable->UpdateNative();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (gameinfo.gametype == GAME_Hexen)
|
||||||
|
{
|
||||||
|
if (memcmp (sprites[skin->sprite].name, "PLAY", 4) == 0)
|
||||||
|
{ // The fighter is different! He gets a brown hairy loincloth, but the other
|
||||||
|
// two have blue capes.
|
||||||
|
float vs[9] = { .28f, .32f, .38f, .42f, .47f, .5f, .58f, .71f, .83f };
|
||||||
|
|
||||||
|
// Build player sprite translation
|
||||||
|
//h = 45.f;
|
||||||
|
v = MAX (0.1f, v);
|
||||||
|
|
||||||
|
for (i = start; i <= end; i++)
|
||||||
|
{
|
||||||
|
HSVtoRGB (&r, &g, &b, h, s, vs[(i-start)*9/(int)range]*basev);
|
||||||
|
SetRemap(table, i, r, g, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float ms[18] = { .95f, .96f, .89f, .97f, .97f, 1.f, 1.f, 1.f, .97f, .99f, .87f, .77f, .69f, .62f, .57f, .47f, .43f };
|
||||||
|
float mv[18] = { .16f, .19f, .22f, .25f, .31f, .35f, .38f, .41f, .47f, .54f, .60f, .65f, .71f, .77f, .83f, .89f, .94f, 1.f };
|
||||||
|
|
||||||
|
// Build player sprite translation
|
||||||
|
v = MAX (0.1f, v);
|
||||||
|
|
||||||
|
for (i = start; i <= end; i++)
|
||||||
|
{
|
||||||
|
HSVtoRGB (&r, &g, &b, h, ms[(i-start)*18/(int)range]*bases, mv[(i-start)*18/(int)range]*basev);
|
||||||
|
SetRemap(table, i, r, g, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build lifegem translation
|
||||||
|
if (alttable)
|
||||||
|
{
|
||||||
|
for (i = 164; i <= 185; ++i)
|
||||||
|
{
|
||||||
|
const PalEntry *base = &GPalette.BaseColors[i];
|
||||||
|
float dummy;
|
||||||
|
|
||||||
|
RGBtoHSV (base->r/255.f, base->g/255.f, base->b/255.f, &dummy, &s, &v);
|
||||||
|
HSVtoRGB (&r, &g, &b, h, s*bases, v*basev);
|
||||||
|
SetRemap(alttable, i, r, g, b);
|
||||||
|
}
|
||||||
|
alttable->UpdateNative();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
table->UpdateNative();
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_BuildPlayerTranslation (int player)
|
||||||
|
{
|
||||||
|
float h, s, v;
|
||||||
|
|
||||||
|
D_GetPlayerColor (player, &h, &s, &v);
|
||||||
|
|
||||||
|
R_CreatePlayerTranslation (h, s, v,
|
||||||
|
&skins[players[player].userinfo.skin],
|
||||||
|
translationtables[TRANSLATION_Players][player],
|
||||||
|
translationtables[TRANSLATION_PlayersExtra][player]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_GetPlayerTranslation (int color, FPlayerSkin *skin, FRemapTable *table)
|
||||||
|
{
|
||||||
|
float h, s, v;
|
||||||
|
|
||||||
|
RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f,
|
||||||
|
&h, &s, &v);
|
||||||
|
|
||||||
|
R_CreatePlayerTranslation (h, s, v, skin, table, NULL);
|
||||||
|
}
|
85
src/r_translate.h
Normal file
85
src/r_translate.h
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#ifndef __R_TRANSLATE_H
|
||||||
|
#define __R_TRANSLATE_H
|
||||||
|
|
||||||
|
#include "doomtype.h"
|
||||||
|
#include "tarray.h"
|
||||||
|
|
||||||
|
class FNativeTexture;
|
||||||
|
class FArchive;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TRANSLATION_Invalid,
|
||||||
|
TRANSLATION_Players,
|
||||||
|
TRANSLATION_PlayersExtra,
|
||||||
|
TRANSLATION_Standard,
|
||||||
|
TRANSLATION_LevelScripted,
|
||||||
|
TRANSLATION_Decals,
|
||||||
|
TRANSLATION_PlayerCorpses,
|
||||||
|
TRANSLATION_Decorate,
|
||||||
|
TRANSLATION_Blood,
|
||||||
|
|
||||||
|
NUM_TRANSLATION_TABLES
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FRemapTable
|
||||||
|
{
|
||||||
|
FRemapTable(int count=256);
|
||||||
|
FRemapTable(const FRemapTable &o);
|
||||||
|
~FRemapTable();
|
||||||
|
|
||||||
|
FRemapTable &operator= (const FRemapTable &o);
|
||||||
|
bool operator==(const FRemapTable &o);
|
||||||
|
void MakeIdentity();
|
||||||
|
void KillNative();
|
||||||
|
void UpdateNative();
|
||||||
|
FNativeTexture *GetNative();
|
||||||
|
bool IsIdentity() const;
|
||||||
|
void Serialize(FArchive &ar);
|
||||||
|
void AddIndexRange(int start, int end, int pal1, int pal2);
|
||||||
|
void AddColorRange(int start, int end, int r1,int g1, int b1, int r2, int g2, int b2);
|
||||||
|
|
||||||
|
BYTE *Remap; // For the software renderer
|
||||||
|
PalEntry *Palette; // The ideal palette this maps to
|
||||||
|
FNativeTexture *Native; // The Palette stored in a HW texture
|
||||||
|
int NumEntries; // # of elements in this table (usually 256)
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Free();
|
||||||
|
void Alloc(int count);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern TAutoGrowArray<FRemapTable *> translationtables[NUM_TRANSLATION_TABLES];
|
||||||
|
|
||||||
|
#define TRANSLATION_SHIFT 16
|
||||||
|
#define TRANSLATION_MASK ((1<<TRANSLATION_SHIFT)-1)
|
||||||
|
#define TRANSLATIONTYPE_MASK (255<<TRANSLATION_SHIFT)
|
||||||
|
|
||||||
|
inline DWORD TRANSLATION(BYTE a, DWORD b)
|
||||||
|
{
|
||||||
|
return (a<<TRANSLATION_SHIFT) | b;
|
||||||
|
}
|
||||||
|
inline int GetTranslationType(DWORD trans)
|
||||||
|
{
|
||||||
|
return (trans&TRANSLATIONTYPE_MASK) >> TRANSLATION_SHIFT;
|
||||||
|
}
|
||||||
|
inline int GetTranslationIndex(DWORD trans)
|
||||||
|
{
|
||||||
|
return (trans&TRANSLATION_MASK);
|
||||||
|
}
|
||||||
|
// Retrieve the FRemapTable that an actor's translation value maps to.
|
||||||
|
FRemapTable *TranslationToTable(int translation);
|
||||||
|
|
||||||
|
const int MAX_ACS_TRANSLATIONS = 65535;
|
||||||
|
const int MAX_DECORATE_TRANSLATIONS = 65535;
|
||||||
|
|
||||||
|
// Initialize color translation tables, for player rendering etc.
|
||||||
|
void R_InitTranslationTables (void);
|
||||||
|
void R_DeinitTranslationTables();
|
||||||
|
|
||||||
|
// [RH] Actually create a player's translation table.
|
||||||
|
void R_BuildPlayerTranslation (int player);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __R_TRANSLATE_H
|
|
@ -51,6 +51,7 @@
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "thingdef.h"
|
#include "thingdef.h"
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
// TYPES -------------------------------------------------------------------
|
// TYPES -------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,6 @@ void ParseClass();
|
||||||
void ParseGlobalConst();
|
void ParseGlobalConst();
|
||||||
void ParseGlobalEnum();
|
void ParseGlobalEnum();
|
||||||
void FinishThingdef();
|
void FinishThingdef();
|
||||||
void InitDecorateTranslations();
|
|
||||||
void ParseOldDecoration(EDefinitionType def);
|
void ParseOldDecoration(EDefinitionType def);
|
||||||
|
|
||||||
// STATIC FUNCTION PROTOTYPES --------------------------------------------
|
// STATIC FUNCTION PROTOTYPES --------------------------------------------
|
||||||
|
@ -164,7 +163,6 @@ void LoadDecorations ()
|
||||||
{
|
{
|
||||||
int lastlump, lump;
|
int lastlump, lump;
|
||||||
|
|
||||||
InitDecorateTranslations();
|
|
||||||
lastlump = 0;
|
lastlump = 0;
|
||||||
while ((lump = Wads.FindLump ("DECORATE", &lastlump)) != -1)
|
while ((lump = Wads.FindLump ("DECORATE", &lastlump)) != -1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "thingdef.h"
|
#include "thingdef.h"
|
||||||
#include "a_sharedglobal.h"
|
#include "a_sharedglobal.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -506,17 +507,10 @@ void ParseActorFlag (Baggage &bag, int mod)
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static int NumUsedTranslations;
|
FRemapTable CurrentTranslation;
|
||||||
static int NumUsedBloodTranslations;
|
TArray<PalEntry> BloodTranslationColors;
|
||||||
BYTE decorate_translations[256*256*2];
|
|
||||||
PalEntry BloodTranslations[256];
|
|
||||||
|
|
||||||
void InitDecorateTranslations()
|
PalEntry BloodTranslations[256];
|
||||||
{
|
|
||||||
// The translation tables haven't been allocated yet so we may as easily use a static buffer instead!
|
|
||||||
NumUsedBloodTranslations = NumUsedTranslations = 0;
|
|
||||||
for(int i=0;i<256*256*2;i++) decorate_translations[i]=i&255;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool Check(char *& range, char c, bool error=true)
|
static bool Check(char *& range, char c, bool error=true)
|
||||||
{
|
{
|
||||||
|
@ -534,7 +528,7 @@ static bool Check(char *& range, char c, bool error=true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void AddToTranslation(unsigned char * translation, char * range)
|
static void AddToTranslation(char * range)
|
||||||
{
|
{
|
||||||
int start,end;
|
int start,end;
|
||||||
|
|
||||||
|
@ -545,40 +539,17 @@ static void AddToTranslation(unsigned char * translation, char * range)
|
||||||
if (!Check(range, '[', false))
|
if (!Check(range, '[', false))
|
||||||
{
|
{
|
||||||
int pal1,pal2;
|
int pal1,pal2;
|
||||||
fixed_t palcol, palstep;
|
|
||||||
|
|
||||||
pal1=strtol(range, &range, 10);
|
pal1=strtol(range, &range, 10);
|
||||||
if (!Check(range, ':')) return;
|
if (!Check(range, ':')) return;
|
||||||
pal2=strtol(range, &range, 10);
|
pal2=strtol(range, &range, 10);
|
||||||
|
|
||||||
if (start > end)
|
CurrentTranslation.AddIndexRange(start, end, pal1, pal2);
|
||||||
{
|
|
||||||
swap (start, end);
|
|
||||||
swap (pal1, pal2);
|
|
||||||
}
|
|
||||||
else if (start == end)
|
|
||||||
{
|
|
||||||
translation[start] = pal1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
palcol = pal1 << FRACBITS;
|
|
||||||
palstep = ((pal2 << FRACBITS) - palcol) / (end - start);
|
|
||||||
for (int i = start; i <= end; palcol += palstep, ++i)
|
|
||||||
{
|
|
||||||
translation[i] = palcol >> FRACBITS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// translation using RGB values
|
// translation using RGB values
|
||||||
int r1;
|
int r1,g1,b1,r2,g2,b2;
|
||||||
int g1;
|
|
||||||
int b1;
|
|
||||||
int r2;
|
|
||||||
int g2;
|
|
||||||
int b2;
|
|
||||||
int r,g,b;
|
|
||||||
int rs,gs,bs;
|
|
||||||
|
|
||||||
r1=strtol(range, &range, 10);
|
r1=strtol(range, &range, 10);
|
||||||
if (!Check(range, ',')) return;
|
if (!Check(range, ',')) return;
|
||||||
|
@ -595,98 +566,62 @@ static void AddToTranslation(unsigned char * translation, char * range)
|
||||||
b2=strtol(range, &range, 10);
|
b2=strtol(range, &range, 10);
|
||||||
if (!Check(range, ']')) return;
|
if (!Check(range, ']')) return;
|
||||||
|
|
||||||
if (start > end)
|
CurrentTranslation.AddColorRange(start, end, r1, g1, b1, r2, g2, b2);
|
||||||
{
|
|
||||||
swap (start, end);
|
|
||||||
r = r2;
|
|
||||||
g = g2;
|
|
||||||
b = b2;
|
|
||||||
rs = r1 - r2;
|
|
||||||
gs = g1 - g2;
|
|
||||||
bs = b1 - b2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
r = r1;
|
|
||||||
g = g1;
|
|
||||||
b = b1;
|
|
||||||
rs = r2 - r1;
|
|
||||||
gs = g2 - g1;
|
|
||||||
bs = b2 - b1;
|
|
||||||
}
|
|
||||||
r <<= FRACBITS;
|
|
||||||
g <<= FRACBITS;
|
|
||||||
b <<= FRACBITS;
|
|
||||||
rs <<= FRACBITS;
|
|
||||||
gs <<= FRACBITS;
|
|
||||||
bs <<= FRACBITS;
|
|
||||||
if (start == end)
|
|
||||||
{
|
|
||||||
translation[start] = ColorMatcher.Pick
|
|
||||||
(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
rs /= (end - start);
|
|
||||||
gs /= (end - start);
|
|
||||||
bs /= (end - start);
|
|
||||||
for (int i = start; i <= end; ++i)
|
|
||||||
{
|
|
||||||
translation[i] = ColorMatcher.Pick
|
|
||||||
(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
|
||||||
r += rs;
|
|
||||||
g += gs;
|
|
||||||
b += bs;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int StoreTranslation(const unsigned char * translation)
|
static int StoreTranslation()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NumUsedTranslations; i++)
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < translationtables[TRANSLATION_Decorate].Size(); i++)
|
||||||
{
|
{
|
||||||
if (!memcmp(translation, decorate_translations + i*256, 256))
|
if (CurrentTranslation == *translationtables[TRANSLATION_Decorate][i])
|
||||||
{
|
{
|
||||||
// A duplicate of this translation already exists
|
// A duplicate of this translation already exists
|
||||||
return TRANSLATION(TRANSLATION_Decorate, i);
|
return TRANSLATION(TRANSLATION_Decorate, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (NumUsedTranslations>=MAX_DECORATE_TRANSLATIONS)
|
if (translationtables[TRANSLATION_Decorate].Size() >= MAX_DECORATE_TRANSLATIONS)
|
||||||
{
|
{
|
||||||
SC_ScriptError("Too many translations in DECORATE");
|
SC_ScriptError("Too many translations in DECORATE");
|
||||||
}
|
}
|
||||||
memcpy(decorate_translations + NumUsedTranslations*256, translation, 256);
|
FRemapTable *newtrans = new FRemapTable;
|
||||||
NumUsedTranslations++;
|
*newtrans = CurrentTranslation;
|
||||||
return TRANSLATION(TRANSLATION_Decorate, NumUsedTranslations-1);
|
i = translationtables[TRANSLATION_Decorate].Push(newtrans);
|
||||||
|
return TRANSLATION(TRANSLATION_Decorate, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CreateBloodTranslation(PalEntry color)
|
static int CreateBloodTranslation(PalEntry color)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < NumUsedBloodTranslations; i++)
|
for (i = 0; i < BloodTranslationColors.Size(); i++)
|
||||||
{
|
{
|
||||||
if (color.r == BloodTranslations[i].r &&
|
if (color.r == BloodTranslationColors[i].r &&
|
||||||
color.g == BloodTranslations[i].g &&
|
color.g == BloodTranslationColors[i].g &&
|
||||||
color.b == BloodTranslations[i].b)
|
color.b == BloodTranslationColors[i].b)
|
||||||
{
|
{
|
||||||
// A duplicate of this translation already exists
|
// A duplicate of this translation already exists
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (NumUsedBloodTranslations>=MAX_DECORATE_TRANSLATIONS)
|
if (BloodTranslationColors.Size() >= MAX_DECORATE_TRANSLATIONS)
|
||||||
{
|
{
|
||||||
SC_ScriptError("Too many blood colors in DECORATE");
|
SC_ScriptError("Too many blood colors in DECORATE");
|
||||||
}
|
}
|
||||||
|
FRemapTable *trans = new FRemapTable;
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
int bright = MAX(MAX(GPalette.BaseColors[i].r, GPalette.BaseColors[i].g), GPalette.BaseColors[i].b);
|
int bright = MAX(MAX(GPalette.BaseColors[i].r, GPalette.BaseColors[i].g), GPalette.BaseColors[i].b);
|
||||||
int entry = ColorMatcher.Pick(color.r*bright/255, color.g*bright/255, color.b*bright/255);
|
PalEntry pe = PalEntry(color.r*bright/255, color.g*bright/255, color.b*bright/255);
|
||||||
|
int entry = ColorMatcher.Pick(pe.r, pe.g, pe.b);
|
||||||
|
|
||||||
*(decorate_translations + MAX_DECORATE_TRANSLATIONS*256 + NumUsedBloodTranslations*256 + i)=entry;
|
trans->Palette[i] = pe;
|
||||||
|
trans->Remap[i] = entry;
|
||||||
}
|
}
|
||||||
BloodTranslations[NumUsedBloodTranslations]=color;
|
translationtables[TRANSLATION_Blood].Push(trans);
|
||||||
return NumUsedBloodTranslations++;
|
return BloodTranslationColors.Push(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -1447,15 +1382,14 @@ static void ActorTranslation (AActor *defaults, Baggage &bag)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned char translation[256];
|
CurrentTranslation.MakeIdentity();
|
||||||
for(int i=0;i<256;i++) translation[i]=i;
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
SC_GetString();
|
SC_GetString();
|
||||||
AddToTranslation(translation,sc_String);
|
AddToTranslation(sc_String);
|
||||||
}
|
}
|
||||||
while (SC_CheckString(","));
|
while (SC_CheckString(","));
|
||||||
defaults->Translation = StoreTranslation (translation);
|
defaults->Translation = StoreTranslation ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "r_defs.h"
|
#include "r_defs.h"
|
||||||
#include "r_draw.h"
|
#include "r_draw.h"
|
||||||
#include "r_things.h"
|
#include "r_things.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "i_video.h"
|
#include "i_video.h"
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "sc_man.h"
|
#include "sc_man.h"
|
||||||
#include "hu_stuff.h"
|
#include "hu_stuff.h"
|
||||||
#include "r_draw.h"
|
#include "r_draw.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "sbar.h"
|
#include "sbar.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
IMPLEMENT_ABSTRACT_CLASS (DCanvas)
|
IMPLEMENT_ABSTRACT_CLASS (DCanvas)
|
||||||
IMPLEMENT_ABSTRACT_CLASS (DFrameBuffer)
|
IMPLEMENT_ABSTRACT_CLASS (DFrameBuffer)
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "sc_man.h"
|
#include "sc_man.h"
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
// States for the intermission
|
// States for the intermission
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
#include "doomerrors.h"
|
#include "doomerrors.h"
|
||||||
#include "r_draw.h"
|
#include "r_draw.h"
|
||||||
|
#include "r_translate.h"
|
||||||
|
|
||||||
#include "win32iface.h"
|
#include "win32iface.h"
|
||||||
|
|
||||||
|
|
|
@ -8962,6 +8962,10 @@
|
||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\r_translate.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Render Headers"
|
Name="Render Headers"
|
||||||
|
@ -9018,6 +9022,10 @@
|
||||||
RelativePath=".\src\r_things.h"
|
RelativePath=".\src\r_things.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\r_translate.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Textures"
|
Name="Textures"
|
||||||
|
|
Loading…
Reference in a new issue