mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-24 21:21:04 +00:00
- moved DObject and core parts of the VM to 'common'.
# Conflicts: # src/common/objects/dobject.h
This commit is contained in:
parent
1a0ace4f88
commit
f8ac9a2662
48 changed files with 403 additions and 349 deletions
|
@ -194,7 +194,6 @@ endif()
|
||||||
# find_package( asmjit )
|
# find_package( asmjit )
|
||||||
#endif()
|
#endif()
|
||||||
|
|
||||||
|
|
||||||
if( MSVC )
|
if( MSVC )
|
||||||
# Eliminate unreferenced functions and data
|
# Eliminate unreferenced functions and data
|
||||||
# Perform identical COMDAT folding
|
# Perform identical COMDAT folding
|
||||||
|
@ -213,20 +212,6 @@ if( MSVC )
|
||||||
#set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2") # This is already the default
|
#set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2") # This is already the default
|
||||||
|
|
||||||
|
|
||||||
# if( CMAKE_SIZEOF_VOID_P MATCHES "4")
|
|
||||||
# # SSE2 option (to allow x87 in 32 bit and disallow extended feature sets which have not yet been checked for precision)
|
|
||||||
# option (ZDOOM_USE_SSE2 "Use SSE2 instruction set")
|
|
||||||
# if (ZDOOM_USE_SSE2)
|
|
||||||
# set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2")
|
|
||||||
# else ()
|
|
||||||
# if (MSVC_VERSION GREATER 1699)
|
|
||||||
# # On Visual C++ 2012 and later SSE2 is the default, so we need to switch it off explicitly
|
|
||||||
# set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:IA32")
|
|
||||||
# endif ()
|
|
||||||
# endif ()
|
|
||||||
# else()
|
|
||||||
# set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2")
|
|
||||||
# endif()
|
|
||||||
|
|
||||||
# Avoid CRT DLL dependancies in release builds, optionally generate assembly output for checking crash locations.
|
# Avoid CRT DLL dependancies in release builds, optionally generate assembly output for checking crash locations.
|
||||||
option( ZDOOM_GENERATE_ASM "Generate assembly output." OFF )
|
option( ZDOOM_GENERATE_ASM "Generate assembly output." OFF )
|
||||||
|
@ -330,7 +315,7 @@ if( ZLIB_FOUND AND NOT FORCE_INTERNAL_ZLIB )
|
||||||
message( STATUS "Using system zlib, includes found at ${ZLIB_INCLUDE_DIR}" )
|
message( STATUS "Using system zlib, includes found at ${ZLIB_INCLUDE_DIR}" )
|
||||||
else()
|
else()
|
||||||
message( STATUS "Using internal zlib" )
|
message( STATUS "Using internal zlib" )
|
||||||
set( SKIP_INSTALL_ALL TRUE ) # Avoid installing zlib alongside zdoom
|
set( SKIP_INSTALL_ALL TRUE ) # Avoid installing zlib
|
||||||
add_subdirectory( libraries/zlib )
|
add_subdirectory( libraries/zlib )
|
||||||
set( ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libraries/zlib )
|
set( ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libraries/zlib )
|
||||||
set( ZLIB_LIBRARIES z )
|
set( ZLIB_LIBRARIES z )
|
||||||
|
|
|
@ -612,19 +612,23 @@ file( GLOB HEADER_FILES
|
||||||
common/utility/*.h
|
common/utility/*.h
|
||||||
common/engine/*.h
|
common/engine/*.h
|
||||||
common/fonts/*.h
|
common/fonts/*.h
|
||||||
|
common/objects/*.h
|
||||||
common/filesystem/*.h
|
common/filesystem/*.h
|
||||||
common/textures/hires/hqnx/*.h
|
common/textures/hires/hqnx/*.h
|
||||||
common/textures/hires/hqnx_asm/*.h
|
common/textures/hires/hqnx_asm/*.h
|
||||||
common/textures/hires/xbr/*.h
|
common/textures/hires/xbr/*.h
|
||||||
common/thirdparty/*.h
|
common/thirdparty/*.h
|
||||||
common/thirdparty/rapidjson/*.h
|
common/thirdparty/rapidjson/*.h
|
||||||
common/thirdparty/math./*h
|
common/thirdparty/math/*h
|
||||||
|
common/scripting/core/*h
|
||||||
|
common/scripting/vm/*h
|
||||||
|
common/scripting/jit/*h
|
||||||
|
common/scripting/interface/*.h
|
||||||
utility/*.h
|
utility/*.h
|
||||||
scripting/*.h
|
scripting/*.h
|
||||||
scripting/backend/*.h
|
scripting/backend/*.h
|
||||||
scripting/decorate/*.h
|
scripting/decorate/*.h
|
||||||
scripting/zscript/*.h
|
scripting/zscript/*.h
|
||||||
scripting/vm/*.h
|
|
||||||
sound/midisources/*.h
|
sound/midisources/*.h
|
||||||
rendering/*.h
|
rendering/*.h
|
||||||
rendering/2d/*.h
|
rendering/2d/*.h
|
||||||
|
@ -739,14 +743,14 @@ set( NOT_COMPILED_SOURCE_FILES
|
||||||
)
|
)
|
||||||
|
|
||||||
set( VM_JIT_SOURCES
|
set( VM_JIT_SOURCES
|
||||||
scripting/vm/jit.cpp
|
common/scripting/jit/jit.cpp
|
||||||
scripting/vm/jit_runtime.cpp
|
common/scripting/jit/jit_runtime.cpp
|
||||||
scripting/vm/jit_call.cpp
|
common/scripting/jit/jit_call.cpp
|
||||||
scripting/vm/jit_flow.cpp
|
common/scripting/jit/jit_flow.cpp
|
||||||
scripting/vm/jit_load.cpp
|
common/scripting/jit/jit_load.cpp
|
||||||
scripting/vm/jit_math.cpp
|
common/scripting/jit/jit_math.cpp
|
||||||
scripting/vm/jit_move.cpp
|
common/scripting/jit/jit_move.cpp
|
||||||
scripting/vm/jit_store.cpp
|
common/scripting/jit/jit_store.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# This is disabled for now because I cannot find a way to give the .pch file a different name.
|
# This is disabled for now because I cannot find a way to give the .pch file a different name.
|
||||||
|
@ -838,9 +842,6 @@ set (PCH_SOURCES
|
||||||
d_net.cpp
|
d_net.cpp
|
||||||
d_netinfo.cpp
|
d_netinfo.cpp
|
||||||
d_protocol.cpp
|
d_protocol.cpp
|
||||||
dobject.cpp
|
|
||||||
dobjgc.cpp
|
|
||||||
dobjtype.cpp
|
|
||||||
doomstat.cpp
|
doomstat.cpp
|
||||||
g_cvars.cpp
|
g_cvars.cpp
|
||||||
g_dumpinfo.cpp
|
g_dumpinfo.cpp
|
||||||
|
@ -1037,25 +1038,19 @@ set (PCH_SOURCES
|
||||||
r_data/models/models_ue1.cpp
|
r_data/models/models_ue1.cpp
|
||||||
r_data/models/models_obj.cpp
|
r_data/models/models_obj.cpp
|
||||||
scripting/dictionary.cpp
|
scripting/dictionary.cpp
|
||||||
scripting/symbols.cpp
|
|
||||||
scripting/vmiterators.cpp
|
scripting/vmiterators.cpp
|
||||||
scripting/vmthunks.cpp
|
scripting/vmthunks.cpp
|
||||||
scripting/vmthunks_actors.cpp
|
scripting/vmthunks_actors.cpp
|
||||||
scripting/types.cpp
|
|
||||||
scripting/thingdef.cpp
|
scripting/thingdef.cpp
|
||||||
scripting/thingdef_data.cpp
|
scripting/thingdef_data.cpp
|
||||||
scripting/thingdef_properties.cpp
|
scripting/thingdef_properties.cpp
|
||||||
scripting/backend/codegen.cpp
|
scripting/backend/codegen.cpp
|
||||||
scripting/backend/scopebarrier.cpp
|
|
||||||
scripting/backend/dynarrays.cpp
|
scripting/backend/dynarrays.cpp
|
||||||
scripting/backend/vmbuilder.cpp
|
scripting/backend/vmbuilder.cpp
|
||||||
scripting/backend/vmdisasm.cpp
|
|
||||||
scripting/decorate/olddecorations.cpp
|
scripting/decorate/olddecorations.cpp
|
||||||
scripting/decorate/thingdef_exp.cpp
|
scripting/decorate/thingdef_exp.cpp
|
||||||
scripting/decorate/thingdef_parse.cpp
|
scripting/decorate/thingdef_parse.cpp
|
||||||
scripting/decorate/thingdef_states.cpp
|
scripting/decorate/thingdef_states.cpp
|
||||||
scripting/vm/vmexec.cpp
|
|
||||||
scripting/vm/vmframe.cpp
|
|
||||||
scripting/zscript/ast.cpp
|
scripting/zscript/ast.cpp
|
||||||
scripting/zscript/zcc_compile.cpp
|
scripting/zscript/zcc_compile.cpp
|
||||||
scripting/zscript/zcc_parser.cpp
|
scripting/zscript/zcc_parser.cpp
|
||||||
|
@ -1152,6 +1147,16 @@ set (PCH_SOURCES
|
||||||
common/engine/i_interface.cpp
|
common/engine/i_interface.cpp
|
||||||
common/engine/renderstyle.cpp
|
common/engine/renderstyle.cpp
|
||||||
common/engine/v_colortables.cpp
|
common/engine/v_colortables.cpp
|
||||||
|
common/objects/dobject.cpp
|
||||||
|
common/objects/dobjgc.cpp
|
||||||
|
common/objects/dobjtype.cpp
|
||||||
|
common/scripting/core/symbols.cpp
|
||||||
|
common/scripting/core/types.cpp
|
||||||
|
common/scripting/core/scopebarrier.cpp
|
||||||
|
common/scripting/core/vmdisasm.cpp
|
||||||
|
common/scripting/vm/vmexec.cpp
|
||||||
|
common/scripting/vm/vmframe.cpp
|
||||||
|
common/scripting/interface/stringformat.cpp
|
||||||
|
|
||||||
utility/m_random.cpp
|
utility/m_random.cpp
|
||||||
utility/nodebuilder/nodebuild.cpp
|
utility/nodebuilder/nodebuild.cpp
|
||||||
|
@ -1181,7 +1186,7 @@ endif()
|
||||||
add_executable( zdoom WIN32 MACOSX_BUNDLE
|
add_executable( zdoom WIN32 MACOSX_BUNDLE
|
||||||
${HEADER_FILES}
|
${HEADER_FILES}
|
||||||
${NOT_COMPILED_SOURCE_FILES}
|
${NOT_COMPILED_SOURCE_FILES}
|
||||||
__autostart.cpp
|
common/objects/__autostart.cpp
|
||||||
${SYSTEM_SOURCES}
|
${SYSTEM_SOURCES}
|
||||||
${FASTMATH_SOURCES}
|
${FASTMATH_SOURCES}
|
||||||
${PCH_SOURCES}
|
${PCH_SOURCES}
|
||||||
|
@ -1207,7 +1212,7 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
|
||||||
common/thirdparty/math/tan.c
|
common/thirdparty/math/tan.c
|
||||||
common/thirdparty/math/tanh.c
|
common/thirdparty/math/tanh.c
|
||||||
common/thirdparty/math/fastsin.cpp
|
common/thirdparty/math/fastsin.cpp
|
||||||
zzautozend.cpp
|
common/objects/zzautozend.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set_source_files_properties( ${FASTMATH_SOURCES} PROPERTIES COMPILE_FLAGS ${ZD_FASTMATH_FLAG} )
|
set_source_files_properties( ${FASTMATH_SOURCES} PROPERTIES COMPILE_FLAGS ${ZD_FASTMATH_FLAG} )
|
||||||
|
@ -1241,6 +1246,10 @@ include_directories( .
|
||||||
common/console
|
common/console
|
||||||
common/engine
|
common/engine
|
||||||
common/fonts
|
common/fonts
|
||||||
|
common/objects
|
||||||
|
common/scripting/vm
|
||||||
|
common/scripting/jit
|
||||||
|
common/scripting/core
|
||||||
g_statusbar
|
g_statusbar
|
||||||
console
|
console
|
||||||
playsim
|
playsim
|
||||||
|
@ -1258,7 +1267,6 @@ include_directories( .
|
||||||
utility
|
utility
|
||||||
utility/nodebuilder
|
utility/nodebuilder
|
||||||
scripting
|
scripting
|
||||||
scripting/vm
|
|
||||||
rendering
|
rendering
|
||||||
rendering/vulkan/thirdparty
|
rendering/vulkan/thirdparty
|
||||||
../libraries/gdtoa
|
../libraries/gdtoa
|
||||||
|
@ -1427,7 +1435,6 @@ source_group("Platforms\\Win32 Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURC
|
||||||
source_group("Scripting\\Decorate frontend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/decorate/.+")
|
source_group("Scripting\\Decorate frontend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/decorate/.+")
|
||||||
source_group("Scripting\\ZScript frontend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/zscript/.+" FILES ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h)
|
source_group("Scripting\\ZScript frontend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/zscript/.+" FILES ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h)
|
||||||
source_group("Scripting\\Compiler backend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/backend/.+")
|
source_group("Scripting\\Compiler backend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/backend/.+")
|
||||||
source_group("Scripting\\VM" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/vm/.+")
|
|
||||||
source_group("Scripting" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/.+")
|
source_group("Scripting" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/.+")
|
||||||
source_group("Common" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/.+")
|
source_group("Common" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/.+")
|
||||||
source_group("Common\\Audio" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/audio/.+")
|
source_group("Common\\Audio" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/audio/.+")
|
||||||
|
|
|
@ -91,8 +91,8 @@ enum
|
||||||
ROLLOFF_Custom // Lookup volume from SNDCURVE
|
ROLLOFF_Custom // Lookup volume from SNDCURVE
|
||||||
};
|
};
|
||||||
|
|
||||||
int S_FindSound(const char *logicalname);
|
inline int S_FindSoundByResID(int ndx);
|
||||||
int S_FindSoundByResID(int snd_id);
|
inline int S_FindSound(const char* name);
|
||||||
|
|
||||||
// An index into the S_sfx[] array.
|
// An index into the S_sfx[] array.
|
||||||
class FSoundID
|
class FSoundID
|
||||||
|
@ -429,3 +429,12 @@ struct FReverbField
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline int S_FindSoundByResID(int ndx)
|
||||||
|
{
|
||||||
|
return soundEngine->FindSoundByResID(ndx);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int S_FindSound(const char* name)
|
||||||
|
{
|
||||||
|
return soundEngine->FindSound(name);
|
||||||
|
}
|
||||||
|
|
|
@ -36,9 +36,11 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include "doomtype.h"
|
|
||||||
#include "m_alloc.h"
|
#include "m_alloc.h"
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
|
#include "name.h"
|
||||||
|
#include "palentry.h"
|
||||||
|
#include "textureid.h"
|
||||||
|
|
||||||
class PClass;
|
class PClass;
|
||||||
class PType;
|
class PType;
|
|
@ -293,12 +293,7 @@ static void MarkRoot()
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
players[i].PropagateMark();
|
players[i].PropagateMark();
|
||||||
}
|
}
|
||||||
// Mark sectors.
|
|
||||||
|
|
||||||
for (auto Level : AllLevels())
|
|
||||||
{
|
|
||||||
Level->Mark();
|
|
||||||
}
|
|
||||||
// NextToThink must not be freed while thinkers are ticking.
|
// NextToThink must not be freed while thinkers are ticking.
|
||||||
Mark(NextToThink);
|
Mark(NextToThink);
|
||||||
// Mark soft roots.
|
// Mark soft roots.
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "dobject.h"
|
#include "dobject.h"
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
#include "scripting/backend/scopebarrier.h"
|
#include "scopebarrier.h"
|
||||||
|
|
||||||
// Variable/parameter/field flags -------------------------------------------
|
// Variable/parameter/field flags -------------------------------------------
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "c_console.h"
|
#include "c_console.h"
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "vmintern.h"
|
#include "vmintern.h"
|
||||||
|
#include "printf.h"
|
||||||
|
|
||||||
#define NOP MODE_AUNUSED | MODE_BUNUSED | MODE_CUNUSED
|
#define NOP MODE_AUNUSED | MODE_BUNUSED | MODE_CUNUSED
|
||||||
|
|
278
src/common/scripting/interface/stringformat.cpp
Normal file
278
src/common/scripting/interface/stringformat.cpp
Normal file
|
@ -0,0 +1,278 @@
|
||||||
|
/*
|
||||||
|
** thingdef_data.cpp
|
||||||
|
**
|
||||||
|
** DECORATE data tables
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2002-2008 Christoph Oelckers
|
||||||
|
** Copyright 2004-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.
|
||||||
|
** 4. When not used as part of ZDoom or a ZDoom derivative, this code will be
|
||||||
|
** covered by 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 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 "zstring.h"
|
||||||
|
#include "vm.h"
|
||||||
|
#include "gstrings.h"
|
||||||
|
#include "v_font.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FString FStringFormat(VM_ARGS, int offset)
|
||||||
|
{
|
||||||
|
PARAM_VA_POINTER(va_reginfo) // Get the hidden type information array
|
||||||
|
assert(va_reginfo[offset] == REGT_STRING);
|
||||||
|
|
||||||
|
FString fmtstring = param[offset].s().GetChars();
|
||||||
|
|
||||||
|
param += offset;
|
||||||
|
numparam -= offset;
|
||||||
|
va_reginfo += offset;
|
||||||
|
|
||||||
|
// note: we don't need a real printf format parser.
|
||||||
|
// enough to simply find the subtitution tokens and feed them to the real printf after checking types.
|
||||||
|
// https://en.wikipedia.org/wiki/Printf_format_string#Format_placeholder_specification
|
||||||
|
FString output;
|
||||||
|
bool in_fmt = false;
|
||||||
|
FString fmt_current;
|
||||||
|
int argnum = 1;
|
||||||
|
int argauto = 1;
|
||||||
|
// % = starts
|
||||||
|
// [0-9], -, +, \s, 0, #, . continue
|
||||||
|
// %, s, d, i, u, fF, eE, gG, xX, o, c, p, aA terminate
|
||||||
|
// various type flags are not supported. not like stuff like 'hh' modifier is to be used in the VM.
|
||||||
|
// the only combination that is parsed locally is %n$...
|
||||||
|
bool haveargnums = false;
|
||||||
|
for (size_t i = 0; i < fmtstring.Len(); i++)
|
||||||
|
{
|
||||||
|
char c = fmtstring[i];
|
||||||
|
if (in_fmt)
|
||||||
|
{
|
||||||
|
if (c == '*' && (fmt_current.Len() == 1 || (fmt_current.Len() == 2 && fmt_current[1] == '0')))
|
||||||
|
{
|
||||||
|
fmt_current += c;
|
||||||
|
}
|
||||||
|
else if ((c >= '0' && c <= '9') ||
|
||||||
|
c == '-' || c == '+' || (c == ' ' && fmt_current.Back() != ' ') || c == '#' || c == '.')
|
||||||
|
{
|
||||||
|
fmt_current += c;
|
||||||
|
}
|
||||||
|
else if (c == '$') // %number$format
|
||||||
|
{
|
||||||
|
if (!haveargnums && argauto > 1)
|
||||||
|
ThrowAbortException(X_FORMAT_ERROR, "Cannot mix explicit and implicit arguments.");
|
||||||
|
FString argnumstr = fmt_current.Mid(1);
|
||||||
|
if (!argnumstr.IsInt()) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for argument number, got '%s'.", argnumstr.GetChars());
|
||||||
|
auto argnum64 = argnumstr.ToLong();
|
||||||
|
if (argnum64 < 1 || argnum64 >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format (tried to access argument %d, %d total).", argnum64, numparam);
|
||||||
|
fmt_current = "%";
|
||||||
|
haveargnums = true;
|
||||||
|
argnum = int(argnum64);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fmt_current += c;
|
||||||
|
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
// string
|
||||||
|
case 's':
|
||||||
|
{
|
||||||
|
if (argnum < 0 && haveargnums)
|
||||||
|
ThrowAbortException(X_FORMAT_ERROR, "Cannot mix explicit and implicit arguments.");
|
||||||
|
in_fmt = false;
|
||||||
|
// fail if something was found, but it's not a string
|
||||||
|
if (argnum >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format.");
|
||||||
|
if (va_reginfo[argnum] != REGT_STRING) ThrowAbortException(X_FORMAT_ERROR, "Expected a string for format %s.", fmt_current.GetChars());
|
||||||
|
// append
|
||||||
|
output.AppendFormat(fmt_current.GetChars(), param[argnum].s().GetChars());
|
||||||
|
if (!haveargnums) argnum = ++argauto;
|
||||||
|
else argnum = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pointer
|
||||||
|
case 'p':
|
||||||
|
{
|
||||||
|
if (argnum < 0 && haveargnums)
|
||||||
|
ThrowAbortException(X_FORMAT_ERROR, "Cannot mix explicit and implicit arguments.");
|
||||||
|
in_fmt = false;
|
||||||
|
// fail if something was found, but it's not a string
|
||||||
|
if (argnum >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format.");
|
||||||
|
if (va_reginfo[argnum] != REGT_POINTER) ThrowAbortException(X_FORMAT_ERROR, "Expected a pointer for format %s.", fmt_current.GetChars());
|
||||||
|
// append
|
||||||
|
output.AppendFormat(fmt_current.GetChars(), param[argnum].a);
|
||||||
|
if (!haveargnums) argnum = ++argauto;
|
||||||
|
else argnum = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// int formats (including char)
|
||||||
|
case 'd':
|
||||||
|
case 'i':
|
||||||
|
case 'u':
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
case 'o':
|
||||||
|
case 'c':
|
||||||
|
case 'B':
|
||||||
|
{
|
||||||
|
if (argnum < 0 && haveargnums)
|
||||||
|
ThrowAbortException(X_FORMAT_ERROR, "Cannot mix explicit and implicit arguments.");
|
||||||
|
in_fmt = false;
|
||||||
|
// append
|
||||||
|
if (fmt_current[1] == '*' || fmt_current[2] == '*')
|
||||||
|
{
|
||||||
|
// fail if something was found, but it's not an int
|
||||||
|
if (argnum+1 >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format.");
|
||||||
|
if (va_reginfo[argnum] != REGT_INT &&
|
||||||
|
va_reginfo[argnum] != REGT_FLOAT) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for format %s.", fmt_current.GetChars());
|
||||||
|
if (va_reginfo[argnum+1] != REGT_INT &&
|
||||||
|
va_reginfo[argnum+1] != REGT_FLOAT) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for format %s.", fmt_current.GetChars());
|
||||||
|
|
||||||
|
output.AppendFormat(fmt_current.GetChars(), param[argnum].ToInt(va_reginfo[argnum]), param[argnum + 1].ToInt(va_reginfo[argnum + 1]));
|
||||||
|
argauto++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// fail if something was found, but it's not an int
|
||||||
|
if (argnum >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format.");
|
||||||
|
if (va_reginfo[argnum] != REGT_INT &&
|
||||||
|
va_reginfo[argnum] != REGT_FLOAT) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for format %s.", fmt_current.GetChars());
|
||||||
|
output.AppendFormat(fmt_current.GetChars(), param[argnum].ToInt(va_reginfo[argnum]));
|
||||||
|
}
|
||||||
|
if (!haveargnums) argnum = ++argauto;
|
||||||
|
else argnum = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// double formats
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
case 'g':
|
||||||
|
case 'G':
|
||||||
|
case 'a':
|
||||||
|
case 'A':
|
||||||
|
{
|
||||||
|
if (argnum < 0 && haveargnums)
|
||||||
|
ThrowAbortException(X_FORMAT_ERROR, "Cannot mix explicit and implicit arguments.");
|
||||||
|
in_fmt = false;
|
||||||
|
if (fmt_current[1] == '*' || fmt_current[2] == '*')
|
||||||
|
{
|
||||||
|
// fail if something was found, but it's not an int
|
||||||
|
if (argnum + 1 >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format.");
|
||||||
|
if (va_reginfo[argnum] != REGT_INT &&
|
||||||
|
va_reginfo[argnum] != REGT_FLOAT) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for format %s.", fmt_current.GetChars());
|
||||||
|
if (va_reginfo[argnum + 1] != REGT_INT &&
|
||||||
|
va_reginfo[argnum + 1] != REGT_FLOAT) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for format %s.", fmt_current.GetChars());
|
||||||
|
|
||||||
|
output.AppendFormat(fmt_current.GetChars(), param[argnum].ToInt(va_reginfo[argnum]), param[argnum + 1].ToDouble(va_reginfo[argnum + 1]));
|
||||||
|
argauto++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// fail if something was found, but it's not a float
|
||||||
|
if (argnum >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format.");
|
||||||
|
if (va_reginfo[argnum] != REGT_INT &&
|
||||||
|
va_reginfo[argnum] != REGT_FLOAT) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for format %s.", fmt_current.GetChars());
|
||||||
|
// append
|
||||||
|
output.AppendFormat(fmt_current.GetChars(), param[argnum].ToDouble(va_reginfo[argnum]));
|
||||||
|
}
|
||||||
|
if (!haveargnums) argnum = ++argauto;
|
||||||
|
else argnum = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// invalid character
|
||||||
|
output += fmt_current;
|
||||||
|
in_fmt = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (c == '%')
|
||||||
|
{
|
||||||
|
if (i + 1 < fmtstring.Len() && fmtstring[i + 1] == '%')
|
||||||
|
{
|
||||||
|
output += '%';
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in_fmt = true;
|
||||||
|
fmt_current = "%";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(FStringStruct, Format)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
FString s = FStringFormat(VM_ARGS_NAMES);
|
||||||
|
ACTION_RETURN_STRING(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(FStringStruct, AppendFormat)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
||||||
|
// first parameter is the self pointer
|
||||||
|
FString s = FStringFormat(VM_ARGS_NAMES, 1);
|
||||||
|
(*self) += s;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(FStringStruct, AppendCharacter)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
||||||
|
PARAM_INT(c);
|
||||||
|
self->AppendCharacter(c);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(FStringStruct, DeleteLastCharacter)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
||||||
|
self->DeleteLastCharacter();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
#include "jit.h"
|
#include "jit.h"
|
||||||
#include "jitintern.h"
|
#include "jitintern.h"
|
||||||
|
#include "printf.h"
|
||||||
|
|
||||||
extern PString *TypeString;
|
extern PString *TypeString;
|
||||||
extern PStruct *TypeVector2;
|
extern PStruct *TypeVector2;
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
#include "jitintern.h"
|
#include "jitintern.h"
|
||||||
|
#include "basics.h"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// String instructions.
|
// String instructions.
|
|
@ -1,8 +1,7 @@
|
||||||
|
|
||||||
#include "jitintern.h"
|
#include "jitintern.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "s_sound.h"
|
#include "s_soundinternal.h"
|
||||||
#include "r_state.h"
|
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
|
|
||||||
void JitCompiler::EmitMOVE()
|
void JitCompiler::EmitMOVE()
|
||||||
|
@ -52,8 +51,8 @@ static void CastN2S(FString *a, int b) { FName name = FName(ENamedName(b)); *a =
|
||||||
static int CastS2Co(FString *b) { return V_GetColor(nullptr, *b); }
|
static int CastS2Co(FString *b) { return V_GetColor(nullptr, *b); }
|
||||||
static void CastCo2S(FString *a, int b) { PalEntry c(b); a->Format("%02x %02x %02x", c.r, c.g, c.b); }
|
static void CastCo2S(FString *a, int b) { PalEntry c(b); a->Format("%02x %02x %02x", c.r, c.g, c.b); }
|
||||||
static int CastS2So(FString *b) { return FSoundID(*b); }
|
static int CastS2So(FString *b) { return FSoundID(*b); }
|
||||||
static void CastSo2S(FString* a, int b) { *a = S_GetSoundName(b); }
|
static void CastSo2S(FString* a, int b) { *a = soundEngine->GetSoundName(b); }
|
||||||
static void CastSID2S(FString *a, unsigned int b) { *a = (b >= sprites.Size()) ? "TNT1" : sprites[b].name; }
|
static void CastSID2S(FString* a, unsigned int b) { VM_CastSpriteIDToString(a, b); }
|
||||||
static void CastTID2S(FString *a, int b) { auto tex = TexMan.GetTexture(*(FTextureID*)&b); *a = (tex == nullptr) ? "(null)" : tex->GetName().GetChars(); }
|
static void CastTID2S(FString *a, int b) { auto tex = TexMan.GetTexture(*(FTextureID*)&b); *a = (tex == nullptr) ? "(null)" : tex->GetName().GetChars(); }
|
||||||
|
|
||||||
void JitCompiler::EmitCAST()
|
void JitCompiler::EmitCAST()
|
|
@ -56,7 +56,7 @@ static void *AllocJitMemory(size_t size)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const size_t bytesToAllocate = MAX(size_t(1024 * 1024), size);
|
const size_t bytesToAllocate = std::max(size_t(1024 * 1024), size);
|
||||||
size_t allocatedSize = 0;
|
size_t allocatedSize = 0;
|
||||||
void *p = OSUtils::allocVirtualMemory(bytesToAllocate, &allocatedSize, OSUtils::kVMWritable | OSUtils::kVMExecutable);
|
void *p = OSUtils::allocVirtualMemory(bytesToAllocate, &allocatedSize, OSUtils::kVMWritable | OSUtils::kVMExecutable);
|
||||||
if (!p)
|
if (!p)
|
|
@ -43,7 +43,7 @@
|
||||||
#include "engineerrors.h"
|
#include "engineerrors.h"
|
||||||
#include "memarena.h"
|
#include "memarena.h"
|
||||||
#include "name.h"
|
#include "name.h"
|
||||||
#include "scripting/backend/scopebarrier.h"
|
#include "scopebarrier.h"
|
||||||
|
|
||||||
class DObject;
|
class DObject;
|
||||||
union VMOP;
|
union VMOP;
|
||||||
|
@ -56,6 +56,8 @@ extern FMemArena ClassDataAllocator;
|
||||||
|
|
||||||
void JitRelease();
|
void JitRelease();
|
||||||
|
|
||||||
|
extern void (*VM_CastSpriteIDToString)(FString* a, unsigned int b);
|
||||||
|
|
||||||
|
|
||||||
typedef unsigned char VM_UBYTE;
|
typedef unsigned char VM_UBYTE;
|
||||||
typedef signed char VM_SBYTE;
|
typedef signed char VM_SBYTE;
|
|
@ -32,17 +32,23 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <v_video.h>
|
#include <assert.h>
|
||||||
#include <s_sound.h>
|
#include "v_video.h"
|
||||||
#include "r_state.h"
|
#include "s_soundinternal.h"
|
||||||
|
#include "basics.h"
|
||||||
|
//#include "r_state.h"
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
#include "vmintern.h"
|
#include "vmintern.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "basics.h"
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
|
|
||||||
extern cycle_t VMCycles[10];
|
extern cycle_t VMCycles[10];
|
||||||
extern int VMCalls[10];
|
extern int VMCalls[10];
|
||||||
|
|
||||||
|
// THe sprite ID to string cast is game specific so let's do it with a callback to remove the dependency and allow easier reuse.
|
||||||
|
void (*VM_CastSpriteIDToString)(FString* a, unsigned int b) = [](FString* a, unsigned int b) { a->Format("%d", b); };
|
||||||
|
|
||||||
// intentionally implemented in a different source file to prevent inlining.
|
// intentionally implemented in a different source file to prevent inlining.
|
||||||
#if 0
|
#if 0
|
||||||
void ThrowVMException(VMException *x);
|
void ThrowVMException(VMException *x);
|
|
@ -1837,12 +1837,12 @@ static void DoCast(const VMRegisters ®, const VMFrame *f, int a, int b, int c
|
||||||
|
|
||||||
case CAST_So2S:
|
case CAST_So2S:
|
||||||
ASSERTS(a); ASSERTD(b);
|
ASSERTS(a); ASSERTD(b);
|
||||||
reg.s[a] = S_GetSoundName(reg.d[b]);
|
reg.s[a] = soundEngine->GetSoundName(reg.d[b]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAST_SID2S:
|
case CAST_SID2S:
|
||||||
ASSERTS(a); ASSERTD(b);
|
ASSERTS(a); ASSERTD(b);
|
||||||
reg.s[a] = unsigned(reg.d[b]) >= sprites.Size() ? "TNT1" : sprites[reg.d[b]].name;
|
VM_CastSpriteIDToString(®.s[a], reg.d[b]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAST_TID2S:
|
case CAST_TID2S:
|
|
@ -1,5 +1,4 @@
|
||||||
#ifndef __BASICS_H
|
#pragma once
|
||||||
#define __BASICS_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -56,7 +55,6 @@ typedef uint32_t angle_t;
|
||||||
|
|
||||||
using INTBOOL = int;
|
using INTBOOL = int;
|
||||||
using BITFIELD = uint32_t;
|
using BITFIELD = uint32_t;
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
@ -64,3 +62,45 @@ using BITFIELD = uint32_t;
|
||||||
#else
|
#else
|
||||||
#define NOVTABLE
|
#define NOVTABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// always use our own definition for consistency.
|
||||||
|
#ifdef M_PI
|
||||||
|
#undef M_PI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const double M_PI = 3.14159265358979323846; // matches value in gcc v2 math.h
|
||||||
|
|
||||||
|
inline float DEG2RAD(float deg)
|
||||||
|
{
|
||||||
|
return deg * float(M_PI / 180.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double DEG2RAD(double deg)
|
||||||
|
{
|
||||||
|
return deg * (M_PI / 180.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float RAD2DEG(float deg)
|
||||||
|
{
|
||||||
|
return deg * float(180. / M_PI);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Auto-registration sections for GCC.
|
||||||
|
// Apparently, you cannot do string concatenation inside section attributes.
|
||||||
|
#ifdef __MACH__
|
||||||
|
#define SECTION_AREG "__DATA,areg"
|
||||||
|
#define SECTION_CREG "__DATA,creg"
|
||||||
|
#define SECTION_FREG "__DATA,freg"
|
||||||
|
#define SECTION_GREG "__DATA,greg"
|
||||||
|
#define SECTION_MREG "__DATA,mreg"
|
||||||
|
#define SECTION_YREG "__DATA,yreg"
|
||||||
|
#else
|
||||||
|
#define SECTION_AREG "areg"
|
||||||
|
#define SECTION_CREG "creg"
|
||||||
|
#define SECTION_FREG "freg"
|
||||||
|
#define SECTION_GREG "greg"
|
||||||
|
#define SECTION_MREG "mreg"
|
||||||
|
#define SECTION_YREG "yreg"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -2743,6 +2743,10 @@ int PalCheck(int tex)
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Doom_CastSpriteIDToString(FString* a, unsigned int b)
|
||||||
|
{
|
||||||
|
*a = (b >= sprites.Size()) ? "TNT1" : sprites[b].name;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -2760,6 +2764,8 @@ static int D_DoomMain_Internal (void)
|
||||||
int argcount;
|
int argcount;
|
||||||
FIWadManager *iwad_man;
|
FIWadManager *iwad_man;
|
||||||
|
|
||||||
|
VM_CastSpriteIDToString = Doom_CastSpriteIDToString;
|
||||||
|
|
||||||
// Set up the button list. Mlook and Klook need a bit of extra treatment.
|
// Set up the button list. Mlook and Klook need a bit of extra treatment.
|
||||||
buttonMap.SetButtons(DoomButtons, countof(DoomButtons));
|
buttonMap.SetButtons(DoomButtons, countof(DoomButtons));
|
||||||
buttonMap.GetButton(Button_Mlook)->ReleaseHandler = Mlook_ReleaseHandler;
|
buttonMap.GetButton(Button_Mlook)->ReleaseHandler = Mlook_ReleaseHandler;
|
||||||
|
|
|
@ -52,45 +52,4 @@ enum class ELightMode : int8_t
|
||||||
DoomSoftware = 16
|
DoomSoftware = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
// always use our own definition for consistency.
|
|
||||||
#ifdef M_PI
|
|
||||||
#undef M_PI
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const double M_PI = 3.14159265358979323846; // matches value in gcc v2 math.h
|
|
||||||
|
|
||||||
inline float DEG2RAD(float deg)
|
|
||||||
{
|
|
||||||
return deg * float(M_PI / 180.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double DEG2RAD(double deg)
|
|
||||||
{
|
|
||||||
return deg * (M_PI / 180.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline float RAD2DEG(float deg)
|
|
||||||
{
|
|
||||||
return deg * float(180. / M_PI);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Auto-registration sections for GCC.
|
|
||||||
// Apparently, you cannot do string concatenation inside section attributes.
|
|
||||||
#ifdef __MACH__
|
|
||||||
#define SECTION_AREG "__DATA,areg"
|
|
||||||
#define SECTION_CREG "__DATA,creg"
|
|
||||||
#define SECTION_FREG "__DATA,freg"
|
|
||||||
#define SECTION_GREG "__DATA,greg"
|
|
||||||
#define SECTION_MREG "__DATA,mreg"
|
|
||||||
#define SECTION_YREG "__DATA,yreg"
|
|
||||||
#else
|
|
||||||
#define SECTION_AREG "areg"
|
|
||||||
#define SECTION_CREG "creg"
|
|
||||||
#define SECTION_FREG "freg"
|
|
||||||
#define SECTION_GREG "greg"
|
|
||||||
#define SECTION_MREG "mreg"
|
|
||||||
#define SECTION_YREG "yreg"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "c_buttons.h"
|
#include "c_buttons.h"
|
||||||
#include "scripting/types.h"
|
#include "types.h"
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
|
|
||||||
int DMenu::InMenu;
|
int DMenu::InMenu;
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
#include "p_destructible.h"
|
#include "p_destructible.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "i_time.h"
|
#include "i_time.h"
|
||||||
#include "scripting/vm/vm.h"
|
#include "vm.h"
|
||||||
#include "a_specialspot.h"
|
#include "a_specialspot.h"
|
||||||
#include "maploader/maploader.h"
|
#include "maploader/maploader.h"
|
||||||
#include "p_acs.h"
|
#include "p_acs.h"
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
#include "hw_clipper.h"
|
#include "hw_clipper.h"
|
||||||
#include "g_levellocals.h"
|
#include "g_levellocals.h"
|
||||||
|
#include "basics.h"
|
||||||
|
|
||||||
unsigned Clipper::starttime;
|
unsigned Clipper::starttime;
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "r_data/models/models.h"
|
#include "r_data/models/models.h"
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
|
#include "basics.h"
|
||||||
|
|
||||||
#include "hwrenderer/models/hw_models.h"
|
#include "hwrenderer/models/hw_models.h"
|
||||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#include "codegen.h"
|
#include "codegen.h"
|
||||||
#include "m_argv.h"
|
#include "m_argv.h"
|
||||||
#include "c_cvars.h"
|
#include "c_cvars.h"
|
||||||
#include "scripting/vm/jit.h"
|
#include "jit.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, strictdecorate);
|
EXTERN_CVAR(Bool, strictdecorate);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "dictionary.h"
|
#include "dictionary.h"
|
||||||
|
|
||||||
#include "scripting/vm/vm.h"
|
#include "vm.h"
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
|
@ -949,233 +949,3 @@ DEFINE_ACTION_FUNCTION(DObject, BAM)
|
||||||
ACTION_RETURN_INT(DAngle(ang).BAMs());
|
ACTION_RETURN_INT(DAngle(ang).BAMs());
|
||||||
}
|
}
|
||||||
|
|
||||||
FString FStringFormat(VM_ARGS, int offset)
|
|
||||||
{
|
|
||||||
PARAM_VA_POINTER(va_reginfo) // Get the hidden type information array
|
|
||||||
assert(va_reginfo[offset] == REGT_STRING);
|
|
||||||
|
|
||||||
FString fmtstring = param[offset].s().GetChars();
|
|
||||||
|
|
||||||
param += offset;
|
|
||||||
numparam -= offset;
|
|
||||||
va_reginfo += offset;
|
|
||||||
|
|
||||||
// note: we don't need a real printf format parser.
|
|
||||||
// enough to simply find the subtitution tokens and feed them to the real printf after checking types.
|
|
||||||
// https://en.wikipedia.org/wiki/Printf_format_string#Format_placeholder_specification
|
|
||||||
FString output;
|
|
||||||
bool in_fmt = false;
|
|
||||||
FString fmt_current;
|
|
||||||
int argnum = 1;
|
|
||||||
int argauto = 1;
|
|
||||||
// % = starts
|
|
||||||
// [0-9], -, +, \s, 0, #, . continue
|
|
||||||
// %, s, d, i, u, fF, eE, gG, xX, o, c, p, aA terminate
|
|
||||||
// various type flags are not supported. not like stuff like 'hh' modifier is to be used in the VM.
|
|
||||||
// the only combination that is parsed locally is %n$...
|
|
||||||
bool haveargnums = false;
|
|
||||||
for (size_t i = 0; i < fmtstring.Len(); i++)
|
|
||||||
{
|
|
||||||
char c = fmtstring[i];
|
|
||||||
if (in_fmt)
|
|
||||||
{
|
|
||||||
if (c == '*' && (fmt_current.Len() == 1 || (fmt_current.Len() == 2 && fmt_current[1] == '0')))
|
|
||||||
{
|
|
||||||
fmt_current += c;
|
|
||||||
}
|
|
||||||
else if ((c >= '0' && c <= '9') ||
|
|
||||||
c == '-' || c == '+' || (c == ' ' && fmt_current.Back() != ' ') || c == '#' || c == '.')
|
|
||||||
{
|
|
||||||
fmt_current += c;
|
|
||||||
}
|
|
||||||
else if (c == '$') // %number$format
|
|
||||||
{
|
|
||||||
if (!haveargnums && argauto > 1)
|
|
||||||
ThrowAbortException(X_FORMAT_ERROR, "Cannot mix explicit and implicit arguments.");
|
|
||||||
FString argnumstr = fmt_current.Mid(1);
|
|
||||||
if (!argnumstr.IsInt()) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for argument number, got '%s'.", argnumstr.GetChars());
|
|
||||||
auto argnum64 = argnumstr.ToLong();
|
|
||||||
if (argnum64 < 1 || argnum64 >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format (tried to access argument %d, %d total).", argnum64, numparam);
|
|
||||||
fmt_current = "%";
|
|
||||||
haveargnums = true;
|
|
||||||
argnum = int(argnum64);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fmt_current += c;
|
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
// string
|
|
||||||
case 's':
|
|
||||||
{
|
|
||||||
if (argnum < 0 && haveargnums)
|
|
||||||
ThrowAbortException(X_FORMAT_ERROR, "Cannot mix explicit and implicit arguments.");
|
|
||||||
in_fmt = false;
|
|
||||||
// fail if something was found, but it's not a string
|
|
||||||
if (argnum >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format.");
|
|
||||||
if (va_reginfo[argnum] != REGT_STRING) ThrowAbortException(X_FORMAT_ERROR, "Expected a string for format %s.", fmt_current.GetChars());
|
|
||||||
// append
|
|
||||||
output.AppendFormat(fmt_current.GetChars(), param[argnum].s().GetChars());
|
|
||||||
if (!haveargnums) argnum = ++argauto;
|
|
||||||
else argnum = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pointer
|
|
||||||
case 'p':
|
|
||||||
{
|
|
||||||
if (argnum < 0 && haveargnums)
|
|
||||||
ThrowAbortException(X_FORMAT_ERROR, "Cannot mix explicit and implicit arguments.");
|
|
||||||
in_fmt = false;
|
|
||||||
// fail if something was found, but it's not a string
|
|
||||||
if (argnum >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format.");
|
|
||||||
if (va_reginfo[argnum] != REGT_POINTER) ThrowAbortException(X_FORMAT_ERROR, "Expected a pointer for format %s.", fmt_current.GetChars());
|
|
||||||
// append
|
|
||||||
output.AppendFormat(fmt_current.GetChars(), param[argnum].a);
|
|
||||||
if (!haveargnums) argnum = ++argauto;
|
|
||||||
else argnum = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// int formats (including char)
|
|
||||||
case 'd':
|
|
||||||
case 'i':
|
|
||||||
case 'u':
|
|
||||||
case 'x':
|
|
||||||
case 'X':
|
|
||||||
case 'o':
|
|
||||||
case 'c':
|
|
||||||
case 'B':
|
|
||||||
{
|
|
||||||
if (argnum < 0 && haveargnums)
|
|
||||||
ThrowAbortException(X_FORMAT_ERROR, "Cannot mix explicit and implicit arguments.");
|
|
||||||
in_fmt = false;
|
|
||||||
// append
|
|
||||||
if (fmt_current[1] == '*' || fmt_current[2] == '*')
|
|
||||||
{
|
|
||||||
// fail if something was found, but it's not an int
|
|
||||||
if (argnum+1 >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format.");
|
|
||||||
if (va_reginfo[argnum] != REGT_INT &&
|
|
||||||
va_reginfo[argnum] != REGT_FLOAT) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for format %s.", fmt_current.GetChars());
|
|
||||||
if (va_reginfo[argnum+1] != REGT_INT &&
|
|
||||||
va_reginfo[argnum+1] != REGT_FLOAT) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for format %s.", fmt_current.GetChars());
|
|
||||||
|
|
||||||
output.AppendFormat(fmt_current.GetChars(), param[argnum].ToInt(va_reginfo[argnum]), param[argnum + 1].ToInt(va_reginfo[argnum + 1]));
|
|
||||||
argauto++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// fail if something was found, but it's not an int
|
|
||||||
if (argnum >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format.");
|
|
||||||
if (va_reginfo[argnum] != REGT_INT &&
|
|
||||||
va_reginfo[argnum] != REGT_FLOAT) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for format %s.", fmt_current.GetChars());
|
|
||||||
output.AppendFormat(fmt_current.GetChars(), param[argnum].ToInt(va_reginfo[argnum]));
|
|
||||||
}
|
|
||||||
if (!haveargnums) argnum = ++argauto;
|
|
||||||
else argnum = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// double formats
|
|
||||||
case 'f':
|
|
||||||
case 'F':
|
|
||||||
case 'e':
|
|
||||||
case 'E':
|
|
||||||
case 'g':
|
|
||||||
case 'G':
|
|
||||||
case 'a':
|
|
||||||
case 'A':
|
|
||||||
{
|
|
||||||
if (argnum < 0 && haveargnums)
|
|
||||||
ThrowAbortException(X_FORMAT_ERROR, "Cannot mix explicit and implicit arguments.");
|
|
||||||
in_fmt = false;
|
|
||||||
if (fmt_current[1] == '*' || fmt_current[2] == '*')
|
|
||||||
{
|
|
||||||
// fail if something was found, but it's not an int
|
|
||||||
if (argnum + 1 >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format.");
|
|
||||||
if (va_reginfo[argnum] != REGT_INT &&
|
|
||||||
va_reginfo[argnum] != REGT_FLOAT) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for format %s.", fmt_current.GetChars());
|
|
||||||
if (va_reginfo[argnum + 1] != REGT_INT &&
|
|
||||||
va_reginfo[argnum + 1] != REGT_FLOAT) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for format %s.", fmt_current.GetChars());
|
|
||||||
|
|
||||||
output.AppendFormat(fmt_current.GetChars(), param[argnum].ToInt(va_reginfo[argnum]), param[argnum + 1].ToDouble(va_reginfo[argnum + 1]));
|
|
||||||
argauto++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// fail if something was found, but it's not a float
|
|
||||||
if (argnum >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format.");
|
|
||||||
if (va_reginfo[argnum] != REGT_INT &&
|
|
||||||
va_reginfo[argnum] != REGT_FLOAT) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for format %s.", fmt_current.GetChars());
|
|
||||||
// append
|
|
||||||
output.AppendFormat(fmt_current.GetChars(), param[argnum].ToDouble(va_reginfo[argnum]));
|
|
||||||
}
|
|
||||||
if (!haveargnums) argnum = ++argauto;
|
|
||||||
else argnum = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
// invalid character
|
|
||||||
output += fmt_current;
|
|
||||||
in_fmt = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (c == '%')
|
|
||||||
{
|
|
||||||
if (i + 1 < fmtstring.Len() && fmtstring[i + 1] == '%')
|
|
||||||
{
|
|
||||||
output += '%';
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
in_fmt = true;
|
|
||||||
fmt_current = "%";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
output += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(FStringStruct, Format)
|
|
||||||
{
|
|
||||||
PARAM_PROLOGUE;
|
|
||||||
FString s = FStringFormat(VM_ARGS_NAMES);
|
|
||||||
ACTION_RETURN_STRING(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(FStringStruct, AppendFormat)
|
|
||||||
{
|
|
||||||
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
|
||||||
// first parameter is the self pointer
|
|
||||||
FString s = FStringFormat(VM_ARGS_NAMES, 1);
|
|
||||||
(*self) += s;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(FStringStruct, AppendCharacter)
|
|
||||||
{
|
|
||||||
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
|
||||||
PARAM_INT(c);
|
|
||||||
self->AppendCharacter(c);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(FStringStruct, DeleteLastCharacter)
|
|
||||||
{
|
|
||||||
PARAM_SELF_STRUCT_PROLOGUE(FString);
|
|
||||||
self->DeleteLastCharacter();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1673,7 +1673,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundI
|
||||||
if (!arc.w->inObject() || def == nullptr || sid != *def)
|
if (!arc.w->inObject() || def == nullptr || sid != *def)
|
||||||
{
|
{
|
||||||
arc.WriteKey(key);
|
arc.WriteKey(key);
|
||||||
const char *sn = S_GetSoundName(sid);
|
const char *sn = soundEngine->GetSoundName(sid);
|
||||||
if (sn != nullptr) arc.w->String(sn);
|
if (sn != nullptr) arc.w->String(sn);
|
||||||
else arc.w->Null();
|
else arc.w->Null();
|
||||||
}
|
}
|
||||||
|
@ -2088,7 +2088,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, char *&pstr
|
||||||
//
|
//
|
||||||
// This is a bit of a cheat because it never actually writes out the pointer.
|
// This is a bit of a cheat because it never actually writes out the pointer.
|
||||||
// The rules for levels are that they must be self-contained.
|
// The rules for levels are that they must be self-contained.
|
||||||
// No level and no pbject that is part of a level may reference a different one.
|
// No level and no object that is part of a level may reference a different one.
|
||||||
//
|
//
|
||||||
// When writing, this merely checks if the rules are obeyed and if not errors out.
|
// When writing, this merely checks if the rules are obeyed and if not errors out.
|
||||||
// When reading, it assumes that the object was properly written and restores
|
// When reading, it assumes that the object was properly written and restores
|
||||||
|
|
|
@ -79,12 +79,3 @@ inline const char* S_GetSoundName(FSoundID id)
|
||||||
return soundEngine->GetSoundName(id);
|
return soundEngine->GetSoundName(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int S_FindSound(const char* logicalname)
|
|
||||||
{
|
|
||||||
return soundEngine->FindSound(logicalname);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int S_FindSoundByResID(int rid)
|
|
||||||
{
|
|
||||||
return soundEngine->FindSoundByResID(rid);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue