From cd392e50e92a45120754be10fdd263a2534ce203 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 13 Mar 2017 14:42:14 +0100 Subject: [PATCH] - added a dummy struct named '_' to define global variables. This can only be used internally. This method was chosen because it avoids adding variable declarations to the global namespace which would have required a lot more work while polluting the grammar. This way the global variables can be handled by a small bit of special coding in the struct generator. --- src/c_bind.cpp | 3 + src/d_dehacked.cpp | 1 + src/g_game.cpp | 15 +++ src/g_level.cpp | 2 +- src/gi.cpp | 1 + src/menu/menu.cpp | 4 +- src/menu/menudef.cpp | 2 + src/namedef.h | 1 + src/scripting/thingdef_data.cpp | 138 +--------------------- src/scripting/vm/vm.h | 7 +- src/scripting/zscript/zcc_compile.cpp | 52 +++++--- src/teaminfo.cpp | 3 +- src/v_video.cpp | 14 +++ wadsrc/static/zscript/base.txt | 43 +++++++ wadsrc/static/zscript/menu/optionmenu.txt | 2 +- 15 files changed, 135 insertions(+), 153 deletions(-) diff --git a/src/c_bind.cpp b/src/c_bind.cpp index 65cdc1757..540c77f7b 100644 --- a/src/c_bind.cpp +++ b/src/c_bind.cpp @@ -158,6 +158,9 @@ FKeyBindings Bindings; FKeyBindings DoubleBindings; FKeyBindings AutomapBindings; +DEFINE_GLOBAL(Bindings) +DEFINE_GLOBAL(AutomapBindings) + static unsigned int DClickTime[NUM_KEYS]; static uint8_t DClicked[(NUM_KEYS+7)/8]; diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index a4ff314a7..d2c8f3b25 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -212,6 +212,7 @@ DehInfo deh = 40, // BFG cells per shot }; +DEFINE_GLOBAL(deh) DEFINE_FIELD_X(DehInfo, DehInfo, MaxSoulsphere) DEFINE_FIELD_X(DehInfo, DehInfo, ExplosionStyle) DEFINE_FIELD_X(DehInfo, DehInfo, ExplosionAlpha) diff --git a/src/g_game.cpp b/src/g_game.cpp index 11c5210e5..4bb55ad49 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2982,3 +2982,18 @@ bool G_CheckDemoStatus (void) return false; } + +DEFINE_GLOBAL(players) +DEFINE_GLOBAL(playeringame) +DEFINE_GLOBAL(PlayerClasses) +DEFINE_GLOBAL_NAMED(Skins, PlayerSkins) +DEFINE_GLOBAL(consoleplayer) +DEFINE_GLOBAL_NAMED(PClassActor::AllActorClasses, AllActorClasses) +DEFINE_GLOBAL(validcount) +DEFINE_GLOBAL(multiplayer) +DEFINE_GLOBAL(gameaction) +DEFINE_GLOBAL(gamestate) +DEFINE_GLOBAL(skyflatnum) +DEFINE_GLOBAL_NAMED(bglobal.freeze, globalfreeze) +DEFINE_GLOBAL(gametic) +DEFINE_GLOBAL(demoplayback) diff --git a/src/g_level.cpp b/src/g_level.cpp index e1f77b624..f8c92a271 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1901,7 +1901,7 @@ void FLevelLocals::AddScroller (int secnum) // // //========================================================================== - +DEFINE_GLOBAL(level); DEFINE_FIELD(FLevelLocals, sectors) DEFINE_FIELD(FLevelLocals, lines) DEFINE_FIELD(FLevelLocals, sides) diff --git a/src/gi.cpp b/src/gi.cpp index d30902045..cf28e96be 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -45,6 +45,7 @@ gameinfo_t gameinfo; +DEFINE_GLOBAL(gameinfo) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, backpacktype) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, Armor2Percent) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, ArmorIcon1) diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index ca9659376..797bd5a50 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -1057,7 +1057,9 @@ CCMD(undocolorpic) } - +DEFINE_GLOBAL(menuactive) +DEFINE_GLOBAL(BackbuttonTime) +DEFINE_GLOBAL(BackbuttonAlpha) DEFINE_FIELD(DMenu, mParentMenu) DEFINE_FIELD(DMenu, mMouseCapture); diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index a9fd42773..04015fc5b 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -67,6 +67,8 @@ PClass *DefaultOptionMenuClass; void I_BuildALDeviceList(FOptionValues *opt); +DEFINE_GLOBAL_NAMED(OptionSettings, OptionMenuSettings) + DEFINE_ACTION_FUNCTION(FOptionValues, GetCount) { PARAM_PROLOGUE; diff --git a/src/namedef.h b/src/namedef.h index 91fd28626..28e2ff8c4 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -1,6 +1,7 @@ // 'None' must always be the first name. xx(None) xx(Null) +xx(_) xx(Super) xx(Object) diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index db2abf597..6ff75cc7b 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -664,11 +664,12 @@ AFuncDesc *FindFunction(PStruct *cls, const char * string) FieldDesc *FindField(PStruct *cls, const char * string) { int min = 0, max = FieldTable.Size() - 1; + const char * cname = cls ? cls->TypeName.GetChars() : ""; while (min <= max) { int mid = (min + max) / 2; - int lexval = stricmp(cls->TypeName.GetChars(), FieldTable[mid].ClassName + 1); + int lexval = stricmp(cname, FieldTable[mid].ClassName + 1); if (lexval == 0) lexval = stricmp(string, FieldTable[mid].FieldName); if (lexval == 0) { @@ -740,9 +741,7 @@ static int fieldcmp(const void * a, const void * b) void InitThingdef() { - // Create all global variables here because this cannot be done on the script side and really isn't worth adding support for. - // Also create all special fields here that cannot be declared by script syntax plus the pointer serializers. Doing all these with class overrides would be a bit messy. - + // Some native types need size and serialization information added before the scripts get compiled. auto secplanestruct = NewNativeStruct("Secplane", nullptr); secplanestruct->Size = sizeof(secplane_t); secplanestruct->Align = alignof(secplane_t); @@ -853,140 +852,11 @@ void InitThingdef() } ); - // expose the global validcount variable. - PField *vcf = new PField("validcount", TypeSInt32, VARF_Native | VARF_Static, (intptr_t)&validcount); - Namespaces.GlobalNamespace->Symbols.AddSymbol(vcf); - - // expose the global Multiplayer variable. - PField *multif = new PField("multiplayer", TypeBool, VARF_Native | VARF_ReadOnly | VARF_Static, (intptr_t)&multiplayer); - Namespaces.GlobalNamespace->Symbols.AddSymbol(multif); - - // set up a variable for the global level data structure - PStruct *lstruct = NewNativeStruct("LevelLocals", nullptr); - PField *levelf = new PField("level", lstruct, VARF_Native | VARF_Static, (intptr_t)&level); - Namespaces.GlobalNamespace->Symbols.AddSymbol(levelf); - - auto aact = NewPointer(NewStaticArray(NewClassPointer(RUNTIME_CLASS(AActor))), true); - PField *aacf = new PField("AllActorClasses", aact, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&PClassActor::AllActorClasses); - Namespaces.GlobalNamespace->Symbols.AddSymbol(aacf); - - auto plrcls = NewPointer(NewStaticArray(playerclassstruct), false); - PField *plrclsf = new PField("PlayerClasses", plrcls, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&PlayerClasses); - Namespaces.GlobalNamespace->Symbols.AddSymbol(plrclsf); - - auto plrskn = NewPointer(NewStaticArray(playerskinstruct), false); - PField *plrsknf = new PField("PlayerSkins", plrskn, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&Skins); - Namespaces.GlobalNamespace->Symbols.AddSymbol(plrsknf); - - auto teamst = NewPointer(NewStaticArray(teamstruct), false); - PField *teamf = new PField("Teams", teamst, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&Teams); - Namespaces.GlobalNamespace->Symbols.AddSymbol(teamf); - - auto bindcls = NewNativeStruct("KeyBindings", nullptr); - PField *binding = new PField("Bindings", bindcls, VARF_Native | VARF_Static, (intptr_t)&Bindings); - Namespaces.GlobalNamespace->Symbols.AddSymbol(binding); - binding = new PField("AutomapBindings", bindcls, VARF_Native | VARF_Static, (intptr_t)&AutomapBindings); - Namespaces.GlobalNamespace->Symbols.AddSymbol(binding); - - // set up a variable for the DEH data - PStruct *dstruct = NewNativeStruct("DehInfo", nullptr); - PField *dehf = new PField("deh", dstruct, VARF_Native | VARF_Static, (intptr_t)&deh); - Namespaces.GlobalNamespace->Symbols.AddSymbol(dehf); - - // set up a variable for the global gameinfo data - PStruct *gistruct = NewNativeStruct("GameInfoStruct", nullptr); - PField *gi = new PField("gameinfo", gistruct, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&gameinfo); - Namespaces.GlobalNamespace->Symbols.AddSymbol(gi); - - // set up a variable for the global players array. - PArray *parray = NewArray(pstruct, MAXPLAYERS); - PField *fieldptr = new PField("players", parray, VARF_Native | VARF_Static, (intptr_t)&players); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - parray = NewArray(TypeBool, MAXPLAYERS); - fieldptr = new PField("playeringame", parray, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&playeringame); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("gameaction", TypeUInt32, VARF_Native | VARF_Static, (intptr_t)&gameaction); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("gamestate", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&gamestate); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("skyflatnum", TypeTextureID, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&skyflatnum); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("globalfreeze", TypeUInt8, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&bglobal.freeze); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("consoleplayer", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&consoleplayer); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - auto fontptr = NewPointer(NewNativeStruct("Font", nullptr)); - - fieldptr = new PField("smallfont", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&SmallFont); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("smallfont2", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&SmallFont2); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("bigfont", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&BigFont); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("confont", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&ConFont); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("intermissionfont", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&IntermissionFont); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("CleanXFac", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanXfac); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("CleanYFac", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanYfac); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("CleanWidth", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanWidth); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("CleanHeight", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanHeight); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("CleanXFac_1", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanXfac_1); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("CleanYFac_1", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanYfac_1); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("CleanWidth_1", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanWidth_1); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("CleanHeight_1", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanHeight_1); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("menuactive", TypeSInt32, VARF_Native | VARF_Static, (intptr_t)&menuactive); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("OptionMenuSettings", NewStruct("FOptionMenuSettings", nullptr), VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&OptionSettings); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("gametic", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&gametic); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("demoplayback", TypeBool, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&demoplayback); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("BackbuttonTime", TypeSInt32, VARF_Native | VARF_Static, (intptr_t)&BackbuttonTime); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - fieldptr = new PField("BackbuttonAlpha", TypeFloat32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&BackbuttonAlpha); - Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - - // Argh. It sucks when bad hacks need to be supported. WP_NOCHANGE is just a bogus pointer but it used everywhere as a special flag. // It cannot be defined as constant because constants can either be numbers or strings but nothing else, so the only 'solution' // is to create a static variable from it and reference that in the script. Yuck!!! wpnochg = WP_NOCHANGE; - fieldptr = new PField("WP_NOCHANGE", NewPointer(RUNTIME_CLASS(AWeapon), false), VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&wpnochg); + PField *fieldptr = new PField("WP_NOCHANGE", NewPointer(RUNTIME_CLASS(AWeapon), false), VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&wpnochg); Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); // synthesize a symbol for each flag from the flag name tables to avoid redundant declaration of them. diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h index df5d8a398..4b1f406b1 100644 --- a/src/scripting/vm/vm.h +++ b/src/scripting/vm/vm.h @@ -1170,7 +1170,12 @@ struct AFuncDesc MSVC_FSEG FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr GCC_FSEG = &VMField_##cls##_##scriptname; #define DEFINE_GLOBAL(name) \ - static const FieldDesc VMGlobal_##name = { nullptr, #name, (intptr_t)&name, (unsigned)sizeof(name), 0 }; \ + static const FieldDesc VMGlobal_##name = { "", #name, (intptr_t)&name, (unsigned)sizeof(name), 0 }; \ + extern FieldDesc const *const VMGlobal_##name##_HookPtr; \ + MSVC_FSEG FieldDesc const *const VMGlobal_##name##_HookPtr GCC_FSEG = &VMGlobal_##name; + +#define DEFINE_GLOBAL_NAMED(iname, name) \ + static const FieldDesc VMGlobal_##name = { "", #name, (intptr_t)&iname, (unsigned)sizeof(iname), 0 }; \ extern FieldDesc const *const VMGlobal_##name##_HookPtr; \ MSVC_FSEG FieldDesc const *const VMGlobal_##name##_HookPtr GCC_FSEG = &VMGlobal_##name; diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index 6202be534..7dc916be2 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -487,7 +487,13 @@ void ZCCCompiler::CreateStructTypes() syms = &OutNamespace->Symbols; } - if (s->strct->Flags & ZCC_Native) + if (s->NodeName() == NAME__ && Wads.GetLumpFile(Lump) == 0) + { + // This is just a container for syntactic purposes. + s->strct->Type = nullptr; + continue; + } + else if (s->strct->Flags & ZCC_Native) { s->strct->Type = NewNativeStruct(s->NodeName(), outer); } @@ -776,7 +782,8 @@ void ZCCCompiler::CompileAllConstants() } for (auto s : Structs) { - CopyConstants(constantwork, s->Constants, s->Type(), &s->Type()->Symbols); + if (s->Type() != nullptr) + CopyConstants(constantwork, s->Constants, s->Type(), &s->Type()->Symbols); } // Before starting to resolve the list, let's create symbols for all already resolved ones first (i.e. all literal constants), to reduce work. @@ -1048,7 +1055,7 @@ void ZCCCompiler::CompileAllFields() donesomething = false; for (unsigned i = 0; i < Structs.Size(); i++) { - if (CompileFields(Structs[i]->Type(), Structs[i]->Fields, Structs[i]->Outer, &Structs[i]->TreeNodes, true)) + if (CompileFields(Structs[i]->Type(), Structs[i]->Fields, Structs[i]->Outer, Structs[i]->Type() == 0? GlobalTreeNodes : &Structs[i]->TreeNodes, true)) { // Remove from the list if all fields got compiled. Structs.Delete(i--); @@ -1132,10 +1139,13 @@ bool ZCCCompiler::CompileFields(PStruct *type, TArray &Fiel if (field->Flags & ZCC_Transient) varflags |= VARF_Transient; if (mVersion >= MakeVersion(2, 4, 0)) { - if (type->ObjectFlags & OF_UI) - varflags |= VARF_UI; - if (type->ObjectFlags & OF_Play) - varflags |= VARF_Play; + if (type != nullptr) + { + if (type->ObjectFlags & OF_UI) + varflags |= VARF_UI; + if (type->ObjectFlags & OF_Play) + varflags |= VARF_Play; + } if (field->Flags & ZCC_UIFlag) varflags = FScopeBarrier::ChangeSideInFlags(varflags, FScopeBarrier::Side_UI); if (field->Flags & ZCC_Play) @@ -1202,21 +1212,33 @@ bool ZCCCompiler::CompileFields(PStruct *type, TArray &Fiel fd = FindField(type, FName(name->Name).GetChars()); if (fd == nullptr) { - Error(field, "The member variable '%s.%s' has not been exported from the executable.", type->TypeName.GetChars(), FName(name->Name).GetChars()); + Error(field, "The member variable '%s.%s' has not been exported from the executable.", type == nullptr? "" : type->TypeName.GetChars(), FName(name->Name).GetChars()); } // For native structs a size check cannot be done because they normally have no size. But for a native reference they are still fine. else if (thisfieldtype->Size != ~0u && thisfieldtype->Size != fd->FieldSize && fd->BitValue == 0 && !thisfieldtype->IsA(RUNTIME_CLASS(PNativeStruct))) { - Error(field, "The member variable '%s.%s' has mismatching sizes in internal and external declaration. (Internal = %d, External = %d)", type->TypeName.GetChars(), FName(name->Name).GetChars(), fd->FieldSize, thisfieldtype->Size); + Error(field, "The member variable '%s.%s' has mismatching sizes in internal and external declaration. (Internal = %d, External = %d)", type == nullptr ? "" : type->TypeName.GetChars(), FName(name->Name).GetChars(), fd->FieldSize, thisfieldtype->Size); } // Q: Should we check alignment, too? A mismatch may be an indicator for bad assumptions. - else + else if (type != nullptr) { // for bit fields the type must point to the source variable. if (fd->BitValue != 0) thisfieldtype = fd->FieldSize == 1 ? TypeUInt8 : fd->FieldSize == 2 ? TypeUInt16 : TypeUInt32; auto f = type->AddNativeField(name->Name, thisfieldtype, fd->FieldOffset, varflags, fd->BitValue); if (field->Flags & (ZCC_Version | ZCC_Deprecated)) f->mVersion = field->Version; } + else + { + // This is a global variable. + if (fd->BitValue != 0) thisfieldtype = fd->FieldSize == 1 ? TypeUInt8 : fd->FieldSize == 2 ? TypeUInt16 : TypeUInt32; + PField *field = new PField(name->Name, thisfieldtype, varflags | VARF_Native | VARF_Static, fd->FieldOffset, fd->BitValue); + + if (OutNamespace->Symbols.AddSymbol(field) == nullptr) + { // name is already in use + field->Destroy(); + return nullptr; + } + } } } else if (hasnativechildren) @@ -1432,7 +1454,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n { Error(field, "%s: @ not allowed for user scripts", name.GetChars()); } - retval = ResolveUserType(btype, &outertype->Symbols, true); + retval = ResolveUserType(btype, outertype? &outertype->Symbols : nullptr, true); break; case ZCC_UserType: @@ -1456,7 +1478,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n break; default: - retval = ResolveUserType(btype, &outertype->Symbols, false); + retval = ResolveUserType(btype, outertype ? &outertype->Symbols : nullptr, false); break; } break; @@ -1515,7 +1537,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n // This doesn't check the class list directly but the current symbol table to ensure that // this does not reference a type that got shadowed by a more local definition. // We first look in the current class and its parents, and then in the current namespace and its parents. - auto sym = outertype->Symbols.FindSymbol(ctype->Restriction->Id, true); + auto sym = outertype ? outertype->Symbols.FindSymbol(ctype->Restriction->Id, true) : nullptr; if (sym == nullptr) sym = OutNamespace->Symbols.FindSymbol(ctype->Restriction->Id, true); if (sym == nullptr) { @@ -1562,8 +1584,10 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n PType *ZCCCompiler::ResolveUserType(ZCC_BasicType *type, PSymbolTable *symt, bool nativetype) { // Check the symbol table for the identifier. - PSymbol *sym = symt->FindSymbol(type->UserType->Id, true); + PSymbol *sym = nullptr; + // We first look in the current class and its parents, and then in the current namespace and its parents. + if (symt != nullptr) sym = symt->FindSymbol(type->UserType->Id, true); if (sym == nullptr) sym = OutNamespace->Symbols.FindSymbol(type->UserType->Id, true); if (sym != nullptr && sym->IsKindOf(RUNTIME_CLASS(PSymbolType))) { diff --git a/src/teaminfo.cpp b/src/teaminfo.cpp index b9d5d24aa..0658545b3 100644 --- a/src/teaminfo.cpp +++ b/src/teaminfo.cpp @@ -335,4 +335,5 @@ CCMD (teamlist) } -DEFINE_FIELD_NAMED(FTeam, m_Name, mName) \ No newline at end of file +DEFINE_GLOBAL(Teams) +DEFINE_FIELD_NAMED(FTeam, m_Name, mName) diff --git a/src/v_video.cpp b/src/v_video.cpp index 4fcce944c..c942cb9fe 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1783,3 +1783,17 @@ CCMD(vid_listadapters) if (Video != NULL) Video->DumpAdapters(); } + +DEFINE_GLOBAL(SmallFont) +DEFINE_GLOBAL(SmallFont2) +DEFINE_GLOBAL(BigFont) +DEFINE_GLOBAL(ConFont) +DEFINE_GLOBAL(IntermissionFont) +DEFINE_GLOBAL(CleanXfac) +DEFINE_GLOBAL(CleanYfac) +DEFINE_GLOBAL(CleanWidth) +DEFINE_GLOBAL(CleanHeight) +DEFINE_GLOBAL(CleanXfac_1) +DEFINE_GLOBAL(CleanYfac_1) +DEFINE_GLOBAL(CleanWidth_1) +DEFINE_GLOBAL(CleanHeight_1) diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 3b08b8170..e509702e6 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -1,3 +1,46 @@ +struct _ native +{ + native readonly Array > AllActorClasses; + native readonly Array<@PlayerClass> PlayerClasses; + native readonly Array<@PlayerSkin> PlayerSkins; + native readonly Array<@Team> Teams; + native int validcount; + native readonly bool multiplayer; + native play @LevelLocals level; + native @KeyBindings Bindings; + native @KeyBindings AutomapBindings; + native play @DehInfo deh; + native readonly @GameInfoStruct gameinfo; + native play @PlayerInfo players[MAXPLAYERS]; + native readonly bool playeringame[MAXPLAYERS]; + + native play uint gameaction; + native readonly int gamestate; + native readonly TextureID skyflatnum; + native readonly uint8 globalfreeze; + native readonly int consoleplayer; + native readonly Font smallfont; + native readonly Font smallfont2; + native readonly Font bigfont; + native readonly Font confont; + native readonly Font intermissionfont; + native readonly int CleanXFac; + native readonly int CleanYFac; + native readonly int CleanWidth; + native readonly int CleanHeight; + native readonly int CleanXFac_1; + native readonly int CleanYFac_1; + native readonly int CleanWidth_1; + native readonly int CleanHeight_1; + native ui int menuactive; + native readonly @FOptionMenuSettings OptionMenuSettings; + native readonly int gametic; + native readonly bool demoplayback; + native ui int BackbuttonTime; + native ui float BackbuttonAlpha; + +} + struct TexMan { enum EUseTypes diff --git a/wadsrc/static/zscript/menu/optionmenu.txt b/wadsrc/static/zscript/menu/optionmenu.txt index 99405cd88..dc428d1de 100644 --- a/wadsrc/static/zscript/menu/optionmenu.txt +++ b/wadsrc/static/zscript/menu/optionmenu.txt @@ -32,7 +32,7 @@ ** */ -struct FOptionMenuSettings version("2.4") +struct FOptionMenuSettings native version("2.4") { int mTitleColor; int mFontColor;