diff --git a/src/d_player.h b/src/d_player.h index fdcd29e6a4..4eae01926e 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -250,7 +250,8 @@ struct userinfo_t : TMap } int GetGender() const { - return *static_cast(*CheckKey(NAME_Gender)); + auto cvar = static_cast(*CheckKey(NAME_Gender)); + return cvar? *cvar : 0; } bool GetNoAutostartMap() const { diff --git a/src/g_dumpinfo.cpp b/src/g_dumpinfo.cpp index 63bda28ff2..c21525b8b3 100644 --- a/src/g_dumpinfo.cpp +++ b/src/g_dumpinfo.cpp @@ -42,6 +42,7 @@ #include "w_wad.h" #include "v_text.h" #include "c_functions.h" +#include "gstrings.h" //========================================================================== // @@ -404,3 +405,22 @@ CCMD(listsnapshots) } } + +CCMD(printlocalized) +{ + if (argv.argc() > 1) + { + if (argv.argc() > 2) + { + FString lang = argv[2]; + lang.ToLower(); + if (lang.Len() >= 2) + { + Printf("%s\n", GStrings.GetLanguageString(argv[1], MAKE_ID(lang[0], lang[1], lang[2], 0))); + return; + } + } + Printf("%s\n", GStrings(argv[1])); + } + +} diff --git a/src/gamedata/fonts/v_font.cpp b/src/gamedata/fonts/v_font.cpp index 9f595788d5..0ed18de511 100644 --- a/src/gamedata/fonts/v_font.cpp +++ b/src/gamedata/fonts/v_font.cpp @@ -857,6 +857,11 @@ int stripaccent(int code) static const uint16_t u200map[] = {0xc4, 0xe4, 0xc2, 0xe2, 0xcb, 0xeb, 0xca, 0xea, 0xcf, 0xef, 0xce, 0xee, 0xd6, 0xf6, 0xd4, 0xe4, 'R', 'r', 'R', 'r', 0xdc, 0xfc, 0xdb, 0xfb, 0x15e, 0x15f, 0x162, 0x163}; return u200map[code - 0x200]; } + else if (code == 0x201d) + { + // Map the typographic upper quotation mark to the generic form + code = '"'; + } // skip the rest of Latin characters because none of them are relevant for modern languages. diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index 3e9b6be0df..46f1a6686c 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -7343,6 +7343,10 @@ FxExpression *FxArrayElement::Resolve(FCompileContext &ctx) auto parentfield = static_cast(Array)->membervar; SizeAddr = parentfield->Offset + sizeof(void*); } + else if (Array->ExprType == EFX_ArrayElement) + { + SizeAddr = ~0u; + } else { ScriptPosition.Message(MSG_ERROR, "Invalid resizable array"); @@ -7415,7 +7419,8 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build) ExpEmit arrayvar = Array->Emit(build); ExpEmit start; ExpEmit bound; - + bool nestedarray = false; + if (SizeAddr != ~0u) { bool ismeta = Array->ExprType == EFX_ClassMember && static_cast(Array)->membervar->Flags & VARF_Meta; @@ -7425,20 +7430,44 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build) build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0)); auto f = Create(NAME_None, TypeUInt32, ismeta? VARF_Meta : 0, SizeAddr); - static_cast(Array)->membervar = f; - static_cast(Array)->AddressRequested = false; + auto arraymemberbase = static_cast(Array); + + auto origmembervar = arraymemberbase->membervar; + auto origaddrreq = arraymemberbase->AddressRequested; + auto origvaluetype = Array->ValueType; + + arraymemberbase->membervar = f; + arraymemberbase->AddressRequested = false; Array->ValueType = TypeUInt32; + bound = Array->Emit(build); + + arraymemberbase->membervar = origmembervar; + arraymemberbase->AddressRequested = origaddrreq; + Array->ValueType = origvaluetype; + } + else if (Array->ExprType == EFX_ArrayElement && Array->isStaticArray()) + { + bool ismeta = Array->ExprType == EFX_ClassMember && static_cast(Array)->membervar->Flags & VARF_Meta; + + arrayvar.Free(build); + start = ExpEmit(build, REGT_POINTER); + build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0)); + + bound = ExpEmit(build, REGT_INT); + build->Emit(OP_LW, bound.RegNum, arrayvar.RegNum, build->GetConstantInt(sizeof(void*))); + + nestedarray = true; } else start = arrayvar; if (index->isConstant()) { unsigned indexval = static_cast(index)->GetValue().GetInt(); - assert(SizeAddr != ~0u || (indexval < arraytype->ElementCount && "Array index out of bounds")); + assert(SizeAddr != ~0u || nestedarray || (indexval < arraytype->ElementCount && "Array index out of bounds")); // For resizable arrays we even need to check the bounds if if the index is constant because they are not known at compile time. - if (SizeAddr != ~0u) + if (SizeAddr != ~0u || nestedarray) { ExpEmit indexreg(build, REGT_INT); build->EmitLoadInt(indexreg.RegNum, indexval); diff --git a/src/serializer.cpp b/src/serializer.cpp index ab66c792a8..eada141d9f 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -2147,19 +2147,14 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FFont *&fon { if (arc.isWriting()) { - FName n = font->GetName(); + FName n = font? font->GetName() : NAME_None; return arc(key, n); } else { FName n = NAME_None; arc(key, n); - font = V_GetFont(n); - if (font == nullptr) - { - Printf(TEXTCOLOR_ORANGE "Could not load font %s\n", n.GetChars()); - font = SmallFont; - } + font = n == NAME_None? nullptr : V_GetFont(n); return arc; }