- moved sc_man and palettecontainer to the 'common' folder.
This commit is contained in:
parent
98472d999b
commit
c713850dac
18 changed files with 71 additions and 59 deletions
657
src/common/engine/palettecontainer.cpp
Normal file
657
src/common/engine/palettecontainer.cpp
Normal file
|
|
@ -0,0 +1,657 @@
|
|||
/*
|
||||
** r_translate.cpp
|
||||
** Translation 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 "palutil.h"
|
||||
#include "sc_man.h"
|
||||
#include "v_palette.h"
|
||||
#include "m_crc32.h"
|
||||
#include "printf.h"
|
||||
#include "colormatcher.h"
|
||||
#include "templates.h"
|
||||
#include "palettecontainer.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void PaletteContainer::Init(int numslots) // This cannot be a constructor!!!
|
||||
{
|
||||
Clear();
|
||||
// Make sure that index 0 is always the identity translation.
|
||||
FRemapTable remap;
|
||||
remap.MakeIdentity();
|
||||
remap.Inactive = true;
|
||||
AddRemap(&remap);
|
||||
TranslationTables.Resize(numslots);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void PaletteContainer::Clear()
|
||||
{
|
||||
remapArena.FreeAllBlocks();
|
||||
uniqueRemaps.Reset();
|
||||
TranslationTables.Reset();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
FRemapTable* PaletteContainer::AddRemap(FRemapTable* remap)
|
||||
{
|
||||
if (!remap) return uniqueRemaps[0];
|
||||
|
||||
remap->crc32 = CalcCRC32((uint8_t*)remap->Palette, sizeof(remap->Palette));
|
||||
|
||||
for (auto uremap : uniqueRemaps)
|
||||
{
|
||||
if (uremap->crc32 == remap->crc32 && uremap->NumEntries == remap->NumEntries && *uremap == *remap)
|
||||
return uremap;
|
||||
}
|
||||
auto newremap = (FRemapTable*)remapArena.Alloc(sizeof(FRemapTable));
|
||||
*newremap = *remap;
|
||||
auto index = uniqueRemaps.Push(newremap);
|
||||
newremap->Index = index;
|
||||
return newremap;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void PaletteContainer::UpdateTranslation(int trans, FRemapTable* remap)
|
||||
{
|
||||
auto newremap = AddRemap(remap);
|
||||
TranslationTables[GetTranslationType(trans)].SetVal(GetTranslationIndex(trans), newremap);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
int PaletteContainer::AddTranslation(int slot, FRemapTable* remap, int count)
|
||||
{
|
||||
uint32_t id;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
auto newremap = AddRemap(&remap[i]);
|
||||
id = TranslationTables[slot].Push(newremap);
|
||||
}
|
||||
return TRANSLATION(slot, id);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void PaletteContainer::CopyTranslation(int dest, int src)
|
||||
{
|
||||
TranslationTables[GetTranslationType(dest)][GetTranslationType(src)] = TranslationToTable(src);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
FRemapTable *PaletteContainer::TranslationToTable(int translation)
|
||||
{
|
||||
unsigned int type = GetTranslationType(translation);
|
||||
unsigned int index = GetTranslationIndex(translation);
|
||||
|
||||
if (type <= 0 || type >= TranslationTables.Size() || index >= NumTranslations(type))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return GetTranslation(type, index);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Stores a copy of this translation but avoids duplicates
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
int PaletteContainer::StoreTranslation(int slot, FRemapTable *remap)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
auto size = NumTranslations(slot);
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (*remap == *palMgr.TranslationToTable(TRANSLATION(slot, i)))
|
||||
{
|
||||
// A duplicate of this translation already exists
|
||||
return TRANSLATION(slot, i);
|
||||
}
|
||||
}
|
||||
if (size >= 65535) // Translation IDs only have 16 bits for the index.
|
||||
{
|
||||
I_Error("Too many DECORATE translations");
|
||||
}
|
||||
return AddTranslation(slot, remap);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
static bool IndexOutOfRange(const int color)
|
||||
{
|
||||
const bool outOfRange = color < 0 || color > 255;
|
||||
|
||||
if (outOfRange)
|
||||
{
|
||||
Printf(TEXTCOLOR_ORANGE "Palette index %i is out of range [0..255]\n", color);
|
||||
}
|
||||
|
||||
return outOfRange;
|
||||
}
|
||||
|
||||
static bool IndexOutOfRange(const int start, const int end)
|
||||
{
|
||||
const bool outOfRange = IndexOutOfRange(start);
|
||||
return IndexOutOfRange(end) || outOfRange;
|
||||
}
|
||||
|
||||
static bool IndexOutOfRange(const int start1, const int end1, const int start2, const int end2)
|
||||
{
|
||||
const bool outOfRange = IndexOutOfRange(start1, end1);
|
||||
return IndexOutOfRange(start2, end2) || outOfRange;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
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];
|
||||
}
|
||||
for (i = 1; i < NumEntries; ++i)
|
||||
{
|
||||
Palette[i].a = 255;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool FRemapTable::IsIdentity() const
|
||||
{
|
||||
for (int j = 0; j < 256; ++j)
|
||||
{
|
||||
if (Remap[j] != j)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2)
|
||||
{
|
||||
if (IndexOutOfRange(start, end, pal1, pal2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
double palcol, palstep;
|
||||
|
||||
if (start > end)
|
||||
{
|
||||
std::swap (start, end);
|
||||
std::swap (pal1, pal2);
|
||||
}
|
||||
else if (start == end)
|
||||
{
|
||||
start = GPalette.Remap[start];
|
||||
pal1 = GPalette.Remap[pal1];
|
||||
Remap[start] = pal1;
|
||||
Palette[start] = GPalette.BaseColors[pal1];
|
||||
Palette[start].a = start == 0 ? 0 : 255;
|
||||
return true;
|
||||
}
|
||||
palcol = pal1;
|
||||
palstep = (pal2 - palcol) / (end - start);
|
||||
for (int i = start; i <= end; palcol += palstep, ++i)
|
||||
{
|
||||
int j = GPalette.Remap[i], k = GPalette.Remap[int(round(palcol))];
|
||||
Remap[j] = k;
|
||||
Palette[j] = GPalette.BaseColors[k];
|
||||
Palette[j].a = j == 0 ? 0 : 255;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool FRemapTable::AddColorRange(int start, int end, int _r1,int _g1, int _b1, int _r2, int _g2, int _b2)
|
||||
{
|
||||
if (IndexOutOfRange(start, end))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
double r1 = _r1;
|
||||
double g1 = _g1;
|
||||
double b1 = _b1;
|
||||
double r2 = _r2;
|
||||
double g2 = _g2;
|
||||
double b2 = _b2;
|
||||
double r, g, b;
|
||||
double rs, gs, bs;
|
||||
|
||||
if (start > end)
|
||||
{
|
||||
std::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)
|
||||
{
|
||||
start = GPalette.Remap[start];
|
||||
Palette[start] = PalEntry(start == 0 ? 0 : 255, int(r), int(g), int(b));
|
||||
Remap[start] = ColorMatcher.Pick(Palette[start]);
|
||||
}
|
||||
else
|
||||
{
|
||||
rs /= (end - start);
|
||||
gs /= (end - start);
|
||||
bs /= (end - start);
|
||||
for (int i = start; i <= end; ++i)
|
||||
{
|
||||
int j = GPalette.Remap[i];
|
||||
Palette[j] = PalEntry(j == 0 ? 0 : 255, int(r), int(g), int(b));
|
||||
Remap[j] = ColorMatcher.Pick(Palette[j]);
|
||||
r += rs;
|
||||
g += gs;
|
||||
b += bs;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool FRemapTable::AddDesaturation(int start, int end, double r1, double g1, double b1, double r2, double g2, double b2)
|
||||
{
|
||||
if (IndexOutOfRange(start, end))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
r1 = clamp(r1, 0.0, 2.0);
|
||||
g1 = clamp(g1, 0.0, 2.0);
|
||||
b1 = clamp(b1, 0.0, 2.0);
|
||||
r2 = clamp(r2, 0.0, 2.0);
|
||||
g2 = clamp(g2, 0.0, 2.0);
|
||||
b2 = clamp(b2, 0.0, 2.0);
|
||||
|
||||
if (start > end)
|
||||
{
|
||||
std::swap(start, end);
|
||||
std::swap(r1, r2);
|
||||
std::swap(g1, g2);
|
||||
std::swap(b1, b2);
|
||||
}
|
||||
|
||||
r2 -= r1;
|
||||
g2 -= g1;
|
||||
b2 -= b1;
|
||||
r1 *= 255;
|
||||
g1 *= 255;
|
||||
b1 *= 255;
|
||||
|
||||
for(int c = start; c <= end; c++)
|
||||
{
|
||||
double intensity = (GPalette.BaseColors[c].r * 77 +
|
||||
GPalette.BaseColors[c].g * 143 +
|
||||
GPalette.BaseColors[c].b * 37) / 256.0;
|
||||
|
||||
PalEntry pe = PalEntry( MIN(255, int(r1 + intensity*r2)),
|
||||
MIN(255, int(g1 + intensity*g2)),
|
||||
MIN(255, int(b1 + intensity*b2)));
|
||||
|
||||
int cc = GPalette.Remap[c];
|
||||
|
||||
Remap[cc] = ColorMatcher.Pick(pe);
|
||||
Palette[cc] = pe;
|
||||
Palette[cc].a = cc == 0 ? 0:255;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool FRemapTable::AddColourisation(int start, int end, int r, int g, int b)
|
||||
{
|
||||
if (IndexOutOfRange(start, end))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = start; i < end; ++i)
|
||||
{
|
||||
double br = GPalette.BaseColors[i].r;
|
||||
double bg = GPalette.BaseColors[i].g;
|
||||
double bb = GPalette.BaseColors[i].b;
|
||||
double grey = (br * 0.299 + bg * 0.587 + bb * 0.114) / 255.0f;
|
||||
if (grey > 1.0) grey = 1.0;
|
||||
br = r * grey;
|
||||
bg = g * grey;
|
||||
bb = b * grey;
|
||||
|
||||
int j = GPalette.Remap[i];
|
||||
Palette[j] = PalEntry(j == 0 ? 0 : 255, int(br), int(bg), int(bb));
|
||||
Remap[j] = ColorMatcher.Pick(Palette[j]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool FRemapTable::AddTint(int start, int end, int r, int g, int b, int amount)
|
||||
{
|
||||
if (IndexOutOfRange(start, end))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = start; i < end; ++i)
|
||||
{
|
||||
float br = GPalette.BaseColors[i].r;
|
||||
float bg = GPalette.BaseColors[i].g;
|
||||
float bb = GPalette.BaseColors[i].b;
|
||||
float a = amount * 0.01f;
|
||||
float ia = 1.0f - a;
|
||||
br = br * ia + r * a;
|
||||
bg = bg * ia + g * a;
|
||||
bb = bb * ia + b * a;
|
||||
|
||||
int j = GPalette.Remap[i];
|
||||
Palette[j] = PalEntry(j == 0 ? 0 : 255, int(br), int(bg), int(bb));
|
||||
Remap[j] = ColorMatcher.Pick(Palette[j]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool FRemapTable::AddToTranslation(const char *range)
|
||||
{
|
||||
int start,end;
|
||||
bool desaturated = false;
|
||||
FScanner sc;
|
||||
|
||||
sc.OpenMem("translation", range, int(strlen(range)));
|
||||
sc.SetCMode(true);
|
||||
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
start = sc.Number;
|
||||
sc.MustGetToken(':');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
end = sc.Number;
|
||||
sc.MustGetToken('=');
|
||||
if (start < 0 || start > 255 || end < 0 || end > 255)
|
||||
{
|
||||
sc.ScriptError("Palette index out of range");
|
||||
return false;
|
||||
}
|
||||
|
||||
sc.MustGetAnyToken();
|
||||
|
||||
if (sc.TokenType == '[')
|
||||
{
|
||||
// translation using RGB values
|
||||
int r1,g1,b1,r2,g2,b2;
|
||||
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
r1 = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
g1 = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
b1 = sc.Number;
|
||||
sc.MustGetToken(']');
|
||||
sc.MustGetToken(':');
|
||||
sc.MustGetToken('[');
|
||||
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
r2 = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
g2 = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
b2 = sc.Number;
|
||||
sc.MustGetToken(']');
|
||||
|
||||
return AddColorRange(start, end, r1, g1, b1, r2, g2, b2);
|
||||
}
|
||||
else if (sc.TokenType == '%')
|
||||
{
|
||||
// translation using RGB values
|
||||
double r1,g1,b1,r2,g2,b2;
|
||||
|
||||
sc.MustGetToken('[');
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
|
||||
r1 = sc.Float;
|
||||
sc.MustGetToken(',');
|
||||
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
|
||||
g1 = sc.Float;
|
||||
sc.MustGetToken(',');
|
||||
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
|
||||
b1 = sc.Float;
|
||||
sc.MustGetToken(']');
|
||||
sc.MustGetToken(':');
|
||||
sc.MustGetToken('[');
|
||||
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
|
||||
r2 = sc.Float;
|
||||
sc.MustGetToken(',');
|
||||
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
|
||||
g2 = sc.Float;
|
||||
sc.MustGetToken(',');
|
||||
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
|
||||
b2 = sc.Float;
|
||||
sc.MustGetToken(']');
|
||||
|
||||
return AddDesaturation(start, end, r1, g1, b1, r2, g2, b2);
|
||||
}
|
||||
else if (sc.TokenType == '#')
|
||||
{
|
||||
// Colourise translation
|
||||
int r, g, b;
|
||||
sc.MustGetToken('[');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
r = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
g = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
b = sc.Number;
|
||||
sc.MustGetToken(']');
|
||||
|
||||
return AddColourisation(start, end, r, g, b);
|
||||
}
|
||||
else if (sc.TokenType == '@')
|
||||
{
|
||||
// Tint translation
|
||||
int a, r, g, b;
|
||||
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
a = sc.Number;
|
||||
sc.MustGetToken('[');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
r = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
g = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
b = sc.Number;
|
||||
sc.MustGetToken(']');
|
||||
|
||||
return AddTint(start, end, r, g, b, a);
|
||||
}
|
||||
else
|
||||
{
|
||||
int pal1, pal2;
|
||||
|
||||
sc.TokenMustBe(TK_IntConst);
|
||||
pal1 = sc.Number;
|
||||
sc.MustGetToken(':');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
pal2 = sc.Number;
|
||||
return AddIndexRange(start, end, pal1, pal2);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adds raw colors to a given translation
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool FRemapTable::AddColors(int start, int count, const uint8_t*colors)
|
||||
{
|
||||
int end = start + count;
|
||||
if (IndexOutOfRange(start, end))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = start; i < end; ++i)
|
||||
{
|
||||
auto br = colors[0];
|
||||
auto bg = colors[1];
|
||||
auto bb = colors[2];
|
||||
colors += 3;
|
||||
|
||||
int j = GPalette.Remap[i];
|
||||
Palette[j] = PalEntry(j == 0 ? 0 : 255, br, bg, bb);
|
||||
Remap[j] = ColorMatcher.Pick(Palette[j]);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
106
src/common/engine/palettecontainer.h
Normal file
106
src/common/engine/palettecontainer.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "memarena.h"
|
||||
#include "palentry.h"
|
||||
|
||||
struct FRemapTable
|
||||
{
|
||||
FRemapTable(int count = 256) { NumEntries = count; }
|
||||
FRemapTable(const FRemapTable& o) = default;
|
||||
|
||||
bool operator==(const FRemapTable& o);
|
||||
void MakeIdentity();
|
||||
bool IsIdentity() const;
|
||||
bool AddIndexRange(int start, int end, int pal1, int pal2);
|
||||
bool AddColorRange(int start, int end, int r1, int g1, int b1, int r2, int g2, int b2);
|
||||
bool AddDesaturation(int start, int end, double r1, double g1, double b1, double r2, double g2, double b2);
|
||||
bool AddColourisation(int start, int end, int r, int g, int b);
|
||||
bool AddTint(int start, int end, int r, int g, int b, int amount);
|
||||
bool AddToTranslation(const char* range);
|
||||
bool AddColors(int start, int count, const uint8_t*);
|
||||
|
||||
uint8_t Remap[256]; // For the software renderer
|
||||
PalEntry Palette[256]; // The ideal palette this maps to
|
||||
int crc32;
|
||||
int Index;
|
||||
int NumEntries; // # of elements in this table (usually 256)
|
||||
bool Inactive = false; // This table is inactive and should be treated as if it was passed as NULL
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
// A class that initializes unusued pointers to NULL. This is used so that when
|
||||
// the TAutoGrowArray below is expanded, the new elements will be NULLed.
|
||||
class FRemapTablePtr
|
||||
{
|
||||
public:
|
||||
FRemapTablePtr() throw() : Ptr(0) {}
|
||||
FRemapTablePtr(FRemapTable* p) throw() : Ptr(p) {}
|
||||
FRemapTablePtr(const FRemapTablePtr& p) throw() : Ptr(p.Ptr) {}
|
||||
operator FRemapTable* () const throw() { return Ptr; }
|
||||
FRemapTablePtr& operator= (FRemapTable* p) throw() { Ptr = p; return *this; }
|
||||
FRemapTablePtr& operator= (FRemapTablePtr& p) throw() { Ptr = p.Ptr; return *this; }
|
||||
FRemapTable& operator*() const throw() { return *Ptr; }
|
||||
FRemapTable* operator->() const throw() { return Ptr; }
|
||||
private:
|
||||
FRemapTable* Ptr = nullptr;
|
||||
};
|
||||
|
||||
|
||||
#define TRANSLATION_SHIFT 16
|
||||
#define TRANSLATION_MASK ((1<<TRANSLATION_SHIFT)-1)
|
||||
#define TRANSLATIONTYPE_MASK (255<<TRANSLATION_SHIFT)
|
||||
|
||||
inline uint32_t TRANSLATION(uint8_t a, uint32_t b)
|
||||
{
|
||||
return (a << TRANSLATION_SHIFT) | b;
|
||||
}
|
||||
inline int GetTranslationType(uint32_t trans)
|
||||
{
|
||||
return (trans & TRANSLATIONTYPE_MASK) >> TRANSLATION_SHIFT;
|
||||
}
|
||||
inline int GetTranslationIndex(uint32_t trans)
|
||||
{
|
||||
return (trans & TRANSLATION_MASK);
|
||||
}
|
||||
|
||||
class PaletteContainer
|
||||
{
|
||||
FMemArena remapArena;
|
||||
TArray<FRemapTable*> uniqueRemaps;
|
||||
TArray<TAutoGrowArray<FRemapTablePtr, FRemapTable*>> TranslationTables;
|
||||
public:
|
||||
void Init(int numslots); // This cannot be a constructor!!!
|
||||
void Clear();
|
||||
FRemapTable* AddRemap(FRemapTable* remap);
|
||||
void UpdateTranslation(int trans, FRemapTable* remap);
|
||||
int AddTranslation(int slot, FRemapTable* remap, int count = 1);
|
||||
void CopyTranslation(int dest, int src);
|
||||
int StoreTranslation(int slot, FRemapTable* remap);
|
||||
FRemapTable* TranslationToTable(int translation);
|
||||
|
||||
void PushIdentityTable(int slot)
|
||||
{
|
||||
AddTranslation(slot, nullptr);
|
||||
}
|
||||
|
||||
FRemapTable* GetTranslation(int slot, int index)
|
||||
{
|
||||
return TranslationTables[slot].GetVal(index);
|
||||
}
|
||||
|
||||
void ClearTranslationSlot(int slot)
|
||||
{
|
||||
TranslationTables[slot].Clear();
|
||||
}
|
||||
|
||||
unsigned NumTranslations(int slot) const
|
||||
{
|
||||
return TranslationTables[slot].Size();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern PaletteContainer palMgr;
|
||||
|
||||
83
src/common/engine/printf.h
Normal file
83
src/common/engine/printf.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
|
||||
#if defined __GNUC__ || defined __clang__
|
||||
# define ATTRIBUTE(attrlist) __attribute__(attrlist)
|
||||
#else
|
||||
# define ATTRIBUTE(attrlist)
|
||||
#endif
|
||||
|
||||
// This header collects all things printf, so that this doesn't need to pull in other, far more dirty headers, just for outputting some text.
|
||||
|
||||
extern "C" int mysnprintf(char* buffer, size_t count, const char* format, ...) ATTRIBUTE((format(printf, 3, 4)));
|
||||
extern "C" int myvsnprintf(char* buffer, size_t count, const char* format, va_list argptr) ATTRIBUTE((format(printf, 3, 0)));
|
||||
|
||||
#define TEXTCOLOR_BRICK "\034A"
|
||||
#define TEXTCOLOR_TAN "\034B"
|
||||
#define TEXTCOLOR_GRAY "\034C"
|
||||
#define TEXTCOLOR_GREY "\034C"
|
||||
#define TEXTCOLOR_GREEN "\034D"
|
||||
#define TEXTCOLOR_BROWN "\034E"
|
||||
#define TEXTCOLOR_GOLD "\034F"
|
||||
#define TEXTCOLOR_RED "\034G"
|
||||
#define TEXTCOLOR_BLUE "\034H"
|
||||
#define TEXTCOLOR_ORANGE "\034I"
|
||||
#define TEXTCOLOR_WHITE "\034J"
|
||||
#define TEXTCOLOR_YELLOW "\034K"
|
||||
#define TEXTCOLOR_UNTRANSLATED "\034L"
|
||||
#define TEXTCOLOR_BLACK "\034M"
|
||||
#define TEXTCOLOR_LIGHTBLUE "\034N"
|
||||
#define TEXTCOLOR_CREAM "\034O"
|
||||
#define TEXTCOLOR_OLIVE "\034P"
|
||||
#define TEXTCOLOR_DARKGREEN "\034Q"
|
||||
#define TEXTCOLOR_DARKRED "\034R"
|
||||
#define TEXTCOLOR_DARKBROWN "\034S"
|
||||
#define TEXTCOLOR_PURPLE "\034T"
|
||||
#define TEXTCOLOR_DARKGRAY "\034U"
|
||||
#define TEXTCOLOR_CYAN "\034V"
|
||||
#define TEXTCOLOR_ICE "\034W"
|
||||
#define TEXTCOLOR_FIRE "\034X"
|
||||
#define TEXTCOLOR_SAPPHIRE "\034Y"
|
||||
#define TEXTCOLOR_TEAL "\034Z"
|
||||
|
||||
// game print flags
|
||||
enum
|
||||
{
|
||||
PRINT_LOW, // pickup messages
|
||||
PRINT_MEDIUM, // death messages
|
||||
PRINT_HIGH, // critical messages
|
||||
PRINT_CHAT, // chat messages
|
||||
PRINT_TEAMCHAT, // chat messages from a teammate
|
||||
PRINT_LOG, // only to logfile
|
||||
PRINT_BOLD = 200, // What Printf_Bold used
|
||||
PRINT_TYPES = 1023, // Bitmask.
|
||||
PRINT_NONOTIFY = 1024, // Flag - do not add to notify buffer
|
||||
PRINT_NOLOG = 2048, // Flag - do not print to log file
|
||||
PRINT_NOTIFY = 4096, // Flag - add to notify buffer
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DMSG_OFF, // no developer messages.
|
||||
DMSG_ERROR, // general notification messages
|
||||
DMSG_WARNING, // warnings
|
||||
DMSG_NOTIFY, // general notification messages
|
||||
DMSG_SPAMMY, // for those who want to see everything, regardless of its usefulness.
|
||||
};
|
||||
|
||||
|
||||
void I_Error(const char *fmt, ...) ATTRIBUTE((format(printf,1,2)));
|
||||
void I_FatalError(const char* fmt, ...) ATTRIBUTE((format(printf, 1, 2)));
|
||||
|
||||
// This really could need some cleanup - the main problem is that it'd create
|
||||
// lots of potential for merge conflicts.
|
||||
|
||||
int PrintString (int iprintlevel, const char *outline);
|
||||
int VPrintf(int printlevel, const char* format, va_list parms);
|
||||
int Printf (int printlevel, const char *format, ...) ATTRIBUTE((format(printf,2,3)));
|
||||
int Printf (const char *format, ...) ATTRIBUTE((format(printf,1,2)));
|
||||
int DPrintf (int level, const char *format, ...) ATTRIBUTE((format(printf,2,3)));
|
||||
|
||||
void debugprintf(const char* f, ...); // Prints to the debugger's log.
|
||||
|
||||
// flag to silence non-error output
|
||||
extern bool batchrun;
|
||||
1268
src/common/engine/sc_man.cpp
Normal file
1268
src/common/engine/sc_man.cpp
Normal file
File diff suppressed because it is too large
Load diff
227
src/common/engine/sc_man.h
Normal file
227
src/common/engine/sc_man.h
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
#ifndef __SC_MAN_H__
|
||||
#define __SC_MAN_H__
|
||||
|
||||
#include "zstring.h"
|
||||
#include "name.h"
|
||||
#include "basics.h"
|
||||
|
||||
struct VersionInfo
|
||||
{
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
uint32_t revision;
|
||||
|
||||
bool operator <=(const VersionInfo& o) const
|
||||
{
|
||||
return o.major > this->major || (o.major == this->major && o.minor > this->minor) || (o.major == this->major && o.minor == this->minor && o.revision >= this->revision);
|
||||
}
|
||||
bool operator >=(const VersionInfo& o) const
|
||||
{
|
||||
return o.major < this->major || (o.major == this->major && o.minor < this->minor) || (o.major == this->major && o.minor == this->minor && o.revision <= this->revision);
|
||||
}
|
||||
bool operator > (const VersionInfo& o) const
|
||||
{
|
||||
return o.major < this->major || (o.major == this->major && o.minor < this->minor) || (o.major == this->major && o.minor == this->minor && o.revision < this->revision);
|
||||
}
|
||||
bool operator < (const VersionInfo& o) const
|
||||
{
|
||||
return o.major > this->major || (o.major == this->major && o.minor > this->minor) || (o.major == this->major && o.minor == this->minor && o.revision > this->revision);
|
||||
}
|
||||
void operator=(const char* string);
|
||||
};
|
||||
|
||||
// Cannot be a constructor because Lemon would puke on it.
|
||||
inline VersionInfo MakeVersion(unsigned int ma, unsigned int mi, unsigned int re = 0)
|
||||
{
|
||||
return{ (uint16_t)ma, (uint16_t)mi, (uint32_t)re };
|
||||
}
|
||||
|
||||
|
||||
class FScanner
|
||||
{
|
||||
public:
|
||||
struct SavedPos
|
||||
{
|
||||
const char *SavedScriptPtr;
|
||||
int SavedScriptLine;
|
||||
};
|
||||
|
||||
// Methods ------------------------------------------------------
|
||||
FScanner();
|
||||
FScanner(const FScanner &other);
|
||||
FScanner(int lumpnum);
|
||||
~FScanner();
|
||||
|
||||
FScanner &operator=(const FScanner &other);
|
||||
|
||||
void Open(const char *lumpname);
|
||||
bool OpenFile(const char *filename);
|
||||
void OpenMem(const char *name, const char *buffer, int size);
|
||||
void OpenMem(const char *name, const TArray<uint8_t> &buffer)
|
||||
{
|
||||
OpenMem(name, (const char*)buffer.Data(), buffer.Size());
|
||||
}
|
||||
void OpenString(const char *name, FString buffer);
|
||||
void OpenLumpNum(int lump);
|
||||
void Close();
|
||||
void SetParseVersion(VersionInfo ver)
|
||||
{
|
||||
ParseVersion = ver;
|
||||
}
|
||||
|
||||
void SetCMode(bool cmode);
|
||||
void SetEscape(bool esc);
|
||||
void SetStateMode(bool stately);
|
||||
void DisableStateOptions();
|
||||
const SavedPos SavePos();
|
||||
void RestorePos(const SavedPos &pos);
|
||||
|
||||
static FString TokenName(int token, const char *string=NULL);
|
||||
|
||||
bool GetString();
|
||||
void MustGetString();
|
||||
void MustGetStringName(const char *name);
|
||||
bool CheckString(const char *name);
|
||||
|
||||
bool GetToken();
|
||||
void MustGetAnyToken();
|
||||
void TokenMustBe(int token);
|
||||
void MustGetToken(int token);
|
||||
bool CheckToken(int token);
|
||||
bool CheckTokenId(ENamedName id);
|
||||
|
||||
bool GetNumber();
|
||||
void MustGetNumber();
|
||||
bool CheckNumber();
|
||||
|
||||
bool GetFloat();
|
||||
void MustGetFloat();
|
||||
bool CheckFloat();
|
||||
|
||||
// Token based variant
|
||||
bool CheckValue(bool allowfloat);
|
||||
void MustGetValue(bool allowfloat);
|
||||
bool CheckBoolToken();
|
||||
void MustGetBoolToken();
|
||||
|
||||
void UnGet();
|
||||
|
||||
bool Compare(const char *text);
|
||||
int MatchString(const char * const *strings, size_t stride = sizeof(char*));
|
||||
int MustMatchString(const char * const *strings, size_t stride = sizeof(char*));
|
||||
int GetMessageLine();
|
||||
|
||||
void ScriptError(const char *message, ...) GCCPRINTF(2,3);
|
||||
void ScriptMessage(const char *message, ...) GCCPRINTF(2,3);
|
||||
|
||||
bool isText();
|
||||
|
||||
// Members ------------------------------------------------------
|
||||
char *String;
|
||||
int StringLen;
|
||||
int TokenType;
|
||||
int Number;
|
||||
int64_t BigNumber;
|
||||
double Float;
|
||||
int Line;
|
||||
bool End;
|
||||
bool Crossed;
|
||||
int LumpNum;
|
||||
FString ScriptName;
|
||||
|
||||
protected:
|
||||
void PrepareScript();
|
||||
void CheckOpen();
|
||||
bool ScanString(bool tokens);
|
||||
|
||||
// Strings longer than this minus one will be dynamically allocated.
|
||||
static const int MAX_STRING_SIZE = 128;
|
||||
|
||||
bool ScriptOpen;
|
||||
FString ScriptBuffer;
|
||||
const char *ScriptPtr;
|
||||
const char *ScriptEndPtr;
|
||||
char StringBuffer[MAX_STRING_SIZE];
|
||||
FString BigStringBuffer;
|
||||
bool AlreadyGot;
|
||||
int AlreadyGotLine;
|
||||
bool LastGotToken;
|
||||
const char *LastGotPtr;
|
||||
int LastGotLine;
|
||||
bool CMode;
|
||||
uint8_t StateMode;
|
||||
bool StateOptions;
|
||||
bool Escape;
|
||||
VersionInfo ParseVersion = { 0, 0, 0 }; // no ZScript extensions by default
|
||||
|
||||
|
||||
bool ScanValue(bool allowfloat);
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TK_SequenceStart = 256,
|
||||
#define xx(sym,str) sym,
|
||||
#include "sc_man_tokens.h"
|
||||
TK_LastToken
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
enum
|
||||
{
|
||||
MSG_WARNING,
|
||||
MSG_FATAL,
|
||||
MSG_ERROR,
|
||||
MSG_OPTERROR,
|
||||
MSG_DEBUGERROR,
|
||||
MSG_DEBUGWARN,
|
||||
MSG_DEBUGMSG,
|
||||
MSG_LOG,
|
||||
MSG_DEBUGLOG,
|
||||
MSG_MESSAGE
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// a class that remembers a parser position
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
struct FScriptPosition
|
||||
{
|
||||
static int WarnCounter;
|
||||
static int ErrorCounter;
|
||||
static bool StrictErrors;
|
||||
static int Developer;
|
||||
static bool errorout;
|
||||
FName FileName;
|
||||
int ScriptLine;
|
||||
|
||||
FScriptPosition()
|
||||
{
|
||||
FileName = NAME_None;
|
||||
ScriptLine=0;
|
||||
}
|
||||
FScriptPosition(const FScriptPosition &other) = default;
|
||||
FScriptPosition(FString fname, int line);
|
||||
FScriptPosition(FScanner &sc);
|
||||
FScriptPosition &operator=(const FScriptPosition &other) = default;
|
||||
FScriptPosition &operator=(FScanner &sc);
|
||||
void Message(int severity, const char *message,...) const GCCPRINTF(3,4);
|
||||
static void ResetErrorCounter()
|
||||
{
|
||||
WarnCounter = 0;
|
||||
ErrorCounter = 0;
|
||||
}
|
||||
};
|
||||
|
||||
int ParseHex(const char* hex, FScriptPosition* sc);
|
||||
|
||||
|
||||
#endif //__SC_MAN_H__
|
||||
535
src/common/engine/sc_man_scanner.re
Normal file
535
src/common/engine/sc_man_scanner.re
Normal file
|
|
@ -0,0 +1,535 @@
|
|||
/*
|
||||
**
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2005-2016 Randy Heit
|
||||
** Copyright 2005-2016 Christoph Oelckers
|
||||
** 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.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#define YYCTYPE unsigned char
|
||||
#define YYCURSOR cursor
|
||||
#define YYLIMIT limit
|
||||
#define YYMARKER marker
|
||||
#define YYFILL(n) {}
|
||||
#if 0 // As long as the buffer ends with '\n', we need do nothing special for YYFILL.
|
||||
// This buffer must be as large as the largest YYFILL call
|
||||
YYCTYPE eofbuf[9];
|
||||
#define YYFILL(n) \
|
||||
{ if(!sc_End) { \
|
||||
if(n == 2) { eofbuf[0] = *cursor; } \
|
||||
else if(n >= 3 && n <= 9) { memcpy(eofbuf, cursor, n-1); } \
|
||||
eofbuf[n-1] = '\n'; \
|
||||
cursor = eofbuf; \
|
||||
limit = eofbuf + n - 1; \
|
||||
sc_End = true; } \
|
||||
} \
|
||||
assert(n <= sizeof eofbuf) // Semicolon intentionally omitted
|
||||
#endif
|
||||
|
||||
//#define YYDEBUG(s,c) { Printf ("%d: %02x\n", s, c); }
|
||||
#define YYDEBUG(s,c)
|
||||
|
||||
const char *cursor = ScriptPtr;
|
||||
const char *limit = ScriptEndPtr;
|
||||
|
||||
std1:
|
||||
tok = YYCURSOR;
|
||||
std2:
|
||||
/*!re2c
|
||||
any = [\000-\377];
|
||||
WSP = ([\000- ]\[\n]);
|
||||
NWS = (any\[\000- ]);
|
||||
O = [0-7];
|
||||
D = [0-9];
|
||||
L = [a-zA-Z_];
|
||||
H = [a-fA-F0-9];
|
||||
E = [Ee] [+-]? D+;
|
||||
FS = [fF];
|
||||
IS = [uUlL];
|
||||
ESC = [\\] ([abcfnrtv?'"\\] | "x" H+ | O+);
|
||||
|
||||
TOK1 = [{}|=];
|
||||
TOKC = [{}|=/`~!@#$%^&*()\[\]\\?\-=+;:<>,.];
|
||||
|
||||
STOP1 = (TOK1|["/;]);
|
||||
STOPC = (TOKC|["]);
|
||||
|
||||
TOK2 = (NWS\STOP1);
|
||||
TOKC2 = (NWS\STOPC);
|
||||
*/
|
||||
#define RET(x) TokenType = (x); goto normal_token;
|
||||
if (tokens && StateMode != 0)
|
||||
{
|
||||
/*!re2c
|
||||
"/*" { goto comment; } /* C comment */
|
||||
"//" (any\"\n")* "\n" { goto newline; } /* C++ comment */
|
||||
("#region"|"#endregion") (any\"\n")* "\n"
|
||||
{ goto newline; } /* Region blocks [mxd] */
|
||||
|
||||
(["](([\\]["])|[^"])*["]) { goto string_const; }
|
||||
'stop' { RET(TK_Stop); }
|
||||
'wait' { RET(TK_Wait); }
|
||||
'fail' { RET(TK_Fail); }
|
||||
'loop' { RET(TK_Loop); }
|
||||
'goto' { StateMode = 0; StateOptions = false; RET(TK_Goto); }
|
||||
":" { RET(':'); }
|
||||
";" { RET(';'); }
|
||||
"}" { StateMode = 0; StateOptions = false; RET('}'); }
|
||||
|
||||
WSP+ { goto std1; }
|
||||
"\n" { goto newline; }
|
||||
|
||||
TOKS = (NWS\[/":;}]);
|
||||
TOKS* ([/] (TOKS\[*]) TOKS*)*
|
||||
{ RET(TK_NonWhitespace); }
|
||||
|
||||
*/
|
||||
}
|
||||
else if (tokens) // A well-defined scanner, based on the c.re example.
|
||||
{
|
||||
/*!re2c
|
||||
"/*" { goto comment; } /* C comment */
|
||||
"//" (any\"\n")* "\n" { goto newline; } /* C++ comment */
|
||||
("#region"|"#endregion") (any\"\n")* "\n"
|
||||
{ goto newline; } /* Region blocks [mxd] */
|
||||
|
||||
/* C Keywords */
|
||||
'break' { RET(TK_Break); }
|
||||
'case' { RET(TK_Case); }
|
||||
'const' { RET(TK_Const); }
|
||||
'continue' { RET(TK_Continue); }
|
||||
'default' { RET(TK_Default); }
|
||||
'do' { RET(TK_Do); }
|
||||
'else' { RET(TK_Else); }
|
||||
'for' { RET(TK_For); }
|
||||
'goto' { RET(TK_Goto); }
|
||||
'if' { RET(TK_If); }
|
||||
'return' { RET(TK_Return); }
|
||||
'switch' { RET(TK_Switch); }
|
||||
'until' { RET(TK_Until); }
|
||||
'volatile' { RET(TK_Volatile); }
|
||||
'while' { RET(TK_While); }
|
||||
|
||||
/* Type names */
|
||||
'bool' { RET(TK_Bool); }
|
||||
'float' { RET(TK_Float); }
|
||||
'double' { RET(TK_Double); }
|
||||
'char' { RET(TK_Char); }
|
||||
'byte' { RET(TK_Byte); }
|
||||
'sbyte' { RET(TK_SByte); }
|
||||
'short' { RET(TK_Short); }
|
||||
'ushort' { RET(TK_UShort); }
|
||||
'int8' { RET(TK_Int8); }
|
||||
'uint8' { RET(TK_UInt8); }
|
||||
'int16' { RET(TK_Int16); }
|
||||
'uint16' { RET(TK_UInt16); }
|
||||
'int' { RET(TK_Int); }
|
||||
'uint' { RET(TK_UInt); }
|
||||
'long' { RET(TK_Long); }
|
||||
'ulong' { RET(TK_ULong); }
|
||||
'void' { RET(TK_Void); }
|
||||
'struct' { RET(TK_Struct); }
|
||||
'class' { RET(TK_Class); }
|
||||
'mixin' { RET(TK_Mixin); }
|
||||
'enum' { RET(TK_Enum); }
|
||||
'name' { RET(TK_Name); }
|
||||
'string' { RET(TK_String); }
|
||||
'sound' { RET(TK_Sound); }
|
||||
'state' { RET(TK_State); }
|
||||
'color' { RET(TK_Color); }
|
||||
'vector2' { RET(TK_Vector2); }
|
||||
'vector3' { RET(TK_Vector3); }
|
||||
'map' { RET(TK_Map); }
|
||||
'array' { RET(TK_Array); }
|
||||
'in' { RET(TK_In); }
|
||||
'sizeof' { RET(TK_SizeOf); }
|
||||
'alignof' { RET(TK_AlignOf); }
|
||||
|
||||
/* Other keywords from UnrealScript */
|
||||
'abstract' { RET(TK_Abstract); }
|
||||
'foreach' { RET(TK_ForEach); }
|
||||
'true' { RET(TK_True); }
|
||||
'false' { RET(TK_False); }
|
||||
'none' { RET(TK_None); }
|
||||
'auto' { RET(TK_Auto); }
|
||||
'property' { RET(TK_Property); }
|
||||
'flagdef' { RET(ParseVersion >= MakeVersion(3, 7, 0)? TK_FlagDef : TK_Identifier); }
|
||||
'native' { RET(TK_Native); }
|
||||
'var' { RET(TK_Var); }
|
||||
'out' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Out : TK_Identifier); }
|
||||
'static' { RET(TK_Static); }
|
||||
'transient' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Transient : TK_Identifier); }
|
||||
'final' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Final : TK_Identifier); }
|
||||
'extend' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Extend : TK_Identifier); }
|
||||
'protected' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Protected : TK_Identifier); }
|
||||
'private' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Private : TK_Identifier); }
|
||||
'dot' { RET(TK_Dot); }
|
||||
'cross' { RET(TK_Cross); }
|
||||
'virtual' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Virtual : TK_Identifier); }
|
||||
'override' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Override : TK_Identifier); }
|
||||
'vararg' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_VarArg : TK_Identifier); }
|
||||
'ui' { RET(ParseVersion >= MakeVersion(2, 4, 0)? TK_UI : TK_Identifier); }
|
||||
'play' { RET(ParseVersion >= MakeVersion(2, 4, 0)? TK_Play : TK_Identifier); }
|
||||
'clearscope' { RET(ParseVersion >= MakeVersion(2, 4, 0)? TK_ClearScope : TK_Identifier); }
|
||||
'virtualscope' { RET(ParseVersion >= MakeVersion(2, 4, 0)? TK_VirtualScope : TK_Identifier); }
|
||||
'super' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Super : TK_Identifier); }
|
||||
'stop' { RET(TK_Stop); }
|
||||
'null' { RET(TK_Null); }
|
||||
|
||||
'is' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Is : TK_Identifier); }
|
||||
'replaces' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Replaces : TK_Identifier); }
|
||||
'states' { RET(TK_States); }
|
||||
'meta' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Meta : TK_Identifier); }
|
||||
'deprecated' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Deprecated : TK_Identifier); }
|
||||
'version' { RET(ParseVersion >= MakeVersion(2, 4, 0)? TK_Version : TK_Identifier); }
|
||||
'action' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Action : TK_Identifier); }
|
||||
'readonly' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_ReadOnly : TK_Identifier); }
|
||||
'internal' { RET(ParseVersion >= MakeVersion(3, 4, 0)? TK_Internal : TK_Identifier); }
|
||||
'let' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Let : TK_Identifier); }
|
||||
|
||||
/* Actor state options */
|
||||
'bright' { RET(StateOptions ? TK_Bright : TK_Identifier); }
|
||||
'fast' { RET(StateOptions ? TK_Fast : TK_Identifier); }
|
||||
'slow' { RET(StateOptions ? TK_Slow : TK_Identifier); }
|
||||
'nodelay' { RET(StateOptions ? TK_NoDelay : TK_Identifier); }
|
||||
'canraise' { RET(StateOptions ? TK_CanRaise : TK_Identifier); }
|
||||
'offset' { RET(StateOptions ? TK_Offset : TK_Identifier); }
|
||||
'light' { RET(StateOptions ? TK_Light : TK_Identifier); }
|
||||
|
||||
/* other DECORATE top level keywords */
|
||||
'#include' { RET(TK_Include); }
|
||||
|
||||
L (L|D)* { RET(TK_Identifier); }
|
||||
|
||||
("0" [xX] H+ IS?IS?) | ("0" D+ IS?IS?) | (D+ IS?IS?)
|
||||
{ RET(TK_IntConst); }
|
||||
|
||||
(D+ E FS?) | (D* "." D+ E? FS?) | (D+ "." D* E? FS?)
|
||||
{ RET(TK_FloatConst); }
|
||||
|
||||
(["](([\\]["])|[^"])*["])
|
||||
{ goto string_const; }
|
||||
|
||||
(['] (any\[\n'])* ['])
|
||||
{ RET(TK_NameConst); }
|
||||
|
||||
".." { RET(TK_DotDot); }
|
||||
"..." { RET(TK_Ellipsis); }
|
||||
">>>=" { RET(TK_URShiftEq); }
|
||||
">>=" { RET(TK_RShiftEq); }
|
||||
"<<=" { RET(TK_LShiftEq); }
|
||||
"+=" { RET(TK_AddEq); }
|
||||
"-=" { RET(TK_SubEq); }
|
||||
"*=" { RET(TK_MulEq); }
|
||||
"/=" { RET(TK_DivEq); }
|
||||
"%=" { RET(TK_ModEq); }
|
||||
"&=" { RET(TK_AndEq); }
|
||||
"^=" { RET(TK_XorEq); }
|
||||
"|=" { RET(TK_OrEq); }
|
||||
">>>" { RET(TK_URShift); }
|
||||
">>" { RET(TK_RShift); }
|
||||
"<<" { RET(TK_LShift); }
|
||||
"++" { RET(TK_Incr); }
|
||||
"--" { RET(TK_Decr); }
|
||||
"&&" { RET(TK_AndAnd); }
|
||||
"||" { RET(TK_OrOr); }
|
||||
"<=" { RET(TK_Leq); }
|
||||
">=" { RET(TK_Geq); }
|
||||
"==" { RET(TK_Eq); }
|
||||
"!=" { RET(TK_Neq); }
|
||||
"~==" { RET(TK_ApproxEq); }
|
||||
"<>=" { RET(TK_LtGtEq); }
|
||||
"**" { RET(TK_MulMul); }
|
||||
"::" { RET(TK_ColonColon); }
|
||||
"->" { RET(TK_Arrow); }
|
||||
";" { StateOptions = false; RET(';'); }
|
||||
"{" { StateOptions = false; RET('{'); }
|
||||
"}" { RET('}'); }
|
||||
"," { RET(','); }
|
||||
":" { RET(':'); }
|
||||
"=" { RET('='); }
|
||||
"(" { RET('('); }
|
||||
")" { RET(')'); }
|
||||
"[" { RET('['); }
|
||||
"]" { RET(']'); }
|
||||
"." { RET('.'); }
|
||||
"&" { RET('&'); }
|
||||
"!" { RET('!'); }
|
||||
"~" { RET('~'); }
|
||||
"-" { RET('-'); }
|
||||
"+" { RET('+'); }
|
||||
"*" { RET('*'); }
|
||||
"/" { RET('/'); }
|
||||
"%" { RET('%'); }
|
||||
"<" { RET('<'); }
|
||||
">" { RET('>'); }
|
||||
"^" { RET('^'); }
|
||||
"|" { RET('|'); }
|
||||
"?" { RET('?'); }
|
||||
"#" { RET('#'); }
|
||||
"@" { RET('@'); }
|
||||
|
||||
[ \t\v\f\r]+ { goto std1; }
|
||||
"\n" { goto newline; }
|
||||
any
|
||||
{
|
||||
ScriptError ("Unexpected character: %c (ASCII %d)\n", *tok, *tok);
|
||||
goto std1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
if (!CMode) // The classic Hexen scanner.
|
||||
{
|
||||
/*!re2c
|
||||
"/*" { goto comment; } /* C comment */
|
||||
("//"|";") (any\"\n")* "\n" { goto newline; } /* C++/Hexen comment */
|
||||
("#region"|"#endregion") (any\"\n")* "\n"
|
||||
{ goto newline; } /* Region blocks [mxd] */
|
||||
|
||||
WSP+ { goto std1; } /* whitespace */
|
||||
"\n" { goto newline; }
|
||||
"\"" { goto string; }
|
||||
|
||||
TOK1 { goto normal_token; }
|
||||
|
||||
/* Regular tokens may contain /, but they must not contain comment starts */
|
||||
TOK2* ([/] (TOK2\[*]) TOK2*)* { goto normal_token; }
|
||||
|
||||
any { goto normal_token; } /* unknown character */
|
||||
*/
|
||||
}
|
||||
else // A modified Hexen scanner for DECORATE.
|
||||
{
|
||||
/*!re2c
|
||||
"/*" { goto comment; } /* C comment */
|
||||
"//" (any\"\n")* "\n" { goto newline; } /* C++ comment */
|
||||
("#region"|"#endregion") (any\"\n")* "\n"
|
||||
{ goto newline; } /* Region blocks [mxd] */
|
||||
|
||||
WSP+ { goto std1; } /* whitespace */
|
||||
"\n" { goto newline; }
|
||||
"\"" { goto string; }
|
||||
|
||||
[-] { goto negative_check; }
|
||||
((D* [.] D+) | (D+ [.] D*)) { goto normal_token; } /* decimal number */
|
||||
(D+ E FS?) | (D* "." D+ E? FS?) | (D+ "." D* E? FS?) { goto normal_token; } /* float with exponent */
|
||||
"::" { goto normal_token; }
|
||||
"&&" { goto normal_token; }
|
||||
"==" { goto normal_token; }
|
||||
"||" { goto normal_token; }
|
||||
"<<" { goto normal_token; }
|
||||
">>" { goto normal_token; }
|
||||
TOKC { goto normal_token; }
|
||||
TOKC2+ { goto normal_token; }
|
||||
|
||||
any { goto normal_token; } /* unknown character */
|
||||
*/
|
||||
}
|
||||
|
||||
negative_check:
|
||||
// re2c doesn't have enough state to handle '-' as the start of a negative number
|
||||
// and as its own token, so help it out a little.
|
||||
TokenType = '-';
|
||||
if (YYCURSOR >= YYLIMIT)
|
||||
{
|
||||
goto normal_token;
|
||||
}
|
||||
if (*YYCURSOR >= '0' && *YYCURSOR <= '9')
|
||||
{
|
||||
goto std2;
|
||||
}
|
||||
if (*YYCURSOR != '.' || YYCURSOR+1 >= YYLIMIT)
|
||||
{
|
||||
goto normal_token;
|
||||
}
|
||||
if (*(YYCURSOR+1) >= '0' && *YYCURSOR <= '9')
|
||||
{
|
||||
goto std2;
|
||||
}
|
||||
goto normal_token;
|
||||
|
||||
comment:
|
||||
/*!re2c
|
||||
"*/"
|
||||
{
|
||||
if (YYCURSOR >= YYLIMIT)
|
||||
{
|
||||
ScriptPtr = ScriptEndPtr;
|
||||
return_val = false;
|
||||
goto end;
|
||||
}
|
||||
goto std1;
|
||||
}
|
||||
"\n"
|
||||
{
|
||||
if (YYCURSOR >= YYLIMIT)
|
||||
{
|
||||
ScriptPtr = ScriptEndPtr;
|
||||
return_val = false;
|
||||
goto end;
|
||||
}
|
||||
Line++;
|
||||
Crossed = true;
|
||||
goto comment;
|
||||
}
|
||||
any { goto comment; }
|
||||
*/
|
||||
|
||||
newline:
|
||||
if (YYCURSOR >= YYLIMIT)
|
||||
{
|
||||
ScriptPtr = ScriptEndPtr;
|
||||
return_val = false;
|
||||
goto end;
|
||||
}
|
||||
Line++;
|
||||
Crossed = true;
|
||||
goto std1;
|
||||
|
||||
normal_token:
|
||||
ScriptPtr = (YYCURSOR >= YYLIMIT) ? ScriptEndPtr : cursor;
|
||||
StringLen = int(ScriptPtr - tok);
|
||||
if (tokens && (TokenType == TK_StringConst || TokenType == TK_NameConst))
|
||||
{
|
||||
StringLen -= 2;
|
||||
if (StringLen >= MAX_STRING_SIZE)
|
||||
{
|
||||
BigStringBuffer = FString(tok+1, StringLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (StringBuffer, tok+1, StringLen);
|
||||
}
|
||||
if (StateMode && TokenType == TK_StringConst)
|
||||
{
|
||||
TokenType = TK_NonWhitespace;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (StringLen >= MAX_STRING_SIZE)
|
||||
{
|
||||
BigStringBuffer = FString(tok, StringLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (StringBuffer, tok, StringLen);
|
||||
}
|
||||
}
|
||||
if (tokens && StateMode)
|
||||
{ // State mode is exited after two consecutive TK_NonWhitespace tokens
|
||||
if (TokenType == TK_NonWhitespace)
|
||||
{
|
||||
StateMode--;
|
||||
}
|
||||
else
|
||||
{
|
||||
StateMode = 2;
|
||||
}
|
||||
}
|
||||
if (StringLen < MAX_STRING_SIZE)
|
||||
{
|
||||
String = StringBuffer;
|
||||
StringBuffer[StringLen] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
String = BigStringBuffer.LockBuffer();
|
||||
}
|
||||
return_val = true;
|
||||
goto end;
|
||||
|
||||
string_const:
|
||||
for (const char *c = tok; c < YYCURSOR; ++c)
|
||||
{
|
||||
if (*c == '\n') ++Line;
|
||||
}
|
||||
RET(TK_StringConst);
|
||||
|
||||
string:
|
||||
if (YYLIMIT != ScriptEndPtr)
|
||||
{
|
||||
ScriptPtr = ScriptEndPtr;
|
||||
return_val = false;
|
||||
goto end;
|
||||
}
|
||||
ScriptPtr = cursor;
|
||||
BigStringBuffer = "";
|
||||
for (StringLen = 0; cursor < YYLIMIT; ++cursor)
|
||||
{
|
||||
if (Escape && *cursor == '\\' && *(cursor + 1) == '"')
|
||||
{
|
||||
cursor++;
|
||||
}
|
||||
else if (*cursor == '\r' && *(cursor + 1) == '\n')
|
||||
{
|
||||
cursor++; // convert CR-LF to simply LF
|
||||
}
|
||||
else if (*cursor == '"')
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (*cursor == '\n')
|
||||
{
|
||||
if (CMode)
|
||||
{
|
||||
if (!Escape || StringLen == 0 || String[StringLen - 1] != '\\')
|
||||
{
|
||||
ScriptError ("Unterminated string constant");
|
||||
}
|
||||
else
|
||||
{
|
||||
StringLen--; // overwrite the \ character with \n
|
||||
}
|
||||
}
|
||||
Line++;
|
||||
Crossed = true;
|
||||
}
|
||||
if (StringLen == MAX_STRING_SIZE)
|
||||
{
|
||||
BigStringBuffer.AppendCStrPart(StringBuffer, StringLen);
|
||||
StringLen = 0;
|
||||
}
|
||||
StringBuffer[StringLen++] = *cursor;
|
||||
}
|
||||
if (BigStringBuffer.IsNotEmpty() || StringLen == MAX_STRING_SIZE)
|
||||
{
|
||||
BigStringBuffer.AppendCStrPart(StringBuffer, StringLen);
|
||||
String = BigStringBuffer.LockBuffer();
|
||||
StringLen = int(BigStringBuffer.Len());
|
||||
}
|
||||
else
|
||||
{
|
||||
String = StringBuffer;
|
||||
StringBuffer[StringLen] = '\0';
|
||||
}
|
||||
ScriptPtr = cursor + 1;
|
||||
return_val = true;
|
||||
end:
|
||||
154
src/common/engine/sc_man_tokens.h
Normal file
154
src/common/engine/sc_man_tokens.h
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
xx(TK_Identifier, "identifier")
|
||||
xx(TK_StringConst, "string constant")
|
||||
xx(TK_NameConst, "name constant")
|
||||
xx(TK_IntConst, "integer constant")
|
||||
xx(TK_UIntConst, "unsigned constant")
|
||||
xx(TK_FloatConst, "float constant")
|
||||
xx(TK_NonWhitespace, "non-whitespace")
|
||||
xx(TK_ColonColon, "'::'")
|
||||
xx(TK_DotDot, "'..'")
|
||||
xx(TK_Ellipsis, "'...'")
|
||||
xx(TK_RShiftEq, "'>>='")
|
||||
xx(TK_URShiftEq, "'>>>='")
|
||||
xx(TK_LShiftEq, "'<<='")
|
||||
xx(TK_AddEq, "'+='")
|
||||
xx(TK_SubEq, "'-='")
|
||||
xx(TK_MulEq, "'*='")
|
||||
xx(TK_DivEq, "'/='")
|
||||
xx(TK_ModEq, "'%='")
|
||||
xx(TK_AndEq, "'&='")
|
||||
xx(TK_XorEq, "'^='")
|
||||
xx(TK_OrEq, "'|='")
|
||||
xx(TK_RShift, "'>>'")
|
||||
xx(TK_URShift, "'>>>'")
|
||||
xx(TK_LShift, "'<<'")
|
||||
xx(TK_Incr, "'++'")
|
||||
xx(TK_Decr, "'--'")
|
||||
xx(TK_AndAnd, "'&&'")
|
||||
xx(TK_OrOr, "'||'")
|
||||
xx(TK_Leq, "'<='")
|
||||
xx(TK_Geq, "'>='")
|
||||
xx(TK_Eq, "'=='")
|
||||
xx(TK_Neq, "'!='")
|
||||
xx(TK_ApproxEq, "'~=='")
|
||||
xx(TK_LtGtEq, "'<>='")
|
||||
xx(TK_MulMul, "'**'")
|
||||
xx(TK_Arrow, "'->'")
|
||||
xx(TK_Action, "'action'")
|
||||
xx(TK_Break, "'break'")
|
||||
xx(TK_Case, "'case'")
|
||||
xx(TK_Const, "'const'")
|
||||
xx(TK_Continue, "'continue'")
|
||||
xx(TK_Default, "'default'")
|
||||
xx(TK_Do, "'do'")
|
||||
xx(TK_Else, "'else'")
|
||||
xx(TK_For, "'for'")
|
||||
xx(TK_If, "'if'")
|
||||
xx(TK_Return, "'return'")
|
||||
xx(TK_Switch, "'switch'")
|
||||
xx(TK_Until, "'until'")
|
||||
xx(TK_While, "'while'")
|
||||
xx(TK_Bool, "'bool'")
|
||||
xx(TK_Float, "'float'")
|
||||
xx(TK_Float32, "'float32'")
|
||||
xx(TK_Double, "'double'")
|
||||
xx(TK_Char, "'char'")
|
||||
xx(TK_Byte, "'byte'")
|
||||
xx(TK_SByte, "'sbyte'")
|
||||
xx(TK_Short, "'short'")
|
||||
xx(TK_UShort, "'ushort'")
|
||||
xx(TK_Int8, "'int8'")
|
||||
xx(TK_UInt8, "'uint8'")
|
||||
xx(TK_Int16, "'int16'")
|
||||
xx(TK_UInt16, "'uint16'")
|
||||
xx(TK_Int, "'int'")
|
||||
xx(TK_UInt, "'uint'")
|
||||
xx(TK_Long, "'long'")
|
||||
xx(TK_ULong, "'ulong'")
|
||||
xx(TK_Void, "'void'")
|
||||
xx(TK_Struct, "'struct'")
|
||||
xx(TK_FlagDef, "'flagdef'")
|
||||
xx(TK_Property, "'property'")
|
||||
xx(TK_Class, "'class'")
|
||||
xx(TK_Mixin, "'mixin'")
|
||||
xx(TK_Enum, "'enum'")
|
||||
xx(TK_Name, "'name'")
|
||||
xx(TK_String, "'string'")
|
||||
xx(TK_Sound, "'sound'")
|
||||
xx(TK_State, "'state'")
|
||||
xx(TK_Color, "'color'")
|
||||
xx(TK_Goto, "'goto'")
|
||||
xx(TK_Abstract, "'abstract'")
|
||||
xx(TK_ForEach, "'foreach'")
|
||||
xx(TK_True, "'true'")
|
||||
xx(TK_False, "'false'")
|
||||
xx(TK_None, "'none'")
|
||||
xx(TK_InstanceOf, "'instanceof'")
|
||||
xx(TK_Auto, "'auto'")
|
||||
xx(TK_Exec, "'exec'")
|
||||
xx(TK_DefaultProperties, "'defaultproperties'")
|
||||
xx(TK_Native, "'native'")
|
||||
xx(TK_Var, "'var'")
|
||||
xx(TK_Out, "'out'")
|
||||
xx(TK_Ref, "'ref'")
|
||||
xx(TK_Event, "'event'")
|
||||
xx(TK_Static, "'static'")
|
||||
xx(TK_Transient, "'transient'")
|
||||
xx(TK_Volatile, "'volatile'")
|
||||
xx(TK_Final, "'final'")
|
||||
xx(TK_Throws, "'throws'")
|
||||
xx(TK_Extend, "'extend'")
|
||||
xx(TK_Public, "'public'")
|
||||
xx(TK_Protected, "'protected'")
|
||||
xx(TK_Private, "'private'")
|
||||
xx(TK_Dot, "'dot'")
|
||||
xx(TK_Cross, "'cross'")
|
||||
xx(TK_Ignores, "'ignores'")
|
||||
xx(TK_Localized, "'localized'")
|
||||
xx(TK_Latent, "'latent'")
|
||||
xx(TK_Singular, "'singular'")
|
||||
xx(TK_Config, "'config'")
|
||||
xx(TK_Coerce, "'coerce'")
|
||||
xx(TK_Iterator, "'iterator'")
|
||||
xx(TK_Virtual, "'virtual'")
|
||||
xx(TK_VarArg, "'vararg'")
|
||||
xx(TK_UI, "'ui'")
|
||||
xx(TK_Play, "'play'")
|
||||
xx(TK_ClearScope, "'clearscope'")
|
||||
xx(TK_VirtualScope, "'virtualscope'")
|
||||
xx(TK_Override, "'override'")
|
||||
xx(TK_Super, "'super'")
|
||||
xx(TK_Null, "'null'")
|
||||
xx(TK_Global, "'global'")
|
||||
xx(TK_Stop, "'stop'")
|
||||
xx(TK_Include, "'include'")
|
||||
|
||||
xx(TK_Is, "'is'")
|
||||
xx(TK_Replaces, "'replaces'")
|
||||
xx(TK_Vector2, "'vector2'")
|
||||
xx(TK_Vector3, "'vector3'")
|
||||
xx(TK_Map, "'map'")
|
||||
xx(TK_Array, "'array'")
|
||||
xx(TK_In, "'in'")
|
||||
xx(TK_SizeOf, "'sizeof'")
|
||||
xx(TK_AlignOf, "'alignof'")
|
||||
xx(TK_States, "'states'")
|
||||
xx(TK_Loop, "'loop'")
|
||||
xx(TK_Fail, "'fail'")
|
||||
xx(TK_Wait, "'wait'")
|
||||
xx(TK_Meta, "'meta'")
|
||||
xx(TK_Deprecated, "'deprecated'")
|
||||
xx(TK_Version, "'version'")
|
||||
xx(TK_ReadOnly, "'readonly'")
|
||||
xx(TK_Internal, "'internal'")
|
||||
|
||||
xx(TK_CanRaise, "'canraise'")
|
||||
xx(TK_Fast, "'fast'")
|
||||
xx(TK_Light, "'light'")
|
||||
xx(TK_NoDelay, "'nodelay'")
|
||||
xx(TK_Offset, "'offset'")
|
||||
xx(TK_Slow, "'slow'")
|
||||
xx(TK_Bright, "'bright'")
|
||||
xx(TK_Let, "'let'")
|
||||
xx(TK_StaticConst, "'static const'")
|
||||
#undef xx
|
||||
Loading…
Add table
Add a link
Reference in a new issue