mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
Merge branch 'master' into json
This commit is contained in:
commit
65c6388d44
48 changed files with 662 additions and 445 deletions
|
@ -14,6 +14,11 @@ list( APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} )
|
|||
include( CreateLaunchers )
|
||||
include( FindPackageHandleStandardArgs )
|
||||
|
||||
# Produce a warning if XP support will be missing.
|
||||
if( MSVC14 AND NOT CMAKE_GENERATOR_TOOLSET STREQUAL "v140_xp" )
|
||||
message( WARNING "This project supports Windows XP (including XP x64), but you must set the optional toolset to v140_xp manually to have it in your build! Use -T \"v140_xp\" from the command prompt." )
|
||||
endif()
|
||||
|
||||
# Support cross compiling
|
||||
option( FORCE_CROSSCOMPILE "Turn on cross compiling." NO )
|
||||
if( FORCE_CROSSCOMPILE )
|
||||
|
|
|
@ -114,59 +114,49 @@ if( WIN32 )
|
|||
set( FMOD_LIB_PATH_SUFFIXES PATH_SUFFIXES lib )
|
||||
set( NASM_NAMES nasmw nasm )
|
||||
|
||||
if( NOT MSVC )
|
||||
find_path( D3D_INCLUDE_DIR d3d9.h
|
||||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Include )
|
||||
if( NOT D3D_INCLUDE_DIR )
|
||||
message( SEND_ERROR "Could not find DirectX 9 header files" )
|
||||
else()
|
||||
include_directories( ${D3D_INCLUDE_DIR} )
|
||||
endif()
|
||||
|
||||
find_path( XINPUT_INCLUDE_DIR xinput.h
|
||||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Include )
|
||||
if( NOT XINPUT_INCLUDE_DIR )
|
||||
message( WARNING "Could not find xinput.h. XInput will be disabled." )
|
||||
add_definitions( -DNO_XINPUT )
|
||||
else()
|
||||
include_directories( ${XINPUT_INCLUDE_DIR} )
|
||||
endif()
|
||||
|
||||
find_library( DX_dxguid_LIBRARY dxguid
|
||||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Lib Lib/${XBITS} )
|
||||
find_library( DX_dinput8_LIBRARY dinput8
|
||||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Lib Lib/${XBITS} )
|
||||
|
||||
set( DX_LIBS_FOUND YES )
|
||||
if( NOT DX_dxguid_LIBRARY )
|
||||
set( DX_LIBS_FOUND NO )
|
||||
endif()
|
||||
if( NOT DX_dinput8_LIBRARY )
|
||||
set( DX_LIBS_FOUND NO )
|
||||
endif()
|
||||
|
||||
if( NOT DX_LIBS_FOUND )
|
||||
message( FATAL_ERROR "Could not find DirectX 9 libraries" )
|
||||
endif()
|
||||
|
||||
set( DX_LIBS
|
||||
"${DX_dxguid_LIBRARY}"
|
||||
"${DX_dinput8_LIBRARY}"
|
||||
)
|
||||
find_path( D3D_INCLUDE_DIR d3d9.h
|
||||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Include )
|
||||
if( NOT D3D_INCLUDE_DIR )
|
||||
message( SEND_ERROR "Could not find DirectX 9 header files" )
|
||||
else()
|
||||
set( DX_LIBS
|
||||
dxguid
|
||||
dinput8
|
||||
)
|
||||
include_directories( ${D3D_INCLUDE_DIR} )
|
||||
endif()
|
||||
|
||||
find_path( XINPUT_INCLUDE_DIR xinput.h
|
||||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Include )
|
||||
if( NOT XINPUT_INCLUDE_DIR )
|
||||
message( WARNING "Could not find xinput.h. XInput will be disabled." )
|
||||
add_definitions( -DNO_XINPUT )
|
||||
else()
|
||||
include_directories( ${XINPUT_INCLUDE_DIR} )
|
||||
endif()
|
||||
|
||||
set( ZDOOM_LIBS ${DX_LIBS}
|
||||
find_library( DX_dxguid_LIBRARY dxguid
|
||||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Lib Lib/${XBITS} )
|
||||
find_library( DX_dinput8_LIBRARY dinput8
|
||||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Lib Lib/${XBITS} )
|
||||
|
||||
set( DX_LIBS_FOUND YES )
|
||||
if( NOT DX_dxguid_LIBRARY )
|
||||
set( DX_LIBS_FOUND NO )
|
||||
endif()
|
||||
if( NOT DX_dinput8_LIBRARY )
|
||||
set( DX_LIBS_FOUND NO )
|
||||
endif()
|
||||
|
||||
if( NOT DX_LIBS_FOUND )
|
||||
message( FATAL_ERROR "Could not find DirectX 9 libraries" )
|
||||
endif()
|
||||
|
||||
set( ZDOOM_LIBS
|
||||
wsock32
|
||||
winmm
|
||||
"${DX_dxguid_LIBRARY}"
|
||||
"${DX_dinput8_LIBRARY}"
|
||||
ole32
|
||||
user32
|
||||
gdi32
|
||||
|
@ -272,6 +262,10 @@ if( NOT NO_FMOD )
|
|||
if( FMOD_INCLUDE_DIR )
|
||||
message( STATUS "FMOD include files found at ${FMOD_INCLUDE_DIR}" )
|
||||
include_directories( "${FMOD_INCLUDE_DIR}" )
|
||||
|
||||
if( EXISTS "${FMOD_INCLUDE_DIR}/fmod_common.h" )
|
||||
set( FMOD_STUDIO YES )
|
||||
endif()
|
||||
else()
|
||||
message( STATUS "Could not find FMOD include files" )
|
||||
set( NO_FMOD ON )
|
||||
|
@ -1341,7 +1335,16 @@ endif()
|
|||
|
||||
if( MSVC )
|
||||
option( ZDOOM_GENERATE_MAPFILE "Generate .map file for debugging." OFF )
|
||||
set( LINKERSTUFF "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\"" )
|
||||
set( LINKERSTUFF "/MANIFEST:NO" )
|
||||
|
||||
if( NOT NO_FMOD )
|
||||
if( FMOD_STUDIO )
|
||||
set( LINKERSTUFF "${LINKERSTUFF} /DELAYLOAD:\"fmod${X64}.dll\"" )
|
||||
else()
|
||||
set( LINKERSTUFF "${LINKERSTUFF} /DELAYLOAD:\"fmodex${X64}.dll\"" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if( ZDOOM_GENERATE_MAPFILE )
|
||||
set( LINKERSTUFF "${LINKERSTUFF} /MAP" )
|
||||
endif()
|
||||
|
@ -1381,17 +1384,23 @@ if( APPLE )
|
|||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/posix/osx/zdoom-info.plist" )
|
||||
|
||||
if( NOT NO_FMOD )
|
||||
if( FMOD_STUDIO )
|
||||
set( FMOD_DYLIB libfmod.dylib )
|
||||
else()
|
||||
set( FMOD_DYLIB libfmodex.dylib )
|
||||
endif()
|
||||
|
||||
# Fix fmod link so that it can be found in the app bundle.
|
||||
find_program( OTOOL otool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin" )
|
||||
find_program( INSTALL_NAME_TOOL install_name_tool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin" )
|
||||
execute_process( COMMAND "${OTOOL}" -L "${FMOD_LIBRARY}"
|
||||
COMMAND grep "libfmodex.dylib (compat"
|
||||
COMMAND grep "${FMOD_DYLIB} (compat"
|
||||
COMMAND head -n1
|
||||
COMMAND awk "{print $1}"
|
||||
OUTPUT_VARIABLE FMOD_LINK
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||
add_custom_command( TARGET zdoom POST_BUILD
|
||||
COMMAND "${INSTALL_NAME_TOOL}" -change "${FMOD_LINK}" @executable_path/../Frameworks/libfmodex.dylib "$<TARGET_FILE:zdoom>"
|
||||
COMMAND "${INSTALL_NAME_TOOL}" -change "${FMOD_LINK}" @executable_path/../Frameworks/${FMOD_DYLIB} "$<TARGET_FILE:zdoom>"
|
||||
COMMENT "Relinking FMOD Ex" )
|
||||
endif()
|
||||
endif()
|
||||
|
|
23
src/actor.h
23
src/actor.h
|
@ -111,6 +111,8 @@ struct FPortalGroupArray;
|
|||
// Any questions?
|
||||
//
|
||||
|
||||
|
||||
|
||||
// --- mobj.flags ---
|
||||
enum ActorFlag
|
||||
{
|
||||
|
@ -1015,7 +1017,9 @@ public:
|
|||
|
||||
SDWORD tics; // state tic counter
|
||||
FState *state;
|
||||
VMFunction *Damage; // For missiles and monster railgun
|
||||
//VMFunction *Damage; // For missiles and monster railgun
|
||||
int DamageVal;
|
||||
VMFunction *DamageFunc;
|
||||
int projectileKickback;
|
||||
ActorFlags flags;
|
||||
ActorFlags2 flags2; // Heretic flags
|
||||
|
@ -1203,6 +1207,23 @@ public:
|
|||
FState *GetRaiseState();
|
||||
void Revive();
|
||||
|
||||
void SetDamage(int dmg)
|
||||
{
|
||||
DamageVal = dmg;
|
||||
DamageFunc = nullptr;
|
||||
}
|
||||
|
||||
bool IsZeroDamage() const
|
||||
{
|
||||
return DamageVal == 0 && DamageFunc == nullptr;
|
||||
}
|
||||
|
||||
void RestoreDamage()
|
||||
{
|
||||
DamageVal = GetDefault()->DamageVal;
|
||||
DamageFunc = GetDefault()->DamageFunc;
|
||||
}
|
||||
|
||||
FState *FindState (FName label) const
|
||||
{
|
||||
return GetClass()->FindState(1, &label);
|
||||
|
|
|
@ -923,10 +923,21 @@ static bool IsActorACountItem(AActor *mo)
|
|||
return mo->IsKindOf(RUNTIME_CLASS(AInventory)) && mo->flags&MF_SPECIAL && mo->flags&MF_COUNTITEM;
|
||||
}
|
||||
|
||||
static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const char *FilterName)
|
||||
// [SP] for all actors
|
||||
static bool IsActor(AActor *mo)
|
||||
{
|
||||
if (mo->IsKindOf(RUNTIME_CLASS(AInventory)))
|
||||
return static_cast<AInventory *>(mo)->Owner == NULL; // [SP] Exclude inventory-owned items
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
// [SP] modified - now allows showing count only, new arg must be passed. Also now still counts regardless, if lists are printed.
|
||||
static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const char *FilterName, bool countOnly)
|
||||
{
|
||||
AActor *mo;
|
||||
const PClass *FilterClass = NULL;
|
||||
int counter = 0;
|
||||
|
||||
if (FilterName != NULL)
|
||||
{
|
||||
|
@ -943,10 +954,32 @@ static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const cha
|
|||
{
|
||||
if ((FilterClass == NULL || mo->IsA(FilterClass)) && IsActorType(mo))
|
||||
{
|
||||
Printf ("%s at (%f,%f,%f)\n",
|
||||
mo->GetClass()->TypeName.GetChars(), mo->X(), mo->Y(), mo->Z());
|
||||
counter++;
|
||||
if (!countOnly)
|
||||
Printf ("%s at (%f,%f,%f)\n",
|
||||
mo->GetClass()->TypeName.GetChars(), mo->X(), mo->Y(), mo->Z());
|
||||
}
|
||||
}
|
||||
Printf("%i match(s) found.\n", counter);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CCMD(actorlist) // [SP] print all actors (this can get quite big?)
|
||||
{
|
||||
if (CheckCheatmode ()) return;
|
||||
|
||||
PrintFilteredActorList(IsActor, argv.argc() > 1 ? argv[1] : NULL, false);
|
||||
}
|
||||
|
||||
CCMD(actornum) // [SP] count all actors
|
||||
{
|
||||
if (CheckCheatmode ()) return;
|
||||
|
||||
PrintFilteredActorList(IsActor, argv.argc() > 1 ? argv[1] : NULL, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -958,7 +991,14 @@ CCMD(monster)
|
|||
{
|
||||
if (CheckCheatmode ()) return;
|
||||
|
||||
PrintFilteredActorList(IsActorAMonster, argv.argc() > 1 ? argv[1] : NULL);
|
||||
PrintFilteredActorList(IsActorAMonster, argv.argc() > 1 ? argv[1] : NULL, false);
|
||||
}
|
||||
|
||||
CCMD(monsternum) // [SP] count monsters
|
||||
{
|
||||
if (CheckCheatmode ()) return;
|
||||
|
||||
PrintFilteredActorList(IsActorAMonster, argv.argc() > 1 ? argv[1] : NULL, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -970,7 +1010,14 @@ CCMD(items)
|
|||
{
|
||||
if (CheckCheatmode ()) return;
|
||||
|
||||
PrintFilteredActorList(IsActorAnItem, argv.argc() > 1 ? argv[1] : NULL);
|
||||
PrintFilteredActorList(IsActorAnItem, argv.argc() > 1 ? argv[1] : NULL, false);
|
||||
}
|
||||
|
||||
CCMD(itemsnum) // [SP] # of any items
|
||||
{
|
||||
if (CheckCheatmode ()) return;
|
||||
|
||||
PrintFilteredActorList(IsActorAnItem, argv.argc() > 1 ? argv[1] : NULL, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -982,7 +1029,14 @@ CCMD(countitems)
|
|||
{
|
||||
if (CheckCheatmode ()) return;
|
||||
|
||||
PrintFilteredActorList(IsActorACountItem, argv.argc() > 1 ? argv[1] : NULL);
|
||||
PrintFilteredActorList(IsActorACountItem, argv.argc() > 1 ? argv[1] : NULL, false);
|
||||
}
|
||||
|
||||
CCMD(countitemsnum) // [SP] # of counted items
|
||||
{
|
||||
if (CheckCheatmode ()) return;
|
||||
|
||||
PrintFilteredActorList(IsActorACountItem, argv.argc() > 1 ? argv[1] : NULL, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -1747,6 +1747,14 @@ void C_AddTabCommand (const char *name)
|
|||
|
||||
void C_RemoveTabCommand (const char *name)
|
||||
{
|
||||
if (TabCommands.Size() == 0)
|
||||
{
|
||||
// There are no tab commands that can be removed.
|
||||
// This is important to skip construction of aname
|
||||
// in case the NameManager has already been destroyed.
|
||||
return;
|
||||
}
|
||||
|
||||
FName aname(name, true);
|
||||
|
||||
if (aname == NAME_None)
|
||||
|
|
|
@ -915,7 +915,7 @@ static int PatchThing (int thingy)
|
|||
}
|
||||
else if (linelen == 14 && stricmp (Line1, "Missile damage") == 0)
|
||||
{
|
||||
info->Damage = CreateDamageFunction(val);
|
||||
info->SetDamage(val);
|
||||
}
|
||||
else if (linelen == 5)
|
||||
{
|
||||
|
|
|
@ -47,7 +47,7 @@ static void BrainishExplosion (const DVector3 &pos)
|
|||
boom->SetState (state);
|
||||
}
|
||||
boom->effects = 0;
|
||||
boom->Damage = NULL; // disables collision detection which is not wanted here
|
||||
boom->SetDamage(0); // disables collision detection which is not wanted here
|
||||
boom->tics -= pr_brainscream() & 7;
|
||||
if (boom->tics < 1)
|
||||
boom->tics = 1;
|
||||
|
|
|
@ -115,7 +115,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
|
|||
fire->target = baseFire->target;
|
||||
fire->Angles.Yaw = baseFire->Angles.Yaw;
|
||||
fire->Vel = baseFire->Vel;
|
||||
fire->Damage = NULL;
|
||||
fire->SetDamage(0);
|
||||
fire->health = (i+1) * 2;
|
||||
P_CheckMissileSpawn (fire, self->radius);
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichFireGrow)
|
|||
self->AddZ(9.);
|
||||
if (self->health == 0)
|
||||
{
|
||||
self->Damage = self->GetDefault()->Damage;
|
||||
self->RestoreDamage();
|
||||
self->SetState (self->FindState("NoGrow"));
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -340,7 +340,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LastZap)
|
|||
{
|
||||
mo->SetState (mo->FindState (NAME_Death));
|
||||
mo->Vel.Z = 40;
|
||||
mo->Damage = NULL;
|
||||
mo->SetDamage(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -291,10 +291,9 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger
|
|||
|
||||
if (!(quake->m_Flags & QF_WAVE))
|
||||
{
|
||||
jiggers.Falloff = MAX(falloff, jiggers.Falloff);
|
||||
jiggers.RollIntensity = MAX(r, jiggers.RollIntensity) * jiggers.Falloff;
|
||||
jiggers.RollIntensity = MAX(r, jiggers.RollIntensity) * falloff;
|
||||
|
||||
intensity *= jiggers.Falloff;
|
||||
intensity *= falloff;
|
||||
if (quake->m_Flags & QF_RELATIVE)
|
||||
{
|
||||
jiggers.RelIntensity.X = MAX(intensity.X, jiggers.RelIntensity.X);
|
||||
|
@ -310,14 +309,13 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger
|
|||
}
|
||||
else
|
||||
{
|
||||
jiggers.Falloff = MAX(falloff, jiggers.Falloff);
|
||||
jiggers.RollWave = r * quake->GetModWave(quake->m_RollWave) * jiggers.Falloff * strength;
|
||||
jiggers.RollWave = r * quake->GetModWave(quake->m_RollWave) * falloff * strength;
|
||||
|
||||
|
||||
intensity.X *= quake->GetModWave(quake->m_WaveSpeed.X);
|
||||
intensity.Y *= quake->GetModWave(quake->m_WaveSpeed.Y);
|
||||
intensity.Z *= quake->GetModWave(quake->m_WaveSpeed.Z);
|
||||
intensity *= strength * jiggers.Falloff;
|
||||
intensity *= strength * falloff;
|
||||
|
||||
// [RH] This only gives effect to the last sine quake. I would
|
||||
// prefer if some way was found to make multiples coexist
|
||||
|
|
|
@ -153,7 +153,6 @@ struct FQuakeJiggers
|
|||
DVector3 RelIntensity;
|
||||
DVector3 Offset;
|
||||
DVector3 RelOffset;
|
||||
double Falloff;
|
||||
double RollIntensity, RollWave;
|
||||
};
|
||||
|
||||
|
|
|
@ -1914,7 +1914,7 @@ class CommandAspectRatio : public SBarInfoCommandFlowControl
|
|||
{
|
||||
SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged);
|
||||
|
||||
SetTruth(ratioMap[CheckRatio(screen->GetWidth(), screen->GetHeight())] == ratio, block, statusBar);
|
||||
SetTruth(ratioMap[FindRatio()] == ratio, block, statusBar);
|
||||
}
|
||||
protected:
|
||||
enum Ratio
|
||||
|
@ -1931,6 +1931,37 @@ class CommandAspectRatio : public SBarInfoCommandFlowControl
|
|||
static Ratio ratioMap[5];
|
||||
|
||||
Ratio ratio;
|
||||
|
||||
private:
|
||||
int FindRatio()
|
||||
{
|
||||
float aspect = ActiveRatio(screen->GetWidth(), screen->GetHeight());
|
||||
|
||||
static std::pair<float, int> ratioTypes[] =
|
||||
{
|
||||
{ 21 / 9.0f , ASPECTRATIO_16_9 },
|
||||
{ 16 / 9.0f , ASPECTRATIO_16_9 },
|
||||
{ 17 / 10.0f , ASPECTRATIO_17_10 },
|
||||
{ 16 / 10.0f , ASPECTRATIO_16_10 },
|
||||
{ 4 / 3.0f , ASPECTRATIO_4_3 },
|
||||
{ 5 / 4.0f , ASPECTRATIO_5_4 },
|
||||
{ 0.0f, 0 }
|
||||
};
|
||||
|
||||
int ratio = ratioTypes[0].second;
|
||||
float distance = fabs(ratioTypes[0].first - aspect);
|
||||
for (int i = 1; ratioTypes[i].first != 0.0f; i++)
|
||||
{
|
||||
float d = fabs(ratioTypes[i].first - aspect);
|
||||
if (d < distance)
|
||||
{
|
||||
ratio = ratioTypes[i].second;
|
||||
distance = d;
|
||||
}
|
||||
}
|
||||
|
||||
return ratio;
|
||||
}
|
||||
};
|
||||
CommandAspectRatio::Ratio CommandAspectRatio::ratioMap[5] = {ASPECTRATIO_4_3,ASPECTRATIO_16_9,ASPECTRATIO_16_10,ASPECTRATIO_16_10,ASPECTRATIO_5_4};
|
||||
|
||||
|
|
|
@ -1108,13 +1108,13 @@ void DrawHUD()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (WidescreenRatio == 4)
|
||||
if (AspectTallerThanWide(WidescreenRatio))
|
||||
{
|
||||
hudheight = hudwidth * 30 / BaseRatioSizes[WidescreenRatio][3]; // BaseRatioSizes is inverted for this mode
|
||||
hudheight = hudwidth * 30 / AspectMultiplier(WidescreenRatio); // BaseRatioSizes is inverted for this mode
|
||||
}
|
||||
else
|
||||
{
|
||||
hudheight = hudwidth * 30 / (48*48/BaseRatioSizes[WidescreenRatio][3]);
|
||||
hudheight = hudwidth * 30 / (48*48/AspectMultiplier(WidescreenRatio));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -299,14 +299,15 @@ void DBaseStatusBar::SetScaled (bool scale, bool force)
|
|||
{
|
||||
ST_X = 0;
|
||||
ST_Y = VirticalResolution - RelTop;
|
||||
if (CheckRatio(SCREENWIDTH, SCREENHEIGHT) != 4)
|
||||
float aspect = ActiveRatio(SCREENWIDTH, SCREENHEIGHT);
|
||||
if (!AspectTallerThanWide(aspect))
|
||||
{ // Normal resolution
|
||||
::ST_Y = Scale (ST_Y, SCREENHEIGHT, VirticalResolution);
|
||||
}
|
||||
else
|
||||
{ // 5:4 resolution
|
||||
::ST_Y = Scale(ST_Y - VirticalResolution/2, SCREENHEIGHT*3, Scale(VirticalResolution, BaseRatioSizes[4][1], 200)) + SCREENHEIGHT/2
|
||||
+ (SCREENHEIGHT - SCREENHEIGHT * BaseRatioSizes[4][3] / 48) / 2;
|
||||
::ST_Y = Scale(ST_Y - VirticalResolution/2, SCREENHEIGHT*3, Scale(VirticalResolution, AspectBaseHeight(aspect), 200)) + SCREENHEIGHT/2
|
||||
+ (SCREENHEIGHT - SCREENHEIGHT * AspectMultiplier(aspect) / 48) / 2;
|
||||
}
|
||||
Displacement = 0;
|
||||
}
|
||||
|
@ -1035,10 +1036,10 @@ void DBaseStatusBar::DrSmallNumberOuter (int val, int x, int y, bool center) con
|
|||
|
||||
void DBaseStatusBar::RefreshBackground () const
|
||||
{
|
||||
int x, x2, y, ratio;
|
||||
int x, x2, y;
|
||||
|
||||
ratio = CheckRatio (SCREENWIDTH, SCREENHEIGHT);
|
||||
x = (!IsRatioWidescreen(ratio) || !Scaled) ? ST_X : SCREENWIDTH*(48-BaseRatioSizes[ratio][3])/(48*2);
|
||||
float ratio = ActiveRatio (SCREENWIDTH, SCREENHEIGHT);
|
||||
x = (ratio < 1.5f || !Scaled) ? ST_X : SCREENWIDTH*(48-AspectMultiplier(ratio))/(48*2);
|
||||
y = x == ST_X && x > 0 ? ST_Y : ::ST_Y;
|
||||
|
||||
if(!CompleteBorder)
|
||||
|
@ -1058,8 +1059,8 @@ void DBaseStatusBar::RefreshBackground () const
|
|||
{
|
||||
if(!CompleteBorder)
|
||||
{
|
||||
x2 = !IsRatioWidescreen(ratio) || !Scaled ? ST_X+HorizontalResolution :
|
||||
SCREENWIDTH - (SCREENWIDTH*(48-BaseRatioSizes[ratio][3])+48*2-1)/(48*2);
|
||||
x2 = ratio < 1.5f || !Scaled ? ST_X+HorizontalResolution :
|
||||
SCREENWIDTH - (SCREENWIDTH*(48-AspectMultiplier(ratio))+48*2-1)/(48*2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -344,7 +344,7 @@ size_t PClassActor::PropagateMark()
|
|||
// Mark damage function
|
||||
if (Defaults != NULL)
|
||||
{
|
||||
GC::Mark(((AActor *)Defaults)->Damage);
|
||||
GC::Mark(((AActor *)Defaults)->DamageFunc);
|
||||
}
|
||||
|
||||
// marked += ActorInfo->NumOwnedStates * sizeof(FState);
|
||||
|
|
|
@ -95,7 +95,7 @@ CUSTOM_CVAR (Int, menu_screenratios, -1, CVAR_ARCHIVE)
|
|||
}
|
||||
else
|
||||
{
|
||||
BuildModesList (SCREENWIDTH, SCREENHEIGHT, DisplayBits);
|
||||
BuildModesList (screen->VideoWidth, screen->VideoHeight, DisplayBits);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ public:
|
|||
|
||||
DVideoModeMenu()
|
||||
{
|
||||
SetModesMenu (SCREENWIDTH, SCREENHEIGHT, DisplayBits);
|
||||
SetModesMenu (screen->VideoWidth, screen->VideoHeight, DisplayBits);
|
||||
}
|
||||
|
||||
bool MenuEvent(int mkey, bool fromcontroller)
|
||||
|
@ -163,13 +163,13 @@ public:
|
|||
{
|
||||
if (!GetSelectedSize (&NewWidth, &NewHeight))
|
||||
{
|
||||
NewWidth = SCREENWIDTH;
|
||||
NewHeight = SCREENHEIGHT;
|
||||
NewWidth = screen->VideoWidth;
|
||||
NewHeight = screen->VideoHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
OldWidth = SCREENWIDTH;
|
||||
OldHeight = SCREENHEIGHT;
|
||||
OldWidth = screen->VideoWidth;
|
||||
OldHeight = screen->VideoHeight;
|
||||
OldBits = DisplayBits;
|
||||
NewBits = BitTranslate[DummyDepthCvar];
|
||||
setmodeneeded = true;
|
||||
|
@ -297,11 +297,11 @@ void M_RestoreMode ()
|
|||
void M_SetDefaultMode ()
|
||||
{
|
||||
// Make current resolution the default
|
||||
vid_defwidth = SCREENWIDTH;
|
||||
vid_defheight = SCREENHEIGHT;
|
||||
vid_defwidth = screen->VideoWidth;
|
||||
vid_defheight = screen->VideoHeight;
|
||||
vid_defbits = DisplayBits;
|
||||
testingmode = 0;
|
||||
SetModesMenu (SCREENWIDTH, SCREENHEIGHT, DisplayBits);
|
||||
SetModesMenu (screen->VideoWidth, screen->VideoHeight, DisplayBits);
|
||||
}
|
||||
|
||||
|
||||
|
@ -314,7 +314,7 @@ void M_SetDefaultMode ()
|
|||
|
||||
void M_RefreshModesList ()
|
||||
{
|
||||
BuildModesList (SCREENWIDTH, SCREENHEIGHT, DisplayBits);
|
||||
BuildModesList (screen->VideoWidth, screen->VideoHeight, DisplayBits);
|
||||
}
|
||||
|
||||
void M_InitVideoModesMenu ()
|
||||
|
@ -385,8 +385,8 @@ void M_SetVideoMode()
|
|||
{
|
||||
if (!GetSelectedSize (&NewWidth, &NewHeight))
|
||||
{
|
||||
NewWidth = SCREENWIDTH;
|
||||
NewHeight = SCREENHEIGHT;
|
||||
NewWidth = screen->VideoWidth;
|
||||
NewHeight = screen->VideoHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <string.h>
|
||||
#include "name.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "c_console.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -268,6 +269,8 @@ FName::NameManager::~NameManager()
|
|||
{
|
||||
NameBlock *block, *next;
|
||||
|
||||
C_ClearTabCommands();
|
||||
|
||||
for (block = Blocks; block != NULL; block = next)
|
||||
{
|
||||
next = block->NextBlock;
|
||||
|
|
|
@ -3791,7 +3791,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
|
|||
break;
|
||||
|
||||
case APROP_Damage:
|
||||
actor->Damage = CreateDamageFunction(value);
|
||||
actor->SetDamage(value);
|
||||
break;
|
||||
|
||||
case APROP_Alpha:
|
||||
|
|
|
@ -1320,7 +1320,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
|
|||
// [RH] What is the point of this check, again? In Hexen, it is unconditional,
|
||||
// but here we only do it if the missile's damage is 0.
|
||||
// MBF bouncer might have a non-0 damage value, but they must not deal damage on impact either.
|
||||
if ((tm.thing->BounceFlags & BOUNCE_Actors) && (tm.thing->Damage == 0 || !(tm.thing->flags & MF_MISSILE)))
|
||||
if ((tm.thing->BounceFlags & BOUNCE_Actors) && (tm.thing->IsZeroDamage() || !(tm.thing->flags & MF_MISSILE)))
|
||||
{
|
||||
return (tm.thing->target == thing || !(thing->flags & MF_SOLID));
|
||||
}
|
||||
|
|
116
src/p_mobj.cpp
116
src/p_mobj.cpp
|
@ -139,7 +139,8 @@ IMPLEMENT_POINTY_CLASS (AActor)
|
|||
DECLARE_POINTER (LastHeard)
|
||||
DECLARE_POINTER (master)
|
||||
DECLARE_POINTER (Poisoner)
|
||||
DECLARE_POINTER (Damage)
|
||||
DECLARE_POINTER (DamageFunc)
|
||||
DECLARE_POINTER (alternative)
|
||||
END_POINTERS
|
||||
|
||||
AActor::~AActor ()
|
||||
|
@ -148,73 +149,6 @@ AActor::~AActor ()
|
|||
// Use Destroy() instead.
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CalcDamageValue
|
||||
//
|
||||
// Given a script function, returns an integer to represent it in a
|
||||
// savegame. This encoding is compatible with previous incarnations
|
||||
// where damage was an integer.
|
||||
//
|
||||
// 0 : use null function
|
||||
// 0x40000000 : use default function
|
||||
// anything else : use function that returns this number
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int CalcDamageValue(VMFunction *func)
|
||||
{
|
||||
if (func == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
VMScriptFunction *sfunc = dyn_cast<VMScriptFunction>(func);
|
||||
if (sfunc == NULL)
|
||||
{
|
||||
return 0x40000000;
|
||||
}
|
||||
VMOP *op = sfunc->Code;
|
||||
// If the function was created by CreateDamageFunction(), extract
|
||||
// the value used to create it and return that. Otherwise, return
|
||||
// indicating to use the default function.
|
||||
if (op->op == OP_RETI && op->a == 0)
|
||||
{
|
||||
return op->i16;
|
||||
}
|
||||
if (op->op == OP_RET && op->a == 0 && op->b == (REGT_INT | REGT_KONST))
|
||||
{
|
||||
return sfunc->KonstD[op->c];
|
||||
}
|
||||
return 0x40000000;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// UncalcDamageValue
|
||||
//
|
||||
// Given a damage integer, returns a script function for it.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static VMFunction *UncalcDamageValue(int dmg, VMFunction *def)
|
||||
{
|
||||
if (dmg == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if ((dmg & 0xC0000000) == 0x40000000)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
// Does the default version return this? If so, use it. Otherwise,
|
||||
// create a new function.
|
||||
if (CalcDamageValue(def) == dmg)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return CreateDamageFunction(dmg);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// AActor :: Serialize
|
||||
|
@ -262,18 +196,16 @@ void AActor::Serialize(FArchive &arc)
|
|||
<< projectilepassheight
|
||||
<< Vel
|
||||
<< tics
|
||||
<< state;
|
||||
if (arc.IsStoring())
|
||||
<< state
|
||||
<< DamageVal;
|
||||
if (DamageVal == 0x40000000 || DamageVal == -1)
|
||||
{
|
||||
int dmg;
|
||||
dmg = CalcDamageValue(Damage);
|
||||
arc << dmg;
|
||||
DamageVal = -1;
|
||||
DamageFunc = GetDefault()->DamageFunc;
|
||||
}
|
||||
else
|
||||
{
|
||||
int dmg;
|
||||
arc << dmg;
|
||||
Damage = UncalcDamageValue(dmg, GetDefault()->Damage);
|
||||
DamageFunc = nullptr;
|
||||
}
|
||||
P_SerializeTerrain(arc, floorterrain);
|
||||
arc << projectileKickback
|
||||
|
@ -2974,8 +2906,21 @@ CCMD(utid)
|
|||
|
||||
int AActor::GetMissileDamage (int mask, int add)
|
||||
{
|
||||
if (Damage == NULL)
|
||||
if (DamageVal >= 0)
|
||||
{
|
||||
if (mask == 0)
|
||||
{
|
||||
return add * DamageVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((pr_missiledamage() & mask) + add) * DamageVal;
|
||||
}
|
||||
}
|
||||
if (DamageFunc == nullptr)
|
||||
{
|
||||
// This should never happen
|
||||
assert(false && "No damage function found");
|
||||
return 0;
|
||||
}
|
||||
VMFrameStack stack;
|
||||
|
@ -2987,22 +2932,11 @@ int AActor::GetMissileDamage (int mask, int add)
|
|||
results[0].IntAt(&amount);
|
||||
results[1].IntAt(&calculated);
|
||||
|
||||
if (stack.Call(Damage, ¶m, 1, results, 2) < 1)
|
||||
if (stack.Call(DamageFunc, ¶m, 1, results, 2) < 1)
|
||||
{ // No results
|
||||
return 0;
|
||||
}
|
||||
if (calculated)
|
||||
{
|
||||
return amount;
|
||||
}
|
||||
else if (mask == 0)
|
||||
{
|
||||
return add * amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((pr_missiledamage() & mask) + add) * amount;
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
void AActor::Howl ()
|
||||
|
@ -3694,7 +3628,7 @@ void AActor::Tick ()
|
|||
// still have missiles that go straight up and down through actors without
|
||||
// damaging anything.
|
||||
// (for backwards compatibility this must check for lack of damage function, not for zero damage!)
|
||||
if ((flags & MF_MISSILE) && Vel.X == 0 && Vel.Y == 0 && Damage != NULL)
|
||||
if ((flags & MF_MISSILE) && Vel.X == 0 && Vel.Y == 0 && !IsZeroDamage())
|
||||
{
|
||||
Vel.X = MinVel;
|
||||
}
|
||||
|
|
|
@ -309,6 +309,11 @@ void FUDMFKeys::Sort()
|
|||
|
||||
FUDMFKey *FUDMFKeys::Find(FName key)
|
||||
{
|
||||
if (!mSorted)
|
||||
{
|
||||
mSorted = true;
|
||||
Sort();
|
||||
}
|
||||
int min = 0, max = Size()-1;
|
||||
|
||||
while (min <= max)
|
||||
|
|
|
@ -220,6 +220,7 @@ struct FUDMFKey
|
|||
|
||||
class FUDMFKeys : public TArray<FUDMFKey>
|
||||
{
|
||||
bool mSorted = false;
|
||||
public:
|
||||
void Sort();
|
||||
FUDMFKey *Find(FName key);
|
||||
|
|
|
@ -232,7 +232,7 @@ void R_SetVisibility(double vis)
|
|||
else
|
||||
r_WallVisibility = r_BaseVisibility;
|
||||
|
||||
r_WallVisibility = (InvZtoScale * SCREENWIDTH*BaseRatioSizes[WidescreenRatio][1] /
|
||||
r_WallVisibility = (InvZtoScale * SCREENWIDTH*AspectBaseHeight(WidescreenRatio) /
|
||||
(viewwidth*SCREENHEIGHT*3)) * (r_WallVisibility * FocalTangent);
|
||||
|
||||
// Prevent overflow on floors/ceilings. Note that the calculation of
|
||||
|
@ -295,7 +295,7 @@ CCMD (r_visibility)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio)
|
||||
void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, float trueratio)
|
||||
{
|
||||
int virtheight, virtwidth, virtwidth2, virtheight2;
|
||||
|
||||
|
@ -318,22 +318,22 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight,
|
|||
virtwidth = virtwidth2 = fullWidth;
|
||||
virtheight = virtheight2 = fullHeight;
|
||||
|
||||
if (Is54Aspect(trueratio))
|
||||
if (AspectTallerThanWide(trueratio))
|
||||
{
|
||||
virtheight2 = virtheight2 * BaseRatioSizes[trueratio][3] / 48;
|
||||
virtheight2 = virtheight2 * AspectMultiplier(trueratio) / 48;
|
||||
}
|
||||
else
|
||||
{
|
||||
virtwidth2 = virtwidth2 * BaseRatioSizes[trueratio][3] / 48;
|
||||
virtwidth2 = virtwidth2 * AspectMultiplier(trueratio) / 48;
|
||||
}
|
||||
|
||||
if (Is54Aspect(WidescreenRatio))
|
||||
if (AspectTallerThanWide(WidescreenRatio))
|
||||
{
|
||||
virtheight = virtheight * BaseRatioSizes[WidescreenRatio][3] / 48;
|
||||
virtheight = virtheight * AspectMultiplier(WidescreenRatio) / 48;
|
||||
}
|
||||
else
|
||||
{
|
||||
virtwidth = virtwidth * BaseRatioSizes[WidescreenRatio][3] / 48;
|
||||
virtwidth = virtwidth * AspectMultiplier(WidescreenRatio) / 48;
|
||||
}
|
||||
|
||||
BaseYaspectMul = 320.0 * virtheight2 / (r_Yaspect * virtwidth2);
|
||||
|
@ -948,7 +948,7 @@ void R_RenderViewToCanvas (AActor *actor, DCanvas *canvas,
|
|||
RenderTarget = canvas;
|
||||
bRenderingToCanvas = true;
|
||||
|
||||
R_SetWindow (12, width, height, height);
|
||||
R_SetWindow (12, width, height, height, true);
|
||||
viewwindowx = x;
|
||||
viewwindowy = y;
|
||||
viewactive = true;
|
||||
|
|
|
@ -55,7 +55,7 @@ struct FRenderer
|
|||
virtual void ErrorCleanup () {}
|
||||
virtual void ClearBuffer(int color) = 0;
|
||||
virtual void Init() = 0;
|
||||
virtual void SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio) {}
|
||||
virtual void SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, float trueratio) {}
|
||||
virtual void SetupFrame(player_t *player) {}
|
||||
virtual void CopyStackedViewParameters() {}
|
||||
virtual void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov) = 0;
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
|
||||
class FArchive;
|
||||
void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio);
|
||||
void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, float trueratio);
|
||||
void R_SetupColormap(player_t *);
|
||||
void R_SetupFreelook();
|
||||
void R_InitRenderer();
|
||||
|
@ -275,7 +275,7 @@ void FSoftwareRenderer::ClearBuffer(int color)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FSoftwareRenderer::SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio)
|
||||
void FSoftwareRenderer::SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, float trueratio)
|
||||
{
|
||||
R_SWRSetWindow(windowSize, fullWidth, fullHeight, stHeight, trueratio);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ struct FSoftwareRenderer : public FRenderer
|
|||
void ErrorCleanup ();
|
||||
void ClearBuffer(int color);
|
||||
void Init();
|
||||
void SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio);
|
||||
void SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, float trueratio);
|
||||
void SetupFrame(player_t *player);
|
||||
void CopyStackedViewParameters();
|
||||
void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov);
|
||||
|
|
|
@ -1393,7 +1393,7 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double
|
|||
}
|
||||
if (pspr->GetID() < PSP_TARGETCENTER)
|
||||
{ // Move the weapon down for 1280x1024.
|
||||
vis->texturemid -= BaseRatioSizes[WidescreenRatio][2];
|
||||
vis->texturemid -= AspectPspriteOffset(WidescreenRatio);
|
||||
}
|
||||
vis->x1 = x1 < 0 ? 0 : x1;
|
||||
vis->x2 = x2 >= viewwidth ? viewwidth : x2;
|
||||
|
|
|
@ -138,7 +138,7 @@ angle_t LocalViewAngle;
|
|||
int LocalViewPitch;
|
||||
bool LocalKeyboardTurner;
|
||||
|
||||
int WidescreenRatio;
|
||||
float WidescreenRatio;
|
||||
int setblocks;
|
||||
int extralight;
|
||||
bool setsizeneeded;
|
||||
|
@ -198,9 +198,9 @@ void R_SetViewSize (int blocks)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight)
|
||||
void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, bool renderingToCanvas)
|
||||
{
|
||||
int trueratio;
|
||||
float trueratio;
|
||||
|
||||
if (windowSize >= 11)
|
||||
{
|
||||
|
@ -220,8 +220,15 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight)
|
|||
freelookviewheight = ((setblocks*fullHeight)/10)&~7;
|
||||
}
|
||||
|
||||
// If the screen is approximately 16:9 or 16:10, consider it widescreen.
|
||||
WidescreenRatio = CheckRatio (fullWidth, fullHeight, &trueratio);
|
||||
if (renderingToCanvas)
|
||||
{
|
||||
WidescreenRatio = fullWidth / (float)fullHeight;
|
||||
trueratio = WidescreenRatio;
|
||||
}
|
||||
else
|
||||
{
|
||||
WidescreenRatio = ActiveRatio(fullWidth, fullHeight, &trueratio);
|
||||
}
|
||||
|
||||
DrawFSHUD = (windowSize == 11);
|
||||
|
||||
|
@ -230,13 +237,13 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight)
|
|||
|
||||
centery = viewheight/2;
|
||||
centerx = viewwidth/2;
|
||||
if (Is54Aspect(WidescreenRatio))
|
||||
if (AspectTallerThanWide(WidescreenRatio))
|
||||
{
|
||||
centerxwide = centerx;
|
||||
}
|
||||
else
|
||||
{
|
||||
centerxwide = centerx * BaseRatioSizes[WidescreenRatio][3] / 48;
|
||||
centerxwide = centerx * AspectMultiplier(WidescreenRatio) / 48;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ extern int validcount;
|
|||
extern angle_t LocalViewAngle; // [RH] Added to consoleplayer's angle
|
||||
extern int LocalViewPitch; // [RH] Used directly instead of consoleplayer's pitch
|
||||
extern bool LocalKeyboardTurner; // [RH] The local player used the keyboard to turn, so interpolate
|
||||
extern int WidescreenRatio;
|
||||
extern float WidescreenRatio;
|
||||
|
||||
extern double r_TicFracF;
|
||||
extern DWORD r_FrameTime;
|
||||
|
@ -95,7 +95,7 @@ void R_ExecuteSetViewSize (void);
|
|||
|
||||
// Called by M_Responder.
|
||||
void R_SetViewSize (int blocks);
|
||||
void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight);
|
||||
void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, bool renderingToCanvas = false);
|
||||
|
||||
|
||||
extern void R_FreePastViewers ();
|
||||
|
|
|
@ -971,6 +971,7 @@ bool FMODSoundRenderer::Init()
|
|||
|
||||
#if FMOD_STUDIO
|
||||
FMOD_ADVANCEDSETTINGS advSettings = {};
|
||||
advSettings.cbSize = sizeof advSettings;
|
||||
advSettings.resamplerMethod = resampler;
|
||||
result = Sys->setAdvancedSettings(&advSettings);
|
||||
if (result != FMOD_OK)
|
||||
|
@ -1370,11 +1371,8 @@ void FMODSoundRenderer::PrintStatus()
|
|||
{
|
||||
FMOD_OUTPUTTYPE output;
|
||||
FMOD_SPEAKERMODE speakermode;
|
||||
FMOD_SOUND_FORMAT format;
|
||||
FMOD_DSP_RESAMPLER resampler;
|
||||
int driver;
|
||||
int samplerate;
|
||||
int numoutputchannels;
|
||||
unsigned int bufferlength;
|
||||
int numbuffers;
|
||||
|
||||
|
@ -1413,6 +1411,9 @@ void FMODSoundRenderer::PrintStatus()
|
|||
#endif
|
||||
}
|
||||
#if !FMOD_STUDIO
|
||||
FMOD_SOUND_FORMAT format;
|
||||
FMOD_DSP_RESAMPLER resampler;
|
||||
int numoutputchannels;
|
||||
if (FMOD_OK == Sys->getSoftwareFormat(&samplerate, &format, &numoutputchannels, NULL, &resampler, NULL))
|
||||
{
|
||||
Printf (TEXTCOLOR_LIGHTBLUE "Software mixer sample rate: " TEXTCOLOR_GREEN "%d\n", samplerate);
|
||||
|
@ -2758,6 +2759,16 @@ std::pair<SoundHandle,bool> FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int l
|
|||
exinfo.defaultfrequency = frequency;
|
||||
switch (bits)
|
||||
{
|
||||
#if FMOD_STUDIO
|
||||
case -8:
|
||||
// Need to convert sample data from signed to unsigned.
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
sfxdata[i] ^= 0x80;
|
||||
}
|
||||
|
||||
case 8:
|
||||
#else // !FMOD_STUDIO
|
||||
case 8:
|
||||
// Need to convert sample data from unsigned to signed.
|
||||
for (int i = 0; i < length; ++i)
|
||||
|
@ -2766,6 +2777,7 @@ std::pair<SoundHandle,bool> FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int l
|
|||
}
|
||||
|
||||
case -8:
|
||||
#endif // FMOD_STUDIO
|
||||
exinfo.format = FMOD_SOUND_FORMAT_PCM8;
|
||||
numsamples = length;
|
||||
break;
|
||||
|
|
|
@ -496,8 +496,7 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
|
|||
else if (def == DEF_Projectile && sc.Compare ("Damage"))
|
||||
{
|
||||
sc.MustGetNumber ();
|
||||
FxDamageValue *x = new FxDamageValue(new FxConstant(sc.Number, sc), false);
|
||||
defaults->Damage = (VMFunction *)(uintptr_t)(ActorDamageFuncs.Push(x) + 1);
|
||||
defaults->SetDamage(sc.Number);
|
||||
}
|
||||
else if (def == DEF_Projectile && sc.Compare ("DamageType"))
|
||||
{
|
||||
|
|
|
@ -348,12 +348,12 @@ static void FinishThingdef()
|
|||
continue;
|
||||
}
|
||||
|
||||
if (def->Damage != NULL)
|
||||
if (def->DamageFunc != nullptr)
|
||||
{
|
||||
FxDamageValue *dmg = (FxDamageValue *)ActorDamageFuncs[(uintptr_t)def->Damage - 1];
|
||||
FxDamageValue *dmg = (FxDamageValue *)ActorDamageFuncs[(uintptr_t)def->DamageFunc - 1];
|
||||
VMScriptFunction *sfunc;
|
||||
sfunc = dmg->GetFunction();
|
||||
if (sfunc == NULL)
|
||||
if (sfunc == nullptr)
|
||||
{
|
||||
FCompileContext ctx(ti);
|
||||
dmg = static_cast<FxDamageValue *>(dmg->Resolve(ctx));
|
||||
|
@ -365,15 +365,15 @@ static void FinishThingdef()
|
|||
dmg->Emit(&buildit);
|
||||
sfunc = buildit.MakeFunction();
|
||||
sfunc->NumArgs = 1;
|
||||
sfunc->Proto = NULL; ///FIXME: Need a proper prototype here
|
||||
sfunc->Proto = nullptr; ///FIXME: Need a proper prototype here
|
||||
// Save this function in case this damage value was reused
|
||||
// (which happens quite easily with inheritance).
|
||||
dmg->SetFunction(sfunc);
|
||||
}
|
||||
}
|
||||
def->Damage = sfunc;
|
||||
def->DamageFunc = sfunc;
|
||||
|
||||
if (dump != NULL && sfunc != NULL)
|
||||
if (dump != nullptr && sfunc != nullptr)
|
||||
{
|
||||
char label[64];
|
||||
int labellen = mysnprintf(label, countof(label), "Function %s.Damage",
|
||||
|
|
|
@ -231,6 +231,38 @@ DEFINE_ACTION_FUNCTION(AActor, CheckClass)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CheckClass
|
||||
//
|
||||
// NON-ACTION function to calculate missile damage for the given actor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetMissileDamage)
|
||||
{
|
||||
if (numret > 0)
|
||||
{
|
||||
assert(ret != NULL);
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(mask);
|
||||
PARAM_INT(add)
|
||||
PARAM_INT_OPT(pick_pointer) { pick_pointer = AAPTR_DEFAULT; }
|
||||
|
||||
self = COPY_AAPTR(self, pick_pointer);
|
||||
if (self == NULL)
|
||||
{
|
||||
ret->SetInt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret->SetInt(self->GetMissileDamage(mask, add));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// IsPointerEqual
|
||||
|
|
|
@ -666,4 +666,5 @@ void InitThingdef()
|
|||
symt.AddSymbol(new PField(NAME_Speed, TypeFloat64, VARF_Native, myoffsetof(AActor, Speed)));
|
||||
symt.AddSymbol(new PField(NAME_Threshold, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, threshold)));
|
||||
symt.AddSymbol(new PField(NAME_DefThreshold, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, DefThreshold)));
|
||||
symt.AddSymbol(new PField(NAME_Damage, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, DamageVal)));
|
||||
}
|
||||
|
|
|
@ -854,20 +854,6 @@ public:
|
|||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxDamage
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FxDamage : public FxExpression
|
||||
{
|
||||
public:
|
||||
FxDamage(const FScriptPosition&);
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxArrayElement
|
||||
|
@ -1188,12 +1174,11 @@ public:
|
|||
class FxDamageValue : public FxExpression
|
||||
{
|
||||
FxExpression *val;
|
||||
bool Calculated;
|
||||
VMScriptFunction *MyFunction;
|
||||
|
||||
public:
|
||||
|
||||
FxDamageValue(FxExpression *v, bool calc);
|
||||
FxDamageValue(FxExpression *v);
|
||||
~FxDamageValue();
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
|
||||
|
|
|
@ -3218,11 +3218,6 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
|
|||
ScriptPosition.Message(MSG_ERROR, "Invalid member identifier '%s'\n", Identifier.GetChars());
|
||||
}
|
||||
}
|
||||
// the damage property needs special handling
|
||||
else if (Identifier == NAME_Damage)
|
||||
{
|
||||
newex = new FxDamage(ScriptPosition);
|
||||
}
|
||||
// now check the global identifiers.
|
||||
else if ((sym = ctx.FindGlobal(Identifier)) != NULL)
|
||||
{
|
||||
|
@ -3316,65 +3311,6 @@ ExpEmit FxSelf::Emit(VMFunctionBuilder *build)
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxDamage::FxDamage(const FScriptPosition &pos)
|
||||
: FxExpression(pos)
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxDamage :: Resolve
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxExpression *FxDamage::Resolve(FCompileContext& ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
ValueType = TypeSInt32;
|
||||
return this;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxDamage :: Emit
|
||||
//
|
||||
// Call this actor's damage function, if it has one
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
ExpEmit FxDamage::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
ExpEmit dmgval(build, REGT_INT);
|
||||
|
||||
// Get damage function
|
||||
ExpEmit dmgfunc(build, REGT_POINTER);
|
||||
build->Emit(OP_LO, dmgfunc.RegNum, 0/*self*/, build->GetConstantInt(myoffsetof(AActor, Damage)));
|
||||
|
||||
// If it's non-null...
|
||||
build->Emit(OP_EQA_K, 1, dmgfunc.RegNum, build->GetConstantAddress(nullptr, ATAG_GENERIC));
|
||||
size_t nulljump = build->Emit(OP_JMP, 0);
|
||||
|
||||
// ...call it
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER, 0/*self*/);
|
||||
build->Emit(OP_CALL, dmgfunc.RegNum, 1, 1);
|
||||
build->Emit(OP_RESULT, 0, REGT_INT, dmgval.RegNum);
|
||||
size_t notnulljump = build->Emit(OP_JMP, 0);
|
||||
|
||||
// Otherwise, use 0
|
||||
build->BackpatchToHere(nulljump);
|
||||
build->EmitLoadInt(dmgval.RegNum, 0);
|
||||
build->BackpatchToHere(notnulljump);
|
||||
|
||||
return dmgval;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -5225,18 +5161,12 @@ ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FxDamageValue::FxDamageValue(FxExpression *v, bool calc)
|
||||
FxDamageValue::FxDamageValue(FxExpression *v)
|
||||
: FxExpression(v->ScriptPosition)
|
||||
{
|
||||
val = v;
|
||||
ValueType = TypeVoid;
|
||||
Calculated = calc;
|
||||
MyFunction = NULL;
|
||||
|
||||
if (!calc)
|
||||
{
|
||||
assert(v->isConstant() && "Non-calculated damage must be constant");
|
||||
}
|
||||
}
|
||||
|
||||
FxDamageValue::~FxDamageValue()
|
||||
|
@ -5272,7 +5202,7 @@ ExpEmit FxDamageValue::Emit(VMFunctionBuilder *build)
|
|||
assert(emitval.RegType == REGT_INT);
|
||||
build->Emit(OP_RET, 0, REGT_INT | (emitval.Konst ? REGT_KONST : 0), emitval.RegNum);
|
||||
}
|
||||
build->Emit(OP_RETI, 1 | RET_FINAL, Calculated);
|
||||
build->Emit(OP_RETI, 1 | RET_FINAL, true);
|
||||
|
||||
return ExpEmit();
|
||||
}
|
||||
|
|
|
@ -865,19 +865,21 @@ static bool ParsePropertyParams(FScanner &sc, FPropertyInfo *prop, AActor *defau
|
|||
|
||||
if (sc.CheckString ("("))
|
||||
{
|
||||
x = new FxDamageValue(new FxIntCast(ParseExpression(sc, bag.Info)), true);
|
||||
conv.i = -1;
|
||||
params.Push(conv);
|
||||
x = new FxDamageValue(new FxIntCast(ParseExpression(sc, bag.Info)));
|
||||
sc.MustGetStringName(")");
|
||||
conv.exp = x;
|
||||
params.Push(conv);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
if (sc.Number != 0)
|
||||
{
|
||||
x = new FxDamageValue(new FxConstant(sc.Number, bag.ScriptPosition), false);
|
||||
}
|
||||
conv.i = sc.Number;
|
||||
params.Push(conv);
|
||||
conv.exp = nullptr;
|
||||
}
|
||||
conv.exp = x;
|
||||
params.Push(conv);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -636,7 +636,8 @@ DEFINE_PROPERTY(threshold, I, Actor)
|
|||
//==========================================================================
|
||||
DEFINE_PROPERTY(damage, X, Actor)
|
||||
{
|
||||
PROP_EXP_PARM(id, 0);
|
||||
PROP_INT_PARM(dmgval, 0);
|
||||
PROP_EXP_PARM(id, 1);
|
||||
|
||||
// Damage can either be a single number, in which case it is subject
|
||||
// to the original damage calculation rules. Or, it can be an expression
|
||||
|
@ -646,13 +647,15 @@ DEFINE_PROPERTY(damage, X, Actor)
|
|||
|
||||
// Store this expression here for now. It will be converted to a function
|
||||
// later once all actors have been processed.
|
||||
if (id == NULL)
|
||||
defaults->DamageVal = dmgval;
|
||||
|
||||
if (id == nullptr)
|
||||
{
|
||||
defaults->Damage = NULL;
|
||||
defaults->DamageFunc = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
defaults->Damage = (VMFunction *)(uintptr_t)(ActorDamageFuncs.Push(id) + 1);
|
||||
defaults->DamageFunc = (VMFunction *)(uintptr_t)(ActorDamageFuncs.Push(id) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -863,37 +863,37 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
|
|||
void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h,
|
||||
double vwidth, double vheight, bool vbottom, bool handleaspect) const
|
||||
{
|
||||
int myratio = handleaspect ? CheckRatio (Width, Height) : 0;
|
||||
float myratio = handleaspect ? ActiveRatio (Width, Height) : (4.0f / 3.0f);
|
||||
|
||||
// if 21:9 AR, map to 16:9 for all callers.
|
||||
// this allows for black bars and stops the stretching of fullscreen images
|
||||
if (myratio == 6) {
|
||||
myratio = 2;
|
||||
if (myratio > 1.7f) {
|
||||
myratio = 16.0f / 9.0f;
|
||||
}
|
||||
|
||||
double right = x + w;
|
||||
double bottom = y + h;
|
||||
|
||||
if (myratio != 0 && myratio != 4)
|
||||
if (myratio > 1.334f)
|
||||
{ // The target surface is either 16:9 or 16:10, so expand the
|
||||
// specified virtual size to avoid undesired stretching of the
|
||||
// image. Does not handle non-4:3 virtual sizes. I'll worry about
|
||||
// those if somebody expresses a desire to use them.
|
||||
x = (x - vwidth * 0.5) * Width * 960 / (vwidth * BaseRatioSizes[myratio][0]) + Width * 0.5;
|
||||
w = (right - vwidth * 0.5) * Width * 960 / (vwidth * BaseRatioSizes[myratio][0]) + Width * 0.5 - x;
|
||||
x = (x - vwidth * 0.5) * Width * 960 / (vwidth * AspectBaseWidth(myratio)) + Width * 0.5;
|
||||
w = (right - vwidth * 0.5) * Width * 960 / (vwidth * AspectBaseWidth(myratio)) + Width * 0.5 - x;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = x * Width / vwidth;
|
||||
w = right * Width / vwidth - x;
|
||||
}
|
||||
if (myratio == 4)
|
||||
if (AspectTallerThanWide(myratio))
|
||||
{ // The target surface is 5:4
|
||||
y = (y - vheight * 0.5) * Height * 600 / (vheight * BaseRatioSizes[myratio][1]) + Height * 0.5;
|
||||
h = (bottom - vheight * 0.5) * Height * 600 / (vheight * BaseRatioSizes[myratio][1]) + Height * 0.5 - y;
|
||||
y = (y - vheight * 0.5) * Height * 600 / (vheight * AspectBaseHeight(myratio)) + Height * 0.5;
|
||||
h = (bottom - vheight * 0.5) * Height * 600 / (vheight * AspectBaseHeight(myratio)) + Height * 0.5 - y;
|
||||
if (vbottom)
|
||||
{
|
||||
y += (Height - Height * BaseRatioSizes[myratio][3] / 48.0) * 0.5;
|
||||
y += (Height - Height * AspectMultiplier(myratio) / 48.0) * 0.5;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -937,30 +937,30 @@ void DCanvas::VirtualToRealCoordsInt(int &x, int &y, int &w, int &h,
|
|||
|
||||
void DCanvas::FillBorder (FTexture *img)
|
||||
{
|
||||
int myratio = CheckRatio (Width, Height);
|
||||
float myratio = ActiveRatio (Width, Height);
|
||||
|
||||
// if 21:9 AR, fill borders akin to 16:9, since all fullscreen
|
||||
// images are being drawn to that scale.
|
||||
if (myratio == 6) {
|
||||
myratio = 2;
|
||||
if (myratio > 1.7f) {
|
||||
myratio = 16 / 9.0f;
|
||||
}
|
||||
|
||||
if (myratio == 0)
|
||||
if (myratio >= 1.3f && myratio <= 1.4f)
|
||||
{ // This is a 4:3 display, so no border to show
|
||||
return;
|
||||
}
|
||||
int bordtop, bordbottom, bordleft, bordright, bord;
|
||||
if (Is54Aspect(myratio))
|
||||
if (AspectTallerThanWide(myratio))
|
||||
{ // Screen is taller than it is wide
|
||||
bordleft = bordright = 0;
|
||||
bord = Height - Height * BaseRatioSizes[myratio][3] / 48;
|
||||
bord = Height - Height * AspectMultiplier(myratio) / 48;
|
||||
bordtop = bord / 2;
|
||||
bordbottom = bord - bordtop;
|
||||
}
|
||||
else
|
||||
{ // Screen is wider than it is tall
|
||||
bordtop = bordbottom = 0;
|
||||
bord = Width - Width * BaseRatioSizes[myratio][3] / 48;
|
||||
bord = Width - Width * AspectMultiplier(myratio) / 48;
|
||||
bordleft = bord / 2;
|
||||
bordright = bord - bordleft;
|
||||
}
|
||||
|
|
236
src/v_video.cpp
236
src/v_video.cpp
|
@ -725,6 +725,21 @@ void DCanvas::CalcGamma (float gamma, BYTE gammalookup[256])
|
|||
DSimpleCanvas::DSimpleCanvas (int width, int height)
|
||||
: DCanvas (width, height)
|
||||
{
|
||||
MemBuffer = nullptr;
|
||||
Resize(width, height);
|
||||
}
|
||||
|
||||
void DSimpleCanvas::Resize(int width, int height)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
|
||||
if (MemBuffer != NULL)
|
||||
{
|
||||
delete[] MemBuffer;
|
||||
MemBuffer = NULL;
|
||||
}
|
||||
|
||||
// Making the pitch a power of 2 is very bad for performance
|
||||
// Try to maximize the number of cache lines that can be filled
|
||||
// for each column drawing operation by making the pitch slightly
|
||||
|
@ -761,7 +776,7 @@ DSimpleCanvas::DSimpleCanvas (int width, int height)
|
|||
}
|
||||
}
|
||||
MemBuffer = new BYTE[Pitch * height];
|
||||
memset (MemBuffer, 0, Pitch * height);
|
||||
memset(MemBuffer, 0, Pitch * height);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -835,6 +850,9 @@ DFrameBuffer::DFrameBuffer (int width, int height)
|
|||
{
|
||||
LastMS = LastSec = FrameCount = LastCount = LastTic = 0;
|
||||
Accel2D = false;
|
||||
|
||||
VideoWidth = width;
|
||||
VideoHeight = height;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1259,7 +1277,6 @@ CCMD(clean)
|
|||
bool V_DoModeSetup (int width, int height, int bits)
|
||||
{
|
||||
DFrameBuffer *buff = I_SetMode (width, height, screen);
|
||||
int cx1, cx2;
|
||||
|
||||
if (buff == NULL)
|
||||
{
|
||||
|
@ -1274,6 +1291,17 @@ bool V_DoModeSetup (int width, int height, int bits)
|
|||
// if D3DFB is being used for the display.
|
||||
FFont::StaticPreloadFonts();
|
||||
|
||||
DisplayBits = bits;
|
||||
V_UpdateModeSize(width, height);
|
||||
|
||||
M_RefreshModesList ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void V_UpdateModeSize (int width, int height)
|
||||
{
|
||||
int cx1, cx2;
|
||||
V_CalcCleanFacs(320, 200, width, height, &CleanXfac, &CleanYfac, &cx1, &cx2);
|
||||
|
||||
CleanWidth = width / CleanXfac;
|
||||
|
@ -1314,32 +1342,38 @@ bool V_DoModeSetup (int width, int height, int bits)
|
|||
|
||||
DisplayWidth = width;
|
||||
DisplayHeight = height;
|
||||
DisplayBits = bits;
|
||||
|
||||
R_OldBlend = ~0;
|
||||
Renderer->OnModeSet();
|
||||
|
||||
M_RefreshModesList ();
|
||||
}
|
||||
|
||||
return true;
|
||||
void V_OutputResized (int width, int height)
|
||||
{
|
||||
V_UpdateModeSize(width, height);
|
||||
setsizeneeded = true;
|
||||
if (StatusBar != NULL)
|
||||
{
|
||||
StatusBar->ScreenSizeChanged();
|
||||
}
|
||||
C_NewModeAdjust();
|
||||
}
|
||||
|
||||
void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *_cx1, int *_cx2)
|
||||
{
|
||||
int ratio;
|
||||
float ratio;
|
||||
int cwidth;
|
||||
int cheight;
|
||||
int cx1, cy1, cx2, cy2;
|
||||
|
||||
ratio = CheckRatio(realwidth, realheight);
|
||||
if (Is54Aspect(ratio))
|
||||
ratio = ActiveRatio(realwidth, realheight);
|
||||
if (AspectTallerThanWide(ratio))
|
||||
{
|
||||
cwidth = realwidth;
|
||||
cheight = realheight * BaseRatioSizes[ratio][3] / 48;
|
||||
cheight = realheight * AspectMultiplier(ratio) / 48;
|
||||
}
|
||||
else
|
||||
{
|
||||
cwidth = realwidth * BaseRatioSizes[ratio][3] / 48;
|
||||
cwidth = realwidth * AspectMultiplier(ratio) / 48;
|
||||
cheight = realheight;
|
||||
}
|
||||
// Use whichever pair of cwidth/cheight or width/height that produces less difference
|
||||
|
@ -1573,20 +1607,10 @@ CUSTOM_CVAR (Int, vid_aspect, 0, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
|
|||
}
|
||||
}
|
||||
|
||||
// Tries to guess the physical dimensions of the screen based on the
|
||||
// screen's pixel dimensions. Can return:
|
||||
// 0: 4:3
|
||||
// 1: 16:9
|
||||
// 2: 16:10
|
||||
// 3: 17:10
|
||||
// 4: 5:4
|
||||
// 5: 17:10 (redundant)
|
||||
// 6: 21:9
|
||||
int CheckRatio (int width, int height, int *trueratio)
|
||||
// Helper for ActiveRatio and CheckRatio. Returns the forced ratio type, or -1 if none.
|
||||
int ActiveFakeRatio(int width, int height)
|
||||
{
|
||||
int fakeratio = -1;
|
||||
int ratio;
|
||||
|
||||
if ((vid_aspect >= 1) && (vid_aspect <= 6))
|
||||
{
|
||||
// [SP] User wants to force aspect ratio; let them.
|
||||
|
@ -1598,7 +1622,7 @@ int CheckRatio (int width, int height, int *trueratio)
|
|||
else if (fakeratio == 5)
|
||||
{
|
||||
fakeratio = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vid_nowidescreen)
|
||||
{
|
||||
|
@ -1608,74 +1632,112 @@ int CheckRatio (int width, int height, int *trueratio)
|
|||
}
|
||||
else
|
||||
{
|
||||
fakeratio = (height * 5/4 == width) ? 4 : 0;
|
||||
fakeratio = (height * 5 / 4 == width) ? 4 : 0;
|
||||
}
|
||||
}
|
||||
// If the size is approximately 16:9, consider it so.
|
||||
if (abs (height * 16/9 - width) < 10)
|
||||
{
|
||||
ratio = 1;
|
||||
}
|
||||
// Consider 17:10 as well.
|
||||
else if (abs (height * 17/10 - width) < 10)
|
||||
{
|
||||
ratio = 3;
|
||||
}
|
||||
// 16:10 has more variance in the pixel dimensions. Grr.
|
||||
else if (abs (height * 16/10 - width) < 60)
|
||||
{
|
||||
// 320x200 and 640x400 are always 4:3, not 16:10
|
||||
if ((width == 320 && height == 200) || (width == 640 && height == 400))
|
||||
{
|
||||
ratio = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ratio = 2;
|
||||
}
|
||||
}
|
||||
// Unless vid_tft is set, 1280x1024 is 4:3, not 5:4.
|
||||
else if (height * 5/4 == width && vid_tft)
|
||||
{
|
||||
ratio = 4;
|
||||
}
|
||||
// test for 21:9 (actually 64:27, 21:9 is a semi-accurate ratio used in marketing)
|
||||
else if (abs (height * 64/27 - width) < 30)
|
||||
{
|
||||
ratio = 6;
|
||||
}
|
||||
// Assume anything else is 4:3. (Which is probably wrong these days...)
|
||||
else
|
||||
{
|
||||
ratio = 0;
|
||||
}
|
||||
|
||||
if (trueratio != NULL)
|
||||
{
|
||||
*trueratio = ratio;
|
||||
}
|
||||
return (fakeratio >= 0) ? fakeratio : ratio;
|
||||
return fakeratio;
|
||||
}
|
||||
|
||||
// First column: Base width
|
||||
// Second column: Base height (used for wall visibility multiplier)
|
||||
// Third column: Psprite offset (needed for "tallscreen" modes)
|
||||
// Fourth column: Width or height multiplier
|
||||
|
||||
// For widescreen aspect ratio x:y ...
|
||||
// base_width = 240 * x / y
|
||||
// multiplier = 320 / base_width
|
||||
// base_height = 200 * multiplier
|
||||
const int BaseRatioSizes[7][4] =
|
||||
// Active screen ratio based on cvars and size
|
||||
float ActiveRatio(int width, int height, float *trueratio)
|
||||
{
|
||||
{ 960, 600, 0, 48 }, // 4:3 320, 200, multiplied by three
|
||||
{ 1280, 450, 0, 48*3/4 }, // 16:9 426.6667, 150, multiplied by three
|
||||
{ 1152, 500, 0, 48*5/6 }, // 16:10 386, 166.6667, multiplied by three
|
||||
{ 1224, 471, 0, 48*40/51 }, // 17:10 408, 156.8627, multiplied by three
|
||||
{ 960, 640, (int)(6.5*FRACUNIT), 48*15/16 }, // 5:4 320, 213.3333, multiplied by three
|
||||
{ 1224, 471, 0, 48*40/51 }, // 17:10 408, 156.8627, multiplied by three (REDUNDANT)
|
||||
{ 1707, 338, 0, 48*9/16 } // 21:9 568.8889, 337.5, multiplied by three
|
||||
};
|
||||
static float forcedRatioTypes[] =
|
||||
{
|
||||
4 / 3.0f,
|
||||
16 / 9.0f,
|
||||
16 / 10.0f,
|
||||
17 / 10.0f,
|
||||
5 / 4.0f,
|
||||
17 / 10.0f,
|
||||
21 / 9.0f
|
||||
};
|
||||
|
||||
float ratio = width / (float)height;
|
||||
int fakeratio = ActiveFakeRatio(width, height);
|
||||
|
||||
if (trueratio)
|
||||
*trueratio = ratio;
|
||||
return (fakeratio != -1) ? forcedRatioTypes[fakeratio] : ratio;
|
||||
}
|
||||
|
||||
// Tries to guess the physical dimensions of the screen based on the
|
||||
// screen's pixel dimensions. Can return:
|
||||
// 0: 4:3
|
||||
// 1: 16:9
|
||||
// 2: 16:10
|
||||
// 3: 17:10
|
||||
// 4: 5:4
|
||||
// 5: 17:10 (redundant, never returned)
|
||||
// 6: 21:9
|
||||
int CheckRatio (int width, int height, int *trueratio)
|
||||
{
|
||||
float aspect = width / (float)height;
|
||||
|
||||
static std::pair<float, int> ratioTypes[] =
|
||||
{
|
||||
{ 21 / 9.0f , 6 },
|
||||
{ 16 / 9.0f , 1 },
|
||||
{ 17 / 10.0f , 3 },
|
||||
{ 16 / 10.0f , 2 },
|
||||
{ 4 / 3.0f , 0 },
|
||||
{ 5 / 4.0f , 4 },
|
||||
{ 0.0f, 0 }
|
||||
};
|
||||
|
||||
int ratio = ratioTypes[0].second;
|
||||
float distance = fabs(ratioTypes[0].first - aspect);
|
||||
for (int i = 1; ratioTypes[i].first != 0.0f; i++)
|
||||
{
|
||||
float d = fabs(ratioTypes[i].first - aspect);
|
||||
if (d < distance)
|
||||
{
|
||||
ratio = ratioTypes[i].second;
|
||||
distance = d;
|
||||
}
|
||||
}
|
||||
|
||||
int fakeratio = ActiveFakeRatio(width, height);
|
||||
if (fakeratio == -1)
|
||||
fakeratio = ratio;
|
||||
|
||||
if (trueratio)
|
||||
*trueratio = ratio;
|
||||
return fakeratio;
|
||||
}
|
||||
|
||||
int AspectBaseWidth(float aspect)
|
||||
{
|
||||
return (int)round(240.0f * aspect * 3.0f);
|
||||
}
|
||||
|
||||
int AspectBaseHeight(float aspect)
|
||||
{
|
||||
if (!AspectTallerThanWide(aspect))
|
||||
return (int)round(200.0f * (320.0f / (AspectBaseWidth(aspect) / 3.0f)) * 3.0f);
|
||||
else
|
||||
return (int)round((200.0f * (4.0f / 3.0f)) / aspect * 3.0f);
|
||||
}
|
||||
|
||||
double AspectPspriteOffset(float aspect)
|
||||
{
|
||||
if (!AspectTallerThanWide(aspect))
|
||||
return 0.0;
|
||||
else
|
||||
return ((4.0 / 3.0) / aspect - 1.0) * 97.5;
|
||||
}
|
||||
|
||||
int AspectMultiplier(float aspect)
|
||||
{
|
||||
if (!AspectTallerThanWide(aspect))
|
||||
return (int)round(320.0f / (AspectBaseWidth(aspect) / 3.0f) * 48.0f);
|
||||
else
|
||||
return (int)round(200.0f / (AspectBaseHeight(aspect) / 3.0f) * 48.0f);
|
||||
}
|
||||
|
||||
bool AspectTallerThanWide(float aspect)
|
||||
{
|
||||
return aspect < 1.333f;
|
||||
}
|
||||
|
||||
void IVideo::DumpAdapters ()
|
||||
{
|
||||
|
|
|
@ -47,6 +47,8 @@ extern int CleanWidth_1, CleanHeight_1, CleanXfac_1, CleanYfac_1;
|
|||
extern int DisplayWidth, DisplayHeight, DisplayBits;
|
||||
|
||||
bool V_DoModeSetup (int width, int height, int bits);
|
||||
void V_UpdateModeSize (int width, int height);
|
||||
void V_OutputResized (int width, int height);
|
||||
void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *cx1=NULL, int *cx2=NULL);
|
||||
|
||||
class FTexture;
|
||||
|
@ -300,6 +302,8 @@ public:
|
|||
void Unlock ();
|
||||
|
||||
protected:
|
||||
void Resize(int width, int height);
|
||||
|
||||
BYTE *MemBuffer;
|
||||
|
||||
DSimpleCanvas() {}
|
||||
|
@ -418,6 +422,10 @@ public:
|
|||
virtual bool Is8BitMode() = 0;
|
||||
#endif
|
||||
|
||||
// The original size of the framebuffer as selected in the video menu.
|
||||
int VideoWidth = 0;
|
||||
int VideoHeight = 0;
|
||||
|
||||
protected:
|
||||
void DrawRateStuff ();
|
||||
void CopyFromBuff (BYTE *src, int srcPitch, int width, int height, BYTE *dest);
|
||||
|
@ -512,15 +520,16 @@ extern "C" void ASM_PatchPitch (void);
|
|||
|
||||
int CheckRatio (int width, int height, int *trueratio=NULL);
|
||||
static inline int CheckRatio (double width, double height) { return CheckRatio(int(width), int(height)); }
|
||||
extern const int BaseRatioSizes[7][4];
|
||||
inline bool IsRatioWidescreen(int ratio) { return (ratio & 3) != 0; }
|
||||
|
||||
inline bool IsRatioWidescreen(int ratio) {
|
||||
return (ratio & 3)!=0;
|
||||
}
|
||||
float ActiveRatio (int width, int height, float *trueratio = NULL);
|
||||
static inline double ActiveRatio (double width, double height) { return ActiveRatio(int(width), int(height)); }
|
||||
|
||||
inline bool Is54Aspect(int ratio) {
|
||||
return ratio == 4;
|
||||
}
|
||||
int AspectBaseWidth(float aspect);
|
||||
int AspectBaseHeight(float aspect);
|
||||
double AspectPspriteOffset(float aspect);
|
||||
int AspectMultiplier(float aspect);
|
||||
bool AspectTallerThanWide(float aspect);
|
||||
|
||||
EXTERN_CVAR(Int, uiscale);
|
||||
|
||||
|
|
|
@ -1220,6 +1220,24 @@ void D3DFB::Flip()
|
|||
CurrRenderTexture ^= RenderTextureToggle;
|
||||
TempRenderTexture = RenderTexture[CurrRenderTexture];
|
||||
}
|
||||
|
||||
if (Windowed)
|
||||
{
|
||||
RECT box;
|
||||
GetClientRect(Window, &box);
|
||||
if (box.right > 0 && box.right > 0 && (Width != box.right || Height != box.bottom))
|
||||
{
|
||||
Resize(box.right, box.bottom);
|
||||
|
||||
TrueHeight = Height;
|
||||
PixelDoubling = 0;
|
||||
LBOffsetI = 0;
|
||||
LBOffset = 0.0f;
|
||||
Reset();
|
||||
|
||||
V_OutputResized(Width, Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -537,10 +537,18 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
if (screen && !VidResizing)
|
||||
{
|
||||
LPMINMAXINFO mmi = (LPMINMAXINFO)lParam;
|
||||
RECT rect = { 0, 0, screen->GetWidth(), screen->GetHeight() };
|
||||
AdjustWindowRectEx(&rect, WS_VISIBLE|WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW);
|
||||
mmi->ptMinTrackSize.x = rect.right - rect.left;
|
||||
mmi->ptMinTrackSize.y = rect.bottom - rect.top;
|
||||
if (screen->IsFullscreen())
|
||||
{
|
||||
RECT rect = { 0, 0, screen->GetWidth(), screen->GetHeight() };
|
||||
AdjustWindowRectEx(&rect, WS_VISIBLE | WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW);
|
||||
mmi->ptMinTrackSize.x = rect.right - rect.left;
|
||||
mmi->ptMinTrackSize.y = rect.bottom - rect.top;
|
||||
}
|
||||
else
|
||||
{
|
||||
mmi->ptMinTrackSize.x = 320;
|
||||
mmi->ptMinTrackSize.y = 200;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -156,6 +156,15 @@ enum
|
|||
ATAG_RNG, // pointer to FRandom
|
||||
};
|
||||
|
||||
enum EVMAbortException
|
||||
{
|
||||
X_READ_NIL,
|
||||
X_WRITE_NIL,
|
||||
X_TOO_MANY_TRIES,
|
||||
X_ARRAY_OUT_OF_BOUNDS,
|
||||
X_DIVISION_BY_ZERO,
|
||||
};
|
||||
|
||||
class VMFunction : public DObject
|
||||
{
|
||||
DECLARE_ABSTRACT_CLASS(VMFunction, DObject);
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#define ASSERTKA(x) assert(sfunc != NULL && (unsigned)(x) < sfunc->NumKonstA)
|
||||
#define ASSERTKS(x) assert(sfunc != NULL && (unsigned)(x) < sfunc->NumKonstS)
|
||||
|
||||
#define THROW(x)
|
||||
#define THROW(x) throw(EVMAbortException(x))
|
||||
|
||||
#define CMPJMP(test) \
|
||||
if ((test) == (a & CMP_CHECK)) { \
|
||||
|
@ -54,14 +54,6 @@
|
|||
pc += 1; \
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
X_READ_NIL,
|
||||
X_WRITE_NIL,
|
||||
X_TOO_MANY_TRIES,
|
||||
X_ARRAY_OUT_OF_BOUNDS
|
||||
};
|
||||
|
||||
#define GETADDR(a,o,x) \
|
||||
if (a == NULL) { THROW(x); } \
|
||||
ptr = (VM_SBYTE *)a + o
|
||||
|
|
|
@ -786,27 +786,51 @@ begin:
|
|||
|
||||
OP(DIV_RR):
|
||||
ASSERTD(a); ASSERTD(B); ASSERTD(C);
|
||||
if (reg.d[C] == 0)
|
||||
{
|
||||
THROW(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
reg.d[a] = reg.d[B] / reg.d[C];
|
||||
NEXTOP;
|
||||
OP(DIV_RK):
|
||||
ASSERTD(a); ASSERTD(B); ASSERTKD(C);
|
||||
if (konstd[C] == 0)
|
||||
{
|
||||
THROW(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
reg.d[a] = reg.d[B] / konstd[C];
|
||||
NEXTOP;
|
||||
OP(DIV_KR):
|
||||
ASSERTD(a); ASSERTKD(B); ASSERTD(C);
|
||||
if (reg.d[C] == 0)
|
||||
{
|
||||
THROW(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
reg.d[a] = konstd[B] / reg.d[C];
|
||||
NEXTOP;
|
||||
|
||||
OP(MOD_RR):
|
||||
ASSERTD(a); ASSERTD(B); ASSERTD(C);
|
||||
if (reg.d[C] == 0)
|
||||
{
|
||||
THROW(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
reg.d[a] = reg.d[B] % reg.d[C];
|
||||
NEXTOP;
|
||||
OP(MOD_RK):
|
||||
ASSERTD(a); ASSERTD(B); ASSERTKD(C);
|
||||
if (konstd[C] == 0)
|
||||
{
|
||||
THROW(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
reg.d[a] = reg.d[B] % konstd[C];
|
||||
NEXTOP;
|
||||
OP(MOD_KR):
|
||||
ASSERTD(a); ASSERTKD(B); ASSERTD(C);
|
||||
if (reg.d[C] == 0)
|
||||
{
|
||||
THROW(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
reg.d[a] = konstd[B] % reg.d[C];
|
||||
NEXTOP;
|
||||
|
||||
|
@ -981,14 +1005,26 @@ begin:
|
|||
|
||||
OP(DIVF_RR):
|
||||
ASSERTF(a); ASSERTF(B); ASSERTF(C);
|
||||
if (reg.f[C] == 0.)
|
||||
{
|
||||
THROW(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
reg.f[a] = reg.f[B] / reg.f[C];
|
||||
NEXTOP;
|
||||
OP(DIVF_RK):
|
||||
ASSERTF(a); ASSERTF(B); ASSERTKF(C);
|
||||
if (konstf[C] == 0.)
|
||||
{
|
||||
THROW(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
reg.f[a] = reg.f[B] / konstf[C];
|
||||
NEXTOP;
|
||||
OP(DIVF_KR):
|
||||
ASSERTF(a); ASSERTKF(B); ASSERTF(C);
|
||||
if (reg.f[C] == 0.)
|
||||
{
|
||||
THROW(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
reg.f[a] = konstf[B] / reg.f[C];
|
||||
NEXTOP;
|
||||
|
||||
|
@ -996,6 +1032,10 @@ begin:
|
|||
ASSERTF(a); ASSERTF(B); ASSERTF(C);
|
||||
fb = reg.f[B]; fc = reg.f[C];
|
||||
Do_MODF:
|
||||
if (fc == 0.)
|
||||
{
|
||||
THROW(X_DIVISION_BY_ZERO);
|
||||
}
|
||||
reg.f[a] = luai_nummod(fb, fc);
|
||||
NEXTOP;
|
||||
OP(MODF_RK):
|
||||
|
|
|
@ -407,6 +407,44 @@ int VMFrameStack::Call(VMFunction *func, VMValue *params, int numparams, VMRetur
|
|||
}
|
||||
throw;
|
||||
}
|
||||
catch (EVMAbortException exception)
|
||||
{
|
||||
if (allocated)
|
||||
{
|
||||
PopFrame();
|
||||
}
|
||||
if (trap != nullptr)
|
||||
{
|
||||
*trap = nullptr;
|
||||
}
|
||||
|
||||
Printf("VM execution aborted: ");
|
||||
switch (exception)
|
||||
{
|
||||
case X_READ_NIL:
|
||||
Printf("tried to read from address zero.");
|
||||
break;
|
||||
|
||||
case X_WRITE_NIL:
|
||||
Printf("tried to write to address zero.");
|
||||
break;
|
||||
|
||||
case X_TOO_MANY_TRIES:
|
||||
Printf("too many try-catch blocks.");
|
||||
break;
|
||||
|
||||
case X_ARRAY_OUT_OF_BOUNDS:
|
||||
Printf("array access out of bounds.");
|
||||
break;
|
||||
|
||||
case X_DIVISION_BY_ZERO:
|
||||
Printf("division by zero.");
|
||||
break;
|
||||
}
|
||||
Printf("\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (allocated)
|
||||
|
|
|
@ -53,6 +53,7 @@ ACTOR Actor native //: Thinker
|
|||
native int CountProximity(class<Actor> classname, float distance, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
native float GetSpriteAngle(int ptr = AAPTR_DEFAULT);
|
||||
native float GetSpriteRotation(int ptr = AAPTR_DEFAULT);
|
||||
native int GetMissileDamage(int mask, int add, int ptr = AAPTR_DEFAULT);
|
||||
|
||||
// Action functions
|
||||
// Meh, MBF redundant functions. Only for DeHackEd support.
|
||||
|
|
Loading…
Reference in a new issue