diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 2a7e2768d..d77ae1c2f 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -394,9 +394,9 @@ endif() # Update gitinfo.h add_custom_target( revision_check ALL - COMMAND updaterevision source/gitinfo.h + COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_SOURCE_DIR}/tools/updaterevision/UpdateRevision.cmake" src/gitinfo.h WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - DEPENDS updaterevision ) +) # required libraries @@ -562,8 +562,8 @@ else() endif() add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h - COMMAND re2c --no-generation-date -s -o ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h ${CMAKE_CURRENT_SOURCE_DIR}/core/utility/sc_man_scanner.re - DEPENDS re2c ${CMAKE_CURRENT_SOURCE_DIR}/core/utility/sc_man_scanner.re ) + COMMAND re2c --no-generation-date -s -o ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h ${CMAKE_CURRENT_SOURCE_DIR}/common/engine/sc_man_scanner.re + DEPENDS re2c ${CMAKE_CURRENT_SOURCE_DIR}/common/engine/sc_man_scanner.re ) include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) @@ -603,7 +603,9 @@ file( GLOB HEADER_FILES core/rendering/hwrenderer/utility/*.h common/utility/*.h + common/engine/*.h common/filesystem/*.h + common/textures/*.h common/thirdparty/*.h common/thirdparty/rapidjson/*.h common/thirdparty/math./*h @@ -624,7 +626,7 @@ file( GLOB HEADER_FILES set( NOT_COMPILED_SOURCE_FILES ${OTHER_SYSTEM_SOURCES} sc_man_scanner.h - core/utility/sc_man_scanner.re + common/engine/sc_man_scanner.re platform/win32/zutil.natvis ) @@ -721,6 +723,7 @@ set (PCH_SOURCES core/console/c_con.cpp common/thirdparty/sfmt/SFMT.cpp + common/textures/bitmap.cpp common/utility/engineerrors.cpp common/utility/i_module.cpp common/utility/m_alloc.cpp @@ -735,6 +738,7 @@ set (PCH_SOURCES common/utility/m_argv.cpp common/utility/s_playlist.cpp common/utility/zstrformat.cpp + common/utility/name.cpp common/thirdparty/md5.cpp common/thirdparty/superfasthash.cpp common/filesystem/filesystem.cpp @@ -749,14 +753,13 @@ set (PCH_SOURCES common/filesystem/file_whres.cpp common/filesystem/file_directory.cpp common/filesystem/resourcefile.cpp + common/engine/sc_man.cpp + #common/engine/palettecontainer.cpp // not yet operational. - core/utility/name.cpp core/utility/m_png.cpp - core/utility/sc_man.cpp core/utility/stringtable.cpp core/utility/stats.cpp - core/textures/bitmap.cpp core/textures/buildtiles.cpp core/textures/texture.cpp core/textures/image.cpp @@ -862,7 +865,7 @@ add_executable( ${PROJECT_NAME} WIN32 MACOSX_BUNDLE #set_source_files_properties( ${FASTMATH_SOURCES} PROPERTIES COMPILE_FLAGS ${DEM_FASTMATH_FLAG} ) set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" ) -set_source_files_properties( utility/sc_man.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h" ) +set_source_files_properties( common/engine/sc_man.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h" ) set_source_files_properties( ${NOT_COMPILED_SOURCE_FILES} PROPERTIES HEADER_FILE_ONLY TRUE ) @@ -910,9 +913,10 @@ include_directories( core/rendering platform common/thirdparty + common/textures common/filesystem common/utility - + common/engine ${CMAKE_BINARY_DIR}/libraries/gdtoa ${SYSTEM_SOURCES_DIR} @@ -1021,8 +1025,10 @@ source_group("Platform" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platfor source_group("Platform\\Win32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/win32/.+") source_group("Platform\\POSIX" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/posix/.+") source_group("Common" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/.+") -source_group("Common\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/filesystem/.+") source_group("Common\\Utility" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/utility/.+") +source_group("Common\\Engine" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/engine/.+") +source_group("Common\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/filesystem/.+") +source_group("Common\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/textures/.+") source_group("Common\\Third Party" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/thirdparty/.+") source_group("Common\\Third Party\\Math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/thirdparty/math/.+") source_group("Common\\Third Party\\RapidJSON" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/thirdparty/rapidjson/.+") diff --git a/source/blood/src/gameutil.cpp b/source/blood/src/gameutil.cpp index b03775b43..7e05cba82 100644 --- a/source/blood/src/gameutil.cpp +++ b/source/blood/src/gameutil.cpp @@ -512,7 +512,7 @@ int VectorScan(spritetype *pSprite, int nOffset, int nZOffset, int dx, int dy, i if (width2 >= 0 && width2 < tilesiz[nPicnum].x) { auto pData = tileLoadTile(nPicnum); - if (pData[width2*tilesiz[nPicnum].y+height2] != (char)255) + if (pData[width2*tilesiz[nPicnum].y+height2] != TRANSPARENT_INDEX) return 3; } } @@ -599,7 +599,7 @@ int VectorScan(spritetype *pSprite, int nOffset, int nZOffset, int dx, int dy, i else nPixel = nHOffset*nSizY + nOffset; - if (pData[nPixel] == (char)255) + if (pData[nPixel] == TRANSPARENT_INDEX) { int bakCstat = pWall->cstat; pWall->cstat &= ~64; diff --git a/source/blood/src/osdcmd.cpp b/source/blood/src/osdcmd.cpp index 3c827bb66..061511107 100644 --- a/source/blood/src/osdcmd.cpp +++ b/source/blood/src/osdcmd.cpp @@ -48,7 +48,7 @@ BEGIN_BLD_NS void LevelWarp(int nEpisode, int nLevel); -static int osdcmd_map(osdcmdptr_t parm) +static int osdcmd_map(CCmdFuncPtr parm) { if (parm->numparms != 1) return OSDCMD_SHOWHELP; @@ -96,7 +96,7 @@ static int osdcmd_map(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_demo(osdcmdptr_t parm) +static int osdcmd_demo(CCmdFuncPtr parm) { if (numplayers > 1) { @@ -121,7 +121,7 @@ static int osdcmd_demo(osdcmdptr_t parm) } -static int osdcmd_give(osdcmdptr_t parm) +static int osdcmd_give(CCmdFuncPtr parm) { if (numplayers != 1 || !gGameStarted || gMe->pXSprite->health == 0) { @@ -180,7 +180,7 @@ static int osdcmd_give(osdcmdptr_t parm) return OSDCMD_SHOWHELP; } -static int osdcmd_god(osdcmdptr_t UNUSED(parm)) +static int osdcmd_god(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); if (numplayers == 1 && gGameStarted) @@ -194,7 +194,7 @@ static int osdcmd_god(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_noclip(osdcmdptr_t UNUSED(parm)) +static int osdcmd_noclip(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -220,7 +220,7 @@ void onvideomodechange(int32_t newmode) UpdateDacs(gLastPal, false); } -static int osdcmd_activatecheat(osdcmdptr_t parm) +static int osdcmd_activatecheat(CCmdFuncPtr parm) { FString CheatEntry; if (parm->numparms != 1) @@ -238,7 +238,7 @@ static int osdcmd_activatecheat(osdcmdptr_t parm) } } -static int osdcmd_levelwarp(osdcmdptr_t parm) +static int osdcmd_levelwarp(CCmdFuncPtr parm) { if (parm->numparms != 2) return OSDCMD_SHOWHELP; @@ -255,16 +255,16 @@ static int osdcmd_levelwarp(osdcmdptr_t parm) int32_t registerosdcommands(void) { - OSD_RegisterFunction("map","map : loads the given map", osdcmd_map); - OSD_RegisterFunction("demo","demo : starts the given demo", osdcmd_demo); + C_RegisterFunction("map","map : loads the given map", osdcmd_map); + C_RegisterFunction("demo","demo : starts the given demo", osdcmd_demo); - OSD_RegisterFunction("give","give : gives requested item", osdcmd_give); - OSD_RegisterFunction("god","god: toggles god mode", osdcmd_god); - OSD_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); + C_RegisterFunction("give","give : gives requested item", osdcmd_give); + C_RegisterFunction("god","god: toggles god mode", osdcmd_god); + C_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); - OSD_RegisterFunction("activatecheat","activatecheat : activates a classic cheat code", osdcmd_activatecheat); + C_RegisterFunction("activatecheat","activatecheat : activates a classic cheat code", osdcmd_activatecheat); - OSD_RegisterFunction("levelwarp","levelwarp : warp to episode 'e' and map 'm'", osdcmd_levelwarp); + C_RegisterFunction("levelwarp","levelwarp : warp to episode 'e' and map 'm'", osdcmd_levelwarp); return 0; } diff --git a/source/blood/src/view.cpp b/source/blood/src/view.cpp index d92135dee..f1fee5a0b 100644 --- a/source/blood/src/view.cpp +++ b/source/blood/src/view.cpp @@ -65,7 +65,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "v_2ddrawer.h" #include "v_video.h" -CVARD(Bool, hud_powerupduration, true, CVAR_ARCHIVE|CVAR_FRONTEND_BLOOD, "enable/disable displaying the remaining seconds for power-ups") +CVARD(Bool, hud_powerupduration, true, CVAR_ARCHIVE/*|CVAR_FRONTEND_BLOOD*/, "enable/disable displaying the remaining seconds for power-ups") BEGIN_BLD_NS @@ -1823,7 +1823,7 @@ void viewInit(void) } #endif uint8_t *data = tileAllocTile(4077, kLensSize, kLensSize, 0, 0); - memset(data, 255, kLensSize*kLensSize); + memset(data, TRANSPARENT_INDEX, kLensSize*kLensSize); gGameMessageMgr.SetState(hud_messages); gGameMessageMgr.SetCoordinates(1, 1); char nFont; diff --git a/source/build/include/build.h b/source/build/include/build.h index ab62f35f2..b305e86d9 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -11,6 +11,8 @@ #ifndef build_h_ #define build_h_ +#define TRANSPARENT_INDEX 255 + static_assert('\xff' == 255, "Char must be unsigned!"); #if !defined __cplusplus || (__cplusplus < 201103L && !defined _MSC_VER) diff --git a/source/build/include/osd.h b/source/build/include/osd.h index 6a6c5ae67..49503840a 100644 --- a/source/build/include/osd.h +++ b/source/build/include/osd.h @@ -9,22 +9,13 @@ #include "compat.h" #include "printf.h" - -struct osdfuncparm_t -{ - int32_t numparms; - const char* name; - const char** parms; - const char* raw; -}; - -using osdcmdptr_t = osdfuncparm_t const * const; +#include "c_dispatch.h" const char *OSD_StripColors(char *outBuf, const char *inBuf); -#define OSDCMD_OK 0 -#define OSDCMD_SHOWHELP 1 +#define OSDCMD_OK CCMD_OK +#define OSDCMD_SHOWHELP CCMD_SHOWHELP // void OSD_Draw(); @@ -36,11 +27,5 @@ inline void OSD_DispatchQueued(void) C_RunDelayedCommands(); } -// registers a function -// name = name of the function -// help = a short help string -// func = the entry point to the function -int OSD_RegisterFunction(const char *pszName, const char *pszDesc, int (*func)(osdcmdptr_t)); - #endif // osd_h_ diff --git a/source/build/src/clip.cpp b/source/build/src/clip.cpp index 7af6f3f53..ebdb3be6f 100644 --- a/source/build/src/clip.cpp +++ b/source/build/src/clip.cpp @@ -11,6 +11,7 @@ #include "clip.h" #include "engine_priv.h" + static int16_t clipnum; static linetype clipit[MAXCLIPNUM]; static int32_t clipsectnum, origclipsectnum, clipspritenum; @@ -2539,7 +2540,7 @@ restart_grand: int32_t ytex = mulscale16(vcoefup16, tilesiz[tilenum].y); auto texel = (tilePtr(tilenum) + tilesiz[tilenum].y*xtex + ytex); - if (*texel == 255) + if (*texel == TRANSPARENT_INDEX) continue; } } diff --git a/source/core/utility/namedef.h b/source/common/engine/namedef.h similarity index 95% rename from source/core/utility/namedef.h rename to source/common/engine/namedef.h index 209471dde..5cafc87ce 100644 --- a/source/core/utility/namedef.h +++ b/source/common/engine/namedef.h @@ -143,7 +143,6 @@ xx(ArtiPoisonBag3) // Strife quests xx(QuestItem) xx(Sigil) -xx(ScriptedMarine) xx(GiveSigilPiece) xx(SetWeapon) xx(SetSprite) @@ -151,43 +150,9 @@ xx(SetSprite) // Armor xx(BasicArmor) -// The Wings of Wrath -xx(ArtiFly) - // Doom ammo types xx(Clip) -xx(Shell) -xx(RocketAmmo) -xx(Cell) -// Hexen Mana -xx(Mana1) -xx(Mana2) - -// Hexen's fourth weapons -xx(FWeapQuietus) -xx(CWeapWraithverge) -xx(MWeapBloodscourge) - -// Misc Hexen classes -xx(LightningZap) - -// Ammo and weapon names for the Strife status bar -xx(ClipOfBullets) -xx(PoisonBolts) -xx(ElectricBolts) -xx(HEGrenadeRounds) -xx(PhosphorusGrenadeRounds) -xx(MiniMissiles) -xx(EnergyPod) - -xx(StrifeCrossbow) -xx(AssaultGun) -xx(FlameThrower) -xx(MiniMissileLauncher) -xx(StrifeGrenadeLauncher) -xx(Mauler) -xx(BackpackItem) xx(PuzzleItem) xx(PuzzleItemNumber) xx(HealthPickup) @@ -215,28 +180,13 @@ xx(StateProvider) xx(CallTryPickup) xx(QuestItem25) xx(QuestItem28) -xx(QuestItem29) xx(PowerDoubleFiringSpeed) xx(PowerInfiniteAmmo) xx(PowerBuddha) -xx(AcolyteBlue) -xx(SpectralLightningV1) -xx(SpectralLightningV2) xx(TeleportDest) xx(TeleportDest2) -// Strife's spectres -xx(AlienSpectre1) -xx(AlienSpectre2) -xx(AlienSpectre3) -xx(AlienSpectre4) -xx(AlienSpectre5) -xx(Oracle) - -xx(Chicken) -xx(Pig) - // Standard animator names. xx(Spawn) xx(See) @@ -717,6 +667,7 @@ xx(Next) xx(Prev) xx(Children) xx(Owner) +xx(FlameThrower) xx(HealthFloor) xx(HealthCeiling) diff --git a/source/common/engine/palettecontainer.cpp b/source/common/engine/palettecontainer.cpp new file mode 100644 index 000000000..c07afe4a6 --- /dev/null +++ b/source/common/engine/palettecontainer.cpp @@ -0,0 +1,656 @@ +/* +** 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 "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; + +} + diff --git a/source/common/engine/palettecontainer.h b/source/common/engine/palettecontainer.h new file mode 100644 index 000000000..2737f9f89 --- /dev/null +++ b/source/common/engine/palettecontainer.h @@ -0,0 +1,106 @@ +#pragma once + +#include +#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; +} +inline int GetTranslationIndex(uint32_t trans) +{ + return (trans & TRANSLATION_MASK); +} + +class PaletteContainer +{ + FMemArena remapArena; + TArray uniqueRemaps; + TArray> 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; + diff --git a/source/core/utility/printf.h b/source/common/engine/printf.h similarity index 95% rename from source/core/utility/printf.h rename to source/common/engine/printf.h index 900eb4f74..ef107ae64 100644 --- a/source/core/utility/printf.h +++ b/source/common/engine/printf.h @@ -39,6 +39,12 @@ extern "C" int myvsnprintf(char* buffer, size_t count, const char* format, va_li #define TEXTCOLOR_SAPPHIRE "\034Y" #define TEXTCOLOR_TEAL "\034Z" +#define TEXTCOLOR_NORMAL "\034-" +#define TEXTCOLOR_BOLD "\034+" + +#define TEXTCOLOR_CHAT "\034*" +#define TEXTCOLOR_TEAMCHAT "\034!" + // game print flags enum { diff --git a/source/core/utility/sc_man.cpp b/source/common/engine/sc_man.cpp similarity index 93% rename from source/core/utility/sc_man.cpp rename to source/common/engine/sc_man.cpp index 5e20fd2e6..af5d5d1c2 100644 --- a/source/core/utility/sc_man.cpp +++ b/source/common/engine/sc_man.cpp @@ -33,12 +33,11 @@ - - // HEADER FILES ------------------------------------------------------------ #include #include +#include "engineerrors.h" #include "sc_man.h" #include "cmdlib.h" #include "templates.h" @@ -68,6 +67,31 @@ // CODE -------------------------------------------------------------------- +void VersionInfo::operator=(const char *string) +{ + char *endp; + major = (int16_t)clamp(strtoull(string, &endp, 10), 0, USHRT_MAX); + if (*endp == '.') + { + minor = (int16_t)clamp(strtoull(endp + 1, &endp, 10), 0, USHRT_MAX); + if (*endp == '.') + { + revision = (int16_t)clamp(strtoull(endp + 1, &endp, 10), 0, USHRT_MAX); + if (*endp != 0) major = USHRT_MAX; + } + else if (*endp == 0) + { + revision = 0; + } + else major = USHRT_MAX; + } + else if (*endp == 0) + { + minor = revision = 0; + } + else major = USHRT_MAX; +} + //========================================================================== // // FScanner Constructor @@ -102,6 +126,18 @@ FScanner::FScanner(const FScanner &other) *this = other; } +//========================================================================== +// +// FScanner OpenLumpNum Constructor +// +//========================================================================== + +FScanner::FScanner(int lumpnum) +{ + ScriptOpen = false; + OpenLumpNum(lumpnum); +} + //========================================================================== // // FScanner :: operator = @@ -155,7 +191,6 @@ FScanner &FScanner::operator=(const FScanner &other) TokenType = other.TokenType; Number = other.Number; Float = other.Float; - //Name = other.Name; Line = other.Line; End = other.End; Crossed = other.Crossed; @@ -171,37 +206,12 @@ FScanner &FScanner::operator=(const FScanner &other) void FScanner::Open (const char *name) { - auto fr = fileSystem.OpenFileReader(name); - if (!fr.isOpen()) + int lump = fileSystem.CheckNumForFullName(name, true); + if (lump == -1) { I_Error("Could not find script lump '%s'\n", name); } - Close(); - auto data = fr.ReadPadded(1); - ScriptBuffer = data; - ScriptName = name; - //LumpNum = lump; - PrepareScript(); -} - -//========================================================================== -// -// FScanner :: Open -// -//========================================================================== - -FScanner::FScanner(int lump) -{ - if ((unsigned)lump >= fileSystem.GetNumEntries()) - { - I_Error("Invalid file index %d\n", lump); - } - Close(); - auto data = fileSystem.GetFileData(lump, 1); - ScriptBuffer = data; - ScriptName = fileSystem.GetFileFullName(lump); - LumpNum = lump; - PrepareScript(); + OpenLumpNum(lump); } //========================================================================== @@ -212,16 +222,21 @@ FScanner::FScanner(int lump) // //========================================================================== -void FScanner::OpenFile (const char *name) +bool FScanner::OpenFile (const char *name) { Close (); + FileReader fr; - if (!fr.OpenFile(name)) return; - auto data = fr.ReadPadded(1); - ScriptBuffer = data; + if (!fr.OpenFile(name)) return false; + auto filesize = fr.GetLength(); + auto filebuff = fr.Read(); + if (filebuff.Size() == 0 && filesize > 0) return false; + + ScriptBuffer = FString((const char *)filebuff.Data(), filesize); ScriptName = name; // This is used for error messages so the full file name is preferable LumpNum = -1; PrepareScript (); + return true; } //========================================================================== @@ -255,6 +270,26 @@ void FScanner::OpenString (const char *name, FString buffer) PrepareScript (); } +//========================================================================== +// +// FScanner :: OpenLumpNum +// +// Loads a script from the lump directory +// +//========================================================================== + +void FScanner :: OpenLumpNum (int lump) +{ + Close (); + { + FileData mem = fileSystem.ReadFile(lump); + ScriptBuffer = mem.GetString(); + } + ScriptName = fileSystem.GetFileFullPath(lump); + LumpNum = lump; + PrepareScript (); +} + //========================================================================== // // FScanner :: PrepareScript @@ -1084,7 +1119,7 @@ void FScanner::CheckOpen() { if (ScriptOpen == false) { - I_Error ("SC_ call before SC_Open()."); + I_FatalError ("SC_ call before SC_Open()."); } } @@ -1095,13 +1130,14 @@ void FScanner::CheckOpen() //========================================================================== int FScriptPosition::ErrorCounter; int FScriptPosition::WarnCounter; +int FScriptPosition::Developer; bool FScriptPosition::StrictErrors; // makes all OPTERROR messages real errors. bool FScriptPosition::errorout; // call I_Error instead of printing the error itself. FScriptPosition::FScriptPosition(FString fname, int line) { - FileName = fname.GetChars(); + FileName = fname; ScriptLine = line; } @@ -1128,15 +1164,13 @@ void FScriptPosition::Message (int severity, const char *message, ...) const { FString composed; -#if 0 - if (severity == MSG_DEBUGLOG && developer < DMSG_NOTIFY) return; - if (severity == MSG_DEBUGERROR && developer < DMSG_ERROR) return; - if (severity == MSG_DEBUGWARN && developer < DMSG_WARNING) return; - if (severity == MSG_DEBUGMSG && developer < DMSG_NOTIFY) return; -#endif + if (severity == MSG_DEBUGLOG && Developer < DMSG_NOTIFY) return; + if (severity == MSG_DEBUGERROR && Developer < DMSG_ERROR) return; + if (severity == MSG_DEBUGWARN && Developer < DMSG_WARNING) return; + if (severity == MSG_DEBUGMSG && Developer < DMSG_NOTIFY) return; if (severity == MSG_OPTERROR) { - severity = StrictErrors ? MSG_ERROR : MSG_WARNING; + severity = StrictErrors? MSG_ERROR : MSG_WARNING; } // This is mainly for catching the error with an exception handler. if (severity == MSG_ERROR && errorout) severity = MSG_FATAL; diff --git a/source/core/utility/sc_man.h b/source/common/engine/sc_man.h similarity index 71% rename from source/core/utility/sc_man.h rename to source/common/engine/sc_man.h index 0ca584913..684482e6c 100644 --- a/source/core/utility/sc_man.h +++ b/source/common/engine/sc_man.h @@ -5,6 +5,38 @@ #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: @@ -23,10 +55,19 @@ public: FScanner &operator=(const FScanner &other); void Open(const char *lumpname); - void OpenFile(const char *filename); + bool OpenFile(const char *filename); void OpenMem(const char *name, const char *buffer, int size); + void OpenMem(const char *name, const TArray &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); @@ -111,6 +152,7 @@ protected: uint8_t StateMode; bool StateOptions; bool Escape; + VersionInfo ParseVersion = { 0, 0, 0 }; // no ZScript extensions by default bool ScanValue(bool allowfloat); @@ -156,6 +198,7 @@ struct FScriptPosition static int WarnCounter; static int ErrorCounter; static bool StrictErrors; + static int Developer; static bool errorout; FName FileName; int ScriptLine; diff --git a/source/core/utility/sc_man_scanner.re b/source/common/engine/sc_man_scanner.re similarity index 68% rename from source/core/utility/sc_man_scanner.re rename to source/common/engine/sc_man_scanner.re index 46d7952f4..b10f48081 100644 --- a/source/core/utility/sc_man_scanner.re +++ b/source/common/engine/sc_man_scanner.re @@ -120,7 +120,109 @@ std2: ("#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(ParseVersion >= MakeVersion(1, 0, 0)? TK_Name : TK_Identifier); } + '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); } @@ -167,8 +269,8 @@ std2: "**" { RET(TK_MulMul); } "::" { RET(TK_ColonColon); } "->" { RET(TK_Arrow); } - ";" { RET(';'); } - "{" { RET('{'); } + ";" { StateOptions = false; RET(';'); } + "{" { StateOptions = false; RET('{'); } "}" { RET('}'); } "," { RET(','); } ":" { RET(':'); } diff --git a/source/core/utility/sc_man_tokens.h b/source/common/engine/sc_man_tokens.h similarity index 100% rename from source/core/utility/sc_man_tokens.h rename to source/common/engine/sc_man_tokens.h diff --git a/source/common/textures/bitmap.cpp b/source/common/textures/bitmap.cpp new file mode 100644 index 000000000..6c34b6c56 --- /dev/null +++ b/source/common/textures/bitmap.cpp @@ -0,0 +1,499 @@ +/* +** bitmap.cpp +** +**--------------------------------------------------------------------------- +** Copyright 2008 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. +**--------------------------------------------------------------------------- +** +** +*/ + +#include "bitmap.h" + + +//#include "colormaps.h" // todo: Move the special colormaps out of the game specicic code + +uint8_t 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 } +}; + +//=========================================================================== +// +// multi-format pixel copy with colormap application +// requires the previously defined conversion classes to work +// +//=========================================================================== +template +void iCopyColors(uint8_t *pout, const uint8_t *pin, int count, int step, FCopyInfo *inf, + uint8_t tr, uint8_t tg, uint8_t tb) +{ + int i; + int fac; + uint8_t r,g,b; + int gray; + int a; + + switch(inf? inf->blend : BLEND_NONE) + { + case BLEND_NONE: + for(i=0;i>4; + + TBlend::OpC(pout[TDest::RED], IcePalette[gray][0], a, inf); + TBlend::OpC(pout[TDest::GREEN], IcePalette[gray][1], a, inf); + TBlend::OpC(pout[TDest::BLUE], IcePalette[gray][2], a, inf); + TBlend::OpA(pout[TDest::ALPHA], a, inf); + } + pout+=4; + pin+=step; + } + break; + + default: + + if (inf->blend >= BLEND_SPECIALCOLORMAP1) + { +#if 0 + FSpecialColormap *cm = &SpecialColormaps[inf->blend - BLEND_SPECIALCOLORMAP1]; + for(i=0;i(TSrc::Gray(pin),0,255); + + PalEntry pe = cm->GrayscaleToColor[gray]; + TBlend::OpC(pout[TDest::RED], pe.r , a, inf); + TBlend::OpC(pout[TDest::GREEN], pe.g, a, inf); + TBlend::OpC(pout[TDest::BLUE], pe.b, a, inf); + TBlend::OpA(pout[TDest::ALPHA], a, inf); + } + pout+=4; + pin+=step; + } +#endif + } + else if (inf->blend >= BLEND_DESATURATE1 && inf->blend<=BLEND_DESATURATE31) + { + // Desaturated light settings. + fac=inf->blend-BLEND_DESATURATE1+1; + for(i=0;iblendcolor[0])>>BLENDBITS; + g = (TSrc::G(pin)*inf->blendcolor[1])>>BLENDBITS; + b = (TSrc::B(pin)*inf->blendcolor[2])>>BLENDBITS; + + TBlend::OpC(pout[TDest::RED], r, a, inf); + TBlend::OpC(pout[TDest::GREEN], g, a, inf); + TBlend::OpC(pout[TDest::BLUE], b, a, inf); + TBlend::OpA(pout[TDest::ALPHA], a, inf); + } + pout+=4; + pin+=step; + } + break; + + case BLEND_OVERLAY: + for(i=0;iblendcolor[3] + inf->blendcolor[0]) >> BLENDBITS; + g = (TSrc::G(pin)*inf->blendcolor[3] + inf->blendcolor[1]) >> BLENDBITS; + b = (TSrc::B(pin)*inf->blendcolor[3] + inf->blendcolor[2]) >> BLENDBITS; + + TBlend::OpC(pout[TDest::RED], r, a, inf); + TBlend::OpC(pout[TDest::GREEN], g, a, inf); + TBlend::OpC(pout[TDest::BLUE], b, a, inf); + TBlend::OpA(pout[TDest::ALPHA], a, inf); + } + pout+=4; + pin+=step; + } + break; + + } +} + +typedef void (*CopyFunc)(uint8_t *pout, const uint8_t *pin, int count, int step, FCopyInfo *inf, uint8_t r, uint8_t g, uint8_t b); + +#define COPY_FUNCS(op) \ + { \ + iCopyColors, \ + iCopyColors, \ + iCopyColors, \ + iCopyColors, \ + iCopyColors, \ + iCopyColors, \ + iCopyColors, \ + iCopyColors, \ + iCopyColors, \ + iCopyColors, \ + iCopyColors \ + } +static const CopyFunc copyfuncs[][11]={ + COPY_FUNCS(bCopy), + COPY_FUNCS(bBlend), + COPY_FUNCS(bAdd), + COPY_FUNCS(bSubtract), + COPY_FUNCS(bReverseSubtract), + COPY_FUNCS(bModulate), + COPY_FUNCS(bCopyAlpha), + COPY_FUNCS(bCopyNewAlpha), + COPY_FUNCS(bOverlay), + COPY_FUNCS(bOverwrite) +}; +#undef COPY_FUNCS + +//=========================================================================== +// +// Clips the copy area for CopyPixelData functions +// +//=========================================================================== +bool ClipCopyPixelRect(const FClipRect *cr, int &originx, int &originy, + const uint8_t *&patch, int &srcwidth, int &srcheight, + int &pstep_x, int &pstep_y, int rotate) +{ + int pixxoffset; + int pixyoffset; + + int step_x; + int step_y; + + assert(cr != NULL); + // First adjust the settings for the intended rotation + switch (rotate) + { + default: + case 0: // normal + pixxoffset = 0; + pixyoffset = 0; + step_x = pstep_x; + step_y = pstep_y; + break; + + case 1: // rotate 90° right + pixxoffset = 0; + pixyoffset = srcheight - 1; + step_x = -pstep_y; + step_y = pstep_x; + break; + + case 2: // rotate 180° + pixxoffset = srcwidth - 1; + pixyoffset = srcheight - 1; + step_x = -pstep_x; + step_y = -pstep_y; + break; + + case 3: // rotate 90° left + pixxoffset = srcwidth - 1; + pixyoffset = 0; + step_x = pstep_y; + step_y = -pstep_x; + break; + + case 4: // flip horizontally + pixxoffset = srcwidth - 1; + pixyoffset = 0; + step_x = -pstep_x; + step_y = pstep_y; + break; + + case 5: // flip horizontally and rotate 90° right + pixxoffset = srcwidth - 1; + pixyoffset = srcheight - 1; + step_x = -pstep_y; + step_y = -pstep_x; + break; + + case 6: // flip vertically + pixxoffset = 0; + pixyoffset = srcheight - 1; + step_x = pstep_x; + step_y = -pstep_y; + break; + + case 7: // flip horizontally and rotate 90° left + pixxoffset = 0; + pixyoffset = 0; + step_x = pstep_y; + step_y = pstep_x; + break; + } + if (rotate&1) + { + int v = srcwidth; + srcwidth = srcheight; + srcheight = v; + } + + patch += pixxoffset * pstep_x + pixyoffset * pstep_y; + pstep_x = step_x; + pstep_y = step_y; + + // clip source rectangle to destination + if (originx < cr->x) + { + int skip = cr->x - originx; + + srcwidth -= skip; + patch +=skip * step_x; + originx = cr->x; + if (srcwidth<=0) return false; + } + if (originx + srcwidth > cr->x + cr->width) + { + srcwidth = cr->x + cr->width - originx; + if (srcwidth<=0) return false; + } + + if (originy < cr->y) + { + int skip = cr->y - originy; + + srcheight -= skip; + patch += skip*step_y; + originy = cr->y; + if (srcheight <= 0) return false; + } + if (originy + srcheight > cr->y + cr->height) + { + srcheight = cr->y + cr->height - originy; + if (srcheight <= 0) return false; + } + + return true; +} + + +//=========================================================================== +// +// +// +//=========================================================================== + +bool FClipRect::Intersect(int ix, int iy, int iw, int ih) +{ + if (ix > x) + { + width -= (ix-x); + x = ix; + } + else + { + iw -= (x-ix); + } + if (iy > y) + { + height -= (iy-y); + y = iy; + } + else + { + ih -= (y-iy); + } + if (iw < width) width = iw; + if (ih < height) height = ih; + return width > 0 && height > 0; +} + +//=========================================================================== +// +// True Color texture copy function +// +//=========================================================================== +void FBitmap::CopyPixelDataRGB(int originx, int originy, const uint8_t *patch, int srcwidth, + int srcheight, int step_x, int step_y, int rotate, int ct, FCopyInfo *inf, + int r, int g, int b) +{ + if (ClipCopyPixelRect(&ClipRect, originx, originy, patch, srcwidth, srcheight, step_x, step_y, rotate)) + { + uint8_t *buffer = data + 4 * originx + Pitch * originy; + int op = inf==NULL? OP_COPY : inf->op; + for (int y=0;y +void iCopyPaletted(uint8_t *buffer, const uint8_t * patch, int srcwidth, int srcheight, int Pitch, + int step_x, int step_y, int rotate, const PalEntry * palette, FCopyInfo *inf) +{ + int x,y,pos; + + for (y=0;y, + iCopyPaletted, + iCopyPaletted, + iCopyPaletted, + iCopyPaletted, + iCopyPaletted, + iCopyPaletted, + iCopyPaletted, + iCopyPaletted, + iCopyPaletted +}; + +//=========================================================================== +// +// Paletted to True Color texture copy function +// +//=========================================================================== +void FBitmap::CopyPixelData(int originx, int originy, const uint8_t * patch, int srcwidth, int srcheight, + int step_x, int step_y, int rotate, const PalEntry * palette, FCopyInfo *inf) +{ + if (ClipCopyPixelRect(&ClipRect, originx, originy, patch, srcwidth, srcheight, step_x, step_y, rotate)) + { + uint8_t *buffer = data + 4*originx + Pitch*originy; + PalEntry penew[256]; + + memset(penew, 0, sizeof(penew)); + if (inf) + { + if (inf->blend) + { + iCopyColors((uint8_t*)penew, (const uint8_t*)palette, 256, 4, inf, 0, 0, 0); + palette = penew; + } + else if (inf->palette) + { + palette = inf->palette; + } + } + + copypalettedfuncs[inf==NULL? OP_COPY : inf->op](buffer, patch, srcwidth, srcheight, Pitch, + step_x, step_y, rotate, palette, inf); + } +} + +//=========================================================================== +// +// Clear buffer +// +//=========================================================================== +void FBitmap::Zero() +{ + uint8_t *buffer = data; + for (int y = ClipRect.y; y < ClipRect.height; ++y) + { + memset(buffer + ClipRect.x, 0, ClipRect.width*4); + buffer += Pitch; + } +} diff --git a/source/core/textures/bitmap.h b/source/common/textures/bitmap.h similarity index 70% rename from source/core/textures/bitmap.h rename to source/common/textures/bitmap.h index 2a69c6701..5ee574b7f 100644 --- a/source/core/textures/bitmap.h +++ b/source/common/textures/bitmap.h @@ -2,7 +2,7 @@ ** bitmap.h ** **--------------------------------------------------------------------------- -** Copyright 2008-2019 Christoph Oelckers +** Copyright 2008 Christoph Oelckers ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -36,11 +36,9 @@ #ifndef __BITMAP_H__ #define __BITMAP_H__ -#include -#include "palentry.h" -#include -#include +#include "basics.h" #include "templates.h" +#include "palentry.h" struct FCopyInfo; @@ -83,6 +81,7 @@ protected: int Height; int Pitch; bool FreeBuffer; + FClipRect ClipRect; public: @@ -92,6 +91,7 @@ public: Width = Height = 0; Pitch = 0; FreeBuffer = false; + ClipRect.x = ClipRect.y = ClipRect.width = ClipRect.height = 0; } FBitmap(uint8_t *buffer, int pitch, int width, int height) @@ -102,6 +102,9 @@ public: Width = width; Height = height; FreeBuffer = false; + ClipRect.x = ClipRect.y = 0; + ClipRect.width = width; + ClipRect.height = height; } FBitmap(const FBitmap &other) = delete; // disallow because in nearly all cases this creates an unwanted copy. @@ -113,6 +116,7 @@ public: Width = other.Width; Height = other.Height; FreeBuffer = other.FreeBuffer; + ClipRect = other.ClipRect; other.data = nullptr; other.FreeBuffer = false; } @@ -127,6 +131,7 @@ public: Width = other.Width; Height = other.Height; FreeBuffer = other.FreeBuffer; + ClipRect = other.ClipRect; other.data = nullptr; other.FreeBuffer = false; return *this; @@ -139,6 +144,7 @@ public: Width = other.Width; Height = other.Height; FreeBuffer = deep; + ClipRect = other.ClipRect; if (deep) { data = new uint8_t[Pitch * Height]; @@ -171,6 +177,9 @@ public: data = new uint8_t[4*w*h]; memset(data, 0, 4*w*h); FreeBuffer = true; + ClipRect.x = ClipRect.y = 0; + ClipRect.width = w; + ClipRect.height = h; return data != NULL; } @@ -199,21 +208,52 @@ public: return data; } + void SetClipRect(FClipRect &clip) + { + ClipRect = clip; + } + + void IntersectClipRect(FClipRect &clip) + { + ClipRect.Intersect(clip.x, clip.y, clip.width, clip.height); + } + + void IntersectClipRect(int cx, int cy, int cw, int ch) + { + ClipRect.Intersect(cx, cy, cw, ch); + } + + const FClipRect &GetClipRect() const + { + return ClipRect; + } + + void Zero(); + void CopyPixelDataRGB(int originx, int originy, const uint8_t *patch, int srcwidth, - int srcheight, int step_x, int step_y, int rotate, int ct, + int srcheight, int step_x, int step_y, int rotate, int ct, FCopyInfo *inf = NULL, /* for PNG tRNS */ int r=0, int g=0, int b=0); void CopyPixelData(int originx, int originy, const uint8_t * patch, int srcwidth, int srcheight, - int step_x, int step_y, int rotate, const PalEntry * palette); + int step_x, int step_y, int rotate, const PalEntry * palette, FCopyInfo *inf = NULL); - void Blit(int originx, int originy, const FBitmap &src) + void Blit(int originx, int originy, const FBitmap &src, int width, int height, int rotate = 0, FCopyInfo *inf = NULL) { - CopyPixelDataRGB(originx, originy, src.GetPixels(), src.GetWidth(), src.GetHeight(), 4, src.GetWidth()*4, 0, CF_BGRA); + CopyPixelDataRGB(originx, originy, src.GetPixels(), width, height, 4, src.GetWidth()*4, rotate, CF_BGRA, inf); + } + + void Blit(int originx, int originy, const FBitmap &src, FCopyInfo *inf = NULL) + { + CopyPixelDataRGB(originx, originy, src.GetPixels(), src.GetWidth(), src.GetHeight(), 4, src.GetWidth()*4, 0, CF_BGRA, inf); } }; +bool ClipCopyPixelRect(const FClipRect *cr, int &originx, int &originy, + const uint8_t *&patch, int &srcwidth, int &srcheight, + int &step_x, int &step_y, int rotate); + //=========================================================================== // // True color conversion classes for the different pixel formats @@ -349,10 +389,108 @@ struct cPalEntry static __forceinline int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; } }; +enum EBlend +{ + BLEND_NONE = 0, + BLEND_ICEMAP = 1, + BLEND_DESATURATE1 = 2, + BLEND_DESATURATE31 = 32, + BLEND_SPECIALCOLORMAP1 = 33, + BLEND_MODULATE = -1, + BLEND_OVERLAY = -2, +}; + +enum ECopyOp +{ + OP_COPY, + OP_BLEND, + OP_ADD, + OP_SUBTRACT, + OP_REVERSESUBTRACT, + OP_MODULATE, + OP_COPYALPHA, + OP_COPYNEWALPHA, + OP_OVERLAY, + OP_OVERWRITE +}; + +struct FCopyInfo +{ + ECopyOp op; + EBlend blend; + blend_t blendcolor[4]; + blend_t alpha; + blend_t invalpha; + PalEntry *palette; +}; + +struct bOverwrite +{ + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = s; } + static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } + static __forceinline bool ProcessAlpha0() { return true; } +}; + struct bCopy { - static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a) { d = s; } - static __forceinline void OpA(uint8_t &d, uint8_t s) { d = s; } + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = s; } + static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } + static __forceinline bool ProcessAlpha0() { return false; } +}; + +struct bCopyNewAlpha +{ + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = s; } + static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = (s*i->alpha) >> BLENDBITS; } + static __forceinline bool ProcessAlpha0() { return false; } +}; + +struct bCopyAlpha +{ + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = (s*a + d*(255-a))/255; } + static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } + static __forceinline bool ProcessAlpha0() { return false; } +}; + +struct bOverlay +{ + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = (s*a + d*(255-a))/255; } + static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = MAX(s,d); } + static __forceinline bool ProcessAlpha0() { return false; } +}; + +struct bBlend +{ + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = (d*i->invalpha + s*i->alpha) >> BLENDBITS; } + static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } + static __forceinline bool ProcessAlpha0() { return false; } +}; + +struct bAdd +{ + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = MIN((d*BLENDUNIT + s*i->alpha) >> BLENDBITS, 255); } + static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } + static __forceinline bool ProcessAlpha0() { return false; } +}; + +struct bSubtract +{ + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = MAX((d*BLENDUNIT - s*i->alpha) >> BLENDBITS, 0); } + static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } + static __forceinline bool ProcessAlpha0() { return false; } +}; + +struct bReverseSubtract +{ + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = MAX((-d*BLENDUNIT + s*i->alpha) >> BLENDBITS, 0); } + static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } + static __forceinline bool ProcessAlpha0() { return false; } +}; + +struct bModulate +{ + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = (s*d)/255; } + static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } static __forceinline bool ProcessAlpha0() { return false; } }; diff --git a/source/common/utility/engineerrors.cpp b/source/common/utility/engineerrors.cpp index d15917761..ccc459f72 100644 --- a/source/common/utility/engineerrors.cpp +++ b/source/common/utility/engineerrors.cpp @@ -53,7 +53,6 @@ void I_DebugPrint(const char *cp) #endif #include "engineerrors.h" -#include "printf.h" //========================================================================== // @@ -70,7 +69,7 @@ void I_Error(const char *error, ...) char errortext[MAX_ERRORTEXT]; va_start(argptr, error); - myvsnprintf(errortext, MAX_ERRORTEXT, error, argptr); + vsnprintf(errortext, MAX_ERRORTEXT, error, argptr); va_end(argptr); I_DebugPrint(errortext); @@ -97,7 +96,7 @@ void I_FatalError(const char *error, ...) char errortext[MAX_ERRORTEXT]; va_list argptr; va_start(argptr, error); - myvsnprintf(errortext, MAX_ERRORTEXT, error, argptr); + vsnprintf(errortext, MAX_ERRORTEXT, error, argptr); va_end(argptr); I_DebugPrint(errortext); diff --git a/source/common/utility/m_alloc.cpp b/source/common/utility/m_alloc.cpp index 755e7b1b5..8e3b89ab6 100644 --- a/source/common/utility/m_alloc.cpp +++ b/source/common/utility/m_alloc.cpp @@ -44,7 +44,7 @@ #include #endif -#include "printf.h" +#include "engineerrors.h" #include "m_alloc.h" #ifndef _MSC_VER diff --git a/source/common/utility/memarena.cpp b/source/common/utility/memarena.cpp index c586a42c4..0e2be24ba 100644 --- a/source/common/utility/memarena.cpp +++ b/source/common/utility/memarena.cpp @@ -39,7 +39,6 @@ #include "basics.h" #include "memarena.h" -#include "printf.h" #include "cmdlib.h" #include "m_alloc.h" diff --git a/source/core/utility/name.cpp b/source/common/utility/name.cpp similarity index 100% rename from source/core/utility/name.cpp rename to source/common/utility/name.cpp diff --git a/source/core/utility/name.h b/source/common/utility/name.h similarity index 100% rename from source/core/utility/name.h rename to source/common/utility/name.h diff --git a/source/common/utility/palette.cpp b/source/common/utility/palette.cpp index 84177ecdc..5518b7235 100644 --- a/source/common/utility/palette.cpp +++ b/source/common/utility/palette.cpp @@ -32,9 +32,13 @@ ** */ +#include #include "palutil.h" #include "palentry.h" +#include "sc_man.h" #include "files.h" +#include "filesystem.h" +#include "printf.h" /****************************/ /* Palette management stuff */ @@ -313,3 +317,380 @@ void HSVtoRGB (float *r, float *g, float *b, float h, float s, float v) } } +struct RemappingWork +{ + uint32_t Color; + uint8_t Foreign; // 0 = local palette, 1 = foreign palette + uint8_t PalEntry; // Entry # in the palette + uint8_t Pad[2]; +}; + +static int sortforremap(const void* a, const void* b) +{ + return (*(const uint32_t*)a & 0xFFFFFF) - (*(const uint32_t*)b & 0xFFFFFF); +} + +static int sortforremap2(const void* a, const void* b) +{ + const RemappingWork* ap = (const RemappingWork*)a; + const RemappingWork* bp = (const RemappingWork*)b; + + if (ap->Color == bp->Color) + { + return bp->Foreign - ap->Foreign; + } + else + { + return ap->Color - bp->Color; + } +} + + +void MakeRemap(uint32_t* BaseColors, const uint32_t* colors, uint8_t* remap, const uint8_t* useful, int numcolors) +{ + RemappingWork workspace[255 + 256]; + int i, j, k; + + // Fill in workspace with the colors from the passed palette and this palette. + // By sorting this array, we can quickly find exact matches so that we can + // minimize the time spent calling BestColor for near matches. + + for (i = 1; i < 256; ++i) + { + workspace[i - 1].Color = uint32_t(BaseColors[i]) & 0xFFFFFF; + workspace[i - 1].Foreign = 0; + workspace[i - 1].PalEntry = i; + } + for (i = k = 0, j = 255; i < numcolors; ++i) + { + if (useful == NULL || useful[i] != 0) + { + workspace[j].Color = colors[i] & 0xFFFFFF; + workspace[j].Foreign = 1; + workspace[j].PalEntry = i; + ++j; + ++k; + } + else + { + remap[i] = 0; + } + } + qsort(workspace, j, sizeof(RemappingWork), sortforremap2); + + // Find exact matches + --j; + for (i = 0; i < j; ++i) + { + if (workspace[i].Foreign) + { + if (!workspace[i + 1].Foreign && workspace[i].Color == workspace[i + 1].Color) + { + remap[workspace[i].PalEntry] = workspace[i + 1].PalEntry; + workspace[i].Foreign = 2; + ++i; + --k; + } + } + } + + // Find near matches + if (k > 0) + { + for (i = 0; i <= j; ++i) + { + if (workspace[i].Foreign == 1) + { + remap[workspace[i].PalEntry] = BestColor((uint32_t*)BaseColors, + RPART(workspace[i].Color), GPART(workspace[i].Color), BPART(workspace[i].Color), + 1, 255); + } + } + } +} + +// In ZDoom's new texture system, color 0 is used as the transparent color. +// But color 0 is also a valid color for Doom engine graphics. What to do? +// Simple. The default palette for every game has at least one duplicate +// color, so find a duplicate pair of palette entries, make one of them a +// duplicate of color 0, and remap every graphic so that it uses that entry +// instead of entry 0. +void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap) +{ + for (int i = 0; i < 256; i++) Remap[i] = i; + PalEntry color0 = BaseColors[0]; + int i; + + // First try for an exact match of color 0. Only Hexen does not have one. + for (i = 1; i < 256; ++i) + { + if (BaseColors[i] == color0) + { + Remap[0] = i; + break; + } + } + + // If there is no duplicate of color 0, find the first set of duplicate + // colors and make one of them a duplicate of color 0. In Hexen's PLAYPAL + // colors 209 and 229 are the only duplicates, but we cannot assume + // anything because the player might be using a custom PLAYPAL where those + // entries are not duplicates. + if (Remap[0] == 0) + { + PalEntry sortcopy[256]; + + for (i = 0; i < 256; ++i) + { + sortcopy[i] = BaseColors[i] | (i << 24); + } + qsort(sortcopy, 256, 4, sortforremap); + for (i = 255; i > 0; --i) + { + if ((sortcopy[i] & 0xFFFFFF) == (sortcopy[i - 1] & 0xFFFFFF)) + { + int new0 = sortcopy[i].a; + int dup = sortcopy[i - 1].a; + if (new0 > dup) + { + // Make the lower-numbered entry a copy of color 0. (Just because.) + std::swap(new0, dup); + } + Remap[0] = new0; + Remap[new0] = dup; + BaseColors[new0] = color0; + break; + } + } + } + + // If there were no duplicates, InitPalette() will remap color 0 to the + // closest matching color. Hopefully nobody will use a palette where all + // 256 entries are different. :-) +} + +//========================================================================== +// +// V_GetColorFromString +// +// Passed a string of the form "#RGB", "#RRGGBB", "R G B", or "RR GG BB", +// returns a number representing that color. If palette is non-NULL, the +// index of the best match in the palette is returned, otherwise the +// RRGGBB value is returned directly. +// +//========================================================================== + +int V_GetColorFromString(const uint32_t* palette, const char* cstr, FScriptPosition* sc) +{ + int c[3], i, p; + char val[3]; + + val[2] = '\0'; + + // Check for HTML-style #RRGGBB or #RGB color string + if (cstr[0] == '#') + { + size_t len = strlen(cstr); + + if (len == 7) + { + // Extract each eight-bit component into c[]. + for (i = 0; i < 3; ++i) + { + val[0] = cstr[1 + i * 2]; + val[1] = cstr[2 + i * 2]; + c[i] = ParseHex(val, sc); + } + } + else if (len == 4) + { + // Extract each four-bit component into c[], expanding to eight bits. + for (i = 0; i < 3; ++i) + { + val[1] = val[0] = cstr[1 + i]; + c[i] = ParseHex(val, sc); + } + } + else + { + // Bad HTML-style; pretend it's black. + c[2] = c[1] = c[0] = 0; + } + } + else + { + if (strlen(cstr) == 6) + { + char* p; + int color = strtol(cstr, &p, 16); + if (*p == 0) + { + // RRGGBB string + c[0] = (color & 0xff0000) >> 16; + c[1] = (color & 0xff00) >> 8; + c[2] = (color & 0xff); + } + else goto normal; + } + else + { + normal: + // Treat it as a space-delimited hexadecimal string + for (i = 0; i < 3; ++i) + { + // Skip leading whitespace + while (*cstr <= ' ' && *cstr != '\0') + { + cstr++; + } + // Extract a component and convert it to eight-bit + for (p = 0; *cstr > ' '; ++p, ++cstr) + { + if (p < 2) + { + val[p] = *cstr; + } + } + if (p == 0) + { + c[i] = 0; + } + else + { + if (p == 1) + { + val[1] = val[0]; + } + c[i] = ParseHex(val, sc); + } + } + } + } + if (palette) + return BestColor(palette, c[0], c[1], c[2]); + else + return MAKERGB(c[0], c[1], c[2]); +} + +//========================================================================== +// +// V_GetColorStringByName +// +// Searches for the given color name in x11r6rgb.txt and returns an +// HTML-ish "#RRGGBB" string for it if found or the empty string if not. +// +//========================================================================== + +FString V_GetColorStringByName(const char* name, FScriptPosition* sc) +{ + FileData rgbNames; + char* rgbEnd; + char* rgb, * endp; + int rgblump; + int c[3], step; + size_t namelen; + + if (fileSystem.GetNumEntries() == 0) return FString(); + + rgblump = fileSystem.CheckNumForName("X11R6RGB"); + if (rgblump == -1) + { + if (!sc) Printf("X11R6RGB lump not found\n"); + else sc->Message(MSG_WARNING, "X11R6RGB lump not found"); + return FString(); + } + + rgbNames = fileSystem.ReadFile(rgblump); + rgb = (char*)rgbNames.GetMem(); + rgbEnd = rgb + fileSystem.FileLength(rgblump); + step = 0; + namelen = strlen(name); + + while (rgb < rgbEnd) + { + // Skip white space + if (*rgb <= ' ') + { + do + { + rgb++; + } while (rgb < rgbEnd && *rgb <= ' '); + } + else if (step == 0 && *rgb == '!') + { // skip comment lines + do + { + rgb++; + } while (rgb < rgbEnd && *rgb != '\n'); + } + else if (step < 3) + { // collect RGB values + c[step++] = strtoul(rgb, &endp, 10); + if (endp == rgb) + { + break; + } + rgb = endp; + } + else + { // Check color name + endp = rgb; + // Find the end of the line + while (endp < rgbEnd && *endp != '\n') + endp++; + // Back up over any whitespace + while (endp > rgb && *endp <= ' ') + endp--; + if (endp == rgb) + { + break; + } + size_t checklen = ++endp - rgb; + if (checklen == namelen && strnicmp(rgb, name, checklen) == 0) + { + FString descr; + descr.Format("#%02x%02x%02x", c[0], c[1], c[2]); + return descr; + } + rgb = endp; + step = 0; + } + } + if (rgb < rgbEnd) + { + if (!sc) Printf("X11R6RGB lump is corrupt\n"); + else sc->Message(MSG_WARNING, "X11R6RGB lump is corrupt"); + } + return FString(); +} + +//========================================================================== +// +// V_GetColor +// +// Works like V_GetColorFromString(), but also understands X11 color names. +// +//========================================================================== + +int V_GetColor(const uint32_t* palette, const char* str, FScriptPosition* sc) +{ + FString string = V_GetColorStringByName(str, sc); + int res; + + if (!string.IsEmpty()) + { + res = V_GetColorFromString(palette, string, sc); + } + else + { + res = V_GetColorFromString(palette, str, sc); + } + return res; +} + +int V_GetColor(const uint32_t* palette, FScanner& sc) +{ + FScriptPosition scc = sc; + return V_GetColor(palette, sc.String, &scc); +} + diff --git a/source/common/utility/palutil.h b/source/common/utility/palutil.h index bda7c3251..089f53526 100644 --- a/source/common/utility/palutil.h +++ b/source/common/utility/palutil.h @@ -3,10 +3,29 @@ #include #include "palentry.h" +struct FScriptPosition; +class FScanner; + int BestColor(const uint32_t* pal, int r, int g, int b, int first = 1, int num = 255); int PTM_BestColor(const uint32_t* pal_in, int r, int g, int b, bool reverselookup, float powtable, int first = 1, int num = 255); void DoBlending(const PalEntry* from, PalEntry* to, int count, int r, int g, int b, int a); + +// Given an array of colors, fills in remap with values to remap the +// passed array of colors to BaseColors. Used for loading palette downconversions of PNGs. +void MakeRemap(uint32_t* BaseColors, const uint32_t* colors, uint8_t* remap, const uint8_t* useful, int numcolors); +void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap); + // Colorspace conversion RGB <-> HSV void RGBtoHSV (float r, float g, float b, float *h, float *s, float *v); void HSVtoRGB (float *r, float *g, float *b, float h, float s, float v); +// Returns the closest color to the one desired. String +// should be of the form "rr gg bb". +int V_GetColorFromString(const uint32_t* palette, const char* colorstring, FScriptPosition* sc = nullptr); +// Scans through the X11R6RGB lump for a matching color +// and returns a color string suitable for V_GetColorFromString. +FString V_GetColorStringByName(const char* name, FScriptPosition* sc = nullptr); + +// Tries to get color by name, then by string +int V_GetColor(const uint32_t* palette, const char* str, FScriptPosition* sc = nullptr); +int V_GetColor(const uint32_t* palette, FScanner& sc); diff --git a/source/core/console/c_bind.cpp b/source/core/console/c_bind.cpp index cc4d5fef3..d70839994 100644 --- a/source/core/console/c_bind.cpp +++ b/source/core/console/c_bind.cpp @@ -158,7 +158,7 @@ const char *KeyNames[NUM_KEYS] = FKeyBindings Bindings; FKeyBindings DoubleBindings; -FKeyBindings AutomapBindings; // this is currently not in use but may be added later. +FKeyBindings AutomapBindings; static unsigned int DClickTime[NUM_KEYS]; static FixedBitArray DClicked; @@ -232,7 +232,7 @@ const char *KeyName (int key) if (KeyNames[key]) return KeyNames[key]; - snprintf (name, countof(name), "Key_%d", key); + mysnprintf (name, countof(name), "Key_%d", key); return name; } @@ -410,11 +410,11 @@ void FKeyBindings::PerformBind(FCommandLine &argv, const char *msg) //============================================================================= // // This function is first called for functions in custom key sections. -// In this case, matchcmd is non-nullptr, and only keys bound to that command +// In this case, matchcmd is non-null, and only keys bound to that command // are stored. If a match is found, its binding is set to "\1". // After all custom key sections are saved, it is called one more for the // normal Bindings and DoubleBindings sections for this game. In this case -// matchcmd is nullptr and all keys will be stored. The config section was not +// matchcmd is null and all keys will be stored. The config section was not // previously cleared, so all old bindings are still in place. If the binding // for a key is empty, the corresponding key in the config is removed as well. // If a binding is "\1", then the binding itself is cleared, but nothing @@ -458,6 +458,32 @@ void FKeyBindings::ArchiveBindings(FConfigFile *f, const char *matchcmd) // //============================================================================= +int FKeyBindings::GetKeysForCommand (const char *cmd, int *first, int *second) +{ + int c, i; + + *first = *second = c = i = 0; + + while (i < NUM_KEYS && c < 2) + { + if (stricmp (cmd, Binds[i]) == 0) + { + if (c++ == 0) + *first = i; + else + *second = i; + } + i++; + } + return c; +} + +//============================================================================= +// +// +// +//============================================================================= + TArray FKeyBindings::GetKeysForCommand (const char *cmd) { int i = 0; @@ -535,7 +561,7 @@ void C_UnbindAll () AutomapBindings.UnbindAll(); } -CCMD (unbindall) +UNSAFE_CCMD (unbindall) { C_UnbindAll (); } @@ -737,21 +763,13 @@ const char* KB_ScanCodeToString(int scancode) return ""; } -int KB_StringToScanCode(const char* string) -{ - for (int i = 0; i < NUM_KEYS; i++) - { - if (KeyNames[i] && !stricmp(string, KeyNames[i])) return i; - } - return 0; -} - void AddCommandString (const char *copy, int keynum); //============================================================================= // // // //============================================================================= + bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds) { FString binding; diff --git a/source/core/console/c_bind.h b/source/core/console/c_bind.h index babfcd5c5..76c911a65 100644 --- a/source/core/console/c_bind.h +++ b/source/core/console/c_bind.h @@ -42,7 +42,6 @@ struct event_t; class FConfigFile; class FCommandLine; -const char* KeyName(int key); void C_NameKeys (char *str, int first, int second); FString C_NameKeys (int *keys, int count, bool colors = false); @@ -54,6 +53,7 @@ public: void PerformBind(FCommandLine &argv, const char *msg); bool DoKey(event_t *ev); void ArchiveBindings(FConfigFile *F, const char *matchcmd = NULL); + int GetKeysForCommand (const char *cmd, int *first, int *second); TArray GetKeysForCommand (const char *cmd); void UnbindACommand (const char *str); void UnbindAll (); @@ -96,10 +96,6 @@ bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds); void C_SetDefaultBindings (); void C_UnbindAll (); -const char* KB_ScanCodeToString(int scancode); // convert scancode into a string -int KB_StringToScanCode(const char* string); // convert a string into a scancode - - extern const char *KeyNames[]; struct FKeyAction @@ -116,13 +112,5 @@ struct FKeySection }; extern TArray KeySections; -struct GameFuncDesc -{ - const char *action; - const char *description; - bool replaced; -}; #endif //__C_BINDINGS_H__ - - diff --git a/source/core/console/c_commandline.h b/source/core/console/c_commandline.h index 54d3ad0a6..88b19cc93 100644 --- a/source/core/console/c_commandline.h +++ b/source/core/console/c_commandline.h @@ -33,13 +33,13 @@ */ class FConfigFile; -struct osdfuncparm_t; +struct CCmdFuncParm; // Class that can parse command lines class FCommandLine { - friend int OSD_RegisterFunction(const char* pszName, const char* pszDesc, int (*func)(osdfuncparm_t const* const)); + friend int C_RegisterFunction(const char* name, const char* help, int (*func)(CCmdFuncParm const* const)); public: FCommandLine (const char *commandline, bool no_escapes = false); ~FCommandLine (); diff --git a/source/core/console/c_con.cpp b/source/core/console/c_con.cpp index 273eca022..d9bcda875 100644 --- a/source/core/console/c_con.cpp +++ b/source/core/console/c_con.cpp @@ -55,6 +55,12 @@ // the new command. // //============================================================================= +struct GameFuncDesc +{ + const char* action; + const char* description; + bool replaced; +}; static GameFuncDesc con_gamefuncs[] = { {"+Move_Forward", "Move_Forward"}, @@ -122,6 +128,8 @@ static GameFuncDesc con_gamefuncs[] = { {"+Toggle_Crouch", "Toggle_Crouch"} }; +const char* KB_ScanCodeToString(int scancode); // convert scancode into a string + //============================================================================= // // diff --git a/source/core/console/c_console.cpp b/source/core/console/c_console.cpp index 13a32a170..32e0f8904 100644 --- a/source/core/console/c_console.cpp +++ b/source/core/console/c_console.cpp @@ -40,7 +40,7 @@ #include "c_console.h" #include "c_cvars.h" #include "c_dispatch.h" -//#include "g_input.h" +#include "gamestate.h" #include "v_text.h" #include "filesystem.h" #include "d_gui.h" @@ -60,18 +60,10 @@ #include "s_soundinternal.h" #include "engineerrors.h" - #define LEFTMARGIN 8 #define RIGHTMARGIN 8 #define BOTTOMARGIN 12 -enum -{ - CONTICRATE = 30, - C_BLINKRATE = (CONTICRATE/2), - -}; - extern bool hud_toggled; void D_ToggleHud(); @@ -107,7 +99,7 @@ int ConWidth; bool vidactive = false; bool cursoron = false; int ConBottom, ConScroll, RowAdjust; -int CursorTicker; +uint64_t CursorTicker; constate_e ConsoleState = c_up; @@ -517,6 +509,7 @@ static int HistSize; struct FNotifyText { int TimeOut; + int Ticker; int PrintLevel; FString Text; }; @@ -545,7 +538,7 @@ CUSTOM_CVAR(Int, con_notifylines, NUMNOTIFIES, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) } -int PrintColors[PRINTLEVELS+2] = { CR_RED, CR_GOLD, CR_YELLOW, CR_GREEN, CR_GREEN, CR_GOLD }; +int PrintColors[PRINTLEVELS+2] = { CR_RED, CR_GOLD, CR_GRAY, CR_GREEN, CR_GREEN, CR_GOLD }; static void setmsgcolor (int index, int color); @@ -639,7 +632,7 @@ void C_InitConsole (int width, int height, bool ingame) // //========================================================================== -CCMD (atexit) +UNSAFE_CCMD (atexit) { if (argv.argc() == 1) { @@ -814,7 +807,8 @@ void FNotifyBuffer::AddString(int printlevel, FString source) FNotifyText newline; newline.Text = line.Text; - newline.TimeOut = int(con_notifytime * CONTICRATE); + newline.TimeOut = int(con_notifytime * GameTicRate); + newline.Ticker = 0; newline.PrintLevel = printlevel; if (AddType == NEWLINE || Text.Size() == 0) { @@ -1034,12 +1028,6 @@ void C_Ticker() } } - if (--CursorTicker <= 0) - { - cursoron ^= 1; - CursorTicker = C_BLINKRATE; - } - lasttic = consoletic; NotifyStrings.Tick(); if (ConsoleState == c_down) @@ -1063,12 +1051,19 @@ void FNotifyBuffer::Tick() unsigned i; for (i = 0; i < Text.Size(); ++i) { - if (Text[i].TimeOut != 0 && --Text[i].TimeOut <= 0) + Text[i].Ticker++; + } + + for (i = 0; i < Text.Size(); ++i) + { + if (Text[i].TimeOut != 0 && Text[i].TimeOut > Text[i].Ticker) break; } - if (i < Text.Size()) + if (i > 0) { Text.Delete(0, i); + FFont* font = generic_ui ? NewSmallFont : AlternativeSmallFont; + Top += font->GetHeight(); } } @@ -1095,7 +1090,7 @@ void FNotifyBuffer::Draw() if (notify.TimeOut == 0) continue; - j = notify.TimeOut; + j = notify.TimeOut - notify.Ticker; if (j > 0) { double alpha = (j < NOTIFYFADETIME) ? 1. * j / NOTIFYFADETIME : 1; @@ -1125,11 +1120,6 @@ void FNotifyBuffer::Draw() } else { - if (canskip) - { - Top += lineadv; - line += lineadv; - } notify.TimeOut = 0; } } @@ -1245,8 +1235,14 @@ void C_DrawConsole () if (ConBottom >= 20) { - //if (gamestate != GS_STARTUP) + if (gamestate != GS_STARTUP) { + auto now = I_msTime(); + if (now > CursorTicker) + { + CursorTicker = now + 500; + cursoron = !cursoron; + } CmdLine.Draw(left, bottomline, textScale, cursoron); } if (RowAdjust && ConBottom >= CurrentConsoleFont->GetHeight()*7/2) @@ -1322,7 +1318,7 @@ void C_ToggleConsole () void C_HideConsole () { - //if (gamestate != GS_FULLCONSOLE) + if (gamestate != GS_FULLCONSOLE) { ConsoleState = c_up; ConBottom = 0; @@ -1716,7 +1712,7 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer) buffer.AppendToYankBuffer = keepappending; // Ensure that the cursor is always visible while typing - CursorTicker = C_BLINKRATE; + CursorTicker = I_msTime() + 500; cursoron = 1; return true; } @@ -1993,7 +1989,7 @@ static void C_TabComplete (bool goForward) else { CmdLineText.Truncate(TabStart); - CmdLineText << TabCommands[TabPos].TabName.GetChars() << " "; + CmdLineText << TabCommands[TabPos].TabName.GetChars() << ' '; } } CmdLine.SetString(CmdLineText); @@ -2077,39 +2073,3 @@ static bool C_TabCompleteList () } return true; } - -// color code format is as follows: -// ^## sets a color, where ## is the palette number -// ^S# sets a shade, range is 0-7 equiv to shades 0-14 -// ^O resets formatting to defaults - -const char * OSD_StripColors(char *outBuf, const char *inBuf) -{ - const char *ptr = outBuf; - - while (*inBuf) - { - if (*inBuf == '^') - { - if (isdigit(*(inBuf+1))) - { - inBuf += 2 + !!isdigit(*(inBuf+2)); - continue; - } - else if ((toupper(*(inBuf+1)) == 'O')) - { - inBuf += 2; - continue; - } - else if ((toupper(*(inBuf+1)) == 'S') && isdigit(*(inBuf+2))) - { - inBuf += 3; - continue; - } - } - *(outBuf++) = *(inBuf++); - } - - *outBuf = '\0'; - return ptr; -} diff --git a/source/core/console/c_cvars.cpp b/source/core/console/c_cvars.cpp index 6ef987d60..d45402af0 100644 --- a/source/core/console/c_cvars.cpp +++ b/source/core/console/c_cvars.cpp @@ -35,17 +35,14 @@ #include #include -#include "c_cvars.h" -#include "configfile.h" - -#include "baselayer.h" -#include "c_console.h" -#include "gamecvars.h" - #include "cmdlib.h" +#include "configfile.h" +#include "c_console.h" #include "c_dispatch.h" +#include "c_cvars.h" +#include "engineerrors.h" #include "printf.h" -#include "quotemgr.h" +#include "palutil.h" struct FLatchedValue @@ -66,6 +63,15 @@ FBaseCVar *CVars = NULL; int cvar_defflags; +static ConsoleCallbacks* callbacks; + +// Install game-specific handlers, mainly to deal with serverinfo and userinfo CVARs. +// This is to keep the console independent of game implementation details for easier reusability. +void C_InstallHandlers(ConsoleCallbacks* cb) +{ + callbacks = cb; +} + FBaseCVar::FBaseCVar (const char *var_name, uint32_t flags, void (*callback)(FBaseCVar &), const char *descr) { if (var_name != nullptr && (flags & CVAR_SERVERINFO)) @@ -74,13 +80,11 @@ FBaseCVar::FBaseCVar (const char *var_name, uint32_t flags, void (*callback)(FBa // for name's length with terminating null character static const size_t NAME_LENGHT_MAX = 63; - /* if (strlen(var_name) > NAME_LENGHT_MAX) { I_FatalError("Name of the server console variable \"%s\" is too long.\n" "Its length should not exceed %zu characters.\n", var_name, NAME_LENGHT_MAX); } - */ } @@ -143,22 +147,23 @@ FBaseCVar::~FBaseCVar () const char *FBaseCVar::GetHumanString(int precision) const { - assert(true); return GetGenericRep(CVAR_String).String; } void FBaseCVar::ForceSet (UCVarValue value, ECVarType type, bool nouserinfosend) { DoSet (value, type); + if ((Flags & CVAR_USERINFO) && !nouserinfosend && !(Flags & CVAR_IGNORE)) + if (callbacks && callbacks->UserInfoChanged) callbacks->UserInfoChanged(this); if (m_UseCallback) Callback (); - if ((Flags & CVAR_ARCHIVE)) + if ((Flags & CVAR_ARCHIVE) && !(Flags & CVAR_UNSAFECONTEXT)) { SafeValue = GetGenericRep(CVAR_String).String; } - Flags &= ~(CVAR_ISDEFAULT); + Flags &= ~(CVAR_ISDEFAULT | CVAR_UNSAFECONTEXT); } void FBaseCVar::SetGenericRep (UCVarValue value, ECVarType type) @@ -167,8 +172,7 @@ void FBaseCVar::SetGenericRep (UCVarValue value, ECVarType type) { return; } -#if 0 - else if ((Flags & CVAR_LATCH) && gamestate != GS_FULLCONSOLE && gamestate != GS_STARTUP) + else if ((Flags & CVAR_LATCH) && callbacks && callbacks->MustLatch()) { FLatchedValue latch; @@ -183,17 +187,10 @@ void FBaseCVar::SetGenericRep (UCVarValue value, ECVarType type) Flags &= ~CVAR_UNSAFECONTEXT; } - else if ((Flags & CVAR_SERVERINFO) && gamestate != GS_STARTUP && !demoplayback) + else if ((Flags & CVAR_SERVERINFO) && callbacks && callbacks->SendServerInfoChange) { - if (netgame && !players[consoleplayer].settings_controller) - { - Printf ("Only setting controllers can change %s\n", Name); - Flags &= ~CVAR_UNSAFECONTEXT; - return; - } - D_SendServerInfoChange (this, value, type); + callbacks->SendServerInfoChange (this, value, type); } -#endif else { ForceSet (value, type); @@ -279,6 +276,7 @@ float FBaseCVar::ToFloat (UCVarValue value, ECVarType type) } static char cstrbuf[40]; +static GUID cGUID; static char truestr[] = "true"; static char falsestr[] = "false"; @@ -743,11 +741,6 @@ void FStringCVar::DoSet (UCVarValue value, ECVarType type) // // Color cvar implementation // -#if 0 -#define APART(c) (((c)>>24)&0xff) -#define RPART(c) (((c)>>16)&0xff) -#define GPART(c) (((c)>>8)&0xff) -#define BPART(c) ((c)&0xff) FColorCVar::FColorCVar (const char *name, int def, uint32_t flags, void (*callback)(FColorCVar &), const char* descr) : FIntCVar (name, def, flags, reinterpret_cast(callback), descr) @@ -779,6 +772,11 @@ void FColorCVar::SetGenericRepDefault (UCVarValue value, ECVarType type) } } +void FColorCVar::DoSet (UCVarValue value, ECVarType type) +{ + Value = ToInt2 (value, type); +} + UCVarValue FColorCVar::FromInt2 (int value, ECVarType type) { if (type == CVAR_String) @@ -796,15 +794,15 @@ int FColorCVar::ToInt2 (UCVarValue value, ECVarType type) { int ret; -#if 0 if (type == CVAR_String) { - FString string; + FString string = V_GetColorStringByName(value.String); // Only allow named colors after the screen exists (i.e. after // we've got some lumps loaded, so X11R6RGB can be read). Since // the only time this might be called before that is when loading // zdoom.ini, this shouldn't be a problem. - if (screen && !(string = V_GetColorStringByName (value.String)).IsEmpty() ) + + if (string.IsNotEmpty()) { ret = V_GetColorFromString (NULL, string); } @@ -814,13 +812,11 @@ int FColorCVar::ToInt2 (UCVarValue value, ECVarType type) } } else -#endif { ret = ToInt (value, type); } return ret; } -#endif // // More base cvar stuff @@ -855,6 +851,10 @@ void FBaseCVar::ResetToDefault () void FBaseCVar::MarkUnsafe() { + if (!(Flags & CVAR_MOD) && UnsafeExecutionContext) + { + Flags |= CVAR_UNSAFECONTEXT; + } } // @@ -940,23 +940,16 @@ void FFlagCVar::DoSet (UCVarValue value, ECVarType type) { bool newval = ToBool (value, type); -#if 0 // Server cvars that get changed by this need to use a special message, because // changes are not processed until the next net update. This is a problem with // exec scripts because all flags will base their changes off of the value of // the "master" cvar at the time the script was run, overriding any changes // another flag might have made to the same cvar earlier in the script. - if ((ValueVar.GetFlags() & CVAR_SERVERINFO) && gamestate != GS_STARTUP && !demoplayback) + if (ValueVar.GetFlags() && callbacks && callbacks->SendServerFlagChange) { - if (netgame && !players[consoleplayer].settings_controller) - { - Printf ("Only setting controllers can change %s\n", Name); - return; - } - D_SendServerFlagChange (&ValueVar, BitNum, newval); + callbacks->SendServerFlagChange(&ValueVar, BitNum, newval, false); } else -#endif { int val = *ValueVar; if (newval) @@ -1044,30 +1037,25 @@ void FMaskCVar::DoSet (UCVarValue value, ECVarType type) { int val = ToInt(value, type) << BitNum; -#if 0 // Server cvars that get changed by this need to use a special message, because // changes are not processed until the next net update. This is a problem with // exec scripts because all flags will base their changes off of the value of // the "master" cvar at the time the script was run, overriding any changes // another flag might have made to the same cvar earlier in the script. - if ((ValueVar.GetFlags() & CVAR_SERVERINFO) && gamestate != GS_STARTUP && !demoplayback) + if (ValueVar.GetFlags() && callbacks && callbacks->SendServerFlagChange) { - if (netgame && !players[consoleplayer].settings_controller) - { - Printf ("Only setting controllers can change %s\n", Name); - return; - } - // Ugh... + // The network interface needs to process each bit separately. + bool silent = false; for(int i = 0; i < 32; i++) { if (BitVal & (1<SendServerFlagChange (&ValueVar, i, !!(val & (1< &cvars, uint32_t filter) // Accumulate all cvars that match the filter flags. for (FBaseCVar *cvar = CVars; cvar != NULL; cvar = cvar->m_Next) { - if ((cvar->Flags & filter)) + if ((cvar->Flags & filter) && !(cvar->Flags & CVAR_IGNORE)) cvars.Push(cvar); } // Now sort them, so they're in a deterministic order and not whatever @@ -1127,7 +1115,7 @@ FString C_GetMassCVarString (uint32_t filter, bool compact) { for (cvar = CVars; cvar != NULL; cvar = cvar->m_Next) { - if ((cvar->Flags & filter) && !(cvar->Flags & (CVAR_NOSAVE))) + if ((cvar->Flags & filter) && !(cvar->Flags & (CVAR_NOSAVE|CVAR_IGNORE))) { UCVarValue val = cvar->GetGenericRep(CVAR_String); dump << '\\' << cvar->GetName() << '\\' << val.String; @@ -1288,6 +1276,24 @@ FBaseCVar *FindCVarSub (const char *var_name, int namelen) return var; } +FBaseCVar *GetCVar(int playernum, const char *cvarname) +{ + FBaseCVar *cvar = FindCVar(cvarname, nullptr); + // Either the cvar doesn't exist, or it's for a mod that isn't loaded, so return nullptr. + if (cvar == nullptr || (cvar->GetFlags() & CVAR_IGNORE)) + { + return nullptr; + } + else + { + // For userinfo cvars, redirect to GetUserCVar + if ((cvar->GetFlags() & CVAR_USERINFO) && callbacks && callbacks->GetUserCVar) + { + return callbacks->GetUserCVar(playernum, cvarname); + } + return cvar; + } +} //=========================================================================== // @@ -1308,7 +1314,7 @@ FBaseCVar *C_CreateCVar(const char *var_name, ECVarType var_type, uint32_t flags case CVAR_Int: return new FIntCVar(var_name, 0, flags); case CVAR_Float: return new FFloatCVar(var_name, 0, flags); case CVAR_String: return new FStringCVar(var_name, NULL, flags); - //case CVAR_Color: return new FColorCVar(var_name, 0, flags); + case CVAR_Color: return new FColorCVar(var_name, 0, flags); default: return NULL; } } @@ -1319,6 +1325,8 @@ void UnlatchCVars (void) { uint32_t oldflags = var.Variable->Flags; var.Variable->Flags &= ~(CVAR_LATCH | CVAR_SERVERINFO); + if (var.UnsafeContext) + var.Variable->Flags |= CVAR_UNSAFECONTEXT; var.Variable->SetGenericRep (var.Value, var.Type); if (var.Type == CVAR_String) delete[] var.Value.String; @@ -1377,7 +1385,7 @@ void C_ArchiveCVars (FConfigFile *f, uint32_t filter) while (cvar) { if ((cvar->Flags & - (CVAR_GLOBALCONFIG|CVAR_ARCHIVE|CVAR_AUTO|CVAR_SERVERINFO|CVAR_USERINFO|CVAR_NOSAVE|CVAR_VIDEOCONFIG)) + (CVAR_GLOBALCONFIG|CVAR_ARCHIVE|CVAR_MOD|CVAR_AUTO|CVAR_USERINFO|CVAR_SERVERINFO|CVAR_NOSAVE|CVAR_CONFIG_ONLY)) == filter) { cvarlist.Push(cvar); @@ -1387,10 +1395,9 @@ void C_ArchiveCVars (FConfigFile *f, uint32_t filter) qsort(cvarlist.Data(), cvarlist.Size(), sizeof(FBaseCVar*), cvarcmp); for (auto cvar : cvarlist) { - // This does not work with the menus at use here. - const char* const value = //(cvar->Flags & CVAR_ISDEFAULT) - /*?*/ cvar->GetGenericRep(CVAR_String).String - /*: cvar->SafeValue.GetChars()*/; + const char* const value = (cvar->Flags & CVAR_ISDEFAULT) + ? cvar->GetGenericRep(CVAR_String).String + : cvar->SafeValue.GetChars(); f->SetValueForKey(cvar->GetName(), value); } } @@ -1399,6 +1406,9 @@ EXTERN_CVAR(Bool, sv_cheats); void FBaseCVar::CmdSet (const char *newval) { + if ((GetFlags() & CVAR_CHEAT) && CheckCheatmode ()) + return; + MarkUnsafe(); UCVarValue val; @@ -1491,23 +1501,8 @@ CCMD (toggle) val = var->GetGenericRep (CVAR_Bool); val.Bool = !val.Bool; var->SetGenericRep (val, CVAR_Bool); - const char *statestr = argv.argc() <= 2? "*" : argv[2]; - if (*statestr == '*') - { - gi->PrintMessage(PRINT_MEDIUM, "\"%s\" = \"%s\"\n", var->GetName(), val.Bool ? "true" : "false"); - } - else - { - int state = (int)strtoll(argv[2], nullptr, 0); - if (state != 0) - { - // Order of Duke's quote string varies, some have on first, some off, so use the sign of the parameter to decide. - // Positive means Off/On, negative means On/Off - int quote = state > 0? state + val.Bool : -(state + val.Bool); - auto text = quoteMgr.GetQuote(quote); - if (text) gi->PrintMessage(PRINT_MEDIUM, "%s\n", text); - } - } + Printf ("\"%s\" = \"%s\"\n", var->GetName(), + val.Bool ? "true" : "false"); } } } @@ -1533,7 +1528,7 @@ void FBaseCVar::ListVars (const char *filter, bool plain) else { ++count; - Printf ("%c%c%c %s = %s\n", + Printf ("%c%c%c%c%c %s = %s\n", flags & CVAR_ARCHIVE ? 'A' : ' ', flags & CVAR_USERINFO ? 'U' : flags & CVAR_SERVERINFO ? 'S' : @@ -1541,6 +1536,8 @@ void FBaseCVar::ListVars (const char *filter, bool plain) flags & CVAR_NOSET ? '-' : flags & CVAR_LATCH ? 'L' : flags & CVAR_UNSETTABLE ? '*' : ' ', + flags & CVAR_MOD ? 'M' : ' ', + flags & CVAR_IGNORE ? 'X' : ' ', var->GetName(), var->GetHumanString()); } @@ -1584,3 +1581,4 @@ CCMD (archivecvar) } } } + diff --git a/source/core/console/c_cvars.h b/source/core/console/c_cvars.h index aefec9ed8..37ae5903d 100644 --- a/source/core/console/c_cvars.h +++ b/source/core/console/c_cvars.h @@ -36,6 +36,7 @@ #include "zstring.h" #include "tarray.h" +class FSerializer; // this needs to go away. /* ========================================================== @@ -46,30 +47,29 @@ CVARS (console variables) enum { - CVAR_ARCHIVE = 1, // set to cause it to be saved to config - CVAR_USERINFO = 2, // added to userinfo when changed - CVAR_SERVERINFO = 4, // added to serverinfo when changed - CVAR_NOSET = 8, // don't allow change from console at all, - // but can be set from the command line - CVAR_LATCH = 16, // save changes until server restart - CVAR_UNSETTABLE = 32, // can unset this var from console - CVAR_DEMOSAVE = 64, // save the value of this cvar in a demo - CVAR_ISDEFAULT = 128, // is cvar unchanged since creation? - CVAR_NOSAVE = 256, // when used with CVAR_SERVERINFO, do not save var to savegame - CVAR_NOINITCALL = 512, // don't call callback at game start - CVAR_GLOBALCONFIG = 1024, // cvar is saved to global config section - CVAR_VIDEOCONFIG = 2048, // cvar is saved to video config section (not implemented) - CVAR_AUTO = 4096, // allocated; needs to be freed when destroyed - //CVAR_MOD = 8192, // cvar was defined by a mod - //CVAR_IGNORE = 16384,// do not send cvar across the network/inaccesible from ACS (dummy mod cvar) - //CVAR_CHEAT = 32768,// can be set only when sv_cheats is enabled - //CVAR_UNSAFECONTEXT = 65536,// cvar value came from unsafe context - CVAR_VIRTUAL = 0x20000, //do not invoke the callback recursively so it can - CVAR_FRONTEND_BLOOD = 0x10000000, // To mark frontend specific CVARs, so that the other ones can disable them. - CVAR_FRONTEND_EDUKE = 0x20000000, - CVAR_FRONTEND_DUKELIKE = 0x30000000, - CVAR_FRONTEND_REDNUKEM = 0x40000000, - CVAR_FRONTEND_SHADOWWARRIOR = 0x80000000, + CVAR_ARCHIVE = 1, // set to cause it to be saved to config. + CVAR_USERINFO = 1 << 1, // added to userinfo when changed. + CVAR_SERVERINFO = 1 << 2, // added to serverinfo when changed. + CVAR_NOSET = 1 << 3, // don't allow change from console at all, + // but can be set from the command line. + CVAR_LATCH = 1 << 4, // save changes until server restart. + CVAR_UNSETTABLE = 1 << 5, // can unset this var from console. + CVAR_DEMOSAVE = 1 << 6, // save the value of this cvar in a demo. + CVAR_ISDEFAULT = 1 << 7, // is cvar unchanged since creation? + CVAR_AUTO = 1 << 8, // allocated; needs to be freed when destroyed. + CVAR_NOINITCALL = 1 << 9, // don't call callback at game start. + CVAR_GLOBALCONFIG = 1 << 10, // cvar is saved to global config section. + CVAR_VIDEOCONFIG = 1 << 11, // cvar is saved to video config section (not implemented). + CVAR_NOSAVE = 1 << 12, // when used with CVAR_SERVERINFO, do not save var to savegame + // and config. + CVAR_MOD = 1 << 13, // cvar was defined by a mod. + CVAR_IGNORE = 1 << 14, // do not send cvar across the network/inaccesible from ACS + // (dummy mod cvar). + CVAR_CHEAT = 1 << 15, // can be set only when sv_cheats is enabled. + CVAR_UNSAFECONTEXT = 1 << 16, // cvar value came from unsafe context. + CVAR_VIRTUAL = 1 << 17, // do not invoke the callback recursively so it can be used to + // mirror an external variable. + CVAR_CONFIG_ONLY = 1 << 18, // do not save var to savegame and do not send it across network. }; union UCVarValue @@ -102,6 +102,20 @@ class FConfigFile; class FxCVar; +class FBaseCVar; + +// These are calls into the game code. Having these hard coded in the CVAR implementation has always been the biggest blocker +// for reusing the CVAR module outside of ZDoom. So now they get called through this struct for easier reusability. +struct ConsoleCallbacks +{ + void (*UserInfoChanged)(FBaseCVar*); + void (*SendServerInfoChange)(FBaseCVar* cvar, UCVarValue value, ECVarType type); + void (*SendServerFlagChange)(FBaseCVar* cvar, int bitnum, bool set, bool silent); + FBaseCVar* (*GetUserCVar)(int playernum, const char* cvarname); + bool (*MustLatch)(); + +}; + class FBaseCVar { public: @@ -128,6 +142,7 @@ public: void ResetToDefault (); void SetArchiveBit () { Flags |= CVAR_ARCHIVE; } void MarkUnsafe(); + void MarkSafe() { Flags &= ~CVAR_UNSAFECONTEXT; } int ToInt() { @@ -186,7 +201,9 @@ private: static bool m_UseCallback; static bool m_DoNoSet; + // These need to go away! friend FString C_GetMassCVarString (uint32_t filter, bool compact); + friend void C_SerializeCVars(FSerializer& arc, const char* label, uint32_t filter); friend void C_ReadCVars (uint8_t **demo_p); friend void C_BackupCVars (void); friend FBaseCVar *FindCVar (const char *var_name, FBaseCVar **prev); @@ -210,6 +227,8 @@ void C_WriteCVars (uint8_t **demo_p, uint32_t filter, bool compact=false); // Read all cvars from *demo_p and set them appropriately. void C_ReadCVars (uint8_t **demo_p); +void C_InstallHandlers(ConsoleCallbacks* cb); + // Backup demo cvars. Called before a demo starts playing to save all // cvars the demo might change. void C_BackupCVars (void); @@ -218,6 +237,9 @@ void C_BackupCVars (void); FBaseCVar *FindCVar (const char *var_name, FBaseCVar **prev); FBaseCVar *FindCVarSub (const char *var_name, int namelen); +// Used for ACS and DECORATE. +FBaseCVar *GetCVar(int playernum, const char *cvarname); + // Create a new cvar with the specified name and type FBaseCVar *C_CreateCVar(const char *var_name, ECVarType var_type, uint32_t flags); @@ -259,10 +281,8 @@ public: protected: virtual void DoSet (UCVarValue value, ECVarType type); - // int is needed as long as this needs to connect to the menus -public: // also for the menu code which still needs variable references. (Cannot change everything at once.) - int/*bool*/ Value; - int/*bool*/ DefaultValue; + bool Value; + bool DefaultValue; }; class FIntCVar : public FBaseCVar @@ -287,7 +307,6 @@ public: protected: virtual void DoSet (UCVarValue value, ECVarType type); -public: // for the menu code which still needs variable references. (Cannot change everything at once.) int Value; int DefaultValue; @@ -317,7 +336,6 @@ public: protected: virtual void DoSet (UCVarValue value, ECVarType type) override; -public: // for the menu code which still needs variable references. (Cannot change everything at once.) float Value; float DefaultValue; }; @@ -349,7 +367,6 @@ protected: FString mDefaultValue; }; -#if 0 class FColorCVar : public FIntCVar { friend class FxCVar; @@ -371,7 +388,6 @@ protected: static UCVarValue FromInt2 (int value, ECVarType type); static int ToInt2 (UCVarValue value, ECVarType type); }; -#endif class FFlagCVar : public FBaseCVar { @@ -449,6 +465,11 @@ void C_ForgetCVars (void); F##type##CVar name (#name, def, flags, cvarfunc_##name); \ static void cvarfunc_##name(F##type##CVar &self) +#define CUSTOM_CVAR_NAMED(type,name,cname,def,flags) \ + static void cvarfunc_##name(F##type##CVar &); \ + F##type##CVar name (#cname, def, flags, cvarfunc_##name); \ + static void cvarfunc_##name(F##type##CVar &self) + #define CVAR(type,name,def,flags) \ F##type##CVar name (#name, def, flags); diff --git a/source/core/console/c_dispatch.cpp b/source/core/console/c_dispatch.cpp index 42d3c5480..fc10898f2 100644 --- a/source/core/console/c_dispatch.cpp +++ b/source/core/console/c_dispatch.cpp @@ -40,24 +40,18 @@ #include #include "templates.h" -//#include "doomtype.h" #include "cmdlib.h" #include "c_console.h" #include "c_dispatch.h" #include "m_argv.h" -//#include "g_game.h" -//#include "d_player.h" +#include "gamestate.h" #include "configfile.h" #include "printf.h" #include "c_cvars.h" -#include "v_text.h" -#include "inputstate.h" #include "c_buttons.h" -//#include "d_net.h" -//#include "d_main.h" -//#include "serializer.h" -//#include "menu/menu.h" -//#include "g_levellocals.h" +// Todo: Get rid of +#include "inputstate.h" +bool D_AddFile(TArray& wadfiles, const char* file, bool check = true, int position = -1); // MACROS ------------------------------------------------------------------ @@ -77,14 +71,15 @@ protected: class FWaitingCommand : public FDelayedCommand { public: - FWaitingCommand(const char *cmd, int tics) - : Command(cmd), TicsLeft(tics+1) + FWaitingCommand(const char *cmd, int tics, bool unsafe) + : Command(cmd), TicsLeft(tics+1), IsUnsafe(unsafe) {} bool Tick() override { if (--TicsLeft == 0) { + UnsafeExecutionScope scope(IsUnsafe); AddCommandString(Command); return true; } @@ -93,6 +88,7 @@ public: FString Command; int TicsLeft; + bool IsUnsafe; }; class FStoredCommand : public FDelayedCommand @@ -107,7 +103,7 @@ public: if (Text.IsNotEmpty() && Command != nullptr) { FCommandLine args(Text); - Command->Run(args, /*current player*/nullptr, 0); + Command->Run(args, 0); } return true; } @@ -172,14 +168,28 @@ static FConsoleCommand *ScanChainForName (FConsoleCommand *start, const char *na // EXTERNAL DATA DECLARATIONS ---------------------------------------------- // PUBLIC DATA DEFINITIONS ------------------------------------------------- +bool ParsingKeyConf, UnsafeExecutionContext; +FString StoredWarp; + +FConsoleCommand* Commands[FConsoleCommand::HASH_SIZE]; CVAR (Bool, lookspring, true, CVAR_ARCHIVE); // Generate centerview when -mlook encountered? -FConsoleCommand *Commands[FConsoleCommand::HASH_SIZE]; - - // PRIVATE DATA DEFINITIONS ------------------------------------------------ +static const char *KeyConfCommands[] = +{ + "alias", + "defaultbind", + "addkeysection", + "addmenukey", + "addslotdefault", + "weaponsection", + "setslot", + "addplayerclass", + "clearplayerclasses" +}; + // CODE -------------------------------------------------------------------- void C_DoCommand (const char *cmd, int keynum) @@ -207,6 +217,25 @@ void C_DoCommand (const char *cmd, int keynum) const size_t len = end - beg; + if (ParsingKeyConf) + { + int i; + + for (i = countof(KeyConfCommands)-1; i >= 0; --i) + { + if (strnicmp (beg, KeyConfCommands[i], len) == 0 && + KeyConfCommands[i][len] == 0) + { + break; + } + } + if (i < 0) + { + Printf ("Invalid command for KEYCONF: %s\n", beg); + return; + } + } + // Check if this is an action if (*beg == '+' || *beg == '-') { @@ -238,23 +267,24 @@ void C_DoCommand (const char *cmd, int keynum) if ( (com = FindNameInHashTable (Commands, beg, len)) ) { - if (//gamestate != GS_STARTUP || + if (gamestate != GS_STARTUP || ParsingKeyConf || (len == 3 && strnicmp (beg, "set", 3) == 0) || (len == 7 && strnicmp (beg, "logfile", 7) == 0) || (len == 9 && strnicmp (beg, "unbindall", 9) == 0) || (len == 4 && strnicmp (beg, "bind", 4) == 0) || (len == 4 && strnicmp (beg, "exec", 4) == 0) || - (len ==10 && strnicmp (beg, "doublebind", 10) == 0) + (len ==10 && strnicmp (beg, "doublebind", 10) == 0) || + (len == 6 && strnicmp (beg, "pullin", 6) == 0) ) { FCommandLine args (beg); - com->Run (args, /*current player*/nullptr, keynum); + com->Run (args, keynum); } else { if (len == 4 && strnicmp(beg, "warp", 4) == 0) { - //StoredWarp = beg; + StoredWarp = beg; } else { @@ -326,7 +356,8 @@ void AddCommandString (const char *text, int keynum) cmd++; if (*cmd) { - if (cmd[0] == 'w' && cmd[1] == 'a' && cmd[2] == 'i' && cmd[3] == 't' && + if (!ParsingKeyConf && + cmd[0] == 'w' && cmd[1] == 'a' && cmd[2] == 'i' && cmd[3] == 't' && (cmd[4] == 0 || cmd[4] == ' ')) { int tics; @@ -346,7 +377,7 @@ void AddCommandString (const char *text, int keynum) // Note that deferred commands lose track of which key // (if any) they were pressed from. *brkpt = ';'; - auto cmd = new FWaitingCommand(brkpt, tics); + auto cmd = new FWaitingCommand(brkpt, tics, UnsafeExecutionContext); delayedCommandQueue.AddCommand(cmd); } return; @@ -473,9 +504,20 @@ FConsoleCommand::~FConsoleCommand () C_RemoveTabCommand (m_Name); } -void FConsoleCommand::Run (FCommandLine &argv, void *who, int key) +void FConsoleCommand::Run(FCommandLine &argv, int key) { - m_RunFunc (argv, who, key); + m_RunFunc (argv, key); +} + +void FUnsafeConsoleCommand::Run(FCommandLine &args, int key) +{ + if (UnsafeExecutionContext) + { + Printf(TEXTCOLOR_RED "Cannot execute unsafe command " TEXTCOLOR_GOLD "%s\n", m_Name); + return; + } + + FConsoleCommand::Run (args, key); } FConsoleAlias::FConsoleAlias (const char *name, const char *command, bool noSave) @@ -555,6 +597,11 @@ FString BuildString (int argc, FString *argv) // //=========================================================================== +void FConsoleCommand::PrintCommand() +{ + Printf("%s\n", m_Name.GetChars()); +} + FString SubstituteAliasParams (FString &command, FCommandLine &args) { // Do substitution by replacing %x with the argument x. @@ -790,7 +837,7 @@ CCMD (alias) { if (alias->IsAlias ()) { - static_cast (alias)->Realias (argv[2], false); + static_cast (alias)->Realias (argv[2], ParsingKeyConf); } else { @@ -798,6 +845,10 @@ CCMD (alias) alias = NULL; } } + else if (ParsingKeyConf) + { + new FUnsafeConsoleAlias (argv[1], argv[2]); + } else { new FConsoleAlias (argv[1], argv[2], false); @@ -864,11 +915,6 @@ FExecList *C_ParseCmdLineParams(FExecList *exec) return exec; } -void FConsoleCommand::PrintCommand() -{ - Printf("%s\n", m_Name.GetChars()); -} - bool FConsoleCommand::IsAlias () { return false; @@ -879,7 +925,7 @@ bool FConsoleAlias::IsAlias () return true; } -void FConsoleAlias::Run (FCommandLine &args, void *who, int key) +void FConsoleAlias::Run (FCommandLine &args, int key) { if (bRunning) { @@ -942,10 +988,24 @@ void FConsoleAlias::SafeDelete () } } +void FUnsafeConsoleAlias::Run (FCommandLine &args, int key) +{ + UnsafeExecutionScope scope; + FConsoleAlias::Run(args, key); +} + void FExecList::AddCommand(const char *cmd, const char *file) { + // Pullins are special and need to be separated from general commands. + // They also turned out to be a really bad idea, since they make things + // more complicated. :( + if (file != NULL && strnicmp(cmd, "pullin", 6) == 0 && isspace(cmd[6])) + { + FCommandLine line(cmd); + C_SearchForPullins(this, file, line); + } // Recursive exec: Parse this file now. - if (strnicmp(cmd, "exec", 4) == 0 && isspace(cmd[4])) + else if (strnicmp(cmd, "exec", 4) == 0 && isspace(cmd[4])) { FCommandLine argv(cmd); for (int i = 1; i < argv.argc(); ++i) @@ -967,6 +1027,14 @@ void FExecList::ExecCommands() const } } +void FExecList::AddPullins(TArray &wads) const +{ + for (unsigned i = 0; i < Pullins.Size(); ++i) + { + D_AddFile(wads, Pullins[i]); + } +} + FExecList *C_ParseExecFile(const char *file, FExecList *exec) { char cmd[4096]; @@ -1026,25 +1094,61 @@ bool C_ExecFile (const char *file) if (exec != NULL) { exec->ExecCommands(); + if (exec->Pullins.Size() > 0) + { + Printf(TEXTCOLOR_BOLD "Notice: Pullin files were ignored.\n"); + } delete exec; } return exec != NULL; } -#include "osd.h" +void C_SearchForPullins(FExecList *exec, const char *file, FCommandLine &argv) +{ + const char *lastSlash; + + assert(exec != NULL); + assert(file != NULL); +#ifdef __unix__ + lastSlash = strrchr(file, '/'); +#else + const char *lastSlash1, *lastSlash2; + + lastSlash1 = strrchr(file, '/'); + lastSlash2 = strrchr(file, '\\'); + lastSlash = MAX(lastSlash1, lastSlash2); +#endif + + for (int i = 1; i < argv.argc(); ++i) + { + // Try looking for the wad in the same directory as the .cfg + // before looking for it in the current directory. + if (lastSlash != NULL) + { + FString path(file, (lastSlash - file) + 1); + path += argv[i]; + if (FileExists(path)) + { + exec->Pullins.Push(path); + continue; + } + } + exec->Pullins.Push(argv[i]); + } +} static TArray dynccmds; // This needs to be explicitly deleted before shutdown - the names in here may not be valid during the exit handler. // -// OSD_RegisterFunction() -- Reroutes a Bulid-style CCMD to the new console. +// C_RegisterFunction() -- dynamically register a CCMD. // -int OSD_RegisterFunction(const char* pszName, const char* pszDesc, int (*func)(osdcmdptr_t)) +int C_RegisterFunction(const char* pszName, const char* pszDesc, int (*func)(CCmdFuncPtr)) { FString nname = pszName; - auto callback = [nname, pszDesc, func](FCommandLine& args, void *, int key) + auto callback = [nname, pszDesc, func](FCommandLine& args, int key) { if (args.argc() > 0) args.operator[](0); - osdfuncparm_t param = { args.argc() - 1, nname.GetChars(), (const char**)args._argv + 1, args.cmd }; - if (func(¶m) != OSDCMD_OK) + CCmdFuncParm param = { args.argc() - 1, nname.GetChars(), (const char**)args._argv + 1, args.cmd }; + if (func(¶m) != CCMD_OK) { Printf("%s\n", pszDesc); } @@ -1064,43 +1168,10 @@ void C_ClearDynCCmds() dynccmds.Clear(); } -CCMD (quit) +CCMD (pullin) { - throw CExitEvent(0); + // Actual handling for pullin is now completely special-cased above + Printf (TEXTCOLOR_BOLD "Pullin" TEXTCOLOR_NORMAL " is only valid from .cfg\n" + "files and only when used at startup.\n"); } -CCMD (exit) -{ - throw CExitEvent(0); -} - -extern FILE* Logfile; -void execLogfile(const char* fn, bool append) -{ - if ((Logfile = fopen(fn, append ? "a" : "w"))) - { - const char* timestr = myasctime(); - Printf("Log started: %s\n", timestr); - } - else - { - Printf("Could not start log\n"); - } -} - -CCMD(logfile) -{ - - if (Logfile) - { - const char* timestr = myasctime(); - Printf("Log stopped: %s\n", timestr); - fclose(Logfile); - Logfile = NULL; - } - - if (argv.argc() >= 2) - { - execLogfile(argv[1], argv.argc() >= 3 ? !!argv[2] : false); - } -} diff --git a/source/core/console/c_dispatch.h b/source/core/console/c_dispatch.h index 40004f2b7..b1f5e6564 100644 --- a/source/core/console/c_dispatch.h +++ b/source/core/console/c_dispatch.h @@ -34,23 +34,30 @@ #ifndef __C_DISPATCH_H__ #define __C_DISPATCH_H__ +#include #include #include "c_console.h" -#include "zstring.h" +#include "tarray.h" #include "c_commandline.h" #include "zstring.h" class FConfigFile; + // Contains the contents of an exec'ed file struct FExecList { TArray Commands; + TArray Pullins; - void AddCommand(const char *cmd, const char *file = NULL); + void AddCommand(const char *cmd, const char *file = nullptr); void ExecCommands() const; + void AddPullins(TArray &wads) const; }; +extern bool ParsingKeyConf, UnsafeExecutionContext; +extern FString StoredWarp; // [RH] +warp at the command line + extern bool CheckCheatmode (bool printmsg = true); @@ -69,6 +76,7 @@ void C_ClearDelayedCommands(); void C_DoCommand (const char *cmd, int keynum=0); FExecList *C_ParseExecFile(const char *file, FExecList *source); +void C_SearchForPullins(FExecList *exec, const char *file, class FCommandLine &args); bool C_ExecFile(const char *file); void C_ClearDynCCmds(); @@ -81,7 +89,7 @@ void C_ClearAliases (); // build a single string out of multiple strings FString BuildString (int argc, FString *argv); -typedef std::function CCmdRun;; +typedef std::function CCmdRun;; class FConsoleCommand { @@ -91,7 +99,7 @@ public: virtual bool IsAlias (); void PrintCommand(); - virtual void Run (FCommandLine &args, void *instigator, int key); + virtual void Run (FCommandLine &args, int key); static FConsoleCommand* FindByName (const char* name); FConsoleCommand *m_Next, **m_Prev; @@ -108,9 +116,25 @@ protected: }; #define CCMD(n) \ - void Cmd_##n (FCommandLine &, void *, int key); \ + void Cmd_##n (FCommandLine &, int key); \ FConsoleCommand Cmd_##n##_Ref (#n, Cmd_##n); \ - void Cmd_##n (FCommandLine &argv, void *who, int key) + void Cmd_##n (FCommandLine &argv, int key) + +class FUnsafeConsoleCommand : public FConsoleCommand +{ +public: + FUnsafeConsoleCommand (const char *name, CCmdRun RunFunc) + : FConsoleCommand (name, RunFunc) + { + } + + virtual void Run (FCommandLine &args, int key) override; +}; + +#define UNSAFE_CCMD(n) \ + static void Cmd_##n (FCommandLine &, int key); \ + static FUnsafeConsoleCommand Cmd_##n##_Ref (#n, Cmd_##n); \ + void Cmd_##n (FCommandLine &argv, int key) const int KEY_DBLCLICKED = 0x8000; @@ -119,7 +143,7 @@ class FConsoleAlias : public FConsoleCommand public: FConsoleAlias (const char *name, const char *command, bool noSave); ~FConsoleAlias (); - void Run (FCommandLine &args, void *instigator, int key); + void Run (FCommandLine &args, int key); bool IsAlias (); void PrintAlias (); void Archive (FConfigFile *f); @@ -140,10 +164,51 @@ public: { } - virtual void Run (FCommandLine &args, void *instigator, int key) override; + virtual void Run (FCommandLine &args, int key) override; }; +class UnsafeExecutionScope +{ + const bool wasEnabled; + +public: + explicit UnsafeExecutionScope(const bool enable = true) + : wasEnabled(UnsafeExecutionContext) + { + UnsafeExecutionContext = enable; + } + + ~UnsafeExecutionScope() + { + UnsafeExecutionContext = wasEnabled; + } +}; + + void execLogfile(const char *fn, bool append = false); +enum +{ + CCMD_OK = 0, + CCMD_SHOWHELP = 1 +}; + +struct CCmdFuncParm +{ + int32_t numparms; + const char* name; + const char** parms; + const char* raw; +}; + +using CCmdFuncPtr = CCmdFuncParm const* const; + +// registers a function +// name = name of the function +// help = a short help string +// func = the entry point to the function +int C_RegisterFunction(const char* name, const char* help, int (*func)(CCmdFuncPtr)); + + #endif //__C_DISPATCH_H__ diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index aa668a8b4..22fbf48cf 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -58,6 +58,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "glbackend/glbackend.h" #include "engineerrors.h" #include "mmulti.h" +#include "gamestate.h" // The last remains of sdlayer.cpp double g_beforeSwapTime; @@ -73,6 +74,8 @@ MapRecord *currentLevel; // level that is currently played. (The real level, not MapRecord* lastLevel; // Same here, for the last level. MapRecord userMapRecord; // stand-in for the user map. +gamestate_t gamestate = GS_STARTUP; + FILE* hashfile; FStartupInfo RazeStartupInfo; @@ -691,7 +694,7 @@ int RunGame() InitStatistics(); M_Init(); SetDefaultStrings(); - if (g_gameType & (GAMEFLAG_RR|GAMEFLAG_RRRA)) InitRREndMap(); // this needs to be done better later + if (g_gameType & (GAMEFLAG_RR)) InitRREndMap(); // this needs to be done better later if (Args->CheckParm("-sounddebug")) C_DoCommand("stat sounddebug"); @@ -705,6 +708,7 @@ int RunGame() auto exec = C_ParseCmdLineParams(nullptr); if (exec) exec->ExecCommands(); + gamestate = GS_LEVEL; return gi->app_main(); } @@ -869,3 +873,85 @@ CCMD(printinterface) { Printf("Current interface is %s\n", gi->Name()); } + +CCMD (togglemsg) +{ + FBaseCVar *var, *prev; + UCVarValue val; + + if (argv.argc() > 1) + { + if ( (var = FindCVar (argv[1], &prev)) ) + { + var->MarkUnsafe(); + + val = var->GetGenericRep (CVAR_Bool); + val.Bool = !val.Bool; + var->SetGenericRep (val, CVAR_Bool); + const char *statestr = argv.argc() <= 2? "*" : argv[2]; + if (*statestr == '*') + { + gi->PrintMessage(PRINT_MEDIUM, "\"%s\" = \"%s\"\n", var->GetName(), val.Bool ? "true" : "false"); + } + else + { + int state = (int)strtoll(argv[2], nullptr, 0); + if (state != 0) + { + // Order of Duke's quote string varies, some have on first, some off, so use the sign of the parameter to decide. + // Positive means Off/On, negative means On/Off + int quote = state > 0? state + val.Bool : -(state + val.Bool); + auto text = quoteMgr.GetQuote(quote); + if (text) gi->PrintMessage(PRINT_MEDIUM, "%s\n", text); + } + } + } + } +} + +CCMD(quit) +{ + throw CExitEvent(0); +} + +CCMD(exit) +{ + throw CExitEvent(0); +} + +extern FILE* Logfile; +void execLogfile(const char* fn, bool append) +{ + if ((Logfile = fopen(fn, append ? "a" : "w"))) + { + const char* timestr = myasctime(); + Printf("Log started: %s\n", timestr); + } + else + { + Printf("Could not start log\n"); + } +} + +CCMD(logfile) +{ + + if (Logfile) + { + const char* timestr = myasctime(); + Printf("Log stopped: %s\n", timestr); + fclose(Logfile); + Logfile = NULL; + } + + if (argv.argc() >= 2) + { + execLogfile(argv[1], argv.argc() >= 3 ? !!argv[2] : false); + } +} + +// Just a placeholder for now. +bool CheckCheatmode(bool printmsg) +{ + return false; +} diff --git a/source/core/gamecvars.cpp b/source/core/gamecvars.cpp index b09bc46f6..4df44c21c 100644 --- a/source/core/gamecvars.cpp +++ b/source/core/gamecvars.cpp @@ -47,6 +47,9 @@ #include "gstrings.h" #include "quotemgr.h" +#define CVAR_FRONTEND_BLOOD 0 +#define CVAR_FRONTEND_DUKELIKE 0 + /* Notes RedNukem has this for the toggle autorun command. Todo: Check what this is supposed to accomplish. The implementation makes no sense at all. @@ -444,6 +447,43 @@ bool G_AllowAutoload() return true; } + +// color code format is as follows: +// ^## sets a color, where ## is the palette number +// ^S# sets a shade, range is 0-7 equiv to shades 0-14 +// ^O resets formatting to defaults + +static const char* OSD_StripColors(char* outBuf, const char* inBuf) +{ + const char* ptr = outBuf; + + while (*inBuf) + { + if (*inBuf == '^') + { + if (isdigit(*(inBuf + 1))) + { + inBuf += 2 + !!isdigit(*(inBuf + 2)); + continue; + } + else if ((toupper(*(inBuf + 1)) == 'O')) + { + inBuf += 2; + continue; + } + else if ((toupper(*(inBuf + 1)) == 'S') && isdigit(*(inBuf + 2))) + { + inBuf += 3; + continue; + } + } + *(outBuf++) = *(inBuf++); + } + + *outBuf = '\0'; + return ptr; +} + CVAR(Bool, adult_lockout, false, CVAR_ARCHIVE) CUSTOM_CVAR(String, playername, "Player", CVAR_ARCHIVE | CVAR_USERINFO) { diff --git a/source/core/gamestate.h b/source/core/gamestate.h new file mode 100644 index 000000000..112592f41 --- /dev/null +++ b/source/core/gamestate.h @@ -0,0 +1,23 @@ +#pragma once + +// The current state of the game: whether we are +// playing, gazing at the intermission screen, +// the game final animation, or a demo. +enum gamestate_t : int +{ + GS_LEVEL, + GS_INTERMISSION, + GS_FINALE, + GS_DEMOSCREEN, + GS_FULLCONSOLE, // [RH] Fullscreen console + GS_HIDECONSOLE, // [RH] The menu just did something that should hide fs console + GS_STARTUP, // [RH] Console is fullscreen, and game is just starting + GS_TITLELEVEL, // [RH] A combination of GS_LEVEL and GS_DEMOSCREEN + + GS_FORCEWIPE = -1, + GS_FORCEWIPEFADE = -2, + GS_FORCEWIPEBURN = -3, + GS_FORCEWIPEMELT = -4 +}; + +extern gamestate_t gamestate; diff --git a/source/core/initfs.cpp b/source/core/initfs.cpp index dfcdddb41..d8a07d144 100644 --- a/source/core/initfs.cpp +++ b/source/core/initfs.cpp @@ -45,6 +45,7 @@ #include "v_video.h" #include "v_text.h" #include "findfile.h" +#include "palutil.h" #ifndef PATH_MAX #define PATH_MAX 260 diff --git a/source/core/rendering/v_video.cpp b/source/core/rendering/v_video.cpp index aafdf868f..c60ff82e6 100644 --- a/source/core/rendering/v_video.cpp +++ b/source/core/rendering/v_video.cpp @@ -254,225 +254,6 @@ void DCanvas::Resize(int width, int height, bool optimizepitch) } -//========================================================================== -// -// V_GetColorFromString -// -// Passed a string of the form "#RGB", "#RRGGBB", "R G B", or "RR GG BB", -// returns a number representing that color. If palette is non-NULL, the -// index of the best match in the palette is returned, otherwise the -// RRGGBB value is returned directly. -// -//========================================================================== - -int V_GetColorFromString (const uint32_t *palette, const char *cstr, FScriptPosition *sc) -{ - int c[3], i, p; - char val[3]; - - val[2] = '\0'; - - // Check for HTML-style #RRGGBB or #RGB color string - if (cstr[0] == '#') - { - size_t len = strlen (cstr); - - if (len == 7) - { - // Extract each eight-bit component into c[]. - for (i = 0; i < 3; ++i) - { - val[0] = cstr[1 + i*2]; - val[1] = cstr[2 + i*2]; - c[i] = ParseHex (val, sc); - } - } - else if (len == 4) - { - // Extract each four-bit component into c[], expanding to eight bits. - for (i = 0; i < 3; ++i) - { - val[1] = val[0] = cstr[1 + i]; - c[i] = ParseHex (val, sc); - } - } - else - { - // Bad HTML-style; pretend it's black. - c[2] = c[1] = c[0] = 0; - } - } - else - { - if (strlen(cstr) == 6) - { - char *p; - int color = strtol(cstr, &p, 16); - if (*p == 0) - { - // RRGGBB string - c[0] = (color & 0xff0000) >> 16; - c[1] = (color & 0xff00) >> 8; - c[2] = (color & 0xff); - } - else goto normal; - } - else - { -normal: - // Treat it as a space-delimited hexadecimal string - for (i = 0; i < 3; ++i) - { - // Skip leading whitespace - while (*cstr <= ' ' && *cstr != '\0') - { - cstr++; - } - // Extract a component and convert it to eight-bit - for (p = 0; *cstr > ' '; ++p, ++cstr) - { - if (p < 2) - { - val[p] = *cstr; - } - } - if (p == 0) - { - c[i] = 0; - } - else - { - if (p == 1) - { - val[1] = val[0]; - } - c[i] = ParseHex (val, sc); - } - } - } - } - return MAKERGB(c[0], c[1], c[2]); -} - -//========================================================================== -// -// V_GetColorStringByName -// -// Searches for the given color name in x11r6rgb.txt and returns an -// HTML-ish "#RRGGBB" string for it if found or the empty string if not. -// -//========================================================================== - -FString V_GetColorStringByName (const char *name, FScriptPosition *sc) -{ - char *rgbEnd; - char *rgb, *endp; - int rgblump; - int c[3], step; - size_t namelen; - - if (fileSystem.GetNumEntries()==0) return FString(); - - rgblump = fileSystem.FindFile ("engine/X11R6RGB.txt"); - if (rgblump == -1) - { - if (!sc) Printf ("X11R6RGB lump not found\n"); - else sc->Message(MSG_WARNING, "X11R6RGB lump not found"); - return FString(); - } - rgb = (char*)fileSystem.Lock(rgblump); - rgbEnd = rgb + fileSystem.FileLength (rgblump); - step = 0; - namelen = strlen (name); - - while (rgb < rgbEnd) - { - // Skip white space - if (*rgb <= ' ') - { - do - { - rgb++; - } while (rgb < rgbEnd && *rgb <= ' '); - } - else if (step == 0 && *rgb == '!') - { // skip comment lines - do - { - rgb++; - } while (rgb < rgbEnd && *rgb != '\n'); - } - else if (step < 3) - { // collect RGB values - c[step++] = strtoul (rgb, &endp, 10); - if (endp == rgb) - { - break; - } - rgb = endp; - } - else - { // Check color name - endp = rgb; - // Find the end of the line - while (endp < rgbEnd && *endp != '\n') - endp++; - // Back up over any whitespace - while (endp > rgb && *endp <= ' ') - endp--; - if (endp == rgb) - { - break; - } - size_t checklen = ++endp - rgb; - if (checklen == namelen && strnicmp (rgb, name, checklen) == 0) - { - FString descr; - descr.Format ("#%02x%02x%02x", c[0], c[1], c[2]); - return descr; - } - rgb = endp; - step = 0; - } - } - if (rgb < rgbEnd) - { - if (!sc) Printf ("X11R6RGB lump is corrupt\n"); - else sc->Message(MSG_WARNING, "X11R6RGB lump is corrupt"); - } - return FString(); -} - -//========================================================================== -// -// V_GetColor -// -// Works like V_GetColorFromString(), but also understands X11 color names. -// -//========================================================================== - -int V_GetColor (const uint32_t *palette, const char *str, FScriptPosition *sc) -{ - FString string = V_GetColorStringByName (str, sc); - int res; - - if (!string.IsEmpty()) - { - res = V_GetColorFromString (palette, string, sc); - } - else - { - res = V_GetColorFromString (palette, str, sc); - } - return res; -} - -int V_GetColor(const uint32_t *palette, FScanner &sc) -{ - FScriptPosition scc = sc; - return V_GetColor(palette, sc.String, &scc); -} - CCMD(clean) { Printf ("CleanXfac: %d\nCleanYfac: %d\n", CleanXfac, CleanYfac); diff --git a/source/core/rendering/v_video.h b/source/core/rendering/v_video.h index 1351e2661..6d9948c96 100644 --- a/source/core/rendering/v_video.h +++ b/source/core/rendering/v_video.h @@ -413,19 +413,6 @@ void V_Init2 (); void V_Shutdown (); -class FScanner; -struct FScriptPosition; -// Returns the closest color to the one desired. String -// should be of the form "rr gg bb". -int V_GetColorFromString (const uint32_t *palette, const char *colorstring, FScriptPosition *sc = nullptr); -// Scans through the X11R6RGB lump for a matching color -// and returns a color string suitable for V_GetColorFromString. -FString V_GetColorStringByName (const char *name, FScriptPosition *sc = nullptr); - -// Tries to get color by name, then by string -int V_GetColor (const uint32_t *palette, const char *str, FScriptPosition *sc = nullptr); -int V_GetColor(const uint32_t *palette, FScanner &sc); - int CheckRatio (int width, int height, int *trueratio=NULL); static inline int CheckRatio (double width, double height) { return CheckRatio(int(width), int(height)); } inline bool IsRatioWidescreen(int ratio) { return (ratio & 3) != 0; } diff --git a/source/core/statistics.cpp b/source/core/statistics.cpp index 975363eaf..73bbdb42e 100644 --- a/source/core/statistics.cpp +++ b/source/core/statistics.cpp @@ -113,7 +113,7 @@ static void ParseStatistics(const char *fn, TArray &statlist) try { FScanner sc; - sc.OpenFile(fn); + if (!sc.OpenFile(fn)) return; while (sc.GetString()) { diff --git a/source/core/textures/bitmap.cpp b/source/core/textures/bitmap.cpp deleted file mode 100644 index dfeed247d..000000000 --- a/source/core/textures/bitmap.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* -** bitmap.cpp -** -**--------------------------------------------------------------------------- -** Copyright 2008-2019 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. -**--------------------------------------------------------------------------- -** -** -*/ - -#include -#include "bitmap.h" - - -//=========================================================================== -// -// multi-format pixel copy with colormap application -// requires the previously defined conversion classes to work -// -//=========================================================================== -template -void iCopyColors(uint8_t *pout, const uint8_t *pin, int count, int step, - uint8_t tr, uint8_t tg, uint8_t tb) -{ - int i; - int a; - - for(i=0;i, - iCopyColors, - iCopyColors, - iCopyColors, - iCopyColors, - iCopyColors, - iCopyColors, - iCopyColors, - iCopyColors, - iCopyColors, - iCopyColors -}; - -//=========================================================================== -// -// True Color texture copy function -// -//=========================================================================== -void FBitmap::CopyPixelDataRGB(int originx, int originy, const uint8_t *patch, int srcwidth, - int srcheight, int step_x, int step_y, int rotate, int ct, - int r, int g, int b) -{ - uint8_t *buffer = data + 4 * originx + Pitch * originy; - for (int y=0;y -void iCopyPaletted(uint8_t *buffer, const uint8_t * patch, int srcwidth, int srcheight, int Pitch, - int step_x, int step_y, int rotate, const PalEntry * palette) -{ - int x,y,pos; - - for (y=0;y(buffer, patch, srcwidth, srcheight, Pitch, - step_x, step_y, rotate, palette); -} - diff --git a/source/core/textures/buildtiles.cpp b/source/core/textures/buildtiles.cpp index 115a23670..dc5f5edbd 100644 --- a/source/core/textures/buildtiles.cpp +++ b/source/core/textures/buildtiles.cpp @@ -879,7 +879,7 @@ void tileCopySection(int tilenum1, int sx1, int sy1, int xsiz, int ysiz, int til if (x2 >= 0 && y2 >= 0 && x2 < xsiz2 && y2 < ysiz2) { auto src = p1[x1 * ysiz1 + y1]; - if (src != 255) + if (src != TRANSPARENT_INDEX) p2[x2 * ysiz2 + y2] = src; } diff --git a/source/core/textures/formats/pngtexture.cpp b/source/core/textures/formats/pngtexture.cpp index db9f406f1..7c18f0424 100644 --- a/source/core/textures/formats/pngtexture.cpp +++ b/source/core/textures/formats/pngtexture.cpp @@ -487,7 +487,7 @@ int FPNGTexture::CopyPixels(FBitmap *bmp, int conversion) else { bmp->CopyPixelDataRGB(0, 0, Pixels, Width, Height, 3, pixwidth, 0, CF_RGBT, - NonPaletteTrans[0], NonPaletteTrans[1], NonPaletteTrans[2]); + nullptr, NonPaletteTrans[0], NonPaletteTrans[1], NonPaletteTrans[2]); transpal = true; } break; diff --git a/source/core/textures/imagehelpers.h b/source/core/textures/imagehelpers.h index 877a1873e..fa5206662 100644 --- a/source/core/textures/imagehelpers.h +++ b/source/core/textures/imagehelpers.h @@ -40,7 +40,7 @@ #include #include "tarray.h" #include "palentry.h" -#include "textures/bitmap.h" +#include "bitmap.h" // we do not want to pull in the entirety of build.h here. extern uint8_t palette[768]; diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index 7ef5cd761..75cf810d2 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -49,6 +49,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. FString C_CON_GetBoundKeyForLastInput(int gameFunc); const char* C_CON_GetButtonFunc(int num); +const char* KB_ScanCodeToString(int scancode); // convert scancode into a string BEGIN_DUKE_NS diff --git a/source/duke3d/src/network.cpp b/source/duke3d/src/network.cpp index 5070de32e..6d89ec66e 100644 --- a/source/duke3d/src/network.cpp +++ b/source/duke3d/src/network.cpp @@ -5260,7 +5260,7 @@ void Net_PrintLag(FString &output) } } -int osdcmd_listplayers(osdcmdptr_t parm) +int osdcmd_listplayers(CCmdFuncPtr parm) { ENetPeer* currentPeer; char ipaddr[32]; @@ -5292,7 +5292,7 @@ int osdcmd_listplayers(osdcmdptr_t parm) } #if 0 -static int osdcmd_kick(osdcmdptr_t parm) +static int osdcmd_kick(CCmdFuncPtr parm) { ENetPeer* currentPeer; uint32_t hexaddr; @@ -5330,7 +5330,7 @@ static int osdcmd_kick(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_kickban(osdcmdptr_t parm) +static int osdcmd_kickban(CCmdFuncPtr parm) { ENetPeer* currentPeer; uint32_t hexaddr; diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index 02628bec0..aed9ef0db 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -38,7 +38,7 @@ BEGIN_DUKE_NS struct osdcmd_cheatsinfo osdcmd_cheatsinfo_stat = { -1, 0, 0 }; -static int osdcmd_levelwarp(osdcmdptr_t parm) +static int osdcmd_levelwarp(CCmdFuncPtr parm) { if (parm->numparms != 2) return OSDCMD_SHOWHELP; @@ -71,7 +71,7 @@ static int osdcmd_levelwarp(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_map(osdcmdptr_t parm) +static int osdcmd_map(CCmdFuncPtr parm) { if (parm->numparms != 1) @@ -149,7 +149,7 @@ foundone: // the variance of the run times MUST be taken into account (that is, the // replaying must be performed multiple times for the old and new versions, // etc.) -static int osdcmd_demo(osdcmdptr_t parm) +static int osdcmd_demo(CCmdFuncPtr parm) { if (numplayers > 1) { @@ -176,7 +176,7 @@ static int osdcmd_demo(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_activatecheat(osdcmdptr_t parm) +static int osdcmd_activatecheat(CCmdFuncPtr parm) { if (parm->numparms != 1) return OSDCMD_SHOWHELP; @@ -189,7 +189,7 @@ static int osdcmd_activatecheat(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_god(osdcmdptr_t UNUSED(parm)) +static int osdcmd_god(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); if (numplayers == 1 && g_player[myconnectindex].ps->gm & MODE_GAME) @@ -200,7 +200,7 @@ static int osdcmd_god(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_maxhealth(osdcmdptr_t parm) +static int osdcmd_maxhealth(CCmdFuncPtr parm) { if (parm->numparms != 1) return OSDCMD_SHOWHELP; @@ -219,7 +219,7 @@ static int osdcmd_maxhealth(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_noclip(osdcmdptr_t UNUSED(parm)) +static int osdcmd_noclip(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -235,7 +235,7 @@ static int osdcmd_noclip(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -int osdcmd_restartmap(osdcmdptr_t UNUSED(parm)) +int osdcmd_restartmap(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -245,7 +245,7 @@ int osdcmd_restartmap(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_spawn(osdcmdptr_t parm) +static int osdcmd_spawn(CCmdFuncPtr parm) { int32_t picnum = 0; uint16_t cstat=0; @@ -339,7 +339,7 @@ static int osdcmd_spawn(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_setvar(osdcmdptr_t parm) +static int osdcmd_setvar(CCmdFuncPtr parm) { if (numplayers > 1) { @@ -369,7 +369,7 @@ static int osdcmd_setvar(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_addlogvar(osdcmdptr_t parm) +static int osdcmd_addlogvar(CCmdFuncPtr parm) { if (numplayers > 1) { @@ -393,7 +393,7 @@ static int osdcmd_addlogvar(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_setactorvar(osdcmdptr_t parm) +static int osdcmd_setactorvar(CCmdFuncPtr parm) { if (numplayers > 1) { @@ -433,7 +433,7 @@ static int osdcmd_setactorvar(osdcmdptr_t parm) } -static int osdcmd_give(osdcmdptr_t parm) +static int osdcmd_give(CCmdFuncPtr parm) { int32_t i; @@ -486,7 +486,7 @@ static int osdcmd_give(osdcmdptr_t parm) } -static int osdcmd_dumpmapstate(osdfuncparm_t const * const) +static int osdcmd_dumpmapstate(CCmdFuncParm const * const) { // this command takes no parameters @@ -495,7 +495,7 @@ static int osdcmd_dumpmapstate(osdfuncparm_t const * const) return OSDCMD_OK; } -static int osdcmd_playerinfo(osdfuncparm_t const * const) +static int osdcmd_playerinfo(CCmdFuncParm const * const) { Printf("Your player index is %d.\n", myconnectindex); @@ -514,14 +514,14 @@ static int osdcmd_playerinfo(osdfuncparm_t const * const) return OSDCMD_OK; } -static int osdcmd_disconnect(osdcmdptr_t UNUSED(parm)) +static int osdcmd_disconnect(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); g_netDisconnect = 1; return OSDCMD_OK; } -static int osdcmd_connect(osdcmdptr_t parm) +static int osdcmd_connect(CCmdFuncPtr parm) { if (parm->numparms != 1) return OSDCMD_SHOWHELP; @@ -531,7 +531,7 @@ static int osdcmd_connect(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_password(osdcmdptr_t parm) +static int osdcmd_password(CCmdFuncPtr parm) { if (parm->numparms < 1) { @@ -543,11 +543,11 @@ static int osdcmd_password(osdcmdptr_t parm) return OSDCMD_OK; } -int osdcmd_listplayers(osdcmdptr_t parm); +int osdcmd_listplayers(CCmdFuncPtr parm); -static int osdcmd_printtimes(osdcmdptr_t UNUSED(parm)) +static int osdcmd_printtimes(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -618,43 +618,43 @@ static int osdcmd_printtimes(osdcmdptr_t UNUSED(parm)) int32_t registerosdcommands(void) { #if !defined NETCODE_DISABLE - OSD_RegisterFunction("connect","connect: connects to a multiplayer game", osdcmd_connect); - OSD_RegisterFunction("disconnect","disconnect: disconnects from the local multiplayer game", osdcmd_disconnect); - OSD_RegisterFunction("dumpmapstates", "Dumps current snapshots to CL/Srv_MapStates.bin", osdcmd_dumpmapstate); + C_RegisterFunction("connect","connect: connects to a multiplayer game", osdcmd_connect); + C_RegisterFunction("disconnect","disconnect: disconnects from the local multiplayer game", osdcmd_disconnect); + C_RegisterFunction("dumpmapstates", "Dumps current snapshots to CL/Srv_MapStates.bin", osdcmd_dumpmapstate); #if 0 - OSD_RegisterFunction("kick","kick : kicks a multiplayer client. See listplayers.", osdcmd_kick); - OSD_RegisterFunction("kickban","kickban : kicks a multiplayer client and prevents them from reconnecting. See listplayers.", osdcmd_kickban); + C_RegisterFunction("kick","kick : kicks a multiplayer client. See listplayers.", osdcmd_kick); + C_RegisterFunction("kickban","kickban : kicks a multiplayer client and prevents them from reconnecting. See listplayers.", osdcmd_kickban); #endif - OSD_RegisterFunction("listplayers","listplayers: lists currently connected multiplayer clients", osdcmd_listplayers); - OSD_RegisterFunction("password","password: sets multiplayer game password", osdcmd_password); - OSD_RegisterFunction("playerinfo", "Prints information about the current player", osdcmd_playerinfo); + C_RegisterFunction("listplayers","listplayers: lists currently connected multiplayer clients", osdcmd_listplayers); + C_RegisterFunction("password","password: sets multiplayer game password", osdcmd_password); + C_RegisterFunction("playerinfo", "Prints information about the current player", osdcmd_playerinfo); #endif - OSD_RegisterFunction("map","map : loads the given map", osdcmd_map); + C_RegisterFunction("map","map : loads the given map", osdcmd_map); if (!VOLUMEONE) { - OSD_RegisterFunction("demo","demo : starts the given demo", osdcmd_demo); + C_RegisterFunction("demo","demo : starts the given demo", osdcmd_demo); } - OSD_RegisterFunction("give","give : gives requested item", osdcmd_give); - OSD_RegisterFunction("god","god: toggles god mode", osdcmd_god); - OSD_RegisterFunction("activatecheat","activatecheat : activates a cheat code", osdcmd_activatecheat); - OSD_RegisterFunction("maxhealth", "maxhealth : sets the player's maximum health", osdcmd_maxhealth); + C_RegisterFunction("give","give : gives requested item", osdcmd_give); + C_RegisterFunction("god","god: toggles god mode", osdcmd_god); + C_RegisterFunction("activatecheat","activatecheat : activates a cheat code", osdcmd_activatecheat); + C_RegisterFunction("maxhealth", "maxhealth : sets the player's maximum health", osdcmd_maxhealth); - OSD_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); + C_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); - OSD_RegisterFunction("levelwarp","levelwarp : warp to episode 'e' and map 'm'", osdcmd_levelwarp); + C_RegisterFunction("levelwarp","levelwarp : warp to episode 'e' and map 'm'", osdcmd_levelwarp); - OSD_RegisterFunction("printtimes", "printtimes: prints VM timing statistics", osdcmd_printtimes); + C_RegisterFunction("printtimes", "printtimes: prints VM timing statistics", osdcmd_printtimes); - OSD_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap); - OSD_RegisterFunction("addlogvar","addlogvar : prints the value of a gamevar", osdcmd_addlogvar); - OSD_RegisterFunction("setvar","setvar : sets the value of a gamevar", osdcmd_setvar); - OSD_RegisterFunction("setvarvar","setvarvar : sets the value of to ", osdcmd_setvar); - OSD_RegisterFunction("setactorvar","setactorvar : sets the value of 's to ", osdcmd_setactorvar); + C_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap); + C_RegisterFunction("addlogvar","addlogvar : prints the value of a gamevar", osdcmd_addlogvar); + C_RegisterFunction("setvar","setvar : sets the value of a gamevar", osdcmd_setvar); + C_RegisterFunction("setvarvar","setvarvar : sets the value of to ", osdcmd_setvar); + C_RegisterFunction("setactorvar","setactorvar : sets the value of 's to ", osdcmd_setactorvar); - OSD_RegisterFunction("spawn","spawn [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",osdcmd_spawn); + C_RegisterFunction("spawn","spawn [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",osdcmd_spawn); return 0; } diff --git a/source/exhumed/src/exhumed.cpp b/source/exhumed/src/exhumed.cpp index 3bf117f99..349d9f820 100644 --- a/source/exhumed/src/exhumed.cpp +++ b/source/exhumed/src/exhumed.cpp @@ -1427,7 +1427,7 @@ void DrawClock() auto pixels = TileFiles.tileMakeWritable(kTile3603); - memset(pixels, -1, 4096); + memset(pixels, TRANSPARENT_INDEX, 4096); if (lCountDown / 30 != nClockVal) { @@ -2655,7 +2655,7 @@ void CopyTileToBitmap(short nSrcTile, short nDestTile, int xPos, int yPos) for (int y = 0; y < srcYSize; y++) { uint8_t val = *pSrc; - if (val != 0xFF) { + if (val != TRANSPARENT_INDEX) { *pDestB = val; } @@ -2739,7 +2739,7 @@ void InitSpiritHead() { for (int y = 0; y < 106; y++) { - if (*pTile != 255) + if (*pTile != TRANSPARENT_INDEX) { pixelval[nPixels] = *(pGold + x * 106 + y); origx[nPixels] = x - 48; @@ -2782,7 +2782,7 @@ void InitSpiritHead() nHeadTimeStart = (int)totalclock; - memset(Worktile, -1, WorktileSize); + memset(Worktile, TRANSPARENT_INDEX, WorktileSize); tileInvalidate(kTileRamsesWorkTile, -1, -1); nPixelsToShow = 0; @@ -2867,7 +2867,7 @@ int DoSpiritHead() if (nHeadStage < 2) { - memset(Worktile, -1, WorktileSize); + memset(Worktile, TRANSPARENT_INDEX, WorktileSize); } if (nHeadStage < 2 || nHeadStage != 5) diff --git a/source/exhumed/src/menu.cpp b/source/exhumed/src/menu.cpp index 256505f0e..ff4bba5cb 100644 --- a/source/exhumed/src/menu.cpp +++ b/source/exhumed/src/menu.cpp @@ -479,7 +479,7 @@ void menu_DoPlasma() while (nSmokeOffset < nSmokeBottom) { uint8_t al = *ptr3; - if (al != 255 && al != 96) { + if (al != TRANSPARENT_INDEX && al != 96) { break; } @@ -496,7 +496,7 @@ void menu_DoPlasma() while (nSmokeOffset > nSmokeTop) { uint8_t al = *ptr3; - if (al != 255 && al != 96) { + if (al != TRANSPARENT_INDEX && al != 96) { break; } diff --git a/source/exhumed/src/osdcmds.cpp b/source/exhumed/src/osdcmds.cpp index cc260c3eb..ef405387a 100644 --- a/source/exhumed/src/osdcmds.cpp +++ b/source/exhumed/src/osdcmds.cpp @@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS -static int osdcmd_god(osdcmdptr_t UNUSED(parm)) +static int osdcmd_god(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -45,7 +45,7 @@ static int osdcmd_god(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_noclip(osdcmdptr_t UNUSED(parm)) +static int osdcmd_noclip(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -61,7 +61,7 @@ static int osdcmd_noclip(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_map(osdcmdptr_t parm) +static int osdcmd_map(CCmdFuncPtr parm) { if (parm->numparms != 1) { @@ -88,7 +88,7 @@ static int osdcmd_map(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_changelevel(osdcmdptr_t parm) +static int osdcmd_changelevel(CCmdFuncPtr parm) { char* p; @@ -124,23 +124,23 @@ static int osdcmd_changelevel(osdcmdptr_t parm) int32_t registerosdcommands(void) { //if (VOLUMEONE) - OSD_RegisterFunction("changelevel","changelevel : warps to the given level", osdcmd_changelevel); - OSD_RegisterFunction("map","map : loads the given map", osdcmd_map); - // OSD_RegisterFunction("demo","demo : starts the given demo", osdcmd_demo); + C_RegisterFunction("changelevel","changelevel : warps to the given level", osdcmd_changelevel); + C_RegisterFunction("map","map : loads the given map", osdcmd_map); + // C_RegisterFunction("demo","demo : starts the given demo", osdcmd_demo); //} - //OSD_RegisterFunction("cmenu","cmenu <#>: jumps to menu", osdcmd_cmenu); + //C_RegisterFunction("cmenu","cmenu <#>: jumps to menu", osdcmd_cmenu); - //OSD_RegisterFunction("give","give : gives requested item", osdcmd_give); - OSD_RegisterFunction("god","god: toggles god mode", osdcmd_god); - //OSD_RegisterFunction("activatecheat","activatecheat : activates a cheat code", osdcmd_activatecheat); + //C_RegisterFunction("give","give : gives requested item", osdcmd_give); + C_RegisterFunction("god","god: toggles god mode", osdcmd_god); + //C_RegisterFunction("activatecheat","activatecheat : activates a cheat code", osdcmd_activatecheat); - OSD_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); - //OSD_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap); - //OSD_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound); + C_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); + //C_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap); + //C_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound); - //OSD_RegisterFunction("spawn","spawn [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",osdcmd_spawn); + //C_RegisterFunction("spawn","spawn [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",osdcmd_spawn); return 0; } diff --git a/source/platform/win32/i_system.cpp b/source/platform/win32/i_system.cpp index 6f9eec5e8..efa5b6aa7 100644 --- a/source/platform/win32/i_system.cpp +++ b/source/platform/win32/i_system.cpp @@ -78,7 +78,7 @@ #include "gameconfigfile.h" #include "v_font.h" #include "i_system.h" -#include "textures/bitmap.h" +#include "bitmap.h" #include "cmdlib.h" extern bool batchrun; diff --git a/source/rr/src/net.cpp b/source/rr/src/net.cpp index 8af522e2a..84e2f5a97 100644 --- a/source/rr/src/net.cpp +++ b/source/rr/src/net.cpp @@ -3711,7 +3711,7 @@ void Net_PrintLag(FString& output) } } -int osdcmd_listplayers(osdcmdptr_t parm) +int osdcmd_listplayers(CCmdFuncPtr parm) { ENetPeer* currentPeer; char ipaddr[32]; @@ -3743,7 +3743,7 @@ int osdcmd_listplayers(osdcmdptr_t parm) } #if 0 -static int osdcmd_kick(osdcmdptr_t parm) +static int osdcmd_kick(CCmdFuncPtr parm) { ENetPeer* currentPeer; uint32_t hexaddr; @@ -3781,7 +3781,7 @@ static int osdcmd_kick(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_kickban(osdcmdptr_t parm) +static int osdcmd_kickban(CCmdFuncPtr parm) { ENetPeer* currentPeer; uint32_t hexaddr; diff --git a/source/rr/src/osdcmds.cpp b/source/rr/src/osdcmds.cpp index 3e099e840..0383bcef2 100644 --- a/source/rr/src/osdcmds.cpp +++ b/source/rr/src/osdcmds.cpp @@ -36,7 +36,7 @@ BEGIN_RR_NS struct osdcmd_cheatsinfo osdcmd_cheatsinfo_stat = { -1, 0, 0 }; -static int osdcmd_levelwarp(osdcmdptr_t parm) +static int osdcmd_levelwarp(CCmdFuncPtr parm) { if (parm->numparms != 2) return OSDCMD_SHOWHELP; @@ -69,7 +69,7 @@ static int osdcmd_levelwarp(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_map(osdcmdptr_t parm) +static int osdcmd_map(CCmdFuncPtr parm) { if (parm->numparms != 1) { @@ -147,7 +147,7 @@ foundone: // the variance of the run times MUST be taken into account (that is, the // replaying must be performed multiple times for the old and new versions, // etc.) -static int osdcmd_demo(osdcmdptr_t parm) +static int osdcmd_demo(CCmdFuncPtr parm) { if (numplayers > 1) { @@ -174,7 +174,7 @@ static int osdcmd_demo(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_activatecheat(osdcmdptr_t parm) +static int osdcmd_activatecheat(CCmdFuncPtr parm) { if (parm->numparms != 1) return OSDCMD_SHOWHELP; @@ -187,7 +187,7 @@ static int osdcmd_activatecheat(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_god(osdcmdptr_t UNUSED(parm)) +static int osdcmd_god(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); if (numplayers == 1 && g_player[myconnectindex].ps->gm & MODE_GAME) @@ -198,7 +198,7 @@ static int osdcmd_god(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_noclip(osdcmdptr_t UNUSED(parm)) +static int osdcmd_noclip(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -214,7 +214,7 @@ static int osdcmd_noclip(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -int osdcmd_restartmap(osdcmdptr_t UNUSED(parm)) +int osdcmd_restartmap(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -224,7 +224,7 @@ int osdcmd_restartmap(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_spawn(osdcmdptr_t parm) +static int osdcmd_spawn(CCmdFuncPtr parm) { int32_t picnum = 0; uint16_t cstat=0; @@ -319,7 +319,7 @@ static int osdcmd_spawn(osdcmdptr_t parm) } -static int osdcmd_give(osdcmdptr_t parm) +static int osdcmd_give(CCmdFuncPtr parm) { int32_t i; @@ -372,7 +372,7 @@ static int osdcmd_give(osdcmdptr_t parm) } #if !defined NETCODE_DISABLE -static int osdcmd_disconnect(osdcmdptr_t UNUSED(parm)) +static int osdcmd_disconnect(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); // NUKE-TODO: @@ -381,7 +381,7 @@ static int osdcmd_disconnect(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_connect(osdcmdptr_t parm) +static int osdcmd_connect(CCmdFuncPtr parm) { if (parm->numparms != 1) return OSDCMD_SHOWHELP; @@ -391,7 +391,7 @@ static int osdcmd_connect(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_password(osdcmdptr_t parm) +static int osdcmd_password(CCmdFuncPtr parm) { if (parm->numparms < 1) { @@ -403,10 +403,10 @@ static int osdcmd_password(osdcmdptr_t parm) return OSDCMD_OK; } -int osdcmd_listplayers(osdcmdptr_t parm); +int osdcmd_listplayers(CCmdFuncPtr parm); #endif -static int osdcmd_printtimes(osdcmdptr_t UNUSED(parm)) +static int osdcmd_printtimes(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -450,44 +450,44 @@ static int osdcmd_printtimes(osdcmdptr_t UNUSED(parm)) int32_t registerosdcommands(void) { - OSD_RegisterFunction("map","map : loads the given map", osdcmd_map); + C_RegisterFunction("map","map : loads the given map", osdcmd_map); if (!VOLUMEONE) { - OSD_RegisterFunction("demo","demo : starts the given demo", osdcmd_demo); + C_RegisterFunction("demo","demo : starts the given demo", osdcmd_demo); } - OSD_RegisterFunction("levelwarp","levelwarp : warp to episode 'e' and map 'm'", osdcmd_levelwarp); + C_RegisterFunction("levelwarp","levelwarp : warp to episode 'e' and map 'm'", osdcmd_levelwarp); #if !defined NETCODE_DISABLE - OSD_RegisterFunction("connect","connect: connects to a multiplayer game", osdcmd_connect); - OSD_RegisterFunction("disconnect","disconnect: disconnects from the local multiplayer game", osdcmd_disconnect); + C_RegisterFunction("connect","connect: connects to a multiplayer game", osdcmd_connect); + C_RegisterFunction("disconnect","disconnect: disconnects from the local multiplayer game", osdcmd_disconnect); #endif - OSD_RegisterFunction("give","give : gives requested item", osdcmd_give); - OSD_RegisterFunction("god","god: toggles god mode", osdcmd_god); - OSD_RegisterFunction("activatecheat","activatecheat : activates a cheat code", osdcmd_activatecheat); + C_RegisterFunction("give","give : gives requested item", osdcmd_give); + C_RegisterFunction("god","god: toggles god mode", osdcmd_god); + C_RegisterFunction("activatecheat","activatecheat : activates a cheat code", osdcmd_activatecheat); #ifdef DEBUGGINGAIDS - OSD_RegisterFunction("inittimer","debug", osdcmd_inittimer); + C_RegisterFunction("inittimer","debug", osdcmd_inittimer); #endif #if !defined NETCODE_DISABLE #if 0 - OSD_RegisterFunction("kick","kick : kicks a multiplayer client. See listplayers.", osdcmd_kick); - OSD_RegisterFunction("kickban","kickban : kicks a multiplayer client and prevents them from reconnecting. See listplayers.", osdcmd_kickban); + C_RegisterFunction("kick","kick : kicks a multiplayer client. See listplayers.", osdcmd_kick); + C_RegisterFunction("kickban","kickban : kicks a multiplayer client and prevents them from reconnecting. See listplayers.", osdcmd_kickban); #endif - OSD_RegisterFunction("listplayers","listplayers: lists currently connected multiplayer clients", osdcmd_listplayers); + C_RegisterFunction("listplayers","listplayers: lists currently connected multiplayer clients", osdcmd_listplayers); #endif - OSD_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); + C_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); #if !defined NETCODE_DISABLE - OSD_RegisterFunction("password","password: sets multiplayer game password", osdcmd_password); + C_RegisterFunction("password","password: sets multiplayer game password", osdcmd_password); #endif - OSD_RegisterFunction("printtimes", "printtimes: prints VM timing statistics", osdcmd_printtimes); + C_RegisterFunction("printtimes", "printtimes: prints VM timing statistics", osdcmd_printtimes); - OSD_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap); + C_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap); - OSD_RegisterFunction("spawn","spawn [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",osdcmd_spawn); + C_RegisterFunction("spawn","spawn [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",osdcmd_spawn); return 0; } diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index e63b7416b..2f6d53a6c 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -1450,7 +1450,7 @@ static void prelevel(char g) if (sector[i].ceilingstat&1) { - if (tilePtr(sector[i].ceilingpicnum) == 0) + if (tilePtr(sector[i].ceilingpicnum) == nullptr) { if (sector[i].ceilingpicnum == LA) for (bsize_t j = 0; j < 5; j++) diff --git a/source/rr/src/sector.cpp b/source/rr/src/sector.cpp index 78ff4c853..d9accdc63 100644 --- a/source/rr/src/sector.cpp +++ b/source/rr/src/sector.cpp @@ -5243,7 +5243,7 @@ void G_Thunder(void) if ((gotpic[RRTILE2577>>3]&(1<<(RRTILE2577&7)))) { gotpic[RRTILE2577>>3] &= ~(1<<(RRTILE2577&7)); - if (tilePtr(RRTILE2577) != 0) // why does this on texture load state??? + if (tilePtr(RRTILE2577) != nullptr) // why does this on texture load state??? { g_visibility = 256; if (krand2() > 65000) @@ -5276,7 +5276,7 @@ void G_Thunder(void) if ((gotpic[RRTILE2562>>3]&(1<<(RRTILE2562&7)))) { gotpic[RRTILE2562>>3] &= ~(1<<(RRTILE2562&7)); - if (tilePtr(RRTILE2562) != 0) // why does this on texture load state??? + if (tilePtr(RRTILE2562) != nullptr) // why does this on texture load state??? { if (krand2() > 65000) { diff --git a/source/sw/src/osdcmds.cpp b/source/sw/src/osdcmds.cpp index 3ff291a0f..294155307 100644 --- a/source/sw/src/osdcmds.cpp +++ b/source/sw/src/osdcmds.cpp @@ -53,7 +53,7 @@ char boardfilename[BMAX_PATH] = {0}; struct osdcmd_cheatsinfo osdcmd_cheatsinfo_stat = { -1, 0, 0 }; -static int osdcmd_map(osdcmdptr_t parm) +static int osdcmd_map(CCmdFuncPtr parm) { if (parm->numparms != 1) { @@ -81,7 +81,7 @@ static int osdcmd_map(osdcmdptr_t parm) } -static int osdcmd_activatecheat(osdcmdptr_t parm) +static int osdcmd_activatecheat(CCmdFuncPtr parm) { if (parm->numparms != 1) return OSDCMD_SHOWHELP; @@ -93,7 +93,7 @@ static int osdcmd_activatecheat(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_god(osdcmdptr_t UNUSED(parm)) +static int osdcmd_god(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -102,7 +102,7 @@ static int osdcmd_god(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_noclip(osdcmdptr_t UNUSED(parm)) +static int osdcmd_noclip(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -111,7 +111,7 @@ static int osdcmd_noclip(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -int osdcmd_restartmap(osdcmdptr_t UNUSED(parm)) +int osdcmd_restartmap(CCmdFuncPtr UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -120,7 +120,7 @@ int osdcmd_restartmap(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -int osdcmd_levelwarp(osdcmdptr_t parm) +int osdcmd_levelwarp(CCmdFuncPtr parm) { if (parm->numparms != 1) return OSDCMD_SHOWHELP; @@ -134,7 +134,7 @@ int osdcmd_levelwarp(osdcmdptr_t parm) } #if 0 -static int osdcmd_spawn(osdcmdptr_t parm) +static int osdcmd_spawn(CCmdFuncPtr parm) { int32_t picnum = 0; uint16_t cstat=0; @@ -229,7 +229,7 @@ static int osdcmd_spawn(osdcmdptr_t parm) } #endif -static int osdcmd_give(osdcmdptr_t parm) +static int osdcmd_give(CCmdFuncPtr parm) { int32_t i; @@ -275,18 +275,18 @@ static int osdcmd_give(osdcmdptr_t parm) int32_t registerosdcommands(void) { - OSD_RegisterFunction("map","map : loads the given map", osdcmd_map); - OSD_RegisterFunction("give","give : gives requested item", osdcmd_give); - OSD_RegisterFunction("god","god: toggles god mode", osdcmd_god); - OSD_RegisterFunction("activatecheat","activatecheat : activates a classic cheat code", osdcmd_activatecheat); + C_RegisterFunction("map","map : loads the given map", osdcmd_map); + C_RegisterFunction("give","give : gives requested item", osdcmd_give); + C_RegisterFunction("god","god: toggles god mode", osdcmd_god); + C_RegisterFunction("activatecheat","activatecheat : activates a classic cheat code", osdcmd_activatecheat); - OSD_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); + C_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); - OSD_RegisterFunction("levelwarp", "levelwarp : warp to level", osdcmd_levelwarp); + C_RegisterFunction("levelwarp", "levelwarp : warp to level", osdcmd_levelwarp); - OSD_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap); + C_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap); -// OSD_RegisterFunction("spawn","spawn [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",osdcmd_spawn); +// C_RegisterFunction("spawn","spawn [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",osdcmd_spawn); return 0; } diff --git a/wadsrc/static/engine/commonbinds.txt b/wadsrc/static/engine/commonbinds.txt index e5e46d39f..7681ccc27 100644 --- a/wadsrc/static/engine/commonbinds.txt +++ b/wadsrc/static/engine/commonbinds.txt @@ -35,7 +35,7 @@ LAlt "+Strafe" RAlt "+Strafe" LShift "+Run" RShift "+Run" -Capslock "toggle autorun 85" +Capslock "togglemsg autorun 85" PgUp "+Look_Up" PgDn "+Look_Down" Home "+Aim_Up" diff --git a/wadsrc/static/engine/menudef.txt b/wadsrc/static/engine/menudef.txt index d8311a767..540ded308 100644 --- a/wadsrc/static/engine/menudef.txt +++ b/wadsrc/static/engine/menudef.txt @@ -784,7 +784,7 @@ OptionMenu "ActionControlsMenu"// protected StaticText "" Control "$CNTRLMNU_RUN" , "+run" - Control "$CNTRLMNU_TOGGLERUN" , "toggle cl_autorun" + Control "$CNTRLMNU_TOGGLERUN" , "toggle autorun" Control "$CNTRLMNU_STRAFE" , "+strafe" StaticText "" diff --git a/wadsrc/static/x11r6rgb.txt b/wadsrc/static/x11r6rgb.txt new file mode 100644 index 000000000..b8fcb44ac --- /dev/null +++ b/wadsrc/static/x11r6rgb.txt @@ -0,0 +1,757 @@ +! $XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp $ + +255 250 250 snow +248 248 255 ghost white +248 248 255 GhostWhite +245 245 245 white smoke +245 245 245 WhiteSmoke +220 220 220 gainsboro +255 250 240 floral white +255 250 240 FloralWhite +253 245 230 old lace +253 245 230 OldLace +250 240 230 linen +250 235 215 antique white +250 235 215 AntiqueWhite +255 239 213 papaya whip +255 239 213 PapayaWhip +255 235 205 blanched almond +255 235 205 BlanchedAlmond +255 228 196 bisque +255 218 185 peach puff +255 218 185 PeachPuff +255 222 173 navajo white +255 222 173 NavajoWhite +255 228 181 moccasin +255 248 220 cornsilk +255 255 240 ivory +255 250 205 lemon chiffon +255 250 205 LemonChiffon +255 245 238 seashell +240 255 240 honeydew +245 255 250 mint cream +245 255 250 MintCream +240 255 255 azure +240 248 255 alice blue +240 248 255 AliceBlue +230 230 250 lavender +255 240 245 lavender blush +255 240 245 LavenderBlush +255 228 225 misty rose +255 228 225 MistyRose +255 255 255 white + 0 0 0 black + 47 79 79 dark slate gray + 47 79 79 DarkSlateGray + 47 79 79 dark slate grey + 47 79 79 DarkSlateGrey +105 105 105 dim gray +105 105 105 DimGray +105 105 105 dim grey +105 105 105 DimGrey +112 128 144 slate gray +112 128 144 SlateGray +112 128 144 slate grey +112 128 144 SlateGrey +119 136 153 light slate gray +119 136 153 LightSlateGray +119 136 153 light slate grey +119 136 153 LightSlateGrey +190 190 190 gray +190 190 190 grey +211 211 211 light grey +211 211 211 LightGrey +211 211 211 light gray +211 211 211 LightGray + 25 25 112 midnight blue + 25 25 112 MidnightBlue + 0 0 128 navy + 0 0 128 navy blue + 0 0 128 NavyBlue +100 149 237 cornflower blue +100 149 237 CornflowerBlue + 72 61 139 dark slate blue + 72 61 139 DarkSlateBlue +106 90 205 slate blue +106 90 205 SlateBlue +123 104 238 medium slate blue +123 104 238 MediumSlateBlue +132 112 255 light slate blue +132 112 255 LightSlateBlue + 0 0 205 medium blue + 0 0 205 MediumBlue + 65 105 225 royal blue + 65 105 225 RoyalBlue + 0 0 255 blue + 30 144 255 dodger blue + 30 144 255 DodgerBlue + 0 191 255 deep sky blue + 0 191 255 DeepSkyBlue +135 206 235 sky blue +135 206 235 SkyBlue +135 206 250 light sky blue +135 206 250 LightSkyBlue + 70 130 180 steel blue + 70 130 180 SteelBlue +176 196 222 light steel blue +176 196 222 LightSteelBlue +173 216 230 light blue +173 216 230 LightBlue +176 224 230 powder blue +176 224 230 PowderBlue +175 238 238 pale turquoise +175 238 238 PaleTurquoise + 0 206 209 dark turquoise + 0 206 209 DarkTurquoise + 72 209 204 medium turquoise + 72 209 204 MediumTurquoise + 64 224 208 turquoise + 0 255 255 cyan +224 255 255 light cyan +224 255 255 LightCyan + 95 158 160 cadet blue + 95 158 160 CadetBlue +102 205 170 medium aquamarine +102 205 170 MediumAquamarine +127 255 212 aquamarine + 0 100 0 dark green + 0 100 0 DarkGreen + 85 107 47 dark olive green + 85 107 47 DarkOliveGreen +143 188 143 dark sea green +143 188 143 DarkSeaGreen + 46 139 87 sea green + 46 139 87 SeaGreen + 60 179 113 medium sea green + 60 179 113 MediumSeaGreen + 32 178 170 light sea green + 32 178 170 LightSeaGreen +152 251 152 pale green +152 251 152 PaleGreen + 0 255 127 spring green + 0 255 127 SpringGreen +124 252 0 lawn green +124 252 0 LawnGreen + 0 255 0 green +127 255 0 chartreuse + 0 250 154 medium spring green + 0 250 154 MediumSpringGreen +173 255 47 green yellow +173 255 47 GreenYellow + 50 205 50 lime green + 50 205 50 LimeGreen +154 205 50 yellow green +154 205 50 YellowGreen + 34 139 34 forest green + 34 139 34 ForestGreen +107 142 35 olive drab +107 142 35 OliveDrab +189 183 107 dark khaki +189 183 107 DarkKhaki +240 230 140 khaki +238 232 170 pale goldenrod +238 232 170 PaleGoldenrod +250 250 210 light goldenrod yellow +250 250 210 LightGoldenrodYellow +255 255 224 light yellow +255 255 224 LightYellow +255 255 0 yellow +255 215 0 gold +238 221 130 light goldenrod +238 221 130 LightGoldenrod +218 165 32 goldenrod +184 134 11 dark goldenrod +184 134 11 DarkGoldenrod +188 143 143 rosy brown +188 143 143 RosyBrown +205 92 92 indian red +205 92 92 IndianRed +139 69 19 saddle brown +139 69 19 SaddleBrown +160 82 45 sienna +205 133 63 peru +222 184 135 burlywood +245 245 220 beige +245 222 179 wheat +244 164 96 sandy brown +244 164 96 SandyBrown +210 180 140 tan +210 105 30 chocolate +178 34 34 firebrick +165 42 42 brown +233 150 122 dark salmon +233 150 122 DarkSalmon +250 128 114 salmon +255 160 122 light salmon +255 160 122 LightSalmon +255 165 0 orange +255 140 0 dark orange +255 140 0 DarkOrange +255 127 80 coral +240 128 128 light coral +240 128 128 LightCoral +255 99 71 tomato +255 69 0 orange red +255 69 0 OrangeRed +255 0 0 red +255 105 180 hot pink +255 105 180 HotPink +255 20 147 deep pink +255 20 147 DeepPink +255 192 203 pink +255 182 193 light pink +255 182 193 LightPink +219 112 147 pale violet red +219 112 147 PaleVioletRed +176 48 96 maroon +199 21 133 medium violet red +199 21 133 MediumVioletRed +208 32 144 violet red +208 32 144 VioletRed +255 0 255 magenta +238 130 238 violet +221 160 221 plum +218 112 214 orchid +186 85 211 medium orchid +186 85 211 MediumOrchid +153 50 204 dark orchid +153 50 204 DarkOrchid +148 0 211 dark violet +148 0 211 DarkViolet +138 43 226 blue violet +138 43 226 BlueViolet +160 32 240 purple +147 112 219 medium purple +147 112 219 MediumPurple +216 191 216 thistle +255 250 250 snow1 +238 233 233 snow2 +205 201 201 snow3 +139 137 137 snow4 +255 245 238 seashell1 +238 229 222 seashell2 +205 197 191 seashell3 +139 134 130 seashell4 +255 239 219 AntiqueWhite1 +238 223 204 AntiqueWhite2 +205 192 176 AntiqueWhite3 +139 131 120 AntiqueWhite4 +255 228 196 bisque1 +238 213 183 bisque2 +205 183 158 bisque3 +139 125 107 bisque4 +255 218 185 PeachPuff1 +238 203 173 PeachPuff2 +205 175 149 PeachPuff3 +139 119 101 PeachPuff4 +255 222 173 NavajoWhite1 +238 207 161 NavajoWhite2 +205 179 139 NavajoWhite3 +139 121 94 NavajoWhite4 +255 250 205 LemonChiffon1 +238 233 191 LemonChiffon2 +205 201 165 LemonChiffon3 +139 137 112 LemonChiffon4 +255 248 220 cornsilk1 +238 232 205 cornsilk2 +205 200 177 cornsilk3 +139 136 120 cornsilk4 +255 255 240 ivory1 +238 238 224 ivory2 +205 205 193 ivory3 +139 139 131 ivory4 +240 255 240 honeydew1 +224 238 224 honeydew2 +193 205 193 honeydew3 +131 139 131 honeydew4 +255 240 245 LavenderBlush1 +238 224 229 LavenderBlush2 +205 193 197 LavenderBlush3 +139 131 134 LavenderBlush4 +255 228 225 MistyRose1 +238 213 210 MistyRose2 +205 183 181 MistyRose3 +139 125 123 MistyRose4 +240 255 255 azure1 +224 238 238 azure2 +193 205 205 azure3 +131 139 139 azure4 +131 111 255 SlateBlue1 +122 103 238 SlateBlue2 +105 89 205 SlateBlue3 + 71 60 139 SlateBlue4 + 72 118 255 RoyalBlue1 + 67 110 238 RoyalBlue2 + 58 95 205 RoyalBlue3 + 39 64 139 RoyalBlue4 + 0 0 255 blue1 + 0 0 238 blue2 + 0 0 205 blue3 + 0 0 139 blue4 + 30 144 255 DodgerBlue1 + 28 134 238 DodgerBlue2 + 24 116 205 DodgerBlue3 + 16 78 139 DodgerBlue4 + 99 184 255 SteelBlue1 + 92 172 238 SteelBlue2 + 79 148 205 SteelBlue3 + 54 100 139 SteelBlue4 + 0 191 255 DeepSkyBlue1 + 0 178 238 DeepSkyBlue2 + 0 154 205 DeepSkyBlue3 + 0 104 139 DeepSkyBlue4 +135 206 255 SkyBlue1 +126 192 238 SkyBlue2 +108 166 205 SkyBlue3 + 74 112 139 SkyBlue4 +176 226 255 LightSkyBlue1 +164 211 238 LightSkyBlue2 +141 182 205 LightSkyBlue3 + 96 123 139 LightSkyBlue4 +198 226 255 SlateGray1 +185 211 238 SlateGray2 +159 182 205 SlateGray3 +108 123 139 SlateGray4 +202 225 255 LightSteelBlue1 +188 210 238 LightSteelBlue2 +162 181 205 LightSteelBlue3 +110 123 139 LightSteelBlue4 +191 239 255 LightBlue1 +178 223 238 LightBlue2 +154 192 205 LightBlue3 +104 131 139 LightBlue4 +224 255 255 LightCyan1 +209 238 238 LightCyan2 +180 205 205 LightCyan3 +122 139 139 LightCyan4 +187 255 255 PaleTurquoise1 +174 238 238 PaleTurquoise2 +150 205 205 PaleTurquoise3 +102 139 139 PaleTurquoise4 +152 245 255 CadetBlue1 +142 229 238 CadetBlue2 +122 197 205 CadetBlue3 + 83 134 139 CadetBlue4 + 0 245 255 turquoise1 + 0 229 238 turquoise2 + 0 197 205 turquoise3 + 0 134 139 turquoise4 + 0 255 255 cyan1 + 0 238 238 cyan2 + 0 205 205 cyan3 + 0 139 139 cyan4 +151 255 255 DarkSlateGray1 +141 238 238 DarkSlateGray2 +121 205 205 DarkSlateGray3 + 82 139 139 DarkSlateGray4 +127 255 212 aquamarine1 +118 238 198 aquamarine2 +102 205 170 aquamarine3 + 69 139 116 aquamarine4 +193 255 193 DarkSeaGreen1 +180 238 180 DarkSeaGreen2 +155 205 155 DarkSeaGreen3 +105 139 105 DarkSeaGreen4 + 84 255 159 SeaGreen1 + 78 238 148 SeaGreen2 + 67 205 128 SeaGreen3 + 46 139 87 SeaGreen4 +154 255 154 PaleGreen1 +144 238 144 PaleGreen2 +124 205 124 PaleGreen3 + 84 139 84 PaleGreen4 + 0 255 127 SpringGreen1 + 0 238 118 SpringGreen2 + 0 205 102 SpringGreen3 + 0 139 69 SpringGreen4 + 0 255 0 green1 + 0 238 0 green2 + 0 205 0 green3 + 0 139 0 green4 +127 255 0 chartreuse1 +118 238 0 chartreuse2 +102 205 0 chartreuse3 + 69 139 0 chartreuse4 +192 255 62 OliveDrab1 +179 238 58 OliveDrab2 +154 205 50 OliveDrab3 +105 139 34 OliveDrab4 +202 255 112 DarkOliveGreen1 +188 238 104 DarkOliveGreen2 +162 205 90 DarkOliveGreen3 +110 139 61 DarkOliveGreen4 +255 246 143 khaki1 +238 230 133 khaki2 +205 198 115 khaki3 +139 134 78 khaki4 +255 236 139 LightGoldenrod1 +238 220 130 LightGoldenrod2 +205 190 112 LightGoldenrod3 +139 129 76 LightGoldenrod4 +255 255 224 LightYellow1 +238 238 209 LightYellow2 +205 205 180 LightYellow3 +139 139 122 LightYellow4 +255 255 0 yellow1 +238 238 0 yellow2 +205 205 0 yellow3 +139 139 0 yellow4 +255 215 0 gold1 +238 201 0 gold2 +205 173 0 gold3 +139 117 0 gold4 +255 193 37 goldenrod1 +238 180 34 goldenrod2 +205 155 29 goldenrod3 +139 105 20 goldenrod4 +255 185 15 DarkGoldenrod1 +238 173 14 DarkGoldenrod2 +205 149 12 DarkGoldenrod3 +139 101 8 DarkGoldenrod4 +255 193 193 RosyBrown1 +238 180 180 RosyBrown2 +205 155 155 RosyBrown3 +139 105 105 RosyBrown4 +255 106 106 IndianRed1 +238 99 99 IndianRed2 +205 85 85 IndianRed3 +139 58 58 IndianRed4 +255 130 71 sienna1 +238 121 66 sienna2 +205 104 57 sienna3 +139 71 38 sienna4 +255 211 155 burlywood1 +238 197 145 burlywood2 +205 170 125 burlywood3 +139 115 85 burlywood4 +255 231 186 wheat1 +238 216 174 wheat2 +205 186 150 wheat3 +139 126 102 wheat4 +255 165 79 tan1 +238 154 73 tan2 +205 133 63 tan3 +139 90 43 tan4 +255 127 36 chocolate1 +238 118 33 chocolate2 +205 102 29 chocolate3 +139 69 19 chocolate4 +255 48 48 firebrick1 +238 44 44 firebrick2 +205 38 38 firebrick3 +139 26 26 firebrick4 +255 64 64 brown1 +238 59 59 brown2 +205 51 51 brown3 +139 35 35 brown4 +255 140 105 salmon1 +238 130 98 salmon2 +205 112 84 salmon3 +139 76 57 salmon4 +255 160 122 LightSalmon1 +238 149 114 LightSalmon2 +205 129 98 LightSalmon3 +139 87 66 LightSalmon4 +255 165 0 orange1 +238 154 0 orange2 +205 133 0 orange3 +139 90 0 orange4 +255 127 0 DarkOrange1 +238 118 0 DarkOrange2 +205 102 0 DarkOrange3 +139 69 0 DarkOrange4 +255 114 86 coral1 +238 106 80 coral2 +205 91 69 coral3 +139 62 47 coral4 +255 99 71 tomato1 +238 92 66 tomato2 +205 79 57 tomato3 +139 54 38 tomato4 +255 69 0 OrangeRed1 +238 64 0 OrangeRed2 +205 55 0 OrangeRed3 +139 37 0 OrangeRed4 +255 0 0 red1 +238 0 0 red2 +205 0 0 red3 +139 0 0 red4 +255 20 147 DeepPink1 +238 18 137 DeepPink2 +205 16 118 DeepPink3 +139 10 80 DeepPink4 +255 110 180 HotPink1 +238 106 167 HotPink2 +205 96 144 HotPink3 +139 58 98 HotPink4 +255 181 197 pink1 +238 169 184 pink2 +205 145 158 pink3 +139 99 108 pink4 +255 174 185 LightPink1 +238 162 173 LightPink2 +205 140 149 LightPink3 +139 95 101 LightPink4 +255 130 171 PaleVioletRed1 +238 121 159 PaleVioletRed2 +205 104 137 PaleVioletRed3 +139 71 93 PaleVioletRed4 +255 52 179 maroon1 +238 48 167 maroon2 +205 41 144 maroon3 +139 28 98 maroon4 +255 62 150 VioletRed1 +238 58 140 VioletRed2 +205 50 120 VioletRed3 +139 34 82 VioletRed4 +255 0 255 magenta1 +238 0 238 magenta2 +205 0 205 magenta3 +139 0 139 magenta4 +255 131 250 orchid1 +238 122 233 orchid2 +205 105 201 orchid3 +139 71 137 orchid4 +255 187 255 plum1 +238 174 238 plum2 +205 150 205 plum3 +139 102 139 plum4 +224 102 255 MediumOrchid1 +209 95 238 MediumOrchid2 +180 82 205 MediumOrchid3 +122 55 139 MediumOrchid4 +191 62 255 DarkOrchid1 +178 58 238 DarkOrchid2 +154 50 205 DarkOrchid3 +104 34 139 DarkOrchid4 +155 48 255 purple1 +145 44 238 purple2 +125 38 205 purple3 + 85 26 139 purple4 +171 130 255 MediumPurple1 +159 121 238 MediumPurple2 +137 104 205 MediumPurple3 + 93 71 139 MediumPurple4 +255 225 255 thistle1 +238 210 238 thistle2 +205 181 205 thistle3 +139 123 139 thistle4 + 0 0 0 gray0 + 0 0 0 grey0 + 3 3 3 gray1 + 3 3 3 grey1 + 5 5 5 gray2 + 5 5 5 grey2 + 8 8 8 gray3 + 8 8 8 grey3 + 10 10 10 gray4 + 10 10 10 grey4 + 13 13 13 gray5 + 13 13 13 grey5 + 15 15 15 gray6 + 15 15 15 grey6 + 18 18 18 gray7 + 18 18 18 grey7 + 20 20 20 gray8 + 20 20 20 grey8 + 23 23 23 gray9 + 23 23 23 grey9 + 26 26 26 gray10 + 26 26 26 grey10 + 28 28 28 gray11 + 28 28 28 grey11 + 31 31 31 gray12 + 31 31 31 grey12 + 33 33 33 gray13 + 33 33 33 grey13 + 36 36 36 gray14 + 36 36 36 grey14 + 38 38 38 gray15 + 38 38 38 grey15 + 41 41 41 gray16 + 41 41 41 grey16 + 43 43 43 gray17 + 43 43 43 grey17 + 46 46 46 gray18 + 46 46 46 grey18 + 48 48 48 gray19 + 48 48 48 grey19 + 51 51 51 gray20 + 51 51 51 grey20 + 54 54 54 gray21 + 54 54 54 grey21 + 56 56 56 gray22 + 56 56 56 grey22 + 59 59 59 gray23 + 59 59 59 grey23 + 61 61 61 gray24 + 61 61 61 grey24 + 64 64 64 gray25 + 64 64 64 grey25 + 66 66 66 gray26 + 66 66 66 grey26 + 69 69 69 gray27 + 69 69 69 grey27 + 71 71 71 gray28 + 71 71 71 grey28 + 74 74 74 gray29 + 74 74 74 grey29 + 77 77 77 gray30 + 77 77 77 grey30 + 79 79 79 gray31 + 79 79 79 grey31 + 82 82 82 gray32 + 82 82 82 grey32 + 84 84 84 gray33 + 84 84 84 grey33 + 87 87 87 gray34 + 87 87 87 grey34 + 89 89 89 gray35 + 89 89 89 grey35 + 92 92 92 gray36 + 92 92 92 grey36 + 94 94 94 gray37 + 94 94 94 grey37 + 97 97 97 gray38 + 97 97 97 grey38 + 99 99 99 gray39 + 99 99 99 grey39 +102 102 102 gray40 +102 102 102 grey40 +105 105 105 gray41 +105 105 105 grey41 +107 107 107 gray42 +107 107 107 grey42 +110 110 110 gray43 +110 110 110 grey43 +112 112 112 gray44 +112 112 112 grey44 +115 115 115 gray45 +115 115 115 grey45 +117 117 117 gray46 +117 117 117 grey46 +120 120 120 gray47 +120 120 120 grey47 +122 122 122 gray48 +122 122 122 grey48 +125 125 125 gray49 +125 125 125 grey49 +127 127 127 gray50 +127 127 127 grey50 +130 130 130 gray51 +130 130 130 grey51 +133 133 133 gray52 +133 133 133 grey52 +135 135 135 gray53 +135 135 135 grey53 +138 138 138 gray54 +138 138 138 grey54 +140 140 140 gray55 +140 140 140 grey55 +143 143 143 gray56 +143 143 143 grey56 +145 145 145 gray57 +145 145 145 grey57 +148 148 148 gray58 +148 148 148 grey58 +150 150 150 gray59 +150 150 150 grey59 +153 153 153 gray60 +153 153 153 grey60 +156 156 156 gray61 +156 156 156 grey61 +158 158 158 gray62 +158 158 158 grey62 +161 161 161 gray63 +161 161 161 grey63 +163 163 163 gray64 +163 163 163 grey64 +166 166 166 gray65 +166 166 166 grey65 +168 168 168 gray66 +168 168 168 grey66 +171 171 171 gray67 +171 171 171 grey67 +173 173 173 gray68 +173 173 173 grey68 +176 176 176 gray69 +176 176 176 grey69 +179 179 179 gray70 +179 179 179 grey70 +181 181 181 gray71 +181 181 181 grey71 +184 184 184 gray72 +184 184 184 grey72 +186 186 186 gray73 +186 186 186 grey73 +189 189 189 gray74 +189 189 189 grey74 +191 191 191 gray75 +191 191 191 grey75 +194 194 194 gray76 +194 194 194 grey76 +196 196 196 gray77 +196 196 196 grey77 +199 199 199 gray78 +199 199 199 grey78 +201 201 201 gray79 +201 201 201 grey79 +204 204 204 gray80 +204 204 204 grey80 +207 207 207 gray81 +207 207 207 grey81 +209 209 209 gray82 +209 209 209 grey82 +212 212 212 gray83 +212 212 212 grey83 +214 214 214 gray84 +214 214 214 grey84 +217 217 217 gray85 +217 217 217 grey85 +219 219 219 gray86 +219 219 219 grey86 +222 222 222 gray87 +222 222 222 grey87 +224 224 224 gray88 +224 224 224 grey88 +227 227 227 gray89 +227 227 227 grey89 +229 229 229 gray90 +229 229 229 grey90 +232 232 232 gray91 +232 232 232 grey91 +235 235 235 gray92 +235 235 235 grey92 +237 237 237 gray93 +237 237 237 grey93 +240 240 240 gray94 +240 240 240 grey94 +242 242 242 gray95 +242 242 242 grey95 +245 245 245 gray96 +245 245 245 grey96 +247 247 247 gray97 +247 247 247 grey97 +250 250 250 gray98 +250 250 250 grey98 +252 252 252 gray99 +252 252 252 grey99 +255 255 255 gray100 +255 255 255 grey100 +169 169 169 dark grey +169 169 169 DarkGrey +169 169 169 dark gray +169 169 169 DarkGray +0 0 139 dark blue +0 0 139 DarkBlue +0 139 139 dark cyan +0 139 139 DarkCyan +139 0 139 dark magenta +139 0 139 DarkMagenta +139 0 0 dark red +139 0 0 DarkRed +144 238 144 light green +144 238 144 LightGreen + + + \ No newline at end of file