From 4be63d55d3bbb4fea565121950fe70decd6f7c96 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 8 Nov 2019 18:55:52 +0100 Subject: [PATCH 001/203] - added a stripped down version of ZDoom's DObject. This only retains the objecct factory feature, but removes the garbage collector which I have no use for. # Conflicts: # source/CMakeLists.txt --- source/CMakeLists.txt | 9 ++ source/common/dobject/__autostart.cpp | 75 ++++++++++++ source/common/dobject/autosegs.h | 102 ++++++++++++++++ source/common/dobject/dobject.cpp | 73 +++++++++++ source/common/dobject/dobject.h | 169 ++++++++++++++++++++++++++ source/common/dobject/dobjtype.cpp | 104 ++++++++++++++++ source/common/dobject/dobjtype.h | 51 ++++++++ source/common/dobject/zzautozend.cpp | 54 ++++++++ 8 files changed, 637 insertions(+) create mode 100644 source/common/dobject/__autostart.cpp create mode 100644 source/common/dobject/autosegs.h create mode 100644 source/common/dobject/dobject.cpp create mode 100644 source/common/dobject/dobject.h create mode 100644 source/common/dobject/dobjtype.cpp create mode 100644 source/common/dobject/dobjtype.h create mode 100644 source/common/dobject/zzautozend.cpp diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 13ef32a7a..935a1ec13 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -623,6 +623,7 @@ file( GLOB HEADER_FILES common/console/*.h common/filesystem/*.h common/music/*.h + common/dobject/*.h build/src/*.h thirdparty/include/*.h @@ -664,6 +665,8 @@ set( FASTMATH_SOURCES set (PCH_SOURCES + common/dobject/__autostart.cpp # must be first + audiolib/src/drivers.cpp audiolib/src/driver_adlib.cpp audiolib/src/driver_nosound.cpp @@ -825,6 +828,10 @@ set (PCH_SOURCES common/music/backend/i_sound.cpp + common/dobject/dobject.cpp + common/dobject/dobjtype.cpp + + common/dobject/zzautozend.cpp #must be last ) if( MSVC ) @@ -887,6 +894,7 @@ include_directories( common/textures common/filesystem common/music + common/dobject platform ${CMAKE_BINARY_DIR}/libraries/gdtoa @@ -995,6 +1003,7 @@ source_group("Code\\Console" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/co source_group("Code\\Fonts" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/fonts/.+") source_group("Code\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/.+") source_group("Code\\Music" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/music/.+") +source_group("Code\\DObject" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/dobject/.+") source_group("Utility\\Audiolib" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/audiolib/.+") source_group("Utility\\Audiolib Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/audiolib/include/.+") source_group("Utility\\Audiolib Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/audiolib/src/.+") diff --git a/source/common/dobject/__autostart.cpp b/source/common/dobject/__autostart.cpp new file mode 100644 index 000000000..635bf5b67 --- /dev/null +++ b/source/common/dobject/__autostart.cpp @@ -0,0 +1,75 @@ +/* +** autostart.cpp +** This file contains the heads of lists stored in special data segments +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** The particular scheme used here was chosen because it's small. +** +** An alternative that will work with any C++ compiler is to use static +** classes to build these lists at run time. Under Visual C++, doing things +** that way can require a lot of extra space, which is why I'm doing things +** this way. +** +** In the case of PClass lists (section creg), I orginally used the +** constructor to do just that, and the code for that still exists if you +** compile with something other than Visual C++ or GCC. +*/ + +#include "autosegs.h" + +#if defined(_MSC_VER) + +// The various reg sections are used to group pointers spread across multiple +// source files into cohesive arrays in the final executable. We don't +// actually care about these sections themselves and merge them all into +// a single section during the final link. (.rdata is the standard section +// for initialized read-only data.) + +#pragma comment(linker, "/merge:.creg=.rdata") + +#pragma section(".creg$a",read) +__declspec(allocate(".creg$a")) void *const CRegHead = 0; + +#elif defined(__GNUC__) + +#include "doomtype.h" + +// I don't know of an easy way to merge sections together with the GNU linker, +// so GCC users will see all of these sections appear in the final executable. +// (There are linker scripts, but that apparently involves extracting the +// default script from ld and then modifying it.) + +void *const CRegHead __attribute__((section(SECTION_CREG))) = 0; + +#else + +#error Please fix autostart.cpp for your compiler + +#endif diff --git a/source/common/dobject/autosegs.h b/source/common/dobject/autosegs.h new file mode 100644 index 000000000..1884d9d54 --- /dev/null +++ b/source/common/dobject/autosegs.h @@ -0,0 +1,102 @@ +/* +** autosegs.h +** Arrays built at link-time +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#ifndef AUTOSEGS_H +#define AUTOSEGS_H + +#define REGMARKER(x) (x) +typedef void * const REGINFO; + +// List of Action functons +extern REGINFO ARegHead; +extern REGINFO ARegTail; + +// List of TypeInfos +extern REGINFO CRegHead; +extern REGINFO CRegTail; + +// List of properties +extern REGINFO GRegHead; +extern REGINFO GRegTail; + +// List of variables +extern REGINFO MRegHead; +extern REGINFO MRegTail; + +// List of MAPINFO map options +extern REGINFO YRegHead; +extern REGINFO YRegTail; + +class FAutoSegIterator +{ + public: + FAutoSegIterator(REGINFO &head, REGINFO &tail) + { + // Weirdness. Mingw's linker puts these together backwards. + if (&head <= &tail) + { + Head = &head; + Tail = &tail; + } + else + { + Head = &tail; + Tail = &head; + } + Probe = Head; + } + REGINFO operator*() const + { + return *Probe; + } + FAutoSegIterator &operator++() + { + do + { + ++Probe; + } while (*Probe == 0 && Probe < Tail); + return *this; + } + void Reset() + { + Probe = Head; + } + + protected: + REGINFO *Probe; + REGINFO *Head; + REGINFO *Tail; +}; + +#endif diff --git a/source/common/dobject/dobject.cpp b/source/common/dobject/dobject.cpp new file mode 100644 index 000000000..d926251e1 --- /dev/null +++ b/source/common/dobject/dobject.cpp @@ -0,0 +1,73 @@ +/* +** dobject.cpp +** Implements the base class DObject, which most other classes derive from +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include +#include + +#include "dobject.h" + +PClass DObject::_StaticType; +ClassReg DObject::RegistrationInfo = +{ + &DObject::_StaticType, // MyClass + "DObject", // Name + NULL, // ParentType + sizeof(DObject), // SizeOf + NULL, // Pointers + &DObject::InPlaceConstructor // ConstructNative +}; +_DECLARE_TI(DObject) + +void DObject::InPlaceConstructor (void *mem) +{ + new ((EInPlace *)mem) DObject; +} + +DObject::DObject () +: Class(0) +{ +} + +DObject::DObject (PClass *inClass) +: Class(inClass) +{ +} + +DObject::~DObject () +{ +} + +void DObject::Destroy () +{ +} diff --git a/source/common/dobject/dobject.h b/source/common/dobject/dobject.h new file mode 100644 index 000000000..0e3590b87 --- /dev/null +++ b/source/common/dobject/dobject.h @@ -0,0 +1,169 @@ +/* +** dobject.h +** +**--------------------------------------------------------------------------- +** Copyright 1998-2008 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#ifndef __DOBJECT_H__ +#define __DOBJECT_H__ + +#include + +struct PClass; + +#define RUNTIME_TYPE(object) (object->GetClass()) // Passed an object, returns the type of that object +#define RUNTIME_CLASS(cls) (&cls::_StaticType) // Passed a class name, returns a PClass representing that class +#define NATIVE_TYPE(object) (object->StaticType()) // Passed an object, returns the type of the C++ class representing the object + +struct ClassReg +{ + PClass *MyClass; + const char *Name; + PClass *ParentType; + unsigned int SizeOf; + const size_t *Pointers; + void (*ConstructNative)(void *); + + void RegisterClass() const; +}; + +enum EInPlace { EC_InPlace }; + +#define DECLARE_ABSTRACT_CLASS(cls,parent) \ +public: \ + static PClass _StaticType; \ + virtual PClass *StaticType() const { return &_StaticType; } \ + static ClassReg RegistrationInfo, *RegistrationInfoPtr; \ +private: \ + typedef parent Super; \ + typedef cls ThisClass; + +#define DECLARE_CLASS(cls,parent) \ + DECLARE_ABSTRACT_CLASS(cls,parent) \ + private: static void InPlaceConstructor (void *mem); + +#if defined(_MSC_VER) +# pragma data_seg(".creg$u") +# pragma data_seg() +# define _DECLARE_TI(cls) __declspec(allocate(".creg$u")) ClassReg *cls::RegistrationInfoPtr = &cls::RegistrationInfo; +#else +# define _DECLARE_TI(cls) ClassReg *cls::RegistrationInfoPtr __attribute__((section(SECTION_CREG))) = &cls::RegistrationInfo; +#endif + +#define _IMP_PCLASS(cls,ptrs,create) \ + PClass cls::_StaticType; \ + ClassReg cls::RegistrationInfo = {\ + RUNTIME_CLASS(cls), \ + #cls, \ + RUNTIME_CLASS(cls::Super), \ + sizeof(cls), \ + ptrs, \ + create }; \ + _DECLARE_TI(cls) + +#define _IMP_CREATE_OBJ(cls) \ + void cls::InPlaceConstructor(void *mem) { new((EInPlace *)mem) cls; } + +#define IMPLEMENT_CLASS(cls) \ + _IMP_CREATE_OBJ(cls) \ + _IMP_PCLASS(cls,NULL,cls::InPlaceConstructor) + +#define IMPLEMENT_ABSTRACT_CLASS(cls) \ + _IMP_PCLASS(cls,NULL,NULL) + + +class DObject +{ +public: + static PClass _StaticType; + virtual PClass *StaticType() const { return &_StaticType; } + static ClassReg RegistrationInfo, *RegistrationInfoPtr; + static void InPlaceConstructor (void *mem); +private: + typedef DObject ThisClass; + + // Per-instance variables. There are four. +private: + PClass *Class; // This object's type +public: + +public: + DObject (); + DObject (PClass *inClass); + virtual ~DObject(); + + inline bool IsKindOf (const PClass *base); + inline bool IsA (const PClass *type); + + virtual void Destroy (); + + PClass *GetClass() const + { + if (Class == NULL) + { + // Save a little time the next time somebody wants this object's type + // by recording it now. + const_cast(this)->Class = StaticType(); + } + return Class; + } + + void SetClass (PClass *inClass) + { + Class = inClass; + } + +protected: + // This form of placement new and delete is for use *only* by PClass's + // CreateNew() method. Do not use them for some other purpose. + void *operator new(size_t, EInPlace *mem) + { + return (void *)mem; + } + + void operator delete (void *mem, EInPlace *) + { + free (mem); + } +}; + +#include "dobjtype.h" + +inline bool DObject::IsKindOf (const PClass *base) +{ + return base->IsAncestorOf (GetClass ()); +} + +inline bool DObject::IsA (const PClass *type) +{ + return (type == GetClass()); +} + +#endif //__DOBJECT_H__ diff --git a/source/common/dobject/dobjtype.cpp b/source/common/dobject/dobjtype.cpp new file mode 100644 index 000000000..d77f711bc --- /dev/null +++ b/source/common/dobject/dobjtype.cpp @@ -0,0 +1,104 @@ +/* +** dobjtype.cpp +** Implements the type information class +** +**--------------------------------------------------------------------------- +** Copyright 1998-2008 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include +#include +#include "dobject.h" +#include "templates.h" +#include "autosegs.h" +#include "tarray.h" + +static TArray Types; +static TMap Map; + +static int cregcmp (const void *a, const void *b) +{ + // VC++ introduces NULLs in the sequence. GCC seems to work as expected and not do it. + const ClassReg *class1 = *(const ClassReg **)a; + const ClassReg *class2 = *(const ClassReg **)b; + if (class1 == NULL) return 1; + if (class2 == NULL) return -1; + return strcmp (class1->Name, class2->Name); +} + +void PClass::StaticInit () +{ + // Sort classes by name to remove dependance on how the compiler ordered them. + REGINFO *head = &CRegHead; + REGINFO *tail = &CRegTail; + + // MinGW's linker is linking the object files backwards for me now... + if (head > tail) + { + std::swap (head, tail); + } + qsort ((void*)(head + 1), tail - head - 1, sizeof(REGINFO), cregcmp); + + FAutoSegIterator probe(CRegHead, CRegTail); + + while (*++probe != NULL) + { + ((ClassReg *)*probe)->RegisterClass (); + } +} + +void ClassReg::RegisterClass () const +{ + assert (MyClass != NULL); + + // Add type to list + MyClass->TypeName = FName(Name+1); + MyClass->ParentClass = ParentType; + MyClass->Size = SizeOf; + MyClass->ConstructNative = ConstructNative; + Map.Insert(MyClass->TypeName, MyClass); +} + +// Find a type, passed the name as a name +const PClass *PClass::FindClass (FName zaname) +{ + auto pcls = Map.CheckKey(zaname); + return pcls? *pcls : nullptr; +} + +// Create a new object that this class represents +DObject *PClass::CreateNew () const +{ + uint8_t *mem = (uint8_t *)calloc (Size, 1); + assert (mem != NULL); + + ConstructNative (mem); + ((DObject *)mem)->SetClass (const_cast(this)); + return (DObject *)mem; +} diff --git a/source/common/dobject/dobjtype.h b/source/common/dobject/dobjtype.h new file mode 100644 index 000000000..f499d56e5 --- /dev/null +++ b/source/common/dobject/dobjtype.h @@ -0,0 +1,51 @@ +#ifndef DOBJTYPE_H +#define DOBJTYPE_H + +#ifndef __DOBJECT_H__ +#error You must #include "dobject.h" to get dobjtype.h +#endif + +#include "name.h" + + +// Meta-info for every class derived from DObject --------------------------- + +struct PClass +{ + static void StaticInit (); + + // Per-class information ------------------------------------- + FName TypeName; // this class's name + unsigned int Size; // this class's size + PClass *ParentClass; // the class this class derives from + PClass *HashNext; + + void (*ConstructNative)(void *); + + // The rest are all functions and static data ---------------- + DObject *CreateNew () const; + + // Returns true if this type is an ancestor of (or same as) the passed type. + bool IsAncestorOf (const PClass *ti) const + { + while (ti) + { + if (this == ti) + return true; + ti = ti->ParentClass; + } + return false; + } + inline bool IsDescendantOf (const PClass *ti) const + { + return ti->IsAncestorOf (this); + } + + // Find a type, given its name. + static const PClass *FindClass (const char *name) { return FindClass (FName (name, true)); } + static const PClass *FindClass (const FString &name) { return FindClass (FName (name, true)); } + static const PClass *FindClass (ENamedName name) { return FindClass (FName (name)); } + static const PClass *FindClass (FName name); +}; + +#endif diff --git a/source/common/dobject/zzautozend.cpp b/source/common/dobject/zzautozend.cpp new file mode 100644 index 000000000..70f1a77e9 --- /dev/null +++ b/source/common/dobject/zzautozend.cpp @@ -0,0 +1,54 @@ +/* +** autozend.cpp +** This file contains the tails of lists stored in special data segments +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** See autostart.cpp for an explanation of why I do things like this. +*/ + +#include "autosegs.h" + +#if defined(_MSC_VER) + +#pragma section(".creg$z",read) +__declspec(allocate(".creg$z")) void *const CRegTail = 0; + + +#elif defined(__GNUC__) + +#include "doomtype.h" + +void *const CRegTail __attribute__((section(SECTION_CREG))) = 0; + +#else + +#error Please fix autozend.cpp for your compiler + +#endif From 81ddf22d5d24927907bfa2c52c732144f42313dd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 8 Nov 2019 23:02:52 +0100 Subject: [PATCH 002/203] - added ZDoom's menu system as a base to build a new menu on. # Conflicts: # source/CMakeLists.txt # source/build/src/engine.cpp --- source/CMakeLists.txt | 14 + source/build/src/engine.cpp | 38 +- source/build/src/sdlayer.cpp | 12 + source/common/2d/v_draw.cpp | 30 + source/common/2d/v_draw.h | 1 + source/common/dobject/dobject.h | 10 + source/common/dobject/dobjtype.h | 3 +- source/common/fonts/v_font.cpp | 4 +- source/common/menu/joystickmenu.cpp | 430 +++++++ source/common/menu/listmenu.cpp | 569 ++++++++++ source/common/menu/loadsavemenu.cpp | 958 ++++++++++++++++ source/common/menu/menu.cpp | 812 +++++++++++++ source/common/menu/menu.h | 615 ++++++++++ source/common/menu/menudef.cpp | 1321 ++++++++++++++++++++++ source/common/menu/menuinput.cpp | 367 ++++++ source/common/menu/messagebox.cpp | 361 ++++++ source/common/menu/optionmenu.cpp | 553 +++++++++ source/common/menu/optionmenuitems.h | 961 ++++++++++++++++ source/common/menu/readthis.cpp | 149 +++ source/common/utility/gstrings.h | 48 + source/common/utility/name.h | 13 +- source/common/utility/namedef.h | 2 + source/common/utility/stringtable.cpp | 666 +++++++++++ source/common/utility/stringtable.h | 116 ++ wadsrc/static/fonts/consolefont/0000.png | Bin 0 -> 3827 bytes wadsrc/static/fonts/consolefont/0100.png | Bin 0 -> 2564 bytes wadsrc/static/fonts/consolefont/0400.png | Bin 0 -> 1306 bytes wadsrc/static/fonts/consolefont/font.inf | 3 + 28 files changed, 8013 insertions(+), 43 deletions(-) create mode 100644 source/common/menu/joystickmenu.cpp create mode 100644 source/common/menu/listmenu.cpp create mode 100644 source/common/menu/loadsavemenu.cpp create mode 100644 source/common/menu/menu.cpp create mode 100644 source/common/menu/menu.h create mode 100644 source/common/menu/menudef.cpp create mode 100644 source/common/menu/menuinput.cpp create mode 100644 source/common/menu/messagebox.cpp create mode 100644 source/common/menu/optionmenu.cpp create mode 100644 source/common/menu/optionmenuitems.h create mode 100644 source/common/menu/readthis.cpp create mode 100644 source/common/utility/gstrings.h create mode 100644 source/common/utility/stringtable.cpp create mode 100644 source/common/utility/stringtable.h create mode 100644 wadsrc/static/fonts/consolefont/0000.png create mode 100644 wadsrc/static/fonts/consolefont/0100.png create mode 100644 wadsrc/static/fonts/consolefont/0400.png create mode 100644 wadsrc/static/fonts/consolefont/font.inf diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 935a1ec13..1e743e758 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -624,6 +624,7 @@ file( GLOB HEADER_FILES common/filesystem/*.h common/music/*.h common/dobject/*.h + common/menu/*.h build/src/*.h thirdparty/include/*.h @@ -791,6 +792,7 @@ set (PCH_SOURCES common/utility/m_png.cpp common/utility/memarena.cpp common/utility/sc_man.cpp + common/utility/stringtable.cpp common/utility/stats.cpp common/filesystem/filesystem.cpp @@ -831,6 +833,16 @@ set (PCH_SOURCES common/dobject/dobject.cpp common/dobject/dobjtype.cpp + common/menu/joystickmenu.cpp + common/menu/listmenu.cpp + common/menu/loadsavemenu.cpp + common/menu/menu.cpp + common/menu/menudef.cpp + common/menu/menuinput.cpp + common/menu/messagebox.cpp + common/menu/optionmenu.cpp + common/menu/readthis.cpp + common/dobject/zzautozend.cpp #must be last ) @@ -895,6 +907,7 @@ include_directories( common/filesystem common/music common/dobject + common/menu platform ${CMAKE_BINARY_DIR}/libraries/gdtoa @@ -1004,6 +1017,7 @@ source_group("Code\\Fonts" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/comm source_group("Code\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/.+") source_group("Code\\Music" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/music/.+") source_group("Code\\DObject" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/dobject/.+") +source_group("Code\\Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/menu/.+") source_group("Utility\\Audiolib" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/audiolib/.+") source_group("Utility\\Audiolib Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/audiolib/include/.+") source_group("Utility\\Audiolib Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/audiolib/src/.+") diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index a6dafafa6..428344c19 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -24,6 +24,7 @@ #include "gamecvars.h" #include "c_console.h" #include "v_2ddrawer.h" +#include "v_draw.h" #include "imgui.h" #include "stats.h" @@ -9984,6 +9985,7 @@ int32_t videoSetGameMode(char davidoption, int32_t daupscaledxdim, int32_t daups } xdim = daupscaledxdim/scalefactor; ydim = daupscaledydim/scalefactor; + V_UpdateModeSize(xdim, ydim); #ifdef USE_OPENGL fxdim = (float) xdim; @@ -12066,42 +12068,6 @@ void setfirstwall(int16_t sectnum, int16_t newfirstwall) Xfree(tmpwall); } -// -// qsetmodeany -// -void videoSet2dMode(int32_t daxdim, int32_t daydim) -{ - if (daxdim < 640) daxdim = 640; - if (daydim < 480) daydim = 480; - - if (qsetmode != ((daxdim<<16)|(daydim&0xffff))) - { - g_lastpalettesum = 0; - if (videoSetMode(daxdim, daydim, 8, fullscreen) < 0) - return; - - xdim = xres; - ydim = yres; - -#ifdef USE_OPENGL - fxdim = (float) xdim; - fydim = (float) ydim; - - rendmode = REND_CLASSIC; -#endif - videoAllocateBuffers(); - - ydim16 = ydim - STATUS2DSIZ2; - halfxdim16 = xdim >> 1; - midydim16 = ydim16 >> 1; // scale(200,ydim,480); - - videoBeginDrawing(); //{{{ - Bmemset((char *)frameplace, 0, ydim*bytesperline); - videoEndDrawing(); //}}} - } - - qsetmode = ((daxdim<<16)|(daydim&0xffff)); -} static int32_t printext_checkypos(int32_t ypos, int32_t *yminptr, int32_t *ymaxptr) { diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index eb065a378..72f1f3667 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -2060,6 +2060,18 @@ int32_t handleevents(void) return rv; } +void I_SetMouseCapture() +{ + // Clear out any mouse movement. + SDL_GetRelativeMouseState(NULL, NULL); + SDL_SetRelativeMouseMode(SDL_TRUE); +} + +void I_ReleaseMouseCapture() +{ + SDL_SetRelativeMouseMode(SDL_FALSE); +} + auto vsnprintfptr = vsnprintf; // This is an inline in Visual Studio but we need an address for it to satisfy the MinGW compiled libraries. // diff --git a/source/common/2d/v_draw.cpp b/source/common/2d/v_draw.cpp index 0b44e95d8..d89dcb555 100644 --- a/source/common/2d/v_draw.cpp +++ b/source/common/2d/v_draw.cpp @@ -107,6 +107,36 @@ int CleanWidth, CleanHeight; int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1; +void V_UpdateModeSize(int width, int height) +{ + // This calculates the menu scale. + // The optimal scale will always be to fit a virtual 640 pixel wide display onto the screen. + // Exceptions are made for a few ranges where the available virtual width is > 480. + + // This reference size is being used so that on 800x450 (small 16:9) a scale of 2 gets used. + + CleanXfac = std::max(std::min(screen->GetWidth() / 400, screen->GetHeight() / 240), 1); + if (CleanXfac >= 4) CleanXfac--; // Otherwise we do not have enough space for the episode/skill menus in some languages. + CleanYfac = CleanXfac; + CleanWidth = screen->GetWidth() / CleanXfac; + CleanHeight = screen->GetHeight() / CleanYfac; + + int w = screen->GetWidth(); + int factor; + if (w < 640) factor = 1; + else if (w >= 1024 && w < 1280) factor = 2; + else if (w >= 1600 && w < 1920) factor = 3; + else factor = w / 640; + + if (w < 1360) factor = 1; + else if (w < 1920) factor = 2; + else factor = int(factor * 0.7); + + CleanYfac_1 = CleanXfac_1 = factor;// MAX(1, int(factor * 0.7)); + CleanWidth_1 = width / CleanXfac_1; + CleanHeight_1 = height / CleanYfac_1; +} + //========================================================================== // // Draw parameter parsing diff --git a/source/common/2d/v_draw.h b/source/common/2d/v_draw.h index 3a8bfe67a..c581cad78 100644 --- a/source/common/2d/v_draw.h +++ b/source/common/2d/v_draw.h @@ -42,6 +42,7 @@ double AspectPspriteOffset(float aspect); int AspectMultiplier(float aspect); bool AspectTallerThanWide(float aspect); void ScaleWithAspect(int& w, int& h, int Width, int Height); +void V_UpdateModeSize(int width, int height); void DrawTexture(F2DDrawer *drawer, FTexture* img, double x, double y, int tags_first, ...); void DrawChar (F2DDrawer* drawer, FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...); diff --git a/source/common/dobject/dobject.h b/source/common/dobject/dobject.h index 0e3590b87..0b2b3dc70 100644 --- a/source/common/dobject/dobject.h +++ b/source/common/dobject/dobject.h @@ -140,6 +140,16 @@ public: Class = inClass; } + void* operator new(size_t p) + { + return malloc(p); + } + + void operator delete (void* mem) + { + free(mem); + } + protected: // This form of placement new and delete is for use *only* by PClass's // CreateNew() method. Do not use them for some other purpose. diff --git a/source/common/dobject/dobjtype.h b/source/common/dobject/dobjtype.h index f499d56e5..15c80fbb1 100644 --- a/source/common/dobject/dobjtype.h +++ b/source/common/dobject/dobjtype.h @@ -42,8 +42,7 @@ struct PClass } // Find a type, given its name. - static const PClass *FindClass (const char *name) { return FindClass (FName (name, true)); } - static const PClass *FindClass (const FString &name) { return FindClass (FName (name, true)); } + static const PClass* FindClass(const char* name) { FName nm(name, true); return nm == NAME_None ? nullptr : FindClass(nm); } static const PClass *FindClass (ENamedName name) { return FindClass (FName (name)); } static const PClass *FindClass (FName name); }; diff --git a/source/common/fonts/v_font.cpp b/source/common/fonts/v_font.cpp index 0b14c0348..b8d381414 100644 --- a/source/common/fonts/v_font.cpp +++ b/source/common/fonts/v_font.cpp @@ -720,12 +720,10 @@ void V_InitFonts() NewSmallFont = CreateHexLumpFont2("NewSmallFont", "demolition/newconsolefont.hex"); CurrentConsoleFont = NewConsoleFont; - /* - ConFont = V_GetFont("ConsoleFont", "CONFONT"); + ConFont = V_GetFont("ConsoleFont", "confont"); // The con font is needed for the slider graphics { ConFont = SmallFont; } - */ } void V_ClearFonts() diff --git a/source/common/menu/joystickmenu.cpp b/source/common/menu/joystickmenu.cpp new file mode 100644 index 000000000..bd9dfabf3 --- /dev/null +++ b/source/common/menu/joystickmenu.cpp @@ -0,0 +1,430 @@ +/* +** joystickmenu.cpp +** The joystick configuration menus +** +**--------------------------------------------------------------------------- +** Copyright 2010 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include + +#include "menu.h" +#include "c_dispatch.h" +#include "filesystem.h" +#include "sc_man.h" +#include "v_font.h" +#include "c_bind.h" +#include "d_event.h" +#include "d_gui.h" + +#define NO_IMP +#include "optionmenuitems.h" + +#if 0 // This requires the entire ZDoom backend to work. + +static TArray Joysticks; +IJoystickConfig *SELECTED_JOYSTICK; + +FOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy); + +//============================================================================= +// +// +// +//============================================================================= + +class FOptionMenuSliderJoySensitivity : public FOptionMenuSliderBase +{ +public: + FOptionMenuSliderJoySensitivity(const char *label, double min, double max, double step, int showval) + : FOptionMenuSliderBase(label, min, max, step, showval) + { + } + + double GetSliderValue() + { + return SELECTED_JOYSTICK->GetSensitivity(); + } + + void SetSliderValue(double val) + { + SELECTED_JOYSTICK->SetSensitivity(float(val)); + } +}; + +//============================================================================= +// +// +// +//============================================================================= + +class FOptionMenuSliderJoyScale : public FOptionMenuSliderBase +{ + int mAxis; + int mNeg; + +public: + FOptionMenuSliderJoyScale(const char *label, int axis, double min, double max, double step, int showval) + : FOptionMenuSliderBase(label, min, max, step, showval) + { + mAxis = axis; + mNeg = 1; + } + + double GetSliderValue() + { + double d = SELECTED_JOYSTICK->GetAxisScale(mAxis); + mNeg = d < 0? -1:1; + return d; + } + + void SetSliderValue(double val) + { + SELECTED_JOYSTICK->SetAxisScale(mAxis, float(val * mNeg)); + } +}; + +//============================================================================= +// +// +// +//============================================================================= + +class FOptionMenuSliderJoyDeadZone : public FOptionMenuSliderBase +{ + int mAxis; + int mNeg; + +public: + FOptionMenuSliderJoyDeadZone(const char *label, int axis, double min, double max, double step, int showval) + : FOptionMenuSliderBase(label, min, max, step, showval) + { + mAxis = axis; + mNeg = 1; + } + + double GetSliderValue() + { + double d = SELECTED_JOYSTICK->GetAxisDeadZone(mAxis); + mNeg = d < 0? -1:1; + return d; + } + + void SetSliderValue(double val) + { + SELECTED_JOYSTICK->SetAxisDeadZone(mAxis, float(val * mNeg)); + } +}; + +//============================================================================= +// +// +// +//============================================================================= + +class FOptionMenuItemJoyMap : public FOptionMenuItemOptionBase +{ + int mAxis; +public: + + FOptionMenuItemJoyMap(const char *label, int axis, const char *values, int center) + : FOptionMenuItemOptionBase(label, "none", values, NULL, center) + { + mAxis = axis; + } + + int GetSelection() + { + double f = SELECTED_JOYSTICK->GetAxisMap(mAxis); + FOptionValues **opt = OptionValues.CheckKey(mValues); + if (opt != NULL && *opt != NULL) + { + // Map from joystick axis to menu selection. + for(unsigned i = 0; i < (*opt)->mValues.Size(); i++) + { + if (fabs(f - (*opt)->mValues[i].Value) < FLT_EPSILON) + { + return i; + } + } + } + return -1; + } + + void SetSelection(int selection) + { + FOptionValues **opt = OptionValues.CheckKey(mValues); + // Map from menu selection to joystick axis. + if (opt == NULL || *opt == NULL || (unsigned)selection >= (*opt)->mValues.Size()) + { + selection = JOYAXIS_None; + } + else + { + selection = (int)(*opt)->mValues[selection].Value; + } + SELECTED_JOYSTICK->SetAxisMap(mAxis, (EJoyAxis)selection); + } +}; + +//============================================================================= +// +// +// +//============================================================================= + +class FOptionMenuItemInverter : public FOptionMenuItemOptionBase +{ + int mAxis; +public: + + FOptionMenuItemInverter(const char *label, int axis, int center) + : FOptionMenuItemOptionBase(label, "none", "YesNo", NULL, center) + { + mAxis = axis; + } + + int GetSelection() + { + float f = SELECTED_JOYSTICK->GetAxisScale(mAxis); + return f > 0? 0:1; + } + + void SetSelection(int Selection) + { + float f = fabs(SELECTED_JOYSTICK->GetAxisScale(mAxis)); + if (Selection) f*=-1; + SELECTED_JOYSTICK->SetAxisScale(mAxis, f); + } +}; + +class DJoystickConfigMenu : public DOptionMenu +{ + DECLARE_CLASS(DJoystickConfigMenu, DOptionMenu) +}; + +IMPLEMENT_CLASS(DJoystickConfigMenu) + +//============================================================================= +// +// Executes a CCMD, action is a CCMD name +// +//============================================================================= + +class FOptionMenuItemJoyConfigMenu : public FOptionMenuItemSubmenu +{ + IJoystickConfig *mJoy; +public: + FOptionMenuItemJoyConfigMenu(const char *label, IJoystickConfig *joy) + : FOptionMenuItemSubmenu(label, "JoystickConfigMenu") + { + mJoy = joy; + } + + bool Activate() + { + UpdateJoystickConfigMenu(mJoy); + return FOptionMenuItemSubmenu::Activate(); + } +}; + + +/*======================================= + * + * Joystick Menu + * + *=======================================*/ + +FOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy) +{ + FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickConfigMenu); + if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu) + { + FOptionMenuDescriptor *opt = (FOptionMenuDescriptor *)*desc; + FOptionMenuItem *it; + for(unsigned i=0;imItems.Size();i++) + { + delete opt->mItems[i]; + opt->mItems.Clear(); + } + if (joy == NULL) + { + opt->mTitle = "Configure Controller"; + it = new FOptionMenuItemStaticText("Invalid controller specified for menu", false); + opt->mItems.Push(it); + } + else + { + opt->mTitle.Format("Configure %s", joy->GetName().GetChars()); + + SELECTED_JOYSTICK = joy; + + it = new FOptionMenuSliderJoySensitivity("Overall sensitivity", 0, 2, 0.1, 3); + opt->mItems.Push(it); + it = new FOptionMenuItemStaticText(" ", false); + opt->mItems.Push(it); + + if (joy->GetNumAxes() > 0) + { + it = new FOptionMenuItemStaticText("Axis Configuration", true); + opt->mItems.Push(it); + + for (int i = 0; i < joy->GetNumAxes(); ++i) + { + it = new FOptionMenuItemStaticText(" ", false); + opt->mItems.Push(it); + + it = new FOptionMenuItemJoyMap(joy->GetAxisName(i), i, "JoyAxisMapNames", false); + opt->mItems.Push(it); + it = new FOptionMenuSliderJoyScale("Overall sensitivity", i, 0, 4, 0.1, 3); + opt->mItems.Push(it); + it = new FOptionMenuItemInverter("Invert", i, false); + opt->mItems.Push(it); + it = new FOptionMenuSliderJoyDeadZone("Dead Zone", i, 0, 0.9, 0.05, 3); + opt->mItems.Push(it); + } + } + else + { + it = new FOptionMenuItemStaticText("No configurable axes", false); + opt->mItems.Push(it); + } + } + opt->mScrollPos = 0; + opt->mSelectedItem = -1; + opt->mIndent = 0; + opt->mPosition = -25; + opt->CalcIndent(); + return opt; + } + return NULL; +} + + + +void UpdateJoystickMenu(IJoystickConfig *selected) +{ + FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickOptions); + if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu) + { + FOptionMenuDescriptor *opt = (FOptionMenuDescriptor *)*desc; + FOptionMenuItem *it; + for(unsigned i=0;imItems.Size();i++) + { + delete opt->mItems[i]; + } + opt->mItems.Clear(); + + int i; + int itemnum = -1; + + I_GetJoysticks(Joysticks); + if ((unsigned)itemnum >= Joysticks.Size()) + { + itemnum = Joysticks.Size() - 1; + } + if (selected != NULL) + { + for (i = 0; (unsigned)i < Joysticks.Size(); ++i) + { + if (Joysticks[i] == selected) + { + itemnum = i; + break; + } + } + } + + // Todo: Block joystick for changing this one. + it = new FOptionMenuItemOption("Enable controller support", "use_joystick", "YesNo", NULL, false); + opt->mItems.Push(it); + #ifdef _WIN32 + it = new FOptionMenuItemOption("Enable DirectInput controllers", "joy_dinput", "YesNo", NULL, false); + opt->mItems.Push(it); + it = new FOptionMenuItemOption("Enable XInput controllers", "joy_xinput", "YesNo", NULL, false); + opt->mItems.Push(it); + it = new FOptionMenuItemOption("Enable raw PlayStation 2 adapters", "joy_ps2raw", "YesNo", NULL, false); + opt->mItems.Push(it); + #endif + + it = new FOptionMenuItemStaticText(" ", false); + opt->mItems.Push(it); + + if (Joysticks.Size() == 0) + { + it = new FOptionMenuItemStaticText("No controllers detected", false); + opt->mItems.Push(it); + if (!use_joystick) + { + it = new FOptionMenuItemStaticText("Controller support must be", false); + opt->mItems.Push(it); + it = new FOptionMenuItemStaticText("enabled to detect any", false); + opt->mItems.Push(it); + } + } + else + { + it = new FOptionMenuItemStaticText("Configure controllers:", false); + opt->mItems.Push(it); + + for (int i = 0; i < (int)Joysticks.Size(); ++i) + { + it = new FOptionMenuItemJoyConfigMenu(Joysticks[i]->GetName(), Joysticks[i]); + opt->mItems.Push(it); + if (i == itemnum) opt->mSelectedItem = opt->mItems.Size(); + } + } + if (opt->mSelectedItem >= (int)opt->mItems.Size()) + { + opt->mSelectedItem = opt->mItems.Size() - 1; + } + + opt->CalcIndent(); + + // If the joystick config menu is open, close it if the device it's + // open for is gone. + for (i = 0; (unsigned)i < Joysticks.Size(); ++i) + { + if (Joysticks[i] == SELECTED_JOYSTICK) + { + break; + } + } + if (i == (int)Joysticks.Size()) + { + SELECTED_JOYSTICK = NULL; + if (DMenu::CurrentMenu != NULL && DMenu::CurrentMenu->IsKindOf(RUNTIME_CLASS(DJoystickConfigMenu))) + { + DMenu::CurrentMenu->Close(); + } + } + } +} + +#endif \ No newline at end of file diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp new file mode 100644 index 000000000..7bcec164b --- /dev/null +++ b/source/common/menu/listmenu.cpp @@ -0,0 +1,569 @@ +/* +** listmenu.cpp +** A simple menu consisting of a list of items +** +**--------------------------------------------------------------------------- +** Copyright 2010 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "v_font.h" +#include "cmdlib.h" +#include "gstrings.h" +#include "d_gui.h" +#include "d_event.h" +#include "menu.h" +#include "v_draw.h" + +IMPLEMENT_CLASS(DListMenu) + +//============================================================================= +// +// +// +//============================================================================= + +DListMenu::DListMenu(DMenu *parent, FListMenuDescriptor *desc) +: DMenu(parent) +{ + mDesc = NULL; + if (desc != NULL) Init(parent, desc); +} + +//============================================================================= +// +// +// +//============================================================================= + +void DListMenu::Init(DMenu *parent, FListMenuDescriptor *desc) +{ + mParentMenu = parent; + mDesc = desc; + if (desc->mCenter) + { + int center = 160; + for(unsigned i=0;imItems.Size(); i++) + { + int xpos = mDesc->mItems[i]->GetX(); + int width = mDesc->mItems[i]->GetWidth(); + int curx = mDesc->mSelectOfsX; + + if (width > 0 && mDesc->mItems[i]->Selectable()) + { + int left = 160 - (width - curx) / 2 - curx; + if (left < center) center = left; + } + } + for(unsigned i=0;imItems.Size(); i++) + { + int width = mDesc->mItems[i]->GetWidth(); + + if (width > 0) + { + mDesc->mItems[i]->SetX(center); + } + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + +FListMenuItem *DListMenu::GetItem(FName name) +{ + for(unsigned i=0;imItems.Size(); i++) + { + FName nm = mDesc->mItems[i]->GetAction(NULL); + if (nm == name) return mDesc->mItems[i]; + } + return NULL; +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DListMenu::Responder (event_t *ev) +{ + if (ev->type == EV_GUI_Event) + { + if (ev->subtype == EV_GUI_KeyDown) + { + int ch = tolower (ev->data1); + + for(unsigned i = mDesc->mSelectedItem + 1; i < mDesc->mItems.Size(); i++) + { + if (mDesc->mItems[i]->CheckHotkey(ch)) + { + mDesc->mSelectedItem = i; + //S_Sound(CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + return true; + } + } + for(int i = 0; i < mDesc->mSelectedItem; i++) + { + if (mDesc->mItems[i]->CheckHotkey(ch)) + { + mDesc->mSelectedItem = i; + //S_Sound(CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + return true; + } + } + } + } + return Super::Responder(ev); +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DListMenu::MenuEvent (int mkey, bool fromcontroller) +{ + int startedAt = mDesc->mSelectedItem; + + switch (mkey) + { + case MKEY_Up: + do + { + if (--mDesc->mSelectedItem < 0) mDesc->mSelectedItem = mDesc->mItems.Size()-1; + } + while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + return true; + + case MKEY_Down: + do + { + if (++mDesc->mSelectedItem >= (int)mDesc->mItems.Size()) mDesc->mSelectedItem = 0; + } + while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + return true; + + case MKEY_Enter: + if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate()) + { + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); + } + return true; + + default: + return Super::MenuEvent(mkey, fromcontroller); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DListMenu::MouseEvent(int type, int x, int y) +{ + int sel = -1; + + // convert x/y from screen to virtual coordinates, according to CleanX/Yfac use in DrawTexture + x = ((x - (screen->GetWidth() / 2)) / CleanXfac) + 160; + y = ((y - (screen->GetHeight() / 2)) / CleanYfac) + 100; + + if (mFocusControl != NULL) + { + mFocusControl->MouseEvent(type, x, y); + return true; + } + else + { + if ((mDesc->mWLeft <= 0 || x > mDesc->mWLeft) && + (mDesc->mWRight <= 0 || x < mDesc->mWRight)) + { + for(unsigned i=0;imItems.Size(); i++) + { + if (mDesc->mItems[i]->CheckCoordinate(x, y)) + { + if ((int)i != mDesc->mSelectedItem) + { + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + } + mDesc->mSelectedItem = i; + mDesc->mItems[i]->MouseEvent(type, x, y); + return true; + } + } + } + } + mDesc->mSelectedItem = -1; + return Super::MouseEvent(type, x, y); +} + +//============================================================================= +// +// +// +//============================================================================= + +void DListMenu::Ticker () +{ + Super::Ticker(); + for(unsigned i=0;imItems.Size(); i++) + { + mDesc->mItems[i]->Ticker(); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +void DListMenu::Drawer () +{ + for(unsigned i=0;imItems.Size(); i++) + { + if (mDesc->mItems[i]->mEnabled) mDesc->mItems[i]->Drawer(mDesc->mSelectedItem == (int)i); + } + if (mDesc->mSelectedItem >= 0 && mDesc->mSelectedItem < (int)mDesc->mItems.Size()) + mDesc->mItems[mDesc->mSelectedItem]->DrawSelector(mDesc->mSelectOfsX, mDesc->mSelectOfsY, mDesc->mSelector); + Super::Drawer(); +} + +//============================================================================= +// +// base class for menu items +// +//============================================================================= + +FListMenuItem::~FListMenuItem() +{ +} + +bool FListMenuItem::CheckCoordinate(int x, int y) +{ + return false; +} + +void FListMenuItem::Ticker() +{ +} + +void FListMenuItem::Drawer(bool selected) +{ +} + +bool FListMenuItem::Selectable() +{ + return false; +} + +void FListMenuItem::DrawSelector(int xofs, int yofs, FTexture *tex) +{ + if (!tex) + { + if ((DMenu::MenuTime%8) < 6) + { + DrawText(&twod, ConFont, OptionSettings.mFontColorSelection, + (mXpos + xofs - 160) * CleanXfac + screen->GetWidth() / 2, + (mYpos + yofs - 100) * CleanYfac + screen->GetHeight() / 2, + "\xd", + DTA_CellX, 8 * CleanXfac, + DTA_CellY, 8 * CleanYfac, + TAG_DONE); + } + } + else + { + DrawTexture (&twod, tex, mXpos + xofs, mYpos + yofs, DTA_Clean, true, TAG_DONE); + } +} + +bool FListMenuItem::Activate() +{ + return false; // cannot be activated +} + +FName FListMenuItem::GetAction(int *pparam) +{ + return mAction; +} + +bool FListMenuItem::SetString(int i, const char *s) +{ + return false; +} + +bool FListMenuItem::GetString(int i, char *s, int len) +{ + return false; +} + +bool FListMenuItem::SetValue(int i, int value) +{ + return false; +} + +bool FListMenuItem::GetValue(int i, int *pvalue) +{ + return false; +} + +void FListMenuItem::Enable(bool on) +{ + mEnabled = on; +} + +bool FListMenuItem::MenuEvent(int mkey, bool fromcontroller) +{ + return false; +} + +bool FListMenuItem::MouseEvent(int type, int x, int y) +{ + return false; +} + +bool FListMenuItem::CheckHotkey(int c) +{ + return false; +} + +int FListMenuItem::GetWidth() +{ + return 0; +} + + +//============================================================================= +// +// static patch +// +//============================================================================= + +FListMenuItemStaticPatch::FListMenuItemStaticPatch(int x, int y, FTexture *patch, bool centered) +: FListMenuItem(x, y) +{ + mTexture = patch; + mCentered = centered; +} + +void FListMenuItemStaticPatch::Drawer(bool selected) +{ + if (!mTexture) + { + return; + } + + int x = mXpos; + FTexture *tex = mTexture; + if (mYpos >= 0) + { + if (mCentered) x -= tex->GetWidth()/2; + DrawTexture (&twod, tex, x, mYpos, DTA_Clean, true, TAG_DONE); + } + else + { + int x = (mXpos - 160) * CleanXfac + (screen->GetWidth()>>1); + if (mCentered) x -= (tex->GetWidth()*CleanXfac)/2; + DrawTexture (&twod, tex, x, -mYpos*CleanYfac, DTA_CleanNoMove, true, TAG_DONE); + } +} + +//============================================================================= +// +// static text +// +//============================================================================= + +FListMenuItemStaticText::FListMenuItemStaticText(int x, int y, const char *text, FFont *font, EColorRange color, bool centered) +: FListMenuItem(x, y) +{ + mText = text; + mFont = font; + mColor = color; + mCentered = centered; +} + +void FListMenuItemStaticText::Drawer(bool selected) +{ + const char *text = mText; + if (text != NULL) + { + if (*text == '$') text = GStrings(text+1); + if (mYpos >= 0) + { + int x = mXpos; + if (mCentered) x -= mFont->StringWidth(text)/2; + DrawText(&twod, mFont, mColor, x, mYpos, text, DTA_Clean, true, TAG_DONE); + } + else + { + int x = (mXpos - 160) * CleanXfac + (screen->GetWidth()>>1); + if (mCentered) x -= (mFont->StringWidth(text)*CleanXfac)/2; + DrawText (&twod, mFont, mColor, x, -mYpos*CleanYfac, text, DTA_CleanNoMove, true, TAG_DONE); + } + } +} + +FListMenuItemStaticText::~FListMenuItemStaticText() +{ + if (mText != NULL) delete [] mText; +} + +//============================================================================= +// +// base class for selectable items +// +//============================================================================= + +FListMenuItemSelectable::FListMenuItemSelectable(int x, int y, int height, FName action, int param) +: FListMenuItem(x, y, action) +{ + mHeight = height; + mParam = param; + mHotkey = 0; +} + +bool FListMenuItemSelectable::CheckCoordinate(int x, int y) +{ + return mEnabled && y >= mYpos && y < mYpos + mHeight; // no x check here +} + +bool FListMenuItemSelectable::Selectable() +{ + return mEnabled; +} + +bool FListMenuItemSelectable::Activate() +{ + M_SetMenu(mAction, mParam); + return true; +} + +FName FListMenuItemSelectable::GetAction(int *pparam) +{ + if (pparam != NULL) *pparam = mParam; + return mAction; +} + +bool FListMenuItemSelectable::CheckHotkey(int c) +{ + return c == tolower(mHotkey); +} + +bool FListMenuItemSelectable::MouseEvent(int type, int x, int y) +{ + if (type == DMenu::MOUSE_Release) + { + if (NULL != DMenu::CurrentMenu && DMenu::CurrentMenu->MenuEvent(MKEY_Enter, true)) + { + return true; + } + } + return false; +} + +//============================================================================= +// +// text item +// +//============================================================================= + +FListMenuItemText::FListMenuItemText(int x, int y, int height, int hotkey, const char *text, FFont *font, EColorRange color, EColorRange color2, FName child, int param) +: FListMenuItemSelectable(x, y, height, child, param) +{ + mText = text; + mFont = font; + mColor = color; + mColorSelected = color2; + mHotkey = hotkey; +} + +FListMenuItemText::~FListMenuItemText() +{ + if (mText != NULL) + { + delete [] mText; + } +} + +void FListMenuItemText::Drawer(bool selected) +{ + const char *text = mText; + if (text != NULL) + { + if (*text == '$') text = GStrings(text+1); + DrawText(&twod, mFont, selected ? mColorSelected : mColor, mXpos, mYpos, text, DTA_Clean, true, TAG_DONE); + } +} + +int FListMenuItemText::GetWidth() +{ + const char *text = mText; + if (text != NULL) + { + if (*text == '$') text = GStrings(text+1); + return mFont->StringWidth(text); + } + return 1; +} + + +//============================================================================= +// +// patch item +// +//============================================================================= + +FListMenuItemPatch::FListMenuItemPatch(int x, int y, int height, int hotkey, FTexture *patch, FName child, int param) +: FListMenuItemSelectable(x, y, height, child, param) +{ + mHotkey = hotkey; + mTexture = patch; +} + +void FListMenuItemPatch::Drawer(bool selected) +{ + DrawTexture (&twod, mTexture, mXpos, mYpos, DTA_Clean, true, TAG_DONE); +} + +int FListMenuItemPatch::GetWidth() +{ + return mTexture + ? mTexture->GetWidth() + : 0; +} + diff --git a/source/common/menu/loadsavemenu.cpp b/source/common/menu/loadsavemenu.cpp new file mode 100644 index 000000000..20c5f6caf --- /dev/null +++ b/source/common/menu/loadsavemenu.cpp @@ -0,0 +1,958 @@ +/* +** loadsavemenu.cpp +** The load game and save game menus +** +**--------------------------------------------------------------------------- +** Copyright 2001-2010 Randy Heit +** Copyright 2010 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "menu/menu.h" +#include "version.h" +#include "m_png.h" +#include "filesystem.h" +#include "v_text.h" +#include "d_event.h" +#include "gstrings.h" +#include "d_gui.h" +#include "v_draw.h" +#include "../../platform/win32/i_findfile.h" // This is a temporary direct path. Needs to be fixed when stuff gets cleaned up. + + + +class DLoadSaveMenu : public DListMenu +{ + DECLARE_CLASS(DLoadSaveMenu, DListMenu) + friend void ClearSaveGames(); + +protected: + static TArray SaveGames; + static int LastSaved; + static int LastAccessed; + + int Selected; + int TopItem; + + + int savepicLeft; + int savepicTop; + int savepicWidth; + int savepicHeight; + + int rowHeight; + int listboxLeft; + int listboxTop; + int listboxWidth; + + int listboxRows; + int listboxHeight; + int listboxRight; + int listboxBottom; + + int commentLeft; + int commentTop; + int commentWidth; + int commentHeight; + int commentRight; + int commentBottom; + + + static int InsertSaveNode (FSaveGameNode *node); + static void ReadSaveStrings (); + + + FTexture *SavePic; + TArray SaveComment; + bool mEntering; + FString savegamestring; + + DLoadSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); + void Destroy(); + + int RemoveSaveSlot (int index); + void UnloadSaveData (); + void ClearSaveStuff (); + void ExtractSaveData (int index); + void Drawer (); + bool MenuEvent (int mkey, bool fromcontroller); + bool MouseEvent(int type, int x, int y); + bool Responder(event_t *ev); + +public: + static void NotifyNewSave (const char *file, const char *title, bool okForQuicksave); + +}; + +IMPLEMENT_CLASS(DLoadSaveMenu) + +TArray DLoadSaveMenu::SaveGames; +int DLoadSaveMenu::LastSaved = -1; +int DLoadSaveMenu::LastAccessed = -1; + +FSaveGameNode *quickSaveSlot; + +//============================================================================= +// +// Save data maintenance (stored statically) +// +//============================================================================= + +void ClearSaveGames() +{ + for(unsigned i=0;ibNoDelete) + delete DLoadSaveMenu::SaveGames[i]; + } + DLoadSaveMenu::SaveGames.Clear(); +} + +//============================================================================= +// +// Save data maintenance (stored statically) +// +//============================================================================= + +int DLoadSaveMenu::RemoveSaveSlot (int index) +{ + FSaveGameNode *file = SaveGames[index]; + + if (quickSaveSlot == SaveGames[index]) + { + quickSaveSlot = NULL; + } + if (Selected == index) + { + Selected = -1; + } + if (!file->bNoDelete) delete file; + SaveGames.Delete(index); + if ((unsigned)index >= SaveGames.Size()) index--; + return index; +} + +//============================================================================= +// +// +// +//============================================================================= + +int DLoadSaveMenu::InsertSaveNode (FSaveGameNode *node) +{ + if (SaveGames.Size() == 0) + { + return SaveGames.Push(node); + } + + if (node->bOldVersion) + { // Add node at bottom of list + return SaveGames.Push(node); + } + else + { // Add node at top of list + unsigned int i; + for(i = 0; i < SaveGames.Size(); i++) + { + if (SaveGames[i]->bOldVersion || + stricmp (node->Title, SaveGames[i]->Title) <= 0) + { + break; + } + } + SaveGames.Insert(i, node); + return i; + } +} + + +//============================================================================= +// +// M_ReadSaveStrings +// +// Find savegames and read their titles +// +//============================================================================= + +void DLoadSaveMenu::ReadSaveStrings () +{ + if (SaveGames.Size() == 0) + { + void *filefirst; + findstate_t c_file; + FString filter; + + LastSaved = LastAccessed = -1; + quickSaveSlot = NULL; + filter = "";// G_BuildSaveName("*.zds", -1); + filefirst = I_FindFirst (filter.GetChars(), &c_file); + if (filefirst != ((void *)(-1))) + { + do + { + // I_FindName only returns the file's name and not its full path + FString filepath = "";// G_BuildSaveName(I_FindName(&c_file), -1); + FILE *file = fopen (filepath, "rb"); + + if (file != NULL) + { + //PNGHandle *png; + //char sig[16]; + FString title; + bool oldVer = true; + bool addIt = false; + bool missing = false; + + // ZDoom 1.23 betas 21-33 have the savesig first. + // Earlier versions have the savesig second. + // Later versions have the savegame encapsulated inside a PNG. + // + // Old savegame versions are always added to the menu so + // the user can easily delete them if desired. + + // Todo: Identify savegames here. + } + } while (I_FindNext (filefirst, &c_file) == 0); + I_FindClose (filefirst); + } + } +} + + +//============================================================================= +// +// +// +//============================================================================= + +void DLoadSaveMenu::NotifyNewSave (const char *file, const char *title, bool okForQuicksave) +{ + FSaveGameNode *node; + + if (file == NULL) + return; + + ReadSaveStrings (); + + // See if the file is already in our list + for (unsigned i=0; iFilename.Compare (file) == 0) +#else + if (node->Filename.CompareNoCase (file) == 0) +#endif + { + node->Title = title; + node->bOldVersion = false; + node->bMissingWads = false; + if (okForQuicksave) + { + if (quickSaveSlot == NULL) quickSaveSlot = node; + LastAccessed = LastSaved = i; + } + return; + } + } + + node = new FSaveGameNode; + node->Title = title; + node->Filename = file; + node->bOldVersion = false; + node->bMissingWads = false; + int index = InsertSaveNode (node); + + if (okForQuicksave) + { + if (quickSaveSlot == NULL) quickSaveSlot = node; + LastAccessed = LastSaved = index; + } +} + +void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave) +{ + DLoadSaveMenu::NotifyNewSave(file, title, okForQuicksave); +} + +//============================================================================= +// +// End of static savegame maintenance code +// +//============================================================================= + +DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, FListMenuDescriptor *desc) +: DListMenu(parent, desc) +{ + ReadSaveStrings(); + + savepicLeft = 10; + savepicTop = 54*CleanYfac; + savepicWidth = 216*screen->GetWidth()/640; + savepicHeight = 135*screen->GetHeight()/400; + + rowHeight = (SmallFont->GetHeight() + 1) * CleanYfac; + listboxLeft = savepicLeft + savepicWidth + 14; + listboxTop = savepicTop; + listboxWidth = screen->GetWidth() - listboxLeft - 10; + int listboxHeight1 = screen->GetHeight() - listboxTop - 10; + listboxRows = (listboxHeight1 - 1) / rowHeight; + listboxHeight = listboxRows * rowHeight + 1; + listboxRight = listboxLeft + listboxWidth; + listboxBottom = listboxTop + listboxHeight; + + commentLeft = savepicLeft; + commentTop = savepicTop + savepicHeight + 16; + commentWidth = savepicWidth; + commentHeight = (51+(screen->GetHeight()>200?10:0))*CleanYfac; + commentRight = commentLeft + commentWidth; + commentBottom = commentTop + commentHeight; +} + +void DLoadSaveMenu::Destroy() +{ + ClearSaveStuff (); +} + +//============================================================================= +// +// +// +//============================================================================= + +void DLoadSaveMenu::UnloadSaveData () +{ + if (SavePic != NULL) + { + delete SavePic; + } + SaveComment.Clear(); + + SavePic = NULL; +} + +//============================================================================= +// +// +// +//============================================================================= + +void DLoadSaveMenu::ClearSaveStuff () +{ + UnloadSaveData(); + if (quickSaveSlot == (FSaveGameNode*)1) + { + quickSaveSlot = NULL; + } +} + +//============================================================================= +// +// +// +//============================================================================= + +void DLoadSaveMenu::ExtractSaveData (int index) +{ + FILE *file; + //PNGHandle *png; + FSaveGameNode *node; + + UnloadSaveData (); + + if ((unsigned)index < SaveGames.Size() && + (node = SaveGames[index]) && + !node->Filename.IsEmpty() && + !node->bOldVersion && + (file = fopen (node->Filename.GetChars(), "rb")) != NULL) + { + // Todo. + } +} + +//============================================================================= +// +// +// +//============================================================================= + +void DLoadSaveMenu::Drawer () +{ + Super::Drawer(); + + FSaveGameNode *node; + int i; + unsigned j; + bool didSeeSelected = false; + + // Draw picture area + /* + if (gameaction == ga_loadgame || gameaction == ga_loadgamehidecon || gameaction == ga_savegame) + { + return; + } + */ + + //V_DrawFrame (savepicLeft, savepicTop, savepicWidth, savepicHeight); + if (SavePic != NULL) + { + DrawTexture(&twod, SavePic, savepicLeft, savepicTop, + DTA_DestWidth, savepicWidth, + DTA_DestHeight, savepicHeight, + DTA_Masked, false, + TAG_DONE); + } + else + { + twod.AddColorOnlyQuad(savepicLeft, savepicTop, savepicLeft+savepicWidth, savepicTop+savepicHeight, 0xff000000); + + if (SaveGames.Size() > 0) + { + const char *text = + (Selected == -1 || !SaveGames[Selected]->bOldVersion) + ? GStrings("MNU_NOPICTURE") : GStrings("MNU_DIFFVERSION"); + const int textlen = SmallFont->StringWidth (text)*CleanXfac; + + DrawText (&twod, SmallFont, CR_GOLD, savepicLeft+(savepicWidth-textlen)/2, + savepicTop+(savepicHeight-rowHeight)/2, text, + DTA_CleanNoMove, true, TAG_DONE); + } + } + + // Draw comment area + //V_DrawFrame (commentLeft, commentTop, commentWidth, commentHeight); + twod.AddColorOnlyQuad(commentLeft, commentTop, commentRight, commentBottom, 0xff000000); + if (SaveComment.Size()) + { + // I'm not sure why SaveComment would go NULL in this loop, but I got + // a crash report where it was NULL when i reached 1, so now I check + // for that. + for (i = 0; i < SaveComment.Size() && SaveComment[i].Width >= 0 && i < 6; ++i) + { + DrawText (&twod, SmallFont, CR_GOLD, commentLeft, commentTop + + SmallFont->GetHeight()*i*CleanYfac, SaveComment[i].Text, + DTA_CleanNoMove, true, TAG_DONE); + } + } + + // Draw file area + //V_DrawFrame (listboxLeft, listboxTop, listboxWidth, listboxHeight); + twod.AddColorOnlyQuad(listboxLeft, listboxTop, listboxRight, listboxBottom, 0xff000000); + + if (SaveGames.Size() == 0) + { + const char * text = GStrings("MNU_NOFILES"); + const int textlen = SmallFont->StringWidth (text)*CleanXfac; + + DrawText (&twod, SmallFont, CR_GOLD, listboxLeft+(listboxWidth-textlen)/2, + listboxTop+(listboxHeight-rowHeight)/2, text, + DTA_CleanNoMove, true, TAG_DONE); + return; + } + + for (i = 0, j = TopItem; i < listboxRows && j < SaveGames.Size(); i++,j++) + { + int color; + node = SaveGames[j]; + if (node->bOldVersion) + { + color = CR_BLUE; + } + else if (node->bMissingWads) + { + color = CR_ORANGE; + } + else if ((int)j == Selected) + { + color = CR_WHITE; + } + else + { + color = CR_TAN; + } + + if ((int)j == Selected) + { + twod.AddColorOnlyQuad(listboxLeft, listboxTop+rowHeight*i, listboxRight, listboxTop+rowHeight*(i+1), mEntering ? PalEntry(255,255,0,0) : PalEntry(255,0,0,255)); + didSeeSelected = true; + if (!mEntering) + { + DrawText(&twod, SmallFont, color, + listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->Title, + DTA_CleanNoMove, true, TAG_DONE); + } + else + { + DrawText(&twod, SmallFont, CR_WHITE, + listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, savegamestring, + DTA_CleanNoMove, true, TAG_DONE); + + char curs[2] = { SmallFont->GetCursor(), 0 }; + DrawText(&twod, SmallFont, CR_WHITE, + listboxLeft+1+SmallFont->StringWidth (savegamestring)*CleanXfac, + listboxTop+rowHeight*i+CleanYfac, + curs, + DTA_CleanNoMove, true, TAG_DONE); + } + } + else + { + DrawText(&twod, SmallFont, color, + listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->Title, + DTA_CleanNoMove, true, TAG_DONE); + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DLoadSaveMenu::MenuEvent (int mkey, bool fromcontroller) +{ + switch (mkey) + { + case MKEY_Up: + if (SaveGames.Size() > 1) + { + if (Selected == -1) Selected = TopItem; + else + { + if (--Selected < 0) Selected = SaveGames.Size()-1; + if (Selected < TopItem) TopItem = Selected; + else if (Selected >= TopItem + listboxRows) TopItem = std::max(0, Selected - listboxRows + 1); + } + UnloadSaveData (); + ExtractSaveData (Selected); + } + return true; + + case MKEY_Down: + if (SaveGames.Size() > 1) + { + if (Selected == -1) Selected = TopItem; + else + { + if (unsigned(++Selected) >= SaveGames.Size()) Selected = 0; + if (Selected < TopItem) TopItem = Selected; + else if (Selected >= TopItem + listboxRows) TopItem = std::max(0, Selected - listboxRows + 1); + } + UnloadSaveData (); + ExtractSaveData (Selected); + } + return true; + + case MKEY_PageDown: + if (SaveGames.Size() > 1) + { + if (TopItem >= (int)SaveGames.Size() - listboxRows) + { + TopItem = 0; + if (Selected != -1) Selected = 0; + } + else + { + TopItem = std::min(TopItem + listboxRows, SaveGames.Size() - listboxRows); + if (TopItem > Selected && Selected != -1) Selected = TopItem; + } + UnloadSaveData (); + ExtractSaveData (Selected); + } + return true; + + case MKEY_PageUp: + if (SaveGames.Size() > 1) + { + if (TopItem == 0) + { + TopItem = SaveGames.Size() - listboxRows; + if (Selected != -1) Selected = TopItem; + } + else + { + TopItem = std::max(TopItem - listboxRows, 0); + if (Selected >= TopItem + listboxRows) Selected = TopItem; + } + UnloadSaveData (); + ExtractSaveData (Selected); + } + return true; + + case MKEY_Enter: + return false; // This event will be handled by the subclasses + + case MKEY_MBYes: + { + if ((unsigned)Selected < SaveGames.Size()) + { + int listindex = SaveGames[0]->bNoDelete? Selected-1 : Selected; + remove (SaveGames[Selected]->Filename.GetChars()); + UnloadSaveData (); + Selected = RemoveSaveSlot (Selected); + ExtractSaveData (Selected); + + if (LastSaved == listindex) LastSaved = -1; + else if (LastSaved > listindex) LastSaved--; + if (LastAccessed == listindex) LastAccessed = -1; + else if (LastAccessed > listindex) LastAccessed--; + } + return true; + } + + default: + return Super::MenuEvent(mkey, fromcontroller); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DLoadSaveMenu::MouseEvent(int type, int x, int y) +{ + if (x >= listboxLeft && x < listboxLeft + listboxWidth && + y >= listboxTop && y < listboxTop + listboxHeight) + { + int lineno = (y - listboxTop) / rowHeight; + + if (TopItem + lineno < (int)SaveGames.Size()) + { + Selected = TopItem + lineno; + UnloadSaveData (); + ExtractSaveData (Selected); + if (type == MOUSE_Release) + { + if (MenuEvent(MKEY_Enter, true)) + { + return true; + } + } + } + else Selected = -1; + } + else Selected = -1; + + return Super::MouseEvent(type, x, y); +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DLoadSaveMenu::Responder (event_t *ev) +{ + if (ev->type == EV_GUI_Event) + { + if (ev->subtype == EV_GUI_KeyDown) + { + if ((unsigned)Selected < SaveGames.Size()) + { + switch (ev->data1) + { + case GK_F1: + if (!SaveGames[Selected]->Filename.IsEmpty()) + { + FStringf workbuf("File on disk:\n%s", SaveGames[Selected]->Filename.GetChars()); + SaveComment = V_BreakLines (SmallFont, 216*screen->GetWidth()/640/CleanXfac, workbuf); + } + return true; + + case GK_DEL: + case '\b': + { + FString EndString; + EndString.Format("%s" TEXTCOLOR_WHITE "%s" TEXTCOLOR_NORMAL "?\n\n%s", + GStrings("MNU_DELETESG"), SaveGames[Selected]->Title, GStrings("PRESSYN")); + M_StartMessage (EndString, 0); + } + return true; + } + } + } + else if (ev->subtype == EV_GUI_WheelUp) + { + if (TopItem > 0) TopItem--; + return true; + } + else if (ev->subtype == EV_GUI_WheelDown) + { + if (TopItem < (int)SaveGames.Size() - listboxRows) TopItem++; + return true; + } + } + return Super::Responder(ev); +} + + +//============================================================================= +// +// +// +//============================================================================= + +class DSaveMenu : public DLoadSaveMenu +{ + DECLARE_CLASS(DSaveMenu, DLoadSaveMenu) + + FSaveGameNode NewSaveNode; + +public: + + DSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); + void Destroy(); + void DoSave (FSaveGameNode *node); + bool Responder (event_t *ev); + bool MenuEvent (int mkey, bool fromcontroller); + +}; + +IMPLEMENT_CLASS(DSaveMenu) + + +//============================================================================= +// +// +// +//============================================================================= + +DSaveMenu::DSaveMenu(DMenu *parent, FListMenuDescriptor *desc) +: DLoadSaveMenu(parent, desc) +{ + NewSaveNode.Title = GStrings["NEWSAVE"]; + NewSaveNode.bNoDelete = true; + SaveGames.Insert(0, &NewSaveNode); + TopItem = 0; + if (LastSaved == -1) + { + Selected = 0; + } + else + { + Selected = LastSaved + 1; + } + ExtractSaveData (Selected); +} + +//============================================================================= +// +// +// +//============================================================================= + +void DSaveMenu::Destroy() +{ + if (SaveGames[0] == &NewSaveNode) + { + SaveGames.Delete(0); + if (Selected == 0) Selected = -1; + else Selected--; + } +} + +//============================================================================= +// +// +// +//============================================================================= + +void DSaveMenu::DoSave (FSaveGameNode *node) +{ + if (node != &NewSaveNode) + { + //G_SaveGame (node->Filename.GetChars(), savegamestring); + } + else + { + // Find an unused filename and save as that + FString filename; + int i; + FILE *test; + + for (i = 0;; ++i) + { + filename = "";// G_BuildSaveName("save", i); + test = fopen (filename, "rb"); + if (test == NULL) + { + break; + } + fclose (test); + } + //G_SaveGame (filename, savegamestring); + } + M_ClearMenus(); +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DSaveMenu::MenuEvent (int mkey, bool fromcontroller) +{ + if (Super::MenuEvent(mkey, fromcontroller)) + { + return true; + } + if (Selected == -1) + { + return false; + } + + if (mkey == MKEY_Enter) + { + if (Selected != 0) + { + savegamestring = SaveGames[Selected]->Title; + } + else + { + savegamestring = ""; + } + DMenu *input = new DTextEnterMenu(this, savegamestring, 1, fromcontroller); + M_ActivateMenu(input); + mEntering = true; + } + else if (mkey == MKEY_Input) + { + mEntering = false; + DoSave(SaveGames[Selected]); + } + else if (mkey == MKEY_Abort) + { + mEntering = false; + } + return false; +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DSaveMenu::Responder (event_t *ev) +{ + if (ev->subtype == EV_GUI_KeyDown) + { + if (Selected != -1) + { + switch (ev->data1) + { + case GK_DEL: + case '\b': + // cannot delete 'new save game' item + if (Selected == 0) return true; + break; + + case 'N': + Selected = TopItem = 0; + UnloadSaveData (); + return true; + } + } + } + return Super::Responder(ev); +} + +//============================================================================= +// +// +// +//============================================================================= + +class DLoadMenu : public DLoadSaveMenu +{ + DECLARE_CLASS(DLoadMenu, DLoadSaveMenu) + +public: + + DLoadMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); + + bool MenuEvent (int mkey, bool fromcontroller); +}; + +IMPLEMENT_CLASS(DLoadMenu) + + +//============================================================================= +// +// +// +//============================================================================= + +DLoadMenu::DLoadMenu(DMenu *parent, FListMenuDescriptor *desc) +: DLoadSaveMenu(parent, desc) +{ + TopItem = 0; + if (LastAccessed != -1) + { + Selected = LastAccessed; + } + ExtractSaveData (Selected); + +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DLoadMenu::MenuEvent (int mkey, bool fromcontroller) +{ + if (Super::MenuEvent(mkey, fromcontroller)) + { + return true; + } + if (Selected == -1 || SaveGames.Size() == 0) + { + return false; + } + + if (mkey == MKEY_Enter) + { + //G_LoadGame (SaveGames[Selected]->Filename.GetChars(), true); + if (quickSaveSlot == (FSaveGameNode*)1) + { + quickSaveSlot = SaveGames[Selected]; + } + M_ClearMenus(); + LastAccessed = Selected; + return true; + } + return false; +} + diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp new file mode 100644 index 000000000..57e9219d8 --- /dev/null +++ b/source/common/menu/menu.cpp @@ -0,0 +1,812 @@ +/* +** menu.cpp +** Menu base class and global interface +** +**--------------------------------------------------------------------------- +** Copyright 2010 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "c_dispatch.h" +#include "d_gui.h" +#include "c_console.h" +#include "c_bind.h" +#include "c_cvars.h" +#include "d_event.h" +//#include "i_input.h" +#include "gameconfigfile.h" +#include "gstrings.h" +#include "menu.h" +#include "textures.h" +#include "c_buttons.h" +#include "v_2ddrawer.h" +#include "printf.h" +#include "v_draw.h" +#include "gamecontrol.h" + +// +// Todo: Move these elsewhere +// +CVAR (Float, mouse_sensitivity, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +EXTERN_CVAR (Bool, show_messages) + + +CVAR (Float, snd_menuvolume, 0.6f, CVAR_ARCHIVE) +CVAR(Int, m_use_mouse, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR(Int, m_show_backbutton, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + +DMenu *DMenu::CurrentMenu; +int DMenu::MenuTime; + +FGameStartup GameStartupInfo; +EMenuState menuactive; +bool M_DemoNoPlay; +FButtonStatus MenuButtons[NUM_MKEYS]; +int MenuButtonTickers[NUM_MKEYS]; +bool MenuButtonOrigin[NUM_MKEYS]; +int BackbuttonTime; +float BackbuttonAlpha; +static bool MenuEnabled = true; + + +#define KEY_REPEAT_DELAY (MENU_TICRATE*5/12) +#define KEY_REPEAT_RATE (3) + +//============================================================================ +// +// DMenu base class +// +//============================================================================ + +IMPLEMENT_CLASS (DMenu) + +DMenu::DMenu(DMenu *parent) +{ + mParentMenu = parent; + mMouseCapture = false; + mBackbuttonSelected = false; +} + +bool DMenu::Responder (event_t *ev) +{ + bool res = false; + if (ev->type == EV_GUI_Event) + { + if (ev->subtype == EV_GUI_LButtonDown) + { + res = MouseEventBack(MOUSE_Click, ev->data1, ev->data2); + // make the menu's mouse handler believe that the current coordinate is outside the valid range + if (res) ev->data2 = -1; + res |= MouseEvent(MOUSE_Click, ev->data1, ev->data2); + if (res) + { + SetCapture(); + } + + } + else if (ev->subtype == EV_GUI_MouseMove) + { + BackbuttonTime = BACKBUTTON_TIME; + if (mMouseCapture || m_use_mouse == 1) + { + res = MouseEventBack(MOUSE_Move, ev->data1, ev->data2); + if (res) ev->data2 = -1; + res |= MouseEvent(MOUSE_Move, ev->data1, ev->data2); + } + } + else if (ev->subtype == EV_GUI_LButtonUp) + { + if (mMouseCapture) + { + ReleaseCapture(); + res = MouseEventBack(MOUSE_Release, ev->data1, ev->data2); + if (res) ev->data2 = -1; + res |= MouseEvent(MOUSE_Release, ev->data1, ev->data2); + } + } + } + return false; +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DMenu::MenuEvent (int mkey, bool fromcontroller) +{ + switch (mkey) + { + case MKEY_Back: + { + Close(); + //S_Sound (CHAN_VOICE | CHAN_UI, DMenu::CurrentMenu != NULL? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE); + return true; + } + } + return false; +} + +//============================================================================= +// +// +// +//============================================================================= + +void DMenu::Close () +{ + assert(DMenu::CurrentMenu == this); + DMenu::CurrentMenu = mParentMenu; + Destroy(); + if (DMenu::CurrentMenu == NULL) + { + M_ClearMenus (); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DMenu::MouseEvent(int type, int x, int y) +{ + return true; +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DMenu::MouseEventBack(int type, int x, int y) +{ + if (m_show_backbutton >= 0) + { +#if 0 + FTexture *tex = TexMan(gameinfo.mBackButton); + if (tex != NULL) + { + if (m_show_backbutton&1) x -= screen->GetWidth() - tex->GetScaledWidth() * CleanXfac; + if (m_show_backbutton&2) y -= screen->GetHeight() - tex->GetScaledHeight() * CleanYfac; + mBackbuttonSelected = ( x >= 0 && x < tex->GetScaledWidth() * CleanXfac && + y >= 0 && y < tex->GetScaledHeight() * CleanYfac); + if (mBackbuttonSelected && type == MOUSE_Release) + { + if (m_use_mouse == 2) mBackbuttonSelected = false; + MenuEvent(MKEY_Back, true); + } + return mBackbuttonSelected; + } +#endif + } + return false; +} + +//============================================================================= +// +// +// +//============================================================================= + +void DMenu::SetCapture() +{ + if (!mMouseCapture) + { + mMouseCapture = true; + I_SetMouseCapture(); + } +} + +void DMenu::ReleaseCapture() +{ + if (mMouseCapture) + { + mMouseCapture = false; + I_ReleaseMouseCapture(); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +void DMenu::Ticker () +{ +} + +void DMenu::Drawer () +{ +#if 0 + if (this == DMenu::CurrentMenu && BackbuttonAlpha > 0 && m_show_backbutton >= 0 && m_use_mouse) + { + FTexture *tex = TexMan(gameinfo.mBackButton); + int w = tex->GetScaledWidth() * CleanXfac; + int h = tex->GetScaledHeight() * CleanYfac; + int x = (!(m_show_backbutton&1))? 0:screen->GetWidth() - w; + int y = (!(m_show_backbutton&2))? 0:screen->GetHeight() - h; + if (mBackbuttonSelected && (mMouseCapture || m_use_mouse == 1)) + { + screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_ColorOverlay, MAKEARGB(40, 255,255,255), TAG_DONE); + } + else + { + screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_Alpha, BackbuttonAlpha, TAG_DONE); + } + } +#endif +} + +bool DMenu::DimAllowed() +{ + return true; +} + +bool DMenu::TranslateKeyboardEvents() +{ + return true; +} + +//============================================================================= +// +// +// +//============================================================================= + +void M_StartControlPanel (bool makeSound) +{ + // intro might call this repeatedly + if (DMenu::CurrentMenu != NULL) + return; + + buttonMap.ResetButtonStates (); + for (int i = 0; i < NUM_MKEYS; ++i) + { + MenuButtons[i].ReleaseKey(0); + } + + C_HideConsole (); // [RH] Make sure console goes bye bye. + menuactive = MENU_On; + // Pause sound effects before we play the menu switch sound. + // That way, it won't be paused. + //P_CheckTickerPaused (); + + if (makeSound) + { + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); + } + BackbuttonTime = 0; + BackbuttonAlpha = 0; +} + +//============================================================================= +// +// +// +//============================================================================= + +void M_ActivateMenu(DMenu *menu) +{ + if (menuactive == MENU_Off) menuactive = MENU_On; + if (DMenu::CurrentMenu != NULL) DMenu::CurrentMenu->ReleaseCapture(); + DMenu::CurrentMenu = menu; +} + +//============================================================================= +// +// +// +//============================================================================= + +void M_SetMenu(FName menu, int param) +{ + // some menus need some special treatment (needs to be adjusted for the various frontends. +#if 0 + switch (menu) + { + case NAME_Episodemenu: + // sent from the player class menu + GameStartupInfo.Skill = -1; + GameStartupInfo.Episode = -1; + GameStartupInfo.PlayerClass = + param == -1000? NULL : + param == -1? "Random" : GetPrintableDisplayName(PlayerClasses[param].Type); + break; + + case NAME_Skillmenu: + // sent from the episode menu + + if ((gameinfo.flags & GI_SHAREWARE) && param > 0) + { + // Only Doom and Heretic have multi-episode shareware versions. + M_StartMessage(GStrings("SWSTRING"), 1); + return; + } + + GameStartupInfo.Episode = param; + M_StartupSkillMenu(&GameStartupInfo); // needs player class name from class menu (later) + break; + + case NAME_StartgameConfirm: + { + // sent from the skill menu for a skill that needs to be confirmed + GameStartupInfo.Skill = param; + + const char *msg = AllSkills[param].MustConfirmText; + if (*msg==0) msg = GStrings("NIGHTMARE"); + M_StartMessage (msg, 0, NAME_StartgameConfirmed); + return; + } + + case NAME_Startgame: + // sent either from skill menu or confirmation screen. Skill gets only set if sent from skill menu + // Now we can finally start the game. Ugh... + GameStartupInfo.Skill = param; + case NAME_StartgameConfirmed: + + G_DeferedInitNew (&GameStartupInfo); + if (gamestate == GS_FULLCONSOLE) + { + gamestate = GS_HIDECONSOLE; + gameaction = ga_newgame; + } + M_ClearMenus (); + return; + + case NAME_Savegamemenu: + if (!usergame || (players[consoleplayer].health <= 0 && !multiplayer) || gamestate != GS_LEVEL) + { + // cannot save outside the game. + M_StartMessage (GStrings("SAVEDEAD"), 1); + return; + } + } +#endif + + // End of special checks + + FMenuDescriptor **desc = MenuDescriptors.CheckKey(menu); + if (desc != NULL) + { + /* + if ((*desc)->mNetgameMessage.IsNotEmpty() && netgame && !demoplayback) + { + M_StartMessage((*desc)->mNetgameMessage, 1); + return; + } + */ + + if ((*desc)->mType == MDESC_ListMenu) + { + FListMenuDescriptor *ld = static_cast(*desc); + if (ld->mAutoselect >= 0 && ld->mAutoselect < (int)ld->mItems.Size()) + { + // recursively activate the autoselected item without ever creating this menu. + ld->mItems[ld->mAutoselect]->Activate(); + } + else + { + const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DListMenu) : ld->mClass; + + DListMenu *newmenu = (DListMenu *)cls->CreateNew(); + newmenu->Init(DMenu::CurrentMenu, ld); + M_ActivateMenu(newmenu); + } + } + else if ((*desc)->mType == MDESC_OptionsMenu) + { + FOptionMenuDescriptor *ld = static_cast(*desc); + const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DOptionMenu) : ld->mClass; + + DOptionMenu *newmenu = (DOptionMenu *)cls->CreateNew(); + newmenu->Init(DMenu::CurrentMenu, ld); + M_ActivateMenu(newmenu); + } + return; + } + else + { + const PClass *menuclass = PClass::FindClass(menu); + if (menuclass != NULL) + { + if (menuclass->IsDescendantOf(RUNTIME_CLASS(DMenu))) + { + DMenu *newmenu = (DMenu*)menuclass->CreateNew(); + newmenu->mParentMenu = DMenu::CurrentMenu; + M_ActivateMenu(newmenu); + return; + } + } + } + Printf("Attempting to open menu of unknown type '%s'\n", menu.GetChars()); +} + +//============================================================================= +// +// +// +//============================================================================= + +bool M_Responder (event_t *ev) +{ + int ch = 0; + bool keyup = false; + int mkey = NUM_MKEYS; + bool fromcontroller = true; + + /* + if (chatmodeon) + { + return false; + } + */ + + if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) + { + // There are a few input sources we are interested in: + // + // EV_KeyDown / EV_KeyUp : joysticks/gamepads/controllers + // EV_GUI_KeyDown / EV_GUI_KeyUp : the keyboard + // EV_GUI_Char : printable characters, which we want in string input mode + // + // This code previously listened for EV_GUI_KeyRepeat to handle repeating + // in the menus, but that doesn't work with gamepads, so now we combine + // the multiple inputs into buttons and handle the repetition manually. + if (ev->type == EV_GUI_Event) + { + fromcontroller = false; + if (ev->subtype == EV_GUI_KeyRepeat) + { + // We do our own key repeat handling but still want to eat the + // OS's repeated keys. + return true; + } + else if (ev->subtype == EV_GUI_BackButtonDown || ev->subtype == EV_GUI_BackButtonUp) + { + mkey = MKEY_Back; + keyup = ev->subtype == EV_GUI_BackButtonUp; + } + else if (ev->subtype != EV_GUI_KeyDown && ev->subtype != EV_GUI_KeyUp) + { + // do we want mouse input? + if (ev->subtype >= EV_GUI_FirstMouseEvent && ev->subtype <= EV_GUI_LastMouseEvent) + { + if (!m_use_mouse) + return true; + } + + // pass everything else on to the current menu + return DMenu::CurrentMenu->Responder(ev); + } + else if (DMenu::CurrentMenu->TranslateKeyboardEvents()) + { + ch = ev->data1; + keyup = ev->subtype == EV_GUI_KeyUp; + switch (ch) + { + case GK_BACK: mkey = MKEY_Back; break; + case GK_ESCAPE: mkey = MKEY_Back; break; + case GK_RETURN: mkey = MKEY_Enter; break; + case GK_UP: mkey = MKEY_Up; break; + case GK_DOWN: mkey = MKEY_Down; break; + case GK_LEFT: mkey = MKEY_Left; break; + case GK_RIGHT: mkey = MKEY_Right; break; + case GK_BACKSPACE: mkey = MKEY_Clear; break; + case GK_PGUP: mkey = MKEY_PageUp; break; + case GK_PGDN: mkey = MKEY_PageDown; break; + default: + if (!keyup) + { + return DMenu::CurrentMenu->Responder(ev); + } + break; + } + } + } + else if (menuactive != MENU_WaitKey && (ev->type == EV_KeyDown || ev->type == EV_KeyUp)) + { + keyup = ev->type == EV_KeyUp; + + ch = ev->data1; + switch (ch) + { + case KEY_JOY1: + case KEY_PAD_A: + mkey = MKEY_Enter; + break; + + case KEY_JOY2: + case KEY_PAD_B: + mkey = MKEY_Back; + break; + + case KEY_JOY3: + case KEY_PAD_X: + mkey = MKEY_Clear; + break; + + case KEY_JOY5: + case KEY_PAD_LSHOULDER: + mkey = MKEY_PageUp; + break; + + case KEY_JOY6: + case KEY_PAD_RSHOULDER: + mkey = MKEY_PageDown; + break; + + case KEY_PAD_DPAD_UP: + case KEY_PAD_LTHUMB_UP: + case KEY_JOYAXIS1MINUS: + case KEY_JOYPOV1_UP: + mkey = MKEY_Up; + break; + + case KEY_PAD_DPAD_DOWN: + case KEY_PAD_LTHUMB_DOWN: + case KEY_JOYAXIS1PLUS: + case KEY_JOYPOV1_DOWN: + mkey = MKEY_Down; + break; + + case KEY_PAD_DPAD_LEFT: + case KEY_PAD_LTHUMB_LEFT: + case KEY_JOYAXIS2MINUS: + case KEY_JOYPOV1_LEFT: + mkey = MKEY_Left; + break; + + case KEY_PAD_DPAD_RIGHT: + case KEY_PAD_LTHUMB_RIGHT: + case KEY_JOYAXIS2PLUS: + case KEY_JOYPOV1_RIGHT: + mkey = MKEY_Right; + break; + } + } + + if (mkey != NUM_MKEYS) + { + if (keyup) + { + MenuButtons[mkey].ReleaseKey(ch); + return false; + } + else + { + MenuButtons[mkey].PressKey(ch); + MenuButtonOrigin[mkey] = fromcontroller; + if (mkey <= MKEY_PageDown) + { + MenuButtonTickers[mkey] = KEY_REPEAT_DELAY; + } + DMenu::CurrentMenu->MenuEvent(mkey, fromcontroller); + return true; + } + } + return DMenu::CurrentMenu->Responder(ev) || !keyup; + } + else if (MenuEnabled) + { + if (ev->type == EV_KeyDown) + { + // Pop-up menu? + if (ev->data1 == KEY_ESCAPE) + { + M_StartControlPanel(true); + M_SetMenu(NAME_Mainmenu, -1); + return true; + } + return false; + } + else if (ev->type == EV_GUI_Event && ev->subtype == EV_GUI_LButtonDown && + ConsoleState != c_down && m_use_mouse) + { + M_StartControlPanel(true); + M_SetMenu(NAME_Mainmenu, -1); + return true; + } + } + return false; +} + +//============================================================================= +// +// +// +//============================================================================= + +void M_Ticker (void) +{ + DMenu::MenuTime++; + if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) + { + DMenu::CurrentMenu->Ticker(); + + for (int i = 0; i < NUM_MKEYS; ++i) + { + if (MenuButtons[i].bDown) + { + if (MenuButtonTickers[i] > 0 && --MenuButtonTickers[i] <= 0) + { + MenuButtonTickers[i] = KEY_REPEAT_RATE; + DMenu::CurrentMenu->MenuEvent(i, MenuButtonOrigin[i]); + } + } + } + if (BackbuttonTime > 0) + { + if (BackbuttonAlpha < 1.0f) BackbuttonAlpha += 0.1f; + BackbuttonTime--; + } + else + { + if (BackbuttonAlpha > 0) BackbuttonAlpha -= 0.1f; + if (BackbuttonAlpha < 0) BackbuttonAlpha = 0; + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + +void M_Drawer (void) +{ + PalEntry fade = 0;// x70000000; +#if 0 + player_t *player = &players[consoleplayer]; + AActor *camera = player->camera; + + if (!screen->Accel2D && camera != NULL && (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL)) + { + if (camera->player != NULL) + { + player = camera->player; + } + fade = PalEntry (BYTE(player->BlendA*255), BYTE(player->BlendR*255), BYTE(player->BlendG*255), BYTE(player->BlendB*255)); + } +#endif + + + if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off && fade) + { + if (DMenu::CurrentMenu->DimAllowed()) twod.AddColorOnlyQuad(0, 0, screen->GetWidth(), screen->GetHeight(), fade); + DMenu::CurrentMenu->Drawer(); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +void M_ClearMenus () +{ + M_DemoNoPlay = false; + if (DMenu::CurrentMenu != NULL) + { + DMenu::CurrentMenu->Destroy(); + DMenu::CurrentMenu = NULL; + } + menuactive = MENU_Off; +} + +//============================================================================= +// +// +// +//============================================================================= + +void M_Init (void) +{ + M_ParseMenuDefs(); + M_CreateMenus(); +} + + +//============================================================================= +// +// +// +//============================================================================= + +void M_EnableMenu (bool on) +{ + MenuEnabled = on; +} + + +//============================================================================= +// +// [RH] Most menus can now be accessed directly +// through console commands. +// +//============================================================================= + + +CCMD (openmenu) +{ + if (argv.argc() < 2) + { + Printf("Usage: openmenu \"menu_name\""); + return; + } + M_StartControlPanel (true); + M_SetMenu(argv[1], -1); +} + +CCMD (closemenu) +{ + M_ClearMenus(); +} + +// +// Toggle messages on/off +// +CCMD (togglemessages) +{ + if (show_messages) + { + Printf (128, "%s\n", GStrings("MSGOFF")); + show_messages = false; + } + else + { + Printf (128, "%s\n", GStrings("MSGON")); + show_messages = true; + } +} + +EXTERN_CVAR (Int, screenblocks) + +CCMD(menuconsole) +{ + M_ClearMenus(); + C_ToggleConsole(); +} + +CCMD(reset2defaults) +{ + C_SetDefaultBindings (); + C_SetCVarsToDefaults (); +} + +CCMD(reset2saved) +{ + GameConfig->DoGlobalSetup (); + GameConfig->DoGameSetup (currentGame); +} diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h new file mode 100644 index 000000000..8d70dac72 --- /dev/null +++ b/source/common/menu/menu.h @@ -0,0 +1,615 @@ +#ifndef __M_MENU_MENU_H__ +#define __M_MENU_MENU_H__ + + + + +#include "dobject.h" +#include "c_cvars.h" +#include "v_font.h" +#include "version.h" +#include "textures.h" + +EXTERN_CVAR(Float, snd_menuvolume) +EXTERN_CVAR(Int, m_use_mouse); + + +const int MENU_TICRATE = 30; + + +enum EMenuState : int +{ + MENU_Off, // Menu is closed + MENU_On, // Menu is opened + MENU_WaitKey, // Menu is opened and waiting for a key in the controls menu + MENU_OnNoPause, // Menu is opened but does not pause the game +}; + +struct event_t; +class FTexture; +class FFont; +enum EColorRange; +class FPlayerClass; +class FKeyBindings; + +enum EMenuKey +{ + MKEY_Up, + MKEY_Down, + MKEY_Left, + MKEY_Right, + MKEY_PageUp, + MKEY_PageDown, + //----------------- Keys past here do not repeat. + MKEY_Enter, + MKEY_Back, // Back to previous menu + MKEY_Clear, // Clear keybinding/flip player sprite preview + NUM_MKEYS, + + // These are not buttons but events sent from other menus + + MKEY_Input, // Sent when input is confirmed + MKEY_Abort, // Input aborted + MKEY_MBYes, + MKEY_MBNo, +}; + + +struct FGameStartup +{ + const char *PlayerClass; + int Episode; + int Skill; +}; + +extern FGameStartup GameStartupInfo; + +struct FSaveGameNode +{ + FString Title; + FString Filename; + bool bOldVersion; + bool bMissingWads; + bool bNoDelete; + + FSaveGameNode() { bNoDelete = false; } +}; + +extern EMenuState menuactive; + + +//============================================================================= +// +// menu descriptor. This is created from the menu definition lump +// Items must be inserted in the order they are cycled through with the cursor +// +//============================================================================= + +enum EMenuDescriptorType +{ + MDESC_ListMenu, + MDESC_OptionsMenu, +}; + +struct FMenuDescriptor +{ + FName mMenuName; + FString mNetgameMessage; + int mType; + const PClass *mClass; + + virtual ~FMenuDescriptor() {} +}; + +class FListMenuItem; +class FOptionMenuItem; + +struct FListMenuDescriptor : public FMenuDescriptor +{ + TDeletingArray mItems; + int mSelectedItem; + int mSelectOfsX; + int mSelectOfsY; + FTexture *mSelector; + int mDisplayTop; + int mXpos, mYpos; + int mWLeft, mWRight; + int mLinespacing; // needs to be stored for dynamically created menus + int mAutoselect; // this can only be set by internal menu creation functions + FFont *mFont; + EColorRange mFontColor; + EColorRange mFontColor2; + FMenuDescriptor *mRedirect; // used to redirect overlong skill and episode menus to option menu based alternatives + bool mCenter; + + void Reset() + { + // Reset the default settings (ignore all other values in the struct) + mSelectOfsX = 0; + mSelectOfsY = 0; + mSelector = nullptr; + mDisplayTop = 0; + mXpos = 0; + mYpos = 0; + mLinespacing = 0; + mNetgameMessage = ""; + mFont = NULL; + mFontColor = CR_UNTRANSLATED; + mFontColor2 = CR_UNTRANSLATED; + } +}; + +struct FOptionMenuSettings +{ + EColorRange mTitleColor; + EColorRange mFontColor; + EColorRange mFontColorValue; + EColorRange mFontColorMore; + EColorRange mFontColorHeader; + EColorRange mFontColorHighlight; + EColorRange mFontColorSelection; + int mLinespacing; +}; + +struct FOptionMenuDescriptor : public FMenuDescriptor +{ + TDeletingArray mItems; + FString mTitle; + int mSelectedItem; + int mDrawTop; + int mScrollTop; + int mScrollPos; + int mIndent; + int mPosition; + bool mDontDim; + + void CalcIndent(); + FOptionMenuItem *GetItem(FName name); + void Reset() + { + // Reset the default settings (ignore all other values in the struct) + mPosition = 0; + mScrollTop = 0; + mIndent = 0; + mDontDim = 0; + } + +}; + + +typedef TMap MenuDescriptorList; + +extern FOptionMenuSettings OptionSettings; +extern MenuDescriptorList MenuDescriptors; + +#define CURSORSPACE (14 * CleanXfac_1) + +//============================================================================= +// +// +// +//============================================================================= + +struct FMenuRect +{ + int x, y; + int width, height; + + void set(int _x, int _y, int _w, int _h) + { + x = _x; + y = _y; + width = _w; + height = _h; + } + + bool inside(int _x, int _y) + { + return _x >= x && _x < x+width && _y >= y && _y < y+height; + } + +}; + + +class DMenu : public DObject +{ + DECLARE_CLASS (DMenu, DObject) + +protected: + bool mMouseCapture; + bool mBackbuttonSelected; + +public: + enum + { + MOUSE_Click, + MOUSE_Move, + MOUSE_Release + }; + + enum + { + BACKBUTTON_TIME = 4*MENU_TICRATE + }; + + static DMenu *CurrentMenu; + static int MenuTime; + + DMenu *mParentMenu; + + DMenu(DMenu *parent = NULL); + virtual bool Responder (event_t *ev); + virtual bool MenuEvent (int mkey, bool fromcontroller); + virtual void Ticker (); + virtual void Drawer (); + virtual bool DimAllowed (); + virtual bool TranslateKeyboardEvents(); + virtual void Close(); + virtual bool MouseEvent(int type, int x, int y); + bool MouseEventBack(int type, int x, int y); + void SetCapture(); + void ReleaseCapture(); + bool HasCapture() + { + return mMouseCapture; + } +}; + +//============================================================================= +// +// base class for menu items +// +//============================================================================= + +class FListMenuItem +{ +protected: + int mXpos, mYpos; + FName mAction; + +public: + bool mEnabled; + + FListMenuItem(int xpos = 0, int ypos = 0, FName action = NAME_None) + { + mXpos = xpos; + mYpos = ypos; + mAction = action; + mEnabled = true; + } + + virtual ~FListMenuItem(); + + virtual bool CheckCoordinate(int x, int y); + virtual void Ticker(); + virtual void Drawer(bool selected); + virtual bool Selectable(); + virtual bool Activate(); + virtual FName GetAction(int *pparam); + virtual bool SetString(int i, const char *s); + virtual bool GetString(int i, char *s, int len); + virtual bool SetValue(int i, int value); + virtual bool GetValue(int i, int *pvalue); + virtual void Enable(bool on); + virtual bool MenuEvent (int mkey, bool fromcontroller); + virtual bool MouseEvent(int type, int x, int y); + virtual bool CheckHotkey(int c); + virtual int GetWidth(); + void DrawSelector(int xofs, int yofs, FTexture *tex); + void OffsetPositionY(int ydelta) { mYpos += ydelta; } + int GetY() { return mYpos; } + int GetX() { return mXpos; } + void SetX(int x) { mXpos = x; } +}; + +class FListMenuItemStaticPatch : public FListMenuItem +{ +protected: + FTexture *mTexture; + bool mCentered; + +public: + FListMenuItemStaticPatch(int x, int y, FTexture *patch, bool centered); + void Drawer(bool selected); +}; + +class FListMenuItemStaticText : public FListMenuItem +{ +protected: + const char *mText; + FFont *mFont; + EColorRange mColor; + bool mCentered; + +public: + FListMenuItemStaticText(int x, int y, const char *text, FFont *font, EColorRange color, bool centered); + ~FListMenuItemStaticText(); + void Drawer(bool selected); +}; + +//============================================================================= +// +// the player sprite window +// +//============================================================================= +#if 0 +class FListMenuItemPlayerDisplay : public FListMenuItem +{ + FListMenuDescriptor *mOwner; + FTexture *mBackdrop; + FRemapTable mRemap; + FPlayerClass *mPlayerClass; + int mPlayerTics; + bool mNoportrait; + uint8_t mRotation; + uint8_t mMode; // 0: automatic (used by class selection), 1: manual (used by player setup) + uint8_t mTranslate; + int mSkin; + int mRandomClass; + int mRandomTimer; + int mClassNum; + + void SetPlayerClass(int classnum, bool force = false); + bool UpdatePlayerClass(); + void UpdateRandomClass(); + void UpdateTranslation(); + +public: + + enum + { + PDF_ROTATION = 0x10001, + PDF_SKIN = 0x10002, + PDF_CLASS = 0x10003, + PDF_MODE = 0x10004, + PDF_TRANSLATE = 0x10005, + }; + + FListMenuItemPlayerDisplay(FListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action); + ~FListMenuItemPlayerDisplay(); + virtual void Ticker(); + virtual void Drawer(bool selected); + bool SetValue(int i, int value); +}; +#endif + + +//============================================================================= +// +// selectable items +// +//============================================================================= + +class FListMenuItemSelectable : public FListMenuItem +{ +protected: + int mHotkey; + int mHeight; + int mParam; + +public: + FListMenuItemSelectable(int x, int y, int height, FName childmenu, int mParam = -1); + bool CheckCoordinate(int x, int y); + bool Selectable(); + bool CheckHotkey(int c); + bool Activate(); + bool MouseEvent(int type, int x, int y); + FName GetAction(int *pparam); +}; + +class FListMenuItemText : public FListMenuItemSelectable +{ + const char *mText; + FFont *mFont; + EColorRange mColor; + EColorRange mColorSelected; +public: + FListMenuItemText(int x, int y, int height, int hotkey, const char *text, FFont *font, EColorRange color, EColorRange color2, FName child, int param = 0); + ~FListMenuItemText(); + void Drawer(bool selected); + int GetWidth(); +}; + +class FListMenuItemPatch : public FListMenuItemSelectable +{ + FTexture* mTexture; +public: + FListMenuItemPatch(int x, int y, int height, int hotkey, FTexture* patch, FName child, int param = 0); + void Drawer(bool selected); + int GetWidth(); +}; + +//============================================================================= +// +// list menu class runs a menu described by a FListMenuDescriptor +// +//============================================================================= + +class DListMenu : public DMenu +{ + DECLARE_CLASS(DListMenu, DMenu) + +protected: + FListMenuDescriptor *mDesc; + FListMenuItem *mFocusControl; + +public: + DListMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); + virtual void Init(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); + FListMenuItem *GetItem(FName name); + bool Responder (event_t *ev); + bool MenuEvent (int mkey, bool fromcontroller); + bool MouseEvent(int type, int x, int y); + void Ticker (); + void Drawer (); + void SetFocus(FListMenuItem *fc) + { + mFocusControl = fc; + } + bool CheckFocus(FListMenuItem *fc) + { + return mFocusControl == fc; + } + void ReleaseFocus() + { + mFocusControl = NULL; + } +}; + + +//============================================================================= +// +// base class for menu items +// +//============================================================================= + +class FOptionMenuItem : public FListMenuItem +{ +protected: + FString mLabel; + bool mCentered; + + void drawLabel(int indent, int y, EColorRange color, bool grayed = false); +public: + + FOptionMenuItem(const char *text, FName action = NAME_None, bool center = false) + : FListMenuItem(0, 0, action) + { + mLabel = text; + mCentered = center; + } + + ~FOptionMenuItem(); + virtual int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected); + virtual bool Selectable(); + virtual int GetIndent(); + virtual bool MouseEvent(int type, int x, int y); +}; + +//============================================================================= +// +// +// +//============================================================================= +struct FOptionValues +{ + struct Pair + { + double Value; + FString TextValue; + FString Text; + }; + + TArray mValues; +}; + +typedef TMap< FName, FOptionValues* > FOptionMap; + +extern FOptionMap OptionValues; + + +//============================================================================= +// +// Option menu class runs a menu described by a FOptionMenuDescriptor +// +//============================================================================= + +class DOptionMenu : public DMenu +{ + DECLARE_CLASS(DOptionMenu, DMenu) + + bool CanScrollUp; + bool CanScrollDown; + int VisBottom; + FOptionMenuItem *mFocusControl; + +protected: + FOptionMenuDescriptor *mDesc; + +public: + FOptionMenuItem *GetItem(FName name); + DOptionMenu(DMenu *parent = NULL, FOptionMenuDescriptor *desc = NULL); + virtual void Init(DMenu *parent = NULL, FOptionMenuDescriptor *desc = NULL); + int FirstSelectable(); + bool Responder (event_t *ev); + bool MenuEvent (int mkey, bool fromcontroller); + bool MouseEvent(int type, int x, int y); + void Ticker (); + void Drawer (); + const FOptionMenuDescriptor *GetDescriptor() const { return mDesc; } + void SetFocus(FOptionMenuItem *fc) + { + mFocusControl = fc; + } + bool CheckFocus(FOptionMenuItem *fc) + { + return mFocusControl == fc; + } + void ReleaseFocus() + { + mFocusControl = NULL; + } +}; + + +//============================================================================= +// +// Input some text +// +//============================================================================= + +class DTextEnterMenu : public DMenu +{ + DECLARE_ABSTRACT_CLASS(DTextEnterMenu, DMenu) + + TArray mEnterString; + FString* mOutString; + unsigned int mEnterSize; + unsigned int mEnterPos; + int mSizeMode; // 1: size is length in chars. 2: also check string width + bool mInputGridOkay; + + int InputGridX; + int InputGridY; + + // [TP] + bool AllowColors; + +public: + + // [TP] Added allowcolors + DTextEnterMenu(DMenu *parent, FString &textbuffer, int sizemode, bool showgrid, bool allowcolors = false); + + void Drawer (); + bool MenuEvent (int mkey, bool fromcontroller); + bool Responder(event_t *ev); + bool TranslateKeyboardEvents(); + bool MouseEvent(int type, int x, int y); + +}; + + + + +struct event_t; +void M_EnableMenu (bool on) ; +bool M_Responder (event_t *ev); +void M_Ticker (void); +void M_Drawer (void); +void M_Init (void); +void M_CreateMenus(); +void M_ActivateMenu(DMenu *menu); +void M_ClearMenus (); +void M_ParseMenuDefs(); +void M_StartupSkillMenu(FGameStartup *gs); +int M_GetDefaultSkill(); +void M_StartControlPanel (bool makeSound); +void M_SetMenu(FName menu, int param = -1); +void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave); +void M_StartMessage(const char *message, int messagemode, FName action = NAME_None); + +void I_SetMouseCapture(); +void I_ReleaseMouseCapture(); + + +#endif \ No newline at end of file diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp new file mode 100644 index 000000000..4f1f5939b --- /dev/null +++ b/source/common/menu/menudef.cpp @@ -0,0 +1,1321 @@ +/* +** menudef.cpp +** MENUDEF parser amd menu generation code +** +**--------------------------------------------------------------------------- +** Copyright 2010 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ +#include + +#include "menu.h" +#include "c_dispatch.h" +#include "filesystem.h" +#include "sc_man.h" +#include "v_font.h" +#include "c_bind.h" +#include "d_event.h" +#include "d_gui.h" +#include "printf.h" +#include "gamecontrol.h" +#include "cmdlib.h" + +#include "optionmenuitems.h" + +void ClearSaveGames(); + +MenuDescriptorList MenuDescriptors; +static FListMenuDescriptor DefaultListMenuSettings; // contains common settings for all list menus +static FOptionMenuDescriptor DefaultOptionMenuSettings; // contains common settings for all Option menus +FOptionMenuSettings OptionSettings; +FOptionMap OptionValues; + +void I_BuildALDeviceList(FOptionValues *opt); + +static void DeinitMenus() +{ + { + MenuDescriptorList::Iterator it(MenuDescriptors); + + MenuDescriptorList::Pair *pair; + + while (it.NextPair(pair)) + { + delete pair->Value; + pair->Value = NULL; + } + } + + { + FOptionMap::Iterator it(OptionValues); + + FOptionMap::Pair *pair; + + while (it.NextPair(pair)) + { + delete pair->Value; + pair->Value = NULL; + } + } + MenuDescriptors.Clear(); + OptionValues.Clear(); + DMenu::CurrentMenu = NULL; + DefaultListMenuSettings.mItems.Clear(); + ClearSaveGames(); +} + +static FTexture* GetMenuTexture(const char* const name) +{ + auto tex = TileFiles.GetTexture(name); + + if (!tex) + { + Printf("Missing menu texture: \"%s\"\n", name); + } + + return tex; +} + +//============================================================================= +// +// +// +//============================================================================= + +static void SkipSubBlock(FScanner &sc) +{ + sc.MustGetStringName("{"); + int depth = 1; + while (depth > 0) + { + sc.MustGetString(); + if (sc.Compare("{")) depth++; + if (sc.Compare("}")) depth--; + } +} + +//============================================================================= +// +// +// +//============================================================================= + +struct gamefilter +{ + const char* gamename; + int gameflag; +}; + +static const gamefilter games[] = { + { "Duke", GAMEFLAG_DUKE}, + { "Nam", GAMEFLAG_NAM}, + { "WW2GI", GAMEFLAG_WW2GI}, + { "Fury", GAMEFLAG_FURY}, + { "Redneck", GAMEFLAG_RR}, + { "RedneckRides", GAMEFLAG_RRRA}, + { "Blood", GAMEFLAG_BLOOD}, + { "ShadowWarrior", GAMEFLAG_SW}, +}; + + +static bool CheckSkipGameBlock(FScanner &sc) +{ + int filter = 0; + sc.MustGetStringName("("); + do + { + sc.MustGetString(); + int gi = sc.MustMatchString(&games[0].gamename, sizeof(games[0])); + + filter |= games[gi].gameflag; + } + while (sc.CheckString(",")); + sc.MustGetStringName(")"); + if (!(filter & 1)) // todo: apply correct filter. + { + SkipSubBlock(sc); + return true; + } + return false; +} + +//============================================================================= +// +// +// +//============================================================================= + +static bool CheckSkipOptionBlock(FScanner &sc) +{ + bool filter = false; + sc.MustGetStringName("("); + do + { + sc.MustGetString(); + if (sc.Compare("Windows")) + { + #ifdef _WIN32 + filter = true; + #endif + } + else if (sc.Compare("unix")) + { + #ifdef __unix__ + filter = true; + #endif + } + else if (sc.Compare("Mac")) + { + #ifdef __APPLE__ + filter = true; + #endif + } + } + while (sc.CheckString(",")); + sc.MustGetStringName(")"); + if (!filter) + { + SkipSubBlock(sc); + return !sc.CheckString("else"); + } + return false; +} + +//============================================================================= +// +// +// +//============================================================================= + +static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) +{ + sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (sc.Compare("else")) + { + SkipSubBlock(sc); + } + else if (sc.Compare("ifgame")) + { + if (!CheckSkipGameBlock(sc)) + { + // recursively parse sub-block + ParseListMenuBody(sc, desc); + } + } + else if (sc.Compare("ifoption")) + { + if (!CheckSkipOptionBlock(sc)) + { + // recursively parse sub-block + ParseListMenuBody(sc, desc); + } + } + else if (sc.Compare("Class")) + { + sc.MustGetString(); + const PClass *cls = PClass::FindClass(sc.String); + if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(DListMenu))) + { + sc.ScriptError("Unknown menu class '%s'", sc.String); + } + desc->mClass = cls; + } + else if (sc.Compare("Selector")) + { + sc.MustGetString(); + desc->mSelector = GetMenuTexture(sc.String); + sc.MustGetStringName(","); + sc.MustGetNumber(); + desc->mSelectOfsX = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + desc->mSelectOfsY = sc.Number; + } + else if (sc.Compare("Linespacing")) + { + sc.MustGetNumber(); + desc->mLinespacing = sc.Number; + } + else if (sc.Compare("Position")) + { + sc.MustGetNumber(); + desc->mXpos = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + desc->mYpos = sc.Number; + } + else if (sc.Compare("Centermenu")) + { + desc->mCenter = true; + } + else if (sc.Compare("MouseWindow")) + { + sc.MustGetNumber(); + desc->mWLeft = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + desc->mWRight = sc.Number; + } + else if (sc.Compare("StaticPatch") || sc.Compare("StaticPatchCentered")) + { + bool centered = sc.Compare("StaticPatchCentered"); + sc.MustGetNumber(); + int x = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + int y = sc.Number; + sc.MustGetStringName(","); + sc.MustGetString(); + FTexture* tex = GetMenuTexture(sc.String); + + FListMenuItem *it = new FListMenuItemStaticPatch(x, y, tex, centered); + desc->mItems.Push(it); + } + else if (sc.Compare("StaticText") || sc.Compare("StaticTextCentered")) + { + bool centered = sc.Compare("StaticTextCentered"); + sc.MustGetNumber(); + int x = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + int y = sc.Number; + sc.MustGetStringName(","); + sc.MustGetString(); + FListMenuItem *it = new FListMenuItemStaticText(x, y, sc.String, desc->mFont, desc->mFontColor, centered); + desc->mItems.Push(it); + } + else if (sc.Compare("PatchItem")) + { + sc.MustGetString(); + FTexture* tex = GetMenuTexture(sc.String); + sc.MustGetStringName(","); + sc.MustGetString(); + int hotkey = sc.String[0]; + sc.MustGetStringName(","); + sc.MustGetString(); + FName action = sc.String; + int param = 0; + if (sc.CheckString(",")) + { + sc.MustGetNumber(); + param = sc.Number; + } + + FListMenuItem *it = new FListMenuItemPatch(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, tex, action, param); + desc->mItems.Push(it); + desc->mYpos += desc->mLinespacing; + if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; + } + else if (sc.Compare("TextItem")) + { + sc.MustGetString(); + FString text = sc.String; + sc.MustGetStringName(","); + sc.MustGetString(); + int hotkey = sc.String[0]; + sc.MustGetStringName(","); + sc.MustGetString(); + FName action = sc.String; + int param = 0; + if (sc.CheckString(",")) + { + sc.MustGetNumber(); + param = sc.Number; + } + + FListMenuItem *it = new FListMenuItemText(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, text, desc->mFont, desc->mFontColor, desc->mFontColor2, action, param); + desc->mItems.Push(it); + desc->mYpos += desc->mLinespacing; + if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; + + } + else if (sc.Compare("Font")) + { + sc.MustGetString(); + FFont *newfont = V_GetFont(sc.String); + if (newfont != NULL) desc->mFont = newfont; + if (sc.CheckString(",")) + { + sc.MustGetString(); + desc->mFontColor2 = desc->mFontColor = V_FindFontColor((FName)sc.String); + if (sc.CheckString(",")) + { + sc.MustGetString(); + desc->mFontColor2 = V_FindFontColor((FName)sc.String); + } + } + else + { + desc->mFontColor = OptionSettings.mFontColor; + desc->mFontColor2 = OptionSettings.mFontColorValue; + } + } + else if (sc.Compare("NetgameMessage")) + { + sc.MustGetString(); + desc->mNetgameMessage = sc.String; + } +#if 0 + else if (sc.Compare("PlayerDisplay")) + { + bool noportrait = false; + FName action = NAME_None; + sc.MustGetNumber(); + int x = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + int y = sc.Number; + sc.MustGetStringName(","); + sc.MustGetString(); + PalEntry c1 = V_GetColor(NULL, sc.String); + sc.MustGetStringName(","); + sc.MustGetString(); + PalEntry c2 = V_GetColor(NULL, sc.String); + if (sc.CheckString(",")) + { + sc.MustGetNumber(); + noportrait = !!sc.Number; + if (sc.CheckString(",")) + { + sc.MustGetString(); + action = sc.String; + } + } + FListMenuItemPlayerDisplay *it = new FListMenuItemPlayerDisplay(desc, x, y, c1, c2, noportrait, action); + desc->mItems.Push(it); + } +#endif + else + { + sc.ScriptError("Unknown keyword '%s'", sc.String); + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + +static bool CheckCompatible(FMenuDescriptor *newd, FMenuDescriptor *oldd) +{ + if (oldd->mClass == NULL) return true; + return oldd->mClass == newd->mClass; +} + +static bool ReplaceMenu(FScanner &sc, FMenuDescriptor *desc) +{ + FMenuDescriptor **pOld = MenuDescriptors.CheckKey(desc->mMenuName); + if (pOld != NULL && *pOld != NULL) + { + if (CheckCompatible(desc, *pOld)) + { + delete *pOld; + } + else + { + sc.ScriptMessage("Tried to replace menu '%s' with a menu of different type", desc->mMenuName.GetChars()); + return true; + } + } + MenuDescriptors[desc->mMenuName] = desc; + return false; +} + +//============================================================================= +// +// +// +//============================================================================= + +static void ParseListMenu(FScanner &sc) +{ + sc.MustGetString(); + + FListMenuDescriptor *desc = new FListMenuDescriptor; + desc->mType = MDESC_ListMenu; + desc->mMenuName = sc.String; + desc->mSelectedItem = -1; + desc->mAutoselect = -1; + desc->mSelectOfsX = DefaultListMenuSettings.mSelectOfsX; + desc->mSelectOfsY = DefaultListMenuSettings.mSelectOfsY; + desc->mSelector = DefaultListMenuSettings.mSelector; + desc->mDisplayTop = DefaultListMenuSettings.mDisplayTop; + desc->mXpos = DefaultListMenuSettings.mXpos; + desc->mYpos = DefaultListMenuSettings.mYpos; + desc->mLinespacing = DefaultListMenuSettings.mLinespacing; + desc->mNetgameMessage = DefaultListMenuSettings.mNetgameMessage; + desc->mFont = DefaultListMenuSettings.mFont; + desc->mFontColor = DefaultListMenuSettings.mFontColor; + desc->mFontColor2 = DefaultListMenuSettings.mFontColor2; + desc->mClass = NULL; + desc->mRedirect = NULL; + desc->mWLeft = 0; + desc->mWRight = 0; + desc->mCenter = false; + + ParseListMenuBody(sc, desc); + bool scratch = ReplaceMenu(sc, desc); + if (scratch) delete desc; +} + +//============================================================================= +// +// +// +//============================================================================= + +static void ParseOptionValue(FScanner &sc) +{ + FName optname; + + FOptionValues *val = new FOptionValues; + sc.MustGetString(); + optname = sc.String; + sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { + FOptionValues::Pair &pair = val->mValues[val->mValues.Reserve(1)]; + sc.MustGetFloat(); + pair.Value = sc.Float; + sc.MustGetStringName(","); + sc.MustGetString(); + pair.Text = strbin1(sc.String); + } + FOptionValues **pOld = OptionValues.CheckKey(optname); + if (pOld != NULL && *pOld != NULL) + { + delete *pOld; + } + OptionValues[optname] = val; +} + + +//============================================================================= +// +// +// +//============================================================================= + +static void ParseOptionString(FScanner &sc) +{ + FName optname; + + FOptionValues *val = new FOptionValues; + sc.MustGetString(); + optname = sc.String; + sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { + FOptionValues::Pair &pair = val->mValues[val->mValues.Reserve(1)]; + sc.MustGetString(); + pair.Value = DBL_MAX; + pair.TextValue = sc.String; + sc.MustGetStringName(","); + sc.MustGetString(); + pair.Text = strbin1(sc.String); + } + FOptionValues **pOld = OptionValues.CheckKey(optname); + if (pOld != NULL && *pOld != NULL) + { + delete *pOld; + } + OptionValues[optname] = val; +} + + +//============================================================================= +// +// +// +//============================================================================= + +static void ParseOptionSettings(FScanner &sc) +{ + sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (sc.Compare("else")) + { + SkipSubBlock(sc); + } + else if (sc.Compare("ifgame")) + { + if (!CheckSkipGameBlock(sc)) + { + // recursively parse sub-block + ParseOptionSettings(sc); + } + } + else if (sc.Compare("Linespacing")) + { + sc.MustGetNumber(); + OptionSettings.mLinespacing = sc.Number; + } + else if (sc.Compare("LabelOffset")) + { + sc.MustGetNumber(); + // ignored + } + else + { + sc.ScriptError("Unknown keyword '%s'", sc.String); + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + +static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) +{ + sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (sc.Compare("else")) + { + SkipSubBlock(sc); + } + else if (sc.Compare("ifgame")) + { + if (!CheckSkipGameBlock(sc)) + { + // recursively parse sub-block + ParseOptionMenuBody(sc, desc); + } + } + else if (sc.Compare("ifoption")) + { + if (!CheckSkipOptionBlock(sc)) + { + // recursively parse sub-block + ParseOptionMenuBody(sc, desc); + } + } + else if (sc.Compare("Class")) + { + sc.MustGetString(); + const PClass *cls = PClass::FindClass(sc.String); + if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(DOptionMenu))) + { + sc.ScriptError("Unknown menu class '%s'", sc.String); + } + desc->mClass = cls; + } + else if (sc.Compare("Title")) + { + sc.MustGetString(); + desc->mTitle = sc.String; + } + else if (sc.Compare("Position")) + { + sc.MustGetNumber(); + desc->mPosition = sc.Number; + } + else if (sc.Compare("DefaultSelection")) + { + sc.MustGetNumber(); + desc->mSelectedItem = sc.Number; + } + else if (sc.Compare("ScrollTop")) + { + sc.MustGetNumber(); + desc->mScrollTop = sc.Number; + } + else if (sc.Compare("Indent")) + { + sc.MustGetNumber(); + desc->mIndent = sc.Number; + } + else if (sc.Compare("Submenu")) + { + sc.MustGetString(); + FString label = sc.String; + sc.MustGetStringName(","); + sc.MustGetString(); + FOptionMenuItem *it = new FOptionMenuItemSubmenu(label, sc.String); + desc->mItems.Push(it); + } + else if (sc.Compare("Option")) + { + sc.MustGetString(); + FString label = sc.String; + sc.MustGetStringName(","); + sc.MustGetString(); + FString cvar = sc.String; + sc.MustGetStringName(","); + sc.MustGetString(); + FString values = sc.String; + FString check; + int center = 0; + if (sc.CheckString(",")) + { + sc.MustGetString(); + if (*sc.String != 0) check = sc.String; + if (sc.CheckString(",")) + { + sc.MustGetNumber(); + center = sc.Number; + } + } + FOptionMenuItem *it = new FOptionMenuItemOption(label, cvar, values, check, center); + desc->mItems.Push(it); + } + else if (sc.Compare("Command")) + { + sc.MustGetString(); + FString label = sc.String; + sc.MustGetStringName(","); + sc.MustGetString(); + FOptionMenuItem *it = new FOptionMenuItemCommand(label, sc.String); + desc->mItems.Push(it); + } + else if (sc.Compare("SafeCommand")) + { + sc.MustGetString(); + FString label = sc.String; + sc.MustGetStringName(","); + sc.MustGetString(); + FOptionMenuItem *it = new FOptionMenuItemSafeCommand(label, sc.String); + desc->mItems.Push(it); + } + else if (sc.Compare("Control") || sc.Compare("MapControl")) + { + bool map = sc.Compare("MapControl"); + sc.MustGetString(); + FString label = sc.String; + sc.MustGetStringName(","); + sc.MustGetString(); + FOptionMenuItem *it = new FOptionMenuItemControl(label, sc.String, map? &AutomapBindings : &Bindings); + desc->mItems.Push(it); + } + else if (sc.Compare("StaticText")) + { + sc.MustGetString(); + FString label = sc.String; + bool cr = false; + if (sc.CheckString(",")) + { + sc.MustGetNumber(); + cr = !!sc.Number; + } + FOptionMenuItem *it = new FOptionMenuItemStaticText(label, cr); + desc->mItems.Push(it); + } + else if (sc.Compare("StaticTextSwitchable")) + { + sc.MustGetString(); + FString label = sc.String; + sc.MustGetStringName(","); + sc.MustGetString(); + FString label2 = sc.String; + sc.MustGetStringName(","); + sc.MustGetString(); + FName action = sc.String; + bool cr = false; + if (sc.CheckString(",")) + { + sc.MustGetNumber(); + cr = !!sc.Number; + } + FOptionMenuItem *it = new FOptionMenuItemStaticTextSwitchable(label, label2, action, cr); + desc->mItems.Push(it); + } + else if (sc.Compare("Slider")) + { + sc.MustGetString(); + FString text = sc.String; + sc.MustGetStringName(","); + sc.MustGetString(); + FString action = sc.String; + sc.MustGetStringName(","); + sc.MustGetFloat(); + double min = sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + double max = sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + double step = sc.Float; + int showvalue = 1; + if (sc.CheckString(",")) + { + sc.MustGetNumber(); + showvalue = sc.Number; + } + FOptionMenuItem *it = new FOptionMenuSliderCVar(text, action, min, max, step, showvalue); + desc->mItems.Push(it); + } + // [TP] -- Text input widget + else if ( sc.Compare( "TextField" )) + { + sc.MustGetString(); + FString label = sc.String; + sc.MustGetStringName( "," ); + sc.MustGetString(); + FString cvar = sc.String; + FString check; + + if ( sc.CheckString( "," )) + { + sc.MustGetString(); + check = sc.String; + } + + FOptionMenuItem* it = new FOptionMenuTextField( label, cvar, check ); + desc->mItems.Push( it ); + } + // [TP] -- Number input widget + else if ( sc.Compare( "NumberField" )) + { + sc.MustGetString(); + FString label = sc.String; + sc.MustGetStringName( "," ); + sc.MustGetString(); + FString cvar = sc.String; + float minimum = 0.0f; + float maximum = 100.0f; + float step = 1.0f; + FString check; + + if ( sc.CheckString( "," )) + { + sc.MustGetFloat(); + minimum = (float) sc.Float; + sc.MustGetStringName( "," ); + sc.MustGetFloat(); + maximum = (float) sc.Float; + + if ( sc.CheckString( "," )) + { + sc.MustGetFloat(); + step = (float) sc.Float; + + if ( sc.CheckString( "," )) + { + sc.MustGetString(); + check = sc.String; + } + } + } + + FOptionMenuItem* it = new FOptionMenuNumberField( label, cvar, + minimum, maximum, step, check ); + desc->mItems.Push( it ); + } + else + { + sc.ScriptError("Unknown keyword '%s'", sc.String); + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + +static void ParseOptionMenu(FScanner &sc) +{ + sc.MustGetString(); + + FOptionMenuDescriptor *desc = new FOptionMenuDescriptor; + desc->mType = MDESC_OptionsMenu; + desc->mMenuName = sc.String; + desc->mSelectedItem = -1; + desc->mScrollPos = 0; + desc->mClass = NULL; + desc->mPosition = DefaultOptionMenuSettings.mPosition; + desc->mScrollTop = DefaultOptionMenuSettings.mScrollTop; + desc->mIndent = DefaultOptionMenuSettings.mIndent; + desc->mDontDim = DefaultOptionMenuSettings.mDontDim; + + ParseOptionMenuBody(sc, desc); + bool scratch = ReplaceMenu(sc, desc); + if (desc->mIndent == 0) desc->CalcIndent(); + if (scratch) delete desc; +} + + +//============================================================================= +// +// +// +//============================================================================= + +void M_ParseMenuDefs() +{ + int lump, lastlump = 0; + + OptionSettings.mTitleColor = CR_RED;// V_FindFontColor(gameinfo.mTitleColor); + OptionSettings.mFontColor = CR_RED; // V_FindFontColor(gameinfo.mFontColor); + OptionSettings.mFontColorValue = CR_GRAY;// = V_FindFontColor(gameinfo.mFontColorValue); + OptionSettings.mFontColorMore = CR_GOLD;// = V_FindFontColor(gameinfo.mFontColorMore); + OptionSettings.mFontColorHeader = CR_YELLOW;// = V_FindFontColor(gameinfo.mFontColorHeader); + OptionSettings.mFontColorHighlight = CR_BRICK;// = V_FindFontColor(gameinfo.mFontColorHighlight); + OptionSettings.mFontColorSelection = CR_DARKRED;// = V_FindFontColor(gameinfo.mFontColorSelection); + DefaultListMenuSettings.Reset(); + DefaultOptionMenuSettings.Reset(); + + atexit(DeinitMenus); + DeinitMenus(); + while ((lump = fileSystem.Iterate("demolition/menudef.txt", &lastlump)) != -1) + { + FScanner sc(lump); + + sc.SetCMode(true); + while (sc.GetString()) + { + if (sc.Compare("LISTMENU")) + { + ParseListMenu(sc); + } + else if (sc.Compare("DEFAULTLISTMENU")) + { + ParseListMenuBody(sc, &DefaultListMenuSettings); + if (DefaultListMenuSettings.mItems.Size() > 0) + { + I_Error("You cannot add menu items to the menu default settings."); + } + } + else if (sc.Compare("OPTIONVALUE")) + { + ParseOptionValue(sc); + } + else if (sc.Compare("OPTIONSTRING")) + { + ParseOptionString(sc); + } + else if (sc.Compare("OPTIONMENUSETTINGS")) + { + ParseOptionSettings(sc); + } + else if (sc.Compare("OPTIONMENU")) + { + ParseOptionMenu(sc); + } + else if (sc.Compare("DEFAULTOPTIONMENU")) + { + ParseOptionMenuBody(sc, &DefaultOptionMenuSettings); + if (DefaultOptionMenuSettings.mItems.Size() > 0) + { + I_Error("You cannot add menu items to the menu default settings."); + } + } + else + { + sc.ScriptError("Unknown keyword '%s'", sc.String); + } + } + } +} + + +//============================================================================= +// +// Creates the episode menu +// Falls back on an option menu if there's not enough screen space to show all episodes +// +//============================================================================= + +static void BuildEpisodeMenu() +{ +#if 0 + // Build episode menu + bool success = false; + FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Episodemenu); + if (desc != NULL) + { + if ((*desc)->mType == MDESC_ListMenu) + { + FListMenuDescriptor *ld = static_cast(*desc); + int posy = ld->mYpos; + int topy = posy; + + // Get lowest y coordinate of any static item in the menu + for(unsigned i = 0; i < ld->mItems.Size(); i++) + { + int y = ld->mItems[i]->GetY(); + if (y < topy) topy = y; + } + + // center the menu on the screen if the top space is larger than the bottom space + int totalheight = posy + AllEpisodes.Size() * ld->mLinespacing - topy; + + if (totalheight < 190 || AllEpisodes.Size() == 1) + { + int newtop = (200 - totalheight + topy) / 2; + int topdelta = newtop - topy; + if (topdelta < 0) + { + for(unsigned i = 0; i < ld->mItems.Size(); i++) + { + ld->mItems[i]->OffsetPositionY(topdelta); + } + posy -= topdelta; + } + + ld->mSelectedItem = ld->mItems.Size(); + for(unsigned i = 0; i < AllEpisodes.Size(); i++) + { + FListMenuItem *it; + if (AllEpisodes[i].mPicName.IsNotEmpty()) + { + FTextureID tex = GetMenuTexture(AllEpisodes[i].mPicName); + it = new FListMenuItemPatch(ld->mXpos, posy, ld->mLinespacing, AllEpisodes[i].mShortcut, + tex, NAME_Skillmenu, i); + } + else + { + it = new FListMenuItemText(ld->mXpos, posy, ld->mLinespacing, AllEpisodes[i].mShortcut, + AllEpisodes[i].mEpisodeName, ld->mFont, ld->mFontColor, ld->mFontColor2, NAME_Skillmenu, i); + } + ld->mItems.Push(it); + posy += ld->mLinespacing; + } + if (AllEpisodes.Size() == 1) + { + ld->mAutoselect = ld->mSelectedItem; + } + success = true; + } + } + } + if (!success) + { + // Couldn't create the episode menu, either because there's too many episodes or some error occured + // Create an option menu for episode selection instead. + FOptionMenuDescriptor *od = new FOptionMenuDescriptor; + if (desc != NULL) delete *desc; + MenuDescriptors[NAME_Episodemenu] = od; + od->mType = MDESC_OptionsMenu; + od->mMenuName = NAME_Episodemenu; + od->mTitle = "$MNU_EPISODE"; + od->mSelectedItem = 0; + od->mScrollPos = 0; + od->mClass = NULL; + od->mPosition = -15; + od->mScrollTop = 0; + od->mIndent = 160; + od->mDontDim = false; + for(unsigned i = 0; i < AllEpisodes.Size(); i++) + { + FOptionMenuItemSubmenu *it = new FOptionMenuItemSubmenu(AllEpisodes[i].mEpisodeName, "Skillmenu", i); + od->mItems.Push(it); + } + } +#endif +} + +//============================================================================= +// +// Reads any XHAIRS lumps for the names of crosshairs and +// adds them to the display options menu. +// +//============================================================================= + +static void InitCrosshairsList() +{ +#if 0 + int lastlump, lump; + + lastlump = 0; + + FOptionValues **opt = OptionValues.CheckKey(NAME_Crosshairs); + if (opt == NULL) + { + return; // no crosshair value list present. No need to go on. + } + + FOptionValues::Pair *pair = &(*opt)->mValues[(*opt)->mValues.Reserve(1)]; + pair->Value = 0; + pair->Text = "None"; + + while ((lump = Wads.FindLump("XHAIRS", &lastlump)) != -1) + { + FScanner sc(lump); + while (sc.GetNumber()) + { + FOptionValues::Pair value; + value.Value = sc.Number; + sc.MustGetString(); + value.Text = sc.String; + if (value.Value != 0) + { // Check if it already exists. If not, add it. + unsigned int i; + + for (i = 1; i < (*opt)->mValues.Size(); ++i) + { + if ((*opt)->mValues[i].Value == value.Value) + { + break; + } + } + if (i < (*opt)->mValues.Size()) + { + (*opt)->mValues[i].Text = value.Text; + } + else + { + (*opt)->mValues.Push(value); + } + } + } + } +#endif +} + +//============================================================================= +// +// Special menus will be created once all engine data is loaded +// +//============================================================================= + +void M_CreateMenus() +{ + BuildEpisodeMenu(); + InitCrosshairsList(); + +#if 0 + FOptionValues **opt = OptionValues.CheckKey(NAME_Mididevices); + if (opt != NULL) + { + I_BuildMIDIMenuList(*opt); + } + opt = OptionValues.CheckKey(NAME_Aldevices); + if (opt != NULL) + { + I_BuildALDeviceList(*opt); + } +#endif +} + +//============================================================================= +// +// The skill menu must be refeshed each time it starts up +// +//============================================================================= +extern int restart; + +void M_StartupSkillMenu(FGameStartup *gs) +{ +#if 0 + static int done = -1; + bool success = false; + FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Skillmenu); + if (desc != NULL) + { + if ((*desc)->mType == MDESC_ListMenu) + { + FListMenuDescriptor *ld = static_cast(*desc); + int x = ld->mXpos; + int y = ld->mYpos; + + // Delete previous contents + for(unsigned i=0; imItems.Size(); i++) + { + FName n = ld->mItems[i]->GetAction(NULL); + if (n == NAME_Startgame || n == NAME_StartgameConfirm) + { + for(unsigned j=i; jmItems.Size(); j++) + { + delete ld->mItems[j]; + } + ld->mItems.Resize(i); + break; + } + } + + if (done != restart) + { + done = restart; + int defskill = DefaultSkill; + if ((unsigned int)defskill >= AllSkills.Size()) + { + defskill = (AllSkills.Size() - 1) / 2; + } + ld->mSelectedItem = ld->mItems.Size() + defskill; + + int posy = y; + int topy = posy; + + // Get lowest y coordinate of any static item in the menu + for(unsigned i = 0; i < ld->mItems.Size(); i++) + { + int y = ld->mItems[i]->GetY(); + if (y < topy) topy = y; + } + + // center the menu on the screen if the top space is larger than the bottom space + int totalheight = posy + AllSkills.Size() * ld->mLinespacing - topy; + + if (totalheight < 190 || AllSkills.Size() == 1) + { + int newtop = (200 - totalheight + topy) / 2; + int topdelta = newtop - topy; + if (topdelta < 0) + { + for(unsigned i = 0; i < ld->mItems.Size(); i++) + { + ld->mItems[i]->OffsetPositionY(topdelta); + } + y = ld->mYpos = posy - topdelta; + } + } + else + { + // too large + delete ld; + desc = NULL; + done = false; + goto fail; + } + } + + unsigned firstitem = ld->mItems.Size(); + for(unsigned int i = 0; i < AllSkills.Size(); i++) + { + FSkillInfo &skill = AllSkills[i]; + FListMenuItem *li; + // Using a different name for skills that must be confirmed makes handling this easier. + FName action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? + NAME_StartgameConfirm : NAME_Startgame; + FString *pItemText = NULL; + if (gs->PlayerClass != NULL) + { + pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); + } + + if (skill.PicName.Len() != 0 && pItemText == NULL) + { + FTextureID tex = GetMenuTexture(skill.PicName); + li = new FListMenuItemPatch(ld->mXpos, y, ld->mLinespacing, skill.Shortcut, tex, action, i); + } + else + { + EColorRange color = (EColorRange)skill.GetTextColor(); + if (color == CR_UNTRANSLATED) color = ld->mFontColor; + li = new FListMenuItemText(x, y, ld->mLinespacing, skill.Shortcut, + pItemText? *pItemText : skill.MenuName, ld->mFont, color,ld->mFontColor2, action, i); + } + ld->mItems.Push(li); + y += ld->mLinespacing; + } + if (AllEpisodes[gs->Episode].mNoSkill || AllSkills.Size() == 1) + { + ld->mAutoselect = firstitem + M_GetDefaultSkill(); + } + else + { + ld->mAutoselect = -1; + } + success = true; + } + } + if (success) return; +fail: + // Option menu fallback for overlong skill lists + FOptionMenuDescriptor *od; + if (desc == NULL) + { + od = new FOptionMenuDescriptor; + if (desc != NULL) delete *desc; + MenuDescriptors[NAME_Skillmenu] = od; + od->mType = MDESC_OptionsMenu; + od->mMenuName = NAME_Skillmenu; + od->mTitle = "$MNU_CHOOSESKILL"; + od->mSelectedItem = 0; + od->mScrollPos = 0; + od->mClass = NULL; + od->mPosition = -15; + od->mScrollTop = 0; + od->mIndent = 160; + od->mDontDim = false; + } + else + { + od = static_cast(*desc); + for(unsigned i=0;imItems.Size(); i++) + { + delete od->mItems[i]; + } + od->mItems.Clear(); + } + for(unsigned int i = 0; i < AllSkills.Size(); i++) + { + FSkillInfo &skill = AllSkills[i]; + FOptionMenuItem *li; + // Using a different name for skills that must be confirmed makes handling this easier. + const char *action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? + "StartgameConfirm" : "Startgame"; + + FString *pItemText = NULL; + if (gs->PlayerClass != NULL) + { + pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); + } + li = new FOptionMenuItemSubmenu(pItemText? *pItemText : skill.MenuName, action, i); + od->mItems.Push(li); + if (!done) + { + done = true; + od->mSelectedItem = M_GetDefaultSkill(); + } + } +#endif +} + +//============================================================================= +// +// Returns the default skill level. +// +//============================================================================= + +int M_GetDefaultSkill() +{ +#if 0 + int defskill = DefaultSkill; + if ((unsigned int)defskill >= AllSkills.Size()) + { + defskill = (AllSkills.Size() - 1) / 2; + } + return defskill; +#else + return 1; +#endif +} diff --git a/source/common/menu/menuinput.cpp b/source/common/menu/menuinput.cpp new file mode 100644 index 000000000..b355b905b --- /dev/null +++ b/source/common/menu/menuinput.cpp @@ -0,0 +1,367 @@ +/* +** menuinput.cpp +** The string input code +** +**--------------------------------------------------------------------------- +** Copyright 2001-2010 Randy Heit +** Copyright 2010 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "menu/menu.h" +#include "c_cvars.h" +#include "d_event.h" +#include "d_gui.h" +#include "v_font.h" +#include "v_text.h" +#include "v_draw.h" + +IMPLEMENT_ABSTRACT_CLASS(DTextEnterMenu) + +#define INPUTGRID_WIDTH 13 +#define INPUTGRID_HEIGHT 5 + +// Heretic and Hexen do not, by default, come with glyphs for all of these +// characters. Oh well. Doom and Strife do. +static const char InputGridChars[INPUTGRID_WIDTH * INPUTGRID_HEIGHT] = + "ABCDEFGHIJKLM" + "NOPQRSTUVWXYZ" + "0123456789+-=" + ".,!?@'\":;[]()" + "<>^#$%&*/_ \b"; + + +CVAR(Bool, m_showinputgrid, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + +//============================================================================= +// +// +// +//============================================================================= + +// [TP] Added allowcolors +DTextEnterMenu::DTextEnterMenu(DMenu *parent, FString &textbuffer, int sizemode, bool showgrid, bool allowcolors) +: DMenu(parent) +{ + mOutString = &textbuffer; + mEnterSize = 32; // this needs to calculate the size based on screen space (or scroll) + mEnterString.Resize(mEnterSize + 1); + mEnterPos = (unsigned)textbuffer.Len(); + mSizeMode = sizemode; + mInputGridOkay = showgrid || m_showinputgrid; + if (mEnterPos > 0) + { + InputGridX = INPUTGRID_WIDTH - 1; + InputGridY = INPUTGRID_HEIGHT - 1; + } + else + { + // If we are naming a new save, don't start the cursor on "end". + InputGridX = 0; + InputGridY = 0; + } + AllowColors = allowcolors; // [TP] +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DTextEnterMenu::TranslateKeyboardEvents() +{ + return mInputGridOkay; +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DTextEnterMenu::Responder(event_t *ev) +{ + if (ev->type == EV_GUI_Event) + { + // Save game and player name string input + if (ev->subtype == EV_GUI_Char) + { + mInputGridOkay = false; + if (mEnterPos < mEnterSize && + (mSizeMode == 2/*entering player name*/ || (size_t)SmallFont->StringWidth(mEnterString) < (mEnterSize-1)*8)) + { + mEnterString[mEnterPos] = (char)ev->data1; + mEnterString[++mEnterPos] = 0; + } + return true; + } + char ch = (char)ev->data1; + if ((ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_KeyRepeat) && ch == '\b') + { + if (mEnterPos > 0) + { + mEnterPos--; + mEnterString[mEnterPos] = 0; + } + } + else if (ev->subtype == EV_GUI_KeyDown) + { + if (ch == GK_ESCAPE) + { + DMenu *parent = mParentMenu; + Close(); + parent->MenuEvent(MKEY_Abort, false); + return true; + } + else if (ch == '\r') + { + if (mEnterString[0]) + { + DMenu *parent = mParentMenu; + Close(); + parent->MenuEvent(MKEY_Input, false); + return true; + } + } + } + if (ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_KeyRepeat) + { + return true; + } + } + return Super::Responder(ev); +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DTextEnterMenu::MouseEvent(int type, int x, int y) +{ + const int cell_width = 18 * CleanXfac; + const int cell_height = 12 * CleanYfac; + const int screen_y = screen->GetHeight() - INPUTGRID_HEIGHT * cell_height; + const int screen_x = (screen->GetWidth() - INPUTGRID_WIDTH * cell_width) / 2; + + if (x >= screen_x && x < screen_x + INPUTGRID_WIDTH * cell_width && y >= screen_y) + { + InputGridX = (x - screen_x) / cell_width; + InputGridY = (y - screen_y) / cell_height; + if (type == DMenu::MOUSE_Release) + { + if (MenuEvent(MKEY_Enter, true)) + { + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); + if (m_use_mouse == 2) InputGridX = InputGridY = -1; + return true; + } + } + } + else + { + InputGridX = InputGridY = -1; + } + return Super::MouseEvent(type, x, y); +} + + + +//============================================================================= +// +// +// +//============================================================================= + +bool DTextEnterMenu::MenuEvent (int key, bool fromcontroller) +{ + if (key == MKEY_Back) + { + mParentMenu->MenuEvent(MKEY_Abort, false); + return Super::MenuEvent(key, fromcontroller); + } + if (fromcontroller) + { + mInputGridOkay = true; + } + + if (mInputGridOkay) + { + int ch; + + if (InputGridX == -1 || InputGridY == -1) + { + InputGridX = InputGridY = 0; + } + switch (key) + { + case MKEY_Down: + InputGridY = (InputGridY + 1) % INPUTGRID_HEIGHT; + return true; + + case MKEY_Up: + InputGridY = (InputGridY + INPUTGRID_HEIGHT - 1) % INPUTGRID_HEIGHT; + return true; + + case MKEY_Right: + InputGridX = (InputGridX + 1) % INPUTGRID_WIDTH; + return true; + + case MKEY_Left: + InputGridX = (InputGridX + INPUTGRID_WIDTH - 1) % INPUTGRID_WIDTH; + return true; + + case MKEY_Clear: + if (mEnterPos > 0) + { + mEnterString[--mEnterPos] = 0; + } + return true; + + case MKEY_Enter: + assert(unsigned(InputGridX) < INPUTGRID_WIDTH && unsigned(InputGridY) < INPUTGRID_HEIGHT); + if (mInputGridOkay) + { + ch = InputGridChars[InputGridX + InputGridY * INPUTGRID_WIDTH]; + if (ch == 0) // end + { + if (mEnterString[0] != '\0') + { + DMenu *parent = mParentMenu; + Close(); + parent->MenuEvent(MKEY_Input, false); + return true; + } + } + else if (ch == '\b') // bs + { + if (mEnterPos > 0) + { + mEnterString[--mEnterPos] = 0; + } + } + else if (mEnterPos < mEnterSize && + (mSizeMode == 2/*entering player name*/ || (size_t)SmallFont->StringWidth(mEnterString) < (mEnterSize-1)*8)) + { + mEnterString[mEnterPos] = ch; + mEnterString[++mEnterPos] = 0; + } + } + return true; + + default: + break; // Keep GCC quiet + } + } + return false; +} + +//============================================================================= +// +// +// +//============================================================================= + +void DTextEnterMenu::Drawer () +{ + mParentMenu->Drawer(); + if (mInputGridOkay) + { + const int cell_width = 18 * CleanXfac; + const int cell_height = 12 * CleanYfac; + const int top_padding = cell_height / 2 - SmallFont->GetHeight() * CleanYfac / 2; + + // Darken the background behind the character grid. + // Unless we frame it with a border, I think it looks better to extend the + // background across the full width of the screen. + twod.AddColorOnlyQuad(0 /*screen->GetWidth()/2 - 13 * cell_width / 2*/, + screen->GetHeight() - INPUTGRID_HEIGHT * cell_height, + screen->GetWidth() /*13 * cell_width*/, + INPUTGRID_HEIGHT * cell_height, 0xff000000); + + if (InputGridX >= 0 && InputGridY >= 0) + { + // Highlight the background behind the selected character. + twod.AddColorOnlyQuad( + InputGridX * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen->GetWidth() / 2, + InputGridY * cell_height - INPUTGRID_HEIGHT * cell_height + screen->GetHeight(), + cell_width, cell_height, PalEntry(255, 255, 248, 220)); + } + + for (int y = 0; y < INPUTGRID_HEIGHT; ++y) + { + const int yy = y * cell_height - INPUTGRID_HEIGHT * cell_height + screen->GetHeight(); + for (int x = 0; x < INPUTGRID_WIDTH; ++x) + { + int width; + const int xx = x * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen->GetWidth() / 2; + const int ch = InputGridChars[y * INPUTGRID_WIDTH + x]; + FTexture *pic = SmallFont->GetChar(ch, CR_DARKGRAY, &width); + EColorRange color; + int remap; + + // The highlighted character is yellow; the rest are dark gray. + color = (x == InputGridX && y == InputGridY) ? CR_YELLOW : CR_DARKGRAY; + remap = SmallFont->GetColorTranslation(color); + + if (pic != NULL) + { + // Draw a normal character. + DrawTexture(&twod, pic, xx + cell_width/2 - width*CleanXfac/2, yy + top_padding, + DTA_TranslationIndex, remap, + DTA_CleanNoMove, true, + TAG_DONE); + } + else if (ch == ' ') + { + // Draw the space as a box outline. We also draw it 50% wider than it really is. + const int x1 = xx + cell_width/2 - width * CleanXfac * 3 / 4; + const int x2 = x1 + width * 3 * CleanXfac / 2; + const int y1 = yy + top_padding; + const int y2 = y1 + SmallFont->GetHeight() * CleanYfac; + auto palcolor = PalEntry(255, 160, 160, 160); + twod.AddColorOnlyQuad(x1, y1, x2, y1+CleanYfac, palcolor); // top + twod.AddColorOnlyQuad(x1, y2, x2, y2+CleanYfac, palcolor); // bottom + twod.AddColorOnlyQuad(x1, y1+CleanYfac, x1+CleanXfac, y2, palcolor); // left + twod.AddColorOnlyQuad(x2-CleanXfac, y1+CleanYfac, x2, y2, palcolor); // right + } + else if (ch == '\b' || ch == 0) + { + // Draw the backspace and end "characters". + const char *const str = ch == '\b' ? "BS" : "ED"; + DrawText(&twod, SmallFont, color, + xx + cell_width/2 - SmallFont->StringWidth(str)*CleanXfac/2, + yy + top_padding, str, DTA_CleanNoMove, true, TAG_DONE); + } + } + } + } + Super::Drawer(); +} \ No newline at end of file diff --git a/source/common/menu/messagebox.cpp b/source/common/menu/messagebox.cpp new file mode 100644 index 000000000..f568553f5 --- /dev/null +++ b/source/common/menu/messagebox.cpp @@ -0,0 +1,361 @@ +/* +** messagebox.cpp +** Confirmation, notification screns +** +**--------------------------------------------------------------------------- +** Copyright 2010 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "menu/menu.h" +#include "d_event.h" +#include "d_gui.h" +#include "v_text.h" +#include "v_draw.h" +#include "gstrings.h" +#include "c_dispatch.h" +#include "v_2ddrawer.h" + + +extern FSaveGameNode *quickSaveSlot; + +class DMessageBoxMenu : public DMenu +{ + DECLARE_CLASS(DMessageBoxMenu, DMenu) + + TArray mMessage; + int mMessageMode; + int messageSelection; + int mMouseLeft, mMouseRight, mMouseY; + FName mAction; + +public: + + DMessageBoxMenu(DMenu *parent = NULL, const char *message = NULL, int messagemode = 0, bool playsound = false, FName action = NAME_None); + void Destroy(); + void Init(DMenu *parent, const char *message, int messagemode, bool playsound = false); + void Drawer(); + bool Responder(event_t *ev); + bool MenuEvent(int mkey, bool fromcontroller); + bool MouseEvent(int type, int x, int y); + void CloseSound(); + virtual void HandleResult(bool res); +}; + +IMPLEMENT_CLASS(DMessageBoxMenu) + +//============================================================================= +// +// +// +//============================================================================= + +DMessageBoxMenu::DMessageBoxMenu(DMenu *parent, const char *message, int messagemode, bool playsound, FName action) +: DMenu(parent) +{ + mAction = action; + messageSelection = 0; + mMouseLeft = 140; + mMouseY = INT_MIN; + int mr1 = 170 + SmallFont->StringWidth(GStrings["TXT_YES"]); + int mr2 = 170 + SmallFont->StringWidth(GStrings["TXT_NO"]); + mMouseRight = std::max(mr1, mr2); + + Init(parent, message, messagemode, playsound); +} + +//============================================================================= +// +// +// +//============================================================================= + +void DMessageBoxMenu::Init(DMenu *parent, const char *message, int messagemode, bool playsound) +{ + mParentMenu = parent; + if (message != NULL) + { + if (*message == '$') message = GStrings(message+1); + mMessage = V_BreakLines(SmallFont, 300, message); + } + mMessageMode = messagemode; + if (playsound) + { + //S_StopSound (CHAN_VOICE); + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/prompt", snd_menuvolume, ATTN_NONE); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +void DMessageBoxMenu::Destroy() +{ + mMessage.Reset(); +} + +//============================================================================= +// +// +// +//============================================================================= + +void DMessageBoxMenu::CloseSound() +{ + //S_Sound (CHAN_VOICE | CHAN_UI, DMenu::CurrentMenu != NULL? "menu/backup" : "menu/dismiss", snd_menuvolume, ATTN_NONE); +} + +//============================================================================= +// +// +// +//============================================================================= + +void DMessageBoxMenu::HandleResult(bool res) +{ + if (mParentMenu != NULL) + { + if (mMessageMode == 0) + { + if (mAction == NAME_None) + { + mParentMenu->MenuEvent(res? MKEY_MBYes : MKEY_MBNo, false); + Close(); + } + else + { + Close(); + if (res) M_SetMenu(mAction, -1); + } + CloseSound(); + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + +void DMessageBoxMenu::Drawer () +{ + int y; + PalEntry fade = 0; + + int fontheight = SmallFont->GetHeight(); + //V_SetBorderNeedRefresh(); + //ST_SetNeedRefresh(); + + y = 100; + + if (mMessage.Size()) + { + for (unsigned i = 0; i < mMessage.Size(); i++) + y -= SmallFont->GetHeight () / 2; + + for (unsigned i = 0; i < mMessage.Size(); i++) + { + DrawText(&twod, SmallFont, CR_UNTRANSLATED, 160 - mMessage[i].Width/2, y, mMessage[i].Text, + DTA_Clean, true, TAG_DONE); + y += fontheight; + } + } + + if (mMessageMode == 0) + { + y += fontheight; + mMouseY = y; + DrawText(&twod, SmallFont, + messageSelection == 0? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, + 160, y, GStrings["TXT_YES"], DTA_Clean, true, TAG_DONE); + DrawText(&twod, SmallFont, + messageSelection == 1? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, + 160, y + fontheight + 1, GStrings["TXT_NO"], DTA_Clean, true, TAG_DONE); + + if (messageSelection >= 0) + { + if ((DMenu::MenuTime%8) < 6) + { + DrawText(&twod, ConFont, OptionSettings.mFontColorSelection, + (150 - 160) * CleanXfac + screen->GetWidth() / 2, + (y + (fontheight + 1) * messageSelection - 100 + fontheight/2 - 5) * CleanYfac + screen->GetHeight() / 2, + "\xd", + DTA_CellX, 8 * CleanXfac, + DTA_CellY, 8 * CleanYfac, + TAG_DONE); + } + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DMessageBoxMenu::Responder(event_t *ev) +{ + if (ev->type == EV_GUI_Event && ev->subtype == EV_GUI_KeyDown) + { + if (mMessageMode == 0) + { + int ch = tolower(ev->data1); + if (ch == 'n' || ch == ' ') + { + HandleResult(false); + return true; + } + else if (ch == 'y') + { + HandleResult(true); + return true; + } + } + else + { + Close(); + return true; + } + return false; + } + else if (ev->type == EV_KeyDown) + { + Close(); + return true; + } + return Super::Responder(ev); +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DMessageBoxMenu::MenuEvent(int mkey, bool fromcontroller) +{ + if (mMessageMode == 0) + { + if (mkey == MKEY_Up || mkey == MKEY_Down) + { + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + messageSelection = !messageSelection; + return true; + } + else if (mkey == MKEY_Enter) + { + // 0 is yes, 1 is no + HandleResult(!messageSelection); + return true; + } + else if (mkey == MKEY_Back) + { + HandleResult(false); + return true; + } + return false; + } + else + { + Close(); + CloseSound(); + return true; + } +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DMessageBoxMenu::MouseEvent(int type, int x, int y) +{ + if (mMessageMode == 1) + { + if (type == MOUSE_Click) + { + return MenuEvent(MKEY_Enter, true); + } + return false; + } + else + { + int sel = -1; + int fh = SmallFont->GetHeight() + 1; + + // convert x/y from screen to virtual coordinates, according to CleanX/Yfac use in DrawTexture + x = ((x - (screen->GetWidth() / 2)) / CleanXfac) + 160; + y = ((y - (screen->GetHeight() / 2)) / CleanYfac) + 100; + + if (x >= mMouseLeft && x <= mMouseRight && y >= mMouseY && y < mMouseY + 2 * fh) + { + sel = y >= mMouseY + fh; + } + if (sel != -1 && sel != messageSelection) + { + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + } + messageSelection = sel; + if (type == MOUSE_Release) + { + return MenuEvent(MKEY_Enter, true); + } + return true; + } +} + +//============================================================================= +// +// +// +//============================================================================= + +//============================================================================= +// +// +// +//============================================================================= + +void M_StartMessage(const char *message, int messagemode, FName action) +{ + if (DMenu::CurrentMenu == NULL) + { + // only play a sound if no menu was active before + M_StartControlPanel(menuactive == MENU_Off); + } + DMenu *newmenu = new DMessageBoxMenu(DMenu::CurrentMenu, message, messagemode, false, action); + newmenu->mParentMenu = DMenu::CurrentMenu; + M_ActivateMenu(newmenu); +} + diff --git a/source/common/menu/optionmenu.cpp b/source/common/menu/optionmenu.cpp new file mode 100644 index 000000000..bbe1d278f --- /dev/null +++ b/source/common/menu/optionmenu.cpp @@ -0,0 +1,553 @@ +/* +** optionmenu.cpp +** Handler class for the option menus and associated items +** +**--------------------------------------------------------------------------- +** Copyright 2010 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "v_font.h" +#include "cmdlib.h" +#include "gstrings.h" +#include "d_gui.h" +#include "d_event.h" +#include "c_dispatch.h" +#include "c_console.h" +#include "c_cvars.h" +#include "c_bind.h" +#include "gameconfigfile.h" +#include "menu/menu.h" +#include "v_draw.h" +#include "v_2ddrawer.h" + +//============================================================================= +// +// Draws a string in the console font, scaled to the 8x8 cells +// used by the default console font. +// +//============================================================================= + +void M_DrawConText (int color, int x, int y, const char *str) +{ + DrawText (&twod, ConFont, color, x, y, str, + DTA_CellX, 8 * CleanXfac_1, + DTA_CellY, 8 * CleanYfac_1, + TAG_DONE); +} + + +IMPLEMENT_CLASS(DOptionMenu) + +//============================================================================= +// +// +// +//============================================================================= + +DOptionMenu::DOptionMenu(DMenu *parent, FOptionMenuDescriptor *desc) +: DMenu(parent) +{ + CanScrollUp = false; + CanScrollDown = false; + VisBottom = 0; + mFocusControl = NULL; + Init(parent, desc); +} + +//============================================================================= +// +// +// +//============================================================================= + +void DOptionMenu::Init(DMenu *parent, FOptionMenuDescriptor *desc) +{ + mParentMenu = parent; + mDesc = desc; + if (mDesc != NULL && mDesc->mSelectedItem == -1) mDesc->mSelectedItem = FirstSelectable(); + +} + +//============================================================================= +// +// +// +//============================================================================= + +int DOptionMenu::FirstSelectable() +{ + if (mDesc != NULL) + { + // Go down to the first selectable item + int i = -1; + do + { + i++; + } + while (i < (int)mDesc->mItems.Size() && !mDesc->mItems[i]->Selectable()); + if (i>=0 && i < (int)mDesc->mItems.Size()) return i; + } + return -1; +} + +//============================================================================= +// +// +// +//============================================================================= + +FOptionMenuItem *DOptionMenu::GetItem(FName name) +{ + for(unsigned i=0;imItems.Size(); i++) + { + FName nm = mDesc->mItems[i]->GetAction(NULL); + if (nm == name) return mDesc->mItems[i]; + } + return NULL; +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DOptionMenu::Responder (event_t *ev) +{ + if (ev->type == EV_GUI_Event) + { + if (ev->subtype == EV_GUI_WheelUp) + { + int scrollamt = std::min(2, mDesc->mScrollPos); + mDesc->mScrollPos -= scrollamt; + return true; + } + else if (ev->subtype == EV_GUI_WheelDown) + { + if (CanScrollDown) + { + if (VisBottom < (int)(mDesc->mItems.Size()-2)) + { + mDesc->mScrollPos += 2; + VisBottom += 2; + } + else + { + mDesc->mScrollPos++; + VisBottom++; + } + } + return true; + } + } + return Super::Responder(ev); +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DOptionMenu::MenuEvent (int mkey, bool fromcontroller) +{ + int startedAt = mDesc->mSelectedItem; + + switch (mkey) + { + case MKEY_Up: + if (mDesc->mSelectedItem == -1) + { + mDesc->mSelectedItem = FirstSelectable(); + break; + } + do + { + --mDesc->mSelectedItem; + + if (mDesc->mScrollPos > 0 && + mDesc->mSelectedItem <= mDesc->mScrollTop + mDesc->mScrollPos) + { + mDesc->mScrollPos = std::max(mDesc->mSelectedItem - mDesc->mScrollTop - 1, 0); + } + + if (mDesc->mSelectedItem < 0) + { + // Figure out how many lines of text fit on the menu + int y = mDesc->mPosition; + + if (y <= 0) + { + if (BigFont && mDesc->mTitle.IsNotEmpty()) + { + y = -y + BigFont->GetHeight(); + } + else + { + y = -y; + } + } + y *= CleanYfac_1; + int rowheight = OptionSettings.mLinespacing * CleanYfac_1; + int maxitems = (screen->GetHeight() - rowheight - y) / rowheight + 1; + + mDesc->mScrollPos = std::max(0, (int)mDesc->mItems.Size() - maxitems + mDesc->mScrollTop); + mDesc->mSelectedItem = mDesc->mItems.Size()-1; + } + } + while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); + break; + + case MKEY_Down: + if (mDesc->mSelectedItem == -1) + { + mDesc->mSelectedItem = FirstSelectable(); + break; + } + do + { + ++mDesc->mSelectedItem; + + if (CanScrollDown && mDesc->mSelectedItem == VisBottom) + { + mDesc->mScrollPos++; + VisBottom++; + } + if (mDesc->mSelectedItem >= (int)mDesc->mItems.Size()) + { + if (startedAt == -1) + { + mDesc->mSelectedItem = -1; + mDesc->mScrollPos = -1; + break; + } + else + { + mDesc->mSelectedItem = 0; + mDesc->mScrollPos = 0; + } + } + } + while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); + break; + + case MKEY_PageUp: + if (mDesc->mScrollPos > 0) + { + mDesc->mScrollPos -= VisBottom - mDesc->mScrollPos - mDesc->mScrollTop; + if (mDesc->mScrollPos < 0) + { + mDesc->mScrollPos = 0; + } + if (mDesc->mSelectedItem != -1) + { + mDesc->mSelectedItem = mDesc->mScrollTop + mDesc->mScrollPos + 1; + while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable()) + { + if (++mDesc->mSelectedItem >= (int)mDesc->mItems.Size()) + { + mDesc->mSelectedItem = 0; + } + } + if (mDesc->mScrollPos > mDesc->mSelectedItem) + { + mDesc->mScrollPos = mDesc->mSelectedItem; + } + } + } + break; + + case MKEY_PageDown: + if (CanScrollDown) + { + int pagesize = VisBottom - mDesc->mScrollPos - mDesc->mScrollTop; + mDesc->mScrollPos += pagesize; + if (mDesc->mScrollPos + mDesc->mScrollTop + pagesize > (int)mDesc->mItems.Size()) + { + mDesc->mScrollPos = mDesc->mItems.Size() - mDesc->mScrollTop - pagesize; + } + if (mDesc->mSelectedItem != -1) + { + mDesc->mSelectedItem = mDesc->mScrollTop + mDesc->mScrollPos; + while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable()) + { + if (++mDesc->mSelectedItem >= (int)mDesc->mItems.Size()) + { + mDesc->mSelectedItem = 0; + } + } + if (mDesc->mScrollPos > mDesc->mSelectedItem) + { + mDesc->mScrollPos = mDesc->mSelectedItem; + } + } + } + break; + + case MKEY_Enter: + if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate()) + { + return true; + } + // fall through to default + default: + if (mDesc->mSelectedItem >= 0 && + mDesc->mItems[mDesc->mSelectedItem]->MenuEvent(mkey, fromcontroller)) return true; + return Super::MenuEvent(mkey, fromcontroller); + } + + if (mDesc->mSelectedItem != startedAt) + { + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + } + return true; +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DOptionMenu::MouseEvent(int type, int x, int y) +{ + y = (y / CleanYfac_1) - mDesc->mDrawTop; + + if (mFocusControl) + { + mFocusControl->MouseEvent(type, x, y); + return true; + } + else + { + int yline = (y / OptionSettings.mLinespacing); + if (yline >= mDesc->mScrollTop) + { + yline += mDesc->mScrollPos; + } + if ((unsigned)yline < mDesc->mItems.Size() && mDesc->mItems[yline]->Selectable()) + { + if (yline != mDesc->mSelectedItem) + { + mDesc->mSelectedItem = yline; + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + } + mDesc->mItems[yline]->MouseEvent(type, x, y); + return true; + } + } + mDesc->mSelectedItem = -1; + return Super::MouseEvent(type, x, y); +} + +//============================================================================= +// +// +// +//============================================================================= + +void DOptionMenu::Ticker () +{ + Super::Ticker(); + for(unsigned i=0;imItems.Size(); i++) + { + mDesc->mItems[i]->Ticker(); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +void DOptionMenu::Drawer () +{ + int y = mDesc->mPosition; + + if (y <= 0) + { + if (BigFont && mDesc->mTitle.IsNotEmpty()) + { + const char *tt = mDesc->mTitle; + if (*tt == '$') tt = GStrings(tt+1); + DrawText (&twod, BigFont, OptionSettings.mTitleColor, + (screen->GetWidth() - BigFont->StringWidth(tt) * CleanXfac_1) / 2, 10*CleanYfac_1, + tt, DTA_CleanNoMove_1, true, TAG_DONE); + y = -y + BigFont->GetHeight(); + } + else + { + y = -y; + } + } + mDesc->mDrawTop = y; + int fontheight = OptionSettings.mLinespacing * CleanYfac_1; + y *= CleanYfac_1; + + int indent = mDesc->mIndent; + if (indent > 280) + { // kludge for the compatibility options with their extremely long labels + if (indent + 40 <= CleanWidth_1) + { + indent = (screen->GetWidth() - ((indent + 40) * CleanXfac_1)) / 2 + indent * CleanXfac_1; + } + else + { + indent = screen->GetWidth() - 40 * CleanXfac_1; + } + } + else + { + indent = (indent - 160) * CleanXfac_1 + screen->GetWidth() / 2; + } + + int ytop = y + mDesc->mScrollTop * 8 * CleanYfac_1; + int lastrow = screen->GetHeight() - SmallFont->GetHeight() * CleanYfac_1; + + unsigned i; + for (i = 0; i < mDesc->mItems.Size() && y <= lastrow; i++, y += fontheight) + { + // Don't scroll the uppermost items + if ((int)i == mDesc->mScrollTop) + { + i += mDesc->mScrollPos; + if (i >= mDesc->mItems.Size()) break; // skipped beyond end of menu + } + bool isSelected = mDesc->mSelectedItem == (int)i; + int cur_indent = mDesc->mItems[i]->Draw(mDesc, y, indent, isSelected); + if (cur_indent >= 0 && isSelected && mDesc->mItems[i]->Selectable()) + { + if (((DMenu::MenuTime%8) < 6) || DMenu::CurrentMenu != this) + { + M_DrawConText(OptionSettings.mFontColorSelection, cur_indent + 3 * CleanXfac_1, y+fontheight-9*CleanYfac_1, "\xd"); + } + } + } + + CanScrollUp = (mDesc->mScrollPos > 0); + CanScrollDown = (i < mDesc->mItems.Size()); + VisBottom = i - 1; + + if (CanScrollUp) + { + M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, ytop, "\x1a"); + } + if (CanScrollDown) + { + M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, y - 8*CleanYfac_1, "\x1b"); + } + Super::Drawer(); +} + + +//============================================================================= +// +// base class for menu items +// +//============================================================================= + +FOptionMenuItem::~FOptionMenuItem() +{ +} + +int FOptionMenuItem::Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) +{ + return indent; +} + +bool FOptionMenuItem::Selectable() +{ + return true; +} + +bool FOptionMenuItem::MouseEvent(int type, int x, int y) +{ + if (Selectable() && type == DMenu::MOUSE_Release) + { + return DMenu::CurrentMenu->MenuEvent(MKEY_Enter, true); + } + return false; +} + +int FOptionMenuItem::GetIndent() +{ + if (mCentered) + { + return 0; + } + const char *label = mLabel; + if (*label == '$') label = GStrings(label+1); + return SmallFont->StringWidth(label); +} + +void FOptionMenuItem::drawLabel(int indent, int y, EColorRange color, bool grayed) +{ + const char *label = mLabel; + if (*label == '$') label = GStrings(label+1); + + int overlay = grayed? MAKEARGB(96,48,0,0) : 0; + + int x; + int w = SmallFont->StringWidth(label) * CleanXfac_1; + if (!mCentered) x = indent - w; + else x = (screen->GetWidth() - w) / 2; + DrawText (&twod, SmallFont, color, x, y, label, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE); +} + + + +void FOptionMenuDescriptor::CalcIndent() +{ + // calculate the menu indent + int widest = 0, thiswidth; + + for (unsigned i = 0; i < mItems.Size(); i++) + { + thiswidth = mItems[i]->GetIndent(); + if (thiswidth > widest) widest = thiswidth; + } + mIndent = widest + 4; +} + +//============================================================================= +// +// +// +//============================================================================= + +FOptionMenuItem *FOptionMenuDescriptor::GetItem(FName name) +{ + for(unsigned i=0;iGetAction(NULL); + if (nm == name) return mItems[i]; + } + return NULL; +} diff --git a/source/common/menu/optionmenuitems.h b/source/common/menu/optionmenuitems.h new file mode 100644 index 000000000..bc0b443fb --- /dev/null +++ b/source/common/menu/optionmenuitems.h @@ -0,0 +1,961 @@ +/* +** optionmenuitems.h +** Control items for option menus +** +**--------------------------------------------------------------------------- +** Copyright 2010 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ +#include "v_text.h" +#include "v_draw.h" +#include "gstrings.h" + + +void M_DrawConText (int color, int x, int y, const char *str); +void M_SetVideoMode(); + + + +//============================================================================= +// +// opens a submenu, action is a submenu name +// +//============================================================================= + +class FOptionMenuItemSubmenu : public FOptionMenuItem +{ + int mParam; +public: + FOptionMenuItemSubmenu(const char *label, const char *menu, int param = 0) + : FOptionMenuItem(label, menu) + { + mParam = param; + } + + int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + { + drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColorMore); + return indent; + } + + bool Activate() + { + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); + M_SetMenu(mAction, mParam); + return true; + } +}; + + +//============================================================================= +// +// Executes a CCMD, action is a CCMD name +// +//============================================================================= + +class FOptionMenuItemCommand : public FOptionMenuItemSubmenu +{ +public: + FOptionMenuItemCommand(const char *label, const char *menu) + : FOptionMenuItemSubmenu(label, menu) + { + } + + bool Activate() + { + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); + C_DoCommand(mAction); + return true; + } + +}; + +//============================================================================= +// +// Executes a CCMD after confirmation, action is a CCMD name +// +//============================================================================= + +class FOptionMenuItemSafeCommand : public FOptionMenuItemCommand +{ + // action is a CCMD +public: + FOptionMenuItemSafeCommand(const char *label, const char *menu) + : FOptionMenuItemCommand(label, menu) + { + } + + bool MenuEvent (int mkey, bool fromcontroller) + { + if (mkey == MKEY_MBYes) + { + C_DoCommand(mAction); + return true; + } + return FOptionMenuItemCommand::MenuEvent(mkey, fromcontroller); + } + + bool Activate() + { + M_StartMessage("Do you really want to do this?", 0); + return true; + } +}; + +//============================================================================= +// +// Base class for option lists +// +//============================================================================= + +class FOptionMenuItemOptionBase : public FOptionMenuItem +{ +protected: + // action is a CVAR + FName mValues; // Entry in OptionValues table + FBaseCVar *mGrayCheck; + int mCenter; +public: + + enum + { + OP_VALUES = 0x11001 + }; + + FOptionMenuItemOptionBase(const char *label, const char *menu, const char *values, const char *graycheck, int center) + : FOptionMenuItem(label, menu) + { + mValues = values; + mGrayCheck = (FBoolCVar*)FindCVar(graycheck, NULL); + mCenter = center; + } + + bool SetString(int i, const char *newtext) + { + if (i == OP_VALUES) + { + FOptionValues **opt = OptionValues.CheckKey(newtext); + mValues = newtext; + if (opt != NULL && *opt != NULL) + { + int s = GetSelection(); + if (s >= (int)(*opt)->mValues.Size()) s = 0; + SetSelection(s); // readjust the CVAR if its value is outside the range now + return true; + } + } + return false; + } + + + + //============================================================================= + virtual int GetSelection() = 0; + virtual void SetSelection(int Selection) = 0; + + //============================================================================= + int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + { + bool grayed = mGrayCheck != NULL && !(mGrayCheck->GetGenericRep(CVAR_Bool).Bool); + + if (mCenter) + { + indent = (screen->GetWidth() / 2); + } + drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed); + + int overlay = grayed? MAKEARGB(96,48,0,0) : 0; + const char *text; + int Selection = GetSelection(); + FOptionValues **opt = OptionValues.CheckKey(mValues); + if (Selection < 0 || opt == NULL || *opt == NULL) + { + text = "Unknown"; + } + else + { + text = (*opt)->mValues[Selection].Text; + } + if (*text == '$') text = GStrings(text + 1); + DrawText(&twod,SmallFont, OptionSettings.mFontColorValue, indent + CURSORSPACE, y, + text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE); + return indent; + } + + //============================================================================= + bool MenuEvent (int mkey, bool fromcontroller) + { + FOptionValues **opt = OptionValues.CheckKey(mValues); + if (opt != NULL && *opt != NULL && (*opt)->mValues.Size() > 0) + { + int Selection = GetSelection(); + if (mkey == MKEY_Left) + { + if (Selection == -1) Selection = 0; + else if (--Selection < 0) Selection = (*opt)->mValues.Size()-1; + } + else if (mkey == MKEY_Right || mkey == MKEY_Enter) + { + if (++Selection >= (int)(*opt)->mValues.Size()) Selection = 0; + } + else + { + return FOptionMenuItem::MenuEvent(mkey, fromcontroller); + } + SetSelection(Selection); + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); + } + return true; + } + + bool Selectable() + { + return !(mGrayCheck != NULL && !(mGrayCheck->GetGenericRep(CVAR_Bool).Bool)); + } +}; + +//============================================================================= +// +// Change a CVAR, action is the CVAR name +// +//============================================================================= + +class FOptionMenuItemOption : public FOptionMenuItemOptionBase +{ + // action is a CVAR + FBaseCVar *mCVar; +public: + + FOptionMenuItemOption(const char *label, const char *menu, const char *values, const char *graycheck, int center) + : FOptionMenuItemOptionBase(label, menu, values, graycheck, center) + { + mCVar = FindCVar(mAction, NULL); + } + + //============================================================================= + int GetSelection() + { + int Selection = -1; + FOptionValues **opt = OptionValues.CheckKey(mValues); + if (opt != NULL && *opt != NULL && mCVar != NULL && (*opt)->mValues.Size() > 0) + { + if ((*opt)->mValues[0].TextValue.IsEmpty()) + { + UCVarValue cv = mCVar->GetGenericRep(CVAR_Float); + for(unsigned i = 0; i < (*opt)->mValues.Size(); i++) + { + if (fabs(cv.Float - (*opt)->mValues[i].Value) < FLT_EPSILON) + { + Selection = i; + break; + } + } + } + else + { + UCVarValue cv = mCVar->GetGenericRep(CVAR_String); + for(unsigned i = 0; i < (*opt)->mValues.Size(); i++) + { + if ((*opt)->mValues[i].TextValue.CompareNoCase(cv.String) == 0) + { + Selection = i; + break; + } + } + } + } + return Selection; + } + + void SetSelection(int Selection) + { + UCVarValue value; + FOptionValues **opt = OptionValues.CheckKey(mValues); + if (opt != NULL && *opt != NULL && mCVar != NULL && (*opt)->mValues.Size() > 0) + { + if ((*opt)->mValues[0].TextValue.IsEmpty()) + { + value.Float = (float)(*opt)->mValues[Selection].Value; + mCVar->SetGenericRep (value, CVAR_Float); + } + else + { + value.String = (*opt)->mValues[Selection].TextValue.LockBuffer(); + mCVar->SetGenericRep (value, CVAR_String); + (*opt)->mValues[Selection].TextValue.UnlockBuffer(); + } + } + } +}; + +//============================================================================= +// +// This class is used to capture the key to be used as the new key binding +// for a control item +// +//============================================================================= + +class DEnterKey : public DMenu +{ + DECLARE_CLASS(DEnterKey, DMenu) + + int *pKey; + +public: + DEnterKey(DMenu *parent, int *keyptr) + : DMenu(parent) + { + pKey = keyptr; + SetMenuMessage(1); + menuactive = MENU_WaitKey; // There should be a better way to disable GUI capture... + } + + bool TranslateKeyboardEvents() + { + return false; + } + + void SetMenuMessage(int which) + { + if (mParentMenu->IsKindOf(RUNTIME_CLASS(DOptionMenu))) + { + DOptionMenu *m = static_cast(mParentMenu); + FListMenuItem *it = m->GetItem(NAME_Controlmessage); + if (it != NULL) + { + it->SetValue(0, which); + } + } + } + + bool Responder(event_t *ev) + { + if (ev->type == EV_KeyDown) + { + *pKey = ev->data1; + menuactive = MENU_On; + SetMenuMessage(0); + Close(); + mParentMenu->MenuEvent((ev->data1 == KEY_ESCAPE)? MKEY_Abort : MKEY_Input, 0); + return true; + } + return false; + } + + void Drawer() + { + mParentMenu->Drawer(); + } +}; + +#ifndef NO_IMP +IMPLEMENT_ABSTRACT_CLASS(DEnterKey) +#endif + +//============================================================================= +// +// // Edit a key binding, Action is the CCMD to bind +// +//============================================================================= + +class FOptionMenuItemControl : public FOptionMenuItem +{ + FKeyBindings *mBindings; + int mInput; + bool mWaiting; +public: + + FOptionMenuItemControl(const char *label, const char *menu, FKeyBindings *bindings) + : FOptionMenuItem(label, menu) + { + mBindings = bindings; + mWaiting = false; + } + + + //============================================================================= + int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + { + drawLabel(indent, y, mWaiting? OptionSettings.mFontColorHighlight: + (selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor)); + + auto keys = mBindings->GetKeysForCommand(mAction); + auto description = C_NameKeys(keys.Data(), keys.Size()); + if (description.IsNotEmpty()) + { + M_DrawConText(CR_WHITE, indent + CURSORSPACE, y + (OptionSettings.mLinespacing-8)*CleanYfac_1, description); + } + else + { + DrawText(&twod,SmallFont, CR_BLACK, indent + CURSORSPACE, y + (OptionSettings.mLinespacing-8)*CleanYfac_1, "---", + DTA_CleanNoMove_1, true, TAG_DONE); + } + return indent; + } + + //============================================================================= + bool MenuEvent(int mkey, bool fromcontroller) + { + if (mkey == MKEY_Input) + { + mWaiting = false; + mBindings->SetBind(mInput, mAction); + return true; + } + else if (mkey == MKEY_Clear) + { + mBindings->UnbindACommand(mAction); + return true; + } + else if (mkey == MKEY_Abort) + { + mWaiting = false; + return true; + } + return false; + } + + bool Activate() + { + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); + mWaiting = true; + DMenu *input = new DEnterKey(DMenu::CurrentMenu, &mInput); + M_ActivateMenu(input); + return true; + } +}; + +//============================================================================= +// +// +// +//============================================================================= + +class FOptionMenuItemStaticText : public FOptionMenuItem +{ + EColorRange mColor; +public: + FOptionMenuItemStaticText(const char *label, bool header) + : FOptionMenuItem(label, NAME_None, true) + { + mColor = header? OptionSettings.mFontColorHeader : OptionSettings.mFontColor; + } + + int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + { + drawLabel(indent, y, mColor); + return -1; + } + + bool Selectable() + { + return false; + } + +}; + +//============================================================================= +// +// +// +//============================================================================= + +class FOptionMenuItemStaticTextSwitchable : public FOptionMenuItem +{ + EColorRange mColor; + FString mAltText; + int mCurrent; + +public: + FOptionMenuItemStaticTextSwitchable(const char *label, const char *label2, FName action, bool header) + : FOptionMenuItem(label, action, true) + { + mColor = header? OptionSettings.mFontColorHeader : OptionSettings.mFontColor; + mAltText = label2; + mCurrent = 0; + } + + int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + { + const char *txt = mCurrent? mAltText.GetChars() : mLabel.GetChars(); + if (*txt == '$') txt = GStrings(txt + 1); + int w = SmallFont->StringWidth(txt) * CleanXfac_1; + int x = (screen->GetWidth() - w) / 2; + DrawText(&twod,SmallFont, mColor, x, y, txt, DTA_CleanNoMove_1, true, TAG_DONE); + return -1; + } + + bool SetValue(int i, int val) + { + if (i == 0) + { + mCurrent = val; + return true; + } + return false; + } + + bool SetString(int i, const char *newtext) + { + if (i == 0) + { + mAltText = newtext; + return true; + } + return false; + } + + bool Selectable() + { + return false; + } +}; + +//============================================================================= +// +// +// +//============================================================================= + +class FOptionMenuSliderBase : public FOptionMenuItem +{ + // action is a CVAR + double mMin, mMax, mStep; + int mShowValue; + int mDrawX; + int mSliderShort; + +public: + FOptionMenuSliderBase(const char *label, double min, double max, double step, int showval) + : FOptionMenuItem(label, NAME_None) + { + mMin = min; + mMax = max; + mStep = step; + mShowValue = showval; + mDrawX = 0; + mSliderShort = 0; + } + + virtual double GetSliderValue() = 0; + virtual void SetSliderValue(double val) = 0; + + //============================================================================= + // + // Draw a slider. Set fracdigits negative to not display the current value numerically. + // + //============================================================================= + + void DrawSlider (int x, int y, double min, double max, double cur, int fracdigits, int indent) + { + char textbuf[16]; + double range; + int maxlen = 0; + int right = x + (12*8 + 4) * CleanXfac_1; + int cy = y + (OptionSettings.mLinespacing-8)*CleanYfac_1; + + range = max - min; + double ccur = clamp(cur, min, max) - min; + + if (fracdigits >= 0) + { + snprintf(textbuf, countof(textbuf), "%.*f", fracdigits, max); + maxlen = SmallFont->StringWidth(textbuf) * CleanXfac_1; + } + + mSliderShort = right + maxlen > screen->GetWidth(); + + if (!mSliderShort) + { + M_DrawConText(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12"); + M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 78) / range)) * CleanXfac_1), cy, "\x13"); + } + else + { + // On 320x200 we need a shorter slider + M_DrawConText(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x12"); + M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 38) / range)) * CleanXfac_1), cy, "\x13"); + right -= 5*8*CleanXfac_1; + } + + if (fracdigits >= 0 && right + maxlen <= screen->GetWidth()) + { + snprintf(textbuf, countof(textbuf), "%.*f", fracdigits, cur); + DrawText(&twod,SmallFont, CR_DARKGRAY, right, y, textbuf, DTA_CleanNoMove_1, true, TAG_DONE); + } + } + + + //============================================================================= + int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + { + drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor); + mDrawX = indent + CURSORSPACE; + DrawSlider (mDrawX, y, mMin, mMax, GetSliderValue(), mShowValue, indent); + return indent; + } + + //============================================================================= + bool MenuEvent (int mkey, bool fromcontroller) + { + double value = GetSliderValue(); + + if (mkey == MKEY_Left) + { + value -= mStep; + } + else if (mkey == MKEY_Right) + { + value += mStep; + } + else + { + return FOptionMenuItem::MenuEvent(mkey, fromcontroller); + } + SetSliderValue(clamp(value, mMin, mMax)); + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); + return true; + } + + bool MouseEvent(int type, int x, int y) + { + DOptionMenu *lm = static_cast(DMenu::CurrentMenu); + if (type != DMenu::MOUSE_Click) + { + if (!lm->CheckFocus(this)) return false; + } + if (type == DMenu::MOUSE_Release) + { + lm->ReleaseFocus(); + } + + int slide_left = mDrawX+8*CleanXfac_1; + int slide_right = slide_left + (10*8*CleanXfac_1 >> mSliderShort); // 12 char cells with 8 pixels each. + + if (type == DMenu::MOUSE_Click) + { + if (x < slide_left || x >= slide_right) return true; + } + + x = clamp(x, slide_left, slide_right); + double v = mMin + ((x - slide_left) * (mMax - mMin)) / (slide_right - slide_left); + if (v != GetSliderValue()) + { + SetSliderValue(v); + ////S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); + } + if (type == DMenu::MOUSE_Click) + { + lm->SetFocus(this); + } + return true; + } + +}; + +//============================================================================= +// +// +// +//============================================================================= + +class FOptionMenuSliderCVar : public FOptionMenuSliderBase +{ + FBaseCVar *mCVar; +public: + FOptionMenuSliderCVar(const char *label, const char *menu, double min, double max, double step, int showval) + : FOptionMenuSliderBase(label, min, max, step, showval) + { + mCVar = FindCVar(menu, NULL); + } + + double GetSliderValue() + { + if (mCVar != NULL) + { + return mCVar->GetGenericRep(CVAR_Float).Float; + } + else + { + return 0; + } + } + + void SetSliderValue(double val) + { + if (mCVar != NULL) + { + UCVarValue value; + value.Float = (float)val; + mCVar->SetGenericRep(value, CVAR_Float); + } + } +}; + +//============================================================================= +// +// +// +//============================================================================= + +class FOptionMenuSliderVar : public FOptionMenuSliderBase +{ + float *mPVal; +public: + + FOptionMenuSliderVar(const char *label, float *pVal, double min, double max, double step, int showval) + : FOptionMenuSliderBase(label, min, max, step, showval) + { + mPVal = pVal; + } + + double GetSliderValue() + { + return *mPVal; + } + + void SetSliderValue(double val) + { + *mPVal = (float)val; + } +}; + + +//============================================================================= +// +// [TP] FOptionMenuFieldBase +// +// Base class for input fields +// +//============================================================================= + +class FOptionMenuFieldBase : public FOptionMenuItem +{ +public: + FOptionMenuFieldBase ( const char* label, const char* menu, const char* graycheck ) : + FOptionMenuItem ( label, menu ), + mCVar ( FindCVar( mAction, NULL )), + mGrayCheck (( graycheck && strlen( graycheck )) ? FindCVar( graycheck, NULL ) : NULL ) {} + + const char* GetCVarString() + { + if ( mCVar == NULL ) + return ""; + + return mCVar->GetGenericRep( CVAR_String ).String; + } + + virtual FString Represent() + { + return GetCVarString(); + } + + int Draw ( FOptionMenuDescriptor*, int y, int indent, bool selected ) + { + bool grayed = mGrayCheck != NULL && !( mGrayCheck->GetGenericRep( CVAR_Bool ).Bool ); + drawLabel( indent, y, selected ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed ); + int overlay = grayed? MAKEARGB( 96, 48, 0, 0 ) : 0; + + DrawText(&twod, SmallFont, OptionSettings.mFontColorValue, indent + CURSORSPACE, y, + Represent().GetChars(), DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE ); + return indent; + } + + bool GetString ( int i, char* s, int len ) + { + if ( i == 0 ) + { + strncpy( s, GetCVarString(), len ); + s[len - 1] = '\0'; + return true; + } + + return false; + } + + bool SetString ( int i, const char* s ) + { + if ( i == 0 ) + { + if ( mCVar ) + { + UCVarValue vval; + vval.String = s; + mCVar->SetGenericRep( vval, CVAR_String ); + } + + return true; + } + + return false; + } + +protected: + // Action is a CVar in this class and derivatives. + FBaseCVar* mCVar; + FBaseCVar* mGrayCheck; +}; + +//============================================================================= +// +// [TP] FOptionMenuTextField +// +// A text input field widget, for use with string CVars. +// +//============================================================================= + +class FOptionMenuTextField : public FOptionMenuFieldBase +{ +public: + FOptionMenuTextField ( const char *label, const char* menu, const char* graycheck ) : + FOptionMenuFieldBase ( label, menu, graycheck ), + mEntering ( false ) {} + + FString Represent() + { + FString text = mEntering ? mEditName : GetCVarString(); + + if ( mEntering ) + text += '_'; + + return text; + } + + int Draw(FOptionMenuDescriptor*desc, int y, int indent, bool selected) + { + if (mEntering) + { + // reposition the text so that the cursor is visible when in entering mode. + FString text = Represent(); + int tlen = SmallFont->StringWidth(text) * CleanXfac_1; + int newindent = screen->GetWidth() - tlen - CURSORSPACE; + if (newindent < indent) indent = newindent; + } + return FOptionMenuFieldBase::Draw(desc, y, indent, selected); + } + + bool MenuEvent ( int mkey, bool fromcontroller ) + { + if ( mkey == MKEY_Enter ) + { + //S_Sound( CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE ); + strcpy( mEditName, GetCVarString() ); + mEntering = true; + //DMenu* input = new DTextEnterMenu ( DMenu::CurrentMenu, mEditName, sizeof mEditName, 2, fromcontroller ); + //M_ActivateMenu( input ); + return true; + } + else if ( mkey == MKEY_Input ) + { + if ( mCVar ) + { + UCVarValue vval; + vval.String = mEditName; + mCVar->SetGenericRep( vval, CVAR_String ); + } + + mEntering = false; + return true; + } + else if ( mkey == MKEY_Abort ) + { + mEntering = false; + return true; + } + + return FOptionMenuItem::MenuEvent( mkey, fromcontroller ); + } + +private: + bool mEntering; + char mEditName[128]; +}; + +//============================================================================= +// +// [TP] FOptionMenuNumberField +// +// A numeric input field widget, for use with number CVars where sliders are inappropriate (i.e. +// where the user is interested in the exact value specifically) +// +//============================================================================= + +class FOptionMenuNumberField : public FOptionMenuFieldBase +{ +public: + FOptionMenuNumberField ( const char *label, const char* menu, float minimum, float maximum, + float step, const char* graycheck ) + : FOptionMenuFieldBase ( label, menu, graycheck ), + mMinimum ( minimum ), + mMaximum ( maximum ), + mStep ( step ) + { + if ( mMaximum <= mMinimum ) + std::swap( mMinimum, mMaximum ); + + if ( mStep <= 0 ) + mStep = 1; + } + + bool MenuEvent ( int mkey, bool fromcontroller ) + { + if ( mCVar ) + { + float value = mCVar->GetGenericRep( CVAR_Float ).Float; + + if ( mkey == MKEY_Left ) + { + value -= mStep; + + if ( value < mMinimum ) + value = mMaximum; + } + else if ( mkey == MKEY_Right || mkey == MKEY_Enter ) + { + value += mStep; + + if ( value > mMaximum ) + value = mMinimum; + } + else + return FOptionMenuItem::MenuEvent( mkey, fromcontroller ); + + UCVarValue vval; + vval.Float = value; + mCVar->SetGenericRep( vval, CVAR_Float ); + //S_Sound( CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE ); + } + + return true; + } + +private: + float mMinimum; + float mMaximum; + float mStep; +}; diff --git a/source/common/menu/readthis.cpp b/source/common/menu/readthis.cpp new file mode 100644 index 000000000..43d981822 --- /dev/null +++ b/source/common/menu/readthis.cpp @@ -0,0 +1,149 @@ +/* +** readthis.cpp +** Help screens +** +**--------------------------------------------------------------------------- +** Copyright 2001-2010 Randy Heit +** Copyright 2010 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "menu/menu.h" +#include "v_draw.h" +#include "textures/textures.h" + +#if 0 // This is probably useless. To be replaced with what Build games use to draw their help screens. + +class DReadThisMenu : public DMenu +{ + DECLARE_CLASS(DReadThisMenu, DMenu) + int mScreen; + int mInfoTic; + +public: + + DReadThisMenu(DMenu *parent = NULL); + void Drawer(); + bool MenuEvent(int mkey, bool fromcontroller); + bool DimAllowed () { return false; } + bool MouseEvent(int type, int x, int y); +}; + +IMPLEMENT_CLASS(DReadThisMenu) + +//============================================================================= +// +// Read This Menus +// +//============================================================================= + +DReadThisMenu::DReadThisMenu(DMenu *parent) +: DMenu(parent) +{ + mScreen = 1; + mInfoTic = gametic; +} + + +//============================================================================= +// +// +// +//============================================================================= + +void DReadThisMenu::Drawer() +{ + FTexture *tex = NULL, *prevpic = NULL; + fixed_t alpha; + + // Did the mapper choose a custom help page via MAPINFO? + if ((level.info != NULL) && level.info->F1Pic.Len() != 0) + { + tex = TexMan.FindTexture(level.info->F1Pic); + mScreen = 1; + } + + if (tex == NULL) + { + tex = TexMan[gameinfo.infoPages[mScreen-1].GetChars()]; + } + + if (mScreen > 1) + { + prevpic = TexMan[gameinfo.infoPages[mScreen-2].GetChars()]; + } + + screen->Dim(0, 1.0, 0,0, SCREENWIDTH, SCREENHEIGHT); + alpha = MIN (Scale (gametic - mInfoTic, OPAQUE, TICRATE/3), OPAQUE); + if (alpha < OPAQUE && prevpic != NULL) + { + screen->DrawTexture (prevpic, 0, 0, DTA_Fullscreen, true, TAG_DONE); + } + screen->DrawTexture (tex, 0, 0, DTA_Fullscreen, true, DTA_Alpha, alpha, TAG_DONE); + +} + + +//============================================================================= +// +// +// +//============================================================================= + +bool DReadThisMenu::MenuEvent(int mkey, bool fromcontroller) +{ + if (mkey == MKEY_Enter) + { + S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); + mScreen++; + mInfoTic = gametic; + if ((level.info != NULL && level.info->F1Pic.Len() != 0) || mScreen > int(gameinfo.infoPages.Size())) + { + Close(); + } + return true; + } + else return Super::MenuEvent(mkey, fromcontroller); +} + +//============================================================================= +// +// +// +//============================================================================= + +bool DReadThisMenu::MouseEvent(int type, int x, int y) +{ + if (type == MOUSE_Click) + { + return MenuEvent(MKEY_Enter, true); + } + return false; +} + +#endif \ No newline at end of file diff --git a/source/common/utility/gstrings.h b/source/common/utility/gstrings.h new file mode 100644 index 000000000..b9b8fff62 --- /dev/null +++ b/source/common/utility/gstrings.h @@ -0,0 +1,48 @@ +/* +** gstrings.h +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#ifndef __GSTRINGS_H__ +#define __GSTRINGS_H__ + +#ifdef _MSC_VER +#pragma once +#endif + +#include "stringtable.h" + +extern FStringTable GStrings; + +extern const char *endmsg[]; + + +#endif //__GSTRINGS_H__ diff --git a/source/common/utility/name.h b/source/common/utility/name.h index 76324fe7c..1d7f2a581 100644 --- a/source/common/utility/name.h +++ b/source/common/utility/name.h @@ -34,6 +34,8 @@ #ifndef NAME_H #define NAME_H +#include "tarray.h" + enum ENamedName { #define xx(n) NAME_##n, @@ -50,8 +52,6 @@ public: FName (const char *text) { Index = NameData.FindName (text, false); } FName (const char *text, bool noCreate) { Index = NameData.FindName (text, noCreate); } FName (const char *text, size_t textlen, bool noCreate) { Index = NameData.FindName (text, textlen, noCreate); } - FName (const FString &text); - FName (const FString &text, bool noCreate); FName (const FName &other) = default; FName (ENamedName index) { Index = index; } // ~FName () {} // Names can be added but never removed. @@ -122,4 +122,13 @@ protected: static NameManager NameData; }; + +template<> struct THashTraits +{ + hash_t Hash(FName key) + { + return key.GetIndex(); + } + int Compare(FName left, FName right) { return left != right; } +}; #endif diff --git a/source/common/utility/namedef.h b/source/common/utility/namedef.h index d0cfff7b7..acb8a5ff9 100644 --- a/source/common/utility/namedef.h +++ b/source/common/utility/namedef.h @@ -8,3 +8,5 @@ xx(SEQ) xx(SFX) xx(RAW) xx(MAP) +xx(Mainmenu) +xx(Controlmessage) \ No newline at end of file diff --git a/source/common/utility/stringtable.cpp b/source/common/utility/stringtable.cpp new file mode 100644 index 000000000..bd5d3fcd4 --- /dev/null +++ b/source/common/utility/stringtable.cpp @@ -0,0 +1,666 @@ +/* +** stringtable.cpp +** Implements the FStringTable class +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include + +#include "stringtable.h" +#include "cmdlib.h" +#include "filesystem.h" +#include "sc_man.h" +#include "c_dispatch.h" +#include "v_text.h" +#include "c_cvars.h" +#include "printf.h" + +EXTERN_CVAR(String, language) +CUSTOM_CVAR(Int, cl_gender, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (self < 0 || self > 3) self = 0; +} + +//========================================================================== +// +// +// +//========================================================================== + +void FStringTable::LoadStrings () +{ + int lastlump, lump; + + lastlump = 0; + while ((lump = fileSystem.Iterate("Language/lmacros", &lastlump, ELookupMode::NoExtension)) != -1) + { + readMacros(lump); + } + + lastlump = 0; + while ((lump = fileSystem.Iterate ("Language/language", &lastlump, ELookupMode::NoExtension)) != -1) + { + auto lumpdata = fileSystem.GetFileData(lump); + + if (!ParseLanguageCSV(lump, lumpdata)) + LoadLanguage (lump, lumpdata); + } + UpdateLanguage(); + allMacros.Clear(); +} + + +//========================================================================== +// +// This was tailored to parse CSV as exported by Google Docs. +// +//========================================================================== + + +TArray> FStringTable::parseCSV(const TArray &buffer) +{ + const size_t bufLength = buffer.Size(); + TArray> data; + TArray row; + TArray cell; + bool quoted = false; + + /* + auto myisspace = [](int ch) { return ch == '\t' || ch == '\r' || ch == '\n' || ch == ' '; }; + while (*vcopy && myisspace((unsigned char)*vcopy)) vcopy++; // skip over leaading whitespace; + auto vend = vcopy + strlen(vcopy); + while (vend > vcopy && myisspace((unsigned char)vend[-1])) *--vend = 0; // skip over trailing whitespace + */ + + for (size_t i = 0; i < bufLength; ++i) + { + if (buffer[i] == '"') + { + // Double quotes inside a quoted string count as an escaped quotation mark. + if (quoted && i < bufLength - 1 && buffer[i + 1] == '"') + { + cell.Push('"'); + i++; + } + else if (cell.Size() == 0 || quoted) + { + quoted = !quoted; + } + } + else if (buffer[i] == ',') + { + if (!quoted) + { + cell.Push(0); + ProcessEscapes(cell.Data()); + row.Push(cell.Data()); + cell.Clear(); + } + else + { + cell.Push(buffer[i]); + } + } + else if (buffer[i] == '\r') + { + // Ignore all CR's. + } + else if (buffer[i] == '\n' && !quoted) + { + cell.Push(0); + ProcessEscapes(cell.Data()); + row.Push(cell.Data()); + data.Push(std::move(row)); + cell.Clear(); + } + else + { + cell.Push(buffer[i]); + } + } + + // Handle last line without linebreak + if (cell.Size() > 0 || row.Size() > 0) + { + cell.Push(0); + ProcessEscapes(cell.Data()); + row.Push(cell.Data()); + data.Push(std::move(row)); + } + return data; +} + +//========================================================================== +// +// +// +//========================================================================== + +bool FStringTable::readMacros(int lumpnum) +{ + auto lumpdata = fileSystem.GetFileData(lumpnum); + auto data = parseCSV(lumpdata); + + for (unsigned i = 1; i < data.Size(); i++) + { + auto macroname = data[i][0]; + auto language = data[i][1]; + if (macroname.IsEmpty() || language.IsEmpty()) continue; + FStringf combined_name("%s/%s", language.GetChars(), macroname.GetChars()); + FName name = combined_name.GetChars(); + + StringMacro macro; + + for (int k = 0; k < 4; k++) + { + macro.Replacements[k] = data[i][k+2]; + } + allMacros.Insert(name, macro); + } + return true; +} + +//========================================================================== +// +// +// +//========================================================================== + +bool FStringTable::ParseLanguageCSV(int lumpnum, const TArray &buffer) +{ + if (memcmp(buffer.Data(), "default,", 8)) return false; + auto data = parseCSV(buffer); + + int labelcol = -1; + int filtercol = -1; + TArray> langrows; + bool hasDefaultEntry = false; + + if (data.Size() > 0) + { + for (unsigned column = 0; column < data[0].Size(); column++) + { + auto &entry = data[0][column]; + if (entry.CompareNoCase("filter") == 0) + { + filtercol = column; + } + else if (entry.CompareNoCase("identifier") == 0) + { + labelcol = column; + } + else + { + auto languages = entry.Split(" ", FString::TOK_SKIPEMPTY); + for (auto &lang : languages) + { + if (lang.CompareNoCase("default") == 0) + { + langrows.Push(std::make_pair(column, default_table)); + hasDefaultEntry = true; + } + else if (lang.Len() < 4) + { + lang.ToLower(); + langrows.Push(std::make_pair(column, MAKE_ID(lang[0], lang[1], lang[2], 0))); + } + } + } + } + + for (unsigned i = 1; i < data.Size(); i++) + { + auto &row = data[i]; +#if 0 + if (filtercol > -1) + { + auto filterstr = row[filtercol]; + auto filter = filterstr.Split(" ", FString::TOK_SKIPEMPTY); + if (filter.Size() > 0 && filter.FindEx([](const auto &str) { return str.CompareNoCase(GameNames[gameinfo.gametype]) == 0; }) == filter.Size()) + continue; + } +#endif + + FName strName = row[labelcol].GetChars(); + if (hasDefaultEntry) + { + DeleteForLabel(lumpnum, strName); + } + for (auto &langentry : langrows) + { + auto str = row[langentry.first]; + if (str.Len() > 0) + { + InsertString(lumpnum, langentry.second, strName, str); + } + else + { + DeleteString(langentry.second, strName); + } + } + } + } + return true; +} + +//========================================================================== +// +// +// +//========================================================================== + +void FStringTable::LoadLanguage (int lumpnum, const TArray &buffer) +{ + bool errordone = false; + TArray activeMaps; + FScanner sc; + bool hasDefaultEntry = false; + + sc.OpenMem("LANGUAGE", (const char*)buffer.Data(), buffer.Size()); + sc.SetCMode (true); + while (sc.GetString ()) + { + if (sc.Compare ("[")) + { // Process language identifiers + activeMaps.Clear(); + sc.MustGetString (); + do + { + size_t len = sc.StringLen; + if (len != 2 && len != 3) + { + if (len == 1 && sc.String[0] == '~') + { + // deprecated and ignored + sc.ScriptMessage("Deprecated option '~' found in language list"); + sc.MustGetString (); + continue; + } + if (len == 1 && sc.String[0] == '*') + { + activeMaps.Clear(); + activeMaps.Push(global_table); + } + else if (len == 7 && stricmp (sc.String, "default") == 0) + { + activeMaps.Clear(); + activeMaps.Push(default_table); + hasDefaultEntry = true; + } + else + { + sc.ScriptError ("The language code must be 2 or 3 characters long.\n'%s' is %lu characters long.", + sc.String, len); + } + } + else + { + if (activeMaps.Size() != 1 || (activeMaps[0] != default_table && activeMaps[0] != global_table)) + activeMaps.Push(MAKE_ID(tolower(sc.String[0]), tolower(sc.String[1]), tolower(sc.String[2]), 0)); + } + sc.MustGetString (); + } while (!sc.Compare ("]")); + } + else + { // Process string definitions. + if (activeMaps.Size() == 0) + { + // LANGUAGE lump is bad. We need to check if this is an old binary + // lump and if so just skip it to allow old WADs to run which contain + // such a lump. + if (!sc.isText()) + { + if (!errordone) Printf("Skipping binary 'LANGUAGE' lump.\n"); + errordone = true; + return; + } + sc.ScriptError ("Found a string without a language specified."); + } + + bool skip = false; +#if 0 // I don't think this is needed. + if (sc.Compare("$")) + { + sc.MustGetStringName("ifgame"); + sc.MustGetStringName("("); + sc.MustGetString(); + if (sc.Compare("strifeteaser")) + { + skip |= (gameinfo.gametype != GAME_Strife) || !(gameinfo.flags & GI_SHAREWARE); + } + else + { + skip |= !sc.Compare(GameTypeName()); + } + sc.MustGetStringName(")"); + sc.MustGetString(); + + } +#endif + + FName strName (sc.String); + sc.MustGetStringName ("="); + sc.MustGetString (); + FString strText (sc.String, ProcessEscapes (sc.String)); + sc.MustGetString (); + while (!sc.Compare (";")) + { + ProcessEscapes (sc.String); + strText += sc.String; + sc.MustGetString (); + } + if (!skip) + { + if (hasDefaultEntry) + { + DeleteForLabel(lumpnum, strName); + } + // Insert the string into all relevant tables. + for (auto map : activeMaps) + { + InsertString(lumpnum, map, strName, strText); + } + } + } + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void FStringTable::DeleteString(int langid, FName label) +{ + allStrings[langid].Remove(label); +} + +//========================================================================== +// +// This deletes all older entries for a given label. This gets called +// when a string in the default table gets updated. +// +//========================================================================== + +void FStringTable::DeleteForLabel(int lumpnum, FName label) +{ + decltype(allStrings)::Iterator it(allStrings); + decltype(allStrings)::Pair *pair; + auto filenum = fileSystem.GetFileContainer(lumpnum); + + while (it.NextPair(pair)) + { + auto entry = pair->Value.CheckKey(label); + if (entry && entry->filenum < filenum) + { + pair->Value.Remove(label); + } + } + +} + +//========================================================================== +// +// +// +//========================================================================== + +void FStringTable::InsertString(int lumpnum, int langid, FName label, const FString &string) +{ + const char *strlangid = (const char *)&langid; + TableElement te = { fileSystem.GetFileContainer(lumpnum), { string, string, string, string } }; + long index; + while ((index = te.strings[0].IndexOf("@[")) >= 0) + { + auto endindex = te.strings[0].IndexOf(']', index); + if (endindex == -1) + { + Printf("Bad macro in %s : %s\n", strlangid, label.GetChars()); + break; + } + FString macroname(te.strings[0].GetChars() + index + 2, endindex - index - 2); + FStringf lookupstr("%s/%s", strlangid, macroname.GetChars()); + FStringf replacee("@[%s]", macroname.GetChars()); + FName lookupname(lookupstr.GetChars(), true); + auto replace = allMacros.CheckKey(lookupname); + for (int i = 0; i < 4; i++) + { + const char *replacement = replace? replace->Replacements[i].GetChars() : ""; + te.strings[i].Substitute(replacee, replacement); + } + } + allStrings[langid].Insert(label, te); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FStringTable::UpdateLanguage() +{ + size_t langlen = strlen(language); + + int LanguageID = (langlen < 2 || langlen > 3) ? + MAKE_ID('e', 'n', 'u', '\0') : + MAKE_ID(language[0], language[1], language[2], '\0'); + + currentLanguageSet.Clear(); + + auto checkone = [&](uint32_t lang_id) + { + auto list = allStrings.CheckKey(lang_id); + if (list && currentLanguageSet.FindEx([&](const auto &element) { return element.first == lang_id; }) == currentLanguageSet.Size()) + currentLanguageSet.Push(std::make_pair(lang_id, list)); + }; + + checkone(global_table); + checkone(LanguageID); + checkone(LanguageID & MAKE_ID(0xff, 0xff, 0, 0)); + checkone(default_table); +} + +//========================================================================== +// +// Replace \ escape sequences in a string with the escaped characters. +// +//========================================================================== + +size_t FStringTable::ProcessEscapes (char *iptr) +{ + char *sptr = iptr, *optr = iptr, c; + + while ((c = *iptr++) != '\0') + { + if (c == '\\') + { + c = *iptr++; + if (c == 'n') + c = '\n'; + else if (c == 'c') + c = TEXTCOLOR_ESCAPE; + else if (c == 'r') + c = '\r'; + else if (c == 't') + c = '\t'; + else if (c == '\n') + continue; + } + *optr++ = c; + } + *optr = '\0'; + return optr - sptr; +} + +//========================================================================== +// +// Checks if the given key exists in any one of the default string tables that are valid for all languages. +// To replace IWAD content this condition must be true. +// +//========================================================================== + +bool FStringTable::exists(const char *name) +{ + if (name == nullptr || *name == 0) + { + return false; + } + FName nm(name, true); + if (nm != NAME_None) + { + uint32_t defaultStrings[] = { default_table, global_table }; + + for (auto mapid : defaultStrings) + { + auto map = allStrings.CheckKey(mapid); + if (map) + { + auto item = map->CheckKey(nm); + if (item) return true; + } + } + } + return false; +} + +//========================================================================== +// +// Finds a string by name and returns its value +// +//========================================================================== + +const char *FStringTable::GetString(const char *name, uint32_t *langtable, int gender) const +{ + if (name == nullptr || *name == 0) + { + return nullptr; + } + if (gender == -1) gender = cl_gender; + if (gender < 0 || gender > 3) gender = 0; + FName nm(name, true); + if (nm != NAME_None) + { + for (auto map : currentLanguageSet) + { + auto item = map.second->CheckKey(nm); + if (item) + { + if (langtable) *langtable = map.first; + return item->strings[gender].GetChars(); + } + } + } + return nullptr; +} + +//========================================================================== +// +// Finds a string by name in a given language +// +//========================================================================== + +const char *FStringTable::GetLanguageString(const char *name, uint32_t langtable, int gender) const +{ + if (name == nullptr || *name == 0) + { + return nullptr; + } + if (gender == -1) gender = cl_gender; + if (gender < 0 || gender > 3) gender = 0; + FName nm(name, true); + if (nm != NAME_None) + { + auto map = allStrings.CheckKey(langtable); + if (map == nullptr) return nullptr; + auto item = map->CheckKey(nm); + if (item) + { + return item->strings[gender].GetChars(); + } + } + return nullptr; +} + +bool FStringTable::MatchDefaultString(const char *name, const char *content) const +{ + // This only compares the first line to avoid problems with bad linefeeds. For the few cases where this feature is needed it is sufficient. + auto c = GetLanguageString(name, FStringTable::default_table); + if (!c) return false; + + // Check a secondary key, in case the text comparison cannot be done due to needed orthographic fixes (see Harmony's exit text) + FStringf checkkey("%s_CHECK", name); + auto cc = GetLanguageString(checkkey, FStringTable::default_table); + if (cc) c = cc; + + return (c && !strnicmp(c, content, strcspn(content, "\n\r\t"))); +} + +//========================================================================== +// +// Finds a string by name and returns its value. If the string does +// not exist, returns the passed name instead. +// +//========================================================================== + +const char *FStringTable::operator() (const char *name) const +{ + const char *str = operator[] (name); + return str ? str : name; +} + + +//========================================================================== +// +// Find a string with the same exact text. Returns its name. +// This does not need to check genders, it is only used by +// Dehacked on the English table for finding stock strings. +// +//========================================================================== + +const char *StringMap::MatchString (const char *string) const +{ + StringMap::ConstIterator it(*this); + StringMap::ConstPair *pair; + + while (it.NextPair(pair)) + { + if (pair->Value.strings[0].CompareNoCase(string) == 0) + { + return pair->Key.GetChars(); + } + } + return nullptr; +} + +FStringTable GStrings; +CVAR(String, language, "en", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) diff --git a/source/common/utility/stringtable.h b/source/common/utility/stringtable.h new file mode 100644 index 000000000..e4137de3d --- /dev/null +++ b/source/common/utility/stringtable.h @@ -0,0 +1,116 @@ +/* +** stringtable.h +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +** FStringTable +** +** This class manages a list of localizable strings stored in a wad file. +*/ + +#ifndef __STRINGTABLE_H__ +#define __STRINGTABLE_H__ + +#ifdef _MSC_VER +#pragma once +#endif + + +#include +#include "basics.h" +#include "zstring.h" +#include "tarray.h" +#include "name.h" + +struct TableElement +{ + int filenum; + FString strings[4]; +}; + +// This public interface is for Dehacked +class StringMap : public TMap +{ +public: + const char *MatchString(const char *string) const; +}; + + +struct StringMacro +{ + FString Replacements[4]; +}; + + +class FStringTable +{ +public: + enum : uint32_t + { + default_table = MAKE_ID('*', '*', 0, 0), + global_table = MAKE_ID('*', 0, 0, 0), + }; + + using LangMap = TMap; + using StringMacroMap = TMap; + + void LoadStrings (); + void UpdateLanguage(); + + const char *GetLanguageString(const char *name, uint32_t langtable, int gender = -1) const; + bool MatchDefaultString(const char *name, const char *content) const; + const char *GetString(const char *name, uint32_t *langtable, int gender = -1) const; + const char *operator() (const char *name) const; // Never returns NULL + const char *operator[] (const char *name) const + { + return GetString(name, nullptr); + } + bool exists(const char *name); + +private: + + StringMacroMap allMacros; + LangMap allStrings; + TArray> currentLanguageSet; + + void LoadLanguage (int lumpnum, const TArray &buffer); + TArray> parseCSV(const TArray &buffer); + bool ParseLanguageCSV(int lumpnum, const TArray &buffer); + + bool LoadLanguageFromSpreadsheet(int lumpnum, const TArray &buffer); + bool readMacros(int lumpnum); + void InsertString(int lumpnum, int langid, FName label, const FString &string); + void DeleteString(int langid, FName label); + void DeleteForLabel(int lumpnum, FName label); + + static size_t ProcessEscapes (char *str); +}; + +#endif //__STRINGTABLE_H__ diff --git a/wadsrc/static/fonts/consolefont/0000.png b/wadsrc/static/fonts/consolefont/0000.png new file mode 100644 index 0000000000000000000000000000000000000000..aa78736f71935569ba563838e0ed9c69c660156e GIT binary patch literal 3827 zcmV$P)C00004XF*Lt006O% z3;baP0000WV@Og>004R>004l5008;`004mK004C`008P>0026e000+ooVrmw0002k zP)t-s0093tH#b*TS3^TXOG`^UJUlNiFElhXBO@al8yf)u0U;qFC@3fs6B7pq2Rl1E zp`oFLg@r{$MJ+8Yr>Cc!oSc`JmyV8(hlhuMe}51V5HK(>R8&-khK6ZrX8f|TDl$4ZMSXh&jlcc1itgNhMWo2MsU@^KKtOA2Ym$L`Pt~$$J0*010qNS#tmY z3y1&!3y1;bjwwk101XLAL_t(|+SOYLcigrS2CXcYoITV!cH&C5o6uESS?=LVZfrSe zw5#L)|D?_Ua{qJ3E~?J22cn}&6DQH(KpScnS{_b)2^F#Juvkx%0x{& z>*f~TwUf4M+j;n6YMwkfY8D zcD`sP9o9EJZ5sTwO>^|JnM~V0gjcU#Spz`i?)B?GK1~gH@x$x*@cM@rsR2L!NDVk@ z+P=q{^oP_n-4x#oYviszp&q~vXep{6s0$`j{KKl7=D5SJ5Z=6@UkHDS1mR8m3*Ffn zH(}g>pMC;r0984ePP*6Okp)r6Tgg(LI2wQ?rvq^8Gy-!_Dp8(%)v5YM^;U2&@g>H&8X--eO$z;-=cBiMO zv3?!{e~Dycp!+sfzp(-MO*{Gsa6*HfD(cg#H#q1b3{w**nBE-w?Iey0>@8{;-WCh` z05S$bdJ&O3uD*hTVK$Le-h#2CDQi#-_HwrPc68*I6uF*iajvHca-#088={#!Tpjt3_D{vw8Lyk4S4(R zLu|pn&dy$5#5_O$j6(sgK7RW2>FCqZQM`Xd_VEg+0a!n_9Q3!i#-O3Qx;j6)6*=&gaju!B`JrrNuz}9zBkVo%Nb^g?XrrwAxOXcf(`h1Ri%Jg z=hvslj<83rtpUpx%kHmR(HGbNstapt@y)3v3+#V<7*3-8u&(D%f%NOIfO%`xQ;F1q zk`_bgQVMJU%I!?Yz#NBLOEqD&vC73#i5}m+`!~^rpdp0ckU&sbQXGa-~%Z>EmA`vE)4v>oWB?Qe@+>B9`0=8z_i*9b10sctR0KGwshMO!0g}D5O z*C@1F0kimv6lLNRi5Em!x-{nSBH!Wz-?xzEOtfAn5opYkgulq+M}#DzOc9a+ESo&7 z*D2gZ)QOWB-QI#1BJmSPL%iRnr_@xRjh=2Lqvp>F%&RLKm<8P30sbHc-`z!-II?(U zDK!Vd?e0z=c=)FTjJrH_M)&u*1o$J41oR9PMl$3nIb%$bmLSmpBV0jUJrl6b)gqDK9pSaiSj}rh=iXq zJ`x%uuGfrPV3|3E@)bw1a2F2}uO&zok*WSzC;h=%B(T0n;B|n$O*l`ugB7ZTjQ<9AUuLJMf5y6c;HZeE_TvQboBe+>q|M7GoNKS;BeZEYichghNyU zCJPUYX_hr!Vej;S?*W%P=x6}P!M?F#HIs|*ET4Nb2mg_RsRe&MQb6AD#BU-!lyVVn z#)8AWM7YRs<1b$>P0GOYdc-B;Glp~5dzrZt1@Ve|F&@NzNRcbOBu@3f+T(c5^SR9C zrVA2|nR5_}>wNx~^v*1hbdouS##@}=A$Z&a0aY;VbU}P&=9~wj==F%?RjuH(L^39r zvkr<_1_+90e-YJWVaa9)r5=$>VV~|Xas1`^6#qKk8{WM>P}$T+vJ)gsXL@HlNI(>U zZHz*17>+A=ugZdA6SMh0(-6%2c6_=t1f=u7RP@b-kr4NR8QypF{$nh9_s^-Z=U}-)ad~$N$d&HFDZs)aMemWhhCh)Lq#8$C9e}dhgS6fxO6qU!N&eq zQv@X)zOH{{GCO``?^om^T-OdB@wS$*;FZ68xj|qlleDw-)%^Jz(pB zFS7@j1k_)_9&q2`QS5=jzWDm~K<+@i+~tRSL{b9)GT}xXi;2emfQlYi<=BokK*;#m zk01tt=ovNx;#YtWGDiW=@ugpYKXQEXeuB)d=e#!AgZLLkEw~472Z)=HaqsMbTk#0m zIzD9f0OQ!%1A=q`ejH?C2RJ*yb-nrx#UF5YClft@IQBN#12IX>9)RGM|D|Ctaxdy~ zT|R|kdaFGUL@kIt0CjsHK4#$s>cm`d!S(e)X%86cx7!2WaxlTsm#P6lamMME*+ie#44cXkN-(d5 zXRysO`1mvkP!6EQ@j@Z#giYlz6<+)-rrvOmYaa|{fuK|W*3mX{+~;O|vJHw18RyUt zcN2o?4}OIDa=_7j;rOQw7N<%oBBVIvh|;K9S6ynVc35dSnHlsE>~ z4COq3fc?+FwrxOv?aZ6h!M=K+mdf`3fVT%JAnhT-Caqw(A$kj-)B_v4J&aP>zM(Gt zlUtD2|8;$_Vxs`@4)_G3S4w(&gNNyt`m7zc~K`#)51tglI^gpsmIjxj^F7X`mqbVtec}IC zJ6{bX`Xw!Mr3Y5w(AARy05r) zHlBtDm&+Fa<{v040Xu+DkoosyAu!rkofJ^(Af_`F8`BjAhLB(R`~5?A9spdr>b##h9Nf-e*qm-W2=T;#t_$2` zFtP)7&HDhMj{kD>kL~c!Z&X3J z_-Iamandn2x_*d6_y)hOFAV>XpZ19;Usb=MstFHvvJzm$oZN&gyHC1K7Cp#BZt!Ke zf;`K+x1uOUHkBPfND73JPk$t1 z@>}@>x6feY{a?&2()JPH4$75&UI6PD z!}ZvZ^Ah-dgc0BDFJx|h!M!eVAsUW%@sU5F;OX0 z{Q|e27Y?}GdE?#b-MT~eB~pmn|I5z{?&5M~`-)q*KT! z#`tMpdtej&uk3-%j>7-e9vE@;cjXHL+7j4&o?x>*;L4Taa~sai3+?8>>-*hyK(=qd z`RhEb?DyrjW*u%7G3^0W0()@Y5eQ$^9uRy#Y{&in_JG?UsN&YdFR=$k z@go`;1bf*7wSublz)g^c!XA)tG1MLIN4RAv$FD6H#OqhhXAOoty@cyN03*}>4PZMr zf8pAE2fHt`2Uxaq#5%9bx#AsM@xH(PpgRao&d&WDU=PS@`XGCNSte)aeh#q*f}IjL z&>krM4W>LP(w{F|ZAyK}DjKf9J@4oF>3P4N=PC3fdc*Wg^Z)>W z`TF4eHAvIAtFE>tN_9B|4Qz;WBe(&;UmWOa)J9E?i1zW<@YzenrCoY0QqFv z>8R9LfD#p-oQ6t{O+z@KY*G7Tyn{8@Y2!g(oLeBtqqdxtcLTeLF=h5LY(kyeY=4o5 z1_h4wjO6$R9QH&~oS!tV(Ua;Ym-Wxu-}~4QLxhfVlapHiUWAzr2N}~RGbZ%NckaIG zsj*yRy76NQ>T8X@RrJEfl&8;+9ixis(6p2b^$=lVhkA<4UZYx6d&137NMi z$(Y-*XPgH~3p00Crrt(JyHXE>j@~a+0(nC)Z=I<({yF$_7kA4Cp$`NoM#~MX%+i;CSLjT46GnyG-#lBe>|C0J}G458(W_Jsj3lYy=j|- zn(oKG2(d=hrRm*3Zwh)~a=7q*zAmnh^#0e07lu z`?SDoFV6rPayH-a=DVwKK1PA-yKJX|HoyulOznYwG<%eZF8yg~@3hV@`1gr^=9?3~ zjTFpER$=4JpDw^R@d)j&^;`$$8*WwxpM8B4ZgesF)U9N@+5!1_WRkXLX+H~Lx5KoO zd)>WQ+o@|O+~$}SZ}wfW?SX^(q!!toe=^NXwT}1uok(nZ@AI=@yL5_Xi)Uu`f}P-(-o3E- zL(*f5j?88>yTas(95TG(;pO5(mujR}9C9EYrBk|AhHrCte< z(ZhFg(?N+>=M4-xpyyIcAk`kd73XI9GwU(nzk+0giCmGsVHnXsM;_I64XGrS^9LSsMati+g{Ii(!59B)mYOhBk#iHe?ei9hkPR{s;#uIK!^$ z@dQ#8(eO}OW|yBUzSr>8L20FOw|h9m!k=ZEb3b^>;*|x>#G|Ye{Uqq?9S*Z^Q`Gv^ zK`)*7$Qz986q7jr=_+``=*OHk4)2Qg2J@004R>004l5008;`004mK004C`008P>0026e000+ooVrmw0000a zP)t-s0094hfPjyWj{yMzj*gC>pP#RL<=9+#J~Um1NlirK~zY`y;i%9+ei@XT|Q)GzCSSbeqew;iIgJ+ z`T*ht<^l*zEP%nJ0+cXZKoMhS{z_MMla#!7J{-<_7FC>{o*rSBRjg@|r;j2}Pjdf! zd!5cH5TrhVUsdGs(8z!4iIq{mvN&mFRg(^8erFvFf#Xou7n^}|g8Z8bpa)hEw!@eO z*9N2AbusRCmM7{^vJfm!&W(5HA9=@A{|-7JpW-?& zt~n>qyxW*hpgd>`d*8EvezAQr^DmpD^8E(?eB%||2jd%hAV_fxVk7q)XZ_6l+q-YP zZ}F~oA=(ArF(;^%XtqGFpcYsM0|Dp3JitW|QdRW=&Qk!>{7UNp=3m+Fok4+OHn>B;ropkW?p8{t>Ymmauh{n!}wkSNulYlWUJ3o+VrMTA% z_;f?rp8Sl6c2<}kkb@dJg69FfBc5iMPw<5|en22+60Qy9EMmnGCratlI z&rgdUEN4BUDWzef*_3EBQDa(>O~ZfHJYwk+JAI7R`^1y*z+j`7 z0Xv!-b;3#j001R)MObuXVRU6WV{&C-bY%cCFflnTFf%PMGE^}(IyEsmGchYLF*-0X z!{00*0000bbVXQnWMOn=I&E)cX=Zr Date: Thu, 21 Nov 2019 19:30:27 +0100 Subject: [PATCH 003/203] - added a redirection hack for rotatesprite so that it can be transitionally used in the 2D drawer. --- source/build/src/engine.cpp | 9 +++++++ source/common/2d/v_2ddrawer.cpp | 47 +++++++++++++++++++++++++++++++++ source/common/2d/v_2ddrawer.h | 7 ++++- source/glbackend/hw_draw2d.cpp | 19 +++++++++++++ 4 files changed, 81 insertions(+), 1 deletion(-) diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 428344c19..0a9f5070e 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -11398,6 +11398,9 @@ void renderFlushPerms(void) } +bool rotatesprite_2doverride; // gross hack alert. Thanks to the insufficient abstraction the only chance to redirect rotatesprite calls + // to the 2D drawer is to use a global flag and check in rotatesprite_. +#include "v_2ddrawer.h" // // rotatesprite // @@ -11415,6 +11418,12 @@ void rotatesprite_(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, tileUpdatePicnum(&picnum, (int16_t)0xc000); if ((tilesiz[picnum].x <= 0) || (tilesiz[picnum].y <= 0)) return; + if (rotatesprite_2doverride) + { + twod.rotatesprite(sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, dablend, cx1, cy1, cx2, cy2); + return; + } + // Experimental / development bits. ONLY FOR INTERNAL USE! // bit RS_CENTERORIGIN: see dorotspr_handle_bit2 //////////////////// diff --git a/source/common/2d/v_2ddrawer.cpp b/source/common/2d/v_2ddrawer.cpp index bdc0da2f5..92b499f06 100644 --- a/source/common/2d/v_2ddrawer.cpp +++ b/source/common/2d/v_2ddrawer.cpp @@ -31,6 +31,7 @@ #include "renderstyle.h" #include "drawparms.h" #include "vectors.h" +#include "gamecvars.h" //#include "doomtype.h" #include "templates.h" //#include "r_utility.h" @@ -554,3 +555,49 @@ void F2DDrawer::Clear() mData.Clear(); mIsFirstPass = true; } + +//========================================================================== +// +// +// +//========================================================================== + + +#include "build.h" +#include "../src/engine_priv.h" + +void F2DDrawer::rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, + int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend, + int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2) +{ + if (r_rotatespritenowidescreen) + { + dastat |= RS_STRETCH; + dastat &= ~RS_ALIGN_MASK; + } + + // This is mainly a hack because the rotatesprite code is far too messed up to integrate into the 2D drawer. + // This merely stores the parameters and later just calls polymost_rotatesprite do do the work. + // Cleanup can be done once everything is working - but for the menu's transition the original calls should be preserved. + RenderCommand dg; + + dg.mType = DrawTypeRotateSprite; + + // Just store the values in the otherwise useless fields of the draw command instead of allocating separate memory. + dg.mVertIndex = sx; + dg.mVertCount = sy; + dg.mIndexIndex = z; + dg.mIndexCount = a; + dg.mSpecialColormap[0].d = picnum; + dg.mRemapIndex = dashade; + dg.mFlags = dapalnum; + dg.mSpecialColormap[1].d = dastat; + dg.mDesaturate = daalpha; + dg.mColor1.d = dablend; + dg.mScissor[0] = cx1; + dg.mScissor[1] = cy1; + dg.mScissor[2] = cx2; + dg.mScissor[3] = cy2; + mData.Push(dg); // don't even try to merge. +} + diff --git a/source/common/2d/v_2ddrawer.h b/source/common/2d/v_2ddrawer.h index 8e2d52e6e..0641d42b1 100644 --- a/source/common/2d/v_2ddrawer.h +++ b/source/common/2d/v_2ddrawer.h @@ -19,6 +19,7 @@ public: DrawTypeTriangles, DrawTypeLines, DrawTypePoints, + DrawTypeRotateSprite, }; enum ETextureFlags : uint8_t @@ -85,7 +86,7 @@ public: bool isCompatible(const RenderCommand &other) const { return mTexture == other.mTexture && - mType == other.mType && + mType == other.mType && mType != DrawTypeRotateSprite && mRemapIndex == other.mRemapIndex && mSpecialColormap[0].d == other.mSpecialColormap[0].d && mSpecialColormap[1].d == other.mSpecialColormap[1].d && @@ -122,6 +123,10 @@ public: void AddThickLine(int x1, int y1, int x2, int y2, double thickness, uint32_t color, uint8_t alpha = 255); void AddPixel(int x1, int y1, uint32_t color); + void rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, + int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend, + int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2); + void Clear(); bool mIsFirstPass = true; diff --git a/source/glbackend/hw_draw2d.cpp b/source/glbackend/hw_draw2d.cpp index 46b278652..bdd0f08f7 100644 --- a/source/glbackend/hw_draw2d.cpp +++ b/source/glbackend/hw_draw2d.cpp @@ -82,6 +82,7 @@ public: // Draws the 2D stuff. This is the version for OpenGL 3 and later. // //=========================================================================== +void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend, int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, int32_t uniqid); void GLInstance::Draw2D(F2DDrawer *drawer) { @@ -123,6 +124,24 @@ void GLInstance::Draw2D(F2DDrawer *drawer) for(auto &cmd : commands) { + if (cmd.mType == F2DDrawer::DrawTypeRotateSprite) + { + // This just gets forwarded to the original drawer. Long term this should not survive and all calls be refactored. + UseColorOnly(false); + SetFadeDisable(false); + polymost_dorotatesprite(cmd.mVertIndex, cmd.mVertCount, cmd.mIndexIndex, cmd.mIndexCount, cmd.mSpecialColormap[0].d, cmd.mRemapIndex, cmd.mFlags, cmd.mSpecialColormap[1].d, + cmd.mDesaturate, cmd.mColor1.d, cmd.mScissor[0], cmd.mScissor[1], cmd.mScissor[2], cmd.mScissor[3], 0); + // Reset everything to the default. + SetFadeDisable(true); + EnableDepthTest(false); + EnableMultisampling(false); + EnableBlend(true); + EnableAlphaTest(true); + SetBlendFunc(STYLEALPHA_Src, STYLEALPHA_InvSrc); + + continue; + } + int gltrans = -1; //state.SetRenderStyle(cmd.mRenderStyle); From 5f9b57519a94f0cdab38294f0ad3c9e5f656f8f0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 21 Nov 2019 22:31:46 +0100 Subject: [PATCH 004/203] - hooked up the menu code so that it can receive events. Nothing pretty yet but a start is made. --- source/build/src/engine.cpp | 2 ++ source/common/console/d_event.cpp | 3 +-- source/common/gamecontrol.cpp | 2 ++ source/common/menu/listmenu.cpp | 15 ++++++----- source/common/menu/menu.cpp | 18 ++++++++----- source/common/menu/menu.h | 12 ++++----- source/common/menu/menudef.cpp | 18 +++---------- source/common/menu/messagebox.cpp | 2 +- source/common/menu/optionmenu.cpp | 2 +- wadsrc/static/demolition/menudef.txt | 40 ++++++++++++++++++++++++++++ wadsrc/static/language.txt | 0 11 files changed, 76 insertions(+), 38 deletions(-) create mode 100644 wadsrc/static/demolition/menudef.txt create mode 100644 wadsrc/static/language.txt diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 0a9f5070e..d67f72f81 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -27,6 +27,7 @@ #include "v_draw.h" #include "imgui.h" #include "stats.h" +#include "menu.h" #ifdef USE_OPENGL # include "glsurface.h" @@ -10067,6 +10068,7 @@ void videoNextPage(void) // Draw the console plus debug output on top of everything else. DrawFullscreenBlends(); + M_Drawer(); FStat::PrintStat(); C_DrawConsole(); GLInterface.Draw2D(&twod); diff --git a/source/common/console/d_event.cpp b/source/common/console/d_event.cpp index 3846e5829..b61ef1948 100644 --- a/source/common/console/d_event.cpp +++ b/source/common/console/d_event.cpp @@ -25,6 +25,7 @@ #include "c_console.h" #include "d_gui.h" #include "inputstate.h" +#include "menu.h" int eventhead; int eventtail; @@ -150,10 +151,8 @@ void D_ProcessEvents (void) (void)0;//UpdateJoystickMenu(I_UpdateDeviceList()); if (C_Responder (ev)) continue; // console ate the event -#if 0 if (M_Responder (ev)) continue; // menu ate the event -#endif G_Responder (ev); } } diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index 2fabae2d1..62aefcd3e 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -23,6 +23,7 @@ #include "i_specialpaths.h" #include "z_music.h" #include "statistics.h" +#include "menu.h" #ifndef NETCODE_DISABLE #include "enet.h" #endif @@ -381,6 +382,7 @@ int CONFIG_Init() buttonMap.SetGameAliases(); Mus_Init(); InitStatistics(); + M_Init(); diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 7bcec164b..7cb389e8a 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -502,28 +502,29 @@ bool FListMenuItemSelectable::MouseEvent(int type, int x, int y) // //============================================================================= -FListMenuItemText::FListMenuItemText(int x, int y, int height, int hotkey, const char *text, FFont *font, EColorRange color, EColorRange color2, FName child, int param) +FListMenuItemText::FListMenuItemText(int x, int y, int height, int hotkey, const FString &text, FFont *font, EColorRange color, EColorRange color2, FName child, int param) : FListMenuItemSelectable(x, y, height, child, param) { mText = text; + /* mFont = font; mColor = color; mColorSelected = color2; + */ + mFont = NewSmallFont; + mColor = CR_RED; + mColorSelected = CR_GOLD; mHotkey = hotkey; } FListMenuItemText::~FListMenuItemText() { - if (mText != NULL) - { - delete [] mText; - } } void FListMenuItemText::Drawer(bool selected) { const char *text = mText; - if (text != NULL) + if (mText.Len()) { if (*text == '$') text = GStrings(text+1); DrawText(&twod, mFont, selected ? mColorSelected : mColor, mXpos, mYpos, text, DTA_Clean, true, TAG_DONE); @@ -533,7 +534,7 @@ void FListMenuItemText::Drawer(bool selected) int FListMenuItemText::GetWidth() { const char *text = mText; - if (text != NULL) + if (mText.Len()) { if (*text == '$') text = GStrings(text+1); return mFont->StringWidth(text); diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 57e9219d8..2256f7ebc 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -296,6 +296,7 @@ void M_StartControlPanel (bool makeSound) } C_HideConsole (); // [RH] Make sure console goes bye bye. + GUICapture |= 1; menuactive = MENU_On; // Pause sound effects before we play the menu switch sound. // That way, it won't be paused. @@ -416,9 +417,9 @@ void M_SetMenu(FName menu, int param) } else { - const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DListMenu) : ld->mClass; + //const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DListMenu) : ld->mClass; - DListMenu *newmenu = (DListMenu *)cls->CreateNew(); + DListMenu* newmenu = new DListMenu; newmenu->Init(DMenu::CurrentMenu, ld); M_ActivateMenu(newmenu); } @@ -426,9 +427,9 @@ void M_SetMenu(FName menu, int param) else if ((*desc)->mType == MDESC_OptionsMenu) { FOptionMenuDescriptor *ld = static_cast(*desc); - const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DOptionMenu) : ld->mClass; + //const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DOptionMenu) : ld->mClass; - DOptionMenu *newmenu = (DOptionMenu *)cls->CreateNew(); + DOptionMenu *newmenu = new DOptionMenu; newmenu->Init(DMenu::CurrentMenu, ld); M_ActivateMenu(newmenu); } @@ -649,6 +650,7 @@ bool M_Responder (event_t *ev) void M_Ticker (void) { DMenu::MenuTime++; + if (DMenu::MenuTime & 3) return; if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) { DMenu::CurrentMenu->Ticker(); @@ -685,7 +687,7 @@ void M_Ticker (void) void M_Drawer (void) { - PalEntry fade = 0;// x70000000; + PalEntry fade = 0x70000000; #if 0 player_t *player = &players[consoleplayer]; AActor *camera = player->camera; @@ -701,9 +703,9 @@ void M_Drawer (void) #endif - if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off && fade) + if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) { - if (DMenu::CurrentMenu->DimAllowed()) twod.AddColorOnlyQuad(0, 0, screen->GetWidth(), screen->GetHeight(), fade); + if (DMenu::CurrentMenu->DimAllowed() && fade) twod.AddColorOnlyQuad(0, 0, screen->GetWidth(), screen->GetHeight(), fade); DMenu::CurrentMenu->Drawer(); } } @@ -723,6 +725,7 @@ void M_ClearMenus () DMenu::CurrentMenu = NULL; } menuactive = MENU_Off; + GUICapture &= ~1; } //============================================================================= @@ -733,6 +736,7 @@ void M_ClearMenus () void M_Init (void) { + timerSetCallback(M_Ticker); M_ParseMenuDefs(); M_CreateMenus(); } diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 8d70dac72..874a7768d 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -96,7 +96,7 @@ struct FMenuDescriptor FName mMenuName; FString mNetgameMessage; int mType; - const PClass *mClass; + FName mClass; virtual ~FMenuDescriptor() {} }; @@ -399,12 +399,12 @@ public: class FListMenuItemText : public FListMenuItemSelectable { - const char *mText; + FString mText; FFont *mFont; EColorRange mColor; EColorRange mColorSelected; public: - FListMenuItemText(int x, int y, int height, int hotkey, const char *text, FFont *font, EColorRange color, EColorRange color2, FName child, int param = 0); + FListMenuItemText(int x, int y, int height, int hotkey, const FString &text, FFont *font, EColorRange color, EColorRange color2, FName child, int param = 0); ~FListMenuItemText(); void Drawer(bool selected); int GetWidth(); @@ -430,8 +430,8 @@ class DListMenu : public DMenu DECLARE_CLASS(DListMenu, DMenu) protected: - FListMenuDescriptor *mDesc; - FListMenuItem *mFocusControl; + FListMenuDescriptor *mDesc = nullptr; + FListMenuItem *mFocusControl = nullptr; public: DListMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); @@ -467,7 +467,7 @@ class FOptionMenuItem : public FListMenuItem { protected: FString mLabel; - bool mCentered; + bool mCentered = false; void drawLabel(int indent, int y, EColorRange color, bool grayed = false); public: diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 4f1f5939b..40023216c 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -241,12 +241,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) else if (sc.Compare("Class")) { sc.MustGetString(); - const PClass *cls = PClass::FindClass(sc.String); - if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(DListMenu))) - { - sc.ScriptError("Unknown menu class '%s'", sc.String); - } - desc->mClass = cls; + desc->mClass = sc.String; } else if (sc.Compare("Selector")) { @@ -428,8 +423,8 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) static bool CheckCompatible(FMenuDescriptor *newd, FMenuDescriptor *oldd) { - if (oldd->mClass == NULL) return true; - return oldd->mClass == newd->mClass; + /*if (oldd->mClass == NULL)*/ return true; + //return oldd->mClass == newd->mClass; } static bool ReplaceMenu(FScanner &sc, FMenuDescriptor *desc) @@ -629,12 +624,7 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) else if (sc.Compare("Class")) { sc.MustGetString(); - const PClass *cls = PClass::FindClass(sc.String); - if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(DOptionMenu))) - { - sc.ScriptError("Unknown menu class '%s'", sc.String); - } - desc->mClass = cls; + desc->mClass = sc.String; } else if (sc.Compare("Title")) { diff --git a/source/common/menu/messagebox.cpp b/source/common/menu/messagebox.cpp index f568553f5..f0f17576d 100644 --- a/source/common/menu/messagebox.cpp +++ b/source/common/menu/messagebox.cpp @@ -203,7 +203,7 @@ void DMessageBoxMenu::Drawer () if (messageSelection >= 0) { - if ((DMenu::MenuTime%8) < 6) + if (((DMenu::MenuTime>>2)%8) < 6) { DrawText(&twod, ConFont, OptionSettings.mFontColorSelection, (150 - 160) * CleanXfac + screen->GetWidth() / 2, diff --git a/source/common/menu/optionmenu.cpp b/source/common/menu/optionmenu.cpp index bbe1d278f..1eb6b7981 100644 --- a/source/common/menu/optionmenu.cpp +++ b/source/common/menu/optionmenu.cpp @@ -444,7 +444,7 @@ void DOptionMenu::Drawer () int cur_indent = mDesc->mItems[i]->Draw(mDesc, y, indent, isSelected); if (cur_indent >= 0 && isSelected && mDesc->mItems[i]->Selectable()) { - if (((DMenu::MenuTime%8) < 6) || DMenu::CurrentMenu != this) + if ((((DMenu::MenuTime>>2)%8) < 6) || DMenu::CurrentMenu != this) { M_DrawConText(OptionSettings.mFontColorSelection, cur_indent + 3 * CleanXfac_1, y+fontheight-9*CleanYfac_1, "\xd"); } diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt new file mode 100644 index 000000000..838c4a6fa --- /dev/null +++ b/wadsrc/static/demolition/menudef.txt @@ -0,0 +1,40 @@ +//------------------------------------------------------------------------------------------- +// +// Text only variant of the main menu for Doom, Strife and Chex Quest to be used with localized content. +// +//------------------------------------------------------------------------------------------- + +LISTMENU "MainMenu" +{ + linespacing 15 + TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + TextItem "$MNU_OPTIONS", "o", "OptionsMenu" + TextItem "$MNU_HELP", "h", "HelpMenu" + TextItem "$MNU_CREDITS", "c", "CreditsMenu" + TextItem "$MNU_QUITGAME", "q", "QuitMenu" +} + +LISTMENU "MainMenu_Blood" +{ + linespacing 15 + TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + TextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" + TextItem "$MNU_OPTIONS", "o", "OptionsMenu" + TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + TextItem "$MNU_HELP", "h", "HelpMenu" + TextItem "$MNU_CREDITS", "c", "CreditsMenu" + TextItem "$MNU_QUITGAME", "q", "QuitMenu" +} + +LISTMENU "MainMenu_SW" +{ + linespacing 15 + TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + TextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" + TextItem "$MNU_OPTIONS", "o", "OptionsMenu" + TextItem "$MNU_COOLSTUFF", "h", "HelpMenu" + TextItem "$MNU_QUITGAME", "q", "QuitMenu" +} + diff --git a/wadsrc/static/language.txt b/wadsrc/static/language.txt new file mode 100644 index 000000000..e69de29bb From ceb07280cf56e09e27cdadc4174c61be487aefc3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 22 Nov 2019 22:52:11 +0100 Subject: [PATCH 005/203] - more work on the menu. Duke Nukem's menu title is getting rendered. --- source/common/dobject/dobject.cpp | 3 + source/common/dobject/dobject.h | 3 + source/common/dobject/dobjtype.cpp | 2 + source/common/menu/joystickmenu.cpp | 2 - source/common/menu/listmenu.cpp | 4 +- source/common/menu/loadsavemenu.cpp | 15 +-- source/common/menu/menu.cpp | 36 ++++++- source/common/menu/menu.h | 47 +++++++-- source/common/menu/menudef.cpp | 12 ++- source/common/menu/menuinput.cpp | 2 - source/common/menu/messagebox.cpp | 4 +- source/common/menu/optionmenu.cpp | 1 - source/common/menu/optionmenuitems.h | 8 +- source/common/menu/readthis.cpp | 2 - source/duke3d/CMakeLists.txt | 3 +- source/duke3d/src/d_menu.cpp | 146 +++++++++++++++++++++++++++ source/duke3d/src/game.h | 24 ----- source/duke3d/src/menus.cpp | 11 +- source/glbackend/hw_draw2d.cpp | 4 + wadsrc/static/demolition/menudef.txt | 81 +++++++++------ 20 files changed, 302 insertions(+), 108 deletions(-) create mode 100644 source/duke3d/src/d_menu.cpp diff --git a/source/common/dobject/dobject.cpp b/source/common/dobject/dobject.cpp index d926251e1..98b8105fe 100644 --- a/source/common/dobject/dobject.cpp +++ b/source/common/dobject/dobject.cpp @@ -37,6 +37,8 @@ #include "dobject.h" +#if 0 + PClass DObject::_StaticType; ClassReg DObject::RegistrationInfo = { @@ -71,3 +73,4 @@ DObject::~DObject () void DObject::Destroy () { } +#endif \ No newline at end of file diff --git a/source/common/dobject/dobject.h b/source/common/dobject/dobject.h index 0b2b3dc70..502f3c35b 100644 --- a/source/common/dobject/dobject.h +++ b/source/common/dobject/dobject.h @@ -34,6 +34,8 @@ #ifndef __DOBJECT_H__ #define __DOBJECT_H__ +#if 0 + #include struct PClass; @@ -176,4 +178,5 @@ inline bool DObject::IsA (const PClass *type) return (type == GetClass()); } +#endif #endif //__DOBJECT_H__ diff --git a/source/common/dobject/dobjtype.cpp b/source/common/dobject/dobjtype.cpp index d77f711bc..6f4d50485 100644 --- a/source/common/dobject/dobjtype.cpp +++ b/source/common/dobject/dobjtype.cpp @@ -38,6 +38,7 @@ #include "templates.h" #include "autosegs.h" #include "tarray.h" +#if 0 static TArray Types; static TMap Map; @@ -102,3 +103,4 @@ DObject *PClass::CreateNew () const ((DObject *)mem)->SetClass (const_cast(this)); return (DObject *)mem; } +#endif \ No newline at end of file diff --git a/source/common/menu/joystickmenu.cpp b/source/common/menu/joystickmenu.cpp index bd9dfabf3..18a1e5af6 100644 --- a/source/common/menu/joystickmenu.cpp +++ b/source/common/menu/joystickmenu.cpp @@ -226,10 +226,8 @@ public: class DJoystickConfigMenu : public DOptionMenu { - DECLARE_CLASS(DJoystickConfigMenu, DOptionMenu) }; -IMPLEMENT_CLASS(DJoystickConfigMenu) //============================================================================= // diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 7cb389e8a..d7b31e52d 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -40,8 +40,6 @@ #include "menu.h" #include "v_draw.h" -IMPLEMENT_CLASS(DListMenu) - //============================================================================= // // @@ -253,12 +251,14 @@ void DListMenu::Ticker () void DListMenu::Drawer () { + PreDraw(); for(unsigned i=0;imItems.Size(); i++) { if (mDesc->mItems[i]->mEnabled) mDesc->mItems[i]->Drawer(mDesc->mSelectedItem == (int)i); } if (mDesc->mSelectedItem >= 0 && mDesc->mSelectedItem < (int)mDesc->mItems.Size()) mDesc->mItems[mDesc->mSelectedItem]->DrawSelector(mDesc->mSelectOfsX, mDesc->mSelectOfsY, mDesc->mSelector); + PostDraw(); Super::Drawer(); } diff --git a/source/common/menu/loadsavemenu.cpp b/source/common/menu/loadsavemenu.cpp index 20c5f6caf..12f527aef 100644 --- a/source/common/menu/loadsavemenu.cpp +++ b/source/common/menu/loadsavemenu.cpp @@ -48,7 +48,7 @@ class DLoadSaveMenu : public DListMenu { - DECLARE_CLASS(DLoadSaveMenu, DListMenu) + using Super = DListMenu; friend void ClearSaveGames(); protected: @@ -109,8 +109,6 @@ public: }; -IMPLEMENT_CLASS(DLoadSaveMenu) - TArray DLoadSaveMenu::SaveGames; int DLoadSaveMenu::LastSaved = -1; int DLoadSaveMenu::LastAccessed = -1; @@ -723,8 +721,7 @@ bool DLoadSaveMenu::Responder (event_t *ev) class DSaveMenu : public DLoadSaveMenu { - DECLARE_CLASS(DSaveMenu, DLoadSaveMenu) - + using Super = DLoadSaveMenu; FSaveGameNode NewSaveNode; public: @@ -737,9 +734,6 @@ public: }; -IMPLEMENT_CLASS(DSaveMenu) - - //============================================================================= // // @@ -895,7 +889,7 @@ bool DSaveMenu::Responder (event_t *ev) class DLoadMenu : public DLoadSaveMenu { - DECLARE_CLASS(DLoadMenu, DLoadSaveMenu) + using Super = DLoadSaveMenu; public: @@ -904,9 +898,6 @@ public: bool MenuEvent (int mkey, bool fromcontroller); }; -IMPLEMENT_CLASS(DLoadMenu) - - //============================================================================= // // diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 2256f7ebc..e47190369 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -49,6 +49,9 @@ #include "v_draw.h" #include "gamecontrol.h" +void RegisterDukeMenus(); +extern bool rotatesprite_2doverride; + // // Todo: Move these elsewhere // @@ -60,6 +63,8 @@ CVAR (Float, snd_menuvolume, 0.6f, CVAR_ARCHIVE) CVAR(Int, m_use_mouse, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Int, m_show_backbutton, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +TArray menuClasses(TArray::ENoInit(0)); + DMenu *DMenu::CurrentMenu; int DMenu::MenuTime; @@ -69,7 +74,7 @@ bool M_DemoNoPlay; FButtonStatus MenuButtons[NUM_MKEYS]; int MenuButtonTickers[NUM_MKEYS]; bool MenuButtonOrigin[NUM_MKEYS]; -int BackbuttonTime; +int BackbuttonTime; float BackbuttonAlpha; static bool MenuEnabled = true; @@ -83,7 +88,6 @@ static bool MenuEnabled = true; // //============================================================================ -IMPLEMENT_CLASS (DMenu) DMenu::DMenu(DMenu *parent) { @@ -164,6 +168,7 @@ void DMenu::Close () assert(DMenu::CurrentMenu == this); DMenu::CurrentMenu = mParentMenu; Destroy(); + delete this; if (DMenu::CurrentMenu == NULL) { M_ClearMenus (); @@ -417,9 +422,23 @@ void M_SetMenu(FName menu, int param) } else { - //const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DListMenu) : ld->mClass; - - DListMenu* newmenu = new DListMenu; + DListMenu* newmenu; + if (ld->mClass != NAME_None) + { + auto ndx = menuClasses.FindEx([=](const auto p) { return p->mName == ld->mClass; }); + if (ndx == menuClasses.Size()) + { + I_Error("Bad menu class %s\n", ld->mClass.GetChars()); + } + else + { + newmenu = (DListMenu*)menuClasses[ndx]->CreateNew(); + } + } + else + { + newmenu = new DListMenu; + } newmenu->Init(DMenu::CurrentMenu, ld); M_ActivateMenu(newmenu); } @@ -437,6 +456,7 @@ void M_SetMenu(FName menu, int param) } else { + /* const PClass *menuclass = PClass::FindClass(menu); if (menuclass != NULL) { @@ -448,6 +468,7 @@ void M_SetMenu(FName menu, int param) return; } } + */ } Printf("Attempting to open menu of unknown type '%s'\n", menu.GetChars()); } @@ -687,6 +708,7 @@ void M_Ticker (void) void M_Drawer (void) { + rotatesprite_2doverride = true; PalEntry fade = 0x70000000; #if 0 player_t *player = &players[consoleplayer]; @@ -705,9 +727,11 @@ void M_Drawer (void) if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) { + DMenu::CurrentMenu->origin = { 0,0 }; if (DMenu::CurrentMenu->DimAllowed() && fade) twod.AddColorOnlyQuad(0, 0, screen->GetWidth(), screen->GetHeight(), fade); DMenu::CurrentMenu->Drawer(); } + rotatesprite_2doverride = false; } //============================================================================= @@ -722,6 +746,7 @@ void M_ClearMenus () if (DMenu::CurrentMenu != NULL) { DMenu::CurrentMenu->Destroy(); + delete DMenu::CurrentMenu; DMenu::CurrentMenu = NULL; } menuactive = MENU_Off; @@ -736,6 +761,7 @@ void M_ClearMenus () void M_Init (void) { + RegisterDukeMenus(); timerSetCallback(M_Ticker); M_ParseMenuDefs(); M_CreateMenus(); diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 874a7768d..b1aaddb65 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -4,7 +4,6 @@ -#include "dobject.h" #include "c_cvars.h" #include "v_font.h" #include "version.h" @@ -107,6 +106,7 @@ class FOptionMenuItem; struct FListMenuDescriptor : public FMenuDescriptor { TDeletingArray mItems; + FString mCaption; int mSelectedItem; int mSelectOfsX; int mSelectOfsY; @@ -116,6 +116,8 @@ struct FListMenuDescriptor : public FMenuDescriptor int mWLeft, mWRight; int mLinespacing; // needs to be stored for dynamically created menus int mAutoselect; // this can only be set by internal menu creation functions + int mScriptId; + int mSecondaryId; FFont *mFont; EColorRange mFontColor; EColorRange mFontColor2; @@ -136,6 +138,8 @@ struct FListMenuDescriptor : public FMenuDescriptor mFont = NULL; mFontColor = CR_UNTRANSLATED; mFontColor2 = CR_UNTRANSLATED; + mScriptId = 0; + mSecondaryId = 0; } }; @@ -211,10 +215,8 @@ struct FMenuRect }; -class DMenu : public DObject +class DMenu { - DECLARE_CLASS (DMenu, DObject) - protected: bool mMouseCapture; bool mBackbuttonSelected; @@ -236,19 +238,24 @@ public: static int MenuTime; DMenu *mParentMenu; + vec2_t origin; DMenu(DMenu *parent = NULL); virtual bool Responder (event_t *ev); virtual bool MenuEvent (int mkey, bool fromcontroller); virtual void Ticker (); + virtual void PreDraw() {} + virtual void PostDraw() {} virtual void Drawer (); virtual bool DimAllowed (); virtual bool TranslateKeyboardEvents(); virtual void Close(); virtual bool MouseEvent(int type, int x, int y); + virtual void Destroy() {} bool MouseEventBack(int type, int x, int y); void SetCapture(); void ReleaseCapture(); + void SetOrigin(); bool HasCapture() { return mMouseCapture; @@ -427,8 +434,7 @@ public: class DListMenu : public DMenu { - DECLARE_CLASS(DListMenu, DMenu) - + typedef DMenu Super; protected: FListMenuDescriptor *mDesc = nullptr; FListMenuItem *mFocusControl = nullptr; @@ -516,8 +522,7 @@ extern FOptionMap OptionValues; class DOptionMenu : public DMenu { - DECLARE_CLASS(DOptionMenu, DMenu) - + using Super = DMenu; bool CanScrollUp; bool CanScrollDown; int VisBottom; @@ -560,8 +565,7 @@ public: class DTextEnterMenu : public DMenu { - DECLARE_ABSTRACT_CLASS(DTextEnterMenu, DMenu) - + using Super = DMenu; TArray mEnterString; FString* mOutString; unsigned int mEnterSize; @@ -611,5 +615,28 @@ void M_StartMessage(const char *message, int messagemode, FName action = NAME_No void I_SetMouseCapture(); void I_ReleaseMouseCapture(); +struct MenuClassDescriptor; +extern TArray menuClasses; + +struct MenuClassDescriptor +{ + FName mName; + MenuClassDescriptor(const char* name) : mName(name) + { + //menuClasses.Push(this); + } + + virtual DMenu* CreateNew() = 0; +}; + +template struct TMenuClassDescriptor : public MenuClassDescriptor +{ + TMenuClassDescriptor(const char* name) : MenuClassDescriptor(name) + {} + DMenu* CreateNew() + { + return new Menu; + } +}; #endif \ No newline at end of file diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 40023216c..dbb1f7ab6 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -133,7 +133,7 @@ struct gamefilter static const gamefilter games[] = { { "Duke", GAMEFLAG_DUKE}, - { "Nam", GAMEFLAG_NAM}, + { "Nam", GAMEFLAG_NAM|GAMEFLAG_NAPALM}, { "WW2GI", GAMEFLAG_WW2GI}, { "Fury", GAMEFLAG_FURY}, { "Redneck", GAMEFLAG_RR}, @@ -294,6 +294,16 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) FListMenuItem *it = new FListMenuItemStaticPatch(x, y, tex, centered); desc->mItems.Push(it); } + else if (sc.Compare("ScriptId")) + { + sc.MustGetNumber(); + desc->mScriptId = sc.Number; + } + else if (sc.Compare("Caption")) + { + sc.MustGetString(); + desc->mCaption = sc.String; + } else if (sc.Compare("StaticText") || sc.Compare("StaticTextCentered")) { bool centered = sc.Compare("StaticTextCentered"); diff --git a/source/common/menu/menuinput.cpp b/source/common/menu/menuinput.cpp index b355b905b..2a5b2faff 100644 --- a/source/common/menu/menuinput.cpp +++ b/source/common/menu/menuinput.cpp @@ -41,8 +41,6 @@ #include "v_text.h" #include "v_draw.h" -IMPLEMENT_ABSTRACT_CLASS(DTextEnterMenu) - #define INPUTGRID_WIDTH 13 #define INPUTGRID_HEIGHT 5 diff --git a/source/common/menu/messagebox.cpp b/source/common/menu/messagebox.cpp index f0f17576d..99cc86160 100644 --- a/source/common/menu/messagebox.cpp +++ b/source/common/menu/messagebox.cpp @@ -46,8 +46,7 @@ extern FSaveGameNode *quickSaveSlot; class DMessageBoxMenu : public DMenu { - DECLARE_CLASS(DMessageBoxMenu, DMenu) - + using Super = DMenu; TArray mMessage; int mMessageMode; int messageSelection; @@ -67,7 +66,6 @@ public: virtual void HandleResult(bool res); }; -IMPLEMENT_CLASS(DMessageBoxMenu) //============================================================================= // diff --git a/source/common/menu/optionmenu.cpp b/source/common/menu/optionmenu.cpp index 1eb6b7981..e8bf2f42d 100644 --- a/source/common/menu/optionmenu.cpp +++ b/source/common/menu/optionmenu.cpp @@ -62,7 +62,6 @@ void M_DrawConText (int color, int x, int y, const char *str) } -IMPLEMENT_CLASS(DOptionMenu) //============================================================================= // diff --git a/source/common/menu/optionmenuitems.h b/source/common/menu/optionmenuitems.h index bc0b443fb..fd115b398 100644 --- a/source/common/menu/optionmenuitems.h +++ b/source/common/menu/optionmenuitems.h @@ -322,8 +322,6 @@ public: class DEnterKey : public DMenu { - DECLARE_CLASS(DEnterKey, DMenu) - int *pKey; public: @@ -342,6 +340,7 @@ public: void SetMenuMessage(int which) { + /* if (mParentMenu->IsKindOf(RUNTIME_CLASS(DOptionMenu))) { DOptionMenu *m = static_cast(mParentMenu); @@ -351,6 +350,7 @@ public: it->SetValue(0, which); } } + */ } bool Responder(event_t *ev) @@ -373,10 +373,6 @@ public: } }; -#ifndef NO_IMP -IMPLEMENT_ABSTRACT_CLASS(DEnterKey) -#endif - //============================================================================= // // // Edit a key binding, Action is the CCMD to bind diff --git a/source/common/menu/readthis.cpp b/source/common/menu/readthis.cpp index 43d981822..c68cf5751 100644 --- a/source/common/menu/readthis.cpp +++ b/source/common/menu/readthis.cpp @@ -41,7 +41,6 @@ class DReadThisMenu : public DMenu { - DECLARE_CLASS(DReadThisMenu, DMenu) int mScreen; int mInfoTic; @@ -54,7 +53,6 @@ public: bool MouseEvent(int type, int x, int y); }; -IMPLEMENT_CLASS(DReadThisMenu) //============================================================================= // diff --git a/source/duke3d/CMakeLists.txt b/source/duke3d/CMakeLists.txt index c0619e2cb..b3169684e 100644 --- a/source/duke3d/CMakeLists.txt +++ b/source/duke3d/CMakeLists.txt @@ -62,8 +62,9 @@ set( PCH_SOURCES src/sector.cpp src/sounds.cpp src/soundsdyn.cpp + src/d_menu.cpp ) - + if( MSVC ) enable_precompiled_headers( ../g_pch.h PCH_SOURCES ) # The original Build code was written with unsigned chars and unfortunately they still haven't been eliminated entirely. diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp new file mode 100644 index 000000000..356464116 --- /dev/null +++ b/source/duke3d/src/d_menu.cpp @@ -0,0 +1,146 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2016 EDuke32 developers and contributors +Copyright (C) 2019 Christoph Oelckers + +This is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +//------------------------------------------------------------------------- + +#include "ns.h" // Must come before everything else! + +#include "cheats.h" +#include "compat.h" +#include "demo.h" +#include "duke3d.h" +#include "input.h" +#include "menus.h" +#include "osdcmds.h" +#include "savegame.h" +#include "game.h" +#include "superfasthash.h" +#include "gamecvars.h" +#include "gamecontrol.h" +#include "c_bind.h" +#include "menu/menu.h" +#include "../../glbackend/glbackend.h" + +BEGIN_DUKE_NS + +#define MENU_MARGIN_REGULAR 40 +#define MENU_MARGIN_WIDE 32 +#define MENU_MARGIN_CENTER 160 +#define MENU_HEIGHT_CENTER 100 + + +static void Menu_DrawTopBar(const vec2_t origin) +{ + if ((G_GetLogoFlags() & LOGO_NOTITLEBAR) == 0) + rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (19<<16), MF_Redfont.cursorScale, 0,MENUBAR,16,0,10); +} + +static void Menu_DrawTopBarCaption(const char *caption, const vec2_t origin) +{ + static char t[64]; + size_t const srclen = strlen(caption); + size_t const dstlen = min(srclen, ARRAY_SIZE(t)-1); + memcpy(t, caption, dstlen); + t[dstlen] = '\0'; + char *p = &t[dstlen-1]; + if (*p == ':') + *p = '\0'; + captionmenutext(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (24<<16) + ((15>>1)<<16), t); +} + + + +class DukeListMenu : public DListMenu +{ + using Super = DListMenu; +protected: + + virtual void CallScript(int event, bool getorigin = false) + { + ud.returnvar[0] = origin.x; + ud.returnvar[1] = origin.y; + ud.returnvar[2] = mDesc->mSelectedItem; + VM_OnEventWithReturn(event, g_player[screenpeek].ps->i, screenpeek, mDesc->mScriptId); + if (getorigin) + { + origin.x = ud.returnvar[0]; + origin.y = ud.returnvar[1]; + } + } + + void PreDraw() override + { + CallScript(CurrentMenu == this ? EVENT_DISPLAYMENU : EVENT_DISPLAYMENUREST, true); + } + + void PostDraw() override + { + CallScript(CurrentMenu == this ? EVENT_DISPLAYMENUREST : EVENT_DISPLAYINACTIVEMENUREST, false); + } + + void Drawer() override + { + auto v = origin; + Super::Drawer(); + origin = v; + } +}; + +class DukeNewGameCustomSubMenu : public DukeListMenu +{ + virtual void CallScript(int event, bool getorigin) override + { + // This needs to get the secondary ID to the script. + ud.returnvar[3] = mDesc->mSecondaryId; + DukeListMenu::CallScript(event, getorigin); + } +}; + +class MainMenu : public DukeListMenu +{ + void PreDraw() override + { + DukeListMenu::PreDraw(); + if ((G_GetLogoFlags() & LOGO_NOGAMETITLE) == 0) + { + rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + ((28)<<16), 65536L,0,INGAMEDUKETHREEDEE,0,0,10); + if (PLUTOPAK) // JBF 20030804 + rotatesprite_fs(origin.x + ((MENU_MARGIN_CENTER+100)<<16), origin.y + (36<<16), 65536L,0,PLUTOPAKSPRITE+2,(sintable[((int32_t) totalclock<<4)&2047]>>11),0,2+8); + } + else if (mDesc->mCaption.IsNotEmpty()) + { + Menu_DrawTopBar(origin); + Menu_DrawTopBarCaption(mDesc->mCaption, origin); + } + } +}; + + +END_DUKE_NS + +static TMenuClassDescriptor _mm("Duke.MainMenu"); +static TMenuClassDescriptor _lm("Duke.ListMenu"); +static TMenuClassDescriptor _ngcsm("Duke.NewGameCustomSubMenu"); + +void RegisterDukeMenus() +{ + menuClasses.Push(&_mm); + menuClasses.Push(&_lm); + menuClasses.Push(&_ngcsm); +} diff --git a/source/duke3d/src/game.h b/source/duke3d/src/game.h index cf89ab514..e71d6a899 100644 --- a/source/duke3d/src/game.h +++ b/source/duke3d/src/game.h @@ -118,32 +118,12 @@ void A_DeleteSprite(int spriteNum); static inline int32_t G_GetLogoFlags(void) { -#if !defined LUNATIC return Gv_GetVarByLabel("LOGO_FLAGS",255, -1, -1); -#else - extern int32_t g_logoFlags; - return g_logoFlags; -#endif } -#ifdef LUNATIC -typedef struct { - vec3_t pos; - int32_t dist, clock; - fix16_t q16horiz, q16ang; - int16_t sect; -} camera_t; - -extern camera_t g_camera; - -# define CAMERA(Membname) (g_camera.Membname) -# define CAMERADIST (g_camera.dist) -# define CAMERACLOCK (g_camera.clock) -#else # define CAMERA(Membname) (ud.camera ## Membname) # define CAMERADIST g_cameraDistance # define CAMERACLOCK g_cameraClock -#endif #endif @@ -155,9 +135,7 @@ extern camera_t g_camera; #define MAX_RETURN_VALUES 6 typedef struct { -#if !defined LUNATIC vec3_t camerapos; -#endif int32_t const_visibility,uw_framerate; int32_t camera_time,folfvel,folavel,folx,foly,fola; int32_t reccnt; @@ -188,10 +166,8 @@ typedef struct { uint32_t userbytever; -#if !defined LUNATIC fix16_t cameraq16ang, cameraq16horiz; int16_t camerasect; -#endif int16_t pause_on,from_bonus; int16_t camerasprite,last_camsprite; int16_t last_level,secretlevel; diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index 785b1b465..02e20a3f9 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -1603,16 +1603,13 @@ void Menu_Init(void) MEOS_NETOPTIONS_LEVEL[i].optionNames = MEOSN_NetLevels[i]; } M_EPISODE.numEntries = g_volumeCnt+2; -#ifndef EDUKE32_SIMPLE_MENU - MEL_EPISODE[g_volumeCnt] = &ME_Space4_Redfont; + + MEL_EPISODE[g_volumeCnt] = &ME_Space4_Redfont; MEL_EPISODE[g_volumeCnt+1] = &ME_EPISODE_USERMAP; MEOSN_NetEpisodes[k] = MenuUserMap; MEOSV_NetEpisodes[k] = MAXVOLUMES; -#else - M_EPISODE.numEntries = g_volumeCnt; - k--; -#endif - MEOS_NETOPTIONS_EPISODE.numOptions = k + 1; + + MEOS_NETOPTIONS_EPISODE.numOptions = k + 1; NetEpisode = MEOSV_NetEpisodes[0]; MMF_Top_Episode.pos.y = (58 + (3-k)*6)<<16; if (g_skillCnt == 0) diff --git a/source/glbackend/hw_draw2d.cpp b/source/glbackend/hw_draw2d.cpp index bdd0f08f7..460466ffe 100644 --- a/source/glbackend/hw_draw2d.cpp +++ b/source/glbackend/hw_draw2d.cpp @@ -129,6 +129,8 @@ void GLInstance::Draw2D(F2DDrawer *drawer) // This just gets forwarded to the original drawer. Long term this should not survive and all calls be refactored. UseColorOnly(false); SetFadeDisable(false); + SetVertexBuffer(nullptr, 0, 0); + SetIndexBuffer(nullptr); polymost_dorotatesprite(cmd.mVertIndex, cmd.mVertCount, cmd.mIndexIndex, cmd.mIndexCount, cmd.mSpecialColormap[0].d, cmd.mRemapIndex, cmd.mFlags, cmd.mSpecialColormap[1].d, cmd.mDesaturate, cmd.mColor1.d, cmd.mScissor[0], cmd.mScissor[1], cmd.mScissor[2], cmd.mScissor[3], 0); // Reset everything to the default. @@ -138,6 +140,8 @@ void GLInstance::Draw2D(F2DDrawer *drawer) EnableBlend(true); EnableAlphaTest(true); SetBlendFunc(STYLEALPHA_Src, STYLEALPHA_InvSrc); + SetVertexBuffer(vb.GetBufferObjects().first, 0, 0); + SetIndexBuffer(vb.GetBufferObjects().second); continue; } diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 838c4a6fa..402209124 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -6,35 +6,56 @@ LISTMENU "MainMenu" { - linespacing 15 - TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" - TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" - TextItem "$MNU_OPTIONS", "o", "OptionsMenu" - TextItem "$MNU_HELP", "h", "HelpMenu" - TextItem "$MNU_CREDITS", "c", "CreditsMenu" - TextItem "$MNU_QUITGAME", "q", "QuitMenu" -} - -LISTMENU "MainMenu_Blood" -{ - linespacing 15 - TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" - TextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" - TextItem "$MNU_OPTIONS", "o", "OptionsMenu" - TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" - TextItem "$MNU_HELP", "h", "HelpMenu" - TextItem "$MNU_CREDITS", "c", "CreditsMenu" - TextItem "$MNU_QUITGAME", "q", "QuitMenu" -} - -LISTMENU "MainMenu_SW" -{ - linespacing 15 - TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" - TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" - TextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" - TextItem "$MNU_OPTIONS", "o", "OptionsMenu" - TextItem "$MNU_COOLSTUFF", "h", "HelpMenu" - TextItem "$MNU_QUITGAME", "q", "QuitMenu" + ifgame(Duke, Nam, WW2GI, Fury) + { + linespacing 15 + class "Duke.MainMenu" + TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + //TextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) + ifgame(fury) + { + TextItem "$MNU_CONTINUE", "l", "LoadGameMenu" + } + else + { + TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + } + TextItem "$MNU_OPTIONS", "o", "OptionsMenu" + TextItem "$MNU_HELP", "h", "HelpMenu" + TextItem "$MNU_CREDITS", "c", "CreditsMenu" + TextItem "$MNU_QUITGAME", "q", "QuitMenu" + } + ifgame(Redneck, RedneckRides) + { + linespacing 15 + TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + //TextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) + TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + TextItem "$MNU_OPTIONS", "o", "OptionsMenu" + TextItem "$MNU_HELP", "h", "HelpMenu" + TextItem "$MNU_CREDITS", "c", "CreditsMenu" + TextItem "$MNU_QUITGAME", "q", "QuitMenu" + } + ifgame(Blood) + { + linespacing 15 + TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + TextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" + TextItem "$MNU_OPTIONS", "o", "OptionsMenu" + TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + TextItem "$MNU_HELP", "h", "HelpMenu" + TextItem "$MNU_CREDITS", "c", "CreditsMenu" + TextItem "$MNU_QUITGAME", "q", "QuitMenu" + } + ifgame(ShadowWarrior) + { + linespacing 15 + TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + TextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" + TextItem "$MNU_OPTIONS", "o", "OptionsMenu" + TextItem "$MNU_COOLSTUFF", "h", "HelpMenu" + TextItem "$MNU_QUITGAME", "q", "QuitMenu" + } } From f2fc3fc2cb15dc78a2d980e6e6e91ce2f7dd0c62 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 23 Nov 2019 12:38:38 +0100 Subject: [PATCH 006/203] - WIP commit. --- source/build/include/baselayer.h | 11 ++ source/common/fonts/v_font.cpp | 2 +- source/common/gamecontrol.cpp | 2 + source/common/menu/listmenu.cpp | 59 +++++++++- source/common/menu/menu.h | 107 ++++++++---------- source/common/menu/menudef.cpp | 88 ++++++++++++-- source/common/utility/stringtable.cpp | 4 +- source/duke3d/src/duke3d.h | 6 + source/duke3d/src/menus.cpp | 16 --- source/rr/src/menus.cpp | 30 ----- wadsrc/static/demolition/language.csv | 13 +++ wadsrc/static/demolition/menudef.txt | 68 ++++++----- wadsrc/static/{ => demolition}/textcolors.txt | 0 wadsrc/static/language.txt | 0 14 files changed, 248 insertions(+), 158 deletions(-) create mode 100644 wadsrc/static/demolition/language.csv rename wadsrc/static/{ => demolition}/textcolors.txt (100%) delete mode 100644 wadsrc/static/language.txt diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 2e0cb6ce2..864b1cd09 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -168,6 +168,14 @@ struct GameStats int timesecnd; }; +enum ETextOrientation +{ + TOR_Default, + TOR_Left, + TOR_Center, + TOR_Right +}; + struct GameInterface { virtual ~GameInterface() {} @@ -179,6 +187,9 @@ struct GameInterface virtual bool mouseInactiveConditional(bool condition) { return condition; } virtual FString statFPS() { return "FPS display not available"; } virtual GameStats getStats() { return {}; } + virtual void DrawNativeMenuText(int fontnum, int palnum, int xpos, int ypos, float fontscale, const char* text, int orientation = TOR_Default) {} + virtual int GetMenuFontHeight(int fontnum) { return 16; /* something arbitrarily non-zero */ } + virtual int GetMenuTextWidth(int fontnum, const char* text) { return 10 * strlen(text); } }; extern GameInterface* gi; diff --git a/source/common/fonts/v_font.cpp b/source/common/fonts/v_font.cpp index b8d381414..7bb57e7c7 100644 --- a/source/common/fonts/v_font.cpp +++ b/source/common/fonts/v_font.cpp @@ -403,7 +403,7 @@ void V_InitFontColors () TranslationLookup.Clear(); TranslationColors.Clear(); - while ((lump = fileSystem.Iterate("textcolors.txt", &lastlump)) != -1) + while ((lump = fileSystem.Iterate("demolition/textcolors.txt", &lastlump)) != -1) { FScanner sc(lump); while (sc.GetString()) diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index 62aefcd3e..d6f32708e 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -24,6 +24,7 @@ #include "z_music.h" #include "statistics.h" #include "menu.h" +#include "gstrings.h" #ifndef NETCODE_DISABLE #include "enet.h" #endif @@ -378,6 +379,7 @@ int CONFIG_Init() { playername = userConfig.CommandName; } + GStrings.LoadStrings(); V_InitFonts(); buttonMap.SetGameAliases(); Mus_Init(); diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index d7b31e52d..0264808e4 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -39,6 +39,7 @@ #include "d_event.h" #include "menu.h" #include "v_draw.h" +#include "baselayer.h" //============================================================================= // @@ -254,10 +255,14 @@ void DListMenu::Drawer () PreDraw(); for(unsigned i=0;imItems.Size(); i++) { - if (mDesc->mItems[i]->mEnabled) mDesc->mItems[i]->Drawer(mDesc->mSelectedItem == (int)i); + auto o = origin; + if (mDesc->mItems[i]->mEnabled) mDesc->mItems[i]->Drawer(o, mDesc->mSelectedItem == (int)i); + o.y += gi->GetMenuFontHeight(mDesc->mNativeFontNum); } + /* if (mDesc->mSelectedItem >= 0 && mDesc->mSelectedItem < (int)mDesc->mItems.Size()) mDesc->mItems[mDesc->mSelectedItem]->DrawSelector(mDesc->mSelectOfsX, mDesc->mSelectOfsY, mDesc->mSelector); + */ PostDraw(); Super::Drawer(); } @@ -281,7 +286,7 @@ void FListMenuItem::Ticker() { } -void FListMenuItem::Drawer(bool selected) +void FListMenuItem::Drawer(const vec2_t& origin, bool selected) { } @@ -380,7 +385,7 @@ FListMenuItemStaticPatch::FListMenuItemStaticPatch(int x, int y, FTexture *patch mCentered = centered; } -void FListMenuItemStaticPatch::Drawer(bool selected) +void FListMenuItemStaticPatch::Drawer(const vec2_t& origin, bool selected) { if (!mTexture) { @@ -417,7 +422,7 @@ FListMenuItemStaticText::FListMenuItemStaticText(int x, int y, const char *text, mCentered = centered; } -void FListMenuItemStaticText::Drawer(bool selected) +void FListMenuItemStaticText::Drawer(const vec2_t& origin, bool selected) { const char *text = mText; if (text != NULL) @@ -521,7 +526,7 @@ FListMenuItemText::~FListMenuItemText() { } -void FListMenuItemText::Drawer(bool selected) +void FListMenuItemText::Drawer(const vec2_t& origin, bool selected) { const char *text = mText; if (mText.Len()) @@ -543,6 +548,48 @@ int FListMenuItemText::GetWidth() } +//============================================================================= +// +// native text item +// +//============================================================================= + +FListMenuItemNativeText::FListMenuItemNativeText(int x, int y, int height, int hotkey, const FString& text, int fontnum, int palnum, float fontscale, FName child, int param) + : FListMenuItemSelectable(x, y, height, child, param) +{ + mText = text; + mFontnum = NIT_BigFont; + mPalnum = NIT_ActiveColor; + mFontscale = fontscale; + mHotkey = hotkey; +} + +FListMenuItemNativeText::~FListMenuItemNativeText() +{ +} + +void FListMenuItemNativeText::Drawer(const vec2_t& origin, bool selected) +{ + const char* text = mText; + if (mText.Len()) + { + if (*text == '$') text = GStrings(text + 1); + gi->DrawNativeMenuText(mFontnum, selected ? NIT_SelectedColor : mPalnum, mXpos + origin.x, mYpos + origin.y, mFontscale, text); + } +} + +int FListMenuItemText::GetWidth() +{ + const char* text = mText; + if (mText.Len()) + { + if (*text == '$') text = GStrings(text + 1); + return mFont->StringWidth(text); + } + return 1; +} + + //============================================================================= // // patch item @@ -556,7 +603,7 @@ FListMenuItemPatch::FListMenuItemPatch(int x, int y, int height, int hotkey, FTe mTexture = patch; } -void FListMenuItemPatch::Drawer(bool selected) +void FListMenuItemPatch::Drawer(const vec2_t& origin, bool selected) { DrawTexture (&twod, mTexture, mXpos, mYpos, DTA_Clean, true, TAG_DONE); } diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index b1aaddb65..8615693c9 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -53,6 +53,18 @@ enum EMenuKey MKEY_MBNo, }; +enum ENativeFontValues +{ + NIT_BigFont, + NIT_SmallFont, + NIT_TinyFont, + + NIT_ActiveColor = -1, + NIT_InactiveColor = -2, + NIT_SelectedColor = -3 + // positive values for color are direct palswap indices. +}; + struct FGameStartup { @@ -118,11 +130,13 @@ struct FListMenuDescriptor : public FMenuDescriptor int mAutoselect; // this can only be set by internal menu creation functions int mScriptId; int mSecondaryId; + int mNativeFontNum, mNativePalNum; + float mNativeFontScale; FFont *mFont; EColorRange mFontColor; EColorRange mFontColor2; FMenuDescriptor *mRedirect; // used to redirect overlong skill and episode menus to option menu based alternatives - bool mCenter; + int mCenter; void Reset() { @@ -140,6 +154,9 @@ struct FListMenuDescriptor : public FMenuDescriptor mFontColor2 = CR_UNTRANSLATED; mScriptId = 0; mSecondaryId = 0; + mNativeFontNum = NIT_BigFont; + mNativePalNum = NIT_ActiveColor; + mNativeFontScale = 1.f; } }; @@ -289,7 +306,7 @@ public: virtual bool CheckCoordinate(int x, int y); virtual void Ticker(); - virtual void Drawer(bool selected); + virtual void Drawer(const vec2_t &origin, bool selected); virtual bool Selectable(); virtual bool Activate(); virtual FName GetAction(int *pparam); @@ -317,7 +334,7 @@ protected: public: FListMenuItemStaticPatch(int x, int y, FTexture *patch, bool centered); - void Drawer(bool selected); + void Drawer(const vec2_t& origin, bool selected); }; class FListMenuItemStaticText : public FListMenuItem @@ -331,56 +348,9 @@ protected: public: FListMenuItemStaticText(int x, int y, const char *text, FFont *font, EColorRange color, bool centered); ~FListMenuItemStaticText(); - void Drawer(bool selected); + void Drawer(const vec2_t& origin, bool selected) override; }; -//============================================================================= -// -// the player sprite window -// -//============================================================================= -#if 0 -class FListMenuItemPlayerDisplay : public FListMenuItem -{ - FListMenuDescriptor *mOwner; - FTexture *mBackdrop; - FRemapTable mRemap; - FPlayerClass *mPlayerClass; - int mPlayerTics; - bool mNoportrait; - uint8_t mRotation; - uint8_t mMode; // 0: automatic (used by class selection), 1: manual (used by player setup) - uint8_t mTranslate; - int mSkin; - int mRandomClass; - int mRandomTimer; - int mClassNum; - - void SetPlayerClass(int classnum, bool force = false); - bool UpdatePlayerClass(); - void UpdateRandomClass(); - void UpdateTranslation(); - -public: - - enum - { - PDF_ROTATION = 0x10001, - PDF_SKIN = 0x10002, - PDF_CLASS = 0x10003, - PDF_MODE = 0x10004, - PDF_TRANSLATE = 0x10005, - }; - - FListMenuItemPlayerDisplay(FListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action); - ~FListMenuItemPlayerDisplay(); - virtual void Ticker(); - virtual void Drawer(bool selected); - bool SetValue(int i, int value); -}; -#endif - - //============================================================================= // // selectable items @@ -396,12 +366,12 @@ protected: public: FListMenuItemSelectable(int x, int y, int height, FName childmenu, int mParam = -1); - bool CheckCoordinate(int x, int y); - bool Selectable(); - bool CheckHotkey(int c); - bool Activate(); - bool MouseEvent(int type, int x, int y); - FName GetAction(int *pparam); + bool CheckCoordinate(int x, int y) override; + bool Selectable() override; + bool CheckHotkey(int c) override; + bool Activate() override; + bool MouseEvent(int type, int x, int y) override; + FName GetAction(int *pparam) override; }; class FListMenuItemText : public FListMenuItemSelectable @@ -413,17 +383,32 @@ class FListMenuItemText : public FListMenuItemSelectable public: FListMenuItemText(int x, int y, int height, int hotkey, const FString &text, FFont *font, EColorRange color, EColorRange color2, FName child, int param = 0); ~FListMenuItemText(); - void Drawer(bool selected); - int GetWidth(); + void Drawer(const vec2_t& origin, bool selected) override; + int GetWidth() override; }; +class FListMenuItemNativeText : public FListMenuItemSelectable +{ + // This draws the item with the game frontend's native text drawer and uses a front end defined font, it takes only symbolic constants as parameters. + FString mText; + int mFontnum; + int mPalnum; + float mFontscale; +public: + FListMenuItemNativeText(int x, int y, int height, int hotkey, const FString& text, int fontnum, int palnum, float fontscale, FName child, int param = 0); + ~FListMenuItemNativeText(); + void Drawer(const vec2_t& origin, bool selected) override; + int GetWidth() override; +}; + + class FListMenuItemPatch : public FListMenuItemSelectable { FTexture* mTexture; public: FListMenuItemPatch(int x, int y, int height, int hotkey, FTexture* patch, FName child, int param = 0); - void Drawer(bool selected); - int GetWidth(); + void Drawer(const vec2_t& origin, bool selected) override; + int GetWidth() override; }; //============================================================================= diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index dbb1f7ab6..cbf085cd1 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -159,7 +159,7 @@ static bool CheckSkipGameBlock(FScanner &sc) if (!(filter & 1)) // todo: apply correct filter. { SkipSubBlock(sc); - return true; + return !sc.CheckString("else"); } return false; } @@ -362,26 +362,90 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; } - else if (sc.Compare("Font")) + else if (sc.Compare("NativeTextItem")) { + sc.MustGetString(); + FString text = sc.String; + sc.MustGetStringName(","); + sc.MustGetString(); + int hotkey = sc.String[0]; + sc.MustGetStringName(","); + sc.MustGetString(); + FName action = sc.String; + int param = 0; + if (sc.CheckString(",")) + { + sc.MustGetNumber(); + param = sc.Number; + } + + auto it = new FListMenuItemNativeText(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, text, desc->mNativeFontNum, desc->mNativePalNum, desc->mNativeFontScale, action, param); + desc->mItems.Push(it); + desc->mYpos += desc->mLinespacing; + if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size() - 1; + + } + else if (sc.Compare("NativeFont")) + { + desc->mNativePalNum = NIT_ActiveColor; + desc->mNativeFontScale = 1.f; sc.MustGetString(); - FFont *newfont = V_GetFont(sc.String); - if (newfont != NULL) desc->mFont = newfont; + if (sc.Compare("Big")) desc->mNativeFontNum = NIT_BigFont; + else if (sc.Compare("Small")) desc->mNativeFontNum = NIT_SmallFont; + else if (sc.Compare("Tiny")) desc->mNativeFontNum = NIT_TinyFont; + else sc.ScriptError("Unknown native font type"); if (sc.CheckString(",")) { sc.MustGetString(); - desc->mFontColor2 = desc->mFontColor = V_FindFontColor((FName)sc.String); + if (sc.Compare("Active")) desc->mNativePalNum = NIT_ActiveColor; + else if (sc.Compare("Inactive")) desc->mNativePalNum = NIT_InactiveColor; + else if (sc.Compare("Selected")) desc->mNativePalNum = NIT_SelectedColor; + else + { + char* ep; + int v = (int)strtoll(sc.String, &ep, 0); + if (*ep != 0) sc.ScriptError("Unknown native palette"); + desc->mNativePalNum = v; + } if (sc.CheckString(",")) { - sc.MustGetString(); - desc->mFontColor2 = V_FindFontColor((FName)sc.String); + sc.MustGetFloat(); + desc->mNativeFontScale = sc.Float; + } + } + } + else if (sc.Compare("Position")) + { + sc.MustGetNumber(); + sc.MustGetStringName(","); + desc->mXpos = sc.Number; + sc.MustGetNumber(); + desc->mYpos = sc.Number; + if (sc.CheckString(",")) + { + desc->mCenter = sc.Number; + } + } + else if (sc.Compare("Font")) + { + sc.MustGetString(); + FFont* newfont = V_GetFont(sc.String); + if (newfont != NULL) desc->mFont = newfont; + if (sc.CheckString(",")) + { + sc.MustGetString(); + desc->mFontColor2 = desc->mFontColor = V_FindFontColor((FName)sc.String); + if (sc.CheckString(",")) + { + sc.MustGetString(); + desc->mFontColor2 = V_FindFontColor((FName)sc.String); } } - else - { - desc->mFontColor = OptionSettings.mFontColor; - desc->mFontColor2 = OptionSettings.mFontColorValue; - } + else + { + desc->mFontColor = OptionSettings.mFontColor; + desc->mFontColor2 = OptionSettings.mFontColorValue; + } } else if (sc.Compare("NetgameMessage")) { diff --git a/source/common/utility/stringtable.cpp b/source/common/utility/stringtable.cpp index bd5d3fcd4..838af71fa 100644 --- a/source/common/utility/stringtable.cpp +++ b/source/common/utility/stringtable.cpp @@ -60,13 +60,13 @@ void FStringTable::LoadStrings () int lastlump, lump; lastlump = 0; - while ((lump = fileSystem.Iterate("Language/lmacros", &lastlump, ELookupMode::NoExtension)) != -1) + while ((lump = fileSystem.Iterate("demolition/lmacros", &lastlump, ELookupMode::NoExtension)) != -1) { readMacros(lump); } lastlump = 0; - while ((lump = fileSystem.Iterate ("Language/language", &lastlump, ELookupMode::NoExtension)) != -1) + while ((lump = fileSystem.Iterate ("demolition/language", &lastlump, ELookupMode::NoExtension)) != -1) { auto lumpdata = fileSystem.GetFileData(lump); diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index b8c1c5771..e78c8835b 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -154,6 +154,12 @@ struct GameInterface : ::GameInterface bool mouseInactiveConditional(bool condition) override; FString statFPS() override; GameStats getStats() override; + // Access to the front end specific menu code. Use is restricted to the main menu, the ingame menu and the skill/episode selection. + // Everything else is either custom screens or will use the generic option menu style. + void DrawNativeMenuText(int fontnum, int palnum, int xpos, int ypos, float fontscale, const char* text, int orientation = TOR_Default) override; + int GetMenuFontHeight(int fontnum) override; + int GetMenuTextWidth(int fontnum, const char* text) override; + }; END_DUKE_NS diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index 02e20a3f9..f22e38e6d 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -192,22 +192,6 @@ they effectively stand in for curly braces as struct initializers. MenuGameplayStemEntry g_MenuGameplayEntries[MAXMENUGAMEPLAYENTRIES]; -// common font types -// tilenums are set after namesdyn runs - -// emptychar x,y between x,y zoom cursorLeft cursorCenter cursorScale textflags -// tilenum shade_deselected shade_disabled pal pal_selected pal_deselected pal_disabled -MenuFont_t MF_Redfont = { { 5<<16, 15<<16 }, { 0, 0 }, 65536, 20<<16, 110<<16, 65536, TEXT_BIGALPHANUM | TEXT_UPPERCASE, - -1, 10, 0, 0, 0, 0, 1, - 0, 0, 1 }; -MenuFont_t MF_Bluefont = { { 5<<16, 7<<16 }, { 0, 0 }, 65536, 10<<16, 110<<16, 32768, 0, - -1, 10, 0, 0, 10, 10, 16, - 0, 0, 16 }; -MenuFont_t MF_Minifont = { { 4<<16, 5<<16 }, { 1<<16, 1<<16 }, 65536, 10<<16, 110<<16, 32768, 0, - -1, 10, 0, 0, 2, 2, 0, - 0, 0, 16 }; - - static MenuMenuFormat_t MMF_Top_Main = { { MENU_MARGIN_CENTER<<16, 55<<16, }, -(170<<16) }; static MenuMenuFormat_t MMF_Top_Episode = { { MENU_MARGIN_CENTER<<16, 48<<16, }, -(190<<16) }; static MenuMenuFormat_t MMF_Top_NewGameCustom = { { MENU_MARGIN_CENTER<<16, 48<<16, }, -(190<<16) }; diff --git a/source/rr/src/menus.cpp b/source/rr/src/menus.cpp index ad42eb674..e246ea230 100644 --- a/source/rr/src/menus.cpp +++ b/source/rr/src/menus.cpp @@ -1693,36 +1693,6 @@ void Menu_Init(void) } } -#if 0 - // prepare sound setup - if (WW2GI) - ME_SOUND_DUKETALK.name = "GI talk:"; - else if (NAM) - ME_SOUND_DUKETALK.name = "Grunt talk:"; - - if (IONMAIDEN) - { - MF_Redfont.between.x = 2<<16; - MF_Redfont.cursorScale = 32768; - MF_Redfont.zoom = 16384; - MF_Bluefont.zoom = 16384; - - // hack; should swap out pointers - MF_Minifont = MF_Bluefont; - - MMF_Top_Main.pos.x = 40<<16; - MMF_Top_Main.pos.y = 130<<16; - MMF_Top_Main.bottomcutoff = 190<<16; - M_OPTIONS.format = &MMF_Top_Main; - - MEF_MainMenu.width = MEF_OptionsMenu.width = -(160<<16); - MEF_MainMenu.marginBottom = 7<<16; - - M_OPTIONS.title = NoTitle; - - SELECTDIR_z = 16384; - } -#endif if (RR) { diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv new file mode 100644 index 000000000..cfd2f5717 --- /dev/null +++ b/wadsrc/static/demolition/language.csv @@ -0,0 +1,13 @@ +default,Identifier,Remarks,Filter,eng enc ena enz eni ens enj enb enl ent enw,cs,de,el,eo,es,esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu,fi,fr,hu,it,jp,ko,nl,pl,pt,ptg,ro,ru,sr +,,,,,,,,,,,,,,,,,,,,,,, +New Game,MNU_NEWGAME,,,,Nová hra,Neues Spiel,,Nova Ludo,Nueva Partida,,Uusi peli,Nouvelle Partie,,Nuovo gioco,新規ゲーム,새로운 게임,Nieuw spel,Nowa Gra,Novo Jogo,,,Новая игра,Нова игра +Options,MNU_OPTIONS,,,,Možnosti,Optionen,,Agordoj,Opciones,,Asetukset,Options,,Opzioni,オプション,설정,Opties,Opcje,Opções,,,Настройки,Подешавања +Quit,MNU_QUITGAME,,,,Ukončit hru,Spiel verlassen,,Ĉesigi Ludon,Salir del juego,,Lopeta peli,Quitter le jeu,,Esci dal gioco,終了,게임 종료,Verlaat spel,Wyjdź z Gry,Sair,,,Выход,Заврши игру +Load Game,MNU_LOADGAME,,,,Načíst hru,Spiel laden,,Ŝarĝi Ludon,Cargar Partida,,Lataa peli,Chargement,,Carica gioco,ロード,게임 불러오기,Laden spel,Wczytaj Grę,Carregar,,,Загрузка,Учитај игру +Save Game,MNU_SAVEGAME,,,,Uložit hru,Spiel sichern,,Konservi Ludon,Guardar Partida,,Tallenna peli,Sauvegarde,,Salva gioco,セーブ,게임 저장하기,Opslaan spel,Zapisz Grę,Salvar,Gravar,,Сохранение,Сачувај игру +Help,MNU_HELP,,,,,Hilfe,,,,,,Aide,,,,,,,,,,, +Continue,MNU_CONTINUE,,,,,Fortfahren,,,,,,,,,,,,,,,,, +Credits,MNU_CREDITS,,,,,,,,,,,,,,,,,,,,,, +Cool Stuff,MNU_COOLSTUFF,,,,,Cooles Zeug,,,,,,,,,,,,,,,,, +Multiplayer,MNU_MULTIPLAYER,,,,,Mehrspieler,,,,,,,,,,,,,,,,, +End Game,MNU_ENDGAME,,,,,Spiel beenden,,,,,,,,,,,,,,,,, \ No newline at end of file diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 402209124..d3298200d 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -8,54 +8,62 @@ LISTMENU "MainMenu" { ifgame(Duke, Nam, WW2GI, Fury) { - linespacing 15 - class "Duke.MainMenu" - TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" - //TextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) ifgame(fury) { - TextItem "$MNU_CONTINUE", "l", "LoadGameMenu" + position 40, 130, -160 } else { - TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + position 160, 55 } - TextItem "$MNU_OPTIONS", "o", "OptionsMenu" - TextItem "$MNU_HELP", "h", "HelpMenu" - TextItem "$MNU_CREDITS", "c", "CreditsMenu" - TextItem "$MNU_QUITGAME", "q", "QuitMenu" + linespacing 15 + class "Duke.MainMenu" + NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + //NativeTextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) + ifgame(fury) + { + NativeTextItem "$MNU_CONTINUE", "l", "LoadGameMenu" + } + else + { + NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + } + NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" + NativeTextItem "$MNU_HELP", "h", "HelpMenu" + NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" + NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" } ifgame(Redneck, RedneckRides) { linespacing 15 - TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" - //TextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) - TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" - TextItem "$MNU_OPTIONS", "o", "OptionsMenu" - TextItem "$MNU_HELP", "h", "HelpMenu" - TextItem "$MNU_CREDITS", "c", "CreditsMenu" - TextItem "$MNU_QUITGAME", "q", "QuitMenu" + NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + //NativeTextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) + NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" + NativeTextItem "$MNU_HELP", "h", "HelpMenu" + NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" + NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" } ifgame(Blood) { linespacing 15 - TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" - TextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" - TextItem "$MNU_OPTIONS", "o", "OptionsMenu" - TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" - TextItem "$MNU_HELP", "h", "HelpMenu" - TextItem "$MNU_CREDITS", "c", "CreditsMenu" - TextItem "$MNU_QUITGAME", "q", "QuitMenu" + NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" + NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" + NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + NativeTextItem "$MNU_HELP", "h", "HelpMenu" + NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" + NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" } ifgame(ShadowWarrior) { linespacing 15 - TextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" - TextItem "$MNU_LOADGAME", "l", "LoadGameMenu" - TextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" - TextItem "$MNU_OPTIONS", "o", "OptionsMenu" - TextItem "$MNU_COOLSTUFF", "h", "HelpMenu" - TextItem "$MNU_QUITGAME", "q", "QuitMenu" + NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" + NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" + NativeTextItem "$MNU_COOLSTUFF", "h", "HelpMenu" + NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" } } diff --git a/wadsrc/static/textcolors.txt b/wadsrc/static/demolition/textcolors.txt similarity index 100% rename from wadsrc/static/textcolors.txt rename to wadsrc/static/demolition/textcolors.txt diff --git a/wadsrc/static/language.txt b/wadsrc/static/language.txt deleted file mode 100644 index e69de29bb..000000000 From 9529adb3e1fcf9d48ce9ddf1ed6fa5f5628cb819 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 23 Nov 2019 12:41:13 +0100 Subject: [PATCH 007/203] - font tables moved. --- source/common/menu/menudef.cpp | 30 ------------------------------ source/duke3d/src/d_menu.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index cbf085cd1..867430200 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -452,36 +452,6 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) sc.MustGetString(); desc->mNetgameMessage = sc.String; } -#if 0 - else if (sc.Compare("PlayerDisplay")) - { - bool noportrait = false; - FName action = NAME_None; - sc.MustGetNumber(); - int x = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - int y = sc.Number; - sc.MustGetStringName(","); - sc.MustGetString(); - PalEntry c1 = V_GetColor(NULL, sc.String); - sc.MustGetStringName(","); - sc.MustGetString(); - PalEntry c2 = V_GetColor(NULL, sc.String); - if (sc.CheckString(",")) - { - sc.MustGetNumber(); - noportrait = !!sc.Number; - if (sc.CheckString(",")) - { - sc.MustGetString(); - action = sc.String; - } - } - FListMenuItemPlayerDisplay *it = new FListMenuItemPlayerDisplay(desc, x, y, c1, c2, noportrait, action); - desc->mItems.Push(it); - } -#endif else { sc.ScriptError("Unknown keyword '%s'", sc.String); diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 356464116..e3c231294 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -45,6 +45,22 @@ BEGIN_DUKE_NS #define MENU_HEIGHT_CENTER 100 +// common font types +// tilenums are set after namesdyn runs. +// These are also modifiable by scripts. +// emptychar x,y between x,y zoom cursorLeft cursorCenter cursorScale textflags +// tilenum shade_deselected shade_disabled pal pal_selected pal_deselected pal_disabled +MenuFont_t MF_Redfont = { { 5<<16, 15<<16 }, { 0, 0 }, 65536, 20<<16, 110<<16, 65536, TEXT_BIGALPHANUM | TEXT_UPPERCASE, + -1, 10, 0, 0, 0, 0, 1, + 0, 0, 1 }; +MenuFont_t MF_Bluefont = { { 5<<16, 7<<16 }, { 0, 0 }, 65536, 10<<16, 110<<16, 32768, 0, + -1, 10, 0, 0, 10, 10, 16, + 0, 0, 16 }; +MenuFont_t MF_Minifont = { { 4<<16, 5<<16 }, { 1<<16, 1<<16 }, 65536, 10<<16, 110<<16, 32768, 0, + -1, 10, 0, 0, 2, 2, 0, + 0, 0, 16 }; + + static void Menu_DrawTopBar(const vec2_t origin) { if ((G_GetLogoFlags() & LOGO_NOTITLEBAR) == 0) @@ -64,6 +80,19 @@ static void Menu_DrawTopBarCaption(const char *caption, const vec2_t origin) captionmenutext(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (24<<16) + ((15>>1)<<16), t); } +int GetMenuFontHeight(int fontnum) +{ + +} + +int GetMenuTextWidth(int fontnum, const char* text) +{ +} + +void GameInterface::DrawNativeMenuText(int fontnum, int palnum, int xpos, int ypos, float fontscale, const char* text, int orientation) +{ +} + class DukeListMenu : public DListMenu From 326d0f5f76af393121c7643b85517c452530b2dc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 23 Nov 2019 17:50:36 +0100 Subject: [PATCH 008/203] - the new menu displays something. --- source/build/include/baselayer.h | 4 +- source/common/menu/listmenu.cpp | 18 +-- source/common/menu/menu.cpp | 2 + source/common/menu/menu.h | 19 +++- source/common/menu/menudef.cpp | 24 ++-- source/duke3d/src/d_menu.cpp | 157 +++++++++++++++++++++++++-- source/duke3d/src/duke3d.h | 4 +- source/duke3d/src/menus.cpp | 11 -- wadsrc/static/demolition/menudef.txt | 5 +- 9 files changed, 184 insertions(+), 60 deletions(-) diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 864b1cd09..ca51ed4a2 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -187,9 +187,7 @@ struct GameInterface virtual bool mouseInactiveConditional(bool condition) { return condition; } virtual FString statFPS() { return "FPS display not available"; } virtual GameStats getStats() { return {}; } - virtual void DrawNativeMenuText(int fontnum, int palnum, int xpos, int ypos, float fontscale, const char* text, int orientation = TOR_Default) {} - virtual int GetMenuFontHeight(int fontnum) { return 16; /* something arbitrarily non-zero */ } - virtual int GetMenuTextWidth(int fontnum, const char* text) { return 10 * strlen(text); } + virtual void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int orientation = TOR_Default) {} }; extern GameInterface* gi; diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 0264808e4..37a7ed75c 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -255,14 +255,10 @@ void DListMenu::Drawer () PreDraw(); for(unsigned i=0;imItems.Size(); i++) { - auto o = origin; - if (mDesc->mItems[i]->mEnabled) mDesc->mItems[i]->Drawer(o, mDesc->mSelectedItem == (int)i); - o.y += gi->GetMenuFontHeight(mDesc->mNativeFontNum); + if (mDesc->mItems[i]->mEnabled) mDesc->mItems[i]->Drawer(origin, mDesc->mSelectedItem == (int)i); } - /* if (mDesc->mSelectedItem >= 0 && mDesc->mSelectedItem < (int)mDesc->mItems.Size()) mDesc->mItems[mDesc->mSelectedItem]->DrawSelector(mDesc->mSelectOfsX, mDesc->mSelectOfsY, mDesc->mSelector); - */ PostDraw(); Super::Drawer(); } @@ -574,18 +570,12 @@ void FListMenuItemNativeText::Drawer(const vec2_t& origin, bool selected) if (mText.Len()) { if (*text == '$') text = GStrings(text + 1); - gi->DrawNativeMenuText(mFontnum, selected ? NIT_SelectedColor : mPalnum, mXpos + origin.x, mYpos + origin.y, mFontscale, text); + gi->DrawNativeMenuText(mFontnum, selected ? NIT_SelectedState : mEnabled? NIT_ActiveState : NIT_InactiveState, mXpos + origin.x, mYpos + origin.y, 1.f, text, TOR_Center); // needs to be able to handle other orientations, too. } -} +} -int FListMenuItemText::GetWidth() +int FListMenuItemNativeText::GetWidth() { - const char* text = mText; - if (mText.Len()) - { - if (*text == '$') text = GStrings(text + 1); - return mFont->StringWidth(text); - } return 1; } diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index e47190369..12b5bd7fa 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -313,6 +313,8 @@ void M_StartControlPanel (bool makeSound) } BackbuttonTime = 0; BackbuttonAlpha = 0; + DMenu::MenuTime = -1; + M_Ticker(); // This needs to be called once here to make sure that the menu actually has ticked before it gets drawn for the first time. } //============================================================================= diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 8615693c9..c5e9b4555 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -61,7 +61,11 @@ enum ENativeFontValues NIT_ActiveColor = -1, NIT_InactiveColor = -2, - NIT_SelectedColor = -3 + NIT_SelectedColor = -3, + + NIT_ActiveState = 1, + NIT_InactiveState = 2, + NIT_SelectedState = 3 // positive values for color are direct palswap indices. }; @@ -124,7 +128,7 @@ struct FListMenuDescriptor : public FMenuDescriptor int mSelectOfsY; FTexture *mSelector; int mDisplayTop; - int mXpos, mYpos; + int mXpos, mYpos, mYbotton; int mWLeft, mWRight; int mLinespacing; // needs to be stored for dynamically created menus int mAutoselect; // this can only be set by internal menu creation functions @@ -138,6 +142,11 @@ struct FListMenuDescriptor : public FMenuDescriptor FMenuDescriptor *mRedirect; // used to redirect overlong skill and episode menus to option menu based alternatives int mCenter; + FListMenuDescriptor() + { + Reset(); + } + void Reset() { // Reset the default settings (ignore all other values in the struct) @@ -319,12 +328,13 @@ public: virtual bool MouseEvent(int type, int x, int y); virtual bool CheckHotkey(int c); virtual int GetWidth(); - void DrawSelector(int xofs, int yofs, FTexture *tex); + virtual void DrawSelector(int xofs, int yofs, FTexture *tex); void OffsetPositionY(int ydelta) { mYpos += ydelta; } int GetY() { return mYpos; } int GetX() { return mXpos; } void SetX(int x) { mXpos = x; } -}; + void SetY(int x) { mYpos = x; } +}; class FListMenuItemStaticPatch : public FListMenuItem { @@ -399,6 +409,7 @@ public: ~FListMenuItemNativeText(); void Drawer(const vec2_t& origin, bool selected) override; int GetWidth() override; + void DrawSelector(int xofs, int yofs, FTexture* tex) override { } // The text drawer handles this itself. }; diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 867430200..3eeae1acc 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -266,6 +266,16 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) sc.MustGetStringName(","); sc.MustGetNumber(); desc->mYpos = sc.Number; + if (sc.CheckString(",")) + { + sc.MustGetNumber(); + desc->mYbotton = sc.Number; + if (sc.CheckString(",")) + { + sc.MustGetNumber(); + desc->mCenter = sc.Number; + } + } } else if (sc.Compare("Centermenu")) { @@ -381,7 +391,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) auto it = new FListMenuItemNativeText(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, text, desc->mNativeFontNum, desc->mNativePalNum, desc->mNativeFontScale, action, param); desc->mItems.Push(it); - desc->mYpos += desc->mLinespacing; + //desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size() - 1; } @@ -414,18 +424,6 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) } } } - else if (sc.Compare("Position")) - { - sc.MustGetNumber(); - sc.MustGetStringName(","); - desc->mXpos = sc.Number; - sc.MustGetNumber(); - desc->mYpos = sc.Number; - if (sc.CheckString(",")) - { - desc->mCenter = sc.Number; - } - } else if (sc.Compare("Font")) { sc.MustGetString(); diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index e3c231294..4239e8526 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -44,6 +44,17 @@ BEGIN_DUKE_NS #define MENU_MARGIN_CENTER 160 #define MENU_HEIGHT_CENTER 100 +enum MenuTextFlags_t +{ + MT_Selected = 1 << 0, + MT_Disabled = 1 << 1, + MT_XCenter = 1 << 2, + MT_XRight = 1 << 3, + MT_YCenter = 1 << 4, + MT_Literal = 1 << 5, + MT_RightSide = 1 << 6, +}; + // common font types // tilenums are set after namesdyn runs. @@ -80,17 +91,118 @@ static void Menu_DrawTopBarCaption(const char *caption, const vec2_t origin) captionmenutext(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (24<<16) + ((15>>1)<<16), t); } -int GetMenuFontHeight(int fontnum) +static void Menu_GetFmt(const MenuFont_t* font, uint8_t const status, int32_t* s, int32_t* z) { + if (status & MT_Selected) + *s = VM_OnEventWithReturn(EVENT_MENUSHADESELECTED, -1, myconnectindex, sintable[((int32_t)totalclock << 5) & 2047] >> 12); + else + *s = font->shade_deselected; + // sum shade values + if (status & MT_Disabled) + *s += font->shade_disabled; + if (FURY && status & MT_Selected) + *z += (*z >> 4); } -int GetMenuTextWidth(int fontnum, const char* text) +static vec2_t Menu_Text(int32_t x, int32_t y, const MenuFont_t* font, const char* t, uint8_t status, int32_t ydim_upper, int32_t ydim_lower) { + int32_t s, p, ybetween = font->between.y; + int32_t f = font->textflags; + if (status & MT_XCenter) + f |= TEXT_XCENTER; + if (status & MT_XRight) + f |= TEXT_XRIGHT; + if (status & MT_YCenter) + { + f |= TEXT_YCENTER | TEXT_YOFFSETZERO; + ybetween = font->emptychar.y; // <^ the battle against 'Q' + } + if (status & MT_Literal) + f |= TEXT_LITERALESCAPE; + + int32_t z = font->zoom; + + if (status & MT_Disabled) + p = (status & MT_RightSide) ? font->pal_disabled_right : font->pal_disabled; + else if (status & MT_Selected) + p = (status & MT_RightSide) ? font->pal_selected_right : font->pal_selected; + else + p = (status & MT_RightSide) ? font->pal_deselected_right : font->pal_deselected; + + Menu_GetFmt(font, status, &s, &z); + + return G_ScreenText(font->tilenum, x, y, z, 0, 0, t, s, p, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, font->emptychar.x, font->emptychar.y, font->between.x, ybetween, f, 0, ydim_upper, xdim - 1, ydim_lower); } -void GameInterface::DrawNativeMenuText(int fontnum, int palnum, int xpos, int ypos, float fontscale, const char* text, int orientation) +static int32_t Menu_CursorShade(void) { + return VM_OnEventWithReturn(EVENT_MENUCURSORSHADE, -1, myconnectindex, 4 - (sintable[((int32_t)totalclock << 4) & 2047] >> 11)); +} + +static void Menu_DrawCursorCommon(int32_t x, int32_t y, int32_t z, int32_t picnum, int32_t ydim_upper = 0, int32_t ydim_lower = ydim - 1) +{ + rotatesprite_(x, y, z, 0, picnum, Menu_CursorShade(), 0, 2 | 8, 0, 0, 0, ydim_upper, xdim - 1, ydim_lower); +} + +static void Menu_DrawCursorLeft(int32_t x, int32_t y, int32_t z) +{ + if (FURY) return; + Menu_DrawCursorCommon(x, y, z, VM_OnEventWithReturn(EVENT_MENUCURSORLEFT, -1, myconnectindex, SPINNINGNUKEICON + (((int32_t)totalclock >> 3) % 7))); +} + +static void Menu_DrawCursorRight(int32_t x, int32_t y, int32_t z) +{ + if (FURY) return; + Menu_DrawCursorCommon(x, y, z, VM_OnEventWithReturn(EVENT_MENUCURSORRIGHT, -1, myconnectindex, SPINNINGNUKEICON + 6 - ((6 + ((int32_t)totalclock >> 3)) % 7))); +} + +static int Menu_GetFontHeight(int fontnum) +{ + auto& font = fontnum == NIT_BigFont ? MF_Redfont : fontnum == NIT_SmallFont ? MF_Bluefont : MF_Minifont; + return font.get_yline(); +} + +void GameInterface::DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int orientation) +{ + int ydim_upper = 0; + int ydim_lower = ydim - 1; + int32_t const indent = 0; // not set for any relevant menu + int32_t x = xpos << 16; + + uint8_t status = 0; + if (state == NIT_SelectedState) + status |= MT_Selected; + if (state == NIT_InactiveState) + status |= MT_Disabled; + if (orientation == TOR_Center) + status |= MT_XCenter; + + bool const dodraw = true; + MenuFont_t &font = fontnum == NIT_BigFont ? MF_Redfont : fontnum == NIT_SmallFont ? MF_Bluefont : MF_Minifont; + + int32_t const height = font.get_yline(); + status |= MT_YCenter; + int32_t const y_internal = (ypos + (height >> 17)) << 16;// -menu->scrollPos; + + vec2_t textsize; + if (dodraw) + textsize = Menu_Text(x, y_internal, &font, text, status, ydim_upper, ydim_lower); + + if (orientation == TOR_Right) + status |= MT_XRight; + + if (dodraw && (status & MT_Selected) && state != 1) + { + if (status & MT_XCenter) + { + Menu_DrawCursorLeft(x + font.cursorCenterPosition, y_internal, font.cursorScale); + Menu_DrawCursorRight(x - font.cursorCenterPosition, y_internal, font.cursorScale); + } + else + Menu_DrawCursorLeft(x /*+ indent*/ - font.cursorLeftPosition, y_internal, font.cursorScale); + } + } @@ -113,6 +225,38 @@ protected: } } + void Ticker() override + { + // Lay out the menu. Since scripts are allowed to mess around with the font this needs to be redone each frame. + int32_t y_upper = mDesc->mYpos; + int32_t y_lower = y_upper + mDesc->mYbotton; + int32_t y = 0; + int32_t calculatedentryspacing = 0; + int32_t const height = Menu_GetFontHeight(mDesc->mNativeFontNum) >> 16; + + // None of the menus still being supported will hide entries - only decactivate them if not applicable. + int32_t totalheight = 0, numvalidentries = mDesc->mItems.Size(); + + for (int e = 0; e < numvalidentries; ++e) + { + totalheight += height; + } + + calculatedentryspacing = std::max(0, (y_lower - y_upper - totalheight) / (numvalidentries > 1 ? numvalidentries - 1 : 1)); + + // totalHeight calculating pass + int totalHeight; + for (int e = 0; e < numvalidentries; ++e) + { + auto entry = mDesc->mItems[e]; + + entry->SetY(y_upper + y); + y += height; + totalHeight = y; + y += calculatedentryspacing; + } + } + void PreDraw() override { CallScript(CurrentMenu == this ? EVENT_DISPLAYMENU : EVENT_DISPLAYMENUREST, true); @@ -122,13 +266,6 @@ protected: { CallScript(CurrentMenu == this ? EVENT_DISPLAYMENUREST : EVENT_DISPLAYINACTIVEMENUREST, false); } - - void Drawer() override - { - auto v = origin; - Super::Drawer(); - origin = v; - } }; class DukeNewGameCustomSubMenu : public DukeListMenu diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index e78c8835b..4fed016c8 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -156,9 +156,7 @@ struct GameInterface : ::GameInterface GameStats getStats() override; // Access to the front end specific menu code. Use is restricted to the main menu, the ingame menu and the skill/episode selection. // Everything else is either custom screens or will use the generic option menu style. - void DrawNativeMenuText(int fontnum, int palnum, int xpos, int ypos, float fontscale, const char* text, int orientation = TOR_Default) override; - int GetMenuFontHeight(int fontnum) override; - int GetMenuTextWidth(int fontnum, const char* text) override; + void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int orientation = TOR_Default) override; }; diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index f22e38e6d..95597e1f8 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -4342,17 +4342,6 @@ static vec2_t Menu_Text(int32_t x, int32_t y, const MenuFont_t *font, const char return G_ScreenText(font->tilenum, x, y, z, 0, 0, t, s, p, 2|8|16|ROTATESPRITE_FULL16, 0, font->emptychar.x, font->emptychar.y, font->between.x, ybetween, f, 0, ydim_upper, xdim-1, ydim_lower); } -#if 0 -static vec2_t Menu_TextSize(int32_t x, int32_t y, const MenuFont_t *font, const char *t, uint8_t status) -{ - int32_t f = font->textflags; - if (status & MT_Literal) - f |= TEXT_LITERALESCAPE; - - return G_ScreenTextSize(font->tilenum, x, y, font->zoom, 0, t, 2|8|16|ROTATESPRITE_FULL16, font->emptychar.x, font->emptychar.y, font->between.x, font->between.y, f, 0, 0, xdim-1, ydim-1); -} -#endif - static int32_t Menu_FindOptionBinarySearch(MenuOption_t *object, const int32_t query, uint16_t searchstart, uint16_t searchend) { const uint16_t thissearch = (searchstart + searchend) / 2; diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index d3298200d..7470f6123 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -10,11 +10,12 @@ LISTMENU "MainMenu" { ifgame(fury) { - position 40, 130, -160 + position 40, 130, 60, -160 } else { - position 160, 55 + position 160, 55, 115, 0 + centermenu } linespacing 15 class "Duke.MainMenu" From 52cfb7fb9229dcbe49cacc8a2a06a05e1bd860e8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 23 Nov 2019 23:05:24 +0100 Subject: [PATCH 009/203] - completely disconnected the old menu from the rest of the game to allow rebuilding the new one. Sadly this uncovered a few more places where script events are allowed too broad access to the game state. --- source/blood/src/blood.cpp | 3 - source/blood/src/menus.h | 2 - source/blood/src/osdcmd.cpp | 7 - source/build/include/baselayer.h | 5 + source/build/src/screenshot.cpp | 6 + source/build/src/sdlayer.cpp | 2 + source/common/console/d_event.cpp | 2 +- source/common/menu/listmenu.cpp | 24 +- source/common/menu/menu.cpp | 84 +++- source/common/menu/menu.h | 6 +- source/common/utility/namedef.h | 18 +- source/duke3d/src/actors.cpp | 8 +- source/duke3d/src/d_menu.cpp | 388 +++++++++++++++++- source/duke3d/src/demo.cpp | 29 +- source/duke3d/src/duke3d.h | 4 + source/duke3d/src/game.cpp | 158 +------ source/duke3d/src/gameexec.cpp | 10 +- source/duke3d/src/gamestructures.cpp | 8 +- source/duke3d/src/gamevars.cpp | 1 + source/duke3d/src/menus.cpp | 12 +- source/duke3d/src/menus.h | 102 ++--- source/duke3d/src/osdcmds.cpp | 106 ----- source/duke3d/src/premap.cpp | 5 +- source/duke3d/src/savegame.cpp | 3 +- source/duke3d/src/screens.cpp | 17 +- source/rr/src/game.cpp | 22 - source/rr/src/osdcmds.cpp | 63 --- source/sw/src/draw.cpp | 18 - source/sw/src/game.cpp | 3 - wadsrc/static/demolition/defbinds.all | 15 + wadsrc/static/demolition/menudef.txt | 59 +++ .../filter/duke/demolition/defbinds.txt | 3 - .../filter/duke/demolition/leftbinds.txt | 3 - .../filter/duke/demolition/origbinds.txt | 3 - .../filter/ionfury/demolition/defbinds.txt | 3 - .../filter/ionfury/demolition/leftbinds.txt | 3 - .../filter/ionfury/demolition/origbinds.txt | 3 - .../static/filter/nam/demolition/defbinds.txt | 3 - .../filter/nam/demolition/leftbinds.txt | 3 - .../filter/nam/demolition/origbinds.txt | 3 - .../filter/redneck/demolition/defbinds.txt | 3 - .../filter/redneck/demolition/leftbinds.txt | 3 - .../filter/redneck/demolition/origbinds.txt | 3 - .../filter/ww2gi/demolition/defbinds.txt | 3 - .../filter/ww2gi/demolition/leftbinds.txt | 3 - .../filter/ww2gi/demolition/origbinds.txt | 3 - 46 files changed, 697 insertions(+), 538 deletions(-) create mode 100644 wadsrc/static/demolition/defbinds.all diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index be0f0327b..c0c06a857 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -939,9 +939,6 @@ void LocalKeys(void) break; case sc_F11: break; - case sc_F12: - videoCaptureScreen(); - break; } } } diff --git a/source/blood/src/menus.h b/source/blood/src/menus.h index b7792a9c7..104366533 100644 --- a/source/blood/src/menus.h +++ b/source/blood/src/menus.h @@ -475,8 +475,6 @@ void Menu_AnimateChange(int32_t cm, MenuAnimationType_t animtype); int32_t Menu_IsTextInput(Menu_t *cm); int G_CheckPlayerColor(int color); void Menu_Init(void); -void Menu_Open(uint8_t playerID); -void Menu_Close(uint8_t playerID); void M_DisplayMenus(void); extern MenuFont_t MF_Redfont, MF_Bluefont, MF_Minifont; diff --git a/source/blood/src/osdcmd.cpp b/source/blood/src/osdcmd.cpp index c7dd70d98..d8028716a 100644 --- a/source/blood/src/osdcmd.cpp +++ b/source/blood/src/osdcmd.cpp @@ -429,12 +429,6 @@ static int osdcmd_quickload(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_screenshot(osdcmdptr_t parm) -{ - videoCaptureScreen(); - - return OSDCMD_OK; -} #if 0 static int osdcmd_savestate(osdcmdptr_t UNUSED(parm)) @@ -485,7 +479,6 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("quicksave","quicksave: performs a quick save", osdcmd_quicksave); OSD_RegisterFunction("quickload","quickload: performs a quick load", osdcmd_quickload); OSD_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound); - OSD_RegisterFunction("screenshot","screenshot [format]: takes a screenshot.", osdcmd_screenshot); OSD_RegisterFunction("vidmode","vidmode : change the video mode",osdcmd_vidmode); diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index ca51ed4a2..7d4ed9166 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -188,6 +188,11 @@ struct GameInterface virtual FString statFPS() { return "FPS display not available"; } virtual GameStats getStats() { return {}; } virtual void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int orientation = TOR_Default) {} + virtual void MainMenuOpened() {} + virtual void MenuOpened() {} + virtual void MenuSelectSound() {} + virtual void MenuChooseSound() {} + virtual bool CanSave() { return true; } }; extern GameInterface* gi; diff --git a/source/build/src/screenshot.cpp b/source/build/src/screenshot.cpp index 3a6de4d2e..21f8649d5 100644 --- a/source/build/src/screenshot.cpp +++ b/source/build/src/screenshot.cpp @@ -8,6 +8,7 @@ #include "cmdlib.h" #include "gamecontrol.h" #include "printf.h" +#include "c_dispatch.h" #include "../../glbackend/glbackend.h" @@ -156,5 +157,10 @@ int videoCaptureScreen() return 0; } +CCMD(screenshot) +{ + videoCaptureScreen(); +} + #undef HICOLOR diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index 72f1f3667..d5e22a5f8 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -98,6 +98,7 @@ unsigned char syncstate; // fix for mousewheel int32_t inputchecked = 0; +bool screenshot_requested; char quitevent=0, appactive=1, novideo=0; @@ -2090,3 +2091,4 @@ void debugprintf(const char* f, ...) OutputDebugStringA(buf); } + diff --git a/source/common/console/d_event.cpp b/source/common/console/d_event.cpp index b61ef1948..0aace459a 100644 --- a/source/common/console/d_event.cpp +++ b/source/common/console/d_event.cpp @@ -65,7 +65,7 @@ bool G_Responder (event_t *ev) stricmp (cmd, "screenshot"))) { M_StartControlPanel(true); - M_SetMenu(NAME_Mainmenu, -1); + M_SetMenu(NAME_MainMenu, -1); return true; } else diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 37a7ed75c..4fd448276 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -64,6 +64,7 @@ void DListMenu::Init(DMenu *parent, FListMenuDescriptor *desc) { mParentMenu = parent; mDesc = desc; + if (mDesc->mScriptId) scriptID = mDesc->mScriptId; if (desc->mCenter) { int center = 160; @@ -126,7 +127,7 @@ bool DListMenu::Responder (event_t *ev) if (mDesc->mItems[i]->CheckHotkey(ch)) { mDesc->mSelectedItem = i; - //S_Sound(CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + gi->MenuSelectSound(); return true; } } @@ -135,7 +136,7 @@ bool DListMenu::Responder (event_t *ev) if (mDesc->mItems[i]->CheckHotkey(ch)) { mDesc->mSelectedItem = i; - //S_Sound(CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + gi->MenuSelectSound(); return true; } } @@ -162,7 +163,7 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller) if (--mDesc->mSelectedItem < 0) mDesc->mSelectedItem = mDesc->mItems.Size()-1; } while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + gi->MenuSelectSound(); return true; case MKEY_Down: @@ -171,13 +172,13 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller) if (++mDesc->mSelectedItem >= (int)mDesc->mItems.Size()) mDesc->mSelectedItem = 0; } while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + gi->MenuSelectSound(); return true; case MKEY_Enter: if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate()) { - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); + gi->MenuChooseSound(); } return true; @@ -192,13 +193,18 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller) // //============================================================================= -bool DListMenu::MouseEvent(int type, int x, int y) +bool DListMenu::MouseEvent(int type, int xx, int yy) { int sel = -1; // convert x/y from screen to virtual coordinates, according to CleanX/Yfac use in DrawTexture - x = ((x - (screen->GetWidth() / 2)) / CleanXfac) + 160; - y = ((y - (screen->GetHeight() / 2)) / CleanYfac) + 100; + //x = ((x - (screen->GetWidth() / 2)) / CleanXfac) + 160; + //y = ((y - (screen->GetHeight() / 2)) / CleanYfac) + 100; + + + int width43 = (screen->GetHeight() * 4 / 3); + int x = (xx - (screen->GetWidth() - width43) / 2) * 320 / width43; + int y = yy * 200 / screen->GetHeight(); if (mFocusControl != NULL) { @@ -216,7 +222,7 @@ bool DListMenu::MouseEvent(int type, int x, int y) { if ((int)i != mDesc->mSelectedItem) { - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + // no sound. This is too noisy. } mDesc->mSelectedItem = i; mDesc->mItems[i]->MouseEvent(type, x, y); diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 12b5bd7fa..75c8b3382 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -48,9 +48,13 @@ #include "printf.h" #include "v_draw.h" #include "gamecontrol.h" +#include "fx_man.h" void RegisterDukeMenus(); extern bool rotatesprite_2doverride; +bool help_disabled, credits_disabled; +int g_currentMenu; // accessible by CON scripts - contains the current menu's script ID if defined or INT_MAX if none given. +int DrawBackground; // // Todo: Move these elsewhere @@ -149,9 +153,12 @@ bool DMenu::MenuEvent (int mkey, bool fromcontroller) { case MKEY_Back: { - Close(); - //S_Sound (CHAN_VOICE | CHAN_UI, DMenu::CurrentMenu != NULL? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE); - return true; + if (scriptID != 1) + { + Close(); + //S_Sound (CHAN_VOICE | CHAN_UI, DMenu::CurrentMenu != NULL? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE); + return true; + } } } return false; @@ -171,7 +178,11 @@ void DMenu::Close () delete this; if (DMenu::CurrentMenu == NULL) { - M_ClearMenus (); + M_ClearMenus(); + } + else + { + g_currentMenu = DMenu::CurrentMenu->scriptID; } } @@ -307,16 +318,18 @@ void M_StartControlPanel (bool makeSound) // That way, it won't be paused. //P_CheckTickerPaused (); - if (makeSound) - { - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); - } BackbuttonTime = 0; BackbuttonAlpha = 0; - DMenu::MenuTime = -1; + DrawBackground = -1; + DMenu::MenuTime = -1; M_Ticker(); // This needs to be called once here to make sure that the menu actually has ticked before it gets drawn for the first time. } +void Menu_Open(int playerid) +{ + M_StartControlPanel(DMenu::CurrentMenu == nullptr); +} + //============================================================================= // // @@ -325,6 +338,7 @@ void M_StartControlPanel (bool makeSound) void M_ActivateMenu(DMenu *menu) { + g_currentMenu = menu->scriptID; if (menuactive == MENU_Off) menuactive = MENU_On; if (DMenu::CurrentMenu != NULL) DMenu::CurrentMenu->ReleaseCapture(); DMenu::CurrentMenu = menu; @@ -338,6 +352,11 @@ void M_ActivateMenu(DMenu *menu) void M_SetMenu(FName menu, int param) { + if (DrawBackground == -1) + { + if (menu == NAME_MainMenu) DrawBackground = 1; + else DrawBackground = 0; + } // some menus need some special treatment (needs to be adjusted for the various frontends. #if 0 switch (menu) @@ -648,7 +667,7 @@ bool M_Responder (event_t *ev) if (ev->data1 == KEY_ESCAPE) { M_StartControlPanel(true); - M_SetMenu(NAME_Mainmenu, -1); + M_SetMenu(NAME_IngameMenu, -1); return true; } return false; @@ -657,7 +676,7 @@ bool M_Responder (event_t *ev) ConsoleState != c_down && m_use_mouse) { M_StartControlPanel(true); - M_SetMenu(NAME_Mainmenu, -1); + M_SetMenu(NAME_MainMenu, -1); return true; } } @@ -730,7 +749,8 @@ void M_Drawer (void) if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) { DMenu::CurrentMenu->origin = { 0,0 }; - if (DMenu::CurrentMenu->DimAllowed() && fade) twod.AddColorOnlyQuad(0, 0, screen->GetWidth(), screen->GetHeight(), fade); + if (DMenu::CurrentMenu->DimAllowed() && fade && !DrawBackground) twod.AddColorOnlyQuad(0, 0, screen->GetWidth(), screen->GetHeight(), fade); + // else if (DrawBackground) Menu_DrawBackground(origin); DMenu::CurrentMenu->Drawer(); } rotatesprite_2doverride = false; @@ -755,6 +775,10 @@ void M_ClearMenus () GUICapture &= ~1; } +void Menu_Close(int playerid) +{ + M_ClearMenus(); +} //============================================================================= // // @@ -842,3 +866,39 @@ CCMD(reset2saved) GameConfig->DoGlobalSetup (); GameConfig->DoGameSetup (currentGame); } + +CCMD(openmainmenu) +{ + FX_StopAllSounds(); + //gi->ClearSoundLocks(); + //gi->MenuSound(); + M_StartControlPanel(false); + M_SetMenu(NAME_IngameMenu); +} + +CCMD(openhelpmenu) +{ + if (!help_disabled) + { + gi->MenuOpened(); + M_StartControlPanel(false); + M_SetMenu(NAME_HelpMenu); + } +} + +CCMD(opensavemenu) +{ + if (gi->CanSave()) + { + gi->MenuOpened(); + M_StartControlPanel(false); + M_SetMenu(NAME_SaveMenu); + } +} + +CCMD(openloadmenu) +{ + gi->MenuOpened(); + M_StartControlPanel(false); + M_SetMenu(NAME_LoadMenu); +} diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index c5e9b4555..7d07c5db5 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -14,6 +14,8 @@ EXTERN_CVAR(Int, m_use_mouse); const int MENU_TICRATE = 30; +extern bool help_disabled, credits_disabled; +extern int g_currentMenu; enum EMenuState : int @@ -265,6 +267,7 @@ public: DMenu *mParentMenu; vec2_t origin; + int scriptID = INT_MAX; DMenu(DMenu *parent = NULL); virtual bool Responder (event_t *ev); @@ -301,7 +304,7 @@ protected: FName mAction; public: - bool mEnabled; + bool mEnabled, mHidden; FListMenuItem(int xpos = 0, int ypos = 0, FName action = NAME_None) { @@ -309,6 +312,7 @@ public: mYpos = ypos; mAction = action; mEnabled = true; + mHidden = false; } virtual ~FListMenuItem(); diff --git a/source/common/utility/namedef.h b/source/common/utility/namedef.h index acb8a5ff9..b5425f821 100644 --- a/source/common/utility/namedef.h +++ b/source/common/utility/namedef.h @@ -1,4 +1,10 @@ // 'None' must always be the first name. + +// Windows.h is just dangerous! +#ifdef LoadMenu +#undef LoadMenu +#endif + xx(None) xx(Null) xx(_) @@ -8,5 +14,13 @@ xx(SEQ) xx(SFX) xx(RAW) xx(MAP) -xx(Mainmenu) -xx(Controlmessage) \ No newline at end of file +xx(Controlmessage) + +xx(MainMenu) +xx(IngameMenu) +xx(HelpMenu) +xx(CreditsMenu) +xx(SaveMenu) +xx(LoadMenu) +xx(SoundMenu) +xx(ConfirmPlayerReset) diff --git a/source/duke3d/src/actors.cpp b/source/duke3d/src/actors.cpp index 83871ebde..d7e43c61f 100644 --- a/source/duke3d/src/actors.cpp +++ b/source/duke3d/src/actors.cpp @@ -7988,13 +7988,13 @@ next_sprite: static void G_DoEffectorLights(void) // STATNUM 14 { - int32_t i; +#ifdef POLYMER + int32_t i; for (SPRITES_OF(STAT_LIGHT, i)) { - switch (sprite[i].lotag) + switch (sprite[i].lotag) { -#ifdef POLYMER case SE_49_POINT_LIGHT: { if (!A_CheckSpriteFlags(i, SFLAG_NOLIGHT) && videoGetRenderMode() == REND_POLYMER && @@ -8156,9 +8156,9 @@ static void G_DoEffectorLights(void) // STATNUM 14 break; } -#endif // POLYMER } } +#endif // POLYMER } #ifdef POLYMER diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 4239e8526..65eaa844f 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -44,6 +44,11 @@ BEGIN_DUKE_NS #define MENU_MARGIN_CENTER 160 #define MENU_HEIGHT_CENTER 100 +// This is for intermediate levels in the episode selection chain. Ion Fury uses this. +MenuGameplayStemEntry g_MenuGameplayEntries[MAXMENUGAMEPLAYENTRIES]; +int ME_NEWGAMECUSTOMENTRIES[MAXMENUGAMEPLAYENTRIES]; +int ME_NEWGAMECUSTOMSUBENTRIES[MAXMENUGAMEPLAYENTRIES][MAXMENUGAMEPLAYENTRIES]; + enum MenuTextFlags_t { MT_Selected = 1 << 0, @@ -72,6 +77,306 @@ MenuFont_t MF_Minifont = { { 4<<16, 5<<16 }, { 1<<16, 1<<16 }, 0, 0, 16 }; +/* +This function prepares data after ART and CON have been processed. +It also initializes some data in loops rather than statically at compile time. +*/ +void Menu_Init(void) +{ + + // prepare menu fonts + // check if tilenum is -1 in case it was set in EVENT_SETDEFAULTS + if ((unsigned)MF_Redfont.tilenum >= MAXTILES) MF_Redfont.tilenum = BIGALPHANUM; + if ((unsigned)MF_Bluefont.tilenum >= MAXTILES) MF_Bluefont.tilenum = STARTALPHANUM; + if ((unsigned)MF_Minifont.tilenum >= MAXTILES) MF_Minifont.tilenum = MINIFONT; + MF_Redfont.emptychar.y = tilesiz[MF_Redfont.tilenum].y << 16; + MF_Bluefont.emptychar.y = tilesiz[MF_Bluefont.tilenum].y << 16; + MF_Minifont.emptychar.y = tilesiz[MF_Minifont.tilenum].y << 16; + if (!minitext_lowercase) + MF_Minifont.textflags |= TEXT_UPPERCASE; + +#if 0 + //int32_t i, j, k; + if (FURY) + { + MMF_Top_Skill.pos.x = (320 << 15); + ME_SKILL_TEMPLATE.format = &MEF_LeftMenu; + } + + // prepare gamefuncs and keys + MEOSN_Gamefuncs[0] = MenuGameFuncNone; + MEOSV_Gamefuncs[0] = -1; + k = 1; + for (i = 0; i < NUMGAMEFUNCTIONS; ++i) + { + MenuGameFuncs[i] = buttonMap.GetButtonAlias(i); + MenuGameFuncs[i].Substitute('_', ' '); + + if (MenuGameFuncs[i][0] != '\0') + { + MEOSN_Gamefuncs[k] = MenuGameFuncs[i]; + MEOSV_Gamefuncs[k] = i; + ++k; + } + } + MEOS_Gamefuncs.numOptions = k; + + for (i = 0; i < NUMKEYS; ++i) + MEOSN_Keys[i] = KB_ScanCodeToString(i); + MEOSN_Keys[NUMKEYS - 1] = MenuKeyNone; + + + // prepare episodes + k = 0; + for (i = 0; i < g_volumeCnt; ++i) + { + if (g_volumeNames[i][0]) + { + if (!(g_volumeFlags[i] & EF_HIDEFROMSP)) + { + MEL_EPISODE[i] = &ME_EPISODE[i]; + ME_EPISODE[i] = ME_EPISODE_TEMPLATE; + ME_EPISODE[i].name = g_volumeNames[i]; + } + + // if (!(EpisodeFlags[i] & EF_HIDEFROMMP)) + { + MEOSN_NetEpisodes[k] = g_volumeNames[i]; + MEOSV_NetEpisodes[k] = i; + + k++; + } + } + + // prepare levels + MEOS_NETOPTIONS_LEVEL[i] = MEOS_NETOPTIONS_LEVEL_TEMPLATE; + for (j = 0; j < MAXLEVELS; ++j) + { + MEOSN_NetLevels[i][j] = g_mapInfo[MAXLEVELS * i + j].name; + if (g_mapInfo[i * MAXLEVELS + j].filename != NULL) + MEOS_NETOPTIONS_LEVEL[i].numOptions = j + 1; + } + MEOS_NETOPTIONS_LEVEL[i].optionNames = MEOSN_NetLevels[i]; + } + M_EPISODE.numEntries = g_volumeCnt + 2; + + MEL_EPISODE[g_volumeCnt] = &ME_Space4_Redfont; + MEL_EPISODE[g_volumeCnt + 1] = &ME_EPISODE_USERMAP; + MEOSN_NetEpisodes[k] = MenuUserMap; + MEOSV_NetEpisodes[k] = MAXVOLUMES; + + MEOS_NETOPTIONS_EPISODE.numOptions = k + 1; + NetEpisode = MEOSV_NetEpisodes[0]; + MMF_Top_Episode.pos.y = (58 + (3 - k) * 6) << 16; + if (g_skillCnt == 0) + MEO_EPISODE.linkID = MENU_NULL; + M_EPISODE.currentEntry = ud.default_volume; + + // prepare new game custom :O + if (g_MenuGameplayEntries[0].entry.isValid()) + { + MEO_MAIN_NEWGAME.linkID = M_NEWVERIFY.linkID = MENU_NEWGAMECUSTOM; + + int e = 0; + for (MenuGameplayStemEntry const& stem : g_MenuGameplayEntries) + { + MenuGameplayEntry const& entry = stem.entry; + if (!entry.isValid()) + break; + + MenuEntry_t& e_me = ME_NEWGAMECUSTOMENTRIES[e]; + e_me = ME_EPISODE_TEMPLATE; + MenuLink_t& e_meo = MEO_NEWGAMECUSTOM[e]; + e_meo = MEO_NEWGAMECUSTOM_TEMPLATE; + e_me.entry = &e_meo; + + e_me.name = entry.name; + if (entry.flags & MGE_Locked) + e_me.flags |= MEF_Disabled; + if (entry.flags & MGE_Hidden) + e_me.flags |= MEF_Hidden; + + int s = 0; + for (MenuGameplayEntry const& subentry : stem.subentries) + { + if (!subentry.isValid()) + break; + + MenuEntry_t& s_me = ME_NEWGAMECUSTOMSUBENTRIES[e][s]; + s_me = ME_EPISODE_TEMPLATE; + MenuLink_t& s_meo = MEO_NEWGAMECUSTOMSUB[e][s]; + s_meo = MEO_NEWGAMECUSTOMSUB_TEMPLATE; + s_me.entry = &s_meo; + + s_me.name = subentry.name; + if (subentry.flags & MGE_Locked) + s_me.flags |= MEF_Disabled; + if (subentry.flags & MGE_Hidden) + s_me.flags |= MEF_Hidden; + + ++s; + } + + if (entry.flags & MGE_UserContent) + e_meo.linkID = MENU_USERMAP; + else if (s == 0) + e_meo.linkID = MENU_SKILL; + + ++e; + } + + Menu_PopulateNewGameCustom(); + } + + // prepare skills + k = -1; + for (i = 0; i < g_skillCnt && g_skillNames[i][0]; ++i) + { + MEL_SKILL[i] = &ME_SKILL[i]; + ME_SKILL[i] = ME_SKILL_TEMPLATE; + ME_SKILL[i].name = g_skillNames[i]; + + MEOSN_NetSkills[i] = g_skillNames[i]; + + k = i; + } + ++k; + M_SKILL.numEntries = g_skillCnt; // k; + MEOS_NETOPTIONS_MONSTERS.numOptions = g_skillCnt + 1; // k+1; + MEOSN_NetSkills[g_skillCnt] = MenuSkillNone; + MMF_Top_Skill.pos.y = (58 + (4 - g_skillCnt) * 6) << 16; + M_SKILL.currentEntry = ud.default_skill; + Menu_AdjustForCurrentEntryAssignmentBlind(&M_SKILL); + + // prepare multiplayer gametypes + k = -1; + for (i = 0; i < MAXGAMETYPES; ++i) + if (g_gametypeNames[i][0]) + { + MEOSN_NetGametypes[i] = g_gametypeNames[i]; + k = i; + } + ++k; + MEOS_NETOPTIONS_GAMETYPE.numOptions = k; + if (NAM_WW2GI) + ME_NETOPTIONS_MONSTERS.name = "Enemies"; + + // prepare cheats + for (i = 0; i < NUMCHEATFUNCS; ++i) + MEL_CHEATS[i + 1] = &ME_CheatCodes[i]; + + // prepare text chat macros + for (i = 0; i < MAXRIDECULE; ++i) + { + MEL_MACROS[i] = &ME_MACROS[i]; + ME_MACROS[i] = ME_MACROS_TEMPLATE; + ME_MACROS[i].entry = &MEO_MACROS[i]; + MEO_MACROS[i] = MEO_MACROS_TEMPLATE; + + MEO_MACROS[i].variable = sink;// ud.ridecule[i]; temporarily disabled + } + + // prepare input + for (i = 0; i < NUMGAMEFUNCTIONS; ++i) + { + if (MenuGameFuncs[i][0] == '\0') + { + MEL_KEYBOARDSETUPFUNCS[i] = NULL; + continue; + } + + MEL_KEYBOARDSETUPFUNCS[i] = &ME_KEYBOARDSETUPFUNCS[i]; + ME_KEYBOARDSETUPFUNCS[i] = ME_KEYBOARDSETUPFUNCS_TEMPLATE; + ME_KEYBOARDSETUPFUNCS[i].name = MenuGameFuncs[i]; + ME_KEYBOARDSETUPFUNCS[i].entry = &MEO_KEYBOARDSETUPFUNCS[i]; + MEO_KEYBOARDSETUPFUNCS[i] = MEO_KEYBOARDSETUPFUNCS_TEMPLATE; + } + M_KEYBOARDKEYS.numEntries = NUMGAMEFUNCTIONS; + for (i = 0; i < 2 * joystick.numButtons + 8 * joystick.numHats; ++i) + { + if (i < 2 * joystick.numButtons) + { + if (i & 1) + Bsnprintf(MenuJoystickNames[i], MAXJOYBUTTONSTRINGLENGTH, "Double %s", joyGetName(1, i >> 1)); + else + Bstrncpy(MenuJoystickNames[i], joyGetName(1, i >> 1), MAXJOYBUTTONSTRINGLENGTH); + } + else + { + Bsnprintf(MenuJoystickNames[i], MAXJOYBUTTONSTRINGLENGTH, (i & 1) ? "Double Hat %d %s" : "Hat %d %s", ((i - 2 * joystick.numButtons) >> 3), MenuJoystickHatDirections[((i - 2 * joystick.numButtons) >> 1) % 4]); + } + } + for (i = 0; i < joystick.numAxes; ++i) + { + ME_JOYSTICKAXES[i] = ME_JOYSTICKAXES_TEMPLATE; + Bstrncpy(MenuJoystickAxes[i], joyGetName(0, i), MAXJOYBUTTONSTRINGLENGTH); + ME_JOYSTICKAXES[i].name = MenuJoystickAxes[i]; + MEL_JOYSTICKAXES[i] = &ME_JOYSTICKAXES[i]; + } + M_JOYSTICKAXES.numEntries = joystick.numAxes; + + // prepare sound setup +#ifndef EDUKE32_STANDALONE + if (WW2GI) + ME_SOUND_DUKETALK.name = "GI talk:"; + else if (NAM) + ME_SOUND_DUKETALK.name = "Grunt talk:"; +#endif + + if (FURY) + { + MF_Redfont.between.x = 2 << 16; + MF_Redfont.cursorScale = 32768; + MF_Redfont.zoom = 16384; + MF_Bluefont.zoom = 16384; + + // hack; should swap out pointers + MF_Minifont = MF_Bluefont; + + MMF_Top_Main.pos.x = 40 << 16; + MMF_Top_Main.pos.y = 130 << 16; + MMF_Top_Main.bottomcutoff = 190 << 16; + M_OPTIONS.format = &MMF_Top_Main; + + MEF_MainMenu.width = MEF_OptionsMenu.width = -(160 << 16); + MEF_MainMenu.marginBottom = 7 << 16; + + M_OPTIONS.title = NoTitle; + + SELECTDIR_z = 16384; + } + + // prepare shareware + if (VOLUMEONE) + { + // blue out episodes beyond the first + for (i = 1; i < g_volumeCnt; ++i) + { + if (MEL_EPISODE[i]) + { + ME_EPISODE[i].entry = &MEO_EPISODE_SHAREWARE; + ME_EPISODE[i].flags |= MEF_LookDisabled; + } + } + M_EPISODE.numEntries = g_volumeCnt; // remove User Map (and spacer) + MEOS_NETOPTIONS_EPISODE.numOptions = 1; + MenuEntry_DisableOnCondition(&ME_NETOPTIONS_EPISODE, 1); + } + + // prepare pre-Atomic + if (!VOLUMEALL || !PLUTOPAK) + { + // prepare credits + M_CREDITS.title = M_CREDITS2.title = M_CREDITS3.title = s_Credits; + } + + MenuEntry_HideOnCondition(&ME_MAIN_HELP, G_GetLogoFlags() & LOGO_NOHELP); +#ifndef EDUKE32_SIMPLE_MENU + MenuEntry_HideOnCondition(&ME_MAIN_CREDITS, G_GetLogoFlags() & LOGO_NOCREDITS); +#endif +#endif +} + static void Menu_DrawTopBar(const vec2_t origin) { if ((G_GetLogoFlags() & LOGO_NOTITLEBAR) == 0) @@ -128,11 +433,11 @@ static vec2_t Menu_Text(int32_t x, int32_t y, const MenuFont_t* font, const char else if (status & MT_Selected) p = (status & MT_RightSide) ? font->pal_selected_right : font->pal_selected; else - p = (status & MT_RightSide) ? font->pal_deselected_right : font->pal_deselected; +p = (status & MT_RightSide) ? font->pal_deselected_right : font->pal_deselected; - Menu_GetFmt(font, status, &s, &z); +Menu_GetFmt(font, status, &s, &z); - return G_ScreenText(font->tilenum, x, y, z, 0, 0, t, s, p, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, font->emptychar.x, font->emptychar.y, font->between.x, ybetween, f, 0, ydim_upper, xdim - 1, ydim_lower); +return G_ScreenText(font->tilenum, x, y, z, 0, 0, t, s, p, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, font->emptychar.x, font->emptychar.y, font->between.x, ybetween, f, 0, ydim_upper, xdim - 1, ydim_lower); } static int32_t Menu_CursorShade(void) @@ -179,7 +484,7 @@ void GameInterface::DrawNativeMenuText(int fontnum, int state, int xpos, int ypo status |= MT_XCenter; bool const dodraw = true; - MenuFont_t &font = fontnum == NIT_BigFont ? MF_Redfont : fontnum == NIT_SmallFont ? MF_Bluefont : MF_Minifont; + MenuFont_t& font = fontnum == NIT_BigFont ? MF_Redfont : fontnum == NIT_SmallFont ? MF_Bluefont : MF_Minifont; int32_t const height = font.get_yline(); status |= MT_YCenter; @@ -227,6 +532,10 @@ protected: void Ticker() override { + auto lf = G_GetLogoFlags(); + help_disabled = (lf & LOGO_NOHELP); + credits_disabled = (lf & LOGO_NOCREDITS); + // Lay out the menu. Since scripts are allowed to mess around with the font this needs to be redone each frame. int32_t y_upper = mDesc->mYpos; int32_t y_lower = y_upper + mDesc->mYbotton; @@ -237,8 +546,22 @@ protected: // None of the menus still being supported will hide entries - only decactivate them if not applicable. int32_t totalheight = 0, numvalidentries = mDesc->mItems.Size(); - for (int e = 0; e < numvalidentries; ++e) + for (unsigned e = 0; e < mDesc->mItems.Size(); ++e) { + auto entry = mDesc->mItems[e]; + entry->mHidden = false; + if (entry->GetAction(nullptr) == NAME_HelpMenu && help_disabled) + { + entry->mHidden = true; + numvalidentries--; + continue; + } + else if (entry->GetAction(nullptr) == NAME_CreditsMenu && credits_disabled) + { + entry->mHidden = true; + numvalidentries--; + continue; + } totalheight += height; } @@ -249,11 +572,13 @@ protected: for (int e = 0; e < numvalidentries; ++e) { auto entry = mDesc->mItems[e]; - - entry->SetY(y_upper + y); - y += height; - totalHeight = y; - y += calculatedentryspacing; + if (!entry->mHidden) + { + entry->SetY(y_upper + y); + y += height; + totalHeight = y; + y += calculatedentryspacing; + } } } @@ -298,6 +623,49 @@ class MainMenu : public DukeListMenu }; +void GameInterface::MenuOpened() +{ + S_PauseSounds(true); + if ((!g_netServer && ud.multimode < 2)) + { + ready2send = 0; + totalclock = ototalclock; + screenpeek = myconnectindex; + } +} + +void GameInterface::MenuSelectSound() +{ + S_PlaySound(KICK_HIT); +} + +void GameInterface::MenuChooseSound() +{ + S_PlaySound(PISTOL_BODYHIT); +} + + +/* +void GameInterface::MenuClosed() +{ + S_PlaySound(EXITMENUSOUND); + if (!ud.pause_on) + S_PauseSounds(false); +} +*/ + +bool GameInterface::CanSave() +{ + if (ud.recstat == 2) return false; + auto &myplayer = *g_player[myconnectindex].ps; + if (sprite[myplayer.i].extra <= 0) + { + P_DoQuote(QUOTE_SAVE_DEAD, &myplayer); + return false; + } + return true; +} + END_DUKE_NS static TMenuClassDescriptor _mm("Duke.MainMenu"); diff --git a/source/duke3d/src/demo.cpp b/source/duke3d/src/demo.cpp index ea8c1f243..9ac934183 100644 --- a/source/duke3d/src/demo.cpp +++ b/source/duke3d/src/demo.cpp @@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "screens.h" #include "i_specialpaths.h" #include "printf.h" +#include "menu/menu.h" BEGIN_DUKE_NS @@ -55,9 +56,9 @@ static int32_t demorec_seeds=1, demo_hasseeds; static void Demo_RestoreModes(int32_t menu) { if (menu) - Menu_Open(myconnectindex); + M_StartControlPanel(false); else - Menu_Close(myconnectindex); + M_ClearMenus(); g_player[myconnectindex].ps->gm &= ~MODE_GAME; g_player[myconnectindex].ps->gm |= MODE_DEMO; @@ -488,7 +489,7 @@ RECHECK: fadepal(0,0,0, 0,252,28); P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 1); // JBF 20040308 G_DrawBackground(); - M_DisplayMenus(); + //M_DisplayMenus(); videoNextPage(); fadepal(0,0,0, 252,0,-28); ud.reccnt = 0; @@ -522,7 +523,7 @@ RECHECK: { FX_StopAllSounds(); S_ClearSoundLocks(); - Menu_Open(myconnectindex); + M_StartControlPanel(false); } ready2send = 0; @@ -663,7 +664,7 @@ RECHECK: corrupt: OSD_Printf(OSD_ERROR "Demo %d is corrupt (code %d).\n", g_whichDemo-1, corruptcode); nextdemo: - Menu_Open(myconnectindex); + M_StartControlPanel(false); nextdemo_nomenu: foundemo = 0; ud.reccnt = 0; @@ -856,16 +857,6 @@ nextdemo_nomenu: goto RECHECK; } - if (I_EscapeTrigger() && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0 && (g_player[myconnectindex].ps->gm&MODE_TYPE) == 0) - { - I_EscapeTriggerClear(); - FX_StopAllSounds(); - S_ClearSoundLocks(); - Menu_Open(myconnectindex); - Menu_Change(MENU_MAIN); - S_MenuSound(); - } - if (Demo_IsProfiling()) { // Do nothing: sampletimer() is reached from M_DisplayMenus() -> @@ -878,15 +869,15 @@ nextdemo_nomenu: if ((g_player[myconnectindex].ps->gm&MODE_TYPE) != MODE_TYPE) { g_player[myconnectindex].ps->gm = 0; - Menu_Open(myconnectindex); + M_StartControlPanel(false); } } else { - if (ud.recstat != 2) - M_DisplayMenus(); + //if (ud.recstat != 2) + // M_DisplayMenus(); - if ((g_netServer || ud.multimode > 1) && !Menu_IsTextInput(m_currentMenu)) + if ((g_netServer || ud.multimode > 1))// && !Menu_IsTextInput(m_currentMenu)) { ControlInfo noshareinfo; CONTROL_GetInput(&noshareinfo); diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index 4fed016c8..36ebf07dd 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -157,6 +157,10 @@ struct GameInterface : ::GameInterface // Access to the front end specific menu code. Use is restricted to the main menu, the ingame menu and the skill/episode selection. // Everything else is either custom screens or will use the generic option menu style. void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int orientation = TOR_Default) override; + void MenuOpened() override; + void MenuSelectSound() override; + void MenuChooseSound() override; + bool CanSave() override; }; diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 625dcd27a..aeac1605c 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -44,8 +44,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gameconfigfile.h" #include "printf.h" #include "m_argv.h" +#include "c_dispatch.h" #include "filesystem/filesystem.h" #include "statistics.h" +#include "menu/menu.h" // Uncomment to prevent anything except mirrors from drawing. It is sensible to // also uncomment ENGINE_CLEAR_SCREEN in build/src/engine_priv.h. @@ -204,13 +206,6 @@ void G_HandleSpecialKeys(void) G_UpdateScreenArea(); } - if (inputState.UnboundKeyPressed(sc_F12)) - { - inputState.ClearKeyStatus(sc_F12); - videoCaptureScreen(); - P_DoQuote(QUOTE_SCREEN_SAVED, &myplayer); - } - // only dispatch commands here when not in a game if ((myplayer.gm & MODE_GAME) != MODE_GAME) OSD_DispatchQueued(); @@ -4717,84 +4712,6 @@ void G_HandleLocalKeys(void) typebuf[0] = 0; } - if (inputState.UnboundKeyPressed(sc_F1) && !(G_GetLogoFlags() & LOGO_NOHELP)/* || (ud.show_help && I_AdvanceTrigger())*/) - { - inputState.ClearKeyStatus(sc_F1); - - Menu_Change(MENU_STORY); - S_PauseSounds(true); - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2)) - { - ready2send = 0; - totalclock = ototalclock; - screenpeek = myconnectindex; - } - } - - // if((!net_server && ud.multimode < 2)) - { - if (ud.recstat != 2 && inputState.UnboundKeyPressed(sc_F2)) - { - inputState.ClearKeyStatus(sc_F2); - -FAKE_F2: - if (sprite[myplayer.i].extra <= 0) - { - P_DoQuote(QUOTE_SAVE_DEAD, &myplayer); - return; - } - - Menu_Change(MENU_SAVE); - - S_PauseSounds(true); - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2)) - { - ready2send = 0; - totalclock = ototalclock; - screenpeek = myconnectindex; - } - } - - if (inputState.UnboundKeyPressed(sc_F3)) - { - inputState.ClearKeyStatus(sc_F3); - -FAKE_F3: - Menu_Change(MENU_LOAD); - S_PauseSounds(true); - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) - { - ready2send = 0; - totalclock = ototalclock; - } - - screenpeek = myconnectindex; - } - } - - if (inputState.GetKeyStatus(sc_F4)) - if (inputState.UnboundKeyPressed(sc_F4)) - { - inputState.ClearKeyStatus(sc_F4); - - S_PauseSounds(true); - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) - { - ready2send = 0; - totalclock = ototalclock; - } - - Menu_Change(MENU_SOUND_INGAME); - } - if (inputState.UnboundKeyPressed(sc_F5) && MusicEnabled()) { map_t *const pMapInfo = &g_mapInfo[g_musicIndex]; @@ -4816,9 +4733,11 @@ FAKE_F3: g_doQuickSave = 0; - if (!g_lastusersave.isValid()) - goto FAKE_F2; - + if (!g_lastusersave.isValid()) + { + C_DoCommand("opensavemenu"); + return; + } inputState.keyFlushChars(); if (sprite[myplayer.i].extra <= 0) @@ -4875,8 +4794,10 @@ FAKE_F3: g_doQuickSave = 0; - if (g_quickload == nullptr || !g_quickload->isValid()) - goto FAKE_F3; + if (g_quickload == nullptr || !g_quickload->isValid()) + { + C_DoCommand("openloadmenu"); + } else if (g_quickload->isValid()) { inputState.keyFlushChars(); @@ -4887,36 +4808,6 @@ FAKE_F3: } } - if (inputState.UnboundKeyPressed(sc_F10)) - { - inputState.ClearKeyStatus(sc_F10); - - Menu_Change(MENU_QUIT_INGAME); - S_PauseSounds(true); - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) - { - ready2send = 0; - totalclock = ototalclock; - } - } - - if (inputState.UnboundKeyPressed(sc_F11)) - { - inputState.ClearKeyStatus(sc_F11); - - Menu_Change(MENU_COLCORR_INGAME); - S_PauseSounds(true); - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) - { - ready2send = 0; - totalclock = ototalclock; - } - } - if (ud.overhead_on != 0) { int const timerOffset = ((int) totalclock - nonsharedtimer); @@ -4963,17 +4854,6 @@ FAKE_F3: ud.last_overhead = ud.overhead_on; } -#ifdef __ANDROID__ - if (ud.overhead_on == 1) - ud.scrollmode = 0; - else if (ud.overhead_on == 2) - { - ud.scrollmode = 1; - ud.folx = g_player[screenpeek].ps->opos.x; - ud.foly = g_player[screenpeek].ps->opos.y; - ud.fola = g_player[screenpeek].ps->oang; - } -#endif g_restorePalette = 1; G_UpdateScreenArea(); } @@ -6006,8 +5886,8 @@ void G_BackToMenu(void) if (ud.recstat == 1) G_CloseDemoWrite(); ud.warp_on = 0; g_player[myconnectindex].ps->gm = 0; - Menu_Open(myconnectindex); - Menu_Change(MENU_MAIN); + M_StartControlPanel(false); + M_SetMenu(NAME_MainMenu); inputState.keyFlushChars(); } @@ -6050,9 +5930,9 @@ static int G_EndOfLevel(void) G_DoOrderScreen(); #endif p.gm = 0; - Menu_Open(myconnectindex); - Menu_Change(MENU_MAIN); - return 2; + M_StartControlPanel(false); + M_SetMenu(NAME_MainMenu); + return 2; } else { @@ -6335,8 +6215,6 @@ MAIN_LOOP_RESTART: for (int32_t & q : user_quote_time) q = 0; - Menu_Change(MENU_MAIN); - if(g_netClient) { OSD_Printf("Waiting for initial snapshot..."); @@ -6380,6 +6258,9 @@ MAIN_LOOP_RESTART: if (g_networkMode != NET_DEDICATED_SERVER) { + M_StartControlPanel(false); + M_SetMenu(NAME_MainMenu); + if (G_PlaybackDemo()) { FX_StopAllSounds(); @@ -6390,6 +6271,7 @@ MAIN_LOOP_RESTART: } else G_UpdateScreenArea(); + // G_GameExit(" "); /// ud.showweapons = ud.config.ShowWeapons; diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index c5d614877..398b9a592 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -37,6 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "files.h" #include "base64.h" #include "version.h" +#include "menu/menu.h" #include "debugbreak.h" @@ -1059,7 +1060,7 @@ static void VM_Fall(int const spriteNum, spritetype * const pSprite) static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags, int32_t const resetFlags) { - //AddLog("resetplayer"); + // Who thought that allowing a script to do this shit is a good idea??? if (!g_netServer && ud.multimode < 2 && !(resetFlags & 2)) { if (g_quickload && g_quickload->isValid() && ud.recstat != 2 && !(resetFlags & 8)) @@ -1078,10 +1079,10 @@ static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags, int32_t cons } else if (!(resetFlags & 1)) { - Menu_Open(playerNum); inputState.ClearKeyStatus(sc_Space); I_AdvanceTriggerClear(); - Menu_Change(MENU_RESETPLAYER); + M_StartControlPanel(false); + M_SetMenu(NAME_ConfirmPlayerReset); } } else @@ -4130,7 +4131,8 @@ badindex: vInstruction(CON_CMENU): insptr++; - Menu_Change(Gv_GetVar(*insptr++)); + // Well, sorry, but - no. + //Menu_Change(Gv_GetVar(*insptr++)); dispatch(); vInstruction(CON_SOUND): diff --git a/source/duke3d/src/gamestructures.cpp b/source/duke3d/src/gamestructures.cpp index da3abf8b6..c3bc39c7a 100644 --- a/source/duke3d/src/gamestructures.cpp +++ b/source/duke3d/src/gamestructures.cpp @@ -915,11 +915,13 @@ void __fastcall VM_SetPlayer(int const playerNum, int const labelNum, int const break; case PLAYER_GM: + /* WTF?!? if (!(ps.gm & MODE_MENU) && (newValue & MODE_MENU)) Menu_Open(playerNum); else if ((ps.gm & MODE_MENU) && !(newValue & MODE_MENU)) Menu_Close(playerNum); - ps.gm = newValue; + */ + ps.gm = newValue & ~MODE_MENU; break; case PLAYER_GOTWEAPON: @@ -1752,12 +1754,12 @@ void __fastcall VM_SetUserdef(int const labelNum, int const lParm2, int32_t cons case USERDEFS_NEWGAMECUSTOMOPEN: for (unsigned int b = 0; b < MAXMENUGAMEPLAYENTRIES; ++b) if (iSet & (1u<parms[0]); - if (picnum != INT32_MIN) - i = !i; -#else int32_t j; for (j=0; j<2; j++) @@ -499,7 +488,6 @@ static int osdcmd_spawn(osdcmdptr_t parm) if (i < g_labelCnt) break; } -#endif if (i==g_labelCnt) { OSD_Printf("spawn: Invalid tile label given\n"); @@ -534,7 +522,6 @@ static int osdcmd_spawn(osdcmdptr_t parm) return OSDCMD_OK; } -#if !defined LUNATIC static int osdcmd_setvar(osdcmdptr_t parm) { if (numplayers > 1) @@ -627,59 +614,6 @@ static int osdcmd_setactorvar(osdcmdptr_t parm) return OSDCMD_OK; } -#else -static int osdcmd_lua(osdcmdptr_t parm) -{ - // Should be used like - // lua "lua code..." - // (the quotes making the whole string passed as one argument) - - int32_t ret; - - if (parm->numparms != 1) - return OSDCMD_SHOWHELP; - - if (!L_IsInitialized(&g_ElState)) - { - OSD_Printf("Lua state is not initialized.\n"); - return OSDCMD_OK; - } - - // TODO: "=" as shorthand for "print()", like in the - // stand-alone Lua interpreter? - // TODO: reserve some table to explicitly store stuff on the top level, for - // debugging convenience? - - // For the 'lua' OSD command, don't make errors appear on-screen: - el_addNewErrors = 0; - ret = L_RunString(&g_ElState, parm->parms[0], -1, "console"); - el_addNewErrors = 1; - - if (ret != 0) - OSD_Printf("Error running the Lua code (error code %d)\n", ret); - - return OSDCMD_OK; -} -#endif - -static int osdcmd_cmenu(osdcmdptr_t parm) -{ - if (parm->numparms != 1) - return OSDCMD_SHOWHELP; - - if (numplayers > 1) - { - OSD_Printf("Command not allowed in multiplayer\n"); - return OSDCMD_OK; - } - - if ((g_player[myconnectindex].ps->gm & MODE_MENU) != MODE_MENU) - Menu_Open(myconnectindex); - - Menu_Change(Batol(parm->parms[0])); - - return OSDCMD_OK; -} @@ -806,44 +740,6 @@ static int osdcmd_quickload(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_screenshot(osdcmdptr_t parm) -{ - videoCaptureScreen(); - return OSDCMD_OK; -} - -#if 0 -static int osdcmd_savestate(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_PARAMETER(parm); - G_SaveMapState(); - return OSDCMD_OK; -} - -static int osdcmd_restorestate(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_PARAMETER(parm); - G_RestoreMapState(); - return OSDCMD_OK; -} -#endif - -#ifdef DEBUGGINGAIDS -static int osdcmd_inittimer(osdcmdptr_t parm) -{ - if (parm->numparms != 1) - { - OSD_Printf("%dHz timer\n",g_timerTicsPerSecond); - return OSDCMD_SHOWHELP; - } - - G_InitTimer(Batol(parm->parms[0])); - - OSD_Printf("%s\n",parm->raw); - return OSDCMD_OK; -} -#endif - static int osdcmd_dumpmapstate(osdfuncparm_t const * const) { @@ -1116,7 +1012,6 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("demo","demo : starts the given demo", osdcmd_demo); } - OSD_RegisterFunction("cmenu","cmenu <#>: jumps to menu", osdcmd_cmenu); OSD_RegisterFunction("crosshaircolor","crosshaircolor: changes the crosshair color", osdcmd_crosshaircolor); OSD_RegisterFunction("give","give : gives requested item", osdcmd_give); @@ -1141,7 +1036,6 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("setvar","setvar : sets the value of a gamevar", osdcmd_setvar); OSD_RegisterFunction("setvarvar","setvarvar : sets the value of to ", osdcmd_setvar); OSD_RegisterFunction("setactorvar","setactorvar : sets the value of 's to ", osdcmd_setactorvar); - OSD_RegisterFunction("screenshot","screenshot [format]: takes a screenshot.", osdcmd_screenshot); OSD_RegisterFunction("spawn","spawn [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",osdcmd_spawn); diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index 180ae4f38..ac66b21c4 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "menus.h" #include "savegame.h" #include "statistics.h" +#include "menu/menu.h" BEGIN_DUKE_NS static uint8_t precachehightile[2][(MAXTILES+7)>>3]; @@ -1358,7 +1359,7 @@ void G_NewGame(int volumeNum, int levelNum, int skillNum) #endif p0.gm = 0; - Menu_Close(0); + M_ClearMenus(); #if !defined LUNATIC Gv_ResetVars(); @@ -1911,12 +1912,12 @@ int G_EnterLevel(int gameMode) } } + M_ClearMenus(); if (gameMode & (MODE_GAME|MODE_EOL)) { for (int TRAVERSE_CONNECT(i)) { g_player[i].ps->gm = MODE_GAME; - Menu_Close(i); } } else if (gameMode & MODE_RESTART) diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index 9bbbb4008..2695d3d03 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "statistics.h" #include "secrets.h" #include "savegamehelp.h" +#include "menu/menu.h" BEGIN_DUKE_NS @@ -502,7 +503,7 @@ int32_t G_LoadPlayer(savebrief_t & sv) #endif p0.gm = 0; - Menu_Close(0); + M_ClearMenus(); #if !defined LUNATIC Gv_ResetVars(); diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index 3b2dfe562..d0f4d5eee 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -1003,19 +1003,12 @@ void G_DisplayRest(int32_t smoothratio) } } +#if 0 if (I_EscapeTrigger() && ud.overhead_on == 0 && ud.show_help == 0 && g_player[myconnectindex].ps->newowner == -1) { - if ((g_player[myconnectindex].ps->gm&MODE_MENU) == MODE_MENU && g_currentMenu <= MENU_MAIN_INGAME) - { - I_EscapeTriggerClear(); - S_PlaySound(EXITMENUSOUND); - Menu_Change(MENU_CLOSE); - if (!ud.pause_on) - S_PauseSounds(false); - } - else if ((g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU && + if ((g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU && g_player[myconnectindex].ps->newowner == -1 && (g_player[myconnectindex].ps->gm&MODE_TYPE) != MODE_TYPE) { @@ -1033,6 +1026,7 @@ void G_DisplayRest(int32_t smoothratio) S_MenuSound(); } } +#endif if (g_player[myconnectindex].ps->newowner == -1 && ud.overhead_on == 0 && cl_crosshair && ud.camerasprite == -1) { @@ -1157,8 +1151,8 @@ void G_DisplayRest(int32_t smoothratio) { if (g_player[myconnectindex].ps->gm&MODE_TYPE) Net_SendMessage(); - else - M_DisplayMenus(); + //else + //M_DisplayMenus(); } { @@ -1182,7 +1176,6 @@ void G_DisplayRest(int32_t smoothratio) GameStats GameInterface::getStats() { - GameStats stats; DukePlayer_t* p = g_player[myconnectindex].ps; return { p->actors_killed, p->max_actors_killed, p->secret_rooms, p->max_secret_rooms, p->player_par / REALGAMETICSPERSEC }; } diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 3ed55ff05..928497a2a 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -183,13 +183,6 @@ void G_HandleSpecialKeys(void) G_UpdateScreenArea(); } - if (inputState.UnboundKeyPressed(sc_F12)) - { - inputState.ClearKeyStatus(sc_F12); - videoCaptureScreen(); - P_DoQuote(QUOTE_SCREEN_SAVED, g_player[myconnectindex].ps); - } - // only dispatch commands here when not in a game if (!(g_player[myconnectindex].ps->gm & MODE_GAME)) OSD_DispatchQueued(); @@ -6338,21 +6331,6 @@ FAKE_F3: Menu_Change(MENU_SOUND_INGAME); } - if (inputState.UnboundKeyPressed(sc_F5) && MusicEnabled()) - { - map_t *const pMapInfo = &g_mapInfo[g_musicIndex]; - char *const musicString = apStrings[QUOTE_MUSIC]; - - inputState.ClearKeyStatus(sc_F5); - - if (pMapInfo->musicfn != NULL) - Bsnprintf(musicString, MAXQUOTELEN, "%s. Use SHIFT-F5 to change.", pMapInfo->musicfn); - else - musicString[0] = '\0'; - - P_DoQuote(QUOTE_MUSIC, g_player[myconnectindex].ps); - } - if ((buttonMap.ButtonDown(gamefunc_Quick_Save) || g_doQuickSave == 1) && (!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && (g_player[myconnectindex].ps->gm&MODE_GAME)) { buttonMap.ClearButton(gamefunc_Quick_Save); diff --git a/source/rr/src/osdcmds.cpp b/source/rr/src/osdcmds.cpp index c42665d92..c380a897d 100644 --- a/source/rr/src/osdcmds.cpp +++ b/source/rr/src/osdcmds.cpp @@ -519,27 +519,6 @@ static int osdcmd_spawn(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_cmenu(osdcmdptr_t parm) -{ - if (parm->numparms != 1) - return OSDCMD_SHOWHELP; - - if (numplayers > 1) - { - OSD_Printf("Command not allowed in multiplayer\n"); - return OSDCMD_OK; - } - - if ((g_player[myconnectindex].ps->gm & MODE_MENU) != MODE_MENU) - Menu_Open(myconnectindex); - - Menu_Change(Batol(parm->parms[0])); - - return OSDCMD_OK; -} - - - static int osdcmd_crosshaircolor(osdcmdptr_t parm) { @@ -664,45 +643,6 @@ static int osdcmd_quickload(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_screenshot(osdcmdptr_t parm) -{ - videoCaptureScreen(); - - return OSDCMD_OK; -} - -#if 0 -static int osdcmd_savestate(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_PARAMETER(parm); - G_SaveMapState(); - return OSDCMD_OK; -} - -static int osdcmd_restorestate(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_PARAMETER(parm); - G_RestoreMapState(); - return OSDCMD_OK; -} -#endif - -#ifdef DEBUGGINGAIDS -static int osdcmd_inittimer(osdcmdptr_t parm) -{ - if (parm->numparms != 1) - { - OSD_Printf("%dHz timer\n",g_timerTicsPerSecond); - return OSDCMD_SHOWHELP; - } - - G_InitTimer(Batol(parm->parms[0])); - - OSD_Printf("%s\n",parm->raw); - return OSDCMD_OK; -} -#endif - #if !defined NETCODE_DISABLE static int osdcmd_disconnect(osdcmdptr_t UNUSED(parm)) { @@ -911,7 +851,6 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("demo","demo : starts the given demo", osdcmd_demo); } - OSD_RegisterFunction("cmenu","cmenu <#>: jumps to menu", osdcmd_cmenu); OSD_RegisterFunction("crosshaircolor","crosshaircolor: changes the crosshair color", osdcmd_crosshaircolor); #if !defined NETCODE_DISABLE @@ -950,8 +889,6 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap); OSD_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound); - OSD_RegisterFunction("screenshot","screenshot [format]: takes a screenshot.", osdcmd_screenshot); - OSD_RegisterFunction("spawn","spawn [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",osdcmd_spawn); OSD_RegisterFunction("vidmode","vidmode : change the video mode",osdcmd_vidmode); diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index de415fbf7..46399de54 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -1665,22 +1665,6 @@ void ResChange(void) } #endif -void ScreenCaptureKeys(void) -{ - if (ConPanel) - return; - - // screen capture - if (inputState.GetKeyStatus(KEYSC_F12)) - { - inputState.ClearKeyStatus(KEYSC_F12); - PauseAction(); - videoCaptureScreen(); - ResumeAction(); - PutStringInfo(Player + myconnectindex, "Screen Captured"); - } -} - void DrawCheckKeys(PLAYERp pp) { extern SWBOOL ResCheat; @@ -1696,8 +1680,6 @@ void DrawCheckKeys(PLAYERp pp) if (!InputMode) ResizeView(pp); - - ScreenCaptureKeys(); } #if 0 diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 7ae7c0378..4483a9caf 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -2368,7 +2368,6 @@ void BonusScreen(PLAYERp pp) MNU_DrawString(TEXT_TEST_COL(w), 185, ds,1,19); videoNextPage(); - ScreenCaptureKeys(); if (State == State->NextState) BonusDone = TRUE; @@ -2590,8 +2589,6 @@ void StatScreen(PLAYERp mpp) while (!inputState.GetKeyStatus(KEYSC_SPACE) && !inputState.GetKeyStatus(KEYSC_ENTER)) { handleevents(); - - ScreenCaptureKeys(); } StopSound(); diff --git a/wadsrc/static/demolition/defbinds.all b/wadsrc/static/demolition/defbinds.all new file mode 100644 index 000000000..83c9546b9 --- /dev/null +++ b/wadsrc/static/demolition/defbinds.all @@ -0,0 +1,15 @@ +// These bindings are valid for all configurationas + +F1 "openhelpmenu" +F2 "opensavemenu" +F3 "openloadmenu" +F4 "openmenu SoundOptions" +F5 "openmeun OptionMenu" //this key performs some fuckery with the music in Duke Nukem,so the default here is Blood's. +F6 "+Quick_Save" +F7 "+Third_Person_View" +//F8 "toggle hud_messages" // this one needs a means to print the status to the quote display. +F9 "+Quick_Load" +F10 "openmenu QuitIngame" +F11 "openmenu ColorCorrection" +F12 "screenshot" + diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 7470f6123..0b5f699ea 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -6,6 +6,7 @@ LISTMENU "MainMenu" { + ScriptId 1 ifgame(Duke, Nam, WW2GI, Fury) { ifgame(fury) @@ -68,3 +69,61 @@ LISTMENU "MainMenu" } } + +LISTMENU "IngameMenu" +{ + ifgame(Duke, Nam, WW2GI, Fury) + { + ifgame(fury) + { + position 40, 130, 60, -160 + } + else + { + position 160, 55, 115, 0 + centermenu + } + linespacing 15 + class "Duke.MainMenu" + NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" + NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" + NativeTextItem "$MNU_HELP", "h", "HelpMenu" + NativeTextItem "$MNU_ENDGAME", "e", "QuitToMenu" + NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" + } + ifgame(Redneck, RedneckRides) + { + linespacing 15 + NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" + NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" + NativeTextItem "$MNU_HELP", "h", "HelpMenu" + NativeTextItem "$MNU_ENDGAME", "e", "QuitToMenu" + NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" + } + ifgame(Blood) + { + linespacing 15 + NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" + NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" + NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + NativeTextItem "$MNU_HELP", "h", "HelpMenu" + NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" + NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" + } + ifgame(ShadowWarrior) + { + linespacing 15 + NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" + NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" + NativeTextItem "$MNU_COOLSTUFF", "h", "HelpMenu" + NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" + } +} + diff --git a/wadsrc/static/filter/duke/demolition/defbinds.txt b/wadsrc/static/filter/duke/demolition/defbinds.txt index c42bb1742..07c52db2b 100644 --- a/wadsrc/static/filter/duke/demolition/defbinds.txt +++ b/wadsrc/static/filter/duke/demolition/defbinds.txt @@ -66,9 +66,6 @@ Q "+Quick_Kick" ` "toggleconsole" Capslock "+AutoRun" X "+Last_Used_Weapon" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" C "+Toggle_Crouch" Mouse1 "+Fire" Mouse2 "+Jetpack" diff --git a/wadsrc/static/filter/duke/demolition/leftbinds.txt b/wadsrc/static/filter/duke/demolition/leftbinds.txt index cd2f8dbfe..8d08af393 100644 --- a/wadsrc/static/filter/duke/demolition/leftbinds.txt +++ b/wadsrc/static/filter/duke/demolition/leftbinds.txt @@ -61,9 +61,6 @@ Q "+Quick_Kick" ; "+Previous_Weapon" ` "toggleconsole" Capslock "+AutoRun" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" Mouse1 "+Fire" Mouse2 "+Open" Mouse3 "+Run" diff --git a/wadsrc/static/filter/duke/demolition/origbinds.txt b/wadsrc/static/filter/duke/demolition/origbinds.txt index 8f0bf2ccc..3cd17cb62 100644 --- a/wadsrc/static/filter/duke/demolition/origbinds.txt +++ b/wadsrc/static/filter/duke/demolition/origbinds.txt @@ -68,9 +68,6 @@ R "+Steroids" ; "+Previous_Weapon" C "toggleconsole" Capslock "+AutoRun" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" diff --git a/wadsrc/static/filter/ionfury/demolition/defbinds.txt b/wadsrc/static/filter/ionfury/demolition/defbinds.txt index 0d6cfee6a..f65bbcbfb 100644 --- a/wadsrc/static/filter/ionfury/demolition/defbinds.txt +++ b/wadsrc/static/filter/ionfury/demolition/defbinds.txt @@ -60,9 +60,6 @@ K "+See_Coop_View" ` "toggleconsole" Capslock "+AutoRun" X "+Last_Used_Weapon" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" C "+Toggle_Crouch" Mouse1 "+Fire" Mouse2 "+Jetpack" diff --git a/wadsrc/static/filter/ionfury/demolition/leftbinds.txt b/wadsrc/static/filter/ionfury/demolition/leftbinds.txt index 30a7a866c..39d507542 100644 --- a/wadsrc/static/filter/ionfury/demolition/leftbinds.txt +++ b/wadsrc/static/filter/ionfury/demolition/leftbinds.txt @@ -59,9 +59,6 @@ I "+Toggle_Crosshair" ; "+Previous_Weapon" ` "toggleconsole" Capslock "+AutoRun" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" Mouse1 "+Fire" Mouse2 "+Open" Mouse3 "+Run" diff --git a/wadsrc/static/filter/ionfury/demolition/origbinds.txt b/wadsrc/static/filter/ionfury/demolition/origbinds.txt index b3c3a0a63..a2162df89 100644 --- a/wadsrc/static/filter/ionfury/demolition/origbinds.txt +++ b/wadsrc/static/filter/ionfury/demolition/origbinds.txt @@ -62,9 +62,6 @@ I "+Toggle_Crosshair" ; "+Previous_Weapon" C "toggleconsole" Capslock "+AutoRun" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" diff --git a/wadsrc/static/filter/nam/demolition/defbinds.txt b/wadsrc/static/filter/nam/demolition/defbinds.txt index c42bb1742..07c52db2b 100644 --- a/wadsrc/static/filter/nam/demolition/defbinds.txt +++ b/wadsrc/static/filter/nam/demolition/defbinds.txt @@ -66,9 +66,6 @@ Q "+Quick_Kick" ` "toggleconsole" Capslock "+AutoRun" X "+Last_Used_Weapon" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" C "+Toggle_Crouch" Mouse1 "+Fire" Mouse2 "+Jetpack" diff --git a/wadsrc/static/filter/nam/demolition/leftbinds.txt b/wadsrc/static/filter/nam/demolition/leftbinds.txt index 7006cc1eb..ae728a200 100644 --- a/wadsrc/static/filter/nam/demolition/leftbinds.txt +++ b/wadsrc/static/filter/nam/demolition/leftbinds.txt @@ -65,9 +65,6 @@ Q "+Quick_Kick" ; "+Previous_Weapon" ` "toggleconsole" Capslock "+AutoRun" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" Mouse1 "+Fire" Mouse2 "+Open" Mouse3 "+Run" diff --git a/wadsrc/static/filter/nam/demolition/origbinds.txt b/wadsrc/static/filter/nam/demolition/origbinds.txt index 8f0bf2ccc..3cd17cb62 100644 --- a/wadsrc/static/filter/nam/demolition/origbinds.txt +++ b/wadsrc/static/filter/nam/demolition/origbinds.txt @@ -68,9 +68,6 @@ R "+Steroids" ; "+Previous_Weapon" C "toggleconsole" Capslock "+AutoRun" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" diff --git a/wadsrc/static/filter/redneck/demolition/defbinds.txt b/wadsrc/static/filter/redneck/demolition/defbinds.txt index 41aaede53..092a05cf9 100644 --- a/wadsrc/static/filter/redneck/demolition/defbinds.txt +++ b/wadsrc/static/filter/redneck/demolition/defbinds.txt @@ -67,9 +67,6 @@ Q "+Quick_Kick" ` "toggleconsole" + "+Dpad_Select" X "+Last_Used_Weapon" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" diff --git a/wadsrc/static/filter/redneck/demolition/leftbinds.txt b/wadsrc/static/filter/redneck/demolition/leftbinds.txt index abe5376c6..d7def8ae0 100644 --- a/wadsrc/static/filter/redneck/demolition/leftbinds.txt +++ b/wadsrc/static/filter/redneck/demolition/leftbinds.txt @@ -64,9 +64,6 @@ Q "+Quick_Kick" ' "+Next_Weapon" ; "+Previous_Weapon" ` "toggleconsole" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" Mouse1 "+Fire" Mouse2 "+Open" Mouse3 "+Run" diff --git a/wadsrc/static/filter/redneck/demolition/origbinds.txt b/wadsrc/static/filter/redneck/demolition/origbinds.txt index 978b05640..9144ec6a4 100644 --- a/wadsrc/static/filter/redneck/demolition/origbinds.txt +++ b/wadsrc/static/filter/redneck/demolition/origbinds.txt @@ -69,6 +69,3 @@ M "+Steroids" ' "+Next_Weapon" ; "+Previous_Weapon" V "toggleconsole" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" diff --git a/wadsrc/static/filter/ww2gi/demolition/defbinds.txt b/wadsrc/static/filter/ww2gi/demolition/defbinds.txt index c42bb1742..07c52db2b 100644 --- a/wadsrc/static/filter/ww2gi/demolition/defbinds.txt +++ b/wadsrc/static/filter/ww2gi/demolition/defbinds.txt @@ -66,9 +66,6 @@ Q "+Quick_Kick" ` "toggleconsole" Capslock "+AutoRun" X "+Last_Used_Weapon" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" C "+Toggle_Crouch" Mouse1 "+Fire" Mouse2 "+Jetpack" diff --git a/wadsrc/static/filter/ww2gi/demolition/leftbinds.txt b/wadsrc/static/filter/ww2gi/demolition/leftbinds.txt index 83e14ed3e..957df7637 100644 --- a/wadsrc/static/filter/ww2gi/demolition/leftbinds.txt +++ b/wadsrc/static/filter/ww2gi/demolition/leftbinds.txt @@ -66,9 +66,6 @@ Q "+Quick_Kick" ; "+Previous_Weapon" ` "toggleconsole" Capslock "+AutoRun" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" Mouse1 "+Fire" Mouse2 "+Open" Mouse3 "+Run" diff --git a/wadsrc/static/filter/ww2gi/demolition/origbinds.txt b/wadsrc/static/filter/ww2gi/demolition/origbinds.txt index 07b541143..44d4a1eaa 100644 --- a/wadsrc/static/filter/ww2gi/demolition/origbinds.txt +++ b/wadsrc/static/filter/ww2gi/demolition/origbinds.txt @@ -69,9 +69,6 @@ R "+Steroids" ; "+Previous_Weapon" C "toggleconsole" Capslock "+AutoRun" -F6 "+Quick_Save" -F9 "+Quick_Load" -F7 "+Third_Person_View" Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" From a96f1b25f775f8469e19b1b17333888bc0dcbfba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Nov 2019 17:52:54 +0100 Subject: [PATCH 010/203] - fixed recursion issue with menu and CON scripting. Curse all those busy loops in the engine. --- source/build/src/engine.cpp | 26 ++++++++++++++------------ source/duke3d/src/gameexec.cpp | 8 +++++++- source/rr/src/gameexec.cpp | 6 +++++- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index d67f72f81..ae2e4478c 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -10040,8 +10040,22 @@ void DrawFullscreenBlends(); // void videoNextPage(void) { + static bool recursion; permfifotype *per; + if (!recursion) + { + // This protection is needed because the menu can call scripts and the scripts can call the busy-looping Screen_Play script event + // which calls videoNextPage for page flipping again. In this loop the UI drawers may not get called again. + // Ideally this stuff should be moved out of videoNextPage so that all those busy loops won't call UI overlays at all. + recursion = true; + M_Drawer(); + FStat::PrintStat(); + C_DrawConsole(); + recursion = false; + } + + if (in3dmode()) { // software rendering only @@ -10058,25 +10072,13 @@ void videoNextPage(void) g_beforeSwapTime = timerGetHiTicks(); - // Draw the ImGui menu on top of the game content, but below the console (if open.) - if (GUICapture & 6) - { - ImGui::Render(); - GLInterface.DrawImGui(ImGui::GetDrawData()); - GUICapture &= ~4; - } - // Draw the console plus debug output on top of everything else. DrawFullscreenBlends(); - M_Drawer(); - FStat::PrintStat(); - C_DrawConsole(); GLInterface.Draw2D(&twod); videoShowFrame(0); - // software rendering only videoBeginDrawing(); //{{{ for (bssize_t i=permtail; i!=permhead; i=((i+1)&(MAXPERMS-1))) { diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index 398b9a592..9d6e871a6 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -40,6 +40,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "menu/menu.h" #include "debugbreak.h" +extern bool rotatesprite_2doverride; BEGIN_DUKE_NS @@ -1219,13 +1220,17 @@ LUNATIC_EXTERN void G_ShowView(vec3_t vec, fix16_t a, fix16_t horiz, int sect, i renderSetAspect(viewingRange, yxAspect); } + void Screen_Play(void) { bool running = true; I_ClearAllInput(); - do + // This needs to be disabled during the loop. + auto r2dover = rotatesprite_2doverride; + rotatesprite_2doverride = false; + do { gameHandleEvents(); @@ -1242,6 +1247,7 @@ void Screen_Play(void) videoNextPage(); I_ClearAllInput(); } while (running); + rotatesprite_2doverride = r2dover; } #if !defined LUNATIC diff --git a/source/rr/src/gameexec.cpp b/source/rr/src/gameexec.cpp index 500b78f5b..712dae268 100644 --- a/source/rr/src/gameexec.cpp +++ b/source/rr/src/gameexec.cpp @@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gamecvars.h" #include "debugbreak.h" +extern bool rotatesprite_2doverride; BEGIN_RR_NS @@ -1120,7 +1121,9 @@ void Screen_Play(void) I_ClearAllInput(); - do + auto r2dover = rotatesprite_2doverride; + rotatesprite_2doverride = false; + do { G_HandleAsync(); @@ -1136,6 +1139,7 @@ void Screen_Play(void) videoNextPage(); I_ClearAllInput(); } while (running); + rotatesprite_2doverride = r2dover; } GAMEEXEC_STATIC void VM_Execute(native_t loop) From b3b5ac440af83874e45c5906664bbf2b99d33e14 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Nov 2019 19:07:23 +0100 Subject: [PATCH 011/203] - fixed Blood fullscreen tinting. The lookup table for blend equations was missing one entry at the start. No idea why this became apparent only now. --- source/glbackend/glbackend.cpp | 2 +- source/glbackend/hw_draw2d.cpp | 2 +- .../demolition/shaders/glsl/polymost.fpp | 235 ------------------ 3 files changed, 2 insertions(+), 237 deletions(-) delete mode 100644 wadsrc/static/demolition/shaders/glsl/polymost.fpp diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index 7201c5406..4b222a273 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -427,7 +427,7 @@ void GLInstance::SetBlendFunc(int src, int dst) glBlendFunc(blendstyles[src], blendstyles[dst]); } -static int renderops[] = { GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT }; +static int renderops[] = { GL_FUNC_ADD, GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT }; void GLInstance::SetBlendOp(int op) { diff --git a/source/glbackend/hw_draw2d.cpp b/source/glbackend/hw_draw2d.cpp index 460466ffe..c9ec925d0 100644 --- a/source/glbackend/hw_draw2d.cpp +++ b/source/glbackend/hw_draw2d.cpp @@ -287,7 +287,7 @@ void fullscreen_tint_gl_blood(int tint_blood_r, int tint_blood_g, int tint_blood vt[2].Set(.0f, -2.5f); GLInterface.Draw(DT_TRIANGLES, data.first, 3); GLInterface.SetBlendOp(STYLEOP_Add); - GLInterface.SetColorub(0, 0, 0, 0); + GLInterface.SetColorub(255, 255, 255, 255); GLInterface.SetBlendFunc(STYLEALPHA_Src, STYLEALPHA_InvSrc); GLInterface.UseColorOnly(false); diff --git a/wadsrc/static/demolition/shaders/glsl/polymost.fpp b/wadsrc/static/demolition/shaders/glsl/polymost.fpp deleted file mode 100644 index e9dba291b..000000000 --- a/wadsrc/static/demolition/shaders/glsl/polymost.fpp +++ /dev/null @@ -1,235 +0,0 @@ -#version 330 - -const int RF_ColorOnly = 1; -const int RF_UsePalette = 2; -const int RF_DetailMapping = 4; -const int RF_GlowMapping = 8; -const int RF_Brightmapping = 16; -const int RF_NPOTEmulation = 32; -const int RF_ShadeInterpolate = 64; -const int RF_FogDisabled = 128; - -const int RF_HICTINT_Grayscale = 0x10000; -const int RF_HICTINT_Invert = 0x20000; -const int RF_HICTINT_Colorize = 0x40000; -const int RF_HICTINT_BLEND_Screen = 0x80000; -const int RF_HICTINT_BLEND_Overlay = 0x100000; -const int RF_HICTINT_BLEND_Hardlight = 0x200000; -const int RF_HICTINT_BLENDMASK = RF_HICTINT_BLEND_Screen | RF_HICTINT_BLEND_Overlay | RF_HICTINT_BLEND_Hardlight; - - -//s_texture points to an indexed color texture -uniform sampler2D s_texture; -//s_palswap is the palette swap texture where u is the color index and v is the shade -uniform sampler2D s_palswap; -//s_palette is the base palette texture where u is the color index -uniform sampler2D s_palette; - -uniform sampler2D s_detail; -uniform sampler2D s_glow; -uniform sampler2D s_brightmap; - -uniform float u_shade; -uniform float u_numShades; -uniform float u_shadeDiv; -uniform float u_visFactor; -uniform int u_flags; -uniform float u_alphaThreshold; - -uniform float u_npotEmulationFactor; -uniform float u_npotEmulationXOffset; -uniform float u_brightness; -uniform vec4 u_fogColor; -uniform vec3 u_tintcolor; -uniform vec3 u_tintmodulate; - -in vec4 v_color; -in float v_distance; -in vec4 v_texCoord; -in vec4 v_detailCoord; -in float v_fogCoord; - -const float c_basepalScale = 255.0/256.0; -const float c_basepalOffset = 0.5/256.0; - -const float c_zero = 0.0; -const float c_one = 1.0; -const float c_two = 2.0; -const vec4 c_vec4_one = vec4(c_one); -const float c_wrapThreshold = 0.9; - -layout(location=0) out vec4 fragColor; - -//=========================================================================== -// -// Color to grayscale -// -//=========================================================================== - -float grayscale(vec4 color) -{ - return dot(color.rgb, vec3(0.3, 0.56, 0.14)); -} - -//=========================================================================== -// -// Hightile tinting code. (hictinting[dapalnum]) This can be done inside the shader -// to avoid costly texture duplication (but needs a more modern GLSL than 1.10.) -// -//=========================================================================== - -vec4 convertColor(vec4 color, int effect, vec3 tint) -{ -#if 0 - - if (effect & RF_HICTINT_Grayscale) - { - float g = grayscale(color); - color = vec4(g, g, g, color.a); - } - - if (effect & RF_HICTINT_Invert) - { - color = vec4(1.0 - color.r, 1.0 - color.g, 1.0 - color.b); - } - - vec3 tcol = color.rgb * 255.0; // * 255.0 to make it easier to reuse the integer math. - tint *= 255.0; - - if (effect & RF_HICTINT_Colorize) - { - tcol.b = min(((tcol.b) * tint.r) / 64.0, 255.0); - tcol.g = min(((tcol.g) * tint.g) / 64.0, 255.0); - tcol.r = min(((tcol.r) * tint.b) / 64.0, 255.0); - } - - switch (effect & RF_HICTINT_BLENDMASK) - { - case RF_HICTINT_BLEND_Screen: - tcol.b = 255.0 - (((255.0 - tcol.b) * (255.0 - tint.r)) / 256.0); - tcol.g = 255.0 - (((255.0 - tcol.g) * (255.0 - tint.g)) / 256.0); - tcol.r = 255.0 - (((255.0 - tcol.r) * (255.0 - tint.b)) / 256.0); - break; - case RF_HICTINT_BLEND_Overlay: - tcol.b = tcol.b < 128.0? (tcol.b * tint.r) / 128.0 : 255.0 - (((255.0 - tcol.b) * (255.0 - tint.r)) / 128.0); - tcol.g = tcol.g < 128.0? (tcol.g * tint.g) / 128.0 : 255.0 - (((255.0 - tcol.g) * (255.0 - tint.g)) / 128.0); - tcol.r = tcol.r < 128.0? (tcol.r * tint.b) / 128.0 : 255.0 - (((255.0 - tcol.r) * (255.0 - tint.b)) / 128.0); - break; - case RF_HICTINT_BLEND_Hardlight: - tcol.b = tint.r < 128.0 ? (tcol.b * tint.r) / 128.0 : 255.0 - (((255.0 - tcol.b) * (255.0 - r)) / 128.0); - tcol.g = tint.g < 128.0 ? (tcol.g * tint.g) / 128.0 : 255.0 - (((255.0 - tcol.g) * (255.0 - g)) / 128.0); - tcol.r = tint.b < 128.0 ? (tcol.r * tint.b) / 128.0 : 255.0 - (((255.0 - tcol.r) * (255.0 - b)) / 128.0); - break; - } - color.rgb = tcol / 255.0; -#endif - return color; -} - -//=========================================================================== -// -// -// -//=========================================================================== - -void main() -{ - float fullbright = 0.0; - vec4 color; - if ((u_flags & RF_ColorOnly) == 0) - { - float coordX = v_texCoord.x; - float coordY = v_texCoord.y; - vec2 newCoord; - - // Coordinate adjustment for NPOT textures (something must have gone very wrong to make this necessary...) - if ((u_flags & RF_NPOTEmulation) != 0) - { - float period = floor(coordY / u_npotEmulationFactor); - coordX += u_npotEmulationXOffset * floor(mod(coordY, u_npotEmulationFactor)); - coordY = period + mod(coordY, u_npotEmulationFactor); - } - newCoord = vec2(coordX, coordY); - - // Paletted textures are stored in column major order rather than row major so coordinates need to be swapped here. - color = texture2D(s_texture, newCoord); - - // This was further down but it really should be done before applying any kind of depth fading, not afterward. - vec4 detailColor = vec4(1.0); - if ((u_flags & RF_DetailMapping) != 0) - { - detailColor = texture2D(s_detail, v_detailCoord.xy); - detailColor = mix(vec4(1.0), 2.0 * detailColor, detailColor.a); - // Application of this differs based on render mode because for paletted rendering with palettized shade tables it can only be done after processing the shade table. We only have a palette index before. - } - - float visibility = max(u_visFactor * v_distance - ((u_flags & RF_ShadeInterpolate) != 0.0? 0.5 : 0.0), 0.0); - float shade = clamp((u_shade + visibility), 0.0, u_numShades - 1.0); - - - if ((u_flags & RF_UsePalette) != 0) - { - int palindex = int(color.r * 255.0 + 0.1); // The 0.1 is for roundoff error compensation. - int shadeindex = int(floor(shade)); - float colorIndexF = texelFetch(s_palswap, ivec2(palindex, shadeindex), 0).r; - int colorIndex = int(colorIndexF * 255.0 + 0.1); // The 0.1 is for roundoff error compensation. - vec4 palettedColor = texelFetch(s_palette, ivec2(colorIndex, 0), 0); - - if ((u_flags & RF_ShadeInterpolate) != 0) - { - // Get the next shaded palette index for interpolation - colorIndexF = texelFetch(s_palswap, ivec2(palindex, shadeindex+1), 0).r; - colorIndex = int(colorIndexF * 255.0 + 0.1); // The 0.1 is for roundoff error compensation. - vec4 palettedColorNext = texelFetch(s_palette, ivec2(colorIndex, 0), 0); - float shadeFrac = mod(shade, 1.0); - palettedColor.rgb = mix(palettedColor.rgb, palettedColorNext.rgb, shadeFrac); - } - - fullbright = palettedColor.a; // This only gets set for paletted rendering. - palettedColor.a = c_one-floor(color.r); - color = palettedColor; - color.rgb *= detailColor.rgb; // with all this palettizing, this can only be applied afterward, even though it is wrong to do it this way. - if (fullbright == 0.0) color.rgb *= v_color.rgb; // Well, this is dead wrong but unavoidable. For colored fog it applies the light to the fog as well... - } - else - { - color.rgb *= detailColor.rgb; - - shade = clamp(shade * u_shadeDiv, 0.0, 1.0); // u_shadeDiv is really 1/shadeDiv. - vec3 lightcolor = v_color.rgb; - if ((u_flags & RF_FogDisabled) == 0) - { - lightcolor *= shade; - } - if ((u_flags & RF_Brightmapping) != 0) - { - vec4 brightcolor = texture2D(s_brightmap, v_texCoord.xy); - lightcolor = clamp(brightcolor.rgb + lightcolor, 0.0, 1.0); - } - color.rgb *= lightcolor; - - if ((u_flags & RF_FogDisabled) == 0 && u_fogColor.rgb != vec3(0)) - { - // Apply the shade as a linear depth fade ramp. - color.rgb += u_fogColor.rgb * (1.0 - shade); - } - } - if (color.a < u_alphaThreshold) discard; // it's only here that we have the alpha value available to be able to perform the alpha test. - - color.a *= v_color.a; - } - else - { - // untextured rendering - color = v_color; - } - - if ((u_flags & (RF_ColorOnly|RF_GlowMapping)) == RF_GlowMapping) - { - vec4 glowColor = texture2D(s_glow, v_texCoord.xy); - color.rgb = mix(color.rgb, glowColor.rgb, glowColor.a); - } - - color.rgb = pow(color.rgb, vec3(u_brightness)); - fragColor = color; -} From 57b542671c58a4cea41302899682c20cd0839142 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Nov 2019 20:40:53 +0100 Subject: [PATCH 012/203] - Ion Fury main menu fixes. --- source/common/menu/listmenu.cpp | 21 ++++++++++++--------- source/common/menu/menu.h | 18 ++++++++++++------ source/common/menu/menudef.cpp | 6 +++--- source/duke3d/src/d_menu.cpp | 10 +++++----- wadsrc/static/demolition/menudef.txt | 2 +- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 4fd448276..311d0e15d 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -65,6 +65,7 @@ void DListMenu::Init(DMenu *parent, FListMenuDescriptor *desc) mParentMenu = parent; mDesc = desc; if (mDesc->mScriptId) scriptID = mDesc->mScriptId; +#if 0 if (desc->mCenter) { int center = 160; @@ -90,6 +91,7 @@ void DListMenu::Init(DMenu *parent, FListMenuDescriptor *desc) } } } +#endif } //============================================================================= @@ -261,7 +263,7 @@ void DListMenu::Drawer () PreDraw(); for(unsigned i=0;imItems.Size(); i++) { - if (mDesc->mItems[i]->mEnabled) mDesc->mItems[i]->Drawer(origin, mDesc->mSelectedItem == (int)i); + if (mDesc->mItems[i]->mEnabled) mDesc->mItems[i]->Drawer(this, origin, mDesc->mSelectedItem == (int)i); } if (mDesc->mSelectedItem >= 0 && mDesc->mSelectedItem < (int)mDesc->mItems.Size()) mDesc->mItems[mDesc->mSelectedItem]->DrawSelector(mDesc->mSelectOfsX, mDesc->mSelectOfsY, mDesc->mSelector); @@ -288,7 +290,7 @@ void FListMenuItem::Ticker() { } -void FListMenuItem::Drawer(const vec2_t& origin, bool selected) +void FListMenuItem::Drawer(DListMenu* menu, const vec2_t& origin, bool selected) { } @@ -387,7 +389,7 @@ FListMenuItemStaticPatch::FListMenuItemStaticPatch(int x, int y, FTexture *patch mCentered = centered; } -void FListMenuItemStaticPatch::Drawer(const vec2_t& origin, bool selected) +void FListMenuItemStaticPatch::Drawer(DListMenu* menu, const vec2_t& origin, bool selected) { if (!mTexture) { @@ -424,7 +426,7 @@ FListMenuItemStaticText::FListMenuItemStaticText(int x, int y, const char *text, mCentered = centered; } -void FListMenuItemStaticText::Drawer(const vec2_t& origin, bool selected) +void FListMenuItemStaticText::Drawer(DListMenu* menu, const vec2_t& origin, bool selected) { const char *text = mText; if (text != NULL) @@ -528,7 +530,7 @@ FListMenuItemText::~FListMenuItemText() { } -void FListMenuItemText::Drawer(const vec2_t& origin, bool selected) +void FListMenuItemText::Drawer(DListMenu* menu, const vec2_t& origin, bool selected) { const char *text = mText; if (mText.Len()) @@ -570,13 +572,14 @@ FListMenuItemNativeText::~FListMenuItemNativeText() { } -void FListMenuItemNativeText::Drawer(const vec2_t& origin, bool selected) +void FListMenuItemNativeText::Drawer(DListMenu* menu, const vec2_t& origin, bool selected) { const char* text = mText; - if (mText.Len()) + if (mText.Len() && !mHidden) { if (*text == '$') text = GStrings(text + 1); - gi->DrawNativeMenuText(mFontnum, selected ? NIT_SelectedState : mEnabled? NIT_ActiveState : NIT_InactiveState, mXpos + origin.x, mYpos + origin.y, 1.f, text, TOR_Center); // needs to be able to handle other orientations, too. + int direction = menu->Descriptor()->mCenter == 0 ? TOR_Center : menu->Descriptor()->mCenter < 0 ? TOR_Right : TOR_Left; + gi->DrawNativeMenuText(mFontnum, selected ? NIT_SelectedState : mEnabled? NIT_ActiveState : NIT_InactiveState, (mXpos << 16) + origin.x, (mYpos << 16) + origin.y, 1.f, text, direction); } } @@ -599,7 +602,7 @@ FListMenuItemPatch::FListMenuItemPatch(int x, int y, int height, int hotkey, FTe mTexture = patch; } -void FListMenuItemPatch::Drawer(const vec2_t& origin, bool selected) +void FListMenuItemPatch::Drawer(DListMenu* menu, const vec2_t& origin, bool selected) { DrawTexture (&twod, mTexture, mXpos, mYpos, DTA_Clean, true, TAG_DONE); } diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 7d07c5db5..b3cf00b6b 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -297,6 +297,8 @@ public: // //============================================================================= +class DListMenu; + class FListMenuItem { protected: @@ -319,7 +321,7 @@ public: virtual bool CheckCoordinate(int x, int y); virtual void Ticker(); - virtual void Drawer(const vec2_t &origin, bool selected); + virtual void Drawer(DListMenu *menu, const vec2_t& origin, bool selected); virtual bool Selectable(); virtual bool Activate(); virtual FName GetAction(int *pparam); @@ -348,7 +350,7 @@ protected: public: FListMenuItemStaticPatch(int x, int y, FTexture *patch, bool centered); - void Drawer(const vec2_t& origin, bool selected); + void Drawer(DListMenu* menu, const vec2_t& origin, bool selected); }; class FListMenuItemStaticText : public FListMenuItem @@ -362,7 +364,7 @@ protected: public: FListMenuItemStaticText(int x, int y, const char *text, FFont *font, EColorRange color, bool centered); ~FListMenuItemStaticText(); - void Drawer(const vec2_t& origin, bool selected) override; + void Drawer(DListMenu* menu, const vec2_t& origin, bool selected) override; }; //============================================================================= @@ -397,7 +399,7 @@ class FListMenuItemText : public FListMenuItemSelectable public: FListMenuItemText(int x, int y, int height, int hotkey, const FString &text, FFont *font, EColorRange color, EColorRange color2, FName child, int param = 0); ~FListMenuItemText(); - void Drawer(const vec2_t& origin, bool selected) override; + void Drawer(DListMenu* menu, const vec2_t& origin, bool selected) override; int GetWidth() override; }; @@ -411,7 +413,7 @@ class FListMenuItemNativeText : public FListMenuItemSelectable public: FListMenuItemNativeText(int x, int y, int height, int hotkey, const FString& text, int fontnum, int palnum, float fontscale, FName child, int param = 0); ~FListMenuItemNativeText(); - void Drawer(const vec2_t& origin, bool selected) override; + void Drawer(DListMenu* menu, const vec2_t& origin, bool selected) override; int GetWidth() override; void DrawSelector(int xofs, int yofs, FTexture* tex) override { } // The text drawer handles this itself. }; @@ -422,7 +424,7 @@ class FListMenuItemPatch : public FListMenuItemSelectable FTexture* mTexture; public: FListMenuItemPatch(int x, int y, int height, int hotkey, FTexture* patch, FName child, int param = 0); - void Drawer(const vec2_t& origin, bool selected) override; + void Drawer(DListMenu* menu, const vec2_t& origin, bool selected) override; int GetWidth() override; }; @@ -460,6 +462,10 @@ public: { mFocusControl = NULL; } + const FListMenuDescriptor* Descriptor() const + { + return mDesc; + } }; diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 3eeae1acc..97b0dba14 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -156,7 +156,7 @@ static bool CheckSkipGameBlock(FScanner &sc) } while (sc.CheckString(",")); sc.MustGetStringName(")"); - if (!(filter & 1)) // todo: apply correct filter. + if (!(filter & g_gameType)) { SkipSubBlock(sc); return !sc.CheckString("else"); @@ -279,7 +279,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) } else if (sc.Compare("Centermenu")) { - desc->mCenter = true; + desc->mCenter = 0; } else if (sc.Compare("MouseWindow")) { @@ -518,7 +518,7 @@ static void ParseListMenu(FScanner &sc) desc->mRedirect = NULL; desc->mWLeft = 0; desc->mWRight = 0; - desc->mCenter = false; + desc->mCenter = 0; ParseListMenuBody(sc, desc); bool scratch = ReplaceMenu(sc, desc); diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 65eaa844f..f5e0d332b 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -473,7 +473,7 @@ void GameInterface::DrawNativeMenuText(int fontnum, int state, int xpos, int ypo int ydim_upper = 0; int ydim_lower = ydim - 1; int32_t const indent = 0; // not set for any relevant menu - int32_t x = xpos << 16; + int32_t x = xpos; uint8_t status = 0; if (state == NIT_SelectedState) @@ -488,7 +488,7 @@ void GameInterface::DrawNativeMenuText(int fontnum, int state, int xpos, int ypo int32_t const height = font.get_yline(); status |= MT_YCenter; - int32_t const y_internal = (ypos + (height >> 17)) << 16;// -menu->scrollPos; + int32_t const y_internal = ypos + ((height >> 17) << 16);// -menu->scrollPos; vec2_t textsize; if (dodraw) @@ -569,7 +569,7 @@ protected: // totalHeight calculating pass int totalHeight; - for (int e = 0; e < numvalidentries; ++e) + for (unsigned e = 0; e < mDesc->mItems.Size(); ++e) { auto entry = mDesc->mItems[e]; if (!entry->mHidden) @@ -610,9 +610,9 @@ class MainMenu : public DukeListMenu DukeListMenu::PreDraw(); if ((G_GetLogoFlags() & LOGO_NOGAMETITLE) == 0) { - rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + ((28)<<16), 65536L,0,INGAMEDUKETHREEDEE,0,0,10); + rotatesprite_fs((origin.x << 16) + (MENU_MARGIN_CENTER<<16), (origin.y << 16) + ((28)<<16), 65536L,0,INGAMEDUKETHREEDEE,0,0,10); if (PLUTOPAK) // JBF 20030804 - rotatesprite_fs(origin.x + ((MENU_MARGIN_CENTER+100)<<16), origin.y + (36<<16), 65536L,0,PLUTOPAKSPRITE+2,(sintable[((int32_t) totalclock<<4)&2047]>>11),0,2+8); + rotatesprite_fs((origin.y << 16) + ((MENU_MARGIN_CENTER+100)<<16), (origin.y << 16) + (36<<16), 65536L,0,PLUTOPAKSPRITE+2,(sintable[((int32_t) totalclock<<4)&2047]>>11),0,2+8); } else if (mDesc->mCaption.IsNotEmpty()) { diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 0b5f699ea..4d566fa67 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -21,7 +21,7 @@ LISTMENU "MainMenu" linespacing 15 class "Duke.MainMenu" NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" - //NativeTextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) + //NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) ifgame(fury) { NativeTextItem "$MNU_CONTINUE", "l", "LoadGameMenu" From 42b3d12630fa414712f7366254ea13f5e67b8835 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Nov 2019 22:31:27 +0100 Subject: [PATCH 013/203] - Ion Fury's main menu now looks correct. --- source/build/include/baselayer.h | 10 +--------- source/common/menu/listmenu.cpp | 8 ++++---- source/common/menu/menu.h | 13 +++++++++++-- source/common/menu/menudef.cpp | 13 ++++++------- source/duke3d/src/d_menu.cpp | 10 ++++------ source/duke3d/src/duke3d.h | 2 +- source/duke3d/src/menus.cpp | 3 --- wadsrc/static/demolition/menudef.txt | 14 ++++++++------ 8 files changed, 35 insertions(+), 38 deletions(-) diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 7d4ed9166..36c406492 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -168,14 +168,6 @@ struct GameStats int timesecnd; }; -enum ETextOrientation -{ - TOR_Default, - TOR_Left, - TOR_Center, - TOR_Right -}; - struct GameInterface { virtual ~GameInterface() {} @@ -187,7 +179,7 @@ struct GameInterface virtual bool mouseInactiveConditional(bool condition) { return condition; } virtual FString statFPS() { return "FPS display not available"; } virtual GameStats getStats() { return {}; } - virtual void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int orientation = TOR_Default) {} + virtual void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int flags) {} virtual void MainMenuOpened() {} virtual void MenuOpened() {} virtual void MenuSelectSound() {} diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 311d0e15d..df1cfa725 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -64,7 +64,7 @@ void DListMenu::Init(DMenu *parent, FListMenuDescriptor *desc) { mParentMenu = parent; mDesc = desc; - if (mDesc->mScriptId) scriptID = mDesc->mScriptId; + if (mDesc->mScriptId >= 0) scriptID = mDesc->mScriptId; #if 0 if (desc->mCenter) { @@ -473,7 +473,7 @@ bool FListMenuItemSelectable::CheckCoordinate(int x, int y) bool FListMenuItemSelectable::Selectable() { - return mEnabled; + return mEnabled && !mHidden; } bool FListMenuItemSelectable::Activate() @@ -578,8 +578,8 @@ void FListMenuItemNativeText::Drawer(DListMenu* menu, const vec2_t& origin, bool if (mText.Len() && !mHidden) { if (*text == '$') text = GStrings(text + 1); - int direction = menu->Descriptor()->mCenter == 0 ? TOR_Center : menu->Descriptor()->mCenter < 0 ? TOR_Right : TOR_Left; - gi->DrawNativeMenuText(mFontnum, selected ? NIT_SelectedState : mEnabled? NIT_ActiveState : NIT_InactiveState, (mXpos << 16) + origin.x, (mYpos << 16) + origin.y, 1.f, text, direction); + auto state = selected ? NIT_SelectedState : mEnabled ? NIT_ActiveState : NIT_InactiveState; + gi->DrawNativeMenuText(mFontnum, state, (mXpos << 16) + origin.x, (mYpos << 16) + origin.y, 1.f, text, menu->Descriptor()->mFlags); } } diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index b3cf00b6b..5214e2900 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -121,6 +121,12 @@ struct FMenuDescriptor class FListMenuItem; class FOptionMenuItem; +enum ListMenuFlags +{ + LMF_Centered = 1, + LMF_DontSpace = 2 +}; + struct FListMenuDescriptor : public FMenuDescriptor { TDeletingArray mItems; @@ -142,7 +148,8 @@ struct FListMenuDescriptor : public FMenuDescriptor EColorRange mFontColor; EColorRange mFontColor2; FMenuDescriptor *mRedirect; // used to redirect overlong skill and episode menus to option menu based alternatives - int mCenter; + int mFlags; + int mSpacing; FListMenuDescriptor() { @@ -163,11 +170,13 @@ struct FListMenuDescriptor : public FMenuDescriptor mFont = NULL; mFontColor = CR_UNTRANSLATED; mFontColor2 = CR_UNTRANSLATED; - mScriptId = 0; + mScriptId = -1; mSecondaryId = 0; mNativeFontNum = NIT_BigFont; mNativePalNum = NIT_ActiveColor; mNativeFontScale = 1.f; + mFlags = 0; + mSpacing = 0; } }; diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 97b0dba14..33b188b07 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -270,16 +270,16 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) { sc.MustGetNumber(); desc->mYbotton = sc.Number; - if (sc.CheckString(",")) - { - sc.MustGetNumber(); - desc->mCenter = sc.Number; - } } } else if (sc.Compare("Centermenu")) { - desc->mCenter = 0; + desc->mFlags |= LMF_Centered; + } + else if (sc.Compare("Fixedspacing")) + { + sc.MustGetNumber(); + desc->mSpacing = sc.Number; } else if (sc.Compare("MouseWindow")) { @@ -518,7 +518,6 @@ static void ParseListMenu(FScanner &sc) desc->mRedirect = NULL; desc->mWLeft = 0; desc->mWRight = 0; - desc->mCenter = 0; ParseListMenuBody(sc, desc); bool scratch = ReplaceMenu(sc, desc); diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index f5e0d332b..fb94c809b 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -468,7 +468,7 @@ static int Menu_GetFontHeight(int fontnum) return font.get_yline(); } -void GameInterface::DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int orientation) +void GameInterface::DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int flags) { int ydim_upper = 0; int ydim_lower = ydim - 1; @@ -480,7 +480,7 @@ void GameInterface::DrawNativeMenuText(int fontnum, int state, int xpos, int ypo status |= MT_Selected; if (state == NIT_InactiveState) status |= MT_Disabled; - if (orientation == TOR_Center) + if (flags & LMF_Centered) status |= MT_XCenter; bool const dodraw = true; @@ -494,9 +494,6 @@ void GameInterface::DrawNativeMenuText(int fontnum, int state, int xpos, int ypo if (dodraw) textsize = Menu_Text(x, y_internal, &font, text, status, ydim_upper, ydim_lower); - if (orientation == TOR_Right) - status |= MT_XRight; - if (dodraw && (status & MT_Selected) && state != 1) { if (status & MT_XCenter) @@ -564,8 +561,9 @@ protected: } totalheight += height; } + if (mDesc->mSpacing <= 0) calculatedentryspacing = std::max(0, (y_lower - y_upper - totalheight) / (numvalidentries > 1 ? numvalidentries - 1 : 1)); + if (calculatedentryspacing <= 0) calculatedentryspacing = mDesc->mSpacing; - calculatedentryspacing = std::max(0, (y_lower - y_upper - totalheight) / (numvalidentries > 1 ? numvalidentries - 1 : 1)); // totalHeight calculating pass int totalHeight; diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index 36ebf07dd..4d6405e7f 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -156,7 +156,7 @@ struct GameInterface : ::GameInterface GameStats getStats() override; // Access to the front end specific menu code. Use is restricted to the main menu, the ingame menu and the skill/episode selection. // Everything else is either custom screens or will use the generic option menu style. - void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int orientation = TOR_Default) override; + void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int orientation) override; void MenuOpened() override; void MenuSelectSound() override; void MenuChooseSound() override; diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index d9d2b1c4b..970eed8c7 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -1760,9 +1760,6 @@ void Menu_Init(void) // hack; should swap out pointers MF_Minifont = MF_Bluefont; - MMF_Top_Main.pos.x = 40<<16; - MMF_Top_Main.pos.y = 130<<16; - MMF_Top_Main.bottomcutoff = 190<<16; M_OPTIONS.format = &MMF_Top_Main; MEF_MainMenu.width = MEF_OptionsMenu.width = -(160<<16); diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 4d566fa67..529bd04a9 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -6,16 +6,17 @@ LISTMENU "MainMenu" { - ScriptId 1 + ScriptId 0 ifgame(Duke, Nam, WW2GI, Fury) { ifgame(fury) { - position 40, 130, 60, -160 + position 40, 130, 60 + fixedspacing 2 } else { - position 160, 55, 115, 0 + position 160, 55, 115 centermenu } linespacing 15 @@ -39,7 +40,7 @@ LISTMENU "MainMenu" { linespacing 15 NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" - //NativeTextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) + //NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" NativeTextItem "$MNU_HELP", "h", "HelpMenu" @@ -76,11 +77,12 @@ LISTMENU "IngameMenu" { ifgame(fury) { - position 40, 130, 60, -160 + position 40, 130, 60 + fixedspacing 2 } else { - position 160, 55, 115, 0 + position 160, 55, 115 centermenu } linespacing 15 From d7bc013eeea810652a2197499f850371106dd6d8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Nov 2019 23:12:58 +0100 Subject: [PATCH 014/203] - empty templates for the programmatically generated menus --- wadsrc/static/demolition/menudef.txt | 77 ++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 529bd04a9..36b32ff4f 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -73,6 +73,7 @@ LISTMENU "MainMenu" LISTMENU "IngameMenu" { + ScriptId 50 ifgame(Duke, Nam, WW2GI, Fury) { ifgame(fury) @@ -87,7 +88,7 @@ LISTMENU "IngameMenu" } linespacing 15 class "Duke.MainMenu" - NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_NEWGAME", "n", "CustomGameMenu" NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" @@ -98,7 +99,7 @@ LISTMENU "IngameMenu" ifgame(Redneck, RedneckRides) { linespacing 15 - NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" @@ -109,7 +110,7 @@ LISTMENU "IngameMenu" ifgame(Blood) { linespacing 15 - NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" NativeTextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" @@ -120,7 +121,7 @@ LISTMENU "IngameMenu" ifgame(ShadowWarrior) { linespacing 15 - NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" @@ -129,3 +130,71 @@ LISTMENU "IngameMenu" } } +LISTMENU "EpisodeMenu" +{ + ScriptId 100 + // Episode names filled in programmatically + NativeTextItem "1", "", "SkillMenu", 1 + NativeTextItem "2", "", "SkillMenu", 2 + NativeTextItem "3", "", "SkillMenu", 3 + NativeTextItem "4", "", "SkillMenu", 4 + NativeTextItem "5", "", "SkillMenu", 5 + NativeTextItem "6", "", "SkillMenu", 6 + NativeTextItem "7", "", "SkillMenu", 7 + //Spacer + NativeTextItem "$MNU_USERMAP", "u", "UserMap" +} + +LISTMENU "SkillMenu" +{ + NativeTextItem "1", "", "StartGame", 1 +} + +LISTMENU "CustomGameMenu" +{ + ScriptId 102 + // Filled in programmatically + //NativeTextItem "1", "", "CustomSubMenu1" +} + +LISTMENU "CustomSubMenu1" +{ + ScriptId 103 + //NativeTextItem "1", "", "SkillMenu" +} + +LISTMENU "CustomSubMenu2" +{ + ScriptId 103 + //NativeTextItem "1", "", "SkillMenu" +} + +LISTMENU "CustomSubMenu3" +{ + ScriptId 103 + //NativeTextItem "1", "", "SkillMenu" +} + +LISTMENU "CustomSubMenu4" +{ + ScriptId 103 + //NativeTextItem "1", "", "SkillMenu" +} + +LISTMENU "CustomSubMenu5" +{ + ScriptId 103 + //NativeTextItem "1", "", "SkillMenu" +} + +LISTMENU "CustomSubMenu6" +{ + ScriptId 103 + //NativeTextItem "1", "", "SkillMenu" +} + +LISTMENU "CustomSubMenu7" +{ + ScriptId 103 + //NativeTextItem "1", "", "SkillMenu" +} From 1f1e39fac06acde06e1892dee847b5c1e60fa16f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 25 Nov 2019 00:02:00 +0100 Subject: [PATCH 015/203] - consolidation of texts for episode and skill menus So far without localization capability - the engine cannot handle it yet. --- source/blood/src/levels.cpp | 5 ++- source/common/gamecontrol.cpp | 47 ++++++++++++++++++++++-- source/common/menu/menu.h | 13 ++++++- source/common/menu/menudef.cpp | 5 +++ source/duke3d/src/d_menu.cpp | 34 ++++++------------ source/duke3d/src/gamedef.cpp | 54 ++++++++-------------------- source/duke3d/src/gameexec.cpp | 4 ++- source/duke3d/src/global.cpp | 7 +--- source/duke3d/src/global.h | 5 +-- source/duke3d/src/menus.cpp | 44 +---------------------- source/duke3d/src/premap.cpp | 2 +- source/duke3d/src/screens.cpp | 3 +- source/glbackend/gl_texture.cpp | 6 +--- source/rr/src/gamedef.cpp | 44 +++++------------------ source/rr/src/global.cpp | 4 --- source/rr/src/global.h | 4 --- source/rr/src/menus.cpp | 25 ++++++------- source/rr/src/premap.cpp | 3 +- source/rr/src/screens.cpp | 3 +- wadsrc/static/demolition/menudef.txt | 24 +++++++++---- 20 files changed, 144 insertions(+), 192 deletions(-) diff --git a/source/blood/src/levels.cpp b/source/blood/src/levels.cpp index c1ad24fae..e477c7265 100644 --- a/source/blood/src/levels.cpp +++ b/source/blood/src/levels.cpp @@ -43,6 +43,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "sfx.h" #include "view.h" #include "eventq.h" +#include "menu/menu.h" BEGIN_BLD_NS @@ -236,7 +237,9 @@ void levelLoadDefaults(void) if (!BloodINI->SectionExists(buffer)) break; EPISODEINFO *pEpisodeInfo = &gEpisodeInfo[i]; - strncpy(pEpisodeInfo->at0, BloodINI->GetKeyString(buffer, "Title", buffer), 31); + auto ep_str = BloodINI->GetKeyString(buffer, "Title", buffer); + strncpy(pEpisodeInfo->at0, ep_str, 31); + gVolumeNames[i] = ep_str; // For the menu. strncpy(pEpisodeInfo->at8f08, BloodINI->GetKeyString(buffer, "CutSceneA", ""), BMAX_PATH); pEpisodeInfo->at9028 = BloodINI->GetKeyInt(buffer, "CutWavA", -1); if (pEpisodeInfo->at9028 == 0) diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index d6f32708e..12981b4c7 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -259,6 +259,49 @@ int GameMain() return r; } +//========================================================================== +// +// Try to keep all initializations of global string variables in this one place +// +//========================================================================== + +#define LOCALIZED_STRING(s) s // change to "${" s "}" later, once all text output functions can replace text macros + +void SetDefaultStrings() +{ + // Hard coded texts for the episode and skill selection menus. + if (g_gameType & GAMEFLAG_DUKE) + { + gVolumeNames[0] = LOCALIZED_STRING("L.A. Meltdown"); + gVolumeNames[1] = LOCALIZED_STRING("Lunar Apocalypse"); + gVolumeNames[2] = LOCALIZED_STRING("Shrapnel City"); + gSkillNames[0] = LOCALIZED_STRING("Piece Of Cake"); + gSkillNames[1] = LOCALIZED_STRING("Let's Rock"); + gSkillNames[2] = LOCALIZED_STRING("Come Get Some"); + gSkillNames[3] = LOCALIZED_STRING("Damn I'm Good"); + } + else if (g_gameType & GAMEFLAG_BLOOD) + { + gSkillNames[0] = LOCALIZED_STRING("STILL KICKING"); + gSkillNames[1] = LOCALIZED_STRING("PINK ON THE INSIDE"); + gSkillNames[2] = LOCALIZED_STRING("LIGHTLY BROILED"); + gSkillNames[3] = LOCALIZED_STRING("WELL DONE"); + gSkillNames[4] = LOCALIZED_STRING("EXTRA CRISPY"); + } + else if (g_gameType & GAMEFLAG_SW) + { + gVolumeNames[0] = LOCALIZED_STRING("Enter the Wang"); + gVolumeNames[1] = LOCALIZED_STRING("Code of Honor"); + + gVolumeSubtitles[0] = LOCALIZED_STRING("Four levels (Shareware Version)"); + gVolumeSubtitles[1] = LOCALIZED_STRING("Eighteen levels (Full Version Only)"); + + gSkillNames[0] = LOCALIZED_STRING("Tiny grasshopper"); + gSkillNames[1] = LOCALIZED_STRING("I Have No Fear"); + gSkillNames[2] = LOCALIZED_STRING("Who Wants Wang"); + gSkillNames[3] = LOCALIZED_STRING("No Pain, No Gain"); + } +} //========================================================================== // // @@ -385,9 +428,7 @@ int CONFIG_Init() Mus_Init(); InitStatistics(); M_Init(); - - - + SetDefaultStrings(); return gi->app_main(); } diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 5214e2900..fe5c4b3e3 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -12,6 +12,17 @@ EXTERN_CVAR(Float, snd_menuvolume) EXTERN_CVAR(Int, m_use_mouse); +enum +{ + MAXSKILLS = 7, + MAXVOLUMES = 7, +}; + +// These get filled in by the map definition parsers of the front ends. +extern FString gSkillNames[MAXSKILLS]; +extern FString gVolumeNames[MAXVOLUMES]; +extern FString gVolumeSubtitles[MAXVOLUMES]; +extern int32_t gVolumeFlags[MAXVOLUMES]; const int MENU_TICRATE = 30; extern bool help_disabled, credits_disabled; @@ -654,4 +665,4 @@ template struct TMenuClassDescriptor : public MenuClassDescriptor } }; -#endif \ No newline at end of file +#endif diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 33b188b07..6f479e368 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -49,6 +49,11 @@ void ClearSaveGames(); +FString gSkillNames[MAXSKILLS]; +FString gVolumeNames[MAXVOLUMES]; +FString gVolumeSubtitles[MAXVOLUMES]; +int32_t gVolumeFlags[MAXVOLUMES]; + MenuDescriptorList MenuDescriptors; static FListMenuDescriptor DefaultListMenuSettings; // contains common settings for all list menus static FOptionMenuDescriptor DefaultOptionMenuSettings; // contains common settings for all Option menus diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index fb94c809b..d4c6c71eb 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -128,35 +128,23 @@ void Menu_Init(void) // prepare episodes k = 0; - for (i = 0; i < g_volumeCnt; ++i) + + if (gVolumeNames[i].IsNotEmpty()) { - if (g_volumeNames[i][0]) + if (!(gVolumeFlags[i] & EF_HIDEFROMSP)) { - if (!(g_volumeFlags[i] & EF_HIDEFROMSP)) - { - MEL_EPISODE[i] = &ME_EPISODE[i]; - ME_EPISODE[i] = ME_EPISODE_TEMPLATE; - ME_EPISODE[i].name = g_volumeNames[i]; - } - - // if (!(EpisodeFlags[i] & EF_HIDEFROMMP)) - { - MEOSN_NetEpisodes[k] = g_volumeNames[i]; - MEOSV_NetEpisodes[k] = i; - - k++; - } + MEL_EPISODE[i] = &ME_EPISODE[i]; + ME_EPISODE[i] = ME_EPISODE_TEMPLATE; + ME_EPISODE[i].name = gVolumeNames[i]; } - // prepare levels - MEOS_NETOPTIONS_LEVEL[i] = MEOS_NETOPTIONS_LEVEL_TEMPLATE; - for (j = 0; j < MAXLEVELS; ++j) + // if (!(EpisodeFlags[i] & EF_HIDEFROMMP)) { - MEOSN_NetLevels[i][j] = g_mapInfo[MAXLEVELS * i + j].name; - if (g_mapInfo[i * MAXLEVELS + j].filename != NULL) - MEOS_NETOPTIONS_LEVEL[i].numOptions = j + 1; + MEOSN_NetEpisodes[k] = gVolumeNames[i]; + MEOSV_NetEpisodes[k] = i; + + k++; } - MEOS_NETOPTIONS_LEVEL[i].optionNames = MEOSN_NetLevels[i]; } M_EPISODE.numEntries = g_volumeCnt + 2; diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index c4093393d..8af2b6b0c 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -36,6 +36,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "savegame.h" #include "printf.h" #include "m_argv.h" +#include "menu/menu.h" BEGIN_DUKE_NS @@ -2033,7 +2034,7 @@ void C_DefineVolumeFlags(int32_t vol, int32_t flags) { Bassert((unsigned)vol < MAXVOLUMES); - g_volumeFlags[vol] = flags; + gVolumeFlags[vol] = flags; } void C_UndefineVolume(int32_t vol) @@ -2043,12 +2044,12 @@ void C_UndefineVolume(int32_t vol) for (bssize_t i = 0; i < MAXLEVELS; i++) C_UndefineLevel(vol, i); - g_volumeNames[vol][0] = '\0'; + gVolumeNames[vol] = ""; g_volumeCnt = 0; for (bssize_t i = MAXVOLUMES-1; i >= 0; i--) { - if (g_volumeNames[i][0]) + if (gVolumeNames[i].IsNotEmpty()) { g_volumeCnt = i+1; break; @@ -2060,12 +2061,12 @@ void C_UndefineSkill(int32_t skill) { Bassert((unsigned)skill < MAXSKILLS); - g_skillNames[skill][0] = '\0'; + gSkillNames[skill] = ""; g_skillCnt = 0; for (bssize_t i = MAXSKILLS-1; i >= 0; i--) { - if (g_skillNames[i][0]) + if (gSkillNames[i][0]) { g_skillCnt = i+1; break; @@ -5015,23 +5016,11 @@ repeatcase: continue; } - i = 0; - - while (*textptr != 0x0a && *textptr != 0x0d && *textptr != 0) - { - g_volumeNames[j][i] = *textptr; - textptr++,i++; - if (EDUKE32_PREDICT_FALSE(i >= (signed)sizeof(g_volumeNames[j])-1)) - { - initprintf("%s:%d: warning: truncating volume name to %d characters.\n", - g_scriptFileName,g_lineNumber,(int32_t)sizeof(g_volumeNames[j])-1); - g_warningCnt++; - scriptSkipLine(); - break; - } - } + i = strcspn(textptr, "\r\n"); + gVolumeNames[j] = FString(textptr, i); + textptr += i; + g_volumeCnt = j+1; - g_volumeNames[j][i] = '\0'; continue; case CON_DEFINEVOLUMEFLAGS: @@ -5128,27 +5117,14 @@ repeatcase: continue; } - i = 0; - - while (*textptr != 0x0a && *textptr != 0x0d && *textptr != 0) - { - g_skillNames[j][i] = *textptr; - textptr++,i++; - if (EDUKE32_PREDICT_FALSE(i >= (signed)sizeof(g_skillNames[j])-1)) - { - initprintf("%s:%d: warning: truncating skill name to %d characters.\n", - g_scriptFileName,g_lineNumber,(int32_t)sizeof(g_skillNames[j])-1); - g_warningCnt++; - scriptSkipLine(); - break; - } - } - - g_skillNames[j][i] = '\0'; + i = strcspn(textptr, "\r\n"); + gSkillNames[j] = FString(textptr, i); + textptr+=i; for (i=0; i 0) mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8)<<16), g_skillNames[ud.m_player_skill], MF_Minifont.pal_deselected_right); @@ -2302,15 +2279,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) break; } -#ifdef EDUKE32_ANDROID_MENU - case MENU_SKILL: - { - static const char *s[] = { "EASY - Few enemies, and lots of stuff.", "MEDIUM - Normal difficulty.", "HARD - For experienced players.", "EXPERTS - Lots of enemies, plus they respawn!" }; - if (M_SKILL.currentEntry < ARRAY_SSIZE(s)) - mgametextcenter(origin.x, origin.y + (168<<16), s[M_SKILL.currentEntry]); - } - break; -#endif case MENU_SAVECLEANVERIFY: videoFadeToBlack(1); @@ -2334,16 +2302,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) Bsprintf(tempbuf, "Resume game from sequence point:\n\"%s\"", msv.brief.name); Menu_DrawVerifyPrompt(origin.x, origin.y, tempbuf, 2); } - else if (msv.isOldVer) - { -#if 1 - mgametextcenter(origin.x, origin.y + (90<<16), "You're not supposed to be here."); -#else - Bsprintf(tempbuf, "Start new game:\n%s / %s" - , g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name, g_skillNames[ud.player_skill-1]); - Menu_DrawVerifyPrompt(origin.x, origin.y, tempbuf, 2); -#endif - } else { Bsprintf(tempbuf, "Load game:\n\"%s\"", msv.brief.name); diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index ac66b21c4..a8dc821cf 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -1339,7 +1339,7 @@ void G_NewGame(int volumeNum, int levelNum, int skillNum) ud.secretlevel = 0; ud.skill_voice = -1; ud.volume_number = volumeNum; - STAT_StartNewGame(g_volumeNames[volumeNum], skillNum); + STAT_StartNewGame(gVolumeNames[volumeNum], skillNum); g_lastAutoSaveArbitraryID = -1; g_lastautosave.reset(); diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index d0f4d5eee..8ef72c260 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "sbar.h" #include "screens.h" #include "gamecvars.h" +#include "menu/menu.h" BEGIN_DUKE_NS @@ -961,7 +962,7 @@ void G_DisplayRest(int32_t smoothratio) if (G_HaveUserMap()) levelname = boardfilename; else if (!(G_GetLogoFlags() & LOGO_HIDEEPISODE)) - minitext(5, a+6, g_volumeNames[ud.volume_number], 0, 2+8+16+256); + minitext(5, a+6, gVolumeNames[ud.volume_number], 0, 2+8+16+256); minitext(5, a+6+6, levelname, 0, 2+8+16+256); } } diff --git a/source/glbackend/gl_texture.cpp b/source/glbackend/gl_texture.cpp index 37cc41136..f6d153bd1 100644 --- a/source/glbackend/gl_texture.cpp +++ b/source/glbackend/gl_texture.cpp @@ -69,7 +69,6 @@ void FlipNonSquareBlock(T* dst, const T* src, int x, int y, int srcpitch) FHardwareTexture* GLInstance::CreateIndexedTexture(FTexture* tex) { auto siz = tex->GetSize(); - bool npoty = false; const uint8_t* p = tex->Get8BitPixels(); TArray store(siz.x * siz.y, true); @@ -96,9 +95,6 @@ FHardwareTexture* GLInstance::CreateIndexedTexture(FTexture* tex) FHardwareTexture* GLInstance::CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency, bool rgb8bit) { - auto siz = tex->GetSize(); - bool npoty = false; - auto palette = palid < 0? nullptr : palmanager.GetPaletteData(palid); if (palette == nullptr) return nullptr; auto texbuffer = tex->CreateTexBuffer(palette, CTF_ProcessData); @@ -266,7 +262,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int auto brep = tex->FindReplacement(BRIGHTPAL); if (brep) { - auto htex = LoadTexture(brep->faces[0], TT_HICREPLACE, 0); + LoadTexture(brep->faces[0], TT_HICREPLACE, 0); UseBrightmaps(true); BindTexture(5, mtex, sampler); } diff --git a/source/rr/src/gamedef.cpp b/source/rr/src/gamedef.cpp index 992076693..da4d67fc2 100644 --- a/source/rr/src/gamedef.cpp +++ b/source/rr/src/gamedef.cpp @@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "osd.h" #include "m_crc32.h" #include "printf.h" +#include "menu/menu.h" BEGIN_RR_NS @@ -894,7 +895,7 @@ void C_DefineVolumeFlags(int32_t vol, int32_t flags) { Bassert((unsigned)vol < MAXVOLUMES); - g_volumeFlags[vol] = flags; + gVolumeFlags[vol] = flags; } int32_t C_AllocQuote(int32_t qnum) @@ -1884,23 +1885,10 @@ static int32_t C_ParseCommand(int32_t loop) continue; } - i = 0; - - while (*textptr != 0x0a && *textptr != 0x0d && *textptr != 0) - { - g_volumeNames[j][i] = *textptr; - textptr++,i++; - if (EDUKE32_PREDICT_FALSE(i >= (signed)sizeof(g_volumeNames[j])-1)) - { - initprintf("%s:%d: warning: truncating volume name to %d characters.\n", - g_scriptFileName,g_lineNumber,(int32_t)sizeof(g_volumeNames[j])-1); - g_warningCnt++; - C_NextLine(); - break; - } - } + i = strcspn(textptr, "\r\n"); + gVolumeNames[j] = FString(textptr, i); + textptr+=i; g_volumeCnt = j+1; - g_volumeNames[j][i] = '\0'; continue; case CON_DEFINESKILLNAME: @@ -1921,26 +1909,12 @@ static int32_t C_ParseCommand(int32_t loop) continue; } - i = 0; - - while (*textptr != 0x0a && *textptr != 0x0d && *textptr != 0) - { - g_skillNames[j][i] = *textptr; - textptr++,i++; - if (EDUKE32_PREDICT_FALSE(i >= (signed)sizeof(g_skillNames[j])-1)) - { - initprintf("%s:%d: warning: truncating skill name to %d characters.\n", - g_scriptFileName,g_lineNumber,(int32_t)sizeof(g_skillNames[j])-1); - g_warningCnt++; - C_NextLine(); - break; - } - } - - g_skillNames[j][i] = '\0'; + i = strcspn(textptr, "\r\n"); + gSkillNames[j] = FString(textptr, i); + textptr+=i; for (i=0; i 0) - mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8)<<16), g_skillNames[ud.m_player_skill], MF_Minifont.pal_deselected_right); + mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8)<<16), gSkillNames[ud.m_player_skill], MF_Minifont.pal_deselected_right); else mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8)<<16), "None", MF_Minifont.pal_deselected_right); if (m_coop == 0) { @@ -2199,7 +2200,7 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) { const char *name = g_mapInfo[(savehead.volnum*MAXLEVELS) + savehead.levnum].name; - Bsprintf(tempbuf, "%s / %s", name ? name : "^10unnamed^0", g_skillNames[savehead.skill-1]); + Bsprintf(tempbuf, "%s / %s", name ? name : "^10unnamed^0", gSkillNames[savehead.skill-1].GetChars()); } mgametextcenter(origin.x, origin.y + (168<<16), tempbuf); @@ -2261,7 +2262,7 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) mgametextcenter(origin.x, origin.y + (156<<16), tempbuf); } - Bsprintf(tempbuf,"%s / %s",g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name, g_skillNames[ud.player_skill-1]); + Bsprintf(tempbuf,"%s / %s",g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name, gSkillNames[ud.player_skill-1].GetChars()); mgametextcenter(origin.x, origin.y + (168<<16), tempbuf); if (ud.volume_number == 0 && ud.level_number == 7) mgametextcenter(origin.x, origin.y + (180<<16), currentboardfilename); @@ -2305,7 +2306,7 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) #ifndef EDUKE32_ANDROID_MENU "\n(Y/N)" #endif - , g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name, g_skillNames[ud.player_skill-1]); + , g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name, gSkillNames[ud.player_skill-1].GetChars()); mgametextcenter(origin.x, origin.y + (90<<16), tempbuf); } else diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index b7f4b9316..7b369be2b 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "savegame.h" #include "cmdline.h" #include "statistics.h" +#include "menu/menu.h" BEGIN_RR_NS @@ -1900,7 +1901,7 @@ void G_NewGame(int volumeNum, int levelNum, int skillNum) ud.player_skill = skillNum; ud.secretlevel = 0; ud.from_bonus = 0; - STAT_StartNewGame(g_volumeNames[volumeNum], skillNum); + STAT_StartNewGame(gVolumeNames[volumeNum], skillNum); ud.last_level = -1; g_lastAutoSaveArbitraryID = -1; diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index 87bbf83ba..6bdcdad61 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "demo.h" #include "mdsprite.h" #include "gamecvars.h" +#include "menu/menu.h" BEGIN_RR_NS @@ -993,7 +994,7 @@ void G_DisplayRest(int32_t smoothratio) else { if (!G_HaveUserMap()) - minitext(5, a+6, g_volumeNames[ud.volume_number], 0, 2+8+16+256); + minitext(5, a+6, gVolumeNames[ud.volume_number], 0, 2+8+16+256); minitext(5, a+6+6, g_mapInfo[ud.volume_number*MAXLEVELS + ud.level_number].name, 0, 2+8+16+256); } } diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 36b32ff4f..2be188358 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -134,15 +134,25 @@ LISTMENU "EpisodeMenu" { ScriptId 100 // Episode names filled in programmatically - NativeTextItem "1", "", "SkillMenu", 1 - NativeTextItem "2", "", "SkillMenu", 2 - NativeTextItem "3", "", "SkillMenu", 3 - NativeTextItem "4", "", "SkillMenu", 4 - NativeTextItem "5", "", "SkillMenu", 5 - NativeTextItem "6", "", "SkillMenu", 6 - NativeTextItem "7", "", "SkillMenu", 7 + NativeTextItem "", "", "SkillMenu", 1 + NativeStaticTextItem "" + NativeTextItem "", "", "SkillMenu", 2 + NativeStaticTextItem "" + NativeTextItem "", "", "SkillMenu", 3 + NativeStaticTextItem "" + NativeTextItem "", "", "SkillMenu", 4 + NativeStaticTextItem "" + NativeTextItem "", "", "SkillMenu", 5 + NativeStaticTextItem "" + NativeTextItem "", "", "SkillMenu", 6 + NativeStaticTextItem "" + NativeTextItem "", "", "SkillMenu", 7 //Spacer NativeTextItem "$MNU_USERMAP", "u", "UserMap" + ifgame(ShadowWarrior) + { + NativeStaticTextItem "$MNU_SELECTUSERMAP" + } } LISTMENU "SkillMenu" From a9ee5940fcfcbdf1af1ced1ea20e8f95585b5d68 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 25 Nov 2019 00:28:59 +0100 Subject: [PATCH 016/203] - localization wrappers Currently a no-op, but if it's in it won't be forgotten later. --- source/common/utility/stringtable.h | 12 ++++++++++++ source/duke3d/src/gamedef.cpp | 5 +++-- source/rr/src/gamedef.cpp | 5 +++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/source/common/utility/stringtable.h b/source/common/utility/stringtable.h index e4137de3d..c9f71bfa2 100644 --- a/source/common/utility/stringtable.h +++ b/source/common/utility/stringtable.h @@ -111,6 +111,18 @@ private: void DeleteForLabel(int lumpnum, FName label); static size_t ProcessEscapes (char *str); +public: + static FString MakeMacro(const char *str) + { + //return FStringf("${%s}", str); + return str; + } + + static FString MakeMacro(const char *str, size_t len) + { + //return FStringf("${%.*s}", len, str); + return FString(str, len); + } }; #endif //__STRINGTABLE_H__ diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index 8af2b6b0c..3893ceb09 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -37,6 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "printf.h" #include "m_argv.h" #include "menu/menu.h" +#include "stringtable.h" BEGIN_DUKE_NS @@ -5017,7 +5018,7 @@ repeatcase: } i = strcspn(textptr, "\r\n"); - gVolumeNames[j] = FString(textptr, i); + gVolumeNames[j] = StringTable::MakeMacro(textptr, i); textptr += i; g_volumeCnt = j+1; @@ -5118,7 +5119,7 @@ repeatcase: } i = strcspn(textptr, "\r\n"); - gSkillNames[j] = FString(textptr, i); + gSkillNames[j] = StringTable::MakeMacro(textptr, i); textptr+=i; for (i=0; i Date: Mon, 25 Nov 2019 17:19:48 +0100 Subject: [PATCH 017/203] - fixed compile errors. (Include dependencies suck, it's time for modules to become an option.) --- source/common/menu/menu.h | 3 ++- source/duke3d/src/duke3d.h | 2 +- source/duke3d/src/game.h | 1 + source/duke3d/src/gamedef.cpp | 4 ++-- source/duke3d/src/global.h | 2 +- source/rr/src/duke3d.h | 2 +- source/rr/src/gamedef.cpp | 4 ++-- source/rr/src/global.h | 1 - 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index fe5c4b3e3..51a1bf56c 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -8,11 +8,12 @@ #include "v_font.h" #include "version.h" #include "textures.h" +#include "zstring.h" EXTERN_CVAR(Float, snd_menuvolume) EXTERN_CVAR(Int, m_use_mouse); -enum +enum EMax { MAXSKILLS = 7, MAXVOLUMES = 7, diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index 4d6405e7f..53686b96a 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -34,6 +34,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "pragmas.h" #include "polymost.h" #include "gamecvars.h" +#include "menu/menu.h" #define HEAD2 APPNAME @@ -58,7 +59,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define MOVEFIFOSIZ 2 // KEEPINSYNC lunatic/con_lang.lua -#define MAXVOLUMES 7 #define MAXLEVELS 64 #define MAXGAMETYPES 16 diff --git a/source/duke3d/src/game.h b/source/duke3d/src/game.h index e71d6a899..eaec48713 100644 --- a/source/duke3d/src/game.h +++ b/source/duke3d/src/game.h @@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gamevars.h" #include "mmulti.h" #include "network.h" +#include "menu/menu.h" BEGIN_DUKE_NS diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index 3893ceb09..ce83c0d40 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -5018,7 +5018,7 @@ repeatcase: } i = strcspn(textptr, "\r\n"); - gVolumeNames[j] = StringTable::MakeMacro(textptr, i); + gVolumeNames[j] = FStringTable::MakeMacro(textptr, i); textptr += i; g_volumeCnt = j+1; @@ -5119,7 +5119,7 @@ repeatcase: } i = strcspn(textptr, "\r\n"); - gSkillNames[j] = StringTable::MakeMacro(textptr, i); + gSkillNames[j] = FStringTable::MakeMacro(textptr, i); textptr+=i; for (i=0; i Date: Mon, 25 Nov 2019 18:41:39 +0100 Subject: [PATCH 018/203] - episode menu setup. --- source/common/menu/menu.h | 3 +- source/common/menu/menudef.cpp | 108 +++++++++++---------------- source/common/utility/namedef.h | 10 +++ source/duke3d/src/d_menu.cpp | 1 + wadsrc/static/demolition/menudef.txt | 16 +--- 5 files changed, 59 insertions(+), 79 deletions(-) diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 51a1bf56c..244e1ba1b 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -324,6 +324,7 @@ class FListMenuItem { protected: int mXpos, mYpos; + int mHeight; FName mAction; public: @@ -361,6 +362,7 @@ public: int GetX() { return mXpos; } void SetX(int x) { mXpos = x; } void SetY(int x) { mYpos = x; } + void SetHeight(int x) { mHeight = x; } }; class FListMenuItemStaticPatch : public FListMenuItem @@ -398,7 +400,6 @@ class FListMenuItemSelectable : public FListMenuItem { protected: int mHotkey; - int mHeight; int mParam; public: diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 6f479e368..92316cc5d 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -991,90 +991,70 @@ void M_ParseMenuDefs() static void BuildEpisodeMenu() { -#if 0 // Build episode menu - bool success = false; - FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Episodemenu); + int addedVolumes = 0; + FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_EpisodeMenu); if (desc != NULL) { if ((*desc)->mType == MDESC_ListMenu) { FListMenuDescriptor *ld = static_cast(*desc); - int posy = ld->mYpos; - int topy = posy; + ld->mSelectedItem = 1; - // Get lowest y coordinate of any static item in the menu - for(unsigned i = 0; i < ld->mItems.Size(); i++) + for (int i = 0; i < MAXVOLUMES; i++) { - int y = ld->mItems[i]->GetY(); - if (y < topy) topy = y; - } - - // center the menu on the screen if the top space is larger than the bottom space - int totalheight = posy + AllEpisodes.Size() * ld->mLinespacing - topy; - - if (totalheight < 190 || AllEpisodes.Size() == 1) - { - int newtop = (200 - totalheight + topy) / 2; - int topdelta = newtop - topy; - if (topdelta < 0) + if (gVolumeNames[i].IsNotEmpty()) { - for(unsigned i = 0; i < ld->mItems.Size(); i++) - { - ld->mItems[i]->OffsetPositionY(topdelta); - } - posy -= topdelta; - } - - ld->mSelectedItem = ld->mItems.Size(); - for(unsigned i = 0; i < AllEpisodes.Size(); i++) - { - FListMenuItem *it; - if (AllEpisodes[i].mPicName.IsNotEmpty()) - { - FTextureID tex = GetMenuTexture(AllEpisodes[i].mPicName); - it = new FListMenuItemPatch(ld->mXpos, posy, ld->mLinespacing, AllEpisodes[i].mShortcut, - tex, NAME_Skillmenu, i); - } - else - { - it = new FListMenuItemText(ld->mXpos, posy, ld->mLinespacing, AllEpisodes[i].mShortcut, - AllEpisodes[i].mEpisodeName, ld->mFont, ld->mFontColor, ld->mFontColor2, NAME_Skillmenu, i); - } + auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, gVolumeNames[i][0], gVolumeNames[i], NIT_BigFont, NIT_ActiveState, 1, NAME_SkillMenu, i + 1); ld->mItems.Push(it); - posy += ld->mLinespacing; + addedVolumes++; + if (gVolumeSubtitles[i].IsNotEmpty()) + { + //auto it = new FListMenuItemNativeStaticText(ld->mXpos, gVolumeSubtitles[i], NIT_SmallFont); + //ld->mItems.Push(it); + } } - if (AllEpisodes.Size() == 1) + if (1 /*CheckUserMaps()*/) { - ld->mAutoselect = ld->mSelectedItem; + //auto it = new FListMenuItemNativeStaticText(ld->mXpos, "", NIT_SmallFont); // empty entry as spacer. + //ld->mItems.Push(it); + + auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, 0, "$MNU_USERMAP", NIT_BigFont, NIT_ActiveState, 1, NAME_SkillMenu, i + 1); + ld->mItems.Push(it); + addedVolumes++; + if (g_gameType & GAMEFLAG_SW) // fixme: make this game independent. + { + //auto it = new FListMenuItemNativeStaticText(ld->mXpos, "$MNU_SELECTUSERMAP", NIT_SmallFont); + //ld->mItems.Push(it); + } + } + if (addedVolumes == 1) + { + ld->mAutoselect = 0; } - success = true; } } } - if (!success) +#if 0 + if (gVolumeNames[i].IsNotEmpty()) { - // Couldn't create the episode menu, either because there's too many episodes or some error occured - // Create an option menu for episode selection instead. - FOptionMenuDescriptor *od = new FOptionMenuDescriptor; - if (desc != NULL) delete *desc; - MenuDescriptors[NAME_Episodemenu] = od; - od->mType = MDESC_OptionsMenu; - od->mMenuName = NAME_Episodemenu; - od->mTitle = "$MNU_EPISODE"; - od->mSelectedItem = 0; - od->mScrollPos = 0; - od->mClass = NULL; - od->mPosition = -15; - od->mScrollTop = 0; - od->mIndent = 160; - od->mDontDim = false; - for(unsigned i = 0; i < AllEpisodes.Size(); i++) + if (!(gVolumeFlags[i] & EF_HIDEFROMSP)) { - FOptionMenuItemSubmenu *it = new FOptionMenuItemSubmenu(AllEpisodes[i].mEpisodeName, "Skillmenu", i); - od->mItems.Push(it); + MEL_EPISODE[i] = &ME_EPISODE[i]; + ME_EPISODE[i] = ME_EPISODE_TEMPLATE; + ME_EPISODE[i].name = gVolumeNames[i]; + } + + // if (!(EpisodeFlags[i] & EF_HIDEFROMMP)) + { + MEOSN_NetEpisodes[k] = gVolumeNames[i]; + MEOSV_NetEpisodes[k] = i; + + k++; } } + M_EPISODE.numEntries = g_volumeCnt + 2; + #endif } diff --git a/source/common/utility/namedef.h b/source/common/utility/namedef.h index b5425f821..47e37b7c4 100644 --- a/source/common/utility/namedef.h +++ b/source/common/utility/namedef.h @@ -24,3 +24,13 @@ xx(SaveMenu) xx(LoadMenu) xx(SoundMenu) xx(ConfirmPlayerReset) +xx(EpisodeMenu) +xx(SkillMenu) +xx(CustomGameMenu) +xx(CustomSubMenu1) +xx(CustomSubMenu2) +xx(CustomSubMenu3) +xx(CustomSubMenu4) +xx(CustomSubMenu5) +xx(CustomSubMenu6) +xx(CustomSubMenu7) diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index d4c6c71eb..c62f09588 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -547,6 +547,7 @@ protected: numvalidentries--; continue; } + entry->SetHeight(height); totalheight += height; } if (mDesc->mSpacing <= 0) calculatedentryspacing = std::max(0, (y_lower - y_upper - totalheight) / (numvalidentries > 1 ? numvalidentries - 1 : 1)); diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 2be188358..bccda7541 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -19,7 +19,6 @@ LISTMENU "MainMenu" position 160, 55, 115 centermenu } - linespacing 15 class "Duke.MainMenu" NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" //NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) @@ -134,25 +133,14 @@ LISTMENU "EpisodeMenu" { ScriptId 100 // Episode names filled in programmatically - NativeTextItem "", "", "SkillMenu", 1 - NativeStaticTextItem "" - NativeTextItem "", "", "SkillMenu", 2 - NativeStaticTextItem "" - NativeTextItem "", "", "SkillMenu", 3 - NativeStaticTextItem "" - NativeTextItem "", "", "SkillMenu", 4 - NativeStaticTextItem "" - NativeTextItem "", "", "SkillMenu", 5 - NativeStaticTextItem "" - NativeTextItem "", "", "SkillMenu", 6 - NativeStaticTextItem "" - NativeTextItem "", "", "SkillMenu", 7 //Spacer + /* NativeTextItem "$MNU_USERMAP", "u", "UserMap" ifgame(ShadowWarrior) { NativeStaticTextItem "$MNU_SELECTUSERMAP" } + */ } LISTMENU "SkillMenu" From a74a670c9979c195edb7c3bea841be51a0ad718c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 25 Nov 2019 23:21:51 +0100 Subject: [PATCH 019/203] -- more work on the menu - episode and skill menus are working in DN3D. --- source/build/src/sdlayer.cpp | 2 +- source/common/menu/listmenu.cpp | 9 +- source/common/menu/menu.cpp | 91 +++---- source/common/menu/menu.h | 42 ++- source/common/menu/menudef.cpp | 371 ++++++++++---------------- source/common/menu/optionmenu.cpp | 2 +- source/common/utility/namedef.h | 2 + source/duke3d/src/config.cpp | 1 - source/duke3d/src/d_menu.cpp | 249 +---------------- source/duke3d/src/game.h | 2 - source/duke3d/src/gamestructures.cpp | 20 +- source/duke3d/src/global.h | 5 - source/duke3d/src/menus.cpp | 70 ----- source/duke3d/src/menus.h | 26 -- source/rr/src/config.cpp | 1 - source/rr/src/game.h | 2 - source/rr/src/menus.cpp | 4 +- source/rr/src/screens.cpp | 1 - wadsrc/static/demolition/language.csv | 8 +- wadsrc/static/demolition/menudef.txt | 83 ++++-- 20 files changed, 309 insertions(+), 682 deletions(-) diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index d5e22a5f8..65f3bb8ab 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -1780,7 +1780,7 @@ int32_t handleevents_sdlcommon(SDL_Event *ev) break; case SDL_QUIT: - quitevent = 1; + throw ExitEvent(0); // completely bypass the hackery in the games to block Alt-F4. return -1; } diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index df1cfa725..8d1e3f164 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -178,7 +178,7 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller) return true; case MKEY_Enter: - if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate()) + if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate(mDesc->mMenuName)) { gi->MenuChooseSound(); } @@ -320,7 +320,7 @@ void FListMenuItem::DrawSelector(int xofs, int yofs, FTexture *tex) } } -bool FListMenuItem::Activate() +bool FListMenuItem::Activate(FName) { return false; // cannot be activated } @@ -476,10 +476,9 @@ bool FListMenuItemSelectable::Selectable() return mEnabled && !mHidden; } -bool FListMenuItemSelectable::Activate() +bool FListMenuItemSelectable::Activate(FName caller) { - M_SetMenu(mAction, mParam); - return true; + return M_SetMenu(mAction, mParam, caller); } FName FListMenuItemSelectable::GetAction(int *pparam) diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 75c8b3382..170132509 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -153,7 +153,7 @@ bool DMenu::MenuEvent (int mkey, bool fromcontroller) { case MKEY_Back: { - if (scriptID != 1) + if (scriptID != 0) { Close(); //S_Sound (CHAN_VOICE | CHAN_UI, DMenu::CurrentMenu != NULL? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE); @@ -301,10 +301,17 @@ bool DMenu::TranslateKeyboardEvents() void M_StartControlPanel (bool makeSound) { + static bool created = false; // intro might call this repeatedly if (DMenu::CurrentMenu != NULL) return; + if (!created) // Cannot do this earlier. + { + created = true; + M_CreateMenus(); + } + buttonMap.ResetButtonStates (); for (int i = 0; i < NUM_MKEYS; ++i) { @@ -350,7 +357,7 @@ void M_ActivateMenu(DMenu *menu) // //============================================================================= -void M_SetMenu(FName menu, int param) +bool M_SetMenu(FName menu, int param, FName caller) { if (DrawBackground == -1) { @@ -358,32 +365,40 @@ void M_SetMenu(FName menu, int param) else DrawBackground = 0; } // some menus need some special treatment (needs to be adjusted for the various frontends. -#if 0 + switch (caller) + { + case NAME_EpisodeMenu: + // sent from the episode menu + GameStartupInfo.Episode = param; + GameStartupInfo.CustomLevel1 = GameStartupInfo.CustomLevel2 = -1; + GameStartupInfo.Skill = gDefaultSkill; + break; + + case NAME_CustomGameMenu: + GameStartupInfo.CustomLevel1 = param; + GameStartupInfo.Episode = GameStartupInfo.CustomLevel2 = -1; + GameStartupInfo.Skill = gDefaultSkill; + // gi->CustomMenuSelection(-1, param); + break; + + case NAME_CustomSubMenu1: + GameStartupInfo.CustomLevel2 = param; + // gi->CustomMenuSelection(GameStartupInfo.CustomLevel1, param); + menu = FName(ENamedName(menu + param)); + break; + + case NAME_SkillMenu: + GameStartupInfo.Skill = param; + break; + } + switch (menu) { - case NAME_Episodemenu: - // sent from the player class menu - GameStartupInfo.Skill = -1; - GameStartupInfo.Episode = -1; - GameStartupInfo.PlayerClass = - param == -1000? NULL : - param == -1? "Random" : GetPrintableDisplayName(PlayerClasses[param].Type); - break; - - case NAME_Skillmenu: - // sent from the episode menu - - if ((gameinfo.flags & GI_SHAREWARE) && param > 0) - { - // Only Doom and Heretic have multi-episode shareware versions. - M_StartMessage(GStrings("SWSTRING"), 1); - return; - } - - GameStartupInfo.Episode = param; - M_StartupSkillMenu(&GameStartupInfo); // needs player class name from class menu (later) - break; + case NAME_StartGame: + // gi->StartGame(&GameStartupInfo); + return false; +#if 0 case NAME_StartgameConfirm: { // sent from the skill menu for a skill that needs to be confirmed @@ -395,21 +410,6 @@ void M_SetMenu(FName menu, int param) return; } - case NAME_Startgame: - // sent either from skill menu or confirmation screen. Skill gets only set if sent from skill menu - // Now we can finally start the game. Ugh... - GameStartupInfo.Skill = param; - case NAME_StartgameConfirmed: - - G_DeferedInitNew (&GameStartupInfo); - if (gamestate == GS_FULLCONSOLE) - { - gamestate = GS_HIDECONSOLE; - gameaction = ga_newgame; - } - M_ClearMenus (); - return; - case NAME_Savegamemenu: if (!usergame || (players[consoleplayer].health <= 0 && !multiplayer) || gamestate != GS_LEVEL) { @@ -417,8 +417,8 @@ void M_SetMenu(FName menu, int param) M_StartMessage (GStrings("SAVEDEAD"), 1); return; } - } #endif + } // End of special checks @@ -439,7 +439,7 @@ void M_SetMenu(FName menu, int param) if (ld->mAutoselect >= 0 && ld->mAutoselect < (int)ld->mItems.Size()) { // recursively activate the autoselected item without ever creating this menu. - ld->mItems[ld->mAutoselect]->Activate(); + ld->mItems[ld->mAutoselect]->Activate(ld->mMenuName); } else { @@ -462,6 +462,7 @@ void M_SetMenu(FName menu, int param) } newmenu->Init(DMenu::CurrentMenu, ld); M_ActivateMenu(newmenu); + return true; } } else if ((*desc)->mType == MDESC_OptionsMenu) @@ -473,7 +474,7 @@ void M_SetMenu(FName menu, int param) newmenu->Init(DMenu::CurrentMenu, ld); M_ActivateMenu(newmenu); } - return; + return true; } else { @@ -486,12 +487,13 @@ void M_SetMenu(FName menu, int param) DMenu *newmenu = (DMenu*)menuclass->CreateNew(); newmenu->mParentMenu = DMenu::CurrentMenu; M_ActivateMenu(newmenu); - return; + return true; } } */ } Printf("Attempting to open menu of unknown type '%s'\n", menu.GetChars()); + return false; } //============================================================================= @@ -790,7 +792,6 @@ void M_Init (void) RegisterDukeMenus(); timerSetCallback(M_Ticker); M_ParseMenuDefs(); - M_CreateMenus(); } diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 244e1ba1b..13f549c6d 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -17,6 +17,7 @@ enum EMax { MAXSKILLS = 7, MAXVOLUMES = 7, + MAXMENUGAMEPLAYENTRIES = 7, }; // These get filled in by the map definition parsers of the front ends. @@ -24,11 +25,40 @@ extern FString gSkillNames[MAXSKILLS]; extern FString gVolumeNames[MAXVOLUMES]; extern FString gVolumeSubtitles[MAXVOLUMES]; extern int32_t gVolumeFlags[MAXVOLUMES]; +extern int gDefaultVolume, gDefaultSkill; const int MENU_TICRATE = 30; extern bool help_disabled, credits_disabled; extern int g_currentMenu; +enum +{ + EF_HIDEFROMSP = 1 << 0, +}; + +enum MenuGameplayEntryFlags +{ + MGE_Locked = 1u << 0u, + MGE_Hidden = 1u << 1u, + MGE_UserContent = 1u << 2u, +}; + +typedef struct MenuGameplayEntry +{ + char name[64]; + uint8_t flags; + + bool isValid() const { return name[0] != '\0'; } +} MenuGameplayEntry; + +typedef struct MenuGameplayStemEntry +{ + MenuGameplayEntry entry; + MenuGameplayEntry subentries[MAXMENUGAMEPLAYENTRIES]; +} MenuGameplayStemEntry; + +extern MenuGameplayStemEntry g_MenuGameplayEntries[MAXMENUGAMEPLAYENTRIES]; + enum EMenuState : int { @@ -86,9 +116,10 @@ enum ENativeFontValues struct FGameStartup { - const char *PlayerClass; int Episode; int Skill; + int CustomLevel1; + int CustomLevel2; }; extern FGameStartup GameStartupInfo; @@ -345,7 +376,7 @@ public: virtual void Ticker(); virtual void Drawer(DListMenu *menu, const vec2_t& origin, bool selected); virtual bool Selectable(); - virtual bool Activate(); + virtual bool Activate(FName caller); virtual FName GetAction(int *pparam); virtual bool SetString(int i, const char *s); virtual bool GetString(int i, char *s, int len); @@ -363,6 +394,7 @@ public: void SetX(int x) { mXpos = x; } void SetY(int x) { mYpos = x; } void SetHeight(int x) { mHeight = x; } + void SetAction(FName action) { mAction = action; } }; class FListMenuItemStaticPatch : public FListMenuItem @@ -407,7 +439,7 @@ public: bool CheckCoordinate(int x, int y) override; bool Selectable() override; bool CheckHotkey(int c) override; - bool Activate() override; + bool Activate(FName caller) override; bool MouseEvent(int type, int x, int y) override; FName GetAction(int *pparam) override; }; @@ -636,9 +668,11 @@ void M_ParseMenuDefs(); void M_StartupSkillMenu(FGameStartup *gs); int M_GetDefaultSkill(); void M_StartControlPanel (bool makeSound); -void M_SetMenu(FName menu, int param = -1); +bool M_SetMenu(FName menu, int param = -1, FName callingMenu = NAME_None); void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave); void M_StartMessage(const char *message, int messagemode, FName action = NAME_None); +void M_UnhideCustomMenu(int menu, int itemmask); + void I_SetMouseCapture(); void I_ReleaseMouseCapture(); diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 92316cc5d..49920aef3 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -49,10 +49,13 @@ void ClearSaveGames(); +// Menu-relevant content that gets filled in by scripts. This will get processed after the game has loaded. FString gSkillNames[MAXSKILLS]; FString gVolumeNames[MAXVOLUMES]; FString gVolumeSubtitles[MAXVOLUMES]; int32_t gVolumeFlags[MAXVOLUMES]; +int gDefaultVolume = 0, gDefaultSkill = 1; +MenuGameplayStemEntry g_MenuGameplayEntries[MAXMENUGAMEPLAYENTRIES]; MenuDescriptorList MenuDescriptors; static FListMenuDescriptor DefaultListMenuSettings; // contains common settings for all list menus @@ -982,10 +985,34 @@ void M_ParseMenuDefs() } +//============================================================================= +// +// Unlocks a custom menu from a script +// +//============================================================================= + +void M_UnhideCustomMenu(int menu, int iSet) +{ + FName menuname = FName(ENamedName(NAME_CustomSubMenu1 + menu)); + auto desc = MenuDescriptors.CheckKey(menuname); + if (desc != NULL && (*desc)->mType == MDESC_ListMenu) + { + FListMenuDescriptor* ld = static_cast(*desc); + for (unsigned int b = 0; b < MAXMENUGAMEPLAYENTRIES; ++b) + { + if (b >= ld->mItems.Size()) return; + if (iSet & (1u << b)) + { + ld->mItems[b]->mHidden = false; + ld->mItems[b]->mEnabled = true; + } + } + } +} + //============================================================================= // // Creates the episode menu -// Falls back on an option menu if there's not enough screen space to show all episodes // //============================================================================= @@ -994,68 +1021,130 @@ static void BuildEpisodeMenu() // Build episode menu int addedVolumes = 0; FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_EpisodeMenu); - if (desc != NULL) + if (desc != NULL && (*desc)->mType == MDESC_ListMenu) { - if ((*desc)->mType == MDESC_ListMenu) + FListMenuDescriptor *ld = static_cast(*desc); + ld->mSelectedItem = gDefaultVolume; + + for (int i = 0; i < MAXVOLUMES; i++) { - FListMenuDescriptor *ld = static_cast(*desc); - ld->mSelectedItem = 1; + if (gVolumeNames[i].IsNotEmpty() && !(gVolumeFlags[i] & EF_HIDEFROMSP)) - for (int i = 0; i < MAXVOLUMES; i++) { - if (gVolumeNames[i].IsNotEmpty()) + auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, gVolumeNames[i][0], gVolumeNames[i], NIT_BigFont, NIT_ActiveState, 1, NAME_SkillMenu, i + 1); + ld->mItems.Push(it); + addedVolumes++; + if (gVolumeSubtitles[i].IsNotEmpty()) { - auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, gVolumeNames[i][0], gVolumeNames[i], NIT_BigFont, NIT_ActiveState, 1, NAME_SkillMenu, i + 1); - ld->mItems.Push(it); - addedVolumes++; - if (gVolumeSubtitles[i].IsNotEmpty()) - { - //auto it = new FListMenuItemNativeStaticText(ld->mXpos, gVolumeSubtitles[i], NIT_SmallFont); - //ld->mItems.Push(it); - } - } - if (1 /*CheckUserMaps()*/) - { - //auto it = new FListMenuItemNativeStaticText(ld->mXpos, "", NIT_SmallFont); // empty entry as spacer. + //auto it = new FListMenuItemNativeStaticText(ld->mXpos, gVolumeSubtitles[i], NIT_SmallFont); //ld->mItems.Push(it); + } + } + } + if (1 /*CheckUserMaps()*/) + { + //auto it = new FListMenuItemNativeStaticText(ld->mXpos, "", NIT_SmallFont); // empty entry as spacer. + //ld->mItems.Push(it); - auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, 0, "$MNU_USERMAP", NIT_BigFont, NIT_ActiveState, 1, NAME_SkillMenu, i + 1); - ld->mItems.Push(it); - addedVolumes++; - if (g_gameType & GAMEFLAG_SW) // fixme: make this game independent. + auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, 0, "$MNU_USERMAP", NIT_BigFont, NIT_ActiveState, 1, NAME_UsermapMenu); + ld->mItems.Push(it); + addedVolumes++; + if (g_gameType & GAMEFLAG_SW) // fixme: make this game independent. + { + //auto it = new FListMenuItemNativeStaticText(ld->mXpos, "$MNU_SELECTUSERMAP", NIT_SmallFont); + //ld->mItems.Push(it); + } + } + if (addedVolumes == 1) + { + ld->mAutoselect = 0; + } + } + + // Build skill menu + int addedSkills = 0; + desc = MenuDescriptors.CheckKey(NAME_SkillMenu); + if (desc != NULL && (*desc)->mType == MDESC_ListMenu) + { + FListMenuDescriptor* ld = static_cast(*desc); + ld->mSelectedItem = gDefaultSkill; + + for (int i = 0; i < MAXSKILLS; i++) + { + if (gSkillNames[i].IsNotEmpty()) + { + auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, gSkillNames[i][0], gSkillNames[i], NIT_BigFont, NIT_ActiveState, 1, NAME_StartGame, i); + ld->mItems.Push(it); + addedSkills++; + } + } + if (addedSkills == 0) + { + // Need to add one item with the default skill so that the menu does not break. + auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, 0, "", NIT_BigFont, NIT_ActiveState, 1, NAME_StartGame, gDefaultSkill); + ld->mItems.Push(it); + } + if (addedSkills == 1) + { + ld->mAutoselect = 0; + } + } + + if (g_MenuGameplayEntries[0].entry.isValid()) + { + int e = 0; + FMenuDescriptor** desc = MenuDescriptors.CheckKey(NAME_CustomGameMenu); + if (desc != NULL && (*desc)->mType == MDESC_ListMenu) + { + FListMenuDescriptor* ld = static_cast(*desc); + + for (MenuGameplayStemEntry const& stem : g_MenuGameplayEntries) + { + MenuGameplayEntry const& entry = stem.entry; + if (!entry.isValid()) + break; + + int s = 0; + FMenuDescriptor** sdesc = MenuDescriptors.CheckKey(FName(ENamedName(NAME_CustomSubMenu1 + e))); + if (sdesc != NULL && (*sdesc)->mType == MDESC_ListMenu) + { + FListMenuDescriptor* ld = static_cast(*desc); + + for (MenuGameplayEntry const& subentry : stem.subentries) { - //auto it = new FListMenuItemNativeStaticText(ld->mXpos, "$MNU_SELECTUSERMAP", NIT_SmallFont); - //ld->mItems.Push(it); + if (!subentry.isValid()) + break; + + auto li = new FListMenuItemNativeText(ld->mXpos, 0, 0, 0, subentry.name, NIT_BigFont, NIT_ActiveColor, 1.f, subentry.flags & MGE_UserContent ? NAME_UsermapMenu : NAME_SkillMenu); + + if (subentry.flags & MGE_Locked) li->mEnabled = false; + if (subentry.flags & MGE_Hidden) li->mHidden = true; + + ++s; } } - if (addedVolumes == 1) + FName link = entry.flags & MGE_UserContent ? NAME_UsermapMenu : s == 0 ? NAME_SkillMenu : NAME_CustomSubMenu1; + + auto li = new FListMenuItemNativeText(ld->mXpos, 0, 0, 0, entry.name, NIT_BigFont, NIT_ActiveColor, 1.f, link, link == NAME_CustomSubMenu1 ? e : -1); + if (entry.flags & MGE_Locked) li->mEnabled = false; + if (entry.flags & MGE_Hidden) li->mHidden = true; + e++; + } + } + if (e > 0) + { + FMenuDescriptor** desc = MenuDescriptors.CheckKey(NAME_MainMenu); + if (desc != NULL && (*desc)->mType == MDESC_ListMenu) + { + FListMenuDescriptor* ld = static_cast(*desc); + auto li = ld->mItems[0]; + if (li->GetAction(nullptr) == NAME_EpisodeMenu) { - ld->mAutoselect = 0; + li->SetAction(NAME_CustomGameMenu); } } } } -#if 0 - if (gVolumeNames[i].IsNotEmpty()) - { - if (!(gVolumeFlags[i] & EF_HIDEFROMSP)) - { - MEL_EPISODE[i] = &ME_EPISODE[i]; - ME_EPISODE[i] = ME_EPISODE_TEMPLATE; - ME_EPISODE[i].name = gVolumeNames[i]; - } - - // if (!(EpisodeFlags[i] & EF_HIDEFROMMP)) - { - MEOSN_NetEpisodes[k] = gVolumeNames[i]; - MEOSV_NetEpisodes[k] = i; - - k++; - } - } - M_EPISODE.numEntries = g_volumeCnt + 2; - -#endif } //============================================================================= @@ -1141,181 +1230,6 @@ void M_CreateMenus() #endif } -//============================================================================= -// -// The skill menu must be refeshed each time it starts up -// -//============================================================================= -extern int restart; - -void M_StartupSkillMenu(FGameStartup *gs) -{ -#if 0 - static int done = -1; - bool success = false; - FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Skillmenu); - if (desc != NULL) - { - if ((*desc)->mType == MDESC_ListMenu) - { - FListMenuDescriptor *ld = static_cast(*desc); - int x = ld->mXpos; - int y = ld->mYpos; - - // Delete previous contents - for(unsigned i=0; imItems.Size(); i++) - { - FName n = ld->mItems[i]->GetAction(NULL); - if (n == NAME_Startgame || n == NAME_StartgameConfirm) - { - for(unsigned j=i; jmItems.Size(); j++) - { - delete ld->mItems[j]; - } - ld->mItems.Resize(i); - break; - } - } - - if (done != restart) - { - done = restart; - int defskill = DefaultSkill; - if ((unsigned int)defskill >= AllSkills.Size()) - { - defskill = (AllSkills.Size() - 1) / 2; - } - ld->mSelectedItem = ld->mItems.Size() + defskill; - - int posy = y; - int topy = posy; - - // Get lowest y coordinate of any static item in the menu - for(unsigned i = 0; i < ld->mItems.Size(); i++) - { - int y = ld->mItems[i]->GetY(); - if (y < topy) topy = y; - } - - // center the menu on the screen if the top space is larger than the bottom space - int totalheight = posy + AllSkills.Size() * ld->mLinespacing - topy; - - if (totalheight < 190 || AllSkills.Size() == 1) - { - int newtop = (200 - totalheight + topy) / 2; - int topdelta = newtop - topy; - if (topdelta < 0) - { - for(unsigned i = 0; i < ld->mItems.Size(); i++) - { - ld->mItems[i]->OffsetPositionY(topdelta); - } - y = ld->mYpos = posy - topdelta; - } - } - else - { - // too large - delete ld; - desc = NULL; - done = false; - goto fail; - } - } - - unsigned firstitem = ld->mItems.Size(); - for(unsigned int i = 0; i < AllSkills.Size(); i++) - { - FSkillInfo &skill = AllSkills[i]; - FListMenuItem *li; - // Using a different name for skills that must be confirmed makes handling this easier. - FName action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? - NAME_StartgameConfirm : NAME_Startgame; - FString *pItemText = NULL; - if (gs->PlayerClass != NULL) - { - pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); - } - - if (skill.PicName.Len() != 0 && pItemText == NULL) - { - FTextureID tex = GetMenuTexture(skill.PicName); - li = new FListMenuItemPatch(ld->mXpos, y, ld->mLinespacing, skill.Shortcut, tex, action, i); - } - else - { - EColorRange color = (EColorRange)skill.GetTextColor(); - if (color == CR_UNTRANSLATED) color = ld->mFontColor; - li = new FListMenuItemText(x, y, ld->mLinespacing, skill.Shortcut, - pItemText? *pItemText : skill.MenuName, ld->mFont, color,ld->mFontColor2, action, i); - } - ld->mItems.Push(li); - y += ld->mLinespacing; - } - if (AllEpisodes[gs->Episode].mNoSkill || AllSkills.Size() == 1) - { - ld->mAutoselect = firstitem + M_GetDefaultSkill(); - } - else - { - ld->mAutoselect = -1; - } - success = true; - } - } - if (success) return; -fail: - // Option menu fallback for overlong skill lists - FOptionMenuDescriptor *od; - if (desc == NULL) - { - od = new FOptionMenuDescriptor; - if (desc != NULL) delete *desc; - MenuDescriptors[NAME_Skillmenu] = od; - od->mType = MDESC_OptionsMenu; - od->mMenuName = NAME_Skillmenu; - od->mTitle = "$MNU_CHOOSESKILL"; - od->mSelectedItem = 0; - od->mScrollPos = 0; - od->mClass = NULL; - od->mPosition = -15; - od->mScrollTop = 0; - od->mIndent = 160; - od->mDontDim = false; - } - else - { - od = static_cast(*desc); - for(unsigned i=0;imItems.Size(); i++) - { - delete od->mItems[i]; - } - od->mItems.Clear(); - } - for(unsigned int i = 0; i < AllSkills.Size(); i++) - { - FSkillInfo &skill = AllSkills[i]; - FOptionMenuItem *li; - // Using a different name for skills that must be confirmed makes handling this easier. - const char *action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? - "StartgameConfirm" : "Startgame"; - - FString *pItemText = NULL; - if (gs->PlayerClass != NULL) - { - pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); - } - li = new FOptionMenuItemSubmenu(pItemText? *pItemText : skill.MenuName, action, i); - od->mItems.Push(li); - if (!done) - { - done = true; - od->mSelectedItem = M_GetDefaultSkill(); - } - } -#endif -} - //============================================================================= // // Returns the default skill level. @@ -1324,14 +1238,5 @@ fail: int M_GetDefaultSkill() { -#if 0 - int defskill = DefaultSkill; - if ((unsigned int)defskill >= AllSkills.Size()) - { - defskill = (AllSkills.Size() - 1) / 2; - } - return defskill; -#else - return 1; -#endif + return gDefaultSkill; } diff --git a/source/common/menu/optionmenu.cpp b/source/common/menu/optionmenu.cpp index e8bf2f42d..38dddb82b 100644 --- a/source/common/menu/optionmenu.cpp +++ b/source/common/menu/optionmenu.cpp @@ -310,7 +310,7 @@ bool DOptionMenu::MenuEvent (int mkey, bool fromcontroller) break; case MKEY_Enter: - if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate()) + if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate(mDesc->mMenuName)) { return true; } diff --git a/source/common/utility/namedef.h b/source/common/utility/namedef.h index 47e37b7c4..ad19352e1 100644 --- a/source/common/utility/namedef.h +++ b/source/common/utility/namedef.h @@ -34,3 +34,5 @@ xx(CustomSubMenu4) xx(CustomSubMenu5) xx(CustomSubMenu6) xx(CustomSubMenu7) +xx(UsermapMenu) +xx(StartGame) \ No newline at end of file diff --git a/source/duke3d/src/config.cpp b/source/duke3d/src/config.cpp index 886984031..93d36764a 100644 --- a/source/duke3d/src/config.cpp +++ b/source/duke3d/src/config.cpp @@ -74,7 +74,6 @@ void CONFIG_SetDefaults(void) ud.angleinterpolation = 0; ud.camerasprite = -1; ud.config.ShowWeapons = 0; - ud.default_skill = 1; ud.display_bonus_screen = 1; hud_position = 0; diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index c62f09588..9a3a89449 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gamecontrol.h" #include "c_bind.h" #include "menu/menu.h" +#include "gstrings.h" #include "../../glbackend/glbackend.h" BEGIN_DUKE_NS @@ -44,10 +45,6 @@ BEGIN_DUKE_NS #define MENU_MARGIN_CENTER 160 #define MENU_HEIGHT_CENTER 100 -// This is for intermediate levels in the episode selection chain. Ion Fury uses this. -MenuGameplayStemEntry g_MenuGameplayEntries[MAXMENUGAMEPLAYENTRIES]; -int ME_NEWGAMECUSTOMENTRIES[MAXMENUGAMEPLAYENTRIES]; -int ME_NEWGAMECUSTOMSUBENTRIES[MAXMENUGAMEPLAYENTRIES][MAXMENUGAMEPLAYENTRIES]; enum MenuTextFlags_t { @@ -96,212 +93,6 @@ void Menu_Init(void) MF_Minifont.textflags |= TEXT_UPPERCASE; #if 0 - //int32_t i, j, k; - if (FURY) - { - MMF_Top_Skill.pos.x = (320 << 15); - ME_SKILL_TEMPLATE.format = &MEF_LeftMenu; - } - - // prepare gamefuncs and keys - MEOSN_Gamefuncs[0] = MenuGameFuncNone; - MEOSV_Gamefuncs[0] = -1; - k = 1; - for (i = 0; i < NUMGAMEFUNCTIONS; ++i) - { - MenuGameFuncs[i] = buttonMap.GetButtonAlias(i); - MenuGameFuncs[i].Substitute('_', ' '); - - if (MenuGameFuncs[i][0] != '\0') - { - MEOSN_Gamefuncs[k] = MenuGameFuncs[i]; - MEOSV_Gamefuncs[k] = i; - ++k; - } - } - MEOS_Gamefuncs.numOptions = k; - - for (i = 0; i < NUMKEYS; ++i) - MEOSN_Keys[i] = KB_ScanCodeToString(i); - MEOSN_Keys[NUMKEYS - 1] = MenuKeyNone; - - - // prepare episodes - k = 0; - - if (gVolumeNames[i].IsNotEmpty()) - { - if (!(gVolumeFlags[i] & EF_HIDEFROMSP)) - { - MEL_EPISODE[i] = &ME_EPISODE[i]; - ME_EPISODE[i] = ME_EPISODE_TEMPLATE; - ME_EPISODE[i].name = gVolumeNames[i]; - } - - // if (!(EpisodeFlags[i] & EF_HIDEFROMMP)) - { - MEOSN_NetEpisodes[k] = gVolumeNames[i]; - MEOSV_NetEpisodes[k] = i; - - k++; - } - } - M_EPISODE.numEntries = g_volumeCnt + 2; - - MEL_EPISODE[g_volumeCnt] = &ME_Space4_Redfont; - MEL_EPISODE[g_volumeCnt + 1] = &ME_EPISODE_USERMAP; - MEOSN_NetEpisodes[k] = MenuUserMap; - MEOSV_NetEpisodes[k] = MAXVOLUMES; - - MEOS_NETOPTIONS_EPISODE.numOptions = k + 1; - NetEpisode = MEOSV_NetEpisodes[0]; - MMF_Top_Episode.pos.y = (58 + (3 - k) * 6) << 16; - if (g_skillCnt == 0) - MEO_EPISODE.linkID = MENU_NULL; - M_EPISODE.currentEntry = ud.default_volume; - - // prepare new game custom :O - if (g_MenuGameplayEntries[0].entry.isValid()) - { - MEO_MAIN_NEWGAME.linkID = M_NEWVERIFY.linkID = MENU_NEWGAMECUSTOM; - - int e = 0; - for (MenuGameplayStemEntry const& stem : g_MenuGameplayEntries) - { - MenuGameplayEntry const& entry = stem.entry; - if (!entry.isValid()) - break; - - MenuEntry_t& e_me = ME_NEWGAMECUSTOMENTRIES[e]; - e_me = ME_EPISODE_TEMPLATE; - MenuLink_t& e_meo = MEO_NEWGAMECUSTOM[e]; - e_meo = MEO_NEWGAMECUSTOM_TEMPLATE; - e_me.entry = &e_meo; - - e_me.name = entry.name; - if (entry.flags & MGE_Locked) - e_me.flags |= MEF_Disabled; - if (entry.flags & MGE_Hidden) - e_me.flags |= MEF_Hidden; - - int s = 0; - for (MenuGameplayEntry const& subentry : stem.subentries) - { - if (!subentry.isValid()) - break; - - MenuEntry_t& s_me = ME_NEWGAMECUSTOMSUBENTRIES[e][s]; - s_me = ME_EPISODE_TEMPLATE; - MenuLink_t& s_meo = MEO_NEWGAMECUSTOMSUB[e][s]; - s_meo = MEO_NEWGAMECUSTOMSUB_TEMPLATE; - s_me.entry = &s_meo; - - s_me.name = subentry.name; - if (subentry.flags & MGE_Locked) - s_me.flags |= MEF_Disabled; - if (subentry.flags & MGE_Hidden) - s_me.flags |= MEF_Hidden; - - ++s; - } - - if (entry.flags & MGE_UserContent) - e_meo.linkID = MENU_USERMAP; - else if (s == 0) - e_meo.linkID = MENU_SKILL; - - ++e; - } - - Menu_PopulateNewGameCustom(); - } - - // prepare skills - k = -1; - for (i = 0; i < g_skillCnt && g_skillNames[i][0]; ++i) - { - MEL_SKILL[i] = &ME_SKILL[i]; - ME_SKILL[i] = ME_SKILL_TEMPLATE; - ME_SKILL[i].name = g_skillNames[i]; - - MEOSN_NetSkills[i] = g_skillNames[i]; - - k = i; - } - ++k; - M_SKILL.numEntries = g_skillCnt; // k; - MEOS_NETOPTIONS_MONSTERS.numOptions = g_skillCnt + 1; // k+1; - MEOSN_NetSkills[g_skillCnt] = MenuSkillNone; - MMF_Top_Skill.pos.y = (58 + (4 - g_skillCnt) * 6) << 16; - M_SKILL.currentEntry = ud.default_skill; - Menu_AdjustForCurrentEntryAssignmentBlind(&M_SKILL); - - // prepare multiplayer gametypes - k = -1; - for (i = 0; i < MAXGAMETYPES; ++i) - if (g_gametypeNames[i][0]) - { - MEOSN_NetGametypes[i] = g_gametypeNames[i]; - k = i; - } - ++k; - MEOS_NETOPTIONS_GAMETYPE.numOptions = k; - if (NAM_WW2GI) - ME_NETOPTIONS_MONSTERS.name = "Enemies"; - - // prepare cheats - for (i = 0; i < NUMCHEATFUNCS; ++i) - MEL_CHEATS[i + 1] = &ME_CheatCodes[i]; - - // prepare text chat macros - for (i = 0; i < MAXRIDECULE; ++i) - { - MEL_MACROS[i] = &ME_MACROS[i]; - ME_MACROS[i] = ME_MACROS_TEMPLATE; - ME_MACROS[i].entry = &MEO_MACROS[i]; - MEO_MACROS[i] = MEO_MACROS_TEMPLATE; - - MEO_MACROS[i].variable = sink;// ud.ridecule[i]; temporarily disabled - } - - // prepare input - for (i = 0; i < NUMGAMEFUNCTIONS; ++i) - { - if (MenuGameFuncs[i][0] == '\0') - { - MEL_KEYBOARDSETUPFUNCS[i] = NULL; - continue; - } - - MEL_KEYBOARDSETUPFUNCS[i] = &ME_KEYBOARDSETUPFUNCS[i]; - ME_KEYBOARDSETUPFUNCS[i] = ME_KEYBOARDSETUPFUNCS_TEMPLATE; - ME_KEYBOARDSETUPFUNCS[i].name = MenuGameFuncs[i]; - ME_KEYBOARDSETUPFUNCS[i].entry = &MEO_KEYBOARDSETUPFUNCS[i]; - MEO_KEYBOARDSETUPFUNCS[i] = MEO_KEYBOARDSETUPFUNCS_TEMPLATE; - } - M_KEYBOARDKEYS.numEntries = NUMGAMEFUNCTIONS; - for (i = 0; i < 2 * joystick.numButtons + 8 * joystick.numHats; ++i) - { - if (i < 2 * joystick.numButtons) - { - if (i & 1) - Bsnprintf(MenuJoystickNames[i], MAXJOYBUTTONSTRINGLENGTH, "Double %s", joyGetName(1, i >> 1)); - else - Bstrncpy(MenuJoystickNames[i], joyGetName(1, i >> 1), MAXJOYBUTTONSTRINGLENGTH); - } - else - { - Bsnprintf(MenuJoystickNames[i], MAXJOYBUTTONSTRINGLENGTH, (i & 1) ? "Double Hat %d %s" : "Hat %d %s", ((i - 2 * joystick.numButtons) >> 3), MenuJoystickHatDirections[((i - 2 * joystick.numButtons) >> 1) % 4]); - } - } - for (i = 0; i < joystick.numAxes; ++i) - { - ME_JOYSTICKAXES[i] = ME_JOYSTICKAXES_TEMPLATE; - Bstrncpy(MenuJoystickAxes[i], joyGetName(0, i), MAXJOYBUTTONSTRINGLENGTH); - ME_JOYSTICKAXES[i].name = MenuJoystickAxes[i]; - MEL_JOYSTICKAXES[i] = &ME_JOYSTICKAXES[i]; - } - M_JOYSTICKAXES.numEntries = joystick.numAxes; // prepare sound setup #ifndef EDUKE32_STANDALONE @@ -311,28 +102,6 @@ void Menu_Init(void) ME_SOUND_DUKETALK.name = "Grunt talk:"; #endif - if (FURY) - { - MF_Redfont.between.x = 2 << 16; - MF_Redfont.cursorScale = 32768; - MF_Redfont.zoom = 16384; - MF_Bluefont.zoom = 16384; - - // hack; should swap out pointers - MF_Minifont = MF_Bluefont; - - MMF_Top_Main.pos.x = 40 << 16; - MMF_Top_Main.pos.y = 130 << 16; - MMF_Top_Main.bottomcutoff = 190 << 16; - M_OPTIONS.format = &MMF_Top_Main; - - MEF_MainMenu.width = MEF_OptionsMenu.width = -(160 << 16); - MEF_MainMenu.marginBottom = 7 << 16; - - M_OPTIONS.title = NoTitle; - - SELECTDIR_z = 16384; - } // prepare shareware if (VOLUMEONE) @@ -358,10 +127,7 @@ void Menu_Init(void) M_CREDITS.title = M_CREDITS2.title = M_CREDITS3.title = s_Credits; } - MenuEntry_HideOnCondition(&ME_MAIN_HELP, G_GetLogoFlags() & LOGO_NOHELP); -#ifndef EDUKE32_SIMPLE_MENU - MenuEntry_HideOnCondition(&ME_MAIN_CREDITS, G_GetLogoFlags() & LOGO_NOCREDITS); -#endif + #endif } @@ -374,6 +140,7 @@ static void Menu_DrawTopBar(const vec2_t origin) static void Menu_DrawTopBarCaption(const char *caption, const vec2_t origin) { static char t[64]; + if (*caption == '$') caption = GStrings(caption + 1); size_t const srclen = strlen(caption); size_t const dstlen = min(srclen, ARRAY_SIZE(t)-1); memcpy(t, caption, dstlen); @@ -572,6 +339,11 @@ protected: void PreDraw() override { CallScript(CurrentMenu == this ? EVENT_DISPLAYMENU : EVENT_DISPLAYMENUREST, true); + if (mDesc->mCaption.IsNotEmpty()) + { + Menu_DrawTopBar(origin); + Menu_DrawTopBarCaption(mDesc->mCaption, origin); + } } void PostDraw() override @@ -601,11 +373,6 @@ class MainMenu : public DukeListMenu if (PLUTOPAK) // JBF 20030804 rotatesprite_fs((origin.y << 16) + ((MENU_MARGIN_CENTER+100)<<16), (origin.y << 16) + (36<<16), 65536L,0,PLUTOPAKSPRITE+2,(sintable[((int32_t) totalclock<<4)&2047]>>11),0,2+8); } - else if (mDesc->mCaption.IsNotEmpty()) - { - Menu_DrawTopBar(origin); - Menu_DrawTopBarCaption(mDesc->mCaption, origin); - } } }; diff --git a/source/duke3d/src/game.h b/source/duke3d/src/game.h index eaec48713..f9a7903fe 100644 --- a/source/duke3d/src/game.h +++ b/source/duke3d/src/game.h @@ -161,8 +161,6 @@ typedef struct { int32_t playerbest; - int32_t default_volume, default_skill; - int32_t returnvar[MAX_RETURN_VALUES-1]; uint32_t userbytever; diff --git a/source/duke3d/src/gamestructures.cpp b/source/duke3d/src/gamestructures.cpp index c3bc39c7a..a171b205f 100644 --- a/source/duke3d/src/gamestructures.cpp +++ b/source/duke3d/src/gamestructures.cpp @@ -1508,8 +1508,8 @@ int32_t __fastcall VM_GetUserdef(int32_t labelNum, int const lParm2) case USERDEFS_GLOBAL_R: labelNum = globalr; break; case USERDEFS_GLOBAL_G: labelNum = globalg; break; case USERDEFS_GLOBAL_B: labelNum = globalb; break; - case USERDEFS_DEFAULT_VOLUME: labelNum = ud.default_volume; break; - case USERDEFS_DEFAULT_SKILL: labelNum = ud.default_skill; break; + case USERDEFS_DEFAULT_VOLUME: labelNum = gDefaultVolume; break; + case USERDEFS_DEFAULT_SKILL: labelNum = gDefaultSkill; break; case USERDEFS_MENU_SHADEDESELECTED: labelNum = MF_Redfont.shade_deselected; break; case USERDEFS_MENU_SHADEDISABLED: labelNum = MF_Redfont.shade_disabled; break; case USERDEFS_MENUTEXT_ZOOM: labelNum = MF_Redfont.zoom; break; @@ -1701,8 +1701,8 @@ void __fastcall VM_SetUserdef(int const labelNum, int const lParm2, int32_t cons case USERDEFS_GLOBAL_R: globalr = iSet; break; case USERDEFS_GLOBAL_G: globalg = iSet; break; case USERDEFS_GLOBAL_B: globalb = iSet; break; - case USERDEFS_DEFAULT_VOLUME: ud.default_volume = iSet; break; - case USERDEFS_DEFAULT_SKILL: ud.default_skill = iSet; break; + case USERDEFS_DEFAULT_VOLUME: gDefaultVolume = iSet; break; + case USERDEFS_DEFAULT_SKILL: gDefaultSkill = iSet; break; case USERDEFS_MENU_SHADEDESELECTED: MF_Redfont.shade_deselected = MF_Bluefont.shade_deselected = MF_Minifont.shade_deselected = iSet; break; case USERDEFS_MENU_SHADEDISABLED: MF_Redfont.shade_disabled = MF_Bluefont.shade_disabled = MF_Minifont.shade_disabled = iSet; break; case USERDEFS_MENUTEXT_ZOOM: MF_Redfont.zoom = iSet; break; @@ -1751,16 +1751,8 @@ void __fastcall VM_SetUserdef(int const labelNum, int const lParm2, int32_t cons case USERDEFS_DRAW_Y: rotatesprite_y_offset = iSet; break; case USERDEFS_DRAW_YXASPECT: rotatesprite_yxaspect = iSet; break; case USERDEFS_FOV: r_fov.SetGenericRepDefault(iSet, CVAR_Int); break; - case USERDEFS_NEWGAMECUSTOMOPEN: - for (unsigned int b = 0; b < MAXMENUGAMEPLAYENTRIES; ++b) - if (iSet & (1u<actors_killed, p->max_actors_killed, p->secret_rooms, p->max_secret_rooms, p->player_par / REALGAMETICSPERSEC }; } diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index cfd2f5717..55e8b3769 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -10,4 +10,10 @@ Continue,MNU_CONTINUE,,,,,Fortfahren,,,,,,,,,,,,,,,,, Credits,MNU_CREDITS,,,,,,,,,,,,,,,,,,,,,, Cool Stuff,MNU_COOLSTUFF,,,,,Cooles Zeug,,,,,,,,,,,,,,,,, Multiplayer,MNU_MULTIPLAYER,,,,,Mehrspieler,,,,,,,,,,,,,,,,, -End Game,MNU_ENDGAME,,,,,Spiel beenden,,,,,,,,,,,,,,,,, \ No newline at end of file +End Game,MNU_ENDGAME,,,,,Spiel beenden,,,,,,,,,,,,,,,,, +User Map,MNU_USERMAP,,,,,Benutzerlevel,,,,,,,,,,,,,,,,, +Select a user map to play,MNU_SELECTUSERMAP,,,,,"Wähle ein Level zum Spielen +",,,,,,,,,,,,,,,,, +Select an Episode,MNU_SELECTEPISODE,,,,,"Welche Episode? +",,,,,,,,,,,,,,,,, +Select Skill,MNU_SELECTSKILL,,,,,Schwierigkeitsgrad,,,,,,,,,,,,,,,,, \ No newline at end of file diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index bccda7541..0fa8099b0 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------------- // -// Text only variant of the main menu for Doom, Strife and Chex Quest to be used with localized content. +// // //------------------------------------------------------------------------------------------- @@ -20,7 +20,7 @@ LISTMENU "MainMenu" centermenu } class "Duke.MainMenu" - NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" //NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) ifgame(fury) { @@ -37,8 +37,7 @@ LISTMENU "MainMenu" } ifgame(Redneck, RedneckRides) { - linespacing 15 - NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" //NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" @@ -48,8 +47,7 @@ LISTMENU "MainMenu" } ifgame(Blood) { - linespacing 15 - NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" NativeTextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" @@ -59,8 +57,7 @@ LISTMENU "MainMenu" } ifgame(ShadowWarrior) { - linespacing 15 - NativeTextItem "$MNU_NEWGAME", "n", "PlayerclassMenu" + NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" @@ -87,7 +84,7 @@ LISTMENU "IngameMenu" } linespacing 15 class "Duke.MainMenu" - NativeTextItem "$MNU_NEWGAME", "n", "CustomGameMenu" + NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" @@ -131,68 +128,100 @@ LISTMENU "IngameMenu" LISTMENU "EpisodeMenu" { - ScriptId 100 - // Episode names filled in programmatically - //Spacer - /* - NativeTextItem "$MNU_USERMAP", "u", "UserMap" - ifgame(ShadowWarrior) + ifgame(Duke, Nam, WW2GI, Fury) // Ion Fury does not use this menu. { - NativeStaticTextItem "$MNU_SELECTUSERMAP" + caption "$MNU_SELECTEPISODE" + position 160, 48, 142 + centermenu + fixedspacing 5 + class "Duke.ListMenu" } - */ + + ScriptId 100 } LISTMENU "SkillMenu" { - NativeTextItem "1", "", "StartGame", 1 + ifgame(Duke, Nam, WW2GI, Fury) // Ion Fury does not use this menu. + { + caption "$MNU_SELECTSKILL" + position 160, 55, 135 + centermenu + fixedspacing 5 + class "Duke.ListMenu" + } + + ScriptId 110 } LISTMENU "CustomGameMenu" { + position 160, 48, 142 + centermenu + fixedspacing 5 ScriptId 102 - // Filled in programmatically - //NativeTextItem "1", "", "CustomSubMenu1" } LISTMENU "CustomSubMenu1" { + position 160, 48, 142 + centermenu + fixedspacing 5 ScriptId 103 - //NativeTextItem "1", "", "SkillMenu" } LISTMENU "CustomSubMenu2" { + position 160, 48, 142 + centermenu + fixedspacing 5 ScriptId 103 - //NativeTextItem "1", "", "SkillMenu" } LISTMENU "CustomSubMenu3" { + position 160, 48, 142 + centermenu + fixedspacing 5 ScriptId 103 - //NativeTextItem "1", "", "SkillMenu" } LISTMENU "CustomSubMenu4" { + position 160, 48, 142 + centermenu + fixedspacing 5 ScriptId 103 - //NativeTextItem "1", "", "SkillMenu" } LISTMENU "CustomSubMenu5" { + position 160, 48, 142 + centermenu + fixedspacing 5 ScriptId 103 - //NativeTextItem "1", "", "SkillMenu" } LISTMENU "CustomSubMenu6" { + position 160, 48, 142 + centermenu + fixedspacing 5 ScriptId 103 - //NativeTextItem "1", "", "SkillMenu" } LISTMENU "CustomSubMenu7" { + position 160, 48, 142 + centermenu + fixedspacing 5 ScriptId 103 - //NativeTextItem "1", "", "SkillMenu" +} + +LISTMENU "MultiMenu" +{ + Caption "$MNU_NETWORKGAME" + NativeTextItem "$MNU_PLAYERSETUP", "p", "PlayerSetupMenu" + NativeTextItem "$MNU_JOINGAME", "j", "JoinGameMenu" + NativeTextItem "$MNU_HOSTGAME", "h", "HostGameMenu" } From dce633de8b03d03101b6e196b5471697f790c881 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 26 Nov 2019 00:20:21 +0100 Subject: [PATCH 020/203] - use a floating point origin in the menu's implementation Using fixed point here makes no sense, let's keep that to the code that still lives in the 90's. --- source/common/menu/listmenu.cpp | 14 +++++++------- source/common/menu/menu.h | 15 ++++++++------- source/duke3d/src/d_menu.cpp | 22 +++++++++++----------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 8d1e3f164..39e68cc67 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -290,7 +290,7 @@ void FListMenuItem::Ticker() { } -void FListMenuItem::Drawer(DListMenu* menu, const vec2_t& origin, bool selected) +void FListMenuItem::Drawer(DListMenu* menu, const DVector2& origin, bool selected) { } @@ -389,7 +389,7 @@ FListMenuItemStaticPatch::FListMenuItemStaticPatch(int x, int y, FTexture *patch mCentered = centered; } -void FListMenuItemStaticPatch::Drawer(DListMenu* menu, const vec2_t& origin, bool selected) +void FListMenuItemStaticPatch::Drawer(DListMenu* menu, const DVector2& origin, bool selected) { if (!mTexture) { @@ -426,7 +426,7 @@ FListMenuItemStaticText::FListMenuItemStaticText(int x, int y, const char *text, mCentered = centered; } -void FListMenuItemStaticText::Drawer(DListMenu* menu, const vec2_t& origin, bool selected) +void FListMenuItemStaticText::Drawer(DListMenu* menu, const DVector2& origin, bool selected) { const char *text = mText; if (text != NULL) @@ -529,7 +529,7 @@ FListMenuItemText::~FListMenuItemText() { } -void FListMenuItemText::Drawer(DListMenu* menu, const vec2_t& origin, bool selected) +void FListMenuItemText::Drawer(DListMenu* menu, const DVector2& origin, bool selected) { const char *text = mText; if (mText.Len()) @@ -571,14 +571,14 @@ FListMenuItemNativeText::~FListMenuItemNativeText() { } -void FListMenuItemNativeText::Drawer(DListMenu* menu, const vec2_t& origin, bool selected) +void FListMenuItemNativeText::Drawer(DListMenu* menu, const DVector2& origin, bool selected) { const char* text = mText; if (mText.Len() && !mHidden) { if (*text == '$') text = GStrings(text + 1); auto state = selected ? NIT_SelectedState : mEnabled ? NIT_ActiveState : NIT_InactiveState; - gi->DrawNativeMenuText(mFontnum, state, (mXpos << 16) + origin.x, (mYpos << 16) + origin.y, 1.f, text, menu->Descriptor()->mFlags); + gi->DrawNativeMenuText(mFontnum, state, int((origin.X + mXpos) / 65536) , int((origin.Y + mYpos) / 65536), 1.f, text, menu->Descriptor()->mFlags); } } @@ -601,7 +601,7 @@ FListMenuItemPatch::FListMenuItemPatch(int x, int y, int height, int hotkey, FTe mTexture = patch; } -void FListMenuItemPatch::Drawer(DListMenu* menu, const vec2_t& origin, bool selected) +void FListMenuItemPatch::Drawer(DListMenu* menu, const DVector2& origin, bool selected) { DrawTexture (&twod, mTexture, mXpos, mYpos, DTA_Clean, true, TAG_DONE); } diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 13f549c6d..b970a1f2a 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -318,10 +318,11 @@ public: static int MenuTime; DMenu *mParentMenu; - vec2_t origin; + DVector2 origin; int scriptID = INT_MAX; DMenu(DMenu *parent = NULL); + virtual ~DMenu() = default; virtual bool Responder (event_t *ev); virtual bool MenuEvent (int mkey, bool fromcontroller); virtual void Ticker (); @@ -374,7 +375,7 @@ public: virtual bool CheckCoordinate(int x, int y); virtual void Ticker(); - virtual void Drawer(DListMenu *menu, const vec2_t& origin, bool selected); + virtual void Drawer(DListMenu *menu, const DVector2& origin, bool selected); virtual bool Selectable(); virtual bool Activate(FName caller); virtual FName GetAction(int *pparam); @@ -405,7 +406,7 @@ protected: public: FListMenuItemStaticPatch(int x, int y, FTexture *patch, bool centered); - void Drawer(DListMenu* menu, const vec2_t& origin, bool selected); + void Drawer(DListMenu* menu, const DVector2& origin, bool selected); }; class FListMenuItemStaticText : public FListMenuItem @@ -419,7 +420,7 @@ protected: public: FListMenuItemStaticText(int x, int y, const char *text, FFont *font, EColorRange color, bool centered); ~FListMenuItemStaticText(); - void Drawer(DListMenu* menu, const vec2_t& origin, bool selected) override; + void Drawer(DListMenu* menu, const DVector2& origin, bool selected) override; }; //============================================================================= @@ -453,7 +454,7 @@ class FListMenuItemText : public FListMenuItemSelectable public: FListMenuItemText(int x, int y, int height, int hotkey, const FString &text, FFont *font, EColorRange color, EColorRange color2, FName child, int param = 0); ~FListMenuItemText(); - void Drawer(DListMenu* menu, const vec2_t& origin, bool selected) override; + void Drawer(DListMenu* menu, const DVector2& origin, bool selected) override; int GetWidth() override; }; @@ -467,7 +468,7 @@ class FListMenuItemNativeText : public FListMenuItemSelectable public: FListMenuItemNativeText(int x, int y, int height, int hotkey, const FString& text, int fontnum, int palnum, float fontscale, FName child, int param = 0); ~FListMenuItemNativeText(); - void Drawer(DListMenu* menu, const vec2_t& origin, bool selected) override; + void Drawer(DListMenu* menu, const DVector2& origin, bool selected) override; int GetWidth() override; void DrawSelector(int xofs, int yofs, FTexture* tex) override { } // The text drawer handles this itself. }; @@ -478,7 +479,7 @@ class FListMenuItemPatch : public FListMenuItemSelectable FTexture* mTexture; public: FListMenuItemPatch(int x, int y, int height, int hotkey, FTexture* patch, FName child, int param = 0); - void Drawer(DListMenu* menu, const vec2_t& origin, bool selected) override; + void Drawer(DListMenu* menu, const DVector2& origin, bool selected) override; int GetWidth() override; }; diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 9a3a89449..ab1837265 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -131,13 +131,13 @@ void Menu_Init(void) #endif } -static void Menu_DrawTopBar(const vec2_t origin) +static void Menu_DrawTopBar(const DVector2 &origin) { if ((G_GetLogoFlags() & LOGO_NOTITLEBAR) == 0) - rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (19<<16), MF_Redfont.cursorScale, 0,MENUBAR,16,0,10); + rotatesprite_fs(int(origin.X*65536) + (MENU_MARGIN_CENTER<<16), int(origin.Y*65536) + (19<<16), MF_Redfont.cursorScale, 0,MENUBAR,16,0,10); } -static void Menu_DrawTopBarCaption(const char *caption, const vec2_t origin) +static void Menu_DrawTopBarCaption(const char *caption, const DVector2 &origin) { static char t[64]; if (*caption == '$') caption = GStrings(caption + 1); @@ -148,7 +148,7 @@ static void Menu_DrawTopBarCaption(const char *caption, const vec2_t origin) char *p = &t[dstlen-1]; if (*p == ':') *p = '\0'; - captionmenutext(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (24<<16) + ((15>>1)<<16), t); + captionmenutext(int(origin.X*65536) + (MENU_MARGIN_CENTER<<16), int(origin.Y*65536) + (24<<16) + ((15>>1)<<16), t); } static void Menu_GetFmt(const MenuFont_t* font, uint8_t const status, int32_t* s, int32_t* z) @@ -227,7 +227,7 @@ void GameInterface::DrawNativeMenuText(int fontnum, int state, int xpos, int ypo { int ydim_upper = 0; int ydim_lower = ydim - 1; - int32_t const indent = 0; // not set for any relevant menu + //int32_t const indent = 0; // not set for any relevant menu int32_t x = xpos; uint8_t status = 0; @@ -271,14 +271,14 @@ protected: virtual void CallScript(int event, bool getorigin = false) { - ud.returnvar[0] = origin.x; - ud.returnvar[1] = origin.y; + ud.returnvar[0] = int(origin.X * 65536); + ud.returnvar[1] = int(origin.Y * 65536); ud.returnvar[2] = mDesc->mSelectedItem; VM_OnEventWithReturn(event, g_player[screenpeek].ps->i, screenpeek, mDesc->mScriptId); if (getorigin) { - origin.x = ud.returnvar[0]; - origin.y = ud.returnvar[1]; + origin.X = ud.returnvar[0] / 65536.; + origin.Y = ud.returnvar[1] / 65536.; } } @@ -369,9 +369,9 @@ class MainMenu : public DukeListMenu DukeListMenu::PreDraw(); if ((G_GetLogoFlags() & LOGO_NOGAMETITLE) == 0) { - rotatesprite_fs((origin.x << 16) + (MENU_MARGIN_CENTER<<16), (origin.y << 16) + ((28)<<16), 65536L,0,INGAMEDUKETHREEDEE,0,0,10); + rotatesprite_fs(int(origin.X * 65536) + (MENU_MARGIN_CENTER<<16), int(origin.Y * 65536) + ((28)<<16), 65536L,0,INGAMEDUKETHREEDEE,0,0,10); if (PLUTOPAK) // JBF 20030804 - rotatesprite_fs((origin.y << 16) + ((MENU_MARGIN_CENTER+100)<<16), (origin.y << 16) + (36<<16), 65536L,0,PLUTOPAKSPRITE+2,(sintable[((int32_t) totalclock<<4)&2047]>>11),0,2+8); + rotatesprite_fs(int(origin.X * 65536) + ((MENU_MARGIN_CENTER+100)<<16), int(origin.Y * 65536) + (36<<16), 65536L,0,PLUTOPAKSPRITE+2,(sintable[((int32_t) totalclock<<4)&2047]>>11),0,2+8); } } }; From 2ed598bb6cdc0ae27d7a7bf7eef9c57a08cb020c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 26 Nov 2019 00:29:51 +0100 Subject: [PATCH 021/203] - menu transition animation added. --- source/common/menu/menu.cpp | 52 +++++++++++++++++++++++++++++++++++++ source/common/menu/menu.h | 1 + 2 files changed, 53 insertions(+) diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 170132509..42b121719 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -49,6 +49,8 @@ #include "v_draw.h" #include "gamecontrol.h" #include "fx_man.h" +#include "pragmas.h" +#include "build.h" void RegisterDukeMenus(); extern bool rotatesprite_2doverride; @@ -86,6 +88,56 @@ static bool MenuEnabled = true; #define KEY_REPEAT_DELAY (MENU_TICRATE*5/12) #define KEY_REPEAT_RATE (3) +enum MenuTransitionType +{ // Note: This enum is for logical categories, not visual types. + MA_None, + MA_Return, + MA_Advance, +} ; + +struct MenuTransition +{ + DMenu *previous; + DMenu *current; + + int32_t start; + int32_t length; + int32_t dir; +}; + +bool M_StartTransition(DMenu *from, DMenu *to, MenuTransitionType animtype, MenuTransition &transition) +{ + if (!from->canAnimate || !to->canAnimate || animtype == MA_None) + { + return false; + } + else + { + transition.start = (int32_t) totalclock; + transition.length = 30; + transition.dir = animtype == MA_Advance? 1 : -1; + transition.previous = from; + transition.current = to; + return true; + } +} + +bool M_DrawTransition(MenuTransition &transition) +{ + if (totalclock < transition.start + transition.length) + { + double factor = 120 * xdim / ydim; + double phase = ((int32_t) totalclock - transition.start) / double(transition.length) * M_PI + M_PI/2; + + transition.previous->origin.X = factor * transition.dir * (sin(phase) - 1.); + transition.current->origin.X = factor * transition.dir * (sin(phase) + 1.); + transition.previous->Drawer(); + transition.current->Drawer(); + return false; + } + return true; +} + //============================================================================ // // DMenu base class diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index b970a1f2a..cbabae10c 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -320,6 +320,7 @@ public: DMenu *mParentMenu; DVector2 origin; int scriptID = INT_MAX; + bool canAnimate = false; DMenu(DMenu *parent = NULL); virtual ~DMenu() = default; From 0597b4cf12b8cac04dbe5e9e44d6a46432404090 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 26 Nov 2019 00:43:20 +0100 Subject: [PATCH 022/203] - enabled the menu transitions. --- source/common/menu/menu.cpp | 65 +++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 42b121719..ce5fab649 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -105,6 +105,8 @@ struct MenuTransition int32_t dir; }; +static MenuTransition transition; + bool M_StartTransition(DMenu *from, DMenu *to, MenuTransitionType animtype, MenuTransition &transition) { if (!from->canAnimate || !to->canAnimate || animtype == MA_None) @@ -133,9 +135,9 @@ bool M_DrawTransition(MenuTransition &transition) transition.current->origin.X = factor * transition.dir * (sin(phase) + 1.); transition.previous->Drawer(); transition.current->Drawer(); - return false; + return true; } - return true; + return false; } //============================================================================ @@ -225,16 +227,24 @@ bool DMenu::MenuEvent (int mkey, bool fromcontroller) void DMenu::Close () { assert(DMenu::CurrentMenu == this); + DMenu::CurrentMenu = mParentMenu; - Destroy(); - delete this; - if (DMenu::CurrentMenu == NULL) + if (mParentMenu && M_StartTransition(this, mParentMenu, MA_Return, transition)) { - M_ClearMenus(); + g_currentMenu = DMenu::CurrentMenu->scriptID; } else { - g_currentMenu = DMenu::CurrentMenu->scriptID; + Destroy(); + delete this; + if (DMenu::CurrentMenu == NULL) + { + M_ClearMenus(); + } + else + { + g_currentMenu = DMenu::CurrentMenu->scriptID; + } } } @@ -399,7 +409,11 @@ void M_ActivateMenu(DMenu *menu) { g_currentMenu = menu->scriptID; if (menuactive == MENU_Off) menuactive = MENU_On; - if (DMenu::CurrentMenu != NULL) DMenu::CurrentMenu->ReleaseCapture(); + if (DMenu::CurrentMenu != NULL) + { + DMenu::CurrentMenu->ReleaseCapture(); + M_StartTransition(DMenu::CurrentMenu, menu, MA_Advance, transition); + } DMenu::CurrentMenu = menu; } @@ -785,27 +799,28 @@ void M_Drawer (void) { rotatesprite_2doverride = true; PalEntry fade = 0x70000000; -#if 0 - player_t *player = &players[consoleplayer]; - AActor *camera = player->camera; - - if (!screen->Accel2D && camera != NULL && (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL)) - { - if (camera->player != NULL) - { - player = camera->player; - } - fade = PalEntry (BYTE(player->BlendA*255), BYTE(player->BlendR*255), BYTE(player->BlendG*255), BYTE(player->BlendB*255)); - } -#endif - if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) { - DMenu::CurrentMenu->origin = { 0,0 }; if (DMenu::CurrentMenu->DimAllowed() && fade && !DrawBackground) twod.AddColorOnlyQuad(0, 0, screen->GetWidth(), screen->GetHeight(), fade); - // else if (DrawBackground) Menu_DrawBackground(origin); - DMenu::CurrentMenu->Drawer(); + + bool done = false; + if (transition.previous) + { + done = M_DrawTransition(transition); + if (!done) + { + delete transition.previous; + transition.previous = nullptr; + transition.current = nullptr; + } + } + if (!done) + { + DMenu::CurrentMenu->origin = { 0,0 }; + // else if (DrawBackground) Menu_DrawBackground(origin); + DMenu::CurrentMenu->Drawer(); + } } rotatesprite_2doverride = false; } From 6782d817b76f530d9994c45298b0e5924777cd94 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 26 Nov 2019 17:42:57 +0100 Subject: [PATCH 023/203] - reformatting and deletion of unused code. --- source/duke3d/src/d_menu.cpp | 6 ++-- source/duke3d/src/menus.cpp | 62 ------------------------------------ 2 files changed, 3 insertions(+), 65 deletions(-) diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index ab1837265..3c1d69f7d 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -188,11 +188,11 @@ static vec2_t Menu_Text(int32_t x, int32_t y, const MenuFont_t* font, const char else if (status & MT_Selected) p = (status & MT_RightSide) ? font->pal_selected_right : font->pal_selected; else -p = (status & MT_RightSide) ? font->pal_deselected_right : font->pal_deselected; + p = (status & MT_RightSide) ? font->pal_deselected_right : font->pal_deselected; -Menu_GetFmt(font, status, &s, &z); + Menu_GetFmt(font, status, &s, &z); -return G_ScreenText(font->tilenum, x, y, z, 0, 0, t, s, p, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, font->emptychar.x, font->emptychar.y, font->between.x, ybetween, f, 0, ydim_upper, xdim - 1, ydim_lower); + return G_ScreenText(font->tilenum, x, y, z, 0, 0, t, s, p, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, font->emptychar.x, font->emptychar.y, font->between.x, ybetween, f, 0, ydim_upper, xdim - 1, ydim_lower); } static int32_t Menu_CursorShade(void) diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index fd9c253a2..c7c9a8ea1 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -136,24 +136,6 @@ static void Menu_DrawTopBarCaption(const char *caption, const vec2_t origin) captionmenutext(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (24<<16) + ((15>>1)<<16), t); } -static FORCE_INLINE int32_t Menu_CursorShade(void) -{ - return VM_OnEventWithReturn(EVENT_MENUCURSORSHADE, -1, myconnectindex, 4-(sintable[((int32_t) totalclock<<4)&2047]>>11)); -} -static void Menu_DrawCursorCommon(int32_t x, int32_t y, int32_t z, int32_t picnum, int32_t ydim_upper = 0, int32_t ydim_lower = ydim-1) -{ - rotatesprite_(x, y, z, 0, picnum, Menu_CursorShade(), 0, 2|8, 0, 0, 0, ydim_upper, xdim-1, ydim_lower); -} -static void Menu_DrawCursorLeft(int32_t x, int32_t y, int32_t z) -{ - if (FURY) return; - Menu_DrawCursorCommon(x, y, z, VM_OnEventWithReturn(EVENT_MENUCURSORLEFT, -1, myconnectindex, SPINNINGNUKEICON+(((int32_t) totalclock>>3)%7))); -} -static void Menu_DrawCursorRight(int32_t x, int32_t y, int32_t z) -{ - if (FURY) return; - Menu_DrawCursorCommon(x, y, z, VM_OnEventWithReturn(EVENT_MENUCURSORRIGHT, -1, myconnectindex, SPINNINGNUKEICON+6-((6+((int32_t) totalclock>>3))%7))); -} static void Menu_DrawCursorTextTile(int32_t x, int32_t y, int32_t h, int32_t picnum, vec2_16_t const & siz, int32_t ydim_upper = 0, int32_t ydim_lower = ydim-1) { vec2_t const adjsiz = { (siz.x>>1)<<16, siz.y<<16 }; @@ -4182,50 +4164,6 @@ enum MenuTextFlags_t MT_RightSide = 1<<6, }; -static void Menu_GetFmt(const MenuFont_t *font, uint8_t const status, int32_t *s, int32_t *z) -{ - if (status & MT_Selected) - *s = VM_OnEventWithReturn(EVENT_MENUSHADESELECTED, -1, myconnectindex, sintable[((int32_t) totalclock<<5)&2047]>>12); - else - *s = font->shade_deselected; - // sum shade values - if (status & MT_Disabled) - *s += font->shade_disabled; - - if (FURY && status & MT_Selected) - *z += (*z >> 4); -} - -static vec2_t Menu_Text(int32_t x, int32_t y, const MenuFont_t *font, const char *t, uint8_t status, int32_t ydim_upper, int32_t ydim_lower) -{ - int32_t s, p, ybetween = font->between.y; - int32_t f = font->textflags; - if (status & MT_XCenter) - f |= TEXT_XCENTER; - if (status & MT_XRight) - f |= TEXT_XRIGHT; - if (status & MT_YCenter) - { - f |= TEXT_YCENTER | TEXT_YOFFSETZERO; - ybetween = font->emptychar.y; // <^ the battle against 'Q' - } - if (status & MT_Literal) - f |= TEXT_LITERALESCAPE; - - int32_t z = font->zoom; - - if (status & MT_Disabled) - p = (status & MT_RightSide) ? font->pal_disabled_right : font->pal_disabled; - else if (status & MT_Selected) - p = (status & MT_RightSide) ? font->pal_selected_right : font->pal_selected; - else - p = (status & MT_RightSide) ? font->pal_deselected_right : font->pal_deselected; - - Menu_GetFmt(font, status, &s, &z); - - return G_ScreenText(font->tilenum, x, y, z, 0, 0, t, s, p, 2|8|16|ROTATESPRITE_FULL16, 0, font->emptychar.x, font->emptychar.y, font->between.x, ybetween, f, 0, ydim_upper, xdim-1, ydim_lower); -} - static int32_t Menu_FindOptionBinarySearch(MenuOption_t *object, const int32_t query, uint16_t searchstart, uint16_t searchend) { const uint16_t thissearch = (searchstart + searchend) / 2; From 1adceb82ef93bdfc9c2bc306d68382bb6046369b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 26 Nov 2019 21:06:43 +0100 Subject: [PATCH 024/203] - consolidation of defbinds definitions. Putting all the generic definitions in files used by all games greatly reduces the clutter and chance for errors. --- source/common/console/c_bind.cpp | 16 ++-- source/common/console/c_bind.h | 3 +- source/common/menu/listmenu.cpp | 2 +- wadsrc/static/demolition/commonbinds.txt | 64 ++++++++++++++++ wadsrc/static/demolition/defbinds.all | 15 ---- wadsrc/static/demolition/defbinds.txt | 18 +++++ wadsrc/static/demolition/leftbinds.txt | 14 ++++ .../filter/blood/demolition/defbinds.txt | 69 +---------------- .../filter/blood/demolition/leftbinds.txt | 68 +---------------- .../filter/blood/demolition/origbinds.txt | 69 +---------------- .../filter/duke/demolition/defbinds.txt | 68 +---------------- .../filter/duke/demolition/leftbinds.txt | 64 +--------------- .../filter/duke/demolition/origbinds.txt | 75 ++----------------- .../filter/ionfury/demolition/defbinds.txt | 64 +--------------- .../filter/ionfury/demolition/leftbinds.txt | 64 ---------------- .../filter/ionfury/demolition/origbinds.txt | 65 ---------------- .../static/filter/nam/demolition/defbinds.txt | 68 +---------------- .../filter/nam/demolition/leftbinds.txt | 68 +---------------- .../filter/nam/demolition/origbinds.txt | 73 ++---------------- .../filter/redneck/demolition/defbinds.txt | 69 +---------------- .../filter/redneck/demolition/leftbinds.txt | 71 +----------------- .../filter/redneck/demolition/origbinds.txt | 72 ++---------------- .../shadowwarrior/demolition/defbinds.txt | 41 +--------- .../shadowwarrior/demolition/leftbinds.txt | 59 --------------- .../shadowwarrior/demolition/origbinds.txt | 64 +--------------- .../filter/ww2gi/demolition/defbinds.txt | 68 +---------------- .../filter/ww2gi/demolition/leftbinds.txt | 69 +---------------- .../filter/ww2gi/demolition/origbinds.txt | 74 ++---------------- 28 files changed, 167 insertions(+), 1367 deletions(-) create mode 100644 wadsrc/static/demolition/commonbinds.txt delete mode 100644 wadsrc/static/demolition/defbinds.all create mode 100644 wadsrc/static/demolition/defbinds.txt create mode 100644 wadsrc/static/demolition/leftbinds.txt diff --git a/source/common/console/c_bind.cpp b/source/common/console/c_bind.cpp index b504bb41e..bae950673 100644 --- a/source/common/console/c_bind.cpp +++ b/source/common/console/c_bind.cpp @@ -649,7 +649,7 @@ CCMD(rebind) // //============================================================================= -void ReadBindings(int lump) +void ReadBindings(int lump, bool override) { FScanner sc(lump); @@ -675,20 +675,26 @@ void ReadBindings(int lump) } key = GetConfigKeyFromName(sc.String); sc.MustGetString(); - dest->SetBind(key, sc.String); + dest->SetBind(key, sc.String, override); } } void CONFIG_SetDefaultKeys(const char* baseconfig) { - auto lump = fileSystem.GetFile(baseconfig); - ReadBindings(lump); + auto lump = fileSystem.GetFile("demolition/commonbinds.txt", ELookupMode::FullName, 0); + if (lump >= 0) ReadBindings(lump, true); int lastlump = 0; + while ((lump = fileSystem.Iterate(baseconfig, &lastlump)) != -1) + { + if (fileSystem.GetFileContainer(lump) > 0) break; + ReadBindings(lump, true); + } + while ((lump = fileSystem.Iterate("defbinds.txt", &lastlump)) != -1) { - ReadBindings(lump); + ReadBindings(lump, false); } } diff --git a/source/common/console/c_bind.h b/source/common/console/c_bind.h index 9fbd32f41..11f5bd6d7 100644 --- a/source/common/console/c_bind.h +++ b/source/common/console/c_bind.h @@ -61,8 +61,9 @@ public: void DoBind (const char *key, const char *bind); void DefaultBind(const char *keyname, const char *cmd); - void SetBind(unsigned int key, const char *bind) + void SetBind(unsigned int key, const char *bind, bool override = true) { + if (!override && Binds[key].IsNotEmpty()) return; if (key < NUM_KEYS) Binds[key] = bind; } diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 39e68cc67..86ceb66d4 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -578,7 +578,7 @@ void FListMenuItemNativeText::Drawer(DListMenu* menu, const DVector2& origin, bo { if (*text == '$') text = GStrings(text + 1); auto state = selected ? NIT_SelectedState : mEnabled ? NIT_ActiveState : NIT_InactiveState; - gi->DrawNativeMenuText(mFontnum, state, int((origin.X + mXpos) / 65536) , int((origin.Y + mYpos) / 65536), 1.f, text, menu->Descriptor()->mFlags); + gi->DrawNativeMenuText(mFontnum, state, int((origin.X + mXpos) * 65536) , int((origin.Y + mYpos) * 65536), 1.f, text, menu->Descriptor()->mFlags); } } diff --git a/wadsrc/static/demolition/commonbinds.txt b/wadsrc/static/demolition/commonbinds.txt new file mode 100644 index 000000000..e9babc5c6 --- /dev/null +++ b/wadsrc/static/demolition/commonbinds.txt @@ -0,0 +1,64 @@ +// These bindings are valid for all configurationas + +F1 "openhelpmenu" +F2 "opensavemenu" +F3 "openloadmenu" +F4 "openmenu SoundOptions" +F5 "openmeun OptionMenu" //this key performs some fuckery with the music in Duke Nukem,so the default here is Blood's. +F6 "+Quick_Save" +F7 "+Third_Person_View" +//F8 "toggle hud_messages" // this one needs a means to print the status to the quote display. +F9 "+Quick_Load" +F10 "openmenu QuitIngame" +F11 "openmenu ColorCorrection" +F12 "screenshot" +1 "+Weapon_1" +2 "+Weapon_2" +3 "+Weapon_3" +4 "+Weapon_4" +5 "+Weapon_5" +6 "+Weapon_6" +7 "+Weapon_7" +8 "+Weapon_8" +9 "+Weapon_9" +0 "+Weapon_10" +Ins "+Look_Left" +KP0 "+Look_Left" +Del "+Look_Right" +leftarrow "+Turn_Left" +rightarrow "+Turn_Right" +KP8 "+Move_Forward" +KP2 "+Move_Backward" +KP4 "+Turn_Left" +KP6 "+Turn_Right" +LAlt "+Strafe" +RAlt "+Strafe" +LShift "+Run" +RShift "+Run" +Capslock "+AutoRun" +PgUp "+Look_Up" +PgDn "+Look_Down" +Home "+Aim_Up" +End "+Aim_Down" +RCtrl "+Fire" + +Enter "+Inventory" +KP-Enter "+Inventory" +[ "+Inventory_Left" +] "+Inventory_Right" + +' "+Next_Weapon" +; "+Previous_Weapon" +` "toggleconsole" + +Backspace "+Turn_Around" +T "+Send_Message" +Tab "+Map" +F "+Map_Follow_Mode" +- "+Shrink_Screen" += "+Enlarge_Screen" +K "+See_Coop_View" + +Mouse1 "+Fire" +MWheelUp "+Previous_Weapon" +MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/demolition/defbinds.all b/wadsrc/static/demolition/defbinds.all deleted file mode 100644 index 83c9546b9..000000000 --- a/wadsrc/static/demolition/defbinds.all +++ /dev/null @@ -1,15 +0,0 @@ -// These bindings are valid for all configurationas - -F1 "openhelpmenu" -F2 "opensavemenu" -F3 "openloadmenu" -F4 "openmenu SoundOptions" -F5 "openmeun OptionMenu" //this key performs some fuckery with the music in Duke Nukem,so the default here is Blood's. -F6 "+Quick_Save" -F7 "+Third_Person_View" -//F8 "toggle hud_messages" // this one needs a means to print the status to the quote display. -F9 "+Quick_Load" -F10 "openmenu QuitIngame" -F11 "openmenu ColorCorrection" -F12 "screenshot" - diff --git a/wadsrc/static/demolition/defbinds.txt b/wadsrc/static/demolition/defbinds.txt new file mode 100644 index 000000000..eb5a41054 --- /dev/null +++ b/wadsrc/static/demolition/defbinds.txt @@ -0,0 +1,18 @@ +// Common bindings for all games (some may not be active everywhere, though) +W "+Move_Forward" +S "+Move_Backward" +E "+Open" +A "+Strafe_Left" +D "+Strafe_Right" +Space "+Jump" +/ "+Jump" +LCtrl "+Crouch" +KP7 "+Aim_Up" +KP1 "+Aim_Down" +KP5 "+Center_View" +KP9 "+Look_Up" +KP3 "+Look_Down" +KP. "+Look_Right" +KP- "+Shrink_Screen" +KP+ "+Enlarge_Screen" +Y "+Show_Opponents_Weapon" diff --git a/wadsrc/static/demolition/leftbinds.txt b/wadsrc/static/demolition/leftbinds.txt new file mode 100644 index 000000000..6f7f79710 --- /dev/null +++ b/wadsrc/static/demolition/leftbinds.txt @@ -0,0 +1,14 @@ +// Left handed config (puts as many controls as possible on the numpad. Also more useful actions on the mouse.) +uparrow "+Move_Forward" +downarrow "+Move_Backward" +LCtrl "+Fire" +Space "+Open" +A "+Jump" +KP- "+Jump" +Z "+Crouch" +KP. "+Look_Right" +KP7 "+Strafe_Left" +KP9 "+Strafe_Right" +KP. "+Look_Right" +Mouse2 "+Open" +Mouse3 "+Run" diff --git a/wadsrc/static/filter/blood/demolition/defbinds.txt b/wadsrc/static/filter/blood/demolition/defbinds.txt index 1f10c0029..22fb508cd 100644 --- a/wadsrc/static/filter/blood/demolition/defbinds.txt +++ b/wadsrc/static/filter/blood/demolition/defbinds.txt @@ -1,75 +1,10 @@ -W "+Move_Forward" -KP8 "+Move_Forward" -S "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -Backspace "+Turn_Around" -LAlt "+Strafe" -RAlt "+Strafe" -A "+Strafe_Left" -D "+Strafe_Right" -Space "+Jump" -/ "+Jump" -LCtrl "+Crouch" -LShift "+Run" -RShift "+Run" -Capslock "+AutoRun" -E "+Open" -RCtrl "+Fire" -X "+Alt_Fire" -Home "+Aim_Up" -KP7 "+Aim_Up" -End "+Aim_Down" -KP1 "+Aim_Down" -KP5 "+Center_View" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" -Tab "+Map" -F "+Map_Follow_Mode" -- "+Shrink_Screen" -KP- "+Shrink_Screen" -= "+Enlarge_Screen" -KP+ "+Enlarge_Screen" -T "+Send_Message" -K "+See_Coop_View" -F7 "+See_Chase_View" +// U "+Mouse_Aiming" I "+Toggle_Crosshair" -' "+Next_Weapon" -; "+Previous_Weapon" Scroll "+Holster_Weapon" -Y "+Show_Opponents_Weapon" B "+BeastVision" C "+CrystalBall" -J "+JetPack" -M "+MedKit" P "+ProximityBombs" R "+RemoteBombs" -` "toggleconsole" -Mouse1 "+Fire" +X "+Alt_Fire" Mouse2 "+Alt_Fire" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/blood/demolition/leftbinds.txt b/wadsrc/static/filter/blood/demolition/leftbinds.txt index 17101dbe1..463332ea4 100644 --- a/wadsrc/static/filter/blood/demolition/leftbinds.txt +++ b/wadsrc/static/filter/blood/demolition/leftbinds.txt @@ -1,72 +1,8 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -Backspace "+Turn_Around" -LAlt "+Strafe" -RAlt "+Strafe" -, "+Strafe_Left" -KP7 "+Strafe_Left" -. "+Strafe_Right" -KP9 "+Strafe_Right" -A "+Jump" -KP- "+Jump" -Z "+Crouch" -LShift "+Run" -RShift "+Run" -Capslock "+AutoRun" -Space "+Open" -LCtrl "+Fire" -RCtrl "+Fire" -X "+Alt_Fire" -Home "+Aim_Up" -End "+Aim_Down" -PgUp "+Look_Up" -PgDn "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" -Tab "+Map" -F "+Map_Follow_Mode" -- "+Shrink_Screen" -= "+Enlarge_Screen" -T "+Send_Message" -K "+See_Coop_View" -F7 "+Third_Person_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -' "+Next_Weapon" -; "+Previous_Weapon" +// Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" B "+BeastVision" C "+CrystalBall" -J "+JetPack" -M "+MedKit" P "+ProximityBombs" R "+RemoteBombs" -` "toggleconsole" -Mouse1 "+Fire" -Mouse2 "+Open" -Mouse3 "+Run" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" +X "+Alt_Fire" diff --git a/wadsrc/static/filter/blood/demolition/origbinds.txt b/wadsrc/static/filter/blood/demolition/origbinds.txt index 192221292..5fe54e583 100644 --- a/wadsrc/static/filter/blood/demolition/origbinds.txt +++ b/wadsrc/static/filter/blood/demolition/origbinds.txt @@ -1,67 +1,6 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -Backspace "+Turn_Around" -LAlt "+Strafe" -RAlt "+Strafe" -, "+Strafe_Left" -. "+Strafe_Right" -A "+Jump" -/ "+Jump" -Z "+Crouch" -LShift "+Run" -RShift "+Run" -Capslock "+AutoRun" -Space "+Open" -LCtrl "+Fire" -RCtrl "+Fire" -X "+Alt_Fire" -Home "+Aim_Up" -KP7 "+Aim_Up" -End "+Aim_Down" -KP1 "+Aim_Down" -KP5 "+Center_View" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" -Tab "+Map" -F "+Map_Follow_Mode" -- "+Shrink_Screen" -KP- "+Shrink_Screen" -= "+Enlarge_Screen" -KP+ "+Enlarge_Screen" -T "+Send_Message" -K "+See_Coop_View" -F7 "+Third_Person_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -' "+Next_Weapon" -; "+Previous_Weapon" +// Scroll "+Holster_Weapon" +X "+Alt_Fire" W "+Show_Opponents_Weapon" B "+BeastVision" C "+CrystalBall" @@ -69,8 +8,4 @@ J "+JetPack" M "+MedKit" P "+ProximityBombs" R "+RemoteBombs" -` "toggleconsole" -Mouse1 "+Fire" Mouse2 "+Alt_Fire" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/duke/demolition/defbinds.txt b/wadsrc/static/filter/duke/demolition/defbinds.txt index 07c52db2b..c92a8f972 100644 --- a/wadsrc/static/filter/duke/demolition/defbinds.txt +++ b/wadsrc/static/filter/duke/demolition/defbinds.txt @@ -1,74 +1,12 @@ -W "+Move_Forward" -KP8 "+Move_Forward" -S "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -RCtrl "+Fire" -E "+Open" -LShift "+Run" -RShift "+Run" -Space "+Jump" -/ "+Jump" -LCtrl "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -A "+Strafe_Left" -D "+Strafe_Right" -Home "+Aim_Up" -KP7 "+Aim_Up" -End "+Aim_Down" -KP1 "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" +// +R "+Steroids" +Q "+Quick_Kick" H "+Holo_Duke" J "+Jetpack" N "+NightVision" M "+MedKit" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -KP- "+Shrink_Screen" -= "+Enlarge_Screen" -KP+ "+Enlarge_Screen" -KP5 "+Center_View" Scroll "+Holster_Weapon" -Y "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -R "+Steroids" -Q "+Quick_Kick" -' "+Next_Weapon" -; "+Previous_Weapon" -` "toggleconsole" -Capslock "+AutoRun" X "+Last_Used_Weapon" C "+Toggle_Crouch" -Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/duke/demolition/leftbinds.txt b/wadsrc/static/filter/duke/demolition/leftbinds.txt index 8d08af393..85e0ad3fc 100644 --- a/wadsrc/static/filter/duke/demolition/leftbinds.txt +++ b/wadsrc/static/filter/duke/demolition/leftbinds.txt @@ -1,68 +1,8 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -LCtrl "+Fire" -RCtrl "+Fire" -Space "+Open" -LShift "+Run" -RShift "+Run" -A "+Jump" -KP- "+Jump" -Z "+Crouch" -PgUp "+Look_Up" -PgDn "+Look_Down" -Ins "+Look_Left" -Del "+Look_Right" -, "+Strafe_Left" -KP7 "+Strafe_Left" -. "+Strafe_Right" -KP9 "+Strafe_Right" -Home "+Aim_Up" -End "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" H "+Holo_Duke" +R "+Steroids" +Q "+Quick_Kick" J "+Jetpack" N "+NightVision" M "+MedKit" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -= "+Enlarge_Screen" Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -R "+Steroids" -Q "+Quick_Kick" -' "+Next_Weapon" -; "+Previous_Weapon" -` "toggleconsole" -Capslock "+AutoRun" -Mouse1 "+Fire" -Mouse2 "+Open" -Mouse3 "+Run" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/duke/demolition/origbinds.txt b/wadsrc/static/filter/duke/demolition/origbinds.txt index 3cd17cb62..795737df9 100644 --- a/wadsrc/static/filter/duke/demolition/origbinds.txt +++ b/wadsrc/static/filter/duke/demolition/origbinds.txt @@ -1,75 +1,14 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -LCtrl "+Fire" -RCtrl "+Fire" -Space "+Open" -LShift "+Run" -RShift "+Run" -A "+Jump" -/ "+Jump" -Z "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -, "+Strafe_Left" -. "+Strafe_Right" -Home "+Aim_Up" -KP7 "+Aim_Up" -End "+Aim_Down" -KP1 "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" +// +R "+Steroids" +` "+Quick_Kick" +Scroll "+Holster_Weapon" +W "+Show_Opponents_Weapon" H "+Holo_Duke" J "+Jetpack" N "+NightVision" M "+MedKit" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -KP- "+Shrink_Screen" -= "+Enlarge_Screen" -KP+ "+Enlarge_Screen" -KP5 "+Center_View" -Scroll "+Holster_Weapon" -W "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -R "+Steroids" -` "+Quick_Kick" -' "+Next_Weapon" -; "+Previous_Weapon" C "toggleconsole" -Capslock "+AutoRun" -Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" + + \ No newline at end of file diff --git a/wadsrc/static/filter/ionfury/demolition/defbinds.txt b/wadsrc/static/filter/ionfury/demolition/defbinds.txt index f65bbcbfb..760257501 100644 --- a/wadsrc/static/filter/ionfury/demolition/defbinds.txt +++ b/wadsrc/static/filter/ionfury/demolition/defbinds.txt @@ -1,68 +1,6 @@ -W "+Move_Forward" -KP8 "+Move_Forward" -S "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -RCtrl "+Fire" -E "+Open" -LShift "+Run" -RShift "+Run" -Space "+Jump" -/ "+Jump" -LCtrl "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -A "+Strafe_Left" -D "+Strafe_Right" -Home "+Aim_Up" -KP7 "+Aim_Up" -End "+Aim_Down" -KP1 "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -KP- "+Shrink_Screen" -= "+Enlarge_Screen" -KP+ "+Enlarge_Screen" -KP5 "+Center_View" +// Scroll "+Holster_Weapon" -Y "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -' "+Next_Weapon" -; "+Previous_Weapon" -` "toggleconsole" -Capslock "+AutoRun" X "+Last_Used_Weapon" C "+Toggle_Crouch" -Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/ionfury/demolition/leftbinds.txt b/wadsrc/static/filter/ionfury/demolition/leftbinds.txt index 39d507542..529143e4b 100644 --- a/wadsrc/static/filter/ionfury/demolition/leftbinds.txt +++ b/wadsrc/static/filter/ionfury/demolition/leftbinds.txt @@ -1,66 +1,2 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -LCtrl "+Fire" -RCtrl "+Fire" -Space "+Open" -LShift "+Run" -RShift "+Run" -A "+Jump" -KP- "+Jump" -Z "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -, "+Strafe_Left" -KP7 "+Strafe_Left" -. "+Strafe_Right" -KP9 "+Strafe_Right" -Home "+Aim_Up" -End "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -= "+Enlarge_Screen" Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -' "+Next_Weapon" -; "+Previous_Weapon" -` "toggleconsole" -Capslock "+AutoRun" -Mouse1 "+Fire" -Mouse2 "+Open" -Mouse3 "+Run" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/ionfury/demolition/origbinds.txt b/wadsrc/static/filter/ionfury/demolition/origbinds.txt index a2162df89..e46a2a16e 100644 --- a/wadsrc/static/filter/ionfury/demolition/origbinds.txt +++ b/wadsrc/static/filter/ionfury/demolition/origbinds.txt @@ -1,69 +1,4 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -LCtrl "+Fire" -RCtrl "+Fire" -Space "+Open" -LShift "+Run" -RShift "+Run" -A "+Jump" -/ "+Jump" -Z "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -, "+Strafe_Left" -. "+Strafe_Right" -Home "+Aim_Up" -KP7 "+Aim_Up" -End "+Aim_Down" -KP1 "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -KP- "+Shrink_Screen" -= "+Enlarge_Screen" -KP+ "+Enlarge_Screen" -KP5 "+Center_View" Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -' "+Next_Weapon" -; "+Previous_Weapon" -C "toggleconsole" -Capslock "+AutoRun" -Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/nam/demolition/defbinds.txt b/wadsrc/static/filter/nam/demolition/defbinds.txt index 07c52db2b..c92a8f972 100644 --- a/wadsrc/static/filter/nam/demolition/defbinds.txt +++ b/wadsrc/static/filter/nam/demolition/defbinds.txt @@ -1,74 +1,12 @@ -W "+Move_Forward" -KP8 "+Move_Forward" -S "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -RCtrl "+Fire" -E "+Open" -LShift "+Run" -RShift "+Run" -Space "+Jump" -/ "+Jump" -LCtrl "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -A "+Strafe_Left" -D "+Strafe_Right" -Home "+Aim_Up" -KP7 "+Aim_Up" -End "+Aim_Down" -KP1 "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" +// +R "+Steroids" +Q "+Quick_Kick" H "+Holo_Duke" J "+Jetpack" N "+NightVision" M "+MedKit" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -KP- "+Shrink_Screen" -= "+Enlarge_Screen" -KP+ "+Enlarge_Screen" -KP5 "+Center_View" Scroll "+Holster_Weapon" -Y "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -R "+Steroids" -Q "+Quick_Kick" -' "+Next_Weapon" -; "+Previous_Weapon" -` "toggleconsole" -Capslock "+AutoRun" X "+Last_Used_Weapon" C "+Toggle_Crouch" -Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/nam/demolition/leftbinds.txt b/wadsrc/static/filter/nam/demolition/leftbinds.txt index ae728a200..85e0ad3fc 100644 --- a/wadsrc/static/filter/nam/demolition/leftbinds.txt +++ b/wadsrc/static/filter/nam/demolition/leftbinds.txt @@ -1,72 +1,8 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -LCtrl "+Fire" -RCtrl "+Fire" -Space "+Open" -LShift "+Run" -RShift "+Run" -A "+Jump" -KP- "+Jump" -Z "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -, "+Strafe_Left" -KP7 "+Strafe_Left" -. "+Strafe_Right" -KP9 "+Strafe_Right" -Home "+Aim_Up" -End "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" H "+Holo_Duke" +R "+Steroids" +Q "+Quick_Kick" J "+Jetpack" N "+NightVision" M "+MedKit" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -= "+Enlarge_Screen" Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -R "+Steroids" -Q "+Quick_Kick" -' "+Next_Weapon" -; "+Previous_Weapon" -` "toggleconsole" -Capslock "+AutoRun" -Mouse1 "+Fire" -Mouse2 "+Open" -Mouse3 "+Run" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/nam/demolition/origbinds.txt b/wadsrc/static/filter/nam/demolition/origbinds.txt index 3cd17cb62..c97488acd 100644 --- a/wadsrc/static/filter/nam/demolition/origbinds.txt +++ b/wadsrc/static/filter/nam/demolition/origbinds.txt @@ -1,75 +1,12 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -LCtrl "+Fire" -RCtrl "+Fire" -Space "+Open" -LShift "+Run" -RShift "+Run" -A "+Jump" -/ "+Jump" -Z "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -, "+Strafe_Left" -. "+Strafe_Right" -Home "+Aim_Up" -KP7 "+Aim_Up" -End "+Aim_Down" -KP1 "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" +// +R "+Steroids" +` "+Quick_Kick" +Scroll "+Holster_Weapon" +W "+Show_Opponents_Weapon" H "+Holo_Duke" J "+Jetpack" N "+NightVision" M "+MedKit" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -KP- "+Shrink_Screen" -= "+Enlarge_Screen" -KP+ "+Enlarge_Screen" -KP5 "+Center_View" -Scroll "+Holster_Weapon" -W "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -R "+Steroids" -` "+Quick_Kick" -' "+Next_Weapon" -; "+Previous_Weapon" C "toggleconsole" -Capslock "+AutoRun" -Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/redneck/demolition/defbinds.txt b/wadsrc/static/filter/redneck/demolition/defbinds.txt index 092a05cf9..a322d4009 100644 --- a/wadsrc/static/filter/redneck/demolition/defbinds.txt +++ b/wadsrc/static/filter/redneck/demolition/defbinds.txt @@ -1,74 +1,13 @@ -W "+Move_Forward" -KP8 "+Move_Forward" -S "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -RCtrl "+Fire" -E "+Open" -LShift "+Run" -RShift "+Run" -Capslock "+AutoRun" -Space "+Jump" -/ "+Jump" -LCtrl "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -A "+Strafe_Left" -D "+Strafe_Right" -Home "+Aim_Up" -KP7 "+Aim_Up" -End "+Aim_Down" -KP1 "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" +// +Scroll "+Holster_Weapon" +E "+Show_Opponents_Weapon" B "+Holo_Duke" C "+Jetpack" Y "+NightVision" R "+MedKit" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -KP- "+Shrink_Screen" -= "+Enlarge_Screen" -KP+ "+Enlarge_Screen" -KP5 "+Center_View" -Scroll "+Holster_Weapon" -E "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" ++ "+Dpad_Select" M "+Steroids" Q "+Quick_Kick" -' "+Next_Weapon" -; "+Previous_Weapon" -` "toggleconsole" -+ "+Dpad_Select" X "+Last_Used_Weapon" -Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/redneck/demolition/leftbinds.txt b/wadsrc/static/filter/redneck/demolition/leftbinds.txt index d7def8ae0..2f58d2cb6 100644 --- a/wadsrc/static/filter/redneck/demolition/leftbinds.txt +++ b/wadsrc/static/filter/redneck/demolition/leftbinds.txt @@ -1,71 +1,8 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -LCtrl "+Fire" -RCtrl "+Fire" -LCtrl "+Fire" -RCtrl "+Fire" -LShift "+Run" -RShift "+Run" -Capslock "+AutoRun" -A "+Jump" -KP- "+Jump" -Z "+Crouch" -PgUp "+Look_Up" -PgDn "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -, "+Strafe_Left" -KP7 "+Strafe_Left" -. "+Strafe_Right" -KP9 "+Strafe_Right" -Home "+Aim_Up" -End "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" +Scroll "+Holster_Weapon" +E "+Show_Opponents_Weapon" +M "+Steroids" +Q "+Quick_Kick" B "+Holo_Duke" C "+Jetpack" Y "+NightVision" W "+MedKit" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -= "+Enlarge_Screen" -Scroll "+Holster_Weapon" -E "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -M "+Steroids" -Q "+Quick_Kick" -' "+Next_Weapon" -; "+Previous_Weapon" -` "toggleconsole" -Mouse1 "+Fire" -Mouse2 "+Open" -Mouse3 "+Run" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/redneck/demolition/origbinds.txt b/wadsrc/static/filter/redneck/demolition/origbinds.txt index 9144ec6a4..ba9d9f2e9 100644 --- a/wadsrc/static/filter/redneck/demolition/origbinds.txt +++ b/wadsrc/static/filter/redneck/demolition/origbinds.txt @@ -1,71 +1,9 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -LCtrl "+Fire" -RCtrl "+Fire" -LCtrl "+Fire" -RCtrl "+Fire" -LShift "+Run" -RShift "+Run" -Capslock "+AutoRun" -A "+Jump" -/ "+Jump" -Z "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -, "+Strafe_Left" -. "+Strafe_Right" -Home "+Aim_Up" -KP7 "+Aim_Up" -End "+Aim_Down" -KP1 "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" +V "toggleconsole" +Scroll "+Holster_Weapon" +E "+Show_Opponents_Weapon" +M "+Steroids" +` "+Quick_Kick" B "+Holo_Duke" C "+Jetpack" Y "+NightVision" W "+MedKit" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -KP- "+Shrink_Screen" -= "+Enlarge_Screen" -KP+ "+Enlarge_Screen" -KP5 "+Center_View" -Scroll "+Holster_Weapon" -E "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -M "+Steroids" -` "+Quick_Kick" -' "+Next_Weapon" -; "+Previous_Weapon" -V "toggleconsole" diff --git a/wadsrc/static/filter/shadowwarrior/demolition/defbinds.txt b/wadsrc/static/filter/shadowwarrior/demolition/defbinds.txt index e3d8597b0..50b79abaf 100644 --- a/wadsrc/static/filter/shadowwarrior/demolition/defbinds.txt +++ b/wadsrc/static/filter/shadowwarrior/demolition/defbinds.txt @@ -1,43 +1,10 @@ -W "+Move_Forward" -S "+Move_Backward" -E "+Open" -LShift "+Run" -Capslock "+AutoRun" -Space "+Jump" -LAlt "+Crouch" -A "+Strafe_Left" -D "+Strafe_Right" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" +// +I "+Toggle_Crosshair" +Mouse2 "+MediKit" +H "+Holster_Weapon" M "+MedKit" B "+Smoke_Bomb" N "+Nightvision" G "+Gas_Bomb" F "+Flash_Bomb" C "+Caltrops" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -= "+Enlarge_Screen" -H "+Holster_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -` "toggleconsole" -Mouse1 "+Fire" -Mouse2 "+MediKit" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/shadowwarrior/demolition/leftbinds.txt b/wadsrc/static/filter/shadowwarrior/demolition/leftbinds.txt index 9395911f3..a7122a63d 100644 --- a/wadsrc/static/filter/shadowwarrior/demolition/leftbinds.txt +++ b/wadsrc/static/filter/shadowwarrior/demolition/leftbinds.txt @@ -1,66 +1,7 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -LCtrl "+Fire" -RCtrl "+Fire" -LCtrl "+Fire" -RCtrl "+Fire" -LShift "+Run" -RShift "+Run" -Capslock "+AutoRun" -A "+Jump" -KP- "+Jump" -Z "+Crouch" -PgUp "+Look_Up" -PgDn "+Look_Down" -, "+Strafe_Left" -KP7 "+Strafe_Left" -. "+Strafe_Right" -KP9 "+Strafe_Right" -Home "+Aim_Up" -End "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" M "+MedKit" S "+Smoke_Bomb" N "+Nightvision" G "+Gas_Bomb" F "+Flash_Bomb" C "+Caltrops" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -= "+Enlarge_Screen" Scroll "+Holster_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -' "+Next_Weapon" -; "+Previous_Weapon" -` "toggleconsole" -Mouse1 "+Fire" -Mouse2 "+Open" -Mouse3 "+Run" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/shadowwarrior/demolition/origbinds.txt b/wadsrc/static/filter/shadowwarrior/demolition/origbinds.txt index b4c02a99e..677ef1342 100644 --- a/wadsrc/static/filter/shadowwarrior/demolition/origbinds.txt +++ b/wadsrc/static/filter/shadowwarrior/demolition/origbinds.txt @@ -1,70 +1,8 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -LCtrl "+Fire" -RCtrl "+Fire" -LCtrl "+Fire" -RCtrl "+Fire" -LShift "+Run" -RShift "+Run" -Capslock "+AutoRun" -A "+Jump" -/ "+Jump" -Z "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -, "+Strafe_Left" -. "+Strafe_Right" -Home "+Aim_Up" -KP7 "+Aim_Up" -End "+Aim_Down" -KP1 "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" M "+MedKit" S "+Smoke_Bomb" N "+Nightvision" G "+Gas_Bomb" F "+Flash_Bomb" C "+Caltrops" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -KP- "+Shrink_Screen" -= "+Enlarge_Screen" -KP+ "+Enlarge_Screen" -KP5 "+Center_View" -Scroll "+Holster_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -' "+Next_Weapon" -; "+Previous_Weapon" -` "toggleconsole" -Mouse1 "+Fire" Mouse2 "+MediKit" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" +Scroll "+Holster_Weapon" diff --git a/wadsrc/static/filter/ww2gi/demolition/defbinds.txt b/wadsrc/static/filter/ww2gi/demolition/defbinds.txt index 07c52db2b..c92a8f972 100644 --- a/wadsrc/static/filter/ww2gi/demolition/defbinds.txt +++ b/wadsrc/static/filter/ww2gi/demolition/defbinds.txt @@ -1,74 +1,12 @@ -W "+Move_Forward" -KP8 "+Move_Forward" -S "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -RCtrl "+Fire" -E "+Open" -LShift "+Run" -RShift "+Run" -Space "+Jump" -/ "+Jump" -LCtrl "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -A "+Strafe_Left" -D "+Strafe_Right" -Home "+Aim_Up" -KP7 "+Aim_Up" -End "+Aim_Down" -KP1 "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" +// +R "+Steroids" +Q "+Quick_Kick" H "+Holo_Duke" J "+Jetpack" N "+NightVision" M "+MedKit" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -KP- "+Shrink_Screen" -= "+Enlarge_Screen" -KP+ "+Enlarge_Screen" -KP5 "+Center_View" Scroll "+Holster_Weapon" -Y "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -R "+Steroids" -Q "+Quick_Kick" -' "+Next_Weapon" -; "+Previous_Weapon" -` "toggleconsole" -Capslock "+AutoRun" X "+Last_Used_Weapon" C "+Toggle_Crouch" -Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/ww2gi/demolition/leftbinds.txt b/wadsrc/static/filter/ww2gi/demolition/leftbinds.txt index 957df7637..85e0ad3fc 100644 --- a/wadsrc/static/filter/ww2gi/demolition/leftbinds.txt +++ b/wadsrc/static/filter/ww2gi/demolition/leftbinds.txt @@ -1,73 +1,8 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -LCtrl "+Fire" -RCtrl "+Fire" -LCtrl "+Fire" -RCtrl "+Fire" -LShift "+Run" -RShift "+Run" -A "+Jump" -KP- "+Jump" -Z "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -, "+Strafe_Left" -KP7 "+Strafe_Left" -. "+Strafe_Right" -KP9 "+Strafe_Right" -Home "+Aim_Up" -End "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" H "+Holo_Duke" +R "+Steroids" +Q "+Quick_Kick" J "+Jetpack" N "+NightVision" M "+MedKit" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -= "+Enlarge_Screen" Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -R "+Steroids" -Q "+Quick_Kick" -' "+Next_Weapon" -; "+Previous_Weapon" -` "toggleconsole" -Capslock "+AutoRun" -Mouse1 "+Fire" -Mouse2 "+Open" -Mouse3 "+Run" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" diff --git a/wadsrc/static/filter/ww2gi/demolition/origbinds.txt b/wadsrc/static/filter/ww2gi/demolition/origbinds.txt index 44d4a1eaa..c97488acd 100644 --- a/wadsrc/static/filter/ww2gi/demolition/origbinds.txt +++ b/wadsrc/static/filter/ww2gi/demolition/origbinds.txt @@ -1,76 +1,12 @@ -uparrow "+Move_Forward" -KP8 "+Move_Forward" -downarrow "+Move_Backward" -KP2 "+Move_Backward" -leftarrow "+Turn_Left" -KP4 "+Turn_Left" -rightarrow "+Turn_Right" -KP6 "+Turn_Right" -LAlt "+Strafe" -RAlt "+Strafe" -LCtrl "+Fire" -RCtrl "+Fire" -LCtrl "+Fire" -RCtrl "+Fire" -LShift "+Run" -RShift "+Run" -A "+Jump" -/ "+Jump" -Z "+Crouch" -PgUp "+Look_Up" -KP9 "+Look_Up" -PgDn "+Look_Down" -KP3 "+Look_Down" -Ins "+Look_Left" -KP0 "+Look_Left" -Del "+Look_Right" -KP. "+Look_Right" -, "+Strafe_Left" -. "+Strafe_Right" -Home "+Aim_Up" -KP7 "+Aim_Up" -End "+Aim_Down" -KP1 "+Aim_Down" -1 "+Weapon_1" -2 "+Weapon_2" -3 "+Weapon_3" -4 "+Weapon_4" -5 "+Weapon_5" -6 "+Weapon_6" -7 "+Weapon_7" -8 "+Weapon_8" -9 "+Weapon_9" -0 "+Weapon_10" -Enter "+Inventory" -KP-Enter "+Inventory" -[ "+Inventory_Left" -] "+Inventory_Right" +// +R "+Steroids" +` "+Quick_Kick" +Scroll "+Holster_Weapon" +W "+Show_Opponents_Weapon" H "+Holo_Duke" J "+Jetpack" N "+NightVision" M "+MedKit" -Backspace "+Turn_Around" -T "+Send_Message" -Tab "+Map" -- "+Shrink_Screen" -KP- "+Shrink_Screen" -= "+Enlarge_Screen" -KP+ "+Enlarge_Screen" -KP5 "+Center_View" -Scroll "+Holster_Weapon" -W "+Show_Opponents_Weapon" -F "+Map_Follow_Mode" -K "+See_Coop_View" -U "+Mouse_Aiming" -I "+Toggle_Crosshair" -R "+Steroids" -` "+Quick_Kick" -' "+Next_Weapon" -; "+Previous_Weapon" C "toggleconsole" -Capslock "+AutoRun" -Mouse1 "+Fire" Mouse2 "+Jetpack" Mouse3 "+MediKit" -MWheelUp "+Previous_Weapon" -MWheelDown "+Next_Weapon" From a5a0c384746536af5dc95861e584acbf986b348f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 26 Nov 2019 21:25:45 +0100 Subject: [PATCH 025/203] - removed DObject. Just for the menu this can be done much simpler - the entire setup here doesn't work well with the game frontends being compiled as separate modules anyway. --- source/CMakeLists.txt | 10 +- source/common/dobject/__autostart.cpp | 75 ----------- source/common/dobject/autosegs.h | 102 --------------- source/common/dobject/dobject.cpp | 76 ----------- source/common/dobject/dobject.h | 182 -------------------------- source/common/dobject/dobjtype.cpp | 106 --------------- source/common/dobject/dobjtype.h | 50 ------- source/common/dobject/zzautozend.cpp | 54 -------- 8 files changed, 1 insertion(+), 654 deletions(-) delete mode 100644 source/common/dobject/__autostart.cpp delete mode 100644 source/common/dobject/autosegs.h delete mode 100644 source/common/dobject/dobject.cpp delete mode 100644 source/common/dobject/dobject.h delete mode 100644 source/common/dobject/dobjtype.cpp delete mode 100644 source/common/dobject/dobjtype.h delete mode 100644 source/common/dobject/zzautozend.cpp diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 1e743e758..8ae283e2c 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -623,7 +623,6 @@ file( GLOB HEADER_FILES common/console/*.h common/filesystem/*.h common/music/*.h - common/dobject/*.h common/menu/*.h build/src/*.h @@ -666,8 +665,7 @@ set( FASTMATH_SOURCES set (PCH_SOURCES - common/dobject/__autostart.cpp # must be first - + audiolib/src/drivers.cpp audiolib/src/driver_adlib.cpp audiolib/src/driver_nosound.cpp @@ -829,10 +827,6 @@ set (PCH_SOURCES common/music/backend/oalsound.cpp common/music/backend/i_sound.cpp - - common/dobject/dobject.cpp - common/dobject/dobjtype.cpp - common/menu/joystickmenu.cpp common/menu/listmenu.cpp common/menu/loadsavemenu.cpp @@ -842,8 +836,6 @@ set (PCH_SOURCES common/menu/messagebox.cpp common/menu/optionmenu.cpp common/menu/readthis.cpp - - common/dobject/zzautozend.cpp #must be last ) if( MSVC ) diff --git a/source/common/dobject/__autostart.cpp b/source/common/dobject/__autostart.cpp deleted file mode 100644 index 635bf5b67..000000000 --- a/source/common/dobject/__autostart.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* -** autostart.cpp -** This file contains the heads of lists stored in special data segments -** -**--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -** The particular scheme used here was chosen because it's small. -** -** An alternative that will work with any C++ compiler is to use static -** classes to build these lists at run time. Under Visual C++, doing things -** that way can require a lot of extra space, which is why I'm doing things -** this way. -** -** In the case of PClass lists (section creg), I orginally used the -** constructor to do just that, and the code for that still exists if you -** compile with something other than Visual C++ or GCC. -*/ - -#include "autosegs.h" - -#if defined(_MSC_VER) - -// The various reg sections are used to group pointers spread across multiple -// source files into cohesive arrays in the final executable. We don't -// actually care about these sections themselves and merge them all into -// a single section during the final link. (.rdata is the standard section -// for initialized read-only data.) - -#pragma comment(linker, "/merge:.creg=.rdata") - -#pragma section(".creg$a",read) -__declspec(allocate(".creg$a")) void *const CRegHead = 0; - -#elif defined(__GNUC__) - -#include "doomtype.h" - -// I don't know of an easy way to merge sections together with the GNU linker, -// so GCC users will see all of these sections appear in the final executable. -// (There are linker scripts, but that apparently involves extracting the -// default script from ld and then modifying it.) - -void *const CRegHead __attribute__((section(SECTION_CREG))) = 0; - -#else - -#error Please fix autostart.cpp for your compiler - -#endif diff --git a/source/common/dobject/autosegs.h b/source/common/dobject/autosegs.h deleted file mode 100644 index 1884d9d54..000000000 --- a/source/common/dobject/autosegs.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -** autosegs.h -** Arrays built at link-time -** -**--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#ifndef AUTOSEGS_H -#define AUTOSEGS_H - -#define REGMARKER(x) (x) -typedef void * const REGINFO; - -// List of Action functons -extern REGINFO ARegHead; -extern REGINFO ARegTail; - -// List of TypeInfos -extern REGINFO CRegHead; -extern REGINFO CRegTail; - -// List of properties -extern REGINFO GRegHead; -extern REGINFO GRegTail; - -// List of variables -extern REGINFO MRegHead; -extern REGINFO MRegTail; - -// List of MAPINFO map options -extern REGINFO YRegHead; -extern REGINFO YRegTail; - -class FAutoSegIterator -{ - public: - FAutoSegIterator(REGINFO &head, REGINFO &tail) - { - // Weirdness. Mingw's linker puts these together backwards. - if (&head <= &tail) - { - Head = &head; - Tail = &tail; - } - else - { - Head = &tail; - Tail = &head; - } - Probe = Head; - } - REGINFO operator*() const - { - return *Probe; - } - FAutoSegIterator &operator++() - { - do - { - ++Probe; - } while (*Probe == 0 && Probe < Tail); - return *this; - } - void Reset() - { - Probe = Head; - } - - protected: - REGINFO *Probe; - REGINFO *Head; - REGINFO *Tail; -}; - -#endif diff --git a/source/common/dobject/dobject.cpp b/source/common/dobject/dobject.cpp deleted file mode 100644 index 98b8105fe..000000000 --- a/source/common/dobject/dobject.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* -** dobject.cpp -** Implements the base class DObject, which most other classes derive from -** -**--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#include -#include - -#include "dobject.h" - -#if 0 - -PClass DObject::_StaticType; -ClassReg DObject::RegistrationInfo = -{ - &DObject::_StaticType, // MyClass - "DObject", // Name - NULL, // ParentType - sizeof(DObject), // SizeOf - NULL, // Pointers - &DObject::InPlaceConstructor // ConstructNative -}; -_DECLARE_TI(DObject) - -void DObject::InPlaceConstructor (void *mem) -{ - new ((EInPlace *)mem) DObject; -} - -DObject::DObject () -: Class(0) -{ -} - -DObject::DObject (PClass *inClass) -: Class(inClass) -{ -} - -DObject::~DObject () -{ -} - -void DObject::Destroy () -{ -} -#endif \ No newline at end of file diff --git a/source/common/dobject/dobject.h b/source/common/dobject/dobject.h deleted file mode 100644 index 502f3c35b..000000000 --- a/source/common/dobject/dobject.h +++ /dev/null @@ -1,182 +0,0 @@ -/* -** dobject.h -** -**--------------------------------------------------------------------------- -** Copyright 1998-2008 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#ifndef __DOBJECT_H__ -#define __DOBJECT_H__ - -#if 0 - -#include - -struct PClass; - -#define RUNTIME_TYPE(object) (object->GetClass()) // Passed an object, returns the type of that object -#define RUNTIME_CLASS(cls) (&cls::_StaticType) // Passed a class name, returns a PClass representing that class -#define NATIVE_TYPE(object) (object->StaticType()) // Passed an object, returns the type of the C++ class representing the object - -struct ClassReg -{ - PClass *MyClass; - const char *Name; - PClass *ParentType; - unsigned int SizeOf; - const size_t *Pointers; - void (*ConstructNative)(void *); - - void RegisterClass() const; -}; - -enum EInPlace { EC_InPlace }; - -#define DECLARE_ABSTRACT_CLASS(cls,parent) \ -public: \ - static PClass _StaticType; \ - virtual PClass *StaticType() const { return &_StaticType; } \ - static ClassReg RegistrationInfo, *RegistrationInfoPtr; \ -private: \ - typedef parent Super; \ - typedef cls ThisClass; - -#define DECLARE_CLASS(cls,parent) \ - DECLARE_ABSTRACT_CLASS(cls,parent) \ - private: static void InPlaceConstructor (void *mem); - -#if defined(_MSC_VER) -# pragma data_seg(".creg$u") -# pragma data_seg() -# define _DECLARE_TI(cls) __declspec(allocate(".creg$u")) ClassReg *cls::RegistrationInfoPtr = &cls::RegistrationInfo; -#else -# define _DECLARE_TI(cls) ClassReg *cls::RegistrationInfoPtr __attribute__((section(SECTION_CREG))) = &cls::RegistrationInfo; -#endif - -#define _IMP_PCLASS(cls,ptrs,create) \ - PClass cls::_StaticType; \ - ClassReg cls::RegistrationInfo = {\ - RUNTIME_CLASS(cls), \ - #cls, \ - RUNTIME_CLASS(cls::Super), \ - sizeof(cls), \ - ptrs, \ - create }; \ - _DECLARE_TI(cls) - -#define _IMP_CREATE_OBJ(cls) \ - void cls::InPlaceConstructor(void *mem) { new((EInPlace *)mem) cls; } - -#define IMPLEMENT_CLASS(cls) \ - _IMP_CREATE_OBJ(cls) \ - _IMP_PCLASS(cls,NULL,cls::InPlaceConstructor) - -#define IMPLEMENT_ABSTRACT_CLASS(cls) \ - _IMP_PCLASS(cls,NULL,NULL) - - -class DObject -{ -public: - static PClass _StaticType; - virtual PClass *StaticType() const { return &_StaticType; } - static ClassReg RegistrationInfo, *RegistrationInfoPtr; - static void InPlaceConstructor (void *mem); -private: - typedef DObject ThisClass; - - // Per-instance variables. There are four. -private: - PClass *Class; // This object's type -public: - -public: - DObject (); - DObject (PClass *inClass); - virtual ~DObject(); - - inline bool IsKindOf (const PClass *base); - inline bool IsA (const PClass *type); - - virtual void Destroy (); - - PClass *GetClass() const - { - if (Class == NULL) - { - // Save a little time the next time somebody wants this object's type - // by recording it now. - const_cast(this)->Class = StaticType(); - } - return Class; - } - - void SetClass (PClass *inClass) - { - Class = inClass; - } - - void* operator new(size_t p) - { - return malloc(p); - } - - void operator delete (void* mem) - { - free(mem); - } - -protected: - // This form of placement new and delete is for use *only* by PClass's - // CreateNew() method. Do not use them for some other purpose. - void *operator new(size_t, EInPlace *mem) - { - return (void *)mem; - } - - void operator delete (void *mem, EInPlace *) - { - free (mem); - } -}; - -#include "dobjtype.h" - -inline bool DObject::IsKindOf (const PClass *base) -{ - return base->IsAncestorOf (GetClass ()); -} - -inline bool DObject::IsA (const PClass *type) -{ - return (type == GetClass()); -} - -#endif -#endif //__DOBJECT_H__ diff --git a/source/common/dobject/dobjtype.cpp b/source/common/dobject/dobjtype.cpp deleted file mode 100644 index 6f4d50485..000000000 --- a/source/common/dobject/dobjtype.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* -** dobjtype.cpp -** Implements the type information class -** -**--------------------------------------------------------------------------- -** Copyright 1998-2008 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#include -#include -#include "dobject.h" -#include "templates.h" -#include "autosegs.h" -#include "tarray.h" -#if 0 - -static TArray Types; -static TMap Map; - -static int cregcmp (const void *a, const void *b) -{ - // VC++ introduces NULLs in the sequence. GCC seems to work as expected and not do it. - const ClassReg *class1 = *(const ClassReg **)a; - const ClassReg *class2 = *(const ClassReg **)b; - if (class1 == NULL) return 1; - if (class2 == NULL) return -1; - return strcmp (class1->Name, class2->Name); -} - -void PClass::StaticInit () -{ - // Sort classes by name to remove dependance on how the compiler ordered them. - REGINFO *head = &CRegHead; - REGINFO *tail = &CRegTail; - - // MinGW's linker is linking the object files backwards for me now... - if (head > tail) - { - std::swap (head, tail); - } - qsort ((void*)(head + 1), tail - head - 1, sizeof(REGINFO), cregcmp); - - FAutoSegIterator probe(CRegHead, CRegTail); - - while (*++probe != NULL) - { - ((ClassReg *)*probe)->RegisterClass (); - } -} - -void ClassReg::RegisterClass () const -{ - assert (MyClass != NULL); - - // Add type to list - MyClass->TypeName = FName(Name+1); - MyClass->ParentClass = ParentType; - MyClass->Size = SizeOf; - MyClass->ConstructNative = ConstructNative; - Map.Insert(MyClass->TypeName, MyClass); -} - -// Find a type, passed the name as a name -const PClass *PClass::FindClass (FName zaname) -{ - auto pcls = Map.CheckKey(zaname); - return pcls? *pcls : nullptr; -} - -// Create a new object that this class represents -DObject *PClass::CreateNew () const -{ - uint8_t *mem = (uint8_t *)calloc (Size, 1); - assert (mem != NULL); - - ConstructNative (mem); - ((DObject *)mem)->SetClass (const_cast(this)); - return (DObject *)mem; -} -#endif \ No newline at end of file diff --git a/source/common/dobject/dobjtype.h b/source/common/dobject/dobjtype.h deleted file mode 100644 index 15c80fbb1..000000000 --- a/source/common/dobject/dobjtype.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef DOBJTYPE_H -#define DOBJTYPE_H - -#ifndef __DOBJECT_H__ -#error You must #include "dobject.h" to get dobjtype.h -#endif - -#include "name.h" - - -// Meta-info for every class derived from DObject --------------------------- - -struct PClass -{ - static void StaticInit (); - - // Per-class information ------------------------------------- - FName TypeName; // this class's name - unsigned int Size; // this class's size - PClass *ParentClass; // the class this class derives from - PClass *HashNext; - - void (*ConstructNative)(void *); - - // The rest are all functions and static data ---------------- - DObject *CreateNew () const; - - // Returns true if this type is an ancestor of (or same as) the passed type. - bool IsAncestorOf (const PClass *ti) const - { - while (ti) - { - if (this == ti) - return true; - ti = ti->ParentClass; - } - return false; - } - inline bool IsDescendantOf (const PClass *ti) const - { - return ti->IsAncestorOf (this); - } - - // Find a type, given its name. - static const PClass* FindClass(const char* name) { FName nm(name, true); return nm == NAME_None ? nullptr : FindClass(nm); } - static const PClass *FindClass (ENamedName name) { return FindClass (FName (name)); } - static const PClass *FindClass (FName name); -}; - -#endif diff --git a/source/common/dobject/zzautozend.cpp b/source/common/dobject/zzautozend.cpp deleted file mode 100644 index 70f1a77e9..000000000 --- a/source/common/dobject/zzautozend.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* -** autozend.cpp -** This file contains the tails of lists stored in special data segments -** -**--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -** See autostart.cpp for an explanation of why I do things like this. -*/ - -#include "autosegs.h" - -#if defined(_MSC_VER) - -#pragma section(".creg$z",read) -__declspec(allocate(".creg$z")) void *const CRegTail = 0; - - -#elif defined(__GNUC__) - -#include "doomtype.h" - -void *const CRegTail __attribute__((section(SECTION_CREG))) = 0; - -#else - -#error Please fix autozend.cpp for your compiler - -#endif From 248c2feba26a85edd53c2072758e317534d18b86 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 26 Nov 2019 21:26:01 +0100 Subject: [PATCH 026/203] - missed one binding definition file. --- wadsrc/static/demolition/origbinds.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 wadsrc/static/demolition/origbinds.txt diff --git a/wadsrc/static/demolition/origbinds.txt b/wadsrc/static/demolition/origbinds.txt new file mode 100644 index 000000000..7e1f14da0 --- /dev/null +++ b/wadsrc/static/demolition/origbinds.txt @@ -0,0 +1,22 @@ +uparrow "+Move_Forward" +downarrow "+Move_Backward" +LCtrl "+Fire" +RCtrl "+Fire" +Space "+Open" +A "+Jump" +/ "+Jump" +Z "+Crouch" +PgUp "+Look_Up" +KP9 "+Look_Up" +PgDn "+Look_Down" +KP3 "+Look_Down" +KP. "+Look_Right" +, "+Strafe_Left" +. "+Strafe_Right" +KP7 "+Aim_Up" +KP1 "+Aim_Down" +KP5 "+Center_View" +KP- "+Shrink_Screen" +KP+ "+Enlarge_Screen" +U "+Mouse_Aiming" +I "+Toggle_Crosshair" From 46d1f8517a13634cb8856d720f3172ff12671fac Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 26 Nov 2019 22:05:52 +0100 Subject: [PATCH 027/203] - animated transitions are working. --- source/common/menu/listmenu.cpp | 1 + source/common/menu/menu.cpp | 12 ++++++----- source/common/menu/menu.h | 5 +++-- source/common/menu/menudef.cpp | 4 ++++ wadsrc/static/demolition/menudef.txt | 31 +++++++++++++++++++++++++++- 5 files changed, 45 insertions(+), 8 deletions(-) diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 86ceb66d4..bff609e2e 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -64,6 +64,7 @@ void DListMenu::Init(DMenu *parent, FListMenuDescriptor *desc) { mParentMenu = parent; mDesc = desc; + canAnimate = !!(mDesc->mFlags & LMF_Animate); if (mDesc->mScriptId >= 0) scriptID = mDesc->mScriptId; #if 0 if (desc->mCenter) diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index ce5fab649..7e7b6d7d8 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -133,6 +133,7 @@ bool M_DrawTransition(MenuTransition &transition) transition.previous->origin.X = factor * transition.dir * (sin(phase) - 1.); transition.current->origin.X = factor * transition.dir * (sin(phase) + 1.); + Printf("prev.X = %2.5f, next.X = %2.5f\n", transition.previous->origin.X, transition.current->origin.X); transition.previous->Drawer(); transition.current->Drawer(); return true; @@ -763,6 +764,7 @@ void M_Ticker (void) if (DMenu::MenuTime & 3) return; if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) { + if (transition.previous) transition.previous->Ticker(); DMenu::CurrentMenu->Ticker(); for (int i = 0; i < NUM_MKEYS; ++i) @@ -804,18 +806,18 @@ void M_Drawer (void) { if (DMenu::CurrentMenu->DimAllowed() && fade && !DrawBackground) twod.AddColorOnlyQuad(0, 0, screen->GetWidth(), screen->GetHeight(), fade); - bool done = false; + bool going = false; if (transition.previous) { - done = M_DrawTransition(transition); - if (!done) + going = M_DrawTransition(transition); + if (!going) { - delete transition.previous; + if (transition.dir == -1) delete transition.previous; transition.previous = nullptr; transition.current = nullptr; } } - if (!done) + if (!going) { DMenu::CurrentMenu->origin = { 0,0 }; // else if (DrawBackground) Menu_DrawBackground(origin); diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index cbabae10c..b13dbe08f 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -167,7 +167,8 @@ class FOptionMenuItem; enum ListMenuFlags { LMF_Centered = 1, - LMF_DontSpace = 2 + LMF_DontSpace = 2, + LMF_Animate = 4, }; struct FListMenuDescriptor : public FMenuDescriptor @@ -318,7 +319,7 @@ public: static int MenuTime; DMenu *mParentMenu; - DVector2 origin; + DVector2 origin = { 0,0 }; int scriptID = INT_MAX; bool canAnimate = false; diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 49920aef3..c1ba3ea16 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -284,6 +284,10 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) { desc->mFlags |= LMF_Centered; } + else if (sc.Compare("animatedtransition")) + { + desc->mFlags |= LMF_Animate; + } else if (sc.Compare("Fixedspacing")) { sc.MustGetNumber(); diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 0fa8099b0..b9b0a345b 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -18,6 +18,7 @@ LISTMENU "MainMenu" { position 160, 55, 115 centermenu + animatedtransition } class "Duke.MainMenu" NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" @@ -81,6 +82,7 @@ LISTMENU "IngameMenu" { position 160, 55, 115 centermenu + animatedtransition } linespacing 15 class "Duke.MainMenu" @@ -134,6 +136,7 @@ LISTMENU "EpisodeMenu" position 160, 48, 142 centermenu fixedspacing 5 + animatedtransition class "Duke.ListMenu" } @@ -149,17 +152,20 @@ LISTMENU "SkillMenu" centermenu fixedspacing 5 class "Duke.ListMenu" + animatedtransition } - ScriptId 110 } +// The custom menus are only supported by the EDuke32 frontend. LISTMENU "CustomGameMenu" { position 160, 48, 142 centermenu fixedspacing 5 ScriptId 102 + class "Duke.ListMenu" + animatedtransition } LISTMENU "CustomSubMenu1" @@ -168,6 +174,8 @@ LISTMENU "CustomSubMenu1" centermenu fixedspacing 5 ScriptId 103 + class "Duke.ListMenu" + animatedtransition } LISTMENU "CustomSubMenu2" @@ -176,6 +184,8 @@ LISTMENU "CustomSubMenu2" centermenu fixedspacing 5 ScriptId 103 + class "Duke.ListMenu" + animatedtransition } LISTMENU "CustomSubMenu3" @@ -184,6 +194,8 @@ LISTMENU "CustomSubMenu3" centermenu fixedspacing 5 ScriptId 103 + class "Duke.ListMenu" + animatedtransition } LISTMENU "CustomSubMenu4" @@ -192,6 +204,8 @@ LISTMENU "CustomSubMenu4" centermenu fixedspacing 5 ScriptId 103 + class "Duke.ListMenu" + animatedtransition } LISTMENU "CustomSubMenu5" @@ -200,6 +214,8 @@ LISTMENU "CustomSubMenu5" centermenu fixedspacing 5 ScriptId 103 + class "Duke.ListMenu" + animatedtransition } LISTMENU "CustomSubMenu6" @@ -208,6 +224,8 @@ LISTMENU "CustomSubMenu6" centermenu fixedspacing 5 ScriptId 103 + class "Duke.ListMenu" + animatedtransition } LISTMENU "CustomSubMenu7" @@ -216,10 +234,21 @@ LISTMENU "CustomSubMenu7" centermenu fixedspacing 5 ScriptId 103 + class "Duke.ListMenu" + animatedtransition } LISTMENU "MultiMenu" { + ifgame(Duke, Nam, WW2GI, Fury) // Ion Fury does not use this menu. + { + position 160, 55, 135 + centermenu + fixedspacing 5 + class "Duke.ListMenu" + animatedtransition + } + Caption "$MNU_NETWORKGAME" NativeTextItem "$MNU_PLAYERSETUP", "p", "PlayerSetupMenu" NativeTextItem "$MNU_JOINGAME", "j", "JoinGameMenu" From 3b7aa74c27531adb205014c5d1f47e53f65067bf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 26 Nov 2019 23:20:54 +0100 Subject: [PATCH 028/203] - connecting the dots in the menu. Duke Nukem can now start a level. --- source/build/include/baselayer.h | 21 +- source/common/menu/listmenu.cpp | 10 +- source/common/menu/menu.cpp | 13 +- source/common/menu/menu.h | 10 +- source/common/menu/menudef.cpp | 2 +- source/duke3d/src/d_menu.cpp | 61 +++++- source/duke3d/src/duke3d.h | 6 +- source/duke3d/src/gamestructures.cpp | 4 +- source/duke3d/src/menus.cpp | 297 +-------------------------- 9 files changed, 95 insertions(+), 329 deletions(-) diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 36c406492..4bc2bac9f 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -168,8 +168,23 @@ struct GameStats int timesecnd; }; +struct FGameStartup +{ + int Episode; + int Level; + int Skill; + int CustomLevel1; + int CustomLevel2; +}; + struct GameInterface { + enum EMenuSounds + { + SelectSound, + ChooseSound + }; + virtual ~GameInterface() {} virtual void faketimerhandler() {} // This is a remnant of older versions, but Blood backend has not updated yet. virtual int app_main() = 0; @@ -182,9 +197,11 @@ struct GameInterface virtual void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int flags) {} virtual void MainMenuOpened() {} virtual void MenuOpened() {} - virtual void MenuSelectSound() {} - virtual void MenuChooseSound() {} + virtual void MenuClosed() {} + virtual void MenuSound(EMenuSounds snd) {} virtual bool CanSave() { return true; } + virtual void CustomMenuSelection(int menu, int item) {} + virtual void StartGame(FGameStartup& gs) {} }; extern GameInterface* gi; diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index bff609e2e..9138a840a 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -130,7 +130,7 @@ bool DListMenu::Responder (event_t *ev) if (mDesc->mItems[i]->CheckHotkey(ch)) { mDesc->mSelectedItem = i; - gi->MenuSelectSound(); + gi->MenuSound(GameInterface::SelectSound); return true; } } @@ -139,7 +139,7 @@ bool DListMenu::Responder (event_t *ev) if (mDesc->mItems[i]->CheckHotkey(ch)) { mDesc->mSelectedItem = i; - gi->MenuSelectSound(); + gi->MenuSound(GameInterface::SelectSound); return true; } } @@ -166,7 +166,7 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller) if (--mDesc->mSelectedItem < 0) mDesc->mSelectedItem = mDesc->mItems.Size()-1; } while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); - gi->MenuSelectSound(); + gi->MenuSound(GameInterface::SelectSound); return true; case MKEY_Down: @@ -175,13 +175,13 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller) if (++mDesc->mSelectedItem >= (int)mDesc->mItems.Size()) mDesc->mSelectedItem = 0; } while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); - gi->MenuSelectSound(); + gi->MenuSound(GameInterface::SelectSound); return true; case MKEY_Enter: if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate(mDesc->mMenuName)) { - gi->MenuChooseSound(); + gi->MenuSound(GameInterface::ChooseSound); } return true; diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 7e7b6d7d8..c3823d631 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -437,20 +437,23 @@ bool M_SetMenu(FName menu, int param, FName caller) case NAME_EpisodeMenu: // sent from the episode menu GameStartupInfo.Episode = param; + GameStartupInfo.Level = 0; GameStartupInfo.CustomLevel1 = GameStartupInfo.CustomLevel2 = -1; GameStartupInfo.Skill = gDefaultSkill; break; case NAME_CustomGameMenu: GameStartupInfo.CustomLevel1 = param; - GameStartupInfo.Episode = GameStartupInfo.CustomLevel2 = -1; + GameStartupInfo.CustomLevel2 = -1; + GameStartupInfo.Episode = -1; + GameStartupInfo.Level = -1; GameStartupInfo.Skill = gDefaultSkill; - // gi->CustomMenuSelection(-1, param); + gi->CustomMenuSelection(param, -1); break; case NAME_CustomSubMenu1: GameStartupInfo.CustomLevel2 = param; - // gi->CustomMenuSelection(GameStartupInfo.CustomLevel1, param); + gi->CustomMenuSelection(GameStartupInfo.CustomLevel1, param); menu = FName(ENamedName(menu + param)); break; @@ -462,7 +465,8 @@ bool M_SetMenu(FName menu, int param, FName caller) switch (menu) { case NAME_StartGame: - // gi->StartGame(&GameStartupInfo); + M_ClearMenus(); // must be done before starting the level. + gi->StartGame(GameStartupInfo); return false; #if 0 @@ -844,6 +848,7 @@ void M_ClearMenus () } menuactive = MENU_Off; GUICapture &= ~1; + gi->MenuClosed(); } void Menu_Close(int playerid) diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index b13dbe08f..545de2b20 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -9,6 +9,7 @@ #include "version.h" #include "textures.h" #include "zstring.h" +#include "baselayer.h" EXTERN_CVAR(Float, snd_menuvolume) EXTERN_CVAR(Int, m_use_mouse); @@ -113,15 +114,6 @@ enum ENativeFontValues // positive values for color are direct palswap indices. }; - -struct FGameStartup -{ - int Episode; - int Skill; - int CustomLevel1; - int CustomLevel2; -}; - extern FGameStartup GameStartupInfo; struct FSaveGameNode diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index c1ba3ea16..fdda98779 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -1035,7 +1035,7 @@ static void BuildEpisodeMenu() if (gVolumeNames[i].IsNotEmpty() && !(gVolumeFlags[i] & EF_HIDEFROMSP)) { - auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, gVolumeNames[i][0], gVolumeNames[i], NIT_BigFont, NIT_ActiveState, 1, NAME_SkillMenu, i + 1); + auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, gVolumeNames[i][0], gVolumeNames[i], NIT_BigFont, NIT_ActiveState, 1, NAME_SkillMenu, i); ld->mItems.Push(it); addedVolumes++; if (gVolumeSubtitles[i].IsNotEmpty()) diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 3c1d69f7d..40fbc6a04 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -388,25 +388,30 @@ void GameInterface::MenuOpened() } } -void GameInterface::MenuSelectSound() +void GameInterface::MenuSound(::GameInterface::EMenuSounds snd) { - S_PlaySound(KICK_HIT); -} + switch (snd) + { + case SelectSound: + S_PlaySound(KICK_HIT); + break; -void GameInterface::MenuChooseSound() -{ - S_PlaySound(PISTOL_BODYHIT); + case ChooseSound: + S_PlaySound(PISTOL_BODYHIT); + break; + + default: + return; + } } -/* void GameInterface::MenuClosed() { S_PlaySound(EXITMENUSOUND); if (!ud.pause_on) S_PauseSounds(false); } -*/ bool GameInterface::CanSave() { @@ -420,6 +425,46 @@ bool GameInterface::CanSave() return true; } +void GameInterface::CustomMenuSelection(int menu, int item) +{ + ud.returnvar[0] = item; + ud.returnvar[1] = -1; + VM_OnEventWithReturn(EVENT_NEWGAMECUSTOM, -1, myconnectindex, menu); +} + +void GameInterface::StartGame(FGameStartup& gs) +{ + int32_t skillsound = PISTOL_BODYHIT; + + switch (gs.Skill) + { + case 0: + skillsound = JIBBED_ACTOR6; + break; + case 1: + skillsound = BONUS_SPEECH1; + break; + case 2: + skillsound = DUKE_GETWEAPON2; + break; + case 3: + skillsound = JIBBED_ACTOR5; + break; + } + + ud.m_player_skill = gs.Skill + 1; + ud.skill_voice = S_PlaySound(skillsound); + ud.m_respawn_monsters = (gs.Skill == 3); + ud.m_monsters_off = ud.monsters_off = 0; + ud.m_respawn_items = 0; + ud.m_respawn_inventory = 0; + ud.multimode = 1; + ud.m_volume_number = gs.Episode; + ud.m_level_number = gs.Level; + G_NewGame_EnterLevel(); + +} + END_DUKE_NS static TMenuClassDescriptor _mm("Duke.MainMenu"); diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index 53686b96a..d1e864766 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -158,9 +158,11 @@ struct GameInterface : ::GameInterface // Everything else is either custom screens or will use the generic option menu style. void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int orientation) override; void MenuOpened() override; - void MenuSelectSound() override; - void MenuChooseSound() override; + void MenuClosed() override; + void MenuSound(EMenuSounds snd) override; bool CanSave() override; + void CustomMenuSelection(int menu, int item) override; + void StartGame(FGameStartup& gs) override; }; diff --git a/source/duke3d/src/gamestructures.cpp b/source/duke3d/src/gamestructures.cpp index a171b205f..40727c8fe 100644 --- a/source/duke3d/src/gamestructures.cpp +++ b/source/duke3d/src/gamestructures.cpp @@ -1632,8 +1632,8 @@ void __fastcall VM_SetUserdef(int const labelNum, int const lParm2, int32_t cons case USERDEFS_M_FFIRE: m_ffire = iSet; break; case USERDEFS_FFIRE: ud.ffire = iSet; break; case USERDEFS_M_PLAYER_SKILL: ud.m_player_skill = iSet; break; - case USERDEFS_M_LEVEL_NUMBER: m_level_number = iSet; break; - case USERDEFS_M_VOLUME_NUMBER: ud.m_volume_number = iSet; break; + case USERDEFS_M_LEVEL_NUMBER: GameStartupInfo.Level = m_level_number = iSet; break; + case USERDEFS_M_VOLUME_NUMBER: GameStartupInfo.Episode = ud.m_volume_number = iSet; break; case USERDEFS_MULTIMODE: ud.multimode = iSet; break; case USERDEFS_PLAYER_SKILL: ud.player_skill = iSet; break; case USERDEFS_LEVEL_NUMBER: ud.level_number = iSet; break; diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index edb88a201..b2a17664c 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -2763,63 +2763,6 @@ static void Menu_EntryLinkActivate(MenuEntry_t *entry) { switch (g_currentMenu) { - case MENU_EPISODE: - if (entry != &ME_EPISODE_USERMAP) - { - ud.m_volume_number = M_EPISODE.currentEntry; - m_level_number = 0; - - if (g_skillCnt == 0) - Menu_StartGameWithoutSkill(); - } - break; - - case MENU_NEWGAMECUSTOM: - ud.returnvar[0] = -1; - VM_OnEventWithReturn(EVENT_NEWGAMECUSTOM, -1, myconnectindex, M_NEWGAMECUSTOM.currentEntry); - break; - - case MENU_NEWGAMECUSTOMSUB: - ud.returnvar[0] = M_NEWGAMECUSTOMSUB.currentEntry; - ud.returnvar[1] = -1; - VM_OnEventWithReturn(EVENT_NEWGAMECUSTOM, -1, myconnectindex, M_NEWGAMECUSTOM.currentEntry); - break; - - case MENU_SKILL: - { - int32_t skillsound = PISTOL_BODYHIT; - - switch (M_SKILL.currentEntry) - { - case 0: - skillsound = JIBBED_ACTOR6; - break; - case 1: - skillsound = BONUS_SPEECH1; - break; - case 2: - skillsound = DUKE_GETWEAPON2; - break; - case 3: - skillsound = JIBBED_ACTOR5; - break; - } - - ud.m_player_skill = M_SKILL.currentEntry+1; - - ud.skill_voice = S_PlaySound(skillsound); - - if (M_SKILL.currentEntry == 3) ud.m_respawn_monsters = 1; - else ud.m_respawn_monsters = 0; - - ud.m_monsters_off = ud.monsters_off = 0; - - ud.m_respawn_items = 0; - ud.m_respawn_inventory = 0; - - ud.multimode = 1; - - G_NewGame_EnterLevel(); break; } @@ -3563,163 +3506,6 @@ static void Menu_FileSelect(int32_t input) } - - - -static Menu_t* Menu_BinarySearch(MenuID_t query, uint16_t searchstart, uint16_t searchend) -{ - const uint16_t thissearch = (searchstart + searchend) / 2; - const MenuID_t difference = query - Menus[thissearch].menuID; - - if (difference == 0) - return &Menus[thissearch]; - else if (searchstart == searchend) - return NULL; - else if (difference > 0) - { - if (thissearch == searchend) - return NULL; - searchstart = thissearch + 1; - } - else if (difference < 0) - { - if (thissearch == searchstart) - return NULL; - searchend = thissearch - 1; - } - - return Menu_BinarySearch(query, searchstart, searchend); -} - -static Menu_t* Menu_Find(MenuID_t query) -{ - if ((unsigned) query > (unsigned) Menus[numMenus-1].menuID) - return NULL; - - return Menu_BinarySearch(query, 0, numMenus-1); -} - -static Menu_t* Menu_FindFiltered(MenuID_t query) -{ - if ((g_player[myconnectindex].ps->gm&MODE_GAME) && query == MENU_MAIN) - query = MENU_MAIN_INGAME; - - return Menu_Find(query); -} - -MenuAnimation_t m_animation; - -int32_t Menu_Anim_SinOutRight(MenuAnimation_t *animdata) -{ - return sintable[divscale10((int32_t) totalclock - animdata->start, animdata->length) + 512] - 16384; -} -int32_t Menu_Anim_SinInRight(MenuAnimation_t *animdata) -{ - return sintable[divscale10((int32_t) totalclock - animdata->start, animdata->length) + 512] + 16384; -} -int32_t Menu_Anim_SinOutLeft(MenuAnimation_t *animdata) -{ - return -sintable[divscale10((int32_t) totalclock - animdata->start, animdata->length) + 512] + 16384; -} -int32_t Menu_Anim_SinInLeft(MenuAnimation_t *animdata) -{ - return -sintable[divscale10((int32_t) totalclock - animdata->start, animdata->length) + 512] - 16384; -} - -void Menu_AnimateChange(int32_t cm, MenuAnimationType_t animtype) -{ - if (cm == MENU_KEYBOARDKEYS) - { - GUICapture |= 2; - return; - } - - if (FURY) - { - m_animation.start = 0; - m_animation.length = 0; - Menu_Change(cm); - return; - } - - switch (animtype) - { - case MA_Advance: - { - Menu_t * const previousMenu = m_currentMenu; - - if (!Menu_Change(cm)) - { - m_animation.out = Menu_Anim_SinOutRight; - m_animation.in = Menu_Anim_SinInRight; - m_animation.start = (int32_t) totalclock; - m_animation.length = 30; - - m_animation.previous = previousMenu; - m_animation.current = m_currentMenu; - } - - break; - } - case MA_Return: - { - Menu_t * const previousMenu = m_currentMenu; - - if (!Menu_Change(cm)) - { - m_animation.out = Menu_Anim_SinOutLeft; - m_animation.in = Menu_Anim_SinInLeft; - m_animation.start = (int32_t) totalclock; - m_animation.length = 30; - - m_animation.previous = previousMenu; - m_animation.current = m_currentMenu; - } - - break; - } - default: - m_animation.start = 0; - m_animation.length = 0; - Menu_Change(cm); - break; - } -} - -static void Menu_MaybeSetSelectionToChild(Menu_t * m, MenuID_t id) -{ - if (m->type == Menu) - { - auto menu = (MenuMenu_t *)m->object; - - if (menu->currentEntry < menu->numEntries) - { - MenuEntry_t const * currentEntry = menu->entrylist[menu->currentEntry]; - if (currentEntry != NULL && currentEntry->type == Link) - { - auto const * link = (MenuLink_t const *)currentEntry->entry; - if (link->linkID == id) - return; // already good to go - } - } - - for (int i = 0, i_end = menu->numEntries; i < i_end; ++i) - { - MenuEntry_t const * entry = menu->entrylist[i]; - if (entry != NULL && entry->type == Link && !(entry->flags & MEF_Hidden)) - { - auto const * link = (MenuLink_t const *)entry->entry; - if (link->linkID == id) - { - menu->currentEntry = i; - Menu_AdjustForCurrentEntryAssignmentBlind(menu); - break; - } - } - } - } -} - static void Menu_ReadSaveGameHeaders() { ReadSaveGameHeaders(); @@ -3761,16 +3547,6 @@ static void Menu_AboutToStartDisplaying(Menu_t * m) { switch (m->menuID) { - case MENU_MAIN: - if (FURY) - ME_MAIN_LOADGAME.name = s_Continue; - break; - - case MENU_MAIN_INGAME: - if (FURY) - ME_MAIN_LOADGAME.name = s_LoadGame; - break; - case MENU_NEWGAMECUSTOMSUB: Menu_PopulateNewGameCustomSub(M_NEWGAMECUSTOM.currentEntry); break; @@ -3888,10 +3664,7 @@ static void Menu_AboutToStartDisplaying(Menu_t * m) static void Menu_ChangingTo(Menu_t * m) { -#ifdef __ANDROID__ - if (m->menuID == MENU_TOUCHBUTTONS) - AndroidToggleButtonEditor(); -#endif + switch (m->type) { @@ -3903,74 +3676,6 @@ static void Menu_ChangingTo(Menu_t * m) } } -int Menu_Change(MenuID_t cm) -{ - Menu_t * beginMenu = m_currentMenu; - - cm = VM_OnEventWithReturn(EVENT_CHANGEMENU, g_player[screenpeek].ps->i, screenpeek, cm); - - if (cm == MENU_PREVIOUS) - { - m_currentMenu = m_previousMenu; - g_currentMenu = g_previousMenu; - } - else if (cm == MENU_CLOSE) - Menu_Close(myconnectindex); - else if (cm >= 0) - { - Menu_t * search = Menu_FindFiltered(cm); - - if (search == NULL) - return 0; // intentional, so that users don't use any random value as "don't change" - - // security - if (search->type == Verify && - search->parentID != MENU_PREVIOUS && - search->parentID != MENU_CLOSE && - search->parentID != g_currentMenu) - return 1; - - m_previousMenu = m_currentMenu; - g_previousMenu = g_currentMenu; - m_currentMenu = search; - g_currentMenu = search->menuID; - } - else - return 1; - - if (FURY) - { - Menu_t * parent = m_currentMenu, * result = NULL; - - while (parent != NULL && parent->menuID != MENU_OPTIONS && parent->menuID != MENU_MAIN && parent->menuID != MENU_MAIN_INGAME) - { - result = parent = Menu_FindFiltered(parent->parentID); - } - - m_parentMenu = result; - - if (result) - { - Menu_MaybeSetSelectionToChild(result, m_currentMenu->menuID); - Menu_AboutToStartDisplaying(result); - } - } - - Menu_MaybeSetSelectionToChild(m_currentMenu, beginMenu->menuID); - Menu_AboutToStartDisplaying(m_currentMenu); - Menu_ChangingTo(m_currentMenu); - -#if !defined EDUKE32_TOUCH_DEVICES - m_menuchange_watchpoint = 1; -#endif - - return 0; -} - - - - - From 723b210c9539b6af6007ac4eab624977ae1ad054 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 27 Nov 2019 00:41:26 +0100 Subject: [PATCH 029/203] - major work on savegame code Not tested yet! * Added a JSON-based header to the savegames so that the unified menu can read from a common data source. * moved loading and saving of frontend independent data to the wrapper so that support is automatic. --- source/blood/src/blood.h | 2 + source/blood/src/loadsave.cpp | 13 +- source/blood/src/loadsave.h | 4 +- source/blood/src/menu.cpp | 30 ++-- source/build/include/baselayer.h | 8 + source/common/initfs.cpp | 2 +- source/common/menu/loadsavemenu.cpp | 48 +++--- source/common/savegamehelp.cpp | 211 +++++++++++++++++++++++++- source/common/savegamehelp.h | 10 ++ source/common/version.h | 21 ++- source/duke3d/src/d_menu.cpp | 7 + source/duke3d/src/duke3d.h | 1 + source/duke3d/src/game.cpp | 4 +- source/duke3d/src/menus.cpp | 66 +------- source/duke3d/src/osdcmds.cpp | 8 - source/duke3d/src/savegame.cpp | 223 +++------------------------- source/duke3d/src/savegame.h | 5 - source/rr/src/duke3d.h | 1 + source/rr/src/menus.cpp | 15 +- source/rr/src/osdcmds.cpp | 9 -- source/rr/src/savegame.cpp | 203 +++---------------------- source/rr/src/savegame.h | 3 - source/sw/src/game.h | 1 + source/sw/src/menus.cpp | 6 + source/sw/src/save.cpp | 9 ++ 25 files changed, 371 insertions(+), 539 deletions(-) diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index 166f05f61..71de1cbc5 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -92,6 +92,8 @@ struct GameInterface : ::GameInterface void set_hud_scale(int size) override; bool mouseInactiveConditional(bool condition) override; FString statFPS() override; + FSavegameInfo GetSaveSig() override; + }; END_BLD_NS diff --git a/source/blood/src/loadsave.cpp b/source/blood/src/loadsave.cpp index 9ea75dd63..0c0ab264c 100644 --- a/source/blood/src/loadsave.cpp +++ b/source/blood/src/loadsave.cpp @@ -46,8 +46,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "sound.h" #include "i_specialpaths.h" #include "view.h" -#include "statistics.h" -#include "secrets.h" #include "savegamehelp.h" BEGIN_BLD_NS @@ -102,7 +100,7 @@ void LoadSave::Write(void *pData, int nSize) ThrowError("File error #%d writing save file.", errno); } -void LoadSave::LoadGame(char *pzFile) +void LoadSave::LoadGame(const char *pzFile) { bool demoWasPlayed = gDemo.at1; if (gDemo.at1) @@ -128,8 +126,6 @@ void LoadSave::LoadGame(char *pzFile) rover->Load(); rover = rover->next; } - if (!ReadStatistics() || !SECRET_Load()) // read the rest... - ThrowError("Error loading save file."); hLFile.Close(); FinishSavegameRead(); @@ -194,7 +190,7 @@ void LoadSave::LoadGame(char *pzFile) //sndPlaySong(gGameOptions.zLevelSong, 1); } -void LoadSave::SaveGame(char *pzFile) +void LoadSave::SaveGame(const char *pzFile) { OpenSaveGameForWrite(pzFile); hSFile = WriteSavegameChunk("snapshot.bld"); @@ -211,8 +207,9 @@ void LoadSave::SaveGame(char *pzFile) dword_27AA38 = 0; rover = rover->next; } - SaveStatistics(); - SECRET_Save(); + auto & li = gEpisodeInfo[gGameOptions.nEpisode].at28[gGameOptions.nLevel]; + G_WriteSaveHeader(gGameOptions.szUserGameName, li.at0, li.at90); + FinishSavegameWrite(); hSFile = NULL; } diff --git a/source/blood/src/loadsave.h b/source/blood/src/loadsave.h index 3da580a62..e8d4cf00a 100644 --- a/source/blood/src/loadsave.h +++ b/source/blood/src/loadsave.h @@ -49,8 +49,8 @@ public: virtual void Load(void); void Read(void *, int); void Write(void *, int); - static void LoadGame(char *); - static void SaveGame(char *); + static void LoadGame(const char *); + static void SaveGame(const char *); }; extern unsigned int gSavedOffset; diff --git a/source/blood/src/menu.cpp b/source/blood/src/menu.cpp index 2cd2194bf..bd74f2ca7 100644 --- a/source/blood/src/menu.cpp +++ b/source/blood/src/menu.cpp @@ -43,6 +43,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "view.h" #include "cmdlib.h" #include "i_specialpaths.h" +#include "savegamehelp.h" EXTERN_CVAR(Bool, hud_powerupduration) @@ -2069,7 +2070,6 @@ short gQuickSaveSlot = -1; void SaveGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event) { - char strSaveGameName[BMAX_PATH]; int nSlot = pItem->at28; if (gGameOptions.nGameType > 0 || !gGameStarted) return; @@ -2078,21 +2078,21 @@ void SaveGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event) gGameMenuMgr.Deactivate(); return; } - snprintf(strSaveGameName, BMAX_PATH, "%sgame00%02d.sav", M_GetSavegamesPath().GetChars(), nSlot); + FStringf basename("save%04d", nSlot); + auto strSaveGameName = G_BuildSaveName(basename); strcpy(gGameOptions.szUserGameName, strRestoreGameStrings[nSlot]); - sprintf(gGameOptions.szSaveGameName, "%s", strSaveGameName); + sprintf(gGameOptions.szSaveGameName, "%s", strSaveGameName.GetChars()); gGameOptions.nSaveGameSlot = nSlot; viewLoadingScreen(2518, "Saving", "Saving Your Game", strRestoreGameStrings[nSlot]); videoNextPage(); gSaveGameNum = nSlot; - LoadSave::SaveGame(strSaveGameName); + LoadSave::SaveGame(strSaveGameName.GetChars()); gQuickSaveSlot = nSlot; gGameMenuMgr.Deactivate(); } void QuickSaveGame(void) { - char strSaveGameName[BMAX_PATH]; if (gGameOptions.nGameType > 0 || !gGameStarted) return; /*if (strSaveGameName[0]) @@ -2100,9 +2100,11 @@ void QuickSaveGame(void) gGameMenuMgr.Deactivate(); return; }*/ - snprintf(strSaveGameName, BMAX_PATH, "%sgame00%02d.sav", M_GetSavegamesPath().GetChars(), gQuickSaveSlot); + FStringf basename("save%04d", gQuickSaveSlot); + auto strSaveGameName = G_BuildSaveName(basename); + strcpy(gGameOptions.szUserGameName, strRestoreGameStrings[gQuickSaveSlot]); - sprintf(gGameOptions.szSaveGameName, "%s", strSaveGameName); + sprintf(gGameOptions.szSaveGameName, "%s", strSaveGameName.GetChars()); gGameOptions.nSaveGameSlot = gQuickSaveSlot; viewLoadingScreen(2518, "Saving", "Saving Your Game", strRestoreGameStrings[gQuickSaveSlot]); videoNextPage(); @@ -2116,11 +2118,11 @@ void QuickSaveGame(void) void LoadGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event) { UNREFERENCED_PARAMETER(event); - char strLoadGameName[BMAX_PATH]; int nSlot = pItem->at28; if (gGameOptions.nGameType > 0) return; - snprintf(strLoadGameName, BMAX_PATH, "%sgame00%02d.sav", M_GetSavegamesPath().GetChars(), nSlot); + FStringf basename("save%04d", nSlot); + auto strLoadGameName = G_BuildSaveName(basename); if (!FileExists(strLoadGameName)) return; viewLoadingScreen(2518, "Loading", "Loading Saved Game", strRestoreGameStrings[nSlot]); @@ -2132,10 +2134,11 @@ void LoadGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event) void QuickLoadGame(void) { - char strLoadGameName[BMAX_PATH]; + if (gGameOptions.nGameType > 0) return; - snprintf(strLoadGameName, BMAX_PATH, "%sgame00%02d.sav", M_GetSavegamesPath().GetChars(), gQuickLoadSlot); + FStringf basename("save%04d", gQuickSaveSlot); + auto strLoadGameName = G_BuildSaveName(basename); if (!FileExists(strLoadGameName)) return; viewLoadingScreen(2518, "Loading", "Loading Saved Game", strRestoreGameStrings[gQuickLoadSlot]); @@ -2270,4 +2273,9 @@ void drawLoadingScreen(void) viewLoadingScreen(2049, buffer, levelGetTitle(), NULL); } +FSavegameInfo GameInterface::GetSaveSig() +{ + return { SAVESIG_BLD, MINSAVEVER_BLD, SAVEVER_BLD }; +} + END_BLD_NS diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 4bc2bac9f..dec688c0a 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -177,6 +177,13 @@ struct FGameStartup int CustomLevel2; }; +struct FSavegameInfo +{ + const char *savesig; + int minsavever; + int currentsavever; +}; + struct GameInterface { enum EMenuSounds @@ -202,6 +209,7 @@ struct GameInterface virtual bool CanSave() { return true; } virtual void CustomMenuSelection(int menu, int item) {} virtual void StartGame(FGameStartup& gs) {} + virtual FSavegameInfo GetSaveSig() { return { "", 0, 0}; } }; extern GameInterface* gi; diff --git a/source/common/initfs.cpp b/source/common/initfs.cpp index 4a93a87e0..cb9bda281 100644 --- a/source/common/initfs.cpp +++ b/source/common/initfs.cpp @@ -267,7 +267,7 @@ static void D_AddDirectory (TArray &wadfiles, const char *dir) { skindir[stuffstart++] = '/'; int savedstart = stuffstart; - const char* validexts[] = { "*.grp", "*.zip", "*.pk3", "*.pk4", "*.7z", "*.pk7" }; + const char* validexts[] = { "*.grp", "*.zip", "*.pk3", "*.pk4", "*.7z", "*.pk7", "*.dat" }; for (auto ext : validexts) { stuffstart = savedstart; diff --git a/source/common/menu/loadsavemenu.cpp b/source/common/menu/loadsavemenu.cpp index 12f527aef..7930d1606 100644 --- a/source/common/menu/loadsavemenu.cpp +++ b/source/common/menu/loadsavemenu.cpp @@ -42,6 +42,11 @@ #include "gstrings.h" #include "d_gui.h" #include "v_draw.h" +#include "files.h" +#include "resourcefile.h" +#include "sjson.h" +#include "savegamehelp.h" +#include "i_specialpaths.h" #include "../../platform/win32/i_findfile.h" // This is a temporary direct path. Needs to be fixed when stuff gets cleaned up. @@ -207,7 +212,7 @@ void DLoadSaveMenu::ReadSaveStrings () LastSaved = LastAccessed = -1; quickSaveSlot = NULL; - filter = "";// G_BuildSaveName("*.zds", -1); + filter = G_BuildSaveName("*"); filefirst = I_FindFirst (filter.GetChars(), &c_file); if (filefirst != ((void *)(-1))) { @@ -215,25 +220,30 @@ void DLoadSaveMenu::ReadSaveStrings () { // I_FindName only returns the file's name and not its full path FString filepath = "";// G_BuildSaveName(I_FindName(&c_file), -1); - FILE *file = fopen (filepath, "rb"); - - if (file != NULL) + + FResourceFile *savegame = FResourceFile::OpenResourceFile(filepath, true, true); + if (savegame != nullptr) { - //PNGHandle *png; - //char sig[16]; + FResourceLump *info = savegame->FindLump("info.json"); + if (info == nullptr) + { + // savegame info not found. This is not a savegame so leave it alone. + delete savegame; + continue; + } + auto fr = info->NewReader(); FString title; - bool oldVer = true; - bool addIt = false; - bool missing = false; - - // ZDoom 1.23 betas 21-33 have the savesig first. - // Earlier versions have the savesig second. - // Later versions have the savegame encapsulated inside a PNG. - // - // Old savegame versions are always added to the menu so - // the user can easily delete them if desired. - - // Todo: Identify savegames here. + int check = G_ValidateSavegame(fr, &title); + delete savegame; + if (check != 0) + { + FSaveGameNode *node = new FSaveGameNode; + node->Filename = filepath; + node->bOldVersion = check == -1; + node->bMissingWads = check == -2; + node->Title = title; + InsertSaveNode(node); + } } } while (I_FindNext (filefirst, &c_file) == 0); I_FindClose (filefirst); @@ -691,7 +701,7 @@ bool DLoadSaveMenu::Responder (event_t *ev) { FString EndString; EndString.Format("%s" TEXTCOLOR_WHITE "%s" TEXTCOLOR_NORMAL "?\n\n%s", - GStrings("MNU_DELETESG"), SaveGames[Selected]->Title, GStrings("PRESSYN")); + GStrings("MNU_DELETESG"), SaveGames[Selected]->Title.GetChars(), GStrings("PRESSYN")); M_StartMessage (EndString, 0); } return true; diff --git a/source/common/savegamehelp.cpp b/source/common/savegamehelp.cpp index 3a3cdffa7..57602da34 100644 --- a/source/common/savegamehelp.cpp +++ b/source/common/savegamehelp.cpp @@ -1,5 +1,7 @@ /* ** savegame.cpp +** +** common savegame utilities for all front ends. ** **--------------------------------------------------------------------------- ** Copyright 2019 Christoph Oelckers @@ -29,21 +31,36 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **--------------------------------------------------------------------------- ** -** This is for keeping my sanity while working with the horrible mess -** that is the savegame code in Duke Nukem. -** Without handling this in global variables it is a losing proposition -** to save custom data along with the regular snapshot. :( -** With this the savegame code can mostly pretend to load from and write -** to files while really using a composite archive. -*/ +*/ #include "compositesaveame.h" #include "savegamehelp.h" - +#include "sjson.h" +#include "baselayer.h" +#include "gstrings.h" +#include "i_specialpaths.h" +#include "cmdlib.h" +#include "filesystem/filesystem.h" +#include "statistics.h" +#include "secrets.h" static CompositeSavegameWriter savewriter; static FResourceFile *savereader; +//============================================================================= +// +// This is for keeping my sanity while working with the horrible mess +// that is the savegame code in Duke Nukem. +// Without handling this in global variables it is a losing proposition +// to save custom data along with the regular snapshot. :( +// With this the savegame code can mostly pretend to load from and write +// to files while really using a composite archive. +// +// All global non-game dependent state is also saved right here for convenience. +// +//============================================================================= + + void OpenSaveGameForWrite(const char *name) { savewriter.Clear(); @@ -54,6 +71,13 @@ bool OpenSaveGameForRead(const char *name) { if (savereader) delete savereader; savereader = FResourceFile::OpenResourceFile(name, true, true); + + if (savereader != nullptr) + { + ReadStatistics(); + SECRET_Load(); + } + return savereader != nullptr; } @@ -80,3 +104,174 @@ void FinishSavegameRead() delete savereader; savereader = nullptr; } + +//============================================================================= +// +// Writes the header which is used to display the savegame in the menu. +// +//============================================================================= + +void G_WriteSaveHeader(const char *name, const char*mapname, const char *maptitle) +{ + sjson_context* ctx = sjson_create_context(0, 0, NULL); + if (!ctx) + { + return; + } + sjson_node* root = sjson_mkobject(ctx); + auto savesig = gi->GetSaveSig(); + sjson_put_int(ctx, root, "Save Version", savesig.currentsavever); + sjson_put_string(ctx, root, "Engine", savesig.savesig); + sjson_put_string(ctx, root, "Game Resource", fileSystem.GetResourceFileName(1)); + sjson_put_string(ctx, root, "map", mapname); + sjson_put_string(ctx, root, "Title", maptitle); + if (*mapname == '/') mapname++; + sjson_put_string(ctx, root, "Map Resource", mapname); + + char* encoded = sjson_stringify(ctx, root, " "); + + FileWriter* fil = WriteSavegameChunk("info.json"); + if (!fil) + { + sjson_destroy_context(ctx); + return; + } + + fil->Write(encoded, strlen(encoded)); + + sjson_free_string(ctx, encoded); + sjson_destroy_context(ctx); + + SaveStatistics(); + SECRET_Save(); +} + +//============================================================================= +// +// +// +//============================================================================= + +static bool CheckSingleFile (const char *name, bool &printRequires, bool printwarn) +{ + if (name == NULL) + { + return true; + } + if (fileSystem.CheckIfResourceFileLoaded(name) < 0) + { + if (printwarn) + { + if (!printRequires) + { + Printf ("%s:\n%s", GStrings("TXT_SAVEGAMENEEDS"), name); + } + else + { + Printf (", %s", name); + } + } + printRequires = true; + return false; + } + return true; +} + +//============================================================================= +// +// Return false if not all the needed wads have been loaded. +// +//============================================================================= + +bool G_CheckSaveGameWads (sjson_node* root, bool printwarn) +{ + bool printRequires = false; + auto text = sjson_get_string(root, "Game Resource", ""); + CheckSingleFile (text, printRequires, printwarn); + text = sjson_get_string(root, "MAP Resource", ""); + CheckSingleFile (text, printRequires, printwarn); + + if (printRequires) + { + if (printwarn) + { + Printf ("\n"); + } + return false; + } + + return true; +} + +//============================================================================= +// +// Checks if the savegame is valid. Gets a reader to the included info.json +// Returns 1 if valid, 0 if invalid and -1 if old and -2 if content missing +// +//============================================================================= + +int G_ValidateSavegame(FileReader &fr, FString *savetitle) +{ + auto data = fr.ReadPadded(1); + + sjson_context* ctx = sjson_create_context(0, 0, NULL); + if (ctx) + { + sjson_node* root = sjson_decode(ctx, (const char*)data.Data()); + + + int savever = sjson_get_int(root, "Save Version", -1); + FString engine = sjson_get_string(root, "Engine", ""); + FString gamegrp = sjson_get_string(root, "Game Resource", ""); + FString title = sjson_get_string(root, "Title", ""); + auto savesig = gi->GetSaveSig(); + + sjson_destroy_context(ctx); + + if (savetitle) *savetitle = title; + if (engine.Compare(savesig.savesig) != 0 || savever > savesig.currentsavever) + { + // different engine or newer version: + // not our business. Leave it alone. + return 0; + } + + if (savever < savesig.minsavever) + { + // old, incompatible savegame. List as not usable. + return -1; + } + else if (gamegrp.CompareNoCase(fileSystem.GetResourceFileName(1)) == 0) + { + return G_CheckSaveGameWads(root, false)? 0 : -2; + } + else + { + // different game. Skip this. + return 0; + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + +FString G_BuildSaveName (const char *prefix) +{ + FString name = M_GetSavegamesPath(); + size_t len = name.Len(); + if (name[0] != '\0' && name[len-1] != '\\' && name[len-1] != '/') + { + name << "/"; + } + name << prefix; + if (!strchr(prefix, '.')) name << SAVEGAME_EXT; // only add an extension if the prefix doesn't have one already. + name = NicePath(name); + name.Substitute("\\", "/"); + CreatePath(name); + return name; +} + diff --git a/source/common/savegamehelp.h b/source/common/savegamehelp.h index 9dec6d617..12e56cc3d 100644 --- a/source/common/savegamehelp.h +++ b/source/common/savegamehelp.h @@ -10,3 +10,13 @@ FileReader ReadSavegameChunk(const char *name); bool FinishSavegameWrite(); void FinishSavegameRead(); + +// Savegame utilities +class FileReader; + +FString G_BuildSaveName (const char *prefix); +bool G_CheckSaveGameWads (struct sjson_node* root, bool printwarn); +int G_ValidateSavegame(FileReader &fr, FString *savetitle); +void G_WriteSaveHeader(const char *name, const char*mapname, const char *title); + +#define SAVEGAME_EXT ".dsave" diff --git a/source/common/version.h b/source/common/version.h index 388737dbf..c9908ab51 100644 --- a/source/common/version.h +++ b/source/common/version.h @@ -41,11 +41,11 @@ const char *GetVersionString(); /** Lots of different version numbers **/ -#define VERSIONSTR "0.0.1" +#define VERSIONSTR "0.1.0" // The version as seen in the Windows resource -#define RC_FILEVERSION 0,0,1,0 -#define RC_PRODUCTVERSION 0,0,1,0 +#define RC_FILEVERSION 0,1,0,0 +#define RC_PRODUCTVERSION 0,1,0,0 #define RC_PRODUCTVERSION2 VERSIONSTR // These are for content versioning. #define VER_MAJOR 0 @@ -59,6 +59,21 @@ const char *GetVersionString(); #define FORUM_URL "http://forum.zdoom.org/" //#define BUGS_FORUM_URL "http://forum.zdoom.org/viewforum.php?f=2" +#define SAVESIG_DN3D "Demolition.Duke" +#define SAVESIG_BLD "Demolition.Blood" +#define SAVESIG_RR "Demolition.Redneck" +#define SAVESIG_SW "Demolition.SW" + +#define MINSAVEVER_DN3D 1 +#define MINSAVEVER_BLD 1 +#define MINSAVEVER_RR 1 +#define MINSAVEVER_SW 1 + +#define SAVEVER_DN3D 1 +#define SAVEVER_BLD 1 +#define SAVEVER_RR 1 +#define SAVEVER_SW 1 + #if defined(__APPLE__) || defined(_WIN32) #define GAME_DIR GAMENAME #else diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 40fbc6a04..e51a8f022 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -36,6 +36,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "c_bind.h" #include "menu/menu.h" #include "gstrings.h" +#include "version.h" #include "../../glbackend/glbackend.h" BEGIN_DUKE_NS @@ -465,6 +466,12 @@ void GameInterface::StartGame(FGameStartup& gs) } +FSavegameInfo GameInterface::GetSaveSig() +{ + return { SAVESIG_DN3D, MINSAVEVER_DN3D, SAVEVER_DN3D }; +} + + END_DUKE_NS static TMenuClassDescriptor _mm("Duke.MainMenu"); diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index d1e864766..ebf34735c 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -163,6 +163,7 @@ struct GameInterface : ::GameInterface bool CanSave() override; void CustomMenuSelection(int menu, int item) override; void StartGame(FGameStartup& gs) override; + FSavegameInfo GetSaveSig() override; }; diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index aeac1605c..082385980 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -5497,7 +5497,7 @@ static void G_FreeHashAnim(const char * /*string*/, intptr_t key) static void G_Cleanup(void) { - ReadSaveGameHeaders(); // for culling + //ReadSaveGameHeaders(); // for culling int32_t i; @@ -6189,8 +6189,6 @@ int GameInterface::app_main() Menu_Init(); } - ReadSaveGameHeaders(); - FX_StopAllSounds(); S_ClearSoundLocks(); diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index b2a17664c..7af81181a 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -2543,31 +2543,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) } -static void Menu_ReadSaveGameHeaders(); - -static void Menu_LoadReadHeaders() -{ - Menu_ReadSaveGameHeaders(); - - for (int i = 0; i < g_nummenusaves; ++i) - { - menusave_t const & msv = g_menusaves[i]; - // MenuEntry_LookDisabledOnCondition(&ME_LOAD[i], msv.isOldVer && msv.brief.isExt); - MenuEntry_DisableOnCondition(&ME_LOAD[i], msv.isOldVer && !msv.brief.isExt); - } -} - -static void Menu_SaveReadHeaders() -{ - Menu_ReadSaveGameHeaders(); - - for (int i = 0; i < g_nummenusaves; ++i) - { - menusave_t const & msv = g_menusaves[i]; - MenuEntry_LookDisabledOnCondition(&ME_SAVE[i], msv.isOldVer && !msv.brief.isExt); - } -} - static void Menu_PreInput(MenuEntry_t *entry) { switch (g_currentMenu) @@ -2862,7 +2837,6 @@ static void Menu_EntryLinkActivate(MenuEntry_t *entry) } else if (entry == &ME_SAVESETUP_CLEANUP) { - g_oldSaveCnt = G_CountOldSaves(); Menu_Change(MENU_SAVECLEANVERIFY); } else if (entry == &ME_NETHOST_LAUNCH) @@ -3247,15 +3221,13 @@ static void Menu_Verify(int32_t input) case MENU_LOADDELVERIFY: if (input) { - G_DeleteSave(g_menusaves[M_LOAD.currentEntry].brief); - Menu_LoadReadHeaders(); + Menu_LoadReadHeaders(); M_LOAD.currentEntry = clamp(M_LOAD.currentEntry, 0, (int32_t)g_nummenusaves-1); } break; case MENU_SAVEDELVERIFY: if (input) { - G_DeleteSave(g_menusaves[M_SAVE.currentEntry-1].brief); Menu_SaveReadHeaders(); M_SAVE.currentEntry = clamp(M_SAVE.currentEntry, 0, (int32_t)g_nummenusaves); } @@ -3506,42 +3478,6 @@ static void Menu_FileSelect(int32_t input) } -static void Menu_ReadSaveGameHeaders() -{ - ReadSaveGameHeaders(); - - int const numloaditems = max(g_nummenusaves, 1), numsaveitems = g_nummenusaves+1; - ME_LOAD = (MenuEntry_t *)Xrealloc(ME_LOAD, g_nummenusaves * sizeof(MenuEntry_t)); - MEL_LOAD = (MenuEntry_t **)Xrealloc(MEL_LOAD, numloaditems * sizeof(MenuEntry_t *)); - MEO_SAVE = (MenuString_t *)Xrealloc(MEO_SAVE, g_nummenusaves * sizeof(MenuString_t)); - ME_SAVE = (MenuEntry_t *)Xrealloc(ME_SAVE, g_nummenusaves * sizeof(MenuEntry_t)); - MEL_SAVE = (MenuEntry_t **)Xrealloc(MEL_SAVE, numsaveitems * sizeof(MenuEntry_t *)); - - MEL_SAVE[0] = &ME_SAVE_NEW; - ME_SAVE_NEW.name = s_NewSaveGame; - for (int i = 0; i < g_nummenusaves; ++i) - { - MEL_LOAD[i] = &ME_LOAD[i]; - MEL_SAVE[i+1] = &ME_SAVE[i]; - ME_LOAD[i] = ME_LOAD_TEMPLATE; - ME_SAVE[i] = ME_SAVE_TEMPLATE; - ME_SAVE[i].entry = &MEO_SAVE[i]; - MEO_SAVE[i] = MEO_SAVE_TEMPLATE; - - ME_LOAD[i].name = g_menusaves[i].brief.name; - MEO_SAVE[i].variable = g_menusaves[i].brief.name; - } - - if (g_nummenusaves == 0) - MEL_LOAD[0] = &ME_LOAD_EMPTY; - - M_LOAD.entrylist = MEL_LOAD; - M_LOAD.numEntries = numloaditems; - M_SAVE.entrylist = MEL_SAVE; - M_SAVE.numEntries = numsaveitems; - - // lexicographical sorting? -} static void Menu_AboutToStartDisplaying(Menu_t * m) { diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index 215fb3d9a..6f951cab4 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -913,12 +913,6 @@ static int osdcmd_kickban(osdcmdptr_t parm) } #endif -static int osdcmd_purgesaves(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_CONST_PARAMETER(parm); - G_DeleteOldSaves(); - return OSDCMD_OK; -} static int osdcmd_printtimes(osdcmdptr_t UNUSED(parm)) { @@ -1025,8 +1019,6 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("printtimes", "printtimes: prints VM timing statistics", osdcmd_printtimes); - OSD_RegisterFunction("purgesaves", "purgesaves: deletes obsolete and unreadable save files", osdcmd_purgesaves); - OSD_RegisterFunction("quicksave","quicksave: performs a quick save", osdcmd_quicksave); OSD_RegisterFunction("quickload","quickload: performs a quick load", osdcmd_quickload); diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index 2695d3d03..7b997f2d5 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -30,8 +30,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "i_specialpaths.h" #include "gamecontrol.h" #include "version.h" -#include "statistics.h" -#include "secrets.h" #include "savegamehelp.h" #include "menu/menu.h" @@ -147,11 +145,6 @@ int32_t g_lastAutoSaveArbitraryID = -1; bool g_saveRequested; savebrief_t * g_quickload; -menusave_t * g_menusaves; -uint16_t g_nummenusaves; - -static menusave_t * g_internalsaves; -static uint16_t g_numinternalsaves; static FileReader *OpenSavegame(const char *fn) { @@ -159,12 +152,17 @@ static FileReader *OpenSavegame(const char *fn) { return nullptr; } - auto file = ReadSavegameChunk("DEMOLITION_ED"); + auto file = ReadSavegameChunk("info.json"); if (!file.isOpen()) { FinishSavegameRead(); return nullptr; } + if (G_ValidateSavegame(file, nullptr) <= 0) + { + FinishSavegameRead(); + return nullptr; + } file = ReadSavegameChunk("snapshot.dat"); if (!file.isOpen()) { @@ -174,145 +172,6 @@ static FileReader *OpenSavegame(const char *fn) return new FileReader(std::move(file)); } -static void ReadSaveGameHeaders_CACHE1D(TArray &saves) -{ - savehead_t h; - - for (FString &save : saves) - { - auto fil = OpenSavegame(save); - if (!fil) - continue; - - menusave_t & msv = g_internalsaves[g_numinternalsaves]; - - msv.brief.isExt = 0; - - int32_t k = sv_loadheader(*fil, 0, &h); - delete fil; - if (k) - { - if (k < 0) - msv.isUnreadable = 1; - else - { - if (FURY) - { - auto extfil = ReadSavegameChunk("ext.json"); - if (extfil.isOpen()) - { - msv.brief.isExt = 1; - } - } - } - msv.isOldVer = 1; - } - else - msv.isOldVer = 0; - - msv.isAutoSave = h.isAutoSave(); - - strncpy(msv.brief.path, save.GetChars(), ARRAY_SIZE(msv.brief.path)); - ++g_numinternalsaves; - - if (k >= 0 && h.savename[0] != '\0') - { - memcpy(msv.brief.name, h.savename, ARRAY_SIZE(msv.brief.name)); - } - else - msv.isUnreadable = 1; - - } - FinishSavegameRead(); -} - -static void ReadSaveGameHeaders_Internal(void) -{ - FString pattern = M_GetSavegamesPath() + "*.bsv"; - TArray saves; - D_AddWildFile(saves, pattern); - // potentially overallocating but programmatically simple - int const numfiles = saves.Size(); - size_t const internalsavesize = sizeof(menusave_t) * numfiles; - - g_internalsaves = (menusave_t *)Xrealloc(g_internalsaves, internalsavesize); - - for (int x = 0; x < numfiles; ++x) - g_internalsaves[x].clear(); - - g_numinternalsaves = 0; - ReadSaveGameHeaders_CACHE1D(saves); - - g_nummenusaves = 0; - for (int x = g_numinternalsaves-1; x >= 0; --x) - { - menusave_t & msv = g_internalsaves[x]; - if (!msv.isUnreadable) - { - ++g_nummenusaves; - } - } - size_t const menusavesize = sizeof(menusave_t) * g_nummenusaves; - - g_menusaves = (menusave_t *)Xrealloc(g_menusaves, menusavesize); - - for (int x = 0; x < g_nummenusaves; ++x) - g_menusaves[x].clear(); - - for (int x = g_numinternalsaves-1, y = 0; x >= 0; --x) - { - menusave_t & msv = g_internalsaves[x]; - if (!msv.isUnreadable) - { - g_menusaves[y++] = msv; - } - } - - for (int x = g_numinternalsaves-1; x >= 0; --x) - { - char const * const path = g_internalsaves[x].brief.path; - int const pathlen = Bstrlen(path); - if (pathlen < 12) - continue; - char const * const fn = path + (pathlen-12); - if (fn[0] == 's' && fn[1] == 'a' && fn[2] == 'v' && fn[3] == 'e' && - isdigit(fn[4]) && isdigit(fn[5]) && isdigit(fn[6]) && isdigit(fn[7])) - { - char number[5]; - memcpy(number, fn+4, 4); - number[4] = '\0'; - savecounter.count = Batoi(number)+1; - break; - } - } -} - -void ReadSaveGameHeaders(void) -{ - ReadSaveGameHeaders_Internal(); - - if (!cl_autosavedeletion) - return; - - bool didDelete = false; - int numautosaves = 0; - for (int x = 0; x < g_nummenusaves; ++x) - { - menusave_t & msv = g_menusaves[x]; - if (!msv.isAutoSave) - continue; - if (numautosaves >= cl_maxautosaves) - { - G_DeleteSave(msv.brief); - didDelete = true; - } - ++numautosaves; - } - - if (didDelete) - ReadSaveGameHeaders_Internal(); -} - int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh) { FileReader ssfil; @@ -681,7 +540,7 @@ int32_t G_LoadPlayer(savebrief_t & sv) if (status == 2) G_NewGame_EnterLevel(); - else if ((status = sv_loadsnapshot(*fil, 0, &h)) || !ReadStatistics() || !SECRET_Load()) // read the rest... + else if ((status = sv_loadsnapshot(*fil, 0, &h))) // read the rest... { // in theory, we could load into an initial dump first and trivially // recover if things go wrong... @@ -722,49 +581,6 @@ static void G_RestoreTimers(void) ////////// -void G_DeleteSave(savebrief_t const & sv) -{ - if (!sv.isValid()) - return; - - char temp[BMAX_PATH]; - - if (snprintf(temp, sizeof(temp), "%s%s", M_GetSavegamesPath().GetChars(), sv.path)) - { - OSD_Printf("G_SavePlayer: file name \"%s\" too long\n", sv.path); - return; - } - - remove(temp); -} - -void G_DeleteOldSaves(void) -{ - ReadSaveGameHeaders(); - - for (int x = 0; x < g_numinternalsaves; ++x) - { - menusave_t const & msv = g_internalsaves[x]; - if (msv.isOldVer || msv.isUnreadable) - G_DeleteSave(msv.brief); - } -} - -uint16_t G_CountOldSaves(void) -{ - ReadSaveGameHeaders(); - - int bad = 0; - for (int x = 0; x < g_numinternalsaves; ++x) - { - menusave_t const & msv = g_internalsaves[x]; - if (msv.isOldVer || msv.isUnreadable) - ++bad; - } - - return bad; -} - int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) { #ifdef __ANDROID__ @@ -783,29 +599,28 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) if (sv.isValid()) { - fn.Format("%s%s", M_GetSavegamesPath().GetChars(), sv.path); + fn = G_BuildSaveName(sv.path); OpenSaveGameForWrite(fn); fil = WriteSavegameChunk("snapshot.dat"); } else { - static char const SaveName[] = "save0000.bsv"; - fn.Format("%s%s", M_GetSavegamesPath().GetChars(), SaveName); + fn = G_BuildSaveName("save0000"); auto fnp = fn.LockBuffer(); - char* zeros = fnp + (fn.Len() - 8); - fil = savecounter.opennextfile(fnp, zeros); + char* zeros = strstr(fnp, "0000"); + fil = savecounter.opennextfile(fnp, zeros); // fixme: Rewrite this so that it won't create the file. + fn.UnlockBuffer(); if (fil) { delete fil; - remove(fnp); - OpenSaveGameForWrite(fnp); + remove(fn); + OpenSaveGameForWrite(fn); fil = WriteSavegameChunk("snapshot.dat"); } - fn.UnlockBuffer(); savecounter.count++; - // don't copy the mod dir into sv.path - Bstrcpy(sv.path, fn + (fn.Len() - (ARRAY_SIZE(SaveName) - 1))); + // don't copy the mod dir into sv.path (G_BuildSaveName guarantees the presence of a slash.) + Bstrcpy(sv.path, strrchr(fn, '/') + 1); } if (!fil) @@ -821,7 +636,6 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) } else { - WriteSavegameChunk("DEMOLITION_ED"); auto& fw = *fil; sv.isExt = 0; @@ -835,8 +649,7 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) // SAVE! sv_saveandmakesnapshot(fw, sv.name, 0, 0, 0, 0, isAutoSave); - SaveStatistics(); - SECRET_Save(); + fw.Close(); FinishSavegameWrite(); @@ -1712,6 +1525,8 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i Bstrncpyz(h.savename, name, sizeof(h.savename)); auto fw = WriteSavegameChunk("header.dat"); fw->Write(&h, sizeof(savehead_t)); + + G_WriteSaveHeader(name, currentboardfilename, g_mapInfo[(MAXLEVELS * ud.volume_number) + ud.level_number].name); } else { diff --git a/source/duke3d/src/savegame.h b/source/duke3d/src/savegame.h index d66e837f9..6f34329ac 100644 --- a/source/duke3d/src/savegame.h +++ b/source/duke3d/src/savegame.h @@ -114,8 +114,6 @@ extern int32_t g_lastAutoSaveArbitraryID; extern bool g_saveRequested; extern savebrief_t * g_quickload; -extern menusave_t * g_menusaves; -extern uint16_t g_nummenusaves; int32_t sv_updatestate(int32_t frominit); int32_t sv_readdiff(FileReader& fil); @@ -124,9 +122,6 @@ int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h); int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h); int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave = false); void sv_freemem(); -void G_DeleteSave(savebrief_t const & sv); -void G_DeleteOldSaves(void); -uint16_t G_CountOldSaves(void); int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave); int32_t G_LoadPlayer(savebrief_t & sv); int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh); diff --git a/source/rr/src/duke3d.h b/source/rr/src/duke3d.h index 48462e06d..28d426db3 100644 --- a/source/rr/src/duke3d.h +++ b/source/rr/src/duke3d.h @@ -158,6 +158,7 @@ struct GameInterface : ::GameInterface bool mouseInactiveConditional(bool condition) override; FString statFPS() override; GameStats getStats() override; + FSavegameInfo GetSaveSig() override; }; END_RR_NS diff --git a/source/rr/src/menus.cpp b/source/rr/src/menus.cpp index eea4a87e8..34dcd480a 100644 --- a/source/rr/src/menus.cpp +++ b/source/rr/src/menus.cpp @@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "cheats.h" #include "gamecvars.h" #include "menu/menu.h" +#include "version.h" #include "../../glbackend/glbackend.h" BEGIN_RR_NS @@ -3446,7 +3447,6 @@ static void Menu_EntryLinkActivate(MenuEntry_t *entry) } else if (entry == &ME_SAVESETUP_CLEANUP) { - g_oldSaveCnt = G_CountOldSaves(); Menu_Change(MENU_SAVECLEANVERIFY); } else if (entry == &ME_COLCORR_RESET) @@ -3768,10 +3768,6 @@ static void Menu_Verify(int32_t input) switch (g_currentMenu) { case MENU_SAVECLEANVERIFY: - if (input) - { - G_DeleteOldSaves(); - } break; case MENU_RESETPLAYER: @@ -3839,7 +3835,7 @@ static void Menu_Verify(int32_t input) case MENU_LOADDELVERIFY: if (input) { - G_DeleteSave(g_menusaves[M_LOAD.currentEntry].brief); + //G_DeleteSave(g_menusaves[M_LOAD.currentEntry].brief); Menu_LoadReadHeaders(); M_LOAD.currentEntry = clamp(M_LOAD.currentEntry, 0, (int32_t)g_nummenusaves-1); } @@ -3847,7 +3843,7 @@ static void Menu_Verify(int32_t input) case MENU_SAVEDELVERIFY: if (input) { - G_DeleteSave(g_menusaves[M_SAVE.currentEntry-1].brief); + //G_DeleteSave(g_menusaves[M_SAVE.currentEntry-1].brief); Menu_SaveReadHeaders(); M_SAVE.currentEntry = clamp(M_SAVE.currentEntry, 0, (int32_t)g_nummenusaves); } @@ -7462,4 +7458,9 @@ bool GameInterface::mouseInactiveConditional(bool condition) return MOUSEINACTIVECONDITIONAL(condition); } +FSavegameInfo GameInterface::GetSaveSig() +{ + return { SAVESIG_RR, MINSAVEVER_RR, SAVEVER_RR }; +} + END_RR_NS diff --git a/source/rr/src/osdcmds.cpp b/source/rr/src/osdcmds.cpp index c380a897d..0c1f02cb9 100644 --- a/source/rr/src/osdcmds.cpp +++ b/source/rr/src/osdcmds.cpp @@ -791,13 +791,6 @@ static int osdcmd_kickban(osdcmdptr_t parm) #endif #endif -static int osdcmd_purgesaves(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_CONST_PARAMETER(parm); - G_DeleteOldSaves(); - return OSDCMD_OK; -} - static int osdcmd_printtimes(osdcmdptr_t UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -881,8 +874,6 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("printtimes", "printtimes: prints VM timing statistics", osdcmd_printtimes); - OSD_RegisterFunction("purgesaves", "purgesaves: deletes obsolete and unreadable save files", osdcmd_purgesaves); - OSD_RegisterFunction("quicksave","quicksave: performs a quick save", osdcmd_quicksave); OSD_RegisterFunction("quickload","quickload: performs a quick load", osdcmd_quickload); diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index 0501c6f7a..3b35aac73 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -28,8 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "i_specialpaths.h" #include "gamecontrol.h" #include "version.h" -#include "statistics.h" -#include "secrets.h" + #include "savegamehelp.h" BEGIN_RR_NS @@ -155,12 +154,17 @@ static FileReader *OpenSavegame(const char *fn) { return nullptr; } - auto file = ReadSavegameChunk("DEMOLITION_RN"); + auto file = ReadSavegameChunk("info.json"); if (!file.isOpen()) { FinishSavegameRead(); return nullptr; } + if (G_ValidateSavegame(file, nullptr) <= 0) + { + FinishSavegameRead(); + return nullptr; + } file = ReadSavegameChunk("snapshot.dat"); if (!file.isOpen()) { @@ -170,130 +174,9 @@ static FileReader *OpenSavegame(const char *fn) return new FileReader(std::move(file)); } -static void ReadSaveGameHeaders_CACHE1D(TArray& saves) -{ - savehead_t h; - - for (FString &save : saves) - { - auto fil = OpenSavegame(save); - if (!fil) - continue; - - menusave_t & msv = g_internalsaves[g_numinternalsaves]; - - int32_t k = sv_loadheader(*fil, 0, &h); - delete fil; - if (k) - { - if (k < 0) - msv.isUnreadable = 1; - msv.isOldVer = 1; - } - else - msv.isOldVer = 0; - - msv.isAutoSave = h.isAutoSave(); - - strncpy(msv.brief.path, save.GetChars(), ARRAY_SIZE(msv.brief.path)); - ++g_numinternalsaves; - - if (k >= 0 && h.savename[0] != '\0') - { - memcpy(msv.brief.name, h.savename, ARRAY_SIZE(msv.brief.name)); - } - else - msv.isUnreadable = 1; - } - FinishSavegameRead(); -} - -static void ReadSaveGameHeaders_Internal(void) -{ - FString pattern = M_GetSavegamesPath() + "*.bsv"; - TArray saves; - D_AddWildFile(saves, pattern); - - // potentially overallocating but programmatically simple - int const numfiles = saves.Size(); - size_t const internalsavesize = sizeof(menusave_t) * numfiles; - - g_internalsaves = (menusave_t *)Xrealloc(g_internalsaves, internalsavesize); - - for (int x = 0; x < numfiles; ++x) - g_internalsaves[x].clear(); - - g_numinternalsaves = 0; - ReadSaveGameHeaders_CACHE1D(saves); - - g_nummenusaves = 0; - for (int x = g_numinternalsaves-1; x >= 0; --x) - { - menusave_t & msv = g_internalsaves[x]; - if (!msv.isUnreadable) - { - ++g_nummenusaves; - } - } - size_t const menusavesize = sizeof(menusave_t) * g_nummenusaves; - - g_menusaves = (menusave_t *)Xrealloc(g_menusaves, menusavesize); - - for (int x = 0; x < g_nummenusaves; ++x) - g_menusaves[x].clear(); - - for (int x = g_numinternalsaves-1, y = 0; x >= 0; --x) - { - menusave_t & msv = g_internalsaves[x]; - if (!msv.isUnreadable) - { - g_menusaves[y++] = msv; - } - } - - for (int x = g_numinternalsaves-1; x >= 0; --x) - { - char const * const path = g_internalsaves[x].brief.path; - int const pathlen = Bstrlen(path); - if (pathlen < 12) - continue; - char const * const fn = path + (pathlen-12); - if (fn[0] == 's' && fn[1] == 'a' && fn[2] == 'v' && fn[3] == 'e' && - isdigit(fn[4]) && isdigit(fn[5]) && isdigit(fn[6]) && isdigit(fn[7])) - { - char number[5]; - memcpy(number, fn+4, 4); - number[4] = '\0'; - savecounter.count = Batoi(number)+1; - break; - } - } -} void ReadSaveGameHeaders(void) { - ReadSaveGameHeaders_Internal(); - - if (!cl_autosavedeletion) - return; - - bool didDelete = false; - int numautosaves = 0; - for (int x = 0; x < g_nummenusaves; ++x) - { - menusave_t & msv = g_menusaves[x]; - if (!msv.isAutoSave) - continue; - if (numautosaves >= cl_maxautosaves) - { - G_DeleteSave(msv.brief); - didDelete = true; - } - ++numautosaves; - } - - if (didDelete) - ReadSaveGameHeaders_Internal(); } int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh) @@ -415,7 +298,7 @@ int32_t G_LoadPlayer(savebrief_t & sv) if (status == 2) G_NewGame_EnterLevel(); - else if ((status = sv_loadsnapshot(*fil, 0, &h)) || !ReadStatistics() || !SECRET_Load()) // read the rest... + else if ((status = sv_loadsnapshot(*fil, 0, &h))) // read the rest... { // in theory, we could load into an initial dump first and trivially // recover if things go wrong... @@ -455,52 +338,6 @@ static void G_RestoreTimers(void) lockclock = g_timers.lockclock; } -////////// - - -void G_DeleteSave(savebrief_t const & sv) -{ - if (!sv.isValid()) - return; - - char temp[BMAX_PATH]; - - if (snprintf(temp, sizeof(temp), "%s%s", M_GetSavegamesPath().GetChars(), sv.path)) - { - OSD_Printf("G_SavePlayer: file name \"%s\" too long\n", sv.path); - return; - } - - remove(temp); -} - -void G_DeleteOldSaves(void) -{ - ReadSaveGameHeaders(); - - for (int x = 0; x < g_numinternalsaves; ++x) - { - menusave_t const & msv = g_internalsaves[x]; - if (msv.isOldVer || msv.isUnreadable) - G_DeleteSave(msv.brief); - } -} - -uint16_t G_CountOldSaves(void) -{ - ReadSaveGameHeaders(); - - int bad = 0; - for (int x = 0; x < g_numinternalsaves; ++x) - { - menusave_t const & msv = g_internalsaves[x]; - if (msv.isOldVer || msv.isUnreadable) - ++bad; - } - - return bad; -} - int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) { #ifdef __ANDROID__ @@ -519,29 +356,28 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) if (sv.isValid()) { - fn.Format("%s%s", M_GetSavegamesPath().GetChars(), sv.path); + fn = G_BuildSaveName(sv.path); OpenSaveGameForWrite(fn); fil = WriteSavegameChunk("snapshot.dat"); } else { - static char const SaveName[] = "save0000.bsv"; - fn.Format("%s%s", M_GetSavegamesPath().GetChars(), SaveName); + fn = G_BuildSaveName("save0000"); auto fnp = fn.LockBuffer(); - char* zeros = fnp + (fn.Len() - 8); - fil = savecounter.opennextfile(fnp, zeros); + char* zeros = strstr(fnp, "0000"); + fil = savecounter.opennextfile(fnp, zeros); // fixme: Rewrite this so that it won't create the file. + fn.UnlockBuffer(); if (fil) { delete fil; - remove(fnp); - OpenSaveGameForWrite(fnp); + remove(fn); + OpenSaveGameForWrite(fn); fil = WriteSavegameChunk("snapshot.dat"); } - fn.UnlockBuffer(); savecounter.count++; - // don't copy the mod dir into sv.path - Bstrcpy(sv.path, fn + (fn.Len() - (ARRAY_SIZE(SaveName) - 1))); + // don't copy the mod dir into sv.path (G_BuildSaveName guarantees the presence of a slash.) + Bstrcpy(sv.path, strrchr(fn, '/') + 1); } if (!fil) @@ -567,8 +403,7 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) // SAVE! sv_saveandmakesnapshot(fw, sv.name, 0, 0, 0, 0, isAutoSave); - SaveStatistics(); - SECRET_Save(); + fw.Close(); FinishSavegameWrite(); @@ -1385,6 +1220,8 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i Bstrncpyz(h.savename, name, sizeof(h.savename)); auto fw = WriteSavegameChunk("header.dat"); fw->Write(&h, sizeof(savehead_t)); + + G_WriteSaveHeader(name, currentboardfilename, g_mapInfo[(MAXLEVELS * ud.volume_number) + ud.level_number].name); } else { diff --git a/source/rr/src/savegame.h b/source/rr/src/savegame.h index d4f912af6..705698488 100644 --- a/source/rr/src/savegame.h +++ b/source/rr/src/savegame.h @@ -117,9 +117,6 @@ int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h); int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h); int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave = false); void sv_freemem(); -void G_DeleteSave(savebrief_t const & sv); -void G_DeleteOldSaves(void); -uint16_t G_CountOldSaves(void); int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave); int32_t G_LoadPlayer(savebrief_t & sv); int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh); diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 111ac1878..9a60d6fc3 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -2382,6 +2382,7 @@ struct GameInterface : ::GameInterface void set_hud_layout(int size) override; void set_hud_scale(int size) override; bool mouseInactiveConditional(bool condition) override; + FSavegameInfo GetSaveSig() override; }; diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index 0144da70d..b4ab5e12b 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -53,6 +53,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "fx_man.h" #include "music.h" #include "text.h" +#include "version.h" #include "colormap.h" #include "config.h" @@ -4737,5 +4738,10 @@ void ResetPalette(PLAYERp pp) // vim:ts=4:sw=4:enc=utf-8: +FSavegameInfo GameInterface::GetSaveSig() +{ + return { SAVESIG_SW, MINSAVEVER_SW, SAVEVER_SW }; +} + END_SW_NS diff --git a/source/sw/src/save.cpp b/source/sw/src/save.cpp index 7aafcf519..cb61d11ff 100644 --- a/source/sw/src/save.cpp +++ b/source/sw/src/save.cpp @@ -245,6 +245,15 @@ int SaveGame(short save_num) OrgTileP otp, next_otp; Saveable_Init(); + + +#if 0 // A lot of work is needed here... (Thank God for all the macros around the load/save functions. :) ) + FStringf base("save%04d", save_num); + auto game_name = G_BuildSaveName(base); + OpenSaveGameForWrite(game_name); + G_WriteSaveHeader(SaveGameDescr[save_num], LevelInfo[Level].LevelName, LevelInfo[Level].Description); + auto fil = WriteSavegameChunk("snapshot.sw"); +#endif snprintf(game_name, 256, "%sgame%d.sav", M_GetSavegamesPath().GetChars(), save_num); if ((fil = MOPEN_WRITE(game_name)) == MOPEN_WRITE_ERR) From a4a4b230fd22713b11ae5e3ed5e5b085b963898f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 27 Nov 2019 17:57:45 +0100 Subject: [PATCH 030/203] - deleted a large batch of code from the menu that is no longer needed. --- source/duke3d/src/menus.cpp | 829 +----------------------------------- 1 file changed, 1 insertion(+), 828 deletions(-) diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index 7af81181a..840a304ca 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -3407,76 +3407,6 @@ static void Menu_TextFormSubmit(char *input) } -static void Menu_FileSelectInit(MenuFileSelect_t *object) -{ - // Same crap as everywhere - it expects the user to dump all the shit in the game directory so that it gets in the way of everything. - // Needs to be redone - or removed. - if (usermapfolder) - { - } - else - { - } -#if 0 - fnlist_clearnames(&object->fnlist); - - if (object->destination[0] == 0) - { - BDIR * usermaps = Bopendir(object->startdir); - if (usermaps) - { - Bclosedir(usermaps); - Bstrcpy(object->destination, object->startdir); - } - else - Bstrcpy(object->destination, "./"); - } - Bcorrectfilename(object->destination, 1); - - fnlist_getnames(&object->fnlist, object->destination, object->pattern, 0, 0); - object->findhigh[0] = object->fnlist.finddirs; - object->findhigh[1] = object->fnlist.findfiles; - - for (int i = 0; i < 2; ++i) - { - object->scrollPos[i] = 0; - klistbookends(object->findhigh[i]); - } - - object->currentList = 0; - if (object->findhigh[1]) - object->currentList = 1; - -#endif - inputState.keyFlushChars(); -} - -static void Menu_FileSelect(int32_t input) -{ - switch (g_currentMenu) - { - case MENU_NETUSERMAP: - if ((g_netServer || ud.multimode > 1)) - Net_SendUserMapName(); - fallthrough__; - case MENU_USERMAP: - if (input) - { - ud.m_volume_number = 0; - m_level_number = 7; - - if (g_skillCnt > 0) - Menu_AnimateChange(MENU_SKILL, MA_Advance); - else - Menu_StartGameWithoutSkill(); - } - break; - - default: - break; - } -} - static void Menu_AboutToStartDisplaying(Menu_t * m) @@ -4435,107 +4365,7 @@ static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *current break; } -#ifdef MENU_ENABLE_RANGEDOUBLE - case RangeDouble: - { - MenuRangeDouble_t *object = (MenuRangeDouble_t*)entry->entry; - int32_t s, p; - int32_t z = entry->font->cursorScale; - Menu_GetFmt(object->font, status|MT_RightSide, &s, &z); - - if (status & MT_Disabled) - p = ud.slidebar_paldisabled; - else if (status & MT_Selected) - p = ud.slidebar_palselected; - else - p = 0; - - const int32_t slidebarwidth = mulscale16(tilesiz[SLIDEBAR].x * ud.menu_slidebarz, z); - const int32_t slidebarheight = mulscale16(tilesiz[SLIDEBAR].y * ud.menu_slidebarz, z); - - if (status & MT_XRight) - x -= slidebarwidth; - else - mousewidth += slidebarwidth; - - const int32_t slidebarx = origin.x + x; - const int32_t slidebary = origin.y + y_upper + y + (((height - slidebarheight)>>17)<<16) - menu->scrollPos; - - rotatesprite_ybounds(slidebarx, slidebary, mulscale16(ud.menu_slidebarz, z), 0, SLIDEBAR, s, p, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); - - const int32_t slideregionwidth = mulscale16((tilesiz[SLIDEBAR].x * ud.menu_slidebarz) - (ud.menu_slidebarmargin<<1) - (tilesiz[SLIDEBAR+1].x * ud.menu_slidecursorz), z); - const int32_t slidepointx = slidebarx + mulscale16(ud.menu_slidebarmargin, z) + lrint((double) slideregionwidth * (*object->variable - object->min) / (object->max - object->min)); - const int32_t slidepointy = slidebary + mulscale16(((tilesiz[SLIDEBAR].y)>>1 * ud.menu_slidebarz) - ((tilesiz[SLIDEBAR+1].y)>>1 * ud.menu_slidecursorz), z); - - rotatesprite_ybounds(slidepointx, slidepointy, mulscale16(ud.menu_slidecursorz, z), 0, SLIDEBAR+1, s, p, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); - - if (object->flags & DisplayTypeMask) - { - status |= MT_XRight; - - double onehundredpercent = object->onehundredpercent; - if (onehundredpercent == 0.) - onehundredpercent = 1.; - - switch (object->flags & DisplayTypeMask) - { - case DisplayTypeInteger: - Bsprintf(tempbuf, "%.2f", *object->variable); - break; - case DisplayTypePercent: - Bsprintf(tempbuf, "%ld%%", lrint(*object->variable * 100. / onehundredpercent)); - break; - case DisplayTypeNormalizedDecimal: - Bsprintf(tempbuf, "%.2f", *object->variable / onehundredpercent); - break; - } - - Menu_Text(origin.x + x - (4<<16), origin.y + y_upper + y + ((height>>17)<<16) - menu->scrollPos, object->font, tempbuf, status, ydim_upper, ydim_lower); - } - - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - if (!m_mousecaught && (inputState.mouseClickState() == MOUSE_PRESSED || inputState.mouseClickState() == MOUSE_HELD)) - { - const int32_t slidepointhalfwidth = mulscale16((2+tilesiz[SLIDEBAR+1].x)<<15, z); - const int32_t slideregionx = slidebarx + slidepointhalfwidth; - - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - - if (entry->flags & MEF_Disabled) - break; - - // region between the x-midline of the slidepoint at the extremes slides proportionally - if (!Menu_MouseOutsideBounds(&m_mousepos, slideregionx, mousey, slideregionwidth, height)) - { - Menu_RunInput_EntryRangeDouble_MovementArbitrary(/*entry, */object, (object->max - object->min) * (m_mousepos.x - slideregionx) / slideregionwidth + object->min); - - m_mousecaught = 1; - } - // region outside the x-midlines clamps to the extremes - else if (!Menu_MouseOutsideBounds(&m_mousepos, slidebarx, mousey, slidebarwidth, height)) - { - if (m_mousepos.x > slideregionx + ((slideregionwidth>>17)<<16)) - Menu_RunInput_EntryRangeDouble_MovementVerify(/*entry, */object, object->max); - else - Menu_RunInput_EntryRangeDouble_MovementVerify(/*entry, */object, object->min); - - m_mousecaught = 1; - } - } - } - - break; - } -#endif case String: { auto object = (MenuString_t*)entry->entry; @@ -4893,130 +4723,7 @@ static void Menu_Run(Menu_t *cm, const vec2_t origin) break; } - case FileSelect: - { -#if 0 - auto object = (MenuFileSelect_t*)cm->object; - const int32_t MenuFileSelect_scrollbar_rightedge[2] = { 160<<16, 284<<16 }; - int32_t i, selected = 0; - Menu_Pre(cm->menuID); - - Menu_PreDrawBackground(cm->menuID, origin); - - if (object->title != NoTitle) - Menu_DrawTopBar(origin); - - - // black translucent background underneath file lists - Menu_BlackRectangle(origin.x + (36<<16), origin.y + (42<<16), 248<<16, 123<<16, 1|32); - - // path - Bsnprintf(tempbuf, sizeof(tempbuf), "Path: %s", object->destination); - mgametext(origin.x + object->format[0]->pos.x, origin.y + (32<<16), tempbuf); - - uint8_t column_status[2] = { 0, MT_RightSide }; - - for (i = 0; i < 2; ++i) - { - if (object->findhigh[i]) - { - CACHE1D_FIND_REC *dir; - int32_t y = 0; - const int32_t y_upper = object->format[i]->pos.y; - const int32_t y_lower = klabs(object->format[i]->bottomcutoff); - - int32_t totalHeight = 0; - for (dir = object->findhigh[i]->usera; dir; dir = dir->next) - { - y += object->font[i]->get_yline(); - totalHeight = y; - y += object->getMarginBottom(i); - } - y = 0; - - int32_t ydim_upper, ydim_lower; - if (y_upper + totalHeight > y_lower) - { - ydim_upper = ydim_from_200_16(origin.y + y_upper); - ydim_lower = ydim_from_200_16(origin.y + y_lower); - } - else - { - ydim_upper = 0; - ydim_lower = ydim-1; - } - - for (dir = object->findhigh[i]->usera; dir; dir = dir->next) - { - uint8_t status = column_status[i]; - if (dir == object->findhigh[i] && object->currentList == i) - status |= MT_Selected; - - // pal = dir->source==CACHE1D_SOURCE_ZIP ? 8 : 2 - - Menu_Run_AbbreviateNameIntoBuffer(dir->name, USERMAPENTRYLENGTH); - - const int32_t thisx = object->format[i]->pos.x; - const int32_t thisy = y - object->scrollPos[i]; - - int32_t const height = object->font[i]->get_yline(); - - if (0 <= thisy + height && thisy <= klabs(object->format[i]->bottomcutoff) - object->format[i]->pos.y) - { - status |= MT_YCenter; - - const int32_t mousex = origin.x + thisx; - const int32_t mousey = origin.y + y_upper + thisy + ((height>>17)<<16); - - vec2_t textdim = Menu_Text(mousex, mousey, object->font[i], tempbuf, status, ydim_upper, ydim_lower); - - if (MOUSEACTIVECONDITIONAL(cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, textdim.x, object->font[i]->get_yline()))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, textdim.x, object->font[i]->get_yline()))) - { - object->findhigh[i] = dir; - object->currentList = i; - - Menu_RunInput_FileSelect_MovementVerify(object); - } - - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, mousex, mousey, textdim.x, object->font[i]->get_yline())) - { - object->findhigh[i] = dir; - object->currentList = i; - - Menu_RunInput_FileSelect_MovementVerify(object); - - m_mousecaught = 1; - selected = 1; - } - } - } - - y += object->font[i]->get_yline() + object->getMarginBottom(i); - } - - Menu_RunScrollbar(cm, object->format[i], y_upper + totalHeight, &object->scrollPos[i], MenuFileSelect_scrollbar_rightedge[i], origin); - } - } - - Menu_PreDraw(cm->menuID, NULL, origin); - - if (object->title != NoTitle) - Menu_DrawTopBarCaption(object->title, origin); - - if (selected) - { - Menu_RunInput_FileSelect_Select(object); - - S_PlaySound(PISTOL_BODYHIT); - - m_mousecaught = 1; - } -#endif - break; - } case Panel: { @@ -5409,66 +5116,6 @@ static void Menu_RunInput_EntryRangeFloat_Movement(MenuEntry_t *entry, MenuRange Menu_RunInput_EntryRangeFloat_MovementVerify(entry, object, newValue); } -#ifdef MENU_ENABLE_RANGEDOUBLE -static void Menu_RunInput_EntryRangeDouble_MovementVerify(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, double newValue) -{ - if (!Menu_EntryRangeDoubleModify(/*entry, newValue*/)) - *object->variable = newValue; -} - -static void Menu_RunInput_EntryRangeDouble_MovementArbitrary(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, double newValue) -{ - if (object->flags & EnforceIntervals) - { - double const range = object->max - object->min; - double const maxInterval = object->steps - 1; - double const newValueIndex = rint((newValue - object->min) * maxInterval / range); - newValue = newValueIndex * range / maxInterval + object->min; - } - - Menu_RunInput_EntryRangeDouble_MovementVerify(/*entry, */object, newValue); -} - -static void Menu_RunInput_EntryRangeDouble_Movement(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, MenuMovement_t direction) -{ - double const oldValue = *object->variable; - double const range = object->max - object->min; - double const maxInterval = object->steps - 1; - double const oldValueIndex = rint((oldValue - object->min) * maxInterval / range); - double const oldValueQuantized = oldValueIndex * range / maxInterval + object->min; - double newValueIndex = oldValueIndex; - - switch (direction) - { - case MM_Left: - if (oldValueQuantized >= oldValue) - newValueIndex -= 1.; - if (newValueIndex >= 0.) - break; - fallthrough__; - case MM_AllTheWayLeft: - newValueIndex = 0.; - break; - - case MM_Right: - if (oldValueQuantized <= oldValue) - newValueIndex += 1.; - if (newValueIndex <= maxInterval) - break; - fallthrough__; - case MM_AllTheWayRight: - newValueIndex = maxInterval; - break; - - default: - break; - } - - double const newValue = newValueIndex * range / maxInterval + object->min; - Menu_RunInput_EntryRangeDouble_MovementVerify(/*entry, */object, newValue); -} -#endif - static void Menu_RunInput_EntryString_Activate(MenuEntry_t *entry) { auto object = (MenuString_t*)entry->entry; @@ -5509,82 +5156,16 @@ static void Menu_RunInput_EntryString_Cancel(/*MenuEntry_t *entry, */MenuString_ static void Menu_RunInput_FileSelect_MovementVerify(MenuFileSelect_t *object) { -#if 0 - const int32_t listytop = object->format[object->currentList]->pos.y; - const int32_t listybottom = klabs(object->format[object->currentList]->bottomcutoff); - const int32_t ytop = listytop + object->findhigh[object->currentList]->type * (object->font[object->currentList]->get_yline() + object->getMarginBottom(object->currentList)); - const int32_t ybottom = ytop + object->font[object->currentList]->get_yline(); - if (ybottom - object->scrollPos[object->currentList] > listybottom) - object->scrollPos[object->currentList] = ybottom - listybottom; - else if (ytop - object->scrollPos[object->currentList] < listytop) - object->scrollPos[object->currentList] = ytop - listytop; -#endif } static void Menu_RunInput_FileSelect_Movement(MenuFileSelect_t *object, MenuMovement_t direction) { -#if 0 - switch (direction) - { - case MM_Up: - if (!object->findhigh[object->currentList]) - break; - if (object->findhigh[object->currentList]->prev) - { - object->findhigh[object->currentList] = object->findhigh[object->currentList]->prev; - break; - } - fallthrough__; - case MM_End: - object->findhigh[object->currentList] = object->findhigh[object->currentList]->userb; - break; - - case MM_Down: - if (!object->findhigh[object->currentList]) - break; - if (object->findhigh[object->currentList]->next) - { - object->findhigh[object->currentList] = object->findhigh[object->currentList]->next; - break; - } - fallthrough__; - case MM_Home: - object->findhigh[object->currentList] = object->findhigh[object->currentList]->usera; - break; - - case MM_Swap: - object->currentList = !object->currentList; - break; - - default: - break; - } - - Menu_RunInput_FileSelect_MovementVerify(object); -#endif } static void Menu_RunInput_FileSelect_Select(MenuFileSelect_t *object) { -#if 0 - if (!object->findhigh[object->currentList]) - return; - Bstrcat(object->destination, object->findhigh[object->currentList]->name); - - if (object->currentList == 0) - { - Bstrcat(object->destination, "/"); - Bcorrectfilename(object->destination, 1); - - Menu_FileSelectInit(object); - } - else - { - Menu_FileSelect(1); - } -#endif } static void Menu_RunInput(Menu_t *cm) @@ -5652,150 +5233,6 @@ static void Menu_RunInput(Menu_t *cm) case FileSelect: { -#if 0 - auto object = (MenuFileSelect_t*)cm->object; - - if (I_ReturnTrigger() || Menu_RunInput_MouseReturn()) - { - I_ReturnTriggerClear(); - m_mousecaught = 1; - - S_PlaySound(EXITMENUSOUND); - - object->destination[0] = 0; - - Menu_FileSelect(0); - - Menu_AnimateChange(cm->parentID, MA_Return); - } - else if (I_AdvanceTrigger()) - { - I_AdvanceTriggerClear(); - - Menu_RunInput_FileSelect_Select(object); - - S_PlaySound(PISTOL_BODYHIT); - } - else if (inputState.GetKeyStatus(sc_Home)) - { - inputState.ClearKeyStatus(sc_Home); - - Menu_RunInput_FileSelect_Movement(object, MM_Home); - - S_PlaySound(KICK_HIT); - } - else if (inputState.GetKeyStatus(sc_End)) - { - inputState.ClearKeyStatus(sc_End); - - Menu_RunInput_FileSelect_Movement(object, MM_End); - - S_PlaySound(KICK_HIT); - } - else if (inputState.GetKeyStatus(sc_PgUp)) - { - int32_t i; - - CACHE1D_FIND_REC *seeker = object->findhigh[object->currentList]; - - inputState.ClearKeyStatus(sc_PgUp); - - for (i = 0; i < 6; ++i) - { - if (seeker && seeker->prev) - seeker = seeker->prev; - } - - if (seeker) - { - object->findhigh[object->currentList] = seeker; - - Menu_RunInput_FileSelect_MovementVerify(object); - - S_PlaySound(KICK_HIT); - } - } - else if (inputState.GetKeyStatus(sc_PgDn)) - { - int32_t i; - - CACHE1D_FIND_REC *seeker = object->findhigh[object->currentList]; - - inputState.ClearKeyStatus(sc_PgDn); - - for (i = 0; i < 6; ++i) - { - if (seeker && seeker->next) - seeker = seeker->next; - } - - if (seeker) - { - object->findhigh[object->currentList] = seeker; - - Menu_RunInput_FileSelect_MovementVerify(object); - - S_PlaySound(KICK_HIT); - } - } - else if (I_MenuLeft() || I_MenuRight()) - { - I_MenuLeftClear(); - I_MenuRightClear(); - - if ((object->currentList ? object->fnlist.numdirs : object->fnlist.numfiles) > 0) - { - Menu_RunInput_FileSelect_Movement(object, MM_Swap); - - S_PlaySound(KICK_HIT); - } - } - else if (I_MenuUp()) - { - I_MenuUpClear(); - - Menu_RunInput_FileSelect_Movement(object, MM_Up); - - S_PlaySound(KICK_HIT); - } - else if (I_MenuDown()) - { - I_MenuDownClear(); - - Menu_RunInput_FileSelect_Movement(object, MM_Down); - - S_PlaySound(KICK_HIT); - } - else - { - // JBF 20040208: seek to first name matching pressed character - char ch2, ch; - ch = inputState.keyGetChar(); - if (ch > 0 && ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9'))) - { - CACHE1D_FIND_REC *seeker = object->findhigh[object->currentList]->usera; - if (ch >= 'a') - ch -= ('a'-'A'); - while (seeker) - { - ch2 = seeker->name[0]; - if (ch2 >= 'a' && ch2 <= 'z') - ch2 -= ('a'-'A'); - if (ch2 == ch) - break; - seeker = seeker->next; - } - if (seeker) - { - object->findhigh[object->currentList] = seeker; - - Menu_RunInput_FileSelect_MovementVerify(object); - - S_PlaySound(KICK_HIT); - } - } - } -#endif Menu_PreInput(NULL); break; } @@ -5857,199 +5294,6 @@ static void Menu_RunInput(Menu_t *cm) Menu_PreInput(NULL); break; - case Menu: - { - int32_t state; - - auto menu = (MenuMenu_t*)cm->object; - MenuEntry_t *currentry = menu->entrylist[menu->currentEntry]; - - state = Menu_DetermineSpecialState(currentry); - - if (state == 0) - { - if (currentry != NULL) - switch (currentry->type) - { - case Dummy: - case Spacer: - break; - case Link: - if (currentry->flags & MEF_Disabled) - break; - if (I_AdvanceTrigger()) - { - I_AdvanceTriggerClear(); - - Menu_RunInput_EntryLink_Activate(currentry); - - if (g_player[myconnectindex].ps->gm&MODE_MENU) // for skill selection - S_PlaySound(PISTOL_BODYHIT); - } - break; - case Option: - { - auto object = (MenuOption_t*)currentry->entry; - - if (currentry->flags & MEF_Disabled) - break; - - if (I_AdvanceTrigger()) - { - I_AdvanceTriggerClear(); - - Menu_RunInput_EntryOption_Activate(currentry, object); - - S_PlaySound(PISTOL_BODYHIT); - } - else if (I_MenuRight()) - { - I_MenuRightClear(); - - Menu_RunInput_EntryOption_Movement(currentry, object, MM_Right); - - S_PlaySound(PISTOL_BODYHIT); - } - else if (I_MenuLeft()) - { - I_MenuLeftClear(); - - Menu_RunInput_EntryOption_Movement(currentry, object, MM_Left); - - S_PlaySound(PISTOL_BODYHIT); - } - } - break; - case Custom2Col: - if (I_MenuLeft() || I_MenuRight()) - { - I_MenuLeftClear(); - I_MenuRightClear(); - - Menu_RunInput_Menu_Movement(menu, MM_Swap); - - S_PlaySound(KICK_HIT); - } - - if (currentry->flags & MEF_Disabled) - break; - - if (I_AdvanceTrigger()) - { - I_AdvanceTriggerClear(); - - Menu_RunInput_EntryCustom2Col_Activate(currentry); - - S_PlaySound(PISTOL_BODYHIT); - } - break; - case RangeInt32: - { - auto object = (MenuRangeInt32_t*)currentry->entry; - - if (currentry->flags & MEF_Disabled) - break; - - if (I_SliderLeft()) - { - I_SliderLeftClear(); - - Menu_RunInput_EntryRangeInt32_Movement(currentry, object, MM_Left); - - S_PlaySound(KICK_HIT); - } - else if (I_SliderRight()) - { - I_SliderRightClear(); - - Menu_RunInput_EntryRangeInt32_Movement(currentry, object, MM_Right); - - S_PlaySound(KICK_HIT); - } - break; - } - case RangeFloat: - { - auto object = (MenuRangeFloat_t*)currentry->entry; - - if (currentry->flags & MEF_Disabled) - break; - - if (I_SliderLeft()) - { - I_SliderLeftClear(); - - Menu_RunInput_EntryRangeFloat_Movement(currentry, object, MM_Left); - - S_PlaySound(KICK_HIT); - } - else if (I_SliderRight()) - { - I_SliderRightClear(); - - Menu_RunInput_EntryRangeFloat_Movement(currentry, object, MM_Right); - - S_PlaySound(KICK_HIT); - } - break; - } -#ifdef MENU_ENABLE_RANGEDOUBLE - case RangeDouble: - { - MenuRangeDouble_t *object = (MenuRangeDouble_t*)currentry->entry; - - if (currentry->flags & MEF_Disabled) - break; - - if (I_SliderLeft()) - { - I_SliderLeftClear(); - - Menu_RunInput_EntryRangeDouble_Movement(/*currentry, */object, MM_Left); - - S_PlaySound(KICK_HIT); - } - else if (I_SliderRight()) - { - I_SliderRightClear(); - - Menu_RunInput_EntryRangeDouble_Movement(/*currentry, */object, MM_Right); - - S_PlaySound(KICK_HIT); - } - break; - } -#endif - - case String: - { - if (currentry->flags & MEF_Disabled) - break; - - if (I_AdvanceTrigger()) - { - I_AdvanceTriggerClear(); - - Menu_RunInput_EntryString_Activate(currentry); - - S_PlaySound(PISTOL_BODYHIT); - } - - break; - } - } - - if (I_ReturnTrigger() || I_EscapeTrigger() || Menu_RunInput_MouseReturn()) - { - I_ReturnTriggerClear(); - I_EscapeTriggerClear(); - m_mousecaught = 1; - - if (cm->parentID != MENU_CLOSE || (g_player[myconnectindex].ps->gm & MODE_GAME)) - S_PlaySound(EXITMENUSOUND); - - Menu_AnimateChange(cm->parentID, cm->parentAnimation); - } else if (inputState.GetKeyStatus(sc_Home)) { inputState.ClearKeyStatus(sc_Home); @@ -6239,38 +5483,7 @@ void M_DisplayMenus(void) origin.y = ud.returnvar[1]; } - // Determine animation values. - if (totalclock < m_animation.start + m_animation.length) - { - const int32_t screenwidth = scale(240<<16, xdim, ydim); - origin.x = mulscale15(screenwidth, m_animation.in(&m_animation)); - previousOrigin.x = mulscale15(screenwidth, m_animation.out(&m_animation)); - - ud.returnvar[0] = previousOrigin.x; - ud.returnvar[1] = previousOrigin.y; - if (m_animation.previous->type == Menu) - { - ud.returnvar[2] = ((MenuMenu_t *)m_animation.previous->object)->currentEntry; - if (m_animation.previous->menuID == MENU_NEWGAMECUSTOMSUB) - ud.returnvar[3] = M_NEWGAMECUSTOM.currentEntry; - } - VM_OnEventWithReturn(EVENT_DISPLAYINACTIVEMENU, g_player[screenpeek].ps->i, screenpeek, m_animation.previous->menuID); - previousOrigin.x = ud.returnvar[0]; - previousOrigin.y = ud.returnvar[1]; - } - - ud.returnvar[0] = origin.x; - ud.returnvar[1] = origin.y; - if (m_currentMenu->type == Menu) - { - ud.returnvar[2] = ((MenuMenu_t *)m_currentMenu->object)->currentEntry; - if (g_currentMenu == MENU_NEWGAMECUSTOMSUB) - ud.returnvar[3] = M_NEWGAMECUSTOM.currentEntry; - } - VM_OnEventWithReturn(EVENT_DISPLAYMENU, g_player[screenpeek].ps->i, screenpeek, g_currentMenu); - origin.x = ud.returnvar[0]; - origin.y = ud.returnvar[1]; if (m_parentMenu && backgroundOK) { @@ -6308,47 +5521,7 @@ void M_DisplayMenus(void) VM_OnEventWithReturn(EVENT_DISPLAYINACTIVEMENUREST, g_player[screenpeek].ps->i, screenpeek, m_parentMenu->menuID); } - if (totalclock < m_animation.start + m_animation.length) - { - ud.returnvar[0] = previousOrigin.x; - ud.returnvar[1] = previousOrigin.y; - if (m_animation.previous->type == Menu) - { - ud.returnvar[2] = ((MenuMenu_t *)m_animation.previous->object)->currentEntry; - if (m_animation.previous->menuID == MENU_NEWGAMECUSTOMSUB) - ud.returnvar[3] = M_NEWGAMECUSTOM.currentEntry; - } - VM_OnEventWithReturn(EVENT_DISPLAYINACTIVEMENUREST, g_player[screenpeek].ps->i, screenpeek, m_animation.previous->menuID); - } - - ud.returnvar[0] = origin.x; - ud.returnvar[1] = origin.y; - if (m_currentMenu->type == Menu) - { - ud.returnvar[2] = ((MenuMenu_t *)m_currentMenu->object)->currentEntry; - if (g_currentMenu == MENU_NEWGAMECUSTOMSUB) - ud.returnvar[3] = M_NEWGAMECUSTOM.currentEntry; - } - VM_OnEventWithReturn(EVENT_DISPLAYMENUREST, g_player[screenpeek].ps->i, screenpeek, g_currentMenu); - - if (GUICapture & 2) - { - ImGui_Begin_Frame(); - bool b = true; - videoFadeToBlack(1); -#if 0 - ImGui::ShowDemoWindow(&b); - if (!b) -#else - if (!ShowOptionMenu()) -#endif - { - GUICapture &= ~2; - GUICapture |= 4; - } - return; - } - + #if !defined EDUKE32_TOUCH_DEVICES if (tilesiz[CROSSHAIR].x > 0 && mousestatus) From 8492e3c67a3e931594b8552674281ad39e49f03f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 27 Nov 2019 19:31:58 +0100 Subject: [PATCH 031/203] - migrated SW's savegame code to the same containers as the other front ends. Fortunately everything here was wrapped in macros so that it was relatively simple to change. --- source/duke3d/src/menus.h | 88 +++++++++++++++++++-------------------- source/sw/src/mfile.h | 34 ++++++++++----- source/sw/src/save.cpp | 27 ++++++------ 3 files changed, 82 insertions(+), 67 deletions(-) diff --git a/source/duke3d/src/menus.h b/source/duke3d/src/menus.h index bfc02d8ad..00aedb009 100644 --- a/source/duke3d/src/menus.h +++ b/source/duke3d/src/menus.h @@ -56,59 +56,57 @@ enum MenuIndex_t { MENU_NULL = INT32_MIN, // sentinel for "do nothing" MENU_CLOSE = -2, // sentinel for "close the menu"/"no menu" MENU_PREVIOUS = -1, // sentinel for "go to previous menu" - MENU_MAIN = 0, - MENU_MAIN_INGAME = 50, - MENU_EPISODE = 100, + MENU_MAIN = 0, // done + MENU_MAIN_INGAME = 50, // done + MENU_EPISODE = 100, // done MENU_USERMAP = 101, - MENU_NEWGAMECUSTOM = 102, - MENU_NEWGAMECUSTOMSUB = 103, - MENU_SKILL = 110, - MENU_GAMESETUP = 200, + MENU_NEWGAMECUSTOM = 102, // done + MENU_NEWGAMECUSTOMSUB = 103,// done + MENU_SKILL = 110, // done MENU_OPTIONS = 202, - MENU_VIDEOSETUP = 203, - MENU_KEYBOARDSETUP = 204, - MENU_MOUSESETUP = 205, - MENU_JOYSTICKSETUP = 206, - MENU_JOYSTICKBTNS = 207, - MENU_JOYSTICKAXES = 208, - MENU_KEYBOARDKEYS = 209, - MENU_MOUSEBTNS = 210, - MENU_MOUSEADVANCED = 212, - MENU_JOYSTICKAXIS = 213, - MENU_TOUCHSETUP = 214, - MENU_TOUCHSENS = 215, - MENU_TOUCHBUTTONS = 216, - MENU_CONTROLS = 220, - MENU_POLYMOST = 230, - MENU_COLCORR = 231, - MENU_COLCORR_INGAME = 232, - MENU_SCREENSETUP = 233, - MENU_DISPLAYSETUP = 234, - MENU_POLYMER = 240, + MENU_GAMESETUP = 200, + MENU_CHEATS = 800, // IF script hacked + MENU_CHEATENTRY = 801, // IF script hacked + MENU_CHEAT_WARP = 802, + MENU_CHEAT_SKILL = 803, + MENU_DISPLAYSETUP = 234, + MENU_SCREENSETUP = 233, // HUD + MENU_COLCORR = 231, // color correction + MENU_COLCORR_INGAME = 232, // almost the same for ingame - not needed + MENU_VIDEOSETUP = 203, + MENU_POLYMOST = 230, + MENU_POLYMER = 240, // Who needs a renderer that's folding performance-wise with a single light? + MENU_SOUND = 700, + MENU_SOUND_INGAME = 701, // Just the same with different exit logic. + MENU_ADVSOUND = 702, // Only needed for space reasons. Fold into main sound menu. + MENU_PLAYER = 20002, + MENU_MACROS = 20004, + MENU_CONTROLS = 220, + MENU_KEYBOARDSETUP = 204, + MENU_KEYBOARDKEYS = 209, + MENU_MOUSESETUP = 205, + MENU_MOUSEBTNS = 210, // folded with keyboard + MENU_MOUSEADVANCED = 212, + MENU_JOYSTICKSETUP = 206, + MENU_JOYSTICKBTNS = 207, + MENU_JOYSTICKAXES = 208, + MENU_JOYSTICKAXIS = 213, MENU_LOAD = 300, MENU_SAVE = 350, MENU_STORY = 400, MENU_F1HELP = 401, + MENU_CREDITS = 990, + MENU_CREDITS2 = 991, + MENU_CREDITS3 = 992, + MENU_CREDITS4 = 993, + MENU_CREDITS5 = 994, MENU_QUIT = 500, MENU_QUITTOTITLE = 501, MENU_QUIT_INGAME = 502, - MENU_NETSETUP = 600, - MENU_NETWAITMASTER = 601, - MENU_NETWAITVOTES = 603, - MENU_SOUND = 700, - MENU_SOUND_INGAME = 701, - MENU_ADVSOUND = 702, + MENU_SAVESETUP = 750, + MENU_SAVECLEANVERIFY = 751, - MENU_CHEATS = 800, - MENU_CHEATENTRY = 801, - MENU_CHEAT_WARP = 802, - MENU_CHEAT_SKILL = 803, - MENU_CREDITS = 990, - MENU_CREDITS2 = 991, - MENU_CREDITS3 = 992, - MENU_CREDITS4 = 993, - MENU_CREDITS5 = 994, MENU_LOADVERIFY = 1000, MENU_LOADDELVERIFY = 1100, MENU_NEWVERIFY = 1500, @@ -123,9 +121,11 @@ enum MenuIndex_t { MENU_ADULTPASSWORD = 10001, MENU_RESETPLAYER = 15000, MENU_BUYDUKE = 20000, + + MENU_NETSETUP = 600, + MENU_NETWAITMASTER = 601, + MENU_NETWAITVOTES = 603, MENU_NETWORK = 20001, - MENU_PLAYER = 20002, - MENU_MACROS = 20004, MENU_NETHOST = 20010, MENU_NETOPTIONS = 20011, MENU_NETUSERMAP = 20012, diff --git a/source/sw/src/mfile.h b/source/sw/src/mfile.h index 4702e170c..6ee541090 100644 --- a/source/sw/src/mfile.h +++ b/source/sw/src/mfile.h @@ -26,19 +26,31 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "compat.h" #include "cache1d.h" +#include "savegamehelp.h" BEGIN_SW_NS -typedef FILE* MFILE_WRITE; -typedef FILE* MFILE_READ; +typedef FileWriter* MFILE_WRITE; +typedef FileReader* MFILE_READ; + +inline size_t MREAD(void* buf, size_t size, size_t nelem, FileReader* handle) +{ + return handle->Read(buf, size * nelem) / size; +} + +inline size_t MWRITE(void* buf, size_t size, size_t nelem, FileWriter* handle) +{ + return handle->Write(buf, size * nelem) / size; +} + +inline void MCLOSE_WRITE(FileWriter* handle) +{ + FinishSavegameWrite(); +} + +inline void MCLOSE_READ(FileReader* handle) +{ + FinishSavegameRead(); +} -// This needs some real fixing... -#define MREAD(ptr, size, num,handle) fread((ptr),(size),(num),(handle)) -#define MWRITE(ptr, size, num,handle) fwrite((ptr),(size),(num),(handle)) -#define MOPEN_WRITE(name) fopen(name,"wb") -#define MOPEN_READ(name) fopen(name,"rb") -#define MCLOSE_WRITE(handle) fclose(handle) -#define MCLOSE_READ(handle) fclose(handle) -#define MOPEN_WRITE_ERR nullptr -#define MOPEN_READ_ERR nullptr END_SW_NS diff --git a/source/sw/src/save.cpp b/source/sw/src/save.cpp index cb61d11ff..56f5c242e 100644 --- a/source/sw/src/save.cpp +++ b/source/sw/src/save.cpp @@ -56,6 +56,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "colormap.h" #include "player.h" #include "i_specialpaths.h" +#include "savegamehelp.h" //void TimerFunc(task * Task); BEGIN_SW_NS @@ -240,24 +241,17 @@ int SaveGame(short save_num) PANEL_SPRITE tpanel_sprite; PANEL_SPRITEp psp,cur,next; SECTOR_OBJECTp sop; - char game_name[256]; int cnt = 0, saveisshot=0; OrgTileP otp, next_otp; Saveable_Init(); -#if 0 // A lot of work is needed here... (Thank God for all the macros around the load/save functions. :) ) FStringf base("save%04d", save_num); auto game_name = G_BuildSaveName(base); OpenSaveGameForWrite(game_name); G_WriteSaveHeader(SaveGameDescr[save_num], LevelInfo[Level].LevelName, LevelInfo[Level].Description); - auto fil = WriteSavegameChunk("snapshot.sw"); -#endif - - snprintf(game_name, 256, "%sgame%d.sav", M_GetSavegamesPath().GetChars(), save_num); - if ((fil = MOPEN_WRITE(game_name)) == MOPEN_WRITE_ERR) - return -1; + fil = WriteSavegameChunk("snapshot.sw"); MWRITE(&GameVersion,sizeof(GameVersion),1,fil); @@ -711,6 +705,7 @@ int SaveGame(short save_num) int LoadGameFullHeader(short save_num, char *descr, short *level, short *skill) { +#if 0 // only used by the menu. Will go away soon. MFILE_READ fil; char game_name[256]; short tile; @@ -738,10 +733,14 @@ int LoadGameFullHeader(short save_num, char *descr, short *level, short *skill) MCLOSE_READ(fil); return tile; +#else + return 0; +#endif } void LoadGameDescr(short save_num, char *descr) { +#if 0 MFILE_READ fil; char game_name[256]; short tile; @@ -761,6 +760,7 @@ void LoadGameDescr(short save_num, char *descr) MREAD(descr, sizeof(SaveGameDescr[0]),1,fil); MCLOSE_READ(fil); +#endif } @@ -780,7 +780,6 @@ int LoadGame(short save_num) int16_t data_ndx; PANEL_SPRITEp psp,next,cur; PANEL_SPRITE tpanel_sprite; - char game_name[256]; OrgTileP otp, next_otp; int RotNdx; @@ -791,9 +790,13 @@ int LoadGame(short save_num) Saveable_Init(); - snprintf(game_name, 256, "%sgame%d.sav", M_GetSavegamesPath().GetChars(), save_num); - if ((fil = MOPEN_READ(game_name)) == MOPEN_READ_ERR) - return -1; + FStringf base("save%04d", save_num); + auto game_name = G_BuildSaveName(base); + OpenSaveGameForRead(game_name); + + auto filr = ReadSavegameChunk("snapshot.sw"); + if (!filr.isOpen()) return -1; + fil = &filr; MREAD(&i,sizeof(i),1,fil); if (i != GameVersion) From 2c36e986b9eb3b7fcc0701eaada2721376afa102 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 27 Nov 2019 22:41:15 +0100 Subject: [PATCH 032/203] - fixed most issues with Ion Fury's game startup menus. --- source/common/menu/listmenu.cpp | 7 +- source/common/menu/menu.cpp | 5 +- source/common/menu/menu.h | 1 + source/common/menu/menudef.cpp | 10 ++- wadsrc/static/demolition/menudef.txt | 105 ++++++++++++++++++++++----- 5 files changed, 103 insertions(+), 25 deletions(-) diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 9138a840a..b6033dd28 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -130,6 +130,7 @@ bool DListMenu::Responder (event_t *ev) if (mDesc->mItems[i]->CheckHotkey(ch)) { mDesc->mSelectedItem = i; + SelectionChanged(); gi->MenuSound(GameInterface::SelectSound); return true; } @@ -139,6 +140,7 @@ bool DListMenu::Responder (event_t *ev) if (mDesc->mItems[i]->CheckHotkey(ch)) { mDesc->mSelectedItem = i; + SelectionChanged(); gi->MenuSound(GameInterface::SelectSound); return true; } @@ -166,6 +168,7 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller) if (--mDesc->mSelectedItem < 0) mDesc->mSelectedItem = mDesc->mItems.Size()-1; } while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); + SelectionChanged(); gi->MenuSound(GameInterface::SelectSound); return true; @@ -175,6 +178,7 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller) if (++mDesc->mSelectedItem >= (int)mDesc->mItems.Size()) mDesc->mSelectedItem = 0; } while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); + SelectionChanged(); gi->MenuSound(GameInterface::SelectSound); return true; @@ -228,6 +232,7 @@ bool DListMenu::MouseEvent(int type, int xx, int yy) // no sound. This is too noisy. } mDesc->mSelectedItem = i; + SelectionChanged(); mDesc->mItems[i]->MouseEvent(type, x, y); return true; } @@ -264,7 +269,7 @@ void DListMenu::Drawer () PreDraw(); for(unsigned i=0;imItems.Size(); i++) { - if (mDesc->mItems[i]->mEnabled) mDesc->mItems[i]->Drawer(this, origin, mDesc->mSelectedItem == (int)i); + mDesc->mItems[i]->Drawer(this, origin, mDesc->mSelectedItem == (int)i); } if (mDesc->mSelectedItem >= 0 && mDesc->mSelectedItem < (int)mDesc->mItems.Size()) mDesc->mItems[mDesc->mSelectedItem]->DrawSelector(mDesc->mSelectOfsX, mDesc->mSelectOfsY, mDesc->mSelector); diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index c3823d631..101de17ad 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -454,7 +454,6 @@ bool M_SetMenu(FName menu, int param, FName caller) case NAME_CustomSubMenu1: GameStartupInfo.CustomLevel2 = param; gi->CustomMenuSelection(GameStartupInfo.CustomLevel1, param); - menu = FName(ENamedName(menu + param)); break; case NAME_SkillMenu: @@ -469,6 +468,10 @@ bool M_SetMenu(FName menu, int param, FName caller) gi->StartGame(GameStartupInfo); return false; + case NAME_CustomSubMenu1: + menu = ENamedName(menu + param); + break; + #if 0 case NAME_StartgameConfirm: { diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 545de2b20..6167ecaa4 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -499,6 +499,7 @@ public: bool MouseEvent(int type, int x, int y); void Ticker (); void Drawer (); + virtual void SelectionChanged() {} void SetFocus(FListMenuItem *fc) { mFocusControl = fc; diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index fdda98779..279c6d427 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -1100,7 +1100,7 @@ static void BuildEpisodeMenu() FMenuDescriptor** desc = MenuDescriptors.CheckKey(NAME_CustomGameMenu); if (desc != NULL && (*desc)->mType == MDESC_ListMenu) { - FListMenuDescriptor* ld = static_cast(*desc); + FListMenuDescriptor* ldo = static_cast(*desc); for (MenuGameplayStemEntry const& stem : g_MenuGameplayEntries) { @@ -1112,7 +1112,8 @@ static void BuildEpisodeMenu() FMenuDescriptor** sdesc = MenuDescriptors.CheckKey(FName(ENamedName(NAME_CustomSubMenu1 + e))); if (sdesc != NULL && (*sdesc)->mType == MDESC_ListMenu) { - FListMenuDescriptor* ld = static_cast(*desc); + FListMenuDescriptor* ld = static_cast(*sdesc); + ld->mCaption = entry.name; for (MenuGameplayEntry const& subentry : stem.subentries) { @@ -1123,15 +1124,16 @@ static void BuildEpisodeMenu() if (subentry.flags & MGE_Locked) li->mEnabled = false; if (subentry.flags & MGE_Hidden) li->mHidden = true; - + ld->mItems.Push(li); ++s; } } FName link = entry.flags & MGE_UserContent ? NAME_UsermapMenu : s == 0 ? NAME_SkillMenu : NAME_CustomSubMenu1; - auto li = new FListMenuItemNativeText(ld->mXpos, 0, 0, 0, entry.name, NIT_BigFont, NIT_ActiveColor, 1.f, link, link == NAME_CustomSubMenu1 ? e : -1); + auto li = new FListMenuItemNativeText(ldo->mXpos, 0, 0, 0, entry.name, NIT_BigFont, NIT_ActiveColor, 1.f, link, e); if (entry.flags & MGE_Locked) li->mEnabled = false; if (entry.flags & MGE_Hidden) li->mHidden = true; + ldo->mItems.Push(li); e++; } } diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index b9b0a345b..3fc40df5a 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -147,9 +147,18 @@ LISTMENU "SkillMenu" { ifgame(Duke, Nam, WW2GI, Fury) // Ion Fury does not use this menu. { + ifgame(fury) + { + position 160, 55, 115 + fixedspacing 2 + } + else + { + position 160, 55, 115 + centermenu + animatedtransition + } caption "$MNU_SELECTSKILL" - position 160, 55, 135 - centermenu fixedspacing 5 class "Duke.ListMenu" animatedtransition @@ -160,82 +169,140 @@ LISTMENU "SkillMenu" // The custom menus are only supported by the EDuke32 frontend. LISTMENU "CustomGameMenu" { + caption "$MNU_NEWGAME" position 160, 48, 142 - centermenu - fixedspacing 5 + ifgame(fury) + { + fixedspacing 2 + } + else + { + fixedspacing 5 + animatedtransition + } ScriptId 102 class "Duke.ListMenu" - animatedtransition + centermenu } LISTMENU "CustomSubMenu1" { position 160, 48, 142 centermenu - fixedspacing 5 + ifgame(fury) + { + fixedspacing 2 + } + else + { + fixedspacing 5 + animatedtransition + } + centermenu ScriptId 103 class "Duke.ListMenu" - animatedtransition } LISTMENU "CustomSubMenu2" { position 160, 48, 142 + ifgame(fury) + { + fixedspacing 2 + } + else + { + fixedspacing 5 + animatedtransition + } centermenu - fixedspacing 5 ScriptId 103 class "Duke.ListMenu" - animatedtransition } LISTMENU "CustomSubMenu3" { position 160, 48, 142 + ifgame(fury) + { + fixedspacing 2 + } + else + { + fixedspacing 5 + animatedtransition + } centermenu - fixedspacing 5 ScriptId 103 class "Duke.ListMenu" - animatedtransition } LISTMENU "CustomSubMenu4" { position 160, 48, 142 + ifgame(fury) + { + fixedspacing 2 + } + else + { + fixedspacing 5 + animatedtransition + } centermenu - fixedspacing 5 ScriptId 103 class "Duke.ListMenu" - animatedtransition } LISTMENU "CustomSubMenu5" { position 160, 48, 142 + ifgame(fury) + { + fixedspacing 2 + } + else + { + fixedspacing 5 + animatedtransition + } centermenu - fixedspacing 5 ScriptId 103 class "Duke.ListMenu" - animatedtransition } LISTMENU "CustomSubMenu6" { position 160, 48, 142 + ifgame(fury) + { + fixedspacing 2 + } + else + { + fixedspacing 5 + animatedtransition + } centermenu - fixedspacing 5 ScriptId 103 class "Duke.ListMenu" - animatedtransition } LISTMENU "CustomSubMenu7" { position 160, 48, 142 + ifgame(fury) + { + fixedspacing 2 + } + else + { + fixedspacing 5 + animatedtransition + } centermenu - fixedspacing 5 ScriptId 103 class "Duke.ListMenu" - animatedtransition } LISTMENU "MultiMenu" From 5f5fe271f79f365d9448e36bffccfe7cf09ca835 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 27 Nov 2019 23:35:12 +0100 Subject: [PATCH 033/203] - fixed handling of the custom game mode menus in Ion Fury. Sadly the scripting which necessitates this all is such a hack that it's probably necessary to fix again if the next project comes along that uses the same kind of "creativity" instead of providing a robust implementation. --- source/common/menu/menu.cpp | 10 ++++++++-- source/common/menu/menudef.cpp | 15 +++++++++------ source/duke3d/src/d_menu.cpp | 10 ++++++++++ source/duke3d/src/gamestructures.cpp | 2 +- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 101de17ad..df7a8d36c 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -445,13 +445,19 @@ bool M_SetMenu(FName menu, int param, FName caller) case NAME_CustomGameMenu: GameStartupInfo.CustomLevel1 = param; GameStartupInfo.CustomLevel2 = -1; - GameStartupInfo.Episode = -1; - GameStartupInfo.Level = -1; + GameStartupInfo.Episode = 0; // Set start to E1L1 so that even if the script fails to set the starting level it is set to something valid. + GameStartupInfo.Level = 0; GameStartupInfo.Skill = gDefaultSkill; gi->CustomMenuSelection(param, -1); break; case NAME_CustomSubMenu1: + case NAME_CustomSubMenu2: + case NAME_CustomSubMenu3: + case NAME_CustomSubMenu4: + case NAME_CustomSubMenu5: + case NAME_CustomSubMenu6: + case NAME_CustomSubMenu7: GameStartupInfo.CustomLevel2 = param; gi->CustomMenuSelection(GameStartupInfo.CustomLevel1, param); break; diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 279c6d427..2a7ca894c 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -1139,14 +1139,17 @@ static void BuildEpisodeMenu() } if (e > 0) { - FMenuDescriptor** desc = MenuDescriptors.CheckKey(NAME_MainMenu); - if (desc != NULL && (*desc)->mType == MDESC_ListMenu) + for (auto name : { NAME_MainMenu, NAME_IngameMenu }) { - FListMenuDescriptor* ld = static_cast(*desc); - auto li = ld->mItems[0]; - if (li->GetAction(nullptr) == NAME_EpisodeMenu) + FMenuDescriptor** desc = MenuDescriptors.CheckKey(name); + if (desc != NULL && (*desc)->mType == MDESC_ListMenu) { - li->SetAction(NAME_CustomGameMenu); + FListMenuDescriptor* ld = static_cast(*desc); + auto li = ld->mItems[0]; + if (li->GetAction(nullptr) == NAME_EpisodeMenu) + { + li->SetAction(NAME_CustomGameMenu); + } } } } diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index e51a8f022..310b6743c 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -270,6 +270,16 @@ class DukeListMenu : public DListMenu using Super = DListMenu; protected: + void SelectionChanged() override + { + if (mDesc->mScriptId == 110) + { + // Hack alert: Ion Fury depends on the skill getting set globally when the selection changes because the script cannot detect actual selection changes. + // Yuck! + ud.m_player_skill = mDesc->mSelectedItem+1; + } + } + virtual void CallScript(int event, bool getorigin = false) { ud.returnvar[0] = int(origin.X * 65536); diff --git a/source/duke3d/src/gamestructures.cpp b/source/duke3d/src/gamestructures.cpp index 40727c8fe..291878e69 100644 --- a/source/duke3d/src/gamestructures.cpp +++ b/source/duke3d/src/gamestructures.cpp @@ -921,7 +921,7 @@ void __fastcall VM_SetPlayer(int const playerNum, int const labelNum, int const else if ((ps.gm & MODE_MENU) && !(newValue & MODE_MENU)) Menu_Close(playerNum); */ - ps.gm = newValue & ~MODE_MENU; + ps.gm = (newValue & ~MODE_MENU) | (ps.gm & MODE_MENU); break; case PLAYER_GOTWEAPON: From ef3ad690dab8ca8613b53190f85c804c92cd289e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 00:02:36 +0100 Subject: [PATCH 034/203] - initial work on credits screens. --- source/duke3d/src/d_menu.cpp | 157 +++++++++++++++++++++++++++++++++++ source/duke3d/src/menus.cpp | 150 --------------------------------- 2 files changed, 157 insertions(+), 150 deletions(-) diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 310b6743c..1341f646b 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -132,6 +132,11 @@ void Menu_Init(void) #endif } +static void Menu_DrawBackground(const DVector2 &origin) +{ + rotatesprite_fs(int(origin.X * 65536) + (MENU_MARGIN_CENTER << 16), int(origin.Y * 65536) + (100 << 16), 65536L, 0, MENUSCREEN, 16, 0, 10 + 64); +} + static void Menu_DrawTopBar(const DVector2 &origin) { if ((G_GetLogoFlags() & LOGO_NOTITLEBAR) == 0) @@ -196,6 +201,15 @@ static vec2_t Menu_Text(int32_t x, int32_t y, const MenuFont_t* font, const char return G_ScreenText(font->tilenum, x, y, z, 0, 0, t, s, p, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, font->emptychar.x, font->emptychar.y, font->between.x, ybetween, f, 0, ydim_upper, xdim - 1, ydim_lower); } +static vec2_t mgametextcenterat(int32_t x, int32_t y, char const* t, int32_t f = 0) +{ + return G_ScreenText(MF_Bluefont.tilenum, x, y, MF_Bluefont.zoom, 0, 0, t, 0, MF_Bluefont.pal, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags | f | TEXT_XCENTER, 0, 0, xdim - 1, ydim - 1); +} +static vec2_t mgametextcenter(int32_t x, int32_t y, char const* t, int32_t f = 0) +{ + return mgametextcenterat((MENU_MARGIN_CENTER << 16) + x, y, t, f); +} + static int32_t Menu_CursorShade(void) { return VM_OnEventWithReturn(EVENT_MENUCURSORSHADE, -1, myconnectindex, 4 - (sintable[((int32_t)totalclock << 4) & 2047] >> 11)); @@ -387,6 +401,149 @@ class MainMenu : public DukeListMenu } }; +class DukeCreditScreen : public DMenu +{ + int screen; + + void shadowminitext(int32_t x, int32_t y, const char* t, int32_t p) + { + int32_t f = 0; + + if (!minitext_lowercase) + f |= TEXT_UPPERCASE; + + G_ScreenTextShadow(1, 1, MINIFONT, x, y, 65536, 0, 0, t, 0, p, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, 4 << 16, 8 << 16, 1 << 16, 0, f, 0, 0, xdim - 1, ydim - 1); + } + + + void Drawer() + { + if (VOLUMEALL && PLUTOPAK) + { + rotatesprite_fs(int(origin.X * 65536) + (MENU_MARGIN_CENTER << 16), int(origin.Y * 65536) + (100 << 16), 65536L, 0, 2504 + screen, 0, 0, 10 + 64); + return; + } + Menu_DrawBackground(origin); + + // On the latest version there's real graphics for this. + int32_t m, l; + switch (screen) + { + case 0: + m = int(origin.X * 65536) + (20 << 16); + l = int(origin.Y * 65536) + (33 << 16); + + shadowminitext(m, l, "Original Concept", 12); l += 7 << 16; + shadowminitext(m, l, "Todd Replogle and Allen H. Blum III", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Produced & Directed By", 12); l += 7 << 16; + shadowminitext(m, l, "Greg Malone", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Executive Producer", 12); l += 7 << 16; + shadowminitext(m, l, "George Broussard", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "BUILD Engine", 12); l += 7 << 16; + shadowminitext(m, l, "Ken Silverman", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Game Programming", 12); l += 7 << 16; + shadowminitext(m, l, "Todd Replogle", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "3D Engine/Tools/Net", 12); l += 7 << 16; + shadowminitext(m, l, "Ken Silverman", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Network Layer/Setup Program", 12); l += 7 << 16; + shadowminitext(m, l, "Mark Dochtermann", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Map Design", 12); l += 7 << 16; + shadowminitext(m, l, "Allen H. Blum III", 12); l += 7 << 16; + shadowminitext(m, l, "Richard Gray", 12); l += 7 << 16; + + m = int(origin.X * 65536) + (180 << 16); + l = int(origin.Y * 65536) + (33 << 16); + + shadowminitext(m, l, "3D Modeling", 12); l += 7 << 16; + shadowminitext(m, l, "Chuck Jones", 12); l += 7 << 16; + shadowminitext(m, l, "Sapphire Corporation", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Artwork", 12); l += 7 << 16; + shadowminitext(m, l, "Dirk Jones, Stephen Hornback", 12); l += 7 << 16; + shadowminitext(m, l, "James Storey, David Demaret", 12); l += 7 << 16; + shadowminitext(m, l, "Douglas R. Wood", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Sound Engine", 12); l += 7 << 16; + shadowminitext(m, l, "Jim Dose", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Sound & Music Development", 12); l += 7 << 16; + shadowminitext(m, l, "Robert Prince", 12); l += 7 << 16; + shadowminitext(m, l, "Lee Jackson", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Voice Talent", 12); l += 7 << 16; + shadowminitext(m, l, "Lani Minella - Voice Producer", 12); l += 7 << 16; + shadowminitext(m, l, "Jon St. John as \"Duke Nukem\"", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Graphic Design", 12); l += 7 << 16; + shadowminitext(m, l, "Packaging, Manual, Ads", 12); l += 7 << 16; + shadowminitext(m, l, "Robert M. Atkins", 12); l += 7 << 16; + shadowminitext(m, l, "Michael Hadwin", 12); l += 7 << 16; + break; + + case 1: + m = int(origin.X * 65536) + (20 << 16); + l = int(origin.Y * 65536) + (33 << 16); + + shadowminitext(m, l, "Special Thanks To", 12); l += 7 << 16; + shadowminitext(m, l, "Steven Blackburn, Tom Hall", 12); l += 7 << 16; + shadowminitext(m, l, "Scott Miller, Joe Siegler", 12); l += 7 << 16; + shadowminitext(m, l, "Terry Nagy, Colleen Compton", 12); l += 7 << 16; + shadowminitext(m, l, "HASH, Inc., FormGen, Inc.", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "The 3D Realms Beta Testers", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Nathan Anderson, Wayne Benner", 12); l += 7 << 16; + shadowminitext(m, l, "Glenn Brensinger, Rob Brown", 12); l += 7 << 16; + shadowminitext(m, l, "Erik Harris, Ken Heckbert", 12); l += 7 << 16; + shadowminitext(m, l, "Terry Herrin, Greg Hively", 12); l += 7 << 16; + shadowminitext(m, l, "Hank Leukart, Eric Baker", 12); l += 7 << 16; + shadowminitext(m, l, "Jeff Rausch, Kelly Rogers", 12); l += 7 << 16; + shadowminitext(m, l, "Mike Duncan, Doug Howell", 12); l += 7 << 16; + shadowminitext(m, l, "Bill Blair", 12); l += 7 << 16; + + m = int(origin.X * 65536) + (160 << 16); + l = int(origin.Y * 65536) + (33 << 16); + + shadowminitext(m, l, "Company Product Support", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "The following companies were cool", 12); l += 7 << 16; + shadowminitext(m, l, "enough to give us lots of stuff", 12); l += 7 << 16; + shadowminitext(m, l, "during the making of Duke Nukem 3D.", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Altec Lansing Multimedia", 12); l += 7 << 16; + shadowminitext(m, l, "for tons of speakers and the", 12); l += 7 << 16; + shadowminitext(m, l, "THX-licensed sound system.", 12); l += 7 << 16; + shadowminitext(m, l, "For info call 1-800-548-0620", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Creative Labs, Inc.", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Thanks for the hardware, guys.", 12); l += 7 << 16; + break; + + case 2: + mgametextcenter(int(origin.X * 65536), int(origin.Y * 65536) + (50 << 16), "Duke Nukem 3D is a trademark of\n" + "3D Realms Entertainment" + "\n" + "Duke Nukem 3D\n" + "(C) 1996 3D Realms Entertainment"); + + if (VOLUMEONE) + { + mgametextcenter(int(origin.X * 65536), int(origin.Y * 65536) + (106 << 16), "Please read LICENSE.DOC for shareware\n" + "distribution grants and restrictions."); + } + mgametextcenter(int(origin.X * 65536), int(origin.Y * 65536) + ((VOLUMEONE ? 134 : 115) << 16), "Made in Dallas, Texas USA"); + break; + } + } +}; void GameInterface::MenuOpened() { diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index 840a304ca..fb332a782 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -75,28 +75,11 @@ static void mgametext(int32_t x, int32_t y, char const * t) G_ScreenText(MF_Bluefont.tilenum, x, y, MF_Bluefont.zoom, 0, 0, t, 0, MF_Bluefont.pal, 2|8|16|ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags, 0, 0, xdim-1, ydim-1); } -static vec2_t mgametextcenterat(int32_t x, int32_t y, char const * t, int32_t f = 0) -{ - return G_ScreenText(MF_Bluefont.tilenum, x, y, MF_Bluefont.zoom, 0, 0, t, 0, MF_Bluefont.pal, 2|8|16|ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f|TEXT_XCENTER, 0, 0, xdim-1, ydim-1); -} -static vec2_t mgametextcenter(int32_t x, int32_t y, char const * t, int32_t f = 0) -{ - return mgametextcenterat((MENU_MARGIN_CENTER<<16) + x, y, t, f); -} #define mminitext(x,y,t,p) minitext_(x, y, t, 0, p, 2|8|16|ROTATESPRITE_FULL16) #define mmenutext menutext #ifndef EDUKE32_STANDALONE -static void shadowminitext(int32_t x, int32_t y, const char *t, int32_t p) -{ - int32_t f = 0; - - if (!minitext_lowercase) - f |= TEXT_UPPERCASE; - - G_ScreenTextShadow(1, 1, MINIFONT, x, y, 65536, 0, 0, t, 0, p, 2|8|16|ROTATESPRITE_FULL16, 0, 4<<16, 8<<16, 1<<16, 0, f, 0, 0, xdim-1, ydim-1); -} #endif static void creditsminitext(int32_t x, int32_t y, const char *t, int32_t p) { @@ -112,11 +95,6 @@ static void creditsminitext(int32_t x, int32_t y, const char *t, int32_t p) static savehead_t savehead; #pragma pack(pop) -static void Menu_DrawBackground(const vec2_t origin) -{ - rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (100<<16), 65536L,0,MENUSCREEN,16,0,10+64); -} - static void Menu_DrawTopBar(const vec2_t origin) { if ((G_GetLogoFlags() & LOGO_NOTITLEBAR) == 0) @@ -1955,11 +1933,6 @@ static void Menu_PreDrawBackground(MenuID_t cm, const vec2_t origin) case MENU_CREDITS: case MENU_CREDITS2: case MENU_CREDITS3: - if (!VOLUMEALL || !PLUTOPAK) - Menu_DrawBackground(origin); - else - rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (100<<16), 65536L,0,2504+cm-MENU_CREDITS,0,0,10+64); - break; case MENU_LOAD: case MENU_SAVE: @@ -2304,129 +2277,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) mgametextcenter(origin.x, origin.y + ((148+16)<<16), "Press any key or button..."); break; #endif - case MENU_CREDITS: - case MENU_CREDITS2: - case MENU_CREDITS3: -#ifndef EDUKE32_STANDALONE - if (!VOLUMEALL || !PLUTOPAK) - { - int32_t m; - switch (cm) - { - case MENU_CREDITS: - m = origin.x + (20<<16); - l = origin.y + (33<<16); - - shadowminitext(m, l, "Original Concept", 12); l += 7<<16; - shadowminitext(m, l, "Todd Replogle and Allen H. Blum III", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Produced & Directed By", 12); l += 7<<16; - shadowminitext(m, l, "Greg Malone", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Executive Producer", 12); l += 7<<16; - shadowminitext(m, l, "George Broussard", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "BUILD Engine", 12); l += 7<<16; - shadowminitext(m, l, "Ken Silverman", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Game Programming", 12); l += 7<<16; - shadowminitext(m, l, "Todd Replogle", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "3D Engine/Tools/Net", 12); l += 7<<16; - shadowminitext(m, l, "Ken Silverman", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Network Layer/Setup Program", 12); l += 7<<16; - shadowminitext(m, l, "Mark Dochtermann", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Map Design", 12); l += 7<<16; - shadowminitext(m, l, "Allen H. Blum III", 12); l += 7<<16; - shadowminitext(m, l, "Richard Gray", 12); l += 7<<16; - - m = origin.x + (180<<16); - l = origin.y + (33<<16); - - shadowminitext(m, l, "3D Modeling", 12); l += 7<<16; - shadowminitext(m, l, "Chuck Jones", 12); l += 7<<16; - shadowminitext(m, l, "Sapphire Corporation", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Artwork", 12); l += 7<<16; - shadowminitext(m, l, "Dirk Jones, Stephen Hornback", 12); l += 7<<16; - shadowminitext(m, l, "James Storey, David Demaret", 12); l += 7<<16; - shadowminitext(m, l, "Douglas R. Wood", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Sound Engine", 12); l += 7<<16; - shadowminitext(m, l, "Jim Dose", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Sound & Music Development", 12); l += 7<<16; - shadowminitext(m, l, "Robert Prince", 12); l += 7<<16; - shadowminitext(m, l, "Lee Jackson", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Voice Talent", 12); l += 7<<16; - shadowminitext(m, l, "Lani Minella - Voice Producer", 12); l += 7<<16; - shadowminitext(m, l, "Jon St. John as \"Duke Nukem\"", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Graphic Design", 12); l += 7<<16; - shadowminitext(m, l, "Packaging, Manual, Ads", 12); l += 7<<16; - shadowminitext(m, l, "Robert M. Atkins", 12); l += 7<<16; - shadowminitext(m, l, "Michael Hadwin", 12); l += 7<<16; - break; - - case MENU_CREDITS2: - m = origin.x + (20<<16); - l = origin.y + (33<<16); - - shadowminitext(m, l, "Special Thanks To", 12); l += 7<<16; - shadowminitext(m, l, "Steven Blackburn, Tom Hall", 12); l += 7<<16; - shadowminitext(m, l, "Scott Miller, Joe Siegler", 12); l += 7<<16; - shadowminitext(m, l, "Terry Nagy, Colleen Compton", 12); l += 7<<16; - shadowminitext(m, l, "HASH, Inc., FormGen, Inc.", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "The 3D Realms Beta Testers", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Nathan Anderson, Wayne Benner", 12); l += 7<<16; - shadowminitext(m, l, "Glenn Brensinger, Rob Brown", 12); l += 7<<16; - shadowminitext(m, l, "Erik Harris, Ken Heckbert", 12); l += 7<<16; - shadowminitext(m, l, "Terry Herrin, Greg Hively", 12); l += 7<<16; - shadowminitext(m, l, "Hank Leukart, Eric Baker", 12); l += 7<<16; - shadowminitext(m, l, "Jeff Rausch, Kelly Rogers", 12); l += 7<<16; - shadowminitext(m, l, "Mike Duncan, Doug Howell", 12); l += 7<<16; - shadowminitext(m, l, "Bill Blair", 12); l += 7<<16; - - m = origin.x + (160<<16); - l = origin.y + (33<<16); - - shadowminitext(m, l, "Company Product Support", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "The following companies were cool", 12); l += 7<<16; - shadowminitext(m, l, "enough to give us lots of stuff", 12); l += 7<<16; - shadowminitext(m, l, "during the making of Duke Nukem 3D.", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Altec Lansing Multimedia", 12); l += 7<<16; - shadowminitext(m, l, "for tons of speakers and the", 12); l += 7<<16; - shadowminitext(m, l, "THX-licensed sound system.", 12); l += 7<<16; - shadowminitext(m, l, "For info call 1-800-548-0620", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Creative Labs, Inc.", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Thanks for the hardware, guys.", 12); l += 7<<16; - break; - - case MENU_CREDITS3: - mgametextcenter(origin.x, origin.y + (50<<16), "Duke Nukem 3D is a trademark of\n" - "3D Realms Entertainment" - "\n" - "Duke Nukem 3D\n" - "(C) 1996 3D Realms Entertainment"); - -#if !defined(EDUKE32_ANDROID_MENU) && !defined(EDUKE32_STANDALONE) - if (VOLUMEONE) - { - mgametextcenter(origin.x, origin.y + (106<<16), "Please read LICENSE.DOC for shareware\n" - "distribution grants and restrictions."); - } -#endif - mgametextcenter(origin.x, origin.y + ((VOLUMEONE?134:115)<<16), "Made in Dallas, Texas USA"); - break; } } break; From 4e5f59a373616e6ab69228e8b11160645f8f53da Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 01:02:45 +0100 Subject: [PATCH 035/203] - Menu WIP * implemented single image screens * implemented skeleton of the image scroller * added RR-specific definitions to the menus (need to copy and adjust d_menu.cpp) * added definitions for credits screens. --- source/build/include/baselayer.h | 2 + source/common/gamecontrol.cpp | 3 +- source/common/gamecontrol.h | 4 + source/common/menu/listmenu.cpp | 33 ++ source/common/menu/menu.cpp | 2 + source/common/menu/menu.h | 53 +- source/common/menu/menudef.cpp | 98 ++++ source/common/utility/namedef.h | 3 +- source/common/utility/stringtable.cpp | 14 +- source/duke3d/src/d_menu.cpp | 329 ++++++----- source/duke3d/src/duke3d.h | 2 + source/duke3d/src/gamedef.cpp | 12 - source/duke3d/src/menus.cpp | 29 - source/duke3d/src/names.h | 764 -------------------------- source/duke3d/src/namesdyn.cpp | 32 +- source/duke3d/src/namesdyn.h | 27 +- source/rr/src/namesdyn.cpp | 5 + wadsrc/static/demolition/menudef.txt | 203 +++++-- 18 files changed, 582 insertions(+), 1033 deletions(-) delete mode 100644 source/duke3d/src/names.h diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index dec688c0a..e45646689 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -210,6 +210,8 @@ struct GameInterface virtual void CustomMenuSelection(int menu, int item) {} virtual void StartGame(FGameStartup& gs) {} virtual FSavegameInfo GetSaveSig() { return { "", 0, 0}; } + virtual bool DrawSpecialScreen(const DVector2 &origin, int tilenum) { return false; } + virtual void DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position); }; extern GameInterface* gi; diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index 12981b4c7..29909e7c5 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -38,7 +38,8 @@ bool gHaveNetworking; FString currentGame; FString LumpFilter; - +TMap NameToTileIndex; // for assigning names to tiles. The menu accesses this list. By default it gets everything from the dynamic tile map in Duke Nukem and Redneck Rampage. + // Todo: Add additional definition file for the other games or textures not in that list so that the menu does not have to rely on indices. CVAR(Int, cl_defaultconfiguration, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) diff --git a/source/common/gamecontrol.h b/source/common/gamecontrol.h index 61d3a1068..876c82d54 100644 --- a/source/common/gamecontrol.h +++ b/source/common/gamecontrol.h @@ -7,6 +7,8 @@ #include "zstring.h" #include "inputstate.h" #include "gamecvars.h" +#include "tarray.h" +#include "name.h" EXTERN_CVAR(Int, cl_defaultconfiguration) @@ -14,6 +16,8 @@ extern FString currentGame; extern FString LumpFilter; class FArgs; +extern TMap NameToTileIndex; + void D_AddWildFile(TArray& wadfiles, const char* value); int CONFIG_Init(); diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index b6033dd28..8ec1259e3 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -40,6 +40,8 @@ #include "menu.h" #include "v_draw.h" #include "baselayer.h" +#include "gamecontrol.h" +#include "build.h" //============================================================================= // @@ -619,3 +621,34 @@ int FListMenuItemPatch::GetWidth() : 0; } +//============================================================================= +// +// Fullscreen image drawer (move to its own source file!) +// +//============================================================================= + +void ImageScreen::Drawer() +{ + if (mDesc->mType == 0) + { + auto tileindexp = NameToTileIndex.CheckKey(mDesc->mText); + int tileindex; + if (tileindexp == nullptr) + { + // If this isn't a name, try a literal tile index; + auto c = mDesc->mMenuName.GetChars(); + if (*c == '#') tileindex = (int)strtoll(c+1, nullptr, 0); + // Error out if the screen cannot be found, this is always a definition error that needs to be reported. + else I_Error("Invalid menu screen '%s'", mDesc->mMenuName.GetChars()); + } + else tileindex = *tileindexp; + if (!gi->DrawSpecialScreen(origin, tileindex)) // allows the front end to do custom handling for a given image. + { + rotatesprite_fs(int(origin.X * 65536) + (160<<16), int(origin.Y * 65536) + (100<<16), 65536L,0,tileindex,0,0,10+64); + } + } + else + { + gi->DrawCenteredTextScreen(origin, mDesc->mText, mDesc->type); + } +} diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index df7a8d36c..3478b1890 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -53,6 +53,7 @@ #include "build.h" void RegisterDukeMenus(); +void RegisterSpecialMenus(); extern bool rotatesprite_2doverride; bool help_disabled, credits_disabled; int g_currentMenu; // accessible by CON scripts - contains the current menu's script ID if defined or INT_MAX if none given. @@ -872,6 +873,7 @@ void Menu_Close(int playerid) void M_Init (void) { + RegisterSpecialMenus(); RegisterDukeMenus(); timerSetCallback(M_Ticker); M_ParseMenuDefs(); diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 6167ecaa4..611ae0ad9 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -141,6 +141,7 @@ enum EMenuDescriptorType { MDESC_ListMenu, MDESC_OptionsMenu, + MDESC_ImageScroller, }; struct FMenuDescriptor @@ -252,7 +253,20 @@ struct FOptionMenuDescriptor : public FMenuDescriptor } }; - + +struct FImageScrollerDescriptor : public FMenuDescriptor +{ + struct ScrollerItem + { + int type; // 0: fullscreen image; 1: centered text + int scriptID; + FString text; + }; + + TArray mItems; +}; + + typedef TMap MenuDescriptorList; @@ -494,11 +508,11 @@ public: DListMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); virtual void Init(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); FListMenuItem *GetItem(FName name); - bool Responder (event_t *ev); - bool MenuEvent (int mkey, bool fromcontroller); - bool MouseEvent(int type, int x, int y); - void Ticker (); - void Drawer (); + bool Responder (event_t *ev) override; + bool MenuEvent (int mkey, bool fromcontroller) override; + bool MouseEvent(int type, int x, int y) override; + void Ticker () override; + void Drawer () override; virtual void SelectionChanged() {} void SetFocus(FListMenuItem *fc) { @@ -613,6 +627,33 @@ public: }; +//============================================================================= +// +// ImageScroller +// +//============================================================================= + +class DImageScrollerMenu : public DMenu +{ + +}; + +//============================================================================= +// +// Show a fullscreen image / centered text screen for an image scroller +// +//============================================================================= + +class ImageScreen : public DMenu // Todo: This should be global +{ + const FImageScrollerDescriptor::ScrollerItem *mDesc; + ImageScreen(const FImageScrollerDescriptor::ScrollerItem *it) + { + mDesc = it; + } + void Drawer() override; +}; + //============================================================================= // // Input some text diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 2a7ca894c..eef422731 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -142,6 +142,8 @@ struct gamefilter static const gamefilter games[] = { { "Duke", GAMEFLAG_DUKE}, { "Nam", GAMEFLAG_NAM|GAMEFLAG_NAPALM}, + { "NamOnly", GAMEFLAG_NAM}, // for cases where the difference matters. + { "Napalm", GAMEFLAG_NAPALM}, { "WW2GI", GAMEFLAG_WW2GI}, { "Fury", GAMEFLAG_FURY}, { "Redneck", GAMEFLAG_RR}, @@ -150,6 +152,19 @@ static const gamefilter games[] = { { "ShadowWarrior", GAMEFLAG_SW}, }; +// for other parts that need to filter by game name. +bool validFilter(const char *str) +{ + for (auto &gf : games) + { + if (g_gameType & gf.gameflag) + { + if (!stricmp(str, gf.gamename)) return true; + } + } + return false; +} + static bool CheckSkipGameBlock(FScanner &sc) { @@ -542,6 +557,85 @@ static void ParseListMenu(FScanner &sc) // //============================================================================= +static void ParseImageScrollerBody(FScanner &sc, FImageScrollerDescriptor *desc) +{ + sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (sc.Compare("else")) + { + SkipSubBlock(sc); + } + else if (sc.Compare("ifgame")) + { + if (!CheckSkipGameBlock(sc)) + { + // recursively parse sub-block + ParseImageScrollerBody(sc, desc); + } + } + else if (sc.Compare("ifoption")) + { + if (!CheckSkipOptionBlock(sc)) + { + // recursively parse sub-block + ParseImageScrollerBody(sc, desc); + } + } + else if (sc.Compare("TextItem") || sc.Compare("ImageItem")) + { + FImageScrollerDescriptor::ScrollerItem item; + sc.MustGetString(); + item.text = sc.String; + int type = sc.Compare("TextItem"); + if (type) + { + sc.MustGetStringName(","); + sc.MustGetNumber(); + item.type = sc.Number; // y-coordinate + } + item.scriptID = INT_MAX; + if (sc.CheckString(",")) + { + sc.MustGetNumber(); + item.scriptID = sc.Number; + } + desc->mItems.Push(item); + } + else + { + sc.ScriptError("Unknown keyword '%s'", sc.String); + } + } +} + + +//============================================================================= +// +// +// +//============================================================================= + +static void ParseImageScroller(FScanner &sc) +{ + sc.MustGetString(); + + FImageScrollerDescriptor *desc = new FImageScrollerDescriptor; + desc->mType = MDESC_ImageScroller; + desc->mMenuName = sc.String; + + ParseImageScrollerBody(sc, desc); + bool scratch = ReplaceMenu(sc, desc); + if (scratch) delete desc; +} + +//============================================================================= +// +// +// +//============================================================================= + static void ParseOptionValue(FScanner &sc) { FName optname; @@ -948,6 +1042,10 @@ void M_ParseMenuDefs() { ParseListMenu(sc); } + if (sc.Compare("ImageScroller")) + { + ParseImageScroller(sc); + } else if (sc.Compare("DEFAULTLISTMENU")) { ParseListMenuBody(sc, &DefaultListMenuSettings); diff --git a/source/common/utility/namedef.h b/source/common/utility/namedef.h index ad19352e1..dfb6d7eb4 100644 --- a/source/common/utility/namedef.h +++ b/source/common/utility/namedef.h @@ -35,4 +35,5 @@ xx(CustomSubMenu5) xx(CustomSubMenu6) xx(CustomSubMenu7) xx(UsermapMenu) -xx(StartGame) \ No newline at end of file +xx(StartGame) +xx(ImageScroller) diff --git a/source/common/utility/stringtable.cpp b/source/common/utility/stringtable.cpp index 838af71fa..0307b26ac 100644 --- a/source/common/utility/stringtable.cpp +++ b/source/common/utility/stringtable.cpp @@ -43,6 +43,7 @@ #include "c_cvars.h" #include "printf.h" +bool validFilter(const char *str); EXTERN_CVAR(String, language) CUSTOM_CVAR(Int, cl_gender, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { @@ -239,12 +240,21 @@ bool FStringTable::ParseLanguageCSV(int lumpnum, const TArray &buffer) for (unsigned i = 1; i < data.Size(); i++) { auto &row = data[i]; -#if 0 +#if 1 if (filtercol > -1) { auto filterstr = row[filtercol]; auto filter = filterstr.Split(" ", FString::TOK_SKIPEMPTY); - if (filter.Size() > 0 && filter.FindEx([](const auto &str) { return str.CompareNoCase(GameNames[gameinfo.gametype]) == 0; }) == filter.Size()) + bool ok = false; + for (auto &entry : filter) + { + if (validFilter(entry)) + { + ok = true; + break; + } + } + if (!ok) continue; continue; } #endif diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 1341f646b..935b1b152 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -37,6 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "menu/menu.h" #include "gstrings.h" #include "version.h" +#include "namesdyn.h" #include "../../glbackend/glbackend.h" BEGIN_DUKE_NS @@ -279,6 +280,14 @@ void GameInterface::DrawNativeMenuText(int fontnum, int state, int xpos, int ypo +//---------------------------------------------------------------------------- +// +// Implements the native looking menu used for the main menu +// and the episode/skill selection screens, i.e. the parts +// that need to look authentic +// +//---------------------------------------------------------------------------- + class DukeListMenu : public DListMenu { using Super = DListMenu; @@ -401,149 +410,11 @@ class MainMenu : public DukeListMenu } }; -class DukeCreditScreen : public DMenu -{ - int screen; - - void shadowminitext(int32_t x, int32_t y, const char* t, int32_t p) - { - int32_t f = 0; - - if (!minitext_lowercase) - f |= TEXT_UPPERCASE; - - G_ScreenTextShadow(1, 1, MINIFONT, x, y, 65536, 0, 0, t, 0, p, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, 4 << 16, 8 << 16, 1 << 16, 0, f, 0, 0, xdim - 1, ydim - 1); - } - - - void Drawer() - { - if (VOLUMEALL && PLUTOPAK) - { - rotatesprite_fs(int(origin.X * 65536) + (MENU_MARGIN_CENTER << 16), int(origin.Y * 65536) + (100 << 16), 65536L, 0, 2504 + screen, 0, 0, 10 + 64); - return; - } - Menu_DrawBackground(origin); - - // On the latest version there's real graphics for this. - int32_t m, l; - switch (screen) - { - case 0: - m = int(origin.X * 65536) + (20 << 16); - l = int(origin.Y * 65536) + (33 << 16); - - shadowminitext(m, l, "Original Concept", 12); l += 7 << 16; - shadowminitext(m, l, "Todd Replogle and Allen H. Blum III", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Produced & Directed By", 12); l += 7 << 16; - shadowminitext(m, l, "Greg Malone", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Executive Producer", 12); l += 7 << 16; - shadowminitext(m, l, "George Broussard", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "BUILD Engine", 12); l += 7 << 16; - shadowminitext(m, l, "Ken Silverman", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Game Programming", 12); l += 7 << 16; - shadowminitext(m, l, "Todd Replogle", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "3D Engine/Tools/Net", 12); l += 7 << 16; - shadowminitext(m, l, "Ken Silverman", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Network Layer/Setup Program", 12); l += 7 << 16; - shadowminitext(m, l, "Mark Dochtermann", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Map Design", 12); l += 7 << 16; - shadowminitext(m, l, "Allen H. Blum III", 12); l += 7 << 16; - shadowminitext(m, l, "Richard Gray", 12); l += 7 << 16; - - m = int(origin.X * 65536) + (180 << 16); - l = int(origin.Y * 65536) + (33 << 16); - - shadowminitext(m, l, "3D Modeling", 12); l += 7 << 16; - shadowminitext(m, l, "Chuck Jones", 12); l += 7 << 16; - shadowminitext(m, l, "Sapphire Corporation", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Artwork", 12); l += 7 << 16; - shadowminitext(m, l, "Dirk Jones, Stephen Hornback", 12); l += 7 << 16; - shadowminitext(m, l, "James Storey, David Demaret", 12); l += 7 << 16; - shadowminitext(m, l, "Douglas R. Wood", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Sound Engine", 12); l += 7 << 16; - shadowminitext(m, l, "Jim Dose", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Sound & Music Development", 12); l += 7 << 16; - shadowminitext(m, l, "Robert Prince", 12); l += 7 << 16; - shadowminitext(m, l, "Lee Jackson", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Voice Talent", 12); l += 7 << 16; - shadowminitext(m, l, "Lani Minella - Voice Producer", 12); l += 7 << 16; - shadowminitext(m, l, "Jon St. John as \"Duke Nukem\"", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Graphic Design", 12); l += 7 << 16; - shadowminitext(m, l, "Packaging, Manual, Ads", 12); l += 7 << 16; - shadowminitext(m, l, "Robert M. Atkins", 12); l += 7 << 16; - shadowminitext(m, l, "Michael Hadwin", 12); l += 7 << 16; - break; - - case 1: - m = int(origin.X * 65536) + (20 << 16); - l = int(origin.Y * 65536) + (33 << 16); - - shadowminitext(m, l, "Special Thanks To", 12); l += 7 << 16; - shadowminitext(m, l, "Steven Blackburn, Tom Hall", 12); l += 7 << 16; - shadowminitext(m, l, "Scott Miller, Joe Siegler", 12); l += 7 << 16; - shadowminitext(m, l, "Terry Nagy, Colleen Compton", 12); l += 7 << 16; - shadowminitext(m, l, "HASH, Inc., FormGen, Inc.", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "The 3D Realms Beta Testers", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Nathan Anderson, Wayne Benner", 12); l += 7 << 16; - shadowminitext(m, l, "Glenn Brensinger, Rob Brown", 12); l += 7 << 16; - shadowminitext(m, l, "Erik Harris, Ken Heckbert", 12); l += 7 << 16; - shadowminitext(m, l, "Terry Herrin, Greg Hively", 12); l += 7 << 16; - shadowminitext(m, l, "Hank Leukart, Eric Baker", 12); l += 7 << 16; - shadowminitext(m, l, "Jeff Rausch, Kelly Rogers", 12); l += 7 << 16; - shadowminitext(m, l, "Mike Duncan, Doug Howell", 12); l += 7 << 16; - shadowminitext(m, l, "Bill Blair", 12); l += 7 << 16; - - m = int(origin.X * 65536) + (160 << 16); - l = int(origin.Y * 65536) + (33 << 16); - - shadowminitext(m, l, "Company Product Support", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "The following companies were cool", 12); l += 7 << 16; - shadowminitext(m, l, "enough to give us lots of stuff", 12); l += 7 << 16; - shadowminitext(m, l, "during the making of Duke Nukem 3D.", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Altec Lansing Multimedia", 12); l += 7 << 16; - shadowminitext(m, l, "for tons of speakers and the", 12); l += 7 << 16; - shadowminitext(m, l, "THX-licensed sound system.", 12); l += 7 << 16; - shadowminitext(m, l, "For info call 1-800-548-0620", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Creative Labs, Inc.", 12); l += 7 << 16; - l += 3 << 16; - shadowminitext(m, l, "Thanks for the hardware, guys.", 12); l += 7 << 16; - break; - - case 2: - mgametextcenter(int(origin.X * 65536), int(origin.Y * 65536) + (50 << 16), "Duke Nukem 3D is a trademark of\n" - "3D Realms Entertainment" - "\n" - "Duke Nukem 3D\n" - "(C) 1996 3D Realms Entertainment"); - - if (VOLUMEONE) - { - mgametextcenter(int(origin.X * 65536), int(origin.Y * 65536) + (106 << 16), "Please read LICENSE.DOC for shareware\n" - "distribution grants and restrictions."); - } - mgametextcenter(int(origin.X * 65536), int(origin.Y * 65536) + ((VOLUMEONE ? 134 : 115) << 16), "Made in Dallas, Texas USA"); - break; - } - } -}; +//---------------------------------------------------------------------------- +// +// Menu related game interface functions +// +//---------------------------------------------------------------------------- void GameInterface::MenuOpened() { @@ -638,9 +509,181 @@ FSavegameInfo GameInterface::GetSaveSig() return { SAVESIG_DN3D, MINSAVEVER_DN3D, SAVEVER_DN3D }; } +//---------------------------------------------------------------------------- +// +// +// +//---------------------------------------------------------------------------- + +static void shadowminitext(int32_t x, int32_t y, const char* t, int32_t p) +{ + int32_t f = 0; + + if (!minitext_lowercase) + f |= TEXT_UPPERCASE; + + G_ScreenTextShadow(1, 1, MINIFONT, x, y, 65536, 0, 0, t, 0, p, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, 4 << 16, 8 << 16, 1 << 16, 0, f, 0, 0, xdim - 1, ydim - 1); +} + +//---------------------------------------------------------------------------- +// +// allows the front end to override certain fullscreen image menus +// with custom implementations. +// +// This is needed because the credits screens in Duke Nukem +// are eithrr done by providing an image or by printing text, based on the version used. +// +//---------------------------------------------------------------------------- + +bool GameInterface::DrawSpecialScreen(const DVector2 &origin, int tilenum) +{ + // Older versions of Duke Nukem create the credits screens manually. + // On the latest version there's real graphics for this. + bool haveCredits = VOLUMEALL && PLUTOPAK; + + int32_t m, l; + if (!haveCredits) + { + if (tilenum == CREDITSTEXT1) + { + Menu_DrawBackground(origin); + m = int(origin.X * 65536) + (20 << 16); + l = int(origin.Y * 65536) + (33 << 16); + + shadowminitext(m, l, "Original Concept", 12); l += 7 << 16; + shadowminitext(m, l, "Todd Replogle and Allen H. Blum III", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Produced & Directed By", 12); l += 7 << 16; + shadowminitext(m, l, "Greg Malone", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Executive Producer", 12); l += 7 << 16; + shadowminitext(m, l, "George Broussard", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "BUILD Engine", 12); l += 7 << 16; + shadowminitext(m, l, "Ken Silverman", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Game Programming", 12); l += 7 << 16; + shadowminitext(m, l, "Todd Replogle", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "3D Engine/Tools/Net", 12); l += 7 << 16; + shadowminitext(m, l, "Ken Silverman", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Network Layer/Setup Program", 12); l += 7 << 16; + shadowminitext(m, l, "Mark Dochtermann", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Map Design", 12); l += 7 << 16; + shadowminitext(m, l, "Allen H. Blum III", 12); l += 7 << 16; + shadowminitext(m, l, "Richard Gray", 12); l += 7 << 16; + + m = int(origin.X * 65536) + (180 << 16); + l = int(origin.Y * 65536) + (33 << 16); + + shadowminitext(m, l, "3D Modeling", 12); l += 7 << 16; + shadowminitext(m, l, "Chuck Jones", 12); l += 7 << 16; + shadowminitext(m, l, "Sapphire Corporation", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Artwork", 12); l += 7 << 16; + shadowminitext(m, l, "Dirk Jones, Stephen Hornback", 12); l += 7 << 16; + shadowminitext(m, l, "James Storey, David Demaret", 12); l += 7 << 16; + shadowminitext(m, l, "Douglas R. Wood", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Sound Engine", 12); l += 7 << 16; + shadowminitext(m, l, "Jim Dose", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Sound & Music Development", 12); l += 7 << 16; + shadowminitext(m, l, "Robert Prince", 12); l += 7 << 16; + shadowminitext(m, l, "Lee Jackson", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Voice Talent", 12); l += 7 << 16; + shadowminitext(m, l, "Lani Minella - Voice Producer", 12); l += 7 << 16; + shadowminitext(m, l, "Jon St. John as \"Duke Nukem\"", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Graphic Design", 12); l += 7 << 16; + shadowminitext(m, l, "Packaging, Manual, Ads", 12); l += 7 << 16; + shadowminitext(m, l, "Robert M. Atkins", 12); l += 7 << 16; + shadowminitext(m, l, "Michael Hadwin", 12); l += 7 << 16; + return true; + } + else if (tilenum == CREDITSTEXT2__STATIC) + { + Menu_DrawBackground(origin); + m = int(origin.X * 65536) + (20 << 16); + l = int(origin.Y * 65536) + (33 << 16); + + shadowminitext(m, l, "Special Thanks To", 12); l += 7 << 16; + shadowminitext(m, l, "Steven Blackburn, Tom Hall", 12); l += 7 << 16; + shadowminitext(m, l, "Scott Miller, Joe Siegler", 12); l += 7 << 16; + shadowminitext(m, l, "Terry Nagy, Colleen Compton", 12); l += 7 << 16; + shadowminitext(m, l, "HASH, Inc., FormGen, Inc.", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "The 3D Realms Beta Testers", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Nathan Anderson, Wayne Benner", 12); l += 7 << 16; + shadowminitext(m, l, "Glenn Brensinger, Rob Brown", 12); l += 7 << 16; + shadowminitext(m, l, "Erik Harris, Ken Heckbert", 12); l += 7 << 16; + shadowminitext(m, l, "Terry Herrin, Greg Hively", 12); l += 7 << 16; + shadowminitext(m, l, "Hank Leukart, Eric Baker", 12); l += 7 << 16; + shadowminitext(m, l, "Jeff Rausch, Kelly Rogers", 12); l += 7 << 16; + shadowminitext(m, l, "Mike Duncan, Doug Howell", 12); l += 7 << 16; + shadowminitext(m, l, "Bill Blair", 12); l += 7 << 16; + + m = int(origin.X * 65536) + (160 << 16); + l = int(origin.Y * 65536) + (33 << 16); + + shadowminitext(m, l, "Company Product Support", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "The following companies were cool", 12); l += 7 << 16; + shadowminitext(m, l, "enough to give us lots of stuff", 12); l += 7 << 16; + shadowminitext(m, l, "during the making of Duke Nukem 3D.", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Altec Lansing Multimedia", 12); l += 7 << 16; + shadowminitext(m, l, "for tons of speakers and the", 12); l += 7 << 16; + shadowminitext(m, l, "THX-licensed sound system.", 12); l += 7 << 16; + shadowminitext(m, l, "For info call 1-800-548-0620", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Creative Labs, Inc.", 12); l += 7 << 16; + l += 3 << 16; + shadowminitext(m, l, "Thanks for the hardware, guys.", 12); l += 7 << 16; + return true; + } + else if (tilenum == CREDITSTEXT3) + { + Menu_DrawBackground(origin); + mgametextcenter(int(origin.X * 65536), int(origin.Y * 65536) + (50 << 16), "Duke Nukem 3D is a trademark of\n" + "3D Realms Entertainment" + "\n" + "Duke Nukem 3D\n" + "(C) 1996 3D Realms Entertainment"); + + if (VOLUMEONE) + { + mgametextcenter(int(origin.X * 65536), int(origin.Y * 65536) + (106 << 16), "Please read LICENSE.DOC for shareware\n" + "distribution grants and restrictions."); + } + mgametextcenter(int(origin.X * 65536), int(origin.Y * 65536) + ((VOLUMEONE ? 134 : 115) << 16), "Made in Dallas, Texas USA"); + return true; + } + } + return false; +} + + +void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) +{ + Menu_DrawBackground(origin); + mgametextcenter(int(origin.X * 65536), int((origin.Y + position) * 65536), text); +} + END_DUKE_NS +//---------------------------------------------------------------------------- +// +// Class registration +// +//---------------------------------------------------------------------------- + + static TMenuClassDescriptor _mm("Duke.MainMenu"); static TMenuClassDescriptor _lm("Duke.ListMenu"); static TMenuClassDescriptor _ngcsm("Duke.NewGameCustomSubMenu"); diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index ebf34735c..8cdd71442 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -164,6 +164,8 @@ struct GameInterface : ::GameInterface void CustomMenuSelection(int menu, int item) override; void StartGame(FGameStartup& gs) override; FSavegameInfo GetSaveSig() override; + bool DrawSpecialScreen(const DVector2 &origin, int tilenum) override; + void DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) override; }; diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index ce83c0d40..62d4b52dd 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -3560,19 +3560,7 @@ DO_DEFSTATE: initprintf("%s:%d: warning: duplicate dynamicremap statement\n",g_scriptFileName,g_lineNumber); g_warningCnt++; } -#ifdef DYNTILEREMAP_ENABLE -#ifdef DEBUGGINGAIDS - else - initprintf("Using dynamic tile remapping\n"); -#endif g_dynamicTileMapping = 1; -#else - else - { - initprintf("%s:%d: warning: dynamic tile remapping is disabled in this build\n",g_scriptFileName,g_lineNumber); - g_warningCnt++; - } -#endif continue; case CON_DYNAMICSOUNDREMAP: diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index fb332a782..0bf1c9322 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -1926,35 +1926,6 @@ static void Menu_Pre(MenuID_t cm) } -static void Menu_PreDrawBackground(MenuID_t cm, const vec2_t origin) -{ - switch (cm) - { - case MENU_CREDITS: - case MENU_CREDITS2: - case MENU_CREDITS3: - - case MENU_LOAD: - case MENU_SAVE: - if (FURY) - break; - fallthrough__; - case MENU_CREDITS4: - case MENU_CREDITS5: - Menu_DrawBackground(origin); - break; - - case MENU_STORY: - rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (100<<16), 65536L,0,TEXTSTORY,0,0,10+64); - break; - - case MENU_F1HELP: - rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (100<<16), 65536L,0,F1HELP,0,0,10+64); - break; - } -} - - static void Menu_DrawVerifyPrompt(int32_t x, int32_t y, const char * text, int numlines = 1) { mgametextcenter(x, y + (90<<16), text); diff --git a/source/duke3d/src/names.h b/source/duke3d/src/names.h deleted file mode 100644 index 5e1fffec5..000000000 --- a/source/duke3d/src/names.h +++ /dev/null @@ -1,764 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2010 EDuke32 developers and contributors - -This file is part of EDuke32. - -EDuke32 is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. - -This program 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 this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -#define SECTOREFFECTOR 1 -#define ACTIVATOR 2 -#define TOUCHPLATE 3 -#define ACTIVATORLOCKED 4 -#define MUSICANDSFX 5 -#define LOCATORS 6 -#define CYCLER 7 -#define MASTERSWITCH 8 -#define RESPAWN 9 -#define GPSPEED 10 -#define FOF 13 -#define ARROW 20 -#define FIRSTGUNSPRITE 21 -#define CHAINGUNSPRITE 22 -#define RPGSPRITE 23 -#define FREEZESPRITE 24 -#define SHRINKERSPRITE 25 -#define HEAVYHBOMB 26 -#define TRIPBOMBSPRITE 27 -#define SHOTGUNSPRITE 28 -#define DEVISTATORSPRITE 29 -#define HEALTHBOX 30 -#define AMMOBOX 31 -#define GROWSPRITEICON 32 -#define INVENTORYBOX 33 -#define FREEZEAMMO 37 -#define AMMO 40 -#define BATTERYAMMO 41 -#define DEVISTATORAMMO 42 -#define RPGAMMO 44 -#define GROWAMMO 45 -#define CRYSTALAMMO 46 -#define HBOMBAMMO 47 -#define AMMOLOTS 48 -#define SHOTGUNAMMO 49 -#define COLA 51 -#define SIXPAK 52 -#define FIRSTAID 53 -#define SHIELD 54 -#define STEROIDS 55 -#define AIRTANK 56 -#define JETPACK 57 -#define HEATSENSOR 59 -#define ACCESSCARD 60 -#define BOOTS 61 -#define MIRRORBROKE 70 -#define CLOUDYOCEAN 78 -#define CLOUDYSKIES 79 -#define MOONSKY1 80 -#define MOONSKY2 81 -#define MOONSKY3 82 -#define MOONSKY4 83 -#define BIGORBIT1 84 -#define BIGORBIT2 85 -#define BIGORBIT3 86 -#define BIGORBIT4 87 -#define BIGORBIT5 88 -#define LA 89 -#define REDSKY1 98 -#define REDSKY2 99 -#define ATOMICHEALTH 100 -#define TECHLIGHT2 120 -#define TECHLIGHTBUST2 121 -#define TECHLIGHT4 122 -#define TECHLIGHTBUST4 123 -#define WALLLIGHT4 124 -#define WALLLIGHTBUST4 125 -#define ACCESSSWITCH 130 -#define SLOTDOOR 132 -#define LIGHTSWITCH 134 -#define SPACEDOORSWITCH 136 -#define SPACELIGHTSWITCH 138 -#define FRANKENSTINESWITCH 140 -#define NUKEBUTTON 142 -#define MULTISWITCH 146 -#define DOORTILE5 150 -#define DOORTILE6 151 -#define DOORTILE1 152 -#define DOORTILE2 153 -#define DOORTILE3 154 -#define DOORTILE4 155 -#define DOORTILE7 156 -#define DOORTILE8 157 -#define DOORTILE9 158 -#define DOORTILE10 159 -#define DOORSHOCK 160 -#define DIPSWITCH 162 -#define DIPSWITCH2 164 -#define TECHSWITCH 166 -#define DIPSWITCH3 168 -#define ACCESSSWITCH2 170 -#define REFLECTWATERTILE 180 -#define FLOORSLIME 200 -#define BIGFORCE 230 -#define EPISODE 247 -#define MASKWALL9 255 -#define W_LIGHT 260 -#define SCREENBREAK1 263 -#define SCREENBREAK2 264 -#define SCREENBREAK3 265 -#define SCREENBREAK4 266 -#define SCREENBREAK5 267 -#define SCREENBREAK6 268 -#define SCREENBREAK7 269 -#define SCREENBREAK8 270 -#define SCREENBREAK9 271 -#define SCREENBREAK10 272 -#define SCREENBREAK11 273 -#define SCREENBREAK12 274 -#define SCREENBREAK13 275 -#define MASKWALL1 285 -#define W_TECHWALL1 293 -#define W_TECHWALL2 297 -#define W_TECHWALL15 299 -#define W_TECHWALL3 301 -#define W_TECHWALL4 305 -#define W_TECHWALL10 306 -#define W_TECHWALL16 307 -#define WATERTILE2 336 -#define BPANNEL1 341 -#define PANNEL1 342 -#define PANNEL2 343 -#define WATERTILE 344 -#define STATIC 351 -#define W_SCREENBREAK 357 -#define W_HITTECHWALL3 360 -#define W_HITTECHWALL4 361 -#define W_HITTECHWALL2 362 -#define W_HITTECHWALL1 363 -#define MASKWALL10 387 -#define MASKWALL11 391 -#define DOORTILE22 395 -#define FANSPRITE 407 -#define FANSPRITEBROKE 411 -#define FANSHADOW 412 -#define FANSHADOWBROKE 416 -#define DOORTILE18 447 -#define DOORTILE19 448 -#define DOORTILE20 449 -#define SPACESHUTTLE 487 -#define SATELLITE 489 -#define VIEWSCREEN2 499 -#define VIEWSCREENBROKE 501 -#define VIEWSCREEN 502 -#define GLASS 503 -#define GLASS2 504 -#define STAINGLASS1 510 -#define MASKWALL5 514 -#define SATELITE 516 -#define FUELPOD 517 -#define SLIMEPIPE 538 -#define CRACK1 546 -#define CRACK2 547 -#define CRACK3 548 -#define CRACK4 549 -#define FOOTPRINTS 550 -#define DOMELITE 551 -#define CAMERAPOLE 554 -#define CHAIR1 556 -#define CHAIR2 557 -#define BROKENCHAIR 559 -#define MIRROR 560 -#define WATERFOUNTAIN 563 -#define WATERFOUNTAINBROKE 567 -#define FEMMAG1 568 -#define TOILET 569 -#define STALL 571 -#define STALLBROKE 573 -#define FEMMAG2 577 -#define REACTOR2 578 -#define REACTOR2BURNT 579 -#define REACTOR2SPARK 580 -#define GRATE1 595 -#define BGRATE1 596 -#define SOLARPANNEL 602 -#define NAKED1 603 -#define ANTENNA 607 -#define MASKWALL12 609 -#define TOILETBROKE 615 -#define PIPE2 616 -#define PIPE1B 617 -#define PIPE3 618 -#define PIPE1 619 -#define CAMERA1 621 -#define BRICK 626 -#define SPLINTERWOOD 630 -#define PIPE2B 633 -#define BOLT1 634 -#define W_NUMBERS 640 -#define WATERDRIP 660 -#define WATERBUBBLE 661 -#define WATERBUBBLEMAKER 662 -#define W_FORCEFIELD 663 -#define VACUUM 669 -#define FOOTPRINTS2 672 -#define FOOTPRINTS3 673 -#define FOOTPRINTS4 674 -#define EGG 675 -#define SCALE 678 -#define CHAIR3 680 -#define CAMERALIGHT 685 -#define MOVIECAMERA 686 -#define IVUNIT 689 -#define POT1 694 -#define POT2 695 -#define POT3 697 -#define PIPE3B 700 -#define WALLLIGHT3 701 -#define WALLLIGHTBUST3 702 -#define WALLLIGHT1 703 -#define WALLLIGHTBUST1 704 -#define WALLLIGHT2 705 -#define WALLLIGHTBUST2 706 -#define LIGHTSWITCH2 712 -#define WAITTOBESEATED 716 -#define DOORTILE14 717 -#define STATUE 753 -#define MIKE 762 -#define VASE 765 -#define SUSHIPLATE1 768 -#define SUSHIPLATE2 769 -#define SUSHIPLATE3 774 -#define SUSHIPLATE4 779 -#define DOORTILE16 781 -#define SUSHIPLATE5 792 -#define OJ 806 -#define MASKWALL13 830 -#define HURTRAIL 859 -#define POWERSWITCH1 860 -#define LOCKSWITCH1 862 -#define POWERSWITCH2 864 -#define ATM 867 -#define STATUEFLASH 869 -#define ATMBROKE 888 -#define BIGHOLE2 893 -#define STRIPEBALL 901 -#define QUEBALL 902 -#define POCKET 903 -#define WOODENHORSE 904 -#define TREE1 908 -#define TREE2 910 -#define CACTUS 911 -#define MASKWALL2 913 -#define MASKWALL3 914 -#define MASKWALL4 915 -#define FIREEXT 916 -#define TOILETWATER 921 -#define NEON1 925 -#define NEON2 926 -#define CACTUSBROKE 939 -#define BOUNCEMINE 940 -#define BROKEFIREHYDRENT 950 -#define BOX 951 -#define BULLETHOLE 952 -#define BOTTLE1 954 -#define BOTTLE2 955 -#define BOTTLE3 956 -#define BOTTLE4 957 -#define FEMPIC5 963 -#define FEMPIC6 964 -#define FEMPIC7 965 -#define HYDROPLANT 969 -#define OCEANSPRITE1 971 -#define OCEANSPRITE2 972 -#define OCEANSPRITE3 973 -#define OCEANSPRITE4 974 -#define OCEANSPRITE5 975 -#define GENERICPOLE 977 -#define CONE 978 -#define HANGLIGHT 979 -#define HYDRENT 981 -#define MASKWALL14 988 -#define TIRE 990 -#define PIPE5 994 -#define PIPE6 995 -#define PIPE4 996 -#define PIPE4B 997 -#define BROKEHYDROPLANT 1003 -#define PIPE5B 1005 -#define NEON3 1007 -#define NEON4 1008 -#define NEON5 1009 -#define BOTTLE5 1012 -#define BOTTLE6 1013 -#define BOTTLE8 1014 -#define SPOTLITE 1020 -#define HANGOOZ 1022 -#define MASKWALL15 1024 -#define BOTTLE7 1025 -#define HORSEONSIDE 1026 -#define GLASSPIECES 1031 -#define HORSELITE 1034 -#define DONUTS 1045 -#define NEON6 1046 -#define MASKWALL6 1059 -#define CLOCK 1060 -#define RUBBERCAN 1062 -#define BROKENCLOCK 1067 -#define PLUG 1069 -#define OOZFILTER 1079 -#define FLOORPLASMA 1082 -#define REACTOR 1088 -#define REACTORSPARK 1092 -#define REACTORBURNT 1096 -#define DOORTILE15 1102 -#define HANDSWITCH 1111 -#define CIRCLEPANNEL 1113 -#define CIRCLEPANNELBROKE 1114 -#define PULLSWITCH 1122 -#define MASKWALL8 1124 -#define BIGHOLE 1141 -#define ALIENSWITCH 1142 -#define DOORTILE21 1144 -#define HANDPRINTSWITCH 1155 -#define BOTTLE10 1157 -#define BOTTLE11 1158 -#define BOTTLE12 1159 -#define BOTTLE13 1160 -#define BOTTLE14 1161 -#define BOTTLE15 1162 -#define BOTTLE16 1163 -#define BOTTLE17 1164 -#define BOTTLE18 1165 -#define BOTTLE19 1166 -#define DOORTILE17 1169 -#define MASKWALL7 1174 -#define JAILBARBREAK 1175 -#define DOORTILE11 1178 -#define DOORTILE12 1179 -#define VENDMACHINE 1212 -#define VENDMACHINEBROKE 1214 -#define COLAMACHINE 1215 -#define COLAMACHINEBROKE 1217 -#define CRANEPOLE 1221 -#define CRANE 1222 -#define BARBROKE 1225 -#define BLOODPOOL 1226 -#define NUKEBARREL 1227 -#define NUKEBARRELDENTED 1228 -#define NUKEBARRELLEAKED 1229 -#define CANWITHSOMETHING 1232 -#define MONEY 1233 -#define BANNER 1236 -#define EXPLODINGBARREL 1238 -#define EXPLODINGBARREL2 1239 -#define FIREBARREL 1240 -#define SEENINE 1247 -#define SEENINEDEAD 1248 -#define STEAM 1250 -#define CEILINGSTEAM 1255 -#define PIPE6B 1260 -#define TRANSPORTERBEAM 1261 -#define RAT 1267 -#define TRASH 1272 -#define FEMPIC1 1280 -#define FEMPIC2 1289 -#define BLANKSCREEN 1293 -#define PODFEM1 1294 -#define FEMPIC3 1298 -#define FEMPIC4 1306 -#define FEM1 1312 -#define FEM2 1317 -#define FEM3 1321 -#define FEM5 1323 -#define BLOODYPOLE 1324 -#define FEM4 1325 -#define FEM6 1334 -#define FEM6PAD 1335 -#define FEM8 1336 -#define HELECOPT 1346 -#define FETUSJIB 1347 -#define HOLODUKE 1348 -#define SPACEMARINE 1353 -#define INDY 1355 -#define FETUS 1358 -#define FETUSBROKE 1359 -#define MONK 1352 -#define LUKE 1354 -#define COOLEXPLOSION1 1360 -#define WATERSPLASH2 1380 -#define FIREVASE 1390 -#define SCRATCH 1393 -#define FEM7 1395 -#define APLAYERTOP 1400 -#define APLAYER 1405 -#define PLAYERONWATER 1420 -#define DUKELYINGDEAD 1518 -#define DUKETORSO 1520 -#define DUKEGUN 1528 -#define DUKELEG 1536 -#define SHARK 1550 -#define BLOOD 1620 -#define FIRELASER 1625 -#define TRANSPORTERSTAR 1630 -#define SPIT 1636 -#define LOOGIE 1637 -#define FIST 1640 -#define FREEZEBLAST 1641 -#define DEVISTATORBLAST 1642 -#define SHRINKSPARK 1646 -#define TONGUE 1647 -#define MORTER 1650 -#define SHRINKEREXPLOSION 1656 -#define RADIUSEXPLOSION 1670 -#define FORCERIPPLE 1671 -#define LIZTROOP 1680 -#define LIZTROOPRUNNING 1681 -#define LIZTROOPSTAYPUT 1682 -#define LIZTOP 1705 -#define LIZTROOPSHOOT 1715 -#define LIZTROOPJETPACK 1725 -#define LIZTROOPDSPRITE 1734 -#define LIZTROOPONTOILET 1741 -#define LIZTROOPJUSTSIT 1742 -#define LIZTROOPDUCKING 1744 -#define HEADJIB1 1768 -#define ARMJIB1 1772 -#define LEGJIB1 1776 -#define CANNON 1810 -#define CANNONBALL 1817 -#define CANNONBALLS 1818 -#define OCTABRAIN 1820 -#define OCTABRAINSTAYPUT 1821 -#define OCTATOP 1845 -#define OCTADEADSPRITE 1855 -#define INNERJAW 1860 -#define DRONE 1880 -#define EXPLOSION2 1890 -#define COMMANDER 1920 -#define COMMANDERSTAYPUT 1921 -#define RECON 1960 -#define TANK 1975 -#define PIGCOP 2000 -#define PIGCOPSTAYPUT 2001 -#define PIGCOPDIVE 2045 -#define PIGCOPDEADSPRITE 2060 -#define PIGTOP 2061 -#define LIZMAN 2120 -#define LIZMANSTAYPUT 2121 -#define LIZMANSPITTING 2150 -#define LIZMANFEEDING 2160 -#define LIZMANJUMP 2165 -#define LIZMANDEADSPRITE 2185 -#define FECES 2200 -#define LIZMANHEAD1 2201 -#define LIZMANARM1 2205 -#define LIZMANLEG1 2209 -#define EXPLOSION2BOT 2219 -#define USERWEAPON 2235 -#define HEADERBAR 2242 -#define JIBS1 2245 -#define JIBS2 2250 -#define JIBS3 2255 -#define JIBS4 2260 -#define JIBS5 2265 -#define BURNING 2270 -#define FIRE 2271 -#define JIBS6 2286 -#define BLOODSPLAT1 2296 -#define BLOODSPLAT3 2297 -#define BLOODSPLAT2 2298 -#define BLOODSPLAT4 2299 -#define OOZ 2300 -#define OOZ2 2309 -#define WALLBLOOD1 2301 -#define WALLBLOOD2 2302 -#define WALLBLOOD3 2303 -#define WALLBLOOD4 2304 -#define WALLBLOOD5 2305 -#define WALLBLOOD6 2306 -#define WALLBLOOD7 2307 -#define WALLBLOOD8 2308 -#define BURNING2 2310 -#define FIRE2 2311 -#define CRACKKNUCKLES 2324 -#define SMALLSMOKE 2329 -#define SMALLSMOKEMAKER 2330 -#define FLOORFLAME 2333 -#define ROTATEGUN 2360 -#define GREENSLIME 2370 -#define WATERDRIPSPLASH 2380 -#define SCRAP6 2390 -#define SCRAP1 2400 -#define SCRAP2 2404 -#define SCRAP3 2408 -#define SCRAP4 2412 -#define SCRAP5 2416 -#define ORGANTIC 2420 -#define BETAVERSION 2440 -#define PLAYERISHERE 2442 -#define PLAYERWASHERE 2443 -#define SELECTDIR 2444 -#define F1HELP 2445 -#define NOTCHON 2446 -#define NOTCHOFF 2447 -#define GROWSPARK 2448 -#define DUKEICON 2452 -#define BADGUYICON 2453 -#define FOODICON 2454 -#define GETICON 2455 -#define MENUSCREEN 2456 -#define MENUBAR 2457 -#define KILLSICON 2458 -#define FIRSTAID_ICON 2460 -#define HEAT_ICON 2461 -#define BOTTOMSTATUSBAR 2462 -#define BOOT_ICON 2463 -#define FRAGBAR 2465 -#define JETPACK_ICON 2467 -#define AIRTANK_ICON 2468 -#define STEROIDS_ICON 2469 -#define HOLODUKE_ICON 2470 -#define ACCESS_ICON 2471 -#define DIGITALNUM 2472 -#define DUKECAR 2491 -#define CAMCORNER 2482 -#define CAMLIGHT 2484 -#define LOGO 2485 -#define TITLE 2486 -#define NUKEWARNINGICON 2487 -#define MOUSECURSOR 2488 -#define SLIDEBAR 2489 -#define DREALMS 2492 -#define BETASCREEN 2493 -#define WINDOWBORDER1 2494 -#define TEXTBOX 2495 -#define WINDOWBORDER2 2496 -#define DUKENUKEM 2497 -#define THREEDEE 2498 -#define INGAMEDUKETHREEDEE 2499 -#define TENSCREEN 2500 -#define PLUTOPAKSPRITE 2501 -#define DEVISTATOR 2510 -#define KNEE 2521 -#define CROSSHAIR 2523 -#define FIRSTGUN 2524 -#define FIRSTGUNRELOAD 2528 -#define FALLINGCLIP 2530 -#define CLIPINHAND 2531 -#define HAND 2532 -#define SHELL 2533 -#define SHOTGUNSHELL 2535 -#define CHAINGUN 2536 -#define RPGGUN 2544 -#define RPGMUZZLEFLASH 2545 -#define FREEZE 2548 -#define CATLITE 2552 -#define SHRINKER 2556 -#define HANDHOLDINGLASER 2563 -#define TRIPBOMB 2566 -#define LASERLINE 2567 -#define HANDHOLDINGACCESS 2568 -#define HANDREMOTE 2570 -#define HANDTHROW 2573 -#define TIP 2576 -#define GLAIR 2578 -#define SCUBAMASK 2581 -#define SPACEMASK 2584 -#define FORCESPHERE 2590 -#define SHOTSPARK1 2595 -#define RPG 2605 -#define LASERSITE 2612 -#define SHOTGUN 2613 -#define BOSS1 2630 -#define BOSS1STAYPUT 2631 -#define BOSS1SHOOT 2660 -#define BOSS1LOB 2670 -#define BOSSTOP 2696 -#define BOSS2 2710 -#define BOSS3 2760 -#define SPINNINGNUKEICON 2813 -#define BIGFNTCURSOR 2820 -#define SMALLFNTCURSOR 2821 -#define STARTALPHANUM 2822 -#define ENDALPHANUM 2915 -#define BIGALPHANUM 2940 -#define BIGPERIOD 3002 -#define BIGCOMMA 3003 -#define BIGX 3004 -#define BIGQ 3005 -#define BIGSEMI 3006 -#define BIGCOLIN 3007 -#define THREEBYFIVE 3010 -#define BIGAPPOS 3022 -#define BLANK 3026 -#define MINIFONT 3072 -#define BUTTON1 3164 -#define GLASS3 3187 -#define RESPAWNMARKERRED 3190 -#define RESPAWNMARKERYELLOW 3200 -#define RESPAWNMARKERGREEN 3210 -#define BONUSSCREEN 3240 -#define VIEWBORDER 3250 -#define VICTORY1 3260 -#define ORDERING 3270 -#define TEXTSTORY 3280 -#define LOADSCREEN 3281 -#define BORNTOBEWILDSCREEN 3370 -#define BLIMP 3400 -#define FEM9 3450 -#define FOOTPRINT 3701 -#define FRAMEEFFECT1_13 3999 -#define POOP 4094 -#define FRAMEEFFECT1 4095 -#define PANNEL3 4099 -#define SCREENBREAK14 4120 -#define SCREENBREAK15 4123 -#define SCREENBREAK19 4125 -#define SCREENBREAK16 4127 -#define SCREENBREAK17 4128 -#define SCREENBREAK18 4129 -#define W_TECHWALL11 4130 -#define W_TECHWALL12 4131 -#define W_TECHWALL13 4132 -#define W_TECHWALL14 4133 -#define W_TECHWALL5 4134 -#define W_TECHWALL6 4136 -#define W_TECHWALL7 4138 -#define W_TECHWALL8 4140 -#define W_TECHWALL9 4142 -#define BPANNEL3 4100 -#define W_HITTECHWALL16 4144 -#define W_HITTECHWALL10 4145 -#define W_HITTECHWALL15 4147 -#define W_MILKSHELF 4181 -#define W_MILKSHELFBROKE 4203 -#define PURPLELAVA 4240 -#define LAVABUBBLE 4340 -#define DUKECUTOUT 4352 -#define TARGET 4359 -#define GUNPOWDERBARREL 4360 -#define DUCK 4361 -#define HATRACK 4367 -#define DESKLAMP 4370 -#define COFFEEMACHINE 4372 -#define CUPS 4373 -#define GAVALS 4374 -#define GAVALS2 4375 -#define POLICELIGHTPOLE 4377 -#define FLOORBASKET 4388 -#define PUKE 4389 -#define DOORTILE23 4391 -#define TOPSECRET 4396 -#define SPEAKER 4397 -#define TEDDYBEAR 4400 -#define ROBOTDOG 4402 -#define ROBOTPIRATE 4404 -#define ROBOTMOUSE 4407 -#define MAIL 4410 -#define MAILBAG 4413 -#define HOTMEAT 4427 -#define COFFEEMUG 4438 -#define DONUTS2 4440 -#define TRIPODCAMERA 4444 -#define METER 4453 -#define DESKPHONE 4454 -#define GUMBALLMACHINE 4458 -#define GUMBALLMACHINEBROKE 4459 -#define PAPER 4460 -#define MACE 4464 -#define GENERICPOLE2 4465 -#define XXXSTACY 4470 -#define WETFLOOR 4495 -#define BROOM 4496 -#define MOP 4497 -#define LETTER 4502 -#define PIRATE1A 4510 -#define PIRATE4A 4511 -#define PIRATE2A 4512 -#define PIRATE5A 4513 -#define PIRATE3A 4514 -#define PIRATE6A 4515 -#define PIRATEHALF 4516 -#define CHESTOFGOLD 4520 -#define SIDEBOLT1 4525 -#define FOODOBJECT1 4530 -#define FOODOBJECT2 4531 -#define FOODOBJECT3 4532 -#define FOODOBJECT4 4533 -#define FOODOBJECT5 4534 -#define FOODOBJECT6 4535 -#define FOODOBJECT7 4536 -#define FOODOBJECT8 4537 -#define FOODOBJECT9 4538 -#define FOODOBJECT10 4539 -#define FOODOBJECT11 4540 -#define FOODOBJECT12 4541 -#define FOODOBJECT13 4542 -#define FOODOBJECT14 4543 -#define FOODOBJECT15 4544 -#define FOODOBJECT16 4545 -#define FOODOBJECT17 4546 -#define FOODOBJECT18 4547 -#define FOODOBJECT19 4548 -#define FOODOBJECT20 4549 -#define HEADLAMP 4550 -#define TAMPON 4557 -#define SKINNEDCHICKEN 4554 -#define FEATHEREDCHICKEN 4555 -#define ROBOTDOG2 4560 -#define JOLLYMEAL 4569 -#define DUKEBURGER 4570 -#define SHOPPINGCART 4576 -#define CANWITHSOMETHING2 4580 -#define CANWITHSOMETHING3 4581 -#define CANWITHSOMETHING4 4582 -#define SNAKEP 4590 -#define DOLPHIN1 4591 -#define DOLPHIN2 4592 -#define NEWBEAST 4610 -#define NEWBEASTSTAYPUT 4611 -#define NEWBEASTJUMP 4690 -#define NEWBEASTHANG 4670 -#define NEWBEASTHANGDEAD 4671 -#define BOSS4 4740 -#define BOSS4STAYPUT 4741 -#define FEM10 4864 -#define TOUGHGAL 4866 -#define MAN 4871 -#define MAN2 4872 -#define WOMAN 4874 -#define PLEASEWAIT 4887 -#define NATURALLIGHTNING 4890 -#define WEATHERWARN 4893 -#define DUKETAG 4900 -#define SIGN1 4909 -#define SIGN2 4912 -#define JURYGUY 4943 - -// These tile positions are reserved! -#define RESERVEDSLOT1 6132 -#define RESERVEDSLOT2 6133 -#define RESERVEDSLOT3 6134 -#define RESERVEDSLOT4 6135 -#define RESERVEDSLOT5 6136 -#define RESERVEDSLOT6 6137 -#define RESERVEDSLOT7 6138 -#define RESERVEDSLOT8 6139 -#define RESERVEDSLOT9 6140 -#define RESERVEDSLOT10 6141 -#define RESERVEDSLOT11 6142 -#define RESERVEDSLOT12 6143 diff --git a/source/duke3d/src/namesdyn.cpp b/source/duke3d/src/namesdyn.cpp index ac381ca07..d4b8fb520 100644 --- a/source/duke3d/src/namesdyn.cpp +++ b/source/duke3d/src/namesdyn.cpp @@ -27,14 +27,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "namesdyn.h" #include "global.h" +#include "gamecontrol.h" BEGIN_DUKE_NS -#ifdef DYNTILEREMAP_ENABLE # define DVPTR(x) &x -#else -# define DVPTR(x) NULL -#endif int16_t DynamicTileMap[MAXTILES]; @@ -170,6 +167,9 @@ LUNATIC_EXTERN struct dynitem g_dynTileList[] = { "CRACKKNUCKLES", DVPTR(CRACKKNUCKLES), CRACKKNUCKLES__STATIC }, { "CRANE", DVPTR(CRANE), CRANE__STATIC }, { "CRANEPOLE", DVPTR(CRANEPOLE), CRANEPOLE__STATIC }, + { "CREDITSTEXT1", DVPTR(CREDITSTEXT1), CREDITSTEXT1__STATIC }, + { "CREDITSTEXT2", DVPTR(CREDITSTEXT2), CREDITSTEXT2__STATIC }, + { "CREDITSTEXT3", DVPTR(CREDITSTEXT3), CREDITSTEXT3__STATIC }, { "CROSSHAIR", DVPTR(CROSSHAIR), CROSSHAIR__STATIC }, { "CRYSTALAMMO", DVPTR(CRYSTALAMMO), CRYSTALAMMO__STATIC }, { "CYCLER", DVPTR(CYCLER), CYCLER__STATIC }, @@ -642,7 +642,7 @@ LUNATIC_EXTERN struct dynitem g_dynTileList[] = { "XXXSTACY", DVPTR(XXXSTACY), XXXSTACY__STATIC }, }; -#ifdef DYNTILEREMAP_ENABLE + int32_t ACCESS_ICON = ACCESS_ICON__STATIC; int32_t ACCESSCARD = ACCESSCARD__STATIC; int32_t ACCESSSWITCH = ACCESSSWITCH__STATIC; @@ -766,6 +766,9 @@ int32_t CRACK4 = CRACK4__STATIC; int32_t CRACKKNUCKLES = CRACKKNUCKLES__STATIC; int32_t CRANE = CRANE__STATIC; int32_t CRANEPOLE = CRANEPOLE__STATIC; +int32_t CREDITSTEXT1 = CREDITSTEXT1__STATIC; +int32_t CREDITSTEXT2 = CREDITSTEXT2__STATIC; +int32_t CREDITSTEXT3 = CREDITSTEXT3__STATIC; int32_t CROSSHAIR = CROSSHAIR__STATIC; int32_t CRYSTALAMMO = CRYSTALAMMO__STATIC; int32_t CYCLER = CYCLER__STATIC; @@ -1237,7 +1240,6 @@ int32_t WOMAN = WOMAN__STATIC; int32_t WOODENHORSE = WOODENHORSE__STATIC; int32_t XXXSTACY = XXXSTACY__STATIC; -#if !defined LUNATIC static hashtable_t h_names = {512, NULL}; void G_ProcessDynamicTileMapping(const char *szLabel, int32_t lValue) @@ -1250,10 +1252,6 @@ void G_ProcessDynamicTileMapping(const char *szLabel, int32_t lValue) if (i>=0) { struct dynitem *di = &g_dynTileList[i]; -#ifdef DEBUGGINGAIDS - if (g_scriptDebug && di->staticval != lValue) - OSD_Printf("REMAP %s (%d) --> %d\n", di->str, di->staticval, lValue); -#endif *di->dynvalptr = lValue; } } @@ -1270,8 +1268,6 @@ void freehashnames(void) { hash_free(&h_names); } -#endif -#endif // This is run after all CON define's have been processed to set up the // dynamic->static tile mapping. @@ -1280,11 +1276,10 @@ void G_InitDynamicTiles(void) Bmemset(DynamicTileMap, 0, sizeof(DynamicTileMap)); for (auto & i : g_dynTileList) -#ifdef DYNTILEREMAP_ENABLE + { DynamicTileMap[*(i.dynvalptr)] = i.staticval; -#else - DynamicTileMap[i.staticval] = i.staticval; -#endif + NameToTileIndex.Insert(i.str, *(i.dynvalptr)); + } g_blimpSpawnItems[0] = RPGSPRITE; g_blimpSpawnItems[1] = CHAINGUNSPRITE; @@ -1314,10 +1309,5 @@ void G_InitDynamicTiles(void) WeaponPickupSprites[9] = FREEZESPRITE; WeaponPickupSprites[10] = HEAVYHBOMB; WeaponPickupSprites[11] = SHRINKERSPRITE; - - // ouch... the big background image takes up a fuckload of memory and takes a second to load! -#ifdef EDUKE32_GLES - MENUSCREEN = LOADSCREEN = BETASCREEN; -#endif } END_DUKE_NS diff --git a/source/duke3d/src/namesdyn.h b/source/duke3d/src/namesdyn.h index c87b2e06a..6b5dcfe24 100644 --- a/source/duke3d/src/namesdyn.h +++ b/source/duke3d/src/namesdyn.h @@ -26,9 +26,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_DUKE_NS -#define DYNTILEREMAP_ENABLE - - #define SECTOREFFECTOR__STATIC 1 #define ACTIVATOR__STATIC 2 #define TOUCHPLATE__STATIC 3 @@ -505,6 +502,9 @@ BEGIN_DUKE_NS #define INGAMEDUKETHREEDEE__STATIC 2499 #define TENSCREEN__STATIC 2500 #define PLUTOPAKSPRITE__STATIC 2501 +#define CREDITSTEXT1__STATIC 2504 +#define CREDITSTEXT2__STATIC 2505 +#define CREDITSTEXT3__STATIC 2506 #define DEVISTATOR__STATIC 2510 #define KNEE__STATIC 2521 #define CROSSHAIR__STATIC 2523 @@ -627,8 +627,6 @@ extern int16_t DynamicTileMap[MAXTILES]; void G_InitDynamicTiles(void); -#ifdef DYNTILEREMAP_ENABLE - void G_ProcessDynamicTileMapping(const char *szLabel, int32_t lValue); #if !defined LUNATIC @@ -759,6 +757,9 @@ extern int32_t CRACK4; extern int32_t CRACKKNUCKLES; extern int32_t CRANE; extern int32_t CRANEPOLE; +extern int32_t CREDITSTEXT1; +extern int32_t CREDITSTEXT2; +extern int32_t CREDITSTEXT3; extern int32_t CROSSHAIR; extern int32_t CRYSTALAMMO; extern int32_t CYCLER; @@ -1232,22 +1233,6 @@ extern int32_t XXXSTACY; #define DYNAMICTILEMAP(Tilenum) (DynamicTileMap[Tilenum]) -#else /* if !defined DYNTILEREMAP_ENABLE */ - -#define G_ProcessDynamicTileMapping(x, y) ((void)(0)) - -#define inithashnames() ((void)0) -#define freehashnames() ((void)0) - -#include "names.h" -#undef SPACESHUTTLE -#undef CANNON -#undef CANNONBALLS - -#define DYNAMICTILEMAP(Tilenum) (Tilenum) - -#endif - END_DUKE_NS #endif // namesdyn_h__ diff --git a/source/rr/src/namesdyn.cpp b/source/rr/src/namesdyn.cpp index 4a3ee6a87..99bea9a07 100644 --- a/source/rr/src/namesdyn.cpp +++ b/source/rr/src/namesdyn.cpp @@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "namesdyn.h" #include "global.h" +#include "gamecontrol.h" BEGIN_RR_NS @@ -2965,6 +2966,7 @@ void G_InitDynamicTiles(void) *(g_dynTileList[i].dynvalptr) = -g_dynTileList[i].staticval_rr; if (RRRA && *(g_dynTileList[i].dynvalptr) == -UFO1__STATICRR) *(g_dynTileList[i].dynvalptr) = -UFO1__STATICRRRA; DynamicTileMap[*(g_dynTileList[i].dynvalptr)] = g_dynTileList[i].staticval_rr; + NameToTileIndex.Insert(g_dynTileList[i].str, *(g_dynTileList[i].dynvalptr)); } for (i = 0; g_dynWeaponList[i].staticval >= 0; i++) *(g_dynWeaponList[i].dynvalptr) = g_dynWeaponList[i].staticval_rr; @@ -2974,7 +2976,10 @@ void G_InitDynamicTiles(void) for (i=0; g_dynTileList[i].staticval >= 0; i++) if (g_dynTileList[i].staticval > 0) + { DynamicTileMap[*(g_dynTileList[i].dynvalptr)] = g_dynTileList[i].staticval; + NameToTileIndex.Insert(g_dynTileList[i].str, *(g_dynTileList[i].dynvalptr)); + } for (i=0; g_dynWeaponList[i].staticval >= 0; i++) DynamicWeaponMap[*(g_dynWeaponList[i].dynvalptr)] = g_dynWeaponList[i].staticval; diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 3fc40df5a..d8f9c80eb 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -1,13 +1,13 @@ //------------------------------------------------------------------------------------------- // -// +// Main Memu // //------------------------------------------------------------------------------------------- LISTMENU "MainMenu" { ScriptId 0 - ifgame(Duke, Nam, WW2GI, Fury) + ifgame(Duke, Nam, WW2GI, Fury, Redneck, RedneckRides) { ifgame(fury) { @@ -20,7 +20,14 @@ LISTMENU "MainMenu" centermenu animatedtransition } - class "Duke.MainMenu" + ifgame(Duke, Nam, WW2GI, Fury) + { + class "Duke.ListMenu" + } + else + { + class "Redneck.ListMenu" + } NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" //NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) ifgame(fury) @@ -36,16 +43,6 @@ LISTMENU "MainMenu" NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" } - ifgame(Redneck, RedneckRides) - { - NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" - //NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) - NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" - NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" - NativeTextItem "$MNU_HELP", "h", "HelpMenu" - NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" - NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" - } ifgame(Blood) { NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" @@ -67,6 +64,11 @@ LISTMENU "MainMenu" } } +//------------------------------------------------------------------------------------------- +// +// Ingame Memu (same as above with a few more options) +// +//------------------------------------------------------------------------------------------- LISTMENU "IngameMenu" { @@ -84,19 +86,14 @@ LISTMENU "IngameMenu" centermenu animatedtransition } - linespacing 15 - class "Duke.MainMenu" - NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" - NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" - NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" - NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" - NativeTextItem "$MNU_HELP", "h", "HelpMenu" - NativeTextItem "$MNU_ENDGAME", "e", "QuitToMenu" - NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" - } - ifgame(Redneck, RedneckRides) - { - linespacing 15 + ifgame(Duke, Nam, WW2GI, Fury) + { + class "Duke.ListMenu" + } + else + { + class "Redneck.ListMenu" + } NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" @@ -128,24 +125,36 @@ LISTMENU "IngameMenu" } } +//------------------------------------------------------------------------------------------- +// +// Episode and skill menu are filled in programmatically +// +//------------------------------------------------------------------------------------------- + LISTMENU "EpisodeMenu" { - ifgame(Duke, Nam, WW2GI, Fury) // Ion Fury does not use this menu. + ifgame(Duke, Nam, WW2GI, Fury, Redneck, RedneckRides) // Ion Fury does not use this menu. { caption "$MNU_SELECTEPISODE" position 160, 48, 142 centermenu fixedspacing 5 animatedtransition - class "Duke.ListMenu" + ifgame(Duke, Nam, WW2GI, Fury) + { + class "Duke.ListMenu" + } + else + { + class "Redneck.ListMenu" + } } - ScriptId 100 } LISTMENU "SkillMenu" { - ifgame(Duke, Nam, WW2GI, Fury) // Ion Fury does not use this menu. + ifgame(Duke, Nam, WW2GI, Fury, Redneck, RedneckRides) { ifgame(fury) { @@ -160,13 +169,25 @@ LISTMENU "SkillMenu" } caption "$MNU_SELECTSKILL" fixedspacing 5 - class "Duke.ListMenu" + ifgame(Duke, Nam, WW2GI, Fury) + { + class "Duke.ListMenu" + } + else + { + class "Redneck.ListMenu" + } animatedtransition } ScriptId 110 } +//------------------------------------------------------------------------------------------- +// // The custom menus are only supported by the EDuke32 frontend. +// +//------------------------------------------------------------------------------------------- + LISTMENU "CustomGameMenu" { caption "$MNU_NEWGAME" @@ -305,14 +326,27 @@ LISTMENU "CustomSubMenu7" class "Duke.ListMenu" } +//------------------------------------------------------------------------------------------- +// +// No multiplayer support for now, but kept as a reminder. +// +//------------------------------------------------------------------------------------------- + LISTMENU "MultiMenu" { - ifgame(Duke, Nam, WW2GI, Fury) // Ion Fury does not use this menu. + ifgame(Duke, Nam, WW2GI, Fury) { position 160, 55, 135 centermenu fixedspacing 5 - class "Duke.ListMenu" + ifgame(Duke, Nam, WW2GI, Fury) + { + class "Duke.ListMenu" + } + else + { + class "Redneck.ListMenu" + } animatedtransition } @@ -321,3 +355,106 @@ LISTMENU "MultiMenu" NativeTextItem "$MNU_JOINGAME", "j", "JoinGameMenu" NativeTextItem "$MNU_HOSTGAME", "h", "HostGameMenu" } + +//------------------------------------------------------------------------------------------- +// +// +// +//------------------------------------------------------------------------------------------- + +ImageScroller "HelpMenu" +{ + ifgame(Duke, Nam, WW2GI, Fury) + { + ImageItem "TEXTSTORY", 400 + ImageItem "F1HELP", 401 + } + ifgame(Redneck, RedneckRides) + { + ImageItem "TEXTSTORY" + ImageItem "F1HELP" + ImageItem "RRTILE1636" + } +} + +//------------------------------------------------------------------------------------------- +// +// Credits menu. This is logically highly game specific. +// Note that this has been split into two submenus so that the engine +// credits can be handled in a generic fashion instead of having to define +// them for each game natively. +// +// Engine credits are now in the options menu, i.e. the generic part of the menu. +// +//------------------------------------------------------------------------------------------- + +ImageScroller "CreditsMenu" +{ + ifgame(Duke, Nam, WW2GI, Fury) + { + ImageItem "CREDITSTEXT1", 990 + ImageItem "CREDITSTEXT2", 991 + ImageItem "CREDITSTEXT3", 992 + } + ifgame(Redneck) + { + // no point putting this into the string table. + TextItem "ORIGINAL CONCEPT, DESIGN AND DIRECTION\n\nDREW MARKHAM", 80 + TextItem "PRODUCED BY\n\nGREG GOODRICH", 80 + TextItem "GAME PROGRAMMING\n\nRAFAEL PAIZ", 80 + TextItem "ART DIRECTORS\n\nCLAIRE PRADERIE MAXX KAUFMAN ", 80 + TextItem "LEAD LEVEL DESIGNER\nALEX MAYBERRY\n\nLEVEL DESIGN\nMAL BLACKWELL\nSVERRE KVERNMO", 80 + TextItem "SENIOR ANIMATOR AND ARTIST\n\nJASON HOOVER", 80 + TextItem "TECHNICAL DIRECTOR\n\nBARRY DEMPSEY", 80 + TextItem "MOTION CAPTURE SPECIALIST AND\nCHARACTER ANIMATION\nAMIT DORON\n\nA.I. PROGRAMMING\nARTHUR DONAVAN\n\nADDITIONAL ANIMATION\nGEORGE KARL", 60 + TextItem "CHARACTER DESIGN\nCORKY LEHMKUHL\n\nMAP PAINTERS\n"VIKTOR ANTONOV\nMATTHIAS BEEGUER\nSTEPHAN BURLE\n\nSCULPTORS\nGEORGE ENGEL\nJAKE GARBER\nJEFF HIMMEL", 50 + TextItem "CHARACTER VOICES\n\nLEONARD\nBURTON GILLIAM\n\nBUBBA, BILLY RAY, SKINNY OL' COOT\nAND THE TURD MINION\nDREW MARKHAM\n\nSHERIFF LESTER T. HOBBES\nMOJO NIXON\n\nALIEN VIXEN\nPEGGY JO JACOBS", 40 + TextItem "SOUND DESIGN\nGARY BRADFIELD\n\nMUSIC\nMOJO NIXON\nTHE BEAT FARMERS\nTHE REVEREND HORTON HEAT\nCEMENT POND\n\nADDITIONAL SOUND EFFECTS\nJIM SPURGIN", 50 + TextItem "MOTION CAPTURE ACTOR\nJ.P. MANOUX\n\nMOTION CAPTURE VIXEN\nSHAWN WOLFE", 80 + TextItem "PRODUCTION ASSISTANCE\nMINERVA MAYBERRY\n\nNUTS AND BOLTS\nSTEVE GOLDBERG\nMARCUS HUTCHINSON\n\nBEAN COUNTING\nMAX YOSHIKAWA\n\nADMINISTRATIVE ASSISTANCE\nSERAFIN LEWIS", 50 + TextItem "LOCATION MANAGER, LOUISIANA\nRICK SKINNER\n\nLOCATION SCOUT, LOUISIANA\nBRIAN BENOS\n\nPHOTOGRAPHER\nCARLOS SERRAO", 70 + TextItem "ADDITIONAL 3D MODELING BY\n3 NAME 3D\nVIEWPOINT DATALABS INTERNATIONAL\n\nAUDIO RECORDED AT\nPACIFIC OCEAN POST, SANTA MONICA, C.A.\n\nCEMENT POND TRACKS RECORDED AT\nDREAMSTATE RECORDING, BURBANK, C.A.\n\nRECORDING ENGINEER\nDAVE AHLERT", 50 + TextItem "3D BUILD ENGINE LICENSED FROM\n3D REALMS ENTERTAINMENT\n\nBUILD ENGINE AND RELATED TOOLS\nCREATED BY KEN SILVERMAN", 80 + TextItem "FOR INTERPLAY\n\nLEAD TESTER\nDARRELL JONES\n\nTESTERS\nTIM ANDERSON\nERICK LUJAN\nTIEN TRAN", 60 + TextItem "IS TECHS\nBILL DELK\nAARON MEYERS\n\nCOMPATIBILITY TECHS\nMARC DURAN\nDAN FORSYTH\nDEREK GIBBS\nAARON OLAIZ\nJACK PARKER", 60 + TextItem "DIRECTOR OF COMPATIBILITY\nPHUONG NGUYEN\n\nASSISTANT QA DIRECTOR\nCOLIN TOTMAN\n\nQA DIRECTOR\nCHAD ALLISON", 70 + TextItem "INTERPLAY PRODUCER\nBILL DUGAN\n\nINTERPLAY LINE PRODUCER\nCHRIS BENSON\n\nPRODUCT MANAGER\nJIM VEEVAERT\n\nPUBLIC RELATIONS\nERIKA PRICE", 50 + TextItem "SPECIAL THANKS\n\nJIM GAUER\nPAUL VAIS\nSCOTT MILLER\nTODD REPLOGLE\nCHUCK BUECHE\nCARTER LIPSCOMB\nJOHN CONLEY\nDON MAGGI", 60 + TextItem "EXTRA SPECIAL THANKS\n\nBRIAN FARGO", 80 + TextItem "REDNECK RAMPAGE\n(c) 1997 XATRIX ENTERTAINMENT, INC.\n\nREDNECK RAMPAGE IS A TRADEMARK OF\nINTERPLAY PRODUCTIONS", 60 + } + ifgame(RedneckRides) + { + TextItem "ORIGINAL CONCEPT, DESIGN AND DIRECTION\n\nDREW MARKHAM", 80 + TextItem "ART DIRECTION AND ADDITIONAL DESIGN\n\nCORKY LEHMKUHL", 80 + TextItem "PRODUCED BY\n\nGREG GOODRICH", 80 + TextItem "GAME PROGRAMMING\n\nJOSEPH AURILI", 80 + TextItem "ORIGINAL GAME PROGRAMMING\n\nRAFAEL PAIZ", 80 + TextItem "LEVEL DESIGN\n\nRHETT BALDWIN & AARON BARBER", 80 + TextItem "ORIGINAL ART DIRECTION AND SUPPORT\n\nMAXX KAUFMAN & CLAIRE PRADERIE-MARKHAM", 80 + TextItem "COMPUTER GRAPHICS SUPERVISOR &\nCHARACTER ANIMATION DIRECTION\n\nBARRY DEMPSEY", 80 + TextItem "SENIOR ANIMATOR & MODELER\n\nJASON HOOVER", 80 + TextItem "CHARACTER ANIMATION &\nMOTION CAPTURE SPECIALIST\n\nAMIT DORON", 80 + TextItem "SOUND DESIGN &\nMUSIC PRODUCTION COORDINATION\n\nGARY BRADFIELD", 80 + TextItem "INTRODUCTION ANIMATION\n\nDOMINIQUE DROZDZ", 80 + TextItem "ARTIST\n\nMATTHIAS BEEGUER", 80 + TextItem "ADDITIONAL ART\n\nVIKTOR ANTONOV", 80 + TextItem "PRODUCTION COORDINATOR\n\nVICTORIA SYLVESTER", 80 + TextItem "CHARACTER VOICES\n\nLEONARD\nBURTON GILLIAM\n\nDAISY MAE\nTARA CHARENDOFF\n\nBUBBA, BILLY RAY, SKINNY OL' COOT,\nFRANK THE BIKER, THE TURD MINION\n& ALL OTHER VARIOUS RAMBLINGS...\nDREW MARKHAM", 40 + TextItem "SPECIAL APPEARENCE BY\n\nSHERIFF LESTER T. HOBBES\nMOJO NIXON\n\nALIEN VIXEN\nPEGGY JO JACOBS", 70 + TextItem "REDNECK RAMPAGE TITLE TRACK & CYBERSEX\nWRITTEN & PERFORMED BY\nMOJO NIXON\n\n(c) MUFFIN'STUFFIN' MUSIC (BMI)\nADMINISTERED BY BUG.", 70 + TextItem "MUSIC\n\nDISGRACELAND\nTINY D & THE SOFA KINGS\n\nBANJO AND GUITAR PICKIN\nJOHN SCHLOCKER\nHOWARD YEARWOOD", 60 + TextItem "RECORDING ENGINEER\nDAVE AHLERT\n\nRECORDING ASSISTANCE\nJEFF GILBERT", 80 + TextItem "MOTION CAPTURE ACTOR\nJ.P. MANOUX\n\nMOTION CAPTURE ACTRESS\nSHAWN WOLFE", 80 + TextItem "THIS GAME COULD NOT HAVE BEEN MADE WITHOUT\nALEX MAYBERRY\nMAL BLACKWELL\n\nNUTS AND BOLTS\nSTEVE GOLDBERG\n\nBEAN COUNTING\nMAX YOSHIKAWA\n\nADMINISTRATIVE ASSISTANCE\nMINERVA MAYBERRY", 50 + TextItem "FOR INTERPLAY\n\nPRODUCER\nBILL DUGAN\n\nLINE PRODUCER\nCHRIS BENSON\n\nLEAD TESTER\nDARRELL JONES", 60 + TextItem "TESTERS\n\nTIM ANDERSON\nPRIMO PULANCO\nMARK MCCARTY\nBRIAN AXLINE", 70 + TextItem "PRODUCTION BABY\n\nPAULINE MARIE MARKHAM", 80 + TextItem "ORIGINAL PRODUCTION BABY\n\nALYSON KAUFMAN", 80 + TextItem "3D BUILD ENGINE LICENSED FROM\n3D REALMS ENTERTAINMENT\n\nBUILD ENGINE AND RELATED TOOLS\nCREATED BY KEN SILVERMAN", 80 + TextItem "SPECIAL THANKS\n\nSCOTT MILLER\nGEORGE BROUSSARD", 80 + TextItem "EXTRA SPECIAL THANKS\n\nBRIAN FARGO", 80 + TextItem "REDNECK RAMPAGE RIDES AGAIN\n(c) 1998 XATRIX ENTERTAINMENT, INC.\n\nREDNECK RAMPAGE RIDES AGAIN\nIS A TRADEMARK OF\nINTERPLAY PRODUCTIONS", 70 + } +} + From b12377962a6b9b3265f3b0e66b6e5e1f0b33252a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 01:30:24 +0100 Subject: [PATCH 036/203] - moved the game interface function to d_menu --- source/duke3d/src/d_menu.cpp | 6 ++++++ source/duke3d/src/menus.cpp | 7 ------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 935b1b152..77bccbe91 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -416,6 +416,12 @@ class MainMenu : public DukeListMenu // //---------------------------------------------------------------------------- + +bool GameInterface::mouseInactiveConditional(bool condition) // can hopefully go away once the menu refactor is complete +{ + return condition; +} + void GameInterface::MenuOpened() { S_PauseSounds(true); diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index 0bf1c9322..ac6f30af6 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -5435,13 +5435,6 @@ bool GameInterface::mouseInactiveConditional(bool condition) return MOUSEINACTIVECONDITIONAL(condition); } -#else - -bool GameInterface::mouseInactiveConditional(bool condition) -{ - return condition; -} - #endif END_DUKE_NS From f62611e90df5e6f29ef1f55a9c4c3e072f7b3ab6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 01:49:50 +0100 Subject: [PATCH 037/203] - cleaned out a large chunk of menus.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … leaving only the parts still needed for reference. --- source/duke3d/src/menus.cpp | 3504 +---------------------------------- 1 file changed, 2 insertions(+), 3502 deletions(-) diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index ac6f30af6..18b1a50ff 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -55,87 +55,6 @@ BEGIN_DUKE_NS #define USERMAPENTRYLENGTH 25 -static FORCE_INLINE void Menu_StartTextInput() -{ - inputState.keyFlushChars(); - inputState.ClearKeysDown(); -} - -static FORCE_INLINE void Menu_StopTextInput() -{ -} - -static FORCE_INLINE void rotatesprite_ybounds(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, uint8_t dapalnum, int32_t dastat, int32_t ydim_upper, int32_t ydim_lower) -{ - rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, 0, ydim_upper, xdim-1, ydim_lower); -} - -static void mgametext(int32_t x, int32_t y, char const * t) -{ - G_ScreenText(MF_Bluefont.tilenum, x, y, MF_Bluefont.zoom, 0, 0, t, 0, MF_Bluefont.pal, 2|8|16|ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags, 0, 0, xdim-1, ydim-1); -} - - -#define mminitext(x,y,t,p) minitext_(x, y, t, 0, p, 2|8|16|ROTATESPRITE_FULL16) -#define mmenutext menutext - -#ifndef EDUKE32_STANDALONE -#endif -static void creditsminitext(int32_t x, int32_t y, const char *t, int32_t p) -{ - int32_t f = TEXT_XCENTER; - - if (!minitext_lowercase) - f |= TEXT_UPPERCASE; - - G_ScreenTextShadow(1, 1, MINIFONT, x, y, 65536, 0, 0, t, 0, p, 2|8|16|ROTATESPRITE_FULL16, 0, 4<<16, 8<<16, 1<<16, 0, f, 0, 0, xdim-1, ydim-1); -} - -#pragma pack(push,1) -static savehead_t savehead; -#pragma pack(pop) - -static void Menu_DrawTopBar(const vec2_t origin) -{ - if ((G_GetLogoFlags() & LOGO_NOTITLEBAR) == 0) - rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (19<<16), MF_Redfont.cursorScale, 0,MENUBAR,16,0,10); -} - -static void Menu_DrawTopBarCaption(const char *caption, const vec2_t origin) -{ - static char t[64]; - size_t const srclen = strlen(caption); - size_t const dstlen = min(srclen, ARRAY_SIZE(t)-1); - memcpy(t, caption, dstlen); - t[dstlen] = '\0'; - char *p = &t[dstlen-1]; - if (*p == ':') - *p = '\0'; - captionmenutext(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (24<<16) + ((15>>1)<<16), t); -} - -static void Menu_DrawCursorTextTile(int32_t x, int32_t y, int32_t h, int32_t picnum, vec2_16_t const & siz, int32_t ydim_upper = 0, int32_t ydim_lower = ydim-1) -{ - vec2_t const adjsiz = { (siz.x>>1)<<16, siz.y<<16 }; - Menu_DrawCursorCommon(x + scale(adjsiz.x, h, adjsiz.y), y, divscale16(h, adjsiz.y), picnum, ydim_upper, ydim_lower); -} -static void Menu_DrawCursorText(int32_t x, int32_t y, int32_t h, int32_t ydim_upper = 0, int32_t ydim_lower = ydim-1) -{ - vec2_16_t const & siz = tilesiz[SPINNINGNUKEICON]; - - if (FURY || siz.x == 0) - { - Menu_DrawCursorTextTile(x, y, h, SMALLFNTCURSOR, tilesiz[SMALLFNTCURSOR], ydim_upper, ydim_lower); - return; - } - - Menu_DrawCursorTextTile(x, y, h, SPINNINGNUKEICON+(((int32_t) totalclock>>3)%7), siz, ydim_upper, ydim_lower); -} - - -static uint16_t g_oldSaveCnt; - - /* @@ -151,11 +70,6 @@ they effectively stand in for curly braces as struct initializers. */ -static MenuMenuFormat_t MMF_Top_Main = { { MENU_MARGIN_CENTER<<16, 55<<16, }, -(170<<16) }; -static MenuMenuFormat_t MMF_Top_Episode = { { MENU_MARGIN_CENTER<<16, 48<<16, }, -(190<<16) }; -static MenuMenuFormat_t MMF_Top_NewGameCustom = { { MENU_MARGIN_CENTER<<16, 48<<16, }, -(190<<16) }; -static MenuMenuFormat_t MMF_Top_NewGameCustomSub = { { MENU_MARGIN_CENTER<<16, 48<<16, }, -(190<<16) }; -static MenuMenuFormat_t MMF_Top_Skill = { { MENU_MARGIN_CENTER<<16, 58<<16, }, -(190<<16) }; static MenuMenuFormat_t MMF_Top_Options = { { MENU_MARGIN_CENTER<<16, 38<<16, }, -(190<<16) }; static MenuMenuFormat_t MMF_Top_Joystick_Network = { { MENU_MARGIN_CENTER<<16, 70<<16, }, -(190<<16) }; static MenuMenuFormat_t MMF_BigOptions = { { MENU_MARGIN_WIDE<<16, 38<<16, }, -(190<<16) }; @@ -172,8 +86,7 @@ static MenuMenuFormat_t MMF_NetSetup = { { 36<<16, static MenuMenuFormat_t MMF_FileSelectLeft = { { 40<<16, 45<<16, }, 162<<16 }; static MenuMenuFormat_t MMF_FileSelectRight = { { 164<<16, 45<<16, }, 162<<16 }; -static MenuEntryFormat_t MEF_Null = { 0, 0, 0 }; -static MenuEntryFormat_t MEF_MainMenu = { 4<<16, 0, 0 }; + static MenuEntryFormat_t MEF_OptionsMenu = { 7<<16, 0, 0 }; static MenuEntryFormat_t MEF_LeftMenu = { 7<<16, 0, 120<<16 }; static MenuEntryFormat_t MEF_CenterMenu = { 7<<16, 0, 0 }; @@ -254,84 +167,6 @@ static MenuEntry_t ME_Space8_Bluefont = MAKE_MENUENTRY( NULL, &MF_Bluefont, &MEF static MenuEntry_t ME_Space6_Redfont = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_Null, &MEO_Space6, Spacer ); static MenuEntry_t ME_Space8_Redfont = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_Null, &MEO_Space8, Spacer ); -#define MAKE_MENU_TOP_ENTRYLINK( Title, Format, EntryName, LinkID ) \ -static MenuLink_t MEO_ ## EntryName = { LinkID, MA_Advance, };\ -static MenuEntry_t ME_ ## EntryName = MAKE_MENUENTRY( Title, &MF_Redfont, &Format, &MEO_ ## EntryName, Link ) - -static char const s_NewGame[] = "New Game"; -static char const s_SaveGame[] = "Save Game"; -static char const s_LoadGame[] = "Load Game"; -static char const s_Continue[] = "Continue"; -static char const s_Options[] = "Options"; -static char const s_Credits[] = "Credits"; - -MAKE_MENU_TOP_ENTRYLINK( s_NewGame, MEF_MainMenu, MAIN_NEWGAME, MENU_EPISODE ); -#ifdef EDUKE32_SIMPLE_MENU -MAKE_MENU_TOP_ENTRYLINK( "Resume Game", MEF_MainMenu, MAIN_RESUMEGAME, MENU_CLOSE ); -#endif -MAKE_MENU_TOP_ENTRYLINK( s_NewGame, MEF_MainMenu, MAIN_NEWGAME_INGAME, MENU_NEWVERIFY ); -static MenuLink_t MEO_MAIN_NEWGAME_NETWORK = { MENU_NETWORK, MA_Advance, }; -MAKE_MENU_TOP_ENTRYLINK( s_SaveGame, MEF_MainMenu, MAIN_SAVEGAME, MENU_SAVE ); -MAKE_MENU_TOP_ENTRYLINK( s_LoadGame, MEF_MainMenu, MAIN_LOADGAME, MENU_LOAD ); -MAKE_MENU_TOP_ENTRYLINK( s_Options, MEF_MainMenu, MAIN_OPTIONS, MENU_OPTIONS ); -#ifdef EDUKE32_STANDALONE -MAKE_MENU_TOP_ENTRYLINK( "Read me!", MEF_MainMenu, MAIN_HELP, MENU_STORY ); -#else -MAKE_MENU_TOP_ENTRYLINK("Help", MEF_MainMenu, MAIN_HELP, MENU_STORY); -#endif -#ifndef EDUKE32_SIMPLE_MENU -MAKE_MENU_TOP_ENTRYLINK( s_Credits, MEF_MainMenu, MAIN_CREDITS, MENU_CREDITS ); -#endif -MAKE_MENU_TOP_ENTRYLINK( "End Game", MEF_MainMenu, MAIN_QUITTOTITLE, MENU_QUITTOTITLE ); -MAKE_MENU_TOP_ENTRYLINK( "Quit", MEF_MainMenu, MAIN_QUIT, MENU_QUIT ); -#ifndef EDUKE32_SIMPLE_MENU -MAKE_MENU_TOP_ENTRYLINK( "Quit Game", MEF_MainMenu, MAIN_QUITGAME, MENU_QUIT ); -#endif - -static MenuEntry_t *MEL_MAIN[] = { - &ME_MAIN_NEWGAME, - &ME_MAIN_LOADGAME, - &ME_MAIN_OPTIONS, - &ME_MAIN_HELP, -#ifndef EDUKE32_SIMPLE_MENU - &ME_MAIN_CREDITS, -#endif - &ME_MAIN_QUIT, -}; - -static MenuEntry_t *MEL_MAIN_INGAME[] = { -#ifdef EDUKE32_SIMPLE_MENU - &ME_MAIN_RESUMEGAME, -#else - &ME_MAIN_NEWGAME_INGAME, -#endif - &ME_MAIN_SAVEGAME, - &ME_MAIN_LOADGAME, - &ME_MAIN_OPTIONS, - &ME_MAIN_HELP, - &ME_MAIN_QUITTOTITLE, -#ifndef EDUKE32_SIMPLE_MENU - &ME_MAIN_QUITGAME, -#endif -}; - -// Episode and Skill will be dynamically generated after CONs are parsed -static MenuLink_t MEO_EPISODE = { MENU_SKILL, MA_Advance, }; -static MenuLink_t MEO_EPISODE_SHAREWARE = { MENU_BUYDUKE, MA_Advance, }; -static MenuEntry_t ME_EPISODE_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_CenterMenu, &MEO_EPISODE, Link ); -static MenuEntry_t ME_EPISODE[MAXVOLUMES]; -static MenuLink_t MEO_EPISODE_USERMAP = { MENU_USERMAP, MA_Advance, }; -static MenuEntry_t ME_EPISODE_USERMAP = MAKE_MENUENTRY( "User Map", &MF_Redfont, &MEF_CenterMenu, &MEO_EPISODE_USERMAP, Link ); -static MenuEntry_t *MEL_EPISODE[MAXVOLUMES+2]; // +2 for spacer and User Map - -static MenuLink_t MEO_NEWGAMECUSTOM_TEMPLATE = { MENU_NEWGAMECUSTOMSUB, MA_Advance, }; -static MenuLink_t MEO_NEWGAMECUSTOM[MAXMENUGAMEPLAYENTRIES]; -static MenuLink_t MEO_NEWGAMECUSTOMSUB_TEMPLATE = { MENU_SKILL, MA_Advance, }; -static MenuLink_t MEO_NEWGAMECUSTOMSUB[MAXMENUGAMEPLAYENTRIES][MAXMENUGAMEPLAYENTRIES]; -MenuEntry_t ME_NEWGAMECUSTOMENTRIES[MAXMENUGAMEPLAYENTRIES]; -MenuEntry_t ME_NEWGAMECUSTOMSUBENTRIES[MAXMENUGAMEPLAYENTRIES][MAXMENUGAMEPLAYENTRIES]; -static MenuEntry_t *MEL_NEWGAMECUSTOM[MAXMENUGAMEPLAYENTRIES]; -static MenuEntry_t *MEL_NEWGAMECUSTOMSUB[MAXMENUGAMEPLAYENTRIES]; static MenuEntry_t ME_SKILL_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_CenterMenu, &MEO_NULL, Link ); static MenuEntry_t ME_SKILL[MAXSKILLS]; @@ -529,36 +364,6 @@ static MenuEntry_t ME_DISPLAYSETUP_VIDEOSETUP = MAKE_MENUENTRY( "Video mode", &M #endif -static MenuLink_t MEO_ENTERCHEAT = { MENU_CHEATENTRY, MA_None, }; -static MenuEntry_t ME_ENTERCHEAT = MAKE_MENUENTRY( "Enter Cheat Code", &MF_Redfont, &MEF_BigCheats, &MEO_ENTERCHEAT, Link ); - -static MenuLink_t MEO_CHEAT_WARP = { MENU_CHEAT_WARP, MA_None, }; -static MenuLink_t MEO_CHEAT_SKILL = { MENU_CHEAT_SKILL, MA_None, }; -// KEEPINSYNC cheats.h: enum CheatCodeFunctions -// KEEPINSYNC cheats.cpp: uint8_t CheatFunctionIDs[] -#define MAKE_MENUCHEAT( Name ) MAKE_MENUENTRY( Name, &MF_Bluefont, &MEF_Cheats, &MEO_NULL, Link ) -static MenuEntry_t ME_CheatCodes[] = { - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_CASHMAN] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_CORNHOLIO] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_STUFF] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_WEAPONS] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_ITEMS] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_INVENTORY] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_KEYS] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_HYPER] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_VIEW] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_SHOWMAP] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_UNLOCK] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_CLIP] ), - MAKE_MENUENTRY( CheatDescriptions[CHEAT_SCOTTY], &MF_Bluefont, &MEF_Cheats, &MEO_CHEAT_WARP, Link ), - MAKE_MENUENTRY( CheatDescriptions[CHEAT_SKILL], &MF_Bluefont, &MEF_Cheats, &MEO_CHEAT_SKILL, Link ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_MONSTERS] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_RATE] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_BETA] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_TODD] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_ALLEN] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_COORDS] ), - MAKE_MENUCHEAT( CheatDescriptions[CHEAT_DEBUG] ), }; static MenuEntry_t *MEL_OPTIONS[] = { @@ -1182,12 +987,6 @@ static MenuEntry_t *MEL_NETJOIN[] = { #define MAKE_MENUMENU(Title, Format, Entries) { Title, Format, Entries, ARRAY_SIZE(Entries), 0, 0, 0 } #define MAKE_MENUMENU_CUSTOMSIZE(Title, Format, Entries) { Title, Format, Entries, 0, 0, 0, 0 } -static MenuMenu_t M_MAIN = MAKE_MENUMENU( NoTitle, &MMF_Top_Main, MEL_MAIN ); -static MenuMenu_t M_MAIN_INGAME = MAKE_MENUMENU( NoTitle, &MMF_Top_Main, MEL_MAIN_INGAME ); -static MenuMenu_t M_EPISODE = MAKE_MENUMENU( "Select An Episode", &MMF_Top_Episode, MEL_EPISODE ); -static MenuMenu_t M_SKILL = MAKE_MENUMENU( "Select Skill", &MMF_Top_Skill, MEL_SKILL ); -static MenuMenu_t M_NEWGAMECUSTOM = MAKE_MENUMENU( s_NewGame, &MMF_Top_NewGameCustom, MEL_NEWGAMECUSTOM ); -static MenuMenu_t M_NEWGAMECUSTOMSUB = MAKE_MENUMENU( s_NewGame, &MMF_Top_NewGameCustomSub, MEL_NEWGAMECUSTOMSUB ); #ifndef EDUKE32_SIMPLE_MENU static MenuMenu_t M_GAMESETUP = MAKE_MENUMENU( "Game Setup", &MMF_BigOptions, MEL_GAMESETUP ); #endif @@ -1197,11 +996,6 @@ static MenuMenu_t M_KEYBOARDSETUP = MAKE_MENUMENU( "Configure Controls", &MMF_To static MenuMenu_t M_CONTROLS = MAKE_MENUMENU( "Control Setup", &MMF_BigOptions, MEL_CONTROLS ); static MenuMenu_t M_CHEATS = MAKE_MENUMENU( "Cheats", &MMF_SmallOptions, MEL_CHEATS ); static MenuMenu_t M_MOUSESETUP = MAKE_MENUMENU( "Mouse Setup", &MMF_BigOptions, MEL_MOUSESETUP ); -#ifdef EDUKE32_ANDROID_MENU -static MenuMenu_t M_TOUCHSETUP = MAKE_MENUMENU( "Touch Setup", &MMF_Top_Options, MEL_TOUCHSETUP ); -static MenuMenu_t M_TOUCHSENS = MAKE_MENUMENU( "Sensitivity", &MMF_BigOptions, MEL_TOUCHSENS); -static MenuPanel_t M_TOUCHBUTTONS = { "Button Setup", MENU_TOUCHSETUP, MA_Return, MENU_TOUCHSETUP, MA_Advance, }; -#endif static MenuMenu_t M_JOYSTICKSETUP = MAKE_MENUMENU( "Gamepad Setup", &MMF_BigOptions, MEL_JOYSTICKSETUP ); static MenuMenu_t M_JOYSTICKAXES = MAKE_MENUMENU( "Gamepad Axes", &MMF_BigSliders, MEL_JOYSTICKAXES ); static MenuMenu_t M_KEYBOARDKEYS = MAKE_MENUMENU( "Key Configuration", &MMF_KeyboardSetupFuncs, MEL_KEYBOARDSETUPFUNCS ); @@ -1209,9 +1003,6 @@ static MenuMenu_t M_MOUSEADVANCED = MAKE_MENUMENU( "Advanced Mouse", &MMF_BigSli static MenuMenu_t M_JOYSTICKAXIS = MAKE_MENUMENU( NULL, &MMF_BigSliders, MEL_JOYSTICKAXIS ); #ifdef USE_OPENGL static MenuMenu_t M_RENDERERSETUP_POLYMOST = MAKE_MENUMENU( "Polymost Setup", &MMF_SmallOptions, MEL_RENDERERSETUP_POLYMOST ); -# ifdef POLYMER -static MenuMenu_t M_RENDERERSETUP_POLYMER = MAKE_MENUMENU("Polymer Setup", &MMF_SmallOptions, MEL_RENDERERSETUP_POLYMER ); -# endif #endif static MenuMenu_t M_COLCORR = MAKE_MENUMENU( "Color Correction", &MMF_ColorCorrect, MEL_COLCORR ); static MenuMenu_t M_SCREENSETUP = MAKE_MENUMENU( "HUD Setup", &MMF_BigOptions, MEL_SCREENSETUP ); @@ -1228,16 +1019,6 @@ static MenuMenu_t M_NETHOST = MAKE_MENUMENU( "Host Network Game", &MMF_SmallOpti static MenuMenu_t M_NETOPTIONS = MAKE_MENUMENU( "Net Game Options", &MMF_NetSetup, MEL_NETOPTIONS ); static MenuMenu_t M_NETJOIN = MAKE_MENUMENU( "Join Network Game", &MMF_SmallOptionsNarrow, MEL_NETJOIN ); -#ifdef EDUKE32_SIMPLE_MENU -static MenuPanel_t M_STORY = { NoTitle, MENU_STORY, MA_Return, MENU_STORY, MA_Advance, }; -#else -static MenuPanel_t M_STORY = { NoTitle, MENU_F1HELP, MA_Return, MENU_F1HELP, MA_Advance, }; -#endif - -static MenuPanel_t M_F1HELP = { NoTitle, MENU_STORY, MA_Return, MENU_STORY, MA_Advance, }; -static MenuPanel_t M_CREDITS = { NoTitle, MENU_CREDITS5, MA_Return, MENU_CREDITS2, MA_Advance, }; -static MenuPanel_t M_CREDITS2 = { NoTitle, MENU_CREDITS, MA_Return, MENU_CREDITS3, MA_Advance, }; -static MenuPanel_t M_CREDITS3 = { NoTitle, MENU_CREDITS2, MA_Return, MENU_CREDITS4, MA_Advance, }; static MenuPanel_t M_CREDITS4 = { "About " APPNAME, MENU_CREDITS3, MA_Return, MENU_CREDITS5, MA_Advance, }; static MenuPanel_t M_CREDITS5 = { "About " APPNAME, MENU_CREDITS4, MA_Return, MENU_CREDITS, MA_Advance, }; @@ -1277,13 +1058,6 @@ static MenuTextForm_t M_CHEAT_SKILL = { NULL, "Enter Skill #:", 1, 0 }; // MUST be in ascending order of MenuID enum values due to binary search static Menu_t Menus[] = { - { &M_MAIN, MENU_MAIN, MENU_CLOSE, MA_None, Menu }, - { &M_MAIN_INGAME, MENU_MAIN_INGAME, MENU_CLOSE, MA_None, Menu }, - { &M_EPISODE, MENU_EPISODE, MENU_MAIN, MA_Return, Menu }, - //{ &M_USERMAP, MENU_USERMAP, MENU_PREVIOUS, MA_Return, FileSelect }, - { &M_NEWGAMECUSTOM, MENU_NEWGAMECUSTOM, MENU_MAIN, MA_Return, Menu }, - { &M_NEWGAMECUSTOMSUB, MENU_NEWGAMECUSTOMSUB, MENU_NEWGAMECUSTOM, MA_Return, Menu }, - { &M_SKILL, MENU_SKILL, MENU_PREVIOUS, MA_Return, Menu }, #ifndef EDUKE32_SIMPLE_MENU { &M_GAMESETUP, MENU_GAMESETUP, MENU_OPTIONS, MA_Return, Menu }, #endif @@ -1358,112 +1132,6 @@ static Menu_t Menus[] = { { &M_NETJOIN, MENU_NETJOIN, MENU_NETWORK, MA_Return, Menu }, }; -static CONSTEXPR const uint16_t numMenus = ARRAY_SIZE(Menus); - -Menu_t *m_currentMenu = &Menus[0]; -static Menu_t *m_previousMenu = &Menus[0]; -static Menu_t * m_parentMenu; - -MenuID_t g_currentMenu; -static MenuID_t g_previousMenu; - -#define MenuMenu_ChangeEntryList(m, el)\ - do {\ - m.entrylist = el;\ - m.numEntries = ARRAY_SIZE(el);\ - } while (0) - -static void MenuEntry_DisableOnCondition(MenuEntry_t * const entry, const int32_t condition) -{ - if (condition) - entry->flags |= MEF_Disabled; - else - entry->flags &= ~MEF_Disabled; -} -static void MenuEntry_LookDisabledOnCondition(MenuEntry_t * const entry, const int32_t condition) -{ - if (condition) - entry->flags |= MEF_LookDisabled; - else - entry->flags &= ~MEF_LookDisabled; -} -static void MenuEntry_HideOnCondition(MenuEntry_t * const entry, const int32_t condition) -{ - if (condition) - entry->flags |= MEF_Hidden; - else - entry->flags &= ~MEF_Hidden; -} - -static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *currentry, int32_t state, vec2_t origin, bool actually_draw = true); -static void Menu_EntryFocus(/*MenuEntry_t *entry*/); - -static MenuEntry_t *Menu_AdjustForCurrentEntryAssignment(MenuMenu_t *menu) -{ - MenuEntry_t *currentry = menu->entrylist[menu->currentEntry]; - - Menu_EntryFocus(/*currentry*/); - - if (currentry->ybottom - menu->scrollPos > klabs(menu->format->bottomcutoff)) - menu->scrollPos = currentry->ybottom - klabs(menu->format->bottomcutoff); - else if (currentry->ytop - menu->scrollPos < menu->format->pos.y) - menu->scrollPos = currentry->ytop - menu->format->pos.y; - - return currentry; -} - -static MenuEntry_t *Menu_AdjustForCurrentEntryAssignmentBlind(MenuMenu_t *menu) -{ - M_RunMenu_Menu(nullptr, menu, nullptr, 0, { 0, 0 }, false); - return Menu_AdjustForCurrentEntryAssignment(menu); -} - -static int32_t SELECTDIR_z = 65536; - -void Menu_PopulateNewGameCustom(void) -{ - M_NEWGAMECUSTOM.title = s_NewGame; - - int e = 0; - for (MenuGameplayStemEntry const & stem : g_MenuGameplayEntries) - { - MenuGameplayEntry const & entry = stem.entry; - if (!entry.isValid()) - break; - - MEL_NEWGAMECUSTOM[e] = &ME_NEWGAMECUSTOMENTRIES[e]; - - ++e; - } - M_NEWGAMECUSTOM.numEntries = e; - MMF_Top_NewGameCustom.pos.y = (58 + (3-e)*6)<<16; -} - -void Menu_PopulateNewGameCustomSub(int e) -{ - if ((unsigned)e >= MAXMENUGAMEPLAYENTRIES) - return; - - MenuGameplayStemEntry const & stem = g_MenuGameplayEntries[e]; - MenuGameplayEntry const & entry = stem.entry; - if (!entry.isValid()) - return; - - M_NEWGAMECUSTOMSUB.title = entry.name; - - int s = 0; - for (MenuGameplayEntry const & subentry : stem.subentries) - { - if (!subentry.isValid()) - break; - - MEL_NEWGAMECUSTOMSUB[s] = &ME_NEWGAMECUSTOMSUBENTRIES[e][s]; - - ++s; - } - M_NEWGAMECUSTOMSUB.numEntries = s; - MMF_Top_NewGameCustomSub.pos.y = (58 + (3-s)*6)<<16; -} /* This function prepares data after ART and CON have been processed. @@ -1479,78 +1147,7 @@ void Menu_Init(void) ME_SKILL_TEMPLATE.format = &MEF_LeftMenu; } - // prepare menu fonts - // check if tilenum is -1 in case it was set in EVENT_SETDEFAULTS - if ((unsigned)MF_Redfont.tilenum >= MAXTILES) MF_Redfont.tilenum = BIGALPHANUM; - if ((unsigned)MF_Bluefont.tilenum >= MAXTILES) MF_Bluefont.tilenum = STARTALPHANUM; - if ((unsigned)MF_Minifont.tilenum >= MAXTILES) MF_Minifont.tilenum = MINIFONT; - MF_Redfont.emptychar.y = tilesiz[MF_Redfont.tilenum].y<<16; - MF_Bluefont.emptychar.y = tilesiz[MF_Bluefont.tilenum].y<<16; - MF_Minifont.emptychar.y = tilesiz[MF_Minifont.tilenum].y<<16; - if (!minitext_lowercase) - MF_Minifont.textflags |= TEXT_UPPERCASE; - // prepare gamefuncs and keys - MEOSN_Gamefuncs[0] = MenuGameFuncNone; - MEOSV_Gamefuncs[0] = -1; - k = 1; - for (i = 0; i < NUMGAMEFUNCTIONS; ++i) - { - MenuGameFuncs[i] = buttonMap.GetButtonAlias(i); - MenuGameFuncs[i].Substitute('_', ' '); - - if (MenuGameFuncs[i][0] != '\0') - { - MEOSN_Gamefuncs[k] = MenuGameFuncs[i]; - MEOSV_Gamefuncs[k] = i; - ++k; - } - } - MEOS_Gamefuncs.numOptions = k; - - for (i = 1; i < NUMKEYS-1; ++i) - MEOSN_Keys[i] = KB_ScanCodeToString(i); - MEOSN_Keys[0] = MenuKeyNone; - MEOSN_Keys[NUMKEYS-1] = MenuKeyNone; - - // prepare levels - MEOS_NETOPTIONS_LEVEL[i] = MEOS_NETOPTIONS_LEVEL_TEMPLATE; - for (j = 0; j < MAXLEVELS; ++j) - { - MEOSN_NetLevels[i][j] = g_mapInfo[MAXLEVELS*i+j].name; - if (g_mapInfo[i*MAXLEVELS+j].filename != NULL) - MEOS_NETOPTIONS_LEVEL[i].numOptions = j+1; - } - MEOS_NETOPTIONS_LEVEL[i].optionNames = MEOSN_NetLevels[i]; - } - M_EPISODE.numEntries = g_volumeCnt+2; - - MEOSN_NetEpisodes[k] = MenuUserMap; - MEOSV_NetEpisodes[k] = MAXVOLUMES; - - MEOS_NETOPTIONS_EPISODE.numOptions = k + 1; - NetEpisode = MEOSV_NetEpisodes[0]; - MMF_Top_Episode.pos.y = (58 + (3-k)*6)<<16; - if (g_skillCnt == 0) - MEO_EPISODE.linkID = MENU_NULL; - M_EPISODE.currentEntry = ud.default_volume; - - ++k; - M_SKILL.numEntries = g_skillCnt; // k; - MEOS_NETOPTIONS_MONSTERS.numOptions = g_skillCnt + 1; // k+1; - MEOSN_NetSkills[g_skillCnt] = MenuSkillNone; - MMF_Top_Skill.pos.y = (58 + (4-g_skillCnt)*6)<<16; - M_SKILL.currentEntry = ud.default_skill; - Menu_AdjustForCurrentEntryAssignmentBlind(&M_SKILL); - - // prepare multiplayer gametypes - k = -1; - for (i = 0; i < MAXGAMETYPES; ++i) - if (g_gametypeNames[i][0]) - { - MEOSN_NetGametypes[i] = g_gametypeNames[i]; - k = i; - } ++k; MEOS_NETOPTIONS_GAMETYPE.numOptions = k; if (NAM_WW2GI) @@ -1560,55 +1157,7 @@ void Menu_Init(void) for (i = 0; i < NUMCHEATFUNCS; ++i) MEL_CHEATS[i+1] = &ME_CheatCodes[i]; - // prepare text chat macros - for (i = 0; i < MAXRIDECULE; ++i) - { - MEL_MACROS[i] = &ME_MACROS[i]; - ME_MACROS[i] = ME_MACROS_TEMPLATE; - ME_MACROS[i].entry = &MEO_MACROS[i]; - MEO_MACROS[i] = MEO_MACROS_TEMPLATE; - - MEO_MACROS[i].variable = sink;// ud.ridecule[i]; temporarily disabled - } - - // prepare input - for (i = 0; i < NUMGAMEFUNCTIONS; ++i) - { - if (MenuGameFuncs[i][0] == '\0') - { - MEL_KEYBOARDSETUPFUNCS[i] = NULL; - continue; - } - - MEL_KEYBOARDSETUPFUNCS[i] = &ME_KEYBOARDSETUPFUNCS[i]; - ME_KEYBOARDSETUPFUNCS[i] = ME_KEYBOARDSETUPFUNCS_TEMPLATE; - ME_KEYBOARDSETUPFUNCS[i].name = MenuGameFuncs[i]; - ME_KEYBOARDSETUPFUNCS[i].entry = &MEO_KEYBOARDSETUPFUNCS[i]; - MEO_KEYBOARDSETUPFUNCS[i] = MEO_KEYBOARDSETUPFUNCS_TEMPLATE; - } - M_KEYBOARDKEYS.numEntries = NUMGAMEFUNCTIONS; - for (i = 0; i < 2*joystick.numButtons + 8*joystick.numHats; ++i) - { - if (i < 2*joystick.numButtons) - { - if (i & 1) - Bsnprintf(MenuJoystickNames[i], MAXJOYBUTTONSTRINGLENGTH, "Double %s", joyGetName(1, i>>1)); - else - Bstrncpy(MenuJoystickNames[i], joyGetName(1, i>>1), MAXJOYBUTTONSTRINGLENGTH); - } - else - { - Bsnprintf(MenuJoystickNames[i], MAXJOYBUTTONSTRINGLENGTH, (i & 1) ? "Double Hat %d %s" : "Hat %d %s", ((i - 2*joystick.numButtons)>>3), MenuJoystickHatDirections[((i - 2*joystick.numButtons)>>1) % 4]); - } - } - for (i = 0; i < joystick.numAxes; ++i) - { - ME_JOYSTICKAXES[i] = ME_JOYSTICKAXES_TEMPLATE; - Bstrncpy(MenuJoystickAxes[i], joyGetName(0, i), MAXJOYBUTTONSTRINGLENGTH); - ME_JOYSTICKAXES[i].name = MenuJoystickAxes[i]; - MEL_JOYSTICKAXES[i] = &ME_JOYSTICKAXES[i]; - } - M_JOYSTICKAXES.numEntries = joystick.numAxes; + // prepare sound setup #ifndef EDUKE32_STANDALONE @@ -1618,25 +1167,6 @@ void Menu_Init(void) ME_SOUND_DUKETALK.name = "Grunt talk:"; #endif - if (FURY) - { - MF_Redfont.between.x = 2<<16; - MF_Redfont.cursorScale = 32768; - MF_Redfont.zoom = 16384; - MF_Bluefont.zoom = 16384; - - // hack; should swap out pointers - MF_Minifont = MF_Bluefont; - - M_OPTIONS.format = &MMF_Top_Main; - - MEF_MainMenu.width = MEF_OptionsMenu.width = -(160<<16); - MEF_MainMenu.marginBottom = 7<<16; - - M_OPTIONS.title = NoTitle; - - SELECTDIR_z = 16384; - } // prepare shareware if (VOLUMEONE) @@ -1668,16 +1198,8 @@ void Menu_Init(void) #endif } -static void Menu_Run(Menu_t *cm, vec2_t origin); -static void Menu_BlackRectangle(int32_t x, int32_t y, int32_t width, int32_t height, int32_t orientation); - -/* -At present, no true difference is planned between Menu_Pre() and Menu_PreDraw(). -They are separate for purposes of organization. -*/ - static void Menu_Pre(MenuID_t cm) { int32_t i; @@ -1685,22 +1207,6 @@ static void Menu_Pre(MenuID_t cm) switch (cm) { - case MENU_MAIN_INGAME: - MenuEntry_DisableOnCondition(&ME_MAIN_SAVEGAME, ud.recstat == 2); - MenuEntry_DisableOnCondition(&ME_MAIN_QUITTOTITLE, g_netServer || numplayers > 1); - fallthrough__; - case MENU_MAIN: - if ((g_netServer || ud.multimode > 1) && ud.recstat != 2) - { - ME_MAIN_NEWGAME.entry = &MEO_MAIN_NEWGAME_NETWORK; - ME_MAIN_NEWGAME_INGAME.entry = &MEO_MAIN_NEWGAME_NETWORK; - } - else - { - ME_MAIN_NEWGAME.entry = &MEO_MAIN_NEWGAME; - ME_MAIN_NEWGAME_INGAME.entry = &MEO_MAIN_NEWGAME_INGAME; - } - break; case MENU_GAMESETUP: MEO_GAMESETUP_DEMOREC.options = (ps->gm&MODE_GAME) ? &MEOS_DemoRec : &MEOS_OffOn; @@ -1848,78 +1354,8 @@ static void Menu_Pre(MenuID_t cm) case MENU_OPTIONS: MenuEntry_DisableOnCondition(&ME_OPTIONS_PLAYERSETUP, ud.recstat == 1); break; - - case MENU_COLCORR: - case MENU_COLCORR_INGAME: - break; - - case MENU_CHEATS: - case MENU_CHEATENTRY: - case MENU_CHEAT_WARP: - case MENU_CHEAT_SKILL: - { - const int32_t menucheatsdisabled = numplayers != 1 || !(g_player[myconnectindex].ps->gm & MODE_GAME); - - // refresh display names of quote cheats - if (!DUKEBETA) - { - ME_CheatCodes[CHEATFUNC_QUOTEBETA].name = apStrings[QUOTE_CHEAT_BETA]; - if (!NAM) - ME_CheatCodes[CHEATFUNC_QUOTETODD].name = apStrings[QUOTE_CHEAT_TODD]; - ME_CheatCodes[CHEATFUNC_QUOTEALLEN].name = apStrings[QUOTE_CHEAT_ALLEN]; - } - - for (i = 0; i < NUMCHEATFUNCS; i++) - { - uint32_t cheatmask = cl_cheatmask & (1<>11),0,2+8); - } - break; case MENU_PLAYER: rotatesprite_fs(origin.x + (260<<16), origin.y + ((24+(tilesiz[APLAYER].y>>1))<<16), 49152L,0,1441-((((4-((int32_t) totalclock>>4)))&3)*5),0,entry == &ME_PLAYER_TEAM ? G_GetTeamPalette(playerteam) : playercolor,10); @@ -2013,129 +1438,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) Menu_DrawVerifyPrompt(origin.x, origin.y, tempbuf, 2); break; - case MENU_LOAD: - { -#if 0 - for (i = 0; i <= 108; i += 12) - rotatesprite_fs(origin.x + ((160+64+91-64)<<16), origin.y + ((i+56)<<16), 65536L,0,TEXTBOX,24,0,10); -#endif - Menu_BlackRectangle(origin.x + (198<<16), origin.y + (47<<16), 102<<16, 100<<16, 1|32); - - rotatesprite_fs(origin.x + (22<<16), origin.y + (97<<16), 65536L,0,WINDOWBORDER2,24,0,10); - rotatesprite_fs(origin.x + (180<<16), origin.y + (97<<16), 65536L,1024,WINDOWBORDER2,24,0,10); - rotatesprite_fs(origin.x + (99<<16), origin.y + (50<<16), 65536L,512,WINDOWBORDER1,24,0,10); - rotatesprite_fs(origin.x + (103<<16), origin.y + (144<<16), 65536L,1024+512,WINDOWBORDER1,24,0,10); - - if (M_LOAD.currentEntry >= (int32_t)g_nummenusaves) - { - menutext_centeralign(origin.x + (101<<16), origin.y + (97<<16), "Empty"); - break; - } - - menusave_t & msv = g_menusaves[M_LOAD.currentEntry]; - - if (msv.brief.isValid()) - { - if (tilePtr(TILE_LOADSHOT)) - rotatesprite_fs(origin.x + (101<<16), origin.y + (97<<16), 65536>>1,512,TILE_LOADSHOT, msv.isOldVer?16:-32, 0,4+10+64); - - if (msv.isOldVer) - { - mgametextcenterat(origin.x + (101<<16), origin.y + (50<<16), - msv.brief.isExt ? "Previous Version,\nSequence Point Available" : "Previous Version,\nUnable to Load"); - -#ifndef EDUKE32_SIMPLE_MENU - Bsprintf(tempbuf,"Saved: %d.%d.%d.%u %d-bit", savehead.majorver, savehead.minorver, - savehead.bytever, savehead.userbytever, 8*savehead.getPtrSize()); - mgametext(origin.x + (25<<16), origin.y + (124<<16), tempbuf); - Bsprintf(tempbuf,"Our: %d.%d.%d.%u %d-bit", SV_MAJOR_VER, SV_MINOR_VER, BYTEVERSION, - ud.userbytever, (int32_t)(8*sizeof(intptr_t))); - mgametext(origin.x + ((25+16)<<16), origin.y + (134<<16), tempbuf); -#endif - - if (msv.isUnreadable) - break; - } - - if (savehead.numplayers > 1) - { - Bsprintf(tempbuf, "Players: %-2d ", savehead.numplayers); - mgametextcenter(origin.x, origin.y + (156<<16), tempbuf); - } - - { - const char *name = g_mapInfo[(savehead.volnum*MAXLEVELS) + savehead.levnum].name; - Bsprintf(tempbuf, "%s / %s", name ? name : "^10unnamed^0", g_skillNames[savehead.skill-1]); - } - - mgametextcenter(origin.x, origin.y + (168<<16), tempbuf); - if (savehead.volnum == 0 && savehead.levnum == 7) - mgametextcenter(origin.x, origin.y + (180<<16), savehead.boardfn); - } - break; - } - - case MENU_SAVE: - { -#if 0 - for (i = 0; i <= 108; i += 12) - rotatesprite_fs(origin.x + ((160+64+91-64)<<16), origin.y + ((i+56)<<16), 65536L,0,TEXTBOX,24,0,10); -#endif - Menu_BlackRectangle(origin.x + (198<<16), origin.y + (47<<16), 102<<16, 100<<16, 1|32); - - rotatesprite_fs(origin.x + (22<<16), origin.y + (97<<16), 65536L,0,WINDOWBORDER2,24,0,10); - rotatesprite_fs(origin.x + (180<<16), origin.y + (97<<16), 65536L,1024,WINDOWBORDER2,24,0,10); - rotatesprite_fs(origin.x + (99<<16), origin.y + (50<<16), 65536L,512,WINDOWBORDER1,24,0,10); - rotatesprite_fs(origin.x + (103<<16), origin.y + (144<<16), 65536L,1024+512,WINDOWBORDER1,24,0,10); - - j = 0; - for (int k = 0; k < g_nummenusaves+1; ++k) - if (((MenuString_t*)M_SAVE.entrylist[k]->entry)->editfield) - j |= 1; - - if (j) - rotatesprite_fs(origin.x + (101<<16), origin.y + (97<<16), 65536L>>1,512,TILE_SAVESHOT,-32,0,4+10+64); - else if (0 < M_SAVE.currentEntry && M_SAVE.currentEntry <= (int32_t)g_nummenusaves) - { - menusave_t & msv = g_menusaves[M_SAVE.currentEntry-1]; - - if (msv.brief.isValid()) - { - if (tilePtr(TILE_LOADSHOT)) - rotatesprite_fs(origin.x + (101<<16), origin.y + (97<<16), 65536>>1,512,TILE_LOADSHOT, msv.isOldVer?16:-32, 0,4+10+64); - - if (msv.isOldVer) - { - mgametextcenterat(origin.x + (101<<16), origin.y + (50<<16), - msv.brief.isExt ? "Previous Version,\nSequence Point Available" : "Previous Version,\nUnable to Load"); - -#ifndef EDUKE32_SIMPLE_MENU - Bsprintf(tempbuf,"Saved: %d.%d.%d.%u %d-bit", savehead.majorver, savehead.minorver, - savehead.bytever, savehead.userbytever, 8*savehead.getPtrSize()); - mgametext(origin.x + (25<<16), origin.y + (124<<16), tempbuf); - Bsprintf(tempbuf,"Our: %d.%d.%d.%u %d-bit", SV_MAJOR_VER, SV_MINOR_VER, BYTEVERSION, - ud.userbytever, (int32_t)(8*sizeof(intptr_t))); - mgametext(origin.x + ((25+16)<<16), origin.y + (134<<16), tempbuf); -#endif - } - } - } - else - menutext_centeralign(origin.x + (101<<16), origin.y + (97<<16), "New"); - - if (ud.multimode > 1) - { - Bsprintf(tempbuf, "Players: %-2d ", ud.multimode); - mgametextcenter(origin.x, origin.y + (156<<16), tempbuf); - } - - Bsprintf(tempbuf,"%s / %s",g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name, g_skillNames[ud.player_skill-1]); - mgametextcenter(origin.x, origin.y + (168<<16), tempbuf); - if (ud.volume_number == 0 && ud.level_number == 7) - mgametextcenter(origin.x, origin.y + (180<<16), currentboardfilename); - break; - } - case MENU_SAVECLEANVERIFY: videoFadeToBlack(1); @@ -2364,193 +1666,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) } -static void Menu_PreInput(MenuEntry_t *entry) -{ - switch (g_currentMenu) - { - - case MENU_KEYBOARDKEYS: - if (inputState.GetKeyStatus(sc_Delete)) - { - Bindings.UnbindACommand(buttonMap.GetButtonName(M_KEYBOARDKEYS.currentEntry)); - S_PlaySound(KICK_HIT); - inputState.ClearKeyStatus(sc_Delete); - } - break; - - case MENU_LOAD: - if (inputState.GetKeyStatus(sc_Delete)) - { - inputState.ClearKeyStatus(sc_Delete); - if (M_LOAD.currentEntry < g_nummenusaves) - Menu_Change(MENU_LOADDELVERIFY); - } - break; - case MENU_SAVE: - if (inputState.GetKeyStatus(sc_Delete)) - { - inputState.ClearKeyStatus(sc_Delete); - if (0 < M_SAVE.currentEntry && M_SAVE.currentEntry <= (int32_t)g_nummenusaves) - Menu_Change(MENU_SAVEDELVERIFY); - } - break; - - default: - break; - } -} - -static void Menu_PreOptionListDraw(MenuEntry_t *entry, const vec2_t origin) -{ - switch (g_currentMenu) - { - case MENU_MOUSEBTNS: - case MENU_MOUSEADVANCED: - case MENU_JOYSTICKBTNS: - case MENU_JOYSTICKAXIS: - mgametextcenter(origin.x, origin.y + (31<<16), "Select a function to assign"); - - Bsprintf(tempbuf, "to %s", entry->name); - - mgametextcenter(origin.x, origin.y + ((31+9)<<16), tempbuf); - - mgametextcenter(origin.x, origin.y + (161<<16), "Press \"Escape\" To Cancel"); - break; - } -} - -static int32_t Menu_PreCustom2ColScreen(MenuEntry_t *entry) -{ - if (g_currentMenu == MENU_KEYBOARDKEYS) - { - auto column = (MenuCustom2Col_t*)entry->entry; - - int32_t sc = inputState.GetLastScanCode(); - if (sc != sc_None) - { - S_PlaySound(PISTOL_BODYHIT); - Bindings.SetBind(sc, buttonMap.GetButtonName(M_KEYBOARDKEYS.currentEntry)); - inputState.ClearKeyStatus(sc); - - return -1; - } - } - - return 0; -} - -static void Menu_PreCustom2ColScreenDraw(MenuEntry_t *entry, const vec2_t origin) -{ - if (g_currentMenu == MENU_KEYBOARDKEYS) - { - Bsprintf(tempbuf, "Press the key to assign as\n" - "%s for \"%s\"\n" - "\n" - "Press \"Escape\" To Cancel" - , M_KEYBOARDKEYS.currentColumn?"secondary":"primary", entry->name); - mgametextcenter(origin.x, origin.y + (90<<16), tempbuf); - } -} - -static void Menu_EntryFocus(/*MenuEntry_t *entry*/) -{ - switch (g_currentMenu) - { - case MENU_LOAD: - if (M_LOAD.currentEntry < (int32_t)g_nummenusaves) - { - savebrief_t & sv = g_menusaves[M_LOAD.currentEntry].brief; - if (sv.isValid()) - G_LoadSaveHeaderNew(sv.path, &savehead); - } - break; - - case MENU_SAVE: - if (0 < M_SAVE.currentEntry && M_SAVE.currentEntry <= (int32_t)g_nummenusaves) - { - savebrief_t & sv = g_menusaves[M_SAVE.currentEntry-1].brief; - if (sv.isValid()) - G_LoadSaveHeaderNew(sv.path, &savehead); - } - break; - - default: - break; - } -} - -static void Menu_StartGameWithoutSkill(void) -{ - ud.m_player_skill = M_SKILL.currentEntry+1; - - ud.skill_voice = S_PlaySound(PISTOL_BODYHIT); - - ud.m_respawn_monsters = 0; - - ud.m_monsters_off = ud.monsters_off = 0; - - ud.m_respawn_items = 0; - ud.m_respawn_inventory = 0; - - ud.multimode = 1; - - G_NewGame_EnterLevel(); -} - -static void Menu_DoCheat(int32_t cheatID) -{ - if (numplayers != 1 || !(g_player[myconnectindex].ps->gm & MODE_GAME)) - return; - - osdcmd_cheatsinfo_stat.cheatnum = cheatID; -} - -static int32_t Menu_Cheat_Warp(char const * const numbers) -{ - if (numplayers != 1 || !(g_player[myconnectindex].ps->gm & MODE_GAME)) - return 0; - - if (numbers == NULL || !numbers[0] || !numbers[1] || (VOLUMEALL && !numbers[2])) - return 1; - - if (VOLUMEALL) - { - osdcmd_cheatsinfo_stat.volume = numbers[0] - '0'; - osdcmd_cheatsinfo_stat.level = (numbers[1] - '0')*10+(numbers[2]-'0'); - } - else - { - osdcmd_cheatsinfo_stat.volume = numbers[0] - '0'; - osdcmd_cheatsinfo_stat.level = numbers[1] - '0'; - } - - osdcmd_cheatsinfo_stat.volume--; - osdcmd_cheatsinfo_stat.level--; - - if ((VOLUMEONE && osdcmd_cheatsinfo_stat.volume > 0) || osdcmd_cheatsinfo_stat.volume > g_volumeCnt-1 || - osdcmd_cheatsinfo_stat.level >= MAXLEVELS || g_mapInfo[osdcmd_cheatsinfo_stat.volume *MAXLEVELS+osdcmd_cheatsinfo_stat.level].filename == NULL) - return 1; - - osdcmd_cheatsinfo_stat.cheatnum = CHEAT_SCOTTY; - - return 0; -} - -static int32_t Menu_Cheat_Skill(char const * const number) -{ - if (numplayers != 1 || !(g_player[myconnectindex].ps->gm & MODE_GAME)) - return 0; - - if (number == NULL || !number[0]) - return 1; - - osdcmd_cheatsinfo_stat.volume = number[0] - '1'; - - osdcmd_cheatsinfo_stat.cheatnum = CHEAT_SKILL; - - return 0; -} - /* Functions where a "newValue" or similar is passed are run *before* the linked variable is actually changed. That way you can compare the new and old values and potentially block the change. @@ -2767,187 +1882,10 @@ static int32_t Menu_EntryOptionModify(MenuEntry_t *entry, int32_t newOption) } } - switch (g_currentMenu) - { - case MENU_MOUSEBTNS: - break; - case MENU_JOYSTICKBTNS: - break; - case MENU_JOYSTICKAXIS: - { - for (int i = 0; i < ARRAY_SSIZE(MEL_INTERNAL_JOYSTICKAXIS_DIGITAL); i++) - if (entry == MEL_INTERNAL_JOYSTICKAXIS_DIGITAL[i]) - CONTROL_MapDigitalAxis(M_JOYSTICKAXES.currentEntry, newOption, i&1, controldevice_joystick); - } - break; - } return 0; } -static void Menu_EntryOptionDidModify(MenuEntry_t *entry) -{ -#ifdef USE_OPENGL - int domodechange = 0; -#endif - - if (entry == &ME_GAMESETUP_AIM_AUTO || - entry == &ME_GAMESETUP_WEAPSWITCH_PICKUP || - //entry == &ME_PLAYER_NAME || - entry == &ME_PLAYER_COLOR || - entry == &ME_PLAYER_TEAM) - G_UpdatePlayerFromMenu(); -#ifdef USE_OPENGL - if (domodechange) - { - videoResetMode(); - if (videoSetGameMode(fullscreen, xres, yres, bpp, upscalefactor)) - OSD_Printf("restartvid: Reset failed...\n"); - onvideomodechange(ScreenBPP>8); - G_RefreshLights(); - } -#endif -} - -static void Menu_Custom2ColScreen(/*MenuEntry_t *entry*/) -{ - if (g_currentMenu == MENU_KEYBOARDKEYS) - { - inputState.keyFlushChars(); - inputState.ClearLastScanCode(); - } -} - -static int32_t Menu_EntryRangeInt32Modify(MenuEntry_t *entry, int32_t newValue) -{ - if (entry == &ME_SCREENSETUP_SBARSIZE) - G_SetStatusBarScale(newValue); - else if (entry == &ME_SOUND_VOLUME_FX) - FX_SetVolume(newValue); - else if (entry == &ME_SOUND_VOLUME_MUSIC) - S_MusicVolume(newValue); - else if (entry == &ME_JOYSTICKAXIS_SCALE) - CONTROL_SetAnalogAxisScale(M_JOYSTICKAXES.currentEntry, newValue, controldevice_joystick); - else if (entry == &ME_JOYSTICKAXIS_DEAD) - joySetDeadZone(M_JOYSTICKAXES.currentEntry, newValue, *MEO_JOYSTICKAXIS_SATU.cVar); - else if (entry == &ME_JOYSTICKAXIS_SATU) - joySetDeadZone(M_JOYSTICKAXES.currentEntry, *MEO_JOYSTICKAXIS_DEAD.cVar, newValue); - - return 0; -} - -static int32_t Menu_EntryRangeFloatModify(MenuEntry_t *entry, float newValue) -{ -#ifndef EDUKE32_SIMPLE_MENU - if (entry == &ME_COLCORR_AMBIENT) - r_ambientlightrecip = 1.f/newValue; -#else - UNREFERENCED_PARAMETER(entry); - UNREFERENCED_PARAMETER(newValue); -#endif - - return 0; -} - -static int32_t Menu_EntryRangeFloatDidModify(MenuEntry_t *entry) -{ - return 0; -} - -#ifdef MENU_ENABLE_RANGEDOUBLE -static int32_t Menu_EntryRangeDoubleModify(void /*MenuEntry_t *entry, double newValue*/) -{ - - return 0; -} -#endif - -static uint32_t save_xxh = 0; - -static void Menu_EntryStringActivate(/*MenuEntry_t *entry*/) -{ - switch (g_currentMenu) - { - case MENU_SAVE: - if (M_SAVE.currentEntry > 0) - { - savebrief_t & sv = g_menusaves[M_SAVE.currentEntry-1].brief; - if (!save_xxh) - save_xxh = SuperFastHash(sv.name, MAXSAVEGAMENAME); - if (sv.isValid()) - Menu_Change(MENU_SAVEVERIFY); - } - else - { - ME_SAVE_NEW.name = nullptr; - save_xxh = 0; - } - break; - - default: - break; - } -} - -static int32_t Menu_EntryStringSubmit(/*MenuEntry_t *entry, */char *input) -{ - int32_t returnvar = 0; - - switch (g_currentMenu) - { - case MENU_SAVE: - { - savebrief_t & sv = g_lastusersave = M_SAVE.currentEntry == 0 ? savebrief_t{input} : g_menusaves[M_SAVE.currentEntry-1].brief; - - // dirty hack... char 127 in last position indicates an auto-filled name -#ifdef __ANDROID__ - if (1) -#else - if (input[0] == 0 || (sv.name[MAXSAVEGAMENAME] == 127 && - strncmp(sv.name, input, MAXSAVEGAMENAME) == 0 && - save_xxh == SuperFastHash(sv.name, MAXSAVEGAMENAME))) -#endif - { - strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME); - sv.name[MAXSAVEGAMENAME] = 127; - returnvar = -1; - } - else - { - strncpy(sv.name, input, MAXSAVEGAMENAME); - sv.name[MAXSAVEGAMENAME] = 0; - } - - G_SavePlayerMaybeMulti(sv); - - g_quickload = &sv; - g_player[myconnectindex].ps->gm = MODE_GAME; - - Menu_Change(MENU_CLOSE); - save_xxh = 0; - break; - } - - default: - break; - } - - return returnvar; -} - -static void Menu_EntryStringCancel(/*MenuEntry_t *entry*/) -{ - switch (g_currentMenu) - { - case MENU_SAVE: - save_xxh = 0; - ME_SAVE_NEW.name = s_NewSaveGame; - break; - - default: - break; - } -} /* This is polled when the menu code is populating the screen but for some reason doesn't have the data. @@ -2964,533 +1902,6 @@ static int32_t Menu_EntryOptionSource(MenuEntry_t *entry, int32_t currentValue) return currentValue; } -static void Menu_Verify(int32_t input) -{ - switch (g_currentMenu) - { - case MENU_SAVECLEANVERIFY: - if (input) - { - G_DeleteOldSaves(); - } - break; - - case MENU_RESETPLAYER: - switch (input) - { - default: - inputState.keyFlushChars(); - inputState.ClearKeysDown(); - FX_StopAllSounds(); - - if (G_LoadPlayerMaybeMulti(*g_quickload) == 0) - break; - - // error state, consider as a no instead of yes - g_quickload->reset(); - - fallthrough__; - case 0: - if (sprite[g_player[myconnectindex].ps->i].extra <= 0) - { - if (G_EnterLevel(MODE_GAME)) G_BackToMenu(); - return; - } - - Menu_Change(MENU_CLOSE); - break; - } - break; - - case MENU_LOADVERIFY: - if (input) - { - menusave_t & msv = g_menusaves[M_LOAD.currentEntry]; - savebrief_t & sv = msv.brief; - - if (strcmp(sv.path, g_lastusersave.path) != 0) - { - g_freshload = sv; - g_lastusersave.reset(); - g_lastautosave.reset(); - g_quickload = &g_freshload; - } - else - { - g_quickload = &g_lastusersave; - } - - inputState.keyFlushChars(); - inputState.ClearKeysDown(); - - if (G_LoadPlayerMaybeMulti(sv)) - Menu_Change(MENU_PREVIOUS); - else - Menu_Change(MENU_CLOSE); - } - break; - - case MENU_SAVEVERIFY: - if (!input) - { - save_xxh = 0; - - ((MenuString_t*)M_SAVE.entrylist[M_SAVE.currentEntry]->entry)->editfield = NULL; - } - break; - - case MENU_LOADDELVERIFY: - if (input) - { - Menu_LoadReadHeaders(); - M_LOAD.currentEntry = clamp(M_LOAD.currentEntry, 0, (int32_t)g_nummenusaves-1); - } - break; - case MENU_SAVEDELVERIFY: - if (input) - { - Menu_SaveReadHeaders(); - M_SAVE.currentEntry = clamp(M_SAVE.currentEntry, 0, (int32_t)g_nummenusaves); - } - break; - - case MENU_COLCORRRESETVERIFY: - if (input) - { - vid_gamma = 1.f; - vid_contrast = 1.f; - vid_brightness = 0.f; - r_ambientlight = 1.f; - videoSetPalette(0,g_player[myconnectindex].ps->palette,0); - } - break; - - case MENU_KEYSRESETVERIFY: - if (input) - CONFIG_SetDefaultKeys("demolition/defbinds.txt"); - break; - case MENU_KEYSCLASSICVERIFY: - if (input) - CONFIG_SetDefaultKeys("demolition/origbinds.txt"); - break; - case MENU_JOYSTANDARDVERIFY: - if (input) - CONFIG_SetGameControllerDefaultsStandard(); - break; - case MENU_JOYPROVERIFY: - if (input) - CONFIG_SetGameControllerDefaultsPro(); - break; - case MENU_JOYCLEARVERIFY: - if (input) - CONFIG_SetGameControllerDefaultsClear(); - break; - - case MENU_QUIT: - case MENU_QUIT_INGAME: - if (input) - G_GameQuit(); - else - g_quitDeadline = 0; - break; - - case MENU_QUITTOTITLE: - if (input) - { - g_player[myconnectindex].ps->gm = MODE_DEMO; - if (ud.recstat == 1) - G_CloseDemoWrite(); - artClearMapArt(); - } - break; - - case MENU_NETWAITVOTES: - if (!input) - Net_SendMapVoteCancel(0); - break; - - default: - break; - } -} - -static int Menu_CheatStringMatch(char const * input, char const * cheat) -{ - while (*cheat || *input) - { - if (*cheat != *input) - { - if (!(*cheat == '#' && Bisdigit(*input))) - return 0; - } - - ++cheat; - ++input; - } - - return 1; -} - -static void Menu_TextFormSubmit(char *input) -{ - switch (g_currentMenu) - { - case MENU_ADULTPASSWORD: - break; - - case MENU_CHEATENTRY: - { - const size_t inputlength = Bstrlen(input); - Bstrcpy(tempbuf, input); - for (size_t i = 0; i < inputlength; i++) - tempbuf[i] = Btolower(tempbuf[i]); - - int8_t cheatID = -1; - - if (inputlength > 2 && tempbuf[0] == g_keyAsciiTable[CheatKeys[0]] && tempbuf[1] == g_keyAsciiTable[CheatKeys[1]]) - { - for (int i = 0; i < NUMCHEATS; i++) - if (Menu_CheatStringMatch(tempbuf+2, CheatStrings[i])) - { - cheatID = i; - break; - } - } - - switch (cheatID) - { - case -1: - S_PlaySound(KICK_HIT); - break; - case CHEAT_SCOTTY: - { - char const * const numberpos = Bstrchr(CheatStrings[CHEAT_SCOTTY], '#'); - if (numberpos == NULL) - { - S_PlaySound(KICK_HIT); - break; - } - - Menu_Cheat_Warp(input + (numberpos - CheatStrings[CHEAT_SCOTTY]) + 2); - if (g_player[myconnectindex].ps->gm&MODE_MENU) - S_PlaySound(DUKE_GET); - break; - } - case CHEAT_SKILL: - { - char const * const numberpos = Bstrchr(CheatStrings[CHEAT_SKILL], '#'); - if (numberpos == NULL) - { - S_PlaySound(KICK_HIT); - break; - } - - Menu_Cheat_Skill(input + (numberpos - CheatStrings[CHEAT_SKILL]) + 2); - if (g_player[myconnectindex].ps->gm&MODE_MENU) - S_PlaySound(DUKE_GET); - break; - } - default: - Menu_DoCheat(cheatID); - S_PlaySound(DUKE_GET); - break; - } - - if (cheatID >= 0) - cl_cheatmask = cl_cheatmask | CheatFunctionFlags[cheatID]; - - if ((NAM_WW2GI && (cl_cheatmask & (1<menuID) - { - case MENU_NEWGAMECUSTOMSUB: - Menu_PopulateNewGameCustomSub(M_NEWGAMECUSTOM.currentEntry); - break; - - case MENU_LOAD: - if (FURY) - M_LOAD.title = (g_player[myconnectindex].ps->gm & MODE_GAME) ? s_LoadGame : s_Continue; - - Menu_LoadReadHeaders(); - - if (g_quickload && g_quickload->isValid()) - { - for (int i = 0; i < g_nummenusaves; ++i) - { - if (strcmp(g_menusaves[i].brief.path, g_quickload->path) == 0) - { - M_LOAD.currentEntry = i; - Menu_AdjustForCurrentEntryAssignmentBlind(&M_LOAD); - break; - } - } - } - break; - - case MENU_SAVE: - if (g_previousMenu == MENU_SAVEVERIFY || g_previousMenu == MENU_SAVEDELVERIFY) - break; - - Menu_SaveReadHeaders(); - - if (g_lastusersave.isValid()) - { - for (int i = 0; i < g_nummenusaves; ++i) - { - if (strcmp(g_menusaves[i].brief.path, g_lastusersave.path) == 0) - { - M_SAVE.currentEntry = i+1; - Menu_AdjustForCurrentEntryAssignmentBlind(&M_SAVE); - break; - } - } - } - - if (g_player[myconnectindex].ps->gm&MODE_GAME) - { - g_screenCapture = 1; - G_DrawRooms(myconnectindex,65536); - g_screenCapture = 0; - } - break; - - case MENU_VIDEOSETUP: - newresolution = 0; - for (int i = 0; i < MAXVALIDMODES; ++i) - { - if (resolution[i].xdim == xres && resolution[i].ydim == yres) - { - newresolution = i; - break; - } - } - newrendermode = videoGetRenderMode(); - newfullscreen = fullscreen; - newvsync = vid_vsync; - newborderless = r_borderless; - break; - - case MENU_ADVSOUND: - soundrate = snd_mixrate; - soundvoices = snd_numvoices; - musicdevice = MusicDevice; - break; - - default: - break; - } - - switch (m->type) - { - case TextForm: - typebuf[0] = 0; - ((MenuTextForm_t*)m->object)->input = typebuf; - break; - case FileSelect: - Menu_FileSelectInit((MenuFileSelect_t*)m->object); - break; - case Menu: - { - auto menu = (MenuMenu_t*)m->object; - // MenuEntry_t* currentry = menu->entrylist[menu->currentEntry]; - - // need this for MENU_SKILL - if (menu->currentEntry >= menu->numEntries) - menu->currentEntry = 0; - - int32_t i = menu->currentEntry; - while (!menu->entrylist[menu->currentEntry] || - (((MenuEntry_t*)menu->entrylist[menu->currentEntry])->flags & MEF_Hidden) || - ((MenuEntry_t*)menu->entrylist[menu->currentEntry])->type == Spacer) - { - menu->currentEntry++; - if (menu->currentEntry >= menu->numEntries) - menu->currentEntry = 0; - if (menu->currentEntry == i) - G_GameExit("Menu_Change: Attempted to show a menu with no entries."); - } - - Menu_EntryFocus(/*currentry*/); - break; - } - default: - break; - } -} - -static void Menu_ChangingTo(Menu_t * m) -{ - - - switch (m->type) - { - case TextForm: - Menu_StartTextInput(); - break; - default: - break; - } -} - - - - - - -int G_CheckPlayerColor(int color) -{ - for (int i : MEOSV_PLAYER_COLOR) - if (i == color) - return color; - - return -1; -} - - -int32_t Menu_DetermineSpecialState(MenuEntry_t *entry) -{ - if (entry == NULL) - return 0; - - if (entry->type == String) - { - if (((MenuString_t*)entry->entry)->editfield) - return 1; - } - else if (entry->type == Option) - { - if (((MenuOption_t*)entry->entry)->options->currentEntry >= 0) - return 2; - } - else if (entry->type == Custom2Col) - { - if (((MenuCustom2Col_t*)entry->entry)->screenOpen) - return 2; - } - - return 0; -} - -int32_t Menu_IsTextInput(Menu_t *cm) -{ - switch (m_currentMenu->type) - { - case Verify: - case TextForm: - case FileSelect: - case Message: - return 1; - break; - case Panel: - return 0; - break; - case Menu: - { - auto menu = (MenuMenu_t *)cm->object; - auto entry = menu->entrylist[menu->currentEntry]; - return Menu_DetermineSpecialState(entry); - } - break; - } - - return 0; -} - -static inline int32_t Menu_BlackTranslucentBackgroundOK(MenuID_t cm) -{ - switch (cm) - { - case MENU_COLCORR: - case MENU_COLCORR_INGAME: - return 0; - break; - default: - return 1; - break; - } - - return 1; -} - -static inline int32_t Menu_UpdateScreenOK(MenuID_t cm) -{ - switch (cm) - { - case MENU_LOAD: - case MENU_SAVE: - case MENU_LOADVERIFY: - case MENU_LOADDELVERIFY: - case MENU_SAVEVERIFY: - case MENU_SAVEDELVERIFY: - return 0; - break; - default: - return 1; - break; - } - - return 1; -} - - -/* - Code below this point is entirely general, - so if you want to change or add a menu, - chances are you should scroll up. -*/ - -int32_t m_mouselastactivity; -#if !defined EDUKE32_TOUCH_DEVICES -int32_t m_mousewake_watchpoint, m_menuchange_watchpoint; -#endif -int32_t m_mousecaught; -static vec2_t m_prevmousepos, m_mousepos, m_mousedownpos; - -void Menu_Open(uint8_t playerID) -{ - g_player[playerID].ps->gm |= MODE_MENU; - - inputState.mouseReadAbs(&m_prevmousepos); - m_mouselastactivity = -M_MOUSETIMEOUT; - -#if !defined EDUKE32_TOUCH_DEVICES - m_mousewake_watchpoint = 0; -#endif - - mouseLockToWindow(0); -} - void Menu_Close(uint8_t playerID) { auto & gm = g_player[playerID].ps->gm; @@ -3523,1917 +1934,6 @@ void Menu_Close(uint8_t playerID) } } -static int32_t x_widescreen_left(void) -{ - return (320<<15) - scale(240<<15, xdim, ydim); -} - -static int32_t xdim_from_320_16(int32_t x) -{ - const int32_t screenwidth = scale(240<<16, xdim, ydim); - return scale(x + (screenwidth>>1) - (160<<16), xdim, screenwidth); -} -static int32_t ydim_from_200_16(int32_t y) -{ - y = mulscale16(y + rotatesprite_y_offset - (200<<15), rotatesprite_yxaspect) + (200<<15); - return scale(y, ydim, 200<<16); -} - -static void Menu_BlackRectangle(int32_t x, int32_t y, int32_t width, int32_t height, int32_t orientation) -{ - const int32_t xscale = divscale16(width, tilesiz[0].x<<16), yscale = divscale16(height, tilesiz[0].y<<16); - - rotatesprite_(x, y, max(xscale, yscale), 0, 0, 127, ud.shadow_pal, (orientation&(1|32))|2|8|16, 0, 0, xdim_from_320_16(x), ydim_from_200_16(y), xdim_from_320_16(x + width), ydim_from_200_16(y + height)); -} - -enum MenuTextFlags_t -{ - MT_Selected = 1<<0, - MT_Disabled = 1<<1, - MT_XCenter = 1<<2, - MT_XRight = 1<<3, - MT_YCenter = 1<<4, - MT_Literal = 1<<5, - MT_RightSide = 1<<6, -}; - -static int32_t Menu_FindOptionBinarySearch(MenuOption_t *object, const int32_t query, uint16_t searchstart, uint16_t searchend) -{ - const uint16_t thissearch = (searchstart + searchend) / 2; - const bool isIdentityMap = object->options->optionValues == NULL; - const int32_t destination = isIdentityMap ? (int32_t)thissearch : object->options->optionValues[thissearch]; - const int32_t difference = query - destination; - - Bassert(!isIdentityMap || query >= 0); - - if (difference == 0) - return thissearch; - else if (searchstart == searchend) - return -1; - else if (difference > 0) - { - if (thissearch == searchend) - return -1; - searchstart = thissearch + 1; - } - else if (difference < 0) - { - if (thissearch == searchstart) - return -1; - searchend = thissearch - 1; - } - - return Menu_FindOptionBinarySearch(object, query, searchstart, searchend); -} - -static int32_t Menu_MouseOutsideBounds(vec2_t const * const pos, const int32_t x, const int32_t y, const int32_t width, const int32_t height) -{ - return pos->x < x || pos->x >= x + width || pos->y < y || pos->y >= y + height; -} - -static void Menu_RunScrollbar(Menu_t *cm, MenuMenuFormat_t const * const format, const int32_t totalextent, int32_t * const scrollPos, const int32_t rightedge, const vec2_t origin) -{ - if (totalextent > klabs(format->bottomcutoff)) - { - int32_t scrollTile = (ud.menu_scrollbartilenum >= 0) ? ud.menu_scrollbartilenum : -1; - int32_t scrollTileTop = (ud.menu_scrollbartilenum >= 0) ? ud.menu_scrollbartilenum + 1 : -1; - int32_t scrollTileBottom = (ud.menu_scrollbartilenum >= 0) ? ud.menu_scrollbartilenum + 2 : -1; - int32_t scrollTileCursor = (ud.menu_scrollbartilenum >= 0) ? ud.menu_scrollbartilenum + 3 : SELECTDIR; - - const int32_t scrollwidth = (scrollTile >= 0) ? tilesiz[scrollTile].x*ud.menu_scrollbarz : tilesiz[scrollTileCursor].x*ud.menu_scrollcursorz; - const int32_t scrollx = origin.x + rightedge - scrollwidth, scrolly = origin.y + format->pos.y; - const int32_t scrollheight = klabs(format->bottomcutoff) - format->pos.y; - int32_t scrollregionstart = scrolly; - int32_t scrollregionend = scrolly + scrollheight; - if (ud.menu_scrollbartilenum >= 0) - { - scrollregionstart += tilesiz[scrollTileTop].y*ud.menu_scrollbarz; - scrollregionend -= tilesiz[scrollTileBottom].y*ud.menu_scrollbarz; - } - const int32_t scrollregionheight = scrollregionend - scrollregionstart - (tilesiz[scrollTileCursor].y*ud.menu_scrollcursorz); - const int32_t scrollPosMax = totalextent - klabs(format->bottomcutoff); - - if (scrollTile >= 0) - { - // draw the scrollbar (minus the top tile) twice to fill the gaps between tiles - if (tilesiz[scrollTile].y > 0) - { - for (int32_t y = scrollregionstart + ((tilesiz[scrollTileTop].y == 0)*tilesiz[scrollTile].y*ud.menu_scrollbarz); y < scrollregionend; y += tilesiz[scrollTile].y*ud.menu_scrollbarz) - rotatesprite(scrollx, y - (ud.menu_scrollbarz>>1), ud.menu_scrollbarz, 0, scrollTile, 0, 0, 26, 0, 0, xdim-1, mulscale16(scrollregionend, ydim*200)-1); - } - rotatesprite_fs(scrollx, scrollregionend - (ud.menu_scrollbarz>>1), ud.menu_scrollbarz, 0, scrollTileBottom, 0, 0, 26); - - if (tilesiz[scrollTile].y > 0) - { - for (int32_t y = scrollregionstart; y < scrollregionend; y += tilesiz[scrollTile].y*ud.menu_scrollbarz) - rotatesprite(scrollx, y, ud.menu_scrollbarz, 0, scrollTile, 0, 0, 26, 0, 0, xdim-1, mulscale16(scrollregionend, ydim*200)-1); - } - rotatesprite_fs(scrollx, scrolly, ud.menu_scrollbarz, 0, scrollTileTop, 0, 0, 26); - rotatesprite_fs(scrollx, scrollregionend, ud.menu_scrollbarz, 0, scrollTileBottom, 0, 0, 26); - } - else - Menu_BlackRectangle(scrollx, scrolly, scrollwidth, scrollheight, 1|32); - - rotatesprite_fs(scrollx + ((scrollwidth>>17)<<16) - ((tilesiz[scrollTileCursor].x>>1)*ud.menu_scrollcursorz), scrollregionstart + scale(scrollregionheight, *scrollPos, scrollPosMax), ud.menu_scrollcursorz, 0, scrollTileCursor, 0, 0, 26); - - if (cm == m_currentMenu && !m_mousecaught && MOUSEACTIVECONDITIONAL(inputState.mouseClickState() == MOUSE_PRESSED || inputState.mouseClickState() == MOUSE_HELD)) - { - const int32_t scrolltilehalfheight = (tilesiz[scrollTileCursor].y>>1)*ud.menu_scrollcursorz; - const int32_t scrollregiony = scrollregionstart + scrolltilehalfheight; - - // region between the y-midline of the arrow at the extremes scrolls proportionally - if (!Menu_MouseOutsideBounds(&m_mousepos, scrollx, scrollregiony, scrollwidth, scrollregionheight)) - { - *scrollPos = scale(m_mousepos.y - scrollregiony, scrollPosMax, scrollregionheight); - - m_mousecaught = 1; - } - // region outside the y-midlines clamps to the extremes - else if (!Menu_MouseOutsideBounds(&m_mousepos, scrollx, scrolly, scrollwidth, scrollheight)) - { - if (m_mousepos.y > scrolly + ((scrollheight>>17)<<16)) - *scrollPos = scrollPosMax; - else - *scrollPos = 0; - - m_mousecaught = 1; - } - } - } -} - -typedef enum MenuMovement_t -{ - MM_Up = 1, - MM_End = 3, - MM_Down = 4, - MM_Home = 12, - MM_Left = 16, - MM_AllTheWayLeft = 48, - MM_Right = 64, - MM_AllTheWayRight = 192, - MM_Swap = 80, -} MenuMovement_t; - -static MenuEntry_t *Menu_RunInput_Menu_MovementVerify(MenuMenu_t *menu); -static MenuEntry_t *Menu_RunInput_Menu_Movement(MenuMenu_t *menu, MenuMovement_t direction); -static void Menu_RunInput_EntryLink_Activate(MenuEntry_t *entry); -static void Menu_RunInput_EntryOptionList_MovementVerify(MenuOption_t *object); -static void Menu_RunInput_EntryOptionList_Movement(MenuOption_t *object, MenuMovement_t direction); -static int32_t Menu_RunInput_EntryOption_Modify(MenuEntry_t *entry, MenuOption_t *object, int32_t newValueIndex); -static int32_t Menu_RunInput_EntryOption_Movement(MenuEntry_t *entry, MenuOption_t *object, MenuMovement_t direction); -static int32_t Menu_RunInput_EntryOption_Activate(MenuEntry_t *entry, MenuOption_t *object); -static int32_t Menu_RunInput_EntryOptionList_Activate(MenuEntry_t *entry, MenuOption_t *object); -static void Menu_RunInput_EntryCustom2Col_Activate(MenuEntry_t *entry); -static void Menu_RunInput_EntryRangeInt32_MovementVerify(MenuEntry_t *entry, MenuRangeInt32_t *object, int32_t newValue); -static void Menu_RunInput_EntryRangeInt32_MovementArbitrary(MenuEntry_t *entry, MenuRangeInt32_t *object, int32_t newValue); -static void Menu_RunInput_EntryRangeInt32_Movement(MenuEntry_t *entry, MenuRangeInt32_t *object, MenuMovement_t direction); -static void Menu_RunInput_EntryRangeFloat_MovementVerify(MenuEntry_t *entry, MenuRangeFloat_t *object, float newValue); -static void Menu_RunInput_EntryRangeFloat_MovementArbitrary(MenuEntry_t *entry, MenuRangeFloat_t *object, float newValue); -static void Menu_RunInput_EntryRangeFloat_Movement(MenuEntry_t *entry, MenuRangeFloat_t *object, MenuMovement_t direction); -#ifdef MENU_ENABLE_RANGEDOUBLE -static void Menu_RunInput_EntryRangeDouble_MovementVerify(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, double newValue); -static void Menu_RunInput_EntryRangeDouble_MovementArbitrary(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, double newValue); -static void Menu_RunInput_EntryRangeDouble_Movement(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, MenuMovement_t direction); -#endif -static void Menu_RunInput_EntryString_Activate(MenuEntry_t *entry); -static void Menu_RunInput_EntryString_Submit(/*MenuEntry_t *entry, */MenuString_t *object); -static void Menu_RunInput_EntryString_Cancel(/*MenuEntry_t *entry, */MenuString_t *object); -static void Menu_RunInput_FileSelect_MovementVerify(MenuFileSelect_t *object); -static void Menu_RunInput_FileSelect_Movement(MenuFileSelect_t *object, MenuMovement_t direction); -static void Menu_RunInput_FileSelect_Select(MenuFileSelect_t *object); - -static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *currentry, int32_t state, const vec2_t origin, bool actually_draw) -{ - int32_t totalHeight = 0; - - // RIP MenuGroup_t b. 2014-03-?? d. 2014-11-29 - { - int32_t e; - const int32_t y_upper = menu->format->pos.y; - const int32_t y_lower = klabs(menu->format->bottomcutoff); - int32_t y = 0; - int32_t calculatedentryspacing = 0; - - if (menu->format->bottomcutoff < 0) - { - int32_t totalheight = 0, numvalidentries = 0; - - for (e = 0; e < menu->numEntries; ++e) - { - MenuEntry_t *entry = menu->entrylist[e]; - - if (entry == NULL || (entry->flags & MEF_Hidden)) - continue; - - ++numvalidentries; - - // assumes height == font->get_yline()! - totalheight += entry->getHeight(); - } - - calculatedentryspacing = (klabs(menu->format->bottomcutoff) - menu->format->pos.y - totalheight) / (numvalidentries > 1 ? numvalidentries - 1 : 1); - } - - // totalHeight calculating pass - for (e = 0; e < menu->numEntries; ++e) - { - MenuEntry_t *entry = menu->entrylist[e]; - - if (entry == NULL || (entry->flags & MEF_Hidden)) - continue; - - int32_t const height = entry->getHeight(); - - y += height; - totalHeight = y; - y += (!calculatedentryspacing || calculatedentryspacing > entry->getMarginBottom()) ? entry->getMarginBottom() : calculatedentryspacing; - } - y = 0; - - int32_t ydim_upper, ydim_lower; - if (y_upper + totalHeight > y_lower) - { - ydim_upper = ydim_from_200_16(origin.y + y_upper); - ydim_lower = ydim_from_200_16(origin.y + y_lower); - } - else - { - ydim_upper = 0; - ydim_lower = ydim-1; - } - - for (e = 0; e < menu->numEntries; ++e) - { - MenuEntry_t *entry = menu->entrylist[e]; - - if (entry == NULL || (entry->flags & MEF_Hidden)) - continue; - - int32_t const indent = entry->getIndent(); - int32_t x = menu->format->pos.x; - - uint8_t status = 0; - if (e == menu->currentEntry) - status |= MT_Selected; - if (entry->flags & (MEF_Disabled|MEF_LookDisabled)) - status |= MT_Disabled; - if (entry->format->width == 0) - status |= MT_XCenter; - - bool const dodraw = entry->type != Spacer && actually_draw && - 0 <= y - menu->scrollPos + entry->font->get_yline() && - y - menu->scrollPos <= klabs(menu->format->bottomcutoff) - menu->format->pos.y; - - int32_t const height = entry->getHeight(); // max(textsize.y, entry->font->get_yline()); // bluefont Q ruins this - status |= MT_YCenter; - int32_t const y_internal = origin.y + y_upper + y + ((height>>17)<<16) - menu->scrollPos; - - vec2_t textsize; - if (dodraw) - textsize = Menu_Text(origin.x + x + indent, y_internal, entry->font, entry->name, status, ydim_upper, ydim_lower); - - if (entry->format->width < 0) - status |= MT_XRight; - - if (dodraw && (status & MT_Selected) && state != 1) - { - if (status & MT_XCenter) - { - Menu_DrawCursorLeft(origin.x + (MENU_MARGIN_CENTER<<16) + entry->font->cursorCenterPosition, y_internal, entry->font->cursorScale); - Menu_DrawCursorRight(origin.x + (MENU_MARGIN_CENTER<<16) - entry->font->cursorCenterPosition, y_internal, entry->font->cursorScale); - } - else - Menu_DrawCursorLeft(origin.x + x + indent - entry->font->cursorLeftPosition, y_internal, entry->font->cursorScale); - } - - if (entry->name != nullptr && entry->name[0] != '\0') - status |= MT_RightSide; - - // need this up here to avoid race conditions - entry->ybottom = (entry->ytop = y_upper + y) + height; - - if (dodraw) - { - const int32_t mousex = origin.x + indent + entry->format->width == 0 ? x - ((textsize.x>>17)<<16) : x; - const int32_t mousey = origin.y + y_upper + y - menu->scrollPos; - int32_t mousewidth = entry->format->width == 0 ? textsize.x : klabs(entry->format->width); - - if (entry->name) - x += klabs(entry->format->width); - - switch (entry->type) - { - case Spacer: - break; - case Dummy: - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - } - break; - case Link: - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, mousex, mousey, mousewidth, entry->font->get_yline())) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - - if (entry->flags & MEF_Disabled) - break; - - Menu_RunInput_EntryLink_Activate(entry); - - if (g_player[myconnectindex].ps->gm&MODE_MENU) // for skill selection - S_PlaySound(PISTOL_BODYHIT); - - m_mousecaught = 1; - } - } - break; - case Option: - { - auto object = (MenuOption_t*)entry->entry; - int32_t currentOption = Menu_FindOptionBinarySearch(object, object->cVar == NULL ? Menu_EntryOptionSource(entry, object->currentOption) : object->cVar->ToInt(), 0, object->options->numOptions); - - if (currentOption >= 0) - object->currentOption = currentOption; - - int32_t optiontextx = origin.x + x; - const int32_t optiontexty = origin.y + y_upper + y - menu->scrollPos; - - const vec2_t optiontextsize = Menu_Text(optiontextx, optiontexty + ((height>>17)<<16), object->font, - currentOption < 0 ? MenuCustom : currentOption < object->options->numOptions ? object->options->optionNames[currentOption] : NULL, - status, ydim_upper, ydim_lower); - - if (entry->format->width > 0) - mousewidth += optiontextsize.x; - else - optiontextx -= optiontextsize.x; - - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, mousex, mousey, mousewidth, entry->font->get_yline())) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - - if (entry->flags & MEF_Disabled) - break; - - Menu_RunInput_EntryOption_Activate(entry, object); - - S_PlaySound(PISTOL_BODYHIT); - - m_mousecaught = 1; - } - } - - break; - } - case Custom2Col: - { - auto object = (MenuCustom2Col_t*)entry->entry; - int32_t columnx[2] = { origin.x + x - ((status & MT_XRight) ? object->columnWidth : 0), origin.x + x + ((status & MT_XRight) ? 0 : object->columnWidth) }; - const int32_t columny = origin.y + y_upper + y - menu->scrollPos; - - // Beware of hack job! - auto keys = Bindings.GetKeysForCommand(buttonMap.GetButtonName(object->buttonindex)); - FString text1; - FString text2; - if (keys.Size() > 0) text1 = C_NameKeys(&keys[0], 1); - if (keys.Size() > 1) text2 = C_NameKeys(&keys[1], 1); - const vec2_t column0textsize = Menu_Text(columnx[0], columny + ((height >> 17) << 16), object->font, text1, menu->currentColumn == 0 ? status : (status & ~MT_Selected), ydim_upper, ydim_lower); - const vec2_t column1textsize = Menu_Text(columnx[1], columny + ((height>>17)<<16), object->font, text2, menu->currentColumn == 1 ? status : (status & ~MT_Selected), ydim_upper, ydim_lower); - - if (entry->format->width > 0) - mousewidth += object->columnWidth + column1textsize.x; - else - { - columnx[0] -= column0textsize.x; - columnx[1] -= column0textsize.x; - } - - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - if (!Menu_MouseOutsideBounds(&m_mousepos, columnx[1], mousey, column1textsize.x, object->font->get_yline())) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, columnx[1], mousey, column1textsize.x, object->font->get_yline()))) - { - menu->currentColumn = 1; - } - - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, columnx[1], mousey, column1textsize.x, object->font->get_yline())) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - menu->currentColumn = 1; - - if (entry->flags & MEF_Disabled) - break; - - Menu_RunInput_EntryCustom2Col_Activate(entry); - - S_PlaySound(PISTOL_BODYHIT); - - m_mousecaught = 1; - } - } - else if (!Menu_MouseOutsideBounds(&m_mousepos, columnx[0], mousey, column0textsize.x, object->font->get_yline())) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, columnx[0], mousey, column0textsize.x, object->font->get_yline()))) - { - menu->currentColumn = 0; - } - - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, columnx[0], mousey, column0textsize.x, object->font->get_yline())) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - menu->currentColumn = 0; - - if (entry->flags & MEF_Disabled) - break; - - Menu_RunInput_EntryCustom2Col_Activate(entry); - - S_PlaySound(PISTOL_BODYHIT); - - m_mousecaught = 1; - } - } - } - break; - } - case RangeInt32: - { - auto object = (MenuRangeInt32_t*)entry->entry; - - int32_t s, p; - int32_t z = entry->font->cursorScale; - Menu_GetFmt(object->font, status|MT_RightSide, &s, &z); - - if (status & MT_Disabled) - p = ud.slidebar_paldisabled; - else if (status & MT_Selected) - p = ud.slidebar_palselected; - else - p = 0; - - const int32_t slidebarwidth = mulscale16(tilesiz[SLIDEBAR].x * ud.menu_slidebarz, z); - const int32_t slidebarheight = mulscale16(tilesiz[SLIDEBAR].y * ud.menu_slidebarz, z); - - if (status & MT_XRight) - x -= slidebarwidth; - else - mousewidth += slidebarwidth; - - const int32_t slidebarx = origin.x + x; - const int32_t slidebary = origin.y + y_upper + y + (((height - slidebarheight)>>17)<<16) - menu->scrollPos; - - rotatesprite_ybounds(slidebarx, slidebary, mulscale16(ud.menu_slidebarz, z), 0, SLIDEBAR, s, p, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); - - const int32_t slideregionwidth = mulscale16((tilesiz[SLIDEBAR].x * ud.menu_slidebarz) - (ud.menu_slidebarmargin<<1) - (tilesiz[SLIDEBAR+1].x * ud.menu_slidecursorz), z); - const int32_t slidepointx = slidebarx + mulscale16(ud.menu_slidebarmargin, z) + scale(slideregionwidth, *object->cVar - object->min, object->max - object->min); - const int32_t slidepointy = slidebary + mulscale16((((tilesiz[SLIDEBAR].y>>1) * ud.menu_slidebarz) - ((tilesiz[SLIDEBAR+1].y>>1) * ud.menu_slidecursorz)), z); - - rotatesprite_ybounds(slidepointx, slidepointy, mulscale16(ud.menu_slidecursorz, z), 0, SLIDEBAR+1, s, p, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); - - if (object->flags & DisplayTypeMask) - { - status |= MT_XRight; - - int32_t onehundredpercent = object->onehundredpercent; - if (onehundredpercent == 0) - onehundredpercent = object->max; - - switch (object->flags & DisplayTypeMask) - { - case DisplayTypeInteger: - Bsprintf(tempbuf, "%d", **object->cVar); - break; - case DisplayTypePercent: - Bsprintf(tempbuf, "%d%%", roundscale(*object->cVar, 100, onehundredpercent)); - break; - case DisplayTypeNormalizedDecimal: - Bsprintf(tempbuf, "%.2f", (double) *object->cVar / (double) onehundredpercent); - break; - } - - Menu_Text(origin.x + x - (4<<16), origin.y + y_upper + y + ((height>>17)<<16) - menu->scrollPos, object->font, tempbuf, status, ydim_upper, ydim_lower); - } - - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - if (!m_mousecaught && (inputState.mouseClickState() == MOUSE_PRESSED || inputState.mouseClickState() == MOUSE_HELD)) - { - const int32_t slidepointhalfwidth = mulscale16((((tilesiz[SLIDEBAR+1].x)*ud.menu_slidecursorz)>>2) + ud.menu_slidebarmargin, z); - const int32_t slideregionx = slidebarx + slidepointhalfwidth; - - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - - if (entry->flags & MEF_Disabled) - break; - - // region between the x-midline of the slidepoint at the extremes slides proportionally - if (!Menu_MouseOutsideBounds(&m_mousepos, slideregionx, mousey, slideregionwidth, height)) - { - Menu_RunInput_EntryRangeInt32_MovementArbitrary(entry, object, roundscale(object->max - object->min, m_mousepos.x - slideregionx, slideregionwidth) + object->min); - - m_mousecaught = 1; - } - // region outside the x-midlines clamps to the extremes - else if (!Menu_MouseOutsideBounds(&m_mousepos, slidebarx, mousey, slidebarwidth, height)) - { - if (m_mousepos.x > slideregionx + ((slideregionwidth>>17)<<16)) - Menu_RunInput_EntryRangeInt32_MovementVerify(entry, object, object->max); - else - Menu_RunInput_EntryRangeInt32_MovementVerify(entry, object, object->min); - - m_mousecaught = 1; - } - } - } - - break; - } - case RangeFloat: - { - auto object = (MenuRangeFloat_t*)entry->entry; - - int32_t s, p; - int32_t z = entry->font->cursorScale; - Menu_GetFmt(object->font, status|MT_RightSide, &s, &z); - - if (status & MT_Disabled) - p = ud.slidebar_paldisabled; - else if (status & MT_Selected) - p = ud.slidebar_palselected; - else - p = 0; - - const int32_t slidebarwidth = mulscale16(tilesiz[SLIDEBAR].x * ud.menu_slidebarz, z); - const int32_t slidebarheight = mulscale16(tilesiz[SLIDEBAR].y * ud.menu_slidebarz, z); - - if (status & MT_XRight) - x -= slidebarwidth; - else - mousewidth += slidebarwidth; - - const int32_t slidebarx = origin.x + x; - const int32_t slidebary = origin.y + y_upper + y + (((height - slidebarheight)>>17)<<16) - menu->scrollPos; - - rotatesprite_ybounds(slidebarx, slidebary, mulscale16(ud.menu_slidebarz, z), 0, SLIDEBAR, s, p, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); - - const int32_t slideregionwidth = mulscale16((tilesiz[SLIDEBAR].x * ud.menu_slidebarz) - (ud.menu_slidebarmargin<<1) - (tilesiz[SLIDEBAR+1].x * ud.menu_slidecursorz), z); - const int32_t slidepointx = slidebarx + mulscale16(ud.menu_slidebarmargin, z) + Blrintf((float) slideregionwidth * (*object->cVar - object->min) / (object->max - object->min)); - const int32_t slidepointy = slidebary + mulscale16(((tilesiz[SLIDEBAR].y>>1) * ud.menu_slidebarz) - ((tilesiz[SLIDEBAR+1].y>>1) * ud.menu_slidecursorz), z); - - rotatesprite_ybounds(slidepointx, slidepointy, mulscale16(ud.menu_slidecursorz, z), 0, SLIDEBAR+1, s, p, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); - - if (object->flags & DisplayTypeMask) - { - status |= MT_XRight; - - float onehundredpercent = object->onehundredpercent; - if (onehundredpercent == 0.f) - onehundredpercent = 1.f; - - switch (object->flags & DisplayTypeMask) - { - case DisplayTypeInteger: - Bsprintf(tempbuf, "%.2f", **object->cVar); - break; - case DisplayTypePercent: - Bsprintf(tempbuf, "%ld%%", lrintf(*object->cVar * 100.f / onehundredpercent)); - break; - case DisplayTypeNormalizedDecimal: - Bsprintf(tempbuf, "%.2f", *object->cVar / onehundredpercent); - break; - } - - Menu_Text(origin.x + x - (4<<16), origin.y + y_upper + y + ((height>>17)<<16) - menu->scrollPos, object->font, tempbuf, status, ydim_upper, ydim_lower); - } - - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - if (!m_mousecaught && (inputState.mouseClickState() == MOUSE_PRESSED || inputState.mouseClickState() == MOUSE_HELD)) - { - const int32_t slidepointhalfwidth = mulscale16((2+tilesiz[SLIDEBAR+1].x)<<15, z); - const int32_t slideregionx = slidebarx + slidepointhalfwidth; - - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - - if (entry->flags & MEF_Disabled) - break; - - // region between the x-midline of the slidepoint at the extremes slides proportionally - if (!Menu_MouseOutsideBounds(&m_mousepos, slideregionx, mousey, slideregionwidth, height)) - { - Menu_RunInput_EntryRangeFloat_MovementArbitrary(entry, object, (object->max - object->min) * (m_mousepos.x - slideregionx) / slideregionwidth + object->min); - - m_mousecaught = 1; - } - // region outside the x-midlines clamps to the extremes - else if (!Menu_MouseOutsideBounds(&m_mousepos, slidebarx, mousey, slidebarwidth, height)) - { - if (m_mousepos.x > slideregionx + (slideregionwidth>>17<<16)) - Menu_RunInput_EntryRangeFloat_MovementVerify(entry, object, object->max); - else - Menu_RunInput_EntryRangeFloat_MovementVerify(entry, object, object->min); - - m_mousecaught = 1; - } - } - } - - break; - } - - case String: - { - auto object = (MenuString_t*)entry->entry; - - vec2_t dim; - int32_t stringx = x; - const int32_t stringy = origin.y + y_upper + y + ((height>>17)<<16) - menu->scrollPos; - int32_t h; - - if (entry == currentry && object->editfield != NULL) - { - dim = Menu_Text(origin.x + stringx, stringy, object->font, object->editfield, (status & ~MT_Disabled) | MT_Literal, ydim_upper, ydim_lower); - h = max(dim.y, entry->font->get_yline()); - - Menu_DrawCursorText(origin.x + x + dim.x + (1<<16), stringy, h, ydim_upper, ydim_lower); - } - else - { - dim = Menu_Text(origin.x + stringx, stringy, object->font, object->variable, status, ydim_upper, ydim_lower); - h = max(dim.y, entry->font->get_yline()); - } - - if (entry->format->width > 0) - { - if (entry->name) - mousewidth += dim.x; - } - else - stringx -= dim.x; - - if (MOUSEACTIVECONDITIONAL(cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, h))) - { - if (state != 1 && Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, h)) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - #ifndef EDUKE32_TOUCH_DEVICES - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, h) && !Menu_MouseOutsideBounds(&m_mousedownpos, mousex, mousey, mousewidth, h)) - #endif - { - if (entry == currentry && object->editfield != NULL) - { - Menu_RunInput_EntryString_Submit(/*entry, */object); - - S_PlaySound(PISTOL_BODYHIT); - - m_mousecaught = 1; - } - else if (state != 1) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - - if (entry->flags & MEF_Disabled) - break; - - Menu_RunInput_EntryString_Activate(entry); - - S_PlaySound(PISTOL_BODYHIT); - - m_mousecaught = 1; - } - } - } - - break; - } - } - } - - // prepare for the next line - y += height; - y += (!calculatedentryspacing || calculatedentryspacing > entry->getMarginBottom()) ? entry->getMarginBottom() : calculatedentryspacing; - } - - // draw indicators if applicable - if (actually_draw) - Menu_RunScrollbar(cm, menu->format, y_upper + totalHeight, &menu->scrollPos, 320<<16, origin); - } - - return totalHeight; -} - -static void Menu_RunOptionList(Menu_t *cm, MenuEntry_t *entry, MenuOption_t *object, const vec2_t origin) -{ - int32_t e, y = 0; - const int32_t y_upper = object->options->menuFormat->pos.y; - const int32_t y_lower = object->options->menuFormat->bottomcutoff; - int32_t calculatedentryspacing = object->options->getMarginBottom(); - - // assumes height == font->get_yline()! - if (calculatedentryspacing < 0) - calculatedentryspacing = (-calculatedentryspacing - object->options->font->get_yline()) / (object->options->numOptions - 1) - object->options->font->get_yline(); - - int32_t totalHeight = 0; - for (e = 0; e < object->options->numOptions; ++e) - { - int32_t const height = object->options->font->get_yline(); - - y += height; - totalHeight = y; - y += calculatedentryspacing; - } - y = 0; - - int32_t ydim_upper, ydim_lower; - if (y_upper + totalHeight > y_lower) - { - ydim_upper = ydim_from_200_16(origin.y + y_upper); - ydim_lower = ydim_from_200_16(origin.y + y_lower); - } - else - { - ydim_upper = 0; - ydim_lower = ydim-1; - } - - for (e = 0; e < object->options->numOptions; ++e) - { - int32_t const x = object->options->menuFormat->pos.x; - - uint8_t status = 0; - if (e == object->options->currentEntry) - status |= MT_Selected; - if (object->options->entryFormat->width == 0) - status |= MT_XCenter; - - bool const dodraw = 0 <= y - object->options->scrollPos + object->options->font->get_yline() && - y - object->options->scrollPos <= object->options->menuFormat->bottomcutoff - object->options->menuFormat->pos.y; - - int32_t const height = object->options->font->get_yline(); // max(textsize.y, object->options->font->get_yline()); - status |= MT_YCenter; - int32_t const y_internal = origin.y + y_upper + y + ((height>>17)<<16) - object->options->scrollPos; - - vec2_t textsize; - if (dodraw) - textsize = Menu_Text(origin.x + x, y_internal, object->options->font, object->options->optionNames[e], status, ydim_upper, ydim_lower); - - if (object->options->entryFormat->width < 0) - status |= MT_XRight; - - if (dodraw && (status & MT_Selected)) - { - if (status & MT_XCenter) - { - Menu_DrawCursorLeft(origin.x + (MENU_MARGIN_CENTER<<16) + object->options->font->cursorCenterPosition, y_internal, object->options->font->cursorScale); - Menu_DrawCursorRight(origin.x + (MENU_MARGIN_CENTER<<16) - object->options->font->cursorCenterPosition, y_internal, object->options->font->cursorScale); - } - else - Menu_DrawCursorLeft(origin.x + x - object->options->font->cursorLeftPosition, y_internal, object->options->font->cursorScale); - } - - if (dodraw) - { - const int32_t mousex = origin.x + object->options->entryFormat->width == 0 ? x - ((textsize.x>>17)<<16) : x; - const int32_t mousey = origin.y + y_upper + y - object->options->scrollPos; - const int32_t mousewidth = object->options->entryFormat->width == 0 ? textsize.x : klabs(object->options->entryFormat->width); - - if (MOUSEACTIVECONDITIONAL(cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, object->options->font->get_yline()))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, object->options->font->get_yline()))) - { - object->options->currentEntry = e; - } - - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, mousex, mousey, mousewidth, object->options->font->get_yline())) - { - object->options->currentEntry = e; - - if (!Menu_RunInput_EntryOptionList_Activate(entry, object)) - S_PlaySound(PISTOL_BODYHIT); - - m_mousecaught = 1; - } - } - } - - // prepare for the next line - y += height; - y += calculatedentryspacing; - } - - // draw indicators if applicable - Menu_RunScrollbar(cm, object->options->menuFormat, y_upper + totalHeight, &object->options->scrollPos, 320<<16, origin); -} - -static int32_t Menu_RunInput_MouseAdvance(void) -{ - return MOUSEACTIVECONDITIONAL(!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED); -} - -static int32_t Menu_RunInput_MouseReturn_status; - -#if !defined EDUKE32_TOUCH_DEVICES -static void Menu_Run_MouseReturn(Menu_t *cm, const vec2_t origin) -{ - if (!MOUSEACTIVECONDITION) - return; - - if (cm->menuID == MENU_MAIN) - return; - - uint32_t const posx = tilesiz[SELECTDIR].y * SELECTDIR_z; - - rotatesprite_(origin.x + posx, 0, SELECTDIR_z, 512, SELECTDIR, - Menu_RunInput_MouseReturn_status ? 4 - (sintable[((int32_t) totalclock << 4) & 2047] >> 11) : 6, 0, - 2 | 8 | 16 | RS_ALIGN_L, MOUSEALPHA, 0, xdim_from_320_16(origin.x + x_widescreen_left()), 0, - xdim_from_320_16(origin.x + x_widescreen_left() + ((posx>>17)<<16)), ydim - 1); -} -#endif - -static int32_t Menu_RunInput_MouseReturn(void) -{ -#if !defined EDUKE32_TOUCH_DEVICES - if (!MOUSEACTIVECONDITION) - { - Menu_RunInput_MouseReturn_status = 0; - return 0; - } -#endif - - if (g_currentMenu == MENU_MAIN) - return 0; - - const int32_t MouseReturnRegionX = x_widescreen_left(); - - vec2_t backbuttonbound = { ((tilesiz[SELECTDIR].y * SELECTDIR_z)>>17)<<16, tilesiz[SELECTDIR].x * SELECTDIR_z }; - - if (!Menu_MouseOutsideBounds(&m_mousepos, MouseReturnRegionX, 0, backbuttonbound.x, backbuttonbound.y)) - { -#if !defined EDUKE32_TOUCH_DEVICES - Menu_RunInput_MouseReturn_status = 1; -#else - Menu_RunInput_MouseReturn_status = (inputState.mouseClickState() == MOUSE_PRESSED || inputState.mouseClickState() == MOUSE_HELD); -#endif - - return !m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, MouseReturnRegionX, 0, backbuttonbound.x, backbuttonbound.y); - } - - Menu_RunInput_MouseReturn_status = 0; - - return 0; -} - -static void Menu_Run_AbbreviateNameIntoBuffer(const char* name, int32_t entrylength) -{ - int32_t len = Bstrlen(name); - Bstrncpy(tempbuf, name, ARRAY_SIZE(tempbuf)); - if (len > entrylength) - { - len = entrylength-3; - tempbuf[len] = 0; - while (len < entrylength) - tempbuf[len++] = '.'; - } - tempbuf[len] = 0; -} - -static void Menu_Recurse(MenuID_t cm, const vec2_t origin) -{ - switch (cm) - { - case MENU_SAVECLEANVERIFY: - case MENU_LOADVERIFY: - case MENU_LOADDELVERIFY: - case MENU_SAVEVERIFY: - case MENU_SAVEDELVERIFY: - case MENU_COLCORRRESETVERIFY: - case MENU_KEYSRESETVERIFY: - case MENU_KEYSCLASSICVERIFY: - case MENU_JOYSTANDARDVERIFY: - case MENU_JOYPROVERIFY: - case MENU_JOYCLEARVERIFY: - case MENU_ADULTPASSWORD: - case MENU_CHEATENTRY: - case MENU_CHEAT_WARP: - case MENU_CHEAT_SKILL: - Menu_Run(m_previousMenu, origin); - break; - default: - break; - } -} - -static void Menu_Run(Menu_t *cm, const vec2_t origin) -{ - Menu_Recurse(cm->menuID, origin); - - switch (cm->type) - { - case Verify: - { - auto object = (MenuVerify_t*)cm->object; - - Menu_Pre(cm->menuID); - - Menu_PreDrawBackground(cm->menuID, origin); - - Menu_PreDraw(cm->menuID, NULL, origin); - - Menu_DrawCursorLeft(origin.x + object->cursorpos.x, origin.y + object->cursorpos.y, 65536); - - break; - } - - case Message: - { - auto object = (MenuMessage_t*)cm->object; - - Menu_Pre(cm->menuID); - - Menu_PreDrawBackground(cm->menuID, origin); - - Menu_PreDraw(cm->menuID, NULL, origin); - - Menu_DrawCursorLeft(origin.x + object->cursorpos.x, origin.y + object->cursorpos.y, 65536); - - break; - } - - case TextForm: - { - auto object = (MenuTextForm_t*)cm->object; - - Menu_Pre(cm->menuID); - - Menu_PreDrawBackground(cm->menuID, origin); - - Menu_BlackRectangle(origin.x + (60<<16), origin.y + (86<<16), 200<<16, 28<<16, 0); - - mgametextcenter(origin.x, origin.y + (98<<16), object->instructions, TEXT_YBOTTOM); - - const char *displaytext = object->input; - - if (object->flags & MTF_Password) - { - size_t x; - for (x = 0; x < Bstrlen(object->input); ++x) - tempbuf[x] = '*'; - tempbuf[x] = 0; - - displaytext = tempbuf; - } - - const vec2_t textreturn = mgametextcenter(origin.x, origin.y + (102<<16), displaytext); - - Menu_PreDraw(cm->menuID, NULL, origin); - - int32_t const h = MF_Bluefont.get_yline(); - - Menu_DrawCursorText(origin.x + (MENU_MARGIN_CENTER<<16) + ((textreturn.x>>17)<<16) + (1<<16), origin.y + (102<<16) + ((h>>17)<<16), h); - - break; - } - - - - case Panel: - { - auto object = (MenuPanel_t*)cm->object; - - Menu_Pre(cm->menuID); - - Menu_PreDrawBackground(cm->menuID, origin); - - if (object->title != NoTitle) - Menu_DrawTopBar(origin); - - Menu_PreDraw(cm->menuID, NULL, origin); - - if (object->title != NoTitle) - Menu_DrawTopBarCaption(object->title, origin); - - break; - } - - case Menu: - { - int32_t state; - - auto menu = (MenuMenu_t*)cm->object; - MenuEntry_t *currentry = menu->entrylist[menu->currentEntry]; - - state = Menu_DetermineSpecialState(currentry); - - if (state != 2) - { - Menu_Pre(cm->menuID); - - Menu_PreDrawBackground(cm->menuID, origin); - - if (menu->title != NoTitle) - Menu_DrawTopBar(origin); - - Menu_PreDraw(cm->menuID, currentry, origin); - - M_RunMenu_Menu(cm, menu, currentry, state, origin); - } - else - { - Menu_PreDrawBackground(cm->menuID, origin); - - if (menu->title != NoTitle) - Menu_DrawTopBar(origin); - - if (currentry->type == Option) - { - if (currentry->name) - Menu_DrawTopBarCaption(currentry->name, origin); - - Menu_PreOptionListDraw(currentry, origin); - - Menu_RunOptionList(cm, currentry, (MenuOption_t*)currentry->entry, origin); - } - else if (currentry->type == Custom2Col) - { - Menu_PreCustom2ColScreenDraw(currentry, origin); - } - } - - if ((currentry->type != Option || state != 2) && menu->title != NoTitle) - Menu_DrawTopBarCaption(menu->title, origin); - - break; - } - } - -#if !defined EDUKE32_TOUCH_DEVICES - Menu_Run_MouseReturn(cm, origin); -#endif -} - -/* -Note: When menus are exposed to scripting, care will need to be taken so that -a user cannot define an empty MenuEntryList, or one containing only spacers, -or else this function will recurse infinitely. -*/ -static MenuEntry_t *Menu_RunInput_Menu_MovementVerify(MenuMenu_t *menu) -{ - return Menu_AdjustForCurrentEntryAssignment(menu); -} - -static MenuEntry_t *Menu_RunInput_Menu_Movement(MenuMenu_t *menu, MenuMovement_t direction) -{ - if (menu->numEntries == 1) - return menu->entrylist[menu->currentEntry]; - - switch (direction) - { - case MM_End: - menu->currentEntry = menu->numEntries; - fallthrough__; - case MM_Up: - do - { - --menu->currentEntry; - if (menu->currentEntry < 0) - return Menu_RunInput_Menu_Movement(menu, MM_End); - } - while (!menu->entrylist[menu->currentEntry] || - (menu->entrylist[menu->currentEntry]->flags & MEF_Hidden) || - menu->entrylist[menu->currentEntry]->type == Spacer); - break; - - case MM_Home: - menu->currentEntry = -1; - fallthrough__; - case MM_Down: - do - { - ++menu->currentEntry; - if (menu->currentEntry >= menu->numEntries) - return Menu_RunInput_Menu_Movement(menu, MM_Home); - } - while (!menu->entrylist[menu->currentEntry] || - (menu->entrylist[menu->currentEntry]->flags & MEF_Hidden) || - menu->entrylist[menu->currentEntry]->type == Spacer); - break; - - case MM_Swap: - menu->currentColumn = !menu->currentColumn; - break; - - default: - break; - } - - return Menu_RunInput_Menu_MovementVerify(menu); -} - -static void Menu_RunInput_EntryLink_Activate(MenuEntry_t *entry) -{ - auto link = (MenuLink_t*)entry->entry; - - Menu_EntryLinkActivate(entry); - - Menu_AnimateChange(link->linkID, link->animation); -} - -static void Menu_RunInput_EntryOptionList_MovementVerify(MenuOption_t *object) -{ - const int32_t listytop = object->options->menuFormat->pos.y; - // assumes height == font->get_yline()! - const int32_t unitheight = object->options->getMarginBottom() < 0 ? (-object->options->getMarginBottom() - object->options->font->get_yline()) / object->options->numOptions : (object->options->font->get_yline() + object->options->getMarginBottom()); - const int32_t ytop = listytop + object->options->currentEntry * unitheight; - const int32_t ybottom = ytop + object->options->font->get_yline(); - - if (ybottom - object->options->scrollPos > object->options->menuFormat->bottomcutoff) - object->options->scrollPos = ybottom - object->options->menuFormat->bottomcutoff; - else if (ytop - object->options->scrollPos < listytop) - object->options->scrollPos = ytop - listytop; -} - -static void Menu_RunInput_EntryOptionList_Movement(MenuOption_t *object, MenuMovement_t direction) -{ - switch (direction) - { - case MM_Up: - --object->options->currentEntry; - if (object->options->currentEntry >= 0) - break; - fallthrough__; - case MM_End: - object->options->currentEntry = object->options->numOptions-1; - break; - - case MM_Down: - ++object->options->currentEntry; - if (object->options->currentEntry < object->options->numOptions) - break; - fallthrough__; - case MM_Home: - object->options->currentEntry = 0; - break; - - default: - break; - } - - Menu_RunInput_EntryOptionList_MovementVerify(object); -} - -static int32_t Menu_RunInput_EntryOption_Modify(MenuEntry_t *entry, MenuOption_t *object, int32_t newValueIndex) -{ - int32_t newValue = (object->options->optionValues == NULL) ? newValueIndex : object->options->optionValues[newValueIndex]; - if (!Menu_EntryOptionModify(entry, newValue)) - { - object->currentOption = newValueIndex; - - if (object->cVar != NULL) // NULL implies the functions will handle it - { - UCVarValue v; - v.Int = newValue; - object->cVar->ForceSet(v, CVAR_Int, false); - } - Menu_EntryOptionDidModify(entry); - - return 0; - } - - return -1; -} - -static int32_t Menu_RunInput_EntryOption_Movement(MenuEntry_t *entry, MenuOption_t *object, MenuMovement_t direction) -{ - int32_t newValueIndex = object->currentOption; - - switch (direction) - { - case MM_Left: - --newValueIndex; - if (newValueIndex >= 0) - break; - fallthrough__; - case MM_AllTheWayRight: - newValueIndex = object->options->numOptions-1; - break; - - case MM_Right: - ++newValueIndex; - if (newValueIndex < object->options->numOptions) - break; - fallthrough__; - case MM_AllTheWayLeft: - newValueIndex = 0; - break; - - default: - break; - } - - return Menu_RunInput_EntryOption_Modify(entry, object, newValueIndex); -} - -static int32_t Menu_RunInput_EntryOption_Activate(MenuEntry_t *entry, MenuOption_t *object) -{ - if (object->options->features & 2) - return Menu_RunInput_EntryOption_Movement(entry, object, MM_Right); - else - { - object->options->currentEntry = object->currentOption >= 0 ? object->currentOption : 0; - Menu_RunInput_EntryOptionList_MovementVerify(object); - - return 0; - } -} - -static int32_t Menu_RunInput_EntryOptionList_Activate(MenuEntry_t *entry, MenuOption_t *object) -{ - if (!Menu_RunInput_EntryOption_Modify(entry, object, object->options->currentEntry)) - { - object->options->currentEntry = -1; - - return 0; - } - - return -1; -} - -static void Menu_RunInput_EntryCustom2Col_Activate(MenuEntry_t *entry) -{ - auto object = (MenuCustom2Col_t*)entry->entry; - - Menu_Custom2ColScreen(/*entry*/); - - object->screenOpen = 1; -} - -static void Menu_RunInput_EntryRangeInt32_MovementVerify(MenuEntry_t *entry, MenuRangeInt32_t *object, int32_t newValue) -{ - if (!Menu_EntryRangeInt32Modify(entry, newValue)) - *object->cVar = newValue; -} - -static void Menu_RunInput_EntryRangeInt32_MovementArbitrary(MenuEntry_t *entry, MenuRangeInt32_t *object, int32_t newValue) -{ - if (object->flags & EnforceIntervals) - { - int32_t const range = object->max - object->min; - int32_t const maxInterval = object->steps - 1; - int32_t const newValueIndex = roundscale(newValue - object->min, maxInterval, range); - newValue = newValueIndex * range / maxInterval + object->min; - } - - Menu_RunInput_EntryRangeInt32_MovementVerify(entry, object, newValue); -} - -static void Menu_RunInput_EntryRangeInt32_Movement(MenuEntry_t *entry, MenuRangeInt32_t *object, MenuMovement_t direction) -{ - int32_t const oldValue = *object->cVar; - int32_t const range = object->max - object->min; - int32_t const maxInterval = object->steps - 1; - int32_t const oldValueIndex = roundscale(oldValue - object->min, maxInterval, range); - int32_t const oldValueQuantized = oldValueIndex * range / maxInterval + object->min; - int32_t newValueIndex = oldValueIndex; - - switch (direction) - { - case MM_Left: - if (oldValueQuantized >= oldValue) - --newValueIndex; - if (newValueIndex >= 0) - break; - fallthrough__; - case MM_AllTheWayLeft: - newValueIndex = 0; - break; - - case MM_Right: - if (oldValueQuantized <= oldValue) - ++newValueIndex; - if (newValueIndex <= maxInterval) - break; - fallthrough__; - case MM_AllTheWayRight: - newValueIndex = maxInterval; - break; - - default: - break; - } - - int32_t const newValue = newValueIndex * range / maxInterval + object->min; - Menu_RunInput_EntryRangeInt32_MovementVerify(entry, object, newValue); -} - -static void Menu_RunInput_EntryRangeFloat_MovementVerify(MenuEntry_t *entry, MenuRangeFloat_t *object, float newValue) -{ - if (!Menu_EntryRangeFloatModify(entry, newValue)) - { - *object->cVar = newValue; - Menu_EntryRangeFloatDidModify(entry); - } -} - -static void Menu_RunInput_EntryRangeFloat_MovementArbitrary(MenuEntry_t *entry, MenuRangeFloat_t *object, float newValue) -{ - if (object->flags & EnforceIntervals) - { - float const range = object->max - object->min; - float const maxInterval = (float)(object->steps - 1); - float const newValueIndex = rintf((newValue - object->min) * maxInterval / range); - newValue = newValueIndex * range / maxInterval + object->min; - } - - Menu_RunInput_EntryRangeFloat_MovementVerify(entry, object, newValue); -} - -static void Menu_RunInput_EntryRangeFloat_Movement(MenuEntry_t *entry, MenuRangeFloat_t *object, MenuMovement_t direction) -{ - float const oldValue = *object->cVar; - float const range = object->max - object->min; - float const maxInterval = (float)(object->steps - 1); - float const oldValueIndexUnrounded = (oldValue - object->min) * maxInterval / range; - float const oldValueIndex = rintf(oldValueIndexUnrounded); - float const oldValueQuantized = oldValueIndex * range / maxInterval + object->min; - float newValueIndex = oldValueIndex; - - switch (direction) - { - case MM_Left: - if (oldValueQuantized >= oldValue) - newValueIndex -= 1.f; - if (newValueIndex >= 0.f) - break; - fallthrough__; - case MM_AllTheWayLeft: - newValueIndex = 0.f; - break; - - case MM_Right: - if (oldValueQuantized <= oldValue) - newValueIndex += 1.f; - if (newValueIndex <= maxInterval) - break; - fallthrough__; - case MM_AllTheWayRight: - newValueIndex = maxInterval; - break; - - default: - break; - } - - float const newValue = newValueIndex * range / maxInterval + object->min; - Menu_RunInput_EntryRangeFloat_MovementVerify(entry, object, newValue); -} - -static void Menu_RunInput_EntryString_Activate(MenuEntry_t *entry) -{ - auto object = (MenuString_t*)entry->entry; - - if (object->variable) - strncpy(typebuf, object->variable, TYPEBUFSIZE); - else - typebuf[0] = '\0'; - object->editfield = typebuf; - - // this limitation is an arbitrary implementation detail - if (object->bufsize > TYPEBUFSIZE) - object->bufsize = TYPEBUFSIZE; - - Menu_EntryStringActivate(/*entry*/); - Menu_StartTextInput(); -} - -static void Menu_RunInput_EntryString_Submit(/*MenuEntry_t *entry, */MenuString_t *object) -{ - if (!Menu_EntryStringSubmit(/*entry, */object->editfield)) - { - if (object->variable) - strncpy(object->variable, object->editfield, object->bufsize); - } - - object->editfield = NULL; - Menu_StopTextInput(); -} - -static void Menu_RunInput_EntryString_Cancel(/*MenuEntry_t *entry, */MenuString_t *object) -{ - Menu_EntryStringCancel(/*entry*/); - - object->editfield = NULL; - Menu_StopTextInput(); -} - -static void Menu_RunInput_FileSelect_MovementVerify(MenuFileSelect_t *object) -{ - -} - -static void Menu_RunInput_FileSelect_Movement(MenuFileSelect_t *object, MenuMovement_t direction) -{ -} - -static void Menu_RunInput_FileSelect_Select(MenuFileSelect_t *object) -{ - -} - -static void Menu_RunInput(Menu_t *cm) -{ - switch (cm->type) - { - case Panel: - { - auto panel = (MenuPanel_t*)cm->object; - - if (I_ReturnTrigger() || Menu_RunInput_MouseReturn()) - { - I_ReturnTriggerClear(); - m_mousecaught = 1; - - S_PlaySound(EXITMENUSOUND); - - Menu_AnimateChange(cm->parentID, cm->parentAnimation); - } - else if (I_PanelUp()) - { - I_PanelUpClear(); - - S_PlaySound(KICK_HIT); - Menu_AnimateChange(panel->previousID, panel->previousAnimation); - } - else if (I_PanelDown() || Menu_RunInput_MouseAdvance()) - { - I_PanelDownClear(); - m_mousecaught = 1; - - S_PlaySound(KICK_HIT); - Menu_AnimateChange(panel->nextID, panel->nextAnimation); - } - break; - } - - case TextForm: - { - auto object = (MenuTextForm_t*)cm->object; - int32_t hitstate = I_EnterText(object->input, object->bufsize-1, 0); - - if (hitstate == -1 || Menu_RunInput_MouseReturn()) - { - m_mousecaught = 1; - - S_PlaySound(EXITMENUSOUND); - - object->input = NULL; - - Menu_AnimateChange(cm->parentID, cm->parentAnimation); - Menu_StopTextInput(); - } - else if (hitstate == 1 || Menu_RunInput_MouseAdvance()) - { - m_mousecaught = 1; - - Menu_TextFormSubmit(object->input); - - object->input = NULL; - Menu_StopTextInput(); - } - break; - } - - case FileSelect: - { - Menu_PreInput(NULL); - break; - } - - case Message: - if (I_ReturnTrigger() || Menu_RunInput_MouseReturn()) - { - I_ReturnTriggerClear(); - m_mousecaught = 1; - - S_PlaySound(EXITMENUSOUND); - - Menu_AnimateChange(cm->parentID, cm->parentAnimation); - } - - if (I_CheckAllInput()) - { - auto message = (MenuMessage_t*)cm->object; - - I_ClearAllInput(); - - S_PlaySound(EXITMENUSOUND); - - Menu_AnimateChange(message->linkID, message->animation); - } - - Menu_PreInput(NULL); - break; - - case Verify: - if (I_ReturnTrigger() || inputState.GetKeyStatus(sc_N) || Menu_RunInput_MouseReturn()) - { - I_ReturnTriggerClear(); - inputState.ClearKeyStatus(sc_N); - m_mousecaught = 1; - - Menu_Verify(0); - - Menu_AnimateChange(cm->parentID, cm->parentAnimation); - - S_PlaySound(EXITMENUSOUND); - } - - if (I_AdvanceTrigger() || inputState.GetKeyStatus(sc_Y) || Menu_RunInput_MouseAdvance()) - { - auto verify = (MenuVerify_t*)cm->object; - - I_AdvanceTriggerClear(); - inputState.ClearKeyStatus(sc_Y); - m_mousecaught = 1; - - Menu_Verify(1); - - Menu_AnimateChange(verify->linkID, verify->animation); - - S_PlaySound(PISTOL_BODYHIT); - } - - Menu_PreInput(NULL); - break; - - else if (inputState.GetKeyStatus(sc_Home)) - { - inputState.ClearKeyStatus(sc_Home); - - S_PlaySound(KICK_HIT); - - currentry = Menu_RunInput_Menu_Movement(menu, MM_Home); - } - else if (inputState.GetKeyStatus(sc_End)) - { - inputState.ClearKeyStatus(sc_End); - - S_PlaySound(KICK_HIT); - - currentry = Menu_RunInput_Menu_Movement(menu, MM_End); - } - else if (I_MenuUp()) - { - I_MenuUpClear(); - - S_PlaySound(KICK_HIT); - - currentry = Menu_RunInput_Menu_Movement(menu, MM_Up); - } - else if (I_MenuDown()) - { - I_MenuDownClear(); - - S_PlaySound(KICK_HIT); - - currentry = Menu_RunInput_Menu_Movement(menu, MM_Down); - } - - if (currentry != NULL) - Menu_PreInput(currentry); - } - else if (state == 1) - { - if (currentry->type == String) - { - auto object = (MenuString_t*)currentry->entry; - - int32_t hitstate = I_EnterText(object->editfield, object->bufsize-1, object->flags); - - if (hitstate == -1 || Menu_RunInput_MouseReturn()) - { - m_mousecaught = 1; - - Menu_RunInput_EntryString_Cancel(/*currentry, */object); - - S_PlaySound(EXITMENUSOUND); - } - else if (hitstate == 1) - { - Menu_RunInput_EntryString_Submit(/*currentry, */object); - - S_PlaySound(PISTOL_BODYHIT); - } - } - } - else if (state == 2) - { - if (currentry->type == Option) - { - auto object = (MenuOption_t*)currentry->entry; - - if (I_ReturnTrigger() || Menu_RunInput_MouseReturn()) - { - I_ReturnTriggerClear(); - m_mousecaught = 1; - - S_PlaySound(EXITMENUSOUND); - - object->options->currentEntry = -1; - } - else if (I_AdvanceTrigger()) - { - I_AdvanceTriggerClear(); - - if (!Menu_RunInput_EntryOptionList_Activate(currentry, object)) - S_PlaySound(PISTOL_BODYHIT); - } - else if (inputState.GetKeyStatus(sc_Home)) - { - inputState.ClearKeyStatus(sc_Home); - - S_PlaySound(KICK_HIT); - - Menu_RunInput_EntryOptionList_Movement(object, MM_Home); - } - else if (inputState.GetKeyStatus(sc_End)) - { - inputState.ClearKeyStatus(sc_End); - - S_PlaySound(KICK_HIT); - - Menu_RunInput_EntryOptionList_Movement(object, MM_End); - } - else if (I_MenuUp()) - { - I_MenuUpClear(); - - S_PlaySound(KICK_HIT); - - Menu_RunInput_EntryOptionList_Movement(object, MM_Up); - } - else if (I_MenuDown()) - { - I_MenuDownClear(); - - S_PlaySound(KICK_HIT); - - Menu_RunInput_EntryOptionList_Movement(object, MM_Down); - } - } - else if (currentry->type == Custom2Col) - { - if (I_EscapeTrigger() || Menu_RunInput_MouseReturn()) - { - I_EscapeTriggerClear(); - m_mousecaught = 1; - - S_PlaySound(EXITMENUSOUND); - - ((MenuCustom2Col_t*)currentry->entry)->screenOpen = 0; - } - else if (Menu_PreCustom2ColScreen(currentry)) - ((MenuCustom2Col_t*)currentry->entry)->screenOpen = 0; - } - } - - break; - } - } -} - -void M_DisplayMenus(void) -{ - vec2_t origin = { 0, 0 }, previousOrigin = { 0, 0 }; - - Net_GetPackets(); - - if ((g_player[myconnectindex].ps->gm&MODE_MENU) == 0) - { - return; - } - - if (!Menu_IsTextInput(m_currentMenu) && inputState.GetKeyStatus(sc_Q)) - Menu_AnimateChange(MENU_QUIT, MA_Advance); - - int32_t mousestatus = inputState.mouseReadAbs(&m_mousepos); - if (mousestatus && inputState.mouseClickState() == MOUSE_PRESSED) - m_mousedownpos = m_mousepos; - - Menu_RunInput(m_currentMenu); - - g_player[myconnectindex].ps->gm &= (0xff-MODE_TYPE); - // g_player[myconnectindex].ps->fta = 0; - - int32_t const backgroundOK = ud.menubackground && Menu_BlackTranslucentBackgroundOK(g_currentMenu); - - // need EVENT_DISPLAYMENUBACKGROUND here - - if (!FURY && ((g_player[myconnectindex].ps->gm&MODE_GAME) || ud.recstat==2) && backgroundOK) - videoFadeToBlack(1); - - if (Menu_UpdateScreenOK(g_currentMenu)) - G_UpdateScreenArea(); - -#if !defined EDUKE32_TOUCH_DEVICES - if (m_menuchange_watchpoint > 0) - m_menuchange_watchpoint++; -#endif - - if (m_parentMenu) - { - ud.returnvar[0] = origin.x; - ud.returnvar[1] = origin.y; - if (m_parentMenu->type == Menu) - { - ud.returnvar[2] = ((MenuMenu_t *)m_parentMenu->object)->currentEntry; - if (m_parentMenu->menuID == MENU_NEWGAMECUSTOMSUB) - ud.returnvar[3] = M_NEWGAMECUSTOM.currentEntry; - } - VM_OnEventWithReturn(EVENT_DISPLAYINACTIVEMENU, g_player[screenpeek].ps->i, screenpeek, m_parentMenu->menuID); - origin.x = ud.returnvar[0]; - origin.y = ud.returnvar[1]; - } - - - - if (m_parentMenu && backgroundOK) - { - Menu_Run(m_parentMenu, origin); - } - - // hack; need EVENT_DISPLAYMENUBACKGROUND above - if (FURY && ((g_player[myconnectindex].ps->gm&MODE_GAME) || ud.recstat==2 || m_parentMenu != NULL) && backgroundOK) - videoFadeToBlack(1); - - // Display the menu, with a transition animation if applicable. - if (totalclock < m_animation.start + m_animation.length) - { - Menu_Run(m_animation.previous, previousOrigin); - Menu_Run(m_animation.current, origin); - } - else - Menu_Run(m_currentMenu, origin); - -#if !defined EDUKE32_TOUCH_DEVICES - if (m_menuchange_watchpoint >= 3) - m_menuchange_watchpoint = 0; -#endif - - if (m_parentMenu) - { - ud.returnvar[0] = origin.x; - ud.returnvar[1] = origin.y; - if (m_parentMenu->type == Menu) - { - ud.returnvar[2] = ((MenuMenu_t *)m_parentMenu->object)->currentEntry; - if (m_parentMenu->menuID == MENU_NEWGAMECUSTOMSUB) - ud.returnvar[3] = M_NEWGAMECUSTOM.currentEntry; - } - VM_OnEventWithReturn(EVENT_DISPLAYINACTIVEMENUREST, g_player[screenpeek].ps->i, screenpeek, m_parentMenu->menuID); - } - - - -#if !defined EDUKE32_TOUCH_DEVICES - if (tilesiz[CROSSHAIR].x > 0 && mousestatus) -#else - if (mousestatus) -#endif - { -#if !defined EDUKE32_TOUCH_DEVICES - if (!MOUSEACTIVECONDITION) - m_mousewake_watchpoint = 1; -#endif - - if (MOUSEACTIVECONDITIONAL(inputState.mouseAdvanceClickState()) || m_mousepos.x != m_prevmousepos.x || m_mousepos.y != m_prevmousepos.y) - { - m_prevmousepos = m_mousepos; - m_mouselastactivity = (int32_t) totalclock; - } -#if !defined EDUKE32_TOUCH_DEVICES - else - m_mousewake_watchpoint = 0; -#endif - - m_mousecaught = 0; - } - else - { - m_mouselastactivity = -M_MOUSETIMEOUT; - -#if !defined EDUKE32_TOUCH_DEVICES - m_mousewake_watchpoint = 0; -#endif - } - -#ifndef EDUKE32_TOUCH_DEVICES - // Display the mouse cursor, except on touch devices. - if (MOUSEACTIVECONDITION) - { - if (VM_HaveEvent(EVENT_DISPLAYCURSOR)) - { - ud.returnvar[0] = m_mousepos.x; - ud.returnvar[1] = m_mousepos.y; - ud.returnvar[2] = CURSORALPHA; - } - int32_t a = VM_OnEventWithReturn(EVENT_DISPLAYCURSOR, g_player[screenpeek].ps->i, screenpeek, CROSSHAIR); - - if ((unsigned) a < MAXTILES) - { - vec2_t cursorpos = m_mousepos; - int32_t z = 65536; - uint8_t p = CROSSHAIR_PAL; - uint32_t o = 2|8; - - auto const oyxaspect = yxaspect; - int32_t alpha; - if (FURY) - { - renderSetAspect(viewingrange, 65536); - cursorpos.x = scale(cursorpos.x - (320<<15), ydim << 2, xdim * 3) + (320<<15); - cursorpos.y = scale(cursorpos.y - (200<<15), (ydim << 2) * 6, (xdim * 3) * 5) + (200<<15); - z = scale(32768, ydim << 2, xdim * 3); - p = 0; - o |= 1024; - alpha = MOUSEALPHA; - } - else - { - alpha = CURSORALPHA; - } - - rotatesprite_fs_alpha(cursorpos.x, cursorpos.y, z, 0, a, 0, p, o, alpha); - - if (FURY) - renderSetAspect(viewingrange, oyxaspect); - } - } - else - inputState.clearMouseClickState(); -#endif - - if ((g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU) - { - G_UpdateScreenArea(); - CAMERACLOCK = (int32_t) totalclock; - CAMERADIST = 65536; - } -} - -bool GameInterface::mouseInactiveConditional(bool condition) -{ - return MOUSEINACTIVECONDITIONAL(condition); -} #endif From 6ad9c1c0e3a70923dbb07c6ea7bbb5513d6d097a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 02:14:30 +0100 Subject: [PATCH 038/203] - set up d_menu.cpp for Redneck Rampage --- source/common/menu/menu.cpp | 4 +- source/rr/CMakeLists.txt | 9 +- source/rr/src/d_menu.cpp | 468 ++++++++++++++++++++++++++++++++++++ 3 files changed, 474 insertions(+), 7 deletions(-) create mode 100644 source/rr/src/d_menu.cpp diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 3478b1890..e043450c8 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -53,7 +53,7 @@ #include "build.h" void RegisterDukeMenus(); -void RegisterSpecialMenus(); +void RegisterRedneckMenus(); extern bool rotatesprite_2doverride; bool help_disabled, credits_disabled; int g_currentMenu; // accessible by CON scripts - contains the current menu's script ID if defined or INT_MAX if none given. @@ -873,8 +873,8 @@ void Menu_Close(int playerid) void M_Init (void) { - RegisterSpecialMenus(); RegisterDukeMenus(); + RegisterRedneckMenus(); timerSetCallback(M_Ticker); M_ParseMenuDefs(); } diff --git a/source/rr/CMakeLists.txt b/source/rr/CMakeLists.txt index 43ee43de1..7d7cd7e00 100644 --- a/source/rr/CMakeLists.txt +++ b/source/rr/CMakeLists.txt @@ -31,9 +31,9 @@ include_directories( set( NOT_COMPILED_SOURCE_FILES ) - + set_source_files_properties( ${NOT_COMPILED_SOURCE_FILES} PROPERTIES HEADER_FILE_ONLY TRUE ) - + set( PCH_SOURCES src/actors.cpp src/anim.cpp @@ -41,6 +41,7 @@ set( PCH_SOURCES src/cmdline.cpp src/common.cpp src/config.cpp + src/d_menu.cpp src/demo.cpp src/game.cpp src/gamedef.cpp @@ -69,7 +70,7 @@ if( MSVC ) else() # Temporary solution for compilers other than MSVC set_source_files_properties( ${PCH_SOURCES} PROPERTIES COMPILE_FLAGS "-include g_pch.h" ) -endif() +endif() file( GLOB HEADER_FILES src/*.h @@ -79,5 +80,3 @@ add_library( rr STATIC ${PCH_SOURCES} ${NOT_COMPILED_SOURCE_FILES} ) - - diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp new file mode 100644 index 000000000..80dd7bef4 --- /dev/null +++ b/source/rr/src/d_menu.cpp @@ -0,0 +1,468 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2016 EDuke32 developers and contributors +Copyright (C) 2019 Christoph Oelckers + +This is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +//------------------------------------------------------------------------- + +#include "ns.h" // Must come before everything else! + +#include "cheats.h" +#include "compat.h" +#include "demo.h" +#include "duke3d.h" +#include "input.h" +#include "menus.h" +#include "osdcmds.h" +#include "savegame.h" +#include "game.h" +#include "superfasthash.h" +#include "gamecvars.h" +#include "gamecontrol.h" +#include "c_bind.h" +#include "menu/menu.h" +#include "gstrings.h" +#include "version.h" +#include "namesdyn.h" +#include "../../glbackend/glbackend.h" + +BEGIN_DUKE_NS + +#define MENU_MARGIN_REGULAR 40 +#define MENU_MARGIN_WIDE 32 +#define MENU_MARGIN_CENTER 160 +#define MENU_HEIGHT_CENTER 100 + + +enum MenuTextFlags_t +{ + MT_Selected = 1 << 0, + MT_Disabled = 1 << 1, + MT_XCenter = 1 << 2, + MT_XRight = 1 << 3, + MT_YCenter = 1 << 4, + MT_Literal = 1 << 5, + MT_RightSide = 1 << 6, +}; + + +// common font types +// tilenums are set after namesdyn runs. +// These are also modifiable by scripts. +// emptychar x,y between x,y zoom cursorLeft cursorCenter cursorScale textflags +// tilenum shade_deselected shade_disabled pal pal_selected pal_deselected pal_disabled +MenuFont_t MF_Redfont = { { 5<<16, 15<<16 }, { 0, 0 }, 65536, 20<<16, 110<<16, 65536, TEXT_BIGALPHANUM | TEXT_UPPERCASE, + -1, 10, 0, 0, 0, 0, 1, + 0, 0, 1 }; +MenuFont_t MF_Bluefont = { { 5<<16, 7<<16 }, { 0, 0 }, 65536, 10<<16, 110<<16, 32768, 0, + -1, 10, 0, 0, 10, 10, 16, + 0, 0, 16 }; +MenuFont_t MF_Minifont = { { 4<<16, 5<<16 }, { 1<<16, 1<<16 }, 65536, 10<<16, 110<<16, 32768, 0, + -1, 10, 0, 0, 2, 2, 0, + 0, 0, 16 }; + + +/* +This function prepares data after ART and CON have been processed. +It also initializes some data in loops rather than statically at compile time. +*/ +void Menu_Init(void) +{ + + // prepare menu fonts + // check if tilenum is -1 in case it was set in EVENT_SETDEFAULTS + if ((unsigned)MF_Redfont.tilenum >= MAXTILES) MF_Redfont.tilenum = BIGALPHANUM; + if ((unsigned)MF_Bluefont.tilenum >= MAXTILES) MF_Bluefont.tilenum = STARTALPHANUM; + if ((unsigned)MF_Minifont.tilenum >= MAXTILES) MF_Minifont.tilenum = MINIFONT; + MF_Redfont.emptychar.y = tilesiz[MF_Redfont.tilenum].y << 16; + MF_Bluefont.emptychar.y = tilesiz[MF_Bluefont.tilenum].y << 16; + MF_Minifont.emptychar.y = tilesiz[MF_Minifont.tilenum].y << 16; + if (!minitext_lowercase) + MF_Minifont.textflags |= TEXT_UPPERCASE; + +#if 0 + + // prepare sound setup +#ifndef EDUKE32_STANDALONE + if (WW2GI) + ME_SOUND_DUKETALK.name = "GI talk:"; + else if (NAM) + ME_SOUND_DUKETALK.name = "Grunt talk:"; + ME_SOUND_DUKETALK.name = "Leonard Talk:"; + +#endif + + // prepare pre-Atomic + if (!VOLUMEALL || !PLUTOPAK) + { + // prepare credits + M_CREDITS.title = M_CREDITS2.title = M_CREDITS3.title = s_Credits; + } +#endif + + if (RR) + { + MF_Redfont.zoom = 32768; + MF_Redfont.emptychar.x <<= 1; + MF_Redfont.cursorScale = 13107; + MF_Redfont.cursorScale2 = 6553; + //MF_Redfont.emptychar.y <<= 1; + MF_Bluefont.zoom = 32768; + MF_Bluefont.emptychar.x <<= 1; + MF_Bluefont.cursorScale = 6553; + MF_Bluefont.cursorScale2 = 6553; + //MF_Bluefont.emptychar.y <<= 1; + MF_Minifont.zoom = 32768; + MF_Minifont.emptychar.x <<= 1; + MF_Minifont.cursorScale = 6553; + MF_Minifont.cursorScale2 = 6553; + //MF_Minifont.emptychar.y <<= 1; + } + +} + +static void Menu_DrawBackground(const DVector2 &origin) +{ + rotatesprite_fs(int(origin.X * 65536) + (MENU_MARGIN_CENTER << 16), int(origin.Y * 65536) + (100 << 16), 65536L, 0, MENUSCREEN, 16, 0, 10 + 64); +} + +static void Menu_DrawTopBar(const DVector2 &origin) +{ + if ((G_GetLogoFlags() & LOGO_NOTITLEBAR) == 0) + rotatesprite_fs(int(origin.X*65536) + (MENU_MARGIN_CENTER<<16), int(origin.Y*65536) + (19<<16), MF_Redfont.cursorScale, 0,MENUBAR,16,0,10); +} + +static void Menu_DrawTopBarCaption(const char *caption, const DVector2 &origin) +{ + static char t[64]; + if (*caption == '$') caption = GStrings(caption + 1); + size_t const srclen = strlen(caption); + size_t const dstlen = min(srclen, ARRAY_SIZE(t)-1); + memcpy(t, caption, dstlen); + t[dstlen] = '\0'; + char *p = &t[dstlen-1]; + if (*p == ':') + *p = '\0'; + captionmenutext(int(origin.X*65536) + (MENU_MARGIN_CENTER<<16), int(origin.Y*65536) + (24<<16) + ((15>>1)<<16), t); +} + +static void Menu_GetFmt(const MenuFont_t* font, uint8_t const status, int32_t* s, int32_t* z) +{ + if (status & MT_Selected) + *s = VM_OnEventWithReturn(EVENT_MENUSHADESELECTED, -1, myconnectindex, sintable[((int32_t)totalclock << 5) & 2047] >> 12); + else + *s = font->shade_deselected; + // sum shade values + if (status & MT_Disabled) + *s += font->shade_disabled; +} + +static vec2_t Menu_Text(int32_t x, int32_t y, const MenuFont_t* font, const char* t, uint8_t status, int32_t ydim_upper, int32_t ydim_lower) +{ + int32_t s, p, ybetween = font->between.y; + int32_t f = font->textflags; + if (status & MT_XCenter) + f |= TEXT_XCENTER; + if (status & MT_XRight) + f |= TEXT_XRIGHT; + if (status & MT_YCenter) + { + f |= TEXT_YCENTER | TEXT_YOFFSETZERO; + ybetween = font->emptychar.y; // <^ the battle against 'Q' + } + if (status & MT_Literal) + f |= TEXT_LITERALESCAPE; + + int32_t z = font->zoom; + + if (status & MT_Disabled) + p = (status & MT_RightSide) ? font->pal_disabled_right : font->pal_disabled; + else if (status & MT_Selected) + p = (status & MT_RightSide) ? font->pal_selected_right : font->pal_selected; + else + p = (status & MT_RightSide) ? font->pal_deselected_right : font->pal_deselected; + + Menu_GetFmt(font, status, &s, &z); + + return G_ScreenText(font->tilenum, x, y, z, 0, 0, t, s, p, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, font->emptychar.x, font->emptychar.y, font->between.x, ybetween, f, 0, ydim_upper, xdim - 1, ydim_lower); +} + +static int32_t Menu_CursorShade(void) +{ + return 4 - (sintable[((int32_t)totalclock << 4) & 2047] >> 11); +} + +static void Menu_DrawCursorCommon(int32_t x, int32_t y, int32_t z, int32_t picnum, int32_t ydim_upper = 0, int32_t ydim_lower = ydim - 1) +{ + rotatesprite_(x, y, z, 0, picnum, Menu_CursorShade(), 0, 2 | 8, 0, 0, 0, ydim_upper, xdim - 1, ydim_lower); +} + +static void Menu_DrawCursorLeft(int32_t x, int32_t y, int32_t z) +{ + const int frames = RR ? 16 : 7; + Menu_DrawCursorCommon(x, y, z, SPINNINGNUKEICON+(((int32_t) totalclock>>3)%frames)); +} + +static void Menu_DrawCursorRight(int32_t x, int32_t y, int32_t z) +{ + const int frames = RR ? 16 : 7; + Menu_DrawCursorCommon(x, y, z, SPINNINGNUKEICON+frames-1-((frames-1+((int32_t) totalclock>>3))%frames)); +} + +static int Menu_GetFontHeight(int fontnum) +{ + auto& font = fontnum == NIT_BigFont ? MF_Redfont : fontnum == NIT_SmallFont ? MF_Bluefont : MF_Minifont; + return font.get_yline(); +} + +void GameInterface::DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int flags) +{ + int ydim_upper = 0; + int ydim_lower = ydim - 1; + //int32_t const indent = 0; // not set for any relevant menu + int32_t x = xpos; + + uint8_t status = 0; + if (state == NIT_SelectedState) + status |= MT_Selected; + if (state == NIT_InactiveState) + status |= MT_Disabled; + if (flags & LMF_Centered) + status |= MT_XCenter; + + bool const dodraw = true; + MenuFont_t& font = fontnum == NIT_BigFont ? MF_Redfont : fontnum == NIT_SmallFont ? MF_Bluefont : MF_Minifont; + + int32_t const height = font.get_yline(); + status |= MT_YCenter; + int32_t const y_internal = ypos + ((height >> 17) << 16);// -menu->scrollPos; + + vec2_t textsize; + if (dodraw) + textsize = Menu_Text(x, y_internal, &font, text, status, ydim_upper, ydim_lower); + + if (dodraw && (status & MT_Selected) && state != 1) + { + if (status & MT_XCenter) + { + Menu_DrawCursorLeft(x + font.cursorCenterPosition, y_internal, font.cursorScale); + Menu_DrawCursorRight(x - font.cursorCenterPosition, y_internal, font.cursorScale); + } + else + Menu_DrawCursorLeft(x /*+ indent*/ - font.cursorLeftPosition, y_internal, font.cursorScale); + } + +} + + + +//---------------------------------------------------------------------------- +// +// Implements the native looking menu used for the main menu +// and the episode/skill selection screens, i.e. the parts +// that need to look authentic +// +//---------------------------------------------------------------------------- + +class RedneckListMenu : public DListMenu +{ + using Super = DListMenu; +protected: + + void Ticker() override + { + // Lay out the menu. + int32_t y_upper = mDesc->mYpos; + int32_t y_lower = y_upper + mDesc->mYbotton; + int32_t y = 0; + int32_t calculatedentryspacing = 0; + int32_t const height = Menu_GetFontHeight(mDesc->mNativeFontNum) >> 16; + + int32_t totalheight = 0, numvalidentries = mDesc->mItems.Size(); + + for (unsigned e = 0; e < mDesc->mItems.Size(); ++e) + { + auto entry = mDesc->mItems[e]; + entry->mHidden = false; + entry->SetHeight(height); + totalheight += height; + } + if (mDesc->mSpacing <= 0) calculatedentryspacing = std::max(0, (y_lower - y_upper - totalheight) / (numvalidentries > 1 ? numvalidentries - 1 : 1)); + if (calculatedentryspacing <= 0) calculatedentryspacing = mDesc->mSpacing; + + + // totalHeight calculating pass + int totalHeight; + for (unsigned e = 0; e < mDesc->mItems.Size(); ++e) + { + auto entry = mDesc->mItems[e]; + if (!entry->mHidden) + { + entry->SetY(y_upper + y); + y += height; + totalHeight = y; + y += calculatedentryspacing; + } + } + } + + void PreDraw() override + { + if (mDesc->mCaption.IsNotEmpty()) + { + Menu_DrawTopBar(origin); + Menu_DrawTopBarCaption(mDesc->mCaption, origin); + } + } +}; + +class MainMenu : public RedneckListMenu +{ + void PreDraw() override + { + RedneckListMenu::PreDraw(); + rotatesprite_fs(origin.x + ((MENU_MARGIN_CENTER-5)<<16), origin.y + ((57+l)<<16), 16592L,0,RRRA? THREEDEE : INGAMEDUKETHREEDEE,0,0,10); + } +}; + +//---------------------------------------------------------------------------- +// +// Menu related game interface functions +// +//---------------------------------------------------------------------------- + + +bool GameInterface::mouseInactiveConditional(bool condition) // can hopefully go away once the menu refactor is complete +{ + return condition; +} + +void GameInterface::MenuOpened() +{ + S_PauseSounds(true); + if ((!g_netServer && ud.multimode < 2)) + { + ready2send = 0; + totalclock = ototalclock; + screenpeek = myconnectindex; + } +} + +void GameInterface::MenuSound(::GameInterface::EMenuSounds snd) +{ + switch (snd) + { + case SelectSound: + S_PlaySound(RR ? 335 : KICK_HIT); + break; + + case ChooseSound: + S_PlaySound(RR? 341 : PISTOL_BODYHIT); + break; + + default: + return; + } +} + + +void GameInterface::MenuClosed() +{ + S_PlaySound(EXITMENUSOUND); + if (!ud.pause_on) + S_PauseSounds(false); +} + +bool GameInterface::CanSave() +{ + if (ud.recstat == 2) return false; + auto &myplayer = *g_player[myconnectindex].ps; + if (sprite[myplayer.i].extra <= 0) + { + P_DoQuote(QUOTE_SAVE_DEAD, &myplayer); + return false; + } + return true; +} + +void GameInterface::StartGame(FGameStartup& gs) +{ + int32_t skillsound = PISTOL_BODYHIT; + + switch (gs.Skill) + { + case 0: + skillsound = 427; + break; + case 1: + skillsound = 428; + break; + case 2: + skillsound = 196; + break; + case 3: + skillsound = 195; + break; + case 4: + skillsound = 197; + break; + } + + ud.m_player_skill = gs.Skill + 1; + ud.skill_voice = S_PlaySound(skillsound); + ud.m_respawn_monsters = (gs.Skill == 3); + ud.m_monsters_off = ud.monsters_off = 0; + ud.m_respawn_items = 0; + ud.m_respawn_inventory = 0; + ud.multimode = 1; + ud.m_volume_number = gs.Episode; + ud.m_level_number = gs.Level; + G_NewGame_EnterLevel(); + +} + +FSavegameInfo GameInterface::GetSaveSig() +{ + return { SAVESIG_RR, MINSAVEVER_RR, SAVEVER_RR }; +} + +void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) +{ + Menu_DrawBackground(origin); + G_ScreenText(MF_Bluefont.tilenum, int(origin.X + 160) * 65536), int((origin.Y + position) * 65536), MF_Bluefont.zoom, 0, 0, text, 0, MF_Bluefont.pal, + 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, + MF_Bluefont.textflags | f | TEXT_XCENTER, 0, 0, xdim - 1, ydim - 1); +} + + +END_DUKE_NS + +//---------------------------------------------------------------------------- +// +// Class registration +// +//---------------------------------------------------------------------------- + + +static TMenuClassDescriptor _mm("Redneck.MainMenu"); +static TMenuClassDescriptor _lm("Redneck.ListMenu"); + +void RegisterRedneckMenus() +{ + menuClasses.Push(&_mm); + menuClasses.Push(&_lm); +} From d569cd76c162c84cb2408743174e89d7d11bfdf7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 02:36:34 +0100 Subject: [PATCH 039/203] - cleanup of sound code - removal of the cache lock This has been inoperable for a long time and by now the cache is entirely gone. --- source/duke3d/src/global.h | 1 - source/duke3d/src/sounds.cpp | 68 +----------------------------------- source/duke3d/src/sounds.h | 3 +- source/rr/src/global.h | 1 - source/rr/src/sounds.cpp | 28 ++------------- source/rr/src/sounds.h | 3 +- 6 files changed, 6 insertions(+), 98 deletions(-) diff --git a/source/duke3d/src/global.h b/source/duke3d/src/global.h index 5cce04534..9acb60b9f 100644 --- a/source/duke3d/src/global.h +++ b/source/duke3d/src/global.h @@ -147,7 +147,6 @@ G_EXTERN playerspawn_t g_playerSpawnPoints[MAXPLAYERS]; G_EXTERN input_t inputfifo[MOVEFIFOSIZ][MAXPLAYERS]; #pragma pack(pop) -G_EXTERN uint8_t g_soundlocks[MAXSOUNDS]; G_EXTERN int32_t g_noEnemies; G_EXTERN int32_t g_restorePalette; G_EXTERN int32_t g_screenCapture; diff --git a/source/duke3d/src/sounds.cpp b/source/duke3d/src/sounds.cpp index ca4b4ecea..e45f61297 100644 --- a/source/duke3d/src/sounds.cpp +++ b/source/duke3d/src/sounds.cpp @@ -83,10 +83,6 @@ void S_SoundStartup(void) g_sounds[i].num = 0; S_SetProperties(&voice, -1, 0, UINT16_MAX, 0); } - -#ifdef CACHING_DOESNT_SUCK - g_soundlocks[i] = 199; -#endif } cacheAllSounds(); @@ -189,7 +185,6 @@ void S_RestartMusic(void) void S_MenuSound(void) { -#ifndef EDUKE32_STANDALONE static int SoundNum; int const menusnds[] = { LASERTRIP_EXPLODE, DUKE_GRUNT, DUKE_LAND_HURT, CHAINGUN_FIRE, SQUISHED, KICK_HIT, @@ -197,9 +192,6 @@ void S_MenuSound(void) PIPEBOMB_BOUNCE, PIPEBOMB_EXPLODE, NITEVISION_ONOFF, RPG_SHOOT, SELECT_WEAPON, }; int s = VM_OnEventWithReturn(EVENT_OPENMENUSOUND, g_player[screenpeek].ps->i, screenpeek, FURY ? -1 : menusnds[SoundNum++ % ARRAY_SIZE(menusnds)]); -#else - int s = VM_OnEventWithReturn(EVENT_OPENMENUSOUND, g_player[screenpeek].ps->i, screenpeek, -1); -#endif if (s != -1) S_PlaySound(s); } @@ -423,9 +415,6 @@ void S_Cleanup(void) // for which there was no open slot to keep track of the voice if (num >= (MAXSOUNDS*MAXSOUNDINSTANCES)) { -#ifdef CACHING_DOESNT_SUCK - --g_soundlocks[num-(MAXSOUNDS*MAXSOUNDINSTANCES)]; -#endif continue; } @@ -450,9 +439,6 @@ void S_Cleanup(void) S_SetProperties(&voice, -1, 0, UINT16_MAX, 0); -#ifdef CACHING_DOESNT_SUCK - --g_soundlocks[num]; -#endif } } @@ -473,9 +459,8 @@ int32_t S_LoadSound(int num) } int32_t l = fp.GetLength(); - g_soundlocks[num] = 255; snd.siz = l; - cacheAllocateBlock((intptr_t *)&snd.ptr, l, &g_soundlocks[num]); + cacheAllocateBlock((intptr_t *)&snd.ptr, l, nullptr); l = fp.Read(snd.ptr, l); return l; @@ -611,19 +596,13 @@ sound_further_processing: if (sndist < 0) sndist = 0; -#ifndef EDUKE32_STANDALONE if (!FURY && sectNum > -1 && sndist && PN(spriteNum) != MUSICANDSFX && !cansee(cam->x, cam->y, cam->z - (24 << 8), sectNum, SX(spriteNum), SY(spriteNum), SZ(spriteNum) - (24 << 8), SECT(spriteNum))) sndist += sndist>>5; -#else - UNREFERENCED_PARAMETER(sectNum); -#endif if ((g_sounds[soundNum].m & (SF_GLOBAL|SF_DTAG)) == (SF_GLOBAL|SF_DTAG)) { -#ifndef EDUKE32_STANDALONE boost: -#endif int const sdist = g_sounds[soundNum].vo > 0 ? g_sounds[soundNum].vo : 6144; explosion = true; @@ -631,8 +610,6 @@ boost: if (sndist > sdist) sndist = sdist; } - -#ifndef EDUKE32_STANDALONE else if (!FURY) { switch (DYNAMICSOUNDMAP(soundNum)) @@ -643,7 +620,6 @@ boost: goto boost; } } -#endif if ((g_sounds[soundNum].m & (SF_GLOBAL|SF_DTAG)) == SF_GLOBAL || sndist < ((255-LOUDESTVOLUME) << 6)) sndist = ((255-LOUDESTVOLUME) << 6); @@ -751,18 +727,10 @@ int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos) if (snd.num > 0 && PN(spriteNum) != MUSICANDSFX) S_StopEnvSound(sndNum, spriteNum); -#ifdef CACHING_DOESNT_SUCK - if (++g_soundlocks[sndNum] < 200) - g_soundlocks[sndNum] = 200; -#endif - int const sndSlot = S_GetSlot(sndNum); if (sndSlot >= MAXSOUNDINSTANCES) { -#ifdef CACHING_DOESNT_SUCK - g_soundlocks[sndNum]--; -#endif return -1; } @@ -770,9 +738,6 @@ int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos) if (repeatp && (snd.m & SF_ONEINST_INTERNAL) && snd.num > 0) { -#ifdef CACHING_DOESNT_SUCK - g_soundlocks[sndNum]--; -#endif return -1; } @@ -781,9 +746,6 @@ int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos) if (voice <= FX_Ok) { -#ifdef CACHING_DOESNT_SUCK - g_soundlocks[sndNum]--; -#endif return -1; } @@ -816,18 +778,10 @@ int S_PlaySound(int num) int const pitch = S_GetPitch(num); -#ifdef CACHING_DOESNT_SUCK - if (++g_soundlocks[num] < 200) - g_soundlocks[num] = 200; -#endif - sndnum = S_GetSlot(num); if (sndnum >= MAXSOUNDINSTANCES) { -#ifdef CACHING_DOESNT_SUCK - g_soundlocks[num]--; -#endif return -1; } @@ -838,9 +792,6 @@ int S_PlaySound(int num) if (voice <= FX_Ok) { -#ifdef CACHING_DOESNT_SUCK - g_soundlocks[num]--; -#endif return -1; } @@ -876,11 +827,6 @@ void S_StopEnvSound(int sndNum, int sprNum) if ((sprNum == -1 && voice.id > FX_Ok) || (sprNum != -1 && voice.owner == sprNum)) { -#ifdef DEBUGGINGAIDS - if (EDUKE32_PREDICT_FALSE(sprNum >= 0 && voice.id <= FX_Ok)) - initprintf(OSD_ERROR "S_StopEnvSound(): bad voice %d for sound ID %d index %d!\n", voice.id, sndNum, j); - else -#endif if (voice.id > FX_Ok) { if (FX_SoundActive(voice.id)) @@ -996,18 +942,6 @@ void S_Callback(intptr_t num) mutex_unlock(&m_callback); } -void S_ClearSoundLocks(void) -{ -#ifdef CACHING_DOESNT_SUCK - int32_t i; - int32_t const msp = g_highestSoundIdx; - - for (native_t i = 0; i <= msp; ++i) - if (g_soundlocks[i] >= 200) - g_soundlocks[i] = 199; -#endif -} - int A_CheckSoundPlaying(int spriteNum, int soundNum) { if (EDUKE32_PREDICT_FALSE((unsigned)soundNum > (unsigned)g_highestSoundIdx)) return 0; diff --git a/source/duke3d/src/sounds.h b/source/duke3d/src/sounds.h index fab55af82..b19471c53 100644 --- a/source/duke3d/src/sounds.h +++ b/source/duke3d/src/sounds.h @@ -57,7 +57,6 @@ typedef struct char pr, m; // 2b } sound_t; -extern uint8_t g_soundlocks[MAXSOUNDS]; extern sound_t g_sounds[MAXSOUNDS]; extern int32_t g_numEnvSoundsPlaying,g_highestSoundIdx; @@ -67,7 +66,7 @@ void S_Callback(intptr_t num); int A_CheckAnySoundPlaying(int spriteNum); int S_CheckSoundPlaying(int soundNum); void S_Cleanup(void); -void S_ClearSoundLocks(void); +inline void S_ClearSoundLocks(void) {} int32_t S_LoadSound(uint32_t num); void cacheAllSounds(void); void S_MenuSound(void); diff --git a/source/rr/src/global.h b/source/rr/src/global.h index d6c83ed25..217368c60 100644 --- a/source/rr/src/global.h +++ b/source/rr/src/global.h @@ -245,7 +245,6 @@ G_EXTERN playerspawn_t g_playerSpawnPoints[MAXPLAYERS]; G_EXTERN input_t inputfifo[MOVEFIFOSIZ][MAXPLAYERS]; #pragma pack(pop) -G_EXTERN uint8_t g_soundlocks[MAXSOUNDS]; G_EXTERN int32_t g_noEnemies; G_EXTERN int32_t g_restorePalette; G_EXTERN int32_t g_screenCapture; diff --git a/source/rr/src/sounds.cpp b/source/rr/src/sounds.cpp index 85cf2b899..9b11fe2d9 100644 --- a/source/rr/src/sounds.cpp +++ b/source/rr/src/sounds.cpp @@ -394,7 +394,6 @@ void S_Cleanup(void) // for which there was no open slot to keep track of the voice if (num >= (MAXSOUNDS*MAXSOUNDINSTANCES)) { - --g_soundlocks[num-(MAXSOUNDS*MAXSOUNDINSTANCES)]; continue; } @@ -422,8 +421,6 @@ void S_Cleanup(void) voice.id = 0; voice.dist = UINT16_MAX; voice.clock = 0; - - --g_soundlocks[num]; } } @@ -444,9 +441,8 @@ int32_t S_LoadSound(int num) } int32_t l = fp.GetLength(); - g_soundlocks[num] = 200; snd.siz = l; - cacheAllocateBlock((intptr_t *)&snd.ptr, l, &g_soundlocks[num]); + cacheAllocateBlock((intptr_t *)&snd.ptr, l, nullptr); l = fp.Read(snd.ptr, l); return l; @@ -698,14 +694,11 @@ int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos) if (snd.num > 0 && PN(spriteNum) != MUSICANDSFX) S_StopEnvSound(sndNum, spriteNum); - if (++g_soundlocks[sndNum] < 200) - g_soundlocks[sndNum] = 200; int const sndSlot = S_GetSlot(sndNum); if (sndSlot >= MAXSOUNDINSTANCES) { - g_soundlocks[sndNum]--; return -1; } @@ -713,7 +706,6 @@ int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos) if (repeatp && (snd.m & SF_ONEINST_INTERNAL) && snd.num > 0) { - g_soundlocks[sndNum]--; return -1; } @@ -727,7 +719,6 @@ int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos) if (voice <= FX_Ok) { - g_soundlocks[sndNum]--; return -1; } @@ -760,14 +751,10 @@ int S_PlaySound(int num) int const pitch = S_GetPitch(num); - if (++g_soundlocks[num] < 200) - g_soundlocks[num] = 200; - sndnum = S_GetSlot(num); if (sndnum >= MAXSOUNDINSTANCES) { - g_soundlocks[num]--; return -1; } @@ -778,7 +765,6 @@ int S_PlaySound(int num) if (voice <= FX_Ok) { - g_soundlocks[num]--; return -1; } @@ -922,14 +908,6 @@ void S_Callback(intptr_t num) void S_ClearSoundLocks(void) { -#ifdef CACHING_DOESNT_SUCK - int32_t i; - int32_t const msp = g_highestSoundIdx; - - for (native_t i = 0; i <= msp; ++i) - if (g_soundlocks[i] >= 200) - g_soundlocks[i] = 199; -#endif } bool A_CheckSoundPlaying(int spriteNum, int soundNum) @@ -963,8 +941,8 @@ bool A_CheckAnySoundPlaying(int spriteNum) bool S_CheckSoundPlaying(int spriteNum, int soundNum) { - if (EDUKE32_PREDICT_FALSE((unsigned)soundNum > (unsigned)g_highestSoundIdx)) return 0; - return (spriteNum == -1) ? (g_soundlocks[soundNum] > 200) : (g_sounds[soundNum].num != 0); + if (EDUKE32_PREDICT_FALSE((unsigned)soundNum > (unsigned)g_highestSoundIdx)) return false; + return (g_sounds[soundNum].num != 0); } END_RR_NS diff --git a/source/rr/src/sounds.h b/source/rr/src/sounds.h index 7b7c80785..19f52c806 100644 --- a/source/rr/src/sounds.h +++ b/source/rr/src/sounds.h @@ -57,7 +57,6 @@ typedef struct char pr, m; // 2b } sound_t; -extern uint8_t g_soundlocks[MAXSOUNDS]; extern sound_t g_sounds[MAXSOUNDS]; extern int32_t g_skillSoundVoice; extern int32_t g_numEnvSoundsPlaying,g_highestSoundIdx; @@ -68,7 +67,7 @@ void S_Callback(intptr_t num); bool A_CheckAnySoundPlaying(int spriteNum); bool S_CheckSoundPlaying(int spriteNum,int soundNum); void S_Cleanup(void); -void S_ClearSoundLocks(void); +inline void S_ClearSoundLocks(void) {} int32_t S_LoadSound(uint32_t num); void S_PrecacheSounds(void); void S_MenuSound(void); From a59917b35df04df66ed4d9acaa820c390a211765 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 03:02:33 +0100 Subject: [PATCH 040/203] - more cleanup of sound code removed the remaining parts of the old music system in EDuke32 and RedNukem frontends. --- source/common/music/s_music.h | 2 + source/duke3d/src/game.cpp | 2 - source/duke3d/src/menus.cpp | 2 - source/duke3d/src/osdcmds.cpp | 34 ------- source/duke3d/src/sounds.cpp | 173 +--------------------------------- source/duke3d/src/sounds.h | 3 - source/rr/src/game.cpp | 2 - source/rr/src/menus.cpp | 4 - source/rr/src/osdcmds.cpp | 34 ------- source/rr/src/sounds.cpp | 157 +----------------------------- source/rr/src/sounds.h | 3 - 11 files changed, 4 insertions(+), 412 deletions(-) diff --git a/source/common/music/s_music.h b/source/common/music/s_music.h index bca472f67..f3c9a0be9 100644 --- a/source/common/music/s_music.h +++ b/source/common/music/s_music.h @@ -97,5 +97,7 @@ extern MusPlayingInfo mus_playing; extern float relative_volume, saved_relative_volume; +// Note for later when the OPL player is ported. +// DN3D and related games use "d3dtimbr.tmb" #endif diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 082385980..341c75fc7 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -5556,7 +5556,6 @@ static void G_Cleanup(void) void G_Shutdown(void) { S_SoundShutdown(); - S_MusicShutdown(); CONTROL_Shutdown(); engineUnInit(); G_Cleanup(); @@ -6174,7 +6173,6 @@ int GameInterface::app_main() videoSetPalette(0, myplayer.palette, 0); S_SoundStartup(); - S_MusicStartup(); } // check if the minifont will support lowercase letters (3136-3161) diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index 18b1a50ff..d2ff82e32 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -1760,10 +1760,8 @@ static void Menu_EntryLinkActivate(MenuEntry_t *entry) mus_device = musicdevice; S_SoundShutdown(); - S_MusicShutdown(); S_SoundStartup(); - S_MusicStartup(); FX_StopAllSounds(); S_ClearSoundLocks(); diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index 6f951cab4..718630463 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -326,10 +326,8 @@ static int osdcmd_restartsound(osdcmdptr_t UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); S_SoundShutdown(); - S_MusicShutdown(); S_SoundStartup(); - S_MusicStartup(); FX_StopAllSounds(); S_ClearSoundLocks(); @@ -340,36 +338,6 @@ static int osdcmd_restartsound(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_music(osdcmdptr_t parm) -{ - if (parm->numparms == 1) - { - int32_t sel = G_GetMusicIdx(parm->parms[0]); - - if (sel == -1) - return OSDCMD_SHOWHELP; - - if (sel == -2) - { - OSD_Printf("%s is not a valid episode/level number pair\n", parm->parms[0]); - return OSDCMD_OK; - } - - if (!S_TryPlayLevelMusic(sel)) - { - G_PrintCurrentMusic(); - } - else - { - OSD_Printf("No music defined for %s\n", parm->parms[0]); - } - - return OSDCMD_OK; - } - - return OSDCMD_SHOWHELP; -} - int osdcmd_restartmap(osdcmdptr_t UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -1012,8 +980,6 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("god","god: toggles god mode", osdcmd_god); OSD_RegisterFunction("activatecheat","activatecheat : activates a cheat code", osdcmd_activatecheat); - OSD_RegisterFunction("music","music EL: change music", osdcmd_music); - OSD_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); diff --git a/source/duke3d/src/sounds.cpp b/source/duke3d/src/sounds.cpp index e45f61297..bc5dc94e1 100644 --- a/source/duke3d/src/sounds.cpp +++ b/source/duke3d/src/sounds.cpp @@ -88,7 +88,6 @@ void S_SoundStartup(void) cacheAllSounds(); snd_fxvolume.Callback(); - S_MusicVolume(mus_volume); snd_reversestereo.Callback(); FX_SetCallBack(S_Callback); @@ -97,9 +96,6 @@ void S_SoundStartup(void) void S_SoundShutdown(void) { - if (MusicVoice >= 0) - S_MusicShutdown(); - int status = FX_Shutdown(); if (status != FX_Ok) { @@ -108,45 +104,6 @@ void S_SoundShutdown(void) } } -void S_MusicStartup(void) -{ - initprintf("Initializing MIDI driver... "); - - int status; - if ((status = MUSIC_Init(MusicDevice)) == MUSIC_Ok) - { - if (MusicDevice == ASS_AutoDetect) - MusicDevice = MIDI_GetDevice(); - } - else if ((status = MUSIC_Init(ASS_AutoDetect)) == MUSIC_Ok) - { - MusicDevice = MIDI_GetDevice(); - } - else - { - initprintf("S_MusicStartup(): failed initializing: %s\n", MUSIC_ErrorString(status)); - return; - } - - MUSIC_SetVolume(mus_volume); - auto fr = kopenFileReader("d3dtimbr.tmb", 0); - - if (fr.isOpen()) - { - auto tmb = fr.Read(); - AL_RegisterTimbreBank(tmb.Data()); - } -} - -void S_MusicShutdown(void) -{ - S_StopMusic(); - - int status = MUSIC_Shutdown(); - if (status != MUSIC_Ok) - initprintf("S_MusicShutdown(): %s\n", MUSIC_ErrorString(status)); -} - void S_PauseSounds(bool paused) { if (SoundPaused == paused) @@ -162,17 +119,9 @@ void S_PauseSounds(bool paused) } } - -void S_MusicVolume(int32_t volume) -{ - if (MusicIsWaveform && MusicVoice >= 0) - FX_SetPan(MusicVoice, volume, volume, volume); - - MUSIC_SetVolume(volume); -} - void S_RestartMusic(void) { + // Fixme: This should be completely decided by the backend, not here. if (ud.recstat != 2 && g_player[myconnectindex].ps->gm&MODE_GAME) { S_PlayLevelMusicOrNothing(g_musicIndex); @@ -196,125 +145,7 @@ void S_MenuSound(void) S_PlaySound(s); } -#if 0 // In case you desperately want the old system back... ;) -static int S_PlayMusic(const char *, const char *fn, int loop) -{ - if (!MusicEnabled()) - return 0; - if (fn == NULL) - return 1; - - auto fp = S_OpenAudio(fn, 0, 1); - if (!fp.isOpen()) - { - OSD_Printf(OSD_ERROR "S_PlayMusic(): error: can't open \"%s\" for playback!\n",fn); - return 2; - } - - int32_t MusicLen = fp.GetLength(); - - if (EDUKE32_PREDICT_FALSE(MusicLen < 4)) - { - OSD_Printf(OSD_ERROR "S_PlayMusic(): error: empty music file \"%s\"\n", fn); - return 3; - } - - char * MyMusicPtr = (char *)Xaligned_alloc(16, MusicLen); - int MyMusicSize = fp.Read(MyMusicPtr, MusicLen); - - if (EDUKE32_PREDICT_FALSE(MyMusicSize != MusicLen)) - { - OSD_Printf(OSD_ERROR "S_PlayMusic(): error: read %d bytes from \"%s\", expected %d\n", - MyMusicSize, fn, MusicLen); - ALIGNED_FREE_AND_NULL(MyMusicPtr); - return 4; - } - - if (!Bmemcmp(MyMusicPtr, "MThd", 4)) - { - int32_t retval = MUSIC_PlaySong(MyMusicPtr, MyMusicSize, MUSIC_LoopSong, fn); - - if (retval != MUSIC_Ok) - { - ALIGNED_FREE_AND_NULL(MyMusicPtr); - return 5; - } - - if (MusicIsWaveform && MusicVoice >= 0) - { - FX_StopSound(MusicVoice); - MusicVoice = -1; - } - - MusicIsWaveform = 0; - ALIGNED_FREE_AND_NULL(MusicPtr); - MusicPtr = MyMusicPtr; - g_musicSize = MyMusicSize; - } - else - { - int MyMusicVoice = FX_Play(MyMusicPtr, MusicLen, 0, 0, 0, mus_volume, mus_volume, mus_volume, - FX_MUSIC_PRIORITY, 1.f, MUSIC_ID); - - if (MyMusicVoice <= FX_Ok) - { - ALIGNED_FREE_AND_NULL(MyMusicPtr); - return 5; - } - - if (MusicIsWaveform && MusicVoice >= 0) - FX_StopSound(MusicVoice); - - MUSIC_StopSong(); - - MusicVoice = MyMusicVoice; - MusicIsWaveform = 1; - ALIGNED_FREE_AND_NULL(MusicPtr); - MusicPtr = MyMusicPtr; - g_musicSize = MyMusicSize; - } - - return 0; -} - -void S_StopMusic(void) -{ - MusicPaused = 0; - - if (MusicIsWaveform && MusicVoice >= 0) - { - FX_StopSound(MusicVoice); - MusicVoice = -1; - MusicIsWaveform = 0; - } - - MUSIC_StopSong(); - - ALIGNED_FREE_AND_NULL(MusicPtr); - g_musicSize = 0; -} - -void S_PauseMusic(bool paused) -{ - if (MusicPaused == paused || (MusicIsWaveform && MusicVoice < 0)) - return; - - MusicPaused = paused; - - if (MusicIsWaveform) - { - FX_PauseVoice(MusicVoice, paused); - return; - } - - if (paused) - MUSIC_Pause(); - else - MUSIC_Continue(); -} - -#else static int S_PlayMusic(const char *mapname, const char* fn, bool looping = true) { return Mus_Play(mapname, fn, looping); @@ -331,8 +162,6 @@ void S_PauseMusic(bool paused) } -#endif - static void S_SetMusicIndex(unsigned int m) { g_musicIndex = m; diff --git a/source/duke3d/src/sounds.h b/source/duke3d/src/sounds.h index b19471c53..1c7d51f13 100644 --- a/source/duke3d/src/sounds.h +++ b/source/duke3d/src/sounds.h @@ -70,9 +70,6 @@ inline void S_ClearSoundLocks(void) {} int32_t S_LoadSound(uint32_t num); void cacheAllSounds(void); void S_MenuSound(void); -void S_MusicShutdown(void); -void S_MusicStartup(void); -void S_MusicVolume(int32_t volume); void S_RestartMusic(void); void S_PauseMusic(bool paused); void S_PauseSounds(bool paused); diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 928497a2a..f9c4ff19a 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -7046,7 +7046,6 @@ static void G_Cleanup(void) void G_Shutdown(void) { S_SoundShutdown(); - S_MusicShutdown(); CONTROL_Shutdown(); G_SetFog(0); engineUnInit(); @@ -7708,7 +7707,6 @@ int GameInterface::app_main() } videoSetPalette(0, g_player[myconnectindex].ps->palette, 0); - S_MusicStartup(); S_SoundStartup(); } diff --git a/source/rr/src/menus.cpp b/source/rr/src/menus.cpp index 34dcd480a..11fb58d3b 100644 --- a/source/rr/src/menus.cpp +++ b/source/rr/src/menus.cpp @@ -3434,9 +3434,7 @@ static void Menu_EntryLinkActivate(MenuEntry_t *entry) snd_numvoices = soundvoices; S_SoundShutdown(); - S_MusicShutdown(); - S_MusicStartup(); S_SoundStartup(); FX_StopAllSounds(); @@ -3623,8 +3621,6 @@ static int32_t Menu_EntryRangeInt32Modify(MenuEntry_t *entry, int32_t newValue) G_SetStatusBarScale(newValue); else if (entry == &ME_SOUND_VOLUME_FX) FX_SetVolume(newValue); - else if (entry == &ME_SOUND_VOLUME_MUSIC) - S_MusicVolume(newValue); else if (entry == &ME_JOYSTICKAXIS_SCALE) CONTROL_SetAnalogAxisScale(M_JOYSTICKAXES.currentEntry, newValue, controldevice_joystick); else if (entry == &ME_JOYSTICKAXIS_DEAD) diff --git a/source/rr/src/osdcmds.cpp b/source/rr/src/osdcmds.cpp index 0c1f02cb9..7448738c0 100644 --- a/source/rr/src/osdcmds.cpp +++ b/source/rr/src/osdcmds.cpp @@ -323,9 +323,7 @@ static int osdcmd_restartsound(osdcmdptr_t UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); S_SoundShutdown(); - S_MusicShutdown(); - S_MusicStartup(); S_SoundStartup(); FX_StopAllSounds(); @@ -337,36 +335,6 @@ static int osdcmd_restartsound(osdcmdptr_t UNUSED(parm)) return OSDCMD_OK; } -static int osdcmd_music(osdcmdptr_t parm) -{ - if (parm->numparms == 1) - { - int32_t sel = G_GetMusicIdx(parm->parms[0]); - - if (sel == -1) - return OSDCMD_SHOWHELP; - - if (sel == -2) - { - OSD_Printf("%s is not a valid episode/level number pair\n", parm->parms[0]); - return OSDCMD_OK; - } - - if (!S_TryPlayLevelMusic(sel)) - { - G_PrintCurrentMusic(); - } - else - { - OSD_Printf("No music defined for %s\n", parm->parms[0]); - } - - return OSDCMD_OK; - } - - return OSDCMD_SHOWHELP; -} - int osdcmd_restartmap(osdcmdptr_t UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); @@ -864,8 +832,6 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("listplayers","listplayers: lists currently connected multiplayer clients", osdcmd_listplayers); #endif - OSD_RegisterFunction("music","music EL: change music", osdcmd_music); - OSD_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); #if !defined NETCODE_DISABLE diff --git a/source/rr/src/sounds.cpp b/source/rr/src/sounds.cpp index 9b11fe2d9..292a96fc0 100644 --- a/source/rr/src/sounds.cpp +++ b/source/rr/src/sounds.cpp @@ -77,7 +77,6 @@ void S_SoundStartup(void) S_PrecacheSounds(); snd_fxvolume.Callback(); - S_MusicVolume(mus_volume); snd_reversestereo.Callback(); FX_SetCallBack(S_Callback); @@ -86,9 +85,6 @@ void S_SoundStartup(void) void S_SoundShutdown(void) { - if (MusicVoice >= 0) - S_MusicShutdown(); - if (FX_Shutdown() != FX_Ok) { Bsprintf(tempbuf, "S_SoundShutdown(): error: %s", FX_ErrorString(FX_Error)); @@ -96,26 +92,7 @@ void S_SoundShutdown(void) } } -void S_MusicStartup(void) -{ - initprintf("Initializing music...\n"); - if (MUSIC_Init(MusicDevice) == MUSIC_Ok) - { - MUSIC_SetVolume(mus_volume); - return; - } - - initprintf("S_MusicStartup(): failed initializing\n"); -} - -void S_MusicShutdown(void) -{ - S_StopMusic(); - - if (MUSIC_Shutdown() != MUSIC_Ok) - initprintf("%s\n", MUSIC_ErrorString(MUSIC_ErrorCode)); -} void S_PauseSounds(bool paused) { if (SoundPaused == paused) @@ -131,18 +108,9 @@ void S_PauseSounds(bool paused) } } - - -void S_MusicVolume(int32_t volume) -{ - if (MusicIsWaveform && MusicVoice >= 0) - FX_SetPan(MusicVoice, volume, volume, volume); - - MUSIC_SetVolume(volume); -} - void S_RestartMusic(void) { + // Fixme: This should be completely decided by the backend, not here. if (ud.recstat != 2 && g_player[myconnectindex].ps->gm&MODE_GAME) { S_PlayLevelMusicOrNothing(g_musicIndex); @@ -166,128 +134,7 @@ void S_MenuSound(void) S_PlaySound(s); } -#if 0 // In case you desperately want the old system back... ;) -static int S_PlayMusic(const char *, const char *fn, int loop) -{ - if (!MusicEnabled()) - return 0; - if (fn == NULL) - return 1; - - auto fp = S_OpenAudio(fn, 0, 1); - if (!fp.isOpen()) - { - OSD_Printf(OSD_ERROR "S_PlayMusic(): error: can't open \"%s\" for playback!\n",fn); - return 2; - } - - int32_t MusicLen = fp.GetLength(); - - if (EDUKE32_PREDICT_FALSE(MusicLen < 4)) - { - OSD_Printf(OSD_ERROR "S_PlayMusic(): error: empty music file \"%s\"\n", fn); - return 3; - } - - char * MyMusicPtr = (char *)Xaligned_alloc(16, MusicLen); - int MyMusicSize = fp.Read(MyMusicPtr, MusicLen); - - if (EDUKE32_PREDICT_FALSE(MyMusicSize != MusicLen)) - { - OSD_Printf(OSD_ERROR "S_PlayMusic(): error: read %d bytes from \"%s\", expected %d\n", - MyMusicSize, fn, MusicLen); - ALIGNED_FREE_AND_NULL(MyMusicPtr); - return 4; - } - - if (!Bmemcmp(MyMusicPtr, "MThd", 4)) - { - int32_t retval = MUSIC_PlaySong(MyMusicPtr, MyMusicSize, loop); - - if (retval != MUSIC_Ok) - { - ALIGNED_FREE_AND_NULL(MyMusicPtr); - return 5; - } - - if (MusicIsWaveform && MusicVoice >= 0) - { - FX_StopSound(MusicVoice); - MusicVoice = -1; - } - - MusicIsWaveform = 0; - ALIGNED_FREE_AND_NULL(MusicPtr); - MusicPtr = MyMusicPtr; - g_musicSize = MyMusicSize; - } - else - { - int MyMusicVoice = FX_Play(MyMusicPtr, MusicLen, 0, 0, 0, mus_volume, mus_volume, mus_volume, - FX_MUSIC_PRIORITY, 1.f, MUSIC_ID); - - if (MyMusicVoice <= FX_Ok) - { - ALIGNED_FREE_AND_NULL(MyMusicPtr); - return 5; - } - - if (MusicIsWaveform && MusicVoice >= 0) - FX_StopSound(MusicVoice); - - MUSIC_StopSong(); - - MusicVoice = MyMusicVoice; - MusicIsWaveform = 1; - ALIGNED_FREE_AND_NULL(MusicPtr); - MusicPtr = MyMusicPtr; - g_musicSize = MyMusicSize; - } - - return 0; -} - - -void S_StopMusic(void) -{ - MusicPaused = 0; - - if (MusicIsWaveform && MusicVoice >= 0) - { - FX_StopSound(MusicVoice); - MusicVoice = -1; - MusicIsWaveform = 0; - } - - MUSIC_StopSong(); - - ALIGNED_FREE_AND_NULL(MusicPtr); - g_musicSize = 0; -} - -void S_PauseMusic(bool paused) -{ - if (MusicPaused == paused || (MusicIsWaveform && MusicVoice < 0)) - return; - - MusicPaused = paused; - - if (MusicIsWaveform) - { - FX_PauseVoice(MusicVoice, paused); - return; - } - - if (paused) - MUSIC_Pause(); - else - MUSIC_Continue(); -} - - - -#else static int S_PlayMusic(const char *mapname, const char* fn, bool looping = true) { return Mus_Play(mapname, fn, looping); @@ -304,8 +151,6 @@ void S_PauseMusic(bool paused) Mus_SetPaused(paused); } -#endif - static void S_SetMusicIndex(unsigned int m) { diff --git a/source/rr/src/sounds.h b/source/rr/src/sounds.h index 19f52c806..32809074b 100644 --- a/source/rr/src/sounds.h +++ b/source/rr/src/sounds.h @@ -71,9 +71,6 @@ inline void S_ClearSoundLocks(void) {} int32_t S_LoadSound(uint32_t num); void S_PrecacheSounds(void); void S_MenuSound(void); -void S_MusicShutdown(void); -void S_MusicStartup(void); -void S_MusicVolume(int32_t volume); void S_RestartMusic(void); void S_PauseMusic(bool paused); void S_PauseSounds(bool paused); From 324056ad8896dd8ee26d400080e43529e872c500 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 03:18:58 +0100 Subject: [PATCH 041/203] - more cleanup on music code * removed some redundant functionality (e.g. Shift-F5 to change - use the console for that!) * removed a few more leftover parts of the old music system * savegames should not do more than resuming the music at the point of saving. (DN3D and RR only so far. Blood to be done.) * handle music enabling/disabling in the backend, which simply knows better what to do. This was only working in the menu, so changing the CVAR had no effect. --- source/blood/src/menu.cpp | 10 ---- source/common/gamecontrol.h | 2 +- source/common/gamecvars.cpp | 1 - source/common/music/i_music.cpp | 6 +++ source/common/music/music.cpp | 74 ++++++++++++++++++++++++++-- source/common/music/s_music.h | 4 ++ source/common/music/z_music.h | 1 + source/common/savegamehelp.cpp | 5 ++ source/duke3d/src/game.cpp | 39 --------------- source/duke3d/src/game.h | 5 -- source/duke3d/src/gamestructures.cpp | 2 +- source/duke3d/src/menus.cpp | 4 -- source/duke3d/src/osdcmds.cpp | 3 -- source/duke3d/src/savegame.cpp | 24 ++------- source/duke3d/src/sounds.cpp | 13 ----- source/duke3d/src/sounds.h | 1 - source/rr/src/game.cpp | 24 --------- source/rr/src/game.h | 1 - source/rr/src/menus.cpp | 4 -- source/rr/src/osdcmds.cpp | 3 -- source/rr/src/savegame.cpp | 17 +------ source/rr/src/sounds.cpp | 13 ----- source/rr/src/sounds.h | 1 - source/sw/src/sounds.cpp | 1 - 24 files changed, 93 insertions(+), 165 deletions(-) diff --git a/source/blood/src/menu.cpp b/source/blood/src/menu.cpp index bd74f2ca7..1967628d1 100644 --- a/source/blood/src/menu.cpp +++ b/source/blood/src/menu.cpp @@ -1790,13 +1790,6 @@ void UpdateSoundToggle(CGameMenuItemZBool *pItem) void UpdateMusicToggle(CGameMenuItemZBool *pItem) { mus_enabled = pItem->at20; - if (!MusicEnabled()) - sndStopSong(); - else - { - if (gGameStarted || gDemo.at1) - sndPlaySong("*", gGameOptions.zLevelSong, true); - } } void Update3DToggle(CGameMenuItemZBool *pItem) @@ -1847,9 +1840,6 @@ void SetSound(CGameMenuItemChain *pItem) sndInit(); sfxInit(); - - if (mus_enabled && (gGameStarted || gDemo.at1)) - sndPlaySong("*", gGameOptions.zLevelSong, true); } void PreDrawSound(CGameMenuItem *pItem) diff --git a/source/common/gamecontrol.h b/source/common/gamecontrol.h index 876c82d54..4ef9187cd 100644 --- a/source/common/gamecontrol.h +++ b/source/common/gamecontrol.h @@ -100,7 +100,7 @@ extern UserConfig userConfig; inline bool MusicEnabled() { - return mus_enabled && !userConfig.nomusic; + return !userConfig.nomusic; } inline bool SoundEnabled() diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index 181c55b7a..09621fe34 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -129,7 +129,6 @@ CVARD(Bool, snd_enabled, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enables/disables CVARD(Bool, snd_tryformats, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enables/disables automatic discovery of replacement sounds and music in .flac and .ogg formats") CVARD(Bool, snd_doppler, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enable/disable 3d sound") -CVARD(Bool, mus_enabled, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enables/disables music") CVARD(Bool, mus_restartonload, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "restart the music when loading a saved game with the same map or not") // only implemented for Blood - todo: generalize CVARD(Bool, mus_redbook, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_FRONTEND_BLOOD, "enables/disables redbook audio (Blood only!)") // only Blood has assets for this. diff --git a/source/common/music/i_music.cpp b/source/common/music/i_music.cpp index 5cdd9b3c2..7ed6940d0 100644 --- a/source/common/music/i_music.cpp +++ b/source/common/music/i_music.cpp @@ -140,6 +140,12 @@ CUSTOM_CVARD(Int, mus_volume, 255, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "controls mus } } +CUSTOM_CVARD(Bool, mus_enabled, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enables/disables music") +{ + if (self) S_RestartMusic(); + else S_StopMusic(true); +} + //========================================================================== // // Callbacks for the music system. diff --git a/source/common/music/music.cpp b/source/common/music/music.cpp index d521ff13e..95f77c270 100644 --- a/source/common/music/music.cpp +++ b/source/common/music/music.cpp @@ -68,6 +68,8 @@ #include "c_dispatch.h" #include "gamecontrol.h" #include "filereadermusicinterface.h" +#include "savegamehelp.h" +#include "sjson.h" MusPlayingInfo mus_playing; MusicAliasMap MusicAliases; @@ -75,6 +77,7 @@ MidiDeviceMap MidiDevices; MusicVolumeMap MusicVolumes; MusicAliasMap LevelMusicAliases; bool MusicPaused; +static bool mus_blocked; //========================================================================== // // @@ -190,6 +193,7 @@ void S_ResumeMusic () void S_UpdateMusic () { + mus_blocked = false; if (mus_playing.handle != nullptr) { ZMusic_Update(mus_playing.handle); @@ -360,8 +364,8 @@ bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force) // shutdown old music S_StopMusic (true); - // Just record it if volume is 0 - if (mus_volume <= 0) + // Just record it if volume is 0 or music was disabled + if (mus_volume <= 0 || !mus_enabled) { mus_playing.loop = looping; mus_playing.name = musicname; @@ -416,12 +420,11 @@ bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force) // // S_RestartMusic // -// Must only be called from snd_reset in i_sound.cpp! //========================================================================== void S_RestartMusic () { - if (!mus_playing.LastSong.IsEmpty()) + if (!mus_playing.LastSong.IsEmpty() && mus_volume > 0 && mus_enabled) { FString song = mus_playing.LastSong; mus_playing.LastSong = ""; @@ -557,6 +560,7 @@ CCMD (stopmus) static FString lastMusicLevel, lastMusic; int Mus_Play(const char *mapname, const char *fn, bool loop) { + if (mus_blocked) return 0; // Store the requested names for resuming. lastMusicLevel = mapname; lastMusic = fn; @@ -588,6 +592,7 @@ int Mus_Play(const char *mapname, const char *fn, bool loop) void Mus_Stop() { + if (mus_blocked) return; S_StopMusic(true); } @@ -597,3 +602,64 @@ void Mus_SetPaused(bool on) else S_ResumeMusic(); } +void MUS_Save() +{ + FString music = mus_playing.name; + if (music.IsEmpty()) music = mus_playing.LastSong; + + sjson_context* ctx = sjson_create_context(0, 0, NULL); + if (!ctx) + { + return; + } + sjson_node* root = sjson_mkobject(ctx); + sjson_put_string(ctx, root, "music", music); + sjson_put_int(ctx, root, "baseorder", mus_playing.baseorder); + sjson_put_bool(ctx, root, "loop", mus_playing.loop); + + char* encoded = sjson_stringify(ctx, root, " "); + + FileWriter* fil = WriteSavegameChunk("music.json"); + if (!fil) + { + sjson_destroy_context(ctx); + return; + } + + fil->Write(encoded, strlen(encoded)); + + sjson_free_string(ctx, encoded); + sjson_destroy_context(ctx); +} + +bool MUS_Restore() +{ + auto fil = ReadSavegameChunk("music.json"); + if (!fil.isOpen()) + { + return false; + } + + auto text = fil.ReadPadded(1); + fil.Close(); + + if (text.Size() == 0) + { + return false; + } + + sjson_context* ctx = sjson_create_context(0, 0, NULL); + sjson_node* root = sjson_decode(ctx, (const char*)text.Data()); + mus_playing.LastSong = sjson_get_string(root, "music", ""); + mus_playing.baseorder = sjson_get_int(root, "baseorder", 0); + mus_playing.loop = sjson_get_bool(root, "loop", true); + sjson_destroy_context(ctx); + mus_blocked = true; // this is to prevent scripts from resetting the music after it has been loaded from the savegame. + + return true; +} + +void MUS_ResumeSaved() +{ + S_RestartMusic(); +} diff --git a/source/common/music/s_music.h b/source/common/music/s_music.h index f3c9a0be9..96f9eb16a 100644 --- a/source/common/music/s_music.h +++ b/source/common/music/s_music.h @@ -97,7 +97,11 @@ extern MusPlayingInfo mus_playing; extern float relative_volume, saved_relative_volume; +void MUS_Save(); +bool MUS_Restore(); + // Note for later when the OPL player is ported. // DN3D and related games use "d3dtimbr.tmb" + #endif diff --git a/source/common/music/z_music.h b/source/common/music/z_music.h index 754aca1dd..026ff5c30 100644 --- a/source/common/music/z_music.h +++ b/source/common/music/z_music.h @@ -6,3 +6,4 @@ void Mus_Init(); int Mus_Play(const char *mapname, const char *fn, bool loop); void Mus_Stop(); void Mus_SetPaused(bool on); +void MUS_ResumeSaved(); diff --git a/source/common/savegamehelp.cpp b/source/common/savegamehelp.cpp index 57602da34..c16ede5ef 100644 --- a/source/common/savegamehelp.cpp +++ b/source/common/savegamehelp.cpp @@ -43,6 +43,7 @@ #include "filesystem/filesystem.h" #include "statistics.h" #include "secrets.h" +#include "s_music.h" static CompositeSavegameWriter savewriter; static FResourceFile *savereader; @@ -74,8 +75,10 @@ bool OpenSaveGameForRead(const char *name) if (savereader != nullptr) { + // Load system-side data from savegames. ReadStatistics(); SECRET_Load(); + MUS_Restore(); } return savereader != nullptr; @@ -142,8 +145,10 @@ void G_WriteSaveHeader(const char *name, const char*mapname, const char *maptitl sjson_free_string(ctx, encoded); sjson_destroy_context(ctx); + // Handle system-side modules that need to persist data in savegames here, in a central place. SaveStatistics(); SECRET_Save(); + MUS_Save(); } //============================================================================= diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 341c75fc7..6430fb3d3 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -4411,11 +4411,6 @@ extern int G_StartRTS(int lumpNum, int localPlayer) return 0; } -void G_PrintCurrentMusic(void) -{ - Bsnprintf(apStrings[QUOTE_MUSIC], MAXQUOTELEN, "Playing %s", g_mapInfo[g_musicIndex].musicfn); - P_DoQuote(QUOTE_MUSIC, g_player[myconnectindex].ps); -} // Trying to sanitize the mess of options and the mess of variables the mess was stored in. (Did I say this was a total mess before...? >) ) // Hopefully this is more comprehensible, at least it neatly stores everything useful in a single linear value... @@ -4662,25 +4657,6 @@ void G_HandleLocalKeys(void) { if (SHIFTS_IS_PRESSED) { - if (ridiculeNum == 5 && myplayer.fta > 0 && myplayer.ftq == QUOTE_MUSIC) - { - const unsigned int maxi = VOLUMEALL ? MUS_FIRST_SPECIAL : 6; - - unsigned int const oldMusicIndex = g_musicIndex; - unsigned int MyMusicIndex = g_musicIndex; - do - { - ++MyMusicIndex; - if (MyMusicIndex >= maxi) - MyMusicIndex = 0; - } - while (S_TryPlayLevelMusic(MyMusicIndex) && MyMusicIndex != oldMusicIndex); - - G_PrintCurrentMusic(); - - return; - } - G_AddUserQuote(*CombatMacros[ridiculeNum-1]); Net_SendTaunt(ridiculeNum); @@ -4712,21 +4688,6 @@ void G_HandleLocalKeys(void) typebuf[0] = 0; } - if (inputState.UnboundKeyPressed(sc_F5) && MusicEnabled()) - { - map_t *const pMapInfo = &g_mapInfo[g_musicIndex]; - char *const musicString = apStrings[QUOTE_MUSIC]; - - inputState.ClearKeyStatus(sc_F5); - - if (pMapInfo->musicfn != NULL) - Bsnprintf(musicString, MAXQUOTELEN, "%s. Use SHIFT-F5 to change.", pMapInfo->musicfn); - else - musicString[0] = '\0'; - - P_DoQuote(QUOTE_MUSIC, g_player[myconnectindex].ps); - } - if ((buttonMap.ButtonDown(gamefunc_Quick_Save) || g_doQuickSave == 1) && (myplayer.gm & MODE_GAME)) { buttonMap.ClearButton(gamefunc_Quick_Save); diff --git a/source/duke3d/src/game.h b/source/duke3d/src/game.h index f9a7903fe..85964c43f 100644 --- a/source/duke3d/src/game.h +++ b/source/duke3d/src/game.h @@ -481,11 +481,6 @@ static inline int G_GetViewscreenSizeShift(uspriteptr_t const spr) #endif } -extern void G_PrintCurrentMusic(void); - -#ifdef LUNATIC -void El_SetCON(const char *conluacode); -#endif EXTERN_INLINE_HEADER void G_SetStatusBarScale(int32_t sc); diff --git a/source/duke3d/src/gamestructures.cpp b/source/duke3d/src/gamestructures.cpp index 291878e69..2915ba5ad 100644 --- a/source/duke3d/src/gamestructures.cpp +++ b/source/duke3d/src/gamestructures.cpp @@ -1531,7 +1531,7 @@ int32_t __fastcall VM_GetUserdef(int32_t labelNum, int const lParm2) case USERDEFS_MENUTITLE_PAL: labelNum = ud.menutitle_pal; break; case USERDEFS_SLIDEBAR_PALSELECTED: labelNum = ud.slidebar_palselected; break; case USERDEFS_SLIDEBAR_PALDISABLED: labelNum = ud.slidebar_paldisabled; break; - case USERDEFS_MUSIC_EPISODE: labelNum = ud.music_episode; break; + case USERDEFS_MUSIC_EPISODE: labelNum = ud.music_episode; break; // Problem: This info is utterly meaningless with the new music system. case USERDEFS_MUSIC_LEVEL: labelNum = ud.music_level; break; case USERDEFS_SHADOW_PAL: labelNum = ud.shadow_pal; break; case USERDEFS_MENU_SCROLLBARTILENUM: labelNum = ud.menu_scrollbartilenum; break; diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index d2ff82e32..f5ab60a2c 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -1765,9 +1765,6 @@ static void Menu_EntryLinkActivate(MenuEntry_t *entry) FX_StopAllSounds(); S_ClearSoundLocks(); - - if (MusicEnabled()) - S_RestartMusic(); } else if (entry == &ME_SAVESETUP_CLEANUP) { @@ -1831,7 +1828,6 @@ static int32_t Menu_EntryOptionModify(MenuEntry_t *entry, int32_t newOption) S_PauseMusic(true); else { - S_RestartMusic(); S_PauseMusic(false); } } diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index 718630463..b2b8379e1 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -332,9 +332,6 @@ static int osdcmd_restartsound(osdcmdptr_t UNUSED(parm)) FX_StopAllSounds(); S_ClearSoundLocks(); - if (MusicEnabled()) - S_RestartMusic(); - return OSDCMD_OK; } diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index a845019c9..2d1f800e3 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "version.h" #include "savegamehelp.h" #include "menu/menu.h" +#include "z_music.h" BEGIN_DUKE_NS @@ -2110,29 +2111,10 @@ static void postloadplayer(int32_t savegamep) //2.5 if (savegamep) { - int32_t musicIdx = (ud.music_episode*MAXLEVELS) + ud.music_level; - - Bmemset(gotpic, 0, sizeof(gotpic)); + Bmemset(gotpic, 0, sizeof(gotpic)); S_ClearSoundLocks(); G_CacheMapData(); - - if (boardfilename[0] != 0 && ud.level_number == 7 && ud.volume_number == 0 && ud.music_level == USERMAPMUSICFAKELEVEL && ud.music_episode == USERMAPMUSICFAKEVOLUME) - { - char levname[BMAX_PATH]; - G_SetupFilenameBasedMusic(levname, boardfilename); - } - - if (g_mapInfo[musicIdx].musicfn != NULL && (musicIdx != g_musicIndex || different_user_map)) - { - ud.music_episode = g_musicIndex / MAXLEVELS; - ud.music_level = g_musicIndex % MAXLEVELS; - S_PlayLevelMusicOrNothing(musicIdx); - } - else - S_ContinueLevelMusic(); - - if (MusicEnabled()) - S_PauseMusic(false); + MUS_ResumeSaved(); g_player[myconnectindex].ps->gm = MODE_GAME; ud.recstat = 0; diff --git a/source/duke3d/src/sounds.cpp b/source/duke3d/src/sounds.cpp index bc5dc94e1..36b8bb241 100644 --- a/source/duke3d/src/sounds.cpp +++ b/source/duke3d/src/sounds.cpp @@ -119,19 +119,6 @@ void S_PauseSounds(bool paused) } } -void S_RestartMusic(void) -{ - // Fixme: This should be completely decided by the backend, not here. - if (ud.recstat != 2 && g_player[myconnectindex].ps->gm&MODE_GAME) - { - S_PlayLevelMusicOrNothing(g_musicIndex); - } - else if (G_GetLogoFlags() & LOGO_PLAYMUSIC) - { - S_PlaySpecialMusicOrNothing(MUS_INTRO); - } -} - void S_MenuSound(void) { static int SoundNum; diff --git a/source/duke3d/src/sounds.h b/source/duke3d/src/sounds.h index 1c7d51f13..405a4c4b1 100644 --- a/source/duke3d/src/sounds.h +++ b/source/duke3d/src/sounds.h @@ -70,7 +70,6 @@ inline void S_ClearSoundLocks(void) {} int32_t S_LoadSound(uint32_t num); void cacheAllSounds(void); void S_MenuSound(void); -void S_RestartMusic(void); void S_PauseMusic(bool paused); void S_PauseSounds(bool paused); bool S_TryPlayLevelMusic(unsigned int m); diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index f9c4ff19a..6bcd72953 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -5956,12 +5956,6 @@ extern int G_StartRTS(int lumpNum, int localPlayer) return 0; } -void G_PrintCurrentMusic(void) -{ - Bsnprintf(apStrings[QUOTE_MUSIC], MAXQUOTELEN, "Playing %s", g_mapInfo[g_musicIndex].musicfn); - P_DoQuote(QUOTE_MUSIC, g_player[myconnectindex].ps); -} - // Trying to sanitize the mess of options and the mess of variables the mess was stored in. (Did I say this was a total mess before...? >) ) // Hopefully this is more comprehensible, at least it neatly stores everything useful in a single linear value... bool GameInterface::validate_hud(int layout) @@ -6206,24 +6200,6 @@ void G_HandleLocalKeys(void) { if (SHIFTS_IS_PRESSED) { - if (ridiculeNum == 5 && g_player[myconnectindex].ps->fta > 0 && g_player[myconnectindex].ps->ftq == QUOTE_MUSIC) - { - const unsigned int maxi = VOLUMEALL ? MUS_FIRST_SPECIAL : 6; - - unsigned int MyMusicIndex = g_musicIndex; - do - { - ++MyMusicIndex; - if (MyMusicIndex >= maxi) - MyMusicIndex = 0; - } - while (S_TryPlayLevelMusic(MyMusicIndex)); - - G_PrintCurrentMusic(); - - return; - } - G_AddUserQuote(*CombatMacros[ridiculeNum-1]); Net_SendTaunt(ridiculeNum); pus = NUMPAGES; diff --git a/source/rr/src/game.h b/source/rr/src/game.h index 5193a8a43..b3791e105 100644 --- a/source/rr/src/game.h +++ b/source/rr/src/game.h @@ -474,7 +474,6 @@ static inline int G_GetViewscreenSizeShift(const uspritetype *tspr) #endif } -extern void G_PrintCurrentMusic(void); EXTERN_INLINE_HEADER void G_SetStatusBarScale(int32_t sc); diff --git a/source/rr/src/menus.cpp b/source/rr/src/menus.cpp index 11fb58d3b..5b219ad29 100644 --- a/source/rr/src/menus.cpp +++ b/source/rr/src/menus.cpp @@ -3439,9 +3439,6 @@ static void Menu_EntryLinkActivate(MenuEntry_t *entry) FX_StopAllSounds(); S_ClearSoundLocks(); - - if (MusicEnabled()) - S_RestartMusic(); } else if (entry == &ME_SAVESETUP_CLEANUP) { @@ -3517,7 +3514,6 @@ static int32_t Menu_EntryOptionModify(MenuEntry_t *entry, int32_t newOption) S_PauseMusic(true); else { - S_RestartMusic(); S_PauseMusic(false); } } diff --git a/source/rr/src/osdcmds.cpp b/source/rr/src/osdcmds.cpp index 7448738c0..17ca7d68c 100644 --- a/source/rr/src/osdcmds.cpp +++ b/source/rr/src/osdcmds.cpp @@ -329,9 +329,6 @@ static int osdcmd_restartsound(osdcmdptr_t UNUSED(parm)) FX_StopAllSounds(); S_ClearSoundLocks(); - if (MusicEnabled()) - S_RestartMusic(); - return OSDCMD_OK; } diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index 3b35aac73..2edc5e336 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "i_specialpaths.h" #include "gamecontrol.h" #include "version.h" +#include "z_music.h" #include "savegamehelp.h" BEGIN_RR_NS @@ -1687,24 +1688,10 @@ static void postloadplayer(int32_t savegamep) //2.5 if (savegamep) { - int32_t musicIdx = (ud.music_episode*MAXLEVELS) + ud.music_level; - Bmemset(gotpic, 0, sizeof(gotpic)); S_ClearSoundLocks(); G_CacheMapData(); - - if (boardfilename[0] != 0 && ud.level_number == 7 && ud.volume_number == 0 && ud.music_level == 7 && ud.music_episode == 0) - { - char levname[BMAX_PATH]; - G_SetupFilenameBasedMusic(levname, boardfilename, ud.level_number); - } - - if (g_mapInfo[musicIdx].musicfn != NULL && (musicIdx != g_musicIndex || different_user_map)) - { - ud.music_episode = g_musicIndex / MAXLEVELS; - ud.music_level = g_musicIndex % MAXLEVELS; - S_PlayLevelMusicOrNothing(musicIdx); - } + MUS_ResumeSaved(); if (MusicEnabled()) S_PauseMusic(false); diff --git a/source/rr/src/sounds.cpp b/source/rr/src/sounds.cpp index 292a96fc0..17d9b265d 100644 --- a/source/rr/src/sounds.cpp +++ b/source/rr/src/sounds.cpp @@ -108,19 +108,6 @@ void S_PauseSounds(bool paused) } } -void S_RestartMusic(void) -{ - // Fixme: This should be completely decided by the backend, not here. - if (ud.recstat != 2 && g_player[myconnectindex].ps->gm&MODE_GAME) - { - S_PlayLevelMusicOrNothing(g_musicIndex); - } - else - { - S_PlaySpecialMusicOrNothing(MUS_INTRO); - } -} - void S_MenuSound(void) { static int SoundNum; diff --git a/source/rr/src/sounds.h b/source/rr/src/sounds.h index 32809074b..33b5b6082 100644 --- a/source/rr/src/sounds.h +++ b/source/rr/src/sounds.h @@ -71,7 +71,6 @@ inline void S_ClearSoundLocks(void) {} int32_t S_LoadSound(uint32_t num); void S_PrecacheSounds(void); void S_MenuSound(void); -void S_RestartMusic(void); void S_PauseMusic(bool paused); void S_PauseSounds(bool paused); void S_PlayRRMusic(int newTrack = -1); diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp index 284d30b77..c0351c20a 100644 --- a/source/sw/src/sounds.cpp +++ b/source/sw/src/sounds.cpp @@ -1189,7 +1189,6 @@ void MusicStartup(void) else { buildprintf("Music error: %s\n", MUSIC_ErrorString(status)); - mus_enabled = FALSE; return; } From cd4ff922663470e7af045678456a194a7f02fabb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 03:32:02 +0100 Subject: [PATCH 042/203] - handle Blood. --- source/blood/src/blood.cpp | 6 ----- source/blood/src/blood.h | 2 -- source/blood/src/config.cpp | 1 - source/blood/src/loadsave.cpp | 10 ++------- source/blood/src/osdcmd.cpp | 41 ----------------------------------- source/common/music/music.cpp | 2 ++ 6 files changed, 4 insertions(+), 58 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 7369bf5c2..44cc1c255 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -97,8 +97,6 @@ char bAddUserMap = false; bool bNoDemo = false; bool bQuickStart = true; -int gMusicPrevLoadedEpisode = -1; -int gMusicPrevLoadedLevel = -1; char gUserMapFilename[BMAX_PATH]; @@ -387,8 +385,6 @@ void PreloadCache(void) if (gDemo.at1) return; PrecacheSounds(); - if (mus_restartonload) - sndTryPlaySpecialMusic(MUS_LOADING); PreloadTiles(); ClockTicks clock = totalclock; int cnt = 0; @@ -485,8 +481,6 @@ void StartLevel(GAMEOPTIONS *gameOptions) EndLevel(); gStartNewGame = 0; ready2send = 0; - gMusicPrevLoadedEpisode = gGameOptions.nEpisode; - gMusicPrevLoadedLevel = gGameOptions.nLevel; if (gDemo.at0 && gGameStarted) gDemo.Close(); netWaitForEveryone(0); diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index 71de1cbc5..39d4dd700 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -60,8 +60,6 @@ extern bool gRestartGame; extern double g_gameUpdateTime, g_gameUpdateAndDrawTime; extern double g_gameUpdateAvgTime; extern int blood_globalflags; -extern int gMusicPrevLoadedEpisode; -extern int gMusicPrevLoadedLevel; extern int gSaveGameNum; extern bool gPaused; diff --git a/source/blood/src/config.cpp b/source/blood/src/config.cpp index 32fb9e2bb..d0e9b7b45 100644 --- a/source/blood/src/config.cpp +++ b/source/blood/src/config.cpp @@ -50,7 +50,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS -int32_t mus_restartonload; int32_t gTurnSpeed; int32_t gDetail; int32_t cl_weaponswitch; diff --git a/source/blood/src/loadsave.cpp b/source/blood/src/loadsave.cpp index 0c0ab264c..1e9c231a3 100644 --- a/source/blood/src/loadsave.cpp +++ b/source/blood/src/loadsave.cpp @@ -47,6 +47,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "i_specialpaths.h" #include "view.h" #include "savegamehelp.h" +#include "z_music.h" BEGIN_BLD_NS @@ -177,14 +178,7 @@ void LoadSave::LoadGame(const char *pzFile) gGameStarted = 1; bVanilla = false; - if (mus_restartonload - || demoWasPlayed - || (gMusicPrevLoadedEpisode != gGameOptions.nEpisode || gMusicPrevLoadedLevel != gGameOptions.nLevel)) - { - levelTryPlayMusic(gGameOptions.nEpisode, gGameOptions.nLevel); - } - gMusicPrevLoadedEpisode = gGameOptions.nEpisode; - gMusicPrevLoadedLevel = gGameOptions.nLevel; + MUS_ResumeSaved(); netBroadcastPlayerInfo(myconnectindex); //sndPlaySong(gGameOptions.zLevelSong, 1); diff --git a/source/blood/src/osdcmd.cpp b/source/blood/src/osdcmd.cpp index d8028716a..8b53f0c6b 100644 --- a/source/blood/src/osdcmd.cpp +++ b/source/blood/src/osdcmd.cpp @@ -153,43 +153,6 @@ static int osdcmd_demo(osdcmdptr_t parm) return OSDCMD_OK; } -static int osdcmd_music(osdcmdptr_t parm) -{ - char buffer[128]; - if (parm->numparms == 1) - { - int32_t sel = levelGetMusicIdx(parm->parms[0]); - - if (sel == -1) - return OSDCMD_SHOWHELP; - - if (sel == -2) - { - OSD_Printf("%s is not a valid episode/level number pair\n", parm->parms[0]); - return OSDCMD_OK; - } - - int nEpisode = sel/kMaxLevels; - int nLevel = sel%kMaxLevels; - - if (!levelTryPlayMusic(nEpisode, nLevel)) - { - if (mus_redbook) - snprintf(buffer, sizeof(buffer), "Playing %i track", gEpisodeInfo[nEpisode].at28[nLevel].ate0); - else - snprintf(buffer, sizeof(buffer), "Playing %s", gEpisodeInfo[nEpisode].at28[nLevel].atd0); - viewSetMessage(buffer); - } - else - { - OSD_Printf("No music defined for %s\n", parm->parms[0]); - } - - return OSDCMD_OK; - } - - return OSDCMD_SHOWHELP; -} static int osdcmd_vidmode(osdcmdptr_t parm) { @@ -367,9 +330,6 @@ static int osdcmd_restartsound(osdcmdptr_t UNUSED(parm)) sndInit(); sfxInit(); - if (MusicEnabled() && (gGameStarted || gDemo.at1)) - sndPlaySong(nullptr, "*", true); - return OSDCMD_OK; } @@ -474,7 +434,6 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("give","give : gives requested item", osdcmd_give); OSD_RegisterFunction("god","god: toggles god mode", osdcmd_god); - OSD_RegisterFunction("music","music EL: change music", osdcmd_music); OSD_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); OSD_RegisterFunction("quicksave","quicksave: performs a quick save", osdcmd_quicksave); OSD_RegisterFunction("quickload","quickload: performs a quick load", osdcmd_quickload); diff --git a/source/common/music/music.cpp b/source/common/music/music.cpp index 95f77c270..1ff85cda7 100644 --- a/source/common/music/music.cpp +++ b/source/common/music/music.cpp @@ -71,6 +71,8 @@ #include "savegamehelp.h" #include "sjson.h" +CVARD(Bool, mus_restartonload, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "restart the music when loading a saved game with the same map or not") // only implemented for Blood - todo: generalize + MusPlayingInfo mus_playing; MusicAliasMap MusicAliases; MidiDeviceMap MidiDevices; From 59ebb10512149189b5418f2c2be5adefd5ff3478 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 19:35:35 +0100 Subject: [PATCH 043/203] - fixed compilation and unhooked the Redneck Rampage menu so that it can be replaced. --- source/build/include/baselayer.h | 3 +- source/common/inputstate.h | 7 ++ source/common/menu/listmenu.cpp | 10 +-- source/common/menu/menu.cpp | 1 + source/common/music/music.cpp | 38 +++++---- source/common/savegamehelp.cpp | 1 + source/duke3d/src/gameexec.cpp | 2 - source/duke3d/src/menus.cpp | 1 - source/duke3d/src/screens.cpp | 25 ------ source/rr/src/actors.cpp | 6 +- source/rr/src/d_menu.cpp | 16 ++-- source/rr/src/demo.cpp | 38 ++++----- source/rr/src/duke3d.h | 7 ++ source/rr/src/game.cpp | 136 ++++--------------------------- source/rr/src/gameexec.cpp | 8 +- source/rr/src/menus.cpp | 26 +----- source/rr/src/menus.h | 46 ++++++----- source/rr/src/premap.cpp | 4 +- source/rr/src/screens.cpp | 35 +------- source/rr/src/sounds.cpp | 3 - 20 files changed, 126 insertions(+), 287 deletions(-) diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index e45646689..94bf8e9c1 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -14,6 +14,7 @@ #include "inputstate.h" #include "printf.h" #include "zstring.h" +#include "vectors.h" #ifdef DEBUGGINGAIDS @@ -211,7 +212,7 @@ struct GameInterface virtual void StartGame(FGameStartup& gs) {} virtual FSavegameInfo GetSaveSig() { return { "", 0, 0}; } virtual bool DrawSpecialScreen(const DVector2 &origin, int tilenum) { return false; } - virtual void DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position); + virtual void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) {} }; extern GameInterface* gi; diff --git a/source/common/inputstate.h b/source/common/inputstate.h index 834790ff7..12b973ca3 100644 --- a/source/common/inputstate.h +++ b/source/common/inputstate.h @@ -302,6 +302,13 @@ public: int32_t mouseReadAbs(vec2_t* const pResult); void GetMouseDelta(ControlInfo* info); + void ClearAllInput() + { + ClearKeysDown(); + keyFlushChars(); + keyFlushScans(); + } + }; diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 8ec1259e3..adb928d89 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -629,17 +629,17 @@ int FListMenuItemPatch::GetWidth() void ImageScreen::Drawer() { - if (mDesc->mType == 0) + if (mDesc->type == 0) { - auto tileindexp = NameToTileIndex.CheckKey(mDesc->mText); + auto tileindexp = NameToTileIndex.CheckKey(FName(mDesc->text, true)); int tileindex; if (tileindexp == nullptr) { // If this isn't a name, try a literal tile index; - auto c = mDesc->mMenuName.GetChars(); + auto c = mDesc->text.GetChars(); if (*c == '#') tileindex = (int)strtoll(c+1, nullptr, 0); // Error out if the screen cannot be found, this is always a definition error that needs to be reported. - else I_Error("Invalid menu screen '%s'", mDesc->mMenuName.GetChars()); + else I_Error("Invalid menu screen '%s'", mDesc->text.GetChars()); } else tileindex = *tileindexp; if (!gi->DrawSpecialScreen(origin, tileindex)) // allows the front end to do custom handling for a given image. @@ -649,6 +649,6 @@ void ImageScreen::Drawer() } else { - gi->DrawCenteredTextScreen(origin, mDesc->mText, mDesc->type); + gi->DrawCenteredTextScreen(origin, mDesc->text, mDesc->type); } } diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index e043450c8..cfa864708 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -377,6 +377,7 @@ void M_StartControlPanel (bool makeSound) } buttonMap.ResetButtonStates (); + inputState.ClearAllKeyStatus(); for (int i = 0; i < NUM_MKEYS; ++i) { MenuButtons[i].ReleaseKey(0); diff --git a/source/common/music/music.cpp b/source/common/music/music.cpp index 1ff85cda7..2a06e6fe0 100644 --- a/source/common/music/music.cpp +++ b/source/common/music/music.cpp @@ -71,8 +71,6 @@ #include "savegamehelp.h" #include "sjson.h" -CVARD(Bool, mus_restartonload, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "restart the music when loading a saved game with the same map or not") // only implemented for Blood - todo: generalize - MusPlayingInfo mus_playing; MusicAliasMap MusicAliases; MidiDeviceMap MidiDevices; @@ -80,6 +78,8 @@ MusicVolumeMap MusicVolumes; MusicAliasMap LevelMusicAliases; bool MusicPaused; static bool mus_blocked; +static FString lastStartedMusic; + //========================================================================== // // @@ -257,6 +257,7 @@ bool S_StartMusic (const char *m_id) bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force) { + lastStartedMusic = musicname; // remember the last piece of music that was requested to be played. if (musicname == nullptr || musicname[0] == 0) { // Don't choke if the map doesn't have a song attached @@ -269,16 +270,6 @@ bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force) FString DEH_Music; - FName* aliasp = MusicAliases.CheckKey(musicname); - if (aliasp != nullptr) - { - if (*aliasp == NAME_None) - { - return true; // flagged to be ignored - } - musicname = aliasp->GetChars(); - } - if (!mus_playing.name.IsEmpty() && mus_playing.handle != nullptr && stricmp(mus_playing.name, musicname) == 0 && @@ -577,10 +568,11 @@ int Mus_Play(const char *mapname, const char *fn, bool loop) mapname = lastMusicLevel.GetChars(); fn = lastMusic.GetChars(); } + // Allow per level music substitution. - // Unlike some other engines like ZDoom or even Blood which use definition files, the music names in Duke Nukem are being defined in a CON script, making direct replacement a lot harder. // For most cases using $musicalias would be sufficient, but that method only works if a level actually has some music defined at all. - // This way it can be done with an add-on definition lump even in cases like Redneck Rampage where no music definitions exist or where music gets reused for multiple levels but replacement is wanted individually. + // This way it can be done with an add-on definition lump even in cases like Redneck Rampage where no music definitions exist + // or where music gets reused for multiple levels but replacement is wanted individually. if (mapname && *mapname) { if (*mapname == '/') mapname++; @@ -588,6 +580,24 @@ int Mus_Play(const char *mapname, const char *fn, bool loop) if (check) fn = check->GetChars(); } + // Now perform music aliasing. This also needs to be done before checking identities because multiple names can map to the same song. + FName* aliasp = MusicAliases.CheckKey(fn); + if (aliasp != nullptr) + { + if (*aliasp == NAME_None) + { + return true; // flagged to be ignored + } + fn = aliasp->GetChars(); + } + + if (!mus_restartonload) + { + // If the currently playing piece of music is the same, do not restart. Note that there's still edge cases where this may fail to detect identities. + if (mus_playing.handle != nullptr && lastStartedMusic.CompareNoCase(fn) == 0 && mus_playing.loop) + return true; + } + S_ChangeMusic(fn, 0, loop, true); return mus_playing.handle != nullptr; } diff --git a/source/common/savegamehelp.cpp b/source/common/savegamehelp.cpp index c16ede5ef..b0eae5d96 100644 --- a/source/common/savegamehelp.cpp +++ b/source/common/savegamehelp.cpp @@ -256,6 +256,7 @@ int G_ValidateSavegame(FileReader &fr, FString *savetitle) return 0; } } + return 1; } //============================================================================= diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index e9f15c183..0690feac8 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -1080,8 +1080,6 @@ static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags, int32_t cons } else if (!(resetFlags & 1)) { - inputState.ClearKeyStatus(sc_Space); - I_AdvanceTriggerClear(); M_StartControlPanel(false); M_SetMenu(NAME_ConfirmPlayerReset); } diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index f5ab60a2c..b6b580a5a 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -1553,7 +1553,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) } } break; -#endif case MENU_CREDITS4: // JBF 20031220 { #define MENU_YOFFSET 40 diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index 8ef72c260..fb0b9593f 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -1004,31 +1004,6 @@ void G_DisplayRest(int32_t smoothratio) } } -#if 0 - if (I_EscapeTrigger() && ud.overhead_on == 0 - && ud.show_help == 0 - && g_player[myconnectindex].ps->newowner == -1) - { - if ((g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU && - g_player[myconnectindex].ps->newowner == -1 && - (g_player[myconnectindex].ps->gm&MODE_TYPE) != MODE_TYPE) - { - I_EscapeTriggerClear(); - S_PauseSounds(true); - - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) ready2send = 0; - - if (g_player[myconnectindex].ps->gm&MODE_GAME) Menu_Change(MENU_MAIN_INGAME); - else Menu_Change(MENU_MAIN); - screenpeek = myconnectindex; - - S_MenuSound(); - } - } -#endif - if (g_player[myconnectindex].ps->newowner == -1 && ud.overhead_on == 0 && cl_crosshair && ud.camerasprite == -1) { ud.returnvar[0] = (160<<16) - (g_player[myconnectindex].ps->look_ang<<15); diff --git a/source/rr/src/actors.cpp b/source/rr/src/actors.cpp index 12ae0d40c..00bcadf60 100644 --- a/source/rr/src/actors.cpp +++ b/source/rr/src/actors.cpp @@ -9142,13 +9142,13 @@ next_sprite: static void G_DoEffectorLights(void) // STATNUM 14 { - int32_t i; +#ifdef POLYMER + int32_t i; for (SPRITES_OF(STAT_LIGHT, i)) { switch (sprite[i].lotag) { -#ifdef POLYMER case SE_49_POINT_LIGHT: { if (!A_CheckSpriteFlags(i, SFLAG_NOLIGHT) && videoGetRenderMode() == REND_POLYMER && @@ -9310,9 +9310,9 @@ static void G_DoEffectorLights(void) // STATNUM 14 break; } -#endif // POLYMER } } +#endif // POLYMER } #ifdef POLYMER diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index 80dd7bef4..9da300fea 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -40,7 +40,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "namesdyn.h" #include "../../glbackend/glbackend.h" -BEGIN_DUKE_NS + +BEGIN_RR_NS #define MENU_MARGIN_REGULAR 40 #define MENU_MARGIN_WIDE 32 @@ -142,8 +143,7 @@ static void Menu_DrawBackground(const DVector2 &origin) static void Menu_DrawTopBar(const DVector2 &origin) { - if ((G_GetLogoFlags() & LOGO_NOTITLEBAR) == 0) - rotatesprite_fs(int(origin.X*65536) + (MENU_MARGIN_CENTER<<16), int(origin.Y*65536) + (19<<16), MF_Redfont.cursorScale, 0,MENUBAR,16,0,10); + rotatesprite_fs(int(origin.X*65536) + (MENU_MARGIN_CENTER<<16), int(origin.Y*65536) + (19<<16), MF_Redfont.cursorScale, 0,MENUBAR,16,0,10); } static void Menu_DrawTopBarCaption(const char *caption, const DVector2 &origin) @@ -163,7 +163,7 @@ static void Menu_DrawTopBarCaption(const char *caption, const DVector2 &origin) static void Menu_GetFmt(const MenuFont_t* font, uint8_t const status, int32_t* s, int32_t* z) { if (status & MT_Selected) - *s = VM_OnEventWithReturn(EVENT_MENUSHADESELECTED, -1, myconnectindex, sintable[((int32_t)totalclock << 5) & 2047] >> 12); + *s = sintable[((int32_t)totalclock << 5) & 2047] >> 12; else *s = font->shade_deselected; // sum shade values @@ -335,7 +335,7 @@ class MainMenu : public RedneckListMenu void PreDraw() override { RedneckListMenu::PreDraw(); - rotatesprite_fs(origin.x + ((MENU_MARGIN_CENTER-5)<<16), origin.y + ((57+l)<<16), 16592L,0,RRRA? THREEDEE : INGAMEDUKETHREEDEE,0,0,10); + rotatesprite_fs(int((origin.X + MENU_MARGIN_CENTER-5) * 65536), int((origin.Y + 57) * 65536), 16592L,0,RRRA? THREEDEE : INGAMEDUKETHREEDEE,0,0,10); } }; @@ -423,7 +423,7 @@ void GameInterface::StartGame(FGameStartup& gs) } ud.m_player_skill = gs.Skill + 1; - ud.skill_voice = S_PlaySound(skillsound); + g_skillSoundVoice = S_PlaySound(skillsound); ud.m_respawn_monsters = (gs.Skill == 3); ud.m_monsters_off = ud.monsters_off = 0; ud.m_respawn_items = 0; @@ -443,9 +443,9 @@ FSavegameInfo GameInterface::GetSaveSig() void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) { Menu_DrawBackground(origin); - G_ScreenText(MF_Bluefont.tilenum, int(origin.X + 160) * 65536), int((origin.Y + position) * 65536), MF_Bluefont.zoom, 0, 0, text, 0, MF_Bluefont.pal, + G_ScreenText(MF_Bluefont.tilenum, int((origin.X + 160) * 65536), int((origin.Y + position) * 65536), MF_Bluefont.zoom, 0, 0, text, 0, MF_Bluefont.pal, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, - MF_Bluefont.textflags | f | TEXT_XCENTER, 0, 0, xdim - 1, ydim - 1); + MF_Bluefont.textflags | TEXT_XCENTER, 0, 0, xdim - 1, ydim - 1); } diff --git a/source/rr/src/demo.cpp b/source/rr/src/demo.cpp index 1ca20b462..4eea7b22b 100644 --- a/source/rr/src/demo.cpp +++ b/source/rr/src/demo.cpp @@ -55,12 +55,12 @@ static int32_t demorec_seeds=1, demo_hasseeds; static void Demo_RestoreModes(int32_t menu) { - if (menu) - Menu_Open(myconnectindex); - else - Menu_Close(myconnectindex); + if (menu) + M_StartControlPanel(false); + else + M_ClearMenus(); - g_player[myconnectindex].ps->gm &= ~MODE_GAME; + g_player[myconnectindex].ps->gm &= ~MODE_GAME; g_player[myconnectindex].ps->gm |= MODE_DEMO; } @@ -489,7 +489,7 @@ RECHECK: fadepal(0,0,0, 0,252,28); P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 1); // JBF 20040308 G_DrawBackground(); - M_DisplayMenus(); + //M_DisplayMenus(); videoNextPage(); fadepal(0,0,0, 252,0,-28); ud.reccnt = 0; @@ -523,8 +523,8 @@ RECHECK: { FX_StopAllSounds(); S_ClearSoundLocks(); - Menu_Open(myconnectindex); - } + M_StartControlPanel(false); + } ready2send = 0; bigi = 0; @@ -664,7 +664,7 @@ RECHECK: corrupt: OSD_Printf(OSD_ERROR "Demo %d is corrupt (code %d).\n", g_whichDemo-1, corruptcode); nextdemo: - Menu_Open(myconnectindex); + M_StartControlPanel(false); nextdemo_nomenu: foundemo = 0; ud.reccnt = 0; @@ -862,16 +862,6 @@ nextdemo_nomenu: goto RECHECK; } - if (I_EscapeTrigger() && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0 && (g_player[myconnectindex].ps->gm&MODE_TYPE) == 0) - { - I_EscapeTriggerClear(); - FX_StopAllSounds(); - S_ClearSoundLocks(); - Menu_Open(myconnectindex); - Menu_Change(MENU_MAIN); - S_MenuSound(); - } - if (Demo_IsProfiling()) { // Do nothing: sampletimer() is reached from M_DisplayMenus() -> @@ -884,15 +874,15 @@ nextdemo_nomenu: if ((g_player[myconnectindex].ps->gm&MODE_TYPE) != MODE_TYPE) { g_player[myconnectindex].ps->gm = 0; - Menu_Open(myconnectindex); - } + M_StartControlPanel(false); + } } else { - if (ud.recstat != 2) - M_DisplayMenus(); + //if (ud.recstat != 2) + //M_DisplayMenus(); - if ((g_netServer || ud.multimode > 1) && !Menu_IsTextInput(m_currentMenu)) + if ((g_netServer || ud.multimode > 1))// && !Menu_IsTextInput(m_currentMenu)) { ControlInfo noshareinfo; CONTROL_GetInput(&noshareinfo); diff --git a/source/rr/src/duke3d.h b/source/rr/src/duke3d.h index 28d426db3..497b64327 100644 --- a/source/rr/src/duke3d.h +++ b/source/rr/src/duke3d.h @@ -158,7 +158,14 @@ struct GameInterface : ::GameInterface bool mouseInactiveConditional(bool condition) override; FString statFPS() override; GameStats getStats() override; + void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int flags); + void MenuOpened() override; + void MenuSound(::GameInterface::EMenuSounds snd) override; + void MenuClosed() override; + bool CanSave() override; + void StartGame(FGameStartup& gs) override; FSavegameInfo GetSaveSig() override; + void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) override; }; END_RR_NS diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 6bcd72953..bb37e2352 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -46,6 +46,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "m_argv.h" #include "filesystem/filesystem.h" #include "statistics.h" +#include "c_dispatch.h" // Uncomment to prevent anything except mirrors from drawing. It is sensible to // also uncomment ENGINE_CLEAR_SCREEN in build/src/engine_priv.h. @@ -6230,82 +6231,6 @@ void G_HandleLocalKeys(void) typebuf[0] = 0; } - if (inputState.UnboundKeyPressed(sc_F1)/* || (ud.show_help && I_AdvanceTrigger())*/) - { - inputState.ClearKeyStatus(sc_F1); - - Menu_Change(MENU_STORY); - S_PauseSounds(true); - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2)) - { - ready2send = 0; - totalclock = ototalclock; - screenpeek = myconnectindex; - } - } - - // if((!net_server && ud.multimode < 2)) - { - if (ud.recstat != 2 && (!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && inputState.UnboundKeyPressed(sc_F2)) - { - inputState.ClearKeyStatus(sc_F2); - -FAKE_F2: - if (sprite[g_player[myconnectindex].ps->i].extra <= 0) - { - P_DoQuote(QUOTE_SAVE_DEAD,g_player[myconnectindex].ps); - return; - } - - Menu_Change(MENU_SAVE); - - S_PauseSounds(true); - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2)) - { - ready2send = 0; - totalclock = ototalclock; - screenpeek = myconnectindex; - } - } - - if ((!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && inputState.UnboundKeyPressed(sc_F3)) - { - inputState.ClearKeyStatus(sc_F3); - -FAKE_F3: - Menu_Change(MENU_LOAD); - S_PauseSounds(true); - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) - { - ready2send = 0; - totalclock = ototalclock; - } - - screenpeek = myconnectindex; - } - } - - if (inputState.UnboundKeyPressed(sc_F4)) - { - inputState.ClearKeyStatus(sc_F4); - - S_PauseSounds(true); - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) - { - ready2send = 0; - totalclock = ototalclock; - } - - Menu_Change(MENU_SOUND_INGAME); - } if ((buttonMap.ButtonDown(gamefunc_Quick_Save) || g_doQuickSave == 1) && (!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && (g_player[myconnectindex].ps->gm&MODE_GAME)) { @@ -6313,8 +6238,11 @@ FAKE_F3: g_doQuickSave = 0; - if (!g_lastusersave.isValid()) - goto FAKE_F2; + if (!g_lastusersave.isValid()) + { + C_DoCommand("opensavemenu"); + return; + } inputState.keyFlushChars(); @@ -6375,9 +6303,11 @@ FAKE_F3: g_doQuickSave = 0; - if (g_quickload == nullptr || !g_quickload->isValid()) - goto FAKE_F3; - else if (g_quickload->isValid()) + if (g_quickload == nullptr || !g_quickload->isValid()) + { + C_DoCommand("openloadmenu"); + } + else if (g_quickload->isValid()) { inputState.keyFlushChars(); inputState.ClearKeysDown(); @@ -6387,36 +6317,6 @@ FAKE_F3: } } - if (inputState.UnboundKeyPressed(sc_F10)) - { - inputState.ClearKeyStatus(sc_F10); - - Menu_Change(MENU_QUIT_INGAME); - S_PauseSounds(true); - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) - { - ready2send = 0; - totalclock = ototalclock; - } - } - - if (inputState.UnboundKeyPressed(sc_F11)) - { - inputState.ClearKeyStatus(sc_F11); - - Menu_Change(MENU_COLCORR_INGAME); - S_PauseSounds(true); - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) - { - ready2send = 0; - totalclock = ototalclock; - } - } - if (ud.overhead_on != 0) { int const timerOffset = ((int) totalclock - nonsharedtimer); @@ -7381,9 +7281,9 @@ void G_BackToMenu(void) if (ud.recstat == 1) G_CloseDemoWrite(); ud.warp_on = 0; g_player[myconnectindex].ps->gm = 0; - Menu_Open(myconnectindex); - Menu_Change(MENU_MAIN); - inputState.keyFlushChars(); + M_StartControlPanel(false); + M_SetMenu(NAME_MainMenu); + inputState.keyFlushChars(); } static int G_EndOfLevel(void) @@ -7426,9 +7326,9 @@ static int G_EndOfLevel(void) if (!VOLUMEALL) G_DoOrderScreen(); g_player[myconnectindex].ps->gm = 0; - Menu_Open(myconnectindex); - Menu_Change(MENU_MAIN); - return 2; + M_StartControlPanel(false); + M_SetMenu(NAME_MainMenu); + return 2; } else { @@ -7719,8 +7619,6 @@ MAIN_LOOP_RESTART: for (int & q : user_quote_time) q = 0; - Menu_Change(MENU_MAIN); - //if (g_networkMode != NET_DEDICATED_SERVER) { G_GetCrosshairColor(); diff --git a/source/rr/src/gameexec.cpp b/source/rr/src/gameexec.cpp index 712dae268..7f261f91b 100644 --- a/source/rr/src/gameexec.cpp +++ b/source/rr/src/gameexec.cpp @@ -1063,11 +1063,9 @@ static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags) { if (g_quickload && g_quickload->isValid() && ud.recstat != 2) { - Menu_Open(playerNum); - inputState.ClearKeyStatus(sc_Space); - I_AdvanceTriggerClear(); - Menu_Change(MENU_RESETPLAYER); - } + M_StartControlPanel(false); + M_SetMenu(NAME_ConfirmPlayerReset); + } else g_player[playerNum].ps->gm = MODE_RESTART; vmFlags |= VM_NOEXECUTE; diff --git a/source/rr/src/menus.cpp b/source/rr/src/menus.cpp index 5b219ad29..ff2b7672f 100644 --- a/source/rr/src/menus.cpp +++ b/source/rr/src/menus.cpp @@ -36,13 +36,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_RR_NS +#if 0 + // common positions #define MENU_MARGIN_REGULAR 40 #define MENU_MARGIN_WIDE 32 #define MENU_MARGIN_CENTER 160 #define MENU_HEIGHT_CENTER 100 -int32_t g_skillSoundVoice = -1; #define USERMAPENTRYLENGTH 25 @@ -179,19 +180,6 @@ they effectively stand in for curly braces as struct initializers. // common font types // tilenums are set after namesdyn runs -// emptychar x,y between x,y zoom cursorLeft cursorCenter cursorScale textflags -// tilenum shade_deselected shade_disabled pal pal_selected pal_deselected pal_disabled -MenuFont_t MF_Redfont = { { 5<<16, 15<<16 }, { 0, 0 }, 65536, 20<<16, 110<<16, 65536, 65536, 65536, TEXT_BIGALPHANUM | TEXT_UPPERCASE, - -1, 10, 0, 0, 0, 0, 1, - 0, 0, 1 }; -MenuFont_t MF_Bluefont = { { 5<<16, 7<<16 }, { 0, 0 }, 65536, 10<<16, 110<<16, 32768, 65536, 65536, 0, - -1, 10, 0, 0, 10, 10, 16, - 0, 0, 16 }; -MenuFont_t MF_Minifont = { { 4<<16, 5<<16 }, { 1<<16, 1<<16 }, 65536, 10<<16, 110<<16, 32768, 65536, 65536, 0, - -1, 10, 0, 0, 2, 2, 0, - 0, 0, 16 }; - - static MenuMenuFormat_t MMF_Top_Main = { { MENU_MARGIN_CENTER<<16, 55<<16, }, -(170<<16) }; static MenuMenuFormat_t MMF_Top_Episode = { { MENU_MARGIN_CENTER<<16, 48<<16, }, -(190<<16) }; static MenuMenuFormat_t MMF_Top_Skill = { { MENU_MARGIN_CENTER<<16, 58<<16, }, -(190<<16) }; @@ -7445,14 +7433,6 @@ void M_DisplayMenus(void) } } -bool GameInterface::mouseInactiveConditional(bool condition) -{ - return MOUSEINACTIVECONDITIONAL(condition); -} - -FSavegameInfo GameInterface::GetSaveSig() -{ - return { SAVESIG_RR, MINSAVEVER_RR, SAVEVER_RR }; -} +#endif END_RR_NS diff --git a/source/rr/src/menus.h b/source/rr/src/menus.h index 7bdf57a7a..3e8b0a47b 100644 --- a/source/rr/src/menus.h +++ b/source/rr/src/menus.h @@ -27,6 +27,31 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_RR_NS +// a subset of screentext parameters, restricted because menus require accessibility +typedef struct MenuFont_t +{ + // int32_t xspace, yline; + vec2_t emptychar, between; + int32_t zoom; + int32_t cursorLeftPosition, cursorCenterPosition, cursorScale, cursorScale2, cursorScale3; + int32_t textflags; + int16_t tilenum; + // selected shade glows, deselected shade is used by Blood, disabled shade is used by SW + int8_t shade_deselected, shade_disabled; + uint8_t pal; + uint8_t pal_selected, pal_deselected, pal_disabled; + uint8_t pal_selected_right, pal_deselected_right, pal_disabled_right; + + int32_t get_yline() const { return mulscale16(emptychar.y, zoom); } +} MenuFont_t; + +extern MenuFont_t MF_Redfont, MF_Bluefont, MF_Minifont; + +void Menu_Init(void); + +#if 0 + + enum MenuIndex_t { MENU_NULL = INT32_MIN, // sentinel for "do nothing" MENU_CLOSE = -2, // sentinel for "close the menu"/"no menu" @@ -141,25 +166,6 @@ typedef enum MenuAnimationType_t MA_Advance, } MenuAnimationType_t; -// a subset of screentext parameters, restricted because menus require accessibility -typedef struct MenuFont_t -{ -// int32_t xspace, yline; - vec2_t emptychar, between; - int32_t zoom; - int32_t cursorLeftPosition, cursorCenterPosition, cursorScale, cursorScale2, cursorScale3; - int32_t textflags; - int16_t tilenum; - // selected shade glows, deselected shade is used by Blood, disabled shade is used by SW - int8_t shade_deselected, shade_disabled; - uint8_t pal; - uint8_t pal_selected, pal_deselected, pal_disabled; - uint8_t pal_selected_right, pal_deselected_right, pal_disabled_right; - - int32_t get_yline() const { return mulscale16(emptychar.y, zoom); } -} MenuFont_t; - - typedef enum MenuEntryType_t { @@ -505,6 +511,8 @@ extern int32_t m_mousewake_watchpoint, m_menuchange_watchpoint; # define MOUSEINACTIVECONDITIONAL(condition) (!MOUSEACTIVECONDITION && (condition)) # define MOUSEWATCHPOINTCONDITIONAL(condition) ((condition) || m_mousewake_watchpoint || m_menuchange_watchpoint == 3) +#endif + END_RR_NS #endif diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index 7b369be2b..1aaffd4be 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -36,6 +36,7 @@ static int32_t g_whichPalForPlayer = 9; static uint8_t precachehightile[2][MAXTILES>>3]; static int32_t g_precacheCount; +int32_t g_skillSoundVoice = -1; static void flag_precache(int32_t tile, int32_t type) @@ -1948,7 +1949,7 @@ end_vol4a: pPlayer->zoom = 768; #endif pPlayer->gm = 0; - Menu_Close(0); + M_ClearMenus(); //AddLog("Newgame"); @@ -2474,7 +2475,6 @@ int G_EnterLevel(int gameMode) for (TRAVERSE_CONNECT(i)) { g_player[i].ps->gm = MODE_GAME; - Menu_Close(i); } } else if (gameMode & MODE_RESTART) diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index fa99b3788..2c2eb268a 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -1035,37 +1035,6 @@ void G_DisplayRest(int32_t smoothratio) } } - if (I_EscapeTrigger() && ud.overhead_on == 0 - && ud.show_help == 0 - && g_player[myconnectindex].ps->newowner == -1) - { - if ((g_player[myconnectindex].ps->gm&MODE_MENU) == MODE_MENU && g_currentMenu <= MENU_MAIN_INGAME) - { - I_EscapeTriggerClear(); - S_PlaySound(EXITMENUSOUND); - Menu_Change(MENU_CLOSE); - if (!ud.pause_on) - S_PauseSounds(false); - } - else if ((g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU && - g_player[myconnectindex].ps->newowner == -1 && - (g_player[myconnectindex].ps->gm&MODE_TYPE) != MODE_TYPE) - { - I_EscapeTriggerClear(); - S_PauseSounds(true); - - Menu_Open(myconnectindex); - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) ready2send = 0; - - if (g_player[myconnectindex].ps->gm&MODE_GAME) Menu_Change(MENU_MAIN_INGAME); - else Menu_Change(MENU_MAIN); - screenpeek = myconnectindex; - - S_MenuSound(); - } - } - if (g_player[myconnectindex].ps->newowner == -1 && ud.overhead_on == 0 && cl_crosshair && ud.camerasprite == -1) { int32_t a = CROSSHAIR; @@ -1171,8 +1140,8 @@ void G_DisplayRest(int32_t smoothratio) { if (g_player[myconnectindex].ps->gm&MODE_TYPE) Net_SendMessage(); - else - M_DisplayMenus(); + //else + //M_DisplayMenus(); } { diff --git a/source/rr/src/sounds.cpp b/source/rr/src/sounds.cpp index 17d9b265d..473f9f1c3 100644 --- a/source/rr/src/sounds.cpp +++ b/source/rr/src/sounds.cpp @@ -738,9 +738,6 @@ void S_Callback(intptr_t num) dnum++; } -void S_ClearSoundLocks(void) -{ -} bool A_CheckSoundPlaying(int spriteNum, int soundNum) { From 1f1b927b6bcd15b80140b62c68929b5e363f6275 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 20:11:27 +0100 Subject: [PATCH 044/203] - fixed a few issues. --- source/common/menu/menudef.cpp | 2 +- source/common/utility/stringtable.cpp | 18 ++++++++++-------- source/duke3d/src/screentext.cpp | 2 ++ source/rr/src/screentext.cpp | 4 +++- wadsrc/static/demolition/menudef.txt | 10 ++++++---- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index eef422731..f25db2439 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -1042,7 +1042,7 @@ void M_ParseMenuDefs() { ParseListMenu(sc); } - if (sc.Compare("ImageScroller")) + else if (sc.Compare("ImageScroller")) { ParseImageScroller(sc); } diff --git a/source/common/utility/stringtable.cpp b/source/common/utility/stringtable.cpp index 0307b26ac..5f5b9809f 100644 --- a/source/common/utility/stringtable.cpp +++ b/source/common/utility/stringtable.cpp @@ -244,18 +244,20 @@ bool FStringTable::ParseLanguageCSV(int lumpnum, const TArray &buffer) if (filtercol > -1) { auto filterstr = row[filtercol]; - auto filter = filterstr.Split(" ", FString::TOK_SKIPEMPTY); - bool ok = false; - for (auto &entry : filter) + if (filterstr.IsNotEmpty()) { - if (validFilter(entry)) + auto filter = filterstr.Split(" ", FString::TOK_SKIPEMPTY); + bool ok = false; + for (auto& entry : filter) { - ok = true; - break; + if (validFilter(entry)) + { + ok = true; + break; + } } + if (!ok) continue; } - if (!ok) continue; - continue; } #endif diff --git a/source/duke3d/src/screentext.cpp b/source/duke3d/src/screentext.cpp index 9329c52e3..183479a9c 100644 --- a/source/duke3d/src/screentext.cpp +++ b/source/duke3d/src/screentext.cpp @@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "compat.h" #include "sbar.h" #include "menus.h" +#include "gstrings.h" BEGIN_DUKE_NS @@ -468,6 +469,7 @@ vec2_t G_ScreenText(const int32_t font, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, const int32_t f, const int32_t x1, const int32_t y1, const int32_t x2, const int32_t y2) { + if (*str == '$') str = GStrings(str + 1); vec2_t size = { 0, 0, }; // eventually the return value vec2_t origin = { 0, 0, }; // where to start, depending on the alignment vec2_t pos = { 0, 0, }; // holds the coordinate position as we draw each character tile of the string diff --git a/source/rr/src/screentext.cpp b/source/rr/src/screentext.cpp index a16907825..75b1b2d1a 100644 --- a/source/rr/src/screentext.cpp +++ b/source/rr/src/screentext.cpp @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "compat.h" #include "sbar.h" #include "menus.h" +#include "gstrings.h" BEGIN_RR_NS @@ -467,7 +468,8 @@ vec2_t G_ScreenText(const int32_t font, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, const int32_t f, const int32_t x1, const int32_t y1, const int32_t x2, const int32_t y2) { - vec2_t size = { 0, 0, }; // eventually the return value + if (*str == '$') str = GStrings(str + 1); + vec2_t size = { 0, 0, }; // eventually the return value vec2_t origin = { 0, 0, }; // where to start, depending on the alignment vec2_t pos = { 0, 0, }; // holds the coordinate position as we draw each character tile of the string vec2_t extent = { 0, 0, }; // holds the x-width of each character and the greatest y-height of each line diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index d8f9c80eb..c5f414ac4 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -22,11 +22,11 @@ LISTMENU "MainMenu" } ifgame(Duke, Nam, WW2GI, Fury) { - class "Duke.ListMenu" + class "Duke.MainMenu" } else { - class "Redneck.ListMenu" + class "Redneck.MainMenu" } NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" //NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) @@ -88,11 +88,11 @@ LISTMENU "IngameMenu" } ifgame(Duke, Nam, WW2GI, Fury) { - class "Duke.ListMenu" + class "Duke.MainMenu" } else { - class "Redneck.ListMenu" + class "Redneck.MainMenu" } NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" @@ -361,6 +361,7 @@ LISTMENU "MultiMenu" // // //------------------------------------------------------------------------------------------- +/* ImageScroller "HelpMenu" { @@ -458,3 +459,4 @@ ImageScroller "CreditsMenu" } } +*/ \ No newline at end of file From 299314b8a53e77bbaaf6e414d5126cc7b436ca71 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 20:48:58 +0100 Subject: [PATCH 045/203] - Redneck Rampage menu looks correct. --- source/rr/src/d_menu.cpp | 54 +++++++++++++++++++++------------------- source/rr/src/game.cpp | 4 ++- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index 9da300fea..fa485f9d5 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -64,16 +64,16 @@ enum MenuTextFlags_t // common font types // tilenums are set after namesdyn runs. // These are also modifiable by scripts. -// emptychar x,y between x,y zoom cursorLeft cursorCenter cursorScale textflags -// tilenum shade_deselected shade_disabled pal pal_selected pal_deselected pal_disabled -MenuFont_t MF_Redfont = { { 5<<16, 15<<16 }, { 0, 0 }, 65536, 20<<16, 110<<16, 65536, TEXT_BIGALPHANUM | TEXT_UPPERCASE, - -1, 10, 0, 0, 0, 0, 1, +// emptychar x,y between x,y zoom cursorLeft cursorCenter cursorScale textflags +// tilenum shade_deselected shade_disabled pal pal_selected pal_deselected pal_disabled +MenuFont_t MF_Redfont = { { 5<<16, 15<<16 }, { 0, 0 }, 65536, 20<<16, 110<<16, 65536, 65536, 65536, TEXT_BIGALPHANUM | TEXT_UPPERCASE, + -1, 10, 0, 0, 0, 0, 1, 0, 0, 1 }; -MenuFont_t MF_Bluefont = { { 5<<16, 7<<16 }, { 0, 0 }, 65536, 10<<16, 110<<16, 32768, 0, - -1, 10, 0, 0, 10, 10, 16, +MenuFont_t MF_Bluefont = { { 5<<16, 7<<16 }, { 0, 0 }, 65536, 10<<16, 110<<16, 32768, 65536, 65536, 0, + -1, 10, 0, 0, 10, 10, 16, 0, 0, 16 }; -MenuFont_t MF_Minifont = { { 4<<16, 5<<16 }, { 1<<16, 1<<16 }, 65536, 10<<16, 110<<16, 32768, 0, - -1, 10, 0, 0, 2, 2, 0, +MenuFont_t MF_Minifont = { { 4<<16, 5<<16 }, { 1<<16, 1<<16 }, 65536, 10<<16, 110<<16, 32768, 65536, 65536, 0, + -1, 10, 0, 0, 2, 2, 0, 0, 0, 16 }; @@ -81,6 +81,7 @@ MenuFont_t MF_Minifont = { { 4<<16, 5<<16 }, { 1<<16, 1<<16 }, This function prepares data after ART and CON have been processed. It also initializes some data in loops rather than statically at compile time. */ + void Menu_Init(void) { @@ -136,6 +137,7 @@ void Menu_Init(void) } + static void Menu_DrawBackground(const DVector2 &origin) { rotatesprite_fs(int(origin.X * 65536) + (MENU_MARGIN_CENTER << 16), int(origin.Y * 65536) + (100 << 16), 65536L, 0, MENUSCREEN, 16, 0, 10 + 64); @@ -143,24 +145,23 @@ static void Menu_DrawBackground(const DVector2 &origin) static void Menu_DrawTopBar(const DVector2 &origin) { - rotatesprite_fs(int(origin.X*65536) + (MENU_MARGIN_CENTER<<16), int(origin.Y*65536) + (19<<16), MF_Redfont.cursorScale, 0,MENUBAR,16,0,10); + rotatesprite_fs(int(origin.X*65536) + (MENU_MARGIN_CENTER<<16), int(origin.Y*65536) + (19<<16), MF_Redfont.cursorScale3, 0,MENUBAR,16,0,10); } -static void Menu_DrawTopBarCaption(const char *caption, const DVector2 &origin) +static void Menu_DrawTopBarCaption(const char* caption, const DVector2& origin) { - static char t[64]; - if (*caption == '$') caption = GStrings(caption + 1); - size_t const srclen = strlen(caption); - size_t const dstlen = min(srclen, ARRAY_SIZE(t)-1); - memcpy(t, caption, dstlen); - t[dstlen] = '\0'; - char *p = &t[dstlen-1]; - if (*p == ':') - *p = '\0'; - captionmenutext(int(origin.X*65536) + (MENU_MARGIN_CENTER<<16), int(origin.Y*65536) + (24<<16) + ((15>>1)<<16), t); + static char t[64]; + size_t const srclen = strlen(caption); + size_t const dstlen = min(srclen, ARRAY_SIZE(t) - 1); + memcpy(t, caption, dstlen); + t[dstlen] = '\0'; + char* p = &t[dstlen - 1]; + if (*p == ':') + *p = '\0'; + captionmenutext(int(origin.X * 65536) + (MENU_MARGIN_CENTER << 16), int(origin.Y * 65536) + (24 << 16) + (15 << 15), t); } -static void Menu_GetFmt(const MenuFont_t* font, uint8_t const status, int32_t* s, int32_t* z) +static void Menu_GetFmt(const MenuFont_t* font, uint8_t const status, int32_t* s) { if (status & MT_Selected) *s = sintable[((int32_t)totalclock << 5) & 2047] >> 12; @@ -174,7 +175,7 @@ static void Menu_GetFmt(const MenuFont_t* font, uint8_t const status, int32_t* s static vec2_t Menu_Text(int32_t x, int32_t y, const MenuFont_t* font, const char* t, uint8_t status, int32_t ydim_upper, int32_t ydim_lower) { int32_t s, p, ybetween = font->between.y; - int32_t f = font->textflags; + int32_t f = font->textflags | TEXT_RRMENUTEXTHACK; if (status & MT_XCenter) f |= TEXT_XCENTER; if (status & MT_XRight) @@ -196,7 +197,7 @@ static vec2_t Menu_Text(int32_t x, int32_t y, const MenuFont_t* font, const char else p = (status & MT_RightSide) ? font->pal_deselected_right : font->pal_deselected; - Menu_GetFmt(font, status, &s, &z); + Menu_GetFmt(font, status, &s); return G_ScreenText(font->tilenum, x, y, z, 0, 0, t, s, p, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, font->emptychar.x, font->emptychar.y, font->between.x, ybetween, f, 0, ydim_upper, xdim - 1, ydim_lower); } @@ -335,8 +336,11 @@ class MainMenu : public RedneckListMenu void PreDraw() override { RedneckListMenu::PreDraw(); - rotatesprite_fs(int((origin.X + MENU_MARGIN_CENTER-5) * 65536), int((origin.Y + 57) * 65536), 16592L,0,RRRA? THREEDEE : INGAMEDUKETHREEDEE,0,0,10); - } + if (RRRA) + rotatesprite_fs(int(origin.X * 65536) + ((MENU_MARGIN_CENTER - 5) << 16), int(origin.Y * 65536) + ((57) << 16), 16592L, 0, THREEDEE, 0, 0, 10); + else + rotatesprite_fs(int(origin.X * 65536) + ((MENU_MARGIN_CENTER + 5) << 16), int(origin.Y * 65536) + ((24) << 16), 23592L, 0, INGAMEDUKETHREEDEE, 0, 0, 10); + } }; //---------------------------------------------------------------------------- diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index bb37e2352..119ac5df3 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -7657,7 +7657,9 @@ MAIN_LOOP_RESTART: //if (g_networkMode != NET_DEDICATED_SERVER) { - if (G_PlaybackDemo()) + M_StartControlPanel(false); + M_SetMenu(NAME_MainMenu); + if (G_PlaybackDemo()) { FX_StopAllSounds(); g_noLogoAnim = 1; From 48f62ef1ed2db9cb91866725cf8ea31cba1bf8b9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 20:59:34 +0100 Subject: [PATCH 046/203] - cleaned out most of menus.cpp for RR. --- source/rr/src/menus.cpp | 5775 --------------------------------------- 1 file changed, 5775 deletions(-) diff --git a/source/rr/src/menus.cpp b/source/rr/src/menus.cpp index ff2b7672f..62679677d 100644 --- a/source/rr/src/menus.cpp +++ b/source/rr/src/menus.cpp @@ -53,115 +53,6 @@ static FORCE_INLINE void Menu_StartTextInput() inputState.ClearKeysDown(); } -static FORCE_INLINE void Menu_StopTextInput() -{ -} - -static FORCE_INLINE void rotatesprite_ybounds(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, uint8_t dapalnum, int32_t dastat, int32_t ydim_upper, int32_t ydim_lower) -{ - rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, 0, ydim_upper, xdim-1, ydim_lower); -} - -static void mgametext(int32_t x, int32_t y, char const * t) -{ - G_ScreenText(MF_Bluefont.tilenum, x, y, MF_Bluefont.zoom, 0, 0, t, 0, MF_Bluefont.pal, 2|8|16|ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags, 0, 0, xdim-1, ydim-1); -} - -static vec2_t mgametextcenter(int32_t x, int32_t y, char const * t, int32_t f = 0) -{ - return G_ScreenText(MF_Bluefont.tilenum, (MENU_MARGIN_CENTER<<16) + x, y, MF_Bluefont.zoom, 0, 0, t, 0, MF_Bluefont.pal, 2|8|16|ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f|TEXT_XCENTER, 0, 0, xdim-1, ydim-1); -} - -#define mminitext(x,y,t,p) minitext_(x, y, t, 0, p, 2|8|16|ROTATESPRITE_FULL16) -#define mmenutext menutext - -static void shadowminitext(int32_t x, int32_t y, const char *t, int32_t p) -{ - int32_t f = 0; - - if (!minitext_lowercase) - f |= TEXT_UPPERCASE; - - G_ScreenTextShadow(1, 1, MINIFONT, x, y, RR ? 32768 : 65536, 0, 0, t, 0, p, 2|8|16|ROTATESPRITE_FULL16, 0, 4<<16, 8<<16, 1<<16, 0, f, 0, 0, xdim-1, ydim-1); -} - -static void creditsminitext(int32_t x, int32_t y, const char *t, int32_t p) -{ - int32_t f = TEXT_XCENTER; - - if (!minitext_lowercase) - f |= TEXT_UPPERCASE; - - G_ScreenTextShadow(1, 1, MINIFONT, x, y, RR ? 32768 : 65536, 0, 0, t, 0, p, 2|8|16|ROTATESPRITE_FULL16, 0, 4<<16, 8<<16, 1<<16, 0, f, 0, 0, xdim-1, ydim-1); -} - -#pragma pack(push,1) -static savehead_t savehead; -#pragma pack(pop) - -static void Menu_DrawBackground(const vec2_t origin) -{ - rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (100<<16), 65536L,0,MENUSCREEN,16,0,10+64); -} - -static void Menu_DrawTopBar(const vec2_t origin) -{ - rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (19<<16), MF_Redfont.cursorScale3, 0,MENUBAR,16,0,10); -} - -static void Menu_DrawTopBarCaption(const char *caption, const vec2_t origin) -{ - static char t[64]; - size_t const srclen = strlen(caption); - size_t const dstlen = min(srclen, ARRAY_SIZE(t)-1); - memcpy(t, caption, dstlen); - t[dstlen] = '\0'; - char *p = &t[dstlen-1]; - if (*p == ':') - *p = '\0'; - captionmenutext(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + (24<<16) + (15<<15), t); -} - -static FORCE_INLINE int32_t Menu_CursorShade(void) -{ - return 4-(sintable[((int32_t) totalclock<<4)&2047]>>11); -} -static void Menu_DrawCursorCommon(int32_t x, int32_t y, int32_t z, int32_t picnum, int32_t ydim_upper = 0, int32_t ydim_lower = ydim-1) -{ - rotatesprite_(x, y, z, 0, picnum, Menu_CursorShade(), 0, 2|8, 0, 0, 0, ydim_upper, xdim-1, ydim_lower); -} -static void Menu_DrawCursorLeft(int32_t x, int32_t y, int32_t z) -{ - const int frames = RR ? 16 : 7; - Menu_DrawCursorCommon(x, y, z, SPINNINGNUKEICON+(((int32_t) totalclock>>3)%frames)); -} -static void Menu_DrawCursorRight(int32_t x, int32_t y, int32_t z) -{ - const int frames = RR ? 16 : 7; - Menu_DrawCursorCommon(x, y, z, SPINNINGNUKEICON+frames-1-((frames-1+((int32_t) totalclock>>3))%frames)); -} -static void Menu_DrawCursorTextTile(int32_t x, int32_t y, int32_t h, int32_t picnum, vec2_16_t const & siz, int32_t ydim_upper = 0, int32_t ydim_lower = ydim-1) -{ - vec2_t const adjsiz = { siz.x<<15, siz.y<<16 }; - Menu_DrawCursorCommon(x + scale(adjsiz.x, h, adjsiz.y), y, divscale16(h, adjsiz.y), picnum, ydim_upper, ydim_lower); -} -static void Menu_DrawCursorText(int32_t x, int32_t y, int32_t h, int32_t ydim_upper = 0, int32_t ydim_lower = ydim-1) -{ - vec2_16_t const & siz = tilesiz[SPINNINGNUKEICON]; - const int frames = RR ? 16 : 7; - - if (siz.x == 0) - { - Menu_DrawCursorTextTile(x, y, h, SMALLFNTCURSOR, tilesiz[SMALLFNTCURSOR], ydim_upper, ydim_lower); - return; - } - - Menu_DrawCursorTextTile(x, y, h, SPINNINGNUKEICON+(((int32_t) totalclock>>3)%frames), siz, ydim_upper, ydim_lower); -} - - -static uint16_t g_oldSaveCnt; - @@ -392,25 +283,6 @@ static MenuEntry_t *MEL_GAMESETUP[] = { }; #endif -#ifndef EDUKE32_SIMPLE_MENU -MAKE_MENU_TOP_ENTRYLINK( "Game Setup", MEF_OptionsMenu, OPTIONS_GAMESETUP, MENU_GAMESETUP ); -#endif -MAKE_MENU_TOP_ENTRYLINK( "Sound Setup", MEF_OptionsMenu, OPTIONS_SOUNDSETUP, MENU_SOUND ); -MAKE_MENU_TOP_ENTRYLINK( "Display Setup", MEF_OptionsMenu, OPTIONS_DISPLAYSETUP, MENU_DISPLAYSETUP ); -MAKE_MENU_TOP_ENTRYLINK( "Player Setup", MEF_OptionsMenu, OPTIONS_PLAYERSETUP, MENU_PLAYER ); -#ifndef EDUKE32_ANDROID_MENU -MAKE_MENU_TOP_ENTRYLINK( "Control Setup", MEF_OptionsMenu, OPTIONS_CONTROLS, MENU_CONTROLS ); - -MAKE_MENU_TOP_ENTRYLINK( "Configure Controls", MEF_CenterMenu, OPTIONS_KEYBOARDSETUP, MENU_KEYBOARDSETUP ); -MAKE_MENU_TOP_ENTRYLINK( "Mouse Setup", MEF_CenterMenu, OPTIONS_MOUSESETUP, MENU_MOUSESETUP ); -#endif -MAKE_MENU_TOP_ENTRYLINK( "Joystick Setup", MEF_CenterMenu, OPTIONS_JOYSTICKSETUP, MENU_JOYSTICKSETUP ); -#ifdef EDUKE32_ANDROID_MENU -MAKE_MENU_TOP_ENTRYLINK( "Touch Setup", MEF_CenterMenu, OPTIONS_TOUCHSETUP, MENU_TOUCHSETUP ); -#endif -#ifdef EDUKE32_SIMPLE_MENU -MAKE_MENU_TOP_ENTRYLINK("Cheats", MEF_OptionsMenu, OPTIONS_CHEATS, MENU_CHEATS); -#endif // Zhe menu code lacks flexibility, it can either be hardwired to ints or to CVARs. // Since CVARs are more important it means that these need to be implemented as CVARs even though they are just temporaries. @@ -543,32 +415,6 @@ static MenuEntry_t ME_ENTERCHEAT = MAKE_MENUENTRY( "Enter Cheat Code", &MF_Redfo static MenuLink_t MEO_CHEAT_WARP = { MENU_CHEAT_WARP, MA_None, }; static MenuLink_t MEO_CHEAT_SKILL = { MENU_CHEAT_SKILL, MA_None, }; -// KEEPINSYNC game.h: enum CheatCodeFunctions -// KEEPINSYNC game.c: uint8_t CheatFunctionIDs[] -#define MAKE_MENUCHEAT( Name ) MAKE_MENUENTRY( Name, &MF_Bluefont, &MEF_Cheats, &MEO_NULL, Link ) -static MenuEntry_t ME_CheatCodes[] = { - MAKE_MENUCHEAT( "Toggle Cashman" ), - MAKE_MENUCHEAT( "Toggle God Mode" ), - MAKE_MENUCHEAT( "Give Everything" ), - MAKE_MENUCHEAT( "Give Weapons" ), - MAKE_MENUCHEAT( "Give All Items" ), - MAKE_MENUCHEAT( "Give Inventory" ), - MAKE_MENUCHEAT( "Give Keys" ), - MAKE_MENUCHEAT( "Toggle Hyper" ), - MAKE_MENUCHEAT( "Toggle 3rd-Person View" ), - MAKE_MENUCHEAT( "Toggle Show All Map" ), - MAKE_MENUCHEAT( "Toggle All Locks" ), - MAKE_MENUCHEAT( "Toggle Clipping" ), - MAKE_MENUENTRY( "Level Warp", &MF_Bluefont, &MEF_Cheats, &MEO_CHEAT_WARP, Link ), - MAKE_MENUENTRY( "Change Skill", &MF_Bluefont, &MEF_Cheats, &MEO_CHEAT_SKILL, Link ), - MAKE_MENUCHEAT( "Toggle Monsters" ), - MAKE_MENUCHEAT( "Toggle Framerate Display" ), - MAKE_MENUCHEAT( NULL ), - MAKE_MENUCHEAT( NULL ), - MAKE_MENUCHEAT( NULL ), - MAKE_MENUCHEAT( "Toggle Coordinate Display" ), - MAKE_MENUCHEAT( "Toggle Debug Data Dump" ), -}; static MenuEntry_t *MEL_OPTIONS[] = { #ifndef EDUKE32_SIMPLE_MENU @@ -746,39 +592,7 @@ static MenuEntry_t *MEL_MOUSESETUP[] = { #endif }; -#ifdef EDUKE32_ANDROID_MENU -static MenuRangeFloat_t MEO_TOUCHSETUP_SENSITIVITY_MOVE = MAKE_MENURANGE(&droidinput.forward_sens, &MF_Redfont, 1.f, 9.f, 0.f, 17, 1 + EnforceIntervals); -static MenuEntry_t ME_TOUCHSETUP_SENSITIVITY_MOVE = MAKE_MENUENTRY("Running:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_TOUCHSETUP_SENSITIVITY_MOVE, RangeFloat); -static MenuRangeFloat_t MEO_TOUCHSETUP_SENSITIVITY_STRAFE = MAKE_MENURANGE(&droidinput.strafe_sens, &MF_Redfont, 1.f, 9.f, 0.f, 17, 1 + EnforceIntervals); -static MenuEntry_t ME_TOUCHSETUP_SENSITIVITY_STRAFE = MAKE_MENUENTRY("Strafing:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_TOUCHSETUP_SENSITIVITY_STRAFE, RangeFloat); - -static MenuRangeFloat_t MEO_TOUCHSETUP_SENSITIVITY_LOOK = MAKE_MENURANGE(&droidinput.pitch_sens, &MF_Redfont, 1.f, 9.f, 0.f, 17, 1 + EnforceIntervals); -static MenuEntry_t ME_TOUCHSETUP_SENSITIVITY_LOOK = MAKE_MENUENTRY("Looking:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_TOUCHSETUP_SENSITIVITY_LOOK, RangeFloat); - -static MenuRangeFloat_t MEO_TOUCHSETUP_SENSITIVITY_TURN = MAKE_MENURANGE(&droidinput.yaw_sens, &MF_Redfont, 1.f, 9.f, 0.f, 17, 1 + EnforceIntervals); -static MenuEntry_t ME_TOUCHSETUP_SENSITIVITY_TURN = MAKE_MENUENTRY("Turning:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_TOUCHSETUP_SENSITIVITY_TURN, RangeFloat); - -static MenuOption_t MEO_TOUCHSETUP_INVERT = MAKE_MENUOPTION(&MF_Redfont, &MEOS_NoYes, &droidinput.invertLook); -static MenuEntry_t ME_TOUCHSETUP_INVERT = MAKE_MENUENTRY("Invert look:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_TOUCHSETUP_INVERT, Option); - -MAKE_MENU_TOP_ENTRYLINK("Sensitivity", MEF_CenterMenu, TOUCHSENS, MENU_TOUCHSENS); -MAKE_MENU_TOP_ENTRYLINK("Button Setup", MEF_CenterMenu, TOUCHBUTTONS, MENU_TOUCHBUTTONS); - -static MenuEntry_t *MEL_TOUCHSETUP [] = { - &ME_TOUCHSENS, - &ME_TOUCHBUTTONS, -}; - -static MenuEntry_t *MEL_TOUCHSENS [] = { - &ME_TOUCHSETUP_SENSITIVITY_MOVE, - &ME_TOUCHSETUP_SENSITIVITY_STRAFE, - &ME_TOUCHSETUP_SENSITIVITY_LOOK, - &ME_TOUCHSETUP_SENSITIVITY_TURN, - &ME_Space2_Redfont, - &ME_TOUCHSETUP_INVERT, -}; -#endif static MenuOption_t MEO_JOYSTICK_ENABLE = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &in_joystick ); static MenuEntry_t ME_JOYSTICK_ENABLE = MAKE_MENUENTRY( "Enable Gamepad:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_JOYSTICK_ENABLE, Option ); @@ -931,21 +745,7 @@ static MenuEntry_t *MEL_SCREENSETUP[] = { &ME_SCREENSETUP_SHOWPICKUPMESSAGES, }; -// Save and load will be filled in before every viewing of the save/load screen. -static MenuLink_t MEO_LOAD = { MENU_LOADVERIFY, MA_None, }; -static MenuEntry_t ME_LOAD_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Minifont, &MEF_LoadSave, &MEO_LOAD, Link ); -static MenuEntry_t ME_LOAD_EMPTY = MAKE_MENUENTRY( NULL, &MF_Minifont, &MEF_LoadSave, nullptr, Dummy ); -static MenuEntry_t *ME_LOAD; -static MenuEntry_t **MEL_LOAD; -static char const s_NewSaveGame[] = "(New Save Game)"; -static MenuString_t MEO_SAVE_TEMPLATE = MAKE_MENUSTRING( NULL, &MF_Minifont, MAXSAVEGAMENAME, 0 ); -static MenuString_t MEO_SAVE_NEW = MAKE_MENUSTRING( NULL, &MF_Minifont, MAXSAVEGAMENAME, 0 ); -static MenuString_t *MEO_SAVE; -static MenuEntry_t ME_SAVE_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Minifont, &MEF_LoadSave, &MEO_SAVE_TEMPLATE, String ); -static MenuEntry_t ME_SAVE_NEW = MAKE_MENUENTRY( s_NewSaveGame, &MF_Minifont, &MEF_LoadSave, &MEO_SAVE_NEW, String ); -static MenuEntry_t *ME_SAVE; -static MenuEntry_t **MEL_SAVE; CVAR_UNAMED(Int, soundrate) CVAR_UNAMED(Int, soundvoices) @@ -979,51 +779,7 @@ static MenuRangeInt32_t MEO_SOUND_NUMVOICES = MAKE_MENURANGE( &soundvoices, &MF_ static MenuEntry_t ME_SOUND_NUMVOICES = MAKE_MENUENTRY( "Voices:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_NUMVOICES, RangeInt32 ); #endif -static char const *MEOSN_SOUND_MIDIDRIVER[] = { - "OPL3", -#ifdef _WIN32 - "Windows", -#endif -}; -static int32_t MEOSV_SOUND_MIDIDRIVER[] = { - ASS_OPL3, -#ifdef _WIN32 - ASS_WinMM, -#endif -}; -static MenuOptionSet_t MEOS_SOUND_MIDIDRIVER = MAKE_MENUOPTIONSET( MEOSN_SOUND_MIDIDRIVER, MEOSV_SOUND_MIDIDRIVER, 0x2 ); -static MenuOption_t MEO_SOUND_MIDIDRIVER = MAKE_MENUOPTION( &MF_Redfont, &MEOS_SOUND_MIDIDRIVER, &musicdevice ); -static MenuEntry_t ME_SOUND_MIDIDRIVER = MAKE_MENUENTRY( "MIDI driver:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_MIDIDRIVER, Option ); - -static MenuEntry_t ME_SOUND_RESTART = MAKE_MENUENTRY( "Apply Changes", &MF_Redfont, &MEF_BigOptions_Apply, &MEO_NULL, Link ); - -#ifndef EDUKE32_SIMPLE_MENU -static MenuLink_t MEO_ADVSOUND = { MENU_ADVSOUND, MA_Advance, }; -static MenuEntry_t ME_SOUND_ADVSOUND = MAKE_MENUENTRY( "Advanced", &MF_Redfont, &MEF_BigOptionsRt, &MEO_ADVSOUND, Link ); -#endif - -static MenuEntry_t *MEL_SOUND[] = { - &ME_SOUND, - &ME_SOUND_VOLUME_FX, - &ME_SOUND_MUSIC, - &ME_SOUND_VOLUME_MUSIC, - &ME_SOUND_DUKETALK, -#ifndef EDUKE32_SIMPLE_MENU - &ME_SOUND_ADVSOUND, -#endif -}; - -static MenuEntry_t *MEL_ADVSOUND[] = { - &ME_SOUND_SAMPLINGRATE, - &ME_Space2_Redfont, -#ifndef EDUKE32_SIMPLE_MENU - &ME_SOUND_NUMVOICES, - &ME_Space2_Redfont, -#endif - &ME_SOUND_MIDIDRIVER, - &ME_SOUND_RESTART, -}; static MenuEntry_t ME_CDPLAYER_TRACK = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_Null, &MEO_NULL, Dummy); @@ -1231,41 +987,6 @@ static MenuPanel_t M_STORY = { NoTitle, MENU_STORY, MA_Return, MENU_STORY, MA_Ad static MenuPanel_t M_STORY = { NoTitle, MENU_F1HELP, MA_Return, MENU_F1HELP, MA_Advance, }; #endif -static MenuPanel_t M_F1HELP = { NoTitle, MENU_STORY, MA_Return, MENU_STORY, MA_Advance, }; -static MenuPanel_t M_F1HELP2 = { NoTitle, MENU_F1HELP, MA_Return, MENU_STORY, MA_Advance, }; -static MenuPanel_t M_CREDITS = { NoTitle, MENU_CREDITS33, MA_Return, MENU_CREDITS2, MA_Advance, }; -static MenuPanel_t M_CREDITS2 = { NoTitle, MENU_CREDITS, MA_Return, MENU_CREDITS3, MA_Advance, }; -static MenuPanel_t M_CREDITS3 = { NoTitle, MENU_CREDITS2, MA_Return, MENU_CREDITS31, MA_Advance, }; -static MenuPanel_t M_CREDITS4 = { s_Credits, MENU_CREDITS3, MA_Return, MENU_CREDITS5, MA_Advance, }; -static MenuPanel_t M_CREDITS5 = { s_Credits, MENU_CREDITS4, MA_Return, MENU_CREDITS6, MA_Advance, }; -static MenuPanel_t M_CREDITS6 = { s_Credits, MENU_CREDITS5, MA_Return, MENU_CREDITS7, MA_Advance, }; -static MenuPanel_t M_CREDITS7 = { s_Credits, MENU_CREDITS6, MA_Return, MENU_CREDITS8, MA_Advance, }; -static MenuPanel_t M_CREDITS8 = { s_Credits, MENU_CREDITS7, MA_Return, MENU_CREDITS9, MA_Advance, }; -static MenuPanel_t M_CREDITS9 = { s_Credits, MENU_CREDITS8, MA_Return, MENU_CREDITS10, MA_Advance, }; -static MenuPanel_t M_CREDITS10 = { s_Credits, MENU_CREDITS9, MA_Return, MENU_CREDITS11, MA_Advance, }; -static MenuPanel_t M_CREDITS11 = { s_Credits, MENU_CREDITS10, MA_Return, MENU_CREDITS12, MA_Advance, }; -static MenuPanel_t M_CREDITS12 = { s_Credits, MENU_CREDITS11, MA_Return, MENU_CREDITS13, MA_Advance, }; -static MenuPanel_t M_CREDITS13 = { s_Credits, MENU_CREDITS12, MA_Return, MENU_CREDITS14, MA_Advance, }; -static MenuPanel_t M_CREDITS14 = { s_Credits, MENU_CREDITS13, MA_Return, MENU_CREDITS15, MA_Advance, }; -static MenuPanel_t M_CREDITS15 = { s_Credits, MENU_CREDITS14, MA_Return, MENU_CREDITS16, MA_Advance, }; -static MenuPanel_t M_CREDITS16 = { s_Credits, MENU_CREDITS15, MA_Return, MENU_CREDITS17, MA_Advance, }; -static MenuPanel_t M_CREDITS17 = { s_Credits, MENU_CREDITS16, MA_Return, MENU_CREDITS18, MA_Advance, }; -static MenuPanel_t M_CREDITS18 = { s_Credits, MENU_CREDITS17, MA_Return, MENU_CREDITS19, MA_Advance, }; -static MenuPanel_t M_CREDITS19 = { s_Credits, MENU_CREDITS18, MA_Return, MENU_CREDITS20, MA_Advance, }; -static MenuPanel_t M_CREDITS20 = { s_Credits, MENU_CREDITS19, MA_Return, MENU_CREDITS21, MA_Advance, }; -static MenuPanel_t M_CREDITS21 = { s_Credits, MENU_CREDITS20, MA_Return, MENU_CREDITS22, MA_Advance, }; -static MenuPanel_t M_CREDITS22 = { s_Credits, MENU_CREDITS21, MA_Return, MENU_CREDITS23, MA_Advance, }; -static MenuPanel_t M_CREDITS23 = { s_Credits, MENU_CREDITS22, MA_Return, MENU_CREDITS24, MA_Advance, }; -static MenuPanel_t M_CREDITS24 = { s_Credits, MENU_CREDITS23, MA_Return, MENU_CREDITS25, MA_Advance, }; -static MenuPanel_t M_CREDITS25 = { s_Credits, MENU_CREDITS24, MA_Return, MENU_CREDITS26, MA_Advance, }; -static MenuPanel_t M_CREDITS26 = { s_Credits, MENU_CREDITS25, MA_Return, MENU_CREDITS27, MA_Advance, }; -static MenuPanel_t M_CREDITS27 = { s_Credits, MENU_CREDITS26, MA_Return, MENU_CREDITS28, MA_Advance, }; -static MenuPanel_t M_CREDITS28 = { s_Credits, MENU_CREDITS27, MA_Return, MENU_CREDITS29, MA_Advance, }; -static MenuPanel_t M_CREDITS29 = { s_Credits, MENU_CREDITS28, MA_Return, MENU_CREDITS30, MA_Advance, }; -static MenuPanel_t M_CREDITS30 = { s_Credits, MENU_CREDITS29, MA_Return, MENU_CREDITS31, MA_Advance, }; -static MenuPanel_t M_CREDITS31 = { "About " APPNAME, MENU_CREDITS3, MA_Return, MENU_CREDITS32, MA_Advance, }; -static MenuPanel_t M_CREDITS32 = { "About EDuke32", MENU_CREDITS31, MA_Return, MENU_CREDITS33, MA_Advance, }; -static MenuPanel_t M_CREDITS33 = { "About EDuke32", MENU_CREDITS32, MA_Return, MENU_CREDITS, MA_Advance, }; #define CURSOR_CENTER_2LINE { MENU_MARGIN_CENTER<<16, 120<<16, } #define CURSOR_CENTER_3LINE { MENU_MARGIN_CENTER<<16, 129<<16, } @@ -1355,39 +1076,6 @@ static Menu_t Menus[] = { { &M_CHEATENTRY, MENU_CHEATENTRY, MENU_CHEATS, MA_None, TextForm }, { &M_CHEAT_WARP, MENU_CHEAT_WARP, MENU_CHEATS, MA_None, TextForm }, { &M_CHEAT_SKILL, MENU_CHEAT_SKILL, MENU_CHEATS, MA_None, TextForm }, - { &M_CREDITS, MENU_CREDITS, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS2, MENU_CREDITS2, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS3, MENU_CREDITS3, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS4, MENU_CREDITS4, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS5, MENU_CREDITS5, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS6, MENU_CREDITS6, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS7, MENU_CREDITS7, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS8, MENU_CREDITS8, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS9, MENU_CREDITS9, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS10, MENU_CREDITS10, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS11, MENU_CREDITS11, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS12, MENU_CREDITS12, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS13, MENU_CREDITS13, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS14, MENU_CREDITS14, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS15, MENU_CREDITS15, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS16, MENU_CREDITS16, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS17, MENU_CREDITS17, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS18, MENU_CREDITS18, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS19, MENU_CREDITS19, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS20, MENU_CREDITS20, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS21, MENU_CREDITS21, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS22, MENU_CREDITS22, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS23, MENU_CREDITS23, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS24, MENU_CREDITS24, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS25, MENU_CREDITS25, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS26, MENU_CREDITS26, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS27, MENU_CREDITS27, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS28, MENU_CREDITS28, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS29, MENU_CREDITS29, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS30, MENU_CREDITS30, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS31, MENU_CREDITS31, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS32, MENU_CREDITS32, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS33, MENU_CREDITS33, MENU_MAIN, MA_Return, Panel }, { &M_LOADVERIFY, MENU_LOADVERIFY, MENU_LOAD, MA_None, Verify }, { &M_LOADDELVERIFY, MENU_LOADDELVERIFY, MENU_LOAD, MA_None, Verify }, { &M_NEWVERIFY, MENU_NEWVERIFY, MENU_PREVIOUS, MA_Return, Verify }, @@ -1405,67 +1093,6 @@ static Menu_t Menus[] = { { &M_NETJOIN, MENU_NETJOIN, MENU_NETWORK, MA_Return, Menu }, }; -static CONSTEXPR const uint16_t numMenus = ARRAY_SIZE(Menus); - -Menu_t *m_currentMenu = &Menus[0]; -static Menu_t *m_previousMenu = &Menus[0]; -static Menu_t * m_parentMenu; - -MenuID_t g_currentMenu; -static MenuID_t g_previousMenu; - -#define MenuMenu_ChangeEntryList(m, el)\ - do {\ - m.entrylist = el;\ - m.numEntries = ARRAY_SIZE(el);\ - } while (0) - -static void MenuEntry_DisableOnCondition(MenuEntry_t * const entry, const int32_t condition) -{ - if (condition) - entry->flags |= MEF_Disabled; - else - entry->flags &= ~MEF_Disabled; -} -static void MenuEntry_LookDisabledOnCondition(MenuEntry_t * const entry, const int32_t condition) -{ - if (condition) - entry->flags |= MEF_LookDisabled; - else - entry->flags &= ~MEF_LookDisabled; -} -static void MenuEntry_HideOnCondition(MenuEntry_t * const entry, const int32_t condition) -{ - if (condition) - entry->flags |= MEF_Hidden; - else - entry->flags &= ~MEF_Hidden; -} - -static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *currentry, int32_t state, vec2_t origin, bool actually_draw = true); -static void Menu_EntryFocus(/*MenuEntry_t *entry*/); - -static MenuEntry_t *Menu_AdjustForCurrentEntryAssignment(MenuMenu_t *menu) -{ - MenuEntry_t *currentry = menu->entrylist[menu->currentEntry]; - - Menu_EntryFocus(/*currentry*/); - - if (currentry->ybottom - menu->scrollPos > klabs(menu->format->bottomcutoff)) - menu->scrollPos = currentry->ybottom - klabs(menu->format->bottomcutoff); - else if (currentry->ytop - menu->scrollPos < menu->format->pos.y) - menu->scrollPos = currentry->ytop - menu->format->pos.y; - - return currentry; -} - -static MenuEntry_t *Menu_AdjustForCurrentEntryAssignmentBlind(MenuMenu_t *menu) -{ - M_RunMenu_Menu(nullptr, menu, nullptr, 0, { 0, 0 }, false); - return Menu_AdjustForCurrentEntryAssignment(menu); -} - -static int32_t SELECTDIR_z = 65536; /* This function prepares data after ART and CON have been processed. @@ -1756,291 +1383,6 @@ void Menu_Init(void) } } -static void Menu_Run(Menu_t *cm, vec2_t origin); - - -static void Menu_BlackRectangle(int32_t x, int32_t y, int32_t width, int32_t height, int32_t orientation); - -/* -At present, no true difference is planned between Menu_Pre() and Menu_PreDraw(). -They are separate for purposes of organization. -*/ - -static void Menu_Pre(MenuID_t cm) -{ - int32_t i; - DukePlayer_t *ps = g_player[myconnectindex].ps; - - switch (cm) - { - case MENU_MAIN_INGAME: - MenuEntry_DisableOnCondition(&ME_MAIN_LOADGAME, (RRRA && ud.player_skill == 4) || (RR && !RRRA && ud.player_skill == 5)); - MenuEntry_DisableOnCondition(&ME_MAIN_SAVEGAME, ud.recstat == 2 || (RRRA && ud.player_skill == 4) || (RR && !RRRA && ud.player_skill == 5)); - MenuEntry_DisableOnCondition(&ME_MAIN_QUITTOTITLE, g_netServer || numplayers > 1); - fallthrough__; - case MENU_MAIN: - if ((g_netServer || ud.multimode > 1) && ud.recstat != 2) - { - ME_MAIN_NEWGAME.entry = &MEO_MAIN_NEWGAME_NETWORK; - ME_MAIN_NEWGAME_INGAME.entry = &MEO_MAIN_NEWGAME_NETWORK; - } - else - { - ME_MAIN_NEWGAME.entry = &MEO_MAIN_NEWGAME; - ME_MAIN_NEWGAME_INGAME.entry = &MEO_MAIN_NEWGAME_INGAME; - } - break; - - case MENU_GAMESETUP: - MEO_GAMESETUP_DEMOREC.options = (ps->gm&MODE_GAME) ? &MEOS_DemoRec : &MEOS_OffOn; - MenuEntry_DisableOnCondition(&ME_GAMESETUP_DEMOREC, (ps->gm&MODE_GAME) && m_recstat != 1); - break; - -#ifdef USE_OPENGL - case MENU_DISPLAYSETUP: - if (videoGetRenderMode() == REND_CLASSIC) - MenuMenu_ChangeEntryList(M_DISPLAYSETUP, MEL_DISPLAYSETUP); -#ifdef POLYMER - else if (videoGetRenderMode() == REND_POLYMER) - MenuMenu_ChangeEntryList(M_DISPLAYSETUP, MEL_DISPLAYSETUP_GL_POLYMER); -#endif - else - MenuMenu_ChangeEntryList(M_DISPLAYSETUP, MEL_DISPLAYSETUP_GL); - - MEO_SCREENSETUP_SCREENSIZE.steps = !(ud.statusbarflags & STATUSBAR_NONONE) + - !(ud.statusbarflags & STATUSBAR_NOMODERN) + - !(ud.statusbarflags & STATUSBAR_NOMINI) + - !(ud.statusbarflags & STATUSBAR_NOOVERLAY) + - !(ud.statusbarflags & STATUSBAR_NOFULL) + - !(ud.statusbarflags & STATUSBAR_NOSHRINK) * 14; - MEO_SCREENSETUP_SCREENSIZE.max = MEO_SCREENSETUP_SCREENSIZE.steps - 1; - MenuEntry_DisableOnCondition(&ME_SCREENSETUP_SCREENSIZE, (MEO_SCREENSETUP_SCREENSIZE.steps < 2)); - - if (videoGetRenderMode() != REND_CLASSIC) - { - //POGOTODO: allow setting anisotropy again while hw_useindexedcolortextures is set when support is added down the line - // don't allow setting anisotropy or changing palette emulation while in POLYMOST and hw_useindexedcolortextures is enabled - MenuEntry_DisableOnCondition(&ME_DISPLAYSETUP_ANISOTROPY, videoGetRenderMode() == REND_POLYMOST && hw_useindexedcolortextures); -#ifdef EDUKE32_SIMPLE_MENU - MenuEntry_DisableOnCondition(&ME_DISPLAYSETUP_PALETTEEMULATION, videoGetRenderMode() == REND_POLYMOST && hw_useindexedcolortextures); -#endif - - for (i = (int32_t) ARRAY_SIZE(MEOSV_DISPLAYSETUP_ANISOTROPY) - 1; i >= 0; --i) - { - if (MEOSV_DISPLAYSETUP_ANISOTROPY[i] <= GLInterface.glinfo.maxanisotropy) - { - MEOS_DISPLAYSETUP_ANISOTROPY.numOptions = i + 1; - break; - } - } - } - break; - - case MENU_POLYMER: - case MENU_POLYMOST: - MenuEntry_DisableOnCondition(&ME_RENDERERSETUP_PRECACHE, !hw_hightile); -# ifdef USE_GLEXT - MenuEntry_DisableOnCondition(&ME_RENDERERSETUP_DETAILTEX, !hw_hightile); - MenuEntry_DisableOnCondition(&ME_RENDERERSETUP_GLOWTEX, !hw_hightile); -# endif - break; -#endif - - case MENU_VIDEOSETUP: - { - const int32_t nr = newresolution; - - // don't allow setting fullscreen mode if it's not supported by the resolution - MenuEntry_DisableOnCondition(&ME_VIDEOSETUP_FULLSCREEN, !(resolution[nr].flags & RES_FS)); - - MenuEntry_DisableOnCondition(&ME_VIDEOSETUP_APPLY, - (xres == resolution[nr].xdim && yres == resolution[nr].ydim && - videoGetRenderMode() == newrendermode && fullscreen == newfullscreen - && vid_vsync == newvsync - ) - || (newrendermode != REND_CLASSIC && resolution[nr].bppmax <= 8)); - - break; - } - - case MENU_SOUND: - case MENU_SOUND_INGAME: - case MENU_ADVSOUND: - MenuEntry_DisableOnCondition(&ME_SOUND_VOLUME_FX, !snd_enabled); - MenuEntry_DisableOnCondition(&ME_SOUND_VOLUME_MUSIC, !mus_enabled); - MenuEntry_DisableOnCondition(&ME_SOUND_DUKETALK, !snd_enabled); - MenuEntry_DisableOnCondition(&ME_SOUND_SAMPLINGRATE, !snd_enabled && !mus_enabled); -#ifndef EDUKE32_SIMPLE_MENU - MenuEntry_DisableOnCondition(&ME_SOUND_NUMVOICES, !snd_enabled); -#endif - MenuEntry_DisableOnCondition(&ME_SOUND_RESTART, soundrate == snd_mixrate && - soundvoices == snd_numvoices); - break; - - case MENU_SAVESETUP: - MenuEntry_DisableOnCondition(&ME_SAVESETUP_MAXAUTOSAVES, !cl_autosavedeletion); - break; - -#ifndef EDUKE32_SIMPLE_MENU - case MENU_MOUSESETUP: - MenuEntry_DisableOnCondition(&ME_MOUSESETUP_MOUSEAIMING, in_aimmode); - break; -#endif - case MENU_NETOPTIONS: - if (MEOSV_NetEpisodes[MEO_NETOPTIONS_EPISODE.currentOption] == MAXVOLUMES) - MEL_NETOPTIONS[2] = &ME_NETOPTIONS_USERMAP; - else - { - MEL_NETOPTIONS[2] = &ME_NETOPTIONS_LEVEL; - MEO_NETOPTIONS_LEVEL.options = &MEOS_NETOPTIONS_LEVEL[MEOSV_NetEpisodes[MEO_NETOPTIONS_EPISODE.currentOption]]; - } - if (!(g_gametypeFlags[m_coop] & GAMETYPE_MARKEROPTION)) - { - ME_NETOPTIONS_MARKERS.type = Dummy; - ME_NETOPTIONS_MARKERS.flags |= MEF_Disabled; - } - else - { - ME_NETOPTIONS_MARKERS.type = Option; - ME_NETOPTIONS_MARKERS.flags &= ~MEF_Disabled; - } - MEL_NETOPTIONS[5] = (g_gametypeFlags[m_coop] & (GAMETYPE_PLAYERSFRIENDLY|GAMETYPE_TDM)) ? &ME_NETOPTIONS_FRFIRE : &ME_NETOPTIONS_MAPEXITS; - break; - - case MENU_OPTIONS: - MenuEntry_DisableOnCondition(&ME_OPTIONS_PLAYERSETUP, ud.recstat == 1); - MenuEntry_HideOnCondition(&ME_OPTIONS_JOYSTICKSETUP, !in_joystick || CONTROL_JoyPresent == 0); - break; - - case MENU_COLCORR: - case MENU_COLCORR_INGAME: - break; - - case MENU_CHEATS: - case MENU_CHEATENTRY: - case MENU_CHEAT_WARP: - case MENU_CHEAT_SKILL: - { - const int32_t menucheatsdisabled = numplayers != 1 || !(g_player[myconnectindex].ps->gm & MODE_GAME); - - // refresh display names of quote cheats - ME_CheatCodes[CHEATFUNC_QUOTEBETA].name = apStrings[QUOTE_CHEAT_BETA]; - ME_CheatCodes[CHEATFUNC_QUOTETODD].name = apStrings[QUOTE_CHEAT_TODD]; - ME_CheatCodes[CHEATFUNC_QUOTEALLEN].name = apStrings[QUOTE_CHEAT_ALLEN]; - - for (i = 0; i < NUMCHEATFUNCS; i++) - { - uint32_t cheatmask = cl_cheatmask & (1<= (int32_t)g_nummenusaves) - { - menutext_centeralign(origin.x + (101<<16), origin.y + (97<<16), "Empty"); - break; - } - - menusave_t & msv = g_menusaves[M_LOAD.currentEntry]; - - if (msv.brief.isValid()) - { - rotatesprite_fs(origin.x + (101<<16), origin.y + (97<<16), 65536>>1,512,TILE_LOADSHOT,-32,0,4+10+64); - - if (msv.isOldVer) - { - menutext_centeralign(origin.x + (101<<16), origin.y + (97<<16), "Previous\nVersion"); - -#ifndef EDUKE32_SIMPLE_MENU - Bsprintf(tempbuf,"Saved: %d.%d.%d.%u %d-bit", savehead.majorver, savehead.minorver, - savehead.bytever, savehead.userbytever, 8*savehead.getPtrSize()); - mgametext(origin.x + (31<<16), origin.y + (104<<16), tempbuf); - Bsprintf(tempbuf,"Our: %d.%d.%d.%u %d-bit", SV_MAJOR_VER, SV_MINOR_VER, BYTEVERSION, - ud.userbytever, (int32_t)(8*sizeof(intptr_t))); - mgametext(origin.x + ((31+16)<<16), origin.y + (114<<16), tempbuf); -#endif - - break; - } - - if (savehead.numplayers > 1) - { - Bsprintf(tempbuf, "Players: %-2d ", savehead.numplayers); - mgametextcenter(origin.x, origin.y + (156<<16), tempbuf); - } - - { - const char *name = g_mapInfo[(savehead.volnum*MAXLEVELS) + savehead.levnum].name; - Bsprintf(tempbuf, "%s / %s", name ? name : "^10unnamed^0", gSkillNames[savehead.skill-1].GetChars()); - } - - mgametextcenter(origin.x, origin.y + (168<<16), tempbuf); - if (savehead.volnum == 0 && savehead.levnum == 7) - mgametextcenter(origin.x, origin.y + (180<<16), savehead.boardfn); - } - break; - } - - case MENU_SAVE: - { -#if 0 - for (i = 0; i <= 108; i += 12) - rotatesprite_fs(origin.x + ((160+64+91-64)<<16), origin.y + ((i+56)<<16), 65536L,0,TEXTBOX,24,0,10); -#endif - Menu_BlackRectangle(origin.x + (198<<16), origin.y + (47<<16), 102<<16, 100<<16, 1|32); - - rotatesprite_fs(origin.x + (22<<16), origin.y + (97<<16), 65536L,0,WINDOWBORDER2,24,0,10); - rotatesprite_fs(origin.x + (180<<16), origin.y + (97<<16), 65536L,1024,WINDOWBORDER2,24,0,10); - rotatesprite_fs(origin.x + (99<<16), origin.y + (50<<16), 65536L,512,WINDOWBORDER1,24,0,10); - rotatesprite_fs(origin.x + (103<<16), origin.y + (144<<16), 65536L,1024+512,WINDOWBORDER1,24,0,10); - - j = 0; - for (int k = 0; k < g_nummenusaves+1; ++k) - if (((MenuString_t*)M_SAVE.entrylist[k]->entry)->editfield) - j |= 1; - - if (j) - rotatesprite_fs(origin.x + (101<<16), origin.y + (97<<16), 65536L>>1,512,TILE_SAVESHOT,-32,0,4+10+64); - else if (0 < M_SAVE.currentEntry && M_SAVE.currentEntry <= (int32_t)g_nummenusaves) - { - if (g_menusaves[M_SAVE.currentEntry-1].brief.isValid()) - { - rotatesprite_fs(origin.x + (101<<16), origin.y + (97<<16), 65536L>>1,512,TILE_LOADSHOT,-32,0,4+10+64); - - if (g_menusaves[M_SAVE.currentEntry-1].isOldVer) - { - menutext_centeralign(origin.x + (101<<16), origin.y + (97<<16), "Previous\nVersion"); - -#ifndef EDUKE32_SIMPLE_MENU - Bsprintf(tempbuf,"Saved: %d.%d.%d.%u %d-bit", savehead.majorver, savehead.minorver, - savehead.bytever, savehead.userbytever, 8*savehead.getPtrSize()); - mgametext(origin.x + (31<<16), origin.y + (104<<16), tempbuf); - Bsprintf(tempbuf,"Our: %d.%d.%d.%u %d-bit", SV_MAJOR_VER, SV_MINOR_VER, BYTEVERSION, - ud.userbytever, (int32_t)(8*sizeof(intptr_t))); - mgametext(origin.x + ((31+16)<<16), origin.y + (114<<16), tempbuf); -#endif - - break; - } - } - } - else - menutext_centeralign(origin.x + (101<<16), origin.y + (97<<16), "New"); - - if (ud.multimode > 1) - { - Bsprintf(tempbuf, "Players: %-2d ", ud.multimode); - mgametextcenter(origin.x, origin.y + (156<<16), tempbuf); - } - - Bsprintf(tempbuf,"%s / %s",g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name, gSkillNames[ud.player_skill-1].GetChars()); - mgametextcenter(origin.x, origin.y + (168<<16), tempbuf); - if (ud.volume_number == 0 && ud.level_number == 7) - mgametextcenter(origin.x, origin.y + (180<<16), currentboardfilename); - break; - } - -#ifdef EDUKE32_ANDROID_MENU - case MENU_SKILL: - { - static const char *s[] = { "EASY - Few enemies, and lots of stuff.", "MEDIUM - Normal difficulty.", "HARD - For experienced players.", "EXPERTS - Lots of enemies, plus they respawn!" }; - if (M_SKILL.currentEntry < ARRAY_SSIZE(s)) - mgametextcenter(origin.x, origin.y + (168<<16), s[M_SKILL.currentEntry]); - } - break; -#endif - - case MENU_SAVECLEANVERIFY: - videoFadeToBlack(1); - - if (g_oldSaveCnt) - { - Bsprintf(tempbuf, "Delete %d obsolete saves?\nThis action cannot be undone." -#ifndef EDUKE32_ANDROID_MENU - "\n(Y/N)" -#endif - , g_oldSaveCnt); - } - else - Bsprintf(tempbuf, "No obsolete saves found!"); - - mgametextcenter(origin.x, origin.y + (90<<16), tempbuf); - break; - - case MENU_LOADVERIFY: - { - videoFadeToBlack(1); - menusave_t & msv = g_menusaves[M_LOAD.currentEntry]; - if (msv.isOldVer) - { - Bsprintf(tempbuf, "Start new game:\n%s / %s" -#ifndef EDUKE32_ANDROID_MENU - "\n(Y/N)" -#endif - , g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name, gSkillNames[ud.player_skill-1].GetChars()); - mgametextcenter(origin.x, origin.y + (90<<16), tempbuf); - } - else - { - Bsprintf(tempbuf, "Load game:\n\"%s\"" -#ifndef EDUKE32_ANDROID_MENU - "\n(Y/N)" -#endif - , msv.brief.name); - mgametextcenter(origin.x, origin.y + (90<<16), tempbuf); - } - break; - } - - case MENU_SAVEVERIFY: - videoFadeToBlack(1); - mgametextcenter(origin.x, origin.y + (90<<16), "Overwrite previous saved game?" -#ifndef EDUKE32_ANDROID_MENU - "\n(Y/N)" -#endif - ); - break; - - case MENU_LOADDELVERIFY: - case MENU_SAVEDELVERIFY: - { - videoFadeToBlack(1); - menusave_t & msv = cm == MENU_LOADDELVERIFY ? g_menusaves[M_LOAD.currentEntry] : g_menusaves[M_SAVE.currentEntry-1]; - Bsprintf(tempbuf, "Delete saved game:\n\"%s\"?" -#ifndef EDUKE32_ANDROID_MENU - "\n(Y/N)" -#endif - , msv.brief.name); - mgametextcenter(origin.x, origin.y + (90<<16), tempbuf); - break; - } case MENU_NEWVERIFY: videoFadeToBlack(1); @@ -2385,563 +1535,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) mgametextcenter(origin.x, origin.y + ((148+16)<<16), "Press any key or button..."); break; - case MENU_CREDITS: - case MENU_CREDITS2: - case MENU_CREDITS3: - case MENU_CREDITS4: - case MENU_CREDITS5: - case MENU_CREDITS6: - case MENU_CREDITS7: - case MENU_CREDITS8: - case MENU_CREDITS9: - case MENU_CREDITS10: - case MENU_CREDITS11: - case MENU_CREDITS12: - case MENU_CREDITS13: - case MENU_CREDITS14: - case MENU_CREDITS15: - case MENU_CREDITS16: - case MENU_CREDITS17: - case MENU_CREDITS18: - case MENU_CREDITS19: - case MENU_CREDITS20: - case MENU_CREDITS21: - case MENU_CREDITS22: - case MENU_CREDITS23: - case MENU_CREDITS24: - case MENU_CREDITS25: - case MENU_CREDITS26: - case MENU_CREDITS27: - case MENU_CREDITS28: - case MENU_CREDITS29: - case MENU_CREDITS30: - if (RR) - { - if (RRRA) - { - switch (cm) - { - case MENU_CREDITS: - mgametextcenter(origin.x, origin.y + (80<<16), "ORIGINAL CONCEPT, DESIGN AND DIRECTION\n\n" - "DREW MARKHAM"); - break; - - case MENU_CREDITS2: - mgametextcenter(origin.x, origin.y + (80<<16), "ART DIRECTION AND ADDITIONAL DESIGN\n\n" - "CORKY LEHMKUHL"); - break; - - case MENU_CREDITS3: - mgametextcenter(origin.x, origin.y + (80<<16), "PRODUCED BY\n\n" - "GREG GOODRICH"); - break; - - case MENU_CREDITS4: - mgametextcenter(origin.x, origin.y + (80<<16), "GAME PROGRAMMING\n\n" - "JOSEPH AURILI"); - break; - - case MENU_CREDITS5: - mgametextcenter(origin.x, origin.y + (80<<16), "ORIGINAL GAME PROGRAMMING\n\n" - "RAFAEL PAIZ"); - break; - - case MENU_CREDITS6: - mgametextcenter(origin.x, origin.y + (80<<16), "LEVEL DESIGN\n\n" - "RHETT BALDWIN & AARON BARBER"); - break; - - case MENU_CREDITS7: - mgametextcenter(origin.x, origin.y + (80<<16), "ORIGINAL ART DIRECTION AND SUPPORT\n\n" - "MAXX KAUFMAN & CLAIRE PRADERIE-MARKHAM"); - break; - - case MENU_CREDITS8: - mgametextcenter(origin.x, origin.y + (80<<16), "COMPUTER GRAPHICS SUPERVISOR &\n" - "CHARACTER ANIMATION DIRECTION\n\n" - "BARRY DEMPSEY"); - break; - - case MENU_CREDITS9: - mgametextcenter(origin.x, origin.y + (80<<16), "SENIOR ANIMATOR & MODELER\n\n" - "JASON HOOVER"); - break; - - case MENU_CREDITS10: - mgametextcenter(origin.x, origin.y + (80<<16), "CHARACTER ANIMATION &\n" - "MOTION CAPTURE SPECIALIST\n\n" - "AMIT DORON"); - break; - - case MENU_CREDITS11: - mgametextcenter(origin.x, origin.y + (80<<16), "SOUND DESIGN &\n" - "MUSIC PRODUCTION COORDINATION\n\n" - "GARY BRADFIELD"); - break; - - case MENU_CREDITS12: - mgametextcenter(origin.x, origin.y + (80<<16), "INTRODUCTION ANIMATION\n\n" - "DOMINIQUE DROZDZ"); - break; - - case MENU_CREDITS13: - mgametextcenter(origin.x, origin.y + (80<<16), "ARTIST\n\n" - "MATTHIAS BEEGUER"); - break; - - case MENU_CREDITS14: - mgametextcenter(origin.x, origin.y + (80<<16), "ADDITIONAL ART\n\n" - "VIKTOR ANTONOV"); - break; - - case MENU_CREDITS15: - mgametextcenter(origin.x, origin.y + (80<<16), "PRODUCTION COORDINATOR\n\n" - "VICTORIA SYLVESTER"); - break; - - case MENU_CREDITS16: - mgametextcenter(origin.x, origin.y + (40<<16), "CHARACTER VOICES\n\n" - "LEONARD\n" - "BURTON GILLIAM\n\n" - "DAISY MAE\n" - "TARA CHARENDOFF\n\n" - "BUBBA, BILLY RAY, SKINNY OL' COOT,\n" - "FRANK THE BIKER, THE TURD MINION\n" - "& ALL OTHER VARIOUS RAMBLINGS...\n" - "DREW MARKHAM"); - break; - - case MENU_CREDITS17: - mgametextcenter(origin.x, origin.y + (70<<16), "SPECIAL APPEARENCE BY\n\n" - "SHERIFF LESTER T. HOBBES\n" - "MOJO NIXON\n\n" - "ALIEN VIXEN\n" - "PEGGY JO JACOBS"); - break; - - case MENU_CREDITS18: - mgametextcenter(origin.x, origin.y + (70<<16), "REDNECK RAMPAGE TITLE TRACK & CYBERSEX\n" - "WRITTEN & PERFORMED BY\n" - "MOJO NIXON\n\n" - "(c) MUFFIN'STUFFIN' MUSIC (BMI)\n" - "ADMINISTERED BY BUG."); - break; - - case MENU_CREDITS19: - mgametextcenter(origin.x, origin.y + (60<<16), "MUSIC\n\n" - "DISGRACELAND\n" - "TINY D & THE SOFA KINGS\n\n" - "BANJO AND GUITAR PICKIN\n" - "JOHN SCHLOCKER\n" - "HOWARD YEARWOOD"); - break; - - case MENU_CREDITS20: - mgametextcenter(origin.x, origin.y + (80<<16), "RECORDING ENGINEER\n" - "DAVE AHLERT\n\n" - "RECORDING ASSISTANCE\n" - "JEFF GILBERT"); - break; - - case MENU_CREDITS21: - mgametextcenter(origin.x, origin.y + (80<<16), "MOTION CAPTURE ACTOR\n" - "J.P. MANOUX\n\n" - "MOTION CAPTURE ACTRESS\n" - "SHAWN WOLFE"); - break; - - case MENU_CREDITS22: - mgametextcenter(origin.x, origin.y + (50<<16), "THIS GAME COULD NOT HAVE BEEN MADE WITHOUT\n" - "ALEX MAYBERRY\n" - "MAL BLACKWELL\n\n" - "NUTS AND BOLTS\n" - "STEVE GOLDBERG\n\n" - "BEAN COUNTING\n" - "MAX YOSHIKAWA\n\n" - "ADMINISTRATIVE ASSISTANCE\n" - "MINERVA MAYBERRY"); - break; - - case MENU_CREDITS23: - mgametextcenter(origin.x, origin.y + (60<<16), "FOR INTERPLAY\n\n" - "PRODUCER\n" - "BILL DUGAN\n\n" - "LINE PRODUCER\n" - "CHRIS BENSON\n\n" - "LEAD TESTER\n" - "DARRELL JONES"); - break; - - case MENU_CREDITS24: - mgametextcenter(origin.x, origin.y + (70<<16), "TESTERS\n\n" - "TIM ANDERSON\n" - "PRIMO PULANCO\n" - "MARK MCCARTY\n" - "BRIAN AXLINE"); - break; - - case MENU_CREDITS25: - mgametextcenter(origin.x, origin.y + (80<<16), "PRODUCTION BABY\n\n" - "PAULINE MARIE MARKHAM"); - break; - - case MENU_CREDITS26: - mgametextcenter(origin.x, origin.y + (80<<16), "ORIGINAL PRODUCTION BABY\n\n" - "ALYSON KAUFMAN"); - break; - - case MENU_CREDITS27: - mgametextcenter(origin.x, origin.y + (80<<16), "3D BUILD ENGINE LICENSED FROM\n" - "3D REALMS ENTERTAINMENT\n\n" - "BUILD ENGINE AND RELATED TOOLS\n" - "CREATED BY KEN SILVERMAN"); - break; - - case MENU_CREDITS28: - mgametextcenter(origin.x, origin.y + (80<<16), "SPECIAL THANKS\n\n" - "SCOTT MILLER\n" - "GEORGE BROUSSARD"); - break; - - case MENU_CREDITS29: - mgametextcenter(origin.x, origin.y + (80<<16), "EXTRA SPECIAL THANKS\n\n" - "BRIAN FARGO"); - break; - - case MENU_CREDITS30: - mgametextcenter(origin.x, origin.y + (70<<16), "REDNECK RAMPAGE RIDES AGAIN\n" - "(c) 1998 XATRIX ENTERTAINMENT, INC.\n\n" - "REDNECK RAMPAGE RIDES AGAIN\n" - "IS A TRADEMARK OF\n" - "INTERPLAY PRODUCTIONS"); - break; - } - } - else - { - switch (cm) - { - case MENU_CREDITS: - mgametextcenter(origin.x, origin.y + (80<<16), "ORIGINAL CONCEPT, DESIGN AND DIRECTION\n\n" - "DREW MARKHAM"); - break; - - case MENU_CREDITS2: - mgametextcenter(origin.x, origin.y + (80<<16), "PRODUCED BY\n\n" - "GREG GOODRICH"); - break; - - case MENU_CREDITS3: - mgametextcenter(origin.x, origin.y + (80<<16), "GAME PROGRAMMING\n\n" - "RAFAEL PAIZ"); - break; - - case MENU_CREDITS4: - mgametextcenter(origin.x, origin.y + (80<<16), "ART DIRECTORS\n\n" - "CLAIRE PRADERIE MAXX KAUFMAN "); - break; - - case MENU_CREDITS5: - mgametextcenter(origin.x, origin.y + (80<<16), "LEAD LEVEL DESIGNER\n" - "ALEX MAYBERRY\n\n" - "LEVEL DESIGN\n" - "MAL BLACKWELL\n" - "SVERRE KVERNMO"); - break; - - case MENU_CREDITS6: - mgametextcenter(origin.x, origin.y + (80<<16), "SENIOR ANIMATOR AND ARTIST\n\n" - "JASON HOOVER"); - break; - - case MENU_CREDITS7: - mgametextcenter(origin.x, origin.y + (80<<16), "TECHNICAL DIRECTOR\n\n" - "BARRY DEMPSEY"); - break; - - case MENU_CREDITS8: - mgametextcenter(origin.x, origin.y + (60<<16), "MOTION CAPTURE SPECIALIST AND\n" - "CHARACTER ANIMATION\n" - "AMIT DORON\n\n" - "A.I. PROGRAMMING\n" - "ARTHUR DONAVAN\n\n" - "ADDITIONAL ANIMATION\n" - "GEORGE KARL"); - break; - - case MENU_CREDITS9: - mgametextcenter(origin.x, origin.y + (50<<16), "CHARACTER DESIGN\n" - "CORKY LEHMKUHL\n\n" - "MAP PAINTERS\n" - "VIKTOR ANTONOV\n" - "MATTHIAS BEEGUER\n" - "STEPHAN BURLE\n\n" - "SCULPTORS\n" - "GEORGE ENGEL\n" - "JAKE GARBER\n" - "JEFF HIMMEL"); - break; - - case MENU_CREDITS10: - mgametextcenter(origin.x, origin.y + (40<<16), "CHARACTER VOICES\n\n" - "LEONARD\n" - "BURTON GILLIAM\n\n" - "BUBBA, BILLY RAY, SKINNY OL' COOT\n" - "AND THE TURD MINION\n" - "DREW MARKHAM\n\n" - "SHERIFF LESTER T. HOBBES\n" - "MOJO NIXON\n\n" - "ALIEN VIXEN\n" - "PEGGY JO JACOBS"); - break; - - case MENU_CREDITS11: - mgametextcenter(origin.x, origin.y + (50<<16), "SOUND DESIGN\n" - "GARY BRADFIELD\n\n" - "MUSIC\n" - "MOJO NIXON\n" - "THE BEAT FARMERS\n" - "THE REVEREND HORTON HEAT\n" - "CEMENT POND\n\n" - "ADDITIONAL SOUND EFFECTS\n" - "JIM SPURGIN"); - break; - - case MENU_CREDITS12: - mgametextcenter(origin.x, origin.y + (80<<16), "MOTION CAPTURE ACTOR\n" - "J.P. MANOUX\n\n" - "MOTION CAPTURE VIXEN\n" - "SHAWN WOLFE"); - break; - - case MENU_CREDITS13: - mgametextcenter(origin.x, origin.y + (50<<16), "PRODUCTION ASSISTANCE\n" - "MINERVA MAYBERRY\n\n" - "NUTS AND BOLTS\n" - "STEVE GOLDBERG\n" - "MARCUS HUTCHINSON\n\n" - "BEAN COUNTING\n" - "MAX YOSHIKAWA\n\n" - "ADMINISTRATIVE ASSISTANCE\n" - "SERAFIN LEWIS"); - break; - - case MENU_CREDITS14: - mgametextcenter(origin.x, origin.y + (70<<16), "LOCATION MANAGER, LOUISIANA\n" - "RICK SKINNER\n\n" - "LOCATION SCOUT, LOUISIANA\n" - "BRIAN BENOS\n\n" - "PHOTOGRAPHER\n" - "CARLOS SERRAO"); - break; - - case MENU_CREDITS15: - mgametextcenter(origin.x, origin.y + (50<<16), "ADDITIONAL 3D MODELING BY\n" - "3 NAME 3D\n" - "VIEWPOINT DATALABS INTERNATIONAL\n\n" - "AUDIO RECORDED AT\n" - "PACIFIC OCEAN POST, SANTA MONICA, C.A.\n\n" - "CEMENT POND TRACKS RECORDED AT\n" - "DREAMSTATE RECORDING, BURBANK, C.A.\n\n" - "RECORDING ENGINEER\n" - "DAVE AHLERT"); - break; - - case MENU_CREDITS16: - mgametextcenter(origin.x, origin.y + (80<<16), "3D BUILD ENGINE LICENSED FROM\n" - "3D REALMS ENTERTAINMENT\n\n" - "BUILD ENGINE AND RELATED TOOLS\n" - "CREATED BY KEN SILVERMAN"); - break; - - case MENU_CREDITS17: - mgametextcenter(origin.x, origin.y + (60<<16), "FOR INTERPLAY\n\n" - "LEAD TESTER\n" - "DARRELL JONES\n\n" - "TESTERS\n" - "TIM ANDERSON\n" - "ERICK LUJAN\n" - "TIEN TRAN"); - break; - - case MENU_CREDITS18: - mgametextcenter(origin.x, origin.y + (60<<16), "IS TECHS\n" - "BILL DELK\n" - "AARON MEYERS\n\n" - "COMPATIBILITY TECHS\n" - "MARC DURAN\n" - "DAN FORSYTH\n" - "DEREK GIBBS\n" - "AARON OLAIZ\n" - "JACK PARKER"); - break; - - case MENU_CREDITS19: - mgametextcenter(origin.x, origin.y + (70<<16), "DIRECTOR OF COMPATIBILITY\n" - "PHUONG NGUYEN\n\n" - "ASSISTANT QA DIRECTOR\n" - "COLIN TOTMAN\n\n" - "QA DIRECTOR\n" - "CHAD ALLISON"); - break; - - case MENU_CREDITS20: - mgametextcenter(origin.x, origin.y + (50<<16), "INTERPLAY PRODUCER\n" - "BILL DUGAN\n\n" - "INTERPLAY LINE PRODUCER\n" - "CHRIS BENSON\n\n" - "PRODUCT MANAGER\n" - "JIM VEEVAERT\n\n" - "PUBLIC RELATIONS\n" - "ERIKA PRICE"); - break; - - case MENU_CREDITS21: - mgametextcenter(origin.x, origin.y + (60<<16), "SPECIAL THANKS\n\n" - "JIM GAUER\n" - "PAUL VAIS\n" - "SCOTT MILLER\n" - "TODD REPLOGLE\n" - "CHUCK BUECHE\n" - "CARTER LIPSCOMB\n" - "JOHN CONLEY\n" - "DON MAGGI"); - break; - - case MENU_CREDITS22: - mgametextcenter(origin.x, origin.y + (80<<16), "EXTRA SPECIAL THANKS\n\n" - "BRIAN FARGO"); - break; - - case MENU_CREDITS23: - mgametextcenter(origin.x, origin.y + (60<<16), "REDNECK RAMPAGE\n" - "(c) 1997 XATRIX ENTERTAINMENT, INC.\n\n" - "REDNECK RAMPAGE IS A TRADEMARK OF\n" - "INTERPLAY PRODUCTIONS"); - break; - } - } - } - else if (!VOLUMEALL || !PLUTOPAK) - { - int32_t m; - switch (cm) - { - case MENU_CREDITS: - m = origin.x + (20<<16); - l = origin.y + (33<<16); - - shadowminitext(m, l, "Original Concept", 12); l += 7<<16; - shadowminitext(m, l, "Todd Replogle and Allen H. Blum III", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Produced & Directed By", 12); l += 7<<16; - shadowminitext(m, l, "Greg Malone", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Executive Producer", 12); l += 7<<16; - shadowminitext(m, l, "George Broussard", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "BUILD Engine", 12); l += 7<<16; - shadowminitext(m, l, "Ken Silverman", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Game Programming", 12); l += 7<<16; - shadowminitext(m, l, "Todd Replogle", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "3D Engine/Tools/Net", 12); l += 7<<16; - shadowminitext(m, l, "Ken Silverman", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Network Layer/Setup Program", 12); l += 7<<16; - shadowminitext(m, l, "Mark Dochtermann", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Map Design", 12); l += 7<<16; - shadowminitext(m, l, "Allen H. Blum III", 12); l += 7<<16; - shadowminitext(m, l, "Richard Gray", 12); l += 7<<16; - - m = origin.x + (180<<16); - l = origin.y + (33<<16); - - shadowminitext(m, l, "3D Modeling", 12); l += 7<<16; - shadowminitext(m, l, "Chuck Jones", 12); l += 7<<16; - shadowminitext(m, l, "Sapphire Corporation", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Artwork", 12); l += 7<<16; - shadowminitext(m, l, "Dirk Jones, Stephen Hornback", 12); l += 7<<16; - shadowminitext(m, l, "James Storey, David Demaret", 12); l += 7<<16; - shadowminitext(m, l, "Douglas R. Wood", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Sound Engine", 12); l += 7<<16; - shadowminitext(m, l, "Jim Dose", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Sound & Music Development", 12); l += 7<<16; - shadowminitext(m, l, "Robert Prince", 12); l += 7<<16; - shadowminitext(m, l, "Lee Jackson", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Voice Talent", 12); l += 7<<16; - shadowminitext(m, l, "Lani Minella - Voice Producer", 12); l += 7<<16; - shadowminitext(m, l, "Jon St. John as \"Duke Nukem\"", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Graphic Design", 12); l += 7<<16; - shadowminitext(m, l, "Packaging, Manual, Ads", 12); l += 7<<16; - shadowminitext(m, l, "Robert M. Atkins", 12); l += 7<<16; - shadowminitext(m, l, "Michael Hadwin", 12); l += 7<<16; - break; - - case MENU_CREDITS2: - m = origin.x + (20<<16); - l = origin.y + (33<<16); - - shadowminitext(m, l, "Special Thanks To", 12); l += 7<<16; - shadowminitext(m, l, "Steven Blackburn, Tom Hall", 12); l += 7<<16; - shadowminitext(m, l, "Scott Miller, Joe Siegler", 12); l += 7<<16; - shadowminitext(m, l, "Terry Nagy, Colleen Compton", 12); l += 7<<16; - shadowminitext(m, l, "HASH, Inc., FormGen, Inc.", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "The 3D Realms Beta Testers", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Nathan Anderson, Wayne Benner", 12); l += 7<<16; - shadowminitext(m, l, "Glenn Brensinger, Rob Brown", 12); l += 7<<16; - shadowminitext(m, l, "Erik Harris, Ken Heckbert", 12); l += 7<<16; - shadowminitext(m, l, "Terry Herrin, Greg Hively", 12); l += 7<<16; - shadowminitext(m, l, "Hank Leukart, Eric Baker", 12); l += 7<<16; - shadowminitext(m, l, "Jeff Rausch, Kelly Rogers", 12); l += 7<<16; - shadowminitext(m, l, "Mike Duncan, Doug Howell", 12); l += 7<<16; - shadowminitext(m, l, "Bill Blair", 12); l += 7<<16; - - m = origin.x + (160<<16); - l = origin.y + (33<<16); - - shadowminitext(m, l, "Company Product Support", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "The following companies were cool", 12); l += 7<<16; - shadowminitext(m, l, "enough to give us lots of stuff", 12); l += 7<<16; - shadowminitext(m, l, "during the making of Duke Nukem 3D.", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Altec Lansing Multimedia", 12); l += 7<<16; - shadowminitext(m, l, "for tons of speakers and the", 12); l += 7<<16; - shadowminitext(m, l, "THX-licensed sound system.", 12); l += 7<<16; - shadowminitext(m, l, "For info call 1-800-548-0620", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Creative Labs, Inc.", 12); l += 7<<16; - l += 3<<16; - shadowminitext(m, l, "Thanks for the hardware, guys.", 12); l += 7<<16; - break; - - case MENU_CREDITS3: - mgametextcenter(origin.x, origin.y + (50<<16), "Duke Nukem 3D is a trademark of\n" - "3D Realms Entertainment" - "\n" - "Duke Nukem 3D\n" - "(C) 1996 3D Realms Entertainment"); - - if (VOLUMEONE) - { - mgametextcenter(origin.x, origin.y + (106<<16), "Please read LICENSE.DOC for shareware\n" - "distribution grants and restrictions."); - } - mgametextcenter(origin.x, origin.y + ((VOLUMEONE?134:115)<<16), "Made in Dallas, Texas USA"); - break; - } - } - break; case MENU_CREDITS31: l = 7; @@ -3065,4374 +1658,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) } -static void Menu_ReadSaveGameHeaders(); - -static void Menu_LoadReadHeaders() -{ - Menu_ReadSaveGameHeaders(); - - for (int i = 0; i < g_nummenusaves; ++i) - MenuEntry_DisableOnCondition(&ME_LOAD[i], g_menusaves[i].isOldVer); -} - -static void Menu_SaveReadHeaders() -{ - Menu_ReadSaveGameHeaders(); - - for (int i = 0; i < g_nummenusaves; ++i) - MenuEntry_LookDisabledOnCondition(&ME_SAVE[i], g_menusaves[i].isOldVer); -} - -static void Menu_PreInput(MenuEntry_t *entry) -{ - switch (g_currentMenu) - { - - case MENU_KEYBOARDKEYS: - if (inputState.GetKeyStatus(sc_Delete)) - { - Bindings.UnbindACommand(buttonMap.GetButtonName(M_KEYBOARDKEYS.currentEntry)); - S_PlaySound(RR ? 335 : KICK_HIT); - inputState.ClearKeyStatus(sc_Delete); - } - break; - - case MENU_LOAD: - if (inputState.GetKeyStatus(sc_Delete)) - { - inputState.ClearKeyStatus(sc_Delete); - if (M_LOAD.currentEntry < g_nummenusaves) - Menu_Change(MENU_LOADDELVERIFY); - } - break; - case MENU_SAVE: - if (inputState.GetKeyStatus(sc_Delete)) - { - inputState.ClearKeyStatus(sc_Delete); - if (0 < M_SAVE.currentEntry && M_SAVE.currentEntry <= (int32_t)g_nummenusaves) - Menu_Change(MENU_SAVEDELVERIFY); - } - break; - - default: - break; - } -} - -static void Menu_PreOptionListDraw(MenuEntry_t *entry, const vec2_t origin) -{ - switch (g_currentMenu) - { - case MENU_MOUSEBTNS: - case MENU_MOUSEADVANCED: - case MENU_JOYSTICKBTNS: - case MENU_JOYSTICKAXIS: - mgametextcenter(origin.x, origin.y + (31<<16), "Select a function to assign"); - - Bsprintf(tempbuf, "to %s", entry->name); - - mgametextcenter(origin.x, origin.y + ((31+9)<<16), tempbuf); - - mgametextcenter(origin.x, origin.y + (161<<16), "Press \"Escape\" To Cancel"); - break; - } -} - -static int32_t Menu_PreCustom2ColScreen(MenuEntry_t *entry) -{ - if (g_currentMenu == MENU_KEYBOARDKEYS) - { - auto *column = (MenuCustom2Col_t*)entry->entry; - - int32_t sc = inputState.GetLastScanCode(); - if (sc != sc_None) - { - S_PlaySound(PISTOL_BODYHIT); - *column->column[M_KEYBOARDKEYS.currentColumn] = sc; - Bindings.SetBind(sc, buttonMap.GetButtonName(M_KEYBOARDKEYS.currentEntry)); - inputState.ClearKeyStatus(sc); - - return -1; - } - } - - return 0; -} - -static void Menu_PreCustom2ColScreenDraw(MenuEntry_t *entry, const vec2_t origin) -{ - if (g_currentMenu == MENU_KEYBOARDKEYS) - { - Bsprintf(tempbuf, "Press the key to assign as\n" - "%s for \"%s\"\n" - "\n" - "Press \"Escape\" To Cancel" - , M_KEYBOARDKEYS.currentColumn?"secondary":"primary", entry->name); - mgametextcenter(origin.x, origin.y + (90<<16), tempbuf); - } -} - -static void Menu_EntryFocus(/*MenuEntry_t *entry*/) -{ - switch (g_currentMenu) - { - case MENU_LOAD: - if (M_LOAD.currentEntry < (int32_t)g_nummenusaves) - { - savebrief_t & sv = g_menusaves[M_LOAD.currentEntry].brief; - if (sv.isValid()) - G_LoadSaveHeaderNew(sv.path, &savehead); - } - break; - - case MENU_SAVE: - if (0 < M_SAVE.currentEntry && M_SAVE.currentEntry <= (int32_t)g_nummenusaves) - { - savebrief_t & sv = g_menusaves[M_SAVE.currentEntry-1].brief; - if (sv.isValid()) - G_LoadSaveHeaderNew(sv.path, &savehead); - } - break; - - default: - break; - } -} - -static void Menu_StartGameWithoutSkill(void) -{ - ud.m_player_skill = M_SKILL.currentEntry+1; - - g_skillSoundVoice = S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - - ud.m_respawn_monsters = 0; - - ud.m_monsters_off = ud.monsters_off = 0; - - ud.m_respawn_items = 0; - ud.m_respawn_inventory = 0; - - ud.multimode = 1; - - G_NewGame_EnterLevel(); -} - -static void Menu_DoCheat(int32_t cheatID) -{ - if (numplayers != 1 || !(g_player[myconnectindex].ps->gm & MODE_GAME)) - return; - - osdcmd_cheatsinfo_stat.cheatnum = cheatID; -} - -static int32_t Menu_Cheat_Warp(char const * const numbers) -{ - if (numplayers != 1 || !(g_player[myconnectindex].ps->gm & MODE_GAME)) - return 0; - - if (numbers == NULL || !numbers[0] || !numbers[1] || (VOLUMEALL && !numbers[2])) - return 1; - - if (VOLUMEALL) - { - osdcmd_cheatsinfo_stat.volume = numbers[0] - '0'; - osdcmd_cheatsinfo_stat.level = (numbers[1] - '0')*10+(numbers[2]-'0'); - } - else - { - osdcmd_cheatsinfo_stat.volume = numbers[0] - '0'; - osdcmd_cheatsinfo_stat.level = numbers[1] - '0'; - } - - osdcmd_cheatsinfo_stat.volume--; - osdcmd_cheatsinfo_stat.level--; - - if ((VOLUMEONE && osdcmd_cheatsinfo_stat.volume > 0) || osdcmd_cheatsinfo_stat.volume > g_volumeCnt-1 || - osdcmd_cheatsinfo_stat.level >= MAXLEVELS || g_mapInfo[osdcmd_cheatsinfo_stat.volume *MAXLEVELS+osdcmd_cheatsinfo_stat.level].filename == NULL) - return 1; - - osdcmd_cheatsinfo_stat.cheatnum = CHEAT_SCOTTY; - - return 0; -} - -static int32_t Menu_Cheat_Skill(char const * const number) -{ - if (numplayers != 1 || !(g_player[myconnectindex].ps->gm & MODE_GAME)) - return 0; - - if (number == NULL || !number[0]) - return 1; - - osdcmd_cheatsinfo_stat.volume = number[0] - '1'; - - osdcmd_cheatsinfo_stat.cheatnum = CHEAT_SKILL; - - return 0; -} - -/* -Functions where a "newValue" or similar is passed are run *before* the linked variable is actually changed. -That way you can compare the new and old values and potentially block the change. -*/ -static void Menu_EntryLinkActivate(MenuEntry_t *entry) -{ - switch (g_currentMenu) - { - case MENU_EPISODE: - if (entry != &ME_EPISODE_USERMAP) - { - ud.m_volume_number = M_EPISODE.currentEntry; - m_level_number = 0; - - if (g_skillCnt == 0) - Menu_StartGameWithoutSkill(); - } - break; - - case MENU_SKILL: - { - int32_t skillsound = RR ? 341 : PISTOL_BODYHIT; - - if (RR) - switch (M_SKILL.currentEntry) - { - case 0: - skillsound = 427; - break; - case 1: - skillsound = 428; - break; - case 2: - skillsound = 196; - break; - case 3: - skillsound = 195; - break; - case 4: - skillsound = 197; - break; - } - else - switch (M_SKILL.currentEntry) - { - case 0: - skillsound = JIBBED_ACTOR6; - break; - case 1: - skillsound = BONUS_SPEECH1; - break; - case 2: - skillsound = DUKE_GETWEAPON2; - break; - case 3: - skillsound = JIBBED_ACTOR5; - break; - } - - ud.m_player_skill = M_SKILL.currentEntry+(RRRA ? 0 : 1); - - g_skillSoundVoice = S_PlaySound(skillsound); - - if (M_SKILL.currentEntry == 3) ud.m_respawn_monsters = 1; - else ud.m_respawn_monsters = 0; - - ud.m_monsters_off = ud.monsters_off = 0; - - ud.m_respawn_items = 0; - ud.m_respawn_inventory = 0; - - ud.multimode = 1; - - G_NewGame_EnterLevel(); - break; - } - - case MENU_JOYSTICKAXES: - M_JOYSTICKAXIS.title = joyGetName(0, M_JOYSTICKAXES.currentEntry); -#if 0 - MEO_JOYSTICKAXIS_ANALOG.data = &JoystickAnalogueAxes[M_JOYSTICKAXES.currentEntry]; - MEO_JOYSTICKAXIS_SCALE.variable = &JoystickAnalogueScale[M_JOYSTICKAXES.currentEntry]; - MEO_JOYSTICKAXIS_DEAD.variable = &JoystickAnalogueDead[M_JOYSTICKAXES.currentEntry]; - MEO_JOYSTICKAXIS_SATU.variable = &JoystickAnalogueSaturate[M_JOYSTICKAXES.currentEntry]; - MEO_JOYSTICKAXIS_DIGITALNEGATIVE.data = &JoystickDigitalFunctions[M_JOYSTICKAXES.currentEntry][0]; - MEO_JOYSTICKAXIS_DIGITALPOSITIVE.data = &JoystickDigitalFunctions[M_JOYSTICKAXES.currentEntry][1]; -#endif - break; - - case MENU_CHEATS: - { - const int32_t cheatFuncID = M_CHEATS.currentEntry - 1; - switch (cheatFuncID) - { - case -1: - case CHEATFUNC_WARP: - case CHEATFUNC_SKILL: - break; - default: - Menu_DoCheat(CheatFunctionIDs[cheatFuncID]); - break; - } - break; - } - - default: - break; - } - - if (entry == &ME_VIDEOSETUP_APPLY) - { - resolution_t p = { xres, yres, fullscreen, bpp, 0 }; - int32_t prend = videoGetRenderMode(); - int32_t pvsync = vid_vsync; - - resolution_t n = { resolution[newresolution].xdim, resolution[newresolution].ydim, - (resolution[newresolution].flags & RES_FS) ? newfullscreen : 0, - (newrendermode == REND_CLASSIC) ? 8 : resolution[newresolution].bppmax, 0 }; - int32_t nrend = newrendermode; - int32_t nvsync = newvsync; - - if (videoSetGameMode(n.flags, n.xdim, n.ydim, n.bppmax, upscalefactor) < 0) - { - if (videoSetGameMode(p.flags, p.xdim, p.ydim, p.bppmax, upscalefactor) < 0) - { - videoSetRenderMode(prend); - G_GameExit("Failed restoring old video mode."); - } - else - { - onvideomodechange(p.bppmax > 8); - vid_vsync = videoSetVsync(pvsync); - } - } - else onvideomodechange(n.bppmax > 8); - - g_restorePalette = -1; - G_UpdateScreenArea(); - videoSetRenderMode(nrend); - vid_vsync = videoSetVsync(nvsync); - ScreenMode = fullscreen; - ScreenWidth = xres; - ScreenHeight = yres; - ScreenBPP = bpp; - } - else if (entry == &ME_SOUND_RESTART) - { - snd_mixrate = soundrate; - snd_numvoices = soundvoices; - - S_SoundShutdown(); - - S_SoundStartup(); - - FX_StopAllSounds(); - S_ClearSoundLocks(); - } - else if (entry == &ME_SAVESETUP_CLEANUP) - { - Menu_Change(MENU_SAVECLEANVERIFY); - } - else if (entry == &ME_COLCORR_RESET) - { - vid_gamma = 1.f; - vid_contrast = 1.f; - vid_brightness = 0.f; - r_ambientlight = 1.f; - videoSetPalette(0,g_player[myconnectindex].ps->palette,0); - } - else if (entry == &ME_KEYBOARDSETUP_RESET) - CONFIG_SetDefaultKeys("demolition/defbinds.txt"); - else if (entry == &ME_KEYBOARDSETUP_RESETCLASSIC) - CONFIG_SetDefaultKeys("demolition/origbinds.txt"); - else if (entry == &ME_NETHOST_LAUNCH) - { - // master does whatever it wants - if (g_netServer) - { - Net_FillNewGame(&pendingnewgame, 1); - Net_SendNewGame(1, NULL); - Net_StartNewGame(); - } - else if (voting == -1) - { - Net_SendMapVoteInitiate(); - Menu_Change(MENU_NETWAITVOTES); - } - } -} - -static int32_t Menu_EntryOptionModify(MenuEntry_t *entry, int32_t newOption) -{ - int32_t x; - DukePlayer_t *ps = g_player[myconnectindex].ps; - - if (entry == &ME_GAMESETUP_DEMOREC) - { - if ((ps->gm&MODE_GAME)) - G_CloseDemoWrite(); - } - else if (entry == &ME_GAMESETUP_WEAPSWITCH_PICKUP) - { - ud.weaponswitch = ud.weaponswitch & ~(1|4); - switch (newOption) - { - case 2: - ud.weaponswitch = ud.weaponswitch | 4; - fallthrough__; - case 1: - ud.weaponswitch = ud.weaponswitch | 1; - break; - default: - break; - } - } - else if (entry == &ME_SOUND) - { - if (newOption == 0) - { - FX_StopAllSounds(); - S_ClearSoundLocks(); - } - } - else if (entry == &ME_SOUND_MUSIC || entry == &ME_CDPLAYER_TRACK) - { - mus_enabled = newOption; - - if (newOption == 0) - S_PauseMusic(true); - else - { - S_PauseMusic(false); - } - } - else if (entry == &ME_SOUND_DUKETALK) - snd_speech = (snd_speech&~1) | newOption; - else if (entry == &ME_JOYSTICKAXIS_ANALOG) - CONTROL_MapAnalogAxis(M_JOYSTICKAXES.currentEntry, newOption, controldevice_joystick); - else if (entry == &ME_NETOPTIONS_EPISODE) - { - if (newOption < g_volumeCnt) - ud.m_volume_number = newOption; - } - else if (entry == &ME_NETOPTIONS_MONSTERS) - { - ud.m_monsters_off = (newOption == g_skillCnt); - if (newOption < g_skillCnt) - ud.m_player_skill = newOption; - } - else if (entry == &ME_ADULTMODE) - { - if (newOption) - { - for (x=0; x>1, newOption, i&1, controldevice_joystick); - } - break; - } - - return 0; -} - -static void Menu_EntryOptionDidModify(MenuEntry_t *entry) -{ -#ifdef USE_OPENGL - int domodechange = 0; -#endif - - if (entry == &ME_GAMESETUP_AIM_AUTO || - entry == &ME_GAMESETUP_WEAPSWITCH_PICKUP || - //entry == &ME_PLAYER_NAME || - entry == &ME_PLAYER_COLOR || - entry == &ME_PLAYER_TEAM) - G_UpdatePlayerFromMenu(); -#ifdef USE_OPENGL - else if (entry == &ME_DISPLAYSETUP_ANISOTROPY || entry == &ME_DISPLAYSETUP_TEXFILTER) - gltexapplyprops(); - - if (domodechange) - { - videoResetMode(); - if (videoSetGameMode(fullscreen, xres, yres, bpp, upscalefactor)) - OSD_Printf("restartvid: Reset failed...\n"); - onvideomodechange(ScreenBPP>8); - G_RefreshLights(); - } -#endif -} - -static void Menu_Custom2ColScreen(/*MenuEntry_t *entry*/) -{ - if (g_currentMenu == MENU_KEYBOARDKEYS) - { - inputState.keyFlushChars(); - inputState.ClearLastScanCode(); - } -} - -static int32_t Menu_EntryRangeInt32Modify(MenuEntry_t *entry, int32_t newValue) -{ - if (entry == &ME_SCREENSETUP_SBARSIZE) - G_SetStatusBarScale(newValue); - else if (entry == &ME_SOUND_VOLUME_FX) - FX_SetVolume(newValue); - else if (entry == &ME_JOYSTICKAXIS_SCALE) - CONTROL_SetAnalogAxisScale(M_JOYSTICKAXES.currentEntry, newValue, controldevice_joystick); - else if (entry == &ME_JOYSTICKAXIS_DEAD) - joySetDeadZone(M_JOYSTICKAXES.currentEntry, newValue, *MEO_JOYSTICKAXIS_SATU.cVar); - else if (entry == &ME_JOYSTICKAXIS_SATU) - joySetDeadZone(M_JOYSTICKAXES.currentEntry, *MEO_JOYSTICKAXIS_DEAD.cVar, newValue); - - return 0; -} - -static int32_t Menu_EntryRangeFloatModify(MenuEntry_t *entry, float newValue) -{ -#ifndef EDUKE32_SIMPLE_MENU - if (entry == &ME_COLCORR_AMBIENT) - r_ambientlightrecip = 1.f/newValue; -#else - UNREFERENCED_PARAMETER(entry); - UNREFERENCED_PARAMETER(newValue); -#endif - - return 0; -} - -static int32_t Menu_EntryRangeFloatDidModify(MenuEntry_t *entry) -{ - return 0; -} - -#ifdef MENU_ENABLE_RANGEDOUBLE -static int32_t Menu_EntryRangeDoubleModify(void /*MenuEntry_t *entry, double newValue*/) -{ - - return 0; -} -#endif - -static uint32_t save_xxh = 0; - -static void Menu_EntryStringActivate(/*MenuEntry_t *entry*/) -{ - switch (g_currentMenu) - { - case MENU_SAVE: - if (M_SAVE.currentEntry > 0) - { - savebrief_t & sv = g_menusaves[M_SAVE.currentEntry-1].brief; - if (!save_xxh) - save_xxh = SuperFastHash(sv.name, MAXSAVEGAMENAME); - if (sv.isValid()) - Menu_Change(MENU_SAVEVERIFY); - } - else - { - ME_SAVE_NEW.name = nullptr; - save_xxh = 0; - } - break; - - default: - break; - } -} - -static int32_t Menu_EntryStringSubmit(/*MenuEntry_t *entry, */char *input) -{ - int32_t returnvar = 0; - - switch (g_currentMenu) - { - case MENU_SAVE: - { - savebrief_t & sv = g_lastusersave = M_SAVE.currentEntry == 0 ? savebrief_t{input} : g_menusaves[M_SAVE.currentEntry-1].brief; - - // dirty hack... char 127 in last position indicates an auto-filled name -#ifdef __ANDROID__ - if (1) -#else - if (input[0] == 0 || (sv.name[MAXSAVEGAMENAME] == 127 && - strncmp(sv.name, input, MAXSAVEGAMENAME) == 0 && - save_xxh == SuperFastHash(sv.name, MAXSAVEGAMENAME))) -#endif - { - strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME); - sv.name[MAXSAVEGAMENAME] = 127; - returnvar = -1; - } - else - { - strncpy(sv.name, input, MAXSAVEGAMENAME); - sv.name[MAXSAVEGAMENAME] = 0; - } - - G_SavePlayerMaybeMulti(sv); - - g_quickload = &sv; - g_player[myconnectindex].ps->gm = MODE_GAME; - - Menu_Change(MENU_CLOSE); - save_xxh = 0; - break; - } - - default: - break; - } - - return returnvar; -} - -static void Menu_EntryStringCancel(/*MenuEntry_t *entry*/) -{ - switch (g_currentMenu) - { - case MENU_SAVE: - save_xxh = 0; - ME_SAVE_NEW.name = s_NewSaveGame; - break; - - default: - break; - } -} - -/* -This is polled when the menu code is populating the screen but for some reason doesn't have the data. -*/ -static int32_t Menu_EntryOptionSource(MenuEntry_t *entry, int32_t currentValue) -{ - if (entry == &ME_GAMESETUP_WEAPSWITCH_PICKUP) - return (cl_weaponswitch & 1) ? ((cl_weaponswitch & 4) ? 2 : 1) : 0; - else if (entry == &ME_SOUND_DUKETALK) - return snd_speech & 1; - else if (entry == &ME_NETOPTIONS_MONSTERS) - return (ud.m_monsters_off ? g_skillCnt : ud.m_player_skill); - - return currentValue; -} - -static void Menu_Verify(int32_t input) -{ - switch (g_currentMenu) - { - case MENU_SAVECLEANVERIFY: - break; - - case MENU_RESETPLAYER: - switch (input) - { - default: - inputState.keyFlushChars(); - inputState.ClearKeysDown(); - FX_StopAllSounds(); - - if (G_LoadPlayerMaybeMulti(*g_quickload) == 0) - break; - - // error state, consider as a no instead of yes - g_quickload->reset(); - - fallthrough__; - case 0: - if (sprite[g_player[myconnectindex].ps->i].extra <= 0) - { - if (G_EnterLevel(MODE_GAME)) G_BackToMenu(); - return; - } - - Menu_Change(MENU_CLOSE); - break; - } - break; - - case MENU_LOADVERIFY: - if (input) - { - savebrief_t & sv = g_menusaves[M_LOAD.currentEntry].brief; - - if (strcmp(sv.path, g_lastusersave.path) != 0) - { - g_freshload = sv; - g_lastusersave.reset(); - g_lastautosave.reset(); - g_quickload = &g_freshload; - } - else - { - g_quickload = &g_lastusersave; - } - - inputState.keyFlushChars(); - inputState.ClearKeysDown(); - - Menu_Change(MENU_CLOSE); - - G_LoadPlayerMaybeMulti(sv); - } - break; - - case MENU_SAVEVERIFY: - if (!input) - { - save_xxh = 0; - - ((MenuString_t*)M_SAVE.entrylist[M_SAVE.currentEntry]->entry)->editfield = NULL; - } - break; - - case MENU_LOADDELVERIFY: - if (input) - { - //G_DeleteSave(g_menusaves[M_LOAD.currentEntry].brief); - Menu_LoadReadHeaders(); - M_LOAD.currentEntry = clamp(M_LOAD.currentEntry, 0, (int32_t)g_nummenusaves-1); - } - break; - case MENU_SAVEDELVERIFY: - if (input) - { - //G_DeleteSave(g_menusaves[M_SAVE.currentEntry-1].brief); - Menu_SaveReadHeaders(); - M_SAVE.currentEntry = clamp(M_SAVE.currentEntry, 0, (int32_t)g_nummenusaves); - } - break; - - case MENU_QUIT: - case MENU_QUIT_INGAME: - if (input) - G_GameQuit(); - else - g_quitDeadline = 0; - break; - - case MENU_QUITTOTITLE: - if (input) - { - g_player[myconnectindex].ps->gm = MODE_DEMO; - if (ud.recstat == 1) - G_CloseDemoWrite(); - artClearMapArt(); - } - break; - - case MENU_NETWAITVOTES: - if (!input) - Net_SendMapVoteCancel(0); - break; - - default: - break; - } -} - -static int Menu_CheatStringMatch(char const * input, char const * cheat) -{ - while (*cheat || *input) - { - if (*cheat != *input) - { - if (!(*cheat == '#' && Bisdigit(*input))) - return 0; - } - - ++cheat; - ++input; - } - - return 1; -} - -static void Menu_TextFormSubmit(char *input) -{ - switch (g_currentMenu) - { - case MENU_ADULTPASSWORD: - break; - - case MENU_CHEATENTRY: - { - const size_t inputlength = Bstrlen(input); - Bstrcpy(tempbuf, input); - for (size_t i = 0; i < inputlength; i++) - tempbuf[i] = Btolower(tempbuf[i]); - - int8_t cheatID = -1; - - if (inputlength > 2 && tempbuf[0] == g_keyAsciiTable[CheatKeys[0]] && tempbuf[1] == g_keyAsciiTable[CheatKeys[1]]) - { - for (int i = 0; i < NUMCHEATS; i++) - if (Menu_CheatStringMatch(tempbuf+2, CheatStrings[i])) - { - cheatID = i; - break; - } - } - - switch (cheatID) - { - case -1: - S_PlaySound(RR ? 335 : KICK_HIT); - break; - case CHEAT_SCOTTY: - { - char const * const numberpos = Bstrchr(CheatStrings[CHEAT_SCOTTY], '#'); - if (numberpos == NULL) - { - S_PlaySound(RR ? 335 : KICK_HIT); - break; - } - - Menu_Cheat_Warp(input + (numberpos - CheatStrings[CHEAT_SCOTTY]) + 2); - if (g_player[myconnectindex].ps->gm&MODE_MENU) - S_PlaySound(DUKE_GET); - break; - } - case CHEAT_SKILL: - { - char const * const numberpos = Bstrchr(CheatStrings[CHEAT_SKILL], '#'); - if (numberpos == NULL) - { - S_PlaySound(RR ? 335 : KICK_HIT); - break; - } - - Menu_Cheat_Skill(input + (numberpos - CheatStrings[CHEAT_SKILL]) + 2); - if (g_player[myconnectindex].ps->gm&MODE_MENU) - S_PlaySound(DUKE_GET); - break; - } - default: - Menu_DoCheat(cheatID); - S_PlaySound(DUKE_GET); - break; - } - - if (cheatID >= 0) - cl_cheatmask = cl_cheatmask | CheatFunctionFlags[cheatID]; - - if (((cl_cheatmask & (1<fnlist); - - if (object->destination[0] == 0) - Bstrcpy(object->destination, "./"); - Bcorrectfilename(object->destination, 1); - - fnlist_getnames(&object->fnlist, object->destination, object->pattern, 0, 0); - object->findhigh[0] = object->fnlist.finddirs; - object->findhigh[1] = object->fnlist.findfiles; - - for (int i = 0; i < 2; ++i) - { - object->scrollPos[i] = 0; - klistbookends(object->findhigh[i]); - } - - object->currentList = 0; - if (object->findhigh[1]) - object->currentList = 1; - -#endif - inputState.keyFlushChars(); -} - -static void Menu_FileSelect(int32_t input) -{ -#if 0 - switch (g_currentMenu) - { - case MENU_NETUSERMAP: - if ((g_netServer || ud.multimode > 1)) - Net_SendUserMapName(); - fallthrough__; - case MENU_USERMAP: - if (input) - { - ud.m_volume_number = 0; - m_level_number = 7; - - if (g_skillCnt > 0) - Menu_AnimateChange(MENU_SKILL, MA_Advance); - else - Menu_StartGameWithoutSkill(); - } - break; - - default: - break; - } -#endif -} - - - - - -static Menu_t* Menu_BinarySearch(MenuID_t query, uint16_t searchstart, uint16_t searchend) -{ - const uint16_t thissearch = (searchstart + searchend) / 2; - const MenuID_t difference = query - Menus[thissearch].menuID; - - if (difference == 0) - return &Menus[thissearch]; - else if (searchstart == searchend) - return NULL; - else if (difference > 0) - { - if (thissearch == searchend) - return NULL; - searchstart = thissearch + 1; - } - else if (difference < 0) - { - if (thissearch == searchstart) - return NULL; - searchend = thissearch - 1; - } - - return Menu_BinarySearch(query, searchstart, searchend); -} - -static Menu_t* Menu_Find(MenuID_t query) -{ - if ((unsigned) query > (unsigned) Menus[numMenus-1].menuID) - return NULL; - - return Menu_BinarySearch(query, 0, numMenus-1); -} - -static Menu_t* Menu_FindFiltered(MenuID_t query) -{ - if ((g_player[myconnectindex].ps->gm&MODE_GAME) && query == MENU_MAIN) - query = MENU_MAIN_INGAME; - - return Menu_Find(query); -} - -MenuAnimation_t m_animation; - -int32_t Menu_Anim_SinOutRight(MenuAnimation_t *animdata) -{ - return sintable[divscale10((int32_t) totalclock - animdata->start, animdata->length) + 512] - 16384; -} -int32_t Menu_Anim_SinInRight(MenuAnimation_t *animdata) -{ - return sintable[divscale10((int32_t) totalclock - animdata->start, animdata->length) + 512] + 16384; -} -int32_t Menu_Anim_SinOutLeft(MenuAnimation_t *animdata) -{ - return -sintable[divscale10((int32_t) totalclock - animdata->start, animdata->length) + 512] + 16384; -} -int32_t Menu_Anim_SinInLeft(MenuAnimation_t *animdata) -{ - return -sintable[divscale10((int32_t) totalclock - animdata->start, animdata->length) + 512] - 16384; -} - -void Menu_AnimateChange(int32_t cm, MenuAnimationType_t animtype) -{ - if (cm == MENU_KEYBOARDKEYS) - { - GUICapture |= 2; - return; - } - - switch (animtype) - { - case MA_Advance: - { - Menu_t * const previousMenu = m_currentMenu; - - if (!Menu_Change(cm)) - { - m_animation.out = Menu_Anim_SinOutRight; - m_animation.in = Menu_Anim_SinInRight; - m_animation.start = (int32_t) totalclock; - m_animation.length = 30; - - m_animation.previous = previousMenu; - m_animation.current = m_currentMenu; - } - - break; - } - case MA_Return: - { - Menu_t * const previousMenu = m_currentMenu; - - if (!Menu_Change(cm)) - { - m_animation.out = Menu_Anim_SinOutLeft; - m_animation.in = Menu_Anim_SinInLeft; - m_animation.start = (int32_t) totalclock; - m_animation.length = 30; - - m_animation.previous = previousMenu; - m_animation.current = m_currentMenu; - } - - break; - } - default: - m_animation.start = 0; - m_animation.length = 0; - Menu_Change(cm); - break; - } -} - -static void Menu_MaybeSetSelectionToChild(Menu_t * m, MenuID_t id) -{ - if (m->type == Menu) - { - auto * menu = (MenuMenu_t *)m->object; - - if (menu->currentEntry < menu->numEntries) - { - MenuEntry_t const * currentEntry = menu->entrylist[menu->currentEntry]; - if (currentEntry != NULL && currentEntry->type == Link) - { - auto const * link = (MenuLink_t const *)currentEntry->entry; - if (link->linkID == id) - return; // already good to go - } - } - - for (int i = 0, i_end = menu->numEntries; i < i_end; ++i) - { - MenuEntry_t const * entry = menu->entrylist[i]; - if (entry != NULL && entry->type == Link && !(entry->flags & MEF_Hidden)) - { - auto const * link = (MenuLink_t const *)entry->entry; - if (link->linkID == id) - { - menu->currentEntry = i; - Menu_AdjustForCurrentEntryAssignmentBlind(menu); - break; - } - } - } - } -} - -static void Menu_ReadSaveGameHeaders() -{ - ReadSaveGameHeaders(); - - int const numloaditems = max(g_nummenusaves, 1), numsaveitems = g_nummenusaves+1; - ME_LOAD = (MenuEntry_t *)Xrealloc(ME_LOAD, g_nummenusaves * sizeof(MenuEntry_t)); - MEL_LOAD = (MenuEntry_t **)Xrealloc(MEL_LOAD, numloaditems * sizeof(MenuEntry_t *)); - MEO_SAVE = (MenuString_t *)Xrealloc(MEO_SAVE, g_nummenusaves * sizeof(MenuString_t)); - ME_SAVE = (MenuEntry_t *)Xrealloc(ME_SAVE, g_nummenusaves * sizeof(MenuEntry_t)); - MEL_SAVE = (MenuEntry_t **)Xrealloc(MEL_SAVE, numsaveitems * sizeof(MenuEntry_t *)); - - MEL_SAVE[0] = &ME_SAVE_NEW; - ME_SAVE_NEW.name = s_NewSaveGame; - for (int i = 0; i < g_nummenusaves; ++i) - { - MEL_LOAD[i] = &ME_LOAD[i]; - MEL_SAVE[i+1] = &ME_SAVE[i]; - ME_LOAD[i] = ME_LOAD_TEMPLATE; - ME_SAVE[i] = ME_SAVE_TEMPLATE; - ME_SAVE[i].entry = &MEO_SAVE[i]; - MEO_SAVE[i] = MEO_SAVE_TEMPLATE; - - ME_LOAD[i].name = g_menusaves[i].brief.name; - MEO_SAVE[i].variable = g_menusaves[i].brief.name; - } - - if (g_nummenusaves == 0) - MEL_LOAD[0] = &ME_LOAD_EMPTY; - - M_LOAD.entrylist = MEL_LOAD; - M_LOAD.numEntries = numloaditems; - M_SAVE.entrylist = MEL_SAVE; - M_SAVE.numEntries = numsaveitems; - - // lexicographical sorting? -} - -static void Menu_AboutToStartDisplaying(Menu_t * m) -{ - switch (m->menuID) - { - case MENU_MAIN: - break; - - case MENU_MAIN_INGAME: - break; - - case MENU_LOAD: - Menu_LoadReadHeaders(); - - if (g_quickload && g_quickload->isValid()) - { - for (int i = 0; i < g_nummenusaves; ++i) - { - if (strcmp(g_menusaves[i].brief.path, g_quickload->path) == 0) - { - M_LOAD.currentEntry = i; - Menu_AdjustForCurrentEntryAssignmentBlind(&M_LOAD); - break; - } - } - } - break; - - case MENU_SAVE: - if (g_previousMenu == MENU_SAVEVERIFY || g_previousMenu == MENU_SAVEDELVERIFY) - break; - - Menu_SaveReadHeaders(); - - if (g_lastusersave.isValid()) - { - for (int i = 0; i < g_nummenusaves; ++i) - { - if (strcmp(g_menusaves[i].brief.path, g_lastusersave.path) == 0) - { - M_SAVE.currentEntry = i+1; - Menu_AdjustForCurrentEntryAssignmentBlind(&M_SAVE); - break; - } - } - } - - if (g_player[myconnectindex].ps->gm&MODE_GAME) - { - g_screenCapture = 1; - G_DrawRooms(myconnectindex,65536); - g_screenCapture = 0; - } - break; - - case MENU_VIDEOSETUP: - newresolution = 0; - for (int i = 0; i < MAXVALIDMODES; ++i) - { - if (resolution[i].xdim == xres && resolution[i].ydim == yres) - { - newresolution = i; - break; - } - } - newrendermode = videoGetRenderMode(); - newfullscreen = fullscreen; - newvsync = vid_vsync; - break; - - case MENU_ADVSOUND: - soundrate = snd_mixrate; - soundvoices = snd_numvoices; - break; - - default: - break; - } - - switch (m->type) - { - case TextForm: - typebuf[0] = 0; - ((MenuTextForm_t*)m->object)->input = typebuf; - break; - case FileSelect: - Menu_FileSelectInit((MenuFileSelect_t*)m->object); - break; - case CdPlayer: - { - auto *menu = (MenuMenu_t*)m->object; - menu->currentEntry = g_cdTrack-2; - // MenuEntry_t* currentry = menu->entrylist[menu->currentEntry]; - - if (menu->currentEntry < 0 || menu->currentEntry >= menu->numEntries) - menu->currentEntry = 0; - - Menu_EntryFocus(/*currentry*/); - break; - } - case Menu: - { - auto *menu = (MenuMenu_t*)m->object; - // MenuEntry_t* currentry = menu->entrylist[menu->currentEntry]; - - // need this for MENU_SKILL - if (menu->currentEntry >= menu->numEntries) - menu->currentEntry = 0; - - int32_t i = menu->currentEntry; - while (!menu->entrylist[menu->currentEntry] || - (((MenuEntry_t*)menu->entrylist[menu->currentEntry])->flags & MEF_Hidden) || - ((MenuEntry_t*)menu->entrylist[menu->currentEntry])->type == Spacer) - { - menu->currentEntry++; - if (menu->currentEntry >= menu->numEntries) - menu->currentEntry = 0; - if (menu->currentEntry == i) - G_GameExit("Menu_Change: Attempted to show a menu with no entries."); - } - - Menu_EntryFocus(/*currentry*/); - break; - } - default: - break; - } -} - -static void Menu_ChangingTo(Menu_t * m) -{ -#ifdef __ANDROID__ - if (m->menuID == MENU_TOUCHBUTTONS) - AndroidToggleButtonEditor(); -#endif - - switch (m->type) - { - case TextForm: - Menu_StartTextInput(); - break; - default: - break; - } -} - -int Menu_Change(MenuID_t cm) -{ - Menu_t * beginMenu = m_currentMenu; - - if (cm == MENU_PREVIOUS) - { - m_currentMenu = m_previousMenu; - g_currentMenu = g_previousMenu; - } - else if (cm == MENU_CLOSE) - Menu_Close(myconnectindex); - else if (cm >= 0) - { - Menu_t * search = Menu_FindFiltered(cm); - - if (search == NULL) - return 0; // intentional, so that users don't use any random value as "don't change" - - // security - if (search->type == Verify && - search->parentID != MENU_PREVIOUS && - search->parentID != MENU_CLOSE && - search->parentID != g_currentMenu) - return 1; - - m_previousMenu = m_currentMenu; - g_previousMenu = g_currentMenu; - m_currentMenu = search; - g_currentMenu = search->menuID; - } - else - return 1; - - Menu_MaybeSetSelectionToChild(m_currentMenu, beginMenu->menuID); - Menu_AboutToStartDisplaying(m_currentMenu); - Menu_ChangingTo(m_currentMenu); - -#if !defined EDUKE32_TOUCH_DEVICES - m_menuchange_watchpoint = 1; -#endif - - return 0; -} - - - - - - - - - - -int G_CheckPlayerColor(int color) -{ - for (int i : MEOSV_PLAYER_COLOR) - if (i == color) - return color; - - return -1; -} - - -int32_t Menu_DetermineSpecialState(MenuEntry_t *entry) -{ - if (entry == NULL) - return 0; - - if (entry->type == String) - { - if (((MenuString_t*)entry->entry)->editfield) - return 1; - } - else if (entry->type == Option) - { - if (((MenuOption_t*)entry->entry)->options->currentEntry >= 0) - return 2; - } - else if (entry->type == Custom2Col) - { - if (((MenuCustom2Col_t*)entry->entry)->screenOpen) - return 2; - } - - return 0; -} - -int32_t Menu_IsTextInput(Menu_t *cm) -{ - switch (m_currentMenu->type) - { - case Verify: - case TextForm: - case FileSelect: - case Message: - return 1; - break; - case Panel: - case CdPlayer: - return 0; - break; - case Menu: - { - auto *menu = (MenuMenu_t *)cm->object; - auto *entry = menu->entrylist[menu->currentEntry]; - return Menu_DetermineSpecialState(entry); - } - break; - } - - return 0; -} - -static inline int32_t Menu_BlackTranslucentBackgroundOK(MenuID_t cm) -{ - switch (cm) - { - case MENU_COLCORR: - case MENU_COLCORR_INGAME: - return 0; - break; - default: - return 1; - break; - } - - return 1; -} - -static inline int32_t Menu_UpdateScreenOK(MenuID_t cm) -{ - switch (cm) - { - case MENU_LOAD: - case MENU_SAVE: - case MENU_LOADVERIFY: - case MENU_LOADDELVERIFY: - case MENU_SAVEVERIFY: - case MENU_SAVEDELVERIFY: - return 0; - break; - default: - return 1; - break; - } - - return 1; -} - - -/* - Code below this point is entirely general, - so if you want to change or add a menu, - chances are you should scroll up. -*/ - -int32_t m_mouselastactivity; -#if !defined EDUKE32_TOUCH_DEVICES -int32_t m_mousewake_watchpoint, m_menuchange_watchpoint; -#endif -int32_t m_mousecaught; -static vec2_t m_prevmousepos, m_mousepos, m_mousedownpos; - -void Menu_Open(uint8_t playerID) -{ - g_player[playerID].ps->gm |= MODE_MENU; - - inputState.mouseReadAbs(&m_prevmousepos); - m_mouselastactivity = -M_MOUSETIMEOUT; - -#if !defined EDUKE32_TOUCH_DEVICES - m_mousewake_watchpoint = 0; -#endif - - mouseLockToWindow(0); -} - -void Menu_Close(uint8_t playerID) -{ - if (g_player[playerID].ps->gm & (MODE_GAME|MODE_DEMO)) - { - // The following lines are here so that you cannot close the menu when no game is running. - g_player[playerID].ps->gm &= ~MODE_MENU; - mouseLockToWindow(1); - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) - { - ready2send = 1; - totalclock = ototalclock; - CAMERACLOCK = (int32_t) totalclock; - CAMERADIST = 65536; - m_animation.start = 0; - m_animation.length = 0; - - // Reset next-viewscreen-redraw counter. - // XXX: are there any other cases like that in need of handling? - if (g_curViewscreen >= 0) - actor[g_curViewscreen].t_data[0] = (int32_t) totalclock; - } - - G_UpdateScreenArea(); - - if (!ud.pause_on) - S_PauseSounds(false); - } -} - -static int32_t x_widescreen_left(void) -{ - return (320<<15) - scale(240<<15, xdim, ydim); -} - -static int32_t xdim_from_320_16(int32_t x) -{ - const int32_t screenwidth = scale(240<<16, xdim, ydim); - return scale(x + (screenwidth>>1) - (160<<16), xdim, screenwidth); -} -static int32_t ydim_from_200_16(int32_t y) -{ - return scale(y, ydim, 200<<16); -} - -static void Menu_BlackRectangle(int32_t x, int32_t y, int32_t width, int32_t height, int32_t orientation) -{ - const int32_t xscale = divscale16(width, tilesiz[0].x<<16), yscale = divscale16(height, tilesiz[0].y<<16); - - rotatesprite_(x, y, max(xscale, yscale), 0, 0, 127, ud.shadow_pal, (orientation&(1|32))|2|8|16, 0, 0, xdim_from_320_16(x), ydim_from_200_16(y), xdim_from_320_16(x + width), ydim_from_200_16(y + height)); -} - -enum MenuTextFlags_t -{ - MT_Selected = 1<<0, - MT_Disabled = 1<<1, - MT_XCenter = 1<<2, - MT_XRight = 1<<3, - MT_YCenter = 1<<4, - MT_Literal = 1<<5, - MT_RightSide = 1<<6, -}; - -static void Menu_GetFmt(const MenuFont_t *font, uint8_t const status, int32_t *s) -{ - if (status & MT_Selected) - *s = sintable[((int32_t) totalclock<<5)&2047]>>12; - else - *s = font->shade_deselected; - // sum shade values - if (status & MT_Disabled) - *s += font->shade_disabled; -} - -static vec2_t Menu_Text(int32_t x, int32_t y, const MenuFont_t *font, const char *t, uint8_t status, int32_t ydim_upper, int32_t ydim_lower) -{ - int32_t s, p, ybetween = font->between.y; - int32_t f = font->textflags | TEXT_RRMENUTEXTHACK; - if (status & MT_XCenter) - f |= TEXT_XCENTER; - if (status & MT_XRight) - f |= TEXT_XRIGHT; - if (status & MT_YCenter) - { - f |= TEXT_YCENTER | TEXT_YOFFSETZERO; - ybetween = font->emptychar.y; // <^ the battle against 'Q' - } - if (status & MT_Literal) - f |= TEXT_LITERALESCAPE; - - int32_t z = font->zoom; - - if (status & MT_Disabled) - p = (status & MT_RightSide) ? font->pal_disabled_right : font->pal_disabled; - else if (status & MT_Selected) - p = (status & MT_RightSide) ? font->pal_selected_right : font->pal_selected; - else - p = (status & MT_RightSide) ? font->pal_deselected_right : font->pal_deselected; - - Menu_GetFmt(font, status, &s); - - return G_ScreenText(font->tilenum, x, y, z, 0, 0, t, s, p, 2|8|16|ROTATESPRITE_FULL16, 0, font->emptychar.x, font->emptychar.y, font->between.x, ybetween, f, 0, ydim_upper, xdim-1, ydim_lower); -} - -#if 0 -static vec2_t Menu_TextSize(int32_t x, int32_t y, const MenuFont_t *font, const char *t, uint8_t status) -{ - int32_t f = font->textflags; - if (status & MT_Literal) - f |= TEXT_LITERALESCAPE; - - return G_ScreenTextSize(font->tilenum, x, y, font->zoom, 0, t, 2|8|16|ROTATESPRITE_FULL16, font->emptychar.x, font->emptychar.y, font->between.x, font->between.y, f, 0, 0, xdim-1, ydim-1); -} -#endif - -static int32_t Menu_FindOptionBinarySearch(MenuOption_t *object, const int32_t query, uint16_t searchstart, uint16_t searchend) -{ - const uint16_t thissearch = (searchstart + searchend) / 2; - const bool isIdentityMap = object->options->optionValues == NULL; - const int32_t destination = isIdentityMap ? (int32_t)thissearch : object->options->optionValues[thissearch]; - const int32_t difference = query - destination; - - Bassert(!isIdentityMap || query >= 0); - - if (difference == 0) - return thissearch; - else if (searchstart == searchend) - return -1; - else if (difference > 0) - { - if (thissearch == searchend) - return -1; - searchstart = thissearch + 1; - } - else if (difference < 0) - { - if (thissearch == searchstart) - return -1; - searchend = thissearch - 1; - } - - return Menu_FindOptionBinarySearch(object, query, searchstart, searchend); -} - -static int32_t Menu_MouseOutsideBounds(vec2_t const * const pos, const int32_t x, const int32_t y, const int32_t width, const int32_t height) -{ - return pos->x < x || pos->x >= x + width || pos->y < y || pos->y >= y + height; -} - -static void Menu_RunScrollbar(Menu_t *cm, MenuMenuFormat_t const * const format, const int32_t totalextent, int32_t * const scrollPos, const int32_t rightedge, const vec2_t origin) -{ - if (totalextent > klabs(format->bottomcutoff)) - { - int32_t scrollTile = (ud.menu_scrollbartilenum >= 0) ? ud.menu_scrollbartilenum : -1; - int32_t scrollTileTop = (ud.menu_scrollbartilenum >= 0) ? ud.menu_scrollbartilenum + 1 : -1; - int32_t scrollTileBottom = (ud.menu_scrollbartilenum >= 0) ? ud.menu_scrollbartilenum + 2 : -1; - int32_t scrollTileCursor = (ud.menu_scrollbartilenum >= 0) ? ud.menu_scrollbartilenum + 3 : SELECTDIR; - - const int32_t scrollwidth = (scrollTile >= 0) ? tilesiz[scrollTile].x*ud.menu_scrollbarz : tilesiz[scrollTileCursor].x*ud.menu_scrollcursorz; - const int32_t scrollx = origin.x + rightedge - scrollwidth, scrolly = origin.y + format->pos.y; - const int32_t scrollheight = klabs(format->bottomcutoff) - format->pos.y; - int32_t scrollregionstart = scrolly; - int32_t scrollregionend = scrolly + scrollheight; - if (ud.menu_scrollbartilenum >= 0) - { - scrollregionstart += tilesiz[scrollTileTop].y*ud.menu_scrollbarz; - scrollregionend -= tilesiz[scrollTileBottom].y*ud.menu_scrollbarz; - } - const int32_t scrollregionheight = scrollregionend - scrollregionstart - (tilesiz[scrollTileCursor].y*ud.menu_scrollcursorz); - const int32_t scrollPosMax = totalextent - klabs(format->bottomcutoff); - - if (scrollTile >= 0) - { - // draw the scrollbar (minus the top tile) twice to fill the gaps between tiles - if (tilesiz[scrollTile].y > 0) - { - for (int32_t y = scrollregionstart + ((tilesiz[scrollTileTop].y == 0)*tilesiz[scrollTile].y*ud.menu_scrollbarz); y < scrollregionend; y += tilesiz[scrollTile].y*ud.menu_scrollbarz) - rotatesprite(scrollx, y - (ud.menu_scrollbarz>>1), ud.menu_scrollbarz, 0, scrollTile, 0, 0, 26, 0, 0, xdim-1, mulscale16(scrollregionend, ydim*200)-1); - } - rotatesprite_fs(scrollx, scrollregionend - (ud.menu_scrollbarz>>1), ud.menu_scrollbarz, 0, scrollTileBottom, 0, 0, 26); - - if (tilesiz[scrollTile].y > 0) - { - for (int32_t y = scrollregionstart; y < scrollregionend; y += tilesiz[scrollTile].y*ud.menu_scrollbarz) - rotatesprite(scrollx, y, ud.menu_scrollbarz, 0, scrollTile, 0, 0, 26, 0, 0, xdim-1, mulscale16(scrollregionend, ydim*200)-1); - } - rotatesprite_fs(scrollx, scrolly, ud.menu_scrollbarz, 0, scrollTileTop, 0, 0, 26); - rotatesprite_fs(scrollx, scrollregionend, ud.menu_scrollbarz, 0, scrollTileBottom, 0, 0, 26); - } - else - Menu_BlackRectangle(scrollx, scrolly, scrollwidth, scrollheight, 1|32); - - rotatesprite_fs(scrollx + (scrollwidth>>1) - ((tilesiz[scrollTileCursor].x*ud.menu_scrollcursorz)>>1), scrollregionstart + scale(scrollregionheight, *scrollPos, scrollPosMax), ud.menu_scrollcursorz, 0, scrollTileCursor, 0, 0, 26); - - if (cm == m_currentMenu && !m_mousecaught && MOUSEACTIVECONDITIONAL(inputState.mouseClickState() == MOUSE_PRESSED || inputState.mouseClickState() == MOUSE_HELD)) - { - const int32_t scrolltilehalfheight = (tilesiz[scrollTileCursor].y*ud.menu_scrollcursorz)>>1; - const int32_t scrollregiony = scrollregionstart + scrolltilehalfheight; - - // region between the y-midline of the arrow at the extremes scrolls proportionally - if (!Menu_MouseOutsideBounds(&m_mousepos, scrollx, scrollregiony, scrollwidth, scrollregionheight)) - { - *scrollPos = scale(m_mousepos.y - scrollregiony, scrollPosMax, scrollregionheight); - - m_mousecaught = 1; - } - // region outside the y-midlines clamps to the extremes - else if (!Menu_MouseOutsideBounds(&m_mousepos, scrollx, scrolly, scrollwidth, scrollheight)) - { - if (m_mousepos.y > scrolly + scrollheight/2) - *scrollPos = scrollPosMax; - else - *scrollPos = 0; - - m_mousecaught = 1; - } - } - } -} - -typedef enum MenuMovement_t -{ - MM_Up = 1, - MM_End = 3, - MM_Down = 4, - MM_Home = 12, - MM_Left = 16, - MM_AllTheWayLeft = 48, - MM_Right = 64, - MM_AllTheWayRight = 192, - MM_Swap = 80, -} MenuMovement_t; - -static MenuEntry_t *Menu_RunInput_Menu_MovementVerify(MenuMenu_t *menu); -static MenuEntry_t *Menu_RunInput_Menu_Movement(MenuMenu_t *menu, MenuMovement_t direction); -static void Menu_RunInput_EntryLink_Activate(MenuEntry_t *entry); -static void Menu_RunInput_EntryOptionList_MovementVerify(MenuOption_t *object); -static void Menu_RunInput_EntryOptionList_Movement(MenuOption_t *object, MenuMovement_t direction); -static int32_t Menu_RunInput_EntryOption_Modify(MenuEntry_t *entry, MenuOption_t *object, int32_t newValueIndex); -static int32_t Menu_RunInput_EntryOption_Movement(MenuEntry_t *entry, MenuOption_t *object, MenuMovement_t direction); -static int32_t Menu_RunInput_EntryOption_Activate(MenuEntry_t *entry, MenuOption_t *object); -static int32_t Menu_RunInput_EntryOptionList_Activate(MenuEntry_t *entry, MenuOption_t *object); -static void Menu_RunInput_EntryCustom2Col_Activate(MenuEntry_t *entry); -static void Menu_RunInput_EntryRangeInt32_MovementVerify(MenuEntry_t *entry, MenuRangeInt32_t *object, int32_t newValue); -static void Menu_RunInput_EntryRangeInt32_MovementArbitrary(MenuEntry_t *entry, MenuRangeInt32_t *object, int32_t newValue); -static void Menu_RunInput_EntryRangeInt32_Movement(MenuEntry_t *entry, MenuRangeInt32_t *object, MenuMovement_t direction); -static void Menu_RunInput_EntryRangeFloat_MovementVerify(MenuEntry_t *entry, MenuRangeFloat_t *object, float newValue); -static void Menu_RunInput_EntryRangeFloat_MovementArbitrary(MenuEntry_t *entry, MenuRangeFloat_t *object, float newValue); -static void Menu_RunInput_EntryRangeFloat_Movement(MenuEntry_t *entry, MenuRangeFloat_t *object, MenuMovement_t direction); -#ifdef MENU_ENABLE_RANGEDOUBLE -static void Menu_RunInput_EntryRangeDouble_MovementVerify(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, double newValue); -static void Menu_RunInput_EntryRangeDouble_MovementArbitrary(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, double newValue); -static void Menu_RunInput_EntryRangeDouble_Movement(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, MenuMovement_t direction); -#endif -static void Menu_RunInput_EntryString_Activate(MenuEntry_t *entry); -static void Menu_RunInput_EntryString_Submit(/*MenuEntry_t *entry, */MenuString_t *object); -static void Menu_RunInput_EntryString_Cancel(/*MenuEntry_t *entry, */MenuString_t *object); -static void Menu_RunInput_FileSelect_MovementVerify(MenuFileSelect_t *object); -static void Menu_RunInput_FileSelect_Movement(MenuFileSelect_t *object, MenuMovement_t direction); -static void Menu_RunInput_FileSelect_Select(MenuFileSelect_t *object); - -static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *currentry, int32_t state, const vec2_t origin, bool actually_draw) -{ - int32_t totalHeight = 0; - - // RIP MenuGroup_t b. 2014-03-?? d. 2014-11-29 - { - int32_t e; - const int32_t y_upper = menu->format->pos.y; - const int32_t y_lower = klabs(menu->format->bottomcutoff); - int32_t y = 0; - int32_t calculatedentryspacing = 0; - - if (menu->format->bottomcutoff < 0) - { - int32_t totalheight = 0, numvalidentries = 0; - - for (e = 0; e < menu->numEntries; ++e) - { - MenuEntry_t *entry = menu->entrylist[e]; - - if (entry == NULL || (entry->flags & MEF_Hidden)) - continue; - - ++numvalidentries; - - // assumes height == font->get_yline()! - totalheight += entry->getHeight(); - } - - calculatedentryspacing = (klabs(menu->format->bottomcutoff) - menu->format->pos.y - totalheight) / (numvalidentries > 1 ? numvalidentries - 1 : 1); - } - - // totalHeight calculating pass - for (e = 0; e < menu->numEntries; ++e) - { - MenuEntry_t *entry = menu->entrylist[e]; - - if (entry == NULL || (entry->flags & MEF_Hidden)) - continue; - - int32_t const height = entry->getHeight(); - - y += height; - totalHeight = y; - y += (!calculatedentryspacing || calculatedentryspacing > entry->getMarginBottom()) ? entry->getMarginBottom() : calculatedentryspacing; - } - y = 0; - - int32_t ydim_upper, ydim_lower; - if (y_upper + totalHeight > y_lower) - { - ydim_upper = ydim_from_200_16(origin.y + y_upper); - ydim_lower = ydim_from_200_16(origin.y + y_lower); - } - else - { - ydim_upper = 0; - ydim_lower = ydim-1; - } - - for (e = 0; e < menu->numEntries; ++e) - { - MenuEntry_t *entry = menu->entrylist[e]; - - if (entry == NULL || (entry->flags & MEF_Hidden)) - continue; - - int32_t const indent = entry->getIndent(); - int32_t x = menu->format->pos.x; - - uint8_t status = 0; - if (e == menu->currentEntry) - status |= MT_Selected; - if (entry->flags & (MEF_Disabled|MEF_LookDisabled)) - status |= MT_Disabled; - if (entry->format->width == 0) - status |= MT_XCenter; - - bool const dodraw = entry->type != Spacer && actually_draw && - 0 <= y - menu->scrollPos + entry->font->get_yline() && - y - menu->scrollPos <= klabs(menu->format->bottomcutoff) - menu->format->pos.y; - - int32_t const height = entry->getHeight(); // max(textsize.y, entry->font->get_yline()); // bluefont Q ruins this - status |= MT_YCenter; - int32_t const y_internal = origin.y + y_upper + y + (height>>1) - menu->scrollPos; - - vec2_t textsize; - if (dodraw) - textsize = Menu_Text(origin.x + x + indent, y_internal, entry->font, entry->name, status, ydim_upper, ydim_lower); - - if (entry->format->width < 0) - status |= MT_XRight; - - if (dodraw && (status & MT_Selected) && state != 1) - { - if (status & MT_XCenter) - { - Menu_DrawCursorLeft(origin.x + (MENU_MARGIN_CENTER<<16) + entry->font->cursorCenterPosition, y_internal, entry->font->cursorScale); - Menu_DrawCursorRight(origin.x + (MENU_MARGIN_CENTER<<16) - entry->font->cursorCenterPosition, y_internal, entry->font->cursorScale); - } - else - Menu_DrawCursorLeft(origin.x + x + indent - entry->font->cursorLeftPosition, y_internal, entry->font->cursorScale2); - } - - if (entry->name != nullptr && entry->name[0] != '\0') - status |= MT_RightSide; - - // need this up here to avoid race conditions - entry->ybottom = (entry->ytop = y_upper + y) + height; - - if (dodraw) - { - const int32_t mousex = origin.x + indent + entry->format->width == 0 ? x - textsize.x/2 : x; - const int32_t mousey = origin.y + y_upper + y - menu->scrollPos; - int32_t mousewidth = entry->format->width == 0 ? textsize.x : klabs(entry->format->width); - - if (entry->name) - x += klabs(entry->format->width); - - switch (entry->type) - { - case Spacer: - break; - case Dummy: - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - } - break; - case Link: - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, mousex, mousey, mousewidth, entry->font->get_yline())) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - - if (entry->flags & MEF_Disabled) - break; - - Menu_RunInput_EntryLink_Activate(entry); - - if (g_player[myconnectindex].ps->gm&MODE_MENU) // for skill selection - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - - m_mousecaught = 1; - } - } - break; - case Option: - { - auto *object = (MenuOption_t*)entry->entry; - int32_t currentOption = Menu_FindOptionBinarySearch(object, object->cVar == NULL ? Menu_EntryOptionSource(entry, object->currentOption) : object->cVar->ToInt(), 0, object->options->numOptions); - - if (currentOption >= 0) - object->currentOption = currentOption; - - int32_t optiontextx = origin.x + x; - const int32_t optiontexty = origin.y + y_upper + y - menu->scrollPos; - - const vec2_t optiontextsize = Menu_Text(optiontextx, optiontexty + (height>>1), object->font, - currentOption < 0 ? MenuCustom : currentOption < object->options->numOptions ? object->options->optionNames[currentOption] : NULL, - status, ydim_upper, ydim_lower); - - if (entry->format->width > 0) - mousewidth += optiontextsize.x; - else - optiontextx -= optiontextsize.x; - - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, mousex, mousey, mousewidth, entry->font->get_yline())) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - - if (entry->flags & MEF_Disabled) - break; - - Menu_RunInput_EntryOption_Activate(entry, object); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - - m_mousecaught = 1; - } - } - - break; - } - case Custom2Col: - { - auto *object = (MenuCustom2Col_t*)entry->entry; - int32_t columnx[2] = { origin.x + x - ((status & MT_XRight) ? object->columnWidth : 0), origin.x + x + ((status & MT_XRight) ? 0 : object->columnWidth) }; - const int32_t columny = origin.y + y_upper + y - menu->scrollPos; - - const vec2_t column0textsize = Menu_Text(columnx[0], columny + (height>>1), object->font, object->key[*object->column[0]], menu->currentColumn == 0 ? status : (status & ~MT_Selected), ydim_upper, ydim_lower); - const vec2_t column1textsize = Menu_Text(columnx[1], columny + (height>>1), object->font, object->key[*object->column[1]], menu->currentColumn == 1 ? status : (status & ~MT_Selected), ydim_upper, ydim_lower); - - if (entry->format->width > 0) - mousewidth += object->columnWidth + column1textsize.x; - else - { - columnx[0] -= column0textsize.x; - columnx[1] -= column0textsize.x; - } - - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - if (!Menu_MouseOutsideBounds(&m_mousepos, columnx[1], mousey, column1textsize.x, object->font->get_yline())) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, columnx[1], mousey, column1textsize.x, object->font->get_yline()))) - { - menu->currentColumn = 1; - } - - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, columnx[1], mousey, column1textsize.x, object->font->get_yline())) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - menu->currentColumn = 1; - - if (entry->flags & MEF_Disabled) - break; - - Menu_RunInput_EntryCustom2Col_Activate(entry); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - - m_mousecaught = 1; - } - } - else if (!Menu_MouseOutsideBounds(&m_mousepos, columnx[0], mousey, column0textsize.x, object->font->get_yline())) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, columnx[0], mousey, column0textsize.x, object->font->get_yline()))) - { - menu->currentColumn = 0; - } - - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, columnx[0], mousey, column0textsize.x, object->font->get_yline())) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - menu->currentColumn = 0; - - if (entry->flags & MEF_Disabled) - break; - - Menu_RunInput_EntryCustom2Col_Activate(entry); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - - m_mousecaught = 1; - } - } - } - break; - } - case RangeInt32: - { - auto *object = (MenuRangeInt32_t*)entry->entry; - - int32_t s, p; - int32_t z = entry->font->cursorScale3; - Menu_GetFmt(object->font, status|MT_RightSide, &s); - - if (status & MT_Disabled) - p = ud.slidebar_paldisabled; - else if (status & MT_Selected) - p = ud.slidebar_palselected; - else - p = 0; - - const int32_t slidebarwidth = mulscale16(tilesiz[SLIDEBAR].x * ud.menu_slidebarz, z); - const int32_t slidebarheight = mulscale16(tilesiz[SLIDEBAR].y * ud.menu_slidebarz, z); - - if (status & MT_XRight) - x -= slidebarwidth; - else - mousewidth += slidebarwidth; - - const int32_t slidebarx = origin.x + x; - const int32_t slidebary = origin.y + y_upper + y + ((height - slidebarheight)>>1) - menu->scrollPos; - - rotatesprite_ybounds(slidebarx, slidebary, mulscale16(ud.menu_slidebarz, z), 0, SLIDEBAR, s, p, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); - - const int32_t cursorTile = RR ? BIGALPHANUM-9 : SLIDEBAR+1; - const int32_t slideregionwidth = mulscale16((tilesiz[SLIDEBAR].x * ud.menu_slidebarz) - (ud.menu_slidebarmargin<<1) - (tilesiz[cursorTile].x * ud.menu_slidecursorz), z); - const int32_t slidepointx = slidebarx + mulscale16(ud.menu_slidebarmargin, z) + scale(slideregionwidth, *object->cVar - object->min, object->max - object->min); - const int32_t slidepointy = slidebary + mulscale16(((tilesiz[SLIDEBAR].y * ud.menu_slidebarz) - (tilesiz[cursorTile].y * ud.menu_slidecursorz))>>1, z); - - rotatesprite_ybounds(slidepointx, slidepointy, mulscale16(ud.menu_slidecursorz, z), 0, cursorTile, s, p, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); - - if (object->flags & DisplayTypeMask) - { - status |= MT_XRight; - - int32_t onehundredpercent = object->onehundredpercent; - if (onehundredpercent == 0) - onehundredpercent = object->max; - - switch (object->flags & DisplayTypeMask) - { - case DisplayTypeInteger: - Bsprintf(tempbuf, "%d", **object->cVar); - break; - case DisplayTypePercent: - Bsprintf(tempbuf, "%d%%", roundscale(*object->cVar, 100, onehundredpercent)); - break; - case DisplayTypeNormalizedDecimal: - Bsprintf(tempbuf, "%.2f", (double) *object->cVar / (double) onehundredpercent); - break; - } - - Menu_Text(origin.x + x - (4<<16), origin.y + y_upper + y + (height>>1) - menu->scrollPos, object->font, tempbuf, status, ydim_upper, ydim_lower); - } - - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - if (!m_mousecaught && (inputState.mouseClickState() == MOUSE_PRESSED || inputState.mouseClickState() == MOUSE_HELD)) - { - const int32_t slidepointhalfwidth = mulscale16((((tilesiz[cursorTile].x)*ud.menu_slidecursorz)>>2) + ud.menu_slidebarmargin, z); - const int32_t slideregionx = slidebarx + slidepointhalfwidth; - - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - - if (entry->flags & MEF_Disabled) - break; - - // region between the x-midline of the slidepoint at the extremes slides proportionally - if (!Menu_MouseOutsideBounds(&m_mousepos, slideregionx, mousey, slideregionwidth, height)) - { - Menu_RunInput_EntryRangeInt32_MovementArbitrary(entry, object, roundscale(object->max - object->min, m_mousepos.x - slideregionx, slideregionwidth) + object->min); - - m_mousecaught = 1; - } - // region outside the x-midlines clamps to the extremes - else if (!Menu_MouseOutsideBounds(&m_mousepos, slidebarx, mousey, slidebarwidth, height)) - { - if (m_mousepos.x > slideregionx + slideregionwidth/2) - Menu_RunInput_EntryRangeInt32_MovementVerify(entry, object, object->max); - else - Menu_RunInput_EntryRangeInt32_MovementVerify(entry, object, object->min); - - m_mousecaught = 1; - } - } - } - - break; - } - case RangeFloat: - { - auto *object = (MenuRangeFloat_t*)entry->entry; - - int32_t s, p; - int32_t z = entry->font->cursorScale3; - Menu_GetFmt(object->font, status|MT_RightSide, &s); - - if (status & MT_Disabled) - p = ud.slidebar_paldisabled; - else if (status & MT_Selected) - p = ud.slidebar_palselected; - else - p = 0; - - const int32_t slidebarwidth = mulscale16(tilesiz[SLIDEBAR].x * ud.menu_slidebarz, z); - const int32_t slidebarheight = mulscale16(tilesiz[SLIDEBAR].y * ud.menu_slidebarz, z); - - if (status & MT_XRight) - x -= slidebarwidth; - else - mousewidth += slidebarwidth; - - const int32_t slidebarx = origin.x + x; - const int32_t slidebary = origin.y + y_upper + y + ((height - slidebarheight)>>1) - menu->scrollPos; - - rotatesprite_ybounds(slidebarx, slidebary, mulscale16(ud.menu_slidebarz, z), 0, SLIDEBAR, s, p, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); - - const int32_t cursorTile = RR ? BIGALPHANUM-9 : SLIDEBAR+1; - const int32_t slideregionwidth = mulscale16((tilesiz[SLIDEBAR].x * ud.menu_slidebarz) - (ud.menu_slidebarmargin<<1) - (tilesiz[cursorTile].x * ud.menu_slidecursorz), z); - const int32_t slidepointx = slidebarx + mulscale16(ud.menu_slidebarmargin, z) + Blrintf((float) slideregionwidth * (*object->cVar - object->min) / (object->max - object->min)); - const int32_t slidepointy = slidebary + mulscale16(((tilesiz[SLIDEBAR].y * ud.menu_slidebarz) - (tilesiz[cursorTile].y * ud.menu_slidecursorz))>>1, z); - - rotatesprite_ybounds(slidepointx, slidepointy, mulscale16(ud.menu_slidecursorz, z), 0, cursorTile, s, p, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); - - if (object->flags & DisplayTypeMask) - { - status |= MT_XRight; - - float onehundredpercent = object->onehundredpercent; - if (onehundredpercent == 0.f) - onehundredpercent = 1.f; - - switch (object->flags & DisplayTypeMask) - { - case DisplayTypeInteger: - Bsprintf(tempbuf, "%.2f", **object->cVar); - break; - case DisplayTypePercent: - Bsprintf(tempbuf, "%ld%%", lrintf(*object->cVar * 100.f / onehundredpercent)); - break; - case DisplayTypeNormalizedDecimal: - Bsprintf(tempbuf, "%.2f", *object->cVar / onehundredpercent); - break; - } - - Menu_Text(origin.x + x - (4<<16), origin.y + y_upper + y + (height>>1) - menu->scrollPos, object->font, tempbuf, status, ydim_upper, ydim_lower); - } - - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - if (!m_mousecaught && (inputState.mouseClickState() == MOUSE_PRESSED || inputState.mouseClickState() == MOUSE_HELD)) - { - const int32_t slidepointhalfwidth = mulscale16((2+tilesiz[cursorTile].x)<<15, z); - const int32_t slideregionx = slidebarx + slidepointhalfwidth; - - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - - if (entry->flags & MEF_Disabled) - break; - - // region between the x-midline of the slidepoint at the extremes slides proportionally - if (!Menu_MouseOutsideBounds(&m_mousepos, slideregionx, mousey, slideregionwidth, height)) - { - Menu_RunInput_EntryRangeFloat_MovementArbitrary(entry, object, (object->max - object->min) * (m_mousepos.x - slideregionx) / slideregionwidth + object->min); - - m_mousecaught = 1; - } - // region outside the x-midlines clamps to the extremes - else if (!Menu_MouseOutsideBounds(&m_mousepos, slidebarx, mousey, slidebarwidth, height)) - { - if (m_mousepos.x > slideregionx + slideregionwidth/2) - Menu_RunInput_EntryRangeFloat_MovementVerify(entry, object, object->max); - else - Menu_RunInput_EntryRangeFloat_MovementVerify(entry, object, object->min); - - m_mousecaught = 1; - } - } - } - - break; - } -#ifdef MENU_ENABLE_RANGEDOUBLE - case RangeDouble: - { - MenuRangeDouble_t *object = (MenuRangeDouble_t*)entry->entry; - - int32_t s, p; - int32_t z = entry->font->cursorScale3; - Menu_GetFmt(object->font, status|MT_RightSide, &s); - - if (status & MT_Disabled) - p = ud.slidebar_paldisabled; - else if (status & MT_Selected) - p = ud.slidebar_palselected; - else - p = 0; - - const int32_t slidebarwidth = mulscale16(tilesiz[SLIDEBAR].x * ud.menu_slidebarz, z); - const int32_t slidebarheight = mulscale16(tilesiz[SLIDEBAR].y * ud.menu_slidebarz, z); - - if (status & MT_XRight) - x -= slidebarwidth; - else - mousewidth += slidebarwidth; - - const int32_t slidebarx = origin.x + x; - const int32_t slidebary = origin.y + y_upper + y + ((height - slidebarheight)>>1) - menu->scrollPos; - - rotatesprite_ybounds(slidebarx, slidebary, mulscale16(ud.menu_slidebarz, z), 0, SLIDEBAR, s, p, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); - - const int32_t cursorTile = RR ? BIGALPHANUM-9 : SLIDEBAR+1; - const int32_t slideregionwidth = mulscale16((tilesiz[SLIDEBAR].x * ud.menu_slidebarz) - (ud.menu_slidebarmargin<<1) - (tilesiz[cursorTile].x * ud.menu_slidecursorz), z); - const int32_t slidepointx = slidebarx + mulscale16(ud.menu_slidebarmargin, z) + lrint((double) slideregionwidth * (*object->variable - object->min) / (object->max - object->min)); - const int32_t slidepointy = slidebary + mulscale16(((tilesiz[SLIDEBAR].y * ud.menu_slidebarz) - (tilesiz[cursorTile].y * ud.menu_slidecursorz))>>1, z); - - rotatesprite_ybounds(slidepointx, slidepointy, mulscale16(ud.menu_slidecursorz, z), 0, cursorTile, s, p, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); - - if (object->flags & DisplayTypeMask) - { - status |= MT_XRight; - - double onehundredpercent = object->onehundredpercent; - if (onehundredpercent == 0.) - onehundredpercent = 1.; - - switch (object->flags & DisplayTypeMask) - { - case DisplayTypeInteger: - Bsprintf(tempbuf, "%.2f", *object->variable); - break; - case DisplayTypePercent: - Bsprintf(tempbuf, "%ld%%", lrint(*object->variable * 100. / onehundredpercent)); - break; - case DisplayTypeNormalizedDecimal: - Bsprintf(tempbuf, "%.2f", *object->variable / onehundredpercent); - break; - } - - Menu_Text(origin.x + x - (4<<16), origin.y + y_upper + y + (height>>1) - menu->scrollPos, object->font, tempbuf, status, ydim_upper, ydim_lower); - } - - if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - if (!m_mousecaught && (inputState.mouseClickState() == MOUSE_PRESSED || inputState.mouseClickState() == MOUSE_HELD)) - { - const int32_t slidepointhalfwidth = mulscale16((2+tilesiz[cursorTile].x)<<15, z); - const int32_t slideregionx = slidebarx + slidepointhalfwidth; - - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - - if (entry->flags & MEF_Disabled) - break; - - // region between the x-midline of the slidepoint at the extremes slides proportionally - if (!Menu_MouseOutsideBounds(&m_mousepos, slideregionx, mousey, slideregionwidth, height)) - { - Menu_RunInput_EntryRangeDouble_MovementArbitrary(/*entry, */object, (object->max - object->min) * (m_mousepos.x - slideregionx) / slideregionwidth + object->min); - - m_mousecaught = 1; - } - // region outside the x-midlines clamps to the extremes - else if (!Menu_MouseOutsideBounds(&m_mousepos, slidebarx, mousey, slidebarwidth, height)) - { - if (m_mousepos.x > slideregionx + slideregionwidth/2) - Menu_RunInput_EntryRangeDouble_MovementVerify(/*entry, */object, object->max); - else - Menu_RunInput_EntryRangeDouble_MovementVerify(/*entry, */object, object->min); - - m_mousecaught = 1; - } - } - } - - break; - } -#endif - case String: - { - auto *object = (MenuString_t*)entry->entry; - - vec2_t dim; - int32_t stringx = x; - const int32_t stringy = origin.y + y_upper + y + (height>>1) - menu->scrollPos; - int32_t h; - - if (entry == currentry && object->editfield != NULL) - { - dim = Menu_Text(origin.x + stringx, stringy, object->font, object->editfield, (status & ~MT_Disabled) | MT_Literal, ydim_upper, ydim_lower); - h = max(dim.y, entry->font->get_yline()); - - Menu_DrawCursorText(origin.x + x + dim.x + (1<<16), stringy, h, ydim_upper, ydim_lower); - } - else - { - dim = Menu_Text(origin.x + stringx, stringy, object->font, object->variable, status, ydim_upper, ydim_lower); - h = max(dim.y, entry->font->get_yline()); - } - - if (entry->format->width > 0) - { - if (entry->name) - mousewidth += dim.x; - } - else - stringx -= dim.x; - - if (MOUSEACTIVECONDITIONAL(cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, h))) - { - if (state != 1 && Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, h)) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - } - - #ifndef EDUKE32_TOUCH_DEVICES - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, h) && !Menu_MouseOutsideBounds(&m_mousedownpos, mousex, mousey, mousewidth, h)) - #endif - { - if (entry == currentry && object->editfield != NULL) - { - Menu_RunInput_EntryString_Submit(/*entry, */object); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - - m_mousecaught = 1; - } - else if (state != 1) - { - menu->currentEntry = e; - Menu_RunInput_Menu_MovementVerify(menu); - - if (entry->flags & MEF_Disabled) - break; - - Menu_RunInput_EntryString_Activate(entry); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - - m_mousecaught = 1; - } - } - } - - break; - } - } - } - - // prepare for the next line - y += height; - y += (!calculatedentryspacing || calculatedentryspacing > entry->getMarginBottom()) ? entry->getMarginBottom() : calculatedentryspacing; - } - - // draw indicators if applicable - if (actually_draw) - Menu_RunScrollbar(cm, menu->format, y_upper + totalHeight, &menu->scrollPos, 320<<16, origin); - } - - return totalHeight; -} - -static void M_RunMenu_CdPlayer(Menu_t *cm, MenuMenu_t *menu, const vec2_t origin) -{ - static const vec2_t entryPos[8] = { - { 22, 15 }, { 64, 15 }, { 104, 15 }, { 142, 15 }, - { 22, 25 }, { 64, 25 }, { 104, 25 }, { 142, 25 }, - }; - - // RIP MenuGroup_t b. 2014-03-?? d. 2014-11-29 - { - int32_t e; - - for (e = 0; e < menu->numEntries; ++e) - { - const int32_t x = entryPos[e].x-154+(MENU_MARGIN_CENTER<<1); - const int32_t y = entryPos[e].y+65; - - const int32_t mousex = origin.x+(x<<15)-(4<<16); - const int32_t mousey = origin.y+(y<<16)-(4<<16); - - if (e == menu->currentEntry && mus_enabled) - rotatesprite_fs(origin.x+(x<<15), origin.y+(y<<16), 32768, 0, CDPLAYER+1, 16, 0, 10); - - - if (MOUSEACTIVECONDITIONAL(cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, 8<<16, 8<<16))) - { - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED) - { - menu->currentEntry = e; - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - - if (MusicEnabled()) - { - S_StopMusic(); - S_PlayRRMusic(2+menu->currentEntry); - } - - m_mousecaught = 1; - } - } - //switch (entry->type) - //{ - // case Spacer: - // break; - // case Dummy: - //if (MOUSEACTIVECONDITIONAL(state != 1 && cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, height))) - //{ - // if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, height))) - // { - // menu->currentEntry = e; - // Menu_RunInput_Menu_MovementVerify(menu); - // } - //} - //break; - //} - } - } - - const int32_t mousex = origin.x+((MENU_MARGIN_CENTER-60)<<16)-(8<<16); - const int32_t mousey = origin.y+(113<<16)-(8<<16); - if (MOUSEACTIVECONDITIONAL(cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, 16<<16, 16<<16))) - { - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED) - { - mus_enabled = !mus_enabled; - - if (mus_enabled == 0) - S_PauseMusic(true); - else - { - S_PlayRRMusic(2+menu->currentEntry); - S_PauseMusic(false); - } - - m_mousecaught = 1; - } - } - - if (mus_enabled) - rotatesprite_fs(origin.x+((MENU_MARGIN_CENTER-60)<<16), origin.y+(113<<16), 32768, 0, CDPLAYER+3, 16, 0, 10); - else - rotatesprite_fs(origin.x+((MENU_MARGIN_CENTER-60)<<16), origin.y+(113<<16), 32768, 0, CDPLAYER+2, 16, 0, 10); - - return; -} - -static void Menu_RunOptionList(Menu_t *cm, MenuEntry_t *entry, MenuOption_t *object, const vec2_t origin) -{ - int32_t e, y = 0; - const int32_t y_upper = object->options->menuFormat->pos.y; - const int32_t y_lower = object->options->menuFormat->bottomcutoff; - int32_t calculatedentryspacing = object->options->getMarginBottom(); - - // assumes height == font->get_yline()! - if (calculatedentryspacing < 0) - calculatedentryspacing = (-calculatedentryspacing - object->options->font->get_yline()) / (object->options->numOptions - 1) - object->options->font->get_yline(); - - int32_t totalHeight = 0; - for (e = 0; e < object->options->numOptions; ++e) - { - int32_t const height = object->options->font->get_yline(); - - y += height; - totalHeight = y; - y += calculatedentryspacing; - } - y = 0; - - int32_t ydim_upper, ydim_lower; - if (y_upper + totalHeight > y_lower) - { - ydim_upper = ydim_from_200_16(origin.y + y_upper); - ydim_lower = ydim_from_200_16(origin.y + y_lower); - } - else - { - ydim_upper = 0; - ydim_lower = ydim-1; - } - - for (e = 0; e < object->options->numOptions; ++e) - { - int32_t const x = object->options->menuFormat->pos.x; - - uint8_t status = 0; - if (e == object->options->currentEntry) - status |= MT_Selected; - if (object->options->entryFormat->width == 0) - status |= MT_XCenter; - - bool const dodraw = 0 <= y - object->options->scrollPos + object->options->font->get_yline() && - y - object->options->scrollPos <= object->options->menuFormat->bottomcutoff - object->options->menuFormat->pos.y; - - int32_t const height = object->options->font->get_yline(); // max(textsize.y, object->options->font->get_yline()); - status |= MT_YCenter; - int32_t const y_internal = origin.y + y_upper + y + (height>>1) - object->options->scrollPos; - - vec2_t textsize; - if (dodraw) - textsize = Menu_Text(origin.x + x, y_internal, object->options->font, object->options->optionNames[e], status, ydim_upper, ydim_lower); - - if (object->options->entryFormat->width < 0) - status |= MT_XRight; - - if (dodraw && (status & MT_Selected)) - { - if (status & MT_XCenter) - { - Menu_DrawCursorLeft(origin.x + (MENU_MARGIN_CENTER<<16) + object->options->font->cursorCenterPosition, y_internal, object->options->font->cursorScale); - Menu_DrawCursorRight(origin.x + (MENU_MARGIN_CENTER<<16) - object->options->font->cursorCenterPosition, y_internal, object->options->font->cursorScale); - } - else - Menu_DrawCursorLeft(origin.x + x - object->options->font->cursorLeftPosition, y_internal, object->options->font->cursorScale2); - } - - if (dodraw) - { - const int32_t mousex = origin.x + object->options->entryFormat->width == 0 ? x - textsize.x/2 : x; - const int32_t mousey = origin.y + y_upper + y - object->options->scrollPos; - const int32_t mousewidth = object->options->entryFormat->width == 0 ? textsize.x : klabs(object->options->entryFormat->width); - - if (MOUSEACTIVECONDITIONAL(cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, mousewidth, object->options->font->get_yline()))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, mousewidth, object->options->font->get_yline()))) - { - object->options->currentEntry = e; - } - - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, mousex, mousey, mousewidth, object->options->font->get_yline())) - { - object->options->currentEntry = e; - - if (!Menu_RunInput_EntryOptionList_Activate(entry, object)) - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - - m_mousecaught = 1; - } - } - } - - // prepare for the next line - y += height; - y += calculatedentryspacing; - } - - // draw indicators if applicable - Menu_RunScrollbar(cm, object->options->menuFormat, y_upper + totalHeight, &object->options->scrollPos, 320<<16, origin); -} - -static int32_t Menu_RunInput_MouseAdvance(void) -{ - return MOUSEACTIVECONDITIONAL(!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED); -} - -static int32_t Menu_RunInput_MouseReturn_status; - -#if !defined EDUKE32_TOUCH_DEVICES -static void Menu_Run_MouseReturn(Menu_t *cm, const vec2_t origin) -{ - if (!MOUSEACTIVECONDITION) - return; - - if (cm->menuID == MENU_MAIN) - return; - - uint32_t const posx = tilesiz[SELECTDIR].y * SELECTDIR_z; - - rotatesprite_(origin.x + posx, 0, SELECTDIR_z, 512, SELECTDIR, - Menu_RunInput_MouseReturn_status ? 4 - (sintable[((int32_t) totalclock << 4) & 2047] >> 11) : 6, 0, - 2 | 8 | 16 | RS_ALIGN_L, MOUSEALPHA, 0, xdim_from_320_16(origin.x + x_widescreen_left()), 0, - xdim_from_320_16(origin.x + x_widescreen_left() + (posx>>1)), ydim - 1); -} -#endif - -static int32_t Menu_RunInput_MouseReturn(void) -{ -#if !defined EDUKE32_TOUCH_DEVICES - if (!MOUSEACTIVECONDITION) - { - Menu_RunInput_MouseReturn_status = 0; - return 0; - } -#endif - - if (g_currentMenu == MENU_MAIN) - return 0; - - const int32_t MouseReturnRegionX = x_widescreen_left(); - - vec2_t backbuttonbound = { (tilesiz[SELECTDIR].y * SELECTDIR_z)>>1, tilesiz[SELECTDIR].x * SELECTDIR_z }; - - if (!Menu_MouseOutsideBounds(&m_mousepos, MouseReturnRegionX, 0, backbuttonbound.x, backbuttonbound.y)) - { -#if !defined EDUKE32_TOUCH_DEVICES - Menu_RunInput_MouseReturn_status = 1; -#else - Menu_RunInput_MouseReturn_status = (inputState.mouseClickState() == MOUSE_PRESSED || inputState.mouseClickState() == MOUSE_HELD); -#endif - - return !m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, MouseReturnRegionX, 0, backbuttonbound.x, backbuttonbound.y); - } - - Menu_RunInput_MouseReturn_status = 0; - - return 0; -} - -static void Menu_Run_AbbreviateNameIntoBuffer(const char* name, int32_t entrylength) -{ - int32_t len = Bstrlen(name); - Bstrncpy(tempbuf, name, ARRAY_SIZE(tempbuf)); - if (len > entrylength) - { - len = entrylength-3; - tempbuf[len] = 0; - while (len < entrylength) - tempbuf[len++] = '.'; - } - tempbuf[len] = 0; -} - -static void Menu_Recurse(MenuID_t cm, const vec2_t origin) -{ - switch (cm) - { - case MENU_SAVECLEANVERIFY: - case MENU_LOADVERIFY: - case MENU_LOADDELVERIFY: - case MENU_SAVEVERIFY: - case MENU_SAVEDELVERIFY: - case MENU_ADULTPASSWORD: - case MENU_CHEATENTRY: - case MENU_CHEAT_WARP: - case MENU_CHEAT_SKILL: - Menu_Run(m_previousMenu, origin); - break; - default: - break; - } -} - -static void Menu_Run(Menu_t *cm, const vec2_t origin) -{ - Menu_Recurse(cm->menuID, origin); - - switch (cm->type) - { - case Verify: - { - auto *object = (MenuVerify_t*)cm->object; - - Menu_Pre(cm->menuID); - - Menu_PreDrawBackground(cm->menuID, origin); - - Menu_PreDraw(cm->menuID, NULL, origin); - - Menu_DrawCursorLeft(origin.x + object->cursorpos.x, origin.y + object->cursorpos.y, RR ? 3276 : 65536); - - break; - } - - case Message: - { - auto *object = (MenuMessage_t*)cm->object; - - Menu_Pre(cm->menuID); - - Menu_PreDrawBackground(cm->menuID, origin); - - Menu_PreDraw(cm->menuID, NULL, origin); - - Menu_DrawCursorLeft(origin.x + object->cursorpos.x, origin.y + object->cursorpos.y, RR ? 3276 : 65536); - - break; - } - - case TextForm: - { - auto *object = (MenuTextForm_t*)cm->object; - - Menu_Pre(cm->menuID); - - Menu_PreDrawBackground(cm->menuID, origin); - - Menu_BlackRectangle(origin.x + (60<<16), origin.y + (86<<16), 200<<16, 28<<16, 0); - - mgametextcenter(origin.x, origin.y + (98<<16), object->instructions, TEXT_YBOTTOM); - - const char *displaytext = object->input; - - if (object->flags & MTF_Password) - { - size_t x; - for (x = 0; x < Bstrlen(object->input); ++x) - tempbuf[x] = '*'; - tempbuf[x] = 0; - - displaytext = tempbuf; - } - - const vec2_t textreturn = mgametextcenter(origin.x, origin.y + (102<<16), displaytext); - - Menu_PreDraw(cm->menuID, NULL, origin); - - int32_t const h = MF_Bluefont.get_yline(); - - Menu_DrawCursorText(origin.x + (MENU_MARGIN_CENTER<<16) + (textreturn.x>>1) + (1<<16), origin.y + (102<<16) + (h>>1), h); - - break; - } - - case FileSelect: - { -#if 0 - auto *object = (MenuFileSelect_t*)cm->object; - const int32_t MenuFileSelect_scrollbar_rightedge[2] = { 160<<16, 284<<16 }; - int32_t i, selected = 0; - - Menu_Pre(cm->menuID); - - Menu_PreDrawBackground(cm->menuID, origin); - - if (object->title != NoTitle) - Menu_DrawTopBar(origin); - - - // black translucent background underneath file lists - Menu_BlackRectangle(origin.x + (36<<16), origin.y + (42<<16), 248<<16, 123<<16, 1|32); - - // path - Bsnprintf(tempbuf, sizeof(tempbuf), "Path: %s", object->destination); - mgametext(origin.x + object->format[0]->pos.x, origin.y + (32<<16), tempbuf); - - uint8_t column_status[2] = { 0, MT_RightSide }; - - for (i = 0; i < 2; ++i) - { - if (object->findhigh[i]) - { - CACHE1D_FIND_REC *dir; - int32_t y = 0; - const int32_t y_upper = object->format[i]->pos.y; - const int32_t y_lower = klabs(object->format[i]->bottomcutoff); - - int32_t totalHeight = 0; - for (dir = object->findhigh[i]->usera; dir; dir = dir->next) - { - y += object->font[i]->get_yline(); - totalHeight = y; - y += object->getMarginBottom(i); - } - y = 0; - - int32_t ydim_upper, ydim_lower; - if (y_upper + totalHeight > y_lower) - { - ydim_upper = ydim_from_200_16(origin.y + y_upper); - ydim_lower = ydim_from_200_16(origin.y + y_lower); - } - else - { - ydim_upper = 0; - ydim_lower = ydim-1; - } - - for (dir = object->findhigh[i]->usera; dir; dir = dir->next) - { - uint8_t status = column_status[i]; - if (dir == object->findhigh[i] && object->currentList == i) - status |= MT_Selected; - - Menu_Run_AbbreviateNameIntoBuffer(dir->name, USERMAPENTRYLENGTH); - - const int32_t thisx = object->format[i]->pos.x; - const int32_t thisy = y - object->scrollPos[i]; - - int32_t const height = object->font[i]->get_yline(); - - if (0 <= thisy + height && thisy <= klabs(object->format[i]->bottomcutoff) - object->format[i]->pos.y) - { - status |= MT_YCenter; - - const int32_t mousex = origin.x + thisx; - const int32_t mousey = origin.y + y_upper + thisy + (height>>1); - - vec2_t textdim = Menu_Text(mousex, mousey, object->font[i], tempbuf, status, ydim_upper, ydim_lower); - - if (MOUSEACTIVECONDITIONAL(cm == m_currentMenu && !Menu_MouseOutsideBounds(&m_mousepos, mousex, mousey, textdim.x, object->font[i]->get_yline()))) - { - if (MOUSEWATCHPOINTCONDITIONAL(Menu_MouseOutsideBounds(&m_prevmousepos, mousex, mousey, textdim.x, object->font[i]->get_yline()))) - { - object->findhigh[i] = dir; - object->currentList = i; - - Menu_RunInput_FileSelect_MovementVerify(object); - } - - if (!m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !Menu_MouseOutsideBounds(&m_mousedownpos, mousex, mousey, textdim.x, object->font[i]->get_yline())) - { - object->findhigh[i] = dir; - object->currentList = i; - - Menu_RunInput_FileSelect_MovementVerify(object); - - m_mousecaught = 1; - selected = 1; - } - } - } - - y += object->font[i]->get_yline() + object->getMarginBottom(i); - } - - Menu_RunScrollbar(cm, object->format[i], y_upper + totalHeight, &object->scrollPos[i], MenuFileSelect_scrollbar_rightedge[i], origin); - } - } - - Menu_PreDraw(cm->menuID, NULL, origin); - - if (object->title != NoTitle) - Menu_DrawTopBarCaption(object->title, origin); - - if (selected) - { - Menu_RunInput_FileSelect_Select(object); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - - m_mousecaught = 1; - } -#endif - break; - } - - case Panel: - { - auto *object = (MenuPanel_t*)cm->object; - - Menu_Pre(cm->menuID); - - Menu_PreDrawBackground(cm->menuID, origin); - - if (object->title != NoTitle) - Menu_DrawTopBar(origin); - - Menu_PreDraw(cm->menuID, NULL, origin); - - if (object->title != NoTitle) - Menu_DrawTopBarCaption(object->title, origin); - - break; - } - - case CdPlayer: - { - auto *menu = (MenuMenu_t*)cm->object; - Menu_Pre(cm->menuID); - - Menu_PreDrawBackground(cm->menuID, origin); - - if (menu->title != NoTitle) - Menu_DrawTopBar(origin); - - Menu_PreDraw(cm->menuID, NULL, origin); - - M_RunMenu_CdPlayer(cm, menu, origin); - - if (menu->title != NoTitle) - Menu_DrawTopBarCaption(menu->title, origin); - - break; - } - - case Menu: - { - int32_t state; - - auto *menu = (MenuMenu_t*)cm->object; - MenuEntry_t *currentry = menu->entrylist[menu->currentEntry]; - - state = Menu_DetermineSpecialState(currentry); - - if (state != 2) - { - Menu_Pre(cm->menuID); - - Menu_PreDrawBackground(cm->menuID, origin); - - if (menu->title != NoTitle) - Menu_DrawTopBar(origin); - - Menu_PreDraw(cm->menuID, currentry, origin); - - M_RunMenu_Menu(cm, menu, currentry, state, origin); - } - else - { - Menu_PreDrawBackground(cm->menuID, origin); - - if (menu->title != NoTitle) - Menu_DrawTopBar(origin); - - if (currentry->type == Option) - { - if (currentry->name) - Menu_DrawTopBarCaption(currentry->name, origin); - - Menu_PreOptionListDraw(currentry, origin); - - Menu_RunOptionList(cm, currentry, (MenuOption_t*)currentry->entry, origin); - } - else if (currentry->type == Custom2Col) - { - Menu_PreCustom2ColScreenDraw(currentry, origin); - } - } - - if ((currentry->type != Option || state != 2) && menu->title != NoTitle) - Menu_DrawTopBarCaption(menu->title, origin); - - break; - } - } - -#if !defined EDUKE32_TOUCH_DEVICES - Menu_Run_MouseReturn(cm, origin); -#endif -} - -/* -Note: When menus are exposed to scripting, care will need to be taken so that -a user cannot define an empty MenuEntryList, or one containing only spacers, -or else this function will recurse infinitely. -*/ -static MenuEntry_t *Menu_RunInput_Menu_MovementVerify(MenuMenu_t *menu) -{ - return Menu_AdjustForCurrentEntryAssignment(menu); -} - -static MenuEntry_t *Menu_RunInput_Menu_Movement(MenuMenu_t *menu, MenuMovement_t direction) -{ - if (menu->numEntries == 1) - return menu->entrylist[menu->currentEntry]; - - switch (direction) - { - case MM_End: - menu->currentEntry = menu->numEntries; - fallthrough__; - case MM_Up: - do - { - --menu->currentEntry; - if (menu->currentEntry < 0) - return Menu_RunInput_Menu_Movement(menu, MM_End); - } - while (!menu->entrylist[menu->currentEntry] || - (menu->entrylist[menu->currentEntry]->flags & MEF_Hidden) || - menu->entrylist[menu->currentEntry]->type == Spacer); - break; - - case MM_Home: - menu->currentEntry = -1; - fallthrough__; - case MM_Down: - do - { - ++menu->currentEntry; - if (menu->currentEntry >= menu->numEntries) - return Menu_RunInput_Menu_Movement(menu, MM_Home); - } - while (!menu->entrylist[menu->currentEntry] || - (menu->entrylist[menu->currentEntry]->flags & MEF_Hidden) || - menu->entrylist[menu->currentEntry]->type == Spacer); - break; - - case MM_Swap: - menu->currentColumn = !menu->currentColumn; - break; - - default: - break; - } - - return Menu_RunInput_Menu_MovementVerify(menu); -} - -static void Menu_RunInput_EntryLink_Activate(MenuEntry_t *entry) -{ - auto *link = (MenuLink_t*)entry->entry; - - Menu_EntryLinkActivate(entry); - - Menu_AnimateChange(link->linkID, link->animation); -} - -static void Menu_RunInput_EntryOptionList_MovementVerify(MenuOption_t *object) -{ - const int32_t listytop = object->options->menuFormat->pos.y; - // assumes height == font->get_yline()! - const int32_t unitheight = object->options->getMarginBottom() < 0 ? (-object->options->getMarginBottom() - object->options->font->get_yline()) / object->options->numOptions : (object->options->font->get_yline() + object->options->getMarginBottom()); - const int32_t ytop = listytop + object->options->currentEntry * unitheight; - const int32_t ybottom = ytop + object->options->font->get_yline(); - - if (ybottom - object->options->scrollPos > object->options->menuFormat->bottomcutoff) - object->options->scrollPos = ybottom - object->options->menuFormat->bottomcutoff; - else if (ytop - object->options->scrollPos < listytop) - object->options->scrollPos = ytop - listytop; -} - -static void Menu_RunInput_EntryOptionList_Movement(MenuOption_t *object, MenuMovement_t direction) -{ - switch (direction) - { - case MM_Up: - --object->options->currentEntry; - if (object->options->currentEntry >= 0) - break; - fallthrough__; - case MM_End: - object->options->currentEntry = object->options->numOptions-1; - break; - - case MM_Down: - ++object->options->currentEntry; - if (object->options->currentEntry < object->options->numOptions) - break; - fallthrough__; - case MM_Home: - object->options->currentEntry = 0; - break; - - default: - break; - } - - Menu_RunInput_EntryOptionList_MovementVerify(object); -} - -static int32_t Menu_RunInput_EntryOption_Modify(MenuEntry_t *entry, MenuOption_t *object, int32_t newValueIndex) -{ - int32_t newValue = (object->options->optionValues == NULL) ? newValueIndex : object->options->optionValues[newValueIndex]; - if (!Menu_EntryOptionModify(entry, newValue)) - { - object->currentOption = newValueIndex; - - if (object->cVar != NULL) // NULL implies the functions will handle it - { - UCVarValue v; - v.Int = newValue; - object->cVar->ForceSet(v, CVAR_Int, false); - } - Menu_EntryOptionDidModify(entry); - - return 0; - } - - return -1; -} - -static int32_t Menu_RunInput_EntryOption_Movement(MenuEntry_t *entry, MenuOption_t *object, MenuMovement_t direction) -{ - int32_t newValueIndex = object->currentOption; - - switch (direction) - { - case MM_Left: - --newValueIndex; - if (newValueIndex >= 0) - break; - fallthrough__; - case MM_AllTheWayRight: - newValueIndex = object->options->numOptions-1; - break; - - case MM_Right: - ++newValueIndex; - if (newValueIndex < object->options->numOptions) - break; - fallthrough__; - case MM_AllTheWayLeft: - newValueIndex = 0; - break; - - default: - break; - } - - return Menu_RunInput_EntryOption_Modify(entry, object, newValueIndex); -} - -static int32_t Menu_RunInput_EntryOption_Activate(MenuEntry_t *entry, MenuOption_t *object) -{ - if (object->options->features & 2) - return Menu_RunInput_EntryOption_Movement(entry, object, MM_Right); - else - { - object->options->currentEntry = object->currentOption >= 0 ? object->currentOption : 0; - Menu_RunInput_EntryOptionList_MovementVerify(object); - - return 0; - } -} - -static int32_t Menu_RunInput_EntryOptionList_Activate(MenuEntry_t *entry, MenuOption_t *object) -{ - if (!Menu_RunInput_EntryOption_Modify(entry, object, object->options->currentEntry)) - { - object->options->currentEntry = -1; - - return 0; - } - - return -1; -} - -static void Menu_RunInput_EntryCustom2Col_Activate(MenuEntry_t *entry) -{ - auto *object = (MenuCustom2Col_t*)entry->entry; - - Menu_Custom2ColScreen(/*entry*/); - - object->screenOpen = 1; -} - -static void Menu_RunInput_EntryRangeInt32_MovementVerify(MenuEntry_t *entry, MenuRangeInt32_t *object, int32_t newValue) -{ - if (!Menu_EntryRangeInt32Modify(entry, newValue)) - *object->cVar = newValue; -} - -static void Menu_RunInput_EntryRangeInt32_MovementArbitrary(MenuEntry_t *entry, MenuRangeInt32_t *object, int32_t newValue) -{ - if (object->flags & EnforceIntervals) - { - int32_t const range = object->max - object->min; - int32_t const maxInterval = object->steps - 1; - int32_t const newValueIndex = roundscale(newValue - object->min, maxInterval, range); - newValue = newValueIndex * range / maxInterval + object->min; - } - - Menu_RunInput_EntryRangeInt32_MovementVerify(entry, object, newValue); -} - -static void Menu_RunInput_EntryRangeInt32_Movement(MenuEntry_t *entry, MenuRangeInt32_t *object, MenuMovement_t direction) -{ - int32_t const oldValue = *object->cVar; - int32_t const range = object->max - object->min; - int32_t const maxInterval = object->steps - 1; - int32_t const oldValueIndex = roundscale(oldValue - object->min, maxInterval, range); - int32_t const oldValueQuantized = oldValueIndex * range / maxInterval + object->min; - int32_t newValueIndex = oldValueIndex; - - switch (direction) - { - case MM_Left: - if (oldValueQuantized >= oldValue) - --newValueIndex; - if (newValueIndex >= 0) - break; - fallthrough__; - case MM_AllTheWayLeft: - newValueIndex = 0; - break; - - case MM_Right: - if (oldValueQuantized <= oldValue) - ++newValueIndex; - if (newValueIndex <= maxInterval) - break; - fallthrough__; - case MM_AllTheWayRight: - newValueIndex = maxInterval; - break; - - default: - break; - } - - int32_t const newValue = newValueIndex * range / maxInterval + object->min; - Menu_RunInput_EntryRangeInt32_MovementVerify(entry, object, newValue); -} - -static void Menu_RunInput_EntryRangeFloat_MovementVerify(MenuEntry_t *entry, MenuRangeFloat_t *object, float newValue) -{ - if (!Menu_EntryRangeFloatModify(entry, newValue)) - { - *object->cVar = newValue; - Menu_EntryRangeFloatDidModify(entry); - } -} - -static void Menu_RunInput_EntryRangeFloat_MovementArbitrary(MenuEntry_t *entry, MenuRangeFloat_t *object, float newValue) -{ - if (object->flags & EnforceIntervals) - { - float const range = object->max - object->min; - float const maxInterval = (float)(object->steps - 1); - float const newValueIndex = rintf((newValue - object->min) * maxInterval / range); - newValue = newValueIndex * range / maxInterval + object->min; - } - - Menu_RunInput_EntryRangeFloat_MovementVerify(entry, object, newValue); -} - -static void Menu_RunInput_EntryRangeFloat_Movement(MenuEntry_t *entry, MenuRangeFloat_t *object, MenuMovement_t direction) -{ - float const oldValue = *object->cVar; - float const range = object->max - object->min; - float const maxInterval = (float)(object->steps - 1); - float const oldValueIndexUnrounded = (oldValue - object->min) * maxInterval / range; - float const oldValueIndex = rintf(oldValueIndexUnrounded); - float const oldValueQuantized = oldValueIndex * range / maxInterval + object->min; - float newValueIndex = oldValueIndex; - - switch (direction) - { - case MM_Left: - if (oldValueQuantized >= oldValue) - newValueIndex -= 1.f; - if (newValueIndex >= 0.f) - break; - fallthrough__; - case MM_AllTheWayLeft: - newValueIndex = 0.f; - break; - - case MM_Right: - if (oldValueQuantized <= oldValue) - newValueIndex += 1.f; - if (newValueIndex <= maxInterval) - break; - fallthrough__; - case MM_AllTheWayRight: - newValueIndex = maxInterval; - break; - - default: - break; - } - - float const newValue = newValueIndex * range / maxInterval + object->min; - Menu_RunInput_EntryRangeFloat_MovementVerify(entry, object, newValue); -} - -#ifdef MENU_ENABLE_RANGEDOUBLE -static void Menu_RunInput_EntryRangeDouble_MovementVerify(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, double newValue) -{ - if (!Menu_EntryRangeDoubleModify(/*entry, newValue*/)) - *object->variable = newValue; -} - -static void Menu_RunInput_EntryRangeDouble_MovementArbitrary(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, double newValue) -{ - if (object->flags & EnforceIntervals) - { - double const range = object->max - object->min; - double const maxInterval = object->steps - 1; - double const newValueIndex = rint((newValue - object->min) * maxInterval / range); - newValue = newValueIndex * range / maxInterval + object->min; - } - - Menu_RunInput_EntryRangeDouble_MovementVerify(/*entry, */object, newValue); -} - -static void Menu_RunInput_EntryRangeDouble_Movement(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, MenuMovement_t direction) -{ - double const oldValue = *object->variable; - double const range = object->max - object->min; - double const maxInterval = object->steps - 1; - double const oldValueIndex = rint((oldValue - object->min) * maxInterval / range); - double const oldValueQuantized = oldValueIndex * range / maxInterval + object->min; - double newValueIndex = oldValueIndex; - - switch (direction) - { - case MM_Left: - if (oldValueQuantized >= oldValue) - newValueIndex -= 1.; - if (newValueIndex >= 0.) - break; - fallthrough__; - case MM_AllTheWayLeft: - newValueIndex = 0.; - break; - - case MM_Right: - if (oldValueQuantized <= oldValue) - newValueIndex += 1.; - if (newValueIndex <= maxInterval) - break; - fallthrough__; - case MM_AllTheWayRight: - newValueIndex = maxInterval; - break; - - default: - break; - } - - double const newValue = newValueIndex * range / maxInterval + object->min; - Menu_RunInput_EntryRangeDouble_MovementVerify(/*entry, */object, newValue); -} -#endif - -static void Menu_RunInput_EntryString_Activate(MenuEntry_t *entry) -{ - auto *object = (MenuString_t*)entry->entry; - - if (object->variable) - strncpy(typebuf, object->variable, TYPEBUFSIZE); - else - typebuf[0] = '\0'; - object->editfield = typebuf; - - // this limitation is an arbitrary implementation detail - if (object->bufsize > TYPEBUFSIZE) - object->bufsize = TYPEBUFSIZE; - - Menu_EntryStringActivate(/*entry*/); - Menu_StartTextInput(); -} - -static void Menu_RunInput_EntryString_Submit(/*MenuEntry_t *entry, */MenuString_t *object) -{ - if (!Menu_EntryStringSubmit(/*entry, */object->editfield)) - { - if (object->variable) - strncpy(object->variable, object->editfield, object->bufsize); - } - - object->editfield = NULL; - Menu_StopTextInput(); -} - -static void Menu_RunInput_EntryString_Cancel(/*MenuEntry_t *entry, */MenuString_t *object) -{ - Menu_EntryStringCancel(/*entry*/); - - object->editfield = NULL; - Menu_StopTextInput(); -} - -static void Menu_RunInput_FileSelect_MovementVerify(MenuFileSelect_t *object) -{ -#if 0 - const int32_t listytop = object->format[object->currentList]->pos.y; - const int32_t listybottom = klabs(object->format[object->currentList]->bottomcutoff); - const int32_t ytop = listytop + object->findhigh[object->currentList]->type * (object->font[object->currentList]->get_yline() + object->getMarginBottom(object->currentList)); - const int32_t ybottom = ytop + object->font[object->currentList]->get_yline(); - - if (ybottom - object->scrollPos[object->currentList] > listybottom) - object->scrollPos[object->currentList] = ybottom - listybottom; - else if (ytop - object->scrollPos[object->currentList] < listytop) - object->scrollPos[object->currentList] = ytop - listytop; -#endif -} - -static void Menu_RunInput_FileSelect_Movement(MenuFileSelect_t *object, MenuMovement_t direction) -{ -#if 0 - switch (direction) - { - case MM_Up: - if (!object->findhigh[object->currentList]) - break; - if (object->findhigh[object->currentList]->prev) - { - object->findhigh[object->currentList] = object->findhigh[object->currentList]->prev; - break; - } - fallthrough__; - case MM_End: - object->findhigh[object->currentList] = object->findhigh[object->currentList]->userb; - break; - - case MM_Down: - if (!object->findhigh[object->currentList]) - break; - if (object->findhigh[object->currentList]->next) - { - object->findhigh[object->currentList] = object->findhigh[object->currentList]->next; - break; - } - fallthrough__; - case MM_Home: - object->findhigh[object->currentList] = object->findhigh[object->currentList]->usera; - break; - - case MM_Swap: - object->currentList = !object->currentList; - break; - - default: - break; - } - - Menu_RunInput_FileSelect_MovementVerify(object); -#endif -} - -static void Menu_RunInput_FileSelect_Select(MenuFileSelect_t *object) -{ -#if 0 - if (!object->findhigh[object->currentList]) - return; - - Bstrcat(object->destination, object->findhigh[object->currentList]->name); - - if (object->currentList == 0) - { - Bstrcat(object->destination, "/"); - Bcorrectfilename(object->destination, 1); - - Menu_FileSelectInit(object); - } - else - { - Menu_FileSelect(1); - } -#endif -} - -static void Menu_RunInput(Menu_t *cm) -{ - switch (cm->type) - { - case Panel: - { - auto *panel = (MenuPanel_t*)cm->object; - - if (I_ReturnTrigger() || Menu_RunInput_MouseReturn()) - { - I_ReturnTriggerClear(); - m_mousecaught = 1; - - S_PlaySound(EXITMENUSOUND); - - Menu_AnimateChange(cm->parentID, cm->parentAnimation); - } - else if (I_PanelUp()) - { - I_PanelUpClear(); - - S_PlaySound(RR ? 335 : KICK_HIT); - Menu_AnimateChange(panel->previousID, panel->previousAnimation); - } - else if (I_PanelDown() || Menu_RunInput_MouseAdvance()) - { - I_PanelDownClear(); - m_mousecaught = 1; - - S_PlaySound(RR ? 335 : KICK_HIT); - Menu_AnimateChange(panel->nextID, panel->nextAnimation); - } - break; - } - - case TextForm: - { - auto *object = (MenuTextForm_t*)cm->object; - int32_t hitstate = I_EnterText(object->input, object->bufsize-1, 0); - - if (hitstate == -1 || Menu_RunInput_MouseReturn()) - { - m_mousecaught = 1; - - S_PlaySound(EXITMENUSOUND); - - object->input = NULL; - - Menu_AnimateChange(cm->parentID, cm->parentAnimation); - Menu_StopTextInput(); - } - else if (hitstate == 1 || Menu_RunInput_MouseAdvance()) - { - m_mousecaught = 1; - - Menu_TextFormSubmit(object->input); - - object->input = NULL; - Menu_StopTextInput(); - } - break; - } - - case FileSelect: - { -#if 0 - auto *object = (MenuFileSelect_t*)cm->object; - - if (I_ReturnTrigger() || Menu_RunInput_MouseReturn()) - { - I_ReturnTriggerClear(); - m_mousecaught = 1; - - S_PlaySound(EXITMENUSOUND); - - object->destination[0] = 0; - - Menu_FileSelect(0); - - Menu_AnimateChange(cm->parentID, MA_Return); - } - else if (I_AdvanceTrigger()) - { - I_AdvanceTriggerClear(); - - Menu_RunInput_FileSelect_Select(object); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - } - else if (inputState.GetKeyStatus(sc_Home)) - { - inputState.ClearKeyStatus(sc_Home); - - Menu_RunInput_FileSelect_Movement(object, MM_Home); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - else if (inputState.GetKeyStatus(sc_End)) - { - inputState.ClearKeyStatus(sc_End); - - Menu_RunInput_FileSelect_Movement(object, MM_End); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - else if (inputState.GetKeyStatus(sc_PgUp)) - { - int32_t i; - - CACHE1D_FIND_REC *seeker = object->findhigh[object->currentList]; - - inputState.ClearKeyStatus(sc_PgUp); - - for (i = 0; i < 6; ++i) - { - if (seeker && seeker->prev) - seeker = seeker->prev; - } - - if (seeker) - { - object->findhigh[object->currentList] = seeker; - - Menu_RunInput_FileSelect_MovementVerify(object); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - } - else if (inputState.GetKeyStatus(sc_PgDn)) - { - int32_t i; - - CACHE1D_FIND_REC *seeker = object->findhigh[object->currentList]; - - inputState.ClearKeyStatus(sc_PgDn); - - for (i = 0; i < 6; ++i) - { - if (seeker && seeker->next) - seeker = seeker->next; - } - - if (seeker) - { - object->findhigh[object->currentList] = seeker; - - Menu_RunInput_FileSelect_MovementVerify(object); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - } - else if (I_MenuLeft() || I_MenuRight()) - { - I_MenuLeftClear(); - I_MenuRightClear(); - - if ((object->currentList ? object->fnlist.numdirs : object->fnlist.numfiles) > 0) - { - Menu_RunInput_FileSelect_Movement(object, MM_Swap); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - } - else if (I_MenuUp()) - { - I_MenuUpClear(); - - Menu_RunInput_FileSelect_Movement(object, MM_Up); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - else if (I_MenuDown()) - { - I_MenuDownClear(); - - Menu_RunInput_FileSelect_Movement(object, MM_Down); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - else - { - // JBF 20040208: seek to first name matching pressed character - char ch2, ch; - ch = inputState.keyGetChar(); - if (ch > 0 && ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9'))) - { - CACHE1D_FIND_REC *seeker = object->findhigh[object->currentList]->usera; - if (ch >= 'a') - ch -= ('a'-'A'); - while (seeker) - { - ch2 = seeker->name[0]; - if (ch2 >= 'a' && ch2 <= 'z') - ch2 -= ('a'-'A'); - if (ch2 == ch) - break; - seeker = seeker->next; - } - if (seeker) - { - object->findhigh[object->currentList] = seeker; - - Menu_RunInput_FileSelect_MovementVerify(object); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - } - } -#endif - Menu_PreInput(NULL); - break; - } - - case Message: - if (I_ReturnTrigger() || Menu_RunInput_MouseReturn()) - { - I_ReturnTriggerClear(); - m_mousecaught = 1; - - S_PlaySound(EXITMENUSOUND); - - Menu_AnimateChange(cm->parentID, cm->parentAnimation); - } - - if (I_CheckAllInput()) - { - auto *message = (MenuMessage_t*)cm->object; - - I_ClearAllInput(); - - S_PlaySound(EXITMENUSOUND); - - Menu_AnimateChange(message->linkID, message->animation); - } - - Menu_PreInput(NULL); - break; - - case Verify: - if (I_ReturnTrigger() || inputState.GetKeyStatus(sc_N) || Menu_RunInput_MouseReturn()) - { - I_ReturnTriggerClear(); - inputState.ClearKeyStatus(sc_N); - m_mousecaught = 1; - - Menu_Verify(0); - - Menu_AnimateChange(cm->parentID, cm->parentAnimation); - - S_PlaySound(EXITMENUSOUND); - } - - if (I_AdvanceTrigger() || inputState.GetKeyStatus(sc_Y) || Menu_RunInput_MouseAdvance()) - { - auto *verify = (MenuVerify_t*)cm->object; - - I_AdvanceTriggerClear(); - inputState.ClearKeyStatus(sc_Y); - m_mousecaught = 1; - - Menu_Verify(1); - - Menu_AnimateChange(verify->linkID, verify->animation); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - } - - Menu_PreInput(NULL); - break; - - case CdPlayer: - { - auto *menu = (MenuMenu_t*)cm->object; - MenuEntry_t *currentry = menu->entrylist[menu->currentEntry]; - - if (I_AdvanceTrigger()) - { - I_AdvanceTriggerClear(); - - mus_enabled = !mus_enabled; - - if (mus_enabled == 0) - S_PauseMusic(true); - else - { - S_PlayRRMusic(2+menu->currentEntry); - S_PauseMusic(false); - } - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - } - - if (I_ReturnTrigger() || I_EscapeTrigger() || Menu_RunInput_MouseReturn()) - { - I_ReturnTriggerClear(); - I_EscapeTriggerClear(); - m_mousecaught = 1; - - if (cm->parentID != MENU_CLOSE || (g_player[myconnectindex].ps->gm & MODE_GAME)) - S_PlaySound(EXITMENUSOUND); - - Menu_AnimateChange(cm->parentID, cm->parentAnimation); - } - else if (I_MenuUp() || I_MenuLeft()) - { - I_MenuUpClear(); - I_MenuLeftClear(); - - S_PlaySound(RR ? 335 : KICK_HIT); - - currentry = Menu_RunInput_Menu_Movement(menu, MM_Up); - - if (MusicEnabled()) - { - S_StopMusic(); - S_PlayRRMusic(2+menu->currentEntry); - } - } - else if (I_MenuDown() || I_MenuRight()) - { - I_MenuDownClear(); - I_MenuRightClear(); - - S_PlaySound(RR ? 335 : KICK_HIT); - - currentry = Menu_RunInput_Menu_Movement(menu, MM_Down); - - if (MusicEnabled()) - { - S_StopMusic(); - S_PlayRRMusic(2+menu->currentEntry); - } - } - else if (inputState.GetKeyStatus(sc_1)) - { - inputState.ClearKeyStatus(sc_1); - menu->currentEntry = 0; - - S_PlaySound(RR ? 335 : KICK_HIT); - if (MusicEnabled()) - { - S_StopMusic(); - S_PlayRRMusic(2+menu->currentEntry); - } - } - else if (inputState.GetKeyStatus(sc_2)) - { - inputState.ClearKeyStatus(sc_2); - menu->currentEntry = 1; - - S_PlaySound(RR ? 335 : KICK_HIT); - if (MusicEnabled()) - { - S_StopMusic(); - S_PlayRRMusic(2+menu->currentEntry); - } - } - else if (inputState.GetKeyStatus(sc_3)) - { - inputState.ClearKeyStatus(sc_3); - menu->currentEntry = 2; - - S_PlaySound(RR ? 335 : KICK_HIT); - if (MusicEnabled()) - { - S_StopMusic(); - S_PlayRRMusic(2+menu->currentEntry); - } - } - else if (inputState.GetKeyStatus(sc_4)) - { - inputState.ClearKeyStatus(sc_4); - menu->currentEntry = 3; - - S_PlaySound(RR ? 335 : KICK_HIT); - if (MusicEnabled()) - { - S_StopMusic(); - S_PlayRRMusic(2+menu->currentEntry); - } - } - else if (inputState.GetKeyStatus(sc_5)) - { - inputState.ClearKeyStatus(sc_5); - menu->currentEntry = 4; - - S_PlaySound(RR ? 335 : KICK_HIT); - if (MusicEnabled()) - { - S_StopMusic(); - S_PlayRRMusic(2+menu->currentEntry); - } - } - else if (inputState.GetKeyStatus(sc_6)) - { - inputState.ClearKeyStatus(sc_6); - menu->currentEntry = 5; - - S_PlaySound(RR ? 335 : KICK_HIT); - if (MusicEnabled()) - { - S_StopMusic(); - S_PlayRRMusic(2+menu->currentEntry); - } - } - else if (inputState.GetKeyStatus(sc_7)) - { - inputState.ClearKeyStatus(sc_7); - menu->currentEntry = 6; - - S_PlaySound(RR ? 335 : KICK_HIT); - if (MusicEnabled()) - { - S_StopMusic(); - S_PlayRRMusic(2+menu->currentEntry); - } - } - else if (inputState.GetKeyStatus(sc_8)) - { - inputState.ClearKeyStatus(sc_8); - menu->currentEntry = 7; - - S_PlaySound(RR ? 335 : KICK_HIT); - if (MusicEnabled()) - { - S_StopMusic(); - S_PlayRRMusic(2+menu->currentEntry); - } - } - - if (currentry != NULL) - Menu_PreInput(currentry); - - break; - } - - case Menu: - { - int32_t state; - - auto *menu = (MenuMenu_t*)cm->object; - MenuEntry_t *currentry = menu->entrylist[menu->currentEntry]; - - state = Menu_DetermineSpecialState(currentry); - - if (state == 0) - { - if (currentry != NULL) - switch (currentry->type) - { - case Dummy: - case Spacer: - break; - case Link: - if (currentry->flags & MEF_Disabled) - break; - if (I_AdvanceTrigger()) - { - I_AdvanceTriggerClear(); - - Menu_RunInput_EntryLink_Activate(currentry); - - if (g_player[myconnectindex].ps->gm&MODE_MENU) // for skill selection - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - } - break; - case Option: - { - auto *object = (MenuOption_t*)currentry->entry; - - if (currentry->flags & MEF_Disabled) - break; - - if (I_AdvanceTrigger()) - { - I_AdvanceTriggerClear(); - - Menu_RunInput_EntryOption_Activate(currentry, object); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - } - else if (I_MenuRight()) - { - I_MenuRightClear(); - - Menu_RunInput_EntryOption_Movement(currentry, object, MM_Right); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - } - else if (I_MenuLeft()) - { - I_MenuLeftClear(); - - Menu_RunInput_EntryOption_Movement(currentry, object, MM_Left); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - } - } - break; - case Custom2Col: - if (I_MenuLeft() || I_MenuRight()) - { - I_MenuLeftClear(); - I_MenuRightClear(); - - Menu_RunInput_Menu_Movement(menu, MM_Swap); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - - if (currentry->flags & MEF_Disabled) - break; - - if (I_AdvanceTrigger()) - { - I_AdvanceTriggerClear(); - - Menu_RunInput_EntryCustom2Col_Activate(currentry); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - } - break; - case RangeInt32: - { - auto *object = (MenuRangeInt32_t*)currentry->entry; - - if (currentry->flags & MEF_Disabled) - break; - - if (I_SliderLeft()) - { - I_SliderLeftClear(); - - Menu_RunInput_EntryRangeInt32_Movement(currentry, object, MM_Left); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - else if (I_SliderRight()) - { - I_SliderRightClear(); - - Menu_RunInput_EntryRangeInt32_Movement(currentry, object, MM_Right); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - break; - } - case RangeFloat: - { - auto *object = (MenuRangeFloat_t*)currentry->entry; - - if (currentry->flags & MEF_Disabled) - break; - - if (I_SliderLeft()) - { - I_SliderLeftClear(); - - Menu_RunInput_EntryRangeFloat_Movement(currentry, object, MM_Left); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - else if (I_SliderRight()) - { - I_SliderRightClear(); - - Menu_RunInput_EntryRangeFloat_Movement(currentry, object, MM_Right); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - break; - } -#ifdef MENU_ENABLE_RANGEDOUBLE - case RangeDouble: - { - MenuRangeDouble_t *object = (MenuRangeDouble_t*)currentry->entry; - - if (currentry->flags & MEF_Disabled) - break; - - if (I_SliderLeft()) - { - I_SliderLeftClear(); - - Menu_RunInput_EntryRangeDouble_Movement(/*currentry, */object, MM_Left); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - else if (I_SliderRight()) - { - I_SliderRightClear(); - - Menu_RunInput_EntryRangeDouble_Movement(/*currentry, */object, MM_Right); - - S_PlaySound(RR ? 335 : KICK_HIT); - } - break; - } -#endif - - case String: - { - if (currentry->flags & MEF_Disabled) - break; - - if (I_AdvanceTrigger()) - { - I_AdvanceTriggerClear(); - - Menu_RunInput_EntryString_Activate(currentry); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - } - - break; - } - } - - if (I_ReturnTrigger() || I_EscapeTrigger() || Menu_RunInput_MouseReturn()) - { - I_ReturnTriggerClear(); - I_EscapeTriggerClear(); - m_mousecaught = 1; - - if (cm->parentID != MENU_CLOSE || (g_player[myconnectindex].ps->gm & MODE_GAME)) - S_PlaySound(EXITMENUSOUND); - - Menu_AnimateChange(cm->parentID, cm->parentAnimation); - } - else if (inputState.GetKeyStatus(sc_Home)) - { - inputState.ClearKeyStatus(sc_Home); - - S_PlaySound(RR ? 335 : KICK_HIT); - - currentry = Menu_RunInput_Menu_Movement(menu, MM_Home); - } - else if (inputState.GetKeyStatus(sc_End)) - { - inputState.ClearKeyStatus(sc_End); - - S_PlaySound(RR ? 335 : KICK_HIT); - - currentry = Menu_RunInput_Menu_Movement(menu, MM_End); - } - else if (I_MenuUp()) - { - I_MenuUpClear(); - - S_PlaySound(RR ? 335 : KICK_HIT); - - currentry = Menu_RunInput_Menu_Movement(menu, MM_Up); - } - else if (I_MenuDown()) - { - I_MenuDownClear(); - - S_PlaySound(RR ? 335 : KICK_HIT); - - currentry = Menu_RunInput_Menu_Movement(menu, MM_Down); - } - - if (currentry != NULL) - Menu_PreInput(currentry); - } - else if (state == 1) - { - if (currentry->type == String) - { - auto *object = (MenuString_t*)currentry->entry; - - int32_t hitstate = I_EnterText(object->editfield, object->bufsize-1, object->flags); - - if (hitstate == -1 || Menu_RunInput_MouseReturn()) - { - m_mousecaught = 1; - - Menu_RunInput_EntryString_Cancel(/*currentry, */object); - - S_PlaySound(EXITMENUSOUND); - } - else if (hitstate == 1) - { - Menu_RunInput_EntryString_Submit(/*currentry, */object); - - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - } - } - } - else if (state == 2) - { - if (currentry->type == Option) - { - auto *object = (MenuOption_t*)currentry->entry; - - if (I_ReturnTrigger() || Menu_RunInput_MouseReturn()) - { - I_ReturnTriggerClear(); - m_mousecaught = 1; - - S_PlaySound(EXITMENUSOUND); - - object->options->currentEntry = -1; - } - else if (I_AdvanceTrigger()) - { - I_AdvanceTriggerClear(); - - if (!Menu_RunInput_EntryOptionList_Activate(currentry, object)) - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - } - else if (inputState.GetKeyStatus(sc_Home)) - { - inputState.ClearKeyStatus(sc_Home); - - S_PlaySound(RR ? 335 : KICK_HIT); - - Menu_RunInput_EntryOptionList_Movement(object, MM_Home); - } - else if (inputState.GetKeyStatus(sc_End)) - { - inputState.ClearKeyStatus(sc_End); - - S_PlaySound(RR ? 335 : KICK_HIT); - - Menu_RunInput_EntryOptionList_Movement(object, MM_End); - } - else if (I_MenuUp()) - { - I_MenuUpClear(); - - S_PlaySound(RR ? 335 : KICK_HIT); - - Menu_RunInput_EntryOptionList_Movement(object, MM_Up); - } - else if (I_MenuDown()) - { - I_MenuDownClear(); - - S_PlaySound(RR ? 335 : KICK_HIT); - - Menu_RunInput_EntryOptionList_Movement(object, MM_Down); - } - } - else if (currentry->type == Custom2Col) - { - if (I_EscapeTrigger() || Menu_RunInput_MouseReturn()) - { - I_EscapeTriggerClear(); - m_mousecaught = 1; - - S_PlaySound(EXITMENUSOUND); - - ((MenuCustom2Col_t*)currentry->entry)->screenOpen = 0; - } - else if (Menu_PreCustom2ColScreen(currentry)) - ((MenuCustom2Col_t*)currentry->entry)->screenOpen = 0; - } - } - - break; - } - } -} - -// This function MUST NOT RECURSE. That is why Menu_Run is separate. -void M_DisplayMenus(void) -{ - vec2_t origin = { 0, 0 }, previousOrigin = { 0, 0 }; - - Net_GetPackets(); - - if ((g_player[myconnectindex].ps->gm&MODE_MENU) == 0) - { - return; - } - - if (!Menu_IsTextInput(m_currentMenu) && inputState.GetKeyStatus(sc_Q)) - Menu_AnimateChange(MENU_QUIT, MA_Advance); - - int32_t mousestatus = inputState.mouseReadAbs(&m_mousepos); - if (mousestatus && inputState.mouseClickState() == MOUSE_PRESSED) - m_mousedownpos = m_mousepos; - - Menu_RunInput(m_currentMenu); - - g_player[myconnectindex].ps->gm &= (0xff-MODE_TYPE); - // g_player[myconnectindex].ps->fta = 0; - - int32_t const backgroundOK = ud.menubackground && Menu_BlackTranslucentBackgroundOK(g_currentMenu); - - // need EVENT_DISPLAYMENUBACKGROUND here - - if (((g_player[myconnectindex].ps->gm&MODE_GAME) || ud.recstat==2) && backgroundOK) - videoFadeToBlack(1); - - if (Menu_UpdateScreenOK(g_currentMenu)) - G_UpdateScreenArea(); - -#if !defined EDUKE32_TOUCH_DEVICES - if (m_menuchange_watchpoint > 0) - m_menuchange_watchpoint++; -#endif - - if (totalclock < m_animation.start) - { - m_animation.start = 0; - m_animation.length = 0; - } - - // Determine animation values. - if (totalclock < m_animation.start + m_animation.length) - { - const int32_t screenwidth = scale(240<<16, xdim, ydim); - - origin.x = mulscale15(screenwidth, m_animation.in(&m_animation)); - previousOrigin.x = mulscale15(screenwidth, m_animation.out(&m_animation)); - } - - if (m_parentMenu && backgroundOK) - { - Menu_Run(m_parentMenu, origin); - } - - // Display the menu, with a transition animation if applicable. - if (totalclock < m_animation.start + m_animation.length) - { - Menu_Run(m_animation.previous, previousOrigin); - Menu_Run(m_animation.current, origin); - } - else - Menu_Run(m_currentMenu, origin); - -#if !defined EDUKE32_TOUCH_DEVICES - if (m_menuchange_watchpoint >= 3) - m_menuchange_watchpoint = 0; -#endif - -#if !defined EDUKE32_TOUCH_DEVICES - if (tilesiz[CROSSHAIR].x > 0 && mousestatus) -#else - if (mousestatus) -#endif - { -#if !defined EDUKE32_TOUCH_DEVICES - if (!MOUSEACTIVECONDITION) - m_mousewake_watchpoint = 1; -#endif - - if (MOUSEACTIVECONDITIONAL(inputState.mouseAdvanceClickState()) || m_mousepos.x != m_prevmousepos.x || m_mousepos.y != m_prevmousepos.y) - { - m_prevmousepos = m_mousepos; - m_mouselastactivity = (int32_t) totalclock; - } -#if !defined EDUKE32_TOUCH_DEVICES - else - m_mousewake_watchpoint = 0; -#endif - - m_mousecaught = 0; - } - else - { - m_mouselastactivity = -M_MOUSETIMEOUT; - -#if !defined EDUKE32_TOUCH_DEVICES - m_mousewake_watchpoint = 0; -#endif - } - -#ifndef EDUKE32_TOUCH_DEVICES - // Display the mouse cursor, except on touch devices. - if (MOUSEACTIVECONDITION) - { - int32_t a = CROSSHAIR; - - if ((unsigned) a < MAXTILES) - { - vec2_t cursorpos = m_mousepos; - int32_t z = RR ? 32768 : 65536; - uint8_t p = CROSSHAIR_PAL; - uint32_t o = 2; - - int32_t alpha = CURSORALPHA; - - rotatesprite_fs_alpha(cursorpos.x, cursorpos.y, z, 0, a, 0, p, o, alpha); - } - } - else - inputState.clearMouseClickState(); - -#endif - - if ((g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU) - { - G_UpdateScreenArea(); - CAMERACLOCK = (int32_t) totalclock; - CAMERADIST = 65536; - } -} - #endif END_RR_NS From 943cb64edafb77cbc71c8bc2481473067fba1d3c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2019 23:27:10 +0100 Subject: [PATCH 047/203] - image scroller menus working. --- source/CMakeLists.txt | 1 + source/common/menu/imagescroller.cpp | 177 +++++++++++++++++++++++++++ source/common/menu/listmenu.cpp | 31 ----- source/common/menu/loadsavemenu.cpp | 8 ++ source/common/menu/menu.cpp | 60 ++++----- source/common/menu/menu.h | 52 +++++--- source/common/menu/menudef.cpp | 9 +- wadsrc/static/demolition/menudef.txt | 22 ++-- 8 files changed, 266 insertions(+), 94 deletions(-) create mode 100644 source/common/menu/imagescroller.cpp diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 8ae283e2c..a70e9eb18 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -827,6 +827,7 @@ set (PCH_SOURCES common/music/backend/oalsound.cpp common/music/backend/i_sound.cpp + common/menu/imagescroller.cpp common/menu/joystickmenu.cpp common/menu/listmenu.cpp common/menu/loadsavemenu.cpp diff --git a/source/common/menu/imagescroller.cpp b/source/common/menu/imagescroller.cpp new file mode 100644 index 000000000..8fabd1360 --- /dev/null +++ b/source/common/menu/imagescroller.cpp @@ -0,0 +1,177 @@ +/* +** imagescroller.cpp +** Scrolls through multiple fullscreen image pages, +** +**--------------------------------------------------------------------------- +** Copyright 2019 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "v_font.h" +#include "cmdlib.h" +#include "gstrings.h" +#include "d_gui.h" +#include "d_event.h" +#include "menu.h" +#include "v_draw.h" +#include "baselayer.h" +#include "gamecontrol.h" +#include "build.h" + +//============================================================================= +// +// Show a fullscreen image / centered text screen for an image scroller +// +//============================================================================= + +class ImageScreen : public DMenu // Todo: This should be global +{ + const FImageScrollerDescriptor::ScrollerItem* mDesc; +public: + ImageScreen(const FImageScrollerDescriptor::ScrollerItem* it) + { + mDesc = it; + } + void Drawer() override; +}; + + +//============================================================================= +// +// Fullscreen image drawer (move to its own source file!) +// +//============================================================================= + +void ImageScreen::Drawer() +{ + if (mDesc->type == 0) + { + auto tileindexp = NameToTileIndex.CheckKey(FName(mDesc->text, true)); + int tileindex; + if (tileindexp == nullptr) + { + // If this isn't a name, try a literal tile index; + auto c = mDesc->text.GetChars(); + if (*c == '#') tileindex = (int)strtoll(c + 1, nullptr, 0); + // Error out if the screen cannot be found, this is always a definition error that needs to be reported. + else I_Error("Invalid menu screen '%s'", mDesc->text.GetChars()); + } + else tileindex = *tileindexp; + if (!gi->DrawSpecialScreen(origin, tileindex)) // allows the front end to do custom handling for a given image. + { + rotatesprite_fs(int(origin.X * 65536) + (160 << 16), int(origin.Y * 65536) + (100 << 16), 65536L, 0, tileindex, 0, 0, 10 + 64); + } + } + else + { + gi->DrawCenteredTextScreen(origin, mDesc->text, mDesc->type); + } +} + + +DImageScrollerMenu::DImageScrollerMenu(DMenu* parent, FImageScrollerDescriptor* desc) + : DMenu(parent) +{ + index = 0; + mDesc = desc; + canAnimate = !!(mDesc->mFlags & LMF_Animate); + + mCurrent = new ImageScreen(&mDesc->mItems[0]); + mCurrent->canAnimate = canAnimate; +} + +bool DImageScrollerMenu::MenuEvent(int mkey, bool fromcontroller) +{ + switch (mkey) + { + case MKEY_Back: + // Before going back the currently running transition must be terminated. + pageTransition.previous = nullptr; + pageTransition.current->origin = { 0,0 }; + return DMenu::MenuEvent(mkey, fromcontroller); + + case MKEY_Left: + if (pageTransition.previous == nullptr) + { + if (--index < 0) index = mDesc->mItems.Size() - 1; + auto next = new ImageScreen(&mDesc->mItems[index]); + next->canAnimate = canAnimate; + if (!pageTransition.StartTransition(mCurrent, next, MA_Return)) + { + delete mCurrent; + } + mCurrent = next; + //gi->MenuSound(GameInterface::ChooseSound); + } + return true; + + case MKEY_Right: + case MKEY_Enter: + if (pageTransition.previous == nullptr) + { + if (++index >= (int)mDesc->mItems.Size()) index = 0; + auto next = new ImageScreen(&mDesc->mItems[index]); + next->canAnimate = canAnimate; + if (!pageTransition.StartTransition(mCurrent, next, MA_Advance)) + { + delete mCurrent; + } + mCurrent = next; + //gi->MenuSound(GameInterface::ChooseSound); + } + return true; + + default: + return DMenu::MenuEvent(mkey, fromcontroller); + } +} + +bool DImageScrollerMenu::MouseEvent(int type, int x, int y) +{ + // Todo: Implement some form of drag event to switch between pages. + return DMenu::MouseEvent(type, x, y); +} + +void DImageScrollerMenu::Ticker() +{ +} + +void DImageScrollerMenu::Drawer() +{ + if (pageTransition.previous != nullptr) + { + auto res = pageTransition.Draw(); + if (res) return; + delete pageTransition.previous; + pageTransition.previous = nullptr; + } + mCurrent->origin = origin; + mCurrent->Drawer(); + mCurrent->origin = {}; +} + diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index adb928d89..2da15b3e2 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -621,34 +621,3 @@ int FListMenuItemPatch::GetWidth() : 0; } -//============================================================================= -// -// Fullscreen image drawer (move to its own source file!) -// -//============================================================================= - -void ImageScreen::Drawer() -{ - if (mDesc->type == 0) - { - auto tileindexp = NameToTileIndex.CheckKey(FName(mDesc->text, true)); - int tileindex; - if (tileindexp == nullptr) - { - // If this isn't a name, try a literal tile index; - auto c = mDesc->text.GetChars(); - if (*c == '#') tileindex = (int)strtoll(c+1, nullptr, 0); - // Error out if the screen cannot be found, this is always a definition error that needs to be reported. - else I_Error("Invalid menu screen '%s'", mDesc->text.GetChars()); - } - else tileindex = *tileindexp; - if (!gi->DrawSpecialScreen(origin, tileindex)) // allows the front end to do custom handling for a given image. - { - rotatesprite_fs(int(origin.X * 65536) + (160<<16), int(origin.Y * 65536) + (100<<16), 65536L,0,tileindex,0,0,10+64); - } - } - else - { - gi->DrawCenteredTextScreen(origin, mDesc->text, mDesc->type); - } -} diff --git a/source/common/menu/loadsavemenu.cpp b/source/common/menu/loadsavemenu.cpp index 7930d1606..b2996974e 100644 --- a/source/common/menu/loadsavemenu.cpp +++ b/source/common/menu/loadsavemenu.cpp @@ -957,3 +957,11 @@ bool DLoadMenu::MenuEvent (int mkey, bool fromcontroller) return false; } +static TMenuClassDescriptor _lm("LoadMenu"); +static TMenuClassDescriptor _sm("SaveMenu"); + +void RegisterRedneckMenus() +{ + menuClasses.Push(&_sm); + menuClasses.Push(&_lm); +} diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index cfa864708..8908f97c2 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -54,6 +54,7 @@ void RegisterDukeMenus(); void RegisterRedneckMenus(); +void RegisterLoadsaveMenus(); extern bool rotatesprite_2doverride; bool help_disabled, credits_disabled; int g_currentMenu; // accessible by CON scripts - contains the current menu's script ID if defined or INT_MAX if none given. @@ -89,26 +90,10 @@ static bool MenuEnabled = true; #define KEY_REPEAT_DELAY (MENU_TICRATE*5/12) #define KEY_REPEAT_RATE (3) -enum MenuTransitionType -{ // Note: This enum is for logical categories, not visual types. - MA_None, - MA_Return, - MA_Advance, -} ; - -struct MenuTransition -{ - DMenu *previous; - DMenu *current; - - int32_t start; - int32_t length; - int32_t dir; -}; static MenuTransition transition; -bool M_StartTransition(DMenu *from, DMenu *to, MenuTransitionType animtype, MenuTransition &transition) +bool MenuTransition::StartTransition(DMenu *from, DMenu *to, MenuTransitionType animtype) { if (!from->canAnimate || !to->canAnimate || animtype == MA_None) { @@ -116,27 +101,26 @@ bool M_StartTransition(DMenu *from, DMenu *to, MenuTransitionType animtype, Menu } else { - transition.start = (int32_t) totalclock; - transition.length = 30; - transition.dir = animtype == MA_Advance? 1 : -1; - transition.previous = from; - transition.current = to; + start = (int32_t) totalclock; + length = 300; + dir = animtype == MA_Advance? 1 : -1; + previous = from; + current = to; return true; } } -bool M_DrawTransition(MenuTransition &transition) +bool MenuTransition::Draw() { - if (totalclock < transition.start + transition.length) + if (totalclock < start + length) { double factor = 120 * xdim / ydim; - double phase = ((int32_t) totalclock - transition.start) / double(transition.length) * M_PI + M_PI/2; + double phase = ((int32_t) totalclock - start) / double(length) * M_PI + M_PI/2; - transition.previous->origin.X = factor * transition.dir * (sin(phase) - 1.); - transition.current->origin.X = factor * transition.dir * (sin(phase) + 1.); - Printf("prev.X = %2.5f, next.X = %2.5f\n", transition.previous->origin.X, transition.current->origin.X); - transition.previous->Drawer(); - transition.current->Drawer(); + previous->origin.X = factor * dir * (sin(phase) - 1.); + current->origin.X = factor * dir * (sin(phase) + 1.); + previous->Drawer(); + current->Drawer(); return true; } return false; @@ -231,7 +215,7 @@ void DMenu::Close () assert(DMenu::CurrentMenu == this); DMenu::CurrentMenu = mParentMenu; - if (mParentMenu && M_StartTransition(this, mParentMenu, MA_Return, transition)) + if (mParentMenu && transition.StartTransition(this, mParentMenu, MA_Return)) { g_currentMenu = DMenu::CurrentMenu->scriptID; } @@ -415,7 +399,7 @@ void M_ActivateMenu(DMenu *menu) if (DMenu::CurrentMenu != NULL) { DMenu::CurrentMenu->ReleaseCapture(); - M_StartTransition(DMenu::CurrentMenu, menu, MA_Advance, transition); + transition.StartTransition(DMenu::CurrentMenu, menu, MA_Advance); } DMenu::CurrentMenu = menu; } @@ -556,6 +540,15 @@ bool M_SetMenu(FName menu, int param, FName caller) newmenu->Init(DMenu::CurrentMenu, ld); M_ActivateMenu(newmenu); } + else if ((*desc)->mType == MDESC_ImageScroller) + { + FImageScrollerDescriptor* ld = static_cast(*desc); + if (ld->mItems.Size() > 0) // only open the submenu if it isn't empty. + { + DImageScrollerMenu* newmenu = new DImageScrollerMenu(DMenu::CurrentMenu, ld); + M_ActivateMenu(newmenu); + } + } return true; } else @@ -824,7 +817,7 @@ void M_Drawer (void) bool going = false; if (transition.previous) { - going = M_DrawTransition(transition); + going = transition.Draw(); if (!going) { if (transition.dir == -1) delete transition.previous; @@ -876,6 +869,7 @@ void M_Init (void) { RegisterDukeMenus(); RegisterRedneckMenus(); + RegisterLoadsaveMenus(); timerSetCallback(M_Ticker); M_ParseMenuDefs(); } diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 611ae0ad9..0a7a80538 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -32,6 +32,29 @@ const int MENU_TICRATE = 30; extern bool help_disabled, credits_disabled; extern int g_currentMenu; +enum MenuTransitionType +{ // Note: This enum is for logical categories, not visual types. + MA_None, + MA_Return, + MA_Advance, +}; + +class DMenu; + +struct MenuTransition +{ + DMenu* previous; + DMenu* current; + + int32_t start; + int32_t length; + int32_t dir; + + bool StartTransition(DMenu* from, DMenu* to, MenuTransitionType animtype); + bool Draw(); + +}; + enum { EF_HIDEFROMSP = 1 << 0, @@ -262,7 +285,8 @@ struct FImageScrollerDescriptor : public FMenuDescriptor int scriptID; FString text; }; - + int mFlags = 0; + TArray mItems; }; @@ -635,23 +659,17 @@ public: class DImageScrollerMenu : public DMenu { - -}; + DMenu* mCurrent; + FImageScrollerDescriptor* mDesc; + int index; + MenuTransition pageTransition = {}; -//============================================================================= -// -// Show a fullscreen image / centered text screen for an image scroller -// -//============================================================================= - -class ImageScreen : public DMenu // Todo: This should be global -{ - const FImageScrollerDescriptor::ScrollerItem *mDesc; - ImageScreen(const FImageScrollerDescriptor::ScrollerItem *it) - { - mDesc = it; - } - void Drawer() override; +public: + DImageScrollerMenu(DMenu* parent = nullptr, FImageScrollerDescriptor* desc = nullptr); + bool MenuEvent(int mkey, bool fromcontroller); + bool MouseEvent(int type, int x, int y); + void Ticker(); + void Drawer(); }; //============================================================================= diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index f25db2439..5d664e12e 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -586,15 +586,16 @@ static void ParseImageScrollerBody(FScanner &sc, FImageScrollerDescriptor *desc) else if (sc.Compare("TextItem") || sc.Compare("ImageItem")) { FImageScrollerDescriptor::ScrollerItem item; - sc.MustGetString(); - item.text = sc.String; int type = sc.Compare("TextItem"); + sc.MustGetString(); + item.text = strbin1(sc.String); if (type) { sc.MustGetStringName(","); sc.MustGetNumber(); item.type = sc.Number; // y-coordinate } + else item.type = 0; item.scriptID = INT_MAX; if (sc.CheckString(",")) { @@ -603,6 +604,10 @@ static void ParseImageScrollerBody(FScanner &sc, FImageScrollerDescriptor *desc) } desc->mItems.Push(item); } + else if (sc.Compare("animatedtransition")) + { + desc->mFlags |= LMF_Animate; + } else { sc.ScriptError("Unknown keyword '%s'", sc.String); diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index c5f414ac4..014ee3e45 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -361,20 +361,18 @@ LISTMENU "MultiMenu" // // //------------------------------------------------------------------------------------------- -/* ImageScroller "HelpMenu" { - ifgame(Duke, Nam, WW2GI, Fury) + ifgame(Duke, Nam, WW2GI, Fury, Redneck, RedneckRides) { ImageItem "TEXTSTORY", 400 ImageItem "F1HELP", 401 - } - ifgame(Redneck, RedneckRides) - { - ImageItem "TEXTSTORY" - ImageItem "F1HELP" - ImageItem "RRTILE1636" + ifgame(RedneckRides) + { + ImageItem "RRTILE1636" + } + animatedtransition } } @@ -396,6 +394,7 @@ ImageScroller "CreditsMenu" ImageItem "CREDITSTEXT1", 990 ImageItem "CREDITSTEXT2", 991 ImageItem "CREDITSTEXT3", 992 + animatedtransition } ifgame(Redneck) { @@ -408,7 +407,7 @@ ImageScroller "CreditsMenu" TextItem "SENIOR ANIMATOR AND ARTIST\n\nJASON HOOVER", 80 TextItem "TECHNICAL DIRECTOR\n\nBARRY DEMPSEY", 80 TextItem "MOTION CAPTURE SPECIALIST AND\nCHARACTER ANIMATION\nAMIT DORON\n\nA.I. PROGRAMMING\nARTHUR DONAVAN\n\nADDITIONAL ANIMATION\nGEORGE KARL", 60 - TextItem "CHARACTER DESIGN\nCORKY LEHMKUHL\n\nMAP PAINTERS\n"VIKTOR ANTONOV\nMATTHIAS BEEGUER\nSTEPHAN BURLE\n\nSCULPTORS\nGEORGE ENGEL\nJAKE GARBER\nJEFF HIMMEL", 50 + TextItem "CHARACTER DESIGN\nCORKY LEHMKUHL\n\nMAP PAINTERS\nVIKTOR ANTONOV\nMATTHIAS BEEGUER\nSTEPHAN BURLE\n\nSCULPTORS\nGEORGE ENGEL\nJAKE GARBER\nJEFF HIMMEL", 50 TextItem "CHARACTER VOICES\n\nLEONARD\nBURTON GILLIAM\n\nBUBBA, BILLY RAY, SKINNY OL' COOT\nAND THE TURD MINION\nDREW MARKHAM\n\nSHERIFF LESTER T. HOBBES\nMOJO NIXON\n\nALIEN VIXEN\nPEGGY JO JACOBS", 40 TextItem "SOUND DESIGN\nGARY BRADFIELD\n\nMUSIC\nMOJO NIXON\nTHE BEAT FARMERS\nTHE REVEREND HORTON HEAT\nCEMENT POND\n\nADDITIONAL SOUND EFFECTS\nJIM SPURGIN", 50 TextItem "MOTION CAPTURE ACTOR\nJ.P. MANOUX\n\nMOTION CAPTURE VIXEN\nSHAWN WOLFE", 80 @@ -423,6 +422,7 @@ ImageScroller "CreditsMenu" TextItem "SPECIAL THANKS\n\nJIM GAUER\nPAUL VAIS\nSCOTT MILLER\nTODD REPLOGLE\nCHUCK BUECHE\nCARTER LIPSCOMB\nJOHN CONLEY\nDON MAGGI", 60 TextItem "EXTRA SPECIAL THANKS\n\nBRIAN FARGO", 80 TextItem "REDNECK RAMPAGE\n(c) 1997 XATRIX ENTERTAINMENT, INC.\n\nREDNECK RAMPAGE IS A TRADEMARK OF\nINTERPLAY PRODUCTIONS", 60 + animatedtransition } ifgame(RedneckRides) { @@ -456,7 +456,7 @@ ImageScroller "CreditsMenu" TextItem "SPECIAL THANKS\n\nSCOTT MILLER\nGEORGE BROUSSARD", 80 TextItem "EXTRA SPECIAL THANKS\n\nBRIAN FARGO", 80 TextItem "REDNECK RAMPAGE RIDES AGAIN\n(c) 1998 XATRIX ENTERTAINMENT, INC.\n\nREDNECK RAMPAGE RIDES AGAIN\nIS A TRADEMARK OF\nINTERPLAY PRODUCTIONS", 70 + animatedtransition } } - -*/ \ No newline at end of file + \ No newline at end of file From 0cedad6390faaca1873d0ee28193603748a7f17e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Nov 2019 00:37:19 +0100 Subject: [PATCH 048/203] - started work on load/save menus. --- source/build/include/baselayer.h | 3 ++ source/common/console/c_console.cpp | 10 ++--- source/common/fonts/font.cpp | 6 +-- source/common/fonts/v_font.h | 2 +- source/common/fonts/v_text.cpp | 2 +- source/common/menu/listmenu.cpp | 8 ++++ source/common/menu/loadsavemenu.cpp | 64 ++++++++++++++++------------ source/common/menu/menu.cpp | 3 +- source/common/menu/menu.h | 1 + source/duke3d/src/d_menu.cpp | 13 +++--- source/duke3d/src/duke3d.h | 1 + source/rr/src/d_menu.cpp | 15 +++---- source/rr/src/duke3d.h | 1 + wadsrc/static/demolition/menudef.txt | 33 +++++++++++++- 14 files changed, 108 insertions(+), 54 deletions(-) diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 94bf8e9c1..10d4dd547 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -213,6 +213,9 @@ struct GameInterface virtual FSavegameInfo GetSaveSig() { return { "", 0, 0}; } virtual bool DrawSpecialScreen(const DVector2 &origin, int tilenum) { return false; } virtual void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) {} + virtual void DrawMenuCaption(const DVector2& origin, const char* text) {} + + }; extern GameInterface* gi; diff --git a/source/common/console/c_console.cpp b/source/common/console/c_console.cpp index 0a029990a..594d56137 100644 --- a/source/common/console/c_console.cpp +++ b/source/common/console/c_console.cpp @@ -205,13 +205,13 @@ public: if (scale == 1) { DrawChar(&twod, CurrentConsoleFont, CR_ORANGE, x, y, '\x1c', TAG_DONE); - DrawText(&twod, CurrentConsoleFont, CR_ORANGE, x + CurrentConsoleFont->GetCharWidth(0x1c), y, + DrawText(&twod, CurrentConsoleFont, CR_ORANGE, x + CurrentConsoleFont->CharWidth(0x1c), y, &Text[StartPos], TAG_DONE); if (cursor) { DrawChar(&twod, CurrentConsoleFont, CR_YELLOW, - x + CurrentConsoleFont->GetCharWidth(0x1c) + (CursorPosCells - StartPosCells) * CurrentConsoleFont->GetCharWidth(0xb), + x + CurrentConsoleFont->CharWidth(0x1c) + (CursorPosCells - StartPosCells) * CurrentConsoleFont->CharWidth(0xb), y, '\xb', TAG_DONE); } } @@ -222,7 +222,7 @@ public: DTA_VirtualHeight, screen->GetHeight() / scale, DTA_KeepRatio, true, TAG_DONE); - DrawText(&twod, CurrentConsoleFont, CR_ORANGE, x + CurrentConsoleFont->GetCharWidth(0x1c), y, + DrawText(&twod, CurrentConsoleFont, CR_ORANGE, x + CurrentConsoleFont->CharWidth(0x1c), y, &Text[StartPos], DTA_VirtualWidth, screen->GetWidth() / scale, DTA_VirtualHeight, screen->GetHeight() / scale, @@ -231,7 +231,7 @@ public: if (cursor) { DrawChar(&twod, CurrentConsoleFont, CR_YELLOW, - x + CurrentConsoleFont->GetCharWidth(0x1c) + (CursorPosCells - StartPosCells) * CurrentConsoleFont->GetCharWidth(0xb), + x + CurrentConsoleFont->CharWidth(0x1c) + (CursorPosCells - StartPosCells) * CurrentConsoleFont->CharWidth(0xb), y, '\xb', DTA_VirtualWidth, screen->GetWidth() / scale, DTA_VirtualHeight, screen->GetHeight() / scale, @@ -614,7 +614,7 @@ void C_InitConsole (int width, int height, bool ingame) vidactive = ingame; if (CurrentConsoleFont != NULL) { - cwidth = CurrentConsoleFont->GetCharWidth ('M'); + cwidth = CurrentConsoleFont->CharWidth ('M'); cheight = CurrentConsoleFont->GetHeight(); } else diff --git a/source/common/fonts/font.cpp b/source/common/fonts/font.cpp index 26d62aac8..a6a0511d3 100644 --- a/source/common/fonts/font.cpp +++ b/source/common/fonts/font.cpp @@ -576,11 +576,11 @@ FTexture *FFont::GetChar (int code, int translation, int *const width, bool *red //========================================================================== // -// FFont :: GetCharWidth +// FFont :: CharWidth // //========================================================================== -int FFont::GetCharWidth (int code) const +int FFont::CharWidth (int code) const { code = GetCharCode(code, true); if (code >= 0) return Chars[code - FirstChar].XMove; @@ -684,7 +684,7 @@ int FFont::StringWidth(const uint8_t *string) const } else { - w += GetCharWidth(chr) + GlobalKerning; + w += NewSmallFont->CharWidth(chr) + GlobalKerning; } } diff --git a/source/common/fonts/v_font.h b/source/common/fonts/v_font.h index 8c805d57f..5d1afb2ce 100644 --- a/source/common/fonts/v_font.h +++ b/source/common/fonts/v_font.h @@ -98,7 +98,7 @@ public: virtual ~FFont (); virtual FTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const; - virtual int GetCharWidth (int code) const; + virtual int CharWidth (int code) const; int GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const; int GetSpaceWidth () const { return SpaceWidth; } int GetHeight () const { return FontHeight; } diff --git a/source/common/fonts/v_text.cpp b/source/common/fonts/v_text.cpp index 3270f3986..e6e3a2ede 100644 --- a/source/common/fonts/v_text.cpp +++ b/source/common/fonts/v_text.cpp @@ -114,7 +114,7 @@ TArray V_BreakLines (FFont *font, int maxwidth, const uint8_t *str lastWasSpace = false; } - nw = font->GetCharWidth (c); + nw = font->CharWidth (c); if ((w > 0 && w + nw > maxwidth) || c == '\n') { // Time to break the line diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 2da15b3e2..26d7429ca 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -266,6 +266,14 @@ void DListMenu::Ticker () // //============================================================================= +void DListMenu::PreDraw() +{ + if (mDesc->mCaption.IsNotEmpty()) + { + gi->DrawMenuCaption(origin, mDesc->mCaption); + } +} + void DListMenu::Drawer () { PreDraw(); diff --git a/source/common/menu/loadsavemenu.cpp b/source/common/menu/loadsavemenu.cpp index b2996974e..f5ed87171 100644 --- a/source/common/menu/loadsavemenu.cpp +++ b/source/common/menu/loadsavemenu.cpp @@ -92,12 +92,13 @@ protected: static void ReadSaveStrings (); - FTexture *SavePic; + FTexture *SavePic = nullptr; TArray SaveComment; bool mEntering; FString savegamestring; DLoadSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); + void Init(DMenu* parent, FListMenuDescriptor* desc) override; void Destroy(); int RemoveSaveSlot (int index); @@ -314,20 +315,27 @@ void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave) // //============================================================================= -DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, FListMenuDescriptor *desc) -: DListMenu(parent, desc) +DLoadSaveMenu::DLoadSaveMenu(DMenu* parent, FListMenuDescriptor* desc) + : DListMenu(parent, desc) { ReadSaveStrings(); +} - savepicLeft = 10; - savepicTop = 54*CleanYfac; - savepicWidth = 216*screen->GetWidth()/640; - savepicHeight = 135*screen->GetHeight()/400; +void DLoadSaveMenu::Init(DMenu* parent, FListMenuDescriptor* desc) +{ + Super::Init(parent, desc); + int Width43 = screen->GetHeight() * 4 / 3; + int Left43 = (screen->GetWidth() - Width43) / 2; + float wScale = Width43 / 640.; + savepicLeft = Left43 + int(20 * wScale); + savepicTop = mDesc->mYpos * screen->GetHeight() / 200 ; + savepicWidth = int(240 * wScale); + savepicHeight = int(180 * wScale); - rowHeight = (SmallFont->GetHeight() + 1) * CleanYfac; - listboxLeft = savepicLeft + savepicWidth + 14; + rowHeight = (NewConsoleFont->GetHeight() + 1) * CleanYfac; + listboxLeft = savepicLeft + savepicWidth + int(20 * wScale); listboxTop = savepicTop; - listboxWidth = screen->GetWidth() - listboxLeft - 10; + listboxWidth = Width43 + Left43 - listboxLeft - int(30 * wScale); int listboxHeight1 = screen->GetHeight() - listboxTop - 10; listboxRows = (listboxHeight1 - 1) / rowHeight; listboxHeight = listboxRows * rowHeight + 1; @@ -335,7 +343,7 @@ DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, FListMenuDescriptor *desc) listboxBottom = listboxTop + listboxHeight; commentLeft = savepicLeft; - commentTop = savepicTop + savepicHeight + 16; + commentTop = savepicTop + savepicHeight + int(16 * wScale); commentWidth = savepicWidth; commentHeight = (51+(screen->GetHeight()>200?10:0))*CleanYfac; commentRight = commentLeft + commentWidth; @@ -437,16 +445,16 @@ void DLoadSaveMenu::Drawer () } else { - twod.AddColorOnlyQuad(savepicLeft, savepicTop, savepicLeft+savepicWidth, savepicTop+savepicHeight, 0xff000000); + twod.AddColorOnlyQuad(savepicLeft, savepicTop, savepicWidth, savepicHeight, 0x80000000); if (SaveGames.Size() > 0) { const char *text = (Selected == -1 || !SaveGames[Selected]->bOldVersion) ? GStrings("MNU_NOPICTURE") : GStrings("MNU_DIFFVERSION"); - const int textlen = SmallFont->StringWidth (text)*CleanXfac; + const int textlen = NewConsoleFont->StringWidth (text)*CleanXfac; - DrawText (&twod, SmallFont, CR_GOLD, savepicLeft+(savepicWidth-textlen)/2, + DrawText (&twod, NewConsoleFont, CR_GOLD, savepicLeft+(savepicWidth-textlen)/2, savepicTop+(savepicHeight-rowHeight)/2, text, DTA_CleanNoMove, true, TAG_DONE); } @@ -454,7 +462,7 @@ void DLoadSaveMenu::Drawer () // Draw comment area //V_DrawFrame (commentLeft, commentTop, commentWidth, commentHeight); - twod.AddColorOnlyQuad(commentLeft, commentTop, commentRight, commentBottom, 0xff000000); + twod.AddColorOnlyQuad(commentLeft, commentTop, commentWidth, commentHeight, 0x80000000); if (SaveComment.Size()) { // I'm not sure why SaveComment would go NULL in this loop, but I got @@ -462,22 +470,22 @@ void DLoadSaveMenu::Drawer () // for that. for (i = 0; i < SaveComment.Size() && SaveComment[i].Width >= 0 && i < 6; ++i) { - DrawText (&twod, SmallFont, CR_GOLD, commentLeft, commentTop - + SmallFont->GetHeight()*i*CleanYfac, SaveComment[i].Text, + DrawText (&twod, NewConsoleFont, CR_GOLD, commentLeft, commentTop + + NewConsoleFont->GetHeight()*i*CleanYfac, SaveComment[i].Text, DTA_CleanNoMove, true, TAG_DONE); } } // Draw file area //V_DrawFrame (listboxLeft, listboxTop, listboxWidth, listboxHeight); - twod.AddColorOnlyQuad(listboxLeft, listboxTop, listboxRight, listboxBottom, 0xff000000); + twod.AddColorOnlyQuad(listboxLeft, listboxTop, listboxWidth, listboxHeight, 0x80000000); if (SaveGames.Size() == 0) { const char * text = GStrings("MNU_NOFILES"); - const int textlen = SmallFont->StringWidth (text)*CleanXfac; + const int textlen = NewConsoleFont->StringWidth (text)*CleanXfac; - DrawText (&twod, SmallFont, CR_GOLD, listboxLeft+(listboxWidth-textlen)/2, + DrawText (&twod, NewConsoleFont, CR_GOLD, listboxLeft+(listboxWidth-textlen)/2, listboxTop+(listboxHeight-rowHeight)/2, text, DTA_CleanNoMove, true, TAG_DONE); return; @@ -510,19 +518,19 @@ void DLoadSaveMenu::Drawer () didSeeSelected = true; if (!mEntering) { - DrawText(&twod, SmallFont, color, + DrawText(&twod, NewConsoleFont, color, listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->Title, DTA_CleanNoMove, true, TAG_DONE); } else { - DrawText(&twod, SmallFont, CR_WHITE, + DrawText(&twod, NewConsoleFont, CR_WHITE, listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, savegamestring, DTA_CleanNoMove, true, TAG_DONE); - char curs[2] = { SmallFont->GetCursor(), 0 }; - DrawText(&twod, SmallFont, CR_WHITE, - listboxLeft+1+SmallFont->StringWidth (savegamestring)*CleanXfac, + char curs[2] = { NewConsoleFont->GetCursor(), 0 }; + DrawText(&twod, NewConsoleFont, CR_WHITE, + listboxLeft+1+NewConsoleFont->StringWidth (savegamestring)*CleanXfac, listboxTop+rowHeight*i+CleanYfac, curs, DTA_CleanNoMove, true, TAG_DONE); @@ -530,7 +538,7 @@ void DLoadSaveMenu::Drawer () } else { - DrawText(&twod, SmallFont, color, + DrawText(&twod, NewConsoleFont, color, listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->Title, DTA_CleanNoMove, true, TAG_DONE); } @@ -692,7 +700,7 @@ bool DLoadSaveMenu::Responder (event_t *ev) if (!SaveGames[Selected]->Filename.IsEmpty()) { FStringf workbuf("File on disk:\n%s", SaveGames[Selected]->Filename.GetChars()); - SaveComment = V_BreakLines (SmallFont, 216*screen->GetWidth()/640/CleanXfac, workbuf); + SaveComment = V_BreakLines (NewConsoleFont, 216*screen->GetWidth()/640/CleanXfac, workbuf); } return true; @@ -960,7 +968,7 @@ bool DLoadMenu::MenuEvent (int mkey, bool fromcontroller) static TMenuClassDescriptor _lm("LoadMenu"); static TMenuClassDescriptor _sm("SaveMenu"); -void RegisterRedneckMenus() +void RegisterLoadsaveMenus() { menuClasses.Push(&_sm); menuClasses.Push(&_lm); diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 8908f97c2..051241b92 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -102,7 +102,7 @@ bool MenuTransition::StartTransition(DMenu *from, DMenu *to, MenuTransitionType else { start = (int32_t) totalclock; - length = 300; + length = 30; dir = animtype == MA_Advance? 1 : -1; previous = from; current = to; @@ -331,6 +331,7 @@ void DMenu::Drawer () #endif } + bool DMenu::DimAllowed() { return true; diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 0a7a80538..fdc4590f6 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -537,6 +537,7 @@ public: bool MouseEvent(int type, int x, int y) override; void Ticker () override; void Drawer () override; + void PreDraw() override; virtual void SelectionChanged() {} void SetFocus(FListMenuItem *fc) { diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 77bccbe91..e7365d722 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -373,11 +373,7 @@ protected: void PreDraw() override { CallScript(CurrentMenu == this ? EVENT_DISPLAYMENU : EVENT_DISPLAYMENUREST, true); - if (mDesc->mCaption.IsNotEmpty()) - { - Menu_DrawTopBar(origin); - Menu_DrawTopBarCaption(mDesc->mCaption, origin); - } + Super::PreDraw(); } void PostDraw() override @@ -515,6 +511,13 @@ FSavegameInfo GameInterface::GetSaveSig() return { SAVESIG_DN3D, MINSAVEVER_DN3D, SAVEVER_DN3D }; } + +void GameInterface::DrawMenuCaption(const DVector2& origin, const char* text) +{ + Menu_DrawTopBar(origin); + Menu_DrawTopBarCaption(text, origin); +} + //---------------------------------------------------------------------------- // // diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index 8cdd71442..309964ee2 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -166,6 +166,7 @@ struct GameInterface : ::GameInterface FSavegameInfo GetSaveSig() override; bool DrawSpecialScreen(const DVector2 &origin, int tilenum) override; void DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) override; + void DrawMenuCaption(const DVector2& origin, const char* text) override; }; diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index fa485f9d5..017c03485 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -320,15 +320,6 @@ protected: } } } - - void PreDraw() override - { - if (mDesc->mCaption.IsNotEmpty()) - { - Menu_DrawTopBar(origin); - Menu_DrawTopBarCaption(mDesc->mCaption, origin); - } - } }; class MainMenu : public RedneckListMenu @@ -444,6 +435,12 @@ FSavegameInfo GameInterface::GetSaveSig() return { SAVESIG_RR, MINSAVEVER_RR, SAVEVER_RR }; } +void GameInterface::DrawMenuCaption(const DVector2& origin, const char* text) +{ + Menu_DrawTopBar(origin); + Menu_DrawTopBarCaption(text, origin); +} + void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) { Menu_DrawBackground(origin); diff --git a/source/rr/src/duke3d.h b/source/rr/src/duke3d.h index 497b64327..108d565f7 100644 --- a/source/rr/src/duke3d.h +++ b/source/rr/src/duke3d.h @@ -166,6 +166,7 @@ struct GameInterface : ::GameInterface void StartGame(FGameStartup& gs) override; FSavegameInfo GetSaveSig() override; void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) override; + void DrawMenuCaption(const DVector2& origin, const char* text) override; }; END_RR_NS diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 014ee3e45..d1265c883 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -364,7 +364,7 @@ LISTMENU "MultiMenu" ImageScroller "HelpMenu" { - ifgame(Duke, Nam, WW2GI, Fury, Redneck, RedneckRides) + ifgame(Duke, Nam, WW2GI, Redneck, RedneckRides) { ImageItem "TEXTSTORY", 400 ImageItem "F1HELP", 401 @@ -374,6 +374,11 @@ ImageScroller "HelpMenu" } animatedtransition } + ifgame(fury) + { + ImageItem "TEXTSTORY", 400 + ImageItem "F1HELP", 401 + } } //------------------------------------------------------------------------------------------- @@ -459,4 +464,30 @@ ImageScroller "CreditsMenu" animatedtransition } } + +//------------------------------------------------------------------------------------------- +// +// Base definition for load game menu. Only the configurable part is done here +// +//------------------------------------------------------------------------------------------- + +ListMenu "LoadGameMenu" +{ + Caption "$MNU_LOADGAME" + Position 0, 40 + Class "LoadMenu" // uses its own implementation +} + +//------------------------------------------------------------------------------------------- +// +// Base definition for save game menu. Only the configurable part is done here +// +//------------------------------------------------------------------------------------------- + +ListMenu "SaveGameMenu" +{ + Caption "$MNU_SAVEGAME" + Position 0, 40 + Class "SaveMenu" // uses its own implementation +} \ No newline at end of file From f1f5d432d0748b434b9bb3229ad4d0e3692680cf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Nov 2019 00:51:40 +0100 Subject: [PATCH 049/203] - adjustment for pulled changes. --- wadsrc/static/demolition/menudef.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index d1265c883..42a01d684 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -59,7 +59,8 @@ LISTMENU "MainMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" - NativeTextItem "$MNU_COOLSTUFF", "h", "HelpMenu" + //NativeTextItem "$MNU_COOLSTUFF", "h", "HelpMenu" // Perfectly useless retro ads. :D + NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" } } From 90c5ea6acc3e6e6a53f49e71223d62e8a19c209b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Nov 2019 01:28:13 +0100 Subject: [PATCH 050/203] - updated option menu code to latest scripted version This mainly means being able to use the generic font. This also adds more generalization to the menu sound handling, plus an option to turn menu sound off. This is motivated by the pig sounds which RR uses in the menu. --- source/build/include/baselayer.h | 8 +- source/common/menu/listmenu.cpp | 10 +- source/common/menu/loadsavemenu.cpp | 10 +- source/common/menu/menu.cpp | 20 ++- source/common/menu/menu.h | 28 +++- source/common/menu/messagebox.cpp | 3 +- source/common/menu/optionmenu.cpp | 82 ++++++---- source/common/menu/optionmenuitems.h | 223 ++++++++++++++++----------- source/duke3d/src/d_menu.cpp | 16 +- source/rr/src/d_menu.cpp | 15 +- source/rr/src/duke3d.h | 2 +- 11 files changed, 255 insertions(+), 162 deletions(-) diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 10d4dd547..3525930ba 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -185,14 +185,10 @@ struct FSavegameInfo int currentsavever; }; +enum EMenuSounds : int; + struct GameInterface { - enum EMenuSounds - { - SelectSound, - ChooseSound - }; - virtual ~GameInterface() {} virtual void faketimerhandler() {} // This is a remnant of older versions, but Blood backend has not updated yet. virtual int app_main() = 0; diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 26d7429ca..4d7c67f38 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -133,7 +133,7 @@ bool DListMenu::Responder (event_t *ev) { mDesc->mSelectedItem = i; SelectionChanged(); - gi->MenuSound(GameInterface::SelectSound); + M_MenuSound(CursorSound); return true; } } @@ -143,7 +143,7 @@ bool DListMenu::Responder (event_t *ev) { mDesc->mSelectedItem = i; SelectionChanged(); - gi->MenuSound(GameInterface::SelectSound); + M_MenuSound(CursorSound); return true; } } @@ -171,7 +171,7 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller) } while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); SelectionChanged(); - gi->MenuSound(GameInterface::SelectSound); + M_MenuSound(CursorSound); return true; case MKEY_Down: @@ -181,13 +181,13 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller) } while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); SelectionChanged(); - gi->MenuSound(GameInterface::SelectSound); + M_MenuSound(CursorSound); return true; case MKEY_Enter: if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate(mDesc->mMenuName)) { - gi->MenuSound(GameInterface::ChooseSound); + M_MenuSound(AdvanceSound); } return true; diff --git a/source/common/menu/loadsavemenu.cpp b/source/common/menu/loadsavemenu.cpp index f5ed87171..e9422a23c 100644 --- a/source/common/menu/loadsavemenu.cpp +++ b/source/common/menu/loadsavemenu.cpp @@ -99,16 +99,16 @@ protected: DLoadSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); void Init(DMenu* parent, FListMenuDescriptor* desc) override; - void Destroy(); + void Destroy() override; int RemoveSaveSlot (int index); void UnloadSaveData (); void ClearSaveStuff (); void ExtractSaveData (int index); - void Drawer (); - bool MenuEvent (int mkey, bool fromcontroller); - bool MouseEvent(int type, int x, int y); - bool Responder(event_t *ev); + void Drawer () override; + bool MenuEvent (int mkey, bool fromcontroller) override; + bool MouseEvent(int type, int x, int y) override; + bool Responder(event_t *ev) override; public: static void NotifyNewSave (const char *file, const char *title, bool okForQuicksave); diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 051241b92..f147477a6 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -195,8 +195,8 @@ bool DMenu::MenuEvent (int mkey, bool fromcontroller) { if (scriptID != 0) { + M_MenuSound(DMenu::CurrentMenu->mParentMenu? BackSound : CloseSound); Close(); - //S_Sound (CHAN_VOICE | CHAN_UI, DMenu::CurrentMenu != NULL? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE); return true; } } @@ -473,15 +473,15 @@ bool M_SetMenu(FName menu, int param, FName caller) const char *msg = AllSkills[param].MustConfirmText; if (*msg==0) msg = GStrings("NIGHTMARE"); - M_StartMessage (msg, 0, NAME_StartgameConfirmed); + M_StartMessage (msg, 0, -1, NAME_StartgameConfirmed); return; } case NAME_Savegamemenu: - if (!usergame || (players[consoleplayer].health <= 0 && !multiplayer) || gamestate != GS_LEVEL) + if (gi->canSave()) { // cannot save outside the game. - M_StartMessage (GStrings("SAVEDEAD"), 1); + M_StartMessage (GStrings("SAVEDEAD"), 1, -1); return; } #endif @@ -860,6 +860,18 @@ void Menu_Close(int playerid) { M_ClearMenus(); } +//============================================================================= +// +// +// +//============================================================================= +CVAR(Bool, menu_sounds, true, CVAR_ARCHIVE) // added mainly because RR's sounds are so supremely annoying. + +void M_MenuSound(EMenuSounds snd) +{ + if (menu_sounds) gi->MenuSound(snd); +} + //============================================================================= // // diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index fdc4590f6..488580e45 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -92,10 +92,20 @@ enum EMenuState : int MENU_OnNoPause, // Menu is opened but does not pause the game }; +enum EMenuSounds : int +{ + CursorSound, + AdvanceSound, + BackSound, + CloseSound, + PageSound + ChangeSound +}; + struct event_t; class FTexture; class FFont; -enum EColorRange; +enum EColorRange : int; class FPlayerClass; class FKeyBindings; @@ -570,7 +580,14 @@ protected: FString mLabel; bool mCentered = false; - void drawLabel(int indent, int y, EColorRange color, bool grayed = false); + void drawText(int x, int y, int color, const char * text, bool grayed = false); + + int drawLabel(int indent, int y, EColorRange color, bool grayed = false); + void drawValue(int indent, int y, int color, const char *text, bool grayed = false); + + int CursorSpace(); + + public: FOptionMenuItem(const char *text, FName action = NAME_None, bool center = false) @@ -651,6 +668,10 @@ public: } }; +FFont *OptionFont(); +int OptionHeight(); +int OptionWidth(const char * s); +void DrawOptionText(int x, int y, int color, const char *text, bool grayed = false); //============================================================================= // @@ -726,8 +747,9 @@ int M_GetDefaultSkill(); void M_StartControlPanel (bool makeSound); bool M_SetMenu(FName menu, int param = -1, FName callingMenu = NAME_None); void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave); -void M_StartMessage(const char *message, int messagemode, FName action = NAME_None); +void M_StartMessage(const char *message, int messagemode, int scriptId, FName action = NAME_None); void M_UnhideCustomMenu(int menu, int itemmask); +void M_MenuSound(EMenuSounds snd); void I_SetMouseCapture(); diff --git a/source/common/menu/messagebox.cpp b/source/common/menu/messagebox.cpp index 99cc86160..b299f62df 100644 --- a/source/common/menu/messagebox.cpp +++ b/source/common/menu/messagebox.cpp @@ -345,7 +345,7 @@ bool DMessageBoxMenu::MouseEvent(int type, int x, int y) // //============================================================================= -void M_StartMessage(const char *message, int messagemode, FName action) +void M_StartMessage(const char *message, int messagemode, int scriptId, FName action) { if (DMenu::CurrentMenu == NULL) { @@ -354,6 +354,7 @@ void M_StartMessage(const char *message, int messagemode, FName action) } DMenu *newmenu = new DMessageBoxMenu(DMenu::CurrentMenu, message, messagemode, false, action); newmenu->mParentMenu = DMenu::CurrentMenu; + newmenu->scriptID = scriptId; M_ActivateMenu(newmenu); } diff --git a/source/common/menu/optionmenu.cpp b/source/common/menu/optionmenu.cpp index 38dddb82b..6e0c595f4 100644 --- a/source/common/menu/optionmenu.cpp +++ b/source/common/menu/optionmenu.cpp @@ -53,15 +53,27 @@ // //============================================================================= -void M_DrawConText (int color, int x, int y, const char *str) +FFont *OptionFont() { - DrawText (&twod, ConFont, color, x, y, str, - DTA_CellX, 8 * CleanXfac_1, - DTA_CellY, 8 * CleanYfac_1, - TAG_DONE); + return NewSmallFont; } +int OptionHeight() +{ + return OptionFont()->GetHeight(); +} +int OptionWidth(const char * s) +{ + return OptionFont()->StringWidth(s); +} + +void DrawOptionText(int x, int y, int color, const char *text, bool grayed) +{ + text = *text == '$'? GStrings(text+1) : text; + PalEntry overlay = grayed? PalEntry(96,48,0,0) : PalEntry(0,0,0); + DrawText (&twod, OptionFont(), color, x, y, text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay); +} //============================================================================= // @@ -323,7 +335,7 @@ bool DOptionMenu::MenuEvent (int mkey, bool fromcontroller) if (mDesc->mSelectedItem != startedAt) { - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + M_MenuSound(CursorSound); } return true; } @@ -355,7 +367,8 @@ bool DOptionMenu::MouseEvent(int type, int x, int y) if (yline != mDesc->mSelectedItem) { mDesc->mSelectedItem = yline; - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + //M_MenuSound(CursorSound); too noisy + } mDesc->mItems[yline]->MouseEvent(type, x, y); return true; @@ -390,21 +403,9 @@ void DOptionMenu::Drawer () { int y = mDesc->mPosition; - if (y <= 0) + if (mDesc->mTitle.IsNotEmpty()) { - if (BigFont && mDesc->mTitle.IsNotEmpty()) - { - const char *tt = mDesc->mTitle; - if (*tt == '$') tt = GStrings(tt+1); - DrawText (&twod, BigFont, OptionSettings.mTitleColor, - (screen->GetWidth() - BigFont->StringWidth(tt) * CleanXfac_1) / 2, 10*CleanYfac_1, - tt, DTA_CleanNoMove_1, true, TAG_DONE); - y = -y + BigFont->GetHeight(); - } - else - { - y = -y; - } + gi->DrawMenuCaption(origin, mDesc->mTitle); } mDesc->mDrawTop = y; int fontheight = OptionSettings.mLinespacing * CleanYfac_1; @@ -445,7 +446,8 @@ void DOptionMenu::Drawer () { if ((((DMenu::MenuTime>>2)%8) < 6) || DMenu::CurrentMenu != this) { - M_DrawConText(OptionSettings.mFontColorSelection, cur_indent + 3 * CleanXfac_1, y+fontheight-9*CleanYfac_1, "\xd"); + DrawOptionText(cur_indent + 3 * CleanXfac_1, y, OptionSettings.mFontColorSelection, "◄"); + //M_DrawConText(OptionSettings.mFontColorSelection, cur_indent + 3 * CleanXfac_1, y+fontheight-9*CleanYfac_1, "\xd"); } } } @@ -456,11 +458,13 @@ void DOptionMenu::Drawer () if (CanScrollUp) { - M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, ytop, "\x1a"); + DrawOptionText(screen->GetWidth() - 11 * CleanXfac_1, ytop, OptionSettings.mFontColorSelection, "▲"); + //M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, ytop, "\x1a"); } if (CanScrollDown) { - M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, y - 8*CleanYfac_1, "\x1b"); + DrawOptionText(screen->GetWidth() - 11 * CleanXfac_1 , y - 8*CleanYfac_1, OptionSettings.mFontColorSelection, "▼"); + //M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, y - 8*CleanYfac_1, "\x1b"); } Super::Drawer(); } @@ -497,30 +501,40 @@ bool FOptionMenuItem::MouseEvent(int type, int x, int y) int FOptionMenuItem::GetIndent() { - if (mCentered) - { - return 0; - } + if (mCentered) return 0; + if (screen->GetWidth() < 640) return screen->GetWidth() / 2; const char *label = mLabel; if (*label == '$') label = GStrings(label+1); - return SmallFont->StringWidth(label); + return OptionWidth(label); } -void FOptionMenuItem::drawLabel(int indent, int y, EColorRange color, bool grayed) +void FOptionMenuItem::drawText(int x, int y, int color, const char * text, bool grayed) +{ + DrawOptionText(x, y, color, text, grayed); +} + +int FOptionMenuItem::drawLabel(int indent, int y, EColorRange color, bool grayed) { const char *label = mLabel; if (*label == '$') label = GStrings(label+1); - int overlay = grayed? MAKEARGB(96,48,0,0) : 0; - int x; - int w = SmallFont->StringWidth(label) * CleanXfac_1; + int w = OptionWidth(label) * CleanXfac_1; if (!mCentered) x = indent - w; else x = (screen->GetWidth() - w) / 2; - DrawText (&twod, SmallFont, color, x, y, label, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE); + DrawOptionText(x, y, color, label, grayed); + return x; } +void FOptionMenuItem::drawValue(int indent, int y, int color, const char *text, bool grayed) +{ + DrawOptionText(indent + CursorSpace(), y, color, text, grayed); +} +int FOptionMenuItem::CursorSpace() +{ + return (14 * CleanXfac_1); +} void FOptionMenuDescriptor::CalcIndent() { diff --git a/source/common/menu/optionmenuitems.h b/source/common/menu/optionmenuitems.h index fd115b398..c97e53236 100644 --- a/source/common/menu/optionmenuitems.h +++ b/source/common/menu/optionmenuitems.h @@ -57,21 +57,48 @@ public: mParam = param; } - int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override { drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColorMore); return indent; } - bool Activate() + bool Activate(FName caller) override { - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); + M_MenuSound(CursorSound); M_SetMenu(mAction, mParam); return true; } }; +//============================================================================= +// +// opens a submenu, command is a submenu name +// +//============================================================================= + +class FOptionMenuItemLabeledSubmenu : public FOptionMenuItemSubmenu +{ + FBaseCVar *mLabelCVar; + FOptionMenuItemLabeledSubmenu(const char * label, FBaseCVar *labelcvar, FName command, int param = 0) + : FOptionMenuItemSubmenu(label, command, param) + { + mLabelCVar = labelcvar; + } + + int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override + { + drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor); + + auto text = mLabelCVar->GetHumanString(); + if (text[0] == 0) text = GStrings("notset"); + drawValue(indent, y, OptionSettings.mFontColorValue, text); + return indent; + } +}; + + //============================================================================= // // Executes a CCMD, action is a CCMD name @@ -86,9 +113,9 @@ public: { } - bool Activate() + bool Activate(FName caller) override { - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); + M_MenuSound(AdvanceSound); C_DoCommand(mAction); return true; } @@ -104,13 +131,17 @@ public: class FOptionMenuItemSafeCommand : public FOptionMenuItemCommand { // action is a CCMD + FString mPrompt; + int mScriptId; // shouldn't be used, but just in case. public: - FOptionMenuItemSafeCommand(const char *label, const char *menu) + FOptionMenuItemSafeCommand(const char *label, const char *menu, const char *prompt = nullptr, int scriptid = INT_MAX) : FOptionMenuItemCommand(label, menu) { + mPrompt = prompt; + mScriptId = scriptid; } - bool MenuEvent (int mkey, bool fromcontroller) + bool MenuEvent (int mkey, bool fromcontroller) override { if (mkey == MKEY_MBYes) { @@ -120,9 +151,15 @@ public: return FOptionMenuItemCommand::MenuEvent(mkey, fromcontroller); } - bool Activate() + bool Activate(FName caller) override { - M_StartMessage("Do you really want to do this?", 0); + auto msg = mPrompt.IsNotEmpty()? mPrompt.GetChars() : "$SAFEMESSAGE"; + if (*msg == '$') msg = GStrings(msg+1); + auto actionLabel = mLabel.GetChars(); + if (*actionLabel == '$') actionLabel = GStrings(actionLabel+1); + + FStringf FullString("%s%s%s\n\n%s", TEXTCOLOR_WHITE, actionLabel, TEXTCOLOR_NORMAL, msg); + M_StartMessage(FullString, 0, mScriptId); return true; } }; @@ -155,7 +192,7 @@ public: mCenter = center; } - bool SetString(int i, const char *newtext) + bool SetString(int i, const char *newtext) override { if (i == OP_VALUES) { @@ -179,19 +216,16 @@ public: virtual void SetSelection(int Selection) = 0; //============================================================================= - int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override { - bool grayed = mGrayCheck != NULL && !(mGrayCheck->GetGenericRep(CVAR_Bool).Bool); - if (mCenter) { indent = (screen->GetWidth() / 2); } - drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed); + drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, isGrayed()); - int overlay = grayed? MAKEARGB(96,48,0,0) : 0; - const char *text; int Selection = GetSelection(); + const char *text; FOptionValues **opt = OptionValues.CheckKey(mValues); if (Selection < 0 || opt == NULL || *opt == NULL) { @@ -202,13 +236,13 @@ public: text = (*opt)->mValues[Selection].Text; } if (*text == '$') text = GStrings(text + 1); - DrawText(&twod,SmallFont, OptionSettings.mFontColorValue, indent + CURSORSPACE, y, - text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE); + + drawValue(indent, y, OptionSettings.mFontColorValue, text, isGrayed()); return indent; } //============================================================================= - bool MenuEvent (int mkey, bool fromcontroller) + bool MenuEvent (int mkey, bool fromcontroller) override { FOptionValues **opt = OptionValues.CheckKey(mValues); if (opt != NULL && *opt != NULL && (*opt)->mValues.Size() > 0) @@ -228,14 +262,19 @@ public: return FOptionMenuItem::MenuEvent(mkey, fromcontroller); } SetSelection(Selection); - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); + M_MenuSound(ChangeSound); } return true; } - bool Selectable() + virtual bool isGrayed() { - return !(mGrayCheck != NULL && !(mGrayCheck->GetGenericRep(CVAR_Bool).Bool)); + return mGrayCheck != NULL && !(mGrayCheck->GetGenericRep(CVAR_Bool).Bool); + } + + bool Selectable() override + { + return !isGrayed(); } }; @@ -258,7 +297,7 @@ public: } //============================================================================= - int GetSelection() + int GetSelection() override { int Selection = -1; FOptionValues **opt = OptionValues.CheckKey(mValues); @@ -292,7 +331,7 @@ public: return Selection; } - void SetSelection(int Selection) + void SetSelection(int Selection) override { UCVarValue value; FOptionValues **opt = OptionValues.CheckKey(mValues); @@ -333,27 +372,25 @@ public: menuactive = MENU_WaitKey; // There should be a better way to disable GUI capture... } - bool TranslateKeyboardEvents() + bool TranslateKeyboardEvents() override { return false; } void SetMenuMessage(int which) { - /* - if (mParentMenu->IsKindOf(RUNTIME_CLASS(DOptionMenu))) + DOptionMenu *m = static_cast(mParentMenu); + if (m) { - DOptionMenu *m = static_cast(mParentMenu); FListMenuItem *it = m->GetItem(NAME_Controlmessage); if (it != NULL) { it->SetValue(0, which); } } - */ } - bool Responder(event_t *ev) + bool Responder(event_t *ev) override { if (ev->type == EV_KeyDown) { @@ -367,7 +404,7 @@ public: return false; } - void Drawer() + void Drawer() override { mParentMenu->Drawer(); } @@ -395,27 +432,27 @@ public: //============================================================================= - int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override { - drawLabel(indent, y, mWaiting? OptionSettings.mFontColorHighlight: + drawLabel(indent, y, mWaiting? OptionSettings.mFontColorHighlight: (selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor)); - auto keys = mBindings->GetKeysForCommand(mAction); - auto description = C_NameKeys(keys.Data(), keys.Size()); - if (description.IsNotEmpty()) + auto binds = mBindings->GetKeysForCommand(mAction); + auto description = C_NameKeys(binds.Data(), binds.Size()); + + if (description.Len() > 0) { - M_DrawConText(CR_WHITE, indent + CURSORSPACE, y + (OptionSettings.mLinespacing-8)*CleanYfac_1, description); + drawValue(indent, y, CR_WHITE, description); } else { - DrawText(&twod,SmallFont, CR_BLACK, indent + CURSORSPACE, y + (OptionSettings.mLinespacing-8)*CleanYfac_1, "---", - DTA_CleanNoMove_1, true, TAG_DONE); + drawValue(indent, y, CR_BLACK, "---"); } return indent; } //============================================================================= - bool MenuEvent(int mkey, bool fromcontroller) + bool MenuEvent(int mkey, bool fromcontroller) override { if (mkey == MKEY_Input) { @@ -436,9 +473,9 @@ public: return false; } - bool Activate() + bool Activate(FName caller) override { - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); + M_MenuSound(AdvanceSound); mWaiting = true; DMenu *input = new DEnterKey(DMenu::CurrentMenu, &mInput); M_ActivateMenu(input); @@ -456,19 +493,19 @@ class FOptionMenuItemStaticText : public FOptionMenuItem { EColorRange mColor; public: - FOptionMenuItemStaticText(const char *label, bool header) + FOptionMenuItemStaticText(const char *label, EColorRange color = CR_UNDEFINED) : FOptionMenuItem(label, NAME_None, true) { - mColor = header? OptionSettings.mFontColorHeader : OptionSettings.mFontColor; + mColor = color == CR_UNDEFINED? (EColorRange)OptionSettings.mFontColor : color; } - int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override { drawLabel(indent, y, mColor); return -1; } - bool Selectable() + bool Selectable() override { return false; } @@ -488,25 +525,25 @@ class FOptionMenuItemStaticTextSwitchable : public FOptionMenuItem int mCurrent; public: - FOptionMenuItemStaticTextSwitchable(const char *label, const char *label2, FName action, bool header) + FOptionMenuItemStaticTextSwitchable(const char *label, const char *label2, FName action, EColorRange color = CR_UNDEFINED) : FOptionMenuItem(label, action, true) { - mColor = header? OptionSettings.mFontColorHeader : OptionSettings.mFontColor; + mColor = color == CR_UNDEFINED? (EColorRange)OptionSettings.mFontColor : color; mAltText = label2; mCurrent = 0; } - int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override { const char *txt = mCurrent? mAltText.GetChars() : mLabel.GetChars(); if (*txt == '$') txt = GStrings(txt + 1); - int w = SmallFont->StringWidth(txt) * CleanXfac_1; + int w = OptionWidth(txt) * CleanXfac_1; int x = (screen->GetWidth() - w) / 2; - DrawText(&twod,SmallFont, mColor, x, y, txt, DTA_CleanNoMove_1, true, TAG_DONE); + drawText(x, y, mColor, txt); return -1; } - bool SetValue(int i, int val) + bool SetValue(int i, int val) override { if (i == 0) { @@ -516,7 +553,7 @@ public: return false; } - bool SetString(int i, const char *newtext) + bool SetString(int i, const char *newtext) override { if (i == 0) { @@ -526,7 +563,7 @@ public: return false; } - bool Selectable() + bool Selectable() override { return false; } @@ -547,8 +584,8 @@ class FOptionMenuSliderBase : public FOptionMenuItem int mSliderShort; public: - FOptionMenuSliderBase(const char *label, double min, double max, double step, int showval) - : FOptionMenuItem(label, NAME_None) + FOptionMenuSliderBase(const char *label, double min, double max, double step, int showval, FName command = NAME_None) + : FOptionMenuItem(label, command) { mMin = min; mMax = max; @@ -566,6 +603,11 @@ public: // Draw a slider. Set fracdigits negative to not display the current value numerically. // //============================================================================= + + void DrawSliderElement (int color, int x, int y, const char * str) + { + DrawText (&twod, ConFont, color, x, y, str, DTA_CellX, 16 * CleanXfac_1, DTA_CellY, 16 * CleanYfac_1); + } void DrawSlider (int x, int y, double min, double max, double cur, int fracdigits, int indent) { @@ -588,36 +630,36 @@ public: if (!mSliderShort) { - M_DrawConText(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12"); - M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 78) / range)) * CleanXfac_1), cy, "\x13"); + DrawSliderElement(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12"); + DrawSliderElement(CR_ORANGE, x + int((5 + ((ccur * 78) / range)) * CleanXfac_1), cy, "\x13"); } else { // On 320x200 we need a shorter slider - M_DrawConText(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x12"); - M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 38) / range)) * CleanXfac_1), cy, "\x13"); + DrawSliderElement(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x12"); + DrawSliderElement(CR_ORANGE, x + int((5 + ((ccur * 38) / range)) * CleanXfac_1), cy, "\x13"); right -= 5*8*CleanXfac_1; } if (fracdigits >= 0 && right + maxlen <= screen->GetWidth()) { snprintf(textbuf, countof(textbuf), "%.*f", fracdigits, cur); - DrawText(&twod,SmallFont, CR_DARKGRAY, right, y, textbuf, DTA_CleanNoMove_1, true, TAG_DONE); + drawText(right, y, CR_DARKGRAY, textbuf); } } //============================================================================= - int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override { drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor); - mDrawX = indent + CURSORSPACE; + mDrawX = indent + CursorSpace(); DrawSlider (mDrawX, y, mMin, mMax, GetSliderValue(), mShowValue, indent); return indent; } //============================================================================= - bool MenuEvent (int mkey, bool fromcontroller) + bool MenuEvent (int mkey, bool fromcontroller) override { double value = GetSliderValue(); @@ -634,11 +676,11 @@ public: return FOptionMenuItem::MenuEvent(mkey, fromcontroller); } SetSliderValue(clamp(value, mMin, mMax)); - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); + M_MenuSound(ChangeSound); return true; } - bool MouseEvent(int type, int x, int y) + bool MouseEvent(int type, int x, int y) override { DOptionMenu *lm = static_cast(DMenu::CurrentMenu); if (type != DMenu::MOUSE_Click) @@ -651,7 +693,7 @@ public: } int slide_left = mDrawX+8*CleanXfac_1; - int slide_right = slide_left + (10*8*CleanXfac_1 >> mSliderShort); // 12 char cells with 8 pixels each. + int slide_right = slide_left + (10*8*CleanXfac_1 >> mSliderShort); // 10 char cells with 8 pixels each. if (type == DMenu::MOUSE_Click) { @@ -663,7 +705,7 @@ public: if (v != GetSliderValue()) { SetSliderValue(v); - ////S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); + M_MenuSound(ChangeSound); } if (type == DMenu::MOUSE_Click) { @@ -690,7 +732,7 @@ public: mCVar = FindCVar(menu, NULL); } - double GetSliderValue() + double GetSliderValue() override { if (mCVar != NULL) { @@ -702,7 +744,7 @@ public: } } - void SetSliderValue(double val) + void SetSliderValue(double val) override { if (mCVar != NULL) { @@ -730,12 +772,12 @@ public: mPVal = pVal; } - double GetSliderValue() + double GetSliderValue() override { return *mPVal; } - void SetSliderValue(double val) + void SetSliderValue(double val) override { *mPVal = (float)val; } @@ -771,18 +813,15 @@ public: return GetCVarString(); } - int Draw ( FOptionMenuDescriptor*, int y, int indent, bool selected ) + int Draw ( FOptionMenuDescriptor*, int y, int indent, bool selected ) override { bool grayed = mGrayCheck != NULL && !( mGrayCheck->GetGenericRep( CVAR_Bool ).Bool ); - drawLabel( indent, y, selected ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed ); - int overlay = grayed? MAKEARGB( 96, 48, 0, 0 ) : 0; - - DrawText(&twod, SmallFont, OptionSettings.mFontColorValue, indent + CURSORSPACE, y, - Represent().GetChars(), DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE ); + drawLabel(indent, y, selected ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed); + drawValue(indent, y, OptionSettings.mFontColorValue, Represent(), grayed); return indent; } - bool GetString ( int i, char* s, int len ) + bool GetString ( int i, char* s, int len ) override { if ( i == 0 ) { @@ -794,7 +833,7 @@ public: return false; } - bool SetString ( int i, const char* s ) + bool SetString ( int i, const char* s ) override { if ( i == 0 ) { @@ -832,9 +871,9 @@ public: FOptionMenuFieldBase ( label, menu, graycheck ), mEntering ( false ) {} - FString Represent() + FString Represent() override { - FString text = mEntering ? mEditName : GetCVarString(); + FString text = mEntering ? mEditName : FString(GetCVarString()); if ( mEntering ) text += '_'; @@ -842,28 +881,28 @@ public: return text; } - int Draw(FOptionMenuDescriptor*desc, int y, int indent, bool selected) + int Draw(FOptionMenuDescriptor*desc, int y, int indent, bool selected) override { if (mEntering) { // reposition the text so that the cursor is visible when in entering mode. FString text = Represent(); int tlen = SmallFont->StringWidth(text) * CleanXfac_1; - int newindent = screen->GetWidth() - tlen - CURSORSPACE; + int newindent = screen->GetWidth() - tlen - CursorSpace(); if (newindent < indent) indent = newindent; } return FOptionMenuFieldBase::Draw(desc, y, indent, selected); } - bool MenuEvent ( int mkey, bool fromcontroller ) + bool MenuEvent ( int mkey, bool fromcontroller ) override { if ( mkey == MKEY_Enter ) { - //S_Sound( CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE ); - strcpy( mEditName, GetCVarString() ); + M_MenuSound(AdvanceSound); + mEditName = GetCVarString(); mEntering = true; - //DMenu* input = new DTextEnterMenu ( DMenu::CurrentMenu, mEditName, sizeof mEditName, 2, fromcontroller ); - //M_ActivateMenu( input ); + DMenu* input = new DTextEnterMenu ( DMenu::CurrentMenu, mEditName, sizeof mEditName, 2, fromcontroller ); + M_ActivateMenu( input ); return true; } else if ( mkey == MKEY_Input ) @@ -889,7 +928,7 @@ public: private: bool mEntering; - char mEditName[128]; + FString mEditName; }; //============================================================================= @@ -918,7 +957,7 @@ public: mStep = 1; } - bool MenuEvent ( int mkey, bool fromcontroller ) + bool MenuEvent ( int mkey, bool fromcontroller ) override { if ( mCVar ) { @@ -944,7 +983,7 @@ public: UCVarValue vval; vval.Float = value; mCVar->SetGenericRep( vval, CVAR_Float ); - //S_Sound( CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE ); + M_MenuSound(ChangeSound); } return true; diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index e7365d722..1fb3e4438 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gstrings.h" #include "version.h" #include "namesdyn.h" +#include "menus.h" #include "../../glbackend/glbackend.h" BEGIN_DUKE_NS @@ -429,17 +430,21 @@ void GameInterface::MenuOpened() } } -void GameInterface::MenuSound(::GameInterface::EMenuSounds snd) +void GameInterface::MenuSound(EMenuSounds snd) { switch (snd) { - case SelectSound: + case CursorSound: S_PlaySound(KICK_HIT); break; - case ChooseSound: + case AdvanceSound: S_PlaySound(PISTOL_BODYHIT); break; + + case CloseSound: + S_PlaySound(EXITMENUSOUND); + break; default: return; @@ -449,7 +454,6 @@ void GameInterface::MenuSound(::GameInterface::EMenuSounds snd) void GameInterface::MenuClosed() { - S_PlaySound(EXITMENUSOUND); if (!ud.pause_on) S_PauseSounds(false); } @@ -473,6 +477,8 @@ void GameInterface::CustomMenuSelection(int menu, int item) VM_OnEventWithReturn(EVENT_NEWGAMECUSTOM, -1, myconnectindex, menu); } +EXTERN_CVAR(Bool, menu_sounds) + void GameInterface::StartGame(FGameStartup& gs) { int32_t skillsound = PISTOL_BODYHIT; @@ -494,7 +500,7 @@ void GameInterface::StartGame(FGameStartup& gs) } ud.m_player_skill = gs.Skill + 1; - ud.skill_voice = S_PlaySound(skillsound); + if (menu_sounds) ud.skill_voice = S_PlaySound(skillsound); ud.m_respawn_monsters = (gs.Skill == 3); ud.m_monsters_off = ud.monsters_off = 0; ud.m_respawn_items = 0; diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index 017c03485..186429bb2 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -357,27 +357,29 @@ void GameInterface::MenuOpened() } } -void GameInterface::MenuSound(::GameInterface::EMenuSounds snd) +void GameInterface::MenuSound(EMenuSounds snd) { switch (snd) { - case SelectSound: + case CursorSound: S_PlaySound(RR ? 335 : KICK_HIT); break; - case ChooseSound: + case AdvanceSound: S_PlaySound(RR? 341 : PISTOL_BODYHIT); break; + + case CloseSound: + S_PlaySound(EXITMENUSOUND); + break; default: return; } } - void GameInterface::MenuClosed() { - S_PlaySound(EXITMENUSOUND); if (!ud.pause_on) S_PauseSounds(false); } @@ -394,6 +396,7 @@ bool GameInterface::CanSave() return true; } +EXTERN_CVAR(Bool, menu_sounds) void GameInterface::StartGame(FGameStartup& gs) { int32_t skillsound = PISTOL_BODYHIT; @@ -418,7 +421,7 @@ void GameInterface::StartGame(FGameStartup& gs) } ud.m_player_skill = gs.Skill + 1; - g_skillSoundVoice = S_PlaySound(skillsound); + if (menu_sounds) g_skillSoundVoice = S_PlaySound(skillsound); ud.m_respawn_monsters = (gs.Skill == 3); ud.m_monsters_off = ud.monsters_off = 0; ud.m_respawn_items = 0; diff --git a/source/rr/src/duke3d.h b/source/rr/src/duke3d.h index 108d565f7..324b6c2a7 100644 --- a/source/rr/src/duke3d.h +++ b/source/rr/src/duke3d.h @@ -160,7 +160,7 @@ struct GameInterface : ::GameInterface GameStats getStats() override; void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int flags); void MenuOpened() override; - void MenuSound(::GameInterface::EMenuSounds snd) override; + void MenuSound(EMenuSounds snd) override; void MenuClosed() override; bool CanSave() override; void StartGame(FGameStartup& gs) override; From af81141f8280ad3828eb02365a0b25729db1391e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Nov 2019 01:52:21 +0100 Subject: [PATCH 051/203] - defined credits and "help" menu for Shadow Warrior Credits follows the recent VoidSW change, so the help menu will now take care of the ad screens - provided that someone goes to the console and tries to open it. --- wadsrc/static/demolition/menudef.txt | 31 ++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 42a01d684..f4edc5104 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -380,6 +380,15 @@ ImageScroller "HelpMenu" ImageItem "TEXTSTORY", 400 ImageItem "F1HELP", 401 } + ifgame(ShadowWarrior) + { + // The menu has no default binding, but if someone tries to open it anyway show the cool retro ads that were shipped with the game. :D + ImageItem "#5262" + ifnotshareware + { + ImageItem "#5261" + } + } } //------------------------------------------------------------------------------------------- @@ -395,13 +404,19 @@ ImageScroller "HelpMenu" ImageScroller "CreditsMenu" { - ifgame(Duke, Nam, WW2GI, Fury) + ifgame(Duke, Nam, WW2GI) { ImageItem "CREDITSTEXT1", 990 ImageItem "CREDITSTEXT2", 991 ImageItem "CREDITSTEXT3", 992 animatedtransition } + ifgame(fury) + { + // Ion Fury does not have a separate credits menu, so if someone tries to open it anyway, use the same screens as "Help" but start on the one for the credits. + ImageItem "F1HELP", 401 + ImageItem "TEXTSTORY", 400 + } ifgame(Redneck) { // no point putting this into the string table. @@ -464,6 +479,18 @@ ImageScroller "CreditsMenu" TextItem "REDNECK RAMPAGE RIDES AGAIN\n(c) 1998 XATRIX ENTERTAINMENT, INC.\n\nREDNECK RAMPAGE RIDES AGAIN\nIS A TRADEMARK OF\nINTERPLAY PRODUCTIONS", 70 animatedtransition } + ifgame(ShadowWarrior) + { + ifshareware + { + ImageItem "#5110" + ImageItem "#5112" + } + ImageItem "#5111" + ImageItem "#5118" + ImageItem "#4979" + ImageItem "#5113" + } } //------------------------------------------------------------------------------------------- @@ -491,4 +518,4 @@ ListMenu "SaveGameMenu" Position 0, 40 Class "SaveMenu" // uses its own implementation } - \ No newline at end of file + From ebcc25f36d3d31c9324866211692d95f31ac47e7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Nov 2019 02:12:38 +0100 Subject: [PATCH 052/203] - prototyping the Blood fullscreen menu entries These are a bit more sophisticated than what the other games have. ;) --- source/common/menu/menudef.cpp | 13 +++++++++++++ wadsrc/static/demolition/menudef.txt | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 5d664e12e..087e32b6d 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -604,6 +604,19 @@ static void ParseImageScrollerBody(FScanner &sc, FImageScrollerDescriptor *desc) } desc->mItems.Push(item); } + else if (sc.Compare("qavanimationitem")) + { + if (!(g_gameType & GAMEFLAG_BLOOD)) + { + I_Error("QAV animations not available!"); // these (currently) only exist in Blood. + } + FImageScrollerDescriptor::ScrollerItem item; + sc.GetString(); + item.text = sc.String; + item.type = -1; + item.scriptID = INT_MAX; + desc->mItems.Push(item); + } else if (sc.Compare("animatedtransition")) { desc->mFlags |= LMF_Animate; diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index f4edc5104..a369d6835 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -380,6 +380,13 @@ ImageScroller "HelpMenu" ImageItem "TEXTSTORY", 400 ImageItem "F1HELP", 401 } + ifgame(blood) + { + QAVAnimationItem "Help4" + QAVAnimationItem "Help5" + QAVAnimationItem "Help3" + QAVAnimationItem "Help3b" + } ifgame(ShadowWarrior) { // The menu has no default binding, but if someone tries to open it anyway show the cool retro ads that were shipped with the game. :D @@ -479,6 +486,10 @@ ImageScroller "CreditsMenu" TextItem "REDNECK RAMPAGE RIDES AGAIN\n(c) 1998 XATRIX ENTERTAINMENT, INC.\n\nREDNECK RAMPAGE RIDES AGAIN\nIS A TRADEMARK OF\nINTERPLAY PRODUCTIONS", 70 animatedtransition } + ifgame(blood) + { + QAVAnimationItem "Credits" + } ifgame(ShadowWarrior) { ifshareware From 6d110da209cb731c0042d323823e3e231dfaa68a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Nov 2019 20:14:45 +0100 Subject: [PATCH 053/203] - removed some piece of obsolete code merged from upstream. --- source/sw/src/game.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index a7963f151..1c7154892 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -3049,14 +3049,6 @@ int32_t GameInterface::app_main() int cnt = 0; uint32_t TotalMemory; - if (argc > 1) - { - buildputs("Application parameters: "); - for (i = 1; i < argc; ++i) - buildprintf("%s ", argv[i]); - buildputs("\n"); - } - SW_ExtInit(); CONFIG_ReadSetup(); From eded45cf98cf9e3c39a6bf1d08058e1b196d511b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Nov 2019 20:44:36 +0100 Subject: [PATCH 054/203] - fixed GRPINFO. --- wadsrc/static/demolition/demolition.grpinfo | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/wadsrc/static/demolition/demolition.grpinfo b/wadsrc/static/demolition/demolition.grpinfo index f4dcebc85..9674d5d16 100644 --- a/wadsrc/static/demolition/demolition.grpinfo +++ b/wadsrc/static/demolition/demolition.grpinfo @@ -332,8 +332,8 @@ grpinfo grpinfo { + // This is for detecting zipped versions of the mod. The default configuration with all files dumped in the game filter requires starting the game with "-route66" name "Redneck Rampage: Suckin' Grits on Route 66" - loaddirectory scriptname "GAME66.CON" mustcontain "TILESA66.ART", "TILESB66.ART", "CARNIVAL.MAP", "TRUCKSTP.MAP", "GAME66.CON" flags GAMEFLAG_RR|GAMEFLAG_ADDON @@ -370,13 +370,13 @@ grpinfo grpinfo { + // This is for detecting zipped versions of the mod. The default configuration with all files dumped in the game filter requires starting the game with "-cryptic" name "BLOOD: Cryptic Passage" - loaddirectory scriptname "CRYPTIC.INI" mustcontain "CRYPTIC.INI", "CP01.MAP", "CP02.MAP" flags GAMEFLAG_BLOOD|GAMEFLAG_ADDON dependency BLOOD_CRC - loadart "CPART07.AR_", "CPART15.AR_" // some versions have these file names, some have the real ones instead so these must be listed but cannot be used for checking. + loadart "CPART07.AR_", "CPART15.AR_" gamefilter "Blood.Cryptic" } @@ -414,7 +414,7 @@ grpinfo { name "Shadow Warrior Shareware 1.2" flags GAMEFLAG_SW|GAMEFLAG_SHAREWARE - crc 0x08A7FA1F´ + crc 0x08A7FA1F size 26056769 defname "sw.def" gamefilter "ShadowWarrior.Shareware" @@ -424,7 +424,7 @@ grpinfo { name "Shadow Warrior Mac Demo" flags GAMEFLAG_SW|GAMEFLAG_SHAREWARE - crc 0x4227F535u + crc 0x4227F535 size 26056769 defname "sw.def" gamefilter "ShadowWarrior.Shareware" @@ -452,14 +452,3 @@ grpinfo gamefilter "ShadowWarrior.TwinDragon" } - - -internalgrpfile grpfiles[numgrpfiles] = -{ - { "Shadow Warrior", SWREG12_CRC, 47536148, 0, 0 }, - { "Shadow Warrior Shareware 1.0", 0xDAA6BECEu, 25702245, 0, 0 }, - { "Shadow Warrior Shareware 1.1", 0xF21A6B35u, 25833456, 0, 0 }, - { "Shadow Warrior Shareware 1.2", 0x08A7FA1Fu, 26056769, 0, 0 }, - { "Shadow Warrior Mac Demo", 0x4227F535u, 26056769, 0, 0 }, - { "Wanton Destruction", SWWD_CRC, 48698128, GRP_HAS_DEPENDENCY, SWREG12_CRC }, - { "Twin Dragon", SWTD_CRC, 12499012, GRP_HAS_DEPENDENCY, SWREG12_CRC }, From 94b4044d95014bd328215a8aa7a0dcdbbe4faad1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Nov 2019 21:06:38 +0100 Subject: [PATCH 055/203] - text file update. --- wadsrc/static/demolition/language.csv | 58 ++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index 55e8b3769..4ddf96f7c 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -16,4 +16,60 @@ Select a user map to play,MNU_SELECTUSERMAP,,,,,"Wähle ein Level zum Spielen ",,,,,,,,,,,,,,,,, Select an Episode,MNU_SELECTEPISODE,,,,,"Welche Episode? ",,,,,,,,,,,,,,,,, -Select Skill,MNU_SELECTSKILL,,,,,Schwierigkeitsgrad,,,,,,,,,,,,,,,,, \ No newline at end of file +Select Skill,MNU_SELECTSKILL,,,,,Schwierigkeitsgrad,,,,,,,,,,,,,,,,, +About Demolition,MNU_ENGINECREDITS,,,,,Über Demolition,,,,,,,,,,,,,,,,, +No Picture,MNU_NOPICTURE,,,,Bez obrázku,Kein Bild,,Neniu Bildo,Sin Imagen,,Ei kuvaa,Pas d'image,,Nessuna immagine,画像無し,사진 없음,Geen beeld,Brak obrazka,Sem imagem,,,"Нет +изображения",Нема слике +"Different +Version",MNU_DIFFVERSION,,,,Jiná verze,Falsche Version,,Malsama Versio,Versión Diferente,,Eri versio,"Version +Différente",,Versione differente,"別バージョンの +データ",다른 버젼,Anders Versie,"Inna +Wersja","Versão +Diferente",,,"Другая +версия",Другачија верзија +No files,MNU_NOFILES,,,,Žádné soubory,Keine Dateien,,Neniuj dosieroj,Sin archivos,,Ei tiedostoja,Pas de fichiers,,Nessun file,ファイル無し,파일 없음,Geen bestanden,Brak plików,Vazio,,,Нет файлов,Нема фајлова +"Do you really want to delete the savegame +",MNU_DELETESG,,,,Opravdu chceš smazat tuto uloženou hru?,Willst du diesen Spielstand wirklich löschen?,,Ĉu vi vere volas forviŝi la konservan ludon?,"¿Realmente deseas eliminar la partida? +",,Haluatko varmasti poistaa tallennetun pelin ,"Voulez vous vraiment effacer cette sauvegarde? +",Biztos ki akarod törölni a mentést?,Vuoi veramente rimuovere il salvataggio,本当にこのセーブを消すのか?,저장된 게임을 정말로 삭제하시겠습니까?,Wil je echt de opgeslagen spel verwijderen?,Czy naprawdę chcesz usunąć zapis gry,"Deseja mesmo deletar o jogo salvo +",Deseja mesmo apagar o jogo,,"Вы действительно хотите удалить сохранение +",Да ли стварно желите да избришете сачувану игру +Press Y or N.,PRESSYN,,,,Stiskni Y nebo N.,Drücke Y oder N.,"Πάτα Y ή N +",Premu Y aŭ N.,Presiona Y ó N.,,Paina Y tai N.,Appuyez sur Y ou N.,Nyomj Y-t vagy N-t.,Premi Y oppure N.,YかNで答えろ,Y키 또는 N키를 누르시오.,Druk op Y of N.,Wciśnij Y lub N.,Aperte Y ou N.,Carrega Y ou N.,,Нажмите Y или N.,Притисните Y или N. +"You can't save if you aren't playing! + +Press a key.",SAVEDEAD,,,,"Nemůžeš ukládat pokud nehraješ! + +Stiskni libovolnou klávesu.","Du kannst nicht speichern, wenn du nicht spielst. + +Drücke eine Taste",,"Vi ne povas konservi, kiam vi ne ludas! + +Premu klavon.","¡No puedes guardar si no estás jugando! + +Presiona una tecla.",,"Et voi tallentaa, jos et ole pelissä! + +Paina jotain näppäintä.","Vous ne pouvez pas sauvegarder si vous ne jouez pas! + +Appuyez sur une touche.","Nem tudsz menteni ha nem is játszol! + +Nyomj meg egy gombot.","Non puoi salvare se non stai giocando! + +Premi un tasto.","プレイ中でないとセーブできない! + +何かキーを押せ","게임을 플레이 중이지 않을 때는 게임을 저장할 수 없습니다! + +키를 누르시오.","Je kunt niet opslaan als je niet speelt! + +Druk op een toets.","Nie możesz zapisać, jeśli nie grasz! + +Wciśnij dowolny klawisz.","Você não pode salvar se não estiver jogando! + +Aperte qualquer tecla.","Você não pode salvar se não estiver a jogar! + +Carrega numa tecla qualquer.",,"Невозможно сохранить игру, не начав её! + +Нажмите любую клавишу.","Не можете сачувати игру ако не играте! + +Притисните тастер." +Do you really want to do this?,SAFEMESSAGE,,,,Vážně to chceš udělat?,Möchtest du das wirklich tun?,,Ĉu vi vere volas fari tion?,¿Realmente quieres hacer esto?,¿Realmente quieres hacerlo?,Haluatko varmasti tehdä tämän?,Voulez-vous vraiment faire ça?,Biztos megakarod tenni?,Sei sicuro di volerlo fare?,本当に実行するのか?,정말로 정하시겠습니까?,Wil je dit echt doen?,Naprawdę chcesz to zrobić?,Você deseja mesmo fazer isso?,Desejas mesmo fazer isso?,,Вы уверены?,Да ли заиста желите то да урадите? +Not set,NOTSET,,,,Není nastavené,Nicht gesetzt,,Ne agordita,No Asignado,,Ei asetettu,Pas paramétré,Nincs beállítva,Non assegnato,セットされてない,정하지 않음,Niet ingesteld,Nie ustawiono,Não definido,,,Не задан,Није намештено \ No newline at end of file From e266044391be65af1c6714fa50b872259a9c3af4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Nov 2019 00:49:50 +0100 Subject: [PATCH 056/203] - update of load/save menu to latest GZDoom code. Input in save menu working. --- source/CMakeLists.txt | 1 + source/common/2d/v_draw.cpp | 1 + source/common/2d/v_draw.h | 1 + source/common/2d/v_drawtext.cpp | 22 + source/common/fonts/font.cpp | 2 +- source/common/menu/loadsavemenu.cpp | 1230 +++++++++--------------- source/common/menu/menu.cpp | 5 +- source/common/menu/menu.h | 84 +- source/common/menu/menudef.cpp | 3 - source/common/menu/menuinput.cpp | 110 ++- source/common/menu/savegamemanager.cpp | 507 ++++++++++ source/common/utility/namedef.h | 4 +- 12 files changed, 1109 insertions(+), 861 deletions(-) create mode 100644 source/common/menu/savegamemanager.cpp diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index a70e9eb18..ded88484d 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -830,6 +830,7 @@ set (PCH_SOURCES common/menu/imagescroller.cpp common/menu/joystickmenu.cpp common/menu/listmenu.cpp + common/menu/savegamemanager.cpp common/menu/loadsavemenu.cpp common/menu/menu.cpp common/menu/menudef.cpp diff --git a/source/common/2d/v_draw.cpp b/source/common/2d/v_draw.cpp index d89dcb555..3de2fbded 100644 --- a/source/common/2d/v_draw.cpp +++ b/source/common/2d/v_draw.cpp @@ -901,3 +901,4 @@ void ScaleWithAspect(int& w, int& h, int Width, int Height) h = static_cast(y); } + diff --git a/source/common/2d/v_draw.h b/source/common/2d/v_draw.h index c581cad78..a120c0cfe 100644 --- a/source/common/2d/v_draw.h +++ b/source/common/2d/v_draw.h @@ -48,6 +48,7 @@ void DrawTexture(F2DDrawer *drawer, FTexture* img, double x, double y, int tags_ void DrawChar (F2DDrawer* drawer, FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...); void DrawText(F2DDrawer* drawer, FFont *font, int normalcolor, double x, double y, const char *string, int tag_first, ...); void DrawText(F2DDrawer* drawer, FFont *font, int normalcolor, double x, double y, const char32_t *string, int tag_first, ...); +void DrawFrame(F2DDrawer* twod, PalEntry color, int left, int top, int width, int height, int thickness); EXTERN_CVAR(Int, con_scaletext) // Scale notify text at high resolutions? EXTERN_CVAR(Int, con_scale) diff --git a/source/common/2d/v_drawtext.cpp b/source/common/2d/v_drawtext.cpp index 7baeb213d..46bc9a608 100644 --- a/source/common/2d/v_drawtext.cpp +++ b/source/common/2d/v_drawtext.cpp @@ -246,3 +246,25 @@ void DrawText(F2DDrawer* drawer, FFont *font, int normalcolor, double x, double DrawTextCommon(drawer, font, normalcolor, x, y, string, parms); } +//========================================================================== +// +// V_DrawFrame +// +// Draw a frame around the specified area using the view border +// frame graphics. The border is drawn outside the area, not in it. +// +//========================================================================== + +void DrawFrame(F2DDrawer* twod, PalEntry color, int left, int top, int width, int height, int thickness) +{ + // Sanity check for incomplete gameinfo + int offset = thickness == -1 ? screen->GetHeight() / 400 : thickness; + int right = left + width; + int bottom = top + height; + + // Draw top and bottom sides. + twod->AddColorOnlyQuad(left, top - offset, width, offset, color); + twod->AddColorOnlyQuad(left - offset, top - offset, offset, height + 2 * offset, color); + twod->AddColorOnlyQuad(left, bottom, width, offset, color); + twod->AddColorOnlyQuad(right, top - offset, offset, height + 2 * offset, color); +} diff --git a/source/common/fonts/font.cpp b/source/common/fonts/font.cpp index a6a0511d3..5f64a4bca 100644 --- a/source/common/fonts/font.cpp +++ b/source/common/fonts/font.cpp @@ -684,7 +684,7 @@ int FFont::StringWidth(const uint8_t *string) const } else { - w += NewSmallFont->CharWidth(chr) + GlobalKerning; + w += CharWidth(chr) + GlobalKerning; } } diff --git a/source/common/menu/loadsavemenu.cpp b/source/common/menu/loadsavemenu.cpp index f5ed87171..f68ab1d25 100644 --- a/source/common/menu/loadsavemenu.cpp +++ b/source/common/menu/loadsavemenu.cpp @@ -54,12 +54,8 @@ class DLoadSaveMenu : public DListMenu { using Super = DListMenu; - friend void ClearSaveGames(); protected: - static TArray SaveGames; - static int LastSaved; - static int LastAccessed; int Selected; int TopItem; @@ -86,650 +82,361 @@ protected: int commentHeight; int commentRight; int commentBottom; + int commentRows; + + double FontScale; + DTextEnterMenu *mInput = nullptr; + TArray BrokenSaveComment; + bool mEntering = false; - static int InsertSaveNode (FSaveGameNode *node); - static void ReadSaveStrings (); + //============================================================================= + // + // End of static savegame maintenance code + // + //============================================================================= - - FTexture *SavePic = nullptr; - TArray SaveComment; - bool mEntering; - FString savegamestring; - - DLoadSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); - void Init(DMenu* parent, FListMenuDescriptor* desc) override; - void Destroy(); - - int RemoveSaveSlot (int index); - void UnloadSaveData (); - void ClearSaveStuff (); - void ExtractSaveData (int index); - void Drawer (); - bool MenuEvent (int mkey, bool fromcontroller); - bool MouseEvent(int type, int x, int y); - bool Responder(event_t *ev); - -public: - static void NotifyNewSave (const char *file, const char *title, bool okForQuicksave); - -}; - -TArray DLoadSaveMenu::SaveGames; -int DLoadSaveMenu::LastSaved = -1; -int DLoadSaveMenu::LastAccessed = -1; - -FSaveGameNode *quickSaveSlot; - -//============================================================================= -// -// Save data maintenance (stored statically) -// -//============================================================================= - -void ClearSaveGames() -{ - for(unsigned i=0;ibNoDelete) - delete DLoadSaveMenu::SaveGames[i]; + savegameManager.ReadSaveStrings(); } - DLoadSaveMenu::SaveGames.Clear(); -} -//============================================================================= -// -// Save data maintenance (stored statically) -// -//============================================================================= - -int DLoadSaveMenu::RemoveSaveSlot (int index) -{ - FSaveGameNode *file = SaveGames[index]; - - if (quickSaveSlot == SaveGames[index]) + void Init(DMenu* parent, FListMenuDescriptor* desc) { - quickSaveSlot = NULL; + Super::Init(parent, desc); + int Width43 = screen->GetHeight() * 4 / 3; + int Left43 = (screen->GetWidth() - Width43) / 2; + float wScale = Width43 / 640.; + savepicLeft = Left43 + int(20 * wScale); + savepicTop = mDesc->mYpos * screen->GetHeight() / 200 ; + savepicWidth = int(240 * wScale); + savepicHeight = int(180 * wScale); + + + FontScale = max(screen->GetHeight() / 480, 1); + rowHeight = std::max(int((NewConsoleFont->GetHeight() + 1) * FontScale), 1); + listboxLeft = savepicLeft + savepicWidth + int(20 * wScale); + listboxTop = savepicTop; + listboxWidth = Width43 + Left43 - listboxLeft - int(30 * wScale); + int listboxHeight1 = screen->GetHeight() - listboxTop - int(20*wScale); + listboxRows = (listboxHeight1 - 1) / rowHeight; + listboxHeight = listboxRows * rowHeight + 1; + listboxRight = listboxLeft + listboxWidth; + listboxBottom = listboxTop + listboxHeight; + + commentLeft = savepicLeft; + commentTop = savepicTop + savepicHeight + int(16 * wScale); + commentWidth = savepicWidth; + commentHeight = listboxHeight - savepicHeight - (16 * wScale); + commentRight = commentLeft + commentWidth; + commentBottom = commentTop + commentHeight; + commentRows = commentHeight / rowHeight; } - if (Selected == index) + + //============================================================================= + // + // + // + //============================================================================= + + void Drawer() override { - Selected = -1; - } - if (!file->bNoDelete) delete file; - SaveGames.Delete(index); - if ((unsigned)index >= SaveGames.Size()) index--; - return index; -} + Super::Drawer(); -//============================================================================= -// -// -// -//============================================================================= + int i; + unsigned j; + bool didSeeSelected = false; -int DLoadSaveMenu::InsertSaveNode (FSaveGameNode *node) -{ - if (SaveGames.Size() == 0) - { - return SaveGames.Push(node); - } - - if (node->bOldVersion) - { // Add node at bottom of list - return SaveGames.Push(node); - } - else - { // Add node at top of list - unsigned int i; - for(i = 0; i < SaveGames.Size(); i++) + // Draw picture area + /* + if (gameaction == ga_loadgame || gameaction == ga_loadgamehidecon || gameaction == ga_savegame) { - if (SaveGames[i]->bOldVersion || - stricmp (node->Title, SaveGames[i]->Title) <= 0) - { - break; - } - } - SaveGames.Insert(i, node); - return i; - } -} - - -//============================================================================= -// -// M_ReadSaveStrings -// -// Find savegames and read their titles -// -//============================================================================= - -void DLoadSaveMenu::ReadSaveStrings () -{ - if (SaveGames.Size() == 0) - { - void *filefirst; - findstate_t c_file; - FString filter; - - LastSaved = LastAccessed = -1; - quickSaveSlot = NULL; - filter = G_BuildSaveName("*"); - filefirst = I_FindFirst (filter.GetChars(), &c_file); - if (filefirst != ((void *)(-1))) - { - do - { - // I_FindName only returns the file's name and not its full path - FString filepath = "";// G_BuildSaveName(I_FindName(&c_file), -1); - - FResourceFile *savegame = FResourceFile::OpenResourceFile(filepath, true, true); - if (savegame != nullptr) - { - FResourceLump *info = savegame->FindLump("info.json"); - if (info == nullptr) - { - // savegame info not found. This is not a savegame so leave it alone. - delete savegame; - continue; - } - auto fr = info->NewReader(); - FString title; - int check = G_ValidateSavegame(fr, &title); - delete savegame; - if (check != 0) - { - FSaveGameNode *node = new FSaveGameNode; - node->Filename = filepath; - node->bOldVersion = check == -1; - node->bMissingWads = check == -2; - node->Title = title; - InsertSaveNode(node); - } - } - } while (I_FindNext (filefirst, &c_file) == 0); - I_FindClose (filefirst); - } - } -} - - -//============================================================================= -// -// -// -//============================================================================= - -void DLoadSaveMenu::NotifyNewSave (const char *file, const char *title, bool okForQuicksave) -{ - FSaveGameNode *node; - - if (file == NULL) - return; - - ReadSaveStrings (); - - // See if the file is already in our list - for (unsigned i=0; iFilename.Compare (file) == 0) -#else - if (node->Filename.CompareNoCase (file) == 0) -#endif - { - node->Title = title; - node->bOldVersion = false; - node->bMissingWads = false; - if (okForQuicksave) - { - if (quickSaveSlot == NULL) quickSaveSlot = node; - LastAccessed = LastSaved = i; - } return; } - } + */ - node = new FSaveGameNode; - node->Title = title; - node->Filename = file; - node->bOldVersion = false; - node->bMissingWads = false; - int index = InsertSaveNode (node); - - if (okForQuicksave) - { - if (quickSaveSlot == NULL) quickSaveSlot = node; - LastAccessed = LastSaved = index; - } -} - -void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave) -{ - DLoadSaveMenu::NotifyNewSave(file, title, okForQuicksave); -} - -//============================================================================= -// -// End of static savegame maintenance code -// -//============================================================================= - -DLoadSaveMenu::DLoadSaveMenu(DMenu* parent, FListMenuDescriptor* desc) - : DListMenu(parent, desc) -{ - ReadSaveStrings(); -} - -void DLoadSaveMenu::Init(DMenu* parent, FListMenuDescriptor* desc) -{ - Super::Init(parent, desc); - int Width43 = screen->GetHeight() * 4 / 3; - int Left43 = (screen->GetWidth() - Width43) / 2; - float wScale = Width43 / 640.; - savepicLeft = Left43 + int(20 * wScale); - savepicTop = mDesc->mYpos * screen->GetHeight() / 200 ; - savepicWidth = int(240 * wScale); - savepicHeight = int(180 * wScale); - - rowHeight = (NewConsoleFont->GetHeight() + 1) * CleanYfac; - listboxLeft = savepicLeft + savepicWidth + int(20 * wScale); - listboxTop = savepicTop; - listboxWidth = Width43 + Left43 - listboxLeft - int(30 * wScale); - int listboxHeight1 = screen->GetHeight() - listboxTop - 10; - listboxRows = (listboxHeight1 - 1) / rowHeight; - listboxHeight = listboxRows * rowHeight + 1; - listboxRight = listboxLeft + listboxWidth; - listboxBottom = listboxTop + listboxHeight; - - commentLeft = savepicLeft; - commentTop = savepicTop + savepicHeight + int(16 * wScale); - commentWidth = savepicWidth; - commentHeight = (51+(screen->GetHeight()>200?10:0))*CleanYfac; - commentRight = commentLeft + commentWidth; - commentBottom = commentTop + commentHeight; -} - -void DLoadSaveMenu::Destroy() -{ - ClearSaveStuff (); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DLoadSaveMenu::UnloadSaveData () -{ - if (SavePic != NULL) - { - delete SavePic; - } - SaveComment.Clear(); - - SavePic = NULL; -} - -//============================================================================= -// -// -// -//============================================================================= - -void DLoadSaveMenu::ClearSaveStuff () -{ - UnloadSaveData(); - if (quickSaveSlot == (FSaveGameNode*)1) - { - quickSaveSlot = NULL; - } -} - -//============================================================================= -// -// -// -//============================================================================= - -void DLoadSaveMenu::ExtractSaveData (int index) -{ - FILE *file; - //PNGHandle *png; - FSaveGameNode *node; - - UnloadSaveData (); - - if ((unsigned)index < SaveGames.Size() && - (node = SaveGames[index]) && - !node->Filename.IsEmpty() && - !node->bOldVersion && - (file = fopen (node->Filename.GetChars(), "rb")) != NULL) - { - // Todo. - } -} - -//============================================================================= -// -// -// -//============================================================================= - -void DLoadSaveMenu::Drawer () -{ - Super::Drawer(); - - FSaveGameNode *node; - int i; - unsigned j; - bool didSeeSelected = false; - - // Draw picture area - /* - if (gameaction == ga_loadgame || gameaction == ga_loadgamehidecon || gameaction == ga_savegame) - { - return; - } - */ - - //V_DrawFrame (savepicLeft, savepicTop, savepicWidth, savepicHeight); - if (SavePic != NULL) - { - DrawTexture(&twod, SavePic, savepicLeft, savepicTop, - DTA_DestWidth, savepicWidth, - DTA_DestHeight, savepicHeight, - DTA_Masked, false, - TAG_DONE); - } - else - { - twod.AddColorOnlyQuad(savepicLeft, savepicTop, savepicWidth, savepicHeight, 0x80000000); - - if (SaveGames.Size() > 0) + PalEntry frameColor(255, 80, 80, 80); // todo: pick a proper color per game. + PalEntry fillColor(160, 0, 0, 0); + DrawFrame(&twod, frameColor, savepicLeft, savepicTop, savepicWidth, savepicHeight, -1); + if (!savegameManager.DrawSavePic(savepicLeft, savepicTop, savepicWidth, savepicHeight)) { - const char *text = - (Selected == -1 || !SaveGames[Selected]->bOldVersion) - ? GStrings("MNU_NOPICTURE") : GStrings("MNU_DIFFVERSION"); - const int textlen = NewConsoleFont->StringWidth (text)*CleanXfac; + twod.AddColorOnlyQuad(savepicLeft, savepicTop, savepicWidth, savepicHeight, fillColor); - DrawText (&twod, NewConsoleFont, CR_GOLD, savepicLeft+(savepicWidth-textlen)/2, - savepicTop+(savepicHeight-rowHeight)/2, text, - DTA_CleanNoMove, true, TAG_DONE); - } - } - - // Draw comment area - //V_DrawFrame (commentLeft, commentTop, commentWidth, commentHeight); - twod.AddColorOnlyQuad(commentLeft, commentTop, commentWidth, commentHeight, 0x80000000); - if (SaveComment.Size()) - { - // I'm not sure why SaveComment would go NULL in this loop, but I got - // a crash report where it was NULL when i reached 1, so now I check - // for that. - for (i = 0; i < SaveComment.Size() && SaveComment[i].Width >= 0 && i < 6; ++i) - { - DrawText (&twod, NewConsoleFont, CR_GOLD, commentLeft, commentTop - + NewConsoleFont->GetHeight()*i*CleanYfac, SaveComment[i].Text, - DTA_CleanNoMove, true, TAG_DONE); - } - } - - // Draw file area - //V_DrawFrame (listboxLeft, listboxTop, listboxWidth, listboxHeight); - twod.AddColorOnlyQuad(listboxLeft, listboxTop, listboxWidth, listboxHeight, 0x80000000); - - if (SaveGames.Size() == 0) - { - const char * text = GStrings("MNU_NOFILES"); - const int textlen = NewConsoleFont->StringWidth (text)*CleanXfac; - - DrawText (&twod, NewConsoleFont, CR_GOLD, listboxLeft+(listboxWidth-textlen)/2, - listboxTop+(listboxHeight-rowHeight)/2, text, - DTA_CleanNoMove, true, TAG_DONE); - return; - } - - for (i = 0, j = TopItem; i < listboxRows && j < SaveGames.Size(); i++,j++) - { - int color; - node = SaveGames[j]; - if (node->bOldVersion) - { - color = CR_BLUE; - } - else if (node->bMissingWads) - { - color = CR_ORANGE; - } - else if ((int)j == Selected) - { - color = CR_WHITE; - } - else - { - color = CR_TAN; - } - - if ((int)j == Selected) - { - twod.AddColorOnlyQuad(listboxLeft, listboxTop+rowHeight*i, listboxRight, listboxTop+rowHeight*(i+1), mEntering ? PalEntry(255,255,0,0) : PalEntry(255,0,0,255)); - didSeeSelected = true; - if (!mEntering) + if (savegameManager.SavegameCount() > 0) { - DrawText(&twod, NewConsoleFont, color, - listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->Title, - DTA_CleanNoMove, true, TAG_DONE); + FString text = (Selected == -1 || !savegameManager.GetSavegame(Selected)->bOldVersion) ? GStrings("MNU_NOPICTURE") : GStrings("MNU_DIFFVERSION"); + int textlen = NewSmallFont->StringWidth(text) * CleanXfac; + + DrawText(&twod, NewSmallFont, CR_GOLD, savepicLeft + (savepicWidth - textlen) / 2, + savepicTop + (savepicHeight - rowHeight) / 2, text, DTA_CleanNoMove, true, TAG_DONE); + } + } + + // Draw comment area + DrawFrame(&twod, frameColor, commentLeft, commentTop, commentWidth, commentHeight, -1); + twod.AddColorOnlyQuad(commentLeft, commentTop, commentWidth, commentHeight, fillColor); + + int numlinestoprint = std::min(commentRows, (int)BrokenSaveComment.Size()); + for (int i = 0; i < numlinestoprint; i++) + { + DrawText(&twod, NewConsoleFont, CR_ORANGE, commentLeft / FontScale, (commentTop + rowHeight * i) / FontScale, BrokenSaveComment[i].Text, + DTA_VirtualWidthF, screen->GetWidth() / FontScale, DTA_VirtualHeightF, screen->GetHeight() / FontScale, DTA_KeepRatio, true, TAG_DONE); + } + + + // Draw file area + DrawFrame(&twod, frameColor, listboxLeft, listboxTop, listboxWidth, listboxHeight, -1); + twod.AddColorOnlyQuad(listboxLeft, listboxTop, listboxWidth, listboxHeight, fillColor); + + if (savegameManager.SavegameCount() == 0) + { + FString text = GStrings("MNU_NOFILES"); + int textlen = int(NewConsoleFont->StringWidth(text) * FontScale); + + DrawText(&twod, NewConsoleFont, CR_GOLD, (listboxLeft + (listboxWidth - textlen) / 2) / FontScale, (listboxTop + (listboxHeight - rowHeight) / 2) / FontScale, text, + DTA_VirtualWidthF, screen->GetWidth() / FontScale, DTA_VirtualHeightF, screen->GetHeight() / FontScale, DTA_KeepRatio, true, TAG_DONE); + return; + } + + j = TopItem; + for (i = 0; i < listboxRows && j < savegameManager.SavegameCount(); i++) + { + int colr; + auto& node = *savegameManager.GetSavegame(j); + if (node.bOldVersion) + { + colr = CR_RED; + } + else if (node.bMissingWads) + { + colr = CR_YELLOW; + } + else if (j == Selected) + { + colr = CR_WHITE; } else { - DrawText(&twod, NewConsoleFont, CR_WHITE, - listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, savegamestring, - DTA_CleanNoMove, true, TAG_DONE); - - char curs[2] = { NewConsoleFont->GetCursor(), 0 }; - DrawText(&twod, NewConsoleFont, CR_WHITE, - listboxLeft+1+NewConsoleFont->StringWidth (savegamestring)*CleanXfac, - listboxTop+rowHeight*i+CleanYfac, - curs, - DTA_CleanNoMove, true, TAG_DONE); + colr = CR_TAN; } - } - else - { - DrawText(&twod, NewConsoleFont, color, - listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->Title, - DTA_CleanNoMove, true, TAG_DONE); - } - } -} -//============================================================================= -// -// -// -//============================================================================= + //screen->SetClipRect(listboxLeft, listboxTop+rowHeight*i, listboxRight, listboxTop+rowHeight*(i+1)); -bool DLoadSaveMenu::MenuEvent (int mkey, bool fromcontroller) -{ - switch (mkey) - { - case MKEY_Up: - if (SaveGames.Size() > 1) - { - if (Selected == -1) Selected = TopItem; - else + if ((int)j == Selected) { - if (--Selected < 0) Selected = SaveGames.Size()-1; - if (Selected < TopItem) TopItem = Selected; - else if (Selected >= TopItem + listboxRows) TopItem = std::max(0, Selected - listboxRows + 1); - } - UnloadSaveData (); - ExtractSaveData (Selected); - } - return true; - - case MKEY_Down: - if (SaveGames.Size() > 1) - { - if (Selected == -1) Selected = TopItem; - else - { - if (unsigned(++Selected) >= SaveGames.Size()) Selected = 0; - if (Selected < TopItem) TopItem = Selected; - else if (Selected >= TopItem + listboxRows) TopItem = std::max(0, Selected - listboxRows + 1); - } - UnloadSaveData (); - ExtractSaveData (Selected); - } - return true; - - case MKEY_PageDown: - if (SaveGames.Size() > 1) - { - if (TopItem >= (int)SaveGames.Size() - listboxRows) - { - TopItem = 0; - if (Selected != -1) Selected = 0; - } - else - { - TopItem = std::min(TopItem + listboxRows, SaveGames.Size() - listboxRows); - if (TopItem > Selected && Selected != -1) Selected = TopItem; - } - UnloadSaveData (); - ExtractSaveData (Selected); - } - return true; - - case MKEY_PageUp: - if (SaveGames.Size() > 1) - { - if (TopItem == 0) - { - TopItem = SaveGames.Size() - listboxRows; - if (Selected != -1) Selected = TopItem; - } - else - { - TopItem = std::max(TopItem - listboxRows, 0); - if (Selected >= TopItem + listboxRows) Selected = TopItem; - } - UnloadSaveData (); - ExtractSaveData (Selected); - } - return true; - - case MKEY_Enter: - return false; // This event will be handled by the subclasses - - case MKEY_MBYes: - { - if ((unsigned)Selected < SaveGames.Size()) - { - int listindex = SaveGames[0]->bNoDelete? Selected-1 : Selected; - remove (SaveGames[Selected]->Filename.GetChars()); - UnloadSaveData (); - Selected = RemoveSaveSlot (Selected); - ExtractSaveData (Selected); - - if (LastSaved == listindex) LastSaved = -1; - else if (LastSaved > listindex) LastSaved--; - if (LastAccessed == listindex) LastAccessed = -1; - else if (LastAccessed > listindex) LastAccessed--; - } - return true; - } - - default: - return Super::MenuEvent(mkey, fromcontroller); - } -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DLoadSaveMenu::MouseEvent(int type, int x, int y) -{ - if (x >= listboxLeft && x < listboxLeft + listboxWidth && - y >= listboxTop && y < listboxTop + listboxHeight) - { - int lineno = (y - listboxTop) / rowHeight; - - if (TopItem + lineno < (int)SaveGames.Size()) - { - Selected = TopItem + lineno; - UnloadSaveData (); - ExtractSaveData (Selected); - if (type == MOUSE_Release) - { - if (MenuEvent(MKEY_Enter, true)) + twod.AddColorOnlyQuad(listboxLeft, listboxTop + rowHeight * i, listboxWidth, rowHeight, mEntering ? PalEntry(255, 255, 0, 0) : PalEntry(255, 0, 0, 255)); + didSeeSelected = true; + if (!mEntering) { - return true; + DrawText(&twod, NewConsoleFont, colr, (listboxLeft + 1) / FontScale, (listboxTop + rowHeight * i + FontScale) / FontScale, node.SaveTitle, + DTA_VirtualWidthF, screen->GetWidth() / FontScale, DTA_VirtualHeightF, screen->GetHeight() / FontScale, DTA_KeepRatio, true, TAG_DONE); + } + else + { + FStringf s("%s%c", mInput->GetText(), NewConsoleFont->GetCursor()); + int length = int(NewConsoleFont->StringWidth(s) * FontScale); + int displacement = std::min(0, listboxWidth - 2 - length); + DrawText(&twod, NewConsoleFont, CR_WHITE, (listboxLeft + 1 + displacement) / FontScale, (listboxTop + rowHeight * i + FontScale) / FontScale, s, + DTA_VirtualWidthF, screen->GetWidth() / FontScale, DTA_VirtualHeightF, screen->GetHeight() / FontScale, DTA_KeepRatio, true, TAG_DONE); } } + else + { + DrawText(&twod, NewConsoleFont, colr, (listboxLeft + 1) / FontScale, (listboxTop + rowHeight * i + FontScale) / FontScale, node.SaveTitle, + DTA_VirtualWidthF, screen->GetWidth() / FontScale, DTA_VirtualHeightF, screen->GetHeight() / FontScale, DTA_KeepRatio, true, TAG_DONE); + } + //screen->ClearClipRect(); + j++; + } + } + + void UpdateSaveComment() + { + //BrokenSaveComment = NewConsoleFont.BreakLines(manager.SaveCommentString, int(commentWidth / FontScale)); + } + + //============================================================================= + // + // + // + //============================================================================= + + bool MenuEvent(int mkey, bool fromcontroller) override + { + auto& manager = savegameManager; + switch (mkey) + { + case MKEY_Up: + if (manager.SavegameCount() > 1) + { + if (Selected == -1) Selected = TopItem; + else + { + if (--Selected < 0) Selected = manager.SavegameCount() - 1; + if (Selected < TopItem) TopItem = Selected; + else if (Selected >= TopItem + listboxRows) TopItem = std::max(0, Selected - listboxRows + 1); + } + manager.UnloadSaveData(); + manager.ExtractSaveData(Selected); + UpdateSaveComment(); + } + return true; + + case MKEY_Down: + if (manager.SavegameCount() > 1) + { + if (Selected == -1) Selected = TopItem; + else + { + if (++Selected >= manager.SavegameCount()) Selected = 0; + if (Selected < TopItem) TopItem = Selected; + else if (Selected >= TopItem + listboxRows) TopItem = std::max(0, Selected - listboxRows + 1); + } + manager.UnloadSaveData(); + manager.ExtractSaveData(Selected); + UpdateSaveComment(); + } + return true; + + case MKEY_PageDown: + if (manager.SavegameCount() > 1) + { + if (TopItem >= manager.SavegameCount() - listboxRows) + { + TopItem = 0; + if (Selected != -1) Selected = 0; + } + else + { + TopItem = std::min(TopItem + listboxRows, int(manager.SavegameCount()) - listboxRows); + if (TopItem > Selected&& Selected != -1) Selected = TopItem; + } + manager.UnloadSaveData(); + manager.ExtractSaveData(Selected); + UpdateSaveComment(); + } + return true; + + case MKEY_PageUp: + if (manager.SavegameCount() > 1) + { + if (TopItem == 0) + { + TopItem = std::max(0, int(manager.SavegameCount()) - listboxRows); + if (Selected != -1) Selected = TopItem; + } + else + { + TopItem = std::max(int(TopItem - listboxRows), 0); + if (Selected >= TopItem + listboxRows) Selected = TopItem; + } + manager.UnloadSaveData(); + manager.ExtractSaveData(Selected); + UpdateSaveComment(); + } + return true; + + case MKEY_Enter: + return false; // This event will be handled by the subclasses + + case MKEY_MBYes: + { + if (Selected < manager.SavegameCount()) + { + Selected = manager.RemoveSaveSlot(Selected); + UpdateSaveComment(); + } + return true; + } + + default: + return Super::MenuEvent(mkey, fromcontroller); + } + } + + //============================================================================= + // + // + // + //============================================================================= + + bool MouseEvent(int type, int x, int y) override + { + auto& manager = savegameManager; + if (x >= listboxLeft && x < listboxLeft + listboxWidth && + y >= listboxTop && y < listboxTop + listboxHeight) + { + int lineno = (y - listboxTop) / rowHeight; + + if (TopItem + lineno < manager.SavegameCount()) + { + Selected = TopItem + lineno; + manager.UnloadSaveData(); + manager.ExtractSaveData(Selected); + UpdateSaveComment(); + if (type == MOUSE_Release) + { + if (MenuEvent(MKEY_Enter, true)) + { + return true; + } + } + } + else Selected = -1; } else Selected = -1; + + return Super::MouseEvent(type, x, y); } - else Selected = -1; - return Super::MouseEvent(type, x, y); -} + //============================================================================= + // + // + // + //============================================================================= -//============================================================================= -// -// -// -//============================================================================= - -bool DLoadSaveMenu::Responder (event_t *ev) -{ - if (ev->type == EV_GUI_Event) + bool Responder(event_t * ev) override { - if (ev->subtype == EV_GUI_KeyDown) + auto& manager = savegameManager; + if (ev->type == EV_GUI_Event) { - if ((unsigned)Selected < SaveGames.Size()) + if (ev->subtype == EV_GUI_KeyDown) { - switch (ev->data1) + if ((unsigned)Selected < manager.SavegameCount()) { - case GK_F1: - if (!SaveGames[Selected]->Filename.IsEmpty()) + switch (ev->data1) { - FStringf workbuf("File on disk:\n%s", SaveGames[Selected]->Filename.GetChars()); - SaveComment = V_BreakLines (NewConsoleFont, 216*screen->GetWidth()/640/CleanXfac, workbuf); - } - return true; + case GK_F1: + manager.SetFileInfo(Selected); + UpdateSaveComment(); + return true; - case GK_DEL: - case '\b': + case GK_DEL: + case '\b': { FString EndString; EndString.Format("%s" TEXTCOLOR_WHITE "%s" TEXTCOLOR_NORMAL "?\n\n%s", - GStrings("MNU_DELETESG"), SaveGames[Selected]->Title.GetChars(), GStrings("PRESSYN")); - M_StartMessage (EndString, 0); + GStrings("MNU_DELETESG"), manager.GetSavegame(Selected)->SaveTitle.GetChars(), GStrings("PRESSYN")); + M_StartMessage(EndString, 0); } return true; + } } } + else if (ev->subtype == EV_GUI_WheelUp) + { + if (TopItem > 0) TopItem--; + return true; + } + else if (ev->subtype == EV_GUI_WheelDown) + { + if (TopItem < manager.SavegameCount() - listboxRows) TopItem++; + return true; + } } - else if (ev->subtype == EV_GUI_WheelUp) - { - if (TopItem > 0) TopItem--; - return true; - } - else if (ev->subtype == EV_GUI_WheelDown) - { - if (TopItem < (int)SaveGames.Size() - listboxRows) TopItem++; - return true; - } + return Super::Responder(ev); } - return Super::Responder(ev); -} - +}; //============================================================================= // @@ -740,164 +447,140 @@ bool DLoadSaveMenu::Responder (event_t *ev) class DSaveMenu : public DLoadSaveMenu { using Super = DLoadSaveMenu; - FSaveGameNode NewSaveNode; - + FString mSaveName; public: - DSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); - void Destroy(); - void DoSave (FSaveGameNode *node); - bool Responder (event_t *ev); - bool MenuEvent (int mkey, bool fromcontroller); -}; + //============================================================================= + // + // + // + //============================================================================= -//============================================================================= -// -// -// -//============================================================================= - -DSaveMenu::DSaveMenu(DMenu *parent, FListMenuDescriptor *desc) -: DLoadSaveMenu(parent, desc) -{ - NewSaveNode.Title = GStrings["NEWSAVE"]; - NewSaveNode.bNoDelete = true; - SaveGames.Insert(0, &NewSaveNode); - TopItem = 0; - if (LastSaved == -1) + DSaveMenu() { - Selected = 0; + savegameManager.InsertNewSaveNode(); + TopItem = 0; + Selected = savegameManager.ExtractSaveData (-1); + UpdateSaveComment(); } - else + + //============================================================================= + // + // + // + //============================================================================= + + void Destroy() override { - Selected = LastSaved + 1; - } - ExtractSaveData (Selected); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DSaveMenu::Destroy() -{ - if (SaveGames[0] == &NewSaveNode) - { - SaveGames.Delete(0); - if (Selected == 0) Selected = -1; - else Selected--; - } -} - -//============================================================================= -// -// -// -//============================================================================= - -void DSaveMenu::DoSave (FSaveGameNode *node) -{ - if (node != &NewSaveNode) - { - //G_SaveGame (node->Filename.GetChars(), savegamestring); - } - else - { - // Find an unused filename and save as that - FString filename; - int i; - FILE *test; - - for (i = 0;; ++i) + if (savegameManager.RemoveNewSaveNode()) { - filename = "";// G_BuildSaveName("save", i); - test = fopen (filename, "rb"); - if (test == NULL) - { - break; - } - fclose (test); + Selected--; } - //G_SaveGame (filename, savegamestring); + Super::Destroy(); } - M_ClearMenus(); -} + //============================================================================= + // + // + // + //============================================================================= -//============================================================================= -// -// -// -//============================================================================= + bool MenuEvent (int mkey, bool fromcontroller) override + { + if (Super::MenuEvent(mkey, fromcontroller)) + { + return true; + } + if (Selected == -1) + { + return false; + } -bool DSaveMenu::MenuEvent (int mkey, bool fromcontroller) -{ - if (Super::MenuEvent(mkey, fromcontroller)) - { - return true; - } - if (Selected == -1) - { + if (mkey == MKEY_Enter) + { + FString SavegameString = (Selected != 0)? savegameManager.GetSavegame(Selected)->SaveTitle : FString(); + mInput = new DTextEnterMenu(this, NewConsoleFont, SavegameString, listboxWidth, false, false); + M_ActivateMenu(mInput); + mEntering = true; + } + else if (mkey == MKEY_Input) + { + mEntering = false; + mSaveName = mInput->GetText(); + mInput = nullptr; + } + else if (mkey == MKEY_Abort) + { + mEntering = false; + mInput = nullptr; + } return false; } - if (mkey == MKEY_Enter) - { - if (Selected != 0) - { - savegamestring = SaveGames[Selected]->Title; - } - else - { - savegamestring = ""; - } - DMenu *input = new DTextEnterMenu(this, savegamestring, 1, fromcontroller); - M_ActivateMenu(input); - mEntering = true; - } - else if (mkey == MKEY_Input) - { - mEntering = false; - DoSave(SaveGames[Selected]); - } - else if (mkey == MKEY_Abort) - { - mEntering = false; - } - return false; -} + //============================================================================= + // + // + // + //============================================================================= -//============================================================================= -// -// -// -//============================================================================= - -bool DSaveMenu::Responder (event_t *ev) -{ - if (ev->subtype == EV_GUI_KeyDown) - { - if (Selected != -1) + bool MouseEvent(int type, int x, int y) override { - switch (ev->data1) + if (mSaveName.Len() > 0) { - case GK_DEL: - case '\b': - // cannot delete 'new save game' item - if (Selected == 0) return true; - break; - - case 'N': - Selected = TopItem = 0; - UnloadSaveData (); + // Do not process events when saving is in progress to avoid update of the current index, + // i.e. Selected member variable must remain unchanged return true; } + + return Super::MouseEvent(type, x, y); + } + + //============================================================================= + // + // + // + //============================================================================= + + bool Responder (event_t *ev) override + { + if (ev->subtype == EV_GUI_KeyDown) + { + if (Selected != -1) + { + switch (ev->data1) + { + case GK_DEL: + case '\b': + // cannot delete 'new save game' item + if (Selected == 0) return true; + break; + + case 'N': + Selected = TopItem = 0; + savegameManager.UnloadSaveData(); + return true; + } + } + } + return Super::Responder(ev); + } + + //============================================================================= + // + // + // + //============================================================================= + + void Ticker() override + { + if (mSaveName.Len() > 0) + { + savegameManager.DoSave(Selected, mSaveName); + mSaveName = ""; } } - return Super::Responder(ev); -} + +}; //============================================================================= // @@ -911,59 +594,44 @@ class DLoadMenu : public DLoadSaveMenu public: - DLoadMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); + //============================================================================= + // + // + // + //============================================================================= - bool MenuEvent (int mkey, bool fromcontroller); -}; - -//============================================================================= -// -// -// -//============================================================================= - -DLoadMenu::DLoadMenu(DMenu *parent, FListMenuDescriptor *desc) -: DLoadSaveMenu(parent, desc) -{ - TopItem = 0; - if (LastAccessed != -1) + DLoadMenu() { - Selected = LastAccessed; + TopItem = 0; + Selected = savegameManager.ExtractSaveData(-1); + UpdateSaveComment(); } - ExtractSaveData (Selected); -} + //============================================================================= + // + // + // + //============================================================================= -//============================================================================= -// -// -// -//============================================================================= - -bool DLoadMenu::MenuEvent (int mkey, bool fromcontroller) -{ - if (Super::MenuEvent(mkey, fromcontroller)) - { - return true; - } - if (Selected == -1 || SaveGames.Size() == 0) + bool MenuEvent(int mkey, bool fromcontroller) override { + if (Super::MenuEvent(mkey, fromcontroller)) + { + return true; + } + if (Selected == -1 || savegameManager.SavegameCount() == 0) + { + return false; + } + + if (mkey == MKEY_Enter) + { + savegameManager.LoadSavegame(Selected); + return true; + } return false; } - - if (mkey == MKEY_Enter) - { - //G_LoadGame (SaveGames[Selected]->Filename.GetChars(), true); - if (quickSaveSlot == (FSaveGameNode*)1) - { - quickSaveSlot = SaveGames[Selected]; - } - M_ClearMenus(); - LastAccessed = Selected; - return true; - } - return false; -} +}; static TMenuClassDescriptor _lm("LoadMenu"); static TMenuClassDescriptor _sm("SaveMenu"); diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 051241b92..22328a79e 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -569,6 +569,7 @@ bool M_SetMenu(FName menu, int param, FName caller) */ } Printf("Attempting to open menu of unknown type '%s'\n", menu.GetChars()); + M_ClearMenus(); return false; } @@ -974,7 +975,7 @@ CCMD(opensavemenu) { gi->MenuOpened(); M_StartControlPanel(false); - M_SetMenu(NAME_SaveMenu); + M_SetMenu(NAME_SaveGameMenu); } } @@ -982,5 +983,5 @@ CCMD(openloadmenu) { gi->MenuOpened(); M_StartControlPanel(false); - M_SetMenu(NAME_LoadMenu); + M_SetMenu(NAME_LoadGameMenu); } diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index fdc4590f6..4fed91aff 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -138,18 +138,6 @@ enum ENativeFontValues }; extern FGameStartup GameStartupInfo; - -struct FSaveGameNode -{ - FString Title; - FString Filename; - bool bOldVersion; - bool bMissingWads; - bool bNoDelete; - - FSaveGameNode() { bNoDelete = false; } -}; - extern EMenuState menuactive; @@ -682,29 +670,31 @@ public: class DTextEnterMenu : public DMenu { using Super = DMenu; - TArray mEnterString; - FString* mOutString; - unsigned int mEnterSize; - unsigned int mEnterPos; - int mSizeMode; // 1: size is length in chars. 2: also check string width - bool mInputGridOkay; + FString mEnterString; + int mEnterSize; + int mEnterPos; + bool mInputGridOkay; int InputGridX; int InputGridY; - - // [TP] + int CursorSize; bool AllowColors; + FFont *displayFont; + + + void AppendChar(int ch); public: // [TP] Added allowcolors - DTextEnterMenu(DMenu *parent, FString &textbuffer, int sizemode, bool showgrid, bool allowcolors = false); + DTextEnterMenu(DMenu *parent, FFont *dpf, FString textbuffer, int maxlen, bool showgrid, bool allowcolors = false); void Drawer (); bool MenuEvent (int mkey, bool fromcontroller); bool Responder(event_t *ev); bool TranslateKeyboardEvents(); bool MouseEvent(int type, int x, int y); + const char* GetText() { return mEnterString.GetChars(); } }; @@ -757,4 +747,56 @@ template struct TMenuClassDescriptor : public MenuClassDescriptor } }; + +struct FSaveGameNode +{ + FString SaveTitle; + FString Filename; + bool bOldVersion = false; + bool bMissingWads = false; + bool bNoDelete = false; +}; + +struct FSavegameManager +{ +private: + TArray SaveGames; + FSaveGameNode NewSaveNode; + int LastSaved = -1; + int LastAccessed = -1; + TArray SavePicData; + FTexture *SavePic = nullptr; + +public: + int WindowSize = 0; + FString SaveCommentString; + FSaveGameNode *quickSaveSlot = nullptr; + ~FSavegameManager(); + +private: + int InsertSaveNode(FSaveGameNode *node); +public: + void NotifyNewSave(const FString &file, const FString &title, bool okForQuicksave, bool forceQuicksave); + void ClearSaveGames(); + + void ReadSaveStrings(); + void UnloadSaveData(); + + int RemoveSaveSlot(int index); + void LoadSavegame(int Selected); + void DoSave(int Selected, const char *savegamestring); + unsigned ExtractSaveData(int index); + void ClearSaveStuff(); + bool DrawSavePic(int x, int y, int w, int h); + void DrawSaveComment(FFont *font, int cr, int x, int y, int scalefactor); + void SetFileInfo(int Selected); + unsigned SavegameCount(); + FSaveGameNode *GetSavegame(int i); + void InsertNewSaveNode(); + bool RemoveNewSaveNode(); + +}; + +extern FSavegameManager savegameManager; + #endif diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 5d664e12e..97a9ad20d 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -47,8 +47,6 @@ #include "optionmenuitems.h" -void ClearSaveGames(); - // Menu-relevant content that gets filled in by scripts. This will get processed after the game has loaded. FString gSkillNames[MAXSKILLS]; FString gVolumeNames[MAXVOLUMES]; @@ -94,7 +92,6 @@ static void DeinitMenus() OptionValues.Clear(); DMenu::CurrentMenu = NULL; DefaultListMenuSettings.mItems.Clear(); - ClearSaveGames(); } static FTexture* GetMenuTexture(const char* const name) diff --git a/source/common/menu/menuinput.cpp b/source/common/menu/menuinput.cpp index 2a5b2faff..95185c072 100644 --- a/source/common/menu/menuinput.cpp +++ b/source/common/menu/menuinput.cpp @@ -63,16 +63,13 @@ CVAR(Bool, m_showinputgrid, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) //============================================================================= // [TP] Added allowcolors -DTextEnterMenu::DTextEnterMenu(DMenu *parent, FString &textbuffer, int sizemode, bool showgrid, bool allowcolors) +DTextEnterMenu::DTextEnterMenu(DMenu *parent, FFont *dpf, FString textbuffer, int maxlen, bool showgrid, bool allowcolors) : DMenu(parent) { - mOutString = &textbuffer; - mEnterSize = 32; // this needs to calculate the size based on screen space (or scroll) - mEnterString.Resize(mEnterSize + 1); - mEnterPos = (unsigned)textbuffer.Len(); - mSizeMode = sizemode; - mInputGridOkay = showgrid || m_showinputgrid; - if (mEnterPos > 0) + mEnterString = textbuffer; + mEnterPos = maxlen; + mInputGridOkay = (showgrid && (m_showinputgrid == 0)) || (m_showinputgrid >= 1); + if (mEnterString.Len() > 0) { InputGridX = INPUTGRID_WIDTH - 1; InputGridY = INPUTGRID_HEIGHT - 1; @@ -84,6 +81,8 @@ DTextEnterMenu::DTextEnterMenu(DMenu *parent, FString &textbuffer, int sizemode, InputGridY = 0; } AllowColors = allowcolors; // [TP] + displayFont = dpf; + CursorSize = displayFont->StringWidth(displayFont->GetCursor()); } //============================================================================= @@ -111,12 +110,7 @@ bool DTextEnterMenu::Responder(event_t *ev) if (ev->subtype == EV_GUI_Char) { mInputGridOkay = false; - if (mEnterPos < mEnterSize && - (mSizeMode == 2/*entering player name*/ || (size_t)SmallFont->StringWidth(mEnterString) < (mEnterSize-1)*8)) - { - mEnterString[mEnterPos] = (char)ev->data1; - mEnterString[++mEnterPos] = 0; - } + AppendChar(ev->data1); return true; } char ch = (char)ev->data1; @@ -124,8 +118,7 @@ bool DTextEnterMenu::Responder(event_t *ev) { if (mEnterPos > 0) { - mEnterPos--; - mEnterString[mEnterPos] = 0; + mEnterString.DeleteLastCharacter(); } } else if (ev->subtype == EV_GUI_KeyDown) @@ -133,17 +126,21 @@ bool DTextEnterMenu::Responder(event_t *ev) if (ch == GK_ESCAPE) { DMenu *parent = mParentMenu; - Close(); parent->MenuEvent(MKEY_Abort, false); + Close(); return true; } else if (ch == '\r') { - if (mEnterString[0]) + if (mEnterString.Len() > 0) { + // [TP] If we allow color codes, colorize the string now. + //if (AllowColors) + //mEnterString = mEnterString.Filter(); + DMenu *parent = mParentMenu; - Close(); parent->MenuEvent(MKEY_Input, false); + Close(); return true; } } @@ -164,8 +161,8 @@ bool DTextEnterMenu::Responder(event_t *ev) bool DTextEnterMenu::MouseEvent(int type, int x, int y) { - const int cell_width = 18 * CleanXfac; - const int cell_height = 12 * CleanYfac; + const int cell_width = 18 * CleanXfac_1; + const int cell_height = 16 * CleanYfac_1; const int screen_y = screen->GetHeight() - INPUTGRID_HEIGHT * cell_height; const int screen_x = (screen->GetWidth() - INPUTGRID_WIDTH * cell_width) / 2; @@ -177,11 +174,11 @@ bool DTextEnterMenu::MouseEvent(int type, int x, int y) { if (MenuEvent(MKEY_Enter, true)) { - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); + //M_MenuSound(CursorSound); if (m_use_mouse == 2) InputGridX = InputGridY = -1; - return true; } } + return true; } else { @@ -190,8 +187,21 @@ bool DTextEnterMenu::MouseEvent(int type, int x, int y) return Super::MouseEvent(type, x, y); } +//============================================================================= +// +// +// +//============================================================================= + +void DTextEnterMenu::AppendChar(int ch) +{ + FStringf newstring("%s%c%c", mEnterString.GetChars(), ch, displayFont->GetCursor()); + if (mEnterSize < 0 || displayFont->StringWidth(newstring) < mEnterSize) + { + mEnterString.AppendCharacter(ch); + } +} - //============================================================================= // // @@ -237,9 +247,9 @@ bool DTextEnterMenu::MenuEvent (int key, bool fromcontroller) return true; case MKEY_Clear: - if (mEnterPos > 0) - { - mEnterString[--mEnterPos] = 0; + if (mEnterString.Len() > 0) + { + mEnterString.DeleteLastCharacter(); } return true; @@ -250,26 +260,24 @@ bool DTextEnterMenu::MenuEvent (int key, bool fromcontroller) ch = InputGridChars[InputGridX + InputGridY * INPUTGRID_WIDTH]; if (ch == 0) // end { - if (mEnterString[0] != '\0') + if (mEnterString.Len() > 0) { DMenu *parent = mParentMenu; - Close(); parent->MenuEvent(MKEY_Input, false); + Close(); return true; } } else if (ch == '\b') // bs { - if (mEnterPos > 0) + if (mEnterString.Len() > 0) { - mEnterString[--mEnterPos] = 0; + mEnterString.DeleteLastCharacter(); } } - else if (mEnterPos < mEnterSize && - (mSizeMode == 2/*entering player name*/ || (size_t)SmallFont->StringWidth(mEnterString) < (mEnterSize-1)*8)) + else { - mEnterString[mEnterPos] = ch; - mEnterString[++mEnterPos] = 0; + AppendChar(ch); } } return true; @@ -294,7 +302,7 @@ void DTextEnterMenu::Drawer () { const int cell_width = 18 * CleanXfac; const int cell_height = 12 * CleanYfac; - const int top_padding = cell_height / 2 - SmallFont->GetHeight() * CleanYfac / 2; + const int top_padding = cell_height / 2 - displayFont->GetHeight() * CleanYfac / 2; // Darken the background behind the character grid. // Unless we frame it with a border, I think it looks better to extend the @@ -302,7 +310,7 @@ void DTextEnterMenu::Drawer () twod.AddColorOnlyQuad(0 /*screen->GetWidth()/2 - 13 * cell_width / 2*/, screen->GetHeight() - INPUTGRID_HEIGHT * cell_height, screen->GetWidth() /*13 * cell_width*/, - INPUTGRID_HEIGHT * cell_height, 0xff000000); + INPUTGRID_HEIGHT * cell_height, 0xc8000000); if (InputGridX >= 0 && InputGridY >= 0) { @@ -321,42 +329,42 @@ void DTextEnterMenu::Drawer () int width; const int xx = x * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen->GetWidth() / 2; const int ch = InputGridChars[y * INPUTGRID_WIDTH + x]; - FTexture *pic = SmallFont->GetChar(ch, CR_DARKGRAY, &width); + FTexture *pic = displayFont->GetChar(ch, CR_DARKGRAY, &width); EColorRange color; int remap; // The highlighted character is yellow; the rest are dark gray. color = (x == InputGridX && y == InputGridY) ? CR_YELLOW : CR_DARKGRAY; - remap = SmallFont->GetColorTranslation(color); + remap = displayFont->GetColorTranslation(color); if (pic != NULL) { // Draw a normal character. - DrawTexture(&twod, pic, xx + cell_width/2 - width*CleanXfac/2, yy + top_padding, + DrawTexture(&twod, pic, xx + cell_width/2 - width*CleanXfac_1/2, yy + top_padding, DTA_TranslationIndex, remap, - DTA_CleanNoMove, true, + DTA_CleanNoMove_1, true, TAG_DONE); } else if (ch == ' ') { // Draw the space as a box outline. We also draw it 50% wider than it really is. - const int x1 = xx + cell_width/2 - width * CleanXfac * 3 / 4; - const int x2 = x1 + width * 3 * CleanXfac / 2; + const int x1 = xx + cell_width/2 - width * CleanXfac_1 * 3 / 4; + const int x2 = x1 + width * 3 * CleanXfac_1 / 2; const int y1 = yy + top_padding; - const int y2 = y1 + SmallFont->GetHeight() * CleanYfac; + const int y2 = y1 + displayFont->GetHeight() * CleanYfac_1; auto palcolor = PalEntry(255, 160, 160, 160); - twod.AddColorOnlyQuad(x1, y1, x2, y1+CleanYfac, palcolor); // top - twod.AddColorOnlyQuad(x1, y2, x2, y2+CleanYfac, palcolor); // bottom - twod.AddColorOnlyQuad(x1, y1+CleanYfac, x1+CleanXfac, y2, palcolor); // left - twod.AddColorOnlyQuad(x2-CleanXfac, y1+CleanYfac, x2, y2, palcolor); // right + twod.AddColorOnlyQuad(x1, y1, x2 - x1, CleanYfac_1, palcolor); // top + twod.AddColorOnlyQuad(x1, y2, x2 - x1, CleanYfac_1, palcolor); // bottom + twod.AddColorOnlyQuad(x1, y1+CleanYfac_1, CleanXfac_1, y2 - y1, palcolor); // left + twod.AddColorOnlyQuad(x2-CleanXfac_1, y1+CleanYfac_1, CleanXfac_1, CleanYfac_1, palcolor); // right } else if (ch == '\b' || ch == 0) { // Draw the backspace and end "characters". const char *const str = ch == '\b' ? "BS" : "ED"; - DrawText(&twod, SmallFont, color, - xx + cell_width/2 - SmallFont->StringWidth(str)*CleanXfac/2, - yy + top_padding, str, DTA_CleanNoMove, true, TAG_DONE); + DrawText(&twod, NewSmallFont, color, + xx + cell_width/2 - displayFont->StringWidth(str)*CleanXfac_1/2, + yy + top_padding, str, DTA_CleanNoMove_1, true, TAG_DONE); } } } diff --git a/source/common/menu/savegamemanager.cpp b/source/common/menu/savegamemanager.cpp new file mode 100644 index 000000000..c7a748139 --- /dev/null +++ b/source/common/menu/savegamemanager.cpp @@ -0,0 +1,507 @@ +/* +** loadsavemenu.cpp +** The load game and save game menus +** +**--------------------------------------------------------------------------- +** Copyright 2001-2010 Randy Heit +** Copyright 2010 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "menu/menu.h" +#include "version.h" +#include "m_png.h" +#include "filesystem.h" +#include "v_text.h" +#include "d_event.h" +#include "gstrings.h" +#include "d_gui.h" +#include "v_draw.h" +#include "files.h" +#include "resourcefile.h" +#include "sjson.h" +#include "cmdlib.h" +#include "files.h" +#include "savegamehelp.h" +#include "i_specialpaths.h" +#include "../../platform/win32/i_findfile.h" // This is a temporary direct path. Needs to be fixed when stuff gets cleaned up. + + +FSavegameManager savegameManager; + +//============================================================================= +// +// Save data maintenance +// +//============================================================================= + +void FSavegameManager::ClearSaveGames() +{ + for (unsigned i = 0; ibNoDelete) + delete SaveGames[i]; + } + SaveGames.Clear(); +} + +FSavegameManager::~FSavegameManager() +{ + ClearSaveGames(); +} + +//============================================================================= +// +// Save data maintenance +// +//============================================================================= + +int FSavegameManager::RemoveSaveSlot(int index) +{ + int listindex = SaveGames[0]->bNoDelete ? index - 1 : index; + if (listindex < 0) return index; + + remove(SaveGames[index]->Filename.GetChars()); + UnloadSaveData(); + + FSaveGameNode *file = SaveGames[index]; + + if (quickSaveSlot == SaveGames[index]) + { + quickSaveSlot = nullptr; + } + if (!file->bNoDelete) delete file; + + if (LastSaved == listindex) LastSaved = -1; + else if (LastSaved > listindex) LastSaved--; + if (LastAccessed == listindex) LastAccessed = -1; + else if (LastAccessed > listindex) LastAccessed--; + + SaveGames.Delete(index); + if ((unsigned)index >= SaveGames.Size()) index--; + ExtractSaveData(index); + return index; +} + +//============================================================================= +// +// +// +//============================================================================= + +int FSavegameManager::InsertSaveNode(FSaveGameNode *node) +{ + if (SaveGames.Size() == 0) + { + return SaveGames.Push(node); + } + + if (node->bOldVersion) + { // Add node at bottom of list + return SaveGames.Push(node); + } + else + { // Add node at top of list + unsigned int i; + for (i = 0; i < SaveGames.Size(); i++) + { + if (SaveGames[i]->bOldVersion || node->SaveTitle.CompareNoCase(SaveGames[i]->SaveTitle) <= 0) + { + break; + } + } + SaveGames.Insert(i, node); + return i; + } +} + +//============================================================================= +// +// M_ReadSaveStrings +// +// Find savegames and read their titles +// +//============================================================================= + +void FSavegameManager::ReadSaveStrings() +{ + if (SaveGames.Size() == 0) + { + void *filefirst; + findstate_t c_file; + FString filter; + + LastSaved = LastAccessed = -1; + quickSaveSlot = nullptr; + filter = G_BuildSaveName("*"); + filefirst = I_FindFirst(filter.GetChars(), &c_file); + if (filefirst != ((void *)(-1))) + { + do + { + // I_FindName only returns the file's name and not its full path + FString filepath = G_BuildSaveName(I_FindName(&c_file)); + + FResourceFile *savegame = FResourceFile::OpenResourceFile(filepath, true, true); + if (savegame != nullptr) + { + FResourceLump *info = savegame->FindLump("info.json"); + if (info == nullptr) + { + // savegame info not found. This is not a savegame so leave it alone. + delete savegame; + continue; + } + auto fr = info->NewReader(); + FString title; + int check = G_ValidateSavegame(fr, &title); + delete savegame; + if (check != 0) + { + FSaveGameNode *node = new FSaveGameNode; + node->Filename = filepath; + node->bOldVersion = true; + node->bMissingWads = false; + node->SaveTitle = title; + InsertSaveNode(node); + } + } + } while (I_FindNext (filefirst, &c_file) == 0); + I_FindClose (filefirst); + } + } +} + + +//============================================================================= +// +// +// +//============================================================================= + +void FSavegameManager::NotifyNewSave(const FString &file, const FString &title, bool okForQuicksave, bool forceQuicksave) +{ + FSaveGameNode *node; + + if (file.IsEmpty()) + return; + + ReadSaveStrings(); + + // See if the file is already in our list + for (unsigned i = 0; iFilename.Compare(file) == 0) +#else + if (node->Filename.CompareNoCase(file) == 0) +#endif + { + node->SaveTitle = title; + node->bOldVersion = false; + node->bMissingWads = false; + if (okForQuicksave) + { + if (quickSaveSlot == nullptr || quickSaveSlot == (FSaveGameNode*)1 || forceQuicksave) quickSaveSlot = node; + LastAccessed = LastSaved = i; + } + return; + } + } + + node = new FSaveGameNode; + node->SaveTitle = title; + node->Filename = file; + node->bOldVersion = false; + node->bMissingWads = false; + int index = InsertSaveNode(node); + + if (okForQuicksave) + { + if (quickSaveSlot == nullptr || quickSaveSlot == (FSaveGameNode*)1 || forceQuicksave) quickSaveSlot = node; + LastAccessed = LastSaved = index; + } + else + { + LastAccessed = ++LastSaved; + } +} + +//============================================================================= +// +// Loads the savegame +// +//============================================================================= + +void FSavegameManager::LoadSavegame(int Selected) +{ + //G_LoadGame(SaveGames[Selected]->Filename.GetChars(), true); + if (quickSaveSlot == (FSaveGameNode*)1) + { + quickSaveSlot = SaveGames[Selected]; + } + M_ClearMenus(); + LastAccessed = Selected; +} + + +//============================================================================= +// +// +// +//============================================================================= + +void FSavegameManager::DoSave(int Selected, const char *savegamestring) +{ + if (Selected != 0) + { + auto node = SaveGames[Selected]; + //G_SaveGame(node->Filename.GetChars(), savegamestring); + } + else + { + // Find an unused filename and save as that + FString filename; + int i; + + for (i = 0;; ++i) + { + filename = G_BuildSaveName(FStringf("save%04d", i)); + if (!FileExists(filename)) + { + break; + } + } + //G_SaveGame(filename, savegamestring); + } + M_ClearMenus(); +} + + +//============================================================================= +// +// +// +//============================================================================= + +unsigned FSavegameManager::ExtractSaveData(int index) +{ + FResourceFile *resf; + FSaveGameNode *node; + + if (index == -1) + { + if (SaveGames.Size() > 0 && SaveGames[0]->bNoDelete) + { + index = LastSaved + 1; + } + else + { + index = LastAccessed < 0? 0 : LastAccessed; + } + } + + UnloadSaveData(); + + if ((unsigned)index < SaveGames.Size() && + (node = SaveGames[index]) && + !node->Filename.IsEmpty() && + !node->bOldVersion && + (resf = FResourceFile::OpenResourceFile(node->Filename.GetChars(), true)) != nullptr) + { + FResourceLump *info = resf->FindLump("info.json"); + if (info == nullptr) + { + // this should not happen because the file has already been verified. + return index; + } + auto fr = info->NewReader(); + auto data = fr.ReadPadded(1); + sjson_context* ctx = sjson_create_context(0, 0, NULL); + if (ctx) + { + sjson_node* root = sjson_decode(ctx, (const char*)data.Data()); + + + FString comment = sjson_get_string(root, "Creation Time", ""); + FString pcomment = sjson_get_string(root, "Comment", ""); + if (comment.Len() > 0) comment += "\n"; + comment += pcomment; + SaveCommentString = comment; + + // Extract pic (todo: let the renderer write a proper PNG file instead of a raw canvas dunp of the software renderer - and make it work for all games.) + FResourceLump *pic = resf->FindLump("savepic.png"); + if (pic != nullptr) + { + FileReader picreader; + + picreader.OpenMemoryArray([=](TArray &array) + { + auto cache = pic->Lock(); + array.Resize(pic->LumpSize); + memcpy(&array[0], cache, pic->LumpSize); + pic->Unlock(); + return true; + }); + PNGHandle *png = M_VerifyPNG(picreader); + if (png != nullptr) + { + SavePic = nullptr; // not yet implemented: PNGTexture_CreateFromFile(png, node->Filename); + delete png; + if (SavePic && SavePic->GetWidth() == 1 && SavePic->GetHeight() == 1) + { + delete SavePic; + SavePic = nullptr; + SavePicData.Clear(); + } + } + } + } + delete resf; + } + return index; +} + +//============================================================================= +// +// +// +//============================================================================= + +void FSavegameManager::UnloadSaveData() +{ + if (SavePic != nullptr) + { + delete SavePic; + } + + SaveCommentString = ""; + SavePic = nullptr; + SavePicData.Clear(); +} + +//============================================================================= +// +// +// +//============================================================================= + +void FSavegameManager::ClearSaveStuff() +{ + UnloadSaveData(); + if (quickSaveSlot == (FSaveGameNode*)1) + { + quickSaveSlot = nullptr; + } +} + + +//============================================================================= +// +// +// +//============================================================================= + +bool FSavegameManager::DrawSavePic(int x, int y, int w, int h) +{ + if (SavePic == nullptr) return false; + DrawTexture(&twod, SavePic, x, y, DTA_DestWidth, w, DTA_DestHeight, h, DTA_Masked, false, TAG_DONE); + return true; +} + + +//============================================================================= +// +// +// +//============================================================================= + +void FSavegameManager::SetFileInfo(int Selected) +{ + if (!SaveGames[Selected]->Filename.IsEmpty()) + { + SaveCommentString.Format("File on disk:\n%s", SaveGames[Selected]->Filename.GetChars()); + } +} + + +//============================================================================= +// +// +// +//============================================================================= + +unsigned FSavegameManager::SavegameCount() +{ + return SaveGames.Size(); +} + + +//============================================================================= +// +// +// +//============================================================================= + +FSaveGameNode *FSavegameManager::GetSavegame(int i) +{ + return SaveGames[i]; +} + + +//============================================================================= +// +// +// +//============================================================================= + +void FSavegameManager::InsertNewSaveNode() +{ + NewSaveNode.SaveTitle = GStrings["NEWSAVE"]; + NewSaveNode.bNoDelete = true; + SaveGames.Insert(0, &NewSaveNode); +} + + +//============================================================================= +// +// +// +//============================================================================= + +bool FSavegameManager::RemoveNewSaveNode() +{ + if (SaveGames[0] == &NewSaveNode) + { + SaveGames.Delete(0); + return true; + } + return false; +} + diff --git a/source/common/utility/namedef.h b/source/common/utility/namedef.h index dfb6d7eb4..a6b4ca075 100644 --- a/source/common/utility/namedef.h +++ b/source/common/utility/namedef.h @@ -20,8 +20,8 @@ xx(MainMenu) xx(IngameMenu) xx(HelpMenu) xx(CreditsMenu) -xx(SaveMenu) -xx(LoadMenu) +xx(SaveGameMenu) +xx(LoadGameMenu) xx(SoundMenu) xx(ConfirmPlayerReset) xx(EpisodeMenu) From 79ce4563eb26085587450cbb197310aeb7805d27 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Nov 2019 01:03:14 +0100 Subject: [PATCH 057/203] - fixed game resuming when closing the load and save menus. --- source/duke3d/src/d_menu.cpp | 32 +++++++++++++++++++++++++++++++- source/rr/src/d_menu.cpp | 32 +++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index e7365d722..f5300a734 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -427,6 +427,12 @@ void GameInterface::MenuOpened() totalclock = ototalclock; screenpeek = myconnectindex; } + + auto& gm = g_player[myconnectindex].ps->gm; + if (gm & MODE_GAME) + { + gm |= MODE_MENU; + } } void GameInterface::MenuSound(::GameInterface::EMenuSounds snd) @@ -450,8 +456,32 @@ void GameInterface::MenuSound(::GameInterface::EMenuSounds snd) void GameInterface::MenuClosed() { S_PlaySound(EXITMENUSOUND); - if (!ud.pause_on) + + auto& gm = g_player[myconnectindex].ps->gm; + if (gm & MODE_GAME) + { + if (gm & MODE_MENU) + I_ClearAllInput(); + + // The following lines are here so that you cannot close the menu when no game is running. + gm &= ~MODE_MENU; + + if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + CAMERACLOCK = (int32_t)totalclock; + CAMERADIST = 65536; + + // Reset next-viewscreen-redraw counter. + // XXX: are there any other cases like that in need of handling? + if (g_curViewscreen >= 0) + actor[g_curViewscreen].t_data[0] = (int32_t)totalclock; + } + + G_UpdateScreenArea(); S_PauseSounds(false); + } } bool GameInterface::CanSave() diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index 017c03485..7055bb9a8 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -355,6 +355,12 @@ void GameInterface::MenuOpened() totalclock = ototalclock; screenpeek = myconnectindex; } + + auto& gm = g_player[myconnectindex].ps->gm; + if (gm & MODE_GAME) + { + gm |= MODE_MENU; + } } void GameInterface::MenuSound(::GameInterface::EMenuSounds snd) @@ -378,8 +384,32 @@ void GameInterface::MenuSound(::GameInterface::EMenuSounds snd) void GameInterface::MenuClosed() { S_PlaySound(EXITMENUSOUND); - if (!ud.pause_on) + + auto& gm = g_player[myconnectindex].ps->gm; + if (gm & MODE_GAME) + { + if (gm & MODE_MENU) + I_ClearAllInput(); + + // The following lines are here so that you cannot close the menu when no game is running. + gm &= ~MODE_MENU; + + if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + CAMERACLOCK = (int32_t)totalclock; + CAMERADIST = 65536; + + // Reset next-viewscreen-redraw counter. + // XXX: are there any other cases like that in need of handling? + if (g_curViewscreen >= 0) + actor[g_curViewscreen].t_data[0] = (int32_t)totalclock; + } + + G_UpdateScreenArea(); S_PauseSounds(false); + } } bool GameInterface::CanSave() From d5c3991c2e4a894a48164b761c67d3db5e817186 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Nov 2019 10:03:20 +0100 Subject: [PATCH 058/203] - fixed compile errors in menu code. --- source/common/menu/loadsavemenu.cpp | 2 +- source/common/menu/menu.h | 4 +++- source/common/menu/menudef.cpp | 8 ++++---- source/common/menu/optionmenuitems.h | 3 ++- source/duke3d/src/d_menu.cpp | 2 -- source/rr/src/d_menu.cpp | 1 - 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/source/common/menu/loadsavemenu.cpp b/source/common/menu/loadsavemenu.cpp index f68ab1d25..f3d21487f 100644 --- a/source/common/menu/loadsavemenu.cpp +++ b/source/common/menu/loadsavemenu.cpp @@ -417,7 +417,7 @@ protected: FString EndString; EndString.Format("%s" TEXTCOLOR_WHITE "%s" TEXTCOLOR_NORMAL "?\n\n%s", GStrings("MNU_DELETESG"), manager.GetSavegame(Selected)->SaveTitle.GetChars(), GStrings("PRESSYN")); - M_StartMessage(EndString, 0); + M_StartMessage(EndString, 0, -1); } return true; } diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 2fbdf3511..ee2a40458 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -98,10 +98,12 @@ enum EMenuSounds : int AdvanceSound, BackSound, CloseSound, - PageSound + PageSound, ChangeSound }; +EXTERN_CVAR(Bool, menu_sounds) + struct event_t; class FTexture; class FFont; diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 2faaa6935..63f66dc93 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -879,11 +879,11 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) { sc.MustGetString(); FString label = sc.String; - bool cr = false; + EColorRange cr = OptionSettings.mFontColorHeader; if (sc.CheckString(",")) { sc.MustGetNumber(); - cr = !!sc.Number; + cr = sc.Number? OptionSettings.mFontColorHeader : OptionSettings.mFontColor; // fixme! } FOptionMenuItem *it = new FOptionMenuItemStaticText(label, cr); desc->mItems.Push(it); @@ -898,11 +898,11 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) sc.MustGetStringName(","); sc.MustGetString(); FName action = sc.String; - bool cr = false; + EColorRange cr = OptionSettings.mFontColorHeader; if (sc.CheckString(",")) { sc.MustGetNumber(); - cr = !!sc.Number; + cr = sc.Number ? OptionSettings.mFontColorHeader : OptionSettings.mFontColor; // fixme! } FOptionMenuItem *it = new FOptionMenuItemStaticTextSwitchable(label, label2, action, cr); desc->mItems.Push(it); diff --git a/source/common/menu/optionmenuitems.h b/source/common/menu/optionmenuitems.h index c97e53236..fdabd2e33 100644 --- a/source/common/menu/optionmenuitems.h +++ b/source/common/menu/optionmenuitems.h @@ -34,6 +34,7 @@ #include "v_text.h" #include "v_draw.h" #include "gstrings.h" +#include "v_font.h" void M_DrawConText (int color, int x, int y, const char *str); @@ -901,7 +902,7 @@ public: M_MenuSound(AdvanceSound); mEditName = GetCVarString(); mEntering = true; - DMenu* input = new DTextEnterMenu ( DMenu::CurrentMenu, mEditName, sizeof mEditName, 2, fromcontroller ); + DMenu* input = new DTextEnterMenu(DMenu::CurrentMenu, NewSmallFont, mEditName, 256, fromcontroller ); M_ActivateMenu( input ); return true; } diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index bafc2ffef..33b3b0c3c 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -507,8 +507,6 @@ void GameInterface::CustomMenuSelection(int menu, int item) VM_OnEventWithReturn(EVENT_NEWGAMECUSTOM, -1, myconnectindex, menu); } -EXTERN_CVAR(Bool, menu_sounds) - void GameInterface::StartGame(FGameStartup& gs) { int32_t skillsound = PISTOL_BODYHIT; diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index 3913dc466..6800fefe1 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -426,7 +426,6 @@ bool GameInterface::CanSave() return true; } -EXTERN_CVAR(Bool, menu_sounds) void GameInterface::StartGame(FGameStartup& gs) { int32_t skillsound = PISTOL_BODYHIT; From 9cb6c652232f3b8b0c4c627901f552f58a32bc49 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Nov 2019 10:07:25 +0100 Subject: [PATCH 059/203] - fixed errors in SW merge. --- source/sw/src/game.cpp | 19 +++++++++---------- source/sw/src/menus.cpp | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 663283f78..10aad2398 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -94,6 +94,7 @@ Things required to make savegames work: #include "gameconfigfile.h" #include "printf.h" #include "m_argv.h" +#include "debugbreak.h" //#include "crc32.h" @@ -3355,7 +3356,7 @@ SWBOOL DoQuickSave(short save_num) SWBOOL DoQuickLoad() { - KB_ClearKeysDown(); + inputState.ClearKeysDown(); PauseAction(); @@ -3474,16 +3475,14 @@ FunctionKeys(PLAYERp pp) inputState.ClearKeyStatus(KEYSC_F6); if (!TEST(pp->Flags, PF_DEAD)) { - inputState.SetKeyStatus(sc_Escape); if (QuickLoadNum < 0) { - KEY_PRESSED(KEYSC_ESC) = 1; - ControlPanelType = ct_savemenu; + inputState.SetKeyStatus(sc_Escape); + ControlPanelType = ct_savemenu; } else { - KB_ClearKeysDown(); - KB_FlushKeyboardQueue(); + inputState.ClearAllInput(); DoQuickSave(QuickLoadNum); ResumeAction(); } @@ -3499,8 +3498,8 @@ FunctionKeys(PLAYERp pp) { if (QuickLoadNum < 0) { - KEY_PRESSED(KEYSC_ESC) = 1; - ControlPanelType = ct_loadmenu; + inputState.SetKeyStatus(sc_Escape); + ControlPanelType = ct_loadmenu; } else { @@ -4296,9 +4295,9 @@ void getinput(SW_PACKET *loc) SET(loc->bits, prev_weapon + 1); } - if (buttonMap.ButtonDown(gamefunc_Alt_Weapon_Mode)) + if (buttonMap.ButtonDown(gamefunc_Alt_Weapon)) { - buttonMap.ClearButton(gamefunc_Alt_Weapon_Mode); + buttonMap.ClearButton(gamefunc_Alt_Weapon); USERp u = User[pp->PlayerSprite]; short const which_weapon = u->WeaponNum + 1; SET(loc->bits, which_weapon); diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index 9dafae9ec..faac75f1f 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -882,7 +882,7 @@ static int MNU_SelectButtonFunction(const char *buttonname, int *currentfunc) else if (I_MenuDown()) { I_MenuDownClear(); - *currentfunc = min(NUMGAMEFUNCTIONS, *currentfunc + 1); + *currentfunc = std::min(NUMGAMEFUNCTIONS, *currentfunc + 1); } From 2a9e4fca4691d9226b2952a4e22eac340c0d5a1c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Nov 2019 19:23:54 +0100 Subject: [PATCH 060/203] WIP safety commit --- source/blood/src/blood.cpp | 55 --- source/blood/src/menu.cpp | 44 -- source/blood/src/menu.h | 4 - source/blood/src/osdcmd.cpp | 19 - source/build/include/baselayer.h | 20 +- source/build/src/engine.cpp | 2 +- source/common/console/c_buttons.cpp | 2 - source/common/console/c_buttons.h | 2 - source/common/menu/menu.cpp | 16 +- source/common/menu/menu.h | 18 +- source/common/menu/messagebox.cpp | 32 +- source/common/menu/savegamemanager.cpp | 598 ++++++++++++++++++++++++- source/common/savegamehelp.h | 1 + source/common/utility/cmdlib.cpp | 27 ++ source/common/utility/cmdlib.h | 1 + source/duke3d/src/duke3d.h | 2 + source/duke3d/src/game.cpp | 65 +-- source/duke3d/src/gameexec.cpp | 46 +- source/duke3d/src/gamevars.cpp | 4 +- source/duke3d/src/menus.cpp | 6 - source/duke3d/src/osdcmds.cpp | 21 - source/duke3d/src/premap.cpp | 5 - source/duke3d/src/savegame.cpp | 93 ++-- source/duke3d/src/savegame.h | 59 +-- source/rr/src/duke3d.h | 2 + source/rr/src/game.cpp | 80 +--- source/rr/src/gameexec.cpp | 2 + source/rr/src/menus.cpp | 11 - source/rr/src/osdcmds.cpp | 21 - source/rr/src/premap.cpp | 6 +- source/rr/src/savegame.cpp | 91 +--- source/rr/src/savegame.h | 59 +-- source/sw/src/game.cpp | 79 +--- source/sw/src/game.h | 3 - source/sw/src/menus.cpp | 175 +------- source/sw/src/menus.h | 1 - source/sw/src/player.cpp | 3 +- 37 files changed, 772 insertions(+), 903 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 44cc1c255..9f7320fb4 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -762,38 +762,6 @@ void StartNetworkLevel(void) int gDoQuickSave = 0; -static void DoQuickLoad(void) -{ - if (!gGameMenuMgr.m_bActive) - { - if (gQuickLoadSlot != -1) - { - QuickLoadGame(); - return; - } - if (gQuickLoadSlot == -1 && gQuickSaveSlot != -1) - { - gQuickLoadSlot = gQuickSaveSlot; - QuickLoadGame(); - return; - } - gGameMenuMgr.Push(&menuLoadGame,-1); - } -} - -static void DoQuickSave(void) -{ - if (gGameStarted && !gGameMenuMgr.m_bActive && gPlayer[myconnectindex].pXSprite->health != 0) - { - if (gQuickSaveSlot != -1) - { - QuickSaveGame(); - return; - } - gGameMenuMgr.Push(&menuSaveGame,-1); - } -} - void LocalKeys(void) { bool alt = inputState.AltPressed(); @@ -831,21 +799,6 @@ void LocalKeys(void) gView = &gPlayer[gViewIndex]; } } - if (gDoQuickSave) - { - inputState.keyFlushScans(); - switch (gDoQuickSave) - { - case 1: - DoQuickSave(); - break; - case 2: - DoQuickLoad(); - break; - } - gDoQuickSave = 0; - return; - } char key; if ((key = inputState.keyGetScan()) != 0) { @@ -914,19 +867,11 @@ void LocalKeys(void) if (!gGameMenuMgr.m_bActive) gGameMenuMgr.Push(&menuOptions,-1); return; - case sc_F6: - inputState.keyFlushScans(); - DoQuickSave(); - break; case sc_F8: inputState.keyFlushScans(); if (!gGameMenuMgr.m_bActive) gGameMenuMgr.Push(&menuOptionsDisplayMode, -1); return; - case sc_F9: - inputState.keyFlushScans(); - DoQuickLoad(); - break; case sc_F10: inputState.keyFlushScans(); if (!gGameMenuMgr.m_bActive) diff --git a/source/blood/src/menu.cpp b/source/blood/src/menu.cpp index 1967628d1..7cf24fd38 100644 --- a/source/blood/src/menu.cpp +++ b/source/blood/src/menu.cpp @@ -2055,9 +2055,6 @@ void TenProcess(CGameMenuItem7EA1C *pItem) UNREFERENCED_PARAMETER(pItem); } -short gQuickLoadSlot = -1; -short gQuickSaveSlot = -1; - void SaveGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event) { int nSlot = pItem->at28; @@ -2077,31 +2074,6 @@ void SaveGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event) videoNextPage(); gSaveGameNum = nSlot; LoadSave::SaveGame(strSaveGameName.GetChars()); - gQuickSaveSlot = nSlot; - gGameMenuMgr.Deactivate(); -} - -void QuickSaveGame(void) -{ - if (gGameOptions.nGameType > 0 || !gGameStarted) - return; - /*if (strSaveGameName[0]) - { - gGameMenuMgr.Deactivate(); - return; - }*/ - FStringf basename("save%04d", gQuickSaveSlot); - auto strSaveGameName = G_BuildSaveName(basename); - - strcpy(gGameOptions.szUserGameName, strRestoreGameStrings[gQuickSaveSlot]); - sprintf(gGameOptions.szSaveGameName, "%s", strSaveGameName.GetChars()); - gGameOptions.nSaveGameSlot = gQuickSaveSlot; - viewLoadingScreen(2518, "Saving", "Saving Your Game", strRestoreGameStrings[gQuickSaveSlot]); - videoNextPage(); - LoadSave::SaveGame(strSaveGameName); - gGameOptions.picEntry = gSavedOffset; - gSaveGameOptions[gQuickSaveSlot] = gGameOptions; - UpdateSavedInfo(gQuickSaveSlot); gGameMenuMgr.Deactivate(); } @@ -2119,22 +2091,6 @@ void LoadGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event) videoNextPage(); LoadSave::LoadGame(strLoadGameName); gGameMenuMgr.Deactivate(); - gQuickLoadSlot = nSlot; -} - -void QuickLoadGame(void) -{ - - if (gGameOptions.nGameType > 0) - return; - FStringf basename("save%04d", gQuickSaveSlot); - auto strLoadGameName = G_BuildSaveName(basename); - if (!FileExists(strLoadGameName)) - return; - viewLoadingScreen(2518, "Loading", "Loading Saved Game", strRestoreGameStrings[gQuickLoadSlot]); - videoNextPage(); - LoadSave::LoadGame(strLoadGameName); - gGameMenuMgr.Deactivate(); } void SetupLevelMenuItem(int nEpisode) diff --git a/source/blood/src/menu.h b/source/blood/src/menu.h index 786095574..3654f9d7a 100644 --- a/source/blood/src/menu.h +++ b/source/blood/src/menu.h @@ -51,13 +51,9 @@ extern CGameMenu menuSorry2; extern CGameMenu menuOptions; extern CGameMenu menuOptionsSound; extern CGameMenu menuOptionsDisplayMode; -extern short gQuickLoadSlot; -extern short gQuickSaveSlot; extern char strRestoreGameStrings[][16]; void drawLoadingScreen(void); void SetupMenus(void); void UpdateNetworkMenus(void); -void QuickSaveGame(void); -void QuickLoadGame(void); END_BLD_NS diff --git a/source/blood/src/osdcmd.cpp b/source/blood/src/osdcmd.cpp index 8b53f0c6b..5998ad2ab 100644 --- a/source/blood/src/osdcmd.cpp +++ b/source/blood/src/osdcmd.cpp @@ -371,23 +371,6 @@ void onvideomodechange(int32_t newmode) UpdateDacs(gLastPal, false); } -static int osdcmd_quicksave(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_CONST_PARAMETER(parm); - if (!gGameStarted || gDemo.at1 || gGameMenuMgr.m_bActive) - OSD_Printf("quicksave: not in a game.\n"); - else gDoQuickSave = 1; - return OSDCMD_OK; -} - -static int osdcmd_quickload(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_CONST_PARAMETER(parm); - if (!gGameStarted || gDemo.at1 || gGameMenuMgr.m_bActive) - OSD_Printf("quickload: not in a game.\n"); - else gDoQuickSave = 2; - return OSDCMD_OK; -} #if 0 @@ -435,8 +418,6 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("give","give : gives requested item", osdcmd_give); OSD_RegisterFunction("god","god: toggles god mode", osdcmd_god); OSD_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); - OSD_RegisterFunction("quicksave","quicksave: performs a quick save", osdcmd_quicksave); - OSD_RegisterFunction("quickload","quickload: performs a quick load", osdcmd_quickload); OSD_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound); OSD_RegisterFunction("vidmode","vidmode : change the video mode",osdcmd_vidmode); diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 3525930ba..2e5449598 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -185,6 +185,22 @@ struct FSavegameInfo int currentsavever; }; +struct FSaveGameNode +{ + FString SaveTitle; + FString Filename; + bool bOldVersion = false; + bool bMissingWads = false; + bool bNoDelete = false; + bool bIsExt = false; + + bool isValid() const + { + return Filename.IsNotEmpty() && !bOldVersion && !bMissingWads; + } +}; + + enum EMenuSounds : int; struct GameInterface @@ -210,8 +226,8 @@ struct GameInterface virtual bool DrawSpecialScreen(const DVector2 &origin, int tilenum) { return false; } virtual void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) {} virtual void DrawMenuCaption(const DVector2& origin, const char* text) {} - - + virtual bool SaveGame(FSaveGameNode*) { return false; } + virtual bool LoadGame(FSaveGameNode*) { return false; } }; extern GameInterface* gi; diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index ae2e4478c..cb1f66678 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -10045,7 +10045,7 @@ void videoNextPage(void) if (!recursion) { - // This protection is needed because the menu can call scripts and the scripts can call the busy-looping Screen_Play script event + // This protection is needed because the menu can call scripts from inside its drawers and the scripts can call the busy-looping Screen_Play script event // which calls videoNextPage for page flipping again. In this loop the UI drawers may not get called again. // Ideally this stuff should be moved out of videoNextPage so that all those busy loops won't call UI overlays at all. recursion = true; diff --git a/source/common/console/c_buttons.cpp b/source/common/console/c_buttons.cpp index 0d9cbb2c7..cf2c2ba67 100644 --- a/source/common/console/c_buttons.cpp +++ b/source/common/console/c_buttons.cpp @@ -106,8 +106,6 @@ static const ButtonDesc gamefuncs[] = { { gamefunc_Dpad_Aiming, "Dpad_Aiming"}, { gamefunc_AutoRun, "AutoRun"}, { gamefunc_Last_Weapon, "Last_Used_Weapon"}, - { gamefunc_Quick_Save, "Quick_Save"}, - { gamefunc_Quick_Load, "Quick_Load"}, { gamefunc_Alt_Weapon, "Alt_Weapon"}, { gamefunc_Third_Person_View, "Third_Person_View"}, { gamefunc_Toggle_Crouch, "Toggle_Crouch"}, diff --git a/source/common/console/c_buttons.h b/source/common/console/c_buttons.h index 943c49a25..3a4746673 100644 --- a/source/common/console/c_buttons.h +++ b/source/common/console/c_buttons.h @@ -72,8 +72,6 @@ enum GameFunction_t gamefunc_Dpad_Aiming, gamefunc_AutoRun, gamefunc_Last_Weapon, - gamefunc_Quick_Save, - gamefunc_Quick_Load, gamefunc_Alt_Weapon, gamefunc_Third_Person_View, gamefunc_See_Chase_View = gamefunc_Third_Person_View, // this was added by Blood diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 700c528d2..e16d7634c 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -360,6 +360,9 @@ void M_StartControlPanel (bool makeSound) created = true; M_CreateMenus(); } + FX_StopAllSounds(); + gi->MenuOpened(); + if (makeSound) gi->MenuSound(ActivateSound); buttonMap.ResetButtonStates (); inputState.ClearAllKeyStatus(); @@ -964,10 +967,8 @@ CCMD(reset2saved) CCMD(openmainmenu) { - FX_StopAllSounds(); //gi->ClearSoundLocks(); - //gi->MenuSound(); - M_StartControlPanel(false); + M_StartControlPanel(true); M_SetMenu(NAME_IngameMenu); } @@ -975,8 +976,7 @@ CCMD(openhelpmenu) { if (!help_disabled) { - gi->MenuOpened(); - M_StartControlPanel(false); + M_StartControlPanel(true); M_SetMenu(NAME_HelpMenu); } } @@ -985,15 +985,13 @@ CCMD(opensavemenu) { if (gi->CanSave()) { - gi->MenuOpened(); - M_StartControlPanel(false); + M_StartControlPanel(true); M_SetMenu(NAME_SaveGameMenu); } } CCMD(openloadmenu) { - gi->MenuOpened(); - M_StartControlPanel(false); + M_StartControlPanel(true); M_SetMenu(NAME_LoadGameMenu); } diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index ee2a40458..035cda2c6 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -94,6 +94,7 @@ enum EMenuState : int enum EMenuSounds : int { + ActivateSound, CursorSound, AdvanceSound, BackSound, @@ -742,6 +743,7 @@ void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave); void M_StartMessage(const char *message, int messagemode, int scriptId, FName action = NAME_None); void M_UnhideCustomMenu(int menu, int itemmask); void M_MenuSound(EMenuSounds snd); +void M_Autosave(); void I_SetMouseCapture(); @@ -750,6 +752,10 @@ void I_ReleaseMouseCapture(); struct MenuClassDescriptor; extern TArray menuClasses; +using hFunc = std::function; +DMenu* CreateMessageBoxMenu(DMenu* parent, const char* message, int messagemode, int scriptID, bool playsound, FName action = NAME_None, hFunc handler = nullptr); + + struct MenuClassDescriptor { FName mName; @@ -772,15 +778,6 @@ template struct TMenuClassDescriptor : public MenuClassDescriptor }; -struct FSaveGameNode -{ - FString SaveTitle; - FString Filename; - bool bOldVersion = false; - bool bMissingWads = false; - bool bNoDelete = false; -}; - struct FSavegameManager { private: @@ -819,6 +816,9 @@ public: void InsertNewSaveNode(); bool RemoveNewSaveNode(); + void LoadGame(FSaveGameNode* node, bool ok4q, bool forceq); + void SaveGame(FSaveGameNode* node); + }; extern FSavegameManager savegameManager; diff --git a/source/common/menu/messagebox.cpp b/source/common/menu/messagebox.cpp index b299f62df..d0e75cd5d 100644 --- a/source/common/menu/messagebox.cpp +++ b/source/common/menu/messagebox.cpp @@ -32,7 +32,7 @@ ** */ -#include "menu/menu.h" +#include "menu.h" #include "d_event.h" #include "d_gui.h" #include "v_text.h" @@ -41,7 +41,6 @@ #include "c_dispatch.h" #include "v_2ddrawer.h" - extern FSaveGameNode *quickSaveSlot; class DMessageBoxMenu : public DMenu @@ -52,10 +51,11 @@ class DMessageBoxMenu : public DMenu int messageSelection; int mMouseLeft, mMouseRight, mMouseY; FName mAction; + std::function mActionFunc; public: - DMessageBoxMenu(DMenu *parent = NULL, const char *message = NULL, int messagemode = 0, bool playsound = false, FName action = NAME_None); + DMessageBoxMenu(DMenu *parent = NULL, const char *message = NULL, int messagemode = 0, bool playsound = false, FName action = NAME_None, hFunc handler = nullptr); void Destroy(); void Init(DMenu *parent, const char *message, int messagemode, bool playsound = false); void Drawer(); @@ -73,10 +73,11 @@ public: // //============================================================================= -DMessageBoxMenu::DMessageBoxMenu(DMenu *parent, const char *message, int messagemode, bool playsound, FName action) +DMessageBoxMenu::DMessageBoxMenu(DMenu *parent, const char *message, int messagemode, bool playsound, FName action, hFunc handler) : DMenu(parent) { mAction = action; + mActionFunc = handler; messageSelection = 0; mMouseLeft = 140; mMouseY = INT_MIN; @@ -128,7 +129,7 @@ void DMessageBoxMenu::Destroy() void DMessageBoxMenu::CloseSound() { - //S_Sound (CHAN_VOICE | CHAN_UI, DMenu::CurrentMenu != NULL? "menu/backup" : "menu/dismiss", snd_menuvolume, ATTN_NONE); + M_MenuSound(DMenu::CurrentMenu ? BackSound : ::CloseSound); } //============================================================================= @@ -143,7 +144,12 @@ void DMessageBoxMenu::HandleResult(bool res) { if (mMessageMode == 0) { - if (mAction == NAME_None) + if (mActionFunc) + { + mActionFunc(res); + Close(); + } + else if (mAction == NAME_None) { mParentMenu->MenuEvent(res? MKEY_MBYes : MKEY_MBNo, false); Close(); @@ -358,3 +364,17 @@ void M_StartMessage(const char *message, int messagemode, int scriptId, FName ac M_ActivateMenu(newmenu); } + +//============================================================================= +// +// +// +//============================================================================= + +DMenu* CreateMessageBoxMenu(DMenu* parent, const char* message, int messagemode, int scriptId, bool playsound, FName action = NAME_None, hFunc handler) +{ + auto newmenu = new DMessageBoxMenu(DMenu::CurrentMenu, message, messagemode, false, action, handler); + newmenu->scriptID = scriptId; + return newmenu; + +} diff --git a/source/common/menu/savegamemanager.cpp b/source/common/menu/savegamemanager.cpp index c7a748139..7a8b4ae67 100644 --- a/source/common/menu/savegamemanager.cpp +++ b/source/common/menu/savegamemanager.cpp @@ -49,11 +49,27 @@ #include "files.h" #include "savegamehelp.h" #include "i_specialpaths.h" +#include "c_dispatch.h" #include "../../platform/win32/i_findfile.h" // This is a temporary direct path. Needs to be fixed when stuff gets cleaned up. FSavegameManager savegameManager; +void FSavegameManager::LoadGame(FSaveGameNode* node, bool ok4q, bool forceq) +{ + if (gi->LoadGame(node)) + { + FString fn = node->Filename; + FString desc = node->SaveTitle; + NotifyNewSave(fn, desc, ok4q, forceq); + } +} + +void FSavegameManager::SaveGame(FSaveGameNode* node) +{ + gi->SaveGame(node); +} + //============================================================================= // // Save data maintenance @@ -261,7 +277,7 @@ void FSavegameManager::NotifyNewSave(const FString &file, const FString &title, void FSavegameManager::LoadSavegame(int Selected) { - //G_LoadGame(SaveGames[Selected]->Filename.GetChars(), true); + savegameManager.LoadGame(SaveGames[Selected]); if (quickSaveSlot == (FSaveGameNode*)1) { quickSaveSlot = SaveGames[Selected]; @@ -281,8 +297,9 @@ void FSavegameManager::DoSave(int Selected, const char *savegamestring) { if (Selected != 0) { - auto node = SaveGames[Selected]; - //G_SaveGame(node->Filename.GetChars(), savegamestring); + auto node = *SaveGames[Selected]; + node.SaveTitle = savegamestring; + savegameManager.SaveGame(&node); } else { @@ -298,7 +315,8 @@ void FSavegameManager::DoSave(int Selected, const char *savegamestring) break; } } - //G_SaveGame(filename, savegamestring); + FSaveGameNode sg{ savegamestring, filename }; + savegameManager.SaveGame(&sg); } M_ClearMenus(); } @@ -505,3 +523,575 @@ bool FSavegameManager::RemoveNewSaveNode() return false; } +//============================================================================= +// +// +// +//============================================================================= + +CVAR(Bool, saveloadconfirmation, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) + +CVAR(Int, autosavenum, 0, CVAR_NOSET | CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +static int nextautosave = -1; +CVAR(Int, disableautosave, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CUSTOM_CVAR(Int, autosavecount, 4, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (self < 1) + self = 1; +} + +CVAR(Int, quicksavenum, 0, CVAR_NOSET | CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +static int nextquicksave = -1; + CUSTOM_CVAR(Int, quicksavecount, 4, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (self < 1) + self = 1; +} + +void M_Autosave() +{ + if (!gi->CanSave()) return; + FString description; + FString file; + // Keep a rotating sets of autosaves + UCVarValue num; + const char* readableTime; + int count = autosavecount != 0 ? autosavecount : 1; + + if (nextautosave == -1) + { + nextautosave = (autosavenum + 1) % count; + } + + num.Int = nextautosave; + autosavenum.ForceSet(num, CVAR_Int); + + FSaveGameNode sg; + sg.Filename = G_BuildSaveName(FStringf("auto%04d", nextautosave)); + readableTime = myasctime(); + sg.SaveTitle.Format("Autosave %s", readableTime); + nextautosave = (nextautosave + 1) % count; + savegameManager.SaveGame(&sg); +} + +CCMD(autosave) +{ + if (disableautosave) return; + M_Autosave(); +} + +CCMD(rotatingquicksave) +{ + if (!gi->CanSave()) return; + FString description; + FString file; + // Keep a rotating sets of quicksaves + UCVarValue num; + const char* readableTime; + int count = quicksavecount != 0 ? quicksavecount : 1; + + if (nextquicksave == -1) + { + nextquicksave = (quicksavenum + 1) % count; + } + + num.Int = nextquicksave; + quicksavenum.ForceSet(num, CVAR_Int); + + FSaveGameNode sg; + sg.Filename = G_BuildSaveName(FStringf("quick%04d", nextquicksave)); + readableTime = myasctime(); + sg.SaveTitle.Format("Quicksave %s", readableTime); + nextquicksave = (nextquicksave + 1) % count; + savegameManager.SaveGame(&sg); +} + + +//============================================================================= +// +// +// +//============================================================================= + +CCMD(quicksave) +{ // F6 + if (!gi->CanSave()) return; + + if (savegameManager.quickSaveSlot == NULL || savegameManager.quickSaveSlot == (FSaveGameNode*)1) + { + M_StartControlPanel(true); + M_SetMenu(NAME_SaveGameMenu); + return; + } + + auto slot = savegameManager.quickSaveSlot; + + // [mxd]. Just save the game, no questions asked. + if (!saveloadconfirmation) + { + savegameManager.SaveGame(savegameManager.quickSaveSlot); + return; + } + + gi->MenuSound(ActivateSound); + + FString tempstring = GStrings("QSPROMPT"); + tempstring.Substitute("%s", slot->SaveTitle.GetChars()); + + DMenu* newmenu = CreateMessageBoxMenu(DMenu::CurrentMenu, tempstring, 0, INT_MAX, false, NAME_None, [](bool res) + { + if (res) + { + savegameManager.SaveGame(savegameManager.quickSaveSlot); + } + }); + + M_ActivateMenu(newmenu); +} + +//============================================================================= +// +// +// +//============================================================================= + +CCMD(quickload) +{ // F9 +#if 0 + if (netgame) + { + M_StartControlPanel(true); + M_StartMessage(GStrings("QLOADNET"), 1); + return; + } +#endif + + if (savegameManager.quickSaveSlot == nullptr || savegameManager.quickSaveSlot == (FSaveGameNode*)1) + { + M_StartControlPanel(true); + // signal that whatever gets loaded should be the new quicksave + savegameManager.quickSaveSlot = (FSaveGameNode*)1; + M_SetMenu(NAME_LoadGameMenu); + return; + } + + // [mxd]. Just load the game, no questions asked. + if (!saveloadconfirmation) + { + savegameManager.LoadGame(savegameManager.quickSaveSlot); + return; + } + FString tempstring = GStrings("QLPROMPT"); + tempstring.Substitute("%s", savegameManager.quickSaveSlot->SaveTitle.GetChars()); + + M_StartControlPanel(true); + + DMenu* newmenu = CreateMessageBoxMenu(DMenu::CurrentMenu, tempstring, 0, INT_MAX, false, NAME_None, [](bool res) + { + if (res) + { + savegameManager.LoadGame(savegameManager.quickSaveSlot); + } + }); + M_ActivateMenu(newmenu); +} + +#if 0 + +// Duke +if ((buttonMap.ButtonDown(gamefunc_Quick_Load) || g_doQuickSave == 2) && (myplayer.gm & MODE_GAME)) +{ + buttonMap.ClearButton(gamefunc_Quick_Load); + + g_doQuickSave = 0; + + if (g_quickload == nullptr || !g_quickload->isValid()) + { + C_DoCommand("openloadmenu"); + } + else if (g_quickload->isValid()) + { + inputState.keyFlushChars(); + inputState.ClearKeysDown(); + if (G_LoadPlayerMaybeMulti(*g_quickload) != 0) + g_quickload->reset(); + } +} + +if ((buttonMap.ButtonDown(gamefunc_Quick_Save) || g_doQuickSave == 1) && (myplayer.gm & MODE_GAME)) +{ + buttonMap.ClearButton(gamefunc_Quick_Save); + + g_doQuickSave = 0; + + if (!g_lastusersave.isValid()) + { + C_DoCommand("opensavemenu"); + return; + } + inputState.keyFlushChars(); + + if (sprite[myplayer.i].extra <= 0) + { + P_DoQuote(QUOTE_SAVE_DEAD, &myplayer); + return; + } + + g_screenCapture = 1; + G_DrawRooms(myconnectindex, 65536); + g_screenCapture = 0; + + if (g_lastusersave.isValid()) + { + savebrief_t& sv = g_lastusersave; + + // dirty hack... char 127 in last position indicates an auto-filled name + if (sv.name[MAXSAVEGAMENAME] == 127) + { + strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME); + sv.name[MAXSAVEGAMENAME] = 127; + } + + g_quickload = &sv; + G_SavePlayerMaybeMulti(sv); + } + } + + +// handle CON_SAVE and CON_SAVENN +if (g_saveRequested) +{ + inputState.keyFlushChars(); + videoNextPage(); + + g_screenCapture = 1; + G_DrawRooms(myconnectindex, 65536); + g_screenCapture = 0; + + G_SavePlayerMaybeMulti(g_lastautosave, true); + g_quickload = &g_lastautosave; + + OSD_Printf("Saved: %s\n", g_lastautosave.path); + + g_saveRequested = false; +} + + +// RR + +if ((buttonMap.ButtonDown(gamefunc_Quick_Load) || g_doQuickSave == 2) && (!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && (g_player[myconnectindex].ps->gm & MODE_GAME)) +{ + buttonMap.ClearButton(gamefunc_Quick_Load); + + g_doQuickSave = 0; + + if (g_quickload == nullptr || !g_quickload->isValid()) + { + C_DoCommand("openloadmenu"); + } + else if (g_quickload->isValid()) + { + inputState.keyFlushChars(); + inputState.ClearKeysDown(); + S_PauseSounds(true); + if (G_LoadPlayerMaybeMulti(*g_quickload) != 0) + g_quickload->reset(); + } +} + +if ((buttonMap.ButtonDown(gamefunc_Quick_Save) || g_doQuickSave == 1) && (!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && (g_player[myconnectindex].ps->gm & MODE_GAME)) +{ + buttonMap.ClearButton(gamefunc_Quick_Save); + + g_doQuickSave = 0; + + if (!g_lastusersave.isValid()) + { + C_DoCommand("opensavemenu"); + return; + } + + inputState.keyFlushChars(); + + if (sprite[g_player[myconnectindex].ps->i].extra <= 0) + { + P_DoQuote(QUOTE_SAVE_DEAD, g_player[myconnectindex].ps); + return; + } + + g_screenCapture = 1; + G_DrawRooms(myconnectindex, 65536); + g_screenCapture = 0; + + if (g_lastusersave.isValid()) + { + savebrief_t& sv = g_lastusersave; + + // dirty hack... char 127 in last position indicates an auto-filled name + if (sv.name[MAXSAVEGAMENAME] == 127) + { + strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME); + sv.name[MAXSAVEGAMENAME] = 127; + } + + g_quickload = &sv; + G_SavePlayerMaybeMulti(sv); + } +} + +// sw + +SWBOOL DoQuickSave(short save_num) +{ + PauseAction(); + + if (SaveGame(save_num) != -1) + { + QuickLoadNum = save_num; + + LastSaveNum = -1; + + return FALSE; + } + + return TRUE; +} + +SWBOOL DoQuickLoad() +{ + inputState.ClearKeysDown(); + + PauseAction(); + + ReloadPrompt = FALSE; + if (LoadGame(QuickLoadNum) == -1) + { + return FALSE; + } + + ready2send = 1; + LastSaveNum = -1; + + return TRUE; +} + + +// F6 quick save +if (inputState.GetKeyStatus(KEYSC_F6)) +{ + inputState.ClearKeyStatus(KEYSC_F6); + if (!TEST(pp->Flags, PF_DEAD)) + { + if (QuickLoadNum < 0) + { + inputState.SetKeyStatus(sc_Escape); + ControlPanelType = ct_savemenu; + } + else + { + inputState.ClearAllInput(); + DoQuickSave(QuickLoadNum); + ResumeAction(); + } + } +} + +// F9 quick load +if (inputState.GetKeyStatus(KEYSC_F9)) +{ + inputState.ClearKeyStatus(KEYSC_F9); + + if (!TEST(pp->Flags, PF_DEAD)) + { + if (QuickLoadNum < 0) + { + inputState.SetKeyStatus(sc_Escape); + ControlPanelType = ct_loadmenu; + } + else + { + DoQuickLoad(); + ResumeAction(); + } + } +} + +//////////////////////////////////////////////// +// Load Game menu +// This function gets called whenever you +// press enter on one of the load game +// spots. +// I'm figuring it need to do the following: +// . Load the game if there is one by calling: MNU_LoadGameCustom. +//////////////////////////////////////////////// +SWBOOL MNU_GetLoadCustom(void) +{ + short load_num; + + load_num = currentmenu->cursor; + + // no saved game exists - don't do anything + if (SaveGameDescr[load_num][0] == '\0') + return FALSE; + + if (InMenuLevel || DemoMode || DemoPlaying) + { + LoadSaveMsg("Loading..."); + + if (LoadGame(load_num) == -1) + return FALSE; + + QuickLoadNum = load_num; + // the (Quick)Save menu should default to the last loaded game + SaveGameGroup.cursor = load_num; + + ExitMenus(); + ExitLevel = TRUE; + LoadGameOutsideMoveLoop = TRUE; + if (DemoMode || DemoPlaying) + LoadGameFromDemo = TRUE; + + return TRUE; + } + + LoadSaveMsg("Loading..."); + + PauseAction(); + + if (LoadGame(load_num) == -1) + { + ResumeAction(); + return FALSE; + } + + QuickLoadNum = load_num; + // the (Quick)Save menu should default to the last loaded game + SaveGameGroup.cursor = load_num; + + ready2send = 1; + LastSaveNum = -1; + ExitMenus(); + + if (DemoMode) + { + ExitLevel = TRUE; + DemoPlaying = FALSE; + } + + return TRUE; +} + +//////////////////////////////////////////////// +// Save Game menu +// This function gets called whenever you +// press enter on one of the save game +// spots. +// I'm figuring it need to do the following: +// . Call MNU_GetInput to allow string input of description. +// . Save the game if there is one by calling: MNU_SaveGameCustom. +//////////////////////////////////////////////// +SWBOOL MNU_GetSaveCustom(void) +{ + short save_num; + extern SWBOOL InMenuLevel, LoadGameOutsideMoveLoop; + + save_num = currentmenu->cursor; + + if (InMenuLevel) + return FALSE; + + if (MenuInputMode) + { + LoadSaveMsg("Saving..."); + + if (DoQuickSave(save_num) == FALSE) + { + LoadGameGroup.cursor = save_num; + } + + ResumeAction(); + ExitMenus(); + + // toggle edit mode + MenuInputMode = FALSE; + } + else + { + strcpy(BackupSaveGameDescr, SaveGameDescr[save_num]); + + // clear keyboard buffer + while (inputState.keyBufferWaiting()) + { + if (inputState.keyGetChar() == 0) + inputState.keyGetChar(); + } + + // toggle edit mode + MenuInputMode = TRUE; + } + + return TRUE; +} + + + +// Blood +static void DoQuickLoad(void) +{ + if (!gGameMenuMgr.m_bActive) + { + if (gQuickLoadSlot != -1) + { + QuickLoadGame(); + return; + } + if (gQuickLoadSlot == -1 && gQuickSaveSlot != -1) + { + gQuickLoadSlot = gQuickSaveSlot; + QuickLoadGame(); + return; + } + gGameMenuMgr.Push(&menuLoadGame, -1); + } +} + +static void DoQuickSave(void) +{ + if (gGameStarted && !gGameMenuMgr.m_bActive && gPlayer[myconnectindex].pXSprite->health != 0) + { + if (gQuickSaveSlot != -1) + { + QuickSaveGame(); + return; + } + gGameMenuMgr.Push(&menuSaveGame, -1); + } +} + +if (gDoQuickSave) +{ + inputState.keyFlushScans(); + switch (gDoQuickSave) + { + case 1: + DoQuickSave(); + break; + case 2: + DoQuickLoad(); + break; + } + gDoQuickSave = 0; + return; +} + + case sc_F6: + inputState.keyFlushScans(); + DoQuickSave(); + break; + case sc_F9: + inputState.keyFlushScans(); + DoQuickLoad(); + break; + + +#endif \ No newline at end of file diff --git a/source/common/savegamehelp.h b/source/common/savegamehelp.h index 12e56cc3d..78c368e1f 100644 --- a/source/common/savegamehelp.h +++ b/source/common/savegamehelp.h @@ -20,3 +20,4 @@ int G_ValidateSavegame(FileReader &fr, FString *savetitle); void G_WriteSaveHeader(const char *name, const char*mapname, const char *title); #define SAVEGAME_EXT ".dsave" + diff --git a/source/common/utility/cmdlib.cpp b/source/common/utility/cmdlib.cpp index 90ceba980..c0fc1dcb0 100644 --- a/source/common/utility/cmdlib.cpp +++ b/source/common/utility/cmdlib.cpp @@ -391,6 +391,33 @@ void CreatePath(const char *fn) } #endif +//========================================================================== +// +// myasctime +// +// [RH] Returns the current local time as ASCII, even if it's too early +// +//========================================================================== + +const char* myasctime() +{ + static char readabletime[50]; + time_t clock; + struct tm* lt; + + time(&clock); + lt = localtime(&clock); + if (lt != NULL) + { + strftime(readabletime, 50, "%F %T", lt); + return readabletime; + } + else + { + return "Unknown Time"; + } +} + //========================================================================== // // strbin -- In-place version diff --git a/source/common/utility/cmdlib.h b/source/common/utility/cmdlib.h index eec968e1f..045037651 100644 --- a/source/common/utility/cmdlib.h +++ b/source/common/utility/cmdlib.h @@ -36,6 +36,7 @@ bool IsNum (const char *str); // [RH] added bool CheckWildcards (const char *pattern, const char *text); +const char* myasctime(); int strbin (char *str); FString strbin1 (const char *start); diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index 309964ee2..1a2042485 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -167,6 +167,8 @@ struct GameInterface : ::GameInterface bool DrawSpecialScreen(const DVector2 &origin, int tilenum) override; void DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) override; void DrawMenuCaption(const DVector2& origin, const char* text) override; + bool SaveGame(FSaveGameNode*) override; + bool LoadGame(FSaveGameNode*) override; }; diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 6430fb3d3..ec3c682a4 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -4688,45 +4688,6 @@ void G_HandleLocalKeys(void) typebuf[0] = 0; } - if ((buttonMap.ButtonDown(gamefunc_Quick_Save) || g_doQuickSave == 1) && (myplayer.gm & MODE_GAME)) - { - buttonMap.ClearButton(gamefunc_Quick_Save); - - g_doQuickSave = 0; - - if (!g_lastusersave.isValid()) - { - C_DoCommand("opensavemenu"); - return; - } - inputState.keyFlushChars(); - - if (sprite[myplayer.i].extra <= 0) - { - P_DoQuote(QUOTE_SAVE_DEAD, &myplayer); - return; - } - - g_screenCapture = 1; - G_DrawRooms(myconnectindex,65536); - g_screenCapture = 0; - - if (g_lastusersave.isValid()) - { - savebrief_t & sv = g_lastusersave; - - // dirty hack... char 127 in last position indicates an auto-filled name - if (sv.name[MAXSAVEGAMENAME] == 127) - { - strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME); - sv.name[MAXSAVEGAMENAME] = 127; - } - - g_quickload = &sv; - G_SavePlayerMaybeMulti(sv); - } - } - if (buttonMap.ButtonDown(gamefunc_Third_Person_View)) { buttonMap.ClearButton(gamefunc_Third_Person_View); @@ -4749,25 +4710,6 @@ void G_HandleLocalKeys(void) hud_messages = fta; } - if ((buttonMap.ButtonDown(gamefunc_Quick_Load) || g_doQuickSave == 2) && (myplayer.gm & MODE_GAME)) - { - buttonMap.ClearButton(gamefunc_Quick_Load); - - g_doQuickSave = 0; - - if (g_quickload == nullptr || !g_quickload->isValid()) - { - C_DoCommand("openloadmenu"); - } - else if (g_quickload->isValid()) - { - inputState.keyFlushChars(); - inputState.ClearKeysDown(); - S_PauseSounds(true); - if (G_LoadPlayerMaybeMulti(*g_quickload) != 0) - g_quickload->reset(); - } - } if (ud.overhead_on != 0) { @@ -6362,12 +6304,7 @@ MAIN_LOOP_RESTART: inputState.keyFlushChars(); videoNextPage(); - g_screenCapture = 1; - G_DrawRooms(myconnectindex, 65536); - g_screenCapture = 0; - - G_SavePlayerMaybeMulti(g_lastautosave, true); - g_quickload = &g_lastautosave; + M_Autosave(); g_saveRequested = false; } diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index 0690feac8..1345511f2 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "base64.h" #include "version.h" #include "menu/menu.h" +#include "c_dispatch.h" #include "debugbreak.h" extern bool rotatesprite_2doverride; @@ -1061,17 +1062,17 @@ static void VM_Fall(int const spriteNum, spritetype * const pSprite) static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags, int32_t const resetFlags) { - // Who thought that allowing a script to do this shit is a good idea??? + if (!g_netServer && ud.multimode < 2 && !(resetFlags & 2)) { - if (g_quickload && g_quickload->isValid() && ud.recstat != 2 && !(resetFlags & 8)) +#if 0 // Who thought that allowing a script to do this shit is a good idea??? This needs to be sorted out later and implemented properly. + if (!(resetFlags & 8)) { if (resetFlags & 4) { inputState.keyFlushChars(); inputState.ClearKeysDown(); FX_StopAllSounds(); - S_ClearSoundLocks(); if (G_LoadPlayerMaybeMulti(*g_quickload) != 0) { g_quickload->reset(); @@ -1082,16 +1083,22 @@ static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags, int32_t cons { M_StartControlPanel(false); M_SetMenu(NAME_ConfirmPlayerReset); + /* + case MENU_RESETPLAYER: + videoFadeToBlack(1); + Bsprintf(tempbuf, "Load last game:\n\"%s\"", g_quickload->name); + Menu_DrawVerifyPrompt(origin.x, origin.y, tempbuf, 2); + break; + */ } } else +#endif { QuickLoadFailure: g_player[playerNum].ps->gm = MODE_RESTART; } -#if !defined LUNATIC vmFlags |= VM_NOEXECUTE; -#endif } else { @@ -4886,32 +4893,9 @@ badindex: vInstruction(CON_SAVENN): vInstruction(CON_SAVE): insptr++; - { - int32_t const requestedSlot = *insptr++; - - if ((unsigned)requestedSlot >= 10) - dispatch(); - - // check if we need to make a new file - if (strcmp(g_lastautosave.path, g_lastusersave.path) == 0 || requestedSlot != g_lastAutoSaveArbitraryID) - { - g_lastautosave.reset(); - } - - g_lastAutoSaveArbitraryID = requestedSlot; - - if (VM_DECODE_INST(tw) == CON_SAVE || g_lastautosave.name[0] == 0) - { - time_t timeStruct = time(NULL); - struct tm *pTime = localtime(&timeStruct); - - strftime(g_lastautosave.name, sizeof(g_lastautosave.name), "%d %b %Y %I:%M%p", pTime); - } - - g_saveRequested = true; - - dispatch(); - } + insptr++; // skip the slot. I will not allow the script to do targeted saving without user control. + g_saveRequested = true; // cannot save right here. + dispatch(); vInstruction(CON_QUAKE): insptr++; diff --git a/source/duke3d/src/gamevars.cpp b/source/duke3d/src/gamevars.cpp index acc1c37b4..091d83256 100644 --- a/source/duke3d/src/gamevars.cpp +++ b/source/duke3d/src/gamevars.cpp @@ -1311,7 +1311,7 @@ static void Gv_AddSystemVars(void) Gv_NewVar("gravitationalconstant", (intptr_t)&g_spriteGravity, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR); Gv_NewVar("gs", (intptr_t)&hudweap.shade, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR); Gv_NewVar("gun_pos", (intptr_t)&hudweap.gunposy, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR); - Gv_NewVar("lastsavepos", (intptr_t)&g_lastAutoSaveArbitraryID, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR); + Gv_NewVar("lastsavepos", (intptr_t)&g_fakeSaveID, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR); Gv_NewVar("lastvisinc", (intptr_t)&lastvisinc, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR); Gv_NewVar("looking_angSR1", (intptr_t)&hudweap.lookhalfang, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR); Gv_NewVar("looking_arc", (intptr_t)&hudweap.lookhoriz, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR); @@ -1465,7 +1465,7 @@ void Gv_RefreshPointers(void) (intptr_t)&g_spriteGravity; aGameVars[Gv_GetVarIndex("gs")].global = (intptr_t)&hudweap.shade; aGameVars[Gv_GetVarIndex("gun_pos")].global = (intptr_t)&hudweap.gunposy; - aGameVars[Gv_GetVarIndex("lastsavepos")].global = (intptr_t)&g_lastAutoSaveArbitraryID; + aGameVars[Gv_GetVarIndex("lastsavepos")].global = (intptr_t)&g_fakeSaveID; // This won't be of much use anymore. >D aGameVars[Gv_GetVarIndex("lastvisinc")].global = (intptr_t)&lastvisinc; aGameVars[Gv_GetVarIndex("looking_angSR1")].global = (intptr_t)&hudweap.lookhalfang; aGameVars[Gv_GetVarIndex("looking_arc")].global = (intptr_t)&hudweap.lookhoriz; diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index b6b580a5a..39aa8d211 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -1432,12 +1432,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) } break; - case MENU_RESETPLAYER: - videoFadeToBlack(1); - Bsprintf(tempbuf, "Load last game:\n\"%s\"", g_quickload->name); - Menu_DrawVerifyPrompt(origin.x, origin.y, tempbuf, 2); - break; - case MENU_SAVECLEANVERIFY: videoFadeToBlack(1); diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index b2b8379e1..3e9d94c77 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -687,24 +687,6 @@ void onvideomodechange(int32_t newmode) g_crosshairSum = -1; } -static int osdcmd_quicksave(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_CONST_PARAMETER(parm); - if (!(g_player[myconnectindex].ps->gm & MODE_GAME)) - OSD_Printf("quicksave: not in a game.\n"); - else g_doQuickSave = 1; - return OSDCMD_OK; -} - -static int osdcmd_quickload(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_CONST_PARAMETER(parm); - if (!(g_player[myconnectindex].ps->gm & MODE_GAME)) - OSD_Printf("quickload: not in a game.\n"); - else g_doQuickSave = 2; - return OSDCMD_OK; -} - static int osdcmd_dumpmapstate(osdfuncparm_t const * const) { @@ -982,9 +964,6 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("printtimes", "printtimes: prints VM timing statistics", osdcmd_printtimes); - OSD_RegisterFunction("quicksave","quicksave: performs a quick save", osdcmd_quicksave); - OSD_RegisterFunction("quickload","quickload: performs a quick load", osdcmd_quickload); - OSD_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap); OSD_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound); OSD_RegisterFunction("addlogvar","addlogvar : prints the value of a gamevar", osdcmd_addlogvar); diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index a8dc821cf..d9ead5965 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -1341,11 +1341,6 @@ void G_NewGame(int volumeNum, int levelNum, int skillNum) ud.volume_number = volumeNum; STAT_StartNewGame(gVolumeNames[volumeNum], skillNum); - g_lastAutoSaveArbitraryID = -1; - g_lastautosave.reset(); - g_lastusersave.reset(); - g_quickload = nullptr; - // we don't want the intro to play after the multiplayer setup screen if ((!g_netServer && ud.multimode < 2) && !Menu_HaveUserMap() && !VM_OnEventWithReturn(EVENT_NEWGAMESCREEN, g_player[myconnectindex].ps->i, myconnectindex, 0) diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index 2d1f800e3..b5b986209 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -141,10 +141,8 @@ void G_ResetInterpolations(void) G_SetInterpolation(g_animatePtr[i]); } -savebrief_t g_lastautosave, g_lastusersave, g_freshload; -int32_t g_lastAutoSaveArbitraryID = -1; +int32_t g_fakeSaveID = -1; bool g_saveRequested; -savebrief_t * g_quickload; static FileReader *OpenSavegame(const char *fn) @@ -220,15 +218,15 @@ static int different_user_map; // XXX: keyboard input 'blocked' after load fail? (at least ESC?) -int32_t G_LoadPlayer(savebrief_t & sv) +int32_t G_LoadPlayer(FSaveGameNode *sv) { - if (sv.isExt) + if (sv->bIsExt) { int volume = -1; int level = -1; int skill = -1; - auto fil = OpenSavegame(sv.path); + auto fil = OpenSavegame(sv->Filename); if (!fil) return -1; { @@ -354,8 +352,6 @@ int32_t G_LoadPlayer(savebrief_t & sv) ud.skill_voice = -1; ud.volume_number = volume; - g_lastAutoSaveArbitraryID = -1; - #ifdef EDUKE32_TOUCH_DEVICES p0.zoom = 360; #else @@ -465,7 +461,7 @@ int32_t G_LoadPlayer(savebrief_t & sv) return 0; } - auto fil = OpenSavegame(sv.path); + auto fil = OpenSavegame(sv->Filename); if (!fil) return -1; @@ -545,7 +541,7 @@ int32_t G_LoadPlayer(savebrief_t & sv) { // in theory, we could load into an initial dump first and trivially // recover if things go wrong... - Bsprintf(tempbuf, "Loading save game file \"%s\" failed (code %d), cannot recover.", sv.path, status); + Bsprintf(tempbuf, "Loading save game file \"%s\" failed (code %d), cannot recover.", sv->Filename.GetChars(), status); G_GameExit(tempbuf); } @@ -582,7 +578,7 @@ static void G_RestoreTimers(void) ////////// -int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) +bool G_SavePlayer(FSaveGameNode *sv) { #ifdef __ANDROID__ G_SavePalette(); @@ -598,62 +594,26 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) errno = 0; FileWriter *fil; - if (sv.isValid()) - { - fn = G_BuildSaveName(sv.path); - OpenSaveGameForWrite(fn); - fil = WriteSavegameChunk("snapshot.dat"); - } - else - { - fn = G_BuildSaveName("save0000"); - - auto fnp = fn.LockBuffer(); - char* zeros = strstr(fnp, "0000"); - fil = savecounter.opennextfile(fnp, zeros); // fixme: Rewrite this so that it won't create the file. - fn.UnlockBuffer(); - if (fil) - { - delete fil; - remove(fn); - OpenSaveGameForWrite(fn); - fil = WriteSavegameChunk("snapshot.dat"); - } - savecounter.count++; - // don't copy the mod dir into sv.path (G_BuildSaveName guarantees the presence of a slash.) - Bstrcpy(sv.path, strrchr(fn, '/') + 1); - } - - if (!fil) - { - OSD_Printf("G_SavePlayer: failed opening \"%s\" for writing: %s\n", - fn.GetChars(), strerror(errno)); - ready2send = 1; - Net_WaitForServer(); - - G_RestoreTimers(); - ototalclock = totalclock; - return -1; - } - else + fn = G_BuildSaveName(sv->Filename); + OpenSaveGameForWrite(fn); + fil = WriteSavegameChunk("snapshot.dat"); + // The above call cannot fail. { auto& fw = *fil; - sv.isExt = 0; - // temporary hack ud.user_map = G_HaveUserMap(); VM_OnEvent(EVENT_SAVEGAME, g_player[myconnectindex].ps->i, myconnectindex); - portableBackupSave(sv.path, sv.name, ud.last_stateless_volume, ud.last_stateless_level); + portableBackupSave(sv->Filename, sv->SaveTitle, ud.last_stateless_volume, ud.last_stateless_level); // SAVE! - sv_saveandmakesnapshot(fw, sv.name, 0, 0, 0, 0, isAutoSave); + sv_saveandmakesnapshot(fw, sv->SaveTitle, 0, 0, 0, 0); fw.Close(); - FinishSavegameWrite(); + bool res = FinishSavegameWrite(); if (!g_netServer && ud.multimode < 2) { @@ -670,11 +630,12 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) VM_OnEvent(EVENT_POSTSAVEGAME, g_player[myconnectindex].ps->i, myconnectindex); - return 0; + return res; } } -int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv) + +bool GameInterface::LoadGame(FSaveGameNode *sv) { if (g_netServer || ud.multimode > 1) { @@ -682,27 +643,33 @@ int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv) P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); // g_player[myconnectindex].ps->gm = MODE_GAME; - return 127; + return false; } else { int32_t c = G_LoadPlayer(sv); if (c == 0) g_player[myconnectindex].ps->gm = MODE_GAME; - return c; + return c == 0; } } -void G_SavePlayerMaybeMulti(savebrief_t & sv, bool isAutoSave) +bool GameInterface::SaveGame(FSaveGameNode* sv) { if (g_netServer || ud.multimode > 1) { Bstrcpy(apStrings[QUOTE_RESERVED4], "Multiplayer Saving Not Yet Supported"); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); + return false; } else { - G_SavePlayer(sv, isAutoSave); + videoNextPage(); // no idea if this is needed here. + g_screenCapture = 1; + G_DrawRooms(myconnectindex, 65536); + g_screenCapture = 0; + + return G_SavePlayer(sv); } } @@ -1470,7 +1437,7 @@ static void SV_AllocSnap(int32_t allocinit) } // make snapshot only if spot < 0 (demo) -int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave) +int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress) { savehead_t h; @@ -1493,10 +1460,6 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i h.majorver = SV_MAJOR_VER; h.minorver = SV_MINOR_VER; h.ptrsize = sizeof(intptr_t); - - if (isAutoSave) - h.ptrsize |= 1u << 7u; - h.bytever = BYTEVERSION; h.userbytever = ud.userbytever; h.scriptcrc = g_scriptcrc; diff --git a/source/duke3d/src/savegame.h b/source/duke3d/src/savegame.h index 6f34329ac..f50e588fc 100644 --- a/source/duke3d/src/savegame.h +++ b/source/duke3d/src/savegame.h @@ -57,62 +57,13 @@ typedef struct uint8_t numplayers, volnum, levnum, skill; char boardfn[BMAX_PATH]; // 286 bytes -#ifdef __ANDROID__ - char skillname[32], volname[32]; -#endif - uint8_t getPtrSize() const { return ptrsize & 0x7Fu; } - bool isAutoSave() const { return !!(ptrsize & (1u<<7u)); } + uint8_t getPtrSize() const { return ptrsize; } } savehead_t; #pragma pack(pop) -struct savebrief_t -{ - savebrief_t() - { - reset(); - } - savebrief_t(char const *n) - { - strncpy(name, n, MAXSAVEGAMENAME); - path[0] = '\0'; - } - - char name[MAXSAVEGAMENAMESTRUCT]; - char path[BMAX_PATH]; - uint8_t isExt = 0; - - void reset() - { - name[0] = '\0'; - path[0] = '\0'; - isExt = 0; - } - bool isValid() const - { - return path[0] != '\0'; - } -}; - -struct menusave_t -{ - savebrief_t brief; - uint8_t isOldVer = 0; - uint8_t isUnreadable = 0; - uint8_t isAutoSave = 0; - void clear() - { - brief.reset(); - isOldVer = 0; - isUnreadable = 0; - isAutoSave = 0; - } -}; - -extern savebrief_t g_lastautosave, g_lastusersave, g_freshload; -extern int32_t g_lastAutoSaveArbitraryID; +extern int32_t g_fakeSaveID; extern bool g_saveRequested; -extern savebrief_t * g_quickload; int32_t sv_updatestate(int32_t frominit); @@ -120,14 +71,10 @@ int32_t sv_readdiff(FileReader& fil); uint32_t sv_writediff(FileWriter *fil); int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h); int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h); -int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave = false); +int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress); void sv_freemem(); -int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave); -int32_t G_LoadPlayer(savebrief_t & sv); int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh); void ReadSaveGameHeaders(void); -void G_SavePlayerMaybeMulti(savebrief_t & sv, bool isAutoSave = false); -int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv); #ifdef YAX_ENABLE extern void sv_postyaxload(void); diff --git a/source/rr/src/duke3d.h b/source/rr/src/duke3d.h index 324b6c2a7..11795d75e 100644 --- a/source/rr/src/duke3d.h +++ b/source/rr/src/duke3d.h @@ -167,6 +167,8 @@ struct GameInterface : ::GameInterface FSavegameInfo GetSaveSig() override; void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) override; void DrawMenuCaption(const DVector2& origin, const char* text) override; + bool SaveGame(FSaveGameNode*) override; + bool LoadGame(FSaveGameNode*) override; }; END_RR_NS diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 119ac5df3..07336cd03 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -6232,46 +6232,6 @@ void G_HandleLocalKeys(void) } - if ((buttonMap.ButtonDown(gamefunc_Quick_Save) || g_doQuickSave == 1) && (!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && (g_player[myconnectindex].ps->gm&MODE_GAME)) - { - buttonMap.ClearButton(gamefunc_Quick_Save); - - g_doQuickSave = 0; - - if (!g_lastusersave.isValid()) - { - C_DoCommand("opensavemenu"); - return; - } - - inputState.keyFlushChars(); - - if (sprite[g_player[myconnectindex].ps->i].extra <= 0) - { - P_DoQuote(QUOTE_SAVE_DEAD,g_player[myconnectindex].ps); - return; - } - - g_screenCapture = 1; - G_DrawRooms(myconnectindex,65536); - g_screenCapture = 0; - - if (g_lastusersave.isValid()) - { - savebrief_t & sv = g_lastusersave; - - // dirty hack... char 127 in last position indicates an auto-filled name - if (sv.name[MAXSAVEGAMENAME] == 127) - { - strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME); - sv.name[MAXSAVEGAMENAME] = 127; - } - - g_quickload = &sv; - G_SavePlayerMaybeMulti(sv); - } - } - if (buttonMap.ButtonDown(gamefunc_Third_Person_View)) { buttonMap.ClearButton(gamefunc_Third_Person_View); @@ -6297,26 +6257,6 @@ void G_HandleLocalKeys(void) hud_messages = fta; } - if ((buttonMap.ButtonDown(gamefunc_Quick_Load) || g_doQuickSave == 2) && (!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && (g_player[myconnectindex].ps->gm&MODE_GAME)) - { - buttonMap.ClearButton(gamefunc_Quick_Load); - - g_doQuickSave = 0; - - if (g_quickload == nullptr || !g_quickload->isValid()) - { - C_DoCommand("openloadmenu"); - } - else if (g_quickload->isValid()) - { - inputState.keyFlushChars(); - inputState.ClearKeysDown(); - S_PauseSounds(true); - if (G_LoadPlayerMaybeMulti(*g_quickload) != 0) - g_quickload->reset(); - } - } - if (ud.overhead_on != 0) { int const timerOffset = ((int) totalclock - nonsharedtimer); @@ -7783,7 +7723,7 @@ MAIN_LOOP_RESTART: { idle(); } - else */if (G_FPSLimit() || g_saveRequested) + else */if (G_FPSLimit()) { int const smoothRatio = calc_smoothratio(totalclock, ototalclock); @@ -7799,24 +7739,6 @@ MAIN_LOOP_RESTART: } } - // handle CON_SAVE and CON_SAVENN - if (g_saveRequested) - { - inputState.keyFlushChars(); - videoNextPage(); - - g_screenCapture = 1; - G_DrawRooms(myconnectindex, 65536); - g_screenCapture = 0; - - G_SavePlayerMaybeMulti(g_lastautosave, true); - g_quickload = &g_lastautosave; - - OSD_Printf("Saved: %s\n", g_lastautosave.path); - - g_saveRequested = false; - } - if (g_player[myconnectindex].ps->gm&MODE_DEMO) goto MAIN_LOOP_RESTART; } diff --git a/source/rr/src/gameexec.cpp b/source/rr/src/gameexec.cpp index 7f261f91b..49997724e 100644 --- a/source/rr/src/gameexec.cpp +++ b/source/rr/src/gameexec.cpp @@ -1061,12 +1061,14 @@ static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags) //AddLog("resetplayer"); if (!g_netServer && ud.multimode < 2) { +#if 0 if (g_quickload && g_quickload->isValid() && ud.recstat != 2) { M_StartControlPanel(false); M_SetMenu(NAME_ConfirmPlayerReset); } else +#endif g_player[playerNum].ps->gm = MODE_RESTART; vmFlags |= VM_NOEXECUTE; } diff --git a/source/rr/src/menus.cpp b/source/rr/src/menus.cpp index 62679677d..0bbaf8fc6 100644 --- a/source/rr/src/menus.cpp +++ b/source/rr/src/menus.cpp @@ -1472,17 +1472,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) case MENU_MOUSEADVANCED: break; - case MENU_RESETPLAYER: - videoFadeToBlack(1); - Bsprintf(tempbuf, "Load last game:\n\"%s\"" -#ifndef EDUKE32_ANDROID_MENU - "\n(Y/N)" -#endif - , g_quickload->name); - mgametextcenter(origin.x, origin.y + (90<<16), tempbuf); - break; - - case MENU_NEWVERIFY: videoFadeToBlack(1); mgametextcenter(origin.x, origin.y + (90<<16), "Abort this game?" diff --git a/source/rr/src/osdcmds.cpp b/source/rr/src/osdcmds.cpp index 17ca7d68c..91ff1ac51 100644 --- a/source/rr/src/osdcmds.cpp +++ b/source/rr/src/osdcmds.cpp @@ -590,24 +590,6 @@ void onvideomodechange(int32_t newmode) } -static int osdcmd_quicksave(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_CONST_PARAMETER(parm); - if (!(g_player[myconnectindex].ps->gm & MODE_GAME)) - OSD_Printf("quicksave: not in a game.\n"); - else g_doQuickSave = 1; - return OSDCMD_OK; -} - -static int osdcmd_quickload(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_CONST_PARAMETER(parm); - if (!(g_player[myconnectindex].ps->gm & MODE_GAME)) - OSD_Printf("quickload: not in a game.\n"); - else g_doQuickSave = 2; - return OSDCMD_OK; -} - #if !defined NETCODE_DISABLE static int osdcmd_disconnect(osdcmdptr_t UNUSED(parm)) { @@ -837,9 +819,6 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("printtimes", "printtimes: prints VM timing statistics", osdcmd_printtimes); - OSD_RegisterFunction("quicksave","quicksave: performs a quick save", osdcmd_quicksave); - OSD_RegisterFunction("quickload","quickload: performs a quick load", osdcmd_quickload); - OSD_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap); OSD_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound); diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index 1aaffd4be..7f8b9f23a 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -1905,11 +1905,7 @@ void G_NewGame(int volumeNum, int levelNum, int skillNum) STAT_StartNewGame(gVolumeNames[volumeNum], skillNum); ud.last_level = -1; - g_lastAutoSaveArbitraryID = -1; - g_lastautosave.reset(); - g_lastusersave.reset(); - g_quickload = nullptr; - + int const UserMap = Menu_HaveUserMap(); // we don't want the intro to play after the multiplayer setup screen diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index 2edc5e336..bfab8e3a8 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -138,16 +138,6 @@ void G_ResetInterpolations(void) G_SetInterpolation(g_animatePtr[i]); } -savebrief_t g_lastautosave, g_lastusersave, g_freshload; -int32_t g_lastAutoSaveArbitraryID = -1; -bool g_saveRequested; -savebrief_t * g_quickload; - -menusave_t * g_menusaves; -uint16_t g_nummenusaves; - -static menusave_t * g_internalsaves; -static uint16_t g_numinternalsaves; static FileReader *OpenSavegame(const char *fn) { @@ -226,9 +216,9 @@ static void sv_postudload(); static int different_user_map; // XXX: keyboard input 'blocked' after load fail? (at least ESC?) -int32_t G_LoadPlayer(savebrief_t & sv) +int32_t G_LoadPlayer(const char *path) { - auto fil = OpenSavegame(sv.path); + auto fil = OpenSavegame(path); if (!fil) return -1; @@ -255,6 +245,7 @@ int32_t G_LoadPlayer(savebrief_t & sv) // some setup first ud.multimode = h.numplayers; + S_PauseSounds(true); if (numplayers > 1) { @@ -303,7 +294,7 @@ int32_t G_LoadPlayer(savebrief_t & sv) { // in theory, we could load into an initial dump first and trivially // recover if things go wrong... - Bsprintf(tempbuf, "Loading save game file \"%s\" failed (code %d), cannot recover.", sv.path, status); + Bsprintf(tempbuf, "Loading save game file \"%s\" failed (code %d), cannot recover.", path, status); G_GameExit(tempbuf); } @@ -339,12 +330,8 @@ static void G_RestoreTimers(void) lockclock = g_timers.lockclock; } -int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) +bool G_SavePlayer(FSaveGameNode *sv) { -#ifdef __ANDROID__ - G_SavePalette(); -#endif - G_SaveTimers(); Net_WaitForEverybody(); @@ -355,59 +342,23 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) errno = 0; FileWriter *fil; - if (sv.isValid()) + fn = G_BuildSaveName(sv->Filename); + OpenSaveGameForWrite(fn); + fil = WriteSavegameChunk("snapshot.dat"); + // The above call cannot fail. { - fn = G_BuildSaveName(sv.path); - OpenSaveGameForWrite(fn); - fil = WriteSavegameChunk("snapshot.dat"); - } - else - { - fn = G_BuildSaveName("save0000"); - - auto fnp = fn.LockBuffer(); - char* zeros = strstr(fnp, "0000"); - fil = savecounter.opennextfile(fnp, zeros); // fixme: Rewrite this so that it won't create the file. - fn.UnlockBuffer(); - if (fil) - { - delete fil; - remove(fn); - OpenSaveGameForWrite(fn); - fil = WriteSavegameChunk("snapshot.dat"); - } - savecounter.count++; - // don't copy the mod dir into sv.path (G_BuildSaveName guarantees the presence of a slash.) - Bstrcpy(sv.path, strrchr(fn, '/') + 1); - } - - if (!fil) - { - OSD_Printf("G_SavePlayer: failed opening \"%s\" for writing: %s\n", - fn.GetChars(), strerror(errno)); - ready2send = 1; - Net_WaitForEverybody(); - - G_RestoreTimers(); - ototalclock = totalclock; - return -1; - } - else - { - WriteSavegameChunk("DEMOLITION_RN"); auto& fw = *fil; - //CompressedFileWriter fw(fil, true); // temporary hack ud.user_map = G_HaveUserMap(); // SAVE! - sv_saveandmakesnapshot(fw, sv.name, 0, 0, 0, 0, isAutoSave); + sv_saveandmakesnapshot(fw, sv->SaveTitle, 0, 0, 0, 0); fw.Close(); - FinishSavegameWrite(); + bool res = FinishSavegameWrite(); if (!g_netServer && ud.multimode < 2) { @@ -422,11 +373,11 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave) G_RestoreTimers(); ototalclock = totalclock; - return 0; + return res; } } -int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv) +bool GameInterface::LoadGame(FSaveGameNode* sv) { if (g_netServer || ud.multimode > 1) { @@ -434,18 +385,18 @@ int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv) P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); // g_player[myconnectindex].ps->gm = MODE_GAME; - return 127; + return false; } else { - int32_t c = G_LoadPlayer(sv); + int32_t c = G_LoadPlayer(sv->Filename); if (c == 0) g_player[myconnectindex].ps->gm = MODE_GAME; - return c; + return !c; } } -void G_SavePlayerMaybeMulti(savebrief_t & sv, bool isAutoSave) +bool GameInterface::SaveGame(FSaveGameNode* sv) { if (g_netServer || ud.multimode > 1) { @@ -454,7 +405,13 @@ void G_SavePlayerMaybeMulti(savebrief_t & sv, bool isAutoSave) } else { - G_SavePlayer(sv, isAutoSave); + + videoNextPage(); // no idea if this is needed here. + g_screenCapture = 1; + G_DrawRooms(myconnectindex, 65536); + g_screenCapture = 0; + + G_SavePlayer(sv); } } diff --git a/source/rr/src/savegame.h b/source/rr/src/savegame.h index 705698488..c30497b78 100644 --- a/source/rr/src/savegame.h +++ b/source/rr/src/savegame.h @@ -52,64 +52,11 @@ typedef struct uint8_t numplayers, volnum, levnum, skill; char boardfn[BMAX_PATH]; // 286 bytes -#ifdef __ANDROID__ - char skillname[32], volname[32]; -#endif - uint8_t getPtrSize() const { return ptrsize & 0x7Fu; } - bool isAutoSave() const { return !!(ptrsize & (1u<<7u)); } + uint8_t getPtrSize() const { return ptrsize; } } savehead_t; #pragma pack(pop) -struct savebrief_t -{ - savebrief_t() - { - reset(); - } - savebrief_t(char const *n) - { - strncpy(name, n, MAXSAVEGAMENAME); - path[0] = '\0'; - } - - char name[MAXSAVEGAMENAMESTRUCT]; - char path[BMAX_PATH]; - - void reset() - { - name[0] = '\0'; - path[0] = '\0'; - } - bool isValid() const - { - return path[0] != '\0'; - } -}; - -struct menusave_t -{ - savebrief_t brief; - uint8_t isOldVer = 0; - uint8_t isUnreadable = 0; - uint8_t isAutoSave = 0; - void clear() - { - brief.reset(); - isOldVer = 0; - isUnreadable = 0; - isAutoSave = 0; - } -}; - -extern savebrief_t g_lastautosave, g_lastusersave, g_freshload; -extern int32_t g_lastAutoSaveArbitraryID; -extern bool g_saveRequested; -extern savebrief_t * g_quickload; - -extern menusave_t * g_menusaves; -extern uint16_t g_nummenusaves; - int32_t sv_updatestate(int32_t frominit); int32_t sv_readdiff(FileReader& fil); uint32_t sv_writediff(FileWriter *fil); @@ -117,12 +64,8 @@ int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h); int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h); int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave = false); void sv_freemem(); -int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave); -int32_t G_LoadPlayer(savebrief_t & sv); int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh); void ReadSaveGameHeaders(void); -void G_SavePlayerMaybeMulti(savebrief_t & sv, bool isAutoSave = false); -int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv); #ifdef YAX_ENABLE extern void sv_postyaxload(void); diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 10aad2398..d6a40a641 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -3338,40 +3338,6 @@ void ConKey(void) char WangBangMacro[10][64]; -SWBOOL DoQuickSave(short save_num) -{ - PauseAction(); - - if (SaveGame(save_num) != -1) - { - QuickLoadNum = save_num; - - LastSaveNum = -1; - - return FALSE; - } - - return TRUE; -} - -SWBOOL DoQuickLoad() -{ - inputState.ClearKeysDown(); - - PauseAction(); - - ReloadPrompt = FALSE; - if (LoadGame(QuickLoadNum) == -1) - { - return FALSE; - } - - ready2send = 1; - LastSaveNum = -1; - - return TRUE; -} - void FunctionKeys(PLAYERp pp) { @@ -3469,45 +3435,6 @@ FunctionKeys(PLAYERp pp) } } - // F6 quick save - if (inputState.GetKeyStatus(KEYSC_F6)) - { - inputState.ClearKeyStatus(KEYSC_F6); - if (!TEST(pp->Flags, PF_DEAD)) - { - if (QuickLoadNum < 0) - { - inputState.SetKeyStatus(sc_Escape); - ControlPanelType = ct_savemenu; - } - else - { - inputState.ClearAllInput(); - DoQuickSave(QuickLoadNum); - ResumeAction(); - } - } - } - - // F9 quick load - if (inputState.GetKeyStatus(KEYSC_F9)) - { - inputState.ClearKeyStatus(KEYSC_F9); - - if (!TEST(pp->Flags, PF_DEAD)) - { - if (QuickLoadNum < 0) - { - inputState.SetKeyStatus(sc_Escape); - ControlPanelType = ct_loadmenu; - } - else - { - DoQuickLoad(); - ResumeAction(); - } - } - } } @@ -3609,15 +3536,15 @@ void PauseKey(PLAYERp pp) { if (ReloadPrompt) { - if (QuickLoadNum < 0) - { - ReloadPrompt = FALSE; + ReloadPrompt = FALSE; + /* } else { inputState.SetKeyStatus(sc_Escape); ControlPanelType = ct_quickloadmenu; } + */ } } } diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 8644cea3e..9b55ac67c 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -2373,10 +2373,7 @@ int COVERinsertsprite(short sectnum, short statnum); //returns (short)spritenu void AudioUpdate(void); // stupid extern short LastSaveNum; -extern short QuickLoadNum; void LoadSaveMsg(const char *msg); -SWBOOL DoQuickSave(short save_num); -SWBOOL DoQuickLoad(void); struct GameInterface : ::GameInterface { diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index faac75f1f..80f46e060 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -67,8 +67,6 @@ signed char MNU_InputString(char*, short); short TimeLimitTable[9] = {0,3,5,10,15,20,30,45,60}; -short QuickLoadNum = -1; -char QuickLoadDescrDialog[128]; SWBOOL SavePrompt = FALSE; extern SWBOOL InMenuLevel, LoadGameOutsideMoveLoop, LoadGameFromDemo; extern uint8_t RedBookSong[40]; @@ -511,7 +509,7 @@ MenuItem save_i[] = // No actual submenus for this, just quit text. MenuGroup quitgroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_QuitCustom, NULL, 0}; -MenuGroup quickloadgroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_QuickLoadCustom, NULL, 0}; +MenuGroup quickloadgroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_QuitCustom/* MNU_QuickLoadCustom*/, NULL, 0}; // temp.placeholder. MenuGroup ordergroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_OrderCustom, NULL, 0}; // save and load function calls @@ -1734,87 +1732,6 @@ MNU_QuitCustom(UserCall call, MenuItem_p item) return TRUE; } -SWBOOL -MNU_QuickLoadCustom(UserCall call, MenuItem_p item) -{ - int select; - extern SWBOOL ReloadPrompt; - int bak; - PLAYERp pp = Player + myconnectindex; - extern short GlobInfoStringTime; - extern SWBOOL DrawScreen; - int ret; - - if (cust_callback == NULL) - { - if (call != uc_setup) - return FALSE; - - memset(dialog, 0, sizeof(dialog)); - - dialog[0] = "Load saved game"; - sprintf(QuickLoadDescrDialog,"\"%s\" (Y/N)?",SaveGameDescr[QuickLoadNum]); - dialog[1] = QuickLoadDescrDialog; - } - - // Ignore the special touchup calls - if (call == uc_touchup) - return TRUE; - - ret = MNU_Dialog(); - - if (DrawScreen) - { - return TRUE; - } - - if (ret == FALSE) - { - if (inputState.GetKeyStatus(sc_N) || inputState.GetKeyStatus(sc_Space) || inputState.GetKeyStatus(sc_Enter)) - { - cust_callback = NULL; - if (ReloadPrompt) - { - ReloadPrompt = FALSE; - bak = GlobInfoStringTime; - GlobInfoStringTime = 999; - PutStringInfo(pp, "Press SPACE to restart"); - GlobInfoStringTime = bak; - } - - inputState.ClearKeysDown(); - ExitMenus(); - } - else - { - cust_callback = MNU_QuickLoadCustom; - cust_callback_call = call; - cust_callback_item = item; - } - } - else - { - // Y pressed - cust_callback = NULL; - - LoadSaveMsg("Loading..."); - - if (DoQuickLoad() == FALSE) - { - ResumeAction(); - return FALSE; - } - - ExitMenus(); - - return TRUE; - } - - inputState.ClearKeysDown(); - - return TRUE; -} - // MENU FUNCTIONS ///////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////// // Set some global menu related defaults @@ -2349,58 +2266,6 @@ void LoadSaveMsg(const char *msg) //////////////////////////////////////////////// SWBOOL MNU_GetLoadCustom(void) { - short load_num; - - load_num = currentmenu->cursor; - - // no saved game exists - don't do anything - if (SaveGameDescr[load_num][0] == '\0') - return FALSE; - - if (InMenuLevel || DemoMode || DemoPlaying) - { - LoadSaveMsg("Loading..."); - - if (LoadGame(load_num) == -1) - return FALSE; - - QuickLoadNum = load_num; - // the (Quick)Save menu should default to the last loaded game - SaveGameGroup.cursor = load_num; - - ExitMenus(); - ExitLevel = TRUE; - LoadGameOutsideMoveLoop = TRUE; - if (DemoMode || DemoPlaying) - LoadGameFromDemo = TRUE; - - return TRUE; - } - - LoadSaveMsg("Loading..."); - - PauseAction(); - - if (LoadGame(load_num) == -1) - { - ResumeAction(); - return FALSE; - } - - QuickLoadNum = load_num; - // the (Quick)Save menu should default to the last loaded game - SaveGameGroup.cursor = load_num; - - ready2send = 1; - LastSaveNum = -1; - ExitMenus(); - - if (DemoMode) - { - ExitLevel = TRUE; - DemoPlaying = FALSE; - } - return TRUE; } @@ -2415,44 +2280,6 @@ SWBOOL MNU_GetLoadCustom(void) //////////////////////////////////////////////// SWBOOL MNU_GetSaveCustom(void) { - short save_num; - extern SWBOOL InMenuLevel, LoadGameOutsideMoveLoop; - - save_num = currentmenu->cursor; - - if (InMenuLevel) - return FALSE; - - if (MenuInputMode) - { - LoadSaveMsg("Saving..."); - - if (DoQuickSave(save_num) == FALSE) - { - LoadGameGroup.cursor = save_num; - } - - ResumeAction(); - ExitMenus(); - - // toggle edit mode - MenuInputMode = FALSE; - } - else - { - strcpy(BackupSaveGameDescr, SaveGameDescr[save_num]); - - // clear keyboard buffer - while (inputState.keyBufferWaiting()) - { - if (inputState.keyGetChar() == 0) - inputState.keyGetChar(); - } - - // toggle edit mode - MenuInputMode = TRUE; - } - return TRUE; } diff --git a/source/sw/src/menus.h b/source/sw/src/menus.h index bf707d95e..21c7a3ee5 100644 --- a/source/sw/src/menus.h +++ b/source/sw/src/menus.h @@ -284,7 +284,6 @@ typedef struct MenuGroup // Custom Routine Prototypes //////////////////////////////////////////////////////////////////// SWBOOL MNU_QuitCustom(UserCall call, MenuItem *item); -SWBOOL MNU_QuickLoadCustom(UserCall call, MenuItem *item); SWBOOL MNU_LoadSaveTouchupCustom(UserCall call, MenuItem *item); SWBOOL MNU_OrderCustom(UserCall call, MenuItem *item); SWBOOL MNU_DoEpisodeSelect(UserCall call, MenuItem *item); diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index 79a4f332a..cb18476c2 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -6475,7 +6475,6 @@ DoPlayerBeginDie(PLAYERp pp) short bak; int choosesnd = 0; extern short GlobInfoStringTime; - extern short QuickLoadNum; USERp u = User[pp->PlayerSprite]; @@ -6518,11 +6517,13 @@ DoPlayerBeginDie(PLAYERp pp) PlayerSound(PlayerLowHealthPainVocs[choosesnd],&pp->posx, &pp->posy,&pp->posy,v3df_dontpan|v3df_doppler|v3df_follow,pp); +#if 0 if (!CommEnabled && numplayers <= 1 && QuickLoadNum >= 0) { ReloadPrompt = TRUE; } else +#endif { bak = GlobInfoStringTime; GlobInfoStringTime = 999; From 9d71416a55ef471f3641d942746b073542f1ced4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Nov 2019 20:18:42 +0100 Subject: [PATCH 061/203] - key binding verification. Should be correct now, except for a few places which were unified. --- wadsrc/static/demolition/commonbinds.txt | 1 + wadsrc/static/demolition/defbinds.txt | 1 - wadsrc/static/demolition/leftbinds.txt | 1 + wadsrc/static/demolition/origbinds.txt | 3 --- wadsrc/static/filter/blood/demolition/defbinds.txt | 3 ++- wadsrc/static/filter/blood/demolition/leftbinds.txt | 3 ++- wadsrc/static/filter/blood/demolition/origbinds.txt | 1 - wadsrc/static/filter/duke/demolition/defbinds.txt | 1 - wadsrc/static/filter/duke/demolition/leftbinds.txt | 1 - wadsrc/static/filter/duke/demolition/origbinds.txt | 1 - wadsrc/static/filter/ionfury/demolition/defbinds.txt | 1 - wadsrc/static/filter/ionfury/demolition/leftbinds.txt | 1 - wadsrc/static/filter/ionfury/demolition/origbinds.txt | 1 - wadsrc/static/filter/nam/demolition/defbinds.txt | 1 - wadsrc/static/filter/nam/demolition/leftbinds.txt | 1 - wadsrc/static/filter/nam/demolition/origbinds.txt | 3 ++- wadsrc/static/filter/redneck/demolition/defbinds.txt | 4 +--- wadsrc/static/filter/redneck/demolition/leftbinds.txt | 1 - wadsrc/static/filter/redneck/demolition/origbinds.txt | 1 - wadsrc/static/filter/shadowwarrior/demolition/defbinds.txt | 1 - wadsrc/static/filter/shadowwarrior/demolition/leftbinds.txt | 3 +-- wadsrc/static/filter/shadowwarrior/demolition/origbinds.txt | 1 - wadsrc/static/filter/ww2gi/demolition/defbinds.txt | 1 - wadsrc/static/filter/ww2gi/demolition/leftbinds.txt | 1 - wadsrc/static/filter/ww2gi/demolition/origbinds.txt | 3 ++- 25 files changed, 12 insertions(+), 28 deletions(-) diff --git a/wadsrc/static/demolition/commonbinds.txt b/wadsrc/static/demolition/commonbinds.txt index e9babc5c6..1ca90ecac 100644 --- a/wadsrc/static/demolition/commonbinds.txt +++ b/wadsrc/static/demolition/commonbinds.txt @@ -41,6 +41,7 @@ PgDn "+Look_Down" Home "+Aim_Up" End "+Aim_Down" RCtrl "+Fire" +Scroll "+Holster_Weapon" Enter "+Inventory" KP-Enter "+Inventory" diff --git a/wadsrc/static/demolition/defbinds.txt b/wadsrc/static/demolition/defbinds.txt index eb5a41054..a5c467542 100644 --- a/wadsrc/static/demolition/defbinds.txt +++ b/wadsrc/static/demolition/defbinds.txt @@ -12,7 +12,6 @@ KP1 "+Aim_Down" KP5 "+Center_View" KP9 "+Look_Up" KP3 "+Look_Down" -KP. "+Look_Right" KP- "+Shrink_Screen" KP+ "+Enlarge_Screen" Y "+Show_Opponents_Weapon" diff --git a/wadsrc/static/demolition/leftbinds.txt b/wadsrc/static/demolition/leftbinds.txt index 6f7f79710..5e991edf4 100644 --- a/wadsrc/static/demolition/leftbinds.txt +++ b/wadsrc/static/demolition/leftbinds.txt @@ -6,6 +6,7 @@ Space "+Open" A "+Jump" KP- "+Jump" Z "+Crouch" +C "+Toggle_Crouch" KP. "+Look_Right" KP7 "+Strafe_Left" KP9 "+Strafe_Right" diff --git a/wadsrc/static/demolition/origbinds.txt b/wadsrc/static/demolition/origbinds.txt index 7e1f14da0..723b9b43c 100644 --- a/wadsrc/static/demolition/origbinds.txt +++ b/wadsrc/static/demolition/origbinds.txt @@ -1,14 +1,11 @@ uparrow "+Move_Forward" downarrow "+Move_Backward" LCtrl "+Fire" -RCtrl "+Fire" Space "+Open" A "+Jump" / "+Jump" Z "+Crouch" -PgUp "+Look_Up" KP9 "+Look_Up" -PgDn "+Look_Down" KP3 "+Look_Down" KP. "+Look_Right" , "+Strafe_Left" diff --git a/wadsrc/static/filter/blood/demolition/defbinds.txt b/wadsrc/static/filter/blood/demolition/defbinds.txt index 22fb508cd..0713276f9 100644 --- a/wadsrc/static/filter/blood/demolition/defbinds.txt +++ b/wadsrc/static/filter/blood/demolition/defbinds.txt @@ -1,4 +1,3 @@ -// U "+Mouse_Aiming" I "+Toggle_Crosshair" Scroll "+Holster_Weapon" @@ -7,4 +6,6 @@ C "+CrystalBall" P "+ProximityBombs" R "+RemoteBombs" X "+Alt_Fire" +J "+Jetpack" +M "+MedKit" Mouse2 "+Alt_Fire" diff --git a/wadsrc/static/filter/blood/demolition/leftbinds.txt b/wadsrc/static/filter/blood/demolition/leftbinds.txt index 463332ea4..6bd24ae48 100644 --- a/wadsrc/static/filter/blood/demolition/leftbinds.txt +++ b/wadsrc/static/filter/blood/demolition/leftbinds.txt @@ -1,8 +1,9 @@ // -Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" B "+BeastVision" C "+CrystalBall" P "+ProximityBombs" R "+RemoteBombs" X "+Alt_Fire" +J "+Jetpack" +M "+MedKit" diff --git a/wadsrc/static/filter/blood/demolition/origbinds.txt b/wadsrc/static/filter/blood/demolition/origbinds.txt index 5fe54e583..29c8ef5d5 100644 --- a/wadsrc/static/filter/blood/demolition/origbinds.txt +++ b/wadsrc/static/filter/blood/demolition/origbinds.txt @@ -1,5 +1,4 @@ // -Scroll "+Holster_Weapon" X "+Alt_Fire" W "+Show_Opponents_Weapon" B "+BeastVision" diff --git a/wadsrc/static/filter/duke/demolition/defbinds.txt b/wadsrc/static/filter/duke/demolition/defbinds.txt index c92a8f972..04f510ffb 100644 --- a/wadsrc/static/filter/duke/demolition/defbinds.txt +++ b/wadsrc/static/filter/duke/demolition/defbinds.txt @@ -5,7 +5,6 @@ H "+Holo_Duke" J "+Jetpack" N "+NightVision" M "+MedKit" -Scroll "+Holster_Weapon" X "+Last_Used_Weapon" C "+Toggle_Crouch" Mouse2 "+Jetpack" diff --git a/wadsrc/static/filter/duke/demolition/leftbinds.txt b/wadsrc/static/filter/duke/demolition/leftbinds.txt index 85e0ad3fc..953ecd791 100644 --- a/wadsrc/static/filter/duke/demolition/leftbinds.txt +++ b/wadsrc/static/filter/duke/demolition/leftbinds.txt @@ -4,5 +4,4 @@ Q "+Quick_Kick" J "+Jetpack" N "+NightVision" M "+MedKit" -Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" diff --git a/wadsrc/static/filter/duke/demolition/origbinds.txt b/wadsrc/static/filter/duke/demolition/origbinds.txt index 795737df9..62770c115 100644 --- a/wadsrc/static/filter/duke/demolition/origbinds.txt +++ b/wadsrc/static/filter/duke/demolition/origbinds.txt @@ -1,7 +1,6 @@ // R "+Steroids" ` "+Quick_Kick" -Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" H "+Holo_Duke" J "+Jetpack" diff --git a/wadsrc/static/filter/ionfury/demolition/defbinds.txt b/wadsrc/static/filter/ionfury/demolition/defbinds.txt index 760257501..1aba205c4 100644 --- a/wadsrc/static/filter/ionfury/demolition/defbinds.txt +++ b/wadsrc/static/filter/ionfury/demolition/defbinds.txt @@ -1,5 +1,4 @@ // -Scroll "+Holster_Weapon" X "+Last_Used_Weapon" C "+Toggle_Crouch" Mouse2 "+Jetpack" diff --git a/wadsrc/static/filter/ionfury/demolition/leftbinds.txt b/wadsrc/static/filter/ionfury/demolition/leftbinds.txt index 529143e4b..8b448ee89 100644 --- a/wadsrc/static/filter/ionfury/demolition/leftbinds.txt +++ b/wadsrc/static/filter/ionfury/demolition/leftbinds.txt @@ -1,2 +1 @@ -Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" diff --git a/wadsrc/static/filter/ionfury/demolition/origbinds.txt b/wadsrc/static/filter/ionfury/demolition/origbinds.txt index e46a2a16e..c3ac394e8 100644 --- a/wadsrc/static/filter/ionfury/demolition/origbinds.txt +++ b/wadsrc/static/filter/ionfury/demolition/origbinds.txt @@ -1,4 +1,3 @@ -Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" Mouse2 "+Jetpack" Mouse3 "+MediKit" diff --git a/wadsrc/static/filter/nam/demolition/defbinds.txt b/wadsrc/static/filter/nam/demolition/defbinds.txt index c92a8f972..04f510ffb 100644 --- a/wadsrc/static/filter/nam/demolition/defbinds.txt +++ b/wadsrc/static/filter/nam/demolition/defbinds.txt @@ -5,7 +5,6 @@ H "+Holo_Duke" J "+Jetpack" N "+NightVision" M "+MedKit" -Scroll "+Holster_Weapon" X "+Last_Used_Weapon" C "+Toggle_Crouch" Mouse2 "+Jetpack" diff --git a/wadsrc/static/filter/nam/demolition/leftbinds.txt b/wadsrc/static/filter/nam/demolition/leftbinds.txt index 85e0ad3fc..953ecd791 100644 --- a/wadsrc/static/filter/nam/demolition/leftbinds.txt +++ b/wadsrc/static/filter/nam/demolition/leftbinds.txt @@ -4,5 +4,4 @@ Q "+Quick_Kick" J "+Jetpack" N "+NightVision" M "+MedKit" -Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" diff --git a/wadsrc/static/filter/nam/demolition/origbinds.txt b/wadsrc/static/filter/nam/demolition/origbinds.txt index c97488acd..62770c115 100644 --- a/wadsrc/static/filter/nam/demolition/origbinds.txt +++ b/wadsrc/static/filter/nam/demolition/origbinds.txt @@ -1,7 +1,6 @@ // R "+Steroids" ` "+Quick_Kick" -Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" H "+Holo_Duke" J "+Jetpack" @@ -10,3 +9,5 @@ M "+MedKit" C "toggleconsole" Mouse2 "+Jetpack" Mouse3 "+MediKit" + + \ No newline at end of file diff --git a/wadsrc/static/filter/redneck/demolition/defbinds.txt b/wadsrc/static/filter/redneck/demolition/defbinds.txt index a322d4009..1abda301e 100644 --- a/wadsrc/static/filter/redneck/demolition/defbinds.txt +++ b/wadsrc/static/filter/redneck/demolition/defbinds.txt @@ -1,11 +1,9 @@ // -Scroll "+Holster_Weapon" -E "+Show_Opponents_Weapon" +V "+Show_Opponents_Weapon" B "+Holo_Duke" C "+Jetpack" Y "+NightVision" R "+MedKit" -+ "+Dpad_Select" M "+Steroids" Q "+Quick_Kick" X "+Last_Used_Weapon" diff --git a/wadsrc/static/filter/redneck/demolition/leftbinds.txt b/wadsrc/static/filter/redneck/demolition/leftbinds.txt index 2f58d2cb6..519dd5c20 100644 --- a/wadsrc/static/filter/redneck/demolition/leftbinds.txt +++ b/wadsrc/static/filter/redneck/demolition/leftbinds.txt @@ -1,4 +1,3 @@ -Scroll "+Holster_Weapon" E "+Show_Opponents_Weapon" M "+Steroids" Q "+Quick_Kick" diff --git a/wadsrc/static/filter/redneck/demolition/origbinds.txt b/wadsrc/static/filter/redneck/demolition/origbinds.txt index ba9d9f2e9..0fc752ee2 100644 --- a/wadsrc/static/filter/redneck/demolition/origbinds.txt +++ b/wadsrc/static/filter/redneck/demolition/origbinds.txt @@ -1,5 +1,4 @@ V "toggleconsole" -Scroll "+Holster_Weapon" E "+Show_Opponents_Weapon" M "+Steroids" ` "+Quick_Kick" diff --git a/wadsrc/static/filter/shadowwarrior/demolition/defbinds.txt b/wadsrc/static/filter/shadowwarrior/demolition/defbinds.txt index 50b79abaf..43932258a 100644 --- a/wadsrc/static/filter/shadowwarrior/demolition/defbinds.txt +++ b/wadsrc/static/filter/shadowwarrior/demolition/defbinds.txt @@ -1,7 +1,6 @@ // I "+Toggle_Crosshair" Mouse2 "+MediKit" -H "+Holster_Weapon" M "+MedKit" B "+Smoke_Bomb" N "+Nightvision" diff --git a/wadsrc/static/filter/shadowwarrior/demolition/leftbinds.txt b/wadsrc/static/filter/shadowwarrior/demolition/leftbinds.txt index a7122a63d..39c294001 100644 --- a/wadsrc/static/filter/shadowwarrior/demolition/leftbinds.txt +++ b/wadsrc/static/filter/shadowwarrior/demolition/leftbinds.txt @@ -1,7 +1,6 @@ M "+MedKit" -S "+Smoke_Bomb" +B "+Smoke_Bomb" N "+Nightvision" G "+Gas_Bomb" F "+Flash_Bomb" C "+Caltrops" -Scroll "+Holster_Weapon" diff --git a/wadsrc/static/filter/shadowwarrior/demolition/origbinds.txt b/wadsrc/static/filter/shadowwarrior/demolition/origbinds.txt index 677ef1342..91c5b3eef 100644 --- a/wadsrc/static/filter/shadowwarrior/demolition/origbinds.txt +++ b/wadsrc/static/filter/shadowwarrior/demolition/origbinds.txt @@ -5,4 +5,3 @@ G "+Gas_Bomb" F "+Flash_Bomb" C "+Caltrops" Mouse2 "+MediKit" -Scroll "+Holster_Weapon" diff --git a/wadsrc/static/filter/ww2gi/demolition/defbinds.txt b/wadsrc/static/filter/ww2gi/demolition/defbinds.txt index c92a8f972..04f510ffb 100644 --- a/wadsrc/static/filter/ww2gi/demolition/defbinds.txt +++ b/wadsrc/static/filter/ww2gi/demolition/defbinds.txt @@ -5,7 +5,6 @@ H "+Holo_Duke" J "+Jetpack" N "+NightVision" M "+MedKit" -Scroll "+Holster_Weapon" X "+Last_Used_Weapon" C "+Toggle_Crouch" Mouse2 "+Jetpack" diff --git a/wadsrc/static/filter/ww2gi/demolition/leftbinds.txt b/wadsrc/static/filter/ww2gi/demolition/leftbinds.txt index 85e0ad3fc..953ecd791 100644 --- a/wadsrc/static/filter/ww2gi/demolition/leftbinds.txt +++ b/wadsrc/static/filter/ww2gi/demolition/leftbinds.txt @@ -4,5 +4,4 @@ Q "+Quick_Kick" J "+Jetpack" N "+NightVision" M "+MedKit" -Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" diff --git a/wadsrc/static/filter/ww2gi/demolition/origbinds.txt b/wadsrc/static/filter/ww2gi/demolition/origbinds.txt index c97488acd..62770c115 100644 --- a/wadsrc/static/filter/ww2gi/demolition/origbinds.txt +++ b/wadsrc/static/filter/ww2gi/demolition/origbinds.txt @@ -1,7 +1,6 @@ // R "+Steroids" ` "+Quick_Kick" -Scroll "+Holster_Weapon" W "+Show_Opponents_Weapon" H "+Holo_Duke" J "+Jetpack" @@ -10,3 +9,5 @@ M "+MedKit" C "toggleconsole" Mouse2 "+Jetpack" Mouse3 "+MediKit" + + \ No newline at end of file From 41b116e2f2b847d7120372f082b3758d3cb6b97a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Nov 2019 22:46:00 +0100 Subject: [PATCH 062/203] - save menu in Duke Nukem is working. --- source/common/filesystem/filesystem.cpp | 3 +- source/common/menu/loadsavemenu.cpp | 5 +- source/common/menu/menu.cpp | 13 ++- source/common/menu/menu.h | 4 +- source/common/menu/messagebox.cpp | 2 +- source/common/menu/savegamemanager.cpp | 28 +++-- source/common/savegamehelp.cpp | 41 ++++--- source/common/savegamehelp.h | 1 - source/duke3d/src/savegame.cpp | 6 +- source/rr/src/savegame.cpp | 9 +- wadsrc/static/demolition/language.csv | 140 +++++++++++++++++++++++- 11 files changed, 204 insertions(+), 48 deletions(-) diff --git a/source/common/filesystem/filesystem.cpp b/source/common/filesystem/filesystem.cpp index 9525f6081..1a508f6d4 100644 --- a/source/common/filesystem/filesystem.cpp +++ b/source/common/filesystem/filesystem.cpp @@ -230,7 +230,8 @@ int FileSystem::CheckIfResourceFileLoaded (const char *name) noexcept { for (i = 0; i < Files.Size(); ++i) { - if (stricmp (GetResourceFileName (i), name) == 0) + auto pth = ExtractFileBase(GetResourceFileName(i), true); + if (stricmp (pth.GetChars(), name) == 0) { return i; } diff --git a/source/common/menu/loadsavemenu.cpp b/source/common/menu/loadsavemenu.cpp index f3d21487f..0ad22f5f9 100644 --- a/source/common/menu/loadsavemenu.cpp +++ b/source/common/menu/loadsavemenu.cpp @@ -57,8 +57,8 @@ class DLoadSaveMenu : public DListMenu protected: - int Selected; - int TopItem; + int Selected = 0; + int TopItem = 0; int savepicLeft; @@ -576,7 +576,6 @@ public: if (mSaveName.Len() > 0) { savegameManager.DoSave(Selected, mSaveName); - mSaveName = ""; } } diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index e16d7634c..5e9c4d96f 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -849,12 +849,17 @@ void M_Drawer (void) void M_ClearMenus () { M_DemoNoPlay = false; - if (DMenu::CurrentMenu != NULL) + transition.previous = transition.current = nullptr; + transition.dir = 0; + auto menu = DMenu::CurrentMenu; + while (menu != nullptr) { - DMenu::CurrentMenu->Destroy(); - delete DMenu::CurrentMenu; - DMenu::CurrentMenu = NULL; + auto nextm = menu->mParentMenu; + menu->Destroy(); + delete menu; + menu = nextm; } + DMenu::CurrentMenu = nullptr; menuactive = MENU_Off; GUICapture &= ~1; gi->MenuClosed(); diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 035cda2c6..8727f2767 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -816,8 +816,8 @@ public: void InsertNewSaveNode(); bool RemoveNewSaveNode(); - void LoadGame(FSaveGameNode* node, bool ok4q, bool forceq); - void SaveGame(FSaveGameNode* node); + void LoadGame(FSaveGameNode* node); + void SaveGame(FSaveGameNode* node, bool ok4q, bool forceq); }; diff --git a/source/common/menu/messagebox.cpp b/source/common/menu/messagebox.cpp index d0e75cd5d..06f59b59a 100644 --- a/source/common/menu/messagebox.cpp +++ b/source/common/menu/messagebox.cpp @@ -371,7 +371,7 @@ void M_StartMessage(const char *message, int messagemode, int scriptId, FName ac // //============================================================================= -DMenu* CreateMessageBoxMenu(DMenu* parent, const char* message, int messagemode, int scriptId, bool playsound, FName action = NAME_None, hFunc handler) +DMenu* CreateMessageBoxMenu(DMenu* parent, const char* message, int messagemode, int scriptId, bool playsound, FName action, hFunc handler) { auto newmenu = new DMessageBoxMenu(DMenu::CurrentMenu, message, messagemode, false, action, handler); newmenu->scriptID = scriptId; diff --git a/source/common/menu/savegamemanager.cpp b/source/common/menu/savegamemanager.cpp index 7a8b4ae67..694157f9e 100644 --- a/source/common/menu/savegamemanager.cpp +++ b/source/common/menu/savegamemanager.cpp @@ -55,19 +55,22 @@ FSavegameManager savegameManager; -void FSavegameManager::LoadGame(FSaveGameNode* node, bool ok4q, bool forceq) +void FSavegameManager::LoadGame(FSaveGameNode* node) { if (gi->LoadGame(node)) + { + } +} + +void FSavegameManager::SaveGame(FSaveGameNode* node, bool ok4q, bool forceq) +{ + if (gi->SaveGame(node)) { FString fn = node->Filename; FString desc = node->SaveTitle; NotifyNewSave(fn, desc, ok4q, forceq); } -} -void FSavegameManager::SaveGame(FSaveGameNode* node) -{ - gi->SaveGame(node); } //============================================================================= @@ -196,6 +199,7 @@ void FSavegameManager::ReadSaveStrings() auto fr = info->NewReader(); FString title; int check = G_ValidateSavegame(fr, &title); + fr.Close(); delete savegame; if (check != 0) { @@ -299,7 +303,7 @@ void FSavegameManager::DoSave(int Selected, const char *savegamestring) { auto node = *SaveGames[Selected]; node.SaveTitle = savegamestring; - savegameManager.SaveGame(&node); + savegameManager.SaveGame(&node, true, false); } else { @@ -316,7 +320,7 @@ void FSavegameManager::DoSave(int Selected, const char *savegamestring) } } FSaveGameNode sg{ savegamestring, filename }; - savegameManager.SaveGame(&sg); + savegameManager.SaveGame(&sg, true, false); } M_ClearMenus(); } @@ -501,7 +505,7 @@ FSaveGameNode *FSavegameManager::GetSavegame(int i) void FSavegameManager::InsertNewSaveNode() { - NewSaveNode.SaveTitle = GStrings["NEWSAVE"]; + NewSaveNode.SaveTitle = GStrings("NEWSAVE"); NewSaveNode.bNoDelete = true; SaveGames.Insert(0, &NewSaveNode); } @@ -571,7 +575,7 @@ void M_Autosave() readableTime = myasctime(); sg.SaveTitle.Format("Autosave %s", readableTime); nextautosave = (nextautosave + 1) % count; - savegameManager.SaveGame(&sg); + savegameManager.SaveGame(&sg, false, false); } CCMD(autosave) @@ -603,7 +607,7 @@ CCMD(rotatingquicksave) readableTime = myasctime(); sg.SaveTitle.Format("Quicksave %s", readableTime); nextquicksave = (nextquicksave + 1) % count; - savegameManager.SaveGame(&sg); + savegameManager.SaveGame(&sg, false, false); } @@ -629,7 +633,7 @@ CCMD(quicksave) // [mxd]. Just save the game, no questions asked. if (!saveloadconfirmation) { - savegameManager.SaveGame(savegameManager.quickSaveSlot); + savegameManager.SaveGame(savegameManager.quickSaveSlot, true, true); return; } @@ -642,7 +646,7 @@ CCMD(quicksave) { if (res) { - savegameManager.SaveGame(savegameManager.quickSaveSlot); + savegameManager.SaveGame(savegameManager.quickSaveSlot, true, true); } }); diff --git a/source/common/savegamehelp.cpp b/source/common/savegamehelp.cpp index b0eae5d96..7061245ff 100644 --- a/source/common/savegamehelp.cpp +++ b/source/common/savegamehelp.cpp @@ -126,10 +126,16 @@ void G_WriteSaveHeader(const char *name, const char*mapname, const char *maptitl sjson_put_int(ctx, root, "Save Version", savesig.currentsavever); sjson_put_string(ctx, root, "Engine", savesig.savesig); sjson_put_string(ctx, root, "Game Resource", fileSystem.GetResourceFileName(1)); - sjson_put_string(ctx, root, "map", mapname); - sjson_put_string(ctx, root, "Title", maptitle); + sjson_put_string(ctx, root, "Map Name", maptitle); + sjson_put_string(ctx, root, "Title", name); if (*mapname == '/') mapname++; - sjson_put_string(ctx, root, "Map Resource", mapname); + sjson_put_string(ctx, root, "Map File", mapname); + auto fileno = fileSystem.FindFile(mapname); + auto mapfile = fileSystem.GetFileContainer(fileno); + auto mapcname = fileSystem.GetResourceFileName(mapfile); + if (mapcname) sjson_put_string(ctx, root, "Map Resource", mapcname); + else return; // this should never happen. Saving on a map that isn't present is impossible. + char* encoded = sjson_stringify(ctx, root, " "); @@ -188,13 +194,11 @@ static bool CheckSingleFile (const char *name, bool &printRequires, bool printwa // //============================================================================= -bool G_CheckSaveGameWads (sjson_node* root, bool printwarn) +static bool G_CheckSaveGameWads (const char *gamegrp, const char *mapgrp, bool printwarn) { bool printRequires = false; - auto text = sjson_get_string(root, "Game Resource", ""); - CheckSingleFile (text, printRequires, printwarn); - text = sjson_get_string(root, "MAP Resource", ""); - CheckSingleFile (text, printRequires, printwarn); + CheckSingleFile (gamegrp, printRequires, printwarn); + CheckSingleFile (mapgrp, printRequires, printwarn); if (printRequires) { @@ -228,6 +232,7 @@ int G_ValidateSavegame(FileReader &fr, FString *savetitle) int savever = sjson_get_int(root, "Save Version", -1); FString engine = sjson_get_string(root, "Engine", ""); FString gamegrp = sjson_get_string(root, "Game Resource", ""); + FString mapgrp = sjson_get_string(root, "Map Resource", ""); FString title = sjson_get_string(root, "Title", ""); auto savesig = gi->GetSaveSig(); @@ -241,22 +246,27 @@ int G_ValidateSavegame(FileReader &fr, FString *savetitle) return 0; } + if (savever < savesig.minsavever) { // old, incompatible savegame. List as not usable. return -1; } - else if (gamegrp.CompareNoCase(fileSystem.GetResourceFileName(1)) == 0) - { - return G_CheckSaveGameWads(root, false)? 0 : -2; - } else { - // different game. Skip this. - return 0; + auto ggfn = ExtractFileBase(fileSystem.GetResourceFileName(1), true); + if (gamegrp.CompareNoCase(ggfn) == 0) + { + return G_CheckSaveGameWads(gamegrp, mapgrp, false) ? 1 : -2; + } + else + { + // different game. Skip this. + return 0; + } } } - return 1; + return 0; } //============================================================================= @@ -277,7 +287,6 @@ FString G_BuildSaveName (const char *prefix) if (!strchr(prefix, '.')) name << SAVEGAME_EXT; // only add an extension if the prefix doesn't have one already. name = NicePath(name); name.Substitute("\\", "/"); - CreatePath(name); return name; } diff --git a/source/common/savegamehelp.h b/source/common/savegamehelp.h index 78c368e1f..5410a54ee 100644 --- a/source/common/savegamehelp.h +++ b/source/common/savegamehelp.h @@ -15,7 +15,6 @@ void FinishSavegameRead(); class FileReader; FString G_BuildSaveName (const char *prefix); -bool G_CheckSaveGameWads (struct sjson_node* root, bool printwarn); int G_ValidateSavegame(FileReader &fr, FString *savetitle); void G_WriteSaveHeader(const char *name, const char*mapname, const char *title); diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index b5b986209..4ca22833e 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -594,8 +594,7 @@ bool G_SavePlayer(FSaveGameNode *sv) errno = 0; FileWriter *fil; - fn = G_BuildSaveName(sv->Filename); - OpenSaveGameForWrite(fn); + OpenSaveGameForWrite(sv->Filename); fil = WriteSavegameChunk("snapshot.dat"); // The above call cannot fail. { @@ -1490,7 +1489,8 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i auto fw = WriteSavegameChunk("header.dat"); fw->Write(&h, sizeof(savehead_t)); - G_WriteSaveHeader(name, currentboardfilename, g_mapInfo[(MAXLEVELS * ud.volume_number) + ud.level_number].name); + auto& mi = g_mapInfo[(MAXLEVELS * ud.volume_number) + ud.level_number]; + G_WriteSaveHeader(name, mi.filename, mi.name); } else { diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index bfab8e3a8..c5cd7aa4f 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -342,8 +342,7 @@ bool G_SavePlayer(FSaveGameNode *sv) errno = 0; FileWriter *fil; - fn = G_BuildSaveName(sv->Filename); - OpenSaveGameForWrite(fn); + OpenSaveGameForWrite(sv->Filename); fil = WriteSavegameChunk("snapshot.dat"); // The above call cannot fail. { @@ -402,6 +401,7 @@ bool GameInterface::SaveGame(FSaveGameNode* sv) { Bstrcpy(apStrings[QUOTE_RESERVED4], "Multiplayer Saving Not Yet Supported"); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); + return false; } else { @@ -411,7 +411,7 @@ bool GameInterface::SaveGame(FSaveGameNode* sv) G_DrawRooms(myconnectindex, 65536); g_screenCapture = 0; - G_SavePlayer(sv); + return G_SavePlayer(sv); } } @@ -1179,7 +1179,8 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i auto fw = WriteSavegameChunk("header.dat"); fw->Write(&h, sizeof(savehead_t)); - G_WriteSaveHeader(name, currentboardfilename, g_mapInfo[(MAXLEVELS * ud.volume_number) + ud.level_number].name); + auto& mi = g_mapInfo[(MAXLEVELS * ud.volume_number) + ud.level_number]; + G_WriteSaveHeader(name, mi.filename, mi.name); } else { diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index 4ddf96f7c..fcd7b65f3 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -72,4 +72,142 @@ Carrega numa tecla qualquer.",,"Невозможно сохранить игру Притисните тастер." Do you really want to do this?,SAFEMESSAGE,,,,Vážně to chceš udělat?,Möchtest du das wirklich tun?,,Ĉu vi vere volas fari tion?,¿Realmente quieres hacer esto?,¿Realmente quieres hacerlo?,Haluatko varmasti tehdä tämän?,Voulez-vous vraiment faire ça?,Biztos megakarod tenni?,Sei sicuro di volerlo fare?,本当に実行するのか?,정말로 정하시겠습니까?,Wil je dit echt doen?,Naprawdę chcesz to zrobić?,Você deseja mesmo fazer isso?,Desejas mesmo fazer isso?,,Вы уверены?,Да ли заиста желите то да урадите? -Not set,NOTSET,,,,Není nastavené,Nicht gesetzt,,Ne agordita,No Asignado,,Ei asetettu,Pas paramétré,Nincs beállítva,Non assegnato,セットされてない,정하지 않음,Niet ingesteld,Nie ustawiono,Não definido,,,Не задан,Није намештено \ No newline at end of file +Not set,NOTSET,,,,Není nastavené,Nicht gesetzt,,Ne agordita,No Asignado,,Ei asetettu,Pas paramétré,Nincs beállítva,Non assegnato,セットされてない,정하지 않음,Niet ingesteld,Nie ustawiono,Não definido,,,Не задан,Није намештено +"Quicksave over your game named + +'%s'? + +Press Y or N.",QSPROMPT,,,,"Rychle uložit přes tvoji hru s názvem + +'%s'? + +Stiskni Y nebo N.","Überschreibe %s mit einem Schnellspeicherspielstand? + +Drücke Y oder N.",,"Ĉu rapidkonservu super via ludo, ke nomita + +'%s'? + +Premu Y aŭ N.","¿Deseas guardar sobre tu partida llamada + +'%s'? + +Presiona Y ó N.",,"Haluatko tallentaa pelin %s päälle? + +Paina Y tai N.","Sauvegarde rapide sur le fichier + +'%s'? + +Appuyez sur Y ou N.","Gyorsmenteni akarsz az alábbi mentésed alatt + +'%s'? + +Nyomj Y-t vagy N-t.","Sovrascrivere il salvataggio + +'%s'? + +Premi Y oppure N.","この名前で上書きするのか? + +'%s' + +Y か N で答えろ","빠른 저장을 하시겠습니까? + +'%s' + +Y키 또는 N키를 누르시오.","Snel opslaan over je spel genaamd + +'%s'? + +Druk op Y of N.","Szybko nadpisać grę + +„%s”? + +Wciśnij Y lub N.","Salvar sobre seu jogo chamado + +'%s'? + +Aperte Y ou N.","Gravar sobre o seu jogo chamado + +'%s'? + +Carrega Y ou N.",,"Перезаписать быстрое сохранение + +«%s»? + +Нажмите Y или N.","Желите брзо чување за игру под именом + +„%s“? + +Притисните Y или N." +"Do you want to quickload the game named + +'%s'? + +Press Y or N.",QLPROMPT,,,,"Přeješ si rychle načíst hru s názvem + +'%s'? + +Stiskni Y nebo N.","Möchtest du den Spielstand %s schnellladen? + +Drücke Y oder N.",,"Ĉu vi volas rapidŝargi la ludon, ke nomita + +'%s'? + +Premu Y aŭ N.","¿Quieres cargar la partida llamada + +'%s'? + +Presiona Y ó N.",,"Haluatko pikaladata pelin %s? + +Paina Y tai N.","Voulez-vous charger la sauvegarde + +'%s'? + +Appuyez sur Y ou N.","Gyorstölteni akarod ezt a mentést + +'%s'? + +Nyomj Y-t vagy N-t.","Vuoi fare un quickload della partita + +'%s'? + +Premi Y oppure N.","この名前のデータをロードするのか? + +'%s' + +Y か N で答えろ","빠른 불러오기를 하시겠습니까? + +'%s' + +Y키 또는 N키를 누르시오.","Wil je het spel snel laden met de naam + +'%s'? + +Druk op Y of N.","Czy chcesz wczytać szybki zapis + +„%s”? + +Wciśnij Y lub N.","Deseja carregar o jogo chamado + +'%s'? + +Aperte Y ou N.","Deseja carregar o jogo chamado + +'%s'? + +Carrega Y ou N.",,"Загрузить быстрое сохранение + +«%s»? + +Нажмите Y или N.","Желите брзо учитавање за игру под именом + +„%s“? + +Притисните Y или N." +Yes,TXT_YES,,,,Ano,Ja,Ναι,Jes,Sí,,Kyllä,Oui,Igen,Si,はい,네,Ja,Tak,Sim,,,Да,Да +No,TXT_NO,,,,Ne,Nein,Όχι,Ne,No,,Ei,Non,Nem,No,いいえ,아니요,Nee,Nie,Não,,,Нет,Не +,,Savegame,,,,,,,,,,,,,,,,,,,,, +Empty slot,EMPTYSTRING,,,,Prázdný slot,nicht belegt,,Malplena Ingo,Ranura Vacía,,Tyhjä lokero,Emplacement Vide,Üres,Slot libero,空きスロット,빈 슬롯,Lege sleuf,Puste miejsce,Vazio,,,Пустой слот,Празни слот +,NEWSAVE,,,,,,,,,,,,<Új mentés>,,<新規セーブ>,<새로운 게임 저장>,,,,,,<Новое сохранение>,<Нова сачувана игра> +Game saved.,GGSAVED,,,,Hra uložena.,Spielstand gespeichert.,,Ludo konservita.,Partida guardada.,,Peli tallennettu.,Partie sauvegardée.,Játék mentve.,Gioco salvato.,セーブ完了。,게임이 저장됨.,Spel opgeslagen.,Gra zapisana.,Jogo salvo.,Jogo gravado.,,Игра сохранена.,Игра сачувана. +Time,SAVECOMMENT_TIME,,,,Čas,Zeit,,Tempo,Tiempo,,Aika,Temps,Idő,Tempo,"時間 +",시간,Tijd,Czas,Tempo,,,Время,Време \ No newline at end of file From c36402eb5c1cab3792fb20fb4e28017d1eaf57ac Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Nov 2019 23:33:04 +0100 Subject: [PATCH 063/203] - fixed savegame validation and recursive ticker calls. --- source/build/src/timer.cpp | 7 +++++++ source/common/menu/savegamemanager.cpp | 24 +++++++++++++++--------- source/duke3d/src/savegame.cpp | 2 +- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/source/build/src/timer.cpp b/source/build/src/timer.cpp index 0d1b343fa..8fc00ade3 100644 --- a/source/build/src/timer.cpp +++ b/source/build/src/timer.cpp @@ -52,10 +52,17 @@ ATTRIBUTE((flatten)) void timerUpdateClock(void) totalclock += n; timerlastsample += n*nanoseconds(1000000000/timerticspersec); + // This function can get called from deep within processing loops. + // The callbacks in here may not be called recursively, though. + static bool recursion; + if (recursion) return; + recursion = true; + for (; n > 0; n--) { for (auto cb : callbacks) cb(); } + recursion = false; } void(*timerSetCallback(void(*callback)(void)))(void) diff --git a/source/common/menu/savegamemanager.cpp b/source/common/menu/savegamemanager.cpp index 694157f9e..75cedfbe8 100644 --- a/source/common/menu/savegamemanager.cpp +++ b/source/common/menu/savegamemanager.cpp @@ -205,8 +205,8 @@ void FSavegameManager::ReadSaveStrings() { FSaveGameNode *node = new FSaveGameNode; node->Filename = filepath; - node->bOldVersion = true; - node->bMissingWads = false; + node->bOldVersion = check == -1; + node->bMissingWads = check == -2; node->SaveTitle = title; InsertSaveNode(node); } @@ -281,13 +281,17 @@ void FSavegameManager::NotifyNewSave(const FString &file, const FString &title, void FSavegameManager::LoadSavegame(int Selected) { - savegameManager.LoadGame(SaveGames[Selected]); - if (quickSaveSlot == (FSaveGameNode*)1) + auto sel = savegameManager.GetSavegame(Selected); + if (sel && !sel->bOldVersion && !sel->bMissingWads) { - quickSaveSlot = SaveGames[Selected]; + savegameManager.LoadGame(SaveGames[Selected]); + if (quickSaveSlot == (FSaveGameNode*)1) + { + quickSaveSlot = SaveGames[Selected]; + } + M_ClearMenus(); + LastAccessed = Selected; } - M_ClearMenus(); - LastAccessed = Selected; } @@ -365,6 +369,7 @@ unsigned FSavegameManager::ExtractSaveData(int index) } auto fr = info->NewReader(); auto data = fr.ReadPadded(1); + fr.Close(); sjson_context* ctx = sjson_create_context(0, 0, NULL); if (ctx) { @@ -372,8 +377,9 @@ unsigned FSavegameManager::ExtractSaveData(int index) FString comment = sjson_get_string(root, "Creation Time", ""); - FString pcomment = sjson_get_string(root, "Comment", ""); - if (comment.Len() > 0) comment += "\n"; + FString fcomment = sjson_get_string(root, "Map File", ""); + FString ncomment = sjson_get_string(root, "Map Name", ""); + FStringf pcomment("%s - %s\n", fcomment.GetChars(), ncomment.GetChars()); comment += pcomment; SaveCommentString = comment; diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index 4ca22833e..72d746177 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -665,7 +665,7 @@ bool GameInterface::SaveGame(FSaveGameNode* sv) { videoNextPage(); // no idea if this is needed here. g_screenCapture = 1; - G_DrawRooms(myconnectindex, 65536); + //G_DrawRooms(myconnectindex, 65536); g_screenCapture = 0; return G_SavePlayer(sv); From 06d5705ae61f627410e4934e99f0a4c9e0858683 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Nov 2019 23:45:43 +0100 Subject: [PATCH 064/203] - formatting fix and null check for aborted transition. --- source/common/menu/imagescroller.cpp | 2 +- source/common/menu/loadsavemenu.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source/common/menu/imagescroller.cpp b/source/common/menu/imagescroller.cpp index 8fabd1360..8193ab80b 100644 --- a/source/common/menu/imagescroller.cpp +++ b/source/common/menu/imagescroller.cpp @@ -112,7 +112,7 @@ bool DImageScrollerMenu::MenuEvent(int mkey, bool fromcontroller) case MKEY_Back: // Before going back the currently running transition must be terminated. pageTransition.previous = nullptr; - pageTransition.current->origin = { 0,0 }; + if (pageTransition.current) pageTransition.current->origin = { 0,0 }; return DMenu::MenuEvent(mkey, fromcontroller); case MKEY_Left: diff --git a/source/common/menu/loadsavemenu.cpp b/source/common/menu/loadsavemenu.cpp index 0ad22f5f9..4e7ba7291 100644 --- a/source/common/menu/loadsavemenu.cpp +++ b/source/common/menu/loadsavemenu.cpp @@ -130,7 +130,8 @@ protected: commentHeight = listboxHeight - savepicHeight - (16 * wScale); commentRight = commentLeft + commentWidth; commentBottom = commentTop + commentHeight; - commentRows = commentHeight / rowHeight; + commentRows = commentHeight / rowHeight; + UpdateSaveComment(); } //============================================================================= @@ -252,7 +253,7 @@ protected: void UpdateSaveComment() { - //BrokenSaveComment = NewConsoleFont.BreakLines(manager.SaveCommentString, int(commentWidth / FontScale)); + BrokenSaveComment = V_BreakLines(NewConsoleFont, int(commentWidth / FontScale), savegameManager.SaveCommentString); } //============================================================================= From 0fc439a96913d2cbb8cdccf5bd96f099e3c81dde Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Nov 2019 23:59:22 +0100 Subject: [PATCH 065/203] - fixed Redneck Rampage ingame menu and added selection validation to the load menu. --- source/common/menu/loadsavemenu.cpp | 1 + source/rr/src/d_menu.cpp | 1 + wadsrc/static/demolition/menudef.txt | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source/common/menu/loadsavemenu.cpp b/source/common/menu/loadsavemenu.cpp index 4e7ba7291..3c59597b5 100644 --- a/source/common/menu/loadsavemenu.cpp +++ b/source/common/menu/loadsavemenu.cpp @@ -165,6 +165,7 @@ protected: if (savegameManager.SavegameCount() > 0) { + if (Selected > savegameManager.SavegameCount()) Selected = 0; FString text = (Selected == -1 || !savegameManager.GetSavegame(Selected)->bOldVersion) ? GStrings("MNU_NOPICTURE") : GStrings("MNU_DIFFVERSION"); int textlen = NewSmallFont->StringWidth(text) * CleanXfac; diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index 6800fefe1..974c3d8f7 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -151,6 +151,7 @@ static void Menu_DrawTopBar(const DVector2 &origin) static void Menu_DrawTopBarCaption(const char* caption, const DVector2& origin) { static char t[64]; + if (*caption == '$') caption = GStrings(caption + 1); size_t const srclen = strlen(caption); size_t const dstlen = min(srclen, ARRAY_SIZE(t) - 1); memcpy(t, caption, dstlen); diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index a369d6835..ad6dabc68 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -74,7 +74,7 @@ LISTMENU "MainMenu" LISTMENU "IngameMenu" { ScriptId 50 - ifgame(Duke, Nam, WW2GI, Fury) + ifgame(Duke, Nam, WW2GI, Fury, Redneck, RedneckRides) { ifgame(fury) { @@ -121,7 +121,7 @@ LISTMENU "IngameMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" - NativeTextItem "$MNU_COOLSTUFF", "h", "HelpMenu" + NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" } } From 79fd4e830a6437fdc9fb83836281341f11fe2512 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2019 08:23:35 +0100 Subject: [PATCH 066/203] - removed the code for Doom's help screens. --- source/CMakeLists.txt | 1 - source/common/menu/menu.cpp | 4 +- source/common/menu/readthis.cpp | 147 -------------------------------- 3 files changed, 2 insertions(+), 150 deletions(-) delete mode 100644 source/common/menu/readthis.cpp diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index ded88484d..7d9fa2135 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -837,7 +837,6 @@ set (PCH_SOURCES common/menu/menuinput.cpp common/menu/messagebox.cpp common/menu/optionmenu.cpp - common/menu/readthis.cpp ) if( MSVC ) diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 5e9c4d96f..eae10b9ad 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -67,7 +67,8 @@ CVAR (Float, mouse_sensitivity, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) EXTERN_CVAR (Bool, show_messages) -CVAR (Float, snd_menuvolume, 0.6f, CVAR_ARCHIVE) +CVAR(Bool, menu_sounds, true, CVAR_ARCHIVE) // added mainly because RR's sounds are so supremely annoying. +//CVAR (Float, snd_menuvolume, 0.6f, CVAR_ARCHIVE) the current sound engine cannot deal with this. CVAR(Int, m_use_mouse, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Int, m_show_backbutton, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) @@ -874,7 +875,6 @@ void Menu_Close(int playerid) // // //============================================================================= -CVAR(Bool, menu_sounds, true, CVAR_ARCHIVE) // added mainly because RR's sounds are so supremely annoying. void M_MenuSound(EMenuSounds snd) { diff --git a/source/common/menu/readthis.cpp b/source/common/menu/readthis.cpp deleted file mode 100644 index c68cf5751..000000000 --- a/source/common/menu/readthis.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* -** readthis.cpp -** Help screens -** -**--------------------------------------------------------------------------- -** Copyright 2001-2010 Randy Heit -** Copyright 2010 Christoph Oelckers -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#include "menu/menu.h" -#include "v_draw.h" -#include "textures/textures.h" - -#if 0 // This is probably useless. To be replaced with what Build games use to draw their help screens. - -class DReadThisMenu : public DMenu -{ - int mScreen; - int mInfoTic; - -public: - - DReadThisMenu(DMenu *parent = NULL); - void Drawer(); - bool MenuEvent(int mkey, bool fromcontroller); - bool DimAllowed () { return false; } - bool MouseEvent(int type, int x, int y); -}; - - -//============================================================================= -// -// Read This Menus -// -//============================================================================= - -DReadThisMenu::DReadThisMenu(DMenu *parent) -: DMenu(parent) -{ - mScreen = 1; - mInfoTic = gametic; -} - - -//============================================================================= -// -// -// -//============================================================================= - -void DReadThisMenu::Drawer() -{ - FTexture *tex = NULL, *prevpic = NULL; - fixed_t alpha; - - // Did the mapper choose a custom help page via MAPINFO? - if ((level.info != NULL) && level.info->F1Pic.Len() != 0) - { - tex = TexMan.FindTexture(level.info->F1Pic); - mScreen = 1; - } - - if (tex == NULL) - { - tex = TexMan[gameinfo.infoPages[mScreen-1].GetChars()]; - } - - if (mScreen > 1) - { - prevpic = TexMan[gameinfo.infoPages[mScreen-2].GetChars()]; - } - - screen->Dim(0, 1.0, 0,0, SCREENWIDTH, SCREENHEIGHT); - alpha = MIN (Scale (gametic - mInfoTic, OPAQUE, TICRATE/3), OPAQUE); - if (alpha < OPAQUE && prevpic != NULL) - { - screen->DrawTexture (prevpic, 0, 0, DTA_Fullscreen, true, TAG_DONE); - } - screen->DrawTexture (tex, 0, 0, DTA_Fullscreen, true, DTA_Alpha, alpha, TAG_DONE); - -} - - -//============================================================================= -// -// -// -//============================================================================= - -bool DReadThisMenu::MenuEvent(int mkey, bool fromcontroller) -{ - if (mkey == MKEY_Enter) - { - S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); - mScreen++; - mInfoTic = gametic; - if ((level.info != NULL && level.info->F1Pic.Len() != 0) || mScreen > int(gameinfo.infoPages.Size())) - { - Close(); - } - return true; - } - else return Super::MenuEvent(mkey, fromcontroller); -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DReadThisMenu::MouseEvent(int type, int x, int y) -{ - if (type == MOUSE_Click) - { - return MenuEvent(MKEY_Enter, true); - } - return false; -} - -#endif \ No newline at end of file From d8c74a8b00e272ccb06aeadd4c736c592d06544c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2019 08:25:24 +0100 Subject: [PATCH 067/203] - don't show the map name when the menu is active Since it uses the same font this causes ugly visual clashes. --- source/duke3d/src/screens.cpp | 2 +- source/rr/src/screens.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index fb0b9593f..32c676db4 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -984,7 +984,7 @@ void G_DisplayRest(int32_t smoothratio) G_PrintGameQuotes(screenpeek); - if (ud.show_level_text && hud_showmapname && g_levelTextTime > 1) + if (ud.show_level_text && hud_showmapname && g_levelTextTime > 1 && DMenu::CurrentMenu == nullptr) { int32_t o = 10|16; diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index 2c2eb268a..e4cbafa46 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -1015,7 +1015,7 @@ void G_DisplayRest(int32_t smoothratio) G_PrintGameQuotes(screenpeek); - if (ud.show_level_text && hud_showmapname && g_levelTextTime > 1) + if (ud.show_level_text && hud_showmapname && g_levelTextTime > 1 && DMenu::CurrentMenu == nullptr) { int32_t o = 10|16; From 8a98f9b3cac3bca15057b7c68fd365ed3d338c4b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2019 09:02:17 +0100 Subject: [PATCH 068/203] - removed quitevent. This was some meticulously preserved relic of bad old DOS times used to block OS facilities to close an app. Since this has been worked around at a lower level already the variable was essentially without function but some quite bad code depended on it. --- source/blood/src/blood.cpp | 6 +----- source/blood/src/demo.cpp | 23 +++-------------------- source/blood/src/network.cpp | 6 +++++- source/build/include/baselayer.h | 2 +- source/build/src/defs.cpp | 1 - source/build/src/sdlayer.cpp | 2 +- source/duke3d/src/game.cpp | 14 +------------- source/platform/win32/startwin.game.cpp | 2 -- source/rr/src/game.cpp | 14 +------------- source/sw/src/anim.cpp | 4 ++-- source/sw/src/game.cpp | 14 +------------- source/sw/src/network.cpp | 2 +- 12 files changed, 17 insertions(+), 73 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 9f7320fb4..5e9f70636 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -1291,11 +1291,7 @@ RESTART: ready2send = 1; while (!gQuitGame) { - if (handleevents() && quitevent) - { - inputState.SetKeyStatus(sc_Escape, 1); - quitevent = 0; - } + handleevents(); netUpdate(); MUSIC_Update(); inputState.SetBindsEnabled(gInputMode == kInputGame); diff --git a/source/blood/src/demo.cpp b/source/blood/src/demo.cpp index 6b1eb8c11..202ebc661 100644 --- a/source/blood/src/demo.cpp +++ b/source/blood/src/demo.cpp @@ -49,6 +49,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "i_specialpaths.h" #include "view.h" #include "gamecontrol.h" +#include "menu/menu.h" BEGIN_BLD_NS @@ -293,14 +294,7 @@ void CDemo::ProcessKeys(void) { switch (nKey) { - case 1: - if (!CGameMenuMgr::m_bActive) - { - gGameMenuMgr.Push(&menuMain, -1); - at2 = 1; - } - break; - case 0x58: + case sc_F12: gViewIndex = connectpoint2[gViewIndex]; if (gViewIndex == -1) gViewIndex = connecthead; @@ -321,21 +315,12 @@ void CDemo::Playback(void) inputState.SetBindsEnabled(false); ready2send = 0; int v4 = 0; - if (!CGameMenuMgr::m_bActive) - { - gGameMenuMgr.Push(&menuMain, -1); - at2 = 1; - } gNetFifoClock = totalclock; gViewMode = 3; _DEMOPLAYBACK: while (at1 && !gQuitGame) { - if (handleevents() && quitevent) - { - inputState.SetKeyStatus(sc_Escape, 1); - quitevent = 0; - } + handleevents(); MUSIC_Update(); while (totalclock >= gNetFifoClock && !gQuitGame) { @@ -407,8 +392,6 @@ _DEMOPLAYBACK: if (G_FPSLimit()) { viewDrawScreen(); - if (gInputMode == kInputMenu && CGameMenuMgr::m_bActive) - gGameMenuMgr.Draw(); videoNextPage(); } if (TestBitString(gotpic, 2342)) diff --git a/source/blood/src/network.cpp b/source/blood/src/network.cpp index 1e6242d79..0310bfb4f 100644 --- a/source/blood/src/network.cpp +++ b/source/blood/src/network.cpp @@ -542,7 +542,7 @@ void netGetPackets(void) gStartNewGame = 1; break; case 255: - inputState.SetKeyStatus(sc_Escape, 1); + inputState.SetKeyStatus(sc_Escape); break; } } @@ -1007,11 +1007,13 @@ void netInitialize(bool bConsole) while (numplayers < gNetPlayers) { handleevents(); +#if 0 if (quitevent) { netServerDisconnect(); QuitGame(); } +#endif if (!bConsole && inputState.GetKeyStatus(sc_Escape)) { netServerDisconnect(); @@ -1168,11 +1170,13 @@ void netInitialize(bool bConsole) while (bWaitServer) { handleevents(); +#if 0 if (quitevent) { netClientDisconnect(); QuitGame(); } +#endif if (!bConsole && inputState.GetKeyStatus(sc_Escape)) { netClientDisconnect(); diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 2e5449598..40f147f5f 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -22,7 +22,7 @@ extern int32_t g_maskDrawMode; #endif -extern char quitevent, appactive; +extern char appactive; extern char modechange; extern char nogl; diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index 0d0577e4f..872e2c299 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -306,7 +306,6 @@ static int32_t defsparser(scriptfile *script) } #endif handleevents(); - if (quitevent) return 0; tokn = getatoken(script,basetokens,ARRAY_SIZE(basetokens)); cmdtokptr = script->ltextptr; switch (tokn) diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index 65f3bb8ab..84d0badb0 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -100,7 +100,7 @@ unsigned char syncstate; int32_t inputchecked = 0; bool screenshot_requested; -char quitevent=0, appactive=1, novideo=0; +char appactive=1, novideo=0; // video static SDL_Surface *sdl_surface/*=NULL*/; diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index ec3c682a4..423e61e69 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -5720,12 +5720,6 @@ static void G_Startup(void) for (i=0; i 1) @@ -6031,8 +6025,6 @@ int GameInterface::app_main() system_getcvars(); - if (quitevent) return 4; - if (g_networkMode != NET_DEDICATED_SERVER && validmodecnt > 0) { if (videoSetGameMode(ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP, 1) < 0) @@ -6195,11 +6187,7 @@ MAIN_LOOP_RESTART: do //main loop { - if (gameHandleEvents() && quitevent) - { - inputState.SetKeyStatus(sc_Escape, 1); - quitevent = 0; - } + gameHandleEvents(); // only allow binds to function if the player is actually in a game (not in a menu, typing, et cetera) or demo inputState.SetBindsEnabled(!!(myplayer.gm & (MODE_GAME|MODE_DEMO))); diff --git a/source/platform/win32/startwin.game.cpp b/source/platform/win32/startwin.game.cpp index 60d387675..592c93ecc 100644 --- a/source/platform/win32/startwin.game.cpp +++ b/source/platform/win32/startwin.game.cpp @@ -432,7 +432,6 @@ static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, case WM_CLOSE: if (mode == TAB_CONFIG) done = 0; - else quitevent++; return TRUE; case WM_DESTROY: @@ -456,7 +455,6 @@ static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, { case WIN_STARTWIN_CANCEL: if (mode == TAB_CONFIG) done = 0; - else quitevent++; return TRUE; case WIN_STARTWIN_START: done = 1; diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 07336cd03..9456c3d0a 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -7157,12 +7157,6 @@ static void G_Startup(void) for (i=0; i 1) @@ -7416,8 +7410,6 @@ int GameInterface::app_main() i = 1-i; } - if (quitevent) return 4; - Anim_Init(); const char *defsfile = G_DefFile(); @@ -7628,11 +7620,7 @@ MAIN_LOOP_RESTART: do //main loop { - if (handleevents() && quitevent) - { - inputState.SetKeyStatus(sc_Escape, 1); - quitevent = 0; - } + handleevents(); Net_GetPackets(); diff --git a/source/sw/src/anim.cpp b/source/sw/src/anim.cpp index 052822e0c..aec81d051 100644 --- a/source/sw/src/anim.cpp +++ b/source/sw/src/anim.cpp @@ -320,12 +320,12 @@ playanm(short anim_num) switch (ANIMnum) { case ANIM_INTRO: - if (I_GeneralTrigger() || quitevent) + if (I_GeneralTrigger()) I_GeneralTriggerClear(); goto ENDOFANIMLOOP; break; case ANIM_SERP: - if (I_EscapeTrigger() || quitevent) + if (I_EscapeTrigger()) I_EscapeTriggerClear(); goto ENDOFANIMLOOP; break; diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index d6a40a641..308a68e8f 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -842,11 +842,6 @@ void InitGame() while (initmultiplayerscycle()) { handleevents(); - if (quitevent) - { - QuitFlag = TRUE; - return; - } } } #else @@ -1650,7 +1645,6 @@ void LogoLevel(void) while (TRUE) { handleevents(); - if (quitevent) { QuitFlag = TRUE; break; } // taken from top of faketimerhandler // limits checks to max of 40 times a second @@ -1778,7 +1772,7 @@ void SybexScreen(void) videoNextPage(); ResetKeys(); - while (!KeyPressed() && !quitevent) handleevents(); + while (!KeyPressed()) handleevents(); } // CTW REMOVED END @@ -1961,8 +1955,6 @@ void MenuLevel(void) handleevents(); OSD_DispatchQueued(); - if (quitevent) QuitFlag = TRUE; - // taken from top of faketimerhandler // limits checks to max of 40 times a second if (totalclock >= ototalclock + synctics) @@ -2645,8 +2637,6 @@ void Control() handleevents(); OSD_DispatchQueued(); - if (quitevent) QuitFlag = TRUE; - NewLevel(); } @@ -2903,8 +2893,6 @@ void RunLevel(void) D_ProcessEvents(); faketimerhandler(); - if (quitevent) QuitFlag = TRUE; - MoveLoop(); diff --git a/source/sw/src/network.cpp b/source/sw/src/network.cpp index 1eb21c93f..a4fd7f4ba 100644 --- a/source/sw/src/network.cpp +++ b/source/sw/src/network.cpp @@ -631,7 +631,7 @@ waitforeverybody(void) handleevents(); getpackets(); - if (quitevent || (wfe_ExitCallback && wfe_ExitCallback())) + if (wfe_ExitCallback && wfe_ExitCallback())) { // allow exit //if (inputState.GetKeyStatus(KEYSC_ESC)) From 55ba1116ec0333389d018b6f03b11972ba418962 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2019 09:03:51 +0100 Subject: [PATCH 069/203] - fixing the last commit. --- source/duke3d/src/gameexec.cpp | 1 - source/sw/src/network.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index 1345511f2..10be274c7 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -1095,7 +1095,6 @@ static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags, int32_t cons else #endif { - QuickLoadFailure: g_player[playerNum].ps->gm = MODE_RESTART; } vmFlags |= VM_NOEXECUTE; diff --git a/source/sw/src/network.cpp b/source/sw/src/network.cpp index a4fd7f4ba..905e45115 100644 --- a/source/sw/src/network.cpp +++ b/source/sw/src/network.cpp @@ -631,7 +631,7 @@ waitforeverybody(void) handleevents(); getpackets(); - if (wfe_ExitCallback && wfe_ExitCallback())) + if (wfe_ExitCallback && wfe_ExitCallback()) { // allow exit //if (inputState.GetKeyStatus(KEYSC_ESC)) From 5d0d37df25eab28d9119cfe37e7428704078fdc7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2019 10:18:38 +0100 Subject: [PATCH 070/203] - disconnected Blood's menu. This is due for replacement next. --- source/blood/CMakeLists.txt | 1 + source/blood/src/blood.cpp | 87 ++---- source/blood/src/blood.h | 1 - source/blood/src/controls.cpp | 2 +- source/blood/src/d_menu.cpp | 152 +++++++++ source/blood/src/demo.cpp | 3 - source/blood/src/endgame.cpp | 1 + source/blood/src/gamemenu.cpp | 7 +- source/blood/src/gamemenu.h | 28 +- source/blood/src/loadsave.cpp | 2 - source/blood/src/menu.cpp | 74 +---- source/blood/src/menu.h | 5 +- source/blood/src/menus.h | 535 -------------------------------- source/blood/src/messages.cpp | 2 +- source/blood/src/osdcmd.cpp | 4 - source/blood/src/screentext.cpp | 1 - source/blood/src/screentext.h | 2 - source/blood/src/view.cpp | 7 +- source/common/menu/menu.cpp | 8 +- source/common/menu/menu.h | 1 + source/duke3d/src/screens.cpp | 2 +- source/rr/src/screens.cpp | 2 +- 22 files changed, 218 insertions(+), 709 deletions(-) create mode 100644 source/blood/src/d_menu.cpp delete mode 100644 source/blood/src/menus.h diff --git a/source/blood/CMakeLists.txt b/source/blood/CMakeLists.txt index 5750e3d21..564c2a255 100644 --- a/source/blood/CMakeLists.txt +++ b/source/blood/CMakeLists.txt @@ -102,6 +102,7 @@ set( PCH_SOURCES src/view.cpp src/warp.cpp src/weapon.cpp + src/d_menu.cpp ) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 5e9f70636..1b1610d4c 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -71,6 +71,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gamecontrol.h" #include "m_argv.h" #include "statistics.h" +#include "menu/menu.h" #ifdef _WIN32 # include @@ -713,8 +714,8 @@ void StartLevel(GAMEOPTIONS *gameOptions) gCacheMiss = 0; gFrame = 0; gChokeCounter = 0; - if (!gDemo.at1) - gGameMenuMgr.Deactivate(); + if (!gDemo.at1) + M_ClearMenus(); levelTryPlayMusicOrNothing(gGameOptions.nEpisode, gGameOptions.nLevel); // viewSetMessage(""); viewSetErrorMessage(""); @@ -819,67 +820,21 @@ void LocalKeys(void) buttonMap.ClearButton(gamefunc_See_Chase_View); return; } +#if 0 switch (key) { case sc_kpad_Period: case sc_Delete: if (ctrl && alt) { - gQuitGame = 1; + gQuitGame = 1; // uh, what? return; } break; - case sc_Escape: - inputState.keyFlushScans(); - if (gGameStarted && gPlayer[myconnectindex].pXSprite->health != 0) - { - if (!gGameMenuMgr.m_bActive) - gGameMenuMgr.Push(&menuMainWithSave,-1); - } - else - { - if (!gGameMenuMgr.m_bActive) - gGameMenuMgr.Push(&menuMain,-1); - } - return; - case sc_F1: - inputState.keyFlushScans(); - if (gGameOptions.nGameType == 0) - gGameMenuMgr.Push(&menuOrder,-1); - break; - case sc_F2: - inputState.keyFlushScans(); - if (!gGameMenuMgr.m_bActive && gGameOptions.nGameType == 0) - gGameMenuMgr.Push(&menuSaveGame,-1); - break; - case sc_F3: - inputState.keyFlushScans(); - if (!gGameMenuMgr.m_bActive && gGameOptions.nGameType == 0) - gGameMenuMgr.Push(&menuLoadGame,-1); - break; - case sc_F4: - inputState.keyFlushScans(); - if (!gGameMenuMgr.m_bActive) - gGameMenuMgr.Push(&menuOptionsSound,-1); - return; - case sc_F5: - inputState.keyFlushScans(); - if (!gGameMenuMgr.m_bActive) - gGameMenuMgr.Push(&menuOptions,-1); - return; - case sc_F8: - inputState.keyFlushScans(); - if (!gGameMenuMgr.m_bActive) - gGameMenuMgr.Push(&menuOptionsDisplayMode, -1); - return; - case sc_F10: - inputState.keyFlushScans(); - if (!gGameMenuMgr.m_bActive) - gGameMenuMgr.Push(&menuQuit,-1); - break; - case sc_F11: + case default: break; } +#endif } } @@ -943,7 +898,7 @@ void ProcessFrame(void) viewClearInterpolations(); if (!gDemo.at1) { - if (gPaused || gEndGameMgr.at0 || (gGameOptions.nGameType == 0 && gGameMenuMgr.m_bActive)) + if (gPaused || gEndGameMgr.at0 || (gGameOptions.nGameType == 0 && M_Active())) return; if (gDemo.at0) gDemo.Write(gFifoInput[(gNetFifoTail-1)&255]); @@ -1000,8 +955,9 @@ void ProcessFrame(void) { if (gGameOptions.uGameFlags&8) levelPlayEndScene(gGameOptions.nEpisode); - gGameMenuMgr.Deactivate(); - gGameMenuMgr.Push(&menuCredits,-1); + + M_StartControlPanel(false); + M_SetMenu(NAME_CreditsMenu); } gGameOptions.uGameFlags &= ~3; gRestartGame = 1; @@ -1249,7 +1205,6 @@ int GameInterface::app_main() levelAddUserMap(gUserMapFilename); gStartNewGame = 1; } - SetupMenus(); videoSetViewableArea(0, 0, xdim - 1, ydim - 1); if (!bQuickStart) credLogosDos(); @@ -1285,9 +1240,12 @@ RESTART: else if (gDemo.at1 && !bAddUserMap && !bNoDemo) gDemo.Playback(); if (gDemo.at59ef > 0) - gGameMenuMgr.Deactivate(); - if (!bAddUserMap && !gGameStarted) - gGameMenuMgr.Push(&menuMain, -1); + M_ClearMenus(); + if (!bAddUserMap && !gGameStarted) + { + M_StartControlPanel(false); + M_SetMenu(NAME_MainMenu); + } ready2send = 1; while (!gQuitGame) { @@ -1297,10 +1255,6 @@ RESTART: inputState.SetBindsEnabled(gInputMode == kInputGame); switch (gInputMode) { - case kInputMenu: - if (gGameMenuMgr.m_bActive) - gGameMenuMgr.Process(); - break; case kInputGame: LocalKeys(); break; @@ -1377,10 +1331,6 @@ RESTART: { switch (gInputMode) { - case kInputMenu: - if (gGameMenuMgr.m_bActive) - gGameMenuMgr.Draw(); - break; case kInputMessage: gPlayerMsg.ProcessKeys(); gPlayerMsg.Draw(); @@ -1424,6 +1374,8 @@ RESTART: gRestartGame = 0; gGameStarted = 0; levelSetupOptions(0,0); +#if 0 + // What's this loop for? Needs checking while (gGameMenuMgr.m_bActive) { gGameMenuMgr.Process(); @@ -1435,6 +1387,7 @@ RESTART: videoNextPage(); } } +#endif if (gGameOptions.nGameType != 0) { if (!gDemo.at0 && gDemo.at59ef > 0 && gGameOptions.nGameType == 0 && !bNoDemo) diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index 39d4dd700..92bc9186f 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -46,7 +46,6 @@ extern INICHAIN *pINIChain; enum INPUT_MODE { kInputGame = 0, - kInputMenu, kInputMessage, kInputEndGame, }; diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 3678eaa7c..e0b4d9fd5 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -174,7 +174,7 @@ void ctrlGetInput(void) if (gQuitRequest) gInput.keyFlags.quit = 1; - if (gGameStarted && gInputMode != kInputMessage && gInputMode != kInputMenu + if (gGameStarted && gInputMode != kInputMessage && buttonMap.ButtonDown(gamefunc_SendMessage)) { buttonMap.ClearButton(gamefunc_SendMessage); diff --git a/source/blood/src/d_menu.cpp b/source/blood/src/d_menu.cpp new file mode 100644 index 000000000..62521b56a --- /dev/null +++ b/source/blood/src/d_menu.cpp @@ -0,0 +1,152 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2010-2019 EDuke32 developers and contributors +Copyright (C) 2019 Nuke.YKT + +This file is part of NBlood. + +NBlood is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +//------------------------------------------------------------------------- + +#include "ns.h" // Must come before everything else! + +#include "build.h" +#include "compat.h" +#include "mouse.h" +#include "common_game.h" +#include "blood.h" +#include "config.h" +#include "gamemenu.h" +#include "globals.h" +#include "inifile.h" +#include "levels.h" +#include "menu.h" +#include "qav.h" +#include "resource.h" +#include "view.h" +#include "demo.h" +#include "network.h" +#include "c_bind.h" + +bool ShowOptionMenu(); + +BEGIN_BLD_NS + +CMenuTextMgr gMenuTextMgr; + +CMenuTextMgr::CMenuTextMgr() +{ + at0 = -1; +} + +void CMenuTextMgr::DrawText(const char* pString, int nFont, int x, int y, int nShade, int nPalette, bool shadow) +{ + viewDrawText(nFont, pString, x, y, nShade, nPalette, 0, shadow); +} + +void CMenuTextMgr::GetFontInfo(int nFont, const char* pString, int* pXSize, int* pYSize) +{ + if (nFont < 0 || nFont >= 5) + return; + viewGetFontInfo(nFont, pString, pXSize, pYSize); +} + +const char* zNetGameTypes[] = +{ + "Cooperative", + "Bloodbath", + "Teams", +}; + +void drawLoadingScreen(void) +{ + char buffer[80]; + if (gGameOptions.nGameType == 0) + { + if (gDemo.at1) + sprintf(buffer, "Loading Demo"); + else + sprintf(buffer, "Loading Level"); + } + else + sprintf(buffer, "%s", zNetGameTypes[gGameOptions.nGameType - 1]); + viewLoadingScreen(2049, buffer, levelGetTitle(), NULL); +} + +void UpdateNetworkMenus(void) +{ + // Kept as a reminder to reimplement later. +#if 0 + if (gGameOptions.nGameType > 0) + { + itemMain1.at24 = &menuNetStart; + itemMain1.at28 = 2; + } + else + { + itemMain1.at24 = &menuEpisode; + itemMain1.at28 = -1; + } + if (gGameOptions.nGameType > 0) + { + itemMainSave1.at24 = &menuNetStart; + itemMainSave1.at28 = 2; + } + else + { + itemMainSave1.at24 = &menuEpisode; + itemMainSave1.at28 = -1; + } +#endif +} + +void MenuSetupEpisodeInfo(void) +{ +#if 0 + memset(zEpisodeNames, 0, sizeof(zEpisodeNames)); + memset(zLevelNames, 0, sizeof(zLevelNames)); + for (int i = 0; i < 6; i++) + { + if (i < gEpisodeCount) + { + EPISODEINFO* pEpisode = &gEpisodeInfo[i]; + zEpisodeNames[i] = pEpisode->at0; + for (int j = 0; j < 16; j++) + { + if (j < pEpisode->nLevels) + { + zLevelNames[i][j] = pEpisode->at28[j].at90; + } + } + } + } +#endif +} + +bool GameInterface::mouseInactiveConditional(bool condition) +{ + return condition; +} + + + +FSavegameInfo GameInterface::GetSaveSig() +{ + return { SAVESIG_BLD, MINSAVEVER_BLD, SAVEVER_BLD }; +} + + +END_BLD_NS diff --git a/source/blood/src/demo.cpp b/source/blood/src/demo.cpp index 202ebc661..dc1970161 100644 --- a/source/blood/src/demo.cpp +++ b/source/blood/src/demo.cpp @@ -281,9 +281,6 @@ void CDemo::ProcessKeys(void) { switch (gInputMode) { - case kInputMenu: - gGameMenuMgr.Process(); - break; case kInputMessage: gPlayerMsg.ProcessKeys(); break; diff --git a/source/blood/src/endgame.cpp b/source/blood/src/endgame.cpp index d453362e6..50a589d89 100644 --- a/source/blood/src/endgame.cpp +++ b/source/blood/src/endgame.cpp @@ -40,6 +40,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "view.h" #include "messages.h" #include "statistics.h" +#include "gamemenu.h" BEGIN_BLD_NS diff --git a/source/blood/src/gamemenu.cpp b/source/blood/src/gamemenu.cpp index 7e6fd143e..25b02756c 100644 --- a/source/blood/src/gamemenu.cpp +++ b/source/blood/src/gamemenu.cpp @@ -43,6 +43,8 @@ bool ShowOptionMenu(); BEGIN_BLD_NS +#if 0 + CMenuTextMgr gMenuTextMgr; CGameMenuMgr gGameMenuMgr; @@ -2985,9 +2987,6 @@ bool CGameMenuItemPassword::Event(CGameMenuEvent &event) return CGameMenuItem::Event(event); } -bool GameInterface::mouseInactiveConditional(bool condition) -{ - return MOUSEINACTIVECONDITIONAL(condition); -} +#endif END_BLD_NS diff --git a/source/blood/src/gamemenu.h b/source/blood/src/gamemenu.h index f1cad59af..eeba0d837 100644 --- a/source/blood/src/gamemenu.h +++ b/source/blood/src/gamemenu.h @@ -31,6 +31,23 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS +class CMenuTextMgr +{ +public: + int at0; + CMenuTextMgr(); + void DrawText(const char *pString, int nFont, int x, int y, int nShade, int nPalette, bool shadow ); + void GetFontInfo(int nFont, const char *pString, int *pXSize, int *pYSize); +}; + +extern CMenuTextMgr gMenuTextMgr; + +void drawLoadingScreen(void); +void UpdateNetworkMenus(void); + + +#if 0 + #define M_MOUSETIMEOUT 210 #define kMaxGameMenuItems 128 @@ -85,15 +102,6 @@ struct CGameMenuEvent { #undef DrawText #endif -class CMenuTextMgr -{ -public: - int at0; - CMenuTextMgr(); - void DrawText(const char *pString, int nFont, int x, int y, int nShade, int nPalette, bool shadow ); - void GetFontInfo(int nFont, const char *pString, int *pXSize, int *pYSize); -}; - class CGameMenu; class CGameMenuItem { @@ -488,7 +496,7 @@ public: bool MouseOutsideBounds(vec2_t const * const pos, const int32_t x, const int32_t y, const int32_t width, const int32_t height); }; -extern CMenuTextMgr gMenuTextMgr; extern CGameMenuMgr gGameMenuMgr; +#endif END_BLD_NS diff --git a/source/blood/src/loadsave.cpp b/source/blood/src/loadsave.cpp index 1e9c231a3..01e7ef102 100644 --- a/source/blood/src/loadsave.cpp +++ b/source/blood/src/loadsave.cpp @@ -463,7 +463,6 @@ void LoadSavedInfo(void) } if ((uint32_t)hFile.Read(&gSaveGameOptions[nCount], sizeof(gSaveGameOptions[0])) != sizeof(gSaveGameOptions[0])) ThrowError("Error reading save file."); - strcpy(strRestoreGameStrings[gSaveGameOptions[nCount].nSaveGameSlot], gSaveGameOptions[nCount].szUserGameName); nCount++; } FinishSavegameRead(); @@ -471,7 +470,6 @@ void LoadSavedInfo(void) void UpdateSavedInfo(int nSlot) { - strcpy(strRestoreGameStrings[gSaveGameOptions[nSlot].nSaveGameSlot], gSaveGameOptions[nSlot].szUserGameName); } static MyLoadSave *myLoadSave; diff --git a/source/blood/src/menu.cpp b/source/blood/src/menu.cpp index 7cf24fd38..e105d86fc 100644 --- a/source/blood/src/menu.cpp +++ b/source/blood/src/menu.cpp @@ -49,6 +49,8 @@ EXTERN_CVAR(Bool, hud_powerupduration) BEGIN_BLD_NS +#if 0 + void SaveGame(CGameMenuItemZEditBitmap *, CGameMenuEvent *); void SaveGameProcess(CGameMenuItemChain *); @@ -105,13 +107,6 @@ char strRestoreGameStrings[][16] = "", }; -const char *zNetGameTypes[] = -{ - "Cooperative", - "Bloodbath", - "Teams", -}; - const char *zMonsterStrings[] = { "None", @@ -1354,30 +1349,6 @@ void SetupMenus(void) SetupNetworkMenu(); } -void UpdateNetworkMenus(void) -{ - if (gGameOptions.nGameType > 0) - { - itemMain1.at24 = &menuNetStart; - itemMain1.at28 = 2; - } - else - { - itemMain1.at24 = &menuEpisode; - itemMain1.at28 = -1; - } - if (gGameOptions.nGameType > 0) - { - itemMainSave1.at24 = &menuNetStart; - itemMainSave1.at28 = 2; - } - else - { - itemMainSave1.at24 = &menuEpisode; - itemMainSave1.at28 = -1; - } -} - void SetDoppler(CGameMenuItemZBool *pItem) { snd_doppler = pItem->at20; @@ -2183,45 +2154,6 @@ void SetParentalLock(CGameMenuItemZBool *pItem) // NUKE-TODO: CONFIG_WriteAdultMode(); } -void MenuSetupEpisodeInfo(void) -{ - memset(zEpisodeNames, 0, sizeof(zEpisodeNames)); - memset(zLevelNames, 0, sizeof(zLevelNames)); - for (int i = 0; i < 6; i++) - { - if (i < gEpisodeCount) - { - EPISODEINFO *pEpisode = &gEpisodeInfo[i]; - zEpisodeNames[i] = pEpisode->at0; - for (int j = 0; j < 16; j++) - { - if (j < pEpisode->nLevels) - { - zLevelNames[i][j] = pEpisode->at28[j].at90; - } - } - } - } -} - -void drawLoadingScreen(void) -{ - char buffer[80]; - if (gGameOptions.nGameType == 0) - { - if (gDemo.at1) - sprintf(buffer, "Loading Demo"); - else - sprintf(buffer, "Loading Level"); - } - else - sprintf(buffer, "%s", zNetGameTypes[gGameOptions.nGameType-1]); - viewLoadingScreen(2049, buffer, levelGetTitle(), NULL); -} - -FSavegameInfo GameInterface::GetSaveSig() -{ - return { SAVESIG_BLD, MINSAVEVER_BLD, SAVEVER_BLD }; -} +#endif END_BLD_NS diff --git a/source/blood/src/menu.h b/source/blood/src/menu.h index 3654f9d7a..cdc90f0af 100644 --- a/source/blood/src/menu.h +++ b/source/blood/src/menu.h @@ -25,6 +25,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS +#if 0 + extern CGameMenu menuMain; extern CGameMenu menuMainWithSave; extern CGameMenu menuNetMain; @@ -54,6 +56,7 @@ extern CGameMenu menuOptionsDisplayMode; extern char strRestoreGameStrings[][16]; void drawLoadingScreen(void); void SetupMenus(void); -void UpdateNetworkMenus(void); + +#endif END_BLD_NS diff --git a/source/blood/src/menus.h b/source/blood/src/menus.h deleted file mode 100644 index 104366533..000000000 --- a/source/blood/src/menus.h +++ /dev/null @@ -1,535 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2016 EDuke32 developers and contributors - -This file is part of EDuke32. - -EDuke32 is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. - -This program 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 this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -#ifndef menus_h_ -#define menus_h_ - -#include "compat.h" -#include "cache1d.h" -#include "pragmas.h" -#include "common.h" -#include "blood.h" - -BEGIN_BLD_NS - -#if defined EDUKE32_TOUCH_DEVICES -# define EDUKE32_SIMPLE_MENU -# define EDUKE32_ANDROID_MENU -#endif - -// #define EDUKE32_SIMPLE_MENU - -enum MenuIndex_t { - MENU_NULL = INT32_MIN, // sentinel for "do nothing" - MENU_CLOSE = -2, // sentinel for "close the menu"/"no menu" - MENU_PREVIOUS = -1, // sentinel for "go to previous menu" - MENU_MAIN = 0, - MENU_MAIN_INGAME = 50, - MENU_EPISODE = 100, - MENU_USERMAP = 101, - MENU_NEWGAMECUSTOM = 102, - MENU_NEWGAMECUSTOMSUB = 103, - MENU_SKILL = 110, - MENU_GAMESETUP = 200, - MENU_OPTIONS = 202, - MENU_VIDEOSETUP = 203, - MENU_KEYBOARDSETUP = 204, - MENU_MOUSESETUP = 205, - MENU_JOYSTICKSETUP = 206, - MENU_JOYSTICKBTNS = 207, - MENU_JOYSTICKAXES = 208, - MENU_KEYBOARDKEYS = 209, - MENU_MOUSEBTNS = 210, - MENU_MOUSEADVANCED = 212, - MENU_JOYSTICKAXIS = 213, - MENU_TOUCHSETUP = 214, - MENU_TOUCHSENS = 215, - MENU_TOUCHBUTTONS = 216, - MENU_CONTROLS = 220, - MENU_POLYMOST = 230, - MENU_COLCORR = 231, - MENU_COLCORR_INGAME = 232, - MENU_SCREENSETUP = 233, - MENU_DISPLAYSETUP = 234, - MENU_POLYMER = 240, - MENU_LOAD = 300, - MENU_SAVE = 350, - MENU_STORY = 400, - MENU_F1HELP = 401, - MENU_QUIT = 500, - MENU_QUITTOTITLE = 501, - MENU_QUIT_INGAME = 502, - MENU_NETSETUP = 600, - MENU_NETWAITMASTER = 601, - MENU_NETWAITVOTES = 603, - MENU_SOUND = 700, - MENU_SOUND_INGAME = 701, - MENU_ADVSOUND = 702, - MENU_SAVESETUP = 750, - MENU_SAVECLEANVERIFY = 751, - MENU_RESETSTATSVERIFY = 752, - MENU_CHEATS = 800, - MENU_CHEATENTRY = 801, - MENU_CHEAT_WARP = 802, - MENU_CHEAT_SKILL = 803, - MENU_CREDITS = 990, - MENU_CREDITS2 = 991, - MENU_CREDITS3 = 992, - MENU_CREDITS4 = 993, - MENU_CREDITS5 = 994, - MENU_LOADVERIFY = 1000, - MENU_LOADDELVERIFY = 1100, - MENU_NEWVERIFY = 1500, - MENU_SAVEVERIFY = 2000, - MENU_SAVEDELVERIFY = 2100, - MENU_COLCORRRESETVERIFY = 2200, - MENU_KEYSRESETVERIFY = 2201, - MENU_KEYSCLASSICVERIFY = 2202, - MENU_JOYSTANDARDVERIFY = 2203, - MENU_JOYPROVERIFY = 2204, - MENU_JOYCLEARVERIFY = 2205, - MENU_ADULTPASSWORD = 10001, - MENU_RESETPLAYER = 15000, - MENU_BUYDUKE = 20000, - MENU_NETWORK = 20001, - MENU_PLAYER = 20002, - MENU_MACROS = 20004, - MENU_NETHOST = 20010, - MENU_NETOPTIONS = 20011, - MENU_NETUSERMAP = 20012, - MENU_NETJOIN = 20020, -}; - - - -typedef int32_t MenuID_t; - - -typedef enum MenuAnimationType_t -{ // Note: This enum is for logical categories, not visual types. - MA_None, - MA_Return, - MA_Advance, -} MenuAnimationType_t; - -// a subset of screentext parameters, restricted because menus require accessibility -typedef struct MenuFont_t -{ -// int32_t xspace, yline; - vec2_t emptychar, between; - int32_t zoom; - int32_t cursorLeftPosition, cursorCenterPosition, cursorScale; - int32_t textflags; - int16_t tilenum; - // selected shade glows, deselected shade is used by Blood, disabled shade is used by SW - int8_t shade_deselected, shade_disabled; - uint8_t pal; - uint8_t pal_selected, pal_deselected, pal_disabled; - uint8_t pal_selected_right, pal_deselected_right, pal_disabled_right; - - int32_t get_yline() const { return mulscale16(emptychar.y, zoom); } -} MenuFont_t; - - - -typedef enum MenuEntryType_t -{ - Dummy, - Link, - Option, - Custom2Col, - RangeInt32, - RangeFloat, -#ifdef MENU_ENABLE_RANGEDOUBLE - RangeDouble, -#endif - String, - Spacer, -} MenuEntryType_t; - -typedef struct MenuEntryFormat_t -{ - int32_t marginBottom; - int32_t indent; - int32_t width; // 0: center, >0: width of the label column (left-aligned options), <0: -width of everything (right-aligned) -} MenuEntryFormat_t; - - -typedef struct MenuMenuFormat_t -{ - vec2_t pos; - int32_t bottomcutoff; // >0: the bottom edge of the menu before automatic scrolling kicks in, <0: -total height for vertical justification -} MenuMenuFormat_t; - -typedef struct MenuLink_t -{ - // traits - MenuID_t linkID; - MenuAnimationType_t animation; -} MenuLink_t; -typedef struct MenuOptionSet_t -{ - // traits - char const **optionNames; - int32_t *optionValues; // If NULL, the identity of currentOption is assumed. - - // pop-up list appearance - MenuMenuFormat_t *menuFormat; - MenuEntryFormat_t *entryFormat; - MenuFont_t *font; - - // traits - int32_t numOptions; - - // pop-up list state - int32_t currentEntry; - int32_t scrollPos; - - // appearance - uint8_t features; // bit 1 = disable left/right arrows, bit 2 = disable list - - int32_t getMarginBottom() const { return mulscale16(entryFormat->marginBottom, font->zoom); } - int32_t getIndent() const { return mulscale16(entryFormat->indent, font->zoom); } -} MenuOptionSet_t; -typedef struct MenuOption_t -{ - // appearance - MenuFont_t *font; - - // traits - MenuOptionSet_t *options; // so that common sets such as Yes/No, On/Off can be reused - - // effect - int32_t *data; - - // state - int32_t currentOption; -} MenuOption_t; -typedef struct MenuCustom2Col_t -{ - // effect - uint8_t *column[2]; - char const **key; - - // appearance - MenuFont_t *font; - - // effect - size_t numvalid; - - // appearance - int32_t columnWidth; - - // state - int8_t screenOpen; -} MenuCustom2Col_t; - -enum MenuRangeFlags_t -{ - DisplayTypeInteger = 1, - DisplayTypePercent = 2, - DisplayTypeNormalizedDecimal = 3, - DisplayTypeMask = (1<<0)|(1<<1), - - EnforceIntervals = 1<<7, -}; -typedef struct MenuRangeInt32_t -{ - // effect - int32_t *variable; - - // appearance - MenuFont_t *font; - - // traits - int32_t min; - int32_t max; - int32_t onehundredpercent; // 0 implies max - int32_t steps; - - uint8_t flags; -} MenuRangeInt32_t; -typedef struct MenuRangeFloat_t -{ - // effect - float *variable; - - // appearance - MenuFont_t *font; - - // traits - float min; - float max; - float onehundredpercent; // 0 implies 1.0 - int32_t steps; - - uint8_t flags; -} MenuRangeFloat_t; -#ifdef MENU_ENABLE_RANGEDOUBLE -typedef struct MenuRangeDouble_t -{ - // effect - double *variable; - - // appearance - MenuFont_t *font; - - // traits - double min; - double max; - double onehundredpercent; // 0 implies 1.0 - int32_t steps; - - uint8_t flags; -} MenuRangeDouble_t; -#endif -typedef struct MenuString_t -{ - // state - char* editfield; - - // effect - char* variable; - - // appearance - MenuFont_t *font; - - // effect - int32_t bufsize; - int32_t flags; -} MenuString_t; -typedef struct MenuSpacer_t -{ - int32_t height; -} MenuSpacer_t; - -// For internal use only. -enum MenuEntryFlags_t -{ - MEF_Disabled = 1<<0, - MEF_LookDisabled = 1<<1, - MEF_Hidden = 1<<2, -}; - -typedef struct MenuEntry_t -{ - // traits - const char *name; - - // appearance - MenuFont_t *font; - MenuEntryFormat_t *format; - - void *entry; - MenuEntryType_t type; - - // state - int32_t flags; - int32_t ytop, ybottom; - - int32_t getMarginBottom() const { return mulscale16(format->marginBottom, font->zoom); } - int32_t getIndent() const { return mulscale16(format->indent, font->zoom); } - int32_t getHeight() const - { - return type == Spacer ? mulscale16(((MenuSpacer_t *)entry)->height, font->zoom) : font->get_yline(); - } -} MenuEntry_t; - - -typedef enum MenuType_t -{ - Menu, - Panel, - Verify, - Message, - TextForm, - FileSelect, -} MenuType_t; - -typedef struct MenuMenu_t -{ - const char *title; - - MenuMenuFormat_t *format; - - MenuEntry_t **entrylist; - int32_t numEntries; - - // state - int32_t currentEntry, currentColumn; - int32_t scrollPos; -} MenuMenu_t; -typedef struct MenuPanel_t -{ - const char *title; - - MenuID_t previousID; - MenuAnimationType_t previousAnimation; - MenuID_t nextID; - MenuAnimationType_t nextAnimation; -} MenuPanel_t; -typedef struct MenuVerify_t -{ - vec2_t cursorpos; - - MenuID_t linkID; - MenuAnimationType_t animation; -} MenuVerify_t; -typedef struct MenuMessage_t -{ - vec2_t cursorpos; - - MenuID_t linkID; - MenuAnimationType_t animation; -} MenuMessage_t; -enum MenuTextFormFlags_t -{ - MTF_Password = 1<<0, -}; -typedef struct MenuTextForm_t -{ - // state - char *input; - - // traits - const char *instructions; - int32_t bufsize; - uint8_t flags; -} MenuTextForm_t; -typedef struct MenuFileSelect_t -{ - const char *title; - - // appearance - MenuMenuFormat_t *format[2]; - MenuFont_t *font[2]; - - // traits - const char * startdir; - const char *pattern; - char *destination; - - // state - //CACHE1D_FIND_REC *findhigh[2]; - int32_t scrollPos[2]; - - // appearance - int32_t marginBottom[2]; - - // state - //fnlist_t fnlist; - int32_t currentList; - - int32_t getMarginBottom(size_t index) const { return mulscale16(marginBottom[index], font[index]->zoom); } -} MenuFileSelect_t; - -typedef struct Menu_t -{ - void *object; - MenuID_t menuID; - MenuID_t parentID; - MenuAnimationType_t parentAnimation; - MenuType_t type; -} Menu_t; - -typedef struct MenuAnimation_t -{ - int32_t(*out)(struct MenuAnimation_t *); - int32_t(*in)(struct MenuAnimation_t *); - - Menu_t *previous; - Menu_t *current; - - int32_t start; - int32_t length; -} MenuAnimation_t; - -extern MenuAnimation_t m_animation; - -extern MenuID_t g_currentMenu; -extern Menu_t *m_currentMenu; - -extern int32_t g_quitDeadline; -extern int32_t voting; -int Menu_Change(MenuID_t cm); -void Menu_AnimateChange(int32_t cm, MenuAnimationType_t animtype); -int32_t Menu_IsTextInput(Menu_t *cm); -int G_CheckPlayerColor(int color); -void Menu_Init(void); -void M_DisplayMenus(void); - -extern MenuFont_t MF_Redfont, MF_Bluefont, MF_Minifont; - -#define M_MOUSETIMEOUT 210 -extern int32_t m_mouselastactivity; - -#if defined EDUKE32_TOUCH_DEVICES -# define MOUSEALPHA 0 -# define CURSORALPHA (255/3) -# define MOUSEACTIVECONDITIONAL(condition) (condition) -# define MOUSEWATCHPOINTCONDITIONAL(condition) (condition) -#else -extern int32_t m_mousewake_watchpoint, m_menuchange_watchpoint; -// alpha increments of 3 --> 255 / 3 = 85 --> round up to power of 2 --> 128 --> divide by 2 --> 64 alphatabs required -// use 16 anyway :P -#if 0 -# define MOUSEUSEALPHA (videoGetRenderMode() != REND_CLASSIC || numalphatabs >= 15) -# define MOUSEALPHA (MOUSEUSEALPHA ? clamp(((int32_t) totalclock - m_mouselastactivity - 90)*3, 0, 255) : 0) -# define CURSORALPHA (MOUSEUSEALPHA ? clamp(((int32_t) totalclock - m_mouselastactivity - 90)*2 + (255/3), (255/3), 255) : 255/3) -# define MOUSEACTIVECONDITION (totalclock - m_mouselastactivity < M_MOUSETIMEOUT) -# define MOUSEACTIVECONDITIONAL(condition) (MOUSEACTIVECONDITION && (condition)) -# define MOUSEINACTIVECONDITIONAL(condition) ((gInputMode != kInputMenu || !MOUSEACTIVECONDITION) && (condition)) -# define MOUSEWATCHPOINTCONDITIONAL(condition) ((condition) || m_mousewake_watchpoint || m_menuchange_watchpoint == 3) -#endif -#endif - -#define MAXMENUGAMEPLAYENTRIES 7 - -enum MenuGameplayEntryFlags -{ - MGE_Locked = 1u<<0u, - MGE_Hidden = 1u<<1u, - MGE_UserContent = 1u<<2u, -}; - -typedef struct MenuGameplayEntry -{ - char name[64]; - uint8_t flags; - - bool isValid() const { return name[0] != '\0'; } -} MenuGameplayEntry; - -typedef struct MenuGameplayStemEntry -{ - MenuGameplayEntry entry; - MenuGameplayEntry subentries[MAXMENUGAMEPLAYENTRIES]; -} MenuGameplayStemEntry; - -extern MenuGameplayStemEntry g_MenuGameplayEntries[MAXMENUGAMEPLAYENTRIES]; - -extern MenuEntry_t ME_NEWGAMECUSTOMENTRIES[MAXMENUGAMEPLAYENTRIES]; -extern MenuEntry_t ME_NEWGAMECUSTOMSUBENTRIES[MAXMENUGAMEPLAYENTRIES][MAXMENUGAMEPLAYENTRIES]; - -END_BLD_NS - -#endif diff --git a/source/blood/src/messages.cpp b/source/blood/src/messages.cpp index f69cb5c96..ef2f8c5a0 100644 --- a/source/blood/src/messages.cpp +++ b/source/blood/src/messages.cpp @@ -36,7 +36,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "globals.h" #include "levels.h" #include "loadsave.h" -#include "menu.h" +#include "gamemenu.h" #include "messages.h" #include "network.h" #include "player.h" diff --git a/source/blood/src/osdcmd.cpp b/source/blood/src/osdcmd.cpp index 5998ad2ab..e5f253d0c 100644 --- a/source/blood/src/osdcmd.cpp +++ b/source/blood/src/osdcmd.cpp @@ -83,13 +83,11 @@ static int osdcmd_changelevel(osdcmdptr_t parm) gPacketStartGame.levelId = level; netBroadcastNewGame(); gStartNewGame = 1; - gGameMenuMgr.Deactivate(); return OSDCMD_OK; } levelSetupOptions(volume, level); StartLevel(&gGameOptions); viewResizeView(gViewSize); - gGameMenuMgr.Deactivate(); return OSDCMD_OK; } @@ -118,13 +116,11 @@ static int osdcmd_map(osdcmdptr_t parm) gPacketStartGame.levelId = gGameOptions.nLevel; netBroadcastNewGame(); gStartNewGame = 1; - gGameMenuMgr.Deactivate(); return OSDCMD_OK; } levelSetupOptions(gGameOptions.nEpisode, gGameOptions.nLevel); StartLevel(&gGameOptions); viewResizeView(gViewSize); - gGameMenuMgr.Deactivate(); return OSDCMD_OK; } diff --git a/source/blood/src/screentext.cpp b/source/blood/src/screentext.cpp index 8267aea4d..57a9cbd08 100644 --- a/source/blood/src/screentext.cpp +++ b/source/blood/src/screentext.cpp @@ -25,7 +25,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "blood.h" #include "common_game.h" #include "screentext.h" -#include "menus.h" BEGIN_BLD_NS diff --git a/source/blood/src/screentext.h b/source/blood/src/screentext.h index 6824a3eb8..693b64976 100644 --- a/source/blood/src/screentext.h +++ b/source/blood/src/screentext.h @@ -22,8 +22,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #pragma once -#include "menus.h" - BEGIN_BLD_NS #define USERQUOTE_LEFTOFFSET 5 diff --git a/source/blood/src/view.cpp b/source/blood/src/view.cpp index ef6829df5..ff61a06e5 100644 --- a/source/blood/src/view.cpp +++ b/source/blood/src/view.cpp @@ -47,7 +47,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "loadsave.h" #include "map2d.h" #include "messages.h" -#include "menu.h" +#include "gamemenu.h" #include "mirrors.h" #include "network.h" #include "player.h" @@ -61,6 +61,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "warp.h" #include "weapon.h" #include "zstring.h" +#include "menu/menu.h" CVARD(Bool, hud_powerupduration, true, CVAR_ARCHIVE|CVAR_FRONTEND_BLOOD, "enable/disable displaying the remaining seconds for power-ups") @@ -1270,7 +1271,7 @@ void viewDrawPowerUps(PLAYER* pPlayer) void viewDrawMapTitle(void) { - if (!hud_showmapname || gGameMenuMgr.m_bActive) + if (!hud_showmapname || M_Active()) return; int const fadeStartTic = int((videoGetRenderMode() == REND_CLASSIC ? 1.25f : 1.f)*kTicsPerSec); @@ -3056,7 +3057,7 @@ void viewDrawScreen(void) if (delta < 0) delta = 0; lastUpdate = totalclock; - if (!gPaused && (!CGameMenuMgr::m_bActive || gGameOptions.nGameType != 0)) + if (!gPaused && (!M_Active() || gGameOptions.nGameType != 0)) { gInterpolate = ((totalclock-gNetFifoClock)+4).toScale16()/4; } diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index eae10b9ad..ae6fe06ea 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -747,7 +747,7 @@ bool M_Responder (event_t *ev) if (ev->type == EV_KeyDown) { // Pop-up menu? - if (ev->data1 == KEY_ESCAPE) + if (ev->data1 == KEY_ESCAPE) // Should we let the games handle Escape for special actions, like backing out of cameras? { M_StartControlPanel(true); M_SetMenu(NAME_IngameMenu, -1); @@ -870,6 +870,12 @@ void Menu_Close(int playerid) { M_ClearMenus(); } + +bool M_Active() +{ + return DMenu::CurrentMenu != nullptr; +} + //============================================================================= // // diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 8727f2767..6cf842a1c 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -744,6 +744,7 @@ void M_StartMessage(const char *message, int messagemode, int scriptId, FName ac void M_UnhideCustomMenu(int menu, int itemmask); void M_MenuSound(EMenuSounds snd); void M_Autosave(); +bool M_Active(); void I_SetMouseCapture(); diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index 32c676db4..a21436a1f 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -984,7 +984,7 @@ void G_DisplayRest(int32_t smoothratio) G_PrintGameQuotes(screenpeek); - if (ud.show_level_text && hud_showmapname && g_levelTextTime > 1 && DMenu::CurrentMenu == nullptr) + if (ud.show_level_text && hud_showmapname && g_levelTextTime > 1 && !M_Active()) { int32_t o = 10|16; diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index e4cbafa46..adc23ea27 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -1015,7 +1015,7 @@ void G_DisplayRest(int32_t smoothratio) G_PrintGameQuotes(screenpeek); - if (ud.show_level_text && hud_showmapname && g_levelTextTime > 1 && DMenu::CurrentMenu == nullptr) + if (ud.show_level_text && hud_showmapname && g_levelTextTime > 1 && !M_Active()) { int32_t o = 10|16; From aed05840ae63f90637dbdbc6b861f2e2bcab7904 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2019 10:31:44 +0100 Subject: [PATCH 071/203] - removed the mouseInactiveConditional interface function. This was only a crutch to let the input interface work with the original menus. Now that the one in Blood is gone, all the conditions are no longer relevant. (Shadow Warrior never got far enough to implement this) --- source/blood/src/blood.h | 1 - source/blood/src/d_menu.cpp | 6 ------ source/build/include/baselayer.h | 1 - source/duke3d/src/d_menu.cpp | 5 ----- source/duke3d/src/duke3d.h | 1 - source/mact/src/input.cpp | 12 ++++++++---- source/rr/src/d_menu.cpp | 5 ----- source/rr/src/duke3d.h | 1 - source/sw/src/game.cpp | 6 ------ source/sw/src/game.h | 1 - 10 files changed, 8 insertions(+), 31 deletions(-) diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index 92bc9186f..87dc23c57 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -87,7 +87,6 @@ struct GameInterface : ::GameInterface bool validate_hud(int) override; void set_hud_layout(int size) override; void set_hud_scale(int size) override; - bool mouseInactiveConditional(bool condition) override; FString statFPS() override; FSavegameInfo GetSaveSig() override; diff --git a/source/blood/src/d_menu.cpp b/source/blood/src/d_menu.cpp index 62521b56a..3563cf8d1 100644 --- a/source/blood/src/d_menu.cpp +++ b/source/blood/src/d_menu.cpp @@ -136,12 +136,6 @@ void MenuSetupEpisodeInfo(void) #endif } -bool GameInterface::mouseInactiveConditional(bool condition) -{ - return condition; -} - - FSavegameInfo GameInterface::GetSaveSig() { diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 40f147f5f..cbdcf7e3f 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -211,7 +211,6 @@ struct GameInterface virtual bool validate_hud(int) = 0; virtual void set_hud_layout(int size) = 0; virtual void set_hud_scale(int size) = 0; - virtual bool mouseInactiveConditional(bool condition) { return condition; } virtual FString statFPS() { return "FPS display not available"; } virtual GameStats getStats() { return {}; } virtual void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int flags) {} diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 33b3b0c3c..340216664 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -414,11 +414,6 @@ class MainMenu : public DukeListMenu //---------------------------------------------------------------------------- -bool GameInterface::mouseInactiveConditional(bool condition) // can hopefully go away once the menu refactor is complete -{ - return condition; -} - void GameInterface::MenuOpened() { S_PauseSounds(true); diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index 1a2042485..7c431e595 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -151,7 +151,6 @@ struct GameInterface : ::GameInterface bool validate_hud(int) override; void set_hud_layout(int size) override; void set_hud_scale(int size) override; - bool mouseInactiveConditional(bool condition) override; FString statFPS() override; GameStats getStats() override; // Access to the front end specific menu code. Use is restricted to the main menu, the ingame menu and the skill/episode selection. diff --git a/source/mact/src/input.cpp b/source/mact/src/input.cpp index cfe298978..0274e59ed 100644 --- a/source/mact/src/input.cpp +++ b/source/mact/src/input.cpp @@ -31,6 +31,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. char typebuf[TYPEBUFSIZE]; +bool mouseInactiveConditional(bool condition) +{ + return condition; +} int32_t I_CheckAllInput(void) { @@ -54,7 +58,7 @@ int32_t I_TextSubmit(void) return inputState.GetKeyStatus(sc_Enter) || inputState.GetKeyStatus(sc_kpad_Enter) - || gi->mouseInactiveConditional(inputState.MouseGetButtons()&LEFT_MOUSE) + || mouseInactiveConditional(inputState.MouseGetButtons()&LEFT_MOUSE) || (JOYSTICK_GetGameControllerButtons()&(1<mouseInactiveConditional(buttonMap.ButtonDown(gamefunc_Fire)) + || mouseInactiveConditional(buttonMap.ButtonDown(gamefunc_Fire)) || buttonMap.ButtonDown(gamefunc_Crouch) || (JOYSTICK_GetGameControllerButtons()&(1<mouseInactiveConditional((inputState.MouseGetButtons()&LEFT_MOUSE) && (inputState.MouseGetButtons()&WHEELUP_MOUSE)) + || mouseInactiveConditional((inputState.MouseGetButtons()&LEFT_MOUSE) && (inputState.MouseGetButtons()&WHEELUP_MOUSE)) #endif ; } @@ -295,7 +299,7 @@ int32_t I_SliderRight(void) return I_MenuRight() #if !defined EDUKE32_TOUCH_DEVICES - || gi->mouseInactiveConditional((inputState.MouseGetButtons()&LEFT_MOUSE) && (inputState.MouseGetButtons()&WHEELDOWN_MOUSE)) + || mouseInactiveConditional((inputState.MouseGetButtons()&LEFT_MOUSE) && (inputState.MouseGetButtons()&WHEELDOWN_MOUSE)) #endif ; } diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index 974c3d8f7..faa7c718b 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -342,11 +342,6 @@ class MainMenu : public RedneckListMenu //---------------------------------------------------------------------------- -bool GameInterface::mouseInactiveConditional(bool condition) // can hopefully go away once the menu refactor is complete -{ - return condition; -} - void GameInterface::MenuOpened() { S_PauseSounds(true); diff --git a/source/rr/src/duke3d.h b/source/rr/src/duke3d.h index 11795d75e..aedcb0ece 100644 --- a/source/rr/src/duke3d.h +++ b/source/rr/src/duke3d.h @@ -155,7 +155,6 @@ struct GameInterface : ::GameInterface bool validate_hud(int) override; void set_hud_layout(int size) override; void set_hud_scale(int size) override; - bool mouseInactiveConditional(bool condition) override; FString statFPS() override; GameStats getStats() override; void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int flags); diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 308a68e8f..69f0a192c 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -4751,12 +4751,6 @@ void Saveable_Init_Dynamic() /*extern*/ void GameInterface::set_hud_layout(int requested_size) { /* the relevant setting is gs.BorderNum */} /*extern*/ void GameInterface::set_hud_scale(int requested_size) { /* the relevant setting is gs.BorderNum */ } -bool GameInterface::mouseInactiveConditional(bool condition) -{ - return condition; -} - - ::GameInterface* CreateInterface() { return new GameInterface; diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 9b55ac67c..b4e07fe38 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -2381,7 +2381,6 @@ struct GameInterface : ::GameInterface bool validate_hud(int) override; void set_hud_layout(int size) override; void set_hud_scale(int size) override; - bool mouseInactiveConditional(bool condition) override; FSavegameInfo GetSaveSig() override; }; From b0a67349151dc0472c257c74c02c9fc43f24a0bf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2019 11:38:13 +0100 Subject: [PATCH 072/203] - removed no longer needed parts from input.cpp. --- source/mact/include/input.h | 10 ------ source/mact/src/input.cpp | 70 ------------------------------------- source/rr/src/d_menu.cpp | 2 +- 3 files changed, 1 insertion(+), 81 deletions(-) diff --git a/source/mact/include/input.h b/source/mact/include/input.h index 1028331e0..183ec8f0a 100644 --- a/source/mact/include/input.h +++ b/source/mact/include/input.h @@ -56,16 +56,6 @@ extern void I_MenuLeftClear(void); extern int32_t I_MenuRight(void); extern void I_MenuRightClear(void); -extern int32_t I_PanelUp(void); -extern void I_PanelUpClear(void); -extern int32_t I_PanelDown(void); -extern void I_PanelDownClear(void); - -extern int32_t I_SliderLeft(void); -extern void I_SliderLeftClear(void); -extern int32_t I_SliderRight(void); -extern void I_SliderRightClear(void); - enum EnterTextFlags_t { INPUT_NUMERIC = 0x00000001, diff --git a/source/mact/src/input.cpp b/source/mact/src/input.cpp index 0274e59ed..6bb72073b 100644 --- a/source/mact/src/input.cpp +++ b/source/mact/src/input.cpp @@ -241,76 +241,6 @@ void I_MenuRightClear(void) } -int32_t I_PanelUp(void) -{ - return - I_MenuUp() - || I_MenuLeft() - || inputState.GetKeyStatus(sc_PgUp) - ; -} - -void I_PanelUpClear(void) -{ - I_MenuUpClear(); - I_MenuLeftClear(); - inputState.ClearKeyStatus(sc_PgUp); -} - - -int32_t I_PanelDown(void) -{ - return - I_MenuDown() - || I_MenuRight() - || inputState.GetKeyStatus(sc_PgDn) - || I_AdvanceTrigger() - ; -} - -void I_PanelDownClear(void) -{ - I_MenuDownClear(); - I_MenuRightClear(); - inputState.ClearKeyStatus(sc_PgDn); - I_AdvanceTriggerClear(); -} - - -int32_t I_SliderLeft(void) -{ - return - I_MenuLeft() -#if !defined EDUKE32_TOUCH_DEVICES - || mouseInactiveConditional((inputState.MouseGetButtons()&LEFT_MOUSE) && (inputState.MouseGetButtons()&WHEELUP_MOUSE)) -#endif - ; -} - -void I_SliderLeftClear(void) -{ - I_MenuLeftClear(); - inputState.MouseClearButton(WHEELUP_MOUSE); -} - - -int32_t I_SliderRight(void) -{ - return - I_MenuRight() -#if !defined EDUKE32_TOUCH_DEVICES - || mouseInactiveConditional((inputState.MouseGetButtons()&LEFT_MOUSE) && (inputState.MouseGetButtons()&WHEELDOWN_MOUSE)) -#endif - ; -} - -void I_SliderRightClear(void) -{ - I_MenuRightClear(); - inputState.MouseClearButton(WHEELDOWN_MOUSE); -} - - int32_t I_EnterText(char *t, int32_t maxlength, int32_t flags) { char ch; diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index faa7c718b..960dd7d41 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -478,7 +478,7 @@ void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *t } -END_DUKE_NS +END_RR_NS //---------------------------------------------------------------------------- // From b372cb5f357eba4fc829c996db2ab34d12b5f7fb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2019 15:31:08 +0100 Subject: [PATCH 073/203] - the primary Blood menus are working. Now this was magnitudes easier than the EDuke menu - NBlood's menu is actually clean and usable code but still nothing compared to a unified menu system. --- source/blood/src/blood.h | 9 +- source/blood/src/d_menu.cpp | 351 +++++++++++++++++++++++--- source/blood/src/endgame.cpp | 2 +- source/blood/src/gamemenu.cpp | 69 ++--- source/blood/src/gamemenu.h | 27 -- source/blood/src/menu.cpp | 6 - source/blood/src/messages.cpp | 4 +- source/blood/src/view.cpp | 35 +-- source/build/include/baselayer.h | 2 +- source/common/2d/v_drawtext.cpp | 3 +- source/common/menu/listmenu.cpp | 10 +- source/common/menu/menu.cpp | 2 + source/common/menu/menudef.cpp | 13 +- source/common/menu/messagebox.cpp | 3 +- source/common/menu/optionmenu.cpp | 11 +- source/common/menu/optionmenuitems.h | 9 +- source/common/utility/stringtable.h | 5 + source/duke3d/src/d_menu.cpp | 85 +++---- source/duke3d/src/duke3d.h | 2 +- source/duke3d/src/screentext.cpp | 1 - source/rr/src/d_menu.cpp | 85 +++---- source/rr/src/duke3d.h | 2 +- source/rr/src/screentext.cpp | 1 - wadsrc/static/demolition/language.csv | 44 ++-- wadsrc/static/demolition/menudef.txt | 41 ++- 25 files changed, 518 insertions(+), 304 deletions(-) diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index 87dc23c57..612c65ca0 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -89,7 +89,14 @@ struct GameInterface : ::GameInterface void set_hud_scale(int size) override; FString statFPS() override; FSavegameInfo GetSaveSig() override; - + void MenuOpened() override; + void MenuSound(EMenuSounds snd) override; + void MenuClosed() override; + bool CanSave() override; + void StartGame(FGameStartup& gs) override; + void DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) override; + void DrawMenuCaption(const DVector2& origin, const char* text) override; + void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) override; }; END_BLD_NS diff --git a/source/blood/src/d_menu.cpp b/source/blood/src/d_menu.cpp index 3563cf8d1..2ba91858a 100644 --- a/source/blood/src/d_menu.cpp +++ b/source/blood/src/d_menu.cpp @@ -40,75 +40,134 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "demo.h" #include "network.h" #include "c_bind.h" +#include "menu/menu.h" bool ShowOptionMenu(); BEGIN_BLD_NS -CMenuTextMgr gMenuTextMgr; - -CMenuTextMgr::CMenuTextMgr() +class CGameMenuItemQAV { - at0 = -1; -} - -void CMenuTextMgr::DrawText(const char* pString, int nFont, int x, int y, int nShade, int nPalette, bool shadow) -{ - viewDrawText(nFont, pString, x, y, nShade, nPalette, 0, shadow); -} - -void CMenuTextMgr::GetFontInfo(int nFont, const char* pString, int* pXSize, int* pYSize) -{ - if (nFont < 0 || nFont >= 5) - return; - viewGetFontInfo(nFont, pString, pXSize, pYSize); -} - -const char* zNetGameTypes[] = -{ - "Cooperative", - "Bloodbath", - "Teams", +public: + int m_nX, m_nY; + TArray raw; + int at2c; + int lastTick; + bool bWideScreen; + bool bClearBackground; + CGameMenuItemQAV(int, int, const char*, bool widescreen = false, bool clearbackground = false); + void Draw(void); }; -void drawLoadingScreen(void) +CGameMenuItemQAV::CGameMenuItemQAV(int a3, int a4, const char* name, bool widescreen, bool clearbackground) { - char buffer[80]; - if (gGameOptions.nGameType == 0) + m_nY = a4; + m_nX = a3; + bWideScreen = widescreen; + bClearBackground = clearbackground; + + if (name) { - if (gDemo.at1) - sprintf(buffer, "Loading Demo"); - else - sprintf(buffer, "Loading Level"); + // NBlood read this directly from the file system cache, but let's better store the data locally for robustness. + raw = kloadfile(name, 0); + if (raw.Size() != 0) + { + auto data = (QAV*)raw.Data(); + data->nSprite = -1; + data->x = m_nX; + data->y = m_nY; + data->Preload(); + at2c = data->at10; + lastTick = (int)totalclock; + } } - else - sprintf(buffer, "%s", zNetGameTypes[gGameOptions.nGameType - 1]); - viewLoadingScreen(2049, buffer, levelGetTitle(), NULL); } +void CGameMenuItemQAV::Draw(void) +{ + if (bClearBackground) + videoClearScreen(0); + + if (raw.Size() > 0) + { + auto data = (QAV*)raw.Data(); + ClockTicks backFC = gFrameClock; + gFrameClock = totalclock; + int nTicks = (int)totalclock - lastTick; + lastTick = (int)totalclock; + at2c -= nTicks; + if (at2c <= 0 || at2c > data->at10) + { + at2c = data->at10; + } + data->Play(data->at10 - at2c - nTicks, data->at10 - at2c, -1, NULL); + int wx1, wy1, wx2, wy2; + wx1 = windowxy1.x; + wy1 = windowxy1.y; + wx2 = windowxy2.x; + wy2 = windowxy2.y; + windowxy1.x = 0; + windowxy1.y = 0; + windowxy2.x = xdim - 1; + windowxy2.y = ydim - 1; + if (bWideScreen) + { + int xdim43 = scale(ydim, 4, 3); + int nCount = (xdim + xdim43 - 1) / xdim43; + int backX = data->x; + for (int i = 0; i < nCount; i++) + { + data->Draw(data->at10 - at2c, 10 + kQavOrientationLeft, 0, 0); + data->x += 320; + } + data->x = backX; + } + else + data->Draw(data->at10 - at2c, 10, 0, 0); + + windowxy1.x = wx1; + windowxy1.y = wy1; + windowxy2.x = wx2; + windowxy2.y = wy2; + gFrameClock = backFC; + } +} + + + +static std::unique_ptr itemBloodQAV; // This must be global to ensure that the animation remains consistent across menus. +/* +CGameMenuItemQAV itemCreditsQAV("", 3, 160, 100, "CREDITS", false, true); +CGameMenuItemQAV itemHelp3QAV("", 3, 160, 100, "HELP3", false, false); +CGameMenuItemQAV itemHelp3BQAV("", 3, 160, 100, "HELP3B", false, false); +CGameMenuItemQAV itemHelp4QAV("", 3, 160, 100, "HELP4", false, true); +CGameMenuItemQAV itemHelp5QAV("", 3, 160, 100, "HELP5", false, true); +*/ + + void UpdateNetworkMenus(void) { // Kept as a reminder to reimplement later. #if 0 if (gGameOptions.nGameType > 0) { - itemMain1.at24 = &menuNetStart; - itemMain1.at28 = 2; + itemMain1.resource = &menuNetStart; + itemMain1.data = 2; } else { - itemMain1.at24 = &menuEpisode; - itemMain1.at28 = -1; + itemMain1.resource = &menuEpisode; + itemMain1.data = -1; } if (gGameOptions.nGameType > 0) { - itemMainSave1.at24 = &menuNetStart; - itemMainSave1.at28 = 2; + itemMainSave1.resource = &menuNetStart; + itemMainSave1.data = 2; } else { - itemMainSave1.at24 = &menuEpisode; - itemMainSave1.at28 = -1; + itemMainSave1.resource = &menuEpisode; + itemMainSave1.data = -1; } #endif } @@ -128,7 +187,7 @@ void MenuSetupEpisodeInfo(void) { if (j < pEpisode->nLevels) { - zLevelNames[i][j] = pEpisode->at28[j].at90; + zLevelNames[i][j] = pEpisode->data[j].at90; } } } @@ -136,11 +195,219 @@ void MenuSetupEpisodeInfo(void) #endif } +//---------------------------------------------------------------------------- +// +// Implements the native looking menu used for the main menu +// and the episode/skill selection screens, i.e. the parts +// that need to look authentic +// +//---------------------------------------------------------------------------- + +class BloodListMenu : public DListMenu +{ + using Super = DListMenu; +protected: + + void PostDraw() + { + itemBloodQAV->Draw(); + } + +}; + + +//---------------------------------------------------------------------------- +// +// Menu related game interface functions +// +//---------------------------------------------------------------------------- + +void GameInterface::DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) +{ + if (!text) return; + int shade = (state != NIT_InactiveState) ? 32 : 48; + int pal = (state != NIT_InactiveState) ? 5 : 5; + if (state == NIT_SelectedState) shade = 32 - ((int)totalclock & 63); + int width, height; + int gamefont = fontnum == NIT_BigFont ? 1 : fontnum == NIT_SmallFont ? 2 : 3; + + int x = int(xpos); + int y = int(ypos); + viewGetFontInfo(gamefont, text, &width, &height); + + if (flags & LMF_Centered) + { + x -= width / 2; + } + + viewDrawText(gamefont, text, x, y, shade, pal, 0, true); +} + + +void GameInterface::MenuOpened() +{ +#if 0 + S_PauseSounds(true); + if ((!g_netServer && ud.multimode < 2)) + { + ready2send = 0; + totalclock = ototalclock; + screenpeek = myconnectindex; + } + + auto& gm = g_player[myconnectindex].ps->gm; + if (gm & MODE_GAME) + { + gm |= MODE_MENU; + } +#endif + + itemBloodQAV.reset(new CGameMenuItemQAV(160, 100, "BDRIP.QAV", true)); +} + +void GameInterface::MenuSound(EMenuSounds snd) +{ +#if 0 + switch (snd) + { + case CursorSound: + S_PlaySound(RR ? 335 : KICK_HIT); + break; + + case AdvanceSound: + S_PlaySound(RR ? 341 : PISTOL_BODYHIT); + break; + + case CloseSound: + S_PlaySound(EXITMENUSOUND); + break; + + default: + return; + } +#endif +} + +void GameInterface::MenuClosed() +{ + itemBloodQAV.reset(); +#if 0 + auto& gm = g_player[myconnectindex].ps->gm; + if (gm & MODE_GAME) + { + if (gm & MODE_MENU) + I_ClearAllInput(); + + // The following lines are here so that you cannot close the menu when no game is running. + gm &= ~MODE_MENU; + + if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + CAMERACLOCK = (int32_t)totalclock; + CAMERADIST = 65536; + + // Reset next-viewscreen-redraw counter. + // XXX: are there any other cases like that in need of handling? + if (g_curViewscreen >= 0) + actor[g_curViewscreen].t_data[0] = (int32_t)totalclock; + } + + G_UpdateScreenArea(); + S_PauseSounds(false); + } +#endif +} + +bool GameInterface::CanSave() +{ +#if 0 + if (ud.recstat == 2) return false; + auto& myplayer = *g_player[myconnectindex].ps; + if (sprite[myplayer.i].extra <= 0) + { + P_DoQuote(QUOTE_SAVE_DEAD, &myplayer); + return false; + } +#endif + return true; +} + +void GameInterface::StartGame(FGameStartup& gs) +{ +#if 0 + int32_t skillsound = PISTOL_BODYHIT; + + switch (gs.Skill) + { + case 0: + skillsound = 427; + break; + case 1: + skillsound = 428; + break; + case 2: + skillsound = 196; + break; + case 3: + skillsound = 195; + break; + case 4: + skillsound = 197; + break; + } + + ud.m_player_skill = gs.Skill + 1; + if (menu_sounds) g_skillSoundVoice = S_PlaySound(skillsound); + ud.m_respawn_monsters = (gs.Skill == 3); + ud.m_monsters_off = ud.monsters_off = 0; + ud.m_respawn_items = 0; + ud.m_respawn_inventory = 0; + ud.multimode = 1; + ud.m_volume_number = gs.Episode; + ud.m_level_number = gs.Level; + G_NewGame_EnterLevel(); +#endif +} FSavegameInfo GameInterface::GetSaveSig() { return { SAVESIG_BLD, MINSAVEVER_BLD, SAVEVER_BLD }; } +void GameInterface::DrawMenuCaption(const DVector2& origin, const char* text) +{ + int height; + // font #1, tile #2038. + viewGetFontInfo(1, NULL, NULL, &height); + rotatesprite(int(origin.X * 65536) + 320 << 15, 20 << 16, 65536, 0, 2038, -128, 0, 78, 0, 0, xdim - 1, ydim - 1); + viewDrawText(1, text, 160, 20 - height / 2, -128, 0, 1, false); +} + +void GameInterface::DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) +{ +#if 0 + Menu_DrawBackground(origin); + G_ScreenText(MF_Bluefont.tilenum, int((origin.X + 160) * 65536), int((origin.Y + position) * 65536), MF_Bluefont.zoom, 0, 0, text, 0, MF_Bluefont.pal, + 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, + MF_Bluefont.textflags | TEXT_XCENTER, 0, 0, xdim - 1, ydim - 1); +#endif +} + END_BLD_NS + +//---------------------------------------------------------------------------- +// +// Class registration +// +//---------------------------------------------------------------------------- + + +static TMenuClassDescriptor _lm("Blood.ListMenu"); + +void RegisterBloodMenus() +{ + menuClasses.Push(&_lm); +} diff --git a/source/blood/src/endgame.cpp b/source/blood/src/endgame.cpp index 50a589d89..98e6c2361 100644 --- a/source/blood/src/endgame.cpp +++ b/source/blood/src/endgame.cpp @@ -53,7 +53,7 @@ void CEndGameMgr::Draw(void) { viewLoadingScreenWide(); int nHeight; - gMenuTextMgr.GetFontInfo(1, NULL, NULL, &nHeight); + viewGetFontInfo(1, NULL, NULL, &nHeight); rotatesprite(160<<16, 20<<16, 65536, 0, 2038, -128, 0, 6, 0, 0, xdim-1, ydim-1); int nY = 20 - nHeight / 2; if (gGameOptions.nGameType == 0) diff --git a/source/blood/src/gamemenu.cpp b/source/blood/src/gamemenu.cpp index 25b02756c..bc667d65e 100644 --- a/source/blood/src/gamemenu.cpp +++ b/source/blood/src/gamemenu.cpp @@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "levels.h" #include "menu.h" #include "qav.h" +#include "demo.h" #include "resource.h" #include "view.h" #include "c_bind.h" @@ -43,6 +44,28 @@ bool ShowOptionMenu(); BEGIN_BLD_NS +const char* zNetGameTypes[] = +{ + "Cooperative", + "Bloodbath", + "Teams", +}; + +void drawLoadingScreen(void) +{ + char buffer[80]; + if (gGameOptions.nGameType == 0) + { + if (gDemo.at1) + sprintf(buffer, "Loading Demo"); + else + sprintf(buffer, "Loading Level"); + } + else + sprintf(buffer, "%s", zNetGameTypes[gGameOptions.nGameType - 1]); + viewLoadingScreen(2049, buffer, levelGetTitle(), NULL); +} + #if 0 CMenuTextMgr gMenuTextMgr; @@ -159,26 +182,6 @@ void CGameMenuMgr::Draw(void) { if (pActiveMenu) { - if (GUICapture & 2) - { - ImGui_Begin_Frame(); - bool b = true; - videoFadeToBlack(1); -#if 0 - ImGui::ShowDemoWindow(&b); - if (!b) -#else - if (!ShowOptionMenu()) -#endif - { - GUICapture &= ~2; - GUICapture |= 4; - Pop(); - } - return; - } - - pActiveMenu->Draw(); viewUpdatePages(); } @@ -2201,32 +2204,6 @@ bool CGameMenuItemQAV::Event(CGameMenuEvent &event) pMenu->FocusNextItem(); return false; case kMenuEventInit: - if (at20) - { - if (!at28) - { - at24 = gSysRes.Lookup(at20, "QAV"); - if (!at24) - ThrowError("Could not load QAV %s\n", at20); - at28 = (QAV*)gSysRes.Lock(at24); - at28->nSprite = -1; - at28->x = m_nX; - at28->y = m_nY; - at28->Preload(); - at2c = at28->at10; - at30 = (int)totalclock; - return false; - } - gSysRes.Lock(at24); - } - return false; - case kMenuEventDeInit: - if (at20 && at28) - { - gSysRes.Unlock(at24); - if (at24->LockCount() == 0) - at28 = NULL; - } return false; } return CGameMenuItem::Event(event); diff --git a/source/blood/src/gamemenu.h b/source/blood/src/gamemenu.h index eeba0d837..25409acee 100644 --- a/source/blood/src/gamemenu.h +++ b/source/blood/src/gamemenu.h @@ -31,17 +31,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS -class CMenuTextMgr -{ -public: - int at0; - CMenuTextMgr(); - void DrawText(const char *pString, int nFont, int x, int y, int nShade, int nPalette, bool shadow ); - void GetFontInfo(int nFont, const char *pString, int *pXSize, int *pYSize); -}; - -extern CMenuTextMgr gMenuTextMgr; - void drawLoadingScreen(void); void UpdateNetworkMenus(void); @@ -329,22 +318,6 @@ public: virtual bool Event(CGameMenuEvent &); }; -class CGameMenuItemQAV : public CGameMenuItem -{ -public: - const char *at20; - DICTNODE *at24; - QAV *at28; - int at2c; - int at30; - bool bWideScreen; - bool bClearBackground; - CGameMenuItemQAV(); - CGameMenuItemQAV(const char *, int, int, int, const char *, bool widescreen = false, bool clearbackground = false); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); - void Reset(void); -}; class CGameMenuItemZCycleSelect : public CGameMenuItem { diff --git a/source/blood/src/menu.cpp b/source/blood/src/menu.cpp index e105d86fc..ccba6f643 100644 --- a/source/blood/src/menu.cpp +++ b/source/blood/src/menu.cpp @@ -187,12 +187,6 @@ CGameMenu menuNetwork; CGameMenu menuNetworkHost; CGameMenu menuNetworkJoin; -CGameMenuItemQAV itemBloodQAV("", 3, 160, 100, "BDRIP", true); -CGameMenuItemQAV itemCreditsQAV("", 3, 160, 100, "CREDITS", false, true); -CGameMenuItemQAV itemHelp3QAV("", 3, 160, 100, "HELP3", false, false); -CGameMenuItemQAV itemHelp3BQAV("", 3, 160, 100, "HELP3B", false, false); -CGameMenuItemQAV itemHelp4QAV("", 3, 160, 100, "HELP4", false, true); -CGameMenuItemQAV itemHelp5QAV("", 3, 160, 100, "HELP5", false, true); CGameMenuItemTitle itemMainTitle("BLOOD", 1, 160, 20, 2038); CGameMenuItemChain itemMain1("NEW GAME", 1, 0, 45, 320, 1, &menuEpisode, -1, NULL, 0); diff --git a/source/blood/src/messages.cpp b/source/blood/src/messages.cpp index ef2f8c5a0..6993247c5 100644 --- a/source/blood/src/messages.cpp +++ b/source/blood/src/messages.cpp @@ -383,7 +383,7 @@ void CGameMessageMgr::Display(void) if (gViewMode == 3) { int height; - gMenuTextMgr.GetFontInfo(nFont, pMessage->text, &height, NULL); + viewGetFontInfo(nFont, pMessage->text, &height, NULL); if (x+height > gViewX1S) viewUpdatePages(); } @@ -428,7 +428,7 @@ void CGameMessageMgr::Display(void) if (gViewMode == 3) { int height; - gMenuTextMgr.GetFontInfo(nFont, pMessage->text, &height, NULL); + viewGetFontInfo(nFont, pMessage->text, &height, NULL); if (x+height > gViewX1S) viewUpdatePages(); } diff --git a/source/blood/src/view.cpp b/source/blood/src/view.cpp index ff61a06e5..61acd766a 100644 --- a/source/blood/src/view.cpp +++ b/source/blood/src/view.cpp @@ -1004,39 +1004,6 @@ void viewDrawText(int nFont, const char *pString, int x, int y, int nShade, int if (shadow) G_ScreenText(pFont->tile, x + 1, y + 1, 65536, 0, 0, pString, 127, nPalette, 2|8|16|nStat, alpha, 0, 0, pFont->space, 0, nFlags, 0, 0, xdim-1, ydim-1); G_ScreenText(pFont->tile, x, y, 65536, 0, 0, pString, nShade, nPalette, 2|8|16|nStat, alpha, 0, 0, pFont->space, 0, nFlags, 0, 0, xdim-1, ydim-1); - //if (nFont < 0 || nFont >= 5 || !pString) return; - //FONT *pFont = &gFont[nFont]; - // - //if (position) - //{ - // const char *s = pString; - // int width = -pFont->space; - // while (*s) - // { - // int nTile = ((*s-' ')&127)+pFont->tile; - // if (tilesiz[nTile].x && tilesiz[nTile].y) - // width += tilesiz[nTile].x+pFont->space; - // s++; - // } - // if (position == 1) - // width >>= 1; - // x -= width; - //} - //const char *s = pString; - //while (*s) - //{ - // int nTile = ((*s-' ')&127) + pFont->tile; - // if (tilesiz[nTile].x && tilesiz[nTile].y) - // { - // if (shadow) - // { - // rotatesprite_fs_alpha((x+1)<<16, (y+1)<<16, 65536, 0, nTile, 127, nPalette, 26|nStat, alpha); - // } - // rotatesprite_fs_alpha(x<<16, y<<16, 65536, 0, nTile, nShade, nPalette, 26|nStat, alpha); - // x += tilesiz[nTile].x+pFont->space; - // } - // s++; - //} } void viewTileSprite(int nTile, int nShade, int nPalette, int x1, int y1, int x2, int y2) @@ -3632,7 +3599,7 @@ void viewLoadingScreenWide(void) void viewLoadingScreenUpdate(const char *pzText4, int nPercent) { int vc; - gMenuTextMgr.GetFontInfo(1, NULL, NULL, &vc); + viewGetFontInfo(1, NULL, NULL, &vc); if (nLoadingScreenTile == kLoadScreen) viewLoadingScreenWide(); else if (nLoadingScreenTile) diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index cbdcf7e3f..c65cbd35b 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -213,7 +213,7 @@ struct GameInterface virtual void set_hud_scale(int size) = 0; virtual FString statFPS() { return "FPS display not available"; } virtual GameStats getStats() { return {}; } - virtual void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int flags) {} + virtual void DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) {} virtual void MainMenuOpened() {} virtual void MenuOpened() {} virtual void MenuClosed() {} diff --git a/source/common/2d/v_drawtext.cpp b/source/common/2d/v_drawtext.cpp index 46bc9a608..9bf96be39 100644 --- a/source/common/2d/v_drawtext.cpp +++ b/source/common/2d/v_drawtext.cpp @@ -44,6 +44,7 @@ #include "v_draw.h" #include "image.h" #include "v_2ddrawer.h" +#include "gstrings.h" #include "v_font.h" class FFont; @@ -225,7 +226,7 @@ void DrawText(F2DDrawer* drawer, FFont *font, int normalcolor, double x, double { return; } - DrawTextCommon(drawer, font, normalcolor, x, y, (const uint8_t*)string, parms); + DrawTextCommon(drawer, font, normalcolor, x, y, (const uint8_t*)GStrings.localize(string), parms); } void DrawText(F2DDrawer* drawer, FFont *font, int normalcolor, double x, double y, const char32_t *string, int tag_first, ...) diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 4d7c67f38..07767ba36 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -270,7 +270,7 @@ void DListMenu::PreDraw() { if (mDesc->mCaption.IsNotEmpty()) { - gi->DrawMenuCaption(origin, mDesc->mCaption); + gi->DrawMenuCaption(origin, GStrings.localize(mDesc->mCaption)); } } @@ -447,7 +447,6 @@ void FListMenuItemStaticText::Drawer(DListMenu* menu, const DVector2& origin, bo const char *text = mText; if (text != NULL) { - if (*text == '$') text = GStrings(text+1); if (mYpos >= 0) { int x = mXpos; @@ -550,7 +549,6 @@ void FListMenuItemText::Drawer(DListMenu* menu, const DVector2& origin, bool sel const char *text = mText; if (mText.Len()) { - if (*text == '$') text = GStrings(text+1); DrawText(&twod, mFont, selected ? mColorSelected : mColor, mXpos, mYpos, text, DTA_Clean, true, TAG_DONE); } } @@ -560,8 +558,7 @@ int FListMenuItemText::GetWidth() const char *text = mText; if (mText.Len()) { - if (*text == '$') text = GStrings(text+1); - return mFont->StringWidth(text); + return mFont->StringWidth(GStrings.localize(text)); } return 1; } @@ -592,9 +589,8 @@ void FListMenuItemNativeText::Drawer(DListMenu* menu, const DVector2& origin, bo const char* text = mText; if (mText.Len() && !mHidden) { - if (*text == '$') text = GStrings(text + 1); auto state = selected ? NIT_SelectedState : mEnabled ? NIT_ActiveState : NIT_InactiveState; - gi->DrawNativeMenuText(mFontnum, state, int((origin.X + mXpos) * 65536) , int((origin.Y + mYpos) * 65536), 1.f, text, menu->Descriptor()->mFlags); + gi->DrawNativeMenuText(mFontnum, state, origin.X + mXpos, origin.Y + mYpos, 1.f, GStrings.localize(text), menu->Descriptor()->mFlags); } } diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index ae6fe06ea..525fe4ccf 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -54,6 +54,7 @@ void RegisterDukeMenus(); void RegisterRedneckMenus(); +void RegisterBloodMenus(); void RegisterLoadsaveMenus(); extern bool rotatesprite_2doverride; bool help_disabled, credits_disabled; @@ -897,6 +898,7 @@ void M_Init (void) { RegisterDukeMenus(); RegisterRedneckMenus(); + RegisterBloodMenus(); RegisterLoadsaveMenus(); timerSetCallback(M_Ticker); M_ParseMenuDefs(); diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 63f66dc93..0cdc2eb59 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -415,7 +415,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) auto it = new FListMenuItemNativeText(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, text, desc->mNativeFontNum, desc->mNativePalNum, desc->mNativeFontScale, action, param); desc->mItems.Push(it); - //desc->mYpos += desc->mLinespacing; + desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size() - 1; } @@ -1142,13 +1142,15 @@ static void BuildEpisodeMenu() { FListMenuDescriptor *ld = static_cast(*desc); ld->mSelectedItem = gDefaultVolume; + int y = ld->mYpos; for (int i = 0; i < MAXVOLUMES; i++) { if (gVolumeNames[i].IsNotEmpty() && !(gVolumeFlags[i] & EF_HIDEFROMSP)) { - auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, gVolumeNames[i][0], gVolumeNames[i], NIT_BigFont, NIT_ActiveState, 1, NAME_SkillMenu, i); + auto it = new FListMenuItemNativeText(ld->mXpos, y, 0, gVolumeNames[i][0], gVolumeNames[i], NIT_BigFont, NIT_ActiveState, 1, NAME_SkillMenu, i); + y += ld->mLinespacing; ld->mItems.Push(it); addedVolumes++; if (gVolumeSubtitles[i].IsNotEmpty()) @@ -1163,7 +1165,8 @@ static void BuildEpisodeMenu() //auto it = new FListMenuItemNativeStaticText(ld->mXpos, "", NIT_SmallFont); // empty entry as spacer. //ld->mItems.Push(it); - auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, 0, "$MNU_USERMAP", NIT_BigFont, NIT_ActiveState, 1, NAME_UsermapMenu); + y += ld->mLinespacing / 3; + auto it = new FListMenuItemNativeText(ld->mXpos, y, 0, 0, "$MNU_USERMAP", NIT_BigFont, NIT_ActiveState, 1, NAME_UsermapMenu); ld->mItems.Push(it); addedVolumes++; if (g_gameType & GAMEFLAG_SW) // fixme: make this game independent. @@ -1185,12 +1188,14 @@ static void BuildEpisodeMenu() { FListMenuDescriptor* ld = static_cast(*desc); ld->mSelectedItem = gDefaultSkill; + int y = ld->mYpos; for (int i = 0; i < MAXSKILLS; i++) { if (gSkillNames[i].IsNotEmpty()) { - auto it = new FListMenuItemNativeText(ld->mXpos, 0, 0, gSkillNames[i][0], gSkillNames[i], NIT_BigFont, NIT_ActiveState, 1, NAME_StartGame, i); + auto it = new FListMenuItemNativeText(ld->mXpos, y, 0, gSkillNames[i][0], gSkillNames[i], NIT_BigFont, NIT_ActiveState, 1, NAME_StartGame, i); + y += ld->mLinespacing; ld->mItems.Push(it); addedSkills++; } diff --git a/source/common/menu/messagebox.cpp b/source/common/menu/messagebox.cpp index 06f59b59a..e8f1de041 100644 --- a/source/common/menu/messagebox.cpp +++ b/source/common/menu/messagebox.cpp @@ -99,8 +99,7 @@ void DMessageBoxMenu::Init(DMenu *parent, const char *message, int messagemode, mParentMenu = parent; if (message != NULL) { - if (*message == '$') message = GStrings(message+1); - mMessage = V_BreakLines(SmallFont, 300, message); + mMessage = V_BreakLines(SmallFont, 300, GStrings.localize(message)); } mMessageMode = messagemode; if (playsound) diff --git a/source/common/menu/optionmenu.cpp b/source/common/menu/optionmenu.cpp index 6e0c595f4..8076f8635 100644 --- a/source/common/menu/optionmenu.cpp +++ b/source/common/menu/optionmenu.cpp @@ -70,7 +70,6 @@ int OptionWidth(const char * s) void DrawOptionText(int x, int y, int color, const char *text, bool grayed) { - text = *text == '$'? GStrings(text+1) : text; PalEntry overlay = grayed? PalEntry(96,48,0,0) : PalEntry(0,0,0); DrawText (&twod, OptionFont(), color, x, y, text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay); } @@ -405,7 +404,7 @@ void DOptionMenu::Drawer () if (mDesc->mTitle.IsNotEmpty()) { - gi->DrawMenuCaption(origin, mDesc->mTitle); + gi->DrawMenuCaption(origin, GStrings.localize(mDesc->mTitle)); } mDesc->mDrawTop = y; int fontheight = OptionSettings.mLinespacing * CleanYfac_1; @@ -503,9 +502,7 @@ int FOptionMenuItem::GetIndent() { if (mCentered) return 0; if (screen->GetWidth() < 640) return screen->GetWidth() / 2; - const char *label = mLabel; - if (*label == '$') label = GStrings(label+1); - return OptionWidth(label); + return OptionWidth(GStrings.localize(mLabel)); } void FOptionMenuItem::drawText(int x, int y, int color, const char * text, bool grayed) @@ -515,9 +512,7 @@ void FOptionMenuItem::drawText(int x, int y, int color, const char * text, bool int FOptionMenuItem::drawLabel(int indent, int y, EColorRange color, bool grayed) { - const char *label = mLabel; - if (*label == '$') label = GStrings(label+1); - + const char *label = GStrings.localize(mLabel); int x; int w = OptionWidth(label) * CleanXfac_1; if (!mCentered) x = indent - w; diff --git a/source/common/menu/optionmenuitems.h b/source/common/menu/optionmenuitems.h index fdabd2e33..2a35fe1aa 100644 --- a/source/common/menu/optionmenuitems.h +++ b/source/common/menu/optionmenuitems.h @@ -154,10 +154,8 @@ public: bool Activate(FName caller) override { - auto msg = mPrompt.IsNotEmpty()? mPrompt.GetChars() : "$SAFEMESSAGE"; - if (*msg == '$') msg = GStrings(msg+1); - auto actionLabel = mLabel.GetChars(); - if (*actionLabel == '$') actionLabel = GStrings(actionLabel+1); + auto msg = GStrings.localize(mPrompt.IsNotEmpty()? mPrompt.GetChars() : "$SAFEMESSAGE"); + auto actionLabel = GStrings.localize(mLabel.GetChars()); FStringf FullString("%s%s%s\n\n%s", TEXTCOLOR_WHITE, actionLabel, TEXTCOLOR_NORMAL, msg); M_StartMessage(FullString, 0, mScriptId); @@ -536,8 +534,7 @@ public: int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override { - const char *txt = mCurrent? mAltText.GetChars() : mLabel.GetChars(); - if (*txt == '$') txt = GStrings(txt + 1); + const char *txt = GStrings.localize(mCurrent? mAltText.GetChars() : mLabel.GetChars()); int w = OptionWidth(txt) * CleanXfac_1; int x = (screen->GetWidth() - w) / 2; drawText(x, y, mColor, txt); diff --git a/source/common/utility/stringtable.h b/source/common/utility/stringtable.h index c9f71bfa2..e66f45eee 100644 --- a/source/common/utility/stringtable.h +++ b/source/common/utility/stringtable.h @@ -123,6 +123,11 @@ public: //return FStringf("${%.*s}", len, str); return FString(str, len); } + + const char* localize(const char* str) + { + return *str == '$' ? GetString(str + 1, nullptr) : str; + } }; #endif //__STRINGTABLE_H__ diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 340216664..ab7b8e8b4 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -148,7 +148,6 @@ static void Menu_DrawTopBar(const DVector2 &origin) static void Menu_DrawTopBarCaption(const char *caption, const DVector2 &origin) { static char t[64]; - if (*caption == '$') caption = GStrings(caption + 1); size_t const srclen = strlen(caption); size_t const dstlen = min(srclen, ARRAY_SIZE(t)-1); memcpy(t, caption, dstlen); @@ -240,47 +239,6 @@ static int Menu_GetFontHeight(int fontnum) return font.get_yline(); } -void GameInterface::DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int flags) -{ - int ydim_upper = 0; - int ydim_lower = ydim - 1; - //int32_t const indent = 0; // not set for any relevant menu - int32_t x = xpos; - - uint8_t status = 0; - if (state == NIT_SelectedState) - status |= MT_Selected; - if (state == NIT_InactiveState) - status |= MT_Disabled; - if (flags & LMF_Centered) - status |= MT_XCenter; - - bool const dodraw = true; - MenuFont_t& font = fontnum == NIT_BigFont ? MF_Redfont : fontnum == NIT_SmallFont ? MF_Bluefont : MF_Minifont; - - int32_t const height = font.get_yline(); - status |= MT_YCenter; - int32_t const y_internal = ypos + ((height >> 17) << 16);// -menu->scrollPos; - - vec2_t textsize; - if (dodraw) - textsize = Menu_Text(x, y_internal, &font, text, status, ydim_upper, ydim_lower); - - if (dodraw && (status & MT_Selected) && state != 1) - { - if (status & MT_XCenter) - { - Menu_DrawCursorLeft(x + font.cursorCenterPosition, y_internal, font.cursorScale); - Menu_DrawCursorRight(x - font.cursorCenterPosition, y_internal, font.cursorScale); - } - else - Menu_DrawCursorLeft(x /*+ indent*/ - font.cursorLeftPosition, y_internal, font.cursorScale); - } - -} - - - //---------------------------------------------------------------------------- // // Implements the native looking menu used for the main menu @@ -330,7 +288,6 @@ protected: int32_t calculatedentryspacing = 0; int32_t const height = Menu_GetFontHeight(mDesc->mNativeFontNum) >> 16; - // None of the menus still being supported will hide entries - only decactivate them if not applicable. int32_t totalheight = 0, numvalidentries = mDesc->mItems.Size(); for (unsigned e = 0; e < mDesc->mItems.Size(); ++e) @@ -393,7 +350,7 @@ class DukeNewGameCustomSubMenu : public DukeListMenu } }; -class MainMenu : public DukeListMenu +class DukeMainMenu : public DukeListMenu { void PreDraw() override { @@ -413,6 +370,44 @@ class MainMenu : public DukeListMenu // //---------------------------------------------------------------------------- +void GameInterface::DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) +{ + int ydim_upper = 0; + int ydim_lower = ydim - 1; + //int32_t const indent = 0; // not set for any relevant menu + int x = int(xpos * 65536); + + uint8_t status = 0; + if (state == NIT_SelectedState) + status |= MT_Selected; + if (state == NIT_InactiveState) + status |= MT_Disabled; + if (flags & LMF_Centered) + status |= MT_XCenter; + + bool const dodraw = true; + MenuFont_t& font = fontnum == NIT_BigFont ? MF_Redfont : fontnum == NIT_SmallFont ? MF_Bluefont : MF_Minifont; + + int32_t const height = font.get_yline(); + status |= MT_YCenter; + int32_t const y_internal = ypos + ((height >> 17) << 16);// -menu->scrollPos; + + vec2_t textsize; + if (dodraw) + textsize = Menu_Text(x, y_internal, &font, text, status, ydim_upper, ydim_lower); + + if (dodraw && (status & MT_Selected) && state != 1) + { + if (status & MT_XCenter) + { + Menu_DrawCursorLeft(x + font.cursorCenterPosition, y_internal, font.cursorScale); + Menu_DrawCursorRight(x - font.cursorCenterPosition, y_internal, font.cursorScale); + } + else + Menu_DrawCursorLeft(x /*+ indent*/ - font.cursorLeftPosition, y_internal, font.cursorScale); + } + +} void GameInterface::MenuOpened() { @@ -722,7 +717,7 @@ END_DUKE_NS //---------------------------------------------------------------------------- -static TMenuClassDescriptor _mm("Duke.MainMenu"); +static TMenuClassDescriptor _mm("Duke.MainMenu"); static TMenuClassDescriptor _lm("Duke.ListMenu"); static TMenuClassDescriptor _ngcsm("Duke.NewGameCustomSubMenu"); diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index 7c431e595..d43f0f2e3 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -155,7 +155,7 @@ struct GameInterface : ::GameInterface GameStats getStats() override; // Access to the front end specific menu code. Use is restricted to the main menu, the ingame menu and the skill/episode selection. // Everything else is either custom screens or will use the generic option menu style. - void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int orientation) override; + void DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int orientation) override; void MenuOpened() override; void MenuClosed() override; void MenuSound(EMenuSounds snd) override; diff --git a/source/duke3d/src/screentext.cpp b/source/duke3d/src/screentext.cpp index 183479a9c..bc17bbe12 100644 --- a/source/duke3d/src/screentext.cpp +++ b/source/duke3d/src/screentext.cpp @@ -469,7 +469,6 @@ vec2_t G_ScreenText(const int32_t font, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, const int32_t f, const int32_t x1, const int32_t y1, const int32_t x2, const int32_t y2) { - if (*str == '$') str = GStrings(str + 1); vec2_t size = { 0, 0, }; // eventually the return value vec2_t origin = { 0, 0, }; // where to start, depending on the alignment vec2_t pos = { 0, 0, }; // holds the coordinate position as we draw each character tile of the string diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index 960dd7d41..88ada21d4 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -151,7 +151,6 @@ static void Menu_DrawTopBar(const DVector2 &origin) static void Menu_DrawTopBarCaption(const char* caption, const DVector2& origin) { static char t[64]; - if (*caption == '$') caption = GStrings(caption + 1); size_t const srclen = strlen(caption); size_t const dstlen = min(srclen, ARRAY_SIZE(t) - 1); memcpy(t, caption, dstlen); @@ -231,47 +230,6 @@ static int Menu_GetFontHeight(int fontnum) return font.get_yline(); } -void GameInterface::DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int flags) -{ - int ydim_upper = 0; - int ydim_lower = ydim - 1; - //int32_t const indent = 0; // not set for any relevant menu - int32_t x = xpos; - - uint8_t status = 0; - if (state == NIT_SelectedState) - status |= MT_Selected; - if (state == NIT_InactiveState) - status |= MT_Disabled; - if (flags & LMF_Centered) - status |= MT_XCenter; - - bool const dodraw = true; - MenuFont_t& font = fontnum == NIT_BigFont ? MF_Redfont : fontnum == NIT_SmallFont ? MF_Bluefont : MF_Minifont; - - int32_t const height = font.get_yline(); - status |= MT_YCenter; - int32_t const y_internal = ypos + ((height >> 17) << 16);// -menu->scrollPos; - - vec2_t textsize; - if (dodraw) - textsize = Menu_Text(x, y_internal, &font, text, status, ydim_upper, ydim_lower); - - if (dodraw && (status & MT_Selected) && state != 1) - { - if (status & MT_XCenter) - { - Menu_DrawCursorLeft(x + font.cursorCenterPosition, y_internal, font.cursorScale); - Menu_DrawCursorRight(x - font.cursorCenterPosition, y_internal, font.cursorScale); - } - else - Menu_DrawCursorLeft(x /*+ indent*/ - font.cursorLeftPosition, y_internal, font.cursorScale); - } - -} - - - //---------------------------------------------------------------------------- // // Implements the native looking menu used for the main menu @@ -323,7 +281,7 @@ protected: } }; -class MainMenu : public RedneckListMenu +class RedneckMainMenu : public RedneckListMenu { void PreDraw() override { @@ -341,6 +299,45 @@ class MainMenu : public RedneckListMenu // //---------------------------------------------------------------------------- +void GameInterface::DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) +{ + int ydim_upper = 0; + int ydim_lower = ydim - 1; + //int32_t const indent = 0; // not set for any relevant menu + int x = int(xpos * 65536 * 6); + + uint8_t status = 0; + if (state == NIT_SelectedState) + status |= MT_Selected; + if (state == NIT_InactiveState) + status |= MT_Disabled; + if (flags & LMF_Centered) + status |= MT_XCenter; + + bool const dodraw = true; + MenuFont_t& font = fontnum == NIT_BigFont ? MF_Redfont : fontnum == NIT_SmallFont ? MF_Bluefont : MF_Minifont; + + int32_t const height = font.get_yline(); + status |= MT_YCenter; + int32_t const y_internal = int(ypos * 65536) + ((height >> 17) << 16);// -menu->scrollPos; + + vec2_t textsize; + if (dodraw) + textsize = Menu_Text(x, y_internal, &font, text, status, ydim_upper, ydim_lower); + + if (dodraw && (status & MT_Selected) && state != 1) + { + if (status & MT_XCenter) + { + Menu_DrawCursorLeft(x + font.cursorCenterPosition, y_internal, font.cursorScale); + Menu_DrawCursorRight(x - font.cursorCenterPosition, y_internal, font.cursorScale); + } + else + Menu_DrawCursorLeft(x /*+ indent*/ - font.cursorLeftPosition, y_internal, font.cursorScale); + } + +} + void GameInterface::MenuOpened() { @@ -487,7 +484,7 @@ END_RR_NS //---------------------------------------------------------------------------- -static TMenuClassDescriptor _mm("Redneck.MainMenu"); +static TMenuClassDescriptor _mm("Redneck.MainMenu"); static TMenuClassDescriptor _lm("Redneck.ListMenu"); void RegisterRedneckMenus() diff --git a/source/rr/src/duke3d.h b/source/rr/src/duke3d.h index aedcb0ece..44fd44bce 100644 --- a/source/rr/src/duke3d.h +++ b/source/rr/src/duke3d.h @@ -157,7 +157,7 @@ struct GameInterface : ::GameInterface void set_hud_scale(int size) override; FString statFPS() override; GameStats getStats() override; - void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int flags); + void DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags); void MenuOpened() override; void MenuSound(EMenuSounds snd) override; void MenuClosed() override; diff --git a/source/rr/src/screentext.cpp b/source/rr/src/screentext.cpp index 75b1b2d1a..cc0a49ae6 100644 --- a/source/rr/src/screentext.cpp +++ b/source/rr/src/screentext.cpp @@ -468,7 +468,6 @@ vec2_t G_ScreenText(const int32_t font, int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, const int32_t f, const int32_t x1, const int32_t y1, const int32_t x2, const int32_t y2) { - if (*str == '$') str = GStrings(str + 1); vec2_t size = { 0, 0, }; // eventually the return value vec2_t origin = { 0, 0, }; // where to start, depending on the alignment vec2_t pos = { 0, 0, }; // holds the coordinate position as we draw each character tile of the string diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index fcd7b65f3..7ccb43e91 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -8,32 +8,18 @@ Save Game,MNU_SAVEGAME,,,,Uložit hru,Spiel sichern,,Konservi Ludon,Guardar Part Help,MNU_HELP,,,,,Hilfe,,,,,,Aide,,,,,,,,,,, Continue,MNU_CONTINUE,,,,,Fortfahren,,,,,,,,,,,,,,,,, Credits,MNU_CREDITS,,,,,,,,,,,,,,,,,,,,,, -Cool Stuff,MNU_COOLSTUFF,,,,,Cooles Zeug,,,,,,,,,,,,,,,,, +Cool Stuff,MNU_COOLSTUFF,Was removed,,,,Cooles Zeug,,,,,,,,,,,,,,,,, Multiplayer,MNU_MULTIPLAYER,,,,,Mehrspieler,,,,,,,,,,,,,,,,, End Game,MNU_ENDGAME,,,,,Spiel beenden,,,,,,,,,,,,,,,,, User Map,MNU_USERMAP,,,,,Benutzerlevel,,,,,,,,,,,,,,,,, Select a user map to play,MNU_SELECTUSERMAP,,,,,"Wähle ein Level zum Spielen ",,,,,,,,,,,,,,,,, -Select an Episode,MNU_SELECTEPISODE,,,,,"Welche Episode? +Select an Episode,MNU_SELECTEPISODE,DN3D et.al.,,,,"Welche Episode? ",,,,,,,,,,,,,,,,, -Select Skill,MNU_SELECTSKILL,,,,,Schwierigkeitsgrad,,,,,,,,,,,,,,,,, +Episodes,MNU_EPISODES,Blood,,,,Episoden,,,,,,,,,,,,,,,,, +Select Skill,MNU_SELECTSKILL,DN3D et.al.,,,,Schwierigkeitsgrad,,,,,,,,,,,,,,,,, +Difficulty,MBU_DIFFICULTY,Blood,,,,Schwierigkeitsgrad,,,,,,,,,,,,,,,,, About Demolition,MNU_ENGINECREDITS,,,,,Über Demolition,,,,,,,,,,,,,,,,, -No Picture,MNU_NOPICTURE,,,,Bez obrázku,Kein Bild,,Neniu Bildo,Sin Imagen,,Ei kuvaa,Pas d'image,,Nessuna immagine,画像無し,사진 없음,Geen beeld,Brak obrazka,Sem imagem,,,"Нет -изображения",Нема слике -"Different -Version",MNU_DIFFVERSION,,,,Jiná verze,Falsche Version,,Malsama Versio,Versión Diferente,,Eri versio,"Version -Différente",,Versione differente,"別バージョンの -データ",다른 버젼,Anders Versie,"Inna -Wersja","Versão -Diferente",,,"Другая -версия",Другачија верзија -No files,MNU_NOFILES,,,,Žádné soubory,Keine Dateien,,Neniuj dosieroj,Sin archivos,,Ei tiedostoja,Pas de fichiers,,Nessun file,ファイル無し,파일 없음,Geen bestanden,Brak plików,Vazio,,,Нет файлов,Нема фајлова -"Do you really want to delete the savegame -",MNU_DELETESG,,,,Opravdu chceš smazat tuto uloženou hru?,Willst du diesen Spielstand wirklich löschen?,,Ĉu vi vere volas forviŝi la konservan ludon?,"¿Realmente deseas eliminar la partida? -",,Haluatko varmasti poistaa tallennetun pelin ,"Voulez vous vraiment effacer cette sauvegarde? -",Biztos ki akarod törölni a mentést?,Vuoi veramente rimuovere il salvataggio,本当にこのセーブを消すのか?,저장된 게임을 정말로 삭제하시겠습니까?,Wil je echt de opgeslagen spel verwijderen?,Czy naprawdę chcesz usunąć zapis gry,"Deseja mesmo deletar o jogo salvo -",Deseja mesmo apagar o jogo,,"Вы действительно хотите удалить сохранение -",Да ли стварно желите да избришете сачувану игру Press Y or N.,PRESSYN,,,,Stiskni Y nebo N.,Drücke Y oder N.,"Πάτα Y ή N ",Premu Y aŭ N.,Presiona Y ó N.,,Paina Y tai N.,Appuyez sur Y ou N.,Nyomj Y-t vagy N-t.,Premi Y oppure N.,YかNで答えろ,Y키 또는 N키를 누르시오.,Druk op Y of N.,Wciśnij Y lub N.,Aperte Y ou N.,Carrega Y ou N.,,Нажмите Y или N.,Притисните Y или N. "You can't save if you aren't playing! @@ -210,4 +196,22 @@ Empty slot,EMPTYSTRING,,,,Prázdný slot,nicht belegt,,Malplena Ingo,Ranura Vac ,NEWSAVE,,,,,,,,,,,,<Új mentés>,,<新規セーブ>,<새로운 게임 저장>,,,,,,<Новое сохранение>,<Нова сачувана игра> Game saved.,GGSAVED,,,,Hra uložena.,Spielstand gespeichert.,,Ludo konservita.,Partida guardada.,,Peli tallennettu.,Partie sauvegardée.,Játék mentve.,Gioco salvato.,セーブ完了。,게임이 저장됨.,Spel opgeslagen.,Gra zapisana.,Jogo salvo.,Jogo gravado.,,Игра сохранена.,Игра сачувана. Time,SAVECOMMENT_TIME,,,,Čas,Zeit,,Tempo,Tiempo,,Aika,Temps,Idő,Tempo,"時間 -",시간,Tijd,Czas,Tempo,,,Время,Време \ No newline at end of file +",시간,Tijd,Czas,Tempo,,,Время,Време +Load Game,MNU_LOADGAME,,,,Načíst hru,Spiel laden,,Ŝarĝi Ludon,Cargar Partida,,Lataa peli,Chargement,,Carica gioco,ロード,게임 불러오기,Laden spel,Wczytaj Grę,Carregar,,,Загрузка,Учитај игру +Save Game,MNU_SAVEGAME,,,,Uložit hru,Spiel sichern,,Konservi Ludon,Guardar Partida,,Tallenna peli,Sauvegarde,,Salva gioco,セーブ,게임 저장하기,Opslaan spel,Zapisz Grę,Salvar,Gravar,,Сохранение,Сачувај игру +No Picture,MNU_NOPICTURE,,,,Bez obrázku,Kein Bild,,Neniu Bildo,Sin Imagen,,Ei kuvaa,Pas d'image,,Nessuna immagine,画像無し,사진 없음,Geen beeld,Brak obrazka,Sem imagem,,,"Нет +изображения",Нема слике +"Different +Version",MNU_DIFFVERSION,,,,Jiná verze,Falsche Version,,Malsama Versio,Versión Diferente,,Eri versio,"Version +Différente",,Versione differente,"別バージョンの +データ",다른 버젼,Anders Versie,"Inna +Wersja","Versão +Diferente",,,"Другая +версия",Другачија верзија +No files,MNU_NOFILES,,,,Žádné soubory,Keine Dateien,,Neniuj dosieroj,Sin archivos,,Ei tiedostoja,Pas de fichiers,,Nessun file,ファイル無し,파일 없음,Geen bestanden,Brak plików,Vazio,,,Нет файлов,Нема фајлова +"Do you really want to delete the savegame +",MNU_DELETESG,,,,Opravdu chceš smazat tuto uloženou hru?,Willst du diesen Spielstand wirklich löschen?,,Ĉu vi vere volas forviŝi la konservan ludon?,"¿Realmente deseas eliminar la partida? +",,Haluatko varmasti poistaa tallennetun pelin ,"Voulez vous vraiment effacer cette sauvegarde? +",Biztos ki akarod törölni a mentést?,Vuoi veramente rimuovere il salvataggio,本当にこのセーブを消すのか?,저장된 게임을 정말로 삭제하시겠습니까?,Wil je echt de opgeslagen spel verwijderen?,Czy naprawdę chcesz usunąć zapis gry,"Deseja mesmo deletar o jogo salvo +",Deseja mesmo apagar o jogo,,"Вы действительно хотите удалить сохранение +",Да ли стварно желите да избришете сачувану игру \ No newline at end of file diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index ad6dabc68..9489d87ec 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -29,7 +29,7 @@ LISTMENU "MainMenu" class "Redneck.MainMenu" } NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" - //NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder (I'm not going to support EDuke's C/S implementation) + //NativeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder. ifgame(fury) { NativeTextItem "$MNU_CONTINUE", "l", "LoadGameMenu" @@ -45,6 +45,11 @@ LISTMENU "MainMenu" } ifgame(Blood) { + position 160, 45, 150 + caption "Blood" + class "Blood.ListMenu" + centermenu + Linespacing 20 NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" NativeTextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" @@ -105,7 +110,11 @@ LISTMENU "IngameMenu" } ifgame(Blood) { - linespacing 15 + position 160, 45, 150 + caption "Blood" + class "Blood.ListMenu" + centermenu + Linespacing 17 NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" NativeTextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" @@ -150,6 +159,14 @@ LISTMENU "EpisodeMenu" class "Redneck.ListMenu" } } + ifgame(blood) + { + caption "$MNU_EPISODES" + position 160, 45, 150 + class "Blood.ListMenu" + centermenu + Linespacing 20 + } ScriptId 100 } @@ -180,6 +197,14 @@ LISTMENU "SkillMenu" } animatedtransition } + ifgame(blood) + { + caption "$MNU_DIFFICULTY" + position 160, 60, 150 + class "Blood.ListMenu" + centermenu + Linespacing 20 + } ScriptId 110 } @@ -349,10 +374,17 @@ LISTMENU "MultiMenu" class "Redneck.ListMenu" } animatedtransition + NativeTextItem "$MNU_PLAYERSETUP", "p", "PlayerSetupMenu" + } + ifgame(blood) + { + position 160, 80, 150 + class "Blood.ListMenu" + centermenu + Linespacing 20 } Caption "$MNU_NETWORKGAME" - NativeTextItem "$MNU_PLAYERSETUP", "p", "PlayerSetupMenu" NativeTextItem "$MNU_JOINGAME", "j", "JoinGameMenu" NativeTextItem "$MNU_HOSTGAME", "h", "HostGameMenu" } @@ -382,9 +414,12 @@ ImageScroller "HelpMenu" } ifgame(blood) { + // The duplication here is to integrate the alternating versions of HELP3 QAVAnimationItem "Help4" QAVAnimationItem "Help5" QAVAnimationItem "Help3" + QAVAnimationItem "Help4" + QAVAnimationItem "Help5" QAVAnimationItem "Help3b" } ifgame(ShadowWarrior) From e2be025433408ff787c71b34b6f92cfeada98484 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2019 17:48:56 +0100 Subject: [PATCH 074/203] - fixed the Ion Fury credit screens. The entire 'fix' here consisted of hacks to give the CON script exactly what it needs to show them as intended. --- source/blood/src/d_menu.cpp | 2 +- source/common/menu/imagescroller.cpp | 34 +++++------------ source/common/menu/menu.cpp | 21 +++++++++-- source/common/menu/menu.h | 28 ++++++++++++-- source/common/menu/menudef.cpp | 5 +++ source/duke3d/src/d_menu.cpp | 56 +++++++++++++++++++++++++++- wadsrc/static/demolition/menudef.txt | 19 +++++++--- 7 files changed, 124 insertions(+), 41 deletions(-) diff --git a/source/blood/src/d_menu.cpp b/source/blood/src/d_menu.cpp index 2ba91858a..44c8874dd 100644 --- a/source/blood/src/d_menu.cpp +++ b/source/blood/src/d_menu.cpp @@ -381,7 +381,7 @@ void GameInterface::DrawMenuCaption(const DVector2& origin, const char* text) int height; // font #1, tile #2038. viewGetFontInfo(1, NULL, NULL, &height); - rotatesprite(int(origin.X * 65536) + 320 << 15, 20 << 16, 65536, 0, 2038, -128, 0, 78, 0, 0, xdim - 1, ydim - 1); + rotatesprite(int(origin.X * 65536) + (320 << 15), 20 << 16, 65536, 0, 2038, -128, 0, 78, 0, 0, xdim - 1, ydim - 1); viewDrawText(1, text, 160, 20 - height / 2, -128, 0, 1, false); } diff --git a/source/common/menu/imagescroller.cpp b/source/common/menu/imagescroller.cpp index 8193ab80b..d0a50895b 100644 --- a/source/common/menu/imagescroller.cpp +++ b/source/common/menu/imagescroller.cpp @@ -43,24 +43,6 @@ #include "gamecontrol.h" #include "build.h" -//============================================================================= -// -// Show a fullscreen image / centered text screen for an image scroller -// -//============================================================================= - -class ImageScreen : public DMenu // Todo: This should be global -{ - const FImageScrollerDescriptor::ScrollerItem* mDesc; -public: - ImageScreen(const FImageScrollerDescriptor::ScrollerItem* it) - { - mDesc = it; - } - void Drawer() override; -}; - - //============================================================================= // // Fullscreen image drawer (move to its own source file!) @@ -93,15 +75,19 @@ void ImageScreen::Drawer() } } - -DImageScrollerMenu::DImageScrollerMenu(DMenu* parent, FImageScrollerDescriptor* desc) - : DMenu(parent) +ImageScreen* DImageScrollerMenu::newImageScreen(FImageScrollerDescriptor::ScrollerItem* desc) { + return new ImageScreen(desc); +} + +void DImageScrollerMenu::Init(DMenu* parent, FImageScrollerDescriptor* desc) +{ + mParentMenu = parent; index = 0; mDesc = desc; canAnimate = !!(mDesc->mFlags & LMF_Animate); - mCurrent = new ImageScreen(&mDesc->mItems[0]); + mCurrent = newImageScreen(&mDesc->mItems[0]); mCurrent->canAnimate = canAnimate; } @@ -119,7 +105,7 @@ bool DImageScrollerMenu::MenuEvent(int mkey, bool fromcontroller) if (pageTransition.previous == nullptr) { if (--index < 0) index = mDesc->mItems.Size() - 1; - auto next = new ImageScreen(&mDesc->mItems[index]); + auto next = newImageScreen(&mDesc->mItems[index]); next->canAnimate = canAnimate; if (!pageTransition.StartTransition(mCurrent, next, MA_Return)) { @@ -135,7 +121,7 @@ bool DImageScrollerMenu::MenuEvent(int mkey, bool fromcontroller) if (pageTransition.previous == nullptr) { if (++index >= (int)mDesc->mItems.Size()) index = 0; - auto next = new ImageScreen(&mDesc->mItems[index]); + auto next = newImageScreen(&mDesc->mItems[index]); next->canAnimate = canAnimate; if (!pageTransition.StartTransition(mCurrent, next, MA_Advance)) { diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 525fe4ccf..6a4b2aff9 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -534,7 +534,6 @@ bool M_SetMenu(FName menu, int param, FName caller) } newmenu->Init(DMenu::CurrentMenu, ld); M_ActivateMenu(newmenu); - return true; } } else if ((*desc)->mType == MDESC_OptionsMenu) @@ -549,11 +548,25 @@ bool M_SetMenu(FName menu, int param, FName caller) else if ((*desc)->mType == MDESC_ImageScroller) { FImageScrollerDescriptor* ld = static_cast(*desc); - if (ld->mItems.Size() > 0) // only open the submenu if it isn't empty. + DImageScrollerMenu* newmenu; + if (ld->mClass != NAME_None) { - DImageScrollerMenu* newmenu = new DImageScrollerMenu(DMenu::CurrentMenu, ld); - M_ActivateMenu(newmenu); + auto ndx = menuClasses.FindEx([=](const auto p) { return p->mName == ld->mClass; }); + if (ndx == menuClasses.Size()) + { + I_Error("Bad menu class %s\n", ld->mClass.GetChars()); + } + else + { + newmenu = (DImageScrollerMenu*)menuClasses[ndx]->CreateNew(); + } } + else + { + newmenu = new DImageScrollerMenu; + } + newmenu->Init(DMenu::CurrentMenu, ld); + M_ActivateMenu(newmenu); } return true; } diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 6cf842a1c..3ab844da5 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -669,16 +669,19 @@ void DrawOptionText(int x, int y, int color, const char *text, bool grayed = fal // ImageScroller // //============================================================================= +class ImageScreen; class DImageScrollerMenu : public DMenu { - DMenu* mCurrent; - FImageScrollerDescriptor* mDesc; - int index; + DMenu* mCurrent = nullptr; + FImageScrollerDescriptor* mDesc = nullptr; + int index = 0; MenuTransition pageTransition = {}; + virtual ImageScreen* newImageScreen(FImageScrollerDescriptor::ScrollerItem* desc); + public: - DImageScrollerMenu(DMenu* parent = nullptr, FImageScrollerDescriptor* desc = nullptr); + void Init(DMenu* parent = nullptr, FImageScrollerDescriptor* desc = nullptr); bool MenuEvent(int mkey, bool fromcontroller); bool MouseEvent(int type, int x, int y); void Ticker(); @@ -722,6 +725,23 @@ public: }; +//============================================================================= +// +// Show a fullscreen image / centered text screen for an image scroller +// +//============================================================================= + +class ImageScreen : public DMenu +{ +protected: + const FImageScrollerDescriptor::ScrollerItem* mDesc; +public: + ImageScreen(const FImageScrollerDescriptor::ScrollerItem* it) + { + mDesc = it; + } + void Drawer() override; +}; diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 0cdc2eb59..4af11fb44 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -580,6 +580,11 @@ static void ParseImageScrollerBody(FScanner &sc, FImageScrollerDescriptor *desc) ParseImageScrollerBody(sc, desc); } } + else if (sc.Compare("Class")) + { + sc.MustGetString(); + desc->mClass = sc.String; + } else if (sc.Compare("TextItem") || sc.Compare("ImageItem")) { FImageScrollerDescriptor::ScrollerItem item; diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index ab7b8e8b4..e210eb205 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -330,7 +330,7 @@ protected: void PreDraw() override { - CallScript(CurrentMenu == this ? EVENT_DISPLAYMENU : EVENT_DISPLAYMENUREST, true); + CallScript(CurrentMenu == this ? EVENT_DISPLAYMENU : EVENT_DISPLAYINACTIVEMENU, true); Super::PreDraw(); } @@ -364,6 +364,56 @@ class DukeMainMenu : public DukeListMenu } }; +//---------------------------------------------------------------------------- +// +// Hack to display Ion Fury's credits screens +// +//---------------------------------------------------------------------------- + +class DukeImageScreen : public ImageScreen +{ +public: + DukeImageScreen(FImageScrollerDescriptor::ScrollerItem* desc) + : ImageScreen(desc) + {} + + void CallScript(int event, bool getorigin = false) + { + ud.returnvar[0] = int(origin.X * 65536); + ud.returnvar[1] = int(origin.Y * 65536); + ud.returnvar[2] = 0; + VM_OnEventWithReturn(event, g_player[screenpeek].ps->i, screenpeek, mDesc->scriptID); + if (getorigin) + { + origin.X = ud.returnvar[0] / 65536.; + origin.Y = ud.returnvar[1] / 65536.; + } + } + + void Drawer() override + { + // Hack alert: The Ion Fury scripts - being true to the entire design here, take the current menu value + // not from the passed variable but instead from the global current_menu, so we have to temporarily alter that here. + // Ugh. (Talk about "broken by design"...) + auto cm = g_currentMenu; + g_currentMenu = mDesc->scriptID; + auto o = origin; + CallScript(EVENT_DISPLAYMENU, true); + ImageScreen::Drawer(); + CallScript(EVENT_DISPLAYMENUREST, false); + g_currentMenu = cm; + origin = o; + } +}; + +class DDukeImageScrollerMenu : public DImageScrollerMenu +{ + ImageScreen* newImageScreen(FImageScrollerDescriptor::ScrollerItem* desc) override + { + return new DukeImageScreen(desc); + } +}; + //---------------------------------------------------------------------------- // // Menu related game interface functions @@ -390,7 +440,7 @@ void GameInterface::DrawNativeMenuText(int fontnum, int state, double xpos, doub int32_t const height = font.get_yline(); status |= MT_YCenter; - int32_t const y_internal = ypos + ((height >> 17) << 16);// -menu->scrollPos; + int32_t const y_internal = int(ypos * 65536) + ((height >> 17) << 16);// -menu->scrollPos; vec2_t textsize; if (dodraw) @@ -720,10 +770,12 @@ END_DUKE_NS static TMenuClassDescriptor _mm("Duke.MainMenu"); static TMenuClassDescriptor _lm("Duke.ListMenu"); static TMenuClassDescriptor _ngcsm("Duke.NewGameCustomSubMenu"); +static TMenuClassDescriptor _ism("Duke.ImageScrollerMenu"); void RegisterDukeMenus() { menuClasses.Push(&_mm); menuClasses.Push(&_lm); menuClasses.Push(&_ngcsm); + menuClasses.Push(&_ism); } diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 9489d87ec..05f71287d 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -397,21 +397,26 @@ LISTMENU "MultiMenu" ImageScroller "HelpMenu" { - ifgame(Duke, Nam, WW2GI, Redneck, RedneckRides) + ifgame(Duke, Nam, WW2GI, Fury) { ImageItem "TEXTSTORY", 400 ImageItem "F1HELP", 401 + class "Duke.ImageScrollerMenu" + ifgame(Duke, Nam, WW2GI) + { + animatedtransition + } + } + ifgame(Redneck, RedneckRides) + { + ImageItem "TEXTSTORY" + ImageItem "F1HELP" ifgame(RedneckRides) { ImageItem "RRTILE1636" } animatedtransition } - ifgame(fury) - { - ImageItem "TEXTSTORY", 400 - ImageItem "F1HELP", 401 - } ifgame(blood) { // The duplication here is to integrate the alternating versions of HELP3 @@ -452,12 +457,14 @@ ImageScroller "CreditsMenu" ImageItem "CREDITSTEXT2", 991 ImageItem "CREDITSTEXT3", 992 animatedtransition + class "Duke.ImageScrollerMenu" } ifgame(fury) { // Ion Fury does not have a separate credits menu, so if someone tries to open it anyway, use the same screens as "Help" but start on the one for the credits. ImageItem "F1HELP", 401 ImageItem "TEXTSTORY", 400 + class "Duke.ImageScrollerMenu" } ifgame(Redneck) { From e8c5939695f19f09407215cf6ffffc4bed112ef5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2019 20:17:30 +0100 Subject: [PATCH 075/203] - more work on Blood menus. Game start works. --- source/blood/src/blood.h | 2 - source/blood/src/d_menu.cpp | 193 ++++++--------------------- source/blood/src/levels.cpp | 4 - source/common/menu/imagescroller.cpp | 3 +- source/common/menu/menu.h | 1 + wadsrc/static/demolition/menudef.txt | 14 +- 6 files changed, 54 insertions(+), 163 deletions(-) diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index 612c65ca0..e4e1af4e4 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -90,13 +90,11 @@ struct GameInterface : ::GameInterface FString statFPS() override; FSavegameInfo GetSaveSig() override; void MenuOpened() override; - void MenuSound(EMenuSounds snd) override; void MenuClosed() override; bool CanSave() override; void StartGame(FGameStartup& gs) override; void DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) override; void DrawMenuCaption(const DVector2& origin, const char* text) override; - void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) override; }; END_BLD_NS diff --git a/source/blood/src/d_menu.cpp b/source/blood/src/d_menu.cpp index 44c8874dd..5b8e74b17 100644 --- a/source/blood/src/d_menu.cpp +++ b/source/blood/src/d_menu.cpp @@ -39,6 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "view.h" #include "demo.h" #include "network.h" +#include "mmulti.h" #include "c_bind.h" #include "menu/menu.h" @@ -136,13 +137,6 @@ void CGameMenuItemQAV::Draw(void) static std::unique_ptr itemBloodQAV; // This must be global to ensure that the animation remains consistent across menus. -/* -CGameMenuItemQAV itemCreditsQAV("", 3, 160, 100, "CREDITS", false, true); -CGameMenuItemQAV itemHelp3QAV("", 3, 160, 100, "HELP3", false, false); -CGameMenuItemQAV itemHelp3BQAV("", 3, 160, 100, "HELP3B", false, false); -CGameMenuItemQAV itemHelp4QAV("", 3, 160, 100, "HELP4", false, true); -CGameMenuItemQAV itemHelp5QAV("", 3, 160, 100, "HELP5", false, true); -*/ void UpdateNetworkMenus(void) @@ -172,29 +166,6 @@ void UpdateNetworkMenus(void) #endif } -void MenuSetupEpisodeInfo(void) -{ -#if 0 - memset(zEpisodeNames, 0, sizeof(zEpisodeNames)); - memset(zLevelNames, 0, sizeof(zLevelNames)); - for (int i = 0; i < 6; i++) - { - if (i < gEpisodeCount) - { - EPISODEINFO* pEpisode = &gEpisodeInfo[i]; - zEpisodeNames[i] = pEpisode->at0; - for (int j = 0; j < 16; j++) - { - if (j < pEpisode->nLevels) - { - zLevelNames[i][j] = pEpisode->data[j].at90; - } - } - } - } -#endif -} - //---------------------------------------------------------------------------- // // Implements the native looking menu used for the main menu @@ -216,6 +187,38 @@ protected: }; +//---------------------------------------------------------------------------- +// +// +// +//---------------------------------------------------------------------------- + +class BloodImageScreen : public ImageScreen +{ + CGameMenuItemQAV anim; +public: + BloodImageScreen(FImageScrollerDescriptor::ScrollerItem* desc) + : ImageScreen(desc), anim(169, 100, mDesc->text.GetChars(), false, true) + { + + } + + void Drawer() override + { + anim.Draw(); + } +}; + +class DBloodImageScrollerMenu : public DImageScrollerMenu +{ + ImageScreen* newImageScreen(FImageScrollerDescriptor::ScrollerItem* desc) override + { + if (desc->type >= 0) return DImageScrollerMenu::newImageScreen(desc); + return new BloodImageScreen(desc); + } +}; + + //---------------------------------------------------------------------------- // // Menu related game interface functions @@ -246,129 +249,29 @@ void GameInterface::DrawNativeMenuText(int fontnum, int state, double xpos, doub void GameInterface::MenuOpened() { -#if 0 - S_PauseSounds(true); - if ((!g_netServer && ud.multimode < 2)) - { - ready2send = 0; - totalclock = ototalclock; - screenpeek = myconnectindex; - } - - auto& gm = g_player[myconnectindex].ps->gm; - if (gm & MODE_GAME) - { - gm |= MODE_MENU; - } -#endif - itemBloodQAV.reset(new CGameMenuItemQAV(160, 100, "BDRIP.QAV", true)); } -void GameInterface::MenuSound(EMenuSounds snd) -{ -#if 0 - switch (snd) - { - case CursorSound: - S_PlaySound(RR ? 335 : KICK_HIT); - break; - - case AdvanceSound: - S_PlaySound(RR ? 341 : PISTOL_BODYHIT); - break; - - case CloseSound: - S_PlaySound(EXITMENUSOUND); - break; - - default: - return; - } -#endif -} - void GameInterface::MenuClosed() { itemBloodQAV.reset(); -#if 0 - auto& gm = g_player[myconnectindex].ps->gm; - if (gm & MODE_GAME) - { - if (gm & MODE_MENU) - I_ClearAllInput(); - - // The following lines are here so that you cannot close the menu when no game is running. - gm &= ~MODE_MENU; - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) - { - ready2send = 1; - totalclock = ototalclock; - CAMERACLOCK = (int32_t)totalclock; - CAMERADIST = 65536; - - // Reset next-viewscreen-redraw counter. - // XXX: are there any other cases like that in need of handling? - if (g_curViewscreen >= 0) - actor[g_curViewscreen].t_data[0] = (int32_t)totalclock; - } - - G_UpdateScreenArea(); - S_PauseSounds(false); - } -#endif } bool GameInterface::CanSave() { -#if 0 - if (ud.recstat == 2) return false; - auto& myplayer = *g_player[myconnectindex].ps; - if (sprite[myplayer.i].extra <= 0) - { - P_DoQuote(QUOTE_SAVE_DEAD, &myplayer); - return false; - } -#endif - return true; + return (gGameStarted && gPlayer[myconnectindex].pXSprite->health != 0); } void GameInterface::StartGame(FGameStartup& gs) { -#if 0 - int32_t skillsound = PISTOL_BODYHIT; - - switch (gs.Skill) - { - case 0: - skillsound = 427; - break; - case 1: - skillsound = 428; - break; - case 2: - skillsound = 196; - break; - case 3: - skillsound = 195; - break; - case 4: - skillsound = 197; - break; - } - - ud.m_player_skill = gs.Skill + 1; - if (menu_sounds) g_skillSoundVoice = S_PlaySound(skillsound); - ud.m_respawn_monsters = (gs.Skill == 3); - ud.m_monsters_off = ud.monsters_off = 0; - ud.m_respawn_items = 0; - ud.m_respawn_inventory = 0; - ud.multimode = 1; - ud.m_volume_number = gs.Episode; - ud.m_level_number = gs.Level; - G_NewGame_EnterLevel(); -#endif + gGameOptions.nDifficulty = gs.Skill; + gGameOptions.nEpisode = gs.Episode; + gSkill = gs.Skill; + gGameOptions.nLevel = gs.Level; + if (gDemo.at1) + gDemo.StopPlayback(); + gStartNewGame = true; + gCheatMgr.sub_5BCF4(); } FSavegameInfo GameInterface::GetSaveSig() @@ -385,16 +288,6 @@ void GameInterface::DrawMenuCaption(const DVector2& origin, const char* text) viewDrawText(1, text, 160, 20 - height / 2, -128, 0, 1, false); } -void GameInterface::DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) -{ -#if 0 - Menu_DrawBackground(origin); - G_ScreenText(MF_Bluefont.tilenum, int((origin.X + 160) * 65536), int((origin.Y + position) * 65536), MF_Bluefont.zoom, 0, 0, text, 0, MF_Bluefont.pal, - 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, - MF_Bluefont.textflags | TEXT_XCENTER, 0, 0, xdim - 1, ydim - 1); -#endif -} - END_BLD_NS @@ -406,8 +299,10 @@ END_BLD_NS static TMenuClassDescriptor _lm("Blood.ListMenu"); +static TMenuClassDescriptor _im("Blood.ImageScrollerMenu"); void RegisterBloodMenus() { menuClasses.Push(&_lm); + menuClasses.Push(&_im); } diff --git a/source/blood/src/levels.cpp b/source/blood/src/levels.cpp index 739401d91..ec543659a 100644 --- a/source/blood/src/levels.cpp +++ b/source/blood/src/levels.cpp @@ -221,8 +221,6 @@ void levelLoadMapInfo(IniFile *pIni, LEVELINFO *pLevelInfo, const char *pzSectio } } -extern void MenuSetupEpisodeInfo(void); - void levelLoadDefaults(void) { char buffer[64]; @@ -272,7 +270,6 @@ void levelLoadDefaults(void) pEpisodeInfo->nLevels = j; } gEpisodeCount = i; - MenuSetupEpisodeInfo(); } void levelAddUserMap(const char *pzMap) @@ -302,7 +299,6 @@ void levelAddUserMap(const char *pzMap) gGameOptions.nLevel = nLevel; gGameOptions.uMapCRC = dbReadMapCRC(pLevelInfo->at0); strcpy(gGameOptions.zLevelName, pLevelInfo->at0); - MenuSetupEpisodeInfo(); } void levelGetNextLevels(int nEpisode, int nLevel, int *pnEndingA, int *pnEndingB) diff --git a/source/common/menu/imagescroller.cpp b/source/common/menu/imagescroller.cpp index d0a50895b..b9446463a 100644 --- a/source/common/menu/imagescroller.cpp +++ b/source/common/menu/imagescroller.cpp @@ -69,10 +69,11 @@ void ImageScreen::Drawer() rotatesprite_fs(int(origin.X * 65536) + (160 << 16), int(origin.Y * 65536) + (100 << 16), 65536L, 0, tileindex, 0, 0, 10 + 64); } } - else + else if (mDesc->type > 0) { gi->DrawCenteredTextScreen(origin, mDesc->text, mDesc->type); } + // QAVs are handled in the Blood frontend. Maybe they should be moved out? Stuff for later, but this is a feature where it is feasible. } ImageScreen* DImageScrollerMenu::newImageScreen(FImageScrollerDescriptor::ScrollerItem* desc) diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 3ab844da5..32dbf4d69 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -678,6 +678,7 @@ class DImageScrollerMenu : public DMenu int index = 0; MenuTransition pageTransition = {}; +protected: virtual ImageScreen* newImageScreen(FImageScrollerDescriptor::ScrollerItem* desc); public: diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 05f71287d..65223ff78 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -420,12 +420,12 @@ ImageScroller "HelpMenu" ifgame(blood) { // The duplication here is to integrate the alternating versions of HELP3 - QAVAnimationItem "Help4" - QAVAnimationItem "Help5" - QAVAnimationItem "Help3" - QAVAnimationItem "Help4" - QAVAnimationItem "Help5" - QAVAnimationItem "Help3b" + QAVAnimationItem "Help4.qav" + QAVAnimationItem "Help5.qav" + QAVAnimationItem "Help3.qav" + QAVAnimationItem "Help4.qav" + QAVAnimationItem "Help5.qav" + QAVAnimationItem "Help3b.qav" } ifgame(ShadowWarrior) { @@ -530,7 +530,7 @@ ImageScroller "CreditsMenu" } ifgame(blood) { - QAVAnimationItem "Credits" + QAVAnimationItem "Credits.qav" } ifgame(ShadowWarrior) { From 1cfe5be130341f20461f17093f02a333c4ec8049 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2019 21:43:54 +0100 Subject: [PATCH 076/203] - fixed creation of true color textures. The palette check was not correct so they ended up empty and caused other problems down the line. --- source/build/src/polymost.cpp | 2 +- source/glbackend/gl_texture.cpp | 2 +- wadsrc/static/filter/blood/tiles/2574.png | Bin 43434 -> 26842 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 4374b6644..1a70867e3 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -697,7 +697,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32 skyzbufferhack_pass--; } - if (!tilePtr(globalpicnum)) + if (!success) GLInterface.SetColorMask(true); } diff --git a/source/glbackend/gl_texture.cpp b/source/glbackend/gl_texture.cpp index f6d153bd1..a124002d9 100644 --- a/source/glbackend/gl_texture.cpp +++ b/source/glbackend/gl_texture.cpp @@ -96,7 +96,7 @@ FHardwareTexture* GLInstance::CreateIndexedTexture(FTexture* tex) FHardwareTexture* GLInstance::CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency, bool rgb8bit) { auto palette = palid < 0? nullptr : palmanager.GetPaletteData(palid); - if (palette == nullptr) return nullptr; + if (palid >= 0 && palette == nullptr) return nullptr; auto texbuffer = tex->CreateTexBuffer(palette, CTF_ProcessData); // Check if the texture is fully transparent. When creating a brightmap such textures can be discarded. if (checkfulltransparency) diff --git a/wadsrc/static/filter/blood/tiles/2574.png b/wadsrc/static/filter/blood/tiles/2574.png index a3a76ec3ba647f5d854f5c7150bf55fb2ffff87a..cb5d3aa415bc85c8e02b78864075ab06694599f5 100644 GIT binary patch literal 26842 zcmeEt^;a8h)GZPqcyNjaclRP8Sa5f@7Fw*hTL=(5K#LcrXmLtg+-Y&A#ihkcp}2E- z@BJh058pQ{$t1I~W}fxTbN1P1pFMH9+Au;q8ay;KG(t61C4DqBOz_k9VIbzyCx@Od z=hF_|TOX!?Ry$6&_w)nc1l59~p*5u7-`Qb3{ToeJ(@^>8I6gi;F)bApK0X;487(a> z6)g`fqX-!bBdq`j2QeB8F|hy@l?WP|2pO6P6}~hTu{13Xgce_fib|T17Q#r&!otGC z!^6TNEg~W!Apwz=mgeA4hz)p% zO?Vh>B&aMPWEvbS76KeL0vskHJPv4R;b>?MEW{ohI366tE)d3G4q^w0fQy8Hi!_fD zjMiUKz+Z#ITT#MWLn2%Q;%&eZY{3(5BCV*XsG*@@U|?WjVd3E5;Ns%q?d=^L9Gt?) zn2ClK%R`(gz!R$@5@jNiVj&&tB$46(N%w%n8fc{37^FBU=03eVbP7B)a$Rh4{WS`L zHA=j7%EK+HgAK~PU8-Ys%402>5^P%24eFx&+ftmmGF|!#yhqA|qoSe`5)#tW({pok zOG-+rtE-!un!38WMygZRsta~TN>2OQPG?$&hK434CT13978VxP*4B1*cAjSbf4Bed zGeGDq&G!^1Xg>Pd29N)yE1n~Y&5rm7AA%l0?>||x#Q_shF!r- zKX7Kedq%buk_F1)5RyhVe=;a%*DlD<>JFF5%kMUJtlM(pn^bkh;bJ#v%oy`W){(j- z$bNJh$}_GeW%uh?yv5coU?|9W-SVN_;`H=%=Hs3*?ZmdogN?a)&cmN3KO9##SGO!$ zo3wxsg--M?{D*6shhGJtb_0)=8Q@$3Z2nh_gX(QHSF3qF`!_czgeFv zWZqLI-4-R4OU@&8Bl6y=!}-P0h_E+fnE9^MknTx$ZK;WsLrY5T6p);vn6&rmu9fjr zW268|eEh?yz)e0SQCE@kL_;?0vMv1n=<(hLu~UXrmkm65F@UPJysirm{riWt*emg| zUh0lVDk+dLg)x4=OkYHkYgpZAB=oZvQhk{0FMT~-2vQ%5-^q{>m*29dg_1KbX(4Je z;8Z8I&gcx77KLHnj>DfLEK5J&z@4jlK$1UY(EW`05G;KIxVDL9@^9xPjAX<|gF6>&z>J7K z|0B654oQKjyN0gMGR3{1d9AGEu2!l-5Q%IdCY1uUkp(9Rjuu}ZJU zLTTaSloVz+uCKC#c=bS6dKdLdb&P4uRIFSIilxJA@7#vxjjkK&-?+m+#;zsW_o+SC zUOXFCC%^r5y>TpT?#o#GLB^mL?M-uNfFV3niLaEOlGF9rTc&96%(C#8(r1#&98D#C za;;Me=vBb}7IQmJ53^E&SZd=nXhzC9uHgII=iiyFtM&dhH~#_8_yNX%U(K8qGAe;t z?*7XW2xgMaGZx=^g(%%ko5#bo2kE#ky&xp3qP-m+DQ0SPv>6R4pQ@{?tLbxjm>c&E z$${M2u;Ds%Fx9U<6#3RJR~b_;{zAt9OVcaKh`eXRZdZ~+vCOF71-nYDLzJDwU7tmg z5PAh*Cc-K9EfaI;VP|e5%9wtR{C!^YgS33>#{nsCe!RUxQ1jJ9Od&-oyIV3OL(at^ zkzYg;5zxdaxV82Gqqc`Ji-G@p{Ud#1^f`fT)H{~E9(BVnk+v;J?ci?|g%4urM3r!K3ajX|*~%=?Za zu}^n%yCJSAfB20pm$8(3D>#r5f5HfwXdQqoA+5J18Q1Ms(y!qr!QU1wC*?zH7Vgdd z$2E!FScEAhniNitr(lvH$1}(%29?B6BUC-Xe0>*8&8#e}xcsdVyz~uqeSLjO&N@)5 zNCQ1YT#~ZV^G*B;D6@TIP`umQ7h8oqUr+wcG?9b#U86#rv_@L?#b?X)X71+^dOPL` z+{rHdSZ0=arg>Rcta#_e0}(dA-ssLJ%*Rm#8g;mg3ezH&oBw|MAz9wGXxycKh)oNU z{RiO+GHs{RKd>{pFQj_h3V)ag$1yIoM*_a(fVkmyH?Dc?6@p?|itK|!962dNwq64E z5JIwIDNjCDODUsGaCpT>)z|X%{y!Zyo=-lA)FsAZ%o69~Xs$D|Pm`Kw$Gw%WR?^Jp z>wV|)+vSvaX4qk~|7378X&_GLj9E`m?-K^%dYQj-lF8YsTf;a`Oi)^u^34V6yn6Wh z^ojADHpw`M2~aEt^&7$-cVXjWxda}&4b{%XP<6<|{o11w@V~kHuAOmL54LEhZj^k* zgJ(-%E-usjp~~ZhRLe!A@1|Pu^L-}aVnkIp-E>xn&v(5`COfE4g+oe{`joZAW-%_I zv<&?Le%{-nbG(`|5G$dAc8j|!@7iaff1Y|XAq|{s_^0aa^5HZKThaK*jy8g@5u^mx<&qI=VHA5|mi}Il(^(1o zYW?+jZ(j4(F=lci?a^U-+>TIlvT{X~vN-2=lAwVq4yTuir-+2hP{srmy#D8}ohkau z)O>5HwwrL>l3G82qTQ;d1|4MjQi;q{K0W+g(O&RE#e;2j2#34wmlz+fh9LI>C*`_I zF@holm5B<%P|EQl+(301PK>#z3&ytn_a-qK-BB^<0UNkZja7OtK}WAKe$ik-FGI57tnoizeldM~ zcGbXL6;q#AF3&q7|0u2|aG*a>CF9h{s)f-G>r43*v*-BA^VPG*!Z_bT4x<|&{KMug z5^9$1-!#TpuRY;isece32O?~FvVtEfM_41%RpY-NZ z)%=X&VTm;&H!?boOjcyp_U&(JT6BuRkA9>6?j>~ihkkm~^?lg5_I@QkYTUko=2;Wp zo!caeaEM`~@}NwLf;^g0ob{b^MDLf@Bd;LRM^c7(@M}eE7{61h8v$ms8n$8#U+!*L3ir zvtS&0A=&Od7}vMX#;x?8mhOnSzMxE=kKT^+nCXLe`$z>YmVu!<#L6Zg_5B_Cl_VEzZWIdS--Vw9OHH1gK@4KCPgw&zZr8 z#NP8$h(|L`1479sCERsWUqV;Uni(VDtctsnkGDE&XL!ZZjlX9&t#o#swB8TSoPBwP zS4@8#`J8;tINY-88;j1o-mf@f1C*ocU!a|^Uo3Gxdtep?m_9}+5|E}x9({UJD_lhN zLcBPcX-tk1E4v$|H1#Y&$u=XefvG!t~-aRd>k_l4F5d@K_7IjD>8E;cx*W>3A=e*22!`OnjjMZJT#8I81V_BNv$I z&Ke&kTFjY%pQO$IDaM7eHM9*yEW`qP!eJ}1QJ7zcP^x^5Ng}zP*$4w~O9xgmCG}=! zRhLgMpjGi8jy@1KsiYg)KpM$@zYD#pIrpS~gKab8_8spM$+Zxn?B+DiQu0@Z$^?qA zQp!@V?Bnw#kF|Sr_$=qo6xLx68o-8F)@Q@v3q?1i1*spJP|x9S26EGA_N=iL&596~ zQR!w7*GMF>DhTEod0EJ+f1b55ivHQQw=z!B{K}gscGnPNXc|3ae~Ub~@}<=nD}ZTo zi{N{|S;KyGKS2jM)l5{nYE2-B`}YfZ-u?=24xR{xCK(rULRdu6*D=8p7S2KN7jWHL z=l#Vk6X1Hxqw}V%s~WfW0O6`2`nQ`=<=3vIGQRMD-1=vKwxQ=|pf9x%N~|wkh8L@YbCg8g`r8)dZGda)&Msz`?s3U!t(2XCrJA ziE`&6kc)O?{JOY1*y@KL$;(6?9sAQbH{$U4$v6dJF+hEi+)SLBbO_BY=c>G+O0eOV zbsS65FXcY@2}W7NSpHt&4giLyCpPIO{M* zBUjb?$7w`S=2RM3Ce@H;+Paj@OvGLcPM?+pweAeNzghC9gA>fam8cFH-2Y5}Y`>YD zz3Y|v6wQZZSd6jFOOA7fR`v7GdA^LB!CI4ObjqwS*siZY{@`YrkKt^bv*cv$NTpz2 zb}0?j(4Z|PKlFZ{8a>R#Fx239?t@Kf+j2qbqWFSY{>(QcS=9ZSDwQx~j8sRjtbyv{& z1wCK`+!23A4Mtk~yvjd>iGois4eanNNI!9|av1w1lLqe=C^p*)+)vZ?*!jCAqb0w- z_Z;CqjO8vqa=Lj&c~u^*o@Zu#s!^(e7-wYEp)ympH0823nlQB(Wq$sJHRu%YRugrM z88az0x|8xuRnT0BBX34G0BqTuX_|Oq06d zArx@B_Mr293sLZE1zr_q4|!H#U1?_2+2_MRj3{i~ zU`8VCvd}U0QJM}%Lyq}x z97+rieT3LK@oxxIOxQ)w+=wpJ?}NaG#sf zM0Lk2cNR4HW6AzRIjDVv9V!&HnMyn3aSr!IMVWYX4N!MLQTf=VegYXWU?FvzoO1BT zAA7Id4cf${q(;K|4EH1O_w>wEZg=+>@nP!~zK#0GghizyZci(*h~C;>YcVf6E#H%x zO=F1?lZ!zx_#cGKvG~e7y%Yx!$@Kjo1IS5bxtR9Wd z%+lP{()N@j4Cq{h!UiE20aHNwaAL;xkkbpo!QGC~8VF?=0i}}3G}VVG)Bd55P!39t z51hjhik3!z?F}Iryc)dmT}(VlaTt7Y8^eRu?(Xx4oYZHER@VA-6p{_pWrYc1b1Z4C zY_;U#xSJ2}=(430(}O&J`uu9=zLhFmn%a4{`KP+L`D2Q(^2oA0z@bcRie7 z2M$wz{}LU2*!Q}tujZnhU;fLV`6Vv1ko{Q6il>KI&9jAF?loaw> z5+Wza%R=*PNk};>KMsxhIDfXOU4B&LCwc+N?Pwu}8e(O|X(Inn`0yF2(EETJpIG>@ zFVMKQ=WH;hmV~`|pFWwbGw^tSZX~mgSJi#E;Nc3kOA_{$P_+cyp6y?mMCn-7GWlA| z;WdpSDRnO;AS$(wNQhf-UmD3NwVaB_`S%xI-b}(NeLhQsL`C6YX^<6Q4sL*-eJdPB4+3e349|D zwaS&(R{?O^O@PvWZ7Z^z~a)w;BYAO9!Co4VN@7W3i0@-{=NSb$u^l zV*WT#F+-l3!rto^*TY&YM>;EyHWv6CW_HQ7 z&Kk^97e!S~%3f79vnG$-Ce4V@liwzV0mgBXhf^_gf4lv9#k-Jfw*%DF&Mzoq9V%99 z$9^4Vd3m|N2=s`>ilq4hP6|VnB6HJBH!6S_ieIV2c=>q+b`PG_(=!1H<1)JeFtF)$ zUu+6PcS_V#p3(NSo*#?3{+BZdHxMf zGlDF*)srj};CXQarog3haPSw#=Sf&H7S#6j`l}pQkMCv3w*&n#@8AC_OJYO3DT1}6 zuqpn9gj}toV?{Fd$F$!Pg*?U{bv7}4VI+5KB?k}=eJ8zJH>oo0YO-sb8w@5KWNtU| zY=7VfZc=A*7z_?Bj`x#Pq4pOil0G}f8RV@1l5debY5pzynbW5^O^j^X5So9<6m!PU z({MK_m9$i=eeuE;WAsxZxRfD0-83+D)L#|<%C=@Qs3i)2y2E>CyyKSm?^<|-%J#1V z2@fBdgn*id`^zKN|H7pL{rb6!{Omi-GY7v$paG4Ln3OCeWt?&;ogEs27D0we>q?-H zaba-QewFmukfp=}h#X5K^b;#?QEu6Q?2FZzUT|(h|o2k-y75;LU#>x0gpfBsc$V=BiEFbE$%c$%Ef z=t-e%(7)}$cDz_N?XQXeZy8(}JigAOnhvEVsOpqtHN!i`i(xXlm&b0EiI<0M?QZBO zl>G&>H%~3{7*QZYMYZu=ReLMhxmU#)CBJQJsVak3XIY`s<=D5vC2nGpMCpS4(4aJ# za3V#{zQOUqPmdTxLE_@>21JeFmkej0QyAu}7wW8w)6cO(Yb5G?J1XQ( zwiIJp^FGE^S>6r}Ev{5?Ui3){Nt22R1;tVQVL@6sM-(X6F$|=VY+s95i!ez`FD+el zb@Zi>M2*kyyq4*H-*F!-2ndsT%E=K?XA*y2bcFbHpLQIrcHU%$^I_r2_7We@nbU-Eg^FUzJYGJ>S~dHo>ri(Ep`AB$Qq7)P0b8_j z_j5?*67Jz5Yx4dCil{RMly~e?ynSXf#cajaVVNE%220C8W8^4T7CRffF%O3cxf^*Q zvjabuy4vcnx7UC5l)zG~ixbYD02tPFU!Ezj@x6NOz82K)$NE&6e%q?+Jn?Tk0C-p` z!6Zfs5{ntHawmy1G?N@GBWG10K7cu|S>#q;54RkpBkr0vPa_yWhhl;4qUlTUkgR;P zS80p^_2MNAGedr&Tb%hD)G!_>_aoXJIUpv7jSXONjegz-FCV=wvx^OK?Os4UAxGw8r zGDBv2;Pf&h3F6!9>phT=`)##Xsz#`_hl|#=kkgcttq~Q-BK#PG>Btv$u62UVyV}6% z@}}O0HHh$)GX(oq4@&VEW=KoY1(oK8;ksqEra9*uzRa;h=L57yd@vgEG?vKP?@$w3 zy(m)U#efQGKq)t30nh%#K8d-Y+C=|!NmU(E;EAOJ%I(gCF(F)CSlIqX&(doTDK z@nTQ9sn0ga8Tc+^^$IU`l=vq)WDzk*e72wtS?uZM>}Z;N>CGf7$iMSK!Agr5stb`L z$MvrhhLC?6^Eg)A6rORZ&0v9B;jW+2d zTA+N|Zke$*qIy(^BOt4zb42e^e%$weX_eDfnvajw8sz}JY#U36;+V{UE1&pD=R zy8x{u!G!@*mRGSuWZ#I~{3FRy3RMMu;dv4a9s_dK4I2^>wIBr-Dn-H(sS}plF0-Z>NfFFX>peW}nZka^ zeTt6Y-IW)|WmI{+e7U!8WKcgR!b?*}N4vP>iFk_rn2kX4&iR@SFdawz+m9ftQYG4` zr=zdeT2(!gw@$6u-)|M~w?3Pe(9tOKJ-Ej^m<^VLOyLx2kZZ!5g`vC(Hu_}t0ZnaD zXRK zk|O#wR){x_CQ#d(n&DRmM0rV(xf0hg2rJ}Ww+l`>zdjx_gq=Nxq|{mAb2k!rvZ*}P zH@&X-o;L~V=QlMF6td%YRaA{=f7{vBb;$<6Ra93FJI#F@F^D`XWPEX(dbVqAW$t{i zwd=V-cL*%FLOy0Wpvol~&!!~ieu3MQS&9XLdHRu+<9?3G7(W?2m@byZ`dhE2iQ2oQ zh4Q_q&ujLZS&d7K(oV?VjB4A_kMKwtC8A z;rBlACi=%vo4JU}23*bJ7@xerQrXl=J)xR!8~^ZPpitcbsnS1oNonApd5b>orPatn zn=-pRIKK-tXd{q2v-i=mSUqaoyDQ+4dvNb*xsv~5--eH_nl78>H(}q$)%m5gM39hf ze>tB#j(U`Pyb~W}Oz}Tj4m{Z&-*JZekZOckKAemUr5u%}tmCPpL$9`{t|83tf|e)I zl)AFL#cB)ue+$VKz#j30s)Os619pWs7GI5v_j`M&H}@YUndlEO%_9>)<%!AQWlE0@ zaY1G?&T$fVydBABi#U|K1KC=i5pnUqE^p6(jh+sHTZ6@7)DbtP1Fy@MSiC6@uK9Kw z%9`3;739`By`7w%Kw?)1Je*k&KK`UO%BSCtNc@!vJIS)*MSo_m0PhE}lKPxuCZ)ES zm~367*-lgD$qm$b$37!-aM}t!FNunlYfkniq@*Sl7f=?EB61QcYo@D{>v4AJ{n5|G z;s6vMUs_;6Uams@4WT)mT>S&Nl*pgFfGM?_fw;INLZFue(P5u07)Y>T{<$%g1fVrM zPFV-9C($E55C@>Ako@uQ4D@nxDA@A3J3O-L^tAAQseHt}Rb5x5W~01S^!MldcRUsP z49sI!{%X>~6-j&v{mJB^%dak|N|qI5{0Aq4mLXU@gx`d1p20MNZU@Mbgaj{wJTm`T z!)v%_;|+r~D9AU(LcFSet394nskmt}4fA4cz&L)-M$`1SxP+(2?3ph3I5`bHkqdbg z6{Vv~FiuQ_belgI7c21OSGq@M`~CF;L(K2sOaYI{6ls6=8Jyym%!mpg>FYm>#JHsH z$EWc#GfguF(WF7GDaZ31_zuW%fU!6FDbHbidG@LzUAN+!A8=Ef_s0>EOh{J52gNhT zo~GWif0-#qtWT_qRv&m`#01<}q$57YRP?!O=w|}9nH0)$$rg*e5EPS3j#LX_tK-fp zCw1YJeWSiEy46q6na5IuoB2EqtVX=fDJ$hAn|N7+BVGKH^8j&(^XBuyx)v*&_8;iW ztVISqVUh)0MN|@~w2Nui?bp72tR6@qDmHi5FVj%hRsyz96ZOX3szJH^X8Aa?+wci++yEh=QAv{^eOT&+)j9bz>TwU0nR(je+A%)+01i332of|x*Z`D77l;Q;iaz6ZG3x(bDcD2d+Ak)8|A)-jDNM&oP z81ObC1qJU)xpdyP7huE|>e9twvyuTKzkT$Yo13bvvdno-;IJ7W(0~^jM;Z-YPF4Vg zm7<=!a-Jd?Y-l+jH}bMYoPN(!ixW+!BOFjWlbD#%)KSN6VV!pnUw10PVYg6WR)Q}L z8$?FMSv5drS(zJKhWw07s^8^Hhu3>-t1-$?9b5A^7@v-<{YSUd`g|FANwDeS`$|?N zC8tEo2px6zNa!O4g(F>vXC37WiCB;g^a>0F5nG9lKyDmbJ7_@K!UBG1tG%SWeP@g? z=kW5+ioDp5F4WH#)nEZhfxfHtuZxk}5DQlUL;&@H&D;Al)I@lyC#N~R1P{M!X%Tx`I|@)q z)g$)?^qw_BGq2l!Pg0E#QO_=27u0E&#UlcfOfyu4n_f*w8?-hgjdJpw0aKse5mg8iItQdu^mt0n8;P5Z+sdLTf|Qz^2}?fN0y9pTUT zM>Tl`Na<;4CF(|8?i9#|XgyOX#D?Bb3kSiM_x&X1kh&x?hprwWVY!S6z0{7^r<-k* z=yg}BczrK1gqL^yK8a5gA61}llmwY3=sK9$%+}X1hFf=cCvB00jvI$LgL^$yH)2bg zkQ3-|5S1K_^(RDJOD5I$cq#+S){s0D`#@h%$W#2j*e%>uCAwHjEsR_X$RP%pid+3L zz{B;R@m4?T8z~?xF%hi82V55sYarjXa2qm&+hkFAp=nm{eI{A^lMqH>k(@-U8^s4a z&B!Rj&H>%@q~4r~E+wN7@k+!REIxxTDGT&w6xUCDv41_UlaKpT?+{&6pERYfbovOx6f%V;v#A4hQ4@D0OJx%olN~uWS#xo`LTj&e zHsU_2CKM=K;_^mr{o*RD`a598EgZpVS)yaiDzQl_m8d?n8^`Z3}sooQdzIK;|_BuSrP+Pk6{4>Jsj4v<120vQ|nk zkpe32b)y=3Zq@%N+q>*FP1wd@ndx7?Hhz-s)7V7m&sgMfGzyxO!TV@CyTh03qfGx4 zVnsrxkQz99xLX05EyC@T&xj5giD17Qpjq*^D@;HEL^Bu&5%#=3Df0`KBUIgYgxA<~ zg{}ODEhwr9_m$<*B@kY(yYUpkbNUA>a*-K!_ux@uPMOT6JidV1bJjs^)N9KbPAgmuQLE|bps()7%hTX zjw`CDD{Ee#TEV#-=OQewFFuvB9$cf#%gcA0_T^12jgrAcaLX<^ZU+=qSNOx-@0Y^; z-6UacxU?icbc@@F9J~Ub5vhWLNWX?q4ih}t#i)w}_IN1^!A&3czJ2;hNI2$zsCB>( zsmP_!im)P zxVU(5sZ|xU*3xWq0;Pcx@jf_qKmfidLqD}jl=!!h>nvGa)LkVor4{1uXL0ElUCUD)1l^Q2>0De^mR^ri81*c2V1skTi+^mrNyUZ0-FQw!c$eCv18m?$9bp zHfmY6^#;DW{zVe@#;{w0cefG_D{h6vdg`vX$eWlmDc<7tGEh!9Kv6kNnRv3lcj{1V z51Nnj^P4hQ&&r@TM+Fe8AFL~fTFKC_8m>~M$Qx7IyXYxYu?led9oUB@5BazkSAbo_ zK<%Sh>@h&QX#VlyN)iH|6HyX~Q>^tC&Uxdd@Cr+tT>Iu95UNs{@(xhRIgQ5Cgue6g zv-fW)(jZ-Qv-MXcQoYY`i#^1q)ObZ1WTx5{VW80YW+*E4dBXYaPHVueEFlS9WdGx2 zp;_{tHjWkV!@)G+mu?#~p0GGwt^(!D*OW25nmQ*O&xbxt#?&7o6QT@D)j;n@r|n3` z4x{^u*EuFj$Q^xD_M*XhJbDf?!K)=|jz*rw^iLhlZxj1?W$X|cZ}ZEXD-GIXcjTw2 zFkUZ|yND*c>JX&103v^npa9C zN2JlUKx@Wqa`L)N!a;A`>3_X*g9(6?mNp7-BEetvk@?2y;0+i%@MswysXeyvibZ&<`%&_EAVofGDPe2cGe|#Vo3WK` zwch8OpsrDGswej}3)228F~2aX*x&N)aK$rEL!vs$xt%POx zWA2@@kc*)vD5rCIT_mjo;9~j}=rySRE?(Fzn;aNmpYZ^E&HUV>uJ+{SGxy zh#|W2-0&ssvLq_$wRPOC#1Oz~7ZxUsnKW3}QlF(sTig&eiCC#g>3|xObsJ6bXd1Bn z1l2$ba5g}!{ADJ9F92f`2qAu-#LYptkEJ6!F3a%H` zXrD2OV+Xhaj+Twzrm0fPfn=Yfv?C=0Yg3MV$JDe_bK8UtEEVW`By7{ z$AdRG*w>$Q`5ScTA6Pp0;DE)e=y>3C4YFpgpc{*aK}$oXZAZm33a;<>1LK>^C+^CU zjFQ7g6_Z{J_W<%oPN+~PovVRoEobyZ&-K^OB=dci5y=kci|owR>RmoXWdt_y8z_w8 z*vNalI!7O@N}r~x?c7yKRrK9|#Z(_?b{&+;0>rZ?_rK7Svp(_mvNv!ClsdlG7iLu& z_*;15=&MyKXJ|%-@lOp`?pafE>wuV)_iSq~)3P#{ifNYyh4xoAZ zMM;H|c6AK?+ZB0(Pcz(-)e&|2omS$-e0xy~`k|Gn)Cls9noc+}h%GQ&-r;k?+rRL^ zxQGL;@(6JSDuoaUfuAJi3eXd~n_uRb`aofkz6p(_@s)Oge25XF3sw>^*fbC`4XG5A z$|Sq!sGGd2`7cr{R@JXUExW);Ao-(ea6U({MS6$Hq*b3$o=KUM;;*E1?tV|+SMI8L zKN1$0@3{Z#c$lUrVxe~^*Nd!HRuqa_$*>wqe$SYzHZq*NNiE8ykODxZd)Xa5x?T>) zG6P|IhwmuvOeCrq3E_s_$!V~|b%8=}Uk1^Q$nx;8!t>)=uUk#>wEemhxBN8IN zYpRhy83iXB9*Y93x&;*IN;wkloykkB>v+rI{LAIy)vxq?s6QL?Z{$*BhH`a?A;3H= z3j;y_FruEazK53gTOu_e4tY+60e3II>Asy&kXb1;s?dT9Qd|7Xw5O{KYvltqofYxc zbg!ocpf+K9_A5~zu|)3i2(T_(6o3mMzor2F3bOxv;0bOC8K?iMseRTc_pseNfOC14 zaI?AEaqE8x1*SdI$7`IlHn+C3g`z0(fB#x(XYr=rzCN{(20Hj4CK0+x#yp4$ly9Tp z4T?p#i0(b+#5A=S(}y{8(@o``JuV-0HW#`N@BM6C4~tWr)roV|FD_ zxX(HkumO4xcV&mp&#S1T%4K?J6{9cG{_H+OpsDu29x}m1j{z8IXib{g1p*cs^J%kF zPVyfFmu9{wlri|NTQ-6U{m&u*JK5|Od43hJi0VH*7U=C(f6k>yGPf_6rSZ!>_!C&Bf z`@<>Qdmq;3kCCmaPiM1s*K#HQG?{D8agsv6kP3tnEyCOTPfKEn8Ff+9sAC5YH0}3LE7Z#J*M#ZqDvrN{g)b$$FSYki{(Z;CN6RQ(mtB z32U#DujPb78RXRAh4;=NL`wA+@Q4vqQk^l5pK>YXiG$WQ7oSHkYP==@J!oN)Sh2xy z@Pj`0p!t9wm>0td00LY$ zI}~&k(FM-GZ0I*n0Z$G5YzCKjHZk9IgSJ1o+OFYEk^wfA};1QMf-SYm2l~?D@EdNl zr6&P(*z<^IKS++5q{8gaMO&Va4YzBC_yf*7*xcz_m|ksP}1tz!Shc39Aohlo0xS5^l8q zj&fn@(|rU5UVspsLI@hS^_{f>3s3mlmLVOt%utbts{S#y;?JqYnyi5A$g8qQG8zn~%R%c?O0O=pv=Ry}B;e)E~wP5zuZ8(hf+ zeL>XNOJoOQ#cQV!G~}E3u0axLGz5}@0LPz_AFTd*`Tggm7i1X~)5-+&dNkr1?&-UI zL8i|+ZFa~pe6qj)^PKPMNl9`hXk7Z(0;Z_Ye!)vhs3gyl#%exvCHj*vut#C>-t4SL z5O1U9bQ2g&R;AfjvUAM9!1ryZ(+$fccWax4qzFKlLsX@{sgrEevHk{XxOIJN@MZYl ze|Yd0idvxlK+J^vD>7wf{gjt8j7>I%kicT>QazMR8FhTcc{ikmWTDn-8H=tm;?stnAH?9IJCG zmfJ&c99;NvsPC~c{8(l_$`a)W#G2}0fAYtcczBG})w+i@v^3rR$^L&+JULKBgWj7x zd&&(vnCepa+j0;d>}E8g1vAr}A`xfEdWl~gtPaMR*@!);XB4&-$IN+D-xl&hn}{wLn3lOiaM%rqa?S({P#K3q!b} zohq!DKCb+N+^~pY>*L&`pPMiHLcDeT(%kQ7ynk0q1`B5a_7;*;_H zC&)3I@qG2?*DoC>Tox!NLC62P1{LUmU!x?h>Bf~UheEnFSnkRT$mk04qZrfEn9Y+Z zyW%39LN(5+cfX#0p9`d}aohZXFmQoWvt>w%ZOmRO^^}8LdzpfIoek7wMJH`5f>)K? z&?XjapNpJ7s=lMdiB6GI*tfUprA9=dqF@3x3Mk2hcZ3S-I8UY)$4Ej|&m8~Y1i0ne zO6VtP<}NRMXguNh9}EqFw6W*4#1ODW&M&aCY?YDuv^;{ zm=VtOH%-#<{A?%r?QzTCZqzn!i9W55i0ITi&r;bVikG%&D8kjbn<=Q#S);v3er{S< zN}V~suE_ECYdf|M;;B4&R08F;5s=jCDV*=)!S3>sDr-Ni%_6{$haO$>w8G3$XHKG} z^${frnnVWM$JtJ$pbORCE3vLD&i&+F-(h^XUu{z(8H^tlr-2C^d4>algK-dHtqxw; zj#|`V_b1!n_DaM#=^U9}of4|dNIrhmAdff?JxGHX6D#m~|Gbra``1V&F`KHL>MFcG zGZnwFsiQ*}(iG(Wx9k3J79v4(1Qv6`xu;n zS?Ut(JEp)D1|Dg0eA&cH&Bs{)u1qzV2l_(9lUzHmcOC z>#rPivBi};qkKw*tEMOu9A|k>AR#XFDwZ9=2NZy-g07&@uQ$KF&a=ye~`QH6?}0cCw5q-cw87#AnKV)@4bhI%_D-*}szUY?s1htt9ne ze7jgvKSCNQA zdh+?M=VlciAn+;!K8cFLaaZ8x8@7cSe+4-r%%ASo4L%0Wrp-l|P}BEi%CZEHy89G?F^eGNizr2LmQ zTQT827MK>OS?z#F9XslQ86PM6S{=UkoN_lwpNDM?bq7T9V1hfxGJ*D6h*oznf6klz z)XEqoETGrXlF3?VwcLCOj_8w5Kkbk2PbO7gg2ooFckpgvQE-VDJ>U=TIa#SQM3<@} zsUlrO)bY0_aJn@|JMCm~$PicG&|Z++Obj71o(PNG`9`+H(flHIy%w@FslF1S0@Bsr<74o0%l^G`c^ql*1_$1MB^U~$Ak?-9GjTENxxG73idd!1ITj}{Q zd-!voN#9+OJPDZ%*hCO1%Qj3LJ5T_+I)w5W9BHE1^s~n8#b>$;8~6$qEUg0Y! zNspHQTl#ka7k^&Xft8nf!rzI|qWL)z0*|TKow@ZB@m`3sGelkn_enG3(ZuRN=-!t^ zv?BX2i2K>_-+strnZA@%K#h3VbOjIHQrzM;X5u#v3)KGg5trCfC<37WcXDw=pO1?k z)Lltw;eeSN7RaOofu3N!$H)`RQEHY9$$4X$3=EYMo1>!AsxR{y_e6*CcZA;a={R)A zslvNcu%TC&!xT_sx%XynYavw?KB#=wMLfTY{FVJh+)d+>JCpFbH*ayyit;H3nE487 zx7yzxWN$Gghl%|2dZtZWPrk)I>2Khz&?6b|EE4%?u}u(2!N1Y&os79Ui4W!P3_Lyb z_pt5?OvksEmfyFZO0h)cTJU&RSG(luh>7|=U9G(^g=x6S!fM3sdqZq@vbQaRkv#Lq z=WK>DBh@hsx?xyOvkPY>By}{iJEYN!-JVYux~1Dtgngm>?s+3r*tU`m_UH;ukjv=Y z>QF;vi->IC5Hx`4@fx4Ee*MItg?vi%8#o5w;hA!J>C~UZkW+Q=Q=MFMGU`677|uMY zU+P(vrdwolQ{TR}88Y|q83bMC453S40g7u`sJ2fjZYbmBg@nkX@Sj|usD(OCWNnlo z;K$LZE{GNb>ZnQuucjyM;o(3#ndh1WYYP=_x{Lt=i^?Kvd#%h*C${ zE@DePAtq5AncR)UqGRTy&#GVuxdzeDloClT;klm!u>*(HGcMonFGi0)PN1G>G3j;^ zR%OamAP40wD1mMR?;8$<%?9|6}hMHd@?LOMJ$k$!Q=c&e|aX}$A z?H};&r{gFw=CnqHHDAvl8yyY z&Xv@$YwTcDNaAzmBlng7LK<{12sm6=ualg!x0J$&t5P;0gJU@r>TkWG((*N<^BXs0ygC+wer z5SPcq$yE-04IUxG!EeMp)rlLNF~^T$OUCsidjk|Tpvkd}K3Pn|J#7-Q@NKPO3ZQ-> zly&$!9`@eC!VY+N`TSg967iomZMf&uRQmq}b0v)0-FhIgg33DLmGkh!SI>V`9P%a6 zSR7&qacW<@bE01eINXRsaMaPZ9;u_m;yp$c_2TCr00epT-J9><@hoq13$oX~a$bV8 zeWj3>(l;f@ISI0TYeddsiLJI;5LS}nrshX7g!h*?;aKqzag;ZZO6j>q?S~A6vl@t( z5>Clb%qZL_$A{uaYD8imhM~E5p++ytaj{{5AP>KXAa9c(FeC}0$GyGFZ40tg3KA`d z1i8L7GA+o?)7|Zrh#c=8rYm+38bUvg@;-GKd`aQ3J`69`h>IjN@2o0*$!0$SMw~HsP{|0zn=~kk|Zusfr+a+~bvW3c}yFP4}8mkj?AsGw05p zA0XK=>F%pD*)jNm2Si6i!F(u)_7I?4FsAyE8Wk>BSA|OlPAE`_ z0Y}{k!%ZwU(_1aL7qK%(M|Bc{WGJ-}FV+YIxer0Ud;6-tAXm;s3xYnD1W_MrYkh5I z=Iq@1NVOolPj9tPNfGaL)HI$n=fKhZiK+f|B$WDIsDc&3gJIcXq7Jup;9&|sJb^z> z>6HUz6<}AiL%@MI+ITa)$-;Y*!@b0x_SKU;dtRbyu^7>e`~X4j{egnKv>@deq!i@5 z?!}50ByQ(j*^(f?=I;}3j)ovS%lq`{t*w>maqk<5$}Vf14M$o1>0tP2XyWMLI7R&q z-FjeAO*G?`4Ln>fQp1@6_C)*jVc0<|2v0>f574=X-qUz0afv$hl1+9LCA>^CpIo@G z|A)6tf^@q{koH`BDOPsB`^whlRS5Fw`r7*X%BWl@B-`6tOR1OD0EQp&tPwg-XU!m9 zd0>Wv^{Hro54;M~*Au-)daT3L9-LPoJw6;iK>8t1{?+h4_QR!`aEX4n)L}r7JqYss zw=W;oTaa$of?S%@?e43qOLal6tgT&Nzd2IZK`=}oD2U96CtXtyLzp-OtXPNpd%-?Z zg}#>L6vtB&Im*saoEZn-=)-N*7B?IR?qYAdkrBm2!_p}`mBpXe=8QvuAeX;?`(3Xf zclS5eVF>)_v?a*=>MC21`1u10vamXH^t2NxNzap zci)B})sKVR?XIqNB*+W}fgejT2+0IlyK-fH?bfJ#qELS9ZhOc2AVCBg5cq*Mq!y^D z;?qNk?9T* zH`iCMz>p9G-Swp<{?%HLwXK_@GzQt--SLhM2A;%CS-to57L}hfAw9;?Uf78$5$!#U zkByIevLAlYA4UY1-hhE4?!!Y{&%N<(m89dr$KuFDdO`~m&ku)>f{ug!Vmdo47cN|Q z`>rksh97*~SYPdQ_AY6VPB%gj83I8TAqaX{H%F$6W!km3m40xDPCqC}s`9MDbJE9f zheMT2im3sX_!Zs@M??)r+Xsnv0Swz3xY^9=!WlzT90wnb+A-k=Lf*YA1kn(r+wM@1 zyPYd&Lpql(q6I-Pp?g&kge}P0+BWZY9~D7%_}8BFuJs2RoIaiIS}g8+PqNx$l_~gPTFTeZt5AX7?Y}oH~=*NDy zv%0!|Sm=bs5 zModeBX37Fb7{B{v3}3!^CrVNvI4VjUY#$=tgGB6LP;{&~<+Q+sGn{cuK#)fiQ1~wjJ2IU0lL+$g`?r}OGJ}HP zvC~<@TdV}}r9unR>2@K=+}iq6`7sKD>_`s?;u`FMK^s#J{kUs!X68(!3T2p>sU}7# zzS(t8#HPJ<*19ee>z_ z7tf!+c;O&DNumY8-%|W+n&CcrGEf2^2ya{L7idv77V0VErk}M1v4<)O}FoUm927UE+CHykn?dqH@Z6HC=#ImN+gxxp3j`AVJWCl!AmIF-Tv4 zAlGk7kl+8_L3)x%4h=%)U3I`aSq8L|^jN9ff+8`M)v_^FgBfIOyy^Uw0zGjgN4#2- zzfv#SkQ@YwL+*ov0iNSM3S2iCa%HSi1GT}+aq#hl3;PzN+QY&V{E#3t#2=YT=XtkQ z7UpK=wjc-^kWmpN+K???2+6|7HRzPAKGRH=6s3wOP4rMr))IVUvlj(%6m<;aU=E2_ znBi9fPB8UN0SYX~+lPp@zXF0j+qI8eNkWzCs_1vHelQSZ@4GkOg&@&@#AQMV(xD*h z6l8XFewBjoWG@BTT3MN$o0-_!9wk9^7HbEBaKED77(+$XMMuRmq^VMCMS5u{z$7Yy zvBp&Ci3T6^vWvbCbnah*jkUBpvkU>%8K zg#~({5@^BZ;|PsLj@Q|XUe+%GA~A=N<9Pc}NCOXSdrxc!k>3P!S;wl3^jE^I zf)18@SlTUDPEXrg%*MwGn>lJ_`n61&Z|XN6N-S7M>#N|5gx_KvcOMWTMzb6RVMG%y zV6s|qHGybi_~@)7@(I747lJ&vn*`~0x;O9M?X2-9(s>QsXpKQ!}|2(52RQRA|H=BP;Mf!yWT4_zBm)>)GSuGIOskY zxY^!*0DJt+75&02M*&*UIRuiaSRk0h8^l>RAHq`!m z)93IgxrxEKhmz#@V8$P!rwIuK>_amw;L;`B`2o1pdjmo4y?yoW?IWGTy4i^jOWpJr zHb4;x0zW9o;_52T@~+IEqaaJ0(ZL#(yLr3#Lo?D}ki;4J!B3=PLY=ImGe{>N8c><( zOKqX|!eRFzfsSBq$>DyGBeo(5mwgXDzHs608wheBLGIo~$lS$52(s7dNRaty^{|ka z3F13VMop03E><1-!EbB;ZbFV5AC+Nwzojx9aUUMMQs})WLkQB)jJOhpzzZA+-fQya z<+pDS9)uzL9lWpZgdv?y=dvyovH@9`Z_m%S!ODsRIWxDV4%X=0&D-sEcXzwp7I$la zB;iLP$on=SL*WB62$viZFI3`4`*6u>U{D*P`xAKo4yIMk%K+EJP>!mwb z*VM`CbG`7V!^iG@aFBh_a6eoViu}H<$b@d1=2IH8hbF3tVbSXx1q$-|<=byFLGE_e zudRk5oz4nc5czRseuh^9Bi z3gScdemKH@1`JdrdRH~3n4`j2%Jq?PNX^EJ4aX-JF1~vC23;()A2+23QRrN|cKsTn zhg~e5$&w!yq;)m~K^rnEf?$lk`^DDg=G>>2LwGMu++q@H7zzSIju7ZRD#wG5*n8pV z`Z<8TiTY5?_cS8WyUKwxbcBUt!Kji%q!B07aON;Tke3wXKF?k8T6)lpH&?#B^5atQ zV*zep6f!?O-R>;4&&{mwqV*UdLBJPVTWIsbb1>t{lFI?HuibA*CSPM)1CnV5tk>}rjr2wyNiGm=6Fbts}@MG$9yVGu;fgroP?qxYhPZH?S-RgE%*4Eb6p@9vdBHmBX=*JL( z2pls{i8zYJX&L2}?wBp6I2jX0Sx3Pk_4C6OQmIoo zudlDIp0;K%y)|9zi^V63h#7UFDSVL`)m34$i%%*-b5 z!h#{AaX0Vg=H}M*>(FCu-9b;1A+f7R6QrkIh~rS;)Icd8>k-d9LOw`3T;&nVf}eBE zq@sM_tP&e>Wc`f5PHFG!)onjA^6u}i zGsx6}#Dx%!K_-(RoiCp8+QaT>Tqs;wSwr)|_TzerdO=0p(ds>gMWWQ*mI2Fn99o(FuPCmyM&2^$f?4Bin#h2!8*a-#=Zwpeg1 za=#E{ALDc=g8s@r{&l z3!+U93Pa$B1j!B2Jn&Dm4W{}-kmIe{_PG|p<2atq5@q=y8YPu@WyE3L2NsBO#EA_! zu6|a;o_W`e>(8|dK{O8GXk7`+a>-*ts~sDIAomUqNiqaFCuPTU*!Jen1ekAc}cJy`GaHg&?IOp0yyV{-QBRr0KCK zoqER+IbSe~|Fh?12A*dLCRMFGZ19|;L)2HgTxq}6KFml2to;wMi$~Dg&c%TuWYU?%*^N) zJY~pr2kA+o7KDOa|J(Q&OO4!*1|&!{*gOC+RmBIRoWY~#VnX?olg)zE8`=^#DuenL+a;5!?!Hvjj3u+b((5jZ(T%LWzELBTkmMHiPO>o6IxNAwLy@*M~_~o z79`+ZCTpGjP9cbXA%tJ7s9*Bzu!}W^@i6|6j3C$7uXA(O*XMfm2)HA4oR|rcp@5&9 zoLyX;o&EIJfX&9_c_vlBY?PdwOkHDFaSrP~KYVo@3k}pf;XA5xex40TuOLMG9w>5A zrK)OFIt_^{huIrZ5(F?q#Nu_bGMI}AqI3vy`O(AI2fPt0K5ZNQtM=MjXAg!TuG|~Z zmyhy`O_o>Kg3PT!kubzTdXj8zZlaHcMg;%uLxu35he_u|7fZD*X4xi413WC6CH|of zcsG%2|ue8~hSaV?QDoTxrAl=P4&6{0G z2Mqpxc7Vyrc#dDuL0q$Os0dQ}vB(B=>FQNJE-f_*!eymL4ORDe{#A=U4x+bFaYXdO zHpG)ZV?CM$aorfjuH#x$DaMQEglCJCm`_I_lH##0NF-mlaPh%|R|g@;{@(sw-PGG{ z!;sCrz0`sL2%=%_wdL!}ixvciT;JJoke(#hud@k(9#`hh*$txTAHekFn99t|aPXmE zmLUptMZD#hopqbhzxfccWHS>JQxoIk6Z|V(@d0T<<5NXOJcCRfhtkgz?_&+uOQ7Hd zs6$UN&^4!ubx+yBC67S!}OCk1JOeude)hWG|_KVI}0iKqjZ# z6D&3}lln$zMvA6GPntOb4*x@mmkW|8aYTHK5)mmC97jJ}VlTDpu7nH(He$IF+0Lmt z!qx+mkfR-r2;~IX5{YI(F5J5xf?P(%rMvusljvi0_AYlWB7CTa;>j@h&hRYO%1U=< zG`{xd%9SfH({rpdB5U_v>;cm;14~l^Aj~e*cW7LCnBi;Ey!dv zA&l1&jM5$MCW~rj184LDYZ!)D9~6mOx61<;M=5-$;VAm~!kxsvM->=U2r9*uQ^#dQ zS*k9R?GRN%qUwoPQh+20@{od{0Xa2x`ThaF)`Z_`a{2P*OIH|15pE@jz*DEz;Kvuw z(7_rNL8Qpq`SWMdgv54o+doCx`ohY}%JTB^;^LJnm1aeLjH#?DDt_h@6&rCo7>Brp z2r61siUpj_l2jns;d3cKhej^caRmLW!EWkgoob<^C*E^hCXrnntS*KsK0AJv|LaYN zi#Gs4_Av;75|=o)|L`GC^zO-zi;A5BgcP6R?pQP+Up#+?CS*heks<3GgA{^bgFl^H zTZbQ8U}a?*p?DhqKb9QrPPfyZo)}}{bi;2I*PUvQLuouIq$@bqbIMEXK1W|nfbps7 zZ-0)Bx%G&b0)6E8^UwoePgVT|u9rlEC@we{Y7@n)x786BY2uR$7xwN+kmzB(ejq=f z$K?wVW(kZ%Ac&d|uzvj}dRL>K!&JscU)gZAXg9s2)7Jvf{}o??`w-!rtuwMIgxK5ai;i3l|@J_X<C%nSX+hT4)yb-z##&pKA6wn-%^i%ZE_b{9*{o~>FGxR&Zf z-hcvqQ0)UBq9#SgLXbxg9>tEu4exmqo>G+LY8w_US;u*e z=ukJ|!1=SnyI#jtmE#=c9ZeD+llqV1@eD6=IeFp2#r?Y!WRLeMQVCyA&5ms6Ec7K@_&8#W~Y0X z%?D5PUTQ;;>DKhrsdIDZeDXnouf`%Q(32;Wo{~6~(Ub6g`0yG>#V;6C2r9*uQ_}d> z0$iuZgao-OK`wuS`6LL)1&P8S4Cz{sk?CRuot4eD{YWk0+WLh{?f-iJ-tPZ)aZiIR z336$AdcJ+?4E%5lQW6$4xbS1*Lz{45{6Yz9B`T+&x$Xkz9Rm>L5(Gi)T%sQpL!^jC zAeGzs5IYcLho2@KF+sYW%}x7}44GT|;blQLYpZ?Q-JV1mPg$qLV6yAi`pZ?z}{Idsl4;9Z^3k zozmh&nySH{N+8JRm%@A6qka8?8Xve`{@MrOuX19hixhs*X#zQE%Fh{_E1?I`_Rq~- z_^ZG8i;q5PwObeA2L!oR`-*G~zn&lPDR zy@GSzpE2EQvbX=>?ggiS2(18upcUy6q;o4`I&jzrp6}(S5v1FlKf^r`Y6Is!{>%S> z!29^G{^~zoh9A6;4nCcnkRR9?njj%Gyb_xIF$M7ftl?nzgH73@L&Jcf4HdjAx#MY)`*`!eCxJ0uBo@QRV z-Bos^04?ID3<|&}N)v*}1U`6DbmEbpe2TeF{F5Nu)KU=|^3i|!>%Y7pKQ8co_sOz* z#jP+Kaxm3VvRT!exXYLJF-Mns~$_7m*EVR`lSI$6GyLFtG;S3T7`0zuV5eqmkC|}NAY3wng`b8if(w2)GeCB0dO~r?AHBtUcc(oa27qxyYzk^dIAVIL zeEoLBc|krcu&QZBxo4wQ&;wtog&yJQsZgTb;wO~G$6GBdfkA}^-|gvEi(BiL^H>C} z#jig4_%Ap(Z%s||qf*R^z2W}w#$GJ)zJ?I3NpBIFa;nf#@$nIn9AL(&>`FK&exX1$ zG{l>Wh$^k&ybNcUp5s+V1qvAU0Sy6TnH^Es`9g_xvLgLonrq5oiZhxQY<{I8v3${5 zL1aX+U-8Cv4!Kh23bS4W3l$}sUMHd4!wOVzI!Fhn=`b>fo$X(!a;o_CTcQdCoM?#q zz-6mAuf*wx;-i@3fXQ%%4mO{PWIZHeg{CR3j>{w}sh&wY(zvE5nJpKav!_<4{O|6dsD0D$Xe)C`-%mS`Q(Ld65#O0<1h{Dm&4%@_f0NF3GpLvTkRj`BIRW zjr2o_Z5xOSvTRKDMfqIh7ejhb1y$hjWG4VPrQhLjW(8*@oZ1Xt!O>9gt2kW60gTWRI0rlM(J{vH`wMvm)9_Jm@I#Sn-HDEPf%U9tu7xhI&Yo z64qpa7fMTcu9s4fz~zU+izHGK9?M)#aE=ry0fVa=jQVy?mUD?%0CN$%Mcf=pT5YVs zbJ-e+=a`!EBR%Facs8p7mnqQ?bjuYVh#}zX>eZ@n2ld|%0S>2Q;uorDWRcYr!4WCW z8oG|@M$HcqxmpBoW|}N?I5g1W1-Mi^lJc0Qyd0&8Y?7tw1%-1H3OvB+BC{;0siCR* zfi-wGUk}psN|BXbSTE<4f*wI~Lm2MkXxZ`T%)x{oTvD5HC^%4TMH~^o(2IjzvJf2> zptI{?iqfN89c8Ki)UUaB3F0+r^*EM#CQ9v(i>N3`lPPEL3RH9;F4#mL&$0E2>a=LH z2HwIlM?`KASzJ|*BPFav7UnZ%<10m((PWG=fmW~AZ+`!%pd;yU_=QGPMG*~AwS;z9 z6HbA2~;AdNYz9(RZQ|Z+gi;wQD$PI_Oc+d`Vf293)bVy zd_lffTz`75XO>BUlN$u-ZB}}yeq+0EeG9(?(Q6)pBjFeNQ$~a9mCXm-;5UUE*R{M* z$18{LZGC>y9{3QNc!2_~m82P^0#7KfLRQKV*;L9zIZ}UZ7cf1m=n=$=aW$kY&!pa% z_6kc8vKME1rpR&Ns!qh~1lo>%a3>uEzt9L9Sl_-FRVG-m@S|lQ$XRrU)geywbgcAC zIt}3Pr8h-IbomM~Wtbo$l$@HO%z{{A?7*Sz8y_k5m&}SBX=bVT2y|#FMG49yCgb+O1zvBRy2CQ(O zwfhkqLd>6@);hafoh?!ujX$osNZmc{)DcLo7Zm_D@^% zl#*U>>9wtC2c_2j_VyU$C~>o07&+}7T}`>9s!QJuK??uvZ~MdHlbfvfk+KPRIjV+OAum5@QB~rewduwvo=XrZ2b$kQ{KN%eDf@9@oA`=zVTgw6+X3Ya!-WU4A~aa}i_D_oSe*#Zf*eb%(;+^l2i*n2=pdS5l*T6-TUczDak z^!_nuV*`v(rIv;F+Cp|?dl(Qb9L7UR2iQ#8v4fbwN4&xKe*=i5mXi`#Q24N_&cz7#C4G3DthSK;%+x%8g@Yhm%zuqH+)IjUj<4tL@b&u=N z9~?ps068QJA6uYfNxAXM`-T^@1sZDWOY7*Mv316(Rax}05Un7w1x&=sYfYd19srUq z_W<(3%%b9bZy;$^YWI|qRV1}E)c|ADU{;AeSreCX&)LPTzfTE3YWH1oyNa)eK^a?w z5jN|8?4+E-SwUn67|kOPiQZXlAvlK+9G%c}0HIKl0g+btpa7EFZVi0+d+gX3r^rLi z)|cF}S|G#&NC`rEH8cT;J6EnhGvhi9106vKRotlsWGNmYHx|{#ApbtRS1ZLmA>`iU z%q6gqn}GeOZdeC^9Fhf)t+VZ06`|bACw6*~mt33Hf`~VDGkl-9K(z#lOVh2@Ocs#zgK}^c-S@6L0Y3n4WaX@!uSJ63BvNC`k<0DQ%uoEuiI9c`H;sJ$b(zUF|C^#GFgbB_WfmrP0? z7LY@JXy~}q2l5t*Chct2#8qsuh|uE;hTtoF4JgUpYXU$uMN2T2wLXc068S8Ug^nc% zsR78|isHRx&HIqED9x0&Q8hKN;9xLV7gutxck`B(lJtC+T19f#dTI#PrqID=%F(op z2Bp*WNVai(g&EJ!;`k4Hf}iv+0mz`IYxdh*V*OYOI#1z)f(HeV?(~eIp94mVRU`)? zEv{HzO4+emtRMiOw7bT^C>ZlQl>M|@8%_h)YyHVb0+6LdE;RertbH^jfO#bMtQH8N z-X6JFkRu5FkPi_sxK-Rip?ExSk2~KkDmOkTF5NUZPYqD?MVsc=~T5>A@Y=M*XS<$q+K>?Q{nN%=y zXy_#RK?UHTmJ|O!{q);Y0HMdDAR_H)?9|FJAC~|~8vDVxty({p;G=__zMtH>9E9XR zWDSJWT(N2Z0>eY{fD(jw_;77RLz}kD=3)7bJRN5Ys1K%&zxF7 zN&wiGTV@Kx-2eDFFDde>vmTx-`5?o%FTRD_e9f^!aIO!)K=A_NDF9-je=;6iItg_0$AEdO3@1(4bOcF8*@NjhNS zdbI=~i|~;GNYwDyY6#g1AVmntxM9uq8{BWom_n}%w3RcUD65Lo<|nqBWw_@Lq~Ax}?F@75~9 zaL5lWq2U&+A*q5EtRSo~g~Kyy6AVF5WLh;Pt2t4JCfurxE%I!lqut6qYP+zdtOIwFYJGw8bjC$-MI6-w3u ziQrG!8MT~H*QHuD^z^q*Eg&91lwmkY5iB51L2v_eKPdc{zv{?+t3|nPRZ16wxWBzc zuyHCJr(X#nwHdFq`&?VGzDIiCEvbC>cs^@fyOw^d;P#ZjhvXc+(z9Un`SC3*6c}VE zD(F9_Yhz7rRUS^Z$`%U1N0%x(E&wnZgZYk5{&9A!LH+$h>KQ&hv?Zfe z3Rfj?S%RJxSFD;vc z353i>}?z6X4)0TBEA=g86_<$72W!!L^vQUefw?^@eU8L?_{ zAPxdFInMxX0cAxp{!w*M%<8<@!nPIyZ2T0Q1xV4xf&tJg6!b%GFM9;CZ-tOta5~;0 zj2tdlhs+wV2a!@S!1=)bX$B;k%=TD_Xl8-FxVel@^G5o8!wU`wj4o2_DY!@M4I}Y~*G9{`}c zpCJqI;bUZ4WDs9tmn;CCe@lD64I=QNKw^ynmjGuP0vZ|yRx=n}o`H|T2LLc8U^5xb zCg31$SP8_=i%*KM4;$AhV_?RZ6pPq${@$`-ZB@>Hl!A+C-?Y|sS7g3Zx2yv|4tbaG zQ6p{9phP%v3V-N8wH}xGmn`?9Jr$Pwb?u6d@5F*-B3k*B1%)Q1js%)7gRB#Qf zlt5%D8&z)5${nKxR8!E{S_CnTH!7W18MfHQ(tF7PZ4vGYS*L0i5L(roReGeH)h})T zB`B#rf7=BJNu?9zfPg{sDxmBouk2@h`SJy#V)=!g4`@dof*LLq7r38I~(^WZhRgt)Y#U1#w!NE+5wDp*?vJ=8}<2*4kOAw zVQVwI)YYj4U>+5Y?j09*0LUQ^10vKND_5m+DR8-_80p6I0(moI>G)!NiRsLd(rrLf zybtpInZ3;*q_%xlaT?F9^aKxS{KJ~rkW_JQ?dD6*cI`~ezy3PlKl~{!Lgs6M8q96bE@a{*9tihe7Ew20rXHd~)Q|57YRY6U74IgHXS6Q%u9%T0@m zRqh}?$3M!3#OfBM%BA3R4ZIwM^HEwzA)(NSSjw0|r`A7e~LE*QPKo7(yPwJ}hckon3&gB5`z2d}gprNE+%9bNyr5#-w5*-*!d z)fMAgx-`*iYUyv5ti9KUqZTFqR@YP-)0ZX$-z#_=0CE7vZi@MqeRWoMd|Iv0-+LxN zTmVjb$7f4B)!K~s%=fgS2up6WaUf}NWMxBpc7s2qLA9IXClNQe;#3 zIHl`8Pw&H;Y+`#$S`;wnI_3YT7KJtLP4_hIN9SJg`^}aYEI=nxzk<$S=U^cPliW5A zs9kzgA0R9_j|v2)){oTviUz0e4I(LgPzc%60&?d6F>Jb*}417?S!yw^zZQajJmB*?XaBsUq?oC5yB zYudGl@(PcLRPT9DaUchPJQx_H4aYD0{Pcux85bp5jE2t2dv~VPTA?cdutw2O71&xH z>})5o04F7vFTFzPF9xCBA|2`m@Yn;SmS(+k717t8&lneoP8GzN8;xOM?y?pT?f1=f zvbo={)~%aR7!1G)%A)3imMC40)%ijG-bcq z^!%yf&4FB4gdOwZEy-WapCP3TsdYK$QIWz&5hYaNO>y; zb*G|kSRfGM)Ag!xJ&j3PdMDQ?x=YDkJfQe>>-zy)?60@>DNB}$Qq06P$M>3ULtTq+ zX*m%YokNWJ;sGFsG)pc9!o!8naF8}UQLtuwE)*8bHCA0|)EX}K;cTDqT<|qL+ovj2 z&`z$!k5Uvqbp?RJ^B_L-{(R}|kMx1tqf6Bqc-q=gMOKMBw=+?AmWzu0Y#^T8u+pGx zZ7qzoz>2yQf-%VN-*b(*S$S7Am#xq3mcMISIxYdow0%*F&>k@>vJr^(fRGm8YPoi= zbK4z)kk8s?t30GGMuORp;c7|YwNL;i;24yE5V)FqR)7!si5N!wUE1`w7BPGPfKm#l z(<#7*8H+VOiUbQt#holt=%e_Z`SZ6nM{NdR9Iz&e(O?Ns_)nKc*Ur|b0qHi`j>aTu ztuLA^$i1tj@i$$*rC!h0LZoZ@hMJY3w0`%h4p2QZ7(t}a?SMoEapXtBzYrB#fwVIquM7du5q%a z!%f|(u324s2BVpP__a#xYNeOkV4d(n1IY31tq2cU>q`Ml=(?>jA8UfR*9NKQEJ2Hf z^OE$&d&II7k73#dQt!LGb^xz#Tevr8`QWfH;j?2l#C8DAis9D>2&lk=VH^mldVMNY zlZ6lq6|5P)0y+f~x6PDZ7e=C!2FCL1!AG8`+aZkq87ERukitj!U6h{1fo$q~d>s%V zss(bh$6^Z)#si1{K7P7(V~OHEDN;1mF13;{vYw{oO#{wpYG;diLW;Et>$PGV*1*YL zmVi*hr}5l-j+eFZ_tM|t+Vc6qEg=VhJcyLyGQ0w=GYYxRz=*i8Gtt&UCfT0$ZE)Wq z*r!D$drOe_mZE(vh5VxJ>|14jJp&&KK(qpEt?DX;ApiX&K4)vGw3z3w*#R!q1Zk22 zeE9GE2zqput~E_=Zu>P#`kG4aOA34IHOCpS9w!}R?fU(5+EUA-`S~WlXKML~AtX(e z8voysWC=MKF)WS&;MQQUHZDHMEEr_4hD6{&;zQUtjbou4uxJS`26Fs->fLL(X-UCC zn%NwD&}!x{FE8`!x^l*=S|P&hn8K1TxeSSX4t!cMbaGxhMHvDgK=fTQ25t0AiApUX z-ohah5J|zs!wPlVqJil2U7=%%yg+kPqsPMDaMF?z{8GTV22iaz{(DG|t227zqsmbU z{lP&*WExfuKDJVQ?!~=!z}ne9#jaDi)S;FAmt4YDJqP}D`wqgqLGY*9XS#m%z+&2G zrb=#X^!K1jyyP~54H^UDloB<&7R4B(T~PcN;KR!=0Mw^CfT$Izdp8Z-W?THknu_qN z;4i6gPnSo(4cdz-UUE&|0<-3K*ji~`a2{DUmOk5$I~9FnV;sazN2Z9e~4V4)A<2LJA*SYJ13nb>*34kWku2mC(=P=iqiFrNrrU0_RiO zT^a+zIS&?)PHqFGlJ#RvCG@^`*S2>RbfxXg70Va{%LL9Ox4YmB+#1*sQdqJN7t#UE z2rZm37;EEC#-q48W9-eUpl_LIe6-{iKf1KU#XhPl)&U?73?f^C#n%AIJ>Y{v2nC8# zN9bcvZY|dYlho~N>0BjHxkPd9D={g100;oQS`KFFz8}7Fc?moyfPg^AtS;bD%c~!5&|F7&%Fvj5Juum9oNv&){wvTX(dH~<|1h}-9ODReLOczDmXD34TXiit zrLNb@ZR6U{{<+X0_8A!Y*)RY89p|T~RfP)ID8i-V2`;m49E-neQVly*EVZ_-Uc{*A z)l$6DV^F2EAAiiWcv|jyYqRP8T5{(rUCYw(gkZDTctwsS1)u#N`h{LYYZKZ4J)ghU z(@Eg@B%rm0(k61J5rX0QH17@Fai{HG$USIn(G~Wi+r*kFpsWnPg<$SGXQOh;6aWdM zd4Lcu42&(GqZ1l~7SVI0fKii9m}aX9g%JuL#+V2`+;!+E5S>EVpoUctQiG4^(Jr`O z-CSX^Ca6s`oKii$@9-?rYkkC^^aDU1Q1+-;uDmqgGMfkP`vDN#ogCQm@Oxkl9mAaQ)OMYhR4{6QV^-ZRx5mz zo?G_!9N{5V>gUVq03ZZ|5CU5B1Xfs6%2TJD=AmT?5Tg4OK4&X0T&I|U#eDx5E^^N* zg$w`zAkt^_^^3%rkg`nfhh7JLUOE%s&~ehrPCd@Oj*i#y69&_VV@BK0jx~qO4!~dr z^vST#_;ajKr}an3v+0DMK?waVTj0Y(%Ajr04NK^_Qn(NTe^D>^`t|DwQGEc9n&rnB z1E|RgvIHR%YD8jvpzu*DK3KATT&1tiv>^-TT&-+uA?rB95LwM!8eKzN_>6V?Gg!zm z?QUuTu@HAv$mp0$-91Ve+_Ql5qd~|4AP*>|biCJSDbP2n)A5SD^{gK{*uS&^IYDrN1cr$^?97<|nvZV&r zJ(cp7bBmStR{|BW^ZjhG&^!`^902mb5aJt4x~$f)nqR1$QoH(@|C|MYgTdJEi^}_l z2bKby(AW;nMaYgt2Z;1j@XuuC?AvTmSSn7pXRN~V;KxG>%Wy3u==^ly@oB2w=eIYU zpDNj18j9SNmY?Kloiy2qq`$~l%xl-hE&>pRiRFvp$Cxv^S}LH|8TUwKaXg<8VmopWQnP?i2rgMbsFfrI1*J*5|N2h>FqBe7 z@bG{#zm{aio>WT*5R_|Qu(0oYcg){@nZsdn&n@sV3qBu}Uc+KYIRBalQmyK6qEgrx zYk-(SiF9xA@B!)~6QC|Q2ZMz#J7}~57ZPWsGc&;&%CL(A(bH^;xp8|5dU9^TEd_z2=P|zHuNzeG!|s5yVcSRPc0z576%gj z+$-T@X`8;b-)IflJP;C~dzL<~z#JXRAywg{Qr>mIFgQzyvBIU^)gyciK-Xyk5@HcN zN}!R0ka$^at&qavm89CGE?4opJHdzFj;?d>LwszdlI!G`xg9BgPgG$#r(xywx*Nu%#EgrIY!HFrp*4OU>ZX0KCBx(%!i)A1{pqu}Znd z_U&yq@F;E9XCMSvwuT&X$lhWg(RB(25*QR1KLJ{Sixav8ozuYcJ!Q}wOiqgQD}Hui zAW5tTwQzX&@F{pp+j$7_VBu?oXiUL}3k*3=$L5SO5N0VZ; zv1r>Evwi*M$)>{bcZrRy?0>65!KuENi%q#_OvnKsKNyTWJw44DU@3crKt4aXU}e*= zH`n@9v8i>0c39DjzWv_#QeOrs?-5k;gNU6$M+zhNtd$Yu+uJU{u^C(ztRaUSvI}%* z4K4&E<51R20p*?h!5}_!fu`0&;b2R{sqTUf(fRxiR0>a4c?j>)6c#=<~j zFuwzMT2xGP@h2J_%vhYq;B%V&ijhxRO?|I1!(G$cB803t&ZVwcHyt|{6#dd~d8_gS z_i)R4BnUYG*Uu4 z7Pbr+wTj?1`6^r-$kzE+=VCR^juzaoXeYi@XmD?#=h&J{M_UU!&R*^r(0a(n5gLGQ zw1y(H=N>}1IKk*1f=Osw{y%$sI7^BT#;s0{*;fob&tuc(Ih8O!w*thAuTY!%+CXDbAo|WY=%)lyJbeYtOBZ(28 z$9v46gu#LXsKbYcy^@k8eS8d=LSoTqE5`M@sG6;Xh?477ZY;`WVzdcxq=D+iOjzvk zRLe)drhB+%-CGU-`GKTFxZfI}L>In?#vHvkb2y>q+H@8vHw%ykZ3)%}D6J5&)#Ymm zOlrQi>1@)qs;xhS<)Z-%t|`wWc$@(I>Fo`Fd3xH#ulJBcN)VFEz-1s|v;p80d5#m9 zF%V3`at>i6K>jznpVf155aZ%SIu2N2(RGt$BnKZ_Yy4|}0_O-|ky<>v7x@VYv%NpWx@3{dLZQ5wHIoAfuK6YXZ=Cn^FP8rI?OG z^3Npa3U)0xNg?DOF(F4w_`xIx8kZJ6EV*>WFVPd3Q<-;ArT^2<(#xB(pfG$d`nR@N zIK;-cqXjOm1s~UttyR%a!oYmL-*r<6sXqDTloUgF}It=`FIH zgBb&G0}BZTg^(-PaCoMOK!gpjg3aKAD&$@qeDILv%DYzOtR6lEZ)pFS7!a?VE2Z$W z_$#asIJ2L_Hd0C`rSSUtiZA#Vd;tKwTm&6U@F5_ep`ncd2cNBIa-`n*(cF(ASBh}K0iI-+l?UP__cp9X?4N6#6*{7T@V#msewy+JWcL_ zf>U@2=V%37kWc-i1-0)H7ZOtK+V-qar{wb%avlN13$=ojiZ#+|=ziG&ABQZy6Qk1W z>#%TZVMZmuK%!&7U}a`vMg@xqz+tR&%K|r{fMKkFa`;?HR$0jB`Luvl7Jo6%ks?j& zcz7k-TRkXz(3&4 z8Ys2ut!Xg5vQJUgFZ%y^oZWe5m%o5{Q}}hn)g%91ZMsFUDvK!;jMFd7VER+P|9cuXmIMUvWA*{7=IeaqO8^8#2Z zI=FhAvG=j)|LDN7l-hWWHH1RQtztwD0Qmu>WCan8FwzPnTlU#1x%<(WTSq7u=}a)a z??}V7+BkLb**;~TQ<|QL4fb-`$Gx1heoU5-NpX1-Jb*;j38EFLVU6+Z#gZ!W{TEl|P;zBfm5vN3HxO(UU#;4WgA}Clk zQMPJ9@6Q5JZKu`=tXAj<_u2>_wd64OEG&2{V0lmAk^_z{_nSfpg^|6pWgR2y4<;q| ztF&NEOCwzy760|gxjXosHq`0CafDffutv}zcKuSu(03Yh+g^5~Y9J)eCF9U9jQ zOg~1|9~eGT=n#b$DGhXLdC`jL`5FP>?j6pC?RCWr9iB0(clI=eu{V>?Oztdy9u5Z1 zSoFUkzk|sDMcUcy;f`gDnp_bcL_CC~8L^g97HeY;7py~;+q~9z9qI|62hCj_kJ0K8 z-~-Oh3LGvg77$YO`Zm~g+`)(G06u_QUWJa(2PCyW;`h|d0?mCUte?bhFr!I9o&;2{ zAWxzQ3n_?ra93lsbEDg)BBtVkX<`T-Vm@f#z0wSf>s9cfE5UspKA5#&uu*k$V2TAn z0vaN5wF;?rjZe=d-1g)D9Doa*H=*yXrQa?0Pi5f9fyENoY^iYGqI7>`IJqUTtgYz2 z1vqm0&$a4=902lz$`W)ey&Ov&+32D?%PsC_VX*Q=(KmV?*E(N#$rp+t(azu1RB?j~ zow*9d9)T$1ih+f(HnM`GfMQ^0mXo#j>foY%uY0;*rNQW1u7wtTJLHfoT$nxtp_im% zz@SZV#R?Dt1!fYf2u4c?;?%eXgM$h?hm15OE)5{h!AA~4ewMG`mcy#~%c6Q+gb)fM z-c74inZy7OIRsExI`S8XS^cFJbW;G>yS4O`@ zg^Y5+aH+DqI5WRvT0nXqg1dSk@iopfU`5wVVlY~x8Cp8(G>z|>Sahl zG2LzqA;Xk40yJ`U=V+hiU>1S=*>ANm& zp9}h1<7Zm}5*c7*0|XR6qg3g8&rav-7ZE8=r%vKGZGgZ3e)so+#({V@thMd&$bxl9 zz8{F+pl2a*)})pODM}dn32y~qROvZGq6<~djS>z>q_ZMgWx*vNxPy-A`0jn{^uOZF zeh%P~x?trhn*Wm=U>JiCBC6oM6uUuT!^1)fDW?~ad51(5VgNuTJraX~)*3$3w;iX0 zD1TI;=XV(CpmTOzOmLm=C zAqRsXEcS|W|Cm^xS?SXR{T&-vd zUK;zMlOWtLFDLw_41W6i?>IluZy18ozXLsQcUwE;ko?4j2q2DUwt0yx(zfoE7TgrH@=+^6kj&!ob(<>-e2UtV5-6JVHxI_uEUr?BDOvuMEiKgj`> zTSy^8e@;Q67PC>ah=jgih>HZ~;Gz!v0)5|)pg|QD6+wtm^gL5`Dr*hQidR`#2F8W! z4=Xzg#$e$rA{GFwn}joVN{MUn3Cj9DH*G6CTb!^2413MSueF?{`>a*Uw}Mpaa@@LZ z>3D0l+2V4xbg#ANFACsrPu=l$uzARbkdpPIwZX5ErT7V|RF_<`7Gp3T970O6Hnt+o z-+oPKqi$Nh(@YCBt`U`)c@&&imHvB!$O!-~iFVd;YUEtScp+T+)I$zwfskyUVSRx* z?lNJK*pCVFIhd8OY=nC5GF}-Kznv~1+$r`#2=HEmcLvY;7o6G8S<8nHHvgHOAtZ<8 z7G2jxfMAS)WHJCiwr?M|rGV0s?W$RECC8_rk-`Un2tM)yRo?o+Wf%S55ANA8YhXuH zOD!F(9<3h^+NN1~Wn3!uoUv4J4l!Cie0)erNu|pB+FDyBh1ef+jcXU(ekqgHT7`To zEZjyZ-Y*N-=E8?d$KB~TYs6bV_OyZ=0P@iWLR>%N)0&QgD%SM-dxeiFgH-%I2PYmz z==NLSWKW^WwTBV0(1E^pU*H-L`B;#&TKx1IILnUGM^|~sGK6>uLFeB3!5GXKd>;Bh z0wG*#bi9Mo7R<^3_6{JNMM8|l2kl@&Rw^zTHlP3t~s-%r=C1(Ft7 z<63nO7-_xc62$GT=iN$|^y0zeaKSnxl2Uc^d%PI;RREqMH!%NwDf`wI2uWchCp9=p zkJs@}#j56eUV927y)JiVP7#l*spo2da4y5Fpb&iKij^wQW!ApM%T_z(Hm z&{490cnG1N6hZ=Ma6n3qLH7W}l+g+UfGI|UO98>0OVh8zD_)+TBg>;P20xkKrqVUz zCzGsc$S)NZ^vk^Er34@rd;|v$qti@y>9%n|xrYqT7g7i)JuNr72W*4-#dv@aZ}ITJ z5xz4Xs-0_VLPc^vZse3pWj{q0j+~Mn+^3Q_5&yrw)KLsV8KX6lD zy2hnzzZRe@g4j67pM-|iW%sLlLkKNI*kj7f^-PwP0@6KH9dbza-IOBC#tSZ7N?g*f z(%6qQgDi!SuIpgn6jY`pxK!Yl!>~zF9nOIG0+vznRIpD%Ou_t|2PKPIKWqauXltXC>{}H1lJ#OQXjnRaZTS{J$tn72h4rM4q1c{z_|sf zG~Fx7g4HohF(6};q6G3#|>fH~|C%m}Fu9K@Tp@#PTX^`0eR=7|g2YSh9vp;6bb|q~3?Ck3y`pj6-yM z1}AC1Q3d4>C^QJ?t<1iXAp4v_J!CLZ~c&k%!oCi zsdaNo{aV+nwa~EU_RMP)0C$8fR97A zzUL!&a4BF2aCq48)(`)N4#R-c*RRl8LrM;%B!IZ4hfAM(2JhTE#v#BY1J@kJ0D_&+ z53exBKx>!n$_JX~;KOnYjuXHK2qvR-96b8;bvjBG5x-mr0U;QawlE9T&#jrx$+!ye z;Xx$Cd8Dr((=#_L|DG}?v&;Q&GAIpZ4F<~qqoKhU#uZ;oa2%iPcfkGuU|oO{Zzb{2 zK>@`QNMQkJc;tdb-L|$?HTN~7)+)Y&v7)lS)vA#K#Fh+E&1r2PEI#ogK}RVg))518 z2!L&|A0-HpNhR(UWq;}f0BtkNFLb|3^MBW_#aljF&UYzD@GEtC{1l|@+!s9j{&dTY5;7ph+}G@*b_)f){oqFJ@T$tKKqr@=IC$^naR-i=uWO> zaVa1fhqA`Ohqa;I-I+4VA`0pM($U3k58^&Oj z2`ax&#R~vjjK6{A7?gIdqdbvDQn|dTF-M!IQek#w75+=-UC41c_Z1gVJ*Rj2Z2<{ z_g3zl^?`oZq#C)Ot!V+C)|9_F_{e3dO2LCac$TLem;@lHyuz1SL8h5G;@)5llwx5J zr|@AIpIo)L4Azlz1qw>ga4Cr7&eIowpjijEqW{{ z;?RH;+fwLySF1JIud@9*SMFMs0DP>A6%I5qRt_5f5djYaxD_yxM~V%%4B8Gbn!`fD zS`N#m>g3+Ku_V4~d8lX(SLktc(t?G6_R18A^$6oC=Yaj@g7b};1ulCbN_^5%$p4N{8K;E%DJw2^N}$5qw~b8Q~JJad&oZfDjK5mq5sQ1CRiK z_>M3m>(lRQZ4XzhLz+Ou$AI{_4-X&QS`5i>8v@W7V0#8-wM(hnaX@S0UPX!tDgiF_ z=w@Z3Xwl*9gW+jLEIZY$&<3YdhlvwxHlx+nz;g#BCRkTY72NyfDORQ<@JQjquQQCz zG#P7p44Ok*9~3SELNIIKORM`BjS`6XisckSEK!^+1o=K!uEMtLbNFr2$Fjx!c<&g8 zt%`Up-EWI^VoQ9;mSg=W@UTl;!0n0=9;50H(nxe+KMmk{=iqa%{O2+YQ3$zJF~TJU zywz=~s_5SVPN-$XUt7+7>lz)7F)GZ;D#c*z1Ruc-#i(o#b1MkR0m*aAdA_~j<&S@W zv;zQfz{ep)@$OfyztaTHQx_fUj7XIy0%zB z1nKB%1A|Y$>(6CK&i$8eocB|FmJ#UQ5V8a!sVHM0&#%z(`GAl^mfs&z6NIMXP3wQq zIv_qX78_$C`rawfCn>=?=dzP#!h&(J9+q<$-Gg@wR=au@5+Z^TnnK!tPh&Xf|24SS z9XwJ92?I?6ALI9#^&?U$ovW2G2sJ>IWsp2}A(fm#TlZ&;ivls=;4mQ@mRF28Oi+>h zddVy-TmU=gB68;fWC%8ABcNFF-NT{pV`W2^vPUKEwKcykP5FCGCHxXlc@!|&`m8Ro z^gOB@qv{8d7O=R)-O2^1Z?{&YE>f2sFCO^!4Sv4_PI49p8bI#1DFvF}O?g_`8PoK; z-u3E*XjW2M7%c%i>;fUcZ8B!1MG7?lq0WFh`j|r&CILtgdRS&Hkct18HZUNiJ|LKc z9xQ&fujt@X?P_Tt;8Ni#s{lT}Q+xola~1UP;rc&P{4V1LMT>>f>{YFRQQB5(Hsxp$0j8jMF&@LG^i8cFE%BCn!NyvJ^}S}Gy7YRkso?MVtgcx^`j+lj2Y|d& zd3$>cR**g5qDA(O+1M4nD)ArJw7ityq!jcXWv|L~ASHNN1&WG6N;|qm*+qz2f>&Av zJzS?zBY@EM!I64FbGvWw_TDa8&qr5s$le1u=OJkUH-O5my#!`Q&O#~r&Ws(IS>p`s&^cW1v#a|ep;|@Xw zEzpSu)rML>QkSgEee_DfS~;HALP`UpU643^?k*D+Pr$@mfW}E8#&O~t+W72!B3Lk# zF|$|?`oFh)Ok)F&)=}`Oc@eaL$D_=Em*PL({X4v~+f({nO27Xa=)9I|magcW2Y?&` zV0-%AJ*72e?>&GfK!<&Ef9$r;E2r>pO^>@&6C?*HO0^dz{3?K7H%xhWxKN6La{)<| z3x9qoEtuf|e$T?h7HGKnV03ghhpc%oxBzt7Tt?IJY7LkqTdf*vh6pBM8HX8q^dXfl ziPIS4JOt+uRzgEH!3R~|bN^G9t;KzrhE|D{gK79I4iq@Tcj{J^f(6rKg>w%!JSsQ{ zj0Ff8Ep{j&q;WAHQNIc27CHcH$eaKGAOJ~3K~%=6865+OqW>^H0}2)2IG-Xdh{K z4_V!K#L5?9YomQsi%4YgV2=}bvR6^Skk!i80cA`3skI$t7*0~S(r8KcD{AS8Q}k*K zhQa*fXLK-l{@Xg2yK4gnwSxFsAi$K8m(f7pqo+Ki_I_tl@fP1<gQ<-PnXEKP{veoywkmwC0g*wAXe80b;MB=zJ8w0i){{x2a{F`XtOne_O^F-U z`8 zQebgwhjOcoRhM;~>0t8q(82GQfJ{qfueH##CP4uWcK6@YS|G|ggdc*|;y(Ob~o?2kJVy<#|M=TzlE`msS&MbDha`zyh zwF=e_YQ69-S)Mb_uC&N#WtvwtPd`(I%Ex@9@KLf5Jdz@MiH>lu>$?;dt_gEFczg69 z@*I3TJv|*+unuuT8$zo)R_?`JWBPq`_;4?FtSo*s_}Bs}IZ=jXV>|L~Cf<(L`k0+F ztp$=;M>u!B***Ug0HA;I$22&NZY#`cFry&<{`wsY>14ju$%#g%kB&VWTzhtJ?$yr-S&cQ&dnA?y}ms&SGXt@4s+GYtpati3)S*I>l z#`gw}qt?dzc@9Sm$RVp?WC=oQoyuCU*fYb_M;03Mkyc~h%N=VgSV(S*+m@^#OUI?P zKzx9DC`O10G_uc%b0~g_mc5?bwkNH?tVZ{@Z`+>9AOA4vOk9F-0|kI_X9saL-z>E4 zVHAUbj^M{Xi~blx4_SKWr2sbq&qCnWUw@6@!+%B!GtUDD1rPtfcf(4*`&uBbpWg-_ zllxT}LOgtU#oA~D%Y@AJ7$nvs#ECGt?*v>F+;XKoT)2dDtOM*IW}rd;_vdGZ!DtR2 zIt~D8XxDDE)-Yp*bft!n@rpu7dZ;w;+4ZjS7zk6Uzin|Ko2>pfT&@{LC@uA$z8&+1;B|N@Nvl2K8epNfqP4a4?fSi zTfO!QqLcG=qe47bK#s6MEgt|v7OWH~_J9%~4l4J`za7LFBJW(KPUZ{FuYJ6YBKxpu zKX1vPE>@}^^G`7w*7w@tG@7>QJ|0GxFyO*vzbXNSPaSNm1-O7UHdHtV7?`i)#6>o4 zLm30f`3N2+{KnoILW>YC#hH{8{k7?H_p+R<1(rR5sP(*uTpvDAfRAfgKMnx-U=RXK zE?K3z4zx2!<2pG1Od5oaVkp)?1qFgzz{u8Ek9)_6Y=;jwPhlazpaXoQP*JkNr02b4 z)8(u36qKr z;C0F)2IP>Uw8ny@AmU>{7{0@pZv;fdSlL(4pkh_SPWHPNkZgg8()RvXxod4bN9uM} zlU%@fw#ea>TV?#s^b9;o=Ukfx*vEh5EGs-3u%}{#v^b%M6E$3~%@67!AW17@3s!AQECf_}miLF#w&MxnQLbqO~P&n!w=danFEbFZk#O6|!P+Hoy>= zNWq}?zyItyf8B1GkNcqe)q>4~^r|*U#DmDx8Gp_+lx=h7TP!MCTo? z&w|Cdi~`J+VxjkNbw6xyy^06Knl0iwl09QmI58e9V@f*B-j}0~Iivy`YPm18%D_mT zjRlFIn!Kvs9g8maP?Ca%|9>ywNZ}*AMr?>6AcYMM1?{aF5Fwa+aWbK@oj(T!l^n3l z`d|`tZW*6ye{d1LKT9!!#-|YXAvkySKgNk2K?2Op80+De0hqyuw|>yczBM&6N^r3@ zUen@JwePwl_M>I{8eAOUvF#b>VDddb%VTK$pi-*~QkoG-Gh+D;&lO_&UQyNs>3qKt z7$_U|IR88YokxI=*|XXRO1b?~Kg-;8Z%Loq0vb)vF$X8s;<>>LkXk={MRqAI`tvLB zyYu+lmN620wEy;uNlir0H7%5dZ-`a)6=-g%Hr>6@N1- z=330^c3c7u4yJc5PDVxdnMjEYjo&8Er4F>DASeTE;knEEV7_PnZXdpf0Qy$0+XwhWN*>;UB|8k%LfIcYZUlv z-S4Bp$Tb7`*TnFweXgQGpQMxBdsssb0Qo^dq-FMl0!b-duQuNSye0d2e^@uC9z)4H z>rAeg^{WOcTfnLm3sMuwEqYzHet1``H2p43v0ExesFaz-h+Gl}a z@85ri_(y(NKMrYz5MZ)~Xk&skLTiK5NjM9|;H(-HKK!y-Ur<;M052zrS2ev`gBAb> z20Z~a{oE?2m)^#6)WApRCJK0xliGO{+|O6WuKat)3JGNAp4I92=4_pu6=DDP+NZA+*`i~ zj2y%3I~VVlM?cqq2<>2M1q;ia`n*6PwQO)Mz(?QOy+PzwP;)J}u`PfSEAyWV8CzHc z7|X|dsV!P(%f9Z5>wL5pfJz+PLNuw1vpXSebJ z+ouK6?<3bT=88Un0bY4Z;DcEM%Xs*#{$69w-e);x-ZLhu>*3+U5DQBRGig68xrH{{ z>t{*!28&NwLBl9on8 z&9Q4Cr1T=jF!FhX5a)hH1K?K;jv4o@mKcg$V7OnlZ%1dy^a^7` z&I&>SMj3_^8Ovp+s2HsWVvK^ad=`^&4=YI3`Y}rPw{KByACUq0Lk@|RS3NSWPr<4q z2yp{_q0R#V3~({IRB>l55rReV(f2w4gmE$DlfFMRI zXrIKPq(GuAo8lzQw9oU42?6DF(t&jvCrs&h>G3_lNX|m`EBDDp_bCzeHQLxHHpEy9 z#l>jJaM#7GfwnBTT~Y8*V?oAR#q%wbRV5FDAJvWN(I8__xLA`Vl#|2=EiUWnb^8Bn z5R!hcy5l9E)HQ31732Vr4=mIgQVTF{>Co0#N78H^p2GbLq>~pZ_hQsu_~|%r0Y>!r zV%I<<#B}R;|`fB)8z!L^VHXFgg&|1M&Y; z_pDXQU6^@{_wWDB)25DV$@&p~!$1B3@=~kIAwL|5Ob}u)D2;AxLx#G$jus9N9-@;Y zaQK*wB!krmBOWSRz(cQ?b;!d9Lgn*PO_9DK*xkc{-*!q*YqQ&`o&Ia13%85{PipjU0$j;HW_eT|X@sfYD>^4J=klFRedy68)f} zO5hYMC}5Ocmy=*gObD@H)KZL(=klNW%%=Y}eNX2}FSKP~cI=~U8{iB|N6<3ByLKU} z0n(!I8S@=1)9-Ip%rB|yu?H|bLg4kK*RTX1t#EO9zwsDu-J7rf0FXnx&}!(lfb^Tf zPQl7itM0m`1FX4m)oPq*;?8vmOw_<&X~v4=rm1+n)q?(?e)qtU#&qOT?Na5xmUzOiE3Ma- z%^<|XhZGWqx`$e4;PCyB1p|X~FSE?q$n97)9Y(`|!!E!_%k1(sGE-dxNcKF(B`#un z-&<}RrDOdP5O`?V3s7#E`*Cam%+2W=pPBYi2akS|Fujgh9_q;yt_-BnKV$Ov!u5A=dyA>V~B) zgZJ|B-vfkLhCbtdwI+UJv2P&9yfhteJZV#QtxDJRW40=py!ReHJW#MsgOAH7gwR-% zlVI6CgTjblc3Pjfen#-&jw5EQI z$HMLB-#a_inwZc>leKPu*T0@aKAccXNQ;trua1RY3v~fXvk%q&&vjBuRcF_}d_El_ zJ>I2$ymZ}?HRv8P&yHcqfFH+y2*GhaTL3m|8R3;GE?P@aLaj1>zcdacD!P}61BoX^ z812|%6+~M=b68lgba?_Z9zwVQ~9es2Z0_UwGh;w_+2iq||OZUfh9yT|bQL8WE^@k+e7uwkZ! zY;uY}-Db(OCmLW$tmvecEG3tAgzqu)h9KkM#YgN!xcjE8s-8hq`QWD3B$C=n|vqWj9{ z+Dz_X0YXN|@B!u&<6D(;OO*Qbm68d>$T1@pwSt82n$2Kl9EH$vXKfmc4VBpk<0_kL zL$g?^?1)0MTzw?)Sb~ZrxNz~4A@OQ_kBLi?Hs2veH#3{RB8oZT7u8lHkO=)Qd|lce&5mJ#>^l{Wep&YuARK2?(^Ns9g&psYQhT??J>{L2B+-tO6Ts++G#7XUVo{ zzhK7N9IzUaO|D!yON!(iy*94cAZHQq_+o+FV-AV||7r{5nbHSHYyFNcmb_qQhS+>ec0iVz+E@(!g2AM|qxK59YVB@4$| zKhZ-TA5fNOW=y0E(C-vHN<{-p`)&agcik6QuvVPc!$*JA|2U+zok{^H*Uq%|Rt+}Q z0Lgq(mn&}pumH}3nkm@1>{wgjB(<)j>3d7ivh*I=!h6S1cE4iD{{DX-z)s(N|NhgM z62Fyyew;HfJI!tj&H&-|(ZtF@tCVwz0Ko~F0EFL zYh|&b=QhRwf7{^WE4E*oGA0T{7e|vgB-j2&>xVWPP{1%aI~|WEaAL~`ZDW9Q8#-$< zvldWGgDSjdTP-8O{mKLVn6*nA6S-meSdSKkfm$+b0tc!4RnF=`;UWhbOA3sCenu+@ zAuuTADxCuu0!UdHBOv+c)}?!hvEZ!hYra9SPt`;x*BCqYJm%8ml2@#2*_^Ib17lBj zqOJSi11@f9VY!AIAf2$zO7eqp|LabJAFozpt^xfa zhm;ke2|~Q${;Fa(EC9hGlEQ?K|0sb*1SO+F-4ANlELrqieG9fw|%zR>5cvYZ)~B`)>fEDCWk5ocnP) zPHrtOcunY7t9Z96_m_Z5y6+aCSQ8uK@4sbRy3Nv9dJpKxd8pLd>!teD(sqXn)(3?U z+5q$djW#!?0s!O!#d8Bx+-aC9Xe_-HxtCy%;HJ_HK<@jc5YkczaH#{k1W-!*<^s^y zoF@f>93Z3>ir-sZ55XBUA@>siuevB>@Ktaq`Eqndhg9JM0E~9=AGD85fudx|Sh8?< zK%p6_sFiNJA~VIJglt(!h4WNV@Y$){goDk3NX{CPLJ6DoSFT=&vMe0WF9#Na-K_-} z2eSs2aex6`E>4Uw7yv??pws{Zi+=0?a$PJq(5B)F81197l2~zB(L86_dDc$40MPK_U(~Mcdr?ECWm8GeG{gnPZ>; zAwFQ-D$4Uwn zKA#xO72I78`FPTuI{f-NL@=RNw)-4Zq`~U45FfG@M(D9b^69M?G&r6D!E!R|7%-NV z*|}muQ|Ef1OShwME3+n?&+p@)#_gwV?2@(B`kiiHf|ETao$di1th0|fpP!xrbbNk#0y441>3&Q9?;!_(d_X{HtsK7jJR23sYAulk=ty6b zYs81VM_FUGUn4E?AeX?#DwnOl-C%}|t4N6x095yk=k9=yLn?jRn0nXCdH4;AWR6lB z`^qI(t#rKy6Gduuv_N-Aw2%M|%P0t}01O^7azH}iqXZ+)k~3L0Yzh_QadH9c^ti6y zVG&@YLF{zwD#1qyCaV7Q8Q0$ToW!LB9=WlGZtLSEt~J5d@@yXoQf{sLKd<_OQD0x|8@)^k1MqwdZ`iU#s=-u3_YiezuafiaB%$twN?N^%v@o8V!kb)oy)w+j@xq!1fXYUs5q`GV(; z<2)D);|yxYPe+3}WVwCv6Qtlp#rqNnnZ3V-cZb5qQgC|;A9NpWEYw&x<3Ie*zr+69 zPvHN~W%l_>V1$B#hl1SoQrPg@__`dd@Lsz6WZ7q7$+_t=kpK~ekF{gnUaq=JO8GtE z!>1O$hipA>PH#zAt63zO?oCd6~owd27gE-`N5V0n6N-bj+ z{iT&sGf-GtA^l=yPW2G~?Z5APP|J!|kf~R6DpB_=p|yq97W;+4AMz2!jG2^jh5K?! z^%n3*tpQ6`k0lV1oTFD7Cn-WKh%zQRkNK$CxF=3$h~t?68^2_JsUZ-J0&Jjd3IV^kMOQz3t3Dd}#l z!RC)Hhj#e^LF5urZpj8x+xJoZUvq9?*X~?z0Uz{}4lX&r+%>?`0v5LlFrR_R-@ak^ z$IsJsu*r4Ifd_MjIpmPMa3KPO_u8}v4;vId`Y|&UwNUu|)F1zV=l?Omhx+^}0*bKRcDV$Jn z@NpcW{}|svximpwG%R>Hhp%dGqi19uvQKXf?!Ls0=~|Fe8`H1(tXs+hd{hyI|Mi`K zWKZ|213*3qprjCzQgdqo!dwN-HM0z9Al^MYiq>50>Fm#Y0+FSFztVEQ4;>68dn?9( z*MD z-xThdR4w<{DwAwgUYT31qefOgr`_ggx z(q~O|gvo8cP=S>P!bl6FaJ`oZ~y@<3sd8XksZxuOu^kHM4Fy=hI5)Y|c0 zz#}&nwT_c}-rFO(N!MJye{}Fzqx*SK*#kuOcDFhJ+df)kIH=4d$SLE=z;fOEA&`C&rj+`yDbaSnD`N zxXSNA`!T@(oZhDsV1x(&03ZNKL_t)u1|SShzx@XM^wZJd9I^->x&OaDcQ_Af5ke@8 z?52!l(%n+n@eqLo0@Ad+lJiL6_t~>3n4}OvVI)1i2Mk57A%zTMth3OV^jUFe@Q01> z*rISh$~CN+jC_>wZ;hwNM}mwr!BFYB?4f5~8%mBeyzfwaBcKgrDJ$064k?!lJ(n$G zNx`T4Uek12>LAy4mTPCDT08DsmJz><{ymIRRk3cgZhP_X`tSc;89vzMH9EAhFxG?s z^nUg`lk=J*3)Ue8pcQ!)NC>v7EnY)5vKK=dfj|6ZwSZw(yuZ%@E@1UW1q9{@xsglsXt>P}YXShI+|NNb5jQf{~mX z)NJ1?bq-rPQF`sQ!7jHh-M0iZ={Ao9AvqwZfrVe+vP~;|&~5d<|94R~tknIgS_Qoj zfDQnI1#Bj@ZvVdnC&s{%-{pt_Ib;bsqV_c?7_92Fv`WCxGHbMC^;zn`x7H-NR%Q?% z_d%h;7y}^$lv2%Bjx~YkrEOCy$O*uZUN3kZLRJIUA0QY57bm=Q&xhsXkkv8_0|smH zSCuN}vR(MVkCYW)J@LcV)X?L0NW2R%or50l(NneBydOUFGdEgx$f&netX+qEj*dv1Fx z(4zWH&TUO^e73C+;?HrdqJ#&4{D89uA8{`Cqd~}0mG(UcUS*#`EJ;f>begSdDFfD4 zAi1Th7qhVomL}P;I)0kXa36BW;`=K&q}mUxTVgzNF&{NWz1D~P|LvV!iz_*r=l?qh zj=+Kp=zt6;Lm4um5~`pIx?uWZU>bHV26`_BdSSoVUhGGhn})gQfw`E4S?GZor~_3{ z2l7BBxWES@Aqr%WK?el07ZD08WJ#fTvD0?yfy7Qb91#vH9z8!jZ=1ye%iZn(JY3;d zec;h9bkOecOd!$kaXG9X(j1F0u?0h}+3-JyxszQ06r38yY!AfL@T;j%m;fY+SIlnc zeFN(14E8Gn5?9r*W3KwSa!E8?XyDM5uucgIRaStC^{{IvBp9QRmSG_!kP`wS0LB22 zxa*kUBgrV8)N~RTQp~b1{pc&LD?F8_#>&R1dgTh=vc=`);F27G$FUY`rU1t=z~)lt z&Lpo7gRhyCe=KiD0+1_~q16el4L)o) zv>M=4;28S3Az@;#t;es$Fh8XYGe=I-)ZaO_U=RcF;%G|!T2PSyJBIUYJRaOnJxSa2}G z;~4oLPWkxU#-bAdAa3}P3ZOk2tx^iPH8EtLK7)Vp4%w$V4}|bFs@8x^UXUbV_{eGD zgb+#@L|L_PU{+@lPhY2A6qsi@v1(B%$aBTRP>S;Je&!#!A)7e14 zm6lmPhKDTXbG=|}*><6xAD03g2|z9!Ja)UCGuOja<)E+D_PMQaq_yVLi0$q0^%Bv5 zk!6|pJs+q{6-p^sxrTWE;qXl*y%5sb2dN-c-W_L*z^vSx$-Re#fAOwXhzg)m0N8&v z^#Mr|5?A<@l%j1&XqUu|fe$;E!&lu(cNf)Nof;bUo?-}k#+FNB=ZFtZcUT?U%V z2tJiD{2E4g4D`fY@43A|*AiZK>hjTJu8#{oYqC#ENlf;SQJPIiKLa?TQh?EknT!T5_Lp{GhJ-^KRrSERqr<+cGi$GOX zX;37ImP(eWWaIUK#1EU&4G*5a9WD=u{b(97zI>0RQAT&^fRAPKo^Cqm()(j|{a7QE z%Wx={30Q9>gsHE0OYCnH+J4SCea!id9cxp^=~#&E3$^ooX0DtNmyMG=AW2>gNL(RV zA&-cu%*`7p6w9b5I&<5(CjsUm{+Qa=_BKi86J6~}HzFLGgg)kYLP#*|`w(=L*4=H7 zQp+F&?+u^Is?EVz(yPU!+CWkQO0(qsNa7Xk`LIKJpVp_D?99JmA6^L|nzcemag z5E6h7s*N=PP-6EgkR4UXr9{Cf#^@O z04Rkx@I1%rP7NRW(FGr60)VRk4jVpP-U@}A+2*s@;w8TCGzCiLup`EXd>!jv8M4fE z>0XZnAXg@#P^?Q#?)HUSP4RFH@$e++0*IOKp_>toZ9*9P87U>OT-8grcL0+L__T9O zssv0Kc^YY&=&00ph$ELjWbTEzb*}>M@sS21p)fC_2jUdVhBS zT-E@R@<5UV?|Gq+(;Sj;$Vxy6%V#{}dhKf)H5n@wix|(A62>!Uh1h(S5q} z^cncaGVIN=?n6K$bp9@&nfv@>7a!+_51(yjFD74NZ;u2ZNrD6aoF|;Q&&`{=;;G_9 z)C&~ZCpn7|tNeYCb4f7b1B1D8KwQDYRZBfOeni0z8y4#)*DP-F@U4HrueDMxa zeukg~sq;sYq3{6!m8_7{9H0b0myf~wJ>=n-E5ua;#zO-kuJ^{wALl-YoB}+CB!Hh% zOrzapz?(gw`o81bUXrQs;d)Q+|Ja~1hXzK&miISxb)0JsbCd7c^(CK(9sc{5%r0YNALdGd2` z<$Np~$gto0zIpxN4%`AyH+AUBF&4H?4IkGiE>A}&&!Z1gVm>>E@jhhUbIsF3`j{OX zG&=hju=M43T#`WOu*_qOH)2blCYRP zKn}*2JpH}ys~7jUSfKD2Jo?TndLU#DI5>s=>w^zQ!}F?;J21L{ke6p5hVmi$K6C8y zx5om5*Pc`Lyul)2BzZp)fLw&w1GTTz?p#SvzUoouChQ0>GIkqR^_oj8zpFS0ilT*% zKJW;6LPAxvD5a1h13vx&eEbRQw+fJYv4)%*z|tn;{lB z`d}mU8S}H}4kNy*QA0m_ju3LrVlGkGNO;Y(lAHa$!o9X z^;#mOL{;q@{kam-V?e}yUjq%#??M0iTd=Qgz}|lVd;Ck3mqo)z$7p!ocDkmI8ACAO zgBD8&DItYOVOU9=5`qu)ir%wLz;o_`lT8C2u5WXHq(~-LUSJG-WK?y)L&FE9w+HYr z20rElnIWRjpVHg*`MH2hlKtY8{f7h}qa}Gjt^h*pybzyJH3kaoFr~iGB3Ffx*yEV{ zk2MxUuU(?aIK*A9x3~ZIZ9gWyS9?J684|Gzu>o)xY9%Q^i>&^=K5l_*4F;gf3Os?L z`05T2he_yw;r;N=>Ku@Mj|d_BV9e-hDTFdGN)vn}8E3FEg723F9?R;iJfS`~*`S*T zvWb8OpZ<^W01v$;=CSt>vgphJF3-iRzv+nm#&}NZaIcp}=e~FW#rIy4>2Pt3eI)ou z0P<#FBnCu)@s+Y-JQcojeS@F}ewQZ0<#l%-B7HCsf)=h8!OxF%t#i(i=Q*U5U=gFn z2SP^<~X1JEX+cf21HLaqQnsSL2f zH-rN6)e4l-S->mF8!=*ZFA(E@04ON%bOuVx7y6_-rTd^G20rZfkD2qqC20XffkDcb zHech|UWz%OMFYvubCvStWDxS!LbAq|qc&|Y)BZ}}kpSe)$k3i30yyicCU#Y?xmPMK z5k|&rGiBmvb2Ov`=Nyz$R8@r>Ihf%Qh^>TGvLzT>12`<{E2Tui2n3c8??2Q=8v#nb z0kV5!V(+DJgQ$Ari8;R2G_^Lh;r$Q&@@ z>%H=7_p1dSQ$fVG!BT~*1RzNwZon~$q%X9}t^)O1iYDcS%mhOGu)M7cB6@$1Cc&I~ z0HweN>f5hCe)_eJ>zdP^8HY*hYc{vBa#5*>Sbt| z-Z42LHgv?g;(gm+Vr8f|ZAcm3kfEO&vW*Z5AO!6026)~=eB9RK^ozqWuJb|Yz#a>d z5HQqvC*~|dzj%jCaWDzw*?oeKByk3Di)EWikd zou>h6kK$2VpaJX_l<|2Qe0+@3JET-p1lJf!({ivimN>_BCPCDO@)4hSfKJArr zVZg@_=x`g4a?<^gBnbd;Av54ut zuCaLxdw$}wp0_By1%a5g+Lr0@2!&yp;BkpwkiI$J_dDAjykj>-c1355Z7M7rc3YAJ zAXfzLd1RHk`QrXC!{*&5XAko9B|mp78eF&xbS^biL+kKp3+R zQ=G}?s4G|1b`k+2O+5bd7UF9oDc#WvL^Q|CRn=yZ@O;@xkWb!^B+Y4i8rH z5_lX9M$9~rAs_~M4T7TyG1=UyGMucrAbWde0 zbH!Q+0lmdq5flIjWctCA3^S4}FNg^rE(5nOjKl^EpHXBRO;bH1a{)l?xg0(A-U6X9 z-@`W-X~SBBi1tdg_7kwp$&l1cBc(TSq?p)_LbxgWE9;qB}0+6c` zyPCr7V$s{EZ%iJAuMbCzali4D<6|Br;`5rgR!{m?*QS=<9b0Db>J)?J!5ABcC8b1J z>QVFveDj?XSgNdOAtdKz3oOht+3J2E`Nv;S-QA*iesOk1_l03`DUm@ye)?Q{S5%rL zl8hHFIZfss>$?Ce2A0Fnf|PN?Wkd z4HM1J6Kt=t!?`_Q&N(J*NFNijH`n>31oH$SR|6NJkg9|5qGmf50SQCA17hTRgZJAi zfJLh~LaRHz1Tj+y#llBSsYV-)>|B?(QpHP32_Z!LoKhML&$3@*j6w(r#%P;$vEmzS zxImQ^Sg8tYQgW#3E7INBUJpYSz$Ld|AmPJo$G2mlK(LK-N! zaT@9wxgKLx;U<`1K4lCIdHopUBDBbvfFl9O#fmw2T_I5R|Hm?o*v#M&3nVo_EIMke zPjQTmtB$)lw%&$TzSWm&0}rzsy6b(;IkGH^F#Kx+E#n)kvnAHq5`;fuwf+GjTOvmZ z)^tHP!NZgyW=wtkWgULijt|nw>!>8ar2_k<>7d+J`BAMhq?Dm5D==e4Tk;gyn`9W2 z06~gn50ju}NZg&(2nHmapHoxl;K~fv-ecSoElG}5do}+wT zd%Kv-CCJ>Z0LE6f@N8iQL_S zYWV1kWr95Gj;ONYAj*HPw5Owbk|b`xK7@}JLWqJmBOPJGhrXYRi4Za+9Om2%UEg;& zRjFX#_45IRzeBwHJL&zn_7@6`?h{|q`IKvTj4EhTq1Xi>3nL;WmEKJNa`wRS;>qE7 z&DDWWM^dMPJOP-92qnNKDt4CwjjiDE7DBN!fY=qSLQM%>P_oXJ9Wcqil^~)7p2L$} z>46e*cMA{-q4vKgAr?f)tThrdqM&~HwcST_jJ!-9kR-$4qb}Vnfa<)?*@lk;@V6ku zPI4bwiRcpb?l9#cGP<@kYbmH z9Fhld>fDmC4GLpwj=vT7(4uodd`ahJb`L6k23bEs6sw?T#NJP}ya(qw9`JLoC!{l$ z?`{DlTL?LLUmcFFj3~H%IYzsxFfZz)cqtNmBnd;Us|+ttdq=n+$S6hm3f%!*hI`?G z57#!E0mnI}j(kmBD<(E#49$0Q&i%(8T``dkryAkHf{?!RvLhv2&*!@Cu8O0bs#wH)>aXR!AlQ2g^hceY<={*LHXRzMO0;n{}V-GUnl=O7f4WGKJ71N-m`vJb<@ z{@-K@dB#8)O-d=r>|k;Zx^TJM;kzCn(aGsc&-+(rRGt_^ zt>&^Blbi*Jn966j+j*M|hLq?z8T@+)xtXN&=ZMoh#cIfq3FaaVDI*6&7~x1}h?WKw zE#)8n09LN?@csjqfBI7$+VO|K#+oj{^LrH46H2yhKW8=}+|Ufm41fcsGh&S)B>}=v zHJ%YgnqNWzf-~gQA11Th?SSkZ03gruPVR^4^?qo$eR;A=ygZ*=n4!5e3(5fjwO`d zLduuMI9ou-UHfRhZ}-)>=D6Y5@_m;mCRl{>KuidsltQf@@bl^cWc>*C{sY)Q|0h=e zz4n4+gaS<{7NvEg!Zpc}^RfmT>2654*Iu-S54aP~wNz3erv%dI{~>Mww$;0#V3Z&) zaxlu;s#hk2q)J#xoO-t{!`tazR9zL=owbL)I$na zVhW*U-9D#ZD>_=HvTA5{?fLI+uxP+Y4s!fS?3YDU{CHZH7m z{Rnvcw^mHNs2i~obYk{$I}c61t~=@WryM(zGdc2gdF+kn$=BP2YroHzFMj0axQ&sr=GM3mGM<*Nj&)|Hj`381*a!CKJ=9-+r+K6nms&9UhpIKF$d zTZ@3iS$7iU@NFBvw%H%_%5GTjY5)?~$b!4b29HCc1e#wv2VwrYeW4<3K*G*F=0m8) z1%7^VQ8?k(aSgpsP+Us{cU@!#uJH>mu5Bv(r7}4~t>52#l6-4wyZL*{N!y?fx2fru zH^Q}P18k%bflYn&HJv}-JyyJAW-40N zQ#DBDe*lj<57Z8)WI)kQU1c}NOyDn9Z7Mq?wbKOUcUQ~pGi={Cxt$jktcs_s&$9dzYs&8%X6PDNXz+EVEOA7V= zRIBwyPlr+;m)81@YM;RPW6HrgJ^C^8H|DFN`jDW&*W|TU3K&A=dM=P&h*orDsMLk3 zxJ8)-XG&>&D$BN5~(`Hyb zr?OG&&-wDN_M~9bzx!KM_kQ&@RIFZFlrBTBVuI81fDSKj3VqvZptxT-)i>3Ha2n+3vrON}R*9 zyoRN}UZ)j#^naQ?jVr_IpdD$ssb)0`zOq(bG|8fjl^zo za(uOX0<7LR3E#Z)`oUxKgc=7=o)Jay!^`w*2mz8E5!m)&dHBgfI$>-1Z>k~y z=|@KJ^6+2rqUK2|^9u1zpBMr2Q7$DO36T+Ui2O{9uTIvhC(?T*YhdiFw_AN@w-F8O z?@#AD7 z9(|k$@(-ACF8*kl{(0&iVAN(ERDJIbN{4wTx^2Elc_Nw3@zco58!Hpz8g=m?oVMJ# z3!No+z!lW?k(kebI@x~N1`l)VhA^nDApN8}c4r3dE*|;Fgi}8^YA`1NuTTPk}ALavT^l*TW zhbo{(mZzgi#Im*&(h1>iYG3mPaw6cBDBa~REmxfjn*}Mnl=u-pXvvg*7<>ah z4(5bIp zaus4F>F7tHF0`mqB}>=KIjVQwRF$&Eg*w!8(kxddLj5-h07yTX*i;HsPTI5NwxVpp zEbqm}=O?7}AC6o1PCiN92A+Lt z7EW?Rm%YREL0#Uda1Hn&AMB+=Hsn#<%_(nNxXcEo(mx1%YW{N-^f_64Z=95ug4nl{ z58Njf*Nwn48TUv{f!~jr^abyTl&!la7+_{aUo1XzHlhW#{&q zU2OEVW`HAy$@Xl~#8j0EgTUzRZ0cjUHbGoi|1TUyUX)vH`tDWbckl$&V|&4$v;l{|5__E)_dqd4h z1;aWHfCp8i1gpwkdjH}mtMrV`#`PY8Ou|URYFuDdzb_)c?lI>Lc4aWx#X$>MT+&{w zR-8sFCDW}fFTirwV;5%Di;hVAjC1}O z^@}AN%R`F&=y?{oW@n-u-kcx8YNcIG%boWKH_#mU+|Qy$y5X!#@cM0od0iw#->a2U zZ^%Td0I(cEFJ7#t86@le{D3k$wnr7`G-c*-YPy%k5{$+N8&lo$#9n&N7&QH&`(O`` z5Xezp`G_YR05(Mg=O3J0&s_Uz+p5hUQtIH!AG)zQX&d=3wYHoz(RtAg;J{cI{Jy!o z3{PBx>J#Jz6Fpl=SeHaCcS6GiZt5Q&#>pWs33l3A%ZxsYljL{&dQ}2_0kj6J-Qi&e z!S864R`pCT&wds!97fsVC~8DguV|`)FJ&Zs0DwF)O_JMn!uqAg`1`y6B9H5iY6cMI zlZ)1$VFMb{&izso=Ir4hpFg64Q~HIgdXuv&Y<3U>Ndb|j4cH;J~Pl}yH93G)+2S=tJ zPozF(*9^&>++`&3%?!K=u@Rs$ZVEO?UX0Lx0L=y297X>fNn$uZ|?3dubpo95#-?V2*(!@%iMMqf9vz@g zhqQj-k~@w)e)&P^vqcIv-lQl+R=oYidblE9QrsT3^v7t?wjN&P93OoLomeEb=}=qn z{$@EF`sIDtU!LAZdL`Y;0V#?Q&^(?EZ=Q!5YdEQ*DW{dzGP~6}Gp?5ND?*8zz(iU- z_XlpMLe?sB?z0)AK{^tEgo6-Lw}(?D^E|QMvqbSX@fPD^Em7eFSkVrrfNl5i<}B8m z9Zz8_cGLG3j!*E~s7AJe)0KfuB#Po)GUH3*d0(*J)k;3)L%3?dpXS|dvs3&=X?@sE zEl#&(+0Zn0RY*)r3Hu>%mOvgvmEa(uoVfX~$TmvWy_{q`bn}%$`m$9Bjry^yj zTCRG%A9(f5#U>q%qB|MEmFwfU&#h=*@SpaPmtQD5Rx|jeZ6V+hJYI-?Z zz}Vx$9V9;&&cZK6Iaeb87woRCicq`)EV{w!=QejUk%0X0Y#sS)qKe7jhX2_Esa6-6 z1kJNlGIk^y$LfcXP;8v&_%8MN`8}dMeh{wvhqtmRp9pz!n5COw_3!gYaVeV;Mw4{~ zzAEJe20C9dnv#qyOvx?HxRuY0!OAIURwUh^?xgvS_GLNqZ+=&~qY0k}Saq;2=XF-W zA1mnxPV?r@n@=Ee*0XHSRuFGj^Y~N%hMJ^uR*aryM_s_zv`5G`Q7+|>>Scn*2;#|&t3Ji2?J8S zq%O(t;9??$ZO_Rrd4G@PIj(2)VgU2Cn@5{`Px+bO%;8GrdwAPCEX{-Ze{tod&H3NT z5L+Pfk~eZj<2S1uclndOszYi#RW!)0_5e9JNuCR_f@BN0@9e6;HvF^TyKVxOxQ)bA zOtT@9hez1uoE$;7RbR6!ywy!oeSFv%TrI3}xT}wX`*@cL^mF^tDB0rGu#7Q+vyjbW z+l>lQVtt*;ACA_88U}w;_55}!2uMyrLGa-dFNKQm@jaCy{8JGmIKp($VBF7VZg$Ec z>T$T#g(30iA9LDt!I%YNj%$k>Ygo|praZqgGM@+1k1;g!dFD12=8s+meLSi#eSA&* zsm*fZ%0)1~H+|_JyN=K4YS!cTSUU>nOYs$4d zy&s%|6;-BXhfPa&6c-m4K1ifoa6F!^jp`*-=n@#xtEw)@RK^0r1|%^WRE=#CwVcWR z6U(sSv8d-|Fw>nRO`I4k>tvrHO)kx(qzaWX3l@veHqbSp06U#{BVM(L!rj+Chpy3; z3{<{u=HRI~V5N~im3>Mcwi|n|kWo&5I0zT;@w4BmEJcNPMi|90+y6K6^3h`_A5KYU=pA8$aS(>o;t9_4@ zxoi@4;XIvHA%RSGc9oEWwtIGk+e5s8>bD(4MYLHS$@b9)@&U|bY;2gye`1c{M#luG zVg2aI$PV8vzebi)*?~t}Lbv*Yvs0*s>TC0qGMM4cLSc_tisvi(erPHRm)56?B)>sT zT5lC6|C3m;;@4&znwaWUsPZIpJKb=CQr;?y+iMh2%kJ&PoXrn&W2R^8W3?`QQD-g+ zbqMbZpU8)yv3EP@KZUpD)*@?l1T>E%1|n#{-nwqmX=R;-%1!1M9!Kox=fS;WPHf`| zNHX<*+*IOP2WJ;{)nsVG3_mTL&--_7-yx6DB>x*F9@3`-yc=CMytf(s2gSh&7@{ye zl0?pQZjyKgSSsO@9f@kWqq($cj`jE7?>dMk@x+wj2} zHp|>K>Ay+8^HUkcrD;Xmx8BrgGX#-lI|J5zC~~EwM_Y(3?UP$X>}W4$V}d` z)>Dk4*Fc|$yj~)EFGjQQv^IEsoP$JKDBW#Vvea=|G^Bk=xo(k&$t8Ih zhdpmc-Y*Ad{(EwFpPT$$13vdZ{ew)@%ojS_WbId6ADle9z2#uzvRU^!O?z^VvJplQ z?nhBijNS>OX8_fvWf*&=nEZBZt~2nHqw-lQPv8aC8>vSQ8k2^bAH9EHLR|@Im zb>+9_0cxyDrdN$#j49?TA!48Iw+p~4rsVIOaxZyhkM5~WG{Y8`aW7;Ez8 z#;oR*Xh*3$vl;oh#n9WkxP+Vk18oHWR5u?#AWVjcd0>@bu8~c>;6jm{o?VBI$<qg*W8WFY#3lD9}tV-Zq%$?nms;J=sK;PCMN$4qQM55f30Q5pdU$$l`&F z039PHoFYlP*~)}=ZjD3s0Y?yKvhn%slbr%Resz_6eyax0?<<0L>ZEp!&9(T@g1r_3 zz(q6uVA?WdXU&1m22TkmPoh*E_(_rPJ07sGS!LEo-);U+XxhH-e4f#>>5{Doc04lJ z4YPz1en*hVYxa6&s`M!t-N<)00Pa(ZfAxnjt>#clcsDxbNgOdxz}TBlicj858fdu=exW^)Tx3g>zBD#GsWPCx)W7LzDf59!QB11{=xYX z!AOF`TK@$a$r+%BuTo8K=u1f?a$I7oriEj28z)q+H1noRP|Iy3A;d<95#mBm#i;m& z`W3vo#F~00C366WR95(@I*>JAD|;|7{m+Z$=#UgAVw}Le198uhJv{V3;bo#3AF4ih z%@`vZxtdu}(O=uQ05*mJY?zfcJeu0n&JXV6+T!KBI7sRn^LMi1qB;q7YSq(HG0*uTlK8V%fSDy9X7;rGMTcq`!=B{e3hieg*XaOsxh> zNQl}S3s@CpPFqmCrOqJxsiC=2CR;C%Y-^PiS!pZj^gvMd5wUDiFW!)A%yPlxobdjF0fI`ad(B3zvQ z=X@aj{Yr&Tzh?*tx)RG>H#X$NreCq2c19`@raet%$16W=4=3k_MVInj$@PQ!83`Dw zBQVYcHYgi9RPa}C%<lhnIna{ zgn)1O+R{JpP6NRJiz1FFiDodb^Gt_qFV;bjs0GFIfpA$PEU|te><=}5?wXY#F+qgyRGvxn8c8irl!!guoYTW@&p1so#P{1uR>^oq6n?RCC^l}+OXiAONUh*1=F(j7w zXI}Rz(9dGl3M%!+q|TjN!s_CJrU=SOMor;AhddcKc3Z)WcQQ30CO7N_TQ8r8kz&Ja zj2@7786ai?SDpz7P+as=!gpOktm9KsQes`Y!r$Nbg!fk>&=Y^Vh_tT2U6e{SnLt&W z!f@ydGa+ZXNyPB_M*{O(kOjnEpB_qplvK+8BBK$onq?RP~b#$DcBGw1>pmA%X1E!B3&u= zP3~s>O;(~O?TbzD#QfHEB8C2aOk$+YI4w z$g9f`CPO%hwN$+pZ>hy`Qa$3%{N6dXobNjUQC-1N4a1C#uiMmk+TEu@K-o75?uv=p z;h^Y7_>}ZgV0cc@walxb9e*CI5^gnVlEu%ys5(3DpNG>$zX8cdBCTi*urydLwWgVTCu0Ry=P;8|P`I!YpiNbwV0rf4BKNAQCen32l^_r*eV$Fe#&dPh=eTa}^8{tJ4 z5;-_Z12s?+pyTrWz3*bWYaryW?G-i6gakT8fUtC5COaoHJT(y^v81LxyWLons0-4G z%Ez5&?}#L3my$zinq63?+l893xIqrp6R~xvioo|Oa)M3##5K0pXo*_DKPkB6%hQ55 zSv7;RsiSXTWfoIgMdi&{XZqNZuIEcvqN-9%NS+oZbE4pU#9T}=o6wm27Rww(9K*;r>lmyd ziyVXTnIJy%$T0#ASdn|dckar^X%Jr}VUP?~6vD)RPu?C>G>EZ_$r8&$>!4`g6nglQ z+IXuNF)mS=Ks~K|8nk!0033?ufkrH_hy8K|+ng&44nw!22Zq61eMY|nb>>-?@hGOf z5Y3!mAnbw<)$#kefn`&uwMk`|Z7-{I&k3v>B#mQbQaR%PF%qw&g)^hrG=rR2N~X*2 z(RKUy>2dvX*KO8TN)<;q=F<8(A^DYa)7c{4#!1liu&X2R8A;pUYXSOL0>g_SBAzTO z(@OvVc%z}Lq)&ia%Pk}X`TtPVH1U62SQ&WYLL{es3H%_E%|LtFa+3*I{nFT-nb=(s z5V#4%c6KC^rL18E_>58(U+_gdZWU%cP5dvc0hc<>PXCx2W8nzf; z*tgHP#}uD5Ts0r~P4$372{%Euza+{Bd67}Dm`MM(*RiKc-NwMVWLzGGVb53SwR~1u zW+_@xxD_?YXv~=yDz}3GvT+^|?Cz%E*DU<-Z8U+L{dI#A$DVD{+OHPrM%%Xqw<{(a zbQX8l0_+T=c2{_<18rfsEKt7OWRxB?=Y9k#ykw4B6AEm=o8R|LXZw$?G16uw%+k0d z%~flx$OJC1 z;_@0T`UX$5@sFh2HDK#KSErbRRkGrbIhjd;$-OJuQb|7-&e`Nu&YYDu&)KqiJH-x4 zPv2Wm<)m9%zkD@GsgMfI%mSVm7tyI2h(_4=P{?7Cyy%cPd676$J8i&hGOj(}+|KI= z&2Yuhkvrh`NMh)95DmU<=k@^MniPD(AWsZCV&!4IH@Y&oc+GxHX4PniZt?dENXoSr4jtnC&UT576V+RsSRY;{)ZRq0di= zwr(P&jFgxy)E~j_Ou-P z7w@Zxsd=Bzc+fre7@1iWuId#Ru*DYb|9m6l&}Vkf6p%5f>mW0fBO^7GC4kBD=el7{ z+BEJ|AOza*?t%d}yw#Mli~3>i<##O`2W$^5T~B)39j-OqIXW?{H~wABy8(Hj9;gdZ z_+j&})o(pc2ROHNAwEWyIpDk`m{s6w>!RNDpdR6=3>^#corl>co?kr>G}z<^dlV8# zvg~?)nm{$?1rI;=4GWw`RmLAH{4e8F(BS=8h8z~f>k*!w^pmpor|d)y%r>h{3QwyZ z?wFE)Q{Yxzpy@sJ>SDh3z`N3|-)~yX^MA16-wlYOJRg-^*v@Lc5VUD!o#WUso-P&H zged**$~~drtV(KRBN@vW)4zwsOTHN@o9SlC9>nVALwa=qjE-;L;lwi*IK&~DEmNvt zHy_4jPQvT!;TFinESSIltsh|9=c(=w^u+ zJHhlzMdcMj{CTgALq5Z@ng&x&?j}Q72Roy*vQwz%-QvgDMWj3fFrB7@H3{MDYk6Y4 zQ8-29o=03sDPIr44%2B+g7gf+>=we8Azmr|+UY;^|Hu;d4dbL&0an8(jh@W%;n-0e z0+~(&=ASZ6Bfy@(V6y(F52t2gCc*Iig@;;ufNB{Z%Rci*n`o+OhvHq4>&#D`$ZXr- zD3MX|wdgI<;wPZQe`(IFU6rx67;R64Fv$7Qa-MY;ev)x?I0meEJa=@vQ7f~4aBM2J zo_QXkQbP8ctn@UzfIQ>_BjAUXj6M_y=^$Qte!?YDdEHSy!Z%b%nU5r_rG(fHOj2N% z{azoUi95G%S`j_;!C^<9B*x&G(4X_ym&XKX;jBs}`rD8K12S=KW%P)gg>dT{}L02dPu>BnKX(gC{h__>NpU#=QG| z6RxqKb9XT6pgFDzE=xci88MC~z<88QozERw;~6iVv9JC(NvV5>6DfblWO}zf0}!Ky zJ3qxQ`i40!I;-5d;Ael#x5XngG2Q*WJn)St z7vc7Q-Bq8xq3JWxdj-7XymD6ek8$3FHgJ6$nAD$P6esT4ut&wgJ}!0XA|%e6&FDVw zI$be~QadSA+_m%urpd~wcmVp6sei&iHeo|%s=iA;%!%W$kDJ3;)-PP2eO${U!%3Jn zW3|Gj4cM#t%)&h-1+J1m42~S*9G^WWvww8E#uyA!?P0V)3?!e2Ck-294|)gOD5`J-kpa7K`>Hxi zKQfM0Db9LleNv=;@y@CA!S{uG3}Mdm@7tLxFUyrLJtC>dxv+ob)z$revicd%oBdP( P_NSrpM7bPp75e`GpD+!@ From eb668180c8a53f973fc6058d98995288a862f243 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2019 21:44:50 +0100 Subject: [PATCH 077/203] - implemented help and credits menu for Blood. --- source/blood/src/d_menu.cpp | 2 +- source/common/menu/imagescroller.cpp | 1 + source/common/menu/menudef.cpp | 1 + source/common/utility/stringtable.h | 2 +- wadsrc/static/demolition/menudef.txt | 5 ++++- 5 files changed, 8 insertions(+), 3 deletions(-) diff --git a/source/blood/src/d_menu.cpp b/source/blood/src/d_menu.cpp index 5b8e74b17..847703615 100644 --- a/source/blood/src/d_menu.cpp +++ b/source/blood/src/d_menu.cpp @@ -181,7 +181,7 @@ protected: void PostDraw() { - itemBloodQAV->Draw(); + //itemBloodQAV->Draw(); } }; diff --git a/source/common/menu/imagescroller.cpp b/source/common/menu/imagescroller.cpp index b9446463a..92bb9220d 100644 --- a/source/common/menu/imagescroller.cpp +++ b/source/common/menu/imagescroller.cpp @@ -102,6 +102,7 @@ bool DImageScrollerMenu::MenuEvent(int mkey, bool fromcontroller) if (pageTransition.current) pageTransition.current->origin = { 0,0 }; return DMenu::MenuEvent(mkey, fromcontroller); + case MKEY_Left: if (pageTransition.previous == nullptr) { diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 4af11fb44..86f2fbd75 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -644,6 +644,7 @@ static void ParseImageScroller(FScanner &sc) FImageScrollerDescriptor *desc = new FImageScrollerDescriptor; desc->mType = MDESC_ImageScroller; desc->mMenuName = sc.String; + desc->mClass = NAME_None; ParseImageScrollerBody(sc, desc); bool scratch = ReplaceMenu(sc, desc); diff --git a/source/common/utility/stringtable.h b/source/common/utility/stringtable.h index e66f45eee..f18c5315a 100644 --- a/source/common/utility/stringtable.h +++ b/source/common/utility/stringtable.h @@ -126,7 +126,7 @@ public: const char* localize(const char* str) { - return *str == '$' ? GetString(str + 1, nullptr) : str; + return *str == '$' ? operator()(str + 1) : str; } }; diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 65223ff78..825992f80 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -116,11 +116,12 @@ LISTMENU "IngameMenu" centermenu Linespacing 17 NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" - NativeTextItem "$MNU_MULTIPLAYER", "m", "MultiMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" + NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_HELP", "h", "HelpMenu" NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" + NativeTextItem "$MNU_ENDGAME", "e", "QuitToMenu" NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" } ifgame(ShadowWarrior) @@ -419,6 +420,7 @@ ImageScroller "HelpMenu" } ifgame(blood) { + class "Blood.ImageScrollerMenu" // The duplication here is to integrate the alternating versions of HELP3 QAVAnimationItem "Help4.qav" QAVAnimationItem "Help5.qav" @@ -530,6 +532,7 @@ ImageScroller "CreditsMenu" } ifgame(blood) { + class "Blood.ImageScrollerMenu" QAVAnimationItem "Credits.qav" } ifgame(ShadowWarrior) From e743268c4b16f98d45dd002296c2d5780dbf3c2e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2019 22:54:52 +0100 Subject: [PATCH 078/203] - Blood load/save works. --- source/blood/src/blood.h | 2 + source/blood/src/d_menu.cpp | 37 +++++----- source/blood/src/demo.cpp | 2 - source/blood/src/levels.cpp | 2 +- source/blood/src/levels.h | 2 - source/blood/src/loadsave.cpp | 101 ++++++++++------------------ source/blood/src/loadsave.h | 6 +- source/blood/src/menu.cpp | 2 - source/common/menu/loadsavemenu.cpp | 2 +- source/common/utility/namedef.h | 1 + 10 files changed, 60 insertions(+), 97 deletions(-) diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index e4e1af4e4..eda86e57c 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -95,6 +95,8 @@ struct GameInterface : ::GameInterface void StartGame(FGameStartup& gs) override; void DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) override; void DrawMenuCaption(const DVector2& origin, const char* text) override; + bool SaveGame(FSaveGameNode*) override; + bool LoadGame(FSaveGameNode*) override; }; END_BLD_NS diff --git a/source/blood/src/d_menu.cpp b/source/blood/src/d_menu.cpp index 847703615..1d6c14c5f 100644 --- a/source/blood/src/d_menu.cpp +++ b/source/blood/src/d_menu.cpp @@ -141,29 +141,22 @@ static std::unique_ptr itemBloodQAV; // This must be global to void UpdateNetworkMenus(void) { - // Kept as a reminder to reimplement later. -#if 0 - if (gGameOptions.nGameType > 0) + // For now disable the network menu item as it is not yet functional. + for (auto name : { NAME_MainMenu, NAME_IngameMenu }) { - itemMain1.resource = &menuNetStart; - itemMain1.data = 2; + FMenuDescriptor** desc = MenuDescriptors.CheckKey(name); + if (desc != NULL && (*desc)->mType == MDESC_ListMenu) + { + FListMenuDescriptor* ld = static_cast(*desc); + for (auto& li : ld->mItems) + { + if (li->GetAction(nullptr) == NAME_MultiMenu) + { + li->mEnabled = false; + } + } + } } - else - { - itemMain1.resource = &menuEpisode; - itemMain1.data = -1; - } - if (gGameOptions.nGameType > 0) - { - itemMainSave1.resource = &menuNetStart; - itemMainSave1.data = 2; - } - else - { - itemMainSave1.resource = &menuEpisode; - itemMainSave1.data = -1; - } -#endif } //---------------------------------------------------------------------------- @@ -181,7 +174,7 @@ protected: void PostDraw() { - //itemBloodQAV->Draw(); + itemBloodQAV->Draw(); } }; diff --git a/source/blood/src/demo.cpp b/source/blood/src/demo.cpp index dc1970161..de8d9cec2 100644 --- a/source/blood/src/demo.cpp +++ b/source/blood/src/demo.cpp @@ -64,8 +64,6 @@ void ReadGameOptionsLegacy(GAMEOPTIONS &gameOptions, GAMEOPTIONSLEGACY &gameOpti strcpy(gameOptions.zLevelName, gameOptionsLegacy.zLevelName); strcpy(gameOptions.zLevelSong, gameOptionsLegacy.zLevelSong); gameOptions.nTrackNumber = gameOptionsLegacy.nTrackNumber; - strcpy(gameOptions.szSaveGameName, gameOptionsLegacy.szSaveGameName); - strcpy(gameOptions.szUserGameName, gameOptionsLegacy.szUserGameName); gameOptions.nSaveGameSlot = gameOptionsLegacy.nSaveGameSlot; gameOptions.picEntry = gameOptionsLegacy.picEntry; gameOptions.uMapCRC = gameOptionsLegacy.uMapCRC; diff --git a/source/blood/src/levels.cpp b/source/blood/src/levels.cpp index ec543659a..27b094600 100644 --- a/source/blood/src/levels.cpp +++ b/source/blood/src/levels.cpp @@ -50,7 +50,7 @@ BEGIN_BLD_NS GAMEOPTIONS gGameOptions; GAMEOPTIONS gSingleGameOptions = { - 0, 2, 0, 0, "", "", 2, "", "", 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3600, 1800, 1800, 7200 + 0, 2, 0, 0, "", "", 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3600, 1800, 1800, 7200 }; EPISODEINFO gEpisodeInfo[kMaxEpisodes+1]; diff --git a/source/blood/src/levels.h b/source/blood/src/levels.h index f331b0d89..dc526e444 100644 --- a/source/blood/src/levels.h +++ b/source/blood/src/levels.h @@ -41,8 +41,6 @@ struct GAMEOPTIONS { char zLevelName[BMAX_PATH]; char zLevelSong[BMAX_PATH]; int nTrackNumber; //at12a; - char szSaveGameName[BMAX_PATH]; - char szUserGameName[BMAX_PATH]; short nSaveGameSlot; int picEntry; unsigned int uMapCRC; diff --git a/source/blood/src/loadsave.cpp b/source/blood/src/loadsave.cpp index 01e7ef102..5d00cd268 100644 --- a/source/blood/src/loadsave.cpp +++ b/source/blood/src/loadsave.cpp @@ -51,7 +51,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS -GAMEOPTIONS gSaveGameOptions[10]; char *gSaveGamePic[10]; unsigned int gSavedOffset = 0; @@ -101,7 +100,7 @@ void LoadSave::Write(void *pData, int nSize) ThrowError("File error #%d writing save file.", errno); } -void LoadSave::LoadGame(const char *pzFile) +bool GameInterface::LoadGame(FSaveGameNode* node) { bool demoWasPlayed = gDemo.at1; if (gDemo.at1) @@ -117,18 +116,18 @@ void LoadSave::LoadGame(const char *pzFile) memset(sprite, 0, sizeof(spritetype)*kMaxSprites); automapping = 1; } - OpenSaveGameForRead(pzFile); - hLFile = ReadSavegameChunk("snapshot.bld"); - if (!hLFile.isOpen()) - ThrowError("Error loading save file."); - LoadSave *rover = head.next; - while (rover != &head) + OpenSaveGameForRead(node->Filename); + LoadSave::hLFile = ReadSavegameChunk("snapshot.bld"); + if (!LoadSave::hLFile.isOpen()) + return false; + LoadSave *rover = LoadSave::head.next; + while (rover != &LoadSave::head) { rover->Load(); rover = rover->next; } - hLFile.Close(); + LoadSave::hLFile.Close(); FinishSavegameRead(); if (!gGameStarted) scrLoadPLUs(); @@ -182,30 +181,39 @@ void LoadSave::LoadGame(const char *pzFile) netBroadcastPlayerInfo(myconnectindex); //sndPlaySong(gGameOptions.zLevelSong, 1); + return true; } -void LoadSave::SaveGame(const char *pzFile) +bool GameInterface::SaveGame(FSaveGameNode* node) { - OpenSaveGameForWrite(pzFile); - hSFile = WriteSavegameChunk("snapshot.bld"); - if (hSFile == NULL) - ThrowError("File error #%d creating save file.", errno); - dword_27AA38 = 0; - dword_27AA40 = 0; - LoadSave *rover = head.next; - while (rover != &head) - { - rover->Save(); - if (dword_27AA38 > dword_27AA40) - dword_27AA40 = dword_27AA38; - dword_27AA38 = 0; - rover = rover->next; - } - auto & li = gEpisodeInfo[gGameOptions.nEpisode].at28[gGameOptions.nLevel]; - G_WriteSaveHeader(gGameOptions.szUserGameName, li.at0, li.at90); + OpenSaveGameForWrite(node->Filename); + LoadSave::hSFile = WriteSavegameChunk("snapshot.bld"); - FinishSavegameWrite(); - hSFile = NULL; + try + { + dword_27AA38 = 0; + dword_27AA40 = 0; + LoadSave* rover = LoadSave::head.next; + while (rover != &LoadSave::head) + { + rover->Save(); + if (dword_27AA38 > dword_27AA40) + dword_27AA40 = dword_27AA38; + dword_27AA38 = 0; + rover = rover->next; + } + } + catch (std::runtime_error & err) + { + // Let's not abort for write errors. + Printf(TEXTCOLOR_RED "%s\n", err.what()); + return false; + } + auto & li = gEpisodeInfo[gGameOptions.nEpisode].at28[gGameOptions.nLevel]; + G_WriteSaveHeader(node->SaveTitle, FStringf("%s.map", li.at0), li.at90); + LoadSave::hSFile = NULL; + + return FinishSavegameWrite(); } class MyLoadSave : public LoadSave @@ -431,41 +439,6 @@ void MyLoadSave::Save(void) void LoadSavedInfo(void) { - FString path = M_GetSavegamesPath() + "game*.sav"; - TArray saves; - D_AddWildFile(saves, path); - int nCount = 0; - for (auto & savename : saves) - { - OpenSaveGameForRead(savename); - auto hFile = ReadSavegameChunk("snapshot.bld"); - if (!hFile.isOpen()) - { - FinishSavegameRead(); - ThrowError("Error loading save file header."); - } - int vc; - short v4; - vc = 0; - v4 = word_27AA54; - if ((uint32_t)hFile.Read(&vc, sizeof(vc)) != sizeof(vc)) - { - continue; - } - if (vc != 0x5653424e/*'VSBN'*/) - { - continue; - } - hFile.Read(&v4, sizeof(v4)); - if (v4 != BYTEVERSION) - { - continue; - } - if ((uint32_t)hFile.Read(&gSaveGameOptions[nCount], sizeof(gSaveGameOptions[0])) != sizeof(gSaveGameOptions[0])) - ThrowError("Error reading save file."); - nCount++; - } - FinishSavegameRead(); } void UpdateSavedInfo(int nSlot) diff --git a/source/blood/src/loadsave.h b/source/blood/src/loadsave.h index e8d4cf00a..9dac3b0e4 100644 --- a/source/blood/src/loadsave.h +++ b/source/blood/src/loadsave.h @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include "levels.h" +struct FSavegameNode; BEGIN_BLD_NS class LoadSave { @@ -49,12 +50,11 @@ public: virtual void Load(void); void Read(void *, int); void Write(void *, int); - static void LoadGame(const char *); - static void SaveGame(const char *); + static void LoadGame(FSavegameNode *); + static void SaveGame(FSavegameNode*); }; extern unsigned int gSavedOffset; -extern GAMEOPTIONS gSaveGameOptions[]; extern char *gSaveGamePic[10]; void UpdateSavedInfo(int nSlot); void LoadSavedInfo(void); diff --git a/source/blood/src/menu.cpp b/source/blood/src/menu.cpp index ccba6f643..f37af27d3 100644 --- a/source/blood/src/menu.cpp +++ b/source/blood/src/menu.cpp @@ -2032,8 +2032,6 @@ void SaveGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event) } FStringf basename("save%04d", nSlot); auto strSaveGameName = G_BuildSaveName(basename); - strcpy(gGameOptions.szUserGameName, strRestoreGameStrings[nSlot]); - sprintf(gGameOptions.szSaveGameName, "%s", strSaveGameName.GetChars()); gGameOptions.nSaveGameSlot = nSlot; viewLoadingScreen(2518, "Saving", "Saving Your Game", strRestoreGameStrings[nSlot]); videoNextPage(); diff --git a/source/common/menu/loadsavemenu.cpp b/source/common/menu/loadsavemenu.cpp index 3c59597b5..590085281 100644 --- a/source/common/menu/loadsavemenu.cpp +++ b/source/common/menu/loadsavemenu.cpp @@ -165,7 +165,7 @@ protected: if (savegameManager.SavegameCount() > 0) { - if (Selected > savegameManager.SavegameCount()) Selected = 0; + if (Selected >= savegameManager.SavegameCount()) Selected = 0; FString text = (Selected == -1 || !savegameManager.GetSavegame(Selected)->bOldVersion) ? GStrings("MNU_NOPICTURE") : GStrings("MNU_DIFFVERSION"); int textlen = NewSmallFont->StringWidth(text) * CleanXfac; diff --git a/source/common/utility/namedef.h b/source/common/utility/namedef.h index a6b4ca075..9268362de 100644 --- a/source/common/utility/namedef.h +++ b/source/common/utility/namedef.h @@ -18,6 +18,7 @@ xx(Controlmessage) xx(MainMenu) xx(IngameMenu) +xx(MultiMenu) xx(HelpMenu) xx(CreditsMenu) xx(SaveGameMenu) From 71c2a8f33ac5af68319c76112e18ce502319a14b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 2 Dec 2019 00:16:48 +0100 Subject: [PATCH 079/203] - made the main option menu work. --- source/common/menu/menu.cpp | 1 + source/common/menu/menu.h | 1 + source/common/menu/menudef.cpp | 5 ++-- source/common/menu/optionmenu.cpp | 36 ++++++--------------------- wadsrc/static/demolition/language.csv | 20 +++++++++++++-- wadsrc/static/demolition/menudef.txt | 36 +++++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 33 deletions(-) diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 6a4b2aff9..88413202a 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -541,6 +541,7 @@ bool M_SetMenu(FName menu, int param, FName caller) FOptionMenuDescriptor *ld = static_cast(*desc); //const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DOptionMenu) : ld->mClass; + ld->CalcIndent(); DOptionMenu *newmenu = new DOptionMenu; newmenu->Init(DMenu::CurrentMenu, ld); M_ActivateMenu(newmenu); diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 32dbf4d69..b4ec67847 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -644,6 +644,7 @@ public: bool MouseEvent(int type, int x, int y); void Ticker (); void Drawer (); + virtual int GetIndent(); const FOptionMenuDescriptor *GetDescriptor() const { return mDesc; } void SetFocus(FOptionMenuItem *fc) { diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 86f2fbd75..4c88ae577 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -794,7 +794,7 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) sc.MustGetString(); desc->mClass = sc.String; } - else if (sc.Compare("Title")) + else if (sc.Compare("Title") || sc.Compare("Caption")) { sc.MustGetString(); desc->mTitle = sc.String; @@ -1025,7 +1025,6 @@ static void ParseOptionMenu(FScanner &sc) ParseOptionMenuBody(sc, desc); bool scratch = ReplaceMenu(sc, desc); - if (desc->mIndent == 0) desc->CalcIndent(); if (scratch) delete desc; } @@ -1046,7 +1045,7 @@ void M_ParseMenuDefs() OptionSettings.mFontColorMore = CR_GOLD;// = V_FindFontColor(gameinfo.mFontColorMore); OptionSettings.mFontColorHeader = CR_YELLOW;// = V_FindFontColor(gameinfo.mFontColorHeader); OptionSettings.mFontColorHighlight = CR_BRICK;// = V_FindFontColor(gameinfo.mFontColorHighlight); - OptionSettings.mFontColorSelection = CR_DARKRED;// = V_FindFontColor(gameinfo.mFontColorSelection); + OptionSettings.mFontColorSelection = CR_RED;// = V_FindFontColor(gameinfo.mFontColorSelection); DefaultListMenuSettings.Reset(); DefaultOptionMenuSettings.Reset(); diff --git a/source/common/menu/optionmenu.cpp b/source/common/menu/optionmenu.cpp index 8076f8635..946a3ea8d 100644 --- a/source/common/menu/optionmenu.cpp +++ b/source/common/menu/optionmenu.cpp @@ -212,17 +212,6 @@ bool DOptionMenu::MenuEvent (int mkey, bool fromcontroller) // Figure out how many lines of text fit on the menu int y = mDesc->mPosition; - if (y <= 0) - { - if (BigFont && mDesc->mTitle.IsNotEmpty()) - { - y = -y + BigFont->GetHeight(); - } - else - { - y = -y; - } - } y *= CleanYfac_1; int rowheight = OptionSettings.mLinespacing * CleanYfac_1; int maxitems = (screen->GetHeight() - rowheight - y) / rowheight + 1; @@ -397,6 +386,11 @@ void DOptionMenu::Ticker () // // //============================================================================= +int DOptionMenu::GetIndent() +{ + int indent = std::max(0, (mDesc->mIndent + 40) - CleanWidth_1 / 2); + return screen->GetWidth() / 2 + indent * CleanXfac_1; +} void DOptionMenu::Drawer () { @@ -410,25 +404,10 @@ void DOptionMenu::Drawer () int fontheight = OptionSettings.mLinespacing * CleanYfac_1; y *= CleanYfac_1; - int indent = mDesc->mIndent; - if (indent > 280) - { // kludge for the compatibility options with their extremely long labels - if (indent + 40 <= CleanWidth_1) - { - indent = (screen->GetWidth() - ((indent + 40) * CleanXfac_1)) / 2 + indent * CleanXfac_1; - } - else - { - indent = screen->GetWidth() - 40 * CleanXfac_1; - } - } - else - { - indent = (indent - 160) * CleanXfac_1 + screen->GetWidth() / 2; - } + int indent = GetIndent(); int ytop = y + mDesc->mScrollTop * 8 * CleanYfac_1; - int lastrow = screen->GetHeight() - SmallFont->GetHeight() * CleanYfac_1; + int lastrow = screen->GetHeight() - OptionFont()->GetHeight() * CleanYfac_1; unsigned i; for (i = 0; i < mDesc->mItems.Size() && y <= lastrow; i++, y += fontheight) @@ -498,6 +477,7 @@ bool FOptionMenuItem::MouseEvent(int type, int x, int y) return false; } + int FOptionMenuItem::GetIndent() { if (mCentered) return 0; diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index 7ccb43e91..8711b1f38 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -18,7 +18,7 @@ Select an Episode,MNU_SELECTEPISODE,DN3D et.al.,,,,"Welche Episode? ",,,,,,,,,,,,,,,,, Episodes,MNU_EPISODES,Blood,,,,Episoden,,,,,,,,,,,,,,,,, Select Skill,MNU_SELECTSKILL,DN3D et.al.,,,,Schwierigkeitsgrad,,,,,,,,,,,,,,,,, -Difficulty,MBU_DIFFICULTY,Blood,,,,Schwierigkeitsgrad,,,,,,,,,,,,,,,,, +Difficulty,MNU_DIFFICULTY,Blood,,,,Schwierigkeitsgrad,,,,,,,,,,,,,,,,, About Demolition,MNU_ENGINECREDITS,,,,,Über Demolition,,,,,,,,,,,,,,,,, Press Y or N.,PRESSYN,,,,Stiskni Y nebo N.,Drücke Y oder N.,"Πάτα Y ή N ",Premu Y aŭ N.,Presiona Y ó N.,,Paina Y tai N.,Appuyez sur Y ou N.,Nyomj Y-t vagy N-t.,Premi Y oppure N.,YかNで答えろ,Y키 또는 N키를 누르시오.,Druk op Y of N.,Wciśnij Y lub N.,Aperte Y ou N.,Carrega Y ou N.,,Нажмите Y или N.,Притисните Y или N. @@ -214,4 +214,20 @@ No files,MNU_NOFILES,,,,Žádné soubory,Keine Dateien,,Neniuj dosieroj,Sin arch ",,Haluatko varmasti poistaa tallennetun pelin ,"Voulez vous vraiment effacer cette sauvegarde? ",Biztos ki akarod törölni a mentést?,Vuoi veramente rimuovere il salvataggio,本当にこのセーブを消すのか?,저장된 게임을 정말로 삭제하시겠습니까?,Wil je echt de opgeslagen spel verwijderen?,Czy naprawdę chcesz usunąć zapis gry,"Deseja mesmo deletar o jogo salvo ",Deseja mesmo apagar o jogo,,"Вы действительно хотите удалить сохранение -",Да ли стварно желите да избришете сачувану игру \ No newline at end of file +",Да ли стварно желите да избришете сачувану игру +,,,,,,,,,,,,,,,,,,,,,,, +Options,OPTMNU_TITLE,,,,Možnosti,Optionen,,Agordoj,Opciones,,Asetukset,Options,Beállítások,Opzioni,オプション,설정,Opties,Opcje,Opções,,,Настройки,Подешавања +Customize Controls,OPTMNU_CONTROLS,,,,Nastavení ovládání,Steuerung einstellen,,Agordi Regilojn,Personalizar Controles,,Ohjausasetukset,Modifier les Contrôles,Irányítás testreszabása,Personalizza i controlli,キー配置変更,조작 사용자 지정,Instellen van de controle,Ustaw Klawisze,Configurar Controles,Configurar Controlos,,Управление,Контроле +Mouse Options,OPTMNU_MOUSE,,,,Nastavení myši,Mauseinstellungen,,Musagordoj,Opciones de Ratón,,Hiiriasetukset,Options de la Souris,Egér beállítások,Opzioni Mouse,マウス オプション,마우스 설정,Muis opties,Opcje Myszki,Opções de mouse,Opções do rato,,Мышь,Миш +Controller Options,OPTMNU_JOYSTICK,,,,Nastavení ovladače,Joystickeinstellungen,,Ludregilagordoj,Opciones de Mando,,Peliohjainasetukset,Options de la Manette,Játékvezérlő beállítások,Opzioni Joystick,コントローラーオプション,조이스틱 설정,Controller opties,Opcje Kontrolera,Opções de joystick,,,Контроллер,Контролер +Player Setup,OPTMNU_PLAYER,,,,Nastavení hráče,Spieler einrichten,,Ludanta Agordaĵo,Config. del Jugador,,Pelaaja-asetukset,Options du Joueur,Játékos testreszabása,Settaggio giocatore,プレイヤーの特徴,플레이어 설정,Speler instellen,Ustawienia Gracza,Configurações de Jogador,Configurações do Jogador,,Игрок,Играч +Gameplay Options,OPTMNU_GAMEPLAY,,,,Nastavení herních mechanik,Spieleinstellungen,,Ludadagordoj,Opciones de Jugabilidad,,Pelattavuusasetukset,Options du Gameplay,Játék mechanika,Opzioni Gameplay,ゲームプレイ オプション,게임 설정,Gameplay-opties,Opcje Rozgrywki,Opções de jogabilidade,,,Геймплей,Гејмплеј +Automap Options,OPTMNU_AUTOMAP,,,,Nastavení automapy,Automapeinstellungen,,Aŭtomapagordoj,Opciones del Automapa,,Automaattikartan asetukset,Options de la Carte,Térkép beállítások,Opzioni Automappa,オートマップ オプション,오토맵 설정,Automap-opties,Opcje Mapy,Opções de automapa,,,Автокарта,Аутомапа +HUD Options,OPTMNU_HUD,,,,Nastavení HUD,HUD Einstellungen,,Agordoj de HUD,Opciones del HUD,,Tilanäytön asetukset,Options de l'ATH,HUD beállítások,Opzioni HUD,HUD オプション,HUD 설정,HUD opties,Opcje Paska HUD,Opções de HUD,,,HUD,HUD +Miscellaneous Options,OPTMNU_MISCELLANEOUS,,,,Ostatní nastavení,Verschiedene Einstellungen,,Ekstraĵagordoj,Opciones Misceláneas,,Sekalaiset asetukset,Options Annexes,Általános beállítások,Opzioni miste,その他のオプション,그 외 설정,Diverse opties,Różne Opcje,Outras opções,,,Дополнительно,Разно +Sound Options,OPTMNU_SOUND,,,,Nastavení zvuku,Soundeinstellungen,,Sonagordoj,Opciones de Sonido,,Ääniasetukset,Options du Son,Hang beállítások,Opzioni Suono,サウンド オプション,음향 설정,Geluidsopties,Opcje Dźwięku,Opções de som,,,Звук,Звук +Display Options,OPTMNU_DISPLAY,,,,Nastavení grafiky,Anzeigeeinstellungen,,Ekranagordoj,Opciones de Visualización,,Näyttöasetukset,Options de l'Affichage,Megjelenítés beállítások,Opzioni Display,ディスプレイ オプション,디스플레이 설정,Weergaveopties,Opcje Wyświetlania,Opções de vídeo,,,Экран,Приказ +Set video mode,OPTMNU_VIDEO,,,,Nastavit režim displeje,Videomodus,,Agordi videoreĝimon,Modos de Vídeo,,Aseta videotila,Choisir Mode D'Affichage,Felbontás,Settaggio modalità video,ビデオ 調整,화면 설정,Videomodus instellen,Ustaw tryb wideo,Definir modo de vídeo,,,Видеорежим,Видео мод +Reset to defaults,OPTMNU_DEFAULTS,,,,Obnovit původní,Auf Vorgaben zurücksetzen,,Reŝanĝi al defaŭltoj,Valores por Defecto,,Palauta oletusasetukset,Réinitialiser les paramètres,Alapértelmezett beállítások használata,Reimposta ai valori di default,初期設定に戻す,초기화,Terugzetten naar standaardinstellingen,Resetuj do domyślnych,Redefinir para configurações padrão,,,Сбросить все настройки,Врати подразумевано +Reset to last saved,OPTMNU_RESETTOSAVED,,,,Obnovit naposledy uložené,Auf gespeicherte Werte zurücksetzen,,Reŝanĝi al lasta konservo,Últimos Valores Guardados,,Palauta viimeksi tallennettu tila,Recharger dernière config.,Legutóbbi mentett beállítások használata,Reimposta ai valori salvati l'ultima volta,最後に保存した設定に戻す,이전 설정으로 초기화,Reset naar laatste opgeslagen,Resetuj do ostatnio zapisanych,Redefinir para última configuração salva,Redefinir para última configuração gravada,,Вернуть предыдущие настройки,Врати задње сачувано +Go to console,OPTMNU_CONSOLE,,,,Jít do konzole,Öffne Konsole,,Iri al konzolo,Ir a la consola,,Mene konsoliin,Ouvrir la console,Konzol megnyitása,Vai alla console,コンソールを開く,콘솔로 이동,Ga naar de console,Przejdź do konsoli,Abrir console,Abrir consola,,Открыть консоль,Отвори конзолу \ No newline at end of file diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 825992f80..841f2fa7d 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -575,3 +575,39 @@ ListMenu "SaveGameMenu" Class "SaveMenu" // uses its own implementation } +//------------------------------------------------------------------------------------------- +// +// The generic options menus start here +// +//------------------------------------------------------------------------------------------- + +OptionMenuSettings +{ + Linespacing 17 + // todo: implement color themes that fit the games +} + +DefaultOptionMenu +{ + Position 85 +} + +OptionMenu "OptionsMenu" +{ + Caption "$MNU_OPTIONS" + Submenu "$OPTMNU_CONTROLS", "CustomizeControls" + Submenu "$OPTMNU_MOUSE", "MouseOptions" + Submenu "$OPTMNU_JOYSTICK", "JoystickOptions" + StaticText " " + Submenu "$OPTMNU_PLAYER", "NewPlayerMenu" + Submenu "$OPTMNU_SOUND", "SoundOptions" + Submenu "$OPTMNU_DISPLAY", "VideoOptions" + Submenu "$OPTMNU_VIDEO", "VideoModeMenu" + Submenu "$OPTMNU_GAMEPLAY", "GameplayOptions" + Submenu "$OPTMNU_MISCELLANEOUS", "MiscOptions" + StaticText " " + SafeCommand "$OPTMNU_DEFAULTS", "reset2defaults" + SafeCommand "$OPTMNU_RESETTOSAVED", "reset2saved" + Command "$OPTMNU_CONSOLE", "menuconsole" +} + From 36cf2583e49c2e9674e1f6e513f91ec8dc30dd3d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 2 Dec 2019 00:19:35 +0100 Subject: [PATCH 080/203] - removed some dead code. --- source/blood/src/osdcmd.cpp | 63 ---------------------------- source/duke3d/src/osdcmds.cpp | 78 ----------------------------------- 2 files changed, 141 deletions(-) diff --git a/source/blood/src/osdcmd.cpp b/source/blood/src/osdcmd.cpp index e5f253d0c..c1ecb4715 100644 --- a/source/blood/src/osdcmd.cpp +++ b/source/blood/src/osdcmd.cpp @@ -332,36 +332,7 @@ static int osdcmd_restartsound(osdcmdptr_t UNUSED(parm)) void onvideomodechange(int32_t newmode) { UNREFERENCED_PARAMETER(newmode); -#if 0 - uint8_t palid; - // XXX? - if (!newmode || g_player[screenpeek].ps->palette < BASEPALCOUNT) - palid = g_player[screenpeek].ps->palette; - else - palid = BASEPAL; - -#ifdef POLYMER - if (videoGetRenderMode() == REND_POLYMER) - { - int32_t i = 0; - - while (i < MAXSPRITES) - { - if (actor[i].lightptr) - { - polymer_deletelight(actor[i].lightId); - actor[i].lightptr = NULL; - actor[i].lightId = -1; - } - i++; - } - } -#endif - - videoSetPalette(0, palid, 0); - g_restorePalette = -1; -#endif if (newmode) scrResetPalette(); UpdateDacs(gLastPal, false); @@ -369,40 +340,6 @@ void onvideomodechange(int32_t newmode) -#if 0 -static int osdcmd_savestate(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_PARAMETER(parm); - G_SaveMapState(); - return OSDCMD_OK; -} - -static int osdcmd_restorestate(osdcmdptr_t UNUSED(parm)) -{ - UNREFERENCED_PARAMETER(parm); - G_RestoreMapState(); - return OSDCMD_OK; -} -#endif - -#if 0 -#ifdef DEBUGGINGAIDS -static int osdcmd_inittimer(osdcmdptr_t parm) -{ - if (parm->numparms != 1) - { - OSD_Printf("%dHz timer\n",g_timerTicsPerSecond); - return OSDCMD_SHOWHELP; - } - - G_InitTimer(Batol(parm->parms[0])); - - OSD_Printf("%s\n",parm->raw); - return OSDCMD_OK; -} -#endif -#endif - int32_t registerosdcommands(void) { OSD_RegisterFunction("changelevel","changelevel : warps to the given level", osdcmd_changelevel); diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index 3e9d94c77..2505b2ca2 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -79,42 +79,6 @@ static int osdcmd_changelevel(osdcmdptr_t parm) if (numplayers > 1) { - /* - if (g_netServer) - Net_NewGame(volume,level); - else if (voting == -1) - { - ud.m_volume_number = volume; - m_level_number = level; - - if (g_player[myconnectindex].ps->i) - { - int32_t i; - - for (i=0; igm & MODE_GAME) @@ -172,48 +136,6 @@ static int osdcmd_map(osdcmdptr_t parm) if (numplayers > 1) { - /* - if (g_netServer) - { - Net_SendUserMapName(); - ud.m_volume_number = 0; - m_level_number = 7; - Net_NewGame(ud.m_volume_number, m_level_number); - } - else if (voting == -1) - { - Net_SendUserMapName(); - - ud.m_volume_number = 0; - m_level_number = 7; - - if (g_player[myconnectindex].ps->i) - { - int32_t i; - - for (i=0; i Date: Mon, 2 Dec 2019 00:43:33 +0100 Subject: [PATCH 081/203] - added control menu contents --- wadsrc/static/demolition/menudef.txt | 262 +++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 841f2fa7d..ede0749d1 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -581,6 +581,37 @@ ListMenu "SaveGameMenu" // //------------------------------------------------------------------------------------------- +OptionValue "YesNo" +{ + 0, "$TXT_NO" + 1, "$TXT_YES" +} + +OptionValue "NoYes" +{ + 0, "$TXT_YES" + 1, "$TXT_NO" +} + +OptionValue "OnOff" +{ + 0, "$OPTVAL_OFF" + 1, "$OPTVAL_ON" +} + +OptionValue "OffOn" +{ + 0, "$OPTVAL_ON" + 1, "$OPTVAL_OFF" +} + +OptionValue AutoOffOn +{ + -1, "$OPTVAL_AUTO" + 0, "$OPTVAL_OFF" + 1, "$OPTVAL_ON" +} + OptionMenuSettings { Linespacing 17 @@ -611,3 +642,234 @@ OptionMenu "OptionsMenu" Command "$OPTMNU_CONSOLE", "menuconsole" } +//------------------------------------------------------------------------------------------- +// +// Controls Menu +// +//------------------------------------------------------------------------------------------- + +OptionMenu "CustomizeControls" protected +{ + Title "$CNTRLMNU_TITLE" + + Submenu "$CNTRLMNU_ACTION" , "ActionControlsMenu" + Submenu "$CNTRLMNU_CHAT" , "ChatControlsMenu" + Submenu "$CNTRLMNU_WEAPONS" , "WeaponsControlMenu" + Submenu "$CNTRLMNU_INVENTORY" , "InventoryControlsMenu" + Submenu "$CNTRLMNU_OTHER" , "OtherControlsMenu" + //Submenu "$MAPCNTRLMNU_CONTROLS" , "MapControlsMenu" // todo after thorough cleanup +} + +OptionMenu "ActionControlsMenu" protected +{ + Title "$CNTRLMNU_ACTION_TITLE" + ScrollTop 2 + StaticTextSwitchable "$CNTRLMNU_SWITCHTEXT1", "$CNTRLMNU_SWITCHTEXT2", "ControlMessage" + + StaticText "" + Control "$CNTRLMNU_ATTACK" , "+fire" + ifgame(Blood, Duke, Nam, WW2GI, Fury) + { + Control "$CNTRLMNU_ALTATTACK" , "+alt_fire" + } + ifgame(Duke, Nam, WW2GI, Fury, ShadowWarrior) + { + Control "$CNTRLMNU_ALTWEAPON" , "+alt_weapon" + } + + StaticText "" + Control "$CNTRLMNU_USE" , "+open" + + StaticText "" + Control "$CNTRLMNU_FORWARD" , "+move_forward" + Control "$CNTRLMNU_BACK" , "+move_backward" + Control "$CNTRLMNU_MOVELEFT" , "+strafe_left" + Control "$CNTRLMNU_MOVERIGHT" , "+strafe_right" + + StaticText "" + Control "$CNTRLMNU_TURNLEFT" , "+turn_left" + Control "$CNTRLMNU_TURNRIGHT" , "+turn_right" + Control "$CNTRLMNU_TURN180" , "+turn_around" + + StaticText "" + Control "$CNTRLMNU_JUMP" , "+jump" + Control "$CNTRLMNU_CROUCH" , "+crouch" + ifgame(Duke, Nam, WW2GI, Fury, Redneck, RedneckRides) + { + // Fixme: Make this work in all games + Control "$CNTRLMNU_TOGGLECROUCH" , "+toggle_crouch" + } + + StaticText "" + Control "$CNTRLMNU_MOUSELOOK" , "+mouse_aiming" + Control "$CNTRLMNU_LOOKUP" , "+look_up" + Control "$CNTRLMNU_LOOKDOWN" , "+look_down" + Control "$CNTRLMNU_CENTERVIEW" , "+center_view" + + StaticText "" + Control "$CNTRLMNU_RUN" , "+run" + Control "$CNTRLMNU_TOGGLERUN" , "toggle cl_autorun" + Control "$CNTRLMNU_STRAFE" , "+strafe" + + StaticText "" + Control "$CNTRLMNU_SCOREBOARD" , "+show_dukematch_scores" +} + +OptionMenu "ChatControlsMenu" protected +{ + Title "$CNTRLMNU_CHAT_TITLE" + ScrollTop 2 + StaticTextSwitchable "$CNTRLMNU_SWITCHTEXT1", "$CNTRLMNU_SWITCHTEXT2", "ControlMessage" + + StaticText "" + Control "$CNTRLMNU_SAY" , "+send_message" +} + +OptionMenu "WeaponsControlMenu" protected +{ + Title "$CNTRLMNU_WEAPONS_TITLE" + ScrollTop 2 + StaticTextSwitchable "$CNTRLMNU_SWITCHTEXT1", "$CNTRLMNU_SWITCHTEXT2", "ControlMessage" + + StaticText "" + Control "$CNTRLMNU_NEXTWEAPON" , "+nexct_weapon" + Control "$CNTRLMNU_PREVIOUSWEAPON" , "+previous_weapon" + + StaticText "" + Control "$CNTRLMNU_SLOT1" , "+weapon_1" + Control "$CNTRLMNU_SLOT2" , "+weapon_2" + Control "$CNTRLMNU_SLOT3" , "+weapon_3" + Control "$CNTRLMNU_SLOT4" , "+weapon_4" + Control "$CNTRLMNU_SLOT5" , "+weapon_5" + Control "$CNTRLMNU_SLOT6" , "+weapon_6" + Control "$CNTRLMNU_SLOT7" , "+weapon_7" + Control "$CNTRLMNU_SLOT8" , "+weapon_8" + Control "$CNTRLMNU_SLOT9" , "+weapon_9" + Control "$CNTRLMNU_SLOT0" , "+weapon_10" + StaticText "" + Control "$CNTRLMNU_HOLSTER" , "+holster_weapon" + ifgame(Duke, Nam, WW2GI, Fury) + { + Control "$CNTRLMNU_QUICKKICK" , "+quick_kick" + } + ifgame(Redneck, RedneckRides) + { + Control "$CNTRLMNU_PEE" , "+quick_kick" + } + ifgame(Blood) + { + Control "$CNTRLMNU_PROXIMITYBOMBS","+proximitybombs" + Control "$CNTRLMNU_REMOTEBOMBS" ,"+remotebombs" + } + ifgame(ShadowWarrior) + { + Control "$CNTRLMNU_SMOKEBOMB","+smoke_bomb" + Control "$CNTRLMNU_GASBOMB" ,"+gas_bomb" + Control "$CNTRLMNU_FLASHBOMB","+flash_bomb" + Control "$CNTRLMNU_CALTROPS" ,"+caltrops" + } + +} + +OptionMenu "InventoryControlsMenu" protected +{ + Title "$CNTRLMNU_INVENTORY_TITLE" + ScrollTop 2 + StaticTextSwitchable "$CNTRLMNU_SWITCHTEXT1", "$CNTRLMNU_SWITCHTEXT2", "ControlMessage" + + StaticText "" + Control "$CNTRLMNU_USEITEM" , "+inventory" + + StaticText "" + Control "$CNTRLMNU_NEXTITEM" , "+inventory_next" + Control "$CNTRLMNU_PREVIOUSITEM" , "+inventory_prev" + + ifgame(Duke) + { + StaticText "" + Control "$CNTRLMNU_HOLODUKE" , "+holo_duke" + Control "$CNTRLMNU_JETPACK" , "+jetpack" + Control "$CNTRLMNU_NIGHTVISION" , "+nightvision" + Control "$CNTRLMNU_MEDKIT" , "+medkit" + Control "$CNTRLMNU_STEROIDS" , "+steroids" + } + ifgame(Nam) + { + StaticText "" + Control "$CNTRLMNU_HOLOSOLDIER" , "+holo_duke" + Control "$CNTRLMNU_HUEY" , "+jetpack" + Control "$CNTRLMNU_NIGHTVISION" , "+nightvision" + Control "$CNTRLMNU_MEDKIT" , "+medkit" + Control "$CNTRLMNU_TANKMODE" , "+steroids" + } + ifgame(WW2GI) + { + StaticText "" + Control "$CNTRLMNU_FIRE MISSION" , "+holo_duke" + Control "$CNTRLMNU_NIGHTVISION" , "+nightvision" + Control "$CNTRLMNU_MEDKIT" , "+medkit" + Control "$CNTRLMNU_SMOKES" , "+steroids" + } + ifgame(Redneck, RedneckRides) + { + StaticText "" + Control "$CNTRLMNU_BEER" , "+holo_duke" + Control "$CNTRLMNU_COWPIE" , "+jetpack" + Control "$CNTRLMNU_YEEHAA" , "+nightvision" + Control "$CNTRLMNU_WHISKEY" , "+medkit" + Control "$CNTRLMNU_MOONSHINE" , "+steroids" + } + ifgame(Blood) + { + StaticText "" + Control "$CNTRLMNU_CRYSTALBALL" , "+crystalball" + Control "$CNTRLMNU_JUMPBOOTS" , "+jetpack" + Control "$CNTRLMNU_BEASTVISION" , "+nightvision" + Control "$CNTRLMNU_MEDKIT" , "+medkit" + } + ifgame(ShadowWarrior) + { + StaticText "" + Control "$CNTRLMNU_NIGHTVISION" , "+nightvision" + Control "$CNTRLMNU_MEDKIT" , "+medkit" + } + + +OptionMenu "OtherControlsMenu" protected +{ + Title "$CNTRLMNU_OTHER_TITLE" + ScrollTop 2 + StaticTextSwitchable "$CNTRLMNU_SWITCHTEXT1", "$CNTRLMNU_SWITCHTEXT2", "ControlMessage" + + StaticText "" + Control "$CNTRLMNU_AUTOMAP" , "+map" + Control "$MAPCNTRLMNU_TOGGLEFOLLOW","+map_follow_mode" + + StaticText "" + Control "$CNTRLMNU_CHASECAM" , "+third_person_view" + + StaticText "" + Control "$CNTRLMNU_SCREENSHOT" , "screenshot" + Control "$CNTRLMNU_CONSOLE" , "toggleconsole" + Control "$CNTRLMNU_PAUSE" , "pause" + + StaticText "" + Control "$CNTRLMNU_DISPLAY_INC" , "sizeup" + Control "$CNTRLMNU_DISPLAY_DEC" , "sizedown" + Control "$CNTRLMNU_TOGGLE_MESSAGES" , "togglemessages" + Control "$CNTRLMNU_ADJUST_GAMMA" , "bumpgamma" + + StaticText "" + Control "$CNTRLMNU_OPEN_HELP" , "menu_help" + Control "$CNTRLMNU_OPEN_SAVE" , "menu_save" + Control "$CNTRLMNU_OPEN_LOAD" , "menu_load" + Control "$CNTRLMNU_OPEN_OPTIONS" , "menu_options" + Control "$CNTRLMNU_OPEN_DISPLAY" , "menu_display" + Control "$CNTRLMNU_EXIT_TO_MAIN" , "menu_endgame" + Control "$CNTRLMNU_MENU_QUIT" , "menu_quit" + + StaticText "" + Control "$CNTRLMNU_QUICKSAVE" , "quicksave" + Control "$CNTRLMNU_QUICKLOAD" , "quickload" +} + From 00b2467eeae2d185d4c84cb39de69a390dcbf5cc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 2 Dec 2019 02:07:32 +0100 Subject: [PATCH 082/203] - WIP keybinding cleanup --- source/CMakeLists.txt | 2 +- source/blood/src/menu.cpp | 43 ---- source/blood/src/messages.cpp | 62 ------ source/common/console/c_bind.cpp | 213 ++++++++++++++++++++ source/common/console/c_bind.h | 9 + source/common/console/c_buttons.cpp | 293 ++++++---------------------- source/common/console/c_buttons.h | 21 +- source/common/gamecontrol.cpp | 232 +--------------------- source/common/gamecontrol.h | 15 -- source/duke3d/src/gamedef.cpp | 16 +- source/duke3d/src/gameexec.cpp | 5 +- source/rr/src/gamedef.cpp | 12 +- 12 files changed, 315 insertions(+), 608 deletions(-) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 7d9fa2135..844597972 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -860,7 +860,7 @@ add_executable( demolition WIN32 MACOSX_BUNDLE #zzautozend.cpp ) -set_source_files_properties( ${FASTMATH_SOURCES} PROPERTIES COMPILE_FLAGS ${DEM_FASTMATH_FLAG} ) +#set_source_files_properties( ${FASTMATH_SOURCES} PROPERTIES COMPILE_FLAGS ${DEM_FASTMATH_FLAG} ) set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" ) set_source_files_properties( utility/sc_man.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h" ) set_source_files_properties( ${NOT_COMPILED_SOURCE_FILES} PROPERTIES HEADER_FILE_ONLY TRUE ) diff --git a/source/blood/src/menu.cpp b/source/blood/src/menu.cpp index f37af27d3..7bfad8f96 100644 --- a/source/blood/src/menu.cpp +++ b/source/blood/src/menu.cpp @@ -1874,54 +1874,11 @@ void SetMouseYScale(CGameMenuItemSlider *pItem) void SetMouseDigitalAxis(CGameMenuItemZCycle *pItem) { -#if 0 - if (pItem == &itemOptionsControlMouseDigitalUp) - { - MouseDigitalFunctions[1][0] = nGamefuncsValues[pItem->m_nFocus]; - CONTROL_MapDigitalAxis(1, MouseDigitalFunctions[1][0], 0, controldevice_mouse); - } - else if (pItem == &itemOptionsControlMouseDigitalDown) - { - MouseDigitalFunctions[1][1] = nGamefuncsValues[pItem->m_nFocus]; - CONTROL_MapDigitalAxis(1, MouseDigitalFunctions[1][1], 1, controldevice_mouse); - } - else if (pItem == &itemOptionsControlMouseDigitalLeft) - { - MouseDigitalFunctions[0][0] = nGamefuncsValues[pItem->m_nFocus]; - CONTROL_MapDigitalAxis(0, MouseDigitalFunctions[0][0], 0, controldevice_mouse); - } - else if (pItem == &itemOptionsControlMouseDigitalRight) - { - MouseDigitalFunctions[0][1] = nGamefuncsValues[pItem->m_nFocus]; - CONTROL_MapDigitalAxis(0, MouseDigitalFunctions[0][1], 1, controldevice_mouse); - } -#endif } void SetupMouseMenu(CGameMenuItemChain *pItem) { UNREFERENCED_PARAMETER(pItem); -#if 0 - static CGameMenuItemZCycle *pMouseDigitalAxis[4] = { - &itemOptionsControlMouseDigitalLeft, - &itemOptionsControlMouseDigitalRight, - &itemOptionsControlMouseDigitalUp, - &itemOptionsControlMouseDigitalDown - }; - for (int i = 0; i < ARRAY_SSIZE(pMouseDigitalAxis); i++) - { - CGameMenuItemZCycle *pItem = pMouseDigitalAxis[i]; - pItem->m_nFocus = 0; - for (int j = 0; j < NUMGAMEFUNCTIONS+1; j++) - { - if (nGamefuncsValues[j] == MouseDigitalFunctions[i>>1][i&1]) - { - pItem->m_nFocus = j; - break; - } - } - } -#endif itemOptionsControlMouseAimFlipped.at20 = in_mouseflip; itemOptionsControlMouseFilterInput.at20 = in_mousesmoothing; itemOptionsControlMouseAimMode.at20 = in_aimmode; diff --git a/source/blood/src/messages.cpp b/source/blood/src/messages.cpp index 6993247c5..0ceafed93 100644 --- a/source/blood/src/messages.cpp +++ b/source/blood/src/messages.cpp @@ -53,16 +53,6 @@ void sub_5A928(void) buttonMap.ClearButton(i); } -void sub_5A944(int key) -{ - auto binding = Bindings.GetBind(key); - if (binding) - { - auto index = buttonMap.FindButtonIndex(binding); - if (index >= 0) buttonMap.ClearButton(index); - } -} - void SetGodMode(bool god) { playerSetGodMode(gMe, god); @@ -590,58 +580,6 @@ void CPlayerMsg::Send(void) void CPlayerMsg::ProcessKeys(void) { if (inputState.GetKeyStatus(sc_Escape)) Term(); -#if 0 - int key = inputState.keyGetScan(); - int ch; - if (key != 0) - { - bool ctrl = (inputState.CtrlPressed()); - bool shift = (inputState.ShiftPressed()); - switch (key) - { - case sc_Escape: - Term(); - break; - case sc_F1: - case sc_F2: - case sc_F3: - case sc_F4: - case sc_F5: - case sc_F6: - case sc_F7: - case sc_F8: - case sc_F9: - case sc_F10: - buttonMap.ClearButton(gamefunc_See_Chase_View); - Set(*CombatMacros[key-sc_F1]); - Send(); - inputState.ClearKeyStatus(key); - break; - case sc_BackSpace: - if (ctrl) - Clear(); - else - DelChar(); - break; - case sc_Enter: - case sc_kpad_Enter: - if (gCheatMgr.Check(text)) - Term(); - else - Send(); - break; - default: - if (key < 128) - { - ch = shift ? g_keyAsciiTableShift[key] : g_keyAsciiTable[key]; - if (ch) - AddChar(ch); - } - break; - } - sub_5A944(key); - } -#endif } bool CPlayerMsg::IsWhitespaceOnly(const char * const pzString) diff --git a/source/common/console/c_bind.cpp b/source/common/console/c_bind.cpp index bae950673..bdee36e85 100644 --- a/source/common/console/c_bind.cpp +++ b/source/common/console/c_bind.cpp @@ -808,3 +808,216 @@ bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds) } return false; } + +// Todo: Move to a separate file. +//============================================================================= +// +// Interface for CON scripts to get descriptions for actions +// This code can query the 64 original game functions by index. +// +//============================================================================= + +static GameFuncDesc con_gamefuncs[] = { +{"+Move_Forward", "Move_Forward"}, +{"+Move_Backward", "Move_Backward"}, +{"+Turn_Left", "Turn_Left"}, +{"+Turn_Right", "Turn_Right"}, +{"+Strafe", "Strafe"}, +{"+Fire", "Fire"}, +{"+Open", "Open"}, +{"+Run", "Run"}, +{"+Alt_Fire", "Alt_Fire"}, +{"+Jump", "Jump"}, +{"+Crouch", "Crouch"}, +{"+Look_Up", "Look_Up"}, +{"+Look_Down", "Look_Down"}, +{"+Look_Left", "Look_Left"}, +{"+Look_Right", "Look_Right"}, +{"+Strafe_Left", "Strafe_Left"}, +{"+Strafe_Right", "Strafe_Right"}, +{"+Aim_Up", "Aim_Up"}, +{"+Aim_Down", "Aim_Down"}, +{"+Weapon_1", "Weapon_1"}, +{"+Weapon_2", "Weapon_2"}, +{"+Weapon_3", "Weapon_3"}, +{"+Weapon_4", "Weapon_4"}, +{"+Weapon_5", "Weapon_5"}, +{"+Weapon_6", "Weapon_6"}, +{"+Weapon_7", "Weapon_7"}, +{"+Weapon_8", "Weapon_8"}, +{"+Weapon_9", "Weapon_9"}, +{"+Weapon_10", "Weapon_10"}, +{"+Inventory", "Inventory"}, +{"+Inventory_Left", "Inventory_Left"}, +{"+Inventory_Right", "Inventory_Right"}, +{"+Holo_Duke", "Holo_Duke"}, +{"+Jetpack", "Jetpack"}, +{"+NightVision", "NightVision"}, +{"+MedKit", "MedKit"}, +{"+TurnAround", "TurnAround"}, +{"+SendMessage", "SendMessage"}, +{"+Map", "Map"}, +{"+Shrink_Screen", "Shrink_Screen"}, +{"+Enlarge_Screen", "Enlarge_Screen"}, +{"+Center_View", "Center_View"}, +{"+Holster_Weapon", "Holster_Weapon"}, +{"+Show_Opponents_Weapon", "Show_Opponents_Weapon"}, +{"+Map_Follow_Mode", "Map_Follow_Mode"}, +{"+See_Coop_View", "See_Coop_View"}, +{"+Mouse_Aiming", "Mouse_Aiming"}, +{"+Toggle_Crosshair", "Toggle_Crosshair"}, +{"+Steroids", "Steroids"}, +{"+Quick_Kick", "Quick_Kick"}, +{"+Next_Weapon", "Next_Weapon"}, +{"+Previous_Weapon", "Previous_Weapon"}, +{"+Show_Console", "Show_Console"}, +{"+Show_DukeMatch_Scores", "Show_Scoreboard"}, +{"+Dpad_Select", "Dpad_Select"}, +{"+Dpad_Aiming", "Dpad_Aiming"}, +{"+AutoRun", "AutoRun"}, +{"+Last_Used_Weapon", "Last_Used_Weapon"}, +{"+Quick_Save", "Quick_Save"}, +{"+Quick_Load", "Quick_Load"}, +{"+Alt_Weapon", "Alt_Weapon"}, +{"+Third_Person_View", "Third_Person_View"}, +{"+Toggle_Crouch", "Toggle_Crouch"} +}; + +//============================================================================= +// +// +// +//============================================================================= + +void C_CON_SetAliases() +{ + if (g_gameType & GAMEFLAG_NAM) + { + con_gamefuncs[32].description = "Holo_Soldier"; + con_gamefuncs[33].description = "Huey"; + con_gamefuncs[48].description = "Tank_Mode"; + } + if (g_gameType & GAMEFLAG_WW2GI) + { + con_gamefuncs[32].description = "Fire_Mission"; + con_gamefuncs[33].description = ""; + con_gamefuncs[48].description = "Smokes"; + } + +} + +static FString C_CON_GetGameFuncOnKeyboard(int gameFunc) +{ + if (gameFunc >= 0 && gameFunc < countof(con_gamefuncs)) + { + auto keys = Bindings.GetKeysForCommand(con_gamefuncs[gameFunc].action); + for (auto key : keys) + { + if (key < KEY_FIRSTMOUSEBUTTON) + { + auto scan = KB_ScanCodeToString(key); + if (scan) return scan; + } + } + } + return ""; +} + +static FString C_CON_GetGameFuncOnMouse(int gameFunc) +{ + if (gameFunc >= 0 && gameFunc < countof(con_gamefuncs)) + { + auto keys = Bindings.GetKeysForCommand(con_gamefuncs[gameFunc].action); + for (auto key : keys) + { + if ((key >= KEY_FIRSTMOUSEBUTTON && key < KEY_FIRSTJOYBUTTON) || (key >= KEY_MWHEELUP && key <= KEY_MWHEELLEFT)) + { + auto scan = KB_ScanCodeToString(key); + if (scan) return scan; + } + } + } + return ""; +} + +char const* C_CON_GetGameFuncOnJoystick(int gameFunc) +{ + if (gameFunc >= 0 && gameFunc < countof(con_gamefuncs)) + { + auto keys = Bindings.GetKeysForCommand(con_gamefuncs[gameFunc].action); + for (auto key : keys) + { + if (key >= KEY_FIRSTJOYBUTTON && !(key >= KEY_MWHEELUP && key <= KEY_MWHEELLEFT)) + { + auto scan = KB_ScanCodeToString(key); + if (scan) return scan; + } + } + } + return ""; +} + +FString C_CON_GetBoundKeyForLastInput(int gameFunc) +{ + if (CONTROL_LastSeenInput == LastSeenInput::Joystick) + { + FString name = C_CON_GetGameFuncOnJoystick(gameFunc); + if (name.IsNotEmpty()) + { + return name; + } + } + + FString name = C_CON_GetGameFuncOnKeyboard(gameFunc); + if (name.IsNotEmpty()) + { + return name; + } + + name = C_CON_GetGameFuncOnMouse(gameFunc); + if (name.IsNotEmpty()) + { + return name; + } + + name = C_CON_GetGameFuncOnJoystick(gameFunc); + if (name.IsNotEmpty()) + { + return name; + } + return "UNBOUND"; +} + + +//============================================================================= +// +// +// +//============================================================================= + +void C_CON_SetButtonAlias(int num, const char *text) +{ + if (num >= 0 && num < countof(con_gamefuncs)) + { + if (con_gamefuncs[num].replaced) free((void*)con_gamefuncs[num].description); + con_gamefuncs[num].description = strdup(text); + con_gamefuncs[num].replaced = true; + } +} + +//============================================================================= +// +// +// +//============================================================================= + +void C_CON_ClearButtonAlias(int num) +{ + if (num >= 0 && num < countof(con_gamefuncs)) + { + if (con_gamefuncs[num].replaced) free((void*)con_gamefuncs[num].description); + con_gamefuncs[num].description = ""; + con_gamefuncs[num].replaced = false; + } +} + diff --git a/source/common/console/c_bind.h b/source/common/console/c_bind.h index 11f5bd6d7..babfcd5c5 100644 --- a/source/common/console/c_bind.h +++ b/source/common/console/c_bind.h @@ -116,4 +116,13 @@ struct FKeySection }; extern TArray KeySections; +struct GameFuncDesc +{ + const char *action; + const char *description; + bool replaced; +}; #endif //__C_BINDINGS_H__ + + + diff --git a/source/common/console/c_buttons.cpp b/source/common/console/c_buttons.cpp index cf2c2ba67..bbfdab768 100644 --- a/source/common/console/c_buttons.cpp +++ b/source/common/console/c_buttons.cpp @@ -48,168 +48,73 @@ struct ButtonDesc }; static const ButtonDesc gamefuncs[] = { - { gamefunc_Move_Forward, "Move_Forward"}, - { gamefunc_Move_Backward, "Move_Backward"}, - { gamefunc_Turn_Left, "Turn_Left"}, - { gamefunc_Turn_Right, "Turn_Right"}, - { gamefunc_Strafe, "Strafe"}, - { gamefunc_Fire, "Fire"}, - { gamefunc_Open, "Open"}, - { gamefunc_Run, "Run"}, - { gamefunc_Alt_Fire, "Alt_Fire"}, - { gamefunc_Jump, "Jump"}, - { gamefunc_Crouch, "Crouch"}, - { gamefunc_Look_Up, "Look_Up"}, - { gamefunc_Look_Down, "Look_Down"}, + { gamefunc_Move_Forward, "Move_Forward"}, + { gamefunc_Move_Backward, "Move_Backward"}, + { gamefunc_Turn_Left, "Turn_Left"}, + { gamefunc_Turn_Right, "Turn_Right"}, + { gamefunc_Strafe, "Strafe"}, + { gamefunc_Fire, "Fire"}, + { gamefunc_Open, "Open"}, + { gamefunc_Run, "Run"}, + { gamefunc_Alt_Fire, "Alt_Fire"}, + { gamefunc_Jump, "Jump"}, + { gamefunc_Crouch, "Crouch"}, + { gamefunc_Look_Up, "Look_Up"}, + { gamefunc_Look_Down, "Look_Down"}, { gamefunc_Look_Left, "Look_Left"}, { gamefunc_Look_Right, "Look_Right"}, - { gamefunc_Strafe_Left, "Strafe_Left"}, - { gamefunc_Strafe_Right, "Strafe_Right"}, + { gamefunc_Strafe_Left, "Strafe_Left"}, + { gamefunc_Strafe_Right, "Strafe_Right"}, { gamefunc_Aim_Up, "Aim_Up"}, { gamefunc_Aim_Down, "Aim_Down"}, - { gamefunc_Weapon_1, "Weapon_1"}, - { gamefunc_Weapon_2, "Weapon_2"}, - { gamefunc_Weapon_3, "Weapon_3"}, - { gamefunc_Weapon_4, "Weapon_4"}, - { gamefunc_Weapon_5, "Weapon_5"}, - { gamefunc_Weapon_6, "Weapon_6"}, - { gamefunc_Weapon_7, "Weapon_7"}, - { gamefunc_Weapon_8, "Weapon_8"}, - { gamefunc_Weapon_9, "Weapon_9"}, - { gamefunc_Weapon_10, "Weapon_10"}, - { gamefunc_Inventory, "Inventory"}, - { gamefunc_Inventory_Left, "Inventory_Left"}, - { gamefunc_Inventory_Right, "Inventory_Right"}, - { gamefunc_Holo_Duke, "Holo_Duke"}, - { gamefunc_Jetpack, "Jetpack"}, - { gamefunc_NightVision, "NightVision"}, - { gamefunc_MedKit, "MedKit"}, - { gamefunc_TurnAround, "Turn_Around"}, - { gamefunc_SendMessage, "Send_Message"}, - { gamefunc_Map, "Map"}, + { gamefunc_Weapon_1, "Weapon_1"}, + { gamefunc_Weapon_2, "Weapon_2"}, + { gamefunc_Weapon_3, "Weapon_3"}, + { gamefunc_Weapon_4, "Weapon_4"}, + { gamefunc_Weapon_5, "Weapon_5"}, + { gamefunc_Weapon_6, "Weapon_6"}, + { gamefunc_Weapon_7, "Weapon_7"}, + { gamefunc_Weapon_8, "Weapon_8"}, + { gamefunc_Weapon_9, "Weapon_9"}, + { gamefunc_Weapon_10, "Weapon_10"}, + { gamefunc_Inventory, "Inventory"}, + { gamefunc_Inventory_Left, "Inventory_Left"}, + { gamefunc_Inventory_Right, "Inventory_Right"}, + { gamefunc_Holo_Duke, "Holo_Duke"}, + { gamefunc_Jetpack, "Jetpack"}, + { gamefunc_NightVision, "NightVision"}, + { gamefunc_MedKit, "MedKit"}, + { gamefunc_TurnAround, "Turn_Around"}, + { gamefunc_SendMessage, "Send_Message"}, + { gamefunc_Map, "Map"}, { gamefunc_Shrink_Screen, "Shrink_Screen"}, { gamefunc_Enlarge_Screen, "Enlarge_Screen"}, - { gamefunc_Center_View, "Center_View"}, - { gamefunc_Holster_Weapon, "Holster_Weapon"}, + { gamefunc_Center_View, "Center_View"}, + { gamefunc_Holster_Weapon, "Holster_Weapon"}, { gamefunc_Show_Opponents_Weapon, "Show_Opponents_Weapon"}, - { gamefunc_Map_Follow_Mode, "Map_Follow_Mode"}, + { gamefunc_Map_Follow_Mode, "Map_Follow_Mode"}, { gamefunc_See_Coop_View, "See_Coop_View"}, - { gamefunc_Mouse_Aiming, "Mouse_Aiming"}, + { gamefunc_Mouse_Aiming, "Mouse_Aiming"}, { gamefunc_Toggle_Crosshair, "Toggle_Crosshair"}, - { gamefunc_Steroids, "Steroids"}, - { gamefunc_Quick_Kick, "Quick_Kick"}, - { gamefunc_Next_Weapon, "Next_Weapon"}, - { gamefunc_Previous_Weapon, "Previous_Weapon"}, - { gamefunc_Show_Console, "Show_Console"}, - { gamefunc_Show_DukeMatch_Scores, "Show_DukeMatch_Scores"}, + { gamefunc_Steroids, "Steroids"}, + { gamefunc_Quick_Kick, "Quick_Kick"}, + { gamefunc_Next_Weapon, "Next_Weapon"}, + { gamefunc_Previous_Weapon, "Previous_Weapon"}, + { gamefunc_Show_DukeMatch_Scores, "Show_DukeMatch_Scores"}, { gamefunc_Dpad_Select, "Dpad_Select"}, { gamefunc_Dpad_Aiming, "Dpad_Aiming"}, { gamefunc_AutoRun, "AutoRun"}, { gamefunc_Last_Weapon, "Last_Used_Weapon"}, - { gamefunc_Alt_Weapon, "Alt_Weapon"}, - { gamefunc_Third_Person_View, "Third_Person_View"}, - { gamefunc_Toggle_Crouch, "Toggle_Crouch"}, - { gamefunc_See_Chase_View, "See_Chase_View"}, // the following were added by Blood - { gamefunc_BeastVision, "BeastVision"}, - { gamefunc_CrystalBall, "CrystalBall"}, - { gamefunc_JumpBoots, "JumpBoots"}, - { gamefunc_ProximityBombs, "ProximityBombs"}, - { gamefunc_RemoteBombs, "RemoteBombs"}, - { gamefunc_Smoke_Bomb, "Smoke_Bomb" }, - { gamefunc_Gas_Bomb, "Gas_Bomb" }, - { gamefunc_Flash_Bomb, "Flash_Bomb" }, - { gamefunc_Caltrops, "Calitrops" }, - -}; - -static const ButtonDesc gamealiases_Duke3D[] = { - { gamefunc_BeastVision, ""}, - { gamefunc_CrystalBall, ""}, - { gamefunc_ProximityBombs, ""}, - { gamefunc_RemoteBombs, ""}, - { gamefunc_Smoke_Bomb, "" }, - { gamefunc_Gas_Bomb, "" }, - { gamefunc_Flash_Bomb, "" }, - { gamefunc_Caltrops, "" }, - -}; - -static const ButtonDesc gamealiases_Nam[] = { - { gamefunc_Holo_Duke, "Holo_Soldier"}, - { gamefunc_Jetpack, "Huey"}, - { gamefunc_Steroids, "Tank_Mode"}, - { gamefunc_Show_DukeMatch_Scores, "Show_GruntMatch_Scores"}, - { gamefunc_BeastVision, ""}, - { gamefunc_CrystalBall, ""}, - { gamefunc_ProximityBombs, ""}, - { gamefunc_RemoteBombs, ""}, - { gamefunc_Smoke_Bomb, "" }, - { gamefunc_Gas_Bomb, "" }, - { gamefunc_Flash_Bomb, "" }, - { gamefunc_Caltrops, "" }, - -}; - -static const ButtonDesc gamealiases_WW2GI[] = { - { gamefunc_Holo_Duke, "Fire Mission"}, - { gamefunc_Jetpack, ""}, - { gamefunc_Steroids, "Smokes"}, - { gamefunc_Show_DukeMatch_Scores, "Show_GIMatch_Scores"}, - { gamefunc_BeastVision, ""}, - { gamefunc_CrystalBall, ""}, - { gamefunc_ProximityBombs, ""}, - { gamefunc_RemoteBombs, ""}, - { gamefunc_Smoke_Bomb, "" }, - { gamefunc_Gas_Bomb, "" }, - { gamefunc_Flash_Bomb, "" }, - { gamefunc_Caltrops, "" }, -}; - -static const ButtonDesc gamealiases_RR[] = { - { gamefunc_Holo_Duke, "Beer"}, - { gamefunc_Jetpack, "Cow Pie"}, - { gamefunc_NightVision, "Yeehaa"}, - { gamefunc_MedKit, "Whiskey"}, - { gamefunc_Steroids, "Moonshine"}, - { gamefunc_Quick_Kick, "Pee"}, - { gamefunc_Show_DukeMatch_Scores, "Show_Scores"}, - { gamefunc_Alt_Fire, ""}, - { gamefunc_BeastVision, ""}, - { gamefunc_CrystalBall, ""}, - { gamefunc_ProximityBombs, ""}, - { gamefunc_RemoteBombs, ""}, - { gamefunc_Smoke_Bomb, "" }, - { gamefunc_Gas_Bomb, "" }, - { gamefunc_Flash_Bomb, "" }, - { gamefunc_Caltrops, "" }, -}; - -static const ButtonDesc gamealiases_Blood[] = { - { gamefunc_Holo_Duke, ""}, - { gamefunc_JumpBoots, "JumpBoots"}, - { gamefunc_Steroids, ""}, - { gamefunc_Quick_Kick, ""}, - { gamefunc_Show_DukeMatch_Scores, ""}, - { gamefunc_Alt_Weapon, ""}, - { gamefunc_Smoke_Bomb, "" }, - { gamefunc_Gas_Bomb, "" }, - { gamefunc_Flash_Bomb, "" }, - { gamefunc_Caltrops, "" }, - -}; - -static const ButtonDesc gamealiases_SW[] = { - { gamefunc_Holo_Duke, ""}, - { gamefunc_Jetpack, ""}, - { gamefunc_NightVision, ""}, - { gamefunc_MedKit, ""}, - { gamefunc_Steroids, ""}, - { gamefunc_Quick_Kick, ""}, - { gamefunc_Show_DukeMatch_Scores, ""}, - { gamefunc_Smoke_Bomb, "" }, - { gamefunc_Gas_Bomb, "" }, - { gamefunc_Flash_Bomb, "" }, - { gamefunc_Caltrops, "" }, + { gamefunc_Alt_Weapon, "Alt_Weapon"}, + { gamefunc_Third_Person_View, "Third_Person_View"}, + { gamefunc_Toggle_Crouch, "Toggle_Crouch"}, + { gamefunc_CrystalBall, "CrystalBall"}, // the following were added by Blood + { gamefunc_ProximityBombs, "ProximityBombs"}, + { gamefunc_RemoteBombs, "RemoteBombs"}, + { gamefunc_Smoke_Bomb, "Smoke_Bomb" }, + { gamefunc_Gas_Bomb, "Gas_Bomb" }, + { gamefunc_Flash_Bomb, "Flash_Bomb" }, + { gamefunc_Caltrops, "Caltrops" }, }; @@ -234,60 +139,7 @@ ButtonMap::ButtonMap() for(auto &gf : gamefuncs) { NameToNum.Insert(gf.name, gf.index); - NumToAlias[gf.index] = NumToName[gf.index] = gf.name; - } -} - -//============================================================================= -// -// -// -//============================================================================= - -void ButtonMap::SetGameAliases() -{ - // Ion Fury hacks this together from the CON script and uses the same table as Duke Nukem - if (g_gameType & (GAMEFLAG_DUKE|GAMEFLAG_FURY)) - { - for (auto& gf : gamealiases_Duke3D) - { - NumToAlias[gf.index] = gf.name; - } - } - if (g_gameType & GAMEFLAG_NAM) - { - for (auto& gf : gamealiases_Nam) - { - NumToAlias[gf.index] = gf.name; - } - } - if (g_gameType & GAMEFLAG_WW2GI) - { - for (auto& gf : gamealiases_WW2GI) - { - NumToAlias[gf.index] = gf.name; - } - } - if (g_gameType & (GAMEFLAG_RR|GAMEFLAG_RRRA)) - { - for (auto& gf : gamealiases_RR) - { - NumToAlias[gf.index] = gf.name; - } - } - if (g_gameType & GAMEFLAG_BLOOD) - { - for (auto& gf : gamealiases_Blood) - { - NumToAlias[gf.index] = gf.name; - } - } - if (g_gameType & GAMEFLAG_SW) - { - for (auto& gf : gamealiases_SW) - { - NumToAlias[gf.index] = gf.name; - } + NumToName[gf.index] = gf.name; } } @@ -304,18 +156,16 @@ int ButtonMap::ListActionCommands (const char *pattern) for (int i = 0; i < NumButtons(); i++) { - if (NumToAlias[i].IsEmpty()) continue; // do not list buttons that were removed from the alias list - if (pattern == NULL || CheckWildcards (pattern, (snprintf (matcher, countof(matcher), "+%s", NumToName[i].GetChars()), matcher))) { - Printf ("+%s\n", NumToName[i]); + Printf ("+%s\n", NumToName[i].GetChars()); count++; } if (pattern == NULL || CheckWildcards (pattern, (snprintf (matcher, countof(matcher), "-%s", NumToName[i].GetChars()), matcher))) { - Printf ("-%s\n", NumToName[i]); + Printf ("-%s\n", NumToName[i].GetChars()); count++; } } @@ -372,34 +222,6 @@ void ButtonMap::ResetButtonStates () } } -//============================================================================= -// -// -// -//============================================================================= - -void ButtonMap::SetButtonAlias(int num, const char *text) -{ - if ((unsigned)num >= (unsigned)NUMGAMEFUNCTIONS) - return; - NumToAlias[num] = text; - NameToNum.Insert(text, num); -} - -//============================================================================= -// -// -// -//============================================================================= - -void ButtonMap::ClearButtonAlias(int num) -{ - if ((unsigned)num >= (unsigned)NUMGAMEFUNCTIONS) - return; - NumToAlias[num] = ""; -} - - //============================================================================= // // @@ -495,4 +317,3 @@ bool FButtonStatus::ReleaseKey (int keynum) // Returns true if releasing this key caused the button to go up. return wasdown && !bDown; } - diff --git a/source/common/console/c_buttons.h b/source/common/console/c_buttons.h index 3a4746673..d8829dc3b 100644 --- a/source/common/console/c_buttons.h +++ b/source/common/console/c_buttons.h @@ -46,6 +46,7 @@ enum GameFunction_t gamefunc_JumpBoots = gamefunc_Jetpack, gamefunc_NightVision, gamefunc_Night_Vision = gamefunc_NightVision, + gamefunc_BeastVision = gamefunc_NightVision, gamefunc_MedKit, gamefunc_Med_Kit = gamefunc_MedKit, gamefunc_TurnAround, @@ -66,17 +67,18 @@ enum GameFunction_t gamefunc_Quick_Kick, gamefunc_Next_Weapon, gamefunc_Previous_Weapon, - gamefunc_Show_Console, + gamefunc_Unused1, // was gamefunc_Console. Cannot be deleted thanks to CON usuing numeric indiced for addressing this list. gamefunc_Show_DukeMatch_Scores, gamefunc_Dpad_Select, gamefunc_Dpad_Aiming, gamefunc_AutoRun, gamefunc_Last_Weapon, + gamefunc_Unused2, // was quickload/quicksave + gamefunc_Unused3, gamefunc_Alt_Weapon, gamefunc_Third_Person_View, - gamefunc_See_Chase_View = gamefunc_Third_Person_View, // this was added by Blood - gamefunc_Toggle_Crouch, - gamefunc_BeastVision, + gamefunc_See_Chase_View = gamefunc_Third_Person_View, + gamefunc_Toggle_Crouch, // This is the last one used by EDuke32. gamefunc_CrystalBall, gamefunc_ProximityBombs, gamefunc_RemoteBombs, @@ -111,7 +113,6 @@ class ButtonMap FButtonStatus Buttons[NUMGAMEFUNCTIONS]; FString NumToName[NUMGAMEFUNCTIONS]; // The internal name of the button - FString NumToAlias[NUMGAMEFUNCTIONS]; // The display name which can be altered by scripts. TMap NameToNum; public: @@ -131,6 +132,7 @@ public: return index > -1? &Buttons[index] : nullptr; } + // This is still in use but all cases are scheduled for termination. const char* GetButtonName(int32_t func) const { if ((unsigned)func >= (unsigned)NumButtons()) @@ -138,15 +140,6 @@ public: return NumToName[func]; } - const char* GetButtonAlias(int32_t func) const - { - if ((unsigned)func >= (unsigned)NumButtons()) - return nullptr; - return NumToAlias[func]; - } - - void SetButtonAlias(int num, const char* text); - void ClearButtonAlias(int num); void ResetButtonTriggers (); // Call ResetTriggers for all buttons void ResetButtonStates (); // Same as above, but also clear bDown int ListActionCommands(const char* pattern); diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index 29909e7c5..96fbbc2b6 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -29,6 +29,7 @@ #include "enet.h" #endif +void C_CON_SetAliases(); InputState inputState; void SetClipshapes(); int ShowStartupWindow(TArray &); @@ -425,7 +426,7 @@ int CONFIG_Init() } GStrings.LoadStrings(); V_InitFonts(); - buttonMap.SetGameAliases(); + C_CON_SetAliases(); Mus_Init(); InitStatistics(); M_Init(); @@ -483,7 +484,7 @@ int32_t CONFIG_GetMapBestTime(char const* const mapname, uint8_t const* const ma if (GameConfig->SetSection("MapTimes")) { auto s = GameConfig->GetValueForKey(m); - if (s) (int)strtoull(s, nullptr, 0); + if (s) return (int)strtoull(s, nullptr, 0); } return -1; } @@ -504,7 +505,6 @@ int CONFIG_SetMapBestTime(uint8_t const* const mapmd4, int32_t tm) // //========================================================================== -int32_t MouseDigitalFunctions[MAXMOUSEAXES][2]; int32_t MouseAnalogueAxes[MAXMOUSEAXES]; int32_t JoystickFunctions[MAXJOYBUTTONSANDHATS][2]; int32_t JoystickDigitalFunctions[MAXJOYAXES][2]; @@ -521,51 +521,6 @@ static const char* mouseanalogdefaults[MAXMOUSEAXES] = }; -static const char* mousedigitaldefaults[MAXMOUSEDIGITAL] = -{ -}; - -static const char* joystickdefaults[MAXJOYBUTTONSANDHATS] = -{ -"Fire", -"Strafe", -"Run", -"Open", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"", -"Aim_Down", -"Look_Right", -"Aim_Up", -"Look_Left", -}; - - static const char* joystickclickeddefaults[MAXJOYBUTTONSANDHATS] = { "", @@ -583,18 +538,6 @@ static const char* joystickanalogdefaults[MAXJOYAXES] = }; -static const char* joystickdigitaldefaults[MAXJOYDIGITAL] = -{ -"", -"", -"", -"", -"", -"", -"Run", -}; - - //========================================================================== // // @@ -658,62 +601,6 @@ void CONFIG_SetupMouse(void) void CONFIG_SetupJoystick(void) { - const char* val; - FString section = currentGame + ".ControllerSettings"; - if (!GameConfig->SetSection(section)) return; - - for (int i = 0; i < MAXJOYBUTTONSANDHATS; i++) - { - section.Format("ControllerButton%d", i); - val = GameConfig->GetValueForKey(section); - if (val) - JoystickFunctions[i][0] = buttonMap.FindButtonIndex(val); - - section.Format("ControllerButtonClicked%d", i); - val = GameConfig->GetValueForKey(section); - if (val) - JoystickFunctions[i][1] = buttonMap.FindButtonIndex(val); - } - - // map over the axes - for (int i = 0; i < MAXJOYAXES; i++) - { - section.Format("ControllerAnalogAxes%d", i); - val = GameConfig->GetValueForKey(section); - if (val) - JoystickAnalogueAxes[i] = CONFIG_AnalogNameToNum(val); - - section.Format("ControllerDigitalAxes%d_0", i); - val = GameConfig->GetValueForKey(section); - if (val) - JoystickDigitalFunctions[i][0] = buttonMap.FindButtonIndex(val); - - section.Format("ControllerDigitalAxes%d_1", i); - val = GameConfig->GetValueForKey(section); - if (val) - JoystickDigitalFunctions[i][1] = buttonMap.FindButtonIndex(val); - - section.Format("ControllerAnalogScale%d", i); - val = GameConfig->GetValueForKey(section); - if (val) - JoystickAnalogueScale[i] = (int32_t)strtoull(val, nullptr, 0); - - section.Format("ControllerAnalogInvert%d", i); - val = GameConfig->GetValueForKey(section); - if (val) - JoystickAnalogueInvert[i] = (int32_t)strtoull(val, nullptr, 0); - - section.Format("ControllerAnalogDead%d", i); - val = GameConfig->GetValueForKey(section); - if (val) - JoystickAnalogueDead[i] = (int32_t)strtoull(val, nullptr, 0); - - section.Format("ControllerAnalogSaturate%d", i); - val = GameConfig->GetValueForKey(section); - if (val) - JoystickAnalogueSaturate[i] = (int32_t)strtoull(val, nullptr, 0); - } - for (int i = 0; i < MAXJOYAXES; i++) { CONTROL_MapAnalogAxis(i, JoystickAnalogueAxes[i], controldevice_joystick); @@ -877,14 +764,12 @@ void CONFIG_SetGameControllerDefaultsStandard() for (auto const& button : buttons) button.apply(); - /* - if (FURY) + if (g_gameType & GAMEFLAG_FURY) { for (auto const& button : buttonsFury) button.apply(); } else - */ { for (auto const& button : buttonsDuke) button.apply(); @@ -938,14 +823,12 @@ void CONFIG_SetGameControllerDefaultsPro() for (auto const& button : buttons) button.apply(); -#if 0 // ouch... - if (FURY) + if (g_gameType & GAMEFLAG_FURY) { for (auto const& button : buttonsFury) button.apply(); } else -#endif { for (auto const& button : buttonsDuke) button.apply(); @@ -955,99 +838,14 @@ void CONFIG_SetGameControllerDefaultsPro() digitalAxis.apply(); } -FString CONFIG_GetGameFuncOnKeyboard(int gameFunc) -{ - auto binding = buttonMap.GetButtonAlias(gameFunc); - auto keys = Bindings.GetKeysForCommand(binding); - for(auto key : keys) - { - if (key < KEY_FIRSTMOUSEBUTTON) - { - auto scan = KB_ScanCodeToString(key); - if (scan) return scan; - - } - } - return ""; -} - -FString CONFIG_GetGameFuncOnMouse(int gameFunc) -{ - auto binding = buttonMap.GetButtonAlias(gameFunc); - auto keys = Bindings.GetKeysForCommand(binding); - for (auto key : keys) - { - if ((key >= KEY_FIRSTMOUSEBUTTON && key < KEY_FIRSTJOYBUTTON) || (key >= KEY_MWHEELUP && key <= KEY_MWHEELLEFT)) - { - auto scan = KB_ScanCodeToString(key); - if (scan) return scan; - - } - } - return ""; -} - -char const* CONFIG_GetGameFuncOnJoystick(int gameFunc) -{ - auto binding = buttonMap.GetButtonAlias(gameFunc); - auto keys = Bindings.GetKeysForCommand(binding); - for (auto key : keys) - { - if (key >= KEY_FIRSTJOYBUTTON && !(key >= KEY_MWHEELUP && key <= KEY_MWHEELLEFT)) - { - auto scan = KB_ScanCodeToString(key); - if (scan) return scan; - } - } - return ""; -} - -// FIXME: Consider the mouse as well! -FString CONFIG_GetBoundKeyForLastInput(int gameFunc) -{ - if (CONTROL_LastSeenInput == LastSeenInput::Joystick) - { - FString name = CONFIG_GetGameFuncOnJoystick(gameFunc); - if (name.IsNotEmpty()) - { - return name; - } - } - - FString name = CONFIG_GetGameFuncOnKeyboard(gameFunc); - if (name.IsNotEmpty()) - { - return name; - } - - name = CONFIG_GetGameFuncOnMouse(gameFunc); - if (name.IsNotEmpty()) - { - return name; - } - - name = CONFIG_GetGameFuncOnJoystick(gameFunc); - if (name.IsNotEmpty()) - { - return name; - } - return "UNBOUND"; -} - void CONFIG_InitMouseAndController() { - memset(MouseDigitalFunctions, -1, sizeof(MouseDigitalFunctions)); memset(JoystickFunctions, -1, sizeof(JoystickFunctions)); memset(JoystickDigitalFunctions, -1, sizeof(JoystickDigitalFunctions)); for (int i = 0; i < MAXMOUSEAXES; i++) { - MouseDigitalFunctions[i][0] = buttonMap.FindButtonIndex(mousedigitaldefaults[i * 2]); - MouseDigitalFunctions[i][1] = buttonMap.FindButtonIndex(mousedigitaldefaults[i * 2 + 1]); - CONTROL_MapDigitalAxis(i, MouseDigitalFunctions[i][0], 0, controldevice_mouse); - CONTROL_MapDigitalAxis(i, MouseDigitalFunctions[i][1], 1, controldevice_mouse); - MouseAnalogueAxes[i] = CONFIG_AnalogNameToNum(mouseanalogdefaults[i]); CONTROL_MapAnalogAxis(i, MouseAnalogueAxes[i], controldevice_mouse); } @@ -1074,20 +872,6 @@ void CONFIG_WriteControllerSettings() { FString section = currentGame + ".ControllerSettings"; GameConfig->SetSection(section); - for (int dummy = 0; dummy < MAXJOYBUTTONSANDHATS; dummy++) - { - if (buttonMap.GetButtonName(JoystickFunctions[dummy][0])) - { - buf.Format("ControllerButton%d", dummy); - GameConfig->SetValueForKey(buf, buttonMap.GetButtonName(JoystickFunctions[dummy][0])); - } - - if (buttonMap.GetButtonName(JoystickFunctions[dummy][1])) - { - buf.Format("ControllerButtonClicked%d", dummy); - GameConfig->SetValueForKey(buf, buttonMap.GetButtonName(JoystickFunctions[dummy][1])); - } - } for (int dummy = 0; dummy < MAXJOYAXES; dummy++) { if (CONFIG_AnalogNumToName(JoystickAnalogueAxes[dummy])) @@ -1096,12 +880,6 @@ void CONFIG_WriteControllerSettings() GameConfig->SetValueForKey(buf, CONFIG_AnalogNumToName(JoystickAnalogueAxes[dummy])); } - if (buttonMap.GetButtonName(JoystickDigitalFunctions[dummy][0])) - { - buf.Format("ControllerDigitalAxes%d_0", dummy); - GameConfig->SetValueForKey(buf, buttonMap.GetButtonName(JoystickDigitalFunctions[dummy][0])); - } - if (buttonMap.GetButtonName(JoystickDigitalFunctions[dummy][1])) { buf.Format("ControllerDigitalAxes%d_1", dummy); diff --git a/source/common/gamecontrol.h b/source/common/gamecontrol.h index 4ef9187cd..740f3de80 100644 --- a/source/common/gamecontrol.h +++ b/source/common/gamecontrol.h @@ -38,19 +38,6 @@ void CONFIG_SetDefaultKeys(const char *defbinds); #define DEFAULTJOYSTICKANALOGUESATURATE 9500 -extern int32_t MouseDigitalFunctions[MAXMOUSEAXES][2]; -extern int32_t MouseAnalogueAxes[MAXMOUSEAXES]; -extern int32_t JoystickFunctions[MAXJOYBUTTONSANDHATS][2]; -extern int32_t JoystickDigitalFunctions[MAXJOYAXES][2]; -extern int32_t JoystickAnalogueAxes[MAXJOYAXES]; -extern int32_t JoystickAnalogueScale[MAXJOYAXES]; -extern int32_t JoystickAnalogueDead[MAXJOYAXES]; -extern int32_t JoystickAnalogueSaturate[MAXJOYAXES]; -extern int32_t JoystickAnalogueInvert[MAXJOYAXES]; - -int32_t CONFIG_AnalogNameToNum(const char* func); -const char* CONFIG_AnalogNumToName(int32_t func); -void CONFIG_SetupMouse(void); void CONFIG_SetupJoystick(void); void CONFIG_WriteControllerSettings(); void CONFIG_InitMouseAndController(); @@ -59,8 +46,6 @@ void CONFIG_SetGameControllerDefaultsStandard(); void CONFIG_SetGameControllerDefaultsPro(); void CONFIG_SetGameControllerDefaultsClear(); -FString CONFIG_GetBoundKeyForLastInput(int gameFunc); - extern FStringCVar* const CombatMacros[]; void CONFIG_ReadCombatMacros(); diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index 62d4b52dd..3a1c87e58 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -43,6 +43,9 @@ BEGIN_DUKE_NS #define LINE_NUMBER (g_lineNumber << 12) +void C_CON_SetButtonAlias(int num, const char* text); +void C_CON_ClearButtonAlias(int num); + int32_t g_scriptVersion = 13; // 13 = 1.3D-style CON files, 14 = 1.4/1.5 style CON files char g_scriptFileName[BMAX_PATH] = "(none)"; // file we're currently compiling @@ -2197,11 +2200,14 @@ void C_InitQuotes(void) #ifdef EDUKE32_TOUCH_DEVICES apStrings[QUOTE_DEAD] = 0; #else - // WTF ?!? - char const * const OpenGameFunc = buttonMap.GetButtonName(gamefunc_Open); - C_ReplaceQuoteSubstring(QUOTE_DEAD, "SPACE", OpenGameFunc); - C_ReplaceQuoteSubstring(QUOTE_DEAD, "OPEN", OpenGameFunc); - C_ReplaceQuoteSubstring(QUOTE_DEAD, "USE", OpenGameFunc); + auto openkeys = Bindings.GetKeysForCommand("+open"); + if (openkeys.Size()) + { + auto OpenGameFunc = C_NameKeys(openkeys.Data(), 1); + C_ReplaceQuoteSubstring(QUOTE_DEAD, "SPACE", OpenGameFunc); + C_ReplaceQuoteSubstring(QUOTE_DEAD, "OPEN", OpenGameFunc); + C_ReplaceQuoteSubstring(QUOTE_DEAD, "USE", OpenGameFunc); + } #endif // most of these are based on Blood, obviously diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index 10be274c7..726a0f30d 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -55,6 +55,9 @@ BEGIN_DUKE_NS vmstate_t vm; +FString C_CON_GetBoundKeyForLastInput(int gameFunc); + + #if !defined LUNATIC int32_t g_tw; int32_t g_currentEvent = -1; @@ -3684,7 +3687,7 @@ badindex: static char const s_KeyboardFormat[] = "[%s]"; static char const s_JoystickFormat[] = "(%s)"; - auto binding = CONFIG_GetBoundKeyForLastInput(gameFunc); + auto binding = C_CON_GetBoundKeyForLastInput(gameFunc); if (binding.Len()) snprintf(apStrings[quoteIndex], MAXQUOTELEN, "(%s)", binding.GetChars()); dispatch(); } diff --git a/source/rr/src/gamedef.cpp b/source/rr/src/gamedef.cpp index a854e7146..226be8da0 100644 --- a/source/rr/src/gamedef.cpp +++ b/source/rr/src/gamedef.cpp @@ -937,10 +937,14 @@ void C_InitQuotes(void) #ifdef EDUKE32_TOUCH_DEVICES apStrings[QUOTE_DEAD] = 0; #else - char const * OpenGameFunc = buttonMap.GetButtonName(gamefunc_Open); - C_ReplaceQuoteSubstring(QUOTE_DEAD, "SPACE", OpenGameFunc); - C_ReplaceQuoteSubstring(QUOTE_DEAD, "OPEN", OpenGameFunc); - C_ReplaceQuoteSubstring(QUOTE_DEAD, "USE", OpenGameFunc); + auto openkeys = Bindings.GetKeysForCommand("+open"); + if (openkeys.Size()) + { + auto OpenGameFunc = C_NameKeys(openkeys.Data(), 1); + C_ReplaceQuoteSubstring(QUOTE_DEAD, "SPACE", OpenGameFunc); + C_ReplaceQuoteSubstring(QUOTE_DEAD, "OPEN", OpenGameFunc); + C_ReplaceQuoteSubstring(QUOTE_DEAD, "USE", OpenGameFunc); + } #endif // most of these are based on Blood, obviously From 3cf6e6eb7866484d20287c3f1e404cb69c61eca3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 2 Dec 2019 12:11:42 +0100 Subject: [PATCH 083/203] - Ion Fury inventory actions --- wadsrc/static/demolition/menudef.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index ede0749d1..74508b7f6 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -748,10 +748,15 @@ OptionMenu "WeaponsControlMenu" protected Control "$CNTRLMNU_SLOT0" , "+weapon_10" StaticText "" Control "$CNTRLMNU_HOLSTER" , "+holster_weapon" + ifgame(Fury) + { + Control "$CNTRLMNU_RELOAD" , "+steroids" + } ifgame(Duke, Nam, WW2GI, Fury) { Control "$CNTRLMNU_QUICKKICK" , "+quick_kick" } + ifgame(Redneck, RedneckRides) { Control "$CNTRLMNU_PEE" , "+quick_kick" @@ -793,6 +798,12 @@ OptionMenu "InventoryControlsMenu" protected Control "$CNTRLMNU_MEDKIT" , "+medkit" Control "$CNTRLMNU_STEROIDS" , "+steroids" } + ifgame(Fury) + { + StaticText "" + Control "$CNTRLMNU_RADAR" , "+nightvision" + Control "$CNTRLMNU_MEDKIT" , "+medkit" + } ifgame(Nam) { StaticText "" From 26daff79db815f7b802c007a02ca2165f7f46ec4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 2 Dec 2019 18:11:10 +0100 Subject: [PATCH 084/203] - fixed compile errors and updated string table. --- source/CMakeLists.txt | 2 +- source/common/console/c_bind.cpp | 212 ------------------ source/common/console/c_con.cpp | 276 ++++++++++++++++++++++++ source/common/console/d_event.cpp | 7 - source/common/optionmenu/optionmenu.cpp | 96 --------- source/duke3d/src/gamedef.cpp | 9 +- source/duke3d/src/gameexec.cpp | 6 +- source/sw/src/menus.cpp | 9 +- wadsrc/static/demolition/language.csv | 90 +++++++- 9 files changed, 382 insertions(+), 325 deletions(-) create mode 100644 source/common/console/c_con.cpp delete mode 100644 source/common/optionmenu/optionmenu.cpp diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 844597972..5d8a8c36f 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -748,7 +748,6 @@ set (PCH_SOURCES common/searchpaths.cpp common/initfs.cpp common/openaudio.cpp - common/optionmenu/optionmenu.cpp common/statistics.cpp common/secrets.cpp common/compositesavegame.cpp @@ -774,6 +773,7 @@ set (PCH_SOURCES common/console/c_commandline.cpp common/console/c_dispatch.cpp common/console/d_event.cpp + common/console/c_con.cpp common/utility/i_time.cpp common/utility/name.cpp diff --git a/source/common/console/c_bind.cpp b/source/common/console/c_bind.cpp index bdee36e85..cfa0b9f4f 100644 --- a/source/common/console/c_bind.cpp +++ b/source/common/console/c_bind.cpp @@ -809,215 +809,3 @@ bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds) return false; } -// Todo: Move to a separate file. -//============================================================================= -// -// Interface for CON scripts to get descriptions for actions -// This code can query the 64 original game functions by index. -// -//============================================================================= - -static GameFuncDesc con_gamefuncs[] = { -{"+Move_Forward", "Move_Forward"}, -{"+Move_Backward", "Move_Backward"}, -{"+Turn_Left", "Turn_Left"}, -{"+Turn_Right", "Turn_Right"}, -{"+Strafe", "Strafe"}, -{"+Fire", "Fire"}, -{"+Open", "Open"}, -{"+Run", "Run"}, -{"+Alt_Fire", "Alt_Fire"}, -{"+Jump", "Jump"}, -{"+Crouch", "Crouch"}, -{"+Look_Up", "Look_Up"}, -{"+Look_Down", "Look_Down"}, -{"+Look_Left", "Look_Left"}, -{"+Look_Right", "Look_Right"}, -{"+Strafe_Left", "Strafe_Left"}, -{"+Strafe_Right", "Strafe_Right"}, -{"+Aim_Up", "Aim_Up"}, -{"+Aim_Down", "Aim_Down"}, -{"+Weapon_1", "Weapon_1"}, -{"+Weapon_2", "Weapon_2"}, -{"+Weapon_3", "Weapon_3"}, -{"+Weapon_4", "Weapon_4"}, -{"+Weapon_5", "Weapon_5"}, -{"+Weapon_6", "Weapon_6"}, -{"+Weapon_7", "Weapon_7"}, -{"+Weapon_8", "Weapon_8"}, -{"+Weapon_9", "Weapon_9"}, -{"+Weapon_10", "Weapon_10"}, -{"+Inventory", "Inventory"}, -{"+Inventory_Left", "Inventory_Left"}, -{"+Inventory_Right", "Inventory_Right"}, -{"+Holo_Duke", "Holo_Duke"}, -{"+Jetpack", "Jetpack"}, -{"+NightVision", "NightVision"}, -{"+MedKit", "MedKit"}, -{"+TurnAround", "TurnAround"}, -{"+SendMessage", "SendMessage"}, -{"+Map", "Map"}, -{"+Shrink_Screen", "Shrink_Screen"}, -{"+Enlarge_Screen", "Enlarge_Screen"}, -{"+Center_View", "Center_View"}, -{"+Holster_Weapon", "Holster_Weapon"}, -{"+Show_Opponents_Weapon", "Show_Opponents_Weapon"}, -{"+Map_Follow_Mode", "Map_Follow_Mode"}, -{"+See_Coop_View", "See_Coop_View"}, -{"+Mouse_Aiming", "Mouse_Aiming"}, -{"+Toggle_Crosshair", "Toggle_Crosshair"}, -{"+Steroids", "Steroids"}, -{"+Quick_Kick", "Quick_Kick"}, -{"+Next_Weapon", "Next_Weapon"}, -{"+Previous_Weapon", "Previous_Weapon"}, -{"+Show_Console", "Show_Console"}, -{"+Show_DukeMatch_Scores", "Show_Scoreboard"}, -{"+Dpad_Select", "Dpad_Select"}, -{"+Dpad_Aiming", "Dpad_Aiming"}, -{"+AutoRun", "AutoRun"}, -{"+Last_Used_Weapon", "Last_Used_Weapon"}, -{"+Quick_Save", "Quick_Save"}, -{"+Quick_Load", "Quick_Load"}, -{"+Alt_Weapon", "Alt_Weapon"}, -{"+Third_Person_View", "Third_Person_View"}, -{"+Toggle_Crouch", "Toggle_Crouch"} -}; - -//============================================================================= -// -// -// -//============================================================================= - -void C_CON_SetAliases() -{ - if (g_gameType & GAMEFLAG_NAM) - { - con_gamefuncs[32].description = "Holo_Soldier"; - con_gamefuncs[33].description = "Huey"; - con_gamefuncs[48].description = "Tank_Mode"; - } - if (g_gameType & GAMEFLAG_WW2GI) - { - con_gamefuncs[32].description = "Fire_Mission"; - con_gamefuncs[33].description = ""; - con_gamefuncs[48].description = "Smokes"; - } - -} - -static FString C_CON_GetGameFuncOnKeyboard(int gameFunc) -{ - if (gameFunc >= 0 && gameFunc < countof(con_gamefuncs)) - { - auto keys = Bindings.GetKeysForCommand(con_gamefuncs[gameFunc].action); - for (auto key : keys) - { - if (key < KEY_FIRSTMOUSEBUTTON) - { - auto scan = KB_ScanCodeToString(key); - if (scan) return scan; - } - } - } - return ""; -} - -static FString C_CON_GetGameFuncOnMouse(int gameFunc) -{ - if (gameFunc >= 0 && gameFunc < countof(con_gamefuncs)) - { - auto keys = Bindings.GetKeysForCommand(con_gamefuncs[gameFunc].action); - for (auto key : keys) - { - if ((key >= KEY_FIRSTMOUSEBUTTON && key < KEY_FIRSTJOYBUTTON) || (key >= KEY_MWHEELUP && key <= KEY_MWHEELLEFT)) - { - auto scan = KB_ScanCodeToString(key); - if (scan) return scan; - } - } - } - return ""; -} - -char const* C_CON_GetGameFuncOnJoystick(int gameFunc) -{ - if (gameFunc >= 0 && gameFunc < countof(con_gamefuncs)) - { - auto keys = Bindings.GetKeysForCommand(con_gamefuncs[gameFunc].action); - for (auto key : keys) - { - if (key >= KEY_FIRSTJOYBUTTON && !(key >= KEY_MWHEELUP && key <= KEY_MWHEELLEFT)) - { - auto scan = KB_ScanCodeToString(key); - if (scan) return scan; - } - } - } - return ""; -} - -FString C_CON_GetBoundKeyForLastInput(int gameFunc) -{ - if (CONTROL_LastSeenInput == LastSeenInput::Joystick) - { - FString name = C_CON_GetGameFuncOnJoystick(gameFunc); - if (name.IsNotEmpty()) - { - return name; - } - } - - FString name = C_CON_GetGameFuncOnKeyboard(gameFunc); - if (name.IsNotEmpty()) - { - return name; - } - - name = C_CON_GetGameFuncOnMouse(gameFunc); - if (name.IsNotEmpty()) - { - return name; - } - - name = C_CON_GetGameFuncOnJoystick(gameFunc); - if (name.IsNotEmpty()) - { - return name; - } - return "UNBOUND"; -} - - -//============================================================================= -// -// -// -//============================================================================= - -void C_CON_SetButtonAlias(int num, const char *text) -{ - if (num >= 0 && num < countof(con_gamefuncs)) - { - if (con_gamefuncs[num].replaced) free((void*)con_gamefuncs[num].description); - con_gamefuncs[num].description = strdup(text); - con_gamefuncs[num].replaced = true; - } -} - -//============================================================================= -// -// -// -//============================================================================= - -void C_CON_ClearButtonAlias(int num) -{ - if (num >= 0 && num < countof(con_gamefuncs)) - { - if (con_gamefuncs[num].replaced) free((void*)con_gamefuncs[num].description); - con_gamefuncs[num].description = ""; - con_gamefuncs[num].replaced = false; - } -} - diff --git a/source/common/console/c_con.cpp b/source/common/console/c_con.cpp new file mode 100644 index 000000000..09b14a506 --- /dev/null +++ b/source/common/console/c_con.cpp @@ -0,0 +1,276 @@ +/* +** c_con.cpp +** Interface for CON scripts. +** +** +**--------------------------------------------------------------------------- +** Copyright 2019 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include +#include "basics.h" +#include "zstring.h" +#include "c_bind.h" +#include "gamecontrol.h" + +//============================================================================= +// +// Interface for CON scripts to get descriptions for actions +// This code can query the 64 original game functions by index. +// +// This is mostly an ill-advised hackery to change menu texts. It no longer +// changes the menu but gets used when scripts try to write +// key related messages. Ion Fury uses this and is one of the reasons +// why that game is by all accounts not localizable. +// +// Important note: The list of actions may not be altered. If some of these +// commands get refactored, the string below needs to be changed to match +// the new command. +// +//============================================================================= + +static GameFuncDesc con_gamefuncs[] = { +{"+Move_Forward", "Move_Forward"}, +{"+Move_Backward", "Move_Backward"}, +{"+Turn_Left", "Turn_Left"}, +{"+Turn_Right", "Turn_Right"}, +{"+Strafe", "Strafe"}, +{"+Fire", "Fire"}, +{"+Open", "Open"}, +{"+Run", "Run"}, +{"+Alt_Fire", "Alt_Fire"}, +{"+Jump", "Jump"}, +{"+Crouch", "Crouch"}, +{"+Look_Up", "Look_Up"}, +{"+Look_Down", "Look_Down"}, +{"+Look_Left", "Look_Left"}, +{"+Look_Right", "Look_Right"}, +{"+Strafe_Left", "Strafe_Left"}, +{"+Strafe_Right", "Strafe_Right"}, +{"+Aim_Up", "Aim_Up"}, +{"+Aim_Down", "Aim_Down"}, +{"+Weapon_1", "Weapon_1"}, +{"+Weapon_2", "Weapon_2"}, +{"+Weapon_3", "Weapon_3"}, +{"+Weapon_4", "Weapon_4"}, +{"+Weapon_5", "Weapon_5"}, +{"+Weapon_6", "Weapon_6"}, +{"+Weapon_7", "Weapon_7"}, +{"+Weapon_8", "Weapon_8"}, +{"+Weapon_9", "Weapon_9"}, +{"+Weapon_10", "Weapon_10"}, +{"+Inventory", "Inventory"}, +{"+Inventory_Left", "Inventory_Left"}, +{"+Inventory_Right", "Inventory_Right"}, +{"+Holo_Duke", "Holo_Duke"}, +{"+Jetpack", "Jetpack"}, +{"+NightVision", "NightVision"}, +{"+MedKit", "MedKit"}, +{"+TurnAround", "TurnAround"}, +{"+SendMessage", "SendMessage"}, +{"+Map", "Map"}, +{"+Shrink_Screen", "Shrink_Screen"}, +{"+Enlarge_Screen", "Enlarge_Screen"}, +{"+Center_View", "Center_View"}, +{"+Holster_Weapon", "Holster_Weapon"}, +{"+Show_Opponents_Weapon", "Show_Opponents_Weapon"}, +{"+Map_Follow_Mode", "Map_Follow_Mode"}, +{"+See_Coop_View", "See_Coop_View"}, +{"+Mouse_Aiming", "Mouse_Aiming"}, +{"+Toggle_Crosshair", "Toggle_Crosshair"}, +{"+Steroids", "Steroids"}, +{"+Quick_Kick", "Quick_Kick"}, +{"+Next_Weapon", "Next_Weapon"}, +{"+Previous_Weapon", "Previous_Weapon"}, +{"ToggleConsole", "Show_Console"}, +{"+Show_DukeMatch_Scores", "Show_Scoreboard"}, +{"+Dpad_Select", "Dpad_Select"}, +{"+Dpad_Aiming", "Dpad_Aiming"}, +{"+AutoRun", "AutoRun"}, +{"+Last_Used_Weapon", "Last_Used_Weapon"}, +{"QuickSave", "Quick_Save"}, +{"QuickLoad", "Quick_Load"}, +{"+Alt_Weapon", "Alt_Weapon"}, +{"+Third_Person_View", "Third_Person_View"}, +{"+Toggle_Crouch", "Toggle_Crouch"} +}; + +//============================================================================= +// +// +// +//============================================================================= + +void C_CON_SetAliases() +{ + if (g_gameType & GAMEFLAG_NAM) + { + con_gamefuncs[32].description = "Holo_Soldier"; + con_gamefuncs[33].description = "Huey"; + con_gamefuncs[48].description = "Tank_Mode"; + } + if (g_gameType & GAMEFLAG_WW2GI) + { + con_gamefuncs[32].description = "Fire_Mission"; + con_gamefuncs[33].description = ""; + con_gamefuncs[48].description = "Smokes"; + } + +} + +static FString C_CON_GetGameFuncOnKeyboard(int gameFunc) +{ + if (gameFunc >= 0 && gameFunc < countof(con_gamefuncs)) + { + auto keys = Bindings.GetKeysForCommand(con_gamefuncs[gameFunc].action); + for (auto key : keys) + { + if (key < KEY_FIRSTMOUSEBUTTON) + { + auto scan = KB_ScanCodeToString(key); + if (scan) return scan; + } + } + } + return ""; +} + +static FString C_CON_GetGameFuncOnMouse(int gameFunc) +{ + if (gameFunc >= 0 && gameFunc < countof(con_gamefuncs)) + { + auto keys = Bindings.GetKeysForCommand(con_gamefuncs[gameFunc].action); + for (auto key : keys) + { + if ((key >= KEY_FIRSTMOUSEBUTTON && key < KEY_FIRSTJOYBUTTON) || (key >= KEY_MWHEELUP && key <= KEY_MWHEELLEFT)) + { + auto scan = KB_ScanCodeToString(key); + if (scan) return scan; + } + } + } + return ""; +} + +char const* C_CON_GetGameFuncOnJoystick(int gameFunc) +{ + if (gameFunc >= 0 && gameFunc < countof(con_gamefuncs)) + { + auto keys = Bindings.GetKeysForCommand(con_gamefuncs[gameFunc].action); + for (auto key : keys) + { + if (key >= KEY_FIRSTJOYBUTTON && !(key >= KEY_MWHEELUP && key <= KEY_MWHEELLEFT)) + { + auto scan = KB_ScanCodeToString(key); + if (scan) return scan; + } + } + } + return ""; +} + +FString C_CON_GetBoundKeyForLastInput(int gameFunc) +{ + if (CONTROL_LastSeenInput == LastSeenInput::Joystick) + { + FString name = C_CON_GetGameFuncOnJoystick(gameFunc); + if (name.IsNotEmpty()) + { + return name; + } + } + + FString name = C_CON_GetGameFuncOnKeyboard(gameFunc); + if (name.IsNotEmpty()) + { + return name; + } + + name = C_CON_GetGameFuncOnMouse(gameFunc); + if (name.IsNotEmpty()) + { + return name; + } + + name = C_CON_GetGameFuncOnJoystick(gameFunc); + if (name.IsNotEmpty()) + { + return name; + } + return "UNBOUND"; +} + + +//============================================================================= +// +// +// +//============================================================================= + +void C_CON_SetButtonAlias(int num, const char *text) +{ + if (num >= 0 && num < countof(con_gamefuncs)) + { + if (con_gamefuncs[num].replaced) free((void*)con_gamefuncs[num].description); + con_gamefuncs[num].description = strdup(text); + con_gamefuncs[num].replaced = true; + } +} + +//============================================================================= +// +// +// +//============================================================================= + +void C_CON_ClearButtonAlias(int num) +{ + if (num >= 0 && num < countof(con_gamefuncs)) + { + if (con_gamefuncs[num].replaced) free((void*)con_gamefuncs[num].description); + con_gamefuncs[num].description = ""; + con_gamefuncs[num].replaced = false; + } +} + +//============================================================================= +// +// +// +//============================================================================= + +const char *C_CON_GetButtonFunc(int num) +{ + if (num >= 0 && num < countof(con_gamefuncs)) + { + return con_gamefuncs[num].action; + } + return ""; +} + diff --git a/source/common/console/d_event.cpp b/source/common/console/d_event.cpp index 0aace459a..bcb5d4024 100644 --- a/source/common/console/d_event.cpp +++ b/source/common/console/d_event.cpp @@ -185,13 +185,6 @@ void D_PostEvent (const event_t *ev) return; } - if ((GUICapture & 8) && ev->type == EV_KeyDown) - { - // This must bypass the entire event management - sendKeyForBinding(ev->data1); - return; - } - // Add the key to the global keyboard state. // This is probably the biggest roadblock with the input system as it undermines a proper event driven approach. // Too much code depends on just checking this instead of waiting for events to happen. diff --git a/source/common/optionmenu/optionmenu.cpp b/source/common/optionmenu/optionmenu.cpp deleted file mode 100644 index 78ee8adb2..000000000 --- a/source/common/optionmenu/optionmenu.cpp +++ /dev/null @@ -1,96 +0,0 @@ - - - -#include "imgui.h" -#include "v_draw.h" -#include "gamecvars.h" -#include "c_buttons.h" -#include "c_bind.h" -#include "inputstate.h" - -FString activeCommand; - -void sendKeyForBinding(int key) -{ - Bindings.DoBind(KeyName(key), activeCommand); - GUICapture &= ~8; -} - - -bool ShowOptionMenu() -{ - bool isOpen = true; - int w = screen->GetWidth(), h = screen->GetHeight(); - double scale; - if (w >= 1024 && h >= 768) - { - scale = 1; - ImGui::SetNextWindowPos(ImVec2((w-1024)/2, (h-768)/2), ImGuiCond_Always); - ImGui::SetNextWindowSize(ImVec2(1024, 768), ImGuiCond_Always); - } - else - { - // This should use a smaller font! - scale = 640.0/1024.0; - ImGui::SetNextWindowPos(ImVec2((w-640)/2, (h-480)/2), ImGuiCond_Always); - ImGui::SetNextWindowSize(ImVec2(640, 480), ImGuiCond_Always); - } - - - const int window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; - // Main body of the Demo window starts here. - if (!ImGui::Begin("Customize Controls", &isOpen, window_flags)) - { - // Early out if the window is collapsed, as an optimization. - ImGui::End(); - return false; - } - FString emptiness = " "; - - for (int i = 0; i < NUMGAMEFUNCTIONS; i++) - { - FString al = buttonMap.GetButtonAlias(i); - FString cmd = "+" + al; - if (al.IsNotEmpty()) - { - al.Substitute('_', ' '); - ImGui::Text(al.GetChars()); - ImGui::SameLine(300*scale); - al = buttonMap.GetButtonName(i); - auto binds = Bindings.GetKeysForCommand(cmd); - al = C_NameKeys(binds.Data(), binds.Size()); - // This looks like an ImGui bug - it doesn't like two identically labelled buttons on the same page, it seems. - // Work around this by using strings with different numbers of spaces. Stupid but effective. - if (al.IsEmpty()) { al = emptiness; emptiness << " "; } - if (ImGui::Button(al, ImVec2(450 * scale, 0))) - { - activeCommand = cmd; - ImGui::OpenPopup("Bind"); - } - } - } - if (ImGui::BeginPopupModal("Bind", NULL, ImGuiWindowFlags_AlwaysAutoResize)) - { - auto binds = Bindings.GetKeysForCommand(activeCommand); - auto al = C_NameKeys(binds.Data(), binds.Size()); - - ImGui::Text("Press 'bind' to enter binding mode or\n'delete' to clear all bindings for this action\n\nCurrently bound to this action:\n%s\n\n", al.GetChars()); - ImGui::Separator(); - if (ImGui::Button("Done", ImVec2(120, 0))) { ImGui::CloseCurrentPopup(); } - ImGui::SetItemDefaultFocus(); - ImGui::SameLine(); - if (ImGui::Button("Clear", ImVec2(120, 0))) { Bindings.UnbindACommand(activeCommand); } - ImGui::SameLine(); - if (ImGui::Button("Bind", ImVec2(120, 0))) - { - // Todo: Set event handler to binding mode. - // Wait for a bound key to arrive and add to the current command. - GUICapture |= 8; - } - ImGui::EndPopup(); - } - - - ImGui::End(); - return isOpen; -} \ No newline at end of file diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index 3a1c87e58..ee02f33d3 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -39,12 +39,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "menu/menu.h" #include "stringtable.h" +void C_CON_SetButtonAlias(int num, const char* text); +void C_CON_ClearButtonAlias(int num); + BEGIN_DUKE_NS #define LINE_NUMBER (g_lineNumber << 12) -void C_CON_SetButtonAlias(int num, const char* text); -void C_CON_ClearButtonAlias(int num); int32_t g_scriptVersion = 13; // 13 = 1.3D-style CON files, 14 = 1.4/1.5 style CON files @@ -5072,7 +5073,7 @@ repeatcase: } } build.Push(0); - buttonMap.SetButtonAlias(j, build.Data()); + C_CON_SetButtonAlias(j, build.Data()); } continue; @@ -5091,7 +5092,7 @@ repeatcase: continue; } - buttonMap.ClearButtonAlias(j); + C_CON_ClearButtonAlias(j); continue; case CON_DEFINESKILLNAME: diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index 726a0f30d..61ae6e792 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -43,6 +43,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "debugbreak.h" extern bool rotatesprite_2doverride; +FString C_CON_GetBoundKeyForLastInput(int gameFunc); +const char* C_CON_GetButtonFunc(int num); + BEGIN_DUKE_NS #if KRANDDEBUG @@ -55,7 +58,6 @@ BEGIN_DUKE_NS vmstate_t vm; -FString C_CON_GetBoundKeyForLastInput(int gameFunc); #if !defined LUNATIC @@ -3669,7 +3671,7 @@ badindex: VM_ASSERT((unsigned)quoteIndex < MAXQUOTES && apStrings[quoteIndex], "invalid quote %d\n", quoteIndex); VM_ASSERT((unsigned)gameFunc < NUMGAMEFUNCTIONS, "invalid function %d\n", gameFunc); - auto bindings = Bindings.GetKeysForCommand(buttonMap.GetButtonAlias(gameFunc)); + auto bindings = Bindings.GetKeysForCommand(C_CON_GetButtonFunc(gameFunc)); if ((unsigned)funcPos >= bindings.Size()) funcPos = 0; Bstrcpy(apStrings[quoteIndex], KB_ScanCodeToString(bindings[funcPos])); dispatch(); diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index 80f46e060..78491f935 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -3305,9 +3305,13 @@ MNU_DoSlider(short dir, MenuItem_p item, SWBOOL draw) case sldr_joyaxisanalog: { - const char *p; +#if 0 + const char *p; - barwidth = MNU_ControlAxisOffset(analog_maxtype); + barwidth = MNU_ControlAxisOffset(analog_maxt + + + ype); offset = slidersettings[item->slider] + dir; if (TEST(item->flags, mf_disabled)) @@ -3327,6 +3331,7 @@ MNU_DoSlider(short dir, MenuItem_p item, SWBOOL draw) while (*p != 0 && *p != '_') p++; if (*p == '_') p++; MNU_DrawSmallString(OPT_XSIDE+tilesiz[pic_slidelend].x+tilesiz[pic_sliderend].x+(barwidth+1)*tilesiz[pic_slidebar].x, item->y+4, p, 1, 16); +#endif } break; diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index 8711b1f38..4ab60ccd3 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -216,6 +216,9 @@ No files,MNU_NOFILES,,,,Žádné soubory,Keine Dateien,,Neniuj dosieroj,Sin arch ",Deseja mesmo apagar o jogo,,"Вы действительно хотите удалить сохранение ",Да ли стварно желите да избришете сачувану игру ,,,,,,,,,,,,,,,,,,,,,,, +Off,OPTVAL_OFF,,,,Vyp,Aus,,Malaktiva,Desactivado,,Pois,,,Disattivo,オフ,끔,Uit,Wyłączone,Desligado,,,Откл.,Искљ. +On,OPTVAL_ON,,,,Zap,An,,Aktiva,Activado,,Päällä,,,Attivo,オン,켬,Aan,Włączone,Ligado,,,Вкл.,Укљ. +Auto,OPTVAL_AUTO,,,,,,,Aŭtomata,Automático,,Automaattinen,,,Automatico,自動,자동,,Automatycznie,Automático,,,Авто,Аутоматски Options,OPTMNU_TITLE,,,,Možnosti,Optionen,,Agordoj,Opciones,,Asetukset,Options,Beállítások,Opzioni,オプション,설정,Opties,Opcje,Opções,,,Настройки,Подешавања Customize Controls,OPTMNU_CONTROLS,,,,Nastavení ovládání,Steuerung einstellen,,Agordi Regilojn,Personalizar Controles,,Ohjausasetukset,Modifier les Contrôles,Irányítás testreszabása,Personalizza i controlli,キー配置変更,조작 사용자 지정,Instellen van de controle,Ustaw Klawisze,Configurar Controles,Configurar Controlos,,Управление,Контроле Mouse Options,OPTMNU_MOUSE,,,,Nastavení myši,Mauseinstellungen,,Musagordoj,Opciones de Ratón,,Hiiriasetukset,Options de la Souris,Egér beállítások,Opzioni Mouse,マウス オプション,마우스 설정,Muis opties,Opcje Myszki,Opções de mouse,Opções do rato,,Мышь,Миш @@ -230,4 +233,89 @@ Display Options,OPTMNU_DISPLAY,,,,Nastavení grafiky,Anzeigeeinstellungen,,Ekran Set video mode,OPTMNU_VIDEO,,,,Nastavit režim displeje,Videomodus,,Agordi videoreĝimon,Modos de Vídeo,,Aseta videotila,Choisir Mode D'Affichage,Felbontás,Settaggio modalità video,ビデオ 調整,화면 설정,Videomodus instellen,Ustaw tryb wideo,Definir modo de vídeo,,,Видеорежим,Видео мод Reset to defaults,OPTMNU_DEFAULTS,,,,Obnovit původní,Auf Vorgaben zurücksetzen,,Reŝanĝi al defaŭltoj,Valores por Defecto,,Palauta oletusasetukset,Réinitialiser les paramètres,Alapértelmezett beállítások használata,Reimposta ai valori di default,初期設定に戻す,초기화,Terugzetten naar standaardinstellingen,Resetuj do domyślnych,Redefinir para configurações padrão,,,Сбросить все настройки,Врати подразумевано Reset to last saved,OPTMNU_RESETTOSAVED,,,,Obnovit naposledy uložené,Auf gespeicherte Werte zurücksetzen,,Reŝanĝi al lasta konservo,Últimos Valores Guardados,,Palauta viimeksi tallennettu tila,Recharger dernière config.,Legutóbbi mentett beállítások használata,Reimposta ai valori salvati l'ultima volta,最後に保存した設定に戻す,이전 설정으로 초기화,Reset naar laatste opgeslagen,Resetuj do ostatnio zapisanych,Redefinir para última configuração salva,Redefinir para última configuração gravada,,Вернуть предыдущие настройки,Врати задње сачувано -Go to console,OPTMNU_CONSOLE,,,,Jít do konzole,Öffne Konsole,,Iri al konzolo,Ir a la consola,,Mene konsoliin,Ouvrir la console,Konzol megnyitása,Vai alla console,コンソールを開く,콘솔로 이동,Ga naar de console,Przejdź do konsoli,Abrir console,Abrir consola,,Открыть консоль,Отвори конзолу \ No newline at end of file +Go to console,OPTMNU_CONSOLE,,,,Jít do konzole,Öffne Konsole,,Iri al konzolo,Ir a la consola,,Mene konsoliin,Ouvrir la console,Konzol megnyitása,Vai alla console,コンソールを開く,콘솔로 이동,Ga naar de console,Przejdź do konsoli,Abrir console,Abrir consola,,Открыть консоль,Отвори конзолу +,Controls submenu,,,,,,,,,,,,,,,,,,,,,, +"ENTER to change, BACKSPACE to clear",CNTRLMNU_SWITCHTEXT1,,,,"ENTER pro změnu, BACKSPACE pro smazání",ENTER: Editieren BACKSPACE: Löschen,,"ENTER klavo por ŝanĝi, BACKSPACE klavo por viŝi","ENTER para cambiar, BACKSPACE para limpiar",,"Aseta ENTERILLÄ, tyhjennä ASKELPALAUTTIMELLA","ENTREE pour changer, RET. ARRIERE pour effacer.","ENTER a változtatáshoz, BACKSPACE a törléshez","INVIO per modificare, BACKSPACE per ripulire",Enter で決定、BackSpaceで無効化,"바꿀려면 ENTER키, 지울려면 BACKSPACE키를 누르시오","ENTER om te veranderen, BACKSPACE om te wissen.","ENTER by zmienić, BACKSPACE by wyczyścić","ENTER para alterar, BACKSPACE para limpar",,,"ENTER — изменить, BACKSPACE — очистить","ENTER за промену, BACKSPACE за чишћење" +"Press new key for control, ESC to cancel",CNTRLMNU_SWITCHTEXT2,,,,"Zmáčkni novou klávesu pro nastavení, ESC pro storno",Drücke eine Taste oder ESC um abzubrechen,,"Premi novan klavon por reakiri regilon, ESC por nuligi","Presiona una tecla para el control, ESC para cancelar",,"Valitse näppäin toiminnolle, ESC peruuttaa","Appuyez sur la nouvelle touche pour l'assigner, +Appuyez sur ECHAP pour annuler.","Nyomj meg egy gombot, ESC a törléshez","Premi un nuovo tasto per il controllo, ESC per cancellare","登録したいキーを押すか, Escでキャンセル","명령을 얽으려면 아무 키를, 취소는 ESC키를 누르시오","Druk op de nieuwe toets voor controle, ESC om te annuleren.","Wciśnij nowy przycisk by zmienić klawisz, ESC by anulować","Aperte a nova tecla para o comando, ESC para cancelar","Carrega a nova tecla para o comando, ESC para cancelar",,"Нажмите клавишу управления, ESC для отмены","Притисните ново тастер за одређивање контроле, ESC за отказивање" +Controls,CNTRLMNU_CONTROLS,,,,Ovládání,Steuerung,,Regiloj,Controles,,Ohjaimet,Contrôles,Irányítás,Controlli,操作系統,조작,Bedieningselementen,Klawisze,Comandos,Controlos,,Управление,Контроле +Fire,CNTRLMNU_ATTACK,,,,Střelba,Feuer,,Pafi,Fuego,,Tuli,Tirer,Tűz,Fuoco,撃つ,공격,Vuur,Strzał,Atirar,,,Атака,Нападни +Secondary Fire,CNTRLMNU_ALTATTACK,,,,Sekundární střelba,Alternativfeuer,,Duaranga Pafi,Fuego secundario,,Vaihtoehtoistuli,Tir Secondaire,Másodlagos tüzelés,Fuoco secondario,セカンダリ,보조 공격,Secundaire vuur,Strzał Alternatywny,Tiro Secundário,,,Вторичная атака,Секундарни напад +Alternative Weapon,CNTRLMNU_ALTWEAPON,,,,,Alternative Waffe,,,,,,,,,,,,,,,,, +Use / Open,CNTRLMNU_USE,,,,Použít / otevřít,Benutzen / Öffnen,,Uzi / Malfermi,Usar / Abrir,,Käytä / Avaa,Utiliser/Ouvrir,Használ / Ajtónyitás,Usa / Apri,開く / スイッチ等使用,사용/열기,Gebruik / Openen,Użyj / Otwórz,Usar / Abrir,,,Использовать/открыть,Користи / Отвори +Move forward,CNTRLMNU_FORWARD,,,,Pohyb vpřed,Vorwärts bewegen,,Movi anatŭe,Avanzar,,Liiku eteenpäin,Avancer,Előre mozgás,Movimento in Avanti,前進,앞으로 이동,Voorwaarts bewegen,Idź do przodu,Mover para frente,,,Движение вперёд,Крећи се напред +Move backward,CNTRLMNU_BACK,,,,Pohyb vzad,Rückwarts bewegen,,Movi malantaŭe,Retroceder,,Liiku taaksepäin,Reculer,Hátra mozgás,Movimento in Indietro,後退,뒤로 이동,Achteruit bewegen,Idź do tyłu,Mover para trás,,,Движение назад,Крећи се уназад +Strafe left,CNTRLMNU_MOVELEFT,,,,Pohyb doleva,Nach links bewegen,,Flankmovi maldekstre,Moverse a la izquierda,,Astu sivuun vasemmalle,Aller à Gauche,Balra oldalazás,Movimento laterale a sinistra,左移動,왼쪽으로 이동,Verplaats naar links,Unik w lewo,Mover para a esquerda,,,Движение влево,Крећи се лево +Strafe right,CNTRLMNU_MOVERIGHT,,,,Pohyb doprava,Nach rechts bewegen,,Flankmovi dekstre,Moverse a la derecha,,Astu sivuun oikealle,Aller à Droite,Jobbra oldalazás,Movimento laterale a destra,右移動,오른쪽으로 이동,Verplaats naar rechts,Unik w prawo,Mover para a direita,,,Движение вправо,Крећи се десно +Turn left,CNTRLMNU_TURNLEFT,,,,Otočení vlevo,Nach links drehen,,Turni maldekstre,Girar a la izquierda,,Käänny vasemmalle,Tourner à Gauche,Balra fordul,"Gira a sinistra +",左を向く,왼쪽으로 회전,Draai naar links,Obróć się w lewo,Girar para a esquerda,,,Поворот налево,Окрени се лево +Turn right,CNTRLMNU_TURNRIGHT,,,,Otočení vpravo,Nach rechts drehen,,Turni dekstre,Girar a la derecha,,Käänny oikealle,Tourner à Droite,Jobbra fordul,Gira a destra,右を向く,오른쪽으로 회전,Draai naar rechts,Obróć się w prawo,Girar para a direita,,,Поворот направо,Окрени се десно +Quick Turn,CNTRLMNU_TURN180,,,,Rychlé otočení,Schnelle Drehung,,Rapida turno,Giro rápido,,Pikakäännös,Faire un 180,Megfordulás,Rotazione rapida,背後を向く,빠른 회전,Snelle draai,Nagły Obrót,Giro rápido,,,Быстрый разворот,Брзи окрет +Jump,CNTRLMNU_JUMP,,,,Skok,Springen,,Salti,Saltar,,Hyppää,Sauter,Ugrás,Salta,ジャンプ,점프,Springen,Skok,Pular,Saltar,,Прыжок,Скок +Crouch,CNTRLMNU_CROUCH,,,,Kleknutí,Ducken,,Kaŭri,Agacharse,,Kyyristy,S'accroupir (tenir),Guggolás,Abbassati,屈む,숙이기,Hurken,Kucnięcie,Agachar,,,Приседание,Чучни +Crouch Toggle,CNTRLMNU_TOGGLECROUCH,,,,Zap. / Vyp. kleknutí,Ducken an/aus,,Kaŭrbaskulo,Alternar agachado,,Kyyristymisen vaihtokytkin,S'accroupir (alterner),Guggolási kapcsoló,Toggle abbassamento,屈む切替,숙이기 토글,Hurken Toggle,Włącz / Wyłącz kucnięcie,Agachar (Liga/Desliga),,,Сесть/встать,Чучни (без држања) +Mouse look,CNTRLMNU_MOUSELOOK,,,,Pohled myší,Maus-Blick,,Musilregardo,Vista con ratón,,Hiirikatselu,Vue à la souris,Egérrel való nézelődés,Modalità vista col mouse,マウス視点上下化,마우스 룩,Muis-look,Rozglądanie się myszką,Vista com o mouse,Vista com o rato,,Обзор мышью,Гледај мишем +Look up,CNTRLMNU_LOOKUP,,,,Pohled vzhůru,Nach oben schauen,,Rigardi supre,Mirar arriba,,Katso ylös,Regarder en haut,Felfele nézés,Guarda sopra,視点を上げる,위로 보기,Kijk omhoog,Patrz w górę,Olhar para cima,,,Смотреть вверх,Гледај горе +Look down,CNTRLMNU_LOOKDOWN,,,,Pohled dolů,Nach unten schauen,,Rigardi malsupre,Mirar abajo,,Katso alas,Regarder en bas,Lefele nézés,Guarda sotto,視点を下げる,아래로 보기,Kijk naar beneden,Patrz w dół,Olhar para baixo,,,Смотреть вниз,Гледај доле +Center view,CNTRLMNU_CENTERVIEW,,,Centre view,Vystředit pohled,Ansicht zentrieren,,Centra vidon,Centrar vista,,Keskitä katse,Recentrer Vue,Nézet középreigazítása,Sguardo centrato,視点を戻す,중앙 시점으로 보기,Middenaanzicht,Wyśrodkuj widok,Olhar para o centro,,,Отцентрировать взгляд,Централизирај поглед +Run,CNTRLMNU_RUN,,,,Běh,Rennen,,Kuri,Correr,,Juokse,Courir (tenir),Futás,Corri,駆け足,달리기,Rennen,Bieg,Correr,,,Бег,Трчи +Toggle Run,CNTRLMNU_TOGGLERUN,,,,Zap. / Vyp. běh,Rennen an/aus,,Baskulkuri,Alternar Correr,,Juoksun vaihtokytkin,Courir (alterner),Futás kapcsoló,Toggle corsa,常時駆け足切替,달리기 토글,Rennen aan/uit,Włącz / Wyłącz bieg,Correr (Liga/Desliga),,,Бежать/идти,Трчи (без држања) +Strafe,CNTRLMNU_STRAFE,,,,Pohyb vlevo/vpravo,Seitwärts,,Flankmovi,Desplazamiento,,Astu sivuttain,Pas de côté,,Spostamento laterale,横移動化,양옆으로 이동,Zijdelings bewegen,Uniki,Deslocamento lateral,,,Движение боком,Кретање у страну +Show Scoreboard,CNTRLMNU_SCOREBOARD,,,,Zobrazit tabulku skóre,Punktetafel anzeigen,,Montri poentartabulon,Mostrar Marcador,,Näytä pistetaulu,Afficher Scores (tenir),Eredményjelző megjelenítése,Mostra la tabella punteggio,スコアボード表示,점수창 표시,Scorebord tonen,Pokaż tablicę wyników,Mostrar pontuação,,,Таблица очков,Табела +Action,CNTRLMNU_ACTION,,,,Akce,Aktion,,Ago,Acción,,Toiminta,,Akció,Azione,アクション,동작,Actie,Akcja,Ação,,,Основное,Радња +Customize Action Controls,CNTRLMNU_ACTION_TITLE,,,,Nastavit ovládání akcí,Aktions-Steuerung einstellen,,Agordi Agajn Regilojn,Controles de Acción,,Toimintaohjausasetukset,Changer Contrôles Action,Akció beállítások testreszabása,Personalizza i controlli di azione,アクション操作設定,사용자 지정 동작 컨트롤,Aanpassen van de actiecontroles,Ustaw Klawisze Akcji,Configurar Comandos de Ação,Configurar Controlos de Ação,,Основные клавиши управления,Контроле радње +Say,CNTRLMNU_SAY,,,,Říct,Reden,,Diro,Hablar,,Sano,Parler,Üzenet ,Parla,発言,채팅하기,Zeg,Powiedz,Fala,Falar,,Сообщение,Пиши +Customize Chat Controls,CNTRLMNU_CHAT_TITLE,,,,Nastavit ovládání chatu,Chat-Steuerung einstellen,,Agordi Babiladajn Regilojn,Controles de Chat,,Keskusteluohjausasetukset,Changer Contrôles Chat,Chat beállítások testreszabása,Personalizza i controlli della chat,チャット操作設定,사용자 지정 채팅 컨트롤,Chat-controles aanpassen aan uw wensen,Ustaw Klawisze Czatu,Configurar Comandos de Chat,Configurar Controlos de Chat,,Клавиши управления чатом,Контроле ћаскања +Customize Weapon Controls,CNTRLMNU_WEAPONS_TITLE,,,,Nastavit ovládání zbraní,Waffen-Steuerung einstellen,,Agordi Armilojn Regilojn,Controles de Armas,,Aseohjausasetukset,Changer Contrôles Armes,Fegyver beállítások testreszabása,Personalizza i controlli delle armi,武器操作設定,사용자 지정 무기 컨트롤,Wapencontroles aanpassen aan uw eigen wensen,Ustaw Klawisze Broni,Configurar Comandos de Arma,Configurar Controlos de Armas,,Клавиши управления оружием,Контроле оружја +Customize Inventory Controls,CNTRLMNU_INVENTORY_TITLE,,,,Nastavit ovládání inventáře,Inventar-Steuerung einstellen,,Agordi Inventarajn Regilojn,Controles de Inventario,,Varusteohjausasetukset,Changer Contrôles Inventaires,Eszköztár beállítások testreszabása,Personalizza i controlli dell'inventario,インベントリ操作設定,사용자 지정 인벤토리 컨트롤,Inventariscontroles aanpassen aan uw wensen,Ustaw Klawisze Ekwipunku,Configurar Comandos de Inventário,Configurar Controlos de Inventário,,Клавиши управления инвентарём,Контроле складишта +Customize Other Controls,CNTRLMNU_OTHER_TITLE,,,,Nastavit ostatní ovládání,Sonstige Steuerung einstellen,,Agordi Ekstrajn Regilojn,Otros Controles,,Muut ohjausasetukset,Changer Autres Contrôles,Egyéb irányítás testreszabása,Personalizza altri controlli,その他の操作設定,사용자 지정 그 외 컨트롤,Andere bedieningselementen aanpassen,Ustaw Inne Klawisze,Configurar Outros Comandos,Configurar Outros Controlos,,Прочие клавиши,Друге контроле +Weapons,CNTRLMNU_WEAPONS,,,,Zbraně,Waffen,,Armiloj,Armas,,Aseet,Armes,Fegyverek,Armi,武器,무기,Wapens,Bronie,Armas,,,Оружие,Оружје +Next weapon,CNTRLMNU_NEXTWEAPON,,,,Další zbraň,Nächste Waffe,,Proksima armilo,Arma siguiente,,Seuraava ase,Arme Suivante,Következő fegyver,Arma successiva,次の武器,다음 무기,Volgende wapen,Następna broń,Próxima arma,,,Следующее оружие,Следеће оружје +Previous weapon,CNTRLMNU_PREVIOUSWEAPON,,,,Předchozí zbraň,Vorherige Waffe,,Antaŭa armilo,Arma anterior,,Edellinen ase,Arme Précédente,Előző fegyver,Arma precedente,前の武器,이전 무기,Vorige wapen,Poprzednia broń,Arma anterior,,,Предыдущее оружие,Претходно оружје +Weapon 1,CNTRLMNU_SLOT1,Todo - make game specific,,,Slot zbraně 1,Waffe 1,,Armingo 1,Ranura de Arma 1,,Aselokero 1,Emplacement D'Arme 1,1. Fegyver,Slot arma 1,武器スロット 1,무기 슬롯 1,Wapenslot 1,Broń 1,Arma 1,,,Оружие 1,Оружје 1 +Weapon 2,CNTRLMNU_SLOT2,"only show appropriate slots per game +",,,Slot zbraně 2,Waffe 2,,Armingo 2,Ranura de Arma 2,,Aselokero 2,Emplacement D'Arme 2,2. Fegyver,Slot arma 2,武器スロット 2,무기 슬롯 2,Wapenslot 2,Broń 2,Arma 2,,,Оружие 2,Оружје 2 +Weapon 3,CNTRLMNU_SLOT3,,,,Slot zbraně 3,Waffe 3,,Armingo 3,Ranura de Arma 3,,Aselokero 3,Emplacement D'Arme 3,3. Fegyver,Slot arma 3,武器スロット 3,무기 슬롯 3,Wapenslot 3,Broń 3,Arma 3,,,Оружие 3,Оружје 3 +Weapon 4,CNTRLMNU_SLOT4,,,,Slot zbraně 4,Waffe 4,,Armingo 4,Ranura de Arma 4,,Aselokero 4,Emplacement D'Arme 4,4. Fegyver,Slot arma 4,武器スロット 4,무기 슬롯 4,Wapenslot 4,Broń 4,Arma 4,,,Оружие 4,Оружје 4 +Weapon 5,CNTRLMNU_SLOT5,,,,Slot zbraně 5,Waffe 5,,Armingo 5,Ranura de Arma 5,,Aselokero 5,Emplacement D'Arme 5,5. Fegyver,Slot arma 5,武器スロット 5,무기 슬롯 5,Wapenslot 5,Broń 5,Arma 5,,,Оружие 5,Оружје 5 +Weapon 6,CNTRLMNU_SLOT6,,,,Slot zbraně 6,Waffe 6,,Armingo 6,Ranura de Arma 6,,Aselokero 6,Emplacement D'Arme 6,6. Fegyver,Slot arma 6,武器スロット 6,무기 슬롯 6,Wapenslot 6,Broń 6,Arma 6,,,Оружие 6,Оружје 6 +Weapon 7,CNTRLMNU_SLOT7,,,,Slot zbraně 7,Waffe 7,,Armingo 7,Ranura de Arma 7,,Aselokero 7,Emplacement D'Arme 7,7. Fegyver,Slot arma 7,武器スロット 7,무기 슬롯 7,Wapenslot 7,Broń 7,Arma 7,,,Оружие 7,Оружје 7 +Weapon 8,CNTRLMNU_SLOT8,,,,Slot zbraně 8,Waffe 8,,Armingo 8,Ranura de Arma 8,,Aselokero 8,Emplacement D'Arme 8,8. Fegyver,Slot arma 8,武器スロット 8,무기 슬롯 8,Wapenslot 8,Broń 8,Arma 8,,,Оружие 8,Оружје 8 +Weapon 9,CNTRLMNU_SLOT9,,,,Slot zbraně 9,Waffe 9,,Armingo 9,Ranura de Arma 9,,Aselokero 9,Emplacement D'Arme 9,9. Fegyver,Slot arma 9,武器スロット 9,무기 슬롯 9,Wapenslot 9,Broń 9,Arma 9,,,Оружие 9,Оружје 9 +Weapon 10,CNTRLMNU_SLOT0,,,,Slot zbraně 10,Waffe 10,,Armingo 0,Ranura de Arma 0,,Aselokero 0,Emplacement D'Arme 0,0. Fegyver,Slot arma 0,武器スロット 0,무기 슬롯 0,Wapenslot 0,Broń 10,Arma 0,,,Оружие 0,Оружје 0 +Inventory,CNTRLMNU_INVENTORY,,,,Inventář,Inventar,,Inventaro,Inventario,,Varusteet,Inventaire,Eszköztár beállítások testreszabása,Inventario,所持品,인벤토리,Inventaris,Ekwipunek,Inventário,,,Инвентарь,Инвентар +Activate item,CNTRLMNU_USEITEM,,,,Aktivovat předmět,Gegenstand aktivieren,,Aktivigi aĵon,Activar objeto,,Aktivoi varuste,Activer objet,Eszköz használata,Attiva oggetto,アイテムを使用,선택한 아이템 사용,Item activeren,Użyj przedmiot,Ativar item,,,Использовать предмет,Активирај предмет +Activate all items,CNTRLMNU_USEALLITEMS,,,,Aktivovat všechny předměty,Alle Gegenstände aktivieren,,Aktivigi ĉiuj aĵojn,Activar todos los objetos,,Aktivoi kaikki varusteet,Activer tous les objets,Minden eszköz használata,Attiva tutti gli oggetti,全てのアイテムを使用,모든 아이템 사용,Activeer alle items,Użyj wszystkie przedmioty,Ativar todos os itens,,,Использовать все предметы,Активирај све предмете +Next item,CNTRLMNU_NEXTITEM,,,,Další předmět,Nächster Gegenstand,,Proksima aĵo,Objeto siguiente,,Seuraava varuste,Objet suivant,Következő eszköz,Oggetto successivo,次のアイテム,다음 아이템,Volgende item,Następny przedmiot,Próximo item,,,Следующий предмет,Следећи предмет +Previous item,CNTRLMNU_PREVIOUSITEM,,,,Předchozí předmět,Vorheriger Gegenstand,,Antaŭa aĵo,Objeto anterior,,Edellinen varuste,Objet précédent,Előző eszköz,Oggetto precedente,前のアイテム,이전 아이템,Vorige item,Poprzedni przedmiot,Item anterior,,,Предыдущий предмет,Претходни предмет +Holster Weapon,CNTRLMNU_HOLSTER,,,,,Waffe wegstecken,,,,,,,,,,,,,,,,, +Quick Kick,CNTRLMNU_QUICKKICK,,,,,Schneller Tritt,,,,,,,,,,,,,,,,, +Pee,CNTRLMNU_PEE,,,,,Pinkeln,,,,,,,,,,,,,,,,, +Proximity Bomb,CNTRLMNU_PROXIMITYBOMBS,,,,,,,,,,,,,,,,,,,,,, +Remote Bomb,CNTRLMNU_REMOTEBOMBS,,,,,,,,,,,,,,,,,,,,,, +Smoke Bomb,CNTRLMNU_SMOKEBOMB,,,,,Rauchbombe,,,,,,,,,,,,,,,,, +Gas Bomb,CNTRLMNU_GASBOMB,,,,,Gasgranate,,,,,,,,,,,,,,,,, +Flash Bomb,"CNTRLMNU_FLASHBOMB +",,,,,Blendgranate,,,,,,,,,,,,,,,,, +Caltrops,CNTRLMNU_CALTROPS,,,,,Krähenfüße,,,,,,,,,,,,,,,,, +Holo Duke,CNTRLMNU_HOLODUKE,,,,,,,,,,,,,,,,,,,,,, +Jetpack,CNTRLMNU_JETPACK,,,,,,,,,,,,,,,,,,,,,, +Night Vision,CNTRLMNU_NIGHTVISION,,,,,Nachtsichtgerät,,,,,,,,,,,,,,,,, +Medkit,CNTRLMNU_MEDKIT,,,,,,,,,,,,,,,,,,,,,, +Steroids,CNTRLMNU_STEROIDS,,,,,Steroide,,,,,,,,,,,,,,,,, +Holo Soldier,CNTRLMNU_HOLOSOLDIER,,,,,Holosoldat,,,,,,,,,,,,,,,,, +Huey,CNTRLMNU_HUEY,,,,,,,,,,,,,,,,,,,,,, +Bier,CNTRLMNU_BEER,,,,,Bier,,,,,,,,,,,,,,,,, +Cow Pie,CNTRLMNU_COWPIE,not translatable,,,,,,,,,,,,,,,,,,,,, +Yeehaa,CNTRLMNU_YEEHAA,not translatable,,,,,,,,,,,,,,,,,,,,, +Whiskey,CNTRLMNU_WHISKEY,,,,,Whisky,,,,,,,,,,,,,,,,, +Moonshine,CNTRLMNU_MOONSHINE,,,,,Schwarzgebrannter,,,,,,,,,,,,,,,,, +Crystal Ball,CNTRLMNU_CRYSTALBALL,,,,,Kristallkugel,,,,,,,,,,,,,,,,, +Jump Boots,CNTRLMNU_JUMPBOOTS,,,,,Sprungstiefel,,,,,,,,,,,,,,,,, +Beast Vision,CNTRLMNU_BEASTVISION,,,,,,,,,,,,,,,,,,,,,, +Tank Mode,CNTRLMNU_TANKMODE,,,,,Panzermodus,,,,,,,,,,,,,,,,, +Smokes,CNTRLMNU_SMOKES,What precisely is this?,,,,,,,,,,,,,,,,,,,,, +Fire Mission,CNTRLMNU_FIREMISSION,,,,,,,,,,,,,,,,,,,,,, +Reload,CNTRLMENU_RELOAD,,,,,"Waffe laden +",,,,,,,,,,,,,,,,, +Radar,CNTRLMENU_RADAR,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file From 026cc7153c5edb282fdbdd2541d0646768df6cfd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 2 Dec 2019 18:33:11 +0100 Subject: [PATCH 085/203] - externalized the controller bindings and removed all code responsible for maintaining them separately. Bindings were changed a bit because what was there was a very poor default for my own controller. --- source/common/console/c_con.cpp | 1 + source/common/gamecontrol.cpp | 117 ------------------ source/common/gamecontrol.h | 2 - wadsrc/static/demolition/commonbinds.txt | 14 +++ .../filter/ionfury/demolition/defbinds.txt | 5 +- .../filter/ionfury/demolition/origbinds.txt | 5 +- 6 files changed, 23 insertions(+), 121 deletions(-) diff --git a/source/common/console/c_con.cpp b/source/common/console/c_con.cpp index 09b14a506..d8ff9d529 100644 --- a/source/common/console/c_con.cpp +++ b/source/common/console/c_con.cpp @@ -37,6 +37,7 @@ #include "basics.h" #include "zstring.h" #include "c_bind.h" +#include "control.h" #include "gamecontrol.h" //============================================================================= diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index 96fbbc2b6..b086ab39a 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -411,7 +411,6 @@ int CONFIG_Init() CONTROL_ClearAssignments(); CONFIG_InitMouseAndController(); - CONFIG_SetGameControllerDefaultsStandard(); CONFIG_SetDefaultKeys(cl_defaultconfiguration == 1 ? "demolition/origbinds.txt" : cl_defaultconfiguration == 2 ? "demolition/leftbinds.txt" : "demolition/defbinds.txt"); G_ReadConfig(currentGame); @@ -721,122 +720,6 @@ static void CONFIG_SetGameControllerAxesModern() analogAxis.apply(); } -void CONFIG_SetGameControllerDefaultsStandard() -{ - CONFIG_SetGameControllerDefaultsClear(); - CONFIG_SetGameControllerAxesModern(); - - static GameControllerButtonSetting const buttons[] = - { - { GAMECONTROLLER_BUTTON_A, gamefunc_Jump }, - { GAMECONTROLLER_BUTTON_B, gamefunc_Toggle_Crouch }, - { GAMECONTROLLER_BUTTON_BACK, gamefunc_Map }, - { GAMECONTROLLER_BUTTON_LEFTSTICK, gamefunc_Run }, - { GAMECONTROLLER_BUTTON_RIGHTSTICK, gamefunc_Quick_Kick }, - { GAMECONTROLLER_BUTTON_LEFTSHOULDER, gamefunc_Crouch }, - { GAMECONTROLLER_BUTTON_RIGHTSHOULDER, gamefunc_Jump }, - { GAMECONTROLLER_BUTTON_DPAD_UP, gamefunc_Previous_Weapon }, - { GAMECONTROLLER_BUTTON_DPAD_DOWN, gamefunc_Next_Weapon }, - }; - - static GameControllerButtonSetting const buttonsDuke[] = - { - { GAMECONTROLLER_BUTTON_X, gamefunc_Open }, - { GAMECONTROLLER_BUTTON_Y, gamefunc_Inventory }, - { GAMECONTROLLER_BUTTON_DPAD_LEFT, gamefunc_Inventory_Left }, - { GAMECONTROLLER_BUTTON_DPAD_RIGHT, gamefunc_Inventory_Right }, - }; - - static GameControllerButtonSetting const buttonsFury[] = - { - { GAMECONTROLLER_BUTTON_X, gamefunc_Steroids }, // Reload - { GAMECONTROLLER_BUTTON_Y, gamefunc_Open }, - { GAMECONTROLLER_BUTTON_DPAD_LEFT, gamefunc_MedKit }, - { GAMECONTROLLER_BUTTON_DPAD_RIGHT, gamefunc_NightVision }, // Radar - }; - - static GameControllerDigitalAxisSetting const digitalAxes[] = - { - { GAMECONTROLLER_AXIS_TRIGGERLEFT, 1, gamefunc_Alt_Fire }, - { GAMECONTROLLER_AXIS_TRIGGERRIGHT, 1, gamefunc_Fire }, - }; - - for (auto const& button : buttons) - button.apply(); - - if (g_gameType & GAMEFLAG_FURY) - { - for (auto const& button : buttonsFury) - button.apply(); - } - else - { - for (auto const& button : buttonsDuke) - button.apply(); - } - - for (auto const& digitalAxis : digitalAxes) - digitalAxis.apply(); -} - -void CONFIG_SetGameControllerDefaultsPro() -{ - CONFIG_SetGameControllerDefaultsClear(); - CONFIG_SetGameControllerAxesModern(); - - static GameControllerButtonSetting const buttons[] = - { - { GAMECONTROLLER_BUTTON_A, gamefunc_Open }, - { GAMECONTROLLER_BUTTON_B, gamefunc_Third_Person_View }, - { GAMECONTROLLER_BUTTON_Y, gamefunc_Quick_Kick }, - { GAMECONTROLLER_BUTTON_BACK, gamefunc_Map }, - { GAMECONTROLLER_BUTTON_LEFTSTICK, gamefunc_Run }, - { GAMECONTROLLER_BUTTON_RIGHTSTICK, gamefunc_Crouch }, - { GAMECONTROLLER_BUTTON_DPAD_UP, gamefunc_Previous_Weapon }, - { GAMECONTROLLER_BUTTON_DPAD_DOWN, gamefunc_Next_Weapon }, - }; - - static GameControllerButtonSetting const buttonsDuke[] = - { - { GAMECONTROLLER_BUTTON_X, gamefunc_Inventory }, - { GAMECONTROLLER_BUTTON_LEFTSHOULDER, gamefunc_Previous_Weapon }, - { GAMECONTROLLER_BUTTON_RIGHTSHOULDER, gamefunc_Next_Weapon }, - { GAMECONTROLLER_BUTTON_DPAD_LEFT, gamefunc_Inventory_Left }, - { GAMECONTROLLER_BUTTON_DPAD_RIGHT, gamefunc_Inventory_Right }, - }; - - static GameControllerButtonSetting const buttonsFury[] = - { - { GAMECONTROLLER_BUTTON_X, gamefunc_Steroids }, // Reload - { GAMECONTROLLER_BUTTON_LEFTSHOULDER, gamefunc_Crouch }, - { GAMECONTROLLER_BUTTON_RIGHTSHOULDER, gamefunc_Alt_Fire }, - { GAMECONTROLLER_BUTTON_DPAD_LEFT, gamefunc_MedKit }, - { GAMECONTROLLER_BUTTON_DPAD_RIGHT, gamefunc_NightVision }, // Radar - }; - - static GameControllerDigitalAxisSetting const digitalAxes[] = - { - { GAMECONTROLLER_AXIS_TRIGGERLEFT, 1, gamefunc_Jump }, - { GAMECONTROLLER_AXIS_TRIGGERRIGHT, 1, gamefunc_Fire }, - }; - - for (auto const& button : buttons) - button.apply(); - - if (g_gameType & GAMEFLAG_FURY) - { - for (auto const& button : buttonsFury) - button.apply(); - } - else - { - for (auto const& button : buttonsDuke) - button.apply(); - } - - for (auto const& digitalAxis : digitalAxes) - digitalAxis.apply(); -} void CONFIG_InitMouseAndController() diff --git a/source/common/gamecontrol.h b/source/common/gamecontrol.h index 740f3de80..b699693d8 100644 --- a/source/common/gamecontrol.h +++ b/source/common/gamecontrol.h @@ -42,8 +42,6 @@ void CONFIG_SetupJoystick(void); void CONFIG_WriteControllerSettings(); void CONFIG_InitMouseAndController(); -void CONFIG_SetGameControllerDefaultsStandard(); -void CONFIG_SetGameControllerDefaultsPro(); void CONFIG_SetGameControllerDefaultsClear(); extern FStringCVar* const CombatMacros[]; diff --git a/wadsrc/static/demolition/commonbinds.txt b/wadsrc/static/demolition/commonbinds.txt index 1ca90ecac..f96323051 100644 --- a/wadsrc/static/demolition/commonbinds.txt +++ b/wadsrc/static/demolition/commonbinds.txt @@ -63,3 +63,17 @@ K "+See_Coop_View" Mouse1 "+Fire" MWheelUp "+Previous_Weapon" MWheelDown "+Next_Weapon" + +Pad_A "+Fire" +Pad_B "+Toggle_Crouch" // fixme: not yet supported by all games +Pad_Back "+Map" +LTrigger "+Run" +RTrigger "+Quick_Kick" +LShoulder "+Crouch" +RShoulder "+Jump" +DPadUp "+Previous_Weapon" +DPadDown "+Next_Weapon" +Pad_X "+Open" +Pad_Y "+Inventory" +DPadLeft "+Inventory_Left" +DPadRight "+Inventory_Right" diff --git a/wadsrc/static/filter/ionfury/demolition/defbinds.txt b/wadsrc/static/filter/ionfury/demolition/defbinds.txt index 1aba205c4..f0e5627be 100644 --- a/wadsrc/static/filter/ionfury/demolition/defbinds.txt +++ b/wadsrc/static/filter/ionfury/demolition/defbinds.txt @@ -1,5 +1,8 @@ // X "+Last_Used_Weapon" C "+Toggle_Crouch" -Mouse2 "+Jetpack" +Mouse2 "+Steroids" Mouse3 "+MediKit" +Pad_Y "+Steroids" +DPadLeft "+MedKit" +DPadRight "+Nightvision" diff --git a/wadsrc/static/filter/ionfury/demolition/origbinds.txt b/wadsrc/static/filter/ionfury/demolition/origbinds.txt index c3ac394e8..dcd40b932 100644 --- a/wadsrc/static/filter/ionfury/demolition/origbinds.txt +++ b/wadsrc/static/filter/ionfury/demolition/origbinds.txt @@ -1,3 +1,6 @@ W "+Show_Opponents_Weapon" -Mouse2 "+Jetpack" +Mouse2 "+Steroids" Mouse3 "+MediKit" +Pad_Y "+Steroids" +DPadLeft "+MedKit" +DPadRight "+Nightvision" From bc3a921a7298c762961973b752b2f36b52197d3e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 2 Dec 2019 19:21:45 +0100 Subject: [PATCH 086/203] - fixed newly added menu content. --- source/common/menu/menudef.cpp | 44 +++++++++++++++++++++++++++ source/common/menu/optionmenu.cpp | 2 +- wadsrc/static/demolition/language.csv | 9 ++++-- wadsrc/static/demolition/menudef.txt | 24 +++++++-------- 4 files changed, 63 insertions(+), 16 deletions(-) diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 4c88ae577..e6b737fa2 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -232,6 +232,26 @@ static bool CheckSkipOptionBlock(FScanner &sc) // //============================================================================= +static bool CheckSkipNoSwBlock(FScanner& sc) +{ + sc.MustGetStringName("("); + sc.MustGetString(); + bool res = sc.Compare("true"); + sc.MustGetStringName(")"); + if ((!!(g_gameType & GAMEFLAG_SHAREWARE)) == res) + { + SkipSubBlock(sc); + return !sc.CheckString("else"); + } + return false; +} + +//============================================================================= +// +// +// +//============================================================================= + static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) { sc.MustGetStringName("{"); @@ -258,6 +278,14 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) ParseListMenuBody(sc, desc); } } + else if (sc.Compare("ifshareware")) + { + if (!CheckSkipNoSwBlock(sc)) + { + // recursively parse sub-block + ParseListMenuBody(sc, desc); + } + } else if (sc.Compare("Class")) { sc.MustGetString(); @@ -572,6 +600,14 @@ static void ParseImageScrollerBody(FScanner &sc, FImageScrollerDescriptor *desc) ParseImageScrollerBody(sc, desc); } } + else if (sc.Compare("ifshareware")) + { + if (!CheckSkipNoSwBlock(sc)) + { + // recursively parse sub-block + ParseImageScrollerBody(sc, desc); + } + } else if (sc.Compare("ifoption")) { if (!CheckSkipOptionBlock(sc)) @@ -781,6 +817,14 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) ParseOptionMenuBody(sc, desc); } } + else if (sc.Compare("ifshareware")) + { + if (!CheckSkipNoSwBlock(sc)) + { + // recursively parse sub-block + ParseOptionMenuBody(sc, desc); + } + } else if (sc.Compare("ifoption")) { if (!CheckSkipOptionBlock(sc)) diff --git a/source/common/menu/optionmenu.cpp b/source/common/menu/optionmenu.cpp index 946a3ea8d..a7dbf2cf8 100644 --- a/source/common/menu/optionmenu.cpp +++ b/source/common/menu/optionmenu.cpp @@ -71,7 +71,7 @@ int OptionWidth(const char * s) void DrawOptionText(int x, int y, int color, const char *text, bool grayed) { PalEntry overlay = grayed? PalEntry(96,48,0,0) : PalEntry(0,0,0); - DrawText (&twod, OptionFont(), color, x, y, text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay); + DrawText (&twod, OptionFont(), color, x, y, text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_END); } //============================================================================= diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index 4ab60ccd3..53ee61c61 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -235,6 +235,7 @@ Reset to defaults,OPTMNU_DEFAULTS,,,,Obnovit původní,Auf Vorgaben zurücksetze Reset to last saved,OPTMNU_RESETTOSAVED,,,,Obnovit naposledy uložené,Auf gespeicherte Werte zurücksetzen,,Reŝanĝi al lasta konservo,Últimos Valores Guardados,,Palauta viimeksi tallennettu tila,Recharger dernière config.,Legutóbbi mentett beállítások használata,Reimposta ai valori salvati l'ultima volta,最後に保存した設定に戻す,이전 설정으로 초기화,Reset naar laatste opgeslagen,Resetuj do ostatnio zapisanych,Redefinir para última configuração salva,Redefinir para última configuração gravada,,Вернуть предыдущие настройки,Врати задње сачувано Go to console,OPTMNU_CONSOLE,,,,Jít do konzole,Öffne Konsole,,Iri al konzolo,Ir a la consola,,Mene konsoliin,Ouvrir la console,Konzol megnyitása,Vai alla console,コンソールを開く,콘솔로 이동,Ga naar de console,Przejdź do konsoli,Abrir console,Abrir consola,,Открыть консоль,Отвори конзолу ,Controls submenu,,,,,,,,,,,,,,,,,,,,,, +Customize Controls,CNTRLMNU_TITLE,,,,Nastavení ovládání,Steuerung einstellen,,Agordi Regilojn,Personalizar Controles ,,Ohjausasetukset,Modifier contrôles,Irányítás testreszabása,Personalizza i controlli,キー配置変更,조작 사용자 지정,Instellen van de controle,Ustaw Klawisze,Configurar Controles,Configurar Controlos,,Настройки управления,Подешавања контрола "ENTER to change, BACKSPACE to clear",CNTRLMNU_SWITCHTEXT1,,,,"ENTER pro změnu, BACKSPACE pro smazání",ENTER: Editieren BACKSPACE: Löschen,,"ENTER klavo por ŝanĝi, BACKSPACE klavo por viŝi","ENTER para cambiar, BACKSPACE para limpiar",,"Aseta ENTERILLÄ, tyhjennä ASKELPALAUTTIMELLA","ENTREE pour changer, RET. ARRIERE pour effacer.","ENTER a változtatáshoz, BACKSPACE a törléshez","INVIO per modificare, BACKSPACE per ripulire",Enter で決定、BackSpaceで無効化,"바꿀려면 ENTER키, 지울려면 BACKSPACE키를 누르시오","ENTER om te veranderen, BACKSPACE om te wissen.","ENTER by zmienić, BACKSPACE by wyczyścić","ENTER para alterar, BACKSPACE para limpar",,,"ENTER — изменить, BACKSPACE — очистить","ENTER за промену, BACKSPACE за чишћење" "Press new key for control, ESC to cancel",CNTRLMNU_SWITCHTEXT2,,,,"Zmáčkni novou klávesu pro nastavení, ESC pro storno",Drücke eine Taste oder ESC um abzubrechen,,"Premi novan klavon por reakiri regilon, ESC por nuligi","Presiona una tecla para el control, ESC para cancelar",,"Valitse näppäin toiminnolle, ESC peruuttaa","Appuyez sur la nouvelle touche pour l'assigner, Appuyez sur ECHAP pour annuler.","Nyomj meg egy gombot, ESC a törléshez","Premi un nuovo tasto per il controllo, ESC per cancellare","登録したいキーを押すか, Escでキャンセル","명령을 얽으려면 아무 키를, 취소는 ESC키를 누르시오","Druk op de nieuwe toets voor controle, ESC om te annuleren.","Wciśnij nowy przycisk by zmienić klawisz, ESC by anulować","Aperte a nova tecla para o comando, ESC para cancelar","Carrega a nova tecla para o comando, ESC para cancelar",,"Нажмите клавишу управления, ESC для отмены","Притисните ново тастер за одређивање контроле, ESC за отказивање" @@ -264,6 +265,7 @@ Strafe,CNTRLMNU_STRAFE,,,,Pohyb vlevo/vpravo,Seitwärts,,Flankmovi,Desplazamient Show Scoreboard,CNTRLMNU_SCOREBOARD,,,,Zobrazit tabulku skóre,Punktetafel anzeigen,,Montri poentartabulon,Mostrar Marcador,,Näytä pistetaulu,Afficher Scores (tenir),Eredményjelző megjelenítése,Mostra la tabella punteggio,スコアボード表示,점수창 표시,Scorebord tonen,Pokaż tablicę wyników,Mostrar pontuação,,,Таблица очков,Табела Action,CNTRLMNU_ACTION,,,,Akce,Aktion,,Ago,Acción,,Toiminta,,Akció,Azione,アクション,동작,Actie,Akcja,Ação,,,Основное,Радња Customize Action Controls,CNTRLMNU_ACTION_TITLE,,,,Nastavit ovládání akcí,Aktions-Steuerung einstellen,,Agordi Agajn Regilojn,Controles de Acción,,Toimintaohjausasetukset,Changer Contrôles Action,Akció beállítások testreszabása,Personalizza i controlli di azione,アクション操作設定,사용자 지정 동작 컨트롤,Aanpassen van de actiecontroles,Ustaw Klawisze Akcji,Configurar Comandos de Ação,Configurar Controlos de Ação,,Основные клавиши управления,Контроле радње +Chat,CNTRLMNU_CHAT,,,,Chat,Chat,,Babilo,Chat,,Keskustelu,Chat,Chat,Chat,チャット,채팅,Chat,Czat,Chat,Conversar,,Чат,Ћаскање Say,CNTRLMNU_SAY,,,,Říct,Reden,,Diro,Hablar,,Sano,Parler,Üzenet ,Parla,発言,채팅하기,Zeg,Powiedz,Fala,Falar,,Сообщение,Пиши Customize Chat Controls,CNTRLMNU_CHAT_TITLE,,,,Nastavit ovládání chatu,Chat-Steuerung einstellen,,Agordi Babiladajn Regilojn,Controles de Chat,,Keskusteluohjausasetukset,Changer Contrôles Chat,Chat beállítások testreszabása,Personalizza i controlli della chat,チャット操作設定,사용자 지정 채팅 컨트롤,Chat-controles aanpassen aan uw wensen,Ustaw Klawisze Czatu,Configurar Comandos de Chat,Configurar Controlos de Chat,,Клавиши управления чатом,Контроле ћаскања Customize Weapon Controls,CNTRLMNU_WEAPONS_TITLE,,,,Nastavit ovládání zbraní,Waffen-Steuerung einstellen,,Agordi Armilojn Regilojn,Controles de Armas,,Aseohjausasetukset,Changer Contrôles Armes,Fegyver beállítások testreszabása,Personalizza i controlli delle armi,武器操作設定,사용자 지정 무기 컨트롤,Wapencontroles aanpassen aan uw eigen wensen,Ustaw Klawisze Broni,Configurar Comandos de Arma,Configurar Controlos de Armas,,Клавиши управления оружием,Контроле оружја @@ -315,7 +317,8 @@ Jump Boots,CNTRLMNU_JUMPBOOTS,,,,,Sprungstiefel,,,,,,,,,,,,,,,,, Beast Vision,CNTRLMNU_BEASTVISION,,,,,,,,,,,,,,,,,,,,,, Tank Mode,CNTRLMNU_TANKMODE,,,,,Panzermodus,,,,,,,,,,,,,,,,, Smokes,CNTRLMNU_SMOKES,What precisely is this?,,,,,,,,,,,,,,,,,,,,, -Fire Mission,CNTRLMNU_FIREMISSION,,,,,,,,,,,,,,,,,,,,,, -Reload,CNTRLMENU_RELOAD,,,,,"Waffe laden +Fire Mission,CNTRLMNU_FIRE_MISSION,,,,,,,,,,,,,,,,,,,,,, +Reload,CNTRLMNU_RELOAD,,,,,"Waffe laden ",,,,,,,,,,,,,,,,, -Radar,CNTRLMENU_RADAR,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file +Radar,CNTRLMNU_RADAR,,,,,,,,,,,,,,,,,,,,,, +Other,CNTRLMNU_OTHER,,,,Ostatní,Andere,,Alia,Otros,,Muu,Autres,Más,Altro,その他,그 외 조작,Andere,Inne,Outro,,,Прочее,Остало \ No newline at end of file diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 74508b7f6..adbfad988 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -433,7 +433,7 @@ ImageScroller "HelpMenu" { // The menu has no default binding, but if someone tries to open it anyway show the cool retro ads that were shipped with the game. :D ImageItem "#5262" - ifnotshareware + ifshareware(false) { ImageItem "#5261" } @@ -537,7 +537,7 @@ ImageScroller "CreditsMenu" } ifgame(ShadowWarrior) { - ifshareware + ifshareware(true) { ImageItem "#5110" ImageItem "#5112" @@ -648,7 +648,7 @@ OptionMenu "OptionsMenu" // //------------------------------------------------------------------------------------------- -OptionMenu "CustomizeControls" protected +OptionMenu "CustomizeControls"// protected { Title "$CNTRLMNU_TITLE" @@ -660,7 +660,7 @@ OptionMenu "CustomizeControls" protected //Submenu "$MAPCNTRLMNU_CONTROLS" , "MapControlsMenu" // todo after thorough cleanup } -OptionMenu "ActionControlsMenu" protected +OptionMenu "ActionControlsMenu"// protected { Title "$CNTRLMNU_ACTION_TITLE" ScrollTop 2 @@ -715,7 +715,7 @@ OptionMenu "ActionControlsMenu" protected Control "$CNTRLMNU_SCOREBOARD" , "+show_dukematch_scores" } -OptionMenu "ChatControlsMenu" protected +OptionMenu "ChatControlsMenu"// protected { Title "$CNTRLMNU_CHAT_TITLE" ScrollTop 2 @@ -725,14 +725,14 @@ OptionMenu "ChatControlsMenu" protected Control "$CNTRLMNU_SAY" , "+send_message" } -OptionMenu "WeaponsControlMenu" protected +OptionMenu "WeaponsControlMenu"// protected { Title "$CNTRLMNU_WEAPONS_TITLE" ScrollTop 2 StaticTextSwitchable "$CNTRLMNU_SWITCHTEXT1", "$CNTRLMNU_SWITCHTEXT2", "ControlMessage" StaticText "" - Control "$CNTRLMNU_NEXTWEAPON" , "+nexct_weapon" + Control "$CNTRLMNU_NEXTWEAPON" , "+next_weapon" Control "$CNTRLMNU_PREVIOUSWEAPON" , "+previous_weapon" StaticText "" @@ -776,7 +776,7 @@ OptionMenu "WeaponsControlMenu" protected } -OptionMenu "InventoryControlsMenu" protected +OptionMenu "InventoryControlsMenu"// protected { Title "$CNTRLMNU_INVENTORY_TITLE" ScrollTop 2 @@ -786,8 +786,8 @@ OptionMenu "InventoryControlsMenu" protected Control "$CNTRLMNU_USEITEM" , "+inventory" StaticText "" - Control "$CNTRLMNU_NEXTITEM" , "+inventory_next" - Control "$CNTRLMNU_PREVIOUSITEM" , "+inventory_prev" + Control "$CNTRLMNU_NEXTITEM" , "+inventory_right" + Control "$CNTRLMNU_PREVIOUSITEM" , "+inventory_left" ifgame(Duke) { @@ -844,9 +844,9 @@ OptionMenu "InventoryControlsMenu" protected Control "$CNTRLMNU_NIGHTVISION" , "+nightvision" Control "$CNTRLMNU_MEDKIT" , "+medkit" } +} - -OptionMenu "OtherControlsMenu" protected +OptionMenu "OtherControlsMenu"// protected { Title "$CNTRLMNU_OTHER_TITLE" ScrollTop 2 From d55f55c04dcac5b5374b159ee89e9c42a258a9ba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 2 Dec 2019 19:27:35 +0100 Subject: [PATCH 087/203] - now, where this that 6 come from...? --- source/rr/src/d_menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index 88ada21d4..407ea4e7e 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -304,7 +304,7 @@ void GameInterface::DrawNativeMenuText(int fontnum, int state, double xpos, doub int ydim_upper = 0; int ydim_lower = ydim - 1; //int32_t const indent = 0; // not set for any relevant menu - int x = int(xpos * 65536 * 6); + int x = int(xpos * 65536); uint8_t status = 0; if (state == NIT_SelectedState) From 702f91b6b55c5b9444fede7afdc3204587503cac Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 2 Dec 2019 21:05:19 +0100 Subject: [PATCH 088/203] - disconnected Shadow Warrior's menu so it can be replaced. Unlike the other games this was a lot more invasive --- source/sw/src/common_game.h | 4 - source/sw/src/console.cpp | 1 + source/sw/src/demo.cpp | 4 - source/sw/src/draw.cpp | 11 +- source/sw/src/game.cpp | 390 +----------- source/sw/src/menus.cpp | 1163 +++++++++++++++++------------------ source/sw/src/menus.h | 22 +- source/sw/src/network.cpp | 1 - source/sw/src/network.h | 1 + source/sw/src/panel.cpp | 4 +- source/sw/src/player.cpp | 17 +- source/sw/src/sounds.cpp | 7 +- 12 files changed, 635 insertions(+), 990 deletions(-) diff --git a/source/sw/src/common_game.h b/source/sw/src/common_game.h index c7c0248b0..6b4b207b3 100644 --- a/source/sw/src/common_game.h +++ b/source/sw/src/common_game.h @@ -65,10 +65,6 @@ BEGIN_SW_NS #define SETUPPROGRAMNAME ("Shadow Warrior Setup") #define SETUPPROGRAMVERSION ("1.2") -#define GAMENAME "Shadow Warrior" -#define GAMELAUNCHER ("SW.EXE") -#define GAMETOTYPE ("SW") - #define MENUFOOTER "Esc Exits  Move  Selects\0" #define COMMITLAUNCHER ("COMMIT.EXE") diff --git a/source/sw/src/console.cpp b/source/sw/src/console.cpp index e9228f835..313651cea 100644 --- a/source/sw/src/console.cpp +++ b/source/sw/src/console.cpp @@ -66,6 +66,7 @@ BEGIN_SW_NS SWBOOL SpriteInfo = FALSE; extern SWBOOL QuitFlag; +extern SWBOOL MultiPlayQuitFlag; // FUNCTION PROTOTYPES /////////////////////////////////////////////////////////////////////// void CON_ProcessOptions(void); diff --git a/source/sw/src/demo.cpp b/source/sw/src/demo.cpp index cc4e5e02e..648671680 100644 --- a/source/sw/src/demo.cpp +++ b/source/sw/src/demo.cpp @@ -452,8 +452,6 @@ DemoPlayBack(void) domovethings(); - MNU_CheckForMenus(); - // fast forward and slow mo if (DemoEdit) { @@ -621,8 +619,6 @@ ScenePlayBack(void) //movethings(); domovethings(); - - MNU_CheckForMenus(); } // demo is over diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index a67b84492..d43e47155 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -56,6 +56,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "interp.h" #include "sector.h" #include "config.h" +#include "menu/menu.h" BEGIN_SW_NS @@ -1039,7 +1040,7 @@ post_analyzesprites(void) void ResizeView(PLAYERp pp) { - if (MenuInputMode || InputMode || HelpInputMode || ConPanel || ConInputMode || PauseKeySet) + if (M_Active() || PauseKeySet) return; if (dimensionmode == 2 || dimensionmode == 5 || dimensionmode == 6) @@ -1083,7 +1084,6 @@ ResizeView(PLAYERp pp) } // !JIM! 08/06 -extern SWBOOL UsingMenus; #if 0 void @@ -1417,6 +1417,7 @@ void PrintLocationInfo(PLAYERp pp) SWBOOL DebugSecret = FALSE; void SecretInfo(PLAYERp pp) { + if (!hud_stats) return; #define Y_STEP 7 #define AVERAGEFRAMES 16 int x = windowxy1.x+2; @@ -2485,10 +2486,8 @@ drawscreen(PLAYERp pp) DrawCompass(pp); UpdateMiniBar(pp); - if (UsingMenus) - MNU_DrawMenu(); - else - SecretInfo(pp); + if (!M_Active()) + SecretInfo(pp); videoNextPage(); diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 69f0a192c..e29909bb9 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -95,6 +95,7 @@ Things required to make savegames work: #include "printf.h" #include "m_argv.h" #include "debugbreak.h" +#include "menu/menu.h" //#include "crc32.h" @@ -106,6 +107,8 @@ signed char MNU_InputString(char*, short); SWBOOL IsCommand(const char* str); SWBOOL MNU_StartNetGame(void); +extern SWBOOL MultiPlayQuitFlag; + #if DEBUG #define BETA 0 @@ -1819,7 +1822,7 @@ TitleLevel(void) //MNU_CheckForMenusAnyKey(); } - //if (UsingMenus) + //if (M_Active()) // MNU_DrawMenu(); //drawscreen as fast as you can @@ -1941,7 +1944,8 @@ void MenuLevel(void) if (FinishAnim) { inputState.ClearKeyStatus(sc_Escape); - ControlPanelType = ct_ordermenu; + M_StartControlPanel(false); + M_SetMenu(NAME_CreditsMenu); FinishAnim = 0; } } @@ -1960,7 +1964,6 @@ void MenuLevel(void) if (totalclock >= ototalclock + synctics) { ototalclock += synctics; - MNU_CheckForMenusAnyKey(); if (CommEnabled) getpackets(); } @@ -1998,10 +2001,9 @@ void MenuLevel(void) } // force the use of menus at all time - if (!UsingMenus && !ConPanel) + if (!M_Active() && !ConPanel) { inputState.SetKeyStatus(sc_Escape); - MNU_CheckForMenusAnyKey(); } // must lock the clock for drawing so animations will happen @@ -2010,9 +2012,6 @@ void MenuLevel(void) //drawscreen as fast as you can DrawMenuLevelScreen(); - if (UsingMenus) - MNU_DrawMenu(); - videoNextPage(); } @@ -2020,8 +2019,7 @@ void MenuLevel(void) //LoadGameOutsideMoveLoop = FALSE; inputState.ClearKeyStatus(sc_Escape); inputState.ClearKeysDown(); - //ExitMenus(); - UsingMenus = FALSE; + M_ClearMenus(); InMenuLevel = FALSE; videoClearViewableArea(0L); videoNextPage(); @@ -2270,7 +2268,7 @@ void BonusScreen(PLAYERp pp) rotatesprite(0, 0, RS_SCALE, 0, 5120, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1); rotatesprite(158<<16, 86<<16, RS_SCALE, 0, State->Pic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1); videoNextPage(); - FadeIn(0,0); + //FadeIn(0,0); } BonusDone = FALSE; @@ -2375,7 +2373,7 @@ void BonusScreen(PLAYERp pp) void EndGameSequence(void) { SWBOOL anim_ok = TRUE; - FadeOut(0, 5); + //FadeOut(0, 5); if ((adult_lockout || Global_PLock) && FinishAnim == ANIM_SUMO) anim_ok = FALSE; @@ -2442,7 +2440,7 @@ void StatScreen(PLAYERp mpp) // No stats in bot games //if (BotMode) return; - ResetPalette(mpp); + //ResetPalette(mpp); COVER_SetReverb(0); // Reset reverb StopSound(); @@ -2628,7 +2626,7 @@ void Control() InitGame(); MONO_PRINT("InitGame done"); - MNU_InitMenus(); + //MNU_InitMenus(); InGame = TRUE; GameIntro(); @@ -2744,9 +2742,6 @@ void MoveLoop(void) // demosync_record(); #endif } - - if (!InputMode && !PauseKeySet) - MNU_CheckForMenus(); } @@ -3179,150 +3174,7 @@ void ManualPlayerDelete(PLAYERp cur_pp) } } -#if DEBUG -void SinglePlayInput(PLAYERp pp) -{ - int pnum = myconnectindex; - uint8_t* kp; - if (buttonMap.ButtonDown(gamefunc_See_Co_Op_View) && !UsingMenus && !ConPanel && dimensionmode == 3) - { - short oldscreenpeek = screenpeek; - - buttonMap.ClearButton(gamefunc_See_Co_Op_View); - - screenpeek = connectpoint2[screenpeek]; - - if (screenpeek < 0) - screenpeek = connecthead; - - if (dimensionmode == 2 || dimensionmode == 5 || dimensionmode == 6) - setup2dscreen(); - - if (dimensionmode != 2) - { - PLAYERp tp; - - tp = Player + screenpeek; - PlayerUpdatePanelInfo(tp); - setpalettefade(0,0,0,0); - memcpy(pp->temp_pal, palette_data, sizeof(palette_data)); - DoPlayerDivePalette(tp); - DoPlayerNightVisionPalette(tp); -// printf("SingPlayInput set_pal: tp->PlayerSprite = %d\n",tp->PlayerSprite); - } - } - - -} - -void DebugKeys(PLAYERp pp) -{ - short w, h; - - if (!(inputState.GetKeyStatus(KEYSC_ALT) || inputState.GetKeyStatus(KEYSC_RALT))) - return; - - if (InputMode) - return; - - if (CommEnabled) - return; - - // - // visiblity adjust - // - - if (inputState.GetKeyStatus(KEYSC_L) > 0) - { - if (inputState.GetKeyStatus(KEYSC_LSHIFT) | inputState.GetKeyStatus(KEYSC_RSHIFT)) // SHIFT - { - g_visibility = g_visibility - (g_visibility >> 3); - - if (g_visibility < 128) - g_visibility = 16348; - - //if (g_visibility > 16384) - // g_visibility = 128; - } - else - { - inputState.GetKeyStatus(KEYSC_L) = 0; - - g_visibility = g_visibility - (g_visibility >> 3); - - if (g_visibility > 16384) - g_visibility = 128; - } - } - - // - // parallax changes - // - - if (inputState.GetKeyStatus(KEYSC_X)) - { - if (inputState.GetKeyStatus(KEYSC_LSHIFT)) - { - inputState.GetKeyStatus(KEYSC_LSHIFT) = FALSE; - inputState.GetKeyStatus(KEYSC_X) = 0; - - parallaxyoffs_override += 10; - - if (parallaxyoffs_override > 100) - parallaxyoffs_override = 0; - } - else - { - inputState.GetKeyStatus(KEYSC_X) = 0; - parallaxtype++; - if (parallaxtype > 2) - parallaxtype = 0; - } - } -} - -#endif - -void ConKey(void) -{ -#if DEBUG - // Console Input Panel - if (!ConPanel && dimensionmode == 3) - { - //if (inputState.GetKeyStatus(KEYSC_TILDE) && inputState.GetKeyStatus(KEYSC_LSHIFT)) - if (inputState.GetKeyStatus(KEYSC_TILDE)) - { - inputState.GetKeyStatus(KEYSC_TILDE) = FALSE; - //inputState.GetKeyStatus(KEYSC_LSHIFT) = FALSE; - inputState.keyFlushChars(); - ConPanel = TRUE; - InputMode = TRUE; - ConInputMode = TRUE; - if (!CommEnabled) - GamePaused = TRUE; - memset(MessageInputString, '\0', sizeof(MessageInputString)); - } - } - else if (ConPanel) - { - //if (inputState.GetKeyStatus(KEYSC_TILDE) && inputState.GetKeyStatus(KEYSC_LSHIFT)) - if (inputState.GetKeyStatus(KEYSC_TILDE)) - { - inputState.GetKeyStatus(KEYSC_TILDE) = FALSE; - //inputState.GetKeyStatus(KEYSC_LSHIFT) = FALSE; - inputState.keyFlushChars(); - ConPanel = FALSE; - ConInputMode = FALSE; - InputMode = FALSE; - if (!CommEnabled) - GamePaused = FALSE; - memset(MessageInputString, '\0', sizeof(MessageInputString)); - SetFragBar(Player + myconnectindex); - } - } -#endif -} char WangBangMacro[10][64]; @@ -3398,47 +3250,10 @@ FunctionKeys(PLAYERp pp) return; } - - if (numplayers <= 1) - { - // F2 save menu - if (inputState.GetKeyStatus(KEYSC_F2)) - { - inputState.ClearKeyStatus(KEYSC_F2); - if (!TEST(pp->Flags, PF_DEAD)) - { - inputState.SetKeyStatus(sc_Escape); - ControlPanelType = ct_savemenu; - } - } - - // F3 load menu - if (inputState.GetKeyStatus(KEYSC_F3)) - { - inputState.ClearKeyStatus(KEYSC_F3); - if (!TEST(pp->Flags, PF_DEAD)) - { - inputState.SetKeyStatus(sc_Escape); - ControlPanelType = ct_loadmenu; - } - } - - } - - - // F4 sound menu - if (inputState.GetKeyStatus(KEYSC_F4)) - { - inputState.ClearKeyStatus(KEYSC_F4); - inputState.SetKeyStatus(sc_Escape); - ControlPanelType = ct_soundmenu; - } - - // F7 VIEW control - if (inputState.GetKeyStatus(KEYSC_F7)) + if (buttonMap.ButtonDown(gamefunc_Third_Person_View)) { - inputState.ClearKeyStatus(KEYSC_F7); + buttonMap.ClearButton(gamefunc_Third_Person_View); if (inputState.GetKeyStatus(KEYSC_LSHIFT) || inputState.GetKeyStatus(KEYSC_RSHIFT)) { @@ -3459,33 +3274,6 @@ FunctionKeys(PLAYERp pp) } } - // F8 toggle messages - if (inputState.GetKeyStatus(KEYSC_F8)) - { - inputState.ClearKeyStatus(KEYSC_F8); - - hud_messages = !hud_messages; - - if (hud_messages) - PutStringInfoLine(pp, "Messages ON"); - else - PutStringInfoLine(pp, "Messages OFF"); - } - - // F10 quit menu - if (inputState.GetKeyStatus(KEYSC_F10)) - { - inputState.ClearKeyStatus(KEYSC_F10); - inputState.SetKeyStatus(sc_Escape); - ControlPanelType = ct_quitmenu; - } - - // F11 gamma correction - if (inputState.GetKeyStatus(KEYSC_F11) > 0) - { - inputState.ClearKeyStatus(KEYSC_F11); - // Do this entirely in the video backend. - } } @@ -3494,7 +3282,7 @@ void PauseKey(PLAYERp pp) extern SWBOOL GamePaused,CheatInputMode; extern SWBOOL enabled; - if (inputState.GetKeyStatus(sc_Pause) && !CommEnabled && !InputMode && !UsingMenus && !CheatInputMode && !ConPanel) + if (inputState.GetKeyStatus(sc_Pause) && !CommEnabled && !InputMode && !M_Active() && !CheatInputMode && !ConPanel) { inputState.ClearKeyStatus(sc_Pause); @@ -3566,6 +3354,7 @@ void GetMessageInput(PLAYERp pp) } } } +#if 0 // the message input needs to be moved out of the game code! else if (MessageInputMode && !ConInputMode) { if (gs.BorderNum > BORDER_BAR+1) @@ -3687,141 +3476,7 @@ SEND_MESSAGE: break; } } -} - -void GetConInput(PLAYERp pp) -{ - int pnum = myconnectindex; - short w,h; - static SWBOOL cur_show; - - if (MessageInputMode || HelpInputMode) - return; - - ConKey(); - - // Console input commands - if (ConInputMode && !MessageInputMode) - { - // get input - switch (MNU_InputSmallString(MessageInputString, 250)) - { - case -1: // Cancel Input (pressed ESC) or Err - InputMode = FALSE; - inputState.ClearKeysDown(); - inputState.keyFlushChars(); - memset(MessageInputString, '\0', sizeof(MessageInputString)); - break; - case FALSE: // Input finished (RETURN) - if (MessageInputString[0] == '\0') - { - InputMode = FALSE; - inputState.ClearKeysDown(); - inputState.keyFlushChars(); - buttonMap.ClearButton(gamefunc_Inventory); - memset(MessageInputString, '\0', sizeof(MessageInputString)); - } - else - { - InputMode = FALSE; - inputState.ClearKeysDown(); - inputState.keyFlushChars(); - buttonMap.ClearButton(gamefunc_Inventory); - CON_ConMessage("%s", MessageInputString); - CON_ProcessUserCommand(); // Check to see if it's a cheat or command - - conbot += 6; - conbotgoal = conbot; - //addconquote(MessageInputString); - // Clear it out after every entry - memset(MessageInputString, '\0', sizeof(MessageInputString)); - } - break; - case TRUE: // Got input - break; - } - } -} - - -void GetHelpInput(PLAYERp pp) -{ - extern SWBOOL GamePaused; - - if (inputState.GetKeyStatus(KEYSC_ALT) || inputState.GetKeyStatus(KEYSC_RALT)) - return; - - if (inputState.GetKeyStatus(KEYSC_LSHIFT) || inputState.GetKeyStatus(KEYSC_RSHIFT)) - return; - - if (MessageInputMode || ConInputMode) - return; - - // F1 help menu - if (!HelpInputMode) - { - if (inputState.GetKeyStatus(KEYSC_F1)) - { - inputState.ClearKeyStatus(KEYSC_F11); - HelpPage = 0; - HelpInputMode = TRUE; - PanelUpdateMode = FALSE; - InputMode = TRUE; - if (!CommEnabled) - GamePaused = TRUE; - } - } - else if (HelpInputMode) - { - if (inputState.GetKeyStatus(KEYSC_ESC)) - { - inputState.ClearKeyStatus(sc_Escape); - inputState.ClearKeysDown(); - PanelUpdateMode = TRUE; - HelpInputMode = FALSE; - InputMode = FALSE; - if (!CommEnabled) - GamePaused = FALSE; - SetRedrawScreen(pp); - } - - if (inputState.GetKeyStatus(KEYSC_SPACE) || inputState.GetKeyStatus(KEYSC_ENTER) || inputState.GetKeyStatus(KEYSC_PGDN) || inputState.GetKeyStatus(KEYSC_DOWN) || inputState.GetKeyStatus(KEYSC_RIGHT) || inputState.GetKeyStatus(sc_kpad_3) || inputState.GetKeyStatus(sc_kpad_2) || inputState.GetKeyStatus(sc_kpad_6)) - { - inputState.ClearKeyStatus(KEYSC_SPACE); - inputState.ClearKeyStatus(KEYSC_ENTER); - inputState.ClearKeyStatus(KEYSC_PGDN); - inputState.ClearKeyStatus(KEYSC_DOWN); - inputState.ClearKeyStatus(KEYSC_RIGHT); - inputState.ClearKeyStatus(sc_kpad_3); - inputState.ClearKeyStatus(sc_kpad_2); - inputState.ClearKeyStatus(sc_kpad_6); - - HelpPage++; - if (HelpPage >= (int)SIZ(HelpPagePic)) - // CTW MODIFICATION - // "Oops! I did it again..." - // HelpPage = SIZ(HelpPagePic) - 1; - HelpPage = 0; - // CTW MODIFICATION END - } - - if (inputState.GetKeyStatus(KEYSC_PGUP) || inputState.GetKeyStatus(KEYSC_UP) || inputState.GetKeyStatus(KEYSC_LEFT) || inputState.GetKeyStatus(sc_kpad_9) || inputState.GetKeyStatus(sc_kpad_8) || inputState.GetKeyStatus(sc_kpad_4)) - { - inputState.ClearKeyStatus(KEYSC_PGUP); - inputState.ClearKeyStatus(KEYSC_UP); - inputState.ClearKeyStatus(KEYSC_LEFT); - inputState.ClearKeyStatus(sc_kpad_8); - inputState.ClearKeyStatus(sc_kpad_9); - inputState.ClearKeyStatus(sc_kpad_4); - - HelpPage--; - if (HelpPage < 0) - // CTW MODIFICATION - // "Played with the logic, got lost in the game..." - HelpPage = SIZ(HelpPagePic) - 1; - // CTW MODIFICATION END - } - } +#endif } short MirrorDelay; @@ -3920,11 +3575,9 @@ void getinput(SW_PACKET *loc) if (PauseKeySet) return; - if (!MenuInputMode && !UsingMenus) + if (!M_Active()) { GetMessageInput(pp); - GetConInput(pp); - GetHelpInput(pp); } // MAP KEY @@ -3968,8 +3621,8 @@ void getinput(SW_PACKET *loc) if (ScrollMode2D && pp == Player + myconnectindex && !Prediction) MoveScrollMode2D(Player + myconnectindex); - // !JIM! Added UsingMenus so that you don't move at all while using menus - if (MenuInputMode || UsingMenus || ScrollMode2D || InputMode) + // !JIM! Added M_Active() so that you don't move at all while using menus + if (M_Active() || ScrollMode2D || InputMode) return; SET_LOC_KEY(loc->bits, SK_SPACE_BAR, ((!!inputState.GetKeyStatus(KEYSC_SPACE)) | buttonMap.ButtonDown(gamefunc_Open))); @@ -4097,12 +3750,15 @@ void getinput(SW_PACKET *loc) if (!CommEnabled) { + // What a mess...:? +#if 0 if (MenuButtonAutoAim) { MenuButtonAutoAim = FALSE; if ((!!TEST(pp->Flags, PF_AUTO_AIM)) != !!cl_autoaim) SET_LOC_KEY(loc->bits, SK_AUTO_AIM, TRUE); } +#endif } else if (inputState.GetKeyStatus(sc_Pause)) { diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index 78491f935..de61a05ca 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -54,23 +54,594 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "music.h" #include "text.h" #include "version.h" +#include "network.h" #include "colormap.h" #include "config.h" BEGIN_SW_NS -signed char MNU_InputString(char*, short); //#define PLOCK_VERSION TRUE +extern SWBOOL ExitLevel, NewGame; + short TimeLimitTable[9] = {0,3,5,10,15,20,30,45,60}; +SWBOOL +MNU_StartNetGame(void) +{ + extern SWBOOL ExitLevel, ShortGameMode, DemoInitOnce, FirstTimeIntoGame; + extern short Level, Skill; + // CTW REMOVED + //extern int gTenActivated; + // CTW REMOVED END + int pnum; + + // always assumed that a demo is playing + + ready2send = 0; + // Skill can go negative here + Skill = gs.NetMonsters - 1; + Level = gs.NetLevel + 1; + DemoPlaying = FALSE; + ExitLevel = TRUE; + NewGame = TRUE; + // restart demo for multi-play mode + DemoInitOnce = FALSE; + + // TENSW: return if a joiner + if (/* CTW REMOVED gTenActivated && */ !AutoNet && FirstTimeIntoGame) + return TRUE; + + // need to set gNet vars for self + // everone else gets a packet to set them + gNet.AutoAim = cl_autoaim; + gNet.SpawnMarkers = gs.NetSpawnMarkers; + gNet.HurtTeammate = gs.NetHurtTeammate; + gNet.Nuke = gs.NetNuke; + gNet.KillLimit = gs.NetKillLimit * 10; + gNet.TimeLimit = TimeLimitTable[gs.NetTimeLimit] * 60 * 120; + + if (ShortGameMode) + { + gNet.KillLimit /= 10; + gNet.TimeLimit /= 2; + } + + gNet.TimeLimitClock = gNet.TimeLimit; + gNet.TeamPlay = gs.NetTeamPlay; + gNet.MultiGameType = gs.NetGameType + 1; + + if (gNet.MultiGameType == MULTI_GAME_COMMBAT_NO_RESPAWN) + { + gNet.MultiGameType = MULTI_GAME_COMMBAT; + gNet.NoRespawn = TRUE; + } + else + { + gNet.NoRespawn = FALSE; + } + + if (CommEnabled) + { + PACKET_NEW_GAME p; + + p.PacketType = PACKET_TYPE_NEW_GAME; + p.Level = Level; + p.Skill = Skill; + p.GameType = gs.NetGameType; + p.AutoAim = cl_autoaim; + p.HurtTeammate = gs.NetHurtTeammate; + p.TeamPlay = gs.NetTeamPlay; + p.SpawnMarkers = gs.NetSpawnMarkers; + p.KillLimit = gs.NetKillLimit; + p.TimeLimit = gs.NetTimeLimit; + p.Nuke = gs.NetNuke; + + netbroadcastpacket((uint8_t*)(&p), sizeof(p)); // TENSW + } + + + return TRUE; +} + + +//////////////////////////////////////////////// +// Measure the pixel width of a graphic string +//////////////////////////////////////////////// +static char lg_xlat_num[] = { 0,1,2,3,4,5,6,7,8,9 }; +#define FONT_LARGE_ALPHA 3706 +#define FONT_LARGE_DIGIT 3732 +#define MenuDrawFlags (ROTATE_SPRITE_SCREEN_CLIP) +#define MZ 65536 +#define MENU_SHADE_DEFAULT 0 +#define MENU_SHADE_INACTIVE 20 + +void MNU_MeasureStringLarge(const char *string, short *w, short *h) +{ + short ndx, width, height; + char c; + short pic; + + width = 0; + height = *h; + + for (ndx = 0; (c = string[ndx]) != 0; ndx++) + { + if (isalpha(c)) + { + c = toupper(c); + pic = FONT_LARGE_ALPHA + (c - 'A'); + } + else if (isdigit(c)) + { + pic = FONT_LARGE_DIGIT + lg_xlat_num[(c - '0')]; + } + else if (c == ' ') + { + width += 10; // Special case for space char + continue; + } + else + { + continue; + } + + width += tilesiz[pic].x+1; + if (height < tilesiz[pic].y) + height = tilesiz[pic].y; + } + + *w = width; + *h = height; +} + +//////////////////////////////////////////////// +// Draw a string using a graphic font +//////////////////////////////////////////////// +void MNU_DrawStringLarge(short x, short y, const char *string, int shade) +{ + int ndx, offset; + char c; + short pic; + + offset = x; + + for (ndx = 0; (c = string[ndx]) != 0; ndx++) + { + if (isalpha(c)) + { + c = toupper(c); + pic = FONT_LARGE_ALPHA + (c - 'A'); + } + else if (isdigit(c)) + { + pic = FONT_LARGE_DIGIT + lg_xlat_num[(c - '0')]; + } + else if (c == ' ') + { + offset += 10; + continue; + } + else + { + continue; + } + + rotatesprite(offset << 16, y << 16, MZ, 0, pic, shade, 0, MenuDrawFlags|ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); + offset += tilesiz[pic].x + 1; + } + +} + + +//////////////////////////////////////////////// +// Measure the pixel width of a graphic string +//////////////////////////////////////////////// +void MNU_MeasureString(const char *string, short *w, short *h) +{ + short ndx, width, height; + char c; + short ac; + + if (string[0] == '^') + { + MNU_MeasureStringLarge(&string[1], w, h); + return; + } + + width = 0; + height = *h; + + for (ndx = 0; (c = string[ndx]) != 0; ndx++) + { + ac = c - '!' + STARTALPHANUM; + if ((ac < STARTALPHANUM || ac > ENDALPHANUM) && c != asc_Space) + break; + + if (c > asc_Space && c < 127) + { + width += tilesiz[ac].x; + if (height < tilesiz[ac].y) + height = tilesiz[ac].y; + } + else if (c == asc_Space) + width += 4; // Special case for space char + } + + *w = width; + *h = height; +} + +//////////////////////////////////////////////// +// Draw a string using a graphic font +// +// MenuTextShade and MenuDrawFlags +//////////////////////////////////////////////// +void MNU_DrawString(short x, short y, const char *string, short shade, short pal) +{ + int ndx, offset; + char c; + short ac; + + if (string[0] == '^') + { + MNU_DrawStringLarge(x,y, &string[1]); + return; + } + + offset = x; + + for (ndx = 0; (c = string[ndx]) != 0; ndx++) + { + ac = c - '!' + STARTALPHANUM; + if ((ac < STARTALPHANUM || ac > ENDALPHANUM) && c != asc_Space) + break; + + if (c > asc_Space && c < 127) + { + rotatesprite(offset<<16,y<<16,MZ,0,ac, shade, pal, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); + offset += tilesiz[ac].x; + } + else if (c == asc_Space) + offset += 4; // Special case for space char + } + +} + +//////////////////////////////////////////////// +// Measure the pixel width of a small font string +//////////////////////////////////////////////// +void MNU_MeasureSmallString(const char *string, short *w, short *h) +{ + short ndx, width, height; + char c; + short ac; + + width = 0; + height = *h; + + for (ndx = 0; (c = string[ndx]) != 0; ndx++) + { + ac = (c - '!') + 2930; + if ((ac < 2930 || ac > 3023) && c != asc_Space) + break; + + if (c > asc_Space && c < 127) + { + width += tilesiz[ac].x; + if (height < tilesiz[ac].y) + height = tilesiz[ac].y; + } + else if (c == asc_Space) + width += 4; // Special case for space char + } + + *w = width; + *h = height; +} + +//////////////////////////////////////////////// +// Draw a string using a small graphic font +//////////////////////////////////////////////// +void MNU_DrawSmallString(short x, short y, const char *string, short shade, short pal) +{ + int ndx; + char c; + short ac,offset; + + + offset = x; + + for (ndx = 0; (c = string[ndx]) != 0; ndx++) + { + ac = c - '!' + 2930; + if ((ac < 2930 || ac > 3023) && c != asc_Space) + break; + + if (c > asc_Space && c < 127) + { + rotatesprite(offset<<16,y<<16,MZ,0,ac, shade, pal, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); + + offset += tilesiz[ac].x; + + } + else if (c == asc_Space) + { + offset += 4; // Special case for space char + } + } + +} + + +////////////////////////////////////////////////////////////////////////////// +#define FADE_DAMAGE_FACTOR 3 // 100 health / 32 shade cycles = 3.125 + +// Fades from 100% to 62.5% somewhat quickly, +// then from 62.5% to 37.5% slowly, +// then from 37.5% to 0% quickly. +// This seems to capture the pain caused by enemy shots, plus the extreme +// fade caused by being blinded or intense pain. +// Perhaps the next step would be to apply a gentle smoothing to the +// intersections of these lines. +static int faderamp[32] = +{ + // y=64-4x + 252,240,224,208,192,176, + + // y=44.8-(16/20)x + 160,156,152,152,148, + 144,140,136,136,132, + 128,124,120,120,116, + 112,108,104,104,100, + + // y=128-4x + 96,80,64,48,32,16 +}; + + +typedef struct RGB_color_typ +{ + unsigned char red; + unsigned char green; + unsigned char blue; +} RGB_color, * RGB_color_ptr; + +unsigned char ppalette[MAX_SW_PLAYERS_REG][768]; +unsigned char palette_data[256][3]; // Global palette array + +////////////////////////////////////////// +// Set the amount of redness for damage +// the player just took +////////////////////////////////////////// +void SetFadeAmt(PLAYERp pp, short damage, unsigned char startcolor) +{ + int palreg, usereg = 0, tmpreg1 = 0, tmpreg2 = 0; + short fadedamage = 0; + RGB_color color; + + //CON_ConMessage("SetAmt: fadeamt = %d, startcolor = %d, pp = %d",pp->FadeAmt,startcolor,pp->StartColor); + + if (abs(pp->FadeAmt) > 0 && startcolor == pp->StartColor) + return; + + // Don't ever over ride flash bomb + if (pp->StartColor == 1 && abs(pp->FadeAmt) > 0) + return; + + // Reset the palette + if (pp == Player + screenpeek) + { + videoFadePalette(0, 0, 0, 0); + if (pp->FadeAmt <= 0) + GetPaletteFromVESA(&ppalette[screenpeek][0]); + } + + if (damage < -150 && damage > -1000) fadedamage = 150; + else if (damage < -1000) // Underwater + fadedamage = abs(damage + 1000); + else + fadedamage = abs(damage); + + if (damage >= -5 && damage < 0) + fadedamage += 10; + + // Don't let red to TOO red + if (startcolor == COLOR_PAIN && fadedamage > 100) fadedamage = 100; + + pp->FadeAmt = fadedamage / FADE_DAMAGE_FACTOR; + + if (pp->FadeAmt <= 0) + { + pp->FadeAmt = 0; + return; + } + + // It's a health item, just do a preset flash amount + if (damage > 0) + pp->FadeAmt = 3; + + pp->StartColor = startcolor; + + pp->FadeTics = 0; + + // Set player's palette to current game palette + GetPaletteFromVESA(pp->temp_pal); + + color.red = palette_data[pp->StartColor][0]; + color.green = palette_data[pp->StartColor][1]; + color.blue = palette_data[pp->StartColor][2]; + + for (palreg = 0; palreg < 768; palreg++) + { + tmpreg1 = (int)(pp->temp_pal[palreg]) + ((2 * pp->FadeAmt) + 4); + tmpreg2 = (int)(pp->temp_pal[palreg]) - ((2 * pp->FadeAmt) + 4); + if (tmpreg1 > 255) + tmpreg1 = 255; + if (tmpreg2 < 0) + tmpreg2 = 0; + + if (usereg == 0) + { + if (pp->temp_pal[palreg] < color.red) + { + if ((pp->temp_pal[palreg] = tmpreg1) > color.red) + pp->temp_pal[palreg] = color.red; + } + else if (pp->temp_pal[palreg] > color.red) + if ((pp->temp_pal[palreg] = tmpreg2) < color.red) + pp->temp_pal[palreg] = color.red; + } + else if (usereg == 1) + { + if (pp->temp_pal[palreg] < color.green) + { + if ((pp->temp_pal[palreg] = tmpreg1) > color.green) + pp->temp_pal[palreg] = color.green; + } + else if (pp->temp_pal[palreg] > color.green) + if ((pp->temp_pal[palreg] = tmpreg2) < color.green) + pp->temp_pal[palreg] = color.green; + } + else if (usereg == 2) + { + if (pp->temp_pal[palreg] < color.blue) + { + if ((pp->temp_pal[palreg] = tmpreg1) > color.blue) + pp->temp_pal[palreg] = color.blue; + } + else if (pp->temp_pal[palreg] > color.blue) + if ((pp->temp_pal[palreg] = tmpreg2) < color.blue) + pp->temp_pal[palreg] = color.blue; + } + + if (++usereg > 2) + usereg = 0; + } + + // Do initial palette set + if (pp == Player + screenpeek) + { + if (videoGetRenderMode() < REND_POLYMOST) set_pal(pp->temp_pal); + else videoFadePalette(color.red, color.green, color.blue, faderamp[min(31, max(0, 32 - abs(pp->FadeAmt)))]); + if (damage < -1000) + pp->FadeAmt = 1000; // Don't call DoPaletteFlash for underwater stuff + } +} + +////////////////////////////////////////// +// Do the screen reddness based on damage +////////////////////////////////////////// +#define MAXFADETICS 5 +void DoPaletteFlash(PLAYERp pp) +{ + int i, palreg, tmpreg1 = 0, tmpreg2 = 0; + unsigned char* pal_ptr = &ppalette[screenpeek][0]; + + + if (pp->FadeAmt <= 1) + { + pp->FadeAmt = 0; + pp->StartColor = 0; + if (pp == Player + screenpeek) + { + videoFadePalette(0, 0, 0, 0); + memcpy(pp->temp_pal, palette_data, sizeof(palette_data)); + DoPlayerDivePalette(pp); // Check Dive again + DoPlayerNightVisionPalette(pp); // Check Night Vision again + } + + return; + } + + + pp->FadeTics += synctics; // Add this frame's tic amount to + // counter + + if (pp->FadeTics >= MAXFADETICS) + { + while (pp->FadeTics >= MAXFADETICS) + { + pp->FadeTics -= MAXFADETICS; + + pp->FadeAmt--; // Decrement FadeAmt till it gets to + // 0 again. + } + } + else + return; // Return if they were not > + // MAXFADETICS + + if (pp->FadeAmt > 32) + return; + + if (pp->FadeAmt <= 1) + { + pp->FadeAmt = 0; + pp->StartColor = 0; + if (pp == Player + screenpeek) + { + videoFadePalette(0, 0, 0, 0); + memcpy(pp->temp_pal, palette_data, sizeof(palette_data)); + DoPlayerDivePalette(pp); // Check Dive again + DoPlayerNightVisionPalette(pp); // Check Night Vision again + } + return; + } + else + { + //CON_Message("gamavalues = %d, %d, %d",pp->temp_pal[pp->StartColor],pp->temp_pal[pp->StartColor+1],pp->temp_pal[pp->StartColor+2]); + for (palreg = 0; palreg < 768; palreg++) + { + tmpreg1 = (int)(pp->temp_pal[palreg]) + 2; + tmpreg2 = (int)(pp->temp_pal[palreg]) - 2; + if (tmpreg1 > 255) + tmpreg1 = 255; + if (tmpreg2 < 0) + tmpreg2 = 0; + + if (pp->temp_pal[palreg] < pal_ptr[palreg]) + { + if ((pp->temp_pal[palreg] = tmpreg1) > pal_ptr[palreg]) + pp->temp_pal[palreg] = pal_ptr[palreg]; + } + else if (pp->temp_pal[palreg] > pal_ptr[palreg]) + if ((pp->temp_pal[palreg] = tmpreg2) < pal_ptr[palreg]) + pp->temp_pal[palreg] = pal_ptr[palreg]; + + } + + // Only hard set the palette if this is currently the player's view + if (pp == Player + screenpeek) + { + if (videoGetRenderMode() < REND_POLYMOST) set_pal(pp->temp_pal); + else + { + videoFadePalette( + palette_data[pp->StartColor][0], + palette_data[pp->StartColor][1], + palette_data[pp->StartColor][2], + faderamp[min(31, max(0, 32 - abs(pp->FadeAmt)))] + ); + } + } + + } + +} + + + +# if 0 + +signed char MNU_InputString(char*, short); + SWBOOL SavePrompt = FALSE; extern SWBOOL InMenuLevel, LoadGameOutsideMoveLoop, LoadGameFromDemo; extern uint8_t RedBookSong[40]; -extern SWBOOL ExitLevel, NewGame; extern short Level, Skill; extern SWBOOL MusicInitialized, FxInitialized; SWBOOL MNU_CheckUserMap(MenuItem *item); @@ -1581,87 +2152,6 @@ void ResetMenuInput(void) InputMode = FALSE; } -SWBOOL -MNU_StartNetGame(void) -{ - extern SWBOOL ExitLevel, ShortGameMode, DemoInitOnce, FirstTimeIntoGame; - extern short Level, Skill; - // CTW REMOVED - //extern int gTenActivated; - // CTW REMOVED END - int pnum; - - // always assumed that a demo is playing - - ready2send = 0; - // Skill can go negative here - Skill = gs.NetMonsters-1; - Level = gs.NetLevel + 1; - if (!AutoNet) - ExitMenus(); - DemoPlaying = FALSE; - ExitLevel = TRUE; - NewGame = TRUE; - // restart demo for multi-play mode - DemoInitOnce = FALSE; - ResetMenuInput(); - - // TENSW: return if a joiner - if (/* CTW REMOVED gTenActivated && */ !AutoNet && FirstTimeIntoGame) - return TRUE; - - // need to set gNet vars for self - // everone else gets a packet to set them - gNet.AutoAim = cl_autoaim; - gNet.SpawnMarkers = gs.NetSpawnMarkers; - gNet.HurtTeammate = gs.NetHurtTeammate; - gNet.Nuke = gs.NetNuke; - gNet.KillLimit = gs.NetKillLimit*10; - gNet.TimeLimit = TimeLimitTable[gs.NetTimeLimit]*60*120; - - if (ShortGameMode) - { - gNet.KillLimit /= 10; - gNet.TimeLimit /= 2; - } - - gNet.TimeLimitClock = gNet.TimeLimit; - gNet.TeamPlay = gs.NetTeamPlay; - gNet.MultiGameType = gs.NetGameType+1; - - if (gNet.MultiGameType == MULTI_GAME_COMMBAT_NO_RESPAWN) - { - gNet.MultiGameType = MULTI_GAME_COMMBAT; - gNet.NoRespawn = TRUE; - } - else - { - gNet.NoRespawn = FALSE; - } - - if (CommEnabled) - { - PACKET_NEW_GAME p; - - p.PacketType = PACKET_TYPE_NEW_GAME; - p.Level = Level; - p.Skill = Skill; - p.GameType = gs.NetGameType; - p.AutoAim = cl_autoaim; - p.HurtTeammate = gs.NetHurtTeammate; - p.TeamPlay = gs.NetTeamPlay; - p.SpawnMarkers = gs.NetSpawnMarkers; - p.KillLimit = gs.NetKillLimit; - p.TimeLimit = gs.NetTimeLimit; - p.Nuke = gs.NetNuke; - - netbroadcastpacket((uint8_t*)(&p), sizeof(p)); // TENSW - } - - - return TRUE; -} - SWBOOL MNU_EpisodeCustom(void) @@ -1821,258 +2311,6 @@ MNU_InitMenus(void) main_i[4].hotkey = (SW_SHAREWARE) ? KEYSC_H : KEYSC_C; } -//////////////////////////////////////////////// -// Measure the pixel width of a graphic string -//////////////////////////////////////////////// -static char lg_xlat_num[] = {0,1,2,3,4,5,6,7,8,9}; -#define FONT_LARGE_ALPHA 3706 -#define FONT_LARGE_DIGIT 3732 - -void MNU_MeasureStringLarge(const char *string, short *w, short *h) -{ - short ndx, width, height; - char c; - short pic; - - width = 0; - height = *h; - - for (ndx = 0; (c = string[ndx]) != 0; ndx++) - { - if (isalpha(c)) - { - c = toupper(c); - pic = FONT_LARGE_ALPHA + (c - 'A'); - } - else if (isdigit(c)) - { - pic = FONT_LARGE_DIGIT + lg_xlat_num[(c - '0')]; - } - else if (c == ' ') - { - width += 10; // Special case for space char - continue; - } - else - { - continue; - } - - width += tilesiz[pic].x+1; - if (height < tilesiz[pic].y) - height = tilesiz[pic].y; - } - - *w = width; - *h = height; -} - -//////////////////////////////////////////////// -// Draw a string using a graphic font -//////////////////////////////////////////////// -void MNU_DrawStringLarge(short x, short y, const char *string) -{ - int ndx, offset; - char c; - short pic; - - offset = x; - - for (ndx = 0; (c = string[ndx]) != 0; ndx++) - { - if (isalpha(c)) - { - c = toupper(c); - pic = FONT_LARGE_ALPHA + (c - 'A'); - } - else if (isdigit(c)) - { - pic = FONT_LARGE_DIGIT + lg_xlat_num[(c - '0')]; - } - else if (c == ' ') - { - offset += 10; - continue; - } - else - { - continue; - } - - rotatesprite(offset << 16, y << 16, MZ, 0, pic, MenuTextShade, 0, MenuDrawFlags|ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); - offset += tilesiz[pic].x + 1; - } - -} - - -//////////////////////////////////////////////// -// Measure the pixel width of a graphic string -//////////////////////////////////////////////// -void MNU_MeasureString(const char *string, short *w, short *h) -{ - short ndx, width, height; - char c; - short ac; - - if (string[0] == '^') - { - MNU_MeasureStringLarge(&string[1], w, h); - return; - } - - width = 0; - height = *h; - - for (ndx = 0; (c = string[ndx]) != 0; ndx++) - { - ac = c - '!' + STARTALPHANUM; - if ((ac < STARTALPHANUM || ac > ENDALPHANUM) && c != asc_Space) - break; - - if (c > asc_Space && c < 127) - { - width += tilesiz[ac].x; - if (height < tilesiz[ac].y) - height = tilesiz[ac].y; - } - else if (c == asc_Space) - width += 4; // Special case for space char - } - - *w = width; - *h = height; -} - -//////////////////////////////////////////////// -// Draw a string using a graphic font -// -// MenuTextShade and MenuDrawFlags -//////////////////////////////////////////////// -void MNU_DrawString(short x, short y, const char *string, short shade, short pal) -{ - int ndx, offset; - char c; - short ac; - - if (string[0] == '^') - { - MNU_DrawStringLarge(x,y, &string[1]); - return; - } - - offset = x; - - for (ndx = 0; (c = string[ndx]) != 0; ndx++) - { - ac = c - '!' + STARTALPHANUM; - if ((ac < STARTALPHANUM || ac > ENDALPHANUM) && c != asc_Space) - break; - - if (c > asc_Space && c < 127) - { - rotatesprite(offset<<16,y<<16,MZ,0,ac, shade, pal, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - offset += tilesiz[ac].x; - } - else if (c == asc_Space) - offset += 4; // Special case for space char - } - -} -/* Original code -void -MNU_DrawString(short x, short y, char *string) -{ - int ndx, offset; - char c; - - if (string[0] == '^') - { - MNU_DrawStringLarge(x,y, &string[1]); - return; - } - - offset = x; - - for (ndx = 0; (c = string[ndx]) != 0; ndx++) - { - if (c > asc_Space && c < 127) - { - rotatesprite(offset << 16, y << 16, MZ, 0, xlatfont[c], MenuTextShade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - offset += tilesiz[xlatfont[c]].x; - } else - if (c == asc_Space) - offset += 4; // Special case for space char - } - -} -*/ - -//////////////////////////////////////////////// -// Measure the pixel width of a small font string -//////////////////////////////////////////////// -void MNU_MeasureSmallString(const char *string, short *w, short *h) -{ - short ndx, width, height; - char c; - short ac; - - width = 0; - height = *h; - - for (ndx = 0; (c = string[ndx]) != 0; ndx++) - { - ac = (c - '!') + 2930; - if ((ac < 2930 || ac > 3023) && c != asc_Space) - break; - - if (c > asc_Space && c < 127) - { - width += tilesiz[ac].x; - if (height < tilesiz[ac].y) - height = tilesiz[ac].y; - } - else if (c == asc_Space) - width += 4; // Special case for space char - } - - *w = width; - *h = height; -} - -//////////////////////////////////////////////// -// Draw a string using a small graphic font -//////////////////////////////////////////////// -void MNU_DrawSmallString(short x, short y, const char *string, short shade, short pal) -{ - int ndx; - char c; - short ac,offset; - - - offset = x; - - for (ndx = 0; (c = string[ndx]) != 0; ndx++) - { - ac = c - '!' + 2930; - if ((ac < 2930 || ac > 3023) && c != asc_Space) - break; - - if (c > asc_Space && c < 127) - { - rotatesprite(offset<<16,y<<16,MZ,0,ac, shade, pal, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - - offset += tilesiz[ac].x; - - } - else if (c == asc_Space) - { - offset += 4; // Special case for space char - } - } - -} - //////////////////////////////////////////////// // Get an input string from user using small font //////////////////////////////////////////////// @@ -4084,19 +4322,12 @@ static int MNU_ControlAxisNum(int offset) // Miscellaneous Routines /////////////////////////////////////////////////////////////////////////////////////////////////// -typedef struct RGB_color_typ -{ - unsigned char red; - unsigned char green; - unsigned char blue; -} RGB_color, *RGB_color_ptr; #define PALETTE_MASK 0x3c6 #define PALETTE_READ 0x3c7 #define PALETTE_WRITE 0x3c8 #define PALETTE_DATA 0x3c9 -unsigned char palette_data[256][3]; // Global palette array // V E R T I C A L R E T R A C E V A R I A B L E S ////////////////////////////////////////// @@ -4292,253 +4523,6 @@ void FadeOut(unsigned char targetcolor, unsigned int clicks) } } -////////////////////////////////////////////////////////////////////////////// -#define FADE_DAMAGE_FACTOR 3 // 100 health / 32 shade cycles = 3.125 - -// Fades from 100% to 62.5% somewhat quickly, -// then from 62.5% to 37.5% slowly, -// then from 37.5% to 0% quickly. -// This seems to capture the pain caused by enemy shots, plus the extreme -// fade caused by being blinded or intense pain. -// Perhaps the next step would be to apply a gentle smoothing to the -// intersections of these lines. -static int faderamp[32] = -{ - // y=64-4x - 252,240,224,208,192,176, - - // y=44.8-(16/20)x - 160,156,152,152,148, - 144,140,136,136,132, - 128,124,120,120,116, - 112,108,104,104,100, - - // y=128-4x - 96,80,64,48,32,16 -}; - -unsigned char ppalette[MAX_SW_PLAYERS_REG][768]; - -////////////////////////////////////////// -// Set the amount of redness for damage -// the player just took -////////////////////////////////////////// -void SetFadeAmt(PLAYERp pp, short damage, unsigned char startcolor) -{ - int palreg, usereg = 0, tmpreg1 = 0, tmpreg2 = 0; - short fadedamage=0; - RGB_color color; - - //CON_ConMessage("SetAmt: fadeamt = %d, startcolor = %d, pp = %d",pp->FadeAmt,startcolor,pp->StartColor); - - if (abs(pp->FadeAmt) > 0 && startcolor == pp->StartColor) - return; - - // Don't ever over ride flash bomb - if (pp->StartColor == 1 && abs(pp->FadeAmt) > 0) - return; - - // Reset the palette - if (pp == Player + screenpeek) - { - videoFadePalette(0,0,0,0); - if (pp->FadeAmt <= 0) - GetPaletteFromVESA(&ppalette[screenpeek][0]); - } - - if (damage < -150 && damage > -1000) fadedamage = 150; - else if (damage < -1000) // Underwater - fadedamage = abs(damage+1000); - else - fadedamage = abs(damage); - - if (damage >= -5 && damage < 0) - fadedamage += 10; - - // Don't let red to TOO red - if (startcolor == COLOR_PAIN && fadedamage > 100) fadedamage = 100; - - pp->FadeAmt = fadedamage / FADE_DAMAGE_FACTOR; - - if (pp->FadeAmt <= 0) - { - pp->FadeAmt = 0; - return; - } - - // It's a health item, just do a preset flash amount - if (damage > 0) - pp->FadeAmt = 3; - - pp->StartColor = startcolor; - - pp->FadeTics = 0; - - // Set player's palette to current game palette - GetPaletteFromVESA(pp->temp_pal); - - color.red = palette_data[pp->StartColor][0]; - color.green = palette_data[pp->StartColor][1]; - color.blue = palette_data[pp->StartColor][2]; - - for (palreg = 0; palreg < 768; palreg++) - { - tmpreg1 = (int)(pp->temp_pal[palreg]) + ((2 * pp->FadeAmt) + 4); - tmpreg2 = (int)(pp->temp_pal[palreg]) - ((2 * pp->FadeAmt) + 4); - if (tmpreg1 > 255) - tmpreg1 = 255; - if (tmpreg2 < 0) - tmpreg2 = 0; - - if (usereg == 0) - { - if (pp->temp_pal[palreg] < color.red) - { - if ((pp->temp_pal[palreg] = tmpreg1) > color.red) - pp->temp_pal[palreg] = color.red; - } - else if (pp->temp_pal[palreg] > color.red) - if ((pp->temp_pal[palreg] = tmpreg2) < color.red) - pp->temp_pal[palreg] = color.red; - } - else if (usereg == 1) - { - if (pp->temp_pal[palreg] < color.green) - { - if ((pp->temp_pal[palreg] = tmpreg1) > color.green) - pp->temp_pal[palreg] = color.green; - } - else if (pp->temp_pal[palreg] > color.green) - if ((pp->temp_pal[palreg] = tmpreg2) < color.green) - pp->temp_pal[palreg] = color.green; - } - else if (usereg == 2) - { - if (pp->temp_pal[palreg] < color.blue) - { - if ((pp->temp_pal[palreg] = tmpreg1) > color.blue) - pp->temp_pal[palreg] = color.blue; - } - else if (pp->temp_pal[palreg] > color.blue) - if ((pp->temp_pal[palreg] = tmpreg2) < color.blue) - pp->temp_pal[palreg] = color.blue; - } - - if (++usereg > 2) - usereg = 0; - } - - // Do initial palette set - if (pp == Player + screenpeek) - { - if (videoGetRenderMode() < REND_POLYMOST) set_pal(pp->temp_pal); - else videoFadePalette(color.red, color.green, color.blue, faderamp[min(31,max(0,32-abs(pp->FadeAmt)))]); - if (damage < -1000) - pp->FadeAmt = 1000; // Don't call DoPaletteFlash for underwater stuff - } -} - -////////////////////////////////////////// -// Do the screen reddness based on damage -////////////////////////////////////////// -#define MAXFADETICS 5 -void DoPaletteFlash(PLAYERp pp) -{ - int i, palreg, tmpreg1 = 0, tmpreg2 = 0; - unsigned char *pal_ptr = &ppalette[screenpeek][0]; - - - if (pp->FadeAmt <= 1) - { - pp->FadeAmt = 0; - pp->StartColor = 0; - if (pp == Player + screenpeek) - { - videoFadePalette(0,0,0,0); - memcpy(pp->temp_pal, palette_data, sizeof(palette_data)); - DoPlayerDivePalette(pp); // Check Dive again - DoPlayerNightVisionPalette(pp); // Check Night Vision again - } - - return; - } - - - pp->FadeTics += synctics; // Add this frame's tic amount to - // counter - - if (pp->FadeTics >= MAXFADETICS) - { - while (pp->FadeTics >= MAXFADETICS) - { - pp->FadeTics -= MAXFADETICS; - - pp->FadeAmt--; // Decrement FadeAmt till it gets to - // 0 again. - } - } - else - return; // Return if they were not > - // MAXFADETICS - - if (pp->FadeAmt > 32) - return; - - if (pp->FadeAmt <= 1) - { - pp->FadeAmt = 0; - pp->StartColor = 0; - if (pp == Player + screenpeek) - { - videoFadePalette(0,0,0,0); - memcpy(pp->temp_pal, palette_data, sizeof(palette_data)); - DoPlayerDivePalette(pp); // Check Dive again - DoPlayerNightVisionPalette(pp); // Check Night Vision again - } - return; - } - else - { - //CON_Message("gamavalues = %d, %d, %d",pp->temp_pal[pp->StartColor],pp->temp_pal[pp->StartColor+1],pp->temp_pal[pp->StartColor+2]); - for (palreg = 0; palreg < 768; palreg++) - { - tmpreg1 = (int)(pp->temp_pal[palreg]) + 2; - tmpreg2 = (int)(pp->temp_pal[palreg]) - 2; - if (tmpreg1 > 255) - tmpreg1 = 255; - if (tmpreg2 < 0) - tmpreg2 = 0; - - if (pp->temp_pal[palreg] < pal_ptr[palreg]) - { - if ((pp->temp_pal[palreg] = tmpreg1) > pal_ptr[palreg]) - pp->temp_pal[palreg] = pal_ptr[palreg]; - } - else if (pp->temp_pal[palreg] > pal_ptr[palreg]) - if ((pp->temp_pal[palreg] = tmpreg2) < pal_ptr[palreg]) - pp->temp_pal[palreg] = pal_ptr[palreg]; - - } - - // Only hard set the palette if this is currently the player's view - if (pp == Player + screenpeek) - { - if (videoGetRenderMode() < REND_POLYMOST) set_pal(pp->temp_pal); - else - { - videoFadePalette( - palette_data[pp->StartColor][0], - palette_data[pp->StartColor][1], - palette_data[pp->StartColor][2], - faderamp[min(31,max(0,32-abs(pp->FadeAmt)))] - ); - } - } - - } - -} - void ResetPalette(PLAYERp pp) { videoFadePalette(0,0,0,0); @@ -4550,6 +4534,7 @@ void ResetPalette(PLAYERp pp) pp->FadeTics = 0; } +#endif // vim:ts=4:sw=4:enc=utf-8: FSavegameInfo GameInterface::GetSaveSig() diff --git a/source/sw/src/menus.h b/source/sw/src/menus.h index 21c7a3ee5..e6ac403f4 100644 --- a/source/sw/src/menus.h +++ b/source/sw/src/menus.h @@ -32,8 +32,15 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms BEGIN_SW_NS -#define MENU_SHADE_DEFAULT 0 -#define MENU_SHADE_INACTIVE 20 +void MNU_MeasureString(const char* string, short* w, short* h); +void MNU_DrawString(short x, short y, const char* string, short shade, short pal); +void MNU_MeasureSmallString(const char* string, short* w, short* h); +void MNU_DrawSmallString(short x, short y, const char* string, short shade, short pal); +void MNU_MeasureStringLarge(const char* string, short* w, short* h); +void MNU_DrawStringLarge(short x, short y, const char* string, int shade = 0); + + +#if 0 typedef enum { @@ -56,12 +63,6 @@ void MNU_DrawMenu(void); // This is used in drawscreen to refresh menus in // multiplay situations. void MNU_CheckForMenus(void); void MNU_CheckForMenusAnyKey(void); -void MNU_MeasureString(const char *string, short *w, short *h); -void MNU_DrawString(short x, short y, const char *string, short shade, short pal); -void MNU_MeasureSmallString(const char *string,short *w,short *h); -void MNU_DrawSmallString(short x,short y,const char *string,short shade,short pal); -void MNU_MeasureStringLarge(const char *string, short *w, short *h); -void MNU_DrawStringLarge(short x, short y, const char *string); // Functions from my other engine //void Get_Palette (unsigned char *pal); @@ -75,7 +76,6 @@ void ExitMenus(void); void ResetMenuInput(void); extern SWBOOL BorderAdjust; -extern SWBOOL MultiPlayQuitFlag; // Make memcpy an intrinsic function for an easy frame rate boost //#pragma intrinsic( memcpy ); @@ -93,8 +93,6 @@ extern SWBOOL MultiPlayQuitFlag; #define M_CX2 319 #define M_CY2 199 -#define MZ 65536 - #define asc_Esc 27 #define asc_Enter 13 #define asc_Space 32 @@ -335,6 +333,8 @@ typedef struct int x,y; } VMODE; +#endif + END_SW_NS #endif diff --git a/source/sw/src/network.cpp b/source/sw/src/network.cpp index 905e45115..d4c5db866 100644 --- a/source/sw/src/network.cpp +++ b/source/sw/src/network.cpp @@ -1497,7 +1497,6 @@ getpackets(void) NewGame = TRUE; // restart demo for multi-play mode DemoInitOnce = FALSE; - ResetMenuInput(); // send a dummy packet to see when it arrives //tempbuf[0] = PACKET_TYPE_DUMMY; diff --git a/source/sw/src/network.h b/source/sw/src/network.h index 8e9f175df..141eb4fbb 100644 --- a/source/sw/src/network.h +++ b/source/sw/src/network.h @@ -1,3 +1,4 @@ +#pragma once //------------------------------------------------------------------------- /* Copyright (C) 1997, 2005 - 3D Realms Entertainment diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index 21b0defb9..2c39ceade 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -44,6 +44,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "weapon.h" #include "fx_man.h" +#include "menu/menu.h" BEGIN_SW_NS @@ -67,7 +68,6 @@ int InitFistAttack(PLAYERp pp); //#define UK_VERSION TRUE #define PANF_UZI_XFLIP (BIT(21)) -extern SWBOOL UsingMenus; #define XDIM 320 #define YDIM 200 @@ -775,7 +775,7 @@ void PlayerUpdatePanelInfo(PLAYERp pp) if (Prediction) return; - if (UsingMenus) + if (M_Active()) return; PlayerUpdateHealth(pp, 0); diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index cb18476c2..5f1cb8962 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -65,6 +65,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "vis.h" #include "track.h" #include "interp.h" +#include "menu/menu.h" BEGIN_SW_NS @@ -2414,7 +2415,7 @@ MoveScrollMode2D(PLAYERp pp) mfsvel = mfvel = 0; - if (MenuInputMode || UsingMenus) + if (M_Active()) return; // Recenter view if told @@ -2476,7 +2477,7 @@ MoveScrollMode2D(PLAYERp pp) } } - if (!UsingMenus && !HelpInputMode && !ConPanel) + if (!M_Active() && !HelpInputMode && !ConPanel) { if (buttonMap.ButtonDown(gamefunc_Move_Forward)) { @@ -2520,8 +2521,17 @@ MoveScrollMode2D(PLAYERp pp) void DoPlayerMenuKeys(PLAYERp pp) { + if (!CommEnabled) { + // Go back to the source to set this - the old code here was catastrophically bad. + // this needs to be fixed properly - as it is this can never be compatible with demo playback. + if (cl_autoaim) + SET(Player[myconnectindex].Flags, PF_AUTO_AIM); + else + RESET(Player[myconnectindex].Flags, PF_AUTO_AIM); + +#if 0 if (TEST_SYNC_KEY((pp), SK_AUTO_AIM)) { if (FLAG_KEY_PRESSED(pp, SK_AUTO_AIM)) @@ -2532,6 +2542,7 @@ DoPlayerMenuKeys(PLAYERp pp) } else FLAG_KEY_RESET(pp, SK_AUTO_AIM); +#endif } } @@ -7660,7 +7671,7 @@ void ChopsCheck(PLAYERp pp) extern SWBOOL HelpInputMode; extern int ChopTics; - if (!UsingMenus && !HelpInputMode && !TEST(pp->Flags, PF_DEAD) && !pp->sop_riding && numplayers <= 1) + if (!M_Active() && !HelpInputMode && !TEST(pp->Flags, PF_DEAD) && !pp->sop_riding && numplayers <= 1) { if ((pp->input.bits|pp->input.vel|pp->input.svel|pp->input.angvel|pp->input.aimvel) || TEST(pp->Flags, PF_CLIMBING|PF_FALLING|PF_DIVING)) diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp index 14a71dfbf..9bb92f3d1 100644 --- a/source/sw/src/sounds.cpp +++ b/source/sw/src/sounds.cpp @@ -50,6 +50,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "rts.h" #include "menus.h" #include "config.h" +#include "menu/menu.h" #ifdef _WIN32 #include "sdlayer.h" @@ -797,7 +798,7 @@ int PlaySound(int num, int *x, int *y, int *z, Voc3D_Flags flags) // Don't play game sounds when in menus - //if (UsingMenus && (*x!=0 || *y!=0 || *z!=0)) return(-1); + //if (M_Active() && (*x!=0 || *y!=0 || *z!=0)) return(-1); // Weed out parental lock sounds if PLock is active if (adult_lockout || Global_PLock) @@ -864,7 +865,7 @@ int PlaySound(int num, int *x, int *y, int *z, Voc3D_Flags flags) // Assign voc to voc pointer vp = &voc[num]; - if (UsingMenus && *x==0 && *y==0 && *z==0) // Menus sound outdo everything + if (M_Active() && *x==0 && *y==0 && *z==0) // Menus sound outdo everything priority = 100; else priority = vp->priority; @@ -1637,7 +1638,7 @@ DoUpdateSounds3D(void) int i; static SWBOOL MoveSkip8 = 0; - if (UsingMenus) return; + if (M_Active()) return; // This function is already only call 10x per sec, this widdles it down even more! MoveSkip8 = (MoveSkip8 + 1) & 15; From d40cdd0af4c03057fdf4ef3f8f20a8ef22d4ed91 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 2 Dec 2019 21:48:04 +0100 Subject: [PATCH 089/203] - added map definition file for Wanton Destruction add-on. --- .../filter/shadowwarrior.wanton/SWCustom.txt | 261 ++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 wadsrc/static/filter/shadowwarrior.wanton/SWCustom.txt diff --git a/wadsrc/static/filter/shadowwarrior.wanton/SWCustom.txt b/wadsrc/static/filter/shadowwarrior.wanton/SWCustom.txt new file mode 100644 index 000000000..3522d227c --- /dev/null +++ b/wadsrc/static/filter/shadowwarrior.wanton/SWCustom.txt @@ -0,0 +1,261 @@ +level 1 +{ + title "Seppuku Station" + filename "$bullet.map" + song "e1l01.mid" + cdatrack 4 + besttime 60 + partime 300 +} +level 2 +{ + title "Zilla Construction" + filename "$dozer.map" + song "e1l03.mid" + cdatrack 9 + besttime 300 + partime 480 +} +level 3 +{ + title "Master Leep's Temple" + filename "$shrine.map" + song "e1l02.mid" + cdatrack 12 + besttime 196 + partime 600 +} +level 4 +{ + title "Dark Woods of the Serpent" + filename "$woods.map" + song "e1l04.mid" + cdatrack 10 + besttime 428 + partime 960 +} +level 5 +{ + title "Chinatown" + filename "$whirl.map" + song "yokoha03.mid" + cdatrack 5 + besttime 330 + partime 600 +} +level 6 +{ + title "Monastery" + filename "$tank.map" + song "nippon34.mid" + cdatrack 6 + besttime 120 + partime 240 +} +level 7 +{ + title "Trolly Yard" + filename "$boat.map" + song "execut11.mid" + cdatrack 8 + besttime 120 + partime 240 +} +level 8 +{ + title "Restaurant" + filename "$garden.map" + song "execut11.mid" + cdatrack 11 + besttime 66 + partime 120 +} +level 9 +{ + title "Skyscraper" + filename "$outpost.map" + song "sanai.mid" + cdatrack 12 + besttime 90 + partime 180 +} +level 10 +{ + title "Airplane" + filename "$hidtemp.map" + song "kotec2.mid" + cdatrack 5 + besttime 125 + partime 250 +} +level 11 +{ + title "Military Base" + filename "$plax1.map" + song "kotec2.mid" + cdatrack 10 + besttime 392 + partime 720 +} +level 12 +{ + title "Train" + filename "$bath.map" + song "yokoha03" + cdatrack 4 + besttime 600 + partime 600 +} +level 13 +{ + title "Auto Factor" + filename "$airport.map" + song "nippon34" + cdatrack 6 + besttime 180 + partime 300 +} +level 14 +{ + title "Crude Oil" + filename "$refiner.map" + song "kotoki12.mid" + cdatrack 9 + besttime 160 + partime 300 +} +level 15 +{ + title "Coolie Mines" + filename "$newmine.map" + song "hoshia02.mid" + cdatrack 7 + besttime 180 + partime 300 +} +level 16 +{ + title "Subpen 7" + filename "$subbase.map" + song "hoshia02.mid" + cdatrack 10 + besttime 122 + partime 240 +} +level 17 +{ + title "The Great Escape" + filename "$rock.map" + song "" + cdatrack 8 + besttime 198 + partime 360 +} +level 18 +{ + title "Floating Fortress" + filename "$yamato.map" + song "sanai.mid" + cdatrack 7 + besttime 698 + partime 1200 +} +level 19 +{ + title "Water Torture" + filename "$seabase.map" + song "kotec2.mid" + cdatrack 9 + besttime 307 + partime 480 +} +level 20 +{ + title "Skyline" + filename "$volcano.map" + song "" + cdatrack 10 + besttime 554 + partime 660 +} +level 21 +{ + title "Redwood Forest" + filename "$shore.map" + song "" + cdatrack 11 + besttime 240 + partime 480 +} +level 22 +{ + title "The Docks" + filename "$auto.map" + song "" + cdatrack 5 + besttime 247 + partime 480 +} +level 23 +{ + title "Waterfight (DM only)" + filename "tank.map" + song "" + cdatrack 11 + besttime 600 + partime 600 +} +level 24 +{ + title "Wanton DM 1 (DM only)" + filename "$dmwoods.map" + song "" + cdatrack 8 + besttime 600 + partime 600 +} +level 25 +{ + title "Wanton DM2 (DM only)" + filename "$dmshrin.map" + song "" + cdatrack 7 + besttime 600 + partime 600 +} +level 26 +{ + title "Lo Wang Rally (DM only" + filename "$rush.map" + song "" + cdatrack 13 + besttime 600 + partime 600 +} +level 27 +{ + title "Wanton CTF (CTF)" + filename "shotgun.map" + song "" + cdatrack 5 + besttime 600 + partime 600 +} +level 28 +{ + title "Killing Fields (CTF)" + filename "$dmdrop.map" + song "" + cdatrack 6 + besttime 600 + partime 600 +} +episode 1 +{ + title "" +} +episode 2 +{ + title "Wanton Destruction" + subtitle "" +} From 79ced02d3678d155e8d732d63a1457e9a2542527 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 Dec 2019 00:01:04 +0100 Subject: [PATCH 090/203] - implemented the Shadow Warrior menu interface. --- source/common/menu/menu.cpp | 2 + source/common/menu/savegamemanager.cpp | 400 ------------------------- source/rr/src/menus.cpp | 19 -- source/sw/CMakeLists.txt | 1 + source/sw/src/d_menu.cpp | 279 +++++++++++++++++ source/sw/src/game.h | 11 + source/sw/src/menus.cpp | 76 ++--- source/sw/src/menus.h | 123 ++++---- source/sw/src/save.cpp | 122 ++------ source/sw/src/swcvar.cpp | 1 + source/sw/src/swcvar.h | 1 + 11 files changed, 419 insertions(+), 616 deletions(-) create mode 100644 source/sw/src/d_menu.cpp diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 88413202a..0fb2937cb 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -55,6 +55,7 @@ void RegisterDukeMenus(); void RegisterRedneckMenus(); void RegisterBloodMenus(); +void RegisterSWMenus(); void RegisterLoadsaveMenus(); extern bool rotatesprite_2doverride; bool help_disabled, credits_disabled; @@ -913,6 +914,7 @@ void M_Init (void) RegisterDukeMenus(); RegisterRedneckMenus(); RegisterBloodMenus(); + RegisterSWMenus(); RegisterLoadsaveMenus(); timerSetCallback(M_Ticker); M_ParseMenuDefs(); diff --git a/source/common/menu/savegamemanager.cpp b/source/common/menu/savegamemanager.cpp index 75cedfbe8..d04b81cb0 100644 --- a/source/common/menu/savegamemanager.cpp +++ b/source/common/menu/savegamemanager.cpp @@ -705,403 +705,3 @@ CCMD(quickload) }); M_ActivateMenu(newmenu); } - -#if 0 - -// Duke -if ((buttonMap.ButtonDown(gamefunc_Quick_Load) || g_doQuickSave == 2) && (myplayer.gm & MODE_GAME)) -{ - buttonMap.ClearButton(gamefunc_Quick_Load); - - g_doQuickSave = 0; - - if (g_quickload == nullptr || !g_quickload->isValid()) - { - C_DoCommand("openloadmenu"); - } - else if (g_quickload->isValid()) - { - inputState.keyFlushChars(); - inputState.ClearKeysDown(); - if (G_LoadPlayerMaybeMulti(*g_quickload) != 0) - g_quickload->reset(); - } -} - -if ((buttonMap.ButtonDown(gamefunc_Quick_Save) || g_doQuickSave == 1) && (myplayer.gm & MODE_GAME)) -{ - buttonMap.ClearButton(gamefunc_Quick_Save); - - g_doQuickSave = 0; - - if (!g_lastusersave.isValid()) - { - C_DoCommand("opensavemenu"); - return; - } - inputState.keyFlushChars(); - - if (sprite[myplayer.i].extra <= 0) - { - P_DoQuote(QUOTE_SAVE_DEAD, &myplayer); - return; - } - - g_screenCapture = 1; - G_DrawRooms(myconnectindex, 65536); - g_screenCapture = 0; - - if (g_lastusersave.isValid()) - { - savebrief_t& sv = g_lastusersave; - - // dirty hack... char 127 in last position indicates an auto-filled name - if (sv.name[MAXSAVEGAMENAME] == 127) - { - strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME); - sv.name[MAXSAVEGAMENAME] = 127; - } - - g_quickload = &sv; - G_SavePlayerMaybeMulti(sv); - } - } - - -// handle CON_SAVE and CON_SAVENN -if (g_saveRequested) -{ - inputState.keyFlushChars(); - videoNextPage(); - - g_screenCapture = 1; - G_DrawRooms(myconnectindex, 65536); - g_screenCapture = 0; - - G_SavePlayerMaybeMulti(g_lastautosave, true); - g_quickload = &g_lastautosave; - - OSD_Printf("Saved: %s\n", g_lastautosave.path); - - g_saveRequested = false; -} - - -// RR - -if ((buttonMap.ButtonDown(gamefunc_Quick_Load) || g_doQuickSave == 2) && (!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && (g_player[myconnectindex].ps->gm & MODE_GAME)) -{ - buttonMap.ClearButton(gamefunc_Quick_Load); - - g_doQuickSave = 0; - - if (g_quickload == nullptr || !g_quickload->isValid()) - { - C_DoCommand("openloadmenu"); - } - else if (g_quickload->isValid()) - { - inputState.keyFlushChars(); - inputState.ClearKeysDown(); - S_PauseSounds(true); - if (G_LoadPlayerMaybeMulti(*g_quickload) != 0) - g_quickload->reset(); - } -} - -if ((buttonMap.ButtonDown(gamefunc_Quick_Save) || g_doQuickSave == 1) && (!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && (g_player[myconnectindex].ps->gm & MODE_GAME)) -{ - buttonMap.ClearButton(gamefunc_Quick_Save); - - g_doQuickSave = 0; - - if (!g_lastusersave.isValid()) - { - C_DoCommand("opensavemenu"); - return; - } - - inputState.keyFlushChars(); - - if (sprite[g_player[myconnectindex].ps->i].extra <= 0) - { - P_DoQuote(QUOTE_SAVE_DEAD, g_player[myconnectindex].ps); - return; - } - - g_screenCapture = 1; - G_DrawRooms(myconnectindex, 65536); - g_screenCapture = 0; - - if (g_lastusersave.isValid()) - { - savebrief_t& sv = g_lastusersave; - - // dirty hack... char 127 in last position indicates an auto-filled name - if (sv.name[MAXSAVEGAMENAME] == 127) - { - strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME); - sv.name[MAXSAVEGAMENAME] = 127; - } - - g_quickload = &sv; - G_SavePlayerMaybeMulti(sv); - } -} - -// sw - -SWBOOL DoQuickSave(short save_num) -{ - PauseAction(); - - if (SaveGame(save_num) != -1) - { - QuickLoadNum = save_num; - - LastSaveNum = -1; - - return FALSE; - } - - return TRUE; -} - -SWBOOL DoQuickLoad() -{ - inputState.ClearKeysDown(); - - PauseAction(); - - ReloadPrompt = FALSE; - if (LoadGame(QuickLoadNum) == -1) - { - return FALSE; - } - - ready2send = 1; - LastSaveNum = -1; - - return TRUE; -} - - -// F6 quick save -if (inputState.GetKeyStatus(KEYSC_F6)) -{ - inputState.ClearKeyStatus(KEYSC_F6); - if (!TEST(pp->Flags, PF_DEAD)) - { - if (QuickLoadNum < 0) - { - inputState.SetKeyStatus(sc_Escape); - ControlPanelType = ct_savemenu; - } - else - { - inputState.ClearAllInput(); - DoQuickSave(QuickLoadNum); - ResumeAction(); - } - } -} - -// F9 quick load -if (inputState.GetKeyStatus(KEYSC_F9)) -{ - inputState.ClearKeyStatus(KEYSC_F9); - - if (!TEST(pp->Flags, PF_DEAD)) - { - if (QuickLoadNum < 0) - { - inputState.SetKeyStatus(sc_Escape); - ControlPanelType = ct_loadmenu; - } - else - { - DoQuickLoad(); - ResumeAction(); - } - } -} - -//////////////////////////////////////////////// -// Load Game menu -// This function gets called whenever you -// press enter on one of the load game -// spots. -// I'm figuring it need to do the following: -// . Load the game if there is one by calling: MNU_LoadGameCustom. -//////////////////////////////////////////////// -SWBOOL MNU_GetLoadCustom(void) -{ - short load_num; - - load_num = currentmenu->cursor; - - // no saved game exists - don't do anything - if (SaveGameDescr[load_num][0] == '\0') - return FALSE; - - if (InMenuLevel || DemoMode || DemoPlaying) - { - LoadSaveMsg("Loading..."); - - if (LoadGame(load_num) == -1) - return FALSE; - - QuickLoadNum = load_num; - // the (Quick)Save menu should default to the last loaded game - SaveGameGroup.cursor = load_num; - - ExitMenus(); - ExitLevel = TRUE; - LoadGameOutsideMoveLoop = TRUE; - if (DemoMode || DemoPlaying) - LoadGameFromDemo = TRUE; - - return TRUE; - } - - LoadSaveMsg("Loading..."); - - PauseAction(); - - if (LoadGame(load_num) == -1) - { - ResumeAction(); - return FALSE; - } - - QuickLoadNum = load_num; - // the (Quick)Save menu should default to the last loaded game - SaveGameGroup.cursor = load_num; - - ready2send = 1; - LastSaveNum = -1; - ExitMenus(); - - if (DemoMode) - { - ExitLevel = TRUE; - DemoPlaying = FALSE; - } - - return TRUE; -} - -//////////////////////////////////////////////// -// Save Game menu -// This function gets called whenever you -// press enter on one of the save game -// spots. -// I'm figuring it need to do the following: -// . Call MNU_GetInput to allow string input of description. -// . Save the game if there is one by calling: MNU_SaveGameCustom. -//////////////////////////////////////////////// -SWBOOL MNU_GetSaveCustom(void) -{ - short save_num; - extern SWBOOL InMenuLevel, LoadGameOutsideMoveLoop; - - save_num = currentmenu->cursor; - - if (InMenuLevel) - return FALSE; - - if (MenuInputMode) - { - LoadSaveMsg("Saving..."); - - if (DoQuickSave(save_num) == FALSE) - { - LoadGameGroup.cursor = save_num; - } - - ResumeAction(); - ExitMenus(); - - // toggle edit mode - MenuInputMode = FALSE; - } - else - { - strcpy(BackupSaveGameDescr, SaveGameDescr[save_num]); - - // clear keyboard buffer - while (inputState.keyBufferWaiting()) - { - if (inputState.keyGetChar() == 0) - inputState.keyGetChar(); - } - - // toggle edit mode - MenuInputMode = TRUE; - } - - return TRUE; -} - - - -// Blood -static void DoQuickLoad(void) -{ - if (!gGameMenuMgr.m_bActive) - { - if (gQuickLoadSlot != -1) - { - QuickLoadGame(); - return; - } - if (gQuickLoadSlot == -1 && gQuickSaveSlot != -1) - { - gQuickLoadSlot = gQuickSaveSlot; - QuickLoadGame(); - return; - } - gGameMenuMgr.Push(&menuLoadGame, -1); - } -} - -static void DoQuickSave(void) -{ - if (gGameStarted && !gGameMenuMgr.m_bActive && gPlayer[myconnectindex].pXSprite->health != 0) - { - if (gQuickSaveSlot != -1) - { - QuickSaveGame(); - return; - } - gGameMenuMgr.Push(&menuSaveGame, -1); - } -} - -if (gDoQuickSave) -{ - inputState.keyFlushScans(); - switch (gDoQuickSave) - { - case 1: - DoQuickSave(); - break; - case 2: - DoQuickLoad(); - break; - } - gDoQuickSave = 0; - return; -} - - case sc_F6: - inputState.keyFlushScans(); - DoQuickSave(); - break; - case sc_F9: - inputState.keyFlushScans(); - DoQuickLoad(); - break; - - -#endif \ No newline at end of file diff --git a/source/rr/src/menus.cpp b/source/rr/src/menus.cpp index 0bbaf8fc6..238839e89 100644 --- a/source/rr/src/menus.cpp +++ b/source/rr/src/menus.cpp @@ -1390,25 +1390,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) switch (cm) { - case MENU_MAIN_INGAME: - l += 4; - fallthrough__; - case MENU_MAIN: - if (RR) - { - if (RRRA) - rotatesprite_fs(origin.x + ((MENU_MARGIN_CENTER-5)<<16), origin.y + ((57+l)<<16), 16592L,0,THREEDEE,0,0,10); - else - rotatesprite_fs(origin.x + ((MENU_MARGIN_CENTER+5)<<16), origin.y + ((24+l)<<16), 23592L,0,INGAMEDUKETHREEDEE,0,0,10); - } - else - { - rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y + ((28+l)<<16), 65536L,0,INGAMEDUKETHREEDEE,0,0,10); - if (PLUTOPAK) // JBF 20030804 - rotatesprite_fs(origin.x + ((MENU_MARGIN_CENTER+100)<<16), origin.y + (36<<16), 65536L,0,PLUTOPAKSPRITE+2,(sintable[((int32_t) totalclock<<4)&2047]>>11),0,2+8); - } - break; - case MENU_CDPLAYER: rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y+(100<<16),32768L,0,CDPLAYER,16,0,10); break; diff --git a/source/sw/CMakeLists.txt b/source/sw/CMakeLists.txt index 197582dcd..30277199e 100644 --- a/source/sw/CMakeLists.txt +++ b/source/sw/CMakeLists.txt @@ -102,6 +102,7 @@ set( PCH_SOURCES src/zilla.cpp src/zombie.cpp src/swcvar.cpp + src/d_menu.cpp ) diff --git a/source/sw/src/d_menu.cpp b/source/sw/src/d_menu.cpp new file mode 100644 index 000000000..abd344ce1 --- /dev/null +++ b/source/sw/src/d_menu.cpp @@ -0,0 +1,279 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2016 EDuke32 developers and contributors +Copyright (C) 2019 Christoph Oelckers + +This is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +//------------------------------------------------------------------------- + +#include "ns.h" // Must come before everything else! +#include "build.h" +#include "osd.h" + +#include "keys.h" +#include "names2.h" +#include "panel.h" +#include "game.h" +#include "tags.h" +#include "sector.h" +#include "sprite.h" +#include "weapon.h" +#include "player.h" +#include "jsector.h" +#include "control.h" +#include "menus.h" +#include "sw_strs.h" +#include "pal.h" +#include "demo.h" +#include "input.h" +#include "keydef.h" + +#include "gamecontrol.h" +#include "gamedefs.h" +#include "config.h" +#include "network.h" +#include "fx_man.h" +#include "music.h" +#include "text.h" +#include "version.h" +#include "network.h" + +#include "colormap.h" +#include "config.h" +#include "menu/menu.h" + +#include "../../glbackend/glbackend.h" + + +BEGIN_SW_NS + +int handle1; + +void Menu_Init(void) +{ + + +} + +//---------------------------------------------------------------------------- +// +// Implements the native looking menu used for the main menu +// and the episode/skill selection screens, i.e. the parts +// that need to look authentic +// +//---------------------------------------------------------------------------- + +class SWMainMenu : public DListMenu +{ + void PreDraw() override + { + rotatesprite(160, 15, 65536, 0, pic_shadow_warrior, + m_defshade, 0, ROTATE_SPRITE_SCREEN_CLIP, 0, 0, xdim - 1, ydim - 1); + } +}; + +static bool DidOrderSound; +static int zero = 0; +class SWOrderMenu : public DImageScrollerMenu +{ +public: + SWOrderMenu() + { + if (SW_SHAREWARE && !DidOrderSound) + { + DidOrderSound = true; + int choose_snd = STD_RANDOM_RANGE(1000); + if (choose_snd > 500) + PlaySound(DIGI_WANGORDER1, &zero, &zero, &zero, v3df_dontpan); + else + PlaySound(DIGI_WANGORDER2, &zero, &zero, &zero, v3df_dontpan); + } + } +}; + +//---------------------------------------------------------------------------- +// +// Menu related game interface functions +// +//---------------------------------------------------------------------------- + +void GameInterface::DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) +{ + short w, h; + switch (fontnum) + { + case NIT_BigFont: + MNU_MeasureStringLarge(text, &w, &h); + if (flags & LMF_Centered) xpos -= w/2; + MNU_DrawStringLarge(short(xpos), short(ypos), text, state == NIT_InactiveState? 20 : 0); + break; + + case NIT_SmallFont: + MNU_MeasureString(text, &w, &h); + if (flags & LMF_Centered) xpos -= w/2; + MNU_DrawString(short(xpos), short(ypos), text, state == NIT_InactiveState? 20 : 0, 16); + break; + + case NIT_TinyFont: + MNU_MeasureSmallString(text, &w, &h); + if (flags & LMF_Centered) xpos -= w/2; + MNU_DrawSmallString(short(xpos), short(ypos), text, state == NIT_InactiveState? 20 : 0, 16); + break; + } + if (state == NIT_SelectedState) + { + int x = int(xpos), y = int(ypos); + int scale = 65536; + short w,h; + + if (text) + { + scale /= 2; + x -= mulscale17(tilesiz[pic_yinyang].x,scale) + 2; + y += 4; + } + else + { + scale -= (1<<13); + x -= ((tilesiz[pic_yinyang].x) / 2) - 3; + y += 8; + } + + rotatesprite(x << 16, y << 16, + scale, 0, pic_yinyang, 2, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); + } +} + + +void GameInterface::MenuOpened() +{ +} + +void GameInterface::MenuSound(EMenuSounds snd) +{ + switch (snd) + { + case CursorSound: + PlaySound(DIGI_STAR,&zero,&zero,&zero,v3df_dontpan); + break; + + case AdvanceSound: + PlaySound(DIGI_SWORDSWOOSH,&zero,&zero,&zero,v3df_dontpan); + break; + + case CloseSound: + PlaySound(DIGI_STARCLINK,&zero,&zero,&zero,v3df_dontpan); + break; + + default: + return; + } +} + +void GameInterface::MenuClosed() +{ + if (!LoadGameOutsideMoveLoop) + { + ResumeGame(); + SetRedrawScreen(&Player[myconnectindex]); + } +} + +extern SWBOOL InMenuLevel; +extern SWBOOL DemoMode; +extern SWBOOL ExitLevel, NewGame; + +bool GameInterface::CanSave() +{ + return (!CommEnabled && numplayers ==1 && !DemoMode && !InMenuLevel && !TEST(Player[myconnectindex].Flags, PF_DEAD)); +} + +void GameInterface::StartGame(FGameStartup& gs) +{ + PLAYERp pp = Player + screenpeek; + int handle = 0; + int zero = 0; + + // always assumed that a demo is playing + + ready2send = 0; + + if (gs.Episode >= 1) + Level = 5; + else + Level = 1; + + DemoPlaying = FALSE; + ExitLevel = TRUE; + NewGame = TRUE; + DemoMode = FALSE; + CameraTestMode = FALSE; + Skill = gs.Skill; + + //InitNewGame(); + + if (Skill == 0) + handle = PlaySound(DIGI_TAUNTAI3,&zero,&zero,&zero,v3df_none); + else if (Skill == 1) + handle = PlaySound(DIGI_NOFEAR,&zero,&zero,&zero,v3df_none); + else if (Skill == 2) + handle = PlaySound(DIGI_WHOWANTSWANG,&zero,&zero,&zero,v3df_none); + else if (Skill == 3) + handle = PlaySound(DIGI_NOPAIN,&zero,&zero,&zero,v3df_none); + + if (handle > FX_Ok) + while (FX_SoundActive(handle)) + handleevents(); +} + +FSavegameInfo GameInterface::GetSaveSig() +{ + return { SAVESIG_SW, MINSAVEVER_SW, SAVEVER_SW }; +} + +void GameInterface::DrawMenuCaption(const DVector2& origin, const char* text) +{ + short w, h; + // Draw the backdrop bar + rotatesprite(10 << 16, (5-3) << 16, 65536, 0, 2427, + 2, 0, MenuDrawFlags|ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); + MNU_MeasureStringLarge(text, &w, &h); + MNU_DrawString(TEXT_XCENTER(w), 5, text, 1, 16); +} + +void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) +{ +} + + + +END_SW_NS + +//---------------------------------------------------------------------------- +// +// Class registration +// +//---------------------------------------------------------------------------- + + +static TMenuClassDescriptor _mm("ShadowWarrior.MainMenu"); +static TMenuClassDescriptor _so("ShadowWarrior.OrderMenu"); + +void RegisterSWMenus() +{ + menuClasses.Push(&_mm); + menuClasses.Push(&_so); +} diff --git a/source/sw/src/game.h b/source/sw/src/game.h index b4e07fe38..fd2de23cb 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -2381,7 +2381,18 @@ struct GameInterface : ::GameInterface bool validate_hud(int) override; void set_hud_layout(int size) override; void set_hud_scale(int size) override; + void DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) override; + void MenuOpened() override; + void MenuSound(EMenuSounds snd) override; + void MenuClosed() override; + bool CanSave() override; + void StartGame(FGameStartup& gs) override; FSavegameInfo GetSaveSig() override; + void DrawMenuCaption(const DVector2& origin, const char* text) override; + void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) override; + bool LoadGame(FSaveGameNode* sv) override; + bool SaveGame(FSaveGameNode* sv) override; + }; diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index de61a05ca..075413c55 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -634,6 +634,36 @@ void DoPaletteFlash(PLAYERp pp) } +SWBOOL MNU_ShareWareMessage() +{ + const char* extra_text; + short w, h; + + if (SW_SHAREWARE) + { + extra_text = "Be sure to call 800-3DREALMS today"; + MNU_MeasureString(extra_text, &w, &h); + MNU_DrawString(TEXT_XCENTER(w), 110, extra_text, 1, 16); + extra_text = "and order the game."; + MNU_MeasureString(extra_text, &w, &h); + MNU_DrawString(TEXT_XCENTER(w), 120, extra_text, 1, 16); + extra_text = "You are only playing the first "; + MNU_MeasureString(extra_text, &w, &h); + MNU_DrawString(TEXT_XCENTER(w), 130, extra_text, 1, 16); + extra_text = "four levels, and are missing most"; + MNU_MeasureString(extra_text, &w, &h); + MNU_DrawString(TEXT_XCENTER(w), 140, extra_text, 1, 16); + extra_text = "of the game, weapons and monsters."; + MNU_MeasureString(extra_text, &w, &h); + MNU_DrawString(TEXT_XCENTER(w), 150, extra_text, 1, 16); + extra_text = "See the ordering information."; + MNU_MeasureString(extra_text, &w, &h); + MNU_DrawString(TEXT_XCENTER(w), 160, extra_text, 1, 16); + //SET(item->flags, mf_disabled); + } + return TRUE; +} + # if 0 @@ -2105,47 +2135,6 @@ ExitMenus(void) } SWBOOL -MNU_StartGame(void) -{ - PLAYERp pp = Player + screenpeek; - int handle = 0; - int zero = 0; - - // always assumed that a demo is playing - - ready2send = 0; - Skill = currentmenu->cursor; - - if (EpisodeMenuSelection >= 1) - Level = 5; - else - Level = 1; - - ExitMenus(); - DemoPlaying = FALSE; - ExitLevel = TRUE; - NewGame = TRUE; - DemoMode = FALSE; - CameraTestMode = FALSE; - - //InitNewGame(); - - if (Skill == 0) - handle = PlaySound(DIGI_TAUNTAI3,&zero,&zero,&zero,v3df_none); - else if (Skill == 1) - handle = PlaySound(DIGI_NOFEAR,&zero,&zero,&zero,v3df_none); - else if (Skill == 2) - handle = PlaySound(DIGI_WHOWANTSWANG,&zero,&zero,&zero,v3df_none); - else if (Skill == 3) - handle = PlaySound(DIGI_NOPAIN,&zero,&zero,&zero,v3df_none); - - if (handle > FX_Ok) - while (FX_SoundActive(handle)) - handleevents(); - - return TRUE; -} - void ResetMenuInput(void) { cust_callback = NULL; @@ -4537,10 +4526,5 @@ void ResetPalette(PLAYERp pp) #endif // vim:ts=4:sw=4:enc=utf-8: -FSavegameInfo GameInterface::GetSaveSig() -{ - return { SAVESIG_SW, MINSAVEVER_SW, SAVEVER_SW }; -} - END_SW_NS diff --git a/source/sw/src/menus.h b/source/sw/src/menus.h index e6ac403f4..d28c0c952 100644 --- a/source/sw/src/menus.h +++ b/source/sw/src/menus.h @@ -39,65 +39,6 @@ void MNU_DrawSmallString(short x, short y, const char* string, short shade, shor void MNU_MeasureStringLarge(const char* string, short* w, short* h); void MNU_DrawStringLarge(short x, short y, const char* string, int shade = 0); - -#if 0 - -typedef enum -{ - ct_mainmenu, ct_savemenu, ct_loadmenu, ct_soundmenu, ct_optionmenu, ct_quickloadmenu, - ct_quitmenu, ct_ordermenu, ct_episodemenu, ct_max -} CTLType; - -extern SWBOOL UsingMenus; -extern int SENSITIVITY; -extern CTLType ControlPanelType; -extern int16_t MenuTextShade; -extern int16_t MenuTextPalette; - -// Prototypes -//void MNU_DoMenu( CTLType type, PLAYERp pp ); -void MNU_InitMenus(void); -//void (*CustomRefresh)(void); -//void MNU_Refresh( void ); -void MNU_DrawMenu(void); // This is used in drawscreen to refresh menus in -// multiplay situations. -void MNU_CheckForMenus(void); -void MNU_CheckForMenusAnyKey(void); - -// Functions from my other engine -//void Get_Palette (unsigned char *pal); -//void Set_Palette(unsigned char *buff); -//void Fade_Timer(int clicks); -void FadeIn(unsigned char targetcolor, unsigned int clicks); -void FadeOut(unsigned char targetcolor, unsigned int clicks); -void ResetPalette(PLAYERp pp); - -void ExitMenus(void); -void ResetMenuInput(void); - -extern SWBOOL BorderAdjust; - -// Make memcpy an intrinsic function for an easy frame rate boost -//#pragma intrinsic( memcpy ); - -// L O C A L V A R I A B L E S //////////////////////////////////////////////////////////////// - -// Default menu pic brightness -#define m_defshade 2 - -#define FLASHTIME 60 // One second per icon flash - -// Defines for permanentwritesprite clipping box -#define M_CX1 0 -#define M_CY1 0 -#define M_CX2 319 -#define M_CY2 199 - -#define asc_Esc 27 -#define asc_Enter 13 -#define asc_Space 32 - - #define pic_none 0 #define pic_radiobuttn1 2816 #define pic_radiobuttn2 2817 @@ -150,6 +91,69 @@ extern SWBOOL BorderAdjust; #define pic_savedescr 2924 #define pic_shadow_warrior 2366 +#define m_defshade 2 +#define MenuDrawFlags (ROTATE_SPRITE_SCREEN_CLIP) +extern SWBOOL LoadGameOutsideMoveLoop; + + +#if 0 + +typedef enum +{ + ct_mainmenu, ct_savemenu, ct_loadmenu, ct_soundmenu, ct_optionmenu, ct_quickloadmenu, + ct_quitmenu, ct_ordermenu, ct_episodemenu, ct_max +} CTLType; + +extern SWBOOL UsingMenus; +extern int SENSITIVITY; +extern CTLType ControlPanelType; +extern int16_t MenuTextShade; +extern int16_t MenuTextPalette; + +// Prototypes +//void MNU_DoMenu( CTLType type, PLAYERp pp ); +void MNU_InitMenus(void); +//void (*CustomRefresh)(void); +//void MNU_Refresh( void ); +void MNU_DrawMenu(void); // This is used in drawscreen to refresh menus in +// multiplay situations. +void MNU_CheckForMenus(void); +void MNU_CheckForMenusAnyKey(void); + +// Functions from my other engine +//void Get_Palette (unsigned char *pal); +//void Set_Palette(unsigned char *buff); +//void Fade_Timer(int clicks); +void FadeIn(unsigned char targetcolor, unsigned int clicks); +void FadeOut(unsigned char targetcolor, unsigned int clicks); +void ResetPalette(PLAYERp pp); + +void ExitMenus(void); +void ResetMenuInput(void); + +extern SWBOOL BorderAdjust; + +// Make memcpy an intrinsic function for an easy frame rate boost +//#pragma intrinsic( memcpy ); + +// L O C A L V A R I A B L E S //////////////////////////////////////////////////////////////// + +// Default menu pic brightness + +#define FLASHTIME 60 // One second per icon flash + +// Defines for permanentwritesprite clipping box +#define M_CX1 0 +#define M_CY1 0 +#define M_CX2 319 +#define M_CY2 199 + +#define asc_Esc 27 +#define asc_Enter 13 +#define asc_Space 32 + + + // This is the current values set with all slider bar functions #define SENSE_DEFAULT 10 // Default mouse sensitivity ** should be 5!!! #define FXVOL_DEFAULT 8 // Default sound fx volume @@ -226,7 +230,6 @@ enum typedef int MenuFlags; #define MenuSelectFlags (mf_pushed | mf_selected | mf_disabled) -#define MenuDrawFlags (ROTATE_SPRITE_SCREEN_CLIP) typedef enum { diff --git a/source/sw/src/save.cpp b/source/sw/src/save.cpp index 56f5c242e..791f670b6 100644 --- a/source/sw/src/save.cpp +++ b/source/sw/src/save.cpp @@ -221,7 +221,8 @@ int LoadSymCodeInfo(MFILE_READ fil, void **ptr) } -int SaveGame(short save_num) + +bool GameInterface::SaveGame(FSaveGameNode *sv) { MFILE_WRITE fil; int i,j; @@ -247,16 +248,13 @@ int SaveGame(short save_num) Saveable_Init(); - FStringf base("save%04d", save_num); - auto game_name = G_BuildSaveName(base); + auto game_name = G_BuildSaveName(sv->Filename); OpenSaveGameForWrite(game_name); - G_WriteSaveHeader(SaveGameDescr[save_num], LevelInfo[Level].LevelName, LevelInfo[Level].Description); + G_WriteSaveHeader(sv->SaveTitle, LevelInfo[Level].LevelName, LevelInfo[Level].Description); fil = WriteSavegameChunk("snapshot.sw"); MWRITE(&GameVersion,sizeof(GameVersion),1,fil); - MWRITE(SaveGameDescr[save_num],sizeof(SaveGameDescr[save_num]),1,fil); - MWRITE(&Level,sizeof(Level),1,fil); MWRITE(&Skill,sizeof(Skill),1,fil); @@ -693,78 +691,17 @@ int SaveGame(short save_num) //MWRITE(&Zombies, sizeof(Zombies), 1, fil); MCLOSE_WRITE(fil); + if (!saveisshot) + return FinishSavegameWrite(); - ////DSPRINTF(ds, "done saving"); - //MONO_PRINT(ds); - - if (saveisshot) - CON_Message("There was a problem saving. See \"Save Help\" section of release notes."); - - return saveisshot ? -1 : 0; -} - -int LoadGameFullHeader(short save_num, char *descr, short *level, short *skill) -{ -#if 0 // only used by the menu. Will go away soon. - MFILE_READ fil; - char game_name[256]; - short tile; - int ver; - - snprintf(game_name, 256, "%sgame%d.sav", M_GetSavegamesPath().GetChars(), save_num); - if ((fil = MOPEN_READ(game_name)) == MOPEN_READ_ERR) - return -1; - - MREAD(&ver,sizeof(ver),1,fil); - if (ver != GameVersion) - { - MCLOSE_READ(fil); - return -1; - } - - MREAD(descr, sizeof(SaveGameDescr[0]), 1,fil); - - MREAD(level,sizeof(*level),1,fil); - MREAD(skill,sizeof(*skill),1,fil); - - tile = ScreenLoadSaveSetup(Player + myconnectindex); - ScreenLoad(fil); - - MCLOSE_READ(fil); - - return tile; -#else - return 0; -#endif -} - -void LoadGameDescr(short save_num, char *descr) -{ -#if 0 - MFILE_READ fil; - char game_name[256]; - short tile; - int ver; - - snprintf(game_name, 256, "%sgame%d.sav", M_GetSavegamesPath().GetChars(), save_num); - if ((fil = MOPEN_READ(game_name)) == MOPEN_READ_ERR) - return; - - MREAD(&ver,sizeof(ver),1,fil); - if (ver != GameVersion) - { - MCLOSE_READ(fil); - return; - } - - MREAD(descr, sizeof(SaveGameDescr[0]),1,fil); - - MCLOSE_READ(fil); -#endif + return false; } -int LoadGame(short save_num) +extern SWBOOL LoadGameOutsideMoveLoop; +extern SWBOOL InMenuLevel; + +bool GameInterface::LoadGame(FSaveGameNode* sv) { MFILE_READ fil; int i,j,saveisshot=0; @@ -786,23 +723,23 @@ int LoadGame(short save_num) int StateStartNdx; int StateNdx; int StateEndNdx; - extern SWBOOL InMenuLevel; + + if (!InMenuLevel) PauseAction(); Saveable_Init(); - FStringf base("save%04d", save_num); - auto game_name = G_BuildSaveName(base); + auto game_name = G_BuildSaveName(sv->Filename); OpenSaveGameForRead(game_name); auto filr = ReadSavegameChunk("snapshot.sw"); - if (!filr.isOpen()) return -1; + if (!filr.isOpen()) return false; fil = &filr; MREAD(&i,sizeof(i),1,fil); if (i != GameVersion) { MCLOSE_READ(fil); - return -1; + return false; } // Don't terminate until you've made sure conditions are valid for loading. @@ -814,8 +751,6 @@ int LoadGame(short save_num) Terminate3DSounds(); - MREAD(SaveGameDescr[save_num], sizeof(SaveGameDescr[save_num]),1,fil); - MREAD(&Level,sizeof(Level),1,fil); MREAD(&Skill,sizeof(Skill),1,fil); @@ -855,7 +790,7 @@ int LoadGame(short save_num) saveisshot |= LoadSymCodeInfo(fil, (void **)&pp->DoPlayerAction); saveisshot |= LoadSymDataInfo(fil, (void **)&pp->sop_control); saveisshot |= LoadSymDataInfo(fil, (void **)&pp->sop_riding); - if (saveisshot) { MCLOSE_READ(fil); return -1; } + if (saveisshot) { MCLOSE_READ(fil); return false; } } @@ -887,12 +822,12 @@ int LoadGame(short save_num) saveisshot |= LoadSymDataInfo(fil, (void **)&psp->ActionState); saveisshot |= LoadSymDataInfo(fil, (void **)&psp->RestState); saveisshot |= LoadSymCodeInfo(fil, (void **)&psp->PanelSpriteFunc); - if (saveisshot) { MCLOSE_READ(fil); return -1; } + if (saveisshot) { MCLOSE_READ(fil); return false; } for (j = 0; j < (int)SIZ(psp->over); j++) { saveisshot |= LoadSymDataInfo(fil, (void **)&psp->over[j].State); - if (saveisshot) { MCLOSE_READ(fil); return -1; } + if (saveisshot) { MCLOSE_READ(fil); return false; } } } @@ -982,7 +917,7 @@ int LoadGame(short save_num) saveisshot |= LoadSymDataInfo(fil, (void **)&u->SpriteP); saveisshot |= LoadSymDataInfo(fil, (void **)&u->PlayerP); saveisshot |= LoadSymDataInfo(fil, (void **)&u->tgt_sp); - if (saveisshot) { MCLOSE_READ(fil); return -1; } + if (saveisshot) { MCLOSE_READ(fil); return false; } MREAD(&SpriteNum,sizeof(SpriteNum),1,fil); } @@ -998,7 +933,7 @@ int LoadGame(short save_num) saveisshot |= LoadSymCodeInfo(fil, (void **)&sop->Animator); saveisshot |= LoadSymDataInfo(fil, (void **)&sop->controller); saveisshot |= LoadSymDataInfo(fil, (void **)&sop->sp_child); - if (saveisshot) { MCLOSE_READ(fil); return -1; } + if (saveisshot) { MCLOSE_READ(fil); return false; } } MREAD(SineWaveFloor, sizeof(SineWaveFloor),1,fil); @@ -1071,7 +1006,7 @@ int LoadGame(short save_num) saveisshot |= LoadSymCodeInfo(fil, (void **)&a->callback); saveisshot |= LoadSymDataInfo(fil, (void **)&a->callbackdata); - if (saveisshot) { MCLOSE_READ(fil); return -1; } + if (saveisshot) { MCLOSE_READ(fil); return false; } } #else AnimCnt = 0; @@ -1091,7 +1026,7 @@ int LoadGame(short save_num) saveisshot |= LoadSymDataInfo(fil, (void **)&a->ptr); saveisshot |= LoadSymCodeInfo(fil, (void **)&a->callback); saveisshot |= LoadSymDataInfo(fil, (void **)&a->callbackdata); - if (saveisshot) { MCLOSE_READ(fil); return -1; } + if (saveisshot) { MCLOSE_READ(fil); return false; } } #endif #endif @@ -1120,7 +1055,7 @@ int LoadGame(short save_num) MREAD(bakipos,sizeof(bakipos),1,fil); for (i = numinterpolations - 1; i >= 0; i--) saveisshot |= LoadSymDataInfo(fil, (void **)&curipos[i]); - if (saveisshot) { MCLOSE_READ(fil); return -1; } + if (saveisshot) { MCLOSE_READ(fil); return false; } // short interpolations MREAD(&short_numinterpolations,sizeof(short_numinterpolations),1,fil); @@ -1129,7 +1064,7 @@ int LoadGame(short save_num) MREAD(short_bakipos,sizeof(short_bakipos),1,fil); for (i = short_numinterpolations - 1; i >= 0; i--) saveisshot |= LoadSymDataInfo(fil, (void **)&short_curipos[i]); - if (saveisshot) { MCLOSE_READ(fil); return -1; } + if (saveisshot) { MCLOSE_READ(fil); return false; } // parental lock for (i = 0; i < (int)SIZ(otlist); i++) @@ -1311,7 +1246,12 @@ int LoadGame(short save_num) DoPlayerDivePalette(Player+myconnectindex); DoPlayerNightVisionPalette(Player+myconnectindex); - return 0; + + ExitLevel = TRUE; + LoadGameOutsideMoveLoop = TRUE; + + if (!InMenuLevel) ready2send = 1; + return true; } void diff --git a/source/sw/src/swcvar.cpp b/source/sw/src/swcvar.cpp index 61dd2961d..b61f18162 100644 --- a/source/sw/src/swcvar.cpp +++ b/source/sw/src/swcvar.cpp @@ -1,3 +1,4 @@ #include "swcvar.h" CVAR(Bool, sw_ninjahack, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); +CVAR(Bool, sw_usedarts, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); diff --git a/source/sw/src/swcvar.h b/source/sw/src/swcvar.h index 8302d574e..1ca530f7f 100644 --- a/source/sw/src/swcvar.h +++ b/source/sw/src/swcvar.h @@ -2,3 +2,4 @@ EXTERN_CVAR(Bool, sw_ninjahack) +EXTERN_CVAR(Bool, sw_usedarts) From 65ae00fb74d0f9d5fe5a4ae0290a0c341a936d2f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 Dec 2019 00:57:03 +0100 Subject: [PATCH 091/203] - completion of controls menu - some message printing cleanup in SW frontend. This still has its native console that needs to be removed. --- source/blood/src/screentext.cpp | 276 ----------------------- source/common/console/c_buttons.h | 3 - source/common/gamecvars.cpp | 43 +++- source/common/menu/menu.cpp | 10 + source/common/menu/messagebox.cpp | 86 +++++++ source/common/utility/namedef.h | 2 + source/common/utility/printf.h | 13 +- source/duke3d/src/game.cpp | 10 - source/rr/src/game.cpp | 10 - source/sw/src/console.cpp | 230 ++++++++----------- source/sw/src/draw.cpp | 2 +- source/sw/src/game.h | 7 +- source/sw/src/menus.cpp | 2 +- source/sw/src/miscactr.cpp | 2 +- source/sw/src/sounds.cpp | 2 +- source/sw/src/sprite.cpp | 2 +- source/sw/src/text.cpp | 2 +- wadsrc/static/demolition/commonbinds.txt | 26 +-- wadsrc/static/demolition/menudef.txt | 4 +- 19 files changed, 265 insertions(+), 467 deletions(-) diff --git a/source/blood/src/screentext.cpp b/source/blood/src/screentext.cpp index 57a9cbd08..c0cc18735 100644 --- a/source/blood/src/screentext.cpp +++ b/source/blood/src/screentext.cpp @@ -831,282 +831,6 @@ vec2_t G_ScreenTextShadow(int32_t sx, int32_t sy, return size; } -#if 0 -void G_PrintGameText(int32_t tile, int32_t x, int32_t y, const char *t, - int32_t s, int32_t p, int32_t o, - int32_t x1, int32_t y1, int32_t x2, int32_t y2, - int32_t z, int32_t a) -{ - int32_t f = TEXT_GAMETEXTNUMHACK; - if (t == NULL) - return; - - if (!(o & ROTATESPRITE_FULL16)) - { - x <<= 16; - y <<= 16; - } - - if (x == (160<<16)) - f |= TEXT_XCENTER; - - G_ScreenText(tile, x, y, z, 0, 0, t, s, p, 2|o|ROTATESPRITE_FULL16, a, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, x1, y1, x2, y2); -} - -vec2_t gametext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t o, int32_t a, int32_t f) -{ - return G_ScreenText(MF_Bluefont.tilenum, x, y, MF_Bluefont.zoom, 0, 0, t, s, p, o|2|8|16|ROTATESPRITE_FULL16, a, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, 0, 0, xdim-1, ydim-1); -} -void gametext_simple(int32_t x, int32_t y, const char *t) -{ - G_ScreenText(MF_Bluefont.tilenum, x, y, MF_Bluefont.zoom, 0, 0, t, 0, MF_Bluefont.pal, 2|8|16|ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags, 0, 0, xdim-1, ydim-1); -} -vec2_t mpgametext(int32_t x, int32_t y, const char *t, int32_t s, int32_t o, int32_t a, int32_t f) -{ - return G_ScreenText(MF_Bluefont.tilenum, x, y, textsc(MF_Bluefont.zoom), 0, 0, t, s, MF_Bluefont.pal, o|2|8|16|ROTATESPRITE_FULL16, a, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, 0, 0, xdim-1, ydim-1); -} -vec2_t mpgametextsize(const char *t, int32_t f) -{ - return G_ScreenTextSize(MF_Bluefont.tilenum, 0, 0, textsc(MF_Bluefont.zoom), 0, t, 2|8|16|ROTATESPRITE_FULL16, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, 0, 0, xdim-1, ydim-1); -} - -// minitext_yofs: in hud_scale-independent, (<<16)-scaled, 0-200-normalized y coords, -// (sb&ROTATESPRITE_MAX) only. -int32_t minitext_yofs = 0; -int32_t minitext_lowercase = 0; -int32_t minitext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t sb) -{ - vec2_t dim; - int32_t z = MF_Minifont.zoom; - - if (t == NULL) - { - OSD_Printf("minitext: NULL text!\n"); - return 0; - } - - if (!(sb & ROTATESPRITE_FULL16)) - { - x<<=16; - y<<=16; - } - - if (sb & ROTATESPRITE_MAX) - { - x = sbarx16(x); - y = minitext_yofs+sbary16(y); - z = sbarsc(z); - } - - sb &= (ROTATESPRITE_MAX-1)|RS_CENTERORIGIN; - - dim = G_ScreenText(MF_Minifont.tilenum, x, y, z, 0, 0, t, s, p, sb|ROTATESPRITE_FULL16, 0, MF_Minifont.emptychar.x, MF_Minifont.emptychar.y, MF_Minifont.between.x, MF_Minifont.between.y, MF_Minifont.textflags, 0, 0, xdim-1, ydim-1); - - x += dim.x; - - if (!(sb & ROTATESPRITE_FULL16)) - x >>= 16; - - return x; -} - -void menutext_(int32_t x, int32_t y, int32_t s, char const *t, int32_t o, int32_t f) -{ - G_ScreenText(MF_Redfont.tilenum, x, y - (12<<16), MF_Redfont.zoom, 0, 0, t, s, MF_Redfont.pal, o|ROTATESPRITE_FULL16, 0, MF_Redfont.emptychar.x, MF_Redfont.emptychar.y, MF_Redfont.between.x, MF_Redfont.between.y, f|MF_Redfont.textflags|TEXT_LITERALESCAPE, 0, 0, xdim-1, ydim-1); -} - -void captionmenutext(int32_t x, int32_t y, char const *t) -{ - G_ScreenText(MF_Redfont.tilenum, x, y - (12<<16), MF_Redfont.zoom, 0, 0, t, 0, ud.menutitle_pal, 2|8|16|ROTATESPRITE_FULL16, 0, MF_Redfont.emptychar.x, MF_Redfont.emptychar.y, MF_Redfont.between.x, MF_Redfont.between.y, MF_Redfont.textflags|TEXT_LITERALESCAPE|TEXT_XCENTER|TEXT_YCENTER, 0, 0, xdim-1, ydim-1); -} - - -int32_t user_quote_time[MAXUSERQUOTES]; -static char user_quote[MAXUSERQUOTES][178]; - -void G_AddUserQuote(const char *daquote) -{ - int32_t i; - - for (i=MAXUSERQUOTES-1; i>0; i--) - { - Bstrcpy(user_quote[i], user_quote[i-1]); - user_quote_time[i] = user_quote_time[i-1]; - } - Bstrcpy(user_quote[0], daquote); - OSD_Printf("%s\n", daquote); - - user_quote_time[0] = hud_messagetime; - pub = NUMPAGES; -} - -int32_t textsc(int32_t sc) -{ - return scale(sc, hud_textscale, 400); -} - - -#define FTAOPAQUETIME 30 - -// alpha increments of 8 --> 256 / 8 = 32 --> round up to power of 2 --> 32 --> divide by 2 --> 16 alphatabs required -static inline int32_t textsh(uint32_t t) -{ - return (hud_glowingquotes && ((videoGetRenderMode() == REND_CLASSIC && numalphatabs < 15) || t >= FTAOPAQUETIME)) - ? sintable[(t << 7) & 2047] >> 11 - : (sintable[(FTAOPAQUETIME << 7) & 2047] >> 11); -} - -// orientation flags depending on time that a quote has still to be displayed -static inline int32_t texto(int32_t t) -{ - if (videoGetRenderMode() != REND_CLASSIC || numalphatabs >= 15 || t > 4) - return 0; - - if (t > 2) - return 1; - - return 1|32; -} - -static inline int32_t texta(int32_t t) -{ - if (videoGetRenderMode() == REND_CLASSIC && numalphatabs < 15) - return 0; - - return 255 - clamp(t<<3, 0, 255); -} - -static FORCE_INLINE int32_t text_ypos(void) -{ - if (hud_position == 1 && ud.screen_size == 4 && ud.althud == 1) - return 32<<16; - -#ifdef GEKKO - return 16<<16; -#elif defined EDUKE32_TOUCH_DEVICES - return 24<<16; -#else - return 1<<16; -#endif -} - -// this handles both multiplayer and item pickup message type text -// both are passed on to gametext -void G_PrintGameQuotes(int32_t snum) -{ - auto const ps = g_player[snum].ps; - const int32_t reserved_quote = (ps->ftq >= QUOTE_RESERVED && ps->ftq <= QUOTE_RESERVED3); - // NOTE: QUOTE_RESERVED4 is not included. - - int32_t const ybase = (fragbarheight()<<16) + text_ypos(); - int32_t height = 0; - int32_t k = ps->fta; - - - // primary quote - - do - { - if (k <= 1) - break; - - if (EDUKE32_PREDICT_FALSE(apStrings[ps->ftq] == NULL)) - { - OSD_Printf(OSD_ERROR "%s %d null quote %d\n", "screentext:", __LINE__, ps->ftq); - break; - } - - int32_t y = ybase; - if (reserved_quote) - { -#ifdef SPLITSCREEN_MOD_HACKS - if (!g_fakeMultiMode) - y = 140<<16; - else - y = 70<<16; -#else - y = 140<<16; -#endif - } - - int32_t pal = 0; - int32_t x = 160<<16; - -#ifdef SPLITSCREEN_MOD_HACKS - if (g_fakeMultiMode) - { - pal = g_player[snum].pcolor; - const int32_t sidebyside = ud.screen_size != 0; - - if (sidebyside) - x = snum == 1 ? 240<<16 : 80<<16; - else if (snum == 1) - y += 100<<16; - } -#endif - - height = gametext_(x, y, apStrings[ps->ftq], textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1<<16); - } - while (0); - - - // userquotes - - int32_t y = ybase; - - if (k > 1 && !reserved_quote) - y += k <= 8 ? (height * (k-1))>>3 : height; - - for (int i = 0; i < MAXUSERQUOTES; i++) - { - k = user_quote_time[i]; - - if (k <= 0) - continue; - - // int32_t const sh = hud_glowingquotes ? sintable[((totalclock+(i<<2))<<5)&2047]>>11 : 0; - - height = mpgametext(mpgametext_x, y, user_quote[i], textsh(k), texto(k), texta(k), TEXT_LINEWRAP).y + textsc(1<<16); - y += k <= 4 ? (height * (k-1))>>2 : height; - } -} - -void P_DoQuote(int32_t q, DukePlayer_t *p) -{ - int32_t cq = 0; - - if (hud_messages == 0 || q < 0 || !(p->gm & MODE_GAME)) - return; - - if (q & MAXQUOTES) - { - cq = 1; - q &= ~MAXQUOTES; - } - - if (EDUKE32_PREDICT_FALSE(apStrings[q] == NULL)) - { - OSD_Printf(OSD_ERROR "%s %d null quote %d\n", "screentext:", __LINE__, q); - return; - } - - if (p->fta > 0 && q != QUOTE_RESERVED && q != QUOTE_RESERVED2) - if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return; - - p->fta = 100; - - if (p->ftq != q) - { - if (p == g_player[screenpeek].ps && apStrings[q][0] != '\0') - OSD_Printf(cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", apStrings[q]); - - p->ftq = q; - } - - pub = NUMPAGES; - pus = NUMPAGES; -} -#endif END_BLD_NS diff --git a/source/common/console/c_buttons.h b/source/common/console/c_buttons.h index d8829dc3b..7b14bca89 100644 --- a/source/common/console/c_buttons.h +++ b/source/common/console/c_buttons.h @@ -67,14 +67,11 @@ enum GameFunction_t gamefunc_Quick_Kick, gamefunc_Next_Weapon, gamefunc_Previous_Weapon, - gamefunc_Unused1, // was gamefunc_Console. Cannot be deleted thanks to CON usuing numeric indiced for addressing this list. gamefunc_Show_DukeMatch_Scores, gamefunc_Dpad_Select, gamefunc_Dpad_Aiming, gamefunc_AutoRun, gamefunc_Last_Weapon, - gamefunc_Unused2, // was quickload/quicksave - gamefunc_Unused3, gamefunc_Alt_Weapon, gamefunc_Third_Person_View, gamefunc_See_Chase_View = gamefunc_Third_Person_View, diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index 09621fe34..5ddba222f 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -47,6 +47,8 @@ #include "rts.h" #include "stats.h" #include "z_music.h" +#include "c_dispatch.h" +#include "gstrings.h" /* Notes @@ -240,7 +242,32 @@ CVARD(Bool, hud_position, false, CVAR_ARCHIVE, "aligns the status bar to the bot CVARD(Bool, hud_bgstretch, false, CVAR_ARCHIVE|CVAR_FRONTEND_DUKELIKE, "enable/disable background image stretching in wide resolutions") CVARD(Int, hud_messagetime, 120, CVAR_ARCHIVE|CVAR_FRONTEND_DUKELIKE, "length of time to display multiplayer chat messages") // Should be available to all games - the message handling should also be consolidated into a game independent feature. -/*CUSTOM_*/CVARD(Bool, hud_messages, true, CVAR_ARCHIVE | CVAR_FRONTEND_BLOOD|CVAR_FRONTEND_SHADOWWARRIOR, "enable/disable showing messages") +/*CUSTOM_*/CVARD(Bool, hud_messages, true, CVAR_ARCHIVE, "enable/disable showing messages") +CVAR(Bool, hud_messagenative, true, CVAR_ARCHIVE) + +CCMD (togglemessages) +{ + // Fixme: Needs to redirect to the frontend specific routine to handle on-screen messages. + // Ideally as an option to use the ZDoom-style notification. + // P_DoQuote(fta ? QUOTE_MESSAGES_ON : QUOTE_MESSAGES_OFF, &myplayer); (Duke/Redneck - beware of crappy implementation!!! + // void viewSetMessage(const char *pMessage, const int pal, const MESSAGE_PRIORITY priority) Blood + // void viewSetSystemMessage(const char* pMessage, ...) alternative + // void PutStringInfo(PLAYERp pp, const char *string) SW + + if (hud_messages) + { + Printf (128, "%s\n", GStrings("MSGOFF")); + hud_messages = false; + } + else + { + Printf (128, "%s\n", GStrings("MSGON")); + hud_messages = true; + } +} + + + //{ //Blood::gGameMessageMgr.SetState(self); // this is for terminaing an active message. Cannot be done like this because CVARs are global. //} @@ -487,6 +514,20 @@ CUSTOM_CVARD(Float, vid_brightness, 0.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "adju // todo: tell the system to update } +CCMD (bumpgamma) +{ + // [RH] Gamma correction tables are now generated on the fly for *any* gamma level + // Q: What are reasonable limits to use here? + + float newgamma = vid_gamma + 0.1f; + + if (newgamma > 3.0) + newgamma = 1.0; + + vid_gamma = newgamma; + Printf ("Gamma correction level %g\n", newgamma); +} + //{ "vid_contrast","adjusts contrast component of gamma ramp",(void *) &vid_contrast, CVAR_FLOAT|CVAR_FUNCPTR, 0, 10 }, //{ "vid_brightness","adjusts brightness component of gamma ramp",(void *) &vid_brightness, CVAR_FLOAT|CVAR_FUNCPTR, 0, 10 }, diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 0fb2937cb..a85917585 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -491,6 +491,16 @@ bool M_SetMenu(FName menu, int param, FName caller) return; } #endif + + case NAME_QuitMenu: + // The separate menu class no longer exists but the name still needs support for existing mods. + C_DoCommand("menu_quit"); + return true; + + case NAME_EndgameMenu: + // The separate menu class no longer exists but the name still needs support for existing mods. + C_DoCommand("memnu_endgame"); + return true; } // End of special checks diff --git a/source/common/menu/messagebox.cpp b/source/common/menu/messagebox.cpp index e8f1de041..9326dd6ae 100644 --- a/source/common/menu/messagebox.cpp +++ b/source/common/menu/messagebox.cpp @@ -377,3 +377,89 @@ DMenu* CreateMessageBoxMenu(DMenu* parent, const char* message, int messagemode, return newmenu; } + + +#if 0 +void ActivateEndGameMenu() +{ + FString tempstring = GStrings(netgame ? "NETEND" : "ENDGAME"); + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() + { + M_ClearMenus(); + if (!netgame) + { + if (demorecording) + G_CheckDemoStatus(); + D_StartTitle(); + } + }); + + M_ActivateMenu(newmenu); +} + +CCMD (menu_endgame) +{ // F7 + if (!usergame) + { + S_Sound (CHAN_VOICE | CHAN_UI, "menu/invalid", snd_menuvolume, ATTN_NONE); + return; + } + + //M_StartControlPanel (true); + S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); + + ActivateEndGameMenu(); +} + +//============================================================================= +// +// +// +//============================================================================= + +CCMD (menu_quit) +{ // F10 + if (m_quickexit) + { + ST_Endoom(); + } + + M_StartControlPanel (true); + + const size_t messageindex = static_cast(gametic) % gameinfo.quitmessages.Size(); + FString EndString; + const char *msg = gameinfo.quitmessages[messageindex]; + if (msg[0] == '$') + { + if (msg[1] == '*') + { + EndString = GStrings(msg + 2); + } + else + { + EndString.Format("%s\n\n%s", GStrings(msg + 1), GStrings("DOSY")); + } + } + else EndString = gameinfo.quitmessages[messageindex]; + + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, EndString, 0, false, NAME_None, []() + { + if (!netgame) + { + if (gameinfo.quitSound.IsNotEmpty()) + { + S_Sound(CHAN_VOICE | CHAN_UI, gameinfo.quitSound, snd_menuvolume, ATTN_NONE); + I_WaitVBL(105); + } + } + ST_Endoom(); + }); + + + M_ActivateMenu(newmenu); +} + + + + +#endif diff --git a/source/common/utility/namedef.h b/source/common/utility/namedef.h index 9268362de..ffd9c8978 100644 --- a/source/common/utility/namedef.h +++ b/source/common/utility/namedef.h @@ -38,3 +38,5 @@ xx(CustomSubMenu7) xx(UsermapMenu) xx(StartGame) xx(ImageScroller) +xx(QuitMenu) +xx(EndgameMenu) diff --git a/source/common/utility/printf.h b/source/common/utility/printf.h index a906b0a7c..fababaa95 100644 --- a/source/common/utility/printf.h +++ b/source/common/utility/printf.h @@ -39,6 +39,9 @@ enum void I_Error(const char *fmt, ...) ATTRIBUTE((format(printf,1,2))); +// This really could need some cleanup - the main problem is that it'd create +// lots of potential for merge conflicts. + int PrintString (int iprintlevel, const char *outline); int Printf (int printlevel, const char *format, ...) ATTRIBUTE((format(printf,2,3))); int Printf (const char *format, ...) ATTRIBUTE((format(printf,1,2))); @@ -48,26 +51,28 @@ int DPrintf (int level, const char *format, ...) ATTRIBUTE((format(printf,2,3))) void OSD_Printf(const char *format, ...) ATTRIBUTE((format(printf,1,2))); template -inline void initprintf(const char *format, Args&&... args) ATTRIBUTE((format(printf,1,2))) +inline void initprintf(const char *format, Args&&... args) //ATTRIBUTE((format(printf,1,2))) { OSD_Printf(format, std::forward(args)...); } // This was a define before - which should be avoided. Used by Shadow Warrior template -inline void buildprintf(const char *format, Args&&... args) ATTRIBUTE((format(printf,1,2))) +inline void buildprintf(const char *format, Args&&... args) //ATTRIBUTE((format(printf,1,2))) { OSD_Printf(format, std::forward(args)...); } + + inline void initputs(const char *s) { - PrintString(PRINT_HIGH, s); + PrintString(PRINT_HIGH|PRINT_NONOTIFY, s); } inline void buildputs(const char *s) { - PrintString(PRINT_HIGH, s); + PrintString(PRINT_HIGH|PRINT_NONOTIFY, s); } void debugprintf(const char* f, ...); // Prints to the debugger's log. diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 423e61e69..dca063bd6 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -4700,16 +4700,6 @@ void G_HandleLocalKeys(void) P_DoQuote(QUOTE_VIEW_MODE_OFF + myplayer.over_shoulder_on, &myplayer); } - if (inputState.UnboundKeyPressed(sc_F8)) - { - inputState.ClearKeyStatus(sc_F8); - - int const fta = !hud_messages; - hud_messages = 1; - P_DoQuote(fta ? QUOTE_MESSAGES_ON : QUOTE_MESSAGES_OFF, &myplayer); - hud_messages = fta; - } - if (ud.overhead_on != 0) { diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 9456c3d0a..c414339cb 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -6247,16 +6247,6 @@ void G_HandleLocalKeys(void) } } - if (inputState.UnboundKeyPressed(sc_F8)) - { - inputState.ClearKeyStatus(sc_F8); - - int const fta = !hud_messages; - hud_messages = 1; - P_DoQuote(fta ? QUOTE_MESSAGES_ON : QUOTE_MESSAGES_OFF, g_player[myconnectindex].ps); - hud_messages = fta; - } - if (ud.overhead_on != 0) { int const timerOffset = ((int) totalclock - nonsharedtimer); diff --git a/source/sw/src/console.cpp b/source/sw/src/console.cpp index 313651cea..b6afca650 100644 --- a/source/sw/src/console.cpp +++ b/source/sw/src/console.cpp @@ -250,38 +250,6 @@ SWBOOL IsCommand(const char *str) return FALSE; } -// -// Sends a message to the user quote array -// - -void CON_Message(const char *message, ...) -{ - va_list argptr; - - va_start(argptr,message); - vsprintf(&con_message[0],message,argptr); - va_end(argptr); - - // Send message to user quote array for immediate display - adduserquote(&con_message[0]); -} - -// -// Sends a message to the console quote array -// - -void CON_ConMessage(const char *message, ...) -{ - va_list argptr; - - va_start(argptr,message); - vsprintf(&con_message[0],message,argptr); - va_end(argptr); - - // Send message to user quote array for immediate display - addconquote(&con_message[0]); -} - // // Stores user arguments passed in on the command line for later inspection // @@ -389,7 +357,7 @@ void CON_ProcessUserCommand(void) } if (ConPanel) - CON_ConMessage("Syntax Error or Command not enabled!"); + OSD_Printf("Syntax Error or Command not enabled!"); } // @@ -437,7 +405,7 @@ SWBOOL CheckValidSprite(short SpriteNum) { if (SpriteNum < 0 || SpriteNum > 6144) { - CON_ConMessage("ERROR: Sprite %d is out of range.",SpriteNum); + OSD_Printf("ERROR: Sprite %d is out of range.",SpriteNum); return FALSE; } return TRUE; @@ -452,7 +420,7 @@ void CON_GetHelp(void) if (sscanf(MessageInputString,"%s %s",base,command) < 2) { - CON_ConMessage("Usage: help [keyword]"); + OSD_Printf("Usage: help [keyword]"); return; } @@ -460,25 +428,25 @@ void CON_GetHelp(void) if (!strcmp(command, "xrepeat")) { - CON_ConMessage("Usage: xrepeat [repeat value 0-255],"); - CON_ConMessage(" [User ID (-1 for all ID's)], [SpriteNum (-1 for all of type ID)]"); + OSD_Printf("Usage: xrepeat [repeat value 0-255],"); + OSD_Printf(" [User ID (-1 for all ID's)], [SpriteNum (-1 for all of type ID)]"); return; } else if (!strcmp(command, "yrepeat")) { - CON_ConMessage("Usage: yrepeat [repeat value 0-255],"); - CON_ConMessage(" [User ID (-1 for all ID's)], [SpriteNum (-1 for all of type ID)]"); + OSD_Printf("Usage: yrepeat [repeat value 0-255],"); + OSD_Printf(" [User ID (-1 for all ID's)], [SpriteNum (-1 for all of type ID)]"); return; } else if (!strcmp(command, "translucent")) { - CON_ConMessage("Usage: translucent [OFF/ON 0-1],"); - CON_ConMessage(" [User ID (-1 for all ID's)], [SpriteNum (-1 for all of type ID)]"); + OSD_Printf("Usage: translucent [OFF/ON 0-1],"); + OSD_Printf(" [User ID (-1 for all ID's)], [SpriteNum (-1 for all of type ID)]"); return; } else { - CON_ConMessage("No help was located on that subject."); + OSD_Printf("No help was located on that subject."); } } @@ -513,9 +481,9 @@ void CON_ModXrepeat(void) } } if (op2 == -1) - CON_ConMessage("Xrepeat set to %d for all u->ID's for all sprites.",op1); + OSD_Printf("Xrepeat set to %d for all u->ID's for all sprites.",op1); else - CON_ConMessage("Xrepeat set to %d for u->ID = %d for all sprites.",op1,op2); + OSD_Printf("Xrepeat set to %d for u->ID = %d for all sprites.",op1,op2); } else { @@ -526,7 +494,7 @@ void CON_ModXrepeat(void) if (!CheckValidSprite(op3)) return; sp->xrepeat = op1; - CON_ConMessage("Xrepeat set to %d for sprite %d.",op1,op3); + OSD_Printf("Xrepeat set to %d for sprite %d.",op1,op3); } } @@ -562,9 +530,9 @@ void CON_ModYrepeat(void) } } if (op2 == -1) - CON_ConMessage("Yrepeat set to %d for all u->ID's for all sprites.",op1); + OSD_Printf("Yrepeat set to %d for all u->ID's for all sprites.",op1); else - CON_ConMessage("Yrepeat set to %d for u->ID = %d for all sprites.",op1,op2); + OSD_Printf("Yrepeat set to %d for u->ID = %d for all sprites.",op1,op2); } else { @@ -575,7 +543,7 @@ void CON_ModYrepeat(void) if (!CheckValidSprite(op3)) return; sp->yrepeat = op1; - CON_ConMessage("Yrepeat set to %d for sprite %d.",op1,op3); + OSD_Printf("Yrepeat set to %d for sprite %d.",op1,op3); } } @@ -602,12 +570,12 @@ void CON_ModTranslucent(void) if (TEST(sp->cstat,CSTAT_SPRITE_TRANSLUCENT)) { RESET(sp->cstat,CSTAT_SPRITE_TRANSLUCENT); - CON_ConMessage("Translucence RESET for sprite %d.",op1); + OSD_Printf("Translucence RESET for sprite %d.",op1); } else { SET(sp->cstat,CSTAT_SPRITE_TRANSLUCENT); - CON_ConMessage("Translucence SET for sprite %d.",op1); + OSD_Printf("Translucence SET for sprite %d.",op1); } } @@ -628,7 +596,7 @@ void CON_SoundTest(void) if (op1 < 0 || op1 >= DIGI_MAX) { - CON_ConMessage("Sound number out of range."); + OSD_Printf("Sound number out of range."); return; } @@ -650,7 +618,7 @@ void CON_Reverb(void) return; } - CON_ConMessage("Reverb is now set to %d.",op1); + OSD_Printf("Reverb is now set to %d.",op1); COVER_SetReverb(op1); pp->Reverb = op1; } @@ -664,10 +632,10 @@ void CON_Heap(void) void *testheap; totalmemory = Z_AvailHeap(); - CON_ConMessage("Total heap at game startup = %d", TotalMemory); - CON_ConMessage("ActualHeap reserved for non-cache use = %d", ActualHeap); - CON_ConMessage("Total unallocated blocks in bytes minus reserved heap = %d", totalmemory); - CON_ConMessage("NOTE: Allocation exceeding ActualHeap will result in out of memory"); + OSD_Printf("Total heap at game startup = %d", TotalMemory); + OSD_Printf("ActualHeap reserved for non-cache use = %d", ActualHeap); + OSD_Printf("Total unallocated blocks in bytes minus reserved heap = %d", totalmemory); + OSD_Printf("NOTE: Allocation exceeding ActualHeap will result in out of memory"); // Find remaining heap space unused i = ActualHeap; while(i>0) @@ -677,10 +645,10 @@ void CON_Heap(void) i-=1024L; // Decrease in 1k increments else { - CON_ConMessage("Heap test result (+ or - 1k):"); - CON_ConMessage("============================="); - CON_ConMessage("Unallocated heap space remaining = %d",i); - CON_ConMessage("Unallocated heap space used = %d",ActualHeap - i); + OSD_Printf("Heap test result (+ or - 1k):"); + OSD_Printf("============================="); + OSD_Printf("Unallocated heap space remaining = %d",i); + OSD_Printf("Unallocated heap space used = %d",ActualHeap - i); FreeMem(testheap); i=0; // Beam us out of here Scotty! } @@ -688,7 +656,7 @@ void CON_Heap(void) if(ActualHeap < 50000L) { - CON_ConMessage("ALERT: Memory is critically low!"); + OSD_Printf("ALERT: Memory is critically low!"); } */ } @@ -997,14 +965,14 @@ void CON_Cache(void) } } - CON_ConMessage("/////////////////////////////////////////////"); - CON_ConMessage("Current Memory Consumption:"); - CON_ConMessage("Total Tiles = %d",tottiles); - CON_ConMessage("Total Sprites = %d",totsprites); - CON_ConMessage("Total Actors = %d",totactors); - CON_ConMessage("Total Memory = %d",(tottiles+totsprites+totactors)); - CON_ConMessage("Total with LoWang = %d",(tottiles+totsprites+totactors+TileRangeMem(1024))); - CON_ConMessage("/////////////////////////////////////////////"); + OSD_Printf("/////////////////////////////////////////////"); + OSD_Printf("Current Memory Consumption:"); + OSD_Printf("Total Tiles = %d",tottiles); + OSD_Printf("Total Sprites = %d",totsprites); + OSD_Printf("Total Actors = %d",totactors); + OSD_Printf("Total Memory = %d",(tottiles+totsprites+totactors)); + OSD_Printf("Total with LoWang = %d",(tottiles+totsprites+totactors+TileRangeMem(1024))); + OSD_Printf("/////////////////////////////////////////////"); } @@ -1014,11 +982,11 @@ void CON_SpriteInfo(void) if (SpriteInfo > 2) SpriteInfo = 0; if (SpriteInfo == 0) - CON_ConMessage("Sprite information is OFF."); + OSD_Printf("Sprite information is OFF."); else if (SpriteInfo == 1) - CON_ConMessage("Sprite information is ON (Brief Mode)."); + OSD_Printf("Sprite information is ON (Brief Mode)."); else - CON_ConMessage("Sprite information is ON (Verbose Mode)."); + OSD_Printf("Sprite information is ON (Verbose Mode)."); } void CON_KillSprite(void) @@ -1045,14 +1013,14 @@ void CON_KillSprite(void) if (!u->PlayerP) SetSuicide(i); } - CON_ConMessage("Killed all sprites except Players."); + OSD_Printf("Killed all sprites except Players."); } else { if (!CheckValidSprite(op1)) return; SetSuicide(op1); - CON_ConMessage("Killed sprite %d.",op1); + OSD_Printf("Killed sprite %d.",op1); } } @@ -1074,15 +1042,15 @@ void CON_SpriteDetail(void) if (!CheckValidSprite(op1)) return; auto const sp = (uspritetype const *)&sprite[op1]; - CON_ConMessage("x = %d, y = %d, z = %d",sp->x,sp->y,sp->z); - CON_ConMessage("cstat = %d, picnum = %d",sp->cstat,sp->picnum); - CON_ConMessage("shade = %d, pal = %d, clipdist = %d",sp->shade,sp->pal,sp->clipdist); - CON_ConMessage("xrepeat = %d, yrepeat = %d",sp->xrepeat, sp->yrepeat); - CON_ConMessage("xoffset = %d, yoffset = %d",sp->xoffset, sp->yoffset); - CON_ConMessage("sectnum = %d, statnum = %d",sp->sectnum, sp->statnum); - CON_ConMessage("ang = %d, owner = %d",sp->ang,sp->owner); - CON_ConMessage("xvel = %d, yvel = %d, zvel = %d",sp->xvel,sp->yvel,sp->zvel); - CON_ConMessage("lotag = %d, hitag = %d, extra = %d",sp->lotag,sp->hitag,sp->extra); + OSD_Printf("x = %d, y = %d, z = %d",sp->x,sp->y,sp->z); + OSD_Printf("cstat = %d, picnum = %d",sp->cstat,sp->picnum); + OSD_Printf("shade = %d, pal = %d, clipdist = %d",sp->shade,sp->pal,sp->clipdist); + OSD_Printf("xrepeat = %d, yrepeat = %d",sp->xrepeat, sp->yrepeat); + OSD_Printf("xoffset = %d, yoffset = %d",sp->xoffset, sp->yoffset); + OSD_Printf("sectnum = %d, statnum = %d",sp->sectnum, sp->statnum); + OSD_Printf("ang = %d, owner = %d",sp->ang,sp->owner); + OSD_Printf("xvel = %d, yvel = %d, zvel = %d",sp->xvel,sp->yvel,sp->zvel); + OSD_Printf("lotag = %d, hitag = %d, extra = %d",sp->lotag,sp->hitag,sp->extra); } void CON_UserDetail(void) @@ -1107,19 +1075,19 @@ void CON_UserDetail(void) if (!u) return; - CON_ConMessage("State = %p, Rot = %p",u->State,u->Rot); - CON_ConMessage("StateStart = %p, StateEnd = %p",u->StateStart,u->StateEnd); - CON_ConMessage("ActorActionFunc = %p",u->ActorActionFunc); - CON_ConMessage("ActorActionSet = %p",u->ActorActionSet); - CON_ConMessage("Personality = %p",u->Personality); - CON_ConMessage("Attrib = %p",u->Attrib); - CON_ConMessage("Flags = %d, Flags2 = %d, Tics = %d",u->Flags,u->Flags2,u->Tics); - CON_ConMessage("RotNum = %d, ID = %d",u->RotNum,u->ID); - CON_ConMessage("Health = %d, MaxHealth = %d",u->Health,u->MaxHealth); - CON_ConMessage("LastDamage = %d, PainThreshold = %d",u->LastDamage,u->PainThreshold); - CON_ConMessage("jump_speed = %d, jump_grav = %d",u->jump_speed,u->jump_grav); - CON_ConMessage("xchange = %d, ychange = %d, zchange = %d",u->xchange,u->ychange,u->zchange); - CON_ConMessage("ret = %d, WaitTics = %d, spal = %d",u->ret,u->WaitTics,u->spal); + OSD_Printf("State = %p, Rot = %p",u->State,u->Rot); + OSD_Printf("StateStart = %p, StateEnd = %p",u->StateStart,u->StateEnd); + OSD_Printf("ActorActionFunc = %p",u->ActorActionFunc); + OSD_Printf("ActorActionSet = %p",u->ActorActionSet); + OSD_Printf("Personality = %p",u->Personality); + OSD_Printf("Attrib = %p",u->Attrib); + OSD_Printf("Flags = %d, Flags2 = %d, Tics = %d",u->Flags,u->Flags2,u->Tics); + OSD_Printf("RotNum = %d, ID = %d",u->RotNum,u->ID); + OSD_Printf("Health = %d, MaxHealth = %d",u->Health,u->MaxHealth); + OSD_Printf("LastDamage = %d, PainThreshold = %d",u->LastDamage,u->PainThreshold); + OSD_Printf("jump_speed = %d, jump_grav = %d",u->jump_speed,u->jump_grav); + OSD_Printf("xchange = %d, ychange = %d, zchange = %d",u->xchange,u->ychange,u->zchange); + OSD_Printf("ret = %d, WaitTics = %d, spal = %d",u->ret,u->WaitTics,u->spal); } void CON_Quit(void) @@ -1143,7 +1111,7 @@ void CON_MultiNameChange(void) void CON_LoadSetup(void) { - CON_ConMessage("JonoF: Maybe later"); + OSD_Printf("JonoF: Maybe later"); } const char *damagename[] = @@ -1191,34 +1159,34 @@ void CON_DamageData(void) if (op1 < -1 || op1 > 46) { - CON_ConMessage("Damage Data index is out of range."); + OSD_Printf("Damage Data index is out of range."); return; } if (!strcmp(field,"damage_lo")) { DamageData[op1].damage_lo = op2; - CON_ConMessage("DamageData[%s].damage_lo = %d",damagename[op1],op2); + OSD_Printf("DamageData[%s].damage_lo = %d",damagename[op1],op2); } else if (!strcmp(field,"damage_hi")) { DamageData[op1].damage_hi = op2; - CON_ConMessage("DamageData[%s].damage_hi = %d",damagename[op1],op2); + OSD_Printf("DamageData[%s].damage_hi = %d",damagename[op1],op2); } else if (!strcmp(field,"radius")) { DamageData[op1].radius = op2; - CON_ConMessage("DamageData[%s].radius = %d",damagename[op1],op2); + OSD_Printf("DamageData[%s].radius = %d",damagename[op1],op2); } else if (!strcmp(field,"max_ammo")) { DamageData[op1].max_ammo = op2; - CON_ConMessage("DamageData[%s].max_ammo = %d",damagename[op1],op2); + OSD_Printf("DamageData[%s].max_ammo = %d",damagename[op1],op2); } else if (!strcmp(field,"min_ammo")) { DamageData[op1].min_ammo = op2; - CON_ConMessage("DamageData[%s].min_ammo = %d",damagename[op1],op2); + OSD_Printf("DamageData[%s].min_ammo = %d",damagename[op1],op2); } if (!strcmp(field,"show")) { @@ -1227,17 +1195,17 @@ void CON_DamageData(void) for (i=op2; i<=op2+10; i+=2) { if (i<47) - CON_ConMessage("[%d] = %s [%d] = %s",i,damagename[i],i+1,damagename[i+1]); + OSD_Printf("[%d] = %s [%d] = %s",i,damagename[i],i+1,damagename[i+1]); } } else { - CON_ConMessage(" "); - CON_ConMessage("Item = %s:",damagename[op1]); - CON_ConMessage("damage_lo = %d, damag_hi = %d",DamageData[op1].damage_lo,DamageData[op1].damage_hi); - CON_ConMessage("radius = %u",DamageData[op1].radius); - CON_ConMessage("min_ammo = %d, max_ammo = %d",DamageData[op1].min_ammo,DamageData[op1].max_ammo); - CON_ConMessage(" "); + OSD_Printf(" "); + OSD_Printf("Item = %s:",damagename[op1]); + OSD_Printf("damage_lo = %d, damag_hi = %d",DamageData[op1].damage_lo,DamageData[op1].damage_hi); + OSD_Printf("radius = %u",DamageData[op1].radius); + OSD_Printf("min_ammo = %d, max_ammo = %d",DamageData[op1].min_ammo,DamageData[op1].max_ammo); + OSD_Printf(" "); } } } @@ -1279,13 +1247,13 @@ void CON_Tweak(void) { extern short ADJUST; ADJUST = op1; - CON_ConMessage("Zvelocity ADJUST set to %d.",op1); + OSD_Printf("Zvelocity ADJUST set to %d.",op1); } else if (!strcmp(command,"adjustv")) { extern int ADJUSTV; ADJUSTV = op1; - CON_ConMessage("Zvelocity ADJUSTV set to %d.",op1); + OSD_Printf("Zvelocity ADJUSTV set to %d.",op1); } } @@ -1309,20 +1277,20 @@ void CON_CheckHeap(void) switch( _heapchk() ) { case _HEAPOK: - CON_ConMessage( "OK - heap is good\n" ); + OSD_Printf( "OK - heap is good\n" ); break; case _HEAPEMPTY: - CON_ConMessage( "OK - heap is empty\n" ); + OSD_Printf( "OK - heap is empty\n" ); break; case _HEAPBADBEGIN: - CON_ConMessage( "ERROR - heap is damaged\n" ); + OSD_Printf( "ERROR - heap is damaged\n" ); break; case _HEAPBADNODE: - CON_ConMessage( "ERROR - bad node in heap\n" ); + OSD_Printf( "ERROR - bad node in heap\n" ); break; } */ - CON_ConMessage("JonoF: Not now"); + OSD_Printf("JonoF: Not now"); } /* @@ -1364,7 +1332,7 @@ void heap_dump( void ) void CON_DumpHeap(void) { //heap_dump(); // Dump it. - CON_ConMessage("JonoF: Not now"); + OSD_Printf("JonoF: Not now"); } void CON_ShowMirror(void) @@ -1382,21 +1350,21 @@ void CON_ShowMirror(void) if (op1 < 0 || op1 > 9) { - CON_ConMessage("Mirror number is out of range!"); + OSD_Printf("Mirror number is out of range!"); return; } - CON_ConMessage("camera is the ST1 sprite used as the view spot"); - CON_ConMessage("camspite is the SpriteNum of the drawtotile tile in editart"); - CON_ConMessage("camspic is the tile number of the drawtotile in editart"); - CON_ConMessage("iscamera is whether or not this mirror is a camera type"); - CON_ConMessage(" "); - CON_ConMessage("mirror[%d].mirrorwall = %d",op1,mirror[op1].mirrorwall); - CON_ConMessage("mirror[%d].mirrorsector = %d",op1,mirror[op1].mirrorsector); - CON_ConMessage("mirror[%d].camera = %d",op1,mirror[op1].camera); - CON_ConMessage("mirror[%d].camsprite = %d",op1,mirror[op1].camsprite); - CON_ConMessage("mirror[%d].campic = %d",op1,mirror[op1].campic); - CON_ConMessage("mirror[%d].iscamera = %d",op1,mirror[op1].ismagic); + OSD_Printf("camera is the ST1 sprite used as the view spot"); + OSD_Printf("camspite is the SpriteNum of the drawtotile tile in editart"); + OSD_Printf("camspic is the tile number of the drawtotile in editart"); + OSD_Printf("iscamera is whether or not this mirror is a camera type"); + OSD_Printf(" "); + OSD_Printf("mirror[%d].mirrorwall = %d",op1,mirror[op1].mirrorwall); + OSD_Printf("mirror[%d].mirrorsector = %d",op1,mirror[op1].mirrorsector); + OSD_Printf("mirror[%d].camera = %d",op1,mirror[op1].camera); + OSD_Printf("mirror[%d].camsprite = %d",op1,mirror[op1].camsprite); + OSD_Printf("mirror[%d].campic = %d",op1,mirror[op1].campic); + OSD_Printf("mirror[%d].iscamera = %d",op1,mirror[op1].ismagic); } void CON_DumpSoundList(void) @@ -1404,7 +1372,7 @@ void CON_DumpSoundList(void) extern void DumpSounds(void); DumpSounds(); - CON_Message("Sounds dumped to dbg.foo"); + OSD_Printf("Sounds dumped to dbg.foo"); } diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index d43e47155..b32dd5cae 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -694,7 +694,7 @@ analyzesprites(int viewx, int viewy, int viewz, SWBOOL mirror) tu = User[SpriteNum]; //if(tsp->statnum == STAT_GENERIC_QUEUE) - // CON_ConMessage("tsp->pal = %d",tsp->pal); + // OSD_Printf("tsp->pal = %d",tsp->pal); #if 0 // Brighten up the sprite if set somewhere else to do so diff --git a/source/sw/src/game.h b/source/sw/src/game.h index fd2de23cb..9603d1b36 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -78,13 +78,14 @@ void dsprintf(char *, char *, ...); void PokeStringMono(uint8_t Attr, uint8_t* String); -#if 1 // !JIM! Frank, I redirect this for me you'll want to set this back for you +#if 1 +// !JIM! Frank, I redirect this for me you'll want to set this back for you extern int DispMono; #define MONO_PRINT(str) if (DispMono) PokeStringMono(/*MDA_NORMAL*/ 0, str) #else void adduserquote(const char *daquote); extern int DispMono; -#define MONO_PRINT(str) if (DispMono) CON_ConMessage(str); // Put it in my userquote stuff! +#define MONO_PRINT(str) if (DispMono) OSD_Printf(str); // Put it in my userquote stuff! //#define MONO_PRINT(str) if (DispMono) printf(str); #endif @@ -857,8 +858,6 @@ void addconquote(const char *daquote); // Console // /////////////////////////////////////////////////////////////////////////////////////////// -void CON_Message(const char *message, ...) PRINTF_FORMAT(1, 2); -void CON_ConMessage(const char *message, ...) PRINTF_FORMAT(1, 2); void CON_StoreArg(const char *userarg); SWBOOL CON_CheckParm(const char *userarg); void CON_CommandHistory(signed char dir); diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index 075413c55..ee42e2c46 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -423,7 +423,7 @@ void SetFadeAmt(PLAYERp pp, short damage, unsigned char startcolor) short fadedamage = 0; RGB_color color; - //CON_ConMessage("SetAmt: fadeamt = %d, startcolor = %d, pp = %d",pp->FadeAmt,startcolor,pp->StartColor); + //OSD_Printf("SetAmt: fadeamt = %d, startcolor = %d, pp = %d",pp->FadeAmt,startcolor,pp->StartColor); if (abs(pp->FadeAmt) > 0 && startcolor == pp->StartColor) return; diff --git a/source/sw/src/miscactr.cpp b/source/sw/src/miscactr.cpp index ab0d0369b..f6cb36992 100644 --- a/source/sw/src/miscactr.cpp +++ b/source/sw/src/miscactr.cpp @@ -838,7 +838,7 @@ int PachinkoCheckWin(short SpriteNum) u->WaitTics = 0; // Can operate it again now - //CON_ConMessage("bool1 = %d",TEST_BOOL1(sp)); + //OSD_Printf("bool1 = %d",TEST_BOOL1(sp)); // You already won, no more from this machine! if (TEST_BOOL1(sp)) return 0; diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp index 9bb92f3d1..cf3c04d5e 100644 --- a/source/sw/src/sounds.cpp +++ b/source/sw/src/sounds.cpp @@ -746,7 +746,7 @@ SWBOOL CacheSound(int num, int type) if (!OpenSound(vp, handle, &length)) { sprintf(ds,"Could not open sound %s, num %d, priority %d\n",vp->name,num,vp->priority); - CON_ConMessage("%s", ds); + OSD_Printf("%s", ds); return FALSE; } diff --git a/source/sw/src/sprite.cpp b/source/sw/src/sprite.cpp index ae1fda491..dd1562a2b 100644 --- a/source/sw/src/sprite.cpp +++ b/source/sw/src/sprite.cpp @@ -5798,7 +5798,7 @@ KeyMain: sprintf(ds,"Fortune Say: %s\n",ReadFortune[STD_RANDOM_RANGE(10)]); else sprintf(ds,"Fortune Say: %s\n",ReadFortune[STD_RANDOM_RANGE(MAX_FORTUNES)]); - CON_Message("%s", ds); + OSD_Printf("%s", ds); } SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup diff --git a/source/sw/src/text.cpp b/source/sw/src/text.cpp index a63b97b58..2eec36424 100644 --- a/source/sw/src/text.cpp +++ b/source/sw/src/text.cpp @@ -447,7 +447,7 @@ void PutStringInfo(PLAYERp pp, const char *string) if (!hud_messages) return; - CON_ConMessage("%s", string); // Put it in the console too + OSD_Printf("%s", string); // Put it in the console too PutStringInfoLine(pp, string); } diff --git a/wadsrc/static/demolition/commonbinds.txt b/wadsrc/static/demolition/commonbinds.txt index f96323051..23cdfddc2 100644 --- a/wadsrc/static/demolition/commonbinds.txt +++ b/wadsrc/static/demolition/commonbinds.txt @@ -4,13 +4,13 @@ F1 "openhelpmenu" F2 "opensavemenu" F3 "openloadmenu" F4 "openmenu SoundOptions" -F5 "openmeun OptionMenu" //this key performs some fuckery with the music in Duke Nukem,so the default here is Blood's. -F6 "+Quick_Save" +F5 "openmenu OptionMenu" //this key performs some fuckery with the music in Duke Nukem,so the default here is Blood's. +F6 "quicksave" F7 "+Third_Person_View" -//F8 "toggle hud_messages" // this one needs a means to print the status to the quote display. -F9 "+Quick_Load" -F10 "openmenu QuitIngame" -F11 "openmenu ColorCorrection" +F8 "togglemessages" +F9 "quickload" +F10 "menu_endgame" +F11 "bumpgamma" F12 "screenshot" 1 "+Weapon_1" 2 "+Weapon_2" @@ -63,17 +63,3 @@ K "+See_Coop_View" Mouse1 "+Fire" MWheelUp "+Previous_Weapon" MWheelDown "+Next_Weapon" - -Pad_A "+Fire" -Pad_B "+Toggle_Crouch" // fixme: not yet supported by all games -Pad_Back "+Map" -LTrigger "+Run" -RTrigger "+Quick_Kick" -LShoulder "+Crouch" -RShoulder "+Jump" -DPadUp "+Previous_Weapon" -DPadDown "+Next_Weapon" -Pad_X "+Open" -Pad_Y "+Inventory" -DPadLeft "+Inventory_Left" -DPadRight "+Inventory_Right" diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index adbfad988..38eed52f1 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -865,8 +865,8 @@ OptionMenu "OtherControlsMenu"// protected Control "$CNTRLMNU_PAUSE" , "pause" StaticText "" - Control "$CNTRLMNU_DISPLAY_INC" , "sizeup" - Control "$CNTRLMNU_DISPLAY_DEC" , "sizedown" + Control "$CNTRLMNU_DISPLAY_INC" , "+enlarge_Screen" + Control "$CNTRLMNU_DISPLAY_DEC" , "+shrink_screen" Control "$CNTRLMNU_TOGGLE_MESSAGES" , "togglemessages" Control "$CNTRLMNU_ADJUST_GAMMA" , "bumpgamma" From 6245a0e2e262a4c79781b8545c23b81be6c00624 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 Dec 2019 01:21:27 +0100 Subject: [PATCH 092/203] - added mouse and controller menus The controller menu obviously does not work yet, it needs quite a bit of backing code fron GZDoom first. --- source/blood/src/controls.cpp | 10 --- source/common/console/c_buttons.cpp | 13 ++- source/common/console/c_buttons.h | 1 - source/common/console/c_con.cpp | 5 +- source/common/gamecvars.cpp | 18 +++- source/duke3d/src/game.cpp | 7 -- source/rr/src/game.cpp | 7 -- wadsrc/static/demolition/menudef.txt | 125 +++++++++++++++++++++++++-- 8 files changed, 145 insertions(+), 41 deletions(-) diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index e0b4d9fd5..6a21564c9 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -182,16 +182,6 @@ void ctrlGetInput(void) gInputMode = kInputMessage; } - if (buttonMap.ButtonDown(gamefunc_AutoRun)) - { - buttonMap.ClearButton(gamefunc_AutoRun); - gAutoRun = !gAutoRun; - if (gAutoRun) - viewSetMessage("Auto run ON"); - else - viewSetMessage("Auto run OFF"); - } - if (buttonMap.ButtonDown(gamefunc_Map_Toggle)) { buttonMap.ClearButton(gamefunc_Map_Toggle); diff --git a/source/common/console/c_buttons.cpp b/source/common/console/c_buttons.cpp index bbfdab768..0e9939561 100644 --- a/source/common/console/c_buttons.cpp +++ b/source/common/console/c_buttons.cpp @@ -61,12 +61,12 @@ static const ButtonDesc gamefuncs[] = { { gamefunc_Crouch, "Crouch"}, { gamefunc_Look_Up, "Look_Up"}, { gamefunc_Look_Down, "Look_Down"}, - { gamefunc_Look_Left, "Look_Left"}, - { gamefunc_Look_Right, "Look_Right"}, + { gamefunc_Look_Left, "Look_Left"}, + { gamefunc_Look_Right, "Look_Right"}, { gamefunc_Strafe_Left, "Strafe_Left"}, { gamefunc_Strafe_Right, "Strafe_Right"}, - { gamefunc_Aim_Up, "Aim_Up"}, - { gamefunc_Aim_Down, "Aim_Down"}, + { gamefunc_Aim_Up, "Aim_Up"}, + { gamefunc_Aim_Down, "Aim_Down"}, { gamefunc_Weapon_1, "Weapon_1"}, { gamefunc_Weapon_2, "Weapon_2"}, { gamefunc_Weapon_3, "Weapon_3"}, @@ -87,8 +87,8 @@ static const ButtonDesc gamefuncs[] = { { gamefunc_TurnAround, "Turn_Around"}, { gamefunc_SendMessage, "Send_Message"}, { gamefunc_Map, "Map"}, - { gamefunc_Shrink_Screen, "Shrink_Screen"}, - { gamefunc_Enlarge_Screen, "Enlarge_Screen"}, + { gamefunc_Shrink_Screen, "Shrink_Screen"}, + { gamefunc_Enlarge_Screen, "Enlarge_Screen"}, { gamefunc_Center_View, "Center_View"}, { gamefunc_Holster_Weapon, "Holster_Weapon"}, { gamefunc_Show_Opponents_Weapon, "Show_Opponents_Weapon"}, @@ -103,7 +103,6 @@ static const ButtonDesc gamefuncs[] = { { gamefunc_Show_DukeMatch_Scores, "Show_DukeMatch_Scores"}, { gamefunc_Dpad_Select, "Dpad_Select"}, { gamefunc_Dpad_Aiming, "Dpad_Aiming"}, - { gamefunc_AutoRun, "AutoRun"}, { gamefunc_Last_Weapon, "Last_Used_Weapon"}, { gamefunc_Alt_Weapon, "Alt_Weapon"}, { gamefunc_Third_Person_View, "Third_Person_View"}, diff --git a/source/common/console/c_buttons.h b/source/common/console/c_buttons.h index 7b14bca89..4f53282f9 100644 --- a/source/common/console/c_buttons.h +++ b/source/common/console/c_buttons.h @@ -70,7 +70,6 @@ enum GameFunction_t gamefunc_Show_DukeMatch_Scores, gamefunc_Dpad_Select, gamefunc_Dpad_Aiming, - gamefunc_AutoRun, gamefunc_Last_Weapon, gamefunc_Alt_Weapon, gamefunc_Third_Person_View, diff --git a/source/common/console/c_con.cpp b/source/common/console/c_con.cpp index d8ff9d529..df40bde31 100644 --- a/source/common/console/c_con.cpp +++ b/source/common/console/c_con.cpp @@ -31,7 +31,7 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **--------------------------------------------------------------------------- ** -*/ +*/ #include #include "basics.h" @@ -113,7 +113,7 @@ static GameFuncDesc con_gamefuncs[] = { {"+Show_DukeMatch_Scores", "Show_Scoreboard"}, {"+Dpad_Select", "Dpad_Select"}, {"+Dpad_Aiming", "Dpad_Aiming"}, -{"+AutoRun", "AutoRun"}, +{"toggle cl_autorun", "AutoRun"}, {"+Last_Used_Weapon", "Last_Used_Weapon"}, {"QuickSave", "Quick_Save"}, {"QuickLoad", "Quick_Load"}, @@ -274,4 +274,3 @@ const char *C_CON_GetButtonFunc(int num) } return ""; } - diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index 5ddba222f..ed460409d 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -60,7 +60,23 @@ CVARD(Bool, cl_crosshair, true, CVAR_ARCHIVE, "enable/disable crosshair"); CVARD(Bool, cl_automsg, false, CVAR_ARCHIVE, "enable/disable automatically sending messages to all players") // Not implemented for Blood -CVARD(Bool, cl_autorun, true, CVAR_ARCHIVE, "enable/disable autorun") +CUSTOM_CVARD(Bool, cl_autorun, true, CVAR_ARCHIVE, "enable/disable autorun") +{ +#if 0 // todo: print a message + + if (gAutoRun) + viewSetMessage("Auto run ON"); + else + viewSetMessage("Auto run OFF"); + + + RUN MODE OFF + RUN MODE ON + cl_autorun= 1-cl_autorun; + P_DoQuote(QUOTE_RUN_MODE_OFF + cl_autorun, &myplayer); + } +#endif +} CVARD(Bool, cl_runmode, true, CVAR_ARCHIVE, "enable/disable modernized run key operation") CVARD(Bool, cl_autosave, true, CVAR_ARCHIVE, "enable/disable autosaves") // Not implemented for Blood (but looks like the other games never check it either.) CVARD(Bool, cl_autosavedeletion, true, CVAR_ARCHIVE, "enable/disable automatic deletion of autosaves") // Not implemented for Blood diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index dca063bd6..f5737af6e 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -4725,13 +4725,6 @@ void G_HandleLocalKeys(void) G_UpdateScreenArea(); } - if (buttonMap.ButtonDown(gamefunc_AutoRun)) - { - buttonMap.ClearButton(gamefunc_AutoRun); - cl_autorun= 1-cl_autorun; - P_DoQuote(QUOTE_RUN_MODE_OFF + cl_autorun, &myplayer); - } - if (buttonMap.ButtonDown(gamefunc_Map)) { buttonMap.ClearButton(gamefunc_Map); diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index c414339cb..949f66748 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -6271,13 +6271,6 @@ void G_HandleLocalKeys(void) G_UpdateScreenArea(); } - if (buttonMap.ButtonDown(gamefunc_AutoRun)) - { - buttonMap.ClearButton(gamefunc_AutoRun); - cl_autorun = !cl_autorun; - P_DoQuote(QUOTE_RUN_MODE_OFF+cl_autorun,g_player[myconnectindex].ps); - } - if (buttonMap.ButtonDown(gamefunc_Map)) { buttonMap.ClearButton(gamefunc_Map); diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 38eed52f1..5a39cc2a3 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -702,8 +702,15 @@ OptionMenu "ActionControlsMenu"// protected StaticText "" Control "$CNTRLMNU_MOUSELOOK" , "+mouse_aiming" + Control "$CNTRLMNU_AIMUP" , "+aim_up" + Control "$CNTRLMNU_AIMDOWN" , "+aim_down" Control "$CNTRLMNU_LOOKUP" , "+look_up" Control "$CNTRLMNU_LOOKDOWN" , "+look_down" + ifgame(Duke, Nam, WW2GI, Fury, Redneck, RedneckRides) + { + Control "$CNTRLMNU_LOOKLEFT" , "+look_left" + Control "$CNTRLMNU_LOOKRIGHT" , "+look_right" + } Control "$CNTRLMNU_CENTERVIEW" , "+center_view" StaticText "" @@ -871,11 +878,11 @@ OptionMenu "OtherControlsMenu"// protected Control "$CNTRLMNU_ADJUST_GAMMA" , "bumpgamma" StaticText "" - Control "$CNTRLMNU_OPEN_HELP" , "menu_help" - Control "$CNTRLMNU_OPEN_SAVE" , "menu_save" - Control "$CNTRLMNU_OPEN_LOAD" , "menu_load" - Control "$CNTRLMNU_OPEN_OPTIONS" , "menu_options" - Control "$CNTRLMNU_OPEN_DISPLAY" , "menu_display" + Control "$CNTRLMNU_OPEN_HELP" , "openhelpmenu" + Control "$CNTRLMNU_OPEN_SAVE" , "opensavemenu" + Control "$CNTRLMNU_OPEN_LOAD" , "openloadmenu" + Control "$CNTRLMNU_OPEN_OPTIONS" , "openmenu optionsmenu" + Control "$CNTRLMNU_OPEN_DISPLAY" , "openmenu displayoptions" Control "$CNTRLMNU_EXIT_TO_MAIN" , "menu_endgame" Control "$CNTRLMNU_MENU_QUIT" , "menu_quit" @@ -884,3 +891,111 @@ OptionMenu "OtherControlsMenu"// protected Control "$CNTRLMNU_QUICKLOAD" , "quickload" } +//------------------------------------------------------------------------------------------- +// +// Mouse Menu +// +//------------------------------------------------------------------------------------------- + +OptionValue "Corners" +{ + -1, "$OPTVAL_OFF" + 0, "$OPTVAL_UPPERLEFT" + 1, "$OPTVAL_UPPERRIGHT" + 2, "$OPTVAL_LOWERLEFT" + 3, "$OPTVAL_LOWERRIGHT" +} + +OptionValue "MenuMouse" +{ + 0, "$TXT_NO" + 1, "$TXT_YES" + 2, "$OPTVAL_TOUCHSCREENLIKE" +} + +OptionString "Cursors" +{ + "None", "$OPTVAL_DEFAULT" + "cursor", "$OPTSTR_SIMPLEARROW" + "-", "$OPTSTR_SYSTEMCURSOR" +} + +OptionMenu "MouseOptions" protected +{ + Title "$MOUSEMNU_TITLE" + Option "$MOUSEMNU_ENABLEMOUSE", "in_mouse", "YesNo" + Option "$MOUSEMNU_MOUSEINMENU", "m_use_mouse", "MenuMouse", "use_mouse" + Option "$MOUSEMNU_SHOWBACKBUTTON", "m_show_backbutton", "Corners", "use_mouse" + // todo Option "$MOUSEMNU_CURSOR", "vid_cursor", "Cursors" + StaticText "" + Slider "$MOUSEMNU_SENSITIVITY", "mouse_sensitivity", 0.5, 2.5, 0.1 + Option "$MOUSEMNU_NOPRESCALE", "m_noprescale", "NoYes" + Option "$MOUSEMNU_SMOOTHMOUSE", "m_filter", "YesNo" + StaticText "" + Slider "$MOUSEMNU_TURNSPEED", "m_yaw", 0, 2.5, 0.1 + Slider "$MOUSEMNU_MOUSELOOKSPEED", "m_pitch", 0, 2.5, 0.1 + Slider "$MOUSEMNU_FORWBACKSPEED", "m_forward", 0, 2.5, 0.1 + Slider "$MOUSEMNU_STRAFESPEED", "m_side", 0, 2.5, 0.1 + StaticText "" + Option "$MOUSEMNU_ALWAYSMOUSELOOK", "in_mousemode", "OnOff" + Option "$MOUSEMNU_INVERTMOUSE", "in_mouseflip", "OnOff" + Option "$MOUSEMNU_LOOKSPRING", "in_aimmode", "OnOff" // Functionm exists but is very broken. Definitely needs fixing. + // Do we need this? Option "$MOUSEMNU_LOOKSTRAFE", "lookstrafe", "OnOff" +} + +//------------------------------------------------------------------------------------------- +// +// Joystick Menu +// +//------------------------------------------------------------------------------------------- + +OptionMenu "JoystickOptionsDefaults" protected +{ + Title "$JOYMNU_OPTIONS" + Option "$JOYMNU_ENABLE", "use_joystick", "YesNo" + Option "$JOYMNU_NOMENU", "m_blockcontrollers", "YesNo" + /*IfOption(Windows) + { + Option "$JOYMNU_DINPUT", "joy_dinput", "YesNo" + Option "$JOYMNU_XINPUT", "joy_xinput", "YesNo" + Option "$JOYMNU_PS2", "joy_ps2raw", "YesNo" + }*/ + StaticText "" + StaticTextSwitchable "$JOYMNU_NOCON", "$JOYMNU_CONFIG", "ConfigureMessage" + StaticTextSwitchable " ", "$JOYMNU_DISABLED1", "ConnectMessage1" + StaticTextSwitchable " ", "$JOYMNU_DISABLED2", "ConnectMessage2" + + // The rest will be filled in by joystick code if devices get connected or disconnected +} + +OptionMenu "JoystickOptions" protected +{ + Title "$JOYMNU_OPTIONS" +} + +OptionValue "JoyAxisMapNames" +{ + -1, "$OPTVAL_NONE" + 0, "$OPTVAL_TURNING" + 1, "$OPTVAL_LOOKINGUPDOWN" + 2, "$OPTVAL_MOVINGFORWARD" + 3, "$OPTVAL_STRAFING" + 4, "$OPTVAL_MOVINGUPDOWN" +} + +OptionValue "Inversion" +{ + 0, "$OPTVAL_NOTINVERTED" + 1, "$OPTVAL_INVERTED" +} + +OptionMenu "JoystickConfigMenu" protected +{ + Title "$JOYMNU_TITLE" + Class "JoystickConfigMenu" + // Will be filled in by joystick code. +} + + + + From 820bd2545c90a65aa031273e7d1bbc72396a5fe2 Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Tue, 3 Dec 2019 09:44:42 +0000 Subject: [PATCH 093/203] SW: Get widescreen aspect working git-svn-id: https://svn.eduke32.com/eduke32@8346 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/sw/src/draw.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index 84934cff7..8a245cea3 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -2198,6 +2198,8 @@ drawscreen(PLAYERp pp) static short lv_sectnum = -1; static int lv_x, lv_y, lv_z; + int const viewingRange = viewingrange; + if (HelpInputMode) { renderFlushPerms(); @@ -2363,6 +2365,12 @@ drawscreen(PLAYERp pp) thoriz = min(thoriz, PLAYER_HORIZ_MAX); } + if (r_usenewaspect) + { + newaspect_enable = 1; + videoSetCorrectedAspect(); + } + if (FAF_DebugView) videoClearViewableArea(255L); @@ -2387,6 +2395,12 @@ drawscreen(PLAYERp pp) post_analyzesprites(); renderDrawMasks(); + if (r_usenewaspect) + { + newaspect_enable = 0; + renderSetAspect(viewingRange, tabledivide32_noinline(65536 * ydim * 8, xdim * 5)); + } + UpdatePanel(); #define SLIME 2305 From f19848a1b39308a13c9f839ffd189a768e9fcdc3 Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Tue, 3 Dec 2019 09:44:46 +0000 Subject: [PATCH 094/203] SW: Address Sanitization commenceth git-svn-id: https://svn.eduke32.com/eduke32@8347 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/sw/src/game.h | 4 ++-- source/sw/src/player.cpp | 6 +++--- source/sw/src/scrip2.cpp | 3 ++- source/sw/src/weapon.cpp | 43 +++++++++++++++++++++++----------------- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/source/sw/src/game.h b/source/sw/src/game.h index da5d2ad94..ab94a1f7d 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -378,8 +378,8 @@ extern char MessageOutputString[256]; #define TEST_SYNC_KEY(player, sync_num) TEST((player)->input.bits, (1 << (sync_num))) #define RESET_SYNC_KEY(player, sync_num) RESET((player)->input.bits, (1 << (sync_num))) -#define TRAVERSE_SPRITE_SECT(l, o, n) for ((o) = (l); (n) = nextspritesect[o], (o) != -1; (o) = (n)) -#define TRAVERSE_SPRITE_STAT(l, o, n) for ((o) = (l); (n) = nextspritestat[o], (o) != -1; (o) = (n)) +#define TRAVERSE_SPRITE_SECT(l, o, n) for ((o) = (l); (n) = (o) == -1 ? -1 : nextspritesect[o], (o) != -1; (o) = (n)) +#define TRAVERSE_SPRITE_STAT(l, o, n) for ((o) = (l); (n) = (o) == -1 ? -1 : nextspritestat[o], (o) != -1; (o) = (n)) #define TRAVERSE_CONNECT(i) for (i = connecthead; i != -1; i = connectpoint2[i]) diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index 79a4f332a..f6d2a1015 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -3641,7 +3641,7 @@ void StackedWaterSplash(PLAYERp pp) updatesectorz(pp->posx, pp->posy, SPRITEp_BOS(pp->SpriteP), §num); - if (SectorIsUnderwaterArea(sectnum)) + if (sectnum >= 0 && SectorIsUnderwaterArea(sectnum)) { PlaySound(DIGI_SPLASH1, &pp->posx, &pp->posy, &pp->posz, v3df_dontpan); } @@ -4094,7 +4094,7 @@ DoPlayerWadeSuperJump(PLAYERp pp) { hitinfo.sect = wall[hitinfo.wall].nextsector; - if (labs(sector[hitinfo.sect].floorz - pp->posz) < Z(50)) + if (hitinfo.sect >= 0 && labs(sector[hitinfo.sect].floorz - pp->posz) < Z(50)) { if (Distance(pp->posx, pp->posy, hitinfo.pos.x, hitinfo.pos.y) < ((((int)pp->SpriteP->clipdist)<<2) + 256)) return TRUE; @@ -4694,7 +4694,7 @@ PlayerCanDiveNoWarp(PLAYERp pp) updatesectorz(pp->posx, pp->posy, SPRITEp_BOS(pp->SpriteP), §num); - if (SectorIsUnderwaterArea(sectnum)) + if (sectnum >= 0 && SectorIsUnderwaterArea(sectnum)) { pp->cursectnum = sectnum; pp->posz = sector[sectnum].ceilingz; diff --git a/source/sw/src/scrip2.cpp b/source/sw/src/scrip2.cpp index aa770c3c2..10a95f557 100644 --- a/source/sw/src/scrip2.cpp +++ b/source/sw/src/scrip2.cpp @@ -89,7 +89,7 @@ SWBOOL LoadScriptFile(const char *filename) size = fp.GetLength(); - scriptbuffer = (char *)AllocMem(size); + scriptbuffer = (char *)AllocMem(size+1); ASSERT(scriptbuffer != NULL); @@ -97,6 +97,7 @@ SWBOOL LoadScriptFile(const char *filename) ASSERT(readsize == size); + scriptbuffer[readsize] = '\0'; // Convert filebuffer to all upper case //Bstrupr(scriptbuffer); diff --git a/source/sw/src/weapon.cpp b/source/sw/src/weapon.cpp index fdfcd7b56..b84819017 100644 --- a/source/sw/src/weapon.cpp +++ b/source/sw/src/weapon.cpp @@ -2653,12 +2653,12 @@ STATE s_PaperShrapC[] = SWBOOL MissileHitMatch(short Weapon, short WeaponNum, short hit_sprite) { SPRITEp hsp = &sprite[hit_sprite]; - SPRITEp wp = &sprite[Weapon]; - USERp wu = User[Weapon]; if (WeaponNum <= -1) { ASSERT(Weapon >= 0); + SPRITEp wp = &sprite[Weapon]; + USERp wu = User[Weapon]; WeaponNum = wu->WeaponNum; // can be hit by SO only @@ -5760,8 +5760,6 @@ PlayerCheckDeath(PLAYERp pp, short Weapon) { SPRITEp sp = pp->SpriteP; USERp u = User[pp->PlayerSprite]; - SPRITEp wp = &sprite[Weapon]; - USERp wu = User[Weapon]; int SpawnZombie(PLAYERp pp, short); @@ -5786,6 +5784,9 @@ PlayerCheckDeath(PLAYERp pp, short Weapon) return TRUE; } + SPRITEp wp = &sprite[Weapon]; + USERp wu = User[Weapon]; + if (Weapon > -1 && (wu->ID == RIPPER_RUN_R0 || wu->ID == RIPPER2_RUN_R0)) pp->DeathType = PLAYER_DEATH_RIPPER; @@ -5828,14 +5829,14 @@ PlayerCheckDeath(PLAYERp pp, short Weapon) SWBOOL PlayerTakeDamage(PLAYERp pp, short Weapon) { + if (Weapon < 0) + return TRUE; + SPRITEp sp = pp->SpriteP; USERp u = User[pp->PlayerSprite]; SPRITEp wp = &sprite[Weapon]; USERp wu = User[Weapon]; - if (Weapon < 0) - return TRUE; - if (gNet.MultiGameType == MULTI_GAME_NONE) { // ZOMBIE special case for single play @@ -7607,9 +7608,11 @@ DoDamageTest(short Weapon) return 0; } -int -DoHitscanDamage(short Weapon, short hit_sprite) +static int DoHitscanDamage(short Weapon, uint16_t hit_sprite) { + if (hit_sprite >= MAXSPRITES) + return 0; + SPRITEp wp = &sprite[Weapon]; USERp wu = User[Weapon]; unsigned stat; @@ -10832,8 +10835,8 @@ SpawnFireballFlames(int16_t SpriteNum, int16_t enemy) { SPRITEp sp = &sprite[SpriteNum]; USERp u = User[SpriteNum]; - SPRITEp ep = &sprite[enemy]; - USERp eu = User[enemy]; + SPRITEp ep; + USERp eu; SPRITEp np; USERp nu; short New; @@ -10843,6 +10846,9 @@ SpawnFireballFlames(int16_t SpriteNum, int16_t enemy) if (enemy >= 0) { + ep = &sprite[enemy]; + eu = User[enemy]; + // test for already burned if (TEST(ep->extra, SPRX_BURNABLE) && ep->shade > 40) return -1; @@ -17843,17 +17849,18 @@ SWBOOL HitscanSpriteAdjust(short SpriteNum, short hit_wall) { SPRITEp sp = &sprite[SpriteNum]; - short w, nw, ang = sp->ang, wall_ang; + int16_t ang; int xvect,yvect; short sectnum; #if 1 - w = hit_wall; - nw = wall[w].point2; - wall_ang = NORM_ANGLE(getangle(wall[nw].x - wall[w].x, wall[nw].y - wall[w].y)); - if (hit_wall >= 0) + { + uint16_t const w = hit_wall; + uint16_t const nw = wall[hit_wall].point2; + int16_t const wall_ang = NORM_ANGLE(getangle(wall[nw].x - wall[w].x, wall[nw].y - wall[w].y)); ang = sp->ang = NORM_ANGLE(wall_ang + 512); + } else ang = sp->ang; #endif @@ -20638,13 +20645,13 @@ void QueueReset(void) SWBOOL TestDontStick(short SpriteNum, short hit_sect, short hit_wall, int hit_z) { - SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum]; WALLp wp; if (hit_wall < 0) { ASSERT(SpriteNum>=0); + SPRITEp sp = &sprite[SpriteNum]; + USERp u = User[SpriteNum]; hit_wall = NORM_WALL(u->ret); } From 823e47f3e8979a44326d5780d9d95bb3748ae614 Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Tue, 3 Dec 2019 09:44:51 +0000 Subject: [PATCH 095/203] SW: Fix assertions and OOB so that the player can noclip OOB git-svn-id: https://svn.eduke32.com/eduke32@8348 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/sw/src/draw.cpp | 28 ++++++++------- source/sw/src/jweapon.cpp | 6 ++++ source/sw/src/panel.cpp | 27 ++++++++------ source/sw/src/player.cpp | 41 ++++++++++++--------- source/sw/src/rooms.cpp | 18 +++++----- source/sw/src/sector.cpp | 18 ++++++---- source/sw/src/sprite.cpp | 2 +- source/sw/src/warp.cpp | 2 +- source/sw/src/weapon.cpp | 75 ++++++++++++++++++++++++++++++++++++--- 9 files changed, 157 insertions(+), 60 deletions(-) diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index 8a245cea3..b1301efa8 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -2186,7 +2186,6 @@ drawscreen(PLAYERp pp) int tx, ty, tz,thoriz,pp_siz; short tang,tsectnum; short i,j; - walltype *wal; int tiltlock; int bob_amt = 0; int quake_z, quake_x, quake_y; @@ -2285,11 +2284,13 @@ drawscreen(PLAYERp pp) if (tsectnum < 0) { +#if 0 // if we hit an invalid sector move to the last valid position for drawing tsectnum = lv_sectnum; tx = lv_x; ty = lv_y; tz = lv_z; +#endif } else { @@ -2301,7 +2302,7 @@ drawscreen(PLAYERp pp) } // with "last valid" code this should never happen - ASSERT(tsectnum >= 0 && tsectnum <= MAXSECTORS); + // ASSERT(tsectnum >= 0 && tsectnum <= MAXSECTORS); pp->six = tx; pp->siy = ty; @@ -2420,18 +2421,21 @@ drawscreen(PLAYERp pp) i = pp->cursectnum; - show2dsector[i>>3] |= (1<<(i&7)); - wal = &wall[sector[i].wallptr]; - for (j=sector[i].wallnum; j>0; j--,wal++) + if (i >= 0) { - i = wal->nextsector; - if (i < 0) continue; - if (wal->cstat&0x0071) continue; - uint16_t const nextwall = wal->nextwall; - if (nextwall < MAXWALLS && wall[nextwall].cstat&0x0071) continue; - if (sector[i].lotag == 32767) continue; - if (sector[i].ceilingz >= sector[i].floorz) continue; show2dsector[i>>3] |= (1<<(i&7)); + walltype *wal = &wall[sector[i].wallptr]; + for (j=sector[i].wallnum; j>0; j--,wal++) + { + i = wal->nextsector; + if (i < 0) continue; + if (wal->cstat&0x0071) continue; + uint16_t const nextwall = wal->nextwall; + if (nextwall < MAXWALLS && wall[nextwall].cstat&0x0071) continue; + if (sector[i].lotag == 32767) continue; + if (sector[i].ceilingz >= sector[i].floorz) continue; + show2dsector[i>>3] |= (1<<(i&7)); + } } if ((dimensionmode == 5 || dimensionmode == 6) && pp == Player+myconnectindex) diff --git a/source/sw/src/jweapon.cpp b/source/sw/src/jweapon.cpp index 58aa92bc9..823169808 100644 --- a/source/sw/src/jweapon.cpp +++ b/source/sw/src/jweapon.cpp @@ -1389,6 +1389,9 @@ PlayerInitChemBomb(PLAYERp pp) PlaySound(DIGI_THROW, &pp->posx, &pp->posy, &pp->posz, v3df_dontpan | v3df_doppler); + if (pp->cursectnum < 0) + return 0; + nx = pp->posx; ny = pp->posy; nz = pp->posz + pp->bob_z + Z(8); @@ -1834,6 +1837,9 @@ PlayerInitCaltrops(PLAYERp pp) PlaySound(DIGI_THROW, &pp->posx, &pp->posy, &pp->posz, v3df_dontpan | v3df_doppler); + if (pp->cursectnum < 0) + return 0; + nx = pp->posx; ny = pp->posy; nz = pp->posz + pp->bob_z + Z(8); diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index 21b0defb9..e4a1f743e 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -7347,7 +7347,6 @@ pDisplaySprites(PLAYERp pp) int smoothratio; unsigned i; - SECT_USERp sectu = SectUser[pp->cursectnum]; uint8_t pal = 0; short ang; int flags; @@ -7488,17 +7487,23 @@ pDisplaySprites(PLAYERp pp) // if its a weapon sprite and the view is set to the outside don't draw the sprite if (TEST(psp->flags, PANF_WEAPON_SPRITE)) { - pal = sector[pp->cursectnum].floorpal; - - if (sector[pp->cursectnum].floorpal != PALETTE_DEFAULT) + SECT_USERp sectu = nullptr; + int16_t floorshade = 0; + if (pp->cursectnum >= 0) { - SECT_USERp sectu = SectUser[pp->cursectnum]; - if (sectu && TEST(sectu->flags, SECTFU_DONT_COPY_PALETTE)) - pal = PALETTE_DEFAULT; - } + sectu = SectUser[pp->cursectnum]; + pal = sector[pp->cursectnum].floorpal; + floorshade = sector[pp->cursectnum].floorshade; - if (pal == PALETTE_FOG || pal == PALETTE_DIVE || pal == PALETTE_DIVE_LAVA) - pal = psp->pal; // Set it back + if (pal != PALETTE_DEFAULT) + { + if (sectu && TEST(sectu->flags, SECTFU_DONT_COPY_PALETTE)) + pal = PALETTE_DEFAULT; + } + + if (pal == PALETTE_FOG || pal == PALETTE_DIVE || pal == PALETTE_DIVE_LAVA) + pal = psp->pal; // Set it back + } /////////// @@ -7508,7 +7513,7 @@ pDisplaySprites(PLAYERp pp) } //shade = overlay_shade = DIV2(sector[pp->cursectnum].floorshade + sector[pp->cursectnum].ceilingshade); - shade = overlay_shade = sector[pp->cursectnum].floorshade - 10; + shade = overlay_shade = floorshade - 10; if (TEST(psp->PlayerP->Flags, PF_VIEW_FROM_OUTSIDE)) { diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index f6d2a1015..5c1753a4b 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -1794,13 +1794,14 @@ DoPlayerTurnTurret(PLAYERp pp) void SlipSlope(PLAYERp pp) { - short wallptr = sector[pp->cursectnum].wallptr; short ang; - SECT_USERp sectu = SectUser[pp->cursectnum]; + SECT_USERp sectu; - if (!sectu || !TEST(sectu->flags, SECTFU_SLIDE_SECTOR) || !TEST(sector[pp->cursectnum].floorstat, FLOOR_STAT_SLOPE)) + if (pp->cursectnum < 0 || !(sectu = SectUser[pp->cursectnum]) || !TEST(sectu->flags, SECTFU_SLIDE_SECTOR) || !TEST(sector[pp->cursectnum].floorstat, FLOOR_STAT_SLOPE)) return; + short wallptr = sector[pp->cursectnum].wallptr; + ang = getangle(wall[wall[wallptr].point2].x - wall[wallptr].x, wall[wall[wallptr].point2].y - wall[wallptr].y); ang = NORM_ANGLE(ang + 512); @@ -2537,6 +2538,9 @@ DoPlayerMenuKeys(PLAYERp pp) void PlayerSectorBound(PLAYERp pp, int amt) { + if (pp->cursectnum < 9) + return; + int cz,fz; // player should never go into a sector @@ -2680,7 +2684,7 @@ DoPlayerMove(PLAYERp pp) DoPlayerHorizon(pp); - if (TEST(sector[pp->cursectnum].extra, SECTFX_DYNAMIC_AREA)) + if (pp->cursectnum >= 0 && TEST(sector[pp->cursectnum].extra, SECTFX_DYNAMIC_AREA)) { if (TEST(pp->Flags, PF_FLYING|PF_JUMPING|PF_FALLING)) { @@ -2722,6 +2726,9 @@ DoPlayerSectorUpdatePreMove(PLAYERp pp) { short sectnum = pp->cursectnum; + if (sectnum < 0) + return; + if (TEST(sector[pp->cursectnum].extra, SECTFX_DYNAMIC_AREA)) { updatesectorz(pp->posx, pp->posy, pp->posz, §num); @@ -2749,13 +2756,12 @@ DoPlayerSectorUpdatePreMove(PLAYERp pp) void DoPlayerSectorUpdatePostMove(PLAYERp pp) { - short sectnum; + short sectnum = pp->cursectnum; int fz,cz; // need to do updatesectorz if in connect area - if (FAF_ConnectArea(pp->cursectnum)) + if (sectnum >= 0 && FAF_ConnectArea(sectnum)) { - sectnum = pp->cursectnum; updatesectorz(pp->posx, pp->posy, pp->posz, &pp->cursectnum); // can mess up if below @@ -2773,7 +2779,7 @@ DoPlayerSectorUpdatePostMove(PLAYERp pp) // try again updatesectorz(pp->posx, pp->posy, pp->posz, &pp->cursectnum); - ASSERT(pp->cursectnum >= 0); + // ASSERT(pp->cursectnum >= 0); } } else @@ -3662,7 +3668,7 @@ DoPlayerFall(PLAYERp pp) FLAG_KEY_RESET(pp, SK_JUMP); } - if (SectorIsUnderwaterArea(pp->cursectnum)) + if (pp->cursectnum >= 0 && SectorIsUnderwaterArea(pp->cursectnum)) { StackedWaterSplash(pp); DoPlayerBeginDiveNoWarp(pp); @@ -4245,7 +4251,7 @@ DoPlayerCrawl(PLAYERp pp) { USERp u = User[pp->PlayerSprite]; - if (SectorIsUnderwaterArea(pp->cursectnum)) + if (pp->cursectnum >= 0 && SectorIsUnderwaterArea(pp->cursectnum)) { // if stacked water - which it should be if (FAF_ConnectArea(pp->cursectnum)) @@ -4348,7 +4354,7 @@ DoPlayerCrawl(PLAYERp pp) return; } - if (TEST(sector[pp->cursectnum].extra, SECTFX_DYNAMIC_AREA)) + if (pp->cursectnum >= 0 && TEST(sector[pp->cursectnum].extra, SECTFX_DYNAMIC_AREA)) { pp->posz = pp->loz - PLAYER_CRAWL_HEIGHT; } @@ -4430,7 +4436,7 @@ DoPlayerFly(PLAYERp pp) { USERp u = User[pp->PlayerSprite]; - if (SectorIsUnderwaterArea(pp->cursectnum)) + if (pp->cursectnum >= 0 && SectorIsUnderwaterArea(pp->cursectnum)) { DoPlayerBeginDiveNoWarp(pp); return; @@ -5116,7 +5122,7 @@ void DoPlayerBeginDiveNoWarp(PLAYERp pp) if (Prediction) return; - if (!SectorIsUnderwaterArea(pp->cursectnum)) + if (pp->cursectnum < 0 || !SectorIsUnderwaterArea(pp->cursectnum)) return; if (pp->Bloody) pp->Bloody = FALSE; // Water washes away the blood @@ -5282,7 +5288,7 @@ DoPlayerDive(PLAYERp pp) SECT_USERp sectu = SectUser[pp->cursectnum]; // whenever your view is not in a water area - if (!SectorIsUnderwaterArea(pp->cursectnum)) + if (pp->cursectnum < 0 || !SectorIsUnderwaterArea(pp->cursectnum)) { DoPlayerStopDiveNoWarp(pp); DoPlayerBeginRun(pp); @@ -7356,7 +7362,7 @@ DoPlayerRun(PLAYERp pp) { USERp u = User[pp->PlayerSprite]; - if (SectorIsUnderwaterArea(pp->cursectnum)) + if (pp->cursectnum >= 0 && SectorIsUnderwaterArea(pp->cursectnum)) { DoPlayerBeginDiveNoWarp(pp); return; @@ -7428,7 +7434,7 @@ DoPlayerRun(PLAYERp pp) { if (TEST_SYNC_KEY(pp, SK_OPERATE)) { - if (FLAG_KEY_PRESSED(pp, SK_OPERATE)) + if (FLAG_KEY_PRESSED(pp, SK_OPERATE) && pp->cursectnum >= 0) { if (TEST(sector[pp->cursectnum].extra, SECTFX_OPERATIONAL)) { @@ -8405,6 +8411,9 @@ DoFootPrints(short SpriteNum) if (u->PlayerP) { + if (u->PlayerP->cursectnum < 0) + return 0; + if (FAF_ConnectArea(u->PlayerP->cursectnum)) return 0; diff --git a/source/sw/src/rooms.cpp b/source/sw/src/rooms.cpp index 92a258c6f..bf3befdfe 100644 --- a/source/sw/src/rooms.cpp +++ b/source/sw/src/rooms.cpp @@ -59,7 +59,7 @@ SWBOOL FAF_DebugView = 0; void COVERupdatesector(int32_t x, int32_t y, int16_t* newsector) { - ASSERT(*newsector>=0 && *newsector=0 && *newsector= 0 && secte >= 0); + // ASSERT(sects >= 0 && secte >= 0); // early out to regular routine - if (!FAF_Sector(sects) && !FAF_Sector(secte)) + if ((sects < 0 || !FAF_Sector(sects)) && (secte < 0 || !FAF_Sector(secte))) { return cansee(xs,ys,zs,sects,xe,ye,ze,secte); } @@ -356,7 +356,7 @@ GetZadjustment(short sectnum, short hitag) short i, nexti; SPRITEp sp; - if (!TEST(sector[sectnum].extra, SECTFX_Z_ADJUST)) + if (sectnum < 0 || !TEST(sector[sectnum].extra, SECTFX_Z_ADJUST)) return 0L; TRAVERSE_SPRITE_STAT(headspritestat[STAT_ST1], i, nexti) @@ -517,7 +517,7 @@ void FAFgetzrange(int32_t x, int32_t y, int32_t z, int16_t sectnum, // because the ceiling and floors get moved out of the way for drawing. // early out to regular routine - if (!FAF_ConnectArea(sectnum)) + if (sectnum < 0 || !FAF_ConnectArea(sectnum)) { getzrange_old(x, y, z, sectnum, hiz, ceilhit, loz, florhit, clipdist, clipmask); SectorZadjust(*ceilhit, hiz, *florhit, loz); @@ -545,7 +545,7 @@ void FAFgetzrange(int32_t x, int32_t y, int32_t z, int16_t sectnum, updatesectorz(x, y, newz, &uppersect); if (uppersect < 0) - _ErrMsg(ERR_STD_ARG, "Did not find a sector at %d, %d, %d", x, y, newz); + return; // _ErrMsg(ERR_STD_ARG, "Did not find a sector at %d, %d, %d", x, y, newz); getzrange_old(x, y, newz, uppersect, hiz, ceilhit, &foo1, &foo2, clipdist, clipmask); SectorZadjust(*ceilhit, hiz, -1, NULL); } @@ -568,7 +568,7 @@ void FAFgetzrange(int32_t x, int32_t y, int32_t z, int16_t sectnum, updatesectorz(x, y, newz, &lowersect); if (lowersect < 0) - _ErrMsg(ERR_STD_ARG, "Did not find a sector at %d, %d, %d", x, y, newz); + return; // _ErrMsg(ERR_STD_ARG, "Did not find a sector at %d, %d, %d", x, y, newz); getzrange_old(x, y, newz, lowersect, &foo1, &foo2, loz, florhit, clipdist, clipmask); SectorZadjust(-1, NULL, *florhit, loz); WaterAdjust(*florhit, loz); @@ -614,7 +614,7 @@ void FAFgetzrangepoint(int32_t x, int32_t y, int32_t z, int16_t sectnum, } updatesectorz(x, y, newz, &uppersect); if (uppersect < 0) - _ErrMsg(ERR_STD_ARG, "Did not find a sector at %d, %d, %d, sectnum %d", x, y, newz, sectnum); + return; // _ErrMsg(ERR_STD_ARG, "Did not find a sector at %d, %d, %d, sectnum %d", x, y, newz, sectnum); getzrangepoint(x, y, newz, uppersect, hiz, ceilhit, &foo1, &foo2); SectorZadjust(*ceilhit, hiz, -1, NULL); } @@ -630,7 +630,7 @@ void FAFgetzrangepoint(int32_t x, int32_t y, int32_t z, int16_t sectnum, } updatesectorz(x, y, newz, &lowersect); if (lowersect < 0) - _ErrMsg(ERR_STD_ARG, "Did not find a sector at %d, %d, %d, sectnum %d", x, y, newz, sectnum); + return; // _ErrMsg(ERR_STD_ARG, "Did not find a sector at %d, %d, %d, sectnum %d", x, y, newz, sectnum); getzrangepoint(x, y, newz, lowersect, &foo1, &foo2, loz, florhit); SectorZadjust(-1, NULL, *florhit, loz); WaterAdjust(*florhit, loz); diff --git a/source/sw/src/sector.cpp b/source/sw/src/sector.cpp index 93611bec3..24b1947d6 100644 --- a/source/sw/src/sector.cpp +++ b/source/sw/src/sector.cpp @@ -2087,11 +2087,14 @@ int DoTrapMatch(short match) void OperateTripTrigger(PLAYERp pp) { - SECTORp sectp = §or[pp->cursectnum]; - if (Prediction) return; + if (pp->cursectnum < 0) + return; + + SECTORp sectp = §or[pp->cursectnum]; + #if 0 // new method if (TEST(sectp->extra, SECTFX_TRIGGER)) @@ -2249,6 +2252,9 @@ OperateContinuousTrigger(PLAYERp pp) if (Prediction) return; + if (pp->cursectnum < 0) + return; + switch (LOW_TAG(pp->cursectnum)) { case TAG_TRIGGER_MISSILE_TRAP: @@ -2589,8 +2595,6 @@ int DoPlayerGrabStar(PLAYERp pp) void PlayerOperateEnv(PLAYERp pp) { - SECT_USERp sectu = SectUser[pp->cursectnum]; - SECTORp sectp = §or[pp->cursectnum]; SWBOOL found; if (Prediction) @@ -2730,8 +2734,10 @@ PlayerOperateEnv(PLAYERp pp) // // //////////////////////////// - if (sectu && sectu->damage) + SECT_USERp sectu; + if (pp->cursectnum >= 0 && (sectu = SectUser[pp->cursectnum]) && sectu->damage) { + SECTORp sectp = §or[pp->cursectnum]; if (TEST(sectu->flags, SECTFU_DAMAGE_ABOVE_SECTOR)) { PlayerTakeSectorDamage(pp); @@ -2761,7 +2767,7 @@ PlayerOperateEnv(PLAYERp pp) { OperateTripTrigger(pp); - if (TEST(sector[pp->cursectnum].extra, SECTFX_WARP_SECTOR)) + if (pp->cursectnum >= 0 && TEST(sector[pp->cursectnum].extra, SECTFX_WARP_SECTOR)) { if (!TEST(pp->Flags2, PF2_TELEPORTED)) { diff --git a/source/sw/src/sprite.cpp b/source/sw/src/sprite.cpp index ae1fda491..d3ea67e97 100644 --- a/source/sw/src/sprite.cpp +++ b/source/sw/src/sprite.cpp @@ -962,7 +962,7 @@ SpawnSprite(short stat, short id, STATEp state, short sectnum, int x, int y, int ASSERT(!Prediction); - PRODUCTION_ASSERT(sectnum >= 0 && sectnum < MAXSECTORS); + // PRODUCTION_ASSERT(sectnum >= 0 && sectnum < MAXSECTORS); SpriteNum = COVERinsertsprite(sectnum, stat); diff --git a/source/sw/src/warp.cpp b/source/sw/src/warp.cpp index 8410530ac..0a801baba 100644 --- a/source/sw/src/warp.cpp +++ b/source/sw/src/warp.cpp @@ -54,7 +54,7 @@ WarpPlaneSectorInfo(short sectnum, SPRITEp *sp_ceiling, SPRITEp *sp_floor) if (Prediction) return FALSE; - if (!TEST(sector[sectnum].extra, SECTFX_WARP_SECTOR)) + if (sectnum < 0 || !TEST(sector[sectnum].extra, SECTFX_WARP_SECTOR)) return FALSE; TRAVERSE_SPRITE_STAT(headspritestat[STAT_WARP], i, nexti) diff --git a/source/sw/src/weapon.cpp b/source/sw/src/weapon.cpp index b84819017..d5f64cc72 100644 --- a/source/sw/src/weapon.cpp +++ b/source/sw/src/weapon.cpp @@ -2777,7 +2777,7 @@ int DoLavaErupt(short SpriteNum) TRAVERSE_CONNECT(pnum) { pp = Player + pnum; - if (TEST(sector[pp->cursectnum].extra, SECTFX_TRIGGER)) + if (pp->cursectnum >= 0 && TEST(sector[pp->cursectnum].extra, SECTFX_TRIGGER)) { TRAVERSE_SPRITE_SECT(headspritesect[pp->cursectnum],i,nexti) { @@ -13027,6 +13027,9 @@ InitSpellRing(PLAYERp pp) if (!SW_SHAREWARE) PlaySound(DIGI_RFWIZ, &pp->posx, &pp->posy, &pp->posz, v3df_none); + if (pp->cursectnum < 0) + return; + for (missiles = 0, ang = ang_start; missiles < max_missiles; ang += ang_diff, missiles++) { SpriteNum = SpawnSprite(STAT_MISSILE_SKIP4, FIREBALL1, s_Ring, pp->cursectnum, pp->posx, pp->posy, pp->posz, ang, 0); @@ -13575,6 +13578,9 @@ InitSpellNapalm(PLAYERp pp) PlaySound(DIGI_NAPFIRE, &pp->posx, &pp->posy, &pp->posz, v3df_none); + if (pp->cursectnum < 0) + return; + for (i = 0; i < SIZ(mp); i++) { SpriteNum = SpawnSprite(STAT_MISSILE, FIREBALL1, s_Napalm, pp->cursectnum, @@ -13735,6 +13741,9 @@ InitSpellMirv(PLAYERp pp) PlaySound(DIGI_MIRVFIRE, &pp->posx, &pp->posy, &pp->posz, v3df_none); + if (pp->cursectnum < 0) + return 0; + SpriteNum = SpawnSprite(STAT_MISSILE, FIREBALL1, s_Mirv, pp->cursectnum, pp->posx, pp->posy, pp->posz + Z(12), pp->pang, MIRV_VELOCITY); @@ -14746,13 +14755,16 @@ InitStar(PLAYERp pp) PlayerUpdateAmmo(pp, u->WeaponNum, -3); + PlaySound(DIGI_STAR, &pp->posx, &pp->posy, &pp->posz, v3df_dontpan|v3df_doppler); + + if (pp->cursectnum < 0) + return 0; + nx = pp->posx; ny = pp->posy; nz = pp->posz + pp->bob_z + Z(8); - PlaySound(DIGI_STAR, &pp->posx, &pp->posy, &pp->posz, v3df_dontpan|v3df_doppler); - // Spawn a shot // Inserting and setting up variables @@ -14877,6 +14889,9 @@ InitHeartAttack(PLAYERp pp) PlayerUpdateAmmo(pp, WPN_HEART, -1); + if (pp->cursectnum < 0) + return; + SpriteNum = SpawnSprite(STAT_MISSILE_SKIP4, BLOOD_WORM, s_BloodWorm, pp->cursectnum, pp->posx, pp->posy, pp->posz + Z(12), pp->pang, BLOOD_WORM_VELOCITY*2); @@ -14950,6 +14965,9 @@ InitHeartAttack(PLAYERp pp) PlayerUpdateAmmo(pp, WPN_HEART, -1); + if (pp->cursectnum < 0) + return; + SpriteNum = SpawnSprite(STAT_MISSILE_SKIP4, BLOOD_WORM, s_BloodWorm, pp->cursectnum, pp->posx, pp->posy, pp->posz + Z(12), pp->pang, BLOOD_WORM_VELOCITY*2); @@ -15265,6 +15283,9 @@ InitLaser(PLAYERp pp) PlaySound(DIGI_RIOTFIRE, &pp->posx, &pp->posy, &pp->posz, v3df_dontpan|v3df_doppler); + if (pp->cursectnum < 0) + return 0; + nx = pp->posx; ny = pp->posy; @@ -15374,6 +15395,9 @@ InitRail(PLAYERp pp) // Make sprite shade brighter u->Vis = 128; + if (pp->cursectnum < 0) + return 0; + nx = pp->posx; ny = pp->posy; @@ -15555,17 +15579,30 @@ InitRocket(PLAYERp pp) DoPlayerBeginRecoil(pp, ROCKET_RECOIL_AMT); PlayerUpdateAmmo(pp, u->WeaponNum, -1); + if (pp->WpnRocketHeat) + { + switch (pp->WpnRocketType) + { + case 1: + pp->WpnRocketHeat--; + break; + } + } PlaySound(DIGI_RIOTFIRE, &pp->posx, &pp->posy, &pp->posz, v3df_dontpan|v3df_doppler); // Make sprite shade brighter u->Vis = 128; + if (pp->cursectnum < 0) + return 0; + nx = pp->posx; ny = pp->posy; // Spawn a shot // Inserting and setting up variables + //nz = pp->posz + pp->bob_z + Z(12); nz = pp->posz + pp->bob_z + Z(8); w = SpawnSprite(STAT_MISSILE, BOLT_THINMAN_R0, &s_Rocket[0][0], pp->cursectnum, @@ -15601,7 +15638,6 @@ InitRocket(PLAYERp pp) switch (pp->WpnRocketType) { case 1: - pp->WpnRocketHeat--; SET(wu->Flags, SPR_FIND_PLAYER); wp->pal = wu->spal = 20; // Yellow break; @@ -15679,11 +15715,15 @@ InitBunnyRocket(PLAYERp pp) PlaySound(DIGI_BUNNYATTACK, &pp->posx, &pp->posy, &pp->posz, v3df_dontpan|v3df_doppler); + if (pp->cursectnum < 0) + return 0; + nx = pp->posx; ny = pp->posy; // Spawn a shot // Inserting and setting up variables + //nz = pp->posz + pp->bob_z + Z(12); nz = pp->posz + pp->bob_z + Z(8); w = SpawnSprite(STAT_MISSILE, BOLT_THINMAN_R4, &s_BunnyRocket[0][0], pp->cursectnum, @@ -15789,11 +15829,15 @@ InitNuke(PLAYERp pp) // Make sprite shade brighter u->Vis = 128; + if (pp->cursectnum < 0) + return 0; + nx = pp->posx; ny = pp->posy; // Spawn a shot // Inserting and setting up variables + //nz = pp->posz + pp->bob_z + Z(12); nz = pp->posz + pp->bob_z + Z(8); w = SpawnSprite(STAT_MISSILE, BOLT_THINMAN_R0, &s_Rocket[0][0], pp->cursectnum, @@ -15978,6 +16022,9 @@ InitMicro(PLAYERp pp) if (TargetSortCount > MAX_MICRO) TargetSortCount = MAX_MICRO; + if (pp->cursectnum < 0) + return 0; + for (i = 0; i < MAX_MICRO; i++) { if (ts < &TargetSort[TargetSortCount] && ts->sprite_num >= 0) @@ -17534,6 +17581,9 @@ DoDefaultStat(short SpriteNum) int InitTracerUzi(PLAYERp pp) { + if (pp->cursectnum < 0) + return 0; + USERp u = User[pp->PlayerSprite]; SPRITEp wp, hsp; USERp wu; @@ -17552,6 +17602,7 @@ InitTracerUzi(PLAYERp pp) // Spawn a shot // Inserting and setting up variables + w = SpawnSprite(STAT_MISSILE, 0, s_Tracer, pp->cursectnum, nx, ny, nz, pp->pang, TRACER_VELOCITY); @@ -18549,6 +18600,9 @@ InitTurretRail(short SpriteNum, PLAYERp pp) if (SW_SHAREWARE) return FALSE; // JBF: verify + if (pp->cursectnum < 0) + return 0; + nx = sp->x; ny = sp->y; nz = sp->z; @@ -18605,6 +18659,8 @@ InitTurretLaser(short SpriteNum, PLAYERp pp) if (SW_SHAREWARE) return FALSE; // JBF: verify + if (pp->cursectnum < 0) + return 0; nx = sp->x; ny = sp->y; @@ -19394,12 +19450,16 @@ InitGrenade(PLAYERp pp) // Make sprite shade brighter u->Vis = 128; + if (pp->cursectnum < 0) + return 0; + nx = pp->posx; ny = pp->posy; nz = pp->posz + pp->bob_z + Z(8); // Spawn a shot // Inserting and setting up variables + w = SpawnSprite(STAT_MISSILE, GRENADE, &s_Grenade[0][0], pp->cursectnum, nx, ny, nz, pp->pang, GRENADE_VELOCITY); @@ -19561,12 +19621,16 @@ InitMine(PLAYERp pp) PlaySound(DIGI_MINETHROW, &pp->posx, &pp->posy, &pp->posz, v3df_dontpan|v3df_doppler); + if (pp->cursectnum < 0) + return 0; + nx = pp->posx; ny = pp->posy; nz = pp->posz + pp->bob_z + Z(8); // Spawn a shot // Inserting and setting up variables + w = SpawnSprite(STAT_MISSILE, MINE, s_Mine, pp->cursectnum, nx, ny, nz, pp->pang, MINE_VELOCITY); @@ -19740,6 +19804,9 @@ InitFireball(PLAYERp pp) // Make sprite shade brighter u->Vis = 128; + if (pp->cursectnum < 0) + return 0; + nx += pp->posx; ny += pp->posy; From 863d35d7c215803918e1802a4ece329692ec2534 Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Tue, 3 Dec 2019 09:44:56 +0000 Subject: [PATCH 096/203] SW: Activate ASSERT macro with RELEASE=0 builds git-svn-id: https://svn.eduke32.com/eduke32@8349 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/sw/src/game.h | 32 ++++++++++++++------------------ source/sw/src/panel.cpp | 2 +- source/sw/src/sector.cpp | 2 +- source/sw/src/sprite.cpp | 4 ++-- source/sw/src/track.cpp | 7 ++++--- source/sw/src/weapon.cpp | 4 ++-- 6 files changed, 24 insertions(+), 27 deletions(-) diff --git a/source/sw/src/game.h b/source/sw/src/game.h index ab94a1f7d..efe03ec41 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -60,19 +60,23 @@ extern char isShareware; #define ERR_STD_ARG __FILE__, __LINE__ +void _Assert(const char *expr, const char *strFile, unsigned uLine); +#define PRODUCTION_ASSERT(f) \ + do { \ + if (!(f)) \ + _Assert(#f,ERR_STD_ARG); \ + } while (0) + +#if DEBUG || defined DEBUGGINGAIDS +#define ASSERT(f) PRODUCTION_ASSERT(f) +#else +#define ASSERT(f) do { } while (0) +#endif + #if DEBUG void HeapCheck(char *, int); #define HEAP_CHECK() HeapCheck(__FILE__, __LINE__) -void _Assert(const char *expr, const char *strFile, unsigned uLine); -#define ASSERT(f) \ - if (f) \ - do { } while(0); \ - else \ - _Assert(#f,ERR_STD_ARG); - -#define PRODUCTION_ASSERT(f) ASSERT(f) - void dsprintf(char *, char *, ...); #define DSPRINTF dsprintf @@ -90,16 +94,8 @@ extern int DispMono; #define RANDOM_DEBUG 1 // Set this to 1 for network testing. #else -#define ASSERT(f) do { } while(0) #define MONO_PRINT(str) -void _Assert(const char *expr, const char *strFile, unsigned uLine); -#define PRODUCTION_ASSERT(f) \ - if (f) \ - do { } while(0); \ - else \ - _Assert(#f,ERR_STD_ARG); - void dsprintf_null(char *str, const char *format, ...); #define DSPRINTF dsprintf_null //#define DSPRINTF() @@ -1164,7 +1160,7 @@ struct PLAYERstruct short DiveDamageTics; // Death stuff - short DeathType; + uint16_t DeathType; short Kills; short Killer; //who killed me short KilledPlayer[MAX_SW_PLAYERS_REG]; diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index e4a1f743e..12361d022 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -7671,7 +7671,7 @@ pSpriteControl(PLAYERp pp) // RULE: Sprites can only kill themselves PRODUCTION_ASSERT(psp); ASSERT(ValidPtr(psp)); - ASSERT((uint32_t) psp->Next != 0xCCCCCCCC); + // ASSERT((uint32_t) psp->Next != 0xCCCCCCCC); if (psp->State) pStateControl(psp); diff --git a/source/sw/src/sector.cpp b/source/sw/src/sector.cpp index 24b1947d6..bc79eda0b 100644 --- a/source/sw/src/sector.cpp +++ b/source/sw/src/sector.cpp @@ -486,7 +486,7 @@ SectorSetup(void) { SINE_WAVE_FLOOR *swf; short near_sect = i, base_sect = i; - short swf_ndx = 0; + uint16_t swf_ndx = 0; short cnt = 0, sector_cnt; int range; int range_diff = 0; diff --git a/source/sw/src/sprite.cpp b/source/sw/src/sprite.cpp index d3ea67e97..1083ba77d 100644 --- a/source/sw/src/sprite.cpp +++ b/source/sw/src/sprite.cpp @@ -6812,11 +6812,11 @@ SpriteControl(void) u = User[i]; sp = User[i]->SpriteP; STATE_CONTROL(i, sp, u, StateTics) - ASSERT(nexti >= 0 ? User[nexti] != NULL : TRUE); + // ASSERT(nexti >= 0 ? User[nexti] != NULL : TRUE); #else ASSERT(User[i]); StateControl(i); - ASSERT(nexti >= 0 ? User[nexti] != NULL : TRUE); + // ASSERT(nexti >= 0 ? User[nexti] != NULL : TRUE); #endif } diff --git a/source/sw/src/track.cpp b/source/sw/src/track.cpp index a3a147f32..68935f81c 100644 --- a/source/sw/src/track.cpp +++ b/source/sw/src/track.cpp @@ -726,7 +726,7 @@ void SectorObjectSetupBounds(SECTOR_OBJECTp sop) { int xlow, ylow, xhigh, yhigh; - short sp_num, next_sp_num, sn, startwall, endwall; + short sp_num, next_sp_num, startwall, endwall; int i, k, j; SPRITEp BoundSprite; SWBOOL FoundOutsideLoop = FALSE, FoundSector = FALSE; @@ -846,7 +846,7 @@ SectorObjectSetupBounds(SECTOR_OBJECTp sop) sop->num_sectors++; } - ASSERT(sop->num_sectors < SIZ(SectorObject[0].sector)); + ASSERT((uint16_t)sop->num_sectors < SIZ(SectorObject[0].sector)); } // @@ -967,6 +967,7 @@ SectorObjectSetupBounds(SECTOR_OBJECTp sop) // sector // place all sprites on list + uint16_t sn; for (sn = 0; sn < (int)SIZ(sop->sp_num); sn++) { if (sop->sp_num[sn] == -1) @@ -1498,7 +1499,7 @@ PlaceSectorObjectsOnTracks(void) } } - ASSERT(sop->num_walls < SIZ(sop->xorig)); + ASSERT((uint16_t)sop->num_walls < SIZ(sop->xorig)); if (sop->track <= -1) continue; diff --git a/source/sw/src/weapon.cpp b/source/sw/src/weapon.cpp index d5f64cc72..a22b0b22c 100644 --- a/source/sw/src/weapon.cpp +++ b/source/sw/src/weapon.cpp @@ -7748,7 +7748,7 @@ void TraverseBreakableWalls(short start_sect, int x, int y, int z, short ang, in { sect = sectlist[sectlistplc++]; - ASSERT(sectlistplc < SIZ(sectlist)); + ASSERT((uint16_t)sectlistplc < SIZ(sectlist)); startwall = sector[sect].wallptr; endwall = startwall + sector[sect].wallnum; @@ -7798,7 +7798,7 @@ void TraverseBreakableWalls(short start_sect, int x, int y, int z, short ang, in if (k < 0) { sectlist[sectlistend++] = nextsector; - ASSERT(sectlistend < SIZ(sectlist)); + ASSERT((uint16_t)sectlistend < SIZ(sectlist)); } } From c27616508ea4e61e8c7f5d4cb4d3bba56bfc1385 Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Tue, 3 Dec 2019 09:45:00 +0000 Subject: [PATCH 097/203] SW: Move HIT_PLAX_WALL out of the bit range used for limit raised struct IDs git-svn-id: https://svn.eduke32.com/eduke32@8350 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/sw/src/game.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/sw/src/game.h b/source/sw/src/game.h index efe03ec41..b86e20953 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -527,11 +527,11 @@ int StdRandomRange(int range); #define MDA_REVERSEBLINK 0xF0 // defines for move_sprite return value -#define HIT_MASK (BIT(13)|BIT(14)|BIT(15)) +#define HIT_MASK (BIT(14)|BIT(15)|BIT(16)) #define HIT_SPRITE (BIT(14)|BIT(15)) #define HIT_WALL BIT(15) #define HIT_SECTOR BIT(14) -#define HIT_PLAX_WALL BIT(13) +#define HIT_PLAX_WALL BIT(16) #define NORM_SPRITE(val) ((val) & (MAXSPRITES - 1)) #define NORM_WALL(val) ((val) & (MAXWALLS - 1)) From 53e2a8297d317d8c74a20c4f5c29bc989ec8ba83 Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Tue, 3 Dec 2019 09:45:05 +0000 Subject: [PATCH 098/203] Fix STARTUP_WINDOW=0 on modern macOS git-svn-id: https://svn.eduke32.com/eduke32@8351 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # source/build/src/sdlayer.cpp # source/build/src/startosx.editor.mm # source/platform/macos/osxbits.h # source/platform/macos/startosx.game.mm --- source/platform/macos/osxbits.h | 3 +++ source/platform/macos/osxbits.mm | 14 ++++++++++++++ source/platform/macos/startosx.game.mm | 9 +-------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/source/platform/macos/osxbits.h b/source/platform/macos/osxbits.h index 8a35e14df..639e48869 100644 --- a/source/platform/macos/osxbits.h +++ b/source/platform/macos/osxbits.h @@ -2,6 +2,9 @@ #define osxbits_h_ #include +void osx_preopen(void); +void osx_postopen(void); + int osx_msgbox(const char *name, const char *msg); int osx_ynbox(const char *name, const char *msg); diff --git a/source/platform/macos/osxbits.mm b/source/platform/macos/osxbits.mm index 613d6b554..16f04ec01 100644 --- a/source/platform/macos/osxbits.mm +++ b/source/platform/macos/osxbits.mm @@ -23,6 +23,20 @@ # define MAC_OS_VERSION_10_3 1030 #endif +id nsapp; + +void osx_preopen(void) +{ + // fix for "ld: absolute address to symbol _NSApp in a different linkage unit not supported" + // (OS X 10.6) when building for PPC + nsapp = [NSApplication sharedApplication]; +} + +void osx_postopen(void) +{ + [nsapp finishLaunching]; +} + int osx_msgbox(const char *name, const char *msg) { NSString *mmsg = [[NSString alloc] initWithUTF8String:msg]; diff --git a/source/platform/macos/startosx.game.mm b/source/platform/macos/startosx.game.mm index 731a4634f..b88b589e8 100644 --- a/source/platform/macos/startosx.game.mm +++ b/source/platform/macos/startosx.game.mm @@ -11,6 +11,7 @@ #include "compat.h" #include "baselayer.h" #include "grpscan.h" +#include "osxbits.h" #import "GrpFile.game.h" #import "GameListSource.game.h" @@ -105,8 +106,6 @@ static NSPopUpButton * makeComboBox(void) return comboBox; } -static id nsapp; - /* setAppleMenu disappeared from the headers in 10.4 */ @interface NSApplication(NSAppleMenu) - (void)setAppleMenu:(NSMenu *)menu; @@ -599,10 +598,6 @@ static StartupWindow *startwin = nil; int startwin_open(void) { - // fix for "ld: absolute address to symbol _NSApp in a different linkage unit not supported" - // (OS X 10.6) when building for PPC - nsapp = [NSApplication sharedApplication]; - if (startwin != nil) return 1; startwin = [[StartupWindow alloc] init]; @@ -610,8 +605,6 @@ int startwin_open(void) [startwin setupMessagesMode]; - [nsapp finishLaunching]; - [startwin center]; [startwin makeKeyAndOrderFront:nil]; From 6f9494435a820816ee3f66de5e4a559ce4e4ed70 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 Dec 2019 17:40:35 +0100 Subject: [PATCH 099/203] - adjustment for last commit. --- source/sw/src/draw.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index b1301efa8..6c8bbb330 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -2248,12 +2248,6 @@ drawscreen(PLAYERp pp) PreUpdatePanel(); - if (r_usenewaspect) - { - newaspect_enable = 1; - videoSetCorrectedAspect(); - } - smoothratio = min(max(((int32_t) totalclock - ototalclock) * (65536 / synctics),0),65536); if (!ScreenSavePic) @@ -2478,12 +2472,6 @@ drawscreen(PLAYERp pp) SET(sprite[j].cstat, CSTAT_SPRITE_ALIGNMENT_FLOOR); } - if (r_usenewaspect) - { - newaspect_enable = 0; - videoSetCorrectedAspect(); - } - // if doing a screen save don't need to process the rest if (ScreenSavePic) From 49e0e551d663c11c36c38694821f03fe0e2c6db9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 Dec 2019 20:32:35 +0100 Subject: [PATCH 100/203] - fixed the sliders. --- source/common/fonts/fontchars.cpp | 25 ++++++-- source/common/fonts/fontchars.h | 5 +- source/common/fonts/singlelumpfont.cpp | 11 ++-- source/common/fonts/v_font.cpp | 11 ++-- source/common/fonts/v_font.h | 1 + source/common/menu/menu.cpp | 17 ------ source/common/menu/optionmenuitems.h | 10 +-- wadsrc/static/demolition/confont.lmp | Bin 0 -> 10239 bytes wadsrc/static/demolition/language.csv | 81 ++++++++++++++++++++++++- wadsrc/static/demolition/menudef.txt | 8 +-- 10 files changed, 124 insertions(+), 45 deletions(-) create mode 100644 wadsrc/static/demolition/confont.lmp diff --git a/source/common/fonts/fontchars.cpp b/source/common/fonts/fontchars.cpp index 3298c5212..7e8d0a26c 100644 --- a/source/common/fonts/fontchars.cpp +++ b/source/common/fonts/fontchars.cpp @@ -89,8 +89,8 @@ void FFontChar1::Create8BitPixels (uint8_t *data) // //========================================================================== -FFontChar2::FFontChar2 (const char *sourcelump, int sourcepos, int width, int height, int leftofs, int topofs) -: SourceLump (sourcelump), SourcePos (sourcepos), SourceRemap(nullptr) +FFontChar2::FFontChar2 (TArray& sourcelump, int sourcepos, int width, int height, int leftofs, int topofs) +: sourceData (sourcelump), SourcePos (sourcepos), SourceRemap(nullptr) { Size.x = width; Size.y = height; @@ -119,7 +119,8 @@ void FFontChar2::SetSourceRemap(const uint8_t *sourceremap) void FFontChar2::Create8BitPixels(uint8_t *Pixels) { - auto lump = kopenFileReader(SourceLump, 0); + FileReader lump; + lump.OpenMemory(sourceData.Data(), sourceData.Size()); int destSize = GetWidth() * GetHeight(); uint8_t max = 255; bool rle = true; @@ -225,7 +226,23 @@ void FFontChar2::Create8BitPixels(uint8_t *Pixels) if (destSize < 0) { - I_Error ("The font %s is corrupt", SourceLump.GetChars()); + I_Error ("The font %s is corrupt", GetName().GetChars()); } } +FBitmap FFontChar2::GetBgraBitmap(const PalEntry* remap, int* ptrans) +{ + FBitmap bmp; + TArray buffer; + bmp.Create(Size.x, Size.y); + const uint8_t* ppix = Get8BitPixels(); + if (!ppix) + { + // This is needed for tiles with a palette remap. + buffer.Resize(Size.x * Size.y); + Create8BitPixels(buffer.Data()); + ppix = buffer.Data(); + } + if (ppix) bmp.CopyPixelData(0, 0, ppix, Size.x, Size.y, Size.y, 1, 0, remap); + return bmp; +} diff --git a/source/common/fonts/fontchars.h b/source/common/fonts/fontchars.h index 6cd240e77..42f1f9c9f 100644 --- a/source/common/fonts/fontchars.h +++ b/source/common/fonts/fontchars.h @@ -20,13 +20,14 @@ protected: class FFontChar2 : public FTexture { public: - FFontChar2 (const char *sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); + FFontChar2 (TArray& sourceData, int sourcepos, int width, int height, int leftofs=0, int topofs=0); void Create8BitPixels(uint8_t*) override; + FBitmap GetBgraBitmap(const PalEntry* remap, int* ptrans) override; void SetSourceRemap(const uint8_t *sourceremap); protected: - FString SourceLump; + TArray& sourceData; int SourcePos; const uint8_t *SourceRemap; }; diff --git a/source/common/fonts/singlelumpfont.cpp b/source/common/fonts/singlelumpfont.cpp index dac6aef83..2d5ce46c7 100644 --- a/source/common/fonts/singlelumpfont.cpp +++ b/source/common/fonts/singlelumpfont.cpp @@ -125,7 +125,8 @@ FSingleLumpFont::FSingleLumpFont (const char *name, const char * lump) FontName = name; - auto data = kloadfile(name, 0); + rawData = kloadfile(lump, 0); + auto& data = rawData; if (data[0] == 0xE1 && data[1] == 0xE6 && data[2] == 0xD5 && data[3] == 0x1A) { @@ -329,7 +330,7 @@ void FSingleLumpFont::LoadFON2 (const char * lump, const uint8_t *data) } else { - Chars[i].TranslatedPic = new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight); + Chars[i].TranslatedPic = new FFontChar2 (rawData, int(data_p - data), widths2[i], FontHeight); TileFiles.AllTiles.Push(Chars[i].TranslatedPic); do { @@ -458,7 +459,7 @@ void FSingleLumpFont::LoadBMF(const char *lump, const uint8_t *data) { // Empty character: skip it. continue; } - auto tex = new FFontChar2(lump, int(chardata + chari + 6 - data), + auto tex = new FFontChar2(rawData, int(chardata + chari + 6 - data), chardata[chari+1], // width chardata[chari+2], // height -(int8_t)chardata[chari+3], // x offset @@ -514,7 +515,7 @@ int FSingleLumpFont::BMFCompare(const void *a, const void *b) void FSingleLumpFont::CheckFON1Chars (double *luminosity) { - auto data = kloadfile(GetName(), 0); + auto &data = rawData; if (data.Size() < 8) return; uint8_t used[256], reverse[256]; @@ -530,7 +531,7 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity) if(!Chars[i].TranslatedPic) { - Chars[i].TranslatedPic = new FFontChar2 (GetName(), int(data_p - data.Data()), SpaceWidth, FontHeight); + Chars[i].TranslatedPic = new FFontChar2 (rawData, int(data_p - data.Data()), SpaceWidth, FontHeight); Chars[i].XMove = SpaceWidth; TileFiles.AllTiles.Push(Chars[i].TranslatedPic); } diff --git a/source/common/fonts/v_font.cpp b/source/common/fonts/v_font.cpp index 7bb57e7c7..0a1334513 100644 --- a/source/common/fonts/v_font.cpp +++ b/source/common/fonts/v_font.cpp @@ -93,7 +93,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) FFont *font = FFont::FindFont (name); if (font == nullptr) { - auto lumpy = kopenFileReader(name, 0); + auto lumpy = kopenFileReader(fontlumpname, 0); if (!lumpy.isOpen()) return nullptr; uint32_t head; lumpy.Read (&head, 4); @@ -101,7 +101,8 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) head == MAKE_ID(0xE1,0xE6,0xD5,0x1A)) { FFont *CreateSingleLumpFont (const char *fontname, const char *lump); - return CreateSingleLumpFont (name, name); + lumpy.Close(); + return CreateSingleLumpFont (name, fontlumpname); } } return font; @@ -720,10 +721,8 @@ void V_InitFonts() NewSmallFont = CreateHexLumpFont2("NewSmallFont", "demolition/newconsolefont.hex"); CurrentConsoleFont = NewConsoleFont; - ConFont = V_GetFont("ConsoleFont", "confont"); // The con font is needed for the slider graphics - { - ConFont = SmallFont; - } + ConFont = V_GetFont("ConsoleFont", "demolition/confont.lmp"); // The con font is needed for the slider graphics + SmallFont = ConFont; // This is so that it doesn't crash and that it immediately gets seen as a proble. The SmallFont should later be mapped to the small game font. } void V_ClearFonts() diff --git a/source/common/fonts/v_font.h b/source/common/fonts/v_font.h index 5d1afb2ce..0c35c698a 100644 --- a/source/common/fonts/v_font.h +++ b/source/common/fonts/v_font.h @@ -168,6 +168,7 @@ protected: uint8_t PatchRemap[256]; FName FontName = NAME_None; + TArray rawData; FFont *Next; static FFont *FirstFont; diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index a85917585..4bc9b1bf4 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -967,23 +967,6 @@ CCMD (closemenu) M_ClearMenus(); } -// -// Toggle messages on/off -// -CCMD (togglemessages) -{ - if (show_messages) - { - Printf (128, "%s\n", GStrings("MSGOFF")); - show_messages = false; - } - else - { - Printf (128, "%s\n", GStrings("MSGON")); - show_messages = true; - } -} - EXTERN_CVAR (Int, screenblocks) CCMD(menuconsole) diff --git a/source/common/menu/optionmenuitems.h b/source/common/menu/optionmenuitems.h index 2a35fe1aa..f3c1cc889 100644 --- a/source/common/menu/optionmenuitems.h +++ b/source/common/menu/optionmenuitems.h @@ -604,7 +604,7 @@ public: void DrawSliderElement (int color, int x, int y, const char * str) { - DrawText (&twod, ConFont, color, x, y, str, DTA_CellX, 16 * CleanXfac_1, DTA_CellY, 16 * CleanYfac_1); + DrawText (&twod, ConFont, color, x, y, str, DTA_CellX, 16 * CleanXfac_1, DTA_CellY, 16 * CleanYfac_1, TAG_DONE); } void DrawSlider (int x, int y, double min, double max, double cur, int fracdigits, int indent) @@ -612,8 +612,8 @@ public: char textbuf[16]; double range; int maxlen = 0; - int right = x + (12*8 + 4) * CleanXfac_1; - int cy = y + (OptionSettings.mLinespacing-8)*CleanYfac_1; + int right = x + (12*16 + 4) * CleanXfac_1; + int cy = y;// +(OptionSettings.mLinespacing - 8) * CleanYfac_1; range = max - min; double ccur = clamp(cur, min, max) - min; @@ -621,7 +621,7 @@ public: if (fracdigits >= 0) { snprintf(textbuf, countof(textbuf), "%.*f", fracdigits, max); - maxlen = SmallFont->StringWidth(textbuf) * CleanXfac_1; + maxlen = NewSmallFont->StringWidth(textbuf) * CleanXfac_1; } mSliderShort = right + maxlen > screen->GetWidth(); @@ -885,7 +885,7 @@ public: { // reposition the text so that the cursor is visible when in entering mode. FString text = Represent(); - int tlen = SmallFont->StringWidth(text) * CleanXfac_1; + int tlen = NewSmallFont->StringWidth(text) * CleanXfac_1; int newindent = screen->GetWidth() - tlen - CursorSpace(); if (newindent < indent) indent = newindent; } diff --git a/wadsrc/static/demolition/confont.lmp b/wadsrc/static/demolition/confont.lmp new file mode 100644 index 0000000000000000000000000000000000000000..3d46a3ca4cd3acd1046a9e82360df64403285e36 GIT binary patch literal 10239 zcmcJUO^74udB>ku(sa$&?)0u;ZCBwjN`)Xg<7j#j=+Hf6p_#zMkj-IX<`S5L=dhT8 zy#${^`jYG+U_lb_WkDDWa|!5{tJqs^vJVMP4l6s5>~4s+cM^N1^;MPM|0$J9-P0d) z39YJO?wAvmelvV-QGO8*6k%pYd=ZSUdG+&!L&C`Z!yR}-L#dYtxk6u z9fz&$C`4g9+&cJPZ@;&1*6Vb7orA6|(!3YC=`yLOy|kI7wItnNCO6U~{a%~pk~Hls zlaMA^`um+;H%*b9cDg+1HrqYEYc1|G5G6Rb(q`Jx@NK`(fM(L`GCWO=!y8f}3h1G~ zXogxrceWSdX7SA*hV3j|DZbT`PIr;M_|#yoGexZQ!1;y$sWEyVJ#3K6iUP zKAm2=-{lYIOQCLZoYs4H@21&)=xk?E9TT>9)6RY;?R46m-X4DGq`iX=di&i@(&_c~ zQXX~piR3=N_xBF=JDnEO?_Te;EZPpuW@7fj>?d=}{(5Qo)0#bf`kRg44St&)+x)L` zju34A_d0!|(@%B!hgvY3hhuB}#Q0mfoW@h*?^QWdtEKn9yRb(3;fH^AKeOxUqeuE? zT$lHQrP=*F-HI(uznjLH<*CIBdujQzYoGl1M<1I#`}l_+F0FpSC4W}e&||yu@sED| z$+KsS{_uw%pLe;bXJ*Av@_^-94U5}*f0(^r=ko5d9mnl=+wC}t;?|vZyVYz)t#354njXHN)S^RbqI&mwBBYwBIf2R|5vNjOV?^pw&gzwL-_Wg$|O1RUG zlemd#Ev`v3iV`lm#w-&hT$$F=@0f+MsL@X1xRXVBe5Dh2wxg&PB`o|0OhKcBCAgB^ zTsv``Al+b^O;a>JKQ-qngx*7|nbVnRq5Bo*SQO$4H-$#7;h|JPNF zV!mf_Es0{1BF5M(y6IXnw9Sz$qY!T&N7j51WfmUq&MiFM#mSF9dT$quJpRE4yP0i2 z{^-%8_jb)5|KQQ14|eVGM~goWyYJ0*rym8r|LHAm6;F7iky$ZQ0+6#<3D*6WwmgJg z|JK67@}K(oAN~AK7BXA@n}ww<$(*mP7IyAs55mDt_P`FZd;FU3XJ>QuYx9)N0-cGRWUR~e*XXls%{FFq_`z$)}g@%3}6(o-mlNn^61M>W^ zW`~D>tbZf)`{*zj1U}pduu=FG*`D_s*6*XifZ@YN7!E_2jrcyk5yoTEeliJsG^NfI zUwB~)AH86a<%k7CKF)11(V|zv(GkO@2+r&+)?_^$fyt7Mpi!>#ShH?OysyDytwBm0 zLQefWSRaBJ_?_VvQ*AT~8B_D|RxmU(%O*8c%Pezae#5N7Bg`M>3P$+C_|J#c|AmOO1;m4PyW@T@|qU-?FUo_tya zI=5fD^Q%Bg+X{SVHpzh!A#?-QeL&>sR8m( z0mG&HQ9fFPhQl=*zU7eBN$Z_jv>>^>f7MA&r`fQE$pm85Tu*Qx=~OUWg&S5rm3);h zxhFi>859ivwv0DdrZk>di5N1}5{;v`$M=dDKA5OU?CjVbJNIB{T_JNYgAKZ^GinGr zKm&86iw2I(;PDy-A_E6HX6QUC%p1!_x2!U+n2`Gfxe`VhdXQ(Mx`r>u+dhRE@`$5H zvDR1t_*?FHog9~EJAM-!!deZ-h?=B%<-;nTuO%3N9ih-^+24`VPvBU_>R72?Aq#&G zS)S+5sGiC^9dd|{H2@X>HzQX{9F{@4rSY2LDXc3>h4V_1+Y~^10IgoD;BuA>xKP8!>f{REt>jnF z>Ix_ZVXRhQ0+qPoSjB*y00gtLt!kTpeHUaV9 zh>}CkW5J@K+3Yv2c(V!ri3Rhs`A;=fQcniHWWKNImPuK$9&y%j0qYfm!K>22MJ`8M za?m-9SGo~@TwG!{BPvLgO;}a4Hbq_YnD}Wy!lOwj2dW*bIyQ;=#u{A;g~x;xCngmH zUTyD-zHTnh;9*a_Gb6Sci+3)eug$TvtD973OXsb!z0KJq6~NkF0}Cgg%U9)Sg=9-J zl*}tgteHx-mrS*(3QXnT6^6hvijeDYf)XLen{oo*hW>OthIVbDmhHDz@P*2A(POJK zU@i;>mrOV$6<(oMDvbwzJ_W|jBsfMQ8+Z6;hD3Cs&yZfK0okNz1z;*RP+M&J*wlrr zzuL5A;TNlRzff1(k(_3p^Qt@i$})OKT769OEgj}kDO^pnPwihAKeI65WJu5+5}IiZ0l|FK1UYUYLUPqA|FR?Z_9Av4$5bFro&g9>^53d;Lm87;Z=xLLn1N z1}J-?veQCEAn=y#mBC&SkWbr1)K0&sC?}DmgROOYR$7Rtu`;Sa6x(*tSKy4hEA;Vg zMQs{cQY5M1xh0+{EEQeyedMxf1^B*>-8!M%*FQ7b58ht&`}Fnwd~h2`;(EnT7Rgs) zeF6wX$<8_Nf|%jX5-ym>npe5!A(sZAR_)w#-%Ec>XjnZ{uJK{4XF7hJ)IbDRf3Y-S zDrT`vnBnn}7x6y^hT(CK<)ctm>odFW?iCyQZ~RWis{tQ_1BRh5C{;o2mX{u)7+M{5L{ z>nOnn-@{`@a5mSX9J(~bH;2fi78teDVlfjR=O$1@7U_>GluQ>(^o+jMMwwlc5BbV;agK0Hm0)Ef&3~s4F>r^O{xSA(U`Z`bu{iELWARPOp=`4f zhQMslHaK4B*CFM*k6(*AuNS>)@Xvprqga5MzUtNM&(TJy))%*B=+CnLO8MfIz!({E z6Zb0>IPm7{&&Gp?zAC|ZeN77-HCRl^mkq9KRi}!Jb$!W3{syq}3dwkinI$47NmIj77zy*1OIG9u@X0*k8{Tr8{dTGhOqz2*uy zrxTJC1;$F?lJF}9mA)kGuuR^w$2$3yoTWrPfB4Djz}QQ~Z@$GTSPXQGZk8mb%5T+% z_!~u+v;jcUUTp5&7;0U-o7;$9Rp*G}1ux$#SE)|%3%+(eFPu|Gw(J}(pHt-4jm_Lz z4w3@vP61-|O=btXsvmmoank49drdvdenK2YyT>ma-N4P9%9MMDoO|8tKXLBF3|3GyNIqm7+ zRZ%G-zp9B|*H0BiY2?0E;{&C86>X^X;vW;m>%kztbFx#RD7~x(;&sNCfL3$j^nJ++ z1)Q}x=&wtKR)@kbnYmde*t=dby7>18?S2S&Hye6+z_I69UcQ9!*G@y;6s`9bVnOg^n^EWmXh=l>w0FIFp``FL;gF6s_My@LW zJ(uI>+|lc-^6kNIFOVw~Rxc9tcA|;z37$u<>|l+c;O>Iwa{7-~L6zAS#a(?;Hi}9@ z%2v4NeL#tOw`83r@VO@Bkrf_*ln7jM@$NQU|AJ;&*PT`z!6LCYon1u???8Z%CM@O4&s zshyb`S$Mx_4ht+?P%X|s<+lg|Fq^KREqG= G7XE)78R{4S literal 0 HcmV?d00001 diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index 53ee61c61..d4b92acba 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -256,8 +256,12 @@ Jump,CNTRLMNU_JUMP,,,,Skok,Springen,,Salti,Saltar,,Hyppää,Sauter,Ugrás,Salta, Crouch,CNTRLMNU_CROUCH,,,,Kleknutí,Ducken,,Kaŭri,Agacharse,,Kyyristy,S'accroupir (tenir),Guggolás,Abbassati,屈む,숙이기,Hurken,Kucnięcie,Agachar,,,Приседание,Чучни Crouch Toggle,CNTRLMNU_TOGGLECROUCH,,,,Zap. / Vyp. kleknutí,Ducken an/aus,,Kaŭrbaskulo,Alternar agachado,,Kyyristymisen vaihtokytkin,S'accroupir (alterner),Guggolási kapcsoló,Toggle abbassamento,屈む切替,숙이기 토글,Hurken Toggle,Włącz / Wyłącz kucnięcie,Agachar (Liga/Desliga),,,Сесть/встать,Чучни (без држања) Mouse look,CNTRLMNU_MOUSELOOK,,,,Pohled myší,Maus-Blick,,Musilregardo,Vista con ratón,,Hiirikatselu,Vue à la souris,Egérrel való nézelődés,Modalità vista col mouse,マウス視点上下化,마우스 룩,Muis-look,Rozglądanie się myszką,Vista com o mouse,Vista com o rato,,Обзор мышью,Гледај мишем -Look up,CNTRLMNU_LOOKUP,,,,Pohled vzhůru,Nach oben schauen,,Rigardi supre,Mirar arriba,,Katso ylös,Regarder en haut,Felfele nézés,Guarda sopra,視点を上げる,위로 보기,Kijk omhoog,Patrz w górę,Olhar para cima,,,Смотреть вверх,Гледај горе +Look up,CNTRLMNU_LOOKUP,Look doesn't change the aim! It only alters the view pitch,,,Pohled vzhůru,Nach oben schauen,,Rigardi supre,Mirar arriba,,Katso ylös,Regarder en haut,Felfele nézés,Guarda sopra,視点を上げる,위로 보기,Kijk omhoog,Patrz w górę,Olhar para cima,,,Смотреть вверх,Гледај горе Look down,CNTRLMNU_LOOKDOWN,,,,Pohled dolů,Nach unten schauen,,Rigardi malsupre,Mirar abajo,,Katso alas,Regarder en bas,Lefele nézés,Guarda sotto,視点を下げる,아래로 보기,Kijk naar beneden,Patrz w dół,Olhar para baixo,,,Смотреть вниз,Гледај доле +Aim up,CNTRLMNU_AIMUP,,,,,Nach oben zielen,,,,,,,,,,,,,,,,, +Aim down,CNTRLMNU_AIMDOWN,,,,,Nach unten zielen,,,,,,,,,,,,,,,,, +Look left,CNTRLMNU_LOOKLEFT,,,,,Nach links schauen,,,,,,,,,,,,,,,,, +Look right,CNTRLMNU_LOOKRIGHT,,,,,Nach rechts schauen,,,,,,,,,,,,,,,,, Center view,CNTRLMNU_CENTERVIEW,,,Centre view,Vystředit pohled,Ansicht zentrieren,,Centra vidon,Centrar vista,,Keskitä katse,Recentrer Vue,Nézet középreigazítása,Sguardo centrato,視点を戻す,중앙 시점으로 보기,Middenaanzicht,Wyśrodkuj widok,Olhar para o centro,,,Отцентрировать взгляд,Централизирај поглед Run,CNTRLMNU_RUN,,,,Běh,Rennen,,Kuri,Correr,,Juokse,Courir (tenir),Futás,Corri,駆け足,달리기,Rennen,Bieg,Correr,,,Бег,Трчи Toggle Run,CNTRLMNU_TOGGLERUN,,,,Zap. / Vyp. běh,Rennen an/aus,,Baskulkuri,Alternar Correr,,Juoksun vaihtokytkin,Courir (alterner),Futás kapcsoló,Toggle corsa,常時駆け足切替,달리기 토글,Rennen aan/uit,Włącz / Wyłącz bieg,Correr (Liga/Desliga),,,Бежать/идти,Трчи (без држања) @@ -321,4 +325,77 @@ Fire Mission,CNTRLMNU_FIRE_MISSION,,,,,,,,,,,,,,,,,,,,,, Reload,CNTRLMNU_RELOAD,,,,,"Waffe laden ",,,,,,,,,,,,,,,,, Radar,CNTRLMNU_RADAR,,,,,,,,,,,,,,,,,,,,,, -Other,CNTRLMNU_OTHER,,,,Ostatní,Andere,,Alia,Otros,,Muu,Autres,Más,Altro,その他,그 외 조작,Andere,Inne,Outro,,,Прочее,Остало \ No newline at end of file +Other,CNTRLMNU_OTHER,,,,Ostatní,Andere,,Alia,Otros,,Muu,Autres,Más,Altro,その他,그 외 조작,Andere,Inne,Outro,,,Прочее,Остало +Messages: OFF,MSGOFF,,,,Zprávy ZAP,Meldungen AUS,Μηνύματα ΚΛΕΙΣΤΑ,Mesaĝoj MALAKTIVA,Mensajes DESACTIVADOS,,Viestit POIS PÄÄLTÄ,Messages désactivés.,Üzenetek KI,Messaggi DISATTIVATI,メッセージ: オフ,메시지 끔,Berichten UIT,Wiadomości WYŁĄCZONE,Mensagens DESATIVADAS,,,Сообщения ОТКЛЮЧЕНЫ,Поруке ИСКЉУЧЕНЕ +Messages: ON,MSGON,,,,Zprávy VYP,Meldungen AN,Μηνύματα ΑΝΟΙΧΤΑ,Mesaĝoj AKTIVA,Mensajes ACTIVADOS,,Viestit PÄÄLLÄ,Messages activés.,Üzenetek BE,Messaggi ATTIVATI,メッセージ: オン,메시지 켬,Berichten AAN,Wiadomości WŁĄCZONE,Mensagens ATIVADAS,,,Сообщения ВКЛЮЧЁНЫ,Поруке УКЉУЧЕНЕ +Writin': OFF,MSGOFF,,Redneck RedneckRides,,Zprávy ZAP,Geschreibsel: AUS,Μηνύματα ΚΛΕΙΣΤΑ,Mesaĝoj MALAKTIVA,Mensajes DESACTIVADOS,,Viestit POIS PÄÄLTÄ,Messages désactivés.,Üzenetek KI,Messaggi DISATTIVATI,メッセージ: オフ,메시지 끔,Berichten UIT,Wiadomości WYŁĄCZONE,Mensagens DESATIVADAS,,,Сообщения ОТКЛЮЧЕНЫ,Поруке ИСКЉУЧЕНЕ +Writin': ON,MSGON,,Redneck RedneckRides,,Zprávy VYP,Geschreibsel: AN,Μηνύματα ΑΝΟΙΧΤΑ,Mesaĝoj AKTIVA,Mensajes ACTIVADOS,,Viestit PÄÄLLÄ,Messages activés.,Üzenetek BE,Messaggi ATTIVATI,メッセージ: オン,메시지 켬,Berichten AAN,Wiadomości WŁĄCZONE,Mensagens ATIVADAS,,,Сообщения ВКЛЮЧЁНЫ,Поруке УКЉУЧЕНЕ +Toggle automap,CNTRLMNU_AUTOMAP,,,,Zap. / Vyp. automapu,Automap an/aus,,Baskuligi aŭtomapo,Alternar automapa,,Kytke automaattikartta päälle/pois,Activer Carte,Térkép ki- bekapcsolása,Toggle automappa,オートマップの切替,오토맵 조정,Automap aan/uit,Włącz mapę,Ativar automapa,,,Открыть автокарту,Прикажи аутомапу +Chasecam,CNTRLMNU_CHASECAM,,,,Kamera z třetí osoby,Verfolgerkamera,,Ĉaskamerao,Cámara de Seguimiento,,Seurantakamera,Caméra 3ième personne,Külsőnézetű kamera,Telecamera di inseguimento,背後視点,3인칭 카메라,,Kamera Śledzenia,Câmera de terceira-pessoa,Câmera em terceira-pessoa,,Вид от 3-го лица (Chasecam),Чејс-кем +Screenshot,CNTRLMNU_SCREENSHOT,,,,Pořídit snímek obrazovky,,,Ekranfoto,Captura de pantalla,,Kuvakaappaus,Capture d'écran,Képernyő lefényképezése,Cattura schermo,画面キャプチャ,스크린샷,,Zrzut ekranu,Captura de tela,,,Скриншот,Усликај +Open console,CNTRLMNU_CONSOLE,,,,Otevřít konzoli,Konsole öffnen,,Malfermi konzolon,Abrir consola,,Avaa konsoli,Ouvrir Console,Konzol előhozása,Apri la console,コンソールを開く,콘솔 열기,Open console,Otwórz konsolę,Abrir console,Abrir consola,,Открыть консоль,Отвори консолу +Pause,CNTRLMNU_PAUSE,,,,Pauza,,,Paŭzo,Pausa,,Tauko,,Szünet,Pausa,ポーズ,일시정지,Pauze,Pauza,Pausa,,,Пауза,Пауза +Increase Display Size,CNTRLMNU_DISPLAY_INC,,,,Zvětšit velikost displeje,Anzeige vergrößern,,Pligrandigi Ekranamplekson,Agrandar Ventana,,Suurenna näytön kokoa,Agrandir l'affichage,Képméret növelése,Incrementa la dimensione del display,画面サイズを拡大,화면 크기 늘리기,Vergroot het display,Powiększ Rozmiar Wyświetlania,Aumentar Tamanho de Tela,Aumentar Tamanho do Ecrã,,Увеличить размер экрана,Повећајте величину екрана +Decrease Display Size,CNTRLMNU_DISPLAY_DEC,,,,Zmenšit velikost displeje,Anzeige verkleinern,,Plimalgrandigi Ekranamplekson,Reducir Ventana,,Pienennä näytön kokoa,Réduire l'affichage,Képméret csökkentése,Decrementa la dimensione del display,画面サイズを縮小,화면 크기 줄이기,Verlaag het display,Pomniejsz Rozmiar Wyświetlania,Diminuir Tamanho de Tela,Diminuir Tamanho do Ecrã,,Уменьшить размер экрана,Смањите величину екрана +Open Help,CNTRLMNU_OPEN_HELP,,,,Otevřít nápovědu,Hilfe öffnen,,Malfermi Helpon,Abrir Ayuda,,Avaa ohje,Ouvrir Aide,Segítség előhozása,Apri l'aiuto,"ヘルプを開く +",도움말 열기,Open hulp,Otwórz Pomoc,Abrir Ajuda,,,Экран помощи,Отвори помоћ +Open Save Menu,CNTRLMNU_OPEN_SAVE,,,,Otevřít menu pro uložení,Speichermenü öffnen,,Malfermi Konservmenuon,Menú de Guardar Partida,,Avaa tallennusvalikko,Ouvrir Menu Sauvegarde,Mentés menü előhozása,Apri il menu di salvataggio,セーブメニューを開く,저장 화면 열기,Menu opslaan openen,Otwórz Menu Zapisu,Abrir Menu de Salvar,Abrir Menu de Gravação,,Сохранение игры,Отвори сачуване игре +Open Load Menu,CNTRLMNU_OPEN_LOAD,,,,Otevřít menu pro načtení,Lademenü öffnen,,Malfermi Ŝarĝmenuon,Menú de Cargar Partida,,Avaa latausvalikko,Ouvrir Menu Chargement,Betöltés menü előhozása,Apri il menu di caricamento,ロードメニューを開く,불러오기 화면 열기,Menu laden openen,Otwórz Menu Wczytania,Abrir Menu de Carregar,,,Загрузка игры,Отвори игре за учитати +Open Options Menu,CNTRLMNU_OPEN_OPTIONS,,,,Otevřít nastavení,Optionsmenü öffnen,,Malfermi Agordmenuon,Menú de Opciones,,Avaa asetusvalikko,Ouvrir Menu Options,Beállítások menü előhozása,Apri il menu delle opzioni,オプションメニューを開く,설정 화면 열기,Menu Opties openen,Otwórz Menu Opcji,Abrir Menu de Opções,,,Главное меню настроек,Отвори мени опција +Open Display Menu,CNTRLMNU_OPEN_DISPLAY,,,,Otevřít nastavení grafiky,Anzeigemenü öffnen,,Malfermi Ekranmenuon,Menú de Opciones de Visualización,,Avaa näyttövalikko,Ouvrir Menu Affichage,Megjelenítés menü előhozása,Apri il menu del display,ディスプレイメニューを開く,디스플레이 화면 열기,Displaymenu openen,Otwórz Menu Wyświetlania,Abrir Menu de Vídeo,,,Меню настроек видео,Отвори мени приказа +Quicksave,CNTRLMNU_QUICKSAVE,,,,Rychlé uložení,Schnellspeichern,,Rapidkonservo,Guardado Rápido,,Pikatallenna,Sauv. Rapide,Gyorsmentés,Salvataggio rapido,クイックセーブ,빠른 저장,Snel opslaan,Szybki Zapis,Salvamento rápido,Gravação rápida,,Быстрое сохранение,Брзо-сачувај +Quickload,CNTRLMNU_QUICKLOAD,,,,Rychlé načtení,Schnellladen,,Rapidŝarĝo,Cargado Rápido,,Pikalataa,Charg. Rapide,Gyors betöltés,Caricamento rapido,クイックロード,빠른 불러오기,Snel laden,Szybkie Wczytanie,Carregamento rápido,,,Быстрая загрузка,Брзо-учитај +Exit to Main Menu,CNTRLMNU_EXIT_TO_MAIN,,,,Odejít do hlavního menu,Zurück zum Hauptmenü,,Eliri al Ĉefa Menuo,Salir al Menú Principal,,Poistu päävalikkoon,Sortie Menu Principal,Kilépés a főmenübe,Esci dal menu principale,メインメニューに戻る,메뉴로 나오기,Afsluiten naar het hoofdmenu,Wyjdź do Głównego Menu,Sair para o Menu Principal,,,Выход в главное меню,Изађи у главни мени +Toggle Messages,CNTRLMNU_TOGGLE_MESSAGES,,,,Zap. / Vyp. zprávy,Nachrichten an/aus,,Baskuligi Mensaĝojn,Alternar Mensajes,,Kytke viestit päälle tai pois,Act./Déasct. Messages,Üzenetek kapcsololása,Toggle messaggi,メッセージ表示の切替,메시지 토글,Berichten aan/uit,Włącz / Wyłącz Wiadomości,Ativar Mensagens,,,Переключение сообщений,Таглави поруке +Quit Game,CNTRLMNU_MENU_QUIT,,,,Odejít ze hry,Spiel beenden,,Ĉesigi Ludon,Salir del Juego,,Lopeta peli,Quitter le Jeu,Kilépés a játékból.,Esci dal gioco,ゲームを終了,게임 종료,Stop het spel,Wyjdź z Gry,Sair do Jogo,,,Выход,Изађи из игре +Adjust Gamma,CNTRLMNU_ADJUST_GAMMA,,,,Nastavit gamu,Gamma-Anpassung,,Agordi Gamaon,Ajustar Gamma,,Säädä gammaa,Ajuster Gamma,Gamma állítása,Aggiustamento Gamma,ガンマ値を調整,감마 조정,Gamma aanpassen,Dostosuj Gammę,Ajustar Gama,,,Настройка гаммы,Подесите осветљење +Mouse Options,MOUSEMNU_TITLE,,,,Nastavení myši,Mausoptionen,,Musilagordoj,Opciones del Ratón,,Hiiriasetukset,Options Souris,Egér beállítások,Opzioni Mouse,マウス オプション,마우스 설정,Muis opties,Opcje Myszki,Opções de mouse,Opções do rato,,Настройки мыши,Миш +Enable mouse,MOUSEMNU_ENABLEMOUSE,,,,Povolit myš,Maus aktiv,,Aktivigi muson,Habilitar ratón,,Ota hiiri käyttöön,Activer Souris,Egér engedélyezése,Abilita il mouse,マウスの使用,마우스 사용,Muis inschakelen,Włącz myszkę,Habilitar mouse,Permitir uso do rato,,Использовать мышь,Укључи миш +Enable mouse in menus,MOUSEMNU_MOUSEINMENU,,,,Povolit myš v nabídkách,Maus aktiv in Menüs,,Aktivigi muson en menuoj,Usa ratón en los menús,,Ota hiiri käyttöön valikoissa,Activer Souris dans les Menus,Egér engedélyezése a menüben.,Abilita il mouse nei menu,メニューでのマウスの使用,메뉴에서 마우스 사용,Muis in menu's inschakelen,Włącz myszkę w menu,Habilitar mouse nos menus,Permitir rato nos menus,,Использовать мышь в меню,Укључи миш у менијима +Show back button,MOUSEMNU_SHOWBACKBUTTON,,,,Zobrazit tlačítko zpět,Zeige Zurück-Knopf,,Montri antaŭklavon,Botón de retroceso,,Näytä taaksenäppäin,Afficher le bouton retour,Vissza gomb mutatása,Mostra il bottone per tornare indietro,戻るボタンを表示,뒤로가기 버튼 보이기,Toon terug knop,Pokaż przycisk powrotu,Mostrar botão de voltar,,,Расположение кнопки «назад»,Прикажи тастер за назад +Cursor,MOUSEMNU_CURSOR,,,,Kurzor,,,Musmontrilo,,,Osoitin,Curseur,Egérmutató,Cursore,カーソル,커서,,Kursor,,,,Курсор,Курсор +Overall sensitivity,MOUSEMNU_SENSITIVITY,,,,Celková citlivost,Allgemeine Empfindlichkeit,,Tutsentemo,Sensibilidad promedio,,Yleinen herkkyys,Sensibilité générale,Teljes érzékenység,Sensibilità complessiva,全体的な感度,전체 민감도,Algemene gevoeligheid,Ogólna wrażliwość,Sensibilidade geral,,,Общая чувствительность,Осетљивост +Prescale mouse movement,MOUSEMNU_NOPRESCALE,,,,Akcelerace myši,Mausbewegung skalieren,,Antaŭpesilo musmovo,Pre-escalar movimiento,,Esiskaalaa hiiren liike,Prescaling mouvement souris,,Prescala il movimento del mouse,マウス操作の精密化,속도 높인 움직임,Muisbewegingen vooraf inschalen,Przeskaluj ruch myszki,Movimento pré-escalar do mouse,Movimento pré-escalar do rato,,Увеличенная чувствительность,Убрзање миша +Smooth mouse movement,MOUSEMNU_SMOOTHMOUSE,,,,Vyhladit pohyb myši,Mausbewegung glätten,,Glata musmovo,Mov. fluido del ratón,,Sulava hiiren liike,Lissage Souris,Egyenletes egérmozdulatok,Movimento del mouse liscio,マウス操作を滑らかにする,부드러운 움직임,Vlotte muisbeweging,Gładki ruch myszki,Movimento fluído do mouse,Movimento fluído do rato,,Плавное перемещение,Глатки окрет +Turning speed,MOUSEMNU_TURNSPEED,,,,Rychlost otáčení,Umdrehgeschwindigkeit,,Turnorapido,Velocidad de giro,,Kääntymisnopeus,Vitesse pour tourner,Fordulási sebesség,Velocità di rotazione,旋回速度,회전 속도,Draaisnelheid,Szybkość obracania się,Velocidade de giro,,,Скорость поворота,Брзина окрета +Mouselook speed,MOUSEMNU_MOUSELOOKSPEED,,,,Rychlost pohledu nahoru/dolů,Mausblick-Geschwindigkeit,,Musrigarda rapido.,Veloc. de vista con ratón,,Katselunopeus,Vitesse Vue Souris,Egérrel való nézés sebessége,Velocità di rotazione della vista,上下視点速度,마우스룩 속도,Mouselook snelheid,Szybkość rozglądania się myszką,Velocidade de vista com mouse,Velocidade de vista com rato,,Скорость обзора,Брзина гледања мишем +Forward/Backward speed,MOUSEMNU_FORWBACKSPEED,,,,Rychlost pohybu vpřed/vzad,Vor/Rückwärtsgeschwindigkeit,,Antaŭa/Malantaŭa rapido,Veloc. de avance/retroceso,,Eteen-/taaksepäin liikkeen nopeus,Vitesse Avancer/reculer,Előre/Hátra sebesség,Velocità avanti/indietro,"前進/後退速度 +",전진/후진 속도,Voorwaartse/achterwaartse snelheid,Szybkość chodzenia do przodu/do tyłu,Velocidade de deslocamento para frente/trás,,,Скорость передвижения,Брзина окрета напред/уназад +Strafing speed,MOUSEMNU_STRAFESPEED,,,,Rychlost pohybu do stran,Seitwärtsgeschwindigkeit,,Flankmova rapido,Veloc. de mov. lateral,,Sivuttaisastunnan nopeus,Vitesse Gauche/Droite,,Velocità movimento laterale,横移動速度,좌진/우진 속도,Zijdelings snelheid,Szybkość uników,Velocidade de deslocamento lateral,,,Скорость движения боком,Брзина стрејфа +Always Mouselook,MOUSEMNU_ALWAYSMOUSELOOK,,,,Vždy se rozhlížet myší,Mausblick immer an,,Ĉiam Musrigardo,Siempre mirar con ratón,,Jatkuva hiirikatselu,Toujours vue Souris,Mindig nézelődés az egérrel,Vista col mouse,常に上下視点をオン,마우스룩 사용,Altijd Mouselook,Zawsze zezwalaj na rozglądanie się myszką,Vista com mouse sempre ligado,Vista com rato sempre ligada,,Обзор мышью,Гледање мишем +Invert Mouse,MOUSEMNU_INVERTMOUSE,,,,Inverzní myš,Maus invertieren,,Inversa Muso,Invertir ratón,,Käännä hiiri,Inverser Souris,Egérirányok megfordítása,Mouse invertito,視点操作反転,마우스 방향 전환,Muis omkeren,Odwróć Myszkę,Inverter mouse,Inverter rato,,Инвертирование мыши,Инвертуј миш +Mouselook Toggle,MOUSEMNU_LOOKSPRING,,,,Automatické vystředění pohledu,Automatisch zentrieren,,Rigardsalto,Mirar con ratón,,Katseenpalautin,Recentrer après Vue Souris,,,視点水平化,마우스룩 시점 초기화,Lente,Automatyczne Wyśrodkowanie,Centralizar automáticamente,Centrar automáticamente,,Передвижение мышью,Покрет мишем +Mouse Strafe,MOUSEMNU_LOOKSTRAFE,,,,Použít myš k pohybu do stran,Seitwärts bewegen mit der Maus,,Rigardturnmovo,Mirar con movimiento,,Sivuttaisastuntapalautin,Mouvement Latéral par Souris,,,視点横移動化,마우스룩 좌우 이동,Lookstrafe,Unikanie przy użyciu myszki,Deslocamento lateral com o mouse,Deslocamento lateral com o rato,,Движение боком мышью,Стрејф мишем +Upper left,OPTVAL_UPPERLEFT,,,,Vlevo nahoře,Oben links,,Supra maldekstre,Sup. izquierda,,Ylävasemmalla,Supérieur gauche,,Superiore sinistro,左上,왼쪽 위,Linksboven,Lewy górny róg,Esquerda superior,,,Вверху слева,Горње лево +Upper right,OPTVAL_UPPERRIGHT,,,,Vpravo nahoře,Oben rechts,,Supra dekstre,Sup. derecha,,Yläoikealla,Supérieur droite,,Superiore destro,右上,오른쪽 위,Rechtsboven,Prawy górny róg,Direita superior,,,Вверху справа,Горње десно +Lower left,OPTVAL_LOWERLEFT,,,,Vlevo dole,Unten links ,,Suba maldekstre,Inf. izquierda,,Alavasemmalla,Inférieur gauche,,Inferiore sinistro,左下,왼쪽 밑,Linksonder,Lewy dolny róg,Esquerda inferior,,,Внизу слева,Доње лево +Lower right,OPTVAL_LOWERRIGHT,,,,Vpravo dole,Unten rechts,,Suba dekstre,Inf. derecha,,Alaoikealla,Inférieur droite,,Inferiore destro,右下,오른쪽 밑,Rechtsonder,Prawy dolny róg,Direita inferior,,,Внизу справа,Доње десно +Touchscreen-like,OPTVAL_TOUCHSCREENLIKE,,,,Jako dotyková obrazovka,Wie auf einem Touchscreen,,Tuŝekrana,Pant. táctil,,Kosketusnäyttömäinen,Style écran tactile,,Come il Touchscreen,タッチスクリーン式,터치스크린 같게,Touchscreen-achtige,Jak ekrean dotykowy,Estilo touchscreen,,,Как сенсорный экран,Као додирни екран +Simple arrow,OPTSTR_SIMPLEARROW,,,,Jednoduchý kurzor,Einfacher Pfeil,,Simpla sago,Flecha simple,,Yksinkertainen nuoli,Flèche simple,,Freccia semplice,シンプル,기본 커서,Eenvoudige pijl,Prosta strzałka,Flecha simples,Cursor simples,,Стрелка,Стрелица +System cursor,OPTSTR_SYSTEMCURSOR,,,,Systémový kurzor,Systemcursor,,Sistema kursoro,Cursor del sistema,,Järjestelmän osoitin,Curseur Système,,Cursore di sistema,システム,시스템 커서,Systeemcursor,Kursor systemu,Cursor do sistema,,,Системный курсор,Системска стрелица +Default,OPTVAL_DEFAULT,,,,Výchozí,Standard,,Defaŭlte,Por defecto,,Oletus,Défaut,,,デフォルト,기본 설정,Standaard,Domyślne,Padrão,,,По умолчанию,Подраз. +Configure Controller,JOYMNU_TITLE,,,,Konfigurovat ovladač,Controller konfigurieren,,Agordi Ludregilon,Configurar Mando,,Peliohjainasetukset,Configurer Mannette,Kontroller testreszabása,Configura il controller,コントローラー構成:,컨트롤러 구성,Controller configureren,Konfiguruj Kontroler,Configurar Controle,Configurar Comando,,Настроить контроллер,Конфигурација контролера +Controller Options,JOYMNU_OPTIONS,,,,Nastavení ovladače,Controlleroptionen,,Ludregilagordoj,Opciones del mando,,Peliohjainasetukset,Options Mannette,Kontroller beállításai,Opzioni del controller,コントローラー設定,컨트롤러 설정,Controller opties,Opcje Kontrolera,Opções de Controle,Opções do Comando,,Настройки контроллера,Подешавања контролера +Block controller input in menu,JOYMNU_NOMENU,,,,Zakázat ovladač v nabídkách,Blockiere Controllereingabe im Menü,,Blokigi ludregilon enigon en menuo,Bloq. entrada de mando en menú,,Estä ohjainsyötteet valikoissa,Bloquer manette dans les menus,Kontroller ne működjön a menüben,Blocca l'input del controller nei menu,メニューではコントローラーを無視,메뉴에서 컨트롤러 끄기,Blokkeer de controller in het menu,Blokuj wejście kontrolera w menu,Bloquear controle no menu,Bloquear comando no menu,,Отключить контроллер в меню,Блокирај улаз контролера у менију +Enable controller support,JOYMNU_ENABLE,,,,Povolit podporu pro ovladače,Erlaube Controllerunterstützung,,Aktivigi ludregilsubtenon,Activar soporte de mandos,,Ota käyttöön peliohjaintuki,Activer support contrôleur,,Abilita il supporto del controller,コントローラーサポート許可,컨트롤러 지원 허용,Controllerondersteuning inschakelen,Włącz wsparcie kontrolera,Habilitar suporte de controles,,,Включить поддержку контроллера,Омогући подршку за контролере +Enable DirectInput controllers,JOYMNU_DINPUT,,,,Povolit ovladače DirectInput,Erlaube DirectInput-Controller,,Aktivigi DirectInput ludregilojn,Usa controles DirectInput,,Ota käyttöön DirectInput-ohjaimet,Activer contrôleurs DirectInput,,Abilita i controlli DirectInput,ダイレクトインプットコントローラー許可,다이렉트 인풋 컨트롤러 허용,DirectInput-controllers inschakelen,Włącz kontrolery DirectInput,Habilitar controles DirectInput,,,Включить контроллеры DirectInput,Омогући директинпут контролере +Enable XInput controllers,JOYMNU_XINPUT,,,,Povolit ovladače XInput,Erlaube XInput-Controller,,Aktivigi XInput ludregilojn,Usa controles XInput,,Ota käyttöön XInput-ohjaimet,Activer contrôleurs XInput,,Abilita i controlli XInput,Xinput コントローラー許可,X인풋 컨트롤러 허용,XInput-controllers inschakelen,Włącz kontrolery XInput,Habilitar controles XInput,,,Включить контроллеры XInput,Омогући Иксинпут контролере +Enable raw PlayStation 2 adapters,JOYMNU_PS2,,,,Povolit ovladače PlayStation 2,Erlaube Playstation 2-Controller,,Aktivigi krudajn PlayStation 2 adaptilojn,Usa adaptadores de PlayStation 2,,Ota käyttöön raa'at PlayStation 2 -adapterit,Activer adaptateurs PS2 bruts,,Abilita gli adattatori raw PlayStation 2,PlayStation2 アダプター許可,PS2 어뎁터 허용,Raw PlayStation 2-adapters inschakelen,Włącz adaptery PlayStation 2,Habilitar adaptadores de PlayStation 2,,,Использовать адаптеры PlayStation 2 напрямую,Омогући сирове Плејстејшн 2 адаптере +No controllers detected,JOYMNU_NOCON,,,,Nenalezeny žádné ovladače,Keine Controller gefunden,,Neniu ludregilojn detektas,No hay mandos detectados,,Ei havaittuja ohjaimia,Aucun Contrôleur détecté.,,Nessun controller trovato,コントローラーが見つかりません,인식된 컨트롤러 없음,Geen controllers gedetecteerd,Nie wykryto kontrolerów,Nenhum controle detectado,Nenhum comando foi detectado,,Контроллеры не обнаружены,Нема детектованих контролера +Configure controllers:,JOYMNU_CONFIG,,,,Nastavit ovladače:,Controller konfigurieren,,Agordi ludregilojn:,Configurar controles:,,Mukauta ohjaimia:,Configurer contrôleurs:,,Configura i controller:,コントローラー構成:,컨트롤러 설정:,Configureer controllers:,Konfiguruj kontrolery:,Configurar controles:,Configurar comandos,,Настроить контроллер:,Подешавања контролере: +Controller support must be,JOYMNU_DISABLED1,,,,Podpora ovladačů musí být,Controllerunterstütung muss aktiviert sein,,Ludregilsubteno devas esti,El soporte de mandos debe estar,,Ohjaintuen täytyy olla otettu,Le Support de contrôleur doit être activé,,Il supporto ai controller deve essere,コントローラーサポートは,감지하려면 컨트롤러 지원을,Controller ondersteuning moet ingeschakeld zijn,Wsparcie kontrolera musi być,Suporte à controles deve ser,Suporte a comandos devem ser,,Включите поддержку контроллера,Омогућите подржавање контролера +enabled to detect any,JOYMNU_DISABLED2,Supposed to be empty in Russian and Serbian.,,,zapnuta pro jejich detekování,um welche zu finden,,ŝaltita detekti ajn,activado para detectar alguno,,käyttöön ohjainten havaitsemiseksi,avant de pouvoir en détecter un.,,abilitato a trovare ogni,検出しました,활성화 해야합니다.,om eventuele regelaars te detecteren.,Włączony by wykryć jakikolwiek,habilitado para poder detectar algum,,, \n, \n +Invalid controller specified for menu,JOYMNU_INVALID,,,,Vybrán nesprávný ovladač pro nabídky,Ungültiger Controller für Menü ausgewählt,,Malprava ludregilo specifigis por menuo,Mando inválido especificado para el menú,,Epäkelpo ohjain määritetty valikolle,Contrôleur invalide spécifé dans le menu.,,Controller invalido specificato per il menu,メニューではコントローラーを使用しない,메뉴에 특정된 컨트롤러가 아닙니다.,Ongeldige regelaar gespecificeerd voor het menu,Niewłaściwy kontroler określony dla menu,Controle inválido especificado para o menu,Comando inválido,,Недопустимый контроллер выбран для меню,Невалидан контролер специфиран за мени +Overall sensitivity,JOYMNU_OVRSENS,,,,Celková citlivost,Allgemeine Empfindlichkeit,,Tutsentemeco,Sensibilidad general,,Yleisherkkyys,Sensibilité générale,,Sensibilità generale,全体的な感度,전체 민감도,Algemene gevoeligheid,Ogólna Czułość,Sensibilidade geral,,,Общая чувствительность,Уупна сензитивност +Axis Configuration,JOYMNU_AXIS,,,,Nastavení os,Achsenkonfiguration,,Akso-agordoj,Configuración del eje,,Akseleiden säätäminen,Configuration des axes,,Configurazione assi,軸構成,축 구성,Asconfiguratie,Konfiguruj Oś,Configuração de Eixo,,,Конфигурация осей,Конфигурација осе +Invert,JOYMNU_INVERT,,,,Obrátit,Invertieren,,Inversigi,Invertir,,Käännä,Inverser,,Inverti,反転,순서 바꿈,Omkeren,Odwróć,Inverter,,,Инвертировать,Инвертовано +Dead zone,JOYMNU_DEADZONE,,,,Mrtvá zóna,Totzone,,Mortzono,Zona muerta,,Kuollut alue,Zone neutre,,Zona cieca,デッドゾーン,불감대,Dode zone,Martwa strefa,Zona morta,,,Мёртвая зона,Мртва зона +No configurable axes,JOYMNU_NOAXES,,,,Žádné nastavitelné osy,Keine konfigurierbaren Achsen,,Neniu agordeblaj aksoj,No hay ejes configurables,,Ei säädettäviä akseleita,Aucun axe à configurer,,Nessun asse configurabile,軸構成を無効,설정할 방향키가 없습니다.,Geen configureerbare assen,Brak osi do skonfigurowania,Sem eixos configuráveis,,,Нет настраиваемых осей,Нема конфигурационих оса +None,OPTVAL_NONE,,,,Žádný,Kein,,Neniu,Ninguno,,Ei mitään,Aucun,,Nessuno,無し,없음,Geen,Żaden,Nenhum,,,Откл.,Ништа +Turning,OPTVAL_TURNING,,,,Otáčení,Umdrehen,,Turnanta,Girar,,Kääntyminen,Tourner,,Rotazione,旋回,회전,Draaien,Obracanie się,Girar,,,Поворот,Скретање +Looking Up/Down,OPTVAL_LOOKINGUPDOWN,,,,Dívání se nahoru/dolů,Hoch/runterblicken,,Rigardanta Supre/Malsupre,Mirar hacia Arriba/Abajo,,Ylös/Alas katsominen,Vue haut/bas,,Sguardo Sopra/Sotto,視点上下,위/아래로 보기,Omhoog/omlaag zoeken,Patrzenie w górę/w dół,Olhar para cima/baixo,,,Взгляд вверх/вниз,Гледање горе/доле +Moving Forward,OPTVAL_MOVINGFORWARD,,,,Pohyb vpřed,Vorwärtsbewegung,,Movanta Rekte,Avanzar,,Eteenpäin liikkuminen,Avancer,,Movimento in avanti,前進,앞으로 전진,Voorwaarts bewegen,Poruszanie się do przodu,Mover para a frente,,,Движение вперёд,Кретање напред +Strafing,OPTVAL_STRAFING,,,,Pohyb do stran,Seitwärtsbewegung,,Flankmovanta,Desplazarse,,Sivuttaisastunta,Pas de côté,,Movimento laterale,横移動,양옆으로 이동,Strafelen,Uniki,Deslocamento lateral,,,Движение боком,Кретање у страну +Moving Up/Down,OPTVAL_MOVINGUPDOWN,,,,Pohyb nahoru/dolů,Auf/abwärtsbewegung,,Movanta Supre/Malsupre,Moverse hacia Arriba/Abajo,,Ylös/Alas liikkuminen,Mouvement haut/bas,,Movimento Sopra/Sotto,前進後退,위/아래로 이동,Naar boven/beneden bewegen,Poruszanie się w górę/w dół,Deslocar para cima/baixo,,,Движение вверх/вниз,Кретање горе/доле +Inverted,OPTVAL_INVERTED,,,,Inverzní,Invertiert,,Inversigita,Invertido,,Käännetty,Inversé,,Invertito,反転する,반전,Omgekeerd,Odwrócony,Invertido,,,Инвертировано,Обрнуто +Not Inverted,OPTVAL_NOTINVERTED,,,,Nikoliv inverzní,nicht invertiert,,Ne Inversigita,No invertido,,Ei käännetty,Non Inversé,,Non invertito,反転しない,반전되지 않음,Niet omgekeerd,Nieodwrócony,Não Invertido,,,Прямо,Не обрнуто \ No newline at end of file diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 5a39cc2a3..edacd3152 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -920,7 +920,7 @@ OptionString "Cursors" "-", "$OPTSTR_SYSTEMCURSOR" } -OptionMenu "MouseOptions" protected +OptionMenu "MouseOptions" //protected { Title "$MOUSEMNU_TITLE" Option "$MOUSEMNU_ENABLEMOUSE", "in_mouse", "YesNo" @@ -949,7 +949,7 @@ OptionMenu "MouseOptions" protected // //------------------------------------------------------------------------------------------- -OptionMenu "JoystickOptionsDefaults" protected +OptionMenu "JoystickOptions"//Defaults" //protected { Title "$JOYMNU_OPTIONS" Option "$JOYMNU_ENABLE", "use_joystick", "YesNo" @@ -968,7 +968,7 @@ OptionMenu "JoystickOptionsDefaults" protected // The rest will be filled in by joystick code if devices get connected or disconnected } -OptionMenu "JoystickOptions" protected +OptionMenu "JoystickOptions1" //protected { Title "$JOYMNU_OPTIONS" } @@ -989,7 +989,7 @@ OptionValue "Inversion" 1, "$OPTVAL_INVERTED" } -OptionMenu "JoystickConfigMenu" protected +OptionMenu "JoystickConfigMenu" //protected { Title "$JOYMNU_TITLE" Class "JoystickConfigMenu" From fb5d94417003fa3c628f3e5647393fa308082fe1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 Dec 2019 20:49:56 +0100 Subject: [PATCH 101/203] - made the mouse sensitivity CVARs floating point so that the menu can display them properly. - disabled the mouse movement sensitivity CVARs pending a refactoring of the code to handle them in the input backend instead of the individual input handlers. --- source/common/gamecvars.cpp | 16 ++++++++-------- source/common/inputstate.cpp | 9 +++++++-- wadsrc/static/demolition/menudef.txt | 10 +++++----- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index ed460409d..c96225a59 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -348,22 +348,22 @@ CUSTOM_CVARD(Int, in_mousedeadzone, 0, CVAR_GLOBALCONFIG|CVAR_ARCHIVE, "amount o CVARD(Bool, in_mousesmoothing, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE, "enable/disable mouse input smoothing") -CUSTOM_CVARD(Float, in_mousesensitivity, DEFAULTMOUSESENSITIVITY, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "changes the mouse sensitivity") +CUSTOM_CVARD(Float, in_mousesensitivity, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "changes the mouse sensitivity") { if (self < 0) self = 0; - else if (self > 25) self = 25; + else if (self > 6) self = 6; } -CUSTOM_CVARD(Int, in_mousescalex, 65536, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "changes the mouse sensitivity") +CUSTOM_CVARD(Float, in_mousescalex, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "changes the mouse sensitivity") { - if (self < -4*65536) self = 4 * 65536; - else if (self > 4 * 65536) self = 4 * 65536; + if (self < -4) self = 4; + else if (self > 4) self = 4; } -CUSTOM_CVARD(Int, in_mousescaley, 65536, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "changes the mouse sensitivity") +CUSTOM_CVARD(Float, in_mousescaley, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "changes the mouse sensitivity") { - if (self < -4 * 65536) self = 4 * 65536; - else if (self > 4 * 65536) self = 4 * 65536; + if (self < -4) self = 4; + else if (self > 4) self = 4; } diff --git a/source/common/inputstate.cpp b/source/common/inputstate.cpp index 4036dfc0f..94353590d 100644 --- a/source/common/inputstate.cpp +++ b/source/common/inputstate.cpp @@ -40,8 +40,13 @@ void InputState::GetMouseDelta(ControlInfo * info) last = input; } - info->mousex = int(finput.x * (4.f / 65536.f) * in_mousesensitivity * in_mousescalex); - info->mousey = int(finput.y * (4.f / 65536.f) * in_mousesensitivity * in_mousescaley); + info->mousex = int(finput.x * (16.f) * in_mousesensitivity * in_mousescalex); + info->mousey = int(finput.y * (16.f) * in_mousesensitivity * in_mousescaley); + + // todo: Use these when the mouse is used for moving instead of turning. + //info->mousex = int(finput.x * (4.f) * in_mousesensitivity * in_mouseside); + //info->mousey = int(finput.y * (4.f) * in_mousesensitivity * in_mouseforward); + } void InputState::AddEvent(const event_t *ev) diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index edacd3152..781be168d 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -930,12 +930,12 @@ OptionMenu "MouseOptions" //protected StaticText "" Slider "$MOUSEMNU_SENSITIVITY", "mouse_sensitivity", 0.5, 2.5, 0.1 Option "$MOUSEMNU_NOPRESCALE", "m_noprescale", "NoYes" - Option "$MOUSEMNU_SMOOTHMOUSE", "m_filter", "YesNo" + Option "$MOUSEMNU_SMOOTHMOUSE", "in_mousesmoothing", "YesNo" StaticText "" - Slider "$MOUSEMNU_TURNSPEED", "m_yaw", 0, 2.5, 0.1 - Slider "$MOUSEMNU_MOUSELOOKSPEED", "m_pitch", 0, 2.5, 0.1 - Slider "$MOUSEMNU_FORWBACKSPEED", "m_forward", 0, 2.5, 0.1 - Slider "$MOUSEMNU_STRAFESPEED", "m_side", 0, 2.5, 0.1 + Slider "$MOUSEMNU_TURNSPEED", "in_mousescalex", -4, 4, 0.2 + Slider "$MOUSEMNU_MOUSELOOKSPEED", "in_mousescaley", -4, 4, 0.2 + //Slider "$MOUSEMNU_FORWBACKSPEED", "in_mouseforward", 0, 2.5, 0.1 + //Slider "$MOUSEMNU_STRAFESPEED", "in_mouseside", 0, 2.5, 0.1 StaticText "" Option "$MOUSEMNU_ALWAYSMOUSELOOK", "in_mousemode", "OnOff" Option "$MOUSEMNU_INVERTMOUSE", "in_mouseflip", "OnOff" From c561255018a29380286fa68653db9872399bbf18 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 Dec 2019 20:58:43 +0100 Subject: [PATCH 102/203] - moved the application of in_mousebias and in_mousedeadzone into the backend code. This piece was repeated 6x for each call to CONTROL_GetInput, creating quite a bit of redundancy. --- source/blood/src/controls.cpp | 21 ------------ source/common/gamecvars.h | 4 +-- source/common/inputstate.cpp | 21 ++++++++++++ source/duke3d/src/player.cpp | 21 ------------ source/rr/src/player.cpp | 62 ----------------------------------- source/sw/src/game.cpp | 21 ------------ 6 files changed, 23 insertions(+), 127 deletions(-) diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 6a21564c9..508ece563 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -150,27 +150,6 @@ void ctrlGetInput(void) CONTROL_GetInput(&info); - if (in_mousedeadzone) - { - if (info.mousey > 0) - info.mousey = max(info.mousey - in_mousedeadzone, 0); - else if (info.mousey < 0) - info.mousey = min(info.mousey + in_mousedeadzone, 0); - - if (info.mousex > 0) - info.mousex = max(info.mousex - in_mousedeadzone, 0); - else if (info.mousex < 0) - info.mousex = min(info.mousex + in_mousedeadzone, 0); - } - - if (in_mousebias) - { - if (klabs(info.mousex) > klabs(info.mousey)) - info.mousey = tabledivide32_noinline(info.mousey, in_mousebias); - else - info.mousex = tabledivide32_noinline(info.mousex, in_mousebias); - } - if (gQuitRequest) gInput.keyFlags.quit = 1; diff --git a/source/common/gamecvars.h b/source/common/gamecvars.h index 1b9265c47..0a1ffcac1 100644 --- a/source/common/gamecvars.h +++ b/source/common/gamecvars.h @@ -97,8 +97,8 @@ EXTERN_CVAR(Bool, in_mouseflip) EXTERN_CVAR(Bool, in_mousemode) EXTERN_CVAR(Bool, in_mousesmoothing) EXTERN_CVAR(Float, in_mousesensitivity) -EXTERN_CVAR(Int, in_mousescalex) -EXTERN_CVAR(Int, in_mousescaley) +EXTERN_CVAR(Float, in_mousescalex) +EXTERN_CVAR(Float, in_mousescaley) extern int32_t g_MyAimMode; EXTERN_CVAR(Bool, in_mousemode) EXTERN_CVAR(String, wchoice) diff --git a/source/common/inputstate.cpp b/source/common/inputstate.cpp index 94353590d..f5a3e6ced 100644 --- a/source/common/inputstate.cpp +++ b/source/common/inputstate.cpp @@ -47,6 +47,27 @@ void InputState::GetMouseDelta(ControlInfo * info) //info->mousex = int(finput.x * (4.f) * in_mousesensitivity * in_mouseside); //info->mousey = int(finput.y * (4.f) * in_mousesensitivity * in_mouseforward); + if (in_mousedeadzone) + { + if (info->mousey > 0) + info->mousey = max(info->mousey - in_mousedeadzone, 0); + else if (info->mousey < 0) + info->mousey = min(info->mousey + in_mousedeadzone, 0); + + if (info->mousex > 0) + info->mousex = max(info->mousex - in_mousedeadzone, 0); + else if (info->mousex < 0) + info->mousex = min(info->mousex + in_mousedeadzone, 0); + } + + if (in_mousebias) + { + if (abs(info->mousex) > abs(info->mousey)) + info->mousey = tabledivide32_noinline(info->mousey, in_mousebias); + else + info->mousex = tabledivide32_noinline(info->mousex, in_mousebias); + } + } void InputState::AddEvent(const event_t *ev) diff --git a/source/duke3d/src/player.cpp b/source/duke3d/src/player.cpp index 9b354139e..5442cb8ed 100644 --- a/source/duke3d/src/player.cpp +++ b/source/duke3d/src/player.cpp @@ -2926,27 +2926,6 @@ void P_GetInput(int const playerNum) CONTROL_GetInput(&info); - if (in_mousedeadzone) - { - if (info.mousey > 0) - info.mousey = max(info.mousey - in_mousedeadzone, 0); - else if (info.mousey < 0) - info.mousey = min(info.mousey + in_mousedeadzone, 0); - - if (info.mousex > 0) - info.mousex = max(info.mousex - in_mousedeadzone, 0); - else if (info.mousex < 0) - info.mousex = min(info.mousex + in_mousedeadzone, 0); - } - - if (in_mousebias) - { - if (klabs(info.mousex) > klabs(info.mousey)) - info.mousey = tabledivide32_noinline(info.mousey, in_mousebias); - else - info.mousex = tabledivide32_noinline(info.mousex, in_mousebias); - } - // JBF: Run key behaviour is selectable int const playerRunning = G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)); int const turnAmount = playerRunning ? (NORMALTURN << 1) : NORMALTURN; diff --git a/source/rr/src/player.cpp b/source/rr/src/player.cpp index 6cd9c4fdc..a9577925d 100644 --- a/source/rr/src/player.cpp +++ b/source/rr/src/player.cpp @@ -2774,26 +2774,6 @@ void P_GetInput(int playerNum) CONTROL_GetInput(&info); - if (in_mousedeadzone) - { - if (info.mousey > 0) - info.mousey = max(info.mousey - in_mousedeadzone, 0); - else if (info.mousey < 0) - info.mousey = min(info.mousey + in_mousedeadzone, 0); - - if (info.mousex > 0) - info.mousex = max(info.mousex - in_mousedeadzone, 0); - else if (info.mousex < 0) - info.mousex = min(info.mousex + in_mousedeadzone, 0); - } - - if (in_mousebias) - { - if (klabs(info.mousex) > klabs(info.mousey)) - info.mousey = tabledivide32_noinline(info.mousey, in_mousebias); - else - info.mousex = tabledivide32_noinline(info.mousex, in_mousebias); - } // JBF: Run key behaviour is selectable @@ -3080,27 +3060,6 @@ void P_GetInputMotorcycle(int playerNum) CONTROL_GetInput(&info); - if (in_mousedeadzone) - { - if (info.mousey > 0) - info.mousey = max(info.mousey - in_mousedeadzone, 0); - else if (info.mousey < 0) - info.mousey = min(info.mousey + in_mousedeadzone, 0); - - if (info.mousex > 0) - info.mousex = max(info.mousex - in_mousedeadzone, 0); - else if (info.mousex < 0) - info.mousex = min(info.mousex + in_mousedeadzone, 0); - } - - if (in_mousebias) - { - if (klabs(info.mousex) > klabs(info.mousey)) - info.mousey = tabledivide32_noinline(info.mousey, in_mousebias); - else - info.mousex = tabledivide32_noinline(info.mousex, in_mousebias); - } - // JBF: Run key behaviour is selectable int const playerRunning = G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)); constexpr int const analogTurnAmount = (NORMALTURN << 1); @@ -3378,27 +3337,6 @@ void P_GetInputBoat(int playerNum) CONTROL_GetInput(&info); - if (in_mousedeadzone) - { - if (info.mousey > 0) - info.mousey = max(info.mousey - in_mousedeadzone, 0); - else if (info.mousey < 0) - info.mousey = min(info.mousey + in_mousedeadzone, 0); - - if (info.mousex > 0) - info.mousex = max(info.mousex - in_mousedeadzone, 0); - else if (info.mousex < 0) - info.mousex = min(info.mousex + in_mousedeadzone, 0); - } - - if (in_mousebias) - { - if (klabs(info.mousex) > klabs(info.mousey)) - info.mousey = tabledivide32_noinline(info.mousey, in_mousebias); - else - info.mousex = tabledivide32_noinline(info.mousex, in_mousebias); - } - // JBF: Run key behaviour is selectable int const playerRunning = G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)); constexpr int const analogTurnAmount = (NORMALTURN << 1); diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index e29909bb9..f9a0d98ad 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -3545,27 +3545,6 @@ void getinput(SW_PACKET *loc) ControlInfo info; CONTROL_GetInput(&info); - if (in_mousedeadzone) - { - if (info.mousey > 0) - info.mousey = max(info.mousey - in_mousedeadzone, 0); - else if (info.mousey < 0) - info.mousey = min(info.mousey + in_mousedeadzone, 0); - - if (info.mousex > 0) - info.mousex = max(info.mousex - in_mousedeadzone, 0); - else if (info.mousex < 0) - info.mousex = min(info.mousex + in_mousedeadzone, 0); - } - - if (in_mousebias) - { - if (klabs(info.mousex) > klabs(info.mousey)) - info.mousey = tabledivide32_noinline(info.mousey, in_mousebias); - else - info.mousex = tabledivide32_noinline(info.mousex, in_mousebias); - } - //info.dz = (info.dz * move_scale)>>8; //info.dyaw = (info.dyaw * turn_scale)>>8; From 72857db17bcce93f29e4d2cf7fba7e9038d6ed49 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 4 Dec 2019 00:28:28 +0100 Subject: [PATCH 103/203] - refactor of the quote storage. This was consolidated for both EDuke and RedNukem frontends, put into a class with strict access control and the length limit was lifted. The new class will eventually allow better localization control. --- source/CMakeLists.txt | 1 + source/blood/src/controls.cpp | 6 - source/common/quotemgr.h | 65 +++++++++++ source/common/quotes.cpp | 180 ++++++++++++++++++++++++++++++ source/common/savegamehelp.cpp | 3 + source/duke3d/src/cheats.cpp | 6 +- source/duke3d/src/demo.cpp | 8 +- source/duke3d/src/game.cpp | 8 +- source/duke3d/src/gamedef.cpp | 176 ++++------------------------- source/duke3d/src/gameexec.cpp | 185 +++++++++++++------------------ source/duke3d/src/global.h | 1 - source/duke3d/src/network.cpp | 2 +- source/duke3d/src/player.cpp | 10 +- source/duke3d/src/quotes.h | 4 +- source/duke3d/src/savegame.cpp | 79 +------------ source/duke3d/src/screentext.cpp | 20 +--- source/rr/src/cheats.cpp | 6 +- source/rr/src/demo.cpp | 8 +- source/rr/src/game.cpp | 8 +- source/rr/src/gamedef.cpp | 161 ++++----------------------- source/rr/src/gameexec.cpp | 2 +- source/rr/src/global.h | 1 - source/rr/src/player.cpp | 10 +- source/rr/src/quotes.h | 4 +- source/rr/src/savegame.cpp | 41 +------ source/rr/src/screentext.cpp | 19 +--- 26 files changed, 418 insertions(+), 596 deletions(-) create mode 100644 source/common/quotemgr.h create mode 100644 source/common/quotes.cpp diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 5d8a8c36f..37806cc21 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -752,6 +752,7 @@ set (PCH_SOURCES common/secrets.cpp common/compositesavegame.cpp common/savegamehelp.cpp + common/quotes.cpp common/2d/v_2ddrawer.cpp common/2d/v_draw.cpp diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 508ece563..8da67bced 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -384,12 +384,6 @@ void ctrlGetInput(void) strafe = ClipRange(strafe-(info.dx<<5), -2048, 2048); -#if 0 - if (info.dz < 0) - gInput.mlook = ClipRange((info.dz+127)>>7, -127, 127); - else - gInput.mlook = ClipRange(info.dz>>7, -127, 127); -#endif if (g_MyAimMode) gInput.q16mlook = fix16_clamp(fix16_div(fix16_from_int(info.mousey), F16(128)), F16(-127)>>2, F16(127)>>2); else diff --git a/source/common/quotemgr.h b/source/common/quotemgr.h new file mode 100644 index 000000000..3de93401e --- /dev/null +++ b/source/common/quotemgr.h @@ -0,0 +1,65 @@ +#pragma once + +#include "zstring.h" +#include "gstrings.h" +// Reimplementation of the Duke quote string buffer. +// Needed because these strings need a level of abstraction from the engine to allow localization +// and because some of the quotes are really status messages that need to be shared between the different games. +// Also a good opportunity to consolidate the data buffers from Duke and Redneck frontends. + +enum +{ + MAXQUOTES = 16384, +}; + +class Quotes +{ + FString quotes[MAXQUOTES]; + FString exquotes[MAXQUOTES]; + + void MakeStringLabel(FString "e); + +public: + + void InitializeQuote(int num, const char *text, bool fromscript = false); + void InitializeExQuote(int num, const char *text, bool fromscript = false); + + const char *GetQuote(int num) + { + return GStrings.localize(quotes[num]); + } + + const char *GetExQuote(int num) + { + return GStrings.localize(exquotes[num]); + } + + const char *GetRawQuote(int num) + { + return quotes[num]; + } + + const char *GetRawExQuote(int num) + { + return exquotes[num]; + } + + void CopyQuote(int dst, int src) + { + quotes[dst] = quotes[src]; + } + + void CopyExQuote(int dst, int src) + { + quotes[dst] = exquotes[src]; + } + + void AppendQuote(int dst, int src, int len = -1); + void AppendExQuote(int dst, int src, int len = -1); + void FormatQuote(int dst, const char* fmt, ...); + void Substitute(int num, const char* text, const char* replc); + void ReadFromSavegame(); + void WriteToSavegame(); +}; + +extern Quotes quoteMgr; diff --git a/source/common/quotes.cpp b/source/common/quotes.cpp new file mode 100644 index 000000000..4ca7057ce --- /dev/null +++ b/source/common/quotes.cpp @@ -0,0 +1,180 @@ +/* +** +** quotes.cpp +** Duke-Nukem-style quote buffer +** +**--------------------------------------------------------------------------- +** Copyright 2019 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** This is actually a VERY inefficient way to manage strings +** but needs to be preserved because the CON VM depends on it. +*/ + +#include "quotemgr.h" +#include "savegamehelp.h" +#include "sjson.h" + + +void Quotes::MakeStringLabel(FString "e) +{ +} + +void Quotes::InitializeQuote(int num, const char *text, bool fromscript) +{ + quotes[num] = num; + if (fromscript) // means this is the initial setup from the source data. + { + MakeStringLabel(quotes[num]); + } +} + +void Quotes::InitializeExQuote(int num, const char *text, bool fromscript) +{ + exquotes[num] = num; + if (fromscript) // means this is the initial setup from the source data. + { + MakeStringLabel(quotes[num]); + } +} + +void Quotes::AppendQuote(int dst, int src, int len) +{ + // This needs to apply the localization because the combined string is not localizable anymore. + if (quotes[dst][0] == '$') quotes[dst] = GStrings.localize(quotes[dst]); + if (len < 0) quotes[dst] << GStrings.localize(quotes[src]); + else quotes[dst] += FString(GStrings.localize(quotes[src]), len); +} + +void Quotes::AppendExQuote(int dst, int src, int len) +{ + // This needs to apply the localization because the combined string is not localizable anymore. + if (quotes[dst][0] == '$') quotes[dst] = GStrings.localize(quotes[dst]); + if (len < 0) quotes[dst] << GStrings.localize(exquotes[src]); + else quotes[dst] += FString(GStrings.localize(exquotes[src]), len); +} + + +void Quotes::FormatQuote(int dst, const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + quotes[dst].VFormat(fmt, ap); +} + +void Quotes::Substitute(int dst, const char* text, const char* replc) +{ + if (quotes[dst][0] == '$') quotes[dst] = GStrings.localize(quotes[dst]); + quotes[dst].Substitute(text, replc); +} + + +void Quotes::ReadFromSavegame() +{ + for (auto& q : quotes) q = ""; + for (auto& q : exquotes) q = ""; + + auto fil = ReadSavegameChunk("quotes.json"); + if (!fil.isOpen()) + { + return; + } + + auto text = fil.ReadPadded(1); + fil.Close(); + + if (text.Size() == 0) + { + return; + } + + sjson_context* ctx = sjson_create_context(0, 0, NULL); + sjson_node* root = sjson_decode(ctx, (const char*)text.Data()); + + auto qs = sjson_find_member(root, "quotes"); + auto xs = sjson_find_member(root, "exquotes"); + + sjson_node* q; + sjson_foreach(q, qs) + { + int index = (int)strtoll(q->key, nullptr, 10); + quotes[index] = q->string_; + } + sjson_foreach(q, xs) + { + int index = (int)strtoll(q->key, nullptr, 10); + exquotes[index] = q->string_; + } + sjson_destroy_context(ctx); +} + +void Quotes::WriteToSavegame() +{ + sjson_context* ctx = sjson_create_context(0, 0, NULL); + if (!ctx) + { + return; + } + sjson_node* root = sjson_mkobject(ctx); + sjson_node* qs = sjson_mkobject(ctx); + sjson_node* xs = sjson_mkobject(ctx); + + for (unsigned i = 0; i < MAXQUOTES; i++) + { + if (quotes[i].IsNotEmpty()) + { + char buff[10]; + snprintf(buff, 10, "%d", i); + sjson_append_member(ctx, qs, buff, sjson_mkstring(ctx, quotes[i])); + } + if (exquotes[i].IsNotEmpty()) + { + char buff[10]; + snprintf(buff, 10, "%d", i); + sjson_append_member(ctx, xs, buff, sjson_mkstring(ctx, exquotes[i])); + } + } + sjson_append_member(ctx, root, "quotes", qs); + sjson_append_member(ctx, root, "exquotes", xs); + + char* encoded = sjson_stringify(ctx, root, " "); + FileWriter* fil = WriteSavegameChunk("quotes.json"); + if (!fil) + { + sjson_destroy_context(ctx); + return; + } + + fil->Write(encoded, strlen(encoded)); + + sjson_free_string(ctx, encoded); + sjson_destroy_context(ctx); + return; + +} + +Quotes quoteMgr; diff --git a/source/common/savegamehelp.cpp b/source/common/savegamehelp.cpp index 7061245ff..59d7968b3 100644 --- a/source/common/savegamehelp.cpp +++ b/source/common/savegamehelp.cpp @@ -44,6 +44,7 @@ #include "statistics.h" #include "secrets.h" #include "s_music.h" +#include "quotemgr.h" static CompositeSavegameWriter savewriter; static FResourceFile *savereader; @@ -79,6 +80,7 @@ bool OpenSaveGameForRead(const char *name) ReadStatistics(); SECRET_Load(); MUS_Restore(); + quoteMgr.ReadFromSavegame(); } return savereader != nullptr; @@ -155,6 +157,7 @@ void G_WriteSaveHeader(const char *name, const char*mapname, const char *maptitl SaveStatistics(); SECRET_Save(); MUS_Save(); + quoteMgr.WriteToSavegame(); } //============================================================================= diff --git a/source/duke3d/src/cheats.cpp b/source/duke3d/src/cheats.cpp index 13feb226d..0559ed960 100644 --- a/source/duke3d/src/cheats.cpp +++ b/source/duke3d/src/cheats.cpp @@ -499,7 +499,7 @@ void G_DoCheats(void) } else { - Bstrcpy(apStrings[QUOTE_RESERVED4], "Come Get Some!"); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "Come Get Some!"); S_PlaySound(DUKE_GETWEAPON2); P_DoQuote(QUOTE_RESERVED4, pPlayer); @@ -654,7 +654,7 @@ void G_DoCheats(void) case CHEAT_TODD: if (NAM) { - Bstrcpy(apStrings[QUOTE_RESERVED4], CheatDescriptions[CHEAT_TODD]); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, CheatDescriptions[CHEAT_TODD]); P_DoQuote(QUOTE_RESERVED4, pPlayer); } else @@ -690,7 +690,7 @@ void G_DoCheats(void) if (++g_noEnemies == 3) g_noEnemies = 0; - Bsprintf(apStrings[QUOTE_RESERVED4], "Monsters: %s", s[g_noEnemies]); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "Monsters: %s", s[g_noEnemies]); P_DoQuote(QUOTE_RESERVED4, pPlayer); end_cheat(pPlayer); diff --git a/source/duke3d/src/demo.cpp b/source/duke3d/src/demo.cpp index 9ac934183..b06aa304b 100644 --- a/source/duke3d/src/demo.cpp +++ b/source/duke3d/src/demo.cpp @@ -143,7 +143,7 @@ void G_OpenDemoWrite(void) if ((g_player[myconnectindex].ps->gm&MODE_GAME) && g_player[myconnectindex].ps->dead_flag) { - Bstrcpy(apStrings[QUOTE_RESERVED4], "CANNOT START DEMO RECORDING WHEN DEAD!"); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "CANNOT START DEMO RECORDING WHEN DEAD!"); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); ud.recstat = m_recstat = 0; return; @@ -180,7 +180,7 @@ void G_OpenDemoWrite(void) delete g_demo_filePtr; g_demo_filePtr = nullptr; error_wopen_demo: - Bstrcpy(apStrings[QUOTE_RESERVED4], "FAILED STARTING DEMO RECORDING. SEE CONSOLE FOR DETAILS."); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "FAILED STARTING DEMO RECORDING. SEE CONSOLE FOR DETAILS."); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); ud.recstat = m_recstat = 0; return; @@ -190,7 +190,7 @@ error_wopen_demo: demorec_diffs = demorec_diffs_cvar; demorec_difftics = demorec_difftics_cvar; - Bsprintf(apStrings[QUOTE_RESERVED4], "DEMO %d RECORDING STARTED", demonum-1); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "DEMO %d RECORDING STARTED", demonum-1); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); ud.reccnt = 0; @@ -285,7 +285,7 @@ void G_CloseDemoWrite(void) sv_freemem(); - Bstrcpy(apStrings[QUOTE_RESERVED4], "DEMO RECORDING STOPPED"); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "DEMO RECORDING STOPPED"); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); } #if KRANDDEBUG diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index f5737af6e..a33cbc81e 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -5396,12 +5396,6 @@ static void G_Cleanup(void) G_FreeMapState(i); } - for (i=MAXQUOTES-1; i>=0; i--) - { - Xfree(apStrings[i]); - Xfree(apXStrings[i]); - } - for (i=MAXPLAYERS-1; i>=0; i--) { Xfree(g_player[i].ps); @@ -6347,7 +6341,7 @@ int G_DoMoveThings(void) { if (ldist(&sprite[pPlayer->i], &sprite[hitData.sprite]) < 9216) { - Bsprintf(apStrings[QUOTE_RESERVED3], "%s", &g_player[playerNum].user_name[0]); + quoteMgr.InitializeQuote(QUOTE_RESERVED3, "%s", &g_player[playerNum].user_name[0]); pPlayer->fta = 12, pPlayer->ftq = QUOTE_RESERVED3; } } diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index ee02f33d3..ff5a202a2 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -2166,129 +2166,31 @@ LUNATIC_EXTERN void C_DefineProjectile(int32_t j, int32_t what, int32_t val) int32_t C_AllocQuote(int32_t qnum) { Bassert((unsigned)qnum < MAXQUOTES); - - if (apStrings[qnum] == NULL) - { - apStrings[qnum] = (char *)Xcalloc(MAXQUOTELEN,sizeof(uint8_t)); - return 1; - } - - return 0; + // No longer needed, quotes are now FStrings. + return 1; } -#ifndef EDUKE32_TOUCH_DEVICES -static void C_ReplaceQuoteSubstring(const size_t q, char const * const query, char const * const replacement) -{ - size_t querylength = Bstrlen(query); - - for (bssize_t i = MAXQUOTELEN - querylength - 2; i >= 0; i--) - if (Bstrncmp(&apStrings[q][i], query, querylength) == 0) - { - Bmemset(tempbuf, 0, sizeof(tempbuf)); - Bstrncpy(tempbuf, apStrings[q], i); - Bstrcat(tempbuf, replacement); - Bstrcat(tempbuf, &apStrings[q][i + querylength]); - Bstrncpy(apStrings[q], tempbuf, MAXQUOTELEN - 1); - i = MAXQUOTELEN - querylength - 2; - } -} -#endif - void C_InitQuotes(void) { - for (int i = 0; i < 128; i++) C_AllocQuote(i); - -#ifdef EDUKE32_TOUCH_DEVICES - apStrings[QUOTE_DEAD] = 0; -#else auto openkeys = Bindings.GetKeysForCommand("+open"); if (openkeys.Size()) { auto OpenGameFunc = C_NameKeys(openkeys.Data(), 1); - C_ReplaceQuoteSubstring(QUOTE_DEAD, "SPACE", OpenGameFunc); - C_ReplaceQuoteSubstring(QUOTE_DEAD, "OPEN", OpenGameFunc); - C_ReplaceQuoteSubstring(QUOTE_DEAD, "USE", OpenGameFunc); + quoteMgr.Substitute(QUOTE_DEAD, "SPACE", OpenGameFunc); + quoteMgr.Substitute(QUOTE_DEAD, "OPEN", OpenGameFunc); + quoteMgr.Substitute(QUOTE_DEAD, "USE", OpenGameFunc); } -#endif - // most of these are based on Blood, obviously - const char *PlayerObituaries[] = - { - "^02%s^02 beat %s^02 like a cur", - "^02%s^02 broke %s", - "^02%s^02 body bagged %s", - "^02%s^02 boned %s^02 like a fish", - "^02%s^02 castrated %s", - "^02%s^02 creamed %s", - "^02%s^02 crushed %s", - "^02%s^02 destroyed %s", - "^02%s^02 diced %s", - "^02%s^02 disemboweled %s", - "^02%s^02 erased %s", - "^02%s^02 eviscerated %s", - "^02%s^02 flailed %s", - "^02%s^02 flattened %s", - "^02%s^02 gave AnAl MaDnEsS to %s", - "^02%s^02 gave %s^02 Anal Justice", - "^02%s^02 hosed %s", - "^02%s^02 hurt %s^02 real bad", - "^02%s^02 killed %s", - "^02%s^02 made dog meat out of %s", - "^02%s^02 made mincemeat out of %s", - "^02%s^02 manhandled %s", - "^02%s^02 massacred %s", - "^02%s^02 mutilated %s", - "^02%s^02 murdered %s", - "^02%s^02 neutered %s", - "^02%s^02 punted %s", - "^02%s^02 reamed %s", - "^02%s^02 ripped %s^02 a new orifice", - "^02%s^02 rocked %s", - "^02%s^02 sent %s^02 to hell", - "^02%s^02 shredded %s", - "^02%s^02 slashed %s", - "^02%s^02 slaughtered %s", - "^02%s^02 sliced %s", - "^02%s^02 smacked %s around", - "^02%s^02 smashed %s", - "^02%s^02 snuffed %s", - "^02%s^02 sodomized %s", - "^02%s^02 splattered %s", - "^02%s^02 sprayed %s", - "^02%s^02 squashed %s", - "^02%s^02 throttled %s", - "^02%s^02 toasted %s", - "^02%s^02 vented %s", - "^02%s^02 ventilated %s", - "^02%s^02 wasted %s", - "^02%s^02 wrecked %s", - }; - - const char *PlayerSelfObituaries[] = - { - "^02%s^02 is excrement", - "^02%s^02 is hamburger", - "^02%s^02 suffered scrotum separation", - "^02%s^02 volunteered for population control", - "^02%s^02 has suicided", - "^02%s^02 bled out", - }; - - EDUKE32_STATIC_ASSERT(OBITQUOTEINDEX + ARRAY_SIZE(PlayerObituaries)-1 < MAXQUOTES); - EDUKE32_STATIC_ASSERT(SUICIDEQUOTEINDEX + ARRAY_SIZE(PlayerSelfObituaries)-1 < MAXQUOTES); - - g_numObituaries = ARRAY_SIZE(PlayerObituaries); + g_numObituaries = 48; for (bssize_t i = g_numObituaries - 1; i >= 0; i--) { - if (C_AllocQuote(i + OBITQUOTEINDEX)) - Bstrcpy(apStrings[i + OBITQUOTEINDEX], PlayerObituaries[i]); + quoteMgr.FormatQuote(i + OBITQUOTEINDEX, "$TXT_OBITUARY%d", i + 1); } - g_numSelfObituaries = ARRAY_SIZE(PlayerSelfObituaries); + g_numSelfObituaries = 6; for (bssize_t i = g_numSelfObituaries - 1; i >= 0; i--) { - if (C_AllocQuote(i + SUICIDEQUOTEINDEX)) - Bstrcpy(apStrings[i + SUICIDEQUOTEINDEX], PlayerSelfObituaries[i]); + quoteMgr.FormatQuote(i + SUICIDEQUOTEINDEX, "$TXT_SELFOBIT%d", i + 1); } } @@ -3167,7 +3069,7 @@ DO_DEFSTATE: case CON_QUOTE: C_GetNextValue(LABEL_DEFINE); - if (EDUKE32_PREDICT_FALSE(((unsigned)g_scriptPtr[-1] >= MAXQUOTES) || apStrings[g_scriptPtr[-1]] == NULL)) + if (EDUKE32_PREDICT_FALSE(((unsigned)g_scriptPtr[-1] >= MAXQUOTES))) { g_errorCnt++; C_ReportError(-1); @@ -5329,6 +5231,7 @@ repeatcase: case CON_DEFINEQUOTE: case CON_REDEFINEQUOTE: + { if (tw == CON_DEFINEQUOTE) { g_scriptPtr--; @@ -5353,53 +5256,27 @@ repeatcase: if (tw == CON_DEFINEQUOTE) g_scriptPtr--; - i = 0; - scriptSkipSpaces(); - if (tw == CON_REDEFINEQUOTE) - { - if (apXStrings[g_numXStrings] == NULL) - apXStrings[g_numXStrings] = (char *)Xcalloc(MAXQUOTELEN,sizeof(uint8_t)); - } - + TArray buffer; while (*textptr != 0x0a && *textptr != 0x0d && *textptr != 0) { - /* - if (*textptr == '%' && *(textptr+1) == 's') - { - initprintf("%s:%d: error: quote text contains string identifier.\n",g_szScriptFileName,g_lineNumber); - g_numCompilerErrors++; - while (*textptr != 0x0a && *textptr != 0x0d && *textptr != 0) textptr++; - break; - } - */ - if (tw == CON_DEFINEQUOTE) - *(apStrings[k]+i) = *textptr; - else - *(apXStrings[g_numXStrings]+i) = *textptr; - textptr++,i++; - if (EDUKE32_PREDICT_FALSE(i >= MAXQUOTELEN-1)) - { - initprintf("%s:%d: warning: truncating quote text to %d characters.\n",g_scriptFileName,g_lineNumber,MAXQUOTELEN-1); - g_warningCnt++; - scriptSkipLine(); - break; - } + buffer.Push(*textptr); + textptr++; } + buffer.Push(0); + if (tw == CON_DEFINEQUOTE) + quoteMgr.InitializeQuote(k, buffer.Data(), true); + else + quoteMgr.InitializeExQuote(k, buffer.Data(), true); - if (tw == CON_DEFINEQUOTE) + + if (tw != CON_DEFINEQUOTE) { - if ((unsigned)k < MAXQUOTES) - *(apStrings[k]+i) = '\0'; - } - else - { - *(apXStrings[g_numXStrings]+i) = '\0'; scriptWriteValue(g_numXStrings++); } continue; - + } case CON_DEFINECHEATDESCRIPTION: g_scriptPtr--; @@ -5981,14 +5858,7 @@ void C_PrintStats(void) MAXSPRITES * sizeof(spritetype)/(1<<6)), g_gameVarCount, MAXGAMEVARS, g_gameArrayCount, MAXGAMEARRAYS); - int cnt = g_numXStrings; - - for (auto &ptr : apStrings) - if (ptr) - cnt++; - - if (cnt) initprintf("%d strings, ", cnt); - cnt = 0; + int cnt = 0; for (auto & apScriptEvent : apScriptEvents) if (apScriptEvent) diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index 61ae6e792..c457b4223 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -39,6 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "version.h" #include "menu/menu.h" #include "c_dispatch.h" +#include "quotemgr.h" #include "debugbreak.h" extern bool rotatesprite_2doverride; @@ -2772,7 +2773,7 @@ badindex: int const strIndex = *insptr++; int const XstrIndex = *insptr++; - Bstrcpy(apStrings[strIndex], apXStrings[XstrIndex]); + quoteMgr.CopyExQuote(strIndex, XstrIndex); dispatch(); } @@ -3547,9 +3548,9 @@ badindex: int const gameVar = *insptr++; int const quoteNum = Gv_GetVar(*insptr++); - VM_ASSERT((unsigned)quoteNum < MAXQUOTES && apStrings[quoteNum], "invalid quote %d\n", quoteNum); + VM_ASSERT((unsigned)quoteNum < MAXQUOTES, "invalid quote %d\n", quoteNum); - Gv_SetVar(gameVar, Bstrlen(apStrings[quoteNum])); + Gv_SetVar(gameVar, strlen(quoteMgr.GetQuote(quoteNum))); dispatch(); } @@ -3572,11 +3573,11 @@ badindex: if (EDUKE32_PREDICT_FALSE(v.tileNum < 0 || v.tileNum + 127 >= MAXTILES)) CON_ERRPRINTF("invalid base tilenum %d\n", v.tileNum); - else if (EDUKE32_PREDICT_FALSE((unsigned)v.quoteNum >= MAXQUOTES || apStrings[v.quoteNum] == NULL)) + else if ((unsigned)v.quoteNum >= MAXQUOTES) CON_ERRPRINTF("invalid quote %d\n", v.quoteNum); else { - vec2_t dim = G_ScreenTextSize(v.tileNum, v.vect.x, v.vect.y, v.vect.z, v.blockAngle, apStrings[v.quoteNum], 2 | v.orientation, + vec2_t dim = G_ScreenTextSize(v.tileNum, v.vect.x, v.vect.y, v.vect.z, v.blockAngle, quoteMgr.GetQuote(v.quoteNum), 2 | v.orientation, v.offset.x, v.offset.y, v.between.x, v.between.y, v.f, v.bound[0].x, v.bound[0].y, v.bound[1].x, v.bound[1].y); @@ -3668,12 +3669,12 @@ badindex: int const quoteIndex = Gv_GetVar(*insptr++); int const gameFunc = Gv_GetVar(*insptr++); int funcPos = Gv_GetVar(*insptr++); - VM_ASSERT((unsigned)quoteIndex < MAXQUOTES && apStrings[quoteIndex], "invalid quote %d\n", quoteIndex); + VM_ASSERT((unsigned)quoteIndex < MAXQUOTES, "invalid quote %d\n", quoteIndex); VM_ASSERT((unsigned)gameFunc < NUMGAMEFUNCTIONS, "invalid function %d\n", gameFunc); auto bindings = Bindings.GetKeysForCommand(C_CON_GetButtonFunc(gameFunc)); if ((unsigned)funcPos >= bindings.Size()) funcPos = 0; - Bstrcpy(apStrings[quoteIndex], KB_ScanCodeToString(bindings[funcPos])); + quoteMgr.InitializeQuote(quoteIndex, KB_ScanCodeToString(bindings[funcPos])); dispatch(); } @@ -3683,14 +3684,11 @@ badindex: int const quoteIndex = Gv_GetVar(*insptr++); int const gameFunc = Gv_GetVar(*insptr++); - VM_ASSERT((unsigned)quoteIndex < MAXQUOTES && apStrings[quoteIndex], "invalid quote %d\n", quoteIndex); + VM_ASSERT((unsigned)quoteIndex < MAXQUOTES, "invalid quote %d\n", quoteIndex); VM_ASSERT((unsigned)gameFunc < NUMGAMEFUNCTIONS, "invalid function %d\n", gameFunc); - static char const s_KeyboardFormat[] = "[%s]"; - static char const s_JoystickFormat[] = "(%s)"; - auto binding = C_CON_GetBoundKeyForLastInput(gameFunc); - if (binding.Len()) snprintf(apStrings[quoteIndex], MAXQUOTELEN, "(%s)", binding.GetChars()); + if (binding.Len()) quoteMgr.FormatQuote(quoteIndex, "(%s)", binding.GetChars()); dispatch(); } @@ -3703,17 +3701,11 @@ badindex: } v; Gv_FillWithVars(v); - if (EDUKE32_PREDICT_FALSE((unsigned)v.outputQuote >= MAXQUOTES || apStrings[v.outputQuote] == NULL + if (EDUKE32_PREDICT_FALSE((unsigned)v.outputQuote >= MAXQUOTES || (unsigned)v.inputQuote >= MAXQUOTES - || apStrings[v.inputQuote] == NULL)) + )) { - CON_ERRPRINTF("invalid quote %d\n", apStrings[v.outputQuote] ? v.inputQuote : v.outputQuote); - abort_after_error(); - } - - if (EDUKE32_PREDICT_FALSE((unsigned)v.quotePos >= MAXQUOTELEN)) - { - CON_ERRPRINTF("invalid position %d\n", v.quotePos); + CON_ERRPRINTF("invalid quote %d\n", v.inputQuote >= MAXQUOTES ? v.inputQuote : v.outputQuote); abort_after_error(); } @@ -3723,18 +3715,18 @@ badindex: abort_after_error(); } - char * pOutput = apStrings[v.outputQuote]; - char const *pInput = apStrings[v.inputQuote]; + TArray output; + char const *pInput = quoteMgr.GetQuote(v.inputQuote); while (*pInput && v.quotePos--) pInput++; - while ((*pOutput = *pInput) && v.quoteLength--) + while ((*pInput) && v.quoteLength--) { - pOutput++; + output.Push(*pInput); pInput++; } - *pOutput = '\0'; - + output.Push(0); + quoteMgr.InitializeQuote(v.outputQuote, output.Data()); dispatch(); } @@ -3745,13 +3737,7 @@ badindex: int const quote2 = Gv_GetVar(*insptr++); int const gameVar = *insptr++; - if (EDUKE32_PREDICT_FALSE(apStrings[quote1] == NULL || apStrings[quote2] == NULL)) - { - CON_ERRPRINTF("null quote %d\n", apStrings[quote1] ? quote2 : quote1); - abort_after_error(); - } - - Gv_SetVar(gameVar, strcmp(apStrings[quote1], apStrings[quote2])); + Gv_SetVar(gameVar, strcmp(quoteMgr.GetQuote(quote1), quoteMgr.GetQuote(quote2))); dispatch(); } @@ -3775,14 +3761,14 @@ badindex: switch (VM_DECODE_INST(tw)) { case CON_GETPNAME: - VM_ASSERT((unsigned)q < MAXQUOTES && apStrings[q], "invalid quote %d\n", q); - if (g_player[j].user_name[0]) - Bstrcpy(apStrings[q], g_player[j].user_name); - else - Bsprintf(apStrings[q], "%d", j); + VM_ASSERT((unsigned)q < MAXQUOTES, "invalid quote %d\n", q); + if (g_player[j].user_name[0]) + quoteMgr.InitializeQuote(q, g_player[j].user_name); + else + quoteMgr.FormatQuote(q, "%d", j); break; case CON_QGETSYSSTR: - VM_ASSERT((unsigned)q < MAXQUOTES && apStrings[q], "invalid quote %d\n", q); + VM_ASSERT((unsigned)q < MAXQUOTES, "invalid quote %d\n", q); switch (j) { case STR_MAPNAME: @@ -3790,7 +3776,7 @@ badindex: { if (G_HaveUserMap()) { - snprintf(apStrings[q], MAXQUOTELEN, "%s", boardfilename); + quoteMgr.FormatQuote(q, "%s", boardfilename); break; } @@ -3812,22 +3798,22 @@ badindex: abort_after_error(); } - Bstrcpy(apStrings[q], j == STR_MAPNAME ? g_mapInfo[levelNum].name : g_mapInfo[levelNum].filename); + quoteMgr.InitializeQuote(q, j == STR_MAPNAME ? g_mapInfo[levelNum].name : g_mapInfo[levelNum].filename); break; } case STR_PLAYERNAME: VM_ASSERT((unsigned)vm.playerNum < (unsigned)g_mostConcurrentPlayers, "invalid player %d\n", vm.playerNum); - Bstrcpy(apStrings[q], g_player[vm.playerNum].user_name); + quoteMgr.InitializeQuote(q, g_player[vm.playerNum].user_name); break; case STR_VERSION: Bsprintf(tempbuf, HEAD2 " %s", GetGitDescription()); - Bstrcpy(apStrings[q], tempbuf); + quoteMgr.InitializeQuote(q, tempbuf); break; - case STR_GAMETYPE: Bstrcpy(apStrings[q], g_gametypeNames[ud.coop]); break; + case STR_GAMETYPE: quoteMgr.InitializeQuote(q, g_gametypeNames[ud.coop]); break; case STR_VOLUMENAME: if (G_HaveUserMap()) { - apStrings[q][0] = '\0'; + quoteMgr.InitializeQuote(q, ""); break; } @@ -3837,36 +3823,28 @@ badindex: abort_after_error(); } // length is no longer limited so a check is needed. - Bstrncpy(apStrings[q], gVolumeNames[ud.volume_number], MAXQUOTELEN); - apStrings[q][MAXQUOTELEN-1] = 0; + quoteMgr.InitializeQuote(q, gVolumeNames[ud.volume_number]); break; - case STR_YOURTIME: Bstrcpy(apStrings[q], G_PrintYourTime()); break; - case STR_PARTIME: Bstrcpy(apStrings[q], G_PrintParTime()); break; - case STR_DESIGNERTIME: Bstrcpy(apStrings[q], G_PrintDesignerTime()); break; - case STR_BESTTIME: Bstrcpy(apStrings[q], G_PrintBestTime()); break; - case STR_USERMAPFILENAME: snprintf(apStrings[q], MAXQUOTELEN, "%s", boardfilename); break; + case STR_YOURTIME: quoteMgr.InitializeQuote(q, G_PrintYourTime()); break; + case STR_PARTIME: quoteMgr.InitializeQuote(q, G_PrintParTime()); break; + case STR_DESIGNERTIME: quoteMgr.InitializeQuote(q, G_PrintDesignerTime()); break; + case STR_BESTTIME: quoteMgr.InitializeQuote(q, G_PrintBestTime()); break; + case STR_USERMAPFILENAME: quoteMgr.FormatQuote(q, "%s", boardfilename); break; default: CON_ERRPRINTF("invalid string index %d or %d\n", q, j); abort_after_error(); } break; case CON_QSTRCAT: - if (EDUKE32_PREDICT_FALSE(apStrings[q] == NULL || apStrings[j] == NULL)) - goto nullquote; - Bstrncat(apStrings[q], apStrings[j], (MAXQUOTELEN - 1) - Bstrlen(apStrings[q])); + quoteMgr.AppendQuote(q, j); break; case CON_QSTRNCAT: - if (EDUKE32_PREDICT_FALSE(apStrings[q] == NULL || apStrings[j] == NULL)) - goto nullquote; - Bstrncat(apStrings[q], apStrings[j], Gv_GetVar(*insptr++)); + quoteMgr.AppendQuote(q, j, Gv_GetVar(*insptr++)); break; case CON_QSTRCPY: - if (EDUKE32_PREDICT_FALSE(apStrings[q] == NULL || apStrings[j] == NULL)) - goto nullquote; - if (q != j) - Bstrcpy(apStrings[q], apStrings[j]); + if (q != j) + quoteMgr.CopyQuote(q, j); break; default: - nullquote: - CON_ERRPRINTF("invalid quote %d\n", apStrings[q] ? j : q); + CON_ERRPRINTF("invalid quote %d\n", q < MAXQUOTES? j : q); abort_after_error(); } dispatch(); @@ -4188,18 +4166,18 @@ badindex: { int const nQuote = Gv_GetVar(*insptr++); - VM_ASSERT((unsigned)nQuote < MAXQUOTES && apStrings[nQuote], "invalid quote %d\n", nQuote); + VM_ASSERT((unsigned)nQuote < MAXQUOTES, "invalid quote %d\n", nQuote); if (VM_DECODE_INST(tw) == CON_IFCUTSCENE) { insptr--; - VM_CONDITIONAL(g_animPtr == Anim_Find(apStrings[nQuote])); + VM_CONDITIONAL(g_animPtr == Anim_Find(quoteMgr.GetQuote(nQuote))); dispatch(); } tw = vm.pPlayer->palette; I_ClearAllInput(); - Anim_Play(apStrings[nQuote]); + Anim_Play(quoteMgr.GetQuote(nQuote)); P_SetGamePalette(vm.pPlayer, tw, 2 + 16); dispatch(); } @@ -4342,9 +4320,9 @@ badindex: abort_after_error(); } - VM_ASSERT((unsigned)v.nQuote < MAXQUOTES && apStrings[v.nQuote], "invalid quote %d\n", v.nQuote); + VM_ASSERT((unsigned)v.nQuote < MAXQUOTES, "invalid quote %d\n", v.nQuote); - G_PrintGameText(v.tilenum, v.pos.x >> 1, v.pos.y, apStrings[v.nQuote], v.shade, v.pal, v.orientation & (ROTATESPRITE_MAX - 1), + G_PrintGameText(v.tilenum, v.pos.x >> 1, v.pos.y, quoteMgr.GetQuote(v.nQuote), v.shade, v.pal, v.orientation & (ROTATESPRITE_MAX - 1), v.bound[0].x, v.bound[0].y, v.bound[1].x, v.bound[1].y, z, 0); dispatch(); } @@ -4386,9 +4364,9 @@ badindex: } v; Gv_FillWithVars(v); - VM_ASSERT((unsigned)v.nQuote < MAXQUOTES && apStrings[v.nQuote], "invalid quote %d\n", v.nQuote); + VM_ASSERT((unsigned)v.nQuote < MAXQUOTES, "invalid quote %d\n", v.nQuote); - minitextshade(v.pos.x, v.pos.y, apStrings[v.nQuote], v.shade, v.pal, 2 + 8 + 16); + minitextshade(v.pos.x, v.pos.y, quoteMgr.GetQuote(v.nQuote), v.shade, v.pal, 2 + 8 + 16); dispatch(); } @@ -4412,9 +4390,9 @@ badindex: abort_after_error(); } - VM_ASSERT((unsigned)v.nQuote < MAXQUOTES && apStrings[v.nQuote], "invalid quote %d\n", v.nQuote); + VM_ASSERT((unsigned)v.nQuote < MAXQUOTES, "invalid quote %d\n", v.nQuote); - G_ScreenText(v.tilenum, v.v.x, v.v.y, v.v.z, v.blockangle, v.charangle, apStrings[v.nQuote], v.shade, v.pal, + G_ScreenText(v.tilenum, v.v.x, v.v.y, v.v.z, v.blockangle, v.charangle, quoteMgr.GetQuote(v.nQuote), v.shade, v.pal, 2 | (v.orientation & (ROTATESPRITE_MAX - 1)), v.alpha, v.spacing.x, v.spacing.y, v.between.x, v.between.y, v.nFlags, v.bound[0].x, v.bound[0].y, v.bound[1].x, v.bound[1].y); dispatch(); @@ -4814,9 +4792,9 @@ badindex: insptr++; int const nQuote = Gv_GetVar(*insptr++); - VM_ASSERT((unsigned)nQuote < MAXQUOTES && apStrings[nQuote], "invalid quote %d\n", nQuote); + VM_ASSERT((unsigned)nQuote < MAXQUOTES, "invalid quote %d\n", nQuote); - //communityapiUnlockAchievement(apStrings[nQuote]); + //communityapiUnlockAchievement(quoteMgr.GetQuote(v.nQuote)); dispatch(); } @@ -4826,9 +4804,9 @@ badindex: int const nQuote = Gv_GetVar(*insptr++); int const value = Gv_GetVar(*insptr++); - VM_ASSERT((unsigned)nQuote < MAXQUOTES && apStrings[nQuote], "invalid quote %d\n", nQuote); + VM_ASSERT((unsigned)nQuote < MAXQUOTES, "invalid quote %d\n", nQuote); - //communityapiSetStat(apStrings[nQuote], value); + //communityapiSetStat(quoteMgr.GetQuote(nQuote), value); dispatch(); } @@ -5103,16 +5081,10 @@ badindex: int const outputQuote = Gv_GetVar(*insptr++); int const inputQuote = Gv_GetVar(*insptr++); - if (EDUKE32_PREDICT_FALSE(apStrings[inputQuote] == NULL || apStrings[outputQuote] == NULL)) - { - CON_ERRPRINTF("null quote %d\n", apStrings[inputQuote] ? outputQuote : inputQuote); - abort_after_error(); - } - - auto &inBuf = apStrings[inputQuote]; + auto inBuf = quoteMgr.GetQuote(inputQuote); int32_t arg[32]; - char outBuf[MAXQUOTELEN]; + TArray outBuf; int const quoteLen = Bstrlen(inBuf); @@ -5131,8 +5103,8 @@ badindex: do { - while (inputPos < quoteLen && outputPos < MAXQUOTELEN && inBuf[inputPos] != '%') - outBuf[outputPos++] = inBuf[inputPos++]; + while (inputPos < quoteLen && inBuf[inputPos] != '%') + outBuf.Push(inBuf[inputPos++]); if (inBuf[inputPos] == '%') { @@ -5143,8 +5115,8 @@ badindex: if (inBuf[inputPos + 1] != 'd') { // write the % and l - outBuf[outputPos++] = inBuf[inputPos - 1]; - outBuf[outputPos++] = inBuf[inputPos++]; + outBuf.Push(inBuf[inputPos - 1]); + outBuf.Push(inBuf[inputPos++]); break; } inputPos++; @@ -5158,7 +5130,8 @@ badindex: Bsprintf(buf, "%d", arg[argIdx++]); int const bufLen = Bstrlen(buf); - Bmemcpy(&outBuf[outputPos], buf, bufLen); + outputPos = outBuf.Reserve(bufLen); + memcpy(&outBuf[outputPos], buf, bufLen); outputPos += bufLen; inputPos++; } @@ -5169,22 +5142,24 @@ badindex: if (argIdx >= numArgs) goto finish_qsprintf; - int const argLen = Bstrlen(apStrings[arg[argIdx]]); + auto quoteArg = quoteMgr.GetQuote(arg[argIdx]); + int const argLen = (int)strlen(quoteArg); - Bmemcpy(&outBuf[outputPos], apStrings[arg[argIdx]], argLen); + outputPos = outBuf.Reserve(argLen); + memcpy(&outBuf[outputPos], quoteArg, argLen); outputPos += argLen; argIdx++; inputPos++; } break; - default: outBuf[outputPos++] = inBuf[inputPos - 1]; break; + default: outBuf.Push(inBuf[inputPos - 1]); break; } } - } while (inputPos < quoteLen && outputPos < MAXQUOTELEN); + } while (inputPos < quoteLen); finish_qsprintf: - outBuf[outputPos] = '\0'; - Bstrncpyz(apStrings[outputQuote], outBuf, MAXQUOTELEN); + outBuf.Push(0); + quoteMgr.InitializeQuote(outputQuote, outBuf.Data()); dispatch(); } @@ -5600,9 +5575,9 @@ badindex: int const arrayNum = *insptr++; int const quoteFilename = *insptr++; - VM_ASSERT((unsigned)quoteFilename < MAXQUOTES && apStrings[quoteFilename], "invalid quote %d\n", quoteFilename); + VM_ASSERT((unsigned)quoteFilename < MAXQUOTES, "invalid quote %d\n", quoteFilename); FStringf IniSection("%s.UserStrings", LumpFilter.GetChars()); - auto IniKey = apStrings[quoteFilename]; + auto IniKey = quoteMgr.GetQuote(quoteFilename); if (!GameConfig->SetSection(IniSection)) { dispatch(); @@ -5676,12 +5651,12 @@ badindex: int const arrayNum = *insptr++; int const quoteFilename = *insptr++; - VM_ASSERT((unsigned)quoteFilename < MAXQUOTES && apStrings[quoteFilename], "invalid quote %d\n", quoteFilename); + VM_ASSERT((unsigned)quoteFilename < MAXQUOTES, "invalid quote %d\n", quoteFilename); // No, we are not writing stuff to an arbitrary file on the hard drive! This is a first grade exploit for doing serious damage. // Instead, encode the data as BASE64 and write it to the config file, // which doesn't create a wide open door for exploits. FStringf IniSection("%s.UserStrings", LumpFilter.GetChars()); - auto IniKey = apStrings[quoteFilename]; + auto IniKey = quoteMgr.GetQuote(quoteFilename); BufferWriter bw; switch (aGameArrays[arrayNum].flags & GAMEARRAY_SIZE_MASK) @@ -6198,18 +6173,18 @@ badindex: insptr++; tw = Gv_GetVar(*insptr++); - VM_ASSERT((unsigned)tw < MAXQUOTES && apStrings[tw], "invalid quote %d\n", (int)tw); + VM_ASSERT((unsigned)tw < MAXQUOTES, "invalid quote %d\n", (int)tw); - G_AddUserQuote(apStrings[tw]); + G_AddUserQuote(quoteMgr.GetQuote(tw)); dispatch(); vInstruction(CON_ECHO): insptr++; tw = Gv_GetVar(*insptr++); - VM_ASSERT((unsigned)tw < MAXQUOTES && apStrings[tw], "invalid quote %d\n", (int)tw); + VM_ASSERT((unsigned)tw < MAXQUOTES, "invalid quote %d\n", (int)tw); - OSD_Printf("%s\n", apStrings[tw]); + OSD_Printf("%s\n", quoteMgr.GetQuote(tw)); dispatch(); vInstruction(CON_RESPAWNHITAG): diff --git a/source/duke3d/src/global.h b/source/duke3d/src/global.h index 9acb60b9f..23657c87b 100644 --- a/source/duke3d/src/global.h +++ b/source/duke3d/src/global.h @@ -67,7 +67,6 @@ G_EXTERN actor_t actor[MAXSPRITES]; // g_tile: tile-specific data THAT DOES NOT CHANGE during the course of a game G_EXTERN tiledata_t g_tile[MAXTILES]; G_EXTERN animwalltype animwall[MAXANIMWALLS]; -G_EXTERN char *apStrings[MAXQUOTES],*apXStrings[MAXQUOTES]; G_EXTERN char *label; G_EXTERN int32_t g_musicIndex; G_EXTERN char g_loadFromGroupOnly; diff --git a/source/duke3d/src/network.cpp b/source/duke3d/src/network.cpp index f0864e9c1..597dc95ba 100644 --- a/source/duke3d/src/network.cpp +++ b/source/duke3d/src/network.cpp @@ -1517,7 +1517,7 @@ static void P_RemovePlayer(int32_t p) voting = -1; } - Bstrcpy(apStrings[QUOTE_RESERVED2],recbuf); + quoteMgr.InitializeQuote(QUOTE_RESERVED2 ,recbuf); g_player[myconnectindex].ps->ftq = QUOTE_RESERVED2; g_player[myconnectindex].ps->fta = 180; } diff --git a/source/duke3d/src/player.cpp b/source/duke3d/src/player.cpp index 5442cb8ed..2771ef572 100644 --- a/source/duke3d/src/player.cpp +++ b/source/duke3d/src/player.cpp @@ -3768,18 +3768,18 @@ void P_FragPlayer(int playerNum) if (playerNum == screenpeek) { - Bsprintf(apStrings[QUOTE_RESERVED], "Killed by %s", &g_player[pPlayer->frag_ps].user_name[0]); + quoteMgr.FormatQuote(QUOTE_RESERVED, "Killed by %s", &g_player[pPlayer->frag_ps].user_name[0]); P_DoQuote(QUOTE_RESERVED, pPlayer); } else { - Bsprintf(apStrings[QUOTE_RESERVED2], "Killed %s", &g_player[playerNum].user_name[0]); + quoteMgr.FormatQuote(QUOTE_RESERVED2, "Killed %s", &g_player[playerNum].user_name[0]); P_DoQuote(QUOTE_RESERVED2, g_player[pPlayer->frag_ps].ps); } if (cl_obituaries) { - Bsprintf(tempbuf, apStrings[OBITQUOTEINDEX + (krand() % g_numObituaries)], + Bsprintf(tempbuf, quoteMgr.GetQuote(OBITQUOTEINDEX + (krand() % g_numObituaries)), &g_player[pPlayer->frag_ps].user_name[0], &g_player[playerNum].user_name[0]); G_AddUserQuote(tempbuf); } @@ -3792,14 +3792,14 @@ void P_FragPlayer(int playerNum) { pPlayer->fraggedself++; if ((unsigned)pPlayer->wackedbyactor < MAXTILES && A_CheckEnemyTile(sprite[pPlayer->wackedbyactor].picnum)) - Bsprintf(tempbuf, apStrings[OBITQUOTEINDEX + (krand() % g_numObituaries)], "A monster", + Bsprintf(tempbuf, quoteMgr.GetQuote(OBITQUOTEINDEX + (krand() % g_numObituaries)), "A monster", &g_player[playerNum].user_name[0]); else if (actor[pPlayer->i].picnum == NUKEBUTTON) Bsprintf(tempbuf, "^02%s^02 tried to leave", &g_player[playerNum].user_name[0]); else { // random suicide death string - Bsprintf(tempbuf, apStrings[SUICIDEQUOTEINDEX + (krand() % g_numSelfObituaries)], + Bsprintf(tempbuf, quoteMgr.GetQuote(SUICIDEQUOTEINDEX + (krand() % g_numSelfObituaries)), &g_player[playerNum].user_name[0]); } } diff --git a/source/duke3d/src/quotes.h b/source/duke3d/src/quotes.h index b75ff9d13..ae5078a16 100644 --- a/source/duke3d/src/quotes.h +++ b/source/duke3d/src/quotes.h @@ -23,8 +23,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifndef quotes_h_ #define quotes_h_ -#define MAXQUOTES 16384 -#define MAXQUOTELEN 128 +#include "quotemgr.h" + #define OBITQUOTEINDEX (MAXQUOTES-128) #define SUICIDEQUOTEINDEX (MAXQUOTES-32) diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index 72d746177..b7d9ee2c1 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -617,7 +617,7 @@ bool G_SavePlayer(FSaveGameNode *sv) if (!g_netServer && ud.multimode < 2) { OSD_Printf("Saved: %s\n", fn.GetChars()); - strcpy(apStrings[QUOTE_RESERVED4], "Game Saved"); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "Game Saved"); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); } @@ -638,7 +638,7 @@ bool GameInterface::LoadGame(FSaveGameNode *sv) { if (g_netServer || ud.multimode > 1) { - Bstrcpy(apStrings[QUOTE_RESERVED4], "Multiplayer Loading Not Yet Supported"); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "Multiplayer Loading Not Yet Supported"); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); // g_player[myconnectindex].ps->gm = MODE_GAME; @@ -657,7 +657,7 @@ bool GameInterface::SaveGame(FSaveGameNode* sv) { if (g_netServer || ud.multimode > 1) { - Bstrcpy(apStrings[QUOTE_RESERVED4], "Multiplayer Saving Not Yet Supported"); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "Multiplayer Saving Not Yet Supported"); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); return false; } @@ -1145,9 +1145,6 @@ static void sv_create_lua_state(void) static void sv_postactordata(); static void sv_preanimateptrsave(); static void sv_postanimateptr(); -static void sv_prequote(); -static void sv_quotesave(); -static void sv_quoteload(); static void sv_prequoteredef(); static void sv_quoteredefsave(); static void sv_quoteredefload(); @@ -1167,9 +1164,6 @@ static int32_t savegame_projectilecnt = 0; ((sizeof(g_player[0].user_name)+sizeof(g_player[0].pcolor)+sizeof(g_player[0].pteam) \ +sizeof(g_player[0].frags)+sizeof(DukePlayer_t))*MAXPLAYERS) -static uint8_t savegame_quotedef[MAXQUOTES >> 3]; -static char (*savegame_quotes)[MAXQUOTELEN]; -static char (*savegame_quoteredefs)[MAXQUOTELEN]; static uint8_t savegame_restdata[SVARDATALEN]; static char svgm_udnetw_string [] = "blK:udnt"; @@ -1309,20 +1303,6 @@ static const dataspec_t svgm_anmisc[] = { 0, &g_pskyidx, sizeof(g_pskyidx), 1 }, // DS_NOCHK? { 0, &g_earthquakeTime, sizeof(g_earthquakeTime), 1 }, - { DS_SAVEFN|DS_LOADFN|DS_NOCHK, (void *)sv_prequote, 0, 1 }, - { DS_SAVEFN, (void *)&sv_quotesave, 0, 1 }, - { DS_NOCHK, &savegame_quotedef, sizeof(savegame_quotedef), 1 }, // quotes can change during runtime, but new quote numbers cannot be allocated - { DS_DYNAMIC, &savegame_quotes, MAXQUOTELEN, MAXQUOTES }, - { DS_LOADFN, (void *)&sv_quoteload, 0, 1 }, - - { DS_NOCHK|DS_SAVEFN|DS_LOADFN, (void *)&sv_prequoteredef, 0, 1 }, - { DS_NOCHK|DS_SAVEFN, (void *)&sv_quoteredefsave, 0, 1 }, // quote redefinitions replace quotes at runtime, but cannot be changed after CON compilation - { DS_NOCHK|DS_DYNAMIC|DS_CNT(g_numXStrings), &savegame_quoteredefs, MAXQUOTELEN, (intptr_t)&g_numXStrings }, - { DS_NOCHK|DS_LOADFN, (void *)&sv_quoteredefload, 0, 1 }, - { DS_NOCHK|DS_SAVEFN|DS_LOADFN, (void *)&sv_postquoteredef, 0, 1 }, -#ifdef LUNATIC - { 0, g_playerWeapon, sizeof(weapondata_t), MAXPLAYERS*MAX_WEAPONS }, -#endif { DS_SAVEFN, (void *)&sv_restsave, 0, 1 }, { 0, savegame_restdata, 1, sizeof(savegame_restdata) }, // sz/cnt swapped for kdfread { DS_LOADFN, (void *)&sv_restload, 0, 1 }, @@ -1798,34 +1778,6 @@ static void sv_postanimateptr() { G_Util_PtrToIdx(g_animatePtr, g_animateCnt, sector, P2I_BACK); } -static void sv_prequote() -{ - if (!savegame_quotes) - { - void *ptr = Xcalloc(MAXQUOTES, MAXQUOTELEN); - savegame_quotes = (char(*)[MAXQUOTELEN])ptr; - } -} -static void sv_quotesave() -{ - Bmemset(savegame_quotedef, 0, sizeof(savegame_quotedef)); - for (int i = 0; i < MAXQUOTES; i++) - if (apStrings[i]) - { - savegame_quotedef[i>>3] |= 1<<(i&7); - Bmemcpy(savegame_quotes[i], apStrings[i], MAXQUOTELEN); - } -} -static void sv_quoteload() -{ - for (int i = 0; i < MAXQUOTES; i++) - if (savegame_quotedef[i>>3] & pow2char[i&7]) - { - C_AllocQuote(i); - Bmemcpy(apStrings[i], savegame_quotes[i], MAXQUOTELEN); - } -} - static void sv_preprojectilesave() { savegame_projectilecnt = 0; @@ -1881,31 +1833,6 @@ static void sv_postprojectileload() DO_FREE_AND_NULL(savegame_projectiledata); } -static void sv_prequoteredef() -{ - // "+1" needed for dfwrite which doesn't handle the src==NULL && cnt==0 case - void *ptr = Xcalloc(g_numXStrings+1, MAXQUOTELEN); - savegame_quoteredefs = (decltype(savegame_quoteredefs))ptr; -} -static void sv_quoteredefsave() -{ - for (int i = 0; i < g_numXStrings; i++) - if (apXStrings[i]) - Bmemcpy(savegame_quoteredefs[i], apXStrings[i], MAXQUOTELEN); -} -static void sv_quoteredefload() -{ - for (int i = 0; i < g_numXStrings; i++) - { - if (!apXStrings[i]) - apXStrings[i] = (char *)Xcalloc(1,MAXQUOTELEN); - Bmemcpy(apXStrings[i], savegame_quoteredefs[i], MAXQUOTELEN); - } -} -static void sv_postquoteredef() -{ - Xfree(savegame_quoteredefs), savegame_quoteredefs=NULL; -} static void sv_restsave() { uint8_t * mem = savegame_restdata; diff --git a/source/duke3d/src/screentext.cpp b/source/duke3d/src/screentext.cpp index bc17bbe12..5af0e37b0 100644 --- a/source/duke3d/src/screentext.cpp +++ b/source/duke3d/src/screentext.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "sbar.h" #include "menus.h" #include "gstrings.h" +#include "quotemgr.h" BEGIN_DUKE_NS @@ -1069,12 +1070,6 @@ void G_PrintGameQuotes(int32_t snum) if (k <= 1) break; - if (EDUKE32_PREDICT_FALSE(apStrings[ps->ftq] == NULL)) - { - OSD_Printf(OSD_ERROR "%s %d null quote %d\n", "screentext:", __LINE__, ps->ftq); - break; - } - int32_t y = ybase; if (reserved_quote) { @@ -1104,7 +1099,7 @@ void G_PrintGameQuotes(int32_t snum) } #endif - height = gametext_(x, y, apStrings[ps->ftq], textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1<<16); + height = gametext_(x, y, quoteMgr.GetQuote(ps->ftq), textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1<<16); } while (0); @@ -1143,12 +1138,6 @@ void P_DoQuote(int32_t q, DukePlayer_t *p) q &= ~MAXQUOTES; } - if (EDUKE32_PREDICT_FALSE(apStrings[q] == NULL)) - { - OSD_Printf(OSD_ERROR "%s %d null quote %d\n", "screentext:", __LINE__, q); - return; - } - if (p->fta > 0 && q != QUOTE_RESERVED && q != QUOTE_RESERVED2) if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return; @@ -1156,8 +1145,9 @@ void P_DoQuote(int32_t q, DukePlayer_t *p) if (p->ftq != q) { - if (p == g_player[screenpeek].ps && apStrings[q][0] != '\0') - OSD_Printf(cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", apStrings[q]); + auto qu = quoteMgr.GetQuote(q); + if (p == g_player[screenpeek].ps && qu[0] != '\0') + OSD_Printf(cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", qu); p->ftq = q; } diff --git a/source/rr/src/cheats.cpp b/source/rr/src/cheats.cpp index d2e315636..a859e34c6 100644 --- a/source/rr/src/cheats.cpp +++ b/source/rr/src/cheats.cpp @@ -490,7 +490,7 @@ void G_DoCheats(void) //} //else //{ - // Bstrcpy(apStrings[QUOTE_RESERVED4], "Come Get Some!"); + // Bstrcpy(pStrings[QUOTE_RESERVED4], "Come Get Some!"); // // S_PlaySound(DUKE_GETWEAPON2); // P_DoQuote(QUOTE_RESERVED4, pPlayer); @@ -661,7 +661,7 @@ void G_DoCheats(void) case CHEAT_TODD: if (NAM) { - Bstrcpy(apStrings[QUOTE_RESERVED4], g_NAMMattCheatQuote); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, g_NAMMattCheatQuote); P_DoQuote(QUOTE_RESERVED4, pPlayer); } else @@ -698,7 +698,7 @@ void G_DoCheats(void) if (++g_noEnemies == 3) g_noEnemies = 0; - Bsprintf(apStrings[QUOTE_RESERVED4], "Monsters: %s", s[g_noEnemies]); + quoteMgr.FormatQuote(QUOTE_RESERVED4, "Monsters: %s", s[g_noEnemies]); P_DoQuote(QUOTE_RESERVED4, pPlayer); end_cheat(pPlayer); diff --git a/source/rr/src/demo.cpp b/source/rr/src/demo.cpp index 4eea7b22b..e459bc519 100644 --- a/source/rr/src/demo.cpp +++ b/source/rr/src/demo.cpp @@ -143,7 +143,7 @@ void G_OpenDemoWrite(void) if ((g_player[myconnectindex].ps->gm&MODE_GAME) && g_player[myconnectindex].ps->dead_flag) { - Bstrcpy(apStrings[QUOTE_RESERVED4], "CANNOT START DEMO RECORDING WHEN DEAD!"); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "CANNOT START DEMO RECORDING WHEN DEAD!"); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); ud.recstat = m_recstat = 0; return; @@ -180,7 +180,7 @@ void G_OpenDemoWrite(void) delete g_demo_filePtr; g_demo_filePtr = nullptr; error_wopen_demo: - Bstrcpy(apStrings[QUOTE_RESERVED4], "FAILED STARTING DEMO RECORDING. SEE CONSOLE FOR DETAILS."); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "FAILED STARTING DEMO RECORDING. SEE CONSOLE FOR DETAILS."); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); ud.recstat = m_recstat = 0; return; @@ -190,7 +190,7 @@ error_wopen_demo: demorec_diffs = demorec_diffs_cvar; demorec_difftics = demorec_difftics_cvar; - Bsprintf(apStrings[QUOTE_RESERVED4], "DEMO %d RECORDING STARTED", demonum-1); + quoteMgr.FormatQuote(QUOTE_RESERVED4, "DEMO %d RECORDING STARTED", demonum-1); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); ud.reccnt = 0; @@ -285,7 +285,7 @@ void G_CloseDemoWrite(void) sv_freemem(); - Bstrcpy(apStrings[QUOTE_RESERVED4], "DEMO RECORDING STOPPED"); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "DEMO RECORDING STOPPED"); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); } #if KRANDDEBUG diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 949f66748..cb800850a 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -6805,12 +6805,6 @@ static void G_Cleanup(void) G_FreeMapState(i); } - for (i=MAXQUOTES-1; i>=0; i--) - { - Bfree(apStrings[i]); - Bfree(apXStrings[i]); - } - for (i=MAXPLAYERS-1; i>=0; i--) { Bfree(g_player[i].ps); @@ -7794,7 +7788,7 @@ int G_DoMoveThings(void) { if (ldist(&sprite[pPlayer->i], &sprite[hitData.sprite]) < 9216) { - Bsprintf(apStrings[QUOTE_RESERVED3], "%s", &g_player[playerNum].user_name[0]); + quoteMgr.FormatQuote(QUOTE_RESERVED3, "%s", &g_player[playerNum].user_name[0]); pPlayer->fta = 12, pPlayer->ftq = QUOTE_RESERVED3; } } diff --git a/source/rr/src/gamedef.cpp b/source/rr/src/gamedef.cpp index 226be8da0..a05ba4fae 100644 --- a/source/rr/src/gamedef.cpp +++ b/source/rr/src/gamedef.cpp @@ -902,129 +902,30 @@ void C_DefineVolumeFlags(int32_t vol, int32_t flags) int32_t C_AllocQuote(int32_t qnum) { Bassert((unsigned)qnum < MAXQUOTES); - - if (apStrings[qnum] == NULL) - { - apStrings[qnum] = (char *)Xcalloc(MAXQUOTELEN,sizeof(uint8_t)); - return 1; - } - - return 0; + return 1; } -#ifndef EDUKE32_TOUCH_DEVICES -static void C_ReplaceQuoteSubstring(const size_t q, char const * const query, char const * const replacement) -{ - size_t querylength = Bstrlen(query); - - for (bssize_t i = MAXQUOTELEN - querylength - 2; i >= 0; i--) - if (Bstrncmp(&apStrings[q][i], query, querylength) == 0) - { - Bmemset(tempbuf, 0, sizeof(tempbuf)); - Bstrncpy(tempbuf, apStrings[q], i); - Bstrcat(tempbuf, replacement); - Bstrcat(tempbuf, &apStrings[q][i + querylength]); - Bstrncpy(apStrings[q], tempbuf, MAXQUOTELEN - 1); - i = MAXQUOTELEN - querylength - 2; - } -} -#endif - void C_InitQuotes(void) { - for (bssize_t i = 0; i < 128; i++) C_AllocQuote(i); - -#ifdef EDUKE32_TOUCH_DEVICES - apStrings[QUOTE_DEAD] = 0; -#else auto openkeys = Bindings.GetKeysForCommand("+open"); if (openkeys.Size()) { auto OpenGameFunc = C_NameKeys(openkeys.Data(), 1); - C_ReplaceQuoteSubstring(QUOTE_DEAD, "SPACE", OpenGameFunc); - C_ReplaceQuoteSubstring(QUOTE_DEAD, "OPEN", OpenGameFunc); - C_ReplaceQuoteSubstring(QUOTE_DEAD, "USE", OpenGameFunc); + quoteMgr.Substitute(QUOTE_DEAD, "SPACE", OpenGameFunc); + quoteMgr.Substitute(QUOTE_DEAD, "OPEN", OpenGameFunc); + quoteMgr.Substitute(QUOTE_DEAD, "USE", OpenGameFunc); } -#endif - // most of these are based on Blood, obviously - const char *PlayerObituaries[] = - { - "^02%s^02 beat %s^02 like a cur", - "^02%s^02 broke %s", - "^02%s^02 body bagged %s", - "^02%s^02 boned %s^02 like a fish", - "^02%s^02 castrated %s", - "^02%s^02 creamed %s", - "^02%s^02 crushed %s", - "^02%s^02 destroyed %s", - "^02%s^02 diced %s", - "^02%s^02 disemboweled %s", - "^02%s^02 erased %s", - "^02%s^02 eviscerated %s", - "^02%s^02 flailed %s", - "^02%s^02 flattened %s", - "^02%s^02 gave AnAl MaDnEsS to %s", - "^02%s^02 gave %s^02 Anal Justice", - "^02%s^02 hosed %s", - "^02%s^02 hurt %s^02 real bad", - "^02%s^02 killed %s", - "^02%s^02 made dog meat out of %s", - "^02%s^02 made mincemeat out of %s", - "^02%s^02 manhandled %s", - "^02%s^02 massacred %s", - "^02%s^02 mutilated %s", - "^02%s^02 murdered %s", - "^02%s^02 neutered %s", - "^02%s^02 punted %s", - "^02%s^02 reamed %s", - "^02%s^02 ripped %s^02 a new orifice", - "^02%s^02 rocked %s", - "^02%s^02 sent %s^02 to hell", - "^02%s^02 shredded %s", - "^02%s^02 slashed %s", - "^02%s^02 slaughtered %s", - "^02%s^02 sliced %s", - "^02%s^02 smacked %s around", - "^02%s^02 smashed %s", - "^02%s^02 snuffed %s", - "^02%s^02 sodomized %s", - "^02%s^02 splattered %s", - "^02%s^02 sprayed %s", - "^02%s^02 squashed %s", - "^02%s^02 throttled %s", - "^02%s^02 toasted %s", - "^02%s^02 vented %s", - "^02%s^02 ventilated %s", - "^02%s^02 wasted %s", - "^02%s^02 wrecked %s", - }; - - const char *PlayerSelfObituaries[] = - { - "^02%s^02 is excrement", - "^02%s^02 is hamburger", - "^02%s^02 suffered scrotum separation", - "^02%s^02 volunteered for population control", - "^02%s^02 has suicided", - "^02%s^02 bled out", - }; - - EDUKE32_STATIC_ASSERT(OBITQUOTEINDEX + ARRAY_SIZE(PlayerObituaries)-1 < MAXQUOTES); - EDUKE32_STATIC_ASSERT(SUICIDEQUOTEINDEX + ARRAY_SIZE(PlayerSelfObituaries)-1 < MAXQUOTES); - - g_numObituaries = ARRAY_SIZE(PlayerObituaries); + g_numObituaries = 48; for (bssize_t i = g_numObituaries - 1; i >= 0; i--) { - if (C_AllocQuote(i + OBITQUOTEINDEX)) - Bstrcpy(apStrings[i + OBITQUOTEINDEX], PlayerObituaries[i]); + quoteMgr.FormatQuote(i + OBITQUOTEINDEX, "$TXT_OBITUARY%d", i + 1); } - g_numSelfObituaries = ARRAY_SIZE(PlayerSelfObituaries); + g_numSelfObituaries = 6; for (bssize_t i = g_numSelfObituaries - 1; i >= 0; i--) { - if (C_AllocQuote(i + SUICIDEQUOTEINDEX)) - Bstrcpy(apStrings[i + SUICIDEQUOTEINDEX], PlayerSelfObituaries[i]); + quoteMgr.FormatQuote(i + SUICIDEQUOTEINDEX, "$TXT_SELFOBIT%d", i + 1); } } @@ -2028,6 +1929,7 @@ static int32_t C_ParseCommand(int32_t loop) continue; case CON_DEFINEQUOTE: + { g_scriptPtr--; C_GetNextValue(LABEL_DEFINE); @@ -2050,33 +1952,16 @@ static int32_t C_ParseCommand(int32_t loop) C_SkipSpace(); - while (*textptr != 0x0a && *textptr != 0x0d && *textptr != 0) - { - /* - if (*textptr == '%' && *(textptr+1) == 's') - { - initprintf("%s:%d: error: quote text contains string identifier.\n",g_szScriptFileName,g_lineNumber); - g_numCompilerErrors++; - while (*textptr != 0x0a && *textptr != 0x0d && *textptr != 0) textptr++; - break; - } - */ - *(apStrings[k]+i) = *textptr; - - textptr++,i++; - if (EDUKE32_PREDICT_FALSE(i >= MAXQUOTELEN-1)) - { - initprintf("%s:%d: warning: truncating quote text to %d characters.\n",g_scriptFileName,g_lineNumber,MAXQUOTELEN-1); - g_warningCnt++; - C_NextLine(); - break; - } - } - - if ((unsigned)k < MAXQUOTES) - *(apStrings[k]+i) = '\0'; - continue; - + TArray buffer; + while (*textptr != 0x0a && *textptr != 0x0d && *textptr != 0) + { + buffer.Push(*textptr); + textptr++; + } + buffer.Push(0); + quoteMgr.InitializeQuote(k, buffer.Data(), true); + continue; + } case CON_DEFINESOUND: g_scriptPtr--; C_GetNextValue(LABEL_DEFINE); @@ -2313,14 +2198,6 @@ void C_PrintStats(void) int i, j; - for (i=MAXQUOTES-1, j=0; i>=0; i--) - { - if (apStrings[i]) - j++; - } - - if (j) initprintf("%d strings, ", j); - for (i=MAXTILES-1, j=0; i>=0; i--) { if (g_tile[i].execPtr) diff --git a/source/rr/src/gameexec.cpp b/source/rr/src/gameexec.cpp index 49997724e..e6efa911a 100644 --- a/source/rr/src/gameexec.cpp +++ b/source/rr/src/gameexec.cpp @@ -2457,7 +2457,7 @@ GAMEEXEC_STATIC void VM_Execute(native_t loop) case CON_QUOTE: insptr++; - if (EDUKE32_PREDICT_FALSE((unsigned)(*insptr) >= MAXQUOTES) || apStrings[*insptr] == NULL) + if (EDUKE32_PREDICT_FALSE((unsigned)(*insptr) >= MAXQUOTES)) { CON_ERRPRINTF("invalid quote %d\n", (int32_t)(*insptr)); insptr++; diff --git a/source/rr/src/global.h b/source/rr/src/global.h index 217368c60..574f27750 100644 --- a/source/rr/src/global.h +++ b/source/rr/src/global.h @@ -72,7 +72,6 @@ G_EXTERN actor_t actor[MAXSPRITES]; // g_tile: tile-specific data THAT DOES NOT CHANGE during the course of a game G_EXTERN tiledata_t g_tile[MAXTILES]; G_EXTERN animwalltype animwall[MAXANIMWALLS]; -G_EXTERN char *apStrings[MAXQUOTES],*apXStrings[MAXQUOTES]; G_EXTERN char *label; G_EXTERN int32_t g_musicIndex; G_EXTERN char g_loadFromGroupOnly; diff --git a/source/rr/src/player.cpp b/source/rr/src/player.cpp index a9577925d..47756f982 100644 --- a/source/rr/src/player.cpp +++ b/source/rr/src/player.cpp @@ -4478,18 +4478,18 @@ void P_FragPlayer(int playerNum) if (playerNum == screenpeek) { - Bsprintf(apStrings[QUOTE_RESERVED], "Killed by %s", &g_player[pPlayer->frag_ps].user_name[0]); + quoteMgr.InitializeQuote(QUOTE_RESERVED, "Killed by %s", &g_player[pPlayer->frag_ps].user_name[0]); P_DoQuote(QUOTE_RESERVED, pPlayer); } else { - Bsprintf(apStrings[QUOTE_RESERVED2], "Killed %s", &g_player[playerNum].user_name[0]); + quoteMgr.InitializeQuote(QUOTE_RESERVED2, "Killed %s", &g_player[playerNum].user_name[0]); P_DoQuote(QUOTE_RESERVED2, g_player[pPlayer->frag_ps].ps); } if (cl_obituaries) { - Bsprintf(tempbuf, apStrings[OBITQUOTEINDEX + (krand2() % g_numObituaries)], + Bsprintf(tempbuf, quoteMgr.GetQuote(OBITQUOTEINDEX + (krand2() % g_numObituaries)), &g_player[pPlayer->frag_ps].user_name[0], &g_player[playerNum].user_name[0]); G_AddUserQuote(tempbuf); } @@ -4502,14 +4502,14 @@ void P_FragPlayer(int playerNum) { pPlayer->fraggedself++; if ((unsigned)pPlayer->wackedbyactor < MAXTILES && A_CheckEnemyTile(sprite[pPlayer->wackedbyactor].picnum)) - Bsprintf(tempbuf, apStrings[OBITQUOTEINDEX + (krand2() % g_numObituaries)], "A monster", + Bsprintf(tempbuf, quoteMgr.GetQuote(OBITQUOTEINDEX + (krand2() % g_numObituaries)), "A monster", &g_player[playerNum].user_name[0]); else if (actor[pPlayer->i].picnum == NUKEBUTTON) Bsprintf(tempbuf, "^02%s^02 tried to leave", &g_player[playerNum].user_name[0]); else { // random suicide death string - Bsprintf(tempbuf, apStrings[SUICIDEQUOTEINDEX + (krand2() % g_numSelfObituaries)], + Bsprintf(tempbuf, quoteMgr.GetQuote(SUICIDEQUOTEINDEX + (krand2() % g_numSelfObituaries)), &g_player[playerNum].user_name[0]); } } diff --git a/source/rr/src/quotes.h b/source/rr/src/quotes.h index 4ff44df24..46858c821 100644 --- a/source/rr/src/quotes.h +++ b/source/rr/src/quotes.h @@ -23,8 +23,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifndef quotes_h_ #define quotes_h_ -#define MAXQUOTES 16384 -#define MAXQUOTELEN 128 +#include "quotemgr.h" + #define OBITQUOTEINDEX (MAXQUOTES-128) #define SUICIDEQUOTEINDEX (MAXQUOTES-32) diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index c5cd7aa4f..d794681fb 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -362,7 +362,7 @@ bool G_SavePlayer(FSaveGameNode *sv) if (!g_netServer && ud.multimode < 2) { OSD_Printf("Saved: %s\n", fn.GetChars()); - Bstrcpy(apStrings[QUOTE_RESERVED4], "Game Saved"); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "Game Saved"); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); } @@ -380,7 +380,7 @@ bool GameInterface::LoadGame(FSaveGameNode* sv) { if (g_netServer || ud.multimode > 1) { - Bstrcpy(apStrings[QUOTE_RESERVED4], "Multiplayer Loading Not Yet Supported"); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "Multiplayer Loading Not Yet Supported"); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); // g_player[myconnectindex].ps->gm = MODE_GAME; @@ -399,7 +399,7 @@ bool GameInterface::SaveGame(FSaveGameNode* sv) { if (g_netServer || ud.multimode > 1) { - Bstrcpy(apStrings[QUOTE_RESERVED4], "Multiplayer Saving Not Yet Supported"); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "Multiplayer Saving Not Yet Supported"); P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps); return false; } @@ -881,8 +881,6 @@ static void sv_rrrafog(); ((sizeof(g_player[0].user_name)+sizeof(g_player[0].pcolor)+sizeof(g_player[0].pteam) \ +sizeof(g_player[0].frags)+sizeof(DukePlayer_t))*MAXPLAYERS) -static uint8_t savegame_quotedef[MAXQUOTES>>3]; -static char (*savegame_quotes)[MAXQUOTELEN]; static uint8_t savegame_restdata[SVARDATALEN]; static char svgm_udnetw_string [] = "blK:udnt"; @@ -1082,12 +1080,6 @@ static const dataspec_t svgm_anmisc[] = { 0, &g_fogType, sizeof(g_fogType), 1 }, { DS_LOADFN, (void *)sv_rrrafog, 0, 1 }, - { DS_SAVEFN|DS_LOADFN|DS_NOCHK, (void *)sv_prequote, 0, 1 }, - { DS_SAVEFN, (void *)&sv_quotesave, 0, 1 }, - { DS_NOCHK, &savegame_quotedef, sizeof(savegame_quotedef), 1 }, // quotes can change during runtime, but new quote numbers cannot be allocated - { DS_DYNAMIC, &savegame_quotes, MAXQUOTELEN, MAXQUOTES }, - { DS_LOADFN, (void *)&sv_quoteload, 0, 1 }, - { DS_SAVEFN, (void *)&sv_restsave, 0, 1 }, { 0, savegame_restdata, 1, sizeof(savegame_restdata) }, // sz/cnt swapped for kdfread { DS_LOADFN, (void *)&sv_restload, 0, 1 }, @@ -1482,33 +1474,6 @@ static void sv_postanimateptr() { G_Util_PtrToIdx(g_animatePtr, g_animateCnt, sector, P2I_BACK); } -static void sv_prequote() -{ - if (!savegame_quotes) - { - void *ptr = Xcalloc(MAXQUOTES, MAXQUOTELEN); - savegame_quotes = (char(*)[MAXQUOTELEN])ptr; - } -} -static void sv_quotesave() -{ - Bmemset(savegame_quotedef, 0, sizeof(savegame_quotedef)); - for (int i = 0; i < MAXQUOTES; i++) - if (apStrings[i]) - { - savegame_quotedef[i>>3] |= 1<<(i&7); - Bmemcpy(savegame_quotes[i], apStrings[i], MAXQUOTELEN); - } -} -static void sv_quoteload() -{ - for (int i = 0; i < MAXQUOTES; i++) - if (savegame_quotedef[i>>3] & (1<<(i&7))) - { - C_AllocQuote(i); - Bmemcpy(apStrings[i], savegame_quotes[i], MAXQUOTELEN); - } -} static void sv_restsave() { uint8_t * mem = savegame_restdata; diff --git a/source/rr/src/screentext.cpp b/source/rr/src/screentext.cpp index cc0a49ae6..ec66b14c2 100644 --- a/source/rr/src/screentext.cpp +++ b/source/rr/src/screentext.cpp @@ -1071,12 +1071,6 @@ void G_PrintGameQuotes(int32_t snum) if (k <= 1) break; - if (EDUKE32_PREDICT_FALSE(apStrings[ps->ftq] == NULL)) - { - OSD_Printf(OSD_ERROR "%s %d null quote %d\n", __FILE__, __LINE__, ps->ftq); - break; - } - int32_t y = ybase; if (reserved_quote) { @@ -1106,7 +1100,7 @@ void G_PrintGameQuotes(int32_t snum) } #endif - height = gametext_(x, y, apStrings[ps->ftq], textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1<<16); + height = gametext_(x, y, quoteMgr.GetQuote(ps->ftq), textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1<<16); } while (0); @@ -1145,12 +1139,6 @@ void P_DoQuote(int32_t q, DukePlayer_t *p) q &= ~MAXQUOTES; } - if (EDUKE32_PREDICT_FALSE(apStrings[q] == NULL)) - { - OSD_Printf(OSD_ERROR "%s %d null quote %d\n", __FILE__, __LINE__, q); - return; - } - if (p->fta > 0 && q != QUOTE_RESERVED && q != QUOTE_RESERVED2) if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return; @@ -1158,8 +1146,9 @@ void P_DoQuote(int32_t q, DukePlayer_t *p) if (p->ftq != q) { - if (p == g_player[screenpeek].ps && apStrings[q][0] != '\0') - OSD_Printf(cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", apStrings[q]); + auto qu = quoteMgr.GetQuote(q); + if (p == g_player[screenpeek].ps && qu[0] != '\0') + OSD_Printf(cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", qu); p->ftq = q; } From 6a6d6e369426b465deed1cf72f9a2b688b973e7a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 4 Dec 2019 00:38:43 +0100 Subject: [PATCH 104/203] - fixed quote init. --- source/common/quotes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/common/quotes.cpp b/source/common/quotes.cpp index 4ca7057ce..9511f1182 100644 --- a/source/common/quotes.cpp +++ b/source/common/quotes.cpp @@ -46,7 +46,7 @@ void Quotes::MakeStringLabel(FString "e) void Quotes::InitializeQuote(int num, const char *text, bool fromscript) { - quotes[num] = num; + quotes[num] = text; if (fromscript) // means this is the initial setup from the source data. { MakeStringLabel(quotes[num]); @@ -55,7 +55,7 @@ void Quotes::InitializeQuote(int num, const char *text, bool fromscript) void Quotes::InitializeExQuote(int num, const char *text, bool fromscript) { - exquotes[num] = num; + exquotes[num] = text; if (fromscript) // means this is the initial setup from the source data. { MakeStringLabel(quotes[num]); From 7d1eb74b5e741b487af91342f84b37b7e06f29e1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 4 Dec 2019 01:38:51 +0100 Subject: [PATCH 105/203] - more menus implemented --- source/common/gamecvars.cpp | 50 +- source/common/gamecvars.h | 2 +- source/duke3d/src/cheats.cpp | 6 - source/duke3d/src/d_menu.cpp | 6 + source/duke3d/src/game.cpp | 4 +- source/duke3d/src/gamestructures.cpp | 4 +- source/duke3d/src/global.cpp | 9 +- source/duke3d/src/menus.cpp | 704 --------------------------- source/duke3d/src/menus.h | 7 +- source/duke3d/src/network.cpp | 2 +- source/rr/src/cheats.cpp | 3 - source/rr/src/d_menu.cpp | 11 + source/rr/src/game.cpp | 4 +- source/rr/src/menus.h | 7 +- source/rr/src/net.cpp | 2 +- wadsrc/static/demolition/menudef.txt | 292 +++++++++-- 16 files changed, 331 insertions(+), 782 deletions(-) diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index c96225a59..c5d018470 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -258,8 +258,11 @@ CVARD(Bool, hud_position, false, CVAR_ARCHIVE, "aligns the status bar to the bot CVARD(Bool, hud_bgstretch, false, CVAR_ARCHIVE|CVAR_FRONTEND_DUKELIKE, "enable/disable background image stretching in wide resolutions") CVARD(Int, hud_messagetime, 120, CVAR_ARCHIVE|CVAR_FRONTEND_DUKELIKE, "length of time to display multiplayer chat messages") // Should be available to all games - the message handling should also be consolidated into a game independent feature. -/*CUSTOM_*/CVARD(Bool, hud_messages, true, CVAR_ARCHIVE, "enable/disable showing messages") -CVAR(Bool, hud_messagenative, true, CVAR_ARCHIVE) +CUSTOM_CVARD(Int, hud_messages, 1, CVAR_ARCHIVE, "enable/disable showing messages") +{ + if (self < 0 || self > 2) self = 1; +} + CCMD (togglemessages) { @@ -530,6 +533,16 @@ CUSTOM_CVARD(Float, vid_brightness, 0.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "adju // todo: tell the system to update } + +CUSTOM_CVARD(Float, vid_saturation, 0.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "adjusts saturation component of gamma ramp") +{ + if (self < -3) self = -3; + else if (self > 3) self = 3; + // todo: tell the system to update +} + +CVAR(Int, gl_satformula, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); + CCMD (bumpgamma) { // [RH] Gamma correction tables are now generated on the fly for *any* gamma level @@ -555,32 +568,44 @@ CUSTOM_CVAR(String, rtsname, "", CVAR_ARCHIVE | CVAR_USERINFO) CVAR(String, usermapfolder, "", CVAR_ARCHIVE); +CUSTOM_CVAR(Int, playercolor, 0, CVAR_ARCHIVE|CVAR_USERINFO) +{ + if (self < 0 || self > 10) self = 0; + else ;// gi->UpdatePlayerColor(); // this part is game specific +} + +CUSTOM_CVAR(Int, playerteam, 0, CVAR_USERINFO) // this one is transient and won't be saved. +{ + if (self < 0 || self > 3) self = 0; + else ;// gi->UpdatePlayerTeam(); // this part is game specific +} + +// Will only become useful if the obituary system gets overhauled. +CUSTOM_CVAR(Int, playergender, 0, CVAR_USERINFO|CVAR_ARCHIVE) +{ + if (self < 0 || self > 3) self = 0; +} // Internal settings for demo recording and the multiplayer menu. These won't get saved and only are CVARs so that the menu code can use them. CVAR(Bool, m_recstat, false, CVAR_NOSET) CVAR(Int, m_coop, 0, CVAR_NOSET) CVAR(Int, m_ffire, 1, CVAR_NOSET) +CVAR(Int, m_monsters, 1, CVAR_NOSET) CVAR(Int, m_marker, 1, CVAR_NOSET) CVAR(Int, m_level_number, 0, CVAR_NOSET) +CVAR(Int, m_episode_number, 0, CVAR_NOSET) CVAR(Int, m_noexits, 0, CVAR_NOSET) -CVAR(Int, playercolor, 0, CVAR_NOSET) -CVAR(Int, playerteam, 0, CVAR_NOSET) +CVAR(String, m_server, "localhost", CVAR_NOSET) +CVAR(String, m_netport, "19014", CVAR_NOSET) #if 0 -// These have to wait until the HUD code is cleaned up (no idea which may survive and which won't.) /* // Currently unavailable due to dependency on an obsolete OpenGL feature { "deliriumblur", "enable/disable delirium blur effect(polymost)", (void *)&gDeliriumBlur, CVAR_BOOL, 0, 1 }, - if (!Bstrcasecmp(parm->name, "color")) - { - playercolor = G_CheckPlayerColor(playercolor); - g_player[0].ps->palookup = g_player[0].pcolor = playercolor; - } - // This one gets changed at run time by the game code, so making it persistent does not work // This option is not really useful anymore @@ -589,9 +614,6 @@ CVAR(Int, playerteam, 0, CVAR_NOSET) // This requires a different approach, because it got used like a CCMD, not a CVAR. { "skill","changes the game skill setting", (void *)&ud.m_player_skill, CVAR_INT|CVAR_FUNCPTR|CVAR_NOSAVE/*|CVAR_NOMULTI*/, 0, 5 }, - // requires cleanup first - //{ "team","change team in multiplayer", (void *)&playerteam, CVAR_INT|CVAR_MULTI, 0, 3 }, - // just as a reminder: /* else if (!Bstrcasecmp(parm->name, "vid_gamma")) diff --git a/source/common/gamecvars.h b/source/common/gamecvars.h index 0a1ffcac1..b0331a9d2 100644 --- a/source/common/gamecvars.h +++ b/source/common/gamecvars.h @@ -63,7 +63,7 @@ EXTERN_CVAR(Int, hud_messagetime) EXTERN_CVAR(Bool, hud_glowingquotes) EXTERN_CVAR(Int, hud_textscale) EXTERN_CVAR(Int, hud_weaponscale) -EXTERN_CVAR(Bool, hud_messages) +EXTERN_CVAR(Int, hud_messages) EXTERN_CVAR(Int, althud_numbertile) EXTERN_CVAR(Int, althud_numberpal) diff --git a/source/duke3d/src/cheats.cpp b/source/duke3d/src/cheats.cpp index 0559ed960..4f9e9e7ba 100644 --- a/source/duke3d/src/cheats.cpp +++ b/source/duke3d/src/cheats.cpp @@ -187,9 +187,6 @@ void G_SetupCheats(void) Bstrcpy(CheatStrings[23], ""); Bstrcpy(CheatStrings[24], "2debug"); Bstrcpy(CheatStrings[26], "2cgs"); - - Bstrcpy(g_gametypeNames[0], "GI Match (Spawn)"); - Bstrcpy(g_gametypeNames[2], "GI Match (No Spawn)"); } else if (NAM) { @@ -219,9 +216,6 @@ void G_SetupCheats(void) Bstrcpy(CheatStrings[23], ""); Bstrcpy(CheatStrings[24], "adebug"); Bstrcpy(CheatStrings[26], "acgs"); - - Bstrcpy(g_gametypeNames[0], "GruntMatch (Spawn)"); - Bstrcpy(g_gametypeNames[2], "GruntMatch (No Spawn)"); } } #endif diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index e210eb205..0930c3aa2 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -757,6 +757,12 @@ void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *t mgametextcenter(int(origin.X * 65536), int((origin.Y + position) * 65536), text); } +#if 0 +void GameInterface::DrawPlayerSprite(int x, int y) +{ + rotatesprite_fs(origin.x + (260<<16), origin.y + ((24+(tilesiz[APLAYER].y>>1))<<16), 49152L,0,1441-((((4-((int32_t) totalclock>>4)))&3)*5),0,entry == &ME_PLAYER_TEAM ? G_GetTeamPalette(playerteam) : playercolor,10); +} +#endif END_DUKE_NS diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index a33cbc81e..90ebdd3d7 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -5744,7 +5744,7 @@ void G_UpdatePlayerFromMenu(void) /*int32_t j = p.team;*/ P_SetupMiscInputSettings(); - p.palookup = g_player[myconnectindex].pcolor = playercolor; + p.palookup = g_player[myconnectindex].pcolor = G_CheckPlayerColor(playercolor); g_player[myconnectindex].pteam = playerteam; @@ -6150,7 +6150,7 @@ MAIN_LOOP_RESTART: myplayer.palookup = g_player[myconnectindex].pcolor = G_GetTeamPalette(g_player[myconnectindex].pteam); else { - if (playercolor) myplayer.palookup = g_player[myconnectindex].pcolor = playercolor; + if (playercolor) myplayer.palookup = g_player[myconnectindex].pcolor = G_CheckPlayerColor(playercolor); else myplayer.palookup = g_player[myconnectindex].pcolor; } diff --git a/source/duke3d/src/gamestructures.cpp b/source/duke3d/src/gamestructures.cpp index 2915ba5ad..be97ba659 100644 --- a/source/duke3d/src/gamestructures.cpp +++ b/source/duke3d/src/gamestructures.cpp @@ -1646,7 +1646,7 @@ void __fastcall VM_SetUserdef(int const labelNum, int const lParm2, int32_t cons case USERDEFS_MOUSEAIMING: in_aimmode.SetGenericRepDefault(iSet, CVAR_Int); break; case USERDEFS_WEAPONSWITCH: cl_weaponswitch.SetGenericRepDefault(iSet, CVAR_Int); break; case USERDEFS_DEMOCAMS: cl_democams = iSet; break; - case USERDEFS_COLOR: playercolor = iSet; break; + case USERDEFS_COLOR: /*playercolor.SetGenericRepDefault(iSet, CVAR_Int);*/ break; // the value range here does not match, so better leave the CVar alone. case USERDEFS_MSGDISPTIME: hud_messagetime.SetGenericRepDefault(iSet, CVAR_Int); break; case USERDEFS_STATUSBARMODE: ud.statusbarmode = iSet; break; case USERDEFS_M_NOEXITS: m_noexits = iSet; break; @@ -1654,7 +1654,7 @@ void __fastcall VM_SetUserdef(int const labelNum, int const lParm2, int32_t cons case USERDEFS_AUTOVOTE: cl_autovote.SetGenericRepDefault(iSet, CVAR_Int); break; case USERDEFS_AUTOMSG: cl_automsg.SetGenericRepDefault(iSet, CVAR_Int); break; case USERDEFS_IDPLAYERS: cl_idplayers.SetGenericRepDefault(iSet, CVAR_Int); break; - case USERDEFS_TEAM: playerteam = iSet; break; + case USERDEFS_TEAM: playerteam.SetGenericRepDefault(iSet, CVAR_Int); break; case USERDEFS_VIEWBOB: cl_viewbob.SetGenericRepDefault(iSet, CVAR_Int); break; case USERDEFS_WEAPONSWAY: cl_weaponsway.SetGenericRepDefault(iSet, CVAR_Int); break; case USERDEFS_ANGLEINTERPOLATION: ud.angleinterpolation = iSet; break; diff --git a/source/duke3d/src/global.cpp b/source/duke3d/src/global.cpp index 5709ad1d3..efddc8e1d 100644 --- a/source/duke3d/src/global.cpp +++ b/source/duke3d/src/global.cpp @@ -34,14 +34,9 @@ user_defs ud; const char *s_buildDate = "20120522"; -#ifndef EDUKE32_STANDALONE +char g_gametypeNames[MAXGAMETYPES][33] += { "$NETMNU_GAMETYPE1", "$NETMNU_GAMETYPE2", "NETMNU_GAMETYPE3", "NETMNU_GAMETYPE4", "NETMNU_GAMETYPE5" }; -char g_gametypeNames[MAXGAMETYPES][33] -= { "DukeMatch (Spawn)", "Cooperative Play", "DukeMatch (No Spawn)", "Team DM (Spawn)", "Team DM (No Spawn)" }; -#else -char g_gametypeNames[MAXGAMETYPES][33] -= { "Deathmatch (Spawn)", "Cooperative Play", "Deathmatch (No Spawn)", "Team DM (Spawn)", "Team DM (No Spawn)" }; -#endif int32_t g_gametypeFlags[MAXGAMETYPES] = { diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index 39aa8d211..8bef91a7e 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -56,83 +56,6 @@ BEGIN_DUKE_NS #define USERMAPENTRYLENGTH 25 - -/* -All MAKE_* macros are generally for the purpose of keeping state initialization -separate from actual data. Alternatively, they can serve to factor out repetitive -stuff and keep the important bits from getting lost to our eyes. - -They serve as a stand-in for C++ default value constructors, since this was written -when the codebase still used C89. - -Note that I prefer to include a space on the inside of the macro parentheses, since -they effectively stand in for curly braces as struct initializers. -*/ - - -static MenuMenuFormat_t MMF_Top_Options = { { MENU_MARGIN_CENTER<<16, 38<<16, }, -(190<<16) }; -static MenuMenuFormat_t MMF_Top_Joystick_Network = { { MENU_MARGIN_CENTER<<16, 70<<16, }, -(190<<16) }; -static MenuMenuFormat_t MMF_BigOptions = { { MENU_MARGIN_WIDE<<16, 38<<16, }, -(190<<16) }; -static MenuMenuFormat_t MMF_SmallOptions = { { MENU_MARGIN_WIDE<<16, 37<<16, }, 170<<16 }; -static MenuMenuFormat_t MMF_Macros = { { 26<<16, 40<<16, }, 160<<16 }; -static MenuMenuFormat_t MMF_SmallOptionsNarrow = { { MENU_MARGIN_REGULAR<<16, 38<<16, }, -(190<<16) }; -static MenuMenuFormat_t MMF_KeyboardSetupFuncs = { { 50<<16, 34<<16, }, 151<<16 }; -static MenuMenuFormat_t MMF_MouseJoySetupBtns = { { 76<<16, 34<<16, }, 143<<16 }; -static MenuMenuFormat_t MMF_FuncList = { { 100<<16, 51<<16, }, 152<<16 }; -static MenuMenuFormat_t MMF_ColorCorrect = { { MENU_MARGIN_REGULAR<<16, 86<<16, }, 190<<16 }; -static MenuMenuFormat_t MMF_BigSliders = { { MENU_MARGIN_WIDE<<16, 37<<16, }, 190<<16 }; -static MenuMenuFormat_t MMF_LoadSave = { { 200<<16, 49<<16, }, 145<<16 }; -static MenuMenuFormat_t MMF_NetSetup = { { 36<<16, 38<<16, }, 190<<16 }; -static MenuMenuFormat_t MMF_FileSelectLeft = { { 40<<16, 45<<16, }, 162<<16 }; -static MenuMenuFormat_t MMF_FileSelectRight = { { 164<<16, 45<<16, }, 162<<16 }; - - -static MenuEntryFormat_t MEF_OptionsMenu = { 7<<16, 0, 0 }; -static MenuEntryFormat_t MEF_LeftMenu = { 7<<16, 0, 120<<16 }; -static MenuEntryFormat_t MEF_CenterMenu = { 7<<16, 0, 0 }; -static MenuEntryFormat_t MEF_BigOptions_Apply = { 4<<16, 16<<16, -(260<<16) }; -static MenuEntryFormat_t MEF_BigOptionsRt = { 4<<16, 0, -(260<<16) }; -static MenuEntryFormat_t MEF_BigOptionsRtSections = { 3<<16, 0, -(260<<16) }; -#if defined USE_OPENGL || !defined EDUKE32_ANDROID_MENU -static MenuEntryFormat_t MEF_SmallOptions = { 1<<16, 0, -(260<<16) }; -#endif -static MenuEntryFormat_t MEF_BigCheats = { 3<<16, 0, -(260<<16) }; -static MenuEntryFormat_t MEF_Cheats = { 2<<16, 0, -(260<<16) }; -static MenuEntryFormat_t MEF_PlayerNarrow = { 1<<16, 0, 90<<16 }; -static MenuEntryFormat_t MEF_Macros = { 2<<16, -1, 268<<16 }; -static MenuEntryFormat_t MEF_VideoSetup = { 4<<16, 0, 168<<16 }; -static MenuEntryFormat_t MEF_VideoSetup_Apply = { 4<<16, 16<<16, 168<<16 }; -static MenuEntryFormat_t MEF_KBFuncList = { 3<<16, 0, -(225<<16) }; -static MenuEntryFormat_t MEF_FuncList = { 3<<16, 0, -(170<<16) }; -static MenuEntryFormat_t MEF_ColorCorrect = { 2<<16, 0, -(240<<16) }; -static MenuEntryFormat_t MEF_BigSliders = { 2<<16, 0, -(260<<16) }; -static MenuEntryFormat_t MEF_LoadSave = { 2<<16, -1, 78<<16 }; -static MenuEntryFormat_t MEF_NetSetup = { 4<<16, 0, 112<<16 }; -static MenuEntryFormat_t MEF_NetSetup_Confirm = { 4<<16, 16<<16, 112<<16 }; - -// common menu option sets -#define MAKE_MENUOPTIONSET(optionNames, optionValues, features) { optionNames, optionValues, &MMF_FuncList, &MEF_FuncList, &MF_Minifont, ARRAY_SIZE(optionNames), -1, 0, features } -#define MAKE_MENUOPTIONSETDYN(optionNames, optionValues, numOptions, features) { optionNames, optionValues, &MMF_FuncList, &MEF_FuncList, &MF_Minifont, numOptions, -1, 0, features } -#define MAKE_MENUOPTIONSETNULL { NULL, NULL, &MMF_FuncList, &MEF_FuncList, &MF_Minifont, 0, -1, 0, 0 } - -static char const *MEOSN_OffOn[] = { "Off", "On", }; -static MenuOptionSet_t MEOS_OffOn = MAKE_MENUOPTIONSET( MEOSN_OffOn, NULL, 0x3 ); -static char const *MEOSN_OnOff[] = { "On", "Off", }; -static MenuOptionSet_t MEOS_OnOff = MAKE_MENUOPTIONSET( MEOSN_OnOff, NULL, 0x3 ); -static char const *MEOSN_NoYes[] = { "No", "Yes", }; -static MenuOptionSet_t MEOS_NoYes = MAKE_MENUOPTIONSET( MEOSN_NoYes, NULL, 0x3 ); -static char const *MEOSN_YesNo[] = { "Yes", "No", }; -static MenuOptionSet_t MEOS_YesNo = MAKE_MENUOPTIONSET( MEOSN_YesNo, NULL, 0x3 ); - - -static FString MenuGameFuncs[NUMGAMEFUNCTIONS]; -static char const *MenuGameFuncNone = " -None-"; -static char const *MEOSN_Gamefuncs[NUMGAMEFUNCTIONS+1]; -static int32_t MEOSV_Gamefuncs[NUMGAMEFUNCTIONS+1]; -static MenuOptionSet_t MEOS_Gamefuncs = MAKE_MENUOPTIONSET( MEOSN_Gamefuncs, MEOSV_Gamefuncs, 0x1 ); - - - /* MenuEntry_t is passed in arrays of pointers so that the callback function that is called when an entry is modified or activated can test equality of the current @@ -141,97 +64,6 @@ entry pointer directly against the known ones, instead of relying on an ID numbe That way, individual menu entries can be ifdef'd out painlessly. */ -static MenuLink_t MEO_NULL = { MENU_NULL, MA_None, }; -static const char* MenuCustom = "Custom"; - -#define MAKE_MENUSTRING(...) { NULL, __VA_ARGS__, } -#define MAKE_MENUOPTION(...) { __VA_ARGS__, -1, } -#define MAKE_MENURANGE(...) { __VA_ARGS__, } -#define MAKE_MENUENTRY(...) { __VA_ARGS__, 0, 0, 0, } - - -#define MAKE_SPACER( EntryName, Height ) \ -static MenuSpacer_t MEO_ ## EntryName = { Height }; - -MAKE_SPACER( Space2, 2<<16 ); // bigoptions -MAKE_SPACER( Space4, 4<<16 ); // usermap, smalloptions, anything else non-top -MAKE_SPACER( Space6, 6<<16 ); // videosetup -MAKE_SPACER( Space8, 8<<16 ); // colcorr, redslide - -static MenuEntry_t ME_Space2_Redfont = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_Null, &MEO_Space2, Spacer ); -static MenuEntry_t ME_Space4_Bluefont = MAKE_MENUENTRY( NULL, &MF_Bluefont, &MEF_Null, &MEO_Space4, Spacer ); -static MenuEntry_t ME_Space4_Redfont = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_Null, &MEO_Space4, Spacer ); -#ifndef EDUKE32_SIMPLE_MENU -static MenuEntry_t ME_Space8_Bluefont = MAKE_MENUENTRY( NULL, &MF_Bluefont, &MEF_Null, &MEO_Space8, Spacer ); -#endif -static MenuEntry_t ME_Space6_Redfont = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_Null, &MEO_Space6, Spacer ); -static MenuEntry_t ME_Space8_Redfont = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_Null, &MEO_Space8, Spacer ); - - -static MenuEntry_t ME_SKILL_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_CenterMenu, &MEO_NULL, Link ); -static MenuEntry_t ME_SKILL[MAXSKILLS]; -static MenuEntry_t *MEL_SKILL[MAXSKILLS]; - -static char const *MEOSN_GAMESETUP_AIM_AUTO[] = { "Never", "Always", "Hitscan only", -}; -static int32_t MEOSV_GAMESETUP_AIM_AUTO[] = { 0, 1, 2, -}; - -static MenuOptionSet_t MEOS_GAMESETUP_AIM_AUTO = MAKE_MENUOPTIONSET( MEOSN_GAMESETUP_AIM_AUTO, MEOSV_GAMESETUP_AIM_AUTO, 0x2 ); -static MenuOption_t MEO_GAMESETUP_AIM_AUTO = MAKE_MENUOPTION( &MF_Redfont, &MEOS_GAMESETUP_AIM_AUTO, &cl_autoaim ); -static MenuEntry_t ME_GAMESETUP_AIM_AUTO = MAKE_MENUENTRY( "Auto aim:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_GAMESETUP_AIM_AUTO, Option ); - -static MenuOption_t MEO_GAMESETUP_ALWAYS_RUN = MAKE_MENUOPTION( &MF_Redfont, &MEOS_NoYes, &cl_autorun); -static MenuEntry_t ME_GAMESETUP_ALWAYS_RUN = MAKE_MENUENTRY( "Always run:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_GAMESETUP_ALWAYS_RUN, Option ); - -static char const *MEOSN_GAMESETUP_WEAPSWITCH_PICKUP[] = { "Never", "If new", /*"If favored",*/ }; -static MenuOptionSet_t MEOS_GAMESETUP_WEAPSWITCH_PICKUP = MAKE_MENUOPTIONSET( MEOSN_GAMESETUP_WEAPSWITCH_PICKUP, NULL, 0x2 ); -static MenuOption_t MEO_GAMESETUP_WEAPSWITCH_PICKUP = MAKE_MENUOPTION( &MF_Redfont, &MEOS_GAMESETUP_WEAPSWITCH_PICKUP, NULL ); -static MenuEntry_t ME_GAMESETUP_WEAPSWITCH_PICKUP = MAKE_MENUENTRY( "Equip pickups:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_GAMESETUP_WEAPSWITCH_PICKUP, Option ); - -static char const *MEOSN_DemoRec[] = { "Off", "Running", }; -static MenuOptionSet_t MEOS_DemoRec = MAKE_MENUOPTIONSET( MEOSN_DemoRec, NULL, 0x3 ); -static MenuOption_t MEO_GAMESETUP_DEMOREC = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &m_recstat ); -static MenuEntry_t ME_GAMESETUP_DEMOREC = MAKE_MENUENTRY( "Record demo:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_GAMESETUP_DEMOREC, Option ); - -static MenuOption_t MEO_ADULTMODE = MAKE_MENUOPTION(&MF_Redfont, &MEOS_OffOn, &adult_lockout); -static MenuEntry_t ME_ADULTMODE = MAKE_MENUENTRY( "Parental lock:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_ADULTMODE, Option ); - -#if defined(EDUKE32_ANDROID_MENU) || !defined(EDUKE32_SIMPLE_MENU) -static MenuLink_t MEO_GAMESETUP_CHEATS = { MENU_CHEATS, MA_Advance, }; -static MenuEntry_t ME_GAMESETUP_CHEATS = MAKE_MENUENTRY( "Cheats", &MF_Redfont, &MEF_BigOptionsRt, &MEO_GAMESETUP_CHEATS, Link ); - -static MenuEntry_t *MEL_GAMESETUP[] = { - &ME_ADULTMODE, -#if defined STARTUP_SETUP_WINDOW && !defined EDUKE32_SIMPLE_MENU - &ME_GAMESETUP_STARTWIN, -#endif -#ifndef EDUKE32_ANDROID_MENU - &ME_GAMESETUP_DEMOREC, -#endif - &ME_GAMESETUP_CHEATS, -}; -#endif - -#ifndef EDUKE32_SIMPLE_MENU -MAKE_MENU_TOP_ENTRYLINK( "Game Setup", MEF_OptionsMenu, OPTIONS_GAMESETUP, MENU_GAMESETUP ); -#endif -MAKE_MENU_TOP_ENTRYLINK( "Sound Setup", MEF_OptionsMenu, OPTIONS_SOUNDSETUP, MENU_SOUND ); -MAKE_MENU_TOP_ENTRYLINK( "Display Setup", MEF_OptionsMenu, OPTIONS_DISPLAYSETUP, MENU_DISPLAYSETUP ); -MAKE_MENU_TOP_ENTRYLINK( "Player Setup", MEF_OptionsMenu, OPTIONS_PLAYERSETUP, MENU_PLAYER ); -#ifndef EDUKE32_ANDROID_MENU -MAKE_MENU_TOP_ENTRYLINK( "Control Setup", MEF_OptionsMenu, OPTIONS_CONTROLS, MENU_CONTROLS ); - -MAKE_MENU_TOP_ENTRYLINK( "Configure Controls", MEF_BigOptionsRtSections, OPTIONS_KEYBOARDSETUP, MENU_KEYBOARDSETUP ); -MAKE_MENU_TOP_ENTRYLINK( "Mouse Setup", MEF_BigOptionsRtSections, OPTIONS_MOUSESETUP, MENU_MOUSESETUP ); -#endif -MAKE_MENU_TOP_ENTRYLINK( "Gamepad Setup", MEF_BigOptionsRtSections, OPTIONS_JOYSTICKSETUP, MENU_JOYSTICKSETUP ); -#ifdef EDUKE32_ANDROID_MENU -MAKE_MENU_TOP_ENTRYLINK( "Touch Setup", MEF_BigOptionsRtSections, OPTIONS_TOUCHSETUP, MENU_TOUCHSETUP ); -#endif -#ifdef EDUKE32_SIMPLE_MENU -MAKE_MENU_TOP_ENTRYLINK("Cheats", MEF_OptionsMenu, OPTIONS_CHEATS, MENU_CHEATS); -#endif // Zhe menu code lacks flexibility, it can either be hardwired to ints or to CVARs. // Since CVARs are more important it means that these need to be implemented as CVARs even though they are just temporaries. @@ -295,63 +127,8 @@ static MenuEntry_t ME_VIDEOSETUP_VSYNC = MAKE_MENUENTRY("VSync:", &MF_Redfont, & static MenuEntry_t ME_VIDEOSETUP_APPLY = MAKE_MENUENTRY( "Apply Changes", &MF_Redfont, &MEF_BigOptions_Apply, &MEO_NULL, Link ); -static MenuLink_t MEO_DISPLAYSETUP_COLORCORR = { MENU_COLCORR, MA_Advance, }; -static MenuEntry_t ME_DISPLAYSETUP_COLORCORR = MAKE_MENUENTRY( "Color Correction", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_COLORCORR, Link ); -#ifndef EDUKE32_ANDROID_MENU -static MenuOption_t MEO_DISPLAYSETUP_ASPECTRATIO = MAKE_MENUOPTION(&MF_Redfont, &MEOS_OffOn, &r_usenewaspect); -static MenuEntry_t ME_DISPLAYSETUP_ASPECTRATIO = MAKE_MENUENTRY( "Widescreen:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_ASPECTRATIO, Option ); -#endif - -static MenuOption_t MEO_DISPLAYSETUP_VOXELS = MAKE_MENUOPTION(&MF_Redfont, &MEOS_OffOn, &r_voxels); -static MenuEntry_t ME_DISPLAYSETUP_VOXELS = MAKE_MENUENTRY( "Voxels:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_VOXELS, Option ); - -static MenuRangeInt32_t MEO_DISPLAYSETUP_FOV = MAKE_MENURANGE( &r_fov, &MF_Redfont, 70, 120, 0, 11, 1 ); -static MenuEntry_t ME_DISPLAYSETUP_FOV = MAKE_MENUENTRY( "FOV:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_FOV, RangeInt32 ); - - -#ifdef USE_OPENGL -static char const *MEOSN_DISPLAYSETUP_TEXFILTER[] = { "Classic", "Filtered" }; -static int32_t MEOSV_DISPLAYSETUP_TEXFILTER[] = { TEXFILTER_OFF, TEXFILTER_ON }; -static MenuOptionSet_t MEOS_DISPLAYSETUP_TEXFILTER = MAKE_MENUOPTIONSET( MEOSN_DISPLAYSETUP_TEXFILTER, MEOSV_DISPLAYSETUP_TEXFILTER, 0x2 ); -static MenuOption_t MEO_DISPLAYSETUP_TEXFILTER = MAKE_MENUOPTION( &MF_Redfont, &MEOS_DISPLAYSETUP_TEXFILTER, &hw_texfilter ); -static MenuEntry_t ME_DISPLAYSETUP_TEXFILTER = MAKE_MENUENTRY( "Texture Mode:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_TEXFILTER, Option ); - -static char const *MEOSN_DISPLAYSETUP_ANISOTROPY[] = { "Max", "None", "2x", "4x", "8x", "16x", }; -static int32_t MEOSV_DISPLAYSETUP_ANISOTROPY[] = { 0, 1, 2, 4, 8, 16, }; -static MenuOptionSet_t MEOS_DISPLAYSETUP_ANISOTROPY = MAKE_MENUOPTIONSET( MEOSN_DISPLAYSETUP_ANISOTROPY, MEOSV_DISPLAYSETUP_ANISOTROPY, 0x0 ); -static MenuOption_t MEO_DISPLAYSETUP_ANISOTROPY = MAKE_MENUOPTION(&MF_Redfont, &MEOS_DISPLAYSETUP_ANISOTROPY, &hw_anisotropy); -static MenuEntry_t ME_DISPLAYSETUP_ANISOTROPY = MAKE_MENUENTRY( "Anisotropy:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_ANISOTROPY, Option ); - -#endif - -static char const s_Scale[] = "Scale:"; - -static MenuOption_t MEO_SCREENSETUP_CROSSHAIR = MAKE_MENUOPTION(&MF_Redfont, &MEOS_OffOn, &cl_crosshair); -static MenuEntry_t ME_SCREENSETUP_CROSSHAIR = MAKE_MENUENTRY( "Crosshair:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SCREENSETUP_CROSSHAIR, Option ); -static MenuRangeInt32_t MEO_SCREENSETUP_CROSSHAIRSIZE = MAKE_MENURANGE( &cl_crosshairscale, &MF_Redfont, 25, 100, 0, 16, 2 ); -static MenuEntry_t ME_SCREENSETUP_CROSSHAIRSIZE = MAKE_MENUENTRY( s_Scale, &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SCREENSETUP_CROSSHAIRSIZE, RangeInt32 ); - -static MenuRangeInt32_t MEO_SCREENSETUP_SCREENSIZE = MAKE_MENURANGE( &hud_size, &MF_Redfont, 0, 11, 0, 1, EnforceIntervals ); -static MenuOption_t MEO_SCREENSETUP_SCREENSIZE_TWO = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &hud_size ); -static MenuEntry_t ME_SCREENSETUP_SCREENSIZE = MAKE_MENUENTRY( "Status bar:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SCREENSETUP_SCREENSIZE, RangeInt32 ); -static MenuRangeInt32_t MEO_SCREENSETUP_TEXTSIZE = MAKE_MENURANGE( &hud_textscale, &MF_Redfont, 100, 400, 0, 16, 2 ); -static MenuEntry_t ME_SCREENSETUP_TEXTSIZE = MAKE_MENUENTRY( s_Scale, &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SCREENSETUP_TEXTSIZE, RangeInt32 ); -static MenuOption_t MEO_SCREENSETUP_LEVELSTATS = MAKE_MENUOPTION(&MF_Redfont, &MEOS_OffOn, &hud_stats); -static MenuEntry_t ME_SCREENSETUP_LEVELSTATS = MAKE_MENUENTRY( "Level stats:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SCREENSETUP_LEVELSTATS, Option ); - - -static MenuOption_t MEO_SCREENSETUP_SHOWPICKUPMESSAGES = MAKE_MENUOPTION(&MF_Redfont, &MEOS_OffOn, &hud_messages); -static MenuEntry_t ME_SCREENSETUP_SHOWPICKUPMESSAGES = MAKE_MENUENTRY( "Game messages:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SCREENSETUP_SHOWPICKUPMESSAGES, Option ); - -static MenuRangeInt32_t MEO_SCREENSETUP_SBARSIZE = MAKE_MENURANGE( &hud_scale, &MF_Redfont, 50, 100, 0, 10, 2 ); -static MenuEntry_t ME_SCREENSETUP_SBARSIZE = MAKE_MENUENTRY( s_Scale, &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SCREENSETUP_SBARSIZE, RangeInt32 ); - - -static MenuLink_t MEO_DISPLAYSETUP_SCREENSETUP = { MENU_SCREENSETUP, MA_Advance, }; -static MenuEntry_t ME_DISPLAYSETUP_SCREENSETUP = MAKE_MENUENTRY( "HUD setup", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_SCREENSETUP, Link ); - #ifdef USE_OPENGL static MenuLink_t MEO_DISPLAYSETUP_ADVANCED_GL_POLYMOST = { MENU_POLYMOST, MA_Advance, }; @@ -446,225 +223,6 @@ static MenuEntry_t *MEL_DISPLAYSETUP_GL[] = { -static char const MenuKeyNone[] = " -"; -static char const *MEOSN_Keys[NUMKEYS]; - -static MenuCustom2Col_t MEO_KEYBOARDSETUPFUNCS_TEMPLATE = { 0, &MF_Minifont, NUMKEYS, 54<<16, 0 }; -static MenuCustom2Col_t MEO_KEYBOARDSETUPFUNCS[NUMGAMEFUNCTIONS]; -static MenuEntry_t ME_KEYBOARDSETUPFUNCS_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Minifont, &MEF_KBFuncList, &MEO_KEYBOARDSETUPFUNCS_TEMPLATE, Custom2Col ); -static MenuEntry_t ME_KEYBOARDSETUPFUNCS[NUMGAMEFUNCTIONS]; -static MenuEntry_t *MEL_KEYBOARDSETUPFUNCS[NUMGAMEFUNCTIONS]; - -static MenuLink_t MEO_KEYBOARDSETUP_KEYS = { MENU_KEYBOARDKEYS, MA_Advance, }; -static MenuEntry_t ME_KEYBOARDSETUP_KEYS = MAKE_MENUENTRY( "Edit Configuration", &MF_Redfont, &MEF_CenterMenu, &MEO_KEYBOARDSETUP_KEYS, Link ); -static MenuLink_t MEO_KEYBOARDSETUP_RESET = { MENU_KEYSRESETVERIFY, MA_None, }; -static MenuEntry_t ME_KEYBOARDSETUP_RESET = MAKE_MENUENTRY( "Reset To Defaults", &MF_Redfont, &MEF_CenterMenu, &MEO_KEYBOARDSETUP_RESET, Link ); -static MenuLink_t MEO_KEYBOARDSETUP_RESETCLASSIC = { MENU_KEYSCLASSICVERIFY, MA_None, }; -static MenuEntry_t ME_KEYBOARDSETUP_RESETCLASSIC = MAKE_MENUENTRY( "Reset To Classic", &MF_Redfont, &MEF_CenterMenu, &MEO_KEYBOARDSETUP_RESETCLASSIC, Link ); - -static MenuEntry_t *MEL_KEYBOARDSETUP[] = { - &ME_KEYBOARDSETUP_KEYS, - &ME_KEYBOARDSETUP_RESET, - &ME_KEYBOARDSETUP_RESETCLASSIC, -}; - - -// There is no better way to do this than manually. - -#define MENUMOUSEFUNCTIONS 12 - -static char const *MenuMouseNames[MENUMOUSEFUNCTIONS] = { - "Button 1", - "Double Button 1", - "Button 2", - "Double Button 2", - "Button 3", - "Double Button 3", - - "Wheel Up", - "Wheel Down", - - "Button 4", - "Double Button 4", - "Button 5", - "Double Button 5", -}; -static int32_t MenuMouseDataIndex[MENUMOUSEFUNCTIONS][2] = { - { 0, 0, }, - { 0, 1, }, - { 1, 0, }, - { 1, 1, }, - { 2, 0, }, - { 2, 1, }, - - // note the mouse wheel - { 4, 0, }, - { 5, 0, }, - - { 3, 0, }, - { 3, 1, }, - { 6, 0, }, - { 6, 1, }, -}; - -static MenuOption_t MEO_MOUSEJOYSETUPBTNS_TEMPLATE = MAKE_MENUOPTION( &MF_Minifont, &MEOS_Gamefuncs, NULL ); -static MenuOption_t MEO_MOUSESETUPBTNS[MENUMOUSEFUNCTIONS]; -static MenuEntry_t ME_MOUSEJOYSETUPBTNS_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Minifont, &MEF_FuncList, NULL, Option ); - -static MenuRangeFloat_t MEO_MOUSESETUP_SENSITIVITY = MAKE_MENURANGE( &in_mousesensitivity, &MF_Redfont, .5f, 16.f, 0.f, 32, 1 ); -static MenuEntry_t ME_MOUSESETUP_SENSITIVITY = MAKE_MENUENTRY( "Sensitivity:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSESETUP_SENSITIVITY, RangeFloat ); - -#ifndef EDUKE32_SIMPLE_MENU -static char const *MEOSN_MOUSESETUP_AIM_TYPE [] = { "Toggle", "Hold" }; -static MenuOptionSet_t MEOS_MOUSESETUP_AIM_TYPE = MAKE_MENUOPTIONSET(MEOSN_MOUSESETUP_AIM_TYPE, NULL, 0x2); -static MenuOption_t MEO_MOUSESETUP_MOUSEAIMINGTYPE = MAKE_MENUOPTION(&MF_Redfont, &MEOS_MOUSESETUP_AIM_TYPE, &in_aimmode); -static MenuEntry_t ME_MOUSESETUP_MOUSEAIMINGTYPE = MAKE_MENUENTRY("Aiming type:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSESETUP_MOUSEAIMINGTYPE, Option); -static MenuOption_t MEO_MOUSESETUP_MOUSEAIMING = MAKE_MENUOPTION( &MF_Redfont, &MEOS_NoYes, &in_mousemode ); -static MenuEntry_t ME_MOUSESETUP_MOUSEAIMING = MAKE_MENUENTRY( "Vertical aiming:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSESETUP_MOUSEAIMING, Option ); -#endif -static MenuOption_t MEO_MOUSESETUP_INVERT = MAKE_MENUOPTION( &MF_Redfont, &MEOS_YesNo, &in_mouseflip ); -static MenuEntry_t ME_MOUSESETUP_INVERT = MAKE_MENUENTRY( "Invert aiming:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSESETUP_INVERT, Option ); -static MenuOption_t MEO_MOUSESETUP_SMOOTH = MAKE_MENUOPTION( &MF_Redfont, &MEOS_NoYes, &in_mousesmoothing ); -static MenuEntry_t ME_MOUSESETUP_SMOOTH = MAKE_MENUENTRY( "Filter input:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSESETUP_SMOOTH, Option ); -#ifndef EDUKE32_SIMPLE_MENU -static MenuLink_t MEO_MOUSESETUP_ADVANCED = { MENU_MOUSEADVANCED, MA_Advance, }; -static MenuEntry_t ME_MOUSESETUP_ADVANCED = MAKE_MENUENTRY( "Advanced setup", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSESETUP_ADVANCED, Link ); -#endif -static MenuRangeInt32_t MEO_MOUSEADVANCED_SCALEX = MAKE_MENURANGE(&in_mousescalex, &MF_Redfont, -262144, 262144, 65536, 161, 3); -static MenuEntry_t ME_MOUSEADVANCED_SCALEX = MAKE_MENUENTRY("X-Scale:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSEADVANCED_SCALEX, RangeInt32); -static MenuRangeInt32_t MEO_MOUSEADVANCED_SCALEY = MAKE_MENURANGE(&in_mousescaley, &MF_Redfont, -262144, 262144, 65536, 161, 3); -static MenuEntry_t ME_MOUSEADVANCED_SCALEY = MAKE_MENUENTRY("Y-Scale:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSEADVANCED_SCALEY, RangeInt32); - -static MenuEntry_t *MEL_MOUSESETUP[] = { - &ME_MOUSESETUP_SENSITIVITY, -#ifdef EDUKE32_SIMPLE_MENU - &ME_MOUSEADVANCED_SCALEX, - &ME_MOUSEADVANCED_SCALEY, -#endif - &ME_Space2_Redfont, - &ME_MOUSESETUP_INVERT, - &ME_MOUSESETUP_SMOOTH, -#ifndef EDUKE32_SIMPLE_MENU - &ME_MOUSESETUP_MOUSEAIMINGTYPE, - &ME_MOUSESETUP_MOUSEAIMING, - &ME_MOUSESETUP_ADVANCED, -#endif -}; - -#ifdef EDUKE32_ANDROID_MENU -static MenuRangeFloat_t MEO_TOUCHSETUP_SENSITIVITY_MOVE = MAKE_MENURANGE(&droidinput.forward_sens, &MF_Redfont, 1.f, 9.f, 0.f, 17, 1 + EnforceIntervals); -static MenuEntry_t ME_TOUCHSETUP_SENSITIVITY_MOVE = MAKE_MENUENTRY("Running:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_TOUCHSETUP_SENSITIVITY_MOVE, RangeFloat); - -static MenuRangeFloat_t MEO_TOUCHSETUP_SENSITIVITY_STRAFE = MAKE_MENURANGE(&droidinput.strafe_sens, &MF_Redfont, 1.f, 9.f, 0.f, 17, 1 + EnforceIntervals); -static MenuEntry_t ME_TOUCHSETUP_SENSITIVITY_STRAFE = MAKE_MENUENTRY("Strafing:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_TOUCHSETUP_SENSITIVITY_STRAFE, RangeFloat); - -static MenuRangeFloat_t MEO_TOUCHSETUP_SENSITIVITY_LOOK = MAKE_MENURANGE(&droidinput.pitch_sens, &MF_Redfont, 1.f, 9.f, 0.f, 17, 1 + EnforceIntervals); -static MenuEntry_t ME_TOUCHSETUP_SENSITIVITY_LOOK = MAKE_MENUENTRY("Looking:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_TOUCHSETUP_SENSITIVITY_LOOK, RangeFloat); - -static MenuRangeFloat_t MEO_TOUCHSETUP_SENSITIVITY_TURN = MAKE_MENURANGE(&droidinput.yaw_sens, &MF_Redfont, 1.f, 9.f, 0.f, 17, 1 + EnforceIntervals); -static MenuEntry_t ME_TOUCHSETUP_SENSITIVITY_TURN = MAKE_MENUENTRY("Turning:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_TOUCHSETUP_SENSITIVITY_TURN, RangeFloat); - -static MenuOption_t MEO_TOUCHSETUP_INVERT = MAKE_MENUOPTION(&MF_Redfont, &MEOS_NoYes, &droidinput.invertLook); -static MenuEntry_t ME_TOUCHSETUP_INVERT = MAKE_MENUENTRY("Invert look:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_TOUCHSETUP_INVERT, Option); - -MAKE_MENU_TOP_ENTRYLINK("Sensitivity", MEF_CenterMenu, TOUCHSENS, MENU_TOUCHSENS); -MAKE_MENU_TOP_ENTRYLINK("Button Setup", MEF_CenterMenu, TOUCHBUTTONS, MENU_TOUCHBUTTONS); - -static MenuEntry_t *MEL_TOUCHSETUP [] = { - &ME_TOUCHSENS, - &ME_TOUCHBUTTONS, -}; - -static MenuEntry_t *MEL_TOUCHSENS [] = { - &ME_TOUCHSETUP_SENSITIVITY_MOVE, - &ME_TOUCHSETUP_SENSITIVITY_STRAFE, - &ME_TOUCHSETUP_SENSITIVITY_LOOK, - &ME_TOUCHSETUP_SENSITIVITY_TURN, - &ME_Space2_Redfont, - &ME_TOUCHSETUP_INVERT, -}; -#endif - -static MenuOption_t MEO_JOYSTICK_ENABLE = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &in_joystick ); -static MenuEntry_t ME_JOYSTICK_ENABLE = MAKE_MENUENTRY( "Enable Gamepad:", &MF_Redfont, &MEF_BigOptionsRtSections, &MEO_JOYSTICK_ENABLE, Option ); - -MAKE_MENU_TOP_ENTRYLINK( "Edit Buttons", MEF_BigOptionsRtSections, JOYSTICK_EDITBUTTONS, MENU_JOYSTICKBTNS ); -MAKE_MENU_TOP_ENTRYLINK( "Edit Axes", MEF_BigOptionsRtSections, JOYSTICK_EDITAXES, MENU_JOYSTICKAXES ); - -static MenuLink_t MEO_JOYSTICK_DEFAULTS_STANDARD = { MENU_JOYSTANDARDVERIFY, MA_None, }; -static MenuEntry_t ME_JOYSTICK_DEFAULTS_STANDARD = MAKE_MENUENTRY( "Use Standard Layout", &MF_Redfont, &MEF_BigOptionsRtSections, &MEO_JOYSTICK_DEFAULTS_STANDARD, Link ); -static MenuLink_t MEO_JOYSTICK_DEFAULTS_PRO = { MENU_JOYPROVERIFY, MA_None, }; -static MenuEntry_t ME_JOYSTICK_DEFAULTS_PRO = MAKE_MENUENTRY( "Use Pro Layout", &MF_Redfont, &MEF_BigOptionsRtSections, &MEO_JOYSTICK_DEFAULTS_PRO, Link ); -static MenuLink_t MEO_JOYSTICK_DEFAULTS_CLEAR = { MENU_JOYCLEARVERIFY, MA_None, }; -static MenuEntry_t ME_JOYSTICK_DEFAULTS_CLEAR = MAKE_MENUENTRY( "Clear All Settings", &MF_Redfont, &MEF_BigOptionsRtSections, &MEO_JOYSTICK_DEFAULTS_CLEAR, Link ); - -static MenuEntry_t *MEL_JOYSTICKSETUP[] = { - &ME_JOYSTICK_ENABLE, - &ME_Space6_Redfont, - &ME_JOYSTICK_EDITBUTTONS, - &ME_JOYSTICK_EDITAXES, - &ME_Space6_Redfont, - &ME_JOYSTICK_DEFAULTS_STANDARD, - &ME_JOYSTICK_DEFAULTS_PRO, - &ME_JOYSTICK_DEFAULTS_CLEAR, -}; - -#define MAXJOYBUTTONSTRINGLENGTH 32 - -static char MenuJoystickNames[MAXJOYBUTTONSANDHATS*2][MAXJOYBUTTONSTRINGLENGTH]; - -static MenuOption_t MEO_JOYSTICKBTNS[MAXJOYBUTTONSANDHATS*2]; -static MenuEntry_t ME_JOYSTICKBTNS[MAXJOYBUTTONSANDHATS*2]; -static MenuEntry_t *MEL_JOYSTICKBTNS[MAXJOYBUTTONSANDHATS*2]; - -static MenuLink_t MEO_JOYSTICKAXES = { MENU_JOYSTICKAXIS, MA_Advance, }; -static MenuEntry_t ME_JOYSTICKAXES_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_BigSliders, &MEO_JOYSTICKAXES, Link ); -static MenuEntry_t ME_JOYSTICKAXES[MAXJOYAXES]; -static char MenuJoystickAxes[MAXJOYAXES][MAXJOYBUTTONSTRINGLENGTH]; - -static MenuEntry_t *MEL_JOYSTICKAXES[MAXJOYAXES]; - -static MenuEntry_t *MEL_MOUSEADVANCED[] = { - &ME_MOUSEADVANCED_SCALEX, - &ME_MOUSEADVANCED_SCALEY, -}; - -static const char *MenuJoystickHatDirections[] = { "Up", "Right", "Down", "Left", }; - -static char const *MEOSN_JOYSTICKAXIS_ANALOG[] = { " -None-", "Turning", "Strafing", "Looking", "Moving", }; -static int32_t MEOSV_JOYSTICKAXIS_ANALOG[] = { -1, analog_turning, analog_strafing, analog_lookingupanddown, analog_moving, }; -static MenuOptionSet_t MEOS_JOYSTICKAXIS_ANALOG = MAKE_MENUOPTIONSET( MEOSN_JOYSTICKAXIS_ANALOG, MEOSV_JOYSTICKAXIS_ANALOG, 0x0 ); -static MenuOption_t MEO_JOYSTICKAXIS_ANALOG = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_JOYSTICKAXIS_ANALOG, NULL ); -static MenuEntry_t ME_JOYSTICKAXIS_ANALOG = MAKE_MENUENTRY( "Analog", &MF_Redfont, &MEF_BigSliders, &MEO_JOYSTICKAXIS_ANALOG, Option ); -static MenuRangeInt32_t MEO_JOYSTICKAXIS_SCALE = MAKE_MENURANGE( NULL, &MF_Bluefont, -262144, 262144, 65536, 161, 3 ); -static MenuEntry_t ME_JOYSTICKAXIS_SCALE = MAKE_MENUENTRY( "Scale", &MF_Redfont, &MEF_BigSliders, &MEO_JOYSTICKAXIS_SCALE, RangeInt32 ); -static MenuOption_t MEO_JOYSTICKAXIS_INVERT = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, NULL ); -static MenuEntry_t ME_JOYSTICKAXIS_INVERT = MAKE_MENUENTRY( "Invert", &MF_Redfont, &MEF_BigSliders, &MEO_JOYSTICKAXIS_INVERT, Option ); -static MenuRangeInt32_t MEO_JOYSTICKAXIS_DEAD = MAKE_MENURANGE( NULL, &MF_Bluefont, 0, 10000, 0, 101, 2 ); -static MenuEntry_t ME_JOYSTICKAXIS_DEAD = MAKE_MENUENTRY( "Dead Zone", &MF_Redfont, &MEF_BigSliders, &MEO_JOYSTICKAXIS_DEAD, RangeInt32 ); -static MenuRangeInt32_t MEO_JOYSTICKAXIS_SATU = MAKE_MENURANGE( NULL, &MF_Bluefont, 0, 10000, 0, 101, 2 ); -static MenuEntry_t ME_JOYSTICKAXIS_SATU = MAKE_MENUENTRY( "Saturation", &MF_Redfont, &MEF_BigSliders, &MEO_JOYSTICKAXIS_SATU, RangeInt32 ); - -static MenuOption_t MEO_JOYSTICKAXIS_DIGITALNEGATIVE = MAKE_MENUOPTION( &MF_Minifont, &MEOS_Gamefuncs, NULL ); -static MenuEntry_t ME_JOYSTICKAXIS_DIGITALNEGATIVE = MAKE_MENUENTRY( "Digital -", &MF_Bluefont, &MEF_BigSliders, &MEO_JOYSTICKAXIS_DIGITALNEGATIVE, Option ); -static MenuOption_t MEO_JOYSTICKAXIS_DIGITALPOSITIVE = MAKE_MENUOPTION( &MF_Minifont, &MEOS_Gamefuncs, NULL ); -static MenuEntry_t ME_JOYSTICKAXIS_DIGITALPOSITIVE = MAKE_MENUENTRY( "Digital +", &MF_Bluefont, &MEF_BigSliders, &MEO_JOYSTICKAXIS_DIGITALPOSITIVE, Option ); - -static MenuEntry_t *MEL_JOYSTICKAXIS[] = { - &ME_JOYSTICKAXIS_ANALOG, - &ME_JOYSTICKAXIS_SCALE, - &ME_JOYSTICKAXIS_INVERT, - &ME_JOYSTICKAXIS_DEAD, - &ME_JOYSTICKAXIS_SATU, - &ME_Space8_Redfont, - &ME_JOYSTICKAXIS_DIGITALNEGATIVE, - &ME_JOYSTICKAXIS_DIGITALPOSITIVE, -}; - -static MenuEntry_t *MEL_INTERNAL_JOYSTICKAXIS_DIGITAL[] = { - &ME_JOYSTICKAXIS_DIGITALNEGATIVE, - &ME_JOYSTICKAXIS_DIGITALPOSITIVE, -}; #ifdef USE_OPENGL static MenuOption_t MEO_RENDERERSETUP_HIGHTILE = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NoYes, &hw_hightile ); @@ -702,14 +260,6 @@ static MenuEntry_t *MEL_RENDERERSETUP_POLYMOST[] = { #endif -static MenuRangeFloat_t MEO_COLCORR_GAMMA = MAKE_MENURANGE( &vid_gamma, &MF_Bluefont, 0.3f, 4.f, 0.f, 75, 1 ); -static MenuEntry_t ME_COLCORR_GAMMA = MAKE_MENUENTRY( "Gamma:", &MF_Redfont, &MEF_ColorCorrect, &MEO_COLCORR_GAMMA, RangeFloat ); -static MenuRangeFloat_t MEO_COLCORR_CONTRAST = MAKE_MENURANGE( &vid_contrast, &MF_Bluefont, 0.1f, 2.7f, 0.f, 53, 1 ); -static MenuEntry_t ME_COLCORR_CONTRAST = MAKE_MENUENTRY( "Contrast:", &MF_Redfont, &MEF_ColorCorrect, &MEO_COLCORR_CONTRAST, RangeFloat ); -static MenuRangeFloat_t MEO_COLCORR_BRIGHTNESS = MAKE_MENURANGE( &vid_brightness, &MF_Bluefont, -0.8f, 0.8f, 0.f, 33, 1 ); -static MenuEntry_t ME_COLCORR_BRIGHTNESS = MAKE_MENUENTRY( "Brightness:", &MF_Redfont, &MEF_ColorCorrect, &MEO_COLCORR_BRIGHTNESS, RangeFloat ); -static MenuLink_t MEO_COLCORR_RESET = { MENU_COLCORRRESETVERIFY, MA_None, }; -static MenuEntry_t ME_COLCORR_RESET = MAKE_MENUENTRY( "Reset To Defaults", &MF_Redfont, &MEF_ColorCorrect, &MEO_COLCORR_RESET, Link ); #ifdef EDUKE32_ANDROID_MENU #define MINVIS 1.f #else @@ -748,22 +298,6 @@ static MenuEntry_t *MEL_SCREENSETUP[] = { &ME_SCREENSETUP_SHOWPICKUPMESSAGES, }; -// Save and load will be filled in before every viewing of the save/load screen. -static MenuLink_t MEO_LOAD = { MENU_LOADVERIFY, MA_None, }; -static MenuEntry_t ME_LOAD_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Minifont, &MEF_LoadSave, &MEO_LOAD, Link ); -static MenuEntry_t ME_LOAD_EMPTY = MAKE_MENUENTRY( NULL, &MF_Minifont, &MEF_LoadSave, nullptr, Dummy ); -static MenuEntry_t *ME_LOAD; -static MenuEntry_t **MEL_LOAD; - -static char const s_NewSaveGame[] = "(New Save Game)"; -static MenuString_t MEO_SAVE_TEMPLATE = MAKE_MENUSTRING( NULL, &MF_Minifont, MAXSAVEGAMENAME, 0 ); -static MenuString_t MEO_SAVE_NEW = MAKE_MENUSTRING( NULL, &MF_Minifont, MAXSAVEGAMENAME, 0 ); -static MenuString_t *MEO_SAVE; -static MenuEntry_t ME_SAVE_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Minifont, &MEF_LoadSave, &MEO_SAVE_TEMPLATE, String ); -static MenuEntry_t ME_SAVE_NEW = MAKE_MENUENTRY( s_NewSaveGame, &MF_Minifont, &MEF_LoadSave, &MEO_SAVE_NEW, String ); -static MenuEntry_t *ME_SAVE; -static MenuEntry_t **MEL_SAVE; - CVAR_UNAMED(Int, soundrate) CVAR_UNAMED(Int, soundvoices) CVAR_UNAMED(Int, musicdevice) @@ -865,123 +399,6 @@ static MenuEntry_t *MEL_SAVESETUP[] = { }; -MAKE_MENU_TOP_ENTRYLINK( "Player Setup", MEF_CenterMenu, NETWORK_PLAYERSETUP, MENU_PLAYER ); -MAKE_MENU_TOP_ENTRYLINK( "Join Game", MEF_CenterMenu, NETWORK_JOINGAME, MENU_NETJOIN ); -MAKE_MENU_TOP_ENTRYLINK( "Host Game", MEF_CenterMenu, NETWORK_HOSTGAME, MENU_NETHOST ); - -static MenuEntry_t *MEL_NETWORK[] = { - &ME_NETWORK_PLAYERSETUP, - &ME_NETWORK_JOINGAME, - &ME_NETWORK_HOSTGAME, -}; - -//static MenuString_t MEO_PLAYER_NAME = MAKE_MENUSTRING( playername, &MF_Bluefont, MAXPLAYERNAME, 0 ); -//static MenuEntry_t ME_PLAYER_NAME = MAKE_MENUENTRY( "Name", &MF_Bluefont, &MEF_PlayerNarrow, &MEO_PLAYER_NAME, String ); -static char const *MEOSN_PLAYER_COLOR[] = { "Auto", "Blue", "Red", "Green", "Gray", "Dark gray", "Dark green", "Brown", "Dark blue", "Bright red", "Yellow", }; -static int32_t MEOSV_PLAYER_COLOR[] = { 0, 9, 10, 11, 12, 13, 14, 15, 16, 21, 23, }; -static MenuOptionSet_t MEOS_PLAYER_COLOR = MAKE_MENUOPTIONSET( MEOSN_PLAYER_COLOR, MEOSV_PLAYER_COLOR, 0x2 ); -static MenuOption_t MEO_PLAYER_COLOR = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_PLAYER_COLOR, &playercolor ); -static MenuEntry_t ME_PLAYER_COLOR = MAKE_MENUENTRY( "Color", &MF_Bluefont, &MEF_PlayerNarrow, &MEO_PLAYER_COLOR, Option ); -static char const *MEOSN_PLAYER_TEAM[] = { "Blue", "Red", "Green", "Gray", }; -static MenuOptionSet_t MEOS_PLAYER_TEAM = MAKE_MENUOPTIONSET( MEOSN_PLAYER_TEAM, NULL, 0x2 ); -static MenuOption_t MEO_PLAYER_TEAM = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_PLAYER_TEAM, &playerteam ); -static MenuEntry_t ME_PLAYER_TEAM = MAKE_MENUENTRY( "Team", &MF_Bluefont, &MEF_PlayerNarrow, &MEO_PLAYER_TEAM, Option ); -#ifndef EDUKE32_SIMPLE_MENU -static MenuLink_t MEO_PLAYER_MACROS = { MENU_MACROS, MA_Advance, }; -static MenuEntry_t ME_PLAYER_MACROS = MAKE_MENUENTRY( "Multiplayer macros", &MF_Bluefont, &MEF_SmallOptions, &MEO_PLAYER_MACROS, Link ); -#endif - -static MenuEntry_t *MEL_PLAYER[] = { - //&ME_PLAYER_NAME, - &ME_Space4_Bluefont, - &ME_PLAYER_COLOR, - &ME_Space4_Bluefont, - &ME_PLAYER_TEAM, -#ifndef EDUKE32_SIMPLE_MENU - &ME_Space8_Bluefont, - &ME_PLAYER_MACROS, -#endif -}; - -#define MAXRIDECULE 10 -#define MAXRIDECULELENGTH 40 -static MenuString_t MEO_MACROS_TEMPLATE = MAKE_MENUSTRING( NULL, &MF_Bluefont, MAXRIDECULELENGTH, 0 ); -static MenuString_t MEO_MACROS[10]; -static MenuEntry_t ME_MACROS_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Bluefont, &MEF_Macros, &MEO_MACROS_TEMPLATE, String ); -static char sink[50]; -static MenuEntry_t ME_MACROS[MAXRIDECULE]; -static MenuEntry_t *MEL_MACROS[MAXRIDECULE]; - -#ifndef EDUKE32_SIMPLE_MENU -static char const *MenuUserMap = "User Map"; -#endif -static char const *MenuSkillNone = "None"; - -static char const *MEOSN_NetGametypes[MAXGAMETYPES]; -static char const *MEOSN_NetEpisodes[MAXVOLUMES+1]; -static int32_t MEOSV_NetEpisodes[MAXVOLUMES+1]; -static char const *MEOSN_NetLevels[MAXVOLUMES][MAXLEVELS]; -static char const *MEOSN_NetSkills[MAXSKILLS+1]; - -static MenuLink_t MEO_NETHOST_OPTIONS = { MENU_NETOPTIONS, MA_Advance, }; -static MenuEntry_t ME_NETHOST_OPTIONS = MAKE_MENUENTRY( "Game Options", &MF_Redfont, &MEF_VideoSetup, &MEO_NETHOST_OPTIONS, Link ); -static MenuEntry_t ME_NETHOST_LAUNCH = MAKE_MENUENTRY( "Launch Game", &MF_Redfont, &MEF_VideoSetup, &MEO_NULL, Link ); - -static MenuEntry_t *MEL_NETHOST[] = { - &ME_NETHOST_OPTIONS, - &ME_NETHOST_LAUNCH, -}; - -static MenuOptionSet_t MEOS_NETOPTIONS_GAMETYPE = MAKE_MENUOPTIONSET( MEOSN_NetGametypes, NULL, 0x0 ); -static MenuOption_t MEO_NETOPTIONS_GAMETYPE = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NETOPTIONS_GAMETYPE, &m_coop ); -static MenuEntry_t ME_NETOPTIONS_GAMETYPE = MAKE_MENUENTRY( "Game Type", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_GAMETYPE, Option ); -static MenuOptionSet_t MEOS_NETOPTIONS_EPISODE = MAKE_MENUOPTIONSET( MEOSN_NetEpisodes, MEOSV_NetEpisodes, 0x0 ); -CVAR_UNAMED(Int, NetEpisode); -static MenuOption_t MEO_NETOPTIONS_EPISODE = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NETOPTIONS_EPISODE, &NetEpisode ); -static MenuEntry_t ME_NETOPTIONS_EPISODE = MAKE_MENUENTRY( "Episode", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_EPISODE, Option ); -static MenuOptionSet_t MEOS_NETOPTIONS_LEVEL_TEMPLATE = MAKE_MENUOPTIONSETNULL; -static MenuOptionSet_t MEOS_NETOPTIONS_LEVEL[MAXVOLUMES]; -static MenuOption_t MEO_NETOPTIONS_LEVEL = MAKE_MENUOPTION( &MF_Bluefont, NULL, &m_level_number ); -static MenuEntry_t ME_NETOPTIONS_LEVEL = MAKE_MENUENTRY( "Level", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_LEVEL, Option ); -static MenuLink_t MEO_NETOPTIONS_USERMAP = { MENU_NETUSERMAP, MA_Advance, }; -static MenuEntry_t ME_NETOPTIONS_USERMAP = MAKE_MENUENTRY( "User Map", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_USERMAP, Link ); -static MenuOptionSet_t MEOS_NETOPTIONS_MONSTERS = MAKE_MENUOPTIONSET( MEOSN_NetSkills, NULL, 0x0 ); -static MenuOption_t MEO_NETOPTIONS_MONSTERS = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NETOPTIONS_MONSTERS, NULL ); -static MenuEntry_t ME_NETOPTIONS_MONSTERS = MAKE_MENUENTRY( "Monsters", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_MONSTERS, Option ); -static MenuOption_t MEO_NETOPTIONS_MARKERS = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_OffOn, &m_marker ); -static MenuEntry_t ME_NETOPTIONS_MARKERS = MAKE_MENUENTRY( "Markers", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_MARKERS, Option ); -static MenuOption_t MEO_NETOPTIONS_MAPEXITS = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_OnOff, &m_noexits ); -static MenuEntry_t ME_NETOPTIONS_MAPEXITS = MAKE_MENUENTRY( "Map Exits", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_MAPEXITS, Option ); -static MenuOption_t MEO_NETOPTIONS_FRFIRE = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_OffOn, &m_ffire ); -static MenuEntry_t ME_NETOPTIONS_FRFIRE = MAKE_MENUENTRY( "Fr. Fire", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_FRFIRE, Option ); -static MenuEntry_t ME_NETOPTIONS_ACCEPT = MAKE_MENUENTRY( "Accept", &MF_Redfont, &MEF_NetSetup_Confirm, &MEO_NETWORK_HOSTGAME, Link ); - -static MenuEntry_t *MEL_NETOPTIONS[] = { - &ME_NETOPTIONS_GAMETYPE, - &ME_NETOPTIONS_EPISODE, - &ME_NETOPTIONS_LEVEL, - &ME_NETOPTIONS_MONSTERS, - &ME_NETOPTIONS_MARKERS, - &ME_NETOPTIONS_MAPEXITS, - &ME_NETOPTIONS_ACCEPT, -}; - -static char MenuServer[BMAX_PATH] = "localhost"; -static MenuString_t MEO_NETJOIN_SERVER = MAKE_MENUSTRING( MenuServer, &MF_Bluefont, BMAX_PATH, 0 ); -static MenuEntry_t ME_NETJOIN_SERVER = MAKE_MENUENTRY( "Server", &MF_Redfont, &MEF_VideoSetup, &MEO_NETJOIN_SERVER, String ); -#define MAXPORTSTRINGLENGTH 6 // unsigned 16-bit integer -static char MenuPort[MAXPORTSTRINGLENGTH] = "19014"; -static MenuString_t MEO_NETJOIN_PORT = MAKE_MENUSTRING( MenuPort, &MF_Bluefont, MAXPORTSTRINGLENGTH, INPUT_NUMERIC ); -static MenuEntry_t ME_NETJOIN_PORT = MAKE_MENUENTRY( "Port", &MF_Redfont, &MEF_VideoSetup, &MEO_NETJOIN_PORT, String ); -static MenuEntry_t ME_NETJOIN_CONNECT = MAKE_MENUENTRY( "Connect", &MF_Redfont, &MEF_VideoSetup_Apply, &MEO_NULL, Link ); - -static MenuEntry_t *MEL_NETJOIN[] = { - &ME_NETJOIN_SERVER, - &ME_NETJOIN_PORT, - &ME_NETJOIN_CONNECT, -}; - - #define NoTitle NULL #define MAKE_MENUMENU(Title, Format, Entries) { Title, Format, Entries, ARRAY_SIZE(Entries), 0, 0, 0 } @@ -1052,86 +469,6 @@ static MenuTextForm_t M_CHEATENTRY = { NULL, "Enter Cheat Code:", MAXCHEATLEN, 0 static MenuTextForm_t M_CHEAT_WARP = { NULL, "Enter Warp #:", 3, 0 }; static MenuTextForm_t M_CHEAT_SKILL = { NULL, "Enter Skill #:", 1, 0 }; -//#define MAKE_MENUFILESELECT(a, dir, b, c) { a, { &MMF_FileSelectLeft, &MMF_FileSelectRight }, { &MF_Minifont, &MF_Minifont }, dir, b, c, { NULL, NULL }, { 0, 0 }, { 3<<16, 3<<16 }, FNLIST_INITIALIZER, 0 } - -//static MenuFileSelect_t M_USERMAP = MAKE_MENUFILESELECT( "Select A User Map", "./usermaps/", "*.map", boardfilename ); - -// MUST be in ascending order of MenuID enum values due to binary search -static Menu_t Menus[] = { -#ifndef EDUKE32_SIMPLE_MENU - { &M_GAMESETUP, MENU_GAMESETUP, MENU_OPTIONS, MA_Return, Menu }, -#endif - { &M_OPTIONS, MENU_OPTIONS, MENU_MAIN, MA_Return, Menu }, - { &M_VIDEOSETUP, MENU_VIDEOSETUP, MENU_DISPLAYSETUP, MA_Return, Menu }, - { &M_KEYBOARDSETUP, MENU_KEYBOARDSETUP, MENU_CONTROLS, MA_Return, Menu }, - { &M_MOUSESETUP, MENU_MOUSESETUP, MENU_CONTROLS, MA_Return, Menu }, - { &M_JOYSTICKSETUP, MENU_JOYSTICKSETUP, MENU_CONTROLS, MA_Return, Menu }, - { &M_JOYSTICKAXES, MENU_JOYSTICKAXES, MENU_JOYSTICKSETUP, MA_Return, Menu }, - { &M_KEYBOARDKEYS, MENU_KEYBOARDKEYS, MENU_KEYBOARDSETUP, MA_Return, Menu }, - { &M_MOUSEADVANCED, MENU_MOUSEADVANCED, MENU_MOUSESETUP, MA_Return, Menu }, - { &M_JOYSTICKAXIS, MENU_JOYSTICKAXIS, MENU_JOYSTICKAXES, MA_Return, Menu }, - { &M_CONTROLS, MENU_CONTROLS, MENU_OPTIONS, MA_Return, Menu }, -#ifdef USE_OPENGL - { &M_RENDERERSETUP_POLYMOST, MENU_POLYMOST, MENU_DISPLAYSETUP, MA_Return, Menu }, -#endif - { &M_COLCORR, MENU_COLCORR, MENU_DISPLAYSETUP, MA_Return, Menu }, - { &M_COLCORR, MENU_COLCORR_INGAME, MENU_CLOSE, MA_Return, Menu }, - { &M_SCREENSETUP, MENU_SCREENSETUP, MENU_DISPLAYSETUP, MA_Return, Menu }, - { &M_DISPLAYSETUP, MENU_DISPLAYSETUP, MENU_OPTIONS, MA_Return, Menu }, -#ifdef POLYMER - { &M_RENDERERSETUP_POLYMER, MENU_POLYMER, MENU_DISPLAYSETUP, MA_Return, Menu }, -#endif - { &M_LOAD, MENU_LOAD, MENU_MAIN, MA_Return, Menu }, - { &M_SAVE, MENU_SAVE, MENU_MAIN, MA_Return, Menu }, - { &M_STORY, MENU_STORY, MENU_MAIN, MA_Return, Panel }, - { &M_F1HELP, MENU_F1HELP, MENU_MAIN, MA_Return, Panel }, - { &M_QUIT, MENU_QUIT, MENU_PREVIOUS, MA_Return, Verify }, - { &M_QUITTOTITLE, MENU_QUITTOTITLE, MENU_PREVIOUS, MA_Return, Verify }, - { &M_QUIT, MENU_QUIT_INGAME, MENU_CLOSE, MA_None, Verify }, - { &M_NETHOST, MENU_NETSETUP, MENU_MAIN, MA_Return, Menu }, - { &M_NETWAITMASTER, MENU_NETWAITMASTER, MENU_MAIN, MA_Return, Message }, - { &M_NETWAITVOTES, MENU_NETWAITVOTES, MENU_MAIN, MA_Return, Message }, - { &M_SOUND, MENU_SOUND, MENU_OPTIONS, MA_Return, Menu }, - { &M_SOUND, MENU_SOUND_INGAME, MENU_CLOSE, MA_Return, Menu }, - { &M_ADVSOUND, MENU_ADVSOUND, MENU_SOUND, MA_Return, Menu }, - { &M_SAVESETUP, MENU_SAVESETUP, MENU_OPTIONS, MA_Return, Menu }, - { &M_SAVECLEANVERIFY, MENU_SAVECLEANVERIFY, MENU_SAVESETUP, MA_None, Verify }, -#ifdef EDUKE32_SIMPLE_MENU - { &M_CHEATS, MENU_CHEATS, MENU_OPTIONS, MA_Return, Menu }, -#else - { &M_CHEATS, MENU_CHEATS, MENU_GAMESETUP, MA_Return, Menu }, -#endif - { &M_CHEATENTRY, MENU_CHEATENTRY, MENU_CHEATS, MA_None, TextForm }, - { &M_CHEAT_WARP, MENU_CHEAT_WARP, MENU_CHEATS, MA_None, TextForm }, - { &M_CHEAT_SKILL, MENU_CHEAT_SKILL, MENU_CHEATS, MA_None, TextForm }, - { &M_CREDITS, MENU_CREDITS, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS2, MENU_CREDITS2, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS3, MENU_CREDITS3, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS4, MENU_CREDITS4, MENU_MAIN, MA_Return, Panel }, - { &M_CREDITS5, MENU_CREDITS5, MENU_MAIN, MA_Return, Panel }, - { &M_LOADVERIFY, MENU_LOADVERIFY, MENU_LOAD, MA_None, Verify }, - { &M_LOADDELVERIFY, MENU_LOADDELVERIFY, MENU_LOAD, MA_None, Verify }, - { &M_NEWVERIFY, MENU_NEWVERIFY, MENU_PREVIOUS, MA_Return, Verify }, - { &M_SAVEVERIFY, MENU_SAVEVERIFY, MENU_SAVE, MA_None, Verify }, - { &M_SAVEDELVERIFY, MENU_SAVEDELVERIFY, MENU_SAVE, MA_None, Verify }, - { &M_COLCORRRESETVERIFY, MENU_COLCORRRESETVERIFY, MENU_COLCORR, MA_None, Verify }, - { &M_KEYSRESETVERIFY, MENU_KEYSRESETVERIFY, MENU_KEYBOARDSETUP, MA_None, Verify }, - { &M_KEYSCLASSICVERIFY, MENU_KEYSCLASSICVERIFY, MENU_KEYBOARDSETUP, MA_None, Verify }, - { &M_JOYSTANDARDVERIFY, MENU_JOYSTANDARDVERIFY, MENU_JOYSTICKSETUP, MA_None, Verify }, - { &M_JOYPROVERIFY, MENU_JOYPROVERIFY, MENU_JOYSTICKSETUP, MA_None, Verify }, - { &M_JOYCLEARVERIFY, MENU_JOYCLEARVERIFY, MENU_JOYSTICKSETUP, MA_None, Verify }, - { &M_ADULTPASSWORD, MENU_ADULTPASSWORD, MENU_GAMESETUP, MA_None, TextForm }, - { &M_RESETPLAYER, MENU_RESETPLAYER, MENU_CLOSE, MA_None, Verify }, - { &M_BUYDUKE, MENU_BUYDUKE, MENU_EPISODE, MA_Return, Message }, - { &M_NETWORK, MENU_NETWORK, MENU_MAIN, MA_Return, Menu }, - { &M_PLAYER, MENU_PLAYER, MENU_OPTIONS, MA_Return, Menu }, - { &M_MACROS, MENU_MACROS, MENU_PLAYER, MA_Return, Menu }, - { &M_NETHOST, MENU_NETHOST, MENU_NETWORK, MA_Return, Menu }, - { &M_NETOPTIONS, MENU_NETOPTIONS, MENU_NETWORK, MA_Return, Menu }, -// { &M_USERMAP, MENU_NETUSERMAP, MENU_NETOPTIONS, MA_Return, FileSelect }, - { &M_NETJOIN, MENU_NETJOIN, MENU_NETWORK, MA_Return, Menu }, -}; - /* This function prepares data after ART and CON have been processed. @@ -1159,15 +496,6 @@ void Menu_Init(void) - // prepare sound setup -#ifndef EDUKE32_STANDALONE - if (WW2GI) - ME_SOUND_DUKETALK.name = "GI talk:"; - else if (NAM) - ME_SOUND_DUKETALK.name = "Grunt talk:"; -#endif - - // prepare shareware if (VOLUMEONE) { @@ -1401,38 +729,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) rotatesprite_fs(origin.x + (200<<16), origin.y + (32<<16), 16384, 0, LOADSCREEN, 0, 0, 2|8|16); break; - case MENU_NETSETUP: - case MENU_NETHOST: - mminitext(origin.x + (90<<16), origin.y + (90<<16), "Game Type", MF_Minifont.pal_deselected); - mminitext(origin.x + (90<<16), origin.y + ((90+8)<<16), "Episode", MF_Minifont.pal_deselected); - mminitext(origin.x + (90<<16), origin.y + ((90+8+8)<<16), "Level", MF_Minifont.pal_deselected); - mminitext(origin.x + (90<<16), origin.y + ((90+8+8+8)<<16), ME_NETOPTIONS_MONSTERS.name, MF_Minifont.pal_deselected); - if (m_coop == 0) - mminitext(origin.x + (90<<16), origin.y + ((90+8+8+8+8)<<16), "Markers", MF_Minifont.pal_deselected); - else if (m_coop == 1) - mminitext(origin.x + (90<<16), origin.y + ((90+8+8+8+8)<<16), "Friendly Fire", MF_Minifont.pal_deselected); - mminitext(origin.x + (90<<16), origin.y + ((90+8+8+8+8+8)<<16), "User Map", MF_Minifont.pal_deselected); - - mminitext(origin.x + ((90+60)<<16), origin.y + (90<<16), g_gametypeNames[m_coop], MF_Minifont.pal_deselected_right); - - mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8)<<16), gVolumeNames[ud.m_volume_number], MF_Minifont.pal_deselected_right); - mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8)<<16), g_mapInfo[MAXLEVELS*ud.m_volume_number+m_level_number].name, MF_Minifont.pal_deselected_right); - if (ud.m_monsters_off == 0 || ud.m_player_skill > 0) - mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8)<<16), g_skillNames[ud.m_player_skill], MF_Minifont.pal_deselected_right); - else mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8)<<16), "None", MF_Minifont.pal_deselected_right); - if (m_coop == 0) - { - if (m_marker) mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8+8)<<16), "On", MF_Minifont.pal_deselected_right); - else mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8+8)<<16), "Off", MF_Minifont.pal_deselected_right); - } - else if (m_coop == 1) - { - if (m_ffire) mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8+8)<<16), "On", MF_Minifont.pal_deselected_right); - else mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8+8)<<16), "Off", MF_Minifont.pal_deselected_right); - } - break; - - case MENU_SAVECLEANVERIFY: videoFadeToBlack(1); diff --git a/source/duke3d/src/menus.h b/source/duke3d/src/menus.h index 00aedb009..27d56c389 100644 --- a/source/duke3d/src/menus.h +++ b/source/duke3d/src/menus.h @@ -49,6 +49,12 @@ extern MenuFont_t MF_Redfont, MF_Bluefont, MF_Minifont; void Menu_Init(void); +int G_CheckPlayerColor(int color) +{ + static int32_t player_pals[] = { 0, 9, 10, 11, 12, 13, 14, 15, 16, 21, 23, }; + if (color >= 0 && color < 10) return player_pals[color]; +} + #if 0 @@ -466,7 +472,6 @@ extern int32_t voting; int Menu_Change(MenuID_t cm); void Menu_AnimateChange(int32_t cm, MenuAnimationType_t animtype); int32_t Menu_IsTextInput(Menu_t *cm); -int G_CheckPlayerColor(int color); void M_DisplayMenus(void); #define M_MOUSETIMEOUT 210 diff --git a/source/duke3d/src/network.cpp b/source/duke3d/src/network.cpp index 597dc95ba..2de930adf 100644 --- a/source/duke3d/src/network.cpp +++ b/source/duke3d/src/network.cpp @@ -4802,7 +4802,7 @@ void Net_SendClientInfo(void) tempnetbuf[l++] = g_player[myconnectindex].ps->aim_mode = in_aimmode; tempnetbuf[l++] = g_player[myconnectindex].ps->auto_aim = cl_autoaim; tempnetbuf[l++] = g_player[myconnectindex].ps->weaponswitch = cl_weaponswitch; - tempnetbuf[l++] = g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = playercolor; + tempnetbuf[l++] = g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = G_CheckPlayerColor(playercolor); tempnetbuf[l++] = g_player[myconnectindex].pteam = playerteam; diff --git a/source/rr/src/cheats.cpp b/source/rr/src/cheats.cpp index a859e34c6..f684a5186 100644 --- a/source/rr/src/cheats.cpp +++ b/source/rr/src/cheats.cpp @@ -211,9 +211,6 @@ void G_SetupCheats(void) Bstrcpy(CheatStrings[23], ""); Bstrcpy(CheatStrings[24], "adebug"); Bstrcpy(CheatStrings[26], "acgs"); - - Bstrcpy(g_gametypeNames[0], "GruntMatch (Spawn)"); - Bstrcpy(g_gametypeNames[2], "GruntMatch (No Spawn)"); } } diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index 407ea4e7e..5c3334abb 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -475,6 +475,17 @@ void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *t } +#if 0 +void GameInterface::DrawPlayerSprite(int x, int y) +{ + if (RR) + rotatesprite_fs(origin.x + (260<<16), origin.y + ((24+(tilesiz[APLAYER].y>>2))<<16), 24576L,0,3845+36-((((8-((int32_t) totalclock>>4)))&7)*5),0,entry == &ME_PLAYER_TEAM ? G_GetTeamPalette(playerteam) : playercolor,10); + else + rotatesprite_fs(origin.x + (260<<16), origin.y + ((24+(tilesiz[APLAYER].y>>1))<<16), 49152L,0,1441-((((4-((int32_t) totalclock>>4)))&3)*5),0,entry == &ME_PLAYER_TEAM ? G_GetTeamPalette(playerteam) : playercolor,10); +} +#endif + + END_RR_NS //---------------------------------------------------------------------------- diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index cb800850a..18eed1f6b 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -7177,7 +7177,7 @@ void G_UpdatePlayerFromMenu(void) /*int32_t j = g_player[myconnectindex].ps->team;*/ P_SetupMiscInputSettings(); - g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = playercolor; + g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = G_CheckPlayerColor(playercolor); g_player[myconnectindex].pteam = playerteam; @@ -7588,7 +7588,7 @@ MAIN_LOOP_RESTART: g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = G_GetTeamPalette(g_player[myconnectindex].pteam); else { - if (playercolor) g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = playercolor; + if (playercolor) g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = G_CheckPlayerColor(playercolor); else g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor; } diff --git a/source/rr/src/menus.h b/source/rr/src/menus.h index 3e8b0a47b..e31870fa8 100644 --- a/source/rr/src/menus.h +++ b/source/rr/src/menus.h @@ -48,6 +48,12 @@ typedef struct MenuFont_t extern MenuFont_t MF_Redfont, MF_Bluefont, MF_Minifont; void Menu_Init(void); +int G_CheckPlayerColor(int color) +{ + static int32_t player_pals[] = { 0, 9, 10, 11, 12, 13, 14, 15, 16, 21, 23, }; + if (color >= 0 && color < 10) return player_pals[color]; +} + #if 0 @@ -489,7 +495,6 @@ extern int32_t voting; int Menu_Change(MenuID_t cm); void Menu_AnimateChange(int32_t cm, MenuAnimationType_t animtype); int32_t Menu_IsTextInput(Menu_t *cm); -int G_CheckPlayerColor(int color); void Menu_Init(void); void Menu_Open(uint8_t playerID); void Menu_Close(uint8_t playerID); diff --git a/source/rr/src/net.cpp b/source/rr/src/net.cpp index 7506641c5..e16092161 100644 --- a/source/rr/src/net.cpp +++ b/source/rr/src/net.cpp @@ -3430,7 +3430,7 @@ void Net_SendClientInfo(void) tempbuf[l++] = g_player[myconnectindex].ps->aim_mode = in_aimmode; tempbuf[l++] = g_player[myconnectindex].ps->auto_aim = cl_autoaim; tempbuf[l++] = g_player[myconnectindex].ps->weaponswitch = cl_weaponswitch; - tempbuf[l++] = g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = playercolor; + tempbuf[l++] = g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = G_CheckPlayerColor(playercolor); tempbuf[l++] = g_player[myconnectindex].pteam = playerteam; diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 781be168d..9e6eee177 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -353,43 +353,6 @@ LISTMENU "CustomSubMenu7" class "Duke.ListMenu" } -//------------------------------------------------------------------------------------------- -// -// No multiplayer support for now, but kept as a reminder. -// -//------------------------------------------------------------------------------------------- - -LISTMENU "MultiMenu" -{ - ifgame(Duke, Nam, WW2GI, Fury) - { - position 160, 55, 135 - centermenu - fixedspacing 5 - ifgame(Duke, Nam, WW2GI, Fury) - { - class "Duke.ListMenu" - } - else - { - class "Redneck.ListMenu" - } - animatedtransition - NativeTextItem "$MNU_PLAYERSETUP", "p", "PlayerSetupMenu" - } - ifgame(blood) - { - position 160, 80, 150 - class "Blood.ListMenu" - centermenu - Linespacing 20 - } - - Caption "$MNU_NETWORKGAME" - NativeTextItem "$MNU_JOINGAME", "j", "JoinGameMenu" - NativeTextItem "$MNU_HOSTGAME", "h", "HostGameMenu" -} - //------------------------------------------------------------------------------------------- // // @@ -997,5 +960,260 @@ OptionMenu "JoystickConfigMenu" //protected } +OptionValue "PlayerColors" +{ + 0, OPTVAL_AUTO" + 1, "$TXT_COLOR_BLUE" + 2, "TXT_COLOR_RED" + 3, "TXT_COLOR_GREEN" + 4, "TXT_COLOR_GRAY" + 5, "TXT_COLOR_DARKGRAY" + 6, "TXT_COLOR_DARKGREEN" + 7, "TXT_COLOR_BROWN" + 8, "TXT_COLOR_DARKBLUE" + 9, "TXT_COLOR_LIGHTRED" + 10, "TXT_COLOR_YELLOW" +} + +OptionValue "PlayerTeam" +{ + 0, "$TXT_COLOR_BLUE" + 1, "TXT_COLOR_RED" + 2, "TXT_COLOR_GREEN" + 3, "TXT_COLOR_GRAY" +} + +OptionValue "Gender" +{ + 0, "$OPTVAL_MALE" + 1, "$OPTVAL_FEMALE" + 2, "$OPTVAL_NEUTRAL" + 3, "$OPTVAL_OTHER" +} +OptionMenu "NewPlayerMenu" //protected +{ + Title "$MNU_PLAYERSETUP" + TextField "$PLYRMNU_NAME", playername + Option "$PLYRMNU_TEAM", "playerteam", "PlayerTeam" + Option "$PLYRMNU_PLAYERCOLOR", "playercolor", "PlayerColors" + Option "$PLYRMNU_PLAYERGENDER", "playergender", "Gender"" + Submenu "$PLRMNU_TAUNTS", "TauntsMenu" + Class "NewPlayerMenu" +} + +OptionMenu "TauntsMenu" //protected +{ + Title "$PLRMNU_TAUNTS" + TextField "1", "combatmacro0" + TextField "2", "combatmacro0" + TextField "3", "combatmacro0" + TextField "4", "combatmacro0" + TextField "5", "combatmacro0" + TextField "6", "combatmacro0" + TextField "7", "combatmacro0" + TextField "8", "combatmacro0" + TextField "9", "combatmacro0" + TextField "10", "combatmacro0" +} + +//------------------------------------------------------------------------------------------- +// +// Game Setup +// +//------------------------------------------------------------------------------------------- + +OptionValue "AimMode" +{ + 0, "$OPTVAL_NEVER" + 1, "$OPTVAL_ALWAYS" + 2, "$OPTRAL_HITSCAN" +} + +OptionValue "RunMode" +{ + 0, "$PLRMNU_TOGGLE" + 1, "$PLRMNU_OVERRIDE" +} + +OptionValue "WeapSwitch" +{ + 0, "$OPTVAL_NEVER" + 1, "$PLRMNU_IFNEW" + 3, "$PLRMNU_PREFERRED" +} + + +OptionMenu GameplayOptions //protected +{ + Position -35 + Title "$GMPLYMNU_TITLE" + Option "$PLRMNU_AUTOAIM", "cl_autoaim", "AimMode" + Option "$PLRMNU_ALWAYSRUN", "cl_autorun", "OnOff" + Option "$PLRMNU_RUNMODE", "cl_runmode", "RunMode" + Option "$PLRMNU_EQUIP", "cl_weaponswitch", "WeapSwitch" + Option "$PLRMNU_PLOCK", "adult_lockout", "OnOff" // I won't bother password protecting this piece of window dressing + // StaticText "" + // Option "Record Demo", "m_recstat", "OnOff" + // Submenu "Cheats" "CheatsMenu +} + +//------------------------------------------------------------------------------------------- +// +// Display options +// +//------------------------------------------------------------------------------------------- + +OptionValue "FilterModes" +{ + 0, "$OPTVAL_NONE" + 1, "$OPTVAL_NONENEARESTMIPMAP" + 5, "$OPTVAL_NONELINEARMIPMAP" + 6, "$OPTVAL_NONETRILINEAR" + 2, "$OPTVAL_LINEAR_2" + 3, "$OPTVAL_BILINEAR" + 4, "$OPTVAL_TRILINEAR" +} + +OptionValue "Anisotropy" +{ + 1, "$OPTVAL_OFF" + 2, "$OPTVAL_2X" + 4, "$OPTVAL_4X" + 8, "$OPTVAL_8X" + 16, "$OPTVAL_16X" +} + +OptionMenu "VideoOptions" //protected +{ + Title "$DSPLYMNU_TITLE" + + Submenu "$OPTMNU_HUD", "HUDOptions" + Submenu "$OPTMNU_POLYMOST", "PolymostOptions" + + Slider "$DSPLYMNU_GAMMA", "vid_gamma", 0.75, 3.0, 0.05, 2 + Slider "$DSPLYMNU_BRIGHTNESS", "vid_brightness", -0.8,0.8, 0.05,2 + Slider "$DSPLYMNU_CONTRAST", "vid_contrast", 0.1, 3.0, 0.1 + Slider "$DSPLYMNU_SATURATION", "vid_saturation", -3.0, 3.0, 0.25, 2 + + StaticText "" + Option "$GLTEXMNU_TEXFILTER", hw_texfilter, "FilterModes" + Option "$GLTEXMNU_ANISOTROPIC", hw_anisotropy, "Anisotropy" +} + + +//------------------------------------------------------------------------------------------- +// +// HUD options +// +//------------------------------------------------------------------------------------------- + +OptionValue "HUDMessages" +{ + 0, "$OPTVAL_OFF" + 1, "$OPTVAL_ON" + 2, "$DSPLYMNU_GENERIC" +} + +OptionMenu "HUDOptions" //protected +{ + Title "$OPTMNU_HUD" + + Slider "$DSPLYMNU_SCREENSIZE", "hud_size", 3.0, 12.0, 1.0, 0 + Slider "$DSPLYMNU_SBSCALE", "hud_scale", 0.3, 1.0, 0.1, 2 + Option "$DSPLYMNU_LEVELSTATS", "hud_stats", "OnOff" + Slider "$DSPLYMNU_TEXTSCALE", "hud_textscale", 0.3, 1.0, 0.1, 2 + StaticText "" + Option "$DSPLYMNU_MESSAGES", "hud_messages", "HudMessages" + StaticText "" + Option "$DSPLYMNU_CROSSHAIR", "cl_crosshair", OnOff + Slider "$DSPLYMNU_CROSSHAIRSCALE", "cl_crosshairscale", 50, 100, 10, 1 + StaticText "" + Option "$DSPLYMNU_VOXELS", "r_voxels", "OnOff" + StaticText "" + Option "$DSPLYMNU_FOV", "r_fov", 60, 130, 10, 1 +} + + + +//------------------------------------------------------------------------------------------- +// +// No multiplayer support for now, but kept for documentation. +// +//------------------------------------------------------------------------------------------- + +LISTMENU "MultiMenu" +{ + ifgame(Duke, Nam, WW2GI, Fury) + { + position 160, 55, 135 + centermenu + fixedspacing 5 + ifgame(Duke, Nam, WW2GI, Fury) + { + class "Duke.ListMenu" + } + else + { + class "Redneck.ListMenu" + } + animatedtransition + NativeTextItem "$MNU_PLAYERSETUP", "p", "PlayerSetupMenu" + } + ifgame(blood) + { + position 160, 80, 150 + class "Blood.ListMenu" + centermenu + Linespacing 20 + } + ifgame(shadowwarrior) + { + position 160, 80, 150 + class "ShadowWarrior.ListMenu" + centermenu + Linespacing 20 + } + + Caption "$MNU_NETWORKGAME" + NativeTextItem "$MNU_JOINGAME", "j", "JoinGameMenu" + NativeTextItem "$MNU_HOSTGAME", "h", "HostGameMenu" +} + +OptionMenu "HostGameMenu" +{ + title "$MNU_HOSTGAME" + Submenu "$NETMNU_OPTIONS", "MultiOptionsMenu" + Command "$NETMNU_LAUNCH", "Launch_MP" // currently a no-op +} + +OptionMenu "JoinGameMenu" +{ + TextField "$NETMNU_SERVER", "m_server" + TextField "$NETMNU_PORT", "m_netport" + SaveCommand "$NETMNU_CONNECT", "MultiConnect" +} + +OptionValue "MultiGameType" +{ + 0, "$NETMNU_GAMETYPE1" + 1, "$NETMNU_GAMETYPE2" + 2, "$NETMNU_GAMETYPE3" + 3, "$NETMNU_GAMETYPE4" + 4, "$NETMNU_GAMETYPE5" +} + +OptionMenu "MultiOptionsMenu" +{ + title "$NETMNU_OPTIONS" + Option "$NETMNU_GAMETYPE", "m_coop" + Option "$NETMNU_EPISODE", "m_episode_number" + Option "$NETMNU_LEVEL", "m_level_number" + Submenu "$MNU_USERMAP", "MultiUserMap" // todo: fileselect item + Option "$NETMNU_MONSTERS", "m_monsters" + Option "$NETMNU_MARKERS", "m_marker" + Option "$NETMNU_MAPEXITS", "m_noexit" + Option "$NETMNU_FFIRE", "m_ffire" + SafeCommand "$NETMNU_ACCEPT", "MultiAccept" +} From 138326314e495d83b7dc1c79f9b32adccb074994 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 4 Dec 2019 17:30:41 +0100 Subject: [PATCH 106/203] - text update. --- source/duke3d/src/menus.h | 3 +- source/rr/src/menus.h | 3 +- wadsrc/static/demolition/language.csv | 169 +++++++++++++++++++++++++- 3 files changed, 172 insertions(+), 3 deletions(-) diff --git a/source/duke3d/src/menus.h b/source/duke3d/src/menus.h index 27d56c389..140b5383a 100644 --- a/source/duke3d/src/menus.h +++ b/source/duke3d/src/menus.h @@ -49,10 +49,11 @@ extern MenuFont_t MF_Redfont, MF_Bluefont, MF_Minifont; void Menu_Init(void); -int G_CheckPlayerColor(int color) +inline int G_CheckPlayerColor(int color) { static int32_t player_pals[] = { 0, 9, 10, 11, 12, 13, 14, 15, 16, 21, 23, }; if (color >= 0 && color < 10) return player_pals[color]; + return 0; } diff --git a/source/rr/src/menus.h b/source/rr/src/menus.h index e31870fa8..dc2023d67 100644 --- a/source/rr/src/menus.h +++ b/source/rr/src/menus.h @@ -48,10 +48,11 @@ typedef struct MenuFont_t extern MenuFont_t MF_Redfont, MF_Bluefont, MF_Minifont; void Menu_Init(void); -int G_CheckPlayerColor(int color) +inline int G_CheckPlayerColor(int color) { static int32_t player_pals[] = { 0, 9, 10, 11, 12, 13, 14, 15, 16, 21, 23, }; if (color >= 0 && color < 10) return player_pals[color]; + return 0; } diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index d4b92acba..44564d3bc 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -398,4 +398,171 @@ Moving Forward,OPTVAL_MOVINGFORWARD,,,,Pohyb vpřed,Vorwärtsbewegung,,Movanta R Strafing,OPTVAL_STRAFING,,,,Pohyb do stran,Seitwärtsbewegung,,Flankmovanta,Desplazarse,,Sivuttaisastunta,Pas de côté,,Movimento laterale,横移動,양옆으로 이동,Strafelen,Uniki,Deslocamento lateral,,,Движение боком,Кретање у страну Moving Up/Down,OPTVAL_MOVINGUPDOWN,,,,Pohyb nahoru/dolů,Auf/abwärtsbewegung,,Movanta Supre/Malsupre,Moverse hacia Arriba/Abajo,,Ylös/Alas liikkuminen,Mouvement haut/bas,,Movimento Sopra/Sotto,前進後退,위/아래로 이동,Naar boven/beneden bewegen,Poruszanie się w górę/w dół,Deslocar para cima/baixo,,,Движение вверх/вниз,Кретање горе/доле Inverted,OPTVAL_INVERTED,,,,Inverzní,Invertiert,,Inversigita,Invertido,,Käännetty,Inversé,,Invertito,反転する,반전,Omgekeerd,Odwrócony,Invertido,,,Инвертировано,Обрнуто -Not Inverted,OPTVAL_NOTINVERTED,,,,Nikoliv inverzní,nicht invertiert,,Ne Inversigita,No invertido,,Ei käännetty,Non Inversé,,Non invertito,反転しない,반전되지 않음,Niet omgekeerd,Nieodwrócony,Não Invertido,,,Прямо,Не обрнуто \ No newline at end of file +Not Inverted,OPTVAL_NOTINVERTED,,,,Nikoliv inverzní,nicht invertiert,,Ne Inversigita,No invertido,,Ei käännetty,Non Inversé,,Non invertito,反転しない,반전되지 않음,Niet omgekeerd,Nieodwrócony,Não Invertido,,,Прямо,Не обрнуто +,PLayer Menu,,,,,,,,,,,,,,,,,,,,,, +Player Setup,MNU_PLAYERSETUP,,,,Nastavení hráče,Spielereinstellungen,,Ludanto Agordaĵo,Config. del jugador,,Pelaaja-asetukset,Options Joueur,Játékos testreszabása,Settaggio giocatore,プレイヤーの特徴,플레이어 설정,Speler instellen,Ustawienia Gracza,Definições de Jogador,,,Настройки игрока,Подешавања играча +Blue,TXT_COLOR_BLUE,,,,Modrá,Blau,,Blua,Azul,,Sininen,Bleu,Kék,Blu,青,청색,Blauw,Niebieski,Azul,,,Синий,Плава +Red,TXT_COLOR_RED,,,,Červená,Rot,,Ruĝa,Rojo,,Punainen,Rouge,Vörös,Rosso,赤,적색,Rood,Czerwony,Vermelho,,,Красный,Црвена +Green,TXT_COLOR_GREEN,,,,Zelená,Grün,,Verda,Verde,,Vihreä,Vert,Zöld,Verde,緑,녹색,Groen,Zielony,Verde,,,Зелёный,Зелена +Gray,TXT_COLOR_GRAY,,,Grey,Šedá,Grau,,Griza,Gris,,Harmaa,Gris,Szürke,Grigio,灰,회색,Grijs,Szary,Cinza,,,Серый,Сива +Dark gray,TXT_COLOR_DARKGRAY,,,"Dark grey +",Tmavě šedá,Dunkelgrau,,Grizeta,gris oscuro,,Tummanharmaa,Gris sombre,Sötétszürke,Grigio scuro,鉛,치색,Donkergrijs,Ciemnoszary,Cinza escuro,,,Тёмно-серый,Тамно сива +Dark Green,TXT_COLOR_DARKGREEN,,,,Tmavě zelená,Dunkelgrün,,Malhelverda,Verde oscuro,,Tummanvihreä,Vert sombre,Sötétzöld,Verde scuro,深,흑녹색,Donkergroen,Ciemnozielony,Verde escuro,,,Тёмно-зелёный,Тамна зелена +Brown,TXT_COLOR_BROWN,,,,Hnědá,Braun,,Bruna,Marrón,,Ruskea,Brun,Barna,Marrone,茶,갈색,Bruin,Brązowy,Marrom,,,Коричневый,Браон +Dark Blue,TXT_COLOR_DARKBLUE,,,,Tmavě modrá,Dunkelblau,,Malhelblua,Azul oscuro,,Tummansininen,Bleu sombre,Sötétkék,Blu scuro,,,Donkerblauw,,Azul escuro,,,Тёмно-Синий,Тамна Плава +Light Red,TXT_COLOR_LIGHTRED,,,,Světle červená,Hellrot,,Ruĝeta,Rojo claro,,Vaaleanpunainen,Rouge clair,,Rosso chiaro,丹,옅은 적색,Licht Rood,Jasnoczerwony,Vermelho claro,,,Светло-красный,Светло црвена +Yellow,TXT_COLOR_YELLOW,,,,Žlutá,Gelb,,Flava,Amarillo,,Keltainen,Jaune,Sárga,Giallo,黄,노란색,Geel,Żółty,Amarelo,,,Жёлтый,Жута +Auto,OPTVAL_AUTO,,,,,,,Aŭtomata,Automático,,Automaattinen,,,Automatico,自動,자동,,Automatycznie,Automático,,,Авто,Аутоматски +Name,PLYRMNU_NAME,,,,Jméno,,,Nomo,Nombre,,Nimi,Nom,Név,Nome,名前,이름,Naam,Imię,Nome,,,Имя,Надимак +Team,PLYRMNU_TEAM,,,,Tým,,,Teamo,Equipo,,Joukkue,Equipe,Csapat,Squadra,チーム,팀,Team,Drużyna,Equipe,Equipa,,Команда,Тим +Color,PLYRMNU_PLAYERCOLOR,,,Colour,Barva,Farbe,,Koloro,,,Väri,Couleur,Szín,Colore,色,색상,Kleur,Kolor,Cor,,,Цвет,Боја +Multiplayer taunts,PLRMNU_TAUNTS,,,,,Mehrspieler-Spott,,,,,,,,,,,,,,,,, +Male,OPTVAL_MALE,,,,Muž,Männlich,,Vira (Li),Masculino,,Miespuolinen,Masculin,,Maschio,男,남성,Man,Mężczyzna,Masculino,,,Мужской,Мушко +Female,OPTVAL_FEMALE,,,,Žena,Weiblich,,Ina (Ŝi),Femenino,,Naispuolinen,Féminin,,Femmina,女,여성,Vrouw,Kobieta,Feminino,,,Женский,Женско +Neutral,OPTVAL_NEUTRAL,,,,Neutrální,Neutral,,Neŭtrala (Ri),Neutro,,Sukupuoleton,Neutre,,Neutrale,中間,중성,Neutraal,Neutralne,Neutro,,,Нейтральный,Неутрално +Object,OPTVAL_OTHER,,,,Objekt,Objekt,,Objekto (Ĝi),Objeto,,Olio,Objet,,Oggetto,物体,기타,Doel,Obiekt,Objeto,,,Предмет,Предмет +,Multiplayer,,,,,,,,,,,,,,,,,,,,,, +Game Options,NETMNU_OPTIONS,,,,,Spieleinstellungen,,,,,,,,,,,,,,,,, +Launch Game,NETMNU_LAUNCH,,,,,Spiel starten,,,,,,,,,,,,,,,,, +Game Type,NETMNU_GAMETYPE,,,,,,,,,,,,,,,,,,,,,, +Deathmatch (Spawn),NETMNU_GAMETYPE1,,,,,,,,,,,,,,,,,,,,,, +DukeMatch (Spawn),NETMNU_GAMETYPE1,Duke,,,,,,,,,,,,,,,,,,,,, +GI Match (Spawn),NETMNU_GAMETYPE1,Nam,,,,,,,,,,,,,,,,,,,,, +GruntMatch (Spawn),NETMNU_GAMETYPE1,WW2GI,,,,,,,,,,,,,,,,,,,,, +Cooperative Play,NETMNU_GAMETYPE2,,,,,,,,,,,,,,,,,,,,,, +Deathmatch (No Spawn),NETMNU_GAMETYPE3,,,,,,,,,,,,,,,,,,,,,, +DukeMatch (No Spawn),NETMNU_GAMETYPE3,Duke,,,,,,,,,,,,,,,,,,,,, +GI Match (No Spawn),NETMNU_GAMETYPE3,Nam,,,,,,,,,,,,,,,,,,,,, +GruntMatch (No Spawn),NETMNU_GAMETYPE3,WW2GI,,,,,,,,,,,,,,,,,,,,, +Team DM (Spawn),NETMNU_GAMETYPE4,,,,,,,,,,,,,,,,,,,,,, +Team DM (No Spawn),NETMNU_GAMETYPE5,,,,,,,,,,,,,,,,,,,,,, +Episode,NETMNU_EPISODE,,,,,,,,,,,,,,,,,,,,,, +Level,NETMNU_LEVEL,,,,,,,,,,,,,,,,,,,,,, +Monsters,NETMNU_MONSTERS,,,,,,,,,,,,,,,,,,,,,, +Markers,NETMNU_MARKERS,,,,,,,,,,,,,,,,,,,,,, +Map Exits,NETMNU_MAPEXITS,,,,,,,,,,,,,,,,,,,,,, +Friendly Fire,NETMNU_FFIRE,,,,,,,,,,,,,,,,,,,,,, +Accept,NETMNU_ACCEPT,,,,,,,,,,,,,,,,,,,,,, +Server,NETMNU_SERVER,,,,,,,,,,,,,,,,,,,,,, +Port,NETMNU_PORT,Network port!,,,,,,,,,,,,,,,,,,,,, +Connect,NETMNU_CONNECT,,,,,,,,,,,,,,,,,,,,,, +,Gameplay options,,,,,,,,,,,,,,,,,,,,,, +Gameplay Options,GMPLYMNU_TITLE,,,,Nastavení herních mechanik,Gameplay-Optionen,,Ludadagordoj,Opciones de jugabilidad,,Pelattavuusasetukset,Options Gameplay,,Opzioni gameplay,ゲームプレイ オプション,게임플레이 설정,Gameplay-opties,Opcje Rozgrywki,Opções de Jogabilidade,,,Настройки геймплея,Подешавања гејмплеја +Always,OPTVAL_ALWAYS,,,,Vždy,Immer,,Ĉiam,Siempre,,Aina,Toujours,,Sempre,常に,언제나,Altijd,Zawsze,Sempre,,,Всегда,Увек +Never,OPTVAL_NEVER,,,,Nikdy,Nie,,Neniam,Nunca,,Ei koskaan,Jamais,,Mai,しない,없음,Nooit,Nigdy,Nunca,,,Никогда,Никад +Hitscan only,OPTVAL_HITSCAN,,,,,Nur Hitscan,,,,,,,,,,,,,,,,, +Autoaim,PLYRMNU_AUTOAIM,,,,Automatické míření,Automatisch zielen,,Aŭtomate-celi,Autoapuntar,,Automaattitähtäys,Auto-visée,Auto célzás,Mira automatica,自動照準,자동 조준,Autoaim,Automatyczne Celowanie,Mira Automática,,,Автоприцеливание,Аутоматско циљање +Always Run,PLYRMNU_ALWAYSRUN,,,,Vždy běžet,Immer Rennen,,Ĉiam Kuri,Siempre correr,,Jatkuva juoksu,Toujours courir,Mindig fusson,Corri sempre,常に駆け足,달리기 토글,Altijd lopen,Zawsze Biegaj,Sempre Correr,Correr Sempre,,Постоянный бег,Увек трчи +Run Mode,PLRMNU_RUNMODE,,,,,Rennmodus,,,,,,,,,,,,,,,,, +Allow Toggle,PLRMNU_TOGGLE,,,,,Umschalten erlauben,,,,,,,,,,,,,,,,, +Override Toggle,PLRMNU_OVERRIDE,,,,,Umschalten blockieren,,,,,,,,,,,,,,,,, +If New,PLRMNU_IFNEW,,,,,Wenn neu,,,,,,,,,,,,,,,,, +Equip Weapon Pickups,PLRMNU_EQUIP,,,,,Waffen sofort aktivieren,,,,,,,,,,,,,,,,, +Parental Lock,PLRMNU_PLOCK,,,,,Kindersicherung,,,,,,,,,,,,,,,,, +Only preferred,PLRMNU_PREFERRED,,,,,Nur bevorzugte,,,,,,,,,,,,,,,,, +,Display,,,,,,,,,,,,,,,,,,,,,, +Display Options,DSPLYMNU_TITLE,,,,Nastavení grafiky,Anzeigeoptionen,,Ekranagordoj,Opciones de visualización,,Näyttöasetukset,Options Affichage,Megjelenítés beállítások,Opzioni display,ディスプレイ オプション,디스플레이 설정,Weergaveopties,Opcje Wyświetlania,Opções de Vídeo,,,Настройки экрана,Подешавања приказа +Screen size,DSPLYMNU_SCREENSIZE,,,,Velikost obrazovky,Bildschirmgröße,,Ekrano-grandeco,Tamaño de pantalla,,Näytön koko,Taille de l'écran,Képernyő mérete,Dimensione della schermata,画面サイズ,화면 크기,Schermgrootte,Rozmiar Ekranu,Tamanho de tela,Tamanho do ecrã,,Размер экрана,Величина екрана +Vertical Sync,DSPLYMNU_VSYNC,,,,Vertikální synchronizace,Vertikale Synchronisation,,Vertikala-sinkronigo,Sincr. vertical,,Pystytahdistys,Synchronisation Verticale,Függőleges szinkronizálás,Sync verticale,垂直同期,수직 동기화,Verticale Sync,Synchronizacja Pionowa,Sincronização Vertical,,,Вертикальная синхронизация,Вертикална синхорнизација +Models,DSPLYMNU_MODELS,,,,Modely,Modelle,,Modeloj,Modelos,,Mallit,Modèles,3D modellek,Modelli,モデル,모델,Modellen,Modele,Modelos,,,Модели,Модели +Voxels,DSPLYMNU_VOXELS,,,,,Voxel,,,,,,,,,,,,,,,,, +Scale crosshair,DSPLYMNU_CROSSHAIRSCALE,,,,Velikost zaměřovače,Fadenkreuz skalieren,,Skali translinion,Escalar retícula,,Skaalaa tähtäintä,Mise à l'échelle du viseur,,Scala del mirino,照準サイズ,조준점 크기,Dradenkruis schalen,Skala celownika,Escala da mira,,,Масштабирование прицела,Размера нишана +Brightness,DSPLYMNU_BRIGHTNESS,,,,Jas,Helligkeit,,Brileco,Brillo,,Kirkkaus,Luminosité,Fényerő,Luminosità,明るさ,밝기,Helderheid,Jasność,Brilho,,,Яркость,Осветљење +Gamma correction,DSPLYMNU_GAMMA,,,,Korekce gama,Gammakorrektur,,Gamaa korektado,Corrección gamma,,Gammakorjaus,Correction Gamma,,Correzione gamma,ガンマ値,감마 조정,Gamma correctie,Korekta gammy,Correção gama,,,Гамма-коррекция,Корекција светлости +Contrast,DSPLYMNU_CONTRAST,,,,Kontrast,Kontrast,,Kontrasto,Contraste,,Sävykkyys,Contraste,,Contrasto,コントラスト,대비,,Kontrast,Contraste,,,Контраст,Контраст +Saturation,DSPLYMNU_SATURATION,,,,Sytost,Sättigung,,Satureco,Saturación,,Värikylläisyys,,,Saturazione,サチュレーション,채도,Verzadiging,Nasycenie,Saturação,,,Насыщенность,Сатурација +Status Bar Scale,DSPLYMNU_SBSCALE,,,,,Statusleistengröße,,,,,,,,,,,,,,,,, +Level statistics,DSPLYMNU_LEVELSTATS,,,,,Levelstatistik,,,,,,,,,,,,,,,,, +Text Scale,DSPLYMNU_TEXTSCALE,,,,,Textgröße,,,,,,,,,,,,,,,,, +Messages,DSPLYMNU_MESSAGES,,,,Zprávy,Nachrichten,,Mesaĝoj,Mensajes,,Viestit,Messages,,Messaggi,メッセージ類,메시지,Berichten,Wiadomości,Mensagens,,,Сообщения,Поруке +Generic,DSPLYMNU_GENERIC,,,,,Generisch,,,,,,,,,,,,,,,,, +Show Map Name,DSPLYMNU_SHOWMAPNAME,,,,,"Levelnamen anzeigen +",,,,,,,,,,,,,,,,, +FOV,DSPLYMNU_FOV,,,,,Gesichtsfeld,,,,,,,,,,,,,,,,, +Crosshair,DSPLYMNU_CROSSHAIRON,,,,Křížek,Fadenkreuz,,Reteto,Retícula,,Tähtäin,Viseur,,Mirino,クロスヘア,조준점,Draadkruis,Celownik,Mira,,,Прицел,Нишан +HUD Options,OPTMNU_HUD,,,,Nastavení HUD,HUD Einstellungen,,Agordoj de HUD,Opciones del HUD,,Tilanäytön asetukset,Options de l'ATH,HUD beállítások,Opzioni HUD,HUD オプション,HUD 설정,HUD opties,Opcje Paska HUD,Opções de HUD,,,HUD,HUD +Polymost Options,OPTMNU_POLYMOST,,,,,Polymost Einstellungen,,,,,,,,,,,,,,,,, +Texture Filter mode,GLTEXMNU_TEXFILTER,,,,Režim filtrování textur,Texturfiltermodus,,Reĝimo por Teksturfiltrado,Modo de filtro de texturas,,Pintakuviointien suodatustapa,Mode de Filtrage Texture,,Modalità filtro texture,テクスチャーフィルター モード,텍스쳐 필터 모드,Textuur Filter mode,Tryb Filtrowania Tekstur,Modo de filtragem de textura,,,Фильтрация текстур,Текстурни филтер мод +Anisotropic filter,GLTEXMNU_ANISOTROPIC,,,,Anisotropické filtrování,Anisotropische Filterung,,Anizotropa Filtro,Filtro anisotrópico,,Anisotrooppinen suodatus,Filtre Anisotropique,,Filtro anisotropico,異方性フィルター,이방성 필터,Anisotroop filter,Filtr anizotropowy,Filtragem anisotrópica,,,Анизотропная фильтрация,Анизотропни фолтер +None (nearest mipmap),OPTVAL_NONENEARESTMIPMAP,,,,Žádné (nejbližší mipmapa),Aus (nächste Mipmap),,Nenio (plej proksima mipmapo),Ninguno (mipmap cercano),,Ei mitään (lähin mipkartta),Aucun (mipmap proche voisin),,Nessuno (mipmap più vicina),なし(最寄りミップマップ),없음 (밉멥에 가까움),Geen (dichtstbijzijnde mipmap),Brak (najbliższa mipmapa),Nenhum (mipmap vizinho mais próximo),,,Нет (ближайший мипмап),Ништа (најближи мипмап) +None (linear mipmap),OPTVAL_NONELINEARMIPMAP,,,,Žádné (lineární mipmapa),Aus (lineare Mipmap),,Nenio (linia mipmapo),Ninguno (mipmap lineal),,Ei mitään (lin. mipkartta),Aucun (mipmap linéaire),,Nessuno (mipmap lineare),なし(リニアミップマップ),없음 (선형 밉맵),Geen (lineaire mipmap),Brak (liniowa mipmapa),Nenhum (mipmap linear),,,Нет (линейный мипмап),Ништа (линеаран мипмап) +None (trilinear),OPTVAL_NONETRILINEAR,,,,Žádné (trilineární),Aus (trilinear),,Nenio (trilinia),Ninguno (trilineal),,Ei mitään (trilineaarinen),Aucun (mipmap trilinéaire),,Nessuno (mipmap trilineare),なし(トライリニア),없음 (삼선형),Geen (trilineair),Brak (trzyliniowe),Nenhum (trilinear),,,Нет (трилинейная),Ништа (трилинеарно) +Bilinear,OPTVAL_BILINEAR,,,,Bilineární,,,Dulinia,Bilineal,,Bilineaarinen,Bilinéaire,,Bilineare,バイリニア,쌍선형,Bilineair,Dwuliniowe,,,,Билинейная,Билинеарно +Trilinear,OPTVAL_TRILINEAR,,,,Trilineární,,,Trilinia,Trilineal,,Trilineaarinen,Trilinéaire,,Trilineare,トライリニア,삼선형,Trilineair,Trzyliniowe,,,,Трилинейная,Трилинеарно +Linear,OPTVAL_LINEAR_2,,,,Lineární,,,Lineara,Lineal,,Lineaarinen,Linéaire,,Lineare,リニア,선형,Lineair,Liniowa,,,,Линейная,Линеаран +2x,OPTVAL_2X,,,,,,,2-oble,,,,,,,,,,,,,,, +4x,OPTVAL_4X,,,,,,,4-oble,,,,,,,,,,,,,,, +8x,OPTVAL_8X,,,,,,,8-oble,,,,,,,,,,,,,,, +16x,OPTVAL_16X,,,,,,,16-oble,,,,,,,,,,,,,,, +32x,OPTVAL_32X,,,,,,,32-oble,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 beat %s^02 like a cur,",TXT_OBITUARY1,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 broke %s,",TXT_OBITUARY2,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 body bagged %s,",TXT_OBITUARY3,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 boned %s^02 like a fish,",TXT_OBITUARY4,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 castrated %s,",TXT_OBITUARY5,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 creamed %s,",TXT_OBITUARY6,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 crushed %s,",TXT_OBITUARY7,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 destroyed %s,",TXT_OBITUARY8,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 diced %s,",TXT_OBITUARY9,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 disemboweled %s,",TXT_OBITUARY10,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 erased %s,",TXT_OBITUARY11,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 eviscerated %s,",TXT_OBITUARY12,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 flailed %s,",TXT_OBITUARY13,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 flattened %s,",TXT_OBITUARY14,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 gave AnAl MaDnEsS to %s,",TXT_OBITUARY15,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 gave %s^02 Anal Justice,",TXT_OBITUARY16,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 hosed %s,",TXT_OBITUARY17,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 hurt %s^02 real bad,",TXT_OBITUARY18,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 killed %s,",TXT_OBITUARY19,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 made dog meat out of %s,",TXT_OBITUARY20,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 made mincemeat out of %s,",TXT_OBITUARY21,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 manhandled %s,",TXT_OBITUARY22,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 massacred %s,",TXT_OBITUARY23,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 mutilated %s,",TXT_OBITUARY24,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 murdered %s,",TXT_OBITUARY25,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 neutered %s,",TXT_OBITUARY26,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 punted %s,",TXT_OBITUARY27,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 reamed %s,",TXT_OBITUARY28,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 ripped %s^02 a new orifice,",TXT_OBITUARY29,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 rocked %s,",TXT_OBITUARY30,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 sent %s^02 to hell,",TXT_OBITUARY31,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 shredded %s,",TXT_OBITUARY32,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 slashed %s,",TXT_OBITUARY33,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 slaughtered %s,",TXT_OBITUARY34,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 sliced %s,",TXT_OBITUARY35,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 smacked %s around,",TXT_OBITUARY36,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 smashed %s,",TXT_OBITUARY37,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 snuffed %s,",TXT_OBITUARY38,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 sodomized %s,",TXT_OBITUARY39,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 splattered %s,",TXT_OBITUARY40,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 sprayed %s,",TXT_OBITUARY41,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 squashed %s,",TXT_OBITUARY42,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 throttled %s,",TXT_OBITUARY43,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 toasted %s,",TXT_OBITUARY44,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 vented %s,",TXT_OBITUARY45,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 ventilated %s,",TXT_OBITUARY46,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 wasted %s,",TXT_OBITUARY47,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 wrecked %s,",TXT_OBITUARY48,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 is excrement,",TXT_SELFOBIT1,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 is hamburger,",TXT_SELFOBIT2,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 suffered scrotum separation,",TXT_SELFOBIT3,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 volunteered for population control,",TXT_SELFOBIT4,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 has suicided,",TXT_SELFOBIT5,,,,,,,,,,,,,,,,,,,,,, +"^02%s^02 bled out,",TXT_SELFOBIT6,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file From dca118881a46806e1ef54a2533ccce5ebbe2937c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 4 Dec 2019 17:55:43 +0100 Subject: [PATCH 107/203] - added graphics for the mouse back button and reactivated the code for it. --- source/common/menu/menu.cpp | 24 ++++++++---------- wadsrc/static/demolition/graphics/M_BACK.png | Bin 0 -> 1254 bytes .../ionfury/demolition/graphics/M_BACK.png | Bin 0 -> 1255 bytes .../filter/nam/demolition/graphics/M_BACK.png | Bin 0 -> 1254 bytes .../redneck/demolition/graphics/M_BACK.png | Bin 0 -> 1254 bytes .../ww2gi/demolition/graphics/M_BACK.png | Bin 0 -> 1254 bytes 6 files changed, 10 insertions(+), 14 deletions(-) create mode 100644 wadsrc/static/demolition/graphics/M_BACK.png create mode 100644 wadsrc/static/filter/ionfury/demolition/graphics/M_BACK.png create mode 100644 wadsrc/static/filter/nam/demolition/graphics/M_BACK.png create mode 100644 wadsrc/static/filter/redneck/demolition/graphics/M_BACK.png create mode 100644 wadsrc/static/filter/ww2gi/demolition/graphics/M_BACK.png diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 4bc9b1bf4..350b2cabd 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -258,14 +258,13 @@ bool DMenu::MouseEventBack(int type, int x, int y) { if (m_show_backbutton >= 0) { -#if 0 - FTexture *tex = TexMan(gameinfo.mBackButton); + FTexture* tex = TileFiles.GetTexture("demolition/graphics/m_back.png"); if (tex != NULL) { - if (m_show_backbutton&1) x -= screen->GetWidth() - tex->GetScaledWidth() * CleanXfac; - if (m_show_backbutton&2) y -= screen->GetHeight() - tex->GetScaledHeight() * CleanYfac; - mBackbuttonSelected = ( x >= 0 && x < tex->GetScaledWidth() * CleanXfac && - y >= 0 && y < tex->GetScaledHeight() * CleanYfac); + if (m_show_backbutton&1) x -= screen->GetWidth() - tex->GetWidth() * CleanXfac; + if (m_show_backbutton&2) y -= screen->GetHeight() - tex->GetHeight() * CleanYfac; + mBackbuttonSelected = ( x >= 0 && x < tex->GetWidth() * CleanXfac && + y >= 0 && y < tex->GetHeight() * CleanYfac); if (mBackbuttonSelected && type == MOUSE_Release) { if (m_use_mouse == 2) mBackbuttonSelected = false; @@ -273,7 +272,6 @@ bool DMenu::MouseEventBack(int type, int x, int y) } return mBackbuttonSelected; } -#endif } return false; } @@ -314,24 +312,22 @@ void DMenu::Ticker () void DMenu::Drawer () { -#if 0 if (this == DMenu::CurrentMenu && BackbuttonAlpha > 0 && m_show_backbutton >= 0 && m_use_mouse) { - FTexture *tex = TexMan(gameinfo.mBackButton); - int w = tex->GetScaledWidth() * CleanXfac; - int h = tex->GetScaledHeight() * CleanYfac; + FTexture* tex = TileFiles.GetTexture("demolition/graphics/m_back.png"); + int w = tex->GetWidth() * CleanXfac; + int h = tex->GetHeight() * CleanYfac; int x = (!(m_show_backbutton&1))? 0:screen->GetWidth() - w; int y = (!(m_show_backbutton&2))? 0:screen->GetHeight() - h; if (mBackbuttonSelected && (mMouseCapture || m_use_mouse == 1)) { - screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_ColorOverlay, MAKEARGB(40, 255,255,255), TAG_DONE); + DrawTexture(&twod, tex, x, y, DTA_CleanNoMove, true, DTA_ColorOverlay, MAKEARGB(40, 255,255,255), TAG_DONE); } else { - screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_Alpha, BackbuttonAlpha, TAG_DONE); + DrawTexture(&twod, tex, x, y, DTA_CleanNoMove, true, DTA_Alpha, BackbuttonAlpha, TAG_DONE); } } -#endif } diff --git a/wadsrc/static/demolition/graphics/M_BACK.png b/wadsrc/static/demolition/graphics/M_BACK.png new file mode 100644 index 0000000000000000000000000000000000000000..9d562600de6dc3f434b91efc41d3d5c7086865dc GIT binary patch literal 1254 zcmeAS@N?(olHy`uVBq!ia0vp^0w6XAGmxB~Dklb{7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$jZRL%n;xc;tCW8>XKk!&}3jRWMBZwdoeHsFfc?hFk~?>6f-cCGB8v#Ff3zW zxXi$Cn}Ojw1H(U{o>4Fw0>dH%x&^oW0Ok{hk|4j}|05eP1b=5&1x6}ofkz}T<8upw zFk^j6{6wH&vZsq9{6&ZOT&SkD0}5qZw5ylUFnC=#yN-B;A*tzWUJ5$rckrA975* g<0X3T-GZb47;GY4_t?xW>;@$)Pgg&ebxsLQ00X&F4*&oF literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/ionfury/demolition/graphics/M_BACK.png b/wadsrc/static/filter/ionfury/demolition/graphics/M_BACK.png new file mode 100644 index 0000000000000000000000000000000000000000..84a57c49c0c1eb1225191e612dbc3cf49cfb4866 GIT binary patch literal 1255 zcmeAS@N?(olHy`uVBq!ia0vp^0w6XAGmxB~Dklb{7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$jZRL%n;xc;tCXJV&`Gv6l4*QV-;3mmo(szHRDvU=2CIy(emTb4dvAf=QE5J za;z2)o+A;qNIG%5Ov-MVl)XTWqhK@yhI$Ar<({Gs%qI*bL4LviM>b#x{?4unj8D!2 zkH}&M25vzRW~@(%p9mC8@pN$vkqD1H?J0CXfx{&*N42oSdC&jY-iFm1ez@AUUd!jP z*<&4gV6w0u>xAsn8@Lp%*-Z-dE13H4T*gw~>#@h@ENANYbS#Xu;H7c|tC-C6V_~g- o)r%BX9}-jAIaTY;UB~XPjP{3Jk94Lf?F1z%Pgg&ebxsLQ0PXux^#A|> literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/nam/demolition/graphics/M_BACK.png b/wadsrc/static/filter/nam/demolition/graphics/M_BACK.png new file mode 100644 index 0000000000000000000000000000000000000000..32e49b8639f5732c23c43ab24b0f5e2d78cdd619 GIT binary patch literal 1254 zcmeAS@N?(olHy`uVBq!ia0vp^0w6XAGmxB~Dklb{7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$jZRL%n;xc;tCXJV`b&!VCU!M5f?|5|@{eR8f@GQdiQ|RMFE?HPlge zv^EL$aSroyO^onMi4IJO2?S~!1*0J_)I&g1VcB$GK4B;c@(cbyvH?TzcXm}^d~z0e zL>4nJa0`MkV|_~eM4(`@r;B5VM0o6JPoV<}94>)5s)ZfF@9M*qA86^+1^O@iD$UIQ z-cR(yla^q{C%25&Fm-J0Pnjwlvvj|4ROaE*>xR!)GA!D&F_bap7e`nl>+z)k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$jZRL%n;xc;tCXJV`b&!VCU!M5f?|5|@{eR8f@GQdiQ|RMFE?HPlge zv^EL$aSroyO^onMi4IJO2?S~!1*0J_)I&g1VcB$GK4B;c@(cbyvH?TzcXm}^d~z0e zL>4nJa0`MkV|_~eM4(`@r;B5VM0o6JPoV<}94>)5s)ZfF@9M*qA86^+1^O@iD$UIQ z-cR(yla^q{C%25&Fm-J0Pnjwlvvj|4ROaE*>xR!)GA!D&F_bap7e`nl>+z)k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$jZRL%n;xc;tCXJV`b&!VCU!M5f?|5|@{eR8f@GQdiQ|RMFE?HPlge zv^EL$aSroyO^onMi4IJO2?S~!1*0J_)I&g1VcB$GK4B;c@(cbyvH?TzcXm}^d~z0e zL>4nJa0`MkV|_~eM4(`@r;B5VM0o6JPoV<}94>)5s)ZfF@9M*qA86^+1^O@iD$UIQ z-cR(yla^q{C%25&Fm-J0Pnjwlvvj|4ROaE*>xR!)GA!D&F_bap7e`nl>+z) Date: Wed, 4 Dec 2019 18:52:39 +0100 Subject: [PATCH 108/203] - minor menu tweaks and fixes. --- source/rr/src/gamedef.cpp | 2 + wadsrc/static/demolition/language.csv | 3 +- wadsrc/static/demolition/menudef.txt | 78 ++++++++++++++++----------- 3 files changed, 52 insertions(+), 31 deletions(-) diff --git a/source/rr/src/gamedef.cpp b/source/rr/src/gamedef.cpp index a05ba4fae..15352437a 100644 --- a/source/rr/src/gamedef.cpp +++ b/source/rr/src/gamedef.cpp @@ -907,6 +907,7 @@ int32_t C_AllocQuote(int32_t qnum) void C_InitQuotes(void) { +#if 0 // if we want to keep this it must be done differently. This does not play nice with text substitution. auto openkeys = Bindings.GetKeysForCommand("+open"); if (openkeys.Size()) { @@ -915,6 +916,7 @@ void C_InitQuotes(void) quoteMgr.Substitute(QUOTE_DEAD, "OPEN", OpenGameFunc); quoteMgr.Substitute(QUOTE_DEAD, "USE", OpenGameFunc); } +#endif g_numObituaries = 48; for (bssize_t i = g_numObituaries - 1; i >= 0; i--) diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index 44564d3bc..e6fd7bc96 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -417,6 +417,7 @@ Name,PLYRMNU_NAME,,,,Jméno,,,Nomo,Nombre,,Nimi,Nom,Név,Nome,名前,이름,Naam Team,PLYRMNU_TEAM,,,,Tým,,,Teamo,Equipo,,Joukkue,Equipe,Csapat,Squadra,チーム,팀,Team,Drużyna,Equipe,Equipa,,Команда,Тим Color,PLYRMNU_PLAYERCOLOR,,,Colour,Barva,Farbe,,Koloro,,,Väri,Couleur,Szín,Colore,色,색상,Kleur,Kolor,Cor,,,Цвет,Боја Multiplayer taunts,PLRMNU_TAUNTS,,,,,Mehrspieler-Spott,,,,,,,,,,,,,,,,, +Gender,PLYRMNU_PLAYERGENDER,,,,Pohlaví,Geschlecht,,Genro,Género,,Sukupuoli,Genre,Nem,Sesso,性別,성별,Geslacht,Płeć,Gênero,,,Пол,Пол Male,OPTVAL_MALE,,,,Muž,Männlich,,Vira (Li),Masculino,,Miespuolinen,Masculin,,Maschio,男,남성,Man,Mężczyzna,Masculino,,,Мужской,Мушко Female,OPTVAL_FEMALE,,,,Žena,Weiblich,,Ina (Ŝi),Femenino,,Naispuolinen,Féminin,,Femmina,女,여성,Vrouw,Kobieta,Feminino,,,Женский,Женско Neutral,OPTVAL_NEUTRAL,,,,Neutrální,Neutral,,Neŭtrala (Ri),Neutro,,Sukupuoleton,Neutre,,Neutrale,中間,중성,Neutraal,Neutralne,Neutro,,,Нейтральный,Неутрално @@ -479,7 +480,7 @@ Generic,DSPLYMNU_GENERIC,,,,,Generisch,,,,,,,,,,,,,,,,, Show Map Name,DSPLYMNU_SHOWMAPNAME,,,,,"Levelnamen anzeigen ",,,,,,,,,,,,,,,,, FOV,DSPLYMNU_FOV,,,,,Gesichtsfeld,,,,,,,,,,,,,,,,, -Crosshair,DSPLYMNU_CROSSHAIRON,,,,Křížek,Fadenkreuz,,Reteto,Retícula,,Tähtäin,Viseur,,Mirino,クロスヘア,조준점,Draadkruis,Celownik,Mira,,,Прицел,Нишан +Crosshair,DSPLYMNU_CROSSHAIR,,,,Křížek,Fadenkreuz,,Reteto,Retícula,,Tähtäin,Viseur,,Mirino,クロスヘア,조준점,Draadkruis,Celownik,Mira,,,Прицел,Нишан HUD Options,OPTMNU_HUD,,,,Nastavení HUD,HUD Einstellungen,,Agordoj de HUD,Opciones del HUD,,Tilanäytön asetukset,Options de l'ATH,HUD beállítások,Opzioni HUD,HUD オプション,HUD 설정,HUD opties,Opcje Paska HUD,Opções de HUD,,,HUD,HUD Polymost Options,OPTMNU_POLYMOST,,,,,Polymost Einstellungen,,,,,,,,,,,,,,,,, Texture Filter mode,GLTEXMNU_TEXFILTER,,,,Režim filtrování textur,Texturfiltermodus,,Reĝimo por Teksturfiltrado,Modo de filtro de texturas,,Pintakuviointien suodatustapa,Mode de Filtrage Texture,,Modalità filtro texture,テクスチャーフィルター モード,텍스쳐 필터 모드,Textuur Filter mode,Tryb Filtrowania Tekstur,Modo de filtragem de textura,,,Фильтрация текстур,Текстурни филтер мод diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 9e6eee177..64acbf1a4 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -962,7 +962,7 @@ OptionMenu "JoystickConfigMenu" //protected OptionValue "PlayerColors" { - 0, OPTVAL_AUTO" + 0, "$OPTVAL_AUTO" 1, "$TXT_COLOR_BLUE" 2, "TXT_COLOR_RED" 3, "TXT_COLOR_GREEN" @@ -998,7 +998,7 @@ OptionMenu "NewPlayerMenu" //protected TextField "$PLYRMNU_NAME", playername Option "$PLYRMNU_TEAM", "playerteam", "PlayerTeam" Option "$PLYRMNU_PLAYERCOLOR", "playercolor", "PlayerColors" - Option "$PLYRMNU_PLAYERGENDER", "playergender", "Gender"" + Option "$PLYRMNU_PLAYERGENDER", "playergender", "Gender" Submenu "$PLRMNU_TAUNTS", "TauntsMenu" Class "NewPlayerMenu" } @@ -1007,15 +1007,15 @@ OptionMenu "TauntsMenu" //protected { Title "$PLRMNU_TAUNTS" TextField "1", "combatmacro0" - TextField "2", "combatmacro0" - TextField "3", "combatmacro0" - TextField "4", "combatmacro0" - TextField "5", "combatmacro0" - TextField "6", "combatmacro0" - TextField "7", "combatmacro0" - TextField "8", "combatmacro0" - TextField "9", "combatmacro0" - TextField "10", "combatmacro0" + TextField "2", "combatmacro1" + TextField "3", "combatmacro2" + TextField "4", "combatmacro3" + TextField "5", "combatmacro4" + TextField "6", "combatmacro5" + TextField "7", "combatmacro6" + TextField "8", "combatmacro7" + TextField "9", "combatmacro8" + TextField "10", "combatmacro9" } //------------------------------------------------------------------------------------------- @@ -1068,12 +1068,12 @@ OptionMenu GameplayOptions //protected OptionValue "FilterModes" { 0, "$OPTVAL_NONE" - 1, "$OPTVAL_NONENEARESTMIPMAP" - 5, "$OPTVAL_NONELINEARMIPMAP" + 2, "$OPTVAL_NONENEARESTMIPMAP" + 4, "$OPTVAL_NONELINEARMIPMAP" 6, "$OPTVAL_NONETRILINEAR" - 2, "$OPTVAL_LINEAR_2" - 3, "$OPTVAL_BILINEAR" - 4, "$OPTVAL_TRILINEAR" + 3, "$OPTVAL_LINEAR_2" + 1, "$OPTVAL_BILINEAR" + 5, "$OPTVAL_TRILINEAR" } OptionValue "Anisotropy" @@ -1097,6 +1097,11 @@ OptionMenu "VideoOptions" //protected Slider "$DSPLYMNU_CONTRAST", "vid_contrast", 0.1, 3.0, 0.1 Slider "$DSPLYMNU_SATURATION", "vid_saturation", -3.0, 3.0, 0.25, 2 + StaticText "" + Option "$DSPLYMNU_VOXELS", "r_voxels", "OnOff" + StaticText "" + Slider "$DSPLYMNU_FOV", "r_fov", 60, 130, 10, 1 + StaticText "" Option "$GLTEXMNU_TEXFILTER", hw_texfilter, "FilterModes" Option "$GLTEXMNU_ANISOTROPIC", hw_anisotropy, "Anisotropy" @@ -1121,18 +1126,20 @@ OptionMenu "HUDOptions" //protected Title "$OPTMNU_HUD" Slider "$DSPLYMNU_SCREENSIZE", "hud_size", 3.0, 12.0, 1.0, 0 - Slider "$DSPLYMNU_SBSCALE", "hud_scale", 0.3, 1.0, 0.1, 2 + ifgame(duke, nam, ww2gi, redneck, redneckrides, fury) // Fixme: The scaling really needs to be taken out of the game code. + { + Slider "$DSPLYMNU_SBSCALE", "hud_scale", 0.3, 1.0, 0.1, 2 + } Option "$DSPLYMNU_LEVELSTATS", "hud_stats", "OnOff" - Slider "$DSPLYMNU_TEXTSCALE", "hud_textscale", 0.3, 1.0, 0.1, 2 + ifgame(duke, nam, ww2gi, redneck, redneckrides, fury) + { + Slider "$DSPLYMNU_TEXTSCALE", "hud_textscale", 0.3, 1.0, 0.1, 2 + } StaticText "" Option "$DSPLYMNU_MESSAGES", "hud_messages", "HudMessages" StaticText "" Option "$DSPLYMNU_CROSSHAIR", "cl_crosshair", OnOff Slider "$DSPLYMNU_CROSSHAIRSCALE", "cl_crosshairscale", 50, 100, 10, 1 - StaticText "" - Option "$DSPLYMNU_VOXELS", "r_voxels", "OnOff" - StaticText "" - Option "$DSPLYMNU_FOV", "r_fov", 60, 130, 10, 1 } @@ -1192,7 +1199,7 @@ OptionMenu "JoinGameMenu" { TextField "$NETMNU_SERVER", "m_server" TextField "$NETMNU_PORT", "m_netport" - SaveCommand "$NETMNU_CONNECT", "MultiConnect" + SafeCommand "$NETMNU_CONNECT", "MultiConnect" } OptionValue "MultiGameType" @@ -1204,16 +1211,27 @@ OptionValue "MultiGameType" 4, "$NETMNU_GAMETYPE5" } +OptionValue "MultiEpisode" +{ + 0, "1" + 0, "2" + 0, "3" + 0, "4" + 0, "5" + 0, "6" + 0, "7" +} + OptionMenu "MultiOptionsMenu" { title "$NETMNU_OPTIONS" - Option "$NETMNU_GAMETYPE", "m_coop" - Option "$NETMNU_EPISODE", "m_episode_number" - Option "$NETMNU_LEVEL", "m_level_number" + Option "$NETMNU_GAMETYPE", "m_coop", "MultiGameType" + Option "$NETMNU_EPISODE", "m_episode_number", "MultiEpisode" + Option "$NETMNU_LEVEL", "m_level_number", "MultiEpisode" Submenu "$MNU_USERMAP", "MultiUserMap" // todo: fileselect item - Option "$NETMNU_MONSTERS", "m_monsters" - Option "$NETMNU_MARKERS", "m_marker" - Option "$NETMNU_MAPEXITS", "m_noexit" - Option "$NETMNU_FFIRE", "m_ffire" + Option "$NETMNU_MONSTERS", "m_monsters", "OnOff" + Option "$NETMNU_MARKERS", "m_marker", "OnOff" + Option "$NETMNU_MAPEXITS", "m_noexit", "OnOff" + Option "$NETMNU_FFIRE", "m_ffire", "OnOff" SafeCommand "$NETMNU_ACCEPT", "MultiAccept" } From 6d04f0f159e5299922d0fef3c05be7c2b26e6605 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 4 Dec 2019 21:35:35 +0100 Subject: [PATCH 109/203] - added option to print custom messages with Duke Nukem's quote system. - hooked up all front ends with a generic message printing function so that common code can access the native message displays. This is needed for consolidation of some input actions which are mostly identical but print messages. - preparations for a generic message system. --- source/blood/src/blood.h | 2 + source/blood/src/messages.cpp | 2 +- source/blood/src/view.cpp | 11 ++++- source/build/include/baselayer.h | 9 ++++ source/common/console/c_console.cpp | 6 +-- source/common/gamecvars.cpp | 6 --- source/common/secrets.cpp | 2 +- source/common/utility/printf.h | 6 +-- source/duke3d/src/duke3d.h | 1 + source/duke3d/src/screentext.cpp | 72 ++++++++++++++++++++++------- source/rr/src/duke3d.h | 1 + source/rr/src/screentext.cpp | 72 +++++++++++++++++++++-------- source/sw/src/game.h | 1 + source/sw/src/text.cpp | 47 +++++-------------- 14 files changed, 150 insertions(+), 88 deletions(-) diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index eda86e57c..5328b470b 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -97,6 +97,8 @@ struct GameInterface : ::GameInterface void DrawMenuCaption(const DVector2& origin, const char* text) override; bool SaveGame(FSaveGameNode*) override; bool LoadGame(FSaveGameNode*) override; + void DoPrintMessage(int prio, const char*) override; + }; END_BLD_NS diff --git a/source/blood/src/messages.cpp b/source/blood/src/messages.cpp index 0ceafed93..0e5f3bea5 100644 --- a/source/blood/src/messages.cpp +++ b/source/blood/src/messages.cpp @@ -325,7 +325,7 @@ void CGameMessageMgr::SetState(char state) void CGameMessageMgr::Add(const char *pText, char a2, const int pal, const MESSAGE_PRIORITY priority) { - if (a2 && messageFlags) + if (a2 && messageFlags && hud_messages == 1) // add only if messages are enabled and in native format { messageStruct *pMessage = &messages[nextMessagesIndex]; strncpy(pMessage->text, pText, kMaxMessageTextLength-1); diff --git a/source/blood/src/view.cpp b/source/blood/src/view.cpp index 61acd766a..6044a2176 100644 --- a/source/blood/src/view.cpp +++ b/source/blood/src/view.cpp @@ -2759,16 +2759,23 @@ void viewSetSystemMessage(const char* pMessage, ...) { char buffer[1024]; va_list args; va_start(args, pMessage); vsprintf(buffer, pMessage, args); - OSD_Printf("%s\n", buffer); // print it also in console + Printf(PRINT_HIGH | PRINT_NOTIFY, "%s\n", buffer); // print it also in console gGameMessageMgr.Add(buffer, 15, 7, MESSAGE_PRIORITY_SYSTEM); } void viewSetMessage(const char *pMessage, const int pal, const MESSAGE_PRIORITY priority) { - OSD_Printf("%s\n", pMessage); + int printlevel = priority < 0 ? PRINT_LOW : priority < MESSAGE_PRIORITY_SYSTEM ? PRINT_MEDIUM : PRINT_HIGH; + Printf(printlevel|PRINT_NOTIFY, "%s\n", pMessage); gGameMessageMgr.Add(pMessage, 15, pal, priority); } +void GameInterface::DoPrintMessage(int prio, const char*msg) +{ + viewSetMessage(msg, 0, prio == PRINT_LOW ? MESSAGE_PRIORITY_PICKUP : prio == PRINT_MEDIUM ? MESSAGE_PRIORITY_NORMAL : MESSAGE_PRIORITY_SYSTEM); +} + + void viewDisplayMessage(void) { gGameMessageMgr.Display(); diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index c65cbd35b..4d9ac6269 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -227,6 +227,15 @@ struct GameInterface virtual void DrawMenuCaption(const DVector2& origin, const char* text) {} virtual bool SaveGame(FSaveGameNode*) { return false; } virtual bool LoadGame(FSaveGameNode*) { return false; } + virtual void DoPrintMessage(int prio, const char*) = 0; + void PrintMessage(int prio, const char*fmt, ...) + { + va_list ap; + va_start(ap, fmt); + FString f; + f.VFormat(fmt, ap); + DoPrintMessage(prio, fmt); + } }; extern GameInterface* gi; diff --git a/source/common/console/c_console.cpp b/source/common/console/c_console.cpp index 594d56137..0b9ab28e8 100644 --- a/source/common/console/c_console.cpp +++ b/source/common/console/c_console.cpp @@ -901,7 +901,7 @@ int PrintString (int iprintlevel, const char *outline) #endif conbuffer->AddText(printlevel, outline); - if (vidactive && screen && !(iprintlevel & PRINT_NONOTIFY)) + if (vidactive && screen && (iprintlevel & PRINT_NOTIFY)) { NotifyStrings.AddString(printlevel, outline); } @@ -959,7 +959,7 @@ void OSD_Printf(const char *format, ...) int count; va_start (argptr, format); - count = VPrintf (PRINT_HIGH|PRINT_NONOTIFY, format, argptr); + count = VPrintf (PRINT_HIGH, format, argptr); va_end (argptr); } @@ -1802,7 +1802,7 @@ void C_MidPrint (FFont *font, const char *msg, bool bold) if (msg != nullptr) { auto color = (EColorRange)PrintColors[bold? PRINTLEVELS+1 : PRINTLEVELS]; - Printf(PRINT_HIGH|PRINT_NONOTIFY, TEXTCOLOR_ESCAPESTR "%c%s\n%s\n%s\n", color, console_bar, msg, console_bar); + Printf(PRINT_HIGH, TEXTCOLOR_ESCAPESTR "%c%s\n%s\n%s\n", color, console_bar, msg, console_bar); StatusBar->AttachMessage (Create(font, msg, 1.5f, 0.375f, 0, 0, color, con_midtime), MAKE_ID('C','N','T','R')); } diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index c5d018470..a99cf27a1 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -266,12 +266,6 @@ CUSTOM_CVARD(Int, hud_messages, 1, CVAR_ARCHIVE, "enable/disable showing message CCMD (togglemessages) { - // Fixme: Needs to redirect to the frontend specific routine to handle on-screen messages. - // Ideally as an option to use the ZDoom-style notification. - // P_DoQuote(fta ? QUOTE_MESSAGES_ON : QUOTE_MESSAGES_OFF, &myplayer); (Duke/Redneck - beware of crappy implementation!!! - // void viewSetMessage(const char *pMessage, const int pal, const MESSAGE_PRIORITY priority) Blood - // void viewSetSystemMessage(const char* pMessage, ...) alternative - // void PutStringInfo(PLAYERp pp, const char *string) SW if (hud_messages) { diff --git a/source/common/secrets.cpp b/source/common/secrets.cpp index 21cd0d5d7..2e2b32a78 100644 --- a/source/common/secrets.cpp +++ b/source/common/secrets.cpp @@ -166,7 +166,7 @@ void SECRET_SetMapName(const char *filename, const char *_maptitle) void SECRET_Trigger(int num) { - if (secret_notify) Printf(PRINT_NONOTIFY, "Secret #%d found\n", num); + if (secret_notify) Printf("Secret #%d found\n", num); if (discovered_secrets.Find(num) == discovered_secrets.Size()) discovered_secrets.Push(num); } diff --git a/source/common/utility/printf.h b/source/common/utility/printf.h index fababaa95..ad5a04575 100644 --- a/source/common/utility/printf.h +++ b/source/common/utility/printf.h @@ -23,7 +23,7 @@ enum PRINT_LOG, // only to logfile PRINT_BOLD = 200, // What Printf_Bold used PRINT_TYPES = 1023, // Bitmask. - PRINT_NONOTIFY = 1024, // Flag - do not add to notify buffer + PRINT_NOTIFY = 1024, // Flag - add to notify buffer PRINT_NOLOG = 2048, // Flag - do not print to log file }; @@ -67,12 +67,12 @@ inline void buildprintf(const char *format, Args&&... args) //ATTRIBUTE((format( inline void initputs(const char *s) { - PrintString(PRINT_HIGH|PRINT_NONOTIFY, s); + PrintString(PRINT_HIGH, s); } inline void buildputs(const char *s) { - PrintString(PRINT_HIGH|PRINT_NONOTIFY, s); + PrintString(PRINT_HIGH, s); } void debugprintf(const char* f, ...); // Prints to the debugger's log. diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index d43f0f2e3..85978763d 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -168,6 +168,7 @@ struct GameInterface : ::GameInterface void DrawMenuCaption(const DVector2& origin, const char* text) override; bool SaveGame(FSaveGameNode*) override; bool LoadGame(FSaveGameNode*) override; + void DoPrintMessage(int prio, const char*) override; }; diff --git a/source/duke3d/src/screentext.cpp b/source/duke3d/src/screentext.cpp index 5af0e37b0..e3cf83e13 100644 --- a/source/duke3d/src/screentext.cpp +++ b/source/duke3d/src/screentext.cpp @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gstrings.h" #include "quotemgr.h" +#include "c_dispatch.h" BEGIN_DUKE_NS // get the string length until the next '\n' @@ -988,16 +989,20 @@ void G_AddUserQuote(const char *daquote) { int32_t i; - for (i=MAXUSERQUOTES-1; i>0; i--) - { - Bstrcpy(user_quote[i], user_quote[i-1]); - user_quote_time[i] = user_quote_time[i-1]; - } - Bstrcpy(user_quote[0], daquote); - OSD_Printf("%s\n", daquote); + if (hud_messages == 0) return; + Printf(PRINT_MEDIUM | PRINT_NOTIFY, "%s\n", daquote); + if (hud_messages == 1) + { + for (i = MAXUSERQUOTES - 1; i > 0; i--) + { + Bstrcpy(user_quote[i], user_quote[i - 1]); + user_quote_time[i] = user_quote_time[i - 1]; + } + Bstrcpy(user_quote[0], daquote); - user_quote_time[0] = hud_messagetime; - pub = NUMPAGES; + user_quote_time[0] = hud_messagetime; + pub = NUMPAGES; + } } int32_t textsc(int32_t sc) @@ -1006,6 +1011,7 @@ int32_t textsc(int32_t sc) } + #define FTAOPAQUETIME 30 // alpha increments of 8 --> 256 / 8 = 32 --> round up to power of 2 --> 32 --> divide by 2 --> 16 alphatabs required @@ -1050,6 +1056,8 @@ static FORCE_INLINE int32_t text_ypos(void) #endif } +static FString text_quote; // To put text into the quote display that does not come from the quote array. (Is it really necessary to implement everything as a hack??? :( ) + // this handles both multiplayer and item pickup message type text // both are passed on to gametext void G_PrintGameQuotes(int32_t snum) @@ -1099,7 +1107,8 @@ void G_PrintGameQuotes(int32_t snum) } #endif - height = gametext_(x, y, quoteMgr.GetQuote(ps->ftq), textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1<<16); + if (text_quote.IsNotEmpty() && ps->ftq == -32878) height = gametext_(x, y, text_quote, textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1 << 16); + else height = gametext_(x, y, quoteMgr.GetQuote(ps->ftq), textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1<<16); } while (0); @@ -1141,18 +1150,47 @@ void P_DoQuote(int32_t q, DukePlayer_t *p) if (p->fta > 0 && q != QUOTE_RESERVED && q != QUOTE_RESERVED2) if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return; - p->fta = 100; - if (p->ftq != q) { auto qu = quoteMgr.GetQuote(q); if (p == g_player[screenpeek].ps && qu[0] != '\0') - OSD_Printf(cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", qu); + Printf(PRINT_MEDIUM | PRINT_NOTIFY, cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", qu); - p->ftq = q; - } + } - pub = NUMPAGES; - pus = NUMPAGES; + if (hud_messages == 1) + { + p->ftq = q; + p->fta = 100; + pub = NUMPAGES; + pus = NUMPAGES; + } } + +void GameInterface::DoPrintMessage(int prio, const char* t) +{ + auto p = g_player[myconnectindex].ps; // text quotes always belong to the local player. + int32_t cq = 0; + + if (hud_messages == 0 || !(p->gm & MODE_GAME)) + return; + + if (p->fta > 0) + if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return; + + if (p == g_player[screenpeek].ps) + Printf(prio | PRINT_NOTIFY, cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", t); + + if (hud_messages == 1) + { + p->fta = 100; + p->ftq = -32768; + text_quote = t; + pub = NUMPAGES; + pus = NUMPAGES; + } + +} + + END_DUKE_NS diff --git a/source/rr/src/duke3d.h b/source/rr/src/duke3d.h index 44fd44bce..52b1985e2 100644 --- a/source/rr/src/duke3d.h +++ b/source/rr/src/duke3d.h @@ -168,6 +168,7 @@ struct GameInterface : ::GameInterface void DrawMenuCaption(const DVector2& origin, const char* text) override; bool SaveGame(FSaveGameNode*) override; bool LoadGame(FSaveGameNode*) override; + void DoPrintMessage(int prio, const char* text) override; }; END_RR_NS diff --git a/source/rr/src/screentext.cpp b/source/rr/src/screentext.cpp index ec66b14c2..327fcb6c4 100644 --- a/source/rr/src/screentext.cpp +++ b/source/rr/src/screentext.cpp @@ -986,20 +986,24 @@ void captionmenutext(int32_t x, int32_t y, char const *t) int32_t user_quote_time[MAXUSERQUOTES]; static char user_quote[MAXUSERQUOTES][178]; -void G_AddUserQuote(const char *daquote) +void G_AddUserQuote(const char* daquote) { - int32_t i; + int32_t i; - for (i=MAXUSERQUOTES-1; i>0; i--) - { - Bstrcpy(user_quote[i], user_quote[i-1]); - user_quote_time[i] = user_quote_time[i-1]; - } - Bstrcpy(user_quote[0], daquote); - OSD_Printf("%s\n", daquote); + if (hud_messages == 0) return; + Printf(PRINT_MEDIUM | PRINT_NOTIFY, "%s\n", daquote); + if (hud_messages == 1) + { + for (i = MAXUSERQUOTES - 1; i > 0; i--) + { + Bstrcpy(user_quote[i], user_quote[i - 1]); + user_quote_time[i] = user_quote_time[i - 1]; + } + Bstrcpy(user_quote[0], daquote); - user_quote_time[0] = hud_messagetime; - pub = NUMPAGES; + user_quote_time[0] = hud_messagetime; + pub = NUMPAGES; + } } int32_t textsc(int32_t sc) @@ -1051,6 +1055,8 @@ static FORCE_INLINE int32_t text_ypos(void) #endif } +static FString text_quote; // To put text into the quote display that does not come from the quote array. (Is it really necessary to implement everything as a hack??? :( ) + // this handles both multiplayer and item pickup message type text // both are passed on to gametext void G_PrintGameQuotes(int32_t snum) @@ -1100,8 +1106,9 @@ void G_PrintGameQuotes(int32_t snum) } #endif - height = gametext_(x, y, quoteMgr.GetQuote(ps->ftq), textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1<<16); - } + if (text_quote.IsNotEmpty() && ps->ftq == -32768) height = gametext_(x, y, text_quote, textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1 << 16); + else height = gametext_(x, y, quoteMgr.GetQuote(ps->ftq), textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1 << 16); + } while (0); @@ -1142,18 +1149,45 @@ void P_DoQuote(int32_t q, DukePlayer_t *p) if (p->fta > 0 && q != QUOTE_RESERVED && q != QUOTE_RESERVED2) if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return; - p->fta = 100; - if (p->ftq != q) { auto qu = quoteMgr.GetQuote(q); if (p == g_player[screenpeek].ps && qu[0] != '\0') - OSD_Printf(cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", qu); + Printf(PRINT_NOTIFY, cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", qu); - p->ftq = q; } - pub = NUMPAGES; - pus = NUMPAGES; + if (hud_messages == 1) + { + p->ftq = q; + p->fta = 100; + pub = NUMPAGES; + pus = NUMPAGES; + } } + +void GameInterface::DoPrintMessage(int prio, const char* t) +{ + auto p = g_player[myconnectindex].ps; // text quotes always belong to the local player. + int32_t cq = 0; + + if (hud_messages == 0 || !(p->gm & MODE_GAME)) + return; + + if (p->fta > 0) + if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return; + + if (p == g_player[screenpeek].ps) + Printf(PRINT_NOTIFY, cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", t); + + if (hud_messages == 1) + { + p->fta = 100; + p->ftq = -32768; + text_quote = t; + pub = NUMPAGES; + pus = NUMPAGES; + } +} + END_RR_NS diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 9658cb7cf..50005d389 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -2387,6 +2387,7 @@ struct GameInterface : ::GameInterface void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) override; bool LoadGame(FSaveGameNode* sv) override; bool SaveGame(FSaveGameNode* sv) override; + void DoPrintMessage(int prio, const char* text) override; }; diff --git a/source/sw/src/text.cpp b/source/sw/src/text.cpp index 2eec36424..842b77f7d 100644 --- a/source/sw/src/text.cpp +++ b/source/sw/src/text.cpp @@ -447,8 +447,17 @@ void PutStringInfo(PLAYERp pp, const char *string) if (!hud_messages) return; - OSD_Printf("%s", string); // Put it in the console too - PutStringInfoLine(pp, string); + Printf(PRINT_LOW|PRINT_NOTIFY, "%s", string); // Put it in the console too + if (hud_messages == 1) PutStringInfoLine(pp, string); +} + +void GameInterface::DoPrintMessage(int prio, const char* string) +{ + if (!hud_messages) + return; + + Printf(prio | PRINT_NOTIFY, "%s", string); // Put it in the console too + if (hud_messages == 1) PutStringInfoLine(&Player[myconnectindex], string); } void PutStringInfoLine(PLAYERp pp, const char *string) @@ -475,22 +484,6 @@ void PutStringInfoLine(PLAYERp pp, const char *string) //PutStringInfoLine2(pp, ""); } -void PutStringInfoLine2(PLAYERp pp, const char *string) -{ - short x,y; - short w,h; - - if (pp-Player != myconnectindex) - return; - - MNU_MeasureString(string, &w, &h); - - x = TEXT_XCENTER(w); - y = TEXT_INFO_LINE(1); - - PutStringTimer(pp, x, y, string, GlobInfoStringTime); -} - void pMenuClearTextLine(PLAYERp pp) { pMenuClearTextLineID(pp, ID_TEXT, TEXT_INFO_LINE(0), PRI_FRONT_MAX); @@ -500,22 +493,4 @@ void pMenuClearTextLine(PLAYERp pp) #define TEXT_PLAYER_INFO_TIME (3) #define TEXT_PLAYER_INFO_Y (200 - 40) -void PutStringPlayerInfo(PLAYERp pp, const char *string) -{ - short x,y; - short w,h; - - if (pp-Player != myconnectindex) - return; - - if (!hud_messages) - return; - - MNU_MeasureString(string, &w, &h); - - x = TEXT_XCENTER(w); - y = TEXT_PLAYER_INFO_Y; - - PutStringTimer(pp, x, y, string, GlobInfoStringTime); -} END_SW_NS From 3ea526055fb892541b4764bbefcb1bd1ef218215 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 4 Dec 2019 23:07:02 +0100 Subject: [PATCH 110/203] - added a generic message display, using ZDoom's code. This is mainly meant for Nam and WW2GI which have an ugly-as-hell font for these texts. --- source/build/include/baselayer.h | 2 +- source/common/console/c_console.cpp | 17 +++++++---------- source/common/gamecvars.cpp | 6 ++---- source/duke3d/src/screentext.cpp | 4 ++-- source/rr/src/screentext.cpp | 4 ++-- source/sw/src/game.cpp | 4 ++-- source/sw/src/text.cpp | 2 +- 7 files changed, 17 insertions(+), 22 deletions(-) diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 4d9ac6269..555f2a2ab 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -234,7 +234,7 @@ struct GameInterface va_start(ap, fmt); FString f; f.VFormat(fmt, ap); - DoPrintMessage(prio, fmt); + DoPrintMessage(prio, f); } }; diff --git a/source/common/console/c_console.cpp b/source/common/console/c_console.cpp index 0b9ab28e8..b9fba6b15 100644 --- a/source/common/console/c_console.cpp +++ b/source/common/console/c_console.cpp @@ -53,6 +53,8 @@ #include "v_font.h" #include "printf.h" #include "inputstate.h" +#include "i_time.h" +#include "gamecvars.h" #define LEFTMARGIN 8 @@ -123,15 +125,13 @@ static GameAtExit *ExitCmdList; #define SCROLLDN 2 #define SCROLLNO 0 -CVAR (Bool, show_messages, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - // Buffer for AddToConsole() static char *work = NULL; static int worklen = 0; CVAR(Float, con_notifytime, 3.f, CVAR_ARCHIVE) CVAR(Bool, con_centernotify, false, CVAR_ARCHIVE) -CUSTOM_CVAR(Int, con_scaletext, 0, CVAR_ARCHIVE) // Scale notify text at high resolutions? +CUSTOM_CVAR(Int, con_scaletext, 2, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // Scale notify text at high resolutions? { if (self < 0) self = 0; } @@ -541,7 +541,7 @@ CUSTOM_CVAR(Int, con_notifylines, NUMNOTIFIES, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) } -int PrintColors[PRINTLEVELS+2] = { CR_RED, CR_GOLD, CR_GRAY, CR_GREEN, CR_GREEN, CR_GOLD }; +int PrintColors[PRINTLEVELS+2] = { CR_RED, CR_GOLD, CR_YELLOW, CR_GREEN, CR_GREEN, CR_GOLD }; static void setmsgcolor (int index, int color); @@ -775,7 +775,7 @@ void FNotifyBuffer::AddString(int printlevel, FString source) TArray lines; int width; - if ((printlevel != 128 && !show_messages) || + if (hud_messages != 2 || source.IsEmpty() || //gamestate == GS_FULLCONSOLE || //gamestate == GS_DEMOSCREEN || @@ -901,7 +901,7 @@ int PrintString (int iprintlevel, const char *outline) #endif conbuffer->AddText(printlevel, outline); - if (vidactive && screen && (iprintlevel & PRINT_NOTIFY)) + if (vidactive && (iprintlevel & PRINT_NOTIFY)) { NotifyStrings.AddString(printlevel, outline); } @@ -1074,7 +1074,7 @@ void FNotifyBuffer::Tick() if (Text[i].TimeOut != 0 && --Text[i].TimeOut <= 0) break; } - if (i > 0) + if (i < Text.Size()) { Text.Delete(0, i); } @@ -1106,9 +1106,6 @@ void FNotifyBuffer::Draw() j = notify.TimeOut; if (j > 0) { - if (!show_messages && notify.PrintLevel != 128) - continue; - double alpha = (j < NOTIFYFADETIME) ? 1. * j / NOTIFYFADETIME : 1; if (notify.PrintLevel >= PRINTLEVELS) diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index a99cf27a1..5b8f21a32 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -257,7 +257,6 @@ CVARD(Bool, hud_showmapname, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enable/disab CVARD(Bool, hud_position, false, CVAR_ARCHIVE, "aligns the status bar to the bottom/top") CVARD(Bool, hud_bgstretch, false, CVAR_ARCHIVE|CVAR_FRONTEND_DUKELIKE, "enable/disable background image stretching in wide resolutions") CVARD(Int, hud_messagetime, 120, CVAR_ARCHIVE|CVAR_FRONTEND_DUKELIKE, "length of time to display multiplayer chat messages") -// Should be available to all games - the message handling should also be consolidated into a game independent feature. CUSTOM_CVARD(Int, hud_messages, 1, CVAR_ARCHIVE, "enable/disable showing messages") { if (self < 0 || self > 2) self = 1; @@ -266,16 +265,15 @@ CUSTOM_CVARD(Int, hud_messages, 1, CVAR_ARCHIVE, "enable/disable showing message CCMD (togglemessages) { - if (hud_messages) { - Printf (128, "%s\n", GStrings("MSGOFF")); + gi->PrintMessage(PRINT_MEDIUM, "%s\n", GStrings("MSGOFF")); hud_messages = false; } else { - Printf (128, "%s\n", GStrings("MSGON")); hud_messages = true; + gi->PrintMessage(PRINT_MEDIUM, "%s\n", GStrings("MSGON")); } } diff --git a/source/duke3d/src/screentext.cpp b/source/duke3d/src/screentext.cpp index e3cf83e13..792d70d89 100644 --- a/source/duke3d/src/screentext.cpp +++ b/source/duke3d/src/screentext.cpp @@ -1107,7 +1107,7 @@ void G_PrintGameQuotes(int32_t snum) } #endif - if (text_quote.IsNotEmpty() && ps->ftq == -32878) height = gametext_(x, y, text_quote, textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1 << 16); + if (text_quote.IsNotEmpty() && ps->ftq == -32768) height = gametext_(x, y, text_quote, textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1 << 16); else height = gametext_(x, y, quoteMgr.GetQuote(ps->ftq), textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1<<16); } while (0); @@ -1154,7 +1154,7 @@ void P_DoQuote(int32_t q, DukePlayer_t *p) { auto qu = quoteMgr.GetQuote(q); if (p == g_player[screenpeek].ps && qu[0] != '\0') - Printf(PRINT_MEDIUM | PRINT_NOTIFY, cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", qu); + Printf((cq? PRINT_LOW : PRINT_MEDIUM) | PRINT_NOTIFY, "%s\n", qu); } diff --git a/source/rr/src/screentext.cpp b/source/rr/src/screentext.cpp index 327fcb6c4..6aea65a7b 100644 --- a/source/rr/src/screentext.cpp +++ b/source/rr/src/screentext.cpp @@ -1153,7 +1153,7 @@ void P_DoQuote(int32_t q, DukePlayer_t *p) { auto qu = quoteMgr.GetQuote(q); if (p == g_player[screenpeek].ps && qu[0] != '\0') - Printf(PRINT_NOTIFY, cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", qu); + Printf((cq ? PRINT_LOW : PRINT_MEDIUM) | PRINT_NOTIFY, "%s\n", qu); } @@ -1178,7 +1178,7 @@ void GameInterface::DoPrintMessage(int prio, const char* t) if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return; if (p == g_player[screenpeek].ps) - Printf(PRINT_NOTIFY, cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", t); + Printf(prio|PRINT_NOTIFY, cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", t); if (hud_messages == 1) { diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index f9a0d98ad..e4a572994 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -1352,8 +1352,8 @@ InitLevel(void) if (ArgCheat) { - SWBOOL bak = hud_messages; - hud_messages = FALSE; + int bak = hud_messages; + hud_messages = 0; EveryCheatToggle(&Player[0],NULL); hud_messages = bak; GodMode = TRUE; diff --git a/source/sw/src/text.cpp b/source/sw/src/text.cpp index 842b77f7d..bdeabf16c 100644 --- a/source/sw/src/text.cpp +++ b/source/sw/src/text.cpp @@ -447,7 +447,7 @@ void PutStringInfo(PLAYERp pp, const char *string) if (!hud_messages) return; - Printf(PRINT_LOW|PRINT_NOTIFY, "%s", string); // Put it in the console too + Printf(PRINT_MEDIUM|PRINT_NOTIFY, "%s", string); // Put it in the console too if (hud_messages == 1) PutStringInfoLine(pp, string); } From 525cf28d29ee1bf2502f638535905cce62c3dcac Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 4 Dec 2019 23:09:09 +0100 Subject: [PATCH 111/203] - commented FBaseCVar::GetHumanString back in. This had to be deactivated when adding the code, but was forgotten when everything was ready. --- source/common/console/c_cvars.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/common/console/c_cvars.cpp b/source/common/console/c_cvars.cpp index 23b5d7afa..89d3aeee0 100644 --- a/source/common/console/c_cvars.cpp +++ b/source/common/console/c_cvars.cpp @@ -142,7 +142,7 @@ FBaseCVar::~FBaseCVar () const char *FBaseCVar::GetHumanString(int precision) const { assert(true); - return "";// GetGenericRep(CVAR_String).String; + return GetGenericRep(CVAR_String).String; } void FBaseCVar::ForceSet (UCVarValue value, ECVarType type, bool nouserinfosend) From cb0538d0f272568b1902cbd934054c8c2c414ca3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 5 Dec 2019 01:08:35 +0100 Subject: [PATCH 112/203] - mouse aiming cleanup. Reverted this to a sane setting, as it was in the original games and in all other games I have ever seen, i.e. there is a global setting to enable mouse view, and a button to manually trigger it. The toggle can be easily handled by flipping the CVAR directly. The main problem here was that it triggered a few cases for mouse-less gameplay in the default case with a mouse present, because the mouseaim CVAR was no longer what the game expected. This misguided change seems to have originated in JFDuke but by now had propagated to all the other games as well, the code was in all 4 frontends. --- source/blood/src/controls.cpp | 30 +----- source/blood/src/menu.cpp | 20 ---- source/common/gamecvars.cpp | 29 ++++-- source/common/gamecvars.h | 3 +- source/duke3d/src/game.cpp | 2 +- source/duke3d/src/gamestructures.cpp | 4 +- source/duke3d/src/menus.cpp | 5 - source/duke3d/src/network.cpp | 2 +- source/duke3d/src/player.cpp | 19 +--- source/rr/src/game.cpp | 2 +- source/rr/src/menus.cpp | 150 --------------------------- source/rr/src/net.cpp | 2 +- source/rr/src/player.cpp | 46 +------- source/sw/src/game.cpp | 39 +++---- source/sw/src/menus.cpp | 12 --- source/sw/src/player.cpp | 25 +---- wadsrc/static/demolition/menudef.txt | 3 +- 17 files changed, 54 insertions(+), 339 deletions(-) diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 8da67bced..4a85b6afe 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -121,32 +121,8 @@ void ctrlGetInput(void) D_ProcessEvents(); - if (in_aimmode) - g_MyAimMode = 0; - - if (buttonMap.ButtonDown(gamefunc_Mouse_Aiming)) - { - if (in_aimmode) - g_MyAimMode = 1; - else - { - buttonMap.ClearButton(gamefunc_Mouse_Aiming); - g_MyAimMode = !g_MyAimMode; - if (g_MyAimMode) - { - if (!bSilentAim) - viewSetMessage("Mouse aiming ON"); - } - else - { - if (!bSilentAim) - viewSetMessage("Mouse aiming OFF"); - gInput.keyFlags.lookCenter = 1; - } - } - } - else if (in_aimmode) - gInput.keyFlags.lookCenter = 1; + bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); + if (!mouseaim) gInput.keyFlags.lookCenter = 1; CONTROL_GetInput(&info); @@ -384,7 +360,7 @@ void ctrlGetInput(void) strafe = ClipRange(strafe-(info.dx<<5), -2048, 2048); - if (g_MyAimMode) + if (mouseaim) gInput.q16mlook = fix16_clamp(fix16_div(fix16_from_int(info.mousey), F16(128)), F16(-127)>>2, F16(127)>>2); else forward = ClipRange(forward - info.mousey, -2048, 2048); diff --git a/source/blood/src/menu.cpp b/source/blood/src/menu.cpp index 7bfad8f96..e65ecbefb 100644 --- a/source/blood/src/menu.cpp +++ b/source/blood/src/menu.cpp @@ -1852,11 +1852,6 @@ void SetMouseFilterInput(CGameMenuItemZBool *pItem) in_mousesmoothing = pItem->at20; } -void SetMouseAimMode(CGameMenuItemZBool *pItem) -{ - in_aimmode = pItem->at20; -} - void SetMouseVerticalAim(CGameMenuItemZBool *pItem) { in_mousemode = pItem->at20; @@ -1876,21 +1871,6 @@ void SetMouseDigitalAxis(CGameMenuItemZCycle *pItem) { } -void SetupMouseMenu(CGameMenuItemChain *pItem) -{ - UNREFERENCED_PARAMETER(pItem); - itemOptionsControlMouseAimFlipped.at20 = in_mouseflip; - itemOptionsControlMouseFilterInput.at20 = in_mousesmoothing; - itemOptionsControlMouseAimMode.at20 = in_aimmode; - itemOptionsControlMouseVerticalAim.at20 = g_MyAimMode; -} - -void PreDrawControlMouse(CGameMenuItem *pItem) -{ - if (pItem == &itemOptionsControlMouseVerticalAim) - pItem->bEnable = !in_aimmode; -} - void SetMouseButton(CGameMenuItemZCycle *pItem) { } diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index 5b8f21a32..edc505b4f 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -78,6 +78,14 @@ CUSTOM_CVARD(Bool, cl_autorun, true, CVAR_ARCHIVE, "enable/disable autorun") #endif } CVARD(Bool, cl_runmode, true, CVAR_ARCHIVE, "enable/disable modernized run key operation") + +bool G_CheckAutorun(bool button) +{ + if (cl_runmode) return button || cl_autorun; + else return button ^ !!cl_autorun; +} + + CVARD(Bool, cl_autosave, true, CVAR_ARCHIVE, "enable/disable autosaves") // Not implemented for Blood (but looks like the other games never check it either.) CVARD(Bool, cl_autosavedeletion, true, CVAR_ARCHIVE, "enable/disable automatic deletion of autosaves") // Not implemented for Blood CVARD(Int, cl_maxautosaves, 8, CVAR_ARCHIVE, "number of autosaves to keep before deleting the oldest") // Not implemented for Blood @@ -124,12 +132,6 @@ CUSTOM_CVARD(Int, cl_autovote, 0, CVAR_ARCHIVE, "enable/disable automatic voting if (self < 0 || self > 2) self = 0; } -bool G_CheckAutorun(bool button) -{ - if (cl_runmode) return button || cl_autorun; - else return button ^ !!cl_autorun; -} - // Demos CVARD_NAMED(Bool, demorec_diffcompress, demorec_diffcompress_cvar, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "Compression for diffs") @@ -319,14 +321,19 @@ CUSTOM_CVARD(Bool, in_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCAL CONTROL_MouseEnabled = (self && CONTROL_MousePresent); } -// Does it even make sense to have this configurable? It is in the menu but can be switched around at will by the mouse input code. -int32_t g_MyAimMode = 1; -CUSTOM_CVARD(Bool, in_mousemode, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "toggles vertical mouse view") +CVARD(Bool, in_mousemode, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "toggles vertical mouse view") + +CVAR(Bool, silentmouseaimtoggle, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + +CCMD(togglemouseaim) { - g_MyAimMode = self; // Needs to be copied to a shadow variable because the input code messes around with this setting - but that should not affect the user's original choice. + in_mousemode = !in_mousemode; + if (!silentmouseaimtoggle) + { + gi->DoPrintMessage(PRINT_MEDIUM, in_mousemode? GStrings("TXT_MOUSEAIMON") : GStrings("TXT_MOUSEAIMOFF")); + } } -CVARD(Bool, in_aimmode, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "0:toggle, 1:hold to aim") CVARD(Bool, in_mouseflip, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "invert vertical mouse movement") CUSTOM_CVARD(Int, in_mousebias, 0, CVAR_GLOBALCONFIG|CVAR_ARCHIVE, "emulates the original mouse code's weighting of input towards whichever axis is moving the most at any given time") diff --git a/source/common/gamecvars.h b/source/common/gamecvars.h index b0331a9d2..a65b555e8 100644 --- a/source/common/gamecvars.h +++ b/source/common/gamecvars.h @@ -90,16 +90,15 @@ EXTERN_CVAR(Float, vid_brightness) EXTERN_CVAR(Bool, in_joystick) EXTERN_CVAR(Bool, in_mouse) -EXTERN_CVAR(Bool, in_aimmode) EXTERN_CVAR(Int, in_mousebias) EXTERN_CVAR(Int, in_mousedeadzone) EXTERN_CVAR(Bool, in_mouseflip) EXTERN_CVAR(Bool, in_mousemode) +EXTERN_CVAR(Bool, in_aimmode) EXTERN_CVAR(Bool, in_mousesmoothing) EXTERN_CVAR(Float, in_mousesensitivity) EXTERN_CVAR(Float, in_mousescalex) EXTERN_CVAR(Float, in_mousescaley) -extern int32_t g_MyAimMode; EXTERN_CVAR(Bool, in_mousemode) EXTERN_CVAR(String, wchoice) diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 90ebdd3d7..5e2cec747 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -5721,7 +5721,7 @@ static void P_SetupMiscInputSettings(void) { auto ps = g_player[myconnectindex].ps; - ps->aim_mode = in_aimmode; + ps->aim_mode = in_mousemode; ps->auto_aim = cl_autoaim; ps->weaponswitch = cl_weaponswitch; } diff --git a/source/duke3d/src/gamestructures.cpp b/source/duke3d/src/gamestructures.cpp index be97ba659..9ea044ae4 100644 --- a/source/duke3d/src/gamestructures.cpp +++ b/source/duke3d/src/gamestructures.cpp @@ -1450,7 +1450,7 @@ int32_t __fastcall VM_GetUserdef(int32_t labelNum, int const lParm2) case USERDEFS_MOUSEFLIP: labelNum = !in_mouseflip; break; case USERDEFS_STATUSBARSCALE: labelNum = ud.statusbarscale; break; case USERDEFS_DRAWWEAPON: labelNum = r_drawweapon; break; - case USERDEFS_MOUSEAIMING: labelNum = in_aimmode; break; + case USERDEFS_MOUSEAIMING: labelNum = in_mousemode; break; case USERDEFS_WEAPONSWITCH: labelNum = cl_weaponswitch; break; case USERDEFS_DEMOCAMS: labelNum = cl_democams; break; case USERDEFS_COLOR: labelNum = playercolor; break; @@ -1643,7 +1643,7 @@ void __fastcall VM_SetUserdef(int const labelNum, int const lParm2, int32_t cons case USERDEFS_MOUSEFLIP: in_mouseflip.SetGenericRepDefault(iSet, CVAR_Int); break; case USERDEFS_STATUSBARSCALE: ud.statusbarscale = iSet; break; case USERDEFS_DRAWWEAPON: r_drawweapon.SetGenericRepDefault(iSet, CVAR_Int); break; - case USERDEFS_MOUSEAIMING: in_aimmode.SetGenericRepDefault(iSet, CVAR_Int); break; + case USERDEFS_MOUSEAIMING: break; // the script code has no business whatsoever changing this! case USERDEFS_WEAPONSWITCH: cl_weaponswitch.SetGenericRepDefault(iSet, CVAR_Int); break; case USERDEFS_DEMOCAMS: cl_democams = iSet; break; case USERDEFS_COLOR: /*playercolor.SetGenericRepDefault(iSet, CVAR_Int);*/ break; // the value range here does not match, so better leave the CVar alone. diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index 8bef91a7e..07e3e424f 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -653,11 +653,6 @@ static void Menu_Pre(MenuID_t cm) MenuEntry_DisableOnCondition(&ME_JOYSTICK_DEFAULTS_PRO, !joystick.isGameController); break; -#ifndef EDUKE32_SIMPLE_MENU - case MENU_MOUSESETUP: - MenuEntry_DisableOnCondition(&ME_MOUSESETUP_MOUSEAIMING, in_aimmode); - break; -#endif case MENU_NETOPTIONS: if (MEOSV_NetEpisodes[MEO_NETOPTIONS_EPISODE.currentOption] == MAXVOLUMES) MEL_NETOPTIONS[2] = &ME_NETOPTIONS_USERMAP; diff --git a/source/duke3d/src/network.cpp b/source/duke3d/src/network.cpp index 2de930adf..2c421971c 100644 --- a/source/duke3d/src/network.cpp +++ b/source/duke3d/src/network.cpp @@ -4799,7 +4799,7 @@ void Net_SendClientInfo(void) l += 32; tempnetbuf[l++] = 0; - tempnetbuf[l++] = g_player[myconnectindex].ps->aim_mode = in_aimmode; + tempnetbuf[l++] = g_player[myconnectindex].ps->aim_mode = in_mousemode; tempnetbuf[l++] = g_player[myconnectindex].ps->auto_aim = cl_autoaim; tempnetbuf[l++] = g_player[myconnectindex].ps->weaponswitch = cl_weaponswitch; tempnetbuf[l++] = g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = G_CheckPlayerColor(playercolor); diff --git a/source/duke3d/src/player.cpp b/source/duke3d/src/player.cpp index 2771ef572..0b9aabd79 100644 --- a/source/duke3d/src/player.cpp +++ b/source/duke3d/src/player.cpp @@ -2887,7 +2887,6 @@ enddisplayweapon: #define MAXANGVEL 1024 #define MAXHORIZ 256 -int32_t g_myAimStat = 0, g_oldAimStat = 0; int32_t mouseyaxismode = -1; void P_GetInput(int const playerNum) @@ -2910,19 +2909,7 @@ void P_GetInput(int const playerNum) D_ProcessEvents(); - if (in_aimmode) - g_MyAimMode = buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - else - { - g_oldAimStat = g_myAimStat; - g_myAimStat = buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - - if (g_myAimStat > g_oldAimStat) - { - g_MyAimMode ^= 1; - P_DoQuote(QUOTE_MOUSE_AIMING_OFF + g_MyAimMode, pPlayer); - } - } + bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); CONTROL_GetInput(&info); @@ -2950,7 +2937,7 @@ void P_GetInput(int const playerNum) input.q16avel += fix16_from_int(info.dyaw) / analogExtent * (analogTurnAmount << 1); } - if (g_MyAimMode) + if (mouseaim) input.q16horz = fix16_div(fix16_from_int(info.mousey), F16(64)); else input.fvel = -(info.mousey >> 6); @@ -3073,7 +3060,7 @@ void P_GetInput(int const playerNum) localInput.bits |= buttonMap.ButtonDown(gamefunc_Quick_Kick) << SK_QUICK_KICK; localInput.bits |= buttonMap.ButtonDown(gamefunc_TurnAround) << SK_TURNAROUND; - localInput.bits |= (g_MyAimMode << SK_AIMMODE); + localInput.bits |= (mouseaim << SK_AIMMODE); localInput.bits |= (g_gameQuit << SK_GAMEQUIT); localInput.bits |= inputState.GetKeyStatus(sc_Pause) << SK_PAUSE; localInput.bits |= ((uint32_t)inputState.GetKeyStatus(sc_Escape)) << SK_ESCAPE; diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 18eed1f6b..9e4eaad83 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -7156,7 +7156,7 @@ static void P_SetupMiscInputSettings(void) { DukePlayer_t *ps = g_player[myconnectindex].ps; - ps->aim_mode = in_aimmode; + ps->aim_mode = in_mousemode; ps->auto_aim = cl_autoaim; ps->weaponswitch = cl_weaponswitch; } diff --git a/source/rr/src/menus.cpp b/source/rr/src/menus.cpp index 238839e89..5fd9777b7 100644 --- a/source/rr/src/menus.cpp +++ b/source/rr/src/menus.cpp @@ -510,156 +510,6 @@ static MenuEntry_t *MEL_KEYBOARDSETUP[] = { }; -// There is no better way to do this than manually. - -#define MENUMOUSEFUNCTIONS 12 - -static char const *MenuMouseNames[MENUMOUSEFUNCTIONS] = { - "Button 1", - "Double Button 1", - "Button 2", - "Double Button 2", - "Button 3", - "Double Button 3", - - "Wheel Up", - "Wheel Down", - - "Button 4", - "Double Button 4", - "Button 5", - "Double Button 5", -}; -static int32_t MenuMouseDataIndex[MENUMOUSEFUNCTIONS][2] = { - { 0, 0, }, - { 0, 1, }, - { 1, 0, }, - { 1, 1, }, - { 2, 0, }, - { 2, 1, }, - - // note the mouse wheel - { 4, 0, }, - { 5, 0, }, - - { 3, 0, }, - { 3, 1, }, - { 6, 0, }, - { 6, 1, }, -}; - -static MenuOption_t MEO_MOUSEJOYSETUPBTNS_TEMPLATE = MAKE_MENUOPTION( &MF_Minifont, &MEOS_Gamefuncs, NULL ); -static MenuOption_t MEO_MOUSESETUPBTNS[MENUMOUSEFUNCTIONS]; -static MenuEntry_t ME_MOUSEJOYSETUPBTNS_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Minifont, &MEF_FuncList, NULL, Option ); - -static MenuRangeFloat_t MEO_MOUSESETUP_SENSITIVITY = MAKE_MENURANGE( &in_mousesensitivity, &MF_Redfont, .5f, 16.f, 0.f, 32, 1 ); -static MenuEntry_t ME_MOUSESETUP_SENSITIVITY = MAKE_MENUENTRY( "Sensitivity:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSESETUP_SENSITIVITY, RangeFloat ); - -#ifndef EDUKE32_SIMPLE_MENU -static char const *MEOSN_MOUSESETUP_AIM_TYPE [] = { "Toggle", "Hold" }; -static MenuOptionSet_t MEOS_MOUSESETUP_AIM_TYPE = MAKE_MENUOPTIONSET(MEOSN_MOUSESETUP_AIM_TYPE, NULL, 0x2); -static MenuOption_t MEO_MOUSESETUP_MOUSEAIMINGTYPE = MAKE_MENUOPTION(&MF_Redfont, &MEOS_MOUSESETUP_AIM_TYPE, &in_aimmode); -static MenuEntry_t ME_MOUSESETUP_MOUSEAIMINGTYPE = MAKE_MENUENTRY("Aiming type:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSESETUP_MOUSEAIMINGTYPE, Option); -static MenuOption_t MEO_MOUSESETUP_MOUSEAIMING = MAKE_MENUOPTION( &MF_Redfont, &MEOS_NoYes, &in_mousemode ); -static MenuEntry_t ME_MOUSESETUP_MOUSEAIMING = MAKE_MENUENTRY( "Vertical aiming:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSESETUP_MOUSEAIMING, Option ); -#endif -static MenuOption_t MEO_MOUSESETUP_INVERT = MAKE_MENUOPTION( &MF_Redfont, &MEOS_YesNo, &in_mouseflip ); -static MenuEntry_t ME_MOUSESETUP_INVERT = MAKE_MENUENTRY( "Invert aiming:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSESETUP_INVERT, Option ); -static MenuOption_t MEO_MOUSESETUP_SMOOTH = MAKE_MENUOPTION( &MF_Redfont, &MEOS_NoYes, &in_mousesmoothing ); -static MenuEntry_t ME_MOUSESETUP_SMOOTH = MAKE_MENUENTRY( "Filter input:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSESETUP_SMOOTH, Option ); -#ifndef EDUKE32_SIMPLE_MENU -static MenuLink_t MEO_MOUSESETUP_ADVANCED = { MENU_MOUSEADVANCED, MA_Advance, }; -static MenuEntry_t ME_MOUSESETUP_ADVANCED = MAKE_MENUENTRY( "Advanced setup", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSESETUP_ADVANCED, Link ); -#endif -static MenuRangeInt32_t MEO_MOUSEADVANCED_SCALEX = MAKE_MENURANGE(&in_mousescalex, &MF_Redfont, -262144, 262144, 65536, 161, 3); -static MenuEntry_t ME_MOUSEADVANCED_SCALEX = MAKE_MENUENTRY("X-Scale:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSEADVANCED_SCALEX, RangeInt32); -static MenuRangeInt32_t MEO_MOUSEADVANCED_SCALEY = MAKE_MENURANGE(&in_mousescaley, &MF_Redfont, -262144, 262144, 65536, 161, 3); -static MenuEntry_t ME_MOUSEADVANCED_SCALEY = MAKE_MENUENTRY("Y-Scale:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_MOUSEADVANCED_SCALEY, RangeInt32); - -static MenuEntry_t *MEL_MOUSESETUP[] = { - &ME_MOUSESETUP_SENSITIVITY, -#ifdef EDUKE32_SIMPLE_MENU - &ME_MOUSEADVANCED_SCALEX, - &ME_MOUSEADVANCED_SCALEY, -#endif - &ME_Space2_Redfont, - &ME_MOUSESETUP_INVERT, - &ME_MOUSESETUP_SMOOTH, -#ifndef EDUKE32_SIMPLE_MENU - &ME_MOUSESETUP_MOUSEAIMINGTYPE, - &ME_MOUSESETUP_MOUSEAIMING, - &ME_MOUSESETUP_ADVANCED, -#endif -}; - - - -static MenuOption_t MEO_JOYSTICK_ENABLE = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &in_joystick ); -static MenuEntry_t ME_JOYSTICK_ENABLE = MAKE_MENUENTRY( "Enable Gamepad:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_JOYSTICK_ENABLE, Option ); - -MAKE_MENU_TOP_ENTRYLINK( "Edit Buttons", MEF_CenterMenu, JOYSTICK_EDITBUTTONS, MENU_JOYSTICKBTNS ); -MAKE_MENU_TOP_ENTRYLINK( "Edit Axes", MEF_CenterMenu, JOYSTICK_EDITAXES, MENU_JOYSTICKAXES ); - -static MenuEntry_t *MEL_JOYSTICKSETUP[] = { - &ME_JOYSTICK_ENABLE, - &ME_Space6_Redfont, - &ME_JOYSTICK_EDITBUTTONS, - &ME_JOYSTICK_EDITAXES, -}; - -#define MAXJOYBUTTONSTRINGLENGTH 32 - -static char MenuJoystickNames[MAXJOYBUTTONSANDHATS*2][MAXJOYBUTTONSTRINGLENGTH]; - -static MenuOption_t MEO_JOYSTICKBTNS[MAXJOYBUTTONSANDHATS*2]; -static MenuEntry_t ME_JOYSTICKBTNS[MAXJOYBUTTONSANDHATS*2]; -static MenuEntry_t *MEL_JOYSTICKBTNS[MAXJOYBUTTONSANDHATS*2]; - -static MenuLink_t MEO_JOYSTICKAXES = { MENU_JOYSTICKAXIS, MA_Advance, }; -static MenuEntry_t ME_JOYSTICKAXES_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_BigSliders, &MEO_JOYSTICKAXES, Link ); -static MenuEntry_t ME_JOYSTICKAXES[MAXJOYAXES]; -static char MenuJoystickAxes[MAXJOYAXES][MAXJOYBUTTONSTRINGLENGTH]; - -static MenuEntry_t *MEL_JOYSTICKAXES[MAXJOYAXES]; - -static MenuEntry_t *MEL_MOUSEADVANCED[] = { - &ME_MOUSEADVANCED_SCALEX, - &ME_MOUSEADVANCED_SCALEY, -}; - -static const char *MenuJoystickHatDirections[] = { "Up", "Right", "Down", "Left", }; - -static char const *MEOSN_JOYSTICKAXIS_ANALOG[] = { " -None-", "Turning", "Strafing", "Looking", "Moving", }; -static int32_t MEOSV_JOYSTICKAXIS_ANALOG[] = { -1, analog_turning, analog_strafing, analog_lookingupanddown, analog_moving, }; -static MenuOptionSet_t MEOS_JOYSTICKAXIS_ANALOG = MAKE_MENUOPTIONSET( MEOSN_JOYSTICKAXIS_ANALOG, MEOSV_JOYSTICKAXIS_ANALOG, 0x0 ); -static MenuOption_t MEO_JOYSTICKAXIS_ANALOG = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_JOYSTICKAXIS_ANALOG, NULL ); -static MenuEntry_t ME_JOYSTICKAXIS_ANALOG = MAKE_MENUENTRY( "Analog", &MF_Redfont, &MEF_BigSliders, &MEO_JOYSTICKAXIS_ANALOG, Option ); -static MenuRangeInt32_t MEO_JOYSTICKAXIS_SCALE = MAKE_MENURANGE( NULL, &MF_Bluefont, -262144, 262144, 65536, 65, 3 ); -static MenuEntry_t ME_JOYSTICKAXIS_SCALE = MAKE_MENUENTRY( "Scale", &MF_Redfont, &MEF_BigSliders, &MEO_JOYSTICKAXIS_SCALE, RangeInt32 ); -static MenuRangeInt32_t MEO_JOYSTICKAXIS_DEAD = MAKE_MENURANGE( NULL, &MF_Bluefont, 0, 1000000, 0, 33, 2 ); -static MenuEntry_t ME_JOYSTICKAXIS_DEAD = MAKE_MENUENTRY( "Dead Zone", &MF_Redfont, &MEF_BigSliders, &MEO_JOYSTICKAXIS_DEAD, RangeInt32 ); -static MenuRangeInt32_t MEO_JOYSTICKAXIS_SATU = MAKE_MENURANGE( NULL, &MF_Bluefont, 0, 1000000, 0, 33, 2 ); -static MenuEntry_t ME_JOYSTICKAXIS_SATU = MAKE_MENUENTRY( "Saturation", &MF_Redfont, &MEF_BigSliders, &MEO_JOYSTICKAXIS_SATU, RangeInt32 ); - -static MenuOption_t MEO_JOYSTICKAXIS_DIGITALNEGATIVE = MAKE_MENUOPTION( &MF_Minifont, &MEOS_Gamefuncs, NULL ); -static MenuEntry_t ME_JOYSTICKAXIS_DIGITALNEGATIVE = MAKE_MENUENTRY( "Digital -", &MF_Bluefont, &MEF_BigSliders, &MEO_JOYSTICKAXIS_DIGITALNEGATIVE, Option ); -static MenuOption_t MEO_JOYSTICKAXIS_DIGITALPOSITIVE = MAKE_MENUOPTION( &MF_Minifont, &MEOS_Gamefuncs, NULL ); -static MenuEntry_t ME_JOYSTICKAXIS_DIGITALPOSITIVE = MAKE_MENUENTRY( "Digital +", &MF_Bluefont, &MEF_BigSliders, &MEO_JOYSTICKAXIS_DIGITALPOSITIVE, Option ); - -static MenuEntry_t *MEL_JOYSTICKAXIS[] = { - &ME_JOYSTICKAXIS_ANALOG, - &ME_JOYSTICKAXIS_SCALE, - &ME_JOYSTICKAXIS_DEAD, - &ME_JOYSTICKAXIS_SATU, - &ME_Space8_Redfont, - &ME_JOYSTICKAXIS_DIGITALNEGATIVE, - &ME_JOYSTICKAXIS_DIGITALPOSITIVE, -}; - -static MenuEntry_t *MEL_INTERNAL_JOYSTICKAXIS_DIGITAL[] = { - &ME_JOYSTICKAXIS_DIGITALNEGATIVE, - &ME_JOYSTICKAXIS_DIGITALPOSITIVE, -}; #ifdef USE_OPENGL static MenuOption_t MEO_RENDERERSETUP_HIGHTILE = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NoYes, &hw_hightile ); diff --git a/source/rr/src/net.cpp b/source/rr/src/net.cpp index e16092161..da3ca64db 100644 --- a/source/rr/src/net.cpp +++ b/source/rr/src/net.cpp @@ -3427,7 +3427,7 @@ void Net_SendClientInfo(void) l += 32; tempbuf[l++] = 0; - tempbuf[l++] = g_player[myconnectindex].ps->aim_mode = in_aimmode; + tempbuf[l++] = g_player[myconnectindex].ps->aim_mode = in_mousemode; tempbuf[l++] = g_player[myconnectindex].ps->auto_aim = cl_autoaim; tempbuf[l++] = g_player[myconnectindex].ps->weaponswitch = cl_weaponswitch; tempbuf[l++] = g_player[myconnectindex].ps->palookup = g_player[myconnectindex].pcolor = G_CheckPlayerColor(playercolor); diff --git a/source/rr/src/player.cpp b/source/rr/src/player.cpp index 47756f982..434182de6 100644 --- a/source/rr/src/player.cpp +++ b/source/rr/src/player.cpp @@ -2758,19 +2758,7 @@ void P_GetInput(int playerNum) D_ProcessEvents(); - if (in_aimmode) - g_MyAimMode = buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - else - { - g_oldAimStat = g_myAimStat; - g_myAimStat = buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - - if (g_myAimStat > g_oldAimStat) - { - g_MyAimMode ^= 1; - P_DoQuote(QUOTE_MOUSE_AIMING_OFF + g_MyAimMode, pPlayer); - } - } + bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); CONTROL_GetInput(&info); @@ -2800,7 +2788,7 @@ void P_GetInput(int playerNum) input.q16avel += fix16_from_int(info.dyaw) / analogExtent * (analogTurnAmount << 1); } - if (g_MyAimMode) + if (mouseaim) input.q16horz = fix16_div(fix16_from_int(info.mousey), F16(64)); else input.fvel = -(info.mousey >> 6); @@ -2965,7 +2953,7 @@ void P_GetInput(int playerNum) localInput.bits |= buttonMap.ButtonDown(gamefunc_Quick_Kick) << SK_QUICK_KICK; localInput.bits |= buttonMap.ButtonDown(gamefunc_TurnAround) << SK_TURNAROUND; - localInput.bits |= (g_MyAimMode << SK_AIMMODE); + localInput.bits |= (mouseaim << SK_AIMMODE); localInput.bits |= (g_gameQuit << SK_GAMEQUIT); localInput.bits |= inputState.GetKeyStatus(sc_Pause) << SK_PAUSE; localInput.bits |= ((uint32_t)inputState.GetKeyStatus(sc_Escape)) << SK_ESCAPE; @@ -3044,19 +3032,7 @@ void P_GetInputMotorcycle(int playerNum) D_ProcessEvents(); - if (in_aimmode) - g_MyAimMode = buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - else - { - g_oldAimStat = g_myAimStat; - g_myAimStat = buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - - if (g_myAimStat > g_oldAimStat) - { - g_MyAimMode ^= 1; - P_DoQuote(QUOTE_MOUSE_AIMING_OFF + g_MyAimMode, pPlayer); - } - } + bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); CONTROL_GetInput(&info); @@ -3321,19 +3297,7 @@ void P_GetInputBoat(int playerNum) D_ProcessEvents(); - if (in_aimmode) - g_MyAimMode = buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - else - { - g_oldAimStat = g_myAimStat; - g_myAimStat = buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - - if (g_myAimStat > g_oldAimStat) - { - g_MyAimMode ^= 1; - P_DoQuote(QUOTE_MOUSE_AIMING_OFF + g_MyAimMode, pPlayer); - } - } + bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); CONTROL_GetInput(&info); diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index e4a572994..0cc97a153 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -2772,8 +2772,6 @@ void InitPlayerGameSettings(void) else RESET(Player[myconnectindex].Flags, PF_AUTO_AIM); } - - g_MyAimMode = in_aimmode; } @@ -3518,29 +3516,23 @@ void getinput(SW_PACKET *loc) // MAKE SURE THIS WILL GET SET SET_LOC_KEY(loc->bits, SK_QUIT_GAME, MultiPlayQuitFlag); - if (in_aimmode) - g_MyAimMode = 0; + bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - if (buttonMap.ButtonDown(gamefunc_Mouse_Aiming)) + if (!CommEnabled) { - if (in_aimmode) - g_MyAimMode = 1; - else - { - buttonMap.ClearButton(gamefunc_Mouse_Aiming); - g_MyAimMode = !g_MyAimMode; - if (g_MyAimMode) - { - PutStringInfo(pp, "Mouse Aiming Off"); - } - else - { - PutStringInfo(pp, "Mouse Aiming On"); - } - } - } + // Go back to the source to set this - the old code here was catastrophically bad. + // this needs to be fixed properly - as it is this can never be compatible with demo playback. - int const aimMode = TEST(pp->Flags, PF_MOUSE_AIMING_ON); + if (mouseaim) + SET(Player[myconnectindex].Flags, PF_MOUSE_AIMING_ON); + else + RESET(Player[myconnectindex].Flags, PF_MOUSE_AIMING_ON); + + if (cl_autoaim) + SET(Player[myconnectindex].Flags, PF_AUTO_AIM); + else + RESET(Player[myconnectindex].Flags, PF_AUTO_AIM); + } ControlInfo info; CONTROL_GetInput(&info); @@ -3646,7 +3638,7 @@ void getinput(SW_PACKET *loc) angvel += info.dyaw * (turnamount << 1) / analogExtent; } - if (true)//aimMode) + if (mouseaim) aimvel = -info.mousey / 64; else vel = -(info.mousey >> 6); @@ -3758,7 +3750,6 @@ void getinput(SW_PACKET *loc) SET_LOC_KEY(loc->bits, SK_LOOK_UP, buttonMap.ButtonDown(gamefunc_Look_Up)); SET_LOC_KEY(loc->bits, SK_LOOK_DOWN, buttonMap.ButtonDown(gamefunc_Look_Down)); - for (i = 0; i < MAX_WEAPONS_KEYS; i++) { if (buttonMap.ButtonDown(gamefunc_Weapon_1 + i)) diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index ee42e2c46..fae69b844 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -2252,7 +2252,6 @@ MNU_InitMenus(void) buttonsettings[btn_bobbing] = cl_viewbob; buttonsettings[btn_shadows] = r_shadows; - buttonsettings[btn_mouse_aim] = in_aimmode; buttonsettings[btn_mouse_invert] = in_mouseflip; buttonsettings[btn_sound] = snd_enabled; buttonsettings[btn_music] = mus_enabled; @@ -3012,10 +3011,6 @@ void MNU_DoButton(MenuItem_p item, SWBOOL draw) if (cl_autorun != last_value) MenuButtonAutoRun = TRUE; break; - case btn_mouse_aim: - last_value = in_aimmode; - in_aimmode = state = buttonsettings[item->button]; - break; case btn_mouse_invert: in_mouseflip = state = buttonsettings[item->button]; break; @@ -3146,13 +3141,6 @@ void MNU_DoButton(MenuItem_p item, SWBOOL draw) if (!draw) return; - switch (item->button) - { - case btn_mouse_aim: - extra_text = in_aimmode ? "Momentary" : "Toggle"; - break; - default: break; - } state = buttonsettings[item->button]; diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index 6a0f26a10..c5f1b63ed 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -1820,7 +1820,7 @@ PlayerAutoLook(PLAYERp pp) if (!TEST(pp->Flags, PF_FLYING|PF_SWIMMING|PF_DIVING|PF_CLIMBING|PF_JUMPING|PF_FALLING)) { - if (!g_MyAimMode && TEST(sector[pp->cursectnum].floorstat, FLOOR_STAT_SLOPE)) // If the floor is sloped + if (!TEST(pp->Flags, PF_MOUSE_AIMING_ON) && TEST(sector[pp->cursectnum].floorstat, FLOOR_STAT_SLOPE)) // If the floor is sloped { // Get a point, 512 units ahead of player's position x = pp->posx + (sintable[(pp->pang + 512) & 2047] >> 5); @@ -2522,29 +2522,6 @@ MoveScrollMode2D(PLAYERp pp) void DoPlayerMenuKeys(PLAYERp pp) { - - if (!CommEnabled) - { - // Go back to the source to set this - the old code here was catastrophically bad. - // this needs to be fixed properly - as it is this can never be compatible with demo playback. - if (cl_autoaim) - SET(Player[myconnectindex].Flags, PF_AUTO_AIM); - else - RESET(Player[myconnectindex].Flags, PF_AUTO_AIM); - -#if 0 - if (TEST_SYNC_KEY((pp), SK_AUTO_AIM)) - { - if (FLAG_KEY_PRESSED(pp, SK_AUTO_AIM)) - { - FLAG_KEY_RELEASE(pp, SK_AUTO_AIM); - FLIP(pp->Flags, PF_AUTO_AIM); - } - } - else - FLAG_KEY_RESET(pp, SK_AUTO_AIM); -#endif - } } void PlayerSectorBound(PLAYERp pp, int amt) diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 64acbf1a4..328f61d10 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -665,6 +665,8 @@ OptionMenu "ActionControlsMenu"// protected StaticText "" Control "$CNTRLMNU_MOUSELOOK" , "+mouse_aiming" + Control "$CNTRLMNU_MLOOKTOGGLE" , "togglemouseaim" + Control "$CNTRLMNU_AIMUP" , "+aim_up" Control "$CNTRLMNU_AIMDOWN" , "+aim_down" Control "$CNTRLMNU_LOOKUP" , "+look_up" @@ -902,7 +904,6 @@ OptionMenu "MouseOptions" //protected StaticText "" Option "$MOUSEMNU_ALWAYSMOUSELOOK", "in_mousemode", "OnOff" Option "$MOUSEMNU_INVERTMOUSE", "in_mouseflip", "OnOff" - Option "$MOUSEMNU_LOOKSPRING", "in_aimmode", "OnOff" // Functionm exists but is very broken. Definitely needs fixing. // Do we need this? Option "$MOUSEMNU_LOOKSTRAFE", "lookstrafe", "OnOff" } From 1b1fad6e137e8f0dfe0fe43bcdcaaea78ec2f0a7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 5 Dec 2019 01:17:28 +0100 Subject: [PATCH 113/203] - forgot to save this. --- source/common/gamecvars.h | 1 - 1 file changed, 1 deletion(-) diff --git a/source/common/gamecvars.h b/source/common/gamecvars.h index a65b555e8..6dd9d0348 100644 --- a/source/common/gamecvars.h +++ b/source/common/gamecvars.h @@ -94,7 +94,6 @@ EXTERN_CVAR(Int, in_mousebias) EXTERN_CVAR(Int, in_mousedeadzone) EXTERN_CVAR(Bool, in_mouseflip) EXTERN_CVAR(Bool, in_mousemode) -EXTERN_CVAR(Bool, in_aimmode) EXTERN_CVAR(Bool, in_mousesmoothing) EXTERN_CVAR(Float, in_mousesensitivity) EXTERN_CVAR(Float, in_mousescalex) From 628bd9efc66ec07773cb8ab0c6fd8273c930f448 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 5 Dec 2019 00:47:05 +0100 Subject: [PATCH 114/203] Filled in the rest of the menus Sound is only partially functional, video mode completely nonfunctional, but it makes no sense adjusting them to the current backend code when it's due for replacement. --- source/blood/src/menu.cpp | 27 +- source/blood/src/sound.cpp | 179 ---------- source/common/gamecvars.cpp | 8 - source/common/gamecvars.h | 1 - source/common/music/i_music.cpp | 8 +- source/duke3d/src/menus.cpp | 495 +-------------------------- source/rr/src/menus.cpp | 5 - source/sw/src/game.cpp | 1 - source/sw/src/menus.cpp | 20 -- source/sw/src/save.cpp | 1 - source/sw/src/sounds.cpp | 4 - source/sw/src/sounds.h | 1 - wadsrc/static/demolition/menudef.txt | 393 +++++++++++++++++++++ 13 files changed, 400 insertions(+), 743 deletions(-) diff --git a/source/blood/src/menu.cpp b/source/blood/src/menu.cpp index e65ecbefb..40c4fccaa 100644 --- a/source/blood/src/menu.cpp +++ b/source/blood/src/menu.cpp @@ -223,8 +223,7 @@ CGameMenuItemTitle itemOptionsOldTitle("OPTIONS", 1, 160, 20, 2038); CGameMenuItemChain itemOption1("CONTROLS...", 3, 0, 40, 320, 1, &menuControls, -1, NULL, 0); CGameMenuItemSlider sliderDetail("DETAIL:", 3, 66, 50, 180, gDetail, 0, 4, 1, SetDetail, -1, -1); CGameMenuItemSlider sliderGamma("GAMMA:", 3, 66, 60, 180, gGamma, 0, 15, 2, SetGamma, -1, -1); -CGameMenuItemSlider sliderMusic("MUSIC:", 3, 66, 70, 180, mus_volume, 0, 256, 48, SetMusicVol, -1, -1); -CGameMenuItemSlider sliderSound("SOUND:", 3, 66, 80, 180, snd_fxvolume, 0, 256, 48, SetSoundVol, -1, -1); +-1); //CGameMenuItemSlider sliderCDAudio("CD AUDIO:", 3, 66, 90, 180, CDVolume, 0, 256, 48, SetCDVol, -1, -1); CGameMenuItemZBool bool3DAudio("3D AUDIO:", 3, 66, 100, 180, snd_doppler, SetDoppler, NULL, NULL); CGameMenuItemZBool boolCrosshair("CROSSHAIR:", 3, 66, 110, 180, cl_crosshair, SetCrosshair, NULL, NULL); @@ -299,7 +298,6 @@ CGameMenuItemChain itemNetStart12("START GAME", 1, 66, 175, 280, 0, 0, -1, Start CGameMenuItemText itemLoadingText("LOADING...", 1, 160, 100, 1); CGameMenuItemTitle itemSoundsTitle("SOUNDS", 1, 160, 20, 2038); -CGameMenuItemSlider itemSoundsMusic("MUSIC:", 3, 40, 60, 180, mus_volume, 0, 256, 48, SetMusicVol, -1, -1); CGameMenuItemSlider itemSoundsSound("SOUND:", 3, 40, 70, 180, snd_fxvolume, 0, 256, 48, SetSoundVol, -1, -1); //CGameMenuItemSlider itemSoundsCDAudio("CD AUDIO:", 3, 40, 80, 180, CDVolume, 0, 256, 48, SetCDVol, -1, -1); CGameMenuItemZBool itemSounds3DAudio("3D SOUND:", 3, 40, 90, 180, snd_doppler, SetDoppler, NULL, NULL); @@ -591,7 +589,6 @@ CGameMenuItemZBool itemOptionsSoundSoundToggle("SOUND:", 3, 66, 60, 180, false, CGameMenuItemZBool itemOptionsSoundMusicToggle("MUSIC:", 3, 66, 70, 180, false, UpdateMusicToggle, NULL, NULL); CGameMenuItemZBool itemOptionsSound3DToggle("3D AUDIO:", 3, 66, 80, 180, false, Update3DToggle, NULL, NULL); CGameMenuItemSlider itemOptionsSoundSoundVolume("SOUND VOLUME:", 3, 66, 90, 180, &snd_fxvolume.Value, 0, 256, 48, UpdateSoundVolume, -1, -1, kMenuSliderPercent); -CGameMenuItemSlider itemOptionsSoundMusicVolume("MUSIC VOLUME:", 3, 66, 100, 180, &mus_volume.Value, 0, 256, 48, UpdateMusicVolume, -1, -1, kMenuSliderPercent); CGameMenuItemZCycle itemOptionsSoundSampleRate("SAMPLE RATE:", 3, 66, 110, 180, 0, UpdateSoundRate, pzSoundRateStrings, 3, 0); CGameMenuItemSlider itemOptionsSoundNumVoices("VOICES:", 3, 66, 120, 180, snd_numvoices, 16, 256, 16, UpdateNumVoices, -1, -1, kMenuSliderValue); CGameMenuItemZBool itemOptionsSoundCDToggle("REDBOOK AUDIO:", 3, 66, 130, 180, false, UpdateCDToggle, NULL, NULL); @@ -758,8 +755,7 @@ void SetupOptionsOldMenu(void) { sliderDetail.nValue = ClipRange(gDetail, sliderDetail.nRangeLow, sliderDetail.nRangeHigh); sliderGamma.nValue = ClipRange(gGamma, sliderGamma.nRangeLow, sliderGamma.nRangeHigh); - sliderMusic.nValue = ClipRange(mus_volume, sliderMusic.nRangeLow, sliderMusic.nRangeHigh); - sliderSound.nValue = ClipRange(snd_fxvolume, sliderSound.nRangeLow, sliderSound.nRangeHigh); + bool3DAudio.at20 = snd_doppler; boolCrosshair.at20 = cl_crosshair; itemCycleShowWeapons.m_nFocus = cl_showweapon; @@ -1016,8 +1012,6 @@ void SetupLoadGameMenu(void) void SetupSoundsMenu(void) { - itemSoundsMusic.nValue = ClipRange(mus_volume, itemSoundsMusic.nRangeLow, itemSoundsMusic.nRangeHigh); - itemSoundsSound.nValue = ClipRange(snd_fxvolume, itemSoundsSound.nRangeLow, itemSoundsSound.nRangeHigh); menuSounds.Add(&itemSoundsTitle, false); menuSounds.Add(&itemSoundsMusic, true); menuSounds.Add(&itemSoundsSound, false); @@ -1419,17 +1413,6 @@ void SetGamma(CGameMenuItemSlider *pItem) scrSetGamma(gGamma); } -void SetMusicVol(CGameMenuItemSlider *pItem) -{ - mus_volume = pItem->nValue; -} - -void SetSoundVol(CGameMenuItemSlider *pItem) -{ - snd_fxvolume = pItem->nValue; - sndSetFXVolume(pItem->nValue); -} - void SetCDVol(CGameMenuItemSlider *pItem) { UNREFERENCED_PARAMETER(pItem); @@ -1773,12 +1756,6 @@ void UpdateSoundVolume(CGameMenuItemSlider *pItem) { sndSetFXVolume(pItem->nValue); } - -void UpdateMusicVolume(CGameMenuItemSlider *pItem) -{ - mus_volume = pItem->nValue; -} - void UpdateSoundRate(CGameMenuItemZCycle *pItem) { UNREFERENCED_PARAMETER(pItem); diff --git a/source/blood/src/sound.cpp b/source/blood/src/sound.cpp index 5dd1b1d74..235b0e495 100644 --- a/source/blood/src/sound.cpp +++ b/source/blood/src/sound.cpp @@ -75,156 +75,6 @@ SAMPLE2D * FindChannel(void) return NULL; } -#if 0 -DICTNODE *hSong; -char *pSongPtr; -int nSongSize; -bool bWaveMusic; -int nWaveMusicHandle; - -int sndPlaySong(const char *, const char* songName, bool bLoop) -{ - if (!MusicEnabled()) - return 0; - if (!songName || strlen(songName) == 0) - return 1; - - auto fp = S_OpenAudio(songName, 0, 1); - if (!fp.isOpen()) - { - hSong = gSoundRes.Lookup(songName, "MID"); - if (!hSong) - { - OSD_Printf(OSD_ERROR "sndPlaySong(): error: can't open \"%s\" for playback!\n", songName); - return 2; - } - int nNewSongSize = hSong->Size(); - char *pNewSongPtr = (char *)Xaligned_alloc(16, nNewSongSize); - memcpy(pNewSongPtr, hSong->Lock(), nNewSongSize); - hSong->Unlock(true); - MUSIC_SetVolume(mus_volume); - int32_t retval = MUSIC_PlaySong(pNewSongPtr, nNewSongSize, bLoop); - - if (retval != MUSIC_Ok) - { - ALIGNED_FREE_AND_NULL(pNewSongPtr); - return 5; - } - - if (bWaveMusic && nWaveMusicHandle >= 0) - { - FX_StopSound(nWaveMusicHandle); - nWaveMusicHandle = -1; - } - - bWaveMusic = false; - ALIGNED_FREE_AND_NULL(pSongPtr); - pSongPtr = pNewSongPtr; - nSongSize = nNewSongSize; - return 0; - } - - int32_t nSongLen = fp.Tell(); - - if (EDUKE32_PREDICT_FALSE(nSongLen < 4)) - { - OSD_Printf(OSD_ERROR "sndPlaySong(): error: empty music file \"%s\"\n", songName); - return 3; - } - - char * pNewSongPtr = (char *)Xaligned_alloc(16, nSongLen); - int nNewSongSize = fp.Read(pNewSongPtr, nSongLen); - - if (EDUKE32_PREDICT_FALSE(nNewSongSize != nSongLen)) - { - OSD_Printf(OSD_ERROR "sndPlaySong(): error: read %d bytes from \"%s\", expected %d\n", - nNewSongSize, songName, nSongLen); - ALIGNED_FREE_AND_NULL(pNewSongPtr); - return 4; - } - - if (!Bmemcmp(pNewSongPtr, "MThd", 4)) - { - int32_t retval = MUSIC_PlaySong(pNewSongPtr, nNewSongSize, bLoop); - - if (retval != MUSIC_Ok) - { - ALIGNED_FREE_AND_NULL(pNewSongPtr); - return 5; - } - - if (bWaveMusic && nWaveMusicHandle >= 0) - { - FX_StopSound(nWaveMusicHandle); - nWaveMusicHandle = -1; - } - - bWaveMusic = false; - ALIGNED_FREE_AND_NULL(pSongPtr); - pSongPtr = pNewSongPtr; - nSongSize = nNewSongSize; - } - else - { - int nNewWaveMusicHandle = FX_Play(pNewSongPtr, bLoop ? nNewSongSize : -1, 0, 0, 0, mus_volume, mus_volume, mus_volume, - FX_MUSIC_PRIORITY, 1.f, (intptr_t)&nWaveMusicHandle); - - if (nNewWaveMusicHandle <= FX_Ok) - { - ALIGNED_FREE_AND_NULL(pNewSongPtr); - return 5; - } - - if (bWaveMusic && nWaveMusicHandle >= 0) - FX_StopSound(nWaveMusicHandle); - - MUSIC_StopSong(); - - nWaveMusicHandle = nNewWaveMusicHandle; - bWaveMusic = true; - ALIGNED_FREE_AND_NULL(pSongPtr); - pSongPtr = pNewSongPtr; - nSongSize = nNewSongSize; - } - - return 0; -} - -bool sndIsSongPlaying(void) -{ - //return MUSIC_SongPlaying(); - return false; -} - -void sndFadeSong(int nTime) -{ - UNREFERENCED_PARAMETER(nTime); - - if (bWaveMusic && nWaveMusicHandle >= 0) - { - FX_StopSound(nWaveMusicHandle); - nWaveMusicHandle = -1; - bWaveMusic = false; - } - // MUSIC_SetVolume(0); - MUSIC_StopSong(); -} - -void sndStopSong(void) -{ - if (bWaveMusic && nWaveMusicHandle >= 0) - { - FX_StopSound(nWaveMusicHandle); - nWaveMusicHandle = -1; - bWaveMusic = false; - } - - MUSIC_StopSong(); - - ALIGNED_FREE_AND_NULL(pSongPtr); - nSongSize = 0; -} -#else int sndPlaySong(const char *mapname, const char* songName, bool bLoop) { return Mus_Play(mapname, songName, bLoop); @@ -245,7 +95,6 @@ void sndStopSong(void) { Mus_Stop(); } -#endif void sndSetFXVolume(int nVolume) { @@ -450,34 +299,6 @@ void DeinitSoundDevice(void) ThrowError(FX_ErrorString(nStatus)); } -#if 0 -void InitMusicDevice(void) -{ - int nStatus; - if ((nStatus = MUSIC_Init(MusicDevice)) == MUSIC_Ok) - { - if (MusicDevice == ASS_AutoDetect) - MusicDevice = MIDI_GetDevice(); - } - else if ((nStatus = MUSIC_Init(ASS_AutoDetect)) == MUSIC_Ok) - { - initprintf("InitMusicDevice: %s\n", MUSIC_ErrorString(nStatus)); - return; - } - DICTNODE *hTmb = gSoundRes.Lookup("GMTIMBRE", "TMB"); - if (hTmb) - AL_RegisterTimbreBank((unsigned char*)gSoundRes.Load(hTmb)); - MUSIC_SetVolume(mus_volume); -} - -void DeinitMusicDevice(void) -{ - FX_StopAllSounds(); - int nStatus = MUSIC_Shutdown(); - if (nStatus != 0) - ThrowError(MUSIC_ErrorString(nStatus)); -} -#endif bool sndActive = false; diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index edc505b4f..502098b09 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -187,14 +187,6 @@ CUSTOM_CVARD(Int, snd_speech, 5, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enables/disabl else if (self > 5) self = 5; } -int MusicDevice = ASS_WinMM; -CUSTOM_CVARD(Int, mus_device, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "selects music device") -{ - if (self < 0) self = 0; - else if (self > 1) self = 1; - else MusicDevice = self? ASS_WinMM : ASS_OPL3; // must be copied because it gets altered by the music code. -} - // HUD diff --git a/source/common/gamecvars.h b/source/common/gamecvars.h index 6dd9d0348..52aedcbe7 100644 --- a/source/common/gamecvars.h +++ b/source/common/gamecvars.h @@ -46,7 +46,6 @@ EXTERN_CVAR(Int, snd_mixrate) EXTERN_CVAR(Int, snd_numchannels) EXTERN_CVAR(Int, snd_numvoices) EXTERN_CVAR(Int, snd_speech) -EXTERN_CVAR(Int, mus_volume) EXTERN_CVAR(Int, mus_device) extern int MusicDevice; diff --git a/source/common/music/i_music.cpp b/source/common/music/i_music.cpp index 7ed6940d0..88023cee0 100644 --- a/source/common/music/i_music.cpp +++ b/source/common/music/i_music.cpp @@ -115,17 +115,17 @@ CUSTOM_CVAR(Bool, cd_enabled, true, CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBAL // Maximum volume of MOD/stream music. //========================================================================== -CUSTOM_CVARD(Int, mus_volume, 255, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "controls music volume") +CUSTOM_CVARD(Float, mus_volume, 0.5, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "controls music volume") { if (self < 0) self = 0; - else if (self > 255) self = 255; + else if (self > 1) self = 1; else { // Set general music volume. - ChangeMusicSetting(ZMusic::snd_musicvolume, nullptr, self / 255.f); + ChangeMusicSetting(ZMusic::snd_musicvolume, nullptr, self); if (GSnd != nullptr) { - GSnd->SetMusicVolume(clamp(self / 255.f * relative_volume/* * snd_mastervolume*/, 0, 1)); + GSnd->SetMusicVolume(clamp(self * relative_volume/* * snd_mastervolume*/, 0, 1)); } // For music not implemented through the digital sound system, // let them know about the change. diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index 07e3e424f..94c7802cf 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -224,26 +224,6 @@ static MenuEntry_t *MEL_DISPLAYSETUP_GL[] = { -#ifdef USE_OPENGL -static MenuOption_t MEO_RENDERERSETUP_HIGHTILE = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NoYes, &hw_hightile ); -static MenuEntry_t ME_RENDERERSETUP_HIGHTILE = MAKE_MENUENTRY( "True color textures:", &MF_Bluefont, &MEF_SmallOptions, &MEO_RENDERERSETUP_HIGHTILE, Option ); - - -static MenuOption_t MEO_RENDERERSETUP_PRECACHE = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_OffOn, &r_precache ); -static MenuEntry_t ME_RENDERERSETUP_PRECACHE = MAKE_MENUENTRY( "Pre-load map textures:", &MF_Bluefont, &MEF_SmallOptions, &MEO_RENDERERSETUP_PRECACHE, Option ); -# ifndef EDUKE32_GLES -static char const *MEOSN_RENDERERSETUP_TEXCACHE[] = { "Off", "On", "Compr.", }; -static MenuOptionSet_t MEOS_RENDERERSETUP_TEXCACHE = MAKE_MENUOPTIONSET( MEOSN_RENDERERSETUP_TEXCACHE, NULL, 0x2 ); -# endif -# ifdef USE_GLEXT -static MenuOption_t MEO_RENDERERSETUP_DETAILTEX = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NoYes, &hw_detailmapping ); -static MenuEntry_t ME_RENDERERSETUP_DETAILTEX = MAKE_MENUENTRY( "Detail textures:", &MF_Bluefont, &MEF_SmallOptions, &MEO_RENDERERSETUP_DETAILTEX, Option ); -static MenuOption_t MEO_RENDERERSETUP_GLOWTEX = MAKE_MENUOPTION(&MF_Bluefont, &MEOS_NoYes, &hw_glowmapping); -static MenuEntry_t ME_RENDERERSETUP_GLOWTEX = MAKE_MENUENTRY("Glow textures:", &MF_Bluefont, &MEF_SmallOptions, &MEO_RENDERERSETUP_GLOWTEX, Option); -# endif -static MenuOption_t MEO_RENDERERSETUP_MODELS = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NoYes, &hw_models ); -static MenuEntry_t ME_RENDERERSETUP_MODELS = MAKE_MENUENTRY( "3D models:", &MF_Bluefont, &MEF_SmallOptions, &MEO_RENDERERSETUP_MODELS, Option ); -#endif #ifdef USE_OPENGL @@ -312,7 +292,6 @@ static char const s_Volume[] = "Volume:"; static MenuRangeInt32_t MEO_SOUND_VOLUME_FX = MAKE_MENURANGE( &snd_fxvolume, &MF_Redfont, 0, 255, 0, 33, 2 ); static MenuEntry_t ME_SOUND_VOLUME_FX = MAKE_MENUENTRY( s_Volume, &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SOUND_VOLUME_FX, RangeInt32 ); -static MenuRangeInt32_t MEO_SOUND_VOLUME_MUSIC = MAKE_MENURANGE( &mus_volume, &MF_Redfont, 0, 255, 0, 33, 2 ); static MenuEntry_t ME_SOUND_VOLUME_MUSIC = MAKE_MENUENTRY( s_Volume, &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SOUND_VOLUME_MUSIC, RangeInt32 ); #ifndef EDUKE32_STANDALONE @@ -398,104 +377,11 @@ static MenuEntry_t *MEL_SAVESETUP[] = { &ME_SAVESETUP_CLEANUP, }; - -#define NoTitle NULL - -#define MAKE_MENUMENU(Title, Format, Entries) { Title, Format, Entries, ARRAY_SIZE(Entries), 0, 0, 0 } -#define MAKE_MENUMENU_CUSTOMSIZE(Title, Format, Entries) { Title, Format, Entries, 0, 0, 0, 0 } - -#ifndef EDUKE32_SIMPLE_MENU -static MenuMenu_t M_GAMESETUP = MAKE_MENUMENU( "Game Setup", &MMF_BigOptions, MEL_GAMESETUP ); -#endif -static MenuMenu_t M_OPTIONS = MAKE_MENUMENU( s_Options, &MMF_Top_Options, MEL_OPTIONS ); -static MenuMenu_t M_VIDEOSETUP = MAKE_MENUMENU( "Video Mode", &MMF_BigOptions, MEL_VIDEOSETUP ); -static MenuMenu_t M_KEYBOARDSETUP = MAKE_MENUMENU( "Configure Controls", &MMF_Top_Options, MEL_KEYBOARDSETUP ); -static MenuMenu_t M_CONTROLS = MAKE_MENUMENU( "Control Setup", &MMF_BigOptions, MEL_CONTROLS ); -static MenuMenu_t M_CHEATS = MAKE_MENUMENU( "Cheats", &MMF_SmallOptions, MEL_CHEATS ); -static MenuMenu_t M_MOUSESETUP = MAKE_MENUMENU( "Mouse Setup", &MMF_BigOptions, MEL_MOUSESETUP ); -static MenuMenu_t M_JOYSTICKSETUP = MAKE_MENUMENU( "Gamepad Setup", &MMF_BigOptions, MEL_JOYSTICKSETUP ); -static MenuMenu_t M_JOYSTICKAXES = MAKE_MENUMENU( "Gamepad Axes", &MMF_BigSliders, MEL_JOYSTICKAXES ); -static MenuMenu_t M_KEYBOARDKEYS = MAKE_MENUMENU( "Key Configuration", &MMF_KeyboardSetupFuncs, MEL_KEYBOARDSETUPFUNCS ); -static MenuMenu_t M_MOUSEADVANCED = MAKE_MENUMENU( "Advanced Mouse", &MMF_BigSliders, MEL_MOUSEADVANCED ); -static MenuMenu_t M_JOYSTICKAXIS = MAKE_MENUMENU( NULL, &MMF_BigSliders, MEL_JOYSTICKAXIS ); -#ifdef USE_OPENGL -static MenuMenu_t M_RENDERERSETUP_POLYMOST = MAKE_MENUMENU( "Polymost Setup", &MMF_SmallOptions, MEL_RENDERERSETUP_POLYMOST ); -#endif -static MenuMenu_t M_COLCORR = MAKE_MENUMENU( "Color Correction", &MMF_ColorCorrect, MEL_COLCORR ); -static MenuMenu_t M_SCREENSETUP = MAKE_MENUMENU( "HUD Setup", &MMF_BigOptions, MEL_SCREENSETUP ); -static MenuMenu_t M_DISPLAYSETUP = MAKE_MENUMENU( "Display Setup", &MMF_BigOptions, MEL_DISPLAYSETUP ); -static MenuMenu_t M_LOAD = MAKE_MENUMENU_CUSTOMSIZE( s_LoadGame, &MMF_LoadSave, MEL_LOAD ); -static MenuMenu_t M_SAVE = MAKE_MENUMENU_CUSTOMSIZE( s_SaveGame, &MMF_LoadSave, MEL_SAVE ); -static MenuMenu_t M_SOUND = MAKE_MENUMENU( "Sound Setup", &MMF_BigOptions, MEL_SOUND ); -static MenuMenu_t M_ADVSOUND = MAKE_MENUMENU( "Advanced Sound", &MMF_BigOptions, MEL_ADVSOUND ); -static MenuMenu_t M_SAVESETUP = MAKE_MENUMENU( "Save Setup", &MMF_BigOptions, MEL_SAVESETUP ); -static MenuMenu_t M_NETWORK = MAKE_MENUMENU( "Network Game", &MMF_Top_Joystick_Network, MEL_NETWORK ); -static MenuMenu_t M_PLAYER = MAKE_MENUMENU( "Player Setup", &MMF_SmallOptions, MEL_PLAYER ); -static MenuMenu_t M_MACROS = MAKE_MENUMENU( "Multiplayer Macros", &MMF_Macros, MEL_MACROS ); -static MenuMenu_t M_NETHOST = MAKE_MENUMENU( "Host Network Game", &MMF_SmallOptionsNarrow, MEL_NETHOST ); -static MenuMenu_t M_NETOPTIONS = MAKE_MENUMENU( "Net Game Options", &MMF_NetSetup, MEL_NETOPTIONS ); -static MenuMenu_t M_NETJOIN = MAKE_MENUMENU( "Join Network Game", &MMF_SmallOptionsNarrow, MEL_NETJOIN ); - -static MenuPanel_t M_CREDITS4 = { "About " APPNAME, MENU_CREDITS3, MA_Return, MENU_CREDITS5, MA_Advance, }; -static MenuPanel_t M_CREDITS5 = { "About " APPNAME, MENU_CREDITS4, MA_Return, MENU_CREDITS, MA_Advance, }; - -#define CURSOR_CENTER_2LINE { MENU_MARGIN_CENTER<<16, 120<<16, } -#define CURSOR_CENTER_3LINE { MENU_MARGIN_CENTER<<16, 129<<16, } -#define CURSOR_BOTTOMRIGHT { 304<<16, 186<<16, } - -static MenuVerify_t M_SAVECLEANVERIFY = { CURSOR_CENTER_3LINE, MENU_SAVESETUP, MA_None, }; -static MenuVerify_t M_QUIT = { CURSOR_CENTER_2LINE, MENU_CLOSE, MA_None, }; -static MenuVerify_t M_QUITTOTITLE = { CURSOR_CENTER_2LINE, MENU_CLOSE, MA_None, }; -static MenuVerify_t M_LOADVERIFY = { CURSOR_CENTER_3LINE, MENU_CLOSE, MA_None, }; -static MenuVerify_t M_LOADDELVERIFY = { CURSOR_CENTER_3LINE, MENU_LOAD, MA_None, }; -static MenuVerify_t M_NEWVERIFY = { CURSOR_CENTER_2LINE, MENU_EPISODE, MA_Advance, }; -static MenuVerify_t M_SAVEVERIFY = { CURSOR_CENTER_2LINE, MENU_SAVE, MA_None, }; -static MenuVerify_t M_SAVEDELVERIFY = { CURSOR_CENTER_3LINE, MENU_SAVE, MA_None, }; -static MenuVerify_t M_RESETPLAYER = { CURSOR_CENTER_3LINE, MENU_CLOSE, MA_None, }; - -static MenuVerify_t M_COLCORRRESETVERIFY = { CURSOR_CENTER_2LINE, MENU_COLCORR, MA_None, }; -static MenuVerify_t M_KEYSRESETVERIFY = { CURSOR_CENTER_2LINE, MENU_KEYBOARDSETUP, MA_None, }; -static MenuVerify_t M_KEYSCLASSICVERIFY = { CURSOR_CENTER_2LINE, MENU_KEYBOARDSETUP, MA_None, }; -static MenuVerify_t M_JOYSTANDARDVERIFY = { CURSOR_CENTER_2LINE, MENU_JOYSTICKSETUP, MA_None, }; -static MenuVerify_t M_JOYPROVERIFY = { CURSOR_CENTER_2LINE, MENU_JOYSTICKSETUP, MA_None, }; -static MenuVerify_t M_JOYCLEARVERIFY = { CURSOR_CENTER_2LINE, MENU_JOYSTICKSETUP, MA_None, }; - -static MenuMessage_t M_NETWAITMASTER = { CURSOR_BOTTOMRIGHT, MENU_NULL, MA_None, }; -static MenuMessage_t M_NETWAITVOTES = { CURSOR_BOTTOMRIGHT, MENU_NULL, MA_None, }; -static MenuMessage_t M_BUYDUKE = { CURSOR_BOTTOMRIGHT, MENU_EPISODE, MA_Return, }; - -static MenuTextForm_t M_ADULTPASSWORD = { NULL, "Enter Password:", MAXPWLOCKOUT, MTF_Password }; -static MenuTextForm_t M_CHEATENTRY = { NULL, "Enter Cheat Code:", MAXCHEATLEN, 0 }; -static MenuTextForm_t M_CHEAT_WARP = { NULL, "Enter Warp #:", 3, 0 }; -static MenuTextForm_t M_CHEAT_SKILL = { NULL, "Enter Skill #:", 1, 0 }; - - -/* -This function prepares data after ART and CON have been processed. -It also initializes some data in loops rather than statically at compile time. -*/ void Menu_Init(void) { int32_t i, j, k; if (FURY) - { - MMF_Top_Skill.pos.x = (320<<15); - ME_SKILL_TEMPLATE.format = &MEF_LeftMenu; - } - - - ++k; - MEOS_NETOPTIONS_GAMETYPE.numOptions = k; - if (NAM_WW2GI) - ME_NETOPTIONS_MONSTERS.name = "Enemies"; - - // prepare cheats - for (i = 0; i < NUMCHEATFUNCS; ++i) - MEL_CHEATS[i+1] = &ME_CheatCodes[i]; - - - // prepare shareware if (VOLUMEONE) { @@ -536,46 +422,6 @@ static void Menu_Pre(MenuID_t cm) switch (cm) { - case MENU_GAMESETUP: - MEO_GAMESETUP_DEMOREC.options = (ps->gm&MODE_GAME) ? &MEOS_DemoRec : &MEOS_OffOn; - MenuEntry_DisableOnCondition(&ME_GAMESETUP_DEMOREC, (ps->gm&MODE_GAME) && m_recstat != 1); - break; - - case MENU_DISPLAYSETUP: - MenuEntry_HideOnCondition(&ME_DISPLAYSETUP_VOXELS, !g_haveVoxels); -#ifdef USE_OPENGL - if (videoGetRenderMode() == REND_CLASSIC) - MenuMenu_ChangeEntryList(M_DISPLAYSETUP, MEL_DISPLAYSETUP); - else - MenuMenu_ChangeEntryList(M_DISPLAYSETUP, MEL_DISPLAYSETUP_GL); - - MEO_SCREENSETUP_SCREENSIZE.steps = !(ud.statusbarflags & STATUSBAR_NONONE) + - !(ud.statusbarflags & STATUSBAR_NOMODERN) + - !(ud.statusbarflags & STATUSBAR_NOMINI) + - !(ud.statusbarflags & STATUSBAR_NOOVERLAY) + - !(ud.statusbarflags & STATUSBAR_NOFULL) + - !(ud.statusbarflags & STATUSBAR_NOSHRINK) * 14; - MEO_SCREENSETUP_SCREENSIZE.max = MEO_SCREENSETUP_SCREENSIZE.steps - 1; - if (MEO_SCREENSETUP_SCREENSIZE.steps <= 2 && !(ud.statusbarflags & STATUSBAR_NONONE)) - { - ME_SCREENSETUP_SCREENSIZE.entry = &MEO_SCREENSETUP_SCREENSIZE_TWO; - ME_SCREENSETUP_SCREENSIZE.type = Option; - } - else - { - ME_SCREENSETUP_SCREENSIZE.entry = &MEO_SCREENSETUP_SCREENSIZE; - ME_SCREENSETUP_SCREENSIZE.type = RangeInt32; - } - MenuEntry_HideOnCondition(&ME_SCREENSETUP_SCREENSIZE, (MEO_SCREENSETUP_SCREENSIZE.steps < 2)); - - break; - - case MENU_POLYMER: - case MENU_POLYMOST: - MenuEntry_DisableOnCondition(&ME_RENDERERSETUP_PRECACHE, !hw_hightile); - MenuEntry_DisableOnCondition(&ME_RENDERERSETUP_DETAILTEX, !hw_hightile); - MenuEntry_DisableOnCondition(&ME_RENDERERSETUP_GLOWTEX, !hw_hightile); -#endif break; case MENU_VIDEOSETUP: @@ -642,47 +488,7 @@ static void Menu_Pre(MenuID_t cm) soundvoices == snd_numvoices); break; - case MENU_SAVESETUP: - MenuEntry_DisableOnCondition(&ME_SAVESETUP_MAXAUTOSAVES, !cl_autosavedeletion); - break; - - case MENU_JOYSTICKSETUP: - MenuEntry_DisableOnCondition(&ME_JOYSTICK_EDITBUTTONS, !CONTROL_JoyPresent || (joystick.numButtons == 0 && joystick.numHats == 0)); - MenuEntry_DisableOnCondition(&ME_JOYSTICK_EDITAXES, !CONTROL_JoyPresent || joystick.numAxes == 0); - MenuEntry_DisableOnCondition(&ME_JOYSTICK_DEFAULTS_STANDARD, !joystick.isGameController); - MenuEntry_DisableOnCondition(&ME_JOYSTICK_DEFAULTS_PRO, !joystick.isGameController); - break; - - case MENU_NETOPTIONS: - if (MEOSV_NetEpisodes[MEO_NETOPTIONS_EPISODE.currentOption] == MAXVOLUMES) - MEL_NETOPTIONS[2] = &ME_NETOPTIONS_USERMAP; - else - { - MEL_NETOPTIONS[2] = &ME_NETOPTIONS_LEVEL; - MEO_NETOPTIONS_LEVEL.options = &MEOS_NETOPTIONS_LEVEL[MEOSV_NetEpisodes[MEO_NETOPTIONS_EPISODE.currentOption]]; - } - if (!(g_gametypeFlags[m_coop] & GAMETYPE_MARKEROPTION)) - { - ME_NETOPTIONS_MARKERS.type = Dummy; - ME_NETOPTIONS_MARKERS.flags |= MEF_Disabled; - } - else - { - ME_NETOPTIONS_MARKERS.type = Option; - ME_NETOPTIONS_MARKERS.flags &= ~MEF_Disabled; - } - MEL_NETOPTIONS[5] = (g_gametypeFlags[m_coop] & (GAMETYPE_PLAYERSFRIENDLY|GAMETYPE_TDM)) ? &ME_NETOPTIONS_FRFIRE : &ME_NETOPTIONS_MAPEXITS; - break; - - case MENU_OPTIONS: - MenuEntry_DisableOnCondition(&ME_OPTIONS_PLAYERSETUP, ud.recstat == 1); - break; - } - - default: - break; - } -} + } static void Menu_DrawVerifyPrompt(int32_t x, int32_t y, const char * text, int numlines = 1) @@ -703,141 +509,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) switch (cm) { - case MENU_PLAYER: - rotatesprite_fs(origin.x + (260<<16), origin.y + ((24+(tilesiz[APLAYER].y>>1))<<16), 49152L,0,1441-((((4-((int32_t) totalclock>>4)))&3)*5),0,entry == &ME_PLAYER_TEAM ? G_GetTeamPalette(playerteam) : playercolor,10); - break; - - case MENU_MACROS: - mgametextcenter(origin.x, origin.y + (144<<16), "Activate in-game with Shift-F#"); - break; - - case MENU_COLCORR: - case MENU_COLCORR_INGAME: - // center panel - rotatesprite_fs(origin.x + (120<<16), origin.y + (32<<16), 16384, 0, 3290, 0, 0, 2|8|16); - rotatesprite_fs(origin.x + (160<<16) - (tilesiz[BOTTOMSTATUSBAR].x<<13), origin.y + (82<<16) - (tilesiz[BOTTOMSTATUSBAR].y<<14), 16384, 0, BOTTOMSTATUSBAR, 0, 0, 2|8|16); - - // left panel - rotatesprite_fs(origin.x + (40<<16), origin.y + (32<<16), 16384, 0, BONUSSCREEN, 0, 0, 2|8|16); - - // right panel - rotatesprite_fs(origin.x + (200<<16), origin.y + (32<<16), 16384, 0, LOADSCREEN, 0, 0, 2|8|16); - break; - - case MENU_SAVECLEANVERIFY: - videoFadeToBlack(1); - - if (g_oldSaveCnt) - { - Bsprintf(tempbuf, "Delete %d obsolete saves?\nThis action cannot be undone.", g_oldSaveCnt); - Menu_DrawVerifyPrompt(origin.x, origin.y, tempbuf, 2); - } - else - mgametextcenter(origin.x, origin.y + (90<<16), "No obsolete saves found!"); - - break; - - case MENU_LOADVERIFY: - { - videoFadeToBlack(1); - menusave_t & msv = g_menusaves[M_LOAD.currentEntry]; - if (msv.isOldVer && msv.brief.isExt) - { - Bsprintf(tempbuf, "Resume game from sequence point:\n\"%s\"", msv.brief.name); - Menu_DrawVerifyPrompt(origin.x, origin.y, tempbuf, 2); - } - else - { - Bsprintf(tempbuf, "Load game:\n\"%s\"", msv.brief.name); - Menu_DrawVerifyPrompt(origin.x, origin.y, tempbuf, 2); - } - break; - } - - case MENU_SAVEVERIFY: - videoFadeToBlack(1); - Menu_DrawVerifyPrompt(origin.x, origin.y, "Overwrite previous saved game?"); - break; - - case MENU_LOADDELVERIFY: - case MENU_SAVEDELVERIFY: - { - videoFadeToBlack(1); - menusave_t & msv = cm == MENU_LOADDELVERIFY ? g_menusaves[M_LOAD.currentEntry] : g_menusaves[M_SAVE.currentEntry-1]; - Bsprintf(tempbuf, "Delete saved game:\n\"%s\"?", msv.brief.name); - Menu_DrawVerifyPrompt(origin.x, origin.y, tempbuf, 2); - break; - } - - case MENU_NEWVERIFY: - videoFadeToBlack(1); - Menu_DrawVerifyPrompt(origin.x, origin.y, "Abort this game?"); - break; - - case MENU_COLCORRRESETVERIFY: - videoFadeToBlack(1); - Menu_DrawVerifyPrompt(origin.x, origin.y, "Reset color correction to defaults?"); - break; - case MENU_KEYSRESETVERIFY: - videoFadeToBlack(1); - Menu_DrawVerifyPrompt(origin.x, origin.y, "Reset keys to defaults?"); - break; - case MENU_KEYSCLASSICVERIFY: - videoFadeToBlack(1); - Menu_DrawVerifyPrompt(origin.x, origin.y, "Reset keys to classic defaults?"); - break; - case MENU_JOYSTANDARDVERIFY: - videoFadeToBlack(1); - Menu_DrawVerifyPrompt(origin.x, origin.y, "Reset gamepad to standard layout?"); - break; - case MENU_JOYPROVERIFY: - videoFadeToBlack(1); - Menu_DrawVerifyPrompt(origin.x, origin.y, "Reset gamepad to pro layout?"); - break; - case MENU_JOYCLEARVERIFY: - videoFadeToBlack(1); - Menu_DrawVerifyPrompt(origin.x, origin.y, "Clear all gamepad settings?"); - break; - - case MENU_QUIT: - case MENU_QUIT_INGAME: - videoFadeToBlack(1); - Menu_DrawVerifyPrompt(origin.x, origin.y, "Are you sure you want to quit?"); - break; - - case MENU_QUITTOTITLE: - videoFadeToBlack(1); - Menu_DrawVerifyPrompt(origin.x, origin.y, "End game and return to title screen?"); - break; - - case MENU_NETWAITMASTER: - G_DrawFrags(); - mgametextcenter(origin.x, origin.y + (50<<16), "Waiting for master\n" - "to select level"); - break; - - case MENU_NETWAITVOTES: - G_DrawFrags(); - mgametextcenter(origin.x, origin.y + (90<<16), "Waiting for votes"); - break; - -#ifndef EDUKE32_STANDALONE - case MENU_BUYDUKE: - mgametextcenter(origin.x, origin.y + (33<<16), "You are playing the shareware\n" - "version of Duke Nukem 3D. While\n" - "this version is really cool, you\n" - "are missing over 75% of the total\n" - "game, along with other great extras\n" - "which you'll get when you order\n" - "the complete version and get\n" - "the final three episodes."); - - mgametextcenter(origin.x, origin.y + ((148+16)<<16), "Press any key or button..."); - break; -#endif - } - } - break; case MENU_CREDITS4: // JBF 20031220 { #define MENU_YOFFSET 40 @@ -961,32 +632,6 @@ static void Menu_EntryLinkActivate(MenuEntry_t *entry) break; } - case MENU_JOYSTICKAXES: - M_JOYSTICKAXIS.title = joyGetName(0, M_JOYSTICKAXES.currentEntry); -#if 0 - MEO_JOYSTICKAXIS_ANALOG.data = &JoystickAnalogueAxes[M_JOYSTICKAXES.currentEntry]; - MEO_JOYSTICKAXIS_SCALE.variable = &JoystickAnalogueScale[M_JOYSTICKAXES.currentEntry]; - MEO_JOYSTICKAXIS_INVERT.data = &JoystickAnalogueInvert[M_JOYSTICKAXES.currentEntry]; - MEO_JOYSTICKAXIS_DEAD.variable = &JoystickAnalogueDead[M_JOYSTICKAXES.currentEntry]; - MEO_JOYSTICKAXIS_SATU.variable = &JoystickAnalogueSaturate[M_JOYSTICKAXES.currentEntry]; -#endif - break; - - case MENU_CHEATS: - { - const int32_t cheatFuncID = M_CHEATS.currentEntry - 1; - switch (cheatFuncID) - { - case -1: - case CHEATFUNC_WARP: - case CHEATFUNC_SKILL: - break; - default: - Menu_DoCheat(CheatFunctionIDs[cheatFuncID]); - break; - } - break; - } default: break; @@ -1071,146 +716,8 @@ static void Menu_EntryLinkActivate(MenuEntry_t *entry) } } -static int32_t Menu_EntryOptionModify(MenuEntry_t *entry, int32_t newOption) -{ - int32_t x; - auto ps = g_player[myconnectindex].ps; - - if (entry == &ME_GAMESETUP_DEMOREC) - { - if ((ps->gm&MODE_GAME)) - G_CloseDemoWrite(); - } - else if (entry == &ME_GAMESETUP_WEAPSWITCH_PICKUP) - { - ud.weaponswitch = ud.weaponswitch & ~(1|4); - switch (newOption) - { - case 2: - ud.weaponswitch = ud.weaponswitch | 4; - fallthrough__; - case 1: - ud.weaponswitch = ud.weaponswitch | 1; - break; - default: - break; - } - } - else if (entry == &ME_SOUND) - { - if (newOption == 0) - { - FX_StopAllSounds(); - S_ClearSoundLocks(); - } - } - else if (entry == &ME_SOUND_MUSIC) - { - mus_enabled = newOption; - - if (newOption == 0) - S_PauseMusic(true); - else - { - S_PauseMusic(false); - } - } - else if (entry == &ME_SOUND_DUKETALK) - snd_speech = (snd_speech&~1) | newOption; - else if (entry == &ME_JOYSTICK_ENABLE) - { - if (newOption) - CONTROL_ScanForControllers(); - CONTROL_JoystickEnabled = (newOption && CONTROL_JoyPresent); - } - else if (entry == &ME_JOYSTICKAXIS_ANALOG) - CONTROL_MapAnalogAxis(M_JOYSTICKAXES.currentEntry, newOption, controldevice_joystick); - else if (entry == &ME_JOYSTICKAXIS_INVERT) - CONTROL_SetAnalogAxisInvert(M_JOYSTICKAXES.currentEntry, newOption, controldevice_joystick); - else if (entry == &ME_NETOPTIONS_EPISODE) - { - if (newOption < g_volumeCnt) - ud.m_volume_number = newOption; - } - else if (entry == &ME_NETOPTIONS_MONSTERS) - { - ud.m_monsters_off = (newOption == g_skillCnt); - if (newOption < g_skillCnt) - ud.m_player_skill = newOption; - } - else if (entry == &ME_ADULTMODE) - { - if (newOption) - { - for (x=0; xgm; - if (gm & MODE_GAME) - { - if (gm & MODE_MENU) - I_ClearAllInput(); - - // The following lines are here so that you cannot close the menu when no game is running. - gm &= ~MODE_MENU; - mouseLockToWindow(1); - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) - { - ready2send = 1; - totalclock = ototalclock; - CAMERACLOCK = (int32_t) totalclock; - CAMERADIST = 65536; - m_animation.start = 0; - m_animation.length = 0; - - // Reset next-viewscreen-redraw counter. - // XXX: are there any other cases like that in need of handling? - if (g_curViewscreen >= 0) - actor[g_curViewscreen].t_data[0] = (int32_t) totalclock; - } - - G_UpdateScreenArea(); - S_PauseSounds(false); - } -} #endif diff --git a/source/rr/src/menus.cpp b/source/rr/src/menus.cpp index 5fd9777b7..f67aedb86 100644 --- a/source/rr/src/menus.cpp +++ b/source/rr/src/menus.cpp @@ -612,11 +612,6 @@ static MenuEntry_t ME_SOUND_CDPLAYER = MAKE_MENUENTRY( "8 Track Player", &MF_Red static MenuRangeInt32_t MEO_SOUND_VOLUME_FX = MAKE_MENURANGE( &snd_fxvolume, &MF_Redfont, 0, 255, 0, 33, 2 ); static MenuEntry_t ME_SOUND_VOLUME_FX = MAKE_MENUENTRY( "Volume:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_VOLUME_FX, RangeInt32 ); -static MenuRangeInt32_t MEO_SOUND_VOLUME_MUSIC = MAKE_MENURANGE( &mus_volume, &MF_Redfont, 0, 255, 0, 33, 2 ); -static MenuEntry_t ME_SOUND_VOLUME_MUSIC = MAKE_MENUENTRY( "Music:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_VOLUME_MUSIC, RangeInt32 ); - -static MenuOption_t MEO_SOUND_DUKETALK = MAKE_MENUOPTION(&MF_Redfont, &MEOS_NoYes, NULL); -static MenuEntry_t ME_SOUND_DUKETALK = MAKE_MENUENTRY( "Duke talk:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_DUKETALK, Option ); static char const *MEOSN_SOUND_SAMPLINGRATE[] = { "22050Hz", "44100Hz", "48000Hz", }; static int32_t MEOSV_SOUND_SAMPLINGRATE[] = { 22050, 44100, 48000, }; diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 0cc97a153..8b74e3a91 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -2872,7 +2872,6 @@ void RunLevel(void) InitRunLevel(); FX_SetVolume(snd_fxvolume); - SetSongVolume(mus_volume); #if 0 waitforeverybody(); diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index fae69b844..b3a0ab579 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -2222,12 +2222,6 @@ MNU_InitMenus(void) slidersettings[sldr_mouse] = in_mousesensitivity; // (MOUSE_SENS_MAX_VALUE / SLDR_MOUSESENSEMAX); - slidersettings[sldr_sndfxvolume] = snd_fxvolume / (FX_VOL_MAX_VALUE/SLDR_SNDFXVOLMAX); - slidersettings[sldr_musicvolume] = mus_volume / (MUSIC_VOL_MAX_VALUE/SLDR_MUSICVOLMAX); - slidersettings[sldr_scrsize] = gs.BorderNum; - slidersettings[sldr_brightness] = 10; - slidersettings[sldr_bordertile] = gs.BorderTile; - { int i,newx=xdim,newy=ydim; @@ -3235,20 +3229,6 @@ MNU_DoSlider(short dir, MenuItem_p item, SWBOOL draw) FX_SetVolume(snd_fxvolume); break; - case sldr_musicvolume: - barwidth = SLDR_MUSICVOLMAX; - offset = slidersettings[sldr_musicvolume] += dir; - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(SLDR_MUSICVOLMAX-1)); - - slidersettings[sldr_musicvolume] = offset; - mus_volume = MUSIC_MIN + (offset * VOL_MUL); - SetSongVolume(mus_volume); - break; - case sldr_scrsize: { short bnum; diff --git a/source/sw/src/save.cpp b/source/sw/src/save.cpp index 791f670b6..0c67aba1c 100644 --- a/source/sw/src/save.cpp +++ b/source/sw/src/save.cpp @@ -1229,7 +1229,6 @@ bool GameInterface::LoadGame(FSaveGameNode* sv) if (snd_ambience) StartAmbientSound(); FX_SetVolume(snd_fxvolume); - SetSongVolume(mus_volume); TRAVERSE_CONNECT(i) { diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp index cf3c04d5e..5ccc1b28e 100644 --- a/source/sw/src/sounds.cpp +++ b/source/sw/src/sounds.cpp @@ -561,10 +561,6 @@ PauseSong(SWBOOL pauseon) } } -void -SetSongVolume(int volume) -{ -} SWBOOL SongIsPlaying(void) diff --git a/source/sw/src/sounds.h b/source/sw/src/sounds.h index 791de9117..31a0b9dcf 100644 --- a/source/sw/src/sounds.h +++ b/source/sw/src/sounds.h @@ -92,7 +92,6 @@ void StopSound(void); void StartAmbientSound(void); void StopAmbientSound(void); SWBOOL PlaySong(char *song_file_name, int cdaudio_track, SWBOOL loop, SWBOOL restart); -void SetSongVolume(int volume); SWBOOL SongIsPlaying(void); void PlaySoundRTS(int rts_num); diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 328f61d10..59786e00e 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -1144,6 +1144,399 @@ OptionMenu "HUDOptions" //protected } +//------------------------------------------------------------------------------------------- +// +// Polymost options +// +//------------------------------------------------------------------------------------------- + +OptionMenu "PolymostOptions" +{ + Title "Polympost Options" + Option "$POLYMOST_TC", "hw_hightile", "OnOff" + Option "$POLYMOST_CACHE", "r_precache", "OnOff" + StaticText "" + Option "$POLYMOST_DETAIL", "hw_detailmapping", "OnOff", "hw_hightile" + Option "$POLYMOST_GLOW", "hw_glowmapping", "OnOff", "hw_hightile" + StaticText "" + Option "$POLYMOST_PALETTEEMU", "hw_useindexedcolortextures", "OnOff" + Option "$POLYMOST_PALINTER", "hw_shadeinterpolate", "OnOff", "hw_useindexedcolortextures" + StaticText "" + Option "$POLYMOST_MODELS", "hw_models", "OnOff" +} + +//------------------------------------------------------------------------------------------- +// +// Sound options +// Many of these options are not active, but will be needed should I manage to transition +// the entire sound system to OpenAL 3D. So it is easier to just copy all this verbatim +// and only disable the options not yet usable instead of deleting the content. +// +//------------------------------------------------------------------------------------------- + +OptionValue SampleRates +{ + //0, "$OPTVAL_DEFAULT" + //4000, "$OPTVAL_4000HZ" + //8000, "$OPTVAL_8000HZ" + 11025, "$OPTVAL_11025HZ" + 22050, "$OPTVAL_22050HZ" + /32000, "$OPTVAL_32000HZ" + 44100, "$OPTVAL_44100HZ" + 48000, "$OPTVAL_48000HZ" +} + + +OptionValue BufferSizes +{ + 0, "$OPTVAL_DEFAULT" + 64, "$OPTVAL_64SAMPLES" + 128, "$OPTVAL_128SAMPLES" + 256, "$OPTVAL_256SAMPLES" + 512, "$OPTVAL_512SAMPLES" + 1024, "$OPTVAL_1024SAMPLES" + 2048, "$OPTVAL_2048SAMPLES" + 4096, "$OPTVAL_4096SAMPLES" +} + +OptionString ALDevices +{ + // filled in by the sound code +} + +OptionString ALResamplers +{ + // filled in by the sound code +} + +OptionString SpeakerModes +{ + "Auto", "$OPTSTR_AUTO" + "Mono", "$OPTSTR_MONO" + "Stereo", "$OPTSTR_STEREO" + "Prologic", "$OPTSTR_PROLOGIC" + "Quad", "$OPTSTR_QUAD" + "Surround", "$OPTSTR_SURROUND" + "5.1", "$OPTSTR_5POINT1" + "7.1", "$OPTSTR_7POINT1" +} + + +OptionMenu OpenALSoundItems //protected +{ + Title "$OPENALMNU_TITLE" + Option "$OPENALMNU_PLAYBACKDEVICE", "snd_aldevice", "ALDevices" + Option "$OPENALMNU_ENABLEEFX", "snd_efx", "OnOff" + Option "$OPENALMNU_RESAMPLER", "snd_alresampler", "ALResamplers" +} + + +OptionValue MidiDevices +{ + // filled in by the sound code +} + +OptionMenu SoundOptions //protected +{ + Title "$SNDMNU_TITLE" + //Slider "$MODMNU_MASTERVOLUME", "snd_mastervolume", 0, 1, 0.05, 2 + //StaticText " " + Option "$SNDMNU_SNDENABLED", "snd_enabled", "OnOff" + Slider "$SNDMNU_SFXVOLUME", "snd_fxvolume", 0, 255, 2, 1 + //Slider "$SNDMNU_SFXVOLUME", "snd_fxvolume", 0, 1, 0.05, 2 // Todo: Change value type + Option "$SNDMNU_MUSENABLED", "mus_enabled", "OnOff" Slider "$SNDMNU_MUSICVOLUME", "mus_volume", 0, 1, 0.05, 2 + Option "$SNDMNU_MENUSOUND", "menu_sounds", "OnOff" // placeholder until the slider can be made to work + //Slider "$SNDMNU_MENUVOLUME", "snd_menuvolume", 0, 1, 0.05, 2 + StaticText " " + Option "$SNDMNU_MIDIDEVICE", "snd_mididevice", "MidiDevices" + StaticText " " + //Option "$SNDMNU_UNDERWATERREVERB", "snd_waterreverb", "OnOff" + //Option "$SNDMNU_RANDOMIZEPITCHES", "snd_pitched", "OnOff" + Slider "$SNDMNU_CHANNELS", "snd_numchannels", 64, 128, 8, 0 + staticText "" + ifgame (Blood, ShadowWarrior) + { + Option "$SNDMNU_CDEMU", "mus_redbook", "OnOff" + } + ifgame(Duke, Nam, WW2GI, Fury, Redneck, RedneckRides, ShadowWarrior) + { + Option "$SNDMNU_AMBIENCE", "snd_ambience", "OnOff" + Option "$SNDMNU_SPEECH", "snd_speech", "OnOff" + } + StaticText " " + Submenu "$SNDMNU_ADVANCED", "AdvSoundOptions" +} + +/*======================================= + * + * Advanced Sound Options Menu + * + *=======================================*/ + +OptionValue OplCores +{ + 0, "$OPTVAL_MAMEOPL2" + 1, "$OPTVAL_DOSBOXOPL3" + 2, "$OPTVAL_JAVAOPL3" + 3, "$OPTVAL_NUKEDOPL3" +} + + +OptionMenu AdvSoundOptions //protected +{ + Title "$ADVSNDMNU_TITLE" + Option "$ADVSNDMNU_SAMPLERATE", "snd_mixrate", "SampleRates" + //Option "$ADVSNDMNU_HRTF", "snd_hrtf", "AutoOffOn" + Option "$ADVSNDMNU_FLIPSTEREO" "snd_reversestereo", "OnOff" + StaticText " " + Option "$SNDMNU_BACKGROUND", "i_soundinbackground", "OnOff" + StaticText " " + + ifoption(openal) + { + StaticText " " + Submenu "$SNDMNU_OPENAL", "OpenALSoundItems" + } + + StaticText " " + Submenu "$SNDMNU_MIDIPLAYER", "MidiPlayerOptions" + Submenu "$SNDMNU_MODREPLAYER", "ModReplayerOptions" + StaticText " " + Command "$SNDMNU_RESTART", "snd_reset" +} + + +OptionMenu TimidityConfigMenu protected +{ + Title "$ADVSNDMNU_SELCONFIG" +} + +OptionMenu FluidPatchsetMenu protected +{ + Title "$ADVSNDMNU_SELCONFIG" +} + +/*======================================= + * + * Module Replayer Options Menu + * + *=======================================*/ + +OptionValue ModQuality +{ + 0.0, "$OPTVAL_ALIASING" + 1.0, "$OPTVAL_LINEAR_1" + 2.0, "$OPTVAL_CUBIC" + 3.0, "$OPTVAL_BLEP" // Band-limited step + 4.0, "$OPTVAL_LINEARSLOW" + 5.0, "$OPTVAL_BLAM" // Band-limited linear + 6.0, "$OPTVAL_CUBICSLOW" + 7.0, "$OPTVAL_SINC" +} + + +OptionValue ModVolumeRamps +{ + 0.0, "$OPTVAL_NONE" + 1.0, "$OPTVAL_NOTEONOFFONLY" + 2.0, "$OPTVAL_FULLRAMPING" +} + + + +OptionMenu ModReplayerOptions //protected +{ + Title "$MODMNU_TITLE" + Slider "$MODMNU_MASTERVOLUME", "mod_dumb_mastervolume", 1, 16, 0.5, 1 + Option "$ADVSNDMNU_SAMPLERATE", "mod_samplerate", "SampleRates" + Option "$MODMNU_QUALITY", "mod_interp", "ModQuality" + Option "$MODMNU_VOLUMERAMPING", "mod_volramp", "ModVolumeRamps" + StaticText " " + Option "$MODMNU_CHIPOMATIC", "mod_autochip", "OnOff" + // TODO if the menu system is ever rewritten: Provide a decent + // mechanism to edit the chip-o-matic settings like you can with + // the foo_dumb preferences in foobar2000. +} + +/*======================================= + * + * MIDI player + * + *=======================================*/ + + OptionValue TimidityReverb + { + 0, "$OPTVAL_OFF" + 1, "$OPTVAL_STANDARD" + 2, "$ADVSNDMNU_GLOBAL" + 3, "$ADVSNDMNU_FREEVERB" + 4, "$ADVSNDMNU_GLOBAL_FREEVERB" + } + + OptionMenu MidiPlayerOptions //protected + { + Title "$SNDMNU_MIDIPLAYER" + Submenu "$ADVSNDMNU_FLUIDSYNTH", "FluidsynthOptions", 0, 1 + Submenu "$ADVSNDMNU_TIMIDITY", "TimidityOptions", 0, 1 + Submenu "$ADVSNDMNU_OPLSYNTHESIS", "OPLOptions", 0, 1 + } + + OptionMenu FluidsynthOptions //protected + { + Title "$ADVSNDMNU_FLUIDSYNTH" + LabeledSubMenu "$ADVSNDMNU_SELCONFIG", "fluid_patchset", "FluidPatchsetMenu" + Slider "$ADVSNDMNU_FLUIDGAIN", "fluid_gain", 0, 10, 0.5, 1 + Option "$ADVSNDMNU_REVERB", "fluid_reverb", "OnOff" + Option "$ADVSNDMNU_CHORUS", "fluid_chorus", "OnOff" + Slider "$ADVSNDMNU_MIDIVOICES", "fluid_voices", 16, 4096, 16, 0 + // other CVARs need to be revieved for usefulness + } + + OptionMenu TimidityOptions //protected + { + Title "$ADVSNDMNU_TIMIDITY" + LabeledSubMenu "$ADVSNDMNU_SELCONFIG", "timidity_config", "TimidityConfigMenu" + Option "$ADVSNDMNU_REVERB", "timidity_reverb", "TimidityReverb" + Slider "$ADVSNDMNU_REVERB_LEVEL", "timidity_reverb_level", 9, 127, 1, 0 + Option "$ADVSNDMNU_CHORUS", "timidity_chorus", "OnOff" + // other CVARs need to be revieved for usefulness + } + + OptionMenu OPLOptions //protected + { + Title "$ADVSNDMNU_OPLSYNTHESIS" + Option "$ADVSNDMNU_OPLCORES", "opl_core", "OplCores" + Slider "$ADVSNDMNU_OPLNUMCHIPS", "opl_numchips", 1, 8, 1, 0 + Option "$ADVSNDMNU_OPLFULLPAN", "opl_fullpan", "OnOff" + } + +/*======================================= + * + * Video mode menu + * Even more than the sound, much of this has no backing + * and needs replacement of the backend. + * + *=======================================*/ + +OptionValue ForceRatios +{ + 0.0, "$OPTVAL_OFF" + 3.0, "4:3" + 1.0, "16:9" + 5.0, "17:10" + 2.0, "16:10" + 4.0, "5:4" + 6.0, "21:9" +} +OptionValue Ratios +{ + 0.0, "4:3" + 4.0, "5:4" + 1.0, "16:9" + 2.0, "16:10" + 3.0, "17:10" + 6.0, "21:9" + -1, "$OPTVAL_ALL" +} +OptionValue ScaleModes +{ + 0, "$OPTVAL_SCALENEAREST" + 1, "$OPTVAL_SCALELINEAR" + 2, "640x400" + 3, "960x600" + 4, "1280x800" + 5, "$OPTVAL_CUSTOM" +} +OptionValue CropAspect +{ + 0, "$OPTVAL_STRETCH" + 1, "$OPTVAL_LETTERBOX" +} + +OptionValue MaxFps +{ + 0, "$OPTVAL_UNLIMITED" + 60, "$OPTVAL_60FPS" + 75, "$OPTVAL_75FPS" + 90, "$OPTVAL_90FPS" + 120, "$OPTVAL_120FPS" + 144, "$OPTVAL_144FPS" + 200, "$OPTVAL_200FPS" +} + +OptionMenu VideoModeMenu //protected +{ + Title "$VIDMNU_TITLE" + + StaticText "Caution: This menu is currently" + StaticText "not functional!" + + Option "$VIDMNU_RENDERMODE", "vid_rendermode", "RenderMode" + Option "$VIDMNU_FULLSCREEN", "fullscreen", "YesNo" + + IfOption(Mac) + { + Option "$VIDMNU_HIDPI", "vid_hidpi", "YesNo" + } + IfOption(Windows) + { + Option "$DSPLYMNU_GPUSWITCH", vid_gpuswitch, "GPUSwitch" + } + + Option "$VIDMNU_FORCEASPECT", "vid_aspect", "ForceRatios" + Option "$VIDMNU_CROPASPECT", "vid_cropaspect", "CropAspect" + Option "$VIDMNU_SCALEMODE", "vid_scalemode", "ScaleModes" + Slider "$VIDMNU_SCALEFACTOR", "vid_scalefactor", 0.25, 2.0, 0.25, 2 + + StaticText " " + Option "$DSPLYMNU_VSYNC", "vid_vsync", "OnOff" + Option "$VIDMNU_MAXFPS", "r_maxfps", "MaxFps" + + StaticText "" + StaticText "$VIDMNU_CUSTOMRES" + TextField "$VIDMNU_CUSTOMX", menu_resolution_custom_width + TextField "$VIDMNU_CUSTOMY", menu_resolution_custom_height + Option "$VIDMNU_USELINEAR", "vid_scale_customlinear", "YesNo" + StaticText "" + Command "$VIDMNU_APPLYW", "menu_resolution_commit_changes 0" + Command "$VIDMNU_APPLYFS", "menu_resolution_commit_changes 1" + StaticText "" + + SubMenu "$VIDMNU_RESPRESET", CustomResolutionMenu +} + +OptionMenu CustomResolutionMenu //protected +{ + Title "$VIDMNU_RESPRESETTTL" + + StaticText "$VIDMNU_RESPRESETHEAD" + StaticText "" + StaticText "$VIDMNU_ASPECT43" + Command "640x480", "menu_resolution_set_custom 640 480" + Command "1024x768", "menu_resolution_set_custom 1024 768" + Command "1280x960", "menu_resolution_set_custom 1280 960" + Command "1600x1200", "menu_resolution_set_custom 1600 1200" + StaticText "" + StaticText "$VIDMNU_ASPECT54" + Command "1280x1024", "menu_resolution_set_custom 1280 1024" + StaticText "" + StaticText "$VIDMNU_ASPECT169" + Command "960x540", "menu_resolution_set_custom 960 540" + Command "(720p HD) 1280x720", "menu_resolution_set_custom 1280 720" + Command "1366x768", "menu_resolution_set_custom 1366 768" + Command "(1080p HD) 1920x1080", "menu_resolution_set_custom 1920 1080" + Command "(1440p HD) 2560x1440", "menu_resolution_set_custom 2560 1440" + Command "(4K UHD) 3840x2160", "menu_resolution_set_custom 3840 2160" + StaticText "" + StaticText "$VIDMNU_ASPECT1610" + Command "960x600", "menu_resolution_set_custom 960 600" + Command "1280x800", "menu_resolution_set_custom 1280 800" + Command "1440x900", "menu_resolution_set_custom 1440 900" + Command "1680x1050", "menu_resolution_set_custom 1680 1050" + Command "1920x1200", "menu_resolution_set_custom 1920 1200" +} + + //------------------------------------------------------------------------------------------- // From 691440845338b780f56a1bf900e1babfec868f3f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 5 Dec 2019 00:54:55 +0100 Subject: [PATCH 115/203] - fixed writeback of hud_size CVAR G_ChangeHudLayout must ensure that the written value is ok, otherwise the auto validation in the CVAR can screw things up. --- source/common/gamecvars.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index 502098b09..baf242034 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -220,7 +220,7 @@ bool G_ChangeHudLayout(int direction) { int layout = hud_size - 1; while (!gi->validate_hud(layout) && layout >= 0) layout--; - if (layout >= 0) + if (layout >= 0 && layout < hud_size && gi->validate_hud(layout)) { hud_size = layout; return true; @@ -230,7 +230,7 @@ bool G_ChangeHudLayout(int direction) { int layout = hud_size + 1; while (!gi->validate_hud(layout) && layout <= 11) layout++; - if (layout <= 11) + if (layout <= 11 && layout > hud_size && gi->validate_hud(layout)) { hud_size = layout; return true; From 1507e9fd152611e0fafc2d3505c495d923cfa6d8 Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Thu, 5 Dec 2019 05:40:30 +0000 Subject: [PATCH 116/203] SW: Left-pin the mini HUD in widescreen git-svn-id: https://svn.eduke32.com/eduke32@8352 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # source/sw/src/text.cpp --- source/sw/src/inv.cpp | 12 ++++++++---- source/sw/src/text.cpp | 6 ++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/source/sw/src/inv.cpp b/source/sw/src/inv.cpp index 157d51174..5e1fc31f6 100644 --- a/source/sw/src/inv.cpp +++ b/source/sw/src/inv.cpp @@ -138,7 +138,8 @@ void UpdateMiniBar(PLAYERp pp) rotatesprite(x << 16, y << 16, (1 << 16), 0, MINI_BAR_HEALTH_BOX_PIC, 0, 0, - ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); + ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER | RS_ALIGN_L, + 0, 0, xdim - 1, ydim - 1); x = MINI_BAR_HEALTH_BOX_X+3; DisplayMiniBarNumber(pp, x, y+5, u->Health); @@ -149,7 +150,8 @@ void UpdateMiniBar(PLAYERp pp) rotatesprite(x << 16, y << 16, (1 << 16), 0, MINI_BAR_AMMO_BOX_PIC, 0, 0, - ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); + ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER | RS_ALIGN_L, + 0, 0, xdim - 1, ydim - 1); x = MINI_BAR_AMMO_BOX_X+3; DisplayMiniBarNumber(pp, x, y+5, pp->WpnAmmo[u->WeaponNum]); @@ -163,7 +165,8 @@ void UpdateMiniBar(PLAYERp pp) rotatesprite(x << 16, y << 16, (1 << 16), 0, MINI_BAR_INVENTORY_BOX_PIC, 0, 0, - ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); + ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER | RS_ALIGN_L, + 0, 0, xdim - 1, ydim - 1); id = &InventoryData[pp->InventoryNum]; @@ -173,7 +176,8 @@ void UpdateMiniBar(PLAYERp pp) rotatesprite(x << 16, y << 16, (1 << 16), 0, id->State->picndx, 0, 0, - ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); + ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER | RS_ALIGN_L, + 0, 0, xdim - 1, ydim - 1); // will update the AUTO and % inventory values PlayerUpdateInventory(pp, pp->InventoryNum); diff --git a/source/sw/src/text.cpp b/source/sw/src/text.cpp index a63b97b58..e65d2aabc 100644 --- a/source/sw/src/text.cpp +++ b/source/sw/src/text.cpp @@ -284,7 +284,8 @@ void DisplayMiniBarNumber(PLAYERp pp, short xs, short ys, int number) rotatesprite((long)x << 16, (long)ys << 16, (1 << 16), 0, pic, 0, 0, - ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); + ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER | RS_ALIGN_L, + 0, 0, xdim - 1, ydim - 1); size = tilesiz[PANEL_FONT_G + (*ptr - '0')].x + 1; } @@ -310,7 +311,8 @@ void DisplayMiniBarSmString(PLAYERp pp, short xs, short ys, short pal, const cha pic = FRAG_FIRST_TILE + (*ptr - FRAG_FIRST_ASCII); rotatesprite((int)x << 16, (int)ys << 16, (1 << 16), 0, pic, 0, pal, - ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); + ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER | RS_ALIGN_L, + 0, 0, xdim - 1, ydim - 1); } } From 22a778a22c895d2f7da3782bbae768ad89f0e3e1 Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Thu, 5 Dec 2019 05:40:34 +0000 Subject: [PATCH 117/203] SW: Don't show the status bar during the end of level screen git-svn-id: https://svn.eduke32.com/eduke32@8353 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/sw/src/game.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 213ef2113..af64a6667 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -1694,7 +1694,6 @@ void CreditsLevel(void) // get rid of all PERM sprites! renderFlushPerms(); save = gs.BorderNum; - SetBorder(Player + myconnectindex,0); ClearStartMost(); gs.BorderNum = save; videoClearViewableArea(0L); From 007d16712c2fd783399bc10e5ce8177b9be429ea Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Thu, 5 Dec 2019 05:40:38 +0000 Subject: [PATCH 118/203] SW: Draw the status bar under the menu instead of over it git-svn-id: https://svn.eduke32.com/eduke32@8354 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/sw/src/draw.cpp | 2 +- source/sw/src/panel.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index 6c8bbb330..62bcc2763 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -2610,7 +2610,7 @@ DrawCompass(PLAYERp pp) start_ang = NORM_CANG(start_ang - 4); flags = ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER; - if (RedrawCompass) + if (RedrawCompass && !UsingMenus) { RedrawCompass = FALSE; SET(flags, ROTATE_SPRITE_ALL_PAGES); diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index 12361d022..056b1bafa 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -7597,7 +7597,8 @@ pDisplaySprites(PLAYERp pp) } #if 1 - if (TEST(psp->flags, PANF_KILL_AFTER_SHOW) && !TEST(psp->flags, PANF_NOT_ALL_PAGES)) + extern SWBOOL UsingMenus; + if (TEST(psp->flags, PANF_KILL_AFTER_SHOW) && !TEST(psp->flags, PANF_NOT_ALL_PAGES) && !UsingMenus) { psp->numpages = 0; SET(flags, ROTATE_SPRITE_ALL_PAGES); From 5624c9b5b00cb14ec5ebc606ac0e3d90e29f80ca Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Thu, 5 Dec 2019 05:40:43 +0000 Subject: [PATCH 119/203] SW: Avoid a one-pixel tall hall of mirrors above the full status bar git-svn-id: https://svn.eduke32.com/eduke32@8355 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/sw/src/border.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/sw/src/border.cpp b/source/sw/src/border.cpp index 33398e44b..ac5609702 100644 --- a/source/sw/src/border.cpp +++ b/source/sw/src/border.cpp @@ -441,10 +441,9 @@ static void BorderSetView(PLAYERp, int *Xdim, int *Ydim, int *ScreenSize) y = DIV2(*Ydim) - DIV2((*ScreenSize **Ydim) / *Xdim); y2 = y + ((*ScreenSize **Ydim) / *Xdim) - 1; - if (ydim == 480 && gs.BorderNum == 2) - { - y2+=2; - } + // avoid a one-pixel tall HOM + if (gs.BorderNum == BORDER_BAR) + ++y2; // global windowxy1, windowxy2 coords set here videoSetViewableArea(x, y, x2, y2); From d1ed4063eb5c2ebc9017396f2baecf1ccc9bb292 Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Thu, 5 Dec 2019 05:40:46 +0000 Subject: [PATCH 120/203] Fix the widescreen alignment of weapons when shrinking the screen with + or - (currently disabled by default) Patch from Fox. git-svn-id: https://svn.eduke32.com/eduke32@8356 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/build/src/engine.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index a6dafafa6..35015e11b 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -6747,6 +6747,9 @@ void dorotspr_handle_bit2(int32_t *sxptr, int32_t *syptr, int32_t *z, int32_t da int32_t zoomsc, sx=*sxptr, sy=*syptr; int32_t ouryxaspect = yxaspect, ourxyaspect = xyaspect; + if ((dastat & RS_ALIGN_MASK) && (dastat & RS_ALIGN_MASK) != RS_ALIGN_MASK) + sx += NEGATE_ON_CONDITION(scale(120<<16,xdim,ydim) - (160<<16), !(dastat & RS_ALIGN_R)); + sy += rotatesprite_y_offset; // screen center to s[xy], 320<<16 coords. @@ -6774,17 +6777,7 @@ void dorotspr_handle_bit2(int32_t *sxptr, int32_t *syptr, int32_t *z, int32_t da // screen x center to sx1, scaled to viewport const int32_t scaledxofs = scale(normxofs, scale(xdimen, xdim, oxdim), 320); - int32_t xbord = 0; - - if ((dastat & RS_ALIGN_MASK) && (dastat & RS_ALIGN_MASK) != RS_ALIGN_MASK) - { - xbord = scale(oxdim-xdim, twice_midcx, oxdim); - - if ((dastat & RS_ALIGN_R)==0) - xbord = -xbord; - } - - sx = ((twice_midcx+xbord)<<15) + scaledxofs; + sx = ((twice_midcx)<<15) + scaledxofs; zoomsc = xdimenscale; //= scale(xdimen,yxaspect,320); zoomsc = mulscale16(zoomsc, rotatesprite_yxaspect); @@ -6806,9 +6799,7 @@ void dorotspr_handle_bit2(int32_t *sxptr, int32_t *syptr, int32_t *z, int32_t da if ((dastat & RS_ALIGN_MASK) == RS_ALIGN_MASK) sy += (oydim-ydim)<<15; - else if ((dastat & RS_ALIGN_MASK) == RS_ALIGN_R) - sx += (oxdim-xdim)<<16; - else if ((dastat & RS_ALIGN_MASK) == 0) + else sx += (oxdim-xdim)<<15; if (dastat & RS_CENTERORIGIN) From 169d68f583ec3c3e53ae7ebccf7c3094024dce15 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 5 Dec 2019 19:00:40 +0100 Subject: [PATCH 121/203] - fixed stuff and cleaned out most of the old menu code. --- source/blood/src/blood.cpp | 2 +- source/blood/src/d_menu.cpp | 1 - source/blood/src/demo.cpp | 1 - source/blood/src/endgame.cpp | 2 +- source/blood/src/gamemenu.cpp | 2903 +---------------------- source/blood/src/gamemenu.h | 438 ---- source/blood/src/loadsave.cpp | 2 +- source/blood/src/menu.cpp | 1866 +-------------- source/blood/src/menu.h | 62 - source/blood/src/network.cpp | 2 +- source/common/gamecvars.h | 1 - source/common/menu/menudef.cpp | 14 +- source/common/menu/optionmenuitems.h | 3 +- source/common/music/backend/i_sound.cpp | 1 + source/common/music/i_music.cpp | 5 +- source/common/music/music.cpp | 1 + source/duke3d/src/menus.cpp | 487 ---- source/duke3d/src/menus.h | 359 --- source/rr/src/menus.cpp | 1416 ----------- source/sw/src/sounds.cpp | 25 +- wadsrc/static/demolition/language.csv | 327 ++- wadsrc/static/demolition/menudef.txt | 31 +- 22 files changed, 299 insertions(+), 7650 deletions(-) delete mode 100644 source/blood/src/menu.h diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 1b1610d4c..b7f692460 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -48,7 +48,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "globals.h" #include "levels.h" #include "loadsave.h" -#include "menu.h" +#include "gamemenu.h" #include "mirrors.h" #include "music.h" #include "network.h" diff --git a/source/blood/src/d_menu.cpp b/source/blood/src/d_menu.cpp index 1d6c14c5f..66f088d5a 100644 --- a/source/blood/src/d_menu.cpp +++ b/source/blood/src/d_menu.cpp @@ -33,7 +33,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "globals.h" #include "inifile.h" #include "levels.h" -#include "menu.h" #include "qav.h" #include "resource.h" #include "view.h" diff --git a/source/blood/src/demo.cpp b/source/blood/src/demo.cpp index de8d9cec2..b00b89a5e 100644 --- a/source/blood/src/demo.cpp +++ b/source/blood/src/demo.cpp @@ -39,7 +39,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gamemenu.h" #include "globals.h" #include "levels.h" -#include "menu.h" #include "messages.h" #include "misc.h" #include "music.h" diff --git a/source/blood/src/endgame.cpp b/source/blood/src/endgame.cpp index 98e6c2361..cc094afd8 100644 --- a/source/blood/src/endgame.cpp +++ b/source/blood/src/endgame.cpp @@ -33,7 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "globals.h" #include "levels.h" #include "loadsave.h" -#include "menu.h" +#include "gamemenu.h" #include "network.h" #include "player.h" #include "sound.h" diff --git a/source/blood/src/gamemenu.cpp b/source/blood/src/gamemenu.cpp index bc667d65e..8b1428260 100644 --- a/source/blood/src/gamemenu.cpp +++ b/source/blood/src/gamemenu.cpp @@ -33,15 +33,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "globals.h" #include "inifile.h" #include "levels.h" -#include "menu.h" +#include "gamemenu.h" #include "qav.h" #include "demo.h" #include "resource.h" #include "view.h" #include "c_bind.h" -bool ShowOptionMenu(); - BEGIN_BLD_NS const char* zNetGameTypes[] = @@ -66,2904 +64,5 @@ void drawLoadingScreen(void) viewLoadingScreen(2049, buffer, levelGetTitle(), NULL); } -#if 0 - -CMenuTextMgr gMenuTextMgr; -CGameMenuMgr gGameMenuMgr; - -extern CGameMenuItemPicCycle itemSorryPicCycle; -extern CGameMenuItemQAV itemBloodQAV; - -CMenuTextMgr::CMenuTextMgr() -{ - at0 = -1; -} - -static char buffer[21][45]; - -void CMenuTextMgr::DrawText(const char *pString, int nFont, int x, int y, int nShade, int nPalette, bool shadow ) -{ - viewDrawText(nFont, pString, x, y, nShade, nPalette, 0, shadow); -} - -void CMenuTextMgr::GetFontInfo(int nFont, const char *pString, int *pXSize, int *pYSize) -{ - if (nFont < 0 || nFont >= 5) - return; - viewGetFontInfo(nFont, pString, pXSize, pYSize); -} - -bool CGameMenuMgr::m_bInitialized = false; -bool CGameMenuMgr::m_bActive = false; -bool CGameMenuMgr::m_bScanning = false; - -CGameMenuMgr::CGameMenuMgr() -{ - dassert(!m_bInitialized); - m_bInitialized = true; - Clear(); -} - -CGameMenuMgr::~CGameMenuMgr() -{ - m_bInitialized = false; - Clear(); -} - -void CGameMenuMgr::InitializeMenu(void) -{ - if (pActiveMenu) - { - CGameMenuEvent event; - event.at0 = kMenuEventInit; - event.at2 = 0; - pActiveMenu->Event(event); - } -} - -void CGameMenuMgr::DeInitializeMenu(void) -{ - if (pActiveMenu) - { - CGameMenuEvent event; - event.at0 = kMenuEventDeInit; - event.at2 = 0; - pActiveMenu->Event(event); - } -} - -bool CGameMenuMgr::Push(CGameMenu *pMenu, int nItem) -{ - if (nMenuPointer == 0) - { - m_mouselastactivity = -M_MOUSETIMEOUT; - m_mousewake_watchpoint = 0; - mouseLockToWindow(0); - //mouseMoveToCenter(); - inputState.mouseReadAbs(&m_prevmousepos); - } - dassert(pMenu != NULL); - if (nMenuPointer == 8) - return false; - pActiveMenu = pMenuStack[nMenuPointer] = pMenu; - nMenuPointer++; - if (nItem >= 0) - pMenu->SetFocusItem(nItem); - m_bActive = true; - gInputMode = kInputMenu; - InitializeMenu(); - m_menuchange_watchpoint = 1; - m_mousecaught = 1; - return true; -} - -void CGameMenuMgr::Pop(void) -{ - if (nMenuPointer > 0) - { - DeInitializeMenu(); - nMenuPointer--; - if (nMenuPointer == 0) - Deactivate(); - else - pActiveMenu = pMenuStack[nMenuPointer-1]; - - m_menuchange_watchpoint = 1; - } - m_mousecaught = 1; -} - -void CGameMenuMgr::PostPop(void) -{ - m_postPop = true; -} - -void CGameMenuMgr::Draw(void) -{ - if (pActiveMenu) - { - pActiveMenu->Draw(); - viewUpdatePages(); - } - - if (m_postPop) - { - Pop(); - m_postPop = false; - } - - int32_t mousestatus = inputState.mouseReadAbs(&m_mousepos); - if (mousestatus && inputState.mouseClickState() == MOUSE_PRESSED) - m_mousedownpos = m_mousepos; - - int16_t mousetile = 1043; // red arrow - if (tilesiz[mousetile].x > 0 && mousestatus) - { - if (!MOUSEACTIVECONDITION) - m_mousewake_watchpoint = 1; - - if (MOUSEACTIVECONDITIONAL(inputState.mouseAdvanceClickState()) || m_mousepos.x != m_prevmousepos.x || m_mousepos.y != m_prevmousepos.y) - { - m_prevmousepos = m_mousepos; - m_mouselastactivity = (int)totalclock; - } - else - m_mousewake_watchpoint = 0; - - m_mousecaught = 0; - } - else - { - m_mouselastactivity = -M_MOUSETIMEOUT; - - m_mousewake_watchpoint = 0; - } - - // Display the mouse cursor, except on touch devices. - if (MOUSEACTIVECONDITION) - { - vec2_t cursorpos = { m_mousepos.x + (7 << 16), m_mousepos.y + (6 << 16) }; - - if ((unsigned) mousetile < MAXTILES) - { - int32_t scale = 65536; - int16_t rotate = 768; - uint32_t stat = 2|4|8; - int8_t alpha = MOUSEALPHA; //CURSORALPHA; - rotatesprite_fs_alpha(cursorpos.x, cursorpos.y, scale, rotate, mousetile, 0, 0, stat, alpha); - } - } - else - inputState.clearMouseClickState(); - -} - -void CGameMenuMgr::Clear(void) -{ - pActiveMenu = NULL; - memset(pMenuStack, 0, sizeof(pMenuStack)); - nMenuPointer = 0; - m_postPop = false; -} - -void CGameMenuMgr::Process(void) -{ - if (!pActiveMenu) - return; - - if (m_menuchange_watchpoint > 0) - m_menuchange_watchpoint++; - - CGameMenuEvent event; - event.at0 = 0; - event.at2 = 0; - char key; - if (!pActiveMenu->MouseEvent(event) && (key = inputState.keyGetScan()) != 0 ) - { - inputState.keyFlushScans(); - inputState.keyFlushChars(); - event.at2 = key; - switch (key) - { - case sc_Escape: - event.at0 = kMenuEventEscape; - break; - case sc_Tab: - if (inputState.ShiftPressed()) - event.at0 = kMenuEventUp; - else - event.at0 = kMenuEventDown; - break; - case sc_UpArrow: - case sc_kpad_8: - event.at0 = kMenuEventUp; - gGameMenuMgr.m_mouselastactivity = -M_MOUSETIMEOUT; - break; - case sc_DownArrow: - case sc_kpad_2: - event.at0 = kMenuEventDown; - gGameMenuMgr.m_mouselastactivity = -M_MOUSETIMEOUT; - break; - case sc_Enter: - case sc_kpad_Enter: - event.at0 = kMenuEventEnter; - break; - case sc_Space: - event.at0 = kMenuEventSpace; - break; - case sc_LeftArrow: - case sc_kpad_4: - event.at0 = kMenuEventLeft; - break; - case sc_RightArrow: - case sc_kpad_6: - event.at0 = kMenuEventRight; - break; - case sc_Delete: - case sc_kpad_Period: - event.at0 = kMenuEventDelete; - break; - case sc_BackSpace: - event.at0 = kMenuEventBackSpace; - break; - default: - event.at0 = kMenuEventKey; - break; - } - } - if (pActiveMenu->Event(event)) - Pop(); - - if (m_menuchange_watchpoint >= 3) - m_menuchange_watchpoint = 0; -} - -void CGameMenuMgr::Deactivate(void) -{ - Clear(); - inputState.keyFlushScans(); - inputState.keyFlushChars(); - m_bActive = false; - - mouseLockToWindow(1); - gInputMode = kInputGame; -} - -bool CGameMenuMgr::MouseOutsideBounds(vec2_t const * const pos, const int32_t x, const int32_t y, const int32_t width, const int32_t height) -{ - return pos->x < x || pos->x >= x + width || pos->y < y || pos->y >= y + height; -} - -CGameMenu::CGameMenu() -{ - m_nItems = 0; - m_nFocus = at8 = -1; - atc = 0; -} - -CGameMenu::CGameMenu(int unk) -{ - m_nItems = 0; - m_nFocus = at8 = -1; - atc = unk; -} - -CGameMenu::~CGameMenu() -{ - if (!atc) - return; - for (int i = 0; i < m_nItems; i++) - { - if (pItemList[i] != &itemBloodQAV && pItemList[i] != &itemSorryPicCycle) - delete pItemList[i]; - } -} - -void CGameMenu::InitializeItems(CGameMenuEvent &event) -{ - for (int i = 0; i < m_nItems; i++) - { - pItemList[i]->Event(event); - } -} - -void CGameMenu::Draw(void) -{ - for (int i = 0; i < m_nItems; i++) - { - if (pItemList[i]->pPreDrawCallback) - pItemList[i]->pPreDrawCallback(pItemList[i]); - if (i == m_nFocus || (i != m_nFocus && !pItemList[i]->bNoDraw)) - pItemList[i]->Draw(); - } -} - -bool CGameMenu::Event(CGameMenuEvent &event) -{ - if (m_nItems <= 0) - return true; - switch (event.at0) - { - case kMenuEventInit: - case kMenuEventDeInit: - if (at8 >= 0) - m_nFocus = at8; - InitializeItems(event); - return false; - } - if (m_nFocus < 0) - return true; - return pItemList[m_nFocus]->Event(event); -} - -void CGameMenu::Add(CGameMenuItem *pItem, bool active) -{ - dassert(pItem != NULL); - dassert(m_nItems < kMaxGameMenuItems); - pItemList[m_nItems] = pItem; - pItem->pMenu = this; - if (active) - m_nFocus = at8 = m_nItems; - m_nItems++; -} - -void CGameMenu::SetFocusItem(int nItem) -{ - dassert(nItem >= 0 && nItem < m_nItems && nItem < kMaxGameMenuItems); - if (CanSelectItem(nItem)) - m_nFocus = at8 = nItem; -} - -void CGameMenu::SetFocusItem(CGameMenuItem *pItem) -{ - for (int i = 0; i < m_nItems; i++) - if (pItemList[i] == pItem) - { - SetFocusItem(i); - break; - } -} - -bool CGameMenu::CanSelectItem(int nItem) -{ - dassert(nItem >= 0 && nItem < m_nItems && nItem < kMaxGameMenuItems); - return pItemList[nItem]->bCanSelect && pItemList[nItem]->bEnable; -} - -void CGameMenu::FocusPrevItem(void) -{ - dassert(m_nFocus >= -1 && m_nFocus < m_nItems && m_nFocus < kMaxGameMenuItems); - int t = m_nFocus; - do - { - m_nFocus--; - if (m_nFocus < 0) - m_nFocus += m_nItems; - if (CanSelectItem(m_nFocus)) - break; - } while(t != m_nFocus); -} - -void CGameMenu::FocusNextItem(void) -{ - dassert(m_nFocus >= -1 && m_nFocus < m_nItems && m_nFocus < kMaxGameMenuItems); - int t = m_nFocus; - do - { - m_nFocus++; - if (m_nFocus >= m_nItems) - m_nFocus = 0; - if (CanSelectItem(m_nFocus)) - break; - } while(t != m_nFocus); -} - -bool CGameMenu::IsFocusItem(CGameMenuItem *pItem) -{ - if (m_nFocus < 0) - return false; - dassert(m_nFocus >= 0 && m_nFocus < m_nItems && m_nFocus < kMaxGameMenuItems); - return pItemList[m_nFocus] == pItem; -} - -bool CGameMenu::MouseEvent(CGameMenuEvent &event) -{ - if (m_nItems <= 0 || m_nFocus < 0) - return true; - return pItemList[m_nFocus]->MouseEvent(event); -} - -CGameMenuItem::CGameMenuItem() -{ - m_pzText = NULL; - m_nX = m_nY = m_nWidth = 0; - bCanSelect = 1; - bEnable = 1; - m_nFont = -1; - pMenu = NULL; - bNoDraw = 0; - pPreDrawCallback = NULL; -} - -CGameMenuItem::~CGameMenuItem() -{ -} - -bool CGameMenuItem::Event(CGameMenuEvent &event) -{ - switch (event.at0) - { - case kMenuEventEscape: - return true; - case kMenuEventUp: - pMenu->FocusPrevItem(); - break; - case kMenuEventDown: - pMenu->FocusNextItem(); - break; - } - return false; -} - -bool CGameMenuItem::MouseEvent(CGameMenuEvent &event) -{ - event.at0 = kMenuEventNone; - if (MOUSEINACTIVECONDITIONAL(inputState.MouseGetButtons()&LEFT_MOUSE)) - { - event.at0 = kMenuEventEnter; - inputState.MouseClearButton(LEFT_MOUSE); - } - else if (inputState.MouseGetButtons()&RIGHT_MOUSE) - { - event.at0 = kMenuEventEscape; - inputState.MouseClearButton(RIGHT_MOUSE); - } - else if (inputState.MouseGetButtons()&WHEELUP_MOUSE) - { - inputState.MouseClearButton(WHEELUP_MOUSE); - event.at0 = kMenuEventUp; - } - else if (inputState.MouseGetButtons()&WHEELDOWN_MOUSE) - { - inputState.MouseClearButton(WHEELDOWN_MOUSE); - event.at0 = kMenuEventDown; - } - return event.at0 != kMenuEventNone; -} - -CGameMenuItemText::CGameMenuItemText() -{ - m_pzText = 0; - bEnable = 0; -} - -CGameMenuItemText::CGameMenuItemText(const char *a1, int a2, int a3, int a4, int a5) -{ - m_nWidth = 0; - m_pzText = a1; - m_nFont = a2; - m_nX = a3; - m_nY = a4; - at20 = a5; - bEnable = 0; -} - -void CGameMenuItemText::Draw(void) -{ - if (m_pzText) - { - int width; - int x = m_nX; - switch (at20) - { - case 1: - gMenuTextMgr.GetFontInfo(m_nFont, m_pzText, &width, NULL); - x = m_nX-width/2; - break; - case 2: - gMenuTextMgr.GetFontInfo(m_nFont, m_pzText, &width, NULL); - x = m_nX-width; - break; - } - gMenuTextMgr.DrawText(m_pzText,m_nFont, x, m_nY, -128, 0, false); - } -} - -CGameMenuItemTitle::CGameMenuItemTitle() -{ - m_pzText = 0; - bEnable = 0; -} - -CGameMenuItemTitle::CGameMenuItemTitle(const char *a1, int a2, int a3, int a4, int a5) -{ - m_nWidth = 0; - m_pzText = a1; - m_nFont = a2; - m_nX = a3; - m_nY = a4; - at20 = a5; - bEnable = 0; -} - -void CGameMenuItemTitle::Draw(void) -{ - if (m_pzText) - { - int height; - gMenuTextMgr.GetFontInfo(m_nFont, NULL, NULL, &height); - if (at20 >= 0) - rotatesprite(320<<15, m_nY<<16, 65536, 0, at20, -128, 0, 78, 0, 0, xdim-1, ydim-1); - viewDrawText(m_nFont, m_pzText, m_nX, m_nY-height/2, -128, 0, 1, false); - } -} - -CGameMenuItemZBool::CGameMenuItemZBool() -{ - at20 = false; - m_pzText = 0; - at21 = "On"; - at25 = "Off"; -} - -CGameMenuItemZBool::CGameMenuItemZBool(const char *a1, int a2, int a3, int a4, int a5, bool a6, void(*a7)(CGameMenuItemZBool *), const char *a8, const char *a9) -{ - m_pzText = a1; - m_nFont = a2; - m_nX = a3; - m_nY = a4; - m_nWidth = a5; - at20 = a6; - at29 = a7; - if (!a8) - at21 = "On"; - else - at21 = a8; - if (!a9) - at25 = "Off"; - else - at25 = a9; -} - -void CGameMenuItemZBool::Draw(void) -{ - int shade = bEnable ? 32 : 48; - int pal = bEnable ? 0 : 5; - if (pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - if (m_pzText) - gMenuTextMgr.DrawText(m_pzText, m_nFont, m_nX, m_nY, shade, pal, false); - const char *value = at20 ? at21 : at25; - int width, height; - gMenuTextMgr.GetFontInfo(m_nFont, value, &width, &height); - gMenuTextMgr.DrawText(value, m_nFont, m_nWidth-1+m_nX-width, m_nY, shade, pal, false); - int mx = m_nX<<16; - int my = m_nY<<16; - int mw = m_nWidth<<16; - int mh = height<<16; - if (bEnable && MOUSEACTIVECONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousepos, mx, my, mw, mh))) - { - if (MOUSEWATCHPOINTCONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_prevmousepos, mx, my, mw, mh))) - { - pMenu->SetFocusItem(this); - } - - if (!gGameMenuMgr.m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousedownpos, mx, my, mw, mh)) - { - pMenu->SetFocusItem(this); - - CGameMenuEvent event = { kMenuEventEnter, 0 }; - - gGameMenuMgr.m_mousecaught = 1; - - if (Event(event)) - gGameMenuMgr.PostPop(); - } - } -} - -bool CGameMenuItemZBool::Event(CGameMenuEvent &event) -{ - switch (event.at0) - { - case kMenuEventEnter: - case kMenuEventSpace: - at20 = !at20; - if (at29) - at29(this); - return false; - } - return CGameMenuItem::Event(event); -} - -CGameMenuItemChain::CGameMenuItemChain() -{ - m_pzText = NULL; - at24 = NULL; - at28 = -1; - at2c = NULL; - at30 = 0; -} - -CGameMenuItemChain::CGameMenuItemChain(const char *a1, int a2, int a3, int a4, int a5, int a6, CGameMenu *a7, int a8, void(*a9)(CGameMenuItemChain *), int a10) -{ - m_pzText = a1; - m_nFont = a2; - m_nX = a3; - m_nY = a4; - m_nWidth = a5; - at20 = a6; - at24 = a7; - at28 = a8; - at2c = a9; - at30 = a10; -} - -void CGameMenuItemChain::Draw(void) -{ - if (!m_pzText) return; - int shade = bEnable ? 32 : 48; - int pal = bEnable ? 0 : 5; - if (pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - int width, height; - int x = m_nX; - int y = m_nY; - gMenuTextMgr.GetFontInfo(m_nFont, m_pzText, &width, &height); - switch (at20) - { - case 1: - x = m_nX+m_nWidth/2-width/2; - break; - case 2: - x = m_nX+m_nWidth-1-width; - break; - case 0: - default: - break; - } - gMenuTextMgr.DrawText(m_pzText, m_nFont, x, m_nY, shade, pal, true); - if (bEnable && MOUSEACTIVECONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousepos, x<<16, y<<16, width<<16, height<<16))) - { - if (MOUSEWATCHPOINTCONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_prevmousepos, x<<16, y<<16, width<<16, height<<16))) - { - pMenu->SetFocusItem(this); - } - - if (!gGameMenuMgr.m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousedownpos, x<<16, y<<16, width<<16, height<<16)) - { - pMenu->SetFocusItem(this); - - CGameMenuEvent event = { kMenuEventEnter, 0 }; - - gGameMenuMgr.m_mousecaught = 1; - - if (Event(event)) - gGameMenuMgr.PostPop(); - } - } -} - -bool CGameMenuItemChain::Event(CGameMenuEvent &event) -{ - switch (event.at0) - { - case kMenuEventEnter: - if (at2c) - at2c(this); - if (at24) - gGameMenuMgr.Push(at24, at28); - return false; - } - return CGameMenuItem::Event(event); -} - -CGameMenuItem7EA1C::CGameMenuItem7EA1C() -{ - m_pzText = NULL; - at24 = NULL; - at28 = -1; - at2c = NULL; - at30 = 0; - at34 = NULL; - at38[0] = 0; - at48[0] = 0; -} - -CGameMenuItem7EA1C::CGameMenuItem7EA1C(const char *a1, int a2, int a3, int a4, int a5, const char *a6, const char *a7, int a8, int a9, void(*a10)(CGameMenuItem7EA1C *), int a11) -{ - m_pzText = a1; - m_nFont = a2; - m_nX = a3; - m_nY = a4; - m_nWidth = a5; - at20 = a8; - at28 = a9; - at2c = a10; - at30 = a11; - strncpy(at38, a6, 15); - strncpy(at48, a7, 15); -} - -void CGameMenuItem7EA1C::Draw(void) -{ - if (!m_pzText) return; - int shade = bEnable ? 32 : 48; - int pal = bEnable ? 0 : 5; - if (pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - int width; - int x = m_nX; - switch (at20) - { - case 1: - gMenuTextMgr.GetFontInfo(m_nFont, m_pzText, &width, NULL); - x = m_nX+m_nWidth/2-width/2; - break; - case 2: - gMenuTextMgr.GetFontInfo(m_nFont, m_pzText, &width, NULL); - x = m_nX+m_nWidth-1-width; - break; - case 0: - default: - break; - } - gMenuTextMgr.DrawText(m_pzText, m_nFont, x, m_nY, shade, pal, true); -} - -void CGameMenuItem7EA1C::Setup(void) -{ - if (!at34 || !at24) - return; - if (!at34->SectionExists(at48)) - return; - const char *title = at34->GetKeyString(at48, "Title", at48); - at24->Add(new CGameMenuItemTitle(title, 1, 160, 20, 2038), false); - at24->Add(&itemSorryPicCycle, true); - int y = 40; - for (int i = 0; i < 21; i++) - { - sprintf(buffer[i], "Line%d", i+1); - if (!at34->KeyExists(at48, buffer[i])) - break; - const char *line = at34->GetKeyString(at48, buffer[i], NULL); - if (line) - { - if (*line == 0) - { - y += 10; - continue; - } - at24->Add(new CGameMenuItemText(line, 1, 160, y, 1), false); - y += 20; - } - } - at24->Add(&itemBloodQAV, false); -} - -bool CGameMenuItem7EA1C::Event(CGameMenuEvent &event) -{ - switch (event.at0) - { - case kMenuEventEnter: - { - if (at2c) - at2c(this); - if (at24) - delete at24; - at24 = new CGameMenu(1); - /* - DICTNODE *pRes = gGuiRes.Lookup(at38, "MNU"); - if (pRes) - { - at34 = new IniFile(gGuiRes.Load(pRes)); - Setup(); - } - */ - if (at24) - gGameMenuMgr.Push(at24, at28); - return false; - } - case kMenuEventDeInit: - if (at34) - { - delete at34; - at34 = NULL; - } - if (at24) - { - delete at24; - at24 = NULL; - } - return false; - } - return CGameMenuItem::Event(event); -} - -CGameMenuItem7EE34::CGameMenuItem7EE34() -{ - m_pzText = NULL; - at28 = NULL; - at20 = -1; - at2c = NULL; -} - -CGameMenuItem7EE34::CGameMenuItem7EE34(const char *a1, int a2, int a3, int a4, int a5, int a6) -{ - m_pzText = NULL; - at28 = NULL; - at20 = -1; - at2c = NULL; - m_nFont = a2; - m_nX = a3; - m_pzText = a1; - m_nY = a4; - m_nWidth = a5; - at24 = a6; -} - -void CGameMenuItem7EE34::Draw(void) -{ - if (!m_pzText) return; - int shade = bEnable ? 32 : 48; - int pal = bEnable ? 0 : 5; - if (pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - int width; - int x = m_nX; - switch (at24) - { - case 1: - gMenuTextMgr.GetFontInfo(m_nFont, m_pzText, &width, NULL); - x = m_nX+m_nWidth/2-width/2; - break; - case 2: - gMenuTextMgr.GetFontInfo(m_nFont, m_pzText, &width, NULL); - x = m_nX+m_nWidth-1-width; - break; - case 0: - default: - break; - } - gMenuTextMgr.DrawText(m_pzText, m_nFont, x, m_nY, shade, pal, true); -} - -extern void SetVideoModeOld(CGameMenuItemChain *pItem); - -void CGameMenuItem7EE34::Setup(void) -{ - if (!at28) - return; - at28->Add(new CGameMenuItemTitle("Video Mode", 1, 160, 20, 2038), false); - if (!at2c) - { - at2c = new CGameMenu(1); - at2c->Add(new CGameMenuItemTitle(" Mode Change ", 1, 160, 20, 2038), false); - at2c->Add(&itemSorryPicCycle, true); - CGameMenuItem *pItem1 = new CGameMenuItemText("VIDEO MODE WAS SET", 1, 160, 90, 1); - CGameMenuItem *pItem2 = new CGameMenuItemText("NOT ALL MODES Work correctly", 1, 160, 110, 1); - CGameMenuItem *pItem3 = new CGameMenuItemText("Press ESC to exit", 3, 160, 140, 1); - at2c->Add(pItem1, false); - pItem1->bEnable = 0; - at2c->Add(pItem2, false); - pItem2->bEnable = 0; - at2c->Add(pItem3, true); - pItem3->bEnable = 1; - at2c->Add(&itemBloodQAV, false); - } - sprintf(buffer[0], "640 x 480 (default)"); - int y = 40; - at28->Add(new CGameMenuItemChain(buffer[0], 3, 0, y, 320, 1, at2c, -1, SetVideoModeOld, validmodecnt), true); - y += 20; - for (int i = 0; i < validmodecnt && i < 20; i++) - { - sprintf(buffer[i+1], "%d x %d", validmode[i].xdim, validmode[i].ydim); - at28->Add(new CGameMenuItemChain(buffer[i+1], 3, 0, y, 320, 1, at2c, -1, SetVideoModeOld, i), false); - if (validmodecnt > 10) - y += 7; - else - y += 15; - } - at28->Add(&itemBloodQAV, false); -} - -bool CGameMenuItem7EE34::Event(CGameMenuEvent &event) -{ - switch (event.at0) - { - case kMenuEventEnter: - if (at28) - delete at28; - at28 = new CGameMenu(1); - Setup(); - if (at28) - gGameMenuMgr.Push(at28, at20); - return false; - case kMenuEventDeInit: - if (at28) - { - delete at28; - at28 = 0; - } - return false; - } - return CGameMenuItem::Event(event); -} - -CGameMenuItemChain7F2F0::CGameMenuItemChain7F2F0() -{ - at34 = -1; -} - -CGameMenuItemChain7F2F0::CGameMenuItemChain7F2F0(char *a1, int a2, int a3, int a4, int a5, int a6, CGameMenu *a7, int a8, void(*a9)(CGameMenuItemChain *), int a10) : - CGameMenuItemChain(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) -{ - at34 = a10; -} - -bool CGameMenuItemChain7F2F0::Event(CGameMenuEvent &event) -{ - switch (event.at0) - { - case kMenuEventEnter: - if (at34 > -1) - gGameOptions.nEpisode = at34; - return CGameMenuItemChain::Event(event); - } - return CGameMenuItem::Event(event); -} - -CGameMenuItemBitmap::CGameMenuItemBitmap() -{ - m_pzText = NULL; -} - -CGameMenuItemBitmap::CGameMenuItemBitmap(const char *a1, int a2, int a3, int a4, int a5) -{ - m_pzText = a1; - m_nFont = a2; - m_nX = a3; - m_nY = a4; - at20 = a5; -} - -void CGameMenuItemBitmap::Draw(void) -{ - int shade = bEnable ? 32 : 48; - int pal = bEnable ? 0 : 5; - if (bEnable && pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - int x = m_nX; - int y = m_nY; - if (m_pzText) - { - int height; - gMenuTextMgr.DrawText(m_pzText, m_nFont, x, y, shade, pal, false); - gMenuTextMgr.GetFontInfo(m_nFont, NULL, NULL, &height); - y += height + 2; - } - rotatesprite(x<<15,y<<15, 65536, 0, at20, 0, 0, 82, 0, 0, xdim-1,ydim-1); -} - -bool CGameMenuItemBitmap::Event(CGameMenuEvent &event) -{ - if (bEnable && pMenu->IsFocusItem(this)) - pMenu->FocusNextItem(); - return CGameMenuItem::Event(event); -} - -CGameMenuItemBitmapLS::CGameMenuItemBitmapLS() -{ - m_pzText = NULL; -} - -CGameMenuItemBitmapLS::CGameMenuItemBitmapLS(const char *a1, int a2, int a3, int a4, int a5) -{ - at24 = -1; - m_pzText = a1; - m_nFont = a2; - m_nX = a3; - m_nY = a4; - at28 = a5; -} - -void CGameMenuItemBitmapLS::Draw(void) -{ - int shade = bEnable ? 32 : 48; - int pal = bEnable ? 0 : 5; - if (bEnable && pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - int x = m_nX; - int y = m_nY; - if (m_pzText) - { - int height; - gMenuTextMgr.DrawText(m_pzText, m_nFont, x, y, shade, pal, false); - gMenuTextMgr.GetFontInfo(m_nFont, NULL, NULL, &height); - y += height + 2; - } - char stat; - int16_t ang; - int picnum; - if (at24 == -1) - { - stat = 66; - ang = 0; - picnum = at28; - } - else - { - ang = 512; - stat = 70; - picnum = at24; - } - rotatesprite(200<<15,215<<15,32768, ang, picnum, 0, 0, stat, 0, 0, xdim-1, ydim-1); -} - -bool CGameMenuItemBitmapLS::Event(CGameMenuEvent &event) -{ - if (bEnable && pMenu->IsFocusItem(this)) - pMenu->FocusNextItem(); - return CGameMenuItem::Event(event); -} - -CGameMenuItemKeyList::CGameMenuItemKeyList() -{ - m_pzText = NULL; - m_nFont = 3; - m_nX = 0; - m_nY = 0; - nRows = 0; - nTopDelta = 0; - nFocus = 0; - nGameFuncs = 0; - bScan = false; -} - -CGameMenuItemKeyList::CGameMenuItemKeyList(const char *a1, int a2, int a3, int a4, int a5, int a6, int a7, void(*a8)(CGameMenuItemKeyList *)) -{ - nTopDelta = 0; - nFocus = 0; - bScan = false; - m_pzText = a1; - m_nFont = a2; - m_nX = a3; - m_nY = a4; - m_nWidth = a5; - nRows = a6; - pCallback = a8; - nGameFuncs = a7; -} - -void CGameMenuItemKeyList::Scan(void) -{ - inputState.keyFlushChars(); - inputState.keyFlushScans(); - inputState.ClearKeysDown(); - bScan = true; -} - -void CGameMenuItemKeyList::Draw(void) -{ - char buffer[40]; - int width, height; - int shade; - gMenuTextMgr.GetFontInfo(m_nFont, NULL, NULL, &height); - int y = m_nY; - int k = nFocus - nTopDelta; - int nNewFocus = nFocus; - bool bClick = false; - for (int i = 0; i < nRows; i++, y += height, k++) - { - auto keys = Bindings.GetKeysForCommand(buttonMap.GetButtonName(k)); - FString text = C_NameKeys(keys.Data(), std::min(keys.Size(), 2u)); - sprintf(buffer, "%s", buttonMap.GetButtonName(k)); - - if (k == nFocus) - { - shade = 32; - if (pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - viewDrawText(3, buffer, m_nX, y, shade, 0, 0, false); - const char *sVal; - if (bScan && ((int)totalclock & 32)) - sVal = "____"; - else - sVal = text; - gMenuTextMgr.GetFontInfo(m_nFont, sVal, &width, 0); - viewDrawText(m_nFont, sVal, m_nX+m_nWidth-1-width, y, shade, 0, 0, false); - } - else - { - viewDrawText(3, buffer, m_nX, y, 24, 0, 0, false); - gMenuTextMgr.GetFontInfo(m_nFont, text, &width, 0); - viewDrawText(m_nFont, text, m_nX+m_nWidth-1-width, y, 24, 0, 0, false); - } - int mx = m_nX<<16; - int my = y<<16; - int mw = m_nWidth<<16; - int mh = height<<16; - if (!bScan && bEnable && MOUSEACTIVECONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousepos, mx, my, mw, mh))) - { - if (MOUSEWATCHPOINTCONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_prevmousepos, mx, my, mw, mh))) - { - nNewFocus = k; - } - - if (!gGameMenuMgr.m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousedownpos, mx, my, mw, mh)) - { - nNewFocus = k; - bClick = true; - } - } - } - nTopDelta += nNewFocus-nFocus; - nFocus = nNewFocus; - if (bClick) - { - CGameMenuEvent event = { kMenuEventEnter, 0 }; - - gGameMenuMgr.m_mousecaught = 1; - - if (Event(event)) - gGameMenuMgr.PostPop(); - } -} - -bool CGameMenuItemKeyList::Event(CGameMenuEvent &event) -{ - if (bScan) - { - if (inputState.GetLastScanCode() && inputState.GetLastScanCode() != sc_Pause) - { - if (inputState.keyBufferWaiting()) - inputState.keyGetChar(); - - Bindings.SetBind(inputState.GetLastScanCode(), buttonMap.GetButtonName(nFocus)); - inputState.keyFlushChars(); - inputState.keyFlushScans(); - inputState.ClearKeysDown(); - inputState.keyFlushScans(); - inputState.keyFlushChars(); - bScan = 0; - } - return false; - } - switch (event.at0) - { - case kMenuEventUp: - if (event.at2 == sc_Tab || nFocus == 0) - { - pMenu->FocusPrevItem(); - return false; - } - nFocus--; - if (nTopDelta > 0) - nTopDelta--; - return false; - case kMenuEventDown: - if (event.at2 == sc_Tab || nFocus == nGameFuncs-1) - { - pMenu->FocusNextItem(); - return false; - } - nFocus++; - if (nTopDelta+1 < nRows) - nTopDelta++; - return false; - case kMenuEventEnter: - if (pCallback) - pCallback(this); - Scan(); - return false; - case kMenuEventBackSpace: - case kMenuEventDelete: - Bindings.UnbindACommand(buttonMap.GetButtonName(nFocus)); - return false; - case kMenuEventScrollUp: - if (nFocus-nTopDelta > 0) - { - nTopDelta++; - if (nTopDelta>0) - { - nFocus--; - nTopDelta--; - } - } - return false; - case kMenuEventScrollDown: - if (nFocus-nTopDelta+nRows < nGameFuncs) - { - nTopDelta--; - if (nTopDelta+1 < nRows) - { - nFocus++; - nTopDelta++; - } - } - return false; - } - return CGameMenuItem::Event(event); -} - -bool CGameMenuItemKeyList::MouseEvent(CGameMenuEvent &event) -{ - event.at0 = kMenuEventNone; - if (MOUSEACTIVECONDITIONAL(inputState.MouseGetButtons()&WHEELUP_MOUSE)) - { - gGameMenuMgr.m_mouselastactivity = (int)totalclock; - inputState.MouseClearButton(WHEELUP_MOUSE); - event.at0 = kMenuEventScrollUp; - } - else if (MOUSEACTIVECONDITIONAL(inputState.MouseGetButtons()&WHEELDOWN_MOUSE)) - { - gGameMenuMgr.m_mouselastactivity = (int)totalclock; - inputState.MouseClearButton(WHEELDOWN_MOUSE); - event.at0 = kMenuEventScrollDown; - } - else - return CGameMenuItem::MouseEvent(event); - return event.at0 != kMenuEventNone; -} - -CGameMenuItemSlider::CGameMenuItemSlider() -{ - m_pzText = NULL; - m_nFont = -1; - m_nX = 0; - m_nY = 0; - nValue = 0; - nRangeLow = 0; - nStep = 0; - pCallback = NULL; - pValue = NULL; - nSliderTile = 2204; - nCursorTile = 2028; - nShowValue = kMenuSliderNone; -} - -CGameMenuItemSlider::CGameMenuItemSlider(const char *_pzText, int _nFont, int _nX, int _nY, int _nWidth, int _nValue, int _nRangeLow, int _nRangeHigh, int _nStep, void(*_pCallback)(CGameMenuItemSlider *), int _nSliderTile, int _nCursorTile, int _nShowValue) -{ - m_pzText = _pzText; - m_nFont = _nFont; - m_nX = _nX; - m_nY = _nY; - m_nWidth = _nWidth; - nRangeLow = _nRangeLow; - nRangeHigh = _nRangeHigh; - nStep = _nStep; - nValue = ClipRange(_nValue, nRangeLow, nRangeHigh); - pCallback = _pCallback; - nSliderTile = 2204; - nCursorTile = 2028; - if (_nSliderTile >= 0) - nSliderTile = _nSliderTile; - if (_nCursorTile >= 0) - nCursorTile = _nCursorTile; - nShowValue = _nShowValue; -} - -CGameMenuItemSlider::CGameMenuItemSlider(const char *_pzText, int _nFont, int _nX, int _nY, int _nWidth, int *pnValue, int _nRangeLow, int _nRangeHigh, int _nStep, void(*_pCallback)(CGameMenuItemSlider *), int _nSliderTile, int _nCursorTile, int _nShowValue) -{ - m_pzText = _pzText; - m_nFont = _nFont; - m_nX = _nX; - m_nY = _nY; - m_nWidth = _nWidth; - nRangeLow = _nRangeLow; - nRangeHigh = _nRangeHigh; - nStep = _nStep; - dassert(pnValue != NULL); - pValue = pnValue; - nValue = ClipRange(*pnValue, nRangeLow, nRangeHigh); - pCallback = _pCallback; - nSliderTile = 2204; - nCursorTile = 2028; - if (_nSliderTile >= 0) - nSliderTile = _nSliderTile; - if (_nCursorTile >= 0) - nCursorTile = _nCursorTile; - nShowValue = _nShowValue; -} - -void CGameMenuItemSlider::Draw(void) -{ - char buffer[16]; - int height; - nValue = pValue ? *pValue : nValue; - gMenuTextMgr.GetFontInfo(m_nFont, NULL, NULL, &height); - int shade = bEnable ? 32 : 48; - int shade2 = bEnable ? 0 : 16; - int pal = bEnable ? 0 : 5; - if (pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - if (m_pzText) - gMenuTextMgr.DrawText(m_pzText, m_nFont, m_nX, m_nY, shade, pal, false); - int sliderX = m_nX+m_nWidth-1-tilesiz[nSliderTile].x/2; - rotatesprite(sliderX<<16, (m_nY+height/2)<<16, 65536, 0, nSliderTile, shade2, pal, 10, 0, 0, xdim-1, ydim-1); - int nRange = nRangeHigh - nRangeLow; - dassert(nRange > 0); - int value = nValue - nRangeLow; - int width = tilesiz[nSliderTile].x-8; - int cursorX = sliderX + ksgn(nStep)*(value * width / nRange - width / 2); - rotatesprite(cursorX<<16, (m_nY+height/2)<<16, 65536, 0, nCursorTile, shade2, pal, 10, 0, 0, xdim-1, ydim-1); - - buffer[0] = 0; - switch (nShowValue) - { - case kMenuSliderNone: - break; - case kMenuSliderValue: - sprintf(buffer, "%i ", nValue); - break; - case kMenuSliderPercent: - sprintf(buffer, "%i%% ", roundscale(value, 100, nRange)); - break; - case kMenuSliderQ16: - snprintf(buffer, 16, "%.3f ", nValue/65536.f); - break; - } - int valueWidth; - gMenuTextMgr.GetFontInfo(m_nFont, buffer, &valueWidth, NULL); - int valueX = m_nX+m_nWidth-1-tilesiz[nSliderTile].x-valueWidth; - gMenuTextMgr.DrawText(buffer, m_nFont, valueX, m_nY, 32, 0, false); - - int mx = m_nX; - int my = m_nY; - int mw = m_nWidth; - int mh = height; - if (height < tilesiz[nSliderTile].y) - { - my -= (tilesiz[nSliderTile].y-height)/2; - height = tilesiz[nSliderTile].y; - } - mx <<= 16; - my <<= 16; - mw <<= 16; - mh <<= 16; - - if (bEnable && MOUSEACTIVECONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousepos, mx, my, mw, mh))) - { - if (MOUSEWATCHPOINTCONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_prevmousepos, mx, my, mw, mh))) - { - pMenu->SetFocusItem(this); - } - - if (!gGameMenuMgr.m_mousecaught && (inputState.mouseClickState() == MOUSE_PRESSED || inputState.mouseClickState() == MOUSE_HELD)) - { - pMenu->SetFocusItem(this); - - int sliderx = m_nX+m_nWidth-1-tilesiz[nSliderTile].x; - int sliderwidth = tilesiz[nSliderTile].x; - int regionwidth = sliderwidth-8; - int regionx = sliderx+(sliderwidth-regionwidth)/2; - sliderx <<= 16; - sliderwidth <<= 16; - regionwidth <<= 16; - regionx <<= 16; - - // region between the x-midline of the slidepoint at the extremes slides proportionally - if (!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousepos, regionx, my, regionwidth, mh)) - { - int dx = (gGameMenuMgr.m_mousepos.x - (regionx+regionwidth/2))*ksgn(nStep); - nValue = nRangeLow + roundscale(dx+regionwidth/2, nRange, regionwidth); - nValue = ClipRange(nValue, nRangeLow, nRangeHigh); - if (pCallback) - pCallback(this); - gGameMenuMgr.m_mousecaught = 1; - } - // region outside the x-midlines clamps to the extremes - else if (!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousepos, sliderx, my, sliderwidth, mh)) - { - if ((gGameMenuMgr.m_mousepos.x-(regionx+regionwidth/2))*ksgn(nStep) > 0) - nValue = nRangeHigh; - else - nValue = nRangeLow; - if (pCallback) - pCallback(this); - gGameMenuMgr.m_mousecaught = 1; - } - } - } -} - -bool CGameMenuItemSlider::Event(CGameMenuEvent &event) -{ - nValue = pValue ? *pValue : nValue; - switch (event.at0) - { - case kMenuEventUp: - pMenu->FocusPrevItem(); - return false; - case kMenuEventDown: - pMenu->FocusNextItem(); - return false; - case kMenuEventLeft: - if (nStep > 0) - nValue = DecBy(nValue, nStep); - else - nValue = IncBy(nValue, -nStep); - nValue = ClipRange(nValue, nRangeLow, nRangeHigh); - if (pCallback) - pCallback(this); - return false; - case kMenuEventRight: - if (nStep >= 0) - nValue = IncBy(nValue, nStep); - else - nValue = DecBy(nValue, -nStep); - nValue = ClipRange(nValue, nRangeLow, nRangeHigh); - if (pCallback) - pCallback(this); - return false; - case kMenuEventEnter: - if (pCallback) - pCallback(this); - return false; - } - return CGameMenuItem::Event(event); -} - -bool CGameMenuItemSlider::MouseEvent(CGameMenuEvent &event) -{ - event.at0 = kMenuEventNone; - if (MOUSEINACTIVECONDITIONAL((inputState.MouseGetButtons()&LEFT_MOUSE) && (inputState.MouseGetButtons()&WHEELUP_MOUSE))) - { - inputState.MouseClearButton(WHEELUP_MOUSE); - event.at0 = kMenuEventLeft; - } - else if (MOUSEINACTIVECONDITIONAL((inputState.MouseGetButtons()&LEFT_MOUSE) && (inputState.MouseGetButtons()&WHEELDOWN_MOUSE))) - { - inputState.MouseClearButton(WHEELDOWN_MOUSE); - event.at0 = kMenuEventRight; - } - else if (inputState.MouseGetButtons()&RIGHT_MOUSE) - { - inputState.MouseClearButton(RIGHT_MOUSE); - event.at0 = kMenuEventEscape; - } - else if (inputState.MouseGetButtons()&WHEELUP_MOUSE) - { - inputState.MouseClearButton(WHEELUP_MOUSE); - inputState.MouseClearButton(LEFT_MOUSE); - event.at0 = kMenuEventUp; - } - else if (inputState.MouseGetButtons()&WHEELDOWN_MOUSE) - { - inputState.MouseClearButton(WHEELDOWN_MOUSE); - inputState.MouseClearButton(LEFT_MOUSE); - event.at0 = kMenuEventDown; - } - return event.at0 != kMenuEventNone; -} - -CGameMenuItemSliderFloat::CGameMenuItemSliderFloat() -{ - m_pzText = NULL; - m_nFont = -1; - m_nX = 0; - m_nY = 0; - fValue = 0; - fRangeLow = 0; - fStep = 0; - pCallback = NULL; - pValue = NULL; - nSliderTile = 2204; - nCursorTile = 2028; - nShowValue = kMenuSliderNone; -} - -CGameMenuItemSliderFloat::CGameMenuItemSliderFloat(const char *_pzText, int _nFont, int _nX, int _nY, int _nWidth, float _fValue, float _fRangeLow, float _fRangeHigh, float _fStep, void(*_pCallback)(CGameMenuItemSliderFloat *), int _nSliderTile, int _nCursorTile, int _nShowValue) -{ - m_pzText = _pzText; - m_nFont = _nFont; - m_nX = _nX; - m_nY = _nY; - m_nWidth = _nWidth; - fRangeLow = _fRangeLow; - fRangeHigh = _fRangeHigh; - fStep = _fStep; - fValue = ClipRangeF(_fValue, fRangeLow, fRangeHigh); - pCallback = _pCallback; - nSliderTile = 2204; - nCursorTile = 2028; - if (_nSliderTile >= 0) - nSliderTile = _nSliderTile; - if (_nCursorTile >= 0) - nCursorTile = _nCursorTile; - nShowValue = _nShowValue; -} - -CGameMenuItemSliderFloat::CGameMenuItemSliderFloat(const char *_pzText, int _nFont, int _nX, int _nY, int _nWidth, float *pnValue, float _fRangeLow, float _fRangeHigh, float _fStep, void(*_pCallback)(CGameMenuItemSliderFloat *), int _nSliderTile, int _nCursorTile, int _nShowValue) -{ - m_pzText = _pzText; - m_nFont = _nFont; - m_nX = _nX; - m_nY = _nY; - m_nWidth = _nWidth; - fRangeLow = _fRangeLow; - fRangeHigh = _fRangeHigh; - fStep = _fStep; - dassert(pnValue != NULL); - pValue = pnValue; - fValue = ClipRangeF(*pnValue, fRangeLow, fRangeHigh); - pCallback = _pCallback; - nSliderTile = 2204; - nCursorTile = 2028; - if (_nSliderTile >= 0) - nSliderTile = _nSliderTile; - if (_nCursorTile >= 0) - nCursorTile = _nCursorTile; - nShowValue = _nShowValue; -} - -void CGameMenuItemSliderFloat::Draw(void) -{ - char buffer[16]; - int height; - - fValue = pValue ? *pValue : fValue; - gMenuTextMgr.GetFontInfo(m_nFont, NULL, NULL, &height); - int shade = bEnable ? 32 : 48; - int shade2 = bEnable ? 0 : 16; - int pal = bEnable ? 0 : 5; - if (pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - if (m_pzText) - gMenuTextMgr.DrawText(m_pzText, m_nFont, m_nX, m_nY, shade, pal, false); - int sliderX = m_nX+m_nWidth-1-tilesiz[nSliderTile].x/2; - rotatesprite(sliderX<<16, (m_nY+height/2)<<16, 65536, 0, nSliderTile, shade2, pal, 10, 0, 0, xdim-1, ydim-1); - float fRange = fRangeHigh - fRangeLow; - dassert(fRange > 0); - float value = fValue - fRangeLow; - int width = tilesiz[nSliderTile].x-8; - int cursorX = sliderX + (int)(ksgnf(fStep)*(value * width / fRange - width / 2)); - rotatesprite(cursorX<<16, (m_nY+height/2)<<16, 65536, 0, nCursorTile, shade2, pal, 10, 0, 0, xdim-1, ydim-1); - - buffer[0] = 0; - switch (nShowValue) - { - case kMenuSliderNone: - break; - case kMenuSliderValue: - snprintf(buffer, 16, "%.3f ", fValue); - break; - case kMenuSliderPercent: - snprintf(buffer, 16, "%.3f%% ", value*100.f/fRange); - break; - } - int valueWidth; - gMenuTextMgr.GetFontInfo(m_nFont, buffer, &valueWidth, NULL); - int valueX = m_nX+m_nWidth-1-tilesiz[nSliderTile].x-valueWidth; - gMenuTextMgr.DrawText(buffer, m_nFont, valueX, m_nY, 32, 0, false); - - int mx = m_nX; - int my = m_nY; - int mw = m_nWidth; - int mh = height; - if (height < tilesiz[nSliderTile].y) - { - my -= (tilesiz[nSliderTile].y-height)/2; - height = tilesiz[nSliderTile].y; - } - mx <<= 16; - my <<= 16; - mw <<= 16; - mh <<= 16; - - if (bEnable && MOUSEACTIVECONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousepos, mx, my, mw, mh))) - { - if (MOUSEWATCHPOINTCONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_prevmousepos, mx, my, mw, mh))) - { - pMenu->SetFocusItem(this); - } - - if (!gGameMenuMgr.m_mousecaught && (inputState.mouseClickState() == MOUSE_PRESSED || inputState.mouseClickState() == MOUSE_HELD)) - { - pMenu->SetFocusItem(this); - - int sliderx = m_nX+m_nWidth-1-tilesiz[nSliderTile].x; - int sliderwidth = tilesiz[nSliderTile].x; - int regionwidth = sliderwidth-8; - int regionx = sliderx+(sliderwidth-regionwidth)/2; - sliderx <<= 16; - sliderwidth <<= 16; - regionwidth <<= 16; - regionx <<= 16; - - // region between the x-midline of the slidepoint at the extremes slides proportionally - if (!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousepos, regionx, my, regionwidth, mh)) - { - int dx = (gGameMenuMgr.m_mousepos.x - (regionx+regionwidth/2))*ksgnf(fStep); - fValue = fRangeLow + (dx+regionwidth/2) * fRange / regionwidth; - fValue = ClipRangeF(fValue, fRangeLow, fRangeHigh); - if (pCallback) - pCallback(this); - gGameMenuMgr.m_mousecaught = 1; - } - // region outside the x-midlines clamps to the extremes - else if (!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousepos, sliderx, my, sliderwidth, mh)) - { - if ((gGameMenuMgr.m_mousepos.x-(regionx+regionwidth/2))*ksgnf(fStep) > 0) - fValue = fRangeHigh; - else - fValue = fRangeLow; - if (pCallback) - pCallback(this); - gGameMenuMgr.m_mousecaught = 1; - } - } - } -} - -bool CGameMenuItemSliderFloat::Event(CGameMenuEvent &event) -{ - fValue = pValue ? *pValue : fValue; - switch (event.at0) - { - case kMenuEventUp: - pMenu->FocusPrevItem(); - return false; - case kMenuEventDown: - pMenu->FocusNextItem(); - return false; - case kMenuEventLeft: - if (fStep > 0) - fValue -= fStep; - else - fValue += fStep; - fValue = ClipRangeF(fValue, fRangeLow, fRangeHigh); - if (pCallback) - pCallback(this); - return false; - case kMenuEventRight: - if (fStep >= 0) - fValue += fStep; - else - fValue -= fStep; - fValue = ClipRangeF(fValue, fRangeLow, fRangeHigh); - if (pCallback) - pCallback(this); - return false; - case kMenuEventEnter: - if (pCallback) - pCallback(this); - return false; - } - return CGameMenuItem::Event(event); -} - -CGameMenuItemZEdit::CGameMenuItemZEdit() -{ - m_pzText = NULL; - m_nFont = -1; - m_nX = 0; - m_nY = 0; - at20 = NULL; - at24 = 0; - at32 = 0; - at2c = 0; - at30 = 0; - at28 = 0; - at31 = 1; -} - -CGameMenuItemZEdit::CGameMenuItemZEdit(const char *a1, int a2, int a3, int a4, int a5, char *a6, int a7, char a8, void(*a9)(CGameMenuItemZEdit *, CGameMenuEvent *), int a10) -{ - at30 = 0; - at31 = 1; - m_pzText = a1; - m_nFont = a2; - m_nX = a3; - m_nY = a4; - m_nWidth = a5; - at20 = a6; - at24 = a7; - at32 = a8; - at2c = a9; - at28 = a10; -} - -void CGameMenuItemZEdit::AddChar(char ch) -{ - int i = strlen(at20); - if (i + 1 < at24) - { - at20[i] = ch; - at20[i + 1] = 0; - } -} - -void CGameMenuItemZEdit::BackChar(void) -{ - int i = strlen(at20); - if (i > 0) - at20[i - 1] = 0; -} - -void CGameMenuItemZEdit::Draw(void) -{ - int height, width, textWidth = 0; - gMenuTextMgr.GetFontInfo(m_nFont, NULL, &width, &height); - if (at20) - gMenuTextMgr.GetFontInfo(m_nFont, at20, &textWidth, NULL); - int shade = bEnable ? 32 : 48; - int pal = bEnable ? 0 : 5; - if (pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - if (at30) - shade = -128; - if (m_pzText) - gMenuTextMgr.DrawText(m_pzText, m_nFont, m_nX, m_nY, shade, pal, false); - int x = m_nX+m_nWidth-1-textWidth;//(at24+1)*width; - if (at20 && *at20) - { - int width; - gMenuTextMgr.GetFontInfo(m_nFont, at20, &width, NULL); - int shade2; - if (at32) - { - if (at30) - shade2 = -128; - else - shade2 = shade; - } - else - { - if (at30) - shade2 = shade; - else - shade2 = 32; - } - gMenuTextMgr.DrawText(at20, m_nFont, x, m_nY, shade2, pal, false); - x += width; - } - if (at30 && ((int)totalclock & 32)) - gMenuTextMgr.DrawText("_", m_nFont, x, m_nY, shade, 0, false); - - int mx = m_nX<<16; - int my = m_nY<<16; - int mw = m_nWidth<<16; - int mh = height<<16; - - if (bEnable && MOUSEACTIVECONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousepos, mx, my, mw, mh))) - { - if (MOUSEWATCHPOINTCONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_prevmousepos, mx, my, mw, mh))) - { - pMenu->SetFocusItem(this); - } - - if (!gGameMenuMgr.m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousedownpos, mx, my, mw, mh)) - { - pMenu->SetFocusItem(this); - - CGameMenuEvent event = { kMenuEventEnter, 0 }; - - gGameMenuMgr.m_mousecaught = 1; - - if (Event(event)) - gGameMenuMgr.PostPop(); - } - } -} - -bool CGameMenuItemZEdit::Event(CGameMenuEvent &event) -{ - static char buffer[256]; - // Hack - if (event.at2 == sc_kpad_2 || event.at2 == sc_kpad_4 || event.at2 == sc_kpad_6 || event.at2 == sc_kpad_8) - event.at0 = kMenuEventKey; - switch (event.at0) - { - case kMenuEventEscape: - if (at30) - { - strncpy(at20, buffer, at24); - at20[at24-1] = 0; - at30 = 0; - return false; - } - return true; - case kMenuEventEnter: - if (!at31) - { - if (at2c) - at2c(this, &event); - return false; - } - if (at30) - { - if (at2c) - at2c(this, &event); - at30 = 0; - return false; - } - strncpy(buffer, at20, at24); - buffer[at24-1] = 0; - at30 = 1; - return false; - case kMenuEventBackSpace: - if (at30) - BackChar(); - return false; - case kMenuEventKey: - case kMenuEventSpace: - { - char key; - if (event.at2 < 128) - { - if (inputState.ShiftPressed()) - key = g_keyAsciiTableShift[event.at2]; - else - key = g_keyAsciiTable[event.at2]; - if (at30 && (isalnum(key) || ispunct(key) || isspace(key))) - { - AddChar(key); - return false; - } - } - return CGameMenuItem::Event(event); - } - case kMenuEventUp: - if (at30) - return false; - return CGameMenuItem::Event(event); - case kMenuEventDown: - if (at30) - return false; - return CGameMenuItem::Event(event); - } - return CGameMenuItem::Event(event); -} - -CGameMenuItemZEditBitmap::CGameMenuItemZEditBitmap() -{ - m_pzText = NULL; - m_nFont = -1; - m_nX = 0; - m_nY = 0; - at20 = NULL; - at24 = 0; - at36 = 0; - at30 = NULL; - at2c = NULL; - bScan = 0; - at28 = 0; - at37 = 0; - at35 = 1; -} - -CGameMenuItemZEditBitmap::CGameMenuItemZEditBitmap(char *a1, int a2, int a3, int a4, int a5, char *a6, int a7, char a8, void(*a9)(CGameMenuItemZEditBitmap *, CGameMenuEvent *), int a10) -{ - at2c = NULL; - bScan = 0; - at35 = 1; - at37 = 0; - m_pzText = a1; - m_nFont = a2; - m_nX = a3; - m_nY = a4; - m_nWidth = a5; - at20 = a6; - at24 = a7; - at36 = a8; - at30 = a9; - at28 = a10; -} - -void CGameMenuItemZEditBitmap::AddChar(char ch) -{ - int i = strlen(at20); - if (i + 1 < at24) - { - at20[i] = ch; - at20[i + 1] = 0; - } -} - -void CGameMenuItemZEditBitmap::BackChar(void) -{ - int i = strlen(at20); - if (i > 0) - at20[i - 1] = 0; -} - -void CGameMenuItemZEditBitmap::Draw(void) -{ - int height, width; - gMenuTextMgr.GetFontInfo(m_nFont, NULL, &width, &height); - int shade = bEnable ? 32 : 48; - int pal = bEnable ? 0 : 5; - if (pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - at2c->at24 = -1; - if (bScan) - shade = -128; - if (m_pzText) - gMenuTextMgr.DrawText(m_pzText, m_nFont, m_nX, m_nY, shade, pal, false); - int x = m_nX+m_nWidth-1-(at24+1)*width; - if (at20 && *at20) - { - int width; - gMenuTextMgr.GetFontInfo(m_nFont, at20, &width, NULL); - int shade2; - if (at36) - { - if (bScan) - shade2 = -128; - else - shade2 = shade; - } - else - { - if (bScan) - shade2 = shade; - else - shade2 = 32; - } - gMenuTextMgr.DrawText(at20, m_nFont, x, m_nY, shade2, 0, false); - x += width; - } - if (bScan && ((int)totalclock & 32)) - gMenuTextMgr.DrawText("_", m_nFont, x, m_nY, shade, pal, false); - - int mx = m_nX<<16; - int my = m_nY<<16; - int mw = m_nWidth<<16; - int mh = height<<16; - - if (!gGameMenuMgr.m_bScanning && bEnable && MOUSEACTIVECONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousepos, mx, my, mw, mh))) - { - if (MOUSEWATCHPOINTCONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_prevmousepos, mx, my, mw, mh))) - { - pMenu->SetFocusItem(this); - } - - if (!gGameMenuMgr.m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousedownpos, mx, my, mw, mh)) - { - pMenu->SetFocusItem(this); - - CGameMenuEvent event = { kMenuEventEnter, 0 }; - - gGameMenuMgr.m_mousecaught = 1; - - if (Event(event)) - gGameMenuMgr.PostPop(); - } - } -} - -bool CGameMenuItemZEditBitmap::Event(CGameMenuEvent &event) -{ - static char buffer[256]; - // Hack - if (event.at2 == sc_kpad_2 || event.at2 == sc_kpad_4 || event.at2 == sc_kpad_6 || event.at2 == sc_kpad_8) - event.at0 = kMenuEventKey; - switch (event.at0) - { - case kMenuEventEscape: - if (bScan) - { - strncpy(at20, buffer, at24); - at20[at24-1] = 0; - bScan = 0; - gGameMenuMgr.m_bScanning = false; - gSaveGameActive = false; - return false; - } - gSaveGameActive = true; - return true; - case kMenuEventEnter: - if (!at35 || bScan) - { - if (at30) - at30(this, &event); - if (bScan) - { - bScan = 0; - gGameMenuMgr.m_bScanning = false; - } - gSaveGameActive = false; - inputState.ClearKeyStatus(sc_Enter); - inputState.ClearKeyStatus(sc_kpad_Enter); - return false; - } - strncpy(buffer, at20, at24); - if (at37) - at20[0] = 0; - buffer[at24-1] = 0; - bScan = 1; - gGameMenuMgr.m_bScanning = true; - return false; - case kMenuEventBackSpace: - if (bScan) - BackChar(); - return false; - case kMenuEventKey: - case kMenuEventSpace: - { - char key; - if (bScan && event.at2 < 128) - { - if (inputState.ShiftPressed()) - key = g_keyAsciiTableShift[event.at2]; - else - key = g_keyAsciiTable[event.at2]; - if (at30 && (isalnum(key) || ispunct(key) || isspace(key))) - { - AddChar(key); - return false; - } - } - return CGameMenuItem::Event(event); - } - case kMenuEventUp: - if (bScan) - return false; - return CGameMenuItem::Event(event); - case kMenuEventDown: - if (bScan) - return false; - return CGameMenuItem::Event(event); - } - return CGameMenuItem::Event(event); -} - -CGameMenuItemQAV::CGameMenuItemQAV() -{ - at20 = NULL; - at24 = NULL; - at28 = 0; - bEnable = 0; -} - -CGameMenuItemQAV::CGameMenuItemQAV(const char *a1, int a2, int a3, int a4, const char *a5, bool widescreen, bool clearbackground) -{ - m_nWidth = 0; - m_pzText = a1; - m_nFont = a2; - m_nY = a4; - at20 = a5; - m_nX = a3; - bEnable = 0; - bWideScreen = widescreen; - bClearBackground = clearbackground; -} - -void CGameMenuItemQAV::Draw(void) -{ - if (bClearBackground) - videoClearScreen(0); - if (at24) - { - ClockTicks backFC = gFrameClock; - gFrameClock = totalclock; - int nTicks = (int)totalclock - at30; - at30 = (int)totalclock; - at2c -= nTicks; - if (at2c <= 0 || at2c > at28->at10) - { - at2c = at28->at10; - } - at28->Play(at28->at10 - at2c - nTicks, at28->at10 - at2c, -1, NULL); - int wx1, wy1, wx2, wy2; - wx1 = windowxy1.x; - wy1 = windowxy1.y; - wx2 = windowxy2.x; - wy2 = windowxy2.y; - windowxy1.x = 0; - windowxy1.y = 0; - windowxy2.x = xdim-1; - windowxy2.y = ydim-1; - if (bWideScreen) - { - int xdim43 = scale(ydim, 4, 3); - int nCount = (xdim+xdim43-1)/xdim43; - int backX = at28->x; - for (int i = 0; i < nCount; i++) - { - at28->Draw(at28->at10 - at2c, 10+kQavOrientationLeft, 0, 0); - at28->x += 320; - } - at28->x = backX; - } - else - at28->Draw(at28->at10 - at2c, 10, 0, 0); - - windowxy1.x = wx1; - windowxy1.y = wy1; - windowxy2.x = wx2; - windowxy2.y = wy2; - gFrameClock = backFC; - } - - if (bEnable && !gGameMenuMgr.m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED) - { - pMenu->SetFocusItem(this); - - CGameMenuEvent event = { kMenuEventEnter, 0 }; - - gGameMenuMgr.m_mousecaught = 1; - - if (Event(event)) - gGameMenuMgr.PostPop(); - } -} - -bool CGameMenuItemQAV::Event(CGameMenuEvent &event) -{ - switch (event.at0) - { - case kMenuEventLeft: - case kMenuEventBackSpace: - pMenu->FocusPrevItem(); - return false; - case kMenuEventRight: - case kMenuEventEnter: - case kMenuEventSpace: - pMenu->FocusNextItem(); - return false; - case kMenuEventInit: - return false; - } - return CGameMenuItem::Event(event); -} - -void CGameMenuItemQAV::Reset(void) -{ - at2c = at28->at10; - at30 = (int)totalclock; -} - -CGameMenuItemZCycleSelect::CGameMenuItemZCycleSelect() -{ - m_pzText = NULL; - m_nFont = 3; - m_nX = 0; - m_nY = 0; - m_nRows = 0; - m_nTopDelta = 0; - m_nFocus = 0; - m_nItems = 0; - m_pzStrings = NULL; - m_pReturn = NULL; -} - -CGameMenuItemZCycleSelect::CGameMenuItemZCycleSelect(const char *pzText, int nFont, int nX, int nY, int nWidth, int nRows, int nItems, const char **pzStrings, int *pReturn, void(*pCallback)(CGameMenuItemZCycleSelect *)) -{ - m_nTopDelta = 0; - m_nFocus = 0; - m_pzText = pzText; - m_nFont = nFont; - m_nX = nX; - m_nY = nY; - m_nWidth = nWidth; - m_nRows = nRows; - m_pCallback = pCallback; - m_nItems = nItems; - m_pzStrings = pzStrings; - m_pReturn = pReturn; -} - -void CGameMenuItemZCycleSelect::Draw(void) -{ - int height; - int shade; - gMenuTextMgr.GetFontInfo(m_nFont, NULL, NULL, &height); - int y = m_nY; - int k = m_nFocus - m_nTopDelta; - int nNewFocus = m_nFocus; - bool bClick = false; - for (int i = 0; i < m_nRows; i++, y += height, k++) - { - if (k == m_nFocus) - { - shade = 32; - if (pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - viewDrawText(3, m_pzStrings[k], m_nX, y, shade, 0, 0, false); - } - else - { - viewDrawText(3, m_pzStrings[k], m_nX, y, 24, 0, 0, false); - } - int mx = m_nX<<16; - int my = y<<16; - int mw = m_nWidth<<16; - int mh = height<<16; - if (bEnable && MOUSEACTIVECONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousepos, mx, my, mw, mh))) - { - if (MOUSEWATCHPOINTCONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_prevmousepos, mx, my, mw, mh))) - { - nNewFocus = k; - } - - if (!gGameMenuMgr.m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousedownpos, mx, my, mw, mh)) - { - nNewFocus = k; - bClick = true; - } - } - } - m_nTopDelta += nNewFocus-m_nFocus; - m_nFocus = nNewFocus; - if (bClick) - { - CGameMenuEvent event = { kMenuEventEnter, 0 }; - - gGameMenuMgr.m_mousecaught = 1; - - if (Event(event)) - gGameMenuMgr.PostPop(); - } -} - -bool CGameMenuItemZCycleSelect::Event(CGameMenuEvent &event) -{ - switch (event.at0) - { - case kMenuEventUp: - if (event.at2 == sc_Tab || m_nFocus == 0) - { - pMenu->FocusPrevItem(); - return false; - } - m_nFocus--; - if (m_nTopDelta > 0) - m_nTopDelta--; - return false; - case kMenuEventDown: - if (event.at2 == sc_Tab || m_nFocus == m_nItems-1) - { - pMenu->FocusNextItem(); - return false; - } - m_nFocus++; - if (m_nTopDelta+1 < m_nRows) - m_nTopDelta++; - return false; - case kMenuEventEnter: - if (m_pCallback) - m_pCallback(this); - *m_pReturn = m_nFocus; - return true; - case kMenuEventScrollUp: - if (m_nFocus-m_nTopDelta > 0) - { - m_nTopDelta++; - if (m_nTopDelta>0) - { - m_nFocus--; - m_nTopDelta--; - } - } - return false; - case kMenuEventScrollDown: - if (m_nFocus-m_nTopDelta+m_nRows < m_nItems) - { - m_nTopDelta--; - if (m_nTopDelta+1 < m_nRows) - { - m_nFocus++; - m_nTopDelta++; - } - } - return false; - } - return CGameMenuItem::Event(event); -} - -bool CGameMenuItemZCycleSelect::MouseEvent(CGameMenuEvent &event) -{ - event.at0 = kMenuEventNone; - if (MOUSEACTIVECONDITIONAL(inputState.MouseGetButtons()&WHEELUP_MOUSE)) - { - gGameMenuMgr.m_mouselastactivity = (int)totalclock; - inputState.MouseClearButton(WHEELUP_MOUSE); - event.at0 = kMenuEventScrollUp; - } - else if (MOUSEACTIVECONDITIONAL(inputState.MouseGetButtons()&WHEELDOWN_MOUSE)) - { - gGameMenuMgr.m_mouselastactivity = (int)totalclock; - inputState.MouseClearButton(WHEELDOWN_MOUSE); - event.at0 = kMenuEventScrollDown; - } - else - return CGameMenuItem::MouseEvent(event); - return event.at0 != kMenuEventNone; -} - -CGameMenuItemZCycle::CGameMenuItemZCycle() -{ - m_pzText = NULL; - m_nFocus = 0; - m_nItems = 0; - m_pCallback = NULL; - m_pCallbackSelect = NULL; - m_pMenuSelect = NULL; - m_pItemSelectTitle = NULL; - m_pItemSelect = NULL; - m_nMenuSelectReturn = -1; -} - -CGameMenuItemZCycle::CGameMenuItemZCycle(const char *a1, int a2, int a3, int a4, int a5, int a6, void(*a7)(CGameMenuItemZCycle *), const char **a8, int a9, int a10, bool bMenu, void(*pCallbackSelect)(CGameMenuItemZCycleSelect*)) -{ - m_pzText = a1; - m_nFont = a2; - m_nX = a3; - m_nY = a4; - m_nFocus = 0; - m_nWidth = a5; - m_nAlign = a6; - m_pCallback = a7; - m_pCallbackSelect = pCallbackSelect; - m_nItems = 0; - m_bMenu = bMenu; - m_pMenuSelect = NULL; - m_pItemSelectTitle = NULL; - m_pItemSelect = NULL; - m_nMenuSelectReturn = -1; - SetTextArray(a8, a9, a10); -} - -CGameMenuItemZCycle::~CGameMenuItemZCycle() -{ - m_pzText = NULL; - m_nFocus = 0; - m_nItems = 0; - m_pCallback = NULL; - m_pCallbackSelect = NULL; - m_pMenuSelect = NULL; - m_pItemSelectTitle = NULL; - m_pItemSelect = NULL; - m_nMenuSelectReturn = -1; - memset(m_pzStrings, 0, sizeof(m_pzStrings)); -} - -void CGameMenuItemZCycle::Draw(void) -{ - int width = 0, height = 0; - int shade = bEnable ? 32 : 48; - int pal = bEnable ? 0 : 5; - if (pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - int x = m_nX; - int y = m_nY; - - if (m_nMenuSelectReturn != -1) - { - m_nFocus = m_nMenuSelectReturn; - if (m_pCallback) - m_pCallback(this); - m_nMenuSelectReturn = -1; - } - - if (m_pzText) - { - gMenuTextMgr.GetFontInfo(m_nFont, m_pzText, &width, &height); - switch (m_nAlign) - { - case 1: - x = m_nX+m_nWidth/2-width/2; - break; - case 2: - x = m_nX+m_nWidth-1-width; - break; - case 0: - default: - break; - } - gMenuTextMgr.DrawText(m_pzText, m_nFont, x, y, shade, pal, false); - } - const char *pzText; - if (!m_nItems) - pzText = "????"; - else - pzText = m_pzStrings[m_nFocus]; - dassert(pzText != NULL); - gMenuTextMgr.GetFontInfo(m_nFont, pzText, &width, NULL); - gMenuTextMgr.DrawText(pzText, m_nFont, m_nX + m_nWidth - 1 - width, y, shade, pal, false); - if (bEnable && MOUSEACTIVECONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousepos, x<<16, y<<16, m_nWidth<<16, height<<16))) - { - if (MOUSEWATCHPOINTCONDITIONAL(!gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_prevmousepos, x<<16, y<<16, m_nWidth<<16, height<<16))) - { - pMenu->SetFocusItem(this); - } - - if (!gGameMenuMgr.m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED && !gGameMenuMgr.MouseOutsideBounds(&gGameMenuMgr.m_mousedownpos, x<<16, y<<16, m_nWidth<<16, height<<16)) - { - pMenu->SetFocusItem(this); - - CGameMenuEvent event = { kMenuEventEnter, 0 }; - - gGameMenuMgr.m_mousecaught = 1; - - if (Event(event)) - gGameMenuMgr.PostPop(); - } - } -} - -bool CGameMenuItemZCycle::Event(CGameMenuEvent &event) -{ - switch (event.at0) - { - case kMenuEventEnter: - if (m_bMenu) - { - if (m_pMenuSelect) - { - delete m_pMenuSelect; - m_pMenuSelect = NULL; - } - if (m_pItemSelectTitle) - { - delete m_pItemSelectTitle; - m_pItemSelectTitle = NULL; - } - if (m_pItemSelect) - { - delete m_pItemSelect; - m_pItemSelect = NULL; - } - m_pMenuSelect = new CGameMenu(); - dassert(m_pMenuSelect != NULL); - strncpy(m_zTitle, m_pzText, kMaxTitleLength); - int l = strlen(m_zTitle); - if (l > 0 && m_zTitle[l-1] == ':') - l--; - m_zTitle[l] = 0; - m_pItemSelectTitle = new CGameMenuItemTitle(m_zTitle, 1, 160, 20, 2038); - dassert(m_pItemSelectTitle != NULL); - m_pItemSelect = new CGameMenuItemZCycleSelect("", 3, 100, 40, 100, 16, m_nItems, m_pzStrings, &m_nMenuSelectReturn, m_pCallbackSelect); - dassert(m_pItemSelect != NULL); - m_pMenuSelect->Add(m_pItemSelectTitle, false); - m_pMenuSelect->Add(m_pItemSelect, true); - m_pMenuSelect->Add(&itemBloodQAV, false); - gGameMenuMgr.Push(m_pMenuSelect, -1); - return false; - } - fallthrough__; - case kMenuEventRight: - case kMenuEventSpace: - Next(); - if (m_pCallback) - m_pCallback(this); - return false; - case kMenuEventLeft: - Prev(); - if (m_pCallback) - m_pCallback(this); - return false; - case kMenuEventDeInit: - if (m_pMenuSelect) - { - delete m_pMenuSelect; - m_pMenuSelect = NULL; - } - if (m_pItemSelectTitle) - { - delete m_pItemSelectTitle; - m_pItemSelectTitle = NULL; - } - if (m_pItemSelect) - { - delete m_pItemSelect; - m_pItemSelect = NULL; - } - return false; - } - return CGameMenuItem::Event(event); -} - -void CGameMenuItemZCycle::Add(const char *pItem, bool active) -{ - dassert(pItem != NULL); - dassert(m_nItems < kMaxGameCycleItems); - m_pzStrings[m_nItems] = pItem; - if (active) - m_nFocus = m_nItems; - m_nItems++; -} - -void CGameMenuItemZCycle::Next(void) -{ - if (m_nItems > 0) - { - m_nFocus++; - if (m_nFocus >= m_nItems) - m_nFocus = 0; - } -} - -void CGameMenuItemZCycle::Prev(void) -{ - if (m_nItems > 0) - { - m_nFocus--; - if (m_nFocus < 0) - m_nFocus += m_nItems; - } -} - -void CGameMenuItemZCycle::Clear(void) -{ - m_nItems = m_nFocus = 0; - memset(m_pzStrings, 0, sizeof(m_pzStrings)); -} - -void CGameMenuItemZCycle::SetTextArray(const char **pTextArray, int nTextPtrCount, int nIndex) -{ - Clear(); - dassert(nTextPtrCount <= kMaxGameCycleItems); - for (int i = 0; i < nTextPtrCount; i++) - Add(pTextArray[i], false); - SetTextIndex(nIndex); -} - -void CGameMenuItemZCycle::SetTextIndex(int nIndex) -{ - m_nFocus = ClipRange(nIndex, 0, m_nItems); -} - -CGameMenuItemYesNoQuit::CGameMenuItemYesNoQuit() -{ - m_pzText = NULL; - m_nRestart = 0; -} - -CGameMenuItemYesNoQuit::CGameMenuItemYesNoQuit(const char *a1, int a2, int a3, int a4, int a5, int a6, int a7) -{ - m_pzText = a1; - m_nFont = a2; - m_nX = a3; - m_nY = a4; - m_nWidth = a5; - at20 = a6; - m_nRestart = a7; -} - -void CGameMenuItemYesNoQuit::Draw(void) -{ - if (!m_pzText) return; - int shade = 32; - if (pMenu->IsFocusItem(this)) - shade = 32-((int)totalclock&63); - int width; - int x = m_nX; - switch (at20) - { - case 1: - gMenuTextMgr.GetFontInfo(m_nFont, m_pzText, &width, NULL); - x = m_nX+m_nWidth/2-width/2; - break; - case 2: - gMenuTextMgr.GetFontInfo(m_nFont, m_pzText, &width, NULL); - x = m_nX+m_nWidth-1-width; - break; - case 0: - default: - break; - } - gMenuTextMgr.DrawText(m_pzText, m_nFont, x, m_nY, shade, 0, true); - - if (bEnable && !gGameMenuMgr.m_mousecaught && inputState.mouseClickState() == MOUSE_RELEASED) - { - pMenu->SetFocusItem(this); - - CGameMenuEvent event = { kMenuEventEnter, 0 }; - - gGameMenuMgr.m_mousecaught = 1; - - if (Event(event)) - gGameMenuMgr.PostPop(); - } -} - -extern void Restart(CGameMenuItemChain *pItem); -extern void Quit(CGameMenuItemChain *pItem); - -bool CGameMenuItemYesNoQuit::Event(CGameMenuEvent &event) -{ - switch (event.at0) - { - case kMenuEventKey: - if (event.at2 == sc_Y) - { - if (m_nRestart) - Restart(NULL); - else - Quit(NULL); - } - else if (event.at2 == sc_N) - gGameMenuMgr.Pop(); - return false; - case kMenuEventEnter: - if (m_nRestart) - Restart(NULL); - else - Quit(NULL); - return false; - } - return CGameMenuItem::Event(event); -} - -CGameMenuItemPicCycle::CGameMenuItemPicCycle() -{ - m_pzText = NULL; - at24 = 0; - m_nItems = 0; - atb0 = 0; - at2c = 0; - atb4 = 0; -} - -CGameMenuItemPicCycle::CGameMenuItemPicCycle(int a1, int a2, void(*a3)(CGameMenuItemPicCycle *), int *a4, int a5, int a6) -{ - m_nWidth = 0; - at24 = 0; - m_nItems = 0; - m_nX = a1; - m_nY = a2; - atb0 = a3; - atb4 = 0; - SetPicArray(a4, a5, a6); -} - -void CGameMenuItemPicCycle::Draw(void) -{ - videoSetViewableArea(0, 0, xdim - 1, ydim - 1); - if (atb4) - rotatesprite(0, 0, 65536, 0, atb4, 0, 0, 82, 0, 0, xdim - 1, ydim - 1); - if (at30[at24]) - rotatesprite(0, 0, 65536, 0, at30[at24], 0, 0, 82, 0, 0, xdim - 1, ydim - 1); -} - -bool CGameMenuItemPicCycle::Event(CGameMenuEvent &event) -{ - switch (event.at0) - { - case kMenuEventRight: - case kMenuEventEnter: - case kMenuEventSpace: - Next(); - if (atb0) - atb0(this); - return false; - case kMenuEventLeft: - Prev(); - if (atb0) - atb0(this); - return false; - } - return CGameMenuItem::Event(event); -} - -void CGameMenuItemPicCycle::Add(int nItem, bool active) -{ - dassert(m_nItems < kMaxPicCycleItems); - at30[m_nItems] = nItem; - if (active) - at24 = m_nItems; - m_nItems++; -} - -void CGameMenuItemPicCycle::Next(void) -{ - if (m_nItems > 0) - { - at24++; - if (at24 >= m_nItems) - at24 = 0; - } -} - -void CGameMenuItemPicCycle::Prev(void) -{ - if (m_nItems > 0) - { - at24--; - if (at24 < 0) - at24 += m_nItems; - } -} - -void CGameMenuItemPicCycle::Clear(void) -{ - m_nItems = at24 = 0; - memset(at30, 0, sizeof(at30)); - at2c = 0; -} - -void CGameMenuItemPicCycle::SetPicArray(int *pArray, int nTileCount, int nIndex) -{ - Clear(); - at2c = 0; - dassert(nTileCount <= kMaxPicCycleItems); - for (int i = 0; i < nTileCount; i++) - Add(pArray[i], false); - SetPicIndex(nIndex); -} - -void CGameMenuItemPicCycle::SetPicIndex(int nIndex) -{ - at24 = ClipRange(nIndex, 0, m_nItems); -} - -CGameMenuItemPassword::CGameMenuItemPassword() -{ - at37 = 0; - m_pzText = NULL; - at36 = 0; - at32 = 0; - at5b = 0; -} - -CGameMenuItemPassword::CGameMenuItemPassword(const char *a1, int a2, int a3, int a4) -{ - at37 = 0; - m_nWidth = 0; - at36 = 0; - at32 = 0; - at5b = 0; - m_pzText = a1; - m_nFont = a2; - m_nX = a3; - m_nY = a4; -} - -const char *kCheckPasswordMsg = "ENTER PASSWORD: "; -const char *kOldPasswordMsg = "ENTER OLD PASSWORD: "; -const char *kNewPasswordMsg = "ENTER NEW PASSWORD: "; -const char *kInvalidPasswordMsg = "INVALID PASSWORD."; - -void CGameMenuItemPassword::Draw(void) -{ - bool focus = pMenu->IsFocusItem(this); - int shade = 32; - int shadef = 32-((int)totalclock&63); - int width; - switch (at37) - { - case 1: - case 2: - case 3: - switch (at37) - { - case 1: - strcpy(at3b, kCheckPasswordMsg); - break; - case 2: - strcpy(at3b, kOldPasswordMsg); - break; - case 3: - strcpy(at3b, kNewPasswordMsg); - break; - } - for (int i = 0; i < at32; i++) - strcat(at3b, "*"); - strcat(at3b, "_"); - gMenuTextMgr.GetFontInfo(m_nFont, at3b, &width, NULL); - gMenuTextMgr.DrawText(at3b, m_nFont, m_nX-width/2, m_nY+20, shadef, 0, false); - shadef = 32; - break; - case 4: - if (((int)totalclock - at5b) & 32) - { - gMenuTextMgr.GetFontInfo(m_nFont, kInvalidPasswordMsg, &width, NULL); - gMenuTextMgr.DrawText(kInvalidPasswordMsg, m_nFont, m_nX - width / 2, m_nY + 20, shade, 0, false); - } - if (at5b && totalclock-at5b > 256) - { - at5b = 0; - at37 = 0; - } - break; - } - gMenuTextMgr.GetFontInfo(m_nFont, m_pzText, &width, NULL); - gMenuTextMgr.DrawText(m_pzText, m_nFont, m_nX-width/2, m_nY, focus ? shadef : shade, 0, false); -} - -bool CGameMenuItemPassword::Event(CGameMenuEvent &event) -{ - switch (at37) - { - case 0: - case 4: - if (event.at0 == kMenuEventEnter) - { - at29[0] = 0; - if (strcmp(at20, "")) - at37 = 2; - else - at37 = 3; - return false; - } - return CGameMenuItem::Event(event); - case 1: - case 2: - case 3: - switch (event.at0) - { - case kMenuEventEnter: - switch (at37) - { - case 1: - at36 = strcmp(at20,at29) == 0; - if (at36) - at37 = 0; - else - at37 = 4; - if (!at36) - { - at5b = (int)totalclock; - pMenu->FocusPrevItem(); - } - else - { - at5f->at20 = 0; - at5f->Draw(); - gbAdultContent = false; - // NUKE-TODO: - //CONFIG_WriteAdultMode(); - pMenu->FocusPrevItem(); - } - return false; - case 2: - at36 = strcmp(at20,at29) == 0; - if (at36) - at37 = 0; - else - at37 = 4; - if (at36) - { - strcpy(at20, ""); - strcpy(gzAdultPassword, ""); - // NUKE-TODO: - //CONFIG_WriteAdultMode(); - at37 = 0; - } - else - at5b = (int)totalclock; - return false; - case 3: - strcpy(at20, at29); - strcpy(at20, gzAdultPassword); - strcpy(gzAdultPassword, ""); - // NUKE-TODO: - //CONFIG_WriteAdultMode(); - at37 = 0; - return false; - } - break; - case kMenuEventEscape: - at37 = 0; - Draw(); - return false; - case kMenuEventKey: - if (at32 < 8) - { - char key = Btoupper(g_keyAsciiTable[event.at2]); - if (isalnum(key) || ispunct(key) || isspace(key)) - { - at29[at32++] = key; - at29[at32] = 0; - } - } - return false; - case kMenuEventBackSpace: - if (at32 > 0) - at29[--at32] = 0; - return false; - case kMenuEventLeft: - case kMenuEventRight: - case kMenuEventSpace: - return false; - } - } - return CGameMenuItem::Event(event); -} - -#endif END_BLD_NS diff --git a/source/blood/src/gamemenu.h b/source/blood/src/gamemenu.h index 25409acee..909d714c2 100644 --- a/source/blood/src/gamemenu.h +++ b/source/blood/src/gamemenu.h @@ -34,442 +34,4 @@ BEGIN_BLD_NS void drawLoadingScreen(void); void UpdateNetworkMenus(void); - -#if 0 - -#define M_MOUSETIMEOUT 210 - -#define kMaxGameMenuItems 128 -#define kMaxGameCycleItems 128 -#define kMaxPicCycleItems 128 -#define kMaxTitleLength 32 - -// alpha increments of 3 --> 255 / 3 = 85 --> round up to power of 2 --> 128 --> divide by 2 --> 64 alphatabs required -// use 16 anyway :P -#define MOUSEUSEALPHA (videoGetRenderMode() != REND_CLASSIC || numalphatabs >= 15) -#define MOUSEALPHA (MOUSEUSEALPHA ? clamp(((int)totalclock - gGameMenuMgr.m_mouselastactivity - 90)*3, 0, 255) : 0) -#define CURSORALPHA (MOUSEUSEALPHA ? clamp(((int)totalclock - gGameMenuMgr.m_mouselastactivity - 90)*2 + (255/3), (255/3), 255) : 255/3) -#define MOUSEACTIVECONDITION ((int)totalclock - gGameMenuMgr.m_mouselastactivity < M_MOUSETIMEOUT) -#define MOUSEACTIVECONDITIONAL(condition) (MOUSEACTIVECONDITION && (condition)) -#define MOUSEINACTIVECONDITIONAL(condition) (!MOUSEACTIVECONDITION && (condition)) -#define MOUSEWATCHPOINTCONDITIONAL(condition) ((condition) || gGameMenuMgr.m_mousewake_watchpoint || gGameMenuMgr.m_menuchange_watchpoint == 3) - -enum { - kMenuEventNone = 0, - kMenuEventKey = 1, - kMenuEventUp = 2, - kMenuEventDown = 3, - kMenuEventLeft = 4, - kMenuEventRight = 5, - kMenuEventEnter = 6, - kMenuEventEscape = 7, - kMenuEventSpace = 8, - kMenuEventBackSpace = 9, - kMenuEventDelete = 10, - kMenuEventScrollUp = 11, - kMenuEventScrollDown = 12, - - - kMenuEventInit = 0x8000, - kMenuEventDeInit = 0x8001 -}; - -enum { - kMenuSliderNone = 0, - kMenuSliderValue, - kMenuSliderPercent, - kMenuSliderQ16 -}; - -struct CGameMenuEvent { - unsigned short at0; - char at2; -}; - -// NUKE-TODO: -#ifdef DrawText -#undef DrawText -#endif - -class CGameMenu; - -class CGameMenuItem { -public: - CGameMenu *pMenu; - const char* m_pzText; - int m_nFont; - int m_nX; - int m_nY; - int m_nWidth; - void (*pPreDrawCallback)(CGameMenuItem *pItem); - //int nFlags; - unsigned int bCanSelect : 1; - unsigned int bEnable : 1; - unsigned int bNoDraw : 1; - CGameMenuItem(); - virtual ~CGameMenuItem(); - virtual void Draw(void) = 0; - virtual bool Event(CGameMenuEvent &); - virtual bool MouseEvent(CGameMenuEvent &); -}; - -class CGameMenuItemText : public CGameMenuItem -{ -public: - int at20; - CGameMenuItemText(); - CGameMenuItemText(const char *, int, int, int, int); - virtual void Draw(void); - //virtual bool Event(CGameMenuEvent &); -}; - -class CGameMenuItemTitle : public CGameMenuItem -{ -public: - int at20; - CGameMenuItemTitle(); - CGameMenuItemTitle(const char *, int, int, int, int); - virtual void Draw(void); - //virtual bool Event(CGameMenuEvent &); -}; - -class CGameMenuItemZBool : public CGameMenuItem -{ -public: - bool at20; - const char *at21; - const char *at25; - void (*at29)(CGameMenuItemZBool *); - CGameMenuItemZBool(); - CGameMenuItemZBool(const char *,int,int,int,int,bool,void (*)(CGameMenuItemZBool *),const char *,const char *); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); -}; - -class CGameMenuItemChain : public CGameMenuItem -{ -public: - int at20; - CGameMenu *at24; - int at28; - void(*at2c)(CGameMenuItemChain *); - int at30; - CGameMenuItemChain(); - CGameMenuItemChain(const char *, int, int, int, int, int, CGameMenu *, int, void(*)(CGameMenuItemChain *), int); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); -}; - -class CGameMenuItem7EA1C : public CGameMenuItem -{ -public: - int at20; // text align - CGameMenu *at24; - int at28; - void(*at2c)(CGameMenuItem7EA1C *); - int at30; - IniFile *at34; - char at38[16]; - char at48[16]; - CGameMenuItem7EA1C(); - CGameMenuItem7EA1C(const char *a1, int a2, int a3, int a4, int a5, const char *a6, const char *a7, int a8, int a9, void(*a10)(CGameMenuItem7EA1C *), int a11); - void Setup(void); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); -}; - -class CGameMenuItem7EE34 : public CGameMenuItem -{ -public: - int at20; - int at24; - CGameMenu *at28; - CGameMenu *at2c; - CGameMenuItem7EE34(); - CGameMenuItem7EE34(const char *a1, int a2, int a3, int a4, int a5, int a6); - void Setup(void); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); -}; - -class CGameMenuItemChain7F2F0 : public CGameMenuItemChain -{ -public: - int at34; - CGameMenuItemChain7F2F0(); - CGameMenuItemChain7F2F0(char *a1, int a2, int a3, int a4, int a5, int a6, CGameMenu *a7, int a8, void(*a9)(CGameMenuItemChain *), int a10); - //virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); -}; - -class CGameMenuItemBitmap : public CGameMenuItem -{ -public: - int at20; - CGameMenuItemBitmap(); - CGameMenuItemBitmap(const char *, int, int, int, int); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); -}; - -class CGameMenuItemBitmapLS : public CGameMenuItemBitmap -{ -public: - int at24; - int at28; - CGameMenuItemBitmapLS(); - CGameMenuItemBitmapLS(const char *, int, int, int, int); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); -}; - -class CGameMenuItemKeyList : public CGameMenuItem -{ -public: - void(*pCallback)(CGameMenuItemKeyList *); - int at24; - int nRows; - int nTopDelta; - int nFocus; - int nGameFuncs; - bool bScan; - CGameMenuItemKeyList(); - CGameMenuItemKeyList(const char * a1, int a2, int a3, int a4, int a5, int a6, int a7, void(*a8)(CGameMenuItemKeyList *)); - void Scan(void); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); - virtual bool MouseEvent(CGameMenuEvent &); -}; - -class CGameMenuItemSlider : public CGameMenuItem -{ -public: - int *pValue; - int nValue; - int nRangeLow; - int nRangeHigh; - int nStep; - void(*pCallback)(CGameMenuItemSlider *); - int nSliderTile; - int nCursorTile; - int nShowValue; - CGameMenuItemSlider(); - CGameMenuItemSlider(const char *_pzText, int _nFont, int _nX, int _nY, int _nWidth, int _nValue, int _nRangeLow, int _nRangeHigh, int _nStep, void(*_pCallback)(CGameMenuItemSlider *), int _nSliderTile, int _nCursorTile, int _nShowValue = kMenuSliderNone); - CGameMenuItemSlider(const char *_pzText, int _nFont, int _nX, int _nY, int _nWidth, int *pnValue, int _nRangeLow, int _nRangeHigh, int _nStep, void(*_pCallback)(CGameMenuItemSlider *), int _nSliderTile, int _nCursorTile, int _nShowValue = kMenuSliderNone); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); - virtual bool MouseEvent(CGameMenuEvent &); -}; - -class CGameMenuItemSliderFloat : public CGameMenuItem -{ -public: - float *pValue; - float fValue; - float fRangeLow; - float fRangeHigh; - float fStep; - void(*pCallback)(CGameMenuItemSliderFloat *); - int nSliderTile; - int nCursorTile; - int nShowValue; - CGameMenuItemSliderFloat(); - CGameMenuItemSliderFloat(const char *_pzText, int _nFont, int _nX, int _nY, int _nWidth, float _fValue, float _fRangeLow, float _fRangeHigh, float _fStep, void(*_pCallback)(CGameMenuItemSliderFloat *), int _nSliderTile, int _nCursorTile, int _nShowValue = kMenuSliderNone); - CGameMenuItemSliderFloat(const char *_pzText, int _nFont, int _nX, int _nY, int _nWidth, float *pnValue, float _fRangeLow, float _fRangeHigh, float _fStep, void(*_pCallback)(CGameMenuItemSliderFloat *), int _nSliderTile, int _nCursorTile, int _nShowValue = kMenuSliderNone); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); -}; - -class CGameMenuItemZEdit : public CGameMenuItem -{ -public: - char *at20; - int at24; - int at28; - void(*at2c)(CGameMenuItemZEdit *, CGameMenuEvent *); - char at30; - char at31; - char at32; - CGameMenuItemZEdit(); - CGameMenuItemZEdit(const char *, int, int, int, int, char *, int, char, void(*)(CGameMenuItemZEdit *, CGameMenuEvent *), int); - void AddChar(char); - void BackChar(void); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); -}; - -class CGameMenuItemZEditBitmap : public CGameMenuItem -{ -public: - char *at20; - int at24; - int at28; - CGameMenuItemBitmapLS *at2c; - void(*at30)(CGameMenuItemZEditBitmap *, CGameMenuEvent *); - char bScan; - char at35; - char at36; - char at37; - CGameMenuItemZEditBitmap(); - CGameMenuItemZEditBitmap(char *, int, int, int, int, char *, int, char, void(*)(CGameMenuItemZEditBitmap *, CGameMenuEvent *), int); - void AddChar(char); - void BackChar(void); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); -}; - - -class CGameMenuItemZCycleSelect : public CGameMenuItem -{ -public: - void(*m_pCallback)(CGameMenuItemZCycleSelect *); - int m_nRows; - int m_nTopDelta; - int m_nFocus; - int m_nItems; - int *m_pReturn; - const char **m_pzStrings; - CGameMenuItemZCycleSelect(); - CGameMenuItemZCycleSelect(const char *pzText, int nFont, int nX, int nY, int nWidth, int nRows, int nItems, const char **pzStrings, int *pReturn, void(*pCallback)(CGameMenuItemZCycleSelect *)); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); - virtual bool MouseEvent(CGameMenuEvent &); -}; - - -class CGameMenuItemZCycle : public CGameMenuItem -{ -public: - int m_nItems; - int m_nFocus; - int m_nAlign; - const char *m_pzStrings[kMaxGameCycleItems]; - char m_zTitle[kMaxTitleLength]; - void(*m_pCallback)(CGameMenuItemZCycle *); - void(*m_pCallbackSelect)(CGameMenuItemZCycleSelect *); - bool m_bMenu; - int m_nMenuSelectReturn; - CGameMenu *m_pMenuSelect; - CGameMenuItemTitle *m_pItemSelectTitle; - CGameMenuItemZCycleSelect *m_pItemSelect; - CGameMenuItemZCycle(); - CGameMenuItemZCycle(const char *, int, int, int, int, int, void(*)(CGameMenuItemZCycle *), const char **, int, int, bool = false, void(*)(CGameMenuItemZCycleSelect*) = NULL); - ~CGameMenuItemZCycle(); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); - void Add(const char *, bool); - void Next(void); - void Prev(void); - void Clear(void); - void SetTextArray(const char **, int, int); - void SetTextIndex(int); -}; - -class CGameMenuItemYesNoQuit : public CGameMenuItem -{ -public: - int at20; - int m_nRestart; - CGameMenuItemYesNoQuit(); - CGameMenuItemYesNoQuit(const char *, int, int, int, int, int, int); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); -}; - -class CGameMenuItemPicCycle : public CGameMenuItem -{ -public: - int m_nItems; - int at24; - int at28; - int at2c; - int at30[kMaxPicCycleItems]; - void(*atb0)(CGameMenuItemPicCycle *); - int atb4; - CGameMenuItemPicCycle(); - CGameMenuItemPicCycle(int, int, void(*)(CGameMenuItemPicCycle *), int *, int, int); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); - void Add(int, bool); - void Next(void); - void Prev(void); - void Clear(void); - void SetPicArray(int *, int, int); - void SetPicIndex(int); -}; - -class CGameMenuItemPassword : public CGameMenuItem -{ -public: - char at20[9]; - char at29[9]; - int at32; - char at36; - int at37; - char at3b[32]; - int at5b; - CGameMenuItemZBool *at5f; - CGameMenuItemPassword(); - CGameMenuItemPassword(const char *, int, int, int); - virtual void Draw(void); - virtual bool Event(CGameMenuEvent &); -}; - - -class CGameMenu -{ -public: - int m_nItems; - int m_nFocus; - int at8; - char atc; - CGameMenuItem *pItemList[kMaxGameMenuItems]; // atd - CGameMenu(); - CGameMenu(int); - ~CGameMenu(); - void InitializeItems(CGameMenuEvent &event); - void Draw(void); - bool Event(CGameMenuEvent &event); - void Add(CGameMenuItem *pItem, bool active); - void SetFocusItem(int nItem); - void SetFocusItem(CGameMenuItem *Item); - bool CanSelectItem(int nItem); - void FocusPrevItem(void); - void FocusNextItem(void); - bool IsFocusItem(CGameMenuItem *pItem); - bool MouseEvent(CGameMenuEvent &event); -}; - -class CGameMenuMgr -{ -public: - static bool m_bInitialized; - static bool m_bActive; - static bool m_bScanning; - CGameMenu *pTempMenu; - CGameMenu *pActiveMenu; - CGameMenu *pMenuStack[8]; - int nMenuPointer; - int32_t m_mouselastactivity; - int32_t m_mousewake_watchpoint, m_menuchange_watchpoint; - int32_t m_mousecaught; - vec2_t m_prevmousepos, m_mousepos, m_mousedownpos; - bool m_postPop; - CGameMenuMgr(); - ~CGameMenuMgr(); - void InitializeMenu(void); - void DeInitializeMenu(void); - bool Push(CGameMenu *pMenu, int data); - void Pop(void); - void PostPop(void); - void Draw(void); - void Clear(void); - void Process(void); - void Deactivate(void); - bool MouseOutsideBounds(vec2_t const * const pos, const int32_t x, const int32_t y, const int32_t width, const int32_t height); -}; - -extern CGameMenuMgr gGameMenuMgr; - -#endif END_BLD_NS diff --git a/source/blood/src/loadsave.cpp b/source/blood/src/loadsave.cpp index 5d00cd268..9dc5c35e9 100644 --- a/source/blood/src/loadsave.cpp +++ b/source/blood/src/loadsave.cpp @@ -35,7 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "globals.h" #include "db.h" #include "messages.h" -#include "menu.h" +#include "gamemenu.h" #include "network.h" #include "loadsave.h" #include "resource.h" diff --git a/source/blood/src/menu.cpp b/source/blood/src/menu.cpp index 40c4fccaa..de220ffd4 100644 --- a/source/blood/src/menu.cpp +++ b/source/blood/src/menu.cpp @@ -20,92 +20,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //------------------------------------------------------------------------- -#include "ns.h" // Must come before everything else! - -#include "compat.h" -#include "mmulti.h" -#include "common_game.h" -#include "fx_man.h" -#include "music.h" -#include "blood.h" -#include "demo.h" -#include "config.h" -#include "gamemenu.h" -#include "globals.h" -#include "loadsave.h" -#include "menu.h" -#include "messages.h" -#include "network.h" -#include "osdcmds.h" -#include "sfx.h" -#include "screen.h" -#include "sound.h" -#include "view.h" -#include "cmdlib.h" -#include "i_specialpaths.h" -#include "savegamehelp.h" - -EXTERN_CVAR(Bool, hud_powerupduration) - -BEGIN_BLD_NS #if 0 -void SaveGame(CGameMenuItemZEditBitmap *, CGameMenuEvent *); - -void SaveGameProcess(CGameMenuItemChain *); -void SetDifficultyAndStart(CGameMenuItemChain *); -void SetDetail(CGameMenuItemSlider *); -void SetGamma(CGameMenuItemSlider *); -void SetMusicVol(CGameMenuItemSlider *); -void SetSoundVol(CGameMenuItemSlider *); -void SetCDVol(CGameMenuItemSlider *); -void SetDoppler(CGameMenuItemZBool *); -void SetCrosshair(CGameMenuItemZBool *); -void SetCenterHoriz(CGameMenuItemZBool *); -void SetShowPlayerNames(CGameMenuItemZBool *); -void SetShowWeapons(CGameMenuItemZCycle *); -void SetSlopeTilting(CGameMenuItemZBool *); -void SetViewBobbing(CGameMenuItemZBool *); -void SetViewSwaying(CGameMenuItemZBool *); -void SetMouseSensitivity(CGameMenuItemSliderFloat *); -void SetMouseAimFlipped(CGameMenuItemZBool *); -void SetTurnSpeed(CGameMenuItemSlider *); -void ConfigureKeys(CGameMenuItemChain*); -void ResetKeys(CGameMenuItemChain *); -void ResetKeysClassic(CGameMenuItemChain *); -void SetMessages(CGameMenuItemZBool *); -void LoadGame(CGameMenuItemZEditBitmap *, CGameMenuEvent *); -void SetupNetLevels(CGameMenuItemZCycle *); -void StartNetGame(CGameMenuItemChain *); -void SetParentalLock(CGameMenuItemZBool *); -void TenProcess(CGameMenuItem7EA1C *); -void SetupLevelMenuItem(int); -void SetupVideoModeMenu(CGameMenuItemChain *); -void SetVideoMode(CGameMenuItemChain *); -void SetWidescreen(CGameMenuItemZBool *); -void SetFOV(CGameMenuItemSlider *); -void UpdateVideoColorMenu(CGameMenuItemSliderFloat *); -void ResetVideoColor(CGameMenuItemChain *); -void SetWeaponsV10X(CGameMenuItemZBool* pItem); - -#ifdef USE_OPENGL -void SetupVideoPolymostMenu(CGameMenuItemChain *); -#endif - -char strRestoreGameStrings[][16] = -{ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", -}; +// Not yet implemented content kept for reference. Mostly multiplayer related. const char *zMonsterStrings[] = { @@ -136,526 +54,30 @@ const char *zRespawnStrings[] = "Away from Enemies", }; -const char *zDiffStrings[] = -{ - "STILL KICKING", - "PINK ON THE INSIDE", - "LIGHTLY BROILED", - "WELL DONE", - "EXTRA CRISPY", -}; - const char *pzShowWeaponStrings[] = { "OFF", "SPRITE", "VOXEL" }; -char zUserMapName[16]; -const char *zEpisodeNames[6]; -const char *zLevelNames[6][16]; - -static FString MenuGameFuncs[NUMGAMEFUNCTIONS]; -static char const *MenuGameFuncNone = " -None-"; -static char const *pzGamefuncsStrings[NUMGAMEFUNCTIONS + 1]; -static int nGamefuncsValues[NUMGAMEFUNCTIONS + 1]; -static int nGamefuncsNum; - -CGameMenu menuMain; -CGameMenu menuMainWithSave; -CGameMenu menuNetMain; -CGameMenu menuNetStart; -CGameMenu menuEpisode; -CGameMenu menuDifficulty; -CGameMenu menuOptionsOld; -CGameMenu menuControls; -CGameMenu menuMessages; -CGameMenu menuKeys; -CGameMenu menuSaveGame; -CGameMenu menuLoadGame; -CGameMenu menuLoading; -CGameMenu menuSounds; -CGameMenu menuQuit; -CGameMenu menuRestart; -CGameMenu menuCredits; -CGameMenu menuOrder; -CGameMenu menuPlayOnline; -CGameMenu menuParentalLock; -CGameMenu menuSorry; -CGameMenu menuSorry2; -CGameMenu menuNetwork; -CGameMenu menuNetworkHost; -CGameMenu menuNetworkJoin; - - -CGameMenuItemTitle itemMainTitle("BLOOD", 1, 160, 20, 2038); -CGameMenuItemChain itemMain1("NEW GAME", 1, 0, 45, 320, 1, &menuEpisode, -1, NULL, 0); -//CGameMenuItemChain itemMain2("PLAY ONLINE", 1, 0, 65, 320, 1, &menuPlayOnline, -1, NULL, 0); -CGameMenuItemChain itemMain2("MULTIPLAYER", 1, 0, 65, 320, 1, &menuNetwork, -1, NULL, 0); -CGameMenuItemChain itemMain3("OPTIONS", 1, 0, 85, 320, 1, &menuOptions, -1, NULL, 0); -CGameMenuItemChain itemMain4("LOAD GAME", 1, 0, 105, 320, 1, &menuLoadGame, -1, NULL, 0); -CGameMenuItemChain itemMain5("HELP", 1, 0, 125, 320, 1, &menuOrder, -1, NULL, 0); -CGameMenuItemChain itemMain6("CREDITS", 1, 0, 145, 320, 1, &menuCredits, -1, NULL, 0); -CGameMenuItemChain itemMain7("QUIT", 1, 0, 165, 320, 1, &menuQuit, -1, NULL, 0); - -CGameMenuItemTitle itemMainSaveTitle("BLOOD", 1, 160, 20, 2038); -CGameMenuItemChain itemMainSave1("NEW GAME", 1, 0, 45, 320, 1, &menuEpisode, -1, NULL, 0); -//CGameMenuItemChain itemMainSave2("PLAY ONLINE", 1, 0, 60, 320, 1, &menuPlayOnline, -1, NULL, 0); -CGameMenuItemChain itemMainSave2("OPTIONS", 1, 0, 60, 320, 1, &menuOptions, -1, NULL, 0); -CGameMenuItemChain itemMainSave3("SAVE GAME", 1, 0, 75, 320, 1, &menuSaveGame, -1, SaveGameProcess, 0); -CGameMenuItemChain itemMainSave4("LOAD GAME", 1, 0, 90, 320, 1, &menuLoadGame, -1, NULL, 0); -CGameMenuItemChain itemMainSave5("HELP", 1, 0, 105, 320, 1, &menuOrder, -1, NULL, 0); -CGameMenuItemChain itemMainSave6("CREDITS", 1, 0, 120, 320, 1, &menuCredits, -1, NULL, 0); -CGameMenuItemChain itemMainSave7("END GAME", 1, 0, 135, 320, 1, &menuRestart, -1, NULL, 0); -CGameMenuItemChain itemMainSave8("QUIT", 1, 0, 150, 320, 1, &menuQuit, -1, NULL, 0); - -CGameMenuItemTitle itemEpisodesTitle("EPISODES", 1, 160, 20, 2038); -CGameMenuItemChain7F2F0 itemEpisodes[6]; - -CGameMenuItemTitle itemDifficultyTitle("DIFFICULTY", 1, 160, 20, 2038); -CGameMenuItemChain itemDifficulty1("STILL KICKING", 1, 0, 60, 320, 1, NULL, -1, SetDifficultyAndStart, 0); -CGameMenuItemChain itemDifficulty2("PINK ON THE INSIDE", 1, 0, 80, 320, 1, NULL, -1, SetDifficultyAndStart, 1); -CGameMenuItemChain itemDifficulty3("LIGHTLY BROILED", 1, 0, 100, 320, 1, NULL, -1, SetDifficultyAndStart, 2); -CGameMenuItemChain itemDifficulty4("WELL DONE", 1, 0, 120, 320, 1, NULL, -1, SetDifficultyAndStart, 3); -CGameMenuItemChain itemDifficulty5("EXTRA CRISPY", 1, 0, 140, 320, 1, 0, -1, SetDifficultyAndStart, 4); - -CGameMenuItemTitle itemOptionsOldTitle("OPTIONS", 1, 160, 20, 2038); -CGameMenuItemChain itemOption1("CONTROLS...", 3, 0, 40, 320, 1, &menuControls, -1, NULL, 0); -CGameMenuItemSlider sliderDetail("DETAIL:", 3, 66, 50, 180, gDetail, 0, 4, 1, SetDetail, -1, -1); -CGameMenuItemSlider sliderGamma("GAMMA:", 3, 66, 60, 180, gGamma, 0, 15, 2, SetGamma, -1, -1); --1); -//CGameMenuItemSlider sliderCDAudio("CD AUDIO:", 3, 66, 90, 180, CDVolume, 0, 256, 48, SetCDVol, -1, -1); -CGameMenuItemZBool bool3DAudio("3D AUDIO:", 3, 66, 100, 180, snd_doppler, SetDoppler, NULL, NULL); -CGameMenuItemZBool boolCrosshair("CROSSHAIR:", 3, 66, 110, 180, cl_crosshair, SetCrosshair, NULL, NULL); -CGameMenuItemZCycle itemCycleShowWeapons("SHOW WEAPONS:", 3, 66, 120, 180, 0, SetShowWeapons, pzShowWeaponStrings, ARRAY_SSIZE(pzShowWeaponStrings), 0); -CGameMenuItemZBool boolSlopeTilting("SLOPE TILTING:", 3, 66, 130, 180, cl_slopetilting, SetSlopeTilting, NULL, NULL); -CGameMenuItemZBool boolViewBobbing("VIEW BOBBING:", 3, 66, 140, 180, cl_viewvbob, SetViewBobbing, NULL, NULL); -CGameMenuItemZBool boolViewSwaying("VIEW SWAYING:", 3, 66, 150, 180, cl_viewhbob, SetViewSwaying, NULL, NULL); -CGameMenuItem7EE34 itemOption2("VIDEO MODE...", 3, 0, 160, 320, 1); -CGameMenuItemChain itemChainParentalLock("PARENTAL LOCK", 3, 0, 170, 320, 1, &menuParentalLock, -1, NULL, 0); - -CGameMenuItemTitle itemControlsTitle("CONTROLS", 1, 160, 20, 2038); -CGameMenuItemSliderFloat sliderMouseSpeed("Mouse Sensitivity:", 1, 10, 70, 300, in_mousesensitivity, 0.5f, 16.f, 0.5f, SetMouseSensitivity, -1,-1); -CGameMenuItemZBool boolMouseFlipped("Invert Mouse Aim:", 1, 10, 90, 300, in_mouseflip, SetMouseAimFlipped, NULL, NULL); -CGameMenuItemSlider sliderTurnSpeed("Key Turn Speed:", 1, 10, 110, 300, gTurnSpeed, 64, 128, 4, SetTurnSpeed, -1, -1); -CGameMenuItemChain itemChainKeyList("Configure Keys...", 1, 0, 130, 320, 1, &menuKeys, -1, ConfigureKeys, 0); -CGameMenuItemChain itemChainKeyReset("Reset Keys (default)...", 1, 0, 150, 320, 1, &menuKeys, -1, ResetKeys, 0); -CGameMenuItemChain itemChainKeyResetClassic("Reset Keys (classic)...", 1, 0, 170, 320, 1, &menuKeys, -1, ResetKeysClassic, 0); - CGameMenuItemTitle itemMessagesTitle("MESSAGES", 1, 160, 20, 2038); CGameMenuItemZBool boolMessages("MESSAGES:", 3, 66, 70, 180, 0, SetMessages, NULL, NULL); CGameMenuItemSlider sliderMsgCount("MESSAGE COUNT:", 3, 66, 80, 180, gMessageCount, 1, 16, 1, NULL, -1, -1); CGameMenuItemSlider sliderMsgTime("MESSAGE TIME:", 3, 66, 90, 180, gMessageTime, 1, 8, 1, NULL, -1, -1); -CGameMenuItemZBool boolMsgFont("LARGE FONT:", 3, 66, 100, 180, 0, 0, NULL, NULL); -CGameMenuItemZBool boolMsgIncoming("INCOMING:", 3, 66, 110, 180, 0, 0, NULL, NULL); -CGameMenuItemZBool boolMsgSelf("SELF PICKUP:", 3, 66, 120, 180, 0, 0, NULL, NULL); -CGameMenuItemZBool boolMsgOther("OTHER PICKUP:", 3, 66, 130, 180, 0, 0, NULL, NULL); -CGameMenuItemZBool boolMsgRespawn("RESPAWN:", 3, 66, 140, 180, 0, 0, NULL, NULL); -CGameMenuItemTitle itemKeysTitle("KEY SETUP", 1, 160, 20, 2038); -CGameMenuItemKeyList itemKeyList("", 3, 56, 40, 200, 16, NUMGAMEFUNCTIONS, 0); - -CGameMenuItemTitle itemSaveTitle("Save Game", 1, 160, 20, 2038); -CGameMenuItemZEditBitmap itemSaveGame1(NULL, 3, 20, 60, 320, strRestoreGameStrings[0], 16, 1, SaveGame, 0); -CGameMenuItemZEditBitmap itemSaveGame2(NULL, 3, 20, 70, 320, strRestoreGameStrings[1], 16, 1, SaveGame, 1); -CGameMenuItemZEditBitmap itemSaveGame3(NULL, 3, 20, 80, 320, strRestoreGameStrings[2], 16, 1, SaveGame, 2); -CGameMenuItemZEditBitmap itemSaveGame4(NULL, 3, 20, 90, 320, strRestoreGameStrings[3], 16, 1, SaveGame, 3); -CGameMenuItemZEditBitmap itemSaveGame5(NULL, 3, 20, 100, 320, strRestoreGameStrings[4], 16, 1, SaveGame, 4); -CGameMenuItemZEditBitmap itemSaveGame6(NULL, 3, 20, 110, 320, strRestoreGameStrings[5], 16, 1, SaveGame, 5); -CGameMenuItemZEditBitmap itemSaveGame7(NULL, 3, 20, 120, 320, strRestoreGameStrings[6], 16, 1, SaveGame, 6); -CGameMenuItemZEditBitmap itemSaveGame8(NULL, 3, 20, 130, 320, strRestoreGameStrings[7], 16, 1, SaveGame, 7); -CGameMenuItemZEditBitmap itemSaveGame9(NULL, 3, 20, 140, 320, strRestoreGameStrings[8], 16, 1, SaveGame, 8); -CGameMenuItemZEditBitmap itemSaveGame10(NULL, 3, 20, 150, 320, strRestoreGameStrings[9], 16, 1, SaveGame, 9); -CGameMenuItemBitmapLS itemSaveGamePic(NULL, 3, 0, 0, 2050); - -CGameMenuItemTitle itemLoadTitle("Load Game", 1, 160, 20, 2038); -CGameMenuItemZEditBitmap itemLoadGame1(NULL, 3, 20, 60, 320, strRestoreGameStrings[0], 16, 1, LoadGame, 0); -CGameMenuItemZEditBitmap itemLoadGame2(NULL, 3, 20, 70, 320, strRestoreGameStrings[1], 16, 1, LoadGame, 1); -CGameMenuItemZEditBitmap itemLoadGame3(NULL, 3, 20, 80, 320, strRestoreGameStrings[2], 16, 1, LoadGame, 2); -CGameMenuItemZEditBitmap itemLoadGame4(NULL, 3, 20, 90, 320, strRestoreGameStrings[3], 16, 1, LoadGame, 3); -CGameMenuItemZEditBitmap itemLoadGame5(NULL, 3, 20, 100, 320, strRestoreGameStrings[4], 16, 1, LoadGame, 4); -CGameMenuItemZEditBitmap itemLoadGame6(NULL, 3, 20, 110, 320, strRestoreGameStrings[5], 16, 1, LoadGame, 5); -CGameMenuItemZEditBitmap itemLoadGame7(NULL, 3, 20, 120, 320, strRestoreGameStrings[6], 16, 1, LoadGame, 6); -CGameMenuItemZEditBitmap itemLoadGame8(NULL, 3, 20, 130, 320, strRestoreGameStrings[7], 16, 1, LoadGame, 7); -CGameMenuItemZEditBitmap itemLoadGame9(NULL, 3, 20, 140, 320, strRestoreGameStrings[8], 16, 1, LoadGame, 8); -CGameMenuItemZEditBitmap itemLoadGame10(NULL, 3, 20, 150, 320, strRestoreGameStrings[9], 16, 1, LoadGame, 9); -CGameMenuItemBitmapLS itemLoadGamePic(NULL, 3, 0, 0, 2518); - -CGameMenuItemTitle itemNetStartTitle("MULTIPLAYER", 1, 160, 20, 2038); -CGameMenuItemZCycle itemNetStart1("GAME:", 3, 66, 60, 180, 0, 0, zNetGameTypes, 3, 0); -CGameMenuItemZCycle itemNetStart2("EPISODE:", 3, 66, 70, 180, 0, SetupNetLevels, NULL, 0, 0); -CGameMenuItemZCycle itemNetStart3("LEVEL:", 3, 66, 80, 180, 0, NULL, NULL, 0, 0); -CGameMenuItemZCycle itemNetStart4("DIFFICULTY:", 3, 66, 90, 180, 0, 0, zDiffStrings, 5, 0); -CGameMenuItemZCycle itemNetStart5("MONSTERS:", 3, 66, 100, 180, 0, 0, zMonsterStrings, 3, 0); -CGameMenuItemZCycle itemNetStart6("WEAPONS:", 3, 66, 110, 180, 0, 0, zWeaponStrings, 4, 0); -CGameMenuItemZCycle itemNetStart7("ITEMS:", 3, 66, 120, 180, 0, 0, zItemStrings, 3, 0); -CGameMenuItemZBool itemNetStart8("FRIENDLY FIRE:", 3, 66, 130, 180, true, 0, NULL, NULL); -CGameMenuItemZBool itemNetStart9("KEEP KEYS ON RESPAWN:", 3, 66, 140, 180, false, 0, NULL, NULL); -CGameMenuItemZBool itemNetStart10("V1.0x WEAPONS BALANCE:", 3, 66, 150, 180, false, 0, NULL, NULL); -CGameMenuItemZEdit itemNetStart11("USER MAP:", 3, 66, 160, 180, zUserMapName, 13, 0, NULL, 0); -CGameMenuItemChain itemNetStart12("START GAME", 1, 66, 175, 280, 0, 0, -1, StartNetGame, 0); - -CGameMenuItemText itemLoadingText("LOADING...", 1, 160, 100, 1); - -CGameMenuItemTitle itemSoundsTitle("SOUNDS", 1, 160, 20, 2038); -CGameMenuItemSlider itemSoundsSound("SOUND:", 3, 40, 70, 180, snd_fxvolume, 0, 256, 48, SetSoundVol, -1, -1); -//CGameMenuItemSlider itemSoundsCDAudio("CD AUDIO:", 3, 40, 80, 180, CDVolume, 0, 256, 48, SetCDVol, -1, -1); -CGameMenuItemZBool itemSounds3DAudio("3D SOUND:", 3, 40, 90, 180, snd_doppler, SetDoppler, NULL, NULL); - -CGameMenuItemTitle itemQuitTitle("QUIT", 1, 160, 20, 2038); -CGameMenuItemText itemQuitText1("Do you really want to quit?", 0, 160, 100, 1); -CGameMenuItemYesNoQuit itemQuitYesNo("[Y/N]", 0, 20, 110, 280, 1, 0); - -CGameMenuItemTitle itemRestartTitle("RESTART GAME", 1, 160, 20, 2038); -CGameMenuItemText itemRestartText1("Do you really want to restart game?", 0, 160, 100, 1); -CGameMenuItemYesNoQuit itemRestartYesNo("[Y/N]", 0, 20, 110, 280, 1, 1); - -CGameMenuItemPicCycle itemCreditsPicCycle(0, 0, NULL, NULL, 0, 0); -CGameMenuItemPicCycle itemOrderPicCycle(0, 0, NULL, NULL, 0, 0); - -CGameMenuItemTitle itemParentalLockTitle("PARENTAL LOCK", 1, 160, 20, 2038); -CGameMenuItemZBool itemParentalLockToggle("LOCK:", 3, 66, 70, 180, 0, SetParentalLock, NULL, NULL); -CGameMenuItemPassword itemParentalLockPassword("SET PASSWORD:", 3, 160, 80); - -CGameMenuItemPicCycle itemSorryPicCycle(0, 0, NULL, NULL, 0, 0); -CGameMenuItemText itemSorryText1("Loading and saving games", 0, 160, 90, 1); -CGameMenuItemText itemSorryText2("not supported", 0, 160, 100, 1); -CGameMenuItemText itemSorryText3("in this demo version of Blood.", 0, 160, 110, 1); - -CGameMenuItemText itemSorry2Text1("Buy the complete version of", 0, 160, 90, 1); -CGameMenuItemText itemSorry2Text2("Blood for three new episodes", 0, 160, 100, 1); -CGameMenuItemText itemSorry2Text3("plus eight BloodBath-only levels!", 0, 160, 110, 1); - -CGameMenuItemTitle unk_26E06C(" ONLINE ", 1, 160, 20, 2038); -CGameMenuItem7EA1C unk_26E090("DWANGO", 1, 0, 45, 320, "matt", "DWANGO", 1, -1, NULL, 0); -CGameMenuItem7EA1C unk_26E0E8("RTIME", 1, 0, 65, 320, "matt", "RTIME", 1, -1, NULL, 0); -CGameMenuItem7EA1C unk_26E140("HEAT", 1, 0, 85, 320, "matt", "HEAT", 1, -1, NULL, 0); -CGameMenuItem7EA1C unk_26E198("KALI", 1, 0, 105, 320, "matt", "KALI", 1, -1, NULL, 0); -CGameMenuItem7EA1C unk_26E1F0("MPATH", 1, 0, 125, 320, "matt", "MPATH", 1, -1, NULL, 0); -CGameMenuItem7EA1C unk_26E248("TEN", 1, 0, 145, 320, "matt", "TEN", 1, -1, TenProcess, 0); - - -// static int32_t newresolution, newrendermode, newfullscreen, newvsync; - -enum resflags_t { - RES_FS = 0x1, - RES_WIN = 0x2, -}; - -#define MAXRESOLUTIONSTRINGLENGTH 19 - -struct resolution_t { - int32_t xdim, ydim; - int32_t flags; - int32_t bppmax; - char name[MAXRESOLUTIONSTRINGLENGTH]; -}; - -resolution_t gResolution[MAXVALIDMODES]; -int gResolutionNum; -const char *gResolutionName[MAXVALIDMODES]; - -CGameMenu menuOptions; -CGameMenu menuOptionsGame; -CGameMenu menuOptionsDisplay; -CGameMenu menuOptionsDisplayColor; -CGameMenu menuOptionsDisplayMode; -#ifdef USE_OPENGL -CGameMenu menuOptionsDisplayPolymost; -#endif -CGameMenu menuOptionsSound; -CGameMenu menuOptionsPlayer; -CGameMenu menuOptionsControl; - -void SetupOptionsSound(CGameMenuItemChain *pItem); - -CGameMenuItemTitle itemOptionsTitle("OPTIONS", 1, 160, 20, 2038); -CGameMenuItemChain itemOptionsChainGame("GAME SETUP", 1, 0, 50, 320, 1, &menuOptionsGame, -1, NULL, 0); -CGameMenuItemChain itemOptionsChainDisplay("DISPLAY SETUP", 1, 0, 70, 320, 1, &menuOptionsDisplay, -1, NULL, 0); -CGameMenuItemChain itemOptionsChainSound("SOUND SETUP", 1, 0, 90, 320, 1, &menuOptionsSound, -1, SetupOptionsSound, 0); -CGameMenuItemChain itemOptionsChainPlayer("PLAYER SETUP", 1, 0, 110, 320, 1, &menuOptionsPlayer, -1, NULL, 0); -CGameMenuItemChain itemOptionsChainControl("CONTROL SETUP", 1, 0, 130, 320, 1, &menuOptionsControl, -1, NULL, 0); -CGameMenuItemChain itemOptionsChainOld("OLD MENU", 1, 0, 170, 320, 1, &menuOptionsOld, -1, NULL, 0); - -const char *pzAutoAimStrings[] = { - "NEVER", - "ALWAYS", - "HITSCAN ONLY" -}; - -const char *pzWeaponSwitchStrings[] = { - "NEVER", - "IF NEW", - "BY RATING" -}; - -void SetAutoAim(CGameMenuItemZCycle *); -void SetLevelStats(CGameMenuItemZBool *); -void SetPowerupDuration(CGameMenuItemZBool *); -void SetShowMapTitle(CGameMenuItemZBool*); -void SetWeaponSwitch(CGameMenuItemZCycle *pItem); CGameMenuItemTitle itemOptionsGameTitle("GAME SETUP", 1, 160, 20, 2038); -/////////////// -CGameMenuItemZBool itemOptionsGameBoolWeaponsV10X("V1.0x WEAPONS BALANCE:", 3, 66, 130, 180, gWeaponsV10x, SetWeaponsV10X, NULL, NULL); -/////////////////// -CGameMenuItemZBool itemOptionsGameBoolShowPlayerNames("SHOW PLAYER NAMES:", 3, 66, 60, 180, cl_idplayers, SetShowPlayerNames, NULL, NULL); CGameMenuItemZCycle itemOptionsGameShowWeapons("SHOW WEAPONS:", 3, 66, 70, 180, 0, SetShowWeapons, pzShowWeaponStrings, ARRAY_SSIZE(pzShowWeaponStrings), 0); CGameMenuItemZBool itemOptionsGameBoolSlopeTilting("SLOPE TILTING:", 3, 66, 80, 180, cl_slopetilting, SetSlopeTilting, NULL, NULL); CGameMenuItemZBool itemOptionsGameBoolViewBobbing("VIEW BOBBING:", 3, 66, 90, 180, cl_viewvbob, SetViewBobbing, NULL, NULL); CGameMenuItemZBool itemOptionsGameBoolViewSwaying("VIEW SWAYING:", 3, 66, 100, 180, cl_viewhbob, SetViewSwaying, NULL, NULL); -CGameMenuItemZCycle itemOptionsGameBoolAutoAim("AUTO AIM:", 3, 66, 110, 180, 0, SetAutoAim, pzAutoAimStrings, ARRAY_SSIZE(pzAutoAimStrings), 0); -CGameMenuItemZCycle itemOptionsGameWeaponSwitch("EQUIP PICKUPS:", 3, 66, 120, 180, 0, SetWeaponSwitch, pzWeaponSwitchStrings, ARRAY_SSIZE(pzWeaponSwitchStrings), 0); -CGameMenuItemChain itemOptionsGameChainParentalLock("PARENTAL LOCK", 3, 0, 120, 320, 1, &menuParentalLock, -1, NULL, 0); -CGameMenuItemTitle itemOptionsDisplayTitle("DISPLAY SETUP", 1, 160, 20, 2038); -CGameMenuItemChain itemOptionsDisplayColor("COLOR CORRECTION", 3, 66, 60, 180, 0, &menuOptionsDisplayColor, -1, NULL, 0); -CGameMenuItemChain itemOptionsDisplayMode("VIDEO MODE", 3, 66, 70, 180, 0, &menuOptionsDisplayMode, -1, SetupVideoModeMenu, 0); -CGameMenuItemZBool itemOptionsDisplayBoolCrosshair("CROSSHAIR:", 3, 66, 80, 180, cl_crosshair, SetCrosshair, NULL, NULL); CGameMenuItemZBool itemOptionsDisplayBoolCenterHoriz("CENTER HORIZON LINE:", 3, 66, 90, 180, r_horizcenter, SetCenterHoriz, NULL, NULL); -CGameMenuItemZBool itemOptionsDisplayBoolLevelStats("LEVEL STATS:", 3, 66, 100, 180, hud_stats, SetLevelStats, NULL, NULL); CGameMenuItemZBool itemOptionsDisplayBoolPowerupDuration("POWERUP DURATION:", 3, 66, 110, 180, hud_powerupduration, SetPowerupDuration, NULL, NULL); CGameMenuItemZBool itemOptionsDisplayBoolShowMapTitle("MAP TITLE:", 3, 66, 120, 180, hud_showmapname, SetShowMapTitle, NULL, NULL); -CGameMenuItemZBool itemOptionsDisplayBoolMessages("MESSAGES:", 3, 66, 130, 180, hud_messages, SetMessages, NULL, NULL); -CGameMenuItemZBool itemOptionsDisplayBoolWidescreen("WIDESCREEN:", 3, 66, 140, 180, r_usenewaspect, SetWidescreen, NULL, NULL); -CGameMenuItemSlider itemOptionsDisplayFOV("FOV:", 3, 66, 150, 180, &r_fov.Value, 75, 140, 5, SetFOV, -1, -1, kMenuSliderValue); -#ifdef USE_OPENGL -CGameMenuItemChain itemOptionsDisplayPolymost("POLYMOST SETUP", 3, 66, 160, 180, 0, &menuOptionsDisplayPolymost, -1, SetupVideoPolymostMenu, 0); -#endif -const char *pzRendererStrings[] = { - "CLASSIC", - "POLYMOST" -}; - -const int nRendererValues[] = { - REND_CLASSIC, - REND_POLYMOST -}; - -const char *pzVSyncStrings[] = { - "ADAPTIVE", - "OFF", - "ON" -}; - -const int nVSyncValues[] = { - -1, - 0, - 1 -}; - -const char *pzFrameLimitStrings[] = { - "30 FPS", - "60 FPS", - "75 FPS", - "100 FPS", - "120 FPS", - "144 FPS", - "165 FPS", - "240 FPS" -}; - -const int nFrameLimitValues[] = { - 30, - 60, - 75, - 100, - 120, - 144, - 165, - 240 -}; - - -void PreDrawVideoModeMenu(CGameMenuItem *); - -CGameMenuItemTitle itemOptionsDisplayModeTitle("VIDEO MODE", 1, 160, 20, 2038); -CGameMenuItemZCycle itemOptionsDisplayModeResolution("RESOLUTION:", 3, 66, 60, 180, 0, NULL, NULL, 0, 0, true); -CGameMenuItemZCycle itemOptionsDisplayModeRenderer("RENDERER:", 3, 66, 70, 180, 0, NULL, pzRendererStrings, 2, 0); -CGameMenuItemZBool itemOptionsDisplayModeFullscreen("FULLSCREEN:", 3, 66, 80, 180, 0, NULL, NULL, NULL); -CGameMenuItemZCycle itemOptionsDisplayModeVSync("VSYNC:", 3, 66, 90, 180, 0, NULL, pzVSyncStrings, 3, 0); -CGameMenuItemChain itemOptionsDisplayModeApply("APPLY CHANGES", 3, 66, 125, 180, 0, NULL, 0, SetVideoMode, 0); - -void PreDrawDisplayColor(CGameMenuItem *); - -CGameMenuItemTitle itemOptionsDisplayColorTitle("COLOR CORRECTION", 1, 160, 20, -1); -CGameMenuItemSliderFloat itemOptionsDisplayColorGamma("GAMMA:", 3, 66, 140, 180, &vid_gamma.Value, 0.3f, 4.f, 0.1f, UpdateVideoColorMenu, -1, -1, kMenuSliderValue); -CGameMenuItemSliderFloat itemOptionsDisplayColorContrast("CONTRAST:", 3, 66, 150, 180, &vid_contrast.Value, 0.1f, 2.7f, 0.05f, UpdateVideoColorMenu, -1, -1, kMenuSliderValue); -CGameMenuItemSliderFloat itemOptionsDisplayColorBrightness("BRIGHTNESS:", 3, 66, 160, 180, &vid_brightness.Value, -0.8f, 0.8f, 0.05f, UpdateVideoColorMenu, -1, -1, kMenuSliderValue); -CGameMenuItemSliderFloat itemOptionsDisplayColorVisibility("VISIBILITY:", 3, 66, 170, 180, &r_ambientlight.Value, 0.125f, 4.f, 0.125f, UpdateVideoColorMenu, -1, -1, kMenuSliderValue); -CGameMenuItemChain itemOptionsDisplayColorReset("RESET TO DEFAULTS", 3, 66, 180, 180, 0, NULL, 0, ResetVideoColor, 0); - -const char *pzTextureModeStrings[] = { - "CLASSIC", - "FILTERED" -}; - -#ifdef USE_OPENGL -int nTextureModeValues[] = { - TEXFILTER_OFF, - TEXFILTER_ON -}; -#endif - -const char *pzAnisotropyStrings[] = { - "MAX", - "NONE", - "2X", - "4X", - "8X", - "16X" -}; - -int nAnisotropyValues[] = { - 0, - 1, - 2, - 4, - 8, - 16 -}; - -const char *pzTexQualityStrings[] = { - "FULL", - "HALF", - "BARF" -}; - - -void UpdateTextureMode(CGameMenuItemZCycle *pItem); -void UpdateAnisotropy(CGameMenuItemZCycle *pItem); -void UpdateTrueColorTextures(CGameMenuItemZBool *pItem); -void UpdateTexQuality(CGameMenuItemZCycle *pItem); -void UpdatePreloadCache(CGameMenuItemZBool *pItem); -void UpdateDetailTex(CGameMenuItemZBool *pItem); -void UpdateGlowTex(CGameMenuItemZBool *pItem); -void Update3DModels(CGameMenuItemZBool *pItem); -void UpdateDeliriumBlur(CGameMenuItemZBool *pItem); -#ifdef USE_OPENGL -void PreDrawDisplayPolymost(CGameMenuItem *pItem); -CGameMenuItemTitle itemOptionsDisplayPolymostTitle("POLYMOST SETUP", 1, 160, 20, 2038); -CGameMenuItemZCycle itemOptionsDisplayPolymostTextureMode("TEXTURE MODE:", 3, 66, 60, 180, 0, UpdateTextureMode, pzTextureModeStrings, 2, 0); -CGameMenuItemZCycle itemOptionsDisplayPolymostAnisotropy("ANISOTROPY:", 3, 66, 70, 180, 0, UpdateAnisotropy, pzAnisotropyStrings, 6, 0); -CGameMenuItemZBool itemOptionsDisplayPolymostTrueColorTextures("TRUE COLOR TEXTURES:", 3, 66, 80, 180, 0, UpdateTrueColorTextures, NULL, NULL); -CGameMenuItemZBool itemOptionsDisplayPolymostPreloadCache("PRE-LOAD MAP TEXTURES:", 3, 66, 100, 180, 0, UpdatePreloadCache, NULL, NULL); -CGameMenuItemZBool itemOptionsDisplayPolymostDetailTex("DETAIL TEXTURES:", 3, 66, 120, 180, 0, UpdateDetailTex, NULL, NULL); -CGameMenuItemZBool itemOptionsDisplayPolymostGlowTex("GLOW TEXTURES:", 3, 66, 130, 180, 0, UpdateGlowTex, NULL, NULL); -CGameMenuItemZBool itemOptionsDisplayPolymost3DModels("3D MODELS:", 3, 66, 140, 180, 0, Update3DModels, NULL, NULL); -CGameMenuItemZBool itemOptionsDisplayPolymostDeliriumBlur("DELIRIUM EFFECT BLUR:", 3, 66, 150, 180, 0, UpdateDeliriumBlur, NULL, NULL); -#endif - -void UpdateSoundToggle(CGameMenuItemZBool *pItem); -void UpdateMusicToggle(CGameMenuItemZBool *pItem); -void Update3DToggle(CGameMenuItemZBool *pItem); -void UpdateCDToggle(CGameMenuItemZBool *pItem); -void UpdateSoundVolume(CGameMenuItemSlider *pItem); -void UpdateMusicVolume(CGameMenuItemSlider *pItem); -void UpdateSoundRate(CGameMenuItemZCycle *pItem); -void UpdateNumVoices(CGameMenuItemSlider *pItem); -void UpdateMusicDevice(CGameMenuItemZCycle *pItem); -void SetSound(CGameMenuItemChain *pItem); -void PreDrawSound(CGameMenuItem *pItem); -const char *pzSoundRateStrings[] = { - "22050HZ", - "44100HZ", - "48000HZ" -}; - -int nSoundRateValues[] = { - 22050, - 44100, - 48000 -}; - -int nMusicDeviceValues[] = { - ASS_OPL3, -#ifdef _WIN32 - ASS_WinMM, -#endif -}; - -const char *pzMusicDeviceStrings[] = { - "OPL3(SB/ADLIB)", -#ifdef _WIN32 - "SYSTEM MIDI", -#endif -}; - -CGameMenuItemTitle itemOptionsSoundTitle("SOUND SETUP", 1, 160, 20, 2038); -CGameMenuItemZBool itemOptionsSoundSoundToggle("SOUND:", 3, 66, 60, 180, false, UpdateSoundToggle, NULL, NULL); -CGameMenuItemZBool itemOptionsSoundMusicToggle("MUSIC:", 3, 66, 70, 180, false, UpdateMusicToggle, NULL, NULL); -CGameMenuItemZBool itemOptionsSound3DToggle("3D AUDIO:", 3, 66, 80, 180, false, Update3DToggle, NULL, NULL); -CGameMenuItemSlider itemOptionsSoundSoundVolume("SOUND VOLUME:", 3, 66, 90, 180, &snd_fxvolume.Value, 0, 256, 48, UpdateSoundVolume, -1, -1, kMenuSliderPercent); -CGameMenuItemZCycle itemOptionsSoundSampleRate("SAMPLE RATE:", 3, 66, 110, 180, 0, UpdateSoundRate, pzSoundRateStrings, 3, 0); -CGameMenuItemSlider itemOptionsSoundNumVoices("VOICES:", 3, 66, 120, 180, snd_numvoices, 16, 256, 16, UpdateNumVoices, -1, -1, kMenuSliderValue); -CGameMenuItemZBool itemOptionsSoundCDToggle("REDBOOK AUDIO:", 3, 66, 130, 180, false, UpdateCDToggle, NULL, NULL); -CGameMenuItemZCycle itemOptionsSoundMusicDevice("MUSIC DEVICE:", 3, 66, 140, 180, 0, UpdateMusicDevice, pzMusicDeviceStrings, ARRAY_SIZE(pzMusicDeviceStrings), 0); -CGameMenuItemChain itemOptionsSoundApplyChanges("APPLY CHANGES", 3, 66, 150, 180, 0, NULL, 0, SetSound, 0); - - -void UpdatePlayerName(CGameMenuItemZEdit *pItem, CGameMenuEvent *pEvent); - -CGameMenuItemTitle itemOptionsPlayerTitle("PLAYER SETUP", 1, 160, 20, 2038); -// This won't work without messing around with stuff. So it'll have to wait for the new options menu. -//CGameMenuItemZEdit itemOptionsPlayerName("PLAYER NAME:", 3, 66, 60, 180, *playername, MAXPLAYERNAME, 0, UpdatePlayerName, 0); - -CGameMenu menuOptionsControlKeyboard; -CGameMenu menuOptionsControlMouse; -CGameMenu menuOptionsControlMouseButtonAssignment; - -void SetupMouseMenu(CGameMenuItemChain *pItem); - -CGameMenuItemTitle itemOptionsControlTitle("CONTROL SETUP", 1, 160, 20, 2038); -CGameMenuItemChain itemOptionsControlKeyboard("CONFIGURE CONTROLS", 1, 0, 60, 320, 1, &menuOptionsControlKeyboard, -1, NULL, 0); -CGameMenuItemChain itemOptionsControlMouse("MOUSE SETUP", 1, 0, 80, 320, 1, &menuOptionsControlMouse, -1, SetupMouseMenu, 0); - -CGameMenuItemTitle itemOptionsControlKeyboardTitle("CONFIGURE CONTROLS", 1, 160, 20, 2038); -CGameMenuItemChain itemOptionsControlKeyboardList("Edit Configuration...", 1, 0, 60, 320, 1, &menuKeys, -1, ConfigureKeys, 0); -CGameMenuItemChain itemOptionsControlKeyboardReset("Reset Configuration (default)...", 1, 0, 80, 320, 1, &menuKeys, -1, ResetKeys, 0); -CGameMenuItemChain itemOptionsControlKeyboardResetClassic("Reset Configuration (classic)...", 1, 0, 100, 320, 1, &menuKeys, -1, ResetKeysClassic, 0); - -void SetMouseFilterInput(CGameMenuItemZBool *pItem); -void SetMouseAimMode(CGameMenuItemZBool *pItem); -void SetMouseVerticalAim(CGameMenuItemZBool *pItem); -void SetMouseXScale(CGameMenuItemSlider *pItem); -void SetMouseYScale(CGameMenuItemSlider *pItem); -void SetMouseDigitalAxis(CGameMenuItemZCycle *pItem); - -void PreDrawControlMouse(CGameMenuItem *pItem); - -void SetupMouseButtonMenu(CGameMenuItemChain *pItem); - -CGameMenuItemTitle itemOptionsControlMouseTitle("MOUSE SETUP", 1, 160, 20, 2038); -//CGameMenuItemChain itemOptionsControlMouseButton("BUTTON ASSIGNMENT", 3, 66, 60, 180, 0, &menuOptionsControlMouseButtonAssignment, 0, SetupMouseButtonMenu, 0); -CGameMenuItemSliderFloat itemOptionsControlMouseSensitivity("SENSITIVITY:", 3, 66, 70, 180, &in_mousesensitivity.Value, 0.5f, 16.f, 0.5f, SetMouseSensitivity, -1, -1, kMenuSliderValue); -CGameMenuItemZBool itemOptionsControlMouseAimFlipped("INVERT AIMING:", 3, 66, 80, 180, false, SetMouseAimFlipped, NULL, NULL); -CGameMenuItemZBool itemOptionsControlMouseFilterInput("FILTER INPUT:", 3, 66, 90, 180, false, SetMouseFilterInput, NULL, NULL); -CGameMenuItemZBool itemOptionsControlMouseAimMode("AIMING TYPE:", 3, 66, 100, 180, false, SetMouseAimMode, "HOLD", "TOGGLE"); -CGameMenuItemZBool itemOptionsControlMouseVerticalAim("VERTICAL AIMING:", 3, 66, 110, 180, false, SetMouseVerticalAim, NULL, NULL); -CGameMenuItemSlider itemOptionsControlMouseXScale("X-SCALE:", 3, 66, 120, 180, (int*)&in_mousescalex, 0, 65536, 1024, SetMouseXScale, -1, -1, kMenuSliderQ16); -CGameMenuItemSlider itemOptionsControlMouseYScale("Y-SCALE:", 3, 66, 130, 180, (int*)&in_mousescaley, 0, 65536, 1024, SetMouseYScale, -1, -1, kMenuSliderQ16); -/* -CGameMenuItemZCycle itemOptionsControlMouseDigitalUp("DIGITAL UP", 3, 66, 140, 180, 0, SetMouseDigitalAxis, NULL, 0, 0, true); -CGameMenuItemZCycle itemOptionsControlMouseDigitalDown("DIGITAL DOWN", 3, 66, 150, 180, 0, SetMouseDigitalAxis, NULL, 0, 0, true); -CGameMenuItemZCycle itemOptionsControlMouseDigitalLeft("DIGITAL LEFT", 3, 66, 160, 180, 0, SetMouseDigitalAxis, NULL, 0, 0, true); -CGameMenuItemZCycle itemOptionsControlMouseDigitalRight("DIGITAL RIGHT", 3, 66, 170, 180, 0, SetMouseDigitalAxis, NULL, 0, 0, true); -*/ - -void SetupNetworkMenu(void); -void SetupNetworkHostMenu(CGameMenuItemChain *pItem); -void SetupNetworkJoinMenu(CGameMenuItemChain *pItem); -void NetworkHostGame(CGameMenuItemChain *pItem); -void NetworkJoinGame(CGameMenuItemChain *pItem); - -char zNetAddressBuffer[16] = "localhost"; -char zNetPortBuffer[6]; - -CGameMenuItemTitle itemNetworkTitle("MULTIPLAYER", 1, 160, 20, 2038); -CGameMenuItemChain itemNetworkHost("HOST A GAME", 1, 0, 80, 320, 1, &menuNetworkHost, -1, SetupNetworkHostMenu, 0); -CGameMenuItemChain itemNetworkJoin("JOIN A GAME", 1, 0, 100, 320, 1, &menuNetworkJoin, -1, SetupNetworkJoinMenu, 0); CGameMenuItemTitle itemNetworkHostTitle("HOST A GAME", 1, 160, 20, 2038); CGameMenuItemSlider itemNetworkHostPlayerNum("PLAYER NUMBER:", 3, 66, 70, 180, 1, 2, kMaxPlayers, 1, NULL, -1, -1, kMenuSliderValue); @@ -667,705 +89,6 @@ CGameMenuItemZEdit itemNetworkJoinAddress("NETWORK ADDRESS:", 3, 66, 70, 180, zN CGameMenuItemZEdit itemNetworkJoinPort("NETWORK PORT:", 3, 66, 80, 180, zNetPortBuffer, 6, 0, NULL, 0); CGameMenuItemChain itemNetworkJoinJoin("JOIN A GAME", 3, 66, 100, 180, 1, NULL, -1, NetworkJoinGame, 0); -// There is no better way to do this than manually. - -#define MENUMOUSEFUNCTIONS 12 - -static char const *MenuMouseNames[MENUMOUSEFUNCTIONS] = { - "Button 1", - "Double Button 1", - "Button 2", - "Double Button 2", - "Button 3", - "Double Button 3", - - "Wheel Up", - "Wheel Down", - - "Button 4", - "Double Button 4", - "Button 5", - "Double Button 5", -}; - -static int32_t MenuMouseDataIndex[MENUMOUSEFUNCTIONS][2] = { - { 0, 0, }, - { 0, 1, }, - { 1, 0, }, - { 1, 1, }, - { 2, 0, }, - { 2, 1, }, - - // note the mouse wheel - { 4, 0, }, - { 5, 0, }, - - { 3, 0, }, - { 3, 1, }, - { 6, 0, }, - { 6, 1, }, -}; - -void SetMouseButton(CGameMenuItemZCycle *pItem); - -CGameMenuItemZCycle *pItemOptionsControlMouseButton[MENUMOUSEFUNCTIONS]; - -void SetupLoadingScreen(void) -{ - menuLoading.Add(&itemLoadingText, true); -} - -void SetupKeyListMenu(void) -{ - menuKeys.Add(&itemKeysTitle, false); - menuKeys.Add(&itemKeyList, true); - menuKeys.Add(&itemBloodQAV, false); -} - -void SetupMessagesMenu(void) -{ - menuMessages.Add(&itemMessagesTitle, false); - menuMessages.Add(&boolMessages, true); - menuMessages.Add(&sliderMsgCount, false); - menuMessages.Add(&sliderMsgTime, false); - menuMessages.Add(&boolMsgFont, false); - menuMessages.Add(&boolMsgIncoming, false); - menuMessages.Add(&boolMsgSelf, false); - menuMessages.Add(&boolMsgOther, false); - menuMessages.Add(&boolMsgRespawn, false); - menuMessages.Add(&itemBloodQAV, false); -} - -void SetupControlsMenu(void) -{ - sliderMouseSpeed.fValue = ClipRangeF(in_mousesensitivity, sliderMouseSpeed.fRangeLow, sliderMouseSpeed.fRangeHigh); - sliderTurnSpeed.nValue = ClipRange(gTurnSpeed, sliderTurnSpeed.nRangeLow, sliderTurnSpeed.nRangeHigh); - boolMouseFlipped.at20 = in_mouseflip; - menuControls.Add(&itemControlsTitle, false); - menuControls.Add(&sliderMouseSpeed, true); - menuControls.Add(&boolMouseFlipped, false); - menuControls.Add(&sliderTurnSpeed, false); - menuControls.Add(&itemChainKeyList, false); - menuControls.Add(&itemChainKeyReset, false); - menuControls.Add(&itemChainKeyResetClassic, false); - menuControls.Add(&itemBloodQAV, false); -} - -void SetupOptionsOldMenu(void) -{ - sliderDetail.nValue = ClipRange(gDetail, sliderDetail.nRangeLow, sliderDetail.nRangeHigh); - sliderGamma.nValue = ClipRange(gGamma, sliderGamma.nRangeLow, sliderGamma.nRangeHigh); - - bool3DAudio.at20 = snd_doppler; - boolCrosshair.at20 = cl_crosshair; - itemCycleShowWeapons.m_nFocus = cl_showweapon; - boolSlopeTilting.at20 = cl_slopetilting; - boolViewBobbing.at20 = cl_viewvbob; - boolViewSwaying.at20 = cl_viewhbob; - boolMessages.at20 = gGameMessageMgr.state; - menuOptionsOld.Add(&itemOptionsTitle, false); - menuOptionsOld.Add(&itemOption1, true); - menuOptionsOld.Add(&sliderDetail, false); - menuOptionsOld.Add(&sliderGamma, false); - menuOptionsOld.Add(&sliderMusic, false); - menuOptionsOld.Add(&sliderSound, false); - //menuOptionsOld.Add(&sliderCDAudio, false); - menuOptionsOld.Add(&bool3DAudio, false); - menuOptionsOld.Add(&boolCrosshair, false); - menuOptionsOld.Add(&itemCycleShowWeapons, false); - menuOptionsOld.Add(&boolSlopeTilting, false); - menuOptionsOld.Add(&boolViewBobbing, false); - menuOptionsOld.Add(&boolViewSwaying, false); - menuOptionsOld.Add(&itemOption2, false); - menuOptionsOld.Add(&itemChainParentalLock, false); - menuOptionsOld.Add(&itemBloodQAV, false); -} - -void SetupDifficultyMenu(void) -{ - menuDifficulty.Add(&itemDifficultyTitle, false); - menuDifficulty.Add(&itemDifficulty1, false); - menuDifficulty.Add(&itemDifficulty2, false); - menuDifficulty.Add(&itemDifficulty3, true); - menuDifficulty.Add(&itemDifficulty4, false); - menuDifficulty.Add(&itemDifficulty5, false); - menuDifficulty.Add(&itemBloodQAV, false); -} - -void SetupEpisodeMenu(void) -{ - menuEpisode.Add(&itemEpisodesTitle, false); - bool unk = false; - int height; - gMenuTextMgr.GetFontInfo(1, NULL, NULL, &height); - int j = 0; - for (int i = 0; i < 6; i++) - { - EPISODEINFO *pEpisode = &gEpisodeInfo[i]; - if (!pEpisode->bloodbath || gGameOptions.nGameType != 0) - { - if (j < gEpisodeCount) - { - CGameMenuItemChain7F2F0 *pEpisodeItem = &itemEpisodes[j]; - pEpisodeItem->m_nFont = 1; - pEpisodeItem->m_nX = 0; - pEpisodeItem->m_nWidth = 320; - pEpisodeItem->at20 = 1; - pEpisodeItem->m_pzText = pEpisode->at0; - pEpisodeItem->m_nY = 55+(height+8)*j; - pEpisodeItem->at34 = i; - if (!unk || j == 0) - { - pEpisodeItem = &itemEpisodes[j]; - pEpisodeItem->at24 = &menuDifficulty; - pEpisodeItem->at28 = 3; - } - else - { - pEpisodeItem->at24 = &menuSorry2; - pEpisodeItem->at28 = 1; - } - pEpisodeItem = &itemEpisodes[j]; - pEpisodeItem->bCanSelect = 1; - pEpisodeItem->bEnable = 1; - bool first = j == 0; - menuEpisode.Add(&itemEpisodes[j], first); - if (first) - SetupLevelMenuItem(j); - } - j++; - } - } - menuEpisode.Add(&itemBloodQAV, false); -} - -void SetupMainMenu(void) -{ - menuMain.Add(&itemMainTitle, false); - menuMain.Add(&itemMain1, true); - if (gGameOptions.nGameType > 0) - { - itemMain1.at24 = &menuNetStart; - itemMain1.at28 = 2; - } - else - { - itemMain1.at24 = &menuEpisode; - itemMain1.at28 = -1; - } - menuMain.Add(&itemMain2, false); - menuMain.Add(&itemMain3, false); - menuMain.Add(&itemMain4, false); - menuMain.Add(&itemMain5, false); - menuMain.Add(&itemMain6, false); - menuMain.Add(&itemMain7, false); - menuMain.Add(&itemBloodQAV, false); -} - -void SetupMainMenuWithSave(void) -{ - menuMainWithSave.Add(&itemMainSaveTitle, false); - menuMainWithSave.Add(&itemMainSave1, true); - if (gGameOptions.nGameType > 0) - { - itemMainSave1.at24 = &menuNetStart; - itemMainSave1.at28 = 2; - } - else - { - itemMainSave1.at24 = &menuEpisode; - itemMainSave1.at28 = -1; - } - menuMainWithSave.Add(&itemMainSave2, false); - menuMainWithSave.Add(&itemMainSave3, false); - menuMainWithSave.Add(&itemMainSave4, false); - menuMainWithSave.Add(&itemMainSave5, false); - menuMainWithSave.Add(&itemMainSave6, false); - menuMainWithSave.Add(&itemMainSave7, false); - menuMainWithSave.Add(&itemMainSave8, false); - menuMainWithSave.Add(&itemBloodQAV, false); -} - -void SetupNetStartMenu(void) -{ - bool oneEpisode = false; - menuNetStart.Add(&itemNetStartTitle, false); - menuNetStart.Add(&itemNetStart1, false); - for (int i = 0; i < (oneEpisode ? 1 : 6); i++) - { - EPISODEINFO *pEpisode = &gEpisodeInfo[i]; - if (i < gEpisodeCount) - itemNetStart2.Add(pEpisode->at0, i == 0); - } - menuNetStart.Add(&itemNetStart2, false); - menuNetStart.Add(&itemNetStart3, false); - menuNetStart.Add(&itemNetStart4, false); - menuNetStart.Add(&itemNetStart5, false); - menuNetStart.Add(&itemNetStart6, false); - menuNetStart.Add(&itemNetStart7, false); - menuNetStart.Add(&itemNetStart8, false); - menuNetStart.Add(&itemNetStart9, false); - menuNetStart.Add(&itemNetStart10, false); - menuNetStart.Add(&itemNetStart11, false); - menuNetStart.Add(&itemNetStart12, false); - itemNetStart1.SetTextIndex(1); - itemNetStart4.SetTextIndex(2); - itemNetStart5.SetTextIndex(0); - itemNetStart6.SetTextIndex(1); - itemNetStart7.SetTextIndex(1); - menuNetStart.Add(&itemBloodQAV, false); -} - -void SetupSaveGameMenu(void) -{ - menuSaveGame.Add(&itemSaveTitle, false); - menuSaveGame.Add(&itemSaveGame1, true); - menuSaveGame.Add(&itemSaveGame2, false); - menuSaveGame.Add(&itemSaveGame3, false); - menuSaveGame.Add(&itemSaveGame4, false); - menuSaveGame.Add(&itemSaveGame5, false); - menuSaveGame.Add(&itemSaveGame6, false); - menuSaveGame.Add(&itemSaveGame7, false); - menuSaveGame.Add(&itemSaveGame8, false); - menuSaveGame.Add(&itemSaveGame9, false); - menuSaveGame.Add(&itemSaveGame10, false); - menuSaveGame.Add(&itemSaveGamePic, false); - menuSaveGame.Add(&itemBloodQAV, false); - - itemSaveGame1.at2c = &itemSaveGamePic; - if (!strcmp(strRestoreGameStrings[0], "")) - itemSaveGame1.at37 = 1; - - itemSaveGame2.at2c = &itemSaveGamePic; - if (!strcmp(strRestoreGameStrings[1], "")) - itemSaveGame2.at37 = 1; - - itemSaveGame3.at2c = &itemSaveGamePic; - if (!strcmp(strRestoreGameStrings[2], "")) - itemSaveGame3.at37 = 1; - - itemSaveGame4.at2c = &itemSaveGamePic; - if (!strcmp(strRestoreGameStrings[3], "")) - itemSaveGame4.at37 = 1; - - itemSaveGame5.at2c = &itemSaveGamePic; - if (!strcmp(strRestoreGameStrings[4], "")) - itemSaveGame5.at37 = 1; - - itemSaveGame6.at2c = &itemSaveGamePic; - if (!strcmp(strRestoreGameStrings[5], "")) - itemSaveGame6.at37 = 1; - - itemSaveGame7.at2c = &itemSaveGamePic; - if (!strcmp(strRestoreGameStrings[6], "")) - itemSaveGame7.at37 = 1; - - itemSaveGame8.at2c = &itemSaveGamePic; - if (!strcmp(strRestoreGameStrings[7], "")) - itemSaveGame8.at37 = 1; - - itemSaveGame9.at2c = &itemSaveGamePic; - if (!strcmp(strRestoreGameStrings[8], "")) - itemSaveGame9.at37 = 1; - - itemSaveGame10.at2c = &itemSaveGamePic; - if (!strcmp(strRestoreGameStrings[9], "")) - itemSaveGame10.at37 = 1; -} - -void SetupLoadGameMenu(void) -{ - menuLoadGame.Add(&itemLoadTitle, false); - menuLoadGame.Add(&itemLoadGame1, true); - menuLoadGame.Add(&itemLoadGame2, false); - menuLoadGame.Add(&itemLoadGame3, false); - menuLoadGame.Add(&itemLoadGame4, false); - menuLoadGame.Add(&itemLoadGame5, false); - menuLoadGame.Add(&itemLoadGame6, false); - menuLoadGame.Add(&itemLoadGame7, false); - menuLoadGame.Add(&itemLoadGame8, false); - menuLoadGame.Add(&itemLoadGame9, false); - menuLoadGame.Add(&itemLoadGame10, false); - menuLoadGame.Add(&itemLoadGamePic, false); - itemLoadGame1.at35 = 0; - itemLoadGame2.at35 = 0; - itemLoadGame3.at35 = 0; - itemLoadGame4.at35 = 0; - itemLoadGame5.at35 = 0; - itemLoadGame6.at35 = 0; - itemLoadGame7.at35 = 0; - itemLoadGame8.at35 = 0; - itemLoadGame9.at35 = 0; - itemLoadGame10.at35 = 0; - itemLoadGame1.at2c = &itemLoadGamePic; - itemLoadGame2.at2c = &itemLoadGamePic; - itemLoadGame3.at2c = &itemLoadGamePic; - itemLoadGame4.at2c = &itemLoadGamePic; - itemLoadGame5.at2c = &itemLoadGamePic; - itemLoadGame6.at2c = &itemLoadGamePic; - itemLoadGame7.at2c = &itemLoadGamePic; - itemLoadGame8.at2c = &itemLoadGamePic; - itemLoadGame9.at2c = &itemLoadGamePic; - itemLoadGame10.at2c = &itemLoadGamePic; - menuLoadGame.Add(&itemBloodQAV, false); -} - -void SetupSoundsMenu(void) -{ - menuSounds.Add(&itemSoundsTitle, false); - menuSounds.Add(&itemSoundsMusic, true); - menuSounds.Add(&itemSoundsSound, false); - //menuSounds.Add(&itemSoundsCDAudio, false); - menuSounds.Add(&itemSounds3DAudio, false); - menuSounds.Add(&itemBloodQAV, false); -} - -void SetupQuitMenu(void) -{ - menuQuit.Add(&itemQuitTitle, false); - menuQuit.Add(&itemQuitText1, false); - menuQuit.Add(&itemQuitYesNo, true); - menuQuit.Add(&itemBloodQAV, false); - - menuRestart.Add(&itemRestartTitle, false); - menuRestart.Add(&itemRestartText1, false); - menuRestart.Add(&itemRestartYesNo, true); - menuRestart.Add(&itemBloodQAV, false); -} - -void SetupHelpOrderMenu(void) -{ - menuOrder.Add(&itemHelp4QAV, true); - menuOrder.Add(&itemHelp5QAV, false); - menuOrder.Add(&itemHelp3QAV, false); - menuOrder.Add(&itemHelp3BQAV, false); - itemHelp4QAV.bEnable = 1; - itemHelp4QAV.bNoDraw = 1; - itemHelp5QAV.bEnable = 1; - itemHelp5QAV.bNoDraw = 1; - itemHelp3QAV.bEnable = 1; - itemHelp3QAV.bNoDraw = 1; - itemHelp3BQAV.bEnable = 1; - itemHelp3BQAV.bNoDraw = 1; -} - -void SetupCreditsMenu(void) -{ - menuCredits.Add(&itemCreditsQAV, true); - itemCreditsQAV.bEnable = 1; - itemCreditsQAV.bNoDraw = 1; -} - -void SetupParentalLockMenu(void) -{ - itemParentalLockToggle.at20 = gbAdultContent; - strcpy(itemParentalLockPassword.at20, gzAdultPassword); - menuParentalLock.Add(&itemParentalLockTitle, false); - menuParentalLock.Add(&itemParentalLockToggle, true); - menuParentalLock.Add(&itemParentalLockPassword, false); - menuParentalLock.Add(&itemBloodQAV, false); -} - -void SetupSorry3Menu(void) -{ - menuPlayOnline.Add(&unk_26E06C, false); - menuPlayOnline.Add(&unk_26E090, true); - menuPlayOnline.Add(&unk_26E0E8, false); - menuPlayOnline.Add(&unk_26E140, false); - menuPlayOnline.Add(&unk_26E198, false); - menuPlayOnline.Add(&unk_26E1F0, false); - menuPlayOnline.Add(&unk_26E248, false); - menuPlayOnline.Add(&itemBloodQAV, false); -} - -void SetupSorryMenu(void) -{ - menuSorry.Add(&itemSorryPicCycle, true); - menuSorry.Add(&itemSorryText1, false); - menuSorry.Add(&itemSorryText3, false); - menuSorry.Add(&itemBloodQAV, false); -} - -void SetupSorry2Menu(void) -{ - menuSorry2.Add(&itemSorryPicCycle, true); - menuSorry2.Add(&itemSorry2Text1, false); - menuSorry2.Add(&itemSorry2Text2, false); - menuSorry2.Add(&itemSorry2Text3, false); - menuSorry2.Add(&itemBloodQAV, false); -} - -void SetupOptionsMenu(void) -{ - menuOptions.Add(&itemOptionsTitle, false); - menuOptions.Add(&itemOptionsChainGame, true); - menuOptions.Add(&itemOptionsChainDisplay, false); - menuOptions.Add(&itemOptionsChainSound, false); - menuOptions.Add(&itemOptionsChainPlayer, false); - menuOptions.Add(&itemOptionsChainControl, false); - //menuOptions.Add(&itemOptionsChainOld, false); - menuOptions.Add(&itemBloodQAV, false); - - menuOptionsGame.Add(&itemOptionsGameTitle, false); - menuOptionsGame.Add(&itemOptionsGameBoolShowPlayerNames, true); - menuOptionsGame.Add(&itemOptionsGameShowWeapons, false); - menuOptionsGame.Add(&itemOptionsGameBoolSlopeTilting, false); - menuOptionsGame.Add(&itemOptionsGameBoolViewBobbing, false); - menuOptionsGame.Add(&itemOptionsGameBoolViewSwaying, false); - menuOptionsGame.Add(&itemOptionsGameBoolAutoAim, false); - menuOptionsGame.Add(&itemOptionsGameWeaponSwitch, false); - - ////////////////////// - if (gGameOptions.nGameType == 0) { - menuOptionsGame.Add(&itemOptionsGameBoolWeaponsV10X, false); - } - ///////////////////// - - //menuOptionsGame.Add(&itemOptionsGameChainParentalLock, false); - menuOptionsGame.Add(&itemBloodQAV, false); - itemOptionsGameShowWeapons.m_nFocus = cl_showweapon; - itemOptionsGameBoolSlopeTilting.at20 = cl_slopetilting; - itemOptionsGameBoolViewBobbing.at20 = cl_viewvbob; - itemOptionsGameBoolViewSwaying.at20 = cl_viewhbob; - itemOptionsGameBoolAutoAim.m_nFocus = cl_autoaim; - itemOptionsGameWeaponSwitch.m_nFocus = (cl_weaponswitch&1) ? ((cl_weaponswitch&2) ? 1 : 2) : 0; - - /////// - itemOptionsGameBoolWeaponsV10X.at20 = gWeaponsV10x; - /////// - - menuOptionsDisplay.Add(&itemOptionsDisplayTitle, false); - menuOptionsDisplay.Add(&itemOptionsDisplayColor, true); - menuOptionsDisplay.Add(&itemOptionsDisplayMode, false); - menuOptionsDisplay.Add(&itemOptionsDisplayBoolCrosshair, false); - menuOptionsDisplay.Add(&itemOptionsDisplayBoolCenterHoriz, false); - menuOptionsDisplay.Add(&itemOptionsDisplayBoolLevelStats, false); - menuOptionsDisplay.Add(&itemOptionsDisplayBoolPowerupDuration, false); - menuOptionsDisplay.Add(&itemOptionsDisplayBoolShowMapTitle, false); - menuOptionsDisplay.Add(&itemOptionsDisplayBoolMessages, false); - menuOptionsDisplay.Add(&itemOptionsDisplayBoolWidescreen, false); - menuOptionsDisplay.Add(&itemOptionsDisplayFOV, false); -#ifdef USE_OPENGL - menuOptionsDisplay.Add(&itemOptionsDisplayPolymost, false); -#endif - menuOptionsDisplay.Add(&itemBloodQAV, false); - itemOptionsDisplayBoolCrosshair.at20 = cl_crosshair; - itemOptionsDisplayBoolCenterHoriz.at20 = r_horizcenter; - itemOptionsDisplayBoolLevelStats.at20 = hud_stats; - itemOptionsDisplayBoolPowerupDuration.at20 = hud_powerupduration; - itemOptionsDisplayBoolShowMapTitle.at20 = hud_showmapname; - itemOptionsDisplayBoolMessages.at20 = hud_messages; - itemOptionsDisplayBoolWidescreen.at20 = r_usenewaspect; - - menuOptionsDisplayMode.Add(&itemOptionsDisplayModeTitle, false); - menuOptionsDisplayMode.Add(&itemOptionsDisplayModeResolution, true); - // prepare video setup - for (int i = 0; i < validmodecnt; ++i) - { - int j; - for (j = 0; j < gResolutionNum; ++j) - { - if (validmode[i].xdim == gResolution[j].xdim && validmode[i].ydim == gResolution[j].ydim) - { - gResolution[j].flags |= validmode[i].fs ? RES_FS : RES_WIN; - Bsnprintf(gResolution[j].name, MAXRESOLUTIONSTRINGLENGTH, "%d x %d%s", gResolution[j].xdim, gResolution[j].ydim, (gResolution[j].flags & RES_FS) ? "" : "Win"); - gResolutionName[j] = gResolution[j].name; - if (validmode[i].bpp > gResolution[j].bppmax) - gResolution[j].bppmax = validmode[i].bpp; - break; - } - } - - if (j == gResolutionNum) // no match found - { - gResolution[j].xdim = validmode[i].xdim; - gResolution[j].ydim = validmode[i].ydim; - gResolution[j].bppmax = validmode[i].bpp; - gResolution[j].flags = validmode[i].fs ? RES_FS : RES_WIN; - Bsnprintf(gResolution[j].name, MAXRESOLUTIONSTRINGLENGTH, "%d x %d%s", gResolution[j].xdim, gResolution[j].ydim, (gResolution[j].flags & RES_FS) ? "" : "Win"); - gResolutionName[j] = gResolution[j].name; - ++gResolutionNum; - } - } - itemOptionsDisplayModeResolution.SetTextArray(gResolutionName, gResolutionNum, 0); -#ifdef USE_OPENGL - menuOptionsDisplayMode.Add(&itemOptionsDisplayModeRenderer, false); -#endif - menuOptionsDisplayMode.Add(&itemOptionsDisplayModeFullscreen, false); - menuOptionsDisplayMode.Add(&itemOptionsDisplayModeVSync, false); - menuOptionsDisplayMode.Add(&itemOptionsDisplayModeApply, false); - menuOptionsDisplayMode.Add(&itemBloodQAV, false); - -#ifdef USE_OPENGL - itemOptionsDisplayModeRenderer.pPreDrawCallback = PreDrawVideoModeMenu; -#endif - itemOptionsDisplayModeFullscreen.pPreDrawCallback = PreDrawVideoModeMenu; - - menuOptionsDisplayColor.Add(&itemOptionsDisplayColorTitle, false); - menuOptionsDisplayColor.Add(&itemOptionsDisplayColorGamma, true); - menuOptionsDisplayColor.Add(&itemOptionsDisplayColorContrast, false); - menuOptionsDisplayColor.Add(&itemOptionsDisplayColorBrightness, false); - menuOptionsDisplayColor.Add(&itemOptionsDisplayColorVisibility, false); - menuOptionsDisplayColor.Add(&itemOptionsDisplayColorReset, false); - menuOptionsDisplayColor.Add(&itemBloodQAV, false); - - itemOptionsDisplayColorContrast.pPreDrawCallback = PreDrawDisplayColor; - itemOptionsDisplayColorBrightness.pPreDrawCallback = PreDrawDisplayColor; - -#ifdef USE_OPENGL - menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostTitle, false); - //menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostTextureMode, true); - //menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostAnisotropy, false); - menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostTrueColorTextures, true); - menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostPreloadCache, false); - menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostDetailTex, false); - menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostGlowTex, false); - menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymost3DModels, false); - menuOptionsDisplayPolymost.Add(&itemOptionsDisplayPolymostDeliriumBlur, false); - menuOptionsDisplayPolymost.Add(&itemBloodQAV, false); - - itemOptionsDisplayPolymostPreloadCache.pPreDrawCallback = PreDrawDisplayPolymost; - itemOptionsDisplayPolymostDetailTex.pPreDrawCallback = PreDrawDisplayPolymost; - itemOptionsDisplayPolymostGlowTex.pPreDrawCallback = PreDrawDisplayPolymost; -#endif - - menuOptionsSound.Add(&itemOptionsSoundTitle, false); - menuOptionsSound.Add(&itemOptionsSoundSoundToggle, true); - menuOptionsSound.Add(&itemOptionsSoundMusicToggle, false); - menuOptionsSound.Add(&itemOptionsSound3DToggle, false); - menuOptionsSound.Add(&itemOptionsSoundSoundVolume, false); - menuOptionsSound.Add(&itemOptionsSoundMusicVolume, false); - menuOptionsSound.Add(&itemOptionsSoundSampleRate, false); - menuOptionsSound.Add(&itemOptionsSoundNumVoices, false); - menuOptionsSound.Add(&itemOptionsSoundCDToggle, false); - menuOptionsSound.Add(&itemOptionsSoundMusicDevice, false); - menuOptionsSound.Add(&itemOptionsSoundApplyChanges, false); - menuOptionsSound.Add(&itemBloodQAV, false); - - menuOptionsPlayer.Add(&itemOptionsPlayerTitle, false); - //menuOptionsPlayer.Add(&itemOptionsPlayerName, true); - menuOptionsPlayer.Add(&itemBloodQAV, false); - - menuOptionsControl.Add(&itemOptionsControlTitle, false); - menuOptionsControl.Add(&itemOptionsControlKeyboard, true); - menuOptionsControl.Add(&itemOptionsControlMouse, false); - menuOptionsControl.Add(&itemBloodQAV, false); - - menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardTitle, false); - menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardList, true); - menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardReset, false); - menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardResetClassic, false); - menuOptionsControlKeyboard.Add(&itemBloodQAV, false); - - menuOptionsControlMouse.Add(&itemOptionsControlMouseTitle, false); -// menuOptionsControlMouse.Add(&itemOptionsControlMouseButton, true); - menuOptionsControlMouse.Add(&itemOptionsControlMouseSensitivity, false); - menuOptionsControlMouse.Add(&itemOptionsControlMouseAimFlipped, false); - menuOptionsControlMouse.Add(&itemOptionsControlMouseFilterInput, false); - menuOptionsControlMouse.Add(&itemOptionsControlMouseAimMode, false); - menuOptionsControlMouse.Add(&itemOptionsControlMouseVerticalAim, false); - menuOptionsControlMouse.Add(&itemOptionsControlMouseXScale, false); - menuOptionsControlMouse.Add(&itemOptionsControlMouseYScale, false); - //menuOptionsControlMouse.Add(&itemOptionsControlMouseDigitalUp, false); - //menuOptionsControlMouse.Add(&itemOptionsControlMouseDigitalDown, false); - //menuOptionsControlMouse.Add(&itemOptionsControlMouseDigitalLeft, false); - //menuOptionsControlMouse.Add(&itemOptionsControlMouseDigitalRight, false); - //menuOptionsControlMouse.Add(&itemBloodQAV, false); - - //itemOptionsControlMouseDigitalUp.SetTextArray(pzGamefuncsStrings, NUMGAMEFUNCTIONS+1, 0); - //itemOptionsControlMouseDigitalDown.SetTextArray(pzGamefuncsStrings, NUMGAMEFUNCTIONS+1, 0); - //itemOptionsControlMouseDigitalLeft.SetTextArray(pzGamefuncsStrings, NUMGAMEFUNCTIONS+1, 0); - //itemOptionsControlMouseDigitalRight.SetTextArray(pzGamefuncsStrings, NUMGAMEFUNCTIONS+1, 0); - - itemOptionsControlMouseVerticalAim.pPreDrawCallback = PreDrawControlMouse; - - menuOptionsControlMouseButtonAssignment.Add(&itemOptionsControlMouseTitle, false); - int y = 60; - for (int i = 0; i < MENUMOUSEFUNCTIONS; i++) - { - pItemOptionsControlMouseButton[i] = new CGameMenuItemZCycle(MenuMouseNames[i], 3, 66, y, 180, 0, SetMouseButton, pzGamefuncsStrings, NUMGAMEFUNCTIONS+1, 0, true); - dassert(pItemOptionsControlMouseButton[i] != NULL); - menuOptionsControlMouseButtonAssignment.Add(pItemOptionsControlMouseButton[i], i == 0); - y += 10; - } - menuOptionsControlMouseButtonAssignment.Add(&itemBloodQAV, false); -} - -void SetupMenus(void) -{ - // prepare gamefuncs and keys - pzGamefuncsStrings[0] = MenuGameFuncNone; - nGamefuncsValues[0] = -1; - int k = 1; - for (int i = 0; i < NUMGAMEFUNCTIONS; ++i) - { - MenuGameFuncs[i] = buttonMap.GetButtonName(i); - MenuGameFuncs[i].Substitute('_', ' '); - - if (MenuGameFuncs[i][0] != '\0') - { - pzGamefuncsStrings[k] = MenuGameFuncs[i]; - nGamefuncsValues[k] = i; - ++k; - } - } - - nGamefuncsNum = k; - - SetupLoadingScreen(); - SetupKeyListMenu(); - SetupMessagesMenu(); - SetupControlsMenu(); - SetupSaveGameMenu(); - SetupLoadGameMenu(); - SetupOptionsOldMenu(); - SetupCreditsMenu(); - SetupHelpOrderMenu(); - SetupSoundsMenu(); - SetupDifficultyMenu(); - SetupEpisodeMenu(); - SetupMainMenu(); - SetupMainMenuWithSave(); - SetupNetStartMenu(); - SetupQuitMenu(); - SetupParentalLockMenu(); - SetupSorryMenu(); - SetupSorry2Menu(); - SetupSorry3Menu(); - - SetupOptionsMenu(); - SetupNetworkMenu(); -} - -void SetDoppler(CGameMenuItemZBool *pItem) -{ - snd_doppler = pItem->at20; -} - -void SetCrosshair(CGameMenuItemZBool *pItem) -{ - cl_crosshair = pItem->at20; -} - -void SetCenterHoriz(CGameMenuItemZBool *pItem) -{ - r_horizcenter = pItem->at20; -} - -void ConfigureKeys(CGameMenuItemChain*) -{ - GUICapture |= 2; -} - -void ResetKeys(CGameMenuItemChain *) -{ - CONFIG_SetDefaultKeys("demolition/defbinds.txt"); -} - -void ResetKeysClassic(CGameMenuItemChain *) -{ - CONFIG_SetDefaultKeys("demolition/origbinds.txt"); -} //// void SetWeaponsV10X(CGameMenuItemZBool* pItem) @@ -1377,63 +100,6 @@ void SetWeaponsV10X(CGameMenuItemZBool* pItem) } //// -void SetShowPlayerNames(CGameMenuItemZBool *pItem) -{ - cl_idplayers = pItem->at20; -} - -void SetShowWeapons(CGameMenuItemZCycle *pItem) -{ - cl_showweapon = pItem->m_nFocus; -} - -void SetSlopeTilting(CGameMenuItemZBool *pItem) -{ - cl_slopetilting = pItem->at20; -} - -void SetViewBobbing(CGameMenuItemZBool *pItem) -{ - cl_viewvbob = pItem->at20; -} - -void SetViewSwaying(CGameMenuItemZBool *pItem) -{ - cl_viewhbob = pItem->at20; -} - -void SetDetail(CGameMenuItemSlider *pItem) -{ - gDetail = pItem->nValue; -} - -void SetGamma(CGameMenuItemSlider *pItem) -{ - gGamma = pItem->nValue; - scrSetGamma(gGamma); -} - -void SetCDVol(CGameMenuItemSlider *pItem) -{ - UNREFERENCED_PARAMETER(pItem); - // NUKE-TODO: -} - -void SetMessages(CGameMenuItemZBool *pItem) -{ - hud_messages = pItem->at20; -} - -void SetMouseSensitivity(CGameMenuItemSliderFloat *pItem) -{ - in_mousesensitivity = pItem->fValue; -} - -void SetMouseAimFlipped(CGameMenuItemZBool *pItem) -{ - in_mouseflip = pItem->at20; -} - void SetTurnSpeed(CGameMenuItemSlider *pItem) { gTurnSpeed = pItem->nValue; @@ -1449,415 +115,6 @@ void SetAutoAim(CGameMenuItemZCycle *pItem) } } -void SetLevelStats(CGameMenuItemZBool *pItem) -{ - hud_stats = pItem->at20; -} - -void SetPowerupDuration(CGameMenuItemZBool* pItem) -{ - hud_powerupduration = pItem->at20; -} - -void SetShowMapTitle(CGameMenuItemZBool* pItem) -{ - hud_showmapname = pItem->at20; -} - -void SetWeaponSwitch(CGameMenuItemZCycle *pItem) -{ - - cl_weaponswitch = cl_weaponswitch & ~(1|2); - switch (pItem->m_nFocus) - { - case 0: - break; - case 1: - cl_weaponswitch = cl_weaponswitch | 2; - fallthrough__; - case 2: - default: - cl_weaponswitch = cl_weaponswitch | 1; - break; - } - if (!gDemo.at0 && !gDemo.at1) - { - gProfile[myconnectindex].nWeaponSwitch = cl_weaponswitch; - netBroadcastPlayerInfo(myconnectindex); - } -} - -extern bool gStartNewGame; - -void SetDifficultyAndStart(CGameMenuItemChain *pItem) -{ - gGameOptions.nDifficulty = pItem->at30; - gSkill = pItem->at30; - gGameOptions.nLevel = 0; - if (gDemo.at1) - gDemo.StopPlayback(); - gStartNewGame = true; - gCheatMgr.sub_5BCF4(); - gGameMenuMgr.Deactivate(); -} - -void SetVideoModeOld(CGameMenuItemChain *pItem) -{ - if (pItem->at30 == validmodecnt) - { - ScreenMode = 0; - ScreenWidth = 640; - ScreenHeight = 480; - } - else - { - ScreenMode = 0; - ScreenWidth = validmode[pItem->at30].xdim; - ScreenHeight = validmode[pItem->at30].ydim; - } - scrSetGameMode(ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP); - scrSetDac(); - viewResizeView(gViewSize); -} - -void SetVideoMode(CGameMenuItemChain *pItem) -{ - UNREFERENCED_PARAMETER(pItem); - resolution_t p = { xres, yres, fullscreen, bpp, 0 }; - int32_t prend = videoGetRenderMode(); - int32_t pvsync = vid_vsync; - - int32_t nResolution = itemOptionsDisplayModeResolution.m_nFocus; - resolution_t n = { gResolution[nResolution].xdim, gResolution[nResolution].ydim, - (gResolution[nResolution].flags & RES_FS) ? itemOptionsDisplayModeFullscreen.at20 : 0, - (nRendererValues[itemOptionsDisplayModeRenderer.m_nFocus] == REND_CLASSIC) ? 8 : gResolution[nResolution].bppmax, 0 }; - int32_t UNUSED(nrend) = nRendererValues[itemOptionsDisplayModeRenderer.m_nFocus]; - int32_t nvsync = nVSyncValues[itemOptionsDisplayModeVSync.m_nFocus]; - - if (videoSetGameMode(n.flags, n.xdim, n.ydim, n.bppmax, upscalefactor) < 0) - { - if (videoSetGameMode(p.flags, p.xdim, p.ydim, p.bppmax, upscalefactor) < 0) - { - videoSetRenderMode(prend); - ThrowError("Failed restoring old video mode."); - } - else - { - onvideomodechange(p.bppmax > 8); - vid_vsync = videoSetVsync(pvsync); - } - } - else onvideomodechange(n.bppmax > 8); - - viewResizeView(gViewSize); - vid_vsync = videoSetVsync(nvsync); - ScreenMode = fullscreen; - ScreenWidth = xres; - ScreenHeight = yres; - ScreenBPP = bpp; -} - -void SetWidescreen(CGameMenuItemZBool *pItem) -{ - r_usenewaspect = pItem->at20; -} - -void SetFOV(CGameMenuItemSlider *pItem) -{ - r_fov = pItem->nValue; -} - -void SetupVideoModeMenu(CGameMenuItemChain *pItem) -{ - UNREFERENCED_PARAMETER(pItem); - for (int i = 0; i < gResolutionNum; i++) - { - if (ScreenWidth == gResolution[i].xdim && ScreenHeight == gResolution[i].ydim) - { - itemOptionsDisplayModeResolution.m_nFocus = i; - break; - } - } - itemOptionsDisplayModeFullscreen.at20 = ScreenMode; -#ifdef USE_OPENGL - for (int i = 0; i < 2; i++) - { - if (videoGetRenderMode() == nRendererValues[i]) - { - itemOptionsDisplayModeRenderer.m_nFocus = i; - break; - } - } -#endif - for (int i = 0; i < 3; i++) - { - if (vid_vsync == nVSyncValues[i]) - { - itemOptionsDisplayModeVSync.m_nFocus = i; - break; - } - } -} - -void PreDrawVideoModeMenu(CGameMenuItem *pItem) -{ - if (pItem == &itemOptionsDisplayModeFullscreen) - pItem->bEnable = !!(gResolution[itemOptionsDisplayModeResolution.m_nFocus].flags & RES_FS); -#ifdef USE_OPENGL - else if (pItem == &itemOptionsDisplayModeRenderer) - pItem->bEnable = gResolution[itemOptionsDisplayModeResolution.m_nFocus].bppmax > 8; -#endif -} - -void UpdateVideoColorMenu(CGameMenuItemSliderFloat *pItem) -{ - UNREFERENCED_PARAMETER(pItem); - vid_gamma = itemOptionsDisplayColorGamma.fValue; - vid_contrast = itemOptionsDisplayColorContrast.fValue; - vid_brightness = itemOptionsDisplayColorBrightness.fValue; - r_ambientlight = itemOptionsDisplayColorVisibility.fValue; -} - -void PreDrawDisplayColor(CGameMenuItem *pItem) -{ - if (pItem == &itemOptionsDisplayColorContrast) - pItem->bEnable = 1; - else if (pItem == &itemOptionsDisplayColorBrightness) - pItem->bEnable = 1; -} - -void ResetVideoColor(CGameMenuItemChain *pItem) -{ - UNREFERENCED_PARAMETER(pItem); - vid_gamma = 1.f; - vid_contrast = 1.f; - vid_brightness = 0.f; - r_ambientlight = 1.f; -} - -#ifdef USE_OPENGL -void SetupVideoPolymostMenu(CGameMenuItemChain *pItem) -{ - UNREFERENCED_PARAMETER(pItem); - itemOptionsDisplayPolymostTextureMode.m_nFocus = 0; - for (int i = 0; i < 2; i++) - { - if (nTextureModeValues[i] == hw_texfilter) - { - itemOptionsDisplayPolymostTextureMode.m_nFocus = i; - break; - } - } - itemOptionsDisplayPolymostAnisotropy.m_nFocus = 0; - for (int i = 0; i < 6; i++) - { - if (nAnisotropyValues[i] == hw_anisotropy) - { - itemOptionsDisplayPolymostAnisotropy.m_nFocus = i; - break; - } - } - itemOptionsDisplayPolymostTrueColorTextures.at20 = hw_hightile; - itemOptionsDisplayPolymostPreloadCache.at20 = r_precache; - itemOptionsDisplayPolymostDetailTex.at20 = hw_detailmapping; - itemOptionsDisplayPolymostGlowTex.at20 = hw_glowmapping; - itemOptionsDisplayPolymost3DModels.at20 = hw_models; - itemOptionsDisplayPolymostDeliriumBlur.at20 = gDeliriumBlur; -} - -void UpdateTextureMode(CGameMenuItemZCycle *pItem) -{ - hw_texfilter = nTextureModeValues[pItem->m_nFocus]; - gltexapplyprops(); -} - -void UpdateAnisotropy(CGameMenuItemZCycle *pItem) -{ - hw_anisotropy = nAnisotropyValues[pItem->m_nFocus]; - gltexapplyprops(); -} - -void UpdateTrueColorTextures(CGameMenuItemZBool *pItem) -{ - hw_hightile = pItem->at20; -} -#endif - -void DoModeChange(void) -{ - videoResetMode(); - if (videoSetGameMode(fullscreen, xres, yres, bpp, upscalefactor)) - OSD_Printf("restartvid: Reset failed...\n"); - onvideomodechange(ScreenBPP > 8); -} - -#ifdef USE_OPENGL -void UpdatePreloadCache(CGameMenuItemZBool *pItem) -{ - r_precache = pItem->at20; -} - -void UpdateDetailTex(CGameMenuItemZBool *pItem) -{ - hw_detailmapping = pItem->at20; -} - -void UpdateGlowTex(CGameMenuItemZBool *pItem) -{ - hw_glowmapping = pItem->at20; -} - -void Update3DModels(CGameMenuItemZBool *pItem) -{ - hw_models = pItem->at20; -} - -void UpdateDeliriumBlur(CGameMenuItemZBool *pItem) -{ - gDeliriumBlur = pItem->at20; -} - -void PreDrawDisplayPolymost(CGameMenuItem *pItem) -{ - if (pItem == &itemOptionsDisplayPolymostPreloadCache) - pItem->bEnable = hw_hightile; - else if (pItem == &itemOptionsDisplayPolymostDetailTex) - pItem->bEnable = hw_hightile; - else if (pItem == &itemOptionsDisplayPolymostGlowTex) - pItem->bEnable = hw_hightile; -} -#endif - -void UpdateSoundToggle(CGameMenuItemZBool *pItem) -{ - snd_enabled = pItem->at20; - if (!SoundEnabled()) - FX_StopAllSounds(); -} - -void UpdateMusicToggle(CGameMenuItemZBool *pItem) -{ - mus_enabled = pItem->at20; -} - -void Update3DToggle(CGameMenuItemZBool *pItem) -{ - snd_doppler = pItem->at20; -} - -void UpdateCDToggle(CGameMenuItemZBool *pItem) -{ - mus_redbook = pItem->at20; - if (gGameStarted || gDemo.at1) - levelTryPlayMusicOrNothing(gGameOptions.nEpisode, gGameOptions.nLevel); -} - -void UpdateSoundVolume(CGameMenuItemSlider *pItem) -{ - sndSetFXVolume(pItem->nValue); -} -void UpdateSoundRate(CGameMenuItemZCycle *pItem) -{ - UNREFERENCED_PARAMETER(pItem); -} - -void UpdateNumVoices(CGameMenuItemSlider *pItem) -{ - UNREFERENCED_PARAMETER(pItem); -} - -void UpdateMusicDevice(CGameMenuItemZCycle *pItem) -{ - UNREFERENCED_PARAMETER(pItem); -} - -void SetSound(CGameMenuItemChain *pItem) -{ - UNREFERENCED_PARAMETER(pItem); - snd_mixrate = nSoundRateValues[itemOptionsSoundSampleRate.m_nFocus]; - snd_numvoices = itemOptionsSoundNumVoices.nValue; - mus_device = nMusicDeviceValues[itemOptionsSoundMusicDevice.m_nFocus]; - sfxTerm(); - sndTerm(); - - sndInit(); - sfxInit(); -} - -void PreDrawSound(CGameMenuItem *pItem) -{ - UNREFERENCED_PARAMETER(pItem); -} - -void SetupOptionsSound(CGameMenuItemChain *pItem) -{ - UNREFERENCED_PARAMETER(pItem); - itemOptionsSoundSoundToggle.at20 = snd_enabled; - itemOptionsSoundMusicToggle.at20 = mus_enabled; - itemOptionsSound3DToggle.at20 = snd_doppler; - itemOptionsSoundCDToggle.at20 = mus_redbook; - itemOptionsSoundSampleRate.m_nFocus = 0; - for (int i = 0; i < 3; i++) - { - if (nSoundRateValues[i] == snd_mixrate) - { - itemOptionsSoundSampleRate.m_nFocus = i; - break; - } - } - itemOptionsSoundNumVoices.nValue = snd_numvoices; - itemOptionsSoundMusicDevice.m_nFocus = 0; - for (int i = 0; i < ARRAY_SIZE(nMusicDeviceValues); i++) - { - if (nMusicDeviceValues[i] == MusicDevice) - { - itemOptionsSoundMusicDevice.m_nFocus = i; - break; - } - } -} - -void UpdatePlayerName(CGameMenuItemZEdit *pItem, CGameMenuEvent *pEvent) -{ - UNREFERENCED_PARAMETER(pItem); - if (pEvent->at0 == kMenuEventEnter) - netBroadcastPlayerInfo(myconnectindex); -} - -void SetMouseFilterInput(CGameMenuItemZBool *pItem) -{ - in_mousesmoothing = pItem->at20; -} - -void SetMouseVerticalAim(CGameMenuItemZBool *pItem) -{ - in_mousemode = pItem->at20; -} - -void SetMouseXScale(CGameMenuItemSlider *pItem) -{ - in_mousescalex = pItem->nValue; -} - -void SetMouseYScale(CGameMenuItemSlider *pItem) -{ - in_mousescaley = pItem->nValue; -} - -void SetMouseDigitalAxis(CGameMenuItemZCycle *pItem) -{ -} - -void SetMouseButton(CGameMenuItemZCycle *pItem) -{ -} - -void SetupMouseButtonMenu(CGameMenuItemChain *pItem) -{ - UNREFERENCED_PARAMETER(pItem); - // This functionality no longer exists as a separate item. -} - void SetupNetworkMenu(void) { sprintf(zNetPortBuffer, "%d", gNetPort); @@ -1924,91 +181,6 @@ void NetworkJoinGame(CGameMenuItemChain *pItem) gQuitGame = gRestartGame = true; } -void SaveGameProcess(CGameMenuItemChain *pItem) -{ - UNREFERENCED_PARAMETER(pItem); -} - -void TenProcess(CGameMenuItem7EA1C *pItem) -{ - UNREFERENCED_PARAMETER(pItem); -} - -void SaveGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event) -{ - int nSlot = pItem->at28; - if (gGameOptions.nGameType > 0 || !gGameStarted) - return; - if (event->at0 != 6/* || strSaveGameName[0]*/) - { - gGameMenuMgr.Deactivate(); - return; - } - FStringf basename("save%04d", nSlot); - auto strSaveGameName = G_BuildSaveName(basename); - gGameOptions.nSaveGameSlot = nSlot; - viewLoadingScreen(2518, "Saving", "Saving Your Game", strRestoreGameStrings[nSlot]); - videoNextPage(); - gSaveGameNum = nSlot; - LoadSave::SaveGame(strSaveGameName.GetChars()); - gGameMenuMgr.Deactivate(); -} - -void LoadGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event) -{ - UNREFERENCED_PARAMETER(event); - int nSlot = pItem->at28; - if (gGameOptions.nGameType > 0) - return; - FStringf basename("save%04d", nSlot); - auto strLoadGameName = G_BuildSaveName(basename); - if (!FileExists(strLoadGameName)) - return; - viewLoadingScreen(2518, "Loading", "Loading Saved Game", strRestoreGameStrings[nSlot]); - videoNextPage(); - LoadSave::LoadGame(strLoadGameName); - gGameMenuMgr.Deactivate(); -} - -void SetupLevelMenuItem(int nEpisode) -{ - dassert(nEpisode >= 0 && nEpisode < gEpisodeCount); - itemNetStart3.SetTextArray(zLevelNames[nEpisode], gEpisodeInfo[nEpisode].nLevels, 0); -} - -void SetupNetLevels(CGameMenuItemZCycle *pItem) -{ - SetupLevelMenuItem(pItem->m_nFocus); -} - -void StartNetGame(CGameMenuItemChain *pItem) -{ - UNREFERENCED_PARAMETER(pItem); - gPacketStartGame.gameType = itemNetStart1.m_nFocus+1; - if (gPacketStartGame.gameType == 0) - gPacketStartGame.gameType = 2; - gPacketStartGame.episodeId = itemNetStart2.m_nFocus; - gPacketStartGame.levelId = itemNetStart3.m_nFocus; - gPacketStartGame.difficulty = itemNetStart4.m_nFocus; - gPacketStartGame.monsterSettings = itemNetStart5.m_nFocus; - gPacketStartGame.weaponSettings = itemNetStart6.m_nFocus; - gPacketStartGame.itemSettings = itemNetStart7.m_nFocus; - gPacketStartGame.respawnSettings = 0; - gPacketStartGame.bFriendlyFire = itemNetStart8.at20; - gPacketStartGame.bKeepKeysOnRespawn = itemNetStart9.at20; - //// - gPacketStartGame.weaponsV10x = itemNetStart10.at20; - //// - gPacketStartGame.unk = 0; - gPacketStartGame.userMapName[0] = 0; - strncpy(gPacketStartGame.userMapName, itemNetStart11.at20, 13); - gPacketStartGame.userMapName[12] = 0; - gPacketStartGame.userMap = gPacketStartGame.userMapName[0] != 0; - - netBroadcastNewGame(); - gStartNewGame = 1; - gGameMenuMgr.Deactivate(); -} void Restart(CGameMenuItemChain *pItem) { @@ -2023,43 +195,7 @@ void Restart(CGameMenuItemChain *pItem) gGameMenuMgr.Deactivate(); } -void Quit(CGameMenuItemChain *pItem) -{ - UNREFERENCED_PARAMETER(pItem); - if (gGameOptions.nGameType == 0 || numplayers == 1) - gQuitGame = true; - else - gQuitRequest = 1; - gGameMenuMgr.Deactivate(); -} -void SetParentalLock(CGameMenuItemZBool *pItem) -{ - if (!pItem->at20) - { - pItem->at20 = true; - pItem->Draw(); - if (strcmp(itemParentalLockPassword.at20, "")) - { - itemParentalLockPassword.pMenu->FocusNextItem(); - itemParentalLockPassword.at32 = 0; - itemParentalLockPassword.at37 = 1; - itemParentalLockPassword.at5f = pItem; - itemParentalLockPassword.at29[0] = 0; - return; - } - else - { - itemParentalLockPassword.at20[0] = 0; - pItem->Draw(); - gbAdultContent = false; - } - } - else - gbAdultContent = true; - // NUKE-TODO: CONFIG_WriteAdultMode(); -} #endif -END_BLD_NS diff --git a/source/blood/src/menu.h b/source/blood/src/menu.h deleted file mode 100644 index cdc90f0af..000000000 --- a/source/blood/src/menu.h +++ /dev/null @@ -1,62 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2010-2019 EDuke32 developers and contributors -Copyright (C) 2019 Nuke.YKT - -This file is part of NBlood. - -NBlood is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. - -This program 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 this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- -#pragma once -#include "gamemenu.h" - -BEGIN_BLD_NS - -#if 0 - -extern CGameMenu menuMain; -extern CGameMenu menuMainWithSave; -extern CGameMenu menuNetMain; -extern CGameMenu menuNetStart; -extern CGameMenu menuEpisode; -extern CGameMenu menuDifficulty; -extern CGameMenu menuOptionsOld; -extern CGameMenu menuControls; -extern CGameMenu menuMessages; -extern CGameMenu menuKeys; -extern CGameMenu menuSaveGame; -extern CGameMenu menuLoadGame; -extern CGameMenu menuLoading; -extern CGameMenu menuSounds; -extern CGameMenu menuQuit; -extern CGameMenu menuRestart; -extern CGameMenu menuCredits; -extern CGameMenu menuOrder; -extern CGameMenu menuPlayOnline; -extern CGameMenu menuParentalLock; -extern CGameMenu menuSorry; -extern CGameMenu menuSorry2; - -extern CGameMenu menuOptions; -extern CGameMenu menuOptionsSound; -extern CGameMenu menuOptionsDisplayMode; -extern char strRestoreGameStrings[][16]; -void drawLoadingScreen(void); -void SetupMenus(void); - -#endif - -END_BLD_NS diff --git a/source/blood/src/network.cpp b/source/blood/src/network.cpp index 0310bfb4f..6da2b56ad 100644 --- a/source/blood/src/network.cpp +++ b/source/blood/src/network.cpp @@ -33,7 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "controls.h" #include "globals.h" #include "network.h" -#include "menu.h" +#include "gamemenu.h" #include "player.h" #include "seq.h" #include "sound.h" diff --git a/source/common/gamecvars.h b/source/common/gamecvars.h index 52aedcbe7..45463e313 100644 --- a/source/common/gamecvars.h +++ b/source/common/gamecvars.h @@ -47,7 +47,6 @@ EXTERN_CVAR(Int, snd_numchannels) EXTERN_CVAR(Int, snd_numvoices) EXTERN_CVAR(Int, snd_speech) EXTERN_CVAR(Int, mus_device) -extern int MusicDevice; EXTERN_CVAR(Int, hud_layout) EXTERN_CVAR(Int, hud_scale) diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index e6b737fa2..172aaf806 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -44,7 +44,7 @@ #include "printf.h" #include "gamecontrol.h" #include "cmdlib.h" - +#include "c_cvars.h" #include "optionmenuitems.h" // Menu-relevant content that gets filled in by scripts. This will get processed after the game has loaded. @@ -872,6 +872,18 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) FOptionMenuItem *it = new FOptionMenuItemSubmenu(label, sc.String); desc->mItems.Push(it); } + else if (sc.Compare("LabeledSubmenu")) + { + sc.MustGetString(); + FString label = sc.String; + sc.MustGetStringName(","); + sc.MustGetString(); + auto cvar = FindCVar(sc.String, nullptr); + sc.MustGetStringName(","); + sc.MustGetString(); + FOptionMenuItem* it = new FOptionMenuItemLabeledSubmenu(label, cvar, sc.String); + desc->mItems.Push(it); + } else if (sc.Compare("Option")) { sc.MustGetString(); diff --git a/source/common/menu/optionmenuitems.h b/source/common/menu/optionmenuitems.h index f3c1cc889..9de745e97 100644 --- a/source/common/menu/optionmenuitems.h +++ b/source/common/menu/optionmenuitems.h @@ -82,6 +82,7 @@ public: class FOptionMenuItemLabeledSubmenu : public FOptionMenuItemSubmenu { FBaseCVar *mLabelCVar; +public: FOptionMenuItemLabeledSubmenu(const char * label, FBaseCVar *labelcvar, FName command, int param = 0) : FOptionMenuItemSubmenu(label, command, param) { @@ -92,7 +93,7 @@ class FOptionMenuItemLabeledSubmenu : public FOptionMenuItemSubmenu { drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor); - auto text = mLabelCVar->GetHumanString(); + auto text = mLabelCVar? mLabelCVar->GetHumanString() : ""; if (text[0] == 0) text = GStrings("notset"); drawValue(indent, y, OptionSettings.mFontColorValue, text); return indent; diff --git a/source/common/music/backend/i_sound.cpp b/source/common/music/backend/i_sound.cpp index 6cbda4a95..996e75bbe 100644 --- a/source/common/music/backend/i_sound.cpp +++ b/source/common/music/backend/i_sound.cpp @@ -53,6 +53,7 @@ #include "zmusic/zmusic.h" EXTERN_CVAR (Float, snd_sfxvolume) +EXTERN_CVAR(Float, mus_volume) CVAR (Int, snd_samplerate, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Int, snd_buffersize, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Int, snd_hrtf, -1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) diff --git a/source/common/music/i_music.cpp b/source/common/music/i_music.cpp index 88023cee0..23547764a 100644 --- a/source/common/music/i_music.cpp +++ b/source/common/music/i_music.cpp @@ -82,7 +82,8 @@ void I_InitMusicWin32(); // let the operating system decide for us. // //========================================================================== -EXTERN_CVAR(Bool, cd_enabled); +EXTERN_CVAR(Bool, cd_enabled); +EXTERN_CVAR(Float, snd_mastervolume) CUSTOM_CVAR(String, cd_drive, "", CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALCONFIG) { @@ -125,7 +126,7 @@ CUSTOM_CVARD(Float, mus_volume, 0.5, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "controls m ChangeMusicSetting(ZMusic::snd_musicvolume, nullptr, self); if (GSnd != nullptr) { - GSnd->SetMusicVolume(clamp(self * relative_volume/* * snd_mastervolume*/, 0, 1)); + GSnd->SetMusicVolume(clamp(self * relative_volume * snd_mastervolume, 0, 1)); } // For music not implemented through the digital sound system, // let them know about the change. diff --git a/source/common/music/music.cpp b/source/common/music/music.cpp index 2a06e6fe0..5b9540ad9 100644 --- a/source/common/music/music.cpp +++ b/source/common/music/music.cpp @@ -79,6 +79,7 @@ MusicAliasMap LevelMusicAliases; bool MusicPaused; static bool mus_blocked; static FString lastStartedMusic; +EXTERN_CVAR(Float, mus_volume) //========================================================================== // diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index 94c7802cf..3b2d343da 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -47,336 +47,6 @@ BEGIN_DUKE_NS #if 0 -// common positions -#define MENU_MARGIN_REGULAR 40 -#define MENU_MARGIN_WIDE 32 -#define MENU_MARGIN_CENTER 160 -#define MENU_HEIGHT_CENTER 100 - -#define USERMAPENTRYLENGTH 25 - - -/* -MenuEntry_t is passed in arrays of pointers so that the callback function -that is called when an entry is modified or activated can test equality of the current -entry pointer directly against the known ones, instead of relying on an ID number. - -That way, individual menu entries can be ifdef'd out painlessly. -*/ - - -// Zhe menu code lacks flexibility, it can either be hardwired to ints or to CVARs. -// Since CVARs are more important it means that these need to be implemented as CVARs even though they are just temporaries. -// By giving them no name we ensure that they remain outside the CVAR system. -CVAR_UNAMED(Int, newresolution) -CVAR_UNAMED(Int, newrendermode) -CVAR_UNAMED(Int, newfullscreen) -CVAR_UNAMED(Int, newvsync) -CVAR_UNAMED(Int, newborderless) - -enum resflags_t { - RES_FS = 0x1, - RES_WIN = 0x2, -}; - -#define MAXRESOLUTIONSTRINGLENGTH 19 - -typedef struct resolution_t { - int32_t xdim, ydim; - int32_t flags; - int32_t bppmax; - char name[MAXRESOLUTIONSTRINGLENGTH]; -} resolution_t; - -resolution_t resolution[MAXVALIDMODES]; - -static char const *MEOSN_VIDEOSETUP_RESOLUTION[MAXVALIDMODES]; -static MenuOptionSet_t MEOS_VIDEOSETUP_RESOLUTION = MAKE_MENUOPTIONSETDYN( MEOSN_VIDEOSETUP_RESOLUTION, NULL, 0, 0x0 ); -static MenuOption_t MEO_VIDEOSETUP_RESOLUTION = MAKE_MENUOPTION( &MF_Redfont, &MEOS_VIDEOSETUP_RESOLUTION, &newresolution ); -static MenuEntry_t ME_VIDEOSETUP_RESOLUTION = MAKE_MENUENTRY( "Resolution:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_VIDEOSETUP_RESOLUTION, Option ); - -#ifdef USE_OPENGL -static char const *MEOSN_VIDEOSETUP_RENDERER[] = { "Classic", "OpenGL", }; -static int32_t MEOSV_VIDEOSETUP_RENDERER[] = { REND_CLASSIC, REND_POLYMOST, }; - -static MenuOptionSet_t MEOS_VIDEOSETUP_RENDERER = MAKE_MENUOPTIONSET( MEOSN_VIDEOSETUP_RENDERER, MEOSV_VIDEOSETUP_RENDERER, 0x2 ); - -static MenuOption_t MEO_VIDEOSETUP_RENDERER = MAKE_MENUOPTION( &MF_Redfont, &MEOS_VIDEOSETUP_RENDERER, &newrendermode ); -static MenuEntry_t ME_VIDEOSETUP_RENDERER = MAKE_MENUENTRY( "Renderer:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_VIDEOSETUP_RENDERER, Option ); -#endif - -static MenuOption_t MEO_VIDEOSETUP_FULLSCREEN = MAKE_MENUOPTION( &MF_Redfont, &MEOS_YesNo, &newfullscreen ); -static MenuEntry_t ME_VIDEOSETUP_FULLSCREEN = MAKE_MENUENTRY( "Windowed:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_VIDEOSETUP_FULLSCREEN, Option ); - -static char const *MEOSN_VIDEOSETUP_BORDERLESS [] = { "No", "Yes", "Auto", }; -static int32_t MEOSV_VIDEOSETUP_BORDERLESS [] = { 0, 1, 2, }; -static MenuOptionSet_t MEOS_VIDEOSETUP_BORDERLESS = MAKE_MENUOPTIONSET(MEOSN_VIDEOSETUP_BORDERLESS, MEOSV_VIDEOSETUP_BORDERLESS, 0x2); -static MenuOption_t MEO_VIDEOSETUP_BORDERLESS = MAKE_MENUOPTION(&MF_Redfont, &MEOS_VIDEOSETUP_BORDERLESS, &newborderless); -static MenuEntry_t ME_VIDEOSETUP_BORDERLESS = MAKE_MENUENTRY("Borderless:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_VIDEOSETUP_BORDERLESS, Option); - -static char const *MEOSN_VIDEOSETUP_VSYNC [] = { "Adaptive", "Off", "On", }; -static int32_t MEOSV_VIDEOSETUP_VSYNC [] = { -1, 0, 1, }; -static MenuOptionSet_t MEOS_VIDEOSETUP_VSYNC = MAKE_MENUOPTIONSET(MEOSN_VIDEOSETUP_VSYNC, MEOSV_VIDEOSETUP_VSYNC, 0x2); -static MenuOption_t MEO_VIDEOSETUP_VSYNC = MAKE_MENUOPTION(&MF_Redfont, &MEOS_VIDEOSETUP_VSYNC, &newvsync); -static MenuEntry_t ME_VIDEOSETUP_VSYNC = MAKE_MENUENTRY("VSync:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_VIDEOSETUP_VSYNC, Option); - - - -//static char const *MEOSN_VIDEOSETUP_FRAMELIMIT [] = { "None", "30 fps", "60 fps", "75 fps", "100 fps", "120 fps", "144 fps", "165 fps", "240 fps" }; - -static MenuEntry_t ME_VIDEOSETUP_APPLY = MAKE_MENUENTRY( "Apply Changes", &MF_Redfont, &MEF_BigOptions_Apply, &MEO_NULL, Link ); - - - - - -#ifdef USE_OPENGL -static MenuLink_t MEO_DISPLAYSETUP_ADVANCED_GL_POLYMOST = { MENU_POLYMOST, MA_Advance, }; -static MenuEntry_t ME_DISPLAYSETUP_ADVANCED_GL_POLYMOST = MAKE_MENUENTRY( "Polymost setup", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_ADVANCED_GL_POLYMOST, Link ); -#endif - -#ifndef EDUKE32_ANDROID_MENU -static MenuLink_t MEO_DISPLAYSETUP_VIDEOSETUP = { MENU_VIDEOSETUP, MA_Advance, }; -static MenuEntry_t ME_DISPLAYSETUP_VIDEOSETUP = MAKE_MENUENTRY( "Video mode", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_VIDEOSETUP, Link ); -#endif - - -}; - -static MenuEntry_t *MEL_OPTIONS[] = { -#ifndef EDUKE32_SIMPLE_MENU - &ME_OPTIONS_GAMESETUP, -#endif - &ME_OPTIONS_DISPLAYSETUP, - &ME_OPTIONS_SOUNDSETUP, -#ifndef EDUKE32_ANDROID_MENU -#ifndef EDUKE32_SIMPLE_MENU - &ME_OPTIONS_PLAYERSETUP, -#endif - &ME_OPTIONS_CONTROLS, -#else - &ME_OPTIONS_TOUCHSETUP, -#endif -#ifdef EDUKE32_SIMPLE_MENU - &ME_GAMESETUP_SAVESETUP, - &ME_OPTIONS_CHEATS -#endif -}; - -static MenuEntry_t *MEL_CONTROLS[] = { -#ifndef EDUKE32_ANDROID_MENU - &ME_OPTIONS_KEYBOARDSETUP, - &ME_OPTIONS_MOUSESETUP, - &ME_OPTIONS_JOYSTICKSETUP, -#else - &ME_OPTIONS_TOUCHSETUP, -#endif - &ME_Space6_Redfont, - &ME_GAMESETUP_AIM_AUTO, - &ME_GAMESETUP_ALWAYS_RUN, - &ME_GAMESETUP_WEAPSWITCH_PICKUP, -#ifdef EDUKE32_ANDROID_MENU - &ME_GAMESETUP_QUICKSWITCH, - &ME_GAMESETUP_CROUCHLOCK, -#endif -}; - -static MenuEntry_t *MEL_CHEATS[ARRAY_SIZE(ME_CheatCodes)+1] = { - &ME_ENTERCHEAT, -}; - -static MenuEntry_t *MEL_VIDEOSETUP[] = { - &ME_VIDEOSETUP_RESOLUTION, -#ifdef USE_OPENGL - &ME_VIDEOSETUP_RENDERER, -#endif - &ME_VIDEOSETUP_FULLSCREEN, - &ME_VIDEOSETUP_BORDERLESS, - &ME_VIDEOSETUP_VSYNC, - &ME_Space4_Redfont, - &ME_VIDEOSETUP_APPLY, -}; -static MenuEntry_t *MEL_DISPLAYSETUP[] = { - &ME_DISPLAYSETUP_SCREENSETUP, - &ME_DISPLAYSETUP_COLORCORR, -#ifndef EDUKE32_ANDROID_MENU - &ME_DISPLAYSETUP_VIDEOSETUP, - &ME_DISPLAYSETUP_ASPECTRATIO, - &ME_DISPLAYSETUP_VOXELS, - &ME_DISPLAYSETUP_FOV, -#endif -}; - -#ifdef USE_OPENGL -static MenuEntry_t *MEL_DISPLAYSETUP_GL[] = { - &ME_DISPLAYSETUP_SCREENSETUP, - &ME_DISPLAYSETUP_COLORCORR, - &ME_DISPLAYSETUP_VIDEOSETUP, - &ME_DISPLAYSETUP_ASPECTRATIO, - &ME_DISPLAYSETUP_VOXELS, - &ME_DISPLAYSETUP_FOV, - &ME_DISPLAYSETUP_TEXFILTER, - &ME_DISPLAYSETUP_ANISOTROPY, - &ME_DISPLAYSETUP_ADVANCED_GL_POLYMOST, -#endif -}; - - - - - - -#ifdef USE_OPENGL -static MenuEntry_t *MEL_RENDERERSETUP_POLYMOST[] = { - &ME_RENDERERSETUP_HIGHTILE, - &ME_RENDERERSETUP_PRECACHE, -# ifdef USE_GLEXT - &ME_RENDERERSETUP_DETAILTEX, - &ME_RENDERERSETUP_GLOWTEX, -# endif - &ME_Space4_Bluefont, - &ME_RENDERERSETUP_MODELS, -}; - -#endif - -#ifdef EDUKE32_ANDROID_MENU -#define MINVIS 1.f -#else -#define MINVIS 0.125f -#endif -#ifndef EDUKE32_SIMPLE_MENU -static MenuRangeFloat_t MEO_COLCORR_AMBIENT = MAKE_MENURANGE( &r_ambientlight, &MF_Bluefont, MINVIS, 4.f, 0.f, 32, 1 ); -static MenuEntry_t ME_COLCORR_AMBIENT = MAKE_MENUENTRY( "Visibility:", &MF_Redfont, &MEF_ColorCorrect, &MEO_COLCORR_AMBIENT, RangeFloat ); -#endif -static MenuEntry_t *MEL_COLCORR[] = { - &ME_COLCORR_GAMMA, -#ifndef EDUKE32_ANDROID_MENU - &ME_COLCORR_CONTRAST, - &ME_COLCORR_BRIGHTNESS, -#endif -#ifndef EDUKE32_SIMPLE_MENU - &ME_COLCORR_AMBIENT, -#endif - &ME_Space8_Redfont, - &ME_COLCORR_RESET, -}; - -static MenuEntry_t *MEL_SCREENSETUP[] = { -#ifdef EDUKE32_ANDROID_MENU - &ME_SCREENSETUP_STATUSBARONTOP, -#endif - &ME_SCREENSETUP_SCREENSIZE, - &ME_SCREENSETUP_SBARSIZE, - - &ME_SCREENSETUP_CROSSHAIR, - &ME_SCREENSETUP_CROSSHAIRSIZE, - - &ME_SCREENSETUP_LEVELSTATS, - &ME_SCREENSETUP_TEXTSIZE, - - &ME_SCREENSETUP_SHOWPICKUPMESSAGES, -}; - -CVAR_UNAMED(Int, soundrate) -CVAR_UNAMED(Int, soundvoices) -CVAR_UNAMED(Int, musicdevice) -static MenuOption_t MEO_SOUND = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &snd_enabled ); -static MenuEntry_t ME_SOUND = MAKE_MENUENTRY( "Sound:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND, Option ); - -static MenuOption_t MEO_SOUND_MUSIC = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &mus_enabled ); -static MenuEntry_t ME_SOUND_MUSIC = MAKE_MENUENTRY( "Music:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_MUSIC, Option ); - -static char const s_Volume[] = "Volume:"; - -static MenuRangeInt32_t MEO_SOUND_VOLUME_FX = MAKE_MENURANGE( &snd_fxvolume, &MF_Redfont, 0, 255, 0, 33, 2 ); -static MenuEntry_t ME_SOUND_VOLUME_FX = MAKE_MENUENTRY( s_Volume, &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SOUND_VOLUME_FX, RangeInt32 ); - -static MenuEntry_t ME_SOUND_VOLUME_MUSIC = MAKE_MENUENTRY( s_Volume, &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SOUND_VOLUME_MUSIC, RangeInt32 ); - -#ifndef EDUKE32_STANDALONE -static MenuOption_t MEO_SOUND_DUKETALK = MAKE_MENUOPTION(&MF_Redfont, &MEOS_NoYes, NULL); -static MenuEntry_t ME_SOUND_DUKETALK = MAKE_MENUENTRY( "Duke talk:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_DUKETALK, Option ); -#else -static MenuOption_t MEO_SOUND_DUKETALK = MAKE_MENUOPTION(&MF_Redfont, &MEOS_YesNo, NULL); -static MenuEntry_t ME_SOUND_DUKETALK = MAKE_MENUENTRY("Silent protagonist:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_DUKETALK, Option); -#endif - -static char const *MEOSN_SOUND_SAMPLINGRATE[] = { "22050Hz", "44100Hz", "48000Hz", }; -static int32_t MEOSV_SOUND_SAMPLINGRATE[] = { 22050, 44100, 48000, }; -static MenuOptionSet_t MEOS_SOUND_SAMPLINGRATE = MAKE_MENUOPTIONSET( MEOSN_SOUND_SAMPLINGRATE, MEOSV_SOUND_SAMPLINGRATE, 0x3 ); -static MenuOption_t MEO_SOUND_SAMPLINGRATE = MAKE_MENUOPTION( &MF_Redfont, &MEOS_SOUND_SAMPLINGRATE, &soundrate ); -static MenuEntry_t ME_SOUND_SAMPLINGRATE = MAKE_MENUENTRY( "Sample rate:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_SAMPLINGRATE, Option ); - -#ifndef EDUKE32_SIMPLE_MENU -static MenuRangeInt32_t MEO_SOUND_NUMVOICES = MAKE_MENURANGE( &soundvoices, &MF_Redfont, 16, 128, 0, 8, 1 ); -static MenuEntry_t ME_SOUND_NUMVOICES = MAKE_MENUENTRY( "Voices:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_NUMVOICES, RangeInt32 ); -#endif - -static char const *MEOSN_SOUND_MIDIDRIVER[] = { - "OPL3", -#ifdef _WIN32 - "Windows", -#endif -}; -static int32_t MEOSV_SOUND_MIDIDRIVER[] = { - ASS_OPL3, -#ifdef _WIN32 - ASS_WinMM, -#endif -}; - -static MenuOptionSet_t MEOS_SOUND_MIDIDRIVER = MAKE_MENUOPTIONSET( MEOSN_SOUND_MIDIDRIVER, MEOSV_SOUND_MIDIDRIVER, 0x2 ); -static MenuOption_t MEO_SOUND_MIDIDRIVER = MAKE_MENUOPTION( &MF_Redfont, &MEOS_SOUND_MIDIDRIVER, &musicdevice ); -static MenuEntry_t ME_SOUND_MIDIDRIVER = MAKE_MENUENTRY( "MIDI driver:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_MIDIDRIVER, Option ); - -static MenuEntry_t ME_SOUND_RESTART = MAKE_MENUENTRY( "Apply Changes", &MF_Redfont, &MEF_BigOptions_Apply, &MEO_NULL, Link ); - -#ifndef EDUKE32_SIMPLE_MENU -static MenuLink_t MEO_ADVSOUND = { MENU_ADVSOUND, MA_Advance, }; -static MenuEntry_t ME_SOUND_ADVSOUND = MAKE_MENUENTRY( "Advanced", &MF_Redfont, &MEF_BigOptionsRt, &MEO_ADVSOUND, Link ); -#endif - -static MenuEntry_t *MEL_SOUND[] = { - &ME_SOUND, - &ME_SOUND_VOLUME_FX, - &ME_SOUND_MUSIC, - &ME_SOUND_VOLUME_MUSIC, - &ME_SOUND_DUKETALK, -#ifndef EDUKE32_SIMPLE_MENU - &ME_SOUND_ADVSOUND, -#endif -}; - -static MenuEntry_t *MEL_ADVSOUND[] = { - &ME_SOUND_SAMPLINGRATE, - &ME_Space2_Redfont, -#ifndef EDUKE32_SIMPLE_MENU - &ME_SOUND_NUMVOICES, - &ME_Space2_Redfont, -#endif - &ME_SOUND_MIDIDRIVER, - &ME_SOUND_RESTART, -}; - - -static MenuOption_t MEO_SAVESETUP_AUTOSAVE = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &cl_autosave ); -static MenuEntry_t ME_SAVESETUP_AUTOSAVE = MAKE_MENUENTRY( "Checkpoints:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SAVESETUP_AUTOSAVE, Option ); - -static MenuOption_t MEO_SAVESETUP_AUTOSAVEDELETION = MAKE_MENUOPTION( &MF_Redfont, &MEOS_NoYes, &cl_autosavedeletion ); -static MenuEntry_t ME_SAVESETUP_AUTOSAVEDELETION = MAKE_MENUENTRY( "Auto-Delete:", &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SAVESETUP_AUTOSAVEDELETION, Option ); -static MenuRangeInt32_t MEO_SAVESETUP_MAXAUTOSAVES = MAKE_MENURANGE( &cl_maxautosaves, &MF_Redfont, 1, 10, 0, 10, 1 ); -static MenuEntry_t ME_SAVESETUP_MAXAUTOSAVES = MAKE_MENUENTRY( "Limit:", &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SAVESETUP_MAXAUTOSAVES, RangeInt32 ); - -static MenuEntry_t ME_SAVESETUP_CLEANUP = MAKE_MENUENTRY( "Clean Up Saves", &MF_Redfont, &MEF_BigOptionsRt, &MEO_NULL, Link ); - -static MenuEntry_t *MEL_SAVESETUP[] = { - &ME_SAVESETUP_AUTOSAVE, - &ME_SAVESETUP_AUTOSAVEDELETION, - &ME_SAVESETUP_MAXAUTOSAVES, - &ME_SAVESETUP_CLEANUP, -}; - void Menu_Init(void) { int32_t i, j, k; @@ -399,96 +69,11 @@ void Menu_Init(void) MenuEntry_DisableOnCondition(&ME_NETOPTIONS_EPISODE, 1); } - // prepare pre-Atomic - if (!VOLUMEALL || !PLUTOPAK) - { - // prepare credits - M_CREDITS.title = M_CREDITS2.title = M_CREDITS3.title = s_Credits; - } - MenuEntry_HideOnCondition(&ME_MAIN_HELP, G_GetLogoFlags() & LOGO_NOHELP); -#ifndef EDUKE32_SIMPLE_MENU - MenuEntry_HideOnCondition(&ME_MAIN_CREDITS, G_GetLogoFlags() & LOGO_NOCREDITS); -#endif } -static void Menu_Pre(MenuID_t cm) -{ - int32_t i; - auto ps = g_player[myconnectindex].ps; - - switch (cm) - { - - break; - - case MENU_VIDEOSETUP: - { - Bmemset(resolution, 0, sizeof(resolution)); - MEOS_VIDEOSETUP_RESOLUTION.numOptions = 0; - - // prepare video setup - for (int i = 0; i < validmodecnt; ++i) - { - int j; - - for (j = 0; j < MEOS_VIDEOSETUP_RESOLUTION.numOptions; ++j) - { - if (validmode[i].xdim == resolution[j].xdim && validmode[i].ydim == resolution[j].ydim) - { - resolution[j].flags |= validmode[i].fs ? RES_FS : RES_WIN; - Bsnprintf(resolution[j].name, MAXRESOLUTIONSTRINGLENGTH, "%d x %d%s", resolution[j].xdim, resolution[j].ydim, (resolution[j].flags & RES_FS) ? "" : "Win"); - MEOSN_VIDEOSETUP_RESOLUTION[j] = resolution[j].name; - if (validmode[i].bpp > resolution[j].bppmax) - resolution[j].bppmax = validmode[i].bpp; - break; - } - } - - if (j == MEOS_VIDEOSETUP_RESOLUTION.numOptions) // no match found - { - resolution[j].xdim = validmode[i].xdim; - resolution[j].ydim = validmode[i].ydim; - resolution[j].bppmax = validmode[i].bpp; - resolution[j].flags = validmode[i].fs ? RES_FS : RES_WIN; - Bsnprintf(resolution[j].name, MAXRESOLUTIONSTRINGLENGTH, "%d x %d%s", resolution[j].xdim, resolution[j].ydim, (resolution[j].flags & RES_FS) ? "" : "Win"); - MEOSN_VIDEOSETUP_RESOLUTION[j] = resolution[j].name; - ++MEOS_VIDEOSETUP_RESOLUTION.numOptions; - } - } - - const int32_t nr = newresolution; - - // don't allow setting fullscreen mode if it's not supported by the resolution - MenuEntry_DisableOnCondition(&ME_VIDEOSETUP_FULLSCREEN, !(resolution[nr].flags & RES_FS)); - - MenuEntry_DisableOnCondition(&ME_VIDEOSETUP_APPLY, - (xres == resolution[nr].xdim && yres == resolution[nr].ydim && - videoGetRenderMode() == newrendermode && fullscreen == newfullscreen - && vid_vsync == newvsync && r_borderless == newborderless - ) - || (newrendermode != REND_CLASSIC && resolution[nr].bppmax <= 8)); - MenuEntry_DisableOnCondition(&ME_VIDEOSETUP_BORDERLESS, newfullscreen); - break; - } - - case MENU_SOUND: - case MENU_SOUND_INGAME: - case MENU_ADVSOUND: - MenuEntry_DisableOnCondition(&ME_SOUND_VOLUME_FX, !snd_enabled); - MenuEntry_DisableOnCondition(&ME_SOUND_VOLUME_MUSIC, !mus_enabled); - MenuEntry_DisableOnCondition(&ME_SOUND_DUKETALK, !snd_enabled); - MenuEntry_DisableOnCondition(&ME_SOUND_SAMPLINGRATE, !snd_enabled && !mus_enabled); -#ifndef EDUKE32_SIMPLE_MENU - MenuEntry_DisableOnCondition(&ME_SOUND_NUMVOICES, !snd_enabled); -#endif - MenuEntry_DisableOnCondition(&ME_SOUND_RESTART, soundrate == snd_mixrate && - soundvoices == snd_numvoices); - break; - - } static void Menu_DrawVerifyPrompt(int32_t x, int32_t y, const char * text, int numlines = 1) @@ -627,78 +212,6 @@ That way you can compare the new and old values and potentially block the change */ static void Menu_EntryLinkActivate(MenuEntry_t *entry) { - switch (g_currentMenu) - { - break; - } - - - default: - break; - } - - if (entry == &ME_VIDEOSETUP_APPLY) - { - resolution_t p = { xres, yres, fullscreen, bpp, 0 }; - int32_t prend = videoGetRenderMode(); - int32_t pvsync = vid_vsync; - int pborderless = r_borderless; - - resolution_t n = { resolution[newresolution].xdim, resolution[newresolution].ydim, - (resolution[newresolution].flags & RES_FS) ? newfullscreen : 0, - (newrendermode == REND_CLASSIC) ? 8 : resolution[newresolution].bppmax, 0 }; - - if (r_borderless != newborderless) - videoResetMode(); - - r_borderless = newborderless; - - if (videoSetGameMode(n.flags, n.xdim, n.ydim, n.bppmax, upscalefactor) < 0) - { - r_borderless = pborderless; - - if (videoSetGameMode(p.flags, p.xdim, p.ydim, p.bppmax, upscalefactor) < 0) - { - videoSetRenderMode(prend); - G_GameExit("Failed restoring old video mode."); - } - else - { - onvideomodechange(p.bppmax > 8); - vid_vsync = videoSetVsync(pvsync); - } - } - else - { - videoSetRenderMode(newrendermode); - vid_vsync = videoSetVsync(newvsync); - onvideomodechange(n.bppmax > 8); - } - - g_restorePalette = -1; - G_UpdateScreenArea(); - ScreenMode = fullscreen; - ScreenWidth = xres; - ScreenHeight = yres; - ScreenBPP = bpp; - } - else if (entry == &ME_SOUND_RESTART) - { - snd_mixrate = soundrate; - snd_numvoices = soundvoices; - mus_device = musicdevice; - - S_SoundShutdown(); - - S_SoundStartup(); - - FX_StopAllSounds(); - S_ClearSoundLocks(); - } - else if (entry == &ME_SAVESETUP_CLEANUP) - { - Menu_Change(MENU_SAVECLEANVERIFY); - } else if (entry == &ME_NETHOST_LAUNCH) { // master does whatever it wants diff --git a/source/duke3d/src/menus.h b/source/duke3d/src/menus.h index 140b5383a..fe29b6b3b 100644 --- a/source/duke3d/src/menus.h +++ b/source/duke3d/src/menus.h @@ -140,365 +140,6 @@ enum MenuIndex_t { }; - -typedef int32_t MenuID_t; - - -typedef enum MenuAnimationType_t -{ // Note: This enum is for logical categories, not visual types. - MA_None, - MA_Return, - MA_Advance, -} MenuAnimationType_t; - - - - -typedef enum MenuEntryType_t -{ - Dummy, - Link, - Option, - Custom2Col, - RangeInt32, - RangeFloat, -#ifdef MENU_ENABLE_RANGEDOUBLE - RangeDouble, -#endif - String, - Spacer, -} MenuEntryType_t; - -typedef struct MenuEntryFormat_t -{ - int32_t marginBottom; - int32_t indent; - int32_t width; // 0: center, >0: width of the label column (left-aligned options), <0: -width of everything (right-aligned) -} MenuEntryFormat_t; - - -typedef struct MenuMenuFormat_t -{ - vec2_t pos; - int32_t bottomcutoff; // >0: the bottom edge of the menu before automatic scrolling kicks in, <0: -total height for vertical justification -} MenuMenuFormat_t; - -typedef struct MenuLink_t -{ - // traits - MenuID_t linkID; - MenuAnimationType_t animation; -} MenuLink_t; -typedef struct MenuOptionSet_t -{ - // traits - char const **optionNames; - int32_t *optionValues; // If NULL, the identity of currentOption is assumed. - - // pop-up list appearance - MenuMenuFormat_t *menuFormat; - MenuEntryFormat_t *entryFormat; - MenuFont_t *font; - - // traits - int32_t numOptions; - - // pop-up list state - int32_t currentEntry; - int32_t scrollPos; - - // appearance - uint8_t features; // bit 1 = disable left/right arrows, bit 2 = disable list - - int32_t getMarginBottom() const { return mulscale16(entryFormat->marginBottom, font->zoom); } - int32_t getIndent() const { return mulscale16(entryFormat->indent, font->zoom); } -} MenuOptionSet_t; -typedef struct MenuOption_t -{ - // appearance - MenuFont_t *font; - - // traits - MenuOptionSet_t *options; // so that common sets such as Yes/No, On/Off can be reused - - // effect - FBaseCVar *cVar; - - // state - int32_t currentOption; -} MenuOption_t; -typedef struct MenuCustom2Col_t -{ - int buttonindex; - - // appearance - MenuFont_t *font; - - // effect - size_t numvalid; - - // appearance - int32_t columnWidth; - - // state - int8_t screenOpen; -} MenuCustom2Col_t; - -enum MenuRangeFlags_t -{ - DisplayTypeInteger = 1, - DisplayTypePercent = 2, - DisplayTypeNormalizedDecimal = 3, - DisplayTypeMask = (1<<0)|(1<<1), - - EnforceIntervals = 1<<7, -}; -typedef struct MenuRangeInt32_t -{ - // effect - FIntCVar *cVar; - - // appearance - MenuFont_t *font; - - // traits - int32_t min; - int32_t max; - int32_t onehundredpercent; // 0 implies max - int32_t steps; - - uint8_t flags; -} MenuRangeInt32_t; -typedef struct MenuRangeFloat_t -{ - // effect - FFloatCVar *cVar; - - // appearance - MenuFont_t *font; - - // traits - float min; - float max; - float onehundredpercent; // 0 implies 1.0 - int32_t steps; - - uint8_t flags; -} MenuRangeFloat_t; -#ifdef MENU_ENABLE_RANGEDOUBLE -typedef struct MenuRangeDouble_t -{ - // effect - double *variable; - - // appearance - MenuFont_t *font; - - // traits - double min; - double max; - double onehundredpercent; // 0 implies 1.0 - int32_t steps; - - uint8_t flags; -} MenuRangeDouble_t; -#endif -typedef struct MenuString_t -{ - // state - char* editfield; - - // effect - char* variable; - - // appearance - MenuFont_t *font; - - // effect - int32_t bufsize; - int32_t flags; -} MenuString_t; -typedef struct MenuSpacer_t -{ - int32_t height; -} MenuSpacer_t; - -// For internal use only. -enum MenuEntryFlags_t -{ - MEF_Disabled = 1<<0, - MEF_LookDisabled = 1<<1, - MEF_Hidden = 1<<2, -}; - -typedef struct MenuEntry_t -{ - // traits - const char *name; - - // appearance - MenuFont_t *font; - MenuEntryFormat_t *format; - - void *entry; - MenuEntryType_t type; - - // state - int32_t flags; - int32_t ytop, ybottom; - - int32_t getMarginBottom() const { return mulscale16(format->marginBottom, font->zoom); } - int32_t getIndent() const { return mulscale16(format->indent, font->zoom); } - int32_t getHeight() const - { - return type == Spacer ? mulscale16(((MenuSpacer_t *)entry)->height, font->zoom) : font->get_yline(); - } -} MenuEntry_t; - - -typedef enum MenuType_t -{ - Menu, - Panel, - Verify, - Message, - TextForm, - FileSelect, -} MenuType_t; - -typedef struct MenuMenu_t -{ - const char *title; - - MenuMenuFormat_t *format; - - MenuEntry_t **entrylist; - int32_t numEntries; - - // state - int32_t currentEntry, currentColumn; - int32_t scrollPos; -} MenuMenu_t; -typedef struct MenuPanel_t -{ - const char *title; - - MenuID_t previousID; - MenuAnimationType_t previousAnimation; - MenuID_t nextID; - MenuAnimationType_t nextAnimation; -} MenuPanel_t; -typedef struct MenuVerify_t -{ - vec2_t cursorpos; - - MenuID_t linkID; - MenuAnimationType_t animation; -} MenuVerify_t; -typedef struct MenuMessage_t -{ - vec2_t cursorpos; - - MenuID_t linkID; - MenuAnimationType_t animation; -} MenuMessage_t; -enum MenuTextFormFlags_t -{ - MTF_Password = 1<<0, -}; -typedef struct MenuTextForm_t -{ - // state - char *input; - - // traits - const char *instructions; - int32_t bufsize; - uint8_t flags; -} MenuTextForm_t; -typedef struct MenuFileSelect_t -{ - const char *title; - - // appearance - MenuMenuFormat_t *format[2]; - MenuFont_t *font[2]; - - // traits - const char * startdir; - const char *pattern; - char *destination; - - // state - //CACHE1D_FIND_REC *findhigh[2]; - int32_t scrollPos[2]; - - // appearance - int32_t marginBottom[2]; - - // state - //fnlist_t fnlist; - int32_t currentList; - - int32_t getMarginBottom(size_t index) const { return mulscale16(marginBottom[index], font[index]->zoom); } -} MenuFileSelect_t; - -typedef struct Menu_t -{ - void *object; - MenuID_t menuID; - MenuID_t parentID; - MenuAnimationType_t parentAnimation; - MenuType_t type; -} Menu_t; - -typedef struct MenuAnimation_t -{ - int32_t(*out)(struct MenuAnimation_t *); - int32_t(*in)(struct MenuAnimation_t *); - - Menu_t *previous; - Menu_t *current; - - int32_t start; - int32_t length; -} MenuAnimation_t; - -extern MenuAnimation_t m_animation; - -extern Menu_t *m_currentMenu; - -extern int32_t g_quitDeadline; -extern int32_t voting; -int Menu_Change(MenuID_t cm); -void Menu_AnimateChange(int32_t cm, MenuAnimationType_t animtype); -int32_t Menu_IsTextInput(Menu_t *cm); -void M_DisplayMenus(void); - -#define M_MOUSETIMEOUT 210 -extern int32_t m_mouselastactivity; - -#if defined EDUKE32_TOUCH_DEVICES -# define MOUSEALPHA 0 -# define CURSORALPHA (255/3) -# define MOUSEACTIVECONDITIONAL(condition) (condition) -# define MOUSEWATCHPOINTCONDITIONAL(condition) (condition) -#else -extern int32_t m_mousewake_watchpoint, m_menuchange_watchpoint; -// alpha increments of 3 --> 255 / 3 = 85 --> round up to power of 2 --> 128 --> divide by 2 --> 64 alphatabs required -// use 16 anyway :P -# define MOUSEUSEALPHA (videoGetRenderMode() != REND_CLASSIC || numalphatabs >= 15) -# define MOUSEALPHA (MOUSEUSEALPHA ? clamp(((int32_t) totalclock - m_mouselastactivity - 90)*3, 0, 255) : 0) -# define CURSORALPHA (MOUSEUSEALPHA ? clamp(((int32_t) totalclock - m_mouselastactivity - 90)*2 + (255/3), (255/3), 255) : 255/3) -# define MOUSEACTIVECONDITION (totalclock - m_mouselastactivity < M_MOUSETIMEOUT) -# define MOUSEACTIVECONDITIONAL(condition) (MOUSEACTIVECONDITION && (condition)) -# define MOUSEINACTIVECONDITIONAL(condition) ((!(g_player[myconnectindex].ps->gm & MODE_MENU) || !MOUSEACTIVECONDITION) && (condition)) -# define MOUSEWATCHPOINTCONDITIONAL(condition) ((condition) || m_mousewake_watchpoint || m_menuchange_watchpoint == 3) -#endif - -extern MenuEntry_t ME_NEWGAMECUSTOMENTRIES[MAXMENUGAMEPLAYENTRIES]; -extern MenuEntry_t ME_NEWGAMECUSTOMSUBENTRIES[MAXMENUGAMEPLAYENTRIES][MAXMENUGAMEPLAYENTRIES]; - #endif END_DUKE_NS diff --git a/source/rr/src/menus.cpp b/source/rr/src/menus.cpp index f67aedb86..06cd11de8 100644 --- a/source/rr/src/menus.cpp +++ b/source/rr/src/menus.cpp @@ -38,1318 +38,6 @@ BEGIN_RR_NS #if 0 -// common positions -#define MENU_MARGIN_REGULAR 40 -#define MENU_MARGIN_WIDE 32 -#define MENU_MARGIN_CENTER 160 -#define MENU_HEIGHT_CENTER 100 - - -#define USERMAPENTRYLENGTH 25 - -static FORCE_INLINE void Menu_StartTextInput() -{ - inputState.keyFlushChars(); - inputState.ClearKeysDown(); -} - - - - -/* -All MAKE_* macros are generally for the purpose of keeping state initialization -separate from actual data. Alternatively, they can serve to factor out repetitive -stuff and keep the important bits from getting lost to our eyes. - -They serve as a stand-in for C++ default value constructors, since we're using C89. - -Note that I prefer to include a space on the inside of the macro parentheses, since -they effectively stand in for curly braces as struct initializers. -*/ - - -// common font types -// tilenums are set after namesdyn runs - -static MenuMenuFormat_t MMF_Top_Main = { { MENU_MARGIN_CENTER<<16, 55<<16, }, -(170<<16) }; -static MenuMenuFormat_t MMF_Top_Episode = { { MENU_MARGIN_CENTER<<16, 48<<16, }, -(190<<16) }; -static MenuMenuFormat_t MMF_Top_Skill = { { MENU_MARGIN_CENTER<<16, 58<<16, }, -(190<<16) }; -static MenuMenuFormat_t MMF_Top_Options = { { MENU_MARGIN_CENTER<<16, 38<<16, }, -(190<<16) }; -static MenuMenuFormat_t MMF_Top_Joystick_Network = { { MENU_MARGIN_CENTER<<16, 70<<16, }, -(190<<16) }; -static MenuMenuFormat_t MMF_BigOptions = { { MENU_MARGIN_WIDE<<16, 38<<16, }, -(190<<16) }; -static MenuMenuFormat_t MMF_SmallOptions = { { MENU_MARGIN_WIDE<<16, 37<<16, }, 170<<16 }; -static MenuMenuFormat_t MMF_Macros = { { 26<<16, 40<<16, }, 160<<16 }; -static MenuMenuFormat_t MMF_SmallOptionsNarrow = { { MENU_MARGIN_REGULAR<<16, 38<<16, }, -(190<<16) }; -static MenuMenuFormat_t MMF_KeyboardSetupFuncs = { { 50<<16, 34<<16, }, 151<<16 }; -static MenuMenuFormat_t MMF_MouseJoySetupBtns = { { 76<<16, 34<<16, }, 143<<16 }; -static MenuMenuFormat_t MMF_FuncList = { { 100<<16, 51<<16, }, 152<<16 }; -static MenuMenuFormat_t MMF_ColorCorrect = { { MENU_MARGIN_REGULAR<<16, 86<<16, }, 190<<16 }; -static MenuMenuFormat_t MMF_BigSliders = { { MENU_MARGIN_WIDE<<16, 37<<16, }, 190<<16 }; -static MenuMenuFormat_t MMF_LoadSave = { { 200<<16, 49<<16, }, 145<<16 }; -static MenuMenuFormat_t MMF_NetSetup = { { 36<<16, 38<<16, }, 190<<16 }; -static MenuMenuFormat_t MMF_FileSelectLeft = { { 40<<16, 45<<16, }, 162<<16 }; -static MenuMenuFormat_t MMF_FileSelectRight = { { 164<<16, 45<<16, }, 162<<16 }; - -static MenuEntryFormat_t MEF_Null = { 0, 0, 0 }; -static MenuEntryFormat_t MEF_MainMenu = { 4<<16, 0, 0 }; -static MenuEntryFormat_t MEF_OptionsMenu = { 7<<16, 0, 0 }; -static MenuEntryFormat_t MEF_CenterMenu = { 7<<16, 0, 0 }; -static MenuEntryFormat_t MEF_BigOptions_Apply = { 4<<16, 16<<16, -(260<<16) }; -static MenuEntryFormat_t MEF_BigOptionsRt = { 4<<16, 0, -(260<<16) }; -#if defined USE_OPENGL || !defined EDUKE32_ANDROID_MENU -static MenuEntryFormat_t MEF_SmallOptions = { 1<<16, 0, -(260<<16) }; -#endif -static MenuEntryFormat_t MEF_BigCheats = { 3<<16, 0, -(260<<16) }; -static MenuEntryFormat_t MEF_Cheats = { 2<<16, 0, -(260<<16) }; -static MenuEntryFormat_t MEF_PlayerNarrow = { 1<<16, 0, 90<<16 }; -static MenuEntryFormat_t MEF_Macros = { 2<<16, -1, 268<<16 }; -static MenuEntryFormat_t MEF_VideoSetup = { 4<<16, 0, 168<<16 }; -static MenuEntryFormat_t MEF_VideoSetup_Apply = { 4<<16, 16<<16, 168<<16 }; -static MenuEntryFormat_t MEF_KBFuncList = { 3<<16, 0, -(225<<16) }; -static MenuEntryFormat_t MEF_FuncList = { 3<<16, 0, -(170<<16) }; -static MenuEntryFormat_t MEF_ColorCorrect = { 2<<16, 0, -(240<<16) }; -static MenuEntryFormat_t MEF_BigSliders = { 2<<16, 0, -(260<<16) }; -static MenuEntryFormat_t MEF_LoadSave = { 2<<16, -1, 78<<16 }; -static MenuEntryFormat_t MEF_NetSetup = { 4<<16, 0, 112<<16 }; -static MenuEntryFormat_t MEF_NetSetup_Confirm = { 4<<16, 16<<16, 112<<16 }; - -// common menu option sets -#define MAKE_MENUOPTIONSET(optionNames, optionValues, features) { optionNames, optionValues, &MMF_FuncList, &MEF_FuncList, &MF_Minifont, ARRAY_SIZE(optionNames), -1, 0, features } -#define MAKE_MENUOPTIONSETDYN(optionNames, optionValues, numOptions, features) { optionNames, optionValues, &MMF_FuncList, &MEF_FuncList, &MF_Minifont, numOptions, -1, 0, features } -#define MAKE_MENUOPTIONSETNULL { NULL, NULL, &MMF_FuncList, &MEF_FuncList, &MF_Minifont, 0, -1, 0, 0 } - -static char const *MEOSN_OffOn[] = { "Off", "On", }; -static MenuOptionSet_t MEOS_OffOn = MAKE_MENUOPTIONSET( MEOSN_OffOn, NULL, 0x3 ); -static char const *MEOSN_OnOff[] = { "On", "Off", }; -static MenuOptionSet_t MEOS_OnOff = MAKE_MENUOPTIONSET( MEOSN_OnOff, NULL, 0x3 ); -static char const *MEOSN_NoYes[] = { "No", "Yes", }; -static MenuOptionSet_t MEOS_NoYes = MAKE_MENUOPTIONSET( MEOSN_NoYes, NULL, 0x3 ); -static char const *MEOSN_YesNo[] = { "Yes", "No", }; -static MenuOptionSet_t MEOS_YesNo = MAKE_MENUOPTIONSET( MEOSN_YesNo, NULL, 0x3 ); - - -static FString MenuGameFuncs[NUMGAMEFUNCTIONS]; -static char const *MenuGameFuncNone = " -None-"; -static char const *MEOSN_Gamefuncs[NUMGAMEFUNCTIONS+1]; -static int32_t MEOSV_Gamefuncs[NUMGAMEFUNCTIONS+1]; -static MenuOptionSet_t MEOS_Gamefuncs = MAKE_MENUOPTIONSET( MEOSN_Gamefuncs, MEOSV_Gamefuncs, 0x1 ); - - - -/* -MenuEntry_t is passed in arrays of pointers so that the callback function -that is called when an entry is modified or activated can test equality of the current -entry pointer directly against the known ones, instead of relying on an ID number. - -That way, individual menu entries can be ifdef'd out painlessly. -*/ - -static MenuLink_t MEO_NULL = { MENU_NULL, MA_None, }; -static const char* MenuCustom = "Custom"; - -#define MAKE_MENUSTRING(...) { NULL, __VA_ARGS__, } -#define MAKE_MENUOPTION(...) { __VA_ARGS__, -1, } -#define MAKE_MENURANGE(...) { __VA_ARGS__, } -#define MAKE_MENUENTRY(...) { __VA_ARGS__, 0, 0, 0, } - - -#define MAKE_SPACER( EntryName, Height ) \ -static MenuSpacer_t MEO_ ## EntryName = { Height }; - -MAKE_SPACER( Space2, 2<<16 ); // bigoptions -MAKE_SPACER( Space4, 4<<16 ); // usermap, smalloptions, anything else non-top -MAKE_SPACER( Space6, 6<<16 ); // videosetup -MAKE_SPACER( Space8, 8<<16 ); // colcorr, redslide - -static MenuEntry_t ME_Space2_Redfont = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_Null, &MEO_Space2, Spacer ); -static MenuEntry_t ME_Space4_Bluefont = MAKE_MENUENTRY( NULL, &MF_Bluefont, &MEF_Null, &MEO_Space4, Spacer ); -#ifndef EDUKE32_SIMPLE_MENU -static MenuEntry_t ME_Space4_Redfont = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_Null, &MEO_Space4, Spacer ); -static MenuEntry_t ME_Space8_Bluefont = MAKE_MENUENTRY( NULL, &MF_Bluefont, &MEF_Null, &MEO_Space8, Spacer ); -#endif -static MenuEntry_t ME_Space6_Redfont = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_Null, &MEO_Space6, Spacer ); -static MenuEntry_t ME_Space8_Redfont = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_Null, &MEO_Space8, Spacer ); - -#define MAKE_MENU_TOP_ENTRYLINK( Title, Format, EntryName, LinkID ) \ -static MenuLink_t MEO_ ## EntryName = { LinkID, MA_Advance, };\ -static MenuEntry_t ME_ ## EntryName = MAKE_MENUENTRY( Title, &MF_Redfont, &Format, &MEO_ ## EntryName, Link ) - -static char const s_NewGame[] = "New Game"; -static char const s_SaveGame[] = "Save Game"; -static char const s_LoadGame[] = "Load Game"; -static char const s_Continue[] = "Continue"; -static char const s_Options[] = "Options"; -static char const s_Credits[] = "Credits"; - -MAKE_MENU_TOP_ENTRYLINK( s_NewGame, MEF_MainMenu, MAIN_NEWGAME, MENU_EPISODE ); -#ifdef EDUKE32_SIMPLE_MENU -MAKE_MENU_TOP_ENTRYLINK( "Resume Game", MEF_MainMenu, MAIN_RESUMEGAME, MENU_CLOSE ); -#endif -MAKE_MENU_TOP_ENTRYLINK( s_NewGame, MEF_MainMenu, MAIN_NEWGAME_INGAME, MENU_NEWVERIFY ); -static MenuLink_t MEO_MAIN_NEWGAME_NETWORK = { MENU_NETWORK, MA_Advance, }; -MAKE_MENU_TOP_ENTRYLINK( s_SaveGame, MEF_MainMenu, MAIN_SAVEGAME, MENU_SAVE ); -MAKE_MENU_TOP_ENTRYLINK( s_LoadGame, MEF_MainMenu, MAIN_LOADGAME, MENU_LOAD ); -MAKE_MENU_TOP_ENTRYLINK( s_Options, MEF_MainMenu, MAIN_OPTIONS, MENU_OPTIONS ); -MAKE_MENU_TOP_ENTRYLINK("Help", MEF_MainMenu, MAIN_HELP, MENU_STORY); -#ifndef EDUKE32_SIMPLE_MENU -MAKE_MENU_TOP_ENTRYLINK( s_Credits, MEF_MainMenu, MAIN_CREDITS, MENU_CREDITS ); -#endif -MAKE_MENU_TOP_ENTRYLINK( "End Game", MEF_MainMenu, MAIN_QUITTOTITLE, MENU_QUITTOTITLE ); -MAKE_MENU_TOP_ENTRYLINK( "Quit", MEF_MainMenu, MAIN_QUIT, MENU_QUIT ); -#ifndef EDUKE32_SIMPLE_MENU -MAKE_MENU_TOP_ENTRYLINK( "Quit Game", MEF_MainMenu, MAIN_QUITGAME, MENU_QUIT ); -#endif - -static MenuEntry_t *MEL_MAIN[] = { - &ME_MAIN_NEWGAME, - &ME_MAIN_LOADGAME, - &ME_MAIN_OPTIONS, - &ME_MAIN_HELP, -#ifndef EDUKE32_SIMPLE_MENU - &ME_MAIN_CREDITS, -#endif - &ME_MAIN_QUIT, -}; - -static MenuEntry_t *MEL_MAIN_INGAME[] = { -#ifdef EDUKE32_SIMPLE_MENU - &ME_MAIN_RESUMEGAME, -#else - &ME_MAIN_NEWGAME_INGAME, -#endif - &ME_MAIN_SAVEGAME, - &ME_MAIN_LOADGAME, - &ME_MAIN_OPTIONS, - &ME_MAIN_HELP, - &ME_MAIN_QUITTOTITLE, -#ifndef EDUKE32_SIMPLE_MENU - &ME_MAIN_QUITGAME, -#endif -}; - -// Episode and Skill will be dynamically generated after CONs are parsed -static MenuLink_t MEO_EPISODE = { MENU_SKILL, MA_Advance, }; -static MenuLink_t MEO_EPISODE_SHAREWARE = { MENU_BUYDUKE, MA_Advance, }; -static MenuEntry_t ME_EPISODE_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_CenterMenu, &MEO_EPISODE, Link ); -static MenuEntry_t ME_EPISODE[MAXVOLUMES]; -static MenuLink_t MEO_EPISODE_USERMAP = { MENU_USERMAP, MA_Advance, }; -static MenuEntry_t ME_EPISODE_USERMAP = MAKE_MENUENTRY( "User Map", &MF_Redfont, &MEF_CenterMenu, &MEO_EPISODE_USERMAP, Link ); -static MenuEntry_t *MEL_EPISODE[MAXVOLUMES+2]; // +2 for spacer and User Map - -static MenuEntry_t ME_SKILL_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_CenterMenu, &MEO_NULL, Link ); -static MenuEntry_t ME_SKILL[MAXSKILLS]; -static MenuEntry_t *MEL_SKILL[MAXSKILLS]; - -static char const *MEOSN_GAMESETUP_AIM_AUTO[] = { "Never", "Always", "Hitscan only", -}; -static int32_t MEOSV_GAMESETUP_AIM_AUTO[] = { 0, 1, 2, -}; - -static MenuOptionSet_t MEOS_GAMESETUP_AIM_AUTO = MAKE_MENUOPTIONSET( MEOSN_GAMESETUP_AIM_AUTO, MEOSV_GAMESETUP_AIM_AUTO, 0x2 ); -static MenuOption_t MEO_GAMESETUP_AIM_AUTO = MAKE_MENUOPTION( &MF_Redfont, &MEOS_GAMESETUP_AIM_AUTO, &cl_autoaim ); -static MenuEntry_t ME_GAMESETUP_AIM_AUTO = MAKE_MENUENTRY( "Auto aim:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_GAMESETUP_AIM_AUTO, Option ); - -static char const *MEOSN_GAMESETUP_WEAPSWITCH_PICKUP[] = { "Never", "If new", "By rating", }; -static MenuOptionSet_t MEOS_GAMESETUP_WEAPSWITCH_PICKUP = MAKE_MENUOPTIONSET( MEOSN_GAMESETUP_WEAPSWITCH_PICKUP, NULL, 0x2 ); -static MenuOption_t MEO_GAMESETUP_WEAPSWITCH_PICKUP = MAKE_MENUOPTION( &MF_Redfont, &MEOS_GAMESETUP_WEAPSWITCH_PICKUP, NULL ); -static MenuEntry_t ME_GAMESETUP_WEAPSWITCH_PICKUP = MAKE_MENUENTRY( "Equip pickups:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_GAMESETUP_WEAPSWITCH_PICKUP, Option ); - -static char const *MEOSN_DemoRec[] = { "Off", "Running", }; -static MenuOptionSet_t MEOS_DemoRec = MAKE_MENUOPTIONSET( MEOSN_DemoRec, NULL, 0x3 ); -static MenuOption_t MEO_GAMESETUP_DEMOREC = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &m_recstat ); -static MenuEntry_t ME_GAMESETUP_DEMOREC = MAKE_MENUENTRY( "Record demo:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_GAMESETUP_DEMOREC, Option ); - -static MenuOption_t MEO_ADULTMODE = MAKE_MENUOPTION(&MF_Redfont, &MEOS_OffOn, &adult_lockout); -static MenuEntry_t ME_ADULTMODE = MAKE_MENUENTRY( "Parental lock:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_ADULTMODE, Option ); - -#if defined(EDUKE32_ANDROID_MENU) || !defined(EDUKE32_SIMPLE_MENU) -static MenuLink_t MEO_GAMESETUP_CHEATS = { MENU_CHEATS, MA_Advance, }; -static MenuEntry_t ME_GAMESETUP_CHEATS = MAKE_MENUENTRY( "Cheats", &MF_Redfont, &MEF_BigOptionsRt, &MEO_GAMESETUP_CHEATS, Link ); - -static MenuEntry_t *MEL_GAMESETUP[] = { - &ME_ADULTMODE, -#if defined STARTUP_SETUP_WINDOW && !defined EDUKE32_SIMPLE_MENU - &ME_GAMESETUP_STARTWIN, -#endif - &ME_GAMESETUP_AIM_AUTO, - //&ME_GAMESETUP_WEAPSWITCH_PICKUP, -#ifdef EDUKE32_ANDROID_MENU - &ME_GAMESETUP_QUICKSWITCH, - &ME_GAMESETUP_CROUCHLOCK, -#else - &ME_GAMESETUP_DEMOREC, -#endif - &ME_GAMESETUP_CHEATS, -}; -#endif - - -// Zhe menu code lacks flexibility, it can either be hardwired to ints or to CVARs. -// Since CVARs are more important it means that these need to be implemented as CVARs even though they are just temporaries. -// By giving them no name we ensure that they remain outside the CVAR system. -CVAR_UNAMED(Int, newresolution) -CVAR_UNAMED(Int, newrendermode) -CVAR_UNAMED(Int, newfullscreen) -CVAR_UNAMED(Int, newvsync) -CVAR_UNAMED(Int, newborderless) - -enum resflags_t { - RES_FS = 0x1, - RES_WIN = 0x2, -}; - -#define MAXRESOLUTIONSTRINGLENGTH 19 - -typedef struct resolution_t { - int32_t xdim, ydim; - int32_t flags; - int32_t bppmax; - char name[MAXRESOLUTIONSTRINGLENGTH]; -} resolution_t; - -resolution_t resolution[MAXVALIDMODES]; - -static char const *MEOSN_VIDEOSETUP_RESOLUTION[MAXVALIDMODES]; -static MenuOptionSet_t MEOS_VIDEOSETUP_RESOLUTION = MAKE_MENUOPTIONSETDYN( MEOSN_VIDEOSETUP_RESOLUTION, NULL, 0, 0x0 ); -static MenuOption_t MEO_VIDEOSETUP_RESOLUTION = MAKE_MENUOPTION( &MF_Redfont, &MEOS_VIDEOSETUP_RESOLUTION, &newresolution ); -static MenuEntry_t ME_VIDEOSETUP_RESOLUTION = MAKE_MENUENTRY( "Resolution:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_VIDEOSETUP_RESOLUTION, Option ); - -#ifdef USE_OPENGL -static char const *MEOSN_VIDEOSETUP_RENDERER[] = { "Classic", "OpenGL", }; -static int32_t MEOSV_VIDEOSETUP_RENDERER[] = { REND_CLASSIC, REND_POLYMOST, }; - -static MenuOptionSet_t MEOS_VIDEOSETUP_RENDERER = MAKE_MENUOPTIONSET( MEOSN_VIDEOSETUP_RENDERER, MEOSV_VIDEOSETUP_RENDERER, 0x2 ); - -static MenuOption_t MEO_VIDEOSETUP_RENDERER = MAKE_MENUOPTION( &MF_Redfont, &MEOS_VIDEOSETUP_RENDERER, &newrendermode ); -static MenuEntry_t ME_VIDEOSETUP_RENDERER = MAKE_MENUENTRY( "Renderer:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_VIDEOSETUP_RENDERER, Option ); -#endif - -static MenuOption_t MEO_VIDEOSETUP_FULLSCREEN = MAKE_MENUOPTION( &MF_Redfont, &MEOS_YesNo, &newfullscreen ); -static MenuEntry_t ME_VIDEOSETUP_FULLSCREEN = MAKE_MENUENTRY( "Windowed:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_VIDEOSETUP_FULLSCREEN, Option ); - - -static char const *MEOSN_VIDEOSETUP_VSYNC [] = { "Adaptive", "Off", "On", }; -static int32_t MEOSV_VIDEOSETUP_VSYNC [] = { -1, 0, 1, }; -static MenuOptionSet_t MEOS_VIDEOSETUP_VSYNC = MAKE_MENUOPTIONSET(MEOSN_VIDEOSETUP_VSYNC, MEOSV_VIDEOSETUP_VSYNC, 0x2); -static MenuOption_t MEO_VIDEOSETUP_VSYNC = MAKE_MENUOPTION(&MF_Redfont, &MEOS_VIDEOSETUP_VSYNC, &newvsync); -static MenuEntry_t ME_VIDEOSETUP_VSYNC = MAKE_MENUENTRY("VSync:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_VIDEOSETUP_VSYNC, Option); - -//static char const *MEOSN_VIDEOSETUP_FRAMELIMIT [] = { "30 fps", "60 fps", "75 fps", "100 fps", "120 fps", "144 fps", "165 fps", "240 fps" }; - -static MenuEntry_t ME_VIDEOSETUP_APPLY = MAKE_MENUENTRY( "Apply Changes", &MF_Redfont, &MEF_BigOptions_Apply, &MEO_NULL, Link ); - - -static MenuLink_t MEO_DISPLAYSETUP_COLORCORR = { MENU_COLCORR, MA_Advance, }; -static MenuEntry_t ME_DISPLAYSETUP_COLORCORR = MAKE_MENUENTRY( "Color Correction", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_COLORCORR, Link ); - - -#ifndef EDUKE32_ANDROID_MENU -static MenuOption_t MEO_DISPLAYSETUP_ASPECTRATIO = MAKE_MENUOPTION(&MF_Redfont, &MEOS_OffOn, &r_usenewaspect); -static MenuEntry_t ME_DISPLAYSETUP_ASPECTRATIO = MAKE_MENUENTRY( "Widescreen:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_ASPECTRATIO, Option ); -#endif - -static MenuOption_t MEO_DISPLAYSETUP_VOXELS = MAKE_MENUOPTION(&MF_Redfont, &MEOS_OffOn, &r_voxels); -static MenuEntry_t ME_DISPLAYSETUP_VOXELS = MAKE_MENUENTRY( "Voxels:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_VOXELS, Option ); - -static MenuRangeInt32_t MEO_DISPLAYSETUP_FOV = MAKE_MENURANGE( &r_fov, &MF_Redfont, 70, 120, 0, 11, 1 ); -static MenuEntry_t ME_DISPLAYSETUP_FOV = MAKE_MENUENTRY( "FOV:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_FOV, RangeInt32 ); - - -#ifdef USE_OPENGL - -//POGOTODO: allow filtering again in standalone once indexed colour textures support filtering -static char const *MEOSN_DISPLAYSETUP_TEXFILTER[] = { "Classic", "Filtered" }; -static int32_t MEOSV_DISPLAYSETUP_TEXFILTER[] = { TEXFILTER_OFF, TEXFILTER_ON }; -static MenuOptionSet_t MEOS_DISPLAYSETUP_TEXFILTER = MAKE_MENUOPTIONSET( MEOSN_DISPLAYSETUP_TEXFILTER, MEOSV_DISPLAYSETUP_TEXFILTER, 0x2 ); -static MenuOption_t MEO_DISPLAYSETUP_TEXFILTER = MAKE_MENUOPTION( &MF_Redfont, &MEOS_DISPLAYSETUP_TEXFILTER, &hw_texfilter ); -static MenuEntry_t ME_DISPLAYSETUP_TEXFILTER = MAKE_MENUENTRY( "Texture Mode:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_TEXFILTER, Option ); - -static char const *MEOSN_DISPLAYSETUP_ANISOTROPY[] = { "Max", "None", "2x", "4x", "8x", "16x", }; -static int32_t MEOSV_DISPLAYSETUP_ANISOTROPY[] = { 0, 1, 2, 4, 8, 16, }; -static MenuOptionSet_t MEOS_DISPLAYSETUP_ANISOTROPY = MAKE_MENUOPTIONSET( MEOSN_DISPLAYSETUP_ANISOTROPY, MEOSV_DISPLAYSETUP_ANISOTROPY, 0x0 ); -static MenuOption_t MEO_DISPLAYSETUP_ANISOTROPY = MAKE_MENUOPTION(&MF_Redfont, &MEOS_DISPLAYSETUP_ANISOTROPY, &hw_anisotropy); -static MenuEntry_t ME_DISPLAYSETUP_ANISOTROPY = MAKE_MENUENTRY( "Anisotropy:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_ANISOTROPY, Option ); - -#endif - -static char const s_Scale[] = "Scale:"; - -static MenuOption_t MEO_SCREENSETUP_CROSSHAIR = MAKE_MENUOPTION(&MF_Redfont, &MEOS_OffOn, &cl_crosshair); -static MenuEntry_t ME_SCREENSETUP_CROSSHAIR = MAKE_MENUENTRY( "Crosshair:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SCREENSETUP_CROSSHAIR, Option ); -static MenuRangeInt32_t MEO_SCREENSETUP_CROSSHAIRSIZE = MAKE_MENURANGE( &cl_crosshairscale, &MF_Redfont, 25, 100, 0, 16, 2 ); -static MenuEntry_t ME_SCREENSETUP_CROSSHAIRSIZE = MAKE_MENUENTRY( s_Scale, &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SCREENSETUP_CROSSHAIRSIZE, RangeInt32 ); - -static MenuRangeInt32_t MEO_SCREENSETUP_SCREENSIZE = MAKE_MENURANGE( &hud_size, &MF_Redfont, 0, 11, 0, 1, EnforceIntervals ); -static MenuOption_t MEO_SCREENSETUP_SCREENSIZE_TWO = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &hud_size ); -static MenuEntry_t ME_SCREENSETUP_SCREENSIZE = MAKE_MENUENTRY( "Status bar:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SCREENSETUP_SCREENSIZE, RangeInt32 ); -static MenuRangeInt32_t MEO_SCREENSETUP_TEXTSIZE = MAKE_MENURANGE( &hud_textscale, &MF_Redfont, 100, 400, 0, 16, 2 ); -static MenuEntry_t ME_SCREENSETUP_TEXTSIZE = MAKE_MENUENTRY( s_Scale, &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SCREENSETUP_TEXTSIZE, RangeInt32 ); -static MenuOption_t MEO_SCREENSETUP_LEVELSTATS = MAKE_MENUOPTION(&MF_Redfont, &MEOS_OffOn, &hud_stats); -static MenuEntry_t ME_SCREENSETUP_LEVELSTATS = MAKE_MENUENTRY( "Level stats:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SCREENSETUP_LEVELSTATS, Option ); - - -static MenuOption_t MEO_SCREENSETUP_SHOWPICKUPMESSAGES = MAKE_MENUOPTION(&MF_Redfont, &MEOS_OffOn, &hud_messages); -static MenuEntry_t ME_SCREENSETUP_SHOWPICKUPMESSAGES = MAKE_MENUENTRY( "Game messages:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SCREENSETUP_SHOWPICKUPMESSAGES, Option ); - -static MenuRangeInt32_t MEO_SCREENSETUP_SBARSIZE = MAKE_MENURANGE( &hud_scale, &MF_Redfont, 50, 100, 0, 10, 2 ); -static MenuEntry_t ME_SCREENSETUP_SBARSIZE = MAKE_MENUENTRY( s_Scale, &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SCREENSETUP_SBARSIZE, RangeInt32 ); - - -static MenuLink_t MEO_DISPLAYSETUP_SCREENSETUP = { MENU_SCREENSETUP, MA_Advance, }; -static MenuEntry_t ME_DISPLAYSETUP_SCREENSETUP = MAKE_MENUENTRY( "HUD setup", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_SCREENSETUP, Link ); - - -#ifdef USE_OPENGL -static MenuLink_t MEO_DISPLAYSETUP_ADVANCED_GL_POLYMOST = { MENU_POLYMOST, MA_Advance, }; -static MenuEntry_t ME_DISPLAYSETUP_ADVANCED_GL_POLYMOST = MAKE_MENUENTRY( "Polymost setup", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_ADVANCED_GL_POLYMOST, Link ); -#endif - -#ifndef EDUKE32_ANDROID_MENU -static MenuLink_t MEO_DISPLAYSETUP_VIDEOSETUP = { MENU_VIDEOSETUP, MA_Advance, }; -static MenuEntry_t ME_DISPLAYSETUP_VIDEOSETUP = MAKE_MENUENTRY( "Video mode", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_VIDEOSETUP, Link ); -#endif - - -static MenuLink_t MEO_ENTERCHEAT = { MENU_CHEATENTRY, MA_None, }; -static MenuEntry_t ME_ENTERCHEAT = MAKE_MENUENTRY( "Enter Cheat Code", &MF_Redfont, &MEF_BigCheats, &MEO_ENTERCHEAT, Link ); - -static MenuLink_t MEO_CHEAT_WARP = { MENU_CHEAT_WARP, MA_None, }; -static MenuLink_t MEO_CHEAT_SKILL = { MENU_CHEAT_SKILL, MA_None, }; - -static MenuEntry_t *MEL_OPTIONS[] = { -#ifndef EDUKE32_SIMPLE_MENU - &ME_OPTIONS_GAMESETUP, -#endif - &ME_OPTIONS_DISPLAYSETUP, - &ME_OPTIONS_SOUNDSETUP, -#ifndef EDUKE32_ANDROID_MENU -#ifndef EDUKE32_SIMPLE_MENU - &ME_OPTIONS_PLAYERSETUP, -#endif - &ME_OPTIONS_CONTROLS, -#else - &ME_OPTIONS_TOUCHSETUP, -#endif -#ifdef EDUKE32_SIMPLE_MENU - &ME_GAMESETUP_SAVESETUP, - &ME_OPTIONS_CHEATS -#endif -}; - -static MenuEntry_t *MEL_CONTROLS[] = { -#ifndef EDUKE32_ANDROID_MENU - &ME_OPTIONS_KEYBOARDSETUP, - &ME_OPTIONS_MOUSESETUP, - &ME_OPTIONS_JOYSTICKSETUP, -#else - &ME_OPTIONS_TOUCHSETUP -#endif -}; - -static MenuEntry_t *MEL_CHEATS[ARRAY_SIZE(ME_CheatCodes)+1] = { - &ME_ENTERCHEAT, -}; - -static MenuEntry_t *MEL_VIDEOSETUP[] = { - &ME_VIDEOSETUP_RESOLUTION, -#ifdef USE_OPENGL - &ME_VIDEOSETUP_RENDERER, -#endif - &ME_VIDEOSETUP_FULLSCREEN, - &ME_VIDEOSETUP_VSYNC, - &ME_Space6_Redfont, - &ME_VIDEOSETUP_APPLY, -}; -static MenuEntry_t *MEL_DISPLAYSETUP[] = { - &ME_DISPLAYSETUP_SCREENSETUP, - &ME_DISPLAYSETUP_COLORCORR, -#ifndef EDUKE32_ANDROID_MENU - &ME_DISPLAYSETUP_VIDEOSETUP, - &ME_DISPLAYSETUP_ASPECTRATIO, - &ME_DISPLAYSETUP_VOXELS, - &ME_DISPLAYSETUP_FOV, -#endif -}; - -#ifdef USE_OPENGL -static MenuEntry_t *MEL_DISPLAYSETUP_GL[] = { - &ME_DISPLAYSETUP_SCREENSETUP, - &ME_DISPLAYSETUP_COLORCORR, - &ME_DISPLAYSETUP_VIDEOSETUP, - &ME_DISPLAYSETUP_ASPECTRATIO, - &ME_DISPLAYSETUP_VOXELS, - &ME_DISPLAYSETUP_FOV, - &ME_DISPLAYSETUP_TEXFILTER, - &ME_DISPLAYSETUP_ANISOTROPY, - &ME_DISPLAYSETUP_ADVANCED_GL_POLYMOST, -}; - - -#endif - - - -static char const *MenuKeyNone = " -"; -static char const *MEOSN_Keys[NUMKEYS]; - -static MenuCustom2Col_t MEO_KEYBOARDSETUPFUNCS_TEMPLATE = { { NULL, NULL, }, MEOSN_Keys, &MF_Minifont, NUMKEYS, 54<<16, 0 }; -static MenuCustom2Col_t MEO_KEYBOARDSETUPFUNCS[NUMGAMEFUNCTIONS]; -static MenuEntry_t ME_KEYBOARDSETUPFUNCS_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Minifont, &MEF_KBFuncList, &MEO_KEYBOARDSETUPFUNCS_TEMPLATE, Custom2Col ); -static MenuEntry_t ME_KEYBOARDSETUPFUNCS[NUMGAMEFUNCTIONS]; -static MenuEntry_t *MEL_KEYBOARDSETUPFUNCS[NUMGAMEFUNCTIONS]; - -static MenuLink_t MEO_KEYBOARDSETUP_KEYS = { MENU_KEYBOARDKEYS, MA_Advance, }; -static MenuEntry_t ME_KEYBOARDSETUP_KEYS = MAKE_MENUENTRY( "Edit Configuration", &MF_Redfont, &MEF_CenterMenu, &MEO_KEYBOARDSETUP_KEYS, Link ); -static MenuEntry_t ME_KEYBOARDSETUP_RESET = MAKE_MENUENTRY( "Reset To Defaults", &MF_Redfont, &MEF_CenterMenu, &MEO_NULL, Link ); -static MenuEntry_t ME_KEYBOARDSETUP_RESETCLASSIC = MAKE_MENUENTRY( "Reset To Classic", &MF_Redfont, &MEF_CenterMenu, &MEO_NULL, Link ); - -static MenuEntry_t *MEL_KEYBOARDSETUP[] = { - &ME_KEYBOARDSETUP_KEYS, - &ME_KEYBOARDSETUP_RESET, - &ME_KEYBOARDSETUP_RESETCLASSIC, -}; - - - -#ifdef USE_OPENGL -static MenuOption_t MEO_RENDERERSETUP_HIGHTILE = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NoYes, &hw_hightile ); -static MenuEntry_t ME_RENDERERSETUP_HIGHTILE = MAKE_MENUENTRY( "True color textures:", &MF_Bluefont, &MEF_SmallOptions, &MEO_RENDERERSETUP_HIGHTILE, Option ); - -static MenuOption_t MEO_RENDERERSETUP_PRECACHE = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_OffOn, &r_precache ); -static MenuEntry_t ME_RENDERERSETUP_PRECACHE = MAKE_MENUENTRY( "Pre-load map textures:", &MF_Bluefont, &MEF_SmallOptions, &MEO_RENDERERSETUP_PRECACHE, Option ); -# ifndef EDUKE32_GLES -static char const *MEOSN_RENDERERSETUP_TEXCACHE[] = { "Off", "On", "Compr.", }; -static MenuOptionSet_t MEOS_RENDERERSETUP_TEXCACHE = MAKE_MENUOPTIONSET( MEOSN_RENDERERSETUP_TEXCACHE, NULL, 0x2 ); -# endif -# ifdef USE_GLEXT -static MenuOption_t MEO_RENDERERSETUP_DETAILTEX = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NoYes, &hw_detailmapping); -static MenuEntry_t ME_RENDERERSETUP_DETAILTEX = MAKE_MENUENTRY( "Detail textures:", &MF_Bluefont, &MEF_SmallOptions, &MEO_RENDERERSETUP_DETAILTEX, Option ); -static MenuOption_t MEO_RENDERERSETUP_GLOWTEX = MAKE_MENUOPTION(&MF_Bluefont, &MEOS_NoYes, &hw_glowmapping); -static MenuEntry_t ME_RENDERERSETUP_GLOWTEX = MAKE_MENUENTRY("Glow textures:", &MF_Bluefont, &MEF_SmallOptions, &MEO_RENDERERSETUP_GLOWTEX, Option); -# endif -static MenuOption_t MEO_RENDERERSETUP_MODELS = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NoYes, &hw_models ); -static MenuEntry_t ME_RENDERERSETUP_MODELS = MAKE_MENUENTRY( "3D models:", &MF_Bluefont, &MEF_SmallOptions, &MEO_RENDERERSETUP_MODELS, Option ); -#endif - - -#ifdef USE_OPENGL -static MenuEntry_t *MEL_RENDERERSETUP_POLYMOST[] = { - &ME_RENDERERSETUP_HIGHTILE, - &ME_RENDERERSETUP_PRECACHE, -# ifdef USE_GLEXT - &ME_RENDERERSETUP_DETAILTEX, - &ME_RENDERERSETUP_GLOWTEX, -# endif - &ME_Space4_Bluefont, - &ME_RENDERERSETUP_MODELS, -}; - -#endif - -#ifdef EDUKE32_ANDROID_MENU -static MenuRangeFloat_t MEO_COLCORR_GAMMA = MAKE_MENURANGE( &vid_gamma, &MF_Bluefont, 1.f, 2.5f, 0.f, 39, 1 ); -#else -static MenuRangeFloat_t MEO_COLCORR_GAMMA = MAKE_MENURANGE( &vid_gamma, &MF_Bluefont, 0.3f, 4.f, 0.f, 38, 1 ); -#endif -static MenuEntry_t ME_COLCORR_GAMMA = MAKE_MENUENTRY( "Gamma:", &MF_Redfont, &MEF_ColorCorrect, &MEO_COLCORR_GAMMA, RangeFloat ); -static MenuRangeFloat_t MEO_COLCORR_CONTRAST = MAKE_MENURANGE( &vid_contrast, &MF_Bluefont, 0.1f, 2.7f, 0.f, 53, 1 ); -static MenuEntry_t ME_COLCORR_CONTRAST = MAKE_MENUENTRY( "Contrast:", &MF_Redfont, &MEF_ColorCorrect, &MEO_COLCORR_CONTRAST, RangeFloat ); -static MenuRangeFloat_t MEO_COLCORR_BRIGHTNESS = MAKE_MENURANGE( &vid_brightness, &MF_Bluefont, -0.8f, 0.8f, 0.f, 33, 1 ); -static MenuEntry_t ME_COLCORR_BRIGHTNESS = MAKE_MENUENTRY( "Brightness:", &MF_Redfont, &MEF_ColorCorrect, &MEO_COLCORR_BRIGHTNESS, RangeFloat ); -static MenuEntry_t ME_COLCORR_RESET = MAKE_MENUENTRY( "Reset To Defaults", &MF_Redfont, &MEF_ColorCorrect, &MEO_NULL, Link ); -#ifdef EDUKE32_ANDROID_MENU -#define MINVIS 1.f -#else -#define MINVIS 0.125f -#endif -#ifndef EDUKE32_SIMPLE_MENU -static MenuRangeFloat_t MEO_COLCORR_AMBIENT = MAKE_MENURANGE( &r_ambientlight, &MF_Bluefont, MINVIS, 4.f, 0.f, 32, 1 ); -static MenuEntry_t ME_COLCORR_AMBIENT = MAKE_MENUENTRY( "Visibility:", &MF_Redfont, &MEF_ColorCorrect, &MEO_COLCORR_AMBIENT, RangeFloat ); -#endif -static MenuEntry_t *MEL_COLCORR[] = { - &ME_COLCORR_GAMMA, -#ifndef EDUKE32_ANDROID_MENU - &ME_COLCORR_CONTRAST, - &ME_COLCORR_BRIGHTNESS, -#endif -#ifndef EDUKE32_SIMPLE_MENU - &ME_COLCORR_AMBIENT, -#endif - &ME_Space8_Redfont, - &ME_COLCORR_RESET, -}; - -static MenuEntry_t *MEL_SCREENSETUP[] = { -#ifdef EDUKE32_ANDROID_MENU - &ME_SCREENSETUP_STATUSBARONTOP, -#endif - &ME_SCREENSETUP_SCREENSIZE, - &ME_SCREENSETUP_SBARSIZE, - - &ME_SCREENSETUP_CROSSHAIR, - &ME_SCREENSETUP_CROSSHAIRSIZE, - - &ME_SCREENSETUP_LEVELSTATS, - &ME_SCREENSETUP_TEXTSIZE, - - &ME_SCREENSETUP_SHOWPICKUPMESSAGES, -}; - - - -CVAR_UNAMED(Int, soundrate) -CVAR_UNAMED(Int, soundvoices) -CVAR_UNAMED(Int, musicdevice) -static MenuOption_t MEO_SOUND = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &snd_enabled ); -static MenuEntry_t ME_SOUND = MAKE_MENUENTRY( "Sound:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND, Option ); - -static MenuOption_t MEO_SOUND_MUSIC = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &mus_enabled ); -static MenuEntry_t ME_SOUND_MUSIC = MAKE_MENUENTRY( "Music:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_MUSIC, Option ); - -static MenuLink_t MEO_SOUND_CDPLAYER = { MENU_CDPLAYER, MA_Advance, }; -static MenuEntry_t ME_SOUND_CDPLAYER = MAKE_MENUENTRY( "8 Track Player", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_CDPLAYER, Link ); - -static MenuRangeInt32_t MEO_SOUND_VOLUME_FX = MAKE_MENURANGE( &snd_fxvolume, &MF_Redfont, 0, 255, 0, 33, 2 ); -static MenuEntry_t ME_SOUND_VOLUME_FX = MAKE_MENUENTRY( "Volume:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_VOLUME_FX, RangeInt32 ); - - -static char const *MEOSN_SOUND_SAMPLINGRATE[] = { "22050Hz", "44100Hz", "48000Hz", }; -static int32_t MEOSV_SOUND_SAMPLINGRATE[] = { 22050, 44100, 48000, }; -static MenuOptionSet_t MEOS_SOUND_SAMPLINGRATE = MAKE_MENUOPTIONSET( MEOSN_SOUND_SAMPLINGRATE, MEOSV_SOUND_SAMPLINGRATE, 0x3 ); -static MenuOption_t MEO_SOUND_SAMPLINGRATE = MAKE_MENUOPTION( &MF_Redfont, &MEOS_SOUND_SAMPLINGRATE, &soundrate ); -static MenuEntry_t ME_SOUND_SAMPLINGRATE = MAKE_MENUENTRY( "Sample rate:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_SAMPLINGRATE, Option ); - -#ifndef EDUKE32_SIMPLE_MENU -static MenuRangeInt32_t MEO_SOUND_NUMVOICES = MAKE_MENURANGE( &soundvoices, &MF_Redfont, 16, 256, 0, 16, 1 ); -static MenuEntry_t ME_SOUND_NUMVOICES = MAKE_MENUENTRY( "Voices:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SOUND_NUMVOICES, RangeInt32 ); -#endif - - - -static MenuEntry_t ME_CDPLAYER_TRACK = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_Null, &MEO_NULL, Dummy); - -static MenuEntry_t *MEL_CDPLAYER[] = { - &ME_CDPLAYER_TRACK, - &ME_CDPLAYER_TRACK, - &ME_CDPLAYER_TRACK, - &ME_CDPLAYER_TRACK, - &ME_CDPLAYER_TRACK, - &ME_CDPLAYER_TRACK, - &ME_CDPLAYER_TRACK, - &ME_CDPLAYER_TRACK -}; - - -static MenuOption_t MEO_SAVESETUP_AUTOSAVE = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &cl_autosave ); -static MenuEntry_t ME_SAVESETUP_AUTOSAVE = MAKE_MENUENTRY( "Autosaves:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SAVESETUP_AUTOSAVE, Option ); - -static MenuOption_t MEO_SAVESETUP_AUTOSAVEDELETION = MAKE_MENUOPTION( &MF_Redfont, &MEOS_NoYes, &cl_autosavedeletion ); -static MenuEntry_t ME_SAVESETUP_AUTOSAVEDELETION = MAKE_MENUENTRY( "Auto-Delete:", &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SAVESETUP_AUTOSAVEDELETION, Option ); -static MenuRangeInt32_t MEO_SAVESETUP_MAXAUTOSAVES = MAKE_MENURANGE( &cl_maxautosaves, &MF_Redfont, 1, 10, 0, 10, 1 ); -static MenuEntry_t ME_SAVESETUP_MAXAUTOSAVES = MAKE_MENUENTRY( "Limit:", &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SAVESETUP_MAXAUTOSAVES, RangeInt32 ); - -static MenuEntry_t ME_SAVESETUP_CLEANUP = MAKE_MENUENTRY( "Clean Up Saves", &MF_Redfont, &MEF_BigOptionsRt, &MEO_NULL, Link ); - -static MenuEntry_t *MEL_SAVESETUP[] = { - &ME_SAVESETUP_AUTOSAVE, - &ME_SAVESETUP_AUTOSAVEDELETION, - &ME_SAVESETUP_MAXAUTOSAVES, - &ME_SAVESETUP_CLEANUP, -}; - - -MAKE_MENU_TOP_ENTRYLINK( "Player Setup", MEF_CenterMenu, NETWORK_PLAYERSETUP, MENU_PLAYER ); -MAKE_MENU_TOP_ENTRYLINK( "Join Game", MEF_CenterMenu, NETWORK_JOINGAME, MENU_NETJOIN ); -MAKE_MENU_TOP_ENTRYLINK( "Host Game", MEF_CenterMenu, NETWORK_HOSTGAME, MENU_NETHOST ); - -static MenuEntry_t *MEL_NETWORK[] = { - &ME_NETWORK_PLAYERSETUP, - &ME_NETWORK_JOINGAME, - &ME_NETWORK_HOSTGAME, -}; - -//static MenuString_t MEO_PLAYER_NAME = MAKE_MENUSTRING( playername, &MF_Bluefont, MAXPLAYERNAME, 0 ); -//static MenuEntry_t ME_PLAYER_NAME = MAKE_MENUENTRY( "Name", &MF_Bluefont, &MEF_PlayerNarrow, &MEO_PLAYER_NAME, String ); -static char const *MEOSN_PLAYER_COLOR[] = { "Auto", "Blue", "Red", "Green", "Gray", "Dark gray", "Dark green", "Brown", "Dark blue", "Bright red", "Yellow", }; -static int32_t MEOSV_PLAYER_COLOR[] = { 0, 9, 10, 11, 12, 13, 14, 15, 16, 21, 23, }; -static MenuOptionSet_t MEOS_PLAYER_COLOR = MAKE_MENUOPTIONSET( MEOSN_PLAYER_COLOR, MEOSV_PLAYER_COLOR, 0x2 ); -static MenuOption_t MEO_PLAYER_COLOR = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_PLAYER_COLOR, &playercolor ); -static MenuEntry_t ME_PLAYER_COLOR = MAKE_MENUENTRY( "Color", &MF_Bluefont, &MEF_PlayerNarrow, &MEO_PLAYER_COLOR, Option ); -static char const *MEOSN_PLAYER_TEAM[] = { "Blue", "Red", "Green", "Gray", }; -static MenuOptionSet_t MEOS_PLAYER_TEAM = MAKE_MENUOPTIONSET( MEOSN_PLAYER_TEAM, NULL, 0x2 ); -static MenuOption_t MEO_PLAYER_TEAM = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_PLAYER_TEAM, &playerteam ); -static MenuEntry_t ME_PLAYER_TEAM = MAKE_MENUENTRY( "Team", &MF_Bluefont, &MEF_PlayerNarrow, &MEO_PLAYER_TEAM, Option ); -#ifndef EDUKE32_SIMPLE_MENU -static MenuLink_t MEO_PLAYER_MACROS = { MENU_MACROS, MA_Advance, }; -static MenuEntry_t ME_PLAYER_MACROS = MAKE_MENUENTRY( "Multiplayer macros", &MF_Bluefont, &MEF_SmallOptions, &MEO_PLAYER_MACROS, Link ); -#endif - -static MenuEntry_t *MEL_PLAYER[] = { - //&ME_PLAYER_NAME, - &ME_Space4_Bluefont, - &ME_PLAYER_COLOR, - &ME_Space4_Bluefont, - &ME_PLAYER_TEAM, -#ifndef EDUKE32_SIMPLE_MENU - &ME_Space8_Bluefont, - &ME_PLAYER_MACROS, -#endif -}; - -#define MAXRIDECULE 10 -#define MAXRIDECULELENGTH 40 -static MenuString_t MEO_MACROS_TEMPLATE = MAKE_MENUSTRING( NULL, &MF_Bluefont, MAXRIDECULELENGTH, 0 ); -static MenuString_t MEO_MACROS[10]; -static char sink[50]; -static MenuEntry_t ME_MACROS_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Bluefont, &MEF_Macros, &MEO_MACROS_TEMPLATE, String ); -static MenuEntry_t ME_MACROS[MAXRIDECULE]; -static MenuEntry_t *MEL_MACROS[MAXRIDECULE]; - -#ifndef EDUKE32_SIMPLE_MENU -static char const *MenuUserMap = "User Map"; -#endif -static char const *MenuSkillNone = "None"; - -static char const *MEOSN_NetGametypes[MAXGAMETYPES]; -static char const *MEOSN_NetEpisodes[MAXVOLUMES+1]; -static int32_t MEOSV_NetEpisodes[MAXVOLUMES+1]; -static char const *MEOSN_NetLevels[MAXVOLUMES][MAXLEVELS]; -static char const *MEOSN_NetSkills[MAXSKILLS+1]; - -static MenuLink_t MEO_NETHOST_OPTIONS = { MENU_NETOPTIONS, MA_Advance, }; -static MenuEntry_t ME_NETHOST_OPTIONS = MAKE_MENUENTRY( "Game Options", &MF_Redfont, &MEF_VideoSetup, &MEO_NETHOST_OPTIONS, Link ); -static MenuEntry_t ME_NETHOST_LAUNCH = MAKE_MENUENTRY( "Launch Game", &MF_Redfont, &MEF_VideoSetup, &MEO_NULL, Link ); - -static MenuEntry_t *MEL_NETHOST[] = { - &ME_NETHOST_OPTIONS, - &ME_NETHOST_LAUNCH, -}; - -static MenuOptionSet_t MEOS_NETOPTIONS_GAMETYPE = MAKE_MENUOPTIONSET( MEOSN_NetGametypes, NULL, 0x0 ); -static MenuOption_t MEO_NETOPTIONS_GAMETYPE = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NETOPTIONS_GAMETYPE, &m_coop ); -static MenuEntry_t ME_NETOPTIONS_GAMETYPE = MAKE_MENUENTRY( "Game Type", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_GAMETYPE, Option ); -static MenuOptionSet_t MEOS_NETOPTIONS_EPISODE = MAKE_MENUOPTIONSET( MEOSN_NetEpisodes, MEOSV_NetEpisodes, 0x0 ); -CVAR_UNAMED(Int, NetEpisode); -static MenuOption_t MEO_NETOPTIONS_EPISODE = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NETOPTIONS_EPISODE, &NetEpisode ); -static MenuEntry_t ME_NETOPTIONS_EPISODE = MAKE_MENUENTRY( "Episode", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_EPISODE, Option ); -static MenuOptionSet_t MEOS_NETOPTIONS_LEVEL_TEMPLATE = MAKE_MENUOPTIONSETNULL; -static MenuOptionSet_t MEOS_NETOPTIONS_LEVEL[MAXVOLUMES]; -static MenuOption_t MEO_NETOPTIONS_LEVEL = MAKE_MENUOPTION( &MF_Bluefont, NULL, &m_level_number ); -static MenuEntry_t ME_NETOPTIONS_LEVEL = MAKE_MENUENTRY( "Level", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_LEVEL, Option ); -static MenuLink_t MEO_NETOPTIONS_USERMAP = { MENU_NETUSERMAP, MA_Advance, }; -static MenuEntry_t ME_NETOPTIONS_USERMAP = MAKE_MENUENTRY( "User Map", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_USERMAP, Link ); -static MenuOptionSet_t MEOS_NETOPTIONS_MONSTERS = MAKE_MENUOPTIONSET( MEOSN_NetSkills, NULL, 0x0 ); -static MenuOption_t MEO_NETOPTIONS_MONSTERS = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_NETOPTIONS_MONSTERS, NULL ); -static MenuEntry_t ME_NETOPTIONS_MONSTERS = MAKE_MENUENTRY( "Monsters", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_MONSTERS, Option ); -static MenuOption_t MEO_NETOPTIONS_MARKERS = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_OffOn, &m_marker); -static MenuEntry_t ME_NETOPTIONS_MARKERS = MAKE_MENUENTRY( "Markers", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_MARKERS, Option ); -static MenuOption_t MEO_NETOPTIONS_MAPEXITS = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_OnOff, &m_noexits); -static MenuEntry_t ME_NETOPTIONS_MAPEXITS = MAKE_MENUENTRY( "Map Exits", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_MAPEXITS, Option ); -static MenuOption_t MEO_NETOPTIONS_FRFIRE = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_OffOn, &m_ffire); -static MenuEntry_t ME_NETOPTIONS_FRFIRE = MAKE_MENUENTRY( "Fr. Fire", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_FRFIRE, Option ); -static MenuEntry_t ME_NETOPTIONS_ACCEPT = MAKE_MENUENTRY( "Accept", &MF_Redfont, &MEF_NetSetup_Confirm, &MEO_NETWORK_HOSTGAME, Link ); - -static MenuEntry_t *MEL_NETOPTIONS[] = { - &ME_NETOPTIONS_GAMETYPE, - &ME_NETOPTIONS_EPISODE, - &ME_NETOPTIONS_LEVEL, - &ME_NETOPTIONS_MONSTERS, - &ME_NETOPTIONS_MARKERS, - &ME_NETOPTIONS_MAPEXITS, - &ME_NETOPTIONS_ACCEPT, -}; - -static char MenuServer[BMAX_PATH] = "localhost"; -static MenuString_t MEO_NETJOIN_SERVER = MAKE_MENUSTRING( MenuServer, &MF_Bluefont, BMAX_PATH, 0 ); -static MenuEntry_t ME_NETJOIN_SERVER = MAKE_MENUENTRY( "Server", &MF_Redfont, &MEF_VideoSetup, &MEO_NETJOIN_SERVER, String ); -#define MAXPORTSTRINGLENGTH 6 // unsigned 16-bit integer -static char MenuPort[MAXPORTSTRINGLENGTH] = "19014"; -static MenuString_t MEO_NETJOIN_PORT = MAKE_MENUSTRING( MenuPort, &MF_Bluefont, MAXPORTSTRINGLENGTH, INPUT_NUMERIC ); -static MenuEntry_t ME_NETJOIN_PORT = MAKE_MENUENTRY( "Port", &MF_Redfont, &MEF_VideoSetup, &MEO_NETJOIN_PORT, String ); -static MenuEntry_t ME_NETJOIN_CONNECT = MAKE_MENUENTRY( "Connect", &MF_Redfont, &MEF_VideoSetup_Apply, &MEO_NULL, Link ); - -static MenuEntry_t *MEL_NETJOIN[] = { - &ME_NETJOIN_SERVER, - &ME_NETJOIN_PORT, - &ME_NETJOIN_CONNECT, -}; - - -#define NoTitle NULL - -#define MAKE_MENUMENU(Title, Format, Entries) { Title, Format, Entries, ARRAY_SIZE(Entries), 0, 0, 0 } -#define MAKE_MENUMENU_CUSTOMSIZE(Title, Format, Entries) { Title, Format, Entries, 0, 0, 0, 0 } - -static MenuMenu_t M_MAIN = MAKE_MENUMENU( NoTitle, &MMF_Top_Main, MEL_MAIN ); -static MenuMenu_t M_MAIN_INGAME = MAKE_MENUMENU( NoTitle, &MMF_Top_Main, MEL_MAIN_INGAME ); -static MenuMenu_t M_EPISODE = MAKE_MENUMENU( "Select An Episode", &MMF_Top_Episode, MEL_EPISODE ); -static MenuMenu_t M_SKILL = MAKE_MENUMENU( "Select Skill", &MMF_Top_Skill, MEL_SKILL ); -#ifndef EDUKE32_SIMPLE_MENU -static MenuMenu_t M_GAMESETUP = MAKE_MENUMENU( "Game Setup", &MMF_BigOptions, MEL_GAMESETUP ); -#endif -static MenuMenu_t M_OPTIONS = MAKE_MENUMENU( s_Options, &MMF_Top_Options, MEL_OPTIONS ); -static MenuMenu_t M_VIDEOSETUP = MAKE_MENUMENU( "Video Mode", &MMF_BigOptions, MEL_VIDEOSETUP ); -static MenuMenu_t M_KEYBOARDSETUP = MAKE_MENUMENU( "Configure Controls", &MMF_Top_Options, MEL_KEYBOARDSETUP ); -static MenuMenu_t M_CONTROLS = MAKE_MENUMENU( "Control Setup", &MMF_Top_Options, MEL_CONTROLS ); -static MenuMenu_t M_CHEATS = MAKE_MENUMENU( "Cheats", &MMF_SmallOptions, MEL_CHEATS ); -static MenuMenu_t M_MOUSESETUP = MAKE_MENUMENU( "Mouse Setup", &MMF_BigOptions, MEL_MOUSESETUP ); -#ifdef EDUKE32_ANDROID_MENU -static MenuMenu_t M_TOUCHSETUP = MAKE_MENUMENU( "Touch Setup", &MMF_Top_Options, MEL_TOUCHSETUP ); -static MenuMenu_t M_TOUCHSENS = MAKE_MENUMENU( "Sensitivity", &MMF_BigOptions, MEL_TOUCHSENS); -static MenuPanel_t M_TOUCHBUTTONS = { "Button Setup", MENU_TOUCHSETUP, MA_Return, MENU_TOUCHSETUP, MA_Advance, }; -#endif -static MenuMenu_t M_JOYSTICKSETUP = MAKE_MENUMENU( "Joystick Setup", &MMF_Top_Joystick_Network, MEL_JOYSTICKSETUP ); -static MenuMenu_t M_JOYSTICKBTNS = MAKE_MENUMENU( "Joystick Buttons", &MMF_MouseJoySetupBtns, MEL_JOYSTICKBTNS ); -static MenuMenu_t M_JOYSTICKAXES = MAKE_MENUMENU( "Joystick Axes", &MMF_BigSliders, MEL_JOYSTICKAXES ); -static MenuMenu_t M_KEYBOARDKEYS = MAKE_MENUMENU( "Key Configuration", &MMF_KeyboardSetupFuncs, MEL_KEYBOARDSETUPFUNCS ); -static MenuMenu_t M_MOUSEADVANCED = MAKE_MENUMENU( "Advanced Mouse", &MMF_BigSliders, MEL_MOUSEADVANCED ); -static MenuMenu_t M_JOYSTICKAXIS = MAKE_MENUMENU( NULL, &MMF_BigSliders, MEL_JOYSTICKAXIS ); -#ifdef USE_OPENGL -static MenuMenu_t M_RENDERERSETUP_POLYMOST = MAKE_MENUMENU( "Polymost Setup", &MMF_SmallOptions, MEL_RENDERERSETUP_POLYMOST ); -# ifdef POLYMER -static MenuMenu_t M_RENDERERSETUP_POLYMER = MAKE_MENUMENU("Polymer Setup", &MMF_SmallOptions, MEL_RENDERERSETUP_POLYMER ); -# endif -#endif -static MenuMenu_t M_COLCORR = MAKE_MENUMENU( "Color Correction", &MMF_ColorCorrect, MEL_COLCORR ); -static MenuMenu_t M_SCREENSETUP = MAKE_MENUMENU( "HUD Setup", &MMF_BigOptions, MEL_SCREENSETUP ); -static MenuMenu_t M_DISPLAYSETUP = MAKE_MENUMENU( "Display Setup", &MMF_BigOptions, MEL_DISPLAYSETUP ); -static MenuMenu_t M_LOAD = MAKE_MENUMENU_CUSTOMSIZE( s_LoadGame, &MMF_LoadSave, MEL_LOAD ); -static MenuMenu_t M_SAVE = MAKE_MENUMENU_CUSTOMSIZE( s_SaveGame, &MMF_LoadSave, MEL_SAVE ); -static MenuMenu_t M_SOUND = MAKE_MENUMENU( "Sound Setup", &MMF_BigOptions, MEL_SOUND ); -static MenuMenu_t M_ADVSOUND = MAKE_MENUMENU( "Advanced Sound", &MMF_BigOptions, MEL_ADVSOUND ); -static MenuMenu_t M_CDPLAYER = MAKE_MENUMENU( "8 Track Player", &MMF_BigOptions, MEL_CDPLAYER ); -static MenuMenu_t M_SAVESETUP = MAKE_MENUMENU( "Save Setup", &MMF_BigOptions, MEL_SAVESETUP ); -static MenuMenu_t M_NETWORK = MAKE_MENUMENU( "Network Game", &MMF_Top_Joystick_Network, MEL_NETWORK ); -static MenuMenu_t M_PLAYER = MAKE_MENUMENU( "Player Setup", &MMF_SmallOptions, MEL_PLAYER ); -static MenuMenu_t M_MACROS = MAKE_MENUMENU( "Multiplayer Macros", &MMF_Macros, MEL_MACROS ); -static MenuMenu_t M_NETHOST = MAKE_MENUMENU( "Host Network Game", &MMF_SmallOptionsNarrow, MEL_NETHOST ); -static MenuMenu_t M_NETOPTIONS = MAKE_MENUMENU( "Net Game Options", &MMF_NetSetup, MEL_NETOPTIONS ); -static MenuMenu_t M_NETJOIN = MAKE_MENUMENU( "Join Network Game", &MMF_SmallOptionsNarrow, MEL_NETJOIN ); - -#ifdef EDUKE32_SIMPLE_MENU -static MenuPanel_t M_STORY = { NoTitle, MENU_STORY, MA_Return, MENU_STORY, MA_Advance, }; -#else -static MenuPanel_t M_STORY = { NoTitle, MENU_F1HELP, MA_Return, MENU_F1HELP, MA_Advance, }; -#endif - - -#define CURSOR_CENTER_2LINE { MENU_MARGIN_CENTER<<16, 120<<16, } -#define CURSOR_CENTER_3LINE { MENU_MARGIN_CENTER<<16, 129<<16, } -#define CURSOR_BOTTOMRIGHT { 304<<16, 186<<16, } - -static MenuVerify_t M_SAVECLEANVERIFY = { CURSOR_CENTER_3LINE, MENU_SAVESETUP, MA_None, }; -static MenuVerify_t M_QUIT = { CURSOR_CENTER_2LINE, MENU_CLOSE, MA_None, }; -static MenuVerify_t M_QUITTOTITLE = { CURSOR_CENTER_2LINE, MENU_CLOSE, MA_None, }; -static MenuVerify_t M_LOADVERIFY = { CURSOR_CENTER_3LINE, MENU_CLOSE, MA_None, }; -static MenuVerify_t M_LOADDELVERIFY = { CURSOR_CENTER_3LINE, MENU_LOAD, MA_None, }; -static MenuVerify_t M_NEWVERIFY = { CURSOR_CENTER_2LINE, MENU_EPISODE, MA_Advance, }; -static MenuVerify_t M_SAVEVERIFY = { CURSOR_CENTER_2LINE, MENU_SAVE, MA_None, }; -static MenuVerify_t M_SAVEDELVERIFY = { CURSOR_CENTER_3LINE, MENU_SAVE, MA_None, }; -static MenuVerify_t M_RESETPLAYER = { CURSOR_CENTER_3LINE, MENU_CLOSE, MA_None, }; - -static MenuMessage_t M_NETWAITMASTER = { CURSOR_BOTTOMRIGHT, MENU_NULL, MA_None, }; -static MenuMessage_t M_NETWAITVOTES = { CURSOR_BOTTOMRIGHT, MENU_NULL, MA_None, }; -static MenuMessage_t M_BUYDUKE = { CURSOR_BOTTOMRIGHT, MENU_EPISODE, MA_Return, }; - -static MenuTextForm_t M_ADULTPASSWORD = { NULL, "Enter Password:", MAXPWLOCKOUT, MTF_Password }; -static MenuTextForm_t M_CHEATENTRY = { NULL, "Enter Cheat Code:", MAXCHEATLEN, 0 }; -static MenuTextForm_t M_CHEAT_WARP = { NULL, "Enter Warp #:", 3, 0 }; -static MenuTextForm_t M_CHEAT_SKILL = { NULL, "Enter Skill #:", 1, 0 }; - -//#define MAKE_MENUFILESELECT(a, b, c) { a, { &MMF_FileSelectLeft, &MMF_FileSelectRight }, { &MF_Minifont, &MF_Minifont }, b, c, { NULL, NULL }, { 0, 0 }, { 3<<16, 3<<16 }, FNLIST_INITIALIZER, 0 } - -//static MenuFileSelect_t M_USERMAP = MAKE_MENUFILESELECT( "Select A User Map", "*.map", boardfilename ); - -// MUST be in ascending order of MenuID enum values due to binary search -static Menu_t Menus[] = { - { &M_MAIN, MENU_MAIN, MENU_CLOSE, MA_None, Menu }, - { &M_MAIN_INGAME, MENU_MAIN_INGAME, MENU_CLOSE, MA_None, Menu }, - { &M_EPISODE, MENU_EPISODE, MENU_MAIN, MA_Return, Menu }, - //{ &M_USERMAP, MENU_USERMAP, MENU_EPISODE, MA_Return, FileSelect }, - { &M_SKILL, MENU_SKILL, MENU_EPISODE, MA_Return, Menu }, -#ifndef EDUKE32_SIMPLE_MENU - { &M_GAMESETUP, MENU_GAMESETUP, MENU_OPTIONS, MA_Return, Menu }, -#endif - { &M_OPTIONS, MENU_OPTIONS, MENU_MAIN, MA_Return, Menu }, - { &M_VIDEOSETUP, MENU_VIDEOSETUP, MENU_DISPLAYSETUP, MA_Return, Menu }, - { &M_KEYBOARDSETUP, MENU_KEYBOARDSETUP, MENU_CONTROLS, MA_Return, Menu }, - { &M_MOUSESETUP, MENU_MOUSESETUP, MENU_CONTROLS, MA_Return, Menu }, - { &M_JOYSTICKSETUP, MENU_JOYSTICKSETUP, MENU_CONTROLS, MA_Return, Menu }, - { &M_JOYSTICKBTNS, MENU_JOYSTICKBTNS, MENU_JOYSTICKSETUP, MA_Return, Menu }, - { &M_JOYSTICKAXES, MENU_JOYSTICKAXES, MENU_JOYSTICKSETUP, MA_Return, Menu }, - { &M_KEYBOARDKEYS, MENU_KEYBOARDKEYS, MENU_KEYBOARDSETUP, MA_Return, Menu }, - { &M_MOUSEADVANCED, MENU_MOUSEADVANCED, MENU_MOUSESETUP, MA_Return, Menu }, - { &M_JOYSTICKAXIS, MENU_JOYSTICKAXIS, MENU_JOYSTICKAXES, MA_Return, Menu }, -#ifdef EDUKE32_ANDROID_MENU - { &M_TOUCHSETUP, MENU_TOUCHSETUP, MENU_OPTIONS, MA_Return, Menu }, - { &M_TOUCHSENS, MENU_TOUCHSENS, MENU_TOUCHSETUP, MA_Return, Menu }, - { &M_TOUCHBUTTONS, MENU_TOUCHBUTTONS, MENU_TOUCHSETUP, MA_Return, Panel }, -#endif - { &M_CONTROLS, MENU_CONTROLS, MENU_OPTIONS, MA_Return, Menu }, -#ifdef USE_OPENGL - { &M_RENDERERSETUP_POLYMOST, MENU_POLYMOST, MENU_DISPLAYSETUP, MA_Return, Menu }, -#endif - { &M_COLCORR, MENU_COLCORR, MENU_DISPLAYSETUP, MA_Return, Menu }, - { &M_COLCORR, MENU_COLCORR_INGAME, MENU_CLOSE, MA_Return, Menu }, - { &M_SCREENSETUP, MENU_SCREENSETUP, MENU_DISPLAYSETUP, MA_Return, Menu }, - { &M_DISPLAYSETUP, MENU_DISPLAYSETUP, MENU_OPTIONS, MA_Return, Menu }, -#ifdef POLYMER - { &M_RENDERERSETUP_POLYMER, MENU_POLYMER, MENU_DISPLAYSETUP, MA_Return, Menu }, -#endif - { &M_LOAD, MENU_LOAD, MENU_MAIN, MA_Return, Menu }, - { &M_SAVE, MENU_SAVE, MENU_MAIN, MA_Return, Menu }, - { &M_STORY, MENU_STORY, MENU_MAIN, MA_Return, Panel }, - { &M_F1HELP, MENU_F1HELP, MENU_MAIN, MA_Return, Panel }, - { &M_F1HELP2, MENU_F1HELP2, MENU_MAIN, MA_Return, Panel }, - { &M_QUIT, MENU_QUIT, MENU_PREVIOUS, MA_Return, Verify }, - { &M_QUITTOTITLE, MENU_QUITTOTITLE, MENU_PREVIOUS, MA_Return, Verify }, - { &M_QUIT, MENU_QUIT_INGAME, MENU_CLOSE, MA_None, Verify }, - { &M_NETHOST, MENU_NETSETUP, MENU_MAIN, MA_Return, Menu }, - { &M_NETWAITMASTER, MENU_NETWAITMASTER, MENU_MAIN, MA_Return, Message }, - { &M_NETWAITVOTES, MENU_NETWAITVOTES, MENU_MAIN, MA_Return, Message }, - { &M_SOUND, MENU_SOUND, MENU_OPTIONS, MA_Return, Menu }, - { &M_SOUND, MENU_SOUND_INGAME, MENU_CLOSE, MA_Return, Menu }, - { &M_ADVSOUND, MENU_ADVSOUND, MENU_SOUND, MA_Return, Menu }, - { &M_CDPLAYER, MENU_CDPLAYER, MENU_SOUND, MA_Return, CdPlayer }, - { &M_SAVESETUP, MENU_SAVESETUP, MENU_OPTIONS, MA_Return, Menu }, - { &M_SAVECLEANVERIFY, MENU_SAVECLEANVERIFY, MENU_SAVESETUP, MA_None, Verify }, -#ifdef EDUKE32_SIMPLE_MENU - { &M_CHEATS, MENU_CHEATS, MENU_OPTIONS, MA_Return, Menu }, -#else - { &M_CHEATS, MENU_CHEATS, MENU_GAMESETUP, MA_Return, Menu }, -#endif - { &M_CHEATENTRY, MENU_CHEATENTRY, MENU_CHEATS, MA_None, TextForm }, - { &M_CHEAT_WARP, MENU_CHEAT_WARP, MENU_CHEATS, MA_None, TextForm }, - { &M_CHEAT_SKILL, MENU_CHEAT_SKILL, MENU_CHEATS, MA_None, TextForm }, - { &M_LOADVERIFY, MENU_LOADVERIFY, MENU_LOAD, MA_None, Verify }, - { &M_LOADDELVERIFY, MENU_LOADDELVERIFY, MENU_LOAD, MA_None, Verify }, - { &M_NEWVERIFY, MENU_NEWVERIFY, MENU_PREVIOUS, MA_Return, Verify }, - { &M_SAVEVERIFY, MENU_SAVEVERIFY, MENU_SAVE, MA_None, Verify }, - { &M_SAVEDELVERIFY, MENU_SAVEDELVERIFY, MENU_SAVE, MA_None, Verify }, - { &M_ADULTPASSWORD, MENU_ADULTPASSWORD, MENU_GAMESETUP, MA_None, TextForm }, - { &M_RESETPLAYER, MENU_RESETPLAYER, MENU_CLOSE, MA_None, Verify }, - { &M_BUYDUKE, MENU_BUYDUKE, MENU_EPISODE, MA_Return, Message }, - { &M_NETWORK, MENU_NETWORK, MENU_MAIN, MA_Return, Menu }, - { &M_PLAYER, MENU_PLAYER, MENU_OPTIONS, MA_Return, Menu }, - { &M_MACROS, MENU_MACROS, MENU_PLAYER, MA_Return, Menu }, - { &M_NETHOST, MENU_NETHOST, MENU_NETWORK, MA_Return, Menu }, - { &M_NETOPTIONS, MENU_NETOPTIONS, MENU_NETWORK, MA_Return, Menu }, - //{ &M_USERMAP, MENU_NETUSERMAP, MENU_NETOPTIONS, MA_Return, FileSelect }, - { &M_NETJOIN, MENU_NETJOIN, MENU_NETWORK, MA_Return, Menu }, -}; - - -/* -This function prepares data after ART and CON have been processed. -It also initializes some data in loops rather than statically at compile time. -*/ -void Menu_Init(void) -{ - int32_t i, j, k; - - // prepare menu fonts - // check if tilenum is -1 in case it was set in EVENT_SETDEFAULTS - if ((unsigned)MF_Redfont.tilenum >= MAXTILES) MF_Redfont.tilenum = BIGALPHANUM; - if ((unsigned)MF_Bluefont.tilenum >= MAXTILES) MF_Bluefont.tilenum = STARTALPHANUM; - if ((unsigned)MF_Minifont.tilenum >= MAXTILES) MF_Minifont.tilenum = MINIFONT; - MF_Redfont.emptychar.y = tilesiz[MF_Redfont.tilenum].y<<16; - MF_Bluefont.emptychar.y = tilesiz[MF_Bluefont.tilenum].y<<16; - MF_Minifont.emptychar.y = tilesiz[MF_Minifont.tilenum].y<<16; - if (!minitext_lowercase) - MF_Minifont.textflags |= TEXT_UPPERCASE; - - // prepare gamefuncs and keys - MEOSN_Gamefuncs[0] = MenuGameFuncNone; - MEOSV_Gamefuncs[0] = -1; - k = 1; - for (i = 0; i < NUMGAMEFUNCTIONS; ++i) - { - MenuGameFuncs[i] = buttonMap.GetButtonAlias(i); - MenuGameFuncs[i].Substitute('_', ' '); - } - if (RR) - { - MenuGameFuncs[gamefunc_Holo_Duke] = "Beer"; - MenuGameFuncs[gamefunc_Jetpack] = "CowPie"; - MenuGameFuncs[gamefunc_NightVision] = "Yeehaa"; - MenuGameFuncs[gamefunc_MedKit] = "Whiskey"; - MenuGameFuncs[gamefunc_Steroids] = "Moonshine"; - MenuGameFuncs[gamefunc_Quick_Kick] = "Pee"; - } - for (i = 0; i < NUMGAMEFUNCTIONS; ++i) - { - if (MenuGameFuncs[i][0] != '\0') - { - MEOSN_Gamefuncs[k] = MenuGameFuncs[i]; - MEOSV_Gamefuncs[k] = i; - ++k; - } - } - - MEOS_Gamefuncs.numOptions = k; - - for (i = 0; i < NUMKEYS; ++i) - MEOSN_Keys[i] = KB_ScanCodeToString(i); - MEOSN_Keys[NUMKEYS-1] = MenuKeyNone; - - - // prepare episodes - k = 0; - for (i = 0; i < g_volumeCnt; ++i) - { - if (gVolumeNames[i].IsNotEmpty()) - { - if (!(gVolumeFlags[i] & EF_HIDEFROMSP)) - { - MEL_EPISODE[i] = &ME_EPISODE[i]; - ME_EPISODE[i] = ME_EPISODE_TEMPLATE; - ME_EPISODE[i].name = gVolumeNames[i]; - } - - // if (!(EpisodeFlags[i] & EF_HIDEFROMMP)) - { - MEOSN_NetEpisodes[k] = gVolumeNames[i]; - MEOSV_NetEpisodes[k] = i; - - k++; - } - } - - // prepare levels - MEOS_NETOPTIONS_LEVEL[i] = MEOS_NETOPTIONS_LEVEL_TEMPLATE; - for (j = 0; j < MAXLEVELS; ++j) - { - MEOSN_NetLevels[i][j] = g_mapInfo[MAXLEVELS*i+j].name; - if (g_mapInfo[i*MAXLEVELS+j].filename != NULL) - MEOS_NETOPTIONS_LEVEL[i].numOptions = j+1; - } - MEOS_NETOPTIONS_LEVEL[i].optionNames = MEOSN_NetLevels[i]; - } - M_EPISODE.numEntries = g_volumeCnt+2; -#ifndef EDUKE32_SIMPLE_MENU - MEL_EPISODE[g_volumeCnt] = &ME_Space4_Redfont; - MEL_EPISODE[g_volumeCnt+1] = &ME_EPISODE_USERMAP; - MEOSN_NetEpisodes[k] = MenuUserMap; - MEOSV_NetEpisodes[k] = MAXVOLUMES; -#else - M_EPISODE.numEntries = g_volumeCnt; - k--; -#endif - MEOS_NETOPTIONS_EPISODE.numOptions = k + 1; - NetEpisode = MEOSV_NetEpisodes[0]; - MMF_Top_Episode.pos.y = (58 + (3-k)*6)<<16; - if (g_skillCnt == 0) - MEO_EPISODE.linkID = MENU_NULL; - M_EPISODE.currentEntry = gDefaultVolume; - - // prepare skills - k = -1; - for (i = 0; i < g_skillCnt && gSkillNames[i].IsNotEmpty(); ++i) - { - MEL_SKILL[i] = &ME_SKILL[i]; - ME_SKILL[i] = ME_SKILL_TEMPLATE; - ME_SKILL[i].name = gSkillNames[i]; - - MEOSN_NetSkills[i] = gSkillNames[i]; - - k = i; - } - ++k; - M_SKILL.numEntries = g_skillCnt; // k; - MEOS_NETOPTIONS_MONSTERS.numOptions = g_skillCnt + 1; // k+1; - MEOSN_NetSkills[g_skillCnt] = MenuSkillNone; - MMF_Top_Skill.pos.y = (58 + (4-g_skillCnt)*6)<<16; - M_SKILL.currentEntry = gDefaultSkill; - Menu_AdjustForCurrentEntryAssignmentBlind(&M_SKILL); - - // prepare multiplayer gametypes - k = -1; - for (i = 0; i < MAXGAMETYPES; ++i) - if (g_gametypeNames[i][0]) - { - MEOSN_NetGametypes[i] = g_gametypeNames[i]; - k = i; - } - ++k; - MEOS_NETOPTIONS_GAMETYPE.numOptions = k; - - // prepare cheats - for (i = 0; i < NUMCHEATFUNCS; ++i) - MEL_CHEATS[i+1] = &ME_CheatCodes[i]; - - // prepare text chat macros - for (i = 0; i < MAXRIDECULE; ++i) - { - MEL_MACROS[i] = &ME_MACROS[i]; - ME_MACROS[i] = ME_MACROS_TEMPLATE; - ME_MACROS[i].entry = &MEO_MACROS[i]; - MEO_MACROS[i] = MEO_MACROS_TEMPLATE; - - MEO_MACROS[i].variable = sink;// ud.ridecule[i]; temporarily disabled - } - - // prepare input - for (i = 0; i < NUMGAMEFUNCTIONS; ++i) - { - if (MenuGameFuncs[i][0] == '\0') - { - MEL_KEYBOARDSETUPFUNCS[i] = NULL; - continue; - } - - MEL_KEYBOARDSETUPFUNCS[i] = &ME_KEYBOARDSETUPFUNCS[i]; - ME_KEYBOARDSETUPFUNCS[i] = ME_KEYBOARDSETUPFUNCS_TEMPLATE; - ME_KEYBOARDSETUPFUNCS[i].name = MenuGameFuncs[i]; - ME_KEYBOARDSETUPFUNCS[i].entry = &MEO_KEYBOARDSETUPFUNCS[i]; - MEO_KEYBOARDSETUPFUNCS[i] = MEO_KEYBOARDSETUPFUNCS_TEMPLATE; - } - M_KEYBOARDKEYS.numEntries = NUMGAMEFUNCTIONS; - for (i = 0; i < 2*joystick.numButtons + 8*joystick.numHats; ++i) - { - if (i < 2*joystick.numButtons) - { - if (i & 1) - Bsnprintf(MenuJoystickNames[i], MAXJOYBUTTONSTRINGLENGTH, "Double %s", joyGetName(1, i>>1)); - else - Bstrncpy(MenuJoystickNames[i], joyGetName(1, i>>1), MAXJOYBUTTONSTRINGLENGTH); - } - else - { - Bsnprintf(MenuJoystickNames[i], MAXJOYBUTTONSTRINGLENGTH, (i & 1) ? "Double Hat %d %s" : "Hat %d %s", ((i - 2*joystick.numButtons)>>3), MenuJoystickHatDirections[((i - 2*joystick.numButtons)>>1) % 4]); - } - } - for (i = 0; i < joystick.numAxes; ++i) - { - ME_JOYSTICKAXES[i] = ME_JOYSTICKAXES_TEMPLATE; - Bstrncpy(MenuJoystickAxes[i], joyGetName(0, i), MAXJOYBUTTONSTRINGLENGTH); - ME_JOYSTICKAXES[i].name = MenuJoystickAxes[i]; - MEL_JOYSTICKAXES[i] = &ME_JOYSTICKAXES[i]; - } - M_JOYSTICKAXES.numEntries = joystick.numAxes; - - // prepare video setup - for (i = 0; i < validmodecnt; ++i) - { - for (j = 0; j < MEOS_VIDEOSETUP_RESOLUTION.numOptions; ++j) - { - if (validmode[i].xdim == resolution[j].xdim && validmode[i].ydim == resolution[j].ydim) - { - resolution[j].flags |= validmode[i].fs ? RES_FS : RES_WIN; - Bsnprintf(resolution[j].name, MAXRESOLUTIONSTRINGLENGTH, "%d x %d%s", resolution[j].xdim, resolution[j].ydim, (resolution[j].flags & RES_FS) ? "" : "Win"); - MEOSN_VIDEOSETUP_RESOLUTION[j] = resolution[j].name; - if (validmode[i].bpp > resolution[j].bppmax) - resolution[j].bppmax = validmode[i].bpp; - break; - } - } - - if (j == MEOS_VIDEOSETUP_RESOLUTION.numOptions) // no match found - { - resolution[j].xdim = validmode[i].xdim; - resolution[j].ydim = validmode[i].ydim; - resolution[j].bppmax = validmode[i].bpp; - resolution[j].flags = validmode[i].fs ? RES_FS : RES_WIN; - Bsnprintf(resolution[j].name, MAXRESOLUTIONSTRINGLENGTH, "%d x %d%s", resolution[j].xdim, resolution[j].ydim, (resolution[j].flags & RES_FS) ? "" : "Win"); - MEOSN_VIDEOSETUP_RESOLUTION[j] = resolution[j].name; - ++MEOS_VIDEOSETUP_RESOLUTION.numOptions; - } - } - - - if (RR) - { - MF_Redfont.zoom = 32768; - MF_Redfont.emptychar.x <<= 1; - MF_Redfont.cursorScale = 13107; - MF_Redfont.cursorScale2 = 6553; - //MF_Redfont.emptychar.y <<= 1; - MF_Bluefont.zoom = 32768; - MF_Bluefont.emptychar.x <<= 1; - MF_Bluefont.cursorScale = 6553; - MF_Bluefont.cursorScale2 = 6553; - //MF_Bluefont.emptychar.y <<= 1; - MF_Minifont.zoom = 32768; - MF_Minifont.emptychar.x <<= 1; - MF_Minifont.cursorScale = 6553; - MF_Minifont.cursorScale2 = 6553; - //MF_Minifont.emptychar.y <<= 1; - ME_SOUND_DUKETALK.name = "Leonard Talk:"; - } - else if (NAPALM) - { - ME_SOUND_DUKETALK.name = "NAPALM Talk:"; - } - else if (NAM) - { - ME_SOUND_DUKETALK.name = "NAM Talk:"; - } - - // prepare shareware - if (VOLUMEONE) - { - // blue out episodes beyond the first - for (i = 1; i < g_volumeCnt; ++i) - { - if (MEL_EPISODE[i]) - { - ME_EPISODE[i].entry = &MEO_EPISODE_SHAREWARE; - ME_EPISODE[i].flags |= MEF_LookDisabled; - } - } - M_EPISODE.numEntries = g_volumeCnt; // remove User Map (and spacer) - MEOS_NETOPTIONS_EPISODE.numOptions = 1; - MenuEntry_DisableOnCondition(&ME_NETOPTIONS_EPISODE, 1); - } - - if (RR) - { - MEL_SOUND[0] = &ME_SOUND_CDPLAYER; - MEL_SOUND[1] = &ME_SOUND; - M_CREDITS.title = M_CREDITS2.title = M_CREDITS3.title = s_Credits; - M_CREDITS3.nextID = MENU_CREDITS4; - M_STORY.previousID = M_STORY.nextID = MENU_F1HELP; - if (RRRA) - { - M_CREDITS31.previousID = MENU_CREDITS30; - M_STORY.previousID = MENU_F1HELP2; - M_F1HELP.nextID = MENU_F1HELP2; - } - else - { - M_CREDITS31.previousID = MENU_CREDITS23; - M_CREDITS23.nextID = MENU_CREDITS31; - } - } - // prepare pre-Atomic - else if (!VOLUMEALL || !PLUTOPAK) - { - // prepare credits - M_CREDITS.title = M_CREDITS2.title = M_CREDITS3.title = s_Credits; - } -} - - -static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) -{ - int32_t i, j, l = 0; - - switch (cm) - { - case MENU_CDPLAYER: - rotatesprite_fs(origin.x + (MENU_MARGIN_CENTER<<16), origin.y+(100<<16),32768L,0,CDPLAYER,16,0,10); - break; - - case MENU_PLAYER: - if (RR) - rotatesprite_fs(origin.x + (260<<16), origin.y + ((24+(tilesiz[APLAYER].y>>2))<<16), 24576L,0,3845+36-((((8-((int32_t) totalclock>>4)))&7)*5),0,entry == &ME_PLAYER_TEAM ? G_GetTeamPalette(playerteam) : playercolor,10); - else - rotatesprite_fs(origin.x + (260<<16), origin.y + ((24+(tilesiz[APLAYER].y>>1))<<16), 49152L,0,1441-((((4-((int32_t) totalclock>>4)))&3)*5),0,entry == &ME_PLAYER_TEAM ? G_GetTeamPalette(playerteam) : playercolor,10); - break; - - case MENU_MACROS: - mgametextcenter(origin.x, origin.y + (144<<16), "Activate in-game with Shift-F#"); - break; - - case MENU_COLCORR: - case MENU_COLCORR_INGAME: - // center panel - if (!RR) - rotatesprite_fs(origin.x + (120<<16), origin.y + (32<<16), 16384, 0, 3290, 0, 0, 2|8|16); - rotatesprite_fs(origin.x + (160<<16) - (tilesiz[BOTTOMSTATUSBAR].x<<(RR ? 12 : 13)), origin.y + (82<<16) - (tilesiz[BOTTOMSTATUSBAR].y<<14), RR ? 8192 : 16384, 0, BOTTOMSTATUSBAR, 0, 0, 2|8|16); - - // left panel - rotatesprite_fs(origin.x + (40<<16), origin.y + (32<<16), 16384, 0, RR ? RRTILE403 : BONUSSCREEN, 0, 0, 2|8|16); - - // right panel - rotatesprite_fs(origin.x + (200<<16), origin.y + (32<<16), 16384, 0, LOADSCREEN, 0, 0, 2|8|16); - break; - - case MENU_NETSETUP: - case MENU_NETHOST: - mminitext(origin.x + (90<<16), origin.y + (90<<16), "Game Type", MF_Minifont.pal_deselected); - mminitext(origin.x + (90<<16), origin.y + ((90+8)<<16), "Episode", MF_Minifont.pal_deselected); - mminitext(origin.x + (90<<16), origin.y + ((90+8+8)<<16), "Level", MF_Minifont.pal_deselected); - mminitext(origin.x + (90<<16), origin.y + ((90+8+8+8)<<16), ME_NETOPTIONS_MONSTERS.name, MF_Minifont.pal_deselected); - if (m_coop == 0) - mminitext(origin.x + (90<<16), origin.y + ((90+8+8+8+8)<<16), "Markers", MF_Minifont.pal_deselected); - else if (m_coop == 1) - mminitext(origin.x + (90<<16), origin.y + ((90+8+8+8+8)<<16), "Friendly Fire", MF_Minifont.pal_deselected); - mminitext(origin.x + (90<<16), origin.y + ((90+8+8+8+8+8)<<16), "User Map", MF_Minifont.pal_deselected); - - mminitext(origin.x + ((90+60)<<16), origin.y + (90<<16), g_gametypeNames[m_coop], MF_Minifont.pal_deselected_right); - - mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8)<<16), gVolumeNames[ud.m_volume_number], MF_Minifont.pal_deselected_right); - mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8)<<16), g_mapInfo[MAXLEVELS*ud.m_volume_number+m_level_number].name, MF_Minifont.pal_deselected_right); - if (ud.m_monsters_off == 0 || ud.m_player_skill > 0) - mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8)<<16), gSkillNames[ud.m_player_skill], MF_Minifont.pal_deselected_right); - else mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8)<<16), "None", MF_Minifont.pal_deselected_right); - if (m_coop == 0) - { - if (m_marker) mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8+8)<<16), "On", MF_Minifont.pal_deselected_right); - else mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8+8)<<16), "Off", MF_Minifont.pal_deselected_right); - } - else if (m_coop == 1) - { - if (m_ffire) mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8+8)<<16), "On", MF_Minifont.pal_deselected_right); - else mminitext(origin.x + ((90+60)<<16), origin.y + ((90+8+8+8+8)<<16), "Off", MF_Minifont.pal_deselected_right); - } - break; - - case MENU_MOUSEADVANCED: - break; - - case MENU_NEWVERIFY: - videoFadeToBlack(1); - mgametextcenter(origin.x, origin.y + (90<<16), "Abort this game?" -#ifndef EDUKE32_ANDROID_MENU - "\n(Y/N)" -#endif - ); - break; - - case MENU_QUIT: - case MENU_QUIT_INGAME: - videoFadeToBlack(1); - mgametextcenter(origin.x, origin.y + (90<<16), "Are you sure you want to quit?" -#ifndef EDUKE32_ANDROID_MENU - "\n(Y/N)" -#endif - ); - break; - - case MENU_QUITTOTITLE: - videoFadeToBlack(1); - mgametextcenter(origin.x, origin.y + (90<<16), "End game and return to title screen?" -#ifndef EDUKE32_ANDROID_MENU - "\n(Y/N)" -#endif - ); - break; - - case MENU_NETWAITMASTER: - G_DrawFrags(); - mgametextcenter(origin.x, origin.y + (50<<16), "Waiting for master\n" - "to select level"); - break; - - case MENU_NETWAITVOTES: - G_DrawFrags(); - mgametextcenter(origin.x, origin.y + (90<<16), "Waiting for votes"); - break; - - case MENU_BUYDUKE: - mgametextcenter(origin.x, origin.y + (33<<16), "You are playing the shareware\n" - "version of Duke Nukem 3D. While\n" - "this version is really cool, you\n" - "are missing over 75% of the total\n" - "game, along with other great extras\n" - "which you'll get when you order\n" - "the complete version and get\n" - "the final three episodes."); - - mgametextcenter(origin.x, origin.y + ((148+16)<<16), "Press any key or button..."); - break; - case MENU_CREDITS31: l = 7; @@ -1368,110 +56,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) break; - case MENU_CREDITS32: // JBF 20031220 - l = 7; - - mgametextcenter(origin.x, origin.y + ((50-l)<<16), "Developers"); - creditsminitext(origin.x + (160<<16), origin.y + ((50+10-l)<<16), "Richard \"TerminX\" Gobeille", 8); - creditsminitext(origin.x + (160<<16), origin.y + ((50+7+10-l)<<16), "Evan \"Hendricks266\" Ramos", 8); - - mgametextcenter(origin.x, origin.y + ((80-l)<<16), "Retired developers"); - creditsminitext(origin.x + (160<<16), origin.y + ((80+10-l)<<16), "Pierre-Loup \"Plagman\" Griffais", 8); - creditsminitext(origin.x + (160<<16), origin.y + ((80+7+10-l)<<16), "Philipp \"Helixhorned\" Kutin", 8); - - mgametextcenter(origin.x, origin.y + ((130+7-l)<<16), "Special thanks to"); - creditsminitext(origin.x + (160<<16), origin.y + ((130+7+10-l)<<16), "Jonathon \"JonoF\" Fowler", 8); - - mgametextcenter(origin.x, origin.y + ((150+7-l)<<16), "Uses BUILD Engine technology by"); - creditsminitext(origin.x + (160<<16), origin.y + ((150+7+10-l)<<16), "Ken \"Awesoken\" Silverman", 8); - - - break; - - case MENU_CREDITS33: - l = 7; - - mgametextcenter(origin.x, origin.y + ((38-l)<<16), "License and Other Contributors"); - { - static const char *header[] = - { - "This program is distributed under the terms of the", - "GNU General Public License version 2 as published by the", - "Free Software Foundation. See gpl-2.0.txt for details.", - "BUILD engine technology available under license. See buildlic.txt.", - nullptr, - "The EDuke32 team thanks the following people for their contributions:", - nullptr, - }; - static const char *body[] = - { - "Alex Dawson", // "pogokeen" - Polymost2, renderer work, bugfixes - "Bioman", // GTK work, APT repository and package upkeep - "Brandon Bergren", // "Bdragon" - tiles.cfg - "Charlie Honig", // "CONAN" - showview command - "Dan Gaskill", // "DeeperThought" - testing - "David Koenig", // "Bargle" - Merged a couple of things from duke3d_w32 - "Ed Coolidge", // Mapster32 improvements - "Emile Belanger", // original Android work - "Fox", // various patches - "Hunter_rus", // tons of stuff - "James Bentler", // Mapster32 improvements - "Jasper Foreman", // netcode contributions - "Javier Martinez", // "Malone3D" - EDuke 2.1.1 components - "Jeff Hart", // website graphics - "Jonathan Strander", // "Mblackwell" - testing and feature speccing - "Jordon Moss", // "Striker" - various patches, OldMP work - "Jose del Castillo", // "Renegado" - EDuke 2.1.1 components - "Lachlan McDonald", // official EDuke32 icon - "LSDNinja", // OS X help and testing - "Marcus Herbert", // "rhoenie" - OS X compatibility work - "Matthew Palmer", // "Usurper" - testing and eduke32.com domain - "Matt Saettler", // original DOS EDuke/WW2GI enhancements - "NY00123", // Linux / SDL usability patches - "Ozkan Sezer", // SDL/GTK version checking improvements - "Peter Green", // "Plugwash" - dynamic remapping, custom gametypes - "Peter Veenstra", // "Qbix" - port to 64-bit - "Robin Green", // CON array support - "Ryan Gordon", // "icculus" - icculus.org Duke3D port sound code - "Stephen Anthony", // early 64-bit porting work - "tueidj", // Wii port - }; - EDUKE32_STATIC_ASSERT(ARRAY_SIZE(body) % 3 == 0); - static const char *footer[] = - { - nullptr, - "Visit eduke32.com for news and updates", - }; - - static constexpr int header_numlines = ARRAY_SIZE(header); - static constexpr int body_numlines = ARRAY_SIZE(body); - static constexpr int footer_numlines = ARRAY_SIZE(footer); - - static constexpr int CCOLUMNS = 3; - static constexpr int CCOLXBUF = 20; - - int c; - i = 0; - for (c = 0; c < header_numlines; c++) - if (header[c]) - creditsminitext(origin.x + (160<<16), origin.y + ((17+10+10+8+4+(c*7)-l)<<16), header[c], 8); - i += c; - for (c = 0; c < body_numlines; c++) - if (body[c]) - creditsminitext(origin.x + ((CCOLXBUF+((320-CCOLXBUF*2)/(CCOLUMNS*2)) +((320-CCOLXBUF*2)/CCOLUMNS)*(c/(body_numlines/CCOLUMNS)))<<16), origin.y + ((17+10+10+8+4+((c%(body_numlines/CCOLUMNS))*7)+(i*7)-l)<<16), body[c], 8); - i += c/CCOLUMNS; - for (c = 0; c < footer_numlines; c++) - if (footer[c]) - creditsminitext(origin.x + (160<<16), origin.y + ((17+10+10+8+4+(c*7)+(i*7)-l)<<16), footer[c], 8); - } - - break; - - default: - break; - } -} - #endif diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp index 5ccc1b28e..a8c1fb861 100644 --- a/source/sw/src/sounds.cpp +++ b/source/sw/src/sounds.cpp @@ -1169,29 +1169,7 @@ SoundShutdown(void) void MusicStartup(void) { - // if they chose None lets return - - buildprintf("Initializing MIDI driver... "); - - int status; - if ((status = MUSIC_Init(MusicDevice)) == MUSIC_Ok) - { - if (MusicDevice == ASS_AutoDetect) - MusicDevice = MIDI_GetDevice(); - } - else if ((status = MUSIC_Init(ASS_AutoDetect)) == MUSIC_Ok) - { - MusicDevice = MIDI_GetDevice(); - } - else - { - buildprintf("Music error: %s\n", MUSIC_ErrorString(status)); - return; - } - - MusicInitialized = TRUE; - MUSIC_SetVolume(mus_volume); - +#if 0 auto fil = kopenFileReader("swtimbr.tmb", 0); if (fil.isOpen()) @@ -1200,6 +1178,7 @@ void MusicStartup(void) if (tmb.Size()) AL_RegisterTimbreBank(tmb.Data()); } +#endif } void COVER_SetReverb(int amt) diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index e6fd7bc96..d559776cf 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -235,6 +235,11 @@ Reset to defaults,OPTMNU_DEFAULTS,,,,Obnovit původní,Auf Vorgaben zurücksetze Reset to last saved,OPTMNU_RESETTOSAVED,,,,Obnovit naposledy uložené,Auf gespeicherte Werte zurücksetzen,,Reŝanĝi al lasta konservo,Últimos Valores Guardados,,Palauta viimeksi tallennettu tila,Recharger dernière config.,Legutóbbi mentett beállítások használata,Reimposta ai valori salvati l'ultima volta,最後に保存した設定に戻す,이전 설정으로 초기화,Reset naar laatste opgeslagen,Resetuj do ostatnio zapisanych,Redefinir para última configuração salva,Redefinir para última configuração gravada,,Вернуть предыдущие настройки,Врати задње сачувано Go to console,OPTMNU_CONSOLE,,,,Jít do konzole,Öffne Konsole,,Iri al konzolo,Ir a la consola,,Mene konsoliin,Ouvrir la console,Konzol megnyitása,Vai alla console,コンソールを開く,콘솔로 이동,Ga naar de console,Przejdź do konsoli,Abrir console,Abrir consola,,Открыть консоль,Отвори конзолу ,Controls submenu,,,,,,,,,,,,,,,,,,,,,, +Default,CTRL_DEFAULT,,,,,Standard,,,,,,,,,,,,,,,,, +Classic,CTRL_CLASSIC,,,,,"Klassisch +",,,,,,,,,,,,,,,,, +Left-handed,CTRL_LEFTHANDED,,,,,Linkshändig,,,,,,,,,,,,,,,,, +Preferred control preset,CTRL_PRESET,,,,,Bevorzugter Steuerungsstandard,,,,,,,,,,,,,,,,, Customize Controls,CNTRLMNU_TITLE,,,,Nastavení ovládání,Steuerung einstellen,,Agordi Regilojn,Personalizar Controles ,,Ohjausasetukset,Modifier contrôles,Irányítás testreszabása,Personalizza i controlli,キー配置変更,조작 사용자 지정,Instellen van de controle,Ustaw Klawisze,Configurar Controles,Configurar Controlos,,Настройки управления,Подешавања контрола "ENTER to change, BACKSPACE to clear",CNTRLMNU_SWITCHTEXT1,,,,"ENTER pro změnu, BACKSPACE pro smazání",ENTER: Editieren BACKSPACE: Löschen,,"ENTER klavo por ŝanĝi, BACKSPACE klavo por viŝi","ENTER para cambiar, BACKSPACE para limpiar",,"Aseta ENTERILLÄ, tyhjennä ASKELPALAUTTIMELLA","ENTREE pour changer, RET. ARRIERE pour effacer.","ENTER a változtatáshoz, BACKSPACE a törléshez","INVIO per modificare, BACKSPACE per ripulire",Enter で決定、BackSpaceで無効化,"바꿀려면 ENTER키, 지울려면 BACKSPACE키를 누르시오","ENTER om te veranderen, BACKSPACE om te wissen.","ENTER by zmienić, BACKSPACE by wyczyścić","ENTER para alterar, BACKSPACE para limpar",,,"ENTER — изменить, BACKSPACE — очистить","ENTER за промену, BACKSPACE за чишћење" "Press new key for control, ESC to cancel",CNTRLMNU_SWITCHTEXT2,,,,"Zmáčkni novou klávesu pro nastavení, ESC pro storno",Drücke eine Taste oder ESC um abzubrechen,,"Premi novan klavon por reakiri regilon, ESC por nuligi","Presiona una tecla para el control, ESC para cancelar",,"Valitse näppäin toiminnolle, ESC peruuttaa","Appuyez sur la nouvelle touche pour l'assigner, @@ -256,6 +261,7 @@ Jump,CNTRLMNU_JUMP,,,,Skok,Springen,,Salti,Saltar,,Hyppää,Sauter,Ugrás,Salta, Crouch,CNTRLMNU_CROUCH,,,,Kleknutí,Ducken,,Kaŭri,Agacharse,,Kyyristy,S'accroupir (tenir),Guggolás,Abbassati,屈む,숙이기,Hurken,Kucnięcie,Agachar,,,Приседание,Чучни Crouch Toggle,CNTRLMNU_TOGGLECROUCH,,,,Zap. / Vyp. kleknutí,Ducken an/aus,,Kaŭrbaskulo,Alternar agachado,,Kyyristymisen vaihtokytkin,S'accroupir (alterner),Guggolási kapcsoló,Toggle abbassamento,屈む切替,숙이기 토글,Hurken Toggle,Włącz / Wyłącz kucnięcie,Agachar (Liga/Desliga),,,Сесть/встать,Чучни (без држања) Mouse look,CNTRLMNU_MOUSELOOK,,,,Pohled myší,Maus-Blick,,Musilregardo,Vista con ratón,,Hiirikatselu,Vue à la souris,Egérrel való nézelődés,Modalità vista col mouse,マウス視点上下化,마우스 룩,Muis-look,Rozglądanie się myszką,Vista com o mouse,Vista com o rato,,Обзор мышью,Гледај мишем +Mouse look toggle,CNTRLMNI_MLOOKTOGGLE,,,,,Maus-Blick umschalten,,,,,,,,,,,,,,,,, Look up,CNTRLMNU_LOOKUP,Look doesn't change the aim! It only alters the view pitch,,,Pohled vzhůru,Nach oben schauen,,Rigardi supre,Mirar arriba,,Katso ylös,Regarder en haut,Felfele nézés,Guarda sopra,視点を上げる,위로 보기,Kijk omhoog,Patrz w górę,Olhar para cima,,,Смотреть вверх,Гледај горе Look down,CNTRLMNU_LOOKDOWN,,,,Pohled dolů,Nach unten schauen,,Rigardi malsupre,Mirar abajo,,Katso alas,Regarder en bas,Lefele nézés,Guarda sotto,視点を下げる,아래로 보기,Kijk naar beneden,Patrz w dół,Olhar para baixo,,,Смотреть вниз,Гледај доле Aim up,CNTRLMNU_AIMUP,,,,,Nach oben zielen,,,,,,,,,,,,,,,,, @@ -330,6 +336,10 @@ Messages: OFF,MSGOFF,,,,Zprávy ZAP,Meldungen AUS,Μηνύματα ΚΛΕΙΣΤ Messages: ON,MSGON,,,,Zprávy VYP,Meldungen AN,Μηνύματα ΑΝΟΙΧΤΑ,Mesaĝoj AKTIVA,Mensajes ACTIVADOS,,Viestit PÄÄLLÄ,Messages activés.,Üzenetek BE,Messaggi ATTIVATI,メッセージ: オン,메시지 켬,Berichten AAN,Wiadomości WŁĄCZONE,Mensagens ATIVADAS,,,Сообщения ВКЛЮЧЁНЫ,Поруке УКЉУЧЕНЕ Writin': OFF,MSGOFF,,Redneck RedneckRides,,Zprávy ZAP,Geschreibsel: AUS,Μηνύματα ΚΛΕΙΣΤΑ,Mesaĝoj MALAKTIVA,Mensajes DESACTIVADOS,,Viestit POIS PÄÄLTÄ,Messages désactivés.,Üzenetek KI,Messaggi DISATTIVATI,メッセージ: オフ,메시지 끔,Berichten UIT,Wiadomości WYŁĄCZONE,Mensagens DESATIVADAS,,,Сообщения ОТКЛЮЧЕНЫ,Поруке ИСКЉУЧЕНЕ Writin': ON,MSGON,,Redneck RedneckRides,,Zprávy VYP,Geschreibsel: AN,Μηνύματα ΑΝΟΙΧΤΑ,Mesaĝoj AKTIVA,Mensajes ACTIVADOS,,Viestit PÄÄLLÄ,Messages activés.,Üzenetek BE,Messaggi ATTIVATI,メッセージ: オン,메시지 켬,Berichten AAN,Wiadomości WŁĄCZONE,Mensagens ATIVADAS,,,Сообщения ВКЛЮЧЁНЫ,Поруке УКЉУЧЕНЕ +Mouse aiming ON,TXT_MOUSEAIMON,,,,,Maus-Blick AN,,,,,,,,,,,,,,,,, +Mouse aiming OFF,TXT_MOUSEAIMOFF,,,,,Maus-Blick AUS,,,,,,,,,,,,,,,,, +Rat aimin' ON,TXT_MOUSEAIMON,I don't think this translates well...,Redneck RedneckRides,,,Maus-Blick AN,,,,,,,,,,,,,,,,, +Rat aimin' OFF,TXT_MOUSEAIMOFF,,Redneck RedneckRides,,,Maus-Blick AUS,,,,,,,,,,,,,,,,, Toggle automap,CNTRLMNU_AUTOMAP,,,,Zap. / Vyp. automapu,Automap an/aus,,Baskuligi aŭtomapo,Alternar automapa,,Kytke automaattikartta päälle/pois,Activer Carte,Térkép ki- bekapcsolása,Toggle automappa,オートマップの切替,오토맵 조정,Automap aan/uit,Włącz mapę,Ativar automapa,,,Открыть автокарту,Прикажи аутомапу Chasecam,CNTRLMNU_CHASECAM,,,,Kamera z třetí osoby,Verfolgerkamera,,Ĉaskamerao,Cámara de Seguimiento,,Seurantakamera,Caméra 3ième personne,Külsőnézetű kamera,Telecamera di inseguimento,背後視点,3인칭 카메라,,Kamera Śledzenia,Câmera de terceira-pessoa,Câmera em terceira-pessoa,,Вид от 3-го лица (Chasecam),Чејс-кем Screenshot,CNTRLMNU_SCREENSHOT,,,,Pořídit snímek obrazovky,,,Ekranfoto,Captura de pantalla,,Kuvakaappaus,Capture d'écran,Képernyő lefényképezése,Cattura schermo,画面キャプチャ,스크린샷,,Zrzut ekranu,Captura de tela,,,Скриншот,Усликај @@ -461,7 +471,7 @@ If New,PLRMNU_IFNEW,,,,,Wenn neu,,,,,,,,,,,,,,,,, Equip Weapon Pickups,PLRMNU_EQUIP,,,,,Waffen sofort aktivieren,,,,,,,,,,,,,,,,, Parental Lock,PLRMNU_PLOCK,,,,,Kindersicherung,,,,,,,,,,,,,,,,, Only preferred,PLRMNU_PREFERRED,,,,,Nur bevorzugte,,,,,,,,,,,,,,,,, -,Display,,,,,,,,,,,,,,,,,,,,,, +,Display/HUD,,,,,,,,,,,,,,,,,,,,,, Display Options,DSPLYMNU_TITLE,,,,Nastavení grafiky,Anzeigeoptionen,,Ekranagordoj,Opciones de visualización,,Näyttöasetukset,Options Affichage,Megjelenítés beállítások,Opzioni display,ディスプレイ オプション,디스플레이 설정,Weergaveopties,Opcje Wyświetlania,Opções de Vídeo,,,Настройки экрана,Подешавања приказа Screen size,DSPLYMNU_SCREENSIZE,,,,Velikost obrazovky,Bildschirmgröße,,Ekrano-grandeco,Tamaño de pantalla,,Näytön koko,Taille de l'écran,Képernyő mérete,Dimensione della schermata,画面サイズ,화면 크기,Schermgrootte,Rozmiar Ekranu,Tamanho de tela,Tamanho do ecrã,,Размер экрана,Величина екрана Vertical Sync,DSPLYMNU_VSYNC,,,,Vertikální synchronizace,Vertikale Synchronisation,,Vertikala-sinkronigo,Sincr. vertical,,Pystytahdistys,Synchronisation Verticale,Függőleges szinkronizálás,Sync verticale,垂直同期,수직 동기화,Verticale Sync,Synchronizacja Pionowa,Sincronização Vertical,,,Вертикальная синхронизация,Вертикална синхорнизација @@ -490,80 +500,253 @@ None (linear mipmap),OPTVAL_NONELINEARMIPMAP,,,,Žádné (lineární mipmapa),Au None (trilinear),OPTVAL_NONETRILINEAR,,,,Žádné (trilineární),Aus (trilinear),,Nenio (trilinia),Ninguno (trilineal),,Ei mitään (trilineaarinen),Aucun (mipmap trilinéaire),,Nessuno (mipmap trilineare),なし(トライリニア),없음 (삼선형),Geen (trilineair),Brak (trzyliniowe),Nenhum (trilinear),,,Нет (трилинейная),Ништа (трилинеарно) Bilinear,OPTVAL_BILINEAR,,,,Bilineární,,,Dulinia,Bilineal,,Bilineaarinen,Bilinéaire,,Bilineare,バイリニア,쌍선형,Bilineair,Dwuliniowe,,,,Билинейная,Билинеарно Trilinear,OPTVAL_TRILINEAR,,,,Trilineární,,,Trilinia,Trilineal,,Trilineaarinen,Trilinéaire,,Trilineare,トライリニア,삼선형,Trilineair,Trzyliniowe,,,,Трилинейная,Трилинеарно -Linear,OPTVAL_LINEAR_2,,,,Lineární,,,Lineara,Lineal,,Lineaarinen,Linéaire,,Lineare,リニア,선형,Lineair,Liniowa,,,,Линейная,Линеаран 2x,OPTVAL_2X,,,,,,,2-oble,,,,,,,,,,,,,,, 4x,OPTVAL_4X,,,,,,,4-oble,,,,,,,,,,,,,,, 8x,OPTVAL_8X,,,,,,,8-oble,,,,,,,,,,,,,,, 16x,OPTVAL_16X,,,,,,,16-oble,,,,,,,,,,,,,,, 32x,OPTVAL_32X,,,,,,,32-oble,,,,,,,,,,,,,,, +,Polymost,,,,,,,,,,,,,,,,,,,,,, +True Color Textures,POLYMOST_TC,,,True Colour Textures,,True Color Texturen,,,,,,,,,,,,,,,,, +Pre-load map textures,POLYMOST_CACHE,,,,,Texturen cachen,,,,,,,,,,,,,,,,, +Detail Textures,POLYMOST_DETAIL,,,,,Detailtexturen,,,,,,,,,,,,,,,,, +Glow Textures,"POLYMOST_GLOW +",,,,,Leucht-Texturen,,,,,,,,,,,,,,,,, +3D-Models,POLYMOST_MODELS,,,,,3D Modelle,,,,,,,,,,,,,,,,, +"Polymost Options +",POLYMOST_OPTIONS,,,,,Polymost-Optionen,,,,,,,,,,,,,,,,, +Palette Emulation,POLYMOST_PALETTEEMU,,,,,Palettenemulation,,,,,,,,,,,,,,,,, +Palette Interpolation,POLYMOST_PALINTER,,,,,Paletteninterpolation,,,,,,,,,,,,,,,,, +,Sound,,,,,,,,,,,,,,,,,,,,,, +4000 Hz,OPTVAL_4000HZ,,,,,,,,,,,,,,,,,,,,,4000 Гц, +8000 Hz,OPTVAL_8000HZ,,,,,,,,,,,,,,,,,,,,,8000 Гц, +11025 Hz,OPTVAL_11025HZ,,,,,,,,,,,,,,,,,,,,,11025 Гц, +22050 Hz,OPTVAL_22050HZ,,,,,,,,,,,,,,,,,,,,,22050 Гц, +32000 Hz,OPTVAL_32000HZ,,,,,,,,,,,,,,,,,,,,,32000 Гц, +44100 Hz,OPTVAL_44100HZ,,,,,,,,,,,,,,,,,,,,,44100 Гц, +48000 Hz,OPTVAL_48000HZ,,,,,,,,,,,,,,,,,,,,,48000 Гц, +64 samples,OPTVAL_64SAMPLES,,,,64 vzorků,64 Samples,,64 specimenoj,64 Muestras,,64 näytettä,,,,,64 샘플,,64 sample,64 amostras,,,64 семпла,64 узорка +128 samples,OPTVAL_128SAMPLES,,,,128 vzorků,128 Samples,,128 specimenoj,128 Muestras,,128 näytettä,,,,,128 샘플,,128 sampli,128 amostras,,,128 семплов,128 узорка +256 samples,OPTVAL_256SAMPLES,,,,256 vzorků,256 Samples,,256 specimenoj,256 Muestras,,256 näytettä,,,,,256 샘플,,256 sampli,256 amostras,,,256 семплов,256 узорка +512 samples,OPTVAL_512SAMPLES,,,,512 vzorků,512 Samples,,512 specimenoj,512 Muestras,,512 näytettä,,,,,512 샘플,,512 sampli,512 amostras,,,512 семплов,512 узорка +1024 samples,OPTVAL_1024SAMPLES,,,,1024 vzorků,1024 Samples,,1024 specimenoj,1024 Muestras,,1024 näytettä,,,,,1024 샘플,,1024 sampli,1024 amostras,,,1024 семпла,1024 узорка +2048 samples,OPTVAL_2048SAMPLES,,,,2048 vzorků,2048 Samples,,2048 specimenoj,2048 Muestras,,2048 näytettä,,,,,2048 샘플,,2048 sampli,2048 amostras,,,2048 семплов,2048 узорка +4096 samples,OPTVAL_4096SAMPLES,,,,4096 vzorků,4096 Samples,,4096 specimenoj,4096 Muestras,,4096 näytettä,,,,,4096 샘플,,4096 sampli,4096 amostras,,,4096 семплов,4096 узорка +Auto,OPTSTR_AUTO,,,,,,,Aŭtomata,Automático,,Automaattinen,,,Automatico,自動,오토,,Automatycznie,Automático,,,Авто,Аутоматски +Mono,OPTSTR_MONO,,,,,,,1 Laŭtparolilo,,,,,,,モノラル,모노,,,,,,Моно,Монотоно +Stereo,OPTSTR_STEREO,,,,,,,2 Laŭtparoliloj,Estereo,,,Stéréo,,,ステレオ,스테레오,,,Estéreo,,,Стерео,Стереотоно +Dolby Pro Logic Decoder,OPTSTR_PROLOGIC,,,,,,,Malkodilo de Dolby Pro Logic ,,,,,,,ドルビー プロロジック デコーダー,돌비 프로 로직 디코더,,,,,,Декодер Dolby Pro Logic, +Quad,OPTSTR_QUAD,,,,,,,4 Laŭtparolilol,Cuádruple,,Dolby Pro Logic -dekooderi,,,,クァッド,쿼드,,Cztery kanały,,,,Четырёхканальный,Четвородупло +5 speakers,OPTSTR_SURROUND,,,,5 reproduktorů,5 Lautsprecher,,5 Laŭtparoliloj,5 altavoces,5 Bocinas,5 kaiutinta,5 enceintes,,,5 スピーカー,5 스피커,5 luidsprekers,Głośniki 5,5 alto falantes,,,5 динамиков,5 спикер +5.1 speakers,OPTSTR_5POINT1,,,,Reproduktory 5.1,5.1 Lautsprecher,,5.1 Laŭtparoliloj,Altavoces 5.1,Bocinas 5.1,5.1 kaiutinta,Enceintes 5.1,,,5.1 スピーカー,5.1 스피커,5.1 luidsprekers,Głośniki 5.1,Auto falantes 5.1,,,Динамики 5.1,5.1 спикер +7.1 speakers,OPTSTR_7POINT1,,,,Reproduktory 7.1,7.1 Lautsprecher,,7.1 Laůtparoliloj,Altavoces 7.1,Bocinas 7.1,7.1 kaiutinta,Enceintes 7.1,,,7.1 スピーカー,7.1스피커,7.1 luidsprekers,Głośniki 7.1,Auto falantes 7.1,,,Динамики 7.1,7.1 спикер +OpenAL Options,OPENALMNU_TITLE,,,,Nastavení OpenAL,OpenAL Optionen,,OpenAL-agordoj,Opciones de OpenAL,,OpenAL-asetukset,Options OpenAL,,Opzioni OpenAL,OpenAL オプション,오픈에이엘 설정,OpenAL opties,Opcje OpenAL,Opções de OpenAL,,,Настройки OpenAL,OpenAL подешавања +Playback device,OPENALMNU_PLAYBACKDEVICE,,,,Přehravací zařízení,Wiedergabegerät,,Ludado-aparato,Dispositivo de reproducción,,Äänitoistolaite,Sortie sonore,,Dispositivo di playback,プレイバック デバイス,재생 장치,Afspeelapparaat,Urządzenie odtwarzania,Dispositivo de reprodução,,,Устройство воспроизведения,Аудио уређај +Enable EFX,OPENALMNU_ENABLEEFX,,,,Povolit EFX,EFX aktiv,,Aktivigi EFX,Permitir EFX,,Ota käyttöön EFX,Activer EFX,,Abilita EFX,EFXを有効化,EFX 켬,EFX inschakelen,Pozwól na EFX,Habilitar EFX,,,Включить EFX,Укључи EFX +Resampler,OPENALMNU_RESAMPLER,,,,,,,Respecimenilo,,,Näytteenottotaajuusmuunnin,,,,リサンプラー,재배열 기기,,Resampler,,,,Ресэмплер,Ресемплер +Sound Options,SNDMNU_TITLE,,,,Nastavení zvuku,Soundeinstellungen,,Son-agordoj,Opciones de sonido,,Ääniasetukset,Options Sonores,Hangbeállítások,Opzioni del suono,サウンド オプション,음향 설정,Geluidsopties,Opcje Dźwięku,Opções de Áudio,,,Настройки звука,Звучна подешавања +Sounds volume,SNDMNU_SFXVOLUME,,,,Hlasitost zvuků,Effektlautstärke,,Son-laŭtec-menuo,Volumen de sonido,,Äänitehosteiden voimakkuus,Volume des Sons,Effektek hangereje,Volume suoni,効果音音量,효과음 음량,Geluidsvolume,Głośność Dźwięku,Volume de sons,,,Громкость звука,Јачина звука +Menu volume,SNDMNU_MENUVOLUME,,,,Hlasitost nabídek,Menülautstärke,,Menu-laŭteco,Volumen del menú,,Valikon äänenvoimakkuus,Volume du Menu,Menü hangereje,Volume menu,メニュー音量,메뉴 음량,Menu volume,Głośność Menu,Volume do menu,,,Громкость меню,Јачина менија +Music volume,SNDMNU_MUSICVOLUME,,,,Hlasitost hudby,Musiklautstärke,,Muzik-laŭteco,Volumen de la Música,,Musiikin äänenvoimakkuus,Volume Musique,Zene hangereje,Volume musica,音楽音量,배경음 음량,Muziekvolume,Głośność Muzyki,Volume da música,,,Громкость музыки,Јачина музике +MIDI device,SNDMNU_MIDIDEVICE,,,,MIDI zařízení,MIDI-Gerät,,MIDI-aparato,Dispositivo MIDI,,MIDI-laite,Sortie MIDI,MIDI eszköz,Dispositivo MIDI,MIDIデバイス,MIDI 장치,MIDI-apparaat,Urządzenie MIDI,Dispositivo MIDI,,,MIDI проигрыватель,MIDI уређај +Sound in Background,SNDMNU_BACKGROUND,,,,Zvuk na pozadí,Sound im Hintergrund,,Sono en Fono,Sonido en segundo plano,,Ääni taustalla,Son activé en arrière plan,Háttérhangok,Suono di sottofondo,バックグラウンドでのサウンド,배경화면에서도 소리 재생,Geluid in de achtergrond,Dźwięk w Tle,Som de Fundo,,,Звуки в фоне,Звуци у позадини +Underwater reverb,SNDMNU_UNDERWATERREVERB,,,,Ozvěna pod vodou,Unterwasserhall,,Subakva resono,Reverb. bajo el agua,,Vedenalaiskaiku,Reverbération sous l'eau,Vízalatti viszhang,Reverb sott'acqua,水中反響音,수중 울림효과,Onderwater nagalm,Pogłos pod wodą,Reverberação debaixo d'água,Reverberação debaixo de água,,Эффект под водой,Подводни одјек +Randomize pitches,SNDMNU_RANDOMIZEPITCHES,,,,Náhodné výšky tónu,Zufällige Tonhöhe,,Malcertigi son-peĉojn,Tonos aleatorios,,Satunnaista äänenkorkeuksia,Tons sonores aléatoires,Hangmagasság véletlenszerű,Rendi casuale il tono,ランダマイズ ピッチ,음높이 무작위화,Willekeurige plaatsen,Losuj tonacje,Aleatorizar tons,Tons aleatórios,,Изменять высоту,Рандомизација тонова +Sound channels,SNDMNU_CHANNELS,,,,Počet zvukových kanálů,Soundkanäle,,Son-kanaloj,Canales de sonido,,Äänikanavat,Canaux sonores,Hangcsatorna,Numero canali del suono,サウンド チャンネル,음향 채널,Geluidskanalen,Kanały dźwiękowe,Canais de som,,,Количество каналов,Звучни канали +Sound backend,SNDMNU_BACKEND,,,,Zvukový systém,Soundsystem,,Son-servilo,Sistema de sonido,,Äänijärjestelmä,Traitement Son,,Backend suono,サウンド バックエンド,음향 말미,Geluidsarme achterkant,System dźwiękowy,Sistema de som,,,Звуковая система,Звучни бекенд +OpenAL options,SNDMNU_OPENAL,,,,Nastavení OpenAL,OpenAL Optionen,,OpenAL-agordoj,Opciones de OpenAL,,OpenAL-asetukset,Options OpenAL,OpenAL beállításai,Opzioni OpenAL,OpenAL オプション,오픈에이엘 설정,OpenAL opties,Opcje OpenAL,Opções de OpenAL,,,Настройки OpenAL,OpenAL подешавања +Restart sound,SNDMNU_RESTART,,,,Restartovat zvuk,Sound neu starten,,Rekomenci sonon,Reiniciar sonido,,Käynnistä ääni uudelleen,Redémarrer moteur sonore,Hang újraindítása,Resetta il suono,サウンド再起動,음향 재시작,Herstart geluid,Zresetuj dźwięk,Reiniciar som,,,Перезапустить звук,Поново покрени звук +Advanced options,SNDMNU_ADVANCED,,,,Pokročilá nastavení,Erweiterte Optionen,,Altnivelaj agordoj,Opciones avanzadas,,Edistyneet asetukset,Options avancées,Haladó beállítások,Opzioni avanzate,高度なオプション,고급 설정,Geavanceerde opties,Zaawansowane Opcje,Opções avançadas,,,Расширенные настройки,Напредна подешавања +Module replayer options,SNDMNU_MODREPLAYER,,,,Nastavení přehrávače modulů,Modul-Spieler-Optionen,,Agordoj por modulreludilo,Opciones reproductor de módulos,,Moduulisoitinasetukset,Options lecteur de module,,Opzioni Module replayer,モジュールリプレイヤー オプション,모듈 재생 설정,Module replayer opties,Opcje Modułu Odtwarzacza,Opções de reprodutor de módulos,,,Параметры воспроизведения модулей,Подешавања модулног риплејера +Midi player options,SNDMNU_MIDIPLAYER,,,,Nastavení MIDI přehrávače,MIDI-Spieler-Optionen,,Agordoj por MIDI-ludilo,Opciones de reproductor MIDI,,MIDI-soitinasetukset,Option lecteur MIDI,,Opzioni Midi player,Midi再生のオプション,MIDI 플레이어 설정,Midi speler opties,Opcje Odtwarzacza Midi,Opções de reprodutor MIDI,,,Настройки MIDI-проигрывателя,MIDI плејер подешавања +Sound in Menus,SNDMNU_MENUSOUND,,,,,Sound in Menüs,,,,,,,,,,,,,,,,, +Advanced Sound Options,ADVSNDMNU_TITLE,,,,Pokročilá nastavení zvuku,Erweiterte Soundoptionen,,Altnivelaj Son-agordoj,Opciones avanzadas de sonido,,Edistyneet ääniasetukset,Options Sonores Avancées,,Opzioni avanzate dei suoni,高度なサウンドオプション,고급 음향 설정,Geavanceerde geluidsopties,Zaawansowane Opcje Dźwięku,Opções de Áudio Avançadas,,,Расширенные настройки,Напредна подешавања звука +Sample rate,ADVSNDMNU_SAMPLERATE,,,,Vzorkovací frekvence,Samplerate,,Specimenrapideco,Frecuencia de muestreo,,Näytteenottotaajuus,Cadence de Sampling,,,サンプルレート,샘플링레이트,Steekproeftarief,Częstotliwość próbkowania,Taxa de amostragem,,,Частота дискретизации,Фреквенција узорковања +HRTF,ADVSNDMNU_HRTF,,,,,,,,,,,,,,,머리전달함수,,HRTF,,,,, +OPL Synthesis,ADVSNDMNU_OPLSYNTHESIS,,,,Emulace OPL,OPL Synthese,,OPL-Sintezo,Síntesis OPL,,OPL-synteesi,Synthèse OPL,,,OPLシンセサイズ,OPL 합성,OPL synthese,Synteza OPL,Síntese OPL,,,Синтез OPL,OPL синтеза +Number of emulated OPL chips,ADVSNDMNU_OPLNUMCHIPS,,,,Počet emulovaných OPL čipů,Anzahl OPL Chips,,Nombro da imititaj OPL-blatoj,Número de chips OPL emulados,,Emuloitavien OPL-piirien lukumäärä,Puces OPL émulées,,Numero di chip OPL emulati,OPLチップエミュレートの番号,에뮬레이트된 OPL 칩 수,Aantal geëmuleerde OPL chips,Liczba emulowanych czipów OPL,Número de chips OPL emulados,,,Количество эмулируемых OPL чипов,Број емулираних OPL чипа +Full MIDI stereo panning,ADVSNDMNU_OPLFULLPAN,,,,Plné MIDI stereo,Echte MIDI-Stereoeffekte,,Tuta MIDI-sterepanoramado,Balance estéreo MIDI completo,,Täysi MIDI-stereopanorointi,Latéralisation complète MIDI,,,Full MIDIステレオパンニング,완전한 MIDI 스테레오 패닝,Volledige MIDI stereo panning,Pełne efekty stereo dla MIDI,Lateralidade estéreo completa para MIDI,,,Полная стереопанорама для MIDI,Пуно MIDI стерео каналисање +OPL Emulator Core,ADVSNDMNU_OPLCORES,,,,Emulační jádro OPL,OPL Emulatorkern,,OPL Imitilkerno,Núcleo de emulador OPL,,OPL-emulaattoriydin,Cœur émulateur OPL,,,OPL エミュレート コア,OPL 에뮬레이터 코어,OPL Emulator Kern,Rdzeń Emulatora OPL,Núcleo do emulador de OPL,,,Ядро эмуляции OPL,OPL језгро емулације +MIDI voices,ADVSNDMNU_MIDIVOICES,,,,Počet MIDI hlasů,MIDI Stimmen,,MIDI Voĉoj,Voces MIDI,,MIDI-äänet,Voix MIDI,,Voci MIDI,MIDI ボイス,MIDI 최대 음색 양,MIDI-stemmen,Głosy MIDI,Vozes MIDI,,,MIDI-голоса,MIDI гласови +FluidSynth,ADVSNDMNU_FLUIDSYNTH,,,,,,,,,,,,,,,,,,,,,, +Patch set,ADVSNDMNU_FLUIDPATCHSET,,,,Nástrojová sada,Patch-Set,,Flikaro,Set de parche,,Patch-asetus,Banque de Sons,,,パッチ セット,패치 세트,,Zestaw patchów,Banco de sons,,,Патч-набор,Печ сет +Gain,ADVSNDMNU_FLUIDGAIN,,,,Zesílení,Relative Lautstärke,,Akiro,Ganancia,,Vahvistus,,,,ゲイン,쌓기,Relatief volume,Wzmocnienie,Ganho,,,Усиление,Појачање +Reverb,ADVSNDMNU_REVERB,,,,Ozvěna,Hall,,Resono,Reverberación,,Kaiku,Réverbération,,,リバーブ,리버브,Nagalm,Pogłos,Reverberação,,,Реверберация,Одјек +Reverb Level,ADVSNDMNU_REVERB_LEVEL,,,,Intenzita ozvěny,Hallintensität,,Resono-nivelo,Nivel de Reverberación,,Kaiunvoimakkuus,Niveau Réverb.,,,リバーブ量,리버브 강도,Nagalm niveau,Poziom pogłosu,Nível de reverberação,,,Уровень реверберации,Ниво одјека +Chorus,ADVSNDMNU_CHORUS,,,,,,,Koruso,,,,,,,コーラス,코러스,,,,,,Хорус,Корус +Timidity++,ADVSNDMNU_TIMIDITY,,,,,,,,,,,,,,,,,,,,,, +ADLMidi,ADVSNDMNU_ADLMIDI,,,,,,,,,,,,,,,,,,,,,, +OPNMidi,ADVSNDMNU_OPNMIDI,,,,,,,,,,,,,,,,,,,,,, +Timidity config file,ADVSNDMNU_TIMIDITYCONFIG,,,,Konfigurační soubor Timidity,Timidity Konfigurationsdatei,,Agordo-arkivo por Timidity,Ruta al archivo config. Timidity,,Timidity-config-tiedosto,Fichier de config. TiMidity,,File Timidity config,Timidity コンフィグファイル,Timidity 코딩 파일,Timidity++ configuratiebestand,Plik konfiguracyjny Timidity,Arquivo de configuração do Timidity,,,Файл конфигурации Timidity,Timidity конфигурациона датотека +Relative volume,ADVSNDMNU_TIMIDITYVOLUME,,,,Relativní hlasitost,Relative Lautstärke,,Relativa volumeno,Volumen relativo,,Suhteellinen äänenvoimakkuus,Volume Relatif,,Volume relativo,相対音量,비교적인 볼륨,Relatief volume,Względna głośność,Volume relativo,,,Относительная громкость,Релативна јачина +WildMidi,ADVSNDMNU_WILDMIDI,,,,,,,,,,,,,,,,,,,,,, +WildMidi config file,ADVSNDMNU_WILDMIDICONFIG,,,,Konfigurační soubor WildMidi,WilfMidi Konfigurationsdatei,,WildMidi agordarkivo,Archivo de config. WildMidi,,WildMidi-config-tiedosto,Fichier config. WildMidi,,File WildMidi config,WildMidi コンフィグファイル,WildMidi 코딩 파일,WildMidi configuratiebestand,Plik konfiguracyjny WildMidi,Arquivo de configuração do WildMidi,,,Файл конфигурации WildMidi,WildMidi конфигурациона датотека +Select configuration,ADVSNDMNU_SELCONFIG,,,,Vybrat konfiguraci,Konfiguration wählen,,Elekti agordojn,Seleccionar configuración,,Valitse kokoonpano,Sélectionner configuration,,Seleziona la configurazione,構成選択,설정을 고르시오,Selecteer configuratie,Wybierz konfigurację,Selecionar configuração,,,Выбор конфигурации,Изабери конфигурацију +Global,ADVSNDMNU_GLOBAL,,,,Globální,,,Malloka,Global,,Yleinen,,,Globale,グローバル,전반적,Globaal,Globalne,,,,Общие,Глобално +Freeverb,ADVSNDMNU_FREEVERB,,,,,,,,,,,,,,フリーバーブ,프리버브,,,,,,, +Global Freeverb,ADVSNDMNU_GLOBAL_FREEVERB,,,,Globální Freeverb,Globales Freeverb,,Malloka Freeverb,Freeverb Global,,Yleinen Freeverb,Freeverb Global,,Freeverb globale,グローバル フリーバーブ,전반적 프리버브,Globale Freeverb,Globalny Freeverb,Freeverb Global,,,Глобальный Freeverb,Глобални Freeverb +Advanced Resampling,ADVSNDMNU_ADVRESAMPLING,,,,Pokročilé převzorkování,Erweitertes Resampling,,Altnivela respecimenado,Resampleo Avanzado,,Kehittynyt näytteenottotaajuuden muuntaminen,Resampling Avancé,,Resampling avanzato,高度なリサンプリング,향상된 리샘플링,Geavanceerde herbemonstering,Zaawansowane Próbkowanie,Reamostragem Avançada,,,Продвинутый ресэмплинг,Напредно ресампловање +OPL Bank,ADVSNDMNU_OPLBANK,,,,OPL sada,,,Banko por OPL,Banco OPL,,OPL-pankki,Banque OPL,,,,OPL 뱅크,,Bank OPL,Banco OPL,,,Банк OPL,OPL банка +OPL Emulator Core,ADVSNDMNU_ADLOPLCORES,,,,Emulační jádro OPL,OPL Emulatorkern,,Imitilkerno por OPL,Núcleos de Emulador OPL,,OPL-emulaattoriydin,Cœur Emulateur OPL,,,OPL エミュレートコア,OPL 에뮬레이터 코어,OPL Emulator Kern,Rdzeń Emulatora OPL,Núcleo do Emulador de OPL,,,Ядро эмуляции OPL,OPL емулационо језгро +Run emulator at PCM rate,ADVSNDMNU_RUNPCMRATE,,,,Emulátor používá PCM vzorkovací frekvenci,Emulator benutzt PCM Samplerate,,Kurigi imitilon laŭ rapido de PCM,Ejecutar emulador a velocidad PCM,,Aja emulaattoria PCM-taajuudella,Emulateur utilise cadence PCM,,Esegui l'emulatore con rate PCM,PCMレートでエミュレート実行,PCM 속도로 에뮬레이터 실행,Emulator maakt gebruik van PCM Samplerate,Uruchom emulator w częstotliwości PCM,Rodar emulador em taxa PCM,,,Использовать с частотой PCM,Покрени емулацију на PCM стопи +Number of emulated OPL chips,ADVSNDMNU_ADLNUMCHIPS,,,,Počet emulovaných OPL čipů,Anzahl OPL Chips,,Numbro da imitaj OPL-blatoj,Número de chips OPL emulados,,Emuloitavien OPL-piirien lukumäärä,Puces OPL émulées,,Numero di chip OPL emulati,OPLチップエミュレートの番号,에뮬레이트된 OPL 칩 개수,Aantal geëmuleerde OPL chips,Liczba emulowanych czipów OPL,Número de chips OPL emulados,,,Количество эмулируемых чипов OPL,Број емулираних OPL чипова +Volume model,ADVSNDMNU_VLMODEL,,,,Model hlasitosti,Lautstärkemodell,,Volumen-modelo,Modelo de Volumen,,Äänenvoimakkuusmalli,Modèle de Volume,,Modello di volume,音量モデル,모델 볼륨,Volume model,Model głośności,Modelo de volume,,,Модель громкости,Волумски модел +Aliasing,OPTVAL_ALIASING,,,,,,,Kromnomado,,,,,,,エイリアシング,에일리어싱,,,,,,Алиасинг,Преклапање +Linear,OPTVAL_LINEAR_1,This setting is duplicated threefold in order to allow for different grammatical gender endings,,,Lineární,,,Lineara,Lineal,,Lineaarinen,Linéaire,,Lineare,リニア,선형,Lineair,Liniowy,,,,Линейное,Линеаран +Linear,OPTVAL_LINEAR_2,,,,Lineární,,,Lineara,Lineal,,Lineaarinen,Linéaire,,Lineare,リニア,선형,Lineair,Liniowa,,,,Линейная,Линеаран +Linear,OPTVAL_LINEAR_3,,,,Lineární,,,Lineara,Lineal,,Lineaarinen,Linéaire,,Lineare,リニア,선형,Lineair,Liniowe,,,,Линейный,Линеаран +Nearest,OPTVAL_NEAREST,,,,Nejbližší,Nächster Nachbar,,Plej proksima,Cercano,,Lähin,Nearest,,Il più vicino,最寄り,가까이,Naast,Najbiższe,Vizinho mais próximo,,,Ближайший,Најближе +PCF (Low),OPTVAL_PCF_LOW,,,,PCF (nízké),PCF (niedrig),,PCF (Malata),PCF (Bajo),,PCF (matala),PCF (Low),,PCF (basso),PCF (低),PCF (하급),PCF (Laag),PCF (Niski),PCF (Baixo),,,PCF (низкий),PCF (ниско) +PCF (Medium),OPTVAL_PCF_MEDIUM,,,,PCF (střední),PCF (mittel),,PCF (Meza),PCF (Medio),,PCF (keskitaso),PCF (Medium),,PCF (medio),PCF (中),PCF (중급),PCF (Medium),PCF (Średni),PCF (Médio),,,PCF (средний),PCF (средње) +PCF (High),OPTVAL_PCF_HIGH,,,,PCF (vysoké),PCF (hoch),,PCF (Alta),PCF (Alto),,PCF (korkea),PCF (High),,PCF (alto),PCF (高),PCF (상급),PCF (Hoog),PCF (Wysoki),PCF (Alto),,,PCF (высокий),PCF (високо) +Cubic,OPTVAL_CUBIC,,,,Kubická,Kubisch,,Kuba,Cúbico,,Kuutio,Cubique,,Cubico,キュービック,큐빅,Kubieke,Sześcienny,Cúbico,,,Кубическое,Кубан +Band-limited step,OPTVAL_BLEP,,,,Omezené krokování,Bandbegrenzte Schritte,,Bendo-limigita paŝo,Paso limitado por banda,,Kaistarajoitettu askel,Step limité par bande,,Passo limitato dalla banda,帯域制限ステップ,제한된 단계별 밴드,Bandbeperkte stap,Krok ograniczony pasmem,Passo limitado por banda,,,Пошаговое ограничение частоты,Постепено ограничење фреквенције +Linear (Slower),OPTVAL_LINEARSLOW,,,,Lineární (pomalejší),Linear (langsamer),,Lineara (Pli malrapida),Lineal (más lento),,Lineaarinen (hitaampi),Linéaire (Lent),,Lineare (più lento),リニア(遅め),선형 (느리게),Lineair (langzamer),Liniowy (wolniejszy),Linear (Mais lento),,,Линейное (медленнее),Линеаран (спорије) +Band-limited linear,OPTVAL_BLAM,,,,Omezená lineární,Bandbegrenzt linear,,Bendo-limigita lineara,Lineal limitado por banda,,Kaistarajoitettu lineaarinen,Linéaire limité par bande,,Lineare limitato dalla banda,帯域制限リニア,밴드 제한 식 선형,Band-beperkt lineair,Liniowy ograniczony pasmem,Linear limitado por banda,,,Линейное ограничение частоты,Линеарно ограничење фреквенције +Cubic (Slower),OPTVAL_CUBICSLOW,,,,Kubická (pomalejší),Kubisch (langsamer),,Kuba (Pli malrapida),Cúbico (más lento),,Kuutio (hitaampi),Cubique (Lent),,Cubico (più lento),キュービック (遅め),큐빅 (느리게),Kubieke (langzamer),Sześcienny (wolniejszy),Cúbico (Mais lento),,,Кубическое (медленнее),Кубан (спорије) +Sinc,OPTVAL_SINC,,,,,,,,Seno cardinal,,,,,,シンク,싱크,,,,,,Кардинальный синус,Синк +Note on/off only,OPTVAL_NOTEONOFFONLY,,,,Pouze začátek/konec noty,Nur für Note an/aus ,,Nur noton aktivigi/malatkivigi,Sólo notas de Activ./Desact.,,Vain nuotti päällä/pois,Note on/off seulement,,Note solamente ON/OFF,ノート オン/オフ のみ,노트를 끄거나 켰을 때,Alleen toon aan/uit,Tylko dla włączonych/wyłączonych notatek,Somente notas lig./deslig.,,,Только при включении/отключении нот,Само током укључења/искључења ноте +Full ramping,OPTVAL_FULLRAMPING,,,,Plný náběh,,,Plena rampante,Aumento completo,,Täysi kerrytys,Rampe complète,,Ramping completo,フルランピング,최대 램핑,Volledige helling,Pełne zwiększenie,Rampa completa,,,Полное наращивание,Пуно појачање +Module Replayer Options,MODMNU_TITLE,,,,Nastavení přehrávače modulů,Modul-Spieler-Optionen,,Agordoj por Modulo-reludilo,Opciones de reproductor de módulos,,Moduulisoitinasetukset,Options Lecteur de Module,,Opzioni Module replayer,モジュールリプレイヤー オプション,모듈 재생 설정,Module Speler Opties,Opcje Odtwarzacza Modułów,Opções de Reprodutor de Módulos,,,Параметры воспроизведения модулей,Подешавања модуларног реплејера +Master volume,MODMNU_MASTERVOLUME,,,,Celková hlasitost,Grundlautstärke,,Ĉefvolumeno,Volumen maestro,,Yleisäänenvoimakkuus,Volume maître,,Volume master,全体音量,마스터 볼륨,Hoofdvolume,Całkowita głośność,Volume master,,,Общая громкость,Глацни звук +Quality,MODMNU_QUALITY,,,,Kvalita,Qualität,,Kvaliteco,Calidad,,Laatu,Qualité,,Qualità,クオリティ,품질,Kwaliteit,Jakość,Qualidade,,,Качество,Квалитет +Volume ramping,MODMNU_VOLUMERAMPING,,,,Křivka hlasitosti,Lautstärkeverhalten,,Volumeno-pligrandigado,Aumento gradual de Volumen,,Äänenvoimakkuuden kertyminen,Rampe du volume,,Ramping volume,音量ランピング,볼륨 램핑,Volume-aanvulling,Zwiększenie głośności,Rampa de volume,,,Наращивание громкости,Појачавање звука +Chip-o-matic,MODMNU_CHIPOMATIC,,,,,,,,,,,,,,チップ オー マチック,칩-오-매틱,,,,,,, +Global,ADVSNDMNU_GLOBAL,,,,Globální,,,Malloka,Global,,Yleinen,,,Globale,グローバル,전반적,Globaal,Globalne,,,,Общие,Глобално +Freeverb,ADVSNDMNU_FREEVERB,,,,,,,,,,,,,,フリーバーブ,프리버브,,,,,,, +Global Freeverb,ADVSNDMNU_GLOBAL_FREEVERB,,,,Globální Freeverb,Globales Freeverb,,Malloka Freeverb,Freeverb Global,,Yleinen Freeverb,Freeverb Global,,Freeverb globale,グローバル フリーバーブ,전반적 프리버브,Globale Freeverb,Globalny Freeverb,Freeverb Global,,,Глобальный Freeverb,Глобални Freeverb +FluidSynth,ADVSNDMNU_FLUIDSYNTH,,,,,,,,,,,,,,,,,,,,,, +Patch set,ADVSNDMNU_FLUIDPATCHSET,,,,Nástrojová sada,Patch-Set,,Flikaro,Set de parche,,Patch-asetus,Banque de Sons,,,パッチ セット,패치 세트,,Zestaw patchów,Banco de sons,,,Патч-набор,Печ сет +Gain,ADVSNDMNU_FLUIDGAIN,,,,Zesílení,Relative Lautstärke,,Akiro,Ganancia,,Vahvistus,,,,ゲイン,쌓기,Relatief volume,Wzmocnienie,Ganho,,,Усиление,Појачање +Reverb,ADVSNDMNU_REVERB,,,,Ozvěna,Hall,,Resono,Reverberación,,Kaiku,Réverbération,,,リバーブ,리버브,Nagalm,Pogłos,Reverberação,,,Реверберация,Одјек +Reverb Level,ADVSNDMNU_REVERB_LEVEL,,,,Intenzita ozvěny,Hallintensität,,Resono-nivelo,Nivel de Reverberación,,Kaiunvoimakkuus,Niveau Réverb.,,,リバーブ量,리버브 강도,Nagalm niveau,Poziom pogłosu,Nível de reverberação,,,Уровень реверберации,Ниво одјека +Chorus,ADVSNDMNU_CHORUS,,,,,,,Koruso,,,,,,,コーラス,코러스,,,,,,Хорус,Корус +Timidity++,ADVSNDMNU_TIMIDITY,,,,,,,,,,,,,,,,,,,,,, +Sound enabled,SNDMNU_SNDENABLED,,,,,Sound aktiv,,,,,,,,,,,,,,,,, +Music enabled,SNDMNU_MUSENABLED,,,,,Musik aktiv,,,,,,,,,,,,,,,,, +CD Music Emulation,SNDMNU_CDEMU,,,,,CD-Musik-Emulation,,,,,,,,,,,,,,,,, +Sound Ambience,SNDMNU_AMBIENCE,,,,,Umgebungsgeräusche,,,,,,,,,,,,,,,,, +"Player Speech +",SNDMNU_SPEECH,,,,,Spielerkommentare,,,,,,,,,,,,,,,,, +Flip Stereo Channels,ADVSNDMNU_FLIPSTEREO,,,,,Stereo Kanäle vertauschen,,,,,,,,,,,,,,,,, +,Video Mode,,,,,,,,,,,,,,,,,,,,,, +Scaled (Nearest),OPTVAL_SCALENEAREST,,,,Škálován (nejbližší),Skaliert (nächster Nachbar),,Skalita (Plej proksime),Escalado (Cercano),,Skaalattu (läheisin),Mis à l'échelle (Proche Voisin),,Scalato (più vicino),スケーリング (最寄り),확대 (가깝게),Geschaald (Dichtstbijzijnde),Przeskalowany (Najbliższy),Redimensionado (Vizinho mais próximo),Redimensionado (Apróximado),,Масштабировать (ближайшее),Скалиран (најближи) +Scaled (Linear),OPTVAL_SCALELINEAR,,,,Škálován (lineární),Skaliert(linear),,Skalita (Linia),Escalado (Lineal),,Skaalattu (lineaarinen),Mis à l'échelle (Linéaire),,Scalato (lineare),スケーリング (リニア),확대 (선형 식),Geschaald (Lineair),Przeskalowany (Liniowy),Redimensionado (Linear),,,Масштабировать (линейное),Скалиран (линеарно) +Letterbox,OPTVAL_LETTERBOX,,,,,,,Leterkesto,,,,,,Bande nere,レターボックス,레터박스,Brievenbus,,,,,Экранное каше,Поштанско сандуче +Stretch,OPTVAL_STRETCH,,,,Roztažený,Strecken,,Streĉi,Estrechado,Estrecho,Venytetty,Etirer,,Disteso,伸縮,늘림,Rek,Rozciągnięty,Esticado,,,Растянутый,Растегнуто +Render Mode,VIDMNU_RENDERMODE,,,,Režim renderování,Rendermodus,,Bildigo-reĝimo,Modo de Renderizado,,Hahmonnustila,Mode de Rendu,,Modalità motore grafico,レンダラー,렌더링 설정,Render Mode,Tryb Renderowania,Modo de Renderização,,,Режим рендеринга,Рендер мод +Fullscreen,VIDMNU_FULLSCREEN,,,,Přes celou obrazovku,Vollbild,,Plena ekrano,Pantalla completa,,Koko näyttö,Plein écran,,Schermata piena,全画面,전체화면,Volledig scherm,Pełen Ekran,Tela cheia,Ecrã cheio,,Полный экран,Цео екран +Retina/HiDPI support,VIDMNU_HIDPI,,,,Podpora Retiny/HiDPI,Retina/HDPI-Unterstützung,,Retino/HiDPI subteno,Soporte para Retina/HiDPI,,Retina/HiDPI-tuki,Support Retina/HiDPI ,Retina/HiDPI támogatás,Supporto Retina/HiDPi,Retina/HiDPI サポート,망막/하이DPI 활성화,Retina / HiDPI-ondersteuning,Wsparcie Retina/HiDPI,Suporte para Retina/HiDPI,,,Поддержка Retina/HiDPI,Retina/HiDPI подршка +Aspect ratio,VIDMNU_ASPECTRATIO,,,,Poměr stran,Seitenverhältnis,,Ekran-proporcio,Relación de aspecto,,Kuvasuhde,Rapport D'Aspect,Képarány,Proporzioni,アスペクト比,종횡비,Beeldverhouding,Wpółczynnik proporcji,Proporção de tela,Proporção de ecrã,,Соотношение сторон,Однос гледишта +Force aspect ratio,VIDMNU_FORCEASPECT,,,,Vynutit poměr stran,Erzwinge Seitenverhältnis,,Devigi ekran-proporcion,Forzar relación de aspecto,,Pakota kuvasuhde,Forcer Rapport,,Forza le proporzioni,アスペクト比に従う,강제 종횡비,Geforceerde beeldverhouding,Wymuś współczynnik proporcji,Forçar proporção de tela,Forçar proporcção de ecrã,,Принудительное соотношение сторон,Присили однос гледишта +Forced ratio style,VIDMNU_CROPASPECT,,,,Vynucený poměr stran,Modus für erzwungenes Seitenverhältnis,,Maniero por devigi proporcion,Relación de aspecto forzada,,Kuvasuhteen pakotustapa,Style de Ratio forcé,,Forza lo stile delle proporzioni,比率の形式,강제 비율 스타일,Gedwongen verhouding stijl,Wymuszony styl współczynnika,Forçar tipo de proporção,,,Тип принудительного соотношения сторон,Присиљен стил односа +Enable 5:4 aspect ratio,VIDMNU_5X4ASPECTRATIO,,,,Povolit poměr stran 5:4,Erlaube 5:4 Seitenverhältnis,,Aktivigi 5:4 ekran-proporcion,Activar relación de aspecto 5:4,,Ota käyttöön 5:4-kuvasuhde,Activer Rapport 5:4,5:4 képarány engedélyezése,Abilita le proporzioni 5:4,5:4アスペクト比を可能にする,5:4 비율 사용,Inschakelen 5:4 beeldverhouding,Włącz współczynnik proporcji 5:4,Habilitar proporção 5:4,,,Включить соотношение сторон 5:4,Омогући 5:4 однос гледишта +Resolution scale,VIDMNU_SCALEMODE,,,,Škálování rozlišení,Skalierung,,Distingivo-skalo,Escala de Resolución,,Resoluution skaalaus,Echelle de Résolution,,Scala di risoluzione,画面スケール,해상도 크기,Resolutie schaal,Skala rozdzielczości,Escala de resolução,,,Масштабирование,Резолуцијска скала +Scale Factor,VIDMNU_SCALEFACTOR,,,,Faktor rozlišení,Skalierungsfaktor,,Skalfaktoro,Factor de Escala,,Skaalauskerroin,Facteur d'échelle,,Fattore di scala,スケール倍率,축척 펙터,Schaalfactor,Współczynnik Skali,Fator de escala,,,Значение масштаба,Фактор скалирања +Use Linear Scaling (Fullscreen),VIDMNU_USELINEAR,,,,Použít lineární škálování (přes celou obrazovku),Lineare Skalierung (Vollbild),,Uzi Linian Skaladon (Plena ekrano),Usar Escalado Linear (Pant. Completa),,Lineaarinen skaalaus (koko näyttö),Mise à l'échelle Linéaire (Plein écran),,Usa lo scaling lineare (a schermo pieno),リニアスケールを使う(全画面),선형 스케일링 사용 (전체화면),Lineaire schaalverdeling gebruiken (volledig scherm),Użyj Liniowego Skalowania (Pełen Ekran),Usar escala linear (tela cheia),Usar escala linear (ecrã cheio),,Линейное масштабирование (полный экран),Користи линеарно скалирање (цео екран) +Custom Pixel Scaling,VIDMNU_CUSTOMRES,,,,Vlastní škálování pixelů,Benutzerdefinierte Skalierung,,Agorda bildero-skalo,Escalado de Pixel Personalizado,,Mukautettu skaalaus,Résolution Personalisée,,Scaling dei pixel personalizzato,カスタム ピクセルスケール,사용자 지정 픽셀 크기 조정,Aangepaste Pixel Schaalvergroting,Niestandardowe Skalowanie Pikseli,Escala de Pixel Personalizada,,,Масштабирование пикселов,Пиксел скалирање +Custom Width,VIDMNU_CUSTOMX,,,,Vlastní šířka,Benutzerdefinierte Breite,,Agorda larĝo,Ancho Personalizado,,Mukautettu leveys,Largeur Personalisée,Egyéni szélesség,Lunghezza,カスタム 幅,사용자 지정 너비,Aangepaste breedte,Niestandardowa Szerokość,Largura Personalizada,,,Длина,Ширина +Custom Height,VIDMNU_CUSTOMY,,,,Vlastní výška,Benutzerdefinierte Höhe,,Agorda alto,Alto Personalizado,,Mukautettu korkeus,Hauteur Personalisée,Egyéni magasság,Altezza,カスタム 高さ,사용자 지정 높이,Aangepaste hoogte,Niestandardowa Wysokość,Altura Personalizada,,,Высота,Висина +Apply Changes (Windowed),VIDMNU_APPLYW,,,,Použít změny (v okně),Änderungen anwenden (Fenster),,Apliki ŝanĝojn (Fenestrito),Aplicar Cambios (ventana),,Ota käyttöön muutokset (ikkuna),Appliquer Changements (Fenêtre),,Applica le modifiche (a finestra),変更を適用(ウィンドウ化),변경 적용 (윈도우),Wijzigingen toepassen (opgewonden),Zatwierdź Zmiany (Okno),Aplicar alterações (janela),,,Сохранить изменения (оконный режим),Примени промене (прозор) +Apply Changes (Fullscreen),VIDMNU_APPLYFS,,,,Použít změny (přes celou obrazovku),Änderungen anwenden (Vollbild),,Apliki ŝanĝojn (Plena ekrano),Aplicar Cambios (Pant. Completa),,Ota käyttöön muutokset (koko näyttö),Appliquer Changements (Plein écran),,Applica le modifiche (a schermo pieno),変更を適用(全画面化),변경 적용 (전체화면),Wijzigingen toepassen (Volledig scherm),Zatwierdź Zmiany (Pełen Ekran),Aplicar alterações (tela cheia),Aplicar alterações (ecrã cheio),,Сохранить изменения (полный экран),Примени промене (цели екран) +Choose Resolution Preset,VIDMNU_RESPRESET,,,,Vybrat přednastavené rozlišení,Auflösungsvoreinstellung,,Elekti Agordaĵon por Distingivo,Seleccionar Preset de Resolución,,Valitse ennalta määritetty resoluutio,Choisir paramètre personalisé,,Scegli preset di risoluzione,解像度プリセットを選ぶ,해상도 사전 설정 선택,Kies een vooraf ingestelde resolutie,Wybierz Zestaw Rozdzielczości,Escolher Resolução Predefinida,,,Выбор пресета разрешения,Резолуцијска подешавања +Custom Resolution Presets,VIDMNU_RESPRESETTTL,,,,Vlastní přednastavení rozlišení,Benutzerdefinierte Auflösungsvoreinstellungen,,Laŭmendaj agordaĵoj por Distingivo,Seleccionar Preset de Resoluciones,,Ennalta määritetyt mukautetut resoluutiot,Résolutions Personalisée,,Preset di risoluzione personalizzati,カスタム解像度プリセット,사용자 지정 해상도 미리 조정,Vooraf ingestelde aangepaste resolutie,Niestandardowe Zestawy Rozdzielczości,Predefinições Personalizadas,,,Пользовательские пресеты,Резолуцијска подешавања +Preset Resolution Modes,VIDMNU_RESPRESETHEAD,,,,Přednastavená rozlišení,Vordefinierte Auflösungsmodi,,Agordaĵaj Distingivreĝimoj,Modos de Preset de Resolución,,Ennalta määritetyt resoluutiotilat,Choisir mode de Résolution,,Modalità preset di risoluzione,解像度モードの調整,해상도 미리 조정 모드,Vooraf ingestelde resolutie modi,Tryby Zestawów Rozdzielczości,Modos de Resolução Predefinidas,,,Доступные разрешения,Постављени резолуцијски модови +4:3 Aspect,VIDMNU_ASPECT43,,,,Poměr stran 4:3,4:3 Seitenverhältnis,,4:3 Proporcio,Aspecto 4:3,,4:3-tilat,Rapport 4:3,,Aspetto 4:3,4:3アスペクト比,4:3 비율,,Proporcje 4:3,Proporção 4:3,,,Соотношение сторон 4:3,4:3 гледиште +5:4 Aspect,VIDMNU_ASPECT54,,,,Poměr stran 5:4,5:4 Seitenverhältnis,,5:4 Proporcio,Aspecto 5:4,,5:4-tilat,Rapport 5:4,,Aspetto 5:4,5:4アスペクト比,5:4 비율,,Proporcje 5:4,Proporção 5:4,,,Соотношение сторон 5:4,5:4 гледиште +16:9 Aspect,VIDMNU_ASPECT169,,,,Poměr stran 16:9,16:9 Seitenverhältnis,,16:9 Proporcio,Aspecto 16:9,,16:9-tilat,Rapport 16:9,,Aspetto 16:9,16:9アスペクト比,16:9 비율,,Proporcje 16:9,Proporção 16:9,,,Соотношение сторон 16:9,16:9 гледиште +16:10 Aspect,VIDMNU_ASPECT1610,,,,Poměr stran 16:10,16.10 Seitenverhältnis,,16:10 Proporcio,Aspecto 16:10,,16:10-tilat,Rapport 16:10,,Aspetto 16:10,16:10アスペクト比,16:10 비율,,Proporcje 16:10,Proporção 16:10,,,Соотношение сторон 16:10,16:10 гледиште +Max FPS,VIDMNU_MAXFPS,,,,,,,,,,,,,,,,,,,,,, +Unlimited,OPTVAL_UNLIMITED,,,,,Unlimitiert,,,,,,,,,,,,,,,,, +60 fps,OPTVAL_60FPS,,,,,,,,,,,,,,,,,,,,,, +75 fps,OPTVAL_75FPS,,,,,,,,,,,,,,,,,,,,,, +90 fps,OPTVAL_90FPS,,,,,,,,,,,,,,,,,,,,,, +120 fps,OPTVAL_120FPS,,,,,,,,,,,,,,,,,,,,,, +144 fps,OPTVAL_144FPS,,,,,,,,,,,,,,,,,,,,,, +200 fps,OPTVAL_200FPS,,,,,,,,,,,,,,,,,,,,,, +,Obituaries,,,,,,,,,,,,,,,,,,,,,, +"You are playing the shareware +version of Duke Nukem 3D. While +this version is really cool, you +are missing over 75% of the total +game, along with other great extras +which you'll get when you order +the complete version and get +the final three episodes.",BUYDUKE,,,,,,,,,,,,,,,,,,,,,, +"Are you sure you want to end the game? +",ENDGAME,,,,"Opravdu si přeješ ukončit hru? +","Willst du das Spiel wirklich beenden? +",,"Ĉu vi certas, ke vi volas fini la ludon? +","¿Estás segur@[ao_esp] que deseas cerrar el juego? +",,"Haluatko varmasti päättää pelin? +","Voulez vous mettre fin à votre partie? +","Biztos vagy benne hogy beakarod fejezni a játékot? +","Sei sicuro di voler terminare la partita? +","本当にゲームを中断するのか? +","게임을 정말로 종료하시겠습니까? +","Weet je zeker dat je het spel wilt beëindigen? +","Czy jesteś pewien że chcesz zakończyć grę? +","Tem certeza que deseja encerrar este jogo? +","Tem certeza que deseja fechar este jogo? +",,"Вы действительно хотите закончить игру? +","Јесте ли сигурни да желите завршити игру? +" +Are you sure you want to quit?,CONFIRM_QUITMSG,,,,Přeješ si odejít?,"Bist du dir sicher, dass du gehen willst?",,"Ĉu vi certas, ke vi volas ĉesi?",¿Estás segur@[ao_esp] que quieres salir?,,Haluatko varmasti lopettaa?,Êtes vous sûr de vouloir quitter ?,Biztos vagy benne hogy ki akarsz lépni?,Sei sicuro di voler abbandonare?,本当に終了するのか?,정말 종료하시겠습니까?,Weet je zeker dat je wilt stoppen?,Czy jesteś pewien że chcesz wyjść?,Tem certeza que quer sair?,Tens a certeza que queres sair?,,Вы действительно желаете выйти?,Да ли сте сигурни да желите да одустанеш? +Reset controls to defaults?,CONFIRM_CTRL1,,,,,Steuerung auf Standard zurücksetzen?,,,,,,,,,,,,,,,,, +Reset controls to classic defaults?,CONFIRM_CTRL2,,,,,Steuerung auf klassischen Standard zurücksetzen?,,,,,,,,,,,,,,,,, +Reset controls to left-handed defaults?,CONFIRM_CTRL3,,,,,Steuerung auf linkshändigen Standard zurücksetzen?,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 beat %s^02 like a cur,",TXT_OBITUARY1,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 broke %s,",TXT_OBITUARY2,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 body bagged %s,",TXT_OBITUARY3,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 boned %s^02 like a fish,",TXT_OBITUARY4,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 castrated %s,",TXT_OBITUARY5,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 creamed %s,",TXT_OBITUARY6,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 crushed %s,",TXT_OBITUARY7,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 destroyed %s,",TXT_OBITUARY8,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 diced %s,",TXT_OBITUARY9,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 disemboweled %s,",TXT_OBITUARY10,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 erased %s,",TXT_OBITUARY11,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 eviscerated %s,",TXT_OBITUARY12,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 flailed %s,",TXT_OBITUARY13,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 flattened %s,",TXT_OBITUARY14,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 gave AnAl MaDnEsS to %s,",TXT_OBITUARY15,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 gave %s^02 Anal Justice,",TXT_OBITUARY16,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 hosed %s,",TXT_OBITUARY17,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 hurt %s^02 real bad,",TXT_OBITUARY18,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 killed %s,",TXT_OBITUARY19,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 made dog meat out of %s,",TXT_OBITUARY20,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 made mincemeat out of %s,",TXT_OBITUARY21,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 manhandled %s,",TXT_OBITUARY22,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 massacred %s,",TXT_OBITUARY23,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 mutilated %s,",TXT_OBITUARY24,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 murdered %s,",TXT_OBITUARY25,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 neutered %s,",TXT_OBITUARY26,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 punted %s,",TXT_OBITUARY27,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 reamed %s,",TXT_OBITUARY28,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 ripped %s^02 a new orifice,",TXT_OBITUARY29,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 rocked %s,",TXT_OBITUARY30,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 sent %s^02 to hell,",TXT_OBITUARY31,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 shredded %s,",TXT_OBITUARY32,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 slashed %s,",TXT_OBITUARY33,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 slaughtered %s,",TXT_OBITUARY34,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 sliced %s,",TXT_OBITUARY35,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 smacked %s around,",TXT_OBITUARY36,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 smashed %s,",TXT_OBITUARY37,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 snuffed %s,",TXT_OBITUARY38,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 sodomized %s,",TXT_OBITUARY39,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 splattered %s,",TXT_OBITUARY40,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 sprayed %s,",TXT_OBITUARY41,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 squashed %s,",TXT_OBITUARY42,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 throttled %s,",TXT_OBITUARY43,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 toasted %s,",TXT_OBITUARY44,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 vented %s,",TXT_OBITUARY45,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 ventilated %s,",TXT_OBITUARY46,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 wasted %s,",TXT_OBITUARY47,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 wrecked %s,",TXT_OBITUARY48,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 is excrement,",TXT_SELFOBIT1,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 is hamburger,",TXT_SELFOBIT2,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 suffered scrotum separation,",TXT_SELFOBIT3,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 volunteered for population control,",TXT_SELFOBIT4,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 has suicided,",TXT_SELFOBIT5,,,,,,,,,,,,,,,,,,,,,, -"^02%s^02 bled out,",TXT_SELFOBIT6,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file +%k boned %o like a fish,TXT_OBITUARY1,,,,%o byl@[ao_cs] vykoštěn@[ao_cs] jako ryba hráčem %k,%k hat %o zerlegt wie einen Fisch,,%k senostigis %o kiel fiŝon,%k deshuesó a %o como a un pescado,,%k perkasi %o paran kuin kalan,%k désossa %o comme un poisson,%k kifilézte %o -t mint a halat,%k ha dissossato %o come un pesce,%k は %o の骨を魚のように引っこ抜いた。,%k 은(는) %o 의 뼈를 발랐다.,%k uitgebeend %o zoals een vis,%k odfiletował@[ao_pl] %o jak rybę,%k desossou %o como um peixe,,,Игрок %k пересчитал косточки игрока %o,%k је очистио %o као рибу +%k castrated %o,TXT_OBITUARY2,,,,%o byl@[ao_cs] vykastrován@[ao_cs] hráčem %k,%k hat %o kastriert,,%k kastris %o,%k castró a %o,,%k kastroi %o paran,%k castra %o,%k kasztrálta %o -t,%k ha castrato %o,%k は %o を去勢した。,%k 은(는) %o 을(를) 거세시켰다.,%k gecastreerd %o,%k wykastrował@[ao_pl] %o,%k castrou %o,,,Игрок %k кастрировал игрока %o,%k је кастрирао %o +%k creamed %o,TXT_OBITUARY3,,,,%o byl@[ao_cs] rozšlehán@[ao_cs] hráčem %k,%k hat %o eingeseift,,%k kremigis %o,%k cremó a %o,,%k kermasi %o paran,%k a battu %o à plate couture ,%k elkente %o -t,%k ha cremato %o,%k は %o に反吐ブチ撒けさせた。,%k 은(는) %o 을(를) 양념시켰다.,%k romed %o,%k spienił@[ao_pl] %o,%k fez creme de %o,,,Игрок %k взбил игрока %o,%k је истукао %o +%k decimated %o,TXT_OBITUARY4,,,,%o byl@[ao_cs] zdecimován@[ao_cs] hráčem %k,%k hat %o dezimiert,,%k detruegis %o,%k diezmó a %o,,%k hävitti %o paran,%k a décimé %o,%k megtizedelte %o -t,%k ha decimato %o,%k は %o の居場所を間引いた。,%k 은(는) %o 을(를) 망가뜨렸다.,%k gedecimeerd %o,%k przetrzebił@[ao_pl] %o,%k decimou %o,,,Игрок %k скосил игрока %o,%k је десетковао %o +%k destroyed %o,TXT_OBITUARY5,,,,%o byl@[ao_cs] zničen@[ao_cs] hráčem %k,%k hat %o zerstört,,%k detruis %o,%k destruyó a %o,,%k tuhosi %o paran,%k a détruit %o,%k elpusztította %o -t,%k ha distrutto %o,%k は %o を完全に破壊した。,%k 은(는) %o 을(를) 파괴했다.,%k vernietigd %o,%k zniszczył@[ao_pl] %o,%k destruiu %o,,,Игрок %k уничтожил игрока %o,%k је уништио %o +%k diced %o,TXT_OBITUARY6,,,,%o byl@[ao_cs] nakrájen@[ao_cs] na kostičky hráčem %k,%k hat %o in Würfel zerteilt,,%k diskubigis %o,%k picó en cubitos a %o,,%k pilkkosi %o paran,%k a coupé en dés %o,%k felkockázta %o -t,%k ha tagliato a cubetti %o,%k は %o を賽の目に切った。,%k 은(는) %o 을(를) 잘게 잘게 썰었다.,%k in blokjes gesneden %o,%k pokroił@[ao_pl] w kostkę %o,%k fez picadinho de %o,%k cortou %o,,Игрок %k разрезал игрока %o,%k је исецкао %o +%k disembowled %o,TXT_OBITUARY7,,,,%o byl@[ao_cs] vykuchán@[ao_cs] hráčem %k,%k hat %o ausgeweidet,,%k sentripigis %o,%k destripó a %o,,%k suolisti %o paran,%k a étripé %o,%k kibelezve,%k ha smembrato %o,%k は %o の臓物を引きずり出した。,%k 은(는) %o 의 내장을 도려냈다.,%k van de ingewanden gehaald %o,%k wypatroszył@[ao_pl] %o,%k estripou %o,,,Игрок %k выпотрошил игрока %o,%k је ампутирао %o +%k flattened %o,TXT_OBITUARY8,,,,%o byl@[ao_cs] zplacatěn@[ao_cs] hráčem %k,%k hat %o dem Erdboden gleichgemacht,,%k platigis %o,%k aplanó a %o,,%k lyttäsi %o paran,%k a aplati %o,%k kilapítva,%k ha schiacciato %o,%k は %o をぶっ潰した。,%k 은(는) %o 의 코를 납작하게 만들었다.,afgevlakt %k afgevlakt %o,%k rozpłaszczył@[ao_pl] %o,%k achatou %o,%k espalmou %o,,Игрок %k сплюснул игрока %o,%k је изравнао %o +%k gave %o Anal Justice,TXT_OBITUARY9,,,,%o utržil@[ao_cs] anální spravedlnost od hráče %k,%k hat %o anale Gerechtigkeit gegeben,,%k donis %o puga ĵustico,%k le dió Justicia Anal a %o,,%k jakoi %o paralle anaalioikeutta,%k a rendu une justice anale a %o,%k %o -nak Anális Igazságot adott,%k ha dato a %o Giustizia Anale,%k は %o のケツにぶち込んだ。,%k 은(는) %o 에게 홍콩행을 보냈다.,%k gaf %o Anaalrechtvaardigheid,%k dał@[ao_pl] %o Analną Sprawiedliwość,%k deu Justiça Anal para %o,,,Игрок %k устроил Анальное Правосудие игроку %o,%k је дао %o аналну правду +%k gave AnAl MaDnEsS to %o,TXT_OBITUARY10,,,,%o utrpěl@[ao_cs] AnÁlNí ŠíLeNsTvÍ od hráče %,%k gab %o AnAlEn WaHnSiNn,,%k donis pUgAn frEnEzOn al %o,%k le dió LoCuRa AnAl a %o,,%k teki %o paran AnAaLiHuLlUkSi,%k a donné la FOLIE ANALE a %o,%k %o -nak Seggbe Durrantott,%k ha dato FoLlIa AnAle a %o,%k は %o のケツをガバガバにした。,%o 은(는) %k 의 찰진 맛을 보았다.,%k gaf AnAl MaDnEs aan %o,%k dał@[ao_pl] %o AnAlNe SzAlEńStWo ,%k deu LoUcUrA aNaL para %o,,,Игрок %k устроил АнАЛ КаРнаВаЛ игроку %o,%k је дао АнАлНо ЛуДиЛо %o +%k killed %o,TXT_OBITUARY11,,,,%o byl@[ao_cs] zabit@[ao_cs] hráčem %k,%k hat %o getötet,,%k mortigis %o,%k mató a %o,,%k tappoi %o paran,%k a tué %o,%k kicsinálta %o -t,%k ha ucciso %o,%k は %o をブッ殺した。,%k 은(는) %o 을(를) 죽였다.,%k gedood %o,%k zabił@[ao_pl] %o,%k matou %o,,,Игрок %k убил игрока %o,%k је убио %o +%k made mincemeat out of %o,TXT_OBITUARY12,,,,%o byl@[ao_cs] namelen@[ao_cs] hráčem %k,%k hat %o zu Hackfleisch verarbeitet,,%k faris mincemeat el %o,%k hizo picadillo de %o,,%k teki jauhelihaa %o parasta,%k a fait de la viande hachée de %o,%k darálthúst csinált %o -ból,%k ha triturato %o,%k は %o をミンチにした。,%o 은(는) %k 에 의해 분쇄됐다.,%k gemaakt gehakt vlees van %o,%k zrobił@[ao_pl] mięso mielone z %o,%k fez carne moída de %o,%k fez carne picada do %o,,Игрок %k сделал отбивную из игрока %o,%k је направио млевено месо од %o +%k massacred %o,TXT_OBITUARY13,,,,%o byl@[ao_cs] zmasakrován@[ao_cs] hráčem %k,%k hat %o niedergemetzelt,,%k masakris %o,%k masacró a %o,,%k verilöylytti %o parkaa,%k a massacré %o,%k lemészárolta %o -t,%k ha fatto di %o carne tritata,%k は %o を虐殺した。,%k 은(는) %o 을(를) 참살했다.,%k afgeslacht %o,%k zmasakrował@[ao_pl] %o,%k massacrou %o,,,Игрок %k устроил бойню игроку %o,%k је масакрирао %o +%k mutilated %o,TXT_OBITUARY14,,,,%o byl@[ao_cs] zmrzačen@[ao_cs] hráčem %k,%k hat %o verstümmelt,,%k mutilis %o,%k mutiló a %o,,%k silpoi %o paran,%k a mutilé %o,%k megcsonkította %o -t,%k ha massacrato %o,%k は %o をバラバラ死体にした。,%k 은(는) %o 의 팔다리를 절단했다.,%k verminkt %o,%k rozszarpał@[ao_pl] %o,%k mutilou %o,,,Игрок %k изуродовал игрока %o,%k је мутилирао %o +%k reamed %o,TXT_OBITUARY15,,,,%o byl@[ao_cs] proděravěn@[ao_cs] hráčem %k,%k hat %o aufgerieben,,%k reeldonis %o,%k escarió a %o,,%k porasi %o paran,%k a découpé en fines lamelles %o,%k seggbe rakta %o -t,%k ha squartato %o,%k は %o の穴を大きく広げた。,%k 은(는) %o 을(를) 크게 혼냈다.,%k geruimd %o,%k rozwiercił@[ao_pl] %o,%k esquartejou %o,,,Игрок %k просверлил игрока %o,%k је наоружао %o +%k ripped %o a new orifice,TXT_OBITUARY16,,,,%o má novou díru od hráče %k,%k hat %o eine neue Körperöffnung verpasst,,%k ŝiris %o novan orificion,%k le hizo a %o un nuevo orificio,,%k repi %o paralle uuden aukon,%k a ouvert un nouvel orifice a %o,,%k ha aperto a %o un altro orifizio,%k は %o を切り裂いて新しい穴を作ってあげた。,%k 은(는) %o 을(를) 죽여 뜯어서 작품을 만들었다.,%k gescheurd %o een nieuwe doorlaatopening,%k rozerwał@[ao_pl] %o nowy otwór,%k abriu um novo orifício em %o,,,Игрок %k проделал новое отверстие в игроке %o,%k је исцепао %o нови отвор +%k slaughtered %o,TXT_OBITUARY17,,,,%o byl@[ao_cs] zavražděn@[ao_cs] hráčem %k,%k hat %o geschlachtet,,%k buĉis %o,%k sacrificó a %o,,%k teurasti %o paran,%k a meurtri %o,%k lemészárolta %o -t,%k ha macellato %o,%k は %o を屠殺した。,%o 은(는) %k 에 의해 도살당했다.,%k geslacht %o,%k zarżn@[irreg_2_pl] %o,%k abateu %o,,,Игрок %k устроил резню игроку %o,%k је заклао %o +%k smashed %o,TXT_OBITUARY18,,,,%o byl@[ao_cs] zmlácen@[ao_cs] hráčem %k,%k hat %o zerklatscht,,%k frakasis %o,%k destrozó a %o,,%k murskasi %o paran,%k a enfoncé %o,%k földbe döngölte %o -t,%k ha distrutto %o,%k は %o をぶっ飛ばした。,%k 은(는) %o 을(를) 내팽개쳤다.,%k gebroken %o,%k stłukł@[ao_pl] %o,%k esmagou %o,,,Игрок %k размазал игрока %o,%k је поломио %o +%k sodomized %o,TXT_OBITUARY19,,,,Hráč %k se dopustil sodomie na hráči %o,%k hat %o sodomisiert,,%k sodomizata %o,%k sodomizó a %o,,%k anaaliraiskasi %o paran,%k y a sodomisé n %o,%k szodomizálta %o -t,%k ha sodomizzato %o,%o は %k にカマを掘られた。 ,%o 은(는) %k 을(를) 위해 등을 보였다.,%k gesodomiseerd %o,%k spenetrował@[ao_pl] %o,%k sodomizou %o,,,Игрок %k содомировал игрока %o,%k је изјебао %o +%k splattered %o,TXT_OBITUARY20,,,,%o byl@[ao_cs] rozplesknut@[ao_cs] hráčem %k,%k hat %o zerspritzt,,%k disĵetis %o,%k roció a %o,,%k roiski %o paran yltympäri,%k a explosé de %o,%k szétloccsantotta %o -t,%k ha spiaccicato %o,%k は %o にばら撒かれた。,%k 은(는) %o 을(를) 박살냈다.,%k gespat %k gespetterd %o,%k rozbryzgał@[ao_pl] %o,%k explodiu %o,,,Игрок %k разбрызгал игрока %o,%k је спљоштио %o +%k squashed %o,TXT_OBITUARY21,,,,%o byl@[ao_cs] rozmáčknut@[ao_cs] hráčem %k,%k hat %o zerquetscht,,%k premplatigis %o,%k aplastó a %o,,%k litisti %o paran,%k a écrabouillé %o,%k szétnyomta %o -t mint a csótányt,%k ha schiacciato %o,%k は %o に潰された。,%k 은(는) %o 을(를) 짓이겼다.,%k geplet %k geplet %o,%k zmiażdżył@[ao_pl] %o,%k espatifou %o,,,Игрок %k расплющил игрока %o,%k је згњечио %o +%k throttled %o,TXT_OBITUARY22,,,,%o byl@[ao_cs] zaškrcen@[ao_cs] hráčem %k,%k hat %o erdrosselt,,%k ekbruligis %o,%k aceleró a %o,,%k polki %o paran,%k a étouffé %o,,%k ha strozzato %o,%k は %o に絞られた。,%k 은(는) %o 을(를) 목 졸라 죽였다.,%k gewurgt %o,"%k udusił@[ao_pl] %o +",%k estrangulou %o,,,Игрок %k задушил игрока %o,%k је угушио %o +%k wasted %o,TXT_OBITUARY23,,,,%o byl@[ao_cs] zničen@[ao_cs] hráčem %k,%k hat %o verbraucht,,%k malŝparis %o,%k desechó a %o,,%k kulutti %o paran,%k a décharné %o,,%k ha distrutto %o,%k は %o に消された。,%k 은(는) %o 을(를) 쓰레기처럼 내다 버렸다.,%k verspild %o,%k roztrwonił@[ao_pl] %o,%k detonou %o,,,Игрок %k замочил игрока %o,%k је убио %o +%k body bagged %o,TXT_OBITUARY24,,,,Hráč %k narval %o@[psn1_cs] tělo do pytle,%k hat %o eingesackt,,%k korpo malplenigis %o,%k embolsó a %o,,%k kääri %o paran ruumispussiin,%k a placé %o dans son linceul,,%k ha mandato %o all'obitorio,%k は %o を死体袋にした。,%k 은(는) %o 의 장례식을 치렀다.,%k lichaam met zakje %o,%k spakował@[ao_pl] %o do torby na zwłoki,%k mandou %o para o necrotério,,,Игрок %k упаковал игрока %o в мешок для трупов,%k је умртвио %o +%k sent %o to Hell,TXT_OBITUARY25,,,,%o byl@[ao_cs] poslán@[ao_cs] do pekla hráčem %k,%k hat %o zur Hölle fahren lassen,,%k sendis %o al Infero,%k envió a %o al infierno,,%k lähetti %o paran helvettiin,%k a envoyé %o en enfer,,%k ha spedito %o all'Inferno,%k は %o を地獄に送った。,%o 은(는) %k 덕에 지옥으로 돌아갔다.,%k verzonden %o naar de hel,%k wysłał@[ao_pl] %o do Piekła,%k mandou %o para o Inferno,,,Игрок %k отправил в Ад игрока %o,%k је послао %o до Врага +%k toasted %o,TXT_OBITUARY26,,,,%o byl@[ao_cs] upečen@[ao_cs] hráčem %k,%k hat %o geröstet,,%k tostita %o,%k tostó a %o,,%k käristi %o paran,%k a grillé %o,%k megpirította %o -t,%k ha arrostito %o,%k は %o を焼却した。,%o 은(는) %k 덕에 맛있게 구워졌다.,%k geroosterd %o,%k stostował@[ao_pl] %o,%k tostou %o,,,Игрок %k поджарил игрока %o,%k је тостирао %o +%k snuffed %o,TXT_OBITUARY27,,,,%o byl@[ao_cs] rozsápán@[ao_cs] hráčem %k,%k hat %o vernichtet,,%k snufis %o,%k aspiró a %o,,%k sammutti %o paran,%k a crevé %o,,%k ha spento %o,%k は %o を処刑した。,%o 은(는) %k 에 의해 짓눌려졌다.,%k gesnuffeld %o,%k powąchał@[ao_pl] %o,%k apagou %o,,,Игрок %k прикончил игрока %o,%k је угасио %o +%k hosed %o,TXT_OBITUARY28,,,,%o byl@[ao_cs] odstříknut@[ao_cs] hráčem %k,%k hat %o eingetütet,,%k bagigis %o,%k se cargó a %o,,%k pesi %o paran,%k a arrosé %o,,%k l'ha fatta sopra %o,%k は %o にぶっかけた。,%k 은(는) %o 을(를) 패배로 씻겼다.,%k slang %o,%k załatwił@[ao_pl] %o,%k metralhou %o,,,Игрок %k расстрелял игрока %o,%k је упскао %o +%k sprayed %o,TXT_OBITUARY29,,,,%o byl@[ao_cs] postříkán@[ao_cs] hráčem %k,%k hat %o pulverisiert,,%k ŝprucigis %o,%k pulverizó a %o,,%k ruiskutti %o paran,%k a pulvérise %o,,%k ha vaporizzato %o,%k は %o を撒き散らした。,%o 의 피는 %k 의 물감으로 쓰였다.,%k gespoten %o,%k rozpryskał@[ao_pl] %o,%k pulverizou %o,,,Игрок %k распылил игрока %o,%k је испрскао %o +%k made dog meat out of %o,TXT_OBITUARY30,,,,%o byl@[ao_cs] hozen@[ao_cs] psům hráčem %k,%k hat Hundefutter aus %o gemacht,,%k faris hundan viandon el %o,%k hizo comida para perro de %o,,%k teki %o parasta koiranruokaa,%k a fait de la pâtée pour chien de %o,,%k ha fatto di %o polpette,%k は %o を犬の餌にした。,%k 은(는) %o 로 개밥을 만들었다.,%k gemaakt hondenvlees van %o,%k zrobił@[ao_pl] mięso dla psów z %o,%k fez almôndegas de %o,,,Игрок %k скормил псам игрока %o,%k је направио псеће месо од %o +%k beat %o like a cur,TXT_OBITUARY31,,,,%o byl@[ao_cs] zmlácen@[ao_cs] jako pes hráčem %k,%k hat %o wie einen Hund geschlagen,,%k batis %o kiel kur,%k pateó a %o como a un perro callejero,,%k huitoi %o parkaa kuin rakkia,%k a battu %o,,%k ha battuto %o come un cane,%k は %o を狂犬の様に扱った。,%o 은(는) %k 에게 똥개처럼 맞았다.,%k beat %o als een hond,%k pobił@[ao_pl] %o jak kundla,%k espancou %o como um cachorro,%k espancou %o como um cão,,Игрок %k сделал игрока %o как худую свинью,%k је превио %o ко мачку +%k body bagged %o,TXT_OBITUARY32,,,,,,,,,,,,,,,,,,,,,, +%k crushed %o,TXT_OBITUARY33,,,,,,,,,,,,,,,,,,,,,, +%k erased %o,TXT_OBITUARY34,,,,,,,,,,,,,,,,,,,,,, +%k eviscerated %o,TXT_OBITUARY35,,,,,,,,,,,,,,,,,,,,,, +%k flailed %o,TXT_OBITUARY36,,,,,,,,,,,,,,,,,,,,,, +%k hurt %o real bad,TXT_OBITUARY37,,,,,,,,,,,,,,,,,,,,,, +%k manhandled %o,TXT_OBITUARY38,,,,,,,,,,,,,,,,,,,,,, +%k murdered %o,TXT_OBITUARY39,,,,,,,,,,,,,,,,,,,,,, +%k neutered %o,TXT_OBITUARY40,,,,,,,,,,,,,,,,,,,,,, +%k punted %o,TXT_OBITUARY41,,,,,,,,,,,,,,,,,,,,,, +%k shredded %o,TXT_OBITUARY42,,,,,,,,,,,,,,,,,,,,,, +%k slashed %o,TXT_OBITUARY43,,,,,,,,,,,,,,,,,,,,,, +%k sliced %o,TXT_OBITUARY44,,,,,,,,,,,,,,,,,,,,,, +%k smacked %o around,TXT_OBITUARY45,,,,,,,,,,,,,,,,,,,,,, +%k vented %o,TXT_OBITUARY46,,,,,,,,,,,,,,,,,,,,,, +%k ventilated %o,TXT_OBITUARY47,,,,,,,,,,,,,,,,,,,,,, +%k wrecked %o,TXT_OBITUARY48,,,,,,,,,,,,,,,,,,,,,, +%o is excrement,TXT_SELFOBIT1,,,,%o je exkrement,%o wurde zu Exkrement verarbeitet,,%o estas ekskremento,%o es excremento,,%o on ulostetta,%o est une merde,,%o è un escremento,%o はもはや排泄物のようだ。,%o 은(는) 배설물이 되었다.,%o is uitwerpselen,%o został@[ao_pl] odpadkami,%o virou escremento,,,%o теперь экскремент,%o је сада измет +%o is hamburger,TXT_SELFOBIT2,,,,%o je hamburger,%o ist Hamburger,,%o estas hamburgero,%o es una hamburguesa,,%o on hakkelusta,%o est un hamburger,,%o è un hamburger,%o はハンバーガーになった。,%o 은(는) 고기 반죽이 되었다.,%o is hamburger,%o został@[ao_pl] hamburgerem,%o virou hamburguer,,,%o теперь гамбургер,%o је сада пљескавица +%o suffered scrotum separation,TXT_SELFOBIT3,,,,%o prodělal@[ao_cs] separaci šourku,%os Eier wurden gebraten,,%o suferis skrotan disigon,%o sufrió separación de escroto,,%o kärsii kivespussin erotuksesta,%o a souffert d'une séparation du scrotum,,%o ha subito la separazione dello scroto,%o の陰嚢は剥離していた。,%o 은(는) 고자가 되었다.,%o leed aan scrotumscheiding...,%o doznał@[ao_pl] oddzielenia moszny,%o sofreu separação escrotal,,,%o страдает от потери тестикул,%o му је исечена патка +%o volunteered for population control,TXT_SELFOBIT4,,,,%o se zůčastnil@[ao_cs] čistky obyvatelstva,%o hat sich freiwillig zur Bevölkerungskontrolle gemeldet,,%o volontulis por loĝantarkontrolo,%o fue voluntario para control de población,,%o ilmoittautui vapaaehtoiseksi väestönhallintaan,%o s'est proposé pour un contrôle de la population,,%o si è offerto per il controllo della popolazione,%o は人口削減政策の実験台に志願した。,%o 은(는) 자연에 의해 낙태 당했다.,%o vrijwilliger voor bevolkingscontrole,%o zgłosił@[ao_pl] się na kontrolę ludności,%o se voluntariou para o controle populacional,%o se voluntariou para o controlo populacional,,%o борется с перенаселением,%o је волунтирао за контролу популације +%o has suicided,TXT_SELFOBIT5,,,,%o spáchal@[ao_cs] sebevraždu,%o hat Selbstmord begangen,,%o sin mortigis,%o se ha suicidado,,%o on tehnyt itsemurhan,%o s'est suicidé,%o öngyilkos lett,%o si è suicidato,%o は勝手にくたばった。,%o 은(는) 한심하게 자살했다.,%o heeft zelfmoord gepleegd.,%o popełnił@[ao_pl] samobójstwo,%o se suicidou,%o suicidou-se,,Игрок %o самоубился,%o је убио самог себе +%o received the Darwin Award,TXT_SELFOBIT6,,,,%o dostal@[ao_cs] darwinovu cenu,%o hat den Darwinpreis erhalten,,%o ricevis la Darwin-Premion,%o recibió el premio Darwin,,%o sai Darwin-palkinnon,%o a recu la médaille Darwin,És a Darwin Díj nyertese : %o,%o ha ricevuto il Darwin Award,%o にはダーウィン賞が授与された。,%o 은(는) 다윈상을 받을 자격이 있다.,%o ontving de Darwin Award....,%o otrzymał@[ao_pl] Nagrodę Darwina,%o ganhou o Prêmio Darwin,,,Игрок %o получил премию Дарвина,%o је добио Дарвиново признање \ No newline at end of file diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 59786e00e..b6d2e5ff0 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -1181,7 +1181,7 @@ OptionValue SampleRates //8000, "$OPTVAL_8000HZ" 11025, "$OPTVAL_11025HZ" 22050, "$OPTVAL_22050HZ" - /32000, "$OPTVAL_32000HZ" + 32000, "$OPTVAL_32000HZ" 44100, "$OPTVAL_44100HZ" 48000, "$OPTVAL_48000HZ" } @@ -1239,12 +1239,13 @@ OptionValue MidiDevices OptionMenu SoundOptions //protected { Title "$SNDMNU_TITLE" - //Slider "$MODMNU_MASTERVOLUME", "snd_mastervolume", 0, 1, 0.05, 2 - //StaticText " " - Option "$SNDMNU_SNDENABLED", "snd_enabled", "OnOff" + Slider "$MODMNU_MASTERVOLUME", "snd_mastervolume", 0, 1, 0.05, 2 + StaticText " " + Option "$SNDMNU_SNDENABLED", "snd_enabled", "YesNo" Slider "$SNDMNU_SFXVOLUME", "snd_fxvolume", 0, 255, 2, 1 - //Slider "$SNDMNU_SFXVOLUME", "snd_fxvolume", 0, 1, 0.05, 2 // Todo: Change value type - Option "$SNDMNU_MUSENABLED", "mus_enabled", "OnOff" Slider "$SNDMNU_MUSICVOLUME", "mus_volume", 0, 1, 0.05, 2 + //Slider "$SNDMNU_SFXVOLUME", "snd_sfxvolume", 0, 1, 0.05, 2 // Todo: Change value type + Option "$SNDMNU_MUSENABLED", "mus_enabled", "YesNo" + Slider "$SNDMNU_MUSICVOLUME", "mus_volume", 0, 1, 0.05, 2 Option "$SNDMNU_MENUSOUND", "menu_sounds", "OnOff" // placeholder until the slider can be made to work //Slider "$SNDMNU_MENUVOLUME", "snd_menuvolume", 0, 1, 0.05, 2 StaticText " " @@ -1287,10 +1288,10 @@ OptionMenu AdvSoundOptions //protected Title "$ADVSNDMNU_TITLE" Option "$ADVSNDMNU_SAMPLERATE", "snd_mixrate", "SampleRates" //Option "$ADVSNDMNU_HRTF", "snd_hrtf", "AutoOffOn" - Option "$ADVSNDMNU_FLIPSTEREO" "snd_reversestereo", "OnOff" - StaticText " " - Option "$SNDMNU_BACKGROUND", "i_soundinbackground", "OnOff" + Option "$ADVSNDMNU_FLIPSTEREO", "snd_reversestereo", "OnOff" StaticText " " + //Option "$SNDMNU_BACKGROUND", "i_soundinbackground", "OnOff" + //StaticText " " ifoption(openal) { @@ -1302,16 +1303,16 @@ OptionMenu AdvSoundOptions //protected Submenu "$SNDMNU_MIDIPLAYER", "MidiPlayerOptions" Submenu "$SNDMNU_MODREPLAYER", "ModReplayerOptions" StaticText " " - Command "$SNDMNU_RESTART", "snd_reset" + Command "$SNDMNU_RESTART", "restartsound" } -OptionMenu TimidityConfigMenu protected +OptionMenu TimidityConfigMenu //protected { Title "$ADVSNDMNU_SELCONFIG" } -OptionMenu FluidPatchsetMenu protected +OptionMenu FluidPatchsetMenu //protected { Title "$ADVSNDMNU_SELCONFIG" } @@ -1376,9 +1377,9 @@ OptionMenu ModReplayerOptions //protected OptionMenu MidiPlayerOptions //protected { Title "$SNDMNU_MIDIPLAYER" - Submenu "$ADVSNDMNU_FLUIDSYNTH", "FluidsynthOptions", 0, 1 - Submenu "$ADVSNDMNU_TIMIDITY", "TimidityOptions", 0, 1 - Submenu "$ADVSNDMNU_OPLSYNTHESIS", "OPLOptions", 0, 1 + Submenu "$ADVSNDMNU_FLUIDSYNTH", "FluidsynthOptions"//, 0, 1 + Submenu "$ADVSNDMNU_TIMIDITY", "TimidityOptions"//, 0, 1 + Submenu "$ADVSNDMNU_OPLSYNTHESIS", "OPLOptions"//, 0, 1 } OptionMenu FluidsynthOptions //protected From 98d3cb19c976de2cc233f81e0596af31d8293c3d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 5 Dec 2019 19:17:44 +0100 Subject: [PATCH 122/203] - added the miscellaneous options menu. This should be the last one, except for the message confirmation screen. Not all options are implementation backed yet, there's still work to do --- wadsrc/static/demolition/language.csv | 38 ++++++++++++++++++++++++-- wadsrc/static/demolition/menudef.txt | 39 +++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index d559776cf..6dcef59f8 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -628,7 +628,13 @@ Sound Ambience,SNDMNU_AMBIENCE,,,,,Umgebungsgeräusche,,,,,,,,,,,,,,,,, "Player Speech ",SNDMNU_SPEECH,,,,,Spielerkommentare,,,,,,,,,,,,,,,,, Flip Stereo Channels,ADVSNDMNU_FLIPSTEREO,,,,,Stereo Kanäle vertauschen,,,,,,,,,,,,,,,,, +MAME OPL2,OPTVAL_MAMEOPL2,,,,,,,,,,,,,,,마메 OPL2,,,,,,, +DOSBox OPL3,OPTVAL_DOSBOXOPL3,,,,,,,,,,,,,,,도스박스 OPL3,,,,,,, +Java OPL3,OPTVAL_JAVAOPL3,,,,,,,,,,,,,,,자바 OPL3,,,,,,, +Nuked OPL3,OPTVAL_NUKEDOPL3,,,,,,,,,,,,,,,,,,,,,, ,Video Mode,,,,,,,,,,,,,,,,,,,,,, +Video Mode,VIDMNU_TITLE,,,,Režim displeje,Videomodus,,Video-reĝimo,Modos de video,,Videotila,Mode Vidéo,,Modalità video,ビデオ 調整,화면 설정,Videomodus,Tryb Wideo,Modo de Vídeo,,,Настройки видеорежима,Видео мод +Notebook Switchable GPU,DSPLYMNU_GPUSWITCH,,,,Přepínatelné GPU pro notebooky,GPU Umschaltung für Notebooks,,Kajero Ŝanĝa GPU,GPU Altern. de Portátil,,Kannettavan kytkettävä grafiikkapiiri,GPU alternatif sur PC Portable,Váltható GPU laptopon,Scheda GPU Switchable per notebook,ノートブックGPU切替,노트북 성능 조정,Notitieboekje schakelbare GPU,Zmiana GPU Notebooka,Placa de vídeo alternativa de notebook,,,Использование GPU ноутбука,Користи GPU ноутбук Scaled (Nearest),OPTVAL_SCALENEAREST,,,,Škálován (nejbližší),Skaliert (nächster Nachbar),,Skalita (Plej proksime),Escalado (Cercano),,Skaalattu (läheisin),Mis à l'échelle (Proche Voisin),,Scalato (più vicino),スケーリング (最寄り),확대 (가깝게),Geschaald (Dichtstbijzijnde),Przeskalowany (Najbliższy),Redimensionado (Vizinho mais próximo),Redimensionado (Apróximado),,Масштабировать (ближайшее),Скалиран (најближи) Scaled (Linear),OPTVAL_SCALELINEAR,,,,Škálován (lineární),Skaliert(linear),,Skalita (Linia),Escalado (Lineal),,Skaalattu (lineaarinen),Mis à l'échelle (Linéaire),,Scalato (lineare),スケーリング (リニア),확대 (선형 식),Geschaald (Lineair),Przeskalowany (Liniowy),Redimensionado (Linear),,,Масштабировать (линейное),Скалиран (линеарно) Letterbox,OPTVAL_LETTERBOX,,,,,,,Leterkesto,,,,,,Bande nere,レターボックス,레터박스,Brievenbus,,,,,Экранное каше,Поштанско сандуче @@ -663,7 +669,28 @@ Unlimited,OPTVAL_UNLIMITED,,,,,Unlimitiert,,,,,,,,,,,,,,,,, 120 fps,OPTVAL_120FPS,,,,,,,,,,,,,,,,,,,,,, 144 fps,OPTVAL_144FPS,,,,,,,,,,,,,,,,,,,,,, 200 fps,OPTVAL_200FPS,,,,,,,,,,,,,,,,,,,,,, -,Obituaries,,,,,,,,,,,,,,,,,,,,,, +,Miscellaneous Options,,,,,,,,,,,,,,,,,,,,,, +Miscellaneous Options,MISCMNU_TITLE,,,,Ostatní nastavení,Verschiedene Optionen,,Ekstraĵa agordoj,Opciones Misceláneas,,Sekalaiset asetukset,Options Annexes,,Opzioni miste,その他のオプション,그 외 설정,Diverse opties,Różne Opcje,Outras Opções,,,Дополнительные настройки,Разна подешавања +Merge left+right Alt/Ctrl/Shift,MISCMNU_MERGEKEYS,,,,Zkombinovat pravý a levý Alt/Ctrl/Shift,Linke und rechte Umschalt/Strg/Alt zusammenfassen,,Kunigi maldekstro+dekstro Alt/Ctrl/Shift,Combinar izq.+der. Alt/Ctrl/Mayús,,Yhdistä vasen ja oikea Alt/Ctrl/Vaihto,Combiner Alt/Ctrl/maj gauche & droite,,Unisci sinistra+destra Alt/Control/Maiusc,左と右のALT/CTRL/SHIFTキーを統合,양쪽 ALT/CTRL/SHIFT키 합병,Samenvoegen links+rechts Alt/Ctrl/Shift,Połącz przyciski lewo+prawo Alt/Ctrl/Shift,Unir teclas Alt/Ctrl/Shift esquerdas e direitas,Juntar Alt/Ctrl/Shift esquerdo+direito,,Не разделять левый/правый ALT/CTRL/SHIFT,Споји лево+десно Аlt/Ctrl/Shift +Alt-Enter toggles fullscreen,MISCMNU_WINFULLSCREENTOGGLE,,,,Alt-Enter přepíná celou obrazovku,Alt-Enter schaltet Vollbild an/aus,,Alt klavo-Enter klavo baskuligi tutekranon,Alt+Enter alterna pantalla completa,,Alt-Enter kytkee täyden ruudun päälle/pois,Alt-Entrée alterne plein écran,,Alt-Invio attiva/disattiva lo schermo pieno,ALTとENTERで全画面に切り替え,ALT+ENTER키로 전체화면 조정,Alt-Enter schakelt het volledige scherm aan/uit,Alt-Enter przełącza na pełen ekran,Alt-Enter ativa tela cheia,Alt-Enter ativa ecrã cheio,,Переключение полного экрана по ALT+ENTER,Alt-Enter пребацује на цео екран +Command-F toggles fullscreen,MISCMNU_MACFULLSCREENTOGGLE,,,,Command-F přepíná celou obrazovku,Cmd-F schaltet Vollbild an/aus,,Komando-F baskuligi tutekranon,Cmd-F alterna pantalla completa,,Komento-F kytkee täyden ruudun päälle/pois,Command-F alterne plein écran,,Command-F attiva/disattiva lo schermo pieno,Ctrl + Fキーで全画面表示,COMMAND+F키로 전체화면 조정,Command-F schakelt het volledige scherm aan/uit,Command-F przełącza pełny ekran,Command-F ativa tela cheia,Command-F ativa ecrã cheio,,Переключение полного экрана по Command+F,Command-F пребацује на цео екран +Show game selection dialog,MISCMNU_QUERYIWAD,,,,Zobrazit dialog pro výběr GRPu,Zeige Spielauswahl,,Montri GRP elekta dialogo,Mostrar diálogo de selección de GRP,,Näytä GRP-valintaikkuna,Afficher la séléction de jeu,,Mostra la schermata della selezione GRP,GRPの選択画面を表示,GRP 게임 선택창 표시,GRP-selectiedialoogvenster weergeven,Pokaż ekran wyboru gry,Mostrar janela de seleção de jogo.,,,Выбор GRP-файла при запуске,Покажи GRP дијалог за избор +Enable cheats from all games,MISCMNU_ALLCHEATS,,,,Povolit cheaty ze všech her,Ermögliche Cheats aus allen Spielen,,Aktivigi trompojn el tutaj ludoj,Activar trucos de todos los juegos,,Ota käyttöön huijauskoodit kaikista peleistä,Activer cheats de tous les jeux,,Abilita tutti i cheat da tutti i giochi,全ゲームでチート使用可にする,모든 게임에 치트 허용,Laat bedriegers van alle spellen toe,Włącz oszustwa ze wszystkich gier,Habilitar trapaças de todos os jogos,Permitir batotas de todos os jogos,,Читы из всех игр,Омогући читове од свих игара +Enable autosaves,MISCMNU_ENABLEAUTOSAVES,,,,Povolit automatické ukládání,Automatisches Speichern,,Aktivigi aŭtokonservojn,Activar autoguardado,,Ota käyttöön automaattiset tallennukset,Activer Sauvegardes auto,,Abilita i salvataggi automatici,オートセーブを有効化,빠른 저장 허용,Automatisch opslaan inschakelen,Włącz autozapis,Habilitar salvamento automático,Permitir gravação automática,,Автосохранения,Омогући аутосејвове +Number of autosaves,MISCMNU_AUTOSAVECOUNT,,,,Počet automatických uložených her,Anzahl von automatischen Speicherständen,,Kvanto da aŭtokonservojn,Número de autoguardados,,Automaattisten tallennusten lukumäärä,Total de sauvegardes auto,,Numero di salvataggi automatici,オートセーブの最大数,빠른 저장 수,Aantal autosafes,Liczba autozapisów,Número de salvamentos automáticos,Número de gravações automáticos,,Количество автосохранений,Број аутоматских чувања +Save/Load confirmation,MISCMNU_SAVELOADCONFIRMATION,,,,Potvrzení o uložení/načtení,Laden/Speichern bestätigen,,Konservi/Ŝarĝi jesigo,Confirmación al guardar/cargar,,Tallennuksen/Latauksen vahvistus,Confirmation C/S,,Conferma Salvataggio/Caricamento,セーブ/ロード時に確認,스크립트로 스크린샷 생성 허용,Opslaan/Laad bevestiging,Potwierdzenie zapisu/wczytania,Confirmação ao salvar/carregar,Confirmação ao gravar/carregar,,Подтверждение при сохранении/загрузке,Потврђивање током чувања/учитавања +Enable making screenshots by scripts,MISCMNU_ENABLESCRIPTSCREENSHOTS,,,,Povolit skriptům pořizovat snímky obrazovky,"Erlaube Skripts, Screenshots zu machen",,Aktivigi faranto ekrankopiojn per skriptoj,Habilitar captura de pantalla por scripts,,Salli komentosarjoin otetut kuvakaappaukset,Autoriser les Scripts à prendre des captures,,Abilita la cattura dello schermo tramite scripts,スクリプトからのスクショ作成を有効化,저장/불러오기 확인,Screenshots maken met behulp van scripts,Pozwól na robienie zrzutów ekranu przez skrypty,Habilitar capturas de tela por scripts,Permitir capturas de ecrã por scripts,,Возможность делать скриншоты через скрипты,Омогући прављење скриншотова по скрипти +Load *.deh/*.bex lumps,MISCMNU_DEHLOAD,,,,Načítat *.deh/*.bex soubory,Lade *.deh/*.bex Daten,,Ŝarĝi *.deh/*.bex lumpoj,Cargar archivos *.deh/*.bex,,Lataa *.deh/*.bex-lump-tiedostot,Charger fichiers *.deh/*.bex,,Carica i lump *.deh/*.bex,.deh/.bexファイルを読み込む,*.deh/*.bex 럼프 파일 불러오기,*.deh/*.bex laden,Załaduj dane *.deh/*.bex,Carregar lumps *.deh/*.bex,,,Загружать файлы *.deh/*.bex,Учитај *.deh/*.bex фајлове +Cache nodes,MISCMNU_CACHENODES,,,,Cachovat nodes,Nodes zwischenspeichern,,Kaŝmemoraj nodoj,Caché de nodos,,Tallenna solmut välimuistiin,Mise en cache des nodes,,Cache dei nodi,ノードキャッシュ,캐시 노드,Cache nodes,Węzły pamięci podręcznej,Cachê de nodes,Cache de nodes,,Кэширование нодов,Кеширани чворови +Time threshold for node caching,MISCMNU_CACHETIME,,,,Časový práh pro cachování nodes,Zeitschwelle für das Zwischenspeichern von Nodes,,Templimo pro kaŝmemornodi,Umbral de tiempo para caché de nodos,,Kynnysaika solmujen välimuistitallennukseen,Limite cache des nodes,,Soglia di tempo per il caching dei nodi,ノードキャッシュ時間の閾値,노드 캐싱을 위한 시간 임계값 계산,Tijdsdrempel voor het cachen van nodes,Próg czasowy buforowania węzłów,Limite de tempo para cachê de nodes,Limite de tempo para cache de nodes,,Временной порог для кэширования нодов,Временски праг за кеширање чвора +Clear node cache,MISCMNU_CLEARNODECACHE,,,,Vyčistit node cache,Nodespeicher löschen,,Viŝi kaŝmemorajn nodojn,Limpiar Caché de nodos,,Tyhjennä solmuvälimuisti,Vider le cache des nodes,,Pulisci la cache dei nodi,ノードのキャッシュをクリア,노드 캐시를 삭제,Duidelijke node cache,Wyczyść pamięć podręczną,Limpar cachê de nodes,Limpar cache de nodes,,Очистить кэш нодов,"Избриши кеширане чворове +" +Allow skipping of intermission scrollers,MISCMNU_INTERSCROLL,,,,Povolit přeskakování intermission posuvníků,Erlaube Überspringen von Intermission-Scrollern,,Permesi transsalti interaktajn rulumojn,Permitir omisión de intermedios,,Salli tarinaruutujen vierityksen ohittaminen,Sauter compteurs d'intermission,,Consenti di saltare gli scorrimenti delle intermissioni,クリア結果集計のスキップを許可,인터미션 스크롤러 생략 허용,,Pozwól na pominięcie wstawek,Pular telas de intervalo entre fases,Saltar ecrãs de intervalo entre níveis,,Разрешение пропуска текстовых вставок,Дозволи прескакање прелаза са текстовима +Scripts Only,OPTVAL_SCRIPTSONLY,,,,Pouze skripty,Nur Skripte,,Skriptoj Sole,Sólo scripts,,Vain komentosarjat,Scripts seulement,,Solo script,スクリプトのみ,스크립트에만,Alleen scripts,Tylko skrypty,Scripts apenas,,,Только скрипты,Само скрипте +Disable keyboard cheats,MISCMNU_NOCHEATS,,,,,Tastatur-Cheats deaktivieren,,Malaktivigi klavaran trumpon,Desactivar trucos por teclado,,,,,,キーボードからのチート無効,,Schakel cheats uit,,Desabilitar trapaças de teclado,,,, +Quicksave rotation,MISCMNU_QUICKSAVEROTATION,,,,Rotace rychle uložených her,Schnellspeicherrotation,,Rapidkonservado-rotacio,Rotación de Salvado Rápido,,Pikatallennuskierto,Rotation Sauvegardes Rapides,,Rotazione rapide della quicksave,クイックセーブ間隔,빠른 저장 간격,Roteer quicksaves,Rotacja szybkich zapisów,Rotação de quicksave,,,Чередовать слоты для быстрых сохранений,Окретање брзих чувања +Number of quicksaves in rotation,MISCMNU_QUICKSAVECOUNT,,,,Počet rychle uložených her v rotaci,Anzahl Schnellspeicherplätze,,Nombro da rapidkonservitaj ludoj en rotaciado,Número de Salvados Rápidos en Rotación,,Pikatallennusten määrä kierrossa,Nombre de sauvegardes en rotation,,Numero di quicksaves in rotazione,間隔クイックセーブの数,빠른 저장 간격의 수,Aantal roterende quicksaves,Ilość szybkich zapisów w rotacji,Número de quicksaves em rotação,,,Кол-во слотов для быстрых сохранений,Број брзих чувања у окретању +,Miscellaneous,,,,,,,,,,,,,,,,,,,,,, "You are playing the shareware version of Duke Nukem 3D. While this version is really cool, you @@ -672,6 +699,13 @@ game, along with other great extras which you'll get when you order the complete version and get the final three episodes.",BUYDUKE,,,,,,,,,,,,,,,,,,,,,, +"Buy the complete version of +Blood for three new episodes +plus eight BloodBath-only levels!",BUYBLOOD,,,,,,,,,,,,,,,,,,,,,, +"Loading and saving games +not supported +in this demo version of Blood.","BLOOD_SW_BLOCK +",,,,,,,,,,,,,,,,,,,,,, "Are you sure you want to end the game? ",ENDGAME,,,,"Opravdu si přeješ ukončit hru? ","Willst du das Spiel wirklich beenden? @@ -694,7 +728,7 @@ Are you sure you want to quit?,CONFIRM_QUITMSG,,,,Přeješ si odejít?,"Bist du Reset controls to defaults?,CONFIRM_CTRL1,,,,,Steuerung auf Standard zurücksetzen?,,,,,,,,,,,,,,,,, Reset controls to classic defaults?,CONFIRM_CTRL2,,,,,Steuerung auf klassischen Standard zurücksetzen?,,,,,,,,,,,,,,,,, Reset controls to left-handed defaults?,CONFIRM_CTRL3,,,,,Steuerung auf linkshändigen Standard zurücksetzen?,,,,,,,,,,,,,,,,, -,,,,,,,,,,,,,,,,,,,,,,, +,Obituaries,,,,,,,,,,,,,,,,,,,,,, %k boned %o like a fish,TXT_OBITUARY1,,,,%o byl@[ao_cs] vykoštěn@[ao_cs] jako ryba hráčem %k,%k hat %o zerlegt wie einen Fisch,,%k senostigis %o kiel fiŝon,%k deshuesó a %o como a un pescado,,%k perkasi %o paran kuin kalan,%k désossa %o comme un poisson,%k kifilézte %o -t mint a halat,%k ha dissossato %o come un pesce,%k は %o の骨を魚のように引っこ抜いた。,%k 은(는) %o 의 뼈를 발랐다.,%k uitgebeend %o zoals een vis,%k odfiletował@[ao_pl] %o jak rybę,%k desossou %o como um peixe,,,Игрок %k пересчитал косточки игрока %o,%k је очистио %o као рибу %k castrated %o,TXT_OBITUARY2,,,,%o byl@[ao_cs] vykastrován@[ao_cs] hráčem %k,%k hat %o kastriert,,%k kastris %o,%k castró a %o,,%k kastroi %o paran,%k castra %o,%k kasztrálta %o -t,%k ha castrato %o,%k は %o を去勢した。,%k 은(는) %o 을(를) 거세시켰다.,%k gecastreerd %o,%k wykastrował@[ao_pl] %o,%k castrou %o,,,Игрок %k кастрировал игрока %o,%k је кастрирао %o %k creamed %o,TXT_OBITUARY3,,,,%o byl@[ao_cs] rozšlehán@[ao_cs] hráčem %k,%k hat %o eingeseift,,%k kremigis %o,%k cremó a %o,,%k kermasi %o paran,%k a battu %o à plate couture ,%k elkente %o -t,%k ha cremato %o,%k は %o に反吐ブチ撒けさせた。,%k 은(는) %o 을(를) 양념시켰다.,%k romed %o,%k spienił@[ao_pl] %o,%k fez creme de %o,,,Игрок %k взбил игрока %o,%k је истукао %o diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index b6d2e5ff0..8b7b51e9b 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -1538,6 +1538,45 @@ OptionMenu CustomResolutionMenu //protected } +//------------------------------------------------------------------------------------------- +// +// Misc menu +// +//------------------------------------------------------------------------------------------- + +OptionValue Autosave +{ + 0, "$OPTVAL_ALWAYS" + 1, "$OPTVAL_SCRIPTSONLY" + 2, "$OPTVAL_NEVER" +} + +OptionMenu "MiscOptions" //protected +{ + Title "$MISCMNU_TITLE" + //Indent 220 + IfOption(Windows) + { + Option "$MISCMNU_WINFULLSCREENTOGGLE", "k_allowfullscreentoggle", "OnOff" + } + IfOption(Mac) + { + Option "$MISCMNU_MACFULLSCREENTOGGLE", "k_allowfullscreentoggle", "OnOff" + } + Option "$MISCMNU_QUERYIWAD", "queryiwad", "OnOff" + StaticText " " + //Option "$MISCMNU_ALLCHEATS", "allcheats", "OnOff" + Option "$MISCMNU_ENABLEAUTOSAVES", "disableautosave", "Autosave" + //Option "$MISCMNU_SAVELOADCONFIRMATION", "saveloadconfirmation", "OnOff" + Slider "$MISCMNU_AUTOSAVECOUNT", "autosavecount", 1, 20, 1, 0 + //Option "$MISCMNU_QUICKSAVEROTATION", "quicksaverotation", "OnOff" + Slider "$MISCMNU_QUICKSAVECOUNT", "quicksaverotationcount", 1, 20, 1, 0 + Option "$MISCMNU_INTERSCROLL", "nointerscrollabort", "OffOn" + //StaticText " " + //Option "$OPTMNU_LANGUAGE", "language", "LanguageOptions" - not ready yet + +} + //------------------------------------------------------------------------------------------- // From 54177cd27ddf3cc7b21e870882d267552ebaa41b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 5 Dec 2019 19:52:46 +0100 Subject: [PATCH 123/203] - added the animated player display. --- source/build/include/baselayer.h | 1 + source/common/gamecvars.cpp | 2 +- source/common/menu/menu.cpp | 23 +++++++++++++++++++---- source/common/menu/optionmenu.cpp | 20 ++++++++++++++++++++ source/duke3d/src/d_menu.cpp | 6 ++---- source/duke3d/src/duke3d.h | 1 + source/rr/src/d_menu.cpp | 8 +++----- source/rr/src/duke3d.h | 1 + source/rr/src/game.h | 2 +- wadsrc/static/demolition/menudef.txt | 21 ++++++++++----------- 10 files changed, 59 insertions(+), 26 deletions(-) diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 555f2a2ab..af8c402ce 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -236,6 +236,7 @@ struct GameInterface f.VFormat(fmt, ap); DoPrintMessage(prio, f); } + virtual void DrawPlayerSprite(const DVector2& origin, bool onteam) {} }; extern GameInterface* gi; diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index baf242034..c9c4df80a 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -571,7 +571,7 @@ CUSTOM_CVAR(Int, playerteam, 0, CVAR_USERINFO) // this one is transient and won' else ;// gi->UpdatePlayerTeam(); // this part is game specific } -// Will only become useful if the obituary system gets overhauled. +// Will only become useful if the obituary system gets overhauled and for localization CUSTOM_CVAR(Int, playergender, 0, CVAR_USERINFO|CVAR_ARCHIVE) { if (self < 0 || self > 3) self = 0; diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 350b2cabd..e2b6994cc 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -57,6 +57,7 @@ void RegisterRedneckMenus(); void RegisterBloodMenus(); void RegisterSWMenus(); void RegisterLoadsaveMenus(); +void RegisterOptionMenus(); extern bool rotatesprite_2doverride; bool help_disabled, credits_disabled; int g_currentMenu; // accessible by CON scripts - contains the current menu's script ID if defined or INT_MAX if none given. @@ -546,10 +547,23 @@ bool M_SetMenu(FName menu, int param, FName caller) else if ((*desc)->mType == MDESC_OptionsMenu) { FOptionMenuDescriptor *ld = static_cast(*desc); - //const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DOptionMenu) : ld->mClass; - - ld->CalcIndent(); - DOptionMenu *newmenu = new DOptionMenu; + DOptionMenu* newmenu; + if (ld->mClass != NAME_None) + { + auto ndx = menuClasses.FindEx([=](const auto p) { return p->mName == ld->mClass; }); + if (ndx == menuClasses.Size()) + { + I_Error("Bad menu class %s\n", ld->mClass.GetChars()); + } + else + { + newmenu = (DOptionMenu*)menuClasses[ndx]->CreateNew(); + } + } + else + { + newmenu = new DOptionMenu; + } newmenu->Init(DMenu::CurrentMenu, ld); M_ActivateMenu(newmenu); } @@ -922,6 +936,7 @@ void M_Init (void) RegisterBloodMenus(); RegisterSWMenus(); RegisterLoadsaveMenus(); + RegisterOptionMenus(); timerSetCallback(M_Ticker); M_ParseMenuDefs(); } diff --git a/source/common/menu/optionmenu.cpp b/source/common/menu/optionmenu.cpp index a7dbf2cf8..c5e1d5f14 100644 --- a/source/common/menu/optionmenu.cpp +++ b/source/common/menu/optionmenu.cpp @@ -539,3 +539,23 @@ FOptionMenuItem *FOptionMenuDescriptor::GetItem(FName name) } return NULL; } + +class PlayerMenu : public DOptionMenu +{ + using Super = DOptionMenu; + +public: + void Drawer() + { + // Hack: The team item is #3. This part doesn't work properly yet. + gi->DrawPlayerSprite(origin, (mDesc->mSelectedItem == 3)); + Super::Drawer(); + } +}; + +static TMenuClassDescriptor _ppm("NewPlayerMenu"); + +void RegisterOptionMenus() +{ + menuClasses.Push(&_ppm); +} diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 0930c3aa2..9dff0969f 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -757,12 +757,10 @@ void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *t mgametextcenter(int(origin.X * 65536), int((origin.Y + position) * 65536), text); } -#if 0 -void GameInterface::DrawPlayerSprite(int x, int y) +void GameInterface::DrawPlayerSprite(const DVector2& origin, bool onteam) { - rotatesprite_fs(origin.x + (260<<16), origin.y + ((24+(tilesiz[APLAYER].y>>1))<<16), 49152L,0,1441-((((4-((int32_t) totalclock>>4)))&3)*5),0,entry == &ME_PLAYER_TEAM ? G_GetTeamPalette(playerteam) : playercolor,10); + rotatesprite_fs(int(origin.X * 65536) + (260<<16), int(origin.Y*65536) + ((24+(tilesiz[APLAYER].y>>1))<<16), 49152L,0,1441-((((4-((int32_t) totalclock>>4)))&3)*5),0,onteam ? G_GetTeamPalette(playerteam) : G_CheckPlayerColor(playercolor),10); } -#endif END_DUKE_NS diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index 85978763d..231aa76f2 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -169,6 +169,7 @@ struct GameInterface : ::GameInterface bool SaveGame(FSaveGameNode*) override; bool LoadGame(FSaveGameNode*) override; void DoPrintMessage(int prio, const char*) override; + void DrawPlayerSprite(const DVector2& origin, bool onteam) override; }; diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index 5c3334abb..ec69acf1b 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -475,15 +475,13 @@ void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *t } -#if 0 -void GameInterface::DrawPlayerSprite(int x, int y) +void GameInterface::DrawPlayerSprite(const DVector2& origin, bool onteam) { if (RR) - rotatesprite_fs(origin.x + (260<<16), origin.y + ((24+(tilesiz[APLAYER].y>>2))<<16), 24576L,0,3845+36-((((8-((int32_t) totalclock>>4)))&7)*5),0,entry == &ME_PLAYER_TEAM ? G_GetTeamPalette(playerteam) : playercolor,10); + rotatesprite_fs(int(origin.X * 65536) + (260<<16), int(origin.Y * 65536) + ((24+(tilesiz[APLAYER].y>>2))<<16), 24576L,0,3845+36-((((8-((int32_t) totalclock>>4)))&7)*5),0,onteam ? G_GetTeamPalette(playerteam) : G_CheckPlayerColor(playercolor),10); else - rotatesprite_fs(origin.x + (260<<16), origin.y + ((24+(tilesiz[APLAYER].y>>1))<<16), 49152L,0,1441-((((4-((int32_t) totalclock>>4)))&3)*5),0,entry == &ME_PLAYER_TEAM ? G_GetTeamPalette(playerteam) : playercolor,10); + rotatesprite_fs(int(origin.X * 65536) + (260<<16), int(origin.Y * 65536) + ((24+(tilesiz[APLAYER].y>>1))<<16), 49152L,0,1441-((((4-((int32_t) totalclock>>4)))&3)*5),0,onteam ? G_GetTeamPalette(playerteam) : G_CheckPlayerColor(playercolor),10); } -#endif END_RR_NS diff --git a/source/rr/src/duke3d.h b/source/rr/src/duke3d.h index 52b1985e2..523cf612c 100644 --- a/source/rr/src/duke3d.h +++ b/source/rr/src/duke3d.h @@ -169,6 +169,7 @@ struct GameInterface : ::GameInterface bool SaveGame(FSaveGameNode*) override; bool LoadGame(FSaveGameNode*) override; void DoPrintMessage(int prio, const char* text) override; + void DrawPlayerSprite(const DVector2& origin, bool onteam) override; }; END_RR_NS diff --git a/source/rr/src/game.h b/source/rr/src/game.h index b3791e105..7b451136e 100644 --- a/source/rr/src/game.h +++ b/source/rr/src/game.h @@ -307,7 +307,7 @@ void fadepal(int32_t r,int32_t g,int32_t b,int32_t start,int32_t end,int32_t ste //void fadepaltile(int32_t r,int32_t g,int32_t b,int32_t start,int32_t end,int32_t step,int32_t tile); void G_InitTimer(int32_t ticspersec); -static inline int32_t G_GetTeamPalette(int32_t team) +inline int32_t G_GetTeamPalette(int32_t team) { int8_t pal[] = { 3, 10, 11, 12 }; diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 8b7b51e9b..4f00dda81 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -965,15 +965,15 @@ OptionValue "PlayerColors" { 0, "$OPTVAL_AUTO" 1, "$TXT_COLOR_BLUE" - 2, "TXT_COLOR_RED" - 3, "TXT_COLOR_GREEN" - 4, "TXT_COLOR_GRAY" - 5, "TXT_COLOR_DARKGRAY" - 6, "TXT_COLOR_DARKGREEN" - 7, "TXT_COLOR_BROWN" - 8, "TXT_COLOR_DARKBLUE" - 9, "TXT_COLOR_LIGHTRED" - 10, "TXT_COLOR_YELLOW" + 2, "$TXT_COLOR_RED" + 3, "$TXT_COLOR_GREEN" + 4, "$TXT_COLOR_GRAY" + 5, "$TXT_COLOR_DARKGRAY" + 6, "$TXT_COLOR_DARKGREEN" + 7, "$TXT_COLOR_BROWN" + 8, "$TXT_COLOR_DARKBLUE" + 9, "$TXT_COLOR_LIGHTRED" + //10, "TXT_COLOR_YELLOW" } OptionValue "PlayerTeam" @@ -997,9 +997,9 @@ OptionMenu "NewPlayerMenu" //protected { Title "$MNU_PLAYERSETUP" TextField "$PLYRMNU_NAME", playername - Option "$PLYRMNU_TEAM", "playerteam", "PlayerTeam" Option "$PLYRMNU_PLAYERCOLOR", "playercolor", "PlayerColors" Option "$PLYRMNU_PLAYERGENDER", "playergender", "Gender" + Option "$PLYRMNU_TEAM", "playerteam", "PlayerTeam" Submenu "$PLRMNU_TAUNTS", "TauntsMenu" Class "NewPlayerMenu" } @@ -1048,7 +1048,6 @@ OptionValue "WeapSwitch" OptionMenu GameplayOptions //protected { - Position -35 Title "$GMPLYMNU_TITLE" Option "$PLRMNU_AUTOAIM", "cl_autoaim", "AimMode" Option "$PLRMNU_ALWAYSRUN", "cl_autorun", "OnOff" From 1b9d1943c9bbf257203388dfc7054e5304d6c5fe Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 5 Dec 2019 20:50:19 +0100 Subject: [PATCH 124/203] - initialize all dynamic music related menus. --- source/common/menu/menudef.cpp | 67 ++++++++++- source/common/music/backend/oalsound.cpp | 3 +- source/common/music/i_music.cpp | 2 +- source/common/music/music_config.cpp | 4 +- source/common/music/music_midi_base.cpp | 136 +++++++++++++++++++++-- source/common/utility/namedef.h | 4 + wadsrc/static/demolition/GENMIDI.op2 | Bin 0 -> 11908 bytes 7 files changed, 197 insertions(+), 19 deletions(-) create mode 100644 wadsrc/static/demolition/GENMIDI.op2 diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 172aaf806..58cc93aa0 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -46,6 +46,8 @@ #include "cmdlib.h" #include "c_cvars.h" #include "optionmenuitems.h" +#include "i_soundfont.h" +#include "zmusic/zmusic.h" // Menu-relevant content that gets filled in by scripts. This will get processed after the game has loaded. FString gSkillNames[MAXSKILLS]; @@ -61,7 +63,9 @@ static FOptionMenuDescriptor DefaultOptionMenuSettings; // contains common setti FOptionMenuSettings OptionSettings; FOptionMap OptionValues; +void I_BuildMIDIMenuList(FOptionValues* opt); void I_BuildALDeviceList(FOptionValues *opt); +void I_BuildALResamplersList(FOptionValues* opt); static void DeinitMenus() { @@ -1393,6 +1397,55 @@ static void InitCrosshairsList() #endif } +//============================================================================= +// +// Initialize the music configuration submenus +// +//============================================================================= +extern "C" +{ + extern int adl_getBanksCount(); + extern const char* const* adl_getBankNames(); +} + +static void InitMusicMenus() +{ + FMenuDescriptor** advmenu = MenuDescriptors.CheckKey(NAME_AdvSoundOptions); + auto soundfonts = sfmanager.GetList(); + std::tuple sfmenus[] = { + std::make_tuple("TimidityConfigMenu", SF_SF2 | SF_GUS, "timidity_config"), + std::make_tuple("FluidPatchsetMenu", SF_SF2, "fluid_patchset") }; + + for (auto& p : sfmenus) + { + FMenuDescriptor** menu = MenuDescriptors.CheckKey(std::get<0>(p)); + + if (menu != nullptr) + { + if (soundfonts.Size() > 0) + { + for (auto& entry : soundfonts) + { + if (entry.type & std::get<1>(p)) + { + FString display = entry.mName; + display.ReplaceChars("_", ' '); + auto it = new FOptionMenuItemCommand (display, FStringf("%s \"%s\"", std::get<2>(p), entry.mName.GetChars())/*, true*/); + static_cast(*menu)->mItems.Push(it); + } + } + } + else if (advmenu != nullptr) + { + // Remove the item for this submenu + auto d = static_cast(*advmenu); + auto it = d->GetItem(std::get<0>(p)); + if (it != nullptr) d->mItems.Delete(d->mItems.Find(it)); + } + } + } +} + //============================================================================= // // Special menus will be created once all engine data is loaded @@ -1403,19 +1456,23 @@ void M_CreateMenus() { BuildEpisodeMenu(); InitCrosshairsList(); + InitMusicMenus(); -#if 0 - FOptionValues **opt = OptionValues.CheckKey(NAME_Mididevices); - if (opt != NULL) + FOptionValues** opt = OptionValues.CheckKey(NAME_Mididevices); + if (opt != nullptr) { I_BuildMIDIMenuList(*opt); } opt = OptionValues.CheckKey(NAME_Aldevices); - if (opt != NULL) + if (opt != nullptr) { I_BuildALDeviceList(*opt); } -#endif + opt = OptionValues.CheckKey(NAME_Alresamplers); + if (opt != nullptr) + { + I_BuildALResamplersList(*opt); + } } //============================================================================= diff --git a/source/common/music/backend/oalsound.cpp b/source/common/music/backend/oalsound.cpp index ff8afc2f0..5506e445b 100644 --- a/source/common/music/backend/oalsound.cpp +++ b/source/common/music/backend/oalsound.cpp @@ -43,6 +43,7 @@ #include "cmdlib.h" #include "c_cvars.h" #include "printf.h" +#include "menu.h" #include "zmusic/sounddecoder.h" #include "filereadermusicinterface.h" @@ -96,7 +97,6 @@ bool IsOpenALPresent() -#if 0 void I_BuildALDeviceList(FOptionValues *opt) { opt->mValues.Resize(1); @@ -148,7 +148,6 @@ void I_BuildALResamplersList(FOptionValues *opt) } #endif } -#endif ReverbContainer *ForcedEnvironment; diff --git a/source/common/music/i_music.cpp b/source/common/music/i_music.cpp index 23547764a..dd4093b1f 100644 --- a/source/common/music/i_music.cpp +++ b/source/common/music/i_music.cpp @@ -226,7 +226,7 @@ static void SetupGenMidi() { // The OPL renderer should not care about where this comes from. // Note: No I_Error here - this needs to be consistent with the rest of the music code. - auto lump = fileSystem.FindFile("demolition/genmidi.dat"); + auto lump = fileSystem.FindFile("demolition/genmidi.op2"); if (lump < 0) { Printf("No GENMIDI lump found. OPL playback not available."); diff --git a/source/common/music/music_config.cpp b/source/common/music/music_config.cpp index e28875606..2f8cc98ab 100644 --- a/source/common/music/music_config.cpp +++ b/source/common/music/music_config.cpp @@ -74,7 +74,7 @@ CUSTOM_CVAR(String, fluid_lib, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTU FORWARD_STRING_CVAR(fluid_lib); } -CUSTOM_CVAR(String, fluid_patchset, "gzdoom", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) +CUSTOM_CVAR(String, fluid_patchset, "demolition", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { FORWARD_STRING_CVAR(fluid_patchset); } @@ -273,7 +273,7 @@ CUSTOM_CVAR(Float, min_sustain_time, 5000, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CV FORWARD_CVAR(min_sustain_time); } -CUSTOM_CVAR(String, timidity_config, "gzdoom", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) +CUSTOM_CVAR(String, timidity_config, "demolition", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) { FORWARD_STRING_CVAR(timidity_config); } diff --git a/source/common/music/music_midi_base.cpp b/source/common/music/music_midi_base.cpp index 02bf631f9..6c1b615f1 100644 --- a/source/common/music/music_midi_base.cpp +++ b/source/common/music/music_midi_base.cpp @@ -33,32 +33,150 @@ #define DEF_MIDIDEV -5 -static uint32_t nummididevices; -#define NUM_DEF_DEVICES 7 +#define NUM_DEF_DEVICES 3 #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include #include - -void I_InitMusicWin32 () -{ - nummididevices = midiOutGetNumDevs (); -} - - #endif #include "c_dispatch.h" #include "v_text.h" +#include "menu/menu.h" #include "zmusic/zmusic.h" #include "s_music.h" #include "c_cvars.h" #include "printf.h" EXTERN_CVAR(Int, snd_mididevice) +static uint32_t nummididevices; + + +static void AddDefaultMidiDevices(FOptionValues *opt) +{ + FOptionValues::Pair *pair = &opt->mValues[opt->mValues.Reserve(NUM_DEF_DEVICES)]; + pair[0].Text = "FluidSynth"; + pair[0].Value = -5.0; + pair[1].Text = "TiMidity++"; + pair[1].Value = -2.0; + pair[2].Text = "OPL Synth Emulation"; + pair[2].Value = -3.0; + +} + +#ifdef _WIN32 + +void I_InitMusicWin32 () +{ + nummididevices = midiOutGetNumDevs (); +} + +void I_BuildMIDIMenuList (FOptionValues *opt) +{ + AddDefaultMidiDevices(opt); + + for (uint32_t id = 0; id < nummididevices; ++id) + { + MIDIOUTCAPS caps; + MMRESULT res; + + res = midiOutGetDevCaps (id, &caps, sizeof(caps)); + assert(res == MMSYSERR_NOERROR); + if (res == MMSYSERR_NOERROR) + { + FOptionValues::Pair *pair = &opt->mValues[opt->mValues.Reserve(1)]; + pair->Text = caps.szPname; + pair->Value = (float)id; + } + } +} + +static void PrintMidiDevice (int id, const char *name, uint16_t tech, uint32_t support) +{ + if (id == snd_mididevice) + { + Printf (TEXTCOLOR_BOLD); + } + Printf ("% 2d. %s : ", id, name); + switch (tech) + { + case MIDIDEV_MIDIPORT: Printf ("MIDIPORT"); break; + case MIDIDEV_SYNTH: Printf ("SYNTH"); break; + case MIDIDEV_SQSYNTH: Printf ("SQSYNTH"); break; + case MIDIDEV_FMSYNTH: Printf ("FMSYNTH"); break; + case MIDIDEV_MAPPER: Printf ("MAPPER"); break; + case MIDIDEV_WAVETABLE: Printf ("WAVETABLE"); break; + case MIDIDEV_SWSYNTH: Printf ("SWSYNTH"); break; + } + if (support & MIDICAPS_CACHE) + { + Printf (" CACHE"); + } + if (support & MIDICAPS_LRVOLUME) + { + Printf (" LRVOLUME"); + } + if (support & MIDICAPS_STREAM) + { + Printf (" STREAM"); + } + if (support & MIDICAPS_VOLUME) + { + Printf (" VOLUME"); + } + Printf (TEXTCOLOR_NORMAL "\n"); +} + +CCMD (snd_listmididevices) +{ + UINT id; + MIDIOUTCAPS caps; + MMRESULT res; + + PrintMidiDevice(-8, "libOPN", MIDIDEV_FMSYNTH, 0); + PrintMidiDevice(-7, "libADL", MIDIDEV_FMSYNTH, 0); + PrintMidiDevice (-6, "WildMidi", MIDIDEV_SWSYNTH, 0); + PrintMidiDevice (-5, "FluidSynth", MIDIDEV_SWSYNTH, 0); + PrintMidiDevice (-4, "Gravis Ultrasound Emulation", MIDIDEV_SWSYNTH, 0); + PrintMidiDevice (-3, "Emulated OPL FM Synth", MIDIDEV_FMSYNTH, 0); + PrintMidiDevice (-2, "TiMidity++", MIDIDEV_SWSYNTH, 0); + if (nummididevices != 0) + { + for (id = 0; id < nummididevices; ++id) + { + FString text; + res = midiOutGetDevCaps (id, &caps, sizeof(caps)); + if (res == MMSYSERR_NODRIVER) + text = ""; + else if (res == MMSYSERR_NOMEM) + text = ""; + else if (res == MMSYSERR_NOERROR) + text = caps.szPname; + else + continue; + + PrintMidiDevice (id, text, caps.wTechnology, caps.dwSupport); + } + } +} + +#else + +void I_BuildMIDIMenuList (FOptionValues *opt) +{ + AddDefaultMidiDevices(opt); +} + +CCMD (snd_listmididevices) +{ + Printf("%s-5. FluidSynth\n", -5 == snd_mididevice ? TEXTCOLOR_BOLD : ""); + Printf("%s-3. Emulated OPL FM Synth\n", -3 == snd_mididevice ? TEXTCOLOR_BOLD : ""); + Printf("%s-2. TiMidity++\n", -2 == snd_mididevice ? TEXTCOLOR_BOLD : ""); +} +#endif CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) diff --git a/source/common/utility/namedef.h b/source/common/utility/namedef.h index ffd9c8978..3fdb641b3 100644 --- a/source/common/utility/namedef.h +++ b/source/common/utility/namedef.h @@ -40,3 +40,7 @@ xx(StartGame) xx(ImageScroller) xx(QuitMenu) xx(EndgameMenu) +xx(Mididevices) +xx(Aldevices) +xx(Alresamplers) +xx(AdvSoundOptions) \ No newline at end of file diff --git a/wadsrc/static/demolition/GENMIDI.op2 b/wadsrc/static/demolition/GENMIDI.op2 new file mode 100644 index 0000000000000000000000000000000000000000..5c86b77875a5ee61b4978d1cca7ea7c1e5ff9528 GIT binary patch literal 11908 zcmcgwdvH@{c0c#(>PnV{Y}p252ym}$zzL<1WCxl~*~m7}ZW4^GK)Tayd@bMD3bL*& z$#J0F_S!tdOecg*>1OlChBl;W+LW@X$&a zz=4?2B-;hO#mU|oG&8&|iQeR#05w?}@AWqXSY!9#KHUxgp5z-G*sI;C23{8t3vdR! zx8tC@9PX)fEzJBL~|Urr9b5L zbuMq}V?#%I`a^*A;7%?;Rv#TYk}X!hTXbKY&C2@9!uzWc&vVR90oilOKe74+(Vd(J zrVqe0z(ZAt1z5pkO@M9g6!;seyr~-oP2=1tYau2+56xTzU3S*Jp8^o!^UOo(i!ikk z&dngUAts&I97M|Xb`D*}WHr8mc!M1bO#ac~a%v8yHr7nw7qj&h{NV@gxoKO@b{$sF z;kyHFq9hgWyii0$A8Pw2PkX7sb>zGYNX5$j^KV zx&w8zeY6}CjraLl!Cz-@o_WiHF->QRF~#(iORG8EZd0zV<#dw&_m}L5tqfBhkX^p% z1@LclarlML=b2W*7OrZV2$+A)K=k$1;1`5TXYd{6-RSG9Ie)cqIft1(9)Z*AR`>!9 zhOG7;!quJ}CRv=`i1898`x`mEnrvrSoXBATo(1_IHiCbJ=@g1jClQC#>(mI?9GJhaE}0|K%Tate7mpL%43|755thh#Haq%1V6P- zyF6mbjR|N^erDC1M0e^2$M_)Tbj;_}4J(ihhCUncoI2`K zr@>D;w@hz98izZF>Fl_F>*I8r=)QK#!hBfwTc1S-9x>-9*~G_t0}p7U-8(aj0N-)* z(-zDkSX|)1&1gh$Pt0T9*#pz_7PimNu+xtiIN&j+IT{Dj@Fg@>M)Mqeer8?-iz9t$ zpUCtf>^HFAuxk?Ja}tHf``%4Jf1nRf^uttx;JuK=q_byw5%hHqFP(3C8mH+*IN+T{ z8=iL~$K=;H!BmaIm;BhUt2(`C1+;x(uQ0WO(HsNsN421@5$h)2M)OEkryumS_Il+l z@H?69IyAj-6XOH!H{P}yxp8}(4zc`0tPw^{&|&4@+~lDV+?U_Z=8r++d;cke21w^L z9zK`DGsDg@Dv&#T`7?<1@Yrq+Ryusw8fhKRR}m)LrRYXpU+GYkO-BC6(T$wmWbafq zky^%ikM?)*{u+m;b0yFCl**cb=#>T@YWU_}JQtKdqgPt3P!G+$HY>xV^XRN>)oaD( z{#8aVDCKhkrVk)ZqagRMq#6m3TEPC%_~c=*`$?utpj^r5RY?L7eM5^*?`K(APQ|uDwY)|Emlv{;QSpJH;^N^9hI+ z=u?mS_zLu?XE9x(@iZ7Z=V&^FoX*F=w+H>&YQJ=l7nuBxeR$sQvtK^QThUHBr>CIV zZ2|vkkQFRD0`ivK?YzFiE_ZG-Fsm&+n0EKrntL$()El4l&w_uAt<}K9=UI^6e319o zin4-POgTUB=7XH>24xf-+Q4)^1IcIr_raz91O^7*C0|CoehCY38fukpUaxh!uQhNi z?&p+lPOov+&FnHT<&T_b0KLH_kD)BmSvii$R_kp07dz;in5;<{?QOyS=~5<|j9RDk zAztTF6vRgVz`D`568Sik$?Yf#_tEFlW8~q{zSSJaf-ljCK0u$9<`16t&TRm)Q;uyh zWXaQ*$eWz9f?G%y^-B5JApp#&sYZ^y^Nii%q1GQhTyg{4!c_$k0*(Sic(V?tG!1gWIhh+K28bPmjdUs(;kncTXn=t`h+YsZ(MUM{2 z$X~-0xJDnik1)w!&WC6&^q(SM?wKFwdhRhu9YW39T*{&C2A}w!2G9vEWq3SSpC{qL?Ew+mTo;DEZ}`X8-73O* zXEZpH^Op`+y)`gps~+`Hs+O_q?CFzvMXmrqxO2wavZD? z^O)*t>(6%ax}~a}dyLlsu4G!z8Cc0;idU^MZ`5AFd4tXTIgE3H(Q{8gBKQK%E&PR- z(UlZa{s}9uqg{B=87AAkSXZ&x{M2pXv0q%zVbVvwa1r~UQ@(JXWBZCR+4bwF z!26qcWdiFV<@5D^f%9(=5u+)HN!CfF9rVrO_1=Kt=T{H3bNXh;W2!&L&-UW|!r9r~ z$D!@%%w!&8vNJv>!Q0!x>#IfSK)sPu&FNYJB!}16V)&h84amLJt7T8n;G+~_s$rPSj)nmy+8rf?R^m?ILuBX2EC9|t_E`jG1EI({D z&OtF2;0JJS>Y7D&f%ob)!#~eoxrQ|heBLZ3S%I@DoJC!oKVx?pynmfdQf}n20DlhG z+j{}l*hcG7AF5HomR>7jFJWUwdKQ%E+gL;#KK&f9xl;ZsE8&6XEC!~Sx*x;p+Th|Q z6C67i++zZd^APtKrn$if`^D%R0IPU;GHuLb{OB9l^Ta%+I@Uf`$N5*|T#y!6+#9B+ zEq-vg=jL(TWbv8=ZV}@Sz@_7q&*_Y9@t=8E12v2HQvB$_voqtffXm+U!VQttUb9-a z>bMW@dNuAhUlr!Xnx7YP4R3G*6<6w1$(YMu*sYc ztKt1P(bUDA>)EBu|vzYW*zi?H=vr{+sqjG$7sGGq`U>E3KJ7vcifV=${JUSCng29*K1z-Lf zas}?@I|iQ`s`GdUS-@){y&;;j3#&8DIXHQp zRi{|k^Vouz9_;V!Xh@T5&8|Zh%#E8R{vlb{w&SPl9PQ{ZW@_g&)l3%*;dPwy5Hq)P z^ZS5_OtG2B#!9h{)qgrvC*_#2E=O)s~w~pZkw7eI)$^#DmShWjFMxNhXofS##V*xk3Fv-}v6s0rVt%a1MJT#reH)D%6fFPLb`K zfcVq{Kg;-hmEo=u9~TfGfY}V{EOB#oEEpo@A^D7KFMKGbqQ^Favx6X77jdqvhA%P( zwj<`*y&L&7--!>>cx)dLABXkXHq!Zvk{m;tjf{_z{_iQT&*o24#Ao9Nvj(3{GlcDk z=?LLn9VeeV@j;p`ccQVv$sP9OIgF2;O9hPHU5t^>@86lv@jt4Xt>txx%kqtt{v$$; zv%pW;oOx`86Z`GgkC80+xWkZDmBqhgI74=Qrzv@zY+ak2A)3-$wZiEh%hTgL-v7As zLk6GjUl4ZXG0N%|QwPY0!UsW~-78O}I;lqRZ}nLav)uSY>*ABxg`C{{i@BUA&gYZg zDf9;tLor63S4+ueLFXKPvEXIMMj z&U`+95vJC|z860sdRBj03>p`sp|`(bG|oRJ8uAyOi*>)5e+_}t@!}^`Ueg((fqQc_ z-w@5c|IK8%x=0qlR|bupXpB8{2Jb|Jc5UasJczaf%r_DrdY0RTG@d)rpsYu^uQ8aI zhtyLje`>RM5%CK21=8%ROvCc$apyCChB;Q_II|^J`%Cm`tLY~puCph;vP_Z2COU7G zrmL_CI8I;ufqA^puKT1Z{MX6mc8S zH2aB01onk{P}aVc3s=D}*z0DWq22V9*tN5M;VOrHpc2iFyP&D%zW*x@svSR>*9=J} zvTEVqKg2&N9Y0AwQI_U=zex4t|Ec!>NFSwAPEU!>-#cm0ypVdwoTf9Vjl~n8ptL8Z zLb^FpPz+NR5jfaB6T5OQf7k_kzm8UB#L$?}M;|ZmB+g;;F#!$M{rRCG+ zu6N!Y;p0cbT69>8sCP$RLbY=&91M-9v66-Ci=8oLd_ajw`(r~&q#V)j@V%p+9M3x9j_K%Du)WN0o{ZFg0!C2^NH6mp>NXwp`p?E@zCD1|U>)B0sOh&Xw zC>US1St9>t&wrN^XIHJFSm*Vlb*b&iP-IArEvdI;pRpbd1rHaj0_={d2|QtOsSN+V zuo7i!lD9~*0hiY4{#E+)9f>4{D=;WnH)U`zq=iEjl8e?WRR^pe;bjH0NX2d~l87k- z=FUahKujIc!kW~FMKm&m9^U!LlMG<@0kEaU@SWF2^R0@liArKmg zDv?mh``imduCyx>S4RfIs^l%wpm^O^yiWelDQ^-&=KtKfX#{ebe7kQWz6Z5X(7ZzC z{UhxSB}_yFVq+sw)ojHe4#c#PfePg}Fg8#rJ>U^K&Qf_Pcs?RnANOi8^Caww(Yfox zCTm^;v-!=aOxzEJ>)*!xoncBnrEGf(s1YqzfuKu?g|Pdp-#%fn&C>)BH zcMz2otwMLe{*MQ%e1LmG*cvLF;N4*iph@23UiGTfS<3g<9wj1G;?Wh>#v?dCB(O^6 zcou&54J(JohLzxOnIn8?7#o23R>o$3knFFRqJ`p0em|@#gAyM4xH6v5w8U^>Z6ac} z-Y&HTm2fzuMOD-F4qP7&J^AFa&S8jR`yZfn1qaZf;_U|iZBiRM;U%kC`P-$o2e1p6 z>B#v1fz(FdTPRsfc$64j@S?{se;oU#=}uZl^P^h$NSsPxF%hjZ^R-Z6+ssR#bu@oK z8^eu{qV z2oBL^3gSANuOvpacyw5emE;GmllknH5y3g3SVvq(^M|wn?9#<+S^Y8kDqaAj!I%~; z*?*se9LNDUylqVkt0P4k^wCsTU{CSSE+z6*rT&iRb0id3&5JiO`>vL#v>m>yghL}0 zT1b~Ngcql%X>DNkhXw~L9DhLlB1)*(swEr1DyM&LM56k^y}*4of?+ zi<(W30EaYfa3HJ&4;Sz({25R}hc&ieYKy4jB_V!94QqpV!wP64h1>4>cdv>AbX=9X zkD!-LOw7*5G^R?AY8c6)`KBwTDp*?Bl9|vxRf*%}vuu32LNRRrc>2nW7y-P0viqIX zi}PQpguQAw6x5=Lavi2K8VxIB@v`#wj76lrVXchxqWPc2VYv>=?gu98ec{j`Hh267 zpHH`2}!p$ zK2WYU5&1IvO$OY9p#k&|UNTL1)2l-JO|}CIU6)3GBD6hfQlB2y#&LQpyUgZ)X_(R{ zh*U}mlcoH?o1)1&@i$*F3}X7>B@c_6sfTHQg=NFO3PqmwS6GH_y4zM5FCW3NE~uFI z2C@KaQ!F8spJE?IuT)qzobWq*(*J{MdG!qcP!p4IQa7n_#!~ Date: Fri, 6 Dec 2019 03:38:35 +0900 Subject: [PATCH 125/203] Fix rednukem compiling # Conflicts: # source/rr/src/anim.cpp # source/rr/src/common.cpp # source/rr/src/common_game.h # source/rr/src/game.cpp # source/rr/src/grpscan.cpp # source/rr/src/menus.cpp # source/rr/src/menus.h # source/rr/src/net.cpp # source/rr/src/net.h # source/rr/src/osdcmds.cpp # source/rr/src/player.cpp # source/rr/src/rts.cpp # source/rr/src/savegame.cpp # source/rr/src/screens.cpp # source/rr/src/sounds.cpp # source/rr/src/startosx.game.mm # source/rr/src/startwin.game.cpp --- source/platform/gtk/startgtk.game.cpp | 13 ++++++++----- source/rr/src/anim.cpp | 1 - source/rr/src/game.cpp | 6 +----- source/rr/src/menus.cpp | 8 ++++---- source/rr/src/net.cpp | 1 - source/rr/src/osdcmds.cpp | 6 ++++-- source/rr/src/premap.cpp | 1 - source/rr/src/savegame.cpp | 2 -- source/rr/src/sounds.cpp | 17 +++++++++++++++-- 9 files changed, 32 insertions(+), 23 deletions(-) diff --git a/source/platform/gtk/startgtk.game.cpp b/source/platform/gtk/startgtk.game.cpp index f21b92a4f..8f363973b 100644 --- a/source/platform/gtk/startgtk.game.cpp +++ b/source/platform/gtk/startgtk.game.cpp @@ -108,7 +108,9 @@ static struct grpfile_t const * grp; char *gamedir; ud_setup_t shared; +#ifdef POLYMER int polymer; +#endif } settings; static int32_t retval = -1, mode = TAB_MESSAGES; @@ -130,6 +132,7 @@ static void on_vmode3dcombo_changed(GtkComboBox *combobox, gpointer user_data) gtk_tree_model_get(data, &iter, 1, &val, -1); settings.shared.xdim = validmode[val].xdim; settings.shared.ydim = validmode[val].ydim; + settings.shared.bpp = validmode[val].bpp; } static void on_fullscreencheck_toggled(GtkToggleButton *togglebutton, gpointer user_data) @@ -272,7 +275,7 @@ static unsigned char GetModsDirNames(GtkListStore *list) char *homedir; char pdir[BMAX_PATH]; unsigned char iternumb = 0; - CACHE1D_FIND_REC *dirs = NULL; + BUILDVFS_FIND_REC *dirs = NULL; GtkTreeIter iter; pathsearchmode = 1; @@ -280,7 +283,7 @@ static unsigned char GetModsDirNames(GtkListStore *list) if ((homedir = Bgethomedir())) { Bsnprintf(pdir, sizeof(pdir), "%s/" ".eduke32", homedir); - dirs = klistpath(pdir, "*", CACHE1D_FIND_DIR); + dirs = klistpath(pdir, "*", BUILDVFS_FIND_DIR); for (; dirs != NULL; dirs=dirs->next) { if ((Bstrcmp(dirs->name, "autoload") == 0) || @@ -866,9 +869,7 @@ int32_t startwin_run(void) settings.gamedir = g_modDir; settings.grp = g_selectedGrp; #ifdef POLYMER - settings.polymer = (glrendmode == REND_POLYMER); -#else - settings.polymer = 0; + settings.polymer = (glrendmode == REND_POLYMER) & (settings.shared.bpp != 8); #endif PopulateForm(ALL); @@ -878,7 +879,9 @@ int32_t startwin_run(void) if (retval) // launch the game with these parameters { ud.setup = settings.shared; +#ifdef POLYMER glrendmode = (settings.polymer) ? REND_POLYMER : REND_POLYMOST; +#endif g_selectedGrp = settings.grp; Bstrcpy(g_modDir, (g_noSetup == 0 && settings.gamedir != NULL) ? settings.gamedir : "/"); diff --git a/source/rr/src/anim.cpp b/source/rr/src/anim.cpp index fd86e2d32..2eb9b20eb 100644 --- a/source/rr/src/anim.cpp +++ b/source/rr/src/anim.cpp @@ -494,7 +494,6 @@ int32_t Anim_Play(const char *fn) // setpalette(0L,256L,tempbuf); P_SetGamePalette(g_player[myconnectindex].ps, ANIMPAL, 8 + 2); - timerUpdate(); ototalclock = totalclock; i = 1; diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 3ed55ff05..0f078d8ac 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------- +//------------------------------------------------------------------------- /* Copyright (C) 2016 EDuke32 developers and contributors @@ -7882,8 +7882,6 @@ MAIN_LOOP_RESTART: do { - timerUpdate(); - if (ready2send == 0) break; Net_GetInput(); @@ -7897,8 +7895,6 @@ MAIN_LOOP_RESTART: G_MoveLoop(); } - timerUpdate(); - if (totalclock - moveClock >= TICSPERFRAME) { // computing a tic takes longer than a tic, so we're slowing diff --git a/source/rr/src/menus.cpp b/source/rr/src/menus.cpp index ad42eb674..d75dfd18f 100644 --- a/source/rr/src/menus.cpp +++ b/source/rr/src/menus.cpp @@ -5901,7 +5901,7 @@ static void Menu_Run(Menu_t *cm, const vec2_t origin) { if (object->findhigh[i]) { - CACHE1D_FIND_REC *dir; + BUILDVFS_FIND_REC *dir; int32_t y = 0; const int32_t y_upper = object->format[i]->pos.y; const int32_t y_lower = klabs(object->format[i]->bottomcutoff); @@ -6694,7 +6694,7 @@ static void Menu_RunInput(Menu_t *cm) { int32_t i; - CACHE1D_FIND_REC *seeker = object->findhigh[object->currentList]; + BUILDVFS_FIND_REC *seeker = object->findhigh[object->currentList]; inputState.ClearKeyStatus(sc_PgUp); @@ -6717,7 +6717,7 @@ static void Menu_RunInput(Menu_t *cm) { int32_t i; - CACHE1D_FIND_REC *seeker = object->findhigh[object->currentList]; + BUILDVFS_FIND_REC *seeker = object->findhigh[object->currentList]; inputState.ClearKeyStatus(sc_PgDn); @@ -6771,7 +6771,7 @@ static void Menu_RunInput(Menu_t *cm) ch = inputState.keyGetChar(); if (ch > 0 && ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9'))) { - CACHE1D_FIND_REC *seeker = object->findhigh[object->currentList]->usera; + BUILDVFS_FIND_REC *seeker = object->findhigh[object->currentList]->usera; if (ch >= 'a') ch -= ('a'-'A'); while (seeker) diff --git a/source/rr/src/net.cpp b/source/rr/src/net.cpp index 7506641c5..3b0eac385 100644 --- a/source/rr/src/net.cpp +++ b/source/rr/src/net.cpp @@ -2863,7 +2863,6 @@ void Net_ReceiveDisconnect(ENetEvent *event) void Net_GetPackets(void) { - timerUpdate(); MUSIC_Update(); G_HandleSpecialKeys(); diff --git a/source/rr/src/osdcmds.cpp b/source/rr/src/osdcmds.cpp index c42665d92..38bedde7f 100644 --- a/source/rr/src/osdcmds.cpp +++ b/source/rr/src/osdcmds.cpp @@ -927,8 +927,10 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("inittimer","debug", osdcmd_inittimer); #endif #if !defined NETCODE_DISABLE - //OSD_RegisterFunction("kick","kick : kicks a multiplayer client. See listplayers.", osdcmd_kick); - //OSD_RegisterFunction("kickban","kickban : kicks a multiplayer client and prevents them from reconnecting. See listplayers.", osdcmd_kickban); +#if 0 + OSD_RegisterFunction("kick","kick : kicks a multiplayer client. See listplayers.", osdcmd_kick); + OSD_RegisterFunction("kickban","kickban : kicks a multiplayer client and prevents them from reconnecting. See listplayers.", osdcmd_kickban); +#endif OSD_RegisterFunction("listplayers","listplayers: lists currently connected multiplayer clients", osdcmd_listplayers); #endif diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index b7f4b9316..1749ffee7 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -641,7 +641,6 @@ void G_CacheMapData(void) { Bsprintf(tempbuf, "Loaded %d%% (%d/%d textures)\n", lpc, pc, g_precacheCount); G_DoLoadScreen(tempbuf, lpc); - timerUpdate(); if (totalclock - tc >= 1) { diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index 0501c6f7a..b8c80a136 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -447,8 +447,6 @@ static void G_SaveTimers(void) static void G_RestoreTimers(void) { - timerUpdate(); - totalclock = g_timers.totalclock; totalclocklock = g_timers.totalclocklock; ototalclock = g_timers.ototalclock; diff --git a/source/rr/src/sounds.cpp b/source/rr/src/sounds.cpp index 85cf2b899..e3f897ede 100644 --- a/source/rr/src/sounds.cpp +++ b/source/rr/src/sounds.cpp @@ -98,15 +98,28 @@ void S_SoundShutdown(void) void S_MusicStartup(void) { - initprintf("Initializing music...\n"); + initprintf("Initializing MIDI driver... "); if (MUSIC_Init(MusicDevice) == MUSIC_Ok) { MUSIC_SetVolume(mus_volume); return; } +#if 0 + MUSIC_SetVolume(ud.config.MusicVolume); - initprintf("S_MusicStartup(): failed initializing\n"); + auto const fil = kopen4load("d3dtimbr.tmb", 0); + + if (fil != buildvfs_kfd_invalid) + { + int l = kfilelength(fil); + auto tmb = (uint8_t *)Xmalloc(l); + kread(fil, tmb, l); + AL_RegisterTimbreBank(tmb); + Xfree(tmb); + kclose(fil); + } +#endif } void S_MusicShutdown(void) From db425a12289f94cb8ee8cf9b20d61e400f024517 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 5 Dec 2019 21:39:02 +0100 Subject: [PATCH 126/203] - fixed keybinding and mouse cursor display. - fixed some merge issues in Shadow Warrior. --- source/build/include/baselayer.h | 2 +- source/build/src/sdlayer.cpp | 23 +++++++++-------------- source/common/console/c_console.cpp | 6 ++++-- source/common/menu/menu.cpp | 6 ++++-- source/common/menu/optionmenuitems.h | 5 ++++- source/sw/src/draw.cpp | 2 +- source/sw/src/menus.h | 1 - source/sw/src/panel.cpp | 3 +-- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index af8c402ce..c3a878b33 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -145,7 +145,7 @@ void joyScanDevices(void); void mouseInit(void); void mouseUninit(void); void mouseGrabInput(bool grab); -void mouseLockToWindow(char a); +void mouseLockToWindow(bool a); void mouseMoveToCenter(void); void joyReadButtons(int32_t *pResult); diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index 84d0badb0..89cef255a 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -33,10 +33,14 @@ #include "i_time.h" #include "c_dispatch.h" #include "d_gui.h" +#include "menu.h" #include "utf8.h" #include "imgui.h" #include "imgui_impl_sdl.h" #include "imgui_impl_opengl3.h" + + + #ifndef NETCODE_DISABLE #include "enet.h" #endif @@ -960,18 +964,9 @@ void mouseGrabInput(bool grab) g_mouseGrabbed = grab; inputState.MouseSetPos(0, 0); -} - -void mouseLockToWindow(char a) -{ - if (!(a & 2)) - { - mouseGrabInput(a); - g_mouseLockedToWindow = g_mouseGrabbed; - } - - // Fixme - SDL_ShowCursor(GUICapture ? SDL_ENABLE : SDL_DISABLE); + SDL_ShowCursor(!grab ? SDL_ENABLE : SDL_DISABLE); + if (grab) GUICapture &= ~1; + else GUICapture |= 1; } // @@ -1891,7 +1886,7 @@ int32_t handleevents_pollsdl(void) { code = ev.text.text[j]; // Fixme: Send an EV_GUI_Event instead and properly deal with Unicode. - if (GUICapture & 1) + if ((GUICapture & 1) && menuactive != MENU_WaitKey) { event_t ev = { EV_GUI_Event, EV_GUI_Char, int16_t(j), !!(SDL_GetModState() & KMOD_ALT) }; D_PostEvent(&ev); @@ -1903,7 +1898,7 @@ int32_t handleevents_pollsdl(void) case SDL_KEYDOWN: case SDL_KEYUP: { - if (GUICapture & 1) + if ((GUICapture & 1) && menuactive != MENU_WaitKey) { event_t event = {}; event.type = EV_GUI_Event; diff --git a/source/common/console/c_console.cpp b/source/common/console/c_console.cpp index b9fba6b15..aaeff2b06 100644 --- a/source/common/console/c_console.cpp +++ b/source/common/console/c_console.cpp @@ -55,6 +55,7 @@ #include "inputstate.h" #include "i_time.h" #include "gamecvars.h" +#include "baselayer.h" #define LEFTMARGIN 8 @@ -1317,13 +1318,14 @@ void C_ToggleConsole () HistPos = NULL; TabbedLast = false; TabbedList = false; - GUICapture |= 1; + mouseGrabInput(false); + } else //if (gamestate != GS_FULLCONSOLE && gamestate != GS_STARTUP) { ConsoleState = c_rising; C_FlushDisplay (); - GUICapture &= ~1; + mouseGrabInput(true); } } diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index e2b6994cc..a001ea575 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -51,6 +51,7 @@ #include "fx_man.h" #include "pragmas.h" #include "build.h" +#include "baselayer.h" void RegisterDukeMenus(); void RegisterRedneckMenus(); @@ -372,7 +373,7 @@ void M_StartControlPanel (bool makeSound) } C_HideConsole (); // [RH] Make sure console goes bye bye. - GUICapture |= 1; + mouseGrabInput(false); menuactive = MENU_On; // Pause sound effects before we play the menu switch sound. // That way, it won't be paused. @@ -814,6 +815,7 @@ void M_Ticker (void) if (DMenu::MenuTime & 3) return; if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) { + D_ProcessEvents(); // The main loop is blocked when the menu is open and cannot dispatch the events. if (transition.previous) transition.previous->Ticker(); DMenu::CurrentMenu->Ticker(); @@ -898,7 +900,7 @@ void M_ClearMenus () } DMenu::CurrentMenu = nullptr; menuactive = MENU_Off; - GUICapture &= ~1; + mouseGrabInput(true); gi->MenuClosed(); } diff --git a/source/common/menu/optionmenuitems.h b/source/common/menu/optionmenuitems.h index 9de745e97..8df332b8f 100644 --- a/source/common/menu/optionmenuitems.h +++ b/source/common/menu/optionmenuitems.h @@ -370,6 +370,7 @@ public: pKey = keyptr; SetMenuMessage(1); menuactive = MENU_WaitKey; // There should be a better way to disable GUI capture... + mouseGrabInput(true); } bool TranslateKeyboardEvents() override @@ -396,9 +397,11 @@ public: { *pKey = ev->data1; menuactive = MENU_On; + mouseGrabInput(false); SetMenuMessage(0); + auto p = mParentMenu; Close(); - mParentMenu->MenuEvent((ev->data1 == KEY_ESCAPE)? MKEY_Abort : MKEY_Input, 0); + p->MenuEvent((ev->data1 == KEY_ESCAPE)? MKEY_Abort : MKEY_Input, 0); return true; } return false; diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index 4d0384195..b1d6a8c4e 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -2591,7 +2591,7 @@ DrawCompass(PLAYERp pp) start_ang = NORM_CANG(start_ang - 4); flags = ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER; - if (RedrawCompass && !UsingMenus) + if (RedrawCompass && !M_Active()) { RedrawCompass = FALSE; SET(flags, ROTATE_SPRITE_ALL_PAGES); diff --git a/source/sw/src/menus.h b/source/sw/src/menus.h index d28c0c952..6a1289569 100644 --- a/source/sw/src/menus.h +++ b/source/sw/src/menus.h @@ -104,7 +104,6 @@ typedef enum ct_quitmenu, ct_ordermenu, ct_episodemenu, ct_max } CTLType; -extern SWBOOL UsingMenus; extern int SENSITIVITY; extern CTLType ControlPanelType; extern int16_t MenuTextShade; diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index a66b35f2c..16e75b1e3 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -7597,8 +7597,7 @@ pDisplaySprites(PLAYERp pp) } #if 1 - extern SWBOOL UsingMenus; - if (TEST(psp->flags, PANF_KILL_AFTER_SHOW) && !TEST(psp->flags, PANF_NOT_ALL_PAGES) && !UsingMenus) + if (TEST(psp->flags, PANF_KILL_AFTER_SHOW) && !TEST(psp->flags, PANF_NOT_ALL_PAGES) && !M_Active()) { psp->numpages = 0; SET(flags, ROTATE_SPRITE_ALL_PAGES); From 7a9138cde0a2f58709c8dc49cf3d6bc53f2f9432 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 5 Dec 2019 23:17:55 +0100 Subject: [PATCH 127/203] - made the confirmation screen functional. This works but still needs a bit of visual work. --- source/blood/src/blood.h | 1 + source/blood/src/d_menu.cpp | 10 ++ source/build/include/baselayer.h | 2 +- source/common/menu/menu.cpp | 12 +-- source/common/menu/messagebox.cpp | 158 ++++++++++++++---------------- source/duke3d/src/d_menu.cpp | 4 +- source/duke3d/src/duke3d.h | 2 +- source/rr/src/d_menu.cpp | 4 +- source/rr/src/duke3d.h | 2 +- source/sw/src/d_menu.cpp | 18 +++- source/sw/src/game.h | 2 +- 11 files changed, 113 insertions(+), 102 deletions(-) diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index 5328b470b..776b4e319 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -98,6 +98,7 @@ struct GameInterface : ::GameInterface bool SaveGame(FSaveGameNode*) override; bool LoadGame(FSaveGameNode*) override; void DoPrintMessage(int prio, const char*) override; + void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg); }; diff --git a/source/blood/src/d_menu.cpp b/source/blood/src/d_menu.cpp index 66f088d5a..107c2a933 100644 --- a/source/blood/src/d_menu.cpp +++ b/source/blood/src/d_menu.cpp @@ -280,6 +280,16 @@ void GameInterface::DrawMenuCaption(const DVector2& origin, const char* text) viewDrawText(1, text, 160, 20 - height / 2, -128, 0, 1, false); } +void GameInterface::DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg) +{ + if (text) + { + int width; + viewGetFontInfo(0, text, &width, NULL); + int x = 160 - width / 2; + viewDrawText(0, text, x, 100, 0, 0, 0, false); + } +} END_BLD_NS diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index c3a878b33..5c39c6bab 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -223,7 +223,7 @@ struct GameInterface virtual void StartGame(FGameStartup& gs) {} virtual FSavegameInfo GetSaveSig() { return { "", 0, 0}; } virtual bool DrawSpecialScreen(const DVector2 &origin, int tilenum) { return false; } - virtual void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) {} + virtual void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool withbg = true) {} virtual void DrawMenuCaption(const DVector2& origin, const char* text) {} virtual bool SaveGame(FSaveGameNode*) { return false; } virtual bool LoadGame(FSaveGameNode*) { return false; } diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index a001ea575..ee1191f0e 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -480,23 +480,23 @@ bool M_SetMenu(FName menu, int param, FName caller) M_StartMessage (msg, 0, -1, NAME_StartgameConfirmed); return; } +#endif - case NAME_Savegamemenu: - if (gi->canSave()) + case NAME_SaveGameMenu: + if (!gi->CanSave()) { // cannot save outside the game. M_StartMessage (GStrings("SAVEDEAD"), 1, -1); - return; + return true; } -#endif case NAME_QuitMenu: - // The separate menu class no longer exists but the name still needs support for existing mods. + // This is no separate class C_DoCommand("menu_quit"); return true; case NAME_EndgameMenu: - // The separate menu class no longer exists but the name still needs support for existing mods. + // This is no separate class C_DoCommand("memnu_endgame"); return true; } diff --git a/source/common/menu/messagebox.cpp b/source/common/menu/messagebox.cpp index 9326dd6ae..a40343405 100644 --- a/source/common/menu/messagebox.cpp +++ b/source/common/menu/messagebox.cpp @@ -46,6 +46,7 @@ extern FSaveGameNode *quickSaveSlot; class DMessageBoxMenu : public DMenu { using Super = DMenu; + FString mFullMessage; TArray mMessage; int mMessageMode; int messageSelection; @@ -99,6 +100,7 @@ void DMessageBoxMenu::Init(DMenu *parent, const char *message, int messagemode, mParentMenu = parent; if (message != NULL) { + mFullMessage = message; mMessage = V_BreakLines(SmallFont, 300, GStrings.localize(message)); } mMessageMode = messagemode; @@ -168,8 +170,9 @@ void DMessageBoxMenu::HandleResult(bool res) // // //============================================================================= +CVAR(Bool, m_generic_messagebox, false, CVAR_ARCHIVE) -void DMessageBoxMenu::Drawer () +void DMessageBoxMenu::Drawer() { int y; PalEntry fade = 0; @@ -180,43 +183,51 @@ void DMessageBoxMenu::Drawer () y = 100; - if (mMessage.Size()) + if (m_generic_messagebox) { - for (unsigned i = 0; i < mMessage.Size(); i++) - y -= SmallFont->GetHeight () / 2; - - for (unsigned i = 0; i < mMessage.Size(); i++) + if (mMessage.Size()) { - DrawText(&twod, SmallFont, CR_UNTRANSLATED, 160 - mMessage[i].Width/2, y, mMessage[i].Text, - DTA_Clean, true, TAG_DONE); - y += fontheight; - } - } + for (unsigned i = 0; i < mMessage.Size(); i++) + y -= SmallFont->GetHeight() / 2; - if (mMessageMode == 0) - { - y += fontheight; - mMouseY = y; - DrawText(&twod, SmallFont, - messageSelection == 0? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, - 160, y, GStrings["TXT_YES"], DTA_Clean, true, TAG_DONE); - DrawText(&twod, SmallFont, - messageSelection == 1? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, - 160, y + fontheight + 1, GStrings["TXT_NO"], DTA_Clean, true, TAG_DONE); - - if (messageSelection >= 0) - { - if (((DMenu::MenuTime>>2)%8) < 6) + for (unsigned i = 0; i < mMessage.Size(); i++) { - DrawText(&twod, ConFont, OptionSettings.mFontColorSelection, - (150 - 160) * CleanXfac + screen->GetWidth() / 2, - (y + (fontheight + 1) * messageSelection - 100 + fontheight/2 - 5) * CleanYfac + screen->GetHeight() / 2, - "\xd", - DTA_CellX, 8 * CleanXfac, - DTA_CellY, 8 * CleanYfac, - TAG_DONE); + DrawText(&twod, SmallFont, CR_UNTRANSLATED, 160 - mMessage[i].Width / 2, y, mMessage[i].Text, + DTA_Clean, true, TAG_DONE); + y += fontheight; } } + + if (mMessageMode == 0) + { + y += fontheight; + mMouseY = y; + DrawText(&twod, NewSmallFont, + messageSelection == 0 ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, + 160, y, GStrings["TXT_YES"], DTA_Clean, true, TAG_DONE); + DrawText(&twod, NewSmallFont, + messageSelection == 1 ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, + 160, y + fontheight + 1, GStrings["TXT_NO"], DTA_Clean, true, TAG_DONE); + + if (messageSelection >= 0) + { + if (((DMenu::MenuTime >> 2) % 8) < 6) + { + DrawText(&twod, NewSmallFont, OptionSettings.mFontColorSelection, + (150 - 160) * CleanXfac + screen->GetWidth() / 2, + (y + (fontheight + 1) * messageSelection - 100 + fontheight / 2 - 5) * CleanYfac + screen->GetHeight() / 2, + "\xd", + DTA_CellX, 8 * CleanXfac, + DTA_CellY, 8 * CleanYfac, + TAG_DONE); + } + } + } + } + else + { + twod.AddColorOnlyQuad(0, 0, xdim, ydim, 0xa0000000); + gi->DrawCenteredTextScreen(origin, mFullMessage, 100, false); } } @@ -269,7 +280,7 @@ bool DMessageBoxMenu::MenuEvent(int mkey, bool fromcontroller) { if (mMessageMode == 0) { - if (mkey == MKEY_Up || mkey == MKEY_Down) + if ((mkey == MKEY_Up || mkey == MKEY_Down) && m_generic_messagebox) { //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); messageSelection = !messageSelection; @@ -304,7 +315,7 @@ bool DMessageBoxMenu::MenuEvent(int mkey, bool fromcontroller) bool DMessageBoxMenu::MouseEvent(int type, int x, int y) { - if (mMessageMode == 1) + if (mMessageMode == 1 || m_generic_messagebox) { if (type == MOUSE_Click) { @@ -327,7 +338,7 @@ bool DMessageBoxMenu::MouseEvent(int type, int x, int y) } if (sel != -1 && sel != messageSelection) { - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + gi->MenuSound(CursorSound); } messageSelection = sel; if (type == MOUSE_Release) @@ -379,36 +390,38 @@ DMenu* CreateMessageBoxMenu(DMenu* parent, const char* message, int messagemode, } -#if 0 void ActivateEndGameMenu() { - FString tempstring = GStrings(netgame ? "NETEND" : "ENDGAME"); - DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() - { - M_ClearMenus(); - if (!netgame) - { - if (demorecording) - G_CheckDemoStatus(); - D_StartTitle(); - } - }); - - M_ActivateMenu(newmenu); } CCMD (menu_endgame) { // F7 - if (!usergame) + if (!gi->CanSave()) { - S_Sound (CHAN_VOICE | CHAN_UI, "menu/invalid", snd_menuvolume, ATTN_NONE); return; } - //M_StartControlPanel (true); - S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); + M_StartControlPanel (true); + FString tempstring = GStrings("ENDGAME"); + DMenu* newmenu = CreateMessageBoxMenu(DMenu::CurrentMenu, tempstring, 0, 501, false, NAME_None, [](bool res) + { + if (res) + { + M_ClearMenus(); + /*/ + if (!netgame) + { + if (demorecording) + G_CheckDemoStatus(); + D_StartTitle(); + } + */ - ActivateEndGameMenu(); + //gi->ReturnToTitle(); + } + }); + + M_ActivateMenu(newmenu); } //============================================================================= @@ -419,47 +432,18 @@ CCMD (menu_endgame) CCMD (menu_quit) { // F10 - if (m_quickexit) - { - ST_Endoom(); - } M_StartControlPanel (true); - const size_t messageindex = static_cast(gametic) % gameinfo.quitmessages.Size(); - FString EndString; - const char *msg = gameinfo.quitmessages[messageindex]; - if (msg[0] == '$') - { - if (msg[1] == '*') - { - EndString = GStrings(msg + 2); - } - else - { - EndString.Format("%s\n\n%s", GStrings(msg + 1), GStrings("DOSY")); - } - } - else EndString = gameinfo.quitmessages[messageindex]; + FString EndString = GStrings("CONFIRM_QUITMSG"); + EndString << "\n[Y/N]"; - DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, EndString, 0, false, NAME_None, []() + DMenu *newmenu = CreateMessageBoxMenu(DMenu::CurrentMenu, EndString, 0, 500, false, NAME_None, [](bool res) { - if (!netgame) - { - if (gameinfo.quitSound.IsNotEmpty()) - { - S_Sound(CHAN_VOICE | CHAN_UI, gameinfo.quitSound, snd_menuvolume, ATTN_NONE); - I_WaitVBL(105); - } - } - ST_Endoom(); + if (res) throw ExitEvent(0); }); - M_ActivateMenu(newmenu); } - - -#endif diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 9dff0969f..0167ae340 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -751,9 +751,9 @@ bool GameInterface::DrawSpecialScreen(const DVector2 &origin, int tilenum) } -void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) +void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position, bool bg) { - Menu_DrawBackground(origin); + if (bg) Menu_DrawBackground(origin); mgametextcenter(int(origin.X * 65536), int((origin.Y + position) * 65536), text); } diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index 231aa76f2..baa49d0a6 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -164,7 +164,7 @@ struct GameInterface : ::GameInterface void StartGame(FGameStartup& gs) override; FSavegameInfo GetSaveSig() override; bool DrawSpecialScreen(const DVector2 &origin, int tilenum) override; - void DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) override; + void DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position, bool bg) override; void DrawMenuCaption(const DVector2& origin, const char* text) override; bool SaveGame(FSaveGameNode*) override; bool LoadGame(FSaveGameNode*) override; diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index ec69acf1b..2bf67e573 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -466,9 +466,9 @@ void GameInterface::DrawMenuCaption(const DVector2& origin, const char* text) Menu_DrawTopBarCaption(text, origin); } -void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) +void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position, bool bg) { - Menu_DrawBackground(origin); + if (bg) Menu_DrawBackground(origin); G_ScreenText(MF_Bluefont.tilenum, int((origin.X + 160) * 65536), int((origin.Y + position) * 65536), MF_Bluefont.zoom, 0, 0, text, 0, MF_Bluefont.pal, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags | TEXT_XCENTER, 0, 0, xdim - 1, ydim - 1); diff --git a/source/rr/src/duke3d.h b/source/rr/src/duke3d.h index 523cf612c..4430c56db 100644 --- a/source/rr/src/duke3d.h +++ b/source/rr/src/duke3d.h @@ -164,7 +164,7 @@ struct GameInterface : ::GameInterface bool CanSave() override; void StartGame(FGameStartup& gs) override; FSavegameInfo GetSaveSig() override; - void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) override; + void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg) override; void DrawMenuCaption(const DVector2& origin, const char* text) override; bool SaveGame(FSaveGameNode*) override; bool LoadGame(FSaveGameNode*) override; diff --git a/source/sw/src/d_menu.cpp b/source/sw/src/d_menu.cpp index abd344ce1..f7f4548b1 100644 --- a/source/sw/src/d_menu.cpp +++ b/source/sw/src/d_menu.cpp @@ -254,8 +254,24 @@ void GameInterface::DrawMenuCaption(const DVector2& origin, const char* text) MNU_DrawString(TEXT_XCENTER(w), 5, text, 1, 16); } -void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) +void GameInterface::DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg) { + if (text) + { + short width, height = 0; + MNU_MeasureString("T", &width, &height); + + auto lines = FString(text).Split("\n"); + int y = 100 - (height * lines.Size() / 2); + for (auto& l : lines) + { + short lheight = 0; + MNU_MeasureString(text, &width, &lheight); + int x = 160 - width / 2; + MNU_DrawString(x, y, l, 0, 0); + y += height; + } + } } diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 50005d389..a7c6de29a 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -2384,7 +2384,7 @@ struct GameInterface : ::GameInterface void StartGame(FGameStartup& gs) override; FSavegameInfo GetSaveSig() override; void DrawMenuCaption(const DVector2& origin, const char* text) override; - void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) override; + void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg) override; bool LoadGame(FSaveGameNode* sv) override; bool SaveGame(FSaveGameNode* sv) override; void DoPrintMessage(int prio, const char* text) override; From 3d10d006a7ef162a093a29aa6db1fd419118dfd5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 5 Dec 2019 23:49:32 +0100 Subject: [PATCH 128/203] - fixing mouse menu control, part 1. --- source/build/src/sdlayer.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index 89cef255a..8dcf02b66 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -1702,8 +1702,25 @@ int32_t handleevents_sdlcommon(SDL_Event *ev) if (j < 0) break; - event_t evt = { uint8_t((ev->button.state == SDL_PRESSED)? EV_KeyDown : EV_KeyUp), 0, (int16_t)j}; - D_PostEvent(&evt); + if (!(GUICapture & 1)) + { + event_t evt = { uint8_t((ev->button.state == SDL_PRESSED) ? EV_KeyDown : EV_KeyUp), 0, (int16_t)j }; + D_PostEvent(&evt); + } + else + { + event_t evt; + evt.type = EV_GUI_Event; + evt.subtype = uint8_t((ev->button.state == SDL_PRESSED) ? EV_GUI_LButtonDown : EV_GUI_LButtonUp); + + SDL_Keymod kmod = SDL_GetModState(); + evt.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) | + ((kmod & KMOD_CTRL) ? GKM_CTRL : 0) | + ((kmod & KMOD_ALT) ? GKM_ALT : 0); + + D_PostEvent(&evt); + + } break; } @@ -2059,13 +2076,12 @@ int32_t handleevents(void) void I_SetMouseCapture() { // Clear out any mouse movement. - SDL_GetRelativeMouseState(NULL, NULL); - SDL_SetRelativeMouseMode(SDL_TRUE); + SDL_CaptureMouse(SDL_TRUE); } void I_ReleaseMouseCapture() { - SDL_SetRelativeMouseMode(SDL_FALSE); + SDL_CaptureMouse(SDL_FALSE); } auto vsnprintfptr = vsnprintf; // This is an inline in Visual Studio but we need an address for it to satisfy the MinGW compiled libraries. From a0fe7f40489a172252c266d7dac405f4b18416d8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 6 Dec 2019 00:06:41 +0100 Subject: [PATCH 129/203] - more mouse fixes. Most of the menu is now mouse controllable again. The exceptions are the text screens which do not react to the mouse and the confirmation screen which treats a mouse click as a cancel event. --- source/build/src/sdlayer.cpp | 2 ++ source/common/menu/menu.cpp | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index 8dcf02b66..7bb988b39 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -1712,6 +1712,8 @@ int32_t handleevents_sdlcommon(SDL_Event *ev) event_t evt; evt.type = EV_GUI_Event; evt.subtype = uint8_t((ev->button.state == SDL_PRESSED) ? EV_GUI_LButtonDown : EV_GUI_LButtonUp); + evt.data1 = ev->motion.x; + evt.data2 = ev->motion.y; SDL_Keymod kmod = SDL_GetModState(); evt.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) | diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index ee1191f0e..7163ccf0d 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -63,6 +63,7 @@ extern bool rotatesprite_2doverride; bool help_disabled, credits_disabled; int g_currentMenu; // accessible by CON scripts - contains the current menu's script ID if defined or INT_MAX if none given. int DrawBackground; +TArray toDelete; // // Todo: Move these elsewhere @@ -227,7 +228,7 @@ void DMenu::Close () else { Destroy(); - delete this; + toDelete.Push(this); if (DMenu::CurrentMenu == NULL) { M_ClearMenus(); @@ -620,7 +621,7 @@ bool M_SetMenu(FName menu, int param, FName caller) // //============================================================================= -bool M_Responder (event_t *ev) +bool M_DoResponder (event_t *ev) { int ch = 0; bool keyup = false; @@ -803,6 +804,15 @@ bool M_Responder (event_t *ev) return false; } +bool M_Responder(event_t* ev) +{ + // delayed deletion, so that self-deleting menus don't crash if they are getting accesses after being closed. + auto res = M_DoResponder(ev); + for (auto p : toDelete) delete p; + toDelete.Clear(); + return res; +} + //============================================================================= // // From 66756bfa132c58c2cb773e3e65aa07f550023afb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 6 Dec 2019 18:36:49 +0100 Subject: [PATCH 130/203] - final fixes for Blood's and Duke Nukem's menus. --- source/blood/src/blood.h | 1 + source/blood/src/d_menu.cpp | 28 ++++++++++++++++++++++++---- source/build/include/baselayer.h | 2 ++ source/common/menu/menu.cpp | 5 +++-- source/common/menu/messagebox.cpp | 12 +----------- source/duke3d/src/d_menu.cpp | 16 ++++++++++++++++ source/duke3d/src/duke3d.h | 1 + source/duke3d/src/game.cpp | 5 +++++ source/duke3d/src/menus.cpp | 13 ------------- source/rr/src/d_menu.cpp | 15 +++++++++++++++ source/rr/src/duke3d.h | 1 + source/rr/src/game.cpp | 5 +++++ source/sw/src/d_menu.cpp | 2 +- wadsrc/static/demolition/menudef.txt | 4 ++-- 14 files changed, 77 insertions(+), 33 deletions(-) diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index 776b4e319..0761bb81a 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -99,6 +99,7 @@ struct GameInterface : ::GameInterface bool LoadGame(FSaveGameNode*) override; void DoPrintMessage(int prio, const char*) override; void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg); + void QuitToTitle() override; }; diff --git a/source/blood/src/d_menu.cpp b/source/blood/src/d_menu.cpp index 107c2a933..3444b1a06 100644 --- a/source/blood/src/d_menu.cpp +++ b/source/blood/src/d_menu.cpp @@ -284,13 +284,33 @@ void GameInterface::DrawCenteredTextScreen(const DVector2& origin, const char* t { if (text) { - int width; - viewGetFontInfo(0, text, &width, NULL); - int x = 160 - width / 2; - viewDrawText(0, text, x, 100, 0, 0, 0, false); + int width, height = 0; + viewGetFontInfo(0, "T", &width, &height); + + auto lines = FString(text).Split("\n"); + int y = 100 - (height * lines.Size() / 2); + for (auto& l : lines) + { + int lheight = 0; + viewGetFontInfo(0, l, &width, &lheight); + int x = 160 - width / 2; + viewDrawText(0, l, x, y, 0, 0, 0, false); + y += height; + } } } +void GameInterface::QuitToTitle() +{ + if (gGameOptions.nGameType == 0 || numplayers == 1) + { + gQuitGame = true; + gRestartGame = true; + } + else + gQuitRequest = 2; +} + END_BLD_NS //---------------------------------------------------------------------------- diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 5c39c6bab..f590174c4 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -237,6 +237,8 @@ struct GameInterface DoPrintMessage(prio, f); } virtual void DrawPlayerSprite(const DVector2& origin, bool onteam) {} + virtual void QuitToTitle() {} + }; extern GameInterface* gi; diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 7163ccf0d..392289f1a 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -498,7 +498,7 @@ bool M_SetMenu(FName menu, int param, FName caller) case NAME_EndgameMenu: // This is no separate class - C_DoCommand("memnu_endgame"); + C_DoCommand("menu_endgame"); return true; } @@ -806,7 +806,7 @@ bool M_DoResponder (event_t *ev) bool M_Responder(event_t* ev) { - // delayed deletion, so that self-deleting menus don't crash if they are getting accesses after being closed. + // delayed deletion, so that self-deleting menus don't crash if they are getting accessed after being closed. auto res = M_DoResponder(ev); for (auto p : toDelete) delete p; toDelete.Clear(); @@ -827,6 +827,7 @@ void M_Ticker (void) { D_ProcessEvents(); // The main loop is blocked when the menu is open and cannot dispatch the events. if (transition.previous) transition.previous->Ticker(); + if (DMenu::CurrentMenu == nullptr) return; // In case one of the sub-screens has closed the menu. DMenu::CurrentMenu->Ticker(); for (int i = 0; i < NUM_MKEYS; ++i) diff --git a/source/common/menu/messagebox.cpp b/source/common/menu/messagebox.cpp index a40343405..5fe3c8248 100644 --- a/source/common/menu/messagebox.cpp +++ b/source/common/menu/messagebox.cpp @@ -407,17 +407,7 @@ CCMD (menu_endgame) { if (res) { - M_ClearMenus(); - /*/ - if (!netgame) - { - if (demorecording) - G_CheckDemoStatus(); - D_StartTitle(); - } - */ - - //gi->ReturnToTitle(); + gi->QuitToTitle(); } }); diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 0167ae340..7b8fc7fd2 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -754,6 +754,15 @@ bool GameInterface::DrawSpecialScreen(const DVector2 &origin, int tilenum) void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position, bool bg) { if (bg) Menu_DrawBackground(origin); + else + { + // Only used for the confirmation screen. + int lines = 1; + for (int i = 0; text[i]; i++) if (text[i] == '\n') lines++; + int height = lines * Menu_GetFontHeight(NIT_SmallFont); + position -= height >> 17; + Menu_DrawCursorLeft(160 << 16, 130 << 16, 65536); + } mgametextcenter(int(origin.X * 65536), int((origin.Y + position) * 65536), text); } @@ -762,6 +771,13 @@ void GameInterface::DrawPlayerSprite(const DVector2& origin, bool onteam) rotatesprite_fs(int(origin.X * 65536) + (260<<16), int(origin.Y*65536) + ((24+(tilesiz[APLAYER].y>>1))<<16), 49152L,0,1441-((((4-((int32_t) totalclock>>4)))&3)*5),0,onteam ? G_GetTeamPalette(playerteam) : G_CheckPlayerColor(playercolor),10); } +void GameInterface::QuitToTitle() +{ + g_player[myconnectindex].ps->gm = MODE_DEMO; + if (ud.recstat == 1) + G_CloseDemoWrite(); + artClearMapArt(); +} END_DUKE_NS //---------------------------------------------------------------------------- diff --git a/source/duke3d/src/duke3d.h b/source/duke3d/src/duke3d.h index baa49d0a6..21e187a22 100644 --- a/source/duke3d/src/duke3d.h +++ b/source/duke3d/src/duke3d.h @@ -170,6 +170,7 @@ struct GameInterface : ::GameInterface bool LoadGame(FSaveGameNode*) override; void DoPrintMessage(int prio, const char*) override; void DrawPlayerSprite(const DVector2& origin, bool onteam) override; + void QuitToTitle() override; }; diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 5e2cec747..990c1e04e 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -6165,6 +6165,11 @@ MAIN_LOOP_RESTART: do //main loop { gameHandleEvents(); + if (myplayer.gm == MODE_DEMO) + { + M_ClearMenus(); + goto MAIN_LOOP_RESTART; + } // only allow binds to function if the player is actually in a game (not in a menu, typing, et cetera) or demo inputState.SetBindsEnabled(!!(myplayer.gm & (MODE_GAME|MODE_DEMO))); diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index 3b2d343da..a57589d3c 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -74,19 +74,6 @@ void Menu_Init(void) - - -static void Menu_DrawVerifyPrompt(int32_t x, int32_t y, const char * text, int numlines = 1) -{ - mgametextcenter(x, y + (90<<16), text); -#ifndef EDUKE32_ANDROID_MENU - char const * inputs = CONTROL_LastSeenInput == LastSeenInput::Joystick - ? "Press (A) to accept, (B) to return." - : "(Y/N)"; - mgametextcenter(x, y + (90<<16) + MF_Bluefont.get_yline() * numlines, inputs); -#endif -} - static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin) { int32_t i, j, l = 0; diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index 2bf67e573..8ca1d5998 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -469,6 +469,14 @@ void GameInterface::DrawMenuCaption(const DVector2& origin, const char* text) void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position, bool bg) { if (bg) Menu_DrawBackground(origin); + else + { + // Only used for the confirmation screen. + int lines = 1; + for (int i = 0; text[i]; i++) if (text[i] == '\n') lines++; + int height = lines * Menu_GetFontHeight(NIT_SmallFont); + position -= height >> 17; + } G_ScreenText(MF_Bluefont.tilenum, int((origin.X + 160) * 65536), int((origin.Y + position) * 65536), MF_Bluefont.zoom, 0, 0, text, 0, MF_Bluefont.pal, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags | TEXT_XCENTER, 0, 0, xdim - 1, ydim - 1); @@ -483,6 +491,13 @@ void GameInterface::DrawPlayerSprite(const DVector2& origin, bool onteam) rotatesprite_fs(int(origin.X * 65536) + (260<<16), int(origin.Y * 65536) + ((24+(tilesiz[APLAYER].y>>1))<<16), 49152L,0,1441-((((4-((int32_t) totalclock>>4)))&3)*5),0,onteam ? G_GetTeamPalette(playerteam) : G_CheckPlayerColor(playercolor),10); } +void GameInterface::QuitToTitle() +{ + g_player[myconnectindex].ps->gm = MODE_DEMO; + if (ud.recstat == 1) + G_CloseDemoWrite(); + artClearMapArt(); +} END_RR_NS diff --git a/source/rr/src/duke3d.h b/source/rr/src/duke3d.h index 4430c56db..d64e30770 100644 --- a/source/rr/src/duke3d.h +++ b/source/rr/src/duke3d.h @@ -170,6 +170,7 @@ struct GameInterface : ::GameInterface bool LoadGame(FSaveGameNode*) override; void DoPrintMessage(int prio, const char* text) override; void DrawPlayerSprite(const DVector2& origin, bool onteam) override; + void QuitToTitle() override; }; END_RR_NS diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 33a5de7d5..633490c9b 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -7598,6 +7598,11 @@ MAIN_LOOP_RESTART: do //main loop { handleevents(); + if (g_player[myconnectindex].ps->gm == MODE_DEMO) + { + M_ClearMenus(); + goto MAIN_LOOP_RESTART; + } Net_GetPackets(); diff --git a/source/sw/src/d_menu.cpp b/source/sw/src/d_menu.cpp index f7f4548b1..c7d0f553d 100644 --- a/source/sw/src/d_menu.cpp +++ b/source/sw/src/d_menu.cpp @@ -266,7 +266,7 @@ void GameInterface::DrawCenteredTextScreen(const DVector2& origin, const char* t for (auto& l : lines) { short lheight = 0; - MNU_MeasureString(text, &width, &lheight); + MNU_MeasureString(l, &width, &lheight); int x = 160 - width / 2; MNU_DrawString(x, y, l, 0, 0); y += height; diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 4f00dda81..2fdea0f10 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -105,7 +105,7 @@ LISTMENU "IngameMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" NativeTextItem "$MNU_HELP", "h", "HelpMenu" - NativeTextItem "$MNU_ENDGAME", "e", "QuitToMenu" + NativeTextItem "$MNU_ENDGAME", "e", "EndgameMenu" NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" } ifgame(Blood) @@ -121,7 +121,7 @@ LISTMENU "IngameMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_HELP", "h", "HelpMenu" NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" - NativeTextItem "$MNU_ENDGAME", "e", "QuitToMenu" + NativeTextItem "$MNU_ENDGAME", "e", "EndgameMenu" NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" } ifgame(ShadowWarrior) From 06d2f9fcf1a8c08f4aa122bee24aaefa27e36886 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 6 Dec 2019 20:31:17 +0100 Subject: [PATCH 131/203] - fixed music names in Blood --- source/blood/src/levels.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blood/src/levels.cpp b/source/blood/src/levels.cpp index 27b094600..a91314575 100644 --- a/source/blood/src/levels.cpp +++ b/source/blood/src/levels.cpp @@ -402,7 +402,8 @@ bool levelTryPlayMusic(int nEpisode, int nLevel, bool bSetLevelSong) snprintf(buffer, BMAX_PATH, "blood%02i.ogg", gEpisodeInfo[nEpisode].at28[nLevel].ate0); else strncpy(buffer, gEpisodeInfo[nEpisode].at28[nLevel].atd0, BMAX_PATH); - bool bReturn = !!sndPlaySong(gEpisodeInfo[nEpisode].at28[nLevel].atd0, buffer, true); + if (!strchr(buffer, '.')) strcat(buffer, ".mid"); + bool bReturn = !!sndPlaySong(gEpisodeInfo[nEpisode].at28[nLevel].at0, buffer, true); if (bReturn || bSetLevelSong) strncpy(gGameOptions.zLevelSong, buffer, BMAX_PATH); else *gGameOptions.zLevelSong = 0; From 7a8208eb2ff78c62d10b27a2ec0a5b13a5b385e2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 6 Dec 2019 23:20:18 +0100 Subject: [PATCH 132/203] - fixed out of bounds memory access. --- source/blood/src/globals.cpp | 1 - source/common/filesystem/filesystem.cpp | 2 +- source/common/searchpaths.cpp | 2 +- source/common/utility/m_argv.h | 12 ++++++------ source/common/utility/tarray.h | 5 ++++- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/source/blood/src/globals.cpp b/source/blood/src/globals.cpp index a9d70643a..bbfd71188 100644 --- a/source/blood/src/globals.cpp +++ b/source/blood/src/globals.cpp @@ -62,7 +62,6 @@ void _consoleSysMsg(const char* pzFormat, ...) { va_list args; va_start(args, pzFormat); vsprintf(buffer, pzFormat, args); - initprintf("%s(%i): %s\n", _module, _line, buffer); OSD_Printf(OSDTEXT_RED "%s(%i): %s\n", _module, _line, buffer); } diff --git a/source/common/filesystem/filesystem.cpp b/source/common/filesystem/filesystem.cpp index 1a508f6d4..86c819f48 100644 --- a/source/common/filesystem/filesystem.cpp +++ b/source/common/filesystem/filesystem.cpp @@ -482,7 +482,7 @@ int FileSystem::Iterate (const char *name, int *lastlump, ELookupMode lookupmode } lump_p = &FileInfo[*lastlump]; - while (lump_p < &FileInfo[NumEntries]) + while (lump_p <= &FileInfo.Last()) { auto lump = lump_p->lump; if (lump->LumpName[lookupindex] == lname) diff --git a/source/common/searchpaths.cpp b/source/common/searchpaths.cpp index e7cc03255..d7ae77a58 100644 --- a/source/common/searchpaths.cpp +++ b/source/common/searchpaths.cpp @@ -1016,7 +1016,7 @@ TArray GrpScan() for (unsigned i = 0; i < foundGames.Size(); i++) { - for (unsigned j = foundGames.Size(); j > i; j--) + for (unsigned j = foundGames.Size() - 1; j > i; j--) { if (foundGames[i].FileInfo.CRC == foundGames[j].FileInfo.CRC) foundGames.Delete(j); diff --git a/source/common/utility/m_argv.h b/source/common/utility/m_argv.h index 2e822dee7..8684b1fd1 100644 --- a/source/common/utility/m_argv.h +++ b/source/common/utility/m_argv.h @@ -50,28 +50,28 @@ public: iterator begin() { - return &Argv[0]; + return Argv.begin(); } const_iterator begin() const { - return &Argv[0]; + return Argv.begin(); } const_iterator cbegin() const { - return &Argv[0]; + return Argv.begin(); } iterator end() { - return &Argv[Argv.Size()]; + return Argv.end(); } const_iterator end() const { - return &Argv[Argv.Size()]; + return Argv.end(); } const_iterator cend() const { - return &Argv[Argv.Size()]; + return Argv.end(); } FArgs(); diff --git a/source/common/utility/tarray.h b/source/common/utility/tarray.h index 77265ece8..2be5f882a 100644 --- a/source/common/utility/tarray.h +++ b/source/common/utility/tarray.h @@ -237,14 +237,17 @@ public: } return true; } - // Return a reference to an element + // Return a reference to an element. + // Note that the asserts must let the element after the end pass because this gets frequently used as a sentinel pointer. T &operator[] (size_t index) const { + assert(index <= Count); return Array[index]; } // Returns the value of an element TT operator() (size_t index) const { + assert(index <= Count); return Array[index]; } // Returns a reference to the last element From 5c7b05a791691efc4df05dac85c4f30bed3fbb8d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 00:07:02 +0100 Subject: [PATCH 133/203] - made THINGINFO const. --- source/blood/src/actor.cpp | 12 ++++++------ source/blood/src/actor.h | 2 +- source/blood/src/aiunicult.cpp | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blood/src/actor.cpp b/source/blood/src/actor.cpp index cf68e2570..1e83a2a4d 100644 --- a/source/blood/src/actor.cpp +++ b/source/blood/src/actor.cpp @@ -1707,7 +1707,7 @@ MissileType missileInfo[] = { } }; -THINGINFO thingInfo[] = { +const THINGINFO thingInfo[] = { //TNT Barrel { 25, @@ -3868,7 +3868,7 @@ void actImpactMissile(spritetype *pMissile, int hitCode) sectortype *pSectorHit = NULL; XSECTOR *pXSectorHit = NULL; actHitcodeToData(hitCode, &gHitInfo, &nSpriteHit, &pSpriteHit, &pXSpriteHit, &nWallHit, &pWallHit, &pXWallHit, &nSectorHit, &pSectorHit, &pXSectorHit); - THINGINFO *pThingInfo = NULL; DUDEINFO *pDudeInfo = NULL; + const THINGINFO *pThingInfo = NULL; DUDEINFO *pDudeInfo = NULL; if (hitCode == 3 && pSpriteHit) { switch (pSpriteHit->statnum) { @@ -4211,7 +4211,7 @@ void ProcessTouchObjects(spritetype *pSprite, int nXSprite) if (pSprite2->statnum == kStatThing) { int nType = pSprite2->type-kThingBase; - THINGINFO *pThingInfo = &thingInfo[nType]; + const THINGINFO *pThingInfo = &thingInfo[nType]; if (pThingInfo->flags&1) pSprite2->flags |= 1; @@ -4546,7 +4546,7 @@ int MoveThing(spritetype *pSprite) int nSprite = pSprite->index; int v8 = 0; dassert(pSprite->type >= kThingBase && pSprite->type < kThingMax); - THINGINFO *pThingInfo = &thingInfo[pSprite->type-kThingBase]; + const THINGINFO *pThingInfo = &thingInfo[pSprite->type-kThingBase]; int nSector = pSprite->sectnum; dassert(nSector >= 0 && nSector < kMaxSectors); int top, bottom; @@ -5829,7 +5829,7 @@ void actProcessSprites(void) if (pXSector && pXSector->panVel && (pXSector->panAlways || pXSector->state || pXSector->busy)) { int nType = pSprite->type - kThingBase; - THINGINFO *pThingInfo = &thingInfo[nType]; + const THINGINFO *pThingInfo = &thingInfo[nType]; if (pThingInfo->flags & 1) pSprite->flags |= 1; @@ -6546,7 +6546,7 @@ spritetype * actSpawnThing(int nSector, int x, int y, int z, int nThingType) pSprite->type = nThingType; dassert(nXThing > 0 && nXThing < kMaxXSprites); XSPRITE *pXThing = &xsprite[nXThing]; - THINGINFO *pThingInfo = &thingInfo[nType]; + const THINGINFO *pThingInfo = &thingInfo[nType]; pXThing->health = pThingInfo->startHealth<<4; pSprite->clipdist = pThingInfo->clipdist; pSprite->flags = pThingInfo->flags; diff --git a/source/blood/src/actor.h b/source/blood/src/actor.h index 42b785ca8..6d7e8de6d 100644 --- a/source/blood/src/actor.h +++ b/source/blood/src/actor.h @@ -186,7 +186,7 @@ extern WEAPONITEMDATA gWeaponItemData[]; extern ITEMDATA gItemData[]; extern MissileType missileInfo[]; extern EXPLOSION explodeInfo[]; -extern THINGINFO thingInfo[]; +extern const THINGINFO thingInfo[]; extern VECTORDATA gVectorData[]; extern int gDudeDrag; diff --git a/source/blood/src/aiunicult.cpp b/source/blood/src/aiunicult.cpp index 73e726a2b..c81d69b17 100644 --- a/source/blood/src/aiunicult.cpp +++ b/source/blood/src/aiunicult.cpp @@ -284,7 +284,7 @@ static void ThrowThing(int nXIndex, bool impact) { if (curWeapon < kThingBase || curWeapon >= kThingMax) return; - THINGINFO* pThinkInfo = &thingInfo[curWeapon - kThingBase]; + const THINGINFO* pThinkInfo = &thingInfo[curWeapon - kThingBase]; if (!pThinkInfo->allowThrow) return; if (!playGenDudeSound(pSprite, kGenDudeSndAttackThrow)) From 7d7507d4532aa92ae9a8aad8c415b471d9d0a6b4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 00:57:45 +0100 Subject: [PATCH 134/203] - always add movie and music subdirectories. --- source/blood/src/blood.cpp | 2 +- source/common/filesystem/file_directory.cpp | 6 ++++-- source/common/initfs.cpp | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index b7f692460..4be3d78cf 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -375,7 +375,7 @@ static void PrecacheSounds(void) if (pNode->ResType() == NAME_RAW || pNode->ResType() == NAME_SFX) { pNode->Get(); - if ((i&15) == 15) gameHandleEvents(); // don't do this too often. That made sense in 1996 but not in 2019 + //if ((i&15) == 15) gameHandleEvents(); // don't do this too often. That made sense in 1996 but not in 2019 } } } diff --git a/source/common/filesystem/file_directory.cpp b/source/common/filesystem/file_directory.cpp index bbc6d23f5..30686bf77 100644 --- a/source/common/filesystem/file_directory.cpp +++ b/source/common/filesystem/file_directory.cpp @@ -149,8 +149,10 @@ int FDirectory::AddDirectory(const char *dirpath) (fi[1] == '\0' || (fi[1] == '.' && fi[2] == '\0')))) { - // Skip if requested and do not record . and .. directories. - continue; + // Movie and music subdirectories must always pass. + if (fi.CompareNoCase("movie") && fi.CompareNoCase("music")) + // Skip if requested and do not record . and .. directories. + continue; } FString newdir = dirpath; newdir << fi << '/'; diff --git a/source/common/initfs.cpp b/source/common/initfs.cpp index cb9bda281..762825867 100644 --- a/source/common/initfs.cpp +++ b/source/common/initfs.cpp @@ -129,7 +129,7 @@ bool D_AddFile (TArray &wadfiles, const char *file, bool check = true, if (check && !DirEntryExists (file)) { - const char *f = BaseFileSearch (file, ".wad", false); + const char *f = BaseFileSearch (file, ".grp", false); if (f == NULL) { Printf ("Can't find '%s'\n", file); From ddfb2223dba16a6b4389eb15a7e5f7a028103dc8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 09:44:43 +0100 Subject: [PATCH 135/203] - added a directory list function to the file system. - fixed lookup for resources by ID - it always picked the first candidate from the hash chain without checking the actual ID. --- source/common/filesystem/filesystem.cpp | 38 ++++++++++--------------- source/common/filesystem/filesystem.h | 1 + 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/source/common/filesystem/filesystem.cpp b/source/common/filesystem/filesystem.cpp index 86c819f48..05f022ad4 100644 --- a/source/common/filesystem/filesystem.cpp +++ b/source/common/filesystem/filesystem.cpp @@ -48,6 +48,7 @@ #include "filesystem.h" #include "resourcefile.h" #include "v_text.h" +#include "c_dispatch.h" //#include "md5.h" //#include "doomstat.h" @@ -322,6 +323,7 @@ int FileSystem::FindResource (int resid, const char *type, int filenum) const no for (i = fli[int(resid) % NumEntries]; i != NULL_INDEX; i = nli[i]) { if (filenum > 0 && FileInfo[i].rfnum != filenum) continue; + if (FileInfo[i].lump->ResourceId != resid) continue; auto lump = FileInfo[i].lump; if (lump->LumpName[lookuptype] == lname) return i; } @@ -1064,28 +1066,18 @@ static void PrintLastError () } #endif -#if 0 -void FileSystem::HashDump() +CCMD(printfs) { - FILE* f = fopen("fs_hash.txt", "wb"); - for (int list = 0; list < 5; list++) - { - fprintf(f, "List %d\n------------\n", list); - auto fli = FirstFileIndex[list]; - auto nli = NextFileIndex[list]; - for (int hash = 0; hash < NumEntries; hash++) - { - if (fli[hash] != NULL_INDEX) - { - fprintf(f, "\tHash %d\n", hash); - for (uint32_t i = fli[hash]; i != NULL_INDEX; i = nli[i]) - { - auto lump = FileInfo[i].lump; - fprintf(f, "\t\t%s (%d)\t%d, %d\n", lump->LumpName[list].GetChars(), lump->LumpName[list].GetIndex(), lump->Size(), i); - } - } - } - } - fclose(f); + fileSystem.PrintDirectory(); +} + +void FileSystem::PrintDirectory() +{ + for (int i = 0; i < NumEntries; i++) + { + auto lump = FileInfo[i].lump; + auto f = GetFileContainer(i); + auto n = GetResourceFileFullName(f); + Printf("%5d: %9d %64s %4s %3d %s\n", i, lump->LumpSize, lump->LumpName[0].GetChars(), lump->LumpName[4].GetChars(), lump->ResourceId, n); + } } -#endif \ No newline at end of file diff --git a/source/common/filesystem/filesystem.h b/source/common/filesystem/filesystem.h index cf3b6b307..03d406728 100644 --- a/source/common/filesystem/filesystem.h +++ b/source/common/filesystem/filesystem.h @@ -148,6 +148,7 @@ public: { return FileInfo[lump].lump; } + void PrintDirectory(); protected: From ef87d2d4f9fee6b58afa0a5cc55237ec669bd0ad Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 10:01:03 +0100 Subject: [PATCH 136/203] - always pause the game when the console is open. --- source/common/menu/menu.cpp | 2 +- source/sw/src/game.cpp | 6 ------ source/sw/src/player.cpp | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 392289f1a..8f6dccb04 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -922,7 +922,7 @@ void Menu_Close(int playerid) bool M_Active() { - return DMenu::CurrentMenu != nullptr; + return DMenu::CurrentMenu != nullptr || ConsoleState == c_down || ConsoleState == c_falling; } //============================================================================= diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index acdde834a..f3336fd9f 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -1999,12 +1999,6 @@ void MenuLevel(void) break; } - // force the use of menus at all time - if (!M_Active() && !ConPanel) - { - inputState.SetKeyStatus(sc_Escape); - } - // must lock the clock for drawing so animations will happen totalclocklock = totalclock; diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index c5f1b63ed..838bf4d3e 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -2478,7 +2478,7 @@ MoveScrollMode2D(PLAYERp pp) } } - if (!M_Active() && !HelpInputMode && !ConPanel) + if (!HelpInputMode && !ConPanel) { if (buttonMap.ButtonDown(gamefunc_Move_Forward)) { From 749eda32c5f3463a45a7f7172e7cf56f2ae314ef Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 10:14:51 +0100 Subject: [PATCH 137/203] - moved kopenfilereader into the FileSystem class. --- source/blood/src/barf.cpp | 2 +- source/blood/src/credits.cpp | 4 ++-- source/blood/src/inifile.cpp | 2 +- source/blood/src/sound.cpp | 2 +- source/blood/src/tile.cpp | 6 +++--- source/build/include/cache1d.h | 9 --------- source/build/src/defs.cpp | 6 +++--- source/build/src/engine.cpp | 6 +++--- source/build/src/mdsprite.cpp | 2 +- source/build/src/palette.cpp | 2 +- source/build/src/scriptfile.cpp | 2 +- source/build/src/voxmodel.cpp | 6 +++--- source/common/filesystem/filesystem.cpp | 7 +++++++ source/common/filesystem/filesystem.h | 1 + source/common/fonts/v_font.cpp | 2 +- source/common/openaudio.cpp | 6 +++--- source/common/rts.cpp | 2 +- source/common/textures/buildtiles.cpp | 4 ++-- source/common/textures/formats/arttexture.cpp | 4 ++-- source/common/textures/formats/ddstexture.cpp | 4 ++-- source/common/textures/formats/jpegtexture.cpp | 4 ++-- source/common/textures/formats/pcxtexture.cpp | 4 ++-- source/common/textures/formats/pngtexture.cpp | 4 ++-- source/common/textures/formats/stbtexture.cpp | 2 +- source/common/textures/formats/tgatexture.cpp | 4 ++-- source/common/textures/image.cpp | 2 +- source/common/utility/sc_man.cpp | 2 +- source/duke3d/src/anim.cpp | 6 +++--- source/duke3d/src/common.cpp | 2 +- source/duke3d/src/gamedef.cpp | 4 ++-- source/glbackend/glbackend.cpp | 2 +- source/libsmackerdec/src/FileStream.cpp | 2 +- source/rr/src/anim.cpp | 6 +++--- source/rr/src/common.cpp | 2 +- source/rr/src/gamedef.cpp | 4 ++-- source/sw/src/anim.cpp | 2 +- source/sw/src/demo.h | 2 +- source/sw/src/scrip2.cpp | 2 +- source/sw/src/sounds.cpp | 6 +++--- 39 files changed, 70 insertions(+), 71 deletions(-) diff --git a/source/blood/src/barf.cpp b/source/blood/src/barf.cpp index 839f59766..84cfbd697 100644 --- a/source/blood/src/barf.cpp +++ b/source/blood/src/barf.cpp @@ -166,7 +166,7 @@ int RFS::Open(const char *fileName) { strcpy(_fileName, fileName); - auto hFile = kopenFileReader(fileName, 0); + auto hFile = fileSystem.OpenFileReader(fileName, 0); if (!hFile.isOpen()) { initprintf("BARF: Error opening file %s", _fileName); return 1; diff --git a/source/blood/src/credits.cpp b/source/blood/src/credits.cpp index bc579f1ce..f6f1dbc23 100644 --- a/source/blood/src/credits.cpp +++ b/source/blood/src/credits.cpp @@ -160,14 +160,14 @@ FileReader credKOpen4Load(char *&pzFile) if (pzFile[i] == '\\') pzFile[i] = '/'; } - auto nHandle = kopenFileReader(pzFile, 0); + auto nHandle = fileSystem.OpenFileReader(pzFile, 0); if (!nHandle.isOpen()) { // Hack if (nLen >= 3 && isalpha(pzFile[0]) && pzFile[1] == ':' && pzFile[2] == '/') { pzFile += 3; - nHandle = kopenFileReader(pzFile, 0); + nHandle = fileSystem.OpenFileReader(pzFile, 0); } } return nHandle; diff --git a/source/blood/src/inifile.cpp b/source/blood/src/inifile.cpp index b9263efe6..78fd149ec 100644 --- a/source/blood/src/inifile.cpp +++ b/source/blood/src/inifile.cpp @@ -130,7 +130,7 @@ void IniFile::Load() curNode = &head; - auto fp = kopenFileReader(fileName, 0); + auto fp = fileSystem.OpenFileReader(fileName, 0); if (fp.isOpen()) { int nSize = fp.GetLength(); diff --git a/source/blood/src/sound.cpp b/source/blood/src/sound.cpp index 235b0e495..dc1f87dcc 100644 --- a/source/blood/src/sound.cpp +++ b/source/blood/src/sound.cpp @@ -216,7 +216,7 @@ void sndStartWavDisk(const char *pzFile, int nVolume, int nChannel) pChannel = &Channel[nChannel]; if (pChannel->at0 > 0) sndKillSound(pChannel); - auto hFile = kopenFileReader(pzFile, 0); + auto hFile = fileSystem.OpenFileReader(pzFile, 0); if (!hFile.isOpen()) return; int nLength = hFile.GetLength(); diff --git a/source/blood/src/tile.cpp b/source/blood/src/tile.cpp index c700fbb76..cfb857af2 100644 --- a/source/blood/src/tile.cpp +++ b/source/blood/src/tile.cpp @@ -86,12 +86,12 @@ int tileInit(char a1, const char *a2) for (int i = 0; i < kMaxTiles; i++) voxelIndex[i] = 0; - auto hFile = kopenFileReader("SURFACE.DAT", 0); + auto hFile = fileSystem.OpenFileReader("SURFACE.DAT", 0); if (hFile.isOpen()) { hFile.Read(surfType, sizeof(surfType)); } - hFile = kopenFileReader("VOXEL.DAT", 0); + hFile = fileSystem.OpenFileReader("VOXEL.DAT", 0); if (hFile.isOpen()) { hFile.Read(voxelIndex, sizeof(voxelIndex)); @@ -100,7 +100,7 @@ int tileInit(char a1, const char *a2) voxelIndex[i] = B_LITTLE16(voxelIndex[i]); #endif } - hFile = kopenFileReader("SHADE.DAT", 0); + hFile = fileSystem.OpenFileReader("SHADE.DAT", 0); if (hFile.isOpen()) { hFile.Read(tileShade, sizeof(tileShade)); diff --git a/source/build/include/cache1d.h b/source/build/include/cache1d.h index 0468fe660..161425025 100644 --- a/source/build/include/cache1d.h +++ b/source/build/include/cache1d.h @@ -18,15 +18,6 @@ extern int32_t pathsearchmode; // 0 = gamefs mode (default), 1 = localfs mode (e #include "filesystem/filesystem.h" -// Wrappers for the handle based API to get rid of the direct calls without any actual changes to the implementation. -// These are now getting redirected to the file system so that the implementation here can be gutted without making changes to the calling code. -inline FileReader kopenFileReader(const char* name, int where) -{ - auto lump = fileSystem.FindFile(name); - if (lump < 0) return FileReader(); - else return fileSystem.OpenFileReader(lump); -} - // This is only here to mark a file as not being part of the game assets (e.g. savegames) // These should be handled differently (e.g read from a userdata directory or similar things.) inline FileReader fopenFileReader(const char* name, int where) diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index 872e2c299..7495fd5fd 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -2596,7 +2596,7 @@ static int32_t defsparser(scriptfile *script) break; } - FileReader fil = kopenFileReader(fn, 0); + FileReader fil = fileSystem.OpenFileReader(fn, 0); if (!fil.isOpen()) { initprintf("Error: basepalette: Failed opening \"%s\" on line %s:%d\n", fn, @@ -2770,7 +2770,7 @@ static int32_t defsparser(scriptfile *script) break; } - FileReader fil = kopenFileReader(fn, 0); + FileReader fil = fileSystem.OpenFileReader(fn, 0); if (!fil.isOpen()) { initprintf("Error: palookup: Failed opening \"%s\" on line %s:%d\n", fn, @@ -3063,7 +3063,7 @@ static int32_t defsparser(scriptfile *script) break; } - FileReader fil = kopenFileReader(fn, 0); + FileReader fil = fileSystem.OpenFileReader(fn, 0); if (!fil.isOpen()) { initprintf("Error: blendtable: Failed opening \"%s\" on line %s:%d\n", fn, diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 07f048c70..08d8cc25e 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -9447,7 +9447,7 @@ int32_t engineLoadBoard(const char *filename, char flags, vec3_t *dapos, int16_t flags &= 3; - FileReader fr = kopenFileReader(filename, 0); + FileReader fr = fileSystem.OpenFileReader(filename, 0); if (!fr.isOpen()) { mapversion = 7; return -1; } @@ -9639,7 +9639,7 @@ int32_t engineLoadBoardV5V6(const char *filename, char fromwhere, vec3_t *dapos, struct walltypev6 v6wall; struct spritetypev6 v6spr; - FileReader fr = kopenFileReader(filename, fromwhere); + FileReader fr = fileSystem.OpenFileReader(filename, fromwhere); if (!fr.isOpen()) { mapversion = 5L; return -1; } @@ -10109,7 +10109,7 @@ void videoNextPage(void) int32_t qloadkvx(int32_t voxindex, const char *filename) { - auto fil = kopenFileReader(filename, 0); + auto fil = fileSystem.OpenFileReader(filename, 0); if (!fil.isOpen()) return -1; diff --git a/source/build/src/mdsprite.cpp b/source/build/src/mdsprite.cpp index 5fd32bd5d..a7d1191e0 100644 --- a/source/build/src/mdsprite.cpp +++ b/source/build/src/mdsprite.cpp @@ -1862,7 +1862,7 @@ mdmodel_t *mdload(const char *filnam) vm = (mdmodel_t *)voxload(filnam); if (vm) return vm; - auto fil = kopenFileReader(filnam,0); + auto fil = fileSystem.OpenFileReader(filnam,0); if (!fil.isOpen()) return NULL; diff --git a/source/build/src/palette.cpp b/source/build/src/palette.cpp index bc0c09090..cf4c07e0e 100644 --- a/source/build/src/palette.cpp +++ b/source/build/src/palette.cpp @@ -179,7 +179,7 @@ void paletteLoadFromDisk(void) return; } - auto fil = kopenFileReader("palette.dat", 0); + auto fil = fileSystem.OpenFileReader("palette.dat", 0); if (!fil.isOpen()) return; diff --git a/source/build/src/scriptfile.cpp b/source/build/src/scriptfile.cpp index dd1fa5f88..5b7e02475 100644 --- a/source/build/src/scriptfile.cpp +++ b/source/build/src/scriptfile.cpp @@ -299,7 +299,7 @@ void scriptfile_preparse(scriptfile *sf, char *tx, int32_t flen) scriptfile *scriptfile_fromfile(const char *fn) { - auto fr = kopenFileReader(fn, 0); + auto fr = fileSystem.OpenFileReader(fn, 0); if (!fr.isOpen()) return nullptr; uint32_t flen = fr.GetLength(); diff --git a/source/build/src/voxmodel.cpp b/source/build/src/voxmodel.cpp index 7bb7f7650..112f1d1c8 100644 --- a/source/build/src/voxmodel.cpp +++ b/source/build/src/voxmodel.cpp @@ -607,7 +607,7 @@ static void read_pal(FileReader &fil, int32_t pal[256]) static int32_t loadvox(const char *filnam) { - auto fil = kopenFileReader(filnam, 0); + auto fil = fileSystem.OpenFileReader(filnam, 0); if (!fil.isOpen()) return -1; @@ -683,7 +683,7 @@ static int32_t loadkvx(const char *filnam) { int32_t i, mip1leng; - auto fil = kopenFileReader(filnam, 0); + auto fil = fileSystem.OpenFileReader(filnam, 0); if (!fil.isOpen()) return -1; @@ -767,7 +767,7 @@ static int32_t loadkv6(const char *filnam) { int32_t i; - auto fil = kopenFileReader(filnam, 0); + auto fil = fileSystem.OpenFileReader(filnam, 0); if (!fil.isOpen()) return -1; diff --git a/source/common/filesystem/filesystem.cpp b/source/common/filesystem/filesystem.cpp index 05f022ad4..b7bbee4e1 100644 --- a/source/common/filesystem/filesystem.cpp +++ b/source/common/filesystem/filesystem.cpp @@ -770,6 +770,13 @@ FileReader FileSystem::ReopenFileReader(int lump, bool alwayscache) return rl->NewReader(); // This always gets a reader to the cache } +FileReader FileSystem::OpenFileReader(const char* name, int where) +{ + auto lump = FindFile(name); + if (lump < 0) return FileReader(); + else return OpenFileReader(lump); +} + //========================================================================== // // GetAllFilesOfType diff --git a/source/common/filesystem/filesystem.h b/source/common/filesystem/filesystem.h index 03d406728..9bce7a0be 100644 --- a/source/common/filesystem/filesystem.h +++ b/source/common/filesystem/filesystem.h @@ -127,6 +127,7 @@ public: FileReader OpenFileReader(int file); // opens a reader that redirects to the containing file's one. FileReader ReopenFileReader(int file, bool alwayscache = false); // opens an independent reader. + FileReader OpenFileReader(const char* name, int where); int Iterate (const char *name, int *lastfile, ELookupMode lookupmode = ELookupMode::FullName); // [RH] Find files with duplication diff --git a/source/common/fonts/v_font.cpp b/source/common/fonts/v_font.cpp index 0a1334513..a11beba66 100644 --- a/source/common/fonts/v_font.cpp +++ b/source/common/fonts/v_font.cpp @@ -93,7 +93,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) FFont *font = FFont::FindFont (name); if (font == nullptr) { - auto lumpy = kopenFileReader(fontlumpname, 0); + auto lumpy = fileSystem.OpenFileReader(fontlumpname, 0); if (!lumpy.isOpen()) return nullptr; uint32_t head; lumpy.Read (&head, 4); diff --git a/source/common/openaudio.cpp b/source/common/openaudio.cpp index f57869096..423a17525 100644 --- a/source/common/openaudio.cpp +++ b/source/common/openaudio.cpp @@ -13,7 +13,7 @@ static FileReader S_TryFormats(char * const testfn, char * const fn_suffix, char #ifdef HAVE_FLAC { Bstrcpy(fn_suffix, ".flac"); - auto fp = kopenFileReader(testfn, searchfirst); + auto fp = fileSystem.OpenFileReader(testfn, searchfirst); if (fp.isOpen()) return fp; } @@ -22,7 +22,7 @@ static FileReader S_TryFormats(char * const testfn, char * const fn_suffix, char #ifdef HAVE_VORBIS { Bstrcpy(fn_suffix, ".ogg"); - auto fp = kopenFileReader(testfn, searchfirst); + auto fp = fileSystem.OpenFileReader(testfn, searchfirst); if (fp.isOpen()) return fp; } @@ -64,7 +64,7 @@ static FileReader S_TryExtensionReplacements(char * const testfn, char const sea FileReader S_OpenAudio(const char *fn, char searchfirst, uint8_t const ismusic) { - auto origfp = kopenFileReader(fn, searchfirst); + auto origfp = fileSystem.OpenFileReader(fn, searchfirst); if (!snd_tryformats) return origfp; return origfp; #if 0 // this needs to be redone diff --git a/source/common/rts.cpp b/source/common/rts.cpp index f0cb6a9f1..526826520 100644 --- a/source/common/rts.cpp +++ b/source/common/rts.cpp @@ -80,7 +80,7 @@ bool RTS_IsInitialized() { if (LumpInfo.Size() > 0) return true; if (RTSName.IsEmpty()) return false; - auto fr = kopenFileReader(RTSName, 0); + auto fr = fileSystem.OpenFileReader(RTSName, 0); RTSName = ""; // don't try ever again. if (!fr.isOpen()) return false; RTSFile = fr.Read(); diff --git a/source/common/textures/buildtiles.cpp b/source/common/textures/buildtiles.cpp index af0bb7f3e..bd21fafe7 100644 --- a/source/common/textures/buildtiles.cpp +++ b/source/common/textures/buildtiles.cpp @@ -287,7 +287,7 @@ int BuildTiles::LoadArtFile(const char *fn, bool mapart, int firsttile) auto old = FindFile(fn); if (old >= ArtFiles.Size()) // Do not process if already loaded. { - FileReader fr = kopenFileReader(fn, 0); + FileReader fr = fileSystem.OpenFileReader(fn, 0); if (fr.isOpen()) { auto artdata = fr.Read(); @@ -565,7 +565,7 @@ void artSetupMapArt(const char* filename) artClearMapArt(); FStringf firstname("%s_00.art", filename); - auto fr = kopenFileReader(firstname, 0); + auto fr = fileSystem.OpenFileReader(firstname, 0); if (!fr.isOpen()) return; for (bssize_t i = 0; i < MAXARTFILES_TOTAL - MAXARTFILES_BASE; i++) diff --git a/source/common/textures/formats/arttexture.cpp b/source/common/textures/formats/arttexture.cpp index 2f0d75ab7..b5c1157fd 100644 --- a/source/common/textures/formats/arttexture.cpp +++ b/source/common/textures/formats/arttexture.cpp @@ -118,7 +118,7 @@ FArtTexture::FArtTexture(int width, int height, int p) void FArtTexture::CreatePalettedPixels(uint8_t* buffer) { - FileReader fr = kopenFileReader(Name, 0); + FileReader fr = fileSystem.OpenFileReader(Name, 0); if (!fr.isOpen()) return; int numpixels = Width * Height; fr.Read(buffer, numpixels); @@ -139,7 +139,7 @@ int FArtTexture::CopyPixels(FBitmap *bmp, int conversion) // Both Src and Dst are ordered the same with no padding. int numpixels = Width * Height; bool hasalpha = false; - FileReader fr = kopenFileReader(Name, 0); + FileReader fr = fileSystem.OpenFileReader(Name, 0); if (!fr.isOpen()) return 0; TArray source(numpixels, true); fr.Read(source.Data(), numpixels); diff --git a/source/common/textures/formats/ddstexture.cpp b/source/common/textures/formats/ddstexture.cpp index f8160ba94..2d8a581b1 100644 --- a/source/common/textures/formats/ddstexture.cpp +++ b/source/common/textures/formats/ddstexture.cpp @@ -374,7 +374,7 @@ void FDDSTexture::CalcBitShift (uint32_t mask, uint8_t *lshiftp, uint8_t *rshift void FDDSTexture::CreatePalettedPixels(uint8_t *buffer) { - auto lump = kopenFileReader(Name, 0); + auto lump = fileSystem.OpenFileReader(Name, 0); if (!lump.isOpen()) return; // Just leave the texture blank. lump.Seek (sizeof(DDSURFACEDESC2) + 4, FileReader::SeekSet); @@ -781,7 +781,7 @@ void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t int FDDSTexture::CopyPixels(FBitmap *bmp, int conversion) { - auto lump = kopenFileReader(Name, 0); + auto lump = fileSystem.OpenFileReader(Name, 0); if (!lump.isOpen()) return -1; // Just leave the texture blank. uint8_t *TexBuffer = bmp->GetPixels(); diff --git a/source/common/textures/formats/jpegtexture.cpp b/source/common/textures/formats/jpegtexture.cpp index 19404fd79..1adaaeebf 100644 --- a/source/common/textures/formats/jpegtexture.cpp +++ b/source/common/textures/formats/jpegtexture.cpp @@ -262,7 +262,7 @@ FJPEGTexture::FJPEGTexture (int width, int height) void FJPEGTexture::CreatePalettedPixels(uint8_t *buffer) { - auto lump = kopenFileReader(Name, 0); + auto lump = fileSystem.OpenFileReader(Name, 0); if (!lump.isOpen()) return; // Just leave the texture blank. JSAMPLE *buff = NULL; @@ -385,7 +385,7 @@ int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion) { PalEntry pe[256]; - auto lump = kopenFileReader(Name, 0); + auto lump = fileSystem.OpenFileReader(Name, 0); if (!lump.isOpen()) return -1; // Just leave the texture blank. jpeg_decompress_struct cinfo; diff --git a/source/common/textures/formats/pcxtexture.cpp b/source/common/textures/formats/pcxtexture.cpp index 807c1560f..69110bf0d 100644 --- a/source/common/textures/formats/pcxtexture.cpp +++ b/source/common/textures/formats/pcxtexture.cpp @@ -350,7 +350,7 @@ void FPCXTexture::CreatePalettedPixels(uint8_t *buffer) PCXHeader header; int bitcount; - auto lump = kopenFileReader(Name, 0); + auto lump = fileSystem.OpenFileReader(Name, 0); if (!lump.isOpen()) return; // Just leave the texture blank. lump.Read(&header, sizeof(header)); @@ -436,7 +436,7 @@ int FPCXTexture::CopyPixels(FBitmap *bmp, int conversion) int bitcount; TArray Pixels; - auto lump = kopenFileReader(Name, 0); + auto lump = fileSystem.OpenFileReader(Name, 0); if (!lump.isOpen()) return -1; // Just leave the texture blank. lump.Read(&header, sizeof(header)); diff --git a/source/common/textures/formats/pngtexture.cpp b/source/common/textures/formats/pngtexture.cpp index 21660c8d9..30dabba12 100644 --- a/source/common/textures/formats/pngtexture.cpp +++ b/source/common/textures/formats/pngtexture.cpp @@ -291,7 +291,7 @@ void FPNGTexture::CreatePalettedPixels(uint8_t *buffer) FileReader *lump; FileReader lfr; - lfr = kopenFileReader(Name, 0); + lfr = fileSystem.OpenFileReader(Name, 0); if (!lfr.isOpen()) return; lump = 𝔩 @@ -408,7 +408,7 @@ int FPNGTexture::CopyPixels(FBitmap *bmp, int conversion) FileReader *lump; FileReader lfr; - lfr = kopenFileReader(Name, 0); + lfr = fileSystem.OpenFileReader(Name, 0); if (!lfr.isOpen()) return -1; // Just leave the texture blank. lump = 𝔩 diff --git a/source/common/textures/formats/stbtexture.cpp b/source/common/textures/formats/stbtexture.cpp index e0dd82f63..78d6857fb 100644 --- a/source/common/textures/formats/stbtexture.cpp +++ b/source/common/textures/formats/stbtexture.cpp @@ -154,7 +154,7 @@ void FStbTexture::CreatePalettedPixels(uint8_t *buffer) int FStbTexture::CopyPixels(FBitmap *bmp, int conversion) { - auto lump = kopenFileReader(Name, 0); + auto lump = fileSystem.OpenFileReader(Name, 0); if (!lump.isOpen()) return -1; // Just leave the texture blank. int x, y, chan; auto image = stbi_load_from_callbacks(&callbacks, &lump, &x, &y, &chan, STBI_rgb_alpha); diff --git a/source/common/textures/formats/tgatexture.cpp b/source/common/textures/formats/tgatexture.cpp index 6a8596e72..323ad165f 100644 --- a/source/common/textures/formats/tgatexture.cpp +++ b/source/common/textures/formats/tgatexture.cpp @@ -179,7 +179,7 @@ void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytespe void FTGATexture::CreatePalettedPixels(uint8_t *buffer) { uint8_t PaletteMap[256]; - auto lump = kopenFileReader(Name, 0); + auto lump = fileSystem.OpenFileReader(Name, 0); if (!lump.isOpen()) return; TGAHeader hdr; uint16_t w; @@ -385,7 +385,7 @@ void FTGATexture::CreatePalettedPixels(uint8_t *buffer) int FTGATexture::CopyPixels(FBitmap *bmp, int conversion) { PalEntry pe[256]; - auto lump = kopenFileReader(Name, 0); + auto lump = fileSystem.OpenFileReader(Name, 0); if (!lump.isOpen()) return -1; TGAHeader hdr; uint16_t w; diff --git a/source/common/textures/image.cpp b/source/common/textures/image.cpp index 5fd7759e7..0e1154ba7 100644 --- a/source/common/textures/image.cpp +++ b/source/common/textures/image.cpp @@ -79,7 +79,7 @@ FImageSource * FImageSource::GetImage(const char *name) { nullptr } }; - auto data = kopenFileReader(name, 0); + auto data = fileSystem.OpenFileReader(name, 0); if (!data.isOpen()) return nullptr; for (size_t i = 0; CreateInfo[i].TryCreate; i++) diff --git a/source/common/utility/sc_man.cpp b/source/common/utility/sc_man.cpp index 0f09f1a36..8e848fa64 100644 --- a/source/common/utility/sc_man.cpp +++ b/source/common/utility/sc_man.cpp @@ -143,7 +143,7 @@ FScanner &FScanner::operator=(const FScanner &other) void FScanner::Open (const char *name) { - auto fr = kopenFileReader(name, 0); + auto fr = fileSystem.OpenFileReader(name, 0); if (!fr.isOpen()) { I_Error("Could not find script lump '%s'\n", name); diff --git a/source/duke3d/src/anim.cpp b/source/duke3d/src/anim.cpp index a0a0e2e02..3af7e8d8d 100644 --- a/source/duke3d/src/anim.cpp +++ b/source/duke3d/src/anim.cpp @@ -253,7 +253,7 @@ int32_t Anim_Play(const char *fn) FileReader handle; if (!Bstrcmp(dot, ".ivf")) { - handle = kopenFileReader(fn, 0); + handle = fileSystem.OpenFileReader(fn, 0); if (!handle.isOpen()) break; } @@ -272,7 +272,7 @@ int32_t Anim_Play(const char *fn) vpxfndot[3] = 'f'; vpxfndot[4] = '\0'; - handle = kopenFileReader(vpxfn, 0); + handle = fileSystem.OpenFileReader(vpxfn, 0); if (!handle.isOpen()) break; @@ -420,7 +420,7 @@ int32_t Anim_Play(const char *fn) int32_t ogltexfiltermode = hw_texfilter; #endif TArray buffer; - auto fr = kopenFileReader(fn, 0); + auto fr = fileSystem.OpenFileReader(fn, 0); if (!fr.isOpen()) goto end_anim; diff --git a/source/duke3d/src/common.cpp b/source/duke3d/src/common.cpp index 74f0e56ad..ff6be1845 100644 --- a/source/duke3d/src/common.cpp +++ b/source/duke3d/src/common.cpp @@ -106,7 +106,7 @@ void G_LoadLookups(void) { int32_t j; - auto fr = kopenFileReader("lookup.dat", 0); + auto fr = fileSystem.OpenFileReader("lookup.dat", 0); if (!fr.isOpen()) return; diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index ff5a202a2..a60d046af 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -1908,7 +1908,7 @@ static int C_CountCaseStatements() static void C_Include(const char *confile) { - auto fp = kopenFileReader(confile,0); + auto fp = fileSystem.OpenFileReader(confile,0); if (!fp.isOpen()) { @@ -5922,7 +5922,7 @@ void C_Compile(const char *fileName) Gv_Init(); C_InitProjectiles(); - auto kFile = kopenFileReader(fileName,0); + auto kFile = fileSystem.OpenFileReader(fileName,0); if (!kFile.isOpen()) { diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index 4b222a273..a424567d8 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -49,7 +49,7 @@ extern int ydim; FileReader GetResource(const char* fn) { - auto fr = kopenFileReader(fn, 0); + auto fr = fileSystem.OpenFileReader(fn, 0); if (!fr.isOpen()) { I_Error("Fatal: '%s' not found", fn); diff --git a/source/libsmackerdec/src/FileStream.cpp b/source/libsmackerdec/src/FileStream.cpp index a14428392..cdb1eff0f 100644 --- a/source/libsmackerdec/src/FileStream.cpp +++ b/source/libsmackerdec/src/FileStream.cpp @@ -25,7 +25,7 @@ namespace SmackerCommon { bool FileStream::Open(const std::string &fileName) { - file = kopenFileReader(fileName.c_str(), 0); + file = fileSystem.OpenFileReader(fileName.c_str(), 0); if (!file.isOpen()) { // log error diff --git a/source/rr/src/anim.cpp b/source/rr/src/anim.cpp index 2eb9b20eb..9496492cb 100644 --- a/source/rr/src/anim.cpp +++ b/source/rr/src/anim.cpp @@ -289,7 +289,7 @@ int32_t Anim_Play(const char *fn) FileReader handle; if (!Bstrcmp(dot, ".ivf")) { - handle = kopenFileReader(fn, 0); + handle = fileSystem.OpenFileReader(fn, 0); if (!handle.isOpen()) break; } @@ -308,7 +308,7 @@ int32_t Anim_Play(const char *fn) vpxfndot[3] = 'f'; vpxfndot[4] = '\0'; - handle = kopenFileReader(vpxfn, 0); + handle = fileSystem.OpenFileReader(vpxfn, 0); if (!handle.isOpen()) break; @@ -451,7 +451,7 @@ int32_t Anim_Play(const char *fn) #ifdef USE_OPENGL int32_t ogltexfiltermode = hw_texfilter; #endif - auto fr = kopenFileReader(fn, 0); + auto fr = fileSystem.OpenFileReader(fn, 0); if (!fr.isOpen()) return 0; diff --git a/source/rr/src/common.cpp b/source/rr/src/common.cpp index 67af9e974..4ad9d1f6c 100644 --- a/source/rr/src/common.cpp +++ b/source/rr/src/common.cpp @@ -105,7 +105,7 @@ void G_LoadLookups(void) { int32_t j; - auto fr = kopenFileReader("lookup.dat", 0); + auto fr = fileSystem.OpenFileReader("lookup.dat", 0); if (!fr.isOpen()) return; diff --git a/source/rr/src/gamedef.cpp b/source/rr/src/gamedef.cpp index 15352437a..6941e90a9 100644 --- a/source/rr/src/gamedef.cpp +++ b/source/rr/src/gamedef.cpp @@ -780,7 +780,7 @@ static int32_t C_CheckEmptyBranch(int32_t tw, intptr_t lastScriptPtr) static void C_Include(const char *confile) { - auto fp = kopenFileReader(confile,0); + auto fp = fileSystem.OpenFileReader(confile,0); if (!fp.isOpen()) { @@ -2220,7 +2220,7 @@ void C_Compile(const char *fileName) C_InitHashes(); - auto kFile = kopenFileReader(fileName,0); + auto kFile = fileSystem.OpenFileReader(fileName,0); if (!kFile.isOpen()) { diff --git a/source/sw/src/anim.cpp b/source/sw/src/anim.cpp index aec81d051..f602fc08c 100644 --- a/source/sw/src/anim.cpp +++ b/source/sw/src/anim.cpp @@ -243,7 +243,7 @@ unsigned char *LoadAnm(short anim_num) if (anm_ptr[anim_num] == 0) { - auto handle = kopenFileReader(ANIMname[ANIMnum], 0); + auto handle = fileSystem.OpenFileReader(ANIMname[ANIMnum], 0); if (!handle.isOpen()) return NULL; length = handle.GetLength(); diff --git a/source/sw/src/demo.h b/source/sw/src/demo.h index 0be471f6a..e0324923f 100644 --- a/source/sw/src/demo.h +++ b/source/sw/src/demo.h @@ -55,7 +55,7 @@ extern int DemoRecCnt; // Can only record 1-player game #if DEMO_FILE_TYPE == DEMO_FILE_GROUP typedef FileReader DFILE; #define DREAD(ptr, size, num, handle) (handle).Read((ptr),(size)*(num)) -#define DOPEN_READ(name) kopenFileReader(name,0) +#define DOPEN_READ(name) fileSystem.OpenFileReader(name,0) #define DCLOSE(handle) ((handle).Close()) #define DF_ERR(f) (!(f).isOpen()) #else diff --git a/source/sw/src/scrip2.cpp b/source/sw/src/scrip2.cpp index 10a95f557..ba19d1e30 100644 --- a/source/sw/src/scrip2.cpp +++ b/source/sw/src/scrip2.cpp @@ -81,7 +81,7 @@ SWBOOL LoadScriptFile(const char *filename) - if (!(fp = kopenFileReader(filename, 0)).isOpen()) + if (!(fp = fileSystem.OpenFileReader(filename, 0)).isOpen()) { // If there's no script file, forget it. return FALSE; diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp index a8c1fb861..b668bd075 100644 --- a/source/sw/src/sounds.cpp +++ b/source/sw/src/sounds.cpp @@ -1055,7 +1055,7 @@ void PlaySoundRTS(int rts_num) SWBOOL OpenSound(VOC_INFOp vp, FileReader &handle, int *length) { - handle = kopenFileReader(vp->name, 0); + handle = fileSystem.OpenFileReader(vp->name, 0); if (!handle.isOpen()) { @@ -1085,7 +1085,7 @@ ReadSound(FileReader &handle, VOC_INFOp vp, int length) SWBOOL LoadSong(const char *filename) { - auto fr = kopenFileReader(filename, 0); + auto fr = fileSystem.OpenFileReader(filename, 0); if (!fr.isOpen()) { return FALSE; @@ -1170,7 +1170,7 @@ SoundShutdown(void) void MusicStartup(void) { #if 0 - auto fil = kopenFileReader("swtimbr.tmb", 0); + auto fil = fileSystem.OpenFileReader("swtimbr.tmb", 0); if (fil.isOpen()) { From 30cbcb54b104a9937faf5ee31d6eae7225d79e8a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 10:31:27 +0100 Subject: [PATCH 138/203] - renamed the remaining file system access wrappers in cache1d.h --- source/blood/src/blood.cpp | 4 ++-- source/blood/src/d_menu.cpp | 2 +- source/blood/src/levels.cpp | 2 +- source/build/include/cache1d.h | 26 -------------------------- source/build/src/defs.cpp | 16 ++++++++-------- source/common/filesystem/filesystem.h | 22 ++++++++++++++++++++++ source/common/fonts/singlelumpfont.cpp | 2 +- source/duke3d/src/game.cpp | 12 ++++++------ source/duke3d/src/network.cpp | 2 +- source/duke3d/src/osdcmds.cpp | 2 +- source/duke3d/src/premap.cpp | 2 +- source/duke3d/src/screens.cpp | 2 +- source/glbackend/glbackend.cpp | 4 ++-- source/rr/src/game.cpp | 12 ++++++------ source/rr/src/net.cpp | 4 ++-- source/rr/src/osdcmds.cpp | 2 +- source/rr/src/premap.cpp | 2 +- source/rr/src/screens.cpp | 2 +- source/sw/src/anim.cpp | 10 +++------- source/sw/src/anim.h | 2 +- source/sw/src/game.cpp | 23 +++-------------------- 21 files changed, 65 insertions(+), 90 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 4be3d78cf..675b9003d 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -1685,7 +1685,7 @@ static int parsedefinitions_game(scriptfile *pScript, int firstPass) break; } - if (fileName == NULL || check_file_exist(fileName)) + if (fileName == NULL || fileSystem.FileExists(fileName)) break; if (S_DefineMusic(musicID, fileName) == -1) @@ -1937,7 +1937,7 @@ static int parsedefinitions_game(scriptfile *pScript, int firstPass) break; } - if (fileName == NULL || check_file_exist(fileName)) + if (fileName == NULL || fileSystem.FileExists(fileName)) break; // maybe I should have just packed this into a sound_t and passed a reference... diff --git a/source/blood/src/d_menu.cpp b/source/blood/src/d_menu.cpp index 3444b1a06..2b81b6317 100644 --- a/source/blood/src/d_menu.cpp +++ b/source/blood/src/d_menu.cpp @@ -69,7 +69,7 @@ CGameMenuItemQAV::CGameMenuItemQAV(int a3, int a4, const char* name, bool widesc if (name) { // NBlood read this directly from the file system cache, but let's better store the data locally for robustness. - raw = kloadfile(name, 0); + raw = fileSystem.LoadFile(name, 0); if (raw.Size() != 0) { auto data = (QAV*)raw.Data(); diff --git a/source/blood/src/levels.cpp b/source/blood/src/levels.cpp index a91314575..f40f9d1fb 100644 --- a/source/blood/src/levels.cpp +++ b/source/blood/src/levels.cpp @@ -70,7 +70,7 @@ IniFile *BloodINI; void levelInitINI(const char *pzIni) { - if (!testkopen(pzIni, 0)) + if (!fileSystem.FileExists(pzIni)) ThrowError("Initialization: %s does not exist", pzIni); BloodINI = new IniFile(pzIni); Bstrncpy(BloodIniFile, pzIni, BMAX_PATH); diff --git a/source/build/include/cache1d.h b/source/build/include/cache1d.h index 161425025..3d7dc8691 100644 --- a/source/build/include/cache1d.h +++ b/source/build/include/cache1d.h @@ -27,31 +27,5 @@ inline FileReader fopenFileReader(const char* name, int where) return fr; } -inline bool testkopen(const char* name, int where) -{ - // todo: if backed by a single file, we must actually open it to make sure. - return fileSystem.FindFile(name) >= 0; -} - -inline TArray kloadfile(const char* name, int where) -{ - auto lump = fileSystem.FindFile(name); - if (lump < 0) return TArray(); - return fileSystem.GetFileData(lump); -} - -inline int32_t kfilesize(const char* name, int where) -{ - auto lump = fileSystem.FindFile(name); - if (lump < 0) return -1; - return fileSystem.FileLength(lump); -} - -// checks from path and in ZIPs, returns 1 if NOT found -inline int32_t check_file_exist(const char* fn) -{ - return fileSystem.FindFile(fn) >= 0; -} - #endif // cache1d_h_ diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index 7495fd5fd..f350dd231 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -355,7 +355,7 @@ static int32_t defsparser(scriptfile *script) if (scriptfile_getnumber(script,&fnoo)) break; //y-size if (scriptfile_getstring(script,&fn)) break; - if (check_file_exist(fn)) + if (fileSystem.FileExists(fn)) break; tileSetHightileReplacement(tile,pal,fn,-1.0,1.0,1.0,1.0,1.0,0); @@ -373,7 +373,7 @@ static int32_t defsparser(scriptfile *script) { if (scriptfile_getstring(script,&fn[i])) break; //grab the 6 faces - if (check_file_exist(fn[i])) + if (fileSystem.FileExists(fn[i])) happy = 0; } if (i < 6 || !happy) break; @@ -1098,7 +1098,7 @@ static int32_t defsparser(scriptfile *script) if (seenframe) { modelskin = ++lastmodelskin; } seenframe = 0; - if (check_file_exist(skinfn)) + if (fileSystem.FileExists(skinfn)) break; #ifdef USE_OPENGL @@ -1473,7 +1473,7 @@ static int32_t defsparser(scriptfile *script) break; } - if (check_file_exist(skinfn)) + if (fileSystem.FileExists(skinfn)) break; #ifdef USE_OPENGL @@ -1791,7 +1791,7 @@ static int32_t defsparser(scriptfile *script) { if (EDUKE32_PREDICT_FALSE(!fn[i])) initprintf("Error: skybox: missing '%s filename' near line %s:%d\n", skyfaces[i], script->filename, scriptfile_getlinum(script,skyboxtokptr)), happy = 0; // FIXME? - if (check_file_exist(fn[i])) + if (fileSystem.FileExists(fn[i])) happy = 0; } if (!happy) break; @@ -1846,7 +1846,7 @@ static int32_t defsparser(scriptfile *script) break; } - if (check_file_exist(fn)) + if (fileSystem.FileExists(fn)) break; } @@ -2101,7 +2101,7 @@ static int32_t defsparser(scriptfile *script) break; } - if (EDUKE32_PREDICT_FALSE(check_file_exist(fn))) + if (EDUKE32_PREDICT_FALSE(fileSystem.FileExists(fn))) break; if (xsiz > 0 && ysiz > 0) @@ -2164,7 +2164,7 @@ static int32_t defsparser(scriptfile *script) break; } - if (EDUKE32_PREDICT_FALSE(check_file_exist(fn))) + if (EDUKE32_PREDICT_FALSE(fileSystem.FileExists(fn))) break; switch (token) diff --git a/source/common/filesystem/filesystem.h b/source/common/filesystem/filesystem.h index 9bce7a0be..028716c44 100644 --- a/source/common/filesystem/filesystem.h +++ b/source/common/filesystem/filesystem.h @@ -95,12 +95,25 @@ public: int FindFile (const char *name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const noexcept; int GetFile (const char *name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const; // Like FindFile, but throws an exception when it cannot find what it looks for. + bool FileExists(const char* name) + { + return FindFile(name) >= 0; + } int FindFile (const FString &name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const noexcept { return FindFile(name.GetChars(), lookupmode, filenum); } int GetFile (const FString &name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const { return GetFile(name.GetChars(), lookupmode, filenum); } + bool FileExists(const FString & name) + { + return FindFile(name) >= 0; + } int FindFile (const std::string &name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const noexcept { return FindFile(name.c_str(), lookupmode, filenum); } int GetFile (const std::string &name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const { return GetFile(name.c_str(), lookupmode, filenum); } + bool FileExists(const std::string& name) + { + return FindFile(name) >= 0; + } + int FindResource (int resid, const char *type, int filenum = -1) const noexcept; int GetResource (int resid, const char *type, int filenum = -1) const; // Like FindFile, but throws an exception when it cannot find what it looks for. @@ -112,6 +125,15 @@ public: TArray GetFileData(int file, int pad = 0); // reads file into a writable buffer and optionally adds some padding at the end. (FileData isn't writable!) FileData ReadFile (int file); FileData ReadFile (const char *name) { return ReadFile (GetFile (name)); } + + inline TArray LoadFile(const char* name, int padding) + { + auto lump = FindFile(name); + if (lump < 0) return TArray(); + return GetFileData(lump, padding); + } + + const void *Lock(int lump); void Unlock(int lump, bool mayfree = false); diff --git a/source/common/fonts/singlelumpfont.cpp b/source/common/fonts/singlelumpfont.cpp index 2d5ce46c7..5b80a01e9 100644 --- a/source/common/fonts/singlelumpfont.cpp +++ b/source/common/fonts/singlelumpfont.cpp @@ -125,7 +125,7 @@ FSingleLumpFont::FSingleLumpFont (const char *name, const char * lump) FontName = name; - rawData = kloadfile(lump, 0); + rawData = fileSystem.LoadFile(lump, 0); auto& data = rawData; if (data[0] == 0xE1 && data[1] == 0xE6 && data[2] == 0xD5 && data[3] == 0x1A) diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 990c1e04e..800b3a152 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -114,14 +114,14 @@ const char *G_DefaultRtsFile(void) return defaultrtsfilename[GAME_WW2GI]; else if (NAPALM) { - if (!testkopen(defaultrtsfilename[GAME_NAPALM],0) && testkopen(defaultrtsfilename[GAME_NAM],0)) + if (!fileSystem.FileExists(defaultrtsfilename[GAME_NAPALM]) && fileSystem.FileExists(defaultrtsfilename[GAME_NAM])) return defaultrtsfilename[GAME_NAM]; // NAM/NAPALM Sharing else return defaultrtsfilename[GAME_NAPALM]; } else if (NAM) { - if (!testkopen(defaultrtsfilename[GAME_NAM],0) && testkopen(defaultrtsfilename[GAME_NAPALM],0)) + if (!fileSystem.FileExists(defaultrtsfilename[GAME_NAM]) && fileSystem.FileExists(defaultrtsfilename[GAME_NAPALM])) return defaultrtsfilename[GAME_NAPALM]; // NAM/NAPALM Sharing else return defaultrtsfilename[GAME_NAM]; @@ -5065,7 +5065,7 @@ static int parsedefinitions_game(scriptfile *pScript, int firstPass) break; } - if (fileName == NULL || check_file_exist(fileName)) + if (fileName == NULL || fileSystem.FileExists(fileName)) break; if (S_DefineMusic(musicID, fileName) == -1) @@ -5213,7 +5213,7 @@ static int parsedefinitions_game(scriptfile *pScript, int firstPass) break; } - if (fileName == NULL || check_file_exist(fileName)) + if (fileName == NULL || fileSystem.FileExists(fileName)) break; // maybe I should have just packed this into a sound_t and passed a reference... @@ -5682,7 +5682,7 @@ static void G_Startup(void) Bcorrectfilename(boardfilename,0); - if (testkopen(boardfilename, 0)) + if (fileSystem.FileExists(boardfilename)) { initprintf("Using level: \"%s\".\n",boardfilename); } @@ -5875,7 +5875,7 @@ int GameInterface::app_main() g_Shareware = 1; else { - if (testkopen("DUKESW.BIN", 1)) // JBF 20030810 + if (fileSystem.FileExists("DUKESW.BIN")) // JBF 20030810 { g_Shareware = 1; } diff --git a/source/duke3d/src/network.cpp b/source/duke3d/src/network.cpp index 2c421971c..5fa854d4e 100644 --- a/source/duke3d/src/network.cpp +++ b/source/duke3d/src/network.cpp @@ -1986,7 +1986,7 @@ static void Net_ReceiveUserMapName(uint8_t *pbuf, int32_t packbufleng) Bcorrectfilename(boardfilename, 0); if (boardfilename[0] != 0) { - if (testkopen(boardfilename, 0)) + if (fileSystem.FileExists(boardfilename)) { Bmemset(boardfilename, 0, sizeof(boardfilename)); Net_SendUserMapName(); diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index 2505b2ca2..3bb926eac 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -124,7 +124,7 @@ static int osdcmd_map(osdcmdptr_t parm) maybe_append_ext(filename, sizeof(filename), parm->parms[0], ".map"); - if (!testkopen(filename,0)) + if (!fileSystem.FileExists(filename)) { OSD_Printf(OSD_ERROR "map: file \"%s\" not found.\n", filename); return OSDCMD_OK; diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index d9ead5965..324bcd1eb 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -1721,7 +1721,7 @@ void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName) { Bmemcpy(p+1, ext, Bstrlen(ext) + 1); - if (testkopen(nameBuf, 0)) + if (fileSystem.FileExists(nameBuf)) { realloc_copy(&g_mapInfo[USERMAPMUSICFAKESLOT].musicfn, nameBuf); return; diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index a21436a1f..844e91cdd 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -1303,7 +1303,7 @@ void gameDisplay3DRScreen() { Net_GetPackets(); - if (testkopen("3dr.ivf", 0) || testkopen("3dr.anm", 0)) + if (fileSystem.FileExists("3dr.ivf") || fileSystem.FileExists("3dr.anm")) { Anim_Play("3dr.anm"); G_FadePalette(0, 0, 0, 252); diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index a424567d8..ecad690b1 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -104,8 +104,8 @@ void GLInstance::Init(int ydim) ImGui_ImplOpenGL3_Init(); if (!ttf.Size()) { - //ttf = kloadfile("demolition/Capsmall_clean.ttf", 0); - ttf = kloadfile("demolition/Roboto-Regular.ttf", 0); + //ttf = fileSystem.LoadFile("demolition/Capsmall_clean.ttf", 0); + ttf = fileSystem.LoadFile("demolition/Roboto-Regular.ttf", 0); } if (ttf.Size()) io.Fonts->AddFontFromMemoryTTF(ttf.Data(), ttf.Size(), std::clamp(ydim / 40, 10, 30)); } diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 633490c9b..bae9eabae 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -109,14 +109,14 @@ const char *G_DefaultRtsFile(void) return defaultrtsfilename[GAME_DUKE]; else if (NAPALM) { - if (!testkopen(defaultrtsfilename[GAME_NAPALM],0) && testkopen(defaultrtsfilename[GAME_NAM],0)) + if (!fileSystem.FileExists(defaultrtsfilename[GAME_NAPALM]) && fileSystem.FileExists(defaultrtsfilename[GAME_NAM])) return defaultrtsfilename[GAME_NAM]; // NAM/NAPALM Sharing else return defaultrtsfilename[GAME_NAPALM]; } else if (NAM) { - if (!testkopen(defaultrtsfilename[GAME_NAM],0) && testkopen(defaultrtsfilename[GAME_NAPALM],0)) + if (!fileSystem.FileExists(defaultrtsfilename[GAME_NAM]) && fileSystem.FileExists(defaultrtsfilename[GAME_NAPALM])) return defaultrtsfilename[GAME_NAPALM]; // NAM/NAPALM Sharing else return defaultrtsfilename[GAME_NAM]; @@ -6598,7 +6598,7 @@ static int parsedefinitions_game(scriptfile *pScript, int firstPass) break; } - if (fileName == NULL || check_file_exist(fileName)) + if (fileName == NULL || fileSystem.FileExists(fileName)) break; if (S_DefineMusic(musicID, fileName) == -1) @@ -6746,7 +6746,7 @@ static int parsedefinitions_game(scriptfile *pScript, int firstPass) break; } - if (fileName == NULL || check_file_exist(fileName)) + if (fileName == NULL || fileSystem.FileExists(fileName)) break; // maybe I should have just packed this into a sound_t and passed a reference... @@ -7119,7 +7119,7 @@ static void G_Startup(void) Bcorrectfilename(boardfilename,0); - if (testkopen(boardfilename, 0)) + if (fileSystem.FileExists(boardfilename)) { initprintf("Using level: \"%s\".\n",boardfilename); } @@ -7326,7 +7326,7 @@ int GameInterface::app_main() g_Shareware = 1; else { - if (testkopen("DUKESW.BIN",1)) // JBF 20030810 + if (fileSystem.FileExists("DUKESW.BIN")) // JBF 20030810 { g_Shareware = 1; } diff --git a/source/rr/src/net.cpp b/source/rr/src/net.cpp index 19154e116..8fcde4321 100644 --- a/source/rr/src/net.cpp +++ b/source/rr/src/net.cpp @@ -2594,7 +2594,7 @@ void Net_ParsePacket(uint8_t *packbuf, int packbufleng) Bcorrectfilename(boardfilename,0); if (boardfilename[0] != 0) { - if (testkopen(boardfilename,0)) + if (fileSystem.FileExists(boardfilename,0)) { Bmemset(boardfilename,0,sizeof(boardfilename)); Net_SendUserMapName(); @@ -3519,7 +3519,7 @@ void Net_ReceiveUserMapName(uint8_t *pbuf, int32_t packbufleng) Bcorrectfilename(boardfilename,0); if (boardfilename[0] != 0) { - if (testkopen(boardfilename,0)) + if (fileSystem.FileExists(boardfilename)) { Bmemset(boardfilename,0,sizeof(boardfilename)); Net_SendUserMapName(); diff --git a/source/rr/src/osdcmds.cpp b/source/rr/src/osdcmds.cpp index 9a9184f4f..c30c5cd63 100644 --- a/source/rr/src/osdcmds.cpp +++ b/source/rr/src/osdcmds.cpp @@ -157,7 +157,7 @@ static int osdcmd_map(osdcmdptr_t parm) maybe_append_ext(filename, sizeof(filename), parm->parms[0], ".map"); - if (!testkopen(filename,0)) + if (!fileSystem.FileExists(filename)) { OSD_Printf(OSD_ERROR "map: file \"%s\" not found.\n", filename); return OSDCMD_OK; diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index 2ef830756..0498c7a39 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -2280,7 +2280,7 @@ void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName, int levelNum { Bmemcpy(p+1, ext, Bstrlen(ext) + 1); - if (testkopen(nameBuf, 0)) + if (fileSystem.FileExists(nameBuf)) { realloc_copy(&g_mapInfo[levelNum].musicfn, nameBuf); return; diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index adc23ea27..626aa1c0b 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -1393,7 +1393,7 @@ void G_DisplayLogo(void) { Net_GetPackets(); - if (testkopen("3dr.ivf", 0) || testkopen("3dr.anm", 0)) + if (fileSystem.FileExists("3dr.ivf") || fileSystem.FileExists("3dr.anm")) { Anim_Play("3dr.anm"); G_FadePalette(0, 0, 0, 252); diff --git a/source/sw/src/anim.cpp b/source/sw/src/anim.cpp index f602fc08c..37fafd322 100644 --- a/source/sw/src/anim.cpp +++ b/source/sw/src/anim.cpp @@ -226,7 +226,7 @@ void AnimZilla(int frame, int numframes) } } -unsigned char *LoadAnm(short anim_num) +unsigned char *LoadAnm(short anim_num, int *lengthp) { int length; unsigned char *animbuf, *palptr; @@ -246,7 +246,7 @@ unsigned char *LoadAnm(short anim_num) auto handle = fileSystem.OpenFileReader(ANIMname[ANIMnum], 0); if (!handle.isOpen()) return NULL; - length = handle.GetLength(); + *lengthp = length = handle.GetLength(); buffer.Resize(length + sizeof(anim_t)); anm_ptr[anim_num] = (anim_t*)buffer.Data(); @@ -280,14 +280,10 @@ playanm(short anim_num) DSPRINTF(ds,"PlayAnm"); MONO_PRINT(ds); - animbuf = LoadAnm(anim_num); + animbuf = LoadAnm(anim_num, &length); if (!animbuf) return; - // [JM] Temporary, needed to get the file's length for ANIM_LoadAnim. !CHECKME! - length = kfilesize(ANIMname[ANIMnum], 0); - if (length == -1) return; - DSPRINTF(ds,"PlayAnm - Palette Stuff"); MONO_PRINT(ds); diff --git a/source/sw/src/anim.h b/source/sw/src/anim.h index c5bc4c410..b44ca1556 100644 --- a/source/sw/src/anim.h +++ b/source/sw/src/anim.h @@ -30,6 +30,6 @@ BEGIN_SW_NS #define ANIM_SUMO 2 #define ANIM_ZILLA 3 -unsigned char *LoadAnm(short anim_num); +unsigned char *LoadAnm(short anim_num, int *); void playanm(short anim_num); END_SW_NS diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index f3336fd9f..41a38c65d 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -1615,9 +1615,9 @@ void LogoLevel(void) MONO_PRINT(ds); // PreCache Anim - LoadAnm(0); + LoadAnm(0, &fin); - auto pal = kloadfile("3drealms.pal", 0); + auto pal = fileSystem.LoadFile("3drealms.pal", 0); if (pal.Size() >= 768) { @@ -2991,24 +2991,7 @@ char isShareware = FALSE; int DetectShareware(void) { -#define DOS_SCREEN_NAME_SW "SHADSW.BIN" -#define DOS_SCREEN_NAME_REG "SWREG.BIN" - - int h; - - if (testkopen(DOS_SCREEN_NAME_SW, 1)) - { - isShareware = TRUE; - return 0; - } - - if (testkopen(DOS_SCREEN_NAME_REG, 1)) - { - isShareware = FALSE; - return 0; - } - - return 1; // heavens knows what this is... + return (isShareware = !!(g_gameType & GAMEFLAG_SHAREWARE)); } From 0342b963357545d9bf343ffeabf1c5d5ac72d42b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 10:49:23 +0100 Subject: [PATCH 139/203] - cleaned out the remaining wrappers from cache1d.h and use the file system directly instead. --- source/blood/src/demo.cpp | 10 ++++------ source/build/include/cache1d.h | 16 ---------------- source/build/include/palette.h | 2 +- source/build/src/common.cpp | 3 ++- source/build/src/scriptfile.cpp | 2 +- source/build/src/sdlayer.cpp | 4 ++-- source/common/fonts/fontchars.cpp | 2 +- source/common/fonts/singlelumpfont.cpp | 2 +- source/common/openaudio.h | 2 ++ source/common/rts.cpp | 2 +- source/common/secrets.cpp | 2 +- source/common/textures/formats/ddstexture.cpp | 2 +- source/common/textures/formats/jpegtexture.cpp | 2 +- source/common/textures/formats/pcxtexture.cpp | 2 +- source/common/textures/formats/pngtexture.cpp | 2 +- source/common/textures/formats/stbtexture.cpp | 2 +- source/common/textures/formats/tgatexture.cpp | 2 +- source/common/textures/image.cpp | 2 +- source/common/utility/sc_man.cpp | 11 ++++++----- source/duke3d/src/demo.cpp | 3 +-- source/duke3d/src/demo.h | 2 +- source/duke3d/src/gamevars.h | 1 + source/libsmackerdec/src/FileStream.cpp | 2 +- source/rr/src/demo.cpp | 3 +-- 24 files changed, 34 insertions(+), 49 deletions(-) diff --git a/source/blood/src/demo.cpp b/source/blood/src/demo.cpp index b00b89a5e..f83043659 100644 --- a/source/blood/src/demo.cpp +++ b/source/blood/src/demo.cpp @@ -212,16 +212,14 @@ bool CDemo::SetupPlayback(const char *pzFile) at1 = 0; if (pzFile) { - hPFile = fopenFileReader(pzFile, 0); - if (!hPFile.isOpen()) + if (!hPFile.OpenFile(pzFile)) return false; } else { if (!pCurrentDemo) return false; - hPFile = fopenFileReader(pCurrentDemo->zName, 0); - if (hPFile.isOpen()) + if (!hPFile.OpenFile(pCurrentDemo->zName)) return false; } hPFile.Read(&atf, sizeof(DEMOHEADER)); @@ -412,8 +410,8 @@ void CDemo::LoadDemoInfo(void) D_AddWildFile(demos, zFN); for (auto &filename : demos) { - auto hFile = fopenFileReader(filename, 0); - if (!hFile.isOpen()) + FileReader hFile; + if (!hFile.OpenFile(filename)) ThrowError("Error loading demo file header."); hFile.Read(&atf, sizeof(atf)); #if B_BIG_ENDIAN == 1 diff --git a/source/build/include/cache1d.h b/source/build/include/cache1d.h index 3d7dc8691..4e6983879 100644 --- a/source/build/include/cache1d.h +++ b/source/build/include/cache1d.h @@ -9,23 +9,7 @@ #ifndef cache1d_h_ #define cache1d_h_ -#include "compat.h" -#include "files.h" - void cacheAllocateBlock(intptr_t *newhandle, int32_t newbytes, uint8_t *newlockptr); -extern int32_t pathsearchmode; // 0 = gamefs mode (default), 1 = localfs mode (editor's mode) - -#include "filesystem/filesystem.h" - -// This is only here to mark a file as not being part of the game assets (e.g. savegames) -// These should be handled differently (e.g read from a userdata directory or similar things.) -inline FileReader fopenFileReader(const char* name, int where) -{ - FileReader fr; - fr.OpenFile(name); - return fr; -} - #endif // cache1d_h_ diff --git a/source/build/include/palette.h b/source/build/include/palette.h index 8bf75b49b..d8b6f0c21 100644 --- a/source/build/include/palette.h +++ b/source/build/include/palette.h @@ -11,7 +11,7 @@ #ifndef palette_h_ #define palette_h_ -#include "cache1d.h" +#include "filesystem/filesystem.h" #define MAXBASEPALS 256 #define MAXPALOOKUPS 256 diff --git a/source/build/src/common.cpp b/source/build/src/common.cpp index 4333aab95..5531f8d81 100644 --- a/source/build/src/common.cpp +++ b/source/build/src/common.cpp @@ -292,7 +292,8 @@ static char* KeyValues_FindKeyValue(char **vdfbuf, char * const vdfbufend, const void Paths_ParseSteamKeyValuesForPaths(const char *vdf, SteamPathParseFunc func) { - FileReader fr = fopenFileReader(vdf, 0); + FileReader fr; + if (!fr.OpenFile(vdf)) return; auto size = fr.GetLength(); char *vdfbuf, *vdfbufend; diff --git a/source/build/src/scriptfile.cpp b/source/build/src/scriptfile.cpp index 5b7e02475..e6103e68e 100644 --- a/source/build/src/scriptfile.cpp +++ b/source/build/src/scriptfile.cpp @@ -9,7 +9,7 @@ #include "scriptfile.h" #include "baselayer.h" #include "compat.h" -#include "cache1d.h" +#include "filesystem/filesystem.h" #define ISWS(x) ((x == ' ') || (x == '\t') || (x == '\r') || (x == '\n')) diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index 7bb988b39..112bd5193 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -667,8 +667,8 @@ static SDL_GameController *controller = NULL; static void LoadSDLControllerDB() { - auto fh = fopenFileReader("gamecontrollerdb.txt", 0); - if (!fh.isOpen()) + FileReader fh; + if (!fh.OpenFile("gamecontrollerdb.txt")) return; int flen = fh.GetLength(); diff --git a/source/common/fonts/fontchars.cpp b/source/common/fonts/fontchars.cpp index 7e8d0a26c..caa5a874d 100644 --- a/source/common/fonts/fontchars.cpp +++ b/source/common/fonts/fontchars.cpp @@ -34,7 +34,7 @@ ** */ -#include "cache1d.h" +#include "filesystem/filesystem.h" #include "bitmap.h" #include "image.h" #include "imagehelpers.h" diff --git a/source/common/fonts/singlelumpfont.cpp b/source/common/fonts/singlelumpfont.cpp index 5b80a01e9..47282ac97 100644 --- a/source/common/fonts/singlelumpfont.cpp +++ b/source/common/fonts/singlelumpfont.cpp @@ -40,7 +40,7 @@ #include "fontchars.h" #include "printf.h" #include "imagehelpers.h" -#include "cache1d.h" +#include "filesystem/filesystem.h" #include "fontinternals.h" diff --git a/source/common/openaudio.h b/source/common/openaudio.h index e9fee2288..ac3a6c2de 100644 --- a/source/common/openaudio.h +++ b/source/common/openaudio.h @@ -1,4 +1,6 @@ #pragma once +#include "filesystem/filesystem.h" + // This really, really needs to be redone in its entirety, the audio lookup code is hideous. extern FileReader S_OpenAudio(const char *fn, char searchfirst, uint8_t ismusic); diff --git a/source/common/rts.cpp b/source/common/rts.cpp index 526826520..372d12805 100644 --- a/source/common/rts.cpp +++ b/source/common/rts.cpp @@ -35,7 +35,7 @@ #include #include "zstring.h" #include "tarray.h" -#include "cache1d.h" +#include "filesystem/filesystem.h" #include "rts.h" #include "m_swap.h" diff --git a/source/common/secrets.cpp b/source/common/secrets.cpp index 2e2b32a78..d06700ca0 100644 --- a/source/common/secrets.cpp +++ b/source/common/secrets.cpp @@ -1,5 +1,5 @@ #include "c_dispatch.h" -#include "cache1d.h" +#include "filesystem/filesystem.h" #include "printf.h" #include "v_text.h" #include "tarray.h" diff --git a/source/common/textures/formats/ddstexture.cpp b/source/common/textures/formats/ddstexture.cpp index 2d8a581b1..7527c4359 100644 --- a/source/common/textures/formats/ddstexture.cpp +++ b/source/common/textures/formats/ddstexture.cpp @@ -55,7 +55,7 @@ #include "imagehelpers.h" #include "image.h" #include "m_png.h" -#include "cache1d.h" +#include "filesystem/filesystem.h" // Since we want this to compile under Linux too, we need to define this // stuff ourselves instead of including a DirectX header. diff --git a/source/common/textures/formats/jpegtexture.cpp b/source/common/textures/formats/jpegtexture.cpp index 1adaaeebf..5f3b0e2ad 100644 --- a/source/common/textures/formats/jpegtexture.cpp +++ b/source/common/textures/formats/jpegtexture.cpp @@ -40,7 +40,7 @@ #include "printf.h" #include "bitmap.h" #include "image.h" -#include "cache1d.h" +#include "filesystem/filesystem.h" #include "imagehelpers.h" #include "v_text.h" diff --git a/source/common/textures/formats/pcxtexture.cpp b/source/common/textures/formats/pcxtexture.cpp index 69110bf0d..9a0c3d348 100644 --- a/source/common/textures/formats/pcxtexture.cpp +++ b/source/common/textures/formats/pcxtexture.cpp @@ -39,7 +39,7 @@ #include "bitmap.h" #include "imagehelpers.h" #include "image.h" -#include "cache1d.h" +#include "filesystem/filesystem.h" //========================================================================== // diff --git a/source/common/textures/formats/pngtexture.cpp b/source/common/textures/formats/pngtexture.cpp index 30dabba12..1ed4dcf5d 100644 --- a/source/common/textures/formats/pngtexture.cpp +++ b/source/common/textures/formats/pngtexture.cpp @@ -41,7 +41,7 @@ #include "imagehelpers.h" #include "image.h" #include "printf.h" -#include "cache1d.h" +#include "filesystem/filesystem.h" //========================================================================== // diff --git a/source/common/textures/formats/stbtexture.cpp b/source/common/textures/formats/stbtexture.cpp index 78d6857fb..d9bf916f2 100644 --- a/source/common/textures/formats/stbtexture.cpp +++ b/source/common/textures/formats/stbtexture.cpp @@ -49,7 +49,7 @@ #include "bitmap.h" #include "imagehelpers.h" #include "image.h" -#include "cache1d.h" +#include "filesystem/filesystem.h" //========================================================================== // diff --git a/source/common/textures/formats/tgatexture.cpp b/source/common/textures/formats/tgatexture.cpp index 323ad165f..d920160e7 100644 --- a/source/common/textures/formats/tgatexture.cpp +++ b/source/common/textures/formats/tgatexture.cpp @@ -37,7 +37,7 @@ #include "templates.h" #include "bitmap.h" #include "image.h" -#include "cache1d.h" +#include "filesystem/filesystem.h" #include "imagehelpers.h" diff --git a/source/common/textures/image.cpp b/source/common/textures/image.cpp index 0e1154ba7..39ee8018d 100644 --- a/source/common/textures/image.cpp +++ b/source/common/textures/image.cpp @@ -38,7 +38,7 @@ #include "bitmap.h" #include "image.h" #include "files.h" -#include "cache1d.h" +#include "filesystem/filesystem.h" #include "imagehelpers.h" int FImageSource::NextID; diff --git a/source/common/utility/sc_man.cpp b/source/common/utility/sc_man.cpp index 8e848fa64..6cd7ff42a 100644 --- a/source/common/utility/sc_man.cpp +++ b/source/common/utility/sc_man.cpp @@ -20,7 +20,8 @@ #include "printf.h" #include "name.h" #include "v_text.h" -#include "cache1d.h" +#include "templates.h" +#include "filesystem/filesystem.h" // MACROS ------------------------------------------------------------------ @@ -544,13 +545,13 @@ bool FScanner::GetToken () { TokenType = TK_UIntConst; BigNumber = (int64_t)strtoull(String, &stopper, 0); - Number = (int)clamp(BigNumber, 0, UINT_MAX); + Number = (int)clamp(BigNumber, 0, UINT_MAX); Float = (unsigned)Number; } else { BigNumber = strtoll(String, &stopper, 0); - Number = (int)clamp(BigNumber, INT_MIN, INT_MAX); + Number = (int)clamp(BigNumber, INT_MIN, INT_MAX); Float = Number; } } @@ -652,7 +653,7 @@ bool FScanner::GetNumber () else { BigNumber = strtoll(String, &stopper, 0); - Number = (int)clamp(BigNumber, INT_MIN, INT_MAX); + Number = (int)clamp(BigNumber, INT_MIN, INT_MAX); if (*stopper != 0) { ScriptError ("SC_GetNumber: Bad numeric constant \"%s\".", String); @@ -709,7 +710,7 @@ bool FScanner::CheckNumber () else { BigNumber = strtoll (String, &stopper, 0); - Number = (int)clamp(BigNumber, INT_MIN, INT_MAX); + Number = (int)clamp(BigNumber, INT_MIN, INT_MAX); if (*stopper != 0) { UnGet(); diff --git a/source/duke3d/src/demo.cpp b/source/duke3d/src/demo.cpp index b06aa304b..0a2b00ddf 100644 --- a/source/duke3d/src/demo.cpp +++ b/source/duke3d/src/demo.cpp @@ -95,8 +95,7 @@ static int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine demofnptr = demofn; } - g_demo_recFilePtr = fopenFileReader(demofnptr, g_loadFromGroupOnly); - if (!g_demo_recFilePtr.isOpen()) + if (!g_demo_recFilePtr.OpenFile(demofnptr)) return 0; Bassert(g_whichDemo >= 1); diff --git a/source/duke3d/src/demo.h b/source/duke3d/src/demo.h index d01128835..f27b0f9dd 100644 --- a/source/duke3d/src/demo.h +++ b/source/duke3d/src/demo.h @@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define demo_h_ #include "compat.h" -#include "cache1d.h" +#include "filesystem/filesystem.h" BEGIN_DUKE_NS diff --git a/source/duke3d/src/gamevars.h b/source/duke3d/src/gamevars.h index 66d0b8e22..9cc9717fd 100644 --- a/source/duke3d/src/gamevars.h +++ b/source/duke3d/src/gamevars.h @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "fix16.hpp" #include "gamedef.h" +#include "filesystem/filesystem.h" BEGIN_DUKE_NS diff --git a/source/libsmackerdec/src/FileStream.cpp b/source/libsmackerdec/src/FileStream.cpp index cdb1eff0f..5fd112fc1 100644 --- a/source/libsmackerdec/src/FileStream.cpp +++ b/source/libsmackerdec/src/FileStream.cpp @@ -18,7 +18,7 @@ */ #include "FileStream.h" -#include "cache1d.h" +#include "filesystem/filesystem.h" #include namespace SmackerCommon { diff --git a/source/rr/src/demo.cpp b/source/rr/src/demo.cpp index e459bc519..dd3917168 100644 --- a/source/rr/src/demo.cpp +++ b/source/rr/src/demo.cpp @@ -95,8 +95,7 @@ static int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine demofnptr = demofn; } - g_demo_recFilePtr = fopenFileReader(demofnptr, g_loadFromGroupOnly); - if (!g_demo_recFilePtr.isOpen()) + if (!g_demo_recFilePtr.OpenFile(demofnptr)) return 0; Bassert(g_whichDemo >= 1); From 0b8da78ff562181c67a22cb4c9c97f53d489c8cd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 10:56:35 +0100 Subject: [PATCH 140/203] - toupperlookup was no longer referenced anywhere. --- source/build/src/cache1d.cpp | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/source/build/src/cache1d.cpp b/source/build/src/cache1d.cpp index 9b4dae789..ce903189b 100644 --- a/source/build/src/cache1d.cpp +++ b/source/build/src/cache1d.cpp @@ -6,38 +6,9 @@ // by Jonathon Fowler (jf@jonof.id.au) // by the EDuke32 team (development@voidpoint.com) -#include "compat.h" - -#ifdef _WIN32 -// for FILENAME_CASE_CHECK -# define NEED_SHELLAPI_H -# include "windows_inc.h" -#endif +#include +#include "tarray.h" #include "cache1d.h" -#include "pragmas.h" -#include "baselayer.h" - -uint8_t toupperlookup[256] = -{ - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, - 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, - 0x60,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x7b,0x7c,0x7d,0x7e,0x7f, - 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, - 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf, - 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, - 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf, - 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, - 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef, - 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff -}; - - // Only the sound code still uses this - but it never frees the data. // So we may just toss out the cache and do regular allocations. From a45b1ca6376e87db976334afe710dea9e6862956 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 11:48:41 +0100 Subject: [PATCH 141/203] - fixed anim loading in Shadow Warrior. --- source/sw/src/anim.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/sw/src/anim.cpp b/source/sw/src/anim.cpp index 37fafd322..de3e0e216 100644 --- a/source/sw/src/anim.cpp +++ b/source/sw/src/anim.cpp @@ -240,13 +240,16 @@ unsigned char *LoadAnm(short anim_num, int *lengthp) ANIMnum = anim_num; // lock it - + + int file = fileSystem.FindFile(ANIMname[ANIMnum]); + if (file < 0) return nullptr; + *lengthp = length = fileSystem.FileLength(file); + if (anm_ptr[anim_num] == 0) { - auto handle = fileSystem.OpenFileReader(ANIMname[ANIMnum], 0); + auto handle = fileSystem.OpenFileReader(file); if (!handle.isOpen()) return NULL; - *lengthp = length = handle.GetLength(); buffer.Resize(length + sizeof(anim_t)); anm_ptr[anim_num] = (anim_t*)buffer.Data(); From 9960b505e8a4370d87e0db113de1be726e79db31 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 12:42:25 +0100 Subject: [PATCH 142/203] - added captions to SW's game menus. - made Duke Nukem's quote strings localizable. --- source/common/menu/menudef.cpp | 2 +- source/common/quotes.cpp | 1 + source/sw/src/d_menu.cpp | 4 +- source/sw/src/game.cpp | 6 +- wadsrc/static/demolition/language.csv | 777 +++++++++++++++++++++++++- wadsrc/static/demolition/menudef.txt | 38 +- 6 files changed, 817 insertions(+), 11 deletions(-) diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 58cc93aa0..a8b9ef906 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -242,7 +242,7 @@ static bool CheckSkipNoSwBlock(FScanner& sc) sc.MustGetString(); bool res = sc.Compare("true"); sc.MustGetStringName(")"); - if ((!!(g_gameType & GAMEFLAG_SHAREWARE)) == res) + if ((!(g_gameType & GAMEFLAG_SHAREWARE)) == res) { SkipSubBlock(sc); return !sc.CheckString("else"); diff --git a/source/common/quotes.cpp b/source/common/quotes.cpp index 9511f1182..c3805db0c 100644 --- a/source/common/quotes.cpp +++ b/source/common/quotes.cpp @@ -42,6 +42,7 @@ void Quotes::MakeStringLabel(FString "e) { + quote.Insert(0, "$"); } void Quotes::InitializeQuote(int num, const char *text, bool fromscript) diff --git a/source/sw/src/d_menu.cpp b/source/sw/src/d_menu.cpp index c7d0f553d..92e70f05e 100644 --- a/source/sw/src/d_menu.cpp +++ b/source/sw/src/d_menu.cpp @@ -80,7 +80,7 @@ class SWMainMenu : public DListMenu { void PreDraw() override { - rotatesprite(160, 15, 65536, 0, pic_shadow_warrior, + rotatesprite(160 << 16, 15 << 16, 65536, 0, pic_shadow_warrior, m_defshade, 0, ROTATE_SPRITE_SCREEN_CLIP, 0, 0, xdim - 1, ydim - 1); } }; @@ -251,7 +251,7 @@ void GameInterface::DrawMenuCaption(const DVector2& origin, const char* text) rotatesprite(10 << 16, (5-3) << 16, 65536, 0, 2427, 2, 0, MenuDrawFlags|ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); MNU_MeasureStringLarge(text, &w, &h); - MNU_DrawString(TEXT_XCENTER(w), 5, text, 1, 16); + MNU_DrawStringLarge(TEXT_XCENTER(w), 5, text, 1); } void GameInterface::DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg) diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 41a38c65d..839f0bf3f 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -1885,10 +1885,8 @@ void MenuLevel(void) int fin; short w,h; - DSPRINTF(ds,"MenuLevel..."); - MONO_PRINT(ds); - - + M_StartControlPanel(false); + M_SetMenu(NAME_MainMenu); // do demos only if not playing multi play if (!CommEnabled && numplayers <= 1 && !FinishAnim && !NoDemoStartup) { diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index 6dcef59f8..df96c221c 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -8,6 +8,7 @@ Save Game,MNU_SAVEGAME,,,,Uložit hru,Spiel sichern,,Konservi Ludon,Guardar Part Help,MNU_HELP,,,,,Hilfe,,,,,,Aide,,,,,,,,,,, Continue,MNU_CONTINUE,,,,,Fortfahren,,,,,,,,,,,,,,,,, Credits,MNU_CREDITS,,,,,,,,,,,,,,,,,,,,,, +How to Order,MNU_HOWTOORDER,,,,,Bestellen,,,,,,,,,,,,,,,,, Cool Stuff,MNU_COOLSTUFF,Was removed,,,,Cooles Zeug,,,,,,,,,,,,,,,,, Multiplayer,MNU_MULTIPLAYER,,,,,Mehrspieler,,,,,,,,,,,,,,,,, End Game,MNU_ENDGAME,,,,,Spiel beenden,,,,,,,,,,,,,,,,, @@ -783,4 +784,778 @@ Reset controls to left-handed defaults?,CONFIRM_CTRL3,,,,,Steuerung auf linkshä %o suffered scrotum separation,TXT_SELFOBIT3,,,,%o prodělal@[ao_cs] separaci šourku,%os Eier wurden gebraten,,%o suferis skrotan disigon,%o sufrió separación de escroto,,%o kärsii kivespussin erotuksesta,%o a souffert d'une séparation du scrotum,,%o ha subito la separazione dello scroto,%o の陰嚢は剥離していた。,%o 은(는) 고자가 되었다.,%o leed aan scrotumscheiding...,%o doznał@[ao_pl] oddzielenia moszny,%o sofreu separação escrotal,,,%o страдает от потери тестикул,%o му је исечена патка %o volunteered for population control,TXT_SELFOBIT4,,,,%o se zůčastnil@[ao_cs] čistky obyvatelstva,%o hat sich freiwillig zur Bevölkerungskontrolle gemeldet,,%o volontulis por loĝantarkontrolo,%o fue voluntario para control de población,,%o ilmoittautui vapaaehtoiseksi väestönhallintaan,%o s'est proposé pour un contrôle de la population,,%o si è offerto per il controllo della popolazione,%o は人口削減政策の実験台に志願した。,%o 은(는) 자연에 의해 낙태 당했다.,%o vrijwilliger voor bevolkingscontrole,%o zgłosił@[ao_pl] się na kontrolę ludności,%o se voluntariou para o controle populacional,%o se voluntariou para o controlo populacional,,%o борется с перенаселением,%o је волунтирао за контролу популације %o has suicided,TXT_SELFOBIT5,,,,%o spáchal@[ao_cs] sebevraždu,%o hat Selbstmord begangen,,%o sin mortigis,%o se ha suicidado,,%o on tehnyt itsemurhan,%o s'est suicidé,%o öngyilkos lett,%o si è suicidato,%o は勝手にくたばった。,%o 은(는) 한심하게 자살했다.,%o heeft zelfmoord gepleegd.,%o popełnił@[ao_pl] samobójstwo,%o se suicidou,%o suicidou-se,,Игрок %o самоубился,%o је убио самог себе -%o received the Darwin Award,TXT_SELFOBIT6,,,,%o dostal@[ao_cs] darwinovu cenu,%o hat den Darwinpreis erhalten,,%o ricevis la Darwin-Premion,%o recibió el premio Darwin,,%o sai Darwin-palkinnon,%o a recu la médaille Darwin,És a Darwin Díj nyertese : %o,%o ha ricevuto il Darwin Award,%o にはダーウィン賞が授与された。,%o 은(는) 다윈상을 받을 자격이 있다.,%o ontving de Darwin Award....,%o otrzymał@[ao_pl] Nagrodę Darwina,%o ganhou o Prêmio Darwin,,,Игрок %o получил премию Дарвина,%o је добио Дарвиново признање \ No newline at end of file +%o received the Darwin Award,TXT_SELFOBIT6,,,,%o dostal@[ao_cs] darwinovu cenu,%o hat den Darwinpreis erhalten,,%o ricevis la Darwin-Premion,%o recibió el premio Darwin,,%o sai Darwin-palkinnon,%o a recu la médaille Darwin,És a Darwin Díj nyertese : %o,%o ha ricevuto il Darwin Award,%o にはダーウィン賞が授与された。,%o 은(는) 다윈상을 받을 자격이 있다.,%o ontving de Darwin Award....,%o otrzymał@[ao_pl] Nagrodę Darwina,%o ganhou o Prêmio Darwin,,,Игрок %o получил премию Дарвина,%o је добио Дарвиново признање +,,,,,,,,,,,,,,,,,,,,,,, +,Duke Nukem Script quotes,,,,,,,,,,,,,,,,,,,,,, +Auto Aiming,AUTO AIMING,,,,,,,,,,,,,,,,,,,,,, +Show Map: OFF,SHOW MAP: OFF,,,,,,,,,,,,,,,,,,,,,, +Activated,ACTIVATED,,,,,,,,,,,,,,,,,,,,,, +Portable Medkit,PORTABLE MEDKIT,,,,,,,,,,,,,,,,,,,,,, +Locked,LOCKED,,,,,,,,,,,,,,,,,,,,,, +Giving Everything!,GIVING EVERYTHING!,,,,,,,,,,,,,,,,,,,,,, +Boots,BOOTS,,,,,,,,,,,,,,,,,,,,,, +Wasted!,WASTED!,,,,,,,,,,,,,,,,,,,,,, +Unlocked,UNLOCKED,,,,,,,,,,,,,,,,,,,,,, +A Secret Place!,A SECRET PLACE!,,,,,,,,,,,,,,,,,,,,,, +Squish!,SQUISH!,,,,,,,,,,,,,,,,,,,,,, +All Doors Unlocked,ALL DOORS UNLOCKED,,,,,,,,,,,,,,,,,,,,,, +Used Steroids,USED STEROIDS,,,,,,,,,,,,,,,,,,,,,, +Press Space To Restart Level,PRESS SPACE TO RESTART LEVEL,,,,,,,,,,,,,,,,,,,,,, +Ammo For Devastator,AMMO FOR DEVASTATOR,,,,,,,,,,,,,,,,,,,,,, +Deactivated,DEACTIVATED,,,,,,,,,,,,,,,,,,,,,, +Switch Operated Only!,SWITCH OPERATED ONLY!,,,,,,,,,,,,,,,,,,,,,, +God Mode: ON,GOD MODE: ON,,,,,,,,,,,,,,,,,,,,,, +God Mode: OFF,GOD MODE: OFF,,,,,,,,,,,,,,,,,,,,,, +Atomic Health!,ATOMIC HEALTH!,,,,,,,,,,,,,,,,,,,,,, +Crosshair: ON,CROSSHAIR: ON,,,,,,,,,,,,,,,,,,,,,, +Crosshair: OFF,CROSSHAIR: OFF,,,,,,,,,,,,,,,,,,,,,, +You're Too Good To Be Cheating!,YOU'RE TOO GOOD TO BE CHEATING!,,,,,,,,,,,,,,,,,,,,,, +Messages: ON,MESSAGES: ON,,,,,,,,,,,,,,,,,,,,,, +Messages: OFF,MESSAGES: OFF,,,,,,,,,,,,,,,,,,,,,, +Type The Cheat Code:,TYPE THE CHEAT CODE:,,,,,,,,,,,,,,,,,,,,,, +Detail: Low,DETAIL: LOW,,,,,,,,,,,,,,,,,,,,,, +Detail: High,DETAIL: HIGH,,,,,,,,,,,,,,,,,,,,,, +Will Always Have No Future,WILL ALWAYS HAVE NO FUTURE,,,,,,,,,,,,,,,,,,,,,, +Brightness Level: ONe,BRIGHTNESS LEVEL: ONE,,,,,,,,,,,,,,,,,,,,,, +Brightness Level: Two,BRIGHTNESS LEVEL: TWO,,,,,,,,,,,,,,,,,,,,,, +Brightness Level: Three,BRIGHTNESS LEVEL: THREE,,,,,,,,,,,,,,,,,,,,,, +Brightness Level: Four,BRIGHTNESS LEVEL: FOUR,,,,,,,,,,,,,,,,,,,,,, +Brightness Level: Five,BRIGHTNESS LEVEL: FIVE,,,,,,,,,,,,,,,,,,,,,, +Sound: ON,SOUND: ON,,,,,,,,,,,,,,,,,,,,,, +Sound: OFF,SOUND: OFF,,,,,,,,,,,,,,,,,,,,,, +Screen Captured,SCREEN CAPTURED,,,,,,,,,,,,,,,,,,,,,, +Steroids,STEROIDS,,,,,,,,,,,,,,,,,,,,,, +Armor,ARMOR,,,,,,,,,,,,,,,,,,,,,, +Scuba Gear,SCUBA GEAR,,,,,,,,,,,,,,,,,,,,,, +Press F1 For Help,Press F1 for Help,,,,,,,,,,,,,,,,,,,,,, +Jetpack,JETPACK,,,,,,,,,,,,,,,,,,,,,, +Body Suit,BODY SUIT,,,,,,,,,,,,,,,,,,,,,, +Access Card,ACCESS CARD,,,,,,,,,,,,,,,,,,,,,, +Mouse Aiming Off,MOUSE AIMING OFF,,,,,,,,,,,,,,,,,,,,,, +Mouse Aiming On,MOUSE AIMING ON,,,,,,,,,,,,,,,,,,,,,, +Cheat Code: Unrecognized,CHEAT CODE: UNRECOGNIZED,,,,,,,,,,,,,,,,,,,,,, +Holoduke On,HOLODUKE ON,,,,,,,,,,,,,,,,,,,,,, +Holoduke Off,HOLODUKE OFF,,,,,,,,,,,,,,,,,,,,,, +Holoduke Not Found Yet!,HOLODUKE NOT FOUND YET!,,,,,,,,,,,,,,,,,,,,,, +Jetpack Not Found Yet!,JETPACK NOT FOUND YET!,,,,,,,,,,,,,,,,,,,,,, +Holoduke,HOLODUKE,,,,,,,,,,,,,,,,,,,,,, +Jetpack On,JETPACK ON,,,,,,,,,,,,,,,,,,,,,, +Jetpack Off,JETPACK OFF,,,,,,,,,,,,,,,,,,,,,, +Chaingun Cannon!,CHAINGUN CANNON!,,,,,,,,,,,,,,,,,,,,,, +Pipebomb!,PIPEBOMB!,,,,,,,,,,,,,,,,,,,,,, +RPG!,RPG!,,,,,,,,,,,,,,,,,,,,,, +Shotgun,SHOTGUN,,,,,,,,,,,,,,,,,,,,,, +Laser Tripbomb!,LASER TRIPBOMB!,,,,,,,,,,,,,,,,,,,,,, +Freezethrower!,FREEZETHROWER!,,,,,,,,,,,,,,,,,,,,,, +Got Shrinker/Expander!,GOT SHRINKER/EXPANDER!,,,,,,,,,,,,,,,,,,,,,, +Small Medkit: +10,SMALL MEDKIT: +10,,,,,,,,,,,,,,,,,,,,,, +Large Medkit: +30,LARGE MEDKIT: +30,,,,,,,,,,,,,,,,,,,,,, +Ammo For Chaingun Cannon!,AMMO FOR CHAINGUN CANNON!,,,,,,,,,,,,,,,,,,,,,, +Ammo For Rpg!,AMMO FOR RPG!,,,,,,,,,,,,,,,,,,,,,, +Ammo For Pistol!,AMMO FOR PISTOL!,,,,,,,,,,,,,,,,,,,,,, +Ammo For Freezethrower!,AMMO FOR FREEZETHROWER!,,,,,,,,,,,,,,,,,,,,,, +Boots Off,BOOTS OFF,,,,,,,,,,,,,,,,,,,,,, +Boots On,BOOTS ON,,,,,,,,,,,,,,,,,,,,,, +Ammo For Shotgun,AMMO FOR SHOTGUN,,,,,,,,,,,,,,,,,,,,,, +Blue Access Card Required,BLUE ACCESS CARD REQUIRED,,,,,,,,,,,,,,,,,,,,,, +Red Access Card Required,RED ACCESS CARD REQUIRED,,,,,,,,,,,,,,,,,,,,,, +Yellow Access Card Required,YELLOW ACCESS CARD REQUIRED,,,,,,,,,,,,,,,,,,,,,, +Weapon Lowered,WEAPON LOWERED,,,,,,,,,,,,,,,,,,,,,, +Weapon Raised,WEAPON RAISED,,,,,,,,,,,,,,,,,,,,,, +Protective Boots On,PROTECTIVE BOOTS ON,,,,,,,,,,,,,,,,,,,,,, +Scuba Gear On,SCUBA GEAR ON,,,,,,,,,,,,,,,,,,,,,, +Space Suit On,SPACE SUIT ON,,,,,,,,,,,,,,,,,,,,,, +Ammo For Shrinker,AMMO FOR SHRINKER,,,,,,,,,,,,,,,,,,,,,, +Buy Major Stryker,BUY MAJOR STRYKER,,,,,,,,,,,,,,,,,,,,,, +Mighty Foot Engaged,MIGHTY FOOT ENGAGED,,,,,,,,,,,,,,,,,,,,,, +Weapon Mode On,WEAPON MODE ON,,,,,,,,,,,,,,,,,,,,,, +Weapon Mode Off,WEAPON MODE OFF,,,,,,,,,,,,,,,,,,,,,, +Follow Mode Off,FOLLOW MODE OFF,,,,,,,,,,,,,,,,,,,,,, +Follow Mode On,FOLLOW MODE ON,,,,,,,,,,,,,,,,,,,,,, +Run Mode Off,RUN MODE OFF,,,,,,,,,,,,,,,,,,,,,, +Run Mode On,RUN MODE ON,,,,,,,,,,,,,,,,,,,,,, +Devastator Weapon,DEVASTATOR WEAPON,,,,,,,,,,,,,,,,,,,,,, +Jet Pack,JET PACK,,,,,,,,,,,,,,,,,,,,,, +Airtank,AIRTANK,,,,,,,,,,,,,,,,,,,,,, +Steroids,STEROIDS,,,,,,,,,,,,,,,,,,,,,, +Holoduke,HOLODUKE,,,,,,,,,,,,,,,,,,,,,, +Music: ON,MUSIC: ON,,,,,,,,,,,,,,,,,,,,,, +Music: OFF,MUSIC: OFF,,,,,,,,,,,,,,,,,,,,,, +Scroll Mode: ON,SCROLL MODE: ON,,,,,,,,,,,,,,,,,,,,,, +Scroll Mode: OFF,SCROLL MODE: OFF,,,,,,,,,,,,,,,,,,,,,, +Brightness Level: Six,BRIGHTNESS LEVEL: SIX,,,,,,,,,,,,,,,,,,,,,, +Brightness Level: Seven,BRIGHTNESS LEVEL: SEVEN,,,,,,,,,,,,,,,,,,,,,, +Brightness Level: Eight,BRIGHTNESS LEVEL: EIGHT,,,,,,,,,,,,,,,,,,,,,, +Register Cosmo Today!,REGISTER COSMO TODAY!,,,,,,,,,,,,,,,,,,,,,, +All Locks Toggled,ALL LOCKS TOGGLED,,,,,,,,,,,,,,,,,,,,,, +Night Vision Goggles,NIGHT VISION GOGGLES,,,,,,,,,,,,,,,,,,,,,, +"We're Gonna Fry Your Ass, Nukem!","WE'RE GONNA FRY YOUR ASS, NUKEM!",,,,,,,,,,,,,,,,,,,,,, +Screen Saved,SCREEN SAVED,,,,,,,,,,,,,,,,,,,,,, +Got Used Armor,GOT USED ARMOR,,,,,,,,,,,,,,,,,,,,,, +Pirates Suck!,PIRATES SUCK!,,,,,,,,,,,,,,,,,,,,,, +Night Vision On,NIGHT VISION ON,,,,,,,,,,,,,,,,,,,,,, +Night Vision Off,NIGHT VISION OFF,,,,,,,,,,,,,,,,,,,,,, +You're Burning!,YOU'RE BURNING!,,,,,,,,,,,,,,,,,,,,,, +View Mode Off,VIEW MODE OFF,,,,,,,,,,,,,,,,,,,,,, +View Mode On,VIEW MODE ON,,,,,,,,,,,,,,,,,,,,,, +Show Map: ON,SHOW MAP: ON,,,,,,,,,,,,,,,,,,,,,, +Clipping: ON,CLIPPING: ON,,,,,,,,,,,,,,,,,,,,,, +Clipping: OFF,CLIPPING: OFF,,,,,,,,,,,,,,,,,,,,,, +!!! Incorrect Version !!!,!!! INCORRECT VERSION !!!,,,,,,,,,,,,,,,,,,,,,, +"You Cannot ""Quick Save"" When Dead","YOU CANNOT ""QUICK SAVE"" WHEN DEAD",,,,,,,,,,,,,,,,,,,,,, +Got All Weapons/Ammo,GOT ALL WEAPONS/AMMO,,,,,,,,,,,,,,,,,,,,,, +Got All Inventory,GOT ALL INVENTORY,,,,,,,,,,,,,,,,,,,,,, +Got All Keys,GOT ALL KEYS,,,,,,,,,,,,,,,,,,,,,, +Ammo For Expander,AMMO FOR EXPANDER,,,,,,,,,,,,,,,,,,,,,, +Map Has A Different Number Of Players,MAP HAS A DIFFERENT NUMBER OF PLAYERS,,,,,,,,,,,,,,,,,,,,,, +,Alterations from Duke Caribbean: Life's a Beach,,,,,,,,,,,,,,,,,,,,,, +Crate Of Bananas,CRATE OF BANANAS,,,,,,,,,,,,,,,,,,,,,, +Denied,DENIED,,,,,,,,,,,,,,,,,,,,,, +Sandles,SANDLES,,,,,,,,,,,,,,,,,,,,,, +Approved,APPROVED,,,,,,,,,,,,,,,,,,,,,, +Used Hot Sauce,USED HOT SAUCE,,,,,,,,,,,,,,,,,,,,,, +Ammo For Conchanator,AMMO FOR CONCHANATOR,,,,,,,,,,,,,,,,,,,,,, +Pearl Health!,PEARL HEALTH!,,,,,,,,,,,,,,,,,,,,,, +Hot Sauce,HOT SAUCE,,,,,,,,,,,,,,,,,,,,,, +Suntan Lotion,SUNTAN LOTION,,,,,,,,,,,,,,,,,,,,,, +Snorkle,SNORKLE,,,,,,,,,,,,,,,,,,,,,, +Credit Card,CREDIT CARD,,,,,,,,,,,,,,,,,,,,,, +Triple Poison Shooter!,TRIPLE POISON SHOOTER!,,,,,,,,,,,,,,,,,,,,,, +Pineapple!,PINEAPPLE!,,,,,,,,,,,,,,,,,,,,,, +Coconut Launcher!,COCONUT LAUNCHER!,,,,,,,,,,,,,,,,,,,,,, +Super Soak'em!,SUPER SOAK'EM!,,,,,,,,,,,,,,,,,,,,,, +Voodoo Trip Bomb!,VOODOO TRIP BOMB!,,,,,,,,,,,,,,,,,,,,,, +Ice Crusher!,ICE CRUSHER!,,,,,,,,,,,,,,,,,,,,,, +Voodoo Ring!,VOODOO RING!,,,,,,,,,,,,,,,,,,,,,, +Single Banana: +10,SINGLE BANANA: +10,,,,,,,,,,,,,,,,,,,,,, +Bunch Of Bananas: +30,BUNCH OF BANANAS: +30,,,,,,,,,,,,,,,,,,,,,, +Ammo For Triple Poison Shooter!,AMMO FOR TRIPLE POISON SHOOTER!,,,,,,,,,,,,,,,,,,,,,, +Ammo For Coconut Launcher!,AMMO FOR COCONUT LAUNCHER!,,,,,,,,,,,,,,,,,,,,,, +Ammo For Water Pistol!,AMMO FOR WATER PISTOL!,,,,,,,,,,,,,,,,,,,,,, +Ammo For Ice Crusher!,AMMO FOR ICE CRUSHER!,,,,,,,,,,,,,,,,,,,,,, +Sandles Off,SANDLES OFF,,,,,,,,,,,,,,,,,,,,,, +Sandles On,SANDLES ON,,,,,,,,,,,,,,,,,,,,,, +Ammo For Super Soak'em!,AMMO FOR SUPER SOAK'EM!,,,,,,,,,,,,,,,,,,,,,, +Blue Credit Card Required,BLUE CREDIT CARD REQUIRED,,,,,,,,,,,,,,,,,,,,,, +Red Credit Card Required,RED CREDIT CARD REQUIRED,,,,,,,,,,,,,,,,,,,,,, +Yellow Credit Card Required,YELLOW CREDIT CARD REQUIRED,,,,,,,,,,,,,,,,,,,,,, +Protective Sandles On,PROTECTIVE SANDLES ON,,,,,,,,,,,,,,,,,,,,,, +Snorkle On,SNORKLE ON,,,,,,,,,,,,,,,,,,,,,, +Ammo For Voodoo Ring!,AMMO FOR VOODOO RING!,,,,,,,,,,,,,,,,,,,,,, +Conchanator Weapon,CONCHANATOR WEAPON,,,,,,,,,,,,,,,,,,,,,, +Hot Sauce,HOT SAUCE,,,,,,,,,,,,,,,,,,,,,, +Sunglasses,SUNGLASSES,,,,,,,,,,,,,,,,,,,,,, +This Party Is Over Nukem,THIS PARTY IS OVER NUKEM,,,,,,,,,,,,,,,,,,,,,, +Got Used Suntan Lotion,GOT USED SUNTAN LOTION,,,,,,,,,,,,,,,,,,,,,, +Sunglasses On,SUNGLASSES ON,,,,,,,,,,,,,,,,,,,,,, +Sunglasses Off,SUNGLASSES OFF,,,,,,,,,,,,,,,,,,,,,, +,"Episodes, Skills, Maps",,,,,,,,,,,,,,,,,,,,,, +L.A. Meltdown,L.A. MELTDOWN,,,,,,,,,,,,,,,,,,,,,, +Lunar Apocalypse,LUNAR APOCALYPSE,,,,,,,,,,,,,,,,,,,,,, +Shrapnel City,SHRAPNEL CITY,,,,,,,,,,,,,,,,,,,,,, +The Birth,THE BIRTH,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Piece Of Cake,PIECE OF CAKE,,,,,,,,,,,,,,,,,,,,,, +Let's Rock,LET'S ROCK,,,,,,,,,,,,,,,,,,,,,, +Come Get Some,COME GET SOME,,,,,,,,,,,,,,,,,,,,,, +Damn I'm Good,DAMN I'M GOOD,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Hollywood Holocaust,HOLLYWOOD HOLOCAUST,,,,,,,,,,,,,,,,,,,,,, +Red Light District,RED LIGHT DISTRICT,,,,,,,,,,,,,,,,,,,,,, +Death Row,DEATH ROW,,,,,,,,,,,,,,,,,,,,,, +Toxic Dump,TOXIC DUMP,,,,,,,,,,,,,,,,,,,,,, +The Abyss,THE ABYSS,,,,,,,,,,,,,,,,,,,,,, +Launch Facility,LAUNCH FACILITY,,,,,,,,,,,,,,,,,,,,,, +Faces Of Death,FACES OF DEATH,,,,,,,,,,,,,,,,,,,,,, +User Map,USER MAP,,,,,,,,,,,,,,,,,,,,,, +Void Zone,VOID ZONE,,,,,,,,,,,,,,,,,,,,,, +Roach Condo,ROACH CONDO,,,,,,,,,,,,,,,,,,,,,, +Antiprofit,ANTIPROFIT,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Spaceport,SPACEPORT,,,,,,,,,,,,,,,,,,,,,, +Incubator,INCUBATOR,,,,,,,,,,,,,,,,,,,,,, +Warp Factor,WARP FACTOR,,,,,,,,,,,,,,,,,,,,,, +Fusion Station,FUSION STATION,,,,,,,,,,,,,,,,,,,,,, +Occupied Territory,OCCUPIED TERRITORY,,,,,,,,,,,,,,,,,,,,,, +Tiberius Station,TIBERIUS STATION,,,,,,,,,,,,,,,,,,,,,, +Lunar Reactor,LUNAR REACTOR,,,,,,,,,,,,,,,,,,,,,, +Dark Side,DARK SIDE,,,,,,,,,,,,,,,,,,,,,, +Overlord,OVERLORD,,,,,,,,,,,,,,,,,,,,,, +Spin Cycle,SPIN CYCLE,,,,,,,,,,,,,,,,,,,,,, +Lunatic Fringe,LUNATIC FRINGE,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Raw Meat,RAW MEAT,,,,,,,,,,,,,,,,,,,,,, +Bank Roll,BANK ROLL,,,,,,,,,,,,,,,,,,,,,, +Flood Zone,FLOOD ZONE,,,,,,,,,,,,,,,,,,,,,, +L.A. Rumble,L.A. RUMBLE,,,,,,,,,,,,,,,,,,,,,, +Movie Set,MOVIE SET,,,,,,,,,,,,,,,,,,,,,, +Rabid Transit,RABID TRANSIT,,,,,,,,,,,,,,,,,,,,,, +Fahrenheit,FAHRENHEIT,,,,,,,,,,,,,,,,,,,,,, +Hotel Hell,HOTEL HELL,,,,,,,,,,,,,,,,,,,,,, +Stadium,STADIUM,,,,,,,,,,,,,,,,,,,,,, +Tier Drops,TIER DROPS,,,,,,,,,,,,,,,,,,,,,, +Freeway,FREEWAY,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +It's Impossible,IT'S IMPOSSIBLE,,,,,,,,,,,,,,,,,,,,,, +Duke-Burger,DUKE-BURGER,,,,,,,,,,,,,,,,,,,,,, +Shop-N-Bag,SHOP-N-BAG,,,,,,,,,,,,,,,,,,,,,, +Babe Land,BABE LAND,,,,,,,,,,,,,,,,,,,,,, +Pigsty,PIGSTY,,,,,,,,,,,,,,,,,,,,,, +Going Postal,GOING POSTAL,,,,,,,,,,,,,,,,,,,,,, +Xxx-Stacy,XXX-STACY,,,,,,,,,,,,,,,,,,,,,, +Critical Mass,CRITICAL MASS,,,,,,,,,,,,,,,,,,,,,, +Derelict,DERELICT,,,,,,,,,,,,,,,,,,,,,, +The Queen,THE QUEEN,,,,,,,,,,,,,,,,,,,,,, +Area 51,AREA 51,,,,,,,,,,,,,,,,,,,,,, +,Duke Caribbean,,,,,,,,,,,,,,,,,,,,,, +Vacation Dukematch,VACATION DUKEMATCH,,,,,,,,,,,,,,,,,,,,,, +Life's A Beach,LIFE'S A BEACH,,,,,,,,,,,,,,,,,,,,,, +Low Tide,LOW TIDE,,,,,,,,,,,,,,,,,,,,,, +Makin' Waves,MAKIN' WAVES,,,,,,,,,,,,,,,,,,,,,, +Big Kahuna,BIG KAHUNA,,,,,,,,,,,,,,,,,,,,,, +Tsunami,TSUNAMI,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Island Hopping,ISLAND HOPPING,,,,,,,,,,,,,,,,,,,,,, +Hidden Grotto,HIDDEN GROTTO,,,,,,,,,,,,,,,,,,,,,, +Cruise Ship,CRUISE SHIP,,,,,,,,,,,,,,,,,,,,,, +The Docks,THE DOCKS,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Caribbean Catastrophe,CARIBBEAN CATASTROPHE,,,,,,,,,,,,,,,,,,,,,, +Market Melee,MARKET MELEE,,,,,,,,,,,,,,,,,,,,,, +Mr. Splashy's,MR. SPLASHY'S,,,,,,,,,,,,,,,,,,,,,, +The Wavemistress,THE WAVEMISTRESS,,,,,,,,,,,,,,,,,,,,,, +Lost Lagoon,LOST LAGOON,,,,,,,,,,,,,,,,,,,,,, +Voodoo Caves,VOODOO CAVES,,,,,,,,,,,,,,,,,,,,,, +The Alien Remains,THE ALIEN REMAINS,,,,,,,,,,,,,,,,,,,,,, +A Full House,A FULL HOUSE,,,,,,,,,,,,,,,,,,,,,, +,DukeDC,,,,,,,,,,,,,,,,,,,,,, +Duke It Out In D.C.,DUKE IT OUT IN D.C.,,,,,,,,,,,,,,,,,,,,,, +Hell To The Chief,HELL TO THE CHIEF,,,,,,,,,,,,,,,,,,,,,, +Memorial Service,MEMORIAL SERVICE,,,,,,,,,,,,,,,,,,,,,, +Nuked Files,NUKED FILES,,,,,,,,,,,,,,,,,,,,,, +Smithsonian Terror,SMITHSONIAN TERROR,,,,,,,,,,,,,,,,,,,,,, +Capitol Punishment,CAPITOL PUNISHMENT,,,,,,,,,,,,,,,,,,,,,, +Metro Mayhem,METRO MAYHEM,,,,,,,,,,,,,,,,,,,,,, +Brown Water,BROWN WATER,,,,,,,,,,,,,,,,,,,,,, +Dread October,DREAD OCTOBER,,,,,,,,,,,,,,,,,,,,,, +Nuke Proof,NUKE PROOF,,,,,,,,,,,,,,,,,,,,,, +Top Secret,TOP SECRET,,,,,,,,,,,,,,,,,,,,,, +,Nuclear Winter,,,,,,,,,,,,,,,,,,,,,, +Nuclear Winter,NUCLEAR WINTER,,,,,,,,,,,,,,,,,,,,,, +Deja Vu,DEJA VU,,,,,,,,,,,,,,,,,,,,,, +Where It All Began,WHERE IT ALL BEGAN,,,,,,,,,,,,,,,,,,,,,, +Land Of Forgotten Toys,LAND OF FORGOTTEN TOYS,,,,,,,,,,,,,,,,,,,,,, +Santa's Corporate Hq,SANTA'S CORPORATE HQ,,,,,,,,,,,,,,,,,,,,,, +The Backdoor,THE BACKDOOR,,,,,,,,,,,,,,,,,,,,,, +Christmas Village,CHRISTMAS VILLAGE,,,,,,,,,,,,,,,,,,,,,, +Here Comes Santa Claws,HERE COMES SANTA CLAWS,,,,,,,,,,,,,,,,,,,,,, +Santamatch,SANTAMATCH,,,,,,,,,,,,,,,,,,,,,, +,NAM,,,,,,,,,,,,,,,,,,,,,, +Inventory Item,INVENTORY ITEM,,,,,,,,,,,,,,,,,,,,,, +All Ammo Crates Found...Get Back To The M113,ALL AMMO CRATES FOUND...GET BACK TO THE M113,,,,,,,,,,,,,,,,,,,,,, +Tank Mode On,TANK MODE ON,,,,,,,,,,,,,,,,,,,,,, +Killed In Action...Press Space To Restart Level,KILLED IN ACTION...PRESS SPACE TO RESTART LEVEL,,,,,,,,,,,,,,,,,,,,,, +You Need Ammo To Use This Weapon,YOU NEED AMMO TO USE THIS WEAPON,,,,,,,,,,,,,,,,,,,,,, +M-16 Rifle!,M-16 RIFLE!,,,,,,,,,,,,,,,,,,,,,, +Tank,TANK,,,,,,,,,,,,,,,,,,,,,, +Armor Vest,ARMOR VEST,,,,,,,,,,,,,,,,,,,,,, +Chemical Mine!,CHEMICAL MINE!,,,,,,,,,,,,,,,,,,,,,, +Huey,HUEY,,,,,,,,,,,,,,,,,,,,,, +Mine Placed,MINE PLACED,,,,,,,,,,,,,,,,,,,,,, +Holosoldier On,HOLOSOLDIER ON,,,,,,,,,,,,,,,,,,,,,, +Holosoldier Off,HOLOSOLDIER OFF,,,,,,,,,,,,,,,,,,,,,, +Holosoldier Not Found Yet!,HOLOSOLDIER NOT FOUND YET!,,,,,,,,,,,,,,,,,,,,,, +Huey Not Found Yet!,HUEY NOT FOUND YET!,,,,,,,,,,,,,,,,,,,,,, +Holosoldier,HOLOSOLDIER,,,,,,,,,,,,,,,,,,,,,, +Huey Mode On,HUEY MODE ON,,,,,,,,,,,,,,,,,,,,,, +Huey Mode Off,HUEY MODE OFF,,,,,,,,,,,,,,,,,,,,,, +M-60 Machine Gun!,M-60 MACHINE GUN!,,,,,,,,,,,,,,,,,,,,,, +Grenade!,GRENADE!,,,,,,,,,,,,,,,,,,,,,, +M-72 Law!,M-72 LAW!,,,,,,,,,,,,,,,,,,,,,, +Claymore Mine!,CLAYMORE MINE!,,,,,,,,,,,,,,,,,,,,,, +Flamethrower !,FLAMETHROWER !,,,,,,,,,,,,,,,,,,,,,, +M-79 Grenade Launcher!,M-79 GRENADE LAUNCHER!,,,,,,,,,,,,,,,,,,,,,, +Reloading Rocket Launcher,RELOADING ROCKET LAUNCHER,,,,,,,,,,,,,,,,,,,,,, +Medikit: +30,MEDIKIT: +30,,,,,,,,,,,,,,,,,,,,,, +Ammo For M-60!,AMMO FOR M-60!,,,,,,,,,,,,,,,,,,,,,, +Radioman - Calling In Fire Mission (High Explosive),RADIOMAN - CALLING IN FIRE MISSION (HIGH EXPLOSIVE),,,,,,,,,,,,,,,,,,,,,, +Ammo For M-16!,AMMO FOR M-16!,,,,,,,,,,,,,,,,,,,,,, +Rocket Launcher,ROCKET LAUNCHER,,,,,,,,,,,,,,,,,,,,,, +Ammo For Shotgun!,AMMO FOR SHOTGUN!,,,,,,,,,,,,,,,,,,,,,, +Defense System Malfunction,DEFENSE SYSTEM MALFUNCTION,,,,,,,,,,,,,,,,,,,,,, +Empty,EMPTY,,,,,,,,,,,,,,,,,,,,,, +You Can't Use Tank And Huey At The Same Time !!!,YOU CAN'T USE TANK AND HUEY AT THE SAME TIME !!!,,,,,,,,,,,,,,,,,,,,,, +Flare Ready,FLARE READY,,,,,,,,,,,,,,,,,,,,,, +Knife,KNIFE,,,,,,,,,,,,,,,,,,,,,, +Huey,HUEY,,,,,,,,,,,,,,,,,,,,,, +Ctf,CTF,,,,,,,,,,,,,,,,,,,,,, +Tank,TANK,,,,,,,,,,,,,,,,,,,,,, +Holosoldier,HOLOSOLDIER,,,,,,,,,,,,,,,,,,,,,, +Radioman - Following,RADIOMAN - FOLLOWING,,,,,,,,,,,,,,,,,,,,,, +Mine Disarmed,MINE DISARMED,,,,,,,,,,,,,,,,,,,,,, +Mine Ready,MINE READY,,,,,,,,,,,,,,,,,,,,,, +Trip Flare Placed,TRIP FLARE PLACED,,,,,,,,,,,,,,,,,,,,,, +Radioman - Can't Call In Fire Mission,RADIOMAN - CAN'T CALL IN FIRE MISSION,,,,,,,,,,,,,,,,,,,,,, +Medic - Following,MEDIC - FOLLOWING,,,,,,,,,,,,,,,,,,,,,, +Medic - Awaiting Further Orders,MEDIC - AWAITING FURTHER ORDERS,,,,,,,,,,,,,,,,,,,,,, +Demoman - Following,DEMOMAN - FOLLOWING,,,,,,,,,,,,,,,,,,,,,, +Demoman - Awaiting Further Orders,DEMOMAN - AWAITING FURTHER ORDERS,,,,,,,,,,,,,,,,,,,,,, +Demoman - Placing Apers Mine,DEMOMAN - PLACING APERS MINE,,,,,,,,,,,,,,,,,,,,,, +Demoman - Placing C-4 Explosive,DEMOMAN - PLACING C-4 EXPLOSIVE,,,,,,,,,,,,,,,,,,,,,, +Grunt - Following,GRUNT - FOLLOWING,,,,,,,,,,,,,,,,,,,,,, +Grunt - Awaiting Further Orders,GRUNT - AWAITING FURTHER ORDERS,,,,,,,,,,,,,,,,,,,,,, +Grunt - M-16 Ambush Mode,GRUNT - M-16 AMBUSH MODE,,,,,,,,,,,,,,,,,,,,,, +Radioman - Awaiting Further Orders,RADIOMAN - AWAITING FURTHER ORDERS,,,,,,,,,,,,,,,,,,,,,, +Grunt - M 72 Ambush Mode,GRUNT - M 72 AMBUSH MODE,,,,,,,,,,,,,,,,,,,,,, +Laser Loading,LASER LOADING,,,,,,,,,,,,,,,,,,,,,, +Laser Ready,LASER READY,,,,,,,,,,,,,,,,,,,,,, +You Are On The Blue Team,YOU ARE ON THE BLUE TEAM,,,,,,,,,,,,,,,,,,,,,, +You Are On The Red Team,YOU ARE ON THE RED TEAM,,,,,,,,,,,,,,,,,,,,,, +You Got The Enemy Flag...Take It Back To Your Banner,YOU GOT THE ENEMY FLAG...TAKE IT BACK TO YOUR BANNER,,,,,,,,,,,,,,,,,,,,,, +You Got The Beast Flag,YOU GOT THE BEAST FLAG,,,,,,,,,,,,,,,,,,,,,, +Crawl And Press Space To Activate Beast Mode,CRAWL AND PRESS SPACE TO ACTIVATE BEAST MODE,,,,,,,,,,,,,,,,,,,,,, +Blue Team Wins,BLUE TEAM WINS,,,,,,,,,,,,,,,,,,,,,, +Red Team Wins,RED TEAM WINS,,,,,,,,,,,,,,,,,,,,,, +Apers Mine ( 5),APERS MINE ( 5),,,,,,,,,,,,,,,,,,,,,, +Trip Flare ( 5),TRIP FLARE ( 5),,,,,,,,,,,,,,,,,,,,,, +C-4 Explosive,C-4 EXPLOSIVE,,,,,,,,,,,,,,,,,,,,,, +C-4 Placed,C-4 PLACED,,,,,,,,,,,,,,,,,,,,,, +Press Space To View Map,PRESS SPACE TO VIEW MAP,,,,,,,,,,,,,,,,,,,,,, +Booby Trap !!!,BOOBY TRAP !!!,,,,,,,,,,,,,,,,,,,,,, +Mine Detector,MINE DETECTOR,,,,,,,,,,,,,,,,,,,,,, +Radioman - Calling In Fire Mission (Smoke),RADIOMAN - CALLING IN FIRE MISSION (SMOKE),,,,,,,,,,,,,,,,,,,,,, +Ammo For M2machine Gun!,AMMO FOR M2MACHINE GUN!,,,,,,,,,,,,,,,,,,,,,, +M2machine Gun [Press Space To Fire],M2MACHINE GUN [PRESS SPACE TO FIRE],,,,,,,,,,,,,,,,,,,,,, +You're Bleeding,YOU'RE BLEEDING,,,,,,,,,,,,,,,,,,,,,, +A-Gunner,A-GUNNER,,,,,,,,,,,,,,,,,,,,,, +Machine Gunner,MACHINE GUNNER,,,,,,,,,,,,,,,,,,,,,, +Sniper,SNIPER,,,,,,,,,,,,,,,,,,,,,, +Grenadier,GRENADIER,,,,,,,,,,,,,,,,,,,,,, +Point Man,POINT MAN,,,,,,,,,,,,,,,,,,,,,, +Medic,MEDIC,,,,,,,,,,,,,,,,,,,,,, +Squad Leader,SQUAD LEADER,,,,,,,,,,,,,,,,,,,,,, +Killed In Action,KILLED IN ACTION,,,,,,,,,,,,,,,,,,,,,, +Booby Trap Disarmed,BOOBY TRAP DISARMED,,,,,,,,,,,,,,,,,,,,,, +M-60 Machine Gun [Press Space To Fire],M-60 MACHINE GUN [PRESS SPACE TO FIRE],,,,,,,,,,,,,,,,,,,,,, +[Drop Ammo],[DROP AMMO],,,,,,,,,,,,,,,,,,,,,, +[C-4],[C-4],,,,,,,,,,,,,,,,,,,,,, +[Flare],[FLARE],,,,,,,,,,,,,,,,,,,,,, +[Heal],[HEAL],,,,,,,,,,,,,,,,,,,,,, +[Fire Mission],[FIRE MISSION],,,,,,,,,,,,,,,,,,,,,, +[More Ammo],[MORE AMMO],,,,,,,,,,,,,,,,,,,,,, +Medical Supplies,MEDICAL SUPPLIES,,,,,,,,,,,,,,,,,,,,,, +Viet Cong Ammunition,VIET CONG AMMUNITION,,,,,,,,,,,,,,,,,,,,,, +Rotten Food,ROTTEN FOOD,,,,,,,,,,,,,,,,,,,,,, +Sniper Rifle!,SNIPER RIFLE!,,,,,,,,,,,,,,,,,,,,,, +60mm Mortar,60MM MORTAR,,,,,,,,,,,,,,,,,,,,,, +Ammo For 60mm Mortar!,AMMO FOR 60MM MORTAR!,,,,,,,,,,,,,,,,,,,,,, +Shortest [ 1] 2 3 4 5 6 7 Longest,SHORTEST [ 1] 2 3 4 5 6 7 LONGEST,,,,,,,,,,,,,,,,,,,,,, +Shortest 1 [ 2] 3 4 5 6 7 Longest,SHORTEST 1 [ 2] 3 4 5 6 7 LONGEST,,,,,,,,,,,,,,,,,,,,,, +Shortest 1 2 [ 3] 4 5 6 7 Longest,SHORTEST 1 2 [ 3] 4 5 6 7 LONGEST,,,,,,,,,,,,,,,,,,,,,, +Shortest 1 2 3 [ 4] 5 6 7 Longest,SHORTEST 1 2 3 [ 4] 5 6 7 LONGEST,,,,,,,,,,,,,,,,,,,,,, +Shortest 1 2 3 4 [ 5] 6 7 Longest,SHORTEST 1 2 3 4 [ 5] 6 7 LONGEST,,,,,,,,,,,,,,,,,,,,,, +Shortest 1 2 3 4 5 [ 6] 7 Longest,SHORTEST 1 2 3 4 5 [ 6] 7 LONGEST,,,,,,,,,,,,,,,,,,,,,, +Shortest 1 2 3 4 5 6 [ 7] Longest,SHORTEST 1 2 3 4 5 6 [ 7] LONGEST,,,,,,,,,,,,,,,,,,,,,, +Rifleman,RIFLEMAN,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Tour Of Duty I,TOUR OF DUTY I,,,,,,,,,,,,,,,,,,,,,, +Tour Of Duty Ii,TOUR OF DUTY II,,,,,,,,,,,,,,,,,,,,,, +Multiplayer I,MULTIPLAYER I,,,,,,,,,,,,,,,,,,,,,, +Multiplayer Ii,MULTIPLAYER II,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Boot,BOOT,,,,,,,,,,,,,,,,,,,,,, +Grunt,GRUNT,,,,,,,,,,,,,,,,,,,,,, +Salty,SALTY,,,,,,,,,,,,,,,,,,,,,, +Locked On,LOCKED ON,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Base Camp,BASE CAMP,,,,,,,,,,,,,,,,,,,,,, +Assault,ASSAULT,,,,,,,,,,,,,,,,,,,,,, +Hill 104,HILL 104,,,,,,,,,,,,,,,,,,,,,, +Contact Lost,CONTACT LOST,,,,,,,,,,,,,,,,,,,,,, +Huey Down,HUEY DOWN,,,,,,,,,,,,,,,,,,,,,, +Search And Destroy,SEARCH AND DESTROY,,,,,,,,,,,,,,,,,,,,,, +Pow Camp,POW CAMP,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Good Morning,GOOD MORNING,,,,,,,,,,,,,,,,,,,,,, +Village Sweep,VILLAGE SWEEP,,,,,,,,,,,,,,,,,,,,,, +Night Hunters,NIGHT HUNTERS,,,,,,,,,,,,,,,,,,,,,, +Payback Time,PAYBACK TIME,,,,,,,,,,,,,,,,,,,,,, +Casual Ties,CASUAL TIES,,,,,,,,,,,,,,,,,,,,,, +Bloody River,BLOODY RIVER,,,,,,,,,,,,,,,,,,,,,, +Platoonium,PLATOONIUM,,,,,,,,,,,,,,,,,,,,,, +Showdown In Saigon,SHOWDOWN IN SAIGON,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Beirut [Ctf],BEIRUT [CTF],,,,,,,,,,,,,,,,,,,,,, +Defend [Ctf],DEFEND [CTF],,,,,,,,,,,,,,,,,,,,,, +Jungle [Ctf],JUNGLE [CTF],,,,,,,,,,,,,,,,,,,,,, +Mortar Combat [Ctf],MORTAR COMBAT [CTF],,,,,,,,,,,,,,,,,,,,,, +Shack [Ctf],SHACK [CTF],,,,,,,,,,,,,,,,,,,,,, +Town [Ctf],TOWN [CTF],,,,,,,,,,,,,,,,,,,,,, +Casual Ties [Fireteam],CASUAL TIES [FIRETEAM],,,,,,,,,,,,,,,,,,,,,, +Night Hunters [Fireteam],NIGHT HUNTERS [FIRETEAM],,,,,,,,,,,,,,,,,,,,,, +Assault [Fireteam],ASSAULT [FIRETEAM],,,,,,,,,,,,,,,,,,,,,, +Contact Lost [Fireteam],CONTACT LOST [FIRETEAM],,,,,,,,,,,,,,,,,,,,,, +Search And Destroy [Fireteam],SEARCH AND DESTROY [FIRETEAM],,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Beirut [Gm],BEIRUT [GM],,,,,,,,,,,,,,,,,,,,,, +Chemical Factory [Gm],CHEMICAL FACTORY [GM],,,,,,,,,,,,,,,,,,,,,, +Command Post [Gm],COMMAND POST [GM],,,,,,,,,,,,,,,,,,,,,, +Dang Street [Gm],DANG STREET [GM],,,,,,,,,,,,,,,,,,,,,, +Desert Storm [Gm],DESERT STORM [GM],,,,,,,,,,,,,,,,,,,,,, +Guerrilla Warfare [Gm],GUERRILLA WARFARE [GM],,,,,,,,,,,,,,,,,,,,,, +Mall-Ice [Gm],MALL-ICE [GM],,,,,,,,,,,,,,,,,,,,,, +Middle East [Gm],MIDDLE EAST [GM],,,,,,,,,,,,,,,,,,,,,, +,WW2GI,,,,,,,,,,,,,,,,,,,,,, +Medikit,MEDIKIT,,,,,,,,,,,,,,,,,,,,,, +Explosives,EXPLOSIVES,,,,,,,,,,,,,,,,,,,,,, +Locked,LOCKED,,,,,,,,,,,,,,,,,,,,,, +Killed In Action...Press Open To Restart Level,KILLED IN ACTION...PRESS OPEN TO RESTART LEVEL,,,,,,,,,,,,,,,,,,,,,, +You Need 60mm Shells To Use Mortar,YOU NEED 60mm SHELLS TO USE MORTAR,,,,,,,,,,,,,,,,,,,,,, +M1 Thompson!,M1 THOMPSON!,,,,,,,,,,,,,,,,,,,,,, +Small Medikit,SMALL MEDIKIT,,,,,,,,,,,,,,,,,,,,,, +Chemical Mine!,CHEMICAL MINE!,,,,,,,,,,,,,,,,,,,,,, +Mine Placed,MINE PLACED,,,,,,,,,,,,,,,,,,,,,, +Disarming...,DISARMING...,,,,,,,,,,,,,,,,,,,,,, +Ordering Fire Mission,ORDERING FIRE MISSION,,,,,,,,,,,,,,,,,,,,,, +Fire Mission Cancelled,FIRE MISSION CANCELLED,,,,,,,,,,,,,,,,,,,,,, +All 88'S Aren't Destroyed Yet !!!,ALL 88'S AREN'T DESTROYED YET !!!,,,,,,,,,,,,,,,,,,,,,, +Browning Automatic Rifle!,BROWNING AUTOMATIC RIFLE!,,,,,,,,,,,,,,,,,,,,,, +Grenade!,GRENADE!,,,,,,,,,,,,,,,,,,,,,, +Bazooka!,BAZOOKA!,,,,,,,,,,,,,,,,,,,,,, +Mp40!,MP40!,,,,,,,,,,,,,,,,,,,,,, +Tnt!,TNT!,,,,,,,,,,,,,,,,,,,,,, +Flamethrower!,FLAMETHROWER!,,,,,,,,,,,,,,,,,,,,,, +Grenade Garand!,GRENADE GARAND!,,,,,,,,,,,,,,,,,,,,,, +Reloading Rocket Launcher,RELOADING ROCKET LAUNCHER,,,,,,,,,,,,,,,,,,,,,, +Small Medikit,SMALL MEDIKIT,,,,,,,,,,,,,,,,,,,,,, +Ammo For Browning Automatic Rifle!,AMMO FOR BROWNING AUTOMATIC RIFLE!,,,,,,,,,,,,,,,,,,,,,, +Radioman - Calling In Fire Mission (High Explosive),RADIOMAN - CALLING IN FIRE MISSION (HIGH EXPLOSIVE),,,,,,,,,,,,,,,,,,,,,, +Ammo For M1 Thompson!,AMMO FOR M1 THOMPSON!,,,,,,,,,,,,,,,,,,,,,, +Ammo For Colt 1911!,AMMO FOR COLT 1911!,,,,,,,,,,,,,,,,,,,,,, +Ammo For Sniper Rifle!,AMMO FOR SNIPER RIFLE!,,,,,,,,,,,,,,,,,,,,,, +Ammo For Mp40!,AMMO FOR MP40!,,,,,,,,,,,,,,,,,,,,,, +Colt 1911!,COLT 1911!,,,,,,,,,,,,,,,,,,,,,, +Private Mccurkee Dead,PRIVATE MCCURKEE DEAD,,,,,,,,,,,,,,,,,,,,,, +Defense System Malfunction,DEFENSE SYSTEM MALFUNCTION,,,,,,,,,,,,,,,,,,,,,, +Bazooka Shells,BAZOOKA SHELLS,,,,,,,,,,,,,,,,,,,,,, +Out Of Mortar Shells,OUT OF MORTAR SHELLS,,,,,,,,,,,,,,,,,,,,,, +Knife,KNIFE,,,,,,,,,,,,,,,,,,,,,, +60mm Shells For Mortar,60MM SHELLS FOR MORTAR,,,,,,,,,,,,,,,,,,,,,, +Mines,MINES,,,,,,,,,,,,,,,,,,,,,, +Smokes!,SMOKES!,,,,,,,,,,,,,,,,,,,,,, +Mine Detector,MINE DETECTOR,,,,,,,,,,,,,,,,,,,,,, +Mad Cow Mode Activated,MAD COW MODE ACTIVATED,,,,,,,,,,,,,,,,,,,,,, +All Locks Toggled,ALL LOCKS TOGGLED,,,,,,,,,,,,,,,,,,,,,, +Cigarettes,CIGARETTES,,,,,,,,,,,,,,,,,,,,,, +Mine Disarmed,MINE DISARMED,,,,,,,,,,,,,,,,,,,,,, +Screen Saved,SCREEN SAVED,,,,,,,,,,,,,,,,,,,,,, +Activate 60mm Shells To Use Mortar,ACTIVATE 60mm SHELLS TO USE MORTAR,,,,,,,,,,,,,,,,,,,,,, +Mine Ready,MINE READY,,,,,,,,,,,,,,,,,,,,,, +You Smoke Some Cigarettes,YOU SMOKE SOME CIGARETTES,,,,,,,,,,,,,,,,,,,,,, +Proceed Into Village,PROCEED INTO VILLAGE,,,,,,,,,,,,,,,,,,,,,, +Private Mccurkee - Following,PRIVATE McCURKEE - FOLLOWING,,,,,,,,,,,,,,,,,,,,,, +Private Mccurkee Dead,PRIVATE McCURKEE DEAD,,,,,,,,,,,,,,,,,,,,,, +Private Mccurkee - Awaiting Further Orders,PRIVATE McCURKEE - AWAITING FURTHER ORDERS,,,,,,,,,,,,,,,,,,,,,, +Cannot Load Multiplayer Game,CANNOT LOAD MULTIPLAYER GAME,,,,,,,,,,,,,,,,,,,,,, +Radioman - Can't Call In Fire Mission,RADIOMAN - CAN'T CALL IN FIRE MISSION,,,,,,,,,,,,,,,,,,,,,, +Medic - Following,MEDIC - FOLLOWING,,,,,,,,,,,,,,,,,,,,,, +Medic - Awaiting Further Orders,MEDIC - AWAITING FURTHER ORDERS,,,,,,,,,,,,,,,,,,,,,, +Demoman - Following,DEMOMAN - FOLLOWING,,,,,,,,,,,,,,,,,,,,,, +Demoman - Awaiting Further Orders,DEMOMAN - AWAITING FURTHER ORDERS,,,,,,,,,,,,,,,,,,,,,, +Demoman - Placing A Mine,DEMOMAN - PLACING A MINE,,,,,,,,,,,,,,,,,,,,,, +Demoman - Placing Explosives,DEMOMAN - PLACING EXPLOSIVES,,,,,,,,,,,,,,,,,,,,,, +Grunt - Following,GRUNT - FOLLOWING,,,,,,,,,,,,,,,,,,,,,, +Grunt - Awaiting Further Orders,GRUNT - AWAITING FURTHER ORDERS,,,,,,,,,,,,,,,,,,,,,, +Grunt - M-16 Ambush Mode,GRUNT - M-16 AMBUSH MODE,,,,,,,,,,,,,,,,,,,,,, +Radioman - Awaiting Further Orders,RADIOMAN - AWAITING FURTHER ORDERS,,,,,,,,,,,,,,,,,,,,,, +Can't Go Further Or You'll Drown,CAN'T GO FURTHER OR YOU'LL DROWN,,,,,,,,,,,,,,,,,,,,,, +Booze!,BOOZE!,,,,,,,,,,,,,,,,,,,,,, +Laser Loading,LASER LOADING,,,,,,,,,,,,,,,,,,,,,, +Laser Ready,LASER READY,,,,,,,,,,,,,,,,,,,,,, +You Are On The Blue Team,YOU ARE ON THE BLUE TEAM,,,,,,,,,,,,,,,,,,,,,, +You Are On The Red Team,YOU ARE ON THE RED TEAM,,,,,,,,,,,,,,,,,,,,,, +You Got The Enemy Flag...Take It Back To Your Banner,YOU GOT THE ENEMY FLAG...TAKE IT BACK TO YOUR BANNER,,,,,,,,,,,,,,,,,,,,,, +You Got The Beast Flag,YOU GOT THE BEAST FLAG,,,,,,,,,,,,,,,,,,,,,, +You Have Become A Beast,YOU HAVE BECOME A BEAST,,,,,,,,,,,,,,,,,,,,,, +Blue Team Wins,BLUE TEAM WINS,,,,,,,,,,,,,,,,,,,,,, +Red Team Wins,RED TEAM WINS,,,,,,,,,,,,,,,,,,,,,, +Mines ( 5),MINES ( 5),,,,,,,,,,,,,,,,,,,,,, +Medikit Used,MEDIKIT USED,,,,,,,,,,,,,,,,,,,,,, +Explosives,EXPLOSIVES,,,,,,,,,,,,,,,,,,,,,, +Explosives Placed,EXPLOSIVES PLACED,,,,,,,,,,,,,,,,,,,,,, +Press Space To View Map,PRESS SPACE TO VIEW MAP,,,,,,,,,,,,,,,,,,,,,, +Can't Pick Up Artillery Ammo,CAN'T PICK UP ARTILLERY AMMO,,,,,,,,,,,,,,,,,,,,,, +Booze!,BOOZE!,,,,,,,,,,,,,,,,,,,,,, +Booby Trap !!!,BOOBY TRAP !!!,,,,,,,,,,,,,,,,,,,,,, +Mine Detector,MINE DETECTOR,,,,,,,,,,,,,,,,,,,,,, +Radioman - Calling In Fire Mission (Smoke),RADIOMAN - CALLING IN FIRE MISSION (SMOKE),,,,,,,,,,,,,,,,,,,,,, +Ammo For M2machine Gun!,AMMO FOR M2MACHINE GUN!,,,,,,,,,,,,,,,,,,,,,, +M2machine Gun [Press Space To Fire],M2MACHINE GUN [PRESS SPACE TO FIRE],,,,,,,,,,,,,,,,,,,,,, +You're Bleeding,YOU'RE BLEEDING,,,,,,,,,,,,,,,,,,,,,, +A-Gunner,A-GUNNER,,,,,,,,,,,,,,,,,,,,,, +Machine Gunner,MACHINE GUNNER,,,,,,,,,,,,,,,,,,,,,, +Sniper,SNIPER,,,,,,,,,,,,,,,,,,,,,, +Grenadier,GRENADIER,,,,,,,,,,,,,,,,,,,,,, +Point Man,POINT MAN,,,,,,,,,,,,,,,,,,,,,, +Medic,MEDIC,,,,,,,,,,,,,,,,,,,,,, +Squad Leader,SQUAD LEADER,,,,,,,,,,,,,,,,,,,,,, +Killed In Action,KILLED IN ACTION,,,,,,,,,,,,,,,,,,,,,, +Booby Trap Disarmed,BOOBY TRAP DISARMED,,,,,,,,,,,,,,,,,,,,,, +M-60 Machine Gun [Press Space To Fire],M-60 MACHINE GUN [PRESS SPACE TO FIRE],,,,,,,,,,,,,,,,,,,,,, +[Drop Ammo],[DROP AMMO],,,,,,,,,,,,,,,,,,,,,, +[C-4],[C-4],,,,,,,,,,,,,,,,,,,,,, +[Flare],[FLARE],,,,,,,,,,,,,,,,,,,,,, +[Heal],[HEAL],,,,,,,,,,,,,,,,,,,,,, +[Fire Mission],[FIRE MISSION],,,,,,,,,,,,,,,,,,,,,, +[More Ammo],[MORE AMMO],,,,,,,,,,,,,,,,,,,,,, +Medical Supplies,MEDICAL SUPPLIES,,,,,,,,,,,,,,,,,,,,,, +Viet Cong Ammunition,VIET CONG AMMUNITION,,,,,,,,,,,,,,,,,,,,,, +Rotten Food,ROTTEN FOOD,,,,,,,,,,,,,,,,,,,,,, +Sniper Rifle!,SNIPER RIFLE!,,,,,,,,,,,,,,,,,,,,,, +60mm Mortar,60MM MORTAR,,,,,,,,,,,,,,,,,,,,,, +Defend This Position Until Further Orders,DEFEND THIS POSITION UNTIL FURTHER ORDERS,,,,,,,,,,,,,,,,,,,,,, +Shortest }{{{{{{ Longest,SHORTEST }{{{{{{ LONGEST,,,,,,,,,,,,,,,,,,,,,, +Shortest }}{{{{{ Longest,SHORTEST }}{{{{{ LONGEST,,,,,,,,,,,,,,,,,,,,,, +Shortest }}}{{{{ Longest,SHORTEST }}}{{{{ LONGEST,,,,,,,,,,,,,,,,,,,,,, +Shortest }}}}{{{ Longest,SHORTEST }}}}{{{ LONGEST,,,,,,,,,,,,,,,,,,,,,, +Shortest }}}}}{{ Longest,SHORTEST }}}}}{{ LONGEST,,,,,,,,,,,,,,,,,,,,,, +Shortest }}}}}}{ Longest,SHORTEST }}}}}}{ LONGEST,,,,,,,,,,,,,,,,,,,,,, +Shortest }}}}}}} Longest,SHORTEST }}}}}}} LONGEST,,,,,,,,,,,,,,,,,,,,,, +Engineer,ENGINEER,,,,,,,,,,,,,,,,,,,,,, +Can't Proceed Without Private Mccurkee!,CAN'T PROCEED WITHOUT PRIVATE McCURKEE!,,,,,,,,,,,,,,,,,,,,,, +Using A Special Skill...,USING A SPECIAL SKILL...,,,,,,,,,,,,,,,,,,,,,, +Defend This Position Until Reinforcements Arrive,DEFEND THIS POSITION UNTIL REINFORCEMENTS ARRIVE,,,,,,,,,,,,,,,,,,,,,, +Reinforcements Have Arrived,REINFORCEMENTS HAVE ARRIVED,,,,,,,,,,,,,,,,,,,,,, +< Empty >,< EMPTY >,,,,,,,,,,,,,,,,,,,,,, +Your Morale Is Weakening,YOUR MORALE IS WEAKENING,,,,,,,,,,,,,,,,,,,,,, +You Are Panicking,YOU ARE PANICKING,,,,,,,,,,,,,,,,,,,,,, +You Are Becoming Insane,YOU ARE BECOMING INSANE,,,,,,,,,,,,,,,,,,,,,, +Giving Firstaid...,GIVING FIRSTAID...,,,,,,,,,,,,,,,,,,,,,, +Mine Detector On,MINE DETECTOR ON,,,,,,,,,,,,,,,,,,,,,, +Giving Firstaid Fast...,GIVING FIRSTAID FAST...,,,,,,,,,,,,,,,,,,,,,, +Mine Detector Off,MINE DETECTOR OFF,,,,,,,,,,,,,,,,,,,,,, +You Are In Red Team,YOU ARE IN RED TEAM,,,,,,,,,,,,,,,,,,,,,, +You Are In Blue Team,YOU ARE IN BLUE TEAM,,,,,,,,,,,,,,,,,,,,,, +Choose Team,CHOOSE TEAM,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +D Day,D DAY,,,,,,,,,,,,,,,,,,,,,, +France,FRANCE,,,,,,,,,,,,,,,,,,,,,, +Multiplayer I,MULTIPLAYER I,,,,,,,,,,,,,,,,,,,,,, +Multiplayer Ii,MULTIPLAYER II,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Draftee,DRAFTEE,,,,,,,,,,,,,,,,,,,,,, +GI,GI,,,,,,,,,,,,,,,,,,,,,, +Paratrooper,PARATROOPER,,,,,,,,,,,,,,,,,,,,,, +Veteran,VETERAN,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Atlantic Wall,ATLANTIC WALL,,,,,,,,,,,,,,,,,,,,,, +Defend,DEFEND,,,,,,,,,,,,,,,,,,,,,, +Hunt For The 88'S,HUNT FOR THE 88'S,,,,,,,,,,,,,,,,,,,,,, +Finding Private Mccurkee,FINDING PRIVATE McCURKEE,,,,,,,,,,,,,,,,,,,,,, +Saving Private Mccurkee,SAVING PRIVATE McCURKEE,,,,,,,,,,,,,,,,,,,,,, +Mop Up,MOP UP,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Hell From Above,HELL FROM ABOVE,,,,,,,,,,,,,,,,,,,,,, +Seaside Sweep,SEASIDE SWEEP,,,,,,,,,,,,,,,,,,,,,, +Under Fire,UNDER FIRE,,,,,,,,,,,,,,,,,,,,,, +Paperwork,PAPERWORK,,,,,,,,,,,,,,,,,,,,,, +Railroad Typhoon,RAILROAD TYPHOON,,,,,,,,,,,,,,,,,,,,,, +A Game Of Bridge,A GAME OF BRIDGE,,,,,,,,,,,,,,,,,,,,,, +Urban Rush,URBAN RUSH,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Mole Hill [Gimatch],MOLE HILL [GIMATCH],,,,,,,,,,,,,,,,,,,,,, +Monastery [Gimatch],MONASTERY [GIMATCH],,,,,,,,,,,,,,,,,,,,,, +Cavefear2 [Gimatch],CAVEFEAR2 [GIMATCH],,,,,,,,,,,,,,,,,,,,,, +Bastogne Boyz [Gimatch],BASTOGNE BOYZ [GIMATCH],,,,,,,,,,,,,,,,,,,,,, +Small Town [Gimatch],SMALL TOWN [GIMATCH],,,,,,,,,,,,,,,,,,,,,, +Town Ruins [Gimatch],TOWN RUINS [GIMATCH],,,,,,,,,,,,,,,,,,,,,, +Fuhrer's Bunker [Gimatch],FUHRER'S BUNKER [GIMATCH],,,,,,,,,,,,,,,,,,,,,, +Good Night [Gimatch],GOOD NIGHT [GIMATCH],,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +D Day [Fireteam],D DAY [FIRETEAM],,,,,,,,,,,,,,,,,,,,,, +Seaside Sweep [Fireteam],SEASIDE SWEEP [FIRETEAM],,,,,,,,,,,,,,,,,,,,,, +Paperwork [Fireteam],PAPERWORK [FIRETEAM],,,,,,,,,,,,,,,,,,,,,, +Hunt For The 88'S [Fireteam],HUNT FOR THE 88'S [FIRETEAM],,,,,,,,,,,,,,,,,,,,,, +D Day [Ctf],D DAY [CTF],,,,,,,,,,,,,,,,,,,,,, +City In Ruins [Ctf],CITY IN RUINS [CTF],,,,,,,,,,,,,,,,,,,,,, +Hedgerow Hell [Ctf],HEDGEROW HELL [CTF],,,,,,,,,,,,,,,,,,,,,, +Casino De Ouistreham [Ctf],CASINO DE OUISTREHAM [CTF],,,,,,,,,,,,,,,,,,,,,, +,Redneck Rampage,,,,,,,,,,,,,,,,,,,,,, +Auto Aimin'...,AUTO AIMIN'...,,,,,,,,,,,,,,,,,,,,,, +Show Yer Map: OFF,SHOW YER MAP: OFF,,,,,,,,,,,,,,,,,,,,,, +Turned On!,TURNED ON!,,,,,,,,,,,,,,,,,,,,,, +Cheap Ass Whiskey...,CHEAP ASS WHISKEY...,,,,,,,,,,,,,,,,,,,,,, +Locked!,LOCKED!,,,,,,,,,,,,,,,,,,,,,, +Take It All!,TAKE IT ALL!,,,,,,,,,,,,,,,,,,,,,, +Hip Waders...,HIP WADERS...,,,,,,,,,,,,,,,,,,,,,, +Wasted!,WASTED!,,,,,,,,,,,,,,,,,,,,,, +Unlocked,UNLOCKED,,,,,,,,,,,,,,,,,,,,,, +Yer Secret Place!,YER SECRET PLACE!,,,,,,,,,,,,,,,,,,,,,, +Squashed Like A Bug!,SQUASHED LIKE A BUG!,,,,,,,,,,,,,,,,,,,,,, +All Doors Unlocked,ALL DOORS UNLOCKED,,,,,,,,,,,,,,,,,,,,,, +You's On A Rampage!!!,YOU'S ON A RAMPAGE!!!,,,,,,,,,,,,,,,,,,,,,, +Mash Activator Key To Kill Again!,MASH ACTIVATOR KEY TO KILL AGAIN!,,,,,,,,,,,,,,,,,,,,,, +Ammo For Alien Arm Gun!!!,AMMO FOR ALIEN ARM GUN!!!,,,,,,,,,,,,,,,,,,,,,, +Turned Off...,TURNED OFF...,,,,,,,,,,,,,,,,,,,,,, +Switch Operated Only!,SWITCH OPERATED ONLY!,,,,,,,,,,,,,,,,,,,,,, +Elvis Lives!,ELVIS LIVES!,,,,,,,,,,,,,,,,,,,,,, +The King Is Dead!,THE KING IS DEAD!,,,,,,,,,,,,,,,,,,,,,, +Dee-Lishus Goo Goo Cluster!,DEE-LISHUS GOO GOO CLUSTER!,,,,,,,,,,,,,,,,,,,,,, +Wussy Aimin' Device: ON,WUSSY AIMIN' DEVICE: ON,,,,,,,,,,,,,,,,,,,,,, +Wussy Aimin' Device: OFF,WUSSY AIMIN' DEVICE: OFF,,,,,,,,,,,,,,,,,,,,,, +"Hell, I Thought You Was A Killbilly!","HELL, I THOUGHT YOU WAS A KILLBILLY!",,,,,,,,,,,,,,,,,,,,,, +Writin': ON,WRITIN': ON,,,,,,,,,,,,,,,,,,,,,, +Writin': OFF,WRITIN': OFF,,,,,,,,,,,,,,,,,,,,,, +Type The Cheat Code:,TYPE THE CHEAT CODE:,,,,,,,,,,,,,,,,,,,,,, +Yer Sound: ON,YER SOUND: ON,,,,,,,,,,,,,,,,,,,,,, +Yer Sound: OFF,YER SOUND: OFF,,,,,,,,,,,,,,,,,,,,,, +Yer Screen Captured And Jailed!,YER SCREEN CAPTURED AND JAILED!,,,,,,,,,,,,,,,,,,,,,, +Xxx Moonshine!,XXX MOONSHINE!,,,,,,,,,,,,,,,,,,,,,, +Vacuum Cleaner Hose Snorkel System,VACUUM CLEANER HOSE SNORKEL SYSTEM,,,,,,,,,,,,,,,,,,,,,, +Press F1 Fer Help,PRESS F1 FER HELP,,,,,,,,,,,,,,,,,,,,,, +Ain't Got The Key!,AIN'T GOT THE KEY!,,,,,,,,,,,,,,,,,,,,,, +Skeleton Key!,SKELETON KEY!,,,,,,,,,,,,,,,,,,,,,, +Rat Aimin' Off,RAT AIMIN' OFF,,,,,,,,,,,,,,,,,,,,,, +Rat Aimin' On,RAT AIMIN' ON,,,,,,,,,,,,,,,,,,,,,, +Cheat Code: Unrecognized,CHEAT CODE: UNRECOGNIZED,,,,,,,,,,,,,,,,,,,,,, +Teat Gun Ammo !,TEAT GUN AMMO !,,,,,,,,,,,,,,,,,,,,,, +Ripsaw Ammo !,RIPSAW AMMO !,,,,,,,,,,,,,,,,,,,,,, +Cheater! You Used The,CHEATER! YOU USED THE,,,,,,,,,,,,,,,,,,,,,, +Cheat To Come Back Alive,CHEAT TO COME BACK ALIVE,,,,,,,,,,,,,,,,,,,,,, +No Savin' Or Loadin' Fer Psyco,NO SAVIN' OR LOADIN' FER PSYCO,,,,,,,,,,,,,,,,,,,,,, +Huntin' Rifle!,HUNTIN' RIFLE!,,,,,,,,,,,,,,,,,,,,,, +Dyn-O-Mite!,DYN-O-MITE!,,,,,,,,,,,,,,,,,,,,,, +Crossbow!,CROSSBOW!,,,,,,,,,,,,,,,,,,,,,, +Yer Scattergun!,YER SCATTERGUN!,,,,,,,,,,,,,,,,,,,,,, +Powder Keg!,POWDER KEG!,,,,,,,,,,,,,,,,,,,,,, +Alien Teat Gun!,ALIEN TEAT GUN!,,,,,,,,,,,,,,,,,,,,,, +Bowling Ball!!,BOWLING BALL!!,,,,,,,,,,,,,,,,,,,,,, +Ripsaw!!,RIPSAW!!,,,,,,,,,,,,,,,,,,,,,, +Large Pork Rinds!,LARGE PORK RINDS!,,,,,,,,,,,,,,,,,,,,,, +Ammo For Rifle!,AMMO FOR RIFLE!,,,,,,,,,,,,,,,,,,,,,, +Ammo For Crossbow!,AMMO FOR CROSSBOW!,,,,,,,,,,,,,,,,,,,,,, +Speedloader!,SPEEDLOADER!,,,,,,,,,,,,,,,,,,,,,, +Hip Waders Off,HIP WADERS OFF,,,,,,,,,,,,,,,,,,,,,, +Hip Waders On,HIP WADERS ON,,,,,,,,,,,,,,,,,,,,,, +Yer Scattergun Shells!,YER SCATTERGUN SHELLS!,,,,,,,,,,,,,,,,,,,,,, +Some Kind Of Key Required,SOME KIND OF KEY REQUIRED,,,,,,,,,,,,,,,,,,,,,, +Some Other Kind Of Key Required,SOME OTHER KIND OF KEY REQUIRED,,,,,,,,,,,,,,,,,,,,,, +Yet Even Another Kind Of Key Required,YET EVEN ANOTHER KIND OF KEY REQUIRED,,,,,,,,,,,,,,,,,,,,,, +Yer Weapon Lowered,YER WEAPON LOWERED,,,,,,,,,,,,,,,,,,,,,, +Yer Weapon Raised,YER WEAPON RAISED,,,,,,,,,,,,,,,,,,,,,, +Hip Waders On,HIP WADERS ON,,,,,,,,,,,,,,,,,,,,,, +Vaccum Cleaner Hose Snorkel On!,VACCUM CLEANER HOSE SNORKEL ON!,,,,,,,,,,,,,,,,,,,,,, +Haulin' Ass Mode Off...,HAULIN' ASS MODE OFF...,,,,,,,,,,,,,,,,,,,,,, +Haulin' Ass Mode On!!!,HAULIN' ASS MODE ON!!!,,,,,,,,,,,,,,,,,,,,,, +Alien Arm Gun,ALIEN ARM GUN,,,,,,,,,,,,,,,,,,,,,, +Cow Pie!,COW PIE!,,,,,,,,,,,,,,,,,,,,,, +Vacuum Cleaner Snorkle,VACUUM CLEANER SNORKLE,,,,,,,,,,,,,,,,,,,,,, +Xxx Moonshine,XXX MOONSHINE,,,,,,,,,,,,,,,,,,,,,, +Beer,BEER,,,,,,,,,,,,,,,,,,,,,, +For You Grandpa!,FOR YOU GRANDPA!,,,,,,,,,,,,,,,,,,,,,, +All Locks Toggled,ALL LOCKS TOGGLED,,,,,,,,,,,,,,,,,,,,,, +What The!,WHAT THE!,,,,,,,,,,,,,,,,,,,,,, +You Were All Wrong!,YOU WERE ALL WRONG!,,,,,,,,,,,,,,,,,,,,,, +Good'n!,GOOD'N!,,,,,,,,,,,,,,,,,,,,,, +Bad'n...,BAD'N...,,,,,,,,,,,,,,,,,,,,,, +You're Burnin'!,YOU'RE BURNIN'!,,,,,,,,,,,,,,,,,,,,,, +Clippin': OFF,CLIPPIN': OFF,,,,,,,,,,,,,,,,,,,,,, +Clippin': ON,CLIPPIN': ON,,,,,,,,,,,,,,,,,,,,,, +You Done Killed 'Em All!,YOU DONE KILLED 'EM ALL!,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Outskirts,OUTSKIRTS,,,,,,,,,,,,,,,,,,,,,, +Downtown,DOWNTOWN,,,,,,,,,,,,,,,,,,,,,, +Pissin' Contest,PISSIN' CONTEST,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Wuss,WUSS,,,,,,,,,,,,,,,,,,,,,, +Meejum,MEEJUM,,,,,,,,,,,,,,,,,,,,,, +Hard Ass,HARD ASS,,,,,,,,,,,,,,,,,,,,,, +Killbilly,KILLBILLY,,,,,,,,,,,,,,,,,,,,,, +Psychobilly,PSYCHOBILLY,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Taylor Town,TAYLOR TOWN,,,,,,,,,,,,,,,,,,,,,, +Lumberland,LUMBERLAND,,,,,,,,,,,,,,,,,,,,,, +Junkyard,JUNKYARD,,,,,,,,,,,,,,,,,,,,,, +Drive-In,DRIVE-IN,,,,,,,,,,,,,,,,,,,,,, +Dairyair Farms,DAIRYAIR FARMS,,,,,,,,,,,,,,,,,,,,,, +Sewers,SEWERS,,,,,,,,,,,,,,,,,,,,,, +Smeltin' Plant,SMELTIN' PLANT,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Downtown Hickston,DOWNTOWN HICKSTON,,,,,,,,,,,,,,,,,,,,,, +Nut House,NUT HOUSE,,,,,,,,,,,,,,,,,,,,,, +J.Cluck's!,J.CLUCK'S!,,,,,,,,,,,,,,,,,,,,,, +The Ruins,THE RUINS,,,,,,,,,,,,,,,,,,,,,, +Grimley's Mortuary,GRIMLEY'S MORTUARY,,,,,,,,,,,,,,,,,,,,,, +Uranium Mines,URANIUM MINES,,,,,,,,,,,,,,,,,,,,,, +Beaudry Mansion,BEAUDRY MANSION,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Country Livin',COUNTRY LIVIN',,,,,,,,,,,,,,,,,,,,,, +Barnyard Hijinks,BARNYARD HIJINKS,,,,,,,,,,,,,,,,,,,,,, +Condemned,CONDEMNED,,,,,,,,,,,,,,,,,,,,,, +Used Cars,USED CARS,,,,,,,,,,,,,,,,,,,,,, +Trainspotting,TRAINSPOTTING,,,,,,,,,,,,,,,,,,,,,, +Mud Alley!,MUD ALLEY!,,,,,,,,,,,,,,,,,,,,,, +The Factory,THE FACTORY,,,,,,,,,,,,,,,,,,,,,, +,Redneck Rides again,,,,,,,,,,,,,,,,,,,,,, +Got Some Wheels!,GOT SOME WHEELS!,,,,,,,,,,,,,,,,,,,,,, +Ohhhhhhh Noooooooooooo!,OHHHHHHH NOOOOOOOOOOOO!,,,,,,,,,,,,,,,,,,,,,, +Now Yer Fucked!!!,NOW YER FUCKED!!!,,,,,,,,,,,,,,,,,,,,,, +Boat Mode Off,BOAT MODE OFF,,,,,,,,,,,,,,,,,,,,,, +No More Cheatin',NO MORE CHEATIN',,,,,,,,,,,,,,,,,,,,,, +Instadrunk!,INSTADRUNK!,,,,,,,,,,,,,,,,,,,,,, +Instasober,INSTASOBER,,,,,,,,,,,,,,,,,,,,,, +Sea Sick Mode On,SEA SICK MODE ON,,,,,,,,,,,,,,,,,,,,,, +Sea Sick Mode Off,SEA SICK MODE OFF,,,,,,,,,,,,,,,,,,,,,, +Motorcycle Gun Ammo!,MOTORCYCLE GUN AMMO!,,,,,,,,,,,,,,,,,,,,,, +Got A Boat!,GOT A BOAT!,,,,,,,,,,,,,,,,,,,,,, +Boat Mode On,BOAT MODE ON,,,,,,,,,,,,,,,,,,,,,, +Boat Gun Mortars!,BOAT GUN MORTARS!,,,,,,,,,,,,,,,,,,,,,, +Chicken Mode!!!!!!!!,CHICKEN MODE!!!!!!!!,,,,,,,,,,,,,,,,,,,,,, +Chicken Crossbow Ammo!!,CHICKEN CROSSBOW AMMO!!,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Land Of The Lost,LAND OF THE LOST,,,,,,,,,,,,,,,,,,,,,, +Homeward Bound,HOMEWARD BOUND,,,,,,,,,,,,,,,,,,,,,, +Pissin' Contest,PISSIN' CONTEST,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Area 69,AREA 69,,,,,,,,,,,,,,,,,,,,,, +Camino Del Diablo,CAMINO DEL DIABLO,,,,,,,,,,,,,,,,,,,,,, +El Peso,EL PESO,,,,,,,,,,,,,,,,,,,,,, +Jack O' Lope Farm,JACK O' LOPE FARM,,,,,,,,,,,,,,,,,,,,,, +Wako,WAKO,,,,,,,,,,,,,,,,,,,,,, +"El Peso, Again","EL PESO, AGAIN",,,,,,,,,,,,,,,,,,,,,, +Refinery,REFINERY,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Sunny Shores,SUNNY SHORES,,,,,,,,,,,,,,,,,,,,,, +Gamblin' Boat,GAMBLIN' BOAT,,,,,,,,,,,,,,,,,,,,,, +Lummockston,LUMMOCKSTON,,,,,,,,,,,,,,,,,,,,,, +Disgraceland,DISGRACELAND,,,,,,,,,,,,,,,,,,,,,, +Moto Madness,MOTO MADNESS,,,,,,,,,,,,,,,,,,,,,, +Brothel,BROTHEL,,,,,,,,,,,,,,,,,,,,,, +Back To Hickston,BACK TO HICKSTON,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Pipe Dreams,PIPE DREAMS,,,,,,,,,,,,,,,,,,,,,, +Swamp Buggies,SWAMP BUGGIES,,,,,,,,,,,,,,,,,,,,,, +Square Dancin',SQUARE DANCIN',,,,,,,,,,,,,,,,,,,,,, +Hog Wild,HOG WILD,,,,,,,,,,,,,,,,,,,,,, +Road Rage,ROAD RAGE,,,,,,,,,,,,,,,,,,,,,, +Snake Canyon,SNAKE CANYON,,,,,,,,,,,,,,,,,,,,,, +Luck Sore,LUCK SORE,,,,,,,,,,,,,,,,,,,,,, +,Route 66,,,,,,,,,,,,,,,,,,,,,, +Route 66 - Part 1,ROUTE 66 - PART 1,,,,,,,,,,,,,,,,,,,,,, +Route 66 - Part 2,ROUTE 66 - PART 2,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Hit The Road,HIT THE ROAD,,,,,,,,,,,,,,,,,,,,,, +Carnival Of Terror,CARNIVAL OF TERROR,,,,,,,,,,,,,,,,,,,,,, +Big Bertha's,BIG BERTHA'S,,,,,,,,,,,,,,,,,,,,,, +Big Billy's Brewery,BIG BILLY'S BREWERY,,,,,,,,,,,,,,,,,,,,,, +Flea Market,FLEA MARKET,,,,,,,,,,,,,,,,,,,,,, +Slaughterhouse,SLAUGHTERHOUSE,,,,,,,,,,,,,,,,,,,,,, +Fun Park,FUN PARK,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Gassin' Up,GASSIN' UP,,,,,,,,,,,,,,,,,,,,,, +House Of Ill Repute,HOUSE OF ILL REPUTE,,,,,,,,,,,,,,,,,,,,,, +Mystery Dino Cave,MYSTERY DINO CAVE,,,,,,,,,,,,,,,,,,,,,, +Campy Crystal Lake,CAMPY CRYSTAL LAKE,,,,,,,,,,,,,,,,,,,,,, +Bigfoot Convention,BIGFOOT CONVENTION,,,,,,,,,,,,,,,,,,,,,, +Hoover Dam,HOOVER DAM,,,,,,,,,,,,,,,,,,,,,, +Oddity Museum,ODDITY MUSEUM,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 2fdea0f10..2243dd2a1 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -60,12 +60,22 @@ LISTMENU "MainMenu" } ifgame(ShadowWarrior) { + Position 55, 32 + Linespacing 17 + class "ShadowWarrior.MainMenu" NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" //NativeTextItem "$MNU_COOLSTUFF", "h", "HelpMenu" // Perfectly useless retro ads. :D - NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" + ifshareware(false) + { + NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" + } + else + { + NativeTextItem "$MNU_HOWTOORDER", "h", "CreditsMenu" + } NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" } } @@ -126,12 +136,21 @@ LISTMENU "IngameMenu" } ifgame(ShadowWarrior) { - linespacing 15 + Position 55, 32 + Linespacing 17 + class "ShadowWarrior.MainMenu" NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" - NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" + ifshareware(false) + { + NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" + } + else + { + NativeTextItem "$MNU_HOWTOORDER", "h", "CreditsMenu" + } NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" } } @@ -168,6 +187,13 @@ LISTMENU "EpisodeMenu" centermenu Linespacing 20 } + ifgame(ShadowWarrior) + { + caption "$MNU_EPISODES" + Position 35, 32 + Linespacing 17 + } + ScriptId 100 } @@ -206,6 +232,12 @@ LISTMENU "SkillMenu" centermenu Linespacing 20 } + ifgame(ShadowWarrior) + { + caption "$MNU_DIFFICULTY" + Position 35, 32 + Linespacing 17 + } ScriptId 110 } From 13c7dcecf6539314e9c43ffd13c374ea161a416f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 14:53:13 +0100 Subject: [PATCH 143/203] - exported all game relevant texts from Duke Nukem and Redneck Rampage. --- source/duke3d/src/cheats.cpp | 6 +- source/duke3d/src/demo.cpp | 2 +- source/duke3d/src/game.cpp | 4 +- source/duke3d/src/gamedef.cpp | 2 + source/duke3d/src/network.cpp | 28 +++++----- source/duke3d/src/premap.cpp | 14 +++-- source/duke3d/src/sbar.cpp | 12 ++-- source/duke3d/src/screens.cpp | 62 ++++++++++----------- source/rr/src/cheats.cpp | 4 +- source/rr/src/demo.cpp | 2 +- source/rr/src/game.cpp | 4 +- source/rr/src/premap.cpp | 15 ++--- source/rr/src/sbar.cpp | 12 ++-- source/rr/src/screens.cpp | 100 +++++++++++++++++----------------- 14 files changed, 136 insertions(+), 131 deletions(-) diff --git a/source/duke3d/src/cheats.cpp b/source/duke3d/src/cheats.cpp index 4f9e9e7ba..5320822de 100644 --- a/source/duke3d/src/cheats.cpp +++ b/source/duke3d/src/cheats.cpp @@ -493,7 +493,7 @@ void G_DoCheats(void) } else { - quoteMgr.InitializeQuote(QUOTE_RESERVED4, "Come Get Some!"); + quoteMgr.InitializeQuote(QUOTE_RESERVED4, "$COMEGETSOME"); S_PlaySound(DUKE_GETWEAPON2); P_DoQuote(QUOTE_RESERVED4, pPlayer); @@ -679,12 +679,12 @@ void G_DoCheats(void) case CHEAT_MONSTERS: { - const char *s [] = { "On", "Off", "On (2)" }; + const char *s [] = { "OPTVAL_ON", "OPTVAL_OFF", "$TXT_ON2" }; if (++g_noEnemies == 3) g_noEnemies = 0; - quoteMgr.InitializeQuote(QUOTE_RESERVED4, "Monsters: %s", s[g_noEnemies]); + quoteMgr.FormatQuote(QUOTE_RESERVED4, "%s: %s", GStrings("NETMNU_MONSTERS"), s[g_noEnemies]); P_DoQuote(QUOTE_RESERVED4, pPlayer); end_cheat(pPlayer); diff --git a/source/duke3d/src/demo.cpp b/source/duke3d/src/demo.cpp index 0a2b00ddf..9410c395f 100644 --- a/source/duke3d/src/demo.cpp +++ b/source/duke3d/src/demo.cpp @@ -846,7 +846,7 @@ nextdemo_nomenu: Net_GetPackets(); if (g_player[myconnectindex].gotvote == 0 && voting != -1 && voting != myconnectindex) - gametext_center(60, "Press F1 to Accept, F2 to Decline"); + gametext_center(60, GStrings("TXT_PRESSF1_F2")); } if ((g_player[myconnectindex].ps->gm&MODE_MENU) && (g_player[myconnectindex].ps->gm&MODE_EOL)) diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 800b3a152..3a09f1e02 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -4475,7 +4475,7 @@ void G_HandleLocalKeys(void) { if (inputState.UnboundKeyPressed(sc_F1) || inputState.UnboundKeyPressed(sc_F2) || cl_autovote) { - G_AddUserQuote("Vote Cast"); + G_AddUserQuote(GStrings("VoteCast")); Net_SendMapVote(inputState.UnboundKeyPressed(sc_F1) || cl_autovote ? cl_autovote-1 : 0); inputState.ClearKeyStatus(sc_F1); inputState.ClearKeyStatus(sc_F2); @@ -5931,7 +5931,7 @@ int GameInterface::app_main() for (int i=1, j=numplayers; jteam = g_player[j].pteam = i; g_player[j].ps->weaponswitch = 3; g_player[j].ps->auto_aim = 0; diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index a60d046af..9e1e7283d 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -2172,6 +2172,7 @@ int32_t C_AllocQuote(int32_t qnum) void C_InitQuotes(void) { +#if 0 auto openkeys = Bindings.GetKeysForCommand("+open"); if (openkeys.Size()) { @@ -2180,6 +2181,7 @@ void C_InitQuotes(void) quoteMgr.Substitute(QUOTE_DEAD, "OPEN", OpenGameFunc); quoteMgr.Substitute(QUOTE_DEAD, "USE", OpenGameFunc); } +#endif g_numObituaries = 48; for (bssize_t i = g_numObituaries - 1; i >= 0; i--) diff --git a/source/duke3d/src/network.cpp b/source/duke3d/src/network.cpp index 5fa854d4e..8f78e2c56 100644 --- a/source/duke3d/src/network.cpp +++ b/source/duke3d/src/network.cpp @@ -1692,28 +1692,28 @@ static void Net_ReceiveDisconnect(ENetEvent *event) switch (event->data) { case DISC_BAD_PASSWORD: - initprintf("Bad password.\n"); + initprintf("%s\n", GStrings("Bad password.")); return; case DISC_VERSION_MISMATCH: - initprintf("Version mismatch.\n"); + initprintf("%s\n", GStrings("Version mismatch.")); return; case DISC_INVALID: - initprintf("Invalid data detected.\n"); + initprintf("%s\n", GStrings("Invalid data detected.")); return; case DISC_SERVER_QUIT: - initprintf("The server is quitting.\n"); + initprintf("%s\n", GStrings("The server is quitting.")); return; case DISC_SERVER_FULL: - initprintf("The server is full.\n"); + initprintf("%s\n", GStrings("The server is full.\n")); return; case DISC_KICKED: - initprintf("You have been kicked from the server.\n"); + initprintf("%s\n", GStrings("You have been kicked from the server.\n")); return; case DISC_BANNED: - initprintf("You are banned from this server.\n"); + initprintf("%s\n", GStrings("You are banned from this server.\n")); return; default: - initprintf("Disconnected.\n"); + initprintf("%s\n", GStrings("Disconnected.\n")); return; } } @@ -1929,11 +1929,11 @@ static void Net_ReceiveMapVoteCancel(uint8_t *pbuf) if (voting == myconnectindex || voting != pbuf[1]) { - Bsprintf(tempbuf, "Vote Failed"); + Bsprintf(tempbuf, "%s", GStrings("Vote Failed")); } else if (voting == pbuf[1]) { - Bsprintf(tempbuf, "%s^00 has canceled the vote", g_player[voting].user_name); + Bsprintf(tempbuf, GStrings("canceledthevote"), g_player[voting].user_name); } G_AddUserQuote(tempbuf); @@ -2036,11 +2036,11 @@ static void Net_ReceiveMapVoteInitiate(uint8_t *pbuf) vote_episode = pendingnewgame.volume_number; vote_map = pendingnewgame.level_number; - Bsprintf(tempbuf, "%s^00 has called a vote to change map to %s (E%dL%d)", g_player[voting].user_name, + Bsprintf(tempbuf, GStrings("votemap"), g_player[voting].user_name, g_mapInfo[(uint8_t)(vote_episode * MAXLEVELS + vote_map)].name, vote_episode + 1, vote_map + 1); G_AddUserQuote(tempbuf); - Bsprintf(tempbuf, "Press F1 to Accept, F2 to Decline"); + strcpy(tempbuf, GStrings("TXT_PRESSF1_F2")); G_AddUserQuote(tempbuf); for (playerIndex = MAXPLAYERS - 1; playerIndex >= 0; playerIndex--) @@ -2325,7 +2325,7 @@ static void Net_ReceiveNewGame(ENetEvent *event) ClientPlayerReady = 0; if ((vote_map + vote_episode + voting) != -3) - G_AddUserQuote("Vote Succeeded"); + G_AddUserQuote(GStrings("Vote Succeeded")); Bmemcpy(&pendingnewgame, event->packet->data, sizeof(newgame_t)); Net_StartNewGame(); @@ -5051,7 +5051,7 @@ void Net_SendMessage(void) else if (g_chatPlayer == -1) { j = 50; - gametext_center(j, "Send message to..."); + gametext_center(j, GStrings("Send message to")); j += 8; for (TRAVERSE_CONNECT(i)) { diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index 324bcd1eb..7a4c10dd6 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -329,7 +329,8 @@ static void G_DemoLoadScreen(const char *statustext, int const loadScreenTile, i return; } - menutext_center(105, "Loading..."); + FStringf msg("%s...", GStrings("TXT_LOADING")); + menutext_center(105, msg); if (statustext) gametext_center_number(180, statustext); @@ -372,12 +373,12 @@ static void G_DoLoadScreen(const char *statustext, int percent) if (boardfilename[0] != 0 && ud.level_number == 7 && ud.volume_number == 0) { - menutext_center(90, "Loading User Map"); + menutext_center(90, GStrings("TXT_LOADUM")); gametext_center_shade_pal(90+10, boardfilename, 14, 2); } else { - menutext_center(90, "Loading"); + menutext_center(90, GStrings("TXT_LOADING")); if (g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name != NULL) menutext_center(90+16+8, g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name); @@ -1832,7 +1833,8 @@ int G_EnterLevel(int gameMode) int const ssize = ud.screen_size; ud.screen_size = 0; - G_DoLoadScreen("Loading map . . .", -1); + FStringf msg("%s . . .", GStrings("TXT_LOADMAP")); + G_DoLoadScreen(msg, -1); G_UpdateScreenArea(); ud.screen_size = ssize; @@ -1957,9 +1959,9 @@ int G_EnterLevel(int gameMode) } if (G_HaveUserMap()) - OSD_Printf(OSDTEXT_YELLOW "User Map: %s\n", boardfilename); + OSD_Printf(OSDTEXT_YELLOW "%s: %s\n", GStrings("TXT_USERMAP"), boardfilename); else if (FURY) - OSD_Printf(OSDTEXT_YELLOW "Entering: %s\n", m.name); + OSD_Printf(OSDTEXT_YELLOW "%s: %s\n", GStrings("TXT_ENTERING"), m.name); else OSD_Printf(OSDTEXT_YELLOW "E%dL%d: %s\n", ud.volume_number + 1, ud.level_number + 1, m.name); diff --git a/source/duke3d/src/sbar.cpp b/source/duke3d/src/sbar.cpp index 9c5043a49..4fec52794 100644 --- a/source/duke3d/src/sbar.cpp +++ b/source/duke3d/src/sbar.cpp @@ -770,13 +770,13 @@ void G_DrawStatusBar(int32_t snum) if (!WW2GI) { if (j > 0) - minitext(288-30-o, 180, "On", 0, orient); + minitext(288-30-o, 180, GStrings("OPTVAL_ON"), 0, orient); else if ((uint32_t) j != 0x80000000) - minitext(284-30-o, 180, "Off", 2, orient); + minitext(284-30-o, 180, GStrings("OPTVAL_OFF"), 2, orient); } if (p->inven_icon >= ICON_SCUBA) - minitext(284-35-o, 180, "Auto", 2, orient); + minitext(284-35-o, 180, GStrings("OPTVAL_AUTO"), 2, orient); minitext_yofs = 0; } @@ -1000,15 +1000,15 @@ void G_DrawStatusBar(int32_t snum) // XXX: i < 0? rotatesprite_fs(sbarx(231-o), sbary(SBY+13), sb16, 0, i, 0, 0, 10+16+permbit); minitext(292-30-o, SBY+24, "%", 6, 10+16+permbit + ROTATESPRITE_MAX); - if (p->inven_icon >= ICON_SCUBA) minitext(284-35-o, SBY+14, "Auto", 2, 10+16+permbit + ROTATESPRITE_MAX); + if (p->inven_icon >= ICON_SCUBA) minitext(284-35-o, SBY+14, GStrings("OPTVAL_AUTO"), 2, 10+16+permbit + ROTATESPRITE_MAX); } if (u&(2048+4096) && !WW2GI) { j = G_GetInvOn(p); - if (j > 0) minitext(288-30-o, SBY+14, "On", 0, 10+16+permbit + ROTATESPRITE_MAX); - else if ((uint32_t) j != 0x80000000) minitext(284-30-o, SBY+14, "Off", 2, 10+16+permbit + ROTATESPRITE_MAX); + if (j > 0) minitext(288-30-o, SBY+14, GStrings("OPTVAL_ON"), 0, 10+16+permbit + ROTATESPRITE_MAX); + else if ((uint32_t) j != 0x80000000) minitext(284-30-o, SBY+14, GStrings("OPTVAL_OFF"), 2, 10+16+permbit + ROTATESPRITE_MAX); } if (u&8192) diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index 844e91cdd..74270f54e 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -182,14 +182,14 @@ static void G_ShowScores(void) if (g_mostConcurrentPlayers > 1 && (g_gametypeFlags[ud.coop]&GAMETYPE_SCORESHEET)) { - gametext_center(SCORESHEETOFFSET+58+2, "Multiplayer Totals"); + gametext_center(SCORESHEETOFFSET+58+2, GStrings("Multiplayer Totals")); gametext_center(SCORESHEETOFFSET+58+10, g_mapInfo[G_LastMapInfoIndex()].name); t = 0; - minitext(70, SCORESHEETOFFSET+80, "Name", 8, 2+8+16+ROTATESPRITE_MAX); - minitext(170, SCORESHEETOFFSET+80, "Frags", 8, 2+8+16+ROTATESPRITE_MAX); - minitext(200, SCORESHEETOFFSET+80, "Deaths", 8, 2+8+16+ROTATESPRITE_MAX); - minitext(235, SCORESHEETOFFSET+80, "Ping", 8, 2+8+16+ROTATESPRITE_MAX); + minitext(70, SCORESHEETOFFSET+80, GStrings("Name"), 8, 2+8+16+ROTATESPRITE_MAX); + minitext(170, SCORESHEETOFFSET+80, GStrings("Frags"), 8, 2+8+16+ROTATESPRITE_MAX); + minitext(200, SCORESHEETOFFSET+80, GStrings("Deaths"), 8, 2+8+16+ROTATESPRITE_MAX); + minitext(235, SCORESHEETOFFSET+80, GStrings("Ping"), 8, 2+8+16+ROTATESPRITE_MAX); for (i=g_mostConcurrentPlayers-1; i>=0; i--) { @@ -1043,7 +1043,7 @@ void G_DisplayRest(int32_t smoothratio) } if (ud.pause_on==1 && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0) - menutext_center(100, "Game Paused"); + menutext_center(100, GStrings("Game Paused")); if (cl_showcoords) G_PrintCoords(screenpeek); @@ -1756,11 +1756,11 @@ static void G_BonusCutscenes(void) P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1); // JBF 20040308 // G_FadePalette(0,0,0,252); videoClearScreen(0L); - menutext_center(60, "Thanks to all our"); - menutext_center(60+16, "fans for giving"); - menutext_center(60+16+16, "us big heads."); - menutext_center(70+16+16+16, "Look for a Duke Nukem 3D"); - menutext_center(70+16+16+16+16, "sequel soon."); + menutext_center(60, GStrings("Thanks to all our")); + menutext_center(60+16, GStrings("fans for giving")); + menutext_center(60+16+16, GStrings("us big heads.")); + menutext_center(70+16+16+16, GStrings("Look for a Duke Nukem 3D")); + menutext_center(70+16+16+16+16, GStrings("sequel soon.")); videoNextPage(); fadepal(0, 0, 0, 252, 0, -12); @@ -1882,13 +1882,13 @@ static void G_DisplayMPResultsScreen(void) rotatesprite_fs(160<<16, 34<<16, 65536L, 0, INGAMEDUKETHREEDEE, 0, 0, 10); if (PLUTOPAK) // JBF 20030804 rotatesprite_fs((260)<<16, 36<<16, 65536L, 0, PLUTOPAKSPRITE+2, 0, 0, 2+8); - gametext_center(58+2, "Multiplayer Totals"); + gametext_center(58+2, GStrings("Multiplayer Totals")); gametext_center(58+10, g_mapInfo[G_LastMapInfoIndex()].name); - gametext_center_shade(165, "Press any key or button to continue", quotepulseshade); + gametext_center_shade(165, GStrings("Presskey"), quotepulseshade); - minitext(38, 80, "Name", 8, 2+8+16+128); - minitext(269, 80, "Kills", 8, 2+8+16+128); + minitext(38, 80, GStrings("Name"), 8, 2+8+16+128); + minitext(269, 80, GStrings("Kills"), 8, 2+8+16+128); for (i=0; i (60*3)) { yy = zz = 59; - gametext(10, yy+9, "Your Time:"); + gametext(10, yy+9, GStrings("TXT_YourTime")); yy+=10; if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { if (g_mapInfo[G_LastMapInfoIndex()].partime) { - gametext(10, yy+9, "Par Time:"); + gametext(10, yy+9, GStrings("TXT_ParTime")); yy+=10; } if (!NAM_WW2GI && !DUKEBETA && g_mapInfo[G_LastMapInfoIndex()].designertime) { // EDuke 2.0 / NAM source suggests "Green Beret's Time:" - gametext(10, yy+9, "3D Realms' Time:"); + gametext(10, yy+9, GStrings("TXT_3DRTIME")); yy+=10; } } if (ud.playerbest > 0) { - gametext(10, yy+9, (g_player[myconnectindex].ps->player_par > 0 && g_player[myconnectindex].ps->player_par < ud.playerbest) ? "Prev Best Time:" : "Your Best Time:"); + gametext(10, yy+9, (g_player[myconnectindex].ps->player_par > 0 && g_player[myconnectindex].ps->player_par < ud.playerbest) ? GStrings("TXT_PREVBEST") : GStrings("TXT_YourBest")); yy += 10; } @@ -2219,10 +2219,10 @@ void G_BonusScreen(int32_t bonusonly) G_PrintYourTime(); gametext_number((320>>2)+71, yy+9, tempbuf); if (g_player[myconnectindex].ps->player_par < ud.playerbest) - gametext((320>>2)+89+(clockpad*24), yy+9, "New record!"); + gametext((320>>2)+89+(clockpad*24), yy+9, GStrings("TXT_NEWRECORD")); } else - gametext_pal((320>>2)+71, yy+9, "Cheated!", 2); + gametext_pal((320>>2)+71, yy+9, GStrings("TXT_Cheated"), 2); yy+=10; if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) @@ -2253,9 +2253,9 @@ void G_BonusScreen(int32_t bonusonly) zz = yy += 5; if (totalclock > (60*6)) { - gametext(10, yy+9, "Enemies Killed:"); + gametext(10, yy+9, GStrings("TXT_EnemiesKilled")); yy += 10; - gametext(10, yy+9, "Enemies Left:"); + gametext(10, yy+9, GStrings("TXT_EnemiesLeft")); yy += 10; if (bonuscnt == 2) @@ -2278,7 +2278,7 @@ void G_BonusScreen(int32_t bonusonly) yy += 10; if (ud.player_skill > 3) { - gametext((320>>2)+70, yy+9, "N/A"); + gametext((320>>2)+70, yy+9, GStrings("TXT_N_A")); yy += 10; } else @@ -2295,9 +2295,9 @@ void G_BonusScreen(int32_t bonusonly) zz = yy += 5; if (totalclock > (60*9)) { - gametext(10, yy+9, "Secrets Found:"); + gametext(10, yy+9, GStrings("TXT_SECFND")); yy += 10; - gametext(10, yy+9, "Secrets Missed:"); + gametext(10, yy+9, GStrings("TXT_SECMISS")); yy += 10; if (bonuscnt == 4) bonuscnt++; diff --git a/source/rr/src/cheats.cpp b/source/rr/src/cheats.cpp index f684a5186..bfdda7e15 100644 --- a/source/rr/src/cheats.cpp +++ b/source/rr/src/cheats.cpp @@ -690,12 +690,12 @@ void G_DoCheats(void) case CHEAT_MONSTERS: { - const char *s [] = { "On", "Off", "On (2)" }; + const char *s [] = { "OPTVAL_ON", "OPTVAL_OFF", "$TXT_ON2" }; if (++g_noEnemies == 3) g_noEnemies = 0; - quoteMgr.FormatQuote(QUOTE_RESERVED4, "Monsters: %s", s[g_noEnemies]); + quoteMgr.FormatQuote(QUOTE_RESERVED4, "%s: %s", GStrings("NETMNU_MONSTERS"), s[g_noEnemies]); P_DoQuote(QUOTE_RESERVED4, pPlayer); end_cheat(pPlayer); diff --git a/source/rr/src/demo.cpp b/source/rr/src/demo.cpp index dd3917168..bc005061c 100644 --- a/source/rr/src/demo.cpp +++ b/source/rr/src/demo.cpp @@ -851,7 +851,7 @@ nextdemo_nomenu: Net_GetPackets(); if (g_player[myconnectindex].gotvote == 0 && voting != -1 && voting != myconnectindex) - gametext_center(60, "Press F1 to Accept, F2 to Decline"); + gametext_center(60, GStrings("TXT_PRESSF1_F2")); } if ((g_player[myconnectindex].ps->gm&MODE_MENU) && (g_player[myconnectindex].ps->gm&MODE_EOL)) diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index bae9eabae..0dff6a3d7 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -6020,7 +6020,7 @@ void G_HandleLocalKeys(void) { if (inputState.UnboundKeyPressed(sc_F1) || inputState.UnboundKeyPressed(sc_F2) || cl_autovote) { - G_AddUserQuote("Vote Cast"); + G_AddUserQuote(GStrings("VoteCast")); Net_SendMapVote(inputState.UnboundKeyPressed(sc_F1) || cl_autovote ? cl_autovote-1 : 0); inputState.ClearKeyStatus(sc_F1); inputState.ClearKeyStatus(sc_F2); @@ -7380,7 +7380,7 @@ int GameInterface::app_main() for (int i=1, j=numplayers; jteam = g_player[j].pteam = i; g_player[j].ps->weaponswitch = 3; g_player[j].ps->auto_aim = 0; diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index 0498c7a39..d1117295c 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -496,7 +496,7 @@ static void G_DoLoadScreen(const char *statustext, int32_t percent) if (boardfilename[0] != 0 && ud.level_number == 7 && ud.volume_number == 0) { - menutext_center(textY, RR ? "ENTERIN' USER MAP" : "Loading User Map"); + menutext_center(textY, RR ? GStrings("TXT_ENTRUM") : GStrings("TXT_LOADUM")); if (RR) menutext_center(textY+20, boardfilename); else @@ -504,12 +504,12 @@ static void G_DoLoadScreen(const char *statustext, int32_t percent) } else if (RR && g_lastLevel) { - menutext_center(textY,"ENTERIN'"); - menutext_center(textY+16+8,"CLOSE ENCOUNTERS"); + menutext_center(textY,GStrings("ENTERIN")); + menutext_center(textY+16+8,GStrings("TXT_CLOSEENCOUNTERS")); } else { - menutext_center(textY, RR ? "ENTERIN'" : "Loading"); + menutext_center(textY, RR ? GStrings("TXT_ENTERIN") : GStrings("TXT_LOADING")); if (g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name != NULL) menutext_center(textY+16+8,g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name); } @@ -548,7 +548,7 @@ static void G_DoLoadScreen(const char *statustext, int32_t percent) rotatesprite_fs(320<<15,200<<15,65536L, 0,LOADSCREEN,0,0,2+8+64+BGSTRETCH); - menutext_center(RRRA?155:105,RR?"LOADIN'":"Loading..."); + menutext_center(RRRA?155:105,RR? GStrings("TXT_LOADIN") : GStrings("TXT_Loading...")); if (statustext) gametext_center_number(180, statustext); videoNextPage(); } @@ -2370,7 +2370,8 @@ int G_EnterLevel(int gameMode) i = ud.screen_size; ud.screen_size = 0; - G_DoLoadScreen("Loading map . . .", -1); + FStringf msg("%s . . .", GStrings("TXT_LOADMAP")); + G_DoLoadScreen(msg, -1); G_UpdateScreenArea(); ud.screen_size = i; @@ -2540,7 +2541,7 @@ int G_EnterLevel(int gameMode) if (G_HaveUserMap()) { - OSD_Printf(OSDTEXT_YELLOW "User Map: %s\n", boardfilename); + OSD_Printf(OSDTEXT_YELLOW "%s: %s\n", GStrings("TXT_USERMAP"), boardfilename); } else { diff --git a/source/rr/src/sbar.cpp b/source/rr/src/sbar.cpp index 3361575f5..a3c31c67e 100644 --- a/source/rr/src/sbar.cpp +++ b/source/rr/src/sbar.cpp @@ -982,12 +982,12 @@ void G_DrawStatusBar(int32_t snum) G_DrawInvNum(284-30-o, yofssh, 200-6, (uint8_t) i, 0, orient&~16); if (j > 0) - minitext(288-30-o, 180, "On", 0, orient); + minitext(288-30-o, 180, GStrings("OPTVAL_ON"), 0, orient); else if ((uint32_t) j != 0x80000000) - minitext(284-30-o, 180, "Off", 2, orient); + minitext(284-30-o, 180, GStrings("OPTVAL_OFF"), 2, orient); if (p->inven_icon >= ICON_SCUBA) - minitext(284-35-o, 180, "Auto", 2, orient); + minitext(284-35-o, 180, GStrings("OPTVAL_AUTO"), 2, orient); minitext_yofs = 0; } @@ -1276,7 +1276,7 @@ void G_DrawStatusBar(int32_t snum) { rotatesprite_fs(sbarx(231-o), sbary(SBY+13), sb16, 0, i, 0, 0, 10+16+permbit); minitext(292-30-o, SBY+24, "%", 6, 10+16+permbit + ROTATESPRITE_MAX); - if (p->inven_icon >= ICON_SCUBA) minitext(284-35-o, SBY+14, "Auto", 2, 10+16+permbit + ROTATESPRITE_MAX); + if (p->inven_icon >= ICON_SCUBA) minitext(284-35-o, SBY+14, GStrings("OPTVAL_AUTO"), 2, 10+16+permbit + ROTATESPRITE_MAX); } } @@ -1286,8 +1286,8 @@ void G_DrawStatusBar(int32_t snum) if (!RR) { - if (j > 0) minitext(288-30-o, SBY+14, "On", 0, 10+16+permbit + ROTATESPRITE_MAX); - else if ((uint32_t) j != 0x80000000) minitext(284-30-o, SBY+14, "Off", 2, 10+16+permbit + ROTATESPRITE_MAX); + if (j > 0) minitext(288-30-o, SBY+14, GStrings("OPTVAL_ON"), 0, 10+16+permbit + ROTATESPRITE_MAX); + else if ((uint32_t) j != 0x80000000) minitext(284-30-o, SBY+14, GStrings("OPTVAL_OFF"), 2, 10+16+permbit + ROTATESPRITE_MAX); } } diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index 626aa1c0b..9e0b7d48e 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -174,14 +174,14 @@ static void G_ShowScores(void) if (g_mostConcurrentPlayers > 1 && (g_gametypeFlags[ud.coop]&GAMETYPE_SCORESHEET)) { - gametext_center(SCORESHEETOFFSET+58+2, "Multiplayer Totals"); + gametext_center(SCORESHEETOFFSET+58+2, GStrings("Multiplayer Totals")); gametext_center(SCORESHEETOFFSET+58+10, g_mapInfo[G_LastMapInfoIndex()].name); t = 0; - minitext(70, SCORESHEETOFFSET+80, "Name", 8, 2+8+16+ROTATESPRITE_MAX); - minitext(170, SCORESHEETOFFSET+80, "Frags", 8, 2+8+16+ROTATESPRITE_MAX); - minitext(200, SCORESHEETOFFSET+80, "Deaths", 8, 2+8+16+ROTATESPRITE_MAX); - minitext(235, SCORESHEETOFFSET+80, "Ping", 8, 2+8+16+ROTATESPRITE_MAX); + minitext(70, SCORESHEETOFFSET+80, GStrings("Name"), 8, 2+8+16+ROTATESPRITE_MAX); + minitext(170, SCORESHEETOFFSET+80, GStrings("Frags"), 8, 2+8+16+ROTATESPRITE_MAX); + minitext(200, SCORESHEETOFFSET+80, GStrings("Deaths"), 8, 2+8+16+ROTATESPRITE_MAX); + minitext(235, SCORESHEETOFFSET+80, GStrings("Ping"), 8, 2+8+16+ROTATESPRITE_MAX); for (i=g_mostConcurrentPlayers-1; i>=0; i--) { @@ -1053,7 +1053,7 @@ void G_DisplayRest(int32_t smoothratio) if (ud.pause_on==1 && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0) - menutext_center(100, "Game Paused"); + menutext_center(100, GStrings("Game Paused")); if (cl_showcoords) G_PrintCoords(screenpeek); @@ -1796,11 +1796,11 @@ static void G_BonusCutscenes(void) P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1); // JBF 20040308 // G_FadePalette(0,0,0,252); videoClearScreen(0L); - menutext_center(60, "Thanks to all our"); - menutext_center(60+16, "fans for giving"); - menutext_center(60+16+16, "us big heads."); - menutext_center(70+16+16+16, "Look for a Duke Nukem 3D"); - menutext_center(70+16+16+16+16, "sequel soon."); + menutext_center(60, GStrings("Thanks to all our")); + menutext_center(60+16, GStrings("fans for giving")); + menutext_center(60+16+16, GStrings("us big heads.")); + menutext_center(70+16+16+16, GStrings("Look for a Duke Nukem 3D")); + menutext_center(70+16+16+16+16, GStrings("sequel soon.")); videoNextPage(); fadepal(0, 0, 0, 252, 0, -12); @@ -1910,13 +1910,13 @@ static void G_DisplayMPResultsScreen(void) rotatesprite_fs(160<<16, 34<<16, RR ? 23592L : 65536L, 0, INGAMEDUKETHREEDEE, 0, 0, 10); if (!RR && PLUTOPAK) // JBF 20030804 rotatesprite_fs((260)<<16, 36<<16, 65536L, 0, PLUTOPAKSPRITE+2, 0, 0, 2+8); - gametext_center(58+(RR ? 0 : 2), "Multiplayer Totals"); + gametext_center(58+(RR ? 0 : 2), GStrings("Multiplayer Totals")); gametext_center(58+10, g_mapInfo[G_LastMapInfoIndex()].name); - gametext_center_shade(RR ? 175 : 165, "Press any key or button to continue", quotepulseshade); + gametext_center_shade(RR ? 175 : 165, GStrings("Presskey"), quotepulseshade); - minitext(38, 80, "Name", 8, 2+8+16+128); - minitext(269, 80, "Kills", 8, 2+8+16+128); + minitext(38, 80, GStrings("Name"), 8, 2+8+16+128); + minitext(269, 80, GStrings("Kills"), 8, 2+8+16+128); for (i=0; i>2)+71, yy+9, tempbuf); if (g_player[myconnectindex].ps->player_par < ud.playerbest) - gametext((320>>2)+89+(clockpad*24), yy+9, "New record!"); + gametext((320>>2)+89+(clockpad*24), yy+9, GStrings("TXT_NEWRECORD")); } else { @@ -2313,9 +2313,9 @@ void G_BonusScreen(int32_t bonusonly) } } else if (!RR) - gametext_pal((320>>2)+71, yy+9, "Cheated!", 2); + gametext_pal((320>>2)+71, yy+9, GStrings("TXT_Cheated"), 2); else - menutext(191, yy, "Cheated!"); + menutext(191, yy, GStrings("TXT_Cheated")); yy+=yystep; if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) @@ -2356,14 +2356,14 @@ void G_BonusScreen(int32_t bonusonly) if (totalclock > (60*6)) { if (!RR) - gametext(10, yy+9, "Enemies Killed:"); + gametext(10, yy+9, GStrings("TXT_EnemiesKilled")); else - menutext(30, yy, "Varmints Killed:"); + menutext(30, yy, GStrings("TXT_VarmintsKilled")); yy += yystep; if (!RR) - gametext(10, yy+9, "Enemies Left:"); + gametext(10, yy+9, GStrings("TXT_EnemiesLeft")); else - menutext(30, yy, "Varmints Left:"); + menutext(30, yy, GStrings("TXT_VarmintsLeft")); yy += yystep; if (bonuscnt == 2) @@ -2391,9 +2391,9 @@ void G_BonusScreen(int32_t bonusonly) if (ud.player_skill > 3 && !RR) { if (!RR) - gametext((320>>2)+70, yy+9, "N/A"); + gametext((320>>2)+70, yy+9, GStrings("TXT_N_A")); else - menutext(231,yy, "N/A"); + menutext(231,yy, GStrings("TXT_N_A")); yy += yystep; } else @@ -2414,14 +2414,14 @@ void G_BonusScreen(int32_t bonusonly) if (totalclock > (60*9)) { if (!RR) - gametext(10, yy+9, "Secrets Found:"); + gametext(10, yy+9, GStrings("TXT_SECFND")); else - menutext(30, yy, "Secrets Found:"); + menutext(30, yy, GStrings("TXT_SECFND")); yy += yystep; if (!RR) - gametext(10, yy+9, "Secrets Missed:"); + gametext(10, yy+9, GStrings("TXT_SECMISS")); else - menutext(30, yy, "Secrets Missed:"); + menutext(30, yy, GStrings("TXT_SECMISS")); yy += yystep; if (bonuscnt == 4) bonuscnt++; @@ -2629,9 +2629,9 @@ void G_BonusScreenRRRA(int32_t bonusonly) } if ((g_lastLevel && ud.volume_number == 2) || g_vixenLevel) - lastmapname = "CLOSE ENCOUNTERS"; + lastmapname = GStrings("TXT_CLOSEENCOUNTERS"); else if (g_turdLevel) - lastmapname = "SMELTIN' PLANT"; + lastmapname = GStrings("SMELTIN' PLANT"); fadepal(0, 0, 0, 0, 252, 4); @@ -2814,7 +2814,7 @@ void G_BonusScreenRRRA(int32_t bonusonly) if (lastmapname) menutext(80, 16, lastmapname); - menutext(15, 192, "Press any key to continue"); + menutext(15, 192, GStrings("TXT_PRESSKEY")); const int yystep = 16; if (totalclock > (60*3)) @@ -2828,12 +2828,12 @@ void G_BonusScreenRRRA(int32_t bonusonly) { if (g_mapInfo[G_LastMapInfoIndex()].partime) { - menutext(30, yy, "Par Time:"); + menutext(30, yy, GStrings("TXT_PARTIME")); yy+=yystep; } if (g_mapInfo[G_LastMapInfoIndex()].designertime) { - menutext(30, yy, "Xatrix Time:"); + menutext(30, yy, GStrings("TXT_XTRTIME")); yy+=yystep; } @@ -2895,9 +2895,9 @@ void G_BonusScreenRRRA(int32_t bonusonly) zz = yy += 16; if (totalclock > (60*6)) { - menutext(30, yy, "Varmints Killed:"); + menutext(30, yy, GStrings("TXT_VARMINTSKILLED")); yy += yystep; - menutext(30, yy, "Varmints Left:"); + menutext(30, yy, GStrings("TXT_VARMINTSLEFT")); yy += yystep; if (bonuscnt == 2) @@ -2934,9 +2934,9 @@ void G_BonusScreenRRRA(int32_t bonusonly) zz = yy += 0; if (totalclock > (60*9)) { - menutext(30, yy, "Secrets Found:"); + menutext(30, yy, GStrings("TXT_SECFND")); yy += yystep; - menutext(30, yy, "Secrets Missed:"); + menutext(30, yy, GStrings("TXT_SECMISS")); yy += yystep; if (bonuscnt == 4) bonuscnt++; From 2ed03214b1b99d0b254c9b355059efebcdfb16e0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 15:07:43 +0100 Subject: [PATCH 144/203] - disable the save option in SW's main menu if no game is running. --- source/sw/src/d_menu.cpp | 13 +++++++ wadsrc/static/demolition/language.csv | 52 +++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/source/sw/src/d_menu.cpp b/source/sw/src/d_menu.cpp index 92e70f05e..3c431eabc 100644 --- a/source/sw/src/d_menu.cpp +++ b/source/sw/src/d_menu.cpp @@ -78,6 +78,19 @@ void Menu_Init(void) class SWMainMenu : public DListMenu { + void Ticker() override + { + // Dynamically enable and disable the save option + for (unsigned e = 0; e < mDesc->mItems.Size(); ++e) + { + auto entry = mDesc->mItems[e]; + if (entry->GetAction(nullptr) == NAME_SaveGameMenu) + { + entry->mEnabled = gi->CanSave(); + } + } + } + void PreDraw() override { rotatesprite(160 << 16, 15 << 16, 65536, 0, pic_shadow_warrior, diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index df96c221c..c74645b9a 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -725,7 +725,7 @@ in this demo version of Blood.","BLOOD_SW_BLOCK ",,"Вы действительно хотите закончить игру? ","Јесте ли сигурни да желите завршити игру? " -Are you sure you want to quit?,CONFIRM_QUITMSG,,,,Přeješ si odejít?,"Bist du dir sicher, dass du gehen willst?",,"Ĉu vi certas, ke vi volas ĉesi?",¿Estás segur@[ao_esp] que quieres salir?,,Haluatko varmasti lopettaa?,Êtes vous sûr de vouloir quitter ?,Biztos vagy benne hogy ki akarsz lépni?,Sei sicuro di voler abbandonare?,本当に終了するのか?,정말 종료하시겠습니까?,Weet je zeker dat je wilt stoppen?,Czy jesteś pewien że chcesz wyjść?,Tem certeza que quer sair?,Tens a certeza que queres sair?,,Вы действительно желаете выйти?,Да ли сте сигурни да желите да одустанеш? +Are you sure you want to quit this game?,CONFIRM_QUITMSG,,,,Přeješ si odejít?,"Bist du dir sicher, dass du gehen willst?",,"Ĉu vi certas, ke vi volas ĉesi?",¿Estás segur@[ao_esp] que quieres salir?,,Haluatko varmasti lopettaa?,Êtes vous sûr de vouloir quitter ?,Biztos vagy benne hogy ki akarsz lépni?,Sei sicuro di voler abbandonare?,本当に終了するのか?,정말 종료하시겠습니까?,Weet je zeker dat je wilt stoppen?,Czy jesteś pewien że chcesz wyjść?,Tem certeza que quer sair?,Tens a certeza que queres sair?,,Вы действительно желаете выйти?,Да ли сте сигурни да желите да одустанеш? Reset controls to defaults?,CONFIRM_CTRL1,,,,,Steuerung auf Standard zurücksetzen?,,,,,,,,,,,,,,,,, Reset controls to classic defaults?,CONFIRM_CTRL2,,,,,Steuerung auf klassischen Standard zurücksetzen?,,,,,,,,,,,,,,,,, Reset controls to left-handed defaults?,CONFIRM_CTRL3,,,,,Steuerung auf linkshändigen Standard zurücksetzen?,,,,,,,,,,,,,,,,, @@ -1558,4 +1558,52 @@ Mystery Dino Cave,MYSTERY DINO CAVE,,,,,,,,,,,,,,,,,,,,,, Campy Crystal Lake,CAMPY CRYSTAL LAKE,,,,,,,,,,,,,,,,,,,,,, Bigfoot Convention,BIGFOOT CONVENTION,,,,,,,,,,,,,,,,,,,,,, Hoover Dam,HOOVER DAM,,,,,,,,,,,,,,,,,,,,,, -Oddity Museum,ODDITY MUSEUM,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file +Oddity Museum,ODDITY MUSEUM,,,,,,,,,,,,,,,,,,,,,, +,Texts extracted from the source (Duke Nukem),,,,,,,,,,,,,,,,,,,,,, +Come Get Some!,COMEGETSOME,,,,,,,,,,,,,,,,,,,,,, +On (2),TXT_ON2,,,,,,,,,,,,,,,,,,,,,, +Loading,TXT_LOADING,,,,,,,,,,,,,,,,,,,,,, +Loading User Map,TXT_LOADUM,,,,,,,,,,,,,,,,,,,,,, +Loading map,TXT_LOADMAP,,,,,,,,,,,,,,,,,,,,,, +Entering,TXT_ENTERING,,,,,,,,,,,,,,,,,,,,,, +Multiplayer Totals,Multiplayer Totals,,,,,,,,,,,,,,,,,,,,,, +Name,Name,,,,,,,,,,,,,,,,,,,,,, +Frags,Frags,,,,,,,,,,,,,,,,,,,,,, +Deaths,Deaths,,,,,,,,,,,,,,,,,,,,,, +Ping,Ping,,,,,,,,,,,,,,,,,,,,,, +Game Paused,Game Paused,,,,,,,,,,,,,,,,,,,,,, +Thanks to all our,Thanks to all our,,,,,,,,,,,,,,,,,,,,,, +fans for giving,fans for giving,,,,,,,,,,,,,,,,,,,,,, +us big heads.,us big heads.,,,,,,,,,,,,,,,,,,,,,, +Look for a Duke Nukem 3D,Look for a Duke Nukem 3D,,,,,,,,,,,,,,,,,,,,,, +sequel soon.,sequel soon.,,,,,,,,,,,,,,,,,,,,,, +Press any key or button to continue,Presskey,,,,,,,,,,,,,,,,,,,,,, +Kills,Kills,,,,,,,,,,,,,,,,,,,,,, +Completed,Completed,,,,,,,,,,,,,,,,,,,,,, +Your Time:,TXT_YOURTIME,,,,,,,,,,,,,,,,,,,,,, +Yer Time:,TXT_YERTIME,,,,,,,,,,,,,,,,,,,,,, +Par Time:,TXT_PARTIME,,,,,,,,,,,,,,,,,,,,,, +3D Realms' Time:,TXT_3DRTIME,,,,,,,,,,,,,,,,,,,,,, +Green Beret's Time:,TXT_3DRTIME,,"Nam, WW2GI",,,,,,,,,,,,,,,,,,,, +Xatrix Time:,"TXT_XTRTIME +",,,,,,,,,,,,,,,,,,,,,, +Prev Best Time:,TXT_PREVBEST,,,,,,,,,,,,,,,,,,,,,, +Your Best Time:,"TXT_YOURBEST +",,,,,,,,,,,,,,,,,,,,,, +New record!,TXT_NEWRECORD,,,,,,,,,,,,,,,,,,,,,, +Cheated!,TXT_CHEATED,,,,,,,,,,,,,,,,,,,,,, +Enemies Killed:,TXT_ENEMIESKILLED,,,,,,,,,,,,,,,,,,,,,, +Enemies Left:,TXT_ENEMIESLEFT,,,,,,,,,,,,,,,,,,,,,, +Varmints Killed:,TXT_VARMINTSKILLED,,,,,,,,,,,,,,,,,,,,,, +Varmints Left:,TXT_VARMINTSLEFT,,,,,,,,,,,,,,,,,,,,,, +N/A,TXT_N_A,,,,,,,,,,,,,,,,,,,,,, +Secrets Found:,TXT_SECFND,,,,,,,,,,,,,,,,,,,,,, +Secrets Missed:,TXT_SECMISS,,,,,,,,,,,,,,,,,,,,,, +Vote cast,VOTECAST,,,,,,,,,,,,,,,,,,,,,, +"Press F1 to Accept, F2 to Decline",TXT_PRESSF1_F2,,,,,,,,,,,,,,,,,,,,,, +Enterin',TXT_ENTERIN,,,,,,,,,,,,,,,,,,,,,, +Close Encounters,TXT_CLOSEENCOUNTERS,,,,,,,,,,,,,,,,,,,,,, +Enterin' User Mao,TXT_ENTRUM,,,,,,,,,,,,,,,,,,,,,, +Loadin',TXT_LOADIN,,,,,,,,,,,,,,,,,,,,,, +"Loading... +",TXT_LOADING...,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file From a05dab66f72524a1537d90f07fc05680f7608f61 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 15:45:29 +0100 Subject: [PATCH 145/203] - color tweaking for the options menu. --- source/common/menu/menudef.cpp | 48 +++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index a8b9ef906..8949f48a1 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -1099,13 +1099,47 @@ void M_ParseMenuDefs() { int lump, lastlump = 0; - OptionSettings.mTitleColor = CR_RED;// V_FindFontColor(gameinfo.mTitleColor); - OptionSettings.mFontColor = CR_RED; // V_FindFontColor(gameinfo.mFontColor); - OptionSettings.mFontColorValue = CR_GRAY;// = V_FindFontColor(gameinfo.mFontColorValue); - OptionSettings.mFontColorMore = CR_GOLD;// = V_FindFontColor(gameinfo.mFontColorMore); - OptionSettings.mFontColorHeader = CR_YELLOW;// = V_FindFontColor(gameinfo.mFontColorHeader); - OptionSettings.mFontColorHighlight = CR_BRICK;// = V_FindFontColor(gameinfo.mFontColorHighlight); - OptionSettings.mFontColorSelection = CR_RED;// = V_FindFontColor(gameinfo.mFontColorSelection); + //OptionSettings.mTitleColor = CR_RED;// V_FindFontColor(gameinfo.mTitleColor); + OptionSettings.mFontColor = CR_RED; + OptionSettings.mFontColorValue = CR_GRAY; + OptionSettings.mFontColorMore = CR_GRAY; + OptionSettings.mFontColorHeader = CR_GOLD; + OptionSettings.mFontColorHighlight = CR_YELLOW; + OptionSettings.mFontColorSelection = CR_BRICK; + + if (g_gameType & (GAMEFLAG_NAM | GAMEFLAG_NAPALM | GAMEFLAG_WW2GI)) + { + OptionSettings.mFontColor = CR_DARKGREEN; + OptionSettings.mFontColorHeader = CR_DARKGRAY; + OptionSettings.mFontColorHighlight = CR_WHITE; + OptionSettings.mFontColorSelection = CR_DARKGREEN; + } + else if (g_gameType & GAMEFLAG_BLOOD) + { + OptionSettings.mFontColorHeader = CR_DARKGRAY; + OptionSettings.mFontColorHighlight = CR_WHITE; + OptionSettings.mFontColorSelection = CR_DARKRED; + } + else if (g_gameType & GAMEFLAG_FURY) + { + OptionSettings.mFontColor = CR_TEAL; + OptionSettings.mFontColorHeader = CR_LIGHTBLUE; + OptionSettings.mFontColorHighlight = CR_ORANGE; + OptionSettings.mFontColorSelection = CR_GOLD; + } + else if (g_gameType & (GAMEFLAG_RR|GAMEFLAG_RRRA)) + { + OptionSettings.mFontColor = CR_BROWN; + OptionSettings.mFontColorHeader = CR_DARKBROWN; + OptionSettings.mFontColorHighlight = CR_ORANGE; + OptionSettings.mFontColorSelection = CR_TAN; + } + else if (g_gameType & GAMEFLAG_SW) + { + OptionSettings.mFontColorHeader = CR_DARKRED; + OptionSettings.mFontColorHighlight = CR_WHITE; + } + DefaultListMenuSettings.Reset(); DefaultOptionMenuSettings.Reset(); From ff50a1681f609b55929a77d56c228d767673c5cf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 18:28:30 +0100 Subject: [PATCH 146/203] - simplified the music playing interface a bit. # --- source/blood/src/blood.cpp | 17 ++++---------- source/blood/src/credits.cpp | 2 +- source/blood/src/demo.cpp | 1 - source/blood/src/levels.cpp | 17 ++++++-------- source/blood/src/levels.h | 1 - source/blood/src/loadsave.cpp | 1 - source/blood/src/menu.cpp | 4 ++-- source/blood/src/sound.cpp | 23 +----------------- source/blood/src/sound.h | 6 +---- source/common/music/music.cpp | 6 +++++ source/common/music/z_music.h | 1 + source/duke3d/src/gameexec.cpp | 2 +- source/duke3d/src/screens.cpp | 14 +++++------ source/duke3d/src/sector.cpp | 4 ++-- source/duke3d/src/sounds.cpp | 39 ++++-------------------------- source/duke3d/src/sounds.h | 3 +-- source/rr/src/savegame.cpp | 2 +- source/rr/src/screens.cpp | 16 ++++++------- source/rr/src/sector.cpp | 4 ++-- source/rr/src/sounds.cpp | 43 ++++------------------------------ source/rr/src/sounds.h | 4 +--- 21 files changed, 55 insertions(+), 155 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 675b9003d..3ae6eb9a5 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -947,7 +947,7 @@ void ProcessFrame(void) } if (gDemo.at0) gDemo.Close(); - sndFadeSong(4000); + Mus_Fade(4000); seqKillAll(); if (gGameOptions.uGameFlags&2) { @@ -1367,7 +1367,7 @@ RESTART: if (gRestartGame) { UpdateDacs(0, true); - sndStopSong(); + Mus_Stop(); FX_StopAllSounds(); gQuitGame = 0; gQuitRequest = 0; @@ -1991,27 +1991,18 @@ int sndTryPlaySpecialMusic(int nMusic) { int nEpisode = nMusic/kMaxLevels; int nLevel = nMusic%kMaxLevels; - if (sndPlaySong(gEpisodeInfo[nEpisode].at28[nLevel].at0, gEpisodeInfo[nEpisode].at28[nLevel].atd0, true)) + if (Mus_Play(gEpisodeInfo[nEpisode].at28[nLevel].at0, gEpisodeInfo[nEpisode].at28[nLevel].atd0, true)) { - strncpy(gGameOptions.zLevelSong, gEpisodeInfo[nEpisode].at28[nLevel].atd0, BMAX_PATH); return 0; } - else - { - // Unable to stat the music. - *gGameOptions.zLevelSong = 0; - } return 1; } void sndPlaySpecialMusicOrNothing(int nMusic) { - int nEpisode = nMusic/kMaxLevels; - int nLevel = nMusic%kMaxLevels; if (sndTryPlaySpecialMusic(nMusic)) { - sndStopSong(); - strncpy(gGameOptions.zLevelSong, gEpisodeInfo[nEpisode].at28[nLevel].atd0, BMAX_PATH); + Mus_Stop(); } } diff --git a/source/blood/src/credits.cpp b/source/blood/src/credits.cpp index f6f1dbc23..45c2157a2 100644 --- a/source/blood/src/credits.cpp +++ b/source/blood/src/credits.cpp @@ -140,7 +140,7 @@ void credLogosDos(void) rotatesprite(160<<16, 100<<16, 65536, 0, 2518, 0, 0, 0x4a, 0, 0, xdim-1, ydim-1); scrNextPage(); Wait(360); - sndFadeSong(4000); + Mus_Fade(4000); } void credReset(void) diff --git a/source/blood/src/demo.cpp b/source/blood/src/demo.cpp index f83043659..596ac9bc9 100644 --- a/source/blood/src/demo.cpp +++ b/source/blood/src/demo.cpp @@ -61,7 +61,6 @@ void ReadGameOptionsLegacy(GAMEOPTIONS &gameOptions, GAMEOPTIONSLEGACY &gameOpti gameOptions.nEpisode = gameOptionsLegacy.nEpisode; gameOptions.nLevel = gameOptionsLegacy.nLevel; strcpy(gameOptions.zLevelName, gameOptionsLegacy.zLevelName); - strcpy(gameOptions.zLevelSong, gameOptionsLegacy.zLevelSong); gameOptions.nTrackNumber = gameOptionsLegacy.nTrackNumber; gameOptions.nSaveGameSlot = gameOptionsLegacy.nSaveGameSlot; gameOptions.picEntry = gameOptionsLegacy.picEntry; diff --git a/source/blood/src/levels.cpp b/source/blood/src/levels.cpp index f40f9d1fb..0ca5672f6 100644 --- a/source/blood/src/levels.cpp +++ b/source/blood/src/levels.cpp @@ -50,7 +50,7 @@ BEGIN_BLD_NS GAMEOPTIONS gGameOptions; GAMEOPTIONS gSingleGameOptions = { - 0, 2, 0, 0, "", "", 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3600, 1800, 1800, 7200 + 0, 2, 0, 0, "", 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3600, 1800, 1800, 7200 }; EPISODEINFO gEpisodeInfo[kMaxEpisodes+1]; @@ -88,7 +88,7 @@ void levelOverrideINI(const char *pzIni) void levelPlayIntroScene(int nEpisode) { gGameOptions.uGameFlags &= ~4; - sndStopSong(); + Mus_Stop(); sndKillAllSounds(); sfxKillAllSounds(); ambKillAll(); @@ -104,7 +104,7 @@ void levelPlayIntroScene(int nEpisode) void levelPlayEndScene(int nEpisode) { gGameOptions.uGameFlags &= ~8; - sndStopSong(); + Mus_Stop(); sndKillAllSounds(); sfxKillAllSounds(); ambKillAll(); @@ -199,7 +199,6 @@ void levelSetupOptions(int nEpisode, int nLevel) gGameOptions.nLevel = nLevel; strcpy(gGameOptions.zLevelName, gEpisodeInfo[nEpisode].at28[nLevel].at0); gGameOptions.uMapCRC = dbReadMapCRC(gGameOptions.zLevelName); - // strcpy(gGameOptions.zLevelSong, gEpisodeInfo[nEpisode].at28[nLevel].atd0); gGameOptions.nTrackNumber = gEpisodeInfo[nEpisode].at28[nLevel].ate0; } @@ -401,19 +400,17 @@ bool levelTryPlayMusic(int nEpisode, int nLevel, bool bSetLevelSong) if (mus_redbook && gEpisodeInfo[nEpisode].at28[nLevel].ate0 > 0) snprintf(buffer, BMAX_PATH, "blood%02i.ogg", gEpisodeInfo[nEpisode].at28[nLevel].ate0); else + { strncpy(buffer, gEpisodeInfo[nEpisode].at28[nLevel].atd0, BMAX_PATH); + } if (!strchr(buffer, '.')) strcat(buffer, ".mid"); - bool bReturn = !!sndPlaySong(gEpisodeInfo[nEpisode].at28[nLevel].at0, buffer, true); - if (bReturn || bSetLevelSong) - strncpy(gGameOptions.zLevelSong, buffer, BMAX_PATH); - else *gGameOptions.zLevelSong = 0; - return bReturn; + return !!Mus_Play(gEpisodeInfo[nEpisode].at28[nLevel].at0, buffer, true); } void levelTryPlayMusicOrNothing(int nEpisode, int nLevel) { if (levelTryPlayMusic(nEpisode, nLevel, true)) - sndStopSong(); + Mus_Stop(); } class LevelsLoadSave : public LoadSave diff --git a/source/blood/src/levels.h b/source/blood/src/levels.h index dc526e444..eb4223f9b 100644 --- a/source/blood/src/levels.h +++ b/source/blood/src/levels.h @@ -39,7 +39,6 @@ struct GAMEOPTIONS { int nEpisode; int nLevel; char zLevelName[BMAX_PATH]; - char zLevelSong[BMAX_PATH]; int nTrackNumber; //at12a; short nSaveGameSlot; int picEntry; diff --git a/source/blood/src/loadsave.cpp b/source/blood/src/loadsave.cpp index 9dc5c35e9..ae636805e 100644 --- a/source/blood/src/loadsave.cpp +++ b/source/blood/src/loadsave.cpp @@ -180,7 +180,6 @@ bool GameInterface::LoadGame(FSaveGameNode* node) MUS_ResumeSaved(); netBroadcastPlayerInfo(myconnectindex); - //sndPlaySong(gGameOptions.zLevelSong, 1); return true; } diff --git a/source/blood/src/menu.cpp b/source/blood/src/menu.cpp index de220ffd4..ef66e2a5d 100644 --- a/source/blood/src/menu.cpp +++ b/source/blood/src/menu.cpp @@ -152,7 +152,7 @@ void SetupNetworkJoinMenu(CGameMenuItemChain *pItem) void NetworkHostGame(CGameMenuItemChain *pItem) { UNREFERENCED_PARAMETER(pItem); - sndStopSong(); + Mus_Stop(); FX_StopAllSounds(); UpdateDacs(0, true); gNetPlayers = itemNetworkHostPlayerNum.nValue; @@ -168,7 +168,7 @@ void NetworkHostGame(CGameMenuItemChain *pItem) void NetworkJoinGame(CGameMenuItemChain *pItem) { UNREFERENCED_PARAMETER(pItem); - sndStopSong(); + Mus_Stop(); FX_StopAllSounds(); UpdateDacs(0, true); strcpy(gNetAddress, zNetAddressBuffer); diff --git a/source/blood/src/sound.cpp b/source/blood/src/sound.cpp index dc1f87dcc..c844d5e3a 100644 --- a/source/blood/src/sound.cpp +++ b/source/blood/src/sound.cpp @@ -75,27 +75,6 @@ SAMPLE2D * FindChannel(void) return NULL; } -int sndPlaySong(const char *mapname, const char* songName, bool bLoop) -{ - return Mus_Play(mapname, songName, bLoop); -} - -bool sndIsSongPlaying(void) -{ - // Not used - return false; -} - -void sndFadeSong(int nTime) -{ - // not implemented -} - -void sndStopSong(void) -{ - Mus_Stop(); -} - void sndSetFXVolume(int nVolume) { snd_fxvolume = nVolume; @@ -307,7 +286,7 @@ void sndTerm(void) if (!sndActive) return; sndActive = false; - sndStopSong(); + Mus_Stop(); DeinitSoundDevice(); //DeinitMusicDevice(); } diff --git a/source/blood/src/sound.h b/source/blood/src/sound.h index 44b101e29..ccc31501e 100644 --- a/source/blood/src/sound.h +++ b/source/blood/src/sound.h @@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #pragma once #include "resource.h" +#include "z_music.h" BEGIN_BLD_NS @@ -44,12 +45,7 @@ struct SFX }; int sndGetRate(int format); -int sndPlaySong(const char *mapname, const char *songName, bool bLoop); -bool sndIsSongPlaying(void); -void sndFadeSong(int nTime); -void sndSetMusicVolume(int nVolume); void sndSetFXVolume(int nVolume); -void sndStopSong(void); void sndStartSample(const char *pzSound, int nVolume, int nChannel = -1); void sndStartSample(unsigned int nSound, int nVolume, int nChannel = -1, bool bLoop = false); void sndStartWavID(unsigned int nSound, int nVolume, int nChannel = -1); diff --git a/source/common/music/music.cpp b/source/common/music/music.cpp index 5b9540ad9..30d36cc5b 100644 --- a/source/common/music/music.cpp +++ b/source/common/music/music.cpp @@ -609,6 +609,12 @@ void Mus_Stop() S_StopMusic(true); } +void Mus_Fade(double seconds) +{ + // Todo: Blood uses this, but the streamer cannot currently fade the volume. + Mus_Stop(); +} + void Mus_SetPaused(bool on) { if (on) S_PauseMusic(); diff --git a/source/common/music/z_music.h b/source/common/music/z_music.h index 026ff5c30..e2dff877a 100644 --- a/source/common/music/z_music.h +++ b/source/common/music/z_music.h @@ -5,5 +5,6 @@ void Mus_Init(); int Mus_Play(const char *mapname, const char *fn, bool loop); void Mus_Stop(); +void Mus_Fade(double seconds); void Mus_SetPaused(bool on); void MUS_ResumeSaved(); diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index c457b4223..8bbd4bdc5 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -5008,7 +5008,7 @@ badindex: vInstruction(CON_STOPALLMUSIC): insptr++; - S_StopMusic(); + Mus_Stop(); dispatch(); vInstruction(CON_OPERATE): diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index 74270f54e..ea8f64505 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -1287,7 +1287,7 @@ void gameDisplaySharewareScreens() void G_DisplayExtraScreens(void) { - S_StopMusic(); + Mus_Stop(); FX_StopAllSounds(); if (!DUKEBETA && (!VOLUMEALL || G_GetLogoFlags() & LOGO_SHAREWARESCREENS)) @@ -1467,7 +1467,7 @@ void G_DisplayLogo(void) renderFlushPerms(); videoNextPage(); - S_StopMusic(); + Mus_Stop(); FX_StopAllSounds(); // JBF 20031228 S_ClearSoundLocks(); // JBF 20031228 @@ -1669,7 +1669,7 @@ static void G_BonusCutscenes(void) fadepal(0, 0, 0, 0, 252, 4); VOL1_END: - S_StopMusic(); + Mus_Stop(); FX_StopAllSounds(); S_ClearSoundLocks(); break; @@ -1680,7 +1680,7 @@ static void G_BonusCutscenes(void) videoSetViewableArea(0, 0, xdim-1, ydim-1); - S_StopMusic(); + Mus_Stop(); videoClearScreen(0L); videoNextPage(); @@ -1714,7 +1714,7 @@ static void G_BonusCutscenes(void) videoSetViewableArea(0, 0, xdim-1, ydim-1); - S_StopMusic(); + Mus_Stop(); videoClearScreen(0L); videoNextPage(); @@ -1796,7 +1796,7 @@ static void G_BonusCutscenes(void) if ((G_GetLogoFlags() & LOGO_NOE3BONUSSCENE) && (G_GetLogoFlags() & LOGO_NOE3RADLOGO) && (PLUTOPAK || (G_GetLogoFlags() & LOGO_NODUKETEAMPIC))) return; - S_StopMusic(); + Mus_Stop(); videoClearScreen(0L); videoNextPage(); if (adult_lockout == 0 && !(G_GetLogoFlags() & LOGO_NOE3BONUSSCENE)) @@ -2043,7 +2043,7 @@ void G_BonusScreen(int32_t bonusonly) totalclock = 0; bonuscnt = 0; - S_StopMusic(); + Mus_Stop(); FX_StopAllSounds(); S_ClearSoundLocks(); diff --git a/source/duke3d/src/sector.cpp b/source/duke3d/src/sector.cpp index b29a9098d..6f8c5b32b 100644 --- a/source/duke3d/src/sector.cpp +++ b/source/duke3d/src/sector.cpp @@ -2602,12 +2602,12 @@ void P_HandleSharedKeys(int playerNum) else ud.pause_on = 1+SHIFTS_IS_PRESSED; if (ud.pause_on) { - S_PauseMusic(true); + Mus_SetPaused(true); S_PauseSounds(true); } else { - if (MusicEnabled()) S_PauseMusic(false); + if (MusicEnabled()) Mus_SetPaused(false); S_PauseSounds(false); diff --git a/source/duke3d/src/sounds.cpp b/source/duke3d/src/sounds.cpp index 36b8bb241..b3cb42cd8 100644 --- a/source/duke3d/src/sounds.cpp +++ b/source/duke3d/src/sounds.cpp @@ -133,22 +133,6 @@ void S_MenuSound(void) } -static int S_PlayMusic(const char *mapname, const char* fn, bool looping = true) -{ - return Mus_Play(mapname, fn, looping); -} - -void S_StopMusic(void) -{ - Mus_Stop(); -} - -void S_PauseMusic(bool paused) -{ - Mus_SetPaused(paused); -} - - static void S_SetMusicIndex(unsigned int m) { g_musicIndex = m; @@ -156,30 +140,16 @@ static void S_SetMusicIndex(unsigned int m) ud.music_level = m % MAXLEVELS; } -bool S_TryPlayLevelMusic(unsigned int m) +void S_PlayLevelMusicOrNothing(unsigned int m) { ud.returnvar[0] = m / MAXLEVELS; ud.returnvar[1] = m % MAXLEVELS; int retval = VM_OnEvent(EVENT_PLAYLEVELMUSICSLOT, g_player[myconnectindex].ps->i, myconnectindex); - if (retval < 0) - return false; - - if (!S_PlayMusic(g_mapInfo[m].filename, g_mapInfo[m].musicfn)) - { - S_SetMusicIndex(m); - return false; - } - - return true; -} - -void S_PlayLevelMusicOrNothing(unsigned int m) -{ - if (S_TryPlayLevelMusic(m)) + if (retval >= 0) { - //S_StopMusic(); + Mus_Play(g_mapInfo[m].filename, g_mapInfo[m].musicfn, true); S_SetMusicIndex(m); } } @@ -189,7 +159,7 @@ int S_TryPlaySpecialMusic(unsigned int m) char const * musicfn = g_mapInfo[m].musicfn; if (musicfn != NULL) { - if (!S_PlayMusic(nullptr, musicfn)) + if (!Mus_Play(nullptr, musicfn, true)) { S_SetMusicIndex(m); return 0; @@ -203,7 +173,6 @@ void S_PlaySpecialMusicOrNothing(unsigned int m) { if (S_TryPlaySpecialMusic(m)) { - //S_StopMusic(); S_SetMusicIndex(m); } } diff --git a/source/duke3d/src/sounds.h b/source/duke3d/src/sounds.h index 405a4c4b1..428815125 100644 --- a/source/duke3d/src/sounds.h +++ b/source/duke3d/src/sounds.h @@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define sounds_public_h_ #include "sounds_common.h" +#include "z_music.h" BEGIN_DUKE_NS @@ -72,7 +73,6 @@ void cacheAllSounds(void); void S_MenuSound(void); void S_PauseMusic(bool paused); void S_PauseSounds(bool paused); -bool S_TryPlayLevelMusic(unsigned int m); void S_PlayLevelMusicOrNothing(unsigned int); int S_TryPlaySpecialMusic(unsigned int); void S_PlaySpecialMusicOrNothing(unsigned int); @@ -83,7 +83,6 @@ void S_SoundShutdown(void); void S_SoundStartup(void); void S_StopEnvSound(int sndNum,int sprNum); void S_StopAllSounds(void); -void S_StopMusic(void); void S_Update(void); void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset); diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index b9343fb0f..f056ef7db 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -1615,7 +1615,7 @@ static void postloadplayer(int32_t savegamep) MUS_ResumeSaved(); if (MusicEnabled()) - S_PauseMusic(false); + Mus_SetPaused(false); g_player[myconnectindex].ps->gm = MODE_GAME; ud.recstat = 0; diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index 9e0b7d48e..557beea8b 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -1236,7 +1236,7 @@ int inExtraScreens = 0; void G_DisplayExtraScreens(void) { - S_StopMusic(); + Mus_Stop(); FX_StopAllSounds(); if (RR) return; @@ -1310,7 +1310,7 @@ void G_DisplayLogo(void) renderFlushPerms(); videoNextPage(); - S_StopMusic(); + Mus_Stop(); FX_StopAllSounds(); // JBF 20031228 S_ClearSoundLocks(); // JBF 20031228 if (RRRA) @@ -1724,7 +1724,7 @@ static void G_BonusCutscenes(void) G_HandleEventsWhileNoInput(); fadepal(0, 0, 0, 0, 252, 4); - S_StopMusic(); + Mus_Stop(); FX_StopAllSounds(); S_ClearSoundLocks(); break; @@ -1732,7 +1732,7 @@ static void G_BonusCutscenes(void) case 1: videoSetViewableArea(0, 0, xdim-1, ydim-1); - S_StopMusic(); + Mus_Stop(); videoClearScreen(0L); videoNextPage(); @@ -1760,7 +1760,7 @@ static void G_BonusCutscenes(void) case 3: videoSetViewableArea(0, 0, xdim-1, ydim-1); - S_StopMusic(); + Mus_Stop(); videoClearScreen(0L); videoNextPage(); @@ -1828,7 +1828,7 @@ static void G_BonusCutscenes(void) break; case 2: - S_StopMusic(); + Mus_Stop(); videoClearScreen(0L); videoNextPage(); if (adult_lockout == 0) @@ -2077,7 +2077,7 @@ void G_BonusScreen(int32_t bonusonly) totalclock = 0; bonuscnt = 0; - S_StopMusic(); + Mus_Stop(); FX_StopAllSounds(); S_ClearSoundLocks(); @@ -2669,7 +2669,7 @@ void G_BonusScreenRRRA(int32_t bonusonly) totalclock = 0; bonuscnt = 0; - S_StopMusic(); + Mus_Stop(); FX_StopAllSounds(); S_ClearSoundLocks(); diff --git a/source/rr/src/sector.cpp b/source/rr/src/sector.cpp index b716b3142..da95f232e 100644 --- a/source/rr/src/sector.cpp +++ b/source/rr/src/sector.cpp @@ -3649,12 +3649,12 @@ void P_HandleSharedKeys(int playerNum) else ud.pause_on = 1+SHIFTS_IS_PRESSED; if (ud.pause_on) { - S_PauseMusic(true); + Mus_SetPaused(true); S_PauseSounds(true); } else { - if (MusicEnabled()) S_PauseMusic(false); + if (MusicEnabled()) Mus_SetPaused(false); S_PauseSounds(false); diff --git a/source/rr/src/sounds.cpp b/source/rr/src/sounds.cpp index 473f9f1c3..0f5424707 100644 --- a/source/rr/src/sounds.cpp +++ b/source/rr/src/sounds.cpp @@ -122,23 +122,6 @@ void S_MenuSound(void) } -static int S_PlayMusic(const char *mapname, const char* fn, bool looping = true) -{ - return Mus_Play(mapname, fn, looping); -} - -void S_StopMusic(void) -{ - Mus_Stop(); -} - - -void S_PauseMusic(bool paused) -{ - Mus_SetPaused(paused); -} - - static void S_SetMusicIndex(unsigned int m) { g_musicIndex = m; @@ -146,25 +129,10 @@ static void S_SetMusicIndex(unsigned int m) ud.music_level = m % MAXLEVELS; } -bool S_TryPlayLevelMusic(unsigned int m) -{ - // For RR only explicitly invalidate the music name, but still allow the music code to run its own music substitution logic based on map names. - if (!S_PlayMusic(g_mapInfo[m].filename,RR? nullptr : g_mapInfo[m].musicfn)) - { - S_SetMusicIndex(m); - return false; - } - - return true; -} - void S_PlayLevelMusicOrNothing(unsigned int m) { - if (S_TryPlayLevelMusic(m)) - { - //S_StopMusic(); - S_SetMusicIndex(m); - } + Mus_Play(g_mapInfo[m].filename, RR ? nullptr : g_mapInfo[m].musicfn, true); + S_SetMusicIndex(m); } int S_TryPlaySpecialMusic(unsigned int m) @@ -174,7 +142,7 @@ int S_TryPlaySpecialMusic(unsigned int m) char const * musicfn = g_mapInfo[m].musicfn; if (musicfn != NULL) { - if (!S_PlayMusic(nullptr, musicfn, 1)) + if (!Mus_Play(nullptr, musicfn, 1)) { S_SetMusicIndex(m); return 0; @@ -189,20 +157,19 @@ void S_PlayRRMusic(int newTrack) char fileName[16]; if (!RR) return; - S_StopMusic(); + Mus_Stop(); g_cdTrack = newTrack != -1 ? newTrack : g_cdTrack+1; if (newTrack != 10 && (g_cdTrack > 9 || g_cdTrack < 2)) g_cdTrack = 2; Bsprintf(fileName, "track%.2d.ogg", g_cdTrack); - S_PlayMusic(fileName, 0); + Mus_Play(fileName, 0, true); } void S_PlaySpecialMusicOrNothing(unsigned int m) { if (S_TryPlaySpecialMusic(m)) { - //S_StopMusic(); S_SetMusicIndex(m); } } diff --git a/source/rr/src/sounds.h b/source/rr/src/sounds.h index 33b5b6082..39cb58900 100644 --- a/source/rr/src/sounds.h +++ b/source/rr/src/sounds.h @@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define sounds_public_h_ #include "sounds_common.h" +#include "z_music.h" BEGIN_RR_NS @@ -71,10 +72,8 @@ inline void S_ClearSoundLocks(void) {} int32_t S_LoadSound(uint32_t num); void S_PrecacheSounds(void); void S_MenuSound(void); -void S_PauseMusic(bool paused); void S_PauseSounds(bool paused); void S_PlayRRMusic(int newTrack = -1); -bool S_TryPlayLevelMusic(unsigned int m); void S_PlayLevelMusicOrNothing(unsigned int); int S_TryPlaySpecialMusic(unsigned int); void S_PlaySpecialMusicOrNothing(unsigned int); @@ -84,7 +83,6 @@ void S_SoundShutdown(void); void S_SoundStartup(void); void S_StopEnvSound(int32_t num,int32_t i); void S_StopAllSounds(void); -void S_StopMusic(void); void S_Update(void); void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset); From 0157446ad15a2b15a4aa190596b2d147d43b530e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 19:57:19 +0100 Subject: [PATCH 147/203] - thorough cleanup of the Shadow Warrior music code. This was one huge mess where nothing fit together. Also added an enhancement that the CD Audio boss theme tracks are also played when CD music is generally off, because these have no equivalent in MIDI. This needs to be checked if it's stylistically ok, though. --- source/common/music/music.cpp | 6 - source/common/statistics.cpp | 3 +- source/duke3d/src/sector.cpp | 3 +- source/duke3d/src/sounds.cpp | 44 ---- source/rr/src/savegame.cpp | 4 +- source/rr/src/sector.cpp | 2 +- source/rr/src/sounds.cpp | 2 +- source/sw/CMakeLists.txt | 1 + source/sw/src/demo.cpp | 14 +- source/sw/src/game.cpp | 41 +--- source/sw/src/menus.cpp | 30 --- source/sw/src/save.cpp | 10 +- source/sw/src/serp.cpp | 7 +- source/sw/src/sounds.cpp | 329 ++------------------------- source/sw/src/sounds.h | 6 +- source/sw/src/sumo.cpp | 26 +-- source/sw/src/zilla.cpp | 7 +- wadsrc/static/demolition/menudef.txt | 2 +- 18 files changed, 54 insertions(+), 483 deletions(-) diff --git a/source/common/music/music.cpp b/source/common/music/music.cpp index 30d36cc5b..0347cb840 100644 --- a/source/common/music/music.cpp +++ b/source/common/music/music.cpp @@ -563,12 +563,6 @@ int Mus_Play(const char *mapname, const char *fn, bool loop) { return 0; } - // A restart was requested. Ignore the music name being passed and just try tp restart what got here last. - if (mapname && *mapname == '*') - { - mapname = lastMusicLevel.GetChars(); - fn = lastMusic.GetChars(); - } // Allow per level music substitution. // For most cases using $musicalias would be sufficient, but that method only works if a level actually has some music defined at all. diff --git a/source/common/statistics.cpp b/source/common/statistics.cpp index 868ff3e5c..58ebf0e1c 100644 --- a/source/common/statistics.cpp +++ b/source/common/statistics.cpp @@ -259,7 +259,8 @@ static void SaveStatistics(const char *fn, TArray &statlist) { fw->Printf("\t{\n"); - qsort(&ls[0], ls.Size(), sizeof(ls[0]), compare_level_names); + // Only makes sense if level names follow a strict format. This is noz the case here. + //qsort(&ls[0], ls.Size(), sizeof(ls[0]), compare_level_names); for(unsigned k=0;kx-pos->x, cam->y-pos->y, (cam->z-pos->z)); -#ifdef SPLITSCREEN_MOD_HACKS - if (g_fakeMultiMode==2) - { - // HACK for splitscreen mod: take the min of sound distances - // to 1st and 2nd player. - - if (PN(spriteNum) == APLAYER && P_Get(spriteNum) == 1) - { - sndist = sndang = 0; - goto sound_further_processing; - } - - { - const vec3_t *cam2 = &g_player[1].ps->pos; - int32_t sndist2 = FindDistance3D(cam2->x-pos->x, cam2->y-pos->y, (cam2->z-pos->z)); - - if (sndist2 < sndist) - { - cam = cam2; - sectNum = g_player[1].ps->cursectnum; - angle = g_player[1].ps->ang; - - sndist = sndist2; - sndang = S_GetAngle(angle, cam, pos); - } - } - } -#endif - if ((g_sounds[soundNum].m & (SF_GLOBAL|SF_DTAG)) != SF_GLOBAL && S_IsAmbientSFX(spriteNum) && (sector[SECT(spriteNum)].lotag&0xff) < 9) // ST_9_SLIDING_ST_DOOR sndist = divscale14(sndist, SHT(spriteNum)+1); @@ -464,13 +435,6 @@ int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos) while (j < MAXSOUNDINSTANCES && snd.voices[j].id != voice) j++; -#ifdef DEBUGGINGAIDS - if (EDUKE32_PREDICT_FALSE(j >= MAXSOUNDINSTANCES)) - { - OSD_Printf(OSD_ERROR "%s %d: WTF?\n", __FILE__, __LINE__); - return -1; - } -#endif snd.voices[j].owner = spriteNum; @@ -482,14 +446,6 @@ int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos) int pitch = S_GetPitch(sndNum); auto const pOther = g_player[screenpeek].ps; -#ifdef SPLITSCREEN_MOD_HACKS - if (g_fakeMultiMode==2) - { - // splitscreen HACK - if (g_player[1].ps->i == spriteNum) - pOther = g_player[1].ps; -} -#endif if (pOther->sound_pitch) pitch += pOther->sound_pitch; diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index f056ef7db..5ee8113ad 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -1613,9 +1613,7 @@ static void postloadplayer(int32_t savegamep) S_ClearSoundLocks(); G_CacheMapData(); MUS_ResumeSaved(); - - if (MusicEnabled()) - Mus_SetPaused(false); + Mus_SetPaused(false); g_player[myconnectindex].ps->gm = MODE_GAME; ud.recstat = 0; diff --git a/source/rr/src/sector.cpp b/source/rr/src/sector.cpp index da95f232e..a75f5f9e6 100644 --- a/source/rr/src/sector.cpp +++ b/source/rr/src/sector.cpp @@ -3654,7 +3654,7 @@ void P_HandleSharedKeys(int playerNum) } else { - if (MusicEnabled()) Mus_SetPaused(false); + Mus_SetPaused(false); S_PauseSounds(false); diff --git a/source/rr/src/sounds.cpp b/source/rr/src/sounds.cpp index 0f5424707..cb5097f3d 100644 --- a/source/rr/src/sounds.cpp +++ b/source/rr/src/sounds.cpp @@ -155,7 +155,7 @@ int S_TryPlaySpecialMusic(unsigned int m) void S_PlayRRMusic(int newTrack) { char fileName[16]; - if (!RR) + if (!RR || !mus_redbook) return; Mus_Stop(); g_cdTrack = newTrack != -1 ? newTrack : g_cdTrack+1; diff --git a/source/sw/CMakeLists.txt b/source/sw/CMakeLists.txt index 30277199e..6de3ea9b1 100644 --- a/source/sw/CMakeLists.txt +++ b/source/sw/CMakeLists.txt @@ -24,6 +24,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../common/textures ${CMAKE_CURRENT_SOURCE_DIR}/../common/fonts ${CMAKE_CURRENT_SOURCE_DIR}/../common/2d + ${CMAKE_CURRENT_SOURCE_DIR}/../common/music ${CMAKE_CURRENT_SOURCE_DIR}/../platform ) diff --git a/source/sw/src/demo.cpp b/source/sw/src/demo.cpp index 648671680..863214725 100644 --- a/source/sw/src/demo.cpp +++ b/source/sw/src/demo.cpp @@ -84,7 +84,6 @@ SWBOOL DemoInitOnce = FALSE; short DemoDebugBufferMax = 1; extern char LevelName[]; -extern char LevelSong[16]; extern uint8_t FakeMultiNumPlayers; extern SWBOOL QuitFlag; @@ -179,7 +178,7 @@ DemoWriteHeader(void) return; strcpy(dh.map_name, LevelName); - strcpy(dh.LevelSong, LevelSong); + strcpy(dh.LevelSong, ""); dh.Level = Level; if (FakeMultiNumPlayers) @@ -238,7 +237,6 @@ DemoReadHeader(void) DREAD(&dh, sizeof(dh), 1, DemoFileIn); strcpy(DemoLevelName, dh.map_name); - strcpy(LevelSong, dh.LevelSong); Level = dh.Level; if (dh.numplayers > 1) { @@ -389,13 +387,6 @@ DemoPlayBack(void) ControlInfo info; int Xdim, Ydim, ScreenSize; - if (SW_SHAREWARE) - { - // code here needs to be similar to RunLevel startup code - PlaySong(LevelSong, -1, TRUE, TRUE); - } - - // Initialize Game part of network code (When ready2send != 0) InitNetVars(); @@ -570,8 +561,7 @@ ScenePlayBack(void) if (SW_SHAREWARE) { // code here needs to be similar to RunLevel startup code - strcpy(LevelSong,"yokoha03.mid"); - PlaySong(LevelSong, -1, TRUE, TRUE); + PlaySong(nullptr, "yokoha03.mid", -1); } // IMPORTANT - MUST be right before game loop diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 839f0bf3f..e0467609b 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -96,6 +96,7 @@ Things required to make savegames work: #include "m_argv.h" #include "debugbreak.h" #include "menu/menu.h" +#include "z_music.h" //#include "crc32.h" @@ -964,8 +965,6 @@ void InitGame() COVERsetbrightness(0, &palette_data[0][0]); InitFX(); // JBF: do it down here so we get a hold of the window handle - InitMusic(); - } @@ -986,7 +985,6 @@ TYTAIK16 MID YOKOHA03 MID */ -char LevelSong[16]; short SongLevelNum; //#ifndef SW_SHAREWARE LEVEL_INFO LevelInfo[MAX_LEVELS_REG+2] = @@ -1170,7 +1168,7 @@ InitLevel(void) // A few IMPORTANT GLOBAL RESETS InitLevelGlobals(); if (!DemoMode) - StopSong(); + Mus_Stop(); if (LoadGameOutsideMoveLoop) { @@ -1196,7 +1194,6 @@ InitLevel(void) FindLevelInfo(LevelName, &Level); if (Level > 0) { - strcpy(LevelSong, LevelInfo[Level].SongName); strcpy(LevelName, LevelInfo[Level].LevelName); UserMapName[0] = '\0'; } @@ -1235,7 +1232,6 @@ InitLevel(void) if (Level > 0) { // user map is part of game - treat it as such - strcpy(LevelSong, LevelInfo[Level].SongName); strcpy(LevelName, LevelInfo[Level].LevelName); UserMapName[0] = '\0'; } @@ -1243,7 +1239,6 @@ InitLevel(void) else { strcpy(LevelName, LevelInfo[Level].LevelName); - strcpy(LevelSong, LevelInfo[Level].SongName); } } @@ -1599,8 +1594,7 @@ void ResetKeyRange(uint8_t* kb, uint8_t* ke) void PlayTheme() { // start music at logo - strcpy(LevelSong,"theme.mid"); - PlaySong(LevelSong, RedBookSong[0], TRUE, TRUE); + PlaySong(nullptr, "theme.mid", RedBookSong[0]); DSPRINTF(ds,"After music stuff..."); MONO_PRINT(ds); @@ -1704,9 +1698,9 @@ void CreditsLevel(void) while (FX_SoundActive(handle)) ; // try 14 then 2 then quit - if (!PlaySong(NULL, 14, FALSE, TRUE)) + if (!PlaySong(nullptr, nullptr, 14, true)) { - if (!PlaySong(NULL, 2, FALSE, TRUE)) + if (!PlaySong(nullptr, nullptr, 2, true)) { handle = PlaySound(DIGI_NOLIKEMUSIC,&zero,&zero,&zero,v3df_none); if (handle > 0) @@ -1747,10 +1741,6 @@ void CreditsLevel(void) curpic = CREDITS1_PIC; } - - if (!SongIsPlaying()) - break; - if (inputState.GetKeyStatus(KEYSC_ESC)) break; } @@ -1759,7 +1749,7 @@ void CreditsLevel(void) videoClearViewableArea(0L); videoNextPage(); ResetKeys(); - StopSong(); + Mus_Stop(); } @@ -2247,10 +2237,7 @@ void BonusScreen(PLAYERp pp) totalclock = ototalclock = 0; limit = synctics; - if (MusicEnabled()) - { - PlaySong(voc[DIGI_ENDLEV].name, 3, TRUE, TRUE); - } + PlaySong(nullptr, voc[DIGI_ENDLEV].name, 3); // special case code because I don't care any more! if (FinishAnim) @@ -2565,10 +2552,7 @@ void StatScreen(PLAYERp mpp) inputState.ClearKeyStatus(KEYSC_SPACE); inputState.ClearKeyStatus(KEYSC_ENTER); - if (MusicEnabled()) - { - PlaySong(voc[DIGI_ENDLEV].name, 3, TRUE, TRUE); - } + PlaySong(nullptr, voc[DIGI_ENDLEV].name, 3); while (!inputState.GetKeyStatus(KEYSC_SPACE) && !inputState.GetKeyStatus(KEYSC_ENTER)) { @@ -2781,7 +2765,6 @@ void InitRunLevel(void) if (snd_ambience) StartAmbientSound(); SetCrosshair(); - PlaySong(LevelSong, -1, TRUE, TRUE); SetRedrawScreen(Player + myconnectindex); // crappy little hack to prevent play clock from being overwritten // for load games @@ -2803,7 +2786,7 @@ void InitRunLevel(void) waitforeverybody(); - StopSong(); + Mus_Stop(); if (Bstrcasecmp(CacheLastLevel, LevelName) != 0) DoTheCache(); @@ -2827,7 +2810,7 @@ void InitRunLevel(void) { track = RedBookSong[Level]; } - PlaySong(LevelSong, track, TRUE, TRUE); + PlaySong(LevelInfo[Level].LevelName, LevelInfo[Level].SongName, track); } InitPrediction(&Player[myconnectindex]); @@ -3270,12 +3253,12 @@ void PauseKey(PLAYERp pp) #define MSG_GAME_PAUSED "Game Paused" MNU_MeasureString(MSG_GAME_PAUSED, &w, &h); PutStringTimer(pp, TEXT_TEST_COL(w), 100, MSG_GAME_PAUSED, 999); - PauseSong(TRUE); + Mus_SetPaused(true); } else { pClearTextLine(pp, 100); - PauseSong(FALSE); + Mus_SetPaused(false); } } diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index b3a0ab579..eaa78bc41 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -2942,7 +2942,6 @@ void MNU_DoButton(MenuItem_p item, SWBOOL draw) SWBOOL state; int last_value; short shade = MENU_SHADE_DEFAULT; - extern char LevelSong[]; const char *extra_text = NULL; PLAYERp pp = &Player[myconnectindex]; int button_x,zero=0; @@ -3025,35 +3024,6 @@ void MNU_DoButton(MenuItem_p item, SWBOOL draw) } break; case btn_music: - last_value = mus_enabled; - mus_enabled = state = buttonsettings[item->button]; - if (mus_enabled != last_value) - { - SWBOOL bak; - - if (MusicEnabled()) - { - bak = DemoMode; - PlaySong(LevelSong, RedBookSong[Level], TRUE, TRUE); - DemoMode = bak; - } - else - { - bak = DemoMode; - StopSong(); - DemoMode = bak; - - if (SW_SHAREWARE) - { - handle = PlaySound(DIGI_NOLIKEMUSIC,&zero,&zero,&zero,v3df_none); - - if (handle > FX_Ok) - while (FX_SoundActive(handle)) - handleevents(); - } - } - } - break; case btn_talking: snd_speech = state = buttonsettings[item->button]; break; diff --git a/source/sw/src/save.cpp b/source/sw/src/save.cpp index 0c67aba1c..5b18cf121 100644 --- a/source/sw/src/save.cpp +++ b/source/sw/src/save.cpp @@ -57,6 +57,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "player.h" #include "i_specialpaths.h" #include "savegamehelp.h" +#include "z_music.h" //void TimerFunc(task * Task); BEGIN_SW_NS @@ -75,7 +76,6 @@ TO DO extern int lastUpdate; extern uint8_t RedBookSong[40]; extern char UserMapName[80]; -extern char LevelSong[16]; extern char SaveGameDescr[10][80]; extern int PlayClock; extern short TotalKillable; @@ -663,8 +663,6 @@ bool GameInterface::SaveGame(FSaveGameNode *sv) // game settings MWRITE(&gNet,sizeof(gNet),1,fil); - MWRITE(LevelSong,sizeof(LevelSong),1,fil); - MWRITE(palette,sizeof(palette),1,fil); MWRITE(palette_data,sizeof(palette_data),1,fil); MWRITE(&gs,sizeof(gs),1,fil); @@ -744,7 +742,7 @@ bool GameInterface::LoadGame(FSaveGameNode* sv) // Don't terminate until you've made sure conditions are valid for loading. if (InMenuLevel) - StopSong(); + Mus_Stop(); else TerminateLevel(); Terminate3DSounds(); @@ -1112,8 +1110,6 @@ bool GameInterface::LoadGame(FSaveGameNode* sv) // game settings MREAD(&gNet,sizeof(gNet),1,fil); - MREAD(LevelSong,sizeof(LevelSong),1,fil); - MREAD(palette,sizeof(palette),1,fil); MREAD(palette_data,sizeof(palette_data),1,fil); @@ -1225,7 +1221,7 @@ bool GameInterface::LoadGame(FSaveGameNode* sv) screenpeek = myconnectindex; PlayingLevel = Level; - PlaySong(LevelSong, RedBookSong[Level], TRUE, TRUE); + MUS_ResumeSaved(); if (snd_ambience) StartAmbientSound(); FX_SetVolume(snd_fxvolume); diff --git a/source/sw/src/serp.cpp b/source/sw/src/serp.cpp index 0e4debd0f..84f810f23 100644 --- a/source/sw/src/serp.cpp +++ b/source/sw/src/serp.cpp @@ -815,14 +815,13 @@ int DoDeathSpecial(short SpriteNum) { SPRITEp sp = &sprite[SpriteNum]; USERp u = User[SpriteNum]; - static SWBOOL alreadydid = FALSE; DoMatchEverything(NULL, sp->lotag, ON); - if (!SW_SHAREWARE && MusicEnabled() && !alreadydid) + if (!SW_SHAREWARE) { - PlaySong(0, RedBookSong[Level], TRUE, TRUE); - alreadydid = TRUE; + // Resume the regular music - in a hack-free fashion. + PlaySong(LevelInfo[Level].LevelName, LevelInfo[Level].SongName, RedBookSong[Level]); } BossSpriteNum[0] = -2; diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp index b668bd075..044e3d198 100644 --- a/source/sw/src/sounds.cpp +++ b/source/sw/src/sounds.cpp @@ -51,6 +51,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "menus.h" #include "config.h" #include "menu/menu.h" +#include "z_music.h" #ifdef _WIN32 #include "sdlayer.h" @@ -84,11 +85,9 @@ uint8_t RedBookSong[40] = SWBOOL Use_SoundSpriteNum = FALSE; int16_t SoundSpriteNum = -1; // Always set this back to -1 for proper validity checking! -SWBOOL MusicInitialized = FALSE; SWBOOL FxInitialized = FALSE; void SoundCallBack(unsigned int num); -SWBOOL LoadSong(const char *track); #define MUSIC_ID -65536 @@ -121,19 +120,6 @@ int voice; int loopflag; -typedef enum -{ - SongTypeNone, - SongTypeMIDI, - SongTypeWave, -} SongType_t; - -char *SongPtr = NULL; -int SongLength = 0; -char *SongName = NULL; -int SongTrack = 0; -SongType_t SongType = SongTypeNone; -int SongVoice = -1; extern SWBOOL DemoMode; // @@ -254,27 +240,6 @@ int PlayerYellVocs[] = DIGI_PLAYERYELL3 }; -#if 0 -// DEBUG -void CheckSndData(char *file, int line) -{ - short i; - - //return; - - for (i = 0; iname) - continue; -#endif - - if (!Bstrcasecmp(name, vp->name)) - { - // vp->priority = pri; - strcpy(vp->name, new_name); - vp->pitch_lo = pitch_lo; - vp->pitch_hi = pitch_hi; - } - } - } - - fclose(fin); -} - extern short Level; -SWBOOL -PlaySong(char *song_file_name, int cdaudio_track, SWBOOL loop, SWBOOL restart) +SWBOOL PlaySong(const char* mapname, const char* song_file_name, int cdaudio_track, bool isThemeTrack) //(nullptr, nullptr, -1, false) starts the normal level music. { - if (!MusicEnabled()) + if (mapname == nullptr && song_file_name == nullptr && cdaudio_track == -1) { - return FALSE; + // Get the music defined for the current level. + } - - if (DemoMode) - return FALSE; - - if (!restart) + // Play CD audio if enabled or if this is a theme track. + if (cdaudio_track >= 0 && (mus_redbook || isThemeTrack)) { - if (SongType == SongTypeWave) + FStringf trackname("track%02d.ogg", cdaudio_track); + if (!Mus_Play(nullptr, trackname, true)) { - if (SongTrack > 0 && SongTrack == cdaudio_track) - { - // ogg replacement for a CD track - return TRUE; - } - else if (SongName && song_file_name && !strcmp(SongName, song_file_name)) - { - return TRUE; - } - } - else if (SongType == SongTypeMIDI) - { - if (SongName && song_file_name && !strcmp(SongName, song_file_name)) - { - return TRUE; - } + buildprintf("Can't find CD track %i!\n", cdaudio_track); } } - - StopSong(); - - if (!SW_SHAREWARE) - { - if (cdaudio_track >= 0 && mus_redbook) - { - char waveformtrack[MAXWAVEFORMTRACKLENGTH]; - Bstrncpy(waveformtrack, gs.WaveformTrackName, MAXWAVEFORMTRACKLENGTH - 1); - - char *numPos = Bstrstr(waveformtrack, "??"); - - if (numPos && (numPos-waveformtrack) < MAXWAVEFORMTRACKLENGTH - 2) - { - static const char *tracktypes[] = { ".flac", ".ogg" }; - const size_t tracknamebaselen = Bstrlen(waveformtrack); - size_t i; - - numPos[0] = '0' + (cdaudio_track / 10) % 10; - numPos[1] = '0' + cdaudio_track % 10; - - for (i = 0; i < ARRAY_SIZE(tracktypes); ++i) - { - waveformtrack[tracknamebaselen] = '\0'; - Bstrncat(waveformtrack, tracktypes[i], MAXWAVEFORMTRACKLENGTH - 1); - - if (LoadSong(waveformtrack)) - { - SongVoice = FX_Play(SongPtr, SongLength, 0, 0, 0, - 255, 255, 255, FX_MUSIC_PRIORITY, 1.f, MUSIC_ID); - if (SongVoice > FX_Ok) - { - SongType = SongTypeWave; - SongTrack = cdaudio_track; - SongName = Bstrdup(waveformtrack); - return TRUE; - } - } - } - - buildprintf("Can't find CD track %i!\n", cdaudio_track); - } - else - { - buildprintf("Make sure to have \"??\" as a placeholder for the track number in your WaveformTrackName!\n"); - buildprintf(" e.g. WaveformTrackName = \"MUSIC/Track??\"\n"); - } - } - } - - if (!song_file_name || !LoadSong(song_file_name)) - { - return FALSE; - } - - if (!memcmp(SongPtr, "MThd", 4)) - { - MUSIC_PlaySong(SongPtr, SongLength, MUSIC_LoopSong); - SongType = SongTypeMIDI; - SongName = strdup(song_file_name); - return TRUE; - } - else - { - SongVoice = FX_Play(SongPtr, SongLength, 0, 0, 0, - 255, 255, 255, FX_MUSIC_PRIORITY, 1.f, MUSIC_ID); - if (SongVoice > FX_Ok) - { - SongType = SongTypeWave; - SongName = strdup(song_file_name); - return TRUE; - } - } - - return FALSE; + return Mus_Play(nullptr, song_file_name, true); } void @@ -522,57 +334,11 @@ StopFX(void) FX_StopAllSounds(); } -void -StopSong(void) -{ - if (DemoMode) - return; - - if (SongType == SongTypeWave && SongVoice > 0) - { - FX_StopSound(SongVoice); - SongVoice = 0; - } - else if (SongType == SongTypeMIDI) - { - MUSIC_StopSong(); - } - SongType = SongTypeNone; - - DO_FREE_AND_NULL(SongName); - SongTrack = 0; - - if (SongPtr) - { - FreeMem(SongPtr); - SongPtr = 0; - SongLength = 0; - } -} - -void -PauseSong(SWBOOL pauseon) -{ - if (!MusicEnabled()) return; - - if (SongType == SongTypeWave && SongVoice > 0) - { - FX_PauseVoice(SongVoice, pauseon); - } -} - - -SWBOOL -SongIsPlaying(void) -{ - return FALSE; -} - void StopSound(void) { StopFX(); - StopSong(); + Mus_Stop(); } // @@ -1082,34 +848,6 @@ ReadSound(FileReader &handle, VOC_INFOp vp, int length) return 0; } -SWBOOL -LoadSong(const char *filename) -{ - auto fr = fileSystem.OpenFileReader(filename, 0); - if (!fr.isOpen()) - { - return FALSE; - } - - auto size = fr.GetLength(); - - auto ptr = (char *) AllocMem(size); - if (ptr == NULL) - { - return FALSE; - } - - if (fr.Read(ptr, size) != size) - { - FreeMem(ptr); - return FALSE; - } - SongPtr = ptr; - SongLength = size; - - return TRUE; -} - void SoundStartup(void) { @@ -1159,52 +897,11 @@ SoundShutdown(void) } -/* -=================== -= -= MusicStartup -= -=================== -*/ - -void MusicStartup(void) -{ -#if 0 - auto fil = fileSystem.OpenFileReader("swtimbr.tmb", 0); - - if (fil.isOpen()) - { - auto tmb = fil.Read(); - if (tmb.Size()) - AL_RegisterTimbreBank(tmb.Data()); - } -#endif -} - void COVER_SetReverb(int amt) { FX_SetReverb(amt); } -/* -=================== -= -= MusicShutdown -= -=================== -*/ - -void MusicShutdown(void) -{ - StopSong(); - - int status = MUSIC_Shutdown(); - if (status != MUSIC_Ok) - { - buildprintf("Music error: %s\n", MUSIC_ErrorString(status)); - } -} - /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////// diff --git a/source/sw/src/sounds.h b/source/sw/src/sounds.h index 31a0b9dcf..e5b4af630 100644 --- a/source/sw/src/sounds.h +++ b/source/sw/src/sounds.h @@ -84,15 +84,11 @@ SWBOOL CacheSound(int num, int type); void COVER_SetReverb(int amt); void UnInitSound(void); void InitFX(void); -void InitMusic(void); void StopFX(void); -void StopSong(void); -void PauseSong(SWBOOL pauseon); void StopSound(void); void StartAmbientSound(void); void StopAmbientSound(void); -SWBOOL PlaySong(char *song_file_name, int cdaudio_track, SWBOOL loop, SWBOOL restart); -SWBOOL SongIsPlaying(void); +SWBOOL PlaySong(const char *mapname, const char *song_file_name, int cdaudio_track, bool isThemeTrack = false); //(nullptr, nullptr, -1, false) starts the normal level music. void PlaySoundRTS(int rts_num); // diff --git a/source/sw/src/sumo.cpp b/source/sw/src/sumo.cpp index c5a547105..b638f1de1 100644 --- a/source/sw/src/sumo.cpp +++ b/source/sw/src/sumo.cpp @@ -794,7 +794,6 @@ int DoSumoDeathMelt(short SpriteNum) { SPRITEp sp = &sprite[SpriteNum]; USERp u = User[SpriteNum]; - static SWBOOL alreadydid = FALSE; PlaySound(DIGI_SUMOFART, &sp->x, &sp->y, &sp->z, v3df_follow); @@ -803,10 +802,10 @@ int DoSumoDeathMelt(short SpriteNum) u->ID = 0; DoMatchEverything(NULL, sp->lotag, ON); - if (!SW_SHAREWARE && MusicEnabled() && !alreadydid) + if (!SW_SHAREWARE) { - PlaySong(0, RedBookSong[Level], TRUE, TRUE); - alreadydid = TRUE; + // Resume the regular music - in a hack-free fashion. + PlaySong(LevelInfo[Level].LevelName, LevelInfo[Level].SongName, RedBookSong[Level]); } BossSpriteNum[1] = -2; // Sprite is gone, set it back to keep it valid! @@ -882,25 +881,25 @@ BossHealthMeter(void) if (i == 0 && !serpwasseen) { serpwasseen = TRUE; - if (!SW_SHAREWARE && MusicEnabled()) + if (!SW_SHAREWARE) { - PlaySong(0, ThemeTrack[2], TRUE, TRUE); + PlaySong(nullptr, nullptr, ThemeTrack[2], true); } } else if (i == 1 && !sumowasseen) { sumowasseen = TRUE; - if (!SW_SHAREWARE && MusicEnabled()) + if (!SW_SHAREWARE) { - PlaySong(0, ThemeTrack[3], TRUE, TRUE); + PlaySong(nullptr, nullptr, ThemeTrack[3], true); } } else if (i == 2 && !zillawasseen) { zillawasseen = TRUE; - if (!SW_SHAREWARE && MusicEnabled()) + if (!SW_SHAREWARE) { - PlaySong(0, ThemeTrack[4], TRUE, TRUE); + PlaySong(nullptr, nullptr, ThemeTrack[4], true); } } } @@ -919,13 +918,6 @@ BossHealthMeter(void) if (i == 2 && (!zillawasseen || BossSpriteNum[2] < 0)) continue; - // This is needed because of possible saved game situation - if (!SW_SHAREWARE && !triedplay) - { - PlaySong(0, ThemeTrack[i+2], TRUE, FALSE); - triedplay = TRUE; // Only try once, then give up - } - sp = &sprite[BossSpriteNum[i]]; u = User[BossSpriteNum[i]]; diff --git a/source/sw/src/zilla.cpp b/source/sw/src/zilla.cpp index 70a557c4b..fc1fb8dbc 100644 --- a/source/sw/src/zilla.cpp +++ b/source/sw/src/zilla.cpp @@ -769,7 +769,6 @@ int DoZillaDeathMelt(short SpriteNum) { SPRITEp sp = &sprite[SpriteNum]; USERp u = User[SpriteNum]; - static SWBOOL alreadydid = FALSE; if (RANDOM_RANGE(1000) > 800) SpawnGrenadeExp(SpriteNum); @@ -778,10 +777,10 @@ int DoZillaDeathMelt(short SpriteNum) RESET(u->Flags, SPR_JUMPING|SPR_FALLING|SPR_MOVED); //DoMatchEverything(NULL, sp->lotag, ON); - if (!SW_SHAREWARE && MusicEnabled() && !alreadydid) + if (!SW_SHAREWARE) { - PlaySong(0, RedBookSong[Level], TRUE, TRUE); - alreadydid = TRUE; + // Resume the regular music - in a hack-free fashion. + PlaySong(LevelInfo[Level].LevelName, LevelInfo[Level].SongName, RedBookSong[Level]); } //KeepActorOnFloor(SpriteNum); diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 2243dd2a1..155eb7ee4 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -1286,7 +1286,7 @@ OptionMenu SoundOptions //protected //Option "$SNDMNU_RANDOMIZEPITCHES", "snd_pitched", "OnOff" Slider "$SNDMNU_CHANNELS", "snd_numchannels", 64, 128, 8, 0 staticText "" - ifgame (Blood, ShadowWarrior) + ifgame (Blood, ShadowWarrior, Redneck, RedneckRides) { Option "$SNDMNU_CDEMU", "mus_redbook", "OnOff" } From 8f90cc832486f2d2a977ff4d6dab87d831b70bc0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 20:48:16 +0100 Subject: [PATCH 148/203] - more Shadow Warrior cleanup. --- source/build/include/baselayer.h | 1 + source/common/gamecvars.cpp | 5 +- source/sw/src/draw.cpp | 7 +- source/sw/src/game.cpp | 3 - source/sw/src/game.h | 1 + source/sw/src/menus.cpp | 3728 ------------------------- source/sw/src/panel.cpp | 7 +- source/sw/src/settings.h | 4 - source/sw/src/sprite.cpp | 23 +- source/sw/src/swcvar.cpp | 2 +- source/sw/src/swcvar.h | 2 +- source/sw/src/weapon.cpp | 2 +- wadsrc/static/demolition/language.csv | 4 + wadsrc/static/demolition/menudef.txt | 38 +- 14 files changed, 68 insertions(+), 3759 deletions(-) diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index f590174c4..53b93b5d6 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -238,6 +238,7 @@ struct GameInterface } virtual void DrawPlayerSprite(const DVector2& origin, bool onteam) {} virtual void QuitToTitle() {} + virtual void SetAmbience(bool on) {} }; diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index c9c4df80a..9e8a2abac 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -144,7 +144,10 @@ CVARD(Bool, demoplay_showsync, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enable/dis // Sound -CVARD(Bool, snd_ambience, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enables/disables ambient sounds") // Not implemented for Blood +CUSTOM_CVARD(Bool, snd_ambience, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enables/disables ambient sounds") // Not implemented for Blood +{ + gi->SetAmbience(self); +} CVARD(Bool, snd_enabled, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enables/disables sound effects") CVARD(Bool, snd_tryformats, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enables/disables automatic discovery of replacement sounds and music in .flac and .ogg formats") CVARD(Bool, snd_doppler, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enable/disable 3d sound") diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index b1d6a8c4e..4c08f258b 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -57,6 +57,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "sector.h" #include "config.h" #include "menu/menu.h" +#include "swcvar.h" BEGIN_SW_NS @@ -766,7 +767,7 @@ analyzesprites(int viewx, int viewy, int viewz, SWBOOL mirror) //#define DART_REPEAT 6 //#define DART_PIC 2233 - if (gs.Darts) + if (sw_darts) if (tu->ID == 1793 || tsp->picnum == 1793) { tsp->picnum = 2519; @@ -778,7 +779,7 @@ analyzesprites(int viewx, int viewy, int viewz, SWBOOL mirror) #define DART_REPEAT 16 if (tu->ID == STAR1) { - if (gs.Darts) + if (sw_darts) { tsp->picnum = DART_PIC; tsp->ang = NORM_ANGLE(tsp->ang - 512 - 24); @@ -842,7 +843,7 @@ analyzesprites(int viewx, int viewy, int viewz, SWBOOL mirror) } } - if (gs.Darts) + if (sw_darts) if (tsp->statnum == STAT_STAR_QUEUE) { tsp->picnum = DART_PIC; diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index e0467609b..c774969d7 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -212,9 +212,6 @@ const GAME_SET gs_defaults = 0, // Time Limit 0, // Color TRUE, // nuke - "Track??", // waveform track name - FALSE, - TRUE, }; GAME_SET gs; diff --git a/source/sw/src/game.h b/source/sw/src/game.h index a7c6de29a..21ec3146e 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -2388,6 +2388,7 @@ struct GameInterface : ::GameInterface bool LoadGame(FSaveGameNode* sv) override; bool SaveGame(FSaveGameNode* sv) override; void DoPrintMessage(int prio, const char* text) override; + void SetAmbience(bool on) override { if (on) StartAmbientSound(); else StopAmbientSound(); } }; diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index eaa78bc41..b4af7e750 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -664,2541 +664,10 @@ SWBOOL MNU_ShareWareMessage() return TRUE; } - -# if 0 - -signed char MNU_InputString(char*, short); - -SWBOOL SavePrompt = FALSE; -extern SWBOOL InMenuLevel, LoadGameOutsideMoveLoop, LoadGameFromDemo; -extern uint8_t RedBookSong[40]; -extern short Level, Skill; -extern SWBOOL MusicInitialized, FxInitialized; -SWBOOL MNU_CheckUserMap(MenuItem *item); -SWBOOL MNU_SaveGameCheck(MenuItem_p item); -SWBOOL MNU_TeamPlayCheck(MenuItem *item); -SWBOOL MNU_CoopPlayCheck(MenuItem *item); -SWBOOL MNU_StatCheck(MenuItem *item); -SWBOOL MNU_LoadGameCheck(MenuItem *item); -SWBOOL MNU_TenCheck(MenuItem *item); -static SWBOOL MNU_TryMusicInit(void); -static void MNU_UpLevel(void); - -SWBOOL MNU_LoadSaveDraw(UserCall call, MenuItem *item); -SWBOOL MNU_LoadSaveMove(UserCall call, MenuItem *item); - -SWBOOL MenuButtonAutoRun = FALSE; -SWBOOL MenuButtonAutoAim = FALSE; -// misc load-save vars -short LastSaveNum = 99; -char SaveGameDescr[10][80]; -char BackupSaveGameDescr[80]; -short screen_tile = -1; - -SWBOOL MenuInputMode = FALSE; -int16_t MenuTextShade = 0; -SWBOOL passwordvalid = FALSE; - -SWBOOL MNU_HurtTeammateCheck(MenuItem *item); -SWBOOL MNU_TeamPlayChange(void); - -// Font pic table -unsigned short xlatfont[] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32 - 2274, 2294, 2274, 2277, 2278, 2280, 2295, 2282, 2283, 2281, 2286, 2297, 2285, // 45 - 2299, 2301, 2271, 2262, 2263, 2264, 2265, 2266, 2267, 2268, 2269, 2270, // 57 - 2292, 2293, 2296, 2287, 2298, 2300, 2275, 2236, 2237, 2238, 2239, 2240, // 69 - 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, // 81 - 2253, 2254, 2255, 2256, 2257, 2258, 2259, 2260, 2261, 2290, 2289, 2291, // 93 - 2279, 2284, 2295, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2244, // 105 - 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, // 117 - 2257, 2258, 2259, 2260, 2261, 2282, 2288, 2283, 2272 // 126 -}; - -int slidersettings [sldr_max] = -{ - 0, SENSE_DEFAULT, FXVOL_DEFAULT, MUSIC_DEFAULT, SCRSIZE_DEFAULT, - BRIGHTNESS_DEFAULT, BORDERTILE_DEFAULT, GAMETYPE_DEFAULT, NETLEVEL_DEFAULT, - MONSTERS_DEFAULT, KILLLIMIT_DEFAULT, TIMELIMIT_DEFAULT, PLAYERCOLOR_DEFAULT, - 0,0, // video mode - 32767>>12, 32767>>12, // advanced mouse scale -}; - -short buttonsettings[btn_max]; - -// EXTERNS //////////////////////////// -#define XDIM 320 -#define YDIM 200 -extern SWBOOL QuitFlag; - -void TerminateGame(void); -void ResetKeys(void); - -// GLOBALS //////////////////////////// - -char playertextbuffer[80]; // Used for various input strings -char playerbuflen = 0; // Current length of the string in -// the buffer -char maxtextlen; // max length allowed for current - -static struct { int xdim,ydim; } validresolutions[MAXVALIDMODES]; -static int numvalidresolutions = 0, validbpps[8], numvalidbpps = 0; - -static void UpdateValidModes(int bpp, int fs) -{ - int i, j; - - numvalidresolutions = numvalidbpps = 0; - for (i=0; i 0) - { - inputState.ClearKeyStatus(inputState.GetLastScanCode()); - - - currentmode = 0; - } - - MNU_MeasureString(strs[0], &w, &h); - - y = (YDIM - (h+3) * SIZ(strs)) / 2; - - for (i=0; i<(int)SIZ(strs); i++) - { - w = 0; - auto c = buttonMap.GetButtonName(currentkey); - sprintf(ds,strs[i],c,col[currentcol]); - for (j=0; ds[j]; j++) if (ds[j] == '_') ds[j] = ' '; - MNU_MeasureString(ds, &w, &h); - MNU_DrawString((XDIM - w)/2, y, ds, 0, 16); - y += h+3; - } - - } - else - { - // key list -#define PGSIZ 14 - int topitem = 0, botitem = NUMGAMEFUNCTIONS; - int i,j; - const char *morestr = "More..."; - const char *p; - - if (inputState.GetKeyStatus(KEYSC_ESC)) - { - inputState.ClearKeyStatus(sc_Escape); - cust_callback = NULL; - return TRUE; - } - else if (inputState.GetKeyStatus(sc_Delete)) - { - inputState.ClearKeyStatus(sc_Delete); - //Bindings.UnbindACommand(buttonMap.GetButtonName(M_KEYBOARDKEYS.currentEntry)); - } - else if (inputState.GetKeyStatus(sc_Home)) - { - currentkey = 0; - inputState.ClearKeyStatus(sc_Home); - } - else if (inputState.GetKeyStatus(sc_End)) - { - currentkey = NUMGAMEFUNCTIONS-1; - inputState.ClearKeyStatus(sc_End); - } - else if (inputState.GetKeyStatus(sc_PgDn)) - { - currentkey += PGSIZ; - if (currentkey >= NUMGAMEFUNCTIONS) currentkey = NUMGAMEFUNCTIONS-1; - inputState.ClearKeyStatus(sc_PgDn); - } - else if (inputState.GetKeyStatus(sc_PgUp)) - { - currentkey -= PGSIZ; - if (currentkey < 0) currentkey = 0; - inputState.ClearKeyStatus(sc_PgUp); - } - else if (I_EscapeTrigger()) - { - currentmode = 1; - inputState.ClearLastScanCode(); - inputState.ClearKeysDown(); - } - else if (I_MenuUp()) - { - I_MenuUpClear(); - currentkey = max(0, currentkey - 1); - } - else if (I_MenuDown()) - { - I_MenuDownClear(); - currentkey = min(NUMGAMEFUNCTIONS - 1, currentkey + 1); - } - else if (I_MenuRight()) - { - I_MenuRightClear(); - currentcol = 1; - } - else if (I_MenuLeft()) - { - I_MenuLeftClear(); - currentcol = 0; - } - - - if (NUMGAMEFUNCTIONS > PGSIZ) - { - topitem = currentkey - PGSIZ/2; - botitem = topitem + PGSIZ; - - if (topitem < 0) - { - botitem += -topitem; - topitem = 0; - } - else if (botitem >= NUMGAMEFUNCTIONS) - { - botitem = NUMGAMEFUNCTIONS-1; - topitem = botitem - PGSIZ; - } - } - - for (i = topitem; i <= botitem; i++) - { - auto c = buttonMap.GetButtonName(i); - for (j = 0; c[j]; j++) - { - if (c[j] == '_') ds[j] = ' '; - else ds[j] = c[j]; - } - ds[j] = 0; - #if 0 - j = OPT_LINE(0)+(i-topitem)*8; - MNU_DrawSmallString(OPT_XS, j, ds, (i==currentkey) ? 0 : 12, 16); - - p = keyGetName(KeyboardKeys[i][0]); - if (!p || !KeyboardKeys[i][0] || KeyboardKeys[i][0]==0xff) p = " -"; - MNU_DrawSmallString(OPT_XSIDE, j, p, (i==currentkey) ? -5 : 12, - (i==currentkey && currentcol==0) ? 14 : 16); - - p = keyGetName(KeyboardKeys[i][1]); - if (!p || !KeyboardKeys[i][1] || KeyboardKeys[i][1]==0xff) p = " -"; - MNU_DrawSmallString(OPT_XSIDE + 4*14, j, p, (i==currentkey) ? -5 : 12, - (i==currentkey && currentcol==1) ? 14 : 16); -#endif - } - - { - short dx,dy; - dx = 0, dy = 8; - MNU_MeasureSmallString(morestr,&dx,&dy); - if (topitem > 0) - MNU_DrawSmallString(XDIM - OPT_XS - dx, OPT_LINE(0), morestr, 8,16); - if (botitem < NUMGAMEFUNCTIONS-1) - MNU_DrawSmallString(XDIM - OPT_XS - dx, OPT_LINE(0)+PGSIZ*8, morestr, 8,16); - } -#undef PGSIZ - } - - return TRUE; -} - -static int MNU_SelectButtonFunction(const char *buttonname, int *currentfunc) -{ - // Todo: Branch off to the generic keybind menu. - const int PGSIZ = 9; - const char *strs[] = { "Select the function to assign to", "%s", "or ESCAPE to cancel." }; - int topitem = 0, botitem = NUMGAMEFUNCTIONS; - int i, j, y; - short w, h=0; - int returnval = 0; - - if (inputState.GetKeyStatus(sc_Escape)) - { - inputState.ClearKeyStatus(sc_Escape); - returnval = -1; - } - else if (inputState.GetKeyStatus(sc_Home)) - { - *currentfunc = 0; - inputState.ClearKeyStatus(sc_Home); - } - else if (inputState.GetKeyStatus(sc_End)) - { - *currentfunc = NUMGAMEFUNCTIONS; - inputState.ClearKeyStatus(sc_End); - } - else if (inputState.GetKeyStatus(sc_PgDn)) - { - *currentfunc += PGSIZ; - if (*currentfunc > NUMGAMEFUNCTIONS) *currentfunc = NUMGAMEFUNCTIONS; - inputState.ClearKeyStatus(sc_PgDn); - } - else if (inputState.GetKeyStatus(sc_PgUp)) - { - *currentfunc -= PGSIZ; - if (*currentfunc < 0) *currentfunc = 0; - inputState.ClearKeyStatus(sc_PgUp); - } - else if (I_GeneralTrigger()) - { - I_GeneralTriggerClear(); - returnval = 1; - } - else if (I_MenuUp()) - { - I_MenuUpClear(); - *currentfunc = max(0, *currentfunc - 1); - } - else if (I_MenuDown()) - { - I_MenuDownClear(); - *currentfunc = std::min(NUMGAMEFUNCTIONS, *currentfunc + 1); - } - - - if (NUMGAMEFUNCTIONS > PGSIZ) - { - topitem = *currentfunc - PGSIZ/2; - botitem = topitem + PGSIZ; - - if (topitem < 0) - { - botitem += -topitem; - topitem = 0; - } - else if (botitem > NUMGAMEFUNCTIONS) - { - botitem = NUMGAMEFUNCTIONS; - topitem = botitem - PGSIZ; - } - } - - y = OPT_LINE(0); - for (i=0; i<(int)SIZ(strs); i++) - { - w = 0; - sprintf(ds, strs[i], buttonname); - for (j=0; ds[j]; j++) if (ds[j] == '_') ds[j] = ' '; - MNU_MeasureString(ds, &w, &h); - MNU_DrawString((XDIM - w)/2, y, ds, 0, 16); - y += h; - } - - for (i = topitem; i <= botitem; i++) - { - if (i == 0) - { - strcpy(ds, " -none-"); - } - else - { - auto c = buttonMap.GetButtonName(i-1); - for (j = 0; c[j]; j++) - { - if (c[j] == '_') ds[j] = ' '; - else ds[j] = c[j]; - } - ds[j] = 0; - } - - j = OPT_LINE(4)+(i-topitem)*8; - MNU_DrawSmallString(130, j, ds, (i == *currentfunc) ? 0 : 12, 16); - } - - { - short dx = 0, dy = 8; - const char *morestr = "More..."; - - MNU_MeasureSmallString(morestr,&dx,&dy); - if (topitem > 0) - MNU_DrawSmallString(XDIM - OPT_XS - dx, OPT_LINE(4), morestr, 8,16); - if (botitem < NUMGAMEFUNCTIONS) - MNU_DrawSmallString(XDIM - OPT_XS - dx, OPT_LINE(4)+PGSIZ*8, morestr, 8,16); - } - - return returnval; -} - - -static MenuItem_p mouse_button_item = NULL; - -static SWBOOL MNU_MouseButtonPostProcess(MenuItem_p item) -{ - mouse_button_item = item; - return TRUE; -} - -SWBOOL MNU_MouseButtonSetupCustom(UserCall call, MenuItem_p item) -{ - // Mouse buttons are now handled as normal keybinds - return TRUE; -} - -static SWBOOL MNU_SetMouseButtonFunctions(MenuItem_p item) -{ - // Mouse buttons are now handled as normal keybinds - return TRUE; -} - - -static MenuItem_p mouse_digital_item = NULL; - -static SWBOOL MNU_MouseDigitalPostProcess(MenuItem_p item) -{ - mouse_digital_item = item; - return TRUE; -} - -static SWBOOL MNU_MouseDigitalSetupCustom(UserCall call, MenuItem_p item) -{ - // obsolete - return TRUE; -} - -static SWBOOL MNU_SetAdvancedMouseFunctions(MenuItem_p item) -{ - // obsolete - return TRUE; -} - - -static MenuItem_p joystick_button_item = NULL; - -static SWBOOL MNU_JoystickButtonsInitialise(MenuItem_p mitem) -{ - MenuItem_p item; - MenuItem templayer = { DefLayer(0, JoystickButtonNames[0], &joybuttonsgroup), OPT_XS, OPT_LINE(0), 1, m_defshade, 0, NULL, NULL, MNU_JoystickButtonPostProcess }; - MenuItem tempinert = { DefInert(0, JoystickButtonFunctions[0]), OPT_XSIDE, OPT_LINE(0), 1, m_defshade, 0, NULL, MNU_SetJoystickButtonFunctions, NULL }; - MenuItem temppagename = { DefInert(0, JoystickButtonPageName[0]), OPT_XS, OPT_LINE(JOYSTICKITEMSPERPAGE+1), 1, m_defshade, 0, NULL, NULL, NULL }; - MenuItem tempnextpage = { DefOption(0, "Next..."), OPT_XSIDE, OPT_LINE(JOYSTICKITEMSPERPAGE+1), 1, m_defshade, 0, MNU_JoystickButtonNextPage, NULL, NULL }; - MenuItem tempnone = { DefNone }; - const char *hatdirs[] = { " Up", " Right", " Down", " Left" }; - int button, page, pageitem; - - if (joybuttonssetupgroup.items != NULL) - { - return TRUE; - } - - page = 0; - pageitem = 0; - joybuttonssetupgroup.items = joybuttons_i[0]; - item = &joybuttons_i[0][0]; - - for (button = 0; button < joystick.numButtons * 2 + (joystick.numHats > 0) * 4; ) - { - if (button < joystick.numButtons * 2) - { - int dbutton = button / 2; - - strcpy(JoystickButtonNames[dbutton], joyGetName(1, dbutton)); - - templayer.text = JoystickButtonNames[dbutton]; - templayer.y = OPT_LINE(pageitem); - templayer.tics = dbutton; - memcpy(item, &templayer, sizeof(MenuItem)); - item++; - - tempinert.text = JoystickButtonFunctions[dbutton]; - tempinert.y = OPT_LINE(pageitem); - tempinert.tics = dbutton; - memcpy(item, &tempinert, sizeof(MenuItem)); - item++; - - pageitem++; - - strcpy(JoystickButtonNames[dbutton + MAXJOYBUTTONS], "Double "); - strcat(JoystickButtonNames[dbutton + MAXJOYBUTTONS], joyGetName(1, dbutton)); - - templayer.text = JoystickButtonNames[dbutton + MAXJOYBUTTONS]; - templayer.y = OPT_LINE(pageitem); - templayer.tics = 128 | dbutton; - memcpy(item, &templayer, sizeof(MenuItem)); - item++; - - tempinert.text = JoystickButtonFunctions[dbutton + MAXJOYBUTTONS]; - tempinert.y = OPT_LINE(pageitem); - tempinert.tics = 128 | dbutton; - memcpy(item, &tempinert, sizeof(MenuItem)); - item++; - - pageitem++; - - button += 2; - } - else - { - int dir = button - joystick.numButtons * 2; - int dbutton = joystick.numButtons + dir; - - strcpy(JoystickButtonNames[dbutton], joyGetName(2, 0)); - strcat(JoystickButtonNames[dbutton], hatdirs[dir]); - - templayer.text = JoystickButtonNames[dbutton]; - templayer.y = OPT_LINE(pageitem); - templayer.tics = dbutton; - memcpy(item, &templayer, sizeof(MenuItem)); - item++; - - tempinert.text = JoystickButtonFunctions[dbutton]; - tempinert.y = OPT_LINE(pageitem); - tempinert.tics = dbutton; - memcpy(item, &tempinert, sizeof(MenuItem)); - item++; - - pageitem++; - button++; - } - - if (pageitem == JOYSTICKITEMSPERPAGE || button == joystick.numButtons * 2 + (joystick.numHats > 0) * 4) - { - // next page - sprintf(JoystickButtonPageName[page], "Page %d / %d", page+1, - ((joystick.numButtons * 2 + (joystick.numHats > 0) * 4) / JOYSTICKITEMSPERPAGE) + 1); - - temppagename.text = JoystickButtonPageName[page]; - memcpy(item, &temppagename, sizeof(MenuItem)); - item++; - - memcpy(item, &tempnextpage, sizeof(MenuItem)); - item++; - - memcpy(item, &tempnone, sizeof(MenuItem)); - - page++; - pageitem = 0; - item = &joybuttons_i[page][0]; - } - } - - return TRUE; -} - -static SWBOOL MNU_JoystickButtonPostProcess(MenuItem_p item) -{ - joystick_button_item = item; - return TRUE; -} - -static SWBOOL MNU_JoystickButtonSetupCustom(UserCall call, MenuItem *item) -{ - // controller buttons are being handled as keybinds now - return TRUE; -} - -static SWBOOL MNU_JoystickButtonNextPage(void) -{ - JoystickButtonPage = (JoystickButtonPage + 1) % (((joystick.numButtons * 2 + (joystick.numHats > 0) * 4) / JOYSTICKITEMSPERPAGE) + 1); - joybuttonssetupgroup.items = &joybuttons_i[JoystickButtonPage][0]; - joybuttonssetupgroup.cursor = 0; - MNU_ItemPreProcess(&joybuttonssetupgroup); - return TRUE; -} - -static SWBOOL MNU_SetJoystickButtonFunctions(MenuItem_p item) -{ - // controller buttons are being handled as keybinds now - return TRUE; -} - - -static MenuItem_p joystick_axis_item = NULL; - -static SWBOOL MNU_JoystickAxesInitialise(MenuItem_p mitem) -{ -#if 0 - if (!CONTROL_JoyPresent) - { - return TRUE; - } - if (JoystickAxisPage < 0 || JoystickAxisPage >= joystick.numAxes) - { - JoystickAxisPage = 0; - } - - strcpy(JoystickAxisName, joyGetName(0, JoystickAxisPage)); - sprintf(JoystickAxisPageName, "Page %d / %d", JoystickAxisPage+1, joystick.numAxes); - slidersettings[sldr_joyaxisanalog] = MNU_ControlAxisOffset(JoystickAnalogAxes[JoystickAxisPage]); - slidersettings[sldr_joyaxisscale] = JoystickAnalogScale[JoystickAxisPage] >> 13; - slidersettings[sldr_joyaxisdead] = JoystickAnalogDead[JoystickAxisPage] >> 10; - slidersettings[sldr_joyaxissatur] = JoystickAnalogSaturate[JoystickAxisPage] >> 10; -#endif - return TRUE; -} - -static SWBOOL MNU_JoystickAxisPostProcess(MenuItem_p item) -{ - joystick_axis_item = item; - return TRUE; -} - -static SWBOOL MNU_JoystickAxisSetupCustom(UserCall call, MenuItem *item) -{ -#if 0 - static int currentfunc = 0; - - if (call == uc_touchup) - return TRUE; - - if (cust_callback == NULL) - { - if (call != uc_setup) - return FALSE; - - currentfunc = JoystickDigitalAxes[JoystickAxisPage][joystick_axis_item->tics]; - currentfunc++; - - cust_callback = MNU_JoystickAxisSetupCustom; - cust_callback_call = call; - cust_callback_item = item; - } - - { - short w, h = 0; - const char *s = "Joystick Axes"; - - rotatesprite(10 << 16, (5-3) << 16, MZ, 0, 2427, - m_defshade, 0, MenuDrawFlags|ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); - MNU_MeasureStringLarge(s, &w, &h); - MNU_DrawStringLarge(TEXT_XCENTER(w), 5, s); - } - - int selection = MNU_SelectButtonFunction(joystick_axis_item->text, ¤tfunc); - switch (selection) - { - case -1: //cancel - cust_callback = NULL; - break; - case 1: //acknowledge - currentfunc--; - JoystickDigitalAxes[JoystickAxisPage][joystick_axis_item->tics] = currentfunc; - CONTROL_MapDigitalAxis(JoystickAxisPage, currentfunc, joystick_axis_item->tics, controldevice_joystick); - MNU_SetJoystickAxisFunctions(joystick_axis_item); - cust_callback = NULL; - break; - default: break; - } -#endif - return TRUE; -} - -static SWBOOL MNU_JoystickAxisNextPage(void) -{ - JoystickAxisPage = (JoystickAxisPage + 1) % MNU_ControlAxisOffset(analog_maxtype); - joyaxessetupgroup.cursor = 1; - MNU_ItemPreProcess(&joyaxessetupgroup); - MNU_JoystickAxesInitialise(NULL); - return TRUE; -} - -static SWBOOL MNU_SetJoystickAxisFunctions(MenuItem_p item) -{ -#if 0 - int function; - char *p; - - function = JoystickDigitalAxes[JoystickAxisPage][item->tics]; - if (function < 0) - { - strcpy(JoystickAxisFunctions[item->tics], " -"); - } - else - { - strcpy(JoystickAxisFunctions[item->tics], buttonMap.GetButtonName(function)); - for (p = JoystickAxisFunctions[item->tics]; *p; p++) - { - if (*p == '_') - *p = ' '; - } - } -#endif - return TRUE; -} - - -SWBOOL -MNU_OrderCustom(UserCall call, MenuItem *item) -{ - static signed char on_screen = 0,last_screen = 0; - static int limitmove=0; - SWBOOL select_held = FALSE; - int zero = 0; - static SWBOOL DidOrderSound = FALSE; - short choose_snd; - static int wanghandle; - - static short RegOrderScreen[] = - { - // 5262, - // 5261, - 5111, - 5118, - 4979, - 5113, - - 5120 // 5114 // JBF: for my credits - }; - static short SWOrderScreen[] = - { - 5110, - 5112, - // 5262, - 5111, - 5118, - 4979, - 5113, - - 5120 // 5114 // JBF: for my credits - }; - short *OrderScreen, OrderScreenSiz; - - if (SW_SHAREWARE) - { - OrderScreen = SWOrderScreen; - OrderScreenSiz = SIZ(SWOrderScreen); - } - else - { - OrderScreen = RegOrderScreen; - OrderScreenSiz = SIZ(RegOrderScreen); - } - - // Ignore the special touchup calls - if (call == uc_touchup) - return TRUE; - - if (cust_callback == NULL) - { - if (call != uc_setup) - return FALSE; - } - - if (SW_SHAREWARE && on_screen == 0 && !DidOrderSound) - { - DidOrderSound = TRUE; - choose_snd = STD_RANDOM_RANGE(1000); - if (choose_snd > 500 && !FX_SoundValidAndActive(wanghandle)) - wanghandle = PlaySound(DIGI_WANGORDER1, &zero, &zero, &zero, v3df_dontpan); - else if (!FX_SoundValidAndActive(wanghandle)) - wanghandle = PlaySound(DIGI_WANGORDER2, &zero, &zero, &zero, v3df_dontpan); - } - - if (!select_held) - { - //order_input_buffered.dir = tst_input.dir; - // Support a few other keys too - if (inputState.GetKeyStatus(KEYSC_SPACE)||inputState.GetKeyStatus(KEYSC_ENTER)) - { - inputState.ClearKeyStatus(KEYSC_SPACE); - inputState.ClearKeyStatus(KEYSC_ENTER); - //tst_input.dir = dir_South; - } - } - -#if 0 - if (inputState.GetKeyStatus(KEY_MOUSE1)) - { - if (tst_input.button0 == order_input_buffered.button0 && - tst_input.button1 == order_input_buffered.button1 && - tst_input.dir == order_input_buffered.dir) - { - select_held = TRUE; - } - else - { - if (labs((int32_t) totalclock - limitmove) > 7) - { - order_input.button0 = order_input_buffered.button0; - order_input.button1 = order_input_buffered.button1; - order_input.dir = order_input_buffered.dir; - - order_input_buffered.button0 = tst_input.button0; - order_input_buffered.button1 = tst_input.button1; - order_input_buffered.dir = tst_input.dir; - - limitmove = (int32_t) totalclock; - } - } - } - else - { - select_held = FALSE; - order_input_buffered.button0 = tst_input.button0; - order_input_buffered.button1 = tst_input.button1; - order_input_buffered.dir = tst_input.dir; - } -#endif - - if (!inputState.GetKeyStatus(KEYSC_ESC)) - { - cust_callback = MNU_OrderCustom; - cust_callback_call = call; - cust_callback_item = item; - } - else - { - inputState.ClearKeyStatus(sc_Escape); - cust_callback = NULL; - DidOrderSound = FALSE; - on_screen = 0; - ExitMenus(); - } - - if (I_MenuUp()) - { - I_MenuUpClear(); - on_screen--; - } - else if (I_MenuDown()) - { - I_MenuDownClear(); - on_screen++; - } - else if (I_MenuLeft()) - { - I_MenuLeftClear(); - on_screen--; - } - else if (I_MenuRight()) - { - I_MenuRightClear(); - on_screen++; - } - -// CTW MODIFICATION -// I reversed the logic in here to allow the user to loop around. -// Yeah... I changed default behavior just because I wanted to. -// AND YOU CAN'T STOP ME SUCKER!!! - if (on_screen < 0) - on_screen = OrderScreenSiz-1; - - if (on_screen > OrderScreenSiz-1) - on_screen = 0; -// CTW MODIFICATION END - - int const shade = on_screen == OrderScreenSiz-1 ? 8 : 0; - rotatesprite(0,0,RS_SCALE,0,OrderScreen[on_screen], shade, 0, - (ROTATE_SPRITE_CORNER|ROTATE_SPRITE_SCREEN_CLIP|ROTATE_SPRITE_NON_MASK|ROTATE_SPRITE_IGNORE_START_MOST), - 0, 0, xdim-1, ydim-1); - - if (on_screen == OrderScreenSiz-1) - { - // Jonathon's credits page hack :-) - - static const char *jtitle = "^Port Credits"; - static const char *jtext[] = - { - "*Developers", - " Richard \"TerminX\" Gobeille", - " Evan \"Hendricks266\" Ramos", - " Alex \"pogokeen\" Dawson", - "*Retired developers", - " Pierre-Loup \"Plagman\" Griffais", - " Philipp \"Helixhorned\" Kutin", - "*Special thanks to", - " Jonathon \"JonoF\" Fowler", - "*Uses BUILD Engine technology by", - " Ken \"Awesoken\" Silverman", - "*Additional thanks to", - " Alexey \"Nuke.YKT\" Skrybykin", - " Jordon \"Striker\" Moss", - " Par \"Parkar\" Karlsson", // "Pär \"Parkar\" Karlsson", - " Ben \"ProAsm\" Smit", - " NY00123", - "-", - " Visit eduke32.com for news and updates" - }; -#if 0 - static const char *scroller[] = - { - "Thanks to these people for their input and contributions:", - "", - "", - "and all those who submitted bug reports and ", - "supported the project financially!", - "", - "", - "--x--", - "", - "", - "", - "" - }; -#endif - short dimx, dimy; - int ycur = 20; - unsigned ji; - - dimy = 0; MNU_MeasureString(jtitle, &dimx, &dimy); - MNU_DrawString(160-(dimx>>1), ycur, jtitle, 0, 0); - ycur += dimy + 8; - - for (ji = 0; ji < SIZ(jtext); ji++) - { - switch (jtext[ji][0]) - { - case '-': - ycur += 6; - break; - case '*': - dimx = dimy = 0; - MNU_MeasureString(&jtext[ji][1], &dimx, &dimy); - MNU_DrawString(160-(dimx>>1), ycur, &jtext[ji][1], 0, 16); - ycur += dimy+1; - break; - default: - if (ji>0 && jtext[ji-1][0] == '*') ycur += 3; - dimx = dimy = 0; - MNU_MeasureSmallString(&jtext[ji][1], &dimx, &dimy); - MNU_DrawSmallString(160-(dimx>>1), ycur, &jtext[ji][1], 0, 0); - ycur += dimy+1; - break; - } - } - -#if 0 - const int numscrollerlines = SIZ(scroller); - int m,i; - for (m=0, i=((int32_t) totalclock/104)%numscrollerlines; m<4; m++,i++) - { - if (i == numscrollerlines) - i=0; - dimx = dimy = 0; - MNU_MeasureSmallString(scroller[i], &dimx, &dimy); - MNU_DrawSmallString(160-(dimx>>1), 154+(m*7), scroller[i], 0, 8); - } -#endif - } - - //inputState.ClearKeysDown(); - - return TRUE; -} - -SWBOOL MNU_LoadModernDefaults(void) -{ - //SetDefaultKeyDefinitions(1); - //SetMouseDefaults(1); - return TRUE; -} - -SWBOOL MNU_LoadClassicDefaults(void) -{ - //SetDefaultKeyDefinitions(0); - //SetMouseDefaults(0); - return TRUE; -} - - -short EpisodeMenuSelection; - -void -ExitMenus(void) -{ - ControlPanelType = ct_mainmenu; - UsingMenus = FALSE; - - if (LoadGameOutsideMoveLoop) - return; - - ResumeGame(); - SetRedrawScreen(&Player[myconnectindex]); -} - -SWBOOL -void ResetMenuInput(void) -{ - cust_callback = NULL; - InputMode = FALSE; -} - - -SWBOOL -MNU_EpisodeCustom(void) -{ - EpisodeMenuSelection = currentmenu->cursor; - - return TRUE; -} - -SWBOOL -MNU_QuitCustom(UserCall call, MenuItem_p item) -{ - int select; - int ret; - extern SWBOOL DrawScreen; - - // Ignore the special touchup calls - if (call == uc_touchup) - return TRUE; - - if (cust_callback == NULL) - { - if (call != uc_setup) - return FALSE; - - memset(dialog, 0, sizeof(dialog)); - - dialog[0] = S_QUITYN; - } - - ret = MNU_Dialog(); - - if (DrawScreen) - return TRUE; - - if (!ret) - { - if (!inputState.GetKeyStatus(KEY_MOUSE1) && !inputState.GetKeyStatus(sc_N)) - { - cust_callback = MNU_QuitCustom; - cust_callback_call = call; - cust_callback_item = item; - } - else - { - cust_callback = NULL; - ExitMenus(); - } - } - else - { - cust_callback = NULL; - ExitMenus(); - } - - if (inputState.GetKeyStatus(sc_Y) || inputState.GetKeyStatus(sc_Enter) || inputState.GetKeyStatus(KEY_MOUSE1)) - { - if (CommPlayers >= 2) - MultiPlayQuitFlag = TRUE; - else - QuitFlag = TRUE; - - ExitMenus(); - } - - inputState.ClearKeysDown(); - - return TRUE; -} - -// MENU FUNCTIONS ///////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////// -// Set some global menu related defaults -//////////////////////////////////////////////// -void -MNU_InitMenus(void) -{ - pClearTextLine(Player + myconnectindex, TEXT_INFO_LINE(0)); - - slidersettings[sldr_mouse] = in_mousesensitivity; // (MOUSE_SENS_MAX_VALUE / SLDR_MOUSESENSEMAX); - - { - int i,newx=xdim,newy=ydim; - - buttonsettings[btn_videofs] = fullscreen; - - UpdateValidModes(bpp,fullscreen); - for (i=0; i= 0) - for (i=0; i>13; - //slidersettings[sldr_mousescaley] = MouseAnalogScale[1]>>13; - - slidersettings[sldr_joyaxisscale] = 0; - slidersettings[sldr_joyaxisanalog] = 0; - slidersettings[sldr_joyaxisdead] = 0; - slidersettings[sldr_joyaxissatur] = 0; - - // Distinguish between Single or Multiplay for new game menu types - if (numplayers > 1) - main_i[0].child = &networkgroup; - else -// #ifdef SW_SHAREWARE - main_i[0].child = &episodegroup; -// #else -// main_i[0].child = &skillgroup; -// #endif - main_i[4].text = (SW_SHAREWARE) ? MAIN_MENU_HOW_TO_ORDER : MAIN_MENU_COOL_STUFF; - main_i[4].hotkey = (SW_SHAREWARE) ? KEYSC_H : KEYSC_C; -} - -//////////////////////////////////////////////// -// Get an input string from user using small font -//////////////////////////////////////////////// - -signed char MNU_InputSmallString(char *name, short pix_width) -{ - char ch; - short w, h; - -#define ascii_backspace 8 -#define ascii_esc 27 -#define ascii_return 13 - - if (!MoveSkip4 && !MessageInputMode) - { - if (I_MenuUp()) - { - CON_CommandHistory(1); - } - else if (I_MenuDown()) - { - CON_CommandHistory(-1); - } - } - - while (inputState.keyBufferWaiting()) - { - ch = inputState.keyGetChar(); - - // skip any extended key - if (ch == 0) - { - ch = inputState.keyGetChar(); - if (ch == 104) // extended enter - ch = ascii_return; - else - continue; - } - - if (ch == ascii_backspace) - { - name[strlen(name) - 1] = '\0'; - continue; - } - else if (ch == ascii_esc) - { - return -1; - } - else if (ch == ascii_return) - { - return FALSE; - } - else if (!isprint(ch)) - continue; - - MNU_MeasureSmallString(name, &w, &h); - if (w < pix_width) - { - size_t const namelen = strlen(name); - if (namelen < 256) // Dont let it go too far! - { - name[namelen] = ch; - name[namelen+1] = '\0'; - } - } - } - - return TRUE; - -} - -//////////////////////////////////////////////// -// Draw dialog text on screen -//////////////////////////////////////////////// -static SWBOOL MNU_Dialog(void) -{ - short ndx, linecnt, w[MAXDIALOG], h, x, y; - - linecnt = 0; - h = 8; - - for (ndx = 0; ndx < MAXDIALOG && dialog[ndx]; ndx++) - { - MNU_MeasureString(dialog[ndx], &w[ndx], &h); - ASSERT(w[ndx] < XDIM); - linecnt++; - } - - y = ((YDIM - ((h * linecnt) + (linecnt * 2))) / 2); - - for (ndx = 0; ndx < linecnt; ndx++) - { - x = ((XDIM - w[ndx]) / 2); - MNU_DrawString(x, y, dialog[ndx],1,16); - y += (h + 3); - } - - if (inputState.GetKeyStatus(sc_Y) || inputState.GetKeyStatus(sc_Enter) || inputState.GetKeyStatus(KEY_MOUSE1)) - return TRUE; - else - return FALSE; -} - -//////////////////////////////////////////////// -// Get an input string from user -//////////////////////////////////////////////// - -signed char MNU_InputString(char *name, short pix_width) -{ - char ch; - short w, h; - -#define ascii_backspace 8 -#define ascii_esc 27 -#define ascii_return 13 - - while (inputState.keyBufferWaiting()) - { - ch = inputState.keyGetChar(); - - ////DSPRINTF(ds, "%c %d", ch, ch); - //MONO_PRINT(ds); - - // skip most extended keys - if (ch == 0) - { - ch = inputState.keyGetChar(); - - ////DSPRINTF(ds, "extended key %c %d", ch, ch); - //MONO_PRINT(ds); - - if (ch == 104) // extended enter - ch = ascii_return; - else - continue; - } - - if (ch == ascii_backspace) - { - name[strlen(name) - 1] = '\0'; - continue; - } - else if (ch == ascii_esc) - { - return -1; - } - else if (ch == ascii_return) - { - return FALSE; - } - else if (!isprint(ch)) - continue; - - MNU_MeasureString(name, &w, &h); - if (w < pix_width) - { - size_t const namelen = strlen(name); - name[namelen] = ch; - name[namelen+1] = '\0'; - } - } - - return TRUE; - -} - -#define SS_XSTART 146L -#define SS_YSTART SD_YSTART -#define SS_BORDER_SIZE 5L - -void LoadSaveMsg(const char *msg) -{ - short w,h; - - renderFlushPerms(); - DrawMenuLevelScreen(); - strcpy(ds, msg); - MNU_MeasureString(ds, &w, &h); - MNU_DrawString(TEXT_XCENTER(w), 170, ds, 1, 16); - videoNextPage(); -} - - -//////////////////////////////////////////////// -// Load Game menu -// This function gets called whenever you -// press enter on one of the load game -// spots. -// I'm figuring it need to do the following: -// . Load the game if there is one by calling: MNU_LoadGameCustom. -//////////////////////////////////////////////// -SWBOOL MNU_GetLoadCustom(void) -{ - return TRUE; -} - -//////////////////////////////////////////////// -// Save Game menu -// This function gets called whenever you -// press enter on one of the save game -// spots. -// I'm figuring it need to do the following: -// . Call MNU_GetInput to allow string input of description. -// . Save the game if there is one by calling: MNU_SaveGameCustom. -//////////////////////////////////////////////// -SWBOOL MNU_GetSaveCustom(void) -{ - return TRUE; -} - -//////////////////////////////////////////////// -// Load/Save Touchup function -// This function gets called each frame by DrawMenus -//////////////////////////////////////////////// - -static SWBOOL MNU_DrawLoadSave(short game_num) -{ - // screen border - rotatesprite(SS_XSTART << 16, SS_YSTART << 16, MZ, 0, pic_loadsavescreen, - 0, 0, MenuDrawFlags | ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); - - // description box - rotatesprite((SD_XSTART) << 16, (SD_YSTART) << 16, MZ, 0, pic_savedescr, - 0, 0, MenuDrawFlags | ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); - - // cursor for text boxes - rotatesprite((SD_XSTART + 3) << 16, (SD_LINE(game_num) + 1) << 16, MZ, 0, pic_loadsavecursor, - 0, 0, MenuDrawFlags | ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); - - return TRUE; -} - -static char SaveGameInfo1[80]; -static char SaveGameInfo2[80]; - - -SWBOOL MNU_LoadSaveMove(UserCall call, MenuItem_p item) -{ - short i; - short game_num; - short tile; - static short SaveGameEpisode, SaveGameLevel, SaveGameSkill; - SWBOOL GotInput = FALSE; - - if (!UsingMenus) - return TRUE; - - game_num = currentmenu->cursor; - - // read all descr first time through - LastSaveNum starts at 99 - if (LastSaveNum == 99) - { - memset(SaveGameDescr, '\0', sizeof(SaveGameDescr)); - - for (i = 0; i < 10; i++) - LoadGameDescr(i, SaveGameDescr[i]); - } - - // cursor has moved - read header - if (game_num != LastSaveNum) - { - screen_tile = LoadGameFullHeader(game_num, SaveGameDescr[game_num], - &SaveGameLevel, &SaveGameSkill); - - sprintf(SaveGameInfo1, "Level %d, Skill %d", SaveGameLevel, SaveGameSkill+1); - SaveGameInfo2[0] = 0; - } - - LastSaveNum = game_num; - - // input mode check - if (MenuInputMode) - { - MenuItem *item = ¤tmenu->items[currentmenu->cursor]; - - if (SavePrompt) - { - if (inputState.GetKeyStatus(sc_Y) || inputState.GetKeyStatus(sc_Enter)) - { - inputState.ClearKeyStatus(sc_Y); - inputState.ClearKeyStatus(sc_Enter); - SavePrompt = FALSE; - // use input - item->custom(); - } - else if (inputState.GetKeyStatus(sc_N)) - { - inputState.ClearKeyStatus(sc_N); - strcpy(SaveGameDescr[game_num], BackupSaveGameDescr); - SavePrompt = FALSE; - MenuInputMode = FALSE; - } - } - else - // get input - switch (MNU_InputString(SaveGameDescr[game_num], 114)) - { - case -1: // Cancel Input (pressed ESC) or Err - strcpy(SaveGameDescr[game_num], BackupSaveGameDescr); - MenuInputMode = FALSE; - inputState.ClearKeysDown(); - break; - case FALSE: // Input finished (RETURN) - // no input - if (SaveGameDescr[game_num][0] == '\0') - { - strcpy(SaveGameDescr[game_num], BackupSaveGameDescr); - MenuInputMode = FALSE; - } - else - { - GotInput = TRUE; - } - inputState.ClearKeyStatus(sc_Enter); - break; - case TRUE: // Got input - break; - } - - if (GotInput) - { - if (BackupSaveGameDescr[0]) - SavePrompt = TRUE; - - if (!SavePrompt) - { - // use input - item->custom(); - } - } - } - - return TRUE; -} - -SWBOOL MNU_LoadSaveDraw(UserCall call, MenuItem_p item) -{ - short i; - short game_num; - short tile; - - game_num = currentmenu->cursor; - - // misc drawing - MNU_DrawLoadSave(game_num); - - // print game descriptions - for (i = 0; i < 10; i++) - { - if (i == game_num && MenuInputMode && !SavePrompt) - { - static SWBOOL cur_show; - char tmp[sizeof(SaveGameDescr[0])*2]; - - //cur_show ^= 1; - cur_show = ((int32_t) totalclock & 32); - if (cur_show) - { - // add a cursor to the end - sprintf(tmp, "%s_", SaveGameDescr[i]); - } - else - strcpy(tmp, SaveGameDescr[i]); - - MNU_DrawString(SD_XSTART + 4, SD_YSTART + (i * SD_YOFF) + 2, tmp, 1, 16); - } - else if (SaveGameDescr[i][0] != '\0') - { - MNU_DrawString(SD_XSTART + 4, SD_YSTART + (i * SD_YOFF) + 2, SaveGameDescr[i], 1, 16); - } - } - - if (screen_tile != -1) - { - // draw 160x100 save screen - rotatesprite((SS_XSTART + SS_BORDER_SIZE) << 16, (SS_YSTART + SS_BORDER_SIZE) << 16, (1 << 16), 0 + 512, screen_tile, - 0, 0, MenuDrawFlags | ROTATE_SPRITE_CORNER | ROTATE_SPRITE_NON_MASK | ROTATE_SPRITE_YFLIP, 0, 0, xdim - 1, ydim - 1); - - // draw info string - MNU_DrawString(SS_XSTART + 13, SS_YSTART + 100 + 10, SaveGameInfo1, 1, 16); - MNU_DrawString(SS_XSTART + 13, SS_YSTART + 100 + 18, SaveGameInfo2, 1, 16); - - if (SavePrompt) - { - MNU_DrawString(SS_XSTART + SS_BORDER_SIZE + 5, SS_YSTART + SS_BORDER_SIZE + 47, "Overwrite previous", 1, 16); - MNU_DrawString(SS_XSTART + SS_BORDER_SIZE + 5, SS_YSTART + SS_BORDER_SIZE + 47 + 12, " saved game (Y/N)", 1, 16); - } - } - else - { - // draw 160x100 black pic - rotatesprite((SS_XSTART + SS_BORDER_SIZE) << 16, (SS_YSTART + SS_BORDER_SIZE) << 16, (1 << 16), 0, pic_loadsavescreenbak, - 0, 0, MenuDrawFlags | ROTATE_SPRITE_CORNER | ROTATE_SPRITE_NON_MASK, 0, 0, xdim - 1, ydim - 1); - - MNU_DrawString(SS_XSTART + SS_BORDER_SIZE + 60, SS_YSTART + SS_BORDER_SIZE + 47, "Empty", 1, 16); - } - - - return TRUE; -} - -SWBOOL MNU_ShareWareCheck(MenuItem *item) -{ - if (SW_SHAREWARE) - { - SET(item->flags, mf_disabled); - } - - return TRUE; -} - -SWBOOL MNU_CheckUserMap(MenuItem *item) -{ - if (UserMapName[0] == '\0') - RESET(item->flags, mf_disabled); - else - SET(item->flags, mf_disabled); - return TRUE; -} - -SWBOOL MNU_ShareWareMessage(MenuItem *item) -{ - const char *extra_text; - short w,h; - - if (SW_SHAREWARE) - { - extra_text = "Be sure to call 800-3DREALMS today"; - MNU_MeasureString(extra_text, &w, &h); - MNU_DrawString(TEXT_XCENTER(w), 110, extra_text, 1, 16); - extra_text = "and order the game."; - MNU_MeasureString(extra_text, &w, &h); - MNU_DrawString(TEXT_XCENTER(w), 120, extra_text, 1, 16); - extra_text = "You are only playing the first "; - MNU_MeasureString(extra_text, &w, &h); - MNU_DrawString(TEXT_XCENTER(w), 130, extra_text, 1, 16); - extra_text = "four levels, and are missing most"; - MNU_MeasureString(extra_text, &w, &h); - MNU_DrawString(TEXT_XCENTER(w), 140, extra_text, 1, 16); - extra_text = "of the game, weapons and monsters."; - MNU_MeasureString(extra_text, &w, &h); - MNU_DrawString(TEXT_XCENTER(w), 150, extra_text, 1, 16); - extra_text = "See the ordering information."; - MNU_MeasureString(extra_text, &w, &h); - MNU_DrawString(TEXT_XCENTER(w), 160, extra_text, 1, 16); - SET(item->flags, mf_disabled); - } - return TRUE; -} - -SWBOOL MNU_SaveGameCheck(MenuItem *item) -{ - extern SWBOOL InMenuLevel; - extern SWBOOL DemoMode; - - if (0) // JBF: Until we fix the symbol table dilemma, saving is off limits - { - SET(item->flags, mf_disabled); - return TRUE; - } - - if (CommEnabled || numplayers > 1 || DemoMode) - { - SET(item->flags, mf_disabled); - return TRUE; - } - - if (InMenuLevel) - SET(item->flags, mf_disabled); - else - { - if (TEST(Player[myconnectindex].Flags, PF_DEAD)) - SET(item->flags, mf_disabled); - else - RESET(item->flags, mf_disabled); - } - - - return TRUE; -} - -SWBOOL MNU_TenCheck(MenuItem *item) -{ - if (CommEnabled || numplayers > 1) - { - SET(item->flags, mf_disabled); - return TRUE; - } - - return TRUE; -} - -SWBOOL MNU_LoadGameCheck(MenuItem *item) -{ - - if (0) // JBF: Until we fix the symbol table dilemma, loading is off limits - { - SET(item->flags, mf_disabled); - return TRUE; - } - - if (CommEnabled || numplayers > 1) - { - SET(item->flags, mf_disabled); - return TRUE; - } - - return TRUE; -} - -SWBOOL MNU_StatCheck(MenuItem *item) -{ - if (CommEnabled || numplayers > 1) - { - SET(item->flags, mf_disabled); - return TRUE; - } - - return TRUE; -} - -SWBOOL MNU_HurtTeammateCheck(MenuItem *item) -{ - switch (gs.NetGameType+1) - { - // deathmatch and deathmatch no respawn - case MULTI_GAME_COMMBAT: - case MULTI_GAME_COMMBAT_NO_RESPAWN: - if (gs.NetTeamPlay) - RESET(item->flags, mf_disabled); - else - SET(item->flags, mf_disabled); - break; - // co-op - case MULTI_GAME_COOPERATIVE: - RESET(item->flags, mf_disabled); - break; - } - - return TRUE; -} - -SWBOOL MNU_TeamPlayCheck(MenuItem *item) -{ - switch (gs.NetGameType+1) - { - // co-op - case MULTI_GAME_COOPERATIVE: - SET(item->flags, mf_disabled); - break; - default: - RESET(item->flags, mf_disabled); - break; - } - - return TRUE; -} - -SWBOOL MNU_CoopPlayCheck(MenuItem *item) -{ - switch (gs.NetGameType+1) - { - // co-op - case MULTI_GAME_COOPERATIVE: - SET(item->flags, mf_disabled); - break; - default: - RESET(item->flags, mf_disabled); - break; - } - - return TRUE; -} - -SWBOOL -MNU_TeamPlayChange(void) -{ - // if team play changes then do a pre process again - MNU_ItemPreProcess(currentmenu); - return TRUE; -} - -SWBOOL MNU_MouseCheck(MenuItem *item) -{ - if (!CONTROL_MousePresent) - { - SET(item->flags, mf_disabled); - } - else - { - RESET(item->flags, mf_disabled); - } - - return TRUE; -} - -SWBOOL -MNU_JoystickCheck(MenuItem *item) -{ - if (!CONTROL_JoyPresent) - { - SET(item->flags, mf_disabled); - } - else - { - RESET(item->flags, mf_disabled); - } - - return TRUE; -} - -// This is only called when Enter is pressed -static SWBOOL -MNU_TryMusicInit(void) -{ - if (currentmenu->cursor == 0) - MNU_MusicCheck(¤tmenu->items[currentmenu->cursor+1]); - - return TRUE; -} - -SWBOOL -MNU_MusicCheck(MenuItem *item) -{ - RESET(item->flags, mf_disabled); - return TRUE; -} - -SWBOOL MNU_FxCheck(MenuItem *item) -{ - RESET(item->flags, mf_disabled); - return TRUE; -} - -SWBOOL MNU_MusicFxCheck(MenuItem *item) -{ - RESET(item->flags, mf_disabled); - return TRUE; -} - -//////////////////////////////////////////////// -// Do a toggle button -//////////////////////////////////////////////// -void MNU_DoButton(MenuItem_p item, SWBOOL draw) -{ - int x, y; - SWBOOL state; - int last_value; - short shade = MENU_SHADE_DEFAULT; - const char *extra_text = NULL; - PLAYERp pp = &Player[myconnectindex]; - int button_x,zero=0; - int handle=0; - extern SWBOOL MusicInitialized,FxInitialized; - - button_x = OPT_XSIDE; - - x = item->x; - y = item->y; - - if (TEST(item->flags, mf_disabled)) - { - shade = MENU_SHADE_INACTIVE; - } - - if (!draw) - { - switch (item->button) - { - case btn_nuke: - gs.NetNuke = state = buttonsettings[item->button]; - break; - case btn_voxels: - r_voxels = state = buttonsettings[item->button]; - break; - case btn_stats: - hud_stats = state = buttonsettings[item->button]; - break; - case btn_darts: - gs.Darts = state = buttonsettings[item->button]; - break; - case btn_autoswitch: - gs.WeaponAutoSwitch = state = buttonsettings[item->button]; - break; - case btn_markers: - gs.NetSpawnMarkers = state = buttonsettings[item->button]; - break; - case btn_teamplay: - gs.NetTeamPlay = state = buttonsettings[item->button]; - break; - case btn_friendlyfire: - gs.NetHurtTeammate = state = buttonsettings[item->button]; - break; - case btn_crosshair: - cl_crosshair = state = buttonsettings[item->button]; - break; - case btn_auto_aim: - last_value = cl_autoaim; - cl_autoaim = state = buttonsettings[item->button]; - if (cl_autoaim != last_value) - MenuButtonAutoAim = TRUE; - break; - case btn_messages: - hud_messages = state = buttonsettings[item->button]; - break; - case btn_auto_run: - last_value = cl_autorun; - cl_autorun = state = buttonsettings[item->button]; - if (cl_autorun != last_value) - MenuButtonAutoRun = TRUE; - break; - case btn_mouse_invert: - in_mouseflip = state = buttonsettings[item->button]; - break; - case btn_bobbing: - cl_viewbob = state = buttonsettings[item->button]; - break; - case btn_sound: - - if (!FxInitialized) - break; - - last_value = snd_enabled; - snd_enabled = state = buttonsettings[item->button]; - if (snd_enabled != last_value) - { - if (!SoundEnabled()) - StopFX(); - } - break; - case btn_music: - case btn_talking: - snd_speech = state = buttonsettings[item->button]; - break; - case btn_playcd: - last_value = true; - state = buttonsettings[item->button]; - break; - case btn_ambience: - last_value = snd_ambience; - snd_ambience = state = buttonsettings[item->button]; - if (snd_ambience != last_value) - { - if (!InMenuLevel) - { - if (snd_ambience) - StartAmbientSound(); - else - StopAmbientSound(); - } - } - break; - case btn_flipstereo: - last_value = snd_reversestereo; - snd_reversestereo = state = buttonsettings[item->button]; - break; - case btn_shadows: - r_shadows = state = buttonsettings[item->button]; - break; - - case btn_parental: - state = buttonsettings[btn_parental] = adult_lockout = FALSE; - if (!InMenuLevel) - JS_ToggleLockouts(); - break; - - case btn_videofs: - { - int lastx, lasty, lastbpp, newoffset, i; - - state = buttonsettings[btn_videofs]; - - lastx = validresolutions[slidersettings[sldr_videores]].xdim; - lasty = validresolutions[slidersettings[sldr_videores]].ydim; - lastbpp = validbpps[slidersettings[sldr_videobpp]]; - UpdateValidModes(lastbpp, buttonsettings[btn_videofs]); - - // check if the last bpp is still a valid choice - for (i=0; ibutton]; - break; - } - } - - if (!draw) - return; - - - - state = buttonsettings[item->button]; - - // Draw the button - if (item->text) - { - if (state) - { - // set - rotatesprite(button_x << 16, y << 16, MZ, 0, pic_radiobuttn2, shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - } - else - { - // not set - rotatesprite(button_x << 16, y << 16, MZ, 0, pic_radiobuttn1, shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - } - - MenuTextShade = shade; - MNU_DrawString(x, y, item->text, MenuTextShade, 16); - - if (extra_text) - MNU_DrawString(OPT_XSIDE + tilesiz[pic_radiobuttn1].x + 6, y, extra_text, MenuTextShade, 16); - MenuTextShade = MENU_SHADE_DEFAULT; - } - else - { - if (state) - rotatesprite(x << 16, y << 16, MZ, 0, pic_radiobuttn2, 2, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - else - rotatesprite(x << 16, y << 16, MZ, 0, pic_radiobuttn1, 2, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - - x += tilesiz[pic_radiobuttn1].x + 4; - - // Draw the menu item text - rotatesprite(x << 16, y << 16, MZ, 0, item->pic, 2, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - } - -} - -//char *gametype[] = {"War [Respawn]","Cooperative","War [No Respawn]"}; -const char *gametype[] = {"WangBang (spawn)","WangBang (no spawn)","Cooperative"}; -const char *playercolors[] = {"Brown","Gray","Purple","Red","Yellow","Olive","Green","Blue"}; -const char *monsterskills[] = {"No Monsters","Easy","Normal","Hard","Insane!"}; - void MNU_DoSlider(short dir, MenuItem_p item, SWBOOL draw) { - short offset, i, barwidth; - int x, y, knobx; - short shade = MENU_SHADE_DEFAULT; - const char *extra_text=NULL; - char tmp_text[256]; - - memset(tmp_text,0,256); - - if (TEST(item->flags, mf_disabled)) - { - shade = MENU_SHADE_INACTIVE; - dir = 0; - } - - switch (item->slider) - { - case sldr_mouse: - barwidth = SLDR_MOUSESENSEMAX; - offset = slidersettings[sldr_mouse] += dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(SLDR_MOUSESENSEMAX-1)); - - slidersettings[sldr_mouse] = offset; - - in_mousesensitivity = float(offset * (MOUSE_SENS_MAX_VALUE/SLDR_MOUSESENSEMAX));// [JM] Will need to verify this. !CHECKME! - break; - - case sldr_sndfxvolume: - barwidth = SLDR_SNDFXVOLMAX; - offset = slidersettings[sldr_sndfxvolume] += dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(SLDR_SNDFXVOLMAX-1)); - - slidersettings[sldr_sndfxvolume] = offset; - snd_fxvolume = FX_MIN + (offset * VOL_MUL); - FX_SetVolume(snd_fxvolume); - break; - case sldr_scrsize: { short bnum; @@ -3229,20 +698,6 @@ MNU_DoSlider(short dir, MenuItem_p item, SWBOOL draw) break; } - - case sldr_brightness: - barwidth = SLDR_BRIGHTNESSMAX; - offset = slidersettings[sldr_brightness] += dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(SLDR_BRIGHTNESSMAX - 1)); - slidersettings[sldr_brightness] = offset; - - break; - case sldr_bordertile: barwidth = SLDR_BORDERTILEMAX; offset = slidersettings[sldr_bordertile] += dir; @@ -3262,106 +717,6 @@ MNU_DoSlider(short dir, MenuItem_p item, SWBOOL draw) } break; - case sldr_gametype: - barwidth = SLDR_GAMETYPEMAX; - offset = slidersettings[sldr_gametype] += dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(SLDR_GAMETYPEMAX - 1)); - slidersettings[sldr_gametype] = offset; - - extra_text = gametype[offset]; - MNU_DrawString(OPT_XSIDE, item->y, extra_text, 1, 16); - gs.NetGameType = offset; - // friendly fire menu - MNU_ItemPreProcess(currentmenu); - break; - - case sldr_netlevel: - barwidth = SLDR_NETLEVELMAX; - offset = slidersettings[sldr_netlevel] += dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(SLDR_NETLEVELMAX - 1)); - slidersettings[sldr_netlevel] = offset; - - // Show the currently selected level on next line - //extra_text = MNU_LevelName[offset]; - //MNU_DrawString(OPT_XS, item->y+10, extra_text, 1, 16); - sprintf(tmp_text, "L%02d: %s", offset+1, LevelInfo[offset+1].Description); - MNU_DrawString(OPT_XS, item->y+10, tmp_text, 1, 16); - gs.NetLevel = offset; - break; - - case sldr_monsters: - barwidth = SLDR_MONSTERSMAX; - offset = slidersettings[sldr_monsters] += dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(SLDR_MONSTERSMAX - 1)); - slidersettings[sldr_monsters] = offset; - - extra_text = monsterskills[offset]; - MNU_DrawString(OPT_XSIDE+54, item->y, extra_text, 1, 16); - gs.NetMonsters = offset; - break; - - case sldr_killlimit: - barwidth = SLDR_KILLLIMITMAX; - offset = slidersettings[sldr_killlimit] += dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(SLDR_KILLLIMITMAX - 1)); - slidersettings[sldr_killlimit] = offset; - - if (offset == 0) - { - strcpy(tmp_text,"Infinite\n"); - } - else - { - sprintf(tmp_text,"%d",offset*10); - //itoa(offset*10,tmp_text,10); - } - MNU_DrawString(OPT_XSIDE+101, item->y, tmp_text, 1, 16); - gs.NetKillLimit = offset; - break; - - case sldr_timelimit: - barwidth = SLDR_TIMELIMITMAX; - offset = slidersettings[sldr_timelimit] += dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(SLDR_TIMELIMITMAX - 1)); - slidersettings[sldr_timelimit] = offset; - - if (offset == 0) - { - strcpy(tmp_text,"Infinite\n"); - } - else - { - sprintf(tmp_text,"%d Minutes\n",TimeLimitTable[offset]); - } - - MNU_DrawString(OPT_XSIDE+86, item->y, tmp_text, 1, 16); - gs.NetTimeLimit = offset; - break; case sldr_playercolor: barwidth = SLDR_PLAYERCOLORMAX; @@ -3378,1091 +733,8 @@ MNU_DoSlider(short dir, MenuItem_p item, SWBOOL draw) MNU_DrawString(OPT_XSIDE+78, item->y, extra_text, 1, PALETTE_PLAYER0+offset); gs.NetColor = offset; break; - - case sldr_videores: - { - offset = max(0,min(slidersettings[sldr_videores] + dir, numvalidresolutions-1)); - barwidth = numvalidresolutions; - - if (TEST(item->flags, mf_disabled)) - break; - - slidersettings[sldr_videores] = offset; - - sprintf(tmp_text, "%dx%d", validresolutions[offset].xdim, validresolutions[offset].ydim); - MNU_DrawString(OPT_XSIDE, item->y+OPT_YINC, tmp_text, 1, 16); - } break; - - case sldr_videobpp: - { - offset = max(0,min(slidersettings[sldr_videobpp] + dir, numvalidbpps-1)); - barwidth = numvalidbpps; - - if (TEST(item->flags, mf_disabled)) - break; - - if (slidersettings[sldr_videobpp] != offset) - { - int lastx, lasty, newoffset, i; - - slidersettings[sldr_videobpp] = offset; - - // find the nearest resolution to the one last selected - lastx = validresolutions[slidersettings[sldr_videores]].xdim; - lasty = validresolutions[slidersettings[sldr_videores]].ydim; - UpdateValidModes(validbpps[offset], buttonsettings[btn_videofs]); - newoffset = 0; - for (i=0; iy, tmp_text, 1, 16); - } break; - - case sldr_mousescalex: - case sldr_mousescaley: - barwidth = 8+1+8; - offset = slidersettings[item->slider] + dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(barwidth-1)); - - if (slidersettings[item->slider] != offset) - { - slidersettings[item->slider] = offset; - if (item->slider == sldr_mousescalex) in_mousescalex = offset<<13; - else in_mousescaley = offset<13; - } - - sprintf(tmp_text, "%.2f", (float)(slidersettings[item->slider]<<13) / 65535.f); - MNU_DrawSmallString(OPT_XSIDE+tilesiz[pic_slidelend].x+tilesiz[pic_sliderend].x+(MAX_SLDR_WIDTH+1)*tilesiz[pic_slidebar].x, item->y+4, tmp_text, 1, 16); - break; - - case sldr_joyaxisscale: - barwidth = 8+1+8; - offset = slidersettings[item->slider] + dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(barwidth-1)); - - if (slidersettings[item->slider] != offset) - { - slidersettings[item->slider] = offset; - //JoystickAnalogScale[JoystickAxisPage] = offset<<13; - CONTROL_SetAnalogAxisScale(JoystickAxisPage, offset<<13, controldevice_joystick); - } - - sprintf(tmp_text, "%.2f", (float)(slidersettings[item->slider]<<13) / 65535.f); - MNU_DrawSmallString(OPT_XSIDE+tilesiz[pic_slidelend].x+tilesiz[pic_sliderend].x+(MAX_SLDR_WIDTH+1)*tilesiz[pic_slidebar].x, item->y+4, tmp_text, 1, 16); - break; - - case sldr_joyaxisanalog: - { -#if 0 - const char *p; - - barwidth = MNU_ControlAxisOffset(analog_maxt - - - ype); - offset = slidersettings[item->slider] + dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(barwidth-1)); - - if (slidersettings[item->slider] != offset) - { - slidersettings[item->slider] = offset; - //JoystickAnalogAxes[JoystickAxisPage] = MNU_ControlAxisNum(offset); - CONTROL_MapAnalogAxis(JoystickAxisPage, MNU_ControlAxisNum(offset), controldevice_joystick); - } - - p = CONFIG_AnalogNumToName(MNU_ControlAxisNum(offset)); - while (*p != 0 && *p != '_') p++; - if (*p == '_') p++; - MNU_DrawSmallString(OPT_XSIDE+tilesiz[pic_slidelend].x+tilesiz[pic_sliderend].x+(barwidth+1)*tilesiz[pic_slidebar].x, item->y+4, p, 1, 16); -#endif - } - break; - - case sldr_joyaxisdead: - case sldr_joyaxissatur: - barwidth = (32768>>10)+1; - offset = slidersettings[item->slider] + dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(barwidth-1)); - - if (slidersettings[item->slider] != offset) - { - slidersettings[item->slider] = offset; - if (item->slider == sldr_joyaxisdead) - { - //JoystickAnalogDead[JoystickAxisPage] = min((offset<<10), 32767); - //CONTROL_SetJoyAxisDead(JoystickAxisPage, JoystickAnalogDead[JoystickAxisPage]); - } - else - { - //JoystickAnalogSaturate[JoystickAxisPage] = min((offset<<10), 32767); - //CONTROL_SetJoyAxisSaturate(JoystickAxisPage, JoystickAnalogSaturate[JoystickAxisPage]); - } - - //joySetDeadZone(JoystickAxisPage, JoystickAnalogDead[JoystickAxisPage], JoystickAnalogSaturate[JoystickAxisPage]); // [JM] !CHECKME! - } - - sprintf(tmp_text, "%.2f%%", (float)(slidersettings[item->slider]<<10) / 32767.f); - MNU_DrawSmallString(OPT_XSIDE+tilesiz[pic_slidelend].x+tilesiz[pic_sliderend].x+(MAX_SLDR_WIDTH+1)*tilesiz[pic_slidebar].x, item->y+4, tmp_text, 1, 16); - break; - - default: - return; - } - - if (!draw) - return; - - // Now draw it - item++; - x = item->x; - y = item->y; - - // Draw the left end cap of the bar - rotatesprite(x << 16, y << 16, MZ, 0, pic_slidelend, shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - - x += tilesiz[pic_slidelend].x; - knobx = x; - - // Draw the in between sections - for (i = 0; i < min(barwidth, short(MAX_SLDR_WIDTH)); i++) - { - rotatesprite(x << 16, y << 16, MZ, 0, pic_slidebar, shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - x += tilesiz[pic_slidebar].x; - } - - // Draw the right end cap - rotatesprite(x << 16, y << 16, MZ, 0, pic_sliderend, shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - - // Draw the knob, compressing the X coordinate if the bar is too wide - if (barwidth > MAX_SLDR_WIDTH) - { - knobx += offset * (MAX_SLDR_WIDTH*tilesiz[pic_slidebar].x-tilesiz[pic_sliderknob].x) / (barwidth-1); - } - else - { - knobx += tilesiz[pic_slidebar].x * offset; - } - rotatesprite(knobx << 16, (y + 2) << 16, MZ, 0, pic_sliderknob, shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); -} - -//////////////////////////////////////////////// -// Start up menu array -//////////////////////////////////////////////// -static void -MNU_SetupMenu(void) -{ - MenuGroup *rootmenu; - - static MenuGroup *rootmenulist[] = - { - &maingroup, - &SaveGameGroup, - &LoadGameGroup, - &soundgroup, - &optiongroup, - &quickloadgroup, - &quitgroup, - &ordergroup, - &episodegroup, - }; - - rootmenu = rootmenulist[ControlPanelType]; - ASSERT(ControlPanelType < ct_max); - - menuarrayptr = 0; - menuarray[0] = currentmenu = rootmenu; - if (ControlPanelType == ct_mainmenu) - - //order_input_buffered.button0 = order_input_buffered.button1 = FALSE; - //order_input_buffered.dir = dir_None; - ResetKeys(); - - // custom cust_callback starts out as null - cust_callback = NULL; - - // for QuitCustom and QuickLoadCustom - if (currentmenu->items == NULL) - { - if (currentmenu->draw_custom) - currentmenu->draw_custom(uc_setup, NULL); - } - - if (ControlPanelType == ct_mainmenu) - currentmenu->cursor = 0; - - // disable any items necessary - MNU_ItemPreProcess(currentmenu); -} - -//////////////////////////////////////////////// -// Draw an item -//////////////////////////////////////////////// -static void MNU_ClearFlags(MenuGroup * node) -{ - MenuItem *i; - - if (!node->items) - return; - - for (i = node->items; i->type != mt_none; i++) - { - i->flags &= ~MenuSelectFlags; - if (i->child) - MNU_ClearFlags((MenuGroup *) i->child); - } -} - -//////////////////////////////////////////////// -// Pop a group off the menu stack -//////////////////////////////////////////////// -static void MNU_PopGroup(void) -{ - if (!menuarrayptr) - return; - - currentmenu = menuarray[--menuarrayptr]; - - SetFragBar(Player + myconnectindex); - //PanelRefresh(Player + myconnectindex); -} - -//////////////////////////////////////////////// -// Push a group on to the menu stack -//////////////////////////////////////////////// -static void MNU_PushGroup(MenuGroup * node) -{ - if (menuarrayptr == MaxLayers - 1) - return; - - currentmenu = menuarray[++menuarrayptr] = node; - - SetFragBar(Player + myconnectindex); -} - -//////////////////////////////////////////////// -// Setup a new menu subgroup -//////////////////////////////////////////////// -static void MNU_SetupGroup(void) -{ - MNU_SelectItem(currentmenu, currentmenu->cursor, FALSE); - MNU_DrawMenu(); -} - -static VOID MNU_ItemPreProcess(MenuGroup * group) -{ - MenuItem *item; - - if (!group->items) - return; - - // process all items when going down a level - // to see if anything is disabled - for (item = group->items; item->type != mt_none; item++) - { - if (item->preprocess) - item->preprocess(item); - } -} - -void MNU_ItemPostProcess(MenuGroup *group) -{ - MenuItem *item; - int zero = 0; - - if (!group->items) - return; - - item = ¤tmenu->items[currentmenu->cursor]; - - if (item->postprocess) - { - item->postprocess(item); - } -} - -//////////////////////////////////////////////// -// Go to next menu subgroup -//////////////////////////////////////////////// -static void MNU_DownLevel(MenuGroup * group) -{ - - if (!group) - { - TerminateGame(); - printf("MNU_DownLevel() - NULL card\n"); - exit(0); - } - - MNU_PushGroup(group); - - if (group->items == NULL) - { - if (group->draw_custom && group->draw_custom(uc_setup, NULL)) - MNU_PopGroup(); - } - - MNU_ItemPreProcess(currentmenu); - - MNU_SetupGroup(); - - SetRedrawScreen(&Player[myconnectindex]); -} - -//////////////////////////////////////////////// -// Go to previous menu subgroup -//////////////////////////////////////////////// -static void MNU_UpLevel(void) -{ - int zero = 0; - static int handle1; - // if run out of menus then EXIT - if (!menuarrayptr) - { - if (!FX_SoundValidAndActive(handle1)) - handle1 = PlaySound(DIGI_STARCLINK,&zero,&zero,&zero,v3df_dontpan); - ExitMenus(); - return; - } - - if (currentmenu->items) - currentmenu->items[currentmenu->cursor].flags &= ~mf_selected; - MNU_PopGroup(); - MNU_SetupGroup(); - - SetRedrawScreen(&Player[myconnectindex]); -} - -//////////////////////////////////////////////// -// Do a menu item action -//////////////////////////////////////////////// - -static void MNU_DoItem(void) -{ - MenuItem *item; - - item = ¤tmenu->items[currentmenu->cursor]; - if (!item) return; - - if (TEST(item->flags, mf_disabled)) - { - // Try to process again - if (item->preprocess) - item->preprocess(item); - - // Check once more - if (TEST(item->flags, mf_disabled)) - return; - } - - switch (item->type) - { - case mt_option: - if (item->custom != NULL) - item->custom(); - break; - case mt_button: - MNU_PushItem(item, FALSE); - if (item->custom != NULL) - item->custom(); - break; - case mt_layer: - if (item->custom != NULL) - item->custom(); - MNU_DownLevel(item->child); - break; - default: break; - } -} - -//////////////////////////////////////////////// -// Draw an item icon or cursor -//////////////////////////////////////////////// -static void MNU_DrawItemIcon(MenuItem * item) -{ - //void BorderRefreshClip(PLAYERp pp, short x, short y, short x2, short y2); - int x = item->x, y = item->y; - int scale = MZ; - short w,h; - - if (item->text) - { - scale /= 2; - x -= mulscale17(tilesiz[pic_yinyang].x,scale) + 2; - y += 4; - } - else - { - scale -= (1<<13); - x -= ((tilesiz[pic_yinyang].x) / 2) - 3; - y += 8; - } - - rotatesprite(x << 16, y << 16, - scale, 0, pic_yinyang, item->shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - - SetRedrawScreen(&Player[myconnectindex]); - //BorderRefreshClip(&Player[myconnectindex], x - 24, y - 24, x + 24, y + 24); -} - -//////////////////////////////////////////////// -// Draw an item -//////////////////////////////////////////////// -static void MNU_DrawItem(MenuItem * item) -{ - char *ptr; - short px, py; - - MNU_ItemPostProcess(currentmenu); // Put this in so things can be drawn on item select - - if (!item->pic) - return; - - MNU_DrawItemIcon(item); - - // if text string skip this part - if (item->text) - return; - - if (TEST(item->flags, mf_selected) && !TEST(item->flags, mf_disabled)) - { - // Highlighted - if (item->type != mt_button) - rotatesprite(item->x << 16, item->y << 16, MZ, 0, item->pic, - -30 + STD_RANDOM_RANGE(50), PALETTE_MENU_HIGHLIGHT, MenuDrawFlags, - 0, 0, xdim - 1, ydim - 1); - else - rotatesprite((item->x + tilesiz[pic_radiobuttn1].x + 4) << 16, item->y << 16, - MZ, 0, item->pic, item->shade, PALETTE_MENU_HIGHLIGHT, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - } - else - { - // Un highlighted - if (item->type != mt_button) - rotatesprite(item->x << 16, item->y << 16, MZ, 0, item->pic, - item->shade, 0, MenuDrawFlags, 0, 319, 199, 0); - else - rotatesprite((item->x + tilesiz[pic_radiobuttn1].x + 4) << 16, item->y << 16, - MZ, 0, item->pic, item->shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - } -} - -//////////////////////////////////////////////// -// Draw the menu contents -//////////////////////////////////////////////// -static void MNU_DrawMenuContents(void) -{ - MenuItem *item; - short w,h; - - ASSERT(currentmenu != NULL); - - if (currentmenu->text) - { - // Draw the backdrop bar - rotatesprite(10 << 16, (currentmenu->y-3) << 16, MZ, 0, 2427, - currentmenu->shade, 0, MenuDrawFlags|ROTATE_SPRITE_CORNER, 0, 0, xdim - 1, ydim - 1); - MNU_MeasureStringLarge(currentmenu->text, &w, &h); - MNU_DrawString(TEXT_XCENTER(w), currentmenu->y, currentmenu->text, 1, 16); - } - else if (currentmenu->titlepic) - { - rotatesprite(currentmenu->x << 16, currentmenu->y << 16, MZ, 0, currentmenu->titlepic, - currentmenu->shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - } - - if (!currentmenu->items) - return; - - for (item = currentmenu->items; item->type != mt_none; item++) - { - if (item->pic) - { - if (item->type == mt_button) - { - // all drawing done here also - MNU_DoButton(item, TRUE); - } - else - { - if (item->text) - { - if (TEST(item->flags, mf_disabled)) - MenuTextShade = MENU_SHADE_INACTIVE; - MNU_DrawString(item->x, item->y, item->text, MenuTextShade, 16); - MenuTextShade = MENU_SHADE_DEFAULT; - } - else - { - rotatesprite(item->x << 16, item->y << 16, MZ, 0, item->pic, - item->shade, 0, MenuDrawFlags, 0, 0, xdim - 1, ydim - 1); - } - } - } - - // Is there a slider attached to this item? Draw it. - if (item->type == mt_slider) - MNU_DoSlider(0, item, TRUE); - } - - MNU_SelectItem(currentmenu, currentmenu->cursor, TRUE); - - if (currentmenu->draw_custom) - currentmenu->draw_custom(uc_touchup, NULL); -} - -//////////////////////////////////////////////// -// Draw the menu -//////////////////////////////////////////////// -void MNU_DrawMenu(void) -{ - if (cust_callback != NULL) - { - cust_callback(cust_callback_call, cust_callback_item); - return; - } - - if (currentmenu->items || currentmenu->titlepic) - { - MNU_DrawMenuContents(); - } -} - -//////////////////////////////////////////////// -// Select a menu item -//////////////////////////////////////////////// -void MNU_SelectItem(MenuGroup * group, short index, SWBOOL draw) -{ - MenuItem *item; - - if (index != group->cursor) - { - item = &group->items[group->cursor]; - item->flags &= ~mf_selected; - if (draw) - MNU_DrawItem(item); - } - - group->cursor = index; - item = &group->items[group->cursor]; - - item->flags |= mf_selected; - if (draw) - MNU_DrawItem(item); -} - -//////////////////////////////////////////////// -// Toggle a menu radio button on/off -//////////////////////////////////////////////// -static void MNU_PushItem(MenuItem * item, SWBOOL draw) -{ - if (item->type != mt_button) - return; - - buttonsettings[item->button] ^= 1; - -// if (draw) - MNU_DoButton(item, draw); -} - -//////////////////////////////////////////////// -// Go to next item on menu -//////////////////////////////////////////////// -static void MNU_NextItem(void) -{ - MenuTag type; - MenuFlags flag; - - type = currentmenu->items[currentmenu->cursor + 1].type; - flag = currentmenu->items[currentmenu->cursor + 1].flags; - - if (type == mt_none) - MNU_SelectItem(currentmenu, 0, FALSE); - else - MNU_SelectItem(currentmenu, currentmenu->cursor + 1, FALSE); - - type = currentmenu->items[currentmenu->cursor].type; - flag = currentmenu->items[currentmenu->cursor].flags; - - if (type == mt_inert || flag == mf_disabled) - MNU_NextItem(); -} - -//////////////////////////////////////////////// -// Go to previous item on menu -//////////////////////////////////////////////// -static void MNU_PrevItem(void) -{ - MenuTag type; - MenuFlags flag; - - if (!currentmenu->cursor) - while (currentmenu->items[++currentmenu->cursor].type != mt_none) ; - - MNU_SelectItem(currentmenu, currentmenu->cursor - 1, FALSE); - - type = currentmenu->items[currentmenu->cursor].type; - flag = currentmenu->items[currentmenu->cursor].flags; - if (type == mt_inert || flag == mf_disabled) - MNU_PrevItem(); -} - -//////////////////////////////////////////////// -// Find hotkey press on current menu, if any. -//////////////////////////////////////////////// -static SWBOOL MNU_DoHotkey(void) -{ - MenuItem_p item; - short index; - - if (!currentmenu->items) return FALSE; - - index = 0; - for (item = currentmenu->items; item->type != mt_none; item++) - { - if (inputState.GetKeyStatus(item->hotkey) && item->hotkey != 0) - { - MNU_SelectItem(currentmenu, index, FALSE); - return TRUE; - } - index++; - } - - return FALSE; -} - -//////////////////////////////////////////////// -// Setup Menus -//////////////////////////////////////////////// -void SetupMenu(void) -{ - if (!UsingMenus && !ConPanel) // Doing this check for multiplay - // menus - { - MNU_SetupMenu(); - - // Clear the previous ESC key press - inputState.ClearKeyStatus(sc_Escape); - UsingMenus = TRUE; - } -} - -//////////////////////////////////////////////// -// Setup the main menu -// This function will not loop if in modem -// or network game, otherwise it stops the -// game play until user finished in menus. -//////////////////////////////////////////////// -#define MNU_SENSITIVITY 10 // The menu's mouse sensitivity, should be real low - -void MNU_DoMenu( CTLType type, PLAYERp pp ) -{ - SWBOOL resetitem; - unsigned char key; - int zero = 0; - static int handle2; - static int limitmove=0; - static SWBOOL select_held=FALSE; - - resetitem = TRUE; - - if (cust_callback != NULL) - { - cust_callback(cust_callback_call, cust_callback_item); - return; - } - - //ControlPanelType = type; - SetupMenu(); - - // should not get input if you are editing a save game slot - if (totalclock < limitmove) limitmove = (int32_t) totalclock; - - if (I_MenuUp()) - { - I_MenuUpClear(); - MNU_PrevItem(); - resetitem = TRUE; - } - else if (I_MenuDown()) - { - I_MenuDownClear(); - MNU_NextItem(); - resetitem = TRUE; - } - else if (I_GeneralTrigger()) - { - static int handle5=0; - I_GeneralTriggerClear(); - if (!FX_SoundValidAndActive(handle5)) - handle5 = PlaySound(DIGI_SWORDSWOOSH,&zero,&zero,&zero,v3df_dontpan); - inputState.ClearKeysDown(); - MNU_DoItem(); - resetitem = TRUE; - } - else if (I_MenuLeft() - && currentmenu->items[currentmenu->cursor].type == mt_slider) - { - I_MenuLeftClear(); - MNU_DoSlider(-1, ¤tmenu->items[currentmenu->cursor], FALSE); - resetitem = TRUE; - } - else if (I_MenuRight() - && currentmenu->items[currentmenu->cursor].type == mt_slider) - { - I_MenuRightClear(); - MNU_DoSlider(1, ¤tmenu->items[currentmenu->cursor], FALSE); - resetitem = TRUE; - } - else if (I_ReturnTrigger()) - { - I_ReturnTriggerClear(); - static int handle3; - if (!FX_SoundValidAndActive(handle3)) - handle3 = PlaySound(DIGI_SWORDSWOOSH,&zero,&zero,&zero,v3df_dontpan); - MNU_UpLevel(); - resetitem = TRUE; - } - else if (MNU_DoHotkey()) - { - static int handle4; - if (!FX_SoundValidAndActive(handle4)) - handle4 = PlaySound(DIGI_STAR,&zero,&zero,&zero,v3df_dontpan); - resetitem = TRUE; - } - else - resetitem = FALSE; - - // !FRANK! I added this because the old custom was only called for drawing - // Needed one for drawing and moving. - if (currentmenu->move_custom) - currentmenu->move_custom(uc_setup, NULL); - - if (resetitem) - { - inputState.ClearKeysDown(); - ResetKeys(); - } -} - -//////////////////////////////////////////////// -// Checks to see if we should be in menus -//////////////////////////////////////////////// -void MNU_CheckForMenus(void) -{ - extern SWBOOL GamePaused; - - if (UsingMenus) - { - //if (MoveSkip2 == 0) - MNU_DoMenu(ct_mainmenu, Player + myconnectindex); - } - else - { - if ((inputState.GetKeyStatus(KEYSC_ESC)) && dimensionmode == 3 && !ConPanel) - { - inputState.ClearKeyStatus(sc_Escape); - inputState.ClearKeysDown(); - // setup sliders/buttons - MNU_InitMenus(); - MNU_DoMenu(ct_mainmenu, Player + myconnectindex); - pMenuClearTextLine(Player + myconnectindex); - PauseGame(); - } - } -} - -void MNU_CheckForMenusAnyKey(void) -{ - if (UsingMenus) - { - //if (MoveSkip2 == 0) - MNU_DoMenu(ct_mainmenu, Player + myconnectindex); - } - else - { - if (KeyPressed()) - { - ResetKeys(); - inputState.ClearKeysDown(); - MNU_InitMenus(); - MNU_DoMenu(ct_mainmenu, Player + myconnectindex); - pMenuClearTextLine(Player + myconnectindex); - } - } -} - -static int MNU_ControlAxisOffset(int num) -{ - switch (num) - { - case analog_turning: return 0; - case analog_strafing: return 1; - case analog_moving: return 2; - case analog_lookingupanddown: return 3; - case analog_maxtype: return 4; - default: return 0; - } -} - -static int MNU_ControlAxisNum(int offset) -{ - switch (offset) - { - case 0: return analog_turning; - case 1: return analog_strafing; - case 2: return analog_moving; - case 3: return analog_lookingupanddown; - default: return analog_turning; - } -} - - - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Miscellaneous Routines -/////////////////////////////////////////////////////////////////////////////////////////////////// - - -#define PALETTE_MASK 0x3c6 -#define PALETTE_READ 0x3c7 -#define PALETTE_WRITE 0x3c8 -#define PALETTE_DATA 0x3c9 - - -// V E R T I C A L R E T R A C E V A R I A B L E S ////////////////////////////////////////// - -#define VGA_INPUT_STATUS_1 0x3DA // VGA status register 1, bit 3 is the vid_vsync -// 1 = retrace in progress -// 0 = no retrace -#define VGA_VSYNC_MASK 0x08 // Masks off unwanted bits of status register. - - -// These routines are not used and should not be used. Would interfere with VESA palette -// cards. -#if 0 -///////////////////////////////////////////////// -// WaitForVsync -// Waits for a vertical retrace to occur. If one is in progress, it waits for the next one. -///////////////////////////////////////////////// -void WaitForVsync(void) -{ - while (inp(VGA_INPUT_STATUS_1) & VGA_VSYNC_MASK) ; - // Retrace in progress, wait. - - // Wait for vid_vsync, and exit. - while (!inp(VGA_INPUT_STATUS_1) & VGA_VSYNC_MASK) ; -} - -void Get_Palette(unsigned char *pal) -{ - int i; - - outp(PALETTE_READ, 0); - for (i = 0; i < 768; i++) - pal[i] = inp(PALETTE_DATA); -} - -void Set_Palette(unsigned char *buff) -{ - int i; - - outp(PALETTE_WRITE, 0); // Resets color ram pointer to 1st - // color - for (i = 0; i < 768; i++) - outp(PALETTE_DATA, buff[i]); } #endif - -/* -================================================================================================= -= -= FadeOut - Fades the palette to color at assigned click rate -= -================================================================================================= -*/ -// Heres some temp timer junk for this routine. Replace it with game timer stuff later. -//unsigned int *clock = (unsigned int *)0x046C; - -void Fade_Timer(int clicks) -{ -// unsigned int now; - int now; - - now = (int32_t) totalclock; - - while (abs((int32_t) totalclock - now) < clicks) handleevents(); -} - -void FadeIn(unsigned char startcolor, unsigned int clicks) -{ - int i, palreg, usereg, tmpreg1 = 0, tmpreg2 = 0; - RGB_color color; - unsigned char temp_pal[768], *palette; - - if (videoGetRenderMode() >= REND_POLYMOST) return; - - palette = &palette_data[0][0]; - - color.red = palette_data[startcolor][0]; - color.green = palette_data[startcolor][1]; - color.blue = palette_data[startcolor][2]; - - usereg = 0; - for (i = 0; i < 768; i++) - { - if (usereg == 0) - temp_pal[i] = color.red; - else if (usereg == 1) - temp_pal[i] = color.green; - else - temp_pal[i] = color.blue; - - if (++usereg > 2) - usereg = 0; - } - - for (i = 0; i < 32; i++) - { - for (palreg = 0; palreg < 768; palreg++) - { - tmpreg1 = (int)(temp_pal[palreg]) + 2; - tmpreg2 = (int)(temp_pal[palreg]) - 2; - if (tmpreg1 > 255) - tmpreg1 = 255; - if (tmpreg2 < 0) - tmpreg2 = 0; - - if (temp_pal[palreg] < palette[palreg]) - { - if ((temp_pal[palreg] = tmpreg1) > palette[palreg]) - temp_pal[palreg] = palette[palreg]; - } - else if (temp_pal[palreg] > palette[palreg]) - if ((temp_pal[palreg] = tmpreg2) < palette[palreg]) - temp_pal[palreg] = palette[palreg]; - - } - - set_pal(&temp_pal[0]); - - // Delay clicks - Fade_Timer(clicks); - } -} - -void FadeOut(unsigned char targetcolor, unsigned int clicks) -{ - int i, palreg, usereg = 0, tmpreg1 = 0, tmpreg2 = 0; - RGB_color color; - unsigned char temp_pal[768]; - - if (videoGetRenderMode() >= REND_POLYMOST) return; - - color.red = palette_data[targetcolor][0]; - color.green = palette_data[targetcolor][1]; - color.blue = palette_data[targetcolor][2]; - - memcpy(&temp_pal[0], &palette_data[0][0], 768); - - for (i = 0; i < 32; i++) - { - for (palreg = 0; palreg < 768; palreg++) - { - tmpreg1 = (int)(temp_pal[palreg]) + 2; - tmpreg2 = (int)(temp_pal[palreg]) - 2; - if (tmpreg1 > 255) - tmpreg1 = 255; - if (tmpreg2 < 0) - tmpreg2 = 0; - - if (usereg == 0) - { - if (temp_pal[palreg] < color.red) - { - if ((temp_pal[palreg] = tmpreg1) > color.red) - temp_pal[palreg] = color.red; - } - else if (temp_pal[palreg] > color.red) - if ((temp_pal[palreg] = tmpreg2) < color.red) - temp_pal[palreg] = color.red; - } - else if (usereg == 1) - { - if (temp_pal[palreg] < color.green) - { - if ((temp_pal[palreg] = tmpreg1) > color.green) - temp_pal[palreg] = color.green; - } - else if (temp_pal[palreg] > color.green) - if ((temp_pal[palreg] = tmpreg2) < color.green) - temp_pal[palreg] = color.green; - } - else if (usereg == 2) - { - if (temp_pal[palreg] < color.blue) - { - if ((temp_pal[palreg] = tmpreg1) > color.blue) - temp_pal[palreg] = color.blue; - } - else if (temp_pal[palreg] > color.blue) - if ((temp_pal[palreg] = tmpreg2) < color.blue) - temp_pal[palreg] = color.blue; - } - - if (++usereg > 2) - usereg = 0; - } - - - set_pal(&temp_pal[0]); - - // Delay clicks - Fade_Timer(clicks); - } -} - -void ResetPalette(PLAYERp pp) -{ - videoFadePalette(0,0,0,0); - memcpy(pp->temp_pal, palette_data, sizeof(palette_data)); - //DoPlayerDivePalette(pp); // Check Dive again - //DoPlayerNightVisionPalette(pp); // Check Night Vision again - pp->FadeAmt = 0; - pp->StartColor = 0; - pp->FadeTics = 0; -} - -#endif -// vim:ts=4:sw=4:enc=utf-8: - - END_SW_NS diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index 16e75b1e3..378896da2 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -45,6 +45,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "weapon.h" #include "fx_man.h" #include "menu/menu.h" +#include "swcvar.h" BEGIN_SW_NS @@ -1822,7 +1823,7 @@ InitWeaponStar(PLAYERp pp) PlaySound(DIGI_PULL, &pp->posx, &pp->posy, &pp->posz, v3df_follow|v3df_dontpan); if (STD_RANDOM_RANGE(1000) > 900 && pp == Player+myconnectindex) { - if (!gs.Darts) + if (!sw_darts) PlayerSound(DIGI_ILIKESHURIKEN,&pp->posx,&pp->posy,&pp->posz,v3df_follow|v3df_dontpan,pp); } @@ -7388,7 +7389,7 @@ pDisplaySprites(PLAYERp pp) picnum = psp->picndx; // UK panzies have to have darts instead of shurikens. - if (gs.Darts) + if (sw_darts) switch (picnum) { case STAR_REST: @@ -7452,7 +7453,7 @@ pDisplaySprites(PLAYERp pp) case STAR_REST: case 2510: - if (!gs.Darts) + if (!sw_darts) picnum = 2138; else picnum = 2518; // Bloody Dart Hand diff --git a/source/sw/src/settings.h b/source/sw/src/settings.h index 4eda4a023..299eb55c8 100644 --- a/source/sw/src/settings.h +++ b/source/sw/src/settings.h @@ -44,10 +44,6 @@ typedef struct uint8_t NetTimeLimit; // Limit time of game uint8_t NetColor; // Chosen color for player SWBOOL NetNuke; - //SWBOOL PlayCD; // Not implemented and no idea how to support it without the music assets. - char WaveformTrackName[MAXWAVEFORMTRACKLENGTH]; - SWBOOL Darts; - SWBOOL WeaponAutoSwitch; } GAME_SET, *GAME_SETp; extern const GAME_SET gs_defaults; diff --git a/source/sw/src/sprite.cpp b/source/sw/src/sprite.cpp index 499fc1f91..60c131847 100644 --- a/source/sw/src/sprite.cpp +++ b/source/sw/src/sprite.cpp @@ -47,6 +47,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "text.h" #include "slidor.h" #include "player.h" +#include "swcvar.h" BEGIN_SW_NS @@ -5959,7 +5960,7 @@ KeyMain: if (pp->WpnAmmo[WPN_STAR] >= DamageData[WPN_STAR].max_ammo) break; - sprintf(ds, gs.Darts ? "Darts" : "Shurikens"); + sprintf(ds, sw_darts ? "Darts" : "Shurikens"); PutStringInfo(Player+pnum, DamageData[WPN_STAR].weapon_name); PlayerUpdateAmmo(pp, WPN_STAR, DamageData[WPN_STAR].weapon_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup @@ -5970,7 +5971,7 @@ KeyMain: break; SET(pp->WpnFlags, BIT(WPN_STAR)); - if (!gs.WeaponAutoSwitch) + if (!cl_weaponswitch) break; if (User[pp->PlayerSprite]->WeaponNum <= WPN_STAR && User[pp->PlayerSprite]->WeaponNum != WPN_SWORD) break; @@ -5998,7 +5999,7 @@ KeyMain: break; SET(pp->WpnFlags, BIT(WPN_MINE)); - if (!gs.WeaponAutoSwitch) + if (!cl_weaponswitch) break; if (User[pp->PlayerSprite]->WeaponNum > WPN_MINE && User[pp->PlayerSprite]->WeaponNum != WPN_SWORD) break; @@ -6041,7 +6042,7 @@ KeyMain: ChoosePlayerGetSound(pp); } - if (!gs.WeaponAutoSwitch) + if (!cl_weaponswitch) break; if (User[pp->PlayerSprite]->WeaponNum > WPN_UZI && User[pp->PlayerSprite]->WeaponNum != WPN_SWORD) @@ -6084,7 +6085,7 @@ KeyMain: break; SET(pp->WpnFlags, BIT(WPN_MICRO)); - if (!gs.WeaponAutoSwitch) + if (!cl_weaponswitch) break; if (User[pp->PlayerSprite]->WeaponNum > WPN_MICRO && User[pp->PlayerSprite]->WeaponNum != WPN_SWORD) break; @@ -6155,7 +6156,7 @@ KeyMain: break; SET(pp->WpnFlags, BIT(WPN_GRENADE)); - if (!gs.WeaponAutoSwitch) + if (!cl_weaponswitch) break; if (User[pp->PlayerSprite]->WeaponNum > WPN_GRENADE && User[pp->PlayerSprite]->WeaponNum != WPN_SWORD) break; @@ -6184,7 +6185,7 @@ KeyMain: break; SET(pp->WpnFlags, BIT(WPN_ROCKET)); - if (!gs.WeaponAutoSwitch) + if (!cl_weaponswitch) break; InitWeaponRocket(pp); break; @@ -6231,7 +6232,7 @@ KeyMain: break; SET(pp->WpnFlags, BIT(WPN_RAIL)); - if (!gs.WeaponAutoSwitch) + if (!cl_weaponswitch) break; if (User[pp->PlayerSprite]->WeaponNum > WPN_RAIL && User[pp->PlayerSprite]->WeaponNum != WPN_SWORD) break; @@ -6273,7 +6274,7 @@ KeyMain: break; SET(pp->WpnFlags, BIT(WPN_SHOTGUN)); - if (!gs.WeaponAutoSwitch) + if (!cl_weaponswitch) break; if (User[pp->PlayerSprite]->WeaponNum > WPN_SHOTGUN && User[pp->PlayerSprite]->WeaponNum != WPN_SWORD) break; @@ -6342,7 +6343,7 @@ KeyMain: break; SET(pp->WpnFlags, BIT(WPN_NAPALM) | BIT(WPN_RING) | BIT(WPN_HOTHEAD)); - if (!gs.WeaponAutoSwitch) + if (!cl_weaponswitch) break; if (User[pp->PlayerSprite]->WeaponNum > WPN_HOTHEAD && User[pp->PlayerSprite]->WeaponNum != WPN_SWORD) break; @@ -6388,7 +6389,7 @@ KeyMain: break; SET(pp->WpnFlags, BIT(WPN_HEART)); - if (!gs.WeaponAutoSwitch) + if (!cl_weaponswitch) break; if (User[pp->PlayerSprite]->WeaponNum > WPN_HEART && User[pp->PlayerSprite]->WeaponNum != WPN_SWORD) diff --git a/source/sw/src/swcvar.cpp b/source/sw/src/swcvar.cpp index b61f18162..eca95381f 100644 --- a/source/sw/src/swcvar.cpp +++ b/source/sw/src/swcvar.cpp @@ -1,4 +1,4 @@ #include "swcvar.h" CVAR(Bool, sw_ninjahack, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); -CVAR(Bool, sw_usedarts, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); +CVAR(Bool, sw_darts, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); diff --git a/source/sw/src/swcvar.h b/source/sw/src/swcvar.h index 1ca530f7f..41502f714 100644 --- a/source/sw/src/swcvar.h +++ b/source/sw/src/swcvar.h @@ -2,4 +2,4 @@ EXTERN_CVAR(Bool, sw_ninjahack) -EXTERN_CVAR(Bool, sw_usedarts) +EXTERN_CVAR(Bool, sw_darts) diff --git a/source/sw/src/weapon.cpp b/source/sw/src/weapon.cpp index a22b0b22c..217c4b896 100644 --- a/source/sw/src/weapon.cpp +++ b/source/sw/src/weapon.cpp @@ -7493,7 +7493,7 @@ const char *DeathString(short SpriteNum) case 5011: return "blade"; case STAR1: - if (gs.Darts) return "dart"; + if (sw_darts) return "dart"; else return "shuriken"; case CROSSBOLT: return "crossbow bolt"; diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index c74645b9a..9b3848634 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -423,6 +423,8 @@ Brown,TXT_COLOR_BROWN,,,,Hnědá,Braun,,Bruna,Marrón,,Ruskea,Brun,Barna,Marrone Dark Blue,TXT_COLOR_DARKBLUE,,,,Tmavě modrá,Dunkelblau,,Malhelblua,Azul oscuro,,Tummansininen,Bleu sombre,Sötétkék,Blu scuro,,,Donkerblauw,,Azul escuro,,,Тёмно-Синий,Тамна Плава Light Red,TXT_COLOR_LIGHTRED,,,,Světle červená,Hellrot,,Ruĝeta,Rojo claro,,Vaaleanpunainen,Rouge clair,,Rosso chiaro,丹,옅은 적색,Licht Rood,Jasnoczerwony,Vermelho claro,,,Светло-красный,Светло црвена Yellow,TXT_COLOR_YELLOW,,,,Žlutá,Gelb,,Flava,Amarillo,,Keltainen,Jaune,Sárga,Giallo,黄,노란색,Geel,Żółty,Amarelo,,,Жёлтый,Жута +Purple,TXT_COLOR_PURPLE,,,,Fialová,Violett,,Purpura,Morado,,Purppura,Violet,Lila,Viola,紫,보라색,Paars,Fioletowy,Roxo,,,Фиолетовый,Љубичаста +Olive,TXT_COLOR_DULLGREEN,,,,Bledě zelená,Blassgrün,,Gris-Verda,Verde pálido,,Haaleanvihreä,Vert pâle,,Verde pallido,苔,암녹색,Saaie groen,Matowa Zieleń,Verde pálido,,,Мутно-зелёный,Тупа зелена Auto,OPTVAL_AUTO,,,,,,,Aŭtomata,Automático,,Automaattinen,,,Automatico,自動,자동,,Automatycznie,Automático,,,Авто,Аутоматски Name,PLYRMNU_NAME,,,,Jméno,,,Nomo,Nombre,,Nimi,Nom,Név,Nome,名前,이름,Naam,Imię,Nome,,,Имя,Надимак Team,PLYRMNU_TEAM,,,,Tým,,,Teamo,Equipo,,Joukkue,Equipe,Csapat,Squadra,チーム,팀,Team,Drużyna,Equipe,Equipa,,Команда,Тим @@ -691,6 +693,8 @@ Scripts Only,OPTVAL_SCRIPTSONLY,,,,Pouze skripty,Nur Skripte,,Skriptoj Sole,Sól Disable keyboard cheats,MISCMNU_NOCHEATS,,,,,Tastatur-Cheats deaktivieren,,Malaktivigi klavaran trumpon,Desactivar trucos por teclado,,,,,,キーボードからのチート無効,,Schakel cheats uit,,Desabilitar trapaças de teclado,,,, Quicksave rotation,MISCMNU_QUICKSAVEROTATION,,,,Rotace rychle uložených her,Schnellspeicherrotation,,Rapidkonservado-rotacio,Rotación de Salvado Rápido,,Pikatallennuskierto,Rotation Sauvegardes Rapides,,Rotazione rapide della quicksave,クイックセーブ間隔,빠른 저장 간격,Roteer quicksaves,Rotacja szybkich zapisów,Rotação de quicksave,,,Чередовать слоты для быстрых сохранений,Окретање брзих чувања Number of quicksaves in rotation,MISCMNU_QUICKSAVECOUNT,,,,Počet rychle uložených her v rotaci,Anzahl Schnellspeicherplätze,,Nombro da rapidkonservitaj ludoj en rotaciado,Número de Salvados Rápidos en Rotación,,Pikatallennusten määrä kierrossa,Nombre de sauvegardes en rotation,,Numero di quicksaves in rotazione,間隔クイックセーブの数,빠른 저장 간격의 수,Aantal roterende quicksaves,Ilość szybkich zapisów w rotacji,Número de quicksaves em rotação,,,Кол-во слотов для быстрых сохранений,Број брзих чувања у окретању +Ninja Slice Animation,MISCMNU_NINJA,,,,,,,,,,,,,,,,,,,,,, +Use Darts instead of Shurikens,MISCMNU_DARTS,,,,,,,,,,,,,,,,,,,,,, ,Miscellaneous,,,,,,,,,,,,,,,,,,,,,, "You are playing the shareware version of Duke Nukem 3D. While diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 155eb7ee4..4645e5413 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -1005,7 +1005,19 @@ OptionValue "PlayerColors" 7, "$TXT_COLOR_BROWN" 8, "$TXT_COLOR_DARKBLUE" 9, "$TXT_COLOR_LIGHTRED" - //10, "TXT_COLOR_YELLOW" + //10, "$TXT_COLOR_YELLOW" +} + +OptionValie "PlayerColorsSW" +{ + 0, "$TXT_COLOR_BROWN" + 1, "$TXT_COLOR_GRAY" + 2, "$TXT_COLOR_PURPLE" + 3, "$TXT_COLOR_RED" + 4, "$TXT_COLOR_YELLOW" + 5, "$TXT_COLOR_DULLGREEN" + 6, "$TXT_COLOR_GREEN" + 7, "$TXT_COLOR_BLUE" } OptionValue "PlayerTeam" @@ -1029,7 +1041,15 @@ OptionMenu "NewPlayerMenu" //protected { Title "$MNU_PLAYERSETUP" TextField "$PLYRMNU_NAME", playername - Option "$PLYRMNU_PLAYERCOLOR", "playercolor", "PlayerColors" + ifgame(Duke, Nam, WW2GI, Fury, Redneck, RedneckRides) + { + Option "$PLYRMNU_PLAYERCOLOR", "playercolor", "PlayerColors" + } + ifgame(ShadowWarrior) + { + // This curently does not get applied to the single player game. + Option "$PLYRMNU_PLAYERCOLOR", "playercolor", "PlayerColorsSW" + } Option "$PLYRMNU_PLAYERGENDER", "playergender", "Gender" Option "$PLYRMNU_TEAM", "playerteam", "PlayerTeam" Submenu "$PLRMNU_TAUNTS", "TauntsMenu" @@ -1084,7 +1104,14 @@ OptionMenu GameplayOptions //protected Option "$PLRMNU_AUTOAIM", "cl_autoaim", "AimMode" Option "$PLRMNU_ALWAYSRUN", "cl_autorun", "OnOff" Option "$PLRMNU_RUNMODE", "cl_runmode", "RunMode" - Option "$PLRMNU_EQUIP", "cl_weaponswitch", "WeapSwitch" + ifgame(ShadowWarrior) + { + Option "$PLRMNU_EQUIP", "cl_weaponswitch", "OnOff" // does not have the 'preferred' option. + } + else + { + Option "$PLRMNU_EQUIP", "cl_weaponswitch", "WeapSwitch" + } Option "$PLRMNU_PLOCK", "adult_lockout", "OnOff" // I won't bother password protecting this piece of window dressing // StaticText "" // Option "Record Demo", "m_recstat", "OnOff" @@ -1603,6 +1630,11 @@ OptionMenu "MiscOptions" //protected //Option "$MISCMNU_QUICKSAVEROTATION", "quicksaverotation", "OnOff" Slider "$MISCMNU_QUICKSAVECOUNT", "quicksaverotationcount", 1, 20, 1, 0 Option "$MISCMNU_INTERSCROLL", "nointerscrollabort", "OffOn" + ifgame(shadowwarrior) + { + Option "$MISCMNU_DARTS", "sw_darts", "OnOff" + Option "$MISCMNU_NINJA", "sw_ninjahack", "OnOff" + } //StaticText " " //Option "$OPTMNU_LANGUAGE", "language", "LanguageOptions" - not ready yet From f2d06655579c522741e6bb168fba254962391efb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Dec 2019 21:39:17 +0100 Subject: [PATCH 149/203] - connected the screen size CVAR and slider with Shadow Warrior's internal setting. --- source/common/gamecvars.cpp | 4 +- source/sw/src/draw.cpp | 6 +-- source/sw/src/game.cpp | 17 +++++-- source/sw/src/menus.cpp | 69 ---------------------------- wadsrc/static/demolition/menudef.txt | 4 +- 5 files changed, 20 insertions(+), 80 deletions(-) diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index 9e8a2abac..c82ce8cca 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -144,7 +144,7 @@ CVARD(Bool, demoplay_showsync, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enable/dis // Sound -CUSTOM_CVARD(Bool, snd_ambience, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enables/disables ambient sounds") // Not implemented for Blood +CUSTOM_CVARD(Bool, snd_ambience, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL, "enables/disables ambient sounds") // Not implemented for Blood { gi->SetAmbience(self); } @@ -229,7 +229,7 @@ bool G_ChangeHudLayout(int direction) return true; } } - else if (hud_size < 11) + else if (direction > 0 && hud_size < 11) { int layout = hud_size + 1; while (!gi->validate_hud(layout) && layout <= 11) layout++; diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index 4c08f258b..930165ce2 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -1071,15 +1071,13 @@ ResizeView(PLAYERp pp) if (buttonMap.ButtonDown(gamefunc_Shrink_Screen)) // && { buttonMap.ClearButton(gamefunc_Shrink_Screen); - SetBorder(pp, gs.BorderNum + 1); - SetRedrawScreen(pp); + G_ChangeHudLayout(-1); } if (buttonMap.ButtonDown(gamefunc_Enlarge_Screen)) // && { buttonMap.ClearButton(gamefunc_Enlarge_Screen); - SetBorder(pp, gs.BorderNum - 1); - SetRedrawScreen(pp); + G_ChangeHudLayout(1); } } } diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index c774969d7..a82731778 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -177,7 +177,7 @@ SWBOOL NoDemoStartup = FALSE; SWBOOL FirstTimeIntoGame; extern uint8_t RedBookSong[40]; -SWBOOL BorderAdjust = TRUE; +SWBOOL BorderAdjust = FALSE; SWBOOL LocationInfo = 0; void drawoverheadmap(int cposx, int cposy, int czoom, short cang); int DispFrameRate = FALSE; @@ -2988,6 +2988,7 @@ int32_t GameInterface::app_main() int cnt = 0; uint32_t TotalMemory; + BorderAdjust = true; SW_ExtInit(); CONFIG_ReadSetup(); @@ -4326,8 +4327,18 @@ void Saveable_Init_Dynamic() saveable_build.numdata = NUM_SAVEABLE_ITEMS(saveable_build_data); } -/*extern*/ bool GameInterface::validate_hud(int requested_size) { return requested_size; } -/*extern*/ void GameInterface::set_hud_layout(int requested_size) { /* the relevant setting is gs.BorderNum */} +/*extern*/ bool GameInterface::validate_hud(int requested_size) +{ + return requested_size != 10 && requested_size != 8; +} +/*extern*/ void GameInterface::set_hud_layout(int requested_size) +{ + if (requested_size >= 11) requested_size = 9; + else if (requested_size >= 9) requested_size = 8; + gs.BorderNum = 9 - requested_size; + SetBorder(Player + myconnectindex, gs.BorderNum); + SetRedrawScreen(Player + myconnectindex); +} /*extern*/ void GameInterface::set_hud_scale(int requested_size) { /* the relevant setting is gs.BorderNum */ } ::GameInterface* CreateInterface() diff --git a/source/sw/src/menus.cpp b/source/sw/src/menus.cpp index b4af7e750..a834eafa6 100644 --- a/source/sw/src/menus.cpp +++ b/source/sw/src/menus.cpp @@ -665,75 +665,6 @@ SWBOOL MNU_ShareWareMessage() } #if 0 -void -MNU_DoSlider(short dir, MenuItem_p item, SWBOOL draw) -{ - case sldr_scrsize: - { - short bnum; - - barwidth = SLDR_SCRSIZEMAX; - slidersettings[sldr_scrsize] = gs.BorderNum; - slidersettings[sldr_scrsize] -= dir; - offset = slidersettings[sldr_scrsize]; - - if (TEST(item->flags, mf_disabled)) - break; - - ////DSPRINTF(ds,"BorderNum %d",gs.BorderNum); - //MONO_PRINT(ds); - - offset = max(offset, short(0)); - offset = min(offset, short(SLDR_SCRSIZEMAX - 1)); - - bnum = offset; - - offset = (SLDR_SCRSIZEMAX-1) - offset; - slidersettings[sldr_scrsize] = offset; - - if (!BorderAdjust) - gs.BorderNum = bnum; - - SetBorder(&Player[myconnectindex], bnum); - - break; - } - case sldr_bordertile: - barwidth = SLDR_BORDERTILEMAX; - offset = slidersettings[sldr_bordertile] += dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(SLDR_BORDERTILEMAX - 1)); - slidersettings[sldr_bordertile] = offset; - - if (gs.BorderTile != offset) - { - gs.BorderTile = offset; - - SetRedrawScreen(&Player[myconnectindex]); - } - break; - - - case sldr_playercolor: - barwidth = SLDR_PLAYERCOLORMAX; - offset = slidersettings[sldr_playercolor] += dir; - - if (TEST(item->flags, mf_disabled)) - break; - - offset = max(offset, short(0)); - offset = min(offset, short(SLDR_PLAYERCOLORMAX - 1)); - slidersettings[sldr_playercolor] = offset; - - extra_text = playercolors[offset]; - MNU_DrawString(OPT_XSIDE+78, item->y, extra_text, 1, PALETTE_PLAYER0+offset); - gs.NetColor = offset; - break; -} #endif diff --git a/wadsrc/static/demolition/menudef.txt b/wadsrc/static/demolition/menudef.txt index 4645e5413..c2a6a68dd 100644 --- a/wadsrc/static/demolition/menudef.txt +++ b/wadsrc/static/demolition/menudef.txt @@ -1008,7 +1008,7 @@ OptionValue "PlayerColors" //10, "$TXT_COLOR_YELLOW" } -OptionValie "PlayerColorsSW" +OptionValue "PlayerColorsSW" { 0, "$TXT_COLOR_BROWN" 1, "$TXT_COLOR_GRAY" @@ -1184,7 +1184,7 @@ OptionMenu "HUDOptions" //protected { Title "$OPTMNU_HUD" - Slider "$DSPLYMNU_SCREENSIZE", "hud_size", 3.0, 12.0, 1.0, 0 + Slider "$DSPLYMNU_SCREENSIZE", "hud_size", 0.0, 11.0, 1.0, -1 ifgame(duke, nam, ww2gi, redneck, redneckrides, fury) // Fixme: The scaling really needs to be taken out of the game code. { Slider "$DSPLYMNU_SBSCALE", "hud_scale", 0.3, 1.0, 0.1, 2 From b4f8960d958674e1c11879e98f6885d8ad035e82 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 8 Dec 2019 07:51:49 +0100 Subject: [PATCH 150/203] - removed unused code. --- source/mact/include/input.h | 9 ---- source/mact/src/input.cpp | 104 ------------------------------------ 2 files changed, 113 deletions(-) diff --git a/source/mact/include/input.h b/source/mact/include/input.h index 183ec8f0a..46917dca2 100644 --- a/source/mact/include/input.h +++ b/source/mact/include/input.h @@ -47,15 +47,6 @@ extern void I_GeneralTriggerClear(void); extern int32_t I_EscapeTrigger(void); extern void I_EscapeTriggerClear(void); -extern int32_t I_MenuUp(void); -extern void I_MenuUpClear(void); -extern int32_t I_MenuDown(void); -extern void I_MenuDownClear(void); -extern int32_t I_MenuLeft(void); -extern void I_MenuLeftClear(void); -extern int32_t I_MenuRight(void); -extern void I_MenuRightClear(void); - enum EnterTextFlags_t { INPUT_NUMERIC = 0x00000001, diff --git a/source/mact/src/input.cpp b/source/mact/src/input.cpp index 6bb72073b..3687637a7 100644 --- a/source/mact/src/input.cpp +++ b/source/mact/src/input.cpp @@ -137,110 +137,6 @@ void I_EscapeTriggerClear(void) } -int32_t I_MenuUp(void) -{ - return - inputState.GetKeyStatus(sc_UpArrow) - || inputState.GetKeyStatus(sc_kpad_8) - || (inputState.MouseGetButtons()&WHEELUP_MOUSE) - || buttonMap.ButtonDown(gamefunc_Move_Forward) - || (JOYSTICK_GetHat(0)&HAT_UP) - || (JOYSTICK_GetGameControllerButtons()&(1< Date: Sat, 7 Dec 2019 23:49:33 +0000 Subject: [PATCH 151/203] A small amount of driver_adlib cleanup git-svn-id: https://svn.eduke32.com/eduke32@8361 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # platform/Windows/audiolib.vcxproj # platform/Windows/audiolib.vcxproj.filters # source/audiolib/src/driver_adlib.cpp # source/audiolib/src/driver_adlib.h # source/audiolib/src/fx_man.cpp --- source/audiolib/include/al_midi.h | 2 +- source/audiolib/include/opl3_reg.h | 144 +++++++++++++++++++++++++++ source/audiolib/src/driver_adlib.cpp | 129 ++++++++++++------------ source/audiolib/src/driver_adlib.h | 1 + source/audiolib/src/midi.cpp | 4 +- 5 files changed, 209 insertions(+), 71 deletions(-) create mode 100644 source/audiolib/include/opl3_reg.h diff --git a/source/audiolib/include/al_midi.h b/source/audiolib/include/al_midi.h index f49d6058a..1dbb1608a 100644 --- a/source/audiolib/include/al_midi.h +++ b/source/audiolib/include/al_midi.h @@ -39,7 +39,7 @@ typedef struct extern AdLibTimbre ADLIB_TimbreBank[256]; opl3_chip *AL_GetChip(void); -void AL_RegisterTimbreBank(uint8_t *timbres); +void AL_RegisterTimbreBank(uint8_t const *timbres); void AL_SetStereo(int const stereo); #endif diff --git a/source/audiolib/include/opl3_reg.h b/source/audiolib/include/opl3_reg.h new file mode 100644 index 000000000..2396706d6 --- /dev/null +++ b/source/audiolib/include/opl3_reg.h @@ -0,0 +1,144 @@ +/* + * Copyright by Hannu Savolainen 1993-1996 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +// heavily modified for audiolib +// original definitions found at http://www.cs.albany.edu/~sdc/Linux/linux-2.0/drivers/sound/opl3.h +// it's from old Linux source but the license is pretty clearly 2-clause BSD. + +#ifndef opl3_reg_h__ +#define OPL3_opl3_reg_h__ + +#define OPL3_TEST_REGISTER 0x01 +#define OPL3_ENABLE_WAVE_SELECT 0x20 + +#define OPL3_TIMER1_REGISTER 0x02 +#define OPL3_TIMER2_REGISTER 0x03 +#define OPL3_TIMER_CONTROL_REGISTER 0x04 /* Left side */ +#define OPL3_IRQ_RESET 0x80 +#define OPL3_TIMER1_MASK 0x40 +#define OPL3_TIMER2_MASK 0x20 +#define OPL3_TIMER1_START 0x01 +#define OPL3_TIMER2_START 0x02 + +#define OPL3_CONNECTION_SELECT_REGISTER 0x04 /* Right side */ +#define OPL3_RIGHT_4OP_0 0x01 +#define OPL3_RIGHT_4OP_1 0x02 +#define OPL3_RIGHT_4OP_2 0x04 +#define OPL3_LEFT_4OP_0 0x08 +#define OPL3_LEFT_4OP_1 0x10 +#define OPL3_LEFT_4OP_2 0x20 + +#define OPL3_MODE_REGISTER 0x05 /* Right side */ +#define OPL3_ENABLE 0x01 +#define OPL3_OPL4_ENABLE 0x02 + +#define OPL3_KBD_SPLIT_REGISTER 0x08 /* Left side */ +#define OPL3_COMPOSITE_SINE_WAVE_MODE 0x80 /* Don't use with OPL-3? */ +#define OPL3_KEYBOARD_SPLIT 0x40 + +#define OPL3_PERCUSSION_REGISTER 0xbd /* Left side only */ +#define OPL3_TREMOLO_DEPTH 0x80 +#define OPL3_VIBRATO_DEPTH 0x40 +#define OPL3_PERCUSSION_ENABLE 0x20 +#define OPL3_BASSDRUM_ON 0x10 +#define OPL3_SNAREDRUM_ON 0x08 +#define OPL3_TOMTOM_ON 0x04 +#define OPL3_CYMBAL_ON 0x02 +#define OPL3_HIHAT_ON 0x01 + +/* + * Offsets to the register banks for operators. To get the + * register number just add the operator offset to the bank offset + * + * AM/VIB/EG/KSR/Multiple (0x20 to 0x35) + */ +#define OPL3_AM_VIB 0x20 +#define OPL3_TREMOLO_ON 0x80 +#define OPL3_VIBRATO_ON 0x40 +#define OPL3_SUSTAIN_ON 0x20 +#define OPL3_KSR 0x10 /* Key scaling rate */ +#define OPL3_MULTIPLE_MASK 0x0f /* Frequency multiplier */ + +/* + * KSL/Total level (0x40 to 0x55) + */ +#define OPL3_KSL_LEVEL 0x40 +#define OPL3_KSL_MASK 0xc0 /* Envelope scaling bits */ +#define OPL3_TOTAL_LEVEL_MASK 0x3f /* Strength (volume) of OP */ + +/* + * Attack / Decay rate (0x60 to 0x75) + */ +#define OPL3_ATTACK_DECAY 0x60 +#define OPL3_ATTACK_MASK 0xf0 +#define OPL3_DECAY_MASK 0x0f + +/* + * Sustain level / Release rate (0x80 to 0x95) + */ +#define OPL3_SUSTAIN_RELEASE 0x80 +#define OPL3_SUSTAIN_MASK 0xf0 +#define OPL3_RELEASE_MASK 0x0f + +/* + * Wave select (0xE0 to 0xF5) + */ +#define OPL3_WAVE_SELECT 0xe0 + +/* + * Offsets to the register banks for voices. Just add to the + * voice number to get the register number. + * + * F-Number low bits (0xA0 to 0xA8). + */ +#define OPL3_FNUM_LOW 0xa0 + +/* + * F-number high bits / Key on / Block (octave) (0xB0 to 0xB8) + */ +#define OPL3_KEYON_BLOCK 0xb0 +#define OPL3_KEYON_BIT 0x20 +#define OPL3_BLOCKNUM_MASK 0x1c +#define OPL3_FNUM_HIGH_MASK 0x03 + +/* + * Feedback / Connection (0xc0 to 0xc8) + * + * These registers have two new bits when the OPL-3 mode + * is selected. These bits controls connecting the voice + * to the stereo channels. For 4 OP voices this bit is + * defined in the second half of the voice (add 3 to the + * register offset). + * + * For 4 OP voices the connection bit is used in the + * both halfs (gives 4 ways to connect the operators). + */ +#define OPL3_FEEDBACK_CONNECTION 0xc0 +#define OPL3_FEEDBACK_MASK 0x0e /* Valid just for 1st OP of a voice */ +#define OPL3_CONNECTION_BIT 0x01 +#define OPL3_STEREO_BITS 0x30 /* OPL-3 only */ +#define OPL3_VOICE_TO_LEFT 0x10 +#define OPL3_VOICE_TO_RIGHT 0x20 + +#endif // opl3_reg_h__ diff --git a/source/audiolib/src/driver_adlib.cpp b/source/audiolib/src/driver_adlib.cpp index 599601ec8..aefb10bc5 100644 --- a/source/audiolib/src/driver_adlib.cpp +++ b/source/audiolib/src/driver_adlib.cpp @@ -37,6 +37,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "midi.h" #include "midifuncs.h" #include "opl3.h" +#include "opl3_reg.h" #include "c_cvars.h" CUSTOM_CVARD(Bool, mus_al_stereo, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enable/disable OPL3 stereo mode") @@ -127,7 +128,7 @@ static opl3_chip chip; opl3_chip *AL_GetChip(void) { return &chip; } -static constexpr uint32_t OctavePitch[MAX_OCTAVE+1] = { +static uint32_t constexpr OctavePitch[MAX_OCTAVE+1] = { OCTAVE_0, OCTAVE_1, OCTAVE_2, OCTAVE_3, OCTAVE_4, OCTAVE_5, OCTAVE_6, OCTAVE_7, }; @@ -141,7 +142,7 @@ static uint32_t NoteDiv12[MAX_NOTE+1]; // { C, C_SHARP, D, D_SHARP, E, F, F_SHARP, G, G_SHARP, A, A_SHARP, B }, // }; -static constexpr uint32_t NotePitch[FINETUNE_MAX+1][12] = { +static uint32_t constexpr NotePitch[FINETUNE_MAX+1][12] = { { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x241, 0x263, 0x287 }, { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x242, 0x264, 0x288 }, { 0x158, 0x16c, 0x182, 0x199, 0x1b1, 0x1cb, 0x1e6, 0x203, 0x221, 0x243, 0x265, 0x289 }, @@ -179,7 +180,7 @@ static constexpr uint32_t NotePitch[FINETUNE_MAX+1][12] = { // Slot numbers as a function of the voice and the operator. // ( melodic only) -static constexpr int slotVoice[NUMADLIBVOICES][2] = { +static int constexpr slotVoice[NUMADLIBVOICES][2] = { { 0, 3 }, // voice 0 { 1, 4 }, // 1 { 2, 5 }, // 2 @@ -197,7 +198,7 @@ static int VoiceKsl[AL_NumChipSlots][2]; // This table gives the offset of each slot within the chip. // offset = fn( slot) -static constexpr int8_t offsetSlot[AL_NumChipSlots] = { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21 }; +static int8_t constexpr offsetSlot[AL_NumChipSlots] = { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21 }; static int VoiceReserved[NUMADLIBVOICES * 2]; @@ -206,10 +207,14 @@ static AdLibVoiceList Voice_Pool; static AdLibChannel Channel[NUMADLIBCHANNELS]; -static int AL_LeftPort = ADLIB_PORT; -static int AL_RightPort = ADLIB_PORT; +static int constexpr AL_LeftPort = ADLIB_PORT; +static int constexpr AL_RightPort = ADLIB_PORT + 2; + +static int constexpr AL_MaxMidiChannel = ARRAY_SIZE(Channel); + int AL_Stereo = TRUE; -static int AL_MaxMidiChannel = 16; + +int AL_PostAmp = 3; // TODO: clean up this shit... #define OFFSET(structure, offset) (*((char **)&(structure)[offset])) @@ -260,8 +265,7 @@ static void AL_SendOutputToPort(int const port, int const reg, int const data) static void AL_SendOutput(int const voice, int const reg, int const data) { - int port = (voice == 0) ? AL_RightPort : AL_LeftPort; - AL_SendOutputToPort(port, reg, data); + AL_SendOutputToPort(voice ? AL_LeftPort : AL_RightPort, reg, data); } @@ -282,39 +286,39 @@ static void AL_SetVoiceTimbre(int const voice) int slot = slotVoice[voc][0]; int off = offsetSlot[slot]; - VoiceLevel[slot][port] = 63 - (timbre->Level[0] & 0x3f); - VoiceKsl[slot][port] = timbre->Level[0] & 0xc0; + VoiceLevel[slot][port] = OPL3_TOTAL_LEVEL_MASK - (timbre->Level[0] & OPL3_TOTAL_LEVEL_MASK); + VoiceKsl[slot][port] = timbre->Level[0] & OPL3_KSL_MASK; - AL_SendOutput(port, 0xA0 + voc, 0); - AL_SendOutput(port, 0xB0 + voc, 0); + AL_SendOutput(port, OPL3_FNUM_LOW + voc, 0); + AL_SendOutput(port, OPL3_KEYON_BLOCK + voc, 0); // Let voice clear the release - AL_SendOutput(port, 0x80 + off, 0xff); + AL_SendOutput(port, OPL3_SUSTAIN_RELEASE + off, 0xff); - AL_SendOutput(port, 0x60 + off, timbre->Env1[0]); - AL_SendOutput(port, 0x80 + off, timbre->Env2[0]); - AL_SendOutput(port, 0x20 + off, timbre->SAVEK[0]); - AL_SendOutput(port, 0xE0 + off, timbre->Wave[0]); + AL_SendOutput(port, OPL3_ATTACK_DECAY + off, timbre->Env1[0]); + AL_SendOutput(port, OPL3_SUSTAIN_RELEASE + off, timbre->Env2[0]); + AL_SendOutput(port, OPL3_ENABLE_WAVE_SELECT + off, timbre->SAVEK[0]); + AL_SendOutput(port, OPL3_WAVE_SELECT + off, timbre->Wave[0]); - AL_SendOutput(port, 0x40 + off, timbre->Level[0]); + AL_SendOutput(port, OPL3_KSL_LEVEL + off, timbre->Level[0]); slot = slotVoice[voc][1]; - AL_SendOutput(port, 0xC0 + voc, (timbre->Feedback & 0x0f) | 0x30); + AL_SendOutput(port, OPL3_FEEDBACK_CONNECTION + voc, (timbre->Feedback & OPL3_FEEDBACK_MASK) | OPL3_STEREO_BITS); off = offsetSlot[slot]; - VoiceLevel[slot][port] = 63 - (timbre->Level[1] & 0x3f); - VoiceKsl[slot][port] = timbre->Level[1] & 0xc0; + VoiceLevel[slot][port] = OPL3_TOTAL_LEVEL_MASK - (timbre->Level[1] & OPL3_TOTAL_LEVEL_MASK); + VoiceKsl[slot][port] = timbre->Level[1] & OPL3_KSL_MASK; - AL_SendOutput(port, 0x40 + off, 63); + AL_SendOutput(port, OPL3_KSL_LEVEL + off, OPL3_TOTAL_LEVEL_MASK); // Let voice clear the release - AL_SendOutput(port, 0x80 + off, 0xff); + AL_SendOutput(port, OPL3_SUSTAIN_RELEASE + off, 0xff); - AL_SendOutput(port, 0x60 + off, timbre->Env1[1]); - AL_SendOutput(port, 0x80 + off, timbre->Env2[1]); - AL_SendOutput(port, 0x20 + off, timbre->SAVEK[1]); - AL_SendOutput(port, 0xE0 + off, timbre->Wave[1]); + AL_SendOutput(port, OPL3_ATTACK_DECAY + off, timbre->Env1[1]); + AL_SendOutput(port, OPL3_SUSTAIN_RELEASE + off, timbre->Env2[1]); + AL_SendOutput(port, OPL3_ENABLE_WAVE_SELECT + off, timbre->SAVEK[1]); + AL_SendOutput(port, OPL3_WAVE_SELECT + off, timbre->Wave[1]); } @@ -332,10 +336,10 @@ static void AL_SetVoiceVolume(int const voice) auto t1 = (uint32_t)VoiceLevel[slot][port] * (velocity + 0x80); t1 = (Channel[channel].Volume * t1) >> 15; - uint32_t volume = t1 ^ 63; + uint32_t volume = t1 ^ OPL3_TOTAL_LEVEL_MASK; volume |= (uint32_t)VoiceKsl[slot][port]; - AL_SendOutput(port, 0x40 + offsetSlot[slot], volume); + AL_SendOutput(port, OPL3_KSL_LEVEL + offsetSlot[slot], volume); // Check if this timbre is Additive if (timbre->Feedback & 0x01) @@ -349,24 +353,22 @@ static void AL_SetVoiceVolume(int const voice) t2 = (Channel[channel].Volume * t1) >> 15; - volume = t2 ^ 63; + volume = t2 ^ OPL3_TOTAL_LEVEL_MASK; volume |= (uint32_t)VoiceKsl[slot][port]; - AL_SendOutput(port, 0x40 + offsetSlot[slot], volume); + AL_SendOutput(port, OPL3_KSL_LEVEL + offsetSlot[slot], volume); } } static int AL_AllocVoice(void) { - if (Voice_Pool.start) - { + if (!Voice_Pool.start) + return AL_VoiceNotFound; + int const voice = Voice_Pool.start->num; LL_Remove(AdLibVoice, &Voice_Pool, &Voice[voice]); return voice; - } - - return AL_VoiceNotFound; } @@ -418,8 +420,8 @@ static void AL_SetVoicePitch(int const voice) pitch |= Voice[voice].status; - AL_SendOutput(port, 0xA0 + voc, pitch); - AL_SendOutput(port, 0xB0 + voc, pitch >> 8); + AL_SendOutput(port, OPL3_FNUM_LOW + voc, pitch); + AL_SendOutput(port, OPL3_KEYON_BLOCK + voc, pitch >> 8); } static void AL_SetVoicePan(int const voice) @@ -531,32 +533,32 @@ static void AL_FlushCard(int const port) auto slot1 = offsetSlot[slotVoice[i][0]]; auto slot2 = offsetSlot[slotVoice[i][1]]; - AL_SendOutputToPort(port, 0xA0 + i, 0); - AL_SendOutputToPort(port, 0xB0 + i, 0); + AL_SendOutputToPort(port, OPL3_FNUM_LOW + i, 0); + AL_SendOutputToPort(port, OPL3_KEYON_BLOCK + i, 0); - AL_SendOutputToPort(port, 0xE0 + slot1, 0); - AL_SendOutputToPort(port, 0xE0 + slot2, 0); + AL_SendOutputToPort(port, OPL3_WAVE_SELECT + slot1, 0); + AL_SendOutputToPort(port, OPL3_WAVE_SELECT + slot2, 0); // Set the envelope to be fast and quiet - AL_SendOutputToPort(port, 0x60 + slot1, 0xff); - AL_SendOutputToPort(port, 0x60 + slot2, 0xff); - AL_SendOutputToPort(port, 0x80 + slot1, 0xff); - AL_SendOutputToPort(port, 0x80 + slot2, 0xff); + AL_SendOutputToPort(port, OPL3_ATTACK_DECAY + slot1, 0xff); + AL_SendOutputToPort(port, OPL3_ATTACK_DECAY + slot2, 0xff); + AL_SendOutputToPort(port, OPL3_SUSTAIN_RELEASE + slot1, 0xff); + AL_SendOutputToPort(port, OPL3_SUSTAIN_RELEASE + slot2, 0xff); // Maximum attenuation - AL_SendOutputToPort(port, 0x40 + slot1, 0xff); - AL_SendOutputToPort(port, 0x40 + slot2, 0xff); + AL_SendOutputToPort(port, OPL3_KSL_LEVEL + slot1, 0xff); + AL_SendOutputToPort(port, OPL3_KSL_LEVEL + slot2, 0xff); } } static void AL_Reset(void) { - AL_SendOutputToPort(ADLIB_PORT, 1, 0x20); - AL_SendOutputToPort(ADLIB_PORT, 0x08, 0); + AL_SendOutputToPort(ADLIB_PORT, 1, OPL3_ENABLE_WAVE_SELECT); + AL_SendOutputToPort(ADLIB_PORT, OPL3_KBD_SPLIT_REGISTER, 0); // Set the values: AM Depth, VIB depth & Rhythm - AL_SendOutputToPort(ADLIB_PORT, 0xBD, 0); + AL_SendOutputToPort(ADLIB_PORT, OPL3_PERCUSSION_REGISTER, 0); AL_SetStereo(AL_Stereo); @@ -565,10 +567,7 @@ static void AL_Reset(void) } -void AL_SetStereo(int const stereo) -{ - AL_SendOutputToPort(AL_RightPort, 0x5, (stereo<<1)+1); -} +void AL_SetStereo(int const stereo) { AL_SendOutputToPort(AL_RightPort, OPL3_MODE_REGISTER, (stereo << 1) + 1); } static void AL_NoteOff(int const channel, int const key, int velocity) @@ -579,17 +578,17 @@ static void AL_NoteOff(int const channel, int const key, int velocity) if (channel > AL_MaxMidiChannel) return; - int voice = AL_GetVoice(channel, key); + int const voice = AL_GetVoice(channel, key); if (voice == AL_VoiceNotFound) return; Voice[voice].status = NOTE_OFF; - int port = Voice[voice].port; - int voc = (voice >= NUMADLIBVOICES) ? voice - NUMADLIBVOICES : voice; + int const port = Voice[voice].port; + int const voc = (voice >= NUMADLIBVOICES) ? voice - NUMADLIBVOICES : voice; - AL_SendOutput(port, 0xB0 + voc, hibyte(Voice[voice].pitchleft)); + AL_SendOutput(port, OPL3_KEYON_BLOCK + voc, hibyte(Voice[voice].pitchleft)); LL_Remove(AdLibVoice, &Channel[channel].Voices, &Voice[voice]); LL_AddToTail(AdLibVoice, &Voice_Pool, &Voice[voice]); @@ -720,12 +719,9 @@ static void AL_SetPitchBend(int const channel, int const lsb, int const msb) return; int const pitchbend = lsb + (msb << 8); + int const TotalBend = pitchbend * Channel[channel].PitchBendRange / (PITCHBEND_CENTER / FINETUNE_RANGE); Channel[channel].Pitchbend = pitchbend; - - int TotalBend = pitchbend * Channel[channel].PitchBendRange; - TotalBend /= (PITCHBEND_CENTER / FINETUNE_RANGE); - Channel[channel].KeyOffset = (int)(TotalBend / FINETUNE_RANGE); Channel[channel].KeyOffset -= Channel[channel].PitchBendSemiTones; @@ -751,9 +747,6 @@ static int AL_Init(int const rate) { OPL3_Reset(&chip, rate); - AL_LeftPort = ADLIB_PORT; - AL_RightPort = ADLIB_PORT + 2; - AL_CalcPitchInfo(); AL_Reset(); AL_ResetVoices(); @@ -762,7 +755,7 @@ static int AL_Init(int const rate) } -void AL_RegisterTimbreBank(uint8_t *timbres) +void AL_RegisterTimbreBank(uint8_t const *timbres) { for (int i = 0; i < 256; i++) { diff --git a/source/audiolib/src/driver_adlib.h b/source/audiolib/src/driver_adlib.h index 1ddd90544..198d84ae8 100644 --- a/source/audiolib/src/driver_adlib.h +++ b/source/audiolib/src/driver_adlib.h @@ -23,6 +23,7 @@ #include "opl3.h" extern int AL_Stereo; +extern int AL_PostAmp; int AdLibDrv_GetError(void); const char *AdLibDrv_ErrorString(int ErrorNumber); diff --git a/source/audiolib/src/midi.cpp b/source/audiolib/src/midi.cpp index 5347c74e4..cef907974 100644 --- a/source/audiolib/src/midi.cpp +++ b/source/audiolib/src/midi.cpp @@ -538,8 +538,8 @@ static void _MIDI_ServiceMultivoc(void) } if (MV_MIDIRenderTempo >= 0) MV_MIDIRenderTimer += MV_MIDIRenderTempo; OPL3_GenerateResampled(AL_GetChip(), buf); - *buffer16++ = clamp(buf[0]<<3, INT16_MIN, INT16_MAX); - *buffer16++ = clamp(buf[1]<<3, INT16_MIN, INT16_MAX); + *buffer16++ = clamp(buf[0]< Date: Sat, 7 Dec 2019 23:49:37 +0000 Subject: [PATCH 152/203] Update gamecontrollerdb.txt git-svn-id: https://svn.eduke32.com/eduke32@8362 1a8010ca-5511-0410-912e-c29ae57300e0 --- package/common/gamecontrollerdb.txt | 120 ++++++++++++++++++++++++++-- 1 file changed, 113 insertions(+), 7 deletions(-) diff --git a/package/common/gamecontrollerdb.txt b/package/common/gamecontrollerdb.txt index 97dd5c0c7..78d3bdf8b 100644 --- a/package/common/gamecontrollerdb.txt +++ b/package/common/gamecontrollerdb.txt @@ -1,18 +1,44 @@ -# Game Controller DB for SDL in 2.0.9 format +# Game Controller DB for SDL in 2.0.10 format # Source: https://github.com/gabomdq/SDL_GameControllerDB # Windows 03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Windows, 03000000c82d00002038000000000000,8bitdo,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d000011ab000000000000,8BitDo F30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00001038000000000000,8BitDo F30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000650000000000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:a4,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows, +03000000c82d00000310000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, +03000000c82d00002028000000000000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00008010000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, +03000000c82d00000190000000000000,8BitDo N30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00001590000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00015900000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00065280000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000022000000090000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000203800000900000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000130000000000000,8BitDo SF30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000060000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000061000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d000021ab000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00003028000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000030000000000000,8BitDo SN30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000351000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00001290000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d000020ab000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00004028000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00006228000000000000,8BitDo SN30 GP,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000031000000000000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, 030000008f0e00001200000000000000,Acme GA-02,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows, 03000000fa190000f0ff000000000000,Acteck AGJ-3200,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +030000006f0e00001413000000000000,Afterglow,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000341a00003608000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00000263000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00001101000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, @@ -21,6 +47,7 @@ 030000006f0e00001901000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00001a01000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000d62000001d57000000000000,Airflo PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000869800002400000000007801,Astro C40 TR,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000d6200000e557000000000000,Batarang,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows, 030000006f0e00003201000000000000,Battlefield 4 PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, @@ -38,6 +65,7 @@ 0300000066f700000500000000000000,BrutalLegendTest,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, 03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows, 03000000e82000006058000000000000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +03000000457500000401000000000000,Cobra,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000005e0400008e02000000000000,Controller (XBOX 360 For Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e040000a102000000000000,Controller (Xbox 360 Wireless Receiver for Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e040000ff02000000000000,Controller (Xbox One For Windows) - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, @@ -50,6 +78,7 @@ 030000006f0e00003001000000000000,EA SPORTS PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000b80500000410000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows, 03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows, +03000000120c0000f61c000000000000,Elite,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000008f0e00000f31000000000000,EXEQ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, 03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000852100000201000000000000,FF-GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, @@ -83,6 +112,7 @@ 030000000d0f00004900000000000000,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, 03000000632500002605000000000000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +030000000d0f00002d00000000000000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00005f00000000000000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00005e00000000000000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00004000000000000000,Hori Fighting Stick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, @@ -90,9 +120,11 @@ 030000000d0f00000900000000000000,Hori Pad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00004d00000000000000,Hori Pad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00009200000000000000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00009c00000000000000,Hori TAC Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000c100000000000000,Horipad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00006e00000000000000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00006600000000000000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00005500000000000000,Horipad 4 FPS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000ee00000000000000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000250900000017000000000000,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows, 030000008f0e00001330000000000000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Windows, @@ -138,9 +170,13 @@ 03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows, 03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, 03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, +03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows, +0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +03000000d620000010a7000000000000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000008f0e00001030000000000000,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows, 0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, 03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000790000002418000000000000,Mega Drive,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b2,start:b9,x:b3,y:b4,platform:Windows, 03000000380700006382000000000000,MLG GamePad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000efbe0000edfe000000000000,Monect Virtual Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows, 03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, @@ -191,6 +227,8 @@ 03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000321500000204000000000000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000321500000104000000000000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000321500000507000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000321500000707000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 030000000d0f00001100000000000000,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00006a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00006b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, @@ -221,14 +259,16 @@ 03000000a30600002106000000000000,Saitek PS1000,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000a306000020f6000000000000,Saitek PS2700,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000300f00001101000000000000,Saitek Rumble Pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, +03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows, 0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, 030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, -# 030000005e0400008e02000000007801,ShanWan PS3/PC Wired GamePad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +030000005e0400008e02000000007801,ShanWan PS3/PC Wired GamePad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows, 03000000341a00000908000000000000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 030000008f0e00000800000000000000,SpeedLink Strike FX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000c01100000591000000000000,Speedlink Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000381000001214000000000000,SteelSeries Free,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows, 03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,platform:Windows, 03000000790000001c18000000000000,STK-7024X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,platform:Windows, @@ -247,6 +287,7 @@ 03000000b80500000210000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 030000004f04000087b6000000000000,TWCS Throttle,dpdown:b8,dpleft:b9,dpright:b7,dpup:b6,leftstick:b5,lefttrigger:-a5,leftx:a0,lefty:a1,righttrigger:+a5,platform:Windows, 03000000d90400000200000000000000,TwinShock PS2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, +030000006e0500001320000000000000,U4113,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000101c0000171c000000000000,uRage Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000300f00000701000000000000,USB 4-Axis 12-Button Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 03000000341a00002308000000000000,USB gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, @@ -256,7 +297,9 @@ 03000000f0250000c183000000000000,USB gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000ff1100004133000000000000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 03000000632500002305000000000000,USB Vibration Joystick (BM),a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +03000000790000001a18000000000000,Venom,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000006f0e00000302000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, @@ -267,10 +310,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, # Mac OS X 030000008f0e00000300000009010000,2In1 USB Joystick,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X, +03000000c82d00000650000001000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000022000000090000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000190000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000102800000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00000031000001000000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000a00500003232000009010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, @@ -282,6 +329,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, 030000006f0e00000102000000000000,GameStop Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000007d0400000540000001010000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X, +030000000d0f00002d00000000100000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 030000000d0f00005f00000000010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 030000000d0f00005e00000000010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 030000000d0f00005f00000000000000,HORI Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, @@ -302,6 +350,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000006d04000016c2000014040000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 030000006d04000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 030000006d04000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000006d04000019c2000005030000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 030000006d0400001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000006d04000018c2000000010000,Logitech RumblePad 2 USB,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3~,start:b9,x:b0,y:b3,platform:Mac OS X, 030000006d04000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, @@ -310,14 +359,19 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000380700008433000000010000,Mad Catz FightStick TE S+ (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000380700008483000000010000,Mad Catz FightStick TE S+ (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Mac OS X, +03000000242f00007300000000020000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Mac OS X, +0300000079000000d218000026010000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X, +03000000d620000010a7000003010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X, 03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X, 03000000d8140000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X, +03000000632500007505000000020000,NEOGEO mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Mac OS X, 030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Mac OS X, 030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, 030000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, 030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X, +030000004c050000da0c000000010000,Playstation Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X, 03000000d62000006dca000000010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X, 030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X, @@ -329,6 +383,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000321500000204000000010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000321500000104000000010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000321500000010000000010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +03000000321500000507000001010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000321500000009000000020000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X, 030000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X, 0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, @@ -336,6 +391,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, 030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000c6240000fefa000000000000,Rock Candy Gamepad for PS3,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +03000000730700000401000000010000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Mac OS X, 03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X, 03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X, 030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, @@ -353,6 +409,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000bd12000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, 03000000bd12000015d0000000010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, 03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X, +030000006f0e00000302000025040000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X, +03000000791d00000103000009010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X, 050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X, 050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X, 030000005e0400008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, @@ -370,37 +428,57 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, # Linux 05000000c82d00001038000000010000,8Bitdo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00008010000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux, 03000000022000000090000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000190000011010000,8Bitdo NES30 Pro 8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00000061000000010000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, 05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00003028000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001290000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00006228000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +030000005e0400008e02000020010000,8BitDo Wireless Adapter,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00000031000011010000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, 05000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, 030000006f0e00001302000000010000,Afterglow,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00003901000020060000,Afterglow Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, -030000006f0e00003901000013020000,Afterglow Prismatic Wired Controller 048-007-NA,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux, 030000006f0e00003901000000430000,Afterglow Prismatic Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00003901000013020000,Afterglow Prismatic Wired Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, 05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, 03000000120c00000500000010010000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux, 03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux, +03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, 03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux, 03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux, 03000000a306000022f6000011010000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, 03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux, 03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux, +030000004f04000004b3000010010000,Dual Power 2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, 030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux, 03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000008f0e00000800000010010000,Gasia Co. Ltd PS(R) Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, -030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:a0,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:a3,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000007d0400000540000000010000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, @@ -408,6 +486,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys GamePad ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux, 030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, 0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000f0250000c383000010010000,GT VX2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 06000000adde0000efbe000002010000,Hidromancer Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux, 03000000c9110000f055000011010000,HJC Game GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, @@ -428,6 +507,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, 050000006964726f69643a636f6e0000,idroid:con,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000b50700001503000010010000,impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000d80400008200000003000000,IMS PCU#0 Gamepad Interface,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux, 03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux, 0500000049190000020400001b010000,Ipega PG-9069 - Bluetooth Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, @@ -463,10 +543,12 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, -0300000079000000d218000011010000,MAGIC-NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000120c00000500000000010000,Manta Dualshock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, 03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux, 03000000790000004318000010010000,Mayflash GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux, +0300000079000000d218000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000d620000010a7000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 0300000025090000e803000001010000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, 03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 030000005e0400000e00000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux, @@ -478,12 +560,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000005e040000d102000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, 030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +03000000c62400001a53000000010000,Mini PE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, 05000000d6200000e589000001000000,Moga 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, 05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, 05000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, 03000000250900006688000000010000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, 030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Linux, +030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux, 050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, 05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, @@ -498,9 +583,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e0000a802000023020000,PDP Wired Controller for Xbox One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, @@ -510,7 +597,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000006f0e00001402000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000008f0e00000300000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 050000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, -050000004c0500006802000000800000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c0500006802000000800000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 050000004c0500006802000000810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 05000000504c415953544154494f4e00,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, 060000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, @@ -521,6 +608,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000004c050000cc09000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +03000000c01100000140000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 050000004c050000c405000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, @@ -533,6 +621,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000321500000204000011010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000321500000104000011010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000321500000010000011010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000008916000000fe000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c6240000045d000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, @@ -540,6 +629,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, 0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000790000001100000010010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, +0300000081170000990a000001010000,Retronic Adapter,a:b0,leftx:a0,lefty:a1,platform:Linux, 0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, 030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000006f0e00001f01000000010000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, @@ -548,9 +638,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, 03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, 03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux, +03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a1,righty:a2,start:b9,x:b0,y:b1,platform:Linux, 03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, 03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux, 03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux, 03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux, 03000000f025000021c1000010010000,ShanWan Gioteck PS3 Wired Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000632500007505000010010000,SHANWAN PS3/PC Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, @@ -582,11 +674,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000004f04000012b3000010010000,Thrustmaster vibrating gamepad,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, 03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux, +030000005e0400008e02000070050000,Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c01100000591000011010000,Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, 03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, 03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux, 03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux, +030000006f0e00000302000011010000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +03000000791d00000103000010010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, @@ -596,9 +692,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux, 030000005e040000a102000014010000,Xbox 360 Wireless Receiver (XBOX),a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, -030000005e040000ea02000001030000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000d102000002010000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux, 03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux, @@ -619,6 +717,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000004c050000c4050000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, 050000004c050000cc090000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, 35643031303033326130316330353564,PS4 Controller,a:b1,b:b17,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, +050000003215000005070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +050000003215000007070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000003215000000090000bf7f3f00,Razer Serval,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android, 05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android, 05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android, @@ -630,9 +730,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, # iOS 05000000ac0500000100000000006d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS, +05000000ac050000010000004f066d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS, +05000000ac05000001000000cf076d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS, 05000000ac0500000200000000006d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS, +05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS, +050000004c050000cc090000df070000,DUALSHOCK 4 Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, 4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS, 4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS, 05000000ac0500000300000000006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS, +05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS, 05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS, 05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS, +050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, From 265e7109aa75f9617144293d8775d940445ba091 Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:49:41 +0000 Subject: [PATCH 153/203] Equivalent to https://github.com/jonof/jfbuild/commit/04e7e6af69f29479282a487382237d4a70c7be14 git-svn-id: https://svn.eduke32.com/eduke32@8363 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/build/src/engine.cpp | 55 +++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 08d8cc25e..3f4ca9a95 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -159,7 +159,8 @@ int32_t globaltilesizy; int32_t globalx1, globaly2, globalx3, globaly3; int32_t sloptable[SLOPTABLESIZ]; -static intptr_t slopalookup[16384]; // was 2048 +#define SLOPALOOKUPSIZ (MAXXDIM<<1) +static intptr_t slopalookup[SLOPALOOKUPSIZ]; // was 2048 static int32_t no_radarang2 = 0; static int16_t radarang[1280]; @@ -3389,7 +3390,7 @@ static void fgrouscan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat) int32_t i, j, l, globalx1, globaly1, y1, y2, daslope, daz, wxi, wyi; float fi, wx, wy, dasqr; float globalx, globaly, globalx2, globaly2, globalx3, globaly3, globalz, globalzd, globalzx; - int32_t shoffs, m1, m2; + int32_t shoffs, m1, m2, shy1, shy2; intptr_t *mptr1, *mptr2; const usectortype *const sec = (usectortype *)§or[sectnum]; @@ -3523,7 +3524,14 @@ static void fgrouscan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat) //Avoid visibility overflow by crossing horizon m1 += klabs(l); m2 = m1+l; - mptr1 = (intptr_t *)&slopalookup[y1+(shoffs>>15)]; mptr2 = mptr1+1; + shy1 = y1+(shoffs>>15); + if ((unsigned)shy1 >= SLOPALOOKUPSIZ-1) + { + OSD_Printf("%s:%d: slopalookup[] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, sectnum); + return; + } + + mptr1 = &slopalookup[shy1]; mptr2 = mptr1+1; for (int x=dax1; x<=dax2; x++) { @@ -3531,8 +3539,18 @@ static void fgrouscan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat) else { y1 = max(umost[x],dplc[x]); y2 = dmost[x]-1; } if (y1 <= y2) { - intptr_t *nptr1 = &slopalookup[y1+(shoffs>>15)]; - intptr_t *nptr2 = &slopalookup[y2+(shoffs>>15)]; + shy1 = y1+(shoffs>>15); + shy2 = y2+(shoffs>>15); + + if ((unsigned)shy1 >= SLOPALOOKUPSIZ || (unsigned)shy2 >= SLOPALOOKUPSIZ) + { + // Ridiculously steep gradient? + OSD_Printf("%s:%d: slopalookup[] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, sectnum); + goto next_most; + } + + intptr_t *nptr1 = &slopalookup[shy1]; + intptr_t *nptr2 = &slopalookup[shy2]; while (nptr1 <= mptr1) { @@ -3662,6 +3680,7 @@ static void fgrouscan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat) #undef LINTERPSIZ if ((x&15) == 0) faketimerhandler(); } +next_most: globalx2 += globalx; globaly2 += globaly; globalzx += globalz; @@ -3678,7 +3697,7 @@ static void grouscan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat) } int32_t i, l, x, y, dx, dy, wx, wy, y1, y2, daz; int32_t daslope, dasqr; - int32_t shoffs, m1, m2; + int32_t shoffs, m1, m2, shy1, shy2; intptr_t *mptr1, *mptr2, j; // Er, yes, they're not global anymore: @@ -3810,7 +3829,14 @@ static void grouscan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat) //Avoid visibility overflow by crossing horizon m1 += klabs((int32_t) (globalzd>>16)); m2 = m1+l; - mptr1 = (intptr_t *)&slopalookup[y1+(shoffs>>15)]; mptr2 = mptr1+1; + shy1 = y1+(shoffs>>15); + if ((unsigned)shy1 >= SLOPALOOKUPSIZ - 1) + { + OSD_Printf("%s:%d: slopalookup[] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, sectnum); + return; + } + + mptr1 = &slopalookup[shy1]; mptr2 = mptr1+1; for (x=dax1; x<=dax2; x++) { @@ -3818,8 +3844,18 @@ static void grouscan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat) else { y1 = max(umost[x],dplc[x]); y2 = dmost[x]-1; } if (y1 <= y2) { - intptr_t *nptr1 = &slopalookup[y1+(shoffs>>15)]; - intptr_t *nptr2 = &slopalookup[y2+(shoffs>>15)]; + shy1 = y1+(shoffs>>15); + shy2 = y2+(shoffs>>15); + + if ((unsigned)shy1 >= SLOPALOOKUPSIZ || (unsigned)shy2 >= SLOPALOOKUPSIZ) + { + // Ridiculously steep gradient? + OSD_Printf("%s:%d: slopalookup[] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, sectnum); + goto next_most; + } + + intptr_t *nptr1 = &slopalookup[shy1]; + intptr_t *nptr2 = &slopalookup[shy2]; while (nptr1 <= mptr1) { @@ -3851,6 +3887,7 @@ static void grouscan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat) if ((x&15) == 0) faketimerhandler(); } +next_most: globalx2 += globalx; globaly2 += globaly; globalzx += globalz; From cbfb675577a1f420dec0ce8d3076e4b5d824b30f Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:49:56 +0000 Subject: [PATCH 154/203] Shitcan the few uses of the bool type in the VM after reading some things and dicking around on godbolt.org git-svn-id: https://svn.eduke32.com/eduke32@8366 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # source/duke3d/src/gameexec.cpp # source/duke3d/src/gameexec.h --- source/build/include/build.h | 6 +++--- source/build/src/engine.cpp | 4 ++-- source/duke3d/src/gameexec.cpp | 16 +++++++++------- source/duke3d/src/gameexec.h | 2 +- source/duke3d/src/gamevars.h | 2 +- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/source/build/include/build.h b/source/build/include/build.h index 75999d0c1..30acb47cc 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -891,7 +891,7 @@ void updatesectorneighbor(int32_t const x, int32_t const y, int16_t * const sect void updatesectorneighborz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum, int32_t initialMaxDistance = INITIALUPDATESECTORDIST, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(4))); int findwallbetweensectors(int sect1, int sect2); -static FORCE_INLINE bool sectoradjacent(int sect1, int sect2) { return findwallbetweensectors(sect1, sect2) != -1; } +static FORCE_INLINE int sectoradjacent(int sect1, int sect2) { return findwallbetweensectors(sect1, sect2) != -1; } int32_t getsectordist(vec2_t const in, int const sectnum, vec2_t * const out = nullptr); extern const int16_t *chsecptr_onextwall; int32_t checksectorpointer(int16_t i, int16_t sectnum); @@ -1147,7 +1147,7 @@ static FORCE_INLINE int32_t md_tilehasmodel(int32_t const tilenume, int32_t cons } #endif // defined USE_OPENGL -static FORCE_INLINE bool tilehasmodelorvoxel(int const tilenume, int pal) +static FORCE_INLINE int tilehasmodelorvoxel(int const tilenume, int pal) { UNREFERENCED_PARAMETER(pal); return @@ -1189,7 +1189,7 @@ extern const int32_t engine_v8; int32_t Mulscale(int32_t a, int32_t b, int32_t sh); #endif -static FORCE_INLINE CONSTEXPR bool inside_p(int32_t const x, int32_t const y, int const sectnum) { return (sectnum >= 0 && inside(x, y, sectnum) == 1); } +static FORCE_INLINE CONSTEXPR int inside_p(int32_t const x, int32_t const y, int const sectnum) { return (sectnum >= 0 && inside(x, y, sectnum) == 1); } #define SET_AND_RETURN(Lval, Rval) \ do \ diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 3f4ca9a95..e6e33f752 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -10996,13 +10996,13 @@ int32_t lastwall(int16_t point) * NOTE: The redundant bound checks are expected to be optimized away in the * inlined code. */ -static FORCE_INLINE CONSTEXPR bool inside_exclude_p(int32_t const x, int32_t const y, int const sectnum, const uint8_t *excludesectbitmap) +static FORCE_INLINE CONSTEXPR int inside_exclude_p(int32_t const x, int32_t const y, int const sectnum, const uint8_t *excludesectbitmap) { return (sectnum>=0 && !bitmap_test(excludesectbitmap, sectnum) && inside_p(x, y, sectnum)); } /* NOTE: no bound check */ -static inline bool inside_z_p(int32_t const x, int32_t const y, int32_t const z, int const sectnum) +static inline int inside_z_p(int32_t const x, int32_t const y, int32_t const z, int const sectnum) { int32_t cz, fz; getzsofslope(sectnum, x, y, &cz, &fz); diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index 8bbd4bdc5..b05f80dac 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -83,7 +83,7 @@ int32_t g_structVarIDs = -1; uint32_t g_eventCalls[MAXEVENTS], g_actorCalls[MAXTILES]; double g_eventTotalMs[MAXEVENTS], g_actorTotalMs[MAXTILES], g_actorMinMs[MAXTILES], g_actorMaxMs[MAXTILES]; -GAMEEXEC_STATIC void VM_Execute(bool const loop = false); +GAMEEXEC_STATIC void VM_Execute(int const loop = false); # include "gamestructures.cpp" #endif @@ -244,7 +244,7 @@ int32_t VM_ExecuteEventWithValue(int const nEventID, int const spriteNum, int co } -static bool VM_CheckSquished(void) +static int VM_CheckSquished(void) { auto const pSector = (usectorptr_t)§or[vm.pSprite->sectnum]; @@ -298,7 +298,9 @@ GAMEEXEC_STATIC GAMEEXEC_INLINE void P_ForceAngle(DukePlayer_t *pPlayer) #endif // wow, this function sucks -bool A_Dodge(spritetype * const pSprite) + +int A_Dodge(spritetype * const); +int A_Dodge(spritetype * const pSprite) { if (A_CheckEnemySprite(pSprite) && pSprite->extra <= 0) // hack return 0; @@ -1175,7 +1177,7 @@ static int G_StartTrackSlotWrap(int const volumeNum, int const levelNum) int G_StartTrack(int const levelNum) { return G_StartTrackSlot(ud.volume_number, levelNum); } #endif -LUNATIC_EXTERN void G_ShowView(vec3_t vec, fix16_t a, fix16_t horiz, int sect, int ix1, int iy1, int ix2, int iy2, bool unbiasedp) +LUNATIC_EXTERN void G_ShowView(vec3_t vec, fix16_t a, fix16_t horiz, int sect, int ix1, int iy1, int ix2, int iy2, int unbiasedp) { int x1 = min(ix1, ix2); int x2 = max(ix1, ix2); @@ -1305,7 +1307,7 @@ void Screen_Play(void) } \ } while (0) -GAMEEXEC_STATIC void VM_Execute(bool const loop /*= false*/) +GAMEEXEC_STATIC void VM_Execute(int const loop /*= false*/) { int vm_execution_depth = loop; #ifdef CON_USE_COMPUTED_GOTO @@ -5280,7 +5282,7 @@ badindex: // -1 for none found // int const decodedInst = VM_DECODE_INST(tw); - bool const actorsOnly = (decodedInst == CON_FINDNEARACTOR || decodedInst == CON_FINDNEARACTOR3D); + int const actorsOnly = (decodedInst == CON_FINDNEARACTOR || decodedInst == CON_FINDNEARACTOR3D); auto const dist_funcptr = (decodedInst == CON_FINDNEARACTOR || decodedInst == CON_FINDNEARSPRITE) ? &ldist : &dist; int const findTile = *insptr++; @@ -5328,7 +5330,7 @@ badindex: // that is of into // -1 for none found // - bool const actorsOnly = (VM_DECODE_INST(tw) == CON_FINDNEARACTORZ); + int const actorsOnly = (VM_DECODE_INST(tw) == CON_FINDNEARACTORZ); int const findTile = *insptr++; int maxDist = Gv_GetVar(*insptr++); diff --git a/source/duke3d/src/gameexec.h b/source/duke3d/src/gameexec.h index 513672223..55939578f 100644 --- a/source/duke3d/src/gameexec.h +++ b/source/duke3d/src/gameexec.h @@ -35,7 +35,7 @@ int32_t VM_ExecuteEvent(int const nEventID, int const spriteNum, int const playe int32_t VM_ExecuteEvent(int const nEventID, int const spriteNum, int const playerNum); int32_t VM_ExecuteEventWithValue(int const nEventID, int const spriteNum, int const playerNum, int32_t const nReturn); -static FORCE_INLINE bool VM_HaveEvent(int const nEventID) +static FORCE_INLINE int VM_HaveEvent(int const nEventID) { return !!apScriptEvents[nEventID]; } diff --git a/source/duke3d/src/gamevars.h b/source/duke3d/src/gamevars.h index 9cc9717fd..2f3362585 100644 --- a/source/duke3d/src/gamevars.h +++ b/source/duke3d/src/gamevars.h @@ -245,7 +245,7 @@ static FORCE_INLINE void __fastcall Gv_DivVar(int const id, int32_t const operan (var.flags & GAMEVAR_PERACTOR && (unsigned) vm.spriteNum > MAXSPRITES - 1))) return; - bool const foundInTable = (unsigned) operand < DIVTABLESIZE; + int const foundInTable = (unsigned) operand < DIVTABLESIZE; static libdivide::libdivide_s32_t sdiv; intptr_t *iptr = &var.global; static int32_t lastValue; From 441b0460aa97e7847f256ef49b0404dc6f6de49b Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:50:01 +0000 Subject: [PATCH 155/203] Map SDL joystick device trackball input to mouse input git-svn-id: https://svn.eduke32.com/eduke32@8367 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # source/build/src/sdlayer.cpp --- source/build/include/baselayer.h | 1 + source/build/src/sdlayer.cpp | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 53b93b5d6..851b7289e 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -116,6 +116,7 @@ typedef struct void (*pCallback)(int32_t, int32_t); int32_t bits; int32_t numAxes; + int32_t numBalls; int32_t numButtons; int32_t numHats; int32_t isGameController; diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index 112bd5193..9cc9992d9 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -748,8 +748,10 @@ void joyScanDevices() buildprintf("Using controller %s\n", SDL_GameControllerName(controller)); joystick.numAxes = SDL_CONTROLLER_AXIS_MAX; + joystick.numBalls = 0; joystick.numButtons = SDL_CONTROLLER_BUTTON_MAX; joystick.numHats = 0; + joystick.isGameController = 1; Xfree(joystick.pAxis); @@ -772,11 +774,15 @@ void joyScanDevices() // KEEPINSYNC duke3d/src/gamedefs.h, mact/include/_control.h joystick.numAxes = min(9, SDL_JoystickNumAxes(joydev)); + joystick.numBalls = SDL_JoystickNumBalls(joydev); joystick.numButtons = min(32, SDL_JoystickNumButtons(joydev)); - joystick.numHats = min((36-joystick.numButtons)/4,SDL_JoystickNumHats(joydev)); + joystick.numHats = min((36 - joystick.numButtons) / 4, SDL_JoystickNumHats(joydev)); + joystick.isGameController = 0; - initprintf("Joystick %d has %d axes, %d buttons, and %d hat(s).\n", i+1, joystick.numAxes, joystick.numButtons, joystick.numHats); + buildprint("Joystick ", i+1, " has ", joystick.numAxes, " axes, ", joystick.numButtons, " buttons, ", + (joystick.numHats ? std::to_string(joystick.numHats).c_str() : "no"), " hats, and ", + (joystick.numBalls ? std::to_string(joystick.numBalls).c_str() : "no"), " balls.\n"); Xfree(joystick.pAxis); joystick.pAxis = (int32_t *)Xcalloc(joystick.numAxes, sizeof(int32_t)); @@ -1659,6 +1665,7 @@ int32_t handleevents_sdlcommon(SDL_Event *ev) switch (ev->type) { case SDL_MOUSEMOTION: + //case SDL_JOYBALLMOTION: { // The menus need this, even in non GUI-capture mode event_t event; From cf0a74a888aedc350d6fe005438cd60c6bb2f46c Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:50:04 +0000 Subject: [PATCH 156/203] Fix noclip in Duke3d git-svn-id: https://svn.eduke32.com/eduke32@8368 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/duke3d/src/player.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/duke3d/src/player.cpp b/source/duke3d/src/player.cpp index 0b9aabd79..7499f6aba 100644 --- a/source/duke3d/src/player.cpp +++ b/source/duke3d/src/player.cpp @@ -4891,7 +4891,9 @@ void P_ProcessInput(int playerNum) pPlayer->oq16ang = pPlayer->q16ang; updatesector(pPlayer->pos.x, pPlayer->pos.y, &pPlayer->cursectnum); - pushmove(&pPlayer->pos, &pPlayer->cursectnum, pPlayer->clipdist - 1, (4L<<8), stepHeight, CLIPMASK0); + + if (!ud.noclip) + pushmove(&pPlayer->pos, &pPlayer->cursectnum, pPlayer->clipdist - 1, (4L<<8), stepHeight, CLIPMASK0); if (pPlayer->one_eighty_count < 0) { From c851da92a6a38013cb7680fd5e4c19cbdd26d901 Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:50:08 +0000 Subject: [PATCH 157/203] Improve interaction between cheat entry and player input git-svn-id: https://svn.eduke32.com/eduke32@8369 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # source/duke3d/src/cheats.cpp # source/duke3d/src/player.cpp --- source/duke3d/src/cheats.cpp | 33 ++++++++++++++++++--------------- source/duke3d/src/cheats.h | 5 +++-- source/duke3d/src/player.cpp | 21 ++++++++++++--------- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/source/duke3d/src/cheats.cpp b/source/duke3d/src/cheats.cpp index 5320822de..ec63b3bfa 100644 --- a/source/duke3d/src/cheats.cpp +++ b/source/duke3d/src/cheats.cpp @@ -22,9 +22,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "ns.h" // Must come before everything else! +#include "cheats.h" + #include "duke3d.h" #include "osdcmds.h" -#include "cheats.h" BEGIN_DUKE_NS @@ -242,10 +243,12 @@ static void G_CheatGetInv(DukePlayer_t *pPlayer) static void end_cheat(DukePlayer_t * const pPlayer) { pPlayer->cheat_phase = 0; + g_cheatBufLen = 0; inputState.keyFlushChars(); + KB_ClearKeysDown(); } -static int32_t cheatbuflen; +int g_cheatBufLen; static int8_t cheatbuf[MAXCHEATLEN]; void G_DoCheats(void) @@ -311,31 +314,33 @@ void G_DoCheats(void) if (!((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'))) { pPlayer->cheat_phase = 0; + g_cheatBufLen = 0; // P_DoQuote(QUOTE_46,pPlayer); return; } - cheatbuf[cheatbuflen++] = (int8_t) ch; + cheatbuf[g_cheatBufLen++] = (int8_t) ch; // This assertion is not obvious, but it should hold because of the // cheat string matching logic below. - Bassert(cheatbuflen < (signed)sizeof(cheatbuf)); - cheatbuf[cheatbuflen] = 0; + Bassert(g_cheatBufLen < (signed)sizeof(cheatbuf)); + cheatbuf[g_cheatBufLen] = 0; // inputState.ClearKeysDown(); for (cheatNum=0; cheatNum < NUMCHEATCODES; cheatNum++) { - for (bssize_t j = 0; j= '0' && ch <= '9')) { if (CheatStrings[cheatNum][j+1] == 0) goto FOUNDCHEAT; - if (j == cheatbuflen-1) return; + if (j == g_cheatBufLen-1) return; } else break; } } pPlayer->cheat_phase = 0; + g_cheatBufLen = 0; return; FOUNDCHEAT:; @@ -458,8 +463,7 @@ void G_DoCheats(void) case CHEAT_ALLEN: P_DoQuote(QUOTE_CHEAT_ALLEN, pPlayer); - pPlayer->cheat_phase = 0; - inputState.ClearKeyStatus(sc_N); + end_cheat(pPlayer); return; case CHEAT_CORNHOLIO: @@ -622,8 +626,7 @@ void G_DoCheats(void) case CHEAT_CASHMAN: ud.cashman = 1-ud.cashman; - inputState.ClearKeyStatus(sc_N); - pPlayer->cheat_phase = 0; + end_cheat(pPlayer); return; case CHEAT_ITEMS: @@ -666,7 +669,6 @@ void G_DoCheats(void) case CHEAT_BETA: P_DoQuote(QUOTE_CHEAT_BETA, pPlayer); - inputState.ClearKeyStatus(sc_H); end_cheat(pPlayer); return; @@ -695,8 +697,8 @@ void G_DoCheats(void) case CHEAT_RESERVED3: ud.eog = 1; pPlayer->player_par = 0; - pPlayer->gm |= MODE_EOL; - inputState.keyFlushChars(); + pPlayer->gm |= MODE_EOL;; + end_cheat(pPlayer); return; default: @@ -731,13 +733,14 @@ void G_DoCheats(void) { pPlayer->cheat_phase = 1; // P_DoQuote(QUOTE_25,pPlayer); - cheatbuflen = 0; } + g_cheatBufLen = 0; inputState.keyFlushChars(); } else if (pPlayer->cheat_phase != 0) { pPlayer->cheat_phase = 0; + g_cheatBufLen = 0; inputState.ClearKeyStatus((uint8_t) CheatKeys[0]); inputState.ClearKeyStatus((uint8_t) CheatKeys[1]); } diff --git a/source/duke3d/src/cheats.h b/source/duke3d/src/cheats.h index 385aa1c51..aec829785 100644 --- a/source/duke3d/src/cheats.h +++ b/source/duke3d/src/cheats.h @@ -28,8 +28,9 @@ BEGIN_DUKE_NS #define MAXCHEATDESC 64 #define NUMCHEATCODES (int32_t) ARRAY_SIZE(CheatStrings) -extern void G_DoCheats(void); -extern void G_SetupCheats(void); +void G_DoCheats(void); +void G_SetupCheats(void); +extern int g_cheatBufLen; enum cheatindex_t { diff --git a/source/duke3d/src/player.cpp b/source/duke3d/src/player.cpp index 7499f6aba..70f7ded60 100644 --- a/source/duke3d/src/player.cpp +++ b/source/duke3d/src/player.cpp @@ -2894,7 +2894,7 @@ void P_GetInput(int const playerNum) auto const pPlayer = g_player[playerNum].ps; ControlInfo info; - if ((pPlayer->gm & (MODE_MENU|MODE_TYPE)) || (ud.pause_on && !inputState.GetKeyStatus(sc_Pause))) + if (g_cheatBufLen > 1 || (pPlayer->gm & (MODE_MENU|MODE_TYPE)) || (ud.pause_on && !inputState.GetKeyStatus(sc_Pause))) { if (!(pPlayer->gm&MODE_MENU)) CONTROL_GetInput(&info); @@ -3024,20 +3024,23 @@ void P_GetInput(int const playerNum) int const sectorLotag = pPlayer->cursectnum != -1 ? sector[pPlayer->cursectnum].lotag : 0; int const crouchable = sectorLotag != 2 && (sectorLotag != 1 || pPlayer->spritebridge); - if (pPlayer->cheat_phase == 0 && buttonMap.ButtonDown(gamefunc_Toggle_Crouch)) + if (pPlayer->cheat_phase < 1) { - pPlayer->crouch_toggle = !pPlayer->crouch_toggle && crouchable; + if (buttonMap.ButtonDown(gamefunc_Toggle_Crouch)) + { + pPlayer->crouch_toggle = !pPlayer->crouch_toggle && crouchable; - if (crouchable) - buttonMap.ClearButton(gamefunc_Toggle_Crouch); + if (crouchable) + buttonMap.ClearButton(gamefunc_Toggle_Crouch); } - if (buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Jump) || pPlayer->jetpack_on || (!crouchable && pPlayer->on_ground)) - pPlayer->crouch_toggle = 0; + if (buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Jump) || pPlayer->jetpack_on || (!crouchable && pPlayer->on_ground)) + pPlayer->crouch_toggle = 0; - int const crouching = buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Toggle_Crouch) || pPlayer->crouch_toggle; + int const crouching = buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Toggle_Crouch) || pPlayer->crouch_toggle; - localInput.bits |= (buttonMap.ButtonDown(gamefunc_Jump) << SK_JUMP) | (crouching << SK_CROUCH); + localInput.bits |= (buttonMap.ButtonDown(gamefunc_Jump) << SK_JUMP) | (crouching << SK_CROUCH); + } localInput.bits |= (buttonMap.ButtonDown(gamefunc_Aim_Up) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && input.fvel > 0)) << SK_AIM_UP; localInput.bits |= (buttonMap.ButtonDown(gamefunc_Aim_Down) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && input.fvel < 0)) << SK_AIM_DOWN; From 15b76f2041ec7cd457503b76619eb75dd80b6567 Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:50:16 +0000 Subject: [PATCH 158/203] Add Xaligned_calloc() git-svn-id: https://svn.eduke32.com/eduke32@8371 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # source/build/include/compat.h --- source/build/include/compat.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source/build/include/compat.h b/source/build/include/compat.h index 2bcbbf5a3..e8303da8e 100644 --- a/source/build/include/compat.h +++ b/source/build/include/compat.h @@ -1243,8 +1243,21 @@ static FORCE_INLINE void *xaligned_alloc(const bsize_t alignment, const bsize_t void *ptr = Baligned_alloc(alignment, size); return (EDUKE32_PREDICT_TRUE(ptr != NULL)) ? ptr : handle_memerr(ptr); } + +static FORCE_INLINE void *xaligned_calloc(const bsize_t alignment, const bsize_t count, const bsize_t size) +{ + bsize_t const blocksize = count * size; + void *ptr = Baligned_alloc(alignment, blocksize); + if (EDUKE32_PREDICT_TRUE(ptr != NULL)) + { + Bmemset(ptr, 0, blocksize); + return ptr; + } + return handle_memerr(ptr); +} #else # define xaligned_alloc(alignment, size) xmalloc(size) +# define xaligned_calloc(alignment, count, size) xcalloc(count, size) #endif #ifdef DEBUGGINGAIDS @@ -1258,6 +1271,7 @@ static FORCE_INLINE void *xaligned_alloc(const bsize_t alignment, const bsize_t #define Xcalloc(nmemb, size) (EDUKE32_PRE_XALLOC xcalloc(nmemb, size)) #define Xrealloc(ptr, size) (EDUKE32_PRE_XALLOC xrealloc(ptr, size)) #define Xaligned_alloc(alignment, size) (EDUKE32_PRE_XALLOC xaligned_alloc(alignment, size)) +#define Xaligned_calloc(alignment, count, size) (EDUKE32_PRE_XALLOC xaligned_calloc(alignment, count, size)) #define Xfree(ptr) (EDUKE32_PRE_XALLOC xfree(ptr)) #define Xaligned_free(ptr) (EDUKE32_PRE_XALLOC xaligned_free(ptr)) From 0af13dcde0984db14df2414bbfcd5c260634eda1 Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:50:20 +0000 Subject: [PATCH 159/203] Minor changes to hash table code git-svn-id: https://svn.eduke32.com/eduke32@8372 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # source/build/include/hash.h --- source/build/include/hash.h | 33 ++++--- source/build/src/hash.cpp | 170 +++++++++++------------------------- 2 files changed, 69 insertions(+), 134 deletions(-) diff --git a/source/build/include/hash.h b/source/build/include/hash.h index 2aac80399..ec8855036 100644 --- a/source/build/include/hash.h +++ b/source/build/include/hash.h @@ -5,12 +5,13 @@ #define hash_h_ // Hash functions +#define DJB_MAGIC 5381u -typedef struct hashitem_ // size is 12/24 bytes. +typedef struct hashitem // size is 12/24 bytes. { char *string; intptr_t key; - struct hashitem_ *next; + struct hashitem *next; } hashitem_t; typedef struct @@ -22,8 +23,8 @@ typedef struct // djb3 algorithm static inline uint32_t hash_getcode(const char *s) { - uint32_t h = 5381; - int32_t ch; + uint32_t h = DJB_MAGIC; + char ch; while ((ch = Btolower(*s++)) != '\0') h = ((h << 5) + h) ^ ch; @@ -32,49 +33,53 @@ static inline uint32_t hash_getcode(const char *s) } void hash_init(hashtable_t *t); -void hash_loop(hashtable_t *t, void(*func)(const char *, intptr_t)); +void hash_loop(hashtable_t *t, void (*func)(const char *, intptr_t)); void hash_free(hashtable_t *t); -intptr_t hash_findcase(hashtable_t const * t, char const * s); -intptr_t hash_find(hashtable_t const * t, char const * s); void hash_add(hashtable_t *t, const char *s, intptr_t key, int32_t replace); void hash_delete(hashtable_t *t, const char *s); +intptr_t hash_findcase(hashtable_t const *t, char const *s); +intptr_t hash_find(hashtable_t const *t, char const *s); // Hash functions // modified for raw binary keys and one big allocation, and maximum find() performance -typedef struct inthashitem_ +typedef struct inthashitem { intptr_t key; intptr_t value; - struct inthashitem_ *collision; // use NULL to signify empty and pointer identity to signify end of linked list + struct inthashitem *collision; // use NULL to signify empty and pointer identity to signify end of linked list } inthashitem_t; typedef struct { - inthashitem_t * items; + inthashitem_t *items; uint32_t count; } inthashtable_t; // djb3 algorithm static inline uint32_t inthash_getcode(intptr_t key) { - uint32_t h = 5381; + uint32_t h = DJB_MAGIC; - for (uint8_t const * keybuf = (uint8_t *) &key, *const keybuf_end = keybuf + sizeof(intptr_t); keybuf < keybuf_end; ++keybuf) + for (auto keybuf = (uint8_t const *) &key, keybuf_end = keybuf + sizeof(key); keybuf < keybuf_end; ++keybuf) h = ((h << 5) + h) ^ (uint32_t) *keybuf; return h; } void inthash_init(inthashtable_t *t); -void inthash_loop(inthashtable_t const *t, void(*func)(intptr_t, intptr_t)); +void inthash_loop(inthashtable_t const *t, void (*func)(intptr_t, intptr_t)); void inthash_free(inthashtable_t *t); -intptr_t inthash_find(inthashtable_t const *t, intptr_t key); void inthash_add(inthashtable_t *t, intptr_t key, intptr_t value, int32_t replace); void inthash_delete(inthashtable_t *t, intptr_t key); + +intptr_t inthash_find(inthashtable_t const *t, intptr_t key); + // keep the load factor below 0.75 and make sure the size is odd // ideally we would find the next largest prime number #define INTHASH_SIZE(size) ((size * 4u / 3u) | 1u) #endif + +#endif // hash_h_ diff --git a/source/build/src/hash.cpp b/source/build/src/hash.cpp index 6b2b804fc..7614a6e8e 100644 --- a/source/build/src/hash.cpp +++ b/source/build/src/hash.cpp @@ -6,69 +6,63 @@ void hash_init(hashtable_t *t) { hash_free(t); - t->items=(hashitem_t **) Xcalloc(1, t->size * sizeof(hashitem_t)); + t->items = (hashitem_t **) Xaligned_calloc(16, t->size, sizeof(hashitem_t)); } void hash_loop(hashtable_t *t, void(*func)(const char *, intptr_t)) { - if (t->items == NULL) + if (t->items == nullptr) return; - for (bssize_t i=0; i < t->size; i++) - for (hashitem_t *item=t->items[i]; item != NULL; item = item->next) + for (native_t i=0; i < t->size; i++) + for (auto item = t->items[i]; item != nullptr; item = item->next) func(item->string, item->key); } void hash_free(hashtable_t *t) { - if (t == NULL || t->items == NULL) + if (t->items == nullptr) return; int remaining = t->size - 1; do { - hashitem_t *cur = t->items[remaining]; + auto cur = t->items[remaining]; while (cur) { - hashitem_t * const tmp = cur; + auto tmp = cur; cur = cur->next; Xfree(tmp->string); - Xfree(tmp); + Xaligned_free(tmp); } } while (--remaining >= 0); - DO_FREE_AND_NULL(t->items); + ALIGNED_FREE_AND_NULL(t->items); } void hash_add(hashtable_t *t, const char *s, intptr_t key, int32_t replace) { #ifdef DEBUGGINGAIDS - Bassert(t->items != NULL); -#else - if (EDUKE32_PREDICT_FALSE(t->items == NULL)) - { - initprintf("hash_add(): table not initialized!\n"); - return; - } + Bassert(t->items != nullptr); #endif - - uint32_t code = hash_getcode(s) % t->size; - hashitem_t *cur = t->items[code]; + uint32_t const code = hash_getcode(s) % t->size; + auto cur = t->items[code]; if (!cur) { - cur = (hashitem_t *) Xcalloc(1, sizeof(hashitem_t)); + cur = (hashitem_t *) Xaligned_alloc(16, sizeof(hashitem_t)); cur->string = Xstrdup(s); - cur->key = key; - cur->next = NULL; + cur->key = key; + cur->next = nullptr; + t->items[code] = cur; return; } - hashitem_t *prev = NULL; + hashitem_t *prev = nullptr; do { @@ -80,10 +74,11 @@ void hash_add(hashtable_t *t, const char *s, intptr_t key, int32_t replace) prev = cur; } while ((cur = cur->next)); - cur = (hashitem_t *) Xcalloc(1, sizeof(hashitem_t)); + cur = (hashitem_t *) Xaligned_alloc(16, sizeof(hashitem_t)); cur->string = Xstrdup(s); - cur->key = key; - cur->next = NULL; + cur->key = key; + cur->next = nullptr; + prev->next = cur; } @@ -91,22 +86,15 @@ void hash_add(hashtable_t *t, const char *s, intptr_t key, int32_t replace) void hash_delete(hashtable_t *t, const char *s) { #ifdef DEBUGGINGAIDS - Bassert(t->items != NULL); -#else - if (t->items == NULL) - { - initprintf("hash_delete(): table not initialized!\n"); - return; - } + Bassert(t->items != nullptr); #endif - - uint32_t code = hash_getcode(s) % t->size; - hashitem_t *cur = t->items[code]; + uint32_t const code = hash_getcode(s) % t->size; + auto cur = t->items[code]; if (!cur) return; - hashitem_t *prev = NULL; + hashitem_t *prev = nullptr; do { @@ -119,7 +107,7 @@ void hash_delete(hashtable_t *t, const char *s) else prev->next = cur->next; - Xfree(cur); + Xaligned_free(cur); break; } @@ -130,16 +118,9 @@ void hash_delete(hashtable_t *t, const char *s) intptr_t hash_find(const hashtable_t * const t, char const * const s) { #ifdef DEBUGGINGAIDS - Bassert(t->items != NULL); -#else - if (t->items == NULL) - { - initprintf("hash_find(): table not initialized!\n"); - return -1; - } + Bassert(t->items != nullptr); #endif - - hashitem_t *cur = t->items[hash_getcode(s) % t->size]; + auto cur = t->items[hash_getcode(s) % t->size]; if (!cur) return -1; @@ -155,16 +136,9 @@ intptr_t hash_find(const hashtable_t * const t, char const * const s) intptr_t hash_findcase(const hashtable_t * const t, char const * const s) { #ifdef DEBUGGINGAIDS - Bassert(t->items != NULL); -#else - if (t->items == NULL) - { - initprintf("hash_findcase(): table not initialized!\n"); - return -1; - } + Bassert(t->items != nullptr); #endif - - hashitem_t *cur = t->items[hash_getcode(s) % t->size]; + auto cur = t->items[hash_getcode(s) % t->size]; if (!cur) return -1; @@ -178,60 +152,36 @@ intptr_t hash_findcase(const hashtable_t * const t, char const * const s) } +void inthash_free(inthashtable_t *t) { ALIGNED_FREE_AND_NULL(t->items); } + void inthash_init(inthashtable_t *t) { - if (EDUKE32_PREDICT_FALSE(!t->count)) - { - initputs("inthash_add(): count is zero!\n"); - return; - } - inthash_free(t); - - t->items = (inthashitem_t *) Xcalloc(t->count, sizeof(inthashitem_t)); + t->items = (inthashitem_t *) Xaligned_calloc(16, t->count, sizeof(inthashitem_t)); } void inthash_loop(inthashtable_t const *t, void(*func)(intptr_t, intptr_t)) { -#ifdef DEBUGGINGAIDS - Bassert(t->items != NULL); -#else - if (EDUKE32_PREDICT_FALSE(t->items == NULL)) - { - initputs("inthash_loop(): table not initialized!\n"); + if (t->items == nullptr) return; - } -#endif - for (inthashitem_t const * item = t->items, *const items_end = t->items + t->count; item < items_end; ++item) + for (auto *item = t->items, *const items_end = t->items + t->count; item < items_end; ++item) func(item->key, item->value); } -void inthash_free(inthashtable_t *t) -{ - DO_FREE_AND_NULL(t->items); -} void inthash_add(inthashtable_t *t, intptr_t key, intptr_t value, int32_t replace) { #ifdef DEBUGGINGAIDS - Bassert(t->items != NULL); -#else - if (EDUKE32_PREDICT_FALSE(t->items == NULL)) - { - initputs("inthash_add(): table not initialized!\n"); - return; - } + Bassert(t->items != nullptr); #endif + auto seeker = t->items + inthash_getcode(key) % t->count; - inthashitem_t * seeker = t->items + inthash_getcode(key) % t->count; - - if (seeker->collision == NULL) + if (seeker->collision == nullptr) { seeker->key = key; seeker->value = value; seeker->collision = seeker; - return; } @@ -254,17 +204,14 @@ void inthash_add(inthashtable_t *t, intptr_t key, intptr_t value, int32_t replac } } - inthashitem_t *tail = seeker; + auto tail = seeker; do tail = t->items + (tail - t->items + 1) % t->count; - while (tail->collision != NULL && tail != seeker); + while (tail->collision != nullptr && tail != seeker); if (EDUKE32_PREDICT_FALSE(tail == seeker)) - { - initputs("inthash_add(): table full!\n"); - return; - } + fatal_exit("inthash_add(): table full!\n"); tail->key = key; tail->value = value; @@ -275,35 +222,25 @@ void inthash_add(inthashtable_t *t, intptr_t key, intptr_t value, int32_t replac void inthash_delete(inthashtable_t *t, intptr_t key) { #ifdef DEBUGGINGAIDS - Bassert(t->items != NULL); -#else - if (EDUKE32_PREDICT_FALSE(t->items == NULL)) - { - initputs("inthash_delete(): table not initialized!\n"); - return; - } + Bassert(t->items != nullptr); #endif + auto seeker = t->items + inthash_getcode(key) % t->count; - inthashitem_t * seeker = t->items + inthash_getcode(key) % t->count; - - if (seeker->collision == NULL) - return; - - if (seeker->key == key) + if (seeker->collision == nullptr || seeker->key == key) { - seeker->collision = NULL; + seeker->collision = nullptr; return; } while (seeker != seeker->collision) { - inthashitem_t * const prev = seeker; + auto prev = seeker; seeker = seeker->collision; if (seeker->key == key) { prev->collision = seeker == seeker->collision ? prev : seeker->collision; - seeker->collision = NULL; + seeker->collision = nullptr; return; } } @@ -312,18 +249,11 @@ void inthash_delete(inthashtable_t *t, intptr_t key) intptr_t inthash_find(inthashtable_t const *t, intptr_t key) { #ifdef DEBUGGINGAIDS - Bassert(t->items != NULL); -#else - if (EDUKE32_PREDICT_FALSE(t->items == NULL)) - { - initputs("inthash_find(): table not initialized!\n"); - return -1; - } + Bassert(t->items != nullptr); #endif + auto seeker = t->items + inthash_getcode(key) % t->count; - inthashitem_t const * seeker = t->items + inthash_getcode(key) % t->count; - - if (seeker->collision == NULL) + if (seeker->collision == nullptr) return -1; if (seeker->key == key) From fd1656fbf27d6142365cb04aee762e85ff67ce9c Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:50:27 +0000 Subject: [PATCH 160/203] Move atoi_safe() from editor.h to compat.h and #define Batoi atoi_safe They were the same thing so they might as well be in the same place. git-svn-id: https://svn.eduke32.com/eduke32@8374 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # source/build/include/editor.h --- source/build/include/compat.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/build/include/compat.h b/source/build/include/compat.h index e8303da8e..d17ac36ad 100644 --- a/source/build/include/compat.h +++ b/source/build/include/compat.h @@ -568,7 +568,10 @@ typedef FILE BFILE; // parsing the decimal representation of 0xffffffff, // 4294967295 -- long is signed, so strtol would // return LONG_MAX (== 0x7fffffff on 32-bit archs)) -#define Batoi(str) ((int32_t)strtol(str, NULL, 10)) + +static FORCE_INLINE int32_t atoi_safe(const char *str) { return (int32_t)Bstrtol(str, NULL, 10); } + +#define Batoi(x) atoi_safe(x) #define Batol(str) (strtol(str, NULL, 10)) #define Batof(str) (strtod(str, NULL)) From 9146dc9a89798498784bfac1c7ac47203f2369f0 Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:50:30 +0000 Subject: [PATCH 161/203] Remove duplicate call to cacheAllSounds() from S_SoundStartup() git-svn-id: https://svn.eduke32.com/eduke32@8375 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # source/duke3d/src/sounds.cpp --- source/duke3d/src/sounds.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/duke3d/src/sounds.cpp b/source/duke3d/src/sounds.cpp index afab7f808..f52c48e23 100644 --- a/source/duke3d/src/sounds.cpp +++ b/source/duke3d/src/sounds.cpp @@ -85,8 +85,6 @@ void S_SoundStartup(void) } } - cacheAllSounds(); - snd_fxvolume.Callback(); snd_reversestereo.Callback(); From 949d2f311ea5e3276cb7cf0f0ac0d10eb96fe8af Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:51:32 +0000 Subject: [PATCH 162/203] Remove driver_nosound from audiolib Why? Because it's fucking useless. If we want to waste CPU on outputting nothing, SDL has us covered with its "dummy" audio backend. git-svn-id: https://svn.eduke32.com/eduke32@8387 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # GNUmakefile # platform/Windows/audiolib.vcxproj # platform/Windows/audiolib.vcxproj.filters # source/audiolib/src/driver_nosound.cpp # source/audiolib/src/driver_nosound.h # source/audiolib/src/drivers.cpp --- source/CMakeLists.txt | 1 - source/audiolib/include/sndcards.h | 1 - source/audiolib/src/driver_nosound.cpp | 83 -------------------------- source/audiolib/src/driver_nosound.h | 43 ------------- source/audiolib/src/drivers.cpp | 1 - source/audiolib/src/fx_man.cpp | 6 +- 6 files changed, 2 insertions(+), 133 deletions(-) delete mode 100644 source/audiolib/src/driver_nosound.cpp delete mode 100644 source/audiolib/src/driver_nosound.h diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 37806cc21..676b71140 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -668,7 +668,6 @@ set (PCH_SOURCES audiolib/src/drivers.cpp audiolib/src/driver_adlib.cpp - audiolib/src/driver_nosound.cpp audiolib/src/driver_sdl.cpp audiolib/src/driver_winmm.cpp audiolib/src/formats.cpp diff --git a/source/audiolib/include/sndcards.h b/source/audiolib/include/sndcards.h index bc6acffd7..b272480c7 100644 --- a/source/audiolib/include/sndcards.h +++ b/source/audiolib/include/sndcards.h @@ -33,7 +33,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. typedef enum { - ASS_NoSound, ASS_SDL, ASS_DirectSound, ASS_OPL3, diff --git a/source/audiolib/src/driver_nosound.cpp b/source/audiolib/src/driver_nosound.cpp deleted file mode 100644 index fc7a786e8..000000000 --- a/source/audiolib/src/driver_nosound.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program 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 2 - of the License, or (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - */ - -/** - * Stub driver for no output - */ - -#include "compat.h" -#include "midifuncs.h" - -int NoSoundDrv_GetError(void) { return 0; } - -const char *NoSoundDrv_ErrorString(int ErrorNumber) -{ - UNREFERENCED_PARAMETER(ErrorNumber); - return "No sound, Ok."; -} - -int NoSoundDrv_PCM_Init(int *mixrate, int *numchannels, void *initdata) -{ - UNREFERENCED_PARAMETER(mixrate); - UNREFERENCED_PARAMETER(numchannels); - UNREFERENCED_PARAMETER(initdata); - return 0; -} - -void NoSoundDrv_PCM_Shutdown(void) {} - -int NoSoundDrv_PCM_BeginPlayback(char *BufferStart, int BufferSize, int NumDivisions, void (*CallBackFunc)(void)) -{ - UNREFERENCED_PARAMETER(BufferStart); - UNREFERENCED_PARAMETER(BufferSize); - UNREFERENCED_PARAMETER(NumDivisions); - UNREFERENCED_PARAMETER(CallBackFunc); - return 0; -} - -void NoSoundDrv_PCM_StopPlayback(void) {} -void NoSoundDrv_PCM_Lock(void) {} -void NoSoundDrv_PCM_Unlock(void) {} - -int NoSoundDrv_MIDI_Init(midifuncs *funcs) -{ - Bmemset(funcs, 0, sizeof(midifuncs)); - return 0; -} - -void NoSoundDrv_MIDI_Shutdown(void) {} - -int NoSoundDrv_MIDI_StartPlayback(void (*service)(void)) -{ - UNREFERENCED_PARAMETER(service); - return 0; -} - -void NoSoundDrv_MIDI_HaltPlayback(void) {} -uint32_t NoSoundDrv_MIDI_GetTick(void) { return 0; } - -void NoSoundDrv_MIDI_SetTempo(int tempo, int division) -{ - UNREFERENCED_PARAMETER(tempo); - UNREFERENCED_PARAMETER(division); -} - -void NoSoundDrv_MIDI_Lock(void) {} -void NoSoundDrv_MIDI_Unlock(void) {} diff --git a/source/audiolib/src/driver_nosound.h b/source/audiolib/src/driver_nosound.h deleted file mode 100644 index 9d0f7496b..000000000 --- a/source/audiolib/src/driver_nosound.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program 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 2 - of the License, or (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - */ - -#include "midifuncs.h" - -#include - -int NoSoundDrv_GetError(void); -const char *NoSoundDrv_ErrorString( int ErrorNumber ); - -int NoSoundDrv_PCM_Init(int * mixrate, int * numchannels, void * initdata); -void NoSoundDrv_PCM_Shutdown(void); -int NoSoundDrv_PCM_BeginPlayback(char *BufferStart, int BufferSize, - int NumDivisions, void ( *CallBackFunc )( void ) ); -void NoSoundDrv_PCM_StopPlayback(void); -void NoSoundDrv_PCM_Lock(void); -void NoSoundDrv_PCM_Unlock(void); - -int NoSoundDrv_MIDI_Init(midifuncs *); -void NoSoundDrv_MIDI_Shutdown(void); -int NoSoundDrv_MIDI_StartPlayback(void (*service)(void)); -void NoSoundDrv_MIDI_HaltPlayback(void); -uint32_t NoSoundDrv_MIDI_GetTick(void); -void NoSoundDrv_MIDI_SetTempo(int tempo, int division); -void NoSoundDrv_MIDI_Lock(void); -void NoSoundDrv_MIDI_Unlock(void); \ No newline at end of file diff --git a/source/audiolib/src/drivers.cpp b/source/audiolib/src/drivers.cpp index d33da4c5c..114c3dd27 100644 --- a/source/audiolib/src/drivers.cpp +++ b/source/audiolib/src/drivers.cpp @@ -25,7 +25,6 @@ #include "drivers.h" -#include "driver_nosound.h" #include "driver_adlib.h" #ifdef RENDERTYPESDL diff --git a/source/audiolib/src/fx_man.cpp b/source/audiolib/src/fx_man.cpp index 2d3d10799..28154ee31 100644 --- a/source/audiolib/src/fx_man.cpp +++ b/source/audiolib/src/fx_man.cpp @@ -62,8 +62,6 @@ int FX_Init(int numvoices, int numchannels, int mixrate, void *initdata) SoundCard = ASS_SDL; #elif defined RENDERTYPEWIN SoundCard = ASS_DirectSound; -#else - SoundCard = ASS_NoSound; #endif } @@ -76,8 +74,8 @@ int FX_Init(int numvoices, int numchannels, int mixrate, void *initdata) if (SoundDriver_IsPCMSupported(SoundCard) == 0) { // unsupported cards fall back to no sound - MV_Printf("Couldn't init %s, falling back to no sound...\n", SoundDriver_GetName(SoundCard)); - SoundCard = ASS_NoSound; + FX_SetErrorCode(FX_InvalidCard); + return FX_Error; } int status = FX_Ok; From a2fd43da2fdde6e947d2c0bb5cd0b5bf05de64a6 Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:52:06 +0000 Subject: [PATCH 163/203] Clean up CON_FOR a little git-svn-id: https://svn.eduke32.com/eduke32@8395 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/duke3d/src/gameexec.cpp | 109 ++++++++++++--------------------- 1 file changed, 38 insertions(+), 71 deletions(-) diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index b05f80dac..6d4b32e12 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -2614,6 +2614,14 @@ GAMEEXEC_STATIC void VM_Execute(int const loop /*= false*/) dispatch(); } +#define CON_FOR_ITERATION() \ + do \ + { \ + Gv_SetVar(returnVar, jj); \ + insptr = pNext; \ + VM_Execute(); \ + } while (0) + vInstruction(CON_FOR): // special-purpose iteration insptr++; { @@ -2631,113 +2639,76 @@ GAMEEXEC_STATIC void VM_Execute(int const loop /*= false*/) { if (sprite[jj].statnum == MAXSTATUS) continue; - - Gv_SetVar(returnVar, jj); - insptr = pNext; - VM_Execute(); + CON_FOR_ITERATION(); } break; + case ITER_ALLSPRITESBYSTAT: for (native_t statNum = 0; statNum < MAXSTATUS; ++statNum) { - for (native_t jj = headspritestat[statNum]; jj >= 0;) - { - int const kk = nextspritestat[jj]; - Gv_SetVar(returnVar, jj); - insptr = pNext; - VM_Execute(); - jj = kk; - } + for (native_t jj = headspritestat[statNum], kk = nextspritestat[jj]; jj >= 0; jj = kk, kk = nextspritestat[jj]) + CON_FOR_ITERATION(); } break; + case ITER_ALLSPRITESBYSECT: for (native_t sectNum = 0; sectNum < numsectors; ++sectNum) { - for (native_t jj = headspritesect[sectNum]; jj >= 0;) - { - int const kk = nextspritesect[jj]; - Gv_SetVar(returnVar, jj); - insptr = pNext; - VM_Execute(); - jj = kk; - } + for (native_t jj = headspritesect[sectNum], kk = nextspritesect[jj]; jj >= 0; jj = kk, kk = nextspritesect[jj]) + CON_FOR_ITERATION(); } break; + case ITER_ALLSECTORS: for (native_t jj = 0; jj < numsectors; ++jj) - { - Gv_SetVar(returnVar, jj); - insptr = pNext; - VM_Execute(); - } + CON_FOR_ITERATION(); break; + case ITER_ALLWALLS: for (native_t jj = 0; jj < numwalls; ++jj) - { - Gv_SetVar(returnVar, jj); - insptr = pNext; - VM_Execute(); - } + CON_FOR_ITERATION(); break; + case ITER_ACTIVELIGHTS: #ifdef POLYMER for (native_t jj = 0; jj < PR_MAXLIGHTS; ++jj) { if (!prlights[jj].flags.active) continue; - - Gv_SetVar(returnVar, jj); - insptr = pNext; - VM_Execute(); + CON_FOR_ITERATION(); } #endif break; case ITER_DRAWNSPRITES: - { - for (native_t ii = 0; ii < spritesortcnt; ii++) - { - Gv_SetVar(returnVar, ii); - insptr = pNext; - VM_Execute(); - } + for (native_t jj = 0; jj < spritesortcnt; jj++) + CON_FOR_ITERATION(); break; - } case ITER_SPRITESOFSECTOR: if ((unsigned)nIndex >= MAXSECTORS) goto badindex; - for (native_t jj = headspritesect[nIndex]; jj >= 0;) - { - int const kk = nextspritesect[jj]; - Gv_SetVar(returnVar, jj); - insptr = pNext; - VM_Execute(); - jj = kk; - } + + for (native_t jj = headspritesect[nIndex], kk = nextspritesect[jj]; jj >= 0; jj = kk, kk = nextspritesect[jj]) + CON_FOR_ITERATION(); break; + case ITER_SPRITESOFSTATUS: if ((unsigned)nIndex >= MAXSTATUS) goto badindex; - for (native_t jj = headspritestat[nIndex]; jj >= 0;) - { - int const kk = nextspritestat[jj]; - Gv_SetVar(returnVar, jj); - insptr = pNext; - VM_Execute(); - jj = kk; - } + + for (native_t jj = headspritestat[nIndex], kk = nextspritestat[jj]; jj >= 0; jj = kk, kk = nextspritestat[jj]) + CON_FOR_ITERATION(); break; + case ITER_WALLSOFSECTOR: if ((unsigned)nIndex >= MAXSECTORS) goto badindex; + for (native_t jj = sector[nIndex].wallptr, endwall = jj + sector[nIndex].wallnum - 1; jj <= endwall; jj++) - { - Gv_SetVar(returnVar, jj); - insptr = pNext; - VM_Execute(); - } + CON_FOR_ITERATION(); break; + case ITER_LOOPOFWALL: if ((unsigned)nIndex >= (unsigned)numwalls) goto badindex; @@ -2745,20 +2716,15 @@ GAMEEXEC_STATIC void VM_Execute(int const loop /*= false*/) int jj = nIndex; do { - Gv_SetVar(returnVar, jj); - insptr = pNext; - VM_Execute(); + CON_FOR_ITERATION(); jj = wall[jj].point2; } while (jj != nIndex); } break; + case ITER_RANGE: for (native_t jj = 0; jj < nIndex; jj++) - { - Gv_SetVar(returnVar, jj); - insptr = pNext; - VM_Execute(); - } + CON_FOR_ITERATION(); break; badindex: OSD_Printf(OSD_ERROR "Line %d, for %s: index %d out of range!\n", VM_DECODE_LINE_NUMBER(g_tw), iter_tokens[iterType].token, nIndex); @@ -2768,6 +2734,7 @@ badindex: insptr = pEnd; } dispatch(); +#undef CON_FOR_ITERATION vInstruction(CON_REDEFINEQUOTE): insptr++; From 0b2f550f099f8b57efc462df36a754d926a0ee36 Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:52:10 +0000 Subject: [PATCH 164/203] This change to Gv_DivVar() is faster when benchmarked git-svn-id: https://svn.eduke32.com/eduke32@8396 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/duke3d/src/gamevars.h | 104 ++++++++++++++++------------------- 1 file changed, 48 insertions(+), 56 deletions(-) diff --git a/source/duke3d/src/gamevars.h b/source/duke3d/src/gamevars.h index 2f3362585..c45c194e1 100644 --- a/source/duke3d/src/gamevars.h +++ b/source/duke3d/src/gamevars.h @@ -208,82 +208,74 @@ static FORCE_INLINE void __fastcall VM_SetStruct(uint32_t const flags, intptr_t } } -#define VM_GAMEVAR_OPERATOR(func, operator) \ - static FORCE_INLINE void __fastcall func(int const id, int32_t const operand) \ - { \ - auto &var = aGameVars[id]; \ - \ - switch (var.flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) \ - { \ - default: var.global operator operand; break; \ - case GAMEVAR_PERPLAYER: \ - if (EDUKE32_PREDICT_FALSE((unsigned)vm.playerNum > MAXPLAYERS - 1)) \ - break; \ - var.pValues[vm.playerNum] operator operand; \ - break; \ - case GAMEVAR_PERACTOR: \ - if (EDUKE32_PREDICT_FALSE((unsigned)vm.spriteNum > MAXSPRITES - 1)) \ - break; \ - var.pValues[vm.spriteNum] operator operand; \ - break; \ - case GAMEVAR_INT32PTR: *(int32_t *)var.pValues operator(int32_t) operand; break; \ - case GAMEVAR_INT16PTR: *(int16_t *)var.pValues operator(int16_t) operand; break; \ - case GAMEVAR_Q16PTR: \ - { \ - Fix16 *pfix = (Fix16 *)var.global; \ - *pfix operator fix16_from_int(operand); \ - break; \ - } \ - } \ +#define VM_GAMEVAR_OPERATOR(func, operator) \ + static FORCE_INLINE ATTRIBUTE((flatten)) void __fastcall func(int const id, int32_t const operand) \ + { \ + auto &var = aGameVars[id]; \ + \ + switch (var.flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) \ + { \ + default: \ + var.global operator operand; \ + break; \ + case GAMEVAR_PERPLAYER: \ + var.pValues[vm.playerNum & (MAXPLAYERS-1)] operator operand; \ + break; \ + case GAMEVAR_PERACTOR: \ + var.pValues[vm.spriteNum & (MAXSPRITES-1)] operator operand; \ + break; \ + case GAMEVAR_INT32PTR: *(int32_t *)var.pValues operator(int32_t) operand; break; \ + case GAMEVAR_INT16PTR: *(int16_t *)var.pValues operator(int16_t) operand; break; \ + case GAMEVAR_Q16PTR: \ + { \ + Fix16 *pfix = (Fix16 *)var.global; \ + *pfix operator fix16_from_int(operand); \ + break; \ + } \ + } \ } -static FORCE_INLINE void __fastcall Gv_DivVar(int const id, int32_t const operand) +static FORCE_INLINE void __fastcall Gv_DivVar(int const id, int32_t const d) { - auto &var = aGameVars[id]; + using namespace libdivide; - if (EDUKE32_PREDICT_FALSE((var.flags & GAMEVAR_PERPLAYER && (unsigned) vm.playerNum > MAXPLAYERS - 1) || - (var.flags & GAMEVAR_PERACTOR && (unsigned) vm.spriteNum > MAXSPRITES - 1))) - return; - - int const foundInTable = (unsigned) operand < DIVTABLESIZE; - static libdivide::libdivide_s32_t sdiv; - intptr_t *iptr = &var.global; + static libdivide_s32_t sdiv; static int32_t lastValue; - auto dptr = foundInTable ? (libdivide::libdivide_s32_t *) &divtable32[operand] : &sdiv; - if (operand == lastValue || foundInTable) - goto skip; + auto &var = aGameVars[id]; + auto *dptr = &sdiv; + auto iptr = &var.global; - sdiv = libdivide::libdivide_s32_gen((lastValue = operand)); - -skip: + if ((unsigned)d < DIVTABLESIZE) + dptr = &divtable32[d]; + else if (d != lastValue) + sdiv = libdivide_s32_gen((lastValue = d)); + switch (var.flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) { - case GAMEVAR_PERACTOR: iptr = &var.pValues[vm.spriteNum]; break; - case GAMEVAR_PERPLAYER: iptr = &var.pValues[vm.playerNum]; - default: break; + case GAMEVAR_PERACTOR: iptr = &var.pValues[vm.spriteNum & (MAXSPRITES-1)]; goto jmp; + case GAMEVAR_PERPLAYER: iptr = &var.pValues[vm.playerNum & (MAXPLAYERS-1)]; fallthrough__; + jmp: default: *iptr = libdivide_s32_do(*iptr, dptr); break; case GAMEVAR_INT32PTR: { - int32_t &value = *(int32_t *)var.pValues; - value = (int32_t)libdivide::libdivide_s32_do(value, dptr); - return; + auto &value = *(int32_t *)var.pValues; + value = libdivide_s32_do(value, dptr); + break; } case GAMEVAR_INT16PTR: { - int16_t &value = *(int16_t *)var.pValues; - value = (int16_t)libdivide::libdivide_s32_do(value, dptr); - return; + auto &value = *(int16_t *)var.pValues; + value = (int16_t)libdivide_s32_do(value, dptr); + break; } case GAMEVAR_Q16PTR: { - fix16_t &value = *(fix16_t *)var.pValues; - value = fix16_div(value, fix16_from_int(operand)); - return; + auto &value = *(fix16_t *)var.pValues; + value = fix16_div(value, fix16_from_int(d)); + break; } } - - *iptr = libdivide_s32_do(*iptr, dptr); } VM_GAMEVAR_OPERATOR(Gv_AddVar, +=) From f5e3b4bb5a89dd31d85d475e6d5993d07af80749 Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:52:13 +0000 Subject: [PATCH 165/203] Fix osdcmd_changelevel git-svn-id: https://svn.eduke32.com/eduke32@8397 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/duke3d/src/osdcmds.cpp | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index 3bb926eac..bb9239fd0 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -39,41 +39,29 @@ struct osdcmd_cheatsinfo osdcmd_cheatsinfo_stat = { -1, 0, 0 }; static int osdcmd_changelevel(osdcmdptr_t parm) { - int32_t volume=0,level; - char *p; + int volume = 0; + int level; if (!VOLUMEONE) { if (parm->numparms != 2) return OSDCMD_SHOWHELP; - volume = strtol(parm->parms[0], &p, 10) - 1; - if (p[0]) return OSDCMD_SHOWHELP; - level = strtol(parm->parms[1], &p, 10) - 1; - if (p[0]) return OSDCMD_SHOWHELP; + volume = strtol(parm->parms[0], NULL, 10) - 1; + level = strtol(parm->parms[1], NULL, 10) - 1; } else { if (parm->numparms != 1) return OSDCMD_SHOWHELP; - level = strtol(parm->parms[0], &p, 10) - 1; - if (p[0]) return OSDCMD_SHOWHELP; + level = strtol(parm->parms[0], NULL, 10) - 1; } - if (volume < 0) return OSDCMD_SHOWHELP; - if (level < 0) return OSDCMD_SHOWHELP; + if (volume < 0 || level < 0) + return OSDCMD_SHOWHELP; - if (!VOLUMEONE) + if (level > MAXLEVELS || g_mapInfo[volume * MAXLEVELS + level].filename == NULL) { - if (volume > g_volumeCnt) - { - OSD_Printf("changelevel: invalid volume number (range 1-%d)\n",g_volumeCnt); - return OSDCMD_OK; - } - } - - if (level > MAXLEVELS || g_mapInfo[volume *MAXLEVELS+level].filename == NULL) - { - OSD_Printf("changelevel: invalid level number\n"); + OSD_Printf("changelevel: no map defined for episode %d level %d\n", volume + 1, level + 1); return OSDCMD_SHOWHELP; } @@ -81,6 +69,7 @@ static int osdcmd_changelevel(osdcmdptr_t parm) { return OSDCMD_OK; } + if (g_player[myconnectindex].ps->gm & MODE_GAME) { // in-game behave like a cheat From 694863a8a1dfc06836913367c75bb4cc6011cfe5 Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:52:40 +0000 Subject: [PATCH 166/203] Fix cacheAllSounds() being called before .def parsing... oops! git-svn-id: https://svn.eduke32.com/eduke32@8404 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/duke3d/src/game.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 3a09f1e02..437826802 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -5705,8 +5705,6 @@ static void G_Startup(void) if (TileFiles.artLoadFiles("tiles%03i.art") < 0) G_GameExit("Failed loading art."); - cacheAllSounds(); - // Make the fullscreen nuke logo background non-fullbright. Has to be // after dynamic tile remapping (from C_Compile) and loading tiles. picanm[LOADSCREEN].sf |= PICANM_NOFULLBRIGHT_BIT; @@ -5951,6 +5949,8 @@ int GameInterface::app_main() userConfig.AddDefs.reset(); + cacheAllSounds(); + if (enginePostInit()) G_FatalEngineError(); From 0456d8f36d3c468efddc63c337edfe6145076c01 Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 7 Dec 2019 23:52:54 +0000 Subject: [PATCH 167/203] These shouldn't be references git-svn-id: https://svn.eduke32.com/eduke32@8408 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/duke3d/src/gameexec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index 6d4b32e12..c5f06aaeb 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -168,7 +168,7 @@ static inline void VM_DummySprite(void) } // verification that the event actually exists happens elsewhere -static FORCE_INLINE int32_t VM_EventInlineInternal__(int const &eventNum, int const &spriteNum, int const &playerNum, +static FORCE_INLINE int32_t VM_EventInlineInternal__(int const eventNum, int const spriteNum, int const playerNum, int const playerDist = -1, int32_t returnValue = 0) { vmstate_t const newVMstate = { spriteNum, playerNum, playerDist, 0, From a74797b97c2f6440de6d75ad7fe08b139b3dc5f5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 8 Dec 2019 08:51:54 +0100 Subject: [PATCH 168/203] - fix merge errors. --- source/audiolib/src/drivers.cpp | 21 +-------------------- source/build/include/hash.h | 2 -- source/build/src/hash.cpp | 2 +- source/duke3d/src/cheats.cpp | 1 - 4 files changed, 2 insertions(+), 24 deletions(-) diff --git a/source/audiolib/src/drivers.cpp b/source/audiolib/src/drivers.cpp index 114c3dd27..57d90f12b 100644 --- a/source/audiolib/src/drivers.cpp +++ b/source/audiolib/src/drivers.cpp @@ -66,26 +66,7 @@ static struct { void (*MIDI_Unlock)(void); } SoundDrivers[ASS_NumSoundCards] = { - // Everyone gets the "no sound" driver - { - "null sound device", - NoSoundDrv_GetError, - NoSoundDrv_ErrorString, - NoSoundDrv_PCM_Init, - NoSoundDrv_PCM_Shutdown, - NoSoundDrv_PCM_BeginPlayback, - NoSoundDrv_PCM_StopPlayback, - NoSoundDrv_PCM_Lock, - NoSoundDrv_PCM_Unlock, - NoSoundDrv_MIDI_Init, - NoSoundDrv_MIDI_Shutdown, - NoSoundDrv_MIDI_StartPlayback, - NoSoundDrv_MIDI_HaltPlayback, - NoSoundDrv_MIDI_SetTempo, - NoSoundDrv_MIDI_Lock, - NoSoundDrv_MIDI_Unlock, - }, - + // Simple DirectMedia Layer { "SDL", diff --git a/source/build/include/hash.h b/source/build/include/hash.h index ec8855036..87a050b4b 100644 --- a/source/build/include/hash.h +++ b/source/build/include/hash.h @@ -80,6 +80,4 @@ intptr_t inthash_find(inthashtable_t const *t, intptr_t key); // ideally we would find the next largest prime number #define INTHASH_SIZE(size) ((size * 4u / 3u) | 1u) -#endif - #endif // hash_h_ diff --git a/source/build/src/hash.cpp b/source/build/src/hash.cpp index 7614a6e8e..a7c4db450 100644 --- a/source/build/src/hash.cpp +++ b/source/build/src/hash.cpp @@ -211,7 +211,7 @@ void inthash_add(inthashtable_t *t, intptr_t key, intptr_t value, int32_t replac while (tail->collision != nullptr && tail != seeker); if (EDUKE32_PREDICT_FALSE(tail == seeker)) - fatal_exit("inthash_add(): table full!\n"); + I_Error("inthash_add(): table full!\n"); tail->key = key; tail->value = value; diff --git a/source/duke3d/src/cheats.cpp b/source/duke3d/src/cheats.cpp index ec63b3bfa..7fc529c23 100644 --- a/source/duke3d/src/cheats.cpp +++ b/source/duke3d/src/cheats.cpp @@ -245,7 +245,6 @@ static void end_cheat(DukePlayer_t * const pPlayer) pPlayer->cheat_phase = 0; g_cheatBufLen = 0; inputState.keyFlushChars(); - KB_ClearKeysDown(); } int g_cheatBufLen; From 9f25c9c1178607e2d935c5e6a0be94622af05c08 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Dec 2019 00:33:14 +0100 Subject: [PATCH 169/203] - some string rework * removed temporary placeholder content from string init function. All this gets properly read from definition files now. * preinitialize a few quotes that are used for status display purposes and are needed in all games * only use the global episode name table in Blood to avoid redundancy * let SW's swcustom parser write to the global tables instead of local ones. --- source/blood/src/blood.cpp | 2 +- source/blood/src/levels.cpp | 5 +-- source/blood/src/levels.h | 2 +- source/common/console/c_cvars.cpp | 21 ++++++++- source/common/gamecontrol.cpp | 56 +++++++++++------------- source/common/gamecvars.cpp | 24 +++------- source/common/statistics.cpp | 3 +- source/common/utility/stringtable.h | 8 ++-- source/duke3d/src/gamedef.h | 12 ----- source/duke3d/src/quotes.h | 2 +- source/duke3d/src/screens.cpp | 2 +- source/rr/src/screens.cpp | 2 +- source/sw/src/game.cpp | 30 +++---------- source/sw/src/game.h | 5 --- source/sw/src/scrip2.cpp | 12 ++--- wadsrc/static/demolition/commonbinds.txt | 2 +- 16 files changed, 73 insertions(+), 115 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 3ae6eb9a5..019e48fc6 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -1357,7 +1357,7 @@ RESTART: //} if (gStartNewGame) { - STAT_StartNewGame(gEpisodeInfo[gGameOptions.nEpisode].at0, gGameOptions.nDifficulty); + STAT_StartNewGame(gVolumeNames[gGameOptions.nEpisode], gGameOptions.nDifficulty); StartLevel(&gGameOptions); } } diff --git a/source/blood/src/levels.cpp b/source/blood/src/levels.cpp index 0ca5672f6..7cc35c58f 100644 --- a/source/blood/src/levels.cpp +++ b/source/blood/src/levels.cpp @@ -235,8 +235,7 @@ void levelLoadDefaults(void) break; EPISODEINFO *pEpisodeInfo = &gEpisodeInfo[i]; auto ep_str = BloodINI->GetKeyString(buffer, "Title", buffer); - strncpy(pEpisodeInfo->at0, ep_str, 31); - gVolumeNames[i] = ep_str; // For the menu. + gVolumeNames[i] = ep_str; // only keep one table for the names. Todo: Consolidate this across games. strncpy(pEpisodeInfo->at8f08, BloodINI->GetKeyString(buffer, "CutSceneA", ""), BMAX_PATH); pEpisodeInfo->at9028 = BloodINI->GetKeyInt(buffer, "CutWavA", -1); if (pEpisodeInfo->at9028 == 0) @@ -286,7 +285,7 @@ void levelAddUserMap(const char *pzMap) if (pEpisodeInfo->nLevels == 0) { gEpisodeCount++; - sprintf(pEpisodeInfo->at0, "Episode %d", nEpisode); + gVolumeNames[nEpisode].Format("Episode %d", nEpisode+1); } nLevel = pEpisodeInfo->nLevels++; } diff --git a/source/blood/src/levels.h b/source/blood/src/levels.h index eb4223f9b..e0b5bb9d7 100644 --- a/source/blood/src/levels.h +++ b/source/blood/src/levels.h @@ -84,7 +84,7 @@ struct LEVELINFO struct EPISODEINFO { - char at0[32]; + //char at0[32]; removed, so that the global episode name table can be used for consistency int nLevels; unsigned int bloodbath : 1; unsigned int cutALevel : 4; diff --git a/source/common/console/c_cvars.cpp b/source/common/console/c_cvars.cpp index 89d3aeee0..195bfe51a 100644 --- a/source/common/console/c_cvars.cpp +++ b/source/common/console/c_cvars.cpp @@ -38,12 +38,14 @@ #include "c_cvars.h" #include "configfile.h" +#include "baselayer.h" #include "c_console.h" #include "gamecvars.h" #include "cmdlib.h" #include "c_dispatch.h" #include "printf.h" +#include "quotemgr.h" struct FLatchedValue @@ -1511,8 +1513,23 @@ CCMD (toggle) val = var->GetGenericRep (CVAR_Bool); val.Bool = !val.Bool; var->SetGenericRep (val, CVAR_Bool); - Printf ("\"%s\" = \"%s\"\n", var->GetName(), - val.Bool ? "true" : "false"); + const char *statestr = argv.argc() <= 2? "*" : argv[2]; + if (*statestr == '*') + { + gi->PrintMessage(PRINT_MEDIUM, "\"%s\" = \"%s\"\n", var->GetName(), val.Bool ? "true" : "false"); + } + else + { + int state = (int)strtoll(argv[2], nullptr, 0); + if (state != 0) + { + // Order of Duke's quote string varies, some have on first, some off, so use the sign of the parameter to decide. + // Positive means Off/On, negative means On/Off + int quote = state > 0? state + val.Bool : -(state + val.Bool); + auto text = quoteMgr.GetQuote(quote); + if (text) gi->PrintMessage(PRINT_MEDIUM, "%s\n", text); + } + } } } } diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index b086ab39a..8258acb2a 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -25,6 +25,7 @@ #include "statistics.h" #include "menu.h" #include "gstrings.h" +#include "quotemgr.h" #ifndef NETCODE_DISABLE #include "enet.h" #endif @@ -263,47 +264,40 @@ int GameMain() //========================================================================== // -// Try to keep all initializations of global string variables in this one place +// // //========================================================================== -#define LOCALIZED_STRING(s) s // change to "${" s "}" later, once all text output functions can replace text macros +#define LOCALIZED_STRING(s) "$" s void SetDefaultStrings() { - // Hard coded texts for the episode and skill selection menus. - if (g_gameType & GAMEFLAG_DUKE) + // Blood hard codes its skill names, so we have to define them manually. + if (g_gameType & GAMEFLAG_BLOOD) { - gVolumeNames[0] = LOCALIZED_STRING("L.A. Meltdown"); - gVolumeNames[1] = LOCALIZED_STRING("Lunar Apocalypse"); - gVolumeNames[2] = LOCALIZED_STRING("Shrapnel City"); - gSkillNames[0] = LOCALIZED_STRING("Piece Of Cake"); - gSkillNames[1] = LOCALIZED_STRING("Let's Rock"); - gSkillNames[2] = LOCALIZED_STRING("Come Get Some"); - gSkillNames[3] = LOCALIZED_STRING("Damn I'm Good"); + gSkillNames[0] = "$STILL KICKING"; + gSkillNames[1] = "$PINK ON THE INSIDE"; + gSkillNames[2] = "$LIGHTLY BROILED"; + gSkillNames[3] = "$WELL DONE"; + gSkillNames[4] = "$EXTRA CRISPY"; } - else if (g_gameType & GAMEFLAG_BLOOD) - { - gSkillNames[0] = LOCALIZED_STRING("STILL KICKING"); - gSkillNames[1] = LOCALIZED_STRING("PINK ON THE INSIDE"); - gSkillNames[2] = LOCALIZED_STRING("LIGHTLY BROILED"); - gSkillNames[3] = LOCALIZED_STRING("WELL DONE"); - gSkillNames[4] = LOCALIZED_STRING("EXTRA CRISPY"); - } - else if (g_gameType & GAMEFLAG_SW) - { - gVolumeNames[0] = LOCALIZED_STRING("Enter the Wang"); - gVolumeNames[1] = LOCALIZED_STRING("Code of Honor"); + + //Set a few quotes which are used for common handling of a few status messages + quoteMgr.InitializeQuote(23, "$MESSAGES: ON"); + quoteMgr.InitializeQuote(24, "$MESSAGES:OFF"); + quoteMgr.InitializeQuote(83, "$MAPFOLLOWOFF"); + quoteMgr.InitializeQuote(84, "$MAPFOLLOWON"); + quoteMgr.InitializeQuote(85, "$AUTORUNOFF"); + quoteMgr.InitializeQuote(86, "$AUTORUNON"); + #if 0 // todo: print a message + if (gAutoRun) + viewSetMessage("Auto run ON"); + else + viewSetMessage("Auto run OFF"); - gVolumeSubtitles[0] = LOCALIZED_STRING("Four levels (Shareware Version)"); - gVolumeSubtitles[1] = LOCALIZED_STRING("Eighteen levels (Full Version Only)"); - - gSkillNames[0] = LOCALIZED_STRING("Tiny grasshopper"); - gSkillNames[1] = LOCALIZED_STRING("I Have No Fear"); - gSkillNames[2] = LOCALIZED_STRING("Who Wants Wang"); - gSkillNames[3] = LOCALIZED_STRING("No Pain, No Gain"); - } + #endif } + //========================================================================== // // diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index c82ce8cca..5a4674b13 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -49,6 +49,7 @@ #include "z_music.h" #include "c_dispatch.h" #include "gstrings.h" +#include "quotemgr.h" /* Notes @@ -60,23 +61,8 @@ CVARD(Bool, cl_crosshair, true, CVAR_ARCHIVE, "enable/disable crosshair"); CVARD(Bool, cl_automsg, false, CVAR_ARCHIVE, "enable/disable automatically sending messages to all players") // Not implemented for Blood -CUSTOM_CVARD(Bool, cl_autorun, true, CVAR_ARCHIVE, "enable/disable autorun") -{ -#if 0 // todo: print a message +CVARD(Bool, cl_autorun, true, CVAR_ARCHIVE, "enable/disable autorun") - if (gAutoRun) - viewSetMessage("Auto run ON"); - else - viewSetMessage("Auto run OFF"); - - - RUN MODE OFF - RUN MODE ON - cl_autorun= 1-cl_autorun; - P_DoQuote(QUOTE_RUN_MODE_OFF + cl_autorun, &myplayer); - } -#endif -} CVARD(Bool, cl_runmode, true, CVAR_ARCHIVE, "enable/disable modernized run key operation") bool G_CheckAutorun(bool button) @@ -259,18 +245,18 @@ CUSTOM_CVARD(Int, hud_messages, 1, CVAR_ARCHIVE, "enable/disable showing message if (self < 0 || self > 2) self = 1; } - +// This cannot be done with the 'toggle' CCMD because it needs to control itself when to output the message CCMD (togglemessages) { if (hud_messages) { - gi->PrintMessage(PRINT_MEDIUM, "%s\n", GStrings("MSGOFF")); + gi->PrintMessage(PRINT_MEDIUM, "%s\n", quoteMgr.GetQuote(24)); hud_messages = false; } else { hud_messages = true; - gi->PrintMessage(PRINT_MEDIUM, "%s\n", GStrings("MSGON")); + gi->PrintMessage(PRINT_MEDIUM, "%s\n", quoteMgr.GetQuote(23)); } } diff --git a/source/common/statistics.cpp b/source/common/statistics.cpp index 58ebf0e1c..cbe336141 100644 --- a/source/common/statistics.cpp +++ b/source/common/statistics.cpp @@ -47,6 +47,7 @@ #include "baselayer.h" #include "savegamehelp.h" #include "sjson.h" +#include "gstrings.h" CVAR(Int, savestatistics, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(String, statfile, "demolitionstat.txt", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) @@ -354,7 +355,7 @@ static void LevelStatEntry(FSessionStatistics *es, const char *level, const char void STAT_StartNewGame(const char *episode, int skill) { - StartEpisode = episode; + StartEpisode = GStrings.localize(episode); StartSkill = skill; LevelData.Clear(); LevelName = ""; diff --git a/source/common/utility/stringtable.h b/source/common/utility/stringtable.h index f18c5315a..5849d2b2c 100644 --- a/source/common/utility/stringtable.h +++ b/source/common/utility/stringtable.h @@ -114,14 +114,14 @@ private: public: static FString MakeMacro(const char *str) { - //return FStringf("${%s}", str); - return str; + if (*str == '$') return str; + return FString("$") + str; } static FString MakeMacro(const char *str, size_t len) { - //return FStringf("${%.*s}", len, str); - return FString(str, len); + if (*str == '$') return FString(str, len); + return "$" + FString(str, len); } const char* localize(const char* str) diff --git a/source/duke3d/src/gamedef.h b/source/duke3d/src/gamedef.h index a9aa67294..f46bc8df0 100644 --- a/source/duke3d/src/gamedef.h +++ b/source/duke3d/src/gamedef.h @@ -212,18 +212,6 @@ void C_UndefineVolume(int32_t vol); void C_UndefineSkill(int32_t skill); void C_UndefineLevel(int32_t vol, int32_t lev); #if defined LUNATIC -void C_DefineSound(int32_t sndidx, const char *fn, int32_t args[5]); -void C_DefineQuote(int32_t qnum, const char *qstr); -void C_DefineVolumeName(int32_t vol, const char *name); -void C_DefineSkillName(int32_t skill, const char *name); -void C_DefineLevelName(int32_t vol, int32_t lev, const char *fn, - int32_t partime, int32_t designertime, - const char *levelname); -void C_DefineGameFuncName(int32_t idx, const char *name); -void C_DefineGameType(int32_t idx, int32_t flags, const char *name); -int32_t C_SetDefName(const char *name); -void C_DefineProjectile(int32_t j, int32_t what, int32_t val); -void C_SetCfgName(const char *cfgname); #else void C_ReportError(int error); void C_Compile(const char *filenam); diff --git a/source/duke3d/src/quotes.h b/source/duke3d/src/quotes.h index ae5078a16..50b9dc1c2 100644 --- a/source/duke3d/src/quotes.h +++ b/source/duke3d/src/quotes.h @@ -89,7 +89,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define QUOTE_RESERVED 115 #define QUOTE_RESERVED2 116 #define QUOTE_RESERVED3 117 -#define QUOTE_SAVE_DEAD NOBETAQUOTE(118) +#define QUOTE_SAVE_DEAD 118 #define QUOTE_CHEAT_ALL_WEAPONS NOBETAQUOTE(119) #define QUOTE_CHEAT_ALL_INV NOBETAQUOTE(120) #define QUOTE_CHEAT_ALL_KEYS NOBETAQUOTE(121) diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index ea8f64505..df1cd1f4a 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -962,7 +962,7 @@ void G_DisplayRest(int32_t smoothratio) if (G_HaveUserMap()) levelname = boardfilename; else if (!(G_GetLogoFlags() & LOGO_HIDEEPISODE)) - minitext(5, a+6, gVolumeNames[ud.volume_number], 0, 2+8+16+256); + minitext(5, a+6, GStrings.localize(gVolumeNames[ud.volume_number]), 0, 2+8+16+256); minitext(5, a+6+6, levelname, 0, 2+8+16+256); } } diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index 557beea8b..769b26a2a 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -993,7 +993,7 @@ void G_DisplayRest(int32_t smoothratio) else { if (!G_HaveUserMap()) - minitext(5, a+6, gVolumeNames[ud.volume_number], 0, 2+8+16+256); + minitext(5, a+6, GStrings.localize(gVolumeNames[ud.volume_number]), 0, 2+8+16+256); minitext(5, a+6+6, g_mapInfo[ud.volume_number*MAXLEVELS + ud.level_number].name, 0, 2+8+16+256); } } diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index a82731778..5214778ee 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -926,9 +926,13 @@ void InitGame() LoadKVXFromScript("swvoxfil.txt"); // Load voxels from script file LoadPLockFromScript("swplock.txt"); // Get Parental Lock setup info + + LoadCustomInfoFromScript("demolition/swcustom.txt"); // load the internal definitions. These also apply to the shareware version. if (!SW_SHAREWARE) - LoadCustomInfoFromScript("swcustom.txt"); // Load user customisation information - + { + LoadCustomInfoFromScript("swcustom.txt"); // Load user customisation information + } + if (!loaddefinitionsfile(G_DefFile())) buildputs("Definitions file loaded.\n"); userConfig.AddDefs.reset(); @@ -1044,28 +1048,6 @@ int ThemeTrack[6] = 2,3,13,13,13,14 }; -char EpisodeNames[3][MAX_EPISODE_NAME_LEN+2] = -{ - "^Enter the Wang", - "^Code of Honor", - "^User Maps", -}; - -char EpisodeSubtitles[3][MAX_EPISODE_SUBTITLE_LEN+1] = -{ - "Four levels (Shareware Version)", - "Eighteen levels (Full Version Only)", - "Select a user map to play", -}; - -char SkillNames[4][MAX_SKILL_NAME_LEN+2] = -{ - "^Tiny grasshopper", - "^I Have No Fear", - "^Who Wants Wang", - "^No Pain, No Gain" -}; - void InitNewGame(void) { int i, ready_bak; diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 21ec3146e..80bb812b7 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -960,11 +960,6 @@ extern const char *ThemeSongs[6]; // #define MAX_EPISODE_NAME_LEN 24 extern char EpisodeNames[3][MAX_EPISODE_NAME_LEN+2]; -#define MAX_EPISODE_SUBTITLE_LEN 40 -extern char EpisodeSubtitles[3][MAX_EPISODE_SUBTITLE_LEN+1]; - -#define MAX_SKILL_NAME_LEN 24 -extern char SkillNames[4][MAX_SKILL_NAME_LEN+2]; #define MAX_FORTUNES 16 extern const char *ReadFortune[MAX_FORTUNES]; diff --git a/source/sw/src/scrip2.cpp b/source/sw/src/scrip2.cpp index ba19d1e30..f9598e064 100644 --- a/source/sw/src/scrip2.cpp +++ b/source/sw/src/scrip2.cpp @@ -39,6 +39,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "jsector.h" #include "parent.h" #include "scriptfile.h" +#include "menu/menu.h" BEGIN_SW_NS @@ -723,18 +724,14 @@ void LoadCustomInfoFromScript(const char *filename) { char *t; if (scriptfile_getstring(script, &t)) break; - - strncpy(&EpisodeNames[curmap][1], t, MAX_EPISODE_NAME_LEN); - EpisodeNames[curmap][MAX_EPISODE_NAME_LEN+1] = 0; + gVolumeNames[curmap] = t; break; } case CM_SUBTITLE: { char *t; if (scriptfile_getstring(script, &t)) break; - - strncpy(EpisodeSubtitles[curmap], t, MAX_EPISODE_SUBTITLE_LEN); - EpisodeSubtitles[curmap][MAX_EPISODE_SUBTITLE_LEN] = 0; + gVolumeSubtitles[curmap] = t; break; } default: @@ -775,8 +772,7 @@ void LoadCustomInfoFromScript(const char *filename) char *t; if (scriptfile_getstring(script, &t)) break; - strncpy(&SkillNames[curmap][1], t, MAX_SKILL_NAME_LEN); - SkillNames[curmap][MAX_SKILL_NAME_LEN+1] = 0; + gSkillNames[curmap] = t; break; } default: diff --git a/wadsrc/static/demolition/commonbinds.txt b/wadsrc/static/demolition/commonbinds.txt index 23cdfddc2..9c45bf0a3 100644 --- a/wadsrc/static/demolition/commonbinds.txt +++ b/wadsrc/static/demolition/commonbinds.txt @@ -35,7 +35,7 @@ LAlt "+Strafe" RAlt "+Strafe" LShift "+Run" RShift "+Run" -Capslock "+AutoRun" +Capslock "toggle autorun 85" PgUp "+Look_Up" PgDn "+Look_Down" Home "+Aim_Up" From 4ef9ec6708ee03562b50b5a35533f0bd0bc9f72e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Dec 2019 00:43:48 +0100 Subject: [PATCH 170/203] - call STAT_StartNewGame globally from the menu --- source/blood/src/blood.cpp | 1 - source/common/menu/menu.cpp | 2 ++ source/duke3d/src/premap.cpp | 2 -- source/rr/src/premap.cpp | 2 -- 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 019e48fc6..d30d880d6 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -1357,7 +1357,6 @@ RESTART: //} if (gStartNewGame) { - STAT_StartNewGame(gVolumeNames[gGameOptions.nEpisode], gGameOptions.nDifficulty); StartLevel(&gGameOptions); } } diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 8f6dccb04..46791ad54 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -52,6 +52,7 @@ #include "pragmas.h" #include "build.h" #include "baselayer.h" +#include "statistics.h" void RegisterDukeMenus(); void RegisterRedneckMenus(); @@ -463,6 +464,7 @@ bool M_SetMenu(FName menu, int param, FName caller) { case NAME_StartGame: M_ClearMenus(); // must be done before starting the level. + STAT_StartNewGame(gVolumeNames[GameStartupInfo.Episode], GameStartupInfo.Skill); gi->StartGame(GameStartupInfo); return false; diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index 7a4c10dd6..0043a2659 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -28,7 +28,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "duke3d.h" #include "menus.h" #include "savegame.h" -#include "statistics.h" #include "menu/menu.h" BEGIN_DUKE_NS @@ -1340,7 +1339,6 @@ void G_NewGame(int volumeNum, int levelNum, int skillNum) ud.secretlevel = 0; ud.skill_voice = -1; ud.volume_number = volumeNum; - STAT_StartNewGame(gVolumeNames[volumeNum], skillNum); // we don't want the intro to play after the multiplayer setup screen if ((!g_netServer && ud.multimode < 2) && !Menu_HaveUserMap() diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index d1117295c..43bacd77b 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -27,7 +27,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "demo.h" #include "savegame.h" #include "cmdline.h" -#include "statistics.h" #include "menu/menu.h" BEGIN_RR_NS @@ -1901,7 +1900,6 @@ void G_NewGame(int volumeNum, int levelNum, int skillNum) ud.player_skill = skillNum; ud.secretlevel = 0; ud.from_bonus = 0; - STAT_StartNewGame(gVolumeNames[volumeNum], skillNum); ud.last_level = -1; From 66218dd074b3002e26b719e6fe2f1efe864d0ef2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Dec 2019 00:55:30 +0100 Subject: [PATCH 171/203] - connect SW with statistics code and added missing function for Blood # Conflicts: # source/blood/src/blood.h # source/common/menu/messagebox.cpp # source/sw/src/game.cpp # source/sw/src/game.h --- source/blood/src/blood.h | 1 + source/blood/src/view.cpp | 5 +++ source/build/include/baselayer.h | 1 + source/common/menu/messagebox.cpp | 2 ++ source/duke3d/src/screens.cpp | 2 +- source/rr/src/screens.cpp | 2 +- source/sw/src/game.cpp | 58 +++++++++++++++++++------------ source/sw/src/game.h | 1 + 8 files changed, 47 insertions(+), 25 deletions(-) diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index 0761bb81a..164d56413 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -101,6 +101,7 @@ struct GameInterface : ::GameInterface void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg); void QuitToTitle() override; + GameStats getStats() override; }; END_BLD_NS diff --git a/source/blood/src/view.cpp b/source/blood/src/view.cpp index 6044a2176..668319b14 100644 --- a/source/blood/src/view.cpp +++ b/source/blood/src/view.cpp @@ -1164,6 +1164,11 @@ void viewDrawStats(PLAYER *pPlayer, int x, int y) viewDrawText(3, buffer, x, y, 20, 0, 0, true, 256); } +GameStats GameInterface::getStats() +{ + return { gKillMgr.at4, gKillMgr.at0, gSecretMgr.at8, gSecretMgr.at0, gLevelTime / kTicsPerSec, gPlayer[myconnectindex].fragCount }; +} + #define kSBarNumberHealth 9220 #define kSBarNumberAmmo 9230 #define kSBarNumberInv 9240 diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 851b7289e..979f2e95f 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -168,6 +168,7 @@ struct GameStats int kill, tkill; int secret, tsecret; int timesecnd; + int frags; }; struct FGameStartup diff --git a/source/common/menu/messagebox.cpp b/source/common/menu/messagebox.cpp index 5fe3c8248..134358930 100644 --- a/source/common/menu/messagebox.cpp +++ b/source/common/menu/messagebox.cpp @@ -39,6 +39,7 @@ #include "v_draw.h" #include "gstrings.h" #include "c_dispatch.h" +#include "statistics.h" #include "v_2ddrawer.h" extern FSaveGameNode *quickSaveSlot; @@ -407,6 +408,7 @@ CCMD (menu_endgame) { if (res) { + STAT_Cancel(); gi->QuitToTitle(); } }); diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index df1cd1f4a..5dbdac236 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -1153,7 +1153,7 @@ void G_DisplayRest(int32_t smoothratio) GameStats GameInterface::getStats() { DukePlayer_t* p = g_player[myconnectindex].ps; - return { p->actors_killed, p->max_actors_killed, p->secret_rooms, p->max_secret_rooms, p->player_par / REALGAMETICSPERSEC }; + return { p->actors_killed, p->max_actors_killed, p->secret_rooms, p->max_secret_rooms, p->player_par / REALGAMETICSPERSEC, p->frag }; } diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index 769b26a2a..409da64aa 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -755,7 +755,7 @@ FString GameInterface::statFPS() GameStats GameInterface::getStats() { DukePlayer_t* p = g_player[myconnectindex].ps; - return { p->actors_killed, p->max_actors_killed, p->secret_rooms, p->max_secret_rooms, p->player_par / REALGAMETICSPERSEC }; + return { p->actors_killed, p->max_actors_killed, p->secret_rooms, p->max_secret_rooms, p->player_par / REALGAMETICSPERSEC, p->frag }; } #undef FPS_COLOR diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 5214778ee..9fd7f7b56 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -97,6 +97,7 @@ Things required to make savegames work: #include "debugbreak.h" #include "menu/menu.h" #include "z_music.h" +#include "statistics.h" //#include "crc32.h" @@ -644,24 +645,16 @@ void TerminateGame(void) } -void LoadLevel(const char *filename) +bool LoadLevel(const char *filename) { - int pos; - if (engineLoadBoard(filename, SW_SHAREWARE ? 1 : 0, (vec3_t *)&Player[0], &Player[0].pang, &Player[0].cursectnum) == -1) { TerminateGame(); -#ifdef RENDERTYPEWIN - { - char msg[256]; - Bsnprintf(msg, 256, "Level not found: %s", filename); - wm_msgbox(apptitle, msg); - } -#else - printf("Level Not Found: %s\n", filename); -#endif - exit(0); - } + Printf("Level not found: %s", filename); + return false; + } + STAT_NewLevel(filename); + return true; } void LoadDemoRun(void) @@ -808,7 +801,7 @@ static void SW_FatalEngineError(void) I_Error("There was a problem initialising the Build engine: %s", engineerrstr); } -void InitGame() +bool InitGame() { extern int MovesPerPacket; //void *ReserveMem=NULL; @@ -945,7 +938,7 @@ void InitGame() if (UserMapName[0] == '\0') { AnimateCacheCursor(); - LoadLevel("$dozer.map"); + if (!LoadLevel("$dozer.map")) return false AnimateCacheCursor(); SetupPreCache(); DoTheCache(); @@ -953,7 +946,7 @@ void InitGame() else { AnimateCacheCursor(); - LoadLevel(UserMapName); + if (!LoadLevel(UserMapName)) return false; AnimateCacheCursor(); SetupPreCache(); DoTheCache(); @@ -966,6 +959,7 @@ void InitGame() COVERsetbrightness(0, &palette_data[0][0]); InitFX(); // JBF: do it down here so we get a hold of the window handle + return true; } @@ -1231,7 +1225,12 @@ InitLevel(void) if (!DemoMode && !DemoInitOnce) DemoPlaySetup(); - LoadLevel(LevelName); + if (!LoadLevel(LevelName)) + { + NewGame = false; + return; + } + STAT_NewLevel(LevelName); if (Bstrcasecmp(CacheLastLevel, LevelName) != 0) // clears gotpic and does some bit setting @@ -1488,6 +1487,7 @@ void NewLevel(void) FX_SetVolume(0); // Shut the hell up while game is loading! InitLevel(); RunLevel(); + STAT_Update(false); if (!QuitFlag) { @@ -1512,6 +1512,7 @@ void NewLevel(void) { PlayTheme(); MenuLevel(); + STAT_Update(true); } } else @@ -1520,7 +1521,8 @@ void NewLevel(void) { PlayTheme(); MenuLevel(); - } + STAT_Update(true); + } } FinishAnim = 0; } @@ -2092,13 +2094,15 @@ int BonusGrabSound(short SpriteNum) return 0; } +extern SWBOOL FinishedLevel; +extern int PlayClock; +extern short LevelSecrets; +extern short TotalKillable; + void BonusScreen(PLAYERp pp) { int minutes,seconds,second_tics; - extern SWBOOL FinishedLevel; - extern int PlayClock; - extern short LevelSecrets; - extern short TotalKillable; + short w,h; short pic,limit; int zero=0; @@ -4329,4 +4333,12 @@ void Saveable_Init_Dynamic() } +GameStats GameInterface::getStats() +{ + PLAYERp pp = Player + myconnectindex; + return { pp->Kills, TotalKillable, pp->SecretsFound, LevelSecrets, PlayClock / 120, 0 }; +} + + + END_SW_NS diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 80bb812b7..17cbc12ef 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -2385,6 +2385,7 @@ struct GameInterface : ::GameInterface void DoPrintMessage(int prio, const char* text) override; void SetAmbience(bool on) override { if (on) StartAmbientSound(); else StopAmbientSound(); } + GameStats getStats() override; }; From 0604c72586c68e42946c1e1141996bb7522fb7fe Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Dec 2019 01:39:40 +0100 Subject: [PATCH 172/203] - code cleanup removed some unused definitions replaced the copybuf* functions with memcpy. These days doing homegrown copy loops is not efficient anymore. --- source/build/include/colmatch.h | 4 ---- source/build/include/compat.h | 2 -- source/build/include/pragmas.h | 6 ------ source/build/src/compat.cpp | 23 ----------------------- source/build/src/engine.cpp | 22 ++++++---------------- source/build/src/pragmas.cpp | 21 --------------------- source/common/searchpaths.cpp | 2 +- source/rr/src/net.cpp | 14 +++++++------- source/sw/src/sector.cpp | 2 +- 9 files changed, 15 insertions(+), 81 deletions(-) diff --git a/source/build/include/colmatch.h b/source/build/include/colmatch.h index 90c36e0ba..751ba1a68 100644 --- a/source/build/include/colmatch.h +++ b/source/build/include/colmatch.h @@ -13,7 +13,3 @@ static FORCE_INLINE int32_t paletteGetClosestColor(int32_t r, int32_t g, int32_t { return getclosestcol_lim(r, g, b, 255); } -static FORCE_INLINE int32_t getclosestcol_nocache(int32_t r, int32_t g, int32_t b) -{ - return getclosestcol_nocache_lim(r, g, b, 255); -} diff --git a/source/build/include/compat.h b/source/build/include/compat.h index d17ac36ad..e0da70d05 100644 --- a/source/build/include/compat.h +++ b/source/build/include/compat.h @@ -1169,8 +1169,6 @@ static inline void append_ext_UNSAFE(char *outbuf, const char *ext) ////////// Paths ////////// -char *Bgethomedir(void); - int32_t Bcorrectfilename(char *filename, int32_t removefn); ////////// String manipulation ////////// diff --git a/source/build/include/pragmas.h b/source/build/include/pragmas.h index 922917289..527cb03eb 100644 --- a/source/build/include/pragmas.h +++ b/source/build/include/pragmas.h @@ -189,9 +189,6 @@ void qinterpolatedown16short(intptr_t bufptr, int32_t num, int32_t val, int32_t #ifndef pragmas_have_clearbuf void clearbuf(void *d, int32_t c, int32_t a); #endif -#ifndef pragmas_have_copybuf -void copybuf(const void *s, void *d, int32_t c); -#endif #ifndef pragmas_have_swaps void swapbuf4(void *a, void *b, int32_t c); #endif @@ -199,9 +196,6 @@ void swapbuf4(void *a, void *b, int32_t c); #ifndef pragmas_have_clearbufbyte void clearbufbyte(void *D, int32_t c, int32_t a); #endif -#ifndef pragmas_have_copybufbyte -void copybufbyte(const void *S, void *D, int32_t c); -#endif #ifndef pragmas_have_copybufreverse void copybufreverse(const void *S, void *D, int32_t c); #endif diff --git a/source/build/src/compat.cpp b/source/build/src/compat.cpp index fdcffc559..7c411ef24 100644 --- a/source/build/src/compat.cpp +++ b/source/build/src/compat.cpp @@ -73,29 +73,6 @@ void set_memerr_handler(void(*handlerfunc)(int32_t, const char *, const char *)) g_MemErrHandler = handlerfunc; } -// -// Stuff which must be a function -// -char *Bgethomedir(void) -{ -#ifdef _WIN32 - - char appdata[MAX_PATH]; - - if (SUCCEEDED(SHGetSpecialFolderPathA(NULL, appdata, CSIDL_APPDATA, FALSE))) - { - return Xstrdup(appdata); - } - return NULL; -#elif defined EDUKE32_OSX - return osx_gethomedir(); -#else - char *e = getenv("HOME"); - if (!e) return NULL; - return Xstrdup(e); -#endif -} - int32_t Bcorrectfilename(char *filename, int32_t removefn) { diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index e6e33f752..9b1faaa1f 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -4468,7 +4468,7 @@ static void classicDrawBunches(int32_t bunch) smostwall[smostwallcnt] = z; smostwalltype[smostwallcnt] = 1; //1 for umost smostwallcnt++; - copybufbyte(&umost[x1],&smost[smostcnt],i*sizeof(smost[0])); + memcpy(&umost[x1],&smost[smostcnt],i*sizeof(smost[0])); smostcnt += i; } } @@ -4554,7 +4554,7 @@ static void classicDrawBunches(int32_t bunch) smostwall[smostwallcnt] = z; smostwalltype[smostwallcnt] = 2; //2 for dmost smostwallcnt++; - copybufbyte(&dmost[x1],&smost[smostcnt],i*sizeof(smost[0])); + memcpy(&dmost[x1],&smost[smostcnt],i*sizeof(smost[0])); smostcnt += i; } } @@ -5023,16 +5023,6 @@ static void classicDrawVoxel(int32_t dasprx, int32_t daspry, int32_t dasprz, int } } -#if 0 - for (x=0; x=0 && daumost[x]=0 && dadmost[x] &searchpaths) { FString path; - char *homepath = Bgethomedir(); + char *homepath = getenv("HOME"); path.Format("%s/.steam/steam", homepath); G_AddSteamPaths(searchpaths, buf); diff --git a/source/rr/src/net.cpp b/source/rr/src/net.cpp index 8fcde4321..edeb400a5 100644 --- a/source/rr/src/net.cpp +++ b/source/rr/src/net.cpp @@ -1801,7 +1801,7 @@ void Net_GetInput(void) if (g_player[myconnectindex].movefifoend&(g_movesPerPacket-1)) { - copybufbyte(&inputfifo[(g_player[myconnectindex].movefifoend-1)&(MOVEFIFOSIZ-1)][myconnectindex], + memcpy(&inputfifo[(g_player[myconnectindex].movefifoend-1)&(MOVEFIFOSIZ-1)][myconnectindex], &inputfifo[g_player[myconnectindex].movefifoend&(MOVEFIFOSIZ-1)][myconnectindex],sizeof(input_t)); g_player[myconnectindex].movefifoend++; return; @@ -2179,7 +2179,7 @@ void Net_ParsePacket(uint8_t *packbuf, int packbufleng) continue; } - copybufbyte(&osyn[i],&nsyn[i],sizeof(input_t)); + memcpy(&osyn[i],&nsyn[i],sizeof(input_t)); if (l&1) nsyn[i].fvel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2; if (l&2) nsyn[i].svel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2; if (l&4) @@ -2218,7 +2218,7 @@ void Net_ParsePacket(uint8_t *packbuf, int packbufleng) if (i != myconnectindex) for (j=g_movesPerPacket-1;j>=1;j--) { - copybufbyte(&nsyn[i],&inputfifo[g_player[i].movefifoend&(MOVEFIFOSIZ-1)][i],sizeof(input_t)); + memcpy(&nsyn[i],&inputfifo[g_player[i].movefifoend&(MOVEFIFOSIZ-1)][i],sizeof(input_t)); g_player[i].movefifoend++; } @@ -2232,7 +2232,7 @@ void Net_ParsePacket(uint8_t *packbuf, int packbufleng) osyn = (input_t *)&inputfifo[(g_player[other].movefifoend-1)&(MOVEFIFOSIZ-1)][0]; nsyn = (input_t *)&inputfifo[(g_player[other].movefifoend)&(MOVEFIFOSIZ-1)][0]; - copybufbyte(&osyn[other],&nsyn[other],sizeof(input_t)); + memcpy(&osyn[other],&nsyn[other],sizeof(input_t)); if (k&1) nsyn[other].fvel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2; if (k&2) nsyn[other].svel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2; if (k&4) @@ -2271,7 +2271,7 @@ void Net_ParsePacket(uint8_t *packbuf, int packbufleng) for (i=g_movesPerPacket-1;i>=1;i--) { - copybufbyte(&nsyn[other],&inputfifo[g_player[other].movefifoend&(MOVEFIFOSIZ-1)][other],sizeof(input_t)); + memcpy(&nsyn[other],&inputfifo[g_player[other].movefifoend&(MOVEFIFOSIZ-1)][other],sizeof(input_t)); g_player[other].movefifoend++; } @@ -2295,7 +2295,7 @@ void Net_ParsePacket(uint8_t *packbuf, int packbufleng) osyn = (input_t *)&inputfifo[(g_player[other].movefifoend-1)&(MOVEFIFOSIZ-1)][0]; nsyn = (input_t *)&inputfifo[(g_player[other].movefifoend)&(MOVEFIFOSIZ-1)][0]; - copybufbyte(&osyn[other],&nsyn[other],sizeof(input_t)); + memcpy(&osyn[other],&nsyn[other],sizeof(input_t)); k = packbuf[j] + (int)(packbuf[j+1]<<8); j += 2; @@ -2331,7 +2331,7 @@ void Net_ParsePacket(uint8_t *packbuf, int packbufleng) for (i=g_movesPerPacket-1;i>=1;i--) { - copybufbyte(&nsyn[other],&inputfifo[g_player[other].movefifoend&(MOVEFIFOSIZ-1)][other],sizeof(input_t)); + memcpy(&nsyn[other],&inputfifo[g_player[other].movefifoend&(MOVEFIFOSIZ-1)][other],sizeof(input_t)); g_player[other].movefifoend++; } diff --git a/source/sw/src/sector.cpp b/source/sw/src/sector.cpp index bc79eda0b..f8d1be778 100644 --- a/source/sw/src/sector.cpp +++ b/source/sw/src/sector.cpp @@ -3174,7 +3174,7 @@ void movelava(char *dapic) offs2 = (LAVASIZ + 2) + 1 + ((intptr_t) lavabakpic); for (x = 0; x < LAVASIZ; x++) { - copybuf(offs, offs2, LAVASIZ >> 2); + memcpy(offs, offs2, LAVASIZ); offs += LAVASIZ; offs2 += LAVASIZ + 2; } From 5e9b874610a259c514a55c0f99ccebae54b4969b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Dec 2019 02:01:30 +0100 Subject: [PATCH 173/203] - exported most of Blood's text to the string table MP messages with %s yet to do. --- source/blood/src/db.cpp | 93 ----------------------------------- source/blood/src/endgame.cpp | 32 +++++------- source/blood/src/gamemenu.cpp | 13 ++--- source/blood/src/map2d.cpp | 2 + source/blood/src/messages.cpp | 63 ++++++++++++------------ source/blood/src/player.cpp | 25 +++++----- source/blood/src/view.cpp | 9 ++-- source/common/gamecontrol.cpp | 6 +-- 8 files changed, 72 insertions(+), 171 deletions(-) diff --git a/source/blood/src/db.cpp b/source/blood/src/db.cpp index 1e37a3c1f..99f5a47cf 100644 --- a/source/blood/src/db.cpp +++ b/source/blood/src/db.cpp @@ -50,99 +50,6 @@ char qsprite_filler[kMaxSprites], qsector_filler[kMaxSectors]; int gVisibility; bool gModernMap = false; -const char *gItemText[] = { - "Skull Key", - "Eye Key", - "Fire Key", - "Dagger Key", - "Spider Key", - "Moon Key", - "Key 7", - "Doctor's Bag", - "Medicine Pouch", - "Life Essence", - "Life Seed", - "Red Potion", - "Feather Fall", - "Limited Invisibility", - "INVULNERABILITY", - "Boots of Jumping", - "Raven Flight", - "Guns Akimbo", - "Diving Suit", - "Gas mask", - "Clone", - "Crystal Ball", - "Decoy", - "Doppleganger", - "Reflective shots", - "Beast Vision", - "ShadowCloak", - "Rage shroom", - "Delirium Shroom", - "Grow shroom", - "Shrink shroom", - "Death mask", - "Wine Goblet", - "Wine Bottle", - "Skull Grail", - "Silver Grail", - "Tome", - "Black Chest", - "Wooden Chest", - "Asbestos Armor", - "Basic Armor", - "Body Armor", - "Fire Armor", - "Spirit Armor", - "Super Armor", - "Blue Team Base", - "Red Team Base", - "Blue Flag", - "Red Flag", - "DUMMY", - "Level map", -}; - -const char *gAmmoText[] = { - "Spray can", - "Bundle of TNT*", - "Bundle of TNT", - "Case of TNT", - "Proximity Detonator", - "Remote Detonator", - "Trapped Soul", - "4 shotgun shells", - "Box of shotgun shells", - "A few bullets", - "Voodoo Doll", - "OBSOLETE", - "Full drum of bullets", - "Tesla Charge", - "OBSOLETE", - "OBSOLETE", - "Flares", - "OBSOLETE", - "OBSOLETE", - "Gasoline Can", - NULL, -}; - -const char *gWeaponText[] = { - "RANDOM", - "Sawed-off", - "Tommy Gun", - "Flare Pistol", - "Voodoo Doll", - "Tesla Cannon", - "Napalm Launcher", - "Pitchfork", - "Spray Can", - "Dynamite", - "Life Leech", -}; - - void dbCrypt(char *pPtr, int nLength, int nKey) { diff --git a/source/blood/src/endgame.cpp b/source/blood/src/endgame.cpp index cc094afd8..4a55bf6d5 100644 --- a/source/blood/src/endgame.cpp +++ b/source/blood/src/endgame.cpp @@ -41,6 +41,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "messages.h" #include "statistics.h" #include "gamemenu.h" +#include "gstrings.h" BEGIN_BLD_NS @@ -58,22 +59,22 @@ void CEndGameMgr::Draw(void) int nY = 20 - nHeight / 2; if (gGameOptions.nGameType == 0) { - viewDrawText(1, "LEVEL STATS", 160, nY, -128, 0, 1, 0); + viewDrawText(1, GStrings("TXTB_LEVELSTATS"), 160, nY, -128, 0, 1, 0); if (CCheatMgr::m_bPlayerCheated) { - viewDrawText(3, ">>> YOU CHEATED! <<<", 160, 32, -128, 0, 1, 1); + viewDrawText(3, GStrings("TXTB_CHESTED"), 160, 32, -128, 0, 1, 1); } gKillMgr.Draw(); gSecretMgr.Draw(); } else { - viewDrawText(1, "FRAG STATS", 160, nY, -128, 0, 1, 0); + viewDrawText(1, GStrings("TXTB_FRAGSTATS"), 160, nY, -128, 0, 1, 0); gKillMgr.Draw(); } if (/*dword_28E3D4 != 1 && */((int)totalclock&32)) { - viewDrawText(3, "PRESS A KEY TO CONTINUE", 160, 134, -128, 0, 1, 1); + viewDrawText(3, GStrings("PRESSKEY"), 160, 134, -128, 0, 1, 1); } } @@ -164,18 +165,18 @@ void CKillMgr::Draw(void) char pBuffer[40]; if (gGameOptions.nGameType == 0) { - viewDrawText(1, "KILLS:", 75, 50, -128, 0, 0, 1); + viewDrawText(1, FStringf("%s:", GStrings("KILLS")), 75, 50, -128, 0, 0, 1); sprintf(pBuffer, "%2d", at4); viewDrawText(1, pBuffer, 160, 50, -128, 0, 0, 1); - viewDrawText(1, "OF", 190, 50, -128, 0, 0, 1); + viewDrawText(1, GStrings("OF"), 190, 50, -128, 0, 0, 1); sprintf(pBuffer, "%2d", at0); viewDrawText(1, pBuffer, 220, 50, -128, 0, 0, 1); } else { viewDrawText(3, "#", 85, 35, -128, 0, 0, 1); - viewDrawText(3, "NAME", 100, 35, -128, 0, 0, 1); - viewDrawText(3, "FRAGS", 210, 35, -128, 0, 0, 1); + viewDrawText(3, GStrings("NAME"), 100, 35, -128, 0, 0, 1); + viewDrawText(3, GStrings("FRAGS"), 210, 35, -128, 0, 0, 1); int nStart = 0; int nEnd = gInitialNetPlayers; //if (dword_28E3D4 == 1) @@ -219,28 +220,21 @@ void CSecretMgr::Found(int nType) } else at8++; if (gGameOptions.nGameType == 0) { - switch (Random(2)) { - case 0: - viewSetMessage("A secret is revealed.", 0, MESSAGE_PRIORITY_SECRET); - break; - case 1: - viewSetMessage("You found a secret.", 0, MESSAGE_PRIORITY_SECRET); - break; - } + viewSetMessage(GStrings(FStringf("TXT_SECRET%d", Random(2))), 0, MESSAGE_PRIORITY_SECRET); } } void CSecretMgr::Draw(void) { char pBuffer[40]; - viewDrawText(1, "SECRETS:", 75, 70, -128, 0, 0, 1); + viewDrawText(1, FStringf("%s:", GStrings("TXT_SECRETS")), 75, 70, -128, 0, 0, 1); sprintf(pBuffer, "%2d", at4); viewDrawText(1, pBuffer, 160, 70, -128, 0, 0, 1); - viewDrawText(1, "OF", 190, 70, -128, 0, 0, 1); + viewDrawText(1, GStrings("OF"), 190, 70, -128, 0, 0, 1); sprintf(pBuffer, "%2d", at0); viewDrawText(1, pBuffer, 220, 70, -128, 0, 0, 1); if (at8 > 0) - viewDrawText(1, "YOU FOUND A SUPER SECRET!", 160, 100, -128, 2, 1, 1); + viewDrawText(1, GStrings("TXT_SUPERSECRET"), 160, 100, -128, 2, 1, 1); } void CSecretMgr::Clear(void) diff --git a/source/blood/src/gamemenu.cpp b/source/blood/src/gamemenu.cpp index 8b1428260..4ce789220 100644 --- a/source/blood/src/gamemenu.cpp +++ b/source/blood/src/gamemenu.cpp @@ -39,15 +39,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "resource.h" #include "view.h" #include "c_bind.h" +#include "gstrings.h" BEGIN_BLD_NS -const char* zNetGameTypes[] = -{ - "Cooperative", - "Bloodbath", - "Teams", -}; void drawLoadingScreen(void) { @@ -55,12 +50,12 @@ void drawLoadingScreen(void) if (gGameOptions.nGameType == 0) { if (gDemo.at1) - sprintf(buffer, "Loading Demo"); + strcpy(buffer, GStrings("TXTB_LDEMO")); else - sprintf(buffer, "Loading Level"); + strcpy(buffer, GStrings("TXTB_LLEVEL")); } else - sprintf(buffer, "%s", zNetGameTypes[gGameOptions.nGameType - 1]); + strcpy(buffer, GStrings(FStringf("TXTB_NETGT%d", gGameOptions.nGameType))); viewLoadingScreen(2049, buffer, levelGetTitle(), NULL); } diff --git a/source/blood/src/map2d.cpp b/source/blood/src/map2d.cpp index 943919d01..971118a38 100644 --- a/source/blood/src/map2d.cpp +++ b/source/blood/src/map2d.cpp @@ -210,10 +210,12 @@ void CViewMap::sub_25C74(void) nViewY = gViewY0S+1; viewDrawText(3, pBuffer, gViewX1S, nViewY, -128, 0, 2, 0, 256); +#if 0 // needs to be generalized if (gViewMap.bFollowMode) viewDrawText(3, "MAP FOLLOW MODE", gViewX1S, nViewY+8, -128, 0, 2, 0, 256); else viewDrawText(3, "MAP SCROLL MODE", gViewX1S, nViewY+8, -128, 0, 2, 0, 256); +#endif if (tm) viewResizeView(viewSize); } diff --git a/source/blood/src/messages.cpp b/source/blood/src/messages.cpp index 0e5f3bea5..c93c0f13a 100644 --- a/source/blood/src/messages.cpp +++ b/source/blood/src/messages.cpp @@ -41,6 +41,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "network.h" #include "player.h" #include "view.h" +#include "gstrings.h" BEGIN_BLD_NS @@ -57,18 +58,18 @@ void SetGodMode(bool god) { playerSetGodMode(gMe, god); if (gMe->godMode) - viewSetMessage("You are immortal."); + viewSetMessage(GStrings("TXTB_GODMODE")); else - viewSetMessage("You are mortal."); + viewSetMessage(GStrings("TXTB_NOTGODMODE")); } void SetClipMode(bool noclip) { gNoClip = noclip; if (gNoClip) - viewSetMessage("Unclipped movement."); + viewSetMessage(GStrings("TXTB_NOCLIP")); else - viewSetMessage("Normal movement."); + viewSetMessage(GStrings("TXTB_NOCLIPOFF")); } void packStuff(PLAYER *pPlayer) @@ -93,13 +94,13 @@ void SetAmmo(bool stat) { for (int i = 0; i < 12; i++) gMe->ammoCount[i] = gAmmoInfo[i].max; - viewSetMessage("You have full ammo."); + viewSetMessage(GStrings("TXTB_FULLAMMO")); } else { for (int i = 0; i < 12; i++) gMe->ammoCount[i] = 0; - viewSetMessage("You have no ammo."); + viewSetMessage(GStrings("TXTB_NOAMMO")); } } @@ -111,7 +112,7 @@ void SetWeapons(bool stat) } SetAmmo(stat); if (stat) - viewSetMessage("You have all weapons."); + viewSetMessage(GStrings("TXTB_ALLWEAP")); else { if (!VanillaMode()) @@ -121,7 +122,7 @@ void SetWeapons(bool stat) gMe->curWeapon = 0; gMe->nextWeapon = 1; } - viewSetMessage("You have no weapons."); + viewSetMessage(GStrings("TXTB_NOWEAP")); } } @@ -130,12 +131,12 @@ void SetToys(bool stat) if (stat) { packStuff(gMe); - viewSetMessage("Your inventory is full."); + viewSetMessage(GStrings("TXTB_FULLINV")); } else { packClear(gMe); - viewSetMessage("Your inventory is empty."); + viewSetMessage(GStrings("TXTB_NOINV")); } } @@ -144,12 +145,12 @@ void SetArmor(bool stat) int nAmount; if (stat) { - viewSetMessage("You have full armor."); + viewSetMessage(GStrings("TXTB_FULLARM")); nAmount = 3200; } else { - viewSetMessage("You have no armor."); + viewSetMessage(GStrings("TXTB_NOARM")); nAmount = 0; } for (int i = 0; i < 3; i++) @@ -161,27 +162,27 @@ void SetKeys(bool stat) for (int i = 1; i <= 6; i++) gMe->hasKey[i] = stat; if (stat) - viewSetMessage("You have all keys."); + viewSetMessage(GStrings("TXTB_ALLKEYS")); else - viewSetMessage("You have no keys."); + viewSetMessage(GStrings("TXTB_NOKEYS")); } void SetInfiniteAmmo(bool stat) { gInfiniteAmmo = stat; if (gInfiniteAmmo) - viewSetMessage("You have infinite ammo."); + viewSetMessage(GStrings("TXTB_INFAMMO")); else - viewSetMessage("You have limited ammo."); + viewSetMessage(GStrings("TXTB_LIMAMMO")); } void SetMap(bool stat) { gFullMap = stat; if (gFullMap) - viewSetMessage("You have the map."); + viewSetMessage(GStrings("TXTB_ALLMAP")); else - viewSetMessage("You have no map."); + viewSetMessage(GStrings("TXTB_NOALLMAP")); } void SetWooMode(bool stat) @@ -211,7 +212,7 @@ void ToggleBoots(void) { if (powerupCheck(gMe, kPwUpJumpBoots)) { - viewSetMessage("You have no Jumping Boots."); + viewSetMessage(GStrings("TXTB_NOJBOOTS")); if (!VanillaMode()) { gMe->pwUpTime[kPwUpJumpBoots] = 0; @@ -221,7 +222,7 @@ void ToggleBoots(void) } else { - viewSetMessage("You have the Jumping Boots."); + viewSetMessage(GStrings("TXTB_JBOOTS")); if (!VanillaMode()) gMe->pwUpTime[kPwUpJumpBoots] = gPowerUpInfo[kPwUpJumpBoots].bonusTime; powerupActivate(gMe, kPwUpJumpBoots); @@ -232,14 +233,14 @@ void ToggleInvisibility(void) { if (powerupCheck(gMe, kPwUpShadowCloak)) { - viewSetMessage("You are visible."); + viewSetMessage(GStrings("TXTB_VISIBLE")); if (!VanillaMode()) gMe->pwUpTime[kPwUpShadowCloak] = 0; powerupDeactivate(gMe, kPwUpShadowCloak); } else { - viewSetMessage("You are invisible."); + viewSetMessage(GStrings("TXTB_INVISIBLE")); powerupActivate(gMe, kPwUpShadowCloak); } } @@ -248,14 +249,14 @@ void ToggleInvulnerability(void) { if (powerupCheck(gMe, kPwUpDeathMask)) { - viewSetMessage("You are vulnerable."); + viewSetMessage(GStrings("TXTB_VULN")); if (!VanillaMode()) gMe->pwUpTime[kPwUpDeathMask] = 0; powerupDeactivate(gMe, kPwUpDeathMask); } else { - viewSetMessage("You are invulnerable."); + viewSetMessage(GStrings("TXTB_INVULN")); powerupActivate(gMe, kPwUpDeathMask); } } @@ -264,14 +265,14 @@ void ToggleDelirium(void) { if (powerupCheck(gMe, kPwUpDeliriumShroom)) { - viewSetMessage("You are not delirious."); + viewSetMessage(GStrings("TXTB_NODELIR")); if (!VanillaMode()) gMe->pwUpTime[kPwUpDeliriumShroom] = 0; powerupDeactivate(gMe, kPwUpDeliriumShroom); } else { - viewSetMessage("You are delirious."); + viewSetMessage(GStrings("TXTB_DELIR")); powerupActivate(gMe, kPwUpDeliriumShroom); } } @@ -719,19 +720,19 @@ void CCheatMgr::Process(CCheatMgr::CHEATCODE nCheatCode, char* pzArgs) break; case kCheatKevorkian: actDamageSprite(gMe->nSprite, gMe->pSprite, DAMAGE_TYPE_2, 8000); - viewSetMessage("Kevorkian approves."); + viewSetMessage(GStrings("TXTB_KEVORKIAN")); break; case kCheatMcGee: { if (!gMe->pXSprite->burnTime) evPost(gMe->nSprite, 3, 0, kCallbackFXFlameLick); actBurnSprite(actSpriteIdToOwnerId(gMe->nSprite), gMe->pXSprite, 2400); - viewSetMessage("You're fired!"); + viewSetMessage(GStrings("TXTB_FIRED")); break; } case kCheatEdmark: actDamageSprite(gMe->nSprite, gMe->pSprite, DAMAGE_TYPE_3, 8000); - viewSetMessage("Ahhh...those were the days."); + viewSetMessage(GStrings("TXTB_THEDAYS")); break; case kCheatKrueger: { @@ -740,7 +741,7 @@ void CCheatMgr::Process(CCheatMgr::CHEATCODE nCheatCode, char* pzArgs) if (!gMe->pXSprite->burnTime) evPost(gMe->nSprite, 3, 0, kCallbackFXFlameLick); actBurnSprite(actSpriteIdToOwnerId(gMe->nSprite), gMe->pXSprite, 2400); - viewSetMessage("Flame retardant!"); + viewSetMessage(GStrings("TXTB_RETARD")); break; } case kCheatSterno: @@ -758,7 +759,7 @@ void CCheatMgr::Process(CCheatMgr::CHEATCODE nCheatCode, char* pzArgs) case kCheatClarice: if (!VanillaMode()) { - viewSetMessage("You have half armor."); + viewSetMessage(GStrings("TXTB_HALFARMOR")); for (int i = 0; i < 3; i++) gMe->armor[i] = 1600; } diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index 8512ee832..6853e0095 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -53,6 +53,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "weapon.h" #include "common_game.h" #include "messages.h" +#include "gstrings.h" BEGIN_BLD_NS @@ -1468,7 +1469,7 @@ char PickupWeapon(PLAYER *pPlayer, spritetype *pWeapon) { void PickUp(PLAYER *pPlayer, spritetype *pSprite) { - char buffer[80]; + const char *msg = nullptr; int nType = pSprite->type; char pickedUp = 0; int customMsg = -1; @@ -1481,15 +1482,15 @@ void PickUp(PLAYER *pPlayer, spritetype *pSprite) if (nType >= kItemBase && nType <= kItemMax) { pickedUp = PickupItem(pPlayer, pSprite); - if (pickedUp && customMsg == -1) sprintf(buffer, "Picked up %s", gItemText[nType - kItemBase]); + if (pickedUp && customMsg == -1) msg = GStrings(FStringf("TXTB_ITEM%02d", int(nType - kItemBase +1))); } else if (nType >= kItemAmmoBase && nType < kItemAmmoMax) { pickedUp = PickupAmmo(pPlayer, pSprite); - if (pickedUp && customMsg == -1) sprintf(buffer, "Picked up %s", gAmmoText[nType - kItemAmmoBase]); + if (pickedUp && customMsg == -1) msg = GStrings(FStringf("TXTB_AMMO%02d", int(nType - kItemAmmoBase +1))); } else if (nType >= kItemWeaponBase && nType < kItemWeaponMax) { pickedUp = PickupWeapon(pPlayer, pSprite); - if (pickedUp && customMsg == -1) sprintf(buffer, "Picked up %s", gWeaponText[nType - kItemWeaponBase]); + if (pickedUp && customMsg == -1) msg = GStrings(FStringf("TXTB_WPN%02d", int(nType - kItemWeaponBase +1))); } if (!pickedUp) return; @@ -1505,7 +1506,7 @@ void PickUp(PLAYER *pPlayer, spritetype *pSprite) pPlayer->pickupEffect = 30; if (pPlayer == gMe) { if (customMsg > 0) trTextOver(customMsg - 1); - else viewSetMessage(buffer, 0, MESSAGE_PRIORITY_PICKUP); + else if (msg) viewSetMessage(msg, 0, MESSAGE_PRIORITY_PICKUP); } } @@ -1798,14 +1799,14 @@ void ProcessInput(PLAYER *pPlayer) int key = pXSector->Key; if (pXSector->locked && pPlayer == gMe) { - viewSetMessage("It's locked"); + viewSetMessage(GStrings("TXTB_LOCKED")); sndStartSample(3062, 255, 2, 0); } if (!key || pPlayer->hasKey[key]) trTriggerSector(a2, pXSector, kCmdSpritePush, nSprite); else if (pPlayer == gMe) { - viewSetMessage("That requires a key."); + viewSetMessage(GStrings("TXTB_KEY")); sndStartSample(3063, 255, 2, 0); } } @@ -1816,14 +1817,14 @@ void ProcessInput(PLAYER *pPlayer) int key = pXWall->key; if (pXWall->locked && pPlayer == gMe) { - viewSetMessage("It's locked"); + viewSetMessage(GStrings("TXTB_LOCKED")); sndStartSample(3062, 255, 2, 0); } if (!key || pPlayer->hasKey[key]) trTriggerWall(a2, pXWall, kCmdWallPush, pPlayer->nSprite); else if (pPlayer == gMe) { - viewSetMessage("That requires a key."); + viewSetMessage(GStrings("TXTB_KEY")); sndStartSample(3063, 255, 2, 0); } break; @@ -1838,7 +1839,7 @@ void ProcessInput(PLAYER *pPlayer) trTriggerSprite(a2, pXSprite, kCmdSpritePush, pPlayer->nSprite); else if (pPlayer == gMe) { - viewSetMessage("That requires a key."); + viewSetMessage(GStrings("TXTB_KEY")); sndStartSample(3063, 255, 2, 0); } break; @@ -2157,7 +2158,7 @@ void playerFrag(PLAYER *pKiller, PLAYER *pVictim) int nSound = gSuicide[nMessage].at4; if (pVictim == gMe && gMe->handTime <= 0) { - sprintf(buffer, "You killed yourself!"); + sprintf(buffer, GStrings("TXTB_KILLSELF")); if (gGameOptions.nGameType > 0 && nSound >= 0) sndStartSample(nSound, 255, 2, 0); } @@ -2487,7 +2488,7 @@ void PlayerSurvive(int, int nXSprite) { PLAYER *pPlayer = &gPlayer[pSprite->type-kDudePlayer1]; if (pPlayer == gMe) - viewSetMessage("I LIVE...AGAIN!!"); + viewSetMessage(GStrings("TXT_LIVEAGAIM")); else { sprintf(buffer, "%s lives again!", gProfile[pPlayer->nPlayer].name); diff --git a/source/blood/src/view.cpp b/source/blood/src/view.cpp index 668319b14..6b0575aab 100644 --- a/source/blood/src/view.cpp +++ b/source/blood/src/view.cpp @@ -62,6 +62,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "weapon.h" #include "zstring.h" #include "menu/menu.h" +#include "gstrings.h" CVARD(Bool, hud_powerupduration, true, CVAR_ARCHIVE|CVAR_FRONTEND_BLOOD, "enable/disable displaying the remaining seconds for power-ups") @@ -1401,7 +1402,7 @@ void viewDrawCtfHudVanilla(ClockTicks arg) int x = 1, y = 1; if (dword_21EFD0[0] == 0 || ((int)totalclock & 8)) { - viewDrawText(0, "BLUE", x, y, -128, 10, 0, 0, 256); + viewDrawText(0, GStrings("TXT_COLOR_BLUE"), x, y, -128, 10, 0, 0, 256); dword_21EFD0[0] = dword_21EFD0[0] - arg; if (dword_21EFD0[0] < 0) dword_21EFD0[0] = 0; @@ -1411,7 +1412,7 @@ void viewDrawCtfHudVanilla(ClockTicks arg) x = 319; if (dword_21EFD0[1] == 0 || ((int)totalclock & 8)) { - viewDrawText(0, "RED", x, y, -128, 7, 2, 0, 512); + viewDrawText(0, GStrings("TXT_COLOR_RED"), x, y, -128, 7, 2, 0, 512); dword_21EFD0[1] = dword_21EFD0[1] - arg; if (dword_21EFD0[1] < 0) dword_21EFD0[1] = 0; @@ -3557,7 +3558,7 @@ RORHACK: viewDrawAimedPlayerName(); if (gPaused) { - viewDrawText(1, "PAUSED", 160, 10, 0, 0, 1, 0); + viewDrawText(1, GStrings("TXTB_PAUSED"), 160, 10, 0, 0, 1, 0); } else if (gView != gMe) { @@ -3640,7 +3641,7 @@ void viewLoadingScreenUpdate(const char *pzText4, int nPercent) if (nPercent != -1) TileHGauge(2260, 86, 110, nPercent, 100, 0, 131072); - viewDrawText(3, "Please Wait", 160, 134, -128, 0, 1, 1); + viewDrawText(3, GStrings("TXTB_PLSWAIT"), 160, 134, -128, 0, 1, 1); } void viewLoadingScreen(int nTile, const char *pText, const char *pText2, const char *pText3) diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index 8258acb2a..2a52ac741 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -284,9 +284,9 @@ void SetDefaultStrings() //Set a few quotes which are used for common handling of a few status messages quoteMgr.InitializeQuote(23, "$MESSAGES: ON"); - quoteMgr.InitializeQuote(24, "$MESSAGES:OFF"); - quoteMgr.InitializeQuote(83, "$MAPFOLLOWOFF"); - quoteMgr.InitializeQuote(84, "$MAPFOLLOWON"); + quoteMgr.InitializeQuote(24, "$MESSAGES: OFF"); + quoteMgr.InitializeQuote(83, "$FOLLOW MODE OFF"); + quoteMgr.InitializeQuote(84, "$FOLLOW MODE ON"); quoteMgr.InitializeQuote(85, "$AUTORUNOFF"); quoteMgr.InitializeQuote(86, "$AUTORUNON"); #if 0 // todo: print a message From ba978ab0d9b5db5ea180b21956477b2b8a147f31 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Dec 2019 17:17:15 +0100 Subject: [PATCH 174/203] - text update and missing includes. --- source/duke3d/src/premap.cpp | 1 + source/rr/src/premap.cpp | 1 + source/sw/src/game.cpp | 2 +- wadsrc/static/demolition/language.csv | 277 ++++++++++++++++++++------ 4 files changed, 224 insertions(+), 57 deletions(-) diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index 0043a2659..8c5f3aa9b 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "duke3d.h" #include "menus.h" #include "savegame.h" +#include "statistics.h" #include "menu/menu.h" BEGIN_DUKE_NS diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index 43bacd77b..f06317f25 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "demo.h" #include "savegame.h" #include "cmdline.h" +#include "statistics.h" #include "menu/menu.h" BEGIN_RR_NS diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 9fd7f7b56..28109b1d5 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -938,7 +938,7 @@ bool InitGame() if (UserMapName[0] == '\0') { AnimateCacheCursor(); - if (!LoadLevel("$dozer.map")) return false + if (!LoadLevel("$dozer.map")) return false; AnimateCacheCursor(); SetupPreCache(); DoTheCache(); diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index 9b3848634..6b814cc19 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -876,8 +876,8 @@ Weapon Mode On,WEAPON MODE ON,,,,,,,,,,,,,,,,,,,,,, Weapon Mode Off,WEAPON MODE OFF,,,,,,,,,,,,,,,,,,,,,, Follow Mode Off,FOLLOW MODE OFF,,,,,,,,,,,,,,,,,,,,,, Follow Mode On,FOLLOW MODE ON,,,,,,,,,,,,,,,,,,,,,, -Run Mode Off,RUN MODE OFF,,,,,,,,,,,,,,,,,,,,,, -Run Mode On,RUN MODE ON,,,,,,,,,,,,,,,,,,,,,, +Run Mode Off,RUN MODE OFF,,,,,Rennen AN,,,,,,,,,,,,,,,,, +Run Mode On,RUN MODE ON,,,,,Rennen AUS,,,,,,,,,,,,,,,,, Devastator Weapon,DEVASTATOR WEAPON,,,,,,,,,,,,,,,,,,,,,, Jet Pack,JET PACK,,,,,,,,,,,,,,,,,,,,,, Airtank,AIRTANK,,,,,,,,,,,,,,,,,,,,,, @@ -1545,69 +1545,234 @@ Road Rage,ROAD RAGE,,,,,,,,,,,,,,,,,,,,,, Snake Canyon,SNAKE CANYON,,,,,,,,,,,,,,,,,,,,,, Luck Sore,LUCK SORE,,,,,,,,,,,,,,,,,,,,,, ,Route 66,,,,,,,,,,,,,,,,,,,,,, -Route 66 - Part 1,ROUTE 66 - PART 1,,,,,,,,,,,,,,,,,,,,,, -Route 66 - Part 2,ROUTE 66 - PART 2,,,,,,,,,,,,,,,,,,,,,, +Route 66 - Part 1,ROUTE 66 - PART 1,,,,,Route 66 - Teil 1,,,,,,,,,,,,,,,,, +Route 66 - Part 2,ROUTE 66 - PART 2,,,,,Route 66 - Teil 2,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,, -Hit The Road,HIT THE ROAD,,,,,,,,,,,,,,,,,,,,,, -Carnival Of Terror,CARNIVAL OF TERROR,,,,,,,,,,,,,,,,,,,,,, +Hit The Road,HIT THE ROAD,,,,,Auf Achse,,,,,,,,,,,,,,,,, +Carnival Of Terror,CARNIVAL OF TERROR,,,,,Kirmes des Terrors,,,,,,,,,,,,,,,,, Big Bertha's,BIG BERTHA'S,,,,,,,,,,,,,,,,,,,,,, -Big Billy's Brewery,BIG BILLY'S BREWERY,,,,,,,,,,,,,,,,,,,,,, -Flea Market,FLEA MARKET,,,,,,,,,,,,,,,,,,,,,, -Slaughterhouse,SLAUGHTERHOUSE,,,,,,,,,,,,,,,,,,,,,, -Fun Park,FUN PARK,,,,,,,,,,,,,,,,,,,,,, +Big Billy's Brewery,BIG BILLY'S BREWERY,,,,,Big Billys Brauerei,,,,,,,,,,,,,,,,, +Flea Market,FLEA MARKET,,,,,Flohmarkt,,,,,,,,,,,,,,,,, +Slaughterhouse,SLAUGHTERHOUSE,,,,,Schlachthaus,,,,,,,,,,,,,,,,, +Fun Park,FUN PARK,,,,,Freizeitpark,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,, Gassin' Up,GASSIN' UP,,,,,,,,,,,,,,,,,,,,,, -House Of Ill Repute,HOUSE OF ILL REPUTE,,,,,,,,,,,,,,,,,,,,,, -Mystery Dino Cave,MYSTERY DINO CAVE,,,,,,,,,,,,,,,,,,,,,, +House Of Ill Repute,HOUSE OF ILL REPUTE,,,,,Haus des miesen Rufs,,,,,,,,,,,,,,,,, +Mystery Dino Cave,MYSTERY DINO CAVE,,,,,"Geheimnisvolle Dinohöhle +",,,,,,,,,,,,,,,,, Campy Crystal Lake,CAMPY CRYSTAL LAKE,,,,,,,,,,,,,,,,,,,,,, Bigfoot Convention,BIGFOOT CONVENTION,,,,,,,,,,,,,,,,,,,,,, -Hoover Dam,HOOVER DAM,,,,,,,,,,,,,,,,,,,,,, -Oddity Museum,ODDITY MUSEUM,,,,,,,,,,,,,,,,,,,,,, +Hoover Dam,HOOVER DAM,,,,,Hoover Damm,,,,,,,,,,,,,,,,, +Oddity Museum,ODDITY MUSEUM,,,,,Kuriosiätenmuseum,,,,,,,,,,,,,,,,, ,Texts extracted from the source (Duke Nukem),,,,,,,,,,,,,,,,,,,,,, Come Get Some!,COMEGETSOME,,,,,,,,,,,,,,,,,,,,,, -On (2),TXT_ON2,,,,,,,,,,,,,,,,,,,,,, -Loading,TXT_LOADING,,,,,,,,,,,,,,,,,,,,,, -Loading User Map,TXT_LOADUM,,,,,,,,,,,,,,,,,,,,,, -Loading map,TXT_LOADMAP,,,,,,,,,,,,,,,,,,,,,, -Entering,TXT_ENTERING,,,,,,,,,,,,,,,,,,,,,, -Multiplayer Totals,Multiplayer Totals,,,,,,,,,,,,,,,,,,,,,, -Name,Name,,,,,,,,,,,,,,,,,,,,,, -Frags,Frags,,,,,,,,,,,,,,,,,,,,,, -Deaths,Deaths,,,,,,,,,,,,,,,,,,,,,, +On (2),TXT_ON2,,,,,An (2),,,,,,,,,,,,,,,,, +Loading,TXT_LOADING,,,,,Laden,,,,,,,,,,,,,,,,, +Loading User Map,TXT_LOADUM,,,,,Lade Benutzerlevel,,,,,,,,,,,,,,,,, +Loading map,TXT_LOADMAP,,,,,Lade Level,,,,,,,,,,,,,,,,, +Entering,TXT_ENTERING,,,,Vstupujete do,Betrete,,Enirante,Entrando a:,,Seuraava kohde,Niveau Suivant,Következik,Prossimo livello,突入開始,입장,Binnenkomen,Wchodzisz,Próxima fase,Próximo nível,,Следующий уровень,Следећи ниво +Multiplayer Totals,Multiplayer Totals,,,,,Mehrspielerergebnis,,,,,,,,,,,,,,,,, +Name,Name,,,,Jméno,Name,,Nomo,Nombre,,Nimi,Nom,Név,Nome,名前,이름,Naam,Nazwa,Nome,,,Имя,Име +Frags,Frags,,,,Fragy,,,Ĉesoj,Bajas,,Frägit,,Fragek,Frags,フラグ,플레이어 킬수,Frags,Fragi,,,,Фраги,Фрагови +Deaths,Deaths,,,,Smrti,Tode,,Mortoj,Muertes,,Kuolemat,Morts,Halálok,Morti,デス,사망한 횟수,Overlijden,Śmierci,Mortes,,,Смерти,Смрти Ping,Ping,,,,,,,,,,,,,,,,,,,,,, -Game Paused,Game Paused,,,,,,,,,,,,,,,,,,,,,, -Thanks to all our,Thanks to all our,,,,,,,,,,,,,,,,,,,,,, -fans for giving,fans for giving,,,,,,,,,,,,,,,,,,,,,, -us big heads.,us big heads.,,,,,,,,,,,,,,,,,,,,,, -Look for a Duke Nukem 3D,Look for a Duke Nukem 3D,,,,,,,,,,,,,,,,,,,,,, -sequel soon.,sequel soon.,,,,,,,,,,,,,,,,,,,,,, -Press any key or button to continue,Presskey,,,,,,,,,,,,,,,,,,,,,, -Kills,Kills,,,,,,,,,,,,,,,,,,,,,, -Completed,Completed,,,,,,,,,,,,,,,,,,,,,, -Your Time:,TXT_YOURTIME,,,,,,,,,,,,,,,,,,,,,, -Yer Time:,TXT_YERTIME,,,,,,,,,,,,,,,,,,,,,, -Par Time:,TXT_PARTIME,,,,,,,,,,,,,,,,,,,,,, -3D Realms' Time:,TXT_3DRTIME,,,,,,,,,,,,,,,,,,,,,, -Green Beret's Time:,TXT_3DRTIME,,"Nam, WW2GI",,,,,,,,,,,,,,,,,,,, +Game Paused,Game Paused,,,,,Spiel pausiert,,,,,,,,,,,,,,,,, +Thanks to all our,Thanks to all our,,,,,Danke an alle,,,,,,,,,,,,,,,,, +fans for giving,fans for giving,,,,,unsere Fans für,,,,,,,,,,,,,,,,, +us big heads.,us big heads.,,,,,ihre Unterstützung.,,,,,,,,,,,,,,,,, +Look for a Duke Nukem 3D,Look for a Duke Nukem 3D,,,,,Haltet bald Ausschau nach,,,,,,,,,,,,,,,,, +sequel soon.,sequel soon.,,,,,dem Duke Nukem 3D Sequel,,,,,,,,,,,,,,,,, +Press any key or button to continue,Presskey,,,,,Drüclke eine Taste um fortzufahren.,,,,,,,,,,,,,,,,, +Kills,Kills,,,,Zabití,,,Mortigoj,Asesinatos,,Tapot,Victimes,Ölések,Uccisioni,キル,킬수,Doodt,Zabójstwa,Vítimas,,,Убийства,Убиства +Completed,Completed,,,,Dokončen,Abgeschlossen,,Finita,Completado,,Suoritettu,terminé,Teljesítve,Finito,攻略,완료,Klaar,Ukończono,Finalizado,,,Уровень завершён,Ниво завршен +Your Time:,TXT_YOURTIME,,,,,Deine Zeit:,,,,,,,,,,,,,,,,, +Yer Time:,TXT_YERTIME,,,,,Deine Zeit:,,,,,,,,,,,,,,,,, +Par Time:,TXT_PARTIME,,,,,Par Zeit:,,,,,,,,,,,,,,,,, +3D Realms' Time:,TXT_3DRTIME,,,,,3D Realms Zeit:,,,,,,,,,,,,,,,,, +Green Beret's Time:,TXT_3DRTIME,,"Nam, WW2GI",,,Green Berets Zeit:,,,,,,,,,,,,,,,,, Xatrix Time:,"TXT_XTRTIME -",,,,,,,,,,,,,,,,,,,,,, -Prev Best Time:,TXT_PREVBEST,,,,,,,,,,,,,,,,,,,,,, +",,,,,Xatrix Zeit:,,,,,,,,,,,,,,,,, +Prev Best Time:,TXT_PREVBEST,,,,,Vorh. Bestzeit:,,,,,,,,,,,,,,,,, Your Best Time:,"TXT_YOURBEST -",,,,,,,,,,,,,,,,,,,,,, -New record!,TXT_NEWRECORD,,,,,,,,,,,,,,,,,,,,,, -Cheated!,TXT_CHEATED,,,,,,,,,,,,,,,,,,,,,, -Enemies Killed:,TXT_ENEMIESKILLED,,,,,,,,,,,,,,,,,,,,,, -Enemies Left:,TXT_ENEMIESLEFT,,,,,,,,,,,,,,,,,,,,,, -Varmints Killed:,TXT_VARMINTSKILLED,,,,,,,,,,,,,,,,,,,,,, -Varmints Left:,TXT_VARMINTSLEFT,,,,,,,,,,,,,,,,,,,,,, -N/A,TXT_N_A,,,,,,,,,,,,,,,,,,,,,, -Secrets Found:,TXT_SECFND,,,,,,,,,,,,,,,,,,,,,, -Secrets Missed:,TXT_SECMISS,,,,,,,,,,,,,,,,,,,,,, -Vote cast,VOTECAST,,,,,,,,,,,,,,,,,,,,,, -"Press F1 to Accept, F2 to Decline",TXT_PRESSF1_F2,,,,,,,,,,,,,,,,,,,,,, -Enterin',TXT_ENTERIN,,,,,,,,,,,,,,,,,,,,,, -Close Encounters,TXT_CLOSEENCOUNTERS,,,,,,,,,,,,,,,,,,,,,, -Enterin' User Mao,TXT_ENTRUM,,,,,,,,,,,,,,,,,,,,,, -Loadin',TXT_LOADIN,,,,,,,,,,,,,,,,,,,,,, +",,,,,Deine Bestzeit:,,,,,,,,,,,,,,,,, +New record!,TXT_NEWRECORD,,,,,"Neuer Rekord! +",,,,,,,,,,,,,,,,, +Cheated!,TXT_CHEATED,,,,,Geschummelt!,,,,,,,,,,,,,,,,, +Enemies Killed:,TXT_ENEMIESKILLED,,,,,Tote Feinde:,,,,,,,,,,,,,,,,, +Enemies Left:,TXT_ENEMIESLEFT,,,,,Lebende Feinde:,,,,,,,,,,,,,,,,, +Varmints Killed:,TXT_VARMINTSKILLED,,,,,Totes Ungeziefer:,,,,,,,,,,,,,,,,, +Varmints Left:,TXT_VARMINTSLEFT,,,,,Lebendes Ungeziefer:,,,,,,,,,,,,,,,,, +N/A,TXT_N_A,,,,,N/V,,,,,,,,,,,,,,,,, +Secrets Found:,TXT_SECFND,,,,,Gefundene Geheimnisse,,,,,,,,,,,,,,,,, +Secrets Missed:,TXT_SECMISS,,,,,Verpasste Geheimnisse,,,,,,,,,,,,,,,,, +Vote cast,VOTECAST,,,,,Stimme abgegeben,,,,,,,,,,,,,,,,, +"Press F1 to Accept, F2 to Decline",TXT_PRESSF1_F2,,,,,"Drücke F1 zum Akzeptieren, F2 zum Ablehnen",,,,,,,,,,,,,,,,, +Enterin',TXT_ENTERIN,,,,,Starte,,,,,,,,,,,,,,,,, +Close Encounters,TXT_CLOSEENCOUNTERS,,,,,Unheimliche Begegnung,,,,,,,,,,,,,,,,, +Enterin' User Map,TXT_ENTRUM,,,,,Starte Benutzerlevel,,,,,,,,,,,,,,,,, +Loadin',TXT_LOADIN,,,,,Laden,,,,,,,,,,,,,,,,, "Loading... -",TXT_LOADING...,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file +",TXT_LOADING...,,,,,Laden...,,,,,,,,,,,,,,,,, +,Blood,,,,,,,,,,,,,,,,,,,,,, +Still Kicking,STILL KICKING,,,,,Bewegt sich noch,,,,,,,,,,,,,,,,, +Pink On The Inside,PINK ON THE INSIDE,,,,,Innen noch rot,,,,,,,,,,,,,,,,, +Lightly Broiled,LIGHTLY BROILED,,,,,Leicht gegrillt,,,,,,,,,,,,,,,,, +Well Done,WELL DONE,,,,,Durchgebraten,,,,,,,,,,,,,,,,, +Extra Crispy,EXTRA CRISPY,,,,,Extra knusprig,,,,,,,,,,,,,,,,, +Auto run ON,AUTORUNON,,,,,Rennen AN,,,,,,,,,,,,,,,,, +Auto run OFF,AUTORUNOFF,,,,,Rennen AUS,,,,,,,,,,,,,,,,, +Picked up Skull Key,TXTB_ITEM01,,,,,,,,,,,,,,,,,,,,,, +Picked up Eye Key,TXTB_ITEM02,,,,,,,,,,,,,,,,,,,,,, +Picked up Fire Key,TXTB_ITEM03,,,,,,,,,,,,,,,,,,,,,, +Picked up Dagger Key,TXTB_ITEM04,,,,,,,,,,,,,,,,,,,,,, +Picked up Spider Key,TXTB_ITEM05,,,,,,,,,,,,,,,,,,,,,, +Picked up Moon Key,TXTB_ITEM06,,,,,,,,,,,,,,,,,,,,,, +Picked up Key 7,TXTB_ITEM07,,,,,,,,,,,,,,,,,,,,,, +Picked up Doctor's Bag,TXTB_ITEM08,,,,,,,,,,,,,,,,,,,,,, +Picked up Medicine Pouch,TXTB_ITEM09,,,,,,,,,,,,,,,,,,,,,, +Picked up Life Essence,TXTB_ITEM10,,,,,,,,,,,,,,,,,,,,,, +Picked up Life Seed,TXTB_ITEM11,,,,,,,,,,,,,,,,,,,,,, +Picked up Red Potion,TXTB_ITEM12,,,,,,,,,,,,,,,,,,,,,, +Picked up Feather Fall,TXTB_ITEM13,,,,,,,,,,,,,,,,,,,,,, +Picked up Limited Invisibility,TXTB_ITEM14,,,,,,,,,,,,,,,,,,,,,, +Picked up INVULNERABILITY,TXTB_ITEM15,,,,,,,,,,,,,,,,,,,,,, +Picked up Boots of Jumping,TXTB_ITEM16,,,,,,,,,,,,,,,,,,,,,, +Picked up Raven Flight,TXTB_ITEM17,,,,,,,,,,,,,,,,,,,,,, +Picked up Guns Akimbo,TXTB_ITEM18,,,,,,,,,,,,,,,,,,,,,, +Picked up Diving Suit,TXTB_ITEM19,,,,,,,,,,,,,,,,,,,,,, +Picked up Gas mask,TXTB_ITEM20,,,,,,,,,,,,,,,,,,,,,, +Picked up Clone,TXTB_ITEM21,,,,,,,,,,,,,,,,,,,,,, +Picked up Crystal Ball,TXTB_ITEM22,,,,,,,,,,,,,,,,,,,,,, +Picked up Decoy,TXTB_ITEM23,,,,,,,,,,,,,,,,,,,,,, +Picked up Doppleganger,TXTB_ITEM24,,,,,,,,,,,,,,,,,,,,,, +Picked up Reflective shots,TXTB_ITEM25,,,,,,,,,,,,,,,,,,,,,, +Picked up Beast Vision,TXTB_ITEM26,,,,,,,,,,,,,,,,,,,,,, +Picked up ShadowCloak,TXTB_ITEM27,,,,,,,,,,,,,,,,,,,,,, +Picked up Rage shroom,TXTB_ITEM28,,,,,,,,,,,,,,,,,,,,,, +Picked up Delirium Shroom,TXTB_ITEM29,,,,,,,,,,,,,,,,,,,,,, +Picked up Grow shroom,TXTB_ITEM30,,,,,,,,,,,,,,,,,,,,,, +Picked up Shrink shroom,TXTB_ITEM31,,,,,,,,,,,,,,,,,,,,,, +Picked up Death mask,TXTB_ITEM32,,,,,,,,,,,,,,,,,,,,,, +Picked up Wine Goblet,TXTB_ITEM33,,,,,,,,,,,,,,,,,,,,,, +Picked up Wine Bottle,TXTB_ITEM34,,,,,,,,,,,,,,,,,,,,,, +Picked up Skull Grail,TXTB_ITEM35,,,,,,,,,,,,,,,,,,,,,, +Picked up Silver Grail,TXTB_ITEM36,,,,,,,,,,,,,,,,,,,,,, +Picked up Tome,TXTB_ITEM37,,,,,,,,,,,,,,,,,,,,,, +Picked up Black Chest,TXTB_ITEM38,,,,,,,,,,,,,,,,,,,,,, +Picked up Wooden Chest,TXTB_ITEM39,,,,,,,,,,,,,,,,,,,,,, +Picked up Asbestos Armor,TXTB_ITEM40,,,,,,,,,,,,,,,,,,,,,, +Picked up Basic Armor,TXTB_ITEM41,,,,,,,,,,,,,,,,,,,,,, +Picked up Body Armor,TXTB_ITEM42,,,,,,,,,,,,,,,,,,,,,, +Picked up Fire Armor,TXTB_ITEM43,,,,,,,,,,,,,,,,,,,,,, +Picked up Spirit Armor,TXTB_ITEM44,,,,,,,,,,,,,,,,,,,,,, +Picked up Super Armor,TXTB_ITEM45,,,,,,,,,,,,,,,,,,,,,, +Picked up Blue Team Base,TXTB_ITEM46,,,,,,,,,,,,,,,,,,,,,, +Picked up Red Team Base,TXTB_ITEM47,,,,,,,,,,,,,,,,,,,,,, +Picked up Blue Flag,TXTB_ITEM48,,,,,,,,,,,,,,,,,,,,,, +Picked up Red Flag,TXTB_ITEM49,,,,,,,,,,,,,,,,,,,,,, +Picked up DUMMY,TXTB_ITEM50,,,,,,,,,,,,,,,,,,,,,, +Picked up Level map,TXTB_ITEM51,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Picked up Spray can,TXTB_AMMO01,,,,,,,,,,,,,,,,,,,,,, +Picked up Bundle of TNT*,TXTB_AMMO02,,,,,,,,,,,,,,,,,,,,,, +Picked up Bundle of TNT,TXTB_AMMO03,,,,,,,,,,,,,,,,,,,,,, +Picked up Case of TNT,TXTB_AMMO04,,,,,,,,,,,,,,,,,,,,,, +Picked up Proximity Detonator,TXTB_AMMO05,,,,,,,,,,,,,,,,,,,,,, +Picked up Remote Detonator,TXTB_AMMO06,,,,,,,,,,,,,,,,,,,,,, +Picked up Trapped Soul,TXTB_AMMO07,,,,,,,,,,,,,,,,,,,,,, +Picked up 4 shotgun shells,TXTB_AMMO08,,,,,,,,,,,,,,,,,,,,,, +Picked up Box of shotgun shells,TXTB_AMMO09,,,,,,,,,,,,,,,,,,,,,, +Picked up A few bullets,TXTB_AMMO10,,,,,,,,,,,,,,,,,,,,,, +Picked up Voodoo Doll,TXTB_AMMO11,,,,,,,,,,,,,,,,,,,,,, +Picked up OBSOLETE,TXTB_AMMO12,,,,,,,,,,,,,,,,,,,,,, +Picked up Full drum of bullets,TXTB_AMMO13,,,,,,,,,,,,,,,,,,,,,, +Picked up Tesla Charge,TXTB_AMMO14,,,,,,,,,,,,,,,,,,,,,, +Picked up OBSOLETE,TXTB_AMMO15,,,,,,,,,,,,,,,,,,,,,, +Picked up OBSOLETE,TXTB_AMMO16,,,,,,,,,,,,,,,,,,,,,, +Picked up Flares,TXTB_AMMO17,,,,,,,,,,,,,,,,,,,,,, +Picked up OBSOLETE,TXTB_AMMO18,,,,,,,,,,,,,,,,,,,,,, +Picked up OBSOLETE,TXTB_AMMO19,,,,,,,,,,,,,,,,,,,,,, +Picked up Gasoline Can,TXTB_AMMO20,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Picked up RANDOM,TXTB_WPN00,,,,,,,,,,,,,,,,,,,,,, +Picked up Sawed-off,TXTB_WPN01,,,,,,,,,,,,,,,,,,,,,, +Picked up Tommy Gun,TXTB_WPN02,,,,,,,,,,,,,,,,,,,,,, +Picked up Flare Pistol,TXTB_WPN03,,,,,,,,,,,,,,,,,,,,,, +Picked up Voodoo Doll,TXTB_WPN04,,,,,,,,,,,,,,,,,,,,,, +Picked up Tesla Cannon,TXTB_WPN05,,,,,,,,,,,,,,,,,,,,,, +Picked up Napalm Launcher,TXTB_WPN06,,,,,,,,,,,,,,,,,,,,,, +Picked up Pitchfork,TXTB_WPN07,,,,,,,,,,,,,,,,,,,,,, +Picked up Spray Can,TXTB_WPN08,,,,,,,,,,,,,,,,,,,,,, +Picked up Dynamite,TXTB_WPN09,,,,,,,,,,,,,,,,,,,,,, +Picked up Life Leech,TXTB_WPN10,,,,,,,,,,,,,,,,,,,,,, +It's locked,TXTB_LOCKED,,,,,,,,,,,,,,,,,,,,,, +That requires a key.,TXTB_KEY,,,,,,,,,,,,,,,,,,,,,, +%s dropped Blue Flag,"TXTB_DBF +",,,,,,,,,,,,,,,,,,,,,, +%s dropped Red Flag,TXTB_DRF,,,,,,,,,,,,,,,,,,,,,, +%s stole Blue Flag,TXTB_SBF,todo,,,,,,,,,,,,,,,,,,,,, +%s returned Blue Flag,TXTB_RBF,This looks incomplete and broken,,,,,,,,,,,,,,,,,,,,, +%s captured Red Flag!,TXTB_CRF,,,,,,,,,,,,,,,,,,,,,, +You killed yourself!,TXTB_KILLSELF,,,,,,,,,,,,,,,,,,,,,, +I LIVE...AGAIN!!,TXTB_LIVEAGAIN,,,,,,,,,,,,,,,,,,,,,, +%s lives again!,TXTB_LIVESAGAIN,,,,,,,,,,,,,,,,,,,,,, +Level Stats,TXTB_LEVELSTATS,,,,,,,,,,,,,,,,,,,,,, +>>> YOU CHEATED! <<<,TXTB_CHEATED,,,,,,,,,,,,,,,,,,,,,, +Frag Stats,TXTB_FRAGSTATS,,,,,,,,,,,,,,,,,,,,,, +Of,OF,,,,,,,,,,,,,,,,,,,,,, +A secret is revealed.,TXTB_SECRET0,,,,Tajemství odhaleno!,Ein Geheimnis wurde enthüllt!,Ένα μυστικό αποκαλύφθηκε!,Sekreto estas malkaŝita!,¡Se ha revelado un secreto!,,Sala löydetty!,Vous avez découvert un secret!,Egy rejtekhely feltárva!,È stato svelato un segreto! ,シークレットを解き明かした!,비밀 발견!,Een geheim is onthuld!,Znaleziono sekret!,Um segredo foi revelado!,,,Обнаружен тайник!,Тајна је откривена! +You found a secret.,TXTB_SECRET1,,,,,,,,,,,,,,,,,,,,,, +Secrets,TXT_SECRETS,,,,Tajemství,Geheimnisse,,Sekretoj,Secretos,,Salat,,Rejtekhelyek,Segreti,シークレット,밝혀낸 비밀,Geheimen,Sekrety,Segredos,,,Тайники,Тајне +You found a Super Secret!,TXT_SUPERSECRET,,,,,Du hast ein Supergeheimnis gefunden!,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,, +Loading Demo,TXTB_LDEMO,,,,,,,,,,,,,,,,,,,,,, +Loading Level,TXTB_LLEVEL,,,,,,,,,,,,,,,,,,,,,, +Cooperative,TXTB_NETGT1,,,,,,,,,,,,,,,,,,,,,, +Bloodbath,TXTB_NETGT2,,,,,,,,,,,,,,,,,,,,,, +Teams,TXTB_NETGT3,,,,,,,,,,,,,,,,,,,,,, +Map Follow Mode,FOLLOW MODE ON,,Blood,,,,,,,,,,,,,,,,,,,, +Map Scroll Mode,FOLLOW MODE OFF," +",Blood,,,,,,,,,,,,,,,,,,,, +You are immortal.,TXTB_GODMODE,,,,,,,,,,,,,,,,,,,,,, +You are mortal.,TXTB_NOTGODMODE,,,,,,,,,,,,,,,,,,,,,, +Paused,TXTB_PAUSED,,,,,,,,,,,,,,,,,,,,,, +Please Wait,TXTB_PLSWAIT,,,,,,,,,,,,,,,,,,,,,, +Unclipped movement.,TXTB_NOCLIP,,,,,,,,,,,,,,,,,,,,,, +Normal movement.,TXTB_NOCLIPOFF,,,,,,,,,,,,,,,,,,,,,, +You have full ammo.,TXTB_FULLAMMO,,,,,,,,,,,,,,,,,,,,,, +You have no ammo.,TXTB_NOAMMO,,,,,,,,,,,,,,,,,,,,,, +You have all weapons.,TXTB_ALLWEAP,,,,,,,,,,,,,,,,,,,,,, +You have no weapons.,TXTB_NOWEAP,,,,,,,,,,,,,,,,,,,,,, +Your inventory is full.,TXTB_FULLINV,,,,,,,,,,,,,,,,,,,,,, +Your inventory is empty.,TXTB_NOINV,,,,,,,,,,,,,,,,,,,,,, +You have full armor.,TXTB_FULLARM,,,,,,,,,,,,,,,,,,,,,, +You have no armor.,TXTB_NOARM,,,,,,,,,,,,,,,,,,,,,, +You have all keys.,TXTB_ALLKEYS,,,,,,,,,,,,,,,,,,,,,, +You have no keys.,TXTB_NOKEYS,,,,,,,,,,,,,,,,,,,,,, +You have infinite ammo.,TXTB_INFAMMO,,,,,,,,,,,,,,,,,,,,,, +You have limited ammo.,TXTB_LIMAMO,,,,,,,,,,,,,,,,,,,,,, +You have the map.,TXTB_ALLMAP,,,,,,,,,,,,,,,,,,,,,, +You have no map.,TXTB_NOALLMAP,,,,,,,,,,,,,,,,,,,,,, +You have no Jumping Boots.,TXTB_JBOOTS,,,,,,,,,,,,,,,,,,,,,, +You have the Jumping Boots.,TXTB_NOJBOOTS,,,,,,,,,,,,,,,,,,,,,, +You are visible.,TXTB_VISIBLE,,,,,,,,,,,,,,,,,,,,,, +You are invisible.,TXTB_INVISIBLE,,,,,,,,,,,,,,,,,,,,,, +You are vulnerable.,TXTB_VULN,,,,,,,,,,,,,,,,,,,,,, +You are invulnerable.,TXTB_INVULN,,,,,,,,,,,,,,,,,,,,,, +You are not delirious.,TXTB_NODELIR,,,,,,,,,,,,,,,,,,,,,, +You are delirious.,TXTB_DELIR,,,,,,,,,,,,,,,,,,,,,, +Kevorkian approves.,TXTB_KEVORKIAN,,,,,,,,,,,,,,,,,,,,,, +You're fired!,TXTB_FIRED,,,,,,,,,,,,,,,,,,,,,, +Ahhh...those were the days.,TXTB_THEDAYS,,,,,,,,,,,,,,,,,,,,,, +Flame retardant!,TXTB_RETARD,,,,,,,,,,,,,,,,,,,,,, +You have half armor.,TXTB_HALFARMOR,,,,,,,,,,,,,,,,,,,,,, +,Shadow Warrior,,,,,,,,,,,,,,,,,,,,,, +TXTS_EP1,Enter the Wang,,,,,,,,,,,,,,,,,,,,,, +"TXTS_EP2 +",Code of Honor,,,,,,,,,,,,,,,,,,,,,, +TXTS_EPD1,Four levels (Shareware Version),,,,,,,,,,,,,,,,,,,,,, +TXTS_EPD2,Eighteen levels (Full Version Only),,,,,,,,,,,,,,,,,,,,,, +TXTS_SK1,Tiny grasshopper,,,,,,,,,,,,,,,,,,,,,, +TXTS_SK2,I Have No Fear,,,,,,,,,,,,,,,,,,,,,, +TXTS_SK3,Who Wants Wang,,,,,,,,,,,,,,,,,,,,,, +TXTS_SK4,"No Pain, No Gain",,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file From 9134bebc4612f8772681836b40bd75162edd4e7c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Dec 2019 17:22:38 +0100 Subject: [PATCH 175/203] - use base SWCustom.txt as the default way to define stuff, instead of relying on the hard coded texts. --- .../demolition}/SWCustom.txt | 7 ------- 1 file changed, 7 deletions(-) rename wadsrc/static/filter/{shadowwarrior.shadowwarrior => shadowwarrior/demolition}/SWCustom.txt (97%) diff --git a/wadsrc/static/filter/shadowwarrior.shadowwarrior/SWCustom.txt b/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt similarity index 97% rename from wadsrc/static/filter/shadowwarrior.shadowwarrior/SWCustom.txt rename to wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt index 4372f00cc..62b54e600 100644 --- a/wadsrc/static/filter/shadowwarrior.shadowwarrior/SWCustom.txt +++ b/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt @@ -485,13 +485,6 @@ needkey "You need a BRONZE key for this door." "You need a RED key for this door." } -animation -{ - "SwpAnim.zip" // Swp1001.. 43 frames org = sw.anm - "swend.anm" // Swp2001.. 70 - "sumocinm.anm" // Swp3001.. 84 - "zfcin.anm" // Swp4001.. 142 -} theme 1 // game startup menu { song "theme.mid" From b71ef4a1400cde09b4976f374a70cfe39998c642 Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Mon, 9 Dec 2019 06:02:25 +0000 Subject: [PATCH 176/203] Fix regression in software rendering of slopes in r8363 git-svn-id: https://svn.eduke32.com/eduke32@8418 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/build/src/engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 9b1faaa1f..0daadfa45 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -159,7 +159,7 @@ int32_t globaltilesizy; int32_t globalx1, globaly2, globalx3, globaly3; int32_t sloptable[SLOPTABLESIZ]; -#define SLOPALOOKUPSIZ (MAXXDIM<<1) +#define SLOPALOOKUPSIZ 16384 static intptr_t slopalookup[SLOPALOOKUPSIZ]; // was 2048 static int32_t no_radarang2 = 0; From 0d7fc1263ec6d165596df8e5cd89edb91dc83b54 Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Mon, 9 Dec 2019 06:02:28 +0000 Subject: [PATCH 177/203] Improve diagnostic printing of slopalookup overflows git-svn-id: https://svn.eduke32.com/eduke32@8419 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/build/src/engine.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 0daadfa45..2a2e87603 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -3527,7 +3527,7 @@ static void fgrouscan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat) shy1 = y1+(shoffs>>15); if ((unsigned)shy1 >= SLOPALOOKUPSIZ-1) { - OSD_Printf("%s:%d: slopalookup[] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, sectnum); + OSD_Printf("%s:%d: slopalookup[%" PRId32 "] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, shy1, sectnum); return; } @@ -3542,10 +3542,15 @@ static void fgrouscan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat) shy1 = y1+(shoffs>>15); shy2 = y2+(shoffs>>15); - if ((unsigned)shy1 >= SLOPALOOKUPSIZ || (unsigned)shy2 >= SLOPALOOKUPSIZ) + // Ridiculously steep gradient? + if ((unsigned)shy1 >= SLOPALOOKUPSIZ) { - // Ridiculously steep gradient? - OSD_Printf("%s:%d: slopalookup[] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, sectnum); + OSD_Printf("%s:%d: slopalookup[%" PRId32 "] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, shy1, sectnum); + goto next_most; + } + if ((unsigned)shy2 >= SLOPALOOKUPSIZ) + { + OSD_Printf("%s:%d: slopalookup[%" PRId32 "] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, shy2, sectnum); goto next_most; } @@ -3832,7 +3837,7 @@ static void grouscan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat) shy1 = y1+(shoffs>>15); if ((unsigned)shy1 >= SLOPALOOKUPSIZ - 1) { - OSD_Printf("%s:%d: slopalookup[] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, sectnum); + OSD_Printf("%s:%d: slopalookup[%" PRId32 "] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, shy1, sectnum); return; } @@ -3847,10 +3852,15 @@ static void grouscan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat) shy1 = y1+(shoffs>>15); shy2 = y2+(shoffs>>15); - if ((unsigned)shy1 >= SLOPALOOKUPSIZ || (unsigned)shy2 >= SLOPALOOKUPSIZ) + // Ridiculously steep gradient? + if ((unsigned)shy1 >= SLOPALOOKUPSIZ) { - // Ridiculously steep gradient? - OSD_Printf("%s:%d: slopalookup[] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, sectnum); + OSD_Printf("%s:%d: slopalookup[%" PRId32 "] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, shy1, sectnum); + goto next_most; + } + if ((unsigned)shy2 >= SLOPALOOKUPSIZ) + { + OSD_Printf("%s:%d: slopalookup[%" PRId32 "] overflow drawing sector %d!\n", EDUKE32_FUNCTION, __LINE__, shy2, sectnum); goto next_most; } From f658b0f33d669f6c82c93cc2235d54946d9a0a71 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 8 Dec 2019 12:20:23 +0100 Subject: [PATCH 178/203] - deleted duplicated music code. Apparently this got back in with some cherry pick. --- source/zmusic/i_music.cpp | 489 ----------------------- source/zmusic/i_music.h | 53 --- source/zmusic/i_soundfont.cpp | 546 -------------------------- source/zmusic/i_soundfont.h | 165 -------- source/zmusic/music_config.cpp | 490 ----------------------- source/zmusic/music_midi_base.cpp | 229 ----------- source/zmusic/s_music.cpp | 633 ------------------------------ 7 files changed, 2605 deletions(-) delete mode 100644 source/zmusic/i_music.cpp delete mode 100644 source/zmusic/i_music.h delete mode 100644 source/zmusic/i_soundfont.cpp delete mode 100644 source/zmusic/i_soundfont.h delete mode 100644 source/zmusic/music_config.cpp delete mode 100644 source/zmusic/music_midi_base.cpp delete mode 100644 source/zmusic/s_music.cpp diff --git a/source/zmusic/i_music.cpp b/source/zmusic/i_music.cpp deleted file mode 100644 index c6d9f749c..000000000 --- a/source/zmusic/i_music.cpp +++ /dev/null @@ -1,489 +0,0 @@ -/* -** i_music.cpp -** Plays music -** -**--------------------------------------------------------------------------- -** Copyright 1998-2010 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#ifndef _WIN32 -#include -#include -#endif - -#include - -#include "m_argv.h" -#include "w_wad.h" -#include "c_dispatch.h" -#include "templates.h" -#include "stats.h" -#include "c_cvars.h" -#include "c_console.h" -#include "vm.h" -#include "v_text.h" -#include "i_sound.h" -#include "i_soundfont.h" -#include "s_music.h" -#include "doomstat.h" -#include "zmusic/zmusic.h" -#include "zmusic/musinfo.h" -#include "streamsources/streamsource.h" -#include "filereadermusicinterface.h" -#include "../libraries/zmusic/midisources/midisource.h" - - - -void I_InitSoundFonts(); - -EXTERN_CVAR (Int, snd_samplerate) -EXTERN_CVAR (Int, snd_mididevice) - -static bool ungzip(uint8_t *data, int size, std::vector &newdata); - -int nomusic = 0; - -#ifdef _WIN32 - -void I_InitMusicWin32(); - -#include "musicformats/win32/i_cd.h" -//========================================================================== -// -// CVAR: cd_drive -// -// Which drive (letter) to use for CD audio. If not a valid drive letter, -// let the operating system decide for us. -// -//========================================================================== -EXTERN_CVAR(Bool, cd_enabled); - -CUSTOM_CVAR(String, cd_drive, "", CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALCONFIG) -{ - if (cd_enabled && !Args->CheckParm("-nocdaudio")) CD_Enable(self); -} - -//========================================================================== -// -// CVAR: cd_enabled -// -// Use the CD device? Can be overridden with -nocdaudio on the command line -// -//========================================================================== - -CUSTOM_CVAR(Bool, cd_enabled, true, CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALCONFIG) -{ - if (self && !Args->CheckParm("-nocdaudio")) - CD_Enable(cd_drive); - else - CD_Enable(nullptr); -} - - -#endif - -//========================================================================== -// -// CVAR snd_musicvolume -// -// Maximum volume of MOD/stream music. -//========================================================================== - -CUSTOM_CVAR (Float, snd_musicvolume, 0.5f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (self < 0.f) - self = 0.f; - else if (self > 1.f) - self = 1.f; - else - { - // Set general music volume. - ChangeMusicSetting(ZMusic::snd_musicvolume, nullptr, self); - if (GSnd != nullptr) - { - GSnd->SetMusicVolume(clamp(self * relative_volume * snd_mastervolume, 0, 1)); - } - // For music not implemented through the digital sound system, - // let them know about the change. - if (mus_playing.handle != nullptr) - { - mus_playing.handle->MusicVolumeChanged(); - } - else - { // If the music was stopped because volume was 0, start it now. - S_RestartMusic(); - } - } -} - -//========================================================================== -// -// Callbacks for the music system. -// -//========================================================================== - -static void tim_printfunc(int type, int verbosity_level, const char* fmt, ...) -{ - if (verbosity_level >= 3/*Timidity::VERB_DEBUG*/) return; // Don't waste time on diagnostics. - - va_list args; - va_start(args, fmt); - FString msg; - msg.VFormat(fmt, args); - va_end(args); - - switch (type) - { - case 2:// Timidity::CMSG_ERROR: - Printf(TEXTCOLOR_RED "%s\n", msg.GetChars()); - break; - - case 1://Timidity::CMSG_WARNING: - Printf(TEXTCOLOR_YELLOW "%s\n", msg.GetChars()); - break; - - case 0://Timidity::CMSG_INFO: - DPrintf(DMSG_SPAMMY, "%s\n", msg.GetChars()); - break; - } -} - -static void wm_printfunc(const char* wmfmt, va_list args) -{ - Printf(TEXTCOLOR_RED); - VPrintf(PRINT_HIGH, wmfmt, args); -} - -//========================================================================== -// -// other callbacks -// -//========================================================================== - -static short* dumb_decode_vorbis_(int outlen, const void* oggstream, int sizebytes) -{ - return GSnd->DecodeSample(outlen, oggstream, sizebytes, CODEC_Vorbis); -} - -static std::string mus_NicePath(const char* str) -{ - FString strv = NicePath(str); - return strv.GetChars(); -} - -static const char* mus_pathToSoundFont(const char* sfname, int type) -{ - auto info = sfmanager.FindSoundFont(sfname, type); - return info ? info->mFilename.GetChars() : nullptr; -} - -static MusicIO::SoundFontReaderInterface* mus_openSoundFont(const char* sfname, int type) -{ - return sfmanager.OpenSoundFont(sfname, type); -} - - -//========================================================================== -// -// Pass some basic working data to the music backend -// We do this once at startup for everything available. -// -//========================================================================== - -static void SetupGenMidi() -{ - // The OPL renderer should not care about where this comes from. - // Note: No I_Error here - this needs to be consistent with the rest of the music code. - auto lump = Wads.CheckNumForName("GENMIDI", ns_global); - if (lump < 0) - { - Printf("No GENMIDI lump found. OPL playback not available."); - return; - } - auto data = Wads.OpenLumpReader(lump); - - auto genmidi = data.Read(); - if (genmidi.Size() < 8 + 175 * 36 || memcmp(genmidi.Data(), "#OPL_II#", 8)) return; - ZMusic_SetGenMidi(genmidi.Data()+8); -} - -static void SetupWgOpn() -{ - int lump = Wads.CheckNumForFullName("xg.wopn"); - if (lump < 0) - { - return; - } - FMemLump data = Wads.ReadLump(lump); - ZMusic_SetWgOpn(data.GetMem(), (uint32_t)data.GetSize()); -} - -static void SetupDMXGUS() -{ - int lump = Wads.CheckNumForFullName("DMXGUS"); - if (lump < 0) - { - return; - } - FMemLump data = Wads.ReadLump(lump); - ZMusic_SetDmxGus(data.GetMem(), (uint32_t)data.GetSize()); -} - - - -//========================================================================== -// -// -// -//========================================================================== - -void I_InitMusic (void) -{ - I_InitSoundFonts(); - - snd_musicvolume.Callback (); - - nomusic = !!Args->CheckParm("-nomusic") || !!Args->CheckParm("-nosound"); - -#ifdef _WIN32 - I_InitMusicWin32 (); -#endif // _WIN32 - - Callbacks callbacks; - - callbacks.Fluid_MessageFunc = Printf; - callbacks.GUS_MessageFunc = callbacks.Timidity_Messagefunc = tim_printfunc; - callbacks.WildMidi_MessageFunc = wm_printfunc; - callbacks.NicePath = mus_NicePath; - callbacks.PathForSoundfont = mus_pathToSoundFont; - callbacks.OpenSoundFont = mus_openSoundFont; - callbacks.DumbVorbisDecode = dumb_decode_vorbis_; - - ZMusic_SetCallbacks(&callbacks); - SetupGenMidi(); - SetupDMXGUS(); - SetupWgOpn(); -} - - -//========================================================================== -// -// -// -//========================================================================== - -void I_SetRelativeVolume(float vol) -{ - relative_volume = (float)vol; - ChangeMusicSetting(ZMusic::relative_volume, nullptr, (float)vol); - snd_musicvolume.Callback(); -} -//========================================================================== -// -// Sets relative music volume. Takes $musicvolume in SNDINFO into consideration -// -//========================================================================== - -void I_SetMusicVolume (double factor) -{ - factor = clamp(factor, 0., 2.0); - I_SetRelativeVolume((float)factor); -} - -//========================================================================== -// -// test a relative music volume -// -//========================================================================== - -CCMD(testmusicvol) -{ - if (argv.argc() > 1) - { - I_SetRelativeVolume((float)strtod(argv[1], nullptr)); - } - else - Printf("Current relative volume is %1.2f\n", relative_volume); -} - -//========================================================================== -// -// STAT music -// -//========================================================================== - -ADD_STAT(music) -{ - if (mus_playing.handle != nullptr) - { - return FString(mus_playing.handle->GetStats().c_str()); - } - return "No song playing"; -} - -//========================================================================== -// -// Common loader for the dumpers. -// -//========================================================================== - -static MIDISource *GetMIDISource(const char *fn) -{ - FString src = fn; - if (src.Compare("*") == 0) src = mus_playing.name; - - auto lump = Wads.CheckNumForName(src, ns_music); - if (lump < 0) lump = Wads.CheckNumForFullName(src); - if (lump < 0) - { - Printf("Cannot find MIDI lump %s.\n", src.GetChars()); - return nullptr; - } - - auto wlump = Wads.OpenLumpReader(lump); - - uint32_t id[32 / 4]; - - if (wlump.Read(id, 32) != 32 || wlump.Seek(-32, FileReader::SeekCur) != 0) - { - Printf("Unable to read lump %s\n", src.GetChars()); - return nullptr; - } - auto type = IdentifyMIDIType(id, 32); - if (type == MIDI_NOTMIDI) - { - Printf("%s is not MIDI-based.\n", src.GetChars()); - return nullptr; - } - - auto data = wlump.Read(); - auto source = CreateMIDISource(data.Data(), data.Size(), type); - - if (source == nullptr) - { - Printf("%s is not MIDI-based.\n", src.GetChars()); - return nullptr; - } - return source; -} - -//========================================================================== -// -// CCMD writewave -// -// If the current song can be represented as a waveform, dump it to -// the specified file on disk. The sample rate parameter is merely a -// suggestion, and the dumper is free to ignore it. -// -//========================================================================== - -UNSAFE_CCMD (writewave) -{ - if (argv.argc() >= 3 && argv.argc() <= 7) - { - auto source = GetMIDISource(argv[1]); - if (source == nullptr) return; - - EMidiDevice dev = MDEV_DEFAULT; - - if (argv.argc() >= 6) - { - if (!stricmp(argv[5], "WildMidi")) dev = MDEV_WILDMIDI; - else if (!stricmp(argv[5], "GUS")) dev = MDEV_GUS; - else if (!stricmp(argv[5], "Timidity") || !stricmp(argv[5], "Timidity++")) dev = MDEV_TIMIDITY; - else if (!stricmp(argv[5], "FluidSynth")) dev = MDEV_FLUIDSYNTH; - else if (!stricmp(argv[5], "OPL")) dev = MDEV_OPL; - else if (!stricmp(argv[5], "OPN")) dev = MDEV_OPN; - else if (!stricmp(argv[5], "ADL")) dev = MDEV_ADL; - else - { - Printf("%s: Unknown MIDI device\n", argv[5]); - return; - } - } - // We must stop the currently playing music to avoid interference between two synths. - auto savedsong = mus_playing; - S_StopMusic(true); - if (dev == MDEV_DEFAULT && snd_mididevice >= 0) dev = MDEV_FLUIDSYNTH; // The Windows system synth cannot dump a wave. - try - { - MIDIDumpWave(source, dev, argv.argc() < 6 ? nullptr : argv[6], argv[2], argv.argc() < 4 ? 0 : (int)strtol(argv[3], nullptr, 10), argv.argc() < 5 ? 0 : (int)strtol(argv[4], nullptr, 10)); - } - catch (const std::runtime_error& err) - { - Printf("MIDI dump failed: %s\n", err.what()); - } - - S_ChangeMusic(savedsong.name, savedsong.baseorder, savedsong.loop, true); - } - else - { - Printf ("Usage: writewave [subsong] [sample rate] [synth] [soundfont]\n" - " - use '*' as song name to dump the currently playing song\n" - " - use 0 for subsong and sample rate to play the default\n"); - } -} - -//========================================================================== -// -// CCMD writemidi -// -// Writes a given MIDI song to disk. This does not affect playback anymore, -// like older versions did. -// -//========================================================================== - -UNSAFE_CCMD(writemidi) -{ - if (argv.argc() != 3) - { - Printf("Usage: writemidi - use '*' as song name to dump the currently playing song\n"); - return; - } - auto source = GetMIDISource(argv[1]); - if (source == nullptr) return; - - std::vector midi; - bool success; - - source->CreateSMF(midi, 1); - auto f = FileWriter::Open(argv[2]); - if (f == nullptr) - { - Printf("Could not open %s.\n", argv[2]); - return; - } - success = (f->Write(&midi[0], midi.size()) == midi.size()); - delete f; - - if (!success) - { - Printf("Could not write to music file %s.\n", argv[2]); - } -} diff --git a/source/zmusic/i_music.h b/source/zmusic/i_music.h deleted file mode 100644 index af45ec1fe..000000000 --- a/source/zmusic/i_music.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -** i_music.h -** -**--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#ifndef __I_MUSIC_H__ -#define __I_MUSIC_H__ - -class FileReader; -struct FOptionValues; - -// -// MUSIC I/O -// -void I_InitMusic (); -void I_BuildMIDIMenuList (FOptionValues *); - -// Volume. -void I_SetRelativeVolume(float); -void I_SetMusicVolume (double volume); - - -extern int nomusic; - -#endif //__I_MUSIC_H__ diff --git a/source/zmusic/i_soundfont.cpp b/source/zmusic/i_soundfont.cpp deleted file mode 100644 index f14e53842..000000000 --- a/source/zmusic/i_soundfont.cpp +++ /dev/null @@ -1,546 +0,0 @@ -/* -** i_soundfont.cpp -** The sound font manager for the MIDI synths -** -**--------------------------------------------------------------------------- -** Copyright 2018 Christoph Oelckers -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#include -#include -#include "i_soundfont.h" -#include "i_soundinternal.h" -#include "cmdlib.h" -#include "i_system.h" -#include "gameconfigfile.h" -#include "filereadermusicinterface.h" -#include "zmusic/zmusic.h" -#include "resourcefiles/resourcefile.h" - -//========================================================================== -// -// -// -//========================================================================== - -FSoundFontManager sfmanager; - -//========================================================================== -// -// returns both a file reader and the full name of the looked up file -// -//========================================================================== - -std::pair FSoundFontReader::LookupFile(const char *name) -{ - if (!IsAbsPath(name)) - { - for(int i = mPaths.Size()-1; i>=0; i--) - { - FString fullname = mPaths[i] + name; - auto fr = OpenFile(fullname); - if (fr.isOpen()) return std::make_pair(std::move(fr), fullname); - } - } - auto fr = OpenFile(name); - if (!fr.isOpen()) name = ""; - return std::make_pair(std::move(fr), name); -} - -//========================================================================== -// -// This adds a directory to the path list -// -//========================================================================== - -void FSoundFontReader::AddPath(const char *strp) -{ - if (*strp == 0) return; - if (!mAllowAbsolutePaths && IsAbsPath(strp)) return; // of no use so we may just discard it right away - int i = 0; - FString str = strp; - FixPathSeperator(str); - if (str.Back() != '/') str += '/'; // always let it end with a slash. - for (auto &s : mPaths) - { - if (pathcmp(s.GetChars(), str) == 0) - { - // move string to the back. - mPaths.Delete(i); - mPaths.Push(str); - return; - } - i++; - } - mPaths.Push(str); -} - -int FSoundFontReader::pathcmp(const char *p1, const char *p2) -{ - return mCaseSensitivePaths? strcmp(p1, p2) : stricmp(p1, p2); -} - -//========================================================================== -// -// -// -//========================================================================== - -FileReader FSoundFontReader::Open(const char *name, std::string& filename) -{ - FileReader fr; - if (name == nullptr) - { - fr = OpenMainConfigFile(); - filename = MainConfigFileName(); - } - else - { - auto res = LookupFile(name); - fr = std::move(res.first); - filename = res.second; - } - return fr; -} - -//========================================================================== -// -// -// -//========================================================================== - -MusicIO::FileInterface* FSoundFontReader::open_interface(const char* name) -{ - std::string filename; - - FileReader fr = Open(name, filename); - if (!fr.isOpen()) return nullptr; - auto fri = new FileReaderMusicInterface(fr); - fri->filename = std::move(filename); - return fri; -} - - -//========================================================================== -// -// The file interface for the backend -// -//========================================================================== - -struct MusicIO::FileInterface* FSoundFontReader::open_file(const char* name) -{ - return open_interface(name); -} - - -//========================================================================== -// -// Note that the file type has already been checked -// -//========================================================================== - -FSF2Reader::FSF2Reader(const char *fn) -{ - mMainConfigForSF2.Format("soundfont \"%s\"\n", fn); - mFilename = fn; -} - -//========================================================================== -// -// -// -//========================================================================== - -FileReader FSF2Reader::OpenMainConfigFile() -{ - FileReader fr; - if (mMainConfigForSF2.IsNotEmpty()) - { - fr.OpenMemory(mMainConfigForSF2.GetChars(), mMainConfigForSF2.Len()); - } - return fr; -} - -FileReader FSF2Reader::OpenFile(const char *name) -{ - FileReader fr; - if (mFilename.CompareNoCase(name) == 0) - { - fr.OpenFile(name); - } - return fr; -} - -//========================================================================== -// -// -// -//========================================================================== - -FZipPatReader::FZipPatReader(const char *filename) -{ - resf = FResourceFile::OpenResourceFile(filename, true); -} - -FZipPatReader::~FZipPatReader() -{ - if (resf != nullptr) delete resf; -} - -FileReader FZipPatReader::OpenMainConfigFile() -{ - return OpenFile("timidity.cfg"); -} - -FileReader FZipPatReader::OpenFile(const char *name) -{ - FileReader fr; - if (resf != nullptr) - { - auto lump = resf->FindLump(name); - if (lump != nullptr) - { - return lump->NewReader(); - } - } - return fr; -} - -//========================================================================== -// -// -// -//========================================================================== - -FPatchSetReader::FPatchSetReader(const char *filename) -{ -#ifndef _WIN32 - mCaseSensitivePaths = true; - const char *paths[] = { - "/usr/local/lib/timidity", - "/etc/timidity", - "/etc" - }; -#else - const char *paths[] = { - "C:/TIMIDITY", - "/TIMIDITY", - progdir - }; -#endif - mAllowAbsolutePaths = true; - FileReader fr; - if (fr.OpenFile(filename)) - { - mFullPathToConfig = filename; - } - else if (!IsAbsPath(filename)) - { - for(auto c : paths) - { - FStringf fullname("%s/%s", c, filename); - if (fr.OpenFile(fullname)) - { - mFullPathToConfig = fullname; - } - } - } - if (mFullPathToConfig.Len() > 0) - { - FixPathSeperator(mFullPathToConfig); - mBasePath = ExtractFilePath(mFullPathToConfig); - if (mBasePath.Len() > 0 && mBasePath.Back() != '/') mBasePath += '/'; - } -} - - -FileReader FPatchSetReader::OpenMainConfigFile() -{ - FileReader fr; - fr.OpenFile(mFullPathToConfig); - return fr; -} - -FileReader FPatchSetReader::OpenFile(const char *name) -{ - FString path; - if (IsAbsPath(name)) path = name; - else path = mBasePath + name; - FileReader fr; - fr.OpenFile(path); - return fr; -} - -//========================================================================== -// -// -// -//========================================================================== - -FLumpPatchSetReader::FLumpPatchSetReader(const char *filename) -{ - mLumpIndex = Wads.CheckNumForFullName(filename); - - mBasePath = filename; - FixPathSeperator(mBasePath); - mBasePath = ExtractFilePath(mBasePath); - if (mBasePath.Len() > 0 && mBasePath.Back() != '/') mBasePath += '/'; -} - -FileReader FLumpPatchSetReader::OpenMainConfigFile() -{ - return Wads.ReopenLumpReader(mLumpIndex); -} - -FileReader FLumpPatchSetReader::OpenFile(const char *name) -{ - FString path; - if (IsAbsPath(name)) return FileReader(); // no absolute paths in the lump directory. - path = mBasePath + name; - auto index = Wads.CheckNumForFullName(path); - if (index < 0) return FileReader(); - return Wads.ReopenLumpReader(index); -} - -//========================================================================== -// -// collects everything out of the soundfonts directory. -// This may either be .sf2 files or zipped GUS patch sets with a -// 'timidity.cfg' in the root directory. -// Other compression types are not supported, in particular not 7z because -// due to the solid nature of its archives would be too slow. -// -//========================================================================== - -void FSoundFontManager::ProcessOneFile(const FString &fn) -{ - auto fb = ExtractFileBase(fn, false); - auto fbe = ExtractFileBase(fn, true); - for (auto &sfi : soundfonts) - { - // We already got a soundfont with this name. Do not add again. - if (!sfi.mName.CompareNoCase(fb)) return; - } - - FileReader fr; - if (fr.OpenFile(fn)) - { - // Try to identify. We only accept .sf2 and .zip by content. All other archives are intentionally ignored. - char head[16] = { 0}; - fr.Read(head, 16); - if (!memcmp(head, "RIFF", 4) && !memcmp(head+8, "sfbkLIST", 8)) - { - FSoundFontInfo sft = { fb, fbe, fn, SF_SF2 }; - soundfonts.Push(sft); - } - if (!memcmp(head, "WOPL3-BANK\0", 11)) - { - FSoundFontInfo sft = { fb, fbe, fn, SF_WOPL }; - soundfonts.Push(sft); - } - if (!memcmp(head, "WOPN2-BANK\0", 11) || !memcmp(head, "WOPN2-B2NK\0", 11)) - { - FSoundFontInfo sft = { fb, fbe, fn, SF_WOPN }; - soundfonts.Push(sft); - } - else if (!memcmp(head, "PK", 2)) - { - auto zip = FResourceFile::OpenResourceFile(fn, true); - if (zip != nullptr) - { - if (zip->LumpCount() > 1) // Anything with just one lump cannot possibly be a packed GUS patch set so skip it right away and simplify the lookup code - { - auto zipl = zip->FindLump("timidity.cfg"); - if (zipl != nullptr) - { - // It seems like this is what we are looking for - FSoundFontInfo sft = { fb, fbe, fn, SF_GUS }; - soundfonts.Push(sft); - } - } - delete zip; - } - } - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FSoundFontManager::CollectSoundfonts() -{ - findstate_t c_file; - void *file; - - if (GameConfig != NULL && GameConfig->SetSection ("SoundfontSearch.Directories")) - { - const char *key; - const char *value; - - while (GameConfig->NextInSection (key, value)) - { - if (stricmp (key, "Path") == 0) - { - FString dir; - - dir = NicePath(value); - FixPathSeperator(dir); - if (dir.IsNotEmpty()) - { - if (dir.Back() != '/') dir += '/'; - FString mask = dir + '*'; - if ((file = I_FindFirst(mask, &c_file)) != ((void *)(-1))) - { - do - { - if (!(I_FindAttr(&c_file) & FA_DIREC)) - { - FStringf name("%s%s", dir.GetChars(), I_FindName(&c_file)); - ProcessOneFile(name); - } - } while (I_FindNext(file, &c_file) == 0); - I_FindClose(file); - } - } - } - } - } - - if (soundfonts.Size() == 0) - { - ProcessOneFile(NicePath("$PROGDIR/soundfonts/gzdoom.sf2")); - } -} - -//========================================================================== -// -// -// -//========================================================================== - -const FSoundFontInfo *FSoundFontManager::FindSoundFont(const char *name, int allowed) const -{ - for(auto &sfi : soundfonts) - { - // an empty name will pick the first one in a compatible format. - if (allowed & sfi.type && (name == nullptr || *name == 0 || !sfi.mName.CompareNoCase(name) || !sfi.mNameExt.CompareNoCase(name))) - { - return &sfi; - } - } - // We did not find what we were looking for. Let's just return the first valid item that works with the given device. - for (auto &sfi : soundfonts) - { - if (allowed & sfi.type) - { - return &sfi; - } - } - return nullptr; -} - -//========================================================================== -// -// -// -//========================================================================== - -FSoundFontReader *FSoundFontManager::OpenSoundFont(const char *name, int allowed) -{ - - // First check if the given name is inside the loaded resources. - // To avoid clashes this will only be done if the name has the '.cfg' extension. - // Sound fonts cannot be loaded this way. - if (name != nullptr) - { - const char *p = name + strlen(name) - 4; - if (p > name && !stricmp(p, ".cfg") && Wads.CheckNumForFullName(name) >= 0) - { - return new FLumpPatchSetReader(name); - } - } - - auto sfi = FindSoundFont(name, allowed); - if (sfi != nullptr) - { - if (sfi->type == SF_SF2) return new FSF2Reader(sfi->mFilename); - else return new FZipPatReader(sfi->mFilename); - } - // The sound font collection did not yield any good results. - // Next check if the file is a .sf file - if (allowed & SF_SF2) - { - FileReader fr; - if (fr.OpenFile(name)) - { - char head[16] = { 0}; - fr.Read(head, 16); - fr.Close(); - if (!memcmp(head, "RIFF", 4) && !memcmp(head+8, "sfbkLIST", 8)) - { - return new FSF2Reader(name); - } - } - } - if (allowed & SF_GUS) - { - FileReader fr; - if (fr.OpenFile(name)) - { - char head[16] = { 0 }; - fr.Read(head, 2); - fr.Close(); - if (!memcmp(head, "PK", 2)) // The only reason for this check is to block non-Zips. The actual validation will be done by FZipFile. - { - auto r = new FZipPatReader(name); - if (r->isOk()) return r; - delete r; - } - } - - // Config files are only accepted if they are named '.cfg', because they are impossible to validate. - const char *p = name + strlen(name) - 4; - if (p > name && !stricmp(p, ".cfg") && FileExists(name)) - { - return new FPatchSetReader(name); - } - } - return nullptr; - -} - -void I_InitSoundFonts() -{ - sfmanager.CollectSoundfonts(); -} - - diff --git a/source/zmusic/i_soundfont.h b/source/zmusic/i_soundfont.h deleted file mode 100644 index 76e20d1b1..000000000 --- a/source/zmusic/i_soundfont.h +++ /dev/null @@ -1,165 +0,0 @@ -#pragma once - -#include "doomtype.h" -#include "w_wad.h" -#include "files.h" -#include "filereadermusicinterface.h" - -struct FSoundFontInfo -{ - FString mName; // This is what the sounfont is identified with. It's the extension-less base file name - FString mNameExt; // Same with extension. Used for comparing with input names so they can be done with or without extension. - FString mFilename; // Full path to the backing file - this is needed by FluidSynth to load the sound font. - int type; -}; - -//========================================================================== -// -// -// -//========================================================================== - -class FSoundFontReader : public MusicIO::SoundFontReaderInterface -// Yes, it's 3 copies of essentially the same interface, but since we want to keep the 3 renderers as isolated modules we have to pull in their own implementations here. -{ -protected: - // This is only doable for loose config files that get set as sound fonts. All other cases read from a contained environment where this does not apply. - bool mAllowAbsolutePaths = false; - // This has only meaning if being run on a platform with a case sensitive file system and loose files. - // When reading from an archive it will always be case insensitive, just like the lump manager. - bool mCaseSensitivePaths = false; - TArray mPaths; - - - int pathcmp(const char *p1, const char *p2); - - -public: - - virtual ~FSoundFontReader() {} - virtual FileReader OpenMainConfigFile() = 0; // this is special because it needs to be synthesized for .sf files and set some restrictions for patch sets - virtual FString MainConfigFileName() - { - return basePath() + "timidity.cfg"; - } - - virtual FileReader OpenFile(const char *name) = 0; - std::pair LookupFile(const char *name); - void AddPath(const char *str); - virtual FString basePath() const - { - return ""; // archived patch sets do not use paths - } - - virtual FileReader Open(const char* name, std::string &filename); - - // Timidity++ interface - struct MusicIO::FileInterface* open_file(const char* name) override; - void add_search_path(const char* name) override - { - return AddPath(name); - } - - MusicIO::FileInterface* open_interface(const char* name); - -}; - -//========================================================================== -// -// -// -//========================================================================== - -class FSF2Reader : public FSoundFontReader -{ - FString mMainConfigForSF2; - FString mFilename; -public: - FSF2Reader(const char *filename); - virtual FileReader OpenMainConfigFile() override; - virtual FileReader OpenFile(const char *name) override; -}; - -//========================================================================== -// -// -// -//========================================================================== - -class FZipPatReader : public FSoundFontReader -{ - FResourceFile *resf; -public: - FZipPatReader(const char *filename); - ~FZipPatReader(); - virtual FileReader OpenMainConfigFile() override; - virtual FileReader OpenFile(const char *name) override; - bool isOk() { return resf != nullptr; } -}; - -//========================================================================== -// -// -// -//========================================================================== - -class FLumpPatchSetReader : public FSoundFontReader -{ - int mLumpIndex;; - FString mBasePath; - -public: - FLumpPatchSetReader(const char *filename); - virtual FileReader OpenMainConfigFile() override; - virtual FileReader OpenFile(const char *name) override; - virtual FString basePath() const override - { - return mBasePath; - } - -}; - -//========================================================================== -// -// -// -//========================================================================== - -class FPatchSetReader : public FSoundFontReader -{ - FString mBasePath; - FString mFullPathToConfig; - -public: - FPatchSetReader(FileReader &reader); - FPatchSetReader(const char *filename); - virtual FileReader OpenMainConfigFile() override; - virtual FileReader OpenFile(const char *name) override; - virtual FString basePath() const override - { - return mBasePath; - } -}; - -//========================================================================== -// -// -// -//========================================================================== - -class FSoundFontManager -{ - TArray soundfonts; - - void ProcessOneFile(const FString & fn); - -public: - void CollectSoundfonts(); - const FSoundFontInfo *FindSoundFont(const char *name, int allowedtypes) const; - FSoundFontReader *OpenSoundFont(const char *name, int allowedtypes); - const auto &GetList() const { return soundfonts; } // This is for the menu - -}; - - -extern FSoundFontManager sfmanager; diff --git a/source/zmusic/music_config.cpp b/source/zmusic/music_config.cpp deleted file mode 100644 index 47486e8a3..000000000 --- a/source/zmusic/music_config.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/* -** music_config.cpp -** This forwards all CVAR changes to the music system. -** -**--------------------------------------------------------------------------- -** Copyright 1999-2016 Randy Heit -** Copyright 2005-2019 Christoph Oelckers -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#include -#include -#include -#include "c_cvars.h" -#include "s_music.h" -#include "zmusic/zmusic.h" - -//========================================================================== -// -// ADL Midi device -// -//========================================================================== - -#define FORWARD_CVAR(key) \ - decltype(*self) newval; \ - auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle, *self, &newval); \ - self = (decltype(*self))newval; \ - if (ret) S_MIDIDeviceChanged(-1, true); - -#define FORWARD_BOOL_CVAR(key) \ - int newval; \ - auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle,*self, &newval); \ - self = !!newval; \ - if (ret) S_MIDIDeviceChanged(-1, true); - -#define FORWARD_STRING_CVAR(key) \ - auto ret = ChangeMusicSetting(ZMusic::key, mus_playing.handle,*self); \ - if (ret) S_MIDIDeviceChanged(-1, true); - - -CUSTOM_CVAR(Int, adl_chips_count, 6, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(adl_chips_count); -} - -CUSTOM_CVAR(Int, adl_emulator_id, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(adl_emulator_id); -} - -CUSTOM_CVAR(Bool, adl_run_at_pcm_rate, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(adl_run_at_pcm_rate); -} - -CUSTOM_CVAR(Bool, adl_fullpan, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(adl_fullpan); -} - -CUSTOM_CVAR(Int, adl_bank, 14, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(adl_bank); -} - -CUSTOM_CVAR(Bool, adl_use_custom_bank, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(adl_use_custom_bank); -} - -CUSTOM_CVAR(String, adl_custom_bank, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_STRING_CVAR(adl_custom_bank); -} - -CUSTOM_CVAR(Int, adl_volume_model, 3/*ADLMIDI_VolumeModel_DMX*/, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(adl_bank); -} - -//========================================================================== -// -// Fluidsynth MIDI device -// -//========================================================================== - -CUSTOM_CVAR(String, fluid_lib, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_STRING_CVAR(fluid_lib); -} - -CUSTOM_CVAR(String, fluid_patchset, "gzdoom", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_STRING_CVAR(fluid_patchset); -} - -CUSTOM_CVAR(Float, fluid_gain, 0.5, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_gain); -} - -CUSTOM_CVAR(Bool, fluid_reverb, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(fluid_reverb); -} - -CUSTOM_CVAR(Bool, fluid_chorus, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(fluid_chorus); -} - -CUSTOM_CVAR(Int, fluid_voices, 128, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_voices); -} - -CUSTOM_CVAR(Int, fluid_interp, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_interp); -} - -CUSTOM_CVAR(Int, fluid_samplerate, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_samplerate); -} - -CUSTOM_CVAR(Int, fluid_threads, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_threads); -} - -CUSTOM_CVAR(Float, fluid_reverb_roomsize, 0.61f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_reverb_roomsize); -} - -CUSTOM_CVAR(Float, fluid_reverb_damping, 0.23f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_reverb_damping); -} - -CUSTOM_CVAR(Float, fluid_reverb_width, 0.76f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_reverb_width); -} - -CUSTOM_CVAR(Float, fluid_reverb_level, 0.57f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_reverb_level); -} - -CUSTOM_CVAR(Int, fluid_chorus_voices, 3, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_chorus_voices); -} - -CUSTOM_CVAR(Float, fluid_chorus_level, 1.2f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_chorus_level); -} - -CUSTOM_CVAR(Float, fluid_chorus_speed, 0.3f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_chorus_speed); -} - -// depth is in ms and actual maximum depends on the sample rate -CUSTOM_CVAR(Float, fluid_chorus_depth, 8, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_chorus_depth); -} - -CUSTOM_CVAR(Int, fluid_chorus_type, 0/*FLUID_CHORUS_DEFAULT_TYPE*/, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(fluid_chorus_type); -} - - -//========================================================================== -// -// OPL MIDI device -// -//========================================================================== - -CUSTOM_CVAR(Int, opl_numchips, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(opl_numchips); -} - -CUSTOM_CVAR(Int, opl_core, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(opl_core); -} - -CUSTOM_CVAR(Bool, opl_fullpan, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(opl_fullpan); -} - -//========================================================================== -// -// OPN MIDI device -// -//========================================================================== - - -CUSTOM_CVAR(Int, opn_chips_count, 8, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(opn_chips_count); -} - -CUSTOM_CVAR(Int, opn_emulator_id, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(opn_emulator_id); -} - -CUSTOM_CVAR(Bool, opn_run_at_pcm_rate, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(opn_run_at_pcm_rate); -} - -CUSTOM_CVAR(Bool, opn_fullpan, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(opn_fullpan); -} - -CUSTOM_CVAR(Bool, opn_use_custom_bank, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(opn_use_custom_bank); -} - -CUSTOM_CVAR(String, opn_custom_bank, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_STRING_CVAR(opn_custom_bank); -} - -//========================================================================== -// -// GUS MIDI device -// -//========================================================================== - - -CUSTOM_CVAR(String, midi_config, "gzdoom", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_STRING_CVAR(gus_config); -} - -CUSTOM_CVAR(Bool, midi_dmxgus, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) // This was 'true' but since it requires special setup that's not such a good idea. -{ - FORWARD_BOOL_CVAR(gus_dmxgus); -} - -CUSTOM_CVAR(String, gus_patchdir, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_STRING_CVAR(gus_patchdir); -} - -CUSTOM_CVAR(Int, midi_voices, 32, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(gus_midi_voices); -} - -CUSTOM_CVAR(Int, gus_memsize, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(gus_memsize); -} - -//========================================================================== -// -// Timidity++ device -// -//========================================================================== - -CUSTOM_CVAR(Bool, timidity_modulation_wheel, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(timidity_modulation_wheel); -} - -CUSTOM_CVAR(Bool, timidity_portamento, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(timidity_portamento); -} - -CUSTOM_CVAR(Int, timidity_reverb, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(timidity_reverb); -} - -CUSTOM_CVAR(Int, timidity_reverb_level, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(timidity_reverb_level); -} - -CUSTOM_CVAR(Int, timidity_chorus, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(timidity_chorus); -} - -CUSTOM_CVAR(Bool, timidity_surround_chorus, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(timidity_surround_chorus); -} - -CUSTOM_CVAR(Bool, timidity_channel_pressure, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(timidity_channel_pressure); -} - -CUSTOM_CVAR(Int, timidity_lpf_def, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(timidity_lpf_def); -} - -CUSTOM_CVAR(Bool, timidity_temper_control, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(timidity_temper_control); -} - -CUSTOM_CVAR(Bool, timidity_modulation_envelope, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(timidity_modulation_envelope); -} - -CUSTOM_CVAR(Bool, timidity_overlap_voice_allow, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(timidity_overlap_voice_allow); -} - -CUSTOM_CVAR(Bool, timidity_drum_effect, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(timidity_drum_effect); -} - -CUSTOM_CVAR(Bool, timidity_pan_delay, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(timidity_pan_delay); -} - -CUSTOM_CVAR(Float, timidity_drum_power, 1.0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) /* coef. of drum amplitude */ -{ - FORWARD_CVAR(timidity_drum_power); -} - -CUSTOM_CVAR(Int, timidity_key_adjust, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(timidity_key_adjust); -} - -CUSTOM_CVAR(Float, timidity_tempo_adjust, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(timidity_tempo_adjust); -} - -CUSTOM_CVAR(Float, min_sustain_time, 5000, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(min_sustain_time); -} - -CUSTOM_CVAR(String, timidity_config, "gzdoom", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_STRING_CVAR(timidity_config); -} - -//========================================================================== -// -// WildMidi -// -//========================================================================== - -CUSTOM_CVAR(String, wildmidi_config, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_STRING_CVAR(wildmidi_config); -} - -CUSTOM_CVAR(Bool, wildmidi_reverb, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(wildmidi_reverb); -} - -CUSTOM_CVAR(Bool, wildmidi_enhanced_resampling, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(wildmidi_enhanced_resampling); -} - - -//========================================================================== -// -// This one is for Win32 MMAPI. -// -//========================================================================== - -CUSTOM_CVAR(Bool, snd_midiprecache, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(snd_midiprecache); -} - -//========================================================================== -// -// GME -// -//========================================================================== - -CUSTOM_CVAR(Float, gme_stereodepth, 0.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(gme_stereodepth); -} - -//========================================================================== -// -// sndfile -// -//========================================================================== - -CUSTOM_CVAR(Int, snd_streambuffersize, 64, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(snd_streambuffersize); -} - -//========================================================================== -// -// Dumb -// -//========================================================================== - -CUSTOM_CVAR(Int, mod_samplerate, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(mod_samplerate); -} - -CUSTOM_CVAR(Int, mod_volramp, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(mod_volramp); -} - -CUSTOM_CVAR(Int, mod_interp, 2/*DUMB_LQ_CUBIC*/, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(mod_interp); -} - -CUSTOM_CVAR(Bool, mod_autochip, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_BOOL_CVAR(mod_autochip); -} - -CUSTOM_CVAR(Int, mod_autochip_size_force, 100, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(mod_autochip_size_force); -} - -CUSTOM_CVAR(Int, mod_autochip_size_scan, 500, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(mod_autochip_size_scan); -} - -CUSTOM_CVAR(Int, mod_autochip_scan_threshold, 12, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(mod_autochip_scan_threshold); -} - -CUSTOM_CVAR(Float, mod_dumb_mastervolume, 1.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL) -{ - FORWARD_CVAR(mod_dumb_mastervolume); -} - diff --git a/source/zmusic/music_midi_base.cpp b/source/zmusic/music_midi_base.cpp deleted file mode 100644 index 6d08fe0e7..000000000 --- a/source/zmusic/music_midi_base.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* -** music_midi_base.cpp -** -**--------------------------------------------------------------------------- -** Copyright 1998-2010 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#ifdef _WIN32 - -#define WIN32_LEAN_AND_MEAN -#include -#include -#endif - -#include "c_dispatch.h" - -#include "v_text.h" -#include "menu/menu.h" -#include "zmusic/zmusic.h" -#include "s_music.h" - -static uint32_t nummididevices; -static bool nummididevicesset; - -#define NUM_DEF_DEVICES 7 - -static void AddDefaultMidiDevices(FOptionValues *opt) -{ - FOptionValues::Pair *pair = &opt->mValues[opt->mValues.Reserve(NUM_DEF_DEVICES)]; - pair[0].Text = "FluidSynth"; - pair[0].Value = -5.0; - pair[1].Text = "TiMidity++"; - pair[1].Value = -2.0; - pair[2].Text = "WildMidi"; - pair[2].Value = -6.0; - pair[3].Text = "GUS"; - pair[3].Value = -4.0; - pair[4].Text = "OPL Synth Emulation"; - pair[4].Value = -3.0; - pair[5].Text = "libADL"; - pair[5].Value = -7.0; - pair[6].Text = "libOPN"; - pair[6].Value = -8.0; - -} - -#define DEF_MIDIDEV -5 - -#ifdef _WIN32 - -#define WIN32_LEAN_AND_MEAN -#include -#include - -CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (!nummididevicesset) - return; - - if ((self >= (signed)nummididevices) || (self < -8)) - { - // Don't do repeated message spam if there is no valid device. - if (self != 0) - { - Printf("ID out of range. Using default device.\n"); - self = DEF_MIDIDEV; - } - return; - } - else if (self == -1) self = DEF_MIDIDEV; - ChangeMusicSetting(ZMusic::snd_mididevice, nullptr, self); - S_MIDIDeviceChanged(self, false); -} - -void I_InitMusicWin32 () -{ - nummididevices = midiOutGetNumDevs (); - nummididevicesset = true; - snd_mididevice.Callback (); -} - -void I_BuildMIDIMenuList (FOptionValues *opt) -{ - AddDefaultMidiDevices(opt); - - for (uint32_t id = 0; id < nummididevices; ++id) - { - MIDIOUTCAPS caps; - MMRESULT res; - - res = midiOutGetDevCaps (id, &caps, sizeof(caps)); - assert(res == MMSYSERR_NOERROR); - if (res == MMSYSERR_NOERROR) - { - FOptionValues::Pair *pair = &opt->mValues[opt->mValues.Reserve(1)]; - pair->Text = caps.szPname; - pair->Value = (float)id; - } - } -} - -static void PrintMidiDevice (int id, const char *name, uint16_t tech, uint32_t support) -{ - if (id == snd_mididevice) - { - Printf (TEXTCOLOR_BOLD); - } - Printf ("% 2d. %s : ", id, name); - switch (tech) - { - case MIDIDEV_MIDIPORT: Printf ("MIDIPORT"); break; - case MIDIDEV_SYNTH: Printf ("SYNTH"); break; - case MIDIDEV_SQSYNTH: Printf ("SQSYNTH"); break; - case MIDIDEV_FMSYNTH: Printf ("FMSYNTH"); break; - case MIDIDEV_MAPPER: Printf ("MAPPER"); break; - case MIDIDEV_WAVETABLE: Printf ("WAVETABLE"); break; - case MIDIDEV_SWSYNTH: Printf ("SWSYNTH"); break; - } - if (support & MIDICAPS_CACHE) - { - Printf (" CACHE"); - } - if (support & MIDICAPS_LRVOLUME) - { - Printf (" LRVOLUME"); - } - if (support & MIDICAPS_STREAM) - { - Printf (" STREAM"); - } - if (support & MIDICAPS_VOLUME) - { - Printf (" VOLUME"); - } - Printf (TEXTCOLOR_NORMAL "\n"); -} - -CCMD (snd_listmididevices) -{ - UINT id; - MIDIOUTCAPS caps; - MMRESULT res; - - PrintMidiDevice(-8, "libOPN", MIDIDEV_FMSYNTH, 0); - PrintMidiDevice(-7, "libADL", MIDIDEV_FMSYNTH, 0); - PrintMidiDevice (-6, "WildMidi", MIDIDEV_SWSYNTH, 0); - PrintMidiDevice (-5, "FluidSynth", MIDIDEV_SWSYNTH, 0); - PrintMidiDevice (-4, "Gravis Ultrasound Emulation", MIDIDEV_SWSYNTH, 0); - PrintMidiDevice (-3, "Emulated OPL FM Synth", MIDIDEV_FMSYNTH, 0); - PrintMidiDevice (-2, "TiMidity++", MIDIDEV_SWSYNTH, 0); - if (nummididevices != 0) - { - for (id = 0; id < nummididevices; ++id) - { - FString text; - res = midiOutGetDevCaps (id, &caps, sizeof(caps)); - if (res == MMSYSERR_NODRIVER) - text = ""; - else if (res == MMSYSERR_NOMEM) - text = ""; - else if (res == MMSYSERR_NOERROR) - text = caps.szPname; - else - continue; - - PrintMidiDevice (id, text, caps.wTechnology, caps.dwSupport); - } - } -} - -#else - -// Everything but Windows uses this code. - -CUSTOM_CVAR(Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (self < -8) - self = -8; - else if (self > -2) - self = -2; - else - { - ChangeMusicSetting(ZMusic::snd_mididevice, nullptr, self); - S_MIDIDeviceChanged(self, false); - } -} - -void I_BuildMIDIMenuList (FOptionValues *opt) -{ - AddDefaultMidiDevices(opt); -} - -CCMD (snd_listmididevices) -{ - Printf("%s-8. libOPN\n", -8 == snd_mididevice ? TEXTCOLOR_BOLD : ""); - Printf("%s-7. libADL\n", -7 == snd_mididevice ? TEXTCOLOR_BOLD : ""); - Printf("%s-6. WildMidi\n", -6 == snd_mididevice ? TEXTCOLOR_BOLD : ""); - Printf("%s-5. FluidSynth\n", -5 == snd_mididevice ? TEXTCOLOR_BOLD : ""); - Printf("%s-4. Gravis Ultrasound Emulation\n", -4 == snd_mididevice ? TEXTCOLOR_BOLD : ""); - Printf("%s-3. Emulated OPL FM Synth\n", -3 == snd_mididevice ? TEXTCOLOR_BOLD : ""); - Printf("%s-2. TiMidity++\n", -2 == snd_mididevice ? TEXTCOLOR_BOLD : ""); -} -#endif diff --git a/source/zmusic/s_music.cpp b/source/zmusic/s_music.cpp deleted file mode 100644 index 3e8a536d6..000000000 --- a/source/zmusic/s_music.cpp +++ /dev/null @@ -1,633 +0,0 @@ -//----------------------------------------------------------------------------- -// -// Copyright 1993-1996 id Software -// Copyright 1999-2016 Randy Heit -// Copyright 2002-2016 Christoph Oelckers -// -// This program 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. -// -// This program 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 this program. If not, see http://www.gnu.org/licenses/ -// -//----------------------------------------------------------------------------- -// -// DESCRIPTION: none -// -//----------------------------------------------------------------------------- - -/* For code that originates from ZDoom the following applies: -** -**--------------------------------------------------------------------------- -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#include -#include -#ifdef _WIN32 -#include -#include "musicformats/win32/i_cd.h" -#endif - -#include "i_system.h" -#include "i_sound.h" -#include "i_music.h" - -#include "s_sound.h" -#include "s_sndseq.h" -#include "c_dispatch.h" -#include "m_random.h" -#include "w_wad.h" -#include "p_local.h" -#include "doomstat.h" -#include "cmdlib.h" -#include "v_video.h" -#include "v_text.h" -#include "a_sharedglobal.h" -#include "gstrings.h" -#include "gi.h" -#include "po_man.h" -#include "serializer.h" -#include "d_player.h" -#include "g_levellocals.h" -#include "vm.h" -#include "g_game.h" -#include "atterm.h" -#include "s_music.h" -#include "filereadermusicinterface.h" -#include "zmusic/musinfo.h" -#include "zmusic/zmusic.h" - -// MACROS ------------------------------------------------------------------ - - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -extern float S_GetMusicVolume (const char *music); - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -static bool MusicPaused; // whether music is paused -MusPlayingInfo mus_playing; // music currently being played -float relative_volume = 1.f; -float saved_relative_volume = 1.0f; // this could be used to implement an ACS FadeMusic function - -DEFINE_GLOBAL_NAMED(mus_playing, musplaying); -DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, name); -DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, baseorder); -DEFINE_FIELD_X(MusPlayingInfo, MusPlayingInfo, loop); - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -// CODE -------------------------------------------------------------------- - -//========================================================================== -// -// -// -// Create a sound system stream for the currently playing song -//========================================================================== - -static std::unique_ptr musicStream; - -static bool FillStream(SoundStream* stream, void* buff, int len, void* userdata) -{ - bool written = mus_playing.handle? mus_playing.handle->ServiceStream(buff, len) : 0; - if (!written) - { - memset((char*)buff, 0, len); - return false; - } - return true; -} - - -void S_CreateStream() -{ - if (!mus_playing.handle) return; - auto fmt = mus_playing.handle->GetStreamInfo(); - if (fmt.mBufferSize > 0) - { - int flags = fmt.mNumChannels < 0 ? 0 : SoundStream::Float; - if (abs(fmt.mNumChannels) < 2) flags |= SoundStream::Mono; - - musicStream.reset(GSnd->CreateStream(FillStream, fmt.mBufferSize, flags, fmt.mSampleRate, nullptr)); - if (musicStream) musicStream->Play(true, 1); - } -} - -void S_PauseStream(bool paused) -{ - if (musicStream) musicStream->SetPaused(paused); -} - -void S_StopStream() -{ - if (musicStream) - { - musicStream->Stop(); - musicStream.reset(); - } -} - - -//========================================================================== -// -// starts playing this song -// -//========================================================================== - -static void S_StartMusicPlaying(MusInfo* song, bool loop, float rel_vol, int subsong) -{ - if (rel_vol > 0.f) - { - float factor = relative_volume / saved_relative_volume; - saved_relative_volume = rel_vol; - I_SetRelativeVolume(saved_relative_volume * factor); - } - song->Stop(); - song->Play(loop, subsong); - song->m_NotStartedYet = false; - - // Notify the sound system of the changed relative volume - snd_musicvolume.Callback(); -} - - -//========================================================================== -// -// S_PauseSound -// -// Stop music and sound effects, during game PAUSE. -//========================================================================== - -void S_PauseMusic () -{ - if (mus_playing.handle && !MusicPaused) - { - mus_playing.handle->Pause(); - S_PauseStream(true); - MusicPaused = true; - } -} - -//========================================================================== -// -// S_ResumeSound -// -// Resume music and sound effects, after game PAUSE. -//========================================================================== - -void S_ResumeMusic () -{ - if (mus_playing.handle && MusicPaused) - { - mus_playing.handle->Resume(); - S_PauseStream(false); - MusicPaused = false; - } -} - -//========================================================================== -// -// S_UpdateSound -// -//========================================================================== - -void S_UpdateMusic () -{ - if (mus_playing.handle != nullptr) - { - mus_playing.handle->Update(); - - if (!mus_playing.handle->IsPlaying()) - { - S_StopMusic(true); - } - } -} - -//========================================================================== -// -// S_Start -// -// Per level startup code. Kills playing sounds at start of level -// and starts new music. -//========================================================================== - -void S_StartMusic () -{ - // stop the old music if it has been paused. - // This ensures that the new music is started from the beginning - // if it's the same as the last one and it has been paused. - if (MusicPaused) S_StopMusic(true); - - // start new music for the level - MusicPaused = false; - - // Don't start the music if loading a savegame, because the music is stored there. - // Don't start the music if revisiting a level in a hub for the same reason. - if (!primaryLevel->IsReentering()) - { - primaryLevel->SetMusic(); - } -} - -//========================================================================== -// -// S_StartMusic -// -// Starts some music with the given name. -//========================================================================== - -bool S_StartMusic (const char *m_id) -{ - return S_ChangeMusic (m_id, 0, false); -} - -//========================================================================== -// -// S_ChangeMusic -// -// Starts playing a music, possibly looping. -// -// [RH] If music is a MOD, starts it at position order. If name is of the -// format ",CD,,[cd id]" song is a CD track, and if [cd id] is -// specified, it will only be played if the specified CD is in a drive. -//========================================================================== - -bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force) -{ - if (nomusic) return false; // skip the entire procedure if music is globally disabled. - - // allow specifying "*" as a placeholder to play the level's default music. - if (musicname != nullptr && !strcmp(musicname, "*")) - { - if (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL) - { - musicname = primaryLevel->Music; - order = primaryLevel->musicorder; - } - else - { - musicname = nullptr; - } - } - - if (musicname == nullptr || musicname[0] == 0) - { - // Don't choke if the map doesn't have a song attached - S_StopMusic (true); - mus_playing.name = ""; - mus_playing.LastSong = ""; - return true; - } - - FString DEH_Music; - if (musicname[0] == '$') - { - // handle dehacked replacement. - // Any music name defined this way needs to be prefixed with 'D_' because - // Doom.exe does not contain the prefix so these strings don't either. - const char * mus_string = GStrings[musicname+1]; - if (mus_string != nullptr) - { - DEH_Music << "D_" << mus_string; - musicname = DEH_Music; - } - } - - FName *aliasp = MusicAliases.CheckKey(musicname); - if (aliasp != nullptr) - { - if (*aliasp == NAME_None) - { - return true; // flagged to be ignored - } - musicname = aliasp->GetChars(); - } - - if (!mus_playing.name.IsEmpty() && - mus_playing.handle != nullptr && - stricmp (mus_playing.name, musicname) == 0 && - mus_playing.handle->m_Looping == looping) - { - if (order != mus_playing.baseorder) - { - if (mus_playing.handle->SetSubsong(order)) - { - mus_playing.baseorder = order; - } - } - else if (!mus_playing.handle->IsPlaying()) - { - try - { - mus_playing.handle->Play(looping, order); - S_CreateStream(); - } - catch (const std::runtime_error& err) - { - Printf("Unable to start %s: %s\n", mus_playing.name.GetChars(), err.what()); - } - - } - return true; - } - - { - int lumpnum = -1; - int length = 0; - MusInfo *handle = nullptr; - MidiDeviceSetting *devp = MidiDevices.CheckKey(musicname); - - // Strip off any leading file:// component. - if (strncmp(musicname, "file://", 7) == 0) - { - musicname += 7; - } - - FileReader reader; - if (!FileExists (musicname)) - { - if ((lumpnum = Wads.CheckNumForFullName (musicname, true, ns_music)) == -1) - { - Printf ("Music \"%s\" not found\n", musicname); - return false; - } - if (handle == nullptr) - { - if (Wads.LumpLength (lumpnum) == 0) - { - return false; - } - reader = Wads.ReopenLumpReader(lumpnum); - } - } - else - { - // Load an external file. - if (!reader.OpenFile(musicname)) - { - return false; - } - } - - // shutdown old music - S_StopMusic (true); - - // Just record it if volume is 0 - if (snd_musicvolume <= 0) - { - mus_playing.loop = looping; - mus_playing.name = musicname; - mus_playing.baseorder = order; - mus_playing.LastSong = musicname; - return true; - } - - // load & register it - if (handle != nullptr) - { - mus_playing.handle = handle; - } - else - { - try - { - auto mreader = new FileReaderMusicInterface(reader); - mus_playing.handle = ZMusic_OpenSong(mreader, devp? (EMidiDevice)devp->device : MDEV_DEFAULT, devp? devp->args.GetChars() : ""); - } - catch (const std::runtime_error& err) - { - Printf("Unable to load %s: %s\n", mus_playing.name.GetChars(), err.what()); - } - } - } - - mus_playing.loop = looping; - mus_playing.name = musicname; - mus_playing.baseorder = 0; - mus_playing.LastSong = ""; - - if (mus_playing.handle != 0) - { // play it - try - { - S_StartMusicPlaying(mus_playing.handle, looping, S_GetMusicVolume(musicname), order); - S_CreateStream(); - mus_playing.baseorder = order; - } - catch (const std::runtime_error& err) - { - Printf("Unable to start %s: %s\n", mus_playing.name.GetChars(), err.what()); - } - return true; - } - return false; -} - -//========================================================================== -// -// S_RestartMusic -// -// Must only be called from snd_reset in i_sound.cpp! -//========================================================================== - -void S_RestartMusic () -{ - if (!mus_playing.LastSong.IsEmpty()) - { - FString song = mus_playing.LastSong; - mus_playing.LastSong = ""; - S_ChangeMusic (song, mus_playing.baseorder, mus_playing.loop, true); - } -} - -//========================================================================== -// -// S_MIDIDeviceChanged -// -//========================================================================== - - -void S_MIDIDeviceChanged(int newdev, bool force) -{ - static int oldmididev = INT_MIN; - - // If a song is playing, move it to the new device. - if (oldmididev != newdev || force) - { - if (mus_playing.handle != nullptr && mus_playing.handle->IsMIDI()) - { - MusInfo* song = mus_playing.handle; - if (song->m_Status == MusInfo::STATE_Playing) - { - if (song->GetDeviceType() == MDEV_FLUIDSYNTH && force) - { - // FluidSynth must reload the song to change the patch set. - auto mi = mus_playing; - S_StopMusic(true); - S_ChangeMusic(mi.name, mi.baseorder, mi.loop); - } - else - { - song->Stop(); - S_StartMusicPlaying(song, song->m_Looping, -1, 0); - } - } - } - } - // 'force' - if (!force) oldmididev = newdev; -} - -//========================================================================== -// -// S_GetMusic -// -//========================================================================== - -int S_GetMusic (const char **name) -{ - int order; - - if (mus_playing.name.IsNotEmpty()) - { - *name = mus_playing.name; - order = mus_playing.baseorder; - } - else - { - *name = nullptr; - order = 0; - } - return order; -} - -//========================================================================== -// -// S_StopMusic -// -//========================================================================== - -void S_StopMusic (bool force) -{ - try - { - if (mus_playing.handle != nullptr) - { - S_ResumeMusic(); - S_StopStream(); - mus_playing.handle->Stop(); - delete mus_playing.handle; - mus_playing.handle = nullptr; - } - mus_playing.LastSong = std::move(mus_playing.name); - } - catch (const std::runtime_error& ) - { - //Printf("Unable to stop %s: %s\n", mus_playing.name.GetChars(), err.what()); - if (mus_playing.handle != nullptr) - { - delete mus_playing.handle; - mus_playing.handle = nullptr; - } - mus_playing.name = ""; - } -} - -//========================================================================== -// -// CCMD changemus -// -//========================================================================== - -CCMD (changemus) -{ - if (!nomusic) - { - if (argv.argc() > 1) - { - S_ChangeMusic (argv[1], argv.argc() > 2 ? atoi (argv[2]) : 0); - } - else - { - const char *currentmus = mus_playing.name.GetChars(); - if(currentmus != nullptr && *currentmus != 0) - { - Printf ("currently playing %s\n", currentmus); - } - else - { - Printf ("no music playing\n"); - } - } - } - else - { - Printf("Music is disabled\n"); - } -} - -//========================================================================== -// -// CCMD stopmus -// -//========================================================================== - -CCMD (stopmus) -{ - S_StopMusic (false); - mus_playing.LastSong = ""; // forget the last played song so that it won't get restarted if some volume changes occur -} - - -//========================================================================== -// -// -// -//========================================================================== - -CCMD(currentmusic) -{ - if (mus_playing.name.IsNotEmpty()) - { - Printf("Currently playing music '%s'\n", mus_playing.name.GetChars()); - } - else - { - Printf("Currently no music playing\n"); - } -} From 782dfcdc547b1ef40d7671648acf434bbaa0abd6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 8 Dec 2019 12:28:51 +0100 Subject: [PATCH 179/203] - changed licenses in a few files. These originated from GZDoom and originally contained original Doom code, but for Demolition the offending parts are no longer present so the ZDoom-BSD license applies now. --- source/common/console/d_event.cpp | 116 ++++++++++-------------------- source/common/console/d_event.h | 40 +---------- source/common/music/music.cpp | 34 +++------ 3 files changed, 47 insertions(+), 143 deletions(-) diff --git a/source/common/console/d_event.cpp b/source/common/console/d_event.cpp index bcb5d4024..03b424c8e 100644 --- a/source/common/console/d_event.cpp +++ b/source/common/console/d_event.cpp @@ -1,24 +1,37 @@ -//----------------------------------------------------------------------------- -// -// Copyright 1993-1996 id Software -// Copyright 1999-2016 Randy Heit -// Copyright 2002-2016 Christoph Oelckers -// -// This program 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 2 of the License, or -// (at your option) any later version. -// -// This program 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 this program. If not, see http://www.gnu.org/licenses/ -// -// -//----------------------------------------------------------------------------- +/* +** c_dispatch.cpp +** Functions for executing console commands and aliases +** +**--------------------------------------------------------------------------- +** Copyright 1998-2016 Randy Heit +** Copyright 2003-2019 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ #include "c_bind.h" #include "d_event.h" @@ -40,62 +53,6 @@ event_t events[NUM_EVENTS]; bool G_Responder (event_t *ev) { -#if 0 - // any other key pops up menu if in demos - // [RH] But only if the key isn't bound to a "special" command - if (gameaction == ga_nothing && - (demoplayback || gamestate == GS_DEMOSCREEN || gamestate == GS_TITLELEVEL)) - { - const char *cmd = Bindings.GetBind (ev->data1); - - if (ev->type == EV_KeyDown) - { - - if (!cmd || ( - strnicmp (cmd, "menu_", 5) && - stricmp (cmd, "toggleconsole") && - stricmp (cmd, "sizeup") && - stricmp (cmd, "sizedown") && - stricmp (cmd, "togglemap") && - stricmp (cmd, "spynext") && - stricmp (cmd, "spyprev") && - stricmp (cmd, "chase") && - stricmp (cmd, "+showscores") && - stricmp (cmd, "bumpgamma") && - stricmp (cmd, "screenshot"))) - { - M_StartControlPanel(true); - M_SetMenu(NAME_MainMenu, -1); - return true; - } - else - { - return - C_DoKey (ev, &Bindings, &DoubleBindings); - } - } - if (cmd && cmd[0] == '+') - return C_DoKey (ev, &Bindings, &DoubleBindings); - - return false; - } -#endif - -#if 0 - if (gamestate == GS_LEVEL) - { - if (ST_Responder (ev)) - return true; // status window ate it - if (!viewactive && primaryLevel->automap->Responder (ev, false)) - return true; // automap ate it - } - else if (gamestate == GS_FINALE) - { - if (F_Responder (ev)) - return true; // finale ate the event - } -#endif - switch (ev->type) { case EV_KeyDown: @@ -116,10 +73,11 @@ bool G_Responder (event_t *ev) #endif } - // [RH] If the view is active, give the automap a chance at - // the events *last* so that any bound keys get precedence. #if 0 + // [RH] If the view is active, give the automap a chance at + // the events *last* so that any bound keys get precedence. + // An option for later. Currently the automap is insufficiently separated from the game loop if (gamestate == GS_LEVEL && viewactive && primaryLevel->automap) return primaryLevel->automap->Responder (ev, true); #endif diff --git a/source/common/console/d_event.h b/source/common/console/d_event.h index 53f413454..5723ca3aa 100644 --- a/source/common/console/d_event.h +++ b/source/common/console/d_event.h @@ -1,36 +1,6 @@ -//----------------------------------------------------------------------------- -// -// Copyright 1993-1996 id Software -// Copyright 1999-2016 Randy Heit -// Copyright 2002-2016 Christoph Oelckers -// -// This program 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. -// -// This program 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 this program. If not, see http://www.gnu.org/licenses/ -// -//----------------------------------------------------------------------------- - - -#ifndef __D_EVENT_H__ -#define __D_EVENT_H__ - - +#pragma once #include - -// -// Event handling. -// - // Input event types. enum EGenericEvent { @@ -47,7 +17,7 @@ struct event_t { uint8_t type; uint8_t subtype; - int16_t data1; // keys / mouse/joystick buttons + int16_t data1; // keys / mouse/joystick buttons int16_t data2; int16_t data3; int x; // mouse/joystick x move @@ -61,10 +31,6 @@ void D_PostEvent (const event_t* ev); void D_RemoveNextCharEvent(); void D_ProcessEvents(void); - -// -// GLOBAL VARIABLES -// enum { NUM_EVENTS = 128 @@ -72,5 +38,3 @@ enum extern event_t events[NUM_EVENTS]; - -#endif diff --git a/source/common/music/music.cpp b/source/common/music/music.cpp index 0347cb840..340b03124 100644 --- a/source/common/music/music.cpp +++ b/source/common/music/music.cpp @@ -1,29 +1,11 @@ -//----------------------------------------------------------------------------- -// -// Copyright 1993-1996 id Software -// Copyright 1999-2016 Randy Heit -// Copyright 2002-2016 Christoph Oelckers -// -// This program 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. -// -// This program 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 this program. If not, see http://www.gnu.org/licenses/ -// -//----------------------------------------------------------------------------- -// -// DESCRIPTION: none -// -//----------------------------------------------------------------------------- - -/* For code that originates from ZDoom the following applies: +/* +** +** music.cpp +** +** music engine - borrowed from GZDoom +** +** Copyright 1999-2016 Randy Heit +** Copyright 2002-2016 Christoph Oelckers ** **--------------------------------------------------------------------------- ** From 670c8b140830174e052242b75f4962f84425365f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Dec 2019 18:40:07 +0100 Subject: [PATCH 180/203] - use the quote array to store the key, door and fortune cookie messages in Shadow Warrior. This is infinitely better than leaking char pointers. --- source/sw/src/game.h | 16 +++-- source/sw/src/rotator.cpp | 3 +- source/sw/src/scrip2.cpp | 13 ++-- source/sw/src/slidor.cpp | 3 +- source/sw/src/sprite.cpp | 47 ++------------ source/sw/src/text.cpp | 12 ---- source/sw/src/vator.cpp | 5 +- wadsrc/static/demolition/language.csv | 35 +++++++++- .../shadowwarrior/demolition/SWCustom.txt | 64 +++++++++---------- 9 files changed, 94 insertions(+), 104 deletions(-) diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 17cbc12ef..508da6686 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -961,12 +961,18 @@ extern const char *ThemeSongs[6]; // extern char EpisodeNames[3][MAX_EPISODE_NAME_LEN+2]; -#define MAX_FORTUNES 16 -extern const char *ReadFortune[MAX_FORTUNES]; -#define MAX_KEYS 8 -extern const char *KeyMsg[MAX_KEYS]; -extern const char *KeyDoorMessage[MAX_KEYS]; + +enum +{ + MAX_KEYS = 8, + MAX_FORTUNES = 16, + + QUOTE_KEYMSG = 1, + QUOTE_DOORMSG = QUOTE_KEYMSG + MAX_KEYS, + // 23+24 are reserved. + QUOTE_COOKIE = 25, +}; typedef struct { diff --git a/source/sw/src/rotator.cpp b/source/sw/src/rotator.cpp index 97cd46f1d..029656b6f 100644 --- a/source/sw/src/rotator.cpp +++ b/source/sw/src/rotator.cpp @@ -35,6 +35,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "text.h" #include "interp.h" #include "sprite.h" +#include "quotemgr.h" BEGIN_SW_NS @@ -217,7 +218,7 @@ DoRotatorMatch(PLAYERp pp, short match, SWBOOL manual) else #endif { - PutStringInfo(pp, KeyDoorMessage[key_num - 1]); + PutStringInfo(pp, quoteMgr.GetExQuote(QUOTE_DOORMSG + key_num - 1)); return -1; } } diff --git a/source/sw/src/scrip2.cpp b/source/sw/src/scrip2.cpp index f9598e064..0c4d6dde5 100644 --- a/source/sw/src/scrip2.cpp +++ b/source/sw/src/scrip2.cpp @@ -40,6 +40,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "parent.h" #include "scriptfile.h" #include "menu/menu.h" +#include "quotemgr.h" BEGIN_SW_NS @@ -538,9 +539,6 @@ static int cm_transtok(const char *tok, const struct _tokset *set, const unsigne // quit "PRESS (Y) TO QUIT, (N) TO FIGHT ON." static LEVEL_INFO custommaps[MAX_LEVELS_REG]; -static char *customfortune[MAX_FORTUNES]; -static char *customkeymsg[MAX_KEYS]; -static char *customkeydoormsg[MAX_KEYS]; static char *custominventoryname[InvDecl_TOTAL]; static char *customweaponname[2][MAX_WEAPONS]; // weapon, ammo @@ -798,8 +796,7 @@ void LoadCustomInfoFromScript(const char *filename) if (fc == MAX_FORTUNES) continue; - customfortune[fc] = strdup(t); - if (customfortune[fc]) ReadFortune[fc] = customfortune[fc]; + quoteMgr.InitializeQuote(QUOTE_COOKIE + fc, t); fc++; } break; @@ -817,8 +814,7 @@ void LoadCustomInfoFromScript(const char *filename) if (fc == MAX_KEYS) continue; - customkeymsg[fc] = strdup(t); - if (customkeymsg[fc]) KeyMsg[fc] = customkeymsg[fc]; + quoteMgr.InitializeQuote(QUOTE_KEYMSG + fc, t); fc++; } break; @@ -836,8 +832,7 @@ void LoadCustomInfoFromScript(const char *filename) if (fc == MAX_KEYS) continue; - customkeydoormsg[fc] = strdup(t); - if (customkeydoormsg[fc]) KeyDoorMessage[fc] = customkeydoormsg[fc]; + quoteMgr.InitializeQuote(QUOTE_DOORMSG + fc, t); fc++; } break; diff --git a/source/sw/src/slidor.cpp b/source/sw/src/slidor.cpp index 697513cab..f13de4bf7 100644 --- a/source/sw/src/slidor.cpp +++ b/source/sw/src/slidor.cpp @@ -36,6 +36,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "interp.h" #include "text.h" #include "sprite.h" +#include "quotemgr.h" BEGIN_SW_NS @@ -213,7 +214,7 @@ DoSlidorMatch(PLAYERp pp, short match, SWBOOL manual) else #endif { - PutStringInfo(pp, KeyDoorMessage[key_num - 1]); + PutStringInfo(pp, quoteMgr.GetExQuote(QUOTE_DOORMSG + key_num - 1)); return -1; } } diff --git a/source/sw/src/sprite.cpp b/source/sw/src/sprite.cpp index 60c131847..b3e409c2a 100644 --- a/source/sw/src/sprite.cpp +++ b/source/sw/src/sprite.cpp @@ -48,6 +48,8 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "slidor.h" #include "player.h" #include "swcvar.h" +#include "quotemgr.h" +#include "v_text.h" BEGIN_SW_NS @@ -5505,29 +5507,6 @@ void ChoosePlayerGetSound(PLAYERp pp) PlayerSound(PlayerGetItemVocs[choose_snd],&pp->posx,&pp->posy,&pp->posz,v3df_follow|v3df_dontpan,pp); } -//#define MAX_FORTUNES 16 -// With PLOCK on, max = 11 -const char *ReadFortune[MAX_FORTUNES] = -{ - "You never going to score.", - "26-31-43-82-16-29", - "Sorry, you no win this time, try again.", - "You try harder get along. Be a nice man.", - "No man is island, except Lo Wang.", - "There is much death in future.", - "You should kill all business associates.", - "(c)1997,3DRealms fortune cookie company.", - "Your chi attracts many chicks.", - "Don't you know you the scum of society!?", - "You should not scratch yourself there.", - "Man who stand on toilet, high on pot.", - "Man who fart in church sit in own pew.", - "Man trapped in pantry has ass in jam.", - "Baseball wrong. Man with 4 balls cannot walk.", - "Man who buy drowned cat pay for wet pussy.", -}; - - SWBOOL CanGetWeapon(PLAYERp pp, short SpriteNum, int WPN) { USERp u = User[SpriteNum], pu; @@ -5563,18 +5542,6 @@ SWBOOL CanGetWeapon(PLAYERp pp, short SpriteNum, int WPN) return TRUE; } -const char *KeyMsg[MAX_KEYS] = -{ - "Got the RED key!", - "Got the BLUE key!", - "Got the GREEN key!", - "Got the YELLOW key!", - "Got the GOLD master key!", - "Got the SILVER master key!", - "Got the BRONZE master key!", - "Got the RED master key!" -}; - struct InventoryDecl_t InventoryDecls[InvDecl_TOTAL] = { { "Armor Vest +50", 50 }, @@ -5702,7 +5669,7 @@ KeyMain: if (pp->HasKey[key_num]) break; - PutStringInfo(Player+pnum, KeyMsg[key_num]); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_KEYMSG + key_num)); pp->HasKey[key_num] = TRUE; SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup @@ -5795,11 +5762,9 @@ KeyMain: // Say something witty if (pp == Player+myconnectindex && hud_messages) { - if (adult_lockout || Global_PLock) - sprintf(ds,"Fortune Say: %s\n",ReadFortune[STD_RANDOM_RANGE(10)]); - else - sprintf(ds,"Fortune Say: %s\n",ReadFortune[STD_RANDOM_RANGE(MAX_FORTUNES)]); - OSD_Printf("%s", ds); + int cookie = (adult_lockout || Global_PLock)? STD_RANDOM_RANGE(10) : STD_RANDOM_RANGE(MAX_FORTUNES); + // print to the console, and if active to the generic notify display. + Printf(PRINT_NOTIFY, TEXTCOLOR_SAPPHIRE "%s: %s\n", GStrings("TXTS_FORTUNE"), quoteMgr.GetQuote(QUOTE_COOKIE + cookie)); } SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup diff --git a/source/sw/src/text.cpp b/source/sw/src/text.cpp index 11fb643c3..090e79437 100644 --- a/source/sw/src/text.cpp +++ b/source/sw/src/text.cpp @@ -49,18 +49,6 @@ BEGIN_SW_NS #define PANEL_SM_FONT_Y 3613 #define PANEL_SM_FONT_R 3625 -const char *KeyDoorMessage[MAX_KEYS] = -{ - "You need a RED key for this door.", - "You need a BLUE key for this door.", - "You need a GREEN key for this door.", - "You need a YELLOW key for this door.", - "You need a GOLD key for this door.", - "You need a SILVER key for this door.", - "You need a BRONZE key for this door.", - "You need a RED key for this door." -}; - void DisplaySummaryString(PLAYERp pp, short xs, short ys, short color, short shade, const char *buffer) { short size,x; diff --git a/source/sw/src/vator.cpp b/source/sw/src/vator.cpp index ecba7c777..bb3f013ea 100644 --- a/source/sw/src/vator.cpp +++ b/source/sw/src/vator.cpp @@ -36,6 +36,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "text.h" #include "sprite.h" #include "weapon.h" +#include "quotemgr.h" BEGIN_SW_NS @@ -199,7 +200,7 @@ short DoVatorOperate(PLAYERp pp, short sectnum) else #endif { - PutStringInfo(pp, KeyDoorMessage[key_num - 1]); + PutStringInfo(pp, quoteMgr.GetExQuote(QUOTE_DOORMSG + key_num - 1)); return FALSE; } } @@ -267,7 +268,7 @@ DoVatorMatch(PLAYERp pp, short match) else #endif { - PutStringInfo(pp, KeyDoorMessage[key_num - 1]); + PutStringInfo(pp, quoteMgr.GetExQuote(QUOTE_DOORMSG + key_num - 1)); return -1; } } diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index 6b814cc19..45083934c 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -1775,4 +1775,37 @@ TXTS_EPD2,Eighteen levels (Full Version Only),,,,,,,,,,,,,,,,,,,,,, TXTS_SK1,Tiny grasshopper,,,,,,,,,,,,,,,,,,,,,, TXTS_SK2,I Have No Fear,,,,,,,,,,,,,,,,,,,,,, TXTS_SK3,Who Wants Wang,,,,,,,,,,,,,,,,,,,,,, -TXTS_SK4,"No Pain, No Gain",,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file +TXTS_SK4,"No Pain, No Gain",,,,,,,,,,,,,,,,,,,,,, +Got the RED key!,TXTS_KEY1,,,,,,,,,,,,,,,,,,,,,, +Got the BLUE key!,TXTS_KEY2,,,,,,,,,,,,,,,,,,,,,, +Got the GREEN key!,TXTS_KEY3,,,,,,,,,,,,,,,,,,,,,, +Got the YELLOW key!,TXTS_KEY4,,,,,,,,,,,,,,,,,,,,,, +Got the GOLD master key!,TXTS_KEY5,,,,,,,,,,,,,,,,,,,,,, +Got the SILVER master key!,TXTS_KEY6,,,,,,,,,,,,,,,,,,,,,, +Got the BRONZE master key!,TXTS_KEY7,,,,,,,,,,,,,,,,,,,,,, +Got the RED master key!,TXTS_KEY8,,,,,,,,,,,,,,,,,,,,,, +You need a RED key for this door.,TXTS_DOOR1,,,,,,,,,,,,,,,,,,,,,, +You need a BLUE key for this door.,TXTS_DOOR2,,,,,,,,,,,,,,,,,,,,,, +You need a GREEN key for this door.,TXTS_DOOR3,,,,,,,,,,,,,,,,,,,,,, +You need a YELLOW key for this door.,TXTS_DOOR4,,,,,,,,,,,,,,,,,,,,,, +You need a GOLD key for this door.,TXTS_DOOR5,,,,,,,,,,,,,,,,,,,,,, +You need a SILVER key for this door.,TXTS_DOOR6,,,,,,,,,,,,,,,,,,,,,, +You need a BRONZE key for this door.,TXTS_DOOR7,,,,,,,,,,,,,,,,,,,,,, +You need a RED key for this door.,TXTS_DOOR8,,,,,,,,,,,,,,,,,,,,,, +You never going to score.,TXTS_COOKIE1,,,,,,,,,,,,,,,,,,,,,, +26-31-43-82-16-29,TXTS_COOKIE2,,,,,,,,,,,,,,,,,,,,,, +"Sorry, you no win this time, try again.",TXTS_COOKIE3,,,,,,,,,,,,,,,,,,,,,, +You try harder get along. Be a nice man.,TXTS_COOKIE4,,,,,,,,,,,,,,,,,,,,,, +"No man is island, except Lo Wang.",TXTS_COOKIE5,,,,,,,,,,,,,,,,,,,,,, +There is much death in future.,TXTS_COOKIE6,,,,,,,,,,,,,,,,,,,,,, +You should kill all business associates.,TXTS_COOKIE7,,,,,,,,,,,,,,,,,,,,,, +"(c)1997,3DRealms fortune cookie company.",TXTS_COOKIE8,,,,,,,,,,,,,,,,,,,,,, +Your chi attracts many chicks.,TXTS_COOKIE9,,,,,,,,,,,,,,,,,,,,,, +Don't you know you the scum of society!?,TXTS_COOKIE10,,,,,,,,,,,,,,,,,,,,,, +You should not scratch yourself there.,TXTS_COOKIE11,,,,,,,,,,,,,,,,,,,,,, +"Man who stand on toilet, high on pot.",TXTS_COOKIE12,,,,,,,,,,,,,,,,,,,,,, +Man who fart in church sit in own pew.,TXTS_COOKIE13,,,,,,,,,,,,,,,,,,,,,, +Man trapped in pantry has ass in jam.,TXTS_COOKIE14,,,,,,,,,,,,,,,,,,,,,, +Baseball wrong. Man with 4 balls cannot walk.,TXTS_COOKIE15,,,,,,,,,,,,,,,,,,,,,, +Man who buy drowned cat pay for wet pussy.,TXTS_COOKIE16,,,,,,,,,,,,,,,,,,,,,, +Fortune Say:,TXTS_FORTUNE,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file diff --git a/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt b/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt index 62b54e600..7ffcf34f8 100644 --- a/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt +++ b/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt @@ -446,44 +446,44 @@ weapon 12 } fortune { - "You never going to score." - "26-31-43-82-16-29" - "Sorry, you no win this time, try again." - "You try harder get along. Be a nice man." - "No man is island, except Lo Wang." - "There is much death in future." - "You should kill all business associates." - "(c)1997,3DRealms fortune cookie company." - "Your chi attracts many chicks." - "Don't you know you the scum of society!?" - "You should not scratch yourself there." - "Man who stand on toilet, high on pot." - "Man who fart in church sit in own pew." - "Man trapped in pantry has ass in jam." - "Baseball wrong. Man with 4 balls cannot walk." - "Man who buy drowned cat pay for wet pussy." + "$TXTS_COOKIE1" + "$TXTS_COOKIE2" + "$TXTS_COOKIE3" + "$TXTS_COOKIE4" + "$TXTS_COOKIE5" + "$TXTS_COOKIE6" + "$TXTS_COOKIE7" + "$TXTS_COOKIE8" + "$TXTS_COOKIE9" + "$TXTS_COOKIE10" + "$TXTS_COOKIE11" + "$TXTS_COOKIE12" + "$TXTS_COOKIE13" + "$TXTS_COOKIE14" + "$TXTS_COOKIE15" + "$TXTS_COOKIE16" } gotkey { - "Got the RED key!" - "Got the BLUE key!" - "Got the GREEN key!" - "Got the YELLOW key!" - "Got the GOLD master key!" - "Got the SILVER master key!" - "Got the BRONZE master key!" - "Got the RED master key!" + "$TXTS_KEY1" + "$TXTS_KEY2" + "$TXTS_KEY3" + "$TXTS_KEY4" + "$TXTS_KEY5" + "$TXTS_KEY6" + "$TXTS_KEY7" + "$TXTS_KEY8" } needkey { - "You need a RED key for this door." - "You need a BLUE key for this door." - "You need a GREEN key for this door." - "You need a YELLOW key for this door." - "You need a GOLD key for this door." - "You need a SILVER key for this door." - "You need a BRONZE key for this door." - "You need a RED key for this door." + "$TXTS_DOOR1" + "$TXTS_DOOR2" + "$TXTS_DOOR3" + "$TXTS_DOOR4" + "$TXTS_DOOR5" + "$TXTS_DOOR6" + "$TXTS_DOOR7" + "$TXTS_DOOR8" } theme 1 // game startup menu { From da1900dc8a5cda182f02952cd18cb499fb9f4e17 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Dec 2019 19:00:30 +0100 Subject: [PATCH 181/203] - same for inventory pickup messages. --- source/sw/src/game.h | 2 + source/sw/src/scrip2.cpp | 5 +-- source/sw/src/sprite.cpp | 44 +++++++++---------- source/sw/src/sprite.h | 1 - wadsrc/static/demolition/language.csv | 13 +++++- .../shadowwarrior/demolition/SWCustom.txt | 22 +++++----- 6 files changed, 48 insertions(+), 39 deletions(-) diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 508da6686..798d0f96e 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -967,11 +967,13 @@ enum { MAX_KEYS = 8, MAX_FORTUNES = 16, + MAX_INVENTORY_Q = 11,//InvDecl_TOTAL QUOTE_KEYMSG = 1, QUOTE_DOORMSG = QUOTE_KEYMSG + MAX_KEYS, // 23+24 are reserved. QUOTE_COOKIE = 25, + QUOTE_INVENTORY = QUOTE_COOKIE + MAX_FORTUNES, }; typedef struct diff --git a/source/sw/src/scrip2.cpp b/source/sw/src/scrip2.cpp index 0c4d6dde5..b7fe73272 100644 --- a/source/sw/src/scrip2.cpp +++ b/source/sw/src/scrip2.cpp @@ -539,7 +539,6 @@ static int cm_transtok(const char *tok, const struct _tokset *set, const unsigne // quit "PRESS (Y) TO QUIT, (N) TO FIGHT ON." static LEVEL_INFO custommaps[MAX_LEVELS_REG]; -static char *custominventoryname[InvDecl_TOTAL]; static char *customweaponname[2][MAX_WEAPONS]; // weapon, ammo #define WM_DAMAGE 1 @@ -879,9 +878,7 @@ void LoadCustomInfoFromScript(const char *filename) if (name) { - Bfree(custominventoryname[in]); - custominventoryname[in] = strdup(name); - InventoryDecls[in].name = custominventoryname[in]; + quoteMgr.InitializeQuote(QUOTE_INVENTORY + in, name); } if (amt >= 0) { diff --git a/source/sw/src/sprite.cpp b/source/sw/src/sprite.cpp index b3e409c2a..2eea69447 100644 --- a/source/sw/src/sprite.cpp +++ b/source/sw/src/sprite.cpp @@ -5544,17 +5544,17 @@ SWBOOL CanGetWeapon(PLAYERp pp, short SpriteNum, int WPN) struct InventoryDecl_t InventoryDecls[InvDecl_TOTAL] = { - { "Armor Vest +50", 50 }, - { "Kevlar Armor Vest +100", 100 }, - { "MedKit +20", 20 }, - { "Fortune Cookie +50 BOOST", 50 }, - { "Portable MedKit", 100 }, - { "Gas Bomb", 1 }, - { "Flash Bomb", 2 }, - { "Caltrops", 3 }, - { "Night Vision Goggles", 100 }, - { "Repair Kit", 100 }, - { "Smoke Bomb", 100 }, + {50 }, + {100 }, + {20 }, + {50 }, + {100 }, + {1 }, + {2 }, + {3 }, + {100 }, + {100 }, + {100 }, }; #define ITEMFLASHAMT -8 @@ -5690,14 +5690,14 @@ KeyMain: if (u->spal == PALETTE_PLAYER3) { PlayerUpdateArmor(pp, 1000+InventoryDecls[InvDecl_Kevlar].amount); - PutStringInfo(Player+pnum, InventoryDecls[InvDecl_Kevlar].name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_INVENTORY + InvDecl_Kevlar)); } else { if (pp->Armor < InventoryDecls[InvDecl_Armor].amount) { PlayerUpdateArmor(pp, 1000+InventoryDecls[InvDecl_Armor].amount); - PutStringInfo(Player+pnum, InventoryDecls[InvDecl_Armor].name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_INVENTORY + InvDecl_Armor)); } else break; @@ -5726,7 +5726,7 @@ KeyMain: { SWBOOL putbackmax=FALSE; - PutStringInfo(Player+pnum, InventoryDecls[InvDecl_SmMedkit].name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_INVENTORY + InvDecl_SmMedkit)); if (pp->MaxHealth == 200) { @@ -5756,7 +5756,7 @@ KeyMain: pp->MaxHealth = 200; if (pu->Health < 200) { - PutStringInfo(Player+pnum, InventoryDecls[InvDecl_Booster].name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_INVENTORY + InvDecl_Booster)); PlayerUpdateHealth(pp, InventoryDecls[InvDecl_Booster].amount); // This is for health // over 100% // Say something witty @@ -5789,7 +5789,7 @@ KeyMain: if (!pp->InventoryAmount[INVENTORY_MEDKIT] || pp->InventoryPercent[INVENTORY_MEDKIT] < InventoryDecls[InvDecl_Medkit].amount) { - PutStringInfo(Player+pnum, InventoryDecls[InvDecl_Medkit].name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_INVENTORY + InvDecl_Medkit)); pp->InventoryPercent[INVENTORY_MEDKIT] = InventoryDecls[InvDecl_Medkit].amount; pp->InventoryAmount[INVENTORY_MEDKIT] = 1; PlayerUpdateInventory(pp, INVENTORY_MEDKIT); @@ -5812,7 +5812,7 @@ KeyMain: if (pp->InventoryAmount[INVENTORY_CHEMBOMB] < InventoryDecls[InvDecl_ChemBomb].amount) { - PutStringInfo(Player+pnum, InventoryDecls[InvDecl_ChemBomb].name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_INVENTORY + InvDecl_ChemBomb)); pp->InventoryPercent[INVENTORY_CHEMBOMB] = 0; pp->InventoryAmount[INVENTORY_CHEMBOMB]++; PlayerUpdateInventory(pp, INVENTORY_CHEMBOMB); @@ -5827,7 +5827,7 @@ KeyMain: if (pp->InventoryAmount[INVENTORY_FLASHBOMB] < InventoryDecls[InvDecl_FlashBomb].amount) { - PutStringInfo(Player+pnum, InventoryDecls[InvDecl_FlashBomb].name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_INVENTORY + InvDecl_FlashBomb)); pp->InventoryPercent[INVENTORY_FLASHBOMB] = 0; pp->InventoryAmount[INVENTORY_FLASHBOMB]++; PlayerUpdateInventory(pp, INVENTORY_FLASHBOMB); @@ -5842,7 +5842,7 @@ KeyMain: if (pp->InventoryAmount[INVENTORY_CALTROPS] < InventoryDecls[InvDecl_Caltrops].amount) { - PutStringInfo(Player+pnum, InventoryDecls[InvDecl_Caltrops].name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_INVENTORY + InvDecl_Caltrops)); pp->InventoryPercent[INVENTORY_CALTROPS] = 0; pp->InventoryAmount[INVENTORY_CALTROPS]+=3; if (pp->InventoryAmount[INVENTORY_CALTROPS] > InventoryDecls[InvDecl_Caltrops].amount) @@ -5858,7 +5858,7 @@ KeyMain: case ICON_NIGHT_VISION: if (!pp->InventoryAmount[INVENTORY_NIGHT_VISION] || pp->InventoryPercent[INVENTORY_NIGHT_VISION] < InventoryDecls[InvDecl_NightVision].amount) { - PutStringInfo(Player+pnum, InventoryDecls[InvDecl_NightVision].name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_INVENTORY + InvDecl_NightVision)); pp->InventoryPercent[INVENTORY_NIGHT_VISION] = InventoryDecls[InvDecl_NightVision].amount; pp->InventoryAmount[INVENTORY_NIGHT_VISION] = 1; PlayerUpdateInventory(pp, INVENTORY_NIGHT_VISION); @@ -5871,7 +5871,7 @@ KeyMain: case ICON_REPAIR_KIT: if (!pp->InventoryAmount[INVENTORY_REPAIR_KIT] || pp->InventoryPercent[INVENTORY_REPAIR_KIT] < InventoryDecls[InvDecl_RepairKit].amount) { - PutStringInfo(Player+pnum, InventoryDecls[InvDecl_RepairKit].name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_INVENTORY + InvDecl_RepairKit)); pp->InventoryPercent[INVENTORY_REPAIR_KIT] = InventoryDecls[InvDecl_RepairKit].amount; pp->InventoryAmount[INVENTORY_REPAIR_KIT] = 1; PlayerUpdateInventory(pp, INVENTORY_REPAIR_KIT); @@ -5902,7 +5902,7 @@ KeyMain: case ICON_CLOAK: if (!pp->InventoryAmount[INVENTORY_CLOAK] || pp->InventoryPercent[INVENTORY_CLOAK] < InventoryDecls[InvDecl_Cloak].amount) { - PutStringInfo(Player+pnum, InventoryDecls[InvDecl_Cloak].name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_INVENTORY + InvDecl_Cloak)); pp->InventoryPercent[INVENTORY_CLOAK] = InventoryDecls[InvDecl_Cloak].amount; pp->InventoryAmount[INVENTORY_CLOAK] = 1; PlayerUpdateInventory(pp, INVENTORY_CLOAK); diff --git a/source/sw/src/sprite.h b/source/sw/src/sprite.h index 95c8f60f1..4682a1226 100644 --- a/source/sw/src/sprite.h +++ b/source/sw/src/sprite.h @@ -77,7 +77,6 @@ enum struct InventoryDecl_t { - const char *name; int amount; }; extern struct InventoryDecl_t InventoryDecls[InvDecl_TOTAL]; diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index 45083934c..008773924 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -1808,4 +1808,15 @@ Man who fart in church sit in own pew.,TXTS_COOKIE13,,,,,,,,,,,,,,,,,,,,,, Man trapped in pantry has ass in jam.,TXTS_COOKIE14,,,,,,,,,,,,,,,,,,,,,, Baseball wrong. Man with 4 balls cannot walk.,TXTS_COOKIE15,,,,,,,,,,,,,,,,,,,,,, Man who buy drowned cat pay for wet pussy.,TXTS_COOKIE16,,,,,,,,,,,,,,,,,,,,,, -Fortune Say:,TXTS_FORTUNE,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file +Fortune Say:,TXTS_FORTUNE,,,,,,,,,,,,,,,,,,,,,, +Armor Vest +50,TXTS_INV1,,,,,,,,,,,,,,,,,,,,,, +Kevlar Armor Vest +100,TXTS_INV2,,,,,,,,,,,,,,,,,,,,,, +MedKit +20,TXTS_INV3,,,,,,,,,,,,,,,,,,,,,, +Fortune Cookie +50 BOOST,TXTS_INV4,,,,,,,,,,,,,,,,,,,,,, +Portable MedKit,TXTS_INV5,,,,,,,,,,,,,,,,,,,,,, +Gas Bomb,TXTS_INV6,,,,,,,,,,,,,,,,,,,,,, +Flash Bomb,TXTS_INV7,,,,,,,,,,,,,,,,,,,,,, +Caltrops,TXTS_INV8,,,,,,,,,,,,,,,,,,,,,, +Night Vision Goggles,TXTS_INV9,,,,,,,,,,,,,,,,,,,,,, +Repair Kit,TXTS_INV10,,,,,,,,,,,,,,,,,,,,,, +Smoke Bomb,TXTS_INV11,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file diff --git a/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt b/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt index 7ffcf34f8..67a1bd5c5 100644 --- a/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt +++ b/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt @@ -279,57 +279,57 @@ skill 4 /* inventory 1 { - name "Armor Vest +50" + name "$TXT_INV1" amount 50 } inventory 2 { - name "Kevlar Armor Vest +100" + name "$TXT_INV2" amount 100 } inventory 3 { - name "MedKit +20" + name "$TXT_INV3" amount 20 } inventory 4 { - name "Fortune Cookie +50 BOOST" + name "$TXT_INV4" amount 50 } inventory 5 { - name "Portable MedKit" + name "$TXT_INV5" amount 100 } inventory 6 { - name "Gas Bomb" + name "$TXT_INV6" amount 1 } inventory 7 { - name "Flash Bomb" + name "$TXT_INV7" amount 2 } inventory 8 { - name "Caltrops" + name "$TXT_INV8" amount 3 } inventory 9 { - name "Night Vision Goggles" + name "$TXT_INV9" amount 100 } inventory 10 { - name "Repair Kit" + name "$TXT_INV10" amount 100 } inventory 11 { - name "Smoke Bomb" + name "$TXT_INV11" amount 100 } weapon 1 From e62f6cbc207eea93003c54a91e4df95e958c1ea7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Dec 2019 19:49:36 +0100 Subject: [PATCH 182/203] - weapon and ammo names are now also localizable. --- source/sw/src/damage.h | 28 ++++---- source/sw/src/game.h | 30 ++++++++- source/sw/src/scrip2.cpp | 9 +-- source/sw/src/sprite.cpp | 37 +++++------ wadsrc/static/demolition/language.csv | 23 ++++++- .../shadowwarrior/demolition/SWCustom.txt | 65 +++++++++---------- 6 files changed, 116 insertions(+), 76 deletions(-) diff --git a/source/sw/src/damage.h b/source/sw/src/damage.h index c395632f8..d2904f8cc 100644 --- a/source/sw/src/damage.h +++ b/source/sw/src/damage.h @@ -26,15 +26,15 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #ifdef DAMAGE_TABLE #define DAMAGE_ENTRY(id, init_func, damage_lo, damage_hi, radius, max_ammo, min_ammo, with_weapon) \ - { init_func, damage_lo, damage_hi, radius, max_ammo, min_ammo, with_weapon, NULL, NULL, -1, -1 }, -#define DAMAGE_ENTRY_WPN(id, init_func, damage_lo, damage_hi, radius, max_ammo, min_ammo, with_weapon, weapon_name, ammo_name, weapon_pickup, ammo_pickup ) \ - { init_func, damage_lo, damage_hi, radius, max_ammo, min_ammo, with_weapon, weapon_name, ammo_name, weapon_pickup, ammo_pickup }, + { init_func, damage_lo, damage_hi, radius, max_ammo, min_ammo, with_weapon, -1, -1 }, +#define DAMAGE_ENTRY_WPN(id, init_func, damage_lo, damage_hi, radius, max_ammo, min_ammo, with_weapon, weapon_pickup, ammo_pickup ) \ + { init_func, damage_lo, damage_hi, radius, max_ammo, min_ammo, with_weapon, weapon_pickup, ammo_pickup }, #endif #ifdef DAMAGE_ENUM #define DAMAGE_ENTRY(id, init_func, damage_lo, damage_hi, radius, max_ammo, min_ammo, with_weapon) \ id, -#define DAMAGE_ENTRY_WPN(id, init_func, damage_lo, damage_hi, radius, max_ammo, min_ammo, with_weapon, weapon_name, ammo_name, weapon_pickup, ammo_pickup ) \ +#define DAMAGE_ENTRY_WPN(id, init_func, damage_lo, damage_hi, radius, max_ammo, min_ammo, with_weapon, weapon_pickup, ammo_pickup ) \ id, #endif @@ -42,15 +42,15 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms // weapon DAMAGE_ENTRY(WPN_FIST, InitWeaponFist, 10, 40, 0, -1, -1, -1) -DAMAGE_ENTRY_WPN(WPN_STAR, InitWeaponStar, 5, 10, 0, 99, 3, -1, "Shurikens", NULL, 9, -1) -DAMAGE_ENTRY_WPN(WPN_SHOTGUN, InitWeaponShotgun, 4, 4, 0, 52, 1, -1, "Riot Gun", "Shotshells", 8, 24) -DAMAGE_ENTRY_WPN(WPN_UZI, InitWeaponUzi, 5, 7, 0, 200, 1, -1, "UZI Submachine Gun", "UZI Clip", 50, 50) -DAMAGE_ENTRY_WPN(WPN_MICRO, InitWeaponMicro, 15, 30, 0, 50, 1, -1, "Missile Launcher", "Missiles", 5, 5) -DAMAGE_ENTRY_WPN(WPN_GRENADE, InitWeaponGrenade, 15, 30, 0, 50, 1, -1, "Grenade Launcher", "Grenade Shells", 6, 8) -DAMAGE_ENTRY_WPN(WPN_MINE, InitWeaponMine, 5, 10, 0, 20, 1, -1, "Sticky Bombs", NULL, 5, -1) -DAMAGE_ENTRY_WPN(WPN_RAIL, InitWeaponRail, 40, 60, 0, 20, 1, -1, "Rail Gun", "Rail Gun Rods", 10, 10) -DAMAGE_ENTRY_WPN(WPN_HOTHEAD, InitWeaponHothead, 10, 25, 0, 80, 1, -1, "Guardian Head", "Firebursts", 30, 60) -DAMAGE_ENTRY_WPN(WPN_HEART, InitWeaponHeart, 75, 100, 0, 5, 1, -1, "Ripper Heart", "Deathcoils", 1, 6) +DAMAGE_ENTRY_WPN(WPN_STAR, InitWeaponStar, 5, 10, 0, 99, 3, -1, 9, -1) +DAMAGE_ENTRY_WPN(WPN_SHOTGUN, InitWeaponShotgun, 4, 4, 0, 52, 1, -1, 8, 24) +DAMAGE_ENTRY_WPN(WPN_UZI, InitWeaponUzi, 5, 7, 0, 200, 1, -1, 50, 50) +DAMAGE_ENTRY_WPN(WPN_MICRO, InitWeaponMicro, 15, 30, 0, 50, 1, -1, 5, 5) +DAMAGE_ENTRY_WPN(WPN_GRENADE, InitWeaponGrenade, 15, 30, 0, 50, 1, -1, 6, 8) +DAMAGE_ENTRY_WPN(WPN_MINE, InitWeaponMine, 5, 10, 0, 20, 1, -1, 5, -1) +DAMAGE_ENTRY_WPN(WPN_RAIL, InitWeaponRail, 40, 60, 0, 20, 1, -1, 10, 10) +DAMAGE_ENTRY_WPN(WPN_HOTHEAD, InitWeaponHothead, 10, 25, 0, 80, 1, -1, 30, 60) +DAMAGE_ENTRY_WPN(WPN_HEART, InitWeaponHeart, 75, 100, 0, 5, 1, -1, 1, 6) DAMAGE_ENTRY(WPN_NAPALM, InitWeaponHothead, 50, 100, 0, 100, 40, WPN_HOTHEAD) DAMAGE_ENTRY(WPN_RING, InitWeaponHothead, 15, 50, 0, 100, 20, WPN_HOTHEAD) @@ -77,7 +77,7 @@ DAMAGE_ENTRY(DMG_GRENADE_EXP, NULL, 70, 140, 6500, -1, -1 DAMAGE_ENTRY(DMG_MINE_EXP, NULL, 85, 115, 6500, -1, -1, -1) DAMAGE_ENTRY(DMG_MINE_SHRAP, NULL, 15, 30, 0, -1, -1, -1) DAMAGE_ENTRY(DMG_MICRO_EXP, NULL, 50, 100, 4500, -1, -1, -1) -DAMAGE_ENTRY_WPN(DMG_NUCLEAR_EXP, NULL, 0, 800, 30000, -1, -1, -1, "Nuclear Warhead", "Heat Seeker Card", 1, 5) +DAMAGE_ENTRY_WPN(DMG_NUCLEAR_EXP, NULL, 0, 800, 30000, -1, -1, -1, 1, 5) DAMAGE_ENTRY(DMG_RADIATION_CLOUD, NULL, 2, 6, 5000, -1, -1, -1) DAMAGE_ENTRY(DMG_FLASHBOMB, NULL, 100, 150, 16384, -1, -1, -1) diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 798d0f96e..35703d679 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -886,8 +886,6 @@ typedef struct int16_t max_ammo; int16_t min_ammo; int16_t with_weapon; - const char *weapon_name; - const char *ammo_name; int16_t weapon_pickup; int16_t ammo_pickup; } DAMAGE_DATA, *DAMAGE_DATAp; @@ -974,6 +972,34 @@ enum // 23+24 are reserved. QUOTE_COOKIE = 25, QUOTE_INVENTORY = QUOTE_COOKIE + MAX_FORTUNES, + QUOTE_WPNFIST = QUOTE_INVENTORY + MAX_INVENTORY_Q, + QUOTE_WPNSWORD, + QUOTE_WPNSHURIKEN, + QUOTE_WPNSTICKY, + QUOTE_WPNUZI, + QUOTE_WPNLAUNCH, + QUOTE_WPNNUKE, + QUOTE_WPNGRENADE, + QUOTE_WPNRAILGUN, + QUOTE_WPNRIOT, + QUOTE_WPNHEAD, + QUOTE_WPNRIPPER, + // Here a gap of two needs to be inserted because the weapon array contains two bogus entries the parser can access. + // Not all ammo types here are used, but the entries must be reserved for the parser. + QUOTE_AMMOFIST = QUOTE_WPNRIPPER + 2, + QUOTE_AMMOSWORD, + QUOTE_AMMOSHURIKEN, + QUOTE_AMMOSTICKY, + QUOTE_AMMOUZI, + QUOTE_AMMOLAUNCH, + QUOTE_AMMONUKE, + QUOTE_AMMOGRENADE, + QUOTE_AMMORAILGUN, + QUOTE_AMMORIOT, + QUOTE_AMMOHEAD, + QUOTE_AMMORIPPER, + // Again, here a gap of two needs to be inserted because the weapon array contains two bogus entries the parser can access. + }; typedef struct diff --git a/source/sw/src/scrip2.cpp b/source/sw/src/scrip2.cpp index b7fe73272..c7945cb1f 100644 --- a/source/sw/src/scrip2.cpp +++ b/source/sw/src/scrip2.cpp @@ -539,7 +539,6 @@ static int cm_transtok(const char *tok, const struct _tokset *set, const unsigne // quit "PRESS (Y) TO QUIT, (N) TO FIGHT ON." static LEVEL_INFO custommaps[MAX_LEVELS_REG]; -static char *customweaponname[2][MAX_WEAPONS]; // weapon, ammo #define WM_DAMAGE 1 #define WM_WEAP 2 @@ -951,9 +950,7 @@ void LoadCustomInfoFromScript(const char *filename) if (maxammo >= 0) DamageData[id].max_ammo = maxammo; if (name) { - Bfree(customweaponname[0][id]); - customweaponname[0][id] = strdup(name); - DamageData[id].weapon_name = customweaponname[0][id]; + quoteMgr.InitializeQuote(QUOTE_WPNFIST + in, name); } if (wpickup >= 0) DamageData[id].weapon_pickup = wpickup; } @@ -961,9 +958,7 @@ void LoadCustomInfoFromScript(const char *filename) { if (ammo) { - Bfree(customweaponname[1][id]); - customweaponname[1][id] = strdup(ammo); - DamageData[id].ammo_name = customweaponname[1][id]; + quoteMgr.InitializeQuote(QUOTE_AMMOFIST + in, name); } if (pickup >= 0) DamageData[id].ammo_pickup = pickup; } diff --git a/source/sw/src/sprite.cpp b/source/sw/src/sprite.cpp index 2eea69447..2264b0838 100644 --- a/source/sw/src/sprite.cpp +++ b/source/sw/src/sprite.cpp @@ -5925,8 +5925,7 @@ KeyMain: if (pp->WpnAmmo[WPN_STAR] >= DamageData[WPN_STAR].max_ammo) break; - sprintf(ds, sw_darts ? "Darts" : "Shurikens"); - PutStringInfo(Player+pnum, DamageData[WPN_STAR].weapon_name); + PutStringInfo(Player+pnum, sw_darts? GStrings("TXTS_DARTS") : quoteMgr.GetQuote(QUOTE_WPNSHURIKEN)); PlayerUpdateAmmo(pp, WPN_STAR, DamageData[WPN_STAR].weapon_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup if (pp == Player+myconnectindex) @@ -5953,7 +5952,7 @@ KeyMain: if (pp->WpnAmmo[WPN_MINE] >= DamageData[WPN_MINE].max_ammo) break; //sprintf(ds,"Sticky Bombs"); - PutStringInfo(Player+pnum, DamageData[WPN_MINE].weapon_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_WPNSTICKY)); PlayerUpdateAmmo(pp, WPN_MINE, DamageData[WPN_MINE].weapon_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup if (pp == Player+myconnectindex) @@ -5982,7 +5981,7 @@ KeyMain: if (TEST(pp->Flags, PF_TWO_UZI) && pp->WpnAmmo[WPN_UZI] >= DamageData[WPN_UZI].max_ammo) break; //sprintf(ds,"UZI Submachine Gun"); - PutStringInfo(Player+pnum, DamageData[WPN_UZI].weapon_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_WPNUZI)); // pp->WpnAmmo[WPN_UZI] += 50; PlayerUpdateAmmo(pp, WPN_UZI, DamageData[WPN_UZI].weapon_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup @@ -6020,7 +6019,7 @@ KeyMain: if (pp->WpnAmmo[WPN_UZI] >= DamageData[WPN_UZI].max_ammo) break; //sprintf(ds,"UZI Clip"); - PutStringInfo(Player+pnum, DamageData[WPN_UZI].ammo_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_AMMOUZI)); PlayerUpdateAmmo(pp, WPN_UZI, DamageData[WPN_UZI].ammo_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup if (pp == Player+myconnectindex) @@ -6038,7 +6037,7 @@ KeyMain: if (TEST(pp->WpnFlags, BIT(WPN_MICRO)) && pp->WpnAmmo[WPN_MICRO] >= DamageData[WPN_MICRO].max_ammo) break; //sprintf(ds,"Missile Launcher"); - PutStringInfo(Player+pnum, DamageData[WPN_MICRO].weapon_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_WPNLAUNCH)); // pp->WpnAmmo[WPN_MICRO] += 5; PlayerUpdateAmmo(pp, WPN_MICRO, DamageData[WPN_MICRO].weapon_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup @@ -6061,7 +6060,7 @@ KeyMain: if (pp->WpnAmmo[WPN_MICRO] >= DamageData[WPN_MICRO].max_ammo) break; //sprintf(ds,"Missiles"); - PutStringInfo(Player+pnum, DamageData[WPN_MICRO].ammo_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_AMMOLAUNCH)); PlayerUpdateAmmo(pp, WPN_MICRO, DamageData[WPN_MICRO].ammo_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup if (pp == Player+myconnectindex) @@ -6073,7 +6072,7 @@ KeyMain: if (pp->WpnRocketNuke != 1) { //sprintf(ds,"Nuclear Warhead"); - PutStringInfo(Player+pnum, DamageData[DMG_NUCLEAR_EXP].weapon_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_WPNNUKE)); pp->WpnRocketNuke = DamageData[DMG_NUCLEAR_EXP].weapon_pickup; SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup if (pp == Player+myconnectindex) @@ -6106,7 +6105,7 @@ KeyMain: if (TEST(pp->WpnFlags, BIT(WPN_GRENADE)) && pp->WpnAmmo[WPN_GRENADE] >= DamageData[WPN_GRENADE].max_ammo) break; //sprintf(ds,"Grenade Launcher"); - PutStringInfo(Player+pnum, DamageData[WPN_GRENADE].weapon_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_WPNGRENADE)); // pp->WpnAmmo[WPN_GRENADE] += 6; PlayerUpdateAmmo(pp, WPN_GRENADE, DamageData[WPN_GRENADE].weapon_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup @@ -6132,7 +6131,7 @@ KeyMain: if (pp->WpnAmmo[WPN_GRENADE] >= DamageData[WPN_GRENADE].max_ammo) break; //sprintf(ds,"Grenade Shells"); - PutStringInfo(Player+pnum, DamageData[WPN_GRENADE].ammo_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_AMMOGRENADE)); PlayerUpdateAmmo(pp, WPN_GRENADE, DamageData[WPN_GRENADE].ammo_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup if (pp == Player+myconnectindex) @@ -6177,7 +6176,7 @@ KeyMain: if (TEST(pp->WpnFlags, BIT(WPN_RAIL)) && pp->WpnAmmo[WPN_RAIL] >= DamageData[WPN_RAIL].max_ammo) break; //sprintf(ds,"Rail Gun"); - PutStringInfo(Player+pnum, DamageData[WPN_RAIL].weapon_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_WPNRAILGUN)); PlayerUpdateAmmo(pp, WPN_RAIL, DamageData[WPN_RAIL].weapon_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup if (pp == Player+myconnectindex) @@ -6210,7 +6209,7 @@ KeyMain: if (pp->WpnAmmo[WPN_RAIL] >= DamageData[WPN_RAIL].max_ammo) break; //sprintf(ds,"Rail Gun Rods"); - PutStringInfo(Player+pnum, DamageData[WPN_RAIL].ammo_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_AMMORAILGUN)); PlayerUpdateAmmo(pp, WPN_RAIL, DamageData[WPN_RAIL].ammo_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup if (pp == Player+myconnectindex) @@ -6227,7 +6226,7 @@ KeyMain: if (TEST(pp->WpnFlags, BIT(WPN_SHOTGUN)) && pp->WpnAmmo[WPN_SHOTGUN] >= DamageData[WPN_SHOTGUN].max_ammo) break; //sprintf(ds,"Riot Gun"); - PutStringInfo(Player+pnum, DamageData[WPN_SHOTGUN].weapon_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_WPNRIOT)); // pp->WpnAmmo[WPN_SHOTGUN] += 10; PlayerUpdateAmmo(pp, WPN_SHOTGUN, DamageData[WPN_SHOTGUN].weapon_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup @@ -6250,7 +6249,7 @@ KeyMain: if (pp->WpnAmmo[WPN_SHOTGUN] >= DamageData[WPN_SHOTGUN].max_ammo) break; //sprintf(ds,"Shotshells"); - PutStringInfo(Player+pnum, DamageData[WPN_SHOTGUN].ammo_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_AMMORIOT)); PlayerUpdateAmmo(pp, WPN_SHOTGUN, DamageData[WPN_SHOTGUN].ammo_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash on item pickup if (pp == Player+myconnectindex) @@ -6294,7 +6293,7 @@ KeyMain: if (TEST(pp->WpnFlags, BIT(WPN_HOTHEAD)) && pp->WpnAmmo[WPN_HOTHEAD] >= DamageData[WPN_HOTHEAD].max_ammo) break; //sprintf(ds,"Guardian Head"); - PutStringInfo(Player+pnum, DamageData[WPN_HOTHEAD].weapon_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_WPNHEAD)); PlayerUpdateAmmo(pp, WPN_HOTHEAD, DamageData[WPN_HOTHEAD].weapon_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup if (pp == Player+myconnectindex) @@ -6321,7 +6320,7 @@ KeyMain: if (pp->WpnAmmo[WPN_HOTHEAD] >= DamageData[WPN_HOTHEAD].max_ammo) break; //sprintf(ds,"Firebursts"); - PutStringInfo(Player+pnum, DamageData[WPN_HOTHEAD].ammo_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_AMMOHEAD)); PlayerUpdateAmmo(pp, WPN_HOTHEAD, DamageData[WPN_HOTHEAD].ammo_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup if (pp == Player+myconnectindex) @@ -6340,7 +6339,7 @@ KeyMain: if (TEST(pp->WpnFlags, BIT(WPN_HEART)) && pp->WpnAmmo[WPN_HEART] >= DamageData[WPN_HEART].max_ammo) break; //sprintf(ds,"Ripper Heart"); - PutStringInfo(Player+pnum, DamageData[WPN_HEART].weapon_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_WPNRIPPER)); PlayerUpdateAmmo(pp, WPN_HEART, DamageData[WPN_HEART].weapon_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup if (pp == Player+myconnectindex) @@ -6369,7 +6368,7 @@ KeyMain: if (pp->WpnAmmo[WPN_HEART] >= DamageData[WPN_HEART].max_ammo) break; //sprintf(ds,"Deathcoils"); - PutStringInfo(Player+pnum, DamageData[WPN_HEART].ammo_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_AMMORIPPER)); PlayerUpdateAmmo(pp, WPN_HEART, DamageData[WPN_HEART].ammo_pickup); SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup if (pp == Player+myconnectindex) @@ -6410,7 +6409,7 @@ KeyMain: if (pp->WpnRocketHeat != 5) { //sprintf(ds,"Heat Seeker Card"); - PutStringInfo(Player+pnum, DamageData[DMG_NUCLEAR_EXP].ammo_name); + PutStringInfo(Player+pnum, quoteMgr.GetQuote(QUOTE_AMMONUKE)); pp->WpnRocketHeat = DamageData[DMG_NUCLEAR_EXP].ammo_pickup; SetFadeAmt(pp,ITEMFLASHAMT,ITEMFLASHCLR); // Flash blue on item pickup if (pp == Player+myconnectindex) diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index 008773924..b886a6458 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -1819,4 +1819,25 @@ Flash Bomb,TXTS_INV7,,,,,,,,,,,,,,,,,,,,,, Caltrops,TXTS_INV8,,,,,,,,,,,,,,,,,,,,,, Night Vision Goggles,TXTS_INV9,,,,,,,,,,,,,,,,,,,,,, Repair Kit,TXTS_INV10,,,,,,,,,,,,,,,,,,,,,, -Smoke Bomb,TXTS_INV11,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file +Smoke Bomb,TXTS_INV11,,,,,,,,,,,,,,,,,,,,,, +Fists,TXTS_WEAP1,,,,,,,,,,,,,,,,,,,,,, +Sword,TXTS_WEAP2,,,,,,,,,,,,,,,,,,,,,, +Shurikens,TXTS_WEAP3,,,,,,,,,,,,,,,,,,,,,, +Sticky Bombs,TXTS_WEAP4,,,,,,,,,,,,,,,,,,,,,, +Darts,TXTS_DARTS,,,,,,,,,,,,,,,,,,,,,, +UZI Submachine Gun,TXTS_WEAP5,,,,,,,,,,,,,,,,,,,,,, +Missile Launcher,TXTS_WEAP6,,,,,,,,,,,,,,,,,,,,,, +Nuclear Warhead,TXTS_WEAP7,,,,,,,,,,,,,,,,,,,,,, +Grenade Launcher,TXTS_WEAP8,,,,,,,,,,,,,,,,,,,,,, +Rail Gun,TXTS_WEAP9,,,,,,,,,,,,,,,,,,,,,, +Riot Gun,TXTS_WEAP10,,,,,,,,,,,,,,,,,,,,,, +Guardian Head,TXTS_WEAP11,,,,,,,,,,,,,,,,,,,,,, +Ripper Heart,TXTS_WEAP12,,,,,,,,,,,,,,,,,,,,,, +UZI Clip,TXTS_AMMO5,,,,,,,,,,,,,,,,,,,,,, +Missiles,TXTS_AMMO6,,,,,,,,,,,,,,,,,,,,,, +Heat Seeker Card,TXTS_AMMO7,,,,,,,,,,,,,,,,,,,,,, +Grenade Shells,TXTS_AMMO8,,,,,,,,,,,,,,,,,,,,,, +Rail Gun Rods,TXTS_AMMO9,,,,,,,,,,,,,,,,,,,,,, +Shotshells,TXTS_AMMO10,,,,,,,,,,,,,,,,,,,,,, +Firebursts,TXTS_AMMO11,,,,,,,,,,,,,,,,,,,,,, +Deathcoils,TXTS_AMMO12,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file diff --git a/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt b/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt index 67a1bd5c5..0a2373857 100644 --- a/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt +++ b/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt @@ -276,77 +276,77 @@ skill 4 { name "No Pain, No Gain" } -/* + inventory 1 { - name "$TXT_INV1" + name "$TXTS_INV1" amount 50 } inventory 2 { - name "$TXT_INV2" + name "$TXTS_INV2" amount 100 } inventory 3 { - name "$TXT_INV3" + name "$TXTS_INV3" amount 20 } inventory 4 { - name "$TXT_INV4" + name "$TXTS_INV4" amount 50 } inventory 5 { - name "$TXT_INV5" + name "$TXTS_INV5" amount 100 } inventory 6 { - name "$TXT_INV6" + name "$TXTS_INV6" amount 1 } inventory 7 { - name "$TXT_INV7" + name "$TXTS_INV7" amount 2 } inventory 8 { - name "$TXT_INV8" + name "$TXTS_INV8" amount 3 } inventory 9 { - name "$TXT_INV9" + name "$TXTS_INV9" amount 100 } inventory 10 { - name "$TXT_INV10" + name "$TXTS_INV10" amount 100 } inventory 11 { - name "$TXT_INV11" + name "$TXTS_INV11" amount 100 } weapon 1 { - name "Fists" + name "$TXTS_WEAP1" mindamage 10 maxdamage 40 } weapon 2 { - name "Sword" + name "$TXTS_WEAP2" mindamage 50 maxdamage 80 } weapon 3 { - name "Shurikens" + name "$TXTS_WEAP3" ammoname "" maxammo 99 mindamage 5 @@ -356,7 +356,7 @@ weapon 3 } weapon 4 { - name "Sticky Bombs" + name "$TXTS_WEAP4" ammoname "" maxammo 20 mindamage 5 @@ -366,8 +366,8 @@ weapon 4 } weapon 5 { - name "UZI Submachine Gun" - ammoname "UZI Clip" + name "$TXTS_WEAP5" + ammoname "$TXTS_AMMO5" maxammo 200 mindamage 5 maxdamage 7 @@ -376,8 +376,8 @@ weapon 5 } weapon 6 { - name "Missile Launcher" - ammoname "Missiles" + name "$TXTS_WEAP6" + ammoname "$TXTS_AMMO6" maxammo 50 mindamage 15 maxdamage 30 @@ -386,8 +386,8 @@ weapon 6 } weapon 7 { - name "Nuclear Warhead" - ammoname "" + name "$TXTS_WEAP7" + ammoname "$TXTS_AMMO7" maxammo 0 mindamage 0 maxdamage 800 @@ -396,8 +396,8 @@ weapon 7 } weapon 8 { - name "Grenade Launcher" - ammoname "Grenade Shells" + name "$TXTS_WEAP8" + ammoname "$TXTS_AMMO8" maxammo 50 mindamage 15 maxdamage 30 @@ -406,8 +406,8 @@ weapon 8 } weapon 9 { - name "Rail Gun" - ammoname "Rail Gun Rods" + name "$TXTS_WEAP9" + ammoname "$TXTS_AMMO9" maxammo 20 mindamage 40 maxdamage 60 @@ -416,8 +416,8 @@ weapon 9 } weapon 10 { - name "Riot Gun" - ammoname "Shotshells" + name "$TXTS_WEAP10" + ammoname "$TXTS_AMMO10" maxammo 52 mindamage 4 maxdamage 4 @@ -426,8 +426,8 @@ weapon 10 } weapon 11 { - name "Guardian Head" - ammoname "Firebursts" + name "$TXTS_WEAP11" + ammoname "$TXTS_AMMO11" maxammo 80 mindamage 10 maxdamage 25 @@ -436,8 +436,8 @@ weapon 11 } weapon 12 { - name "Ripper Heart" - ammoname "Deathcoils" + name "$TXTS_WEAP12" + ammoname "$TXTS_AMMO12" maxammo 5 mindamage 75 maxdamage 100 @@ -515,4 +515,3 @@ theme 6 // game end sequence song "ending.mid" cdatrack 14 } -*/ \ No newline at end of file From 6ef1f96b40cfef7c8eef45a98bc1e53a6ae3f4d6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Dec 2019 20:12:54 +0100 Subject: [PATCH 183/203] - added SWP's parser for theme music definitions. Because, why not? The SWCustom I use already contains them. However, since the original source does not play theme MIDIs - only CDA, there's a switch to disable them. --- source/sw/src/game.cpp | 24 +++++------------ source/sw/src/game.h | 2 +- source/sw/src/scrip2.cpp | 57 ++++++++++++++++++++++++++++++++++++++-- source/sw/src/sounds.cpp | 6 +++-- source/sw/src/sumo.cpp | 6 ++--- 5 files changed, 69 insertions(+), 26 deletions(-) diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 28109b1d5..a24de0dd2 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -1027,20 +1027,8 @@ LEVEL_INFO LevelInfo[MAX_LEVELS+2] = // Shareware }; #endif*/ -const char *ThemeSongs[6] = -{ - "THEME.MID", - "ENDLEV3.VOC", - "SERPENT.MID", - "SUMO.MID", - "ZILLA.MID" - "ENDING.MID" -}; - -int ThemeTrack[6] = -{ - 2,3,13,13,13,14 -}; +FString ThemeSongs[6]; +int ThemeTrack[6]; void InitNewGame(void) { @@ -1575,7 +1563,7 @@ void ResetKeyRange(uint8_t* kb, uint8_t* ke) void PlayTheme() { // start music at logo - PlaySong(nullptr, "theme.mid", RedBookSong[0]); + PlaySong(nullptr, ThemeSongs[0], ThemeTrack[0]); DSPRINTF(ds,"After music stuff..."); MONO_PRINT(ds); @@ -1679,7 +1667,7 @@ void CreditsLevel(void) while (FX_SoundActive(handle)) ; // try 14 then 2 then quit - if (!PlaySong(nullptr, nullptr, 14, true)) + if (!PlaySong(nullptr, ThemeSongs[5], ThemeTrack[5], true)) { if (!PlaySong(nullptr, nullptr, 2, true)) { @@ -2220,7 +2208,7 @@ void BonusScreen(PLAYERp pp) totalclock = ototalclock = 0; limit = synctics; - PlaySong(nullptr, voc[DIGI_ENDLEV].name, 3); + PlaySong(nullptr, ThemeSongs[1], ThemeTrack[1]); // special case code because I don't care any more! if (FinishAnim) @@ -2535,7 +2523,7 @@ void StatScreen(PLAYERp mpp) inputState.ClearKeyStatus(KEYSC_SPACE); inputState.ClearKeyStatus(KEYSC_ENTER); - PlaySong(nullptr, voc[DIGI_ENDLEV].name, 3); + PlaySong(nullptr, ThemeSongs[1], ThemeTrack[1]); while (!inputState.GetKeyStatus(KEYSC_SPACE) && !inputState.GetKeyStatus(KEYSC_ENTER)) { diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 35703d679..dc79cf0f9 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -953,7 +953,7 @@ typedef struct extern LEVEL_INFO LevelInfo[MAX_LEVELS_REG+2]; extern int ThemeTrack[6]; // w -extern const char *ThemeSongs[6]; // +extern FString ThemeSongs[6]; // #define MAX_EPISODE_NAME_LEN 24 extern char EpisodeNames[3][MAX_EPISODE_NAME_LEN+2]; diff --git a/source/sw/src/scrip2.cpp b/source/sw/src/scrip2.cpp index c7945cb1f..0c63393b6 100644 --- a/source/sw/src/scrip2.cpp +++ b/source/sw/src/scrip2.cpp @@ -404,6 +404,7 @@ enum CM_MAXAMMO, CM_DAMAGEMIN, CM_DAMAGEMAX, + CM_THEME, CM_SECRET, CM_QUIT, }; @@ -424,6 +425,7 @@ static const struct _tokset { "inventory", CM_INVENTORY }, { "weapon", CM_WEAPON }, { "needkey", CM_NEEDKEY }, + { "theme", CM_THEME }, { "secret", CM_SECRET }, { "quit", CM_QUIT }, }, @@ -475,14 +477,20 @@ static const struct _tokset { "maxdamage", CM_DAMAGEMAX }, { "pickup", CM_AMOUNT }, { "weaponpickup",CM_WEAPON }, -} -; +}, +cm_theme_tokens[] = { + { "song", CM_SONG }, + { "music", CM_SONG }, + { "cdatrack", CM_CDATRACK }, + { "cdtrack", CM_CDATRACK }, +}; #define cm_numtokens (sizeof(cm_tokens)/sizeof(cm_tokens[0])) #define cm_map_numtokens (sizeof(cm_map_tokens)/sizeof(cm_map_tokens[0])) #define cm_episode_numtokens (sizeof(cm_episode_tokens)/sizeof(cm_episode_tokens[0])) #define cm_skill_numtokens (sizeof(cm_skill_tokens)/sizeof(cm_skill_tokens[0])) #define cm_inventory_numtokens (sizeof(cm_inventory_tokens)/sizeof(cm_inventory_tokens[0])) #define cm_weapons_numtokens (sizeof(cm_weapons_tokens)/sizeof(cm_weapons_tokens[0])) +#define cm_theme_numtokens (sizeof(cm_theme_tokens)/sizeof(cm_theme_tokens[0])) static int cm_transtok(const char *tok, const struct _tokset *set, const unsigned num) @@ -964,6 +972,51 @@ void LoadCustomInfoFromScript(const char *filename) } break; } + case CM_THEME: + { + char *epnumptr; + char *name = NULL; + int trak = -1; + + if (scriptfile_getnumber(script, &curmap)) break; epnumptr = script->ltextptr; + if (scriptfile_getbraces(script, &braceend)) break; + if ((unsigned)--curmap >= 6u) + { + initprintf("Error: theme number %d not in range 1-6 on line %s:%d\n", + curmap, script->filename, + scriptfile_getlinum(script,epnumptr)); + script->textptr = braceend; + break; + } + while (script->textptr < braceend) + { + if (!(token = scriptfile_gettoken(script))) break; + if (token == braceend) break; + switch (cm_transtok(token, cm_theme_tokens, cm_theme_numtokens)) + { + case CM_SONG: + if (scriptfile_getstring(script, &name)) break; + break; + case CM_CDATRACK: + if (scriptfile_getnumber(script, &trak)) break; + break; + default: + initprintf("Error on line %s:%d\n", + script->filename, + scriptfile_getlinum(script,script->ltextptr)); + break; + } + } + if (name) + { + ThemeSongs[curmap] = name; + } + if (trak >= 2) + { + ThemeTrack[curmap] = trak; + } + break; + } case CM_SECRET: case CM_QUIT: default: diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp index 044e3d198..580c3008a 100644 --- a/source/sw/src/sounds.cpp +++ b/source/sw/src/sounds.cpp @@ -308,6 +308,7 @@ InitFX(void) } extern short Level; +CVAR(Bool, sw_nothememidi, false, CVAR_ARCHIVE) SWBOOL PlaySong(const char* mapname, const char* song_file_name, int cdaudio_track, bool isThemeTrack) //(nullptr, nullptr, -1, false) starts the normal level music. { @@ -316,8 +317,8 @@ SWBOOL PlaySong(const char* mapname, const char* song_file_name, int cdaudio_tra // Get the music defined for the current level. } - // Play CD audio if enabled or if this is a theme track. - if (cdaudio_track >= 0 && (mus_redbook || isThemeTrack)) + // Play CD audio if enabled. + if (cdaudio_track >= 0 && mus_redbook) { FStringf trackname("track%02d.ogg", cdaudio_track); if (!Mus_Play(nullptr, trackname, true)) @@ -325,6 +326,7 @@ SWBOOL PlaySong(const char* mapname, const char* song_file_name, int cdaudio_tra buildprintf("Can't find CD track %i!\n", cdaudio_track); } } + else if (isThemeTrack && sw_nothememidi) return false; // The original SW source only used CD Audio for theme tracks, so this is optional. return Mus_Play(nullptr, song_file_name, true); } diff --git a/source/sw/src/sumo.cpp b/source/sw/src/sumo.cpp index b638f1de1..dab78c9c2 100644 --- a/source/sw/src/sumo.cpp +++ b/source/sw/src/sumo.cpp @@ -883,7 +883,7 @@ BossHealthMeter(void) serpwasseen = TRUE; if (!SW_SHAREWARE) { - PlaySong(nullptr, nullptr, ThemeTrack[2], true); + PlaySong(nullptr, ThemeSongs[2], ThemeTrack[2], true); } } else if (i == 1 && !sumowasseen) @@ -891,7 +891,7 @@ BossHealthMeter(void) sumowasseen = TRUE; if (!SW_SHAREWARE) { - PlaySong(nullptr, nullptr, ThemeTrack[3], true); + PlaySong(nullptr, ThemeSongs[3], ThemeTrack[3], true); } } else if (i == 2 && !zillawasseen) @@ -899,7 +899,7 @@ BossHealthMeter(void) zillawasseen = TRUE; if (!SW_SHAREWARE) { - PlaySong(nullptr, nullptr, ThemeTrack[4], true); + PlaySong(nullptr, ThemeSongs[4], ThemeTrack[4], true); } } } From 16818d2d71d6059a79c09c544ffea9020ae2c3c6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Dec 2019 21:19:05 +0100 Subject: [PATCH 184/203] - exported Shadow Warrior strings to stringtable. The MP obituaries are not handled yet, they were only copied but there's no code using them. --- source/sw/src/cheats.cpp | 45 ++++++--------- source/sw/src/game.cpp | 16 +++--- source/sw/src/player.cpp | 9 +-- source/sw/src/rotator.cpp | 2 +- source/sw/src/scrip2.cpp | 40 ------------- source/sw/src/sector.cpp | 6 +- source/sw/src/slidor.cpp | 2 +- source/sw/src/vator.cpp | 2 +- source/sw/src/weapon.cpp | 81 +++++++++++++------------- wadsrc/static/demolition/language.csv | 83 ++++++++++++++++++++++++++- 10 files changed, 162 insertions(+), 124 deletions(-) diff --git a/source/sw/src/cheats.cpp b/source/sw/src/cheats.cpp index e44e2ff0b..529d38fd1 100644 --- a/source/sw/src/cheats.cpp +++ b/source/sw/src/cheats.cpp @@ -45,6 +45,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "control.h" #include "gamecontrol.h" +#include "gstrings.h" //#include "inv.h" BEGIN_SW_NS @@ -104,8 +105,7 @@ void MapCheat(PLAYERp pp, const char *) else MapSetAll2D(0xFF); - sprintf(ds, "AUTOMAPPING %s", automapping ? "ON" : "OFF" ); - PutStringInfo(pp, ds); + PutStringInfo(pp, GStrings(automapping ? "TXT_AMON" : "TXT_AMOFF")); } void LocCheat(PLAYERp pp, const char *) @@ -123,7 +123,7 @@ void GunsCheat(PLAYERp pp, const char *cheat_string) unsigned int i; short gAmmo[10] = {0,9,12,20,3,6,5,5,10,1}; const char *cp = cheat_string; - const char *str = "GIVEN WEAPON %1d"; + const char *str = "TXT_GIVENW"; int gunnum, x; USERp u; @@ -142,17 +142,16 @@ void GunsCheat(PLAYERp pp, const char *cheat_string) if (TEST(p->WpnFlags, BIT(gunnum-1)) == 0) p->WpnFlags += BIT(gunnum-2) << 1; else - str = "ADD AMMO TO WEAPON %1d"; + str = "TXTS_AMMOW"; p->WpnAmmo[gunnum-1] += x; if (p->WpnAmmo[gunnum-1] > DamageData[gunnum-1].max_ammo) { p->WpnAmmo[gunnum-1] = DamageData[gunnum-1].max_ammo; - str = ""; + str = nullptr; } PlayerUpdateWeapon(p, u->WeaponNum); } - sprintf(ds, str, gunnum); - PutStringInfo(pp, ds); + if (str) PutStringInfo(pp, FStringf("%s %d", GStrings(str), gunnum)); } void WeaponCheat(PLAYERp pp, const char *) @@ -195,16 +194,13 @@ void GodCheat(PLAYERp pp, const char *) // GodMode ^= 1; - sprintf(ds, "GOD MODE %s", GodMode ? "ON" : "OFF"); - PutStringInfo(pp, ds); + PutStringInfo(pp, GStrings(GodMode? "GOD MODE: ON" : "GOD MODE: OFF")); } void ClipCheat(PLAYERp pp, const char *) { FLIP(pp->Flags, PF_CLIP_CHEAT); - - sprintf(ds, "NO CLIP MODE %s", TEST(pp->Flags, PF_CLIP_CHEAT) ? "ON" : "OFF"); - PutStringInfo(pp, ds); + PutStringInfo(pp, GStrings(TEST(pp->Flags, PF_CLIP_CHEAT) ? "CLIPPING: OFF" : "CLIPPING: ON"));; } void WarpCheat(PLAYERp pp, const char *cheat_string) @@ -233,7 +229,7 @@ void WarpCheat(PLAYERp pp, const char *cheat_string) Level = level_num; ExitLevel = TRUE; - sprintf(ds, "ENTERING %1d", Level); + sprintf(ds, "%s %1d", GStrings("TXT_ENTERING"), Level); PutStringInfo(pp, ds); } @@ -284,15 +280,15 @@ void ItemCheat(PLAYERp pp, const char *cheat_string) VOID HealCheat(PLAYERp pp, const char *cheat_string) { short pnum; - const char *str = ""; + const char *str = nullptr; TRAVERSE_CONNECT(pnum) { if (User[Player[pnum].PlayerSprite]->Health < pp->MaxHealth) - str = "ADDED HEALTH"; + str = "TXTS_ADDEDHEALTH"; User[Player[pnum].PlayerSprite]->Health += 25; } - PutStringInfo(pp, str); + if (str) PutStringInfo(pp, GStrings(str)); } VOID SortKeyCheat(PLAYERp pp, const char *sKey) @@ -359,7 +355,7 @@ VOID KeysCheat(PLAYERp pp, const char *cheat_string) PLAYERp p; short pnum; const char *cp = cheat_string; - const char *str = "Given all keys"; + const char *str = "TXT_GIVEKEY"; int keynum = 0; cp += sizeof("swkey")-1; @@ -378,21 +374,17 @@ VOID KeysCheat(PLAYERp pp, const char *cheat_string) if (p->HasKey[keynum-1] == FALSE) { p->HasKey[keynum-1] = TRUE; // cards: 0=red 1=blue 2=green 3=yellow | keys: 4=gold 5=silver 6=bronze 7=red - str = "Given %s"; + str = "TXT_KEYGIVEN"; } else { p->HasKey[keynum-1] = FALSE; - str = "Removed %s"; + str = "TXT_KEYREMOVED"; } } } PlayerUpdateKeys(pp); - if (keynum == 0) - sprintf(ds, str); - else - sprintf(ds, str, CheatKeyType); - PutStringInfo(pp, ds); + PutStringInfo(pp, GStrings(str)); } void EveryCheatToggle(PLAYERp pp, const char *cheat_string) @@ -402,9 +394,6 @@ void EveryCheatToggle(PLAYERp pp, const char *cheat_string) WeaponCheat(pp, cheat_string); GodCheat(pp, cheat_string); ItemCheat(pp, cheat_string); - - sprintf(ds, "EVERY CHEAT %s", EveryCheat ? "ON" : "OFF"); - PutStringInfo(pp, ds); } void GeorgeFunc(PLAYERp pp, char *) @@ -521,7 +510,7 @@ void CheatInput(void) if (Skill >= 3) { - PutStringInfo(Player, "You're too skillful to cheat\n"); + PutStringInfo(Player, GStrings("TXTS_TOOSKILLFUL")); return; } } diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index a24de0dd2..42314b735 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -98,6 +98,7 @@ Things required to make savegames work: #include "menu/menu.h" #include "z_music.h" #include "statistics.h" +#include "gstrings.h" //#include "crc32.h" @@ -2413,17 +2414,18 @@ void StatScreen(PLAYERp mpp) memset(death_total,0,sizeof(death_total)); memset(kills,0,sizeof(kills)); - sprintf(ds,"MULTIPLAYER TOTALS"); - MNU_MeasureString(ds, &w, &h); - MNU_DrawString(TEXT_TEST_COL(w), 68, ds, 0, 0); + auto c = GStrings("MULTIPLAYER TOTALS"); + MNU_MeasureString(c, &w, &h); + MNU_DrawString(TEXT_TEST_COL(w), 68, c, 0, 0); - sprintf(ds,"PRESS SPACE BAR TO CONTINUE"); - MNU_MeasureString(ds, &w, &h); - MNU_DrawString(TEXT_TEST_COL(w), 189, ds, 0, 0); + c = GStrings("TXTS_PRESSSPACE"); + MNU_MeasureString(c, &w, &h); + MNU_DrawString(TEXT_TEST_COL(w), 189, c, 0, 0); x = STAT_START_X; y = STAT_START_Y; + // Hm.... how to translate this without messing up the formatting? sprintf(ds," NAME 1 2 3 4 5 6 7 8 KILLS"); DisplayMiniBarSmString(mpp, x, y, 0, ds); rows = OrigCommPlayers; @@ -2485,7 +2487,7 @@ void StatScreen(PLAYERp mpp) x = STAT_START_X; y += STAT_OFF_Y; - sprintf(ds," DEATHS"); + sprintf(ds," %s", GStrings("DEATHS")); DisplayMiniBarSmString(mpp, x, y, 0, ds); x = STAT_TABLE_X; diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index 838bf4d3e..f320a223a 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -66,6 +66,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "track.h" #include "interp.h" #include "menu/menu.h" +#include "gstrings.h" BEGIN_SW_NS @@ -6521,7 +6522,7 @@ DoPlayerBeginDie(PLAYERp pp) { bak = GlobInfoStringTime; GlobInfoStringTime = 999; - PutStringInfo(pp, "Press SPACE to restart"); + PutStringInfo(pp, GStrings("TXT_PRESSSPACER")); GlobInfoStringTime = bak; } @@ -7880,11 +7881,11 @@ void PauseMultiPlay(void) if (GamePaused) { short w,h; -#define MSG_GAME_PAUSED "Game Paused" - MNU_MeasureString(MSG_GAME_PAUSED, &w, &h); + auto m = GStrings("Game Paused"); + MNU_MeasureString(m, &w, &h); TRAVERSE_CONNECT(p) - PutStringTimer(Player + p, TEXT_TEST_COL(w), 100, MSG_GAME_PAUSED, 999); + PutStringTimer(Player + p, TEXT_TEST_COL(w), 100, m, 999); SavePrediction = PredictionOn; PredictionOn = FALSE; diff --git a/source/sw/src/rotator.cpp b/source/sw/src/rotator.cpp index 029656b6f..dcf0d2a3c 100644 --- a/source/sw/src/rotator.cpp +++ b/source/sw/src/rotator.cpp @@ -181,7 +181,7 @@ DoRotatorMatch(PLAYERp pp, short match, SWBOOL manual) // SWBOOL 8 must be set for message to display if (TEST_BOOL4(fsp) && (gNet.MultiGameType == MULTI_GAME_COMMBAT || gNet.MultiGameType == MULTI_GAME_AI_BOTS)) { - if (pp && TEST_BOOL11(fsp)) PutStringInfo(pp,"This only opens in single play."); + if (pp && TEST_BOOL11(fsp)) PutStringInfo(pp, GStrings("TXT_SPONLY")); continue; } diff --git a/source/sw/src/scrip2.cpp b/source/sw/src/scrip2.cpp index 0c63393b6..fa18faa62 100644 --- a/source/sw/src/scrip2.cpp +++ b/source/sw/src/scrip2.cpp @@ -506,46 +506,6 @@ static int cm_transtok(const char *tok, const struct _tokset *set, const unsigne return -1; } -// level # { -// title "Map Name" -// filename "filename.map" -// song "filename.mid" -// cdatrack n -// besttime secs -// partime secs -// } -// -// episode # { -// title "Episode Name" -// subtitle "Caption text" -// } -// -// skill # { -// name "Tiny grasshopper" -// } -// -// fortune { -// "You never going to score." -// "26-31-43-82-16-29" -// "Sorry, you no win this time, try again." -// } -// gotkey { -// "Got the RED key!" -// "Got the BLUE key!" -// "Got the GREEN key!" -// ... -// } -// needkey { -// "You need a RED key for this door." -// "You need a BLUE key for this door." -// "You need a GREEN key for this door." -// ... -// } -// inventory # { name "Armour" amount 50 } -// weapon # { name "Uzi Submachine Gun" ammoname "Uzi Clip" maxammo 200 mindamage 5 maxdamage 7 pickup 50 } -// secret "You found a secret area!" -// quit "PRESS (Y) TO QUIT, (N) TO FIGHT ON." - static LEVEL_INFO custommaps[MAX_LEVELS_REG]; #define WM_DAMAGE 1 diff --git a/source/sw/src/sector.cpp b/source/sw/src/sector.cpp index f8d1be778..e62347ed8 100644 --- a/source/sw/src/sector.cpp +++ b/source/sw/src/sector.cpp @@ -46,6 +46,8 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "common_game.h" #include "light.h" #include "text.h" +#include "gstrings.h" +#include "secrets.h" BEGIN_SW_NS @@ -2141,7 +2143,9 @@ OperateTripTrigger(PLAYERp pp) PlayerSound(DIGI_ANCIENTSECRET, &pp->posx, &pp->posy, &pp->posz, v3df_dontpan|v3df_doppler|v3df_follow,pp); - sprintf(ds,"You found a secret area!"); + sprintf(ds, GStrings("TXTS_SECRET")); + SECRET_Trigger(pp->cursectnum); + PutStringInfo(pp, ds); // always give to the first player Player->SecretsFound++; diff --git a/source/sw/src/slidor.cpp b/source/sw/src/slidor.cpp index f13de4bf7..a1161d6d7 100644 --- a/source/sw/src/slidor.cpp +++ b/source/sw/src/slidor.cpp @@ -177,7 +177,7 @@ DoSlidorMatch(PLAYERp pp, short match, SWBOOL manual) // SWBOOL 8 must be set for message to display if (TEST_BOOL4(fsp) && (gNet.MultiGameType == MULTI_GAME_COMMBAT || gNet.MultiGameType == MULTI_GAME_AI_BOTS)) { - if (pp && TEST_BOOL11(fsp)) PutStringInfo(pp,"This only opens in single play."); + if (pp && TEST_BOOL11(fsp)) PutStringInfo(pp, GStrings("TXTS_SPONLY")); continue; } diff --git a/source/sw/src/vator.cpp b/source/sw/src/vator.cpp index bb3f013ea..3a580ab85 100644 --- a/source/sw/src/vator.cpp +++ b/source/sw/src/vator.cpp @@ -242,7 +242,7 @@ DoVatorMatch(PLAYERp pp, short match) // SWBOOL 8 must be set for message to display if (TEST_BOOL4(fsp) && (gNet.MultiGameType == MULTI_GAME_COMMBAT || gNet.MultiGameType == MULTI_GAME_AI_BOTS)) { - if (pp && TEST_BOOL11(fsp)) PutStringInfo(pp,"This only opens in single play."); + if (pp && TEST_BOOL11(fsp)) PutStringInfo(pp, GStrings("TXTS_SPONLY")); continue; } diff --git a/source/sw/src/weapon.cpp b/source/sw/src/weapon.cpp index 217c4b896..c5f255cf8 100644 --- a/source/sw/src/weapon.cpp +++ b/source/sw/src/weapon.cpp @@ -48,6 +48,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "actor.h" #include "track.h" #include "player.h" +#include "gstrings.h" BEGIN_SW_NS @@ -7466,94 +7467,94 @@ const char *DeathString(short SpriteNum) case NINJA_RUN_R0: return " "; case ZOMBIE_RUN_R0: - return "Zombie"; + return GStrings("Zombie"); case BLOOD_WORM: - return "Blood Worm"; + return GStrings("Blood Worm"); case SKEL_RUN_R0: - return "Skeletor Priest"; + return GStrings("Skeletor Priest"); case COOLG_RUN_R0: - return "Coolie Ghost"; + return GStrings("Coolie Ghost"); case GORO_RUN_R0: - return "Guardian"; + return GStrings("Guardian"); case HORNET_RUN_R0: - return "Hornet"; + return GStrings("Hornet"); case RIPPER_RUN_R0: - return "Ripper Hatchling"; + return GStrings("Ripper Hatchling"); case RIPPER2_RUN_R0: - return "Ripper"; + return GStrings("Ripper"); case BUNNY_RUN_R0: - return "Killer Rabbit"; + return GStrings("Killer Rabbit"); case SERP_RUN_R0: - return "Serpent god"; + return GStrings("Serpent god"); case GIRLNINJA_RUN_R0: - return "Girl Ninja"; + return GStrings("Girl Ninja"); case BLADE1: case BLADE2: case BLADE3: case 5011: - return "blade"; + return GStrings("blade"); case STAR1: - if (sw_darts) return "dart"; - else return "shuriken"; + if (sw_darts) return GStrings("dart"); + else return GStrings("shuriken"); case CROSSBOLT: - return "crossbow bolt"; + return GStrings("crossbow bolt"); case SPEAR_R0: - return "spear"; + return GStrings("spear"); case LAVA_BOULDER: case LAVA_SHARD: - return "lava boulder"; + return GStrings("lava boulder"); case UZI_SMOKE: - return "Uzi"; + return GStrings("Uzi"); case UZI_SMOKE+2: - return "Evil Ninja Uzi"; + return GStrings("Evil Ninja Uzi"); case SHOTGUN_SMOKE: - return "shotgun"; + return GStrings("shotgun"); case MIRV_METEOR: case SERP_METEOR: - return "meteor"; + return GStrings("meteor"); case BOLT_THINMAN_R0: - return "rocket"; + return GStrings("rocket"); case BOLT_THINMAN_R1: - return "rail gun"; + return GStrings("rail gun"); case BOLT_THINMAN_R2: - return "enemy rocket"; + return GStrings("enemy rocket"); case BOLT_THINMAN_R4: // BunnyRocket - return "bunny rocket"; + return GStrings("bunny rocket"); case BOLT_EXP: - return "explosion"; + return GStrings("explosion"); case TANK_SHELL_EXP: - return "tank shell"; + return GStrings("tank shell"); case MUSHROOM_CLOUD: - return "nuclear bomb"; + return GStrings("nuclear bomb"); case GRENADE_EXP: - return "40mm grenade"; + return GStrings("40mm grenade"); case MICRO_EXP: - return "micro missile"; + return GStrings("micro missile"); case MINE_EXP: //case MINE_SHRAP: - return "sticky bomb"; + return GStrings("sticky bomb"); case NAP_EXP: - return "napalm"; + return GStrings("napalm"); case Vomit1: case Vomit2: - return "vomit"; + return GStrings("vomit"); case COOLG_FIRE: - return "Coolie Ghost phlem"; + return GStrings("Coolie Ghost phlem"); case SKULL_R0: - return "Accursed Head"; + return GStrings("Accursed Head"); case BETTY_R0: - return "Bouncing Betty"; + return GStrings("Bouncing Betty"); case SKULL_SERP: - return "Serpent god Protector"; + return GStrings("Serpent god Protector"); case FIREBALL1: case FIREBALL: case GORO_FIREBALL: case FIREBALL_FLAMES: - return "flames"; + return GStrings("flames"); case RADIATION_CLOUD: - return "radiation"; + return GStrings("radiation"); case CALTROPS: - return "caltrops"; + return GStrings("caltrops"); } return ""; } diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index b886a6458..b85d6e8cd 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -1840,4 +1840,85 @@ Grenade Shells,TXTS_AMMO8,,,,,,,,,,,,,,,,,,,,,, Rail Gun Rods,TXTS_AMMO9,,,,,,,,,,,,,,,,,,,,,, Shotshells,TXTS_AMMO10,,,,,,,,,,,,,,,,,,,,,, Firebursts,TXTS_AMMO11,,,,,,,,,,,,,,,,,,,,,, -Deathcoils,TXTS_AMMO12,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file +Deathcoils,TXTS_AMMO12,,,,,,,,,,,,,,,,,,,,,, +"Automapping ON +",TXTS_AMON,,,,,,,,,,,,,,,,,,,,,, +Automapping OFF,TXTS_AMOFF,,,,,,,,,,,,,,,,,,,,,, +Given Weapon,TXTS_GIVENW,,,,,,,,,,,,,,,,,,,,,, +Add Ammo to Weapon,TXTS_AMMOW,,,,,,,,,,,,,,,,,,,,,, +Added Health,TXTS_ADDEDHEALTH,,,,,,,,,,,,,,,,,,,,,, +Given all keys,TXTS_GIVEKEY,,,,,,,,,,,,,,,,,,,,,, +Key given,TXTS_KEYGIVEN,,,,,,,,,,,,,,,,,,,,,, +Key removed,TXTS_KEYREMOVED,,,,,,,,,,,,,,,,,,,,,, +You're too skillful to cheat,TXTS_TOOSKILLFUL,,,,,,,,,,,,,,,,,,,,,, +Press Space Bar to continue,TXTS_PRESSSPACE,,,,,,,,,,,,,,,,,,,,,, +Press SPACE to restart,TXTS_PRESSSPACER,,,,,,,,,,,,,,,,,,,,,, +%p decided to do the graveyard tour.,TXTS_SUICIDE01,"todo (player.cpp, line 6346ff)",,,,,,,,,,,,,,,,,,,,, +%p had enough and checked out.,TXTS_SUICIDE02,,,,,,,,,,,,,,,,,,,,,, +%p didn't fear the Reaper.,TXTS_SUICIDE03,,,,,,,,,,,,,,,,,,,,,, +%p dialed the 1-800-CYANIDE line.,TXTS_SUICIDE04,,,,,,,,,,,,,,,,,,,,,, +%p wasted himself.,TXTS_SUICIDE05,,,,,,,,,,,,,,,,,,,,,, +%p kicked his own ass.,TXTS_SUICIDE06,,,,,,,,,,,,,,,,,,,,,, +%p went out in blaze of his own glory.,TXTS_SUICIDE07,,,,,,,,,,,,,,,,,,,,,, +%p killed himself before anyone else could.,TXTS_SUICIDE08,,,,,,,,,,,,,,,,,,,,,, +%p needs shooting lessons.,TXTS_SUICIDE09,,,,,,,,,,,,,,,,,,,,,, +%p blew his head off.,TXTS_SUICIDE10,,,,,,,,,,,,,,,,,,,,,, +%p did everyone a favor and offed himself,TXTS_SUICIDE11,,,,,,,,,,,,,,,,,,,,,, +%p was wasted by %k's %z.,TXTS_MPOBIT01,,,,,,,,,,,,,,,,,,,,,, +%p got his ass kicked by %k's %z.,TXTS_MPOBIT02,,,,,,,,,,,,,,,,,,,,,, +%p bows down before the mighty power of %z.,TXTS_MPOBIT03,,,,,,,,,,,,,,,,,,,,,, +%p was killed by %k's %z.,TXTS_MPOBIT04,,,,,,,,,,,,,,,,,,,,,, +%p got slapped down hard by %k's %z.,TXTS_MPOBIT05,,,,,,,,,,,,,,,,,,,,,, +%p got on his knees before %k.,TXTS_MPOBIT06,,,,,,,,,,,,,,,,,,,,,, +%p was totally out classed by %k's %z.,TXTS_MPOBIT07,,,,,,,,,,,,,,,,,,,,,, +%p got chewed apart by %k's %z.,TXTS_MPOBIT08,,,,,,,,,,,,,,,,,,,,,, +%p was retired by %k's %z.,TXTS_MPOBIT09,,,,,,,,,,,,,,,,,,,,,, +%p was greased by %k's %z.,TXTS_MPOBIT10,,,,,,,,,,,,,,,,,,,,,, +%p was humbled lower than dirt by %k.,TXTS_MPOBIT11,,,,,,,,,,,,,,,,,,,,,, +%p beats %k like a red headed step child.,TXTS_MPOBIT12,,,,,,,,,,,,,,,,,,,,,, +%p begs for mercy as %k terminates @[en_ppro] with extreme prejudice.,TXTS_MPOBIT13,,,,,,,,,,,,,,,,,,,,,, +%p falls before the superior skills of %k.,TXTS_MPOBIT14,,,,,,,,,,,,,,,,,,,,,, +%k gives %p a beating @[en_pro] will never forget.,TXTS_MPOBIT15,,,,,,,,,,,,,,,,,,,,,, +%k puts the Smack Dab on %p with the %z.,TXTS_MPOBIT16,,,,,,,,,,,,,,,,,,,,,, +This only opens in single play.,TXTS_SPONLY,,,,,,,,,,,,,,,,,,,,,, +You found a secret area!,TXTS_SECRET,,,,,,,,,,,,,,,,,,,,,, +Zombie,Zombie,,,,,,,,,,,,,,,,,,,,,, +Blood Worm,Blood Worm,,,,,,,,,,,,,,,,,,,,,, +Skeletor Priest,Skeletor Priest,,,,,,,,,,,,,,,,,,,,,, +Coolie Ghost,Coolie Ghost,,,,,,,,,,,,,,,,,,,,,, +Guardian,Guardian,,,,,,,,,,,,,,,,,,,,,, +Hornet,Hornet,,,,,,,,,,,,,,,,,,,,,, +Ripper Hatchling,Ripper Hatchling,,,,,,,,,,,,,,,,,,,,,, +Ripper,Ripper,,,,,,,,,,,,,,,,,,,,,, +Killer Rabbit,Killer Rabbit,,,,,,,,,,,,,,,,,,,,,, +Serpent God,Serpent God,,,,,,,,,,,,,,,,,,,,,, +Girl Ninja,Girl Ninja,,,,,,,,,,,,,,,,,,,,,, +Blade,Blade,,,,,,,,,,,,,,,,,,,,,, +Dart,Dart,,,,,,,,,,,,,,,,,,,,,, +Shuriken,Shuriken,,,,,,,,,,,,,,,,,,,,,, +Crossbow Bolt,Crossbow Bolt,,,,,,,,,,,,,,,,,,,,,, +Spear,Spear,,,,,,,,,,,,,,,,,,,,,, +Lava Boulder,Lava Boulder,,,,,,,,,,,,,,,,,,,,,, +Uzi,Uzi,,,,,,,,,,,,,,,,,,,,,, +Evil Ninja Uzi,Evil Ninja Uzi,,,,,,,,,,,,,,,,,,,,,, +Shotgun,Shotgun,,,,,,,,,,,,,,,,,,,,,, +Meteor,Meteor,,,,,,,,,,,,,,,,,,,,,, +Rocket,Rocket,,,,,,,,,,,,,,,,,,,,,, +Rail Gun,Rail Gun,,,,,,,,,,,,,,,,,,,,,, +Enemy Rocket,Enemy Rocket,,,,,,,,,,,,,,,,,,,,,, +Bunny Rocket,Bunny Rocket,,,,,,,,,,,,,,,,,,,,,, +Explosion,Explosion,,,,,,,,,,,,,,,,,,,,,, +Tank Shell,Tank Shell,,,,,,,,,,,,,,,,,,,,,, +Nuclear Bomb,Nuclear Bomb,,,,,,,,,,,,,,,,,,,,,, +40mm Grenade,40mm Grenade,,,,,,,,,,,,,,,,,,,,,, +Micro Missile,Micro Missile,,,,,,,,,,,,,,,,,,,,,, +Sticky Bomb,Sticky Bomb,,,,,,,,,,,,,,,,,,,,,, +Napalm,Napalm,,,,,,,,,,,,,,,,,,,,,, +Vomit,Vomit,,,,,,,,,,,,,,,,,,,,,, +Coolie Ghost Phlem,Coolie Ghost Phlem,,,,,,,,,,,,,,,,,,,,,, +Accursed Head,Accursed Head,,,,,,,,,,,,,,,,,,,,,, +Bouncing Betty,Bouncing Betty,,,,,,,,,,,,,,,,,,,,,, +Serpent God Protector,Serpent God Protector,,,,,,,,,,,,,,,,,,,,,, +Flames,Flames,,,,,,,,,,,,,,,,,,,,,, +Radiation,Radiation,,,,,,,,,,,,,,,,,,,,,, +Caltrops,Caltrops,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file From 3b57f38e55b1fc5b9116afb9d554bb557f0a3e14 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 10 Dec 2019 00:01:45 +0100 Subject: [PATCH 185/203] - started transitioning to a global mapinfo list. This will make it a lot easier for cross-game parts of the engine to query game state. So far the EDuke frontend has been ported over. --- source/common/gamecontrol.cpp | 4 +++ source/common/mapinfo.h | 41 +++++++++++++++++++++ source/common/quotes.cpp | 3 +- source/duke3d/src/cheats.cpp | 3 +- source/duke3d/src/game.cpp | 8 ++--- source/duke3d/src/gamedef.cpp | 36 ++++++------------- source/duke3d/src/gameexec.cpp | 7 ++-- source/duke3d/src/network.cpp | 3 +- source/duke3d/src/osdcmds.cpp | 3 +- source/duke3d/src/premap.cpp | 65 ++++++++++++++++------------------ source/duke3d/src/savegame.cpp | 17 ++++----- source/duke3d/src/screens.cpp | 40 +++++++++++---------- source/duke3d/src/sector.h | 4 +-- source/duke3d/src/sounds.cpp | 7 ++-- 14 files changed, 137 insertions(+), 104 deletions(-) create mode 100644 source/common/mapinfo.h diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index 2a52ac741..400eb0732 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -26,10 +26,14 @@ #include "menu.h" #include "gstrings.h" #include "quotemgr.h" +#include "mapinfo.h" #ifndef NETCODE_DISABLE #include "enet.h" #endif +MapRecord mapList[512]; // Due to how this gets used it needs to be static. EDuke defines 7 episode plus one spare episode with 64 potential levels each and relies on the static array which is freely accessible by scripts. +MapRecord *currentLevel; + void C_CON_SetAliases(); InputState inputState; void SetClipshapes(); diff --git a/source/common/mapinfo.h b/source/common/mapinfo.h new file mode 100644 index 000000000..8ff323376 --- /dev/null +++ b/source/common/mapinfo.h @@ -0,0 +1,41 @@ +#pragma once + +#include "gstrings.h" + +// Localization capable replacement of the game specific solutions. + +inline void MakeStringLocalizable(FString "e) +{ + // Only prepend a quote if the string is localizable. + if (quote.Len() > 0 && quote[0] != '$' && GStrings[quote]) quote.Insert(0, "$"); +} + +struct MapRecord +{ + int parTime; + int designerTime; + FString fileName; + FString name; + FString music; + int cdSongId; + + // The rest is only used by Blood + int nextLevel; + int nextSecret; + int messageStart; // messages are stored in the quote array to reduce clutter. + FString author; + // bool fog, weather; // Blood defines these but they aren't used. + + const char *DisplayName() + { + return GStrings.localize(name); + } + void SetName(const char *n) + { + name = n; + MakeStringLocalizable(name); + } +}; + +extern MapRecord mapList[512]; +extern MapRecord *currentLevel; \ No newline at end of file diff --git a/source/common/quotes.cpp b/source/common/quotes.cpp index c3805db0c..1b2099d1a 100644 --- a/source/common/quotes.cpp +++ b/source/common/quotes.cpp @@ -42,7 +42,8 @@ void Quotes::MakeStringLabel(FString "e) { - quote.Insert(0, "$"); + // Only prepend a quote if the string is localizable. + if (quote.Len() > 0 && quote[0] != '$' && GStrings[quote]) quote.Insert(0, "$"); } void Quotes::InitializeQuote(int num, const char *text, bool fromscript) diff --git a/source/duke3d/src/cheats.cpp b/source/duke3d/src/cheats.cpp index 7fc529c23..ff4d030d5 100644 --- a/source/duke3d/src/cheats.cpp +++ b/source/duke3d/src/cheats.cpp @@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "duke3d.h" #include "osdcmds.h" +#include "mapinfo.h" BEGIN_DUKE_NS @@ -555,7 +556,7 @@ void G_DoCheats(void) int32_t const volnume = ud.m_volume_number, levnume = m_level_number; if ((!VOLUMEONE || volnume == 0) && (unsigned)volnume < (unsigned)g_volumeCnt && - (unsigned)levnume < MAXLEVELS && g_mapInfo[volnume*MAXLEVELS + levnume].filename != NULL) + (unsigned)levnume < MAXLEVELS && mapList[volnume*MAXLEVELS + levnume].fileName.IsNotEmpty()) { ud.volume_number = volnume; ud.level_number = levnume; diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 437826802..1f35b744a 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -48,6 +48,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "filesystem/filesystem.h" #include "statistics.h" #include "menu/menu.h" +#include "mapinfo.h" // Uncomment to prevent anything except mirrors from drawing. It is sensible to // also uncomment ENGINE_CLEAR_SCREEN in build/src/engine_priv.h. @@ -4814,7 +4815,8 @@ static int32_t S_DefineMusic(const char *ID, const char *name) return -1; } - return S_DefineAudioIfSupported(&g_mapInfo[sel].musicfn, name); + mapList[sel].music = name; + return 0; } static int parsedefinitions_game(scriptfile *, int); @@ -5389,10 +5391,6 @@ static void G_Cleanup(void) for (i=(MAXLEVELS*(MAXVOLUMES+1))-1; i>=0; i--) // +1 volume for "intro", "briefing" music { - Xfree(g_mapInfo[i].name); - Xfree(g_mapInfo[i].filename); - Xfree(g_mapInfo[i].musicfn); - G_FreeMapState(i); } diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index 9e1e7283d..512dbb955 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "m_argv.h" #include "menu/menu.h" #include "stringtable.h" +#include "mapinfo.h" void C_CON_SetButtonAlias(int num, const char* text); void C_CON_ClearButtonAlias(int num); @@ -2029,10 +2030,7 @@ void C_DefineMusic(int volumeNum, int levelNum, const char *fileName) if (strcmp(fileName, "/.") == 0) return; - map_t *const pMapInfo = &g_mapInfo[(MAXLEVELS*volumeNum)+levelNum]; - - Xfree(pMapInfo->musicfn); - pMapInfo->musicfn = dup_filename(fileName); + mapList[(MAXLEVELS * volumeNum) + levelNum].music = fileName; } void C_DefineVolumeFlags(int32_t vol, int32_t flags) @@ -2084,12 +2082,12 @@ void C_UndefineLevel(int32_t vol, int32_t lev) Bassert((unsigned)vol < MAXVOLUMES); Bassert((unsigned)lev < MAXLEVELS); - map_t *const map = &g_mapInfo[(MAXLEVELS*vol)+lev]; + auto& gmap = mapList[(MAXLEVELS * vol) + lev]; - DO_FREE_AND_NULL(map->filename); - DO_FREE_AND_NULL(map->name); - map->partime = 0; - map->designertime = 0; + gmap.fileName = ""; + gmap.name = ""; + gmap.parTime = 0; + gmap.designerTime = 0; } LUNATIC_EXTERN int32_t C_SetDefName(const char *name) @@ -5174,16 +5172,11 @@ repeatcase: Bcorrectfilename(tempbuf,0); - if (g_mapInfo[j *MAXLEVELS+k].filename == NULL) - g_mapInfo[j *MAXLEVELS+k].filename = (char *)Xcalloc(Bstrlen(tempbuf)+1,sizeof(uint8_t)); - else if ((Bstrlen(tempbuf)+1) > sizeof(g_mapInfo[j*MAXLEVELS+k].filename)) - g_mapInfo[j *MAXLEVELS+k].filename = (char *)Xrealloc(g_mapInfo[j*MAXLEVELS+k].filename,(Bstrlen(tempbuf)+1)); - - Bstrcpy(g_mapInfo[j*MAXLEVELS+k].filename,tempbuf); + mapList[j * MAXLEVELS + k].fileName = tempbuf; C_SkipComments(); - g_mapInfo[j *MAXLEVELS+k].partime = + mapList[j *MAXLEVELS+k].parTime = (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*REALGAMETICSPERSEC*60)+ (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*REALGAMETICSPERSEC); @@ -5193,7 +5186,7 @@ repeatcase: // cheap hack, 0.99 doesn't have the 3D Realms time if (*(textptr+2) == ':') { - g_mapInfo[j *MAXLEVELS+k].designertime = + mapList[j *MAXLEVELS+k].designerTime = (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*REALGAMETICSPERSEC*60)+ (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*REALGAMETICSPERSEC); @@ -5220,14 +5213,7 @@ repeatcase: tempbuf[i] = '\0'; - if (g_mapInfo[j*MAXLEVELS+k].name == NULL) - g_mapInfo[j*MAXLEVELS+k].name = (char *)Xcalloc(Bstrlen(tempbuf)+1,sizeof(uint8_t)); - else if ((Bstrlen(tempbuf)+1) > sizeof(g_mapInfo[j*MAXLEVELS+k].name)) - g_mapInfo[j *MAXLEVELS+k].name = (char *)Xrealloc(g_mapInfo[j*MAXLEVELS+k].name,(Bstrlen(tempbuf)+1)); - - /* initprintf("level name string len: %d\n",Bstrlen(tempbuf)); */ - - Bstrcpy(g_mapInfo[j*MAXLEVELS+k].name,tempbuf); + mapList[j * MAXLEVELS + k].SetName(tempbuf); continue; diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index c5f06aaeb..4c0df3108 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -40,6 +40,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "menu/menu.h" #include "c_dispatch.h" #include "quotemgr.h" +#include "mapinfo.h" #include "debugbreak.h" extern bool rotatesprite_2doverride; @@ -3752,13 +3753,13 @@ badindex: int const levelNum = ud.volume_number * MAXLEVELS + ud.level_number; const char *pName; - if (EDUKE32_PREDICT_FALSE((unsigned)levelNum >= ARRAY_SIZE(g_mapInfo))) + if (EDUKE32_PREDICT_FALSE((unsigned)levelNum >= ARRAY_SIZE(mapList))) { CON_ERRPRINTF("out of bounds map number (vol=%d, lev=%d)\n", ud.volume_number, ud.level_number); abort_after_error(); } - pName = j == STR_MAPNAME ? g_mapInfo[levelNum].name : g_mapInfo[levelNum].filename; + pName = j == STR_MAPNAME ? mapList[levelNum].DisplayName() : mapList[levelNum].fileName.GetChars(); if (EDUKE32_PREDICT_FALSE(pName == NULL)) { @@ -3767,7 +3768,7 @@ badindex: abort_after_error(); } - quoteMgr.InitializeQuote(q, j == STR_MAPNAME ? g_mapInfo[levelNum].name : g_mapInfo[levelNum].filename); + quoteMgr.InitializeQuote(q, j == STR_MAPNAME ? mapList[levelNum].DisplayName() : mapList[levelNum].fileName.GetChars()); break; } case STR_PLAYERNAME: diff --git a/source/duke3d/src/network.cpp b/source/duke3d/src/network.cpp index 8f78e2c56..614b1a817 100644 --- a/source/duke3d/src/network.cpp +++ b/source/duke3d/src/network.cpp @@ -37,6 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "savegame.h" #include "input.h" #include "gamecvars.h" +#include "mapinfo.h" #include "enet.h" #include "m_crc32.h" @@ -2037,7 +2038,7 @@ static void Net_ReceiveMapVoteInitiate(uint8_t *pbuf) vote_map = pendingnewgame.level_number; Bsprintf(tempbuf, GStrings("votemap"), g_player[voting].user_name, - g_mapInfo[(uint8_t)(vote_episode * MAXLEVELS + vote_map)].name, vote_episode + 1, vote_map + 1); + mapList[(uint8_t)(vote_episode * MAXLEVELS + vote_map)].DisplayName(), vote_episode + 1, vote_map + 1); G_AddUserQuote(tempbuf); strcpy(tempbuf, GStrings("TXT_PRESSF1_F2")); diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index bb9239fd0..d39dbdd8f 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "menus.h" #include "savegame.h" #include "sbar.h" +#include "mapinfo.h" BEGIN_DUKE_NS @@ -59,7 +60,7 @@ static int osdcmd_changelevel(osdcmdptr_t parm) if (volume < 0 || level < 0) return OSDCMD_SHOWHELP; - if (level > MAXLEVELS || g_mapInfo[volume * MAXLEVELS + level].filename == NULL) + if (level > MAXLEVELS || mapList[volume * MAXLEVELS + level].fileName.IsEmpty()) { OSD_Printf("changelevel: no map defined for episode %d level %d\n", volume + 1, level + 1); return OSDCMD_SHOWHELP; diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index 8c5f3aa9b..84a9ece65 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -30,6 +30,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "savegame.h" #include "statistics.h" #include "menu/menu.h" +#include "mapinfo.h" +#include "cmdlib.h" BEGIN_DUKE_NS static uint8_t precachehightile[2][(MAXTILES+7)>>3]; @@ -379,9 +381,7 @@ static void G_DoLoadScreen(const char *statustext, int percent) else { menutext_center(90, GStrings("TXT_LOADING")); - - if (g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name != NULL) - menutext_center(90+16+8, g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name); + menutext_center(90+16+8, mapList[(ud.volume_number*MAXLEVELS) + ud.level_number].DisplayName()); } #ifndef EDUKE32_TOUCH_DEVICES @@ -1621,13 +1621,11 @@ int G_FindLevelByFile(const char *fileName) { int i = 0; - for (auto &levelNum : g_mapInfo) + for (auto &levelNum : mapList) { i++; - if (levelNum.filename == NULL) - continue; - else if (!Bstrcasecmp(fileName, levelNum.filename)) + if (levelNum.fileName.CompareNoCase(fileName) == 0) return i-1; } @@ -1691,20 +1689,18 @@ void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName) { char *p; char const *exts[] = { -#ifdef HAVE_FLAC "flac", -#endif -#ifdef HAVE_VORBIS "ogg", -#endif -#ifdef HAVE_XMP + "mp3", "xm", "mod", "it", "s3m", "mtm", -#endif - "mid" + "mid", + "hmp", + "hmi", + "xmi" }; Bstrncpy(nameBuf, fileName, BMAX_PATH); @@ -1717,31 +1713,32 @@ void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName) p[0] = '.'; } + // Test if a real file with this name exists with all known extensions for music. for (auto & ext : exts) { Bmemcpy(p+1, ext, Bstrlen(ext) + 1); - if (fileSystem.FileExists(nameBuf)) + if (FileExists(nameBuf)) { - realloc_copy(&g_mapInfo[USERMAPMUSICFAKESLOT].musicfn, nameBuf); + mapList[USERMAPMUSICFAKESLOT].music = nameBuf; return; } } - char const * usermapMusic = g_mapInfo[MUS_USERMAP].musicfn; - if (usermapMusic != nullptr) + auto &usermapMusic = mapList[MUS_USERMAP].music; + if (usermapMusic.IsNotEmpty()) { - realloc_copy(&g_mapInfo[USERMAPMUSICFAKESLOT].musicfn, usermapMusic); + mapList[USERMAPMUSICFAKESLOT].music = usermapMusic; return; } #ifndef EDUKE32_STANDALONE if (!FURY) { - char const * e1l8 = g_mapInfo[7].musicfn; - if (e1l8 != nullptr) + auto &e1l8 = mapList[7].music; + if (e1l8.IsNotEmpty()) { - realloc_copy(&g_mapInfo[USERMAPMUSICFAKESLOT].musicfn, e1l8); + mapList[USERMAPMUSICFAKESLOT].music = e1l8; return; } } @@ -1816,13 +1813,13 @@ int G_EnterLevel(int gameMode) int const mapidx = (ud.volume_number * MAXLEVELS) + ud.level_number; - Bassert((unsigned)mapidx < ARRAY_SIZE(g_mapInfo)); + Bassert((unsigned)mapidx < ARRAY_SIZE(mapList)); - auto &m = g_mapInfo[mapidx]; + auto& mm = mapList[mapidx]; if (VOLUMEONE || !Menu_HaveUserMap()) { - if (m.name == NULL || m.filename == NULL) + if (mm.name.IsEmpty() || mm.fileName.IsEmpty()) { OSD_Printf(OSDTEXT_RED "Map E%dL%d not defined!\n", ud.volume_number+1, ud.level_number+1); return 1; @@ -1856,15 +1853,15 @@ int G_EnterLevel(int gameMode) G_LoadMapHack(levelName, boardfilename); G_SetupFilenameBasedMusic(levelName, boardfilename); } - else if (engineLoadBoard(m.filename, VOLUMEONE, &p0.pos, &playerAngle, &p0.cursectnum) < 0) + else if (engineLoadBoard(mm.fileName, VOLUMEONE, &p0.pos, &playerAngle, &p0.cursectnum) < 0) { - OSD_Printf(OSD_ERROR "Map \"%s\" not found or invalid map version!\n", m.filename); + OSD_Printf(OSD_ERROR "Map \"%s\" not found or invalid map version!\n", mm.fileName.GetChars()); return 1; } else { - STAT_NewLevel(m.filename); - G_LoadMapHack(levelName, m.filename); + STAT_NewLevel(mm.fileName); + G_LoadMapHack(levelName, mm.fileName); } p0.q16ang = fix16_from_int(playerAngle); @@ -1885,7 +1882,7 @@ int G_EnterLevel(int gameMode) G_ResetAllPlayers(); G_CollectSpawnPoints(gameMode); - ud.playerbest = CONFIG_GetMapBestTime(Menu_HaveUserMap() ? boardfilename : m.filename, g_loadedMapHack.md4); + ud.playerbest = CONFIG_GetMapBestTime(Menu_HaveUserMap() ? boardfilename : mm.fileName.GetChars(), g_loadedMapHack.md4); // G_FadeLoad(0,0,0, 252,0, -28, 4, -1); G_CacheMapData(); @@ -1897,8 +1894,8 @@ int G_EnterLevel(int gameMode) { S_PlayLevelMusicOrNothing(USERMAPMUSICFAKESLOT); } - else if (g_mapInfo[g_musicIndex].musicfn == NULL || m.musicfn == NULL || - strcmp(g_mapInfo[g_musicIndex].musicfn, m.musicfn) || g_musicSize == 0 || ud.last_level == -1) + else if (mapList[g_musicIndex].music.IsEmpty() || mm.music.IsEmpty() || mapList[g_musicIndex].music.CompareNoCase(mm.music) == 0 || + g_musicSize == 0 || ud.last_level == -1) { S_PlayLevelMusicOrNothing(mapidx); } @@ -1960,9 +1957,9 @@ int G_EnterLevel(int gameMode) if (G_HaveUserMap()) OSD_Printf(OSDTEXT_YELLOW "%s: %s\n", GStrings("TXT_USERMAP"), boardfilename); else if (FURY) - OSD_Printf(OSDTEXT_YELLOW "%s: %s\n", GStrings("TXT_ENTERING"), m.name); + OSD_Printf(OSDTEXT_YELLOW "%s: %s\n", GStrings("TXT_ENTERING"), mm.DisplayName()); else - OSD_Printf(OSDTEXT_YELLOW "E%dL%d: %s\n", ud.volume_number + 1, ud.level_number + 1, m.name); + OSD_Printf(OSDTEXT_YELLOW "E%dL%d: %s\n", ud.volume_number + 1, ud.level_number + 1, mm.DisplayName()); g_restorePalette = -1; diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index b7d9ee2c1..6a7c1489b 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "version.h" #include "savegamehelp.h" #include "menu/menu.h" +#include "mapinfo.h" #include "z_music.h" BEGIN_DUKE_NS @@ -317,9 +318,9 @@ int32_t G_LoadPlayer(FSaveGameNode *sv) int const mapIdx = volume*MAXLEVELS + level; if (boardfilename[0]) - Bstrcpy(currentboardfilename, boardfilename); - else if (g_mapInfo[mapIdx].filename) - Bstrcpy(currentboardfilename, g_mapInfo[mapIdx].filename); + strcpy(currentboardfilename, boardfilename); + else if (mapList[mapIdx].fileName.IsNotEmpty()) + strcpy(currentboardfilename, mapList[mapIdx].fileName); if (currentboardfilename[0]) @@ -519,9 +520,9 @@ int32_t G_LoadPlayer(FSaveGameNode *sv) int const mapIdx = h.volnum*MAXLEVELS + h.levnum; if (boardfilename[0]) - Bstrcpy(currentboardfilename, boardfilename); - else if (g_mapInfo[mapIdx].filename) - Bstrcpy(currentboardfilename, g_mapInfo[mapIdx].filename); + strcpy(currentboardfilename, boardfilename); + else if (mapList[mapIdx].fileName.IsNotEmpty()) + strcpy(currentboardfilename, mapList[mapIdx].fileName); if (currentboardfilename[0]) { @@ -1469,8 +1470,8 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i auto fw = WriteSavegameChunk("header.dat"); fw->Write(&h, sizeof(savehead_t)); - auto& mi = g_mapInfo[(MAXLEVELS * ud.volume_number) + ud.level_number]; - G_WriteSaveHeader(name, mi.filename, mi.name); + auto& mii = mapList[(MAXLEVELS * ud.volume_number) + ud.level_number]; + G_WriteSaveHeader(name, mii.fileName, mii.DisplayName()); } else { diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index 5dbdac236..0deef00c2 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "screens.h" #include "gamecvars.h" #include "menu/menu.h" +#include "mapinfo.h" BEGIN_DUKE_NS @@ -183,7 +184,7 @@ static void G_ShowScores(void) if (g_mostConcurrentPlayers > 1 && (g_gametypeFlags[ud.coop]&GAMETYPE_SCORESHEET)) { gametext_center(SCORESHEETOFFSET+58+2, GStrings("Multiplayer Totals")); - gametext_center(SCORESHEETOFFSET+58+10, g_mapInfo[G_LastMapInfoIndex()].name); + gametext_center(SCORESHEETOFFSET+58+10, mapList[G_LastMapInfoIndex()].DisplayName()); t = 0; minitext(70, SCORESHEETOFFSET+80, GStrings("Name"), 8, 2+8+16+ROTATESPRITE_MAX); @@ -958,7 +959,7 @@ void G_DisplayRest(int32_t smoothratio) if (textret == 0 && ud.overhead_on == 2) { const int32_t a = (ud.screen_size > 0) ? 147 : 179; - char const * levelname = g_mapInfo[ud.volume_number*MAXLEVELS + ud.level_number].name; + char const * levelname = mapList[ud.volume_number*MAXLEVELS + ud.level_number].DisplayName(); if (G_HaveUserMap()) levelname = boardfilename; else if (!(G_GetLogoFlags() & LOGO_HIDEEPISODE)) @@ -993,12 +994,13 @@ void G_DisplayRest(int32_t smoothratio) else if (g_levelTextTime < 5) o |= 1; - if (g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name != NULL) + auto dname = mapList[(ud.volume_number * MAXLEVELS) + ud.level_number].DisplayName(); + if (dname != NULL && *dname != 0) { char const * const fn = currentboardfilename[0] != 0 && ud.volume_number == 0 && ud.level_number == 7 ? currentboardfilename - : g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name; + : dname; menutext_(160<<16, (90+16+8)<<16, -g_levelTextTime+22/*quotepulseshade*/, fn, o, TEXT_XCENTER); } @@ -1102,7 +1104,7 @@ void G_DisplayRest(int32_t smoothratio) { Bsprintf(tempbuf, "%s^00 has called a vote for map", g_player[voting].user_name); gametext_center(40, tempbuf); - Bsprintf(tempbuf, "%s (E%dL%d)", g_mapInfo[vote_episode*MAXLEVELS + vote_map].name, vote_episode+1, vote_map+1); + Bsprintf(tempbuf, "%s (E%dL%d)", mapList[vote_episode*MAXLEVELS + vote_map].DisplayName(), vote_episode+1, vote_map+1); gametext_center(48, tempbuf); gametext_center(70, "Press F1 to Accept, F2 to Decline"); } @@ -1883,7 +1885,7 @@ static void G_DisplayMPResultsScreen(void) if (PLUTOPAK) // JBF 20030804 rotatesprite_fs((260)<<16, 36<<16, 65536L, 0, PLUTOPAKSPRITE+2, 0, 0, 2+8); gametext_center(58+2, GStrings("Multiplayer Totals")); - gametext_center(58+10, g_mapInfo[G_LastMapInfoIndex()].name); + gametext_center(58+10, mapList[G_LastMapInfoIndex()].DisplayName()); gametext_center_shade(165, GStrings("Presskey"), quotepulseshade); @@ -1951,11 +1953,11 @@ static int32_t G_PrintTime_ClockPad(void) clockpad = max(clockpad, ij); if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - for (ii=g_mapInfo[G_LastMapInfoIndex()].partime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } + for (ii=mapList[G_LastMapInfoIndex()].parTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } clockpad = max(clockpad, ij); - if (!NAM_WW2GI && g_mapInfo[G_LastMapInfoIndex()].designertime) + if (!NAM_WW2GI && mapList[G_LastMapInfoIndex()].designerTime) { - for (ii=g_mapInfo[G_LastMapInfoIndex()].designertime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } + for (ii= mapList[G_LastMapInfoIndex()].designerTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } clockpad = max(clockpad, ij); } } @@ -1984,13 +1986,13 @@ const char* G_PrintParTime(void) { if (ud.last_level < 1) return ""; - return G_PrintTime2(g_mapInfo[G_LastMapInfoIndex()].partime); + return G_PrintTime2(mapList[G_LastMapInfoIndex()].parTime); } const char* G_PrintDesignerTime(void) { if (ud.last_level < 1) return ""; - return G_PrintTime2(g_mapInfo[G_LastMapInfoIndex()].designertime); + return G_PrintTime2(mapList[G_LastMapInfoIndex()].designerTime); } const char* G_PrintBestTime(void) { @@ -2002,7 +2004,7 @@ void G_BonusScreen(int32_t bonusonly) int32_t gfx_offset; int32_t bonuscnt; int32_t clockpad = 2; - char *lastmapname; + const char *lastmapname; if (g_networkMode == NET_DEDICATED_SERVER) return; @@ -2015,9 +2017,9 @@ void G_BonusScreen(int32_t bonusonly) } else { - lastmapname = g_mapInfo[G_LastMapInfoIndex()].name; - if (!lastmapname) // this isn't right but it's better than no name at all - lastmapname = g_mapInfo[G_LastMapInfoIndex()].name; + lastmapname = mapList[G_LastMapInfoIndex()].name; + if (!lastmapname || !*lastmapname) // this isn't right but it's better than no name at all + lastmapname = mapList[G_LastMapInfoIndex()].fileName; } @@ -2183,12 +2185,12 @@ void G_BonusScreen(int32_t bonusonly) yy+=10; if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - if (g_mapInfo[G_LastMapInfoIndex()].partime) + if (mapList[G_LastMapInfoIndex()].parTime) { gametext(10, yy+9, GStrings("TXT_ParTime")); yy+=10; } - if (!NAM_WW2GI && !DUKEBETA && g_mapInfo[G_LastMapInfoIndex()].designertime) + if (!NAM_WW2GI && !DUKEBETA && mapList[G_LastMapInfoIndex()].designerTime) { // EDuke 2.0 / NAM source suggests "Green Beret's Time:" gametext(10, yy+9, GStrings("TXT_3DRTIME")); @@ -2227,13 +2229,13 @@ void G_BonusScreen(int32_t bonusonly) if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - if (g_mapInfo[G_LastMapInfoIndex()].partime) + if (mapList[G_LastMapInfoIndex()].parTime) { G_PrintParTime(); gametext_number((320>>2)+71, yy+9, tempbuf); yy+=10; } - if (!NAM_WW2GI && !DUKEBETA && g_mapInfo[G_LastMapInfoIndex()].designertime) + if (!NAM_WW2GI && !DUKEBETA && mapList[G_LastMapInfoIndex()].designerTime) { G_PrintDesignerTime(); gametext_number((320>>2)+71, yy+9, tempbuf); diff --git a/source/duke3d/src/sector.h b/source/duke3d/src/sector.h index 031ac2a4a..4d1801ad3 100644 --- a/source/duke3d/src/sector.h +++ b/source/duke3d/src/sector.h @@ -106,12 +106,10 @@ extern void G_SaveMapState(); extern void G_RestoreMapState(); typedef struct { - int32_t partime, designertime; - char *name, *filename, *musicfn; mapstate_t *savedstate; } map_t; -//extern map_t g_mapInfo[(MAXVOLUMES+1)*MAXLEVELS]; // +1 volume for "intro", "briefing" music + void G_ActivateBySector(int sect,int spriteNum); int S_FindMusicSFX(int sectNum, int *sndptr); diff --git a/source/duke3d/src/sounds.cpp b/source/duke3d/src/sounds.cpp index f52c48e23..995abb546 100644 --- a/source/duke3d/src/sounds.cpp +++ b/source/duke3d/src/sounds.cpp @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "al_midi.h" #include "openaudio.h" #include "z_music.h" +#include "mapinfo.h" #include BEGIN_DUKE_NS @@ -147,15 +148,15 @@ void S_PlayLevelMusicOrNothing(unsigned int m) if (retval >= 0) { - Mus_Play(g_mapInfo[m].filename, g_mapInfo[m].musicfn, true); + Mus_Play(mapList[m].fileName, mapList[m].music, true); S_SetMusicIndex(m); } } int S_TryPlaySpecialMusic(unsigned int m) { - char const * musicfn = g_mapInfo[m].musicfn; - if (musicfn != NULL) + auto &musicfn = mapList[m].music; + if (musicfn.IsNotEmpty()) { if (!Mus_Play(nullptr, musicfn, true)) { From 4f04fe66de0c6ba6e5992e3bb5ca6fdfbd4e08ec Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 10 Dec 2019 00:31:55 +0100 Subject: [PATCH 186/203] - transitioned RR to the new mapinfo --- source/common/textures/buildtiles.cpp | 5 +- source/duke3d/src/savegame.cpp | 42 ++-- source/rr/src/cheats.cpp | 3 +- source/rr/src/game.cpp | 11 +- source/rr/src/gamedef.cpp | 26 +- source/rr/src/net.cpp | 336 +------------------------- source/rr/src/osdcmds.cpp | 3 +- source/rr/src/premap.cpp | 78 +++--- source/rr/src/savegame.cpp | 21 +- source/rr/src/screens.cpp | 58 ++--- source/rr/src/sector.h | 3 - source/rr/src/sounds.cpp | 7 +- 12 files changed, 115 insertions(+), 478 deletions(-) diff --git a/source/common/textures/buildtiles.cpp b/source/common/textures/buildtiles.cpp index bd21fafe7..1238ea97a 100644 --- a/source/common/textures/buildtiles.cpp +++ b/source/common/textures/buildtiles.cpp @@ -556,12 +556,15 @@ void artClearMapArt(void) //========================================================================== // -// Load map specfici ART +// Load map specficied ART // //========================================================================== +static FString currentMapArt; void artSetupMapArt(const char* filename) { + if (currentMapArt.CompareNoCase(filename)) return; + currentMapArt = filename; artClearMapArt(); FStringf firstname("%s_00.art", filename); diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index 6a7c1489b..1e2e30a17 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -38,7 +38,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_DUKE_NS static OutputFileCounter savecounter; -char previousboardfilename[BMAX_PATH]; // For storing pointers in files. // back_p==0: ptr -> "small int" @@ -221,6 +220,8 @@ static int different_user_map; // XXX: keyboard input 'blocked' after load fail? (at least ESC?) int32_t G_LoadPlayer(FSaveGameNode *sv) { + char workbuffer[BMAX_PATH]; + if (sv->bIsExt) { int volume = -1; @@ -318,19 +319,17 @@ int32_t G_LoadPlayer(FSaveGameNode *sv) int const mapIdx = volume*MAXLEVELS + level; if (boardfilename[0]) - strcpy(currentboardfilename, boardfilename); + strcpy(workbuffer, boardfilename); else if (mapList[mapIdx].fileName.IsNotEmpty()) - strcpy(currentboardfilename, mapList[mapIdx].fileName); + strcpy(workbuffer, mapList[mapIdx].fileName); - if (currentboardfilename[0]) + if (workbuffer[0]) { // only setup art if map differs from previous - if (!previousboardfilename[0] || Bstrcmp(previousboardfilename, currentboardfilename)) - artSetupMapArt(currentboardfilename); - Bstrcpy(previousboardfilename, currentboardfilename); - append_ext_UNSAFE(currentboardfilename, ".mhk"); - engineLoadMHK(currentboardfilename); + artSetupMapArt(workbuffer); + append_ext_UNSAFE(workbuffer, ".mhk"); + engineLoadMHK(workbuffer); } currentboardfilename[0] = '\0'; @@ -519,20 +518,19 @@ int32_t G_LoadPlayer(FSaveGameNode *sv) int const mapIdx = h.volnum*MAXLEVELS + h.levnum; - if (boardfilename[0]) - strcpy(currentboardfilename, boardfilename); - else if (mapList[mapIdx].fileName.IsNotEmpty()) - strcpy(currentboardfilename, mapList[mapIdx].fileName); + if (boardfilename[0]) + strcpy(workbuffer, boardfilename); + else if (mapList[mapIdx].fileName.IsNotEmpty()) + strcpy(workbuffer, mapList[mapIdx].fileName); - if (currentboardfilename[0]) - { - // only setup art if map differs from previous - if (!previousboardfilename[0] || Bstrcmp(previousboardfilename, currentboardfilename)) - artSetupMapArt(currentboardfilename); - Bstrcpy(previousboardfilename, currentboardfilename); - append_ext_UNSAFE(currentboardfilename, ".mhk"); - engineLoadMHK(currentboardfilename); - } + + if (workbuffer[0]) + { + // only setup art if map differs from previous + artSetupMapArt(workbuffer); + append_ext_UNSAFE(workbuffer, ".mhk"); + engineLoadMHK(workbuffer); + } Bmemcpy(currentboardfilename, boardfilename, BMAX_PATH); diff --git a/source/rr/src/cheats.cpp b/source/rr/src/cheats.cpp index bfdda7e15..3c01dea68 100644 --- a/source/rr/src/cheats.cpp +++ b/source/rr/src/cheats.cpp @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "duke3d.h" #include "osdcmds.h" #include "cheats.h" +#inclide "mapinfo.h" BEGIN_RR_NS @@ -554,7 +555,7 @@ void G_DoCheats(void) int32_t const volnume = ud.m_volume_number, levnume = m_level_number; if ((!VOLUMEONE || volnume == 0) && (unsigned)volnume < (unsigned)g_volumeCnt && - (unsigned)levnume < MAXLEVELS && g_mapInfo[volnume*MAXLEVELS + levnume].filename != NULL) + (unsigned)levnume < MAXLEVELS && mapList[volnume*MAXLEVELS + levnume].fileName.IsNotEmpty()) { ud.volume_number = volnume; ud.level_number = levnume; diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 0dff6a3d7..72afda81e 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------- +//------------------------------------------------------------------------- /* Copyright (C) 2016 EDuke32 developers and contributors @@ -47,6 +47,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "filesystem/filesystem.h" #include "statistics.h" #include "c_dispatch.h" +#include "mapinfo.h" // Uncomment to prevent anything except mirrors from drawing. It is sensible to // also uncomment ENGINE_CLEAR_SCREEN in build/src/engine_priv.h. @@ -6366,8 +6367,8 @@ static int32_t S_DefineMusic(const char *ID, const char *name) if (sel < 0) return -1; } - - return S_DefineAudioIfSupported(&g_mapInfo[sel].musicfn, name); + mapList[sel].music = name; + return 0; } static int parsedefinitions_game(scriptfile *, int); @@ -6798,10 +6799,6 @@ static void G_Cleanup(void) for (i=(MAXLEVELS*(MAXVOLUMES+1))-1; i>=0; i--) // +1 volume for "intro", "briefing" music { - Bfree(g_mapInfo[i].name); - Bfree(g_mapInfo[i].filename); - Bfree(g_mapInfo[i].musicfn); - G_FreeMapState(i); } diff --git a/source/rr/src/gamedef.cpp b/source/rr/src/gamedef.cpp index 6941e90a9..582bdc011 100644 --- a/source/rr/src/gamedef.cpp +++ b/source/rr/src/gamedef.cpp @@ -37,6 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "printf.h" #include "menu/menu.h" #include "stringtable.h" +#include "mapinfo.h" BEGIN_RR_NS @@ -886,10 +887,7 @@ void C_DefineMusic(int volumeNum, int levelNum, const char *fileName) Bassert((unsigned)volumeNum < MAXVOLUMES+1); Bassert((unsigned)levelNum < MAXLEVELS); - map_t *const pMapInfo = &g_mapInfo[(MAXLEVELS*volumeNum)+levelNum]; - - Bfree(pMapInfo->musicfn); - pMapInfo->musicfn = dup_filename(fileName); + mapList[(MAXLEVELS*volumeNum)+levelNum].music = fileName; } void C_DefineVolumeFlags(int32_t vol, int32_t flags) @@ -1873,16 +1871,11 @@ static int32_t C_ParseCommand(int32_t loop) Bcorrectfilename(tempbuf,0); - if (g_mapInfo[j *MAXLEVELS+k].filename == NULL) - g_mapInfo[j *MAXLEVELS+k].filename = (char *)Xcalloc(Bstrlen(tempbuf)+1,sizeof(uint8_t)); - else if ((Bstrlen(tempbuf)+1) > sizeof(g_mapInfo[j*MAXLEVELS+k].filename)) - g_mapInfo[j *MAXLEVELS+k].filename = (char *)Xrealloc(g_mapInfo[j*MAXLEVELS+k].filename,(Bstrlen(tempbuf)+1)); - - Bstrcpy(g_mapInfo[j*MAXLEVELS+k].filename,tempbuf); + mapList[j *MAXLEVELS+k].fileName = tempbuf; C_SkipComments(); - g_mapInfo[j *MAXLEVELS+k].partime = + mapList[j *MAXLEVELS+k].parTime = (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*REALGAMETICSPERSEC*60)+ (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*REALGAMETICSPERSEC); @@ -1892,7 +1885,7 @@ static int32_t C_ParseCommand(int32_t loop) // cheap hack, 0.99 doesn't have the 3D Realms time if (*(textptr+2) == ':') { - g_mapInfo[j *MAXLEVELS+k].designertime = + mapList[j *MAXLEVELS+k].designerTime = (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*REALGAMETICSPERSEC*60)+ (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*REALGAMETICSPERSEC); @@ -1919,14 +1912,7 @@ static int32_t C_ParseCommand(int32_t loop) tempbuf[i] = '\0'; - if (g_mapInfo[j*MAXLEVELS+k].name == NULL) - g_mapInfo[j*MAXLEVELS+k].name = (char *)Xcalloc(Bstrlen(tempbuf)+1,sizeof(uint8_t)); - else if ((Bstrlen(tempbuf)+1) > sizeof(g_mapInfo[j*MAXLEVELS+k].name)) - g_mapInfo[j *MAXLEVELS+k].name = (char *)Xrealloc(g_mapInfo[j*MAXLEVELS+k].name,(Bstrlen(tempbuf)+1)); - - /* initprintf("level name string len: %d\n",Bstrlen(tempbuf)); */ - - Bstrcpy(g_mapInfo[j*MAXLEVELS+k].name,tempbuf); + mapList[j *MAXLEVELS+k].name = tempbuf; continue; diff --git a/source/rr/src/net.cpp b/source/rr/src/net.cpp index edeb400a5..993283e75 100644 --- a/source/rr/src/net.cpp +++ b/source/rr/src/net.cpp @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "savegame.h" #include "input.h" #include "m_crc32.h" +#include "mapinfo.h" #include "enet.h" @@ -2359,340 +2360,7 @@ void Net_ParsePacket(uint8_t *packbuf, int packbufleng) //case PACKET_TYPE_QUIT: // G_GameExit(" "); // break; -#if 0 - default: - switch (packbuf[0]) - { - case PACKET_TYPE_MESSAGE: - //slaves in M/S mode only send to master - if ((!g_networkBroadcastMode) && (myconnectindex == connecthead)) - { - if (packbuf[1] == 255) - { - //Master re-transmits message to all others - for (i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) - if (i != other) - Net_SendPacket(i,packbuf,packbufleng); - } - else if (((int)packbuf[1]) != myconnectindex) - { - //Master re-transmits message not intended for master - Net_SendPacket((int)packbuf[1],packbuf,packbufleng); - break; - } - } - Bstrcpy(recbuf,(char*)packbuf+2); - recbuf[packbufleng-2] = 0; - - G_AddUserQuote(recbuf); - S_PlaySound(EXITMENUSOUND); - - pus = NUMPAGES; - pub = NUMPAGES; - - break; - - case PACKET_TYPE_NEW_GAME: - //Slaves in M/S mode only send to master - //Master re-transmits message to all others - if ((!g_networkBroadcastMode) && (myconnectindex == connecthead)) - for (i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) - if (i != other) Net_SendPacket(i,packbuf,packbufleng); - - if (vote_map != -1 || vote_episode != -1 || voting != -1) - G_AddUserQuote("VOTE SUCCEEDED"); - - m_level_number = ud.level_number = packbuf[1]; - ud.m_volume_number = ud.volume_number = packbuf[2]; - ud.m_player_skill = ud.player_skill = packbuf[3]; - - // Non-menu variables handled by G_EnterLevel - ud.m_monsters_off = packbuf[4]; - ud.m_respawn_monsters = packbuf[5]; - ud.m_respawn_items = packbuf[6]; - ud.m_respawn_inventory = packbuf[7]; - m_coop = packbuf[8]; - m_marker = packbuf[9]; - m_ffire = packbuf[10]; - m_noexits = packbuf[11]; - //ud.m_weaponstay = packbuf[12]; - - for (int TRAVERSE_CONNECT(i)) - { - P_ResetWeapons(i); - P_ResetInventory(i); - } - - G_NewGame(ud.volume_number,ud.level_number,ud.player_skill); - - if (G_EnterLevel(MODE_GAME)) G_BackToMenu(); - - break; - - case PACKET_TYPE_INIT_SETTINGS: - //Slaves in M/S mode only send to master - //Master re-transmits message to all others - if ((!g_networkBroadcastMode) && (myconnectindex == connecthead)) - for (i = connectpoint2[connecthead]; i >= 0; i = connectpoint2[i]) - if (i != other) Net_SendPacket(i, packbuf, packbufleng); - - m_level_number = ud.level_number = packbuf[1]; - ud.m_volume_number = ud.volume_number = packbuf[2]; - ud.m_player_skill = ud.player_skill = packbuf[3]; - - // Non-menu variables handled by G_EnterLevel - ud.m_monsters_off = packbuf[4]; - ud.m_respawn_monsters = packbuf[5]; - ud.m_respawn_items = packbuf[6]; - ud.m_respawn_inventory = packbuf[7]; - m_coop = packbuf[8]; - m_marker = packbuf[9]; - m_ffire = packbuf[10]; - m_noexits = packbuf[11]; - //ud.m_weaponstay = packbuf[12]; - break; - - case PACKET_TYPE_VERSION: - //slaves in M/S mode only send to master - //Master re-transmits message to all others - if ((!g_networkBroadcastMode) && (myconnectindex == connecthead)) - for (i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) - if (i != other) Net_SendPacket(i,packbuf,packbufleng); - - if (packbuf[2] != (char)atoi(s_buildDate)) - { - initprintf("Player has version %d, expecting %d\n",packbuf[2],(char)atoi(s_buildDate)); - G_GameExit("You cannot play with different versions of EDuke32!"); - } - if (packbuf[3] != (char)BYTEVERSION) - { - initprintf("Player has version %d, expecting %d (%d, %d, %d)\n",packbuf[3],BYTEVERSION, NETVERSION, PLUTOPAK, VOLUMEONE); - G_GameExit("You cannot play Duke with different versions!"); - } - if (packbuf[4] > g_numSyncBytes) - { - initprintf("Sync debugging enabled\n"); - g_numSyncBytes = packbuf[4]; - } - - break; - - case PACKET_TYPE_PLAYER_OPTIONS: - //slaves in M/S mode only send to master - //Master re-transmits message to all others - if ((!g_networkBroadcastMode) && (myconnectindex == connecthead)) - for (i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) - if (i != other) Net_SendPacket(i,packbuf,packbufleng); - - other = packbuf[1]; - i = 2; - - g_player[other].ps->aim_mode = packbuf[i++]; - g_player[other].ps->auto_aim = packbuf[i++]; - g_player[other].ps->weaponswitch = packbuf[i++]; - g_player[other].ps->palookup = g_player[other].pcolor = packbuf[i++]; - g_player[other].pteam = packbuf[i++]; - - break; - - //case PACKET_TYPE_FRAGLIMIT_CHANGED: - // //slaves in M/S mode only send to master - // //Master re-transmits message to all others - // if ((!g_networkBroadcastMode) && (myconnectindex == connecthead)) - // for (i = connectpoint2[connecthead];i >= 0;i = connectpoint2[i]) - // if (i != other) Net_SendPacket(i, packbuf, packbufleng); - // - // ud.fraglimit = packbuf[2]; - // - // Bsprintf(tempbuf, "FRAGLIMIT CHANGED TO %d", ud.fraglimit); - // G_AddUserQuote(tempbuf); - // break; - - case PACKET_TYPE_EOL: - if ((!g_networkBroadcastMode) && (myconnectindex == connecthead)) - for (i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) - if (i != other) Net_SendPacket(i,packbuf,packbufleng); - - for (TRAVERSE_CONNECT(i)) - g_player[i].ps->gm = MODE_EOL; - - ud.level_number = packbuf[1]; - m_level_number = ud.level_number; - ud.from_bonus = packbuf[2]; - break; - - case PACKET_TYPE_PLAYER_NAME: - //slaves in M/S mode only send to master - //Master re-transmits message to all others - if ((!g_networkBroadcastMode) && (myconnectindex == connecthead)) - for (i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) - if (i != other) Net_SendPacket(i,packbuf,packbufleng); - - other = packbuf[1]; - - for (i=2;packbuf[i];i++) - g_player[other].user_name[i-2] = packbuf[i]; - g_player[other].user_name[i-2] = 0; - i++; - - initprintf("Player %d's name is now %s\n", other, g_player[other].user_name); - - break; - - case PACKET_TYPE_WEAPON_CHOICE: - //slaves in M/S mode only send to master - //Master re-transmits message to all others - if ((!g_networkBroadcastMode) && (myconnectindex == connecthead)) - for (i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) - if (i != other) Net_SendPacket(i,packbuf,packbufleng); - - other = packbuf[1]; - - i = 2; - - j = i; //This used to be Duke packet #9... now concatenated with Duke packet #6 - for (;i-j<10;i++) g_player[other].wchoice[i-j] = packbuf[i]; - - break; - case PACKET_TYPE_RTS: - //slaves in M/S mode only send to master - //Master re-transmits message to all others - if ((!g_networkBroadcastMode) && (myconnectindex == connecthead)) - for (i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) - if (i != other) Net_SendPacket(i,packbuf,packbufleng); - - G_StartRTS(packbuf[1], other); - break; - - case PACKET_TYPE_MENU_LEVEL_QUIT: - //slaves in M/S mode only send to master - if (myconnectindex == connecthead) - { - //Master re-transmits message to all others - for (i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) - if (i != other) - Net_SendPacket(i,packbuf,packbufleng); - } - - G_GameExit("Game aborted from menu; disconnected."); - - break; - - case PACKET_TYPE_USER_MAP: - //slaves in M/S mode only send to master - if (myconnectindex == connecthead) - { - //Master re-transmits message to all others - for (i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) - if (i != other) - Net_SendPacket(i,packbuf,packbufleng); - } - - Bstrcpy(boardfilename,(char*)packbuf+1); - boardfilename[packbufleng-1] = 0; - Bcorrectfilename(boardfilename,0); - if (boardfilename[0] != 0) - { - if (fileSystem.FileExists(boardfilename,0)) - { - Bmemset(boardfilename,0,sizeof(boardfilename)); - Net_SendUserMapName(); - } - } - - if (m_level_number == 7 && ud.m_volume_number == 0 && boardfilename[0] == 0) - m_level_number = 0; - - break; - - case PACKET_TYPE_MAP_VOTE: - case PACKET_TYPE_MAP_VOTE_INITIATE: - case PACKET_TYPE_MAP_VOTE_CANCEL: - - if (myconnectindex == connecthead) - { - //Master re-transmits message to all others - for (i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) - if (i != other) - Net_SendPacket(i,packbuf,packbufleng); - } - - switch (packbuf[0]) - { - case PACKET_TYPE_MAP_VOTE: - if (voting == myconnectindex && g_player[packbuf[1]].gotvote == 0) - { - g_player[packbuf[1]].gotvote = 1; - g_player[packbuf[1]].vote = packbuf[2]; - Bsprintf(tempbuf,"Confirmed vote from %s",g_player[packbuf[1]].user_name); - G_AddUserQuote(tempbuf); - } - break; - - case PACKET_TYPE_MAP_VOTE_INITIATE: // call map vote - /* if (g_networkBroadcastMode == 0 && packbuf[1] == connecthead) - break; // ignore this from master */ - voting = packbuf[1]; - vote_episode = packbuf[2]; - vote_map = packbuf[3]; - - Bsprintf(tempbuf,"%s^00 HAS CALLED A VOTE TO CHANGE MAP TO %s (E%dL%d)", - g_player[packbuf[1]].user_name, - g_mapInfo[(unsigned char)(packbuf[2]*MAXLEVELS + packbuf[3])].name, - packbuf[2]+1,packbuf[3]+1); - G_AddUserQuote(tempbuf); - - Bsprintf(tempbuf,"Press F1 to Accept, F2 to Decline"); - G_AddUserQuote(tempbuf); - - for (i=MAXPLAYERS-1;i>=0;i--) - { - g_player[i].vote = 0; - g_player[i].gotvote = 0; - } - g_player[voting].gotvote = g_player[voting].vote = 1; - break; - - case PACKET_TYPE_MAP_VOTE_CANCEL: // cancel map vote - if (voting == packbuf[1]) - { - voting = -1; - i = 0; - for (j=MAXPLAYERS-1;j>=0;j--) - i += g_player[j].gotvote; - - if (i != numplayers) - Bsprintf(tempbuf,"%s^00 has canceled the vote",g_player[(unsigned char)packbuf[1]].user_name); - else Bsprintf(tempbuf,"Vote failed"); - for (i=MAXPLAYERS-1;i>=0;i--) - { - g_player[i].vote = 0; - g_player[i].gotvote = 0; - } - G_AddUserQuote(tempbuf); - } - break; - } - break; - - //case PACKET_TYPE_LOAD_GAME: - // //Slaves in M/S mode only send to master - // //Master re-transmits message to all others - // if ((!g_networkBroadcastMode) && (myconnectindex == connecthead)) - // for (i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) - // if (i != other) Net_SendPacket(i,packbuf,packbufleng); - // - // multiflag = 2; - // multiwhat = 0; - // multiwho = packbuf[2]; //other: need to send in m/s mode because of possible re-transmit - // multipos = packbuf[1]; - // G_LoadPlayer(multipos); - // multiflag = 0; - // break; - } - break; -#endif } } @@ -3849,7 +3517,7 @@ void Net_ReceiveMapVoteInitiate(uint8_t *pbuf) Bsprintf(tempbuf,"%s^00 has called a vote to change map to %s (E%dL%d)", g_player[voting].user_name, - g_mapInfo[(uint8_t)(vote_episode*MAXLEVELS + vote_map)].name, + mapList[(uint8_t)(vote_episode*MAXLEVELS + vote_map)].DisplayName(), vote_episode+1,vote_map+1); G_AddUserQuote(tempbuf); diff --git a/source/rr/src/osdcmds.cpp b/source/rr/src/osdcmds.cpp index c30c5cd63..1c57d4316 100644 --- a/source/rr/src/osdcmds.cpp +++ b/source/rr/src/osdcmds.cpp @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "osdcmds.h" #include "savegame.h" #include "sbar.h" +#include "mapinfo.h" BEGIN_RR_NS @@ -68,7 +69,7 @@ static int osdcmd_changelevel(osdcmdptr_t parm) } } - if (level > MAXLEVELS || g_mapInfo[volume *MAXLEVELS+level].filename == NULL) + if (level > MAXLEVELS || mapList *MAXLEVELS+level].fileName.IsEmpty) { OSD_Printf("changelevel: invalid level number\n"); return OSDCMD_SHOWHELP; diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index f06317f25..2edc60e0c 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -29,6 +29,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "cmdline.h" #include "statistics.h" #include "menu/menu.h" +#include "mapinfo.h" +#include "cmdlib.h" BEGIN_RR_NS @@ -504,14 +506,13 @@ static void G_DoLoadScreen(const char *statustext, int32_t percent) } else if (RR && g_lastLevel) { - menutext_center(textY,GStrings("ENTERIN")); + menutext_center(textY,GStrings("TXT_ENTERIN")); menutext_center(textY+16+8,GStrings("TXT_CLOSEENCOUNTERS")); } else { menutext_center(textY, RR ? GStrings("TXT_ENTERIN") : GStrings("TXT_LOADING")); - if (g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name != NULL) - menutext_center(textY+16+8,g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name); + menutext_center(textY+16+8,mapList[(ud.volume_number*MAXLEVELS) + ud.level_number].DisplayName()); } #ifndef EDUKE32_TOUCH_DEVICES @@ -2179,10 +2180,7 @@ int G_FindLevelByFile(const char *fileName) for (bssize_t levelNum = 0; levelNum < MAXLEVELS; levelNum++) { - if (g_mapInfo[volOffset + levelNum].filename == NULL) - continue; - - if (!Bstrcasecmp(fileName, g_mapInfo[volOffset + levelNum].filename)) + if (!mapList[volOffset + levelNum].fileName.CompareNoCase(fileName)) return volOffset + levelNum; } } @@ -2249,20 +2247,18 @@ void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName, int levelNum { char *p; char const *exts[] = { -#ifdef HAVE_FLAC "flac", -#endif -#ifdef HAVE_VORBIS "ogg", -#endif -#ifdef HAVE_XMP + "mp3", "xm", "mod", "it", "s3m", "mtm", -#endif - "mid" + "mid", + "hmp", + "hmi", + "xmi" }; Bstrncpy(nameBuf, fileName, BMAX_PATH); @@ -2279,14 +2275,14 @@ void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName, int levelNum { Bmemcpy(p+1, ext, Bstrlen(ext) + 1); - if (fileSystem.FileExists(nameBuf)) - { - realloc_copy(&g_mapInfo[levelNum].musicfn, nameBuf); + if (FileExists(nameBuf)) + { + mapList[levelNum].music = nameBuf; return; } } - realloc_copy(&g_mapInfo[levelNum].musicfn, "dethtoll.mid"); + mapList[levelNum].music = "dethtoll.mid"; } int G_EnterLevel(int gameMode) @@ -2342,22 +2338,19 @@ int G_EnterLevel(int gameMode) } mii = (ud.volume_number*MAXLEVELS)+ud.level_number; + auto &mi = mapList[mii]; - if (g_mapInfo[mii].name == NULL || g_mapInfo[mii].filename == NULL) + if ( mi.name.IsEmpty() || mi.fileName.IsEmpty()) { if (RR && g_lastLevel) { - if (g_mapInfo[mii].filename == NULL) - g_mapInfo[mii].filename = (char *)Xcalloc(BMAX_PATH, sizeof(uint8_t)); - if (g_mapInfo[mii].name == NULL) - g_mapInfo[mii].name = Xstrdup("CLOSE ENCOUNTERS"); + // FIXME: Initialize this properly in the data structures! + mi.fileName = "endgame.map"; + mi.name = "$TXT_CLOSEENCOUNTERS"; } else if (Menu_HaveUserMap()) { - if (g_mapInfo[mii].filename == NULL) - g_mapInfo[mii].filename = (char *)Xcalloc(BMAX_PATH, sizeof(uint8_t)); - if (g_mapInfo[mii].name == NULL) - g_mapInfo[mii].name = Xstrdup("User Map"); + mi.name = "$TXT_USERMAP"; } else { @@ -2378,18 +2371,7 @@ int G_EnterLevel(int gameMode) DukePlayer_t *const pPlayer = g_player[0].ps; int16_t lbang; - if (RR && g_lastLevel) - { - if (engineLoadBoard("endgame.map", 0, &pPlayer->pos, &lbang, &pPlayer->cursectnum) < 0) - { - OSD_Printf(OSD_ERROR "Map \"endgame.map\" not found or invalid map version!\n"); - return 1; - } - - G_LoadMapHack(levelName, "endgame.map"); - G_SetupFilenameBasedMusic(levelName, "endgame.map", m_level_number); - } - else if (!VOLUMEONE && Menu_HaveUserMap()) + if (!VOLUMEONE && Menu_HaveUserMap()) { if (engineLoadBoard(boardfilename, 0, &pPlayer->pos, &lbang, &pPlayer->cursectnum) < 0) { @@ -2401,15 +2383,15 @@ int G_EnterLevel(int gameMode) G_LoadMapHack(levelName, boardfilename); G_SetupFilenameBasedMusic(levelName, boardfilename, m_level_number); } - else if (engineLoadBoard(g_mapInfo[mii].filename, VOLUMEONE, &pPlayer->pos, &lbang, &pPlayer->cursectnum) < 0) + else if (engineLoadBoard(mi.fileName, VOLUMEONE, &pPlayer->pos, &lbang, &pPlayer->cursectnum) < 0) { - OSD_Printf(OSD_ERROR "Map \"%s\" not found or invalid map version!\n", g_mapInfo[mii].filename); + OSD_Printf(OSD_ERROR "Map \"%s\" not found or invalid map version!\n", mi.fileName.GetChars()); return 1; } else { - STAT_NewLevel(g_mapInfo[mii].filename); - G_LoadMapHack(levelName, g_mapInfo[mii].filename); + STAT_NewLevel(mi.fileName); + G_LoadMapHack(levelName, mi.fileName); } if (RR && !RRRA && ud.volume_number == 1 && ud.level_number == 1) @@ -2444,7 +2426,7 @@ int G_EnterLevel(int gameMode) G_AlignWarpElevators(); resetpspritevars(gameMode); - ud.playerbest = CONFIG_GetMapBestTime(Menu_HaveUserMap() ? boardfilename : g_mapInfo[mii].filename, g_loadedMapHack.md4); + ud.playerbest = CONFIG_GetMapBestTime(Menu_HaveUserMap() ? boardfilename : mi.fileName.GetChars(), g_loadedMapHack.md4); // G_FadeLoad(0,0,0, 252,0, -28, 4, -1); G_CacheMapData(); @@ -2452,9 +2434,9 @@ int G_EnterLevel(int gameMode) if (ud.recstat != 2) { - if (g_mapInfo[g_musicIndex].musicfn == NULL || - g_mapInfo[mii].musicfn == NULL || // intentional, to pass control further while avoiding the strcmp on null - strcmp(g_mapInfo[g_musicIndex].musicfn, g_mapInfo[mii].musicfn) || + if (mapList[g_musicIndex].music.IsEmpty() || + mi.music.IsEmpty() || + mi.music.CompareNoCase(mapList[g_musicIndex].music) || g_musicSize == 0 || ud.last_level == -1) { @@ -2545,7 +2527,7 @@ int G_EnterLevel(int gameMode) else { OSD_Printf(OSDTEXT_YELLOW "E%dL%d: %s\n", ud.volume_number+1, ud.level_number+1, - g_mapInfo[mii].name); + mapList[mii].DisplayName()); } g_restorePalette = -1; diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index 5ee8113ad..7838c98c5 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gamecontrol.h" #include "version.h" #include "z_music.h" +#include "mapinfo.h" #include "savegamehelp.h" BEGIN_RR_NS @@ -273,17 +274,17 @@ int32_t G_LoadPlayer(const char *path) Bmemcpy(boardfilename, h.boardfn, sizeof(boardfilename)); int const mapIdx = h.volnum*MAXLEVELS + h.levnum; - + char workbuffer[BMAX_PATH]; if (boardfilename[0]) - Bstrcpy(currentboardfilename, boardfilename); - else if (g_mapInfo[mapIdx].filename) - Bstrcpy(currentboardfilename, g_mapInfo[mapIdx].filename); + Bstrcpy(workbuffer, boardfilename); + else + Bstrcpy(workbuffer, mapList[mapIdx].fileName); - if (currentboardfilename[0]) + if (workbuffer[0]) { - artSetupMapArt(currentboardfilename); - append_ext_UNSAFE(currentboardfilename, ".mhk"); - engineLoadMHK(currentboardfilename); + artSetupMapArt(workbuffer); + append_ext_UNSAFE(workbuffer, ".mhk"); + engineLoadMHK(workbuffer); } Bmemcpy(currentboardfilename, boardfilename, BMAX_PATH); @@ -1169,8 +1170,8 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i auto fw = WriteSavegameChunk("header.dat"); fw->Write(&h, sizeof(savehead_t)); - auto& mi = g_mapInfo[(MAXLEVELS * ud.volume_number) + ud.level_number]; - G_WriteSaveHeader(name, mi.filename, mi.name); + auto& mi = mapList[(MAXLEVELS * ud.volume_number) + ud.level_number]; + G_WriteSaveHeader(name, mi.fileName, mi.DisplayName()); } else { diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index 409da64aa..1d1d95ba1 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "mdsprite.h" #include "gamecvars.h" #include "menu/menu.h" +#include "mapinfo.h" BEGIN_RR_NS @@ -175,7 +176,7 @@ static void G_ShowScores(void) if (g_mostConcurrentPlayers > 1 && (g_gametypeFlags[ud.coop]&GAMETYPE_SCORESHEET)) { gametext_center(SCORESHEETOFFSET+58+2, GStrings("Multiplayer Totals")); - gametext_center(SCORESHEETOFFSET+58+10, g_mapInfo[G_LastMapInfoIndex()].name); + gametext_center(SCORESHEETOFFSET+58+10, mapList[G_LastMapInfoIndex()].DisplayName()); t = 0; minitext(70, SCORESHEETOFFSET+80, GStrings("Name"), 8, 2+8+16+ROTATESPRITE_MAX); @@ -994,7 +995,7 @@ void G_DisplayRest(int32_t smoothratio) { if (!G_HaveUserMap()) minitext(5, a+6, GStrings.localize(gVolumeNames[ud.volume_number]), 0, 2+8+16+256); - minitext(5, a+6+6, g_mapInfo[ud.volume_number*MAXLEVELS + ud.level_number].name, 0, 2+8+16+256); + minitext(5, a+6+6, mapList[ud.volume_number*MAXLEVELS + ud.level_number].DisplayName(), 0, 2+8+16+256); } } } @@ -1024,12 +1025,12 @@ void G_DisplayRest(int32_t smoothratio) else if (g_levelTextTime < 5) o |= 1; - if (g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name != NULL) + if (mapList[(ud.volume_number*MAXLEVELS) + ud.level_number].name.IsNotEmpty()) { char const * const fn = currentboardfilename[0] != 0 && ud.volume_number == 0 && ud.level_number == 7 ? currentboardfilename - : g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name; + : mapList[(ud.volume_number*MAXLEVELS) + ud.level_number].DisplayName(); menutext_(160<<16, (90+16+8)<<16, -g_levelTextTime+22/*quotepulseshade*/, fn, o, TEXT_XCENTER); } @@ -1118,7 +1119,7 @@ void G_DisplayRest(int32_t smoothratio) { Bsprintf(tempbuf, "%s^00 has called a vote for map", g_player[voting].user_name); gametext_center(40, tempbuf); - Bsprintf(tempbuf, "%s (E%dL%d)", g_mapInfo[vote_episode*MAXLEVELS + vote_map].name, vote_episode+1, vote_map+1); + Bsprintf(tempbuf, "%s (E%dL%d)", mapList[vote_episode*MAXLEVELS + vote_map].DisplayName(), vote_episode+1, vote_map+1); gametext_center(48, tempbuf); gametext_center(70, "Press F1 to Accept, F2 to Decline"); } @@ -1911,7 +1912,7 @@ static void G_DisplayMPResultsScreen(void) if (!RR && PLUTOPAK) // JBF 20030804 rotatesprite_fs((260)<<16, 36<<16, 65536L, 0, PLUTOPAKSPRITE+2, 0, 0, 2+8); gametext_center(58+(RR ? 0 : 2), GStrings("Multiplayer Totals")); - gametext_center(58+10, g_mapInfo[G_LastMapInfoIndex()].name); + gametext_center(58+10, mapList[G_LastMapInfoIndex()].DisplayName()); gametext_center_shade(RR ? 175 : 165, GStrings("Presskey"), quotepulseshade); @@ -1979,11 +1980,11 @@ static int32_t G_PrintTime_ClockPad(void) clockpad = max(clockpad, ij); if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - for (ii=g_mapInfo[G_LastMapInfoIndex()].partime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } + for (ii=mapList[G_LastMapInfoIndex()].parTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } clockpad = max(clockpad, ij); - if (g_mapInfo[G_LastMapInfoIndex()].designertime) + if (mapList[G_LastMapInfoIndex()].designerTime) { - for (ii=g_mapInfo[G_LastMapInfoIndex()].designertime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } + for (ii=mapList[G_LastMapInfoIndex()].designerTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } clockpad = max(clockpad, ij); } } @@ -2012,13 +2013,13 @@ const char* G_PrintParTime(void) { if (ud.last_level < 1) return ""; - return G_PrintTime2(g_mapInfo[G_LastMapInfoIndex()].partime); + return G_PrintTime2(mapList[G_LastMapInfoIndex()].parTime); } const char* G_PrintDesignerTime(void) { if (ud.last_level < 1) return ""; - return G_PrintTime2(g_mapInfo[G_LastMapInfoIndex()].designertime); + return G_PrintTime2(mapList[G_LastMapInfoIndex()].designerTime); } const char* G_PrintBestTime(void) { @@ -2043,17 +2044,17 @@ void G_BonusScreen(int32_t bonusonly) } else { - lastmapname = g_mapInfo[G_LastMapInfoIndex()].name; - if (!lastmapname) // this isn't right but it's better than no name at all - lastmapname = g_mapInfo[G_LastMapInfoIndex()].name; + lastmapname = mapList[G_LastMapInfoIndex()].DisplayName(); + if (!lastmapname || !*lastmapname) // this isn't right but it's better than no name at all + lastmapname = mapList[G_LastMapInfoIndex()].fileName; } if (RR) { if ((g_lastLevel && ud.volume_number == 2) || g_vixenLevel) - lastmapname = "CLOSE ENCOUNTERS"; - else if (g_turdLevel) - lastmapname = "SMELTING PLANT"; + lastmapname = GStrings("TXT_CLOSEENCOUNTERS"); + else if (g_turdLevel) + lastmapname = GStrings("SMELTIN' PLANT"); } @@ -2256,7 +2257,7 @@ void G_BonusScreen(int32_t bonusonly) yy+= yystep; if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - if (g_mapInfo[G_LastMapInfoIndex()].partime) + if (mapList[G_LastMapInfoIndex()].parTime) { if (!RR) gametext(10, yy+9, GStrings("TXT_ParTime")); @@ -2264,7 +2265,7 @@ void G_BonusScreen(int32_t bonusonly) menutext(30, yy, GStrings("TXT_ParTime")); yy+=yystep; } - if (g_mapInfo[G_LastMapInfoIndex()].designertime) + if (mapList[G_LastMapInfoIndex()].designerTime) { // EDuke 2.0 / NAM source suggests "Green Beret's Time:" if (DUKE) @@ -2320,7 +2321,7 @@ void G_BonusScreen(int32_t bonusonly) if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - if (g_mapInfo[G_LastMapInfoIndex()].partime) + if (mapList[G_LastMapInfoIndex()].parTime) { G_PrintParTime(); if (!RR) @@ -2329,7 +2330,7 @@ void G_BonusScreen(int32_t bonusonly) menutext(191, yy, tempbuf); yy+=yystep; } - if (g_mapInfo[G_LastMapInfoIndex()].designertime) + if (mapList[G_LastMapInfoIndex()].designerTime) { G_PrintDesignerTime(); if (DUKE) @@ -2623,9 +2624,9 @@ void G_BonusScreenRRRA(int32_t bonusonly) } else { - lastmapname = g_mapInfo[G_LastMapInfoIndex()].name; - if (!lastmapname) // this isn't right but it's better than no name at all - lastmapname = g_mapInfo[G_LastMapInfoIndex()].name; + lastmapname = mapList[G_LastMapInfoIndex()].DisplayName(); + if (!lastmapname || !*lastmapname) // this isn't right but it's better than no name at all + lastmapname = mapList[G_LastMapInfoIndex()].fileName; } if ((g_lastLevel && ud.volume_number == 2) || g_vixenLevel) @@ -2826,12 +2827,12 @@ void G_BonusScreenRRRA(int32_t bonusonly) yy+= yystep; if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - if (g_mapInfo[G_LastMapInfoIndex()].partime) + if (mapList[G_LastMapInfoIndex()].parTime) { menutext(30, yy, GStrings("TXT_PARTIME")); yy+=yystep; } - if (g_mapInfo[G_LastMapInfoIndex()].designertime) + if (mapList[G_LastMapInfoIndex()].designerTime) { menutext(30, yy, GStrings("TXT_XTRTIME")); yy+=yystep; @@ -2869,13 +2870,14 @@ void G_BonusScreenRRRA(int32_t bonusonly) if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - if (g_mapInfo[G_LastMapInfoIndex()].partime) + if (mapList[G_LastMapInfoIndex()].parTime) { G_PrintParTime(); menutext(191, yy, tempbuf); yy+=yystep; } - if (g_mapInfo[G_LastMapInfoIndex()].designertime) + if (mapList[G_LastMapInfoIndex()].designerT + ime) { G_PrintDesignerTime(); menutext(191, yy, tempbuf); diff --git a/source/rr/src/sector.h b/source/rr/src/sector.h index 8647cae3f..f167be4a2 100644 --- a/source/rr/src/sector.h +++ b/source/rr/src/sector.h @@ -98,12 +98,9 @@ typedef struct { } mapstate_t; typedef struct { - int32_t partime, designertime; - char *name, *filename, *musicfn; mapstate_t *savedstate; } map_t; -//extern map_t g_mapInfo[(MAXVOLUMES+1)*MAXLEVELS]; // +1 volume for "intro", "briefing" music void G_ActivateBySector(int sect,int spriteNum); int S_FindMusicSFX(int sectNum, int *sndptr); diff --git a/source/rr/src/sounds.cpp b/source/rr/src/sounds.cpp index cb5097f3d..fa516ac71 100644 --- a/source/rr/src/sounds.cpp +++ b/source/rr/src/sounds.cpp @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "openaudio.h" #include "z_music.h" #include +#include "mapinfo.h" BEGIN_RR_NS @@ -131,7 +132,7 @@ static void S_SetMusicIndex(unsigned int m) void S_PlayLevelMusicOrNothing(unsigned int m) { - Mus_Play(g_mapInfo[m].filename, RR ? nullptr : g_mapInfo[m].musicfn, true); + Mus_Play(mapList[m].fileName, RR ? nullptr : mapList[m].music, true); S_SetMusicIndex(m); } @@ -139,8 +140,8 @@ int S_TryPlaySpecialMusic(unsigned int m) { if (RR) return 1; - char const * musicfn = g_mapInfo[m].musicfn; - if (musicfn != NULL) + auto &musicfn = mapList[m].music; + if (musicfn.IsNotEmpty()) { if (!Mus_Play(nullptr, musicfn, 1)) { From db29fc1a01eaf74a2a5971eae6b369b58c623346 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 10 Dec 2019 17:25:45 +0100 Subject: [PATCH 187/203] - removed the mostly useless changelevel CCMDs. It makes more sense to do a real 'map' CCMD instead once the level management is working properly. --- source/blood/src/osdcmd.cpp | 46 ---------- source/duke3d/src/osdcmds.cpp | 67 +-------------- source/rr/src/cheats.cpp | 2 +- source/rr/src/osdcmds.cpp | 156 +--------------------------------- source/rr/src/screens.cpp | 3 +- 5 files changed, 4 insertions(+), 270 deletions(-) diff --git a/source/blood/src/osdcmd.cpp b/source/blood/src/osdcmd.cpp index c1ecb4715..b8d38f114 100644 --- a/source/blood/src/osdcmd.cpp +++ b/source/blood/src/osdcmd.cpp @@ -47,51 +47,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS -static int osdcmd_changelevel(osdcmdptr_t parm) -{ - int32_t volume,level; - char *p; - - if (parm->numparms != 2) return OSDCMD_SHOWHELP; - - volume = strtol(parm->parms[0], &p, 10) - 1; - if (p[0]) return OSDCMD_SHOWHELP; - level = strtol(parm->parms[1], &p, 10) - 1; - if (p[0]) return OSDCMD_SHOWHELP; - - if (volume < 0) return OSDCMD_SHOWHELP; - if (level < 0) return OSDCMD_SHOWHELP; - - if (volume >= 6) - { - OSD_Printf("changelevel: invalid volume number (range 1-%d)\n",6); - return OSDCMD_OK; - } - - if (level >= gEpisodeInfo[volume].nLevels) - { - OSD_Printf("changelevel: invalid level number\n"); - return OSDCMD_SHOWHELP; - } - - if (gDemo.at1) - gDemo.StopPlayback(); - - if (numplayers > 1) - { - gPacketStartGame.episodeId = volume; - gPacketStartGame.levelId = level; - netBroadcastNewGame(); - gStartNewGame = 1; - return OSDCMD_OK; - } - levelSetupOptions(volume, level); - StartLevel(&gGameOptions); - viewResizeView(gViewSize); - - return OSDCMD_OK; -} - static int osdcmd_map(osdcmdptr_t parm) { char filename[BMAX_PATH]; @@ -342,7 +297,6 @@ void onvideomodechange(int32_t newmode) int32_t registerosdcommands(void) { - OSD_RegisterFunction("changelevel","changelevel : warps to the given level", osdcmd_changelevel); OSD_RegisterFunction("map","map : loads the given user map", osdcmd_map); OSD_RegisterFunction("demo","demo : starts the given demo", osdcmd_demo); OSD_RegisterFunction("crosshaircolor","crosshaircolor: changes the crosshair color", osdcmd_crosshaircolor); diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index d39dbdd8f..92004f793 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -38,68 +38,6 @@ BEGIN_DUKE_NS struct osdcmd_cheatsinfo osdcmd_cheatsinfo_stat = { -1, 0, 0 }; -static int osdcmd_changelevel(osdcmdptr_t parm) -{ - int volume = 0; - int level; - - if (!VOLUMEONE) - { - if (parm->numparms != 2) return OSDCMD_SHOWHELP; - - volume = strtol(parm->parms[0], NULL, 10) - 1; - level = strtol(parm->parms[1], NULL, 10) - 1; - } - else - { - if (parm->numparms != 1) return OSDCMD_SHOWHELP; - - level = strtol(parm->parms[0], NULL, 10) - 1; - } - - if (volume < 0 || level < 0) - return OSDCMD_SHOWHELP; - - if (level > MAXLEVELS || mapList[volume * MAXLEVELS + level].fileName.IsEmpty()) - { - OSD_Printf("changelevel: no map defined for episode %d level %d\n", volume + 1, level + 1); - return OSDCMD_SHOWHELP; - } - - if (numplayers > 1) - { - return OSDCMD_OK; - } - - if (g_player[myconnectindex].ps->gm & MODE_GAME) - { - // in-game behave like a cheat - osdcmd_cheatsinfo_stat.cheatnum = CHEAT_SCOTTY; - osdcmd_cheatsinfo_stat.volume = volume; - osdcmd_cheatsinfo_stat.level = level; - } - else - { - // out-of-game behave like a menu command - osdcmd_cheatsinfo_stat.cheatnum = -1; - - ud.m_volume_number = volume; - m_level_number = level; - - ud.m_monsters_off = 0; - ud.monsters_off = 0; - - ud.m_respawn_items = 0; - ud.m_respawn_inventory = 0; - - ud.multimode = 1; - - G_NewGame_EnterLevel(); - } - - return OSDCMD_OK; -} - static int osdcmd_map(osdcmdptr_t parm) { char filename[BMAX_PATH]; @@ -856,11 +794,8 @@ int32_t registerosdcommands(void) OSD_RegisterFunction("playerinfo", "Prints information about the current player", osdcmd_playerinfo); #endif - if (VOLUMEONE) - OSD_RegisterFunction("changelevel","changelevel : warps to the given level", osdcmd_changelevel); - else + if (!VOLUMEONE) { - OSD_RegisterFunction("changelevel","changelevel : warps to the given level", osdcmd_changelevel); OSD_RegisterFunction("map","map : loads the given user map", osdcmd_map); OSD_RegisterFunction("demo","demo : starts the given demo", osdcmd_demo); } diff --git a/source/rr/src/cheats.cpp b/source/rr/src/cheats.cpp index 3c01dea68..67be9c56f 100644 --- a/source/rr/src/cheats.cpp +++ b/source/rr/src/cheats.cpp @@ -25,7 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "duke3d.h" #include "osdcmds.h" #include "cheats.h" -#inclide "mapinfo.h" +#include "mapinfo.h" BEGIN_RR_NS diff --git a/source/rr/src/osdcmds.cpp b/source/rr/src/osdcmds.cpp index 1c57d4316..57b59fec9 100644 --- a/source/rr/src/osdcmds.cpp +++ b/source/rr/src/osdcmds.cpp @@ -35,115 +35,6 @@ BEGIN_RR_NS struct osdcmd_cheatsinfo osdcmd_cheatsinfo_stat = { -1, 0, 0 }; -static int osdcmd_changelevel(osdcmdptr_t parm) -{ - int32_t volume=0,level; - char *p; - - if (!VOLUMEONE) - { - if (parm->numparms != 2) return OSDCMD_SHOWHELP; - - volume = strtol(parm->parms[0], &p, 10) - 1; - if (p[0]) return OSDCMD_SHOWHELP; - level = strtol(parm->parms[1], &p, 10) - 1; - if (p[0]) return OSDCMD_SHOWHELP; - } - else - { - if (parm->numparms != 1) return OSDCMD_SHOWHELP; - - level = strtol(parm->parms[0], &p, 10) - 1; - if (p[0]) return OSDCMD_SHOWHELP; - } - - if (volume < 0) return OSDCMD_SHOWHELP; - if (level < 0) return OSDCMD_SHOWHELP; - - if (!VOLUMEONE) - { - if (volume > g_volumeCnt) - { - OSD_Printf("changelevel: invalid volume number (range 1-%d)\n",g_volumeCnt); - return OSDCMD_OK; - } - } - - if (level > MAXLEVELS || mapList *MAXLEVELS+level].fileName.IsEmpty) - { - OSD_Printf("changelevel: invalid level number\n"); - return OSDCMD_SHOWHELP; - } - - if (numplayers > 1) - { - /* - if (g_netServer) - Net_NewGame(volume,level); - else if (voting == -1) - { - ud.m_volume_number = volume; - m_level_number = level; - - if (g_player[myconnectindex].ps->i) - { - int32_t i; - - for (i=0; igm & MODE_GAME) - { - // in-game behave like a cheat - osdcmd_cheatsinfo_stat.cheatnum = CHEAT_SCOTTY; - osdcmd_cheatsinfo_stat.volume = volume; - osdcmd_cheatsinfo_stat.level = level; - } - else - { - // out-of-game behave like a menu command - osdcmd_cheatsinfo_stat.cheatnum = -1; - - ud.m_volume_number = volume; - m_level_number = level; - - ud.m_monsters_off = 0; - ud.monsters_off = 0; - - ud.m_respawn_items = 0; - ud.m_respawn_inventory = 0; - - ud.multimode = 1; - - G_NewGame_EnterLevel(); - } - - return OSDCMD_OK; -} - static int osdcmd_map(osdcmdptr_t parm) { char filename[BMAX_PATH]; @@ -170,48 +61,6 @@ static int osdcmd_map(osdcmdptr_t parm) if (numplayers > 1) { - /* - if (g_netServer) - { - Net_SendUserMapName(); - ud.m_volume_number = 0; - m_level_number = 7; - Net_NewGame(ud.m_volume_number, m_level_number); - } - else if (voting == -1) - { - Net_SendUserMapName(); - - ud.m_volume_number = 0; - m_level_number = 7; - - if (g_player[myconnectindex].ps->i) - { - int32_t i; - - for (i=0; i: warps to the given level", osdcmd_changelevel); - else + if (!VOLUMEONE) { - OSD_RegisterFunction("changelevel","changelevel : warps to the given level", osdcmd_changelevel); OSD_RegisterFunction("map","map : loads the given user map", osdcmd_map); OSD_RegisterFunction("demo","demo : starts the given demo", osdcmd_demo); } diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index 1d1d95ba1..0685b1468 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -2876,8 +2876,7 @@ void G_BonusScreenRRRA(int32_t bonusonly) menutext(191, yy, tempbuf); yy+=yystep; } - if (mapList[G_LastMapInfoIndex()].designerT - ime) + if (mapList[G_LastMapInfoIndex()].designerTime) { G_PrintDesignerTime(); menutext(191, yy, tempbuf); From 4cc22e155f54920dec378f576a2b04c7df7bf12d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 10 Dec 2019 17:35:28 +0100 Subject: [PATCH 188/203] - better handling for maps without names. Use the file's base part as name if that happens. --- source/common/mapinfo.h | 9 +++++++++ source/duke3d/src/gamedef.cpp | 2 +- source/duke3d/src/premap.cpp | 2 +- source/rr/src/gamedef.cpp | 2 +- source/rr/src/premap.cpp | 2 +- source/rr/src/screens.cpp | 18 +++++------------- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/source/common/mapinfo.h b/source/common/mapinfo.h index 8ff323376..c7baaa79f 100644 --- a/source/common/mapinfo.h +++ b/source/common/mapinfo.h @@ -1,6 +1,7 @@ #pragma once #include "gstrings.h" +#include "cmdlib.h" // Localization capable replacement of the game specific solutions. @@ -15,6 +16,7 @@ struct MapRecord int parTime; int designerTime; FString fileName; + FString labelName; FString name; FString music; int cdSongId; @@ -28,6 +30,7 @@ struct MapRecord const char *DisplayName() { + if (name.IsEmpty()) return labelName; return GStrings.localize(name); } void SetName(const char *n) @@ -35,6 +38,12 @@ struct MapRecord name = n; MakeStringLocalizable(name); } + void SetFileName(const char* n) + { + fileName = n; + labelName = ExtractFileBase(n); + } + }; extern MapRecord mapList[512]; diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index 512dbb955..fd6134b90 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -5172,7 +5172,7 @@ repeatcase: Bcorrectfilename(tempbuf,0); - mapList[j * MAXLEVELS + k].fileName = tempbuf; + mapList[j * MAXLEVELS + k].SetFileName(tempbuf); C_SkipComments(); diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index 84a9ece65..a8a0a9339 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -1819,7 +1819,7 @@ int G_EnterLevel(int gameMode) if (VOLUMEONE || !Menu_HaveUserMap()) { - if (mm.name.IsEmpty() || mm.fileName.IsEmpty()) + if (mm.fileName.IsEmpty()) { OSD_Printf(OSDTEXT_RED "Map E%dL%d not defined!\n", ud.volume_number+1, ud.level_number+1); return 1; diff --git a/source/rr/src/gamedef.cpp b/source/rr/src/gamedef.cpp index 582bdc011..6ca7bd465 100644 --- a/source/rr/src/gamedef.cpp +++ b/source/rr/src/gamedef.cpp @@ -1871,7 +1871,7 @@ static int32_t C_ParseCommand(int32_t loop) Bcorrectfilename(tempbuf,0); - mapList[j *MAXLEVELS+k].fileName = tempbuf; + mapList[j *MAXLEVELS+k].SetFileName(tempbuf); C_SkipComments(); diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index 2edc60e0c..19b37b88e 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -2340,7 +2340,7 @@ int G_EnterLevel(int gameMode) mii = (ud.volume_number*MAXLEVELS)+ud.level_number; auto &mi = mapList[mii]; - if ( mi.name.IsEmpty() || mi.fileName.IsEmpty()) + if (mi.fileName.IsEmpty()) { if (RR && g_lastLevel) { diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index 0685b1468..cb4c93e07 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -1025,15 +1025,11 @@ void G_DisplayRest(int32_t smoothratio) else if (g_levelTextTime < 5) o |= 1; - if (mapList[(ud.volume_number*MAXLEVELS) + ud.level_number].name.IsNotEmpty()) - { - char const * const fn = currentboardfilename[0] != 0 && - ud.volume_number == 0 && ud.level_number == 7 - ? currentboardfilename - : mapList[(ud.volume_number*MAXLEVELS) + ud.level_number].DisplayName(); - - menutext_(160<<16, (90+16+8)<<16, -g_levelTextTime+22/*quotepulseshade*/, fn, o, TEXT_XCENTER); - } + char const * const fn = currentboardfilename[0] != 0 && + ud.volume_number == 0 && ud.level_number == 7 + ? currentboardfilename + : mapList[(ud.volume_number*MAXLEVELS) + ud.level_number].DisplayName(); + menutext_(160<<16, (90+16+8)<<16, -g_levelTextTime+22/*quotepulseshade*/, fn, o, TEXT_XCENTER); } if (g_player[myconnectindex].ps->newowner == -1 && ud.overhead_on == 0 && cl_crosshair && ud.camerasprite == -1) @@ -2045,8 +2041,6 @@ void G_BonusScreen(int32_t bonusonly) else { lastmapname = mapList[G_LastMapInfoIndex()].DisplayName(); - if (!lastmapname || !*lastmapname) // this isn't right but it's better than no name at all - lastmapname = mapList[G_LastMapInfoIndex()].fileName; } if (RR) @@ -2625,8 +2619,6 @@ void G_BonusScreenRRRA(int32_t bonusonly) else { lastmapname = mapList[G_LastMapInfoIndex()].DisplayName(); - if (!lastmapname || !*lastmapname) // this isn't right but it's better than no name at all - lastmapname = mapList[G_LastMapInfoIndex()].fileName; } if ((g_lastLevel && ud.volume_number == 2) || g_vixenLevel) From 0e19d4262e3cb159a8fde29d14fd76f59e2dbc6a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 10 Dec 2019 22:22:59 +0100 Subject: [PATCH 189/203] - savegame and mapinfo cleanup in DN3D and RR frontends. Also added an "end game" flag to the mapinfo. For those who like to assemble single levels into custom episodes. More features for that to come. ;) --- source/blood/src/loadsave.cpp | 9 +++- source/common/gamecontrol.cpp | 7 ++- source/common/mapinfo.h | 23 ++++++++- source/common/menu/menu.cpp | 1 + source/common/menu/savegamemanager.cpp | 4 +- source/common/savegamehelp.cpp | 71 +++++++++++++++++++++----- source/common/savegamehelp.h | 4 +- source/duke3d/src/game.cpp | 7 ++- source/duke3d/src/global.h | 1 - source/duke3d/src/premap.cpp | 22 ++++---- source/duke3d/src/savegame.cpp | 37 ++------------ source/duke3d/src/sounds.cpp | 5 +- source/rr/src/game.cpp | 6 +-- source/rr/src/global.h | 1 - source/rr/src/premap.cpp | 24 ++++----- source/rr/src/savegame.cpp | 37 ++------------ source/rr/src/sounds.cpp | 14 +---- source/sw/src/save.cpp | 8 ++- 18 files changed, 142 insertions(+), 139 deletions(-) diff --git a/source/blood/src/loadsave.cpp b/source/blood/src/loadsave.cpp index ae636805e..f35071504 100644 --- a/source/blood/src/loadsave.cpp +++ b/source/blood/src/loadsave.cpp @@ -48,6 +48,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "view.h" #include "savegamehelp.h" #include "z_music.h" +#include "mapinfo.h" BEGIN_BLD_NS @@ -209,7 +210,13 @@ bool GameInterface::SaveGame(FSaveGameNode* node) return false; } auto & li = gEpisodeInfo[gGameOptions.nEpisode].at28[gGameOptions.nLevel]; - G_WriteSaveHeader(node->SaveTitle, FStringf("%s.map", li.at0), li.at90); + // workaround until the level info here has been transitioned. + MapRecord mr; + mr.name = li.at90; + mr.labelName = li.at0; + mr.fileName.Format("%s.map", li.at0); + currentLevel = &mr; + G_WriteSaveHeader(node->SaveTitle); LoadSave::hSFile = NULL; return FinishSavegameWrite(); diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index 400eb0732..39dd168e9 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -31,8 +31,10 @@ #include "enet.h" #endif -MapRecord mapList[512]; // Due to how this gets used it needs to be static. EDuke defines 7 episode plus one spare episode with 64 potential levels each and relies on the static array which is freely accessible by scripts. -MapRecord *currentLevel; +MapRecord mapList[512]; // Due to how this gets used it needs to be static. EDuke defines 7 episode plus one spare episode with 64 potential levels each and relies on the static array which is freely accessible by scripts. +MapRecord *currentLevel; // level that is currently played. (The real level, not what script hacks modfifying the current level index can pretend.) +MapRecord* lastLevel; // Same here, for the last level. +MapRecord userMapRecord; // stand-in for the user map. void C_CON_SetAliases(); InputState inputState; @@ -428,6 +430,7 @@ int CONFIG_Init() InitStatistics(); M_Init(); SetDefaultStrings(); + if (g_gameType & GAMEFLAG_RR) InitRREndMap(); // this needs to be done better later return gi->app_main(); } diff --git a/source/common/mapinfo.h b/source/common/mapinfo.h index c7baaa79f..b5882bc00 100644 --- a/source/common/mapinfo.h +++ b/source/common/mapinfo.h @@ -11,6 +11,11 @@ inline void MakeStringLocalizable(FString "e) if (quote.Len() > 0 && quote[0] != '$' && GStrings[quote]) quote.Insert(0, "$"); } +enum +{ + MI_FORCEEOG = 1, +}; + struct MapRecord { int parTime; @@ -27,6 +32,7 @@ struct MapRecord int messageStart; // messages are stored in the quote array to reduce clutter. FString author; // bool fog, weather; // Blood defines these but they aren't used. + int flags; const char *DisplayName() { @@ -47,4 +53,19 @@ struct MapRecord }; extern MapRecord mapList[512]; -extern MapRecord *currentLevel; \ No newline at end of file +extern MapRecord userMapRecord; +extern MapRecord *currentLevel; +extern MapRecord* lastLevel; + + +inline void InitRREndMap() +{ + // RR defines its end map ad-hoc so give it a proper entry to reference (the last one in episode 2 because it needs to be in Ep. 2.) + mapList[127].SetName("$TXT_CLOSEENCOUNTERS"); + mapList[127].SetFileName("endmap.map"); +} + +enum +{ + RRENDSLOT = 127 +}; \ No newline at end of file diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 46791ad54..e1265fd2c 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -492,6 +492,7 @@ bool M_SetMenu(FName menu, int param, FName caller) M_StartMessage (GStrings("SAVEDEAD"), 1, -1); return true; } + break; case NAME_QuitMenu: // This is no separate class diff --git a/source/common/menu/savegamemanager.cpp b/source/common/menu/savegamemanager.cpp index d04b81cb0..e6fa309d3 100644 --- a/source/common/menu/savegamemanager.cpp +++ b/source/common/menu/savegamemanager.cpp @@ -198,7 +198,7 @@ void FSavegameManager::ReadSaveStrings() } auto fr = info->NewReader(); FString title; - int check = G_ValidateSavegame(fr, &title); + int check = G_ValidateSavegame(fr, &title, true); fr.Close(); delete savegame; if (check != 0) @@ -377,7 +377,7 @@ unsigned FSavegameManager::ExtractSaveData(int index) FString comment = sjson_get_string(root, "Creation Time", ""); - FString fcomment = sjson_get_string(root, "Map File", ""); + FString fcomment = sjson_get_string(root, "Map Label", ""); FString ncomment = sjson_get_string(root, "Map Name", ""); FStringf pcomment("%s - %s\n", fcomment.GetChars(), ncomment.GetChars()); comment += pcomment; diff --git a/source/common/savegamehelp.cpp b/source/common/savegamehelp.cpp index 59d7968b3..f0c7b1cb2 100644 --- a/source/common/savegamehelp.cpp +++ b/source/common/savegamehelp.cpp @@ -45,6 +45,7 @@ #include "secrets.h" #include "s_music.h" #include "quotemgr.h" +#include "mapinfo.h" static CompositeSavegameWriter savewriter; static FResourceFile *savereader; @@ -81,8 +82,21 @@ bool OpenSaveGameForRead(const char *name) SECRET_Load(); MUS_Restore(); quoteMgr.ReadFromSavegame(); - } + auto file = ReadSavegameChunk("info.json"); + if (!file.isOpen()) + { + FinishSavegameRead(); + delete savereader; + return false; + } + if (G_ValidateSavegame(file, nullptr, false) <= 0) + { + FinishSavegameRead(); + delete savereader; + return false; + } + } return savereader != nullptr; } @@ -116,7 +130,7 @@ void FinishSavegameRead() // //============================================================================= -void G_WriteSaveHeader(const char *name, const char*mapname, const char *maptitle) +void G_WriteSaveHeader(const char *name) { sjson_context* ctx = sjson_create_context(0, 0, NULL); if (!ctx) @@ -128,16 +142,20 @@ void G_WriteSaveHeader(const char *name, const char*mapname, const char *maptitl sjson_put_int(ctx, root, "Save Version", savesig.currentsavever); sjson_put_string(ctx, root, "Engine", savesig.savesig); sjson_put_string(ctx, root, "Game Resource", fileSystem.GetResourceFileName(1)); - sjson_put_string(ctx, root, "Map Name", maptitle); + sjson_put_string(ctx, root, "Map Name", currentLevel->DisplayName()); sjson_put_string(ctx, root, "Title", name); - if (*mapname == '/') mapname++; - sjson_put_string(ctx, root, "Map File", mapname); - auto fileno = fileSystem.FindFile(mapname); - auto mapfile = fileSystem.GetFileContainer(fileno); - auto mapcname = fileSystem.GetResourceFileName(mapfile); - if (mapcname) sjson_put_string(ctx, root, "Map Resource", mapcname); - else return; // this should never happen. Saving on a map that isn't present is impossible. - + sjson_put_string(ctx, root, "Map File", currentLevel->fileName); + sjson_put_string(ctx, root, "Map Label", currentLevel->labelName); + const char *fn = currentLevel->fileName; + if (*fn == '/') fn++; + if (!strncmp(fn, "file://", 7) != 0) // this only has meaning for non-usermaps + { + auto fileno = fileSystem.FindFile(fn); + auto mapfile = fileSystem.GetFileContainer(fileno); + auto mapcname = fileSystem.GetResourceFileName(mapfile); + if (mapcname) sjson_put_string(ctx, root, "Map Resource", mapcname); + else return; // this should never happen. Saving on a map that isn't present is impossible. + } char* encoded = sjson_stringify(ctx, root, " "); @@ -172,6 +190,10 @@ static bool CheckSingleFile (const char *name, bool &printRequires, bool printwa { return true; } + if (!strncmp(name, "file://", 7) == 0) + { + return FileExists(name + 7); // User maps must be present to be validated. + } if (fileSystem.CheckIfResourceFileLoaded(name) < 0) { if (printwarn) @@ -222,7 +244,7 @@ static bool G_CheckSaveGameWads (const char *gamegrp, const char *mapgrp, bool p // //============================================================================= -int G_ValidateSavegame(FileReader &fr, FString *savetitle) +int G_ValidateSavegame(FileReader &fr, FString *savetitle, bool formenu) { auto data = fr.ReadPadded(1); @@ -237,6 +259,7 @@ int G_ValidateSavegame(FileReader &fr, FString *savetitle) FString gamegrp = sjson_get_string(root, "Game Resource", ""); FString mapgrp = sjson_get_string(root, "Map Resource", ""); FString title = sjson_get_string(root, "Title", ""); + FString filename = sjson_get_string(root, "Map File", ""); auto savesig = gi->GetSaveSig(); sjson_destroy_context(ctx); @@ -248,6 +271,30 @@ int G_ValidateSavegame(FileReader &fr, FString *savetitle) // not our business. Leave it alone. return 0; } + + MapRecord *curLevel = nullptr; + + if (!strncmp(filename, "file://", 7) != 0) + { + for (auto& mr : mapList) + { + if (mr.fileName.Compare(filename) == 0) + { + curLevel = &mr; + } + } + } + else + { + curLevel = &userMapRecord; + if (!formenu) + { + userMapRecord.name = ""; + userMapRecord.SetFileName(filename); + } + } + if (!curLevel) return 0; + if (!formenu) currentLevel = curLevel; if (savever < savesig.minsavever) diff --git a/source/common/savegamehelp.h b/source/common/savegamehelp.h index 5410a54ee..a7e0f839d 100644 --- a/source/common/savegamehelp.h +++ b/source/common/savegamehelp.h @@ -15,8 +15,8 @@ void FinishSavegameRead(); class FileReader; FString G_BuildSaveName (const char *prefix); -int G_ValidateSavegame(FileReader &fr, FString *savetitle); -void G_WriteSaveHeader(const char *name, const char*mapname, const char *title); +int G_ValidateSavegame(FileReader &fr, FString *savetitle, bool formenu); +void G_WriteSaveHeader(const char* name); #define SAVEGAME_EXT ".dsave" diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 1f35b744a..1fc0dc686 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -5764,7 +5764,8 @@ static int G_EndOfLevel(void) { auto &p = *g_player[myconnectindex].ps; - STAT_Update(ud.eog); + if ((currentLevel->flags & MI_FORCEEOG)) ud.eog = 1; // if the finished level says to end the game, end it! + STAT_Update(ud.eog); P_SetGamePalette(&p, BASEPAL, 0); P_UpdateScreenPal(&p); @@ -5789,7 +5790,7 @@ static int G_EndOfLevel(void) // Clear potentially loaded per-map ART only after the bonus screens. artClearMapArt(); - if (ud.eog || G_HaveUserMap()) + if (ud.eog || G_HaveUserMap() || (currentLevel->flags & MI_FORCEEOG)) { ud.eog = 0; if ((!g_netServer && ud.multimode < 2)) @@ -5799,8 +5800,6 @@ static int G_EndOfLevel(void) G_DoOrderScreen(); #endif p.gm = 0; - M_StartControlPanel(false); - M_SetMenu(NAME_MainMenu); return 2; } else diff --git a/source/duke3d/src/global.h b/source/duke3d/src/global.h index 23657c87b..bfb84f74c 100644 --- a/source/duke3d/src/global.h +++ b/source/duke3d/src/global.h @@ -68,7 +68,6 @@ G_EXTERN actor_t actor[MAXSPRITES]; G_EXTERN tiledata_t g_tile[MAXTILES]; G_EXTERN animwalltype animwall[MAXANIMWALLS]; G_EXTERN char *label; -G_EXTERN int32_t g_musicIndex; G_EXTERN char g_loadFromGroupOnly; G_EXTERN char g_skillCnt; G_EXTERN char pus,pub; diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index a8a0a9339..e42bc2ad2 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -1720,7 +1720,7 @@ void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName) if (FileExists(nameBuf)) { - mapList[USERMAPMUSICFAKESLOT].music = nameBuf; + userMapRecord.music = nameBuf; return; } } @@ -1728,7 +1728,7 @@ void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName) auto &usermapMusic = mapList[MUS_USERMAP].music; if (usermapMusic.IsNotEmpty()) { - mapList[USERMAPMUSICFAKESLOT].music = usermapMusic; + userMapRecord.music = usermapMusic; return; } @@ -1738,7 +1738,7 @@ void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName) auto &e1l8 = mapList[7].music; if (e1l8.IsNotEmpty()) { - mapList[USERMAPMUSICFAKESLOT].music = e1l8; + userMapRecord.music = e1l8; return; } } @@ -1849,7 +1849,10 @@ int G_EnterLevel(int gameMode) OSD_Printf(OSD_ERROR "Map \"%s\" not found or invalid map version!\n", boardfilename); return 1; } - STAT_NewLevel(boardfilename); + userMapRecord.name = ""; + userMapRecord.SetFileName(boardfilename); + currentLevel = &userMapRecord; + STAT_NewLevel(boardfilename); G_LoadMapHack(levelName, boardfilename); G_SetupFilenameBasedMusic(levelName, boardfilename); } @@ -1860,6 +1863,7 @@ int G_EnterLevel(int gameMode) } else { + currentLevel = &mm; STAT_NewLevel(mm.fileName); G_LoadMapHack(levelName, mm.fileName); } @@ -1894,15 +1898,7 @@ int G_EnterLevel(int gameMode) { S_PlayLevelMusicOrNothing(USERMAPMUSICFAKESLOT); } - else if (mapList[g_musicIndex].music.IsEmpty() || mm.music.IsEmpty() || mapList[g_musicIndex].music.CompareNoCase(mm.music) == 0 || - g_musicSize == 0 || ud.last_level == -1) - { - S_PlayLevelMusicOrNothing(mapidx); - } - else - { - S_ContinueLevelMusic(); - } + else S_PlayLevelMusicOrNothing(mapidx); } M_ClearMenus(); diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index 1e2e30a17..41368ae6e 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -151,18 +151,7 @@ static FileReader *OpenSavegame(const char *fn) { return nullptr; } - auto file = ReadSavegameChunk("info.json"); - if (!file.isOpen()) - { - FinishSavegameRead(); - return nullptr; - } - if (G_ValidateSavegame(file, nullptr) <= 0) - { - FinishSavegameRead(); - return nullptr; - } - file = ReadSavegameChunk("snapshot.dat"); + auto file = ReadSavegameChunk("snapshot.dat"); if (!file.isOpen()) { FinishSavegameRead(); @@ -182,24 +171,6 @@ int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh) if (i < 0) goto corrupt; - ssfil = ReadSavegameChunk("screenshot.dat"); - - TileFiles.tileCreate(TILE_LOADSHOT, 200, 320); - if (ssfil.isOpen()) - { - if (ssfil.Read(tileData(TILE_LOADSHOT), 320 * 200) != 320 * 200) - { - OSD_Printf("G_LoadSaveHeaderNew(): failed reading screenshot in \"%s\"\n", fn); - goto corrupt; - } - } - else - { - Bmemset(tileData(TILE_LOADSHOT), 0, 320*200); - } - ssfil.Close(); - tileInvalidate(TILE_LOADSHOT, 0, 255); - delete fil; FinishSavegameRead(); return 0; @@ -1468,8 +1439,7 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i auto fw = WriteSavegameChunk("header.dat"); fw->Write(&h, sizeof(savehead_t)); - auto& mii = mapList[(MAXLEVELS * ud.volume_number) + ud.level_number]; - G_WriteSaveHeader(name, mii.fileName, mii.DisplayName()); + G_WriteSaveHeader(name); } else { @@ -1487,13 +1457,14 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i // write header - +#if 0 // not usable anymore if (spot >= 0 && tileData(TILE_SAVESHOT)) { auto fw = WriteSavegameChunk("screenshot.dat"); fw->Write(tileData(TILE_SAVESHOT), 320*200); } +#endif if (spot >= 0) diff --git a/source/duke3d/src/sounds.cpp b/source/duke3d/src/sounds.cpp index 995abb546..68b7e83cc 100644 --- a/source/duke3d/src/sounds.cpp +++ b/source/duke3d/src/sounds.cpp @@ -134,7 +134,6 @@ void S_MenuSound(void) static void S_SetMusicIndex(unsigned int m) { - g_musicIndex = m; ud.music_episode = m / MAXLEVELS; ud.music_level = m % MAXLEVELS; } @@ -148,7 +147,9 @@ void S_PlayLevelMusicOrNothing(unsigned int m) if (retval >= 0) { - Mus_Play(mapList[m].fileName, mapList[m].music, true); + // Thanks to scripting that stupid slot hijack cannot be refactored - but we'll store the real data elsewhere anyway! + auto &mr = m == USERMAPMUSICFAKESLOT ? userMapRecord : mapList[m]; + Mus_Play(mr.fileName, mr.music, true); S_SetMusicIndex(m); } } diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 72afda81e..32c608558 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -7196,7 +7196,7 @@ void G_BackToMenu(void) static int G_EndOfLevel(void) { - STAT_Update(ud.eog); + STAT_Update(ud.eog || (currentLevel->flags & MI_FORCEEOG)); P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 0); P_UpdateScreenPal(g_player[myconnectindex].ps); @@ -7226,7 +7226,7 @@ static int G_EndOfLevel(void) // Clear potentially loaded per-map ART only after the bonus screens. artClearMapArt(); - if (ud.eog) + if (ud.eog || (currentLevel->flags & MI_FORCEEOG)) { ud.eog = 0; if ((!g_netServer && ud.multimode < 2)) @@ -7234,8 +7234,6 @@ static int G_EndOfLevel(void) if (!VOLUMEALL) G_DoOrderScreen(); g_player[myconnectindex].ps->gm = 0; - M_StartControlPanel(false); - M_SetMenu(NAME_MainMenu); return 2; } else diff --git a/source/rr/src/global.h b/source/rr/src/global.h index 574f27750..28c900642 100644 --- a/source/rr/src/global.h +++ b/source/rr/src/global.h @@ -73,7 +73,6 @@ G_EXTERN actor_t actor[MAXSPRITES]; G_EXTERN tiledata_t g_tile[MAXTILES]; G_EXTERN animwalltype animwall[MAXANIMWALLS]; G_EXTERN char *label; -G_EXTERN int32_t g_musicIndex; G_EXTERN char g_loadFromGroupOnly; G_EXTERN char g_skillCnt; G_EXTERN char pus,pub; diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index 19b37b88e..6c879c24b 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -2243,7 +2243,7 @@ static void G_LoadMapHack(char *outbuf, const char *filename) } // levnamebuf should have at least size BMAX_PATH -void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName, int levelNum) +void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName) { char *p; char const *exts[] = { @@ -2277,12 +2277,12 @@ void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName, int levelNum if (FileExists(nameBuf)) { - mapList[levelNum].music = nameBuf; + userMapRecord.music = nameBuf; return; } } - mapList[levelNum].music = "dethtoll.mid"; + userMapRecord.music = "dethtoll.mid"; } int G_EnterLevel(int gameMode) @@ -2378,10 +2378,12 @@ int G_EnterLevel(int gameMode) OSD_Printf(OSD_ERROR "Map \"%s\" not found or invalid map version!\n", boardfilename); return 1; } - - STAT_NewLevel(boardfilename); + userMapRecord.name = ""; + userMapRecord.SetFileName(boardfilename); + currentLevel = &userMapRecord; + STAT_NewLevel(boardfilename); G_LoadMapHack(levelName, boardfilename); - G_SetupFilenameBasedMusic(levelName, boardfilename, m_level_number); + G_SetupFilenameBasedMusic(levelName, boardfilename); } else if (engineLoadBoard(mi.fileName, VOLUMEONE, &pPlayer->pos, &lbang, &pPlayer->cursectnum) < 0) { @@ -2390,6 +2392,7 @@ int G_EnterLevel(int gameMode) } else { + currentLevel = &mi; STAT_NewLevel(mi.fileName); G_LoadMapHack(levelName, mi.fileName); } @@ -2434,14 +2437,7 @@ int G_EnterLevel(int gameMode) if (ud.recstat != 2) { - if (mapList[g_musicIndex].music.IsEmpty() || - mi.music.IsEmpty() || - mi.music.CompareNoCase(mapList[g_musicIndex].music) || - g_musicSize == 0 || - ud.last_level == -1) - { - S_PlayLevelMusicOrNothing(mii); - } + S_PlayLevelMusicOrNothing(mii); } if (RR && !(gameMode & MODE_DEMO)) diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index 7838c98c5..319673e59 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -146,18 +146,7 @@ static FileReader *OpenSavegame(const char *fn) { return nullptr; } - auto file = ReadSavegameChunk("info.json"); - if (!file.isOpen()) - { - FinishSavegameRead(); - return nullptr; - } - if (G_ValidateSavegame(file, nullptr) <= 0) - { - FinishSavegameRead(); - return nullptr; - } - file = ReadSavegameChunk("snapshot.dat"); + auto file = ReadSavegameChunk("snapshot.dat"); if (!file.isOpen()) { FinishSavegameRead(); @@ -182,24 +171,6 @@ int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh) if (i < 0) goto corrupt; - ssfil = ReadSavegameChunk("screenshot.dat"); - - TileFiles.tileCreate(TILE_LOADSHOT, 200, 320); - if (ssfil.isOpen()) - { - if (ssfil.Read(tileData(TILE_LOADSHOT), 320 * 200) != 320 * 200) - { - OSD_Printf("G_LoadSaveHeaderNew(): failed reading screenshot in \"%s\"\n", fn); - goto corrupt; - } - } - else - { - Bmemset(tileData(TILE_LOADSHOT), 0, 320*200); - } - ssfil.Close(); - tileInvalidate(TILE_LOADSHOT, 0, 255); - delete fil; FinishSavegameRead(); return 0; @@ -1169,9 +1140,7 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i Bstrncpyz(h.savename, name, sizeof(h.savename)); auto fw = WriteSavegameChunk("header.dat"); fw->Write(&h, sizeof(savehead_t)); - - auto& mi = mapList[(MAXLEVELS * ud.volume_number) + ud.level_number]; - G_WriteSaveHeader(name, mi.fileName, mi.DisplayName()); + G_WriteSaveHeader(name); } else { @@ -1190,12 +1159,14 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i // write header +#if 0 // not usable anymore if (spot >= 0 && tileData(TILE_SAVESHOT)) { auto fw = WriteSavegameChunk("screenshot.dat"); fw->Write(tileData(TILE_SAVESHOT), 320*200); } +#endif if (spot >= 0) diff --git a/source/rr/src/sounds.cpp b/source/rr/src/sounds.cpp index fa516ac71..72cb948a0 100644 --- a/source/rr/src/sounds.cpp +++ b/source/rr/src/sounds.cpp @@ -123,17 +123,9 @@ void S_MenuSound(void) } -static void S_SetMusicIndex(unsigned int m) -{ - g_musicIndex = m; - ud.music_episode = m / MAXLEVELS; - ud.music_level = m % MAXLEVELS; -} - void S_PlayLevelMusicOrNothing(unsigned int m) { Mus_Play(mapList[m].fileName, RR ? nullptr : mapList[m].music, true); - S_SetMusicIndex(m); } int S_TryPlaySpecialMusic(unsigned int m) @@ -145,7 +137,6 @@ int S_TryPlaySpecialMusic(unsigned int m) { if (!Mus_Play(nullptr, musicfn, 1)) { - S_SetMusicIndex(m); return 0; } } @@ -169,10 +160,7 @@ void S_PlayRRMusic(int newTrack) void S_PlaySpecialMusicOrNothing(unsigned int m) { - if (S_TryPlaySpecialMusic(m)) - { - S_SetMusicIndex(m); - } + S_TryPlaySpecialMusic(m); } void S_Cleanup(void) diff --git a/source/sw/src/save.cpp b/source/sw/src/save.cpp index 5b18cf121..466d08026 100644 --- a/source/sw/src/save.cpp +++ b/source/sw/src/save.cpp @@ -58,6 +58,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "i_specialpaths.h" #include "savegamehelp.h" #include "z_music.h" +#include "mapinfo.h" //void TimerFunc(task * Task); BEGIN_SW_NS @@ -250,7 +251,12 @@ bool GameInterface::SaveGame(FSaveGameNode *sv) auto game_name = G_BuildSaveName(sv->Filename); OpenSaveGameForWrite(game_name); - G_WriteSaveHeader(sv->SaveTitle, LevelInfo[Level].LevelName, LevelInfo[Level].Description); + // workaround until the level info here has been transitioned. + MapRecord mr; + mr.SetFileName(LevelInfo[Level].Description); + mr.labelName = LevelInfo[Level].Description; + currentLevel = &mr; + G_WriteSaveHeader(sv->SaveTitle); fil = WriteSavegameChunk("snapshot.sw"); MWRITE(&GameVersion,sizeof(GameVersion),1,fil); From ebb43f912964748a039b5e494f2c5b7030493834 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 10 Dec 2019 23:04:06 +0100 Subject: [PATCH 190/203] - use the currentLevel record for the status screens. What was there could be broken by scripts thanks to the non-existent access control to critical variables. - give the final map in RR a proper mapinfo record. Without this the map is not really stable with the current savegame system. --- source/duke3d/src/screens.cpp | 26 +++++++++---------- source/duke3d/src/screens.h | 6 ----- source/rr/src/premap.cpp | 22 ++++------------ source/rr/src/screens.cpp | 49 ++++++++++++----------------------- source/rr/src/screens.h | 6 ----- 5 files changed, 35 insertions(+), 74 deletions(-) diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index 0deef00c2..140c4ff52 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -184,7 +184,7 @@ static void G_ShowScores(void) if (g_mostConcurrentPlayers > 1 && (g_gametypeFlags[ud.coop]&GAMETYPE_SCORESHEET)) { gametext_center(SCORESHEETOFFSET+58+2, GStrings("Multiplayer Totals")); - gametext_center(SCORESHEETOFFSET+58+10, mapList[G_LastMapInfoIndex()].DisplayName()); + gametext_center(SCORESHEETOFFSET+58+10, currentLevel->DisplayName()); t = 0; minitext(70, SCORESHEETOFFSET+80, GStrings("Name"), 8, 2+8+16+ROTATESPRITE_MAX); @@ -1885,7 +1885,7 @@ static void G_DisplayMPResultsScreen(void) if (PLUTOPAK) // JBF 20030804 rotatesprite_fs((260)<<16, 36<<16, 65536L, 0, PLUTOPAKSPRITE+2, 0, 0, 2+8); gametext_center(58+2, GStrings("Multiplayer Totals")); - gametext_center(58+10, mapList[G_LastMapInfoIndex()].DisplayName()); + gametext_center(58+10, currentLevel->DisplayName()); gametext_center_shade(165, GStrings("Presskey"), quotepulseshade); @@ -1953,11 +1953,11 @@ static int32_t G_PrintTime_ClockPad(void) clockpad = max(clockpad, ij); if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - for (ii=mapList[G_LastMapInfoIndex()].parTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } + for (ii=currentLevel->parTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } clockpad = max(clockpad, ij); - if (!NAM_WW2GI && mapList[G_LastMapInfoIndex()].designerTime) + if (!NAM_WW2GI && currentLevel->designerTime) { - for (ii= mapList[G_LastMapInfoIndex()].designerTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } + for (ii= currentLevel->designerTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } clockpad = max(clockpad, ij); } } @@ -1986,13 +1986,13 @@ const char* G_PrintParTime(void) { if (ud.last_level < 1) return ""; - return G_PrintTime2(mapList[G_LastMapInfoIndex()].parTime); + return G_PrintTime2(currentLevel->parTime); } const char* G_PrintDesignerTime(void) { if (ud.last_level < 1) return ""; - return G_PrintTime2(mapList[G_LastMapInfoIndex()].designerTime); + return G_PrintTime2(currentLevel->designerTime); } const char* G_PrintBestTime(void) { @@ -2017,9 +2017,9 @@ void G_BonusScreen(int32_t bonusonly) } else { - lastmapname = mapList[G_LastMapInfoIndex()].name; + lastmapname = currentLevel->name; if (!lastmapname || !*lastmapname) // this isn't right but it's better than no name at all - lastmapname = mapList[G_LastMapInfoIndex()].fileName; + lastmapname = currentLevel->fileName; } @@ -2185,12 +2185,12 @@ void G_BonusScreen(int32_t bonusonly) yy+=10; if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - if (mapList[G_LastMapInfoIndex()].parTime) + if (currentLevel->parTime) { gametext(10, yy+9, GStrings("TXT_ParTime")); yy+=10; } - if (!NAM_WW2GI && !DUKEBETA && mapList[G_LastMapInfoIndex()].designerTime) + if (!NAM_WW2GI && !DUKEBETA && currentLevel->designerTime) { // EDuke 2.0 / NAM source suggests "Green Beret's Time:" gametext(10, yy+9, GStrings("TXT_3DRTIME")); @@ -2229,13 +2229,13 @@ void G_BonusScreen(int32_t bonusonly) if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - if (mapList[G_LastMapInfoIndex()].parTime) + if (currentLevel->parTime) { G_PrintParTime(); gametext_number((320>>2)+71, yy+9, tempbuf); yy+=10; } - if (!NAM_WW2GI && !DUKEBETA && mapList[G_LastMapInfoIndex()].designerTime) + if (!NAM_WW2GI && !DUKEBETA && currentLevel->designerTime) { G_PrintDesignerTime(); gametext_number((320>>2)+71, yy+9, tempbuf); diff --git a/source/duke3d/src/screens.h b/source/duke3d/src/screens.h index beea34478..8c4ad1fc1 100644 --- a/source/duke3d/src/screens.h +++ b/source/duke3d/src/screens.h @@ -26,12 +26,6 @@ extern void G_DisplayExtraScreens(void); extern void G_DisplayLogo(void); extern void G_DoOrderScreen(void); -static inline int G_LastMapInfoIndex(void) -{ - Bassert(ud.last_level >= 1); // NOTE: last_level is 1-based - return ud.volume_number*MAXLEVELS + ud.last_level-1; -} - #ifdef DEBUGGINGAIDS typedef struct { uint32_t lastgtic; diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index 6c879c24b..a8f85ea56 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -2337,26 +2337,14 @@ int G_EnterLevel(int gameMode) } } - mii = (ud.volume_number*MAXLEVELS)+ud.level_number; + // Redirect the final RR level to a valid map record so that currentLevel can point to something. + mii = (RR && g_lastLevel)? 127 : (ud.volume_number*MAXLEVELS)+ud.level_number; auto &mi = mapList[mii]; - if (mi.fileName.IsEmpty()) + if (mi.fileName.IsEmpty() && !Menu_HaveUserMap()) { - if (RR && g_lastLevel) - { - // FIXME: Initialize this properly in the data structures! - mi.fileName = "endgame.map"; - mi.name = "$TXT_CLOSEENCOUNTERS"; - } - else if (Menu_HaveUserMap()) - { - mi.name = "$TXT_USERMAP"; - } - else - { - OSD_Printf(OSDTEXT_RED "Map E%dL%d not defined!\n", ud.volume_number+1, ud.level_number+1); - return 1; - } + OSD_Printf(OSDTEXT_RED "Map E%dL%d not defined!\n", ud.volume_number+1, ud.level_number+1); + return 1; } i = ud.screen_size; diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index cb4c93e07..a9f6b0133 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -176,7 +176,7 @@ static void G_ShowScores(void) if (g_mostConcurrentPlayers > 1 && (g_gametypeFlags[ud.coop]&GAMETYPE_SCORESHEET)) { gametext_center(SCORESHEETOFFSET+58+2, GStrings("Multiplayer Totals")); - gametext_center(SCORESHEETOFFSET+58+10, mapList[G_LastMapInfoIndex()].DisplayName()); + gametext_center(SCORESHEETOFFSET+58+10, currentLevel->DisplayName()); t = 0; minitext(70, SCORESHEETOFFSET+80, GStrings("Name"), 8, 2+8+16+ROTATESPRITE_MAX); @@ -1908,7 +1908,7 @@ static void G_DisplayMPResultsScreen(void) if (!RR && PLUTOPAK) // JBF 20030804 rotatesprite_fs((260)<<16, 36<<16, 65536L, 0, PLUTOPAKSPRITE+2, 0, 0, 2+8); gametext_center(58+(RR ? 0 : 2), GStrings("Multiplayer Totals")); - gametext_center(58+10, mapList[G_LastMapInfoIndex()].DisplayName()); + gametext_center(58+10, currentLevel->DisplayName()); gametext_center_shade(RR ? 175 : 165, GStrings("Presskey"), quotepulseshade); @@ -1976,11 +1976,11 @@ static int32_t G_PrintTime_ClockPad(void) clockpad = max(clockpad, ij); if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - for (ii=mapList[G_LastMapInfoIndex()].parTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } + for (ii=currentLevel->parTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } clockpad = max(clockpad, ij); - if (mapList[G_LastMapInfoIndex()].designerTime) + if (currentLevel->designerTime) { - for (ii=mapList[G_LastMapInfoIndex()].designerTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } + for (ii=currentLevel->designerTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } clockpad = max(clockpad, ij); } } @@ -2009,13 +2009,13 @@ const char* G_PrintParTime(void) { if (ud.last_level < 1) return ""; - return G_PrintTime2(mapList[G_LastMapInfoIndex()].parTime); + return G_PrintTime2(currentLevel->parTime); } const char* G_PrintDesignerTime(void) { if (ud.last_level < 1) return ""; - return G_PrintTime2(mapList[G_LastMapInfoIndex()].designerTime); + return G_PrintTime2(currentLevel->designerTime); } const char* G_PrintBestTime(void) { @@ -2040,18 +2040,9 @@ void G_BonusScreen(int32_t bonusonly) } else { - lastmapname = mapList[G_LastMapInfoIndex()].DisplayName(); + lastmapname = currentLevel->DisplayName(); } - if (RR) - { - if ((g_lastLevel && ud.volume_number == 2) || g_vixenLevel) - lastmapname = GStrings("TXT_CLOSEENCOUNTERS"); - else if (g_turdLevel) - lastmapname = GStrings("SMELTIN' PLANT"); - } - - fadepal(0, 0, 0, 0, 252, RR ? 4 : 28); videoSetViewableArea(0, 0, xdim-1, ydim-1); videoClearScreen(0L); @@ -2251,7 +2242,7 @@ void G_BonusScreen(int32_t bonusonly) yy+= yystep; if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - if (mapList[G_LastMapInfoIndex()].parTime) + if (currentLevel->parTime) { if (!RR) gametext(10, yy+9, GStrings("TXT_ParTime")); @@ -2259,7 +2250,7 @@ void G_BonusScreen(int32_t bonusonly) menutext(30, yy, GStrings("TXT_ParTime")); yy+=yystep; } - if (mapList[G_LastMapInfoIndex()].designerTime) + if (currentLevel->designerTime) { // EDuke 2.0 / NAM source suggests "Green Beret's Time:" if (DUKE) @@ -2315,7 +2306,7 @@ void G_BonusScreen(int32_t bonusonly) if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - if (mapList[G_LastMapInfoIndex()].parTime) + if (currentLevel->parTime) { G_PrintParTime(); if (!RR) @@ -2324,7 +2315,7 @@ void G_BonusScreen(int32_t bonusonly) menutext(191, yy, tempbuf); yy+=yystep; } - if (mapList[G_LastMapInfoIndex()].designerTime) + if (currentLevel->designerTime) { G_PrintDesignerTime(); if (DUKE) @@ -2618,15 +2609,9 @@ void G_BonusScreenRRRA(int32_t bonusonly) } else { - lastmapname = mapList[G_LastMapInfoIndex()].DisplayName(); + lastmapname = currentLevel->DisplayName(); } - if ((g_lastLevel && ud.volume_number == 2) || g_vixenLevel) - lastmapname = GStrings("TXT_CLOSEENCOUNTERS"); - else if (g_turdLevel) - lastmapname = GStrings("SMELTIN' PLANT"); - - fadepal(0, 0, 0, 0, 252, 4); videoSetViewableArea(0, 0, xdim-1, ydim-1); videoClearScreen(0L); @@ -2819,12 +2804,12 @@ void G_BonusScreenRRRA(int32_t bonusonly) yy+= yystep; if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - if (mapList[G_LastMapInfoIndex()].parTime) + if (currentLevel->parTime) { menutext(30, yy, GStrings("TXT_PARTIME")); yy+=yystep; } - if (mapList[G_LastMapInfoIndex()].designerTime) + if (currentLevel->designerTime) { menutext(30, yy, GStrings("TXT_XTRTIME")); yy+=yystep; @@ -2862,13 +2847,13 @@ void G_BonusScreenRRRA(int32_t bonusonly) if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - if (mapList[G_LastMapInfoIndex()].parTime) + if (currentLevel->parTime) { G_PrintParTime(); menutext(191, yy, tempbuf); yy+=yystep; } - if (mapList[G_LastMapInfoIndex()].designerTime) + if (currentLevel->designerTime) { G_PrintDesignerTime(); menutext(191, yy, tempbuf); diff --git a/source/rr/src/screens.h b/source/rr/src/screens.h index cf9018678..d6abe2bcd 100644 --- a/source/rr/src/screens.h +++ b/source/rr/src/screens.h @@ -26,12 +26,6 @@ extern void G_DisplayExtraScreens(void); extern void G_DisplayLogo(void); extern void G_DoOrderScreen(void); -static inline int G_LastMapInfoIndex(void) -{ - Bassert(ud.last_level >= 1); // NOTE: last_level is 1-based - return ud.volume_number*MAXLEVELS + ud.last_level-1; -} - #ifdef DEBUGGINGAIDS typedef struct { uint32_t lastgtic; From cc33c6a0ed98a350ba1a953687fc42f2cb7c0dee Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 10 Dec 2019 23:11:02 +0100 Subject: [PATCH 191/203] - deactivate statistics for user maps. This really isn't controllable. --- source/common/statistics.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/common/statistics.cpp b/source/common/statistics.cpp index cbe336141..ad9b31020 100644 --- a/source/common/statistics.cpp +++ b/source/common/statistics.cpp @@ -363,7 +363,11 @@ void STAT_StartNewGame(const char *episode, int skill) void STAT_NewLevel(const char* mapname) { - LevelName = mapname; + if (!strncmp(mapname, "file://", 7) == 0) + { + STAT_StartNewGame("", 0); // reset and deactivate for user maps + } + else LevelName = mapname; } //========================================================================== @@ -590,12 +594,14 @@ FString GetStatString() CCMD(printstats) { + if (*StartEpisode == 0 || *LevelName == 0) return; StoreLevelStats(); // Refresh the current level's results. Printf("%s", GetStatString().GetChars()); } ADD_STAT(statistics) { + if (*StartEpisode == 0 || *LevelName == 0) return; StoreLevelStats(); // Refresh the current level's results. return GetStatString(); } From 5c0cd5114dfb62af2bb1e86d26b992003f7fbddb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 11 Dec 2019 00:57:53 +0100 Subject: [PATCH 192/203] - transitioned Blood to the common mapinfo system. --- source/blood/src/blood.cpp | 10 ++--- source/blood/src/levels.cpp | 79 ++++++++++++++++++----------------- source/blood/src/levels.h | 28 ++++--------- source/blood/src/loadsave.cpp | 7 ---- source/blood/src/map2d.cpp | 4 +- source/blood/src/triggers.cpp | 2 +- source/common/mapinfo.h | 24 +++++++---- source/common/statistics.cpp | 2 +- source/duke3d/src/premap.cpp | 2 +- source/duke3d/src/sounds.cpp | 2 +- source/rr/src/sounds.cpp | 2 +- 11 files changed, 75 insertions(+), 87 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index d30d880d6..2bb26e7c9 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -542,6 +542,7 @@ void StartLevel(GAMEOPTIONS *gameOptions) return; } char levelName[BMAX_PATH]; + currentLevel = &mapList[gGameOptions.nEpisode * kMaxLevels + gGameOptions.nLevel]; STAT_NewLevel(gameOptions->zLevelName); G_LoadMapHack(levelName, gameOptions->zLevelName); wsrand(gameOptions->uMapCRC); @@ -1444,9 +1445,8 @@ static int32_t S_DefineMusic(const char *ID, const char *name) return -1; } - int nEpisode = sel/kMaxLevels; - int nLevel = sel%kMaxLevels; - return S_DefineAudioIfSupported(gEpisodeInfo[nEpisode].at28[nLevel].atd0, name); + quoteMgr.InitializeQuote(sel, name); + return 0; } static int parsedefinitions_game(scriptfile *, int); @@ -1988,9 +1988,7 @@ bool fileExistsRFF(int id, const char *ext) { int sndTryPlaySpecialMusic(int nMusic) { - int nEpisode = nMusic/kMaxLevels; - int nLevel = nMusic%kMaxLevels; - if (Mus_Play(gEpisodeInfo[nEpisode].at28[nLevel].at0, gEpisodeInfo[nEpisode].at28[nLevel].atd0, true)) + if (Mus_Play(nullptr, quoteMgr.GetQuote(nMusic), true)) { return 0; } diff --git a/source/blood/src/levels.cpp b/source/blood/src/levels.cpp index 7cc35c58f..b778153b4 100644 --- a/source/blood/src/levels.cpp +++ b/source/blood/src/levels.cpp @@ -146,48 +146,48 @@ void CheckKeyAbend(const char *pzSection, const char *pzKey) ThrowError("Key %s expected in section [%s] of BLOOD.INI", pzKey, pzSection); } -LEVELINFO * levelGetInfoPtr(int nEpisode, int nLevel) +MapRecord * levelGetInfoPtr(int nEpisode, int nLevel) { dassert(nEpisode >= 0 && nEpisode < gEpisodeCount); EPISODEINFO *pEpisodeInfo = &gEpisodeInfo[nEpisode]; dassert(nLevel >= 0 && nLevel < pEpisodeInfo->nLevels); - return &pEpisodeInfo->at28[nLevel]; + return &pEpisodeInfo->levels[nLevel]; } -char * levelGetFilename(int nEpisode, int nLevel) +const char * levelGetFilename(int nEpisode, int nLevel) { dassert(nEpisode >= 0 && nEpisode < gEpisodeCount); EPISODEINFO *pEpisodeInfo = &gEpisodeInfo[nEpisode]; dassert(nLevel >= 0 && nLevel < pEpisodeInfo->nLevels); - return pEpisodeInfo->at28[nLevel].at0; + return pEpisodeInfo->levels[nLevel].labelName; } -char * levelGetMessage(int nMessage) +const char * levelGetMessage(int nMessage) { int nEpisode = gGameOptions.nEpisode; int nLevel = gGameOptions.nLevel; dassert(nMessage < kMaxMessages); - char *pMessage = gEpisodeInfo[nEpisode].at28[nLevel].atec[nMessage]; + const char *pMessage = gEpisodeInfo[nEpisode].levels[nLevel].GetMessage(nMessage); if (*pMessage == 0) return NULL; return pMessage; } -char * levelGetTitle(void) +const char * levelGetTitle(void) { int nEpisode = gGameOptions.nEpisode; int nLevel = gGameOptions.nLevel; - char *pTitle = gEpisodeInfo[nEpisode].at28[nLevel].at90; + const char *pTitle = gEpisodeInfo[nEpisode].levels[nLevel].DisplayName(); if (*pTitle == 0) return NULL; return pTitle; } -char * levelGetAuthor(void) +const char * levelGetAuthor(void) { int nEpisode = gGameOptions.nEpisode; int nLevel = gGameOptions.nLevel; - char *pAuthor = gEpisodeInfo[nEpisode].at28[nLevel].atb0; + const char *pAuthor = gEpisodeInfo[nEpisode].levels[nLevel].author; if (*pAuthor == 0) return NULL; return pAuthor; @@ -197,26 +197,27 @@ void levelSetupOptions(int nEpisode, int nLevel) { gGameOptions.nEpisode = nEpisode; gGameOptions.nLevel = nLevel; - strcpy(gGameOptions.zLevelName, gEpisodeInfo[nEpisode].at28[nLevel].at0); + strcpy(gGameOptions.zLevelName, gEpisodeInfo[nEpisode].levels[nLevel].labelName); gGameOptions.uMapCRC = dbReadMapCRC(gGameOptions.zLevelName); - gGameOptions.nTrackNumber = gEpisodeInfo[nEpisode].at28[nLevel].ate0; + gGameOptions.nTrackNumber = gEpisodeInfo[nEpisode].levels[nLevel].cdSongId; } -void levelLoadMapInfo(IniFile *pIni, LEVELINFO *pLevelInfo, const char *pzSection) +void levelLoadMapInfo(IniFile *pIni, MapRecord *pLevelInfo, const char *pzSection, int epinum, int mapnum) { char buffer[16]; - strncpy(pLevelInfo->at90, pIni->GetKeyString(pzSection, "Title", pLevelInfo->at0), 31); - strncpy(pLevelInfo->atb0, pIni->GetKeyString(pzSection, "Author", ""), 31); - strncpy(pLevelInfo->atd0, pIni->GetKeyString(pzSection, "Song", ""), BMAX_PATH); - pLevelInfo->ate0 = pIni->GetKeyInt(pzSection, "Track", -1); - pLevelInfo->ate4 = pIni->GetKeyInt(pzSection, "EndingA", -1); - pLevelInfo->ate8 = pIni->GetKeyInt(pzSection, "EndingB", -1); - pLevelInfo->at8ec = pIni->GetKeyInt(pzSection, "Fog", -0); - pLevelInfo->at8ed = pIni->GetKeyInt(pzSection, "Weather", -0); + pLevelInfo->SetName(pIni->GetKeyString(pzSection, "Title", pLevelInfo->labelName)); + pLevelInfo->author = pIni->GetKeyString(pzSection, "Author", ""); + pLevelInfo->music.Format("%s.%s", pIni->GetKeyString(pzSection, "Song", ""), ".mid"); + pLevelInfo->cdSongId = pIni->GetKeyInt(pzSection, "Track", -1); + pLevelInfo->nextLevel = pIni->GetKeyInt(pzSection, "EndingA", -1); //if (pLevelInfo->nextLevel >= 0) pLevelInfo->nextLevel +epinum * kMaxLevels; + pLevelInfo->nextSecret = pIni->GetKeyInt(pzSection, "EndingB", -1); //if (pLevelInfo->nextSecret >= 0) pLevelInfo->nextSecret + epinum * kMaxLevels; + pLevelInfo->fog = pIni->GetKeyInt(pzSection, "Fog", -0); + pLevelInfo->weather = pIni->GetKeyInt(pzSection, "Weather", -0); + pLevelInfo->messageStart = 1024 + ((epinum * kMaxLevels) + mapnum) * kMaxMessages; for (int i = 0; i < kMaxMessages; i++) { sprintf(buffer, "Message%d", i+1); - strncpy(pLevelInfo->atec[i], pIni->GetKeyString(pzSection, buffer, ""), 63); + quoteMgr.InitializeQuote(pLevelInfo->messageStart + i, pIni->GetKeyString(pzSection, buffer, ""), true); } } @@ -226,7 +227,7 @@ void levelLoadDefaults(void) char buffer2[16]; levelInitINI(G_ConFile()); // This doubles for the INI in the global code. memset(gEpisodeInfo, 0, sizeof(gEpisodeInfo)); - strncpy(gEpisodeInfo[MUS_INTRO/kMaxLevels].at28[MUS_INTRO%kMaxLevels].atd0, "PESTIS", BMAX_PATH); + quoteMgr.InitializeQuote(MUS_INTRO, "PESTIS.MID"); int i; for (i = 0; i < kMaxEpisodes; i++) { @@ -253,17 +254,19 @@ void levelLoadDefaults(void) pEpisodeInfo->cutALevel = BloodINI->GetKeyInt(buffer, "CutSceneALevel", 0); if (pEpisodeInfo->cutALevel > 0) pEpisodeInfo->cutALevel--; + pEpisodeInfo->levels = mapList + i * kMaxLevels; int j; for (j = 0; j < kMaxLevels; j++) { - LEVELINFO *pLevelInfo = &pEpisodeInfo->at28[j]; + auto pLevelInfo = &pEpisodeInfo->levels[j]; sprintf(buffer2, "Map%d", j+1); if (!BloodINI->KeyExists(buffer, buffer2)) break; const char *pMap = BloodINI->GetKeyString(buffer, buffer2, NULL); CheckSectionAbend(pMap); - strncpy(pLevelInfo->at0, pMap, BMAX_PATH); - levelLoadMapInfo(BloodINI, pLevelInfo, pMap); + pLevelInfo->labelName = pMap; + pLevelInfo->fileName.Format("%s.map", pMap); + levelLoadMapInfo(BloodINI, pLevelInfo, pMap, i, j); } pEpisodeInfo->nLevels = j; } @@ -289,24 +292,24 @@ void levelAddUserMap(const char *pzMap) } nLevel = pEpisodeInfo->nLevels++; } - LEVELINFO *pLevelInfo = &pEpisodeInfo->at28[nLevel]; + auto pLevelInfo = &pEpisodeInfo->levels[nLevel]; ChangeExtension(buffer, ""); - strncpy(pLevelInfo->at0, buffer, BMAX_PATH); - levelLoadMapInfo(&UserINI, pLevelInfo, NULL); + pLevelInfo->name = buffer; + levelLoadMapInfo(&UserINI, pLevelInfo, NULL, nEpisode, nLevel); gGameOptions.nEpisode = nEpisode; gGameOptions.nLevel = nLevel; - gGameOptions.uMapCRC = dbReadMapCRC(pLevelInfo->at0); - strcpy(gGameOptions.zLevelName, pLevelInfo->at0); + gGameOptions.uMapCRC = dbReadMapCRC(pLevelInfo->name); + strcpy(gGameOptions.zLevelName, pLevelInfo->name); } void levelGetNextLevels(int nEpisode, int nLevel, int *pnEndingA, int *pnEndingB) { dassert(pnEndingA != NULL && pnEndingB != NULL); - LEVELINFO *pLevelInfo = &gEpisodeInfo[nEpisode].at28[nLevel]; - int nEndingA = pLevelInfo->ate4; + auto pLevelInfo = &gEpisodeInfo[nEpisode].levels[nLevel]; + int nEndingA = pLevelInfo->nextLevel; if (nEndingA >= 0) nEndingA--; - int nEndingB = pLevelInfo->ate8; + int nEndingB = pLevelInfo->nextSecret; if (nEndingB >= 0) nEndingB--; *pnEndingA = nEndingA; @@ -396,14 +399,14 @@ int levelGetMusicIdx(const char *str) bool levelTryPlayMusic(int nEpisode, int nLevel, bool bSetLevelSong) { char buffer[BMAX_PATH]; - if (mus_redbook && gEpisodeInfo[nEpisode].at28[nLevel].ate0 > 0) - snprintf(buffer, BMAX_PATH, "blood%02i.ogg", gEpisodeInfo[nEpisode].at28[nLevel].ate0); + if (mus_redbook && gEpisodeInfo[nEpisode].levels[nLevel].cdSongId > 0) + snprintf(buffer, BMAX_PATH, "blood%02i.ogg", gEpisodeInfo[nEpisode].levels[nLevel].cdSongId); else { - strncpy(buffer, gEpisodeInfo[nEpisode].at28[nLevel].atd0, BMAX_PATH); + strncpy(buffer, gEpisodeInfo[nEpisode].levels[nLevel].music, BMAX_PATH); } if (!strchr(buffer, '.')) strcat(buffer, ".mid"); - return !!Mus_Play(gEpisodeInfo[nEpisode].at28[nLevel].at0, buffer, true); + return !!Mus_Play(gEpisodeInfo[nEpisode].levels[nLevel].labelName, buffer, true); } void levelTryPlayMusicOrNothing(int nEpisode, int nLevel) diff --git a/source/blood/src/levels.h b/source/blood/src/levels.h index e0b5bb9d7..1d6aec8e2 100644 --- a/source/blood/src/levels.h +++ b/source/blood/src/levels.h @@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #pragma once #include "common_game.h" #include "inifile.h" +#include "mapinfo.h" BEGIN_BLD_NS @@ -68,27 +69,13 @@ enum { MUS_LOADING = MUS_FIRST_SPECIAL + 1, }; -struct LEVELINFO -{ - char at0[BMAX_PATH]; // Filename - char at90[32]; // Title - char atb0[32]; // Author - char atd0[BMAX_PATH]; // Song; - int ate0; // SongId - int ate4; // EndingA - int ate8; // EndingB - char atec[kMaxMessages][64]; // Messages - char at8ec; // Fog - char at8ed; // Weather -}; // 0x8ee bytes - struct EPISODEINFO { //char at0[32]; removed, so that the global episode name table can be used for consistency int nLevels; unsigned int bloodbath : 1; unsigned int cutALevel : 4; - LEVELINFO at28[kMaxLevels]; + MapRecord* levels; // points into the global table. char at8f08[BMAX_PATH]; char at8f98[BMAX_PATH]; int at9028; @@ -118,13 +105,12 @@ void levelSetupSecret(int nCount); void levelTriggerSecret(int nSecret); void CheckSectionAbend(const char *pzSection); void CheckKeyAbend(const char *pzSection, const char *pzKey); -LEVELINFO * levelGetInfoPtr(int nEpisode, int nLevel); -char * levelGetFilename(int nEpisode, int nLevel); -char * levelGetMessage(int nMessage); -char * levelGetTitle(void); -char * levelGetAuthor(void); +MapRecord * levelGetInfoPtr(int nEpisode, int nLevel); +const char * levelGetFilename(int nEpisode, int nLevel); +const char * levelGetMessage(int nMessage); +const char * levelGetTitle(void); +const char * levelGetAuthor(void); void levelSetupOptions(int nEpisode, int nLevel); -void levelLoadMapInfo(IniFile *pIni, LEVELINFO *pLevelInfo, const char *pzSection); void levelLoadDefaults(void); void levelAddUserMap(const char *pzMap); // EndingA is normal ending, EndingB is secret level diff --git a/source/blood/src/loadsave.cpp b/source/blood/src/loadsave.cpp index f35071504..a42cf95e3 100644 --- a/source/blood/src/loadsave.cpp +++ b/source/blood/src/loadsave.cpp @@ -209,13 +209,6 @@ bool GameInterface::SaveGame(FSaveGameNode* node) Printf(TEXTCOLOR_RED "%s\n", err.what()); return false; } - auto & li = gEpisodeInfo[gGameOptions.nEpisode].at28[gGameOptions.nLevel]; - // workaround until the level info here has been transitioned. - MapRecord mr; - mr.name = li.at90; - mr.labelName = li.at0; - mr.fileName.Format("%s.map", li.at0); - currentLevel = &mr; G_WriteSaveHeader(node->SaveTitle); LoadSave::hSFile = NULL; diff --git a/source/blood/src/map2d.cpp b/source/blood/src/map2d.cpp index 971118a38..e8532289c 100644 --- a/source/blood/src/map2d.cpp +++ b/source/blood/src/map2d.cpp @@ -197,8 +197,8 @@ void CViewMap::sub_25C74(void) videoClearScreen(0); renderDrawMapView(x,y,nZoom>>2,angle); sub_2541C(x,y,nZoom>>2,angle); - char *pTitle = levelGetTitle(); - char *pFilename = levelGetFilename(gGameOptions.nEpisode, gGameOptions.nLevel); + const char *pTitle = levelGetTitle(); + const char *pFilename = levelGetFilename(gGameOptions.nEpisode, gGameOptions.nLevel); if (pTitle) sprintf(pBuffer, "%s: %s", pFilename, pTitle); else diff --git a/source/blood/src/triggers.cpp b/source/blood/src/triggers.cpp index f1c310bff..6814d62c5 100644 --- a/source/blood/src/triggers.cpp +++ b/source/blood/src/triggers.cpp @@ -4769,7 +4769,7 @@ void trInit(void) void trTextOver(int nId) { - char *pzMessage = levelGetMessage(nId); + const char *pzMessage = levelGetMessage(nId); if (pzMessage) viewSetMessage(pzMessage, VanillaMode() ? 0 : 8, MESSAGE_PRIORITY_INI); // 8: gold } diff --git a/source/common/mapinfo.h b/source/common/mapinfo.h index b5882bc00..8ab0a1af9 100644 --- a/source/common/mapinfo.h +++ b/source/common/mapinfo.h @@ -2,6 +2,10 @@ #include "gstrings.h" #include "cmdlib.h" +#include "quotemgr.h" +#ifdef GetMessage +#undef GetMessage // Windows strikes... +#endif // Localization capable replacement of the game specific solutions. @@ -18,21 +22,21 @@ enum struct MapRecord { - int parTime; - int designerTime; + int parTime = -1; + int designerTime = -1; FString fileName; FString labelName; FString name; FString music; - int cdSongId; + int cdSongId = -1; + int flags = -1; // The rest is only used by Blood - int nextLevel; - int nextSecret; - int messageStart; // messages are stored in the quote array to reduce clutter. + int nextLevel = -1; + int nextSecret = -1; + int messageStart = 0; // messages are stored in the quote array to reduce clutter. FString author; - // bool fog, weather; // Blood defines these but they aren't used. - int flags; + int8_t fog = -1, weather = -1; // Blood defines these but they aren't used. const char *DisplayName() { @@ -49,6 +53,10 @@ struct MapRecord fileName = n; labelName = ExtractFileBase(n); } + const char* GetMessage(int num) + { + return quoteMgr.GetQuote(messageStart + num); + } }; diff --git a/source/common/statistics.cpp b/source/common/statistics.cpp index ad9b31020..8405e541c 100644 --- a/source/common/statistics.cpp +++ b/source/common/statistics.cpp @@ -601,7 +601,7 @@ CCMD(printstats) ADD_STAT(statistics) { - if (*StartEpisode == 0 || *LevelName == 0) return; + if (*StartEpisode == 0 || *LevelName == 0) return ""; StoreLevelStats(); // Refresh the current level's results. return GetStatString(); } diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index e42bc2ad2..4909abf05 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -419,7 +419,7 @@ void G_CacheMapData(void) if (ud.recstat == 2) return; - S_TryPlaySpecialMusic(MUS_LOADING); + //S_TryPlaySpecialMusic(MUS_LOADING); uint32_t const cacheStartTime = timerGetTicks(); diff --git a/source/duke3d/src/sounds.cpp b/source/duke3d/src/sounds.cpp index 68b7e83cc..48949bdee 100644 --- a/source/duke3d/src/sounds.cpp +++ b/source/duke3d/src/sounds.cpp @@ -149,7 +149,7 @@ void S_PlayLevelMusicOrNothing(unsigned int m) { // Thanks to scripting that stupid slot hijack cannot be refactored - but we'll store the real data elsewhere anyway! auto &mr = m == USERMAPMUSICFAKESLOT ? userMapRecord : mapList[m]; - Mus_Play(mr.fileName, mr.music, true); + Mus_Play(mr.labelName, mr.music, true); S_SetMusicIndex(m); } } diff --git a/source/rr/src/sounds.cpp b/source/rr/src/sounds.cpp index 72cb948a0..b86632a8f 100644 --- a/source/rr/src/sounds.cpp +++ b/source/rr/src/sounds.cpp @@ -125,7 +125,7 @@ void S_MenuSound(void) void S_PlayLevelMusicOrNothing(unsigned int m) { - Mus_Play(mapList[m].fileName, RR ? nullptr : mapList[m].music, true); + Mus_Play(mapList[m].labelName, RR ? nullptr : mapList[m].music, true); } int S_TryPlaySpecialMusic(unsigned int m) From 69fd6cf69d03db68da2d6f06493521f173f0db0d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 11 Dec 2019 01:01:03 +0100 Subject: [PATCH 193/203] - removed currentBoardFilename This was only used for displaying the name for user maps, everything else was using other means of getting the data already, and even here currentLevel is better suited. --- source/duke3d/src/game.cpp | 2 -- source/duke3d/src/game.h | 2 +- source/duke3d/src/player.cpp | 1 - source/duke3d/src/premap.cpp | 2 -- source/duke3d/src/savegame.cpp | 12 ------------ source/duke3d/src/screens.cpp | 13 ++----------- source/rr/src/game.cpp | 2 +- source/rr/src/game.h | 2 +- source/rr/src/premap.cpp | 1 - source/rr/src/savegame.cpp | 9 --------- source/rr/src/screens.cpp | 17 ++++------------- 11 files changed, 9 insertions(+), 54 deletions(-) diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 1fc0dc686..ca79bfbc1 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -79,8 +79,6 @@ int32_t g_quitDeadline = 0; int32_t g_cameraDistance = 0, g_cameraClock = 0; static int32_t g_quickExit; -char boardfilename[BMAX_PATH] = {0}, currentboardfilename[BMAX_PATH] = {0}; - int32_t voting = -1; int32_t vote_map = -1, vote_episode = -1; diff --git a/source/duke3d/src/game.h b/source/duke3d/src/game.h index 85964c43f..4b77984cf 100644 --- a/source/duke3d/src/game.h +++ b/source/duke3d/src/game.h @@ -199,7 +199,7 @@ extern user_defs ud; // this is checked against http://eduke32.com/VERSION extern const char *s_buildDate; -extern char boardfilename[BMAX_PATH], currentboardfilename[BMAX_PATH]; +extern char boardfilename[BMAX_PATH]; #define USERMAPMUSICFAKEVOLUME MAXVOLUMES #define USERMAPMUSICFAKELEVEL (MAXLEVELS-1) #define USERMAPMUSICFAKESLOT ((USERMAPMUSICFAKEVOLUME * MAXLEVELS) + USERMAPMUSICFAKELEVEL) diff --git a/source/duke3d/src/player.cpp b/source/duke3d/src/player.cpp index 70f7ded60..c15ea143f 100644 --- a/source/duke3d/src/player.cpp +++ b/source/duke3d/src/player.cpp @@ -5613,7 +5613,6 @@ int portableBackupSave(const char * path, const char * name, int volume, int lev sjson_node * root = sjson_mkobject(ctx); sjson_put_string(ctx, root, "name", name); - // sjson_put_string(ctx, root, "map", currentboardfilename); sjson_put_int(ctx, root, "volume", volume); sjson_put_int(ctx, root, "level", level); sjson_put_int(ctx, root, "skill", ud.player_skill); diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index 4909abf05..a48db358e 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -1940,8 +1940,6 @@ int G_EnterLevel(int gameMode) G_ResetTimers(0); // Here we go - Bmemcpy(currentboardfilename, boardfilename, BMAX_PATH); - G_CheckIfStateless(); for (int TRAVERSE_CONNECT(i)) diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index 41368ae6e..c63759737 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -302,9 +302,6 @@ int32_t G_LoadPlayer(FSaveGameNode *sv) append_ext_UNSAFE(workbuffer, ".mhk"); engineLoadMHK(workbuffer); } - - currentboardfilename[0] = '\0'; - // G_NewGame_EnterLevel(); } @@ -503,8 +500,6 @@ int32_t G_LoadPlayer(FSaveGameNode *sv) engineLoadMHK(workbuffer); } - Bmemcpy(currentboardfilename, boardfilename, BMAX_PATH); - if (status == 2) G_NewGame_EnterLevel(); else if ((status = sv_loadsnapshot(*fil, 0, &h))) // read the rest... @@ -1166,8 +1161,6 @@ static const dataspec_t svgm_udnetw[] = { DS_NOCHK, &ud.noexits, sizeof(ud.noexits), 1 }, { DS_NOCHK, &ud.playerai, sizeof(ud.playerai), 1 }, { 0, &ud.pause_on, sizeof(ud.pause_on), 1 }, - { DS_NOCHK, ¤tboardfilename[0], BMAX_PATH, 1 }, -// { DS_LOADFN, (void *)&sv_postudload, 0, 1 }, { 0, connectpoint2, sizeof(connectpoint2), 1 }, { 0, &randomseed, sizeof(randomseed), 1 }, { 0, &g_globalRandom, sizeof(g_globalRandom), 1 }, @@ -1428,10 +1421,6 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i h.levnum = ud.level_number; h.skill = ud.player_skill; - const uint32_t BSZ = sizeof(h.boardfn); - EDUKE32_STATIC_ASSERT(BSZ == sizeof(currentboardfilename)); - Bstrncpy(h.boardfn, currentboardfilename, BSZ); - if (spot >= 0) { // savegame @@ -1686,7 +1675,6 @@ int32_t sv_readdiff(FileReader &fil) // SVGM data description static void sv_postudload() { -// Bmemcpy(&boardfilename[0], ¤tboardfilename[0], BMAX_PATH); // DON'T do this in demos! #if 1 m_level_number = ud.level_number; ud.m_volume_number = ud.volume_number; diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index 140c4ff52..7fa039dbb 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -993,17 +993,8 @@ void G_DisplayRest(int32_t smoothratio) o |= 1|32; else if (g_levelTextTime < 5) o |= 1; - - auto dname = mapList[(ud.volume_number * MAXLEVELS) + ud.level_number].DisplayName(); - if (dname != NULL && *dname != 0) - { - char const * const fn = currentboardfilename[0] != 0 && - ud.volume_number == 0 && ud.level_number == 7 - ? currentboardfilename - : dname; - - menutext_(160<<16, (90+16+8)<<16, -g_levelTextTime+22/*quotepulseshade*/, fn, o, TEXT_XCENTER); - } + + menutext_(160<<16, (90+16+8)<<16, -g_levelTextTime+22/*quotepulseshade*/, currentLevel->DisplayName(), o, TEXT_XCENTER); } if (g_player[myconnectindex].ps->newowner == -1 && ud.overhead_on == 0 && cl_crosshair && ud.camerasprite == -1) diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 32c608558..cc9faa2c5 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -79,7 +79,7 @@ int32_t g_quitDeadline = 0; int32_t g_cameraDistance = 0, g_cameraClock = 0; static int32_t g_quickExit; -char boardfilename[BMAX_PATH] = {0}, currentboardfilename[BMAX_PATH] = {0}; +char boardfilename[BMAX_PATH] = {0}; int32_t voting = -1; int32_t vote_map = -1, vote_episode = -1; diff --git a/source/rr/src/game.h b/source/rr/src/game.h index 7b451136e..cc4d938f0 100644 --- a/source/rr/src/game.h +++ b/source/rr/src/game.h @@ -198,7 +198,7 @@ extern user_defs ud; // this is checked against http://eduke32.com/VERSION extern const char *s_buildDate; -extern char boardfilename[BMAX_PATH], currentboardfilename[BMAX_PATH]; +extern char boardfilename[BMAX_PATH]; static inline int G_HaveUserMap(void) { diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index a8f85ea56..3a98f6808 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -2502,7 +2502,6 @@ int G_EnterLevel(int gameMode) //AddLog(g_szBuf); // variables are set by pointer... - Bmemcpy(currentboardfilename, boardfilename, BMAX_PATH); if (G_HaveUserMap()) { diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index 319673e59..ab9e93477 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -258,8 +258,6 @@ int32_t G_LoadPlayer(const char *path) engineLoadMHK(workbuffer); } - Bmemcpy(currentboardfilename, boardfilename, BMAX_PATH); - if (status == 2) G_NewGame_EnterLevel(); else if ((status = sv_loadsnapshot(*fil, 0, &h))) // read the rest... @@ -883,8 +881,6 @@ static const dataspec_t svgm_udnetw[] = { DS_NOCHK, &ud.noexits, sizeof(ud.noexits), 1 }, { DS_NOCHK, &ud.playerai, sizeof(ud.playerai), 1 }, { 0, &ud.pause_on, sizeof(ud.pause_on), 1 }, - { DS_NOCHK, ¤tboardfilename[0], BMAX_PATH, 1 }, -// { DS_LOADFN, (void *)&sv_postudload, 0, 1 }, { 0, connectpoint2, sizeof(connectpoint2), 1 }, { 0, &randomseed, sizeof(randomseed), 1 }, { 0, &g_globalRandom, sizeof(g_globalRandom), 1 }, @@ -1130,10 +1126,6 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i h.levnum = ud.level_number; h.skill = ud.player_skill; - const uint32_t BSZ = sizeof(h.boardfn); - EDUKE32_STATIC_ASSERT(BSZ == sizeof(currentboardfilename)); - Bstrncpy(h.boardfn, currentboardfilename, BSZ); - if (spot >= 0) { // savegame @@ -1382,7 +1374,6 @@ int32_t sv_readdiff(FileReader &fil) // SVGM data description static void sv_postudload() { -// Bmemcpy(&boardfilename[0], ¤tboardfilename[0], BMAX_PATH); // DON'T do this in demos! #if 1 m_level_number = ud.level_number; ud.m_volume_number = ud.volume_number; diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index a9f6b0133..a00d2d27c 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -989,14 +989,9 @@ void G_DisplayRest(int32_t smoothratio) if (ud.overhead_on == 2) { const int32_t a = RR ? 0 : ((ud.screen_size > 0) ? 147 : 179); - if (RR && g_lastLevel) - minitext(5, a+6, "CLOSE ENCOUNTERS", 0, 2+8+16+256); - else - { - if (!G_HaveUserMap()) - minitext(5, a+6, GStrings.localize(gVolumeNames[ud.volume_number]), 0, 2+8+16+256); - minitext(5, a+6+6, mapList[ud.volume_number*MAXLEVELS + ud.level_number].DisplayName(), 0, 2+8+16+256); - } + if (!G_HaveUserMap()) + minitext(5, a+6, GStrings.localize(gVolumeNames[ud.volume_number]), 0, 2+8+16+256); + minitext(5, a+6+6, currentLevel->DisplayName(), 0, 2+8+16+256); } } } @@ -1025,11 +1020,7 @@ void G_DisplayRest(int32_t smoothratio) else if (g_levelTextTime < 5) o |= 1; - char const * const fn = currentboardfilename[0] != 0 && - ud.volume_number == 0 && ud.level_number == 7 - ? currentboardfilename - : mapList[(ud.volume_number*MAXLEVELS) + ud.level_number].DisplayName(); - menutext_(160<<16, (90+16+8)<<16, -g_levelTextTime+22/*quotepulseshade*/, fn, o, TEXT_XCENTER); + menutext_(160<<16, (90+16+8)<<16, -g_levelTextTime+22/*quotepulseshade*/, currentLevel->DisplayName(), o, TEXT_XCENTER); } if (g_player[myconnectindex].ps->newowner == -1 && ud.overhead_on == 0 && cl_crosshair && ud.camerasprite == -1) From cb051b44ea301d5e2936dc03e23117be0f6afcab Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 11 Dec 2019 01:10:59 +0100 Subject: [PATCH 194/203] - removed unused compression records from savegame header --- source/common/savegamehelp.cpp | 6 ++--- source/duke3d/src/demo.cpp | 2 +- source/duke3d/src/savegame.cpp | 44 +++++-------------------------- source/duke3d/src/savegame.h | 7 ++--- source/rr/src/demo.cpp | 2 +- source/rr/src/savegame.cpp | 48 +++++++--------------------------- source/rr/src/savegame.h | 7 ++--- 7 files changed, 25 insertions(+), 91 deletions(-) diff --git a/source/common/savegamehelp.cpp b/source/common/savegamehelp.cpp index f0c7b1cb2..29d6e7025 100644 --- a/source/common/savegamehelp.cpp +++ b/source/common/savegamehelp.cpp @@ -148,7 +148,7 @@ void G_WriteSaveHeader(const char *name) sjson_put_string(ctx, root, "Map Label", currentLevel->labelName); const char *fn = currentLevel->fileName; if (*fn == '/') fn++; - if (!strncmp(fn, "file://", 7) != 0) // this only has meaning for non-usermaps + if (strncmp(fn, "file://", 7) != 0) // this only has meaning for non-usermaps { auto fileno = fileSystem.FindFile(fn); auto mapfile = fileSystem.GetFileContainer(fileno); @@ -190,7 +190,7 @@ static bool CheckSingleFile (const char *name, bool &printRequires, bool printwa { return true; } - if (!strncmp(name, "file://", 7) == 0) + if (strncmp(name, "file://", 7) == 0) { return FileExists(name + 7); // User maps must be present to be validated. } @@ -274,7 +274,7 @@ int G_ValidateSavegame(FileReader &fr, FString *savetitle, bool formenu) MapRecord *curLevel = nullptr; - if (!strncmp(filename, "file://", 7) != 0) + if (strncmp(filename, "file://", 7) != 0) { for (auto& mr : mapList) { diff --git a/source/duke3d/src/demo.cpp b/source/duke3d/src/demo.cpp index 9410c395f..4326d711a 100644 --- a/source/duke3d/src/demo.cpp +++ b/source/duke3d/src/demo.cpp @@ -109,7 +109,7 @@ static int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine demo_hasdiffs = saveh.recdiffsp; g_demo_totalCnt = saveh.reccnt; - demo_hasseeds = saveh.synccompress & 2; + demo_hasseeds = 0; i = g_demo_totalCnt/REALGAMETICSPERSEC; OSD_Printf("demo %d duration: %d min %d sec\n", g_whichDemo, i/60, i%60); diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index c63759737..b0dd65d68 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -184,10 +184,6 @@ corrupt: static void sv_postudload(); -// hack -static int different_user_map; - - // XXX: keyboard input 'blocked' after load fail? (at least ESC?) int32_t G_LoadPlayer(FSaveGameNode *sv) { @@ -480,9 +476,7 @@ int32_t G_LoadPlayer(FSaveGameNode *sv) ud.m_player_skill = h.skill; // NOTE: Bmemcpy needed for SAVEGAME_MUSIC. - EDUKE32_STATIC_ASSERT(sizeof(boardfilename) == sizeof(h.boardfn)); - different_user_map = Bstrcmp(boardfilename, h.boardfn); - Bmemcpy(boardfilename, h.boardfn, sizeof(boardfilename)); + strcpy(boardfilename, currentLevel->fileName); int const mapIdx = h.volnum*MAXLEVELS + h.levnum; @@ -655,11 +649,6 @@ typedef struct dataspec_gv_ intptr_t cnt; } dataspec_gv_t; -#define SV_DEFAULTCOMPRTHRES 8 -static uint8_t savegame_diffcompress; // 0:none, 1:Ken's LZW in cache1d.c -static uint8_t savegame_comprthres; - - #define DS_DYNAMIC 1 // dereference .ptr one more time #define DS_STRING 2 #define DS_CMP 4 @@ -807,8 +796,8 @@ static int32_t readspecdata(const dataspec_t *spec, FileReader *fil, uint8_t **d if (ksiz != siz) { OSD_Printf("rsd: spec=%s, idx=%d, mem=%p\n", (char *)sptr->ptr, (int32_t)(spec - sptr), mem); - OSD_Printf(" (%s): read %d, expected %d!\n", - ((spec->flags & DS_CNTMASK) == 0 && spec->size * cnt <= savegame_comprthres) ? "uncompressed" : "compressed", ksiz, siz); + OSD_Printf(" : read %d, expected %d!\n", + ksiz, siz); if (ksiz == -1) OSD_Printf(" read: %s\n", strerror(errno)); @@ -1379,14 +1368,10 @@ static void SV_AllocSnap(int32_t allocinit) } // make snapshot only if spot < 0 (demo) -int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress) +int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp) { savehead_t h; - // set a few savegame system globals - savegame_comprthres = SV_DEFAULTCOMPRTHRES; - savegame_diffcompress = diffcompress; - // calculate total snapshot size #if !defined LUNATIC sv_makevarspec(); @@ -1405,10 +1390,6 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i h.bytever = BYTEVERSION; h.userbytever = ud.userbytever; h.scriptcrc = g_scriptcrc; - h.comprthres = savegame_comprthres; - h.recdiffsp = recdiffsp; - h.diffcompress = savegame_diffcompress; - h.synccompress = synccompress; h.reccnt = 0; h.snapsiz = svsnapsiz; @@ -1424,7 +1405,6 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i if (spot >= 0) { // savegame - Bstrncpyz(h.savename, name, sizeof(h.savename)); auto fw = WriteSavegameChunk("header.dat"); fw->Write(&h, sizeof(savehead_t)); @@ -1432,15 +1412,10 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i } else { - // demo - + // demo (currently broken, needs a new format.) const time_t t = time(NULL); - struct tm * st; - - Bstrncpyz(h.savename, "EDuke32 demo", sizeof(h.savename)); - if (t>=0 && (st = localtime(&t))) - Bsnprintf(h.savename, sizeof(h.savename), "Demo %04d%02d%02d %s", - st->tm_year+1900, st->tm_mon+1, st->tm_mday, GetGitDescription()); + struct tm * st = localtime(&t); + FStringf demoname("Demo %04d%02d%02d %s", st->tm_year+1900, st->tm_mon+1, st->tm_mday, GetGitDescription()); fil.Write(&h, sizeof(savehead_t)); } @@ -1566,8 +1541,6 @@ int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h) OSD_Printf("sv_loadsnapshot: snapshot size: %d bytes.\n", h->snapsiz); #endif - savegame_comprthres = h->comprthres; - if (spot >= 0) { // savegame @@ -1580,9 +1553,6 @@ int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h) } else { - // demo - savegame_diffcompress = h->diffcompress; - svsnapsiz = h->snapsiz; SV_AllocSnap(1); diff --git a/source/duke3d/src/savegame.h b/source/duke3d/src/savegame.h index f50e588fc..3b7bddded 100644 --- a/source/duke3d/src/savegame.h +++ b/source/duke3d/src/savegame.h @@ -46,16 +46,13 @@ typedef struct uint32_t userbytever; uint32_t scriptcrc; - uint8_t comprthres; - uint8_t recdiffsp, diffcompress, synccompress; + uint8_t recdiffsp; // 4 bytes int32_t reccnt, snapsiz; // 8 bytes - char savename[MAXSAVEGAMENAMESTRUCT]; uint8_t numplayers, volnum, levnum, skill; - char boardfn[BMAX_PATH]; // 286 bytes uint8_t getPtrSize() const { return ptrsize; } @@ -71,7 +68,7 @@ int32_t sv_readdiff(FileReader& fil); uint32_t sv_writediff(FileWriter *fil); int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h); int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h); -int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress); +int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp); void sv_freemem(); int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh); void ReadSaveGameHeaders(void); diff --git a/source/rr/src/demo.cpp b/source/rr/src/demo.cpp index bc005061c..50aef49a1 100644 --- a/source/rr/src/demo.cpp +++ b/source/rr/src/demo.cpp @@ -109,7 +109,7 @@ static int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine demo_hasdiffs = saveh.recdiffsp; g_demo_totalCnt = saveh.reccnt; - demo_hasseeds = saveh.synccompress&2; + demo_hasseeds = 0; i = g_demo_totalCnt/REALGAMETICSPERSEC; OSD_Printf("demo %d duration: %d min %d sec\n", g_whichDemo, i/60, i%60); diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index ab9e93477..45959408c 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -184,8 +184,6 @@ corrupt: static void sv_postudload(); -// hack -static int different_user_map; // XXX: keyboard input 'blocked' after load fail? (at least ESC?) int32_t G_LoadPlayer(const char *path) @@ -240,16 +238,10 @@ int32_t G_LoadPlayer(const char *path) ud.m_player_skill = h.skill; // NOTE: Bmemcpy needed for SAVEGAME_MUSIC. - EDUKE32_STATIC_ASSERT(sizeof(boardfilename) == sizeof(h.boardfn)); - different_user_map = Bstrcmp(boardfilename, h.boardfn); - Bmemcpy(boardfilename, h.boardfn, sizeof(boardfilename)); + strcpy(boardfilename, currentLevel->fileName); - int const mapIdx = h.volnum*MAXLEVELS + h.levnum; char workbuffer[BMAX_PATH]; - if (boardfilename[0]) - Bstrcpy(workbuffer, boardfilename); - else - Bstrcpy(workbuffer, mapList[mapIdx].fileName); + Bstrcpy(workbuffer, currentLevel->fileName); if (workbuffer[0]) { @@ -393,11 +385,6 @@ typedef struct dataspec_ intptr_t cnt; } dataspec_t; -#define SV_DEFAULTCOMPRTHRES 8 -static uint8_t savegame_diffcompress; // 0:none, 1:Ken's LZW in cache1d.c -static uint8_t savegame_comprthres; - - #define DS_DYNAMIC 1 // dereference .ptr one more time #define DS_STRING 2 #define DS_CMP 4 @@ -545,8 +532,8 @@ static int32_t readspecdata(const dataspec_t *spec, FileReader *fil, uint8_t **d if (ksiz != siz) { OSD_Printf("rsd: spec=%s, idx=%d, mem=%p\n", (char *)sptr->ptr, (int32_t)(spec - sptr), mem); - OSD_Printf(" (%s): read %d, expected %d!\n", - ((spec->flags & DS_CNTMASK) == 0 && spec->size * cnt <= savegame_comprthres) ? "uncompressed" : "compressed", ksiz, siz); + OSD_Printf(" : read %d, expected %d!\n", + ksiz, siz); if (ksiz == -1) OSD_Printf(" read: %s\n", strerror(errno)); @@ -1086,14 +1073,10 @@ static void SV_AllocSnap(int32_t allocinit) } // make snapshot only if spot < 0 (demo) -int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave) +int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, bool isAutoSave) { savehead_t h; - // set a few savegame system globals - savegame_comprthres = SV_DEFAULTCOMPRTHRES; - savegame_diffcompress = diffcompress; - // calculate total snapshot size svsnapsiz = calcsz(svgm_udnetw) + calcsz(svgm_secwsp) + calcsz(svgm_script) + calcsz(svgm_anmisc); @@ -1110,10 +1093,6 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i h.bytever = BYTEVERSION; h.userbytever = ud.userbytever; h.scriptcrc = g_scriptcrc; - h.comprthres = savegame_comprthres; - h.recdiffsp = recdiffsp; - h.diffcompress = savegame_diffcompress; - h.synccompress = synccompress; h.reccnt = 0; h.snapsiz = svsnapsiz; @@ -1129,7 +1108,6 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i if (spot >= 0) { // savegame - Bstrncpyz(h.savename, name, sizeof(h.savename)); auto fw = WriteSavegameChunk("header.dat"); fw->Write(&h, sizeof(savehead_t)); G_WriteSaveHeader(name); @@ -1137,15 +1115,12 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i else { // demo - + // demo (currently broken, needs a new format.) const time_t t = time(NULL); - struct tm * st; - - Bstrncpyz(h.savename, "EDuke32 demo", sizeof(h.savename)); - if (t>=0 && (st = localtime(&t))) - Bsnprintf(h.savename, sizeof(h.savename), "Demo %04d%02d%02d %s", - st->tm_year+1900, st->tm_mon+1, st->tm_mday, GetGitDescription()); + struct tm * st = localtime(&t); + FStringf demoname("Demo %04d%02d%02d %s", st->tm_year+1900, st->tm_mon+1, st->tm_mday, GetGitDescription()); fil.Write(&h, sizeof(savehead_t)); + } @@ -1271,8 +1246,6 @@ int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h) OSD_Printf("sv_loadsnapshot: snapshot size: %d bytes.\n", h->snapsiz); #endif - savegame_comprthres = h->comprthres; - if (spot >= 0) { // savegame @@ -1285,9 +1258,6 @@ int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h) } else { - // demo - savegame_diffcompress = h->diffcompress; - svsnapsiz = h->snapsiz; SV_AllocSnap(1); diff --git a/source/rr/src/savegame.h b/source/rr/src/savegame.h index c30497b78..ab205105d 100644 --- a/source/rr/src/savegame.h +++ b/source/rr/src/savegame.h @@ -41,16 +41,13 @@ typedef struct uint32_t userbytever; uint32_t scriptcrc; - uint8_t comprthres; - uint8_t recdiffsp, diffcompress, synccompress; + uint8_t recdiffsp; // 4 bytes int32_t reccnt, snapsiz; // 8 bytes - char savename[MAXSAVEGAMENAMESTRUCT]; uint8_t numplayers, volnum, levnum, skill; - char boardfn[BMAX_PATH]; // 286 bytes uint8_t getPtrSize() const { return ptrsize; } @@ -62,7 +59,7 @@ int32_t sv_readdiff(FileReader& fil); uint32_t sv_writediff(FileWriter *fil); int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h); int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h); -int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave = false); +int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, bool isAutoSave = false); void sv_freemem(); int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh); void ReadSaveGameHeaders(void); From ec96ae89929830e36000fc08db43c52e916b0bea Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 11 Dec 2019 01:11:35 +0100 Subject: [PATCH 195/203] - cleanup of -map setup. --- source/common/utility/cmdlib.cpp | 15 +++++++++++++++ source/common/utility/cmdlib.h | 1 + source/duke3d/src/game.cpp | 28 ++++++++++------------------ source/rr/src/game.cpp | 30 +++++++++++------------------- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/source/common/utility/cmdlib.cpp b/source/common/utility/cmdlib.cpp index c0fc1dcb0..dcae2ec8d 100644 --- a/source/common/utility/cmdlib.cpp +++ b/source/common/utility/cmdlib.cpp @@ -47,6 +47,7 @@ #endif #endif #include "cmdlib.h" +#include "compat.h" #include #include @@ -757,3 +758,17 @@ bool IsAbsPath(const char *name) #endif /* _WIN32 */ return 0; } + +//========================================================================== +// +// +// +//========================================================================== + +void NormalizeFileName(FString &str) +{ + auto strp = str.LockBuffer(); + Bcorrectfilename(strp, false); + str.UnlockBuffer(); +} + diff --git a/source/common/utility/cmdlib.h b/source/common/utility/cmdlib.h index 045037651..cda5b8a74 100644 --- a/source/common/utility/cmdlib.h +++ b/source/common/utility/cmdlib.h @@ -27,6 +27,7 @@ bool DirEntryExists (const char *pathname, bool *isdir = nullptr); extern FString progdir; void DefaultExtension (FString &path, const char *extension); +void NormalizeFileName(FString &str); FString ExtractFilePath (const char *path); FString ExtractFileBase (const char *path, bool keep_extension=false); diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index ca79bfbc1..759310fda 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -5656,38 +5656,30 @@ static void G_Startup(void) if (userConfig.CommandMap.IsNotEmpty()) { + FString startupMap; if (VOLUMEONE) { initprintf("The -map option is available in the registered version only!\n"); - boardfilename[0] = 0; } else { - char *dot, *slash; + startupMap = userConfig.CommandMap; + if (startupMap.IndexOfAny("/\\") < 0) startupMap.Insert(0, "/"); + DefaultExtension(startupMap, ".map"); + startupMap.Substitute("\\", "/"); + NormalizeFileName(startupMap); - boardfilename[0] = '/'; - boardfilename[1] = 0; - Bstrcat(boardfilename, userConfig.CommandMap); - - dot = Bstrrchr(boardfilename,'.'); - slash = Bstrrchr(boardfilename,'/'); - if (!slash) slash = Bstrrchr(boardfilename,'\\'); - - if ((!slash && !dot) || (slash && dot < slash)) - Bstrcat(boardfilename,".map"); - - Bcorrectfilename(boardfilename,0); - - if (fileSystem.FileExists(boardfilename)) + if (fileSystem.FileExists(startupMap)) { - initprintf("Using level: \"%s\".\n",boardfilename); + initprintf("Using level: \"%s\".\n",startupMap.GetChars()); } else { - initprintf("Level \"%s\" not found.\n",boardfilename); + initprintf("Level \"%s\" not found.\n",startupMap.GetChars()); boardfilename[0] = 0; } } + strncpy(boardfilename, startupMap, BMAX_PATH); } for (i=0; i Date: Wed, 11 Dec 2019 01:19:32 +0100 Subject: [PATCH 196/203] - this better uses currentLevel for consistency --- source/duke3d/src/screens.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index 7fa039dbb..71941ad22 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -959,10 +959,9 @@ void G_DisplayRest(int32_t smoothratio) if (textret == 0 && ud.overhead_on == 2) { const int32_t a = (ud.screen_size > 0) ? 147 : 179; - char const * levelname = mapList[ud.volume_number*MAXLEVELS + ud.level_number].DisplayName(); - if (G_HaveUserMap()) - levelname = boardfilename; - else if (!(G_GetLogoFlags() & LOGO_HIDEEPISODE)) + char const * levelname = currentLevel->DisplayName(); + + if (!Menu_HaveUserMap() && !(G_GetLogoFlags() & LOGO_HIDEEPISODE)) minitext(5, a+6, GStrings.localize(gVolumeNames[ud.volume_number]), 0, 2+8+16+256); minitext(5, a+6+6, levelname, 0, 2+8+16+256); } From 875678f20b39547b14690c23038730fce1f52a6d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 11 Dec 2019 02:01:11 +0100 Subject: [PATCH 197/203] - transitioned Shadow Warrior to the global mapinfo --- source/duke3d/src/gamedef.cpp | 8 +-- source/duke3d/src/screens.cpp | 8 +-- source/rr/src/gamedef.cpp | 8 +-- source/rr/src/screens.cpp | 8 +-- source/sw/src/game.cpp | 92 ++++++----------------------------- source/sw/src/game.h | 10 ---- source/sw/src/save.cpp | 5 -- source/sw/src/scrip2.cpp | 28 +++-------- source/sw/src/serp.cpp | 4 +- source/sw/src/sounds.cpp | 7 --- source/sw/src/sumo.cpp | 4 +- source/sw/src/zilla.cpp | 4 +- 12 files changed, 43 insertions(+), 143 deletions(-) diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index fd6134b90..1f2718dff 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -5177,8 +5177,8 @@ repeatcase: C_SkipComments(); mapList[j *MAXLEVELS+k].parTime = - (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*REALGAMETICSPERSEC*60)+ - (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*REALGAMETICSPERSEC); + (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*60)+ + (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))); textptr += 5; scriptSkipSpaces(); @@ -5187,8 +5187,8 @@ repeatcase: if (*(textptr+2) == ':') { mapList[j *MAXLEVELS+k].designerTime = - (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*REALGAMETICSPERSEC*60)+ - (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*REALGAMETICSPERSEC); + (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*60)+ + (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))); textptr += 5; scriptSkipSpaces(); diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index 71941ad22..8be60fbb5 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -1943,11 +1943,11 @@ static int32_t G_PrintTime_ClockPad(void) clockpad = max(clockpad, ij); if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - for (ii=currentLevel->parTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } + for (ii=currentLevel->parTime/(60), ij=1; ii>9; ii/=10, ij++) { } clockpad = max(clockpad, ij); if (!NAM_WW2GI && currentLevel->designerTime) { - for (ii= currentLevel->designerTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } + for (ii= currentLevel->designerTime/(60), ij=1; ii>9; ii/=10, ij++) { } clockpad = max(clockpad, ij); } } @@ -1976,13 +1976,13 @@ const char* G_PrintParTime(void) { if (ud.last_level < 1) return ""; - return G_PrintTime2(currentLevel->parTime); + return G_PrintTime2(currentLevel->parTime*REALGAMETICSPERSEC); } const char* G_PrintDesignerTime(void) { if (ud.last_level < 1) return ""; - return G_PrintTime2(currentLevel->designerTime); + return G_PrintTime2(currentLevel->designerTime*REALGAMETICSPERSEC); } const char* G_PrintBestTime(void) { diff --git a/source/rr/src/gamedef.cpp b/source/rr/src/gamedef.cpp index 6ca7bd465..219c23bac 100644 --- a/source/rr/src/gamedef.cpp +++ b/source/rr/src/gamedef.cpp @@ -1876,8 +1876,8 @@ static int32_t C_ParseCommand(int32_t loop) C_SkipComments(); mapList[j *MAXLEVELS+k].parTime = - (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*REALGAMETICSPERSEC*60)+ - (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*REALGAMETICSPERSEC); + (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*60)+ + (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))); textptr += 5; C_SkipSpace(); @@ -1886,8 +1886,8 @@ static int32_t C_ParseCommand(int32_t loop) if (*(textptr+2) == ':') { mapList[j *MAXLEVELS+k].designerTime = - (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*REALGAMETICSPERSEC*60)+ - (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*REALGAMETICSPERSEC); + (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*60)+ + (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))); textptr += 5; C_SkipSpace(); diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index a00d2d27c..462ac5da2 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -1967,11 +1967,11 @@ static int32_t G_PrintTime_ClockPad(void) clockpad = max(clockpad, ij); if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) { - for (ii=currentLevel->parTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } + for (ii=currentLevel->parTime/(60), ij=1; ii>9; ii/=10, ij++) { } clockpad = max(clockpad, ij); if (currentLevel->designerTime) { - for (ii=currentLevel->designerTime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { } + for (ii=currentLevel->designerTime/(60), ij=1; ii>9; ii/=10, ij++) { } clockpad = max(clockpad, ij); } } @@ -2000,13 +2000,13 @@ const char* G_PrintParTime(void) { if (ud.last_level < 1) return ""; - return G_PrintTime2(currentLevel->parTime); + return G_PrintTime2(currentLevel->parTime * REALGAMETICSPERSEC); } const char* G_PrintDesignerTime(void) { if (ud.last_level < 1) return ""; - return G_PrintTime2(currentLevel->designerTime); + return G_PrintTime2(currentLevel->designerTime*REALGAMETICSPERSEC); } const char* G_PrintBestTime(void) { diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 42314b735..bb1bf1209 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -99,6 +99,7 @@ Things required to make savegames work: #include "z_music.h" #include "statistics.h" #include "gstrings.h" +#include "mapinfo.h" //#include "crc32.h" @@ -177,7 +178,6 @@ extern SWBOOL GamePaused; short screenpeek = 0; SWBOOL NoDemoStartup = FALSE; SWBOOL FirstTimeIntoGame; -extern uint8_t RedBookSong[40]; SWBOOL BorderAdjust = FALSE; SWBOOL LocationInfo = 0; @@ -982,51 +982,6 @@ YOKOHA03 MID */ short SongLevelNum; -//#ifndef SW_SHAREWARE -LEVEL_INFO LevelInfo[MAX_LEVELS_REG+2] = -{ - {"title.map", "theme.mid", " ", " ", " " }, - {"$bullet.map", "e1l01.mid", "Seppuku Station", "0 : 55", "5 : 00" }, - {"$dozer.map", "e1l03.mid", "Zilla Construction", "4 : 59", "8 : 00" }, - {"$shrine.map", "e1l02.mid", "Master Leep's Temple", "3 : 16", "10 : 00" }, - {"$woods.map", "e1l04.mid", "Dark Woods of the Serpent", "7 : 06", "16 : 00" }, - {"$whirl.map", "yokoha03.mid", "Rising Son", "5 : 30", "10 : 00" }, - {"$tank.map", "nippon34.mid", "Killing Fields", "1 : 46", "4 : 00" }, - {"$boat.map", "execut11.mid", "Hara-Kiri Harbor", "1 : 56", "4 : 00" }, - {"$garden.map", "execut11.mid", "Zilla's Villa", "1 : 06", "2 : 00" }, - {"$outpost.map", "sanai.mid", "Monastery", "1 : 23", "3 : 00" }, - {"$hidtemp.map", "kotec2.mid", "Raider of the Lost Wang", "2 : 05", "4 : 10" }, - {"$plax1.map", "kotec2.mid", "Sumo Sky Palace", "6 : 32", "12 : 00" }, - {"$bath.map", "yokoha03.mid", "Bath House", "10 : 00", "10 : 00" }, - {"$airport.map", "nippon34.mid", "Unfriendly Skies", "2 : 59", "6 : 00" }, - {"$refiner.map", "kotoki12.mid", "Crude Oil", "2 : 40", "5 : 00" }, - {"$newmine.map", "hoshia02.mid", "Coolie Mines", "2 : 48", "6 : 00" }, - {"$subbase.map", "hoshia02.mid", "Subpen 7", "2 : 02", "4 : 00" }, - {"$rock.map", "kotoki12.mid", "The Great Escape", "3 : 18", "6 : 00" }, - {"$yamato.map", "sanai.mid", "Floating Fortress", "11 : 38", "20 : 00" }, - {"$seabase.map", "kotec2.mid", "Water Torture", "5 : 07", "10 : 00" }, - {"$volcano.map", "kotec2.mid", "Stone Rain", "9 : 15", "20 : 00" }, - {"$shore.map", "kotec2.mid", "Shanghai Shipwreck", "3 : 58", "8 : 00" }, - {"$auto.map", "kotec2.mid", "Auto Maul", "4 : 07", "8 : 00" }, - {"tank.map", "kotec2.mid", "Heavy Metal (DM only)", "10 : 00", "10 : 00" }, - {"$dmwoods.map", "kotec2.mid", "Ripper Valley (DM only)", "10 : 00", "10 : 00" }, - {"$dmshrin.map", "kotec2.mid", "House of Wang (DM only)", "10 : 00", "10 : 00" }, - {"$rush.map", "kotec2.mid", "Lo Wang Rally (DM only)", "10 : 00", "10 : 00" }, - {"shotgun.map", "kotec2.mid", "Ruins of the Ronin (CTF)", "10 : 00", "10 : 00" }, - {"$dmdrop.map", "kotec2.mid", "Killing Fields (CTF)", "10 : 00", "10 : 00" }, - {NULL, NULL, NULL, NULL, NULL} -}; -/*#else -LEVEL_INFO LevelInfo[MAX_LEVELS+2] = // Shareware - { - {"title.map", "theme.mid", " ", " ", " " }, - {"$bullet.map", "e1l01.mid", "Seppuku Station", "0 : 55", "5 : 00" }, - {"$dozer.map", "e1l03.mid", "Zilla Construction", "4 : 59", "8 : 00" }, - {"$shrine.map", "e1l02.mid", "Master Leep's Temple", "3 : 16", "10 : 00" }, - {"$woods.map", "e1l04.mid", "Dark Woods of the Serpent", "7 : 06", "16 : 00" }, - {NULL, NULL, NULL, NULL, NULL} - }; -#endif*/ FString ThemeSongs[6]; int ThemeTrack[6]; @@ -1060,13 +1015,10 @@ void FindLevelInfo(char *map_name, short *level) for (j = 1; j <= MAX_LEVELS; j++) { - if (LevelInfo[j].LevelName) + if (Bstrcasecmp(map_name, mapList[j].fileName.GetChars()) == 0) { - if (Bstrcasecmp(map_name, LevelInfo[j].LevelName) == 0) - { - *level = j; - return; - } + *level = j; + return; } } @@ -1156,7 +1108,7 @@ InitLevel(void) FindLevelInfo(LevelName, &Level); if (Level > 0) { - strcpy(LevelName, LevelInfo[Level].LevelName); + strcpy(LevelName, mapList[Level].fileName); UserMapName[0] = '\0'; } else @@ -1194,13 +1146,13 @@ InitLevel(void) if (Level > 0) { // user map is part of game - treat it as such - strcpy(LevelName, LevelInfo[Level].LevelName); + strcpy(LevelName, mapList[Level].fileName); UserMapName[0] = '\0'; } } else { - strcpy(LevelName, LevelInfo[Level].LevelName); + strcpy(LevelName, mapList[Level].fileName); } } @@ -2021,11 +1973,7 @@ void LoadingLevelScreen(char *level_name) MNU_MeasureString(ds, &w, &h); MNU_DrawString(TEXT_TEST_COL(w), 170, ds,1,16); - if (UserMapName[0]) - sprintf(ds,"%s",UserMapName); - else - sprintf(ds,"%s",LevelInfo[Level].Description); - + auto ds = currentLevel->DisplayName(); MNU_MeasureString(ds, &w, &h); MNU_DrawString(TEXT_TEST_COL(w), 180, ds,1,16); @@ -2259,7 +2207,7 @@ void BonusScreen(PLAYERp pp) { if (PlayingLevel <= 1) PlayingLevel = 1; - sprintf(ds,"%s",LevelInfo[PlayingLevel].Description); + auto ds = currentLevel->DisplayName(); MNU_MeasureString(ds, &w, &h); MNU_DrawString(TEXT_TEST_COL(w), 20, ds,1,19); } @@ -2283,12 +2231,12 @@ void BonusScreen(PLAYERp pp) if (!UserMapName[0]) { line++; - sprintf(ds,"3D Realms Best Time: %s", LevelInfo[PlayingLevel].BestTime); + sprintf(ds,"3D Realms Best Time: %d:%02d", currentLevel->designerTime/60, currentLevel->designerTime%60); MNU_MeasureString(ds, &w, &h); MNU_DrawString(40, BONUS_LINE(line), ds,1,16); line++; - sprintf(ds,"Par Time: %s", LevelInfo[PlayingLevel].ParTime); + sprintf(ds,"Par Time: %d:%02d", currentLevel->parTime/ 60, currentLevel->parTime%60); MNU_MeasureString(ds, &w, &h); MNU_DrawString(40, BONUS_LINE(line), ds,1,16); } @@ -2774,16 +2722,14 @@ void InitRunLevel(void) InitNetVars(); { - int track; if (Level == 0) { - track = RedBookSong[4+RANDOM_RANGE(10)]; + PlaySong(nullptr, currentLevel->music, 1 + RANDOM_RANGE(10)); } else { - track = RedBookSong[Level]; + PlaySong(currentLevel->labelName, currentLevel->music, currentLevel->cdSongId); } - PlaySong(LevelInfo[Level].LevelName, LevelInfo[Level].SongName, track); } InitPrediction(&Player[myconnectindex]); @@ -2980,13 +2926,6 @@ int32_t GameInterface::app_main() else buildputs("Detected registered GRP\n"); } - if (SW_SHAREWARE) - { - // Zero out the maps that aren't in shareware version - memset(&LevelInfo[MAX_LEVELS_SW+1], 0, sizeof(LEVEL_INFO)*(MAX_LEVELS_REG-MAX_LEVELS_SW)); - GameVersion++; - } - for (i = 0; i < MAX_SW_PLAYERS; i++) INITLIST(&Player[i].PanelSpriteList); @@ -3894,10 +3833,7 @@ void drawoverheadmap(int cposx, int cposy, int czoom, short cang) minigametext(txt_x,txt_y-7,"Follow Mode",0,2+8); } - if (UserMapName[0]) - sprintf(ds,"%s",UserMapName); - else - sprintf(ds,"%s",LevelInfo[Level].Description); + sprintf(ds,"%s",currentLevel->DisplayName()); minigametext(txt_x,txt_y,ds,0,2+8); diff --git a/source/sw/src/game.h b/source/sw/src/game.h index dc79cf0f9..e27bffb0d 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -942,16 +942,6 @@ typedef struct #define MAX_LEVELS_SW 4 #define MAX_LEVELS (isShareware ? MAX_LEVELS_SW : MAX_LEVELS_REG) -typedef struct -{ - const char *LevelName; - const char *SongName; - const char *Description; - const char *BestTime; - const char *ParTime; -} LEVEL_INFO, *LEVEL_INFOp, * *LEVEL_INFOpp; - -extern LEVEL_INFO LevelInfo[MAX_LEVELS_REG+2]; extern int ThemeTrack[6]; // w extern FString ThemeSongs[6]; // diff --git a/source/sw/src/save.cpp b/source/sw/src/save.cpp index 466d08026..d4ec3501f 100644 --- a/source/sw/src/save.cpp +++ b/source/sw/src/save.cpp @@ -75,7 +75,6 @@ TO DO */ extern int lastUpdate; -extern uint8_t RedBookSong[40]; extern char UserMapName[80]; extern char SaveGameDescr[10][80]; extern int PlayClock; @@ -252,10 +251,6 @@ bool GameInterface::SaveGame(FSaveGameNode *sv) auto game_name = G_BuildSaveName(sv->Filename); OpenSaveGameForWrite(game_name); // workaround until the level info here has been transitioned. - MapRecord mr; - mr.SetFileName(LevelInfo[Level].Description); - mr.labelName = LevelInfo[Level].Description; - currentLevel = &mr; G_WriteSaveHeader(sv->SaveTitle); fil = WriteSavegameChunk("snapshot.sw"); diff --git a/source/sw/src/scrip2.cpp b/source/sw/src/scrip2.cpp index fa18faa62..c98ce0b2c 100644 --- a/source/sw/src/scrip2.cpp +++ b/source/sw/src/scrip2.cpp @@ -41,6 +41,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "scriptfile.h" #include "menu/menu.h" #include "quotemgr.h" +#include "mapinfo.h" BEGIN_SW_NS @@ -506,7 +507,6 @@ static int cm_transtok(const char *tok, const struct _tokset *set, const unsigne return -1; } -static LEVEL_INFO custommaps[MAX_LEVELS_REG]; #define WM_DAMAGE 1 #define WM_WEAP 2 @@ -575,7 +575,7 @@ void LoadCustomInfoFromScript(const char *filename) mapnumptr = script->ltextptr; if (scriptfile_getbraces(script, &braceend)) break; - // first map file in LevelInfo[] is bogus, last map file is NULL + // first map entry may not be used, max. amount needs investigation if (curmap < 1 || curmap > MAX_LEVELS_REG) { initprintf("Error: map number %d not in range 1-%d on line %s:%d\n", @@ -596,9 +596,7 @@ void LoadCustomInfoFromScript(const char *filename) char *t; if (scriptfile_getstring(script, &t)) break; - //Bfree(custommaps[curmap].LevelName); - custommaps[curmap].LevelName = strdup(t); - LevelInfo[curmap].LevelName = custommaps[curmap].LevelName; + mapList[curmap].SetFileName(t); break; } case CM_SONG: @@ -606,9 +604,7 @@ void LoadCustomInfoFromScript(const char *filename) char *t; if (scriptfile_getstring(script, &t)) break; - //Bfree(custommaps[curmap].SongName); - custommaps[curmap].SongName = strdup(t); - LevelInfo[curmap].SongName = custommaps[curmap].SongName; + mapList[curmap].music = t; break; } case CM_TITLE: @@ -616,9 +612,7 @@ void LoadCustomInfoFromScript(const char *filename) char *t; if (scriptfile_getstring(script, &t)) break; - //Bfree(custommaps[curmap].Description); - custommaps[curmap].Description = strdup(t); - LevelInfo[curmap].Description = custommaps[curmap].Description; + mapList[curmap].SetName(t); break; } case CM_BESTTIME: @@ -627,10 +621,7 @@ void LoadCustomInfoFromScript(const char *filename) char s[10]; if (scriptfile_getnumber(script, &n)) break; - Bsnprintf(s, 10, "%d : %02d", n/60, n%60); - //Bfree(custommaps[curmap].BestTime); - custommaps[curmap].BestTime = strdup(s); - LevelInfo[curmap].BestTime = custommaps[curmap].BestTime; + mapList[curmap].designerTime = (int)strtoll(s, nullptr, 0); break; } case CM_PARTIME: @@ -639,10 +630,7 @@ void LoadCustomInfoFromScript(const char *filename) char s[10]; if (scriptfile_getnumber(script, &n)) break; - Bsnprintf(s, 10, "%d : %02d", n/60, n%60); - //Bfree(custommaps[curmap].ParTime); - custommaps[curmap].ParTime = strdup(s); - LevelInfo[curmap].ParTime = custommaps[curmap].ParTime; + mapList[curmap].parTime = (int)strtoll(s, nullptr, 0); break; } case CM_CDATRACK: @@ -668,7 +656,6 @@ void LoadCustomInfoFromScript(const char *filename) epnumptr = script->ltextptr; if (scriptfile_getbraces(script, &braceend)) break; - // first map file in LevelInfo[] is bogus, last map file is NULL if ((unsigned)--curmap >= 2u) { initprintf("Error: episode number %d not in range 1-2 on line %s:%d\n", @@ -715,7 +702,6 @@ void LoadCustomInfoFromScript(const char *filename) epnumptr = script->ltextptr; if (scriptfile_getbraces(script, &braceend)) break; - // first map file in LevelInfo[] is bogus, last map file is NULL if ((unsigned)--curmap >= 4u) { initprintf("Error: skill number %d not in range 1-4 on line %s:%d\n", diff --git a/source/sw/src/serp.cpp b/source/sw/src/serp.cpp index 84f810f23..04d0649f8 100644 --- a/source/sw/src/serp.cpp +++ b/source/sw/src/serp.cpp @@ -35,10 +35,10 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "track.h" #include "sector.h" #include "gamecontrol.h" +#include "mapinfo.h" BEGIN_SW_NS -extern uint8_t RedBookSong[40]; extern short BossSpriteNum[3]; DECISION SerpBattle[] = @@ -821,7 +821,7 @@ int DoDeathSpecial(short SpriteNum) if (!SW_SHAREWARE) { // Resume the regular music - in a hack-free fashion. - PlaySong(LevelInfo[Level].LevelName, LevelInfo[Level].SongName, RedBookSong[Level]); + PlaySong(currentLevel->labelName, currentLevel->music, currentLevel->cdSongId); } BossSpriteNum[0] = -2; diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp index 580c3008a..95d534544 100644 --- a/source/sw/src/sounds.cpp +++ b/source/sw/src/sounds.cpp @@ -72,13 +72,6 @@ int PLocked_Sounds[] = 558,557 }; -uint8_t RedBookSong[40] = -{ - 2,4,9,12,10, // Title and ShareWare levels - 5,6,8,11,12,5,10,4,6,9,7,10,8,7,9,10,11,5, // Registered levels - 11,8,7,13,5,6, // Deathmatch levels - 13 // Fight boss -}; // Global vars used by ambient sounds to set spritenum of ambient sounds for later lookups in // the sprite array so FAFcansee can know the sound sprite's current sector location diff --git a/source/sw/src/sumo.cpp b/source/sw/src/sumo.cpp index dab78c9c2..565c71312 100644 --- a/source/sw/src/sumo.cpp +++ b/source/sw/src/sumo.cpp @@ -38,10 +38,10 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "weapon.h" #include "sector.h" #include "gamecontrol.h" +#include "mapinfo.h" BEGIN_SW_NS -extern uint8_t RedBookSong[40]; extern uint8_t playTrack; SWBOOL serpwasseen = FALSE; SWBOOL sumowasseen = FALSE; @@ -805,7 +805,7 @@ int DoSumoDeathMelt(short SpriteNum) if (!SW_SHAREWARE) { // Resume the regular music - in a hack-free fashion. - PlaySong(LevelInfo[Level].LevelName, LevelInfo[Level].SongName, RedBookSong[Level]); + PlaySong(currentLevel->labelName, currentLevel->music, currentLevel->cdSongId); } BossSpriteNum[1] = -2; // Sprite is gone, set it back to keep it valid! diff --git a/source/sw/src/zilla.cpp b/source/sw/src/zilla.cpp index fc1fb8dbc..6193c911b 100644 --- a/source/sw/src/zilla.cpp +++ b/source/sw/src/zilla.cpp @@ -37,10 +37,10 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "track.h" #include "fx_man.h" #include "gamecontrol.h" +#include "mapinfo.h" BEGIN_SW_NS -extern uint8_t RedBookSong[40]; extern short BossSpriteNum[3]; ANIMATOR InitZillaCharge; @@ -780,7 +780,7 @@ int DoZillaDeathMelt(short SpriteNum) if (!SW_SHAREWARE) { // Resume the regular music - in a hack-free fashion. - PlaySong(LevelInfo[Level].LevelName, LevelInfo[Level].SongName, RedBookSong[Level]); + PlaySong(currentLevel->labelName, currentLevel->music, currentLevel->cdSongId); } //KeepActorOnFloor(SpriteNum); From 3f524d70266d1a8fe43908970780005e8f8142b9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 11 Dec 2019 02:30:34 +0100 Subject: [PATCH 198/203] - set currentLevel in SW --- source/sw/src/game.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index bb1bf1209..896fe2e55 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -654,7 +654,8 @@ bool LoadLevel(const char *filename) Printf("Level not found: %s", filename); return false; } - STAT_NewLevel(filename); + currentLevel = &mapList[Level]; + STAT_NewLevel(currentLevel->labelName); return true; } From 95625567e04a87d1c77e8acbf6c2133113071a13 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 11 Dec 2019 18:40:42 +0100 Subject: [PATCH 199/203] - fixed compile errors. --- source/duke3d/src/demo.cpp | 3 +-- source/duke3d/src/game.cpp | 2 ++ source/duke3d/src/savegame.cpp | 4 ++-- source/duke3d/src/savegame.h | 2 +- source/rr/src/demo.cpp | 3 +-- source/rr/src/savegame.cpp | 4 ++-- source/rr/src/savegame.h | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/source/duke3d/src/demo.cpp b/source/duke3d/src/demo.cpp index 4326d711a..7025715ce 100644 --- a/source/duke3d/src/demo.cpp +++ b/source/duke3d/src/demo.cpp @@ -172,8 +172,7 @@ void G_OpenDemoWrite(void) if (g_demo_filePtr == NULL) return; - i=sv_saveandmakesnapshot(*g_demo_filePtr, nullptr, -1, demorec_diffs_cvar, demorec_diffcompress_cvar, - (demorec_seeds_cvar<<1)); + i=sv_saveandmakesnapshot(*g_demo_filePtr, nullptr, -1); if (i) { delete g_demo_filePtr; diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 759310fda..644425f06 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -79,6 +79,8 @@ int32_t g_quitDeadline = 0; int32_t g_cameraDistance = 0, g_cameraClock = 0; static int32_t g_quickExit; +char boardfilename[BMAX_PATH]; + int32_t voting = -1; int32_t vote_map = -1, vote_episode = -1; diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index b0dd65d68..9c62f961a 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -567,7 +567,7 @@ bool G_SavePlayer(FSaveGameNode *sv) portableBackupSave(sv->Filename, sv->SaveTitle, ud.last_stateless_volume, ud.last_stateless_level); // SAVE! - sv_saveandmakesnapshot(fw, sv->SaveTitle, 0, 0, 0, 0); + sv_saveandmakesnapshot(fw, sv->SaveTitle, 0); fw.Close(); @@ -1368,7 +1368,7 @@ static void SV_AllocSnap(int32_t allocinit) } // make snapshot only if spot < 0 (demo) -int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp) +int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot) { savehead_t h; diff --git a/source/duke3d/src/savegame.h b/source/duke3d/src/savegame.h index 3b7bddded..08f8d7213 100644 --- a/source/duke3d/src/savegame.h +++ b/source/duke3d/src/savegame.h @@ -68,7 +68,7 @@ int32_t sv_readdiff(FileReader& fil); uint32_t sv_writediff(FileWriter *fil); int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h); int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h); -int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp); +int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot); void sv_freemem(); int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh); void ReadSaveGameHeaders(void); diff --git a/source/rr/src/demo.cpp b/source/rr/src/demo.cpp index 50aef49a1..8dd553223 100644 --- a/source/rr/src/demo.cpp +++ b/source/rr/src/demo.cpp @@ -172,8 +172,7 @@ void G_OpenDemoWrite(void) if (g_demo_filePtr == NULL) return; - i=sv_saveandmakesnapshot(*g_demo_filePtr, nullptr, -1, demorec_diffs_cvar, demorec_diffcompress_cvar, - (demorec_seeds_cvar<<1)); + i=sv_saveandmakesnapshot(*g_demo_filePtr, nullptr, -1, (demorec_seeds_cvar<<1)); if (i) { delete g_demo_filePtr; diff --git a/source/rr/src/savegame.cpp b/source/rr/src/savegame.cpp index 45959408c..4059ca312 100644 --- a/source/rr/src/savegame.cpp +++ b/source/rr/src/savegame.cpp @@ -313,7 +313,7 @@ bool G_SavePlayer(FSaveGameNode *sv) // SAVE! - sv_saveandmakesnapshot(fw, sv->SaveTitle, 0, 0, 0, 0); + sv_saveandmakesnapshot(fw, sv->SaveTitle, 0, 0); fw.Close(); @@ -1073,7 +1073,7 @@ static void SV_AllocSnap(int32_t allocinit) } // make snapshot only if spot < 0 (demo) -int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, bool isAutoSave) +int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, bool isAutoSave) { savehead_t h; diff --git a/source/rr/src/savegame.h b/source/rr/src/savegame.h index ab205105d..9feb8950e 100644 --- a/source/rr/src/savegame.h +++ b/source/rr/src/savegame.h @@ -59,7 +59,7 @@ int32_t sv_readdiff(FileReader& fil); uint32_t sv_writediff(FileWriter *fil); int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h); int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h); -int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, bool isAutoSave = false); +int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, bool isAutoSave = false); void sv_freemem(); int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh); void ReadSaveGameHeaders(void); From ae0687a300cd79fa29d7cb87452eae7da4413a5d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 11 Dec 2019 19:36:38 +0100 Subject: [PATCH 200/203] - exported level strings from Blood and Shadow Warrior to the string table. --- wadsrc/static/demolition/language.csv | 289 +++++++++++++++--- .../filter/shadowwarrior.wanton/SWCustom.txt | 143 ++------- .../shadowwarrior/demolition/SWCustom.txt | 72 ++--- 3 files changed, 293 insertions(+), 211 deletions(-) diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index b85d6e8cd..f8e853a5c 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -1582,7 +1582,7 @@ fans for giving,fans for giving,,,,,unsere Fans für,,,,,,,,,,,,,,,,, us big heads.,us big heads.,,,,,ihre Unterstützung.,,,,,,,,,,,,,,,,, Look for a Duke Nukem 3D,Look for a Duke Nukem 3D,,,,,Haltet bald Ausschau nach,,,,,,,,,,,,,,,,, sequel soon.,sequel soon.,,,,,dem Duke Nukem 3D Sequel,,,,,,,,,,,,,,,,, -Press any key or button to continue,Presskey,,,,,Drüclke eine Taste um fortzufahren.,,,,,,,,,,,,,,,,, +Press any key to continue,Presskey,,,,,Drüclke eine Taste um fortzufahren.,,,,,,,,,,,,,,,,, Kills,Kills,,,,Zabití,,,Mortigoj,Asesinatos,,Tapot,Victimes,Ölések,Uccisioni,キル,킬수,Doodt,Zabójstwa,Vítimas,,,Убийства,Убиства Completed,Completed,,,,Dokončen,Abgeschlossen,,Finita,Completado,,Suoritettu,terminé,Teljesítve,Finito,攻略,완료,Klaar,Ukończono,Finalizado,,,Уровень завершён,Ниво завршен Your Time:,TXT_YOURTIME,,,,,Deine Zeit:,,,,,,,,,,,,,,,,, @@ -1766,16 +1766,125 @@ You're fired!,TXTB_FIRED,,,,,,,,,,,,,,,,,,,,,, Ahhh...those were the days.,TXTB_THEDAYS,,,,,,,,,,,,,,,,,,,,,, Flame retardant!,TXTB_RETARD,,,,,,,,,,,,,,,,,,,,,, You have half armor.,TXTB_HALFARMOR,,,,,,,,,,,,,,,,,,,,,, +,Blood levels and messages,,,,,,,,,,,,,,,,,,,,,, +The Way of All Flesh,The Way of All Flesh,,Blood,,,,,,,,,,,,,,,,,,,, +Even Death May Die,Even Death May Die,,Blood,,,,,,,,,,,,,,,,,,,, +Farewell to Arms,Farewell to Arms,,Blood,,,,,,,,,,,,,,,,,,,, +Dead Reckoning,Dead Reckoning,,Blood,,,,,,,,,,,,,,,,,,,, +BloodBath,BloodBath,,Blood,,,,,,,,,,,,,,,,,,,, +Post Mortem,Post Mortem,,Blood,,,,,,,,,,,,,,,,,,,, +Cradle to Grave,Cradle to Grave,,Blood,,,,,,,,,,,,,,,,,,,, +Hit the switch to end the level.,Hit the switch to end the level.,,Blood,,,,,,,,,,,,,,,,,,,, +"Slurp, slurp . . .","Slurp, slurp . . .",,Blood,,,,,,,,,,,,,,,,,,,, +OUT! OUT! DAMN SPOT!,OUT! OUT! DAMN SPOT!,,Blood,,,,,,,,,,,,,,,,,,,, +They'll need more of these.,They'll need more of these.,,Blood,,,,,,,,,,,,,,,,,,,, +Nevermore . . .,Nevermore . . .,,Blood,,,,,,,,,,,,,,,,,,,, +Open for Business.,Open for Business.,,Blood,,,,,,,,,,,,,,,,,,,, +I LIVE AGAIN!,I LIVE AGAIN!,,Blood,,,,,,,,,,,,,,,,,,,, +It is sealed shut.,It is sealed shut.,,Blood,,,,,,,,,,,,,,,,,,,, +Wrong Side of the Tracks,Wrong Side of the Tracks,,Blood,,,,,,,,,,,,,,,,,,,, +This probably isn't a good idea.,This probably isn't a good idea.,,Blood,,,,,,,,,,,,,,,,,,,, +You really should consider turning back.,You really should consider turning back.,,Blood,,,,,,,,,,,,,,,,,,,, +Is there a light at the end of the tunnel?,Is there a light at the end of the tunnel?,,Blood,,,,,,,,,,,,,,,,,,,, +Phantom Express,Phantom Express,,Blood,,,,,,,,,,,,,,,,,,,, +I must stop this train!,I must stop this train!,,Blood,,,,,,,,,,,,,,,,,,,, +Safety clamps are in place. This switch is locked.,Safety clamps are in place. This switch is locked.,,Blood,,,,,,,,,,,,,,,,,,,, +Safety clamps disabled.,Safety clamps disabled.,,Blood,,,,,,,,,,,,,,,,,,,, +Internal engine heat rising!,Internal engine heat rising!,,Blood,,,,,,,,,,,,,,,,,,,, +Internal engine heat critical!,Internal engine heat critical!,,Blood,,,,,,,,,,,,,,,,,,,, +Dark Carnival,Dark Carnival,,Blood,,,,,,,,,,,,,,,,,,,, +This doesn't open from this side.,This doesn't open from this side.,,Blood,,,,,,,,,,,,,,,,,,,, +Hit the switch to end the level.,Hit the switch to end the level.,,Blood,,,,,,,,,,,,,,,,,,,, +You're going to the secret level!,You're going to the secret level!,,Blood,,,,,,,,,,,,,,,,,,,, +Congrats! You win a cupie doll!,Congrats! You win a cupie doll!,,Blood,,,,,,,,,,,,,,,,,,,, +Hallowed Grounds,Hallowed Grounds,,Blood,,,,,,,,,,,,,,,,,,,, +The Great Temple,The Great Temple,,Blood,,,,,,,,,,,,,,,,,,,, +I can't believe you found this!,I can't believe you found this!,,Blood,,,,,,,,,,,,,,,,,,,, +"Here, you can have it all.","Here, you can have it all.",,Blood,,,,,,,,,,,,,,,,,,,, +Altar of Stone,Altar of Stone,,Blood,,,,,,,,,,,,,,,,,,,, +House of Horrors,House of Horrors,,Blood,,,,,,,,,,,,,,,,,,,, +Shipwrecked,Shipwrecked,,Blood,,,,,,,,,,,,,,,,,,,, +The door is jammed shut.,The door is jammed shut.,,Blood,,,,,,,,,,,,,,,,,,,, +The Lumber Mill,The Lumber Mill,,Blood,,,,,,,,,,,,,,,,,,,, +Rest for the Wicked,Rest for the Wicked,,Blood,,,,,,,,,,,,,,,,,,,, +You hear hedges rustling nearby.,You hear hedges rustling nearby.,,Blood,,,,,,,,,,,,,,,,,,,, +The Overlooked Hotel,The Overlooked Hotel,,Blood,,,,,,,,,,,,,,,,,,,, +The secret level lies before you.,The secret level lies before you.,,Blood,,,,,,,,,,,,,,,,,,,, +The Haunting,The Haunting,,Blood,,,,,,,,,,,,,,,,,,,, +The Cold Rush,The Cold Rush,,Blood,,,,,,,,,,,,,,,,,,,, +Bowels of the Earth,Bowels of the Earth,,Blood,,,,,,,,,,,,,,,,,,,, +The Lair of Shial,The Lair of Shial,,Blood,,,,,,,,,,,,,,,,,,,, +Thin Ice,Thin Ice,,Blood,,,,,,,,,,,,,,,,,,,, +Ghost Town,Ghost Town,,Blood,,,,,,,,,,,,,,,,,,,, +The Siege,The Siege,,Blood,,,,,,,,,,,,,,,,,,,, +Raw Sewage,Raw Sewage,,Blood,,,,,,,,,,,,,,,,,,,, +The Sick Ward,The Sick Ward,,Blood,,,,,,,,,,,,,,,,,,,, +Spare Parts,Spare Parts,,Blood,,,,,,,,,,,,,,,,,,,, +Failsafes disabled.,Failsafes disabled.,,Blood,,,,,,,,,,,,,,,,,,,, +Disable failsafes first.,Disable failsafes first.,,Blood,,,,,,,,,,,,,,,,,,,, +Monster Bait,Monster Bait,,Blood,,,,,,,,,,,,,,,,,,,, +The Pit of Cerberus,The Pit of Cerberus,,Blood,,,,,,,,,,,,,,,,,,,, +Catacombs,Catacombs,,Blood,,,,,,,,,,,,,,,,,,,, +Butchery Loves Company,Butchery Loves Company,,Blood,,,,,,,,,,,,,,,,,,,, +Breeding Grounds,Breeding Grounds,,Blood,,,,,,,,,,,,,,,,,,,, +Charnel House,Charnel House,,Blood,,,,,,,,,,,,,,,,,,,, +Crystal Lake,Crystal Lake,,Blood,,,,,,,,,,,,,,,,,,,, +Fire and Brimstone,Fire and Brimstone,,Blood,,,,,,,,,,,,,,,,,,,, +The Ganglion Depths,The Ganglion Depths,,Blood,,,,,,,,,,,,,,,,,,,, +In the Flesh,In the Flesh,,Blood,,,,,,,,,,,,,,,,,,,, +The Hall of the Epiphany,The Hall of the Epiphany,,Blood,,,,,,,,,,,,,,,,,,,, +Mall of the Dead,Mall of the Dead,,Blood,,,,,,,,,,,,,,,,,,,, +The Stronghold,The Stronghold,,Blood,,,,,,,,,,,,,,,,,,,, +Winter Wonderland,Winter Wonderland,,Blood,,,,,,,,,,,,,,,,,,,, +Bodies,Bodies,,Blood,,,,,,,,,,,,,,,,,,,, +The Tower,The Tower,,Blood,,,,,,,,,,,,,,,,,,,, +Click!,Click!,,Blood,,,,,,,,,,,,,,,,,,,, +Twin Fortress,Twin Fortress,,Blood,,,,,,,,,,,,,,,,,,,, +Midgard,Midgard,,Blood,,,,,,,,,,,,,,,,,,,, +Fun With Heads,Fun With Heads,,Blood,,,,,,,,,,,,,,,,,,,, +Monolith Building 11,Monolith Building 11,,Blood,,,,,,,,,,,,,,,,,,,, +Power!,Power!,,Blood,,,,,,,,,,,,,,,,,,,, +Area 15,Area 15,,Blood,,,,,,,,,,,,,,,,,,,, +Welcome to Your Life,Welcome to Your Life,,Blood,,,,,,,,,,,,,,,,,,,, +They Are Here,They Are Here,,Blood,,,,,,,,,,,,,,,,,,,, +Public Storage,Public Storage,,Blood,,,,,,,,,,,,,,,,,,,, +Aqueducts,Aqueducts,,Blood,,,,,,,,,,,,,,,,,,,, +Power restored.,Power restored.,,Blood,,,,,,,,,,,,,,,,,,,, +The Ruined Temple,The Ruined Temple,,Blood,,,,,,,,,,,,,,,,,,,, +Forbidden Rituals,Forbidden Rituals,,Blood,,,,,,,,,,,,,,,,,,,, +The Dungeon,The Dungeon,,Blood,,,,,,,,,,,,,,,,,,,, +You must complete the sequence to open this door.,You must complete the sequence to open this door.,,Blood,,,,,,,,,,,,,,,,,,,, +Part one of three in the sequence has been completed.,Part one of three in the sequence has been completed.,,Blood,,,,,,,,,,,,,,,,,,,, +Part two of three in the sequence has been completed.,Part two of three in the sequence has been completed.,,Blood,,,,,,,,,,,,,,,,,,,, +Final part completed. A door has opened.,Final part completed. A door has opened.,,Blood,,,,,,,,,,,,,,,,,,,, +Beauty and the Beast,Beauty and the Beast,,Blood,,,,,,,,,,,,,,,,,,,, +Forgotten Catacombs,Forgotten Catacombs,,Blood,,,,,,,,,,,,,,,,,,,, +Cryptic Passage,Cryptic Passage,,Blood,,,,,,,,,,,,,,,,,,,, +Cryptic BloodBath,Cryptic BloodBath,,Blood,,,,,,,,,,,,,,,,,,,, +Boat Docks,Boat Docks,,Blood,,,,,,,,,,,,,,,,,,,, +Old Opera House,Old Opera House,,Blood,,,,,,,,,,,,,,,,,,,, +Gothic Library,Gothic Library,,Blood,,,,,,,,,,,,,,,,,,,, +Lost Monastery,Lost Monastery,,Blood,,,,,,,,,,,,,,,,,,,, +Steamboat,Steamboat,,Blood,,,,,,,,,,,,,,,,,,,, +Graveyard,Graveyard,,Blood,,,,,,,,,,,,,,,,,,,, +Mountain Pass,Mountain Pass,,Blood,,,,,,,,,,,,,,,,,,,, +Abysmal Mine,Abysmal Mine,,Blood,,,,,,,,,,,,,,,,,,,, +Castle,Castle,,Blood,,,,,,,,,,,,,,,,,,,, +Boggy Creek,Boggy Creek,,Blood,,,,,,,,,,,,,,,,,,,, +Crypt of Despair,Crypt of Despair,,Blood,,,,,,,,,,,,,,,,,,,, +Pits of Blood,Pits of Blood,,Blood,,,,,,,,,,,,,,,,,,,, +Unholy Cathedral,Unholy Cathedral,,Blood,,,,,,,,,,,,,,,,,,,, +Deadly Inspirations,Deadly Inspirations,,Blood,,,,,,,,,,,,,,,,,,,, ,Shadow Warrior,,,,,,,,,,,,,,,,,,,,,, -TXTS_EP1,Enter the Wang,,,,,,,,,,,,,,,,,,,,,, -"TXTS_EP2 -",Code of Honor,,,,,,,,,,,,,,,,,,,,,, -TXTS_EPD1,Four levels (Shareware Version),,,,,,,,,,,,,,,,,,,,,, -TXTS_EPD2,Eighteen levels (Full Version Only),,,,,,,,,,,,,,,,,,,,,, -TXTS_SK1,Tiny grasshopper,,,,,,,,,,,,,,,,,,,,,, -TXTS_SK2,I Have No Fear,,,,,,,,,,,,,,,,,,,,,, -TXTS_SK3,Who Wants Wang,,,,,,,,,,,,,,,,,,,,,, -TXTS_SK4,"No Pain, No Gain",,,,,,,,,,,,,,,,,,,,,, +Enter the Wang,TXTS_EP1,,,,,,,,,,,,,,,,,,,,,, +Code of Honor,"TXTS_EP2 +",,,,,,,,,,,,,,,,,,,,,, +Four levels (Shareware Version),TXTS_EPD1,,,,,,,,,,,,,,,,,,,,,, +Eighteen levels (Full Version Only),TXTS_EPD2,,,,,,,,,,,,,,,,,,,,,, +Tiny grasshopper,TXTS_SK1,,,,,,,,,,,,,,,,,,,,,, +I Have No Fear,TXTS_SK2,,,,,,,,,,,,,,,,,,,,,, +Who Wants Wang,TXTS_SK3,,,,,,,,,,,,,,,,,,,,,, +"No Pain, No Gain",TXTS_SK4,,,,,,,,,,,,,,,,,,,,,, Got the RED key!,TXTS_KEY1,,,,,,,,,,,,,,,,,,,,,, Got the BLUE key!,TXTS_KEY2,,,,,,,,,,,,,,,,,,,,,, Got the GREEN key!,TXTS_KEY3,,,,,,,,,,,,,,,,,,,,,, @@ -1882,43 +1991,123 @@ Press SPACE to restart,TXTS_PRESSSPACER,,,,,,,,,,,,,,,,,,,,,, %k puts the Smack Dab on %p with the %z.,TXTS_MPOBIT16,,,,,,,,,,,,,,,,,,,,,, This only opens in single play.,TXTS_SPONLY,,,,,,,,,,,,,,,,,,,,,, You found a secret area!,TXTS_SECRET,,,,,,,,,,,,,,,,,,,,,, -Zombie,Zombie,,,,,,,,,,,,,,,,,,,,,, -Blood Worm,Blood Worm,,,,,,,,,,,,,,,,,,,,,, -Skeletor Priest,Skeletor Priest,,,,,,,,,,,,,,,,,,,,,, -Coolie Ghost,Coolie Ghost,,,,,,,,,,,,,,,,,,,,,, -Guardian,Guardian,,,,,,,,,,,,,,,,,,,,,, -Hornet,Hornet,,,,,,,,,,,,,,,,,,,,,, -Ripper Hatchling,Ripper Hatchling,,,,,,,,,,,,,,,,,,,,,, -Ripper,Ripper,,,,,,,,,,,,,,,,,,,,,, -Killer Rabbit,Killer Rabbit,,,,,,,,,,,,,,,,,,,,,, -Serpent God,Serpent God,,,,,,,,,,,,,,,,,,,,,, -Girl Ninja,Girl Ninja,,,,,,,,,,,,,,,,,,,,,, -Blade,Blade,,,,,,,,,,,,,,,,,,,,,, -Dart,Dart,,,,,,,,,,,,,,,,,,,,,, -Shuriken,Shuriken,,,,,,,,,,,,,,,,,,,,,, -Crossbow Bolt,Crossbow Bolt,,,,,,,,,,,,,,,,,,,,,, -Spear,Spear,,,,,,,,,,,,,,,,,,,,,, -Lava Boulder,Lava Boulder,,,,,,,,,,,,,,,,,,,,,, -Uzi,Uzi,,,,,,,,,,,,,,,,,,,,,, -Evil Ninja Uzi,Evil Ninja Uzi,,,,,,,,,,,,,,,,,,,,,, -Shotgun,Shotgun,,,,,,,,,,,,,,,,,,,,,, -Meteor,Meteor,,,,,,,,,,,,,,,,,,,,,, -Rocket,Rocket,,,,,,,,,,,,,,,,,,,,,, -Rail Gun,Rail Gun,,,,,,,,,,,,,,,,,,,,,, -Enemy Rocket,Enemy Rocket,,,,,,,,,,,,,,,,,,,,,, -Bunny Rocket,Bunny Rocket,,,,,,,,,,,,,,,,,,,,,, -Explosion,Explosion,,,,,,,,,,,,,,,,,,,,,, -Tank Shell,Tank Shell,,,,,,,,,,,,,,,,,,,,,, -Nuclear Bomb,Nuclear Bomb,,,,,,,,,,,,,,,,,,,,,, -40mm Grenade,40mm Grenade,,,,,,,,,,,,,,,,,,,,,, -Micro Missile,Micro Missile,,,,,,,,,,,,,,,,,,,,,, -Sticky Bomb,Sticky Bomb,,,,,,,,,,,,,,,,,,,,,, -Napalm,Napalm,,,,,,,,,,,,,,,,,,,,,, -Vomit,Vomit,,,,,,,,,,,,,,,,,,,,,, -Coolie Ghost Phlem,Coolie Ghost Phlem,,,,,,,,,,,,,,,,,,,,,, -Accursed Head,Accursed Head,,,,,,,,,,,,,,,,,,,,,, -Bouncing Betty,Bouncing Betty,,,,,,,,,,,,,,,,,,,,,, -Serpent God Protector,Serpent God Protector,,,,,,,,,,,,,,,,,,,,,, -Flames,Flames,,,,,,,,,,,,,,,,,,,,,, -Radiation,Radiation,,,,,,,,,,,,,,,,,,,,,, -Caltrops,Caltrops,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file +Zombie,Zombie,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Blood Worm,Blood Worm,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Skeletor Priest,Skeletor Priest,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Coolie Ghost,Coolie Ghost,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Guardian,Guardian,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Hornet,Hornet,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Ripper Hatchling,Ripper Hatchling,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Ripper,Ripper,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Killer Rabbit,Killer Rabbit,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Serpent God,Serpent God,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Girl Ninja,Girl Ninja,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Blade,Blade,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Dart,Dart,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Shuriken,Shuriken,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Crossbow Bolt,Crossbow Bolt,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Spear,Spear,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Lava Boulder,Lava Boulder,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Uzi,Uzi,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Evil Ninja Uzi,Evil Ninja Uzi,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Shotgun,Shotgun,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Meteor,Meteor,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Rocket,Rocket,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Rail Gun,Rail Gun,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Enemy Rocket,Enemy Rocket,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Bunny Rocket,Bunny Rocket,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Explosion,Explosion,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Tank Shell,Tank Shell,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Nuclear Bomb,Nuclear Bomb,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +40mm Grenade,40mm Grenade,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Micro Missile,Micro Missile,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Sticky Bomb,Sticky Bomb,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Napalm,Napalm,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Vomit,Vomit,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Coolie Ghost Phlem,Coolie Ghost Phlem,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Accursed Head,Accursed Head,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Bouncing Betty,Bouncing Betty,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Serpent God Protector,Serpent God Protector,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Flames,Flames,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Radiation,Radiation,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Caltrops,Caltrops,,ShadowWarrior,,,,,,,,,,,,,,,,,,,, +Seppuku Station,TXTS_MAP01,,,,,,,,,,,,,,,,,,,,,, +Zilla Construction,TXTS_MAP02,,,,,,,,,,,,,,,,,,,,,, +Master Leep's Temple,TXTS_MAP03,,,,,,,,,,,,,,,,,,,,,, +Dark Woods of the Serpent,TXTS_MAP04,,,,,,,,,,,,,,,,,,,,,, +Rising Son,TXTS_MAP05,,,,,,,,,,,,,,,,,,,,,, +Killing Fields,TXTS_MAP06,,,,,,,,,,,,,,,,,,,,,, +Hara-Kiri Harbor,TXTS_MAP07,,,,,,,,,,,,,,,,,,,,,, +Zilla's Villa,TXTS_MAP08,,,,,,,,,,,,,,,,,,,,,, +Monastery,TXTS_MAP09,,,,,,,,,,,,,,,,,,,,,, +Raider of the Lost Wang,TXTS_MAP10,,,,,,,,,,,,,,,,,,,,,, +Sumo Sky Palace,TXTS_MAP11,,,,,,,,,,,,,,,,,,,,,, +Bath House,TXTS_MAP12,,,,,,,,,,,,,,,,,,,,,, +Unfriendly Skies,TXTS_MAP13,,,,,,,,,,,,,,,,,,,,,, +Crude Oil,TXTS_MAP14,,,,,,,,,,,,,,,,,,,,,, +Coolie Mines,TXTS_MAP15,,,,,,,,,,,,,,,,,,,,,, +Subpen 7,TXTS_MAP16,,,,,,,,,,,,,,,,,,,,,, +The Great Escape,TXTS_MAP17,,,,,,,,,,,,,,,,,,,,,, +Floating Fortress,TXTS_MAP18,,,,,,,,,,,,,,,,,,,,,, +Water Torture,TXTS_MAP19,,,,,,,,,,,,,,,,,,,,,, +Stone Rain,TXTS_MAP20,,,,,,,,,,,,,,,,,,,,,, +Shanghai Shipwreck,TXTS_MAP21,,,,,,,,,,,,,,,,,,,,,, +Auto Maul,TXTS_MAP22,,,,,,,,,,,,,,,,,,,,,, +Heavy Metal (DM only),TXTS_MAP23,,,,,,,,,,,,,,,,,,,,,, +Ripper Valley (DM only),TXTS_MAP24,,,,,,,,,,,,,,,,,,,,,, +House of Wang (DM only),TXTS_MAP25,,,,,,,,,,,,,,,,,,,,,, +Lo Wang Rally (DM only),TXTS_MAP26,,,,,,,,,,,,,,,,,,,,,, +Ruins of the Ronin (CTF),TXTS_MAP27,,,,,,,,,,,,,,,,,,,,,, +Killing Fields (CTF),TXTS_MAP28,,,,,,,,,,,,,,,,,,,,,, +Chinatown,TXTS_W_MAP01,,,,,,,,,,,,,,,,,,,,,, +Monastery,TXTS_W_MAP02,,,,,,,,,,,,,,,,,,,,,, +Trolly Yard,TXTS_W_MAP03,,,,,,,,,,,,,,,,,,,,,, +Restaurant,TXTS_W_MAP04,,,,,,,,,,,,,,,,,,,,,, +Skyscraper,TXTS_W_MAP05,,,,,,,,,,,,,,,,,,,,,, +Airplane,TXTS_W_MAP06,,,,,,,,,,,,,,,,,,,,,, +Military Base,TXTS_W_MAP07,,,,,,,,,,,,,,,,,,,,,, +Train,TXTS_W_MAP08,,,,,,,,,,,,,,,,,,,,,, +Auto Factory,TXTS_W_MAP09,,,,,,,,,,,,,,,,,,,,,, +Skyline,TXTS_W_MAP10,,,,,,,,,,,,,,,,,,,,,, +Redwood Forest,TXTS_W_MAP11,,,,,,,,,,,,,,,,,,,,,, +The Docks,TXTS_W_MAP12,,,,,,,,,,,,,,,,,,,,,, +Waterfight (DM only),TXTS_W_MAP13,,,,,,,,,,,,,,,,,,,,,, +Wanton DM 1 (DM only),TXTS_W_MAP14,,,,,,,,,,,,,,,,,,,,,, +Wanton DM2 (DM only),TXTS_W_MAP15,,,,,,,,,,,,,,,,,,,,,, +Wanton CTF (CTF),TXTS_W_MAP16,,,,,,,,,,,,,,,,,,,,,, +Wanton Destruction,TXTS_W_EP,,,,,,,,,,,,,,,,,,,,,, +Home Sweet Home,Home Sweet Home,"Twin Dragon +","ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +City of Dispair,City of Dispair,already contains,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Emergency Room,Emergency Room,SWCUSTOM.TXT,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Hide and Seek,Hide and Seek,,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Warehouse Madness,Warehouse Madness,,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Weapons Research Center,Weapons Research Center,,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Toxic Waste Facility,Toxic Waste Facility,,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Silver Bullet,Silver Bullet,,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Fishing Village,Fishing Village,,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Secret Garden,Secret Garden,,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Hung Lo's Fortress,Hung Lo's Fortress,,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Hung Lo's Palace,Hung Lo's Palace,,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Prison Camp (secret level),Prison Camp (secret level),,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Ninja Training Camp (dm),Ninja Training Camp (dm),,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +The Morgue/mortuary (dm),The Morgue/mortuary (dm),,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Island Caves (dm),Island Caves (dm),,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, +Twin Dragon,Twin Dragon,,"ShadowWarrior +",,,,,,,,,,,,,,,,,,,, \ No newline at end of file diff --git a/wadsrc/static/filter/shadowwarrior.wanton/SWCustom.txt b/wadsrc/static/filter/shadowwarrior.wanton/SWCustom.txt index 3522d227c..de7cf7ea0 100644 --- a/wadsrc/static/filter/shadowwarrior.wanton/SWCustom.txt +++ b/wadsrc/static/filter/shadowwarrior.wanton/SWCustom.txt @@ -1,42 +1,7 @@ -level 1 -{ - title "Seppuku Station" - filename "$bullet.map" - song "e1l01.mid" - cdatrack 4 - besttime 60 - partime 300 -} -level 2 -{ - title "Zilla Construction" - filename "$dozer.map" - song "e1l03.mid" - cdatrack 9 - besttime 300 - partime 480 -} -level 3 -{ - title "Master Leep's Temple" - filename "$shrine.map" - song "e1l02.mid" - cdatrack 12 - besttime 196 - partime 600 -} -level 4 -{ - title "Dark Woods of the Serpent" - filename "$woods.map" - song "e1l04.mid" - cdatrack 10 - besttime 428 - partime 960 -} + level 5 { - title "Chinatown" + title "$TXTS_W_MAP01" filename "$whirl.map" song "yokoha03.mid" cdatrack 5 @@ -45,7 +10,7 @@ level 5 } level 6 { - title "Monastery" + title "$TXTS_W_MAP02" filename "$tank.map" song "nippon34.mid" cdatrack 6 @@ -54,7 +19,7 @@ level 6 } level 7 { - title "Trolly Yard" + title "$TXTS_W_MAP03" filename "$boat.map" song "execut11.mid" cdatrack 8 @@ -63,7 +28,7 @@ level 7 } level 8 { - title "Restaurant" + title "$TXTS_W_MAP04" filename "$garden.map" song "execut11.mid" cdatrack 11 @@ -72,7 +37,7 @@ level 8 } level 9 { - title "Skyscraper" + title "$TXTS_W_MAP05" filename "$outpost.map" song "sanai.mid" cdatrack 12 @@ -81,7 +46,7 @@ level 9 } level 10 { - title "Airplane" + title "$TXTS_W_MAP06" filename "$hidtemp.map" song "kotec2.mid" cdatrack 5 @@ -90,7 +55,7 @@ level 10 } level 11 { - title "Military Base" + title "$TXTS_W_MAP07" filename "$plax1.map" song "kotec2.mid" cdatrack 10 @@ -99,7 +64,7 @@ level 11 } level 12 { - title "Train" + title "$TXTS_W_MAP08" filename "$bath.map" song "yokoha03" cdatrack 4 @@ -108,70 +73,16 @@ level 12 } level 13 { - title "Auto Factor" + title "$TXTS_W_MAP09" filename "$airport.map" song "nippon34" cdatrack 6 besttime 180 partime 300 } -level 14 -{ - title "Crude Oil" - filename "$refiner.map" - song "kotoki12.mid" - cdatrack 9 - besttime 160 - partime 300 -} -level 15 -{ - title "Coolie Mines" - filename "$newmine.map" - song "hoshia02.mid" - cdatrack 7 - besttime 180 - partime 300 -} -level 16 -{ - title "Subpen 7" - filename "$subbase.map" - song "hoshia02.mid" - cdatrack 10 - besttime 122 - partime 240 -} -level 17 -{ - title "The Great Escape" - filename "$rock.map" - song "" - cdatrack 8 - besttime 198 - partime 360 -} -level 18 -{ - title "Floating Fortress" - filename "$yamato.map" - song "sanai.mid" - cdatrack 7 - besttime 698 - partime 1200 -} -level 19 -{ - title "Water Torture" - filename "$seabase.map" - song "kotec2.mid" - cdatrack 9 - besttime 307 - partime 480 -} level 20 { - title "Skyline" + title "$TXTS_W_MAP10" filename "$volcano.map" song "" cdatrack 10 @@ -180,7 +91,7 @@ level 20 } level 21 { - title "Redwood Forest" + title "$TXTS_W_MAP11" filename "$shore.map" song "" cdatrack 11 @@ -189,7 +100,7 @@ level 21 } level 22 { - title "The Docks" + title "$TXTS_W_MAP12" filename "$auto.map" song "" cdatrack 5 @@ -198,7 +109,7 @@ level 22 } level 23 { - title "Waterfight (DM only)" + title "$TXTS_W_MAP13" filename "tank.map" song "" cdatrack 11 @@ -207,7 +118,7 @@ level 23 } level 24 { - title "Wanton DM 1 (DM only)" + title "$TXTS_W_MAP14" filename "$dmwoods.map" song "" cdatrack 8 @@ -216,46 +127,28 @@ level 24 } level 25 { - title "Wanton DM2 (DM only)" + title "$TXTS_W_MAP15" filename "$dmshrin.map" song "" cdatrack 7 besttime 600 partime 600 } -level 26 -{ - title "Lo Wang Rally (DM only" - filename "$rush.map" - song "" - cdatrack 13 - besttime 600 - partime 600 -} level 27 { - title "Wanton CTF (CTF)" + title "$TXTS_W_MAP16" filename "shotgun.map" song "" cdatrack 5 besttime 600 partime 600 } -level 28 -{ - title "Killing Fields (CTF)" - filename "$dmdrop.map" - song "" - cdatrack 6 - besttime 600 - partime 600 -} episode 1 { title "" } episode 2 { - title "Wanton Destruction" + title "$TXTS_W_EP" subtitle "" } diff --git a/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt b/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt index 0a2373857..bf0703a04 100644 --- a/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt +++ b/wadsrc/static/filter/shadowwarrior/demolition/SWCustom.txt @@ -1,6 +1,6 @@ level 1 { - title "Seppuku Station" + title "$TXTS_MAP01" filename "$bullet.map" song "e1l01.mid" cdatrack 4 @@ -9,7 +9,7 @@ level 1 } level 2 { - title "Zilla Construction" + title "$TXTS_MAP02" filename "$dozer.map" song "e1l03.mid" cdatrack 9 @@ -18,7 +18,7 @@ level 2 } level 3 { - title "Master Leep's Temple" + title "$TXTS_MAP03" filename "$shrine.map" song "e1l02.mid" cdatrack 12 @@ -27,7 +27,7 @@ level 3 } level 4 { - title "Dark Woods of the Serpent" + title "$TXTS_MAP04" filename "$woods.map" song "e1l04.mid" cdatrack 10 @@ -36,7 +36,7 @@ level 4 } level 5 { - title "Rising Son" + title "$TXTS_MAP05" filename "$whirl.map" song "yokoha03.mid" cdatrack 5 @@ -45,7 +45,7 @@ level 5 } level 6 { - title "Killing Fields" + title "$TXTS_MAP06" filename "$tank.map" song "nippon34.mid" cdatrack 6 @@ -54,7 +54,7 @@ level 6 } level 7 { - title "Hara-Kiri Harbor" + title "$TXTS_MAP07" filename "$boat.map" song "execut11.mid" cdatrack 8 @@ -63,7 +63,7 @@ level 7 } level 8 { - title "Zilla's Villa" + title "$TXTS_MAP08" filename "$garden.map" song "execut11.mid" cdatrack 11 @@ -72,7 +72,7 @@ level 8 } level 9 { - title "Monastery" + title "$TXTS_MAP09" filename "$outpost.map" song "sanai.mid" cdatrack 12 @@ -81,7 +81,7 @@ level 9 } level 10 { - title "Raider of the Lost Wang" + title "$TXTS_MAP10" filename "$hidtemp.map" song "kotec2.mid" cdatrack 5 @@ -90,7 +90,7 @@ level 10 } level 11 { - title "Sumo Sky Palace" + title "$TXTS_MAP11" filename "$plax1.map" song "kotec2.mid" cdatrack 10 @@ -99,7 +99,7 @@ level 11 } level 12 { - title "Bath House" + title "$TXTS_MAP12" filename "$bath.map" song "yokoha03" cdatrack 4 @@ -108,7 +108,7 @@ level 12 } level 13 { - title "Unfriendly Skies" + title "$TXTS_MAP13" filename "$airport.map" song "nippon34" cdatrack 6 @@ -117,7 +117,7 @@ level 13 } level 14 { - title "Crude Oil" + title "$TXTS_MAP14" filename "$refiner.map" song "kotoki12.mid" cdatrack 9 @@ -126,7 +126,7 @@ level 14 } level 15 { - title "Coolie Mines" + title "$TXTS_MAP15" filename "$newmine.map" song "hoshia02.mid" cdatrack 7 @@ -135,7 +135,7 @@ level 15 } level 16 { - title "Subpen 7" + title "$TXTS_MAP16" filename "$subbase.map" song "hoshia02.mid" cdatrack 10 @@ -144,7 +144,7 @@ level 16 } level 17 { - title "The Great Escape" + title "$TXTS_MAP17" filename "$rock.map" song "" cdatrack 8 @@ -153,7 +153,7 @@ level 17 } level 18 { - title "Floating Fortress" + title "$TXTS_MAP18" filename "$yamato.map" song "sanai.mid" cdatrack 7 @@ -162,7 +162,7 @@ level 18 } level 19 { - title "Water Torture" + title "$TXTS_MAP19" filename "$seabase.map" song "kotec2.mid" cdatrack 9 @@ -171,7 +171,7 @@ level 19 } level 20 { - title "Stone Rain" + title "$TXTS_MAP20" filename "$volcano.map" song "" cdatrack 10 @@ -180,7 +180,7 @@ level 20 } level 21 { - title "Shanghai Shipwreck" + title "$TXTS_MAP21" filename "$shore.map" song "" cdatrack 11 @@ -189,7 +189,7 @@ level 21 } level 22 { - title "Auto Maul" + title "$TXTS_MAP22" filename "$auto.map" song "" cdatrack 5 @@ -198,7 +198,7 @@ level 22 } level 23 { - title "Heavy Metal (DM only)" + title "$TXTS_MAP23" filename "tank.map" song "" cdatrack 11 @@ -207,7 +207,7 @@ level 23 } level 24 { - title "Ripper Valley (DM only)" + title "$TXTS_MAP24" filename "$dmwoods.map" song "" cdatrack 8 @@ -216,7 +216,7 @@ level 24 } level 25 { - title "House of Wang (DM only)" + title "$TXTS_MAP25" filename "$dmshrin.map" song "" cdatrack 7 @@ -225,7 +225,7 @@ level 25 } level 26 { - title "Lo Wang Rally (DM only" + title "$TXTS_MAP26" filename "$rush.map" song "" cdatrack 13 @@ -234,7 +234,7 @@ level 26 } level 27 { - title "Ruins of the Ronin (CTF)" + title "$TXTS_MAP27" filename "shotgun.map" song "" cdatrack 5 @@ -243,7 +243,7 @@ level 27 } level 28 { - title "Killing Fields (CTF)" + title "$TXTS_MAP28" filename "$dmdrop.map" song "" cdatrack 6 @@ -252,29 +252,29 @@ level 28 } episode 1 { - title "Enter the Wang" - subtitle "Four levels (Shareware Version)" + title "$TXTS_EP1" + subtitle "$TXTS_EPD1" } episode 2 { - title "Code of Honor" - subtitle "Eighteen levels (Full Version Only)" + title "$TXTS_EP2" + subtitle "$TXTS_EPD2" } skill 1 { - name "Tiny Grasshopper" + name "$TXTS_SK1" } skill 2 { - name "I Have No Fear" + name "$TXTS_SK2" } skill 3 { - name "Who Wants Wang" + name "$TXTS_SK3" } skill 4 { - name "No Pain, No Gain" + name "$TXTS_SK4" } inventory 1 From 7942bc9490514119f941dd5ccf782c7722615ad6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 11 Dec 2019 20:35:25 +0100 Subject: [PATCH 201/203] - completed work on Shadow Warrior main menu. This one will definitely be a problem for localization because the font is extremely large. --- source/common/filesystem/resourcefile.cpp | 12 ++++++------ source/common/menu/listmenu.cpp | 24 +++++++++++++++++++++++ source/common/menu/menu.h | 13 ++++++++++++ source/common/menu/menudef.cpp | 12 ++++-------- wadsrc/static/demolition/language.csv | 3 +-- 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/source/common/filesystem/resourcefile.cpp b/source/common/filesystem/resourcefile.cpp index 833b72e94..446db0deb 100644 --- a/source/common/filesystem/resourcefile.cpp +++ b/source/common/filesystem/resourcefile.cpp @@ -303,15 +303,15 @@ void FResourceFile::PostProcessArchive(void *lumps, size_t lumpsize) int lastpos = -1; FString file; - if (LumpFilter.IndexOf('.') < 0) + auto segments = LumpFilter.Split("."); + FString build; + + for (auto& segment : segments) { + if (build.IsEmpty()) build = segment; + else build << "." << segment; max -= FilterLumps(LumpFilter, lumps, lumpsize, max); } - else while ((len = LumpFilter.IndexOf('.', lastpos+1)) > 0) - { - max -= FilterLumps(LumpFilter.Left(len), lumps, lumpsize, max); - lastpos = len; - } JunkLeftoverFilters(lumps, lumpsize, max); } diff --git a/source/common/menu/listmenu.cpp b/source/common/menu/listmenu.cpp index 07767ba36..f9d2562b7 100644 --- a/source/common/menu/listmenu.cpp +++ b/source/common/menu/listmenu.cpp @@ -467,6 +467,30 @@ FListMenuItemStaticText::~FListMenuItemStaticText() if (mText != NULL) delete [] mText; } +//============================================================================= +// +// native static text item +// +//============================================================================= + +FListMenuItemNativeStaticText::FListMenuItemNativeStaticText(int x, int y, const FString& text, int fontnum, int palnum, bool centered) + : FListMenuItem(x, y) +{ + mText = text; + mFontnum = fontnum; + mPalnum = palnum; + mCentered = centered; +} + +void FListMenuItemNativeStaticText::Drawer(DListMenu* menu, const DVector2& origin, bool selected) +{ + const char* text = mText; + if (mText.Len() && !mHidden) + { + gi->DrawNativeMenuText(mFontnum, mPalnum, origin.X + mXpos, origin.Y + mYpos, 1.f, GStrings.localize(text), menu->Descriptor()->mFlags); + } +} + //============================================================================= // // base class for selectable items diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index b4ec67847..79a809c24 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -456,6 +456,19 @@ public: void Drawer(DListMenu* menu, const DVector2& origin, bool selected) override; }; +class FListMenuItemNativeStaticText : public FListMenuItem +{ +protected: + FString mText; + int mFontnum; + int mPalnum; + bool mCentered; + +public: + FListMenuItemNativeStaticText(int x, int y, const FString & text, int fontnum, int palnum, bool centered); + void Drawer(DListMenu* menu, const DVector2& origin, bool selected) override; +}; + //============================================================================= // // selectable items diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index 8949f48a1..94bedc889 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -1254,12 +1254,13 @@ static void BuildEpisodeMenu() addedVolumes++; if (gVolumeSubtitles[i].IsNotEmpty()) { - //auto it = new FListMenuItemNativeStaticText(ld->mXpos, gVolumeSubtitles[i], NIT_SmallFont); - //ld->mItems.Push(it); + auto it = new FListMenuItemNativeStaticText(ld->mXpos, y, gVolumeSubtitles[i], NIT_SmallFont, NIT_ActiveState, false); + y += ld->mLinespacing * 6 / 10; + ld->mItems.Push(it); } } } - if (1 /*CheckUserMaps()*/) + if (!(g_gameType & GAMEFLAG_SHAREWARE)) { //auto it = new FListMenuItemNativeStaticText(ld->mXpos, "", NIT_SmallFont); // empty entry as spacer. //ld->mItems.Push(it); @@ -1268,11 +1269,6 @@ static void BuildEpisodeMenu() auto it = new FListMenuItemNativeText(ld->mXpos, y, 0, 0, "$MNU_USERMAP", NIT_BigFont, NIT_ActiveState, 1, NAME_UsermapMenu); ld->mItems.Push(it); addedVolumes++; - if (g_gameType & GAMEFLAG_SW) // fixme: make this game independent. - { - //auto it = new FListMenuItemNativeStaticText(ld->mXpos, "$MNU_SELECTUSERMAP", NIT_SmallFont); - //ld->mItems.Push(it); - } } if (addedVolumes == 1) { diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index f8e853a5c..39bb6ea4c 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -1877,8 +1877,7 @@ Unholy Cathedral,Unholy Cathedral,,Blood,,,,,,,,,,,,,,,,,,,, Deadly Inspirations,Deadly Inspirations,,Blood,,,,,,,,,,,,,,,,,,,, ,Shadow Warrior,,,,,,,,,,,,,,,,,,,,,, Enter the Wang,TXTS_EP1,,,,,,,,,,,,,,,,,,,,,, -Code of Honor,"TXTS_EP2 -",,,,,,,,,,,,,,,,,,,,,, +Code of Honor,TXTS_EP2,,,,,,,,,,,,,,,,,,,,,, Four levels (Shareware Version),TXTS_EPD1,,,,,,,,,,,,,,,,,,,,,, Eighteen levels (Full Version Only),TXTS_EPD2,,,,,,,,,,,,,,,,,,,,,, Tiny grasshopper,TXTS_SK1,,,,,,,,,,,,,,,,,,,,,, From 86dc909559f6800453640f5cd08173783b6914c3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 11 Dec 2019 23:41:05 +0100 Subject: [PATCH 202/203] - added detection logic for zipped versions of the Cryptic Passage add-on for Blood and the Route66 add-on for Redneck Rampage. - added command line options to load the original file dump of both mods in the game directory. - both also require loading additional non-standard-named .art files --- source/common/gamecontrol.cpp | 29 +++++++++- source/common/initfs.cpp | 2 +- source/common/mapinfo.h | 2 +- source/common/searchpaths.cpp | 61 +++++++++++++++++++-- source/common/textures/buildtiles.cpp | 5 ++ source/common/textures/textures.h | 5 ++ source/duke3d/src/d_menu.cpp | 2 +- source/rr/src/d_menu.cpp | 2 +- wadsrc/static/demolition/demolition.grpinfo | 8 ++- 9 files changed, 104 insertions(+), 12 deletions(-) diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index 39dd168e9..5164b3aea 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -65,14 +65,16 @@ void UserConfig::ProcessOptions() initprintf("Build-format config files not supported and will be ignored\n"); } +#if 0 // MP disabled pending evaluation auto v = Args->CheckValue("-port"); if (v) netPort = strtol(v, nullptr, 0); netServerMode = Args->CheckParm("-server"); netServerAddress = Args->CheckValue("-connect"); netPassword = Args->CheckValue("-password"); +#endif - v = Args->CheckValue("-addon"); + auto v = Args->CheckValue("-addon"); if (v) { auto val = strtol(v, nullptr, 0); @@ -92,6 +94,22 @@ void UserConfig::ProcessOptions() { gamegrp = "WW2GI.GRP"; } + // Set up all needed content for these two mod which feature a very messy distribution. + // As an alternative they can be zipped up - the launcher will be able to detect and set up such versions automatically. + else if (Args->CheckParm("-route66")) + { + gamegrp = "REDNECK.GRP"; + DefaultCon = "GAME66.CON"; + const char* argv[] = { "tilesa66.art" , "tilesb66.art" }; + AddArt.reset(new FArgs(2, argv)); + } + else if (Args->CheckParm("-cryptic")) + { + gamegrp = "BLOOD.RFF"; + DefaultCon = "CRYPTIC.INI"; + const char* argv[] = { "cpart07.ar_" , "cpart15.ar_" }; + AddArt.reset(new FArgs(2, argv)); + } v = Args->CheckValue("-gamegrp"); if (v) @@ -408,6 +426,15 @@ int CONFIG_Init() CheckFrontend(g_gameType); InitFileSystem(usedgroups); + TArray addArt; + for (auto& grp : usedgroups) + { + for (auto& art : grp.FileInfo.loadart) + { + addArt.Push(art); + } + } + TileFiles.AddArt(addArt); CONTROL_ClearAssignments(); CONFIG_InitMouseAndController(); diff --git a/source/common/initfs.cpp b/source/common/initfs.cpp index 762825867..6f46b4892 100644 --- a/source/common/initfs.cpp +++ b/source/common/initfs.cpp @@ -267,7 +267,7 @@ static void D_AddDirectory (TArray &wadfiles, const char *dir) { skindir[stuffstart++] = '/'; int savedstart = stuffstart; - const char* validexts[] = { "*.grp", "*.zip", "*.pk3", "*.pk4", "*.7z", "*.pk7", "*.dat" }; + static const char* validexts[] = { "*.grp", "*.zip", "*.pk3", "*.pk4", "*.7z", "*.pk7", "*.dat" }; for (auto ext : validexts) { stuffstart = savedstart; diff --git a/source/common/mapinfo.h b/source/common/mapinfo.h index 8ab0a1af9..abff2ba2f 100644 --- a/source/common/mapinfo.h +++ b/source/common/mapinfo.h @@ -29,7 +29,7 @@ struct MapRecord FString name; FString music; int cdSongId = -1; - int flags = -1; + int flags = 0; // The rest is only used by Blood int nextLevel = -1; diff --git a/source/common/searchpaths.cpp b/source/common/searchpaths.cpp index 5e618d0d0..1001a2ff8 100644 --- a/source/common/searchpaths.cpp +++ b/source/common/searchpaths.cpp @@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gamecontrol.h" #include "filesystem/filesystem.h" +static const char* res_exts[] = { ".grp", ".zip", ".pk3", ".pk4", ".7z", ".pk7" }; namespace fs = std::filesystem; @@ -809,7 +810,7 @@ static TArray ParseGrpInfo(const char *fn, FileReader &fr, TMap GrpScan() TArray sortedFileList; TArray sortedGroupList; + TArray contentGroupList; auto allFiles = CollectAllFilesInSearchPath(); auto allGroups = ParseAllGrpInfos(allFiles); @@ -935,8 +937,58 @@ TArray GrpScan() // Remove all unnecessary content from the file list. Since this contains all data from the search path's directories it can be quite large. // Sort both lists by file size so that we only need to pass over each list once to weed out all unrelated content. Go backward to avoid too much item movement // (most will be deleted anyway.) + + for (auto& f : allFiles) sortedFileList.Push(&f); - for (auto& g : allGroups) sortedGroupList.Push(&g); + for (auto& g : allGroups) + { + if (g.CRC == 0 && g.mustcontain.Size() > 0) + contentGroupList.Push(&g); + else + sortedGroupList.Push(&g); + } + + // As a first pass we need to look for all known game resources which only are identified by a content list + if (contentGroupList.Size()) + { + for (auto fe : sortedFileList) + { + FString fn = fe->FileName.MakeLower(); + for (auto ext : res_exts) + { + if (strcmp(ext, fn.GetChars() + fn.Len() - 4) == 0) + { + auto resf = FResourceFile::OpenResourceFile(fe->FileName, true, true); + if (resf) + { + for (auto grp : contentGroupList) + { + bool ok = true; + for (auto &lump : grp->mustcontain) + { + if (!resf->FindLump(lump)) + { + ok = false; + break; + } + } + if (ok) + { + // got a match + foundGames.Reserve(1); + auto& fg = foundGames.Last(); + fg.FileInfo = *grp; + fg.FileName = fe->FileName; + fg.FileIndex = fe->Index; + break; + } + } + } + } + } + } + } + std::sort(sortedFileList.begin(), sortedFileList.end(), [](FileEntry* lhs, FileEntry* rhs) { return lhs->FileLength < rhs->FileLength; }); std::sort(sortedGroupList.begin(), sortedGroupList.end(), [](GrpInfo* lhs, GrpInfo* rhs) { return lhs->size < rhs->size; }); @@ -944,6 +996,7 @@ TArray GrpScan() int findex = sortedFileList.Size() - 1; int gindex = sortedGroupList.Size() - 1; + while (findex > 0 && gindex > 0) { if (sortedFileList[findex]->FileLength > sortedGroupList[gindex]->size) @@ -1018,7 +1071,7 @@ TArray GrpScan() { for (unsigned j = foundGames.Size() - 1; j > i; j--) { - if (foundGames[i].FileInfo.CRC == foundGames[j].FileInfo.CRC) + if (foundGames[i].FileInfo.CRC == foundGames[j].FileInfo.CRC && foundGames[j].FileInfo.CRC != 0) foundGames.Delete(j); } } @@ -1094,7 +1147,7 @@ const char* G_DefaultConFile(void) } if (g_gameType & GAMEFLAG_SW) - return nullptr; // SW has no scripts of any kind (todo: Make Blood's INI files usable here for map definitions) + return nullptr; // SW has no scripts of any kind. if (g_gameType & GAMEFLAG_NAM) { diff --git a/source/common/textures/buildtiles.cpp b/source/common/textures/buildtiles.cpp index 1238ea97a..b0c6c8dd0 100644 --- a/source/common/textures/buildtiles.cpp +++ b/source/common/textures/buildtiles.cpp @@ -42,6 +42,7 @@ #include "palette.h" #include "m_crc32.h" #include "build.h" +#include "gamecontrol.h" enum { @@ -339,6 +340,10 @@ void BuildTiles::LoadArtSet(const char* filename) FStringf fn(filename, index); LoadArtFile(fn, false); } + for (auto& addart : addedArt) + { + LoadArtFile(addart, false); + } } diff --git a/source/common/textures/textures.h b/source/common/textures/textures.h index b574bca56..22e54b4c6 100644 --- a/source/common/textures/textures.h +++ b/source/common/textures/textures.h @@ -506,6 +506,7 @@ struct BuildTiles FTexture* tiles[MAXTILES]; FTexture* tilesbak[MAXTILES]; TMap textures; + TArray addedArt; BuildTiles() { @@ -537,6 +538,10 @@ struct BuildTiles int LoadArtFile(const char* file, bool mapart = false, int firsttile = -1); void CloseAllMapArt(); void LoadArtSet(const char* filename); + void AddArt(TArray& art) + { + addedArt = std::move(art); + } FTexture* ValidateCustomTile(int tilenum, int type); int32_t artLoadFiles(const char* filename); uint8_t* tileMakeWritable(int num); diff --git a/source/duke3d/src/d_menu.cpp b/source/duke3d/src/d_menu.cpp index 7b8fc7fd2..38e3822bf 100644 --- a/source/duke3d/src/d_menu.cpp +++ b/source/duke3d/src/d_menu.cpp @@ -575,7 +575,7 @@ void GameInterface::StartGame(FGameStartup& gs) ud.m_respawn_inventory = 0; ud.multimode = 1; ud.m_volume_number = gs.Episode; - ud.m_level_number = gs.Level; + m_level_number = gs.Level; G_NewGame_EnterLevel(); } diff --git a/source/rr/src/d_menu.cpp b/source/rr/src/d_menu.cpp index 8ca1d5998..d275f62fb 100644 --- a/source/rr/src/d_menu.cpp +++ b/source/rr/src/d_menu.cpp @@ -450,7 +450,7 @@ void GameInterface::StartGame(FGameStartup& gs) ud.m_respawn_inventory = 0; ud.multimode = 1; ud.m_volume_number = gs.Episode; - ud.m_level_number = gs.Level; + m_level_number = gs.Level; G_NewGame_EnterLevel(); } diff --git a/wadsrc/static/demolition/demolition.grpinfo b/wadsrc/static/demolition/demolition.grpinfo index 9674d5d16..7321f2e71 100644 --- a/wadsrc/static/demolition/demolition.grpinfo +++ b/wadsrc/static/demolition/demolition.grpinfo @@ -332,10 +332,10 @@ grpinfo grpinfo { - // This is for detecting zipped versions of the mod. The default configuration with all files dumped in the game filter requires starting the game with "-route66" + // This is for detecting zipped versions of the mod. name "Redneck Rampage: Suckin' Grits on Route 66" scriptname "GAME66.CON" - mustcontain "TILESA66.ART", "TILESB66.ART", "CARNIVAL.MAP", "TRUCKSTP.MAP", "GAME66.CON" + mustcontain "TILESA66.ART", "TILESB66.ART", "ROUTE66/CARNIVAL.MAP", "ROUTE66/TRUCKSTP.MAP", "GAME66.CON" flags GAMEFLAG_RR|GAMEFLAG_ADDON dependency RR_CRC loadart "TILESA66.ART", "TILESB66.ART" // replaces TILES009 and TILES023. @@ -355,6 +355,7 @@ grpinfo gamefilter "Blood.Blood" } +/* this doesn't work with the current setup. grpinfo { // This is for identifying older Blood versions. Since I have no information, all I can do is testing for a few known files. @@ -367,10 +368,11 @@ grpinfo loadgrp "SOUNDS.RFF", "GUI.RFF" gamefilter "Blood.Blood" } +*/ grpinfo { - // This is for detecting zipped versions of the mod. The default configuration with all files dumped in the game filter requires starting the game with "-cryptic" + // This is for detecting zipped versions of the mod. name "BLOOD: Cryptic Passage" scriptname "CRYPTIC.INI" mustcontain "CRYPTIC.INI", "CP01.MAP", "CP02.MAP" From 264a450bbeff35505803f8fedf31f5441cf12904 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 11 Dec 2019 23:52:34 +0100 Subject: [PATCH 203/203] - corrected labels for Blood's weapon pickup strings. --- wadsrc/static/demolition/language.csv | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/wadsrc/static/demolition/language.csv b/wadsrc/static/demolition/language.csv index 39bb6ea4c..fb7fcba3e 100644 --- a/wadsrc/static/demolition/language.csv +++ b/wadsrc/static/demolition/language.csv @@ -1694,17 +1694,17 @@ Picked up OBSOLETE,TXTB_AMMO18,,,,,,,,,,,,,,,,,,,,,, Picked up OBSOLETE,TXTB_AMMO19,,,,,,,,,,,,,,,,,,,,,, Picked up Gasoline Can,TXTB_AMMO20,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,, -Picked up RANDOM,TXTB_WPN00,,,,,,,,,,,,,,,,,,,,,, -Picked up Sawed-off,TXTB_WPN01,,,,,,,,,,,,,,,,,,,,,, -Picked up Tommy Gun,TXTB_WPN02,,,,,,,,,,,,,,,,,,,,,, -Picked up Flare Pistol,TXTB_WPN03,,,,,,,,,,,,,,,,,,,,,, -Picked up Voodoo Doll,TXTB_WPN04,,,,,,,,,,,,,,,,,,,,,, -Picked up Tesla Cannon,TXTB_WPN05,,,,,,,,,,,,,,,,,,,,,, -Picked up Napalm Launcher,TXTB_WPN06,,,,,,,,,,,,,,,,,,,,,, -Picked up Pitchfork,TXTB_WPN07,,,,,,,,,,,,,,,,,,,,,, -Picked up Spray Can,TXTB_WPN08,,,,,,,,,,,,,,,,,,,,,, -Picked up Dynamite,TXTB_WPN09,,,,,,,,,,,,,,,,,,,,,, -Picked up Life Leech,TXTB_WPN10,,,,,,,,,,,,,,,,,,,,,, +Picked up RANDOM,TXTB_WPN01,,,,,,,,,,,,,,,,,,,,,, +Picked up Sawed-off,TXTB_WPN02,,,,,,,,,,,,,,,,,,,,,, +Picked up Tommy Gun,TXTB_WPN03,,,,,,,,,,,,,,,,,,,,,, +Picked up Flare Pistol,TXTB_WPN04,,,,,,,,,,,,,,,,,,,,,, +Picked up Voodoo Doll,TXTB_WPN05,,,,,,,,,,,,,,,,,,,,,, +Picked up Tesla Cannon,TXTB_WPN06,,,,,,,,,,,,,,,,,,,,,, +Picked up Napalm Launcher,TXTB_WPN07,,,,,,,,,,,,,,,,,,,,,, +Picked up Pitchfork,TXTB_WPN08,,,,,,,,,,,,,,,,,,,,,, +Picked up Spray Can,TXTB_WPN09,,,,,,,,,,,,,,,,,,,,,, +Picked up Dynamite,TXTB_WPN10,,,,,,,,,,,,,,,,,,,,,, +Picked up Life Leech,TXTB_WPN11,,,,,,,,,,,,,,,,,,,,,, It's locked,TXTB_LOCKED,,,,,,,,,,,,,,,,,,,,,, That requires a key.,TXTB_KEY,,,,,,,,,,,,,,,,,,,,,, %s dropped Blue Flag,"TXTB_DBF