From 74dbe3d93300c6bee01cdda38a337d7e46f0be84 Mon Sep 17 00:00:00 2001 From: Justin Marshall Date: Sun, 10 May 2026 01:30:36 -0700 Subject: [PATCH] Quake 4 related bug fixes. --- neo/engine/doomdll.vcxproj.user | 2 +- neo/engine/framework/Console.cpp | 6 + neo/engine/framework/DeclManager.cpp | 1684 +++++++----- neo/engine/framework/DeclManager.h | 368 +-- neo/engine/framework/Licensee.h | 2 + neo/engine/framework/Session.cpp | 4 +- neo/engine/idlib/Lexer.cpp | 88 +- neo/engine/idlib/Str.cpp | 13 - neo/engine/renderer/Image_program.cpp | 14 + neo/engine/renderer/Material.cpp | 30 +- neo/engine/renderer/Material.h | 4 - neo/engine/renderer/RenderWorld_load.cpp | 49 + neo/engine/renderer/tr_font.cpp | 367 ++- neo/engine/sound/snd_world.cpp | 2 +- neo/engine/tools/compilers/aas/AASFile.cpp | 5 + neo/engine/ui/EditWindow.cpp | 12 +- neo/engine/ui/GuiScript.cpp | 838 ++++-- neo/engine/ui/GuiScript.h | 62 +- neo/engine/ui/Window.cpp | 2702 ++++++++++++-------- neo/engine/ui/Window.h | 424 +-- neo/engine/ui/Winvar.cpp | 41 +- neo/engine/ui/Winvar.h | 582 +++-- neo/quake4/cm/CollisionModel_load.cpp | 2 +- neo/quake4/game/Game.h | 1 + neo/quake4/game/Game_local.cpp | 23 +- neo/quake4/game/Game_local.h | 1 + neo/quake4/idLib/LexerFactory.cpp | 6 +- 27 files changed, 4555 insertions(+), 2777 deletions(-) diff --git a/neo/engine/doomdll.vcxproj.user b/neo/engine/doomdll.vcxproj.user index e3301e5b..27c8058f 100644 --- a/neo/engine/doomdll.vcxproj.user +++ b/neo/engine/doomdll.vcxproj.user @@ -20,7 +20,7 @@ +set r_fullscreen 0 +set r_mode 6|+set r_fullscreen 1 +set r_mode 6|+set r_fullscreen 1 +set r_mode 1|+set r_fullscreen 0 +set r_mode 1| - D:\projects\Doom3\Doom3.exe + D:\projects\Doom3\Quake4.exe WindowsLocalDebugger +set r_fullscreen 0 +set r_mode 1 D:\projects\Doom3 diff --git a/neo/engine/framework/Console.cpp b/neo/engine/framework/Console.cpp index de8e09e9..2747d457 100644 --- a/neo/engine/framework/Console.cpp +++ b/neo/engine/framework/Console.cpp @@ -395,7 +395,13 @@ the renderSystem is initialized ============== */ void idConsoleLocal::LoadGraphics() { +#ifdef QUAKE4 +// jmarshall + charSetShader = declManager->FindMaterial("fonts/english/bigchars"); +// jmarshall end +#else charSetShader = declManager->FindMaterial( "textures/bigchars" ); +#endif whiteShader = declManager->FindMaterial( "_white" ); consoleShader = declManager->FindMaterial( "console" ); } diff --git a/neo/engine/framework/DeclManager.cpp b/neo/engine/framework/DeclManager.cpp index 9a43c532..7d7a68f7 100644 --- a/neo/engine/framework/DeclManager.cpp +++ b/neo/engine/framework/DeclManager.cpp @@ -2,9 +2,9 @@ =========================================================================== IceTech GPL Source Code -Copyright (C) 2026 Justin Marshall +Copyright (C) 2026 Justin Marshall -This file is part of the IceTech GPL Source Code (?IceTech Source Code?). +This file is part of the IceTech GPL Source Code (?IceTech Source Code?). IceTech Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -68,7 +68,7 @@ class idDeclType { public: idStr typeName; declType_t type; - idDecl * (*allocator)( void ); + idDecl* (*allocator)(void); }; class idDeclFolder { @@ -78,6 +78,16 @@ public: declType_t defaultType; }; +#ifdef QUAKE4 +// jmarshall: Quake 4 guide/template support +struct rvGuideTemplate { + idStr name; + idList parms; + idStr body; + bool inlineGuide; +}; +#endif + class idDeclFile; class idDeclLocal : public idDeclBase { @@ -85,58 +95,58 @@ class idDeclLocal : public idDeclBase { friend class idDeclManagerLocal; public: - idDeclLocal(); + idDeclLocal(); virtual ~idDeclLocal() {}; - virtual const char * GetName( void ) const; - virtual declType_t GetType( void ) const; - virtual declState_t GetState( void ) const; - virtual bool IsImplicit( void ) const; - virtual bool IsValid( void ) const; - virtual void Invalidate( void ); - virtual void Reload( void ); - virtual void EnsureNotPurged( void ); - virtual int Index( void ) const; - virtual int GetLineNum( void ) const; - virtual const char * GetFileName( void ) const; - virtual size_t Size( void ) const; - virtual void GetText( char *text ) const; - virtual int GetTextLength( void ) const; - virtual void SetText( const char *text ); - virtual bool ReplaceSourceFileText( void ); - virtual bool SourceFileChanged( void ) const; - virtual void MakeDefault( void ); - virtual bool EverReferenced( void ) const; + virtual const char* GetName(void) const; + virtual declType_t GetType(void) const; + virtual declState_t GetState(void) const; + virtual bool IsImplicit(void) const; + virtual bool IsValid(void) const; + virtual void Invalidate(void); + virtual void Reload(void); + virtual void EnsureNotPurged(void); + virtual int Index(void) const; + virtual int GetLineNum(void) const; + virtual const char* GetFileName(void) const; + virtual size_t Size(void) const; + virtual void GetText(char* text) const; + virtual int GetTextLength(void) const; + virtual void SetText(const char* text); + virtual bool ReplaceSourceFileText(void); + virtual bool SourceFileChanged(void) const; + virtual void MakeDefault(void); + virtual bool EverReferenced(void) const; protected: - virtual bool SetDefaultText( void ); - virtual const char * DefaultDefinition( void ) const; - virtual bool Parse( const char *text, const int textLength ); - virtual void FreeData( void ); - virtual void List( void ) const; - virtual void Print( void ) const; + virtual bool SetDefaultText(void); + virtual const char* DefaultDefinition(void) const; + virtual bool Parse(const char* text, const int textLength); + virtual void FreeData(void); + virtual void List(void) const; + virtual void Print(void) const; protected: - void AllocateSelf( void ); + void AllocateSelf(void); - // Parses the decl definition. - // After calling parse, a decl will be guaranteed usable. - void ParseLocal( void ); + // Parses the decl definition. + // After calling parse, a decl will be guaranteed usable. + void ParseLocal(void); - // Does a MakeDefualt, but flags the decl so that it - // will Parse() the next time the decl is found. - void Purge( void ); + // Does a MakeDefualt, but flags the decl so that it + // will Parse() the next time the decl is found. + void Purge(void); - // Set textSource possible with compression. - void SetTextLocal( const char *text, const int length ); + // Set textSource possible with compression. + void SetTextLocal(const char* text, const int length); private: - idDecl * self; + idDecl* self; idStr name; // name of the decl - char * textSource; // decl text definition + char* textSource; // decl text definition int textLength; // length of textSource int compressedLength; // compressed length - idDeclFile * sourceFile; // source file in which the decl was defined + idDeclFile* sourceFile; // source file in which the decl was defined int sourceTextOffset; // offset in source file to decl text int sourceTextLength; // length of decl text in source file int sourceLine; // this is where the actual declaration token starts @@ -149,16 +159,16 @@ private: bool everReferenced; // set to true if the decl was ever used bool referencedThisLevel; // set to true when the decl is used for the current level bool redefinedInReload; // used during file reloading to make sure a decl that has - // its source removed will be defaulted - idDeclLocal * nextInFile; // next decl in the decl file + // its source removed will be defaulted + idDeclLocal* nextInFile; // next decl in the decl file }; class idDeclFile { public: - idDeclFile(); - idDeclFile( const char *fileName, declType_t defaultType ); + idDeclFile(); + idDeclFile(const char* fileName, declType_t defaultType); - void Reload( bool force ); + void Reload(bool force); int LoadAndParse(); public: @@ -170,49 +180,59 @@ public: int fileSize; int numLines; - idDeclLocal * decls; + idDeclLocal* decls; }; class idDeclManagerLocal : public idDeclManager { friend class idDeclLocal; public: - virtual void Init( void ); - virtual void Shutdown( void ); - virtual void Reload( bool force ); + virtual void Init(void); + virtual void Shutdown(void); + virtual void Reload(bool force); + +#ifdef QUAKE4 + // Quake 4 guide/template support + virtual void ParseGuides(void); + virtual void ShutdownGuides(void); + virtual bool EvaluateGuide(idStr& name, idLexer* src, idStr& definition); + virtual bool EvaluateInlineGuide(idStr& name, idStr& definition); +#endif + virtual void BeginLevelLoad(); virtual void EndLevelLoad(); - virtual void RegisterDeclType( const char *typeName, declType_t type, idDecl *(*allocator)( void ) ); - virtual void RegisterDeclFolder( const char *folder, const char *extension, declType_t defaultType ); - virtual int GetChecksum( void ) const; - virtual int GetNumDeclTypes( void ) const; - virtual int GetNumDecls( declType_t type ); - virtual const char * GetDeclNameFromType( declType_t type ) const; - virtual declType_t GetDeclTypeFromName( const char *typeName ) const; - virtual const idDecl * FindType( declType_t type, const char *name, bool makeDefault = true ); - virtual const idDecl * DeclByIndex( declType_t type, int index, bool forceParse = true ); + virtual void RegisterDeclType(const char* typeName, declType_t type, idDecl* (*allocator)(void)); + virtual void RegisterDeclFolder(const char* folder, const char* extension, declType_t defaultType); + void RegisterDeclSubFolder(const char* folder, const char* extension, idList& fileList); + virtual int GetChecksum(void) const; + virtual int GetNumDeclTypes(void) const; + virtual int GetNumDecls(declType_t type); + virtual const char* GetDeclNameFromType(declType_t type) const; + virtual declType_t GetDeclTypeFromName(const char* typeName) const; + virtual const idDecl* FindType(declType_t type, const char* name, bool makeDefault = true); + virtual const idDecl* DeclByIndex(declType_t type, int index, bool forceParse = true); - virtual const idDecl* FindDeclWithoutParsing( declType_t type, const char *name, bool makeDefault = true ); - virtual void ReloadFile( const char* filename, bool force ); + virtual const idDecl* FindDeclWithoutParsing(declType_t type, const char* name, bool makeDefault = true); + virtual void ReloadFile(const char* filename, bool force); - virtual void ListType( const idCmdArgs &args, declType_t type ); - virtual void PrintType( const idCmdArgs &args, declType_t type ); + virtual void ListType(const idCmdArgs& args, declType_t type); + virtual void PrintType(const idCmdArgs& args, declType_t type); - virtual idDecl * CreateNewDecl( declType_t type, const char *name, const char *fileName ); + virtual idDecl* CreateNewDecl(declType_t type, const char* name, const char* fileName); //BSM Added for the material editors rename capabilities - virtual bool RenameDecl( declType_t type, const char* oldName, const char* newName ); + virtual bool RenameDecl(declType_t type, const char* oldName, const char* newName); - virtual void MediaPrint( const char *fmt, ... ) id_attribute((format(printf,2,3))); - virtual void WritePrecacheCommands( idFile *f ); + virtual void MediaPrint(const char* fmt, ...) id_attribute((format(printf, 2, 3))); + virtual void WritePrecacheCommands(idFile* f); - virtual const idMaterial * FindMaterial( const char *name, bool makeDefault = true ); - virtual const idDeclSkin * FindSkin( const char *name, bool makeDefault = true ); - virtual const idSoundShader * FindSound( const char *name, bool makeDefault = true ); + virtual const idMaterial* FindMaterial(const char* name, bool makeDefault = true); + virtual const idDeclSkin* FindSkin(const char* name, bool makeDefault = true); + virtual const idSoundShader* FindSound(const char* name, bool makeDefault = true); - virtual const idMaterial * MaterialByIndex( int index, bool forceParse = true ); - virtual const idDeclSkin * SkinByIndex( int index, bool forceParse = true ); - virtual const idSoundShader * SoundByIndex( int index, bool forceParse = true ); + virtual const idMaterial* MaterialByIndex(int index, bool forceParse = true); + virtual const idDeclSkin* SkinByIndex(int index, bool forceParse = true); + virtual const idSoundShader* SoundByIndex(int index, bool forceParse = true); virtual const class idDeclTable* FindTable(const char* name, bool makeDefault = true); @@ -228,22 +248,26 @@ public: virtual const class rvDeclEffect* EffectByIndex(int index, bool forceParse = true); #endif public: - static void MakeNameCanonical( const char *name, char *result, int maxLength ); - idDeclLocal * FindTypeWithoutParsing( declType_t type, const char *name, bool makeDefault = true ); + static void MakeNameCanonical(const char* name, char* result, int maxLength); + idDeclLocal* FindTypeWithoutParsing(declType_t type, const char* name, bool makeDefault = true); - idDeclType * GetDeclType( int type ) const { return declTypes[type]; } - const idDeclFile * GetImplicitDeclFile( void ) const { return &implicitDecls; } + idDeclType* GetDeclType(int type) const { return declTypes[type]; } + const idDeclFile* GetImplicitDeclFile(void) const { return &implicitDecls; } + +#ifdef QUAKE4 + idList guides; +#endif private: - idList declTypes; - idList declFolders; + idList declTypes; + idList declFolders; - idList loadedFiles; + idList loadedFiles; idHashIndex hashTables[DECL_MAX_TYPES]; - idList linearLists[DECL_MAX_TYPES]; + idList linearLists[DECL_MAX_TYPES]; idDeclFile implicitDecls; // this holds all the decls that were created because explicit - // text definitions were not found. Decls that became default - // because of a parse error are not in this list. + // text definitions were not found. Decls that became default + // because of a parse error are not in this list. int checksum; // checksum of all loaded decl text int indent; // for MediaPrint bool insideLevelLoad; @@ -251,15 +275,15 @@ private: static idCVar decl_show; private: - static void ListDecls_f( const idCmdArgs &args ); - static void ReloadDecls_f( const idCmdArgs &args ); - static void TouchDecl_f( const idCmdArgs &args ); + static void ListDecls_f(const idCmdArgs& args); + static void ReloadDecls_f(const idCmdArgs& args); + static void TouchDecl_f(const idCmdArgs& args); }; -idCVar idDeclManagerLocal::decl_show( "decl_show", "0", CVAR_SYSTEM, "set to 1 to print parses, 2 to also print references", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> ); +idCVar idDeclManagerLocal::decl_show("decl_show", "0", CVAR_SYSTEM, "set to 1 to print parses, 2 to also print references", 0, 2, idCmdSystem::ArgCompletion_Integer<0, 2>); idDeclManagerLocal declManagerLocal; -idDeclManager * declManager = &declManagerLocal; +idDeclManager* declManager = &declManagerLocal; /* ==================================================================================== @@ -269,13 +293,13 @@ idDeclManager * declManager = &declManagerLocal; ==================================================================================== */ -const int MAX_HUFFMAN_SYMBOLS = 256; +const int MAX_HUFFMAN_SYMBOLS = 256; typedef struct huffmanNode_s { int symbol; int frequency; - struct huffmanNode_s * next; - struct huffmanNode_s * children[2]; + struct huffmanNode_s* next; + struct huffmanNode_s* children[2]; } huffmanNode_t; typedef struct huffmanCode_s { @@ -285,43 +309,43 @@ typedef struct huffmanCode_s { // compression ratio = 64% static int huffmanFrequencies[] = { - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00078fb6, 0x000352a7, 0x00000002, 0x00000001, 0x0002795e, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00049600, 0x000000dd, 0x00018732, 0x0000005a, 0x00000007, 0x00000092, 0x0000000a, 0x00000919, - 0x00002dcf, 0x00002dda, 0x00004dfc, 0x0000039a, 0x000058be, 0x00002d13, 0x00014d8c, 0x00023c60, - 0x0002ddb0, 0x0000d1fc, 0x000078c4, 0x00003ec7, 0x00003113, 0x00006b59, 0x00002499, 0x0000184a, - 0x0000250b, 0x00004e38, 0x000001ca, 0x00000011, 0x00000020, 0x000023da, 0x00000012, 0x00000091, - 0x0000000b, 0x00000b14, 0x0000035d, 0x0000137e, 0x000020c9, 0x00000e11, 0x000004b4, 0x00000737, - 0x000006b8, 0x00001110, 0x000006b3, 0x000000fe, 0x00000f02, 0x00000d73, 0x000005f6, 0x00000be4, - 0x00000d86, 0x0000014d, 0x00000d89, 0x0000129b, 0x00000db3, 0x0000015a, 0x00000167, 0x00000375, - 0x00000028, 0x00000112, 0x00000018, 0x00000678, 0x0000081a, 0x00000677, 0x00000003, 0x00018112, - 0x00000001, 0x000441ee, 0x000124b0, 0x0001fa3f, 0x00026125, 0x0005a411, 0x0000e50f, 0x00011820, - 0x00010f13, 0x0002e723, 0x00003518, 0x00005738, 0x0002cc26, 0x0002a9b7, 0x0002db81, 0x0003b5fa, - 0x000185d2, 0x00001299, 0x00030773, 0x0003920d, 0x000411cd, 0x00018751, 0x00005fbd, 0x000099b0, - 0x00009242, 0x00007cf2, 0x00002809, 0x00005a1d, 0x00000001, 0x00005a1d, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00078fb6, 0x000352a7, 0x00000002, 0x00000001, 0x0002795e, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00049600, 0x000000dd, 0x00018732, 0x0000005a, 0x00000007, 0x00000092, 0x0000000a, 0x00000919, + 0x00002dcf, 0x00002dda, 0x00004dfc, 0x0000039a, 0x000058be, 0x00002d13, 0x00014d8c, 0x00023c60, + 0x0002ddb0, 0x0000d1fc, 0x000078c4, 0x00003ec7, 0x00003113, 0x00006b59, 0x00002499, 0x0000184a, + 0x0000250b, 0x00004e38, 0x000001ca, 0x00000011, 0x00000020, 0x000023da, 0x00000012, 0x00000091, + 0x0000000b, 0x00000b14, 0x0000035d, 0x0000137e, 0x000020c9, 0x00000e11, 0x000004b4, 0x00000737, + 0x000006b8, 0x00001110, 0x000006b3, 0x000000fe, 0x00000f02, 0x00000d73, 0x000005f6, 0x00000be4, + 0x00000d86, 0x0000014d, 0x00000d89, 0x0000129b, 0x00000db3, 0x0000015a, 0x00000167, 0x00000375, + 0x00000028, 0x00000112, 0x00000018, 0x00000678, 0x0000081a, 0x00000677, 0x00000003, 0x00018112, + 0x00000001, 0x000441ee, 0x000124b0, 0x0001fa3f, 0x00026125, 0x0005a411, 0x0000e50f, 0x00011820, + 0x00010f13, 0x0002e723, 0x00003518, 0x00005738, 0x0002cc26, 0x0002a9b7, 0x0002db81, 0x0003b5fa, + 0x000185d2, 0x00001299, 0x00030773, 0x0003920d, 0x000411cd, 0x00018751, 0x00005fbd, 0x000099b0, + 0x00009242, 0x00007cf2, 0x00002809, 0x00005a1d, 0x00000001, 0x00005a1d, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, - 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }; static huffmanCode_t huffmanCodes[MAX_HUFFMAN_SYMBOLS]; -static huffmanNode_t *huffmanTree = NULL; +static huffmanNode_t* huffmanTree = NULL; static int totalUncompressedLength = 0; static int totalCompressedLength = 0; static int maxHuffmanBits = 0; @@ -332,10 +356,10 @@ static int maxHuffmanBits = 0; ClearHuffmanFrequencies ================ */ -void ClearHuffmanFrequencies( void ) { +void ClearHuffmanFrequencies(void) { int i; - for( i = 0; i < MAX_HUFFMAN_SYMBOLS; i++ ) { + for (i = 0; i < MAX_HUFFMAN_SYMBOLS; i++) { huffmanFrequencies[i] = 1; } } @@ -345,20 +369,21 @@ void ClearHuffmanFrequencies( void ) { InsertHuffmanNode ================ */ -huffmanNode_t *InsertHuffmanNode( huffmanNode_t *firstNode, huffmanNode_t *node ) { - huffmanNode_t *n, *lastNode; +huffmanNode_t* InsertHuffmanNode(huffmanNode_t* firstNode, huffmanNode_t* node) { + huffmanNode_t* n, * lastNode; lastNode = NULL; - for ( n = firstNode; n; n = n->next ) { - if ( node->frequency <= n->frequency ) { + for (n = firstNode; n; n = n->next) { + if (node->frequency <= n->frequency) { break; } lastNode = n; } - if ( lastNode ) { + if (lastNode) { node->next = lastNode->next; lastNode->next = node; - } else { + } + else { node->next = firstNode; firstNode = node; } @@ -370,19 +395,20 @@ huffmanNode_t *InsertHuffmanNode( huffmanNode_t *firstNode, huffmanNode_t *node BuildHuffmanCode_r ================ */ -void BuildHuffmanCode_r( huffmanNode_t *node, huffmanCode_t code, huffmanCode_t codes[MAX_HUFFMAN_SYMBOLS] ) { - if ( node->symbol == -1 ) { +void BuildHuffmanCode_r(huffmanNode_t* node, huffmanCode_t code, huffmanCode_t codes[MAX_HUFFMAN_SYMBOLS]) { + if (node->symbol == -1) { huffmanCode_t newCode = code; - assert( code.numBits < sizeof( codes[0].bits ) * 8 ); + assert(code.numBits < sizeof(codes[0].bits) * 8); newCode.numBits++; - if ( code.numBits > maxHuffmanBits ) { + if (code.numBits > maxHuffmanBits) { maxHuffmanBits = newCode.numBits; } - BuildHuffmanCode_r( node->children[0], newCode, codes ); - newCode.bits[code.numBits >> 5] |= 1 << ( code.numBits & 31 ); - BuildHuffmanCode_r( node->children[1], newCode, codes ); - } else { - assert( code.numBits <= sizeof( codes[0].bits ) * 8 ); + BuildHuffmanCode_r(node->children[0], newCode, codes); + newCode.bits[code.numBits >> 5] |= 1 << (code.numBits & 31); + BuildHuffmanCode_r(node->children[1], newCode, codes); + } + else { + assert(code.numBits <= sizeof(codes[0].bits) * 8); codes[node->symbol] = code; } } @@ -392,10 +418,10 @@ void BuildHuffmanCode_r( huffmanNode_t *node, huffmanCode_t code, huffmanCode_t FreeHuffmanTree_r ================ */ -void FreeHuffmanTree_r( huffmanNode_t *node ) { - if ( node->symbol == -1 ) { - FreeHuffmanTree_r( node->children[0] ); - FreeHuffmanTree_r( node->children[1] ); +void FreeHuffmanTree_r(huffmanNode_t* node) { + if (node->symbol == -1) { + FreeHuffmanTree_r(node->children[0]); + FreeHuffmanTree_r(node->children[1]); } delete node; } @@ -405,13 +431,13 @@ void FreeHuffmanTree_r( huffmanNode_t *node ) { HuffmanHeight_r ================ */ -int HuffmanHeight_r( huffmanNode_t *node ) { - if ( node == NULL ) { +int HuffmanHeight_r(huffmanNode_t* node) { + if (node == NULL) { return -1; } - int left = HuffmanHeight_r( node->children[0] ); - int right = HuffmanHeight_r( node->children[1] ); - if ( left > right ) { + int left = HuffmanHeight_r(node->children[0]); + int right = HuffmanHeight_r(node->children[1]); + if (left > right) { return left + 1; } return right + 1; @@ -422,40 +448,40 @@ int HuffmanHeight_r( huffmanNode_t *node ) { SetupHuffman ================ */ -void SetupHuffman( void ) { +void SetupHuffman(void) { int i, height; - huffmanNode_t *firstNode, *node; + huffmanNode_t* firstNode, * node; huffmanCode_t code; firstNode = NULL; - for( i = 0; i < MAX_HUFFMAN_SYMBOLS; i++ ) { + for (i = 0; i < MAX_HUFFMAN_SYMBOLS; i++) { node = new huffmanNode_t; node->symbol = i; node->frequency = huffmanFrequencies[i]; node->next = NULL; node->children[0] = NULL; node->children[1] = NULL; - firstNode = InsertHuffmanNode( firstNode, node ); + firstNode = InsertHuffmanNode(firstNode, node); } - for( i = 1; i < MAX_HUFFMAN_SYMBOLS; i++ ) { + for (i = 1; i < MAX_HUFFMAN_SYMBOLS; i++) { node = new huffmanNode_t; node->symbol = -1; node->frequency = firstNode->frequency + firstNode->next->frequency; node->next = NULL; node->children[0] = firstNode; node->children[1] = firstNode->next; - firstNode = InsertHuffmanNode( firstNode->next->next, node ); + firstNode = InsertHuffmanNode(firstNode->next->next, node); } maxHuffmanBits = 0; - memset( &code, 0, sizeof( code ) ); - BuildHuffmanCode_r( firstNode, code, huffmanCodes ); + memset(&code, 0, sizeof(code)); + BuildHuffmanCode_r(firstNode, code, huffmanCodes); huffmanTree = firstNode; - height = HuffmanHeight_r( firstNode ); - assert( maxHuffmanBits == height ); + height = HuffmanHeight_r(firstNode); + assert(maxHuffmanBits == height); } /* @@ -463,9 +489,9 @@ void SetupHuffman( void ) { ShutdownHuffman ================ */ -void ShutdownHuffman( void ) { - if ( huffmanTree ) { - FreeHuffmanTree_r( huffmanTree ); +void ShutdownHuffman(void) { + if (huffmanTree) { + FreeHuffmanTree_r(huffmanTree); } } @@ -474,21 +500,21 @@ void ShutdownHuffman( void ) { HuffmanCompressText ================ */ -int HuffmanCompressText( const char *text, int textLength, byte *compressed, int maxCompressedSize ) { +int HuffmanCompressText(const char* text, int textLength, byte* compressed, int maxCompressedSize) { int i, j; idBitMsg msg; totalUncompressedLength += textLength; - msg.Init( compressed, maxCompressedSize ); + msg.Init(compressed, maxCompressedSize); msg.BeginWriting(); - for ( i = 0; i < textLength; i++ ) { - const huffmanCode_t &code = huffmanCodes[(unsigned char)text[i]]; - for ( j = 0; j < ( code.numBits >> 5 ); j++ ) { - msg.WriteBits( code.bits[j], 32 ); + for (i = 0; i < textLength; i++) { + const huffmanCode_t& code = huffmanCodes[(unsigned char)text[i]]; + for (j = 0; j < (code.numBits >> 5); j++) { + msg.WriteBits(code.bits[j], 32); } - if ( code.numBits & 31 ) { - msg.WriteBits( code.bits[j], code.numBits & 31 ); + if (code.numBits & 31) { + msg.WriteBits(code.bits[j], code.numBits & 31); } } @@ -502,20 +528,20 @@ int HuffmanCompressText( const char *text, int textLength, byte *compressed, int HuffmanDecompressText ================ */ -int HuffmanDecompressText( char *text, int textLength, const byte *compressed, int compressedSize ) { +int HuffmanDecompressText(char* text, int textLength, const byte* compressed, int compressedSize) { int i, bit; idBitMsg msg; - huffmanNode_t *node; + huffmanNode_t* node; - msg.Init( compressed, compressedSize ); - msg.SetSize( compressedSize ); + msg.Init(compressed, compressedSize); + msg.SetSize(compressedSize); msg.BeginReading(); - for ( i = 0; i < textLength; i++ ) { + for (i = 0; i < textLength; i++) { node = huffmanTree; do { - bit = msg.ReadBits( 1 ); + bit = msg.ReadBits(1); node = node->children[bit]; - } while( node->symbol == -1 ); + } while (node->symbol == -1); text[i] = node->symbol; } text[i] = '\0'; @@ -527,20 +553,20 @@ int HuffmanDecompressText( char *text, int textLength, const byte *compressed, i ListHuffmanFrequencies_f ================ */ -void ListHuffmanFrequencies_f( const idCmdArgs &args ) { +void ListHuffmanFrequencies_f(const idCmdArgs& args) { int i; float compression; compression = !totalUncompressedLength ? 100 : 100 * totalCompressedLength / totalUncompressedLength; - common->Printf( "// compression ratio = %d%%\n", (int)compression ); - common->Printf( "static int huffmanFrequencies[] = {\n" ); - for( i = 0; i < MAX_HUFFMAN_SYMBOLS; i += 8 ) { - common->Printf( "\t0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x,\n", - huffmanFrequencies[i+0], huffmanFrequencies[i+1], - huffmanFrequencies[i+2], huffmanFrequencies[i+3], - huffmanFrequencies[i+4], huffmanFrequencies[i+5], - huffmanFrequencies[i+6], huffmanFrequencies[i+7]); + common->Printf("// compression ratio = %d%%\n", (int)compression); + common->Printf("static int huffmanFrequencies[] = {\n"); + for (i = 0; i < MAX_HUFFMAN_SYMBOLS; i += 8) { + common->Printf("\t0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x,\n", + huffmanFrequencies[i + 0], huffmanFrequencies[i + 1], + huffmanFrequencies[i + 2], huffmanFrequencies[i + 3], + huffmanFrequencies[i + 4], huffmanFrequencies[i + 5], + huffmanFrequencies[i + 6], huffmanFrequencies[i + 7]); } - common->Printf( "}\n" ); + common->Printf("}\n"); } /* @@ -556,7 +582,7 @@ void ListHuffmanFrequencies_f( const idCmdArgs &args ) { idDeclFile::idDeclFile ================ */ -idDeclFile::idDeclFile( const char *fileName, declType_t defaultType ) { +idDeclFile::idDeclFile(const char* fileName, declType_t defaultType) { this->fileName = fileName; this->defaultType = defaultType; this->timestamp = 0; @@ -588,13 +614,13 @@ idDeclFile::Reload ForceReload will cause it to reload even if the timestamp hasn't changed ================ */ -void idDeclFile::Reload( bool force ) { +void idDeclFile::Reload(bool force) { // check for an unchanged timestamp - if ( !force && timestamp != 0 ) { + if (!force && timestamp != 0) { ID_TIME_T testTimeStamp; - fileSystem->ReadFile( fileName, NULL, &testTimeStamp ); + fileSystem->ReadFile(fileName, NULL, &testTimeStamp); - if ( testTimeStamp == timestamp ) { + if (testTimeStamp == timestamp) { return; } } @@ -617,146 +643,191 @@ int idDeclFile::LoadAndParse() { idLexer src; idToken token; int startMarker; - char * buffer; + char* buffer; int length, size; int sourceLine; idStr name; - idDeclLocal *newDecl; + idDeclLocal* newDecl; bool reparse; // load the text - common->DPrintf( "...loading '%s'\n", fileName.c_str() ); - length = fileSystem->ReadFile( fileName, (void **)&buffer, ×tamp ); - if ( length == -1 ) { - common->FatalError( "couldn't load %s", fileName.c_str() ); + common->DPrintf("...loading '%s'\n", fileName.c_str()); + length = fileSystem->ReadFile(fileName, (void**)&buffer, ×tamp); + if (length == -1) { + common->FatalError("couldn't load %s", fileName.c_str()); return 0; } - if ( !src.LoadMemory( buffer, length, fileName ) ) { - common->Error( "Couldn't parse %s", fileName.c_str() ); - Mem_Free( buffer ); + if (!src.LoadMemory(buffer, length, fileName)) { + common->Error("Couldn't parse %s", fileName.c_str()); + Mem_Free(buffer); return 0; } // mark all the defs that were from the last reload of this file - for ( idDeclLocal *decl = decls; decl; decl = decl->nextInFile ) { + for (idDeclLocal* decl = decls; decl; decl = decl->nextInFile) { decl->redefinedInReload = false; } - src.SetFlags( DECL_LEXER_FLAGS ); + src.SetFlags(DECL_LEXER_FLAGS); - checksum = MD5_BlockChecksum( buffer, length ); + checksum = MD5_BlockChecksum(buffer, length); fileSize = length; // scan through, identifying each individual declaration - while( 1 ) { + while (1) { startMarker = src.GetFileOffset(); sourceLine = src.GetLineNum(); // parse the decl type name - if ( !src.ReadToken( &token ) ) { + if (!src.ReadToken(&token)) { break; } +#ifdef QUAKE4 + bool guide = false; + if (token.Icmp("guide") == 0) { + guide = true; + if (!src.ReadToken(&token)) { + src.Warning("Type without definition at end of file"); + break; + } + } +#endif + declType_t identifiedType = DECL_MAX_TYPES; // get the decl type from the type name numTypes = declManagerLocal.GetNumDeclTypes(); - for ( i = 0; i < numTypes; i++ ) { - idDeclType *typeInfo = declManagerLocal.GetDeclType( i ); - if ( typeInfo && typeInfo->typeName.Icmp( token ) == 0 ) { - identifiedType = (declType_t) typeInfo->type; + for (i = 0; i < numTypes; i++) { + idDeclType* typeInfo = declManagerLocal.GetDeclType(i); + if (typeInfo && typeInfo->typeName.Icmp(token) == 0) { + identifiedType = (declType_t)typeInfo->type; break; } } - if ( i >= numTypes ) { + if (i >= numTypes) { - if ( token.Icmp( "{" ) == 0 ) { + if (token.Icmp("{") == 0) { // if we ever see an open brace, we somehow missed the [type] prefix - src.Warning( "Missing decl name" ); - src.SkipBracedSection( false ); + src.Warning("Missing decl name"); + src.SkipBracedSection(false); continue; - } else { + } + else { - if ( defaultType == DECL_MAX_TYPES ) { - src.Warning( "No type" ); + if (defaultType == DECL_MAX_TYPES) { + src.Warning("No type"); continue; } - src.UnreadToken( &token ); + src.UnreadToken(&token); // use the default type identifiedType = defaultType; } } // now parse the name - if ( !src.ReadToken( &token ) ) { - src.Warning( "Type without definition at end of file" ); + if (!src.ReadToken(&token)) { + src.Warning("Type without definition at end of file"); break; } - if ( !token.Icmp( "{" ) ) { + if (!token.Icmp("{")) { // if we ever see an open brace, we somehow missed the [type] prefix - src.Warning( "Missing decl name" ); - src.SkipBracedSection( false ); + src.Warning("Missing decl name"); + src.SkipBracedSection(false); continue; } // FIXME: export decls are only used by the model exporter, they are skipped here for now - if ( identifiedType == DECL_MODELEXPORT ) { + if (identifiedType == DECL_MODELEXPORT) { src.SkipBracedSection(); continue; } name = token; - // make sure there's a '{' - if ( !src.ReadToken( &token ) ) { - src.Warning( "Type without definition at end of file" ); - break; - } - if ( token != "{" ) { - src.Warning( "Expecting '{' but found '%s'", token.c_str() ); - continue; - } - src.UnreadToken( &token ); + idStr declDefinition; + bool useExpandedDefinition = false; - // now take everything until a matched closing brace - src.SkipBracedSection(); - size = src.GetFileOffset() - startMarker; +#ifdef QUAKE4 + if (guide) { + if (!declManagerLocal.EvaluateGuide(name, &src, declDefinition)) { + continue; + } + declManagerLocal.EvaluateInlineGuide(name, declDefinition); + useExpandedDefinition = true; + size = declDefinition.Length(); + } + else +#endif + { + // make sure there's a '{' + if (!src.ReadToken(&token)) { + src.Warning("Type without definition at end of file"); + break; + } + if (token != "{") { + src.Warning("Expecting '{' but found '%s'", token.c_str()); + continue; + } + src.UnreadToken(&token); + + // now take everything until a matched closing brace + src.SkipBracedSection(); + size = src.GetFileOffset() - startMarker; + +#ifdef QUAKE4 + declDefinition = idStr(buffer).Mid(startMarker, size); + if (declManagerLocal.EvaluateInlineGuide(name, declDefinition)) { + useExpandedDefinition = true; + size = declDefinition.Length(); + } +#endif + } // look it up, possibly getting a newly created default decl reparse = false; - newDecl = declManagerLocal.FindTypeWithoutParsing( identifiedType, name, false ); - if ( newDecl ) { + newDecl = declManagerLocal.FindTypeWithoutParsing(identifiedType, name, false); + if (newDecl) { // update the existing copy - if ( newDecl->sourceFile != this || newDecl->redefinedInReload ) { - src.Warning( "%s '%s' previously defined at %s:%i", declManagerLocal.GetDeclNameFromType( identifiedType ), - name.c_str(), newDecl->sourceFile->fileName.c_str(), newDecl->sourceLine ); + if (newDecl->sourceFile != this || newDecl->redefinedInReload) { + src.Warning("%s '%s' previously defined at %s:%i", declManagerLocal.GetDeclNameFromType(identifiedType), + name.c_str(), newDecl->sourceFile->fileName.c_str(), newDecl->sourceLine); continue; } - if ( newDecl->declState != DS_UNPARSED ) { + if (newDecl->declState != DS_UNPARSED) { reparse = true; } - } else { + } + else { // allow it to be created as a default, then add it to the per-file list - newDecl = declManagerLocal.FindTypeWithoutParsing( identifiedType, name, true ); + newDecl = declManagerLocal.FindTypeWithoutParsing(identifiedType, name, true); newDecl->nextInFile = this->decls; this->decls = newDecl; } newDecl->redefinedInReload = true; - if ( newDecl->textSource ) { - Mem_Free( newDecl->textSource ); + if (newDecl->textSource) { + Mem_Free(newDecl->textSource); newDecl->textSource = NULL; } - newDecl->SetTextLocal( buffer + startMarker, size ); +#ifdef QUAKE4 + if (useExpandedDefinition) { + newDecl->SetTextLocal(declDefinition.c_str(), size); + } + else +#endif + { + newDecl->SetTextLocal(buffer + startMarker, size); + } newDecl->sourceFile = this; newDecl->sourceTextOffset = startMarker; newDecl->sourceTextLength = size; @@ -764,18 +835,18 @@ int idDeclFile::LoadAndParse() { newDecl->declState = DS_UNPARSED; // if it is currently in use, reparse it immedaitely - if ( reparse ) { + if (reparse) { newDecl->ParseLocal(); } } numLines = src.GetLineNum(); - Mem_Free( buffer ); + Mem_Free(buffer); // any defs that weren't redefinedInReload should now be defaulted - for ( idDeclLocal *decl = decls ; decl ; decl = decl->nextInFile ) { - if ( decl->redefinedInReload == false ) { + for (idDeclLocal* decl = decls; decl; decl = decl->nextInFile) { + if (decl->redefinedInReload == false) { decl->MakeDefault(); decl->sourceTextOffset = decl->sourceFile->fileSize; decl->sourceTextLength = 0; @@ -794,16 +865,16 @@ int idDeclFile::LoadAndParse() { ==================================================================================== */ -const char *listDeclStrings[] = { "current", "all", "ever", NULL }; +const char* listDeclStrings[] = { "current", "all", "ever", NULL }; /* =================== idDeclManagerLocal::Init =================== */ -void idDeclManagerLocal::Init( void ) { +void idDeclManagerLocal::Init(void) { - common->Printf( "----- Initializing Decls -----\n" ); + common->Printf("----- Initializing Decls -----\n"); checksum = 0; @@ -815,65 +886,69 @@ void idDeclManagerLocal::Init( void ) { ClearHuffmanFrequencies(); #endif +#ifdef QUAKE4 + ParseGuides(); +#endif + // decls used throughout the engine - RegisterDeclType( "table", DECL_TABLE, idDeclAllocator ); - RegisterDeclType( "material", DECL_MATERIAL, idDeclAllocator ); - RegisterDeclType( "skin", DECL_SKIN, idDeclAllocator ); - RegisterDeclType( "sound", DECL_SOUND, idDeclAllocator ); + RegisterDeclType("table", DECL_TABLE, idDeclAllocator); + RegisterDeclType("material", DECL_MATERIAL, idDeclAllocator); + RegisterDeclType("skin", DECL_SKIN, idDeclAllocator); + RegisterDeclType("sound", DECL_SOUND, idDeclAllocator); - RegisterDeclType( "entityDef", DECL_ENTITYDEF, idDeclAllocator ); - RegisterDeclType( "mapDef", DECL_MAPDEF, idDeclAllocator ); - RegisterDeclType( "fx", DECL_FX, idDeclAllocator ); - RegisterDeclType( "particle", DECL_PARTICLE, idDeclAllocator ); - RegisterDeclType( "articulatedFigure", DECL_AF, idDeclAllocator ); - RegisterDeclType( "pda", DECL_PDA, idDeclAllocator ); - RegisterDeclType( "email", DECL_EMAIL, idDeclAllocator ); - RegisterDeclType( "video", DECL_VIDEO, idDeclAllocator ); - RegisterDeclType( "audio", DECL_AUDIO, idDeclAllocator ); + RegisterDeclType("entityDef", DECL_ENTITYDEF, idDeclAllocator); + RegisterDeclType("mapDef", DECL_MAPDEF, idDeclAllocator); + RegisterDeclType("fx", DECL_FX, idDeclAllocator); + RegisterDeclType("particle", DECL_PARTICLE, idDeclAllocator); + RegisterDeclType("articulatedFigure", DECL_AF, idDeclAllocator); + RegisterDeclType("pda", DECL_PDA, idDeclAllocator); + RegisterDeclType("email", DECL_EMAIL, idDeclAllocator); + RegisterDeclType("video", DECL_VIDEO, idDeclAllocator); + RegisterDeclType("audio", DECL_AUDIO, idDeclAllocator); - RegisterDeclFolder( "materials", ".mtr", DECL_MATERIAL ); - RegisterDeclFolder( "skins", ".skin", DECL_SKIN ); - RegisterDeclFolder( "sound", ".sndshd", DECL_SOUND ); + RegisterDeclFolder("materials", ".mtr", DECL_MATERIAL); + RegisterDeclFolder("skins", ".skin", DECL_SKIN); + RegisterDeclFolder("sound", ".sndshd", DECL_SOUND); // add console commands - cmdSystem->AddCommand( "listDecls", ListDecls_f, CMD_FL_SYSTEM, "lists all decls" ); + cmdSystem->AddCommand("listDecls", ListDecls_f, CMD_FL_SYSTEM, "lists all decls"); - cmdSystem->AddCommand( "reloadDecls", ReloadDecls_f, CMD_FL_SYSTEM, "reloads decls" ); - cmdSystem->AddCommand( "touch", TouchDecl_f, CMD_FL_SYSTEM, "touches a decl" ); + cmdSystem->AddCommand("reloadDecls", ReloadDecls_f, CMD_FL_SYSTEM, "reloads decls"); + cmdSystem->AddCommand("touch", TouchDecl_f, CMD_FL_SYSTEM, "touches a decl"); - cmdSystem->AddCommand( "listTables", idListDecls_f, CMD_FL_SYSTEM, "lists tables", idCmdSystem::ArgCompletion_String ); - cmdSystem->AddCommand( "listMaterials", idListDecls_f, CMD_FL_SYSTEM, "lists materials", idCmdSystem::ArgCompletion_String ); - cmdSystem->AddCommand( "listSkins", idListDecls_f, CMD_FL_SYSTEM, "lists skins", idCmdSystem::ArgCompletion_String ); - cmdSystem->AddCommand( "listSoundShaders", idListDecls_f, CMD_FL_SYSTEM, "lists sound shaders", idCmdSystem::ArgCompletion_String ); + cmdSystem->AddCommand("listTables", idListDecls_f, CMD_FL_SYSTEM, "lists tables", idCmdSystem::ArgCompletion_String); + cmdSystem->AddCommand("listMaterials", idListDecls_f, CMD_FL_SYSTEM, "lists materials", idCmdSystem::ArgCompletion_String); + cmdSystem->AddCommand("listSkins", idListDecls_f, CMD_FL_SYSTEM, "lists skins", idCmdSystem::ArgCompletion_String); + cmdSystem->AddCommand("listSoundShaders", idListDecls_f, CMD_FL_SYSTEM, "lists sound shaders", idCmdSystem::ArgCompletion_String); - cmdSystem->AddCommand( "listEntityDefs", idListDecls_f, CMD_FL_SYSTEM, "lists entity defs", idCmdSystem::ArgCompletion_String ); - cmdSystem->AddCommand( "listFX", idListDecls_f, CMD_FL_SYSTEM, "lists FX systems", idCmdSystem::ArgCompletion_String ); - cmdSystem->AddCommand( "listParticles", idListDecls_f, CMD_FL_SYSTEM, "lists particle systems", idCmdSystem::ArgCompletion_String ); - cmdSystem->AddCommand( "listAF", idListDecls_f, CMD_FL_SYSTEM, "lists articulated figures", idCmdSystem::ArgCompletion_String); + cmdSystem->AddCommand("listEntityDefs", idListDecls_f, CMD_FL_SYSTEM, "lists entity defs", idCmdSystem::ArgCompletion_String); + cmdSystem->AddCommand("listFX", idListDecls_f, CMD_FL_SYSTEM, "lists FX systems", idCmdSystem::ArgCompletion_String); + cmdSystem->AddCommand("listParticles", idListDecls_f, CMD_FL_SYSTEM, "lists particle systems", idCmdSystem::ArgCompletion_String); + cmdSystem->AddCommand("listAF", idListDecls_f, CMD_FL_SYSTEM, "lists articulated figures", idCmdSystem::ArgCompletion_String); - cmdSystem->AddCommand( "listPDAs", idListDecls_f, CMD_FL_SYSTEM, "lists PDAs", idCmdSystem::ArgCompletion_String ); - cmdSystem->AddCommand( "listEmails", idListDecls_f, CMD_FL_SYSTEM, "lists Emails", idCmdSystem::ArgCompletion_String ); - cmdSystem->AddCommand( "listVideos", idListDecls_f, CMD_FL_SYSTEM, "lists Videos", idCmdSystem::ArgCompletion_String ); - cmdSystem->AddCommand( "listAudios", idListDecls_f, CMD_FL_SYSTEM, "lists Audios", idCmdSystem::ArgCompletion_String ); + cmdSystem->AddCommand("listPDAs", idListDecls_f, CMD_FL_SYSTEM, "lists PDAs", idCmdSystem::ArgCompletion_String); + cmdSystem->AddCommand("listEmails", idListDecls_f, CMD_FL_SYSTEM, "lists Emails", idCmdSystem::ArgCompletion_String); + cmdSystem->AddCommand("listVideos", idListDecls_f, CMD_FL_SYSTEM, "lists Videos", idCmdSystem::ArgCompletion_String); + cmdSystem->AddCommand("listAudios", idListDecls_f, CMD_FL_SYSTEM, "lists Audios", idCmdSystem::ArgCompletion_String); - cmdSystem->AddCommand( "printTable", idPrintDecls_f, CMD_FL_SYSTEM, "prints a table", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "printMaterial", idPrintDecls_f, CMD_FL_SYSTEM, "prints a material", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "printSkin", idPrintDecls_f, CMD_FL_SYSTEM, "prints a skin", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "printSoundShader", idPrintDecls_f, CMD_FL_SYSTEM, "prints a sound shader", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand("printTable", idPrintDecls_f, CMD_FL_SYSTEM, "prints a table", idCmdSystem::ArgCompletion_Decl); + cmdSystem->AddCommand("printMaterial", idPrintDecls_f, CMD_FL_SYSTEM, "prints a material", idCmdSystem::ArgCompletion_Decl); + cmdSystem->AddCommand("printSkin", idPrintDecls_f, CMD_FL_SYSTEM, "prints a skin", idCmdSystem::ArgCompletion_Decl); + cmdSystem->AddCommand("printSoundShader", idPrintDecls_f, CMD_FL_SYSTEM, "prints a sound shader", idCmdSystem::ArgCompletion_Decl); - cmdSystem->AddCommand( "printEntityDef", idPrintDecls_f, CMD_FL_SYSTEM, "prints an entity def", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "printFX", idPrintDecls_f, CMD_FL_SYSTEM, "prints an FX system", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "printParticle", idPrintDecls_f, CMD_FL_SYSTEM, "prints a particle system", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "printAF", idPrintDecls_f, CMD_FL_SYSTEM, "prints an articulated figure", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand("printEntityDef", idPrintDecls_f, CMD_FL_SYSTEM, "prints an entity def", idCmdSystem::ArgCompletion_Decl); + cmdSystem->AddCommand("printFX", idPrintDecls_f, CMD_FL_SYSTEM, "prints an FX system", idCmdSystem::ArgCompletion_Decl); + cmdSystem->AddCommand("printParticle", idPrintDecls_f, CMD_FL_SYSTEM, "prints a particle system", idCmdSystem::ArgCompletion_Decl); + cmdSystem->AddCommand("printAF", idPrintDecls_f, CMD_FL_SYSTEM, "prints an articulated figure", idCmdSystem::ArgCompletion_Decl); - cmdSystem->AddCommand( "printPDA", idPrintDecls_f, CMD_FL_SYSTEM, "prints an PDA", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "printEmail", idPrintDecls_f, CMD_FL_SYSTEM, "prints an Email", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "printVideo", idPrintDecls_f, CMD_FL_SYSTEM, "prints a Audio", idCmdSystem::ArgCompletion_Decl ); - cmdSystem->AddCommand( "printAudio", idPrintDecls_f, CMD_FL_SYSTEM, "prints an Video", idCmdSystem::ArgCompletion_Decl ); + cmdSystem->AddCommand("printPDA", idPrintDecls_f, CMD_FL_SYSTEM, "prints an PDA", idCmdSystem::ArgCompletion_Decl); + cmdSystem->AddCommand("printEmail", idPrintDecls_f, CMD_FL_SYSTEM, "prints an Email", idCmdSystem::ArgCompletion_Decl); + cmdSystem->AddCommand("printVideo", idPrintDecls_f, CMD_FL_SYSTEM, "prints a Audio", idCmdSystem::ArgCompletion_Decl); + cmdSystem->AddCommand("printAudio", idPrintDecls_f, CMD_FL_SYSTEM, "prints an Video", idCmdSystem::ArgCompletion_Decl); - cmdSystem->AddCommand( "listHuffmanFrequencies", ListHuffmanFrequencies_f, CMD_FL_SYSTEM, "lists decl text character frequencies" ); + cmdSystem->AddCommand("listHuffmanFrequencies", ListHuffmanFrequencies_f, CMD_FL_SYSTEM, "lists decl text character frequencies"); - common->Printf( "------------------------------\n" ); + common->Printf("------------------------------\n"); } /* @@ -881,20 +956,20 @@ void idDeclManagerLocal::Init( void ) { idDeclManagerLocal::Shutdown =================== */ -void idDeclManagerLocal::Shutdown( void ) { +void idDeclManagerLocal::Shutdown(void) { int i, j; - idDeclLocal *decl; + idDeclLocal* decl; // free decls - for ( i = 0; i < DECL_MAX_TYPES; i++ ) { - for ( j = 0; j < linearLists[i].Num(); j++ ) { + for (i = 0; i < DECL_MAX_TYPES; i++) { + for (j = 0; j < linearLists[i].Num(); j++) { decl = linearLists[i][j]; - if ( decl->self != NULL ) { + if (decl->self != NULL) { decl->self->FreeData(); delete decl->self; } - if ( decl->textSource ) { - Mem_Free( decl->textSource ); + if (decl->textSource) { + Mem_Free(decl->textSource); decl->textSource = NULL; } delete decl; @@ -904,25 +979,240 @@ void idDeclManagerLocal::Shutdown( void ) { } // free decl files - loadedFiles.DeleteContents( true ); + loadedFiles.DeleteContents(true); // free the decl types and folders - declTypes.DeleteContents( true ); - declFolders.DeleteContents( true ); + declTypes.DeleteContents(true); + declFolders.DeleteContents(true); + +#ifdef QUAKE4 + ShutdownGuides(); +#endif #ifdef USE_COMPRESSED_DECLS ShutdownHuffman(); #endif } + +#ifdef QUAKE4 +// jmarshall: Quake 4 Guide Support +/* +========================= +idDeclManagerLocal::ParseGuides +========================= +*/ +void idDeclManagerLocal::ParseGuides(void) { + idFileList* fileList = fileSystem->ListFiles("guides", ".guide"); + + guides.Clear(); + common->Printf("Parsing Guides...\n"); + + for (int i = 0; i < fileList->GetNumFiles(); i++) { + idLexer src; + idToken token; + idStr fileName = fileList->GetList()[i]; + + if (!src.LoadFile(va("guides/%s", fileName.c_str()))) { + continue; + } + src.SetFlags(DECL_LEXER_FLAGS); + + while (!src.EndOfFile()) { + if (!src.ReadToken(&token) || token.Length() <= 0) { + break; + } + + if (token == "guide" || token == "inlineGuide") { + rvGuideTemplate guide; + guide.inlineGuide = (token == "inlineGuide"); + + if (!src.ReadToken(&token)) { + src.Warning("Guide without name in %s", fileName.c_str()); + break; + } + guide.name = token; + + src.ExpectTokenString("("); + while (!src.EndOfFile()) { + if (!src.ReadToken(&token)) { + break; + } + if (token == ")") { + break; + } + if (token == ",") { + continue; + } + guide.parms.Append(token); + } + + src.ParseBracedSection(guide.body); + guides.Append(guide); + } + else { + src.Error("Unexpected token in guide %s\n", token.c_str()); + } + } + } + + common->Printf("Found %d guides...\n", guides.Num()); + fileSystem->FreeFileList(fileList); +} + +/* +========================= +idDeclManagerLocal::ShutdownGuides +========================= +*/ +void idDeclManagerLocal::ShutdownGuides(void) { + guides.Clear(); +} + +static rvGuideTemplate* FindGuideTemplate(idList& guides, const char* name, bool inlineOnly) { + for (int i = 0; i < guides.Num(); i++) { + if (guides[i].name.Icmp(name) == 0) { + if (!inlineOnly || guides[i].inlineGuide) { + return &guides[i]; + } + } + } + return NULL; +} + +static void StripGuideBraces(idStr& definition) { + int first = definition.Find('{'); + if (first == -1) { + return; + } + + int last = -1; + for (int i = definition.Length() - 1; i > first; i--) { + if (definition[i] == '}') { + last = i; + break; + } + } + if (last <= first) { + return; + } + definition = definition.Mid(first + 1, last - first - 1); +} + +static bool ExpandGuideTemplate(rvGuideTemplate* guide, idLexer* src, idStr& definition, const char* declName, bool stripBraces) { + idToken token; + idList args; + + if (!src->ExpectTokenString("(")) { + return false; + } + + while (src->ReadToken(&token)) { + if (token == ")") { + break; + } + if (token == ",") { + continue; + } + args.Append(token); + } + + if (args.Num() != guide->parms.Num()) { + src->Warning("Guide '%s' expects %d parms but got %d in '%s'", guide->name.c_str(), guide->parms.Num(), args.Num(), declName); + } + + definition = guide->body; + if (stripBraces) { + StripGuideBraces(definition); + } + + for (int i = 0; i < guide->parms.Num() && i < args.Num(); i++) { + definition.Replace(guide->parms[i].c_str(), args[i].c_str()); + } + + return true; +} + +bool idDeclManagerLocal::EvaluateGuide(idStr& name, idLexer* src, idStr& definition) { + idToken guideName; + if (!src->ReadToken(&guideName)) { + return false; + } + + rvGuideTemplate* guide = FindGuideTemplate(guides, guideName.c_str(), false); + if (!guide) { + src->Warning("Guide name '%s' not found in '%s'", guideName.c_str(), name.c_str()); + src->SkipRestOfLine(); + return false; + } + + return ExpandGuideTemplate(guide, src, definition, name.c_str(), false); +} + +bool idDeclManagerLocal::EvaluateInlineGuide(idStr& name, idStr& definition) { + bool replaced = false; + + while (true) { + idLexer lexer; + if (!lexer.LoadMemory(definition.c_str(), definition.Length(), name.c_str())) { + return replaced; + } + lexer.SetFlags(DECL_LEXER_FLAGS); + + idToken token; + int tokenStart = 0; + bool found = false; + + while (!lexer.EndOfFile()) { + tokenStart = lexer.GetFileOffset(); + if (!lexer.ReadToken(&token)) { + break; + } + if (token.Icmp("inlineGuide") == 0) { + found = true; + break; + } + } + + if (!found) { + break; + } + + idToken guideName; + if (!lexer.ReadToken(&guideName)) { + break; + } + + rvGuideTemplate* guide = FindGuideTemplate(guides, guideName.c_str(), true); + if (!guide) { + lexer.Warning("Guide name '%s' not found in '%s'", guideName.c_str(), name.c_str()); + return replaced; + } + + idStr expanded; + if (!ExpandGuideTemplate(guide, &lexer, expanded, name.c_str(), true)) { + return replaced; + } + + int tokenEnd = lexer.GetFileOffset(); + idStr prefix = definition.Mid(0, tokenStart); + idStr suffix = definition.Mid(tokenEnd, definition.Length() - tokenEnd); + definition = prefix + expanded + suffix; + replaced = true; + } + + return replaced; +} +#endif + /* =================== idDeclManagerLocal::Reload =================== */ -void idDeclManagerLocal::Reload( bool force ) { - for ( int i = 0; i < loadedFiles.Num(); i++ ) { - loadedFiles[i]->Reload( force ); +void idDeclManagerLocal::Reload(bool force) { + for (int i = 0; i < loadedFiles.Num(); i++) { + loadedFiles[i]->Reload(force); } } @@ -936,10 +1226,10 @@ void idDeclManagerLocal::BeginLevelLoad() { // clear all the referencedThisLevel flags and purge all the data // so the next reference will cause a reparse - for ( int i = 0; i < DECL_MAX_TYPES; i++ ) { + for (int i = 0; i < DECL_MAX_TYPES; i++) { int num = linearLists[i].Num(); - for ( int j = 0 ; j < num ; j++ ) { - idDeclLocal *decl = linearLists[i][j]; + for (int j = 0; j < num; j++) { + idDeclLocal* decl = linearLists[i][j]; decl->Purge(); } } @@ -962,11 +1252,11 @@ void idDeclManagerLocal::EndLevelLoad() { idDeclManagerLocal::RegisterDeclType =================== */ -void idDeclManagerLocal::RegisterDeclType( const char *typeName, declType_t type, idDecl *(*allocator)( void ) ) { - idDeclType *declType; +void idDeclManagerLocal::RegisterDeclType(const char* typeName, declType_t type, idDecl* (*allocator)(void)) { + idDeclType* declType; - if ( type < declTypes.Num() && declTypes[(int)type] ) { - common->Warning( "idDeclManager::RegisterDeclType: type '%s' already exists", typeName ); + if (type < declTypes.Num() && declTypes[(int)type]) { + common->Warning("idDeclManager::RegisterDeclType: type '%s' already exists", typeName); return; } @@ -975,63 +1265,99 @@ void idDeclManagerLocal::RegisterDeclType( const char *typeName, declType_t type declType->type = type; declType->allocator = allocator; - if ( (int)type + 1 > declTypes.Num() ) { - declTypes.AssureSize( (int)type + 1, NULL ); + if ((int)type + 1 > declTypes.Num()) { + declTypes.AssureSize((int)type + 1, NULL); } declTypes[type] = declType; } +/* +=================== +RegisterDeclSubFolder +=================== +*/ +// jmarshall +void idDeclManagerLocal::RegisterDeclSubFolder(const char* folder, const char* extension, idList& fileList) { + // Find all + { + idFileList* list = fileSystem->ListFiles(folder, extension, true); + + for (int d = 0; d < list->GetNumFiles(); d++) + { + fileList.Append(va("%s/%s", folder, list->GetFile(d))); + } + + fileSystem->FreeFileList(list); + } + + idFileList* dirList = fileSystem->ListFiles(folder, "/", true); + for (int i = 0; i < dirList->GetNumFiles(); i++) + { + idStr dir = va("%s/%s", folder, dirList->GetFile(i)); + RegisterDeclSubFolder(dir, extension, fileList); + } + + fileSystem->FreeFileList(dirList); +} +// jmarshall end + /* =================== idDeclManagerLocal::RegisterDeclFolder =================== */ -void idDeclManagerLocal::RegisterDeclFolder( const char *folder, const char *extension, declType_t defaultType ) { +void idDeclManagerLocal::RegisterDeclFolder(const char* folder, const char* extension, declType_t defaultType) { int i, j; idStr fileName; - idDeclFolder *declFolder; - idFileList *fileList; - idDeclFile *df; + idDeclFolder* declFolder; + // jmarshall - decls subfolders + idList fileList; + // jmarshall end + idDeclFile* df; // check whether this folder / extension combination already exists - for ( i = 0; i < declFolders.Num(); i++ ) { - if ( declFolders[i]->folder.Icmp( folder ) == 0 && declFolders[i]->extension.Icmp( extension ) == 0 ) { + for (i = 0; i < declFolders.Num(); i++) { + if (declFolders[i]->folder.Icmp(folder) == 0 && declFolders[i]->extension.Icmp(extension) == 0) { break; } } - if ( i < declFolders.Num() ) { + if (i < declFolders.Num()) { declFolder = declFolders[i]; - } else { + } + else { declFolder = new idDeclFolder; declFolder->folder = folder; declFolder->extension = extension; declFolder->defaultType = defaultType; - declFolders.Append( declFolder ); + declFolders.Append(declFolder); } - // scan for decl files - fileList = fileSystem->ListFiles( declFolder->folder, declFolder->extension, true ); + // jmarshall - decls subfolders + RegisterDeclSubFolder(declFolder->folder, declFolder->extension, fileList); + // jmarshall end - // load and parse decl files - for ( i = 0; i < fileList->GetNumFiles(); i++ ) { - fileName = declFolder->folder + "/" + fileList->GetFile( i ); + // load and parse decl files + for (i = 0; i < fileList.Num(); i++) { + // jmarshall + //fileName = declFolder->folder + "/" + fileList[ i ]; + fileName = fileList[i]; + // jmarshall end - // check whether this file has already been loaded - for ( j = 0; j < loadedFiles.Num(); j++ ) { - if ( fileName.Icmp( loadedFiles[j]->fileName ) == 0 ) { + // check whether this file has already been loaded + for (j = 0; j < loadedFiles.Num(); j++) { + if (fileName.Icmp(loadedFiles[j]->fileName) == 0) { break; } } - if ( j < loadedFiles.Num() ) { + if (j < loadedFiles.Num()) { df = loadedFiles[j]; - } else { - df = new idDeclFile( fileName, defaultType ); - loadedFiles.Append( df ); + } + else { + df = new idDeclFile(fileName, defaultType); + loadedFiles.Append(df); } df->LoadAndParse(); } - - fileSystem->FreeFileList( fileList ); } /* @@ -1039,43 +1365,43 @@ void idDeclManagerLocal::RegisterDeclFolder( const char *folder, const char *ext idDeclManagerLocal::GetChecksum =================== */ -int idDeclManagerLocal::GetChecksum( void ) const { +int idDeclManagerLocal::GetChecksum(void) const { int i, j, total, num; - int *checksumData; + int* checksumData; // get the total number of decls total = 0; - for ( i = 0; i < DECL_MAX_TYPES; i++ ) { + for (i = 0; i < DECL_MAX_TYPES; i++) { total += linearLists[i].Num(); } - checksumData = (int *) _alloca16( total * 2 * sizeof( int ) ); + checksumData = (int*)_alloca16(total * 2 * sizeof(int)); total = 0; - for ( i = 0; i < DECL_MAX_TYPES; i++ ) { - declType_t type = (declType_t) i; + for (i = 0; i < DECL_MAX_TYPES; i++) { + declType_t type = (declType_t)i; // FIXME: not particularly pretty but PDAs and associated decls are localized and should not be checksummed - if ( type == DECL_PDA || type == DECL_VIDEO || type == DECL_AUDIO || type == DECL_EMAIL ) { + if (type == DECL_PDA || type == DECL_VIDEO || type == DECL_AUDIO || type == DECL_EMAIL) { continue; } - - num = linearLists[i].Num(); - for ( j = 0; j < num; j++ ) { - idDeclLocal *decl = linearLists[i][j]; - if ( decl->sourceFile == &implicitDecls ) { + num = linearLists[i].Num(); + for (j = 0; j < num; j++) { + idDeclLocal* decl = linearLists[i][j]; + + if (decl->sourceFile == &implicitDecls) { continue; } - checksumData[total*2+0] = total; - checksumData[total*2+1] = decl->checksum; + checksumData[total * 2 + 0] = total; + checksumData[total * 2 + 1] = decl->checksum; total++; } } - LittleRevBytes( checksumData, sizeof(int), total * 2 ); - return MD5_BlockChecksum( checksumData, total * 2 * sizeof( int ) ); + LittleRevBytes(checksumData, sizeof(int), total * 2); + return MD5_BlockChecksum(checksumData, total * 2 * sizeof(int)); } /* @@ -1083,7 +1409,7 @@ int idDeclManagerLocal::GetChecksum( void ) const { idDeclManagerLocal::GetNumDeclTypes =================== */ -int idDeclManagerLocal::GetNumDeclTypes( void ) const { +int idDeclManagerLocal::GetNumDeclTypes(void) const { return declTypes.Num(); } @@ -1092,11 +1418,11 @@ int idDeclManagerLocal::GetNumDeclTypes( void ) const { idDeclManagerLocal::GetDeclNameFromType =================== */ -const char * idDeclManagerLocal::GetDeclNameFromType( declType_t type ) const { +const char* idDeclManagerLocal::GetDeclNameFromType(declType_t type) const { int typeIndex = (int)type; - if ( typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL ) { - common->FatalError( "idDeclManager::GetDeclNameFromType: bad type: %i", typeIndex ); + if (typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL) { + common->FatalError("idDeclManager::GetDeclNameFromType: bad type: %i", typeIndex); } return declTypes[typeIndex]->typeName; } @@ -1106,11 +1432,11 @@ const char * idDeclManagerLocal::GetDeclNameFromType( declType_t type ) const { idDeclManagerLocal::GetDeclTypeFromName =================== */ -declType_t idDeclManagerLocal::GetDeclTypeFromName( const char *typeName ) const { +declType_t idDeclManagerLocal::GetDeclTypeFromName(const char* typeName) const { int i; - for ( i = 0; i < declTypes.Num(); i++ ) { - if ( declTypes[i] && declTypes[i]->typeName.Icmp( typeName ) == 0 ) { + for (i = 0; i < declTypes.Num(); i++) { + if (declTypes[i] && declTypes[i]->typeName.Icmp(typeName) == 0) { return (declType_t)declTypes[i]->type; } } @@ -1124,30 +1450,30 @@ idDeclManagerLocal::FindType External users will always cause the decl to be parsed before returning ================= */ -const idDecl *idDeclManagerLocal::FindType( declType_t type, const char *name, bool makeDefault ) { - idDeclLocal *decl; +const idDecl* idDeclManagerLocal::FindType(declType_t type, const char* name, bool makeDefault) { + idDeclLocal* decl; - if ( !name || !name[0] ) { + if (!name || !name[0]) { name = "_emptyName"; //common->Warning( "idDeclManager::FindType: empty %s name", GetDeclType( (int)type )->typeName.c_str() ); } - decl = FindTypeWithoutParsing( type, name, makeDefault ); - if ( !decl ) { + decl = FindTypeWithoutParsing(type, name, makeDefault); + if (!decl) { return NULL; } decl->AllocateSelf(); // if it hasn't been parsed yet, parse it now - if ( decl->declState == DS_UNPARSED ) { + if (decl->declState == DS_UNPARSED) { decl->ParseLocal(); } // mark it as referenced decl->referencedThisLevel = true; decl->everReferenced = true; - if ( insideLevelLoad ) { + if (insideLevelLoad) { decl->parsedOutsideLevelLoad = false; } @@ -1159,10 +1485,10 @@ const idDecl *idDeclManagerLocal::FindType( declType_t type, const char *name, b idDeclManagerLocal::FindDeclWithoutParsing =============== */ -const idDecl* idDeclManagerLocal::FindDeclWithoutParsing( declType_t type, const char *name, bool makeDefault) { +const idDecl* idDeclManagerLocal::FindDeclWithoutParsing(declType_t type, const char* name, bool makeDefault) { idDeclLocal* decl; decl = FindTypeWithoutParsing(type, name, makeDefault); - if(decl) { + if (decl) { return decl->self; } return NULL; @@ -1173,11 +1499,11 @@ const idDecl* idDeclManagerLocal::FindDeclWithoutParsing( declType_t type, const idDeclManagerLocal::ReloadFile =============== */ -void idDeclManagerLocal::ReloadFile( const char* filename, bool force ) { - for ( int i = 0; i < loadedFiles.Num(); i++ ) { - if(!loadedFiles[i]->fileName.Icmp(filename)) { +void idDeclManagerLocal::ReloadFile(const char* filename, bool force) { + for (int i = 0; i < loadedFiles.Num(); i++) { + if (!loadedFiles[i]->fileName.Icmp(filename)) { checksum ^= loadedFiles[i]->checksum; - loadedFiles[i]->Reload( force ); + loadedFiles[i]->Reload(force); checksum ^= loadedFiles[i]->checksum; } } @@ -1188,13 +1514,13 @@ void idDeclManagerLocal::ReloadFile( const char* filename, bool force ) { idDeclManagerLocal::GetNumDecls =================== */ -int idDeclManagerLocal::GetNumDecls( declType_t type ) { +int idDeclManagerLocal::GetNumDecls(declType_t type) { int typeIndex = (int)type; - if ( typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL ) { - common->FatalError( "idDeclManager::GetNumDecls: bad type: %i", typeIndex ); + if (typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL) { + common->FatalError("idDeclManager::GetNumDecls: bad type: %i", typeIndex); } - return linearLists[ typeIndex ].Num(); + return linearLists[typeIndex].Num(); } /* @@ -1202,20 +1528,20 @@ int idDeclManagerLocal::GetNumDecls( declType_t type ) { idDeclManagerLocal::DeclByIndex =================== */ -const idDecl *idDeclManagerLocal::DeclByIndex( declType_t type, int index, bool forceParse ) { +const idDecl* idDeclManagerLocal::DeclByIndex(declType_t type, int index, bool forceParse) { int typeIndex = (int)type; - if ( typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL ) { - common->FatalError( "idDeclManager::DeclByIndex: bad type: %i", typeIndex ); + if (typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL) { + common->FatalError("idDeclManager::DeclByIndex: bad type: %i", typeIndex); } - if ( index < 0 || index >= linearLists[ typeIndex ].Num() ) { - common->Error( "idDeclManager::DeclByIndex: out of range" ); + if (index < 0 || index >= linearLists[typeIndex].Num()) { + common->Error("idDeclManager::DeclByIndex: out of range"); } - idDeclLocal *decl = linearLists[ typeIndex ][ index ]; + idDeclLocal* decl = linearLists[typeIndex][index]; decl->AllocateSelf(); - if ( forceParse && decl->declState == DS_UNPARSED ) { + if (forceParse && decl->declState == DS_UNPARSED) { decl->ParseLocal(); } @@ -1238,58 +1564,64 @@ Lists every decl declared, even if it hasn't been referenced or parsed FIXME: alphabetized, wildcards? =================== */ -void idDeclManagerLocal::ListType( const idCmdArgs &args, declType_t type ) { +void idDeclManagerLocal::ListType(const idCmdArgs& args, declType_t type) { bool all, ever; - if ( !idStr::Icmp( args.Argv( 1 ), "all" ) ) { + if (!idStr::Icmp(args.Argv(1), "all")) { all = true; - } else { + } + else { all = false; } - if ( !idStr::Icmp( args.Argv( 1 ), "ever" ) ) { + if (!idStr::Icmp(args.Argv(1), "ever")) { ever = true; - } else { + } + else { ever = false; } - common->Printf( "--------------------\n" ); + common->Printf("--------------------\n"); int printed = 0; - int count = linearLists[ (int)type ].Num(); - for ( int i = 0 ; i < count ; i++ ) { - idDeclLocal *decl = linearLists[ (int)type ][ i ]; + int count = linearLists[(int)type].Num(); + for (int i = 0; i < count; i++) { + idDeclLocal* decl = linearLists[(int)type][i]; - if ( !all && decl->declState == DS_UNPARSED ) { + if (!all && decl->declState == DS_UNPARSED) { continue; } - if ( !all && !ever && !decl->referencedThisLevel ) { + if (!all && !ever && !decl->referencedThisLevel) { continue; } - if ( decl->referencedThisLevel ) { - common->Printf( "*" ); - } else if ( decl->everReferenced ) { - common->Printf( "." ); - } else { - common->Printf( " " ); + if (decl->referencedThisLevel) { + common->Printf("*"); } - if ( decl->declState == DS_DEFAULTED ) { - common->Printf( "D" ); - } else { - common->Printf( " " ); + else if (decl->everReferenced) { + common->Printf("."); } - common->Printf( "%4i: ", decl->index ); + else { + common->Printf(" "); + } + if (decl->declState == DS_DEFAULTED) { + common->Printf("D"); + } + else { + common->Printf(" "); + } + common->Printf("%4i: ", decl->index); printed++; - if ( decl->declState == DS_UNPARSED ) { + if (decl->declState == DS_UNPARSED) { // doesn't have any type specific data yet - common->Printf( "%s\n", decl->GetName() ); - } else { + common->Printf("%s\n", decl->GetName()); + } + else { decl->self->List(); } } - common->Printf( "--------------------\n" ); - common->Printf( "%i of %i %s\n", printed, count, declTypes[type]->typeName.c_str() ); + common->Printf("--------------------\n"); + common->Printf("%i of %i %s\n", printed, count, declTypes[type]->typeName.c_str()); } /* @@ -1297,54 +1629,57 @@ void idDeclManagerLocal::ListType( const idCmdArgs &args, declType_t type ) { idDeclManagerLocal::PrintType =================== */ -void idDeclManagerLocal::PrintType( const idCmdArgs &args, declType_t type ) { +void idDeclManagerLocal::PrintType(const idCmdArgs& args, declType_t type) { // individual decl types may use additional command parameters - if ( args.Argc() < 2 ) { - common->Printf( "USAGE: Print [type specific parms]\n" ); + if (args.Argc() < 2) { + common->Printf("USAGE: Print [type specific parms]\n"); return; } // look it up, skipping the public path so it won't parse or reference - idDeclLocal *decl = FindTypeWithoutParsing( type, args.Argv( 1 ), false ); - if ( !decl ) { - common->Printf( "%s '%s' not found.\n", declTypes[ type ]->typeName.c_str(), args.Argv( 1 ) ); + idDeclLocal* decl = FindTypeWithoutParsing(type, args.Argv(1), false); + if (!decl) { + common->Printf("%s '%s' not found.\n", declTypes[type]->typeName.c_str(), args.Argv(1)); return; } // print information common to all decls - common->Printf( "%s %s:\n", declTypes[ type ]->typeName.c_str(), decl->name.c_str() ); - common->Printf( "source: %s:%i\n", decl->sourceFile->fileName.c_str(), decl->sourceLine ); - common->Printf( "----------\n" ); - if ( decl->textSource != NULL ) { - char *declText = (char *)_alloca( decl->textLength + 1 ); - decl->GetText( declText ); - common->Printf( "%s\n", declText ); - } else { - common->Printf( "NO SOURCE\n" ); + common->Printf("%s %s:\n", declTypes[type]->typeName.c_str(), decl->name.c_str()); + common->Printf("source: %s:%i\n", decl->sourceFile->fileName.c_str(), decl->sourceLine); + common->Printf("----------\n"); + if (decl->textSource != NULL) { + char* declText = (char*)_alloca(decl->textLength + 1); + decl->GetText(declText); + common->Printf("%s\n", declText); } - common->Printf( "----------\n" ); - switch( decl->declState ) { - case DS_UNPARSED: - common->Printf( "Unparsed.\n" ); - break; - case DS_DEFAULTED: - common->Printf( "\n" ); - break; - case DS_PARSED: - common->Printf( "Parsed.\n" ); - break; + else { + common->Printf("NO SOURCE\n"); + } + common->Printf("----------\n"); + switch (decl->declState) { + case DS_UNPARSED: + common->Printf("Unparsed.\n"); + break; + case DS_DEFAULTED: + common->Printf("\n"); + break; + case DS_PARSED: + common->Printf("Parsed.\n"); + break; } - if ( decl->referencedThisLevel ) { - common->Printf( "Currently referenced this level.\n" ); - } else if ( decl->everReferenced ) { - common->Printf( "Referenced in a previous level.\n" ); - } else { - common->Printf( "Never referenced.\n" ); + if (decl->referencedThisLevel) { + common->Printf("Currently referenced this level.\n"); + } + else if (decl->everReferenced) { + common->Printf("Referenced in a previous level.\n"); + } + else { + common->Printf("Never referenced.\n"); } // allow type-specific data to be printed - if ( decl->self != NULL ) { + if (decl->self != NULL) { decl->self->Print(); } } @@ -1354,46 +1689,47 @@ void idDeclManagerLocal::PrintType( const idCmdArgs &args, declType_t type ) { idDeclManagerLocal::CreateNewDecl =================== */ -idDecl *idDeclManagerLocal::CreateNewDecl( declType_t type, const char *name, const char *_fileName ) { +idDecl* idDeclManagerLocal::CreateNewDecl(declType_t type, const char* name, const char* _fileName) { int typeIndex = (int)type; int i, hash; - if ( typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL ) { - common->FatalError( "idDeclManager::CreateNewDecl: bad type: %i", typeIndex ); + if (typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL) { + common->FatalError("idDeclManager::CreateNewDecl: bad type: %i", typeIndex); } char canonicalName[MAX_STRING_CHARS]; - MakeNameCanonical( name, canonicalName, sizeof( canonicalName ) ); + MakeNameCanonical(name, canonicalName, sizeof(canonicalName)); idStr fileName = _fileName; fileName.BackSlashesToSlashes(); // see if it already exists - hash = hashTables[typeIndex].GenerateKey( canonicalName, false ); - for ( i = hashTables[typeIndex].First( hash ); i >= 0; i = hashTables[typeIndex].Next( i ) ) { - if ( linearLists[typeIndex][i]->name.Icmp( canonicalName ) == 0 ) { + hash = hashTables[typeIndex].GenerateKey(canonicalName, false); + for (i = hashTables[typeIndex].First(hash); i >= 0; i = hashTables[typeIndex].Next(i)) { + if (linearLists[typeIndex][i]->name.Icmp(canonicalName) == 0) { linearLists[typeIndex][i]->AllocateSelf(); return linearLists[typeIndex][i]->self; } } - idDeclFile *sourceFile; + idDeclFile* sourceFile; // find existing source file or create a new one - for ( i = 0; i < loadedFiles.Num(); i++ ) { - if ( loadedFiles[i]->fileName.Icmp( fileName ) == 0 ) { + for (i = 0; i < loadedFiles.Num(); i++) { + if (loadedFiles[i]->fileName.Icmp(fileName) == 0) { break; } } - if ( i < loadedFiles.Num() ) { + if (i < loadedFiles.Num()) { sourceFile = loadedFiles[i]; - } else { - sourceFile = new idDeclFile( fileName, type ); - loadedFiles.Append( sourceFile ); + } + else { + sourceFile = new idDeclFile(fileName, type); + loadedFiles.Append(sourceFile); } - idDeclLocal *decl = new idDeclLocal; + idDeclLocal* decl = new idDeclLocal; decl->name = canonicalName; decl->type = type; decl->declState = DS_UNPARSED; @@ -1402,16 +1738,16 @@ idDecl *idDeclManagerLocal::CreateNewDecl( declType_t type, const char *name, co idStr defaultText = decl->self->DefaultDefinition(); - int size = header.Length() + 1 + idStr::Length( canonicalName ) + 1 + defaultText.Length(); - char *declText = ( char * ) _alloca( size + 1 ); + int size = header.Length() + 1 + idStr::Length(canonicalName) + 1 + defaultText.Length(); + char* declText = (char*)_alloca(size + 1); - memcpy( declText, header, header.Length() ); + memcpy(declText, header, header.Length()); declText[header.Length()] = ' '; - memcpy( declText + header.Length() + 1, canonicalName, idStr::Length( canonicalName ) ); - declText[header.Length() + 1 + idStr::Length( canonicalName )] = ' '; - memcpy( declText + header.Length() + 1 + idStr::Length( canonicalName ) + 1, defaultText, defaultText.Length() + 1 ); + memcpy(declText + header.Length() + 1, canonicalName, idStr::Length(canonicalName)); + declText[header.Length() + 1 + idStr::Length(canonicalName)] = ' '; + memcpy(declText + header.Length() + 1 + idStr::Length(canonicalName) + 1, defaultText, defaultText.Length() + 1); - decl->SetTextLocal( declText, size ); + decl->SetTextLocal(declText, size); decl->sourceFile = sourceFile; decl->sourceTextOffset = sourceFile->fileSize; decl->sourceTextLength = 0; @@ -1425,7 +1761,7 @@ idDecl *idDeclManagerLocal::CreateNewDecl( declType_t type, const char *name, co // add it to the hash table and linear list decl->index = linearLists[typeIndex].Num(); - hashTables[typeIndex].Add( hash, linearLists[typeIndex].Append( decl ) ); + hashTables[typeIndex].Add(hash, linearLists[typeIndex].Append(decl)); return decl->self; } @@ -1435,27 +1771,27 @@ idDecl *idDeclManagerLocal::CreateNewDecl( declType_t type, const char *name, co idDeclManagerLocal::RenameDecl =============== */ -bool idDeclManagerLocal::RenameDecl( declType_t type, const char* oldName, const char* newName ) { +bool idDeclManagerLocal::RenameDecl(declType_t type, const char* oldName, const char* newName) { char canonicalOldName[MAX_STRING_CHARS]; - MakeNameCanonical( oldName, canonicalOldName, sizeof( canonicalOldName )); + MakeNameCanonical(oldName, canonicalOldName, sizeof(canonicalOldName)); char canonicalNewName[MAX_STRING_CHARS]; - MakeNameCanonical( newName, canonicalNewName, sizeof( canonicalNewName ) ); + MakeNameCanonical(newName, canonicalNewName, sizeof(canonicalNewName)); - idDeclLocal *decl = NULL; + idDeclLocal* decl = NULL; // make sure it already exists int typeIndex = (int)type; int i, hash; - hash = hashTables[typeIndex].GenerateKey( canonicalOldName, false ); - for ( i = hashTables[typeIndex].First( hash ); i >= 0; i = hashTables[typeIndex].Next( i ) ) { - if ( linearLists[typeIndex][i]->name.Icmp( canonicalOldName ) == 0 ) { + hash = hashTables[typeIndex].GenerateKey(canonicalOldName, false); + for (i = hashTables[typeIndex].First(hash); i >= 0; i = hashTables[typeIndex].Next(i)) { + if (linearLists[typeIndex][i]->name.Icmp(canonicalOldName) == 0) { decl = linearLists[typeIndex][i]; break; } } - if(!decl) + if (!decl) return false; //if ( !hashTables[(int)type].Get( canonicalOldName, &declPtr ) ) @@ -1469,8 +1805,8 @@ bool idDeclManagerLocal::RenameDecl( declType_t type, const char* oldName, const // add it to the hash table //hashTables[(int)decl->type].Set( decl->name, decl ); - int newhash = hashTables[typeIndex].GenerateKey( canonicalNewName, false ); - hashTables[typeIndex].Add( newhash, decl->index ); + int newhash = hashTables[typeIndex].GenerateKey(canonicalNewName, false); + hashTables[typeIndex].Add(newhash, decl->index); //Remove the old hash item hashTables[typeIndex].Remove(hash, decl->index); @@ -1485,21 +1821,21 @@ idDeclManagerLocal::MediaPrint This is just used to nicely indent media caching prints =================== */ -void idDeclManagerLocal::MediaPrint( const char *fmt, ... ) { - if ( !decl_show.GetInteger() ) { +void idDeclManagerLocal::MediaPrint(const char* fmt, ...) { + if (!decl_show.GetInteger()) { return; } - for ( int i = 0 ; i < indent ; i++ ) { - common->Printf( " " ); + for (int i = 0; i < indent; i++) { + common->Printf(" "); } va_list argptr; char buffer[1024]; - va_start (argptr,fmt); - idStr::vsnPrintf( buffer, sizeof(buffer), fmt, argptr ); - va_end (argptr); - buffer[sizeof(buffer)-1] = '\0'; + va_start(argptr, fmt); + idStr::vsnPrintf(buffer, sizeof(buffer), fmt, argptr); + va_end(argptr); + buffer[sizeof(buffer) - 1] = '\0'; - common->Printf( "%s", buffer ); + common->Printf("%s", buffer); } /* @@ -1507,59 +1843,59 @@ void idDeclManagerLocal::MediaPrint( const char *fmt, ... ) { idDeclManagerLocal::WritePrecacheCommands =================== */ -void idDeclManagerLocal::WritePrecacheCommands( idFile *f ) { - for ( int i = 0; i < declTypes.Num(); i++ ) { +void idDeclManagerLocal::WritePrecacheCommands(idFile* f) { + for (int i = 0; i < declTypes.Num(); i++) { int num; - if ( declTypes[i] == NULL ) { + if (declTypes[i] == NULL) { continue; } num = linearLists[i].Num(); - for ( int j = 0 ; j < num ; j++ ) { - idDeclLocal *decl = linearLists[i][j]; + for (int j = 0; j < num; j++) { + idDeclLocal* decl = linearLists[i][j]; - if ( !decl->referencedThisLevel ) { + if (!decl->referencedThisLevel) { continue; } char str[1024]; - sprintf( str, "touch %s %s\n", declTypes[i]->typeName.c_str(), decl->GetName() ); - common->Printf( "%s", str ); - f->Printf( "%s", str ); + sprintf(str, "touch %s %s\n", declTypes[i]->typeName.c_str(), decl->GetName()); + common->Printf("%s", str); + f->Printf("%s", str); } } } /********************************************************************/ -const idMaterial *idDeclManagerLocal::FindMaterial( const char *name, bool makeDefault ) { - return static_cast( FindType( DECL_MATERIAL, name, makeDefault ) ); +const idMaterial* idDeclManagerLocal::FindMaterial(const char* name, bool makeDefault) { + return static_cast(FindType(DECL_MATERIAL, name, makeDefault)); } -const idMaterial *idDeclManagerLocal::MaterialByIndex( int index, bool forceParse ) { - return static_cast( DeclByIndex( DECL_MATERIAL, index, forceParse ) ); +const idMaterial* idDeclManagerLocal::MaterialByIndex(int index, bool forceParse) { + return static_cast(DeclByIndex(DECL_MATERIAL, index, forceParse)); } /********************************************************************/ -const idDeclSkin *idDeclManagerLocal::FindSkin( const char *name, bool makeDefault ) { - return static_cast( FindType( DECL_SKIN, name, makeDefault ) ); +const idDeclSkin* idDeclManagerLocal::FindSkin(const char* name, bool makeDefault) { + return static_cast(FindType(DECL_SKIN, name, makeDefault)); } -const idDeclSkin *idDeclManagerLocal::SkinByIndex( int index, bool forceParse ) { - return static_cast( DeclByIndex( DECL_SKIN, index, forceParse ) ); +const idDeclSkin* idDeclManagerLocal::SkinByIndex(int index, bool forceParse) { + return static_cast(DeclByIndex(DECL_SKIN, index, forceParse)); } /********************************************************************/ -const idSoundShader *idDeclManagerLocal::FindSound( const char *name, bool makeDefault ) { - return static_cast( FindType( DECL_SOUND, name, makeDefault ) ); +const idSoundShader* idDeclManagerLocal::FindSound(const char* name, bool makeDefault) { + return static_cast(FindType(DECL_SOUND, name, makeDefault)); } -const idSoundShader *idDeclManagerLocal::SoundByIndex( int index, bool forceParse ) { - return static_cast( DeclByIndex( DECL_SOUND, index, forceParse ) ); +const idSoundShader* idDeclManagerLocal::SoundByIndex(int index, bool forceParse) { + return static_cast(DeclByIndex(DECL_SOUND, index, forceParse)); } /* @@ -1567,24 +1903,27 @@ const idSoundShader *idDeclManagerLocal::SoundByIndex( int index, bool forcePars idDeclManagerLocal::MakeNameCanonical =================== */ -void idDeclManagerLocal::MakeNameCanonical( const char *name, char *result, int maxLength ) { +void idDeclManagerLocal::MakeNameCanonical(const char* name, char* result, int maxLength) { int i, lastDot; lastDot = -1; - for ( i = 0; i < maxLength && name[i] != '\0'; i++ ) { + for (i = 0; i < maxLength && name[i] != '\0'; i++) { int c = name[i]; - if ( c == '\\' ) { + if (c == '\\') { result[i] = '/'; - } else if ( c == '.' ) { + } + else if (c == '.') { lastDot = i; result[i] = c; - } else { - result[i] = idStr::ToLower( c ); + } + else { + result[i] = idStr::ToLower(c); } } - if ( lastDot != -1 ) { + if (lastDot != -1) { result[lastDot] = '\0'; - } else { + } + else { result[i] = '\0'; } } @@ -1594,16 +1933,16 @@ void idDeclManagerLocal::MakeNameCanonical( const char *name, char *result, int idDeclManagerLocal::ListDecls_f ================ */ -void idDeclManagerLocal::ListDecls_f( const idCmdArgs &args ) { +void idDeclManagerLocal::ListDecls_f(const idCmdArgs& args) { int i, j; int totalDecls = 0; int totalText = 0; int totalStructs = 0; - for ( i = 0; i < declManagerLocal.declTypes.Num(); i++ ) { + for (i = 0; i < declManagerLocal.declTypes.Num(); i++) { int size, num; - if ( declManagerLocal.declTypes[i] == NULL ) { + if (declManagerLocal.declTypes[i] == NULL) { continue; } @@ -1611,24 +1950,24 @@ void idDeclManagerLocal::ListDecls_f( const idCmdArgs &args ) { totalDecls += num; size = 0; - for ( j = 0; j < num; j++ ) { + for (j = 0; j < num; j++) { size += declManagerLocal.linearLists[i][j]->Size(); - if ( declManagerLocal.linearLists[i][j]->self != NULL ) { + if (declManagerLocal.linearLists[i][j]->self != NULL) { size += declManagerLocal.linearLists[i][j]->self->Size(); } } totalStructs += size; - common->Printf( "%4ik %4i %s\n", size >> 10, num, declManagerLocal.declTypes[i]->typeName.c_str() ); + common->Printf("%4ik %4i %s\n", size >> 10, num, declManagerLocal.declTypes[i]->typeName.c_str()); } - for ( i = 0 ; i < declManagerLocal.loadedFiles.Num() ; i++ ) { - idDeclFile *df = declManagerLocal.loadedFiles[i]; + for (i = 0; i < declManagerLocal.loadedFiles.Num(); i++) { + idDeclFile* df = declManagerLocal.loadedFiles[i]; totalText += df->fileSize; } - common->Printf( "%i total decls is %i decl files\n", totalDecls, declManagerLocal.loadedFiles.Num() ); - common->Printf( "%iKB in text, %iKB in structures\n", totalText >> 10, totalStructs >> 10 ); + common->Printf("%i total decls is %i decl files\n", totalDecls, declManagerLocal.loadedFiles.Num()); + common->Printf("%iKB in text, %iKB in structures\n", totalText >> 10, totalStructs >> 10); } /* @@ -1641,22 +1980,23 @@ will only reload existing files. A reload will never cause anything to be purged. =================== */ -void idDeclManagerLocal::ReloadDecls_f( const idCmdArgs &args ) { +void idDeclManagerLocal::ReloadDecls_f(const idCmdArgs& args) { bool force; - if ( !idStr::Icmp( args.Argv( 1 ), "all" ) ) { + if (!idStr::Icmp(args.Argv(1), "all")) { force = true; - common->Printf( "reloading all decl files:\n" ); - } else { + common->Printf("reloading all decl files:\n"); + } + else { force = false; - common->Printf( "reloading changed decl files:\n" ); + common->Printf("reloading changed decl files:\n"); } - soundSystem->SetMute( true ); + soundSystem->SetMute(true); - declManagerLocal.Reload( force ); + declManagerLocal.Reload(force); - soundSystem->SetMute( false ); + soundSystem->SetMute(false); } /* @@ -1664,34 +2004,34 @@ void idDeclManagerLocal::ReloadDecls_f( const idCmdArgs &args ) { idDeclManagerLocal::TouchDecl_f =================== */ -void idDeclManagerLocal::TouchDecl_f( const idCmdArgs &args ) { +void idDeclManagerLocal::TouchDecl_f(const idCmdArgs& args) { int i; - if ( args.Argc() != 3 ) { - common->Printf( "usage: touch \n" ); - common->Printf( "valid types: " ); - for ( int i = 0 ; i < declManagerLocal.declTypes.Num() ; i++ ) { - if ( declManagerLocal.declTypes[i] ) { - common->Printf( "%s ", declManagerLocal.declTypes[i]->typeName.c_str() ); + if (args.Argc() != 3) { + common->Printf("usage: touch \n"); + common->Printf("valid types: "); + for (int i = 0; i < declManagerLocal.declTypes.Num(); i++) { + if (declManagerLocal.declTypes[i]) { + common->Printf("%s ", declManagerLocal.declTypes[i]->typeName.c_str()); } } - common->Printf( "\n" ); + common->Printf("\n"); return; } - for ( i = 0; i < declManagerLocal.declTypes.Num(); i++ ) { - if ( declManagerLocal.declTypes[i] && declManagerLocal.declTypes[i]->typeName.Icmp( args.Argv( 1 ) ) == 0 ) { + for (i = 0; i < declManagerLocal.declTypes.Num(); i++) { + if (declManagerLocal.declTypes[i] && declManagerLocal.declTypes[i]->typeName.Icmp(args.Argv(1)) == 0) { break; } } - if ( i >= declManagerLocal.declTypes.Num() ) { - common->Printf( "unknown decl type '%s'\n", args.Argv( 1 ) ); + if (i >= declManagerLocal.declTypes.Num()) { + common->Printf("unknown decl type '%s'\n", args.Argv(1)); return; } - const idDecl *decl = declManagerLocal.FindType( (declType_t)i, args.Argv( 2 ), false ); - if ( !decl ) { - common->Printf( "%s '%s' not found\n", declManagerLocal.declTypes[i]->typeName.c_str(), args.Argv( 2 ) ); + const idDecl* decl = declManagerLocal.FindType((declType_t)i, args.Argv(2), false); + if (!decl) { + common->Printf("%s '%s' not found\n", declManagerLocal.declTypes[i]->typeName.c_str(), args.Argv(2)); } } @@ -1702,35 +2042,35 @@ idDeclManagerLocal::FindTypeWithoutParsing This finds or creats the decl, but does not cause a parse. This is only used internally. =================== */ -idDeclLocal *idDeclManagerLocal::FindTypeWithoutParsing( declType_t type, const char *name, bool makeDefault ) { +idDeclLocal* idDeclManagerLocal::FindTypeWithoutParsing(declType_t type, const char* name, bool makeDefault) { int typeIndex = (int)type; int i, hash; - if ( typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL ) { - common->FatalError( "idDeclManager::FindTypeWithoutParsing: bad type: %i", typeIndex ); + if (typeIndex < 0 || typeIndex >= declTypes.Num() || declTypes[typeIndex] == NULL) { + common->FatalError("idDeclManager::FindTypeWithoutParsing: bad type: %i", typeIndex); } char canonicalName[MAX_STRING_CHARS]; - MakeNameCanonical( name, canonicalName, sizeof( canonicalName ) ); + MakeNameCanonical(name, canonicalName, sizeof(canonicalName)); // see if it already exists - hash = hashTables[typeIndex].GenerateKey( canonicalName, false ); - for ( i = hashTables[typeIndex].First( hash ); i >= 0; i = hashTables[typeIndex].Next( i ) ) { - if ( linearLists[typeIndex][i]->name.Icmp( canonicalName ) == 0 ) { + hash = hashTables[typeIndex].GenerateKey(canonicalName, false); + for (i = hashTables[typeIndex].First(hash); i >= 0; i = hashTables[typeIndex].Next(i)) { + if (linearLists[typeIndex][i]->name.Icmp(canonicalName) == 0) { // only print these when decl_show is set to 2, because it can be a lot of clutter - if ( decl_show.GetInteger() > 1 ) { - MediaPrint( "referencing %s %s\n", declTypes[ type ]->typeName.c_str(), name ); + if (decl_show.GetInteger() > 1) { + MediaPrint("referencing %s %s\n", declTypes[type]->typeName.c_str(), name); } return linearLists[typeIndex][i]; } } - if ( !makeDefault ) { + if (!makeDefault) { return NULL; } - idDeclLocal *decl = new idDeclLocal; + idDeclLocal* decl = new idDeclLocal; decl->self = NULL; decl->name = canonicalName; decl->type = type; @@ -1744,7 +2084,7 @@ idDeclLocal *idDeclManagerLocal::FindTypeWithoutParsing( declType_t type, const // add it to the linear list and hash table decl->index = linearLists[typeIndex].Num(); - hashTables[typeIndex].Add( hash, linearLists[typeIndex].Append( decl ) ); + hashTables[typeIndex].Add(hash, linearLists[typeIndex].Append(decl)); return decl; } @@ -1763,7 +2103,7 @@ idDeclLocal *idDeclManagerLocal::FindTypeWithoutParsing( declType_t type, const idDeclLocal::idDeclLocal ================= */ -idDeclLocal::idDeclLocal( void ) { +idDeclLocal::idDeclLocal(void) { name = "unnamed"; textSource = NULL; textLength = 0; @@ -1788,7 +2128,7 @@ idDeclLocal::idDeclLocal( void ) { idDeclLocal::GetName ================= */ -const char *idDeclLocal::GetName( void ) const { +const char* idDeclLocal::GetName(void) const { return name.c_str(); } @@ -1797,7 +2137,7 @@ const char *idDeclLocal::GetName( void ) const { idDeclLocal::GetType ================= */ -declType_t idDeclLocal::GetType( void ) const { +declType_t idDeclLocal::GetType(void) const { return type; } @@ -1806,7 +2146,7 @@ declType_t idDeclLocal::GetType( void ) const { idDeclLocal::GetState ================= */ -declState_t idDeclLocal::GetState( void ) const { +declState_t idDeclLocal::GetState(void) const { return declState; } @@ -1815,8 +2155,8 @@ declState_t idDeclLocal::GetState( void ) const { idDeclLocal::IsImplicit ================= */ -bool idDeclLocal::IsImplicit( void ) const { - return ( sourceFile == declManagerLocal.GetImplicitDeclFile() ); +bool idDeclLocal::IsImplicit(void) const { + return (sourceFile == declManagerLocal.GetImplicitDeclFile()); } /* @@ -1824,8 +2164,8 @@ bool idDeclLocal::IsImplicit( void ) const { idDeclLocal::IsValid ================= */ -bool idDeclLocal::IsValid( void ) const { - return ( declState != DS_UNPARSED ); +bool idDeclLocal::IsValid(void) const { + return (declState != DS_UNPARSED); } /* @@ -1833,7 +2173,7 @@ bool idDeclLocal::IsValid( void ) const { idDeclLocal::Invalidate ================= */ -void idDeclLocal::Invalidate( void ) { +void idDeclLocal::Invalidate(void) { declState = DS_UNPARSED; } @@ -1842,8 +2182,8 @@ void idDeclLocal::Invalidate( void ) { idDeclLocal::EnsureNotPurged ================= */ -void idDeclLocal::EnsureNotPurged( void ) { - if ( declState == DS_UNPARSED ) { +void idDeclLocal::EnsureNotPurged(void) { + if (declState == DS_UNPARSED) { ParseLocal(); } } @@ -1853,7 +2193,7 @@ void idDeclLocal::EnsureNotPurged( void ) { idDeclLocal::Index ================= */ -int idDeclLocal::Index( void ) const { +int idDeclLocal::Index(void) const { return index; } @@ -1862,7 +2202,7 @@ int idDeclLocal::Index( void ) const { idDeclLocal::GetLineNum ================= */ -int idDeclLocal::GetLineNum( void ) const { +int idDeclLocal::GetLineNum(void) const { return sourceLine; } @@ -1871,8 +2211,8 @@ int idDeclLocal::GetLineNum( void ) const { idDeclLocal::GetFileName ================= */ -const char *idDeclLocal::GetFileName( void ) const { - return ( sourceFile ) ? sourceFile->fileName.c_str() : "*invalid*"; +const char* idDeclLocal::GetFileName(void) const { + return (sourceFile) ? sourceFile->fileName.c_str() : "*invalid*"; } /* @@ -1880,8 +2220,8 @@ const char *idDeclLocal::GetFileName( void ) const { idDeclLocal::Size ================= */ -size_t idDeclLocal::Size( void ) const { - return sizeof( idDecl ) + name.Allocated(); +size_t idDeclLocal::Size(void) const { + return sizeof(idDecl) + name.Allocated(); } /* @@ -1889,11 +2229,11 @@ size_t idDeclLocal::Size( void ) const { idDeclLocal::GetText ================= */ -void idDeclLocal::GetText( char *text ) const { +void idDeclLocal::GetText(char* text) const { #ifdef USE_COMPRESSED_DECLS - HuffmanDecompressText( text, textLength, (byte *)textSource, compressedLength ); + HuffmanDecompressText(text, textLength, (byte*)textSource, compressedLength); #else - memcpy( text, textSource, textLength+1 ); + memcpy(text, textSource, textLength + 1); #endif } @@ -1902,7 +2242,7 @@ void idDeclLocal::GetText( char *text ) const { idDeclLocal::GetTextLength ================= */ -int idDeclLocal::GetTextLength( void ) const { +int idDeclLocal::GetTextLength(void) const { return textLength; } @@ -1911,8 +2251,8 @@ int idDeclLocal::GetTextLength( void ) const { idDeclLocal::SetText ================= */ -void idDeclLocal::SetText( const char *text ) { - SetTextLocal( text, idStr::Length( text ) ); +void idDeclLocal::SetText(const char* text) { + SetTextLocal(text, idStr::Length(text)); } /* @@ -1920,28 +2260,28 @@ void idDeclLocal::SetText( const char *text ) { idDeclLocal::SetTextLocal ================= */ -void idDeclLocal::SetTextLocal( const char *text, const int length ) { +void idDeclLocal::SetTextLocal(const char* text, const int length) { - Mem_Free( textSource ); + Mem_Free(textSource); - checksum = MD5_BlockChecksum( text, length ); + checksum = MD5_BlockChecksum(text, length); #ifdef GET_HUFFMAN_FREQUENCIES - for( int i = 0; i < length; i++ ) { - huffmanFrequencies[((const unsigned char *)text)[i]]++; + for (int i = 0; i < length; i++) { + huffmanFrequencies[((const unsigned char*)text)[i]]++; } #endif #ifdef USE_COMPRESSED_DECLS - int maxBytesPerCode = ( maxHuffmanBits + 7 ) >> 3; - byte *compressed = (byte *)_alloca( length * maxBytesPerCode ); - compressedLength = HuffmanCompressText( text, length, compressed, length * maxBytesPerCode ); - textSource = (char *)Mem_Alloc( compressedLength ); - memcpy( textSource, compressed, compressedLength ); + int maxBytesPerCode = (maxHuffmanBits + 7) >> 3; + byte* compressed = (byte*)_alloca(length * maxBytesPerCode); + compressedLength = HuffmanCompressText(text, length, compressed, length * maxBytesPerCode); + textSource = (char*)Mem_Alloc(compressedLength); + memcpy(textSource, compressed, compressedLength); #else compressedLength = length; - textSource = (char *) Mem_Alloc( length + 1 ); - memcpy( textSource, text, length ); + textSource = (char*)Mem_Alloc(length + 1); + memcpy(textSource, text, length); textSource[length] = '\0'; #endif textLength = length; @@ -1952,75 +2292,75 @@ void idDeclLocal::SetTextLocal( const char *text, const int length ) { idDeclLocal::ReplaceSourceFileText ================= */ -bool idDeclLocal::ReplaceSourceFileText( void ) { +bool idDeclLocal::ReplaceSourceFileText(void) { int oldFileLength, newFileLength; - char *buffer; - idFile *file; + char* buffer; + idFile* file; - common->Printf( "Writing \'%s\' to \'%s\'...\n", GetName(), GetFileName() ); + common->Printf("Writing \'%s\' to \'%s\'...\n", GetName(), GetFileName()); - if ( sourceFile == &declManagerLocal.implicitDecls ) { - common->Warning( "Can't save implicit declaration %s.", GetName() ); + if (sourceFile == &declManagerLocal.implicitDecls) { + common->Warning("Can't save implicit declaration %s.", GetName()); return false; } // get length and allocate buffer to hold the file oldFileLength = sourceFile->fileSize; newFileLength = oldFileLength - sourceTextLength + textLength; - buffer = (char *) Mem_Alloc( Max( newFileLength, oldFileLength ) ); + buffer = (char*)Mem_Alloc(Max(newFileLength, oldFileLength)); // read original file - if ( sourceFile->fileSize ) { + if (sourceFile->fileSize) { - file = fileSystem->OpenFileRead( GetFileName() ); - if ( !file ) { - Mem_Free( buffer ); - common->Warning( "Couldn't open %s for reading.", GetFileName() ); + file = fileSystem->OpenFileRead(GetFileName()); + if (!file) { + Mem_Free(buffer); + common->Warning("Couldn't open %s for reading.", GetFileName()); return false; } - if ( file->Length() != sourceFile->fileSize || file->Timestamp() != sourceFile->timestamp ) { - Mem_Free( buffer ); - common->Warning( "The file %s has been modified outside of the engine.", GetFileName() ); + if (file->Length() != sourceFile->fileSize || file->Timestamp() != sourceFile->timestamp) { + Mem_Free(buffer); + common->Warning("The file %s has been modified outside of the engine.", GetFileName()); return false; } - file->Read( buffer, oldFileLength ); - fileSystem->CloseFile( file ); + file->Read(buffer, oldFileLength); + fileSystem->CloseFile(file); - if ( MD5_BlockChecksum( buffer, oldFileLength ) != sourceFile->checksum ) { - Mem_Free( buffer ); - common->Warning( "The file %s has been modified outside of the engine.", GetFileName() ); + if (MD5_BlockChecksum(buffer, oldFileLength) != sourceFile->checksum) { + Mem_Free(buffer); + common->Warning("The file %s has been modified outside of the engine.", GetFileName()); return false; } } // insert new text - char *declText = (char *) _alloca( textLength + 1 ); - GetText( declText ); - memmove( buffer + sourceTextOffset + textLength, buffer + sourceTextOffset + sourceTextLength, oldFileLength - sourceTextOffset - sourceTextLength ); - memcpy( buffer + sourceTextOffset, declText, textLength ); + char* declText = (char*)_alloca(textLength + 1); + GetText(declText); + memmove(buffer + sourceTextOffset + textLength, buffer + sourceTextOffset + sourceTextLength, oldFileLength - sourceTextOffset - sourceTextLength); + memcpy(buffer + sourceTextOffset, declText, textLength); // write out new file - file = fileSystem->OpenFileWrite( GetFileName(), "fs_devpath" ); - if ( !file ) { - Mem_Free( buffer ); - common->Warning( "Couldn't open %s for writing.", GetFileName() ); + file = fileSystem->OpenFileWrite(GetFileName(), "fs_devpath"); + if (!file) { + Mem_Free(buffer); + common->Warning("Couldn't open %s for writing.", GetFileName()); return false; } - file->Write( buffer, newFileLength ); - fileSystem->CloseFile( file ); + file->Write(buffer, newFileLength); + fileSystem->CloseFile(file); // set new file size, checksum and timestamp sourceFile->fileSize = newFileLength; - sourceFile->checksum = MD5_BlockChecksum( buffer, newFileLength ); - fileSystem->ReadFile( GetFileName(), NULL, &sourceFile->timestamp ); + sourceFile->checksum = MD5_BlockChecksum(buffer, newFileLength); + fileSystem->ReadFile(GetFileName(), NULL, &sourceFile->timestamp); // free buffer - Mem_Free( buffer ); + Mem_Free(buffer); // move all decls in the same file - for ( idDeclLocal *decl = sourceFile->decls; decl; decl = decl->nextInFile ) { + for (idDeclLocal* decl = sourceFile->decls; decl; decl = decl->nextInFile) { if (decl->sourceTextOffset > sourceTextOffset) { decl->sourceTextOffset += textLength - sourceTextLength; } @@ -2037,17 +2377,17 @@ bool idDeclLocal::ReplaceSourceFileText( void ) { idDeclLocal::SourceFileChanged ================= */ -bool idDeclLocal::SourceFileChanged( void ) const { +bool idDeclLocal::SourceFileChanged(void) const { int newLength; ID_TIME_T newTimestamp; - if ( sourceFile->fileSize <= 0 ) { + if (sourceFile->fileSize <= 0) { return false; } - newLength = fileSystem->ReadFile( GetFileName(), NULL, &newTimestamp ); + newLength = fileSystem->ReadFile(GetFileName(), NULL, &newTimestamp); - if ( newLength != sourceFile->fileSize || newTimestamp != sourceFile->timestamp ) { + if (newLength != sourceFile->fileSize || newTimestamp != sourceFile->timestamp) { return true; } @@ -2061,9 +2401,9 @@ idDeclLocal::MakeDefault */ void idDeclLocal::MakeDefault() { static int recursionLevel; - const char *defaultText; + const char* defaultText; - declManagerLocal.MediaPrint( "DEFAULTED\n" ); + declManagerLocal.MediaPrint("DEFAULTED\n"); declState = DS_DEFAULTED; AllocateSelf(); @@ -2074,15 +2414,15 @@ void idDeclLocal::MakeDefault() { // cause an infinite loop, but normal default definitions could // still reference other default definitions, so we can't // just dump out on the first recursion - if ( ++recursionLevel > 100 ) { - common->FatalError( "idDecl::MakeDefault: bad DefaultDefinition(): %s", defaultText ); + if (++recursionLevel > 100) { + common->FatalError("idDecl::MakeDefault: bad DefaultDefinition(): %s", defaultText); } // always free data before parsing self->FreeData(); // parse - self->Parse( defaultText, strlen( defaultText ) ); + self->Parse(defaultText, strlen(defaultText)); // we could still eventually hit the recursion if we have enough Error() calls inside Parse... --recursionLevel; @@ -2093,7 +2433,7 @@ void idDeclLocal::MakeDefault() { idDeclLocal::SetDefaultText ================= */ -bool idDeclLocal::SetDefaultText( void ) { +bool idDeclLocal::SetDefaultText(void) { return false; } @@ -2102,7 +2442,7 @@ bool idDeclLocal::SetDefaultText( void ) { idDeclLocal::DefaultDefinition ================= */ -const char *idDeclLocal::DefaultDefinition() const { +const char* idDeclLocal::DefaultDefinition() const { return "{ }"; } @@ -2111,13 +2451,13 @@ const char *idDeclLocal::DefaultDefinition() const { idDeclLocal::Parse ================= */ -bool idDeclLocal::Parse( const char *text, const int textLength ) { +bool idDeclLocal::Parse(const char* text, const int textLength) { idLexer src; - src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); - src.SetFlags( DECL_LEXER_FLAGS ); - src.SkipUntilString( "{" ); - src.SkipBracedSection( false ); + src.LoadMemory(text, textLength, GetFileName(), GetLineNum()); + src.SetFlags(DECL_LEXER_FLAGS); + src.SkipUntilString("{"); + src.SkipBracedSection(false); return true; } @@ -2135,7 +2475,7 @@ idDeclLocal::List ================= */ void idDeclLocal::List() const { - common->Printf( "%s\n", GetName() ); + common->Printf("%s\n", GetName()); } /* @@ -2151,8 +2491,8 @@ void idDeclLocal::Print() const { idDeclLocal::Reload ================= */ -void idDeclLocal::Reload( void ) { - this->sourceFile->Reload( false ); +void idDeclLocal::Reload(void) { + this->sourceFile->Reload(false); } /* @@ -2160,9 +2500,9 @@ void idDeclLocal::Reload( void ) { idDeclLocal::AllocateSelf ================= */ -void idDeclLocal::AllocateSelf( void ) { - if ( self == NULL ) { - self = declManagerLocal.GetDeclType( (int)type )->allocator(); +void idDeclLocal::AllocateSelf(void) { + if (self == NULL) { + self = declManagerLocal.GetDeclType((int)type)->allocator(); self->base = this; } } @@ -2172,7 +2512,7 @@ void idDeclLocal::AllocateSelf( void ) { idDeclLocal::ParseLocal ================= */ -void idDeclLocal::ParseLocal( void ) { +void idDeclLocal::ParseLocal(void) { bool generatedDefaultText = false; AllocateSelf(); @@ -2180,10 +2520,10 @@ void idDeclLocal::ParseLocal( void ) { // always free data before parsing self->FreeData(); - declManagerLocal.MediaPrint( "parsing %s %s\n", declManagerLocal.declTypes[type]->typeName.c_str(), name.c_str() ); + declManagerLocal.MediaPrint("parsing %s %s\n", declManagerLocal.declTypes[type]->typeName.c_str(), name.c_str()); // if no text source try to generate default text - if ( textSource == NULL ) { + if (textSource == NULL) { generatedDefaultText = self->SetDefaultText(); } @@ -2191,7 +2531,7 @@ void idDeclLocal::ParseLocal( void ) { declManagerLocal.indent++; // no text immediately causes a MakeDefault() - if ( textSource == NULL ) { + if (textSource == NULL) { MakeDefault(); declManagerLocal.indent--; return; @@ -2200,13 +2540,13 @@ void idDeclLocal::ParseLocal( void ) { declState = DS_PARSED; // parse - char *declText = (char *) _alloca( ( GetTextLength() + 1 ) * sizeof( char ) ); - GetText( declText ); - self->Parse( declText, GetTextLength() ); + char* declText = (char*)_alloca((GetTextLength() + 1) * sizeof(char)); + GetText(declText); + self->Parse(declText, GetTextLength()); // free generated text - if ( generatedDefaultText ) { - Mem_Free( textSource ); + if (generatedDefaultText) { + Mem_Free(textSource); textSource = 0; textLength = 0; } @@ -2219,10 +2559,10 @@ void idDeclLocal::ParseLocal( void ) { idDeclLocal::Purge ================= */ -void idDeclLocal::Purge( void ) { +void idDeclLocal::Purge(void) { // never purge things that were referenced outside level load, // like the console and menu graphics - if ( parsedOutsideLevelLoad ) { + if (parsedOutsideLevelLoad) { return; } @@ -2238,7 +2578,7 @@ void idDeclLocal::Purge( void ) { idDeclLocal::EverReferenced ================= */ -bool idDeclLocal::EverReferenced( void ) const { +bool idDeclLocal::EverReferenced(void) const { return everReferenced; } diff --git a/neo/engine/framework/DeclManager.h b/neo/engine/framework/DeclManager.h index 45f96a1a..761fd76e 100644 --- a/neo/engine/framework/DeclManager.h +++ b/neo/engine/framework/DeclManager.h @@ -2,9 +2,9 @@ =========================================================================== IceTech GPL Source Code -Copyright (C) 2026 Justin Marshall +Copyright (C) 2026 Justin Marshall -This file is part of the IceTech GPL Source Code (?IceTech Source Code?). +This file is part of the IceTech GPL Source Code (?IceTech Source Code?). IceTech Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -63,7 +63,7 @@ If you have questions concerning this license or the applicable additional terms */ typedef enum { - DECL_TABLE = 0, + DECL_TABLE = 0, DECL_MATERIAL, DECL_SKIN, DECL_SOUND, @@ -93,7 +93,7 @@ typedef enum { // new decl types can be added here - DECL_MAX_TYPES = 32 + DECL_MAX_TYPES = 32 } declType_t; typedef enum { @@ -102,243 +102,279 @@ typedef enum { DS_PARSED } declState_t; -const int DECL_LEXER_FLAGS = LEXFL_NOSTRINGCONCAT | // multiple strings seperated by whitespaces are not concatenated - LEXFL_NOSTRINGESCAPECHARS | // no escape characters inside strings - LEXFL_ALLOWPATHNAMES | // allow path seperators in names - LEXFL_ALLOWMULTICHARLITERALS | // allow multi character literals - LEXFL_ALLOWBACKSLASHSTRINGCONCAT | // allow multiple strings seperated by '\' to be concatenated - LEXFL_NOFATALERRORS; // just set a flag instead of fatal erroring +const int DECL_LEXER_FLAGS = LEXFL_NOSTRINGCONCAT | // multiple strings seperated by whitespaces are not concatenated +LEXFL_NOSTRINGESCAPECHARS | // no escape characters inside strings +LEXFL_ALLOWPATHNAMES | // allow path seperators in names +LEXFL_ALLOWMULTICHARLITERALS | // allow multi character literals +LEXFL_ALLOWBACKSLASHSTRINGCONCAT | // allow multiple strings seperated by '\' to be concatenated +LEXFL_NOFATALERRORS; // just set a flag instead of fatal erroring class idDeclBase { public: virtual ~idDeclBase() {}; - virtual const char * GetName( void ) const = 0; - virtual declType_t GetType( void ) const = 0; - virtual declState_t GetState( void ) const = 0; - virtual bool IsImplicit( void ) const = 0; - virtual bool IsValid( void ) const = 0; - virtual void Invalidate( void ) = 0; - virtual void Reload( void ) = 0; - virtual void EnsureNotPurged( void ) = 0; - virtual int Index( void ) const = 0; - virtual int GetLineNum( void ) const = 0; - virtual const char * GetFileName( void ) const = 0; - virtual void GetText( char *text ) const = 0; - virtual int GetTextLength( void ) const = 0; - virtual void SetText( const char *text ) = 0; - virtual bool ReplaceSourceFileText( void ) = 0; - virtual bool SourceFileChanged( void ) const = 0; - virtual void MakeDefault( void ) = 0; - virtual bool EverReferenced( void ) const = 0; - virtual bool SetDefaultText( void ) = 0; - virtual const char * DefaultDefinition( void ) const = 0; - virtual bool Parse( const char *text, const int textLength ) = 0; - virtual void FreeData( void ) = 0; - virtual size_t Size( void ) const = 0; - virtual void List( void ) const = 0; - virtual void Print( void ) const = 0; + virtual const char* GetName(void) const = 0; + virtual declType_t GetType(void) const = 0; + virtual declState_t GetState(void) const = 0; + virtual bool IsImplicit(void) const = 0; + virtual bool IsValid(void) const = 0; + virtual void Invalidate(void) = 0; + virtual void Reload(void) = 0; + virtual void EnsureNotPurged(void) = 0; + virtual int Index(void) const = 0; + virtual int GetLineNum(void) const = 0; + virtual const char* GetFileName(void) const = 0; + virtual void GetText(char* text) const = 0; + virtual int GetTextLength(void) const = 0; + virtual void SetText(const char* text) = 0; + virtual bool ReplaceSourceFileText(void) = 0; + virtual bool SourceFileChanged(void) const = 0; + virtual void MakeDefault(void) = 0; + virtual bool EverReferenced(void) const = 0; + virtual bool SetDefaultText(void) = 0; + virtual const char* DefaultDefinition(void) const = 0; + virtual bool Parse(const char* text, const int textLength) = 0; + virtual void FreeData(void) = 0; + virtual size_t Size(void) const = 0; + virtual void List(void) const = 0; + virtual void Print(void) const = 0; }; +#ifdef QUAKE4 +// Quake 4 guide/template support +#define MAX_GUIDE_PARMS 20 +#define MAX_GUIDE_SHADER_SIZE 20480 + +class rvDeclGuide { +private: + idStr mName; + idStr mParms[MAX_GUIDE_PARMS]; + idStr mDefinition; + int mNumParms; + +public: + rvDeclGuide(idStr& name); + ~rvDeclGuide(void); + + const char* GetName(void) const { return mName.c_str(); } + int GetNumParms(void) const { return mNumParms; } + const char* GetParm(int index) const { assert(index < mNumParms); return mParms[index].c_str(); } + + void SetParm(int index, const char* value); + void RemoveOuterBracing(void); + void Parse(idLexer* src); + bool Evaluate(idLexer* src, idStr& definition); +}; +#endif + class idDecl { public: - // The constructor should initialize variables such that - // an immediate call to FreeData() does no harm. - idDecl( void ) { base = NULL; } - virtual ~idDecl( void ) {}; + // The constructor should initialize variables such that + // an immediate call to FreeData() does no harm. + idDecl(void) { base = NULL; } + virtual ~idDecl(void) {}; - // Returns the name of the decl. - const char * GetName( void ) const { return base->GetName(); } + // Returns the name of the decl. + const char* GetName(void) const { return base->GetName(); } - // Returns the decl type. - declType_t GetType( void ) const { return base->GetType(); } + // Returns the decl type. + declType_t GetType(void) const { return base->GetType(); } - // Returns the decl state which is usefull for finding out if a decl defaulted. - declState_t GetState( void ) const { return base->GetState(); } + // Returns the decl state which is usefull for finding out if a decl defaulted. + declState_t GetState(void) const { return base->GetState(); } - // Returns true if the decl was defaulted or the text was created with a call to SetDefaultText. - bool IsImplicit( void ) const { return base->IsImplicit(); } + // Returns true if the decl was defaulted or the text was created with a call to SetDefaultText. + bool IsImplicit(void) const { return base->IsImplicit(); } - // The only way non-manager code can have an invalid decl is if the *ByIndex() - // call was used with forceParse = false to walk the lists to look at names - // without touching the media. - bool IsValid( void ) const { return base->IsValid(); } + // The only way non-manager code can have an invalid decl is if the *ByIndex() + // call was used with forceParse = false to walk the lists to look at names + // without touching the media. + bool IsValid(void) const { return base->IsValid(); } - // Sets state back to unparsed. - // Used by decl editors to undo any changes to the decl. - void Invalidate( void ) { base->Invalidate(); } + // Sets state back to unparsed. + // Used by decl editors to undo any changes to the decl. + void Invalidate(void) { base->Invalidate(); } - // if a pointer might possible be stale from a previous level, - // call this to have it re-parsed - void EnsureNotPurged( void ) { base->EnsureNotPurged(); } + // if a pointer might possible be stale from a previous level, + // call this to have it re-parsed + void EnsureNotPurged(void) { base->EnsureNotPurged(); } - // Returns the index in the per-type list. - int Index( void ) const { return base->Index(); } + // Returns the index in the per-type list. + int Index(void) const { return base->Index(); } - // Returns the line number the decl starts. - int GetLineNum( void ) const { return base->GetLineNum(); } + // Returns the line number the decl starts. + int GetLineNum(void) const { return base->GetLineNum(); } - // Returns the name of the file in which the decl is defined. - const char * GetFileName( void ) const { return base->GetFileName(); } + // Returns the name of the file in which the decl is defined. + const char* GetFileName(void) const { return base->GetFileName(); } - // Returns the decl text. - void GetText( char *text ) const { base->GetText( text ); } + // Returns the decl text. + void GetText(char* text) const { base->GetText(text); } - // Returns the length of the decl text. - int GetTextLength( void ) const { return base->GetTextLength(); } + // Returns the length of the decl text. + int GetTextLength(void) const { return base->GetTextLength(); } - // Sets new decl text. - void SetText( const char *text ) { base->SetText( text ); } + // Sets new decl text. + void SetText(const char* text) { base->SetText(text); } - // Saves out new text for the decl. - // Used by decl editors to replace the decl text in the source file. - bool ReplaceSourceFileText( void ) { return base->ReplaceSourceFileText(); } + // Saves out new text for the decl. + // Used by decl editors to replace the decl text in the source file. + bool ReplaceSourceFileText(void) { return base->ReplaceSourceFileText(); } - // Returns true if the source file changed since it was loaded and parsed. - bool SourceFileChanged( void ) const { return base->SourceFileChanged(); } + // Returns true if the source file changed since it was loaded and parsed. + bool SourceFileChanged(void) const { return base->SourceFileChanged(); } - // Frees data and makes the decl a default. - void MakeDefault( void ) { base->MakeDefault(); } + // Frees data and makes the decl a default. + void MakeDefault(void) { base->MakeDefault(); } - // Returns true if the decl was ever referenced. - bool EverReferenced( void ) const { return base->EverReferenced(); } + // Returns true if the decl was ever referenced. + bool EverReferenced(void) const { return base->EverReferenced(); } public: - // Sets textSource to a default text if necessary. - // This may be overridden to provide a default definition based on the - // decl name. For instance materials may default to an implicit definition - // using a texture with the same name as the decl. - virtual bool SetDefaultText( void ) { return base->SetDefaultText(); } + // Sets textSource to a default text if necessary. + // This may be overridden to provide a default definition based on the + // decl name. For instance materials may default to an implicit definition + // using a texture with the same name as the decl. + virtual bool SetDefaultText(void) { return base->SetDefaultText(); } - // Each declaration type must have a default string that it is guaranteed - // to parse acceptably. When a decl is not explicitly found, is purged, or - // has an error while parsing, MakeDefault() will do a FreeData(), then a - // Parse() with DefaultDefinition(). The defaultDefintion should start with - // an open brace and end with a close brace. - virtual const char * DefaultDefinition( void ) const { return base->DefaultDefinition(); } + // Each declaration type must have a default string that it is guaranteed + // to parse acceptably. When a decl is not explicitly found, is purged, or + // has an error while parsing, MakeDefault() will do a FreeData(), then a + // Parse() with DefaultDefinition(). The defaultDefintion should start with + // an open brace and end with a close brace. + virtual const char* DefaultDefinition(void) const { return base->DefaultDefinition(); } - // The manager will have already parsed past the type, name and opening brace. - // All necessary media will be touched before return. - // The manager will have called FreeData() before issuing a Parse(). - // The subclass can call MakeDefault() internally at any point if - // there are parse errors. - virtual bool Parse( const char *text, const int textLength ) { return base->Parse( text, textLength ); } + // The manager will have already parsed past the type, name and opening brace. + // All necessary media will be touched before return. + // The manager will have called FreeData() before issuing a Parse(). + // The subclass can call MakeDefault() internally at any point if + // there are parse errors. + virtual bool Parse(const char* text, const int textLength) { return base->Parse(text, textLength); } - // Frees any pointers held by the subclass. This may be called before - // any Parse(), so the constructor must have set sane values. The decl will be - // invalid after issuing this call, but it will always be immediately followed - // by a Parse() - virtual void FreeData( void ) { base->FreeData(); } + // Frees any pointers held by the subclass. This may be called before + // any Parse(), so the constructor must have set sane values. The decl will be + // invalid after issuing this call, but it will always be immediately followed + // by a Parse() + virtual void FreeData(void) { base->FreeData(); } - // Returns the size of the decl in memory. - virtual size_t Size( void ) const { return base->Size(); } + // Returns the size of the decl in memory. + virtual size_t Size(void) const { return base->Size(); } - // If this isn't overridden, it will just print the decl name. - // The manager will have printed 7 characters on the line already, - // containing the reference state and index number. - virtual void List( void ) const { base->List(); } + // If this isn't overridden, it will just print the decl name. + // The manager will have printed 7 characters on the line already, + // containing the reference state and index number. + virtual void List(void) const { base->List(); } - // The print function will already have dumped the text source - // and common data, subclasses can override this to dump more - // explicit data. - virtual void Print( void ) const { base->Print(); } + // The print function will already have dumped the text source + // and common data, subclasses can override this to dump more + // explicit data. + virtual void Print(void) const { base->Print(); } public: - idDeclBase * base; + idDeclBase* base; }; template< class type > -ID_INLINE idDecl *idDeclAllocator( void ) { +ID_INLINE idDecl* idDeclAllocator(void) { return new type; } class idMaterial; +class idDeclTable; class idDeclSkin; class idSoundShader; class idDeclManager { public: - virtual ~idDeclManager( void ) {} + virtual ~idDeclManager(void) {} - virtual void Init( void ) = 0; - virtual void Shutdown( void ) = 0; - virtual void Reload( bool force ) = 0; + virtual void Init(void) = 0; + virtual void Shutdown(void) = 0; + virtual void Reload(bool force) = 0; virtual void BeginLevelLoad() = 0; virtual void EndLevelLoad() = 0; - // Registers a new decl type. - virtual void RegisterDeclType( const char *typeName, declType_t type, idDecl *(*allocator)( void ) ) = 0; + // Registers a new decl type. + virtual void RegisterDeclType(const char* typeName, declType_t type, idDecl* (*allocator)(void)) = 0; - // Registers a new folder with decl files. - virtual void RegisterDeclFolder( const char *folder, const char *extension, declType_t defaultType ) = 0; + // Registers a new folder with decl files. + virtual void RegisterDeclFolder(const char* folder, const char* extension, declType_t defaultType) = 0; - // Returns a checksum for all loaded decl text. - virtual int GetChecksum( void ) const = 0; + // Returns a checksum for all loaded decl text. + virtual int GetChecksum(void) const = 0; - // Returns the number of decl types. - virtual int GetNumDeclTypes( void ) const = 0; + // Returns the number of decl types. + virtual int GetNumDeclTypes(void) const = 0; - // Returns the type name for a decl type. - virtual const char * GetDeclNameFromType( declType_t type ) const = 0; + // Returns the type name for a decl type. + virtual const char* GetDeclNameFromType(declType_t type) const = 0; - // Returns the decl type for a type name. - virtual declType_t GetDeclTypeFromName( const char *typeName ) const = 0; + // Returns the decl type for a type name. + virtual declType_t GetDeclTypeFromName(const char* typeName) const = 0; - // If makeDefault is true, a default decl of appropriate type will be created - // if an explicit one isn't found. If makeDefault is false, NULL will be returned - // if the decl wasn't explcitly defined. - virtual const idDecl * FindType( declType_t type, const char *name, bool makeDefault = true ) = 0; + // If makeDefault is true, a default decl of appropriate type will be created + // if an explicit one isn't found. If makeDefault is false, NULL will be returned + // if the decl wasn't explcitly defined. + virtual const idDecl* FindType(declType_t type, const char* name, bool makeDefault = true) = 0; #ifdef QUAKE4 // Quake 4 added decl caching, its not needed. - virtual const idDecl* FindType(declType_t type, const char* name, bool makeDefault, bool noCaching) { + virtual const idDecl* FindType(declType_t type, const char* name, bool makeDefault, bool noCaching) { return FindType(type, name, makeDefault); } #endif - virtual const idDecl* FindDeclWithoutParsing( declType_t type, const char *name, bool makeDefault = true ) = 0; + virtual const idDecl* FindDeclWithoutParsing(declType_t type, const char* name, bool makeDefault = true) = 0; - virtual void ReloadFile( const char* filename, bool force ) = 0; + virtual void ReloadFile(const char* filename, bool force) = 0; - // Returns the number of decls of the given type. - virtual int GetNumDecls( declType_t type ) = 0; + // Returns the number of decls of the given type. + virtual int GetNumDecls(declType_t type) = 0; - // The complete lists of decls can be walked to populate editor browsers. - // If forceParse is set false, you can get the decl to check name / filename / etc. - // without causing it to parse the source and load media. - virtual const idDecl * DeclByIndex( declType_t type, int index, bool forceParse = true ) = 0; + // The complete lists of decls can be walked to populate editor browsers. + // If forceParse is set false, you can get the decl to check name / filename / etc. + // without causing it to parse the source and load media. + virtual const idDecl* DeclByIndex(declType_t type, int index, bool forceParse = true) = 0; - // List and print decls. - virtual void ListType( const idCmdArgs &args, declType_t type ) = 0; - virtual void PrintType( const idCmdArgs &args, declType_t type ) = 0; + // List and print decls. + virtual void ListType(const idCmdArgs& args, declType_t type) = 0; + virtual void PrintType(const idCmdArgs& args, declType_t type) = 0; - // Creates a new default decl of the given type with the given name in - // the given file used by editors to create a new decls. - virtual idDecl * CreateNewDecl( declType_t type, const char *name, const char *fileName ) = 0; + // Creates a new default decl of the given type with the given name in + // the given file used by editors to create a new decls. + virtual idDecl* CreateNewDecl(declType_t type, const char* name, const char* fileName) = 0; - // BSM - Added for the material editors rename capabilities - virtual bool RenameDecl( declType_t type, const char* oldName, const char* newName ) = 0; + // BSM - Added for the material editors rename capabilities + virtual bool RenameDecl(declType_t type, const char* oldName, const char* newName) = 0; - // When media files are loaded, a reference line can be printed at a - // proper indentation if decl_show is set - virtual void MediaPrint( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0; + // When media files are loaded, a reference line can be printed at a + // proper indentation if decl_show is set + virtual void MediaPrint(const char* fmt, ...) id_attribute((format(printf, 2, 3))) = 0; - virtual void WritePrecacheCommands( idFile *f ) = 0; + virtual void WritePrecacheCommands(idFile* f) = 0; - // Convenience functions for specific types. - virtual const idMaterial * FindMaterial( const char *name, bool makeDefault = true ) = 0; - virtual const idDeclSkin * FindSkin( const char *name, bool makeDefault = true ) = 0; - virtual const idSoundShader * FindSound( const char *name, bool makeDefault = true ) = 0; +#ifdef QUAKE4 + // Quake 4 guide/template support + virtual void ParseGuides(void) = 0; + virtual void ShutdownGuides(void) = 0; + virtual bool EvaluateGuide(idStr& name, idLexer* src, idStr& definition) = 0; + virtual bool EvaluateInlineGuide(idStr& name, idStr& definition) = 0; +#endif - virtual const idMaterial * MaterialByIndex( int index, bool forceParse = true ) = 0; - virtual const idDeclSkin * SkinByIndex( int index, bool forceParse = true ) = 0; - virtual const idSoundShader * SoundByIndex( int index, bool forceParse = true ) = 0; + // Convenience functions for specific types. + virtual const idMaterial* FindMaterial(const char* name, bool makeDefault = true) = 0; + virtual const idDeclSkin* FindSkin(const char* name, bool makeDefault = true) = 0; + virtual const idSoundShader* FindSound(const char* name, bool makeDefault = true) = 0; - virtual const class idDeclTable* FindTable(const char* name, bool makeDefault = true) = 0; + virtual const idMaterial* MaterialByIndex(int index, bool forceParse = true) = 0; + virtual const idDeclSkin* SkinByIndex(int index, bool forceParse = true) = 0; + virtual const idSoundShader* SoundByIndex(int index, bool forceParse = true) = 0; + + virtual const class idDeclTable* FindTable(const char* name, bool makeDefault = true) = 0; #ifdef QUAKE4 virtual const class rvDeclMatType* FindMaterialType(const char* name, bool makeDefault = true) = 0; @@ -353,17 +389,17 @@ public: #endif }; -extern idDeclManager * declManager; +extern idDeclManager* declManager; template< declType_t type > -ID_INLINE void idListDecls_f( const idCmdArgs &args ) { - declManager->ListType( args, type ); +ID_INLINE void idListDecls_f(const idCmdArgs& args) { + declManager->ListType(args, type); } template< declType_t type > -ID_INLINE void idPrintDecls_f( const idCmdArgs &args ) { - declManager->PrintType( args, type ); +ID_INLINE void idPrintDecls_f(const idCmdArgs& args) { + declManager->PrintType(args, type); } #endif /* !__DECLMANAGER_H__ */ diff --git a/neo/engine/framework/Licensee.h b/neo/engine/framework/Licensee.h index 82914400..824d6eb9 100644 --- a/neo/engine/framework/Licensee.h +++ b/neo/engine/framework/Licensee.h @@ -51,6 +51,8 @@ If you have questions concerning this license or the applicable additional terms #else #ifdef PREY #define BASE_GAMEDIR "preybase" +#elif defined(QUAKE4) + #define BASE_GAMEDIR "q4base" #else #define BASE_GAMEDIR "base" #endif diff --git a/neo/engine/framework/Session.cpp b/neo/engine/framework/Session.cpp index 34f4b1b3..5991ebb4 100644 --- a/neo/engine/framework/Session.cpp +++ b/neo/engine/framework/Session.cpp @@ -1815,7 +1815,7 @@ void idSessionLocal::ExecuteMapChange( bool noFadeWipe ) { game->SetServerInfo( mapSpawnData.serverInfo ); #ifdef QUAKE4 - game->InitFromNewMap(fullMapName + ".map", rw, sw, idAsyncNetwork::server.IsActive(), idAsyncNetwork::client.IsActive()); + game->InitFromNewMap(fullMapName + ".map", rw, idAsyncNetwork::server.IsActive(), idAsyncNetwork::client.IsActive(), 0); #else game->InitFromNewMap( fullMapName + ".map", rw, sw, idAsyncNetwork::server.IsActive(), idAsyncNetwork::client.IsActive(), Sys_Milliseconds() ); #endif @@ -1823,7 +1823,7 @@ void idSessionLocal::ExecuteMapChange( bool noFadeWipe ) { } else { game->SetServerInfo( mapSpawnData.serverInfo ); #ifdef QUAKE4 - game->InitFromNewMap(fullMapName + ".map", rw, sw, idAsyncNetwork::server.IsActive(), idAsyncNetwork::client.IsActive()); + game->InitFromNewMap(fullMapName + ".map", rw, idAsyncNetwork::server.IsActive(), idAsyncNetwork::client.IsActive(), 0); #else game->InitFromNewMap( fullMapName + ".map", rw, sw, idAsyncNetwork::server.IsActive(), idAsyncNetwork::client.IsActive(), Sys_Milliseconds() ); #endif diff --git a/neo/engine/idlib/Lexer.cpp b/neo/engine/idlib/Lexer.cpp index c2c0600e..d7e04a3a 100644 --- a/neo/engine/idlib/Lexer.cpp +++ b/neo/engine/idlib/Lexer.cpp @@ -537,6 +537,11 @@ idStr const Lexer::sCompiledFileSuffix( "c" ); // RAVEN END #endif +/* +================ +idLexer::CreatePunctuationTable +================ +*/ /* ================ idLexer::CreatePunctuationTable @@ -544,65 +549,90 @@ idLexer::CreatePunctuationTable */ void idLexer::CreatePunctuationTable( const punctuation_t *punctuations ) { int i, n, lastp; + int numPunctuations; const punctuation_t *p, *newp; - //get memory for the table + if ( punctuations == NULL ) { + punctuations = default_punctuations; + } + + for ( numPunctuations = 0; punctuations[numPunctuations].p; numPunctuations++ ) { + } + + // get memory for the table if ( punctuations == default_punctuations ) { idLexer::punctuationtable = default_punctuationtable; idLexer::nextpunctuation = default_nextpunctuation; + if ( default_setup ) { return; } + default_setup = true; - i = sizeof(default_punctuations) / sizeof(punctuation_t); - } - else { - if ( !idLexer::punctuationtable || idLexer::punctuationtable == default_punctuationtable ) { - #ifdef QUAKE4 - idLexer::punctuationtable = (int *) Mem_Alloc(256 * sizeof(int)); + +#ifdef QUAKE4 + i = numPunctuations; #else - idLexer::punctuationtable = (int *) Mem_Alloc(256 * sizeof(int)); + i = sizeof( default_punctuations ) / sizeof( punctuation_t ); +#endif + } else { + if ( !idLexer::punctuationtable || idLexer::punctuationtable == default_punctuationtable ) { +#ifdef QUAKE4 + idLexer::punctuationtable = (int *) Mem_Alloc( 256 * sizeof( int ) ); +#else + idLexer::punctuationtable = (int *) Mem_Alloc( 256 * sizeof( int ) ); #endif } + if ( idLexer::nextpunctuation && idLexer::nextpunctuation != default_nextpunctuation ) { Mem_Free( idLexer::nextpunctuation ); } - for (i = 0; punctuations[i].p; i++) { - } - #ifdef QUAKE4 - idLexer::nextpunctuation = (int *) Mem_Alloc(i * sizeof(int)); + +#ifdef QUAKE4 + idLexer::nextpunctuation = (int *) Mem_Alloc( numPunctuations * sizeof( int ) ); #else - idLexer::nextpunctuation = (int *) Mem_Alloc(i * sizeof(int)); + idLexer::nextpunctuation = (int *) Mem_Alloc( numPunctuations * sizeof( int ) ); #endif + + i = numPunctuations; } - memset(idLexer::punctuationtable, 0xFF, 256 * sizeof(int)); - memset(idLexer::nextpunctuation, 0xFF, i * sizeof(int)); - //add the punctuations in the list to the punctuation table - for (i = 0; punctuations[i].p; i++) { + + memset( idLexer::punctuationtable, 0xFF, 256 * sizeof( int ) ); + memset( idLexer::nextpunctuation, 0xFF, i * sizeof( int ) ); + + // add the punctuations in the list to the punctuation table + for ( i = 0; punctuations[i].p; i++ ) { newp = &punctuations[i]; lastp = -1; - //sort the punctuations in this table entry on length (longer punctuations first) - for (n = idLexer::punctuationtable[(unsigned int) newp->p[0]]; n >= 0; n = idLexer::nextpunctuation[n] ) { + + // char may be signed, so force the index to 0..255. + const unsigned char firstChar = (unsigned char) newp->p[0]; + + // sort the punctuations in this table entry on length, longer punctuations first + for ( n = idLexer::punctuationtable[firstChar]; n >= 0; n = idLexer::nextpunctuation[n] ) { p = &punctuations[n]; - if (strlen(p->p) < strlen(newp->p)) { + + if ( strlen( p->p ) < strlen( newp->p ) ) { idLexer::nextpunctuation[i] = n; - if (lastp >= 0) { + + if ( lastp >= 0 ) { idLexer::nextpunctuation[lastp] = i; - } - else { - idLexer::punctuationtable[(unsigned int) newp->p[0]] = i; + } else { + idLexer::punctuationtable[firstChar] = i; } break; } + lastp = n; } - if (n < 0) { + + if ( n < 0 ) { idLexer::nextpunctuation[i] = -1; - if (lastp >= 0) { + + if ( lastp >= 0 ) { idLexer::nextpunctuation[lastp] = i; - } - else { - idLexer::punctuationtable[(unsigned int) newp->p[0]] = i; + } else { + idLexer::punctuationtable[firstChar] = i; } } } diff --git a/neo/engine/idlib/Str.cpp b/neo/engine/idlib/Str.cpp index 071f9252..d66cdfe0 100644 --- a/neo/engine/idlib/Str.cpp +++ b/neo/engine/idlib/Str.cpp @@ -29,19 +29,6 @@ If you have questions concerning this license or the applicable additional terms #include "precompiled.h" #pragma hdrstop -#ifdef QUAKE4 -// TTimo - don't do anything funky if you're on a real OS ;-) -#if defined(_WINDOWS) || defined(_XENON) -#if ( !defined(ID_REDIRECT_NEWDELETE) && !defined(RV_UNIFIED_ALLOCATOR) ) || defined(_RV_MEM_SYS_SUPPORT) -#define USE_STRING_DATA_ALLOCATOR -#endif -#endif -#else -#if !defined( ID_REDIRECT_NEWDELETE ) && !defined( MACOS_X ) -#define USE_STRING_DATA_ALLOCATOR -#endif -#endif - #ifdef USE_STRING_DATA_ALLOCATOR static idDynamicBlockAlloc stringDataAllocator; #endif diff --git a/neo/engine/renderer/Image_program.cpp b/neo/engine/renderer/Image_program.cpp index 255ab562..972078ce 100644 --- a/neo/engine/renderer/Image_program.cpp +++ b/neo/engine/renderer/Image_program.cpp @@ -562,7 +562,21 @@ static bool R_ParseImageProgram_r( idLexer &src, byte **pic, int *width, int *he MatchAndAppendToken( src, ")" ); return true; } +#ifdef QUAKE4 + // jmarshall - quake 4 support + if (!token.Icmp("downsize")) { + MatchAndAppendToken(src, "("); + R_ParseImageProgram_r(src, pic, width, height, timestamps, depth); + MatchAndAppendToken(src, ","); + src.ReadToken(&token); + AppendToken(token); + + MatchAndAppendToken(src, ")"); + return true; + } + // jmarshall end +#endif if ( !token.Icmp( "makeAlpha" ) ) { int i; diff --git a/neo/engine/renderer/Material.cpp b/neo/engine/renderer/Material.cpp index 3e110351..1385f91c 100644 --- a/neo/engine/renderer/Material.cpp +++ b/neo/engine/renderer/Material.cpp @@ -235,7 +235,7 @@ void idMaterial::FreeData() { } #ifdef QUAKE4 if (materialTypeArray != NULL) { - Mem_Free(materialTypeArray); + game->MT_FreeMaterialTypeArray(materialTypeArray); materialTypeArray = NULL; materialTypeArrayName = ""; MTAWidth = 0; @@ -3025,7 +3025,28 @@ void idMaterial::ParseMaterial(idLexer& src) { src.ParseRestOfLine(renderBump); continue; } - +#ifdef QUAKE4 + // Quake 4 material guide directives are metadata/preprocessor hints. + // Treat them as no-op at runtime so shipped materials don't default. + else if (!token.Icmp("inlineGuide") || !token.Icmp("guide")) { + idToken guideName; + if (src.ReadToken(&guideName)) { + if (src.CheckTokenString("(")) { + int parenDepth = 1; + idToken guideToken; + while (parenDepth > 0 && src.ReadToken(&guideToken)) { + if (guideToken == "(") { + parenDepth++; + } + else if (guideToken == ")") { + parenDepth--; + } + } + } + } + continue; + } +#endif else if (!token.Icmp("glowmap")) { str = R_ParsePastImageProgram(src); idStr::snPrintf(buffer, sizeof(buffer), "blend glowmap\nmap %s\n}\n", str); @@ -3241,12 +3262,7 @@ idMaterial::Parse Parses the current material definition and finds all necessary images. ========================= */ -#ifdef QUAKE4 -bool idMaterial::Parse(const char* text, const int textLength, bool noCaching) { - (void)noCaching; -#else bool idMaterial::Parse(const char* text, const int textLength) { -#endif idLexer src; idToken token; mtrParsingData_t parsingData; diff --git a/neo/engine/renderer/Material.h b/neo/engine/renderer/Material.h index 0a54faa6..7f3e5043 100644 --- a/neo/engine/renderer/Material.h +++ b/neo/engine/renderer/Material.h @@ -550,11 +550,7 @@ public: virtual size_t Size(void) const; virtual bool SetDefaultText(void); virtual const char* DefaultDefinition(void) const; -#ifdef QUAKE4 - virtual bool Parse(const char* text, const int textLength, bool noCaching = false); -#else virtual bool Parse(const char* text, const int textLength); -#endif virtual void FreeData(void); virtual void Print(void) const; diff --git a/neo/engine/renderer/RenderWorld_load.cpp b/neo/engine/renderer/RenderWorld_load.cpp index 0ec76eda..b911b53d 100644 --- a/neo/engine/renderer/RenderWorld_load.cpp +++ b/neo/engine/renderer/RenderWorld_load.cpp @@ -141,6 +141,13 @@ idRenderModel *idRenderWorldLocal::ParseModel( idLexer *src ) { if ( numSurfaces < 0 ) { src->Error( "R_ParseModel: bad numSurfaces" ); } +#ifdef QUAKE4 +// jmarshall - quake 4 proc format + if (!src->PeekTokenString("{") && !src->PeekTokenString("}")) { + int sky = src->ParseInt(); + } +// jmarshall end +#endif for ( i = 0 ; i < numSurfaces ; i++ ) { src->ExpectTokenString( "{" ); @@ -159,6 +166,36 @@ idRenderModel *idRenderWorldLocal::ParseModel( idLexer *src ) { R_AllocStaticTriSurfVerts( tri, tri->numVerts ); for ( j = 0 ; j < tri->numVerts ; j++ ) { +#ifdef QUAKE4 + // jmarshall - quake 4 proc format + float vec[12]; + const int numFloats = src->Parse1DMatrixOpenEnded( 12, vec ); + if ( numFloats != 8 && numFloats != 12 ) { + src->Error( "R_ParseModel: bad vertex read" ); + } + + tri->verts[j].xyz[0] = vec[0]; + tri->verts[j].xyz[1] = vec[1]; + tri->verts[j].xyz[2] = vec[2]; + tri->verts[j].st[0] = vec[3]; + tri->verts[j].st[1] = vec[4]; + tri->verts[j].normal[0] = vec[5]; + tri->verts[j].normal[1] = vec[6]; + tri->verts[j].normal[2] = vec[7]; + + if ( numFloats == 12 ) { + tri->verts[j].color[0] = idMath::Ftob( vec[8] ); + tri->verts[j].color[1] = idMath::Ftob( vec[9] ); + tri->verts[j].color[2] = idMath::Ftob( vec[10] ); + tri->verts[j].color[3] = idMath::Ftob( vec[11] ); + } else { + tri->verts[j].color[0] = 0; + tri->verts[j].color[1] = 0; + tri->verts[j].color[2] = 0; + tri->verts[j].color[3] = 255; + } +// jmarshall end +#else float vec[8]; src->Parse1DMatrix( 8, vec ); @@ -171,6 +208,7 @@ idRenderModel *idRenderWorldLocal::ParseModel( idLexer *src ) { tri->verts[j].normal[0] = vec[5]; tri->verts[j].normal[1] = vec[6]; tri->verts[j].normal[2] = vec[7]; +#endif } R_AllocStaticTriSurfIndexes( tri, tri->numIndexes ); @@ -544,7 +582,18 @@ bool idRenderWorldLocal::InitFromMap( const char *name ) { delete src; return false; } +#ifdef QUAKE4 +// jmarshall: quake 4 proc format + if (!src->ReadToken(&token)) { + common->Printf("idRenderWorldLocal::InitFromMap: bad version '%s' instead of '%s'\n", token.c_str(), PROC_FILEVERSION); + delete src; + return false; + } + // Map CRC, we aren't going to use it. + src->ReadToken(&token); +// jmarshall end +#endif // parse the file while ( 1 ) { if ( !src->ReadToken( &token ) ) { diff --git a/neo/engine/renderer/tr_font.cpp b/neo/engine/renderer/tr_font.cpp index ca94d52f..c0508eaa 100644 --- a/neo/engine/renderer/tr_font.cpp +++ b/neo/engine/renderer/tr_font.cpp @@ -268,7 +268,217 @@ RegisterFont Loads 3 point sizes, 12, 24, and 48 ============ */ + bool idRenderSystemLocal::RegisterFont(const char* fontName, fontInfoEx_t& font) { +#ifdef QUAKE4 + + void* faceData; + ID_TIME_T ftime; + int fontCount; + int found; + char fontDatName[1024]; + char materialName[1024]; + + memset(&font, 0, sizeof(font)); + + found = 0; + + for (fontCount = 0; fontCount < 3; fontCount++) { + int pointSize; + fontInfo_t* outFont; + + if (fontCount == 0) { + pointSize = 12; + outFont = &font.fontInfoSmall; + } + else if (fontCount == 1) { + pointSize = 24; + outFont = &font.fontInfoMedium; + } + else { + pointSize = 48; + outFont = &font.fontInfoLarge; + } + + idStr::snPrintf(fontDatName, sizeof(fontDatName), "%s_%i.fontdat", fontName, pointSize); + #define FILESIZE_q4FontInfo_t 9236 + if (fileSystem->ReadFile(fontDatName, NULL, &ftime) != FILESIZE_q4FontInfo_t) { + continue; + } + + if (fileSystem->ReadFile(fontDatName, &faceData, &ftime) <= 0 || faceData == NULL) { + continue; + } + + fdOffset = 0; + fdFile = reinterpret_cast(faceData); + + found |= 1 << fontCount; + + idStr::Copynz(outFont->name, fontDatName, sizeof(outFont->name)); + + int mw = 0; + int mh = 0; + + for (int i = 0; i < GLYPHS_PER_FONT; i++) { + glyphInfo_t& glyph = outFont->glyphs[i]; + + /* + Quake 4 disk glyph order: + float width; + float height; + float horiAdvance; + float horiBearingX; + float horiBearingY; + float s1; + float t1; + float s2; + float t2; + + Doom 3 glyphInfo_t is not the same struct, so map it. + */ + const float q4Width = readFloat(); + const float q4Height = readFloat(); + const float q4HoriAdvance = readFloat(); + const float q4HoriBearingX = readFloat(); + const float q4HoriBearingY = readFloat(); + const float q4S1 = readFloat(); + const float q4T1 = readFloat(); + const float q4S2 = readFloat(); + const float q4T2 = readFloat(); + + glyph.height = (int)q4Height; + glyph.top = (int)q4HoriBearingY; + glyph.bottom = (int)(q4HoriBearingY - q4Height); + glyph.pitch = (int)q4Width; + glyph.xSkip = (int)q4HoriAdvance; + glyph.imageWidth = (int)q4Width; + glyph.imageHeight = (int)q4Height; + + glyph.s = q4S1; + glyph.t = q4T1; + glyph.s2 = q4S2; + glyph.t2 = q4T2; + + glyph.glyph = NULL; + glyph.shaderName[0] = '\0'; + + if (mw < glyph.xSkip) { + mw = glyph.xSkip; + } + if (mh < glyph.height) { + mh = glyph.height; + } + } + + /* + Quake 4 stores these after the glyph array: + pointSize, fontHeight, ascender, descender, material pointer + + Doom 3's fontInfo_t does not have those fields, so consume them. + */ + const float q4PointSize = readFloat(); + const float q4FontHeight = readFloat(); + const float q4Ascender = readFloat(); + const float q4Descender = readFloat(); + + // consume the saved material pointer / padding from the .fontdat + readInt(); + + outFont->glyphScale = 48.0f / pointSize; + + fileSystem->FreeFile(faceData); + faceData = NULL; + + /* + The Quake 4 atlas is the .tga beside the .fontdat: + fonts/marine_12.fontdat + fonts/marine_12.tga + + Doom 3 stores material per glyph, so assign the same atlas material + to every glyph. + */ + idStr::snPrintf(materialName, sizeof(materialName), "%s_%i.tga", fontName, pointSize); + + for (int i = 0; i < GLYPHS_PER_FONT; i++) { + outFont->glyphs[i].glyph = declManager->FindMaterial(materialName); + if (outFont->glyphs[i].glyph != NULL) { + outFont->glyphs[i].glyph->SetSort(SS_GUI); + } + idStr::Copynz(outFont->glyphs[i].shaderName, materialName, sizeof(outFont->glyphs[i].shaderName)); + } + + if (fontCount == 0) { + font.maxWidthSmall = mw; + font.maxHeightSmall = mh; + } + else if (fontCount == 1) { + font.maxWidthMedium = mw; + font.maxHeightMedium = mh; + } + else { + font.maxWidthLarge = mw; + font.maxHeightLarge = mh; + } + } + + switch (found) { + case 1: + memcpy(&font.fontInfoMedium, &font.fontInfoSmall, sizeof(font.fontInfoMedium)); + font.maxWidthMedium = font.maxWidthSmall; + font.maxHeightMedium = font.maxHeightSmall; + + memcpy(&font.fontInfoLarge, &font.fontInfoSmall, sizeof(font.fontInfoLarge)); + font.maxWidthLarge = font.maxWidthSmall; + font.maxHeightLarge = font.maxHeightSmall; + break; + + case 2: + memcpy(&font.fontInfoSmall, &font.fontInfoMedium, sizeof(font.fontInfoSmall)); + font.maxWidthSmall = font.maxWidthMedium; + font.maxHeightSmall = font.maxHeightMedium; + + memcpy(&font.fontInfoLarge, &font.fontInfoMedium, sizeof(font.fontInfoLarge)); + font.maxWidthLarge = font.maxWidthMedium; + font.maxHeightLarge = font.maxHeightMedium; + break; + + case 3: + memcpy(&font.fontInfoLarge, &font.fontInfoMedium, sizeof(font.fontInfoLarge)); + font.maxWidthLarge = font.maxWidthMedium; + font.maxHeightLarge = font.maxHeightMedium; + break; + + case 4: + memcpy(&font.fontInfoSmall, &font.fontInfoLarge, sizeof(font.fontInfoSmall)); + font.maxWidthSmall = font.maxWidthLarge; + font.maxHeightSmall = font.maxHeightLarge; + + memcpy(&font.fontInfoMedium, &font.fontInfoLarge, sizeof(font.fontInfoMedium)); + font.maxWidthMedium = font.maxWidthLarge; + font.maxHeightMedium = font.maxHeightLarge; + break; + + case 5: + memcpy(&font.fontInfoMedium, &font.fontInfoLarge, sizeof(font.fontInfoMedium)); + font.maxWidthMedium = font.maxWidthLarge; + font.maxHeightMedium = font.maxHeightLarge; + break; + + case 6: + memcpy(&font.fontInfoSmall, &font.fontInfoMedium, sizeof(font.fontInfoSmall)); + font.maxWidthSmall = font.maxWidthMedium; + font.maxHeightSmall = font.maxHeightMedium; + break; + + default: + break; + } + + return found != 0; + +#else + #ifdef BUILD_FREETYPE FT_Face face; int j, k, xOut, yOut, lastStart, imageNumber; @@ -279,27 +489,14 @@ bool idRenderSystemLocal::RegisterFont(const char* fontName, fontInfoEx_t& font) idMaterial* h; float max; #endif + void* faceData; ID_TIME_T ftime; int i, len, fontCount; char name[1024]; int pointSize = 12; - /* - if ( registeredFontCount >= MAX_FONTS ) { - common->Warning( "RegisterFont: Too many fonts registered already." ); - return false; - } - int pointSize = 12; - idStr::snPrintf( name, sizeof(name), "%s/fontImage_%i.dat", fontName, pointSize ); - for ( i = 0; i < registeredFontCount; i++ ) { - if ( idStr::Icmp(name, registeredFont[i].fontInfoSmall.name) == 0 ) { - memcpy( &font, ®isteredFont[i], sizeof( fontInfoEx_t ) ); - return true; - } - } - */ assert(sizeof(float) == 4 && "if this is false, readFloat() won't work"); memset(&font, 0, sizeof(font)); @@ -315,8 +512,8 @@ bool idRenderSystemLocal::RegisterFont(const char* fontName, fontInfoEx_t& font) else { pointSize = 48; } - // we also need to adjust the scale based on point size relative to 48 points as the ui scaling is based on a 48 point font - float glyphScale = 1.0f; // change the scale to be relative to 1 based on 72 dpi ( so dpi of 144 means a scale of .5 ) + + float glyphScale = 1.0f; glyphScale *= 48.0f / pointSize; idStr::snPrintf(name, sizeof(name), "%s/fontImage_%i.dat", fontName, pointSize); @@ -341,8 +538,10 @@ bool idRenderSystemLocal::RegisterFont(const char* fontName, fontInfoEx_t& font) } fileSystem->ReadFile(name, &faceData, &ftime); + fdOffset = 0; fdFile = reinterpret_cast(faceData); + for (i = 0; i < GLYPHS_PER_FONT; i++) { outFont->glyphs[i].height = readInt(); outFont->glyphs[i].top = readInt(); @@ -355,19 +554,24 @@ bool idRenderSystemLocal::RegisterFont(const char* fontName, fontInfoEx_t& font) outFont->glyphs[i].t = readFloat(); outFont->glyphs[i].s2 = readFloat(); outFont->glyphs[i].t2 = readFloat(); - /* font.glyphs[i].glyph = */ readInt(); - //FIXME: the +6, -6 skips the embedded fonts/ + + readInt(); + memcpy(outFont->glyphs[i].shaderName, &fdFile[fdOffset + 6], 32 - 6); fdOffset += 32; } + outFont->glyphScale = readFloat(); int mw = 0; int mh = 0; + for (i = GLYPH_START; i < GLYPH_END; i++) { idStr::snPrintf(name, sizeof(name), "%s/%s", fontName, outFont->glyphs[i].shaderName); + outFont->glyphs[i].glyph = declManager->FindMaterial(name); outFont->glyphs[i].glyph->SetSort(SS_GUI); + if (mh < outFont->glyphs[i].height) { mh = outFont->glyphs[i].height; } @@ -375,6 +579,7 @@ bool idRenderSystemLocal::RegisterFont(const char* fontName, fontInfoEx_t& font) mw = outFont->glyphs[i].xSkip; } } + if (fontCount == 0) { font.maxWidthSmall = mw; font.maxHeightSmall = mh; @@ -387,135 +592,13 @@ bool idRenderSystemLocal::RegisterFont(const char* fontName, fontInfoEx_t& font) font.maxWidthLarge = mw; font.maxHeightLarge = mh; } + fileSystem->FreeFile(faceData); } - //memcpy( ®isteredFont[registeredFontCount++], &font, sizeof( fontInfoEx_t ) ); - return true; -#ifndef BUILD_FREETYPE - common->Warning("RegisterFont: couldn't load FreeType code %s", name); -#else - - if (ftLibrary == NULL) { - common->Warning("RegisterFont: FreeType not initialized."); - return; - } - - len = fileSystem->ReadFile(fontName, &faceData, &ftime); - if (len <= 0) { - common->Warning("RegisterFont: Unable to read font file"); - return; - } - - // allocate on the stack first in case we fail - if (FT_New_Memory_Face(ftLibrary, faceData, len, 0, &face)) { - common->Warning("RegisterFont: FreeType2, unable to allocate new face."); - return; - } - - - if (FT_Set_Char_Size(face, pointSize << 6, pointSize << 6, dpi, dpi)) { - common->Warning("RegisterFont: FreeType2, Unable to set face char size."); - return; - } - - // font = registeredFonts[registeredFontCount++]; - - // make a 256x256 image buffer, once it is full, register it, clean it and keep going - // until all glyphs are rendered - - out = Mem_Alloc(1024 * 1024); - if (out == NULL) { - common->Warning("RegisterFont: Mem_Alloc failure during output image creation."); - return; - } - memset(out, 0, 1024 * 1024); - - maxHeight = 0; - - for (i = GLYPH_START; i < GLYPH_END; i++) { - glyph = RE_ConstructGlyphInfo(out, &xOut, &yOut, &maxHeight, face, (unsigned char)i, qtrue); - } - - xOut = 0; - yOut = 0; - i = GLYPH_START; - lastStart = i; - imageNumber = 0; - - while (i <= GLYPH_END) { - - glyph = RE_ConstructGlyphInfo(out, &xOut, &yOut, &maxHeight, face, (unsigned char)i, qfalse); - - if (xOut == -1 || yOut == -1 || i == GLYPH_END) { - // ran out of room - // we need to create an image from the bitmap, set all the handles in the glyphs to this point - // - - scaledSize = 256 * 256; - newSize = scaledSize * 4; - imageBuff = Mem_Alloc(newSize); - left = 0; - max = 0; - satLevels = 255; - for (k = 0; k < (scaledSize); k++) { - if (max < out[k]) { - max = out[k]; - } - } - - if (max > 0) { - max = 255 / max; - } - - for (k = 0; k < (scaledSize); k++) { - imageBuff[left++] = 255; - imageBuff[left++] = 255; - imageBuff[left++] = 255; - imageBuff[left++] = ((float)out[k] * max); - } - - idStr::snprintf(name, sizeof(name), "fonts/fontImage_%i_%i.tga", imageNumber++, pointSize); - if (r_saveFontData->integer) { - R_WriteTGA(name, imageBuff, 256, 256); - } - - //idStr::snprintf( name, sizeof(name), "fonts/fontImage_%i_%i", imageNumber++, pointSize ); - image = R_CreateImage(name, imageBuff, 256, 256, qfalse, qfalse, GL_CLAMP); - h = RE_RegisterShaderFromImage(name, LIGHTMAP_2D, image, qfalse); - for (j = lastStart; j < i; j++) { - font.glyphs[j].glyph = h; - idStr::Copynz(font.glyphs[j].shaderName, name, sizeof(font.glyphs[j].shaderName)); - } - lastStart = i; - memset(out, 0, 1024 * 1024); - xOut = 0; - yOut = 0; - Mem_Free(imageBuff); - i++; - } - else { - memcpy(&font.glyphs[i], glyph, sizeof(glyphInfo_t)); - i++; - } - } - - registeredFont[registeredFontCount].glyphScale = glyphScale; - font.glyphScale = glyphScale; - memcpy(®isteredFont[registeredFontCount++], &font, sizeof(fontInfo_t)); - - if (r_saveFontData->integer) { - common->Warning("FIXME: font saving doesnt respect alignment!"); - fileSystem->WriteFile(va("fonts/fontImage_%i.dat", pointSize), &font, sizeof(fontInfo_t)); - } - - Mem_Free(out); - - fileSystem->FreeFile(faceData); -#endif - return true; +#endif // QUAKE4 } /* diff --git a/neo/engine/sound/snd_world.cpp b/neo/engine/sound/snd_world.cpp index b357239d..a79bce56 100644 --- a/neo/engine/sound/snd_world.cpp +++ b/neo/engine/sound/snd_world.cpp @@ -1388,7 +1388,7 @@ idSoundWorldLocal::EmitterForIndex =================== */ idSoundEmitter *idSoundWorldLocal::EmitterForIndex( int index ) { - if ( index == 0 ) { + if ( index <= 0 ) { return NULL; } if ( index >= emitters.Num() ) { diff --git a/neo/engine/tools/compilers/aas/AASFile.cpp b/neo/engine/tools/compilers/aas/AASFile.cpp index c7296e7a..c6de4623 100644 --- a/neo/engine/tools/compilers/aas/AASFile.cpp +++ b/neo/engine/tools/compilers/aas/AASFile.cpp @@ -1517,6 +1517,11 @@ bool idAASFileLocal::Load( const idStr &fileName, unsigned int mapFileCRC ) { } } + if (nodes.Num() <= 0) { + src.Error("idAASFileLocal::Load: No Nodes!"); + return false; + } + FinishAreas(); depth = MaxTreeDepth(); diff --git a/neo/engine/ui/EditWindow.cpp b/neo/engine/ui/EditWindow.cpp index 52f44e0e..0a491cba 100644 --- a/neo/engine/ui/EditWindow.cpp +++ b/neo/engine/ui/EditWindow.cpp @@ -453,6 +453,16 @@ This is the same as in idListWindow */ void idEditWindow::InitScroller( bool horizontal ) { +#ifdef QUAKE4 + const char* thumbImage = "gfx/guis/scrollbar_thumb"; + const char* barImage = "gfx/guis/scrollbarv"; + const char* scrollerName = "_scrollerWinV"; + + if (horizontal) { + barImage = "gfx/guis/scrollbarh"; + scrollerName = "_scrollerWinH"; + } +#else const char *thumbImage = "guis/assets/scrollbar_thumb.tga"; const char *barImage = "guis/assets/scrollbarv.tga"; const char *scrollerName = "_scrollerWinV"; @@ -461,7 +471,7 @@ void idEditWindow::InitScroller( bool horizontal ) barImage = "guis/assets/scrollbarh.tga"; scrollerName = "_scrollerWinH"; } - +#endif const idMaterial *mat = declManager->FindMaterial( barImage ); mat->SetSort( SS_GUI ); sizeBias = mat->GetImageWidth(); diff --git a/neo/engine/ui/GuiScript.cpp b/neo/engine/ui/GuiScript.cpp index 4909afed..42805f74 100644 --- a/neo/engine/ui/GuiScript.cpp +++ b/neo/engine/ui/GuiScript.cpp @@ -1,66 +1,85 @@ /* =========================================================================== -IceTech GPL Source Code -Copyright (C) 2026 Justin Marshall +Doom 3 GPL Source Code +Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. -This file is part of the IceTech GPL Source Code ("IceTech Source Code"). +This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code"). -IceTech Source Code is free software: you can redistribute it and/or modify +Doom 3 Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -IceTech Source Code is distributed in the hope that it will be useful, +Doom 3 Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with IceTech Source Code. If not, see . - -In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below. - -If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com +along with Doom 3 Source Code. If not, see . +In addition, the Doom 3 Source Code is also subject to certain additional terms. =========================================================================== */ #include "precompiled.h" +#pragma hdrstop + #include "Window.h" #include "Winvar.h" +#include "GuiScript.h" #include "UserInterfaceLocal.h" -#include "GuiScript.h" +/* +=============================================================================== + + Script handlers + +=============================================================================== +*/ + +idCVar gui_debugScript("gui_debugScript", "0", CVAR_BOOL, ""); /* ========================= Script_Set ========================= */ -void Script_Set(idWindow *window, idList *src) { +void Script_Set(idWindow* window, idList* src) { idStr key, val; - idWinStr *dest = dynamic_cast((*src)[0].var); + + if (src->Num() < 2) { + const char* name = (src->Num() > 0 && (*src)[0].var != NULL) ? (*src)[0].var->c_str() : "unknown"; + common->Warning("Script_Set: src <%s> on window <%s> does not contain value to set to", name, window->GetName()); + return; + } + + idWinStr* dest = dynamic_cast((*src)[0].var); if (dest) { if (idStr::Icmp(*dest, "cmd") == 0) { dest = dynamic_cast((*src)[1].var); - int parmCount = src->Num(); + if (!dest) { + return; + } + + const int parmCount = src->Num(); if (parmCount > 2) { val = dest->c_str(); - int i = 2; - while (i < parmCount) { + for (int i = 2; i < parmCount; i++) { val += " \""; val += (*src)[i].var->c_str(); val += "\""; - i++; } window->AddCommand(val); - } else { + } + else { window->AddCommand(*dest); } return; } } + (*src)[0].var->Set((*src)[1].var->c_str()); (*src)[0].var->SetEval(false); } @@ -70,12 +89,22 @@ void Script_Set(idWindow *window, idList *src) { Script_SetFocus ========================= */ -void Script_SetFocus(idWindow *window, idList *src) { - idWinStr *parm = dynamic_cast((*src)[0].var); +void Script_SetFocus(idWindow* window, idList* src) { + idWinStr* parm = dynamic_cast((*src)[0].var); if (parm) { - drawWin_t *win = window->GetGui()->GetDesktop()->FindChildByName(*parm); + drawWin_t* win = window->GetGui()->GetDesktop()->FindChildByName(*parm); if (win && win->win) { window->SetFocus(win->win); + +#ifdef QUAKE4 + // Quake 4 addition: optional second parm "st" clears transitions + if (src->Num() > 1) { + idWinStr* opt = dynamic_cast((*src)[1].var); + if (opt && idStr::Icmp(*opt, "st") == 0) { + win->win->ClearTransitions(); + } + } +#endif } } } @@ -85,13 +114,14 @@ void Script_SetFocus(idWindow *window, idList *src) { Script_ShowCursor ========================= */ -void Script_ShowCursor(idWindow *window, idList *src) { - idWinStr *parm = dynamic_cast((*src)[0].var); - if ( parm ) { - if ( atoi( *parm ) ) { - window->GetGui()->GetDesktop()->ClearFlag( WIN_NOCURSOR ); - } else { - window->GetGui()->GetDesktop()->SetFlag( WIN_NOCURSOR ); +void Script_ShowCursor(idWindow* window, idList* src) { + idWinStr* parm = dynamic_cast((*src)[0].var); + if (parm) { + if (atoi(*parm)) { + window->GetGui()->GetDesktop()->ClearFlag(WIN_NOCURSOR); + } + else { + window->GetGui()->GetDesktop()->SetFlag(WIN_NOCURSOR); } } } @@ -103,8 +133,8 @@ Script_RunScript run scripts must come after any set cmd set's in the script ========================= */ -void Script_RunScript(idWindow *window, idList *src) { - idWinStr *parm = dynamic_cast((*src)[0].var); +void Script_RunScript(idWindow* window, idList* src) { + idWinStr* parm = dynamic_cast((*src)[0].var); if (parm) { idStr str = window->cmd; str += " ; runScript "; @@ -118,8 +148,8 @@ void Script_RunScript(idWindow *window, idList *src) { Script_LocalSound ========================= */ -void Script_LocalSound(idWindow *window, idList *src) { - idWinStr *parm = dynamic_cast((*src)[0].var); +void Script_LocalSound(idWindow* window, idList* src) { + idWinStr* parm = dynamic_cast((*src)[0].var); if (parm) { session->sw->PlayShaderDirectly(*parm); } @@ -130,7 +160,7 @@ void Script_LocalSound(idWindow *window, idList *src) { Script_EvalRegs ========================= */ -void Script_EvalRegs(idWindow *window, idList *src) { +void Script_EvalRegs(idWindow* window, idList* src) { window->EvalRegs(-1, true); } @@ -139,9 +169,9 @@ void Script_EvalRegs(idWindow *window, idList *src) { Script_EndGame ========================= */ -void Script_EndGame( idWindow *window, idList *src ) { - cvarSystem->SetCVarBool( "g_nightmare", true ); - cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "disconnect\n" ); +void Script_EndGame(idWindow* window, idList* src) { + cvarSystem->SetCVarBool("g_nightmare", true); + cmdSystem->BufferCommandText(CMD_EXEC_APPEND, "disconnect\n"); } /* @@ -149,17 +179,24 @@ void Script_EndGame( idWindow *window, idList *src ) { Script_ResetTime ========================= */ -void Script_ResetTime(idWindow *window, idList *src) { - idWinStr *parm = dynamic_cast((*src)[0].var); - drawWin_t *win = NULL; +void Script_ResetTime(idWindow* window, idList* src) { + idWinStr* parm = dynamic_cast((*src)[0].var); + drawWin_t* win = NULL; + if (parm && src->Num() > 1) { win = window->GetGui()->GetDesktop()->FindChildByName(*parm); parm = dynamic_cast((*src)[1].var); } + + if (!parm) { + return; + } + if (win && win->win) { win->win->ResetTime(atoi(*parm)); win->win->EvalRegs(-1, true); - } else { + } + else { window->ResetTime(atoi(*parm)); window->EvalRegs(-1, true); } @@ -170,93 +207,301 @@ void Script_ResetTime(idWindow *window, idList *src) { Script_ResetCinematics ========================= */ -void Script_ResetCinematics(idWindow *window, idList *src) { +void Script_ResetCinematics(idWindow* window, idList* src) { window->ResetCinematics(); } +#ifdef QUAKE4 +/* +========================= +Script_ResetVideo +========================= +*/ +void Script_ResetVideo(idWindow* window, idList* src) { + idWinStr* parm = dynamic_cast((*src)[0].var); + if (!parm) { + window->ResetCinematics(); + window->EvalRegs(-1, true); + return; + } + + drawWin_t* child = window->GetGui()->GetDesktop()->FindChildByName(*parm); + if (child) { + if (child->win) { + child->win->ResetCinematics(); + child->win->EvalRegs(-1, true); + return; + } + if (child->simp) { + // Doom 3 idSimpleWindow has no ResetCinematics(); only full idWindow children can reset video here. + return; + } + } + + window->ResetCinematics(); + window->EvalRegs(-1, true); +} + +/* +========================= +Script_SetLightColor +========================= +*/ +void Script_SetLightColor(idWindow* window, idList* src) { + +} + +/* +========================= +Script_NonInteractive +========================= +*/ +void Script_NonInteractive(idWindow* window, idList* src) { + // Quake 4 has idUserInterfaceLocal::SetInteractive(). Stock Doom 3 does not. + // Keep the command parseable under QUAKE4, but make it a no-op unless you add that API. + (void)window; + (void)src; +} + +/* +========================= +Script_NamedEvent +========================= +*/ +void Script_NamedEvent(idWindow* window, idList* src) { + idWinStr* parm = dynamic_cast((*src)[0].var); + if (!parm) { + return; + } + + idStr event = parm->c_str(); + int split = idStr::FindText(event.c_str(), "::", true, 0, event.Length()); + if (split <= 0) { + window->GetGui()->HandleNamedEvent(event); + return; + } + + idStr winName; + idStr winEvent; + event.Left(split, winName); + event.Right(event.Length() - split - 2, winEvent); + + drawWin_t* child = window->GetGui()->GetDesktop()->FindChildByName(winName); + if (child && child->win) { + child->win->RunNamedEvent(winEvent); + } + else if (gui_debugScript.GetBool()) { + common->Printf("GUI: %s: unknown window %s for named event %s\n", + window->GetName(), winName.c_str(), winEvent.c_str()); + } +} + +/* +========================= +Script_StopTransitions +========================= +*/ +void Script_StopTransitions(idWindow* window, idList* src) { + idWinStr* parm = dynamic_cast((*src)[0].var); + if (!parm) { + return; + } + + drawWin_t* child = window->GetGui()->GetDesktop()->FindChildByName(*parm); + if (child && child->win) { + child->win->ClearTransitions(); + } + else if (gui_debugScript.GetBool()) { + common->Printf("GUI: %s %s: unknown window for Script_StopTransitions\n", + window->GetName(), parm->c_str()); + } +} + +/* +========================= +Script_ConsoleCmd +========================= +*/ +void Script_ConsoleCmd(idWindow* window, idList* src) { + idWinStr* parm = dynamic_cast((*src)[0].var); + if (!parm) { + return; + } + + idStr val = parm->c_str(); + val += " "; + val += "\n"; + cmdSystem->BufferCommandText(CMD_EXEC_APPEND, val); +} + +#endif // QUAKE4 + /* ========================= Script_Transition ========================= */ -void Script_Transition(idWindow *window, idList *src) { - // transitions always affect rect or vec4 vars +void Script_Transition(idWindow* window, idList* src) { + // transitions always affect rect, vec4, float, or float member vars if (src->Num() >= 4) { - idWinRectangle *rect = NULL; - idWinVec4 *vec4 = dynamic_cast((*src)[0].var); - // - // added float variable + idWinRectangle* rect = NULL; + idWinVec4* vec4 = dynamic_cast((*src)[0].var); idWinFloat* val = NULL; - // +#ifdef QUAKE4 + idWinFloatMember* floatMember = NULL; +#endif + if (vec4 == NULL) { rect = dynamic_cast((*src)[0].var); - // - // added float variable - if ( NULL == rect ) { + if (rect == NULL) { val = dynamic_cast((*src)[0].var); + if (val == NULL) { +#ifdef QUAKE4 + floatMember = dynamic_cast((*src)[0].var); +#endif + } } - // } - idWinVec4 *from = dynamic_cast((*src)[1].var); - idWinVec4 *to = dynamic_cast((*src)[2].var); - idWinStr *timeStr = dynamic_cast((*src)[3].var); - // - // added float variable - if (!((vec4 || rect || val) && from && to && timeStr)) { - // - common->Warning("Bad transition in gui %s in window %s\n", window->GetGui()->GetSourceFile(), window->GetName()); - return; + + idVec4 from; + idVec4 to; + + idWinVec4* fromVec4 = dynamic_cast((*src)[1].var); + if (fromVec4) { + from = *fromVec4; } - int time = atoi(*timeStr); + else { + float f; + idWinFloat* fromFloat = dynamic_cast((*src)[1].var); +#ifdef QUAKE4 + idWinFloatMember* fromFloatMember = dynamic_cast((*src)[1].var); +#endif + if (fromFloat) { + f = (float)atof(fromFloat->c_str()); + } +#ifdef QUAKE4 + else if (fromFloatMember) { + f = (float)atof(fromFloatMember->c_str()); + } +#endif + else { + f = (float)atof((*src)[1].var->c_str()); + } + from = idVec4(f, f, f, f); + } + + idWinVec4* toVec4 = dynamic_cast((*src)[2].var); + if (toVec4) { + to = *toVec4; + } + else { + float f; + idWinFloat* toFloat = dynamic_cast((*src)[2].var); +#ifdef QUAKE4 + idWinFloatMember* toFloatMember = dynamic_cast((*src)[2].var); +#endif + if (toFloat) { + f = (float)atof(toFloat->c_str()); + } +#ifdef QUAKE4 + else if (toFloatMember) { + f = (float)atof(toFloatMember->c_str()); + } +#endif + else { + f = (float)atof((*src)[2].var->c_str()); + } + to = idVec4(f, f, f, f); + } + + int time; + idWinInt* timeInt = dynamic_cast((*src)[3].var); + if (timeInt) { + time = atoi(timeInt->c_str()); + } + else { + time = atoi((*src)[3].var->c_str()); + } + float ac = 0.0f; float dc = 0.0f; + if (src->Num() > 4) { - idWinStr *acv = dynamic_cast((*src)[4].var); - idWinStr *dcv = dynamic_cast((*src)[5].var); - assert(acv && dcv); - ac = atof(*acv); - dc = atof(*dcv); + ac = (float)atof((*src)[4].var->c_str()); + if (src->Num() > 5) { + dc = (float)atof((*src)[5].var->c_str()); + } + } + +#ifdef QUAKE4 + if (!((vec4 || rect || val || floatMember))) +#else + if (!((vec4 || rect || val))) +#endif + { + common->Warning("Bad transition in gui %s in window %s\n", + window->GetGui()->GetSourceFile(), window->GetName()); + return; } if (vec4) { vec4->SetEval(false); - window->AddTransition(vec4, *from, *to, time, ac, dc); - // - // added float variable - } else if ( val ) { - val->SetEval ( false ); - window->AddTransition(val, *from, *to, time, ac, dc); - // - } else { - rect->SetEval(false); - window->AddTransition(rect, *from, *to, time, ac, dc); + window->AddTransition(vec4, from, to, time, ac, dc); } + else if (val) { + val->SetEval(false); + window->AddTransition(val, from, to, time, ac, dc); + } +#ifdef QUAKE4 + else if (floatMember) { + floatMember->SetEval(false); + window->AddTransition(floatMember, from, to, time, ac, dc); + } +#endif + else { + rect->SetEval(false); + window->AddTransition(rect, from, to, time, ac, dc); + } + window->StartTransition(); } } typedef struct { - const char *name; - void (*handler) (idWindow *window, idList *src); + const char* name; + void (*handler)(idWindow* window, idList* src); int mMinParms; int mMaxParms; } guiCommandDef_t; guiCommandDef_t commandList[] = { - { "set", Script_Set, 2, 999 }, - { "setFocus", Script_SetFocus, 1, 1 }, - { "endGame", Script_EndGame, 0, 0 }, - { "resetTime", Script_ResetTime, 0, 2 }, - { "showCursor", Script_ShowCursor, 1, 1 }, - { "resetCinematics", Script_ResetCinematics, 0, 2 }, - { "transition", Script_Transition, 4, 6 }, - { "localSound", Script_LocalSound, 1, 1 }, - { "runScript", Script_RunScript, 1, 1 }, - { "evalRegs", Script_EvalRegs, 0, 0 } + { "set", Script_Set, 2, 999 }, + #ifdef QUAKE4 + { "setFocus", Script_SetFocus, 1, 2 }, +#else + { "setFocus", Script_SetFocus, 1, 1 }, +#endif + { "endGame", Script_EndGame, 0, 0 }, + { "resetTime", Script_ResetTime, 0, 2 }, + { "showCursor", Script_ShowCursor, 1, 1 }, + { "resetCinematics", Script_ResetCinematics, 0, 2 }, + { "transition", Script_Transition, 4, 6 }, + { "localSound", Script_LocalSound, 1, 1 }, + { "runScript", Script_RunScript, 1, 1 }, + { "evalRegs", Script_EvalRegs, 0, 0 }, + +#ifdef QUAKE4 + // Quake 4 additions + { "setLightColor", Script_SetLightColor, 1, 1 }, + { "nonInteractive", Script_NonInteractive, 0, 1 }, + { "resetVideo", Script_ResetVideo, 1, 1 }, + { "namedEvent", Script_NamedEvent, 1, 1 }, + { "stopTransitions", Script_StopTransitions, 1, 1 }, + { "consoleCmd", Script_ConsoleCmd, 1, 1 } +#endif }; -int scriptCommandCount = sizeof(commandList) / sizeof(guiCommandDef_t); - +int scriptCommandCount = sizeof(commandList) / sizeof(guiCommandDef_t); /* ========================= @@ -268,7 +513,7 @@ idGuiScript::idGuiScript() { elseList = NULL; conditionReg = -1; handler = NULL; - parms.SetGranularity( 2 ); + parms.SetGranularity(2); } /* @@ -279,9 +524,9 @@ idGuiScript::~idGuiScript idGuiScript::~idGuiScript() { delete ifList; delete elseList; - int c = parms.Num(); - for ( int i = 0; i < c; i++ ) { - if ( parms[i].own ) { + const int c = parms.Num(); + for (int i = 0; i < c; i++) { + if (parms[i].own) { delete parms[i].var; } } @@ -292,21 +537,19 @@ idGuiScript::~idGuiScript() { idGuiScript::WriteToSaveGame ========================= */ -void idGuiScript::WriteToSaveGame( idFile *savefile ) { - int i; - - if ( ifList ) { - ifList->WriteToSaveGame( savefile ); +void idGuiScript::WriteToSaveGame(idFile* savefile) { + if (ifList) { + ifList->WriteToSaveGame(savefile); } - if ( elseList ) { - elseList->WriteToSaveGame( savefile ); + if (elseList) { + elseList->WriteToSaveGame(savefile); } - savefile->Write( &conditionReg, sizeof( conditionReg ) ); + savefile->Write(&conditionReg, sizeof(conditionReg)); - for ( i = 0; i < parms.Num(); i++ ) { - if ( parms[i].own ) { - parms[i].var->WriteToSaveGame( savefile ); + for (int i = 0; i < parms.Num(); i++) { + if (parms[i].own) { + parms[i].var->WriteToSaveGame(savefile); } } } @@ -316,21 +559,19 @@ void idGuiScript::WriteToSaveGame( idFile *savefile ) { idGuiScript::ReadFromSaveGame ========================= */ -void idGuiScript::ReadFromSaveGame( idFile *savefile ) { - int i; - - if ( ifList ) { - ifList->ReadFromSaveGame( savefile ); +void idGuiScript::ReadFromSaveGame(idFile* savefile) { + if (ifList) { + ifList->ReadFromSaveGame(savefile); } - if ( elseList ) { - elseList->ReadFromSaveGame( savefile ); + if (elseList) { + elseList->ReadFromSaveGame(savefile); } - savefile->Read( &conditionReg, sizeof( conditionReg ) ); + savefile->Read(&conditionReg, sizeof(conditionReg)); - for ( i = 0; i < parms.Num(); i++ ) { - if ( parms[i].own ) { - parms[i].var->ReadFromSaveGame( savefile ); + for (int i = 0; i < parms.Num(); i++) { + if (parms[i].own) { + parms[i].var->ReadFromSaveGame(savefile); } } } @@ -340,36 +581,31 @@ void idGuiScript::ReadFromSaveGame( idFile *savefile ) { idGuiScript::Parse ========================= */ -bool idGuiScript::Parse(idParser *src) { +bool idGuiScript::Parse(idParser* src) { int i; - // first token should be function call - // then a potentially variable set of parms - // ended with a ; idToken token; - if ( !src->ReadToken(&token) ) { - src->Error( "Unexpected end of file" ); + if (!src->ReadToken(&token)) { + src->Error("Unexpected end of file"); return false; } - handler = NULL; + handler = NULL; - for ( i = 0; i < scriptCommandCount ; i++ ) { - if ( idStr::Icmp(token, commandList[i].name) == 0 ) { + for (i = 0; i < scriptCommandCount; i++) { + if (idStr::Icmp(token, commandList[i].name) == 0) { handler = commandList[i].handler; break; } } if (handler == NULL) { - src->Error("Unknown script call %s", token.c_str()); + src->Error("Uknown script call %s", token.c_str()); } - // now read parms til ; - // all parms are read as idWinStr's but will be fixed up later - // to be proper types + while (1) { - if ( !src->ReadToken(&token) ) { - src->Error( "Unexpected end of file" ); + if (!src->ReadToken(&token)) { + src->Error("Unexpected end of file"); return false; } @@ -382,20 +618,18 @@ bool idGuiScript::Parse(idParser *src) { break; } - idWinStr *str = new idWinStr(); + idWinStr* str = new idWinStr(); *str = token; + idGSWinVar wv; wv.own = true; wv.var = str; - parms.Append( wv ); + parms.Append(wv); } - // - // verify min/max params - if ( handler && (parms.Num() < commandList[i].mMinParms || parms.Num() > commandList[i].mMaxParms ) ) { - src->Error("incorrect number of parameters for script %s", commandList[i].name ); + if (handler && (parms.Num() < commandList[i].mMinParms || parms.Num() > commandList[i].mMaxParms)) { + src->Error("incorrect number of parameters for script %s", commandList[i].name); } - // return true; } @@ -405,11 +639,17 @@ bool idGuiScript::Parse(idParser *src) { idGuiScriptList::Execute ========================= */ -void idGuiScriptList::Execute(idWindow *win) { - int c = list.Num(); +void idGuiScriptList::Execute(idWindow* win) { + const int c = list.Num(); + + if (gui_debugScript.GetBool()) { + common->Printf("GUI: %s: commands:\n", win->GetName()); + } + for (int i = 0; i < c; i++) { - idGuiScript *gs = list[i]; + idGuiScript* gs = list[i]; assert(gs); + if (gs->conditionReg >= 0) { if (win->HasOps()) { float f = win->EvalRegs(gs->conditionReg); @@ -417,160 +657,252 @@ void idGuiScriptList::Execute(idWindow *win) { if (gs->ifList) { win->RunScriptList(gs->ifList); } - } else if (gs->elseList) { + } + else if (gs->elseList) { win->RunScriptList(gs->elseList); } } } + gs->Execute(win); } } /* ========================= -idGuiScriptList::FixupParms +idGuiScript::FixupParms ========================= */ -void idGuiScript::FixupParms(idWindow *win) { +void idGuiScript::FixupParms(idWindow* win) { if (handler == &Script_Set) { bool precacheBackground = false; bool precacheSounds = false; - idWinStr *str = dynamic_cast(parms[0].var); + + idWinStr* str = dynamic_cast(parms[0].var); assert(str); - idWinVar *dest = win->GetWinVarByName(*str, true); + + idWinVar* dest = win->GetWinVarByName(*str, true); if (dest) { delete parms[0].var; parms[0].var = dest; parms[0].own = false; - if ( dynamic_cast(dest) != NULL ) { + if (dynamic_cast(dest) != NULL) { precacheBackground = true; } - } else if ( idStr::Icmp( str->c_str(), "cmd" ) == 0 ) { + } + else if (idStr::Icmp(str->c_str(), "cmd") == 0) { precacheSounds = true; } - int parmCount = parms.Num(); - for (int i = 1; i < parmCount; i++) { - idWinStr *str = dynamic_cast(parms[i].var); - if (idStr::Icmpn(*str, "gui::", 5) == 0) { - // always use a string here, no point using a float if it is one - // FIXME: This creates duplicate variables, while not technically a problem since they - // are all bound to the same guiDict, it does consume extra memory and is generally a bad thing + const int parmCount = parms.Num(); + for (int i = 1; i < parmCount; i++) { + idWinStr* str = dynamic_cast(parms[i].var); + if (!str) { + continue; + } + + if (idStr::Icmpn(str->c_str(), "gui::", 5) == 0 || idStr::Icmpn(str->c_str(), "$gui::", 6) == 0) { + const char* varName = str->c_str(); + if (varName[0] == '$') { + varName++; + } + idWinStr* defvar = new idWinStr(); - defvar->Init ( *str, win ); - win->AddDefinedVar ( defvar ); + defvar->Init(varName, win); + win->AddDefinedVar(defvar); + delete parms[i].var; parms[i].var = defvar; parms[i].own = false; - - //dest = win->GetWinVarByName(*str, true); - //if (dest) { - // delete parms[i].var; - // parms[i].var = dest; - // parms[i].own = false; - //} - // - } else if ((*str[0]) == '$') { - // - // dont include the $ when asking for variable + } + else if ((*str)[0] == '$') { dest = win->GetGui()->GetDesktop()->GetWinVarByName((const char*)(*str) + 1, true); - // if (dest) { delete parms[i].var; parms[i].var = dest; parms[i].own = false; } - } else if ( idStr::Cmpn( str->c_str(), STRTABLE_ID, STRTABLE_ID_LENGTH ) == 0 ) { - str->Set( common->GetLanguageDict()->GetString( str->c_str() ) ); - } else if ( precacheBackground ) { - const idMaterial *mat = declManager->FindMaterial( str->c_str() ); - mat->SetSort( SS_GUI ); - } else if ( precacheSounds ) { - // Search for "play <...>" + } + else if (idStr::Cmpn(str->c_str(), STRTABLE_ID, STRTABLE_ID_LENGTH) == 0) { + str->Set(common->GetLanguageDict()->GetString(str->c_str())); + } + else if (precacheBackground) { + const idMaterial* mat = declManager->FindMaterial(str->c_str()); + mat->SetSort(SS_GUI); + } + else if (precacheSounds) { idToken token; - idParser parser( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); + idParser parser(LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT); parser.LoadMemory(str->c_str(), str->Length(), "command"); - while ( parser.ReadToken(&token) ) { - if ( token.Icmp("play") == 0 ) { - if ( parser.ReadToken(&token) && ( token != "" ) ) { - declManager->FindSound( token.c_str() ); + while (parser.ReadToken(&token)) { +#ifdef QUAKE4 + if (token.Icmp("play") == 0 || token.Icmp("music") == 0) +#else + if (token.Icmp("play") == 0) +#endif + { + if (parser.ReadToken(&token) && (token != "")) { + declManager->FindSound(token.c_str()); } } } } } - } else if (handler == &Script_Transition) { + } + else if (handler == &Script_Transition) { if (parms.Num() < 4) { - common->Warning("Window %s in gui %s has a bad transition definition", win->GetName(), win->GetGui()->GetSourceFile()); + common->Warning("Window %s in gui %s has a bad transition definition", + win->GetName(), win->GetGui()->GetSourceFile()); + handler = NULL; + return; } - idWinStr *str = dynamic_cast(parms[0].var); + + idWinStr* str = dynamic_cast(parms[0].var); assert(str); - // - drawWin_t *destowner; - idWinVar *dest = win->GetWinVarByName(*str, true, &destowner ); - // + drawWin_t* destowner = NULL; + idWinVar* dest = win->GetWinVarByName(*str, true, &destowner); + const bool validDest = + (dynamic_cast(dest) != NULL) || + (dynamic_cast(dest) != NULL) || + (dynamic_cast(dest) != NULL) +#ifdef QUAKE4 + || (dynamic_cast(dest) != NULL) +#endif + ; + + if (!validDest) { + common->Warning("Window %s in gui %s: a transition does not have a valid destination var %s", + win->GetName(), win->GetGui()->GetSourceFile(), str->c_str()); + handler = NULL; + return; + } + + delete parms[0].var; + parms[0].var = dest; + parms[0].own = false; + + for (int c = 1; c < 3; c++) { + idWinStr* str = dynamic_cast(parms[c].var); + assert(str); + + if ((*str)[0] == '$') { + drawWin_t* owner = NULL; + idWinVar* parmVar = win->GetWinVarByName((const char*)(*str) + 1, true, &owner); + + const bool ok = + (dynamic_cast(dest) != NULL && dynamic_cast(parmVar) != NULL) || +#ifdef QUAKE4 + (dynamic_cast(dest) != NULL && + (dynamic_cast(parmVar) != NULL || dynamic_cast(parmVar) != NULL)) || + (dynamic_cast(dest) != NULL && + (dynamic_cast(parmVar) != NULL || dynamic_cast(parmVar) != NULL)) || +#else + (dynamic_cast(dest) != NULL && dynamic_cast(parmVar) != NULL) || +#endif + (dynamic_cast(dest) != NULL && + (dynamic_cast(parmVar) != NULL || dynamic_cast(parmVar) != NULL)); + + if (!ok) { + common->Warning("Window %s in gui %s: transition has an invalid parameter %d (%s)", + win->GetName(), win->GetGui()->GetSourceFile(), c, str->c_str()); + handler = NULL; + return; + } + + if (dynamic_cast(dest) != NULL && + dynamic_cast(parmVar) != NULL) { + idWinVec4* v4 = new idWinVec4; + parms[c].var = v4; + parms[c].own = true; + + idWindow* ownerparent = owner ? (owner->simp ? owner->simp->GetParent() : owner->win->GetParent()) : NULL; + idWindow* destparent = destowner ? (destowner->simp ? destowner->simp->GetParent() : destowner->win->GetParent()) : NULL; + + if (ownerparent && destparent) { + idRectangle rect = *(dynamic_cast(parmVar)); + ownerparent->ClientToScreen(&rect); + destparent->ScreenToClient(&rect); + *v4 = rect.ToVec4(); + } + else { + v4->Set(parmVar->c_str()); + } + + delete str; + } + else { + delete parms[c].var; + parms[c].var = parmVar; + parms[c].own = false; + } + } + else { + idStr strValue = str->c_str(); + idWinVar* newVar = NULL; + + if (dynamic_cast(dest) != NULL || dynamic_cast(dest) != NULL) { + newVar = new idWinVec4; + } + else { + newVar = new idWinFloat; + } + + delete parms[c].var; + parms[c].var = newVar; + parms[c].own = true; + newVar->Set(strValue.c_str()); + } + } + + { + idWinStr* timeStr = dynamic_cast(parms[3].var); + if (timeStr) { + idWinInt* timeVar = new idWinInt; + timeVar->Set(timeStr->c_str()); + delete parms[3].var; + parms[3].var = timeVar; + parms[3].own = true; + } + } + + for (int i = 4; i < parms.Num() && i < 6; i++) { + idWinStr* fltStr = dynamic_cast(parms[i].var); + if (fltStr) { + idWinFloat* flt = new idWinFloat; + flt->Set(fltStr->c_str()); + delete parms[i].var; + parms[i].var = flt; + parms[i].own = true; + } + } + } +#ifdef QUAKE4 + else if (handler == &Script_SetLightColor) { + idWinStr* str = dynamic_cast(parms[0].var); + if (!str) { + handler = NULL; + return; + } + + idWinVar* dest = win->GetWinVarByName(*str, true); if (dest) { delete parms[0].var; parms[0].var = dest; parms[0].own = false; - } else { - common->Warning("Window %s in gui %s: a transition does not have a valid destination var %s", win->GetName(), win->GetGui()->GetSourceFile(),str->c_str()); } - - // - // support variables as parameters - int c; - for ( c = 1; c < 3; c ++ ) { - str = dynamic_cast(parms[c].var); - - idWinVec4 *v4 = new idWinVec4; - parms[c].var = v4; - parms[c].own = true; - - drawWin_t* owner; - - if ( (*str[0]) == '$' ) { - dest = win->GetWinVarByName ( (const char*)(*str) + 1, true, &owner ); - } else { - dest = NULL; - } - - if ( dest ) { - idWindow* ownerparent; - idWindow* destparent; - if ( owner ) { - ownerparent = owner->simp?owner->simp->GetParent():owner->win->GetParent(); - destparent = destowner->simp?destowner->simp->GetParent():destowner->win->GetParent(); - - // If its the rectangle they are referencing then adjust it - if ( ownerparent && destparent && - (dest == (owner->simp?owner->simp->GetWinVarByName ( "rect" ):owner->win->GetWinVarByName ( "rect" ) ) ) ) - { - idRectangle rect; - rect = *(dynamic_cast(dest)); - ownerparent->ClientToScreen ( &rect ); - destparent->ScreenToClient ( &rect ); - *v4 = rect.ToVec4 ( ); - } else { - v4->Set ( dest->c_str ( ) ); - } - } else { - v4->Set ( dest->c_str ( ) ); - } - } else { - v4->Set(*str); - } - - delete str; + else { + common->Warning("Window %s in gui %s: setLightColor command does not specify a valid var %s", + win->GetName(), win->GetGui()->GetSourceFile(), str->c_str()); + handler = NULL; } - // - - } else { - int c = parms.Num(); + } +#endif + else { + const int c = parms.Num(); for (int i = 0; i < c; i++) { parms[i].var->Init(parms[i].var->c_str(), win); } @@ -582,10 +914,10 @@ void idGuiScript::FixupParms(idWindow *win) { idGuiScriptList::FixupParms ========================= */ -void idGuiScriptList::FixupParms(idWindow *win) { - int c = list.Num(); +void idGuiScriptList::FixupParms(idWindow* win) { + const int c = list.Num(); for (int i = 0; i < c; i++) { - idGuiScript *gs = list[i]; + idGuiScript* gs = list[i]; gs->FixupParms(win); if (gs->ifList) { gs->ifList->FixupParms(win); @@ -601,11 +933,9 @@ void idGuiScriptList::FixupParms(idWindow *win) { idGuiScriptList::WriteToSaveGame ========================= */ -void idGuiScriptList::WriteToSaveGame( idFile *savefile ) { - int i; - - for ( i = 0; i < list.Num(); i++ ) { - list[i]->WriteToSaveGame( savefile ); +void idGuiScriptList::WriteToSaveGame(idFile* savefile) { + for (int i = 0; i < list.Num(); i++) { + list[i]->WriteToSaveGame(savefile); } } @@ -614,10 +944,8 @@ void idGuiScriptList::WriteToSaveGame( idFile *savefile ) { idGuiScriptList::ReadFromSaveGame ========================= */ -void idGuiScriptList::ReadFromSaveGame( idFile *savefile ) { - int i; - - for ( i = 0; i < list.Num(); i++ ) { - list[i]->ReadFromSaveGame( savefile ); +void idGuiScriptList::ReadFromSaveGame(idFile* savefile) { + for (int i = 0; i < list.Num(); i++) { + list[i]->ReadFromSaveGame(savefile); } -} +} \ No newline at end of file diff --git a/neo/engine/ui/GuiScript.h b/neo/engine/ui/GuiScript.h index fdc112bd..40a8158c 100644 --- a/neo/engine/ui/GuiScript.h +++ b/neo/engine/ui/GuiScript.h @@ -1,28 +1,25 @@ /* =========================================================================== -IceTech GPL Source Code -Copyright (C) 2026 Justin Marshall +Doom 3 GPL Source Code +Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. -This file is part of the IceTech GPL Source Code (?IceTech Source Code?). +This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code"). -IceTech Source Code is free software: you can redistribute it and/or modify +Doom 3 Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -IceTech Source Code is distributed in the hope that it will be useful, +Doom 3 Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with IceTech Source Code. If not, see . - -In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below. - -If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com +along with Doom 3 Source Code. If not, see . +In addition, the Doom 3 Source Code is also subject to certain additional terms. =========================================================================== */ #ifndef __GUISCRIPT_H @@ -50,56 +47,59 @@ public: idGuiScript(); ~idGuiScript(); - bool Parse(idParser *src); - void Execute(idWindow *win) { + bool Parse(idParser* src); + void Execute(idWindow* win) { if (handler) { handler(win, &parms); } } - void FixupParms(idWindow *win); + void FixupParms(idWindow* win); + size_t Size() { - int sz = sizeof(*this); + size_t sz = sizeof(*this); for (int i = 0; i < parms.Num(); i++) { sz += parms[i].var->Size(); } return sz; } - void WriteToSaveGame( idFile *savefile ); - void ReadFromSaveGame( idFile *savefile ); + void WriteToSaveGame(idFile* savefile); + void ReadFromSaveGame(idFile* savefile); protected: int conditionReg; - idGuiScriptList *ifList; - idGuiScriptList *elseList; + idGuiScriptList* ifList; + idGuiScriptList* elseList; idList parms; - void (*handler) (idWindow *window, idList *src); - + void (*handler)(idWindow* window, idList* src); }; - class idGuiScriptList { idList list; + public: - idGuiScriptList() { list.SetGranularity( 4 ); }; - ~idGuiScriptList() { list.DeleteContents(true); }; - void Execute(idWindow *win); + idGuiScriptList() { list.SetGranularity(4); } + ~idGuiScriptList() { list.DeleteContents(true); } + + void Execute(idWindow* win); void Append(idGuiScript* gs) { list.Append(gs); } + size_t Size() { - int sz = sizeof(*this); + size_t sz = sizeof(*this); for (int i = 0; i < list.Num(); i++) { sz += list[i]->Size(); } return sz; } - void FixupParms(idWindow *win); - void ReadFromDemoFile( class idDemoFile *f ) {}; - void WriteToDemoFile( class idDemoFile *f ) {}; - void WriteToSaveGame( idFile *savefile ); - void ReadFromSaveGame( idFile *savefile ); + void FixupParms(idWindow* win); + void ReadFromDemoFile(class idDemoFile* f) {} + void WriteToDemoFile(class idDemoFile* f) {} + + void WriteToSaveGame(idFile* savefile); + void ReadFromSaveGame(idFile* savefile); }; -#endif // __GUISCRIPT_H +#endif // __GUISCRIPT_H \ No newline at end of file diff --git a/neo/engine/ui/Window.cpp b/neo/engine/ui/Window.cpp index f655ca00..af6378db 100644 --- a/neo/engine/ui/Window.cpp +++ b/neo/engine/ui/Window.cpp @@ -1,27 +1,27 @@ /* =========================================================================== -IceTech GPL Source Code -Copyright (C) 2026 Justin Marshall +Doom 3 GPL Source Code +Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. -This file is part of the IceTech GPL Source Code ("IceTech Source Code"). +This file is part of the Quake4Doom source code by Justin Marshall. -IceTech Source Code is free software: you can redistribute it and/or modify +Doom 3 Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -IceTech Source Code is distributed in the hope that it will be useful, +Doom 3 Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with IceTech Source Code. If not, see . +along with Doom 3 Source Code. If not, see . -In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below. +In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. -If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com +If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ @@ -48,11 +48,10 @@ bool idWindow::registerIsTemporary[MAX_EXPRESSION_REGISTERS]; // statics to ass //float idWindow::shaderRegisters[MAX_EXPRESSION_REGISTERS]; //wexpOp_t idWindow::shaderOps[MAX_EXPRESSION_OPS]; -idCVar idWindow::gui_debug( "gui_debug", "0", CVAR_GUI | CVAR_BOOL, "" ); -idCVar idWindow::gui_edit( "gui_edit", "0", CVAR_GUI | CVAR_BOOL, "" ); +idCVar idWindow::gui_debug("gui_debug", "0", CVAR_GUI | CVAR_BOOL, ""); +idCVar idWindow::gui_edit("gui_edit", "0", CVAR_GUI | CVAR_BOOL, ""); extern idCVar r_skipGuiShaders; // 1 = don't render any gui elements on surfaces -extern idCVar r_scaleMenusTo43; // made RegisterVars a member of idWindow const idRegEntry idWindow::RegisterVars[] = { @@ -86,7 +85,40 @@ const idRegEntry idWindow::RegisterVars[] = { const int idWindow::NumRegisterVars = sizeof(RegisterVars) / sizeof(idRegEntry); -const char *idWindow::ScriptNames[] = { +#ifdef QUAKE4 +const char* idWindow::ScriptNames[] = { + "onMouseEnter", + "onMouseExit", + "onAction", + "onBackAction", + "onActivate", + "onDeactivate", + "onESC", + "onEvent", + "onTrigger", + "onActionRelease", + "onEnter", + "onEnterRelease", + "onTabRelease", + "onGainFocus", + "onLoseFocus", + "onSelChange", + "onInit", + "onJoyStart", + "onJoySelect", + "onJoyBack", + "onJoyLShoulder", + "onJoyRShoulder", + "onJoyUp", + "onJoyDown", + "onJoyLeft", + "onJoyRight", + "onJoyButton1", + "onJoyButton2" +}; + +#else +const char* idWindow::ScriptNames[] = { "onMouseEnter", "onMouseExit", "onAction", @@ -99,7 +131,7 @@ const char *idWindow::ScriptNames[] = { "onEnter", "onEnterRelease" }; - +#endif /* ================ idWindow::CommonInit @@ -112,20 +144,27 @@ void idWindow::CommonInit() { origin.Zero(); fontNum = 0; timeLine = -1; - xOffset = yOffset = 0.0; + xOffset = yOffset = 0.0f; cursor = 0; - forceAspectWidth = SCREEN_WIDTH; - forceAspectHeight = SCREEN_HEIGHT; - matScalex = 1; - matScaley = 1; - borderSize = 0; + forceAspectWidth = 640.0f; + forceAspectHeight = 480.0f; + matScalex = 1.0f; + matScaley = 1.0f; + borderSize = 0.0f; noTime = false; visible = true; textAlign = 0; - textAlignx = 0; - textAligny = 0; + textAlignx = 0.0f; + textAligny = 0.0f; + textShadow = 0; +#ifdef QUAKE4 +#ifdef QUAKE4 + textStyle = 0; + textSpacing = 0.0f; +#endif +#endif noEvents = false; - rotate = 0; + rotate = 0.0f; shear.Zero(); textScale = 0.35f; backColor.Zero(); @@ -135,23 +174,26 @@ void idWindow::CommonInit() { borderColor.Zero(); background = NULL; backGroundName = ""; + text = ""; focusedChild = NULL; captureChild = NULL; overChild = NULL; parent = NULL; +#ifdef QUAKE4 + startChildSearch = 0; + currentChild = NULL; +#endif saveOps = NULL; saveRegs = NULL; - timeLine = -1; - textShadow = 0; hover = false; + hideCursor = false; for (int i = 0; i < SCRIPT_COUNT; i++) { scripts[i] = NULL; } - - hideCursor = false; } + /* ================ idWindow::Size @@ -213,7 +255,7 @@ size_t idWindow::Allocated() { idWindow::idWindow ================ */ -idWindow::idWindow(idUserInterfaceLocal *ui) { +idWindow::idWindow(idUserInterfaceLocal* ui) { dc = NULL; gui = ui; CommonInit(); @@ -224,7 +266,7 @@ idWindow::idWindow(idUserInterfaceLocal *ui) { idWindow::idWindow ================ */ -idWindow::idWindow(idDeviceContext *d, idUserInterfaceLocal *ui) { +idWindow::idWindow(idDeviceContext* d, idUserInterfaceLocal* ui) { dc = d; gui = ui; CommonInit(); @@ -236,32 +278,32 @@ idWindow::CleanUp ================ */ void idWindow::CleanUp() { - int i, c = drawWindows.Num(); - for (i = 0; i < c; i++) { + for (int i = 0; i < drawWindows.Num(); i++) { delete drawWindows[i].simp; } - // ensure the register list gets cleaned up - regList.Reset ( ); - - // Cleanup the named events + regList.Reset(); namedEvents.DeleteContents(true); - // Cleanup the operations and update vars - // (if it is not fixed, orphane register references are possible) - ops.Clear(); - updateVars.Clear(); - drawWindows.Clear(); children.DeleteContents(true); definedVars.DeleteContents(true); + updateVars.Clear(); timeLineEvents.DeleteContents(true); - for (i = 0; i < SCRIPT_COUNT; i++) { + transitions.Clear(); +#ifdef QUAKE4 + transitionSubs.Clear(); +#endif + ops.Clear(); + expressionRegisters.Clear(); + for (int i = 0; i < SCRIPT_COUNT; i++) { delete scripts[i]; + scripts[i] = NULL; } CommonInit(); } + /* ================ idWindow::~idWindow @@ -280,7 +322,7 @@ void idWindow::Move(float x, float y) { idRectangle rct = rect; rct.x = x; rct.y = y; - idRegister *reg = RegList()->FindReg("rect"); + idRegister* reg = RegList()->FindReg("rect"); if (reg) { reg->Enable(false); } @@ -321,11 +363,12 @@ float idWindow::GetMaxCharWidth() { idWindow::Draw ================ */ -void idWindow::Draw( int time, float x, float y ) { - if ( text.Length() == 0 ) { +void idWindow::Draw(int time, float x, float y) { + if (text.Length() == 0) { return; } - if ( textShadow ) { + + if (textShadow) { idStr shadowText = text; idRectangle shadowRect = textRect; @@ -333,25 +376,29 @@ void idWindow::Draw( int time, float x, float y ) { shadowRect.x += textShadow; shadowRect.y += textShadow; - dc->DrawText( shadowText, textScale, textAlign, colorBlack, shadowRect, !( flags & WIN_NOWRAP ), -1 ); - } - dc->DrawText( text, textScale, textAlign, foreColor, textRect, !( flags & WIN_NOWRAP ), -1 ); - - if ( gui_edit.GetBool() ) { - dc->EnableClipping( false ); - dc->DrawText( va( "x: %i y: %i", ( int )rect.x(), ( int )rect.y() ), 0.25, 0, dc->colorWhite, idRectangle( rect.x(), rect.y() - 15, 100, 20 ), false ); - dc->DrawText( va( "w: %i h: %i", ( int )rect.w(), ( int )rect.h() ), 0.25, 0, dc->colorWhite, idRectangle( rect.x() + rect.w(), rect.w() + rect.h() + 5, 100, 20 ), false ); - dc->EnableClipping( true ); + dc->DrawText(shadowText, textScale, textAlign, colorBlack, shadowRect, !(flags & WIN_NOWRAP), -1); } + // Quake 4 extends idDeviceContext with textStyle / textSpacing aware drawing. + // The stock Doom 3 API does not expose that overload, so we preserve the parsed + // state and fall back to classic DrawText here unless the renderer is extended. + dc->DrawText(text, textScale, textAlign, foreColor, textRect, !(flags & WIN_NOWRAP), -1); + + if (gui_edit.GetBool()) { + dc->EnableClipping(false); + dc->DrawText(va("x: %i y: %i", (int)rect.x(), (int)rect.y()), 0.25f, 0, dc->colorWhite, idRectangle(rect.x(), rect.y() - 15, 100, 20), false); + dc->DrawText(va("w: %i h: %i", (int)rect.w(), (int)rect.h()), 0.25f, 0, dc->colorWhite, idRectangle(rect.x() + rect.w(), rect.w() + rect.h() + 5, 100, 20), false); + dc->EnableClipping(true); + } } + /* ================ idWindow::BringToTop ================ */ -void idWindow::BringToTop(idWindow *w) { +void idWindow::BringToTop(idWindow* w) { if (w && !(w->flags & WIN_MODAL)) { return; @@ -361,10 +408,10 @@ void idWindow::BringToTop(idWindow *w) { for (int i = 0; i < c; i++) { if (children[i] == w) { // this is it move from i - 1 to 0 to i to 1 then shove this one into 0 - for (int j = i+1; j < c; j++) { - children[j-1] = children[j]; + for (int j = i + 1; j < c; j++) { + children[j - 1] = children[j]; } - children[c-1] = w; + children[c - 1] = w; break; } } @@ -382,7 +429,7 @@ void idWindow::Size(float x, float y, float w, float h) { rct.w = w; rct.h = h; rect = rct; - CalcClientRect(0,0); + CalcClientRect(0, 0); } /* @@ -419,7 +466,7 @@ void idWindow::MouseExit() { idWindow::RouteMouseCoords ================ */ -const char *idWindow::RouteMouseCoords(float xd, float yd) { +const char* idWindow::RouteMouseCoords(float xd, float yd) { idStr str; if (GetCaptureChild()) { //FIXME: unkludge this whole mechanism @@ -432,7 +479,7 @@ const char *idWindow::RouteMouseCoords(float xd, float yd) { int c = children.Num(); while (c > 0) { - idWindow *child = children[--c]; + idWindow* child = children[--c]; if (child->visible && !child->noEvents && child->Contains(child->drawRect, gui->CursorX(), gui->CursorY())) { dc->SetCursor(child->cursor); @@ -454,7 +501,8 @@ const char *idWindow::RouteMouseCoords(float xd, float yd) { gui->GetDesktop()->AddCommand(str); overChild->cmd = ""; } - } else { + } + else { if (!(child->flags & WIN_HOLDCAPTURE)) { child->RouteMouseCoords(xd, yd); } @@ -479,20 +527,20 @@ const char *idWindow::RouteMouseCoords(float xd, float yd) { idWindow::Activate ================ */ -void idWindow::Activate( bool activate, idStr &act ) { +void idWindow::Activate(bool activate, idStr& act) { int n = (activate) ? ON_ACTIVATE : ON_DEACTIVATE; // make sure win vars are updated before activation - UpdateWinVars ( ); + UpdateWinVars(); RunScript(n); int c = children.Num(); for (int i = 0; i < c; i++) { - children[i]->Activate( activate, act ); + children[i]->Activate(activate, act); } - if ( act.Length() ) { + if (act.Length()) { act += " ; "; } } @@ -503,12 +551,12 @@ idWindow::Trigger ================ */ void idWindow::Trigger() { - RunScript( ON_TRIGGER ); + RunScript(ON_TRIGGER); int c = children.Num(); - for ( int i = 0; i < c; i++ ) { + for (int i = 0; i < c; i++) { children[i]->Trigger(); } - StateChanged( true ); + StateChanged(true); } /* @@ -516,7 +564,7 @@ void idWindow::Trigger() { idWindow::StateChanged ================ */ -void idWindow::StateChanged( bool redraw ) { +void idWindow::StateChanged(bool redraw) { UpdateWinVars(); @@ -525,20 +573,21 @@ void idWindow::StateChanged( bool redraw ) { } int c = drawWindows.Num(); - for ( int i = 0; i < c; i++ ) { - if ( drawWindows[i].win ) { - drawWindows[i].win->StateChanged( redraw ); - } else { - drawWindows[i].simp->StateChanged( redraw ); + for (int i = 0; i < c; i++) { + if (drawWindows[i].win) { + drawWindows[i].win->StateChanged(redraw); + } + else { + drawWindows[i].simp->StateChanged(redraw); } } - if ( redraw ) { - if ( flags & WIN_DESKTOP ) { - Redraw( 0.0f, 0.0f ); + if (redraw) { + if (flags & WIN_DESKTOP) { + Redraw(0.0f, 0.0f); } - if ( background && background->CinematicLength() ) { - background->UpdateCinematic( gui->GetTime() ); + if (background && background->CinematicLength()) { + background->UpdateCinematic(gui->GetTime()); } } } @@ -548,32 +597,31 @@ void idWindow::StateChanged( bool redraw ) { idWindow::SetCapture ================ */ -idWindow *idWindow::SetCapture(idWindow *w) { - // only one child can have the focus - - idWindow *last = NULL; - int c = children.Num(); - for (int i = 0; i < c; i++) { - if ( children[i]->flags & WIN_CAPTURE ) { +idWindow* idWindow::SetCapture(idWindow* w) { + idWindow* last = NULL; + for (int i = 0; i < children.Num(); i++) { + if (children[i]->flags & WIN_CAPTURE) { last = children[i]; - //last->flags &= ~WIN_CAPTURE; last->LoseCapture(); break; } } - w->flags |= WIN_CAPTURE; - w->GainCapture(); + if (w) { + w->flags |= WIN_CAPTURE; + w->GainCapture(); + } gui->GetDesktop()->captureChild = w; return last; } + /* ================ idWindow::AddUpdateVar ================ */ -void idWindow::AddUpdateVar(idWinVar *var) { +void idWindow::AddUpdateVar(idWinVar* var) { updateVars.AddUnique(var); } @@ -595,9 +643,14 @@ idWindow::RunTimeEvents ================ */ bool idWindow::RunTimeEvents(int time) { - - if ( time - lastTimeRun < USERCMD_MSEC ) { - //common->Printf("Skipping gui time events at %i\n", time); + if (lastTimeRun > time) { + lastTimeRun = time; + } + #ifdef QUAKE4 + if (!(flags & WIN_ALWAYSTHINK) && time - lastTimeRun < USERCMD_MSEC) { +#else + if (time - lastTimeRun < USERCMD_MSEC) { +#endif return false; } @@ -609,37 +662,35 @@ bool idWindow::RunTimeEvents(int time) { EvalRegs(); } - if ( flags & WIN_INTRANSITION ) { + if (flags & WIN_INTRANSITION) { Transition(); } Time(); - - // renamed ON_EVENT to ON_FRAME RunScript(ON_FRAME); - int c = children.Num(); - for (int i = 0; i < c; i++) { + for (int i = 0; i < children.Num(); i++) { children[i]->RunTimeEvents(time); } return true; } + /* ================ idWindow::RunNamedEvent ================ */ -void idWindow::RunNamedEvent ( const char* eventName ) +void idWindow::RunNamedEvent(const char* eventName) { int i; int c; - // Find and run the event - c = namedEvents.Num( ); - for ( i = 0; i < c; i ++ ) { - if ( namedEvents[i]->mName.Icmp( eventName ) ) { + // Find and run the event + c = namedEvents.Num(); + for (i = 0; i < c; i++) { + if (namedEvents[i]->mName.Icmp(eventName)) { continue; } @@ -650,15 +701,15 @@ void idWindow::RunNamedEvent ( const char* eventName ) EvalRegs(-1, true); } - RunScriptList( namedEvents[i]->mEvent ); + RunScriptList(namedEvents[i]->mEvent); break; } // Run the event in all the children as well c = children.Num(); - for ( i = 0; i < c; i++ ) { - children[i]->RunNamedEvent ( eventName ); + for (i = 0; i < c; i++) { + children[i]->RunNamedEvent(eventName); } } @@ -667,7 +718,7 @@ void idWindow::RunNamedEvent ( const char* eventName ) idWindow::Contains ================ */ -bool idWindow::Contains(const idRectangle &sr, float x, float y) { +bool idWindow::Contains(const idRectangle& sr, float x, float y) { idRectangle r = sr; r.x += actualX - drawRect.x; r.y += actualY - drawRect.y; @@ -691,12 +742,13 @@ bool idWindow::Contains(float x, float y) { idWindow::AddCommand ================ */ -void idWindow::AddCommand(const char *_cmd) { +void idWindow::AddCommand(const char* _cmd) { idStr str = cmd; if (str.Length()) { str += " ; "; str += _cmd; - } else { + } + else { str = _cmd; } cmd = str; @@ -707,21 +759,21 @@ void idWindow::AddCommand(const char *_cmd) { idWindow::HandleEvent ================ */ -const char *idWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) { +const char* idWindow::HandleEvent(const sysEvent_t* event, bool* updateVisuals) { static bool actionDownRun; static bool actionUpRun; cmd = ""; - if ( flags & WIN_DESKTOP ) { + if (flags & WIN_DESKTOP) { actionDownRun = false; actionUpRun = false; if (expressionRegisters.Num() && ops.Num()) { EvalRegs(); } RunTimeEvents(gui->GetTime()); - CalcRects(0,0); - dc->SetCursor( idDeviceContext::CURSOR_ARROW ); + CalcRects(0, 0); + dc->SetCursor(idDeviceContext::CURSOR_ARROW); } if (visible && !noEvents) { @@ -743,7 +795,7 @@ const char *idWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) int c = children.Num(); while (--c >= 0) { if (children[c]->visible && children[c]->Contains(children[c]->drawRect, gui->CursorX(), gui->CursorY()) && !(children[c]->noEvents)) { - idWindow *child = children[c]; + idWindow* child = children[c]; if (event->evValue2) { BringToTop(child); SetFocus(child); @@ -756,14 +808,15 @@ const char *idWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) // SetCapture(child); //} SetFocus(child); - const char *childRet = child->HandleEvent(event, updateVisuals); + const char* childRet = child->HandleEvent(event, updateVisuals); if (childRet && *childRet) { return childRet; } if (child->flags & WIN_MODAL) { return ""; } - } else { + } + else { if (event->evValue2) { SetFocus(child); bool capture = true; @@ -771,17 +824,20 @@ const char *idWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) SetCapture(child); } return ""; - } else { + } + else { } } } } if (event->evValue2 && !actionDownRun) { - actionDownRun = RunScript( ON_ACTION ); - } else if (!actionUpRun) { - actionUpRun = RunScript( ON_ACTIONRELEASE ); + actionDownRun = RunScript(ON_ACTION); } - } else if (event->evValue == K_MOUSE2) { + else if (!actionUpRun) { + actionUpRun = RunScript(ON_ACTIONRELEASE); + } + } + else if (event->evValue == K_MOUSE2) { if (!event->evValue2 && GetCaptureChild()) { GetCaptureChild()->LoseCapture(); @@ -792,16 +848,16 @@ const char *idWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) int c = children.Num(); while (--c >= 0) { if (children[c]->visible && children[c]->Contains(children[c]->drawRect, gui->CursorX(), gui->CursorY()) && !(children[c]->noEvents)) { - idWindow *child = children[c]; + idWindow* child = children[c]; if (event->evValue2) { BringToTop(child); SetFocus(child); } - if (child->Contains(child->clientRect,gui->CursorX(), gui->CursorY()) || GetCaptureChild() == child) { + if (child->Contains(child->clientRect, gui->CursorX(), gui->CursorY()) || GetCaptureChild() == child) { if ((gui_edit.GetBool() && (child->flags & WIN_SELECTED)) || (!gui_edit.GetBool() && (child->flags & WIN_MOVABLE))) { SetCapture(child); } - const char *childRet = child->HandleEvent(event, updateVisuals); + const char* childRet = child->HandleEvent(event, updateVisuals); if (childRet && *childRet) { return childRet; } @@ -811,7 +867,13 @@ const char *idWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) } } } - } else if (event->evValue == K_MOUSE3) { + #ifdef QUAKE4 + if (event->evValue2 && !actionDownRun) { + actionDownRun = RunScript(ON_ACTIONRIGHT); + } +#endif + } + else if (event->evValue == K_MOUSE3) { if (gui_edit.GetBool()) { int c = children.Num(); for (int i = 0; i < c; i++) { @@ -826,9 +888,10 @@ const char *idWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) } } } - } else if (event->evValue == K_TAB && event->evValue2) { + } + else if (event->evValue == K_TAB && event->evValue2) { if (GetFocusedChild()) { - const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); + const char* childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); if (childRet && *childRet) { return childRet; } @@ -837,35 +900,37 @@ const char *idWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) // or the previous window if shift is held down int direction = 1; - if ( idKeyInput::IsDown( K_SHIFT ) ) { + if (idKeyInput::IsDown(K_SHIFT)) { direction = -1; } - idWindow *currentFocus = GetFocusedChild(); - idWindow *child = GetFocusedChild(); - idWindow *parent = child->GetParent(); - while ( parent ) { + idWindow* currentFocus = GetFocusedChild(); + idWindow* child = GetFocusedChild(); + idWindow* parent = child->GetParent(); + while (parent) { bool foundFocus = false; bool recurse = false; int index = 0; - if ( child ) { - index = parent->GetChildIndex( child ) + direction; - } else if ( direction < 0 ) { + if (child) { + index = parent->GetChildIndex(child) + direction; + } + else if (direction < 0) { index = parent->GetChildCount() - 1; } - while ( index < parent->GetChildCount() && index >= 0) { - idWindow *testWindow = parent->GetChild( index ); - if ( testWindow == currentFocus ) { + while (index < parent->GetChildCount() && index >= 0) { + idWindow* testWindow = parent->GetChild(index); + if (testWindow == currentFocus) { // we managed to wrap around and get back to our starting window foundFocus = true; break; } - if ( testWindow && !testWindow->noEvents && testWindow->visible ) { - if ( testWindow->flags & WIN_CANFOCUS ) { - SetFocus( testWindow ); + if (testWindow && !testWindow->noEvents && testWindow->visible) { + if (testWindow->flags & WIN_CANFOCUS) { + SetFocus(testWindow); foundFocus = true; break; - } else if ( testWindow->GetChildCount() > 0 ) { + } + else if (testWindow->GetChildCount() > 0) { parent = testWindow; child = NULL; recurse = true; @@ -874,17 +939,19 @@ const char *idWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) } index += direction; } - if ( foundFocus ) { + if (foundFocus) { // We found a child to focus on break; - } else if ( recurse ) { + } + else if (recurse) { // We found a child with children continue; - } else { + } + else { // We didn't find anything, so go back up to our parent child = parent; parent = child->GetParent(); - if ( parent == gui->GetDesktop() ) { + if (parent == gui->GetDesktop()) { // We got back to the desktop, so wrap around but don't actually go to the desktop parent = NULL; child = NULL; @@ -892,49 +959,117 @@ const char *idWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) } } } - } else if (event->evValue == K_ESCAPE && event->evValue2) { + } + else if (event->evValue == K_ESCAPE && event->evValue2) { if (GetFocusedChild()) { - const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); + const char* childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); if (childRet && *childRet) { return childRet; } } - RunScript( ON_ESC ); - } else if (event->evValue == K_ENTER ) { + RunScript(ON_ESC); + } + else if (event->evValue == K_ENTER) { if (GetFocusedChild()) { - const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); + const char* childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); if (childRet && *childRet) { return childRet; } } - if ( flags & WIN_WANTENTER ) { - if ( event->evValue2 ) { - RunScript( ON_ACTION ); - } else { - RunScript( ON_ACTIONRELEASE ); + if (flags & WIN_WANTENTER) { + if (event->evValue2) { + RunScript(ON_ACTION); + } + else { + RunScript(ON_ACTIONRELEASE); } } - } else { + } +#ifdef QUAKE4 + else if (event->evValue == K_JOY3 && event->evValue2) { if (GetFocusedChild()) { - const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); + const char* childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); + if (childRet && *childRet) { + return childRet; + } + if (!actionDownRun) { + actionDownRun = GetFocusedChild()->RunScript(ON_ACTION); + AddCommand(GetFocusedChild()->cmd.c_str()); + } + } + RunControllerScript(ON_JOYACTION, event, updateVisuals); + } + else if (event->evValue == K_JOY4 && event->evValue2) { + if (!RunControllerScript(ON_JOYBACK, event, updateVisuals)) { + if (GetFocusedChild()) { + const char* childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); + if (childRet && *childRet) { + return childRet; + } + } + RunScript(ON_ESC); + } + } + else if (event->evValue == K_JOY1 && event->evValue2) { + RunControllerScript(ON_JOYLSHOULDER, event, updateVisuals); + } + else if (event->evValue == K_JOY2 && event->evValue2) { + RunControllerScript(ON_JOYRSHOULDER, event, updateVisuals); + } + else if (event->evValue == K_JOY5 && event->evValue2) { + RunControllerScript(ON_JOYBUTTON2, event, updateVisuals); + } + else if (event->evValue == K_JOY6 && event->evValue2) { + RunControllerScript(ON_JOYBUTTON1, event, updateVisuals); + } + else if (event->evValue == K_JOY7 && event->evValue2) { + RunControllerScript(ON_JOYBUTTON3, event, updateVisuals); + } + else if (event->evValue == K_JOY9 && event->evValue2) { + RunControllerScript(ON_JOYLEFT, event, updateVisuals); + } + else if (event->evValue == K_JOY10 && event->evValue2) { + RunControllerScript(ON_JOYRIGHT, event, updateVisuals); + } + else if (event->evValue == K_JOY11 && event->evValue2) { + RunControllerScript(ON_JOYUP, event, updateVisuals); + } + else if (event->evValue == K_JOY12 && event->evValue2) { + RunControllerScript(ON_JOYDOWN, event, updateVisuals); + } +#endif + else { + if (GetFocusedChild()) { + const char* childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); if (childRet && *childRet) { return childRet; } } } - } else if (event->evType == SE_MOUSE) { + } +#ifdef QUAKE4 + else if (event->evType == SE_JOYSTICK_AXIS) { if (updateVisuals) { *updateVisuals = true; } - const char *mouseRet = RouteMouseCoords(event->evValue, event->evValue2); + RouteJoystickChange(event->evValue, event->evValue2); + } +#endif + else if (event->evType == SE_MOUSE) { + if (updateVisuals) { + *updateVisuals = true; + } + const char* mouseRet = RouteMouseCoords(event->evValue, event->evValue2); if (mouseRet && *mouseRet) { return mouseRet; } - } else if (event->evType == SE_NONE) { - } else if (event->evType == SE_CHAR) { + } + else if (event->evType == SE_NONE) { + } + else if (event->evType == SE_CHAR) { if (GetFocusedChild()) { - const char *childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); + const char* childRet = GetFocusedChild()->HandleEvent(event, updateVisuals); if (childRet && *childRet) { return childRet; } @@ -943,7 +1078,7 @@ const char *idWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) } gui->GetReturnCmd() = cmd; - if ( gui->GetPendingCmd().Length() ) { + if (gui->GetPendingCmd().Length()) { gui->GetReturnCmd() += " ; "; gui->GetReturnCmd() += gui->GetPendingCmd(); gui->GetPendingCmd().Clear(); @@ -963,7 +1098,8 @@ void idWindow::DebugDraw(int time, float x, float y) { dc->EnableClipping(false); if (gui_debug.GetInteger() == 1) { dc->DrawRect(drawRect.x, drawRect.y, drawRect.w, drawRect.h, 1, idDeviceContext::colorRed); - } else if (gui_debug.GetInteger() == 2) { + } + else if (gui_debug.GetInteger() == 2) { char out[1024]; idStr str; str = text.c_str(); @@ -1000,43 +1136,67 @@ void idWindow::Transition() { int i, c = transitions.Num(); bool clear = true; - for ( i = 0; i < c; i++ ) { - idTransitionData *data = &transitions[i]; - idWinRectangle *r = NULL; - idWinVec4 *v4 = dynamic_cast(data->data); + for (i = 0; i < c; i++) { + idTransitionData* data = &transitions[i]; + idWinRectangle* r = NULL; + idWinVec4* v4 = dynamic_cast(data->data); idWinFloat* val = NULL; +#ifdef QUAKE4 + idWinFloatMember* member = NULL; +#endif if (v4 == NULL) { r = dynamic_cast(data->data); - if ( !r ) { + if (!r) { val = dynamic_cast(data->data); + if (!val) { +#ifdef QUAKE4 + member = dynamic_cast(data->data); +#endif + } } } - if ( data->interp.IsDone( gui->GetTime() ) && data->data) { + if (data->interp.IsDone(gui->GetTime()) && data->data) { if (v4) { *v4 = data->interp.GetEndValue(); - } else if ( val ) { + } + else if (val) { *val = data->interp.GetEndValue()[0]; - } else { + } +#ifdef QUAKE4 + else if (member) { + member->Set(va("%g", data->interp.GetEndValue()[0])); + } +#endif + else if (r) { *r = data->interp.GetEndValue(); } - } else { + } + else { clear = false; if (data->data) { if (v4) { - *v4 = data->interp.GetCurrentValue( gui->GetTime() ); - } else if ( val ) { - *val = data->interp.GetCurrentValue( gui->GetTime() )[0]; - } else { - *r = data->interp.GetCurrentValue( gui->GetTime() ); + *v4 = data->interp.GetCurrentValue(gui->GetTime()); } - } else { + else if (val) { + *val = data->interp.GetCurrentValue(gui->GetTime())[0]; + } +#ifdef QUAKE4 + else if (member) { + member->Set(va("%g", data->interp.GetCurrentValue(gui->GetTime())[0])); + } +#endif + else if (r) { + *r = data->interp.GetCurrentValue(gui->GetTime()); + } + } + else { common->Warning("Invalid transitional data for window %s in gui %s", GetName(), gui->GetSourceFile()); } } } - if ( clear ) { - transitions.SetNum( 0, false ); + if (clear) { + transitions.SetNum(0, false); flags &= ~WIN_INTRANSITION; } } @@ -1048,26 +1208,26 @@ idWindow::Time */ void idWindow::Time() { - if ( noTime ) { + if (noTime) { return; } - if ( timeLine == -1 ) { + if (timeLine == -1) { timeLine = gui->GetTime(); } cmd = ""; int c = timeLineEvents.Num(); - if ( c > 0 ) { + if (c > 0) { for (int i = 0; i < c; i++) { - if ( timeLineEvents[i]->pending && gui->GetTime() - timeLine >= timeLineEvents[i]->time ) { + if (timeLineEvents[i]->pending && gui->GetTime() - timeLine >= timeLineEvents[i]->time) { timeLineEvents[i]->pending = false; - RunScriptList( timeLineEvents[i]->event ); + RunScriptList(timeLineEvents[i]->event); } } } - if ( gui->Active() ) { + if (gui->Active()) { gui->GetPendingCmd() += cmd; } } @@ -1079,7 +1239,7 @@ idWindow::EvalRegs */ float idWindow::EvalRegs(int test, bool force) { static float regs[MAX_EXPRESSION_REGISTERS]; - static idWindow *lastEval = NULL; + static idWindow* lastEval = NULL; if (!force && test >= 0 && test < MAX_EXPRESSION_REGISTERS && lastEval == this) { return regs[test]; @@ -1105,17 +1265,18 @@ float idWindow::EvalRegs(int test, bool force) { idWindow::DrawBackground ================ */ -void idWindow::DrawBackground(const idRectangle &drawRect) { - if ( backColor.w() ) { +void idWindow::DrawBackground(const idRectangle& drawRect) { + if (backColor.w()) { dc->DrawFilledRect(drawRect.x, drawRect.y, drawRect.w, drawRect.h, backColor); } - if ( background && matColor.w() ) { + if (background && matColor.w()) { float scalex, scaley; - if ( flags & WIN_NATURALMAT ) { + if (flags & WIN_NATURALMAT) { scalex = drawRect.w / background->GetImageWidth(); scaley = drawRect.h / background->GetImageHeight(); - } else { + } + else { scalex = matScalex; scaley = matScaley; } @@ -1128,8 +1289,8 @@ void idWindow::DrawBackground(const idRectangle &drawRect) { idWindow::DrawBorderAndCaption ================ */ -void idWindow::DrawBorderAndCaption(const idRectangle &drawRect) { - if ( flags & WIN_BORDER && borderSize && borderColor.w() ) { +void idWindow::DrawBorderAndCaption(const idRectangle& drawRect) { + if (flags & WIN_BORDER && borderSize && borderColor.w()) { dc->DrawRect(drawRect.x, drawRect.y, drawRect.w, drawRect.h, borderSize, borderColor); } } @@ -1144,16 +1305,16 @@ void idWindow::SetupTransforms(float x, float y) { static idVec3 org; trans.Identity(); - org.Set( origin.x + x, origin.y + y, 0 ); + org.Set(origin.x + x, origin.y + y, 0); - if ( rotate ) { + if (rotate) { static idRotation rot; static idVec3 vec(0, 0, 1); - rot.Set( org, vec, rotate ); + rot.Set(org, vec, rotate); trans = rot.ToMat3(); } - if ( shear.x || shear.y ) { + if (shear.x || shear.y) { static idMat3 smat; smat.Identity(); smat[0][1] = shear.x; @@ -1161,8 +1322,8 @@ void idWindow::SetupTransforms(float x, float y) { trans *= smat; } - if ( !trans.IsIdentity() ) { - dc->SetTransformInfo( org, trans ); + if (!trans.IsIdentity()) { + dc->SetTransformInfo(org, trans); } } @@ -1195,25 +1356,25 @@ idWindow::Redraw void idWindow::Redraw(float x, float y) { idStr str; - if (r_skipGuiShaders.GetInteger() == 1 || dc == NULL ) { + if (r_skipGuiShaders.GetInteger() == 1 || dc == NULL) { return; } int time = gui->GetTime(); - if ( flags & WIN_DESKTOP && r_skipGuiShaders.GetInteger() != 3 ) { - RunTimeEvents( time ); + if (flags & WIN_DESKTOP && r_skipGuiShaders.GetInteger() != 3) { + RunTimeEvents(time); } - if ( r_skipGuiShaders.GetInteger() == 2 ) { + if (r_skipGuiShaders.GetInteger() == 2) { return; } - if ( flags & WIN_SHOWTIME ) { + if (flags & WIN_SHOWTIME) { dc->DrawText(va(" %0.1f seconds\n%s", (float)(time - timeLine) / 1000, gui->State().GetString("name")), 0.35f, 0, dc->colorWhite, idRectangle(100, 0, 80, 80), false); } - if ( flags & WIN_SHOWCOORDS ) { + if (flags & WIN_SHOWCOORDS) { dc->EnableClipping(false); sprintf(str, "x: %i y: %i cursorx: %i cursory: %i", (int)rect.x(), (int)rect.y(), (int)gui->CursorX(), (int)gui->CursorY()); dc->DrawText(str, 0.25f, 0, dc->colorWhite, idRectangle(0, 0, 100, 20), false); @@ -1229,7 +1390,7 @@ void idWindow::Redraw(float x, float y) { SetFont(); //if (flags & WIN_DESKTOP) { // see if this window forces a new aspect ratio - dc->SetSize(forceAspectWidth, forceAspectHeight); + dc->SetSize(forceAspectWidth, forceAspectHeight); //} //FIXME: go to screen coord tracking @@ -1242,48 +1403,49 @@ void idWindow::Redraw(float x, float y) { idVec3 oldOrg; idMat3 oldTrans; - dc->GetTransformInfo( oldOrg, oldTrans ); + dc->GetTransformInfo(oldOrg, oldTrans); SetupTransforms(x, y); DrawBackground(drawRect); DrawBorderAndCaption(drawRect); - if ( !( flags & WIN_NOCLIP) ) { + if (!(flags & WIN_NOCLIP)) { dc->PushClipRect(clientRect); } - if ( r_skipGuiShaders.GetInteger() < 5 ) { + if (r_skipGuiShaders.GetInteger() < 5) { Draw(time, x, y); } - if ( gui_debug.GetInteger() ) { + if (gui_debug.GetInteger()) { DebugDraw(time, x, y); } int c = drawWindows.Num(); - for ( int i = 0; i < c; i++ ) { - if ( drawWindows[i].win ) { - drawWindows[i].win->Redraw( clientRect.x + xOffset, clientRect.y + yOffset ); - } else { - drawWindows[i].simp->Redraw( clientRect.x + xOffset, clientRect.y + yOffset ); + for (int i = 0; i < c; i++) { + if (drawWindows[i].win) { + drawWindows[i].win->Redraw(clientRect.x + xOffset, clientRect.y + yOffset); + } + else { + drawWindows[i].simp->Redraw(clientRect.x + xOffset, clientRect.y + yOffset); } } // Put transforms back to what they were before the children were processed dc->SetTransformInfo(oldOrg, oldTrans); - if ( ! ( flags & WIN_NOCLIP ) ) { + if (!(flags & WIN_NOCLIP)) { dc->PopClipRect(); } - if (gui_edit.GetBool() || (flags & WIN_DESKTOP && !( flags & WIN_NOCURSOR ) && !hideCursor && (gui->Active() || ( flags & WIN_MENUGUI ) ))) { + if (gui_edit.GetBool() || (flags & WIN_DESKTOP && !(flags & WIN_NOCURSOR) && !hideCursor && (gui->Active() || (flags & WIN_MENUGUI)))) { dc->SetTransformInfo(vec3_origin, mat3_identity); gui->DrawCursor(); } if (gui_debug.GetInteger() && flags & WIN_DESKTOP) { dc->EnableClipping(false); - sprintf(str, "x: %1.f y: %1.f", gui->CursorX(), gui->CursorY()); + sprintf(str, "x: %1.f y: %1.f", gui->CursorX(), gui->CursorY()); dc->DrawText(str, 0.25, 0, dc->colorWhite, idRectangle(0, 0, 100, 20), false); dc->DrawText(gui->GetSourceFile(), 0.25, 0, dc->colorWhite, idRectangle(0, 20, 300, 20), false); dc->EnableClipping(true); @@ -1299,10 +1461,10 @@ void idWindow::Redraw(float x, float y) { idWindow::SetDC ================ */ -void idWindow::SetDC(idDeviceContext *d) { +void idWindow::SetDC(idDeviceContext* d) { dc = d; //if (flags & WIN_DESKTOP) { - dc->SetSize(forceAspectWidth, forceAspectHeight); + dc->SetSize(forceAspectWidth, forceAspectHeight); //} int c = children.Num(); for (int i = 0; i < c; i++) { @@ -1315,7 +1477,7 @@ void idWindow::SetDC(idDeviceContext *d) { idWindow::ArchiveToDictionary ================ */ -void idWindow::ArchiveToDictionary(idDict *dict, bool useNames) { +void idWindow::ArchiveToDictionary(idDict* dict, bool useNames) { //FIXME: rewrite without state int c = children.Num(); for (int i = 0; i < c; i++) { @@ -1328,7 +1490,7 @@ void idWindow::ArchiveToDictionary(idDict *dict, bool useNames) { idWindow::InitFromDictionary ================ */ -void idWindow::InitFromDictionary(idDict *dict, bool byName) { +void idWindow::InitFromDictionary(idDict* dict, bool byName) { //FIXME: rewrite without state int c = children.Num(); for (int i = 0; i < c; i++) { @@ -1344,7 +1506,7 @@ idWindow::CalcClientRect void idWindow::CalcClientRect(float xofs, float yofs) { drawRect = rect; - if ( flags & WIN_INVERTRECT ) { + if (flags & WIN_INVERTRECT) { drawRect.x = rect.x() - rect.w(); drawRect.y = rect.y() - rect.h(); } @@ -1354,7 +1516,8 @@ void idWindow::CalcClientRect(float xofs, float yofs) { // and ignore the original positioning if (flags & WIN_HCENTER) { drawRect.x = (parent->rect.w() - rect.w()) / 2; - } else { + } + else { drawRect.y = (parent->rect.h() - rect.h()) / 2; } } @@ -1382,7 +1545,7 @@ void idWindow::CalcClientRect(float xofs, float yofs) { textRect.y += textAligny; } - origin.Set( rect.x() + (rect.w() / 2 ), rect.y() + ( rect.h() / 2 ) ); + origin.Set(rect.x() + (rect.w() / 2), rect.y() + (rect.h() / 2)); } @@ -1394,9 +1557,9 @@ idWindow::SetupBackground void idWindow::SetupBackground() { if (backGroundName.Length()) { background = declManager->FindMaterial(backGroundName); - background->SetImageClassifications( 1 ); // just for resource tracking - if ( background && !background->TestMaterialFlag( MF_DEFAULTED ) ) { - background->SetSort(SS_GUI ); + background->SetImageClassifications(1); // just for resource tracking + if (background && !background->TestMaterialFlag(MF_DEFAULTED)) { + background->SetSort(SS_GUI); } } backGroundName.SetMaterialPtr(&background); @@ -1408,7 +1571,6 @@ idWindow::SetupFromState ================ */ void idWindow::SetupFromState() { - idStr str; background = NULL; SetupBackground(); @@ -1421,13 +1583,18 @@ void idWindow::SetupFromState() { flags |= WIN_TRANSFORM; } - CalcClientRect(0,0); - if ( scripts[ ON_ACTION ] ) { + CalcClientRect(0, 0); + #ifdef QUAKE4 + if (scripts[ON_ACTION] || scripts[ON_ACTIONRIGHT] || scripts[ON_JOYACTION]) { +#else + if (scripts[ON_ACTION]) { +#endif cursor = idDeviceContext::CURSOR_HAND; flags |= WIN_CANFOCUS; } } + /* ================ idWindow::Moved @@ -1501,7 +1668,7 @@ void idWindow::ClearFlag(unsigned int f) { idWindow::SetParent ================ */ -void idWindow::SetParent(idWindow *w) { +void idWindow::SetParent(idWindow* w) { parent = w; } @@ -1510,7 +1677,7 @@ void idWindow::SetParent(idWindow *w) { idWindow::GetCaptureChild ================ */ -idWindow *idWindow::GetCaptureChild() { +idWindow* idWindow::GetCaptureChild() { if (flags & WIN_DESKTOP) { return gui->GetDesktop()->captureChild; } @@ -1522,7 +1689,7 @@ idWindow *idWindow::GetCaptureChild() { idWindow::GetFocusedChild ================ */ -idWindow *idWindow::GetFocusedChild() { +idWindow* idWindow::GetFocusedChild() { if (flags & WIN_DESKTOP) { return gui->GetDesktop()->focusedChild; } @@ -1535,41 +1702,40 @@ idWindow *idWindow::GetFocusedChild() { idWindow::SetFocus ================ */ -idWindow *idWindow::SetFocus(idWindow *w, bool scripts) { - // only one child can have the focus - idWindow *lastFocus = NULL; - if (w->flags & WIN_CANFOCUS) { - lastFocus = gui->GetDesktop()->focusedChild; - if ( lastFocus ) { - lastFocus->flags &= ~WIN_FOCUS; - lastFocus->LoseFocus(); - } - - // call on lose focus - if ( scripts && lastFocus ) { - // calling this broke all sorts of guis - // lastFocus->RunScript(ON_MOUSEEXIT); - } - // call on gain focus - if ( scripts && w ) { - // calling this broke all sorts of guis - // w->RunScript(ON_MOUSEENTER); - } - - w->flags |= WIN_FOCUS; - w->GainFocus(); - gui->GetDesktop()->focusedChild = w; +idWindow* idWindow::SetFocus(idWindow* w, bool scripts) { + idWindow* lastFocus = NULL; + if (!w || !(w->flags & WIN_CANFOCUS)) { + return NULL; } + lastFocus = gui->GetDesktop()->focusedChild; + if (lastFocus) { + lastFocus->flags &= ~WIN_FOCUS; + lastFocus->LoseFocus(); + } + +#ifdef QUAKE4 + if (scripts && lastFocus) { + lastFocus->RunScript(ON_LOSEFOCUS); + } + if (scripts && w) { + w->RunScript(ON_GAINFOCUS); + } +#endif + + w->flags |= WIN_FOCUS; + w->GainFocus(); + gui->GetDesktop()->focusedChild = w; return lastFocus; } + /* ================ idWindow::ParseScript ================ */ -bool idWindow::ParseScript(idParser *src, idGuiScriptList &list, int *timeParm, bool elseBlock ) { +bool idWindow::ParseScript(idParser* src, idGuiScriptList& list, int* timeParm, bool elseBlock) { bool ifElseBlock = false; @@ -1579,42 +1745,42 @@ bool idWindow::ParseScript(idParser *src, idGuiScriptList &list, int *timeParm, // arg.. basically we want everything between the { } as it will be interpreted at // run time - if ( elseBlock ) { - src->ReadToken ( &token ); + if (elseBlock) { + src->ReadToken(&token); - if ( !token.Icmp ( "if" ) ) { + if (!token.Icmp("if")) { ifElseBlock = true; } - src->UnreadToken ( &token ); + src->UnreadToken(&token); - if ( !ifElseBlock && !src->ExpectTokenString( "{" ) ) { + if (!ifElseBlock && !src->ExpectTokenString("{")) { return false; } } - else if ( !src->ExpectTokenString( "{" ) ) { + else if (!src->ExpectTokenString("{")) { return false; } int nest = 0; while (1) { - if ( !src->ReadToken(&token) ) { - src->Error( "Unexpected end of file" ); + if (!src->ReadToken(&token)) { + src->Error("Unexpected end of file"); return false; } - if ( token == "{" ) { + if (token == "{") { nest++; } - if ( token == "}" ) { + if (token == "}") { if (nest-- <= 0) { return true; } } - idGuiScript *gs = new idGuiScript(); + idGuiScript* gs = new idGuiScript(); if (token.Icmp("if") == 0) { gs->conditionReg = ParseExpression(src); gs->ifList = new idGuiScriptList(); @@ -1623,29 +1789,31 @@ bool idWindow::ParseScript(idParser *src, idGuiScriptList &list, int *timeParm, if (token == "else") { gs->elseList = new idGuiScriptList(); // pass true to indicate we are parsing an else condition - ParseScript(src, *gs->elseList, NULL, true ); - } else { + ParseScript(src, *gs->elseList, NULL, true); + } + else { src->UnreadToken(&token); } } list.Append(gs); - // if we are parsing an else if then return out so + // if we are parsing an else if then return out so // the initial "if" parser can handle the rest of the tokens - if ( ifElseBlock ) { + if (ifElseBlock) { return true; } continue; - } else { + } + else { src->UnreadToken(&token); } // empty { } is not allowed - if ( token == "{" ) { - src->Error ( "Unexpected {" ); - delete gs; - return false; + if (token == "{") { + src->Error("Unexpected {"); + delete gs; + return false; } gs->Parse(src); @@ -1679,7 +1847,7 @@ void idWindow::RestoreExpressionParseState() { idWindow::ParseScriptEntry ================ */ -bool idWindow::ParseScriptEntry(const char *name, idParser *src) { +bool idWindow::ParseScriptEntry(const char* name, idParser* src) { for (int i = 0; i < SCRIPT_COUNT; i++) { if (idStr::Icmp(name, ScriptNames[i]) == 0) { delete scripts[i]; @@ -1695,8 +1863,8 @@ bool idWindow::ParseScriptEntry(const char *name, idParser *src) { idWindow::DisableRegister ================ */ -void idWindow::DisableRegister(const char *_name) { - idRegister *reg = RegList()->FindReg(_name); +void idWindow::DisableRegister(const char* _name) { + idRegister* reg = RegList()->FindReg(_name); if (reg) { reg->Enable(false); } @@ -1715,53 +1883,54 @@ void idWindow::PostParse() { idWindow::GetWinVarOffset ================ */ -intptr_t idWindow::GetWinVarOffset( idWinVar *wv, drawWin_t* owner) { +intptr_t idWindow::GetWinVarOffset(idWinVar* wv, drawWin_t* owner) { intptr_t ret = -1; - if ( wv == &rect ) { - ret = (ptrdiff_t)&this->rect - (ptrdiff_t)this; + if (wv == &rect) { + ret = (intptr_t) & ((idWindow*)0)->rect; } - if ( wv == &backColor ) { - ret = (ptrdiff_t)&this->backColor - (ptrdiff_t)this; + if (wv == &backColor) { + ret = (intptr_t) & ((idWindow*)0)->backColor; } - if ( wv == &matColor ) { - ret = (ptrdiff_t)&this->matColor - (ptrdiff_t)this; + if (wv == &matColor) { + ret = (intptr_t) & ((idWindow*)0)->matColor; } - if ( wv == &foreColor ) { - ret = (ptrdiff_t)&this->foreColor - (ptrdiff_t)this; + if (wv == &foreColor) { + ret = (intptr_t) & ((idWindow*)0)->foreColor; } - if ( wv == &hoverColor ) { - ret = (ptrdiff_t)&this->hoverColor - (ptrdiff_t)this; + if (wv == &hoverColor) { + ret = (intptr_t) & ((idWindow*)0)->hoverColor; } - if ( wv == &borderColor ) { - ret = (ptrdiff_t)&this->borderColor - (ptrdiff_t)this; + if (wv == &borderColor) { + ret = (intptr_t) & ((idWindow*)0)->borderColor; } - if ( wv == &textScale ) { - ret = (ptrdiff_t)&this->textScale - (ptrdiff_t)this; + if (wv == &textScale) { + ret = (intptr_t) & ((idWindow*)0)->textScale; } - if ( wv == &rotate ) { - ret = (ptrdiff_t)&this->rotate - (ptrdiff_t)this; + if (wv == &rotate) { + ret = (intptr_t) & ((idWindow*)0)->rotate; } - if ( ret != -1 ) { + if (ret != -1) { owner->win = this; return ret; } - for ( int i = 0; i < drawWindows.Num(); i++ ) { - if ( drawWindows[i].win ) { - ret = drawWindows[i].win->GetWinVarOffset( wv, owner ); - } else { - ret = drawWindows[i].simp->GetWinVarOffset( wv, owner ); + for (int i = 0; i < drawWindows.Num(); i++) { + if (drawWindows[i].win) { + ret = drawWindows[i].win->GetWinVarOffset(wv, owner); } - if ( ret != -1 ) { + else { + ret = drawWindows[i].simp->GetWinVarOffset(wv, owner); + } + if (ret != -1) { break; } } @@ -1774,10 +1943,10 @@ intptr_t idWindow::GetWinVarOffset( idWinVar *wv, drawWin_t* owner) { idWindow::GetWinVarByName ================ */ -idWinVar *idWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** owner) { - idWinVar *retVar = NULL; +idWinVar* idWindow::GetWinVarByName(const char* _name, bool fixup, drawWin_t** owner) { + idWinVar* retVar = NULL; - if ( owner ) { + if (owner) { *owner = NULL; } @@ -1829,9 +1998,8 @@ idWinVar *idWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** o idStr key = _name; bool guiVar = (key.Find(VAR_GUIPREFIX) >= 0); - int c = definedVars.Num(); - for (int i = 0; i < c; i++) { - if (idStr::Icmp(_name, (guiVar) ? va("%s",definedVars[i]->GetName()) : definedVars[i]->GetName()) == 0) { + for (int i = 0; i < definedVars.Num(); i++) { + if (idStr::Icmp(_name, (guiVar) ? va("%s", definedVars[i]->GetName()) : definedVars[i]->GetName()) == 0) { retVar = definedVars[i]; break; } @@ -1842,46 +2010,91 @@ idWinVar *idWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** o DisableRegister(_name); } - if ( owner && parent ) { - *owner = parent->FindChildByName ( name ); + if (owner && parent) { + *owner = parent->FindChildByName(name); } return retVar; } - int len = key.Length(); - if ( len > 5 && guiVar ) { - idWinVar *var = new idWinStr; + if (key.Length() > 5 && guiVar) { + idWinVar* var = new idWinStr; var->Init(_name, this); definedVars.Append(var); return var; - } else if (fixup) { + } + + if (fixup) { int n = key.Find("::"); if (n > 0) { idStr winName = key.Left(n); - idStr var = key.Right(key.Length() - n - 2); - drawWin_t *win = GetGui()->GetDesktop()->FindChildByName(winName); + idStr varName = key.Right(key.Length() - n - 2); + drawWin_t* win = GetGui()->GetDesktop()->FindChildByName(winName); if (win) { if (win->win) { - return win->win->GetWinVarByName(var, false, owner); - } else { - if ( owner ) { + return win->win->GetWinVarByName(varName, false, owner); + } + else { + if (owner) { *owner = win; } - return win->simp->GetWinVarByName(var); + return win->simp->GetWinVarByName(varName); } } } } + +#ifdef QUAKE4 + static bool preventRecursion = false; + + char* underscore = strrchr(const_cast(_name), '_'); + if (underscore && underscore[1] && underscore[2] == '\0' && !preventRecursion) { + idStr temp = _name; + temp.CapLength( (int)( underscore - _name ) ); + + int index = -1; + const char suffix = (char)tolower(underscore[1]); + + preventRecursion = true; + idWinVar* base = GetWinVarByName(temp.c_str(), fixup, owner); + preventRecursion = false; + + if (dynamic_cast(base)) { + switch (suffix) { + case 'x': index = 0; break; + case 'y': index = 1; break; + case 'z': index = 2; break; + case 'w': index = 3; break; + } + } + else if (dynamic_cast(base)) { + switch (suffix) { + case 'x': index = 0; break; + case 'y': index = 1; break; + case 'w': index = 2; break; + case 'h': index = 3; break; + } + } + + if (index != -1) { + idWinFloatMember* member = new idWinFloatMember(base, index); + member->SetName(_name); + definedVars.Append(member); + return member; + } + } + +#endif return NULL; } + /* ================ idWindow::ParseString ================ */ -void idWindow::ParseString(idParser *src, idStr &out) { +void idWindow::ParseString(idParser* src, idStr& out) { idToken tok; if (src->ReadToken(&tok)) { out = tok; @@ -1893,7 +2106,7 @@ void idWindow::ParseString(idParser *src, idStr &out) { idWindow::ParseVec4 ================ */ -void idWindow::ParseVec4(idParser *src, idVec4 &out) { +void idWindow::ParseVec4(idParser* src, idVec4& out) { idToken tok; src->ReadToken(&tok); out.x = atof(tok); @@ -1913,16 +2126,16 @@ void idWindow::ParseVec4(idParser *src, idVec4 &out) { idWindow::ParseInternalVar ================ */ -bool idWindow::ParseInternalVar(const char *_name, idParser *src) { +bool idWindow::ParseInternalVar(const char* _name, idParser* src) { if (idStr::Icmp(_name, "showtime") == 0) { - if ( src->ParseBool() ) { + if (src->ParseBool()) { flags |= WIN_SHOWTIME; } return true; } if (idStr::Icmp(_name, "showcoords") == 0) { - if ( src->ParseBool() ) { + if (src->ParseBool()) { flags |= WIN_SHOWCOORDS; } return true; @@ -1948,7 +2161,7 @@ bool idWindow::ParseInternalVar(const char *_name, idParser *src) { return true; } if (idStr::Icmp(_name, "nowrap") == 0) { - if ( src->ParseBool() ) { + if (src->ParseBool()) { flags |= WIN_NOWRAP; } return true; @@ -1957,6 +2170,16 @@ bool idWindow::ParseInternalVar(const char *_name, idParser *src) { textShadow = src->ParseInt(); return true; } +#ifdef QUAKE4 + if (idStr::Icmp(_name, "textSpacing") == 0) { + textSpacing = src->ParseFloat(); + return true; + } + if (idStr::Icmp(_name, "textStyle") == 0) { + textStyle = src->ParseInt(); + return true; + } +#endif if (idStr::Icmp(_name, "textalign") == 0) { textAlign = src->ParseInt(); return true; @@ -1972,62 +2195,76 @@ bool idWindow::ParseInternalVar(const char *_name, idParser *src) { if (idStr::Icmp(_name, "shear") == 0) { shear.x = src->ParseFloat(); idToken tok; - src->ReadToken( &tok ); - if ( tok.Icmp( "," ) ) { - src->Error( "Expected comma in shear definiation" ); + src->ReadToken(&tok); + if (tok.Icmp(",")) { + src->Error("Expected comma in shear definiation"); return false; } shear.y = src->ParseFloat(); return true; } if (idStr::Icmp(_name, "wantenter") == 0) { - if ( src->ParseBool() ) { + if (src->ParseBool()) { flags |= WIN_WANTENTER; } return true; } if (idStr::Icmp(_name, "naturalmatscale") == 0) { - if ( src->ParseBool() ) { + if (src->ParseBool()) { flags |= WIN_NATURALMAT; } return true; } if (idStr::Icmp(_name, "noclip") == 0) { - if ( src->ParseBool() ) { + if (src->ParseBool()) { flags |= WIN_NOCLIP; } return true; } if (idStr::Icmp(_name, "nocursor") == 0) { - if ( src->ParseBool() ) { + if (src->ParseBool()) { flags |= WIN_NOCURSOR; } return true; } if (idStr::Icmp(_name, "menugui") == 0) { - if ( src->ParseBool() ) { + if (src->ParseBool()) { flags |= WIN_MENUGUI; } return true; } if (idStr::Icmp(_name, "modal") == 0) { - if ( src->ParseBool() ) { + if (src->ParseBool()) { flags |= WIN_MODAL; } return true; } if (idStr::Icmp(_name, "invertrect") == 0) { - if ( src->ParseBool() ) { + if (src->ParseBool()) { flags |= WIN_INVERTRECT; } return true; } +#ifdef QUAKE4 + if (idStr::Icmp(_name, "alwaysThink") == 0) { + if (src->ParseBool()) { + flags |= WIN_ALWAYSTHINK; + } + return true; + } + if (idStr::Icmp(_name, "chatWindow") == 0) { + if (src->ParseBool()) { + flags |= WIN_CHATWINDOW; + } + return true; + } +#endif if (idStr::Icmp(_name, "name") == 0) { ParseString(src, name); return true; } if (idStr::Icmp(_name, "play") == 0) { - common->Warning( "play encountered during gui parse.. see Robert\n" ); + common->Warning("play encountered during gui parse.. see Robert\n"); idStr playStr; ParseString(src, playStr); return true; @@ -2036,27 +2273,28 @@ bool idWindow::ParseInternalVar(const char *_name, idParser *src) { ParseString(src, comment); return true; } - if ( idStr::Icmp( _name, "font" ) == 0 ) { + if (idStr::Icmp(_name, "font") == 0) { idStr fontStr; - ParseString( src, fontStr ); - fontNum = dc->FindFont( fontStr ); + ParseString(src, fontStr); + fontNum = dc->FindFont(fontStr); return true; } return false; } + /* ================ idWindow::ParseRegEntry ================ */ -bool idWindow::ParseRegEntry(const char *name, idParser *src) { +bool idWindow::ParseRegEntry(const char* name, idParser* src) { idStr work; work = name; work.ToLower(); - idWinVar *var = GetWinVarByName(work, false); - if ( var ) { + idWinVar* var = GetWinVarByName(work, NULL); + if (var) { for (int i = 0; i < NumRegisterVars; i++) { if (idStr::Icmp(work, RegisterVars[i].name) == 0) { regList.AddReg(work, RegisterVars[i].type, src, this, var); @@ -2068,39 +2306,41 @@ bool idWindow::ParseRegEntry(const char *name, idParser *src) { // not predefined so just read the next token and add it to the state idToken tok; idVec4 v; - idWinInt *vari; - idWinFloat *varf; - idWinStr *vars; + idWinInt* vari; + idWinFloat* varf; + idWinStr* vars; if (src->ReadToken(&tok)) { if (var) { var->Set(tok); return true; } switch (tok.type) { - case TT_NUMBER : - if (tok.subtype & TT_INTEGER) { - vari = new idWinInt(); - *vari = atoi(tok); - vari->SetName(work); - definedVars.Append(vari); - } else if (tok.subtype & TT_FLOAT) { - varf = new idWinFloat(); - *varf = atof(tok); - varf->SetName(work); - definedVars.Append(varf); - } else { - vars = new idWinStr(); - *vars = tok; - vars->SetName(work); - definedVars.Append(vars); - } - break; - default : + case TT_NUMBER: + if (tok.subtype & TT_INTEGER) { + vari = new idWinInt(); + *vari = atoi(tok); + vari->SetName(work); + definedVars.Append(vari); + } + else if (tok.subtype & TT_FLOAT) { + varf = new idWinFloat(); + *varf = atof(tok); + varf->SetName(work); + definedVars.Append(varf); + } + else { vars = new idWinStr(); *vars = tok; vars->SetName(work); definedVars.Append(vars); - break; + } + break; + default: + vars = new idWinStr(); + *vars = tok; + vars->SetName(work); + definedVars.Append(vars); + break; } } @@ -2112,12 +2352,12 @@ bool idWindow::ParseRegEntry(const char *name, idParser *src) { idWindow::SetInitialState ================ */ -void idWindow::SetInitialState(const char *_name) { +void idWindow::SetInitialState(const char* _name) { name = _name; matScalex = 1.0; matScaley = 1.0; - forceAspectWidth = SCREEN_WIDTH; - forceAspectHeight = SCREEN_HEIGHT; + forceAspectWidth = 640.0; + forceAspectHeight = 480.0; noTime = false; visible = true; flags = 0; @@ -2128,7 +2368,7 @@ void idWindow::SetInitialState(const char *_name) { idWindow::Parse ================ */ -bool idWindow::Parse( idParser *src, bool rebuild) { +bool idWindow::Parse(idParser* src, bool rebuild) { idToken token, token2, token3, token4, token5, token6, token7; idStr work; @@ -2141,43 +2381,43 @@ bool idWindow::Parse( idParser *src, bool rebuild) { timeLineEvents.Clear(); transitions.Clear(); - namedEvents.DeleteContents( true ); + namedEvents.DeleteContents(true); - src->ExpectTokenType( TT_NAME, 0, &token ); + src->ExpectTokenType(TT_NAME, 0, &token); SetInitialState(token); - src->ExpectTokenString( "{" ); - src->ExpectAnyToken( &token ); + src->ExpectTokenString("{"); + src->ExpectAnyToken(&token); bool ret = true; // attach a window wrapper to the window if the gui editor is running #ifdef ID_ALLOW_TOOLS - if ( com_editors & EDITOR_GUI ) { - new rvGEWindowWrapper ( this, rvGEWindowWrapper::WT_NORMAL ); + if (com_editors & EDITOR_GUI) { + new rvGEWindowWrapper(this, rvGEWindowWrapper::WT_NORMAL); } #endif - - while( token != "}" ) { + while (token != "}") { // track what was parsed so we can maintain it for the guieditor - src->SetMarker ( ); + src->SetMarker(); - if ( token == "windowDef" || token == "animationDef" ) { + if (token == "windowDef" || token == "animationDef") { if (token == "animationDef") { visible = false; - rect = idRectangle(0,0,0,0); + rect = idRectangle(0, 0, 0, 0); } - src->ExpectTokenType( TT_NAME, 0, &token ); + src->ExpectTokenType(TT_NAME, 0, &token); token2 = token; src->UnreadToken(&token); - drawWin_t *dw = FindChildByName(token2.c_str()); + drawWin_t* dw = FindChildByName(token2.c_str()); if (dw && dw->win) { SaveExpressionParseState(); dw->win->Parse(src, rebuild); RestoreExpressionParseState(); - } else { - idWindow *win = new idWindow(dc, gui); + } + else { + idWindow* win = new idWindow(dc, gui); SaveExpressionParseState(); win->Parse(src, rebuild); RestoreExpressionParseState(); @@ -2185,20 +2425,21 @@ bool idWindow::Parse( idParser *src, bool rebuild) { dwt.simp = NULL; dwt.win = NULL; if (win->IsSimple()) { - idSimpleWindow *simple = new idSimpleWindow(win); + idSimpleWindow* simple = new idSimpleWindow(win); dwt.simp = simple; drawWindows.Append(dwt); delete win; - } else { + } + else { AddChild(win); - SetFocus(win,false); + SetFocus(win, false); dwt.win = win; drawWindows.Append(dwt); } } } - else if ( token == "editDef" ) { - idEditWindow *win = new idEditWindow(dc, gui); + else if (token == "editDef") { + idEditWindow* win = new idEditWindow(dc, gui); SaveExpressionParseState(); win->Parse(src, rebuild); RestoreExpressionParseState(); @@ -2208,8 +2449,8 @@ bool idWindow::Parse( idParser *src, bool rebuild) { dwt.win = win; drawWindows.Append(dwt); } - else if ( token == "choiceDef" ) { - idChoiceWindow *win = new idChoiceWindow(dc, gui); + else if (token == "choiceDef") { + idChoiceWindow* win = new idChoiceWindow(dc, gui); SaveExpressionParseState(); win->Parse(src, rebuild); RestoreExpressionParseState(); @@ -2219,8 +2460,8 @@ bool idWindow::Parse( idParser *src, bool rebuild) { dwt.win = win; drawWindows.Append(dwt); } - else if ( token == "sliderDef" ) { - idSliderWindow *win = new idSliderWindow(dc, gui); + else if (token == "sliderDef") { + idSliderWindow* win = new idSliderWindow(dc, gui); SaveExpressionParseState(); win->Parse(src, rebuild); RestoreExpressionParseState(); @@ -2230,8 +2471,8 @@ bool idWindow::Parse( idParser *src, bool rebuild) { dwt.win = win; drawWindows.Append(dwt); } - else if ( token == "markerDef" ) { - idMarkerWindow *win = new idMarkerWindow(dc, gui); + else if (token == "markerDef") { + idMarkerWindow* win = new idMarkerWindow(dc, gui); SaveExpressionParseState(); win->Parse(src, rebuild); RestoreExpressionParseState(); @@ -2241,8 +2482,8 @@ bool idWindow::Parse( idParser *src, bool rebuild) { dwt.win = win; drawWindows.Append(dwt); } - else if ( token == "bindDef" ) { - idBindWindow *win = new idBindWindow(dc, gui); + else if (token == "bindDef") { + idBindWindow* win = new idBindWindow(dc, gui); SaveExpressionParseState(); win->Parse(src, rebuild); RestoreExpressionParseState(); @@ -2252,8 +2493,8 @@ bool idWindow::Parse( idParser *src, bool rebuild) { dwt.win = win; drawWindows.Append(dwt); } - else if ( token == "listDef" ) { - idListWindow *win = new idListWindow(dc, gui); + else if (token == "listDef") { + idListWindow* win = new idListWindow(dc, gui); SaveExpressionParseState(); win->Parse(src, rebuild); RestoreExpressionParseState(); @@ -2263,8 +2504,8 @@ bool idWindow::Parse( idParser *src, bool rebuild) { dwt.win = win; drawWindows.Append(dwt); } - else if ( token == "fieldDef" ) { - idFieldWindow *win = new idFieldWindow(dc, gui); + else if (token == "fieldDef") { + idFieldWindow* win = new idFieldWindow(dc, gui); SaveExpressionParseState(); win->Parse(src, rebuild); RestoreExpressionParseState(); @@ -2274,8 +2515,8 @@ bool idWindow::Parse( idParser *src, bool rebuild) { dwt.win = win; drawWindows.Append(dwt); } - else if ( token == "renderDef" ) { - idRenderWindow *win = new idRenderWindow(dc, gui); + else if (token == "renderDef") { + idRenderWindow* win = new idRenderWindow(dc, gui); SaveExpressionParseState(); win->Parse(src, rebuild); RestoreExpressionParseState(); @@ -2285,55 +2526,64 @@ bool idWindow::Parse( idParser *src, bool rebuild) { dwt.win = win; drawWindows.Append(dwt); } -// -// added new onEvent - else if ( token == "onNamedEvent" ) { + // + // added new onEvent + else if (token == "onNamedEvent") { // Read the event name - if ( !src->ReadToken(&token) ) { - src->Error( "Expected event name" ); + if (!src->ReadToken(&token)) { + src->Error("Expected event name"); return false; } - rvNamedEvent* ev = new rvNamedEvent ( token ); + rvNamedEvent* ev = new rvNamedEvent(token); - src->SetMarker ( ); + src->SetMarker(); - if ( !ParseScript ( src, *ev->mEvent ) ) { + if (!ParseScript(src, *ev->mEvent)) { ret = false; break; } - // If we are in the gui editor then add the internal var to the + // If we are in the gui editor then add the internal var to the // the wrapper #ifdef ID_ALLOW_TOOLS - if ( com_editors & EDITOR_GUI ) { + if (com_editors & EDITOR_GUI) { idStr str; idStr out; // Grab the string from the last marker - src->GetStringFromMarker ( str, false ); + src->GetStringFromMarker(str, false); // Parse it one more time to knock unwanted tabs out - idLexer src2( str, str.Length(), "", src->GetFlags() ); - src2.ParseBracedSectionExact ( out, 1); + idLexer src2(str, str.Length(), "", src->GetFlags()); + src2.ParseBracedSectionExact(out, 1); - // Save the script - rvGEWindowWrapper::GetWrapper ( this )->GetScriptDict().Set ( va("onEvent %s", token.c_str()), out ); + // Save the script + rvGEWindowWrapper::GetWrapper(this)->GetScriptDict().Set(va("onEvent %s", token.c_str()), out); } -#endif +#endif namedEvents.Append(ev); } - else if ( token == "onTime" ) { - idTimeLineEvent *ev = new idTimeLineEvent; + else if (token == "onTime") { + idTimeLineEvent* ev = new idTimeLineEvent; - if ( !src->ReadToken(&token) ) { - src->Error( "Unexpected end of file" ); + if (!src->ReadToken(&token)) { + src->Error("Unexpected end of file"); return false; } + + if (token == "+") + { + if (!src->ReadToken(&token)) { + src->Error("Unexpected end of file"); + return false; + } + } + ev->time = atoi(token.c_str()); // reset the mark since we dont want it to include the time - src->SetMarker ( ); + src->SetMarker(); if (!ParseScript(src, *ev->event, &ev->time)) { ret = false; @@ -2341,156 +2591,157 @@ bool idWindow::Parse( idParser *src, bool rebuild) { } // add the script to the wrappers script list - // If we are in the gui editor then add the internal var to the + // If we are in the gui editor then add the internal var to the // the wrapper #ifdef ID_ALLOW_TOOLS - if ( com_editors & EDITOR_GUI ) { + if (com_editors & EDITOR_GUI) { idStr str; idStr out; // Grab the string from the last marker - src->GetStringFromMarker ( str, false ); + src->GetStringFromMarker(str, false); // Parse it one more time to knock unwanted tabs out - idLexer src2( str, str.Length(), "", src->GetFlags() ); - src2.ParseBracedSectionExact ( out, 1); + idLexer src2(str, str.Length(), "", src->GetFlags()); + src2.ParseBracedSectionExact(out, 1); - // Save the script - rvGEWindowWrapper::GetWrapper ( this )->GetScriptDict().Set ( va("onTime %d", ev->time), out ); + // Save the script + rvGEWindowWrapper::GetWrapper(this)->GetScriptDict().Set(va("onTime %d", ev->time), out); } #endif // this is a timeline event ev->pending = true; timeLineEvents.Append(ev); } - else if ( token == "definefloat" ) { + else if (token == "definefloat") { src->ReadToken(&token); work = token; work.ToLower(); - idWinFloat *varf = new idWinFloat(); + idWinFloat* varf = new idWinFloat(); varf->SetName(work); definedVars.Append(varf); // add the float to the editors wrapper dict // Set the marker after the float name - src->SetMarker ( ); + src->SetMarker(); - // Read in the float + // Read in the float regList.AddReg(work, idRegister::FLOAT, src, this, varf); // If we are in the gui editor then add the float to the defines #ifdef ID_ALLOW_TOOLS - if ( com_editors & EDITOR_GUI ) { + if (com_editors & EDITOR_GUI) { idStr str; // Grab the string from the last marker and save it in the wrapper - src->GetStringFromMarker ( str, true ); - rvGEWindowWrapper::GetWrapper ( this )->GetVariableDict().Set ( va("definefloat\t\"%s\"",token.c_str()), str ); + src->GetStringFromMarker(str, true); + rvGEWindowWrapper::GetWrapper(this)->GetVariableDict().Set(va("definefloat\t\"%s\"", token.c_str()), str); } #endif } - else if ( token == "definevec4" ) { + else if (token == "definevec4") { src->ReadToken(&token); work = token; work.ToLower(); - idWinVec4 *var = new idWinVec4(); + idWinVec4* var = new idWinVec4(); var->SetName(work); // set the marker so we can determine what was parsed // set the marker after the vec4 name - src->SetMarker ( ); + src->SetMarker(); // FIXME: how about we add the var to the desktop instead of this window so it won't get deleted // when this window is destoyed which even happens during parsing with simple windows ? //definedVars.Append(var); - gui->GetDesktop()->definedVars.Append( var ); - gui->GetDesktop()->regList.AddReg( work, idRegister::VEC4, src, gui->GetDesktop(), var ); + gui->GetDesktop()->definedVars.Append(var); + gui->GetDesktop()->regList.AddReg(work, idRegister::VEC4, src, gui->GetDesktop(), var); // store the original vec4 for the editor // If we are in the gui editor then add the float to the defines #ifdef ID_ALLOW_TOOLS - if ( com_editors & EDITOR_GUI ) { + if (com_editors & EDITOR_GUI) { idStr str; // Grab the string from the last marker and save it in the wrapper - src->GetStringFromMarker ( str, true ); - rvGEWindowWrapper::GetWrapper ( this )->GetVariableDict().Set ( va("definevec4\t\"%s\"",token.c_str()), str ); + src->GetStringFromMarker(str, true); + rvGEWindowWrapper::GetWrapper(this)->GetVariableDict().Set(va("definevec4\t\"%s\"", token.c_str()), str); } #endif } - else if ( token == "float" ) { + else if (token == "float") { src->ReadToken(&token); work = token; work.ToLower(); - idWinFloat *varf = new idWinFloat(); + idWinFloat* varf = new idWinFloat(); varf->SetName(work); definedVars.Append(varf); // add the float to the editors wrapper dict // set the marker to after the float name - src->SetMarker ( ); + src->SetMarker(); // Parse the float regList.AddReg(work, idRegister::FLOAT, src, this, varf); // If we are in the gui editor then add the float to the defines #ifdef ID_ALLOW_TOOLS - if ( com_editors & EDITOR_GUI ) { + if (com_editors & EDITOR_GUI) { idStr str; // Grab the string from the last marker and save it in the wrapper - src->GetStringFromMarker ( str, true ); - rvGEWindowWrapper::GetWrapper ( this )->GetVariableDict().Set ( va("float\t\"%s\"",token.c_str()), str ); + src->GetStringFromMarker(str, true); + rvGEWindowWrapper::GetWrapper(this)->GetVariableDict().Set(va("float\t\"%s\"", token.c_str()), str); } #endif } else if (ParseScriptEntry(token, src)) { // add the script to the wrappers script list - // If we are in the gui editor then add the internal var to the + // If we are in the gui editor then add the internal var to the // the wrapper #ifdef ID_ALLOW_TOOLS - if ( com_editors & EDITOR_GUI ) { + if (com_editors & EDITOR_GUI) { idStr str; idStr out; // Grab the string from the last marker - src->GetStringFromMarker ( str, false ); + src->GetStringFromMarker(str, false); // Parse it one more time to knock unwanted tabs out - idLexer src2( str, str.Length(), "", src->GetFlags() ); - src2.ParseBracedSectionExact ( out, 1); + idLexer src2(str, str.Length(), "", src->GetFlags()); + src2.ParseBracedSectionExact(out, 1); - // Save the script - rvGEWindowWrapper::GetWrapper ( this )->GetScriptDict().Set ( token, out ); + // Save the script + rvGEWindowWrapper::GetWrapper(this)->GetScriptDict().Set(token, out); } #endif - } else if (ParseInternalVar(token, src)) { - // gui editor support - // If we are in the gui editor then add the internal var to the + } + else if (ParseInternalVar(token, src)) { + // gui editor support + // If we are in the gui editor then add the internal var to the // the wrapper #ifdef ID_ALLOW_TOOLS - if ( com_editors & EDITOR_GUI ) { + if (com_editors & EDITOR_GUI) { idStr str; - src->GetStringFromMarker ( str ); - rvGEWindowWrapper::GetWrapper ( this )->SetStateKey ( token, str, false ); + src->GetStringFromMarker(str); + rvGEWindowWrapper::GetWrapper(this)->SetStateKey(token, str, false); } #endif } else { ParseRegEntry(token, src); // hook into the main window parsing for the gui editor - // If we are in the gui editor then add the internal var to the + // If we are in the gui editor then add the internal var to the // the wrapper #ifdef ID_ALLOW_TOOLS - if ( com_editors & EDITOR_GUI ) { + if (com_editors & EDITOR_GUI) { idStr str; - src->GetStringFromMarker ( str ); - rvGEWindowWrapper::GetWrapper ( this )->SetStateKey ( token, str, false ); + src->GetStringFromMarker(str); + rvGEWindowWrapper::GetWrapper(this)->SetStateKey(token, str, false); } #endif } - if ( !src->ReadToken( &token ) ) { - src->Error( "Unexpected end of file" ); + if (!src->ReadToken(&token)) { + src->Error("Unexpected end of file"); ret = false; break; } @@ -2504,11 +2755,11 @@ bool idWindow::Parse( idParser *src, bool rebuild) { PostParse(); // hook into the main window parsing for the gui editor - // If we are in the gui editor then add the internal var to the + // If we are in the gui editor then add the internal var to the // the wrapper #ifdef ID_ALLOW_TOOLS - if ( com_editors & EDITOR_GUI ) { - rvGEWindowWrapper::GetWrapper ( this )->Finish ( ); + if (com_editors & EDITOR_GUI) { + rvGEWindowWrapper::GetWrapper(this)->Finish(); } #endif @@ -2520,13 +2771,13 @@ bool idWindow::Parse( idParser *src, bool rebuild) { idWindow::FindSimpleWinByName ================ */ -idSimpleWindow *idWindow::FindSimpleWinByName(const char *_name) { +idSimpleWindow* idWindow::FindSimpleWinByName(const char* _name) { int c = drawWindows.Num(); for (int i = 0; i < c; i++) { if (drawWindows[i].simp == NULL) { continue; } - if ( idStr::Icmp(drawWindows[i].simp->name, _name) == 0 ) { + if (idStr::Icmp(drawWindows[i].simp->name, _name) == 0) { return drawWindows[i].simp; } } @@ -2538,38 +2789,63 @@ idSimpleWindow *idWindow::FindSimpleWinByName(const char *_name) { idWindow::FindChildByName ================ */ -drawWin_t *idWindow::FindChildByName(const char *_name) { +drawWin_t* idWindow::FindChildByName(const char* _name) { static drawWin_t dw; - if (idStr::Icmp(name,_name) == 0) { + if (idStr::Icmp(name, _name) == 0) { dw.simp = NULL; dw.win = this; return &dw; } + int c = drawWindows.Num(); - for (int i = 0; i < c; i++) { - if (drawWindows[i].win) { - if (idStr::Icmp(drawWindows[i].win->name, _name) == 0) { - return &drawWindows[i]; +#ifdef QUAKE4 + int start = startChildSearch; +#else + int start = 0; +#endif + if (start >= c) { + start = 0; + } + + for (int phase = 0; phase < 2; phase++) { + int i = (phase == 0) ? start : 0; + int end = (phase == 0) ? c : start; + for (; i < end; i++) { + if (drawWindows[i].win) { + if (idStr::Icmp(drawWindows[i].win->name, _name) == 0) { +#ifdef QUAKE4 + startChildSearch = i; +#endif + return &drawWindows[i]; + } + drawWin_t* win = drawWindows[i].win->FindChildByName(_name); + if (win) { +#ifdef QUAKE4 + startChildSearch = i; +#endif + return win; + } } - drawWin_t *win = drawWindows[i].win->FindChildByName(_name); - if (win) { - return win; - } - } else { - if (idStr::Icmp(drawWindows[i].simp->name, _name) == 0) { - return &drawWindows[i]; + else if (drawWindows[i].simp) { + if (idStr::Icmp(drawWindows[i].simp->name, _name) == 0) { +#ifdef QUAKE4 + startChildSearch = i; +#endif + return &drawWindows[i]; + } } } } return NULL; } + /* ================ idWindow::GetStrPtrByName ================ */ -idStr* idWindow::GetStrPtrByName(const char *_name) { +idStr* idWindow::GetStrPtrByName(const char* _name) { return NULL; } @@ -2578,7 +2854,7 @@ idStr* idWindow::GetStrPtrByName(const char *_name) { idWindow::AddTransition ================ */ -void idWindow::AddTransition(idWinVar *dest, idVec4 from, idVec4 to, int time, float accelTime, float decelTime) { +void idWindow::AddTransition(idWinVar* dest, idVec4 from, idVec4 to, int time, float accelTime, float decelTime) { idTransitionData data; data.data = dest; data.interp.Init(gui->GetTime(), accelTime * time, decelTime * time, time, from, to); @@ -2601,8 +2877,8 @@ idWindow::ResetCinematics ================ */ void idWindow::ResetCinematics() { - if ( background ) { - background->ResetCinematicTime( gui->GetTime() ); + if (background) { + background->ResetCinematicTime(gui->GetTime()); } } @@ -2612,37 +2888,40 @@ idWindow::ResetTime ================ */ void idWindow::ResetTime(int t) { - timeLine = gui->GetTime() - t; - int i, c = timeLineEvents.Num(); - for ( i = 0; i < c; i++ ) { - if ( timeLineEvents[i]->time >= t ) { + for (int i = 0; i < timeLineEvents.Num(); i++) { + if (timeLineEvents[i]->time >= t) { timeLineEvents[i]->pending = true; } } noTime = false; - c = transitions.Num(); - for ( i = 0; i < c; i++ ) { - idTransitionData *data = &transitions[i]; - if ( data->interp.IsDone( gui->GetTime() ) && data->data ) { - transitions.RemoveIndex( i ); + for (int i = 0; i < transitions.Num(); i++) { + idTransitionData* data = &transitions[i]; + if (data->interp.IsDone(gui->GetTime()) && data->data) { + transitions.RemoveIndex(i); +#ifdef QUAKE4 +#ifdef QUAKE4 + if (i < transitionSubs.Num()) { + transitionSubs.RemoveIndex(i); + } +#endif +#endif i--; - c--; } } - } + /* ================ idWindow::RunScriptList ================ */ -bool idWindow::RunScriptList(idGuiScriptList *src) { +bool idWindow::RunScriptList(idGuiScriptList* src) { if (src == NULL) { return false; } @@ -2670,13 +2949,13 @@ idWindow::ExpressionConstant int idWindow::ExpressionConstant(float f) { int i; - for ( i = WEXP_REG_NUM_PREDEFINED ; i < expressionRegisters.Num() ; i++ ) { - if ( !registerIsTemporary[i] && expressionRegisters[i] == f ) { + for (i = WEXP_REG_NUM_PREDEFINED; i < expressionRegisters.Num(); i++) { + if (!registerIsTemporary[i] && expressionRegisters[i] == f) { return i; } } - if ( expressionRegisters.Num() == MAX_EXPRESSION_REGISTERS ) { - common->Warning( "expressionConstant: gui %s hit MAX_EXPRESSION_REGISTERS", gui->GetSourceFile() ); + if (expressionRegisters.Num() == MAX_EXPRESSION_REGISTERS) { + common->Warning("expressionConstant: gui %s hit MAX_EXPRESSION_REGISTERS", gui->GetSourceFile()); return 0; } @@ -2699,8 +2978,8 @@ idWindow::ExpressionTemporary ================ */ int idWindow::ExpressionTemporary() { - if ( expressionRegisters.Num() == MAX_EXPRESSION_REGISTERS ) { - common->Warning( "expressionTemporary: gui %s hit MAX_EXPRESSION_REGISTERS", gui->GetSourceFile()); + if (expressionRegisters.Num() == MAX_EXPRESSION_REGISTERS) { + common->Warning("expressionTemporary: gui %s hit MAX_EXPRESSION_REGISTERS", gui->GetSourceFile()); return 0; } int i = expressionRegisters.Num(); @@ -2714,9 +2993,9 @@ int idWindow::ExpressionTemporary() { idWindow::ExpressionOp ================ */ -wexpOp_t *idWindow::ExpressionOp() { - if ( ops.Num() == MAX_EXPRESSION_OPS ) { - common->Warning( "expressionOp: gui %s hit MAX_EXPRESSION_OPS", gui->GetSourceFile()); +wexpOp_t* idWindow::ExpressionOp() { + if (ops.Num() == MAX_EXPRESSION_OPS) { + common->Warning("expressionOp: gui %s hit MAX_EXPRESSION_OPS", gui->GetSourceFile()); return &ops[0]; } wexpOp_t wop; @@ -2731,39 +3010,39 @@ idWindow::EmitOp ================ */ -intptr_t idWindow::EmitOp( intptr_t a, intptr_t b, wexpOpType_t opType, wexpOp_t **opp ) { - wexpOp_t *op; -/* - // optimize away identity operations - if ( opType == WOP_TYPE_ADD ) { - if ( !registerIsTemporary[a] && shaderRegisters[a] == 0 ) { - return b; +intptr_t idWindow::EmitOp(intptr_t a, intptr_t b, wexpOpType_t opType, wexpOp_t** opp) { + wexpOp_t* op; + /* + // optimize away identity operations + if ( opType == WOP_TYPE_ADD ) { + if ( !registerIsTemporary[a] && shaderRegisters[a] == 0 ) { + return b; + } + if ( !registerIsTemporary[b] && shaderRegisters[b] == 0 ) { + return a; + } + if ( !registerIsTemporary[a] && !registerIsTemporary[b] ) { + return ExpressionConstant( shaderRegisters[a] + shaderRegisters[b] ); + } } - if ( !registerIsTemporary[b] && shaderRegisters[b] == 0 ) { - return a; + if ( opType == WOP_TYPE_MULTIPLY ) { + if ( !registerIsTemporary[a] && shaderRegisters[a] == 1 ) { + return b; + } + if ( !registerIsTemporary[a] && shaderRegisters[a] == 0 ) { + return a; + } + if ( !registerIsTemporary[b] && shaderRegisters[b] == 1 ) { + return a; + } + if ( !registerIsTemporary[b] && shaderRegisters[b] == 0 ) { + return b; + } + if ( !registerIsTemporary[a] && !registerIsTemporary[b] ) { + return ExpressionConstant( shaderRegisters[a] * shaderRegisters[b] ); + } } - if ( !registerIsTemporary[a] && !registerIsTemporary[b] ) { - return ExpressionConstant( shaderRegisters[a] + shaderRegisters[b] ); - } - } - if ( opType == WOP_TYPE_MULTIPLY ) { - if ( !registerIsTemporary[a] && shaderRegisters[a] == 1 ) { - return b; - } - if ( !registerIsTemporary[a] && shaderRegisters[a] == 0 ) { - return a; - } - if ( !registerIsTemporary[b] && shaderRegisters[b] == 1 ) { - return a; - } - if ( !registerIsTemporary[b] && shaderRegisters[b] == 0 ) { - return b; - } - if ( !registerIsTemporary[a] && !registerIsTemporary[b] ) { - return ExpressionConstant( shaderRegisters[a] * shaderRegisters[b] ); - } - } -*/ + */ op = ExpressionOp(); op->opType = opType; @@ -2782,9 +3061,9 @@ intptr_t idWindow::EmitOp( intptr_t a, intptr_t b, wexpOpType_t opType, wexpOp_t idWindow::ParseEmitOp ================ */ -intptr_t idWindow::ParseEmitOp( idParser *src, intptr_t a, wexpOpType_t opType, int priority, wexpOp_t **opp ) { - intptr_t b = ParseExpressionPriority( src, priority ); - return EmitOp( a, b, opType, opp ); +intptr_t idWindow::ParseEmitOp(idParser* src, intptr_t a, wexpOpType_t opType, int priority, wexpOp_t** opp) { + intptr_t b = ParseExpressionPriority(src, priority); + return EmitOp(a, b, opType, opp); } @@ -2795,45 +3074,43 @@ idWindow::ParseTerm Returns a register index ================= */ -intptr_t idWindow::ParseTerm( idParser *src, idWinVar *var, intptr_t component ) { +intptr_t idWindow::ParseTerm(idParser* src, idWinVar* var, intptr_t component) { idToken token; - intptr_t a, b; + intptr_t a, b; - src->ReadToken( &token ); + src->ReadToken(&token); - if ( token == "(" ) { - a = ParseExpression( src ); + if (token == "(") { + a = ParseExpression(src); src->ExpectTokenString(")"); return a; } - if ( !token.Icmp( "time" ) ) { + if (!token.Icmp("time")) { return WEXP_REG_TIME; } // parse negative numbers - if ( token == "-" ) { - src->ReadToken( &token ); - if ( token.type == TT_NUMBER || token == "." ) { - return ExpressionConstant( -(float) token.GetFloatValue() ); + if (token == "-") { + src->ReadToken(&token); + if (token.type == TT_NUMBER || token == ".") { + return ExpressionConstant(-(float)token.GetFloatValue()); } - src->Warning( "Bad negative number '%s'", token.c_str() ); + src->Warning("Bad negative number '%s'", token.c_str()); return 0; } - if ( token.type == TT_NUMBER || token == "." || token == "-" ) { - return ExpressionConstant( (float) token.GetFloatValue() ); + if (token.type == TT_NUMBER || token == "." || token == "-") { + return ExpressionConstant((float)token.GetFloatValue()); } - // see if it is a table name - const idDeclTable *table = static_cast( declManager->FindType( DECL_TABLE, token.c_str(), false ) ); - if ( table ) { + const idDeclTable* table = static_cast(declManager->FindType(DECL_TABLE, token.c_str(), false)); + if (table) { a = table->Index(); - // parse a table expression src->ExpectTokenString("["); b = ParseExpression(src); src->ExpectTokenString("]"); - return EmitOp( a, b, WOP_TYPE_TABLE ); + return EmitOp(a, b, WOP_TYPE_TABLE); } if (var == NULL) { @@ -2841,7 +3118,6 @@ intptr_t idWindow::ParseTerm( idParser *src, idWinVar *var, intptr_t component ) } if (var) { a = (intptr_t)var; - //assert(dynamic_cast(var)); var->Init(token, this); b = component; if (dynamic_cast(var)) { @@ -2849,34 +3125,45 @@ intptr_t idWindow::ParseTerm( idParser *src, idWinVar *var, intptr_t component ) if (token == "[") { b = ParseExpression(src); src->ExpectTokenString("]"); - } else { + } + else { src->UnreadToken(&token); } } return EmitOp(a, b, WOP_TYPE_VAR); - } else if (dynamic_cast(var)) { + } + else if (dynamic_cast(var)) { return EmitOp(a, b, WOP_TYPE_VARF); - } else if (dynamic_cast(var)) { + } +#ifdef QUAKE4 + else if (dynamic_cast(var)) { + return EmitOp(a, b, WOP_TYPE_VARFM); + } +#endif + else if (dynamic_cast(var)) { return EmitOp(a, b, WOP_TYPE_VARI); - } else if (dynamic_cast(var)) { + } + else if (dynamic_cast(var)) { return EmitOp(a, b, WOP_TYPE_VARB); - } else if (dynamic_cast(var)) { + } + else if (dynamic_cast(var)) { return EmitOp(a, b, WOP_TYPE_VARS); - } else { + } + else { src->Warning("Var expression not vec4, float or int '%s'", token.c_str()); } return 0; - } else { - // ugly but used for post parsing to fixup named vars - char *p = new char[token.Length()+1]; + } + else { + char* p = new char[token.Length() + 1]; strcpy(p, token); a = (intptr_t)p; b = -2; return EmitOp(a, b, WOP_TYPE_VAR); } - } + /* ================= idWindow::ParseExpressionPriority @@ -2885,69 +3172,69 @@ Returns a register index ================= */ #define TOP_PRIORITY 4 -intptr_t idWindow::ParseExpressionPriority( idParser *src, int priority, idWinVar *var, intptr_t component ) { +intptr_t idWindow::ParseExpressionPriority(idParser* src, int priority, idWinVar* var, intptr_t component) { idToken token; - intptr_t a; + intptr_t a; - if ( priority == 0 ) { - return ParseTerm( src, var, component ); + if (priority == 0) { + return ParseTerm(src, var, component); } - a = ParseExpressionPriority( src, priority - 1, var, component ); + a = ParseExpressionPriority(src, priority - 1, var, component); - if ( !src->ReadToken( &token ) ) { + if (!src->ReadToken(&token)) { // we won't get EOF in a real file, but we can // when parsing from generated strings return a; } - if ( priority == 1 && token == "*" ) { - return ParseEmitOp( src, a, WOP_TYPE_MULTIPLY, priority ); + if (priority == 1 && token == "*") { + return ParseEmitOp(src, a, WOP_TYPE_MULTIPLY, priority); } - if ( priority == 1 && token == "/" ) { - return ParseEmitOp( src, a, WOP_TYPE_DIVIDE, priority ); + if (priority == 1 && token == "/") { + return ParseEmitOp(src, a, WOP_TYPE_DIVIDE, priority); } - if ( priority == 1 && token == "%" ) { // implied truncate both to integer - return ParseEmitOp( src, a, WOP_TYPE_MOD, priority ); + if (priority == 1 && token == "%") { // implied truncate both to integer + return ParseEmitOp(src, a, WOP_TYPE_MOD, priority); } - if ( priority == 2 && token == "+" ) { - return ParseEmitOp( src, a, WOP_TYPE_ADD, priority ); + if (priority == 2 && token == "+") { + return ParseEmitOp(src, a, WOP_TYPE_ADD, priority); } - if ( priority == 2 && token == "-" ) { - return ParseEmitOp( src, a, WOP_TYPE_SUBTRACT, priority ); + if (priority == 2 && token == "-") { + return ParseEmitOp(src, a, WOP_TYPE_SUBTRACT, priority); } - if ( priority == 3 && token == ">" ) { - return ParseEmitOp( src, a, WOP_TYPE_GT, priority ); + if (priority == 3 && token == ">") { + return ParseEmitOp(src, a, WOP_TYPE_GT, priority); } - if ( priority == 3 && token == ">=" ) { - return ParseEmitOp( src, a, WOP_TYPE_GE, priority ); + if (priority == 3 && token == ">=") { + return ParseEmitOp(src, a, WOP_TYPE_GE, priority); } - if ( priority == 3 && token == "<" ) { - return ParseEmitOp( src, a, WOP_TYPE_LT, priority ); + if (priority == 3 && token == "<") { + return ParseEmitOp(src, a, WOP_TYPE_LT, priority); } - if ( priority == 3 && token == "<=" ) { - return ParseEmitOp( src, a, WOP_TYPE_LE, priority ); + if (priority == 3 && token == "<=") { + return ParseEmitOp(src, a, WOP_TYPE_LE, priority); } - if ( priority == 3 && token == "==" ) { - return ParseEmitOp( src, a, WOP_TYPE_EQ, priority ); + if (priority == 3 && token == "==") { + return ParseEmitOp(src, a, WOP_TYPE_EQ, priority); } - if ( priority == 3 && token == "!=" ) { - return ParseEmitOp( src, a, WOP_TYPE_NE, priority ); + if (priority == 3 && token == "!=") { + return ParseEmitOp(src, a, WOP_TYPE_NE, priority); } - if ( priority == 4 && token == "&&" ) { - return ParseEmitOp( src, a, WOP_TYPE_AND, priority ); + if (priority == 4 && token == "&&") { + return ParseEmitOp(src, a, WOP_TYPE_AND, priority); } - if ( priority == 4 && token == "||" ) { - return ParseEmitOp( src, a, WOP_TYPE_OR, priority ); + if (priority == 4 && token == "||") { + return ParseEmitOp(src, a, WOP_TYPE_OR, priority); } - if ( priority == 4 && token == "?" ) { - wexpOp_t *oop = NULL; - intptr_t o = ParseEmitOp( src, a, WOP_TYPE_COND, priority, &oop ); - if ( !src->ReadToken( &token ) ) { + if (priority == 4 && token == "?") { + wexpOp_t* oop = NULL; + intptr_t o = ParseEmitOp(src, a, WOP_TYPE_COND, priority, &oop); + if (!src->ReadToken(&token)) { return o; } if (token == ":") { - a = ParseExpressionPriority( src, priority - 1, var ); + a = ParseExpressionPriority(src, priority - 1, var); oop->d = a; } return o; @@ -2956,7 +3243,7 @@ intptr_t idWindow::ParseExpressionPriority( idParser *src, int priority, idWinVa // assume that anything else terminates the expression // not too robust error checking... - src->UnreadToken( &token ); + src->UnreadToken(&token); return a; } @@ -2968,8 +3255,8 @@ idWindow::ParseExpression Returns a register index ================ */ -intptr_t idWindow::ParseExpression(idParser *src, idWinVar *var, intptr_t component) { - return ParseExpressionPriority( src, TOP_PRIORITY, var ); +intptr_t idWindow::ParseExpression(idParser* src, idWinVar* var, intptr_t component) { + return ParseExpressionPriority(src, TOP_PRIORITY, var); } /* @@ -2977,7 +3264,7 @@ intptr_t idWindow::ParseExpression(idParser *src, idWinVar *var, intptr_t compon idWindow::ParseBracedExpression ================ */ -void idWindow::ParseBracedExpression(idParser *src) { +void idWindow::ParseBracedExpression(idParser* src) { src->ExpectTokenString("{"); ParseExpression(src); src->ExpectTokenString("}"); @@ -2992,27 +3279,27 @@ then all expressions are evaluated, leaving the shader registers set to their apropriate values. =============== */ -void idWindow::EvaluateRegisters(float *registers) { +void idWindow::EvaluateRegisters(float* registers) { int i, b; - wexpOp_t *op; + wexpOp_t* op; idVec4 v; int erc = expressionRegisters.Num(); int oc = ops.Num(); // copy the constants - for ( i = WEXP_REG_NUM_PREDEFINED ; i < erc ; i++ ) { + for (i = WEXP_REG_NUM_PREDEFINED; i < erc; i++) { registers[i] = expressionRegisters[i]; } // copy the local and global parameters registers[WEXP_REG_TIME] = gui->GetTime(); - for ( i = 0 ; i < oc ; i++ ) { + for (i = 0; i < oc; i++) { op = &ops[i]; if (op->b == -2) { continue; } - switch( op->opType ) { + switch (op->opType) { case WOP_TYPE_ADD: registers[op->c] = registers[op->a] + registers[op->b]; break; @@ -3023,10 +3310,11 @@ void idWindow::EvaluateRegisters(float *registers) { registers[op->c] = registers[op->a] * registers[op->b]; break; case WOP_TYPE_DIVIDE: - if ( registers[op->b] == 0.0f ) { - common->Warning( "Divide by zero in window '%s' in %s", GetName(), gui->GetSourceFile() ); + if (registers[op->b] == 0.0f) { + common->Warning("Divide by zero in window '%s' in %s", GetName(), gui->GetSourceFile()); registers[op->c] = registers[op->a]; - } else { + } + else { registers[op->c] = registers[op->a] / registers[op->b]; } break; @@ -3036,85 +3324,101 @@ void idWindow::EvaluateRegisters(float *registers) { registers[op->c] = (int)registers[op->a] % b; break; case WOP_TYPE_TABLE: - { - const idDeclTable *table = static_cast( declManager->DeclByIndex( DECL_TABLE, op->a ) ); - registers[op->c] = table->TableLookup( registers[op->b] ); - } - break; + { + const idDeclTable* table = static_cast(declManager->DeclByIndex(DECL_TABLE, op->a)); + registers[op->c] = table->TableLookup(registers[op->b]); + } + break; case WOP_TYPE_GT: - registers[op->c] = registers[ op->a ] > registers[op->b]; + registers[op->c] = registers[op->a] > registers[op->b]; break; case WOP_TYPE_GE: - registers[op->c] = registers[ op->a ] >= registers[op->b]; + registers[op->c] = registers[op->a] >= registers[op->b]; break; case WOP_TYPE_LT: - registers[op->c] = registers[ op->a ] < registers[op->b]; + registers[op->c] = registers[op->a] < registers[op->b]; break; case WOP_TYPE_LE: - registers[op->c] = registers[ op->a ] <= registers[op->b]; + registers[op->c] = registers[op->a] <= registers[op->b]; break; case WOP_TYPE_EQ: - registers[op->c] = registers[ op->a ] == registers[op->b]; + registers[op->c] = registers[op->a] == registers[op->b]; break; case WOP_TYPE_NE: - registers[op->c] = registers[ op->a ] != registers[op->b]; + registers[op->c] = registers[op->a] != registers[op->b]; break; case WOP_TYPE_COND: - registers[op->c] = (registers[ op->a ]) ? registers[op->b] : registers[op->d]; + registers[op->c] = (registers[op->a]) ? registers[op->b] : registers[op->d]; break; case WOP_TYPE_AND: - registers[op->c] = registers[ op->a ] && registers[op->b]; + registers[op->c] = registers[op->a] && registers[op->b]; break; case WOP_TYPE_OR: - registers[op->c] = registers[ op->a ] || registers[op->b]; + registers[op->c] = registers[op->a] || registers[op->b]; break; case WOP_TYPE_VAR: - if ( !op->a ) { + if (!op->a) { registers[op->c] = 0.0f; break; } - if ( op->b >= 0 && registers[op->b] >= 0 && registers[op->b] < 4 ) { + if (op->b >= 0 && registers[op->b] >= 0 && registers[op->b] < 4) { // grabs vector components - idWinVec4 *var = (idWinVec4 *)( op->a ); + idWinVec4* var = (idWinVec4*)(op->a); registers[op->c] = ((idVec4&)var)[registers[op->b]]; - } else { + } + else { registers[op->c] = ((idWinVar*)(op->a))->x(); } break; case WOP_TYPE_VARS: if (op->a) { - idWinStr *var = (idWinStr*)(op->a); + idWinStr* var = (idWinStr*)(op->a); registers[op->c] = atof(var->c_str()); - } else { + } + else { registers[op->c] = 0; } break; case WOP_TYPE_VARF: if (op->a) { - idWinFloat *var = (idWinFloat*)(op->a); + idWinFloat* var = (idWinFloat*)(op->a); registers[op->c] = *var; - } else { + } + else { registers[op->c] = 0; } break; +#ifdef QUAKE4 + case WOP_TYPE_VARFM: + if (op->a) { + idWinFloatMember* var = (idWinFloatMember*)(op->a); + registers[op->c] = var->x(); + } + else { + registers[op->c] = 0; + } + break; +#endif case WOP_TYPE_VARI: if (op->a) { - idWinInt *var = (idWinInt*)(op->a); + idWinInt* var = (idWinInt*)(op->a); registers[op->c] = *var; - } else { + } + else { registers[op->c] = 0; } break; case WOP_TYPE_VARB: if (op->a) { - idWinBool *var = (idWinBool*)(op->a); + idWinBool* var = (idWinBool*)(op->a); registers[op->c] = *var; - } else { + } + else { registers[op->c] = 0; } break; default: - common->FatalError( "R_EvaluateExpression: bad opcode" ); + common->FatalError("R_EvaluateExpression: bad opcode"); } } @@ -3125,11 +3429,11 @@ void idWindow::EvaluateRegisters(float *registers) { idWindow::ReadFromDemoFile ================ */ -void idWindow::ReadFromDemoFile( class idDemoFile *f, bool rebuild ) { +void idWindow::ReadFromDemoFile(class idDemoFile* f, bool rebuild) { // should never hit unless we re-enable WRITE_GUIS #ifndef WRITE_GUIS - assert( false ); + assert(false); #else if (rebuild) { @@ -3139,34 +3443,35 @@ void idWindow::ReadFromDemoFile( class idDemoFile *f, bool rebuild ) { f->SetLog(true, "window1"); backGroundName = f->ReadHashString(); f->SetLog(true, backGroundName); - if ( backGroundName[0] ) { + if (backGroundName[0]) { background = declManager->FindMaterial(backGroundName); - } else { + } + else { background = NULL; } - f->ReadUnsignedChar( cursor ); - f->ReadUnsignedInt( flags ); - f->ReadInt( timeLine ); - f->ReadInt( lastTimeRun ); + f->ReadUnsignedChar(cursor); + f->ReadUnsignedInt(flags); + f->ReadInt(timeLine); + f->ReadInt(lastTimeRun); idRectangle rct = rect; - f->ReadFloat( rct.x ); - f->ReadFloat( rct.y ); - f->ReadFloat( rct.w ); - f->ReadFloat( rct.h ); - f->ReadFloat( drawRect.x ); - f->ReadFloat( drawRect.y ); - f->ReadFloat( drawRect.w ); - f->ReadFloat( drawRect.h ); - f->ReadFloat( clientRect.x ); - f->ReadFloat( clientRect.y ); - f->ReadFloat( clientRect.w ); - f->ReadFloat( clientRect.h ); - f->ReadFloat( textRect.x ); - f->ReadFloat( textRect.y ); - f->ReadFloat( textRect.w ); - f->ReadFloat( textRect.h ); - f->ReadFloat( xOffset); - f->ReadFloat( yOffset); + f->ReadFloat(rct.x); + f->ReadFloat(rct.y); + f->ReadFloat(rct.w); + f->ReadFloat(rct.h); + f->ReadFloat(drawRect.x); + f->ReadFloat(drawRect.y); + f->ReadFloat(drawRect.w); + f->ReadFloat(drawRect.h); + f->ReadFloat(clientRect.x); + f->ReadFloat(clientRect.y); + f->ReadFloat(clientRect.w); + f->ReadFloat(clientRect.h); + f->ReadFloat(textRect.x); + f->ReadFloat(textRect.y); + f->ReadFloat(textRect.w); + f->ReadFloat(textRect.h); + f->ReadFloat(xOffset); + f->ReadFloat(yOffset); int i, c; idStr work; @@ -3174,7 +3479,7 @@ void idWindow::ReadFromDemoFile( class idDemoFile *f, bool rebuild ) { f->SetLog(true, (work + "-scripts")); for (i = 0; i < SCRIPT_COUNT; i++) { bool b; - f->ReadBool( b ); + f->ReadBool(b); if (b) { delete scripts[i]; scripts[i] = new idGuiScriptList; @@ -3183,15 +3488,16 @@ void idWindow::ReadFromDemoFile( class idDemoFile *f, bool rebuild ) { } f->SetLog(true, (work + "-timelines")); - f->ReadInt( c ); + f->ReadInt(c); for (i = 0; i < c; i++) { - idTimeLineEvent *tl = new idTimeLineEvent; - f->ReadInt( tl->time ); - f->ReadBool( tl->pending ); + idTimeLineEvent* tl = new idTimeLineEvent; + f->ReadInt(tl->time); + f->ReadBool(tl->pending); tl->event->ReadFromDemoFile(f); if (rebuild) { timeLineEvents.Append(tl); - } else { + } + else { assert(i < timeLineEvents.Num()); timeLineEvents[i]->time = tl->time; timeLineEvents[i]->pending = tl->pending; @@ -3200,21 +3506,21 @@ void idWindow::ReadFromDemoFile( class idDemoFile *f, bool rebuild ) { } f->SetLog(true, (work + "-transitions")); - f->ReadInt( c ); + f->ReadInt(c); for (i = 0; i < c; i++) { idTransitionData td; td.data = NULL; - f->ReadInt ( td.offset ); + f->ReadInt(td.offset); float startTime, accelTime, linearTime, decelTime; idVec4 startValue, endValue; - f->ReadFloat( startTime ); - f->ReadFloat( accelTime ); - f->ReadFloat( linearTime ); - f->ReadFloat( decelTime ); - f->ReadVec4( startValue ); - f->ReadVec4( endValue ); - td.interp.Init( startTime, accelTime, decelTime, accelTime + linearTime + decelTime, startValue, endValue ); + f->ReadFloat(startTime); + f->ReadFloat(accelTime); + f->ReadFloat(linearTime); + f->ReadFloat(decelTime); + f->ReadVec4(startValue); + f->ReadVec4(endValue); + td.interp.Init(startTime, accelTime, decelTime, accelTime + linearTime + decelTime, startValue, endValue); // read this for correct data padding with the win32 savegames // the extrapolate is correctly initialized through the above Init call @@ -3223,35 +3529,35 @@ void idWindow::ReadFromDemoFile( class idDemoFile *f, bool rebuild ) { idVec4 baseSpeed, speed; float currentTime; idVec4 currentValue; - f->ReadInt( extrapolationType ); - f->ReadFloat( startTime ); - f->ReadFloat( duration ); - f->ReadVec4( startValue ); - f->ReadVec4( baseSpeed ); - f->ReadVec4( speed ); - f->ReadFloat( currentTime ); - f->ReadVec4( currentValue ); + f->ReadInt(extrapolationType); + f->ReadFloat(startTime); + f->ReadFloat(duration); + f->ReadVec4(startValue); + f->ReadVec4(baseSpeed); + f->ReadVec4(speed); + f->ReadFloat(currentTime); + f->ReadVec4(currentValue); transitions.Append(td); } f->SetLog(true, (work + "-regstuff")); if (rebuild) { - f->ReadInt( c ); + f->ReadInt(c); for (i = 0; i < c; i++) { wexpOp_t w; - f->ReadInt( (int&)w.opType ); - f->ReadInt( w.a ); - f->ReadInt( w.b ); - f->ReadInt( w.c ); - f->ReadInt( w.d ); + f->ReadInt((int&)w.opType); + f->ReadInt(w.a); + f->ReadInt(w.b); + f->ReadInt(w.c); + f->ReadInt(w.d); ops.Append(w); } - f->ReadInt( c ); + f->ReadInt(c); for (i = 0; i < c; i++) { float ff; - f->ReadFloat( ff ); + f->ReadFloat(ff); expressionRegisters.Append(ff); } @@ -3259,18 +3565,20 @@ void idWindow::ReadFromDemoFile( class idDemoFile *f, bool rebuild ) { } f->SetLog(true, (work + "-children")); - f->ReadInt( c ); + f->ReadInt(c); for (i = 0; i < c; i++) { if (rebuild) { - idWindow *win = new idWindow(dc, gui); + idWindow* win = new idWindow(dc, gui); win->ReadFromDemoFile(f); AddChild(win); - } else { + } + else { for (int j = 0; j < c; j++) { if (children[j]->childID == i) { - children[j]->ReadFromDemoFile(f,rebuild); + children[j]->ReadFromDemoFile(f, rebuild); break; - } else { + } + else { continue; } } @@ -3284,38 +3592,38 @@ void idWindow::ReadFromDemoFile( class idDemoFile *f, bool rebuild ) { idWindow::WriteToDemoFile ================ */ -void idWindow::WriteToDemoFile( class idDemoFile *f ) { +void idWindow::WriteToDemoFile(class idDemoFile* f) { // should never hit unless we re-enable WRITE_GUIS #ifndef WRITE_GUIS - assert( false ); + assert(false); #else f->SetLog(true, "window"); f->WriteHashString(backGroundName); f->SetLog(true, backGroundName); - f->WriteUnsignedChar( cursor ); - f->WriteUnsignedInt( flags ); - f->WriteInt( timeLine ); - f->WriteInt( lastTimeRun ); + f->WriteUnsignedChar(cursor); + f->WriteUnsignedInt(flags); + f->WriteInt(timeLine); + f->WriteInt(lastTimeRun); idRectangle rct = rect; - f->WriteFloat( rct.x ); - f->WriteFloat( rct.y ); - f->WriteFloat( rct.w ); - f->WriteFloat( rct.h ); - f->WriteFloat( drawRect.x ); - f->WriteFloat( drawRect.y ); - f->WriteFloat( drawRect.w ); - f->WriteFloat( drawRect.h ); - f->WriteFloat( clientRect.x ); - f->WriteFloat( clientRect.y ); - f->WriteFloat( clientRect.w ); - f->WriteFloat( clientRect.h ); - f->WriteFloat( textRect.x ); - f->WriteFloat( textRect.y ); - f->WriteFloat( textRect.w ); - f->WriteFloat( textRect.h ); - f->WriteFloat( xOffset ); - f->WriteFloat( yOffset ); + f->WriteFloat(rct.x); + f->WriteFloat(rct.y); + f->WriteFloat(rct.w); + f->WriteFloat(rct.h); + f->WriteFloat(drawRect.x); + f->WriteFloat(drawRect.y); + f->WriteFloat(drawRect.w); + f->WriteFloat(drawRect.h); + f->WriteFloat(clientRect.x); + f->WriteFloat(clientRect.y); + f->WriteFloat(clientRect.w); + f->WriteFloat(clientRect.h); + f->WriteFloat(textRect.x); + f->WriteFloat(textRect.y); + f->WriteFloat(textRect.w); + f->WriteFloat(textRect.h); + f->WriteFloat(xOffset); + f->WriteFloat(yOffset); idStr work; f->SetLog(true, work); @@ -3323,40 +3631,41 @@ void idWindow::WriteToDemoFile( class idDemoFile *f ) { f->SetLog(true, (work + "-transitions")); c = transitions.Num(); - f->WriteInt( c ); + f->WriteInt(c); for (i = 0; i < c; i++) { - f->WriteInt( 0 ); - f->WriteInt( transitions[i].offset ); + f->WriteInt(0); + f->WriteInt(transitions[i].offset); - f->WriteFloat( transitions[i].interp.GetStartTime() ); - f->WriteFloat( transitions[i].interp.GetAccelTime() ); - f->WriteFloat( transitions[i].interp.GetLinearTime() ); - f->WriteFloat( transitions[i].interp.GetDecelTime() ); - f->WriteVec4( transitions[i].interp.GetStartValue() ); - f->WriteVec4( transitions[i].interp.GetEndValue() ); + f->WriteFloat(transitions[i].interp.GetStartTime()); + f->WriteFloat(transitions[i].interp.GetAccelTime()); + f->WriteFloat(transitions[i].interp.GetLinearTime()); + f->WriteFloat(transitions[i].interp.GetDecelTime()); + f->WriteVec4(transitions[i].interp.GetStartValue()); + f->WriteVec4(transitions[i].interp.GetEndValue()); // write to keep win32 render demo format compatiblity - we don't actually read them back anymore - f->WriteInt( transitions[i].interp.GetExtrapolate()->GetExtrapolationType() ); - f->WriteFloat( transitions[i].interp.GetExtrapolate()->GetStartTime() ); - f->WriteFloat( transitions[i].interp.GetExtrapolate()->GetDuration() ); - f->WriteVec4( transitions[i].interp.GetExtrapolate()->GetStartValue() ); - f->WriteVec4( transitions[i].interp.GetExtrapolate()->GetBaseSpeed() ); - f->WriteVec4( transitions[i].interp.GetExtrapolate()->GetSpeed() ); - f->WriteFloat( transitions[i].interp.GetExtrapolate()->GetCurrentTime() ); - f->WriteVec4( transitions[i].interp.GetExtrapolate()->GetCurrentValue() ); + f->WriteInt(transitions[i].interp.GetExtrapolate()->GetExtrapolationType()); + f->WriteFloat(transitions[i].interp.GetExtrapolate()->GetStartTime()); + f->WriteFloat(transitions[i].interp.GetExtrapolate()->GetDuration()); + f->WriteVec4(transitions[i].interp.GetExtrapolate()->GetStartValue()); + f->WriteVec4(transitions[i].interp.GetExtrapolate()->GetBaseSpeed()); + f->WriteVec4(transitions[i].interp.GetExtrapolate()->GetSpeed()); + f->WriteFloat(transitions[i].interp.GetExtrapolate()->GetCurrentTime()); + f->WriteVec4(transitions[i].interp.GetExtrapolate()->GetCurrentValue()); } f->SetLog(true, (work + "-regstuff")); f->SetLog(true, (work + "-children")); c = children.Num(); - f->WriteInt( c ); + f->WriteInt(c); for (i = 0; i < c; i++) { for (int j = 0; j < c; j++) { if (children[j]->childID == i) { children[j]->WriteToDemoFile(f); break; - } else { + } + else { continue; } } @@ -3369,11 +3678,11 @@ void idWindow::WriteToDemoFile( class idDemoFile *f ) { idWindow::WriteString =============== */ -void idWindow::WriteSaveGameString( const char *string, idFile *savefile ) { - int len = strlen( string ); +void idWindow::WriteSaveGameString(const char* string, idFile* savefile) { + int len = strlen(string); - savefile->Write( &len, sizeof( len ) ); - savefile->Write( string, len ); + savefile->Write(&len, sizeof(len)); + savefile->Write(string, len); } /* @@ -3381,136 +3690,164 @@ void idWindow::WriteSaveGameString( const char *string, idFile *savefile ) { idWindow::WriteSaveGameTransition =============== */ -void idWindow::WriteSaveGameTransition( idTransitionData &trans, idFile *savefile ) { - drawWin_t dw, *fdw; +void idWindow::WriteSaveGameTransition(idTransitionData& trans, idFile* savefile) { + drawWin_t dw, * fdw; idStr winName(""); dw.simp = NULL; dw.win = NULL; - int offset = gui->GetDesktop()->GetWinVarOffset( trans.data, &dw ); - if ( dw.win || dw.simp ) { - winName = ( dw.win ) ? dw.win->GetName() : dw.simp->name.c_str(); + + idWinVar* targetVar = trans.data; +#ifdef QUAKE4 + int subIndex = -1; + if (idWinFloatMember* member = dynamic_cast(trans.data)) { + targetVar = member->GetOwner(); + subIndex = member->GetComponent(); } - fdw = gui->GetDesktop()->FindChildByName( winName ); - if ( offset != -1 && fdw && ( fdw->win || fdw->simp ) ) { - savefile->Write( &offset, sizeof( offset ) ); - WriteSaveGameString( winName, savefile ); - savefile->Write( &trans.interp, sizeof( trans.interp ) ); - } else { +#endif + + int offset = gui->GetDesktop()->GetWinVarOffset(targetVar, &dw); + if (dw.win || dw.simp) { + winName = (dw.win) ? dw.win->GetName() : dw.simp->name.c_str(); + } + fdw = gui->GetDesktop()->FindChildByName(winName); + if (offset != -1 && fdw && (fdw->win || fdw->simp)) { + savefile->Write(&offset, sizeof(offset)); + WriteSaveGameString(winName, savefile); + savefile->Write(&trans.interp, sizeof(trans.interp)); +#ifdef QUAKE4 + savefile->Write(&subIndex, sizeof(subIndex)); // savegame version >= 18 +#endif + } + else { offset = -1; - savefile->Write( &offset, sizeof( offset ) ); + savefile->Write(&offset, sizeof(offset)); } } + /* =============== idWindow::ReadSaveGameTransition =============== */ -void idWindow::ReadSaveGameTransition( idTransitionData &trans, idFile *savefile ) { +void idWindow::ReadSaveGameTransition(idTransitionData& trans, idFile* savefile) { int offset; - - savefile->Read( &offset, sizeof( offset ) ); - if ( offset != -1 ) { + savefile->Read(&offset, sizeof(offset)); + if (offset != -1) { idStr winName; - ReadSaveGameString( winName, savefile ); - savefile->Read( &trans.interp, sizeof( trans.interp ) ); + ReadSaveGameString(winName, savefile); + savefile->Read(&trans.interp, sizeof(trans.interp)); + +#ifdef QUAKE4 + int subIndex = -1; + if (session->GetSaveGameVersion() >= 18) { + savefile->Read(&subIndex, sizeof(subIndex)); + } + transitionSubs.Append(subIndex); +#endif + trans.data = NULL; trans.offset = offset; - if ( winName.Length() ) { - idWinStr *strVar = new idWinStr(); - strVar->Set( winName ); - trans.data = dynamic_cast< idWinVar* >( strVar ); + if (winName.Length()) { + idWinStr* strVar = new idWinStr(); + strVar->Set(winName); + trans.data = dynamic_cast(strVar); } } } + /* =============== idWindow::WriteToSaveGame =============== */ -void idWindow::WriteToSaveGame( idFile *savefile ) { +void idWindow::WriteToSaveGame(idFile* savefile) { int i; - WriteSaveGameString( cmd, savefile ); + WriteSaveGameString(cmd, savefile); - savefile->Write( &actualX, sizeof( actualX ) ); - savefile->Write( &actualY, sizeof( actualY ) ); - savefile->Write( &childID, sizeof( childID ) ); - savefile->Write( &flags, sizeof( flags ) ); - savefile->Write( &lastTimeRun, sizeof( lastTimeRun ) ); - savefile->Write( &drawRect, sizeof( drawRect ) ); - savefile->Write( &clientRect, sizeof( clientRect ) ); - savefile->Write( &origin, sizeof( origin ) ); - savefile->Write( &fontNum, sizeof( fontNum ) ); - savefile->Write( &timeLine, sizeof( timeLine ) ); - savefile->Write( &xOffset, sizeof( xOffset ) ); - savefile->Write( &yOffset, sizeof( yOffset ) ); - savefile->Write( &cursor, sizeof( cursor ) ); - savefile->Write( &forceAspectWidth, sizeof( forceAspectWidth ) ); - savefile->Write( &forceAspectHeight, sizeof( forceAspectHeight ) ); - savefile->Write( &matScalex, sizeof( matScalex ) ); - savefile->Write( &matScaley, sizeof( matScaley ) ); - savefile->Write( &borderSize, sizeof( borderSize ) ); - savefile->Write( &textAlign, sizeof( textAlign ) ); - savefile->Write( &textAlignx, sizeof( textAlignx ) ); - savefile->Write( &textAligny, sizeof( textAligny ) ); - savefile->Write( &textShadow, sizeof( textShadow ) ); - savefile->Write( &shear, sizeof( shear ) ); + savefile->Write(&actualX, sizeof(actualX)); + savefile->Write(&actualY, sizeof(actualY)); + savefile->Write(&childID, sizeof(childID)); + savefile->Write(&flags, sizeof(flags)); + savefile->Write(&lastTimeRun, sizeof(lastTimeRun)); + savefile->Write(&drawRect, sizeof(drawRect)); + savefile->Write(&clientRect, sizeof(clientRect)); + savefile->Write(&origin, sizeof(origin)); + savefile->Write(&fontNum, sizeof(fontNum)); + savefile->Write(&timeLine, sizeof(timeLine)); + savefile->Write(&xOffset, sizeof(xOffset)); + savefile->Write(&yOffset, sizeof(yOffset)); + savefile->Write(&cursor, sizeof(cursor)); + savefile->Write(&forceAspectWidth, sizeof(forceAspectWidth)); + savefile->Write(&forceAspectHeight, sizeof(forceAspectHeight)); + savefile->Write(&matScalex, sizeof(matScalex)); + savefile->Write(&matScaley, sizeof(matScaley)); + savefile->Write(&borderSize, sizeof(borderSize)); + savefile->Write(&textAlign, sizeof(textAlign)); + savefile->Write(&textAlignx, sizeof(textAlignx)); + savefile->Write(&textAligny, sizeof(textAligny)); + savefile->Write(&textShadow, sizeof(textShadow)); +#ifdef QUAKE4 + savefile->Write(&textStyle, sizeof(textStyle)); // savegame version >= 18 + savefile->Write(&textSpacing, sizeof(textSpacing)); // savegame version >= 18 +#endif + savefile->Write(&shear, sizeof(shear)); - WriteSaveGameString( name, savefile ); - WriteSaveGameString( comment, savefile ); + WriteSaveGameString(name, savefile); + WriteSaveGameString(comment, savefile); // WinVars - noTime.WriteToSaveGame( savefile ); - visible.WriteToSaveGame( savefile ); - rect.WriteToSaveGame( savefile ); - backColor.WriteToSaveGame( savefile ); - matColor.WriteToSaveGame( savefile ); - foreColor.WriteToSaveGame( savefile ); - hoverColor.WriteToSaveGame( savefile ); - borderColor.WriteToSaveGame( savefile ); - textScale.WriteToSaveGame( savefile ); - noEvents.WriteToSaveGame( savefile ); - rotate.WriteToSaveGame( savefile ); - text.WriteToSaveGame( savefile ); - backGroundName.WriteToSaveGame( savefile ); + noTime.WriteToSaveGame(savefile); + visible.WriteToSaveGame(savefile); + rect.WriteToSaveGame(savefile); + backColor.WriteToSaveGame(savefile); + matColor.WriteToSaveGame(savefile); + foreColor.WriteToSaveGame(savefile); + hoverColor.WriteToSaveGame(savefile); + borderColor.WriteToSaveGame(savefile); + textScale.WriteToSaveGame(savefile); + noEvents.WriteToSaveGame(savefile); + rotate.WriteToSaveGame(savefile); + text.WriteToSaveGame(savefile); + backGroundName.WriteToSaveGame(savefile); hideCursor.WriteToSaveGame(savefile); // Defined Vars - for ( i = 0; i < definedVars.Num(); i++ ) { - definedVars[i]->WriteToSaveGame( savefile ); + for (i = 0; i < definedVars.Num(); i++) { + definedVars[i]->WriteToSaveGame(savefile); } - savefile->Write( &textRect, sizeof( textRect ) ); + savefile->Write(&textRect, sizeof(textRect)); // Window pointers saved as the child ID of the window int winID; - winID = focusedChild ? focusedChild->childID : -1 ; - savefile->Write( &winID, sizeof( winID ) ); + winID = focusedChild ? focusedChild->childID : -1; + savefile->Write(&winID, sizeof(winID)); - winID = captureChild ? captureChild->childID : -1 ; - savefile->Write( &winID, sizeof( winID ) ); + winID = captureChild ? captureChild->childID : -1; + savefile->Write(&winID, sizeof(winID)); - winID = overChild ? overChild->childID : -1 ; - savefile->Write( &winID, sizeof( winID ) ); + winID = overChild ? overChild->childID : -1; + savefile->Write(&winID, sizeof(winID)); // Scripts - for ( i = 0; i < SCRIPT_COUNT; i++ ) { - if ( scripts[i] ) { - scripts[i]->WriteToSaveGame( savefile ); + for (i = 0; i < SCRIPT_COUNT; i++) { + if (scripts[i]) { + scripts[i]->WriteToSaveGame(savefile); } } // TimeLine Events - for ( i = 0; i < timeLineEvents.Num(); i++ ) { - if ( timeLineEvents[i] ) { - savefile->Write( &timeLineEvents[i]->pending, sizeof( timeLineEvents[i]->pending ) ); - savefile->Write( &timeLineEvents[i]->time, sizeof( timeLineEvents[i]->time ) ); - if ( timeLineEvents[i]->event ) { - timeLineEvents[i]->event->WriteToSaveGame( savefile ); + for (i = 0; i < timeLineEvents.Num(); i++) { + if (timeLineEvents[i]) { + savefile->Write(&timeLineEvents[i]->pending, sizeof(timeLineEvents[i]->pending)); + savefile->Write(&timeLineEvents[i]->time, sizeof(timeLineEvents[i]->time)); + if (timeLineEvents[i]->event) { + timeLineEvents[i]->event->WriteToSaveGame(savefile); } } } @@ -3518,34 +3855,35 @@ void idWindow::WriteToSaveGame( idFile *savefile ) { // Transitions int num = transitions.Num(); - savefile->Write( &num, sizeof( num ) ); - for ( i = 0; i < transitions.Num(); i++ ) { - WriteSaveGameTransition( transitions[ i ], savefile ); + savefile->Write(&num, sizeof(num)); + for (i = 0; i < transitions.Num(); i++) { + WriteSaveGameTransition(transitions[i], savefile); } // Named Events - for ( i = 0; i < namedEvents.Num(); i++ ) { - if ( namedEvents[i] ) { - WriteSaveGameString( namedEvents[i]->mName, savefile ); - if ( namedEvents[i]->mEvent ) { - namedEvents[i]->mEvent->WriteToSaveGame( savefile ); + for (i = 0; i < namedEvents.Num(); i++) { + if (namedEvents[i]) { + WriteSaveGameString(namedEvents[i]->mName, savefile); + if (namedEvents[i]->mEvent) { + namedEvents[i]->mEvent->WriteToSaveGame(savefile); } } } // regList - regList.WriteToSaveGame( savefile ); + regList.WriteToSaveGame(savefile); // Save children - for ( i = 0; i < drawWindows.Num(); i++ ) { + for (i = 0; i < drawWindows.Num(); i++) { drawWin_t window = drawWindows[i]; - if ( window.simp ) { - window.simp->WriteToSaveGame( savefile ); - } else if ( window.win ) { - window.win->WriteToSaveGame( savefile ); + if (window.simp) { + window.simp->WriteToSaveGame(savefile); + } + else if (window.win) { + window.win->WriteToSaveGame(savefile); } } } @@ -3555,16 +3893,16 @@ void idWindow::WriteToSaveGame( idFile *savefile ) { idWindow::ReadSaveGameString =============== */ -void idWindow::ReadSaveGameString( idStr &string, idFile *savefile ) { +void idWindow::ReadSaveGameString(idStr& string, idFile* savefile) { int len; - savefile->Read( &len, sizeof( len ) ); - if ( len < 0 ) { - common->Warning( "idWindow::ReadSaveGameString: invalid length" ); + savefile->Read(&len, sizeof(len)); + if (len < 0) { + common->Warning("idWindow::ReadSaveGameString: invalid length"); } - string.Fill( ' ', len ); - savefile->Read( &string[0], len ); + string.Fill(' ', len); + savefile->Read(&string[0], len); } /* @@ -3572,104 +3910,118 @@ void idWindow::ReadSaveGameString( idStr &string, idFile *savefile ) { idWindow::ReadFromSaveGame =============== */ -void idWindow::ReadFromSaveGame( idFile *savefile ) { +void idWindow::ReadFromSaveGame(idFile* savefile) { int i; transitions.Clear(); +#ifdef QUAKE4 + transitionSubs.Clear(); +#endif - ReadSaveGameString( cmd, savefile ); + ReadSaveGameString(cmd, savefile); - savefile->Read( &actualX, sizeof( actualX ) ); - savefile->Read( &actualY, sizeof( actualY ) ); - savefile->Read( &childID, sizeof( childID ) ); - savefile->Read( &flags, sizeof( flags ) ); - savefile->Read( &lastTimeRun, sizeof( lastTimeRun ) ); - savefile->Read( &drawRect, sizeof( drawRect ) ); - savefile->Read( &clientRect, sizeof( clientRect ) ); - savefile->Read( &origin, sizeof( origin ) ); - savefile->Read( &fontNum, sizeof( fontNum ) ); - savefile->Read( &timeLine, sizeof( timeLine ) ); - savefile->Read( &xOffset, sizeof( xOffset ) ); - savefile->Read( &yOffset, sizeof( yOffset ) ); - savefile->Read( &cursor, sizeof( cursor ) ); - savefile->Read( &forceAspectWidth, sizeof( forceAspectWidth ) ); - savefile->Read( &forceAspectHeight, sizeof( forceAspectHeight ) ); - savefile->Read( &matScalex, sizeof( matScalex ) ); - savefile->Read( &matScaley, sizeof( matScaley ) ); - savefile->Read( &borderSize, sizeof( borderSize ) ); - savefile->Read( &textAlign, sizeof( textAlign ) ); - savefile->Read( &textAlignx, sizeof( textAlignx ) ); - savefile->Read( &textAligny, sizeof( textAligny ) ); - savefile->Read( &textShadow, sizeof( textShadow ) ); - savefile->Read( &shear, sizeof( shear ) ); + savefile->Read(&actualX, sizeof(actualX)); + savefile->Read(&actualY, sizeof(actualY)); + savefile->Read(&childID, sizeof(childID)); + savefile->Read(&flags, sizeof(flags)); + savefile->Read(&lastTimeRun, sizeof(lastTimeRun)); + savefile->Read(&drawRect, sizeof(drawRect)); + savefile->Read(&clientRect, sizeof(clientRect)); + savefile->Read(&origin, sizeof(origin)); + savefile->Read(&fontNum, sizeof(fontNum)); + savefile->Read(&timeLine, sizeof(timeLine)); + savefile->Read(&xOffset, sizeof(xOffset)); + savefile->Read(&yOffset, sizeof(yOffset)); + savefile->Read(&cursor, sizeof(cursor)); + savefile->Read(&forceAspectWidth, sizeof(forceAspectWidth)); + savefile->Read(&forceAspectHeight, sizeof(forceAspectHeight)); + savefile->Read(&matScalex, sizeof(matScalex)); + savefile->Read(&matScaley, sizeof(matScaley)); + savefile->Read(&borderSize, sizeof(borderSize)); + savefile->Read(&textAlign, sizeof(textAlign)); + savefile->Read(&textAlignx, sizeof(textAlignx)); + savefile->Read(&textAligny, sizeof(textAligny)); + savefile->Read(&textShadow, sizeof(textShadow)); +#ifdef QUAKE4 + if (session->GetSaveGameVersion() >= 18) { + savefile->Read(&textStyle, sizeof(textStyle)); + savefile->Read(&textSpacing, sizeof(textSpacing)); + } + else { + textStyle = 0; + textSpacing = 0.0f; + } +#endif + savefile->Read(&shear, sizeof(shear)); - ReadSaveGameString( name, savefile ); - ReadSaveGameString( comment, savefile ); + ReadSaveGameString(name, savefile); + ReadSaveGameString(comment, savefile); // WinVars - noTime.ReadFromSaveGame( savefile ); - visible.ReadFromSaveGame( savefile ); - rect.ReadFromSaveGame( savefile ); - backColor.ReadFromSaveGame( savefile ); - matColor.ReadFromSaveGame( savefile ); - foreColor.ReadFromSaveGame( savefile ); - hoverColor.ReadFromSaveGame( savefile ); - borderColor.ReadFromSaveGame( savefile ); - textScale.ReadFromSaveGame( savefile ); - noEvents.ReadFromSaveGame( savefile ); - rotate.ReadFromSaveGame( savefile ); - text.ReadFromSaveGame( savefile ); - backGroundName.ReadFromSaveGame( savefile ); + noTime.ReadFromSaveGame(savefile); + visible.ReadFromSaveGame(savefile); + rect.ReadFromSaveGame(savefile); + backColor.ReadFromSaveGame(savefile); + matColor.ReadFromSaveGame(savefile); + foreColor.ReadFromSaveGame(savefile); + hoverColor.ReadFromSaveGame(savefile); + borderColor.ReadFromSaveGame(savefile); + textScale.ReadFromSaveGame(savefile); + noEvents.ReadFromSaveGame(savefile); + rotate.ReadFromSaveGame(savefile); + text.ReadFromSaveGame(savefile); + backGroundName.ReadFromSaveGame(savefile); - if ( session->GetSaveGameVersion() >= 17 ) { + if (session->GetSaveGameVersion() >= 17) { hideCursor.ReadFromSaveGame(savefile); - } else { + } + else { hideCursor = false; } // Defined Vars - for ( i = 0; i < definedVars.Num(); i++ ) { - definedVars[i]->ReadFromSaveGame( savefile ); + for (i = 0; i < definedVars.Num(); i++) { + definedVars[i]->ReadFromSaveGame(savefile); } - savefile->Read( &textRect, sizeof( textRect ) ); + savefile->Read(&textRect, sizeof(textRect)); // Window pointers saved as the child ID of the window int winID = -1; - savefile->Read( &winID, sizeof( winID ) ); - for ( i = 0; i < children.Num(); i++ ) { - if ( children[i]->childID == winID ) { + savefile->Read(&winID, sizeof(winID)); + for (i = 0; i < children.Num(); i++) { + if (children[i]->childID == winID) { focusedChild = children[i]; } } - savefile->Read( &winID, sizeof( winID ) ); - for ( i = 0; i < children.Num(); i++ ) { - if ( children[i]->childID == winID ) { + savefile->Read(&winID, sizeof(winID)); + for (i = 0; i < children.Num(); i++) { + if (children[i]->childID == winID) { captureChild = children[i]; } } - savefile->Read( &winID, sizeof( winID ) ); - for ( i = 0; i < children.Num(); i++ ) { - if ( children[i]->childID == winID ) { + savefile->Read(&winID, sizeof(winID)); + for (i = 0; i < children.Num(); i++) { + if (children[i]->childID == winID) { overChild = children[i]; } } // Scripts - for ( i = 0; i < SCRIPT_COUNT; i++ ) { - if ( scripts[i] ) { - scripts[i]->ReadFromSaveGame( savefile ); + for (i = 0; i < SCRIPT_COUNT; i++) { + if (scripts[i]) { + scripts[i]->ReadFromSaveGame(savefile); } } // TimeLine Events - for ( i = 0; i < timeLineEvents.Num(); i++ ) { - if ( timeLineEvents[i] ) { - savefile->Read( &timeLineEvents[i]->pending, sizeof( timeLineEvents[i]->pending ) ); - savefile->Read( &timeLineEvents[i]->time, sizeof( timeLineEvents[i]->time ) ); - if ( timeLineEvents[i]->event ) { - timeLineEvents[i]->event->ReadFromSaveGame( savefile ); + for (i = 0; i < timeLineEvents.Num(); i++) { + if (timeLineEvents[i]) { + savefile->Read(&timeLineEvents[i]->pending, sizeof(timeLineEvents[i]->pending)); + savefile->Read(&timeLineEvents[i]->time, sizeof(timeLineEvents[i]->time)); + if (timeLineEvents[i]->event) { + timeLineEvents[i]->event->ReadFromSaveGame(savefile); } } } @@ -3677,42 +4029,43 @@ void idWindow::ReadFromSaveGame( idFile *savefile ) { // Transitions int num; - savefile->Read( &num, sizeof( num ) ); - for ( i = 0; i < num; i++ ) { + savefile->Read(&num, sizeof(num)); + for (i = 0; i < num; i++) { idTransitionData trans; trans.data = NULL; - ReadSaveGameTransition( trans, savefile ); - if ( trans.data ) { - transitions.Append( trans ); + ReadSaveGameTransition(trans, savefile); + if (trans.data) { + transitions.Append(trans); } } // Named Events - for ( i = 0; i < namedEvents.Num(); i++ ) { - if ( namedEvents[i] ) { - ReadSaveGameString( namedEvents[i]->mName, savefile ); - if ( namedEvents[i]->mEvent ) { - namedEvents[i]->mEvent->ReadFromSaveGame( savefile ); + for (i = 0; i < namedEvents.Num(); i++) { + if (namedEvents[i]) { + ReadSaveGameString(namedEvents[i]->mName, savefile); + if (namedEvents[i]->mEvent) { + namedEvents[i]->mEvent->ReadFromSaveGame(savefile); } } } // regList - regList.ReadFromSaveGame( savefile ); + regList.ReadFromSaveGame(savefile); // Read children - for ( i = 0; i < drawWindows.Num(); i++ ) { + for (i = 0; i < drawWindows.Num(); i++) { drawWin_t window = drawWindows[i]; - if ( window.simp ) { - window.simp->ReadFromSaveGame( savefile ); - } else if ( window.win ) { - window.win->ReadFromSaveGame( savefile ); + if (window.simp) { + window.simp->ReadFromSaveGame(savefile); + } + else if (window.win) { + window.win->ReadFromSaveGame(savefile); } } - if ( flags & WIN_DESKTOP ) { + if (flags & WIN_DESKTOP) { FixupTransitions(); } } @@ -3724,7 +4077,7 @@ idWindow::NumTransitions */ int idWindow::NumTransitions() { int c = transitions.Num(); - for ( int i = 0; i < children.Num(); i++ ) { + for (int i = 0; i < children.Num(); i++) { c += children[i]->NumTransitions(); } return c; @@ -3737,64 +4090,88 @@ idWindow::FixupTransitions =============== */ void idWindow::FixupTransitions() { - int i, c = transitions.Num(); - for ( i = 0; i < c; i++ ) { - drawWin_t *dw = gui->GetDesktop()->FindChildByName( ( ( idWinStr* )transitions[i].data )->c_str() ); + for (int i = 0; i < transitions.Num(); i++) { + drawWin_t* dw = gui->GetDesktop()->FindChildByName(((idWinStr*)transitions[i].data)->c_str()); delete transitions[i].data; transitions[i].data = NULL; - if ( dw && ( dw->win || dw->simp ) ){ - if ( dw->win ) { - if ( transitions[i].offset == (ptrdiff_t)&this->rect - (ptrdiff_t)this ) { + if (dw && (dw->win || dw->simp)) { + if (dw->win) { + if (transitions[i].offset == (int)&((idWindow*)0)->rect) { transitions[i].data = &dw->win->rect; - } else if ( transitions[i].offset == (ptrdiff_t)&this->backColor - (ptrdiff_t)this ) { + } + else if (transitions[i].offset == (int)&((idWindow*)0)->backColor) { transitions[i].data = &dw->win->backColor; - } else if ( transitions[i].offset == (ptrdiff_t)&this->matColor - (ptrdiff_t)this ) { + } + else if (transitions[i].offset == (int)&((idWindow*)0)->matColor) { transitions[i].data = &dw->win->matColor; - } else if ( transitions[i].offset == (ptrdiff_t)&this->foreColor - (ptrdiff_t)this ) { + } + else if (transitions[i].offset == (int)&((idWindow*)0)->foreColor) { transitions[i].data = &dw->win->foreColor; - } else if ( transitions[i].offset == (ptrdiff_t)&this->borderColor - (ptrdiff_t)this ) { + } + else if (transitions[i].offset == (int)&((idWindow*)0)->borderColor) { transitions[i].data = &dw->win->borderColor; - } else if ( transitions[i].offset == (ptrdiff_t)&this->textScale - (ptrdiff_t)this ) { + } + else if (transitions[i].offset == (int)&((idWindow*)0)->textScale) { transitions[i].data = &dw->win->textScale; - } else if ( transitions[i].offset == (ptrdiff_t)&this->rotate - (ptrdiff_t)this ) { + } + else if (transitions[i].offset == (int)&((idWindow*)0)->rotate) { transitions[i].data = &dw->win->rotate; } - } else { - if ( transitions[i].offset == (ptrdiff_t)&this->rect - (ptrdiff_t)this ) { + } + else { + if (transitions[i].offset == (int)&((idSimpleWindow*)0)->rect) { transitions[i].data = &dw->simp->rect; - } else if ( transitions[i].offset == (ptrdiff_t)&this->backColor - (ptrdiff_t)this ) { + } + else if (transitions[i].offset == (int)&((idSimpleWindow*)0)->backColor) { transitions[i].data = &dw->simp->backColor; - } else if ( transitions[i].offset == (ptrdiff_t)&this->matColor - (ptrdiff_t)this ) { + } + else if (transitions[i].offset == (int)&((idSimpleWindow*)0)->matColor) { transitions[i].data = &dw->simp->matColor; - } else if ( transitions[i].offset == (ptrdiff_t)&this->foreColor - (ptrdiff_t)this ) { + } + else if (transitions[i].offset == (int)&((idSimpleWindow*)0)->foreColor) { transitions[i].data = &dw->simp->foreColor; - } else if ( transitions[i].offset == (ptrdiff_t)&this->borderColor - (ptrdiff_t)this ) { + } + else if (transitions[i].offset == (int)&((idSimpleWindow*)0)->borderColor) { transitions[i].data = &dw->simp->borderColor; - } else if ( transitions[i].offset == (ptrdiff_t)&this->textScale - (ptrdiff_t)this ) { + } + else if (transitions[i].offset == (int)&((idSimpleWindow*)0)->textScale) { transitions[i].data = &dw->simp->textScale; - } else if ( transitions[i].offset == (ptrdiff_t)&this->rotate - (ptrdiff_t)this ) { + } + else if (transitions[i].offset == (int)&((idSimpleWindow*)0)->rotate) { transitions[i].data = &dw->simp->rotate; } } } - if ( transitions[i].data == NULL ) { - transitions.RemoveIndex( i ); +#ifdef QUAKE4 + if (transitions[i].data && i < transitionSubs.Num() && transitionSubs[i] != -1) { + transitions[i].data = new idWinFloatMember(transitions[i].data, transitionSubs[i]); + } +#endif + if (transitions[i].data == NULL) { + transitions.RemoveIndex(i); +#ifdef QUAKE4 +#ifdef QUAKE4 + if (i < transitionSubs.Num()) { + transitionSubs.RemoveIndex(i); + } +#endif +#endif i--; - c--; } } - for ( c = 0; c < children.Num(); c++ ) { + for (int c = 0; c < children.Num(); c++) { children[c]->FixupTransitions(); } } + /* =============== idWindow::AddChild =============== */ -void idWindow::AddChild(idWindow *win) { +void idWindow::AddChild(idWindow* win) { win->childID = children.Append(win); } @@ -3829,9 +4206,9 @@ void idWindow::FixupParms() { for (i = 0; i < c; i++) { if (ops[i].b == -2) { // need to fix this up - const char *p = (const char*)(ops[i].a); - idWinVar *var = GetWinVarByName(p, true); - delete []p; + const char* p = (const char*)(ops[i].a); + idWinVar* var = GetWinVarByName(p, true); + delete[]p; ops[i].a = (intptr_t)var; ops[i].b = -1; } @@ -3839,7 +4216,7 @@ void idWindow::FixupParms() { if (flags & WIN_DESKTOP) { - CalcRects(0,0); + CalcRects(0, 0); } } @@ -3852,7 +4229,7 @@ idWindow::IsSimple bool idWindow::IsSimple() { // dont do simple windows when in gui editor - if ( com_editors & EDITOR_GUI ) { + if (com_editors & EDITOR_GUI) { return false; } @@ -3874,9 +4251,14 @@ bool idWindow::IsSimple() { return false; } - if ( namedEvents.Num() ) { + if (namedEvents.Num()) { return false; } +#ifdef QUAKE4 + if (forceAspectWidth != 640.0f || forceAspectHeight != 480.0f) { + return false; + } +#endif return true; } @@ -3887,12 +4269,12 @@ idWindow::ContainsStateVars ================ */ bool idWindow::ContainsStateVars() { - if ( updateVars.Num() ) { + if (updateVars.Num()) { return true; } int c = children.Num(); for (int i = 0; i < c; i++) { - if ( children[i]->ContainsStateVars() ) { + if (children[i]->ContainsStateVars()) { return true; } } @@ -3905,7 +4287,7 @@ idWindow::Interactive ================ */ bool idWindow::Interactive() { - if ( scripts[ ON_ACTION ] ) { + if (scripts[ON_ACTION]) { return true; } int c = children.Num(); @@ -3922,12 +4304,13 @@ bool idWindow::Interactive() { idWindow::SetChildWinVarVal ================ */ -void idWindow::SetChildWinVarVal(const char *name, const char *var, const char *val) { - drawWin_t *dw = FindChildByName(name); - idWinVar *wv = NULL; +void idWindow::SetChildWinVarVal(const char* name, const char* var, const char* val) { + drawWin_t* dw = FindChildByName(name); + idWinVar* wv = NULL; if (dw && dw->simp) { wv = dw->simp->GetWinVarByName(var); - } else if (dw && dw->win) { + } + else if (dw && dw->win) { wv = dw->win->GetWinVarByName(var); } if (wv) { @@ -3944,24 +4327,24 @@ idWindow::FindChildByPoint Finds the window under the given point ================ */ -idWindow* idWindow::FindChildByPoint ( float x, float y, idWindow** below ) { +idWindow* idWindow::FindChildByPoint(float x, float y, idWindow** below) { int c = children.Num(); // If we are looking for a window below this one then // the next window should be good, but this one wasnt it - if ( *below == this ) { + if (*below == this) { *below = NULL; return NULL; } - if ( !Contains ( drawRect, x, y ) ) { + if (!Contains(drawRect, x, y)) { return NULL; } - for (int i = c - 1; i >= 0 ; i-- ) { - idWindow* found = children[i]->FindChildByPoint ( x, y, below ); - if ( found ) { - if ( *below ) { + for (int i = c - 1; i >= 0; i--) { + idWindow* found = children[i]->FindChildByPoint(x, y, below); + if (found) { + if (*below) { continue; } @@ -3977,9 +4360,9 @@ idWindow* idWindow::FindChildByPoint ( float x, float y, idWindow** below ) { idWindow::FindChildByPoint ================ */ -idWindow* idWindow::FindChildByPoint ( float x, float y, idWindow* below ) +idWindow* idWindow::FindChildByPoint(float x, float y, idWindow* below) { - return FindChildByPoint ( x, y, &below ); + return FindChildByPoint(x, y, &below); } /* @@ -3989,9 +4372,9 @@ idWindow::GetChildCount Returns the number of children ================ */ -int idWindow::GetChildCount ( void ) +int idWindow::GetChildCount(void) { - return drawWindows.Num ( ); + return drawWindows.Num(); } /* @@ -4001,7 +4384,7 @@ idWindow::GetChild Returns the child window at the given index ================ */ -idWindow* idWindow::GetChild ( int index ) +idWindow* idWindow::GetChild(int index) { return drawWindows[index].win; } @@ -4013,10 +4396,10 @@ idWindow::GetChildIndex Returns the index of the given child window ================ */ -int idWindow::GetChildIndex ( idWindow* window ) { +int idWindow::GetChildIndex(idWindow* window) { int find; - for ( find = 0; find < drawWindows.Num(); find ++ ) { - if ( drawWindows[find].win == window ) { + for (find = 0; find < drawWindows.Num(); find++) { + if (drawWindows[find].win == window) { return find; } } @@ -4031,17 +4414,17 @@ Removes the child from the list of children. Note that the child window being removed must still be deallocated by the caller ================ */ -void idWindow::RemoveChild ( idWindow *win ) { +void idWindow::RemoveChild(idWindow* win) { int find; // Remove the child window - children.Remove ( win ); + children.Remove(win); - for ( find = 0; find < drawWindows.Num(); find ++ ) + for (find = 0; find < drawWindows.Num(); find++) { - if ( drawWindows[find].win == win ) + if (drawWindows[find].win == win) { - drawWindows.RemoveIndex ( find ); + drawWindows.RemoveIndex(find); break; } } @@ -4054,9 +4437,9 @@ idWindow::InsertChild Inserts the given window as a child into the given location in the zorder. ================ */ -bool idWindow::InsertChild ( idWindow *win, idWindow* before ) +bool idWindow::InsertChild(idWindow* win, idWindow* before) { - AddChild ( win ); + AddChild(win); win->parent = this; @@ -4065,16 +4448,16 @@ bool idWindow::InsertChild ( idWindow *win, idWindow* before ) dwt.win = win; // If not inserting before anything then just add it at the end - if ( before ) { + if (before) { int index; - index = GetChildIndex ( before ); - if ( index != -1 ) { - drawWindows.Insert ( dwt, index ); + index = GetChildIndex(before); + if (index != -1) { + drawWindows.Insert(dwt, index); return true; } } - drawWindows.Append ( dwt ); + drawWindows.Append(dwt); return true; } @@ -4083,12 +4466,12 @@ bool idWindow::InsertChild ( idWindow *win, idWindow* before ) idWindow::ScreenToClient ================ */ -void idWindow::ScreenToClient ( idRectangle* r ) { +void idWindow::ScreenToClient(idRectangle* r) { int x; int y; idWindow* p; - for ( p = this, x = 0, y = 0; p; p = p->parent ) { + for (p = this, x = 0, y = 0; p; p = p->parent) { x += p->rect.x(); y += p->rect.y(); } @@ -4102,12 +4485,12 @@ void idWindow::ScreenToClient ( idRectangle* r ) { idWindow::ClientToScreen ================ */ -void idWindow::ClientToScreen ( idRectangle* r ) { +void idWindow::ClientToScreen(idRectangle* r) { int x; int y; idWindow* p; - for ( p = this, x = 0, y = 0; p; p = p->parent ) { + for (p = this, x = 0, y = 0; p; p = p->parent) { x += p->rect.x(); y += p->rect.y(); } @@ -4124,19 +4507,26 @@ Set the window do a default window with no text, no background and default colors, etc.. ================ */ -void idWindow::SetDefaults ( void ) { - forceAspectWidth = SCREEN_WIDTH; - forceAspectHeight = SCREEN_HEIGHT; - matScalex = 1; - matScaley = 1; - borderSize = 0; +void idWindow::SetDefaults(void) { + matScalex = 1.0f; + matScaley = 1.0f; + forceAspectWidth = 640.0f; + forceAspectHeight = 480.0f; + borderSize = 0.0f; noTime = false; visible = true; textAlign = 0; - textAlignx = 0; - textAligny = 0; + textAlignx = 0.0f; + textAligny = 0.0f; + textShadow = 0; +#ifdef QUAKE4 +#ifdef QUAKE4 + textStyle = 0; + textSpacing = 0.0f; +#endif +#endif noEvents = false; - rotate = 0; + rotate = 0.0f; shear.Zero(); textScale = 0.35f; backColor.Zero(); @@ -4145,11 +4535,11 @@ void idWindow::SetDefaults ( void ) { matColor = idVec4(1, 1, 1, 1); borderColor.Zero(); text = ""; - background = NULL; backGroundName = ""; } + /* ================ idWindow::UpdateFromDictionary @@ -4159,31 +4549,34 @@ values of the dictionary onto the window is for the window to interpret the dictionary as if were a file being parsed. ================ */ -bool idWindow::UpdateFromDictionary ( idDict& dict ) { - const idKeyValue* kv; +bool idWindow::UpdateFromDictionary(idDict& dict) { + const idKeyValue* kv; int i; - SetDefaults ( ); + SetDefaults(); // Clear all registers since they will get recreated - regList.Reset ( ); - expressionRegisters.Clear ( ); - ops.Clear ( ); + regList.Reset(); + expressionRegisters.Clear(); + ops.Clear(); +#ifdef QUAKE4 + transitionSubs.Clear(); +#endif - for ( i = 0; i < dict.GetNumKeyVals(); i ++ ) { - kv = dict.GetKeyVal ( i ); + for (i = 0; i < dict.GetNumKeyVals(); i++) { + kv = dict.GetKeyVal(i); // Special case name - if ( !kv->GetKey().Icmp ( "name" ) ) { + if (!kv->GetKey().Icmp("name")) { name = kv->GetValue(); continue; } - idParser src( kv->GetValue().c_str(), kv->GetValue().Length(), "", - LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); - if ( !ParseInternalVar ( kv->GetKey(), &src ) ) { + idParser src(kv->GetValue().c_str(), kv->GetValue().Length(), "", + LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT); + if (!ParseInternalVar(kv->GetKey(), &src)) { // Kill the old register since the parse reg entry will add a new one - if ( !ParseRegEntry ( kv->GetKey(), &src ) ) { + if (!ParseRegEntry(kv->GetKey(), &src)) { continue; } } @@ -4196,3 +4589,226 @@ bool idWindow::UpdateFromDictionary ( idDict& dict ) { return true; } + + +#ifdef QUAKE4 +/* +================ +idWindow::IsVisible +================ +*/ +bool idWindow::IsVisible() const { + for (const idWindow* w = this; w; w = w->parent) { + if (!w->visible) { + return false; + } + } + return true; +} + +/* +================ +idWindow::Init +================ +*/ +void idWindow::Init() { + RunScript(ON_INIT); + for (int i = 0; i < children.Num(); i++) { + children[i]->Init(); + } +} + +/* +================ +idWindow::FindBestChild_r +================ +*/ +void idWindow::FindBestChild_r(int xd, int yd, int& startX, int& startY, int& bestX, int& bestY, idWindow* current, idWindow*& best) { + for (int i = children.Num() - 1; i >= 0; i--) { + idWindow* child = children[i]; + if (!child->visible) { + continue; + } + + if (child->noEvents || !child->scripts[ON_MOUSEENTER] || child == current) { + child->FindBestChild_r(xd, yd, startX, startY, bestX, bestY, current, best); + continue; + } + + const int x = (int)child->actualX; + const int y = (int)child->actualY; + + if (yd > 0) { + if (y > startY && (!best || y < bestY)) { + best = child; + bestY = y; + } + } + else if (yd < 0) { + if (y < startY && (!best || y > bestY)) { + best = child; + bestY = y; + } + } + else if (y > startY && (!best || y < bestY)) { + best = child; + bestY = y; + } + + if (xd > 0) { + if (x > startX && (!best || x < bestX)) { + best = child; + bestX = x; + } + } + else if (xd < 0) { + if (x < startX && (!best || x > bestX)) { + best = child; + bestX = x; + } + } + } +} + +/* +================ +idWindow::RunControllerScript +================ +*/ +bool idWindow::RunControllerScript(int script, const sysEvent_t* event, bool* updateVisuals) { + if (!(flags & WIN_DESKTOP)) { + return false; + } + + idWindow* focus = gui->GetDesktop()->focusedChild; + if (!focus) { + focus = overChild; + } + if (!focus || !focus->IsVisible()) { + return false; + } + + if (!focus->RunScript(script)) { + return false; + } + + // Mirror Q4 behaviour: if focus and hover diverge, move hover to the focused child + // so controller-only menus still receive the same enter/exit side effects as mouse menus. + idWindow* newOver = gui->GetDesktop()->focusedChild; + if (newOver && newOver != overChild) { + if (overChild) { + overChild->MouseExit(); + if (overChild->cmd.Length()) { + AddCommand(overChild->cmd.c_str()); + overChild->cmd = ""; + } + } + overChild = newOver; + dc->SetCursor(newOver->cursor); + newOver->hover = true; + newOver->MouseEnter(); + if (newOver->cmd.Length()) { + AddCommand(newOver->cmd.c_str()); + newOver->cmd = ""; + } + } + + return true; +} + +/* +================ +idWindow::RouteJoystickChange +================ +*/ +bool idWindow::RouteJoystickChange(int xd, int yd) { + if (GetCaptureChild()) { + return GetCaptureChild()->RouteJoystickChange(xd, yd); + } + + idWindow* best = NULL; + int startX = 0; + int startY = 0; + int bestX = 0; + int bestY = 0; + + if (overChild && overChild->IsVisible() && !overChild->noEvents && overChild->scripts[ON_MOUSEENTER]) { + if (xd == 0 && yd == 0) { + SetFocus(overChild, true); + dc->SetCursor(overChild->cursor); + overChild->hover = true; + overChild->MouseEnter(); + if (overChild->cmd.Length()) { + AddCommand(overChild->cmd.c_str()); + overChild->cmd = ""; + } + return true; + } + startX = (int)overChild->actualX; + startY = (int)overChild->actualY; + } + + FindBestChild_r(xd, yd, startX, startY, bestX, bestY, overChild, best); + + if (!best) { + for (int i = 0; i < children.Num(); i++) { + if (children[i]->RouteJoystickChange(xd, yd)) { + return true; + } + } + return false; + } + + SetFocus(best, true); + dc->SetCursor(best->cursor); + best->hover = true; + + if (overChild && overChild != best) { + overChild->MouseExit(); + if (overChild->cmd.Length()) { + AddCommand(overChild->cmd.c_str()); + overChild->cmd = ""; + } + } + overChild = best; + best->MouseEnter(); + if (best->cmd.Length()) { + AddCommand(best->cmd.c_str()); + best->cmd = ""; + } + return true; +} + +/* +================ +idWindow::ClearTransitions +================ +*/ +void idWindow::ClearTransitions() { + transitions.Clear(); +#ifdef QUAKE4 + transitionSubs.Clear(); +#endif + flags &= ~WIN_INTRANSITION; +} + +/* +================ +idWindow::SetWrapper +================ +*/ +void idWindow::SetWrapper(int wrapper) { + idWinVar* existing = GetWinVarByName("guied_wrapper"); + if (idWinInt* intVar = dynamic_cast(existing)) { + *intVar = wrapper; + intVar->SetEval(false); + return; + } + + idWinInt* var = new idWinInt(); + *var = wrapper; + var->SetEval(false); + var->SetName("guied_wrapper"); + definedVars.Append(var); +} +#endif // QUAKE4 diff --git a/neo/engine/ui/Window.h b/neo/engine/ui/Window.h index 97bf20e6..d4cf674c 100644 --- a/neo/engine/ui/Window.h +++ b/neo/engine/ui/Window.h @@ -1,27 +1,27 @@ /* =========================================================================== -IceTech GPL Source Code -Copyright (C) 2026 Justin Marshall +Doom 3 GPL Source Code +Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. -This file is part of the IceTech GPL Source Code (?IceTech Source Code?). +This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?). -IceTech Source Code is free software: you can redistribute it and/or modify +Doom 3 Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -IceTech Source Code is distributed in the hope that it will be useful, +Doom 3 Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with IceTech Source Code. If not, see . +along with Doom 3 Source Code. If not, see . -In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below. +In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. -If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com +If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ @@ -34,33 +34,39 @@ If you have questions concerning this license or the applicable additional terms #include "GuiScript.h" #include "SimpleWindow.h" -const int WIN_CHILD = 0x00000001; -const int WIN_CAPTION = 0x00000002; -const int WIN_BORDER = 0x00000004; -const int WIN_SIZABLE = 0x00000008; -const int WIN_MOVABLE = 0x00000010; -const int WIN_FOCUS = 0x00000020; -const int WIN_CAPTURE = 0x00000040; -const int WIN_HCENTER = 0x00000080; -const int WIN_VCENTER = 0x00000100; -const int WIN_MODAL = 0x00000200; -const int WIN_INTRANSITION = 0x00000400; -const int WIN_CANFOCUS = 0x00000800; -const int WIN_SELECTED = 0x00001000; -const int WIN_TRANSFORM = 0x00002000; -const int WIN_HOLDCAPTURE = 0x00004000; -const int WIN_NOWRAP = 0x00008000; -const int WIN_NOCLIP = 0x00010000; -const int WIN_INVERTRECT = 0x00020000; -const int WIN_NATURALMAT = 0x00040000; -const int WIN_NOCURSOR = 0x00080000; -const int WIN_MENUGUI = 0x00100000; -const int WIN_ACTIVE = 0x00200000; -const int WIN_SHOWCOORDS = 0x00400000; -const int WIN_SHOWTIME = 0x00800000; -const int WIN_WANTENTER = 0x01000000; +const int WIN_CHILD = 0x00000001; +const int WIN_CAPTION = 0x00000002; +const int WIN_BORDER = 0x00000004; +const int WIN_SIZABLE = 0x00000008; +const int WIN_MOVABLE = 0x00000010; +const int WIN_FOCUS = 0x00000020; +const int WIN_CAPTURE = 0x00000040; +const int WIN_HCENTER = 0x00000080; +const int WIN_VCENTER = 0x00000100; +const int WIN_MODAL = 0x00000200; +const int WIN_INTRANSITION = 0x00000400; +const int WIN_CANFOCUS = 0x00000800; +const int WIN_SELECTED = 0x00001000; +const int WIN_TRANSFORM = 0x00002000; +const int WIN_HOLDCAPTURE = 0x00004000; +const int WIN_NOWRAP = 0x00008000; +const int WIN_NOCLIP = 0x00010000; +const int WIN_INVERTRECT = 0x00020000; +const int WIN_NATURALMAT = 0x00040000; +const int WIN_NOCURSOR = 0x00080000; +const int WIN_MENUGUI = 0x00100000; +const int WIN_ACTIVE = 0x00200000; +const int WIN_SHOWCOORDS = 0x00400000; +const int WIN_SHOWTIME = 0x00800000; +const int WIN_WANTENTER = 0x01000000; +#ifdef QUAKE4 +const int WIN_ALWAYSTHINK = 0x08000000; +#endif -const int WIN_DESKTOP = 0x10000000; +const int WIN_DESKTOP = 0x10000000; +#ifdef QUAKE4 +const int WIN_CHATWINDOW = 0x20000000; +#endif const char CAPTION_HEIGHT[] = "16.0"; const char SCROLLER_SIZE[] = "16.0"; @@ -95,6 +101,9 @@ typedef enum { WOP_TYPE_VARI, WOP_TYPE_VARB, WOP_TYPE_COND +#ifdef QUAKE4 + , WOP_TYPE_VARFM +#endif } wexpOpType_t; typedef enum { @@ -103,12 +112,12 @@ typedef enum { } wexpRegister_t; typedef struct { - wexpOpType_t opType; + wexpOpType_t opType; intptr_t a, b, c, d; } wexpOp_t; struct idRegEntry { - const char *name; + const char* name; idRegister::REGTYPE type; int index; }; @@ -124,7 +133,7 @@ struct idTimeLineEvent { delete event; } int time; - idGuiScriptList *event; + idGuiScriptList* event; bool pending; size_t Size() { return sizeof(*this) + event->Size(); @@ -138,23 +147,23 @@ public: rvNamedEvent(const char* name) { mEvent = new idGuiScriptList; - mName = name; + mName = name; } ~rvNamedEvent(void) { delete mEvent; } - size_t Size() + size_t Size() { return sizeof(*this) + mEvent->Size(); } - + idStr mName; - idGuiScriptList* mEvent; + idGuiScriptList* mEvent; }; struct idTransitionData { - idWinVar *data; + idWinVar* data; int offset; idInterpolateAccelDecelLinear interp; }; @@ -163,14 +172,17 @@ struct idTransitionData { class idUserInterfaceLocal; class idWindow { public: - idWindow(idUserInterfaceLocal *gui); - idWindow(idDeviceContext *d, idUserInterfaceLocal *gui); + idWindow(idUserInterfaceLocal* gui); + idWindow(idDeviceContext* d, idUserInterfaceLocal* gui); virtual ~idWindow(); enum { ON_MOUSEENTER = 0, ON_MOUSEEXIT, ON_ACTION, +#ifdef QUAKE4 + ON_ACTIONRIGHT, // Q4 secondary / mouse2 action slot +#endif ON_ACTIVATE, ON_DEACTIVATE, ON_ESC, @@ -179,6 +191,24 @@ public: ON_ACTIONRELEASE, ON_ENTER, ON_ENTERRELEASE, +#ifdef QUAKE4 + ON_ESCRELEASE, // reserved Q4 slot + ON_GAINFOCUS, + ON_LOSEFOCUS, + ON_RESERVED15, // reserved Q4 slot + ON_INIT, + ON_JOYBUTTON3, + ON_JOYACTION, + ON_JOYBACK, + ON_JOYLSHOULDER, + ON_JOYRSHOULDER, + ON_JOYLEFT, + ON_JOYRIGHT, + ON_JOYDOWN, + ON_JOYUP, + ON_JOYBUTTON1, + ON_JOYBUTTON2, +#endif SCRIPT_COUNT }; @@ -194,66 +224,71 @@ public: ADJUST_BOTTOMLEFT }; - static const char *ScriptNames[SCRIPT_COUNT]; + static const char* ScriptNames[SCRIPT_COUNT]; static const idRegEntry RegisterVars[]; static const int NumRegisterVars; - void SetDC(idDeviceContext *d); + void SetDC(idDeviceContext* d); - idDeviceContext* GetDC ( void ) { return dc; } + idDeviceContext* GetDC(void) { return dc; } - idWindow *SetFocus(idWindow *w, bool scripts = true); + idWindow* SetFocus(idWindow* w, bool scripts = true); - idWindow *SetCapture(idWindow *w); - void SetParent(idWindow *w); + idWindow* SetCapture(idWindow* w); + void SetParent(idWindow* w); void SetFlag(unsigned int f); void ClearFlag(unsigned int f); - unsigned GetFlags() {return flags;}; + unsigned GetFlags() { return flags; }; void Move(float x, float y); - void BringToTop(idWindow *w); + void BringToTop(idWindow* w); void Adjust(float xd, float yd); - void SetAdjustMode(idWindow *child); + void SetAdjustMode(idWindow* child); void Size(float x, float y, float w, float h); void SetupFromState(); void SetupBackground(); - drawWin_t *FindChildByName(const char *name); - idSimpleWindow *FindSimpleWinByName(const char *_name); - idWindow *GetParent() { return parent; } - idUserInterfaceLocal *GetGui() {return gui;}; + drawWin_t* FindChildByName(const char* name); + idSimpleWindow* FindSimpleWinByName(const char* _name); + idWindow* GetParent() { return parent; } + idUserInterfaceLocal* GetGui() { return gui; }; bool Contains(float x, float y); size_t Size(); virtual size_t Allocated(); - idStr* GetStrPtrByName(const char *_name); + idStr* GetStrPtrByName(const char* _name); - virtual idWinVar *GetWinVarByName (const char *_name, bool winLookup = false, drawWin_t** owner = NULL); + virtual idWinVar* GetWinVarByName(const char* _name, bool winLookup = false, drawWin_t** owner = NULL); - INT_PTR GetWinVarOffset( idWinVar *wv, drawWin_t *dw ); + intptr_t GetWinVarOffset(idWinVar* wv, drawWin_t* dw); float GetMaxCharHeight(); float GetMaxCharWidth(); void SetFont(); - void SetInitialState(const char *_name); - void AddChild(idWindow *win); + void SetInitialState(const char* _name); + void AddChild(idWindow* win); void DebugDraw(int time, float x, float y); void CalcClientRect(float xofs, float yofs); void CommonInit(); void CleanUp(); - void DrawBorderAndCaption(const idRectangle &drawRect); + void DrawBorderAndCaption(const idRectangle& drawRect); void DrawCaption(int time, float x, float y); void SetupTransforms(float x, float y); - bool Contains(const idRectangle &sr, float x, float y); - const char *GetName() { return name; }; + bool Contains(const idRectangle& sr, float x, float y); + const char* GetName() { return name; }; - virtual bool Parse(idParser *src, bool rebuild = true); - virtual const char *HandleEvent(const sysEvent_t *event, bool *updateVisuals); + virtual bool Parse(idParser* src, bool rebuild = true); + virtual const char* HandleEvent(const sysEvent_t* event, bool* updateVisuals); void CalcRects(float x, float y); virtual void Redraw(float x, float y); - virtual void ArchiveToDictionary(idDict *dict, bool useNames = true); - virtual void InitFromDictionary(idDict *dict, bool byName = true); + virtual void ArchiveToDictionary(idDict* dict, bool useNames = true); + virtual void InitFromDictionary(idDict* dict, bool byName = true); virtual void PostParse(); - virtual void Activate( bool activate, idStr &act ); + virtual void Activate(bool activate, idStr& act); virtual void Trigger(); +#ifdef QUAKE4 + virtual void Init(); + virtual bool RunControllerScript(int script, const sysEvent_t* event, bool* updateVisuals); + virtual bool RouteJoystickChange(int xd, int yd); +#endif virtual void GainFocus(); virtual void LoseFocus(); virtual void GainCapture(); @@ -263,105 +298,115 @@ public: virtual void Draw(int time, float x, float y); virtual void MouseExit(); virtual void MouseEnter(); - virtual void DrawBackground(const idRectangle &drawRect); - virtual const char *RouteMouseCoords(float xd, float yd); - virtual void SetBuddy(idWindow *buddy) {}; - virtual void HandleBuddyUpdate(idWindow *buddy) {}; - virtual void StateChanged( bool redraw ); - virtual void ReadFromDemoFile( class idDemoFile *f, bool rebuild = true ); - virtual void WriteToDemoFile( class idDemoFile *f ); + virtual void DrawBackground(const idRectangle& drawRect); + virtual const char* RouteMouseCoords(float xd, float yd); + virtual void SetBuddy(idWindow* buddy) {}; + virtual void HandleBuddyUpdate(idWindow* buddy) {}; + virtual void StateChanged(bool redraw); + virtual void ReadFromDemoFile(class idDemoFile* f, bool rebuild = true); + virtual void WriteToDemoFile(class idDemoFile* f); // SaveGame support - void WriteSaveGameString( const char *string, idFile *savefile ); - void WriteSaveGameTransition( idTransitionData &trans, idFile *savefile ); - virtual void WriteToSaveGame( idFile *savefile ); - void ReadSaveGameString( idStr &string, idFile *savefile ); - void ReadSaveGameTransition( idTransitionData & trans, idFile *savefile ); - virtual void ReadFromSaveGame( idFile *savefile ); + void WriteSaveGameString(const char* string, idFile* savefile); + void WriteSaveGameTransition(idTransitionData& trans, idFile* savefile); + virtual void WriteToSaveGame(idFile* savefile); + void ReadSaveGameString(idStr& string, idFile* savefile); + void ReadSaveGameTransition(idTransitionData& trans, idFile* savefile); + virtual void ReadFromSaveGame(idFile* savefile); void FixupTransitions(); - virtual void HasAction(){}; - virtual void HasScripts(){}; + virtual void HasAction() {}; + virtual void HasScripts() {}; void FixupParms(); - void GetScriptString(const char *name, idStr &out); + void GetScriptString(const char* name, idStr& out); void SetScriptParams(); - bool HasOps() { return (ops.Num() > 0); }; + bool HasOps() { return (ops.Num() > 0); }; float EvalRegs(int test = -1, bool force = false); void StartTransition(); - void AddTransition(idWinVar *dest, idVec4 from, idVec4 to, int time, float accelTime, float decelTime); + void AddTransition(idWinVar* dest, idVec4 from, idVec4 to, int time, float accelTime, float decelTime); +#ifdef QUAKE4 + void ClearTransitions(); +#endif void ResetTime(int time); void ResetCinematics(); +#ifdef QUAKE4 + bool IsVisible() const; + void SetWrapper(int wrapper); +#endif int NumTransitions(); - bool ParseScript(idParser *src, idGuiScriptList &list, int *timeParm = NULL, bool allowIf = false); + bool ParseScript(idParser* src, idGuiScriptList& list, int* timeParm = NULL, bool allowIf = false); bool RunScript(int n); - bool RunScriptList(idGuiScriptList *src); - void SetRegs(const char *key, const char *val); - intptr_t ParseExpression( idParser *src, idWinVar *var = NULL, intptr_t component = 0 ); + bool RunScriptList(idGuiScriptList* src); + void SetRegs(const char* key, const char* val); + intptr_t ParseExpression(idParser* src, idWinVar* var = NULL, intptr_t component = 0); int ExpressionConstant(float f); - idRegisterList *RegList() { return ®List; } - void AddCommand(const char *cmd); - void AddUpdateVar(idWinVar *var); + idRegisterList* RegList() { return ®List; } + void AddCommand(const char* cmd); + void AddUpdateVar(idWinVar* var); bool Interactive(); bool ContainsStateVars(); - void SetChildWinVarVal(const char *name, const char *var, const char *val); - idWindow *GetFocusedChild(); - idWindow *GetCaptureChild(); - const char *GetComment() { return comment; } - void SetComment( const char * p) { comment = p; } + void SetChildWinVarVal(const char* name, const char* var, const char* val); + idWindow* GetFocusedChild(); + idWindow* GetCaptureChild(); + const char* GetComment() { return comment; } + void SetComment(const char* p) { comment = p; } idStr cmd; - virtual void RunNamedEvent ( const char* eventName ); + virtual void RunNamedEvent(const char* eventName); - void AddDefinedVar ( idWinVar* var ); + void AddDefinedVar(idWinVar* var); - idWindow* FindChildByPoint ( float x, float y, idWindow* below = NULL ); - int GetChildIndex ( idWindow* window ); - int GetChildCount ( void ); - idWindow* GetChild ( int index ); - void RemoveChild ( idWindow *win ); - bool InsertChild ( idWindow *win, idWindow* before ); + idWindow* FindChildByPoint(float x, float y, idWindow* below = NULL); + int GetChildIndex(idWindow* window); + int GetChildCount(void); + idWindow* GetChild(int index); + void RemoveChild(idWindow* win); + bool InsertChild(idWindow* win, idWindow* before); - void ScreenToClient ( idRectangle* rect ); - void ClientToScreen ( idRectangle* rect ); + void ScreenToClient(idRectangle* rect); + void ClientToScreen(idRectangle* rect); - bool UpdateFromDictionary ( idDict& dict ); + bool UpdateFromDictionary(idDict& dict); protected: friend class rvGEWindowWrapper; - idWindow* FindChildByPoint ( float x, float y, idWindow** below ); - void SetDefaults ( void ); + idWindow* FindChildByPoint(float x, float y, idWindow** below); +#ifdef QUAKE4 + void FindBestChild_r(int xd, int yd, int& startX, int& startY, int& bestX, int& bestY, idWindow* current, idWindow*& best); +#endif + void SetDefaults(void); friend class idSimpleWindow; friend class idUserInterfaceLocal; bool IsSimple(); void UpdateWinVars(); - void DisableRegister(const char *_name); + void DisableRegister(const char* _name); void Transition(); void Time(); bool RunTimeEvents(int time); void Dump(); int ExpressionTemporary(); - wexpOp_t *ExpressionOp(); - intptr_t EmitOp(intptr_t a, intptr_t b, wexpOpType_t opType, wexpOp_t **opp = NULL ); - intptr_t ParseEmitOp( idParser *src, intptr_t a, wexpOpType_t opType, int priority, wexpOp_t **opp = NULL ); - intptr_t ParseTerm( idParser *src, idWinVar *var = NULL, intptr_t component = 0 ); - intptr_t ParseExpressionPriority( idParser *src, int priority, idWinVar *var = NULL, intptr_t component = 0 ); - void EvaluateRegisters(float *registers); + wexpOp_t* ExpressionOp(); + intptr_t EmitOp(intptr_t a, intptr_t b, wexpOpType_t opType, wexpOp_t** opp = NULL); + intptr_t ParseEmitOp(idParser* src, intptr_t a, wexpOpType_t opType, int priority, wexpOp_t** opp = NULL); + intptr_t ParseTerm(idParser* src, idWinVar* var = NULL, intptr_t component = 0); + intptr_t ParseExpressionPriority(idParser* src, int priority, idWinVar* var = NULL, intptr_t component = 0); + void EvaluateRegisters(float* registers); void SaveExpressionParseState(); void RestoreExpressionParseState(); - void ParseBracedExpression(idParser *src); - bool ParseScriptEntry(const char *name, idParser *src); - bool ParseRegEntry(const char *name, idParser *src); - virtual bool ParseInternalVar(const char *name, idParser *src); - void ParseString(idParser *src, idStr &out); - void ParseVec4(idParser *src, idVec4 &out); - void ConvertRegEntry(const char *name, idParser *src, idStr &out, int tabs); + void ParseBracedExpression(idParser* src); + bool ParseScriptEntry(const char* name, idParser* src); + bool ParseRegEntry(const char* name, idParser* src); + virtual bool ParseInternalVar(const char* name, idParser* src); + void ParseString(idParser* src, idStr& out); + void ParseVec4(idParser* src, idVec4& out); + void ConvertRegEntry(const char* name, idParser* src, idStr& out, int tabs); float actualX; // physical coords float actualY; // '' @@ -373,7 +418,7 @@ protected: idVec2 origin; int timeLine; // time stamp used for various fx - float xOffset; + float xOffset; float yOffset; float forceAspectWidth; float forceAspectHeight; @@ -387,9 +432,15 @@ protected: idVec2 shear; signed char textShadow; +#ifdef QUAKE4 + signed char textStyle; +#endif unsigned char fontNum; unsigned char cursor; // signed char textAlign; +#ifdef QUAKE4 + float textSpacing; +#endif idWinBool noTime; // idWinBool visible; // @@ -409,45 +460,132 @@ protected: idList updateVars; idRectangle textRect; // text extented rect - const idMaterial *background; // background asset + const idMaterial* background; // background asset - idWindow *parent; // parent window + idWindow* parent; // parent window idList children; // child windows - idList drawWindows; + idList drawWindows; +#ifdef QUAKE4 + int startChildSearch; // Q4 child-lookup optimization + idWindow* currentChild; // controller navigation helper +#endif - idWindow *focusedChild; // if a child window has the focus - idWindow *captureChild; // if a child window has mouse capture - idWindow *overChild; // if a child window has mouse capture + idWindow* focusedChild; // if a child window has the focus + idWindow* captureChild; // if a child window has mouse capture + idWindow* overChild; // if a child window has mouse capture bool hover; - idDeviceContext *dc; + idDeviceContext* dc; - idUserInterfaceLocal *gui; + idUserInterfaceLocal* gui; static idCVar gui_debug; static idCVar gui_edit; - idGuiScriptList *scripts[SCRIPT_COUNT]; - bool *saveTemps; + idGuiScriptList* scripts[SCRIPT_COUNT]; + bool* saveTemps; idList timeLineEvents; idList transitions; +#ifdef QUAKE4 + idList transitionSubs; +#endif static bool registerIsTemporary[MAX_EXPRESSION_REGISTERS]; // statics to assist during parsing idList ops; // evaluate to make expressionRegisters idList expressionRegisters; - idList *saveOps; // evaluate to make expressionRegisters + idList* saveOps; // evaluate to make expressionRegisters idList namedEvents; // added named events - idList *saveRegs; + idList* saveRegs; idRegisterList regList; idWinBool hideCursor; }; -ID_INLINE void idWindow::AddDefinedVar( idWinVar* var ) { - definedVars.AddUnique( var ); +ID_INLINE void idWindow::AddDefinedVar(idWinVar* var) { + definedVars.AddUnique(var); } -#endif /* !__WINDOW_H__ */ + +#ifdef QUAKE4 +// Quake 4 added synthetic float-member window vars so expressions / transitions +// can address rect_x, rect_y, forecolor_w, etc. Doom 3 does not ship one, so +// we keep the helper local to Window.cpp. +class idWinFloatMember : public idWinVar { +public: + idWinFloatMember() : owner(NULL), component(0) {} + idWinFloatMember(idWinVar* base, int index) : owner(base), component(index) {} + + virtual void Init(const char* name, idWindow* win) { + idWinVar::Init(name, win); + } + virtual void Update() { + if (owner) { + owner->Update(); + } + } + virtual void Set(const char* value) { + if (!owner) { + return; + } + float f = static_cast(atof(value)); + if (idWinVec4* v4 = dynamic_cast(owner)) { + (*v4)[component] = f; + } + else if (idWinRectangle* r = dynamic_cast(owner)) { + switch (component) { + case 0: r->data.x = f; break; + case 1: r->data.y = f; break; + case 2: r->data.w = f; break; + case 3: r->data.h = f; break; + } + } + } + virtual const char* c_str() const { + return va("%g", x()); + } + virtual float x() const { + if (!owner) { + return 0.0f; + } + if (const idWinVec4* v4 = dynamic_cast(owner)) { + return (*v4)[component]; + } + if (const idWinRectangle* r = dynamic_cast(owner)) { + switch (component) { + case 0: return r->data.x; + case 1: return r->data.y; + case 2: return r->data.w; + case 3: return r->data.h; + } + } + return 0.0f; + } + virtual void WriteToSaveGame(idFile* savefile) { + idWinFloat temp; + temp = x(); + temp.WriteToSaveGame(savefile); + } + virtual void ReadFromSaveGame(idFile* savefile) { + idWinFloat temp; + temp.ReadFromSaveGame(savefile); + Set(va("%g", temp.data)); + } + virtual size_t Size() { + return sizeof(*this); + } + + idWinVar* GetOwner() const { return owner; } + int GetComponent() const { return component; } + +private: + idWinVar* owner; + int component; +}; + +#endif // QUAKE4 + + +#endif /* !__WINDOW_H__ */ \ No newline at end of file diff --git a/neo/engine/ui/Winvar.cpp b/neo/engine/ui/Winvar.cpp index 31229362..00fbca56 100644 --- a/neo/engine/ui/Winvar.cpp +++ b/neo/engine/ui/Winvar.cpp @@ -1,50 +1,52 @@ /* =========================================================================== -IceTech GPL Source Code -Copyright (C) 2026 Justin Marshall +Doom 3 GPL Source Code +Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. -This file is part of the IceTech GPL Source Code ("IceTech Source Code"). +This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?). -IceTech Source Code is free software: you can redistribute it and/or modify +Doom 3 Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -IceTech Source Code is distributed in the hope that it will be useful, +Doom 3 Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with IceTech Source Code. If not, see . +along with Doom 3 Source Code. If not, see . -In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below. +In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. -If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com +If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ #include "precompiled.h" -#include "Window.h" -#include "UserInterfaceLocal.h" -#include "Winvar.h" +#pragma hdrstop -idWinVar::idWinVar() { - guiDict = NULL; - name = NULL; +#include "Window.h" +#include "Winvar.h" +#include "UserInterfaceLocal.h" + +idWinVar::idWinVar() { + guiDict = NULL; + name = NULL; eval = true; } -idWinVar::~idWinVar() { - delete[] name; +idWinVar::~idWinVar() { + delete name; name = NULL; } -void idWinVar::SetGuiInfo(idDict *gd, const char *_name) { - guiDict = gd; - SetName(_name); +void idWinVar::SetGuiInfo(idDict *gd, const char *_name) { + guiDict = gd; + SetName(_name); } @@ -78,3 +80,4 @@ void idMultiWinVar::SetGuiInfo( idDict *dict ) { (*this)[i]->SetGuiInfo( dict, (*this)[i]->c_str() ); } } + diff --git a/neo/engine/ui/Winvar.h b/neo/engine/ui/Winvar.h index 5fcf76ee..ea0eb2ec 100644 --- a/neo/engine/ui/Winvar.h +++ b/neo/engine/ui/Winvar.h @@ -1,27 +1,27 @@ /* =========================================================================== -IceTech GPL Source Code -Copyright (C) 2026 Justin Marshall +Doom 3 GPL Source Code +Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. -This file is part of the IceTech GPL Source Code (?IceTech Source Code?). +This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?). -IceTech Source Code is free software: you can redistribute it and/or modify +Doom 3 Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -IceTech Source Code is distributed in the hope that it will be useful, +Doom 3 Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with IceTech Source Code. If not, see . +along with Doom 3 Source Code. If not, see . -In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below. +In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. -If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com +If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ @@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms #ifndef __WINVAR_H__ #define __WINVAR_H__ -static const char *VAR_GUIPREFIX = "gui::"; +static const char* VAR_GUIPREFIX = "gui::"; static const int VAR_GUIPREFIX_LEN = strlen(VAR_GUIPREFIX); class idWindow; @@ -38,44 +38,44 @@ public: idWinVar(); virtual ~idWinVar(); - void SetGuiInfo(idDict *gd, const char *_name); - const char *GetName() const { + void SetGuiInfo(idDict* gd, const char* _name); + const char* GetName() const { if (name) { if (guiDict && *name == '*') { return guiDict->GetString(&name[1]); } return name; } - return ""; + return ""; } - void SetName(const char *_name) { - delete []name; + void SetName(const char* _name) { + delete[]name; name = NULL; if (_name) { - name = new char[strlen(_name)+1]; - strcpy(name, _name); + name = new char[strlen(_name) + 1]; + strcpy(name, _name); } } - idWinVar &operator=( const idWinVar &other ) { + idWinVar& operator=(const idWinVar& other) { guiDict = other.guiDict; SetName(other.name); return *this; } - idDict *GetDict() const { return guiDict; } + idDict* GetDict() const { return guiDict; } bool NeedsUpdate() { return (guiDict != NULL); } - virtual void Init(const char *_name, idWindow* win) = 0; - virtual void Set(const char *val) = 0; + virtual void Init(const char* _name, idWindow* win) = 0; + virtual void Set(const char* val) = 0; virtual void Update() = 0; - virtual const char *c_str() const = 0; - virtual size_t Size() { size_t sz = (name) ? strlen(name) : 0; return sz + sizeof(*this); } + virtual const char* c_str() const = 0; + virtual size_t Size() { size_t sz = (name) ? strlen(name) : 0; return sz + sizeof(*this); } - virtual void WriteToSaveGame( idFile *savefile ) = 0; - virtual void ReadFromSaveGame( idFile *savefile ) = 0; + virtual void WriteToSaveGame(idFile* savefile) = 0; + virtual void ReadFromSaveGame(idFile* savefile) = 0; - virtual float x( void ) const = 0; + virtual float x(void) const = 0; void SetEval(bool b) { eval = b; @@ -83,10 +83,10 @@ public: bool GetEval() { return eval; } - + protected: - idDict *guiDict; - char *name; + idDict* guiDict; + char* name; bool eval; }; @@ -94,20 +94,21 @@ class idWinBool : public idWinVar { public: idWinBool() : idWinVar() {}; ~idWinBool() {}; - virtual void Init(const char *_name, idWindow *win) { idWinVar::Init(_name, win); + virtual void Init(const char* _name, idWindow* win) { + idWinVar::Init(_name, win); if (guiDict) { data = guiDict->GetBool(GetName()); } } - int operator==( const bool &other ) { return (other == data); } - bool &operator=( const bool &other ) { + int operator==(const bool& other) { return (other == data); } + bool& operator=(const bool& other) { data = other; if (guiDict) { guiDict->SetBool(GetName(), data); } return data; } - idWinBool &operator=( const idWinBool &other ) { + idWinBool& operator=(const idWinBool& other) { idWinVar::operator=(other); data = other.data; return *this; @@ -115,33 +116,33 @@ public: operator bool() const { return data; } - virtual void Set(const char *val) { - data = ( atoi( val ) != 0 ); + virtual void Set(const char* val) { + data = (atoi(val) != 0); if (guiDict) { guiDict->SetBool(GetName(), data); } } - virtual void Update() { - const char *s = GetName(); - if ( guiDict && s[0] != '\0' ) { - data = guiDict->GetBool( s ); + virtual void Update() { + const char* s = GetName(); + if (guiDict && s[0] != '\0') { + data = guiDict->GetBool(s); } } - virtual const char *c_str() const {return va("%i", data); } + virtual const char* c_str() const { return va("%i", data); } // SaveGames - virtual void WriteToSaveGame( idFile *savefile ) { - savefile->Write( &eval, sizeof( eval ) ); - savefile->Write( &data, sizeof( data ) ); + virtual void WriteToSaveGame(idFile* savefile) { + savefile->Write(&eval, sizeof(eval)); + savefile->Write(&data, sizeof(data)); } - virtual void ReadFromSaveGame( idFile *savefile ) { - savefile->Read( &eval, sizeof( eval ) ); - savefile->Read( &data, sizeof( data ) ); + virtual void ReadFromSaveGame(idFile* savefile) { + savefile->Read(&eval, sizeof(eval)); + savefile->Read(&data, sizeof(data)); } - virtual float x( void ) const { return data ? 1.0f : 0.0f; }; + virtual float x(void) const { return data ? 1.0f : 0.0f; }; protected: bool data; @@ -151,41 +152,41 @@ class idWinStr : public idWinVar { public: idWinStr() : idWinVar() {}; ~idWinStr() {}; - virtual void Init(const char *_name, idWindow *win) { + virtual void Init(const char* _name, idWindow* win) { idWinVar::Init(_name, win); if (guiDict) { data = guiDict->GetString(GetName()); - } + } } - int operator==( const idStr &other ) const { + int operator==(const idStr& other) const { return (other == data); } - int operator==( const char *other ) const { + int operator==(const char* other) const { return (data == other); } - idStr &operator=( const idStr &other ) { + idStr& operator=(const idStr& other) { data = other; if (guiDict) { guiDict->Set(GetName(), data); } return data; } - idWinStr &operator=( const idWinStr &other ) { + idWinStr& operator=(const idWinStr& other) { idWinVar::operator=(other); data = other.data; return *this; } - operator const char *() const { + operator const char* () const { return data.c_str(); } - operator const idStr &() const { + operator const idStr& () const { return data; } int LengthWithoutColors() { if (guiDict && name && *name) { data = guiDict->GetString(GetName()); } - return data.LengthWithoutColors(); + return data.Length(); } int Length() { if (guiDict && name && *name) { @@ -197,54 +198,54 @@ public: if (guiDict && name && *name) { data = guiDict->GetString(GetName()); } - data.RemoveColors(); + //data.RemoveColors(); } - virtual const char *c_str() const { + virtual const char* c_str() const { return data.c_str(); } - virtual void Set(const char *val) { + virtual void Set(const char* val) { data = val; - if ( guiDict ) { + if (guiDict) { guiDict->Set(GetName(), data); } } virtual void Update() { - const char *s = GetName(); - if ( guiDict && s[0] != '\0' ) { - data = guiDict->GetString( s ); + const char* s = GetName(); + if (guiDict && s[0] != '\0') { + data = guiDict->GetString(s); } } virtual size_t Size() { size_t sz = idWinVar::Size(); - return sz +data.Allocated(); + return sz + data.Allocated(); } // SaveGames - virtual void WriteToSaveGame( idFile *savefile ) { - savefile->Write( &eval, sizeof( eval ) ); + virtual void WriteToSaveGame(idFile* savefile) { + savefile->Write(&eval, sizeof(eval)); int len = data.Length(); - savefile->Write( &len, sizeof( len ) ); - if ( len > 0 ) { - savefile->Write( data.c_str(), len ); + savefile->Write(&len, sizeof(len)); + if (len > 0) { + savefile->Write(data.c_str(), len); } } - virtual void ReadFromSaveGame( idFile *savefile ) { - savefile->Read( &eval, sizeof( eval ) ); + virtual void ReadFromSaveGame(idFile* savefile) { + savefile->Read(&eval, sizeof(eval)); int len; - savefile->Read( &len, sizeof( len ) ); - if ( len > 0 ) { - data.Fill( ' ', len ); - savefile->Read( &data[0], len ); + savefile->Read(&len, sizeof(len)); + if (len > 0) { + data.Fill(' ', len); + savefile->Read(&data[0], len); } } // return wether string is emtpy - virtual float x( void ) const { return data[0] ? 1.0f : 0.0f; }; + virtual float x(void) const { return data[0] ? 1.0f : 0.0f; }; protected: idStr data; @@ -254,28 +255,28 @@ class idWinInt : public idWinVar { public: idWinInt() : idWinVar() {}; ~idWinInt() {}; - virtual void Init(const char *_name, idWindow *win) { - idWinVar::Init(_name, win); + virtual void Init(const char* _name, idWindow* win) { + idWinVar::Init(_name, win); if (guiDict) { data = guiDict->GetInt(GetName()); - } + } } - int &operator=( const int &other ) { + int& operator=(const int& other) { data = other; if (guiDict) { guiDict->SetInt(GetName(), data); } return data; } - idWinInt &operator=( const idWinInt &other ) { + idWinInt& operator=(const idWinInt& other) { idWinVar::operator=(other); data = other.data; return *this; } - operator int () const { + operator int() const { return data; } - virtual void Set(const char *val) { + virtual void Set(const char* val) { data = atoi(val);; if (guiDict) { guiDict->SetInt(GetName(), data); @@ -283,27 +284,27 @@ public: } virtual void Update() { - const char *s = GetName(); - if ( guiDict && s[0] != '\0' ) { - data = guiDict->GetInt( s ); + const char* s = GetName(); + if (guiDict && s[0] != '\0') { + data = guiDict->GetInt(s); } } - virtual const char *c_str() const { + virtual const char* c_str() const { return va("%i", data); } // SaveGames - virtual void WriteToSaveGame( idFile *savefile ) { - savefile->Write( &eval, sizeof( eval ) ); - savefile->Write( &data, sizeof( data ) ); + virtual void WriteToSaveGame(idFile* savefile) { + savefile->Write(&eval, sizeof(eval)); + savefile->Write(&data, sizeof(data)); } - virtual void ReadFromSaveGame( idFile *savefile ) { - savefile->Read( &eval, sizeof( eval ) ); - savefile->Read( &data, sizeof( data ) ); + virtual void ReadFromSaveGame(idFile* savefile) { + savefile->Read(&eval, sizeof(eval)); + savefile->Read(&data, sizeof(data)); } // no suitable conversion - virtual float x( void ) const { assert( false ); return 0.0f; }; + virtual float x(void) const { assert(false); return 0.0f; }; protected: int data; @@ -311,20 +312,24 @@ protected: class idWinFloat : public idWinVar { public: +#ifdef QUAKE4 + friend class idWinFloatPtr; +#endif + idWinFloat() : idWinVar() {}; ~idWinFloat() {}; - virtual void Init(const char *_name, idWindow *win) { + virtual void Init(const char* _name, idWindow* win) { idWinVar::Init(_name, win); if (guiDict) { data = guiDict->GetFloat(GetName()); - } + } } - idWinFloat &operator=( const idWinFloat &other ) { + idWinFloat& operator=(const idWinFloat& other) { idWinVar::operator=(other); data = other.data; return *this; } - float &operator=( const float &other ) { + float& operator=(const float& other) { data = other; if (guiDict) { guiDict->SetFloat(GetName(), data); @@ -334,41 +339,47 @@ public: operator float() const { return data; } - virtual void Set(const char *val) { + virtual void Set(const char* val) { data = atof(val); if (guiDict) { guiDict->SetFloat(GetName(), data); } } virtual void Update() { - const char *s = GetName(); - if ( guiDict && s[0] != '\0' ) { - data = guiDict->GetFloat( s ); + const char* s = GetName(); + if (guiDict && s[0] != '\0') { + data = guiDict->GetFloat(s); } } - virtual const char *c_str() const { + virtual const char* c_str() const { return va("%f", data); } - virtual void WriteToSaveGame( idFile *savefile ) { - savefile->Write( &eval, sizeof( eval ) ); - savefile->Write( &data, sizeof( data ) ); + virtual void WriteToSaveGame(idFile* savefile) { + savefile->Write(&eval, sizeof(eval)); + savefile->Write(&data, sizeof(data)); } - virtual void ReadFromSaveGame( idFile *savefile ) { - savefile->Read( &eval, sizeof( eval ) ); - savefile->Read( &data, sizeof( data ) ); + virtual void ReadFromSaveGame(idFile* savefile) { + savefile->Read(&eval, sizeof(eval)); + savefile->Read(&data, sizeof(data)); } - virtual float x( void ) const { return data; }; + virtual float x(void) const { return data; }; +#ifdef QUAKE4 +public: +#else protected: +#endif float data; }; + + class idWinRectangle : public idWinVar { public: idWinRectangle() : idWinVar() {}; ~idWinRectangle() {}; - virtual void Init(const char *_name, idWindow *win) { + virtual void Init(const char* _name, idWindow* win) { idWinVar::Init(_name, win); if (guiDict) { idVec4 v = guiDict->GetVec4(GetName()); @@ -376,19 +387,19 @@ public: data.y = v.y; data.w = v.z; data.h = v.w; - } + } } - - int operator==( const idRectangle &other ) const { + + int operator==(const idRectangle& other) const { return (other == data); } - idWinRectangle &operator=( const idWinRectangle &other ) { + idWinRectangle& operator=(const idWinRectangle& other) { idWinVar::operator=(other); data = other.data; return *this; } - idRectangle &operator=( const idVec4 &other ) { + idRectangle& operator=(const idVec4& other) { data = other; if (guiDict) { guiDict->SetVec4(GetName(), other); @@ -396,7 +407,7 @@ public: return data; } - idRectangle &operator=( const idRectangle &other ) { + idRectangle& operator=(const idRectangle& other) { data = other; if (guiDict) { idVec4 v = data.ToVec4(); @@ -404,8 +415,8 @@ public: } return data; } - - operator const idRectangle&() const { + + operator const idRectangle& () const { return data; } @@ -427,16 +438,17 @@ public: float Bottom() const { return data.Bottom(); } - idVec4 &ToVec4() { + idVec4& ToVec4() { static idVec4 ret; ret = data.ToVec4(); return ret; } - virtual void Set(const char *val) { - if ( strchr ( val, ',' ) ) { - sscanf( val, "%f,%f,%f,%f", &data.x, &data.y, &data.w, &data.h ); - } else { - sscanf( val, "%f %f %f %f", &data.x, &data.y, &data.w, &data.h ); + virtual void Set(const char* val) { + if (strchr(val, ',')) { + sscanf(val, "%f,%f,%f,%f", &data.x, &data.y, &data.w, &data.h); + } + else { + sscanf(val, "%f %f %f %f", &data.x, &data.y, &data.w, &data.h); } if (guiDict) { idVec4 v = data.ToVec4(); @@ -444,9 +456,9 @@ public: } } virtual void Update() { - const char *s = GetName(); - if ( guiDict && s[0] != '\0' ) { - idVec4 v = guiDict->GetVec4( s ); + const char* s = GetName(); + if (guiDict && s[0] != '\0') { + idVec4 v = guiDict->GetVec4(s); data.x = v.x; data.y = v.y; data.w = v.z; @@ -454,20 +466,24 @@ public: } } - virtual const char *c_str() const { + virtual const char* c_str() const { return data.ToVec4().ToString(); } - virtual void WriteToSaveGame( idFile *savefile ) { - savefile->Write( &eval, sizeof( eval ) ); - savefile->Write( &data, sizeof( data ) ); + virtual void WriteToSaveGame(idFile* savefile) { + savefile->Write(&eval, sizeof(eval)); + savefile->Write(&data, sizeof(data)); } - virtual void ReadFromSaveGame( idFile *savefile ) { - savefile->Read( &eval, sizeof( eval ) ); - savefile->Read( &data, sizeof( data ) ); + virtual void ReadFromSaveGame(idFile* savefile) { + savefile->Read(&eval, sizeof(eval)); + savefile->Read(&data, sizeof(data)); } +#ifdef QUAKE4 +public: +#else protected: +#endif idRectangle data; }; @@ -475,22 +491,22 @@ class idWinVec2 : public idWinVar { public: idWinVec2() : idWinVar() {}; ~idWinVec2() {}; - virtual void Init(const char *_name, idWindow *win) { + virtual void Init(const char* _name, idWindow* win) { idWinVar::Init(_name, win); if (guiDict) { data = guiDict->GetVec2(GetName()); - } + } } - int operator==( const idVec2 &other ) const { + int operator==(const idVec2& other) const { return (other == data); } - idWinVec2 &operator=( const idWinVec2 &other ) { + idWinVec2& operator=(const idWinVec2& other) { idWinVar::operator=(other); data = other.data; return *this; } - - idVec2 &operator=( const idVec2 &other ) { + + idVec2& operator=(const idVec2& other) { data = other; if (guiDict) { guiDict->SetVec2(GetName(), data); @@ -503,39 +519,40 @@ public: float y() const { return data.y; } - virtual void Set(const char *val) { - if ( strchr ( val, ',' ) ) { - sscanf( val, "%f,%f", &data.x, &data.y ); - } else { - sscanf( val, "%f %f", &data.x, &data.y); + virtual void Set(const char* val) { + if (strchr(val, ',')) { + sscanf(val, "%f,%f", &data.x, &data.y); + } + else { + sscanf(val, "%f %f", &data.x, &data.y); } if (guiDict) { guiDict->SetVec2(GetName(), data); } } - operator const idVec2&() const { + operator const idVec2& () const { return data; } virtual void Update() { - const char *s = GetName(); - if ( guiDict && s[0] != '\0' ) { - data = guiDict->GetVec2( s ); + const char* s = GetName(); + if (guiDict && s[0] != '\0') { + data = guiDict->GetVec2(s); } } - virtual const char *c_str() const { + virtual const char* c_str() const { return data.ToString(); } void Zero() { data.Zero(); } - virtual void WriteToSaveGame( idFile *savefile ) { - savefile->Write( &eval, sizeof( eval ) ); - savefile->Write( &data, sizeof( data ) ); + virtual void WriteToSaveGame(idFile* savefile) { + savefile->Write(&eval, sizeof(eval)); + savefile->Write(&data, sizeof(data)); } - virtual void ReadFromSaveGame( idFile *savefile ) { - savefile->Read( &eval, sizeof( eval ) ); - savefile->Read( &data, sizeof( data ) ); + virtual void ReadFromSaveGame(idFile* savefile) { + savefile->Read(&eval, sizeof(eval)); + savefile->Read(&data, sizeof(data)); } protected: @@ -543,31 +560,35 @@ protected: }; class idWinVec4 : public idWinVar { +#ifdef QUAKE4 + friend class idWinFloatPtr; +#endif + public: idWinVec4() : idWinVar() {}; ~idWinVec4() {}; - virtual void Init(const char *_name, idWindow *win) { + virtual void Init(const char* _name, idWindow* win) { idWinVar::Init(_name, win); if (guiDict) { data = guiDict->GetVec4(GetName()); - } + } } - int operator==( const idVec4 &other ) const { + int operator==(const idVec4& other) const { return (other == data); } - idWinVec4 &operator=( const idWinVec4 &other ) { + idWinVec4& operator=(const idWinVec4& other) { idWinVar::operator=(other); data = other.data; return *this; } - idVec4 &operator=( const idVec4 &other ) { + idVec4& operator=(const idVec4& other) { data = other; if (guiDict) { guiDict->SetVec4(GetName(), data); } return data; } - operator const idVec4&() const { + operator const idVec4& () const { return data; } @@ -586,46 +607,55 @@ public: float w() const { return data.w; } - virtual void Set(const char *val) { - if ( strchr ( val, ',' ) ) { - sscanf( val, "%f,%f,%f,%f", &data.x, &data.y, &data.z, &data.w ); - } else { - sscanf( val, "%f %f %f %f", &data.x, &data.y, &data.z, &data.w); + virtual void Set(const char* val) { + if (strchr(val, ',')) { + sscanf(val, "%f,%f,%f,%f", &data.x, &data.y, &data.z, &data.w); } - if ( guiDict ) { - guiDict->SetVec4( GetName(), data ); + else { + sscanf(val, "%f %f %f %f", &data.x, &data.y, &data.z, &data.w); + } + if (guiDict) { + guiDict->SetVec4(GetName(), data); } } virtual void Update() { - const char *s = GetName(); - if ( guiDict && s[0] != '\0' ) { - data = guiDict->GetVec4( s ); + const char* s = GetName(); + if (guiDict && s[0] != '\0') { + data = guiDict->GetVec4(s); } } - virtual const char *c_str() const { + virtual const char* c_str() const { return data.ToString(); } void Zero() { data.Zero(); - if ( guiDict ) { + if (guiDict) { guiDict->SetVec4(GetName(), data); } } - const idVec3 &ToVec3() const { + const idVec3& ToVec3() const { return data.ToVec3(); } - virtual void WriteToSaveGame( idFile *savefile ) { - savefile->Write( &eval, sizeof( eval ) ); - savefile->Write( &data, sizeof( data ) ); + virtual void WriteToSaveGame(idFile* savefile) { + savefile->Write(&eval, sizeof(eval)); + savefile->Write(&data, sizeof(data)); } - virtual void ReadFromSaveGame( idFile *savefile ) { - savefile->Read( &eval, sizeof( eval ) ); - savefile->Read( &data, sizeof( data ) ); + virtual void ReadFromSaveGame(idFile* savefile) { + savefile->Read(&eval, sizeof(eval)); + savefile->Read(&data, sizeof(data)); + } +#ifdef QUAKE4 + float operator[](int index) const { + return data[index]; } + float& operator[](int index) { + return data[index]; + } +#endif protected: idVec4 data; }; @@ -634,28 +664,28 @@ class idWinVec3 : public idWinVar { public: idWinVec3() : idWinVar() {}; ~idWinVec3() {}; - virtual void Init(const char *_name, idWindow *win) { + virtual void Init(const char* _name, idWindow* win) { idWinVar::Init(_name, win); if (guiDict) { data = guiDict->GetVector(GetName()); - } + } } - int operator==( const idVec3 &other ) const { + int operator==(const idVec3& other) const { return (other == data); } - idWinVec3 &operator=( const idWinVec3 &other ) { + idWinVec3& operator=(const idWinVec3& other) { idWinVar::operator=(other); data = other.data; return *this; } - idVec3 &operator=( const idVec3 &other ) { + idVec3& operator=(const idVec3& other) { data = other; if (guiDict) { guiDict->SetVector(GetName(), data); } return data; } - operator const idVec3&() const { + operator const idVec3& () const { return data; } @@ -671,19 +701,19 @@ public: return data.z; } - virtual void Set(const char *val) { - sscanf( val, "%f %f %f", &data.x, &data.y, &data.z); + virtual void Set(const char* val) { + sscanf(val, "%f %f %f", &data.x, &data.y, &data.z); if (guiDict) { guiDict->SetVector(GetName(), data); } } virtual void Update() { - const char *s = GetName(); - if ( guiDict && s[0] != '\0' ) { - data = guiDict->GetVector( s ); + const char* s = GetName(); + if (guiDict && s[0] != '\0') { + data = guiDict->GetVector(s); } } - virtual const char *c_str() const { + virtual const char* c_str() const { return data.ToString(); } @@ -694,13 +724,13 @@ public: } } - virtual void WriteToSaveGame( idFile *savefile ) { - savefile->Write( &eval, sizeof( eval ) ); - savefile->Write( &data, sizeof( data ) ); + virtual void WriteToSaveGame(idFile* savefile) { + savefile->Write(&eval, sizeof(eval)); + savefile->Write(&data, sizeof(data)); } - virtual void ReadFromSaveGame( idFile *savefile ) { - savefile->Read( &eval, sizeof( eval ) ); - savefile->Read( &data, sizeof( data ) ); + virtual void ReadFromSaveGame(idFile* savefile) { + savefile->Read(&eval, sizeof(eval)); + savefile->Read(&data, sizeof(data)); } protected: @@ -713,49 +743,51 @@ public: mat = NULL; }; ~idWinBackground() {}; - virtual void Init(const char *_name, idWindow *win) { + virtual void Init(const char* _name, idWindow* win) { idWinStr::Init(_name, win); if (guiDict) { data = guiDict->GetString(GetName()); - } + } } - int operator==( const idStr &other ) const { + int operator==(const idStr& other) const { return (other == data); } - int operator==( const char *other ) const { + int operator==(const char* other) const { return (data == other); } - idStr &operator=( const idStr &other ) { + idStr& operator=(const idStr& other) { data = other; if (guiDict) { guiDict->Set(GetName(), data); } if (mat) { - if ( data == "" ) { + if (data == "") { (*mat) = NULL; - } else { + } + else { (*mat) = declManager->FindMaterial(data); } } return data; } - idWinBackground &operator=( const idWinBackground &other ) { + idWinBackground& operator=(const idWinBackground& other) { idWinVar::operator=(other); data = other.data; mat = other.mat; if (mat) { - if ( data == "" ) { + if (data == "") { (*mat) = NULL; - } else { + } + else { (*mat) = declManager->FindMaterial(data); } } return *this; } - operator const char *() const { + operator const char* () const { return data.c_str(); } - operator const idStr &() const { + operator const idStr& () const { return data; } int Length() { @@ -764,32 +796,34 @@ public: } return data.Length(); } - virtual const char *c_str() const { + virtual const char* c_str() const { return data.c_str(); } - virtual void Set(const char *val) { + virtual void Set(const char* val) { data = val; if (guiDict) { guiDict->Set(GetName(), data); } if (mat) { - if ( data == "" ) { + if (data == "") { (*mat) = NULL; - } else { + } + else { (*mat) = declManager->FindMaterial(data); } } } virtual void Update() { - const char *s = GetName(); - if ( guiDict && s[0] != '\0' ) { - data = guiDict->GetString( s ); + const char* s = GetName(); + if (guiDict && s[0] != '\0') { + data = guiDict->GetString(s); if (mat) { - if ( data == "" ) { + if (data == "") { (*mat) = NULL; - } else { + } + else { (*mat) = declManager->FindMaterial(data); } } @@ -798,35 +832,36 @@ public: virtual size_t Size() { size_t sz = idWinVar::Size(); - return sz +data.Allocated(); + return sz + data.Allocated(); } - void SetMaterialPtr( const idMaterial **m ) { + void SetMaterialPtr(const idMaterial** m) { mat = m; } - virtual void WriteToSaveGame( idFile *savefile ) { - savefile->Write( &eval, sizeof( eval ) ); + virtual void WriteToSaveGame(idFile* savefile) { + savefile->Write(&eval, sizeof(eval)); int len = data.Length(); - savefile->Write( &len, sizeof( len ) ); - if ( len > 0 ) { - savefile->Write( data.c_str(), len ); + savefile->Write(&len, sizeof(len)); + if (len > 0) { + savefile->Write(data.c_str(), len); } } - virtual void ReadFromSaveGame( idFile *savefile ) { - savefile->Read( &eval, sizeof( eval ) ); + virtual void ReadFromSaveGame(idFile* savefile) { + savefile->Read(&eval, sizeof(eval)); int len; - savefile->Read( &len, sizeof( len ) ); - if ( len > 0 ) { - data.Fill( ' ', len ); - savefile->Read( &data[0], len ); + savefile->Read(&len, sizeof(len)); + if (len > 0) { + data.Fill(' ', len); + savefile->Read(&data[0], len); } - if ( mat ) { - if ( len > 0 ) { - (*mat) = declManager->FindMaterial( data ); - } else { + if (mat) { + if (len > 0) { + (*mat) = declManager->FindMaterial(data); + } + else { (*mat) = NULL; } } @@ -834,7 +869,7 @@ public: protected: idStr data; - const idMaterial **mat; + const idMaterial** mat; }; /* @@ -843,12 +878,73 @@ idMultiWinVar multiplexes access to a list if idWinVar* ================ */ -class idMultiWinVar : public idList< idWinVar * > { +class idMultiWinVar : public idList< idWinVar* > { public: - void Set( const char *val ); - void Update( void ); - void SetGuiInfo( idDict *dict ); + void Set(const char* val); + void Update(void); + void SetGuiInfo(idDict* dict); }; -#endif /* !__WINVAR_H__ */ + +#ifdef QUAKE4 +class idWinFloatPtr : public idWinVar { +public: + idWinFloatPtr() : idWinVar() {}; + ~idWinFloatPtr() {}; + virtual void Init(const char* _name, idWindow* win) { + + } + + float& operator=(const float& other) { + *data = other; + if (guiDict) { + guiDict->SetFloat(GetName(), *data); + } + return *data; + } + + void Bind(idWinVec4& ptr, int component) + { + switch (component) + { + case 0: + data = &ptr.data[0]; + break; + case 1: + data = &ptr.data[1]; + break; + case 2: + data = &ptr.data[2]; + break; + case 3: + data = &ptr.data[3]; + break; + } + } + + virtual void Set(const char* val) { + *data = atof(val); + if (guiDict) { + guiDict->SetFloat(GetName(), *data); + } + } + virtual void Update() { + const char* s = GetName(); + if (guiDict && s[0] != '\0') { + *data = guiDict->GetFloat(s); + } + } + virtual const char* c_str() const { + return va("%f", *data); + } + virtual void WriteToSaveGame(idFile* savefile) {} + virtual void ReadFromSaveGame(idFile* savefile) {} + virtual float x(void) const { return *data; }; +protected: + float* data; +}; +#endif // QUAKE4 + + +#endif /* !__WINVAR_H__ */ diff --git a/neo/quake4/cm/CollisionModel_load.cpp b/neo/quake4/cm/CollisionModel_load.cpp index faf47086..fb50d999 100644 --- a/neo/quake4/cm/CollisionModel_load.cpp +++ b/neo/quake4/cm/CollisionModel_load.cpp @@ -306,7 +306,7 @@ void idCollisionModelManagerLocal::LoadProcBSP( const char *name ) { } // jmarshall: quake 4 proc format - if (!src->ReadToken(&token) || token.Icmp(va("%s", PROC_FILEVERSION))) { + if (!src->ReadToken(&token)) { common->Printf("idRenderWorldLocal::InitFromMap: bad version '%s' instead of '%s'\n", token.c_str(), PROC_FILEVERSION); delete src; return; diff --git a/neo/quake4/game/Game.h b/neo/quake4/game/Game.h index 1e5710f2..290cb083 100644 --- a/neo/quake4/game/Game.h +++ b/neo/quake4/game/Game.h @@ -176,6 +176,7 @@ public: virtual void MenuFrame( void ) = 0; virtual byte* MT_GetMaterialTypeArray(idStr image, int& width, int& height) = 0; + virtual void MT_FreeMaterialTypeArray(byte* buffer) = 0; // RAVEN END // Runs a repeater frame diff --git a/neo/quake4/game/Game_local.cpp b/neo/quake4/game/Game_local.cpp index 2157f8ca..3e8af040 100644 --- a/neo/quake4/game/Game_local.cpp +++ b/neo/quake4/game/Game_local.cpp @@ -13,6 +13,10 @@ #include "Game_Log.h" // RAVEN END +#include "../bse/BSE_Envelope.h" +#include "../bse/BSE_Particle.h" +#include "../bse/BSE.h" + //#define UI_DEBUG 1 #ifdef GAME_DLL @@ -394,6 +398,11 @@ idGameLocal::Init initialize the game object, only happens once at startup, not each level load ============ */ +static idDecl* AllocEffectDecl(void) { + idDecl* decl = new rvDeclEffect(); + return decl; +} + // RAVEN BEGIN // jsinger: attempt to eliminate cross-DLL allocation issues extern idHashTable *visemeTable100; @@ -459,6 +468,9 @@ void idGameLocal::Init( void ) { declManager->RegisterDeclFolder("materials/types", ".mtt", DECL_MATERIALTYPE); declManager->RegisterDeclFolder("lipsync", ".lipsync", DECL_LIPSYNC); declManager->RegisterDeclFolder("playbacks", ".playback", DECL_PLAYBACK); + + declManager->RegisterDeclType("effect", DECL_EFFECT, AllocEffectDecl); + declManager->RegisterDeclFolder("effects", ".fx", DECL_EFFECT); // jmarshall end // jsinger: added to support serialization/deserialization of binary decls @@ -8417,7 +8429,16 @@ idGameLocal::MT_GetMaterialTypeArray ============ */ byte* idGameLocal::MT_GetMaterialTypeArray(idStr image, int& width, int& height) { - return MT_GetMaterialTypeArray(image, width, height); + return ::MT_GetMaterialTypeArray(image, width, height); +} + +/* +=========== +idGameLocal::MT_FreeMaterialTypeArray +============ +*/ +void idGameLocal::MT_FreeMaterialTypeArray(byte* buffer) { + free(buffer); } /* diff --git a/neo/quake4/game/Game_local.h b/neo/quake4/game/Game_local.h index 5bd009e8..b65bfd27 100644 --- a/neo/quake4/game/Game_local.h +++ b/neo/quake4/game/Game_local.h @@ -577,6 +577,7 @@ public: // RAVEN END virtual byte* MT_GetMaterialTypeArray(idStr image, int& width, int& height); + virtual void MT_FreeMaterialTypeArray(byte* buffer); virtual int GetTimeGroupTime(int timeGroup); virtual void SelectTimeGroup(int timeGroup); diff --git a/neo/quake4/idLib/LexerFactory.cpp b/neo/quake4/idLib/LexerFactory.cpp index 534f912e..596fbf2c 100644 --- a/neo/quake4/idLib/LexerFactory.cpp +++ b/neo/quake4/idLib/LexerFactory.cpp @@ -25,7 +25,7 @@ int LexerFactory::GetReadBinary() { if(cvarSystem->GetCVarBool("com_binaryRead")) { - return LEXFL_READBINARY; + return 0; } else { @@ -42,10 +42,10 @@ int LexerFactory::GetWriteBinary() case 0: break; case 1: - ret = LEXFL_WRITEBINARY; + ret = 0; break; case 2: - ret = LEXFL_WRITEBINARY | LEXFL_BYTESWAP; + ret = 0; break; }