diff --git a/src/common/2d/v_2ddrawer.cpp b/src/common/2d/v_2ddrawer.cpp index 46d02a2af..2d1387f02 100644 --- a/src/common/2d/v_2ddrawer.cpp +++ b/src/common/2d/v_2ddrawer.cpp @@ -787,7 +787,7 @@ void F2DDrawer::AddPoly(FGameTexture* img, FVector4* vt, size_t vtcount, const u mIndices.Reserve(vtcount); for (size_t i = 0; i < vtcount; i++) { - mIndices[dg.mIndexIndex + i] = i + dg.mVertIndex; + mIndices[dg.mIndexIndex + i] = int(i + dg.mVertIndex); } dg.mIndexCount = (int)vtcount; diff --git a/src/common/2d/v_draw.cpp b/src/common/2d/v_draw.cpp index 6672416da..9c53e754b 100644 --- a/src/common/2d/v_draw.cpp +++ b/src/common/2d/v_draw.cpp @@ -324,6 +324,22 @@ DEFINE_ACTION_FUNCTION(_Screen, ClearClipRect) return 0; } +DEFINE_ACTION_FUNCTION(_Screen, ClearScreen) +{ + PARAM_PROLOGUE; + twod->ClearScreen(); + return 0; +} + +DEFINE_ACTION_FUNCTION(_Screen, SetScreenFade) +{ + PARAM_PROLOGUE; + PARAM_FLOAT(x); + twod->SetScreenFade(float(x)); + return 0; +} + + void F2DDrawer::GetClipRect(int *x, int *y, int *w, int *h) { if (x) *x = clipleft; diff --git a/src/common/audio/music/music.cpp b/src/common/audio/music/music.cpp index c1c8290f6..f81b2396c 100644 --- a/src/common/audio/music/music.cpp +++ b/src/common/audio/music/music.cpp @@ -138,6 +138,10 @@ void S_StopCustomStream(SoundStream *stream) void S_PauseAllCustomStreams(bool on) { + static bool paused = false; + + if (paused == on) return; + paused = on; for (auto s : customStreams) { s->SetPaused(on); diff --git a/src/common/engine/namedef.h b/src/common/engine/namedef.h index cf8b8da62..8ec5d4081 100644 --- a/src/common/engine/namedef.h +++ b/src/common/engine/namedef.h @@ -1107,4 +1107,4 @@ xy(menu_change, "menu/change") xy(menu_advance, "menu/advance") xx(zoomsize) - +xx(ScreenJobRunner) diff --git a/src/common/engine/sc_man.h b/src/common/engine/sc_man.h index 64690d24b..56a4a8d82 100644 --- a/src/common/engine/sc_man.h +++ b/src/common/engine/sc_man.h @@ -122,6 +122,13 @@ public: return true; } + bool GetNumber(int64_t& var, bool evaluate = false) + { + if (!GetNumber(evaluate)) return false; + var = BigNumber; + return true; + } + bool GetString(FString& var) { if (!GetString()) return false; diff --git a/src/common/engine/serializer.h b/src/common/engine/serializer.h index 22f32f73c..400a6f4aa 100644 --- a/src/common/engine/serializer.h +++ b/src/common/engine/serializer.h @@ -269,6 +269,32 @@ FSerializer &Serialize(FSerializer &arc, const char *key, TArray &value, return arc; } +template +FSerializer& Serialize(FSerializer& arc, const char* key, TPointer& value, TPointer* def) +{ + if (arc.isWriting()) + { + if (value.Data() == nullptr && key) return arc; + } + bool res = arc.BeginArray(key); + if (arc.isReading()) + { + if (!res || arc.ArraySize() == 0) + { + value.Clear(); + return arc; + } + value.Alloc(); + } + if (value.Data()) + { + Serialize(arc, nullptr, *value, def ? def->Data() : nullptr); + } + arc.EndArray(); + return arc; +} + + template FSerializer& Serialize(FSerializer& arc, const char* key, FixedBitArray& value, FixedBitArray* def) { diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index dae98edf5..d700679f0 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -63,12 +63,14 @@ struct FileSystem::LumpRecord int rfnum; int Namespace; int resourceId; + int flags; void SetFromLump(int filenum, FResourceLump* lmp) { lump = lmp; rfnum = filenum; linkedTexture = nullptr; + flags = 0; if (lump->Flags & LUMPF_SHORTNAME) { @@ -487,7 +489,7 @@ int FileSystem::CheckNumForName (const char *name, int space) // from a Zip return that. WADs don't know these namespaces and single lumps must // work as well. if (space > ns_specialzipdirectory && lump.Namespace == ns_global && - !(lump.lump->Flags & LUMPF_FULLPATH)) break; + !((lump.lump->Flags ^lump.flags) & LUMPF_FULLPATH)) break; } i = NextLumpIndex[i]; } @@ -796,7 +798,7 @@ int FileSystem::GetFileFlags (int lump) return 0; } - return FileInfo[lump].lump->Flags; + return FileInfo[lump].lump->Flags ^ FileInfo[lump].flags; } //========================================================================== @@ -1532,11 +1534,18 @@ bool FileSystem::CreatePathlessCopy(const char *name, int id, int /*flags*/) auto oldlump = FileInfo[lump]; int slash = oldlump.longName.LastIndexOf('/'); - if (slash == -1) return true; // already is pathless. + + if (slash == -1) + { + FileInfo[lump].flags = LUMPF_FULLPATH; + return true; // already is pathless. + } + // just create a new reference to the original data with a different name. oldlump.longName = oldlump.longName.Mid(slash + 1); oldlump.resourceId = id; + oldlump.flags = LUMPF_FULLPATH; FileInfo.Push(oldlump); return true; } diff --git a/src/common/platform/win32/base_sysfb.cpp b/src/common/platform/win32/base_sysfb.cpp index 9455dbae6..3cb8858a3 100644 --- a/src/common/platform/win32/base_sysfb.cpp +++ b/src/common/platform/win32/base_sysfb.cpp @@ -371,7 +371,6 @@ SystemBaseFrameBuffer::~SystemBaseFrameBuffer() SetWindowLong(Window, GWL_STYLE, WS_VISIBLE | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW); SetWindowLong(Window, GWL_EXSTYLE, WS_EX_WINDOWEDGE); SetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); - I_GetEvent(); static_cast(Video)->Shutdown(); } diff --git a/src/common/rendering/hwrenderer/data/hw_vrmodes.cpp b/src/common/rendering/hwrenderer/data/hw_vrmodes.cpp index caf11f947..59f215e02 100644 --- a/src/common/rendering/hwrenderer/data/hw_vrmodes.cpp +++ b/src/common/rendering/hwrenderer/data/hw_vrmodes.cpp @@ -60,7 +60,6 @@ static VRMode vrmi_checker = { 2, isqrt2, isqrt2, 1.f,{ { -.5f, 1.f },{ .5f, 1.f const VRMode *VRMode::GetVRMode(bool toscreen) { -#ifdef VR3D_ENABLED int mode = !toscreen || (sysCallbacks.DisableTextureFilter && sysCallbacks.DisableTextureFilter()) ? 0 : vr_mode; switch (mode) @@ -96,9 +95,6 @@ const VRMode *VRMode::GetVRMode(bool toscreen) case VR_CHECKERINTERLEAVED: return &vrmi_checker; } -#else - return &vrmi_mono; -#endif } void VRMode::AdjustViewport(DFrameBuffer *screen) const diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index f6f52f0bc..eaafaba98 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -8706,7 +8706,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx) bool writable; ArgList[i] = ArgList[i]->Resolve(ctx); // must be resolved before the address is requested. - if (ArgList[i]->ValueType->isRealPointer()) + if (ArgList[i] && ArgList[i]->ValueType->isRealPointer()) { auto pointedType = ArgList[i]->ValueType->toPointer()->PointedType; if (pointedType && pointedType->isDynArray()) diff --git a/src/common/scripting/core/dynarrays.cpp b/src/common/scripting/core/dynarrays.cpp index 3d8e87e85..6be216c12 100644 --- a/src/common/scripting/core/dynarrays.cpp +++ b/src/common/scripting/core/dynarrays.cpp @@ -37,6 +37,7 @@ #include "dobject.h" #include "vm.h" #include "types.h" +#include "v_draw.h" // We need one specific type for each of the 8 integral VM types and instantiate the needed functions for each of them. // Dynamic arrays cannot hold structs because for every type there'd need to be an internal implementation which is impossible. @@ -412,6 +413,28 @@ DEFINE_ACTION_FUNCTION_NATIVE(FDynArray_I32, Push, ArrayPushPush(val)); } +DEFINE_ACTION_FUNCTION(FDynArray_I32, PushV) +{ + PARAM_SELF_STRUCT_PROLOGUE(FDynArray_I32); + PARAM_VA_POINTER(va_reginfo); // Get the hidden type information array + VMVa_List args = { param + 1, 0, numparam - 2, va_reginfo + 1 }; + while (args.curindex < args.numargs) + { + if (args.reginfo[args.curindex] == REGT_INT) + { + self->Push(args.args[args.curindex++].i); + } + else if (args.reginfo[args.curindex] == REGT_FLOAT) + { + self->Push(int(args.args[args.curindex++].f)); + } + else ThrowAbortException(X_OTHER, "Invalid parameter in pushv, int expected"); + } + + + ACTION_RETURN_INT(self->Size()-1); +} + DEFINE_ACTION_FUNCTION_NATIVE(FDynArray_I32, Pop, ArrayPop) { PARAM_SELF_STRUCT_PROLOGUE(FDynArray_I32); diff --git a/src/common/scripting/interface/stringformat.cpp b/src/common/scripting/interface/stringformat.cpp index 8e0bf0c75..da667cbbf 100644 --- a/src/common/scripting/interface/stringformat.cpp +++ b/src/common/scripting/interface/stringformat.cpp @@ -550,7 +550,21 @@ DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, ToDouble, StringToDbl) ACTION_RETURN_FLOAT(self->ToDouble()); } -static void StringSplit(FString *self, TArray *tokens, const FString &delimiter, int keepEmpty) +static void StringSubst(FString *self, const FString &substr, const FString& replc) +{ + self->Substitute(substr, replc); +} + +DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, Substitute, StringSubst) +{ + PARAM_SELF_STRUCT_PROLOGUE(FString); + PARAM_STRING(substr); + PARAM_STRING(replc); + StringSubst(self, substr, replc); + return 0; +} + +static void StringSplit(FString* self, TArray* tokens, const FString& delimiter, int keepEmpty) { self->Split(*tokens, delimiter, static_cast(keepEmpty)); } diff --git a/src/common/scripting/interface/vmnatives.cpp b/src/common/scripting/interface/vmnatives.cpp index aa15a6a74..23705b93a 100644 --- a/src/common/scripting/interface/vmnatives.cpp +++ b/src/common/scripting/interface/vmnatives.cpp @@ -49,6 +49,7 @@ #include "s_music.h" #include "i_interface.h" #include "base_sbar.h" +#include "image.h" //========================================================================== // @@ -339,8 +340,7 @@ DEFINE_ACTION_FUNCTION(_TexMan, GetName) static int CheckForTexture(const FString& name, int type, int flags) { - // ForceLookup is intentionally blocked here, this flag is for internal use only. - return TexMan.CheckForTexture(name, static_cast(type), (flags & ~FTextureManager::TEXMAN_ForceLookup)).GetIndex(); + return TexMan.CheckForTexture(name, static_cast(type), flags).GetIndex(); } DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, CheckForTexture, CheckForTexture) @@ -480,6 +480,20 @@ DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, OkForLocalization, OkForLocalization_) ACTION_RETURN_INT(OkForLocalization_(name, subst)); } +static int UseGamePalette(int index) +{ + auto tex = TexMan.GameByIndex(index, false); + if (!tex) return false; + auto image = tex->GetTexture()->GetImage(); + return image ? image->UseGamePalette() : false; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, UseGamePalette, UseGamePalette) +{ + PARAM_PROLOGUE; + PARAM_INT(texid); + ACTION_RETURN_INT(UseGamePalette(texid)); +} //===================================================================================== // @@ -870,6 +884,13 @@ DEFINE_ACTION_FUNCTION(FKeyBindings, GetAllKeysForCommand) return 0; } +DEFINE_ACTION_FUNCTION(FKeyBindings, GetBinding) +{ + PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings); + PARAM_INT(key); + ACTION_RETURN_STRING(self->GetBinding(key)); +} + DEFINE_ACTION_FUNCTION(FKeyBindings, UnbindACommand) { PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings); @@ -917,6 +938,7 @@ DEFINE_GLOBAL_NAMED(mus_playing, musplaying); DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, name); DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, baseorder); DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, loop); +DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, handle); DEFINE_GLOBAL_NAMED(PClass::AllClasses, AllClasses) DEFINE_GLOBAL(Bindings) diff --git a/src/common/textures/gametexture.h b/src/common/textures/gametexture.h index c7a753372..e9851fbe3 100644 --- a/src/common/textures/gametexture.h +++ b/src/common/textures/gametexture.h @@ -231,6 +231,7 @@ public: void SetFullbright() { flags |= GTexf_RenderFullbright; } void SetDisableFullbright(bool on) { if (on) flags |= GTexf_DisableFullbrightSprites; else flags &= ~GTexf_DisableFullbrightSprites; } void SetGlowing(PalEntry color) { flags = (flags & ~GTexf_AutoGlowing) | GTexf_Glowing; GlowColor = color; } + void SetDisableBrightmap() { flags |= GTexf_BrightmapChecked; Brightmap = nullptr; } bool isUserContent() const; int CheckRealHeight() { return xs_RoundToInt(Base->CheckRealHeight() / ScaleY); } diff --git a/src/common/utility/tarray.h b/src/common/utility/tarray.h index c44e06c43..635f1cc75 100644 --- a/src/common/utility/tarray.h +++ b/src/common/utility/tarray.h @@ -1368,6 +1368,134 @@ protected: }; +// Pointer wrapper without the unpleasant side effects of std::unique_ptr, mainly the inability to copy it. +// This class owns the object with no means to release it, and copying the pointer copies the object. +template +class TPointer +{ +public: + + //////// + TPointer() + { + Ptr = nullptr; + } + TPointer(const T& other) = delete; + /* + { + Alloc(); + *Ptr = other; + } + */ + TPointer(T&& other) + { + Alloc(); + *Ptr = other; + } + TPointer(const TPointer& other) = delete; + /* + { + DoCopy(other); + } + */ + TPointer(TPointer&& other) + { + Ptr = other.Ptr; + other.Ptr = nullptr; + } + TPointer& operator= (const T& other) + { + if (&other != this) + { + Alloc(); + *Ptr = other; + } + return *this; + } + TPointer& operator= (const TPointer& other) + { + if (&other != this) + { + DoCopy(other); + } + return *this; + } + TPointer& operator= (TPointer&& other) + { + if (&other != this) + { + if (Ptr) delete Ptr; + Ptr = other.Ptr; + other.Ptr = nullptr; + } + return *this; + } + ~TPointer() + { + if (Ptr) delete Ptr; + Ptr = nullptr; + } + // Check equality of two pointers + bool operator==(const TPointer& other) const + { + return *Ptr == *other.Ptr; + } + + T& operator* () const + { + assert(Ptr); + return *Ptr; + } + + T* operator->() { return Ptr; } + + // returns raw pointer + T* Data() const + { + return Ptr; + } + +#if 0 // this is too dangerous. + operator T* () const + { + return Ptr; + } +#endif + + void Alloc() + { + if (!Ptr) Ptr = new T; + } + + void Clear() + { + if (Ptr) delete Ptr; + Ptr = nullptr; + } + + void Swap(TPointer& other) + { + std::swap(Ptr, other.Ptr); + } + +private: + T* Ptr; + + void DoCopy(const TPointer& other) + { + if (other.Ptr == nullptr) + { + Clear(); + } + else + { + Alloc(); + *Ptr = *other.Ptr; + } + } +}; + + //========================================================================== // diff --git a/src/rendering/hwrenderer/scene/hw_portal.cpp b/src/rendering/hwrenderer/scene/hw_portal.cpp index e44f12cae..2fe2223f8 100644 --- a/src/rendering/hwrenderer/scene/hw_portal.cpp +++ b/src/rendering/hwrenderer/scene/hw_portal.cpp @@ -123,7 +123,6 @@ void FPortalSceneState::EndFrame(HWDrawInfo *di, FRenderState &state) //----------------------------------------------------------------------------- bool FPortalSceneState::RenderFirstSkyPortal(int recursion, HWDrawInfo *outer_di, FRenderState &state) { - HWPortal * p; HWPortal * best = nullptr; unsigned bestindex = 0; diff --git a/wadsrc/static/zscript/engine/base.zs b/wadsrc/static/zscript/engine/base.zs index a0b2a0c83..21115a193 100644 --- a/wadsrc/static/zscript/engine/base.zs +++ b/wadsrc/static/zscript/engine/base.zs @@ -187,6 +187,8 @@ struct MusPlayingInfo native native String name; native int baseorder; native bool loop; + native voidptr handle; + }; struct TexMan @@ -218,7 +220,9 @@ struct TexMan AllowSkins = 8, ShortNameOnly = 16, DontCreate = 32, - Localize = 64 + Localize = 64, + ForceLookup = 128, + NoAlias = 256 }; enum ETexReplaceFlags @@ -239,6 +243,7 @@ struct TexMan native static Vector2 GetScaledOffset(TextureID tex); native static int CheckRealHeight(TextureID tex); native static bool OkForLocalization(TextureID patch, String textSubstitute); + native static bool UseGamePalette(TextureID tex); } enum EScaleMode @@ -402,6 +407,8 @@ struct Screen native native static int, int, int, int GetViewWindow(); native static double, double, double, double GetFullscreenRect(double vwidth, double vheight, int fsmode); native static Vector2 SetOffset(double x, double y); + native static void ClearScreen(color col = 0); + native static void SetScreenFade(double factor); } struct Font native @@ -657,6 +664,7 @@ struct StringStruct native native void DeleteLastCharacter(); native int CodePointCount() const; native int, int GetNextCodePoint(int position) const; + native void Substitute(String str, String replace); } struct Translation version("2.4") diff --git a/wadsrc/static/zscript/engine/dynarrays.zs b/wadsrc/static/zscript/engine/dynarrays.zs index 2e80820cd..1db4a6224 100644 --- a/wadsrc/static/zscript/engine/dynarrays.zs +++ b/wadsrc/static/zscript/engine/dynarrays.zs @@ -50,6 +50,7 @@ struct DynArray_I32 native native void Append (DynArray_I32 other); native uint Find(int item) const; native uint Push (int item); + native vararg uint PushV (int item, ...); native bool Pop (); native void Delete (uint index, int deletecount = 1); native void Insert (uint index, int item); diff --git a/wadsrc/static/zscript/engine/inputevents.zs b/wadsrc/static/zscript/engine/inputevents.zs index 95a6d29ab..ba63b59e9 100644 --- a/wadsrc/static/zscript/engine/inputevents.zs +++ b/wadsrc/static/zscript/engine/inputevents.zs @@ -120,6 +120,21 @@ struct InputEvent native play version("2.4") Key_F12 = 0x58, // DIK_F12 Key_Grave = 0x29, // DIK_GRAVE + KEY_kpad_1 = 0x4f, + KEY_kpad_2 = 0x50, + KEY_kpad_3 = 0x51, + KEY_kpad_4 = 0x4b, + KEY_kpad_5 = 0x4c, + KEY_kpad_6 = 0x4d, + KEY_kpad_7 = 0x47, + KEY_kpad_8 = 0x48, + KEY_kpad_9 = 0x49, + KEY_kpad_0 = 0x52, + KEY_kpad_Minus = 0x4a, + KEY_kpad_Plus = 0x4e, + KEY_kpad_Period = 0x53, + + Key_Backspace = 0x0e, // DIK_BACK Key_Equals = 0x0d, // DIK_EQUALS @@ -140,6 +155,9 @@ struct InputEvent native play version("2.4") Key_PgUp = 0xc9, // DIK_PRIOR Key_PgDn = 0xd1, // DIK_NEXT + KEY_VOLUMEDOWN = 0xAE, // DIK_VOLUMEDOWN + KEY_VOLUMEUP = 0xB0, // DIK_VOLUMEUP + Key_Mouse1 = 0x100, Key_Mouse2 = 0x101, Key_Mouse3 = 0x102, diff --git a/wadsrc/static/zscript/engine/ui/menu/listmenu.zs b/wadsrc/static/zscript/engine/ui/menu/listmenu.zs index 6a2c9c1b0..c8a8a0f2e 100644 --- a/wadsrc/static/zscript/engine/ui/menu/listmenu.zs +++ b/wadsrc/static/zscript/engine/ui/menu/listmenu.zs @@ -246,7 +246,6 @@ class ListMenu : Menu y = int((y - fy) * h / fh); } - if (mFocusControl != NULL) { mFocusControl.MouseEvent(type, x, y); diff --git a/wadsrc/static/zscript/engine/ui/menu/menu.zs b/wadsrc/static/zscript/engine/ui/menu/menu.zs index b40c10f0c..8e08870aa 100644 --- a/wadsrc/static/zscript/engine/ui/menu/menu.zs +++ b/wadsrc/static/zscript/engine/ui/menu/menu.zs @@ -40,6 +40,7 @@ struct KeyBindings native version("2.4") native int, int GetKeysForCommand(String cmd); native void GetAllKeysForCommand(out array list, String cmd); + native String GetBinding(int key); native void SetBind(int key, String cmd); native void UnbindACommand (String str);