mirror of
https://github.com/ZDoom/gzdoom-last-svn.git
synced 2025-05-29 16:31:16 +00:00
- Added Skulltag's HQ resite feature
- removed special handling for old ZSBSPs that threw out overlapping linedefs. If such nodes are encountered now a rebuild is forced instead of trying to work with the broken data. - Update to ZDoom r1333: - Added Karate Chris's new DMFlags submission. - Fixed: The correct player class was not remembered when the menu had both a player class selection menu and an episode menu. - Fixed: AddToConsole could write outside its working buffer. - Fixed: 0 was no longer recognized as placeholder for 'no state' in A_Chase. - Fixed: When picking up weapons the code did not check if it should switch away from weak weapons. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@279 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
parent
9ed7dd7fa3
commit
9446999c4c
39 changed files with 583 additions and 300 deletions
|
@ -1,3 +1,14 @@
|
|||
December 28, 2008 (Changes by Graf Zahl)
|
||||
- Added Karate Chris's new DMFlags submission.
|
||||
|
||||
December 27, 2008 (Changes by Graf Zahl)
|
||||
- Fixed: The correct player class was not remembered when the menu had both
|
||||
a player class selection menu and an episode menu.
|
||||
- Fixed: AddToConsole could write outside its working buffer.
|
||||
- Fixed: 0 was no longer recognized as placeholder for 'no state' in A_Chase.
|
||||
- Fixed: When picking up weapons the code did not check if it should switch away
|
||||
from weak weapons.
|
||||
|
||||
December 20, 2008
|
||||
- OggMod improperly decodes the right channel of stereo samples when sending
|
||||
them to OggEnc, so I have no choice but to convert them to mono by chopping
|
||||
|
|
|
@ -6424,6 +6424,10 @@
|
|||
RelativePath=".\src\gl\gl_hirestex.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\gl\gl_hqresize.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\gl\gl_light.cpp"
|
||||
>
|
||||
|
@ -6432,10 +6436,6 @@
|
|||
RelativePath=".\src\gl\gl_menu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\gl\gl_missinglines.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\gl\gl_missingtexture.cpp"
|
||||
>
|
||||
|
@ -6559,6 +6559,10 @@
|
|||
RelativePath=".\src\gl\gl_include.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\gl\gl_hqresize.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\gl\gl_intern.h"
|
||||
>
|
||||
|
|
|
@ -620,7 +620,6 @@ add_executable( zdoom WIN32
|
|||
gl/gl_hirestex.cpp
|
||||
gl/gl_light.cpp
|
||||
gl/gl_menu.cpp
|
||||
gl/gl_missinglines.cpp
|
||||
gl/gl_missingtexture.cpp
|
||||
gl/gl_models.cpp
|
||||
gl/gl_models_md2.cpp
|
||||
|
|
|
@ -863,6 +863,10 @@ void AM_ToggleMap ()
|
|||
if (gamestate != GS_LEVEL)
|
||||
return;
|
||||
|
||||
// Don't activate the automap if we're not allowed to use it.
|
||||
if (dmflags2 & DF2_NO_AUTOMAP)
|
||||
return;
|
||||
|
||||
SB_state = screen->GetPageCount ();
|
||||
if (!automapactive)
|
||||
{
|
||||
|
@ -1572,6 +1576,10 @@ void AM_drawPlayers ()
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// We don't always want to show allies on the automap.
|
||||
if (dmflags2 & DF2_NO_AUTOMAP_ALLIES && i != consoleplayer)
|
||||
continue;
|
||||
|
||||
if (deathmatch && !demoplayback &&
|
||||
!p->mo->IsTeammate (players[consoleplayer].mo) &&
|
||||
|
|
|
@ -232,7 +232,8 @@ CCMD (chase)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (gamestate == GS_LEVEL && deathmatch && CheckCheatmode ())
|
||||
// Check if we're allowed to use chasecam.
|
||||
if (gamestate != GS_LEVEL || (!(dmflags2 & DF2_CHASECAM) && CheckCheatmode ()))
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
|
|
|
@ -667,7 +667,7 @@ void AddToConsole (int printlevel, const char *text)
|
|||
}
|
||||
|
||||
len = (int)strlen (text);
|
||||
size = len + 3;
|
||||
size = len + 20;
|
||||
|
||||
if (addtype != NEWLINE)
|
||||
{
|
||||
|
@ -767,6 +767,15 @@ void AddToConsole (int printlevel, const char *text)
|
|||
if (*work_p)
|
||||
{
|
||||
linestart = work_p - 1 - cc.Len();
|
||||
if (linestart < work)
|
||||
{
|
||||
// The line start is outside the buffer.
|
||||
// Make space for the newly inserted stuff.
|
||||
size_t movesize = work-linestart;
|
||||
memmove(work + movesize, work, strlen(work));
|
||||
work_p += movesize;
|
||||
linestart = work;
|
||||
}
|
||||
linestart[0] = TEXTCOLOR_ESCAPE;
|
||||
strncpy (linestart + 1, cc, cc.Len());
|
||||
}
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
#include "d_event.h"
|
||||
#include "d_netinf.h"
|
||||
#include "v_palette.h"
|
||||
#include "m_cheat.h"
|
||||
|
||||
EXTERN_CVAR(Bool, hud_althud)
|
||||
void DrawHUD();
|
||||
|
@ -114,6 +115,7 @@ extern void M_SetDefaultMode ();
|
|||
extern void R_ExecuteSetViewSize ();
|
||||
extern void G_NewInit ();
|
||||
extern void SetupPlayerClasses ();
|
||||
extern bool CheckCheatmode ();
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
|
@ -139,6 +141,7 @@ EXTERN_CVAR (Float, m_yaw)
|
|||
EXTERN_CVAR (Bool, invertmouse)
|
||||
EXTERN_CVAR (Bool, lookstrafe)
|
||||
EXTERN_CVAR (Int, screenblocks)
|
||||
EXTERN_CVAR (Bool, sv_cheats)
|
||||
|
||||
extern gameinfo_t SharewareGameInfo;
|
||||
extern gameinfo_t RegisteredGameInfo;
|
||||
|
@ -440,7 +443,58 @@ CVAR (Flag, sv_allowcrouch, dmflags, DF_YES_CROUCH);
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
CVAR (Int, dmflags2, 0, CVAR_SERVERINFO);
|
||||
CUSTOM_CVAR (Int, dmflags2, 0, CVAR_SERVERINFO)
|
||||
{
|
||||
// Stop the automap if we aren't allowed to use it.
|
||||
if ((self & DF2_NO_AUTOMAP) && automapactive)
|
||||
AM_Stop ();
|
||||
|
||||
for (int i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
player_t *p = &players[i];
|
||||
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
// Revert our view to our own eyes if spying someone else.
|
||||
if (self & DF2_DISALLOW_SPYING)
|
||||
{
|
||||
// The player isn't looking through its own eyes, so make it.
|
||||
if (p->camera != p->mo)
|
||||
{
|
||||
p->camera = p->mo;
|
||||
|
||||
S_UpdateSounds (p->camera);
|
||||
StatusBar->AttachToPlayer (p);
|
||||
|
||||
if (demoplayback || multiplayer)
|
||||
StatusBar->ShowPlayerName ();
|
||||
}
|
||||
}
|
||||
|
||||
// Come out of chasecam mode if we're not allowed to use chasecam.
|
||||
if (!(dmflags2 & DF2_CHASECAM) && !G_SkillProperty (SKILLP_DisableCheats) && !sv_cheats)
|
||||
{
|
||||
// Take us out of chasecam mode only.
|
||||
if (p->cheats & CF_CHASECAM)
|
||||
cht_DoCheat (p, CHT_CHASECAM);
|
||||
}
|
||||
|
||||
// Change our autoaim settings if need be.
|
||||
if (dmflags2 & DF2_NOAUTOAIM)
|
||||
{
|
||||
// Save our aimdist and set aimdist to 0.
|
||||
p->userinfo.savedaimdist = p->userinfo.aimdist;
|
||||
p->userinfo.aimdist = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Restore our aimdist.
|
||||
p->userinfo.aimdist = p->userinfo.savedaimdist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CVAR (Flag, sv_weapondrop, dmflags2, DF2_YES_WEAPONDROP);
|
||||
CVAR (Flag, sv_noteamswitch, dmflags2, DF2_NO_TEAM_SWITCH);
|
||||
CVAR (Flag, sv_doubleammo, dmflags2, DF2_YES_DOUBLEAMMO);
|
||||
|
@ -452,7 +506,14 @@ CVAR (Flag, sv_norespawn, dmflags2, DF2_NO_RESPAWN);
|
|||
CVAR (Flag, sv_losefrag, dmflags2, DF2_YES_LOSEFRAG);
|
||||
CVAR (Flag, sv_respawnprotect, dmflags2, DF2_YES_RESPAWN_INVUL);
|
||||
CVAR (Flag, sv_samespawnspot, dmflags2, DF2_SAME_SPAWN_SPOT);
|
||||
CVAR (Flag, sv_infiniteinventory, dmflags2, DF2_INFINITE_INVENTORY)
|
||||
CVAR (Flag, sv_infiniteinventory, dmflags2, DF2_INFINITE_INVENTORY);
|
||||
CVAR (Flag, sv_killallmonsters, dmflags2, DF2_KILL_MONSTERS);
|
||||
CVAR (Flag, sv_noautomap, dmflags2, DF2_NO_AUTOMAP);
|
||||
CVAR (Flag, sv_noautomapallies, dmflags2, DF2_NO_AUTOMAP_ALLIES);
|
||||
CVAR (Flag, sv_disallowspying, dmflags2, DF2_DISALLOW_SPYING);
|
||||
CVAR (Flag, sv_chasecam, dmflags2, DF2_CHASECAM);
|
||||
CVAR (Flag, sv_disallowsuicide, dmflags2, DF2_NOSUICIDE);
|
||||
CVAR (Flag, sv_noautoaim, dmflags2, DF2_NOAUTOAIM);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -370,11 +370,17 @@ void D_SetupUserInfo ()
|
|||
}
|
||||
if (autoaim > 35.f || autoaim < 0.f)
|
||||
{
|
||||
coninfo->aimdist = ANGLE_1*35;
|
||||
if (dmflags & DF2_NOAUTOAIM)
|
||||
coninfo->savedaimdist = ANGLE_1*35;
|
||||
else
|
||||
coninfo->aimdist = ANGLE_1*35;
|
||||
}
|
||||
else
|
||||
{
|
||||
coninfo->aimdist = abs ((int)(autoaim * (float)ANGLE_1));
|
||||
if (dmflags & DF2_NOAUTOAIM)
|
||||
coninfo->savedaimdist = abs ((int)(autoaim * (float)ANGLE_1));
|
||||
else
|
||||
coninfo->aimdist = abs ((int)(autoaim * (float)ANGLE_1));
|
||||
}
|
||||
coninfo->color = color;
|
||||
coninfo->skin = R_FindSkin (skin, 0);
|
||||
|
@ -684,11 +690,17 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
|
|||
angles = atof (value);
|
||||
if (angles > 35.f || angles < 0.f)
|
||||
{
|
||||
info->aimdist = ANGLE_1*35;
|
||||
if (dmflags & DF2_NOAUTOAIM)
|
||||
info->savedaimdist = ANGLE_1*35;
|
||||
else
|
||||
info->aimdist = ANGLE_1*35;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->aimdist = abs ((int)(angles * (float)ANGLE_1));
|
||||
if (dmflags & DF2_NOAUTOAIM)
|
||||
info->savedaimdist = abs ((int)(angles * (float)ANGLE_1));
|
||||
else
|
||||
info->aimdist = abs ((int)(angles * (float)ANGLE_1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -804,6 +816,8 @@ FArchive &operator<< (FArchive &arc, userinfo_t &info)
|
|||
arc.Read (&info.netname, sizeof(info.netname));
|
||||
}
|
||||
arc << info.team << info.aimdist << info.color << info.skin << info.gender << info.neverswitch;
|
||||
if (SaveVersion >= 1333) arc << info.savedaimdist;
|
||||
else info.savedaimdist = info.aimdist;
|
||||
return arc;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,8 +82,9 @@ public:
|
|||
virtual void TweakSpeeds (int &forwardmove, int &sidemove);
|
||||
virtual void MorphPlayerThink ();
|
||||
virtual void ActivateMorphWeapon ();
|
||||
virtual AWeapon *PickNewWeapon (const PClass *ammotype);
|
||||
virtual AWeapon *BestWeapon (const PClass *ammotype);
|
||||
AWeapon *PickNewWeapon (const PClass *ammotype);
|
||||
AWeapon *BestWeapon (const PClass *ammotype);
|
||||
void CheckWeaponSwitch(const PClass *ammotype);
|
||||
virtual void GiveDeathmatchInventory ();
|
||||
virtual void FilterCoopRespawnInventory (APlayerPawn *oldplayer);
|
||||
|
||||
|
@ -196,6 +197,7 @@ struct userinfo_t
|
|||
{
|
||||
char netname[MAXPLAYERNAME+1];
|
||||
BYTE team;
|
||||
int savedaimdist;
|
||||
int aimdist;
|
||||
int color;
|
||||
int skin;
|
||||
|
|
|
@ -243,12 +243,17 @@ enum
|
|||
DF2_YES_RESPAWN_INVUL = 1 << 10, // Player is temporarily invulnerable when respawned
|
||||
// DF2_COOP_SHOTGUNSTART = 1 << 11, // All playres start with a shotgun when they respawn
|
||||
DF2_SAME_SPAWN_SPOT = 1 << 12, // Players respawn in the same place they died (co-op)
|
||||
|
||||
DF2_YES_KEEPFRAGS = 1 << 13, // Don't clear frags after each level
|
||||
DF2_NO_RESPAWN = 1 << 14, // Player cannot respawn
|
||||
DF2_YES_LOSEFRAG = 1 << 15, // Lose a frag when killed. More incentive to try to
|
||||
// // not get yerself killed
|
||||
DF2_YES_LOSEFRAG = 1 << 15, // Lose a frag when killed. More incentive to try to not get yerself killed
|
||||
DF2_INFINITE_INVENTORY = 1 << 16, // Infinite inventory.
|
||||
DF2_KILL_MONSTERS = 1 << 17, // All monsters must be killed before the level exits.
|
||||
DF2_NO_AUTOMAP = 1 << 18, // Players are allowed to see the automap.
|
||||
DF2_NO_AUTOMAP_ALLIES = 1 << 19, // Allies can been seen on the automap.
|
||||
DF2_DISALLOW_SPYING = 1 << 20, // You can spy on your allies.
|
||||
DF2_CHASECAM = 1 << 21, // Players can use the chasecam cheat.
|
||||
DF2_NOSUICIDE = 1 << 22, // Players are allowed to suicide.
|
||||
DF2_NOAUTOAIM = 1 << 23, // Players cannot use autoaim.
|
||||
};
|
||||
|
||||
// [RH] Compatibility flags.
|
||||
|
|
|
@ -724,6 +724,10 @@ static void ChangeSpy (bool forward)
|
|||
return;
|
||||
}
|
||||
|
||||
// We may not be allowed to spy on anyone.
|
||||
if (dmflags2 & DF2_DISALLOW_SPYING)
|
||||
return;
|
||||
|
||||
// Otherwise, cycle to the next player.
|
||||
bool checkTeam = !demoplayback && deathmatch;
|
||||
int pnum = players[consoleplayer].camera->player - players;
|
||||
|
|
|
@ -96,18 +96,9 @@ bool AAmmo::HandlePickup (AInventory *item)
|
|||
|
||||
assert (Owner != NULL);
|
||||
|
||||
if (oldamount == 0 && Owner != NULL && Owner->player != NULL &&
|
||||
!Owner->player->userinfo.neverswitch &&
|
||||
Owner->player->PendingWeapon == WP_NOCHANGE &&
|
||||
(Owner->player->ReadyWeapon == NULL ||
|
||||
(Owner->player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)))
|
||||
if (oldamount == 0 && Owner != NULL && Owner->player != NULL)
|
||||
{
|
||||
AWeapon *best = barrier_cast<APlayerPawn *>(Owner)->BestWeapon (GetClass());
|
||||
if (best != NULL && (Owner->player->ReadyWeapon == NULL ||
|
||||
best->SelectionOrder < Owner->player->ReadyWeapon->SelectionOrder))
|
||||
{
|
||||
Owner->player->PendingWeapon = best;
|
||||
}
|
||||
barrier_cast<APlayerPawn *>(Owner)->CheckWeaponSwitch(GetClass());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -129,7 +129,7 @@ struct FSpotList
|
|||
|
||||
ASpecialSpot *GetNextInList(int skipcounter)
|
||||
{
|
||||
if (++SkipCount > skipcounter)
|
||||
if (Spots.Size() > 0 && ++SkipCount > skipcounter)
|
||||
{
|
||||
SkipCount = 0;
|
||||
|
||||
|
|
|
@ -158,8 +158,17 @@ bool AWeapon::PickupForAmmo (AWeapon *ownedWeapon)
|
|||
// Don't take ammo if the weapon sticks around.
|
||||
if (!ShouldStay ())
|
||||
{
|
||||
int oldamount = 0;
|
||||
if (ownedWeapon->Ammo1 != NULL) oldamount = ownedWeapon->Ammo1->Amount;
|
||||
|
||||
if (AmmoGive1 > 0) gotstuff = AddExistingAmmo (ownedWeapon->Ammo1, AmmoGive1);
|
||||
if (AmmoGive2 > 0) gotstuff |= AddExistingAmmo (ownedWeapon->Ammo2, AmmoGive2);
|
||||
|
||||
AActor *Owner = ownedWeapon->Owner;
|
||||
if (gotstuff && oldamount == 0 && Owner != NULL && Owner->player != NULL)
|
||||
{
|
||||
static_cast<APlayerPawn *>(Owner)->CheckWeaponSwitch(ownedWeapon->Ammo1->GetClass());
|
||||
}
|
||||
}
|
||||
return gotstuff;
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ static void AddLine (seg_t *seg,sector_t * sector,subsector_t * polysub)
|
|||
|
||||
SetupWall.Clock();
|
||||
|
||||
wall.Process(seg, sector, backsector, polysub);
|
||||
wall.Process(seg, sector, backsector, polysub, gl_render_segs);
|
||||
rendered_lines++;
|
||||
|
||||
SetupWall.Unclock();
|
||||
|
|
|
@ -727,7 +727,6 @@ void gl_PreprocessLevel()
|
|||
vt->vt = vtx;
|
||||
}
|
||||
}
|
||||
gl_CollectMissingLines();
|
||||
gl_InitVertexData();
|
||||
gl_CreateSections();
|
||||
|
||||
|
|
|
@ -806,6 +806,7 @@ static int __cdecl dicmp (const void *a, const void *b)
|
|||
case GLDIT_POLY: break;
|
||||
}
|
||||
}
|
||||
if (lights[0]!=lights[1]) return lights[0]-lights[1];
|
||||
if (tx[0]!=tx[1]) return tx[0]-tx[1];
|
||||
/*if (lights[0]!=lights[1])*/ return lights[0]-lights[1];
|
||||
}
|
||||
|
|
|
@ -254,6 +254,7 @@ sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, bool back)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
area_t in_area = ::in_area;
|
||||
|
||||
if (in_area==area_above)
|
||||
{
|
||||
|
|
|
@ -131,11 +131,6 @@ angle_t gl_FrustumAngle();
|
|||
void gl_LinkLights();
|
||||
|
||||
|
||||
// ZDBSP shittiness compensation
|
||||
void gl_CollectMissingLines();
|
||||
void gl_RenderMissingLines();
|
||||
|
||||
|
||||
void gl_SetActorLights(AActor *);
|
||||
void gl_DeleteAllAttachedLights();
|
||||
void gl_RecreateAllAttachedLights();
|
||||
|
|
225
src/gl/gl_hqresize.cpp
Normal file
225
src/gl/gl_hqresize.cpp
Normal file
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
** gl_hqresize.cpp
|
||||
** Contains high quality upsampling functions.
|
||||
** So far Scale2x/3x/4x as described in http://scale2x.sourceforge.net/
|
||||
** are implemented.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2008 Benjamin Berkels
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include "gl_hqresize.h"
|
||||
#include "c_cvars.h"
|
||||
|
||||
CUSTOM_CVAR(Int, gl_texture_hqresize, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
if (self < 0 || self > 3) self = 0;
|
||||
FGLTexture::FlushAll();
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, gl_texture_hqresize_maxinputsize, 512, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
if (self > 1024) self = 1024;
|
||||
FGLTexture::FlushAll();
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, gl_texture_hqresize_targets, 7, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
FGLTexture::FlushAll();
|
||||
}
|
||||
|
||||
CVAR (Flag, gl_texture_hqresize_textures, gl_texture_hqresize_targets, 1);
|
||||
CVAR (Flag, gl_texture_hqresize_sprites, gl_texture_hqresize_targets, 2);
|
||||
CVAR (Flag, gl_texture_hqresize_fonts, gl_texture_hqresize_targets, 4);
|
||||
|
||||
|
||||
static void scale2x ( uint32* inputBuffer, uint32* outputBuffer, int inWidth, int inHeight )
|
||||
{
|
||||
const int width = 2* inWidth;
|
||||
const int height = 2 * inHeight;
|
||||
|
||||
for ( int i = 0; i < inWidth; ++i )
|
||||
{
|
||||
const int iMinus = (i > 0) ? (i-1) : 0;
|
||||
const int iPlus = (i < inWidth - 1 ) ? (i+1) : i;
|
||||
for ( int j = 0; j < inHeight; ++j )
|
||||
{
|
||||
const int jMinus = (j > 0) ? (j-1) : 0;
|
||||
const int jPlus = (j < inHeight - 1 ) ? (j+1) : j;
|
||||
const uint32 A = inputBuffer[ iMinus +inWidth*jMinus];
|
||||
const uint32 B = inputBuffer[ iMinus +inWidth*j ];
|
||||
const uint32 C = inputBuffer[ iMinus +inWidth*jPlus];
|
||||
const uint32 D = inputBuffer[ i +inWidth*jMinus];
|
||||
const uint32 E = inputBuffer[ i +inWidth*j ];
|
||||
const uint32 F = inputBuffer[ i +inWidth*jPlus];
|
||||
const uint32 G = inputBuffer[ iPlus +inWidth*jMinus];
|
||||
const uint32 H = inputBuffer[ iPlus +inWidth*j ];
|
||||
const uint32 I = inputBuffer[ iPlus +inWidth*jPlus];
|
||||
if (B != H && D != F) {
|
||||
outputBuffer[2*i + width*2*j ] = D == B ? D : E;
|
||||
outputBuffer[2*i + width*(2*j+1)] = B == F ? F : E;
|
||||
outputBuffer[2*i+1 + width*2*j ] = D == H ? D : E;
|
||||
outputBuffer[2*i+1 + width*(2*j+1)] = H == F ? F : E;
|
||||
} else {
|
||||
outputBuffer[2*i + width*2*j ] = E;
|
||||
outputBuffer[2*i + width*(2*j+1)] = E;
|
||||
outputBuffer[2*i+1 + width*2*j ] = E;
|
||||
outputBuffer[2*i+1 + width*(2*j+1)] = E;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void scale3x ( uint32* inputBuffer, uint32* outputBuffer, int inWidth, int inHeight )
|
||||
{
|
||||
const int width = 3* inWidth;
|
||||
const int height = 3 * inHeight;
|
||||
|
||||
for ( int i = 0; i < inWidth; ++i )
|
||||
{
|
||||
const int iMinus = (i > 0) ? (i-1) : 0;
|
||||
const int iPlus = (i < inWidth - 1 ) ? (i+1) : i;
|
||||
for ( int j = 0; j < inHeight; ++j )
|
||||
{
|
||||
const int jMinus = (j > 0) ? (j-1) : 0;
|
||||
const int jPlus = (j < inHeight - 1 ) ? (j+1) : j;
|
||||
const uint32 A = inputBuffer[ iMinus +inWidth*jMinus];
|
||||
const uint32 B = inputBuffer[ iMinus +inWidth*j ];
|
||||
const uint32 C = inputBuffer[ iMinus +inWidth*jPlus];
|
||||
const uint32 D = inputBuffer[ i +inWidth*jMinus];
|
||||
const uint32 E = inputBuffer[ i +inWidth*j ];
|
||||
const uint32 F = inputBuffer[ i +inWidth*jPlus];
|
||||
const uint32 G = inputBuffer[ iPlus +inWidth*jMinus];
|
||||
const uint32 H = inputBuffer[ iPlus +inWidth*j ];
|
||||
const uint32 I = inputBuffer[ iPlus +inWidth*jPlus];
|
||||
if (B != H && D != F) {
|
||||
outputBuffer[3*i + width*3*j ] = D == B ? D : E;
|
||||
outputBuffer[3*i + width*(3*j+1)] = (D == B && E != C) || (B == F && E != A) ? B : E;
|
||||
outputBuffer[3*i + width*(3*j+2)] = B == F ? F : E;
|
||||
outputBuffer[3*i+1 + width*3*j ] = (D == B && E != G) || (D == H && E != A) ? D : E;
|
||||
outputBuffer[3*i+1 + width*(3*j+1)] = E;
|
||||
outputBuffer[3*i+1 + width*(3*j+2)] = (B == F && E != I) || (H == F && E != C) ? F : E;
|
||||
outputBuffer[3*i+2 + width*3*j ] = D == H ? D : E;
|
||||
outputBuffer[3*i+2 + width*(3*j+1)] = (D == H && E != I) || (H == F && E != G) ? H : E;
|
||||
outputBuffer[3*i+2 + width*(3*j+2)] = H == F ? F : E;
|
||||
} else {
|
||||
outputBuffer[3*i + width*3*j ] = E;
|
||||
outputBuffer[3*i + width*(3*j+1)] = E;
|
||||
outputBuffer[3*i + width*(3*j+2)] = E;
|
||||
outputBuffer[3*i+1 + width*3*j ] = E;
|
||||
outputBuffer[3*i+1 + width*(3*j+1)] = E;
|
||||
outputBuffer[3*i+1 + width*(3*j+2)] = E;
|
||||
outputBuffer[3*i+2 + width*3*j ] = E;
|
||||
outputBuffer[3*i+2 + width*(3*j+1)] = E;
|
||||
outputBuffer[3*i+2 + width*(3*j+2)] = E;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void scale4x ( uint32* inputBuffer, uint32* outputBuffer, int inWidth, int inHeight )
|
||||
{
|
||||
int width = 2* inWidth;
|
||||
int height = 2 * inHeight;
|
||||
uint32 * buffer2x = new uint32[width*height];
|
||||
|
||||
scale2x ( reinterpret_cast<uint32*> ( inputBuffer ), reinterpret_cast<uint32*> ( buffer2x ), inWidth, inHeight );
|
||||
width *= 2;
|
||||
height *= 2;
|
||||
scale2x ( reinterpret_cast<uint32*> ( buffer2x ), reinterpret_cast<uint32*> ( outputBuffer ), 2*inWidth, 2*inHeight );
|
||||
delete[] buffer2x;
|
||||
}
|
||||
|
||||
|
||||
static unsigned char *scaleNxHelper( void (*scaleNxFunction) ( uint32* , uint32* , int , int),
|
||||
const int N,
|
||||
unsigned char *inputBuffer,
|
||||
const int inWidth,
|
||||
const int inHeight,
|
||||
int &outWidth,
|
||||
int &outHeight )
|
||||
{
|
||||
outWidth = N * inWidth;
|
||||
outHeight = N *inHeight;
|
||||
unsigned char * newBuffer = new unsigned char[outWidth*outHeight*4];
|
||||
|
||||
scaleNxFunction ( reinterpret_cast<uint32*> ( inputBuffer ), reinterpret_cast<uint32*> ( newBuffer ), inWidth, inHeight );
|
||||
delete[] inputBuffer;
|
||||
return newBuffer;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// [BB] Upsamples the texture in inputBuffer, frees inputBuffer and returns
|
||||
// the upsampled buffer.
|
||||
//
|
||||
//===========================================================================
|
||||
unsigned char *gl_CreateUpsampledTextureBuffer ( const FGLTexture *inputGLTexture, unsigned char *inputBuffer, const int inWidth, const int inHeight, int &outWidth, int &outHeight )
|
||||
{
|
||||
// [BB] Don't resample if the width or height of the input texture is bigger than gl_texture_hqresize_maxinputsize.
|
||||
if ( ( inWidth > gl_texture_hqresize_maxinputsize ) || ( inHeight > gl_texture_hqresize_maxinputsize ) )
|
||||
return inputBuffer;
|
||||
|
||||
// [BB] The hqnx upsampling (not the scaleN one) destroys partial transparency, don't upsamle textures using it.
|
||||
if ( inputGLTexture->bIsTransparent == 1 )
|
||||
return inputBuffer;
|
||||
|
||||
switch (inputGLTexture->tex->UseType)
|
||||
{
|
||||
case FTexture::TEX_Sprite:
|
||||
case FTexture::TEX_SkinSprite:
|
||||
if (!(gl_texture_hqresize_targets & 2)) return inputBuffer;
|
||||
break;
|
||||
|
||||
case FTexture::TEX_FontChar:
|
||||
if (!(gl_texture_hqresize_targets & 4)) return inputBuffer;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!(gl_texture_hqresize_targets & 1)) return inputBuffer;
|
||||
break;
|
||||
}
|
||||
|
||||
if (inputBuffer)
|
||||
{
|
||||
outWidth = inWidth;
|
||||
outHeight = inHeight;
|
||||
int type = gl_texture_hqresize;
|
||||
switch (type)
|
||||
{
|
||||
case 1:
|
||||
return scaleNxHelper( &scale2x, 2, inputBuffer, inWidth, inHeight, outWidth, outHeight );
|
||||
case 2:
|
||||
return scaleNxHelper( &scale3x, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight );
|
||||
case 3:
|
||||
return scaleNxHelper( &scale4x, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight );
|
||||
}
|
||||
}
|
||||
return inputBuffer;
|
||||
}
|
43
src/gl/gl_hqresize.h
Normal file
43
src/gl/gl_hqresize.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
** gl_hqresize.h
|
||||
** Contains high quality upsampling functions.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2008 Benjamin Berkels
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#ifndef __GL_HQRESIZE_H__
|
||||
#define __GL_HQRESIZE_H__
|
||||
|
||||
#include "gl_texture.h"
|
||||
|
||||
unsigned char *gl_CreateUpsampledTextureBuffer ( const FGLTexture *inputGLTexture, unsigned char *inputBuffer, const int inWidth, const int inHeight, int &outWidth, int &outHeight );
|
||||
|
||||
#endif // __GL_HQRESIZE_H__
|
||||
|
|
@ -39,6 +39,10 @@ EXTERN_CVAR (Bool, gl_lights_additive)
|
|||
EXTERN_CVAR (Float, gl_light_ambient)
|
||||
EXTERN_CVAR(Int, gl_billboard_mode)
|
||||
EXTERN_CVAR(Int, gl_particles_style)
|
||||
EXTERN_CVAR(Int, gl_texture_hqresize)
|
||||
EXTERN_CVAR(Flag, gl_texture_hqresize_textures)
|
||||
EXTERN_CVAR(Flag, gl_texture_hqresize_sprites)
|
||||
EXTERN_CVAR(Flag, gl_texture_hqresize_fonts)
|
||||
|
||||
static value_t SpriteclipModes[]=
|
||||
{
|
||||
|
@ -133,6 +137,20 @@ static value_t Particles[] =
|
|||
{ 2.0, "Smooth" },
|
||||
};
|
||||
|
||||
static value_t HqResizeModes[] =
|
||||
{
|
||||
{ 0.0, "Off" },
|
||||
{ 1.0, "Scale2x" },
|
||||
{ 2.0, "Scale3x" },
|
||||
{ 3.0, "Scale4x" },
|
||||
};
|
||||
|
||||
static value_t HqResizeTargets[] =
|
||||
{
|
||||
{ 0.0, "Everything" },
|
||||
{ 1.0, "Sprites/fonts" },
|
||||
};
|
||||
|
||||
static value_t FogMode[] =
|
||||
{
|
||||
{ 0.0, "Off" },
|
||||
|
@ -168,6 +186,10 @@ menuitem_t GLTextureItems[] = {
|
|||
{ discrete, "Anisotropic filter", {&gl_texture_filter_anisotropic},{5.0},{0.0}, {0.0}, {Anisotropy} },
|
||||
{ discrete, "Texture Format", {&gl_texture_format}, {8.0}, {0.0}, {0.0}, {TextureFormats} },
|
||||
{ discrete, "Enable hires textures", {&gl_texture_usehires}, {2.0}, {0.0}, {0.0}, {YesNo} },
|
||||
{ discrete, "High Quality Resize mode", {&gl_texture_hqresize}, {4.0}, {0.0}, {0.0}, {HqResizeModes} },
|
||||
{ discrete, "Resize textures", {&gl_texture_hqresize_textures},{2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
{ discrete, "Resize sprites", {&gl_texture_hqresize_sprites}, {2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
{ discrete, "Resize fonts", {&gl_texture_hqresize_fonts}, {2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
{ discrete, "Precache GL textures", {&gl_precache}, {2.0}, {0.0}, {0.0}, {YesNo} },
|
||||
};
|
||||
|
||||
|
|
|
@ -1,239 +0,0 @@
|
|||
/*
|
||||
** gl_missinglines.cpp
|
||||
** This mess is only needed because ZDBSP likes to throw out lines
|
||||
** out of the BSP if they overlap
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2005 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
** 4. When not used as part of GZDoom or a GZDoom derivative, this code will be
|
||||
** covered by the terms of the GNU Lesser General Public License as published
|
||||
** by the Free Software Foundation; either version 2.1 of the License, or (at
|
||||
** your option) any later version.
|
||||
** 5. Full disclosure of the entire project's source code, except for third
|
||||
** party libraries is mandatory. (NOTE: This clause is non-negotiable!)
|
||||
**
|
||||
** 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 "gl/gl_include.h"
|
||||
#include "p_local.h"
|
||||
#include "gl/gl_struct.h"
|
||||
#include "gl/gl_renderstruct.h"
|
||||
#include "gl/gl_glow.h"
|
||||
#include "gl/gl_data.h"
|
||||
#include "gl/gl_basic.h"
|
||||
#include "gl/gl_functions.h"
|
||||
#include "gl/gl_geometric.h"
|
||||
|
||||
static seg_t * compareseg;
|
||||
int firstmissingseg;
|
||||
|
||||
static int STACK_ARGS segcmp(const void * a, const void * b)
|
||||
{
|
||||
seg_t * seg1 = *((seg_t**)a);
|
||||
seg_t * seg2 = *((seg_t**)b);
|
||||
|
||||
return
|
||||
P_AproxDistance(seg2->v1->x - compareseg->v1->x, seg2->v1->y - compareseg->v1->y) -
|
||||
P_AproxDistance(seg1->v1->x - compareseg->v1->x, seg1->v1->y - compareseg->v1->y);
|
||||
|
||||
//return (seg2->v1 - compareseg->v1).LengthSquared() - (seg1->v1 - compareseg->v1).LengthSquared();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Collect all sidedefs which are not entirely covered by segs
|
||||
//
|
||||
// (Sigh! Why do I have to compensate for ZDBSP's shortcomings...)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void gl_CollectMissingLines()
|
||||
{
|
||||
firstmissingseg=numsegs;
|
||||
|
||||
TArray<seg_t> MissingSides;
|
||||
TArray<seg_t*> * linesegs = new TArray<seg_t*>[numsides];
|
||||
|
||||
float * added_seglen = new float[numsides];
|
||||
|
||||
memset(added_seglen, 0, sizeof(float)*numsides);
|
||||
for(int i=0;i<numsegs;i++)
|
||||
{
|
||||
seg_t * seg = &segs[i];
|
||||
|
||||
if (seg->sidedef!=NULL)
|
||||
{
|
||||
// collect all the segs and calculate the length they occupy on their sidedef
|
||||
|
||||
//added_seglen[seg->linedef-lines + side]+= (*seg->v2 - *seg->v1).Length();
|
||||
#ifdef _MSC_VER
|
||||
added_seglen[seg->sidedef - sides]+= (Vector(seg->v2)-Vector(seg->v1)).Length();
|
||||
#else
|
||||
Vector vec1(Vector(seg->v1));
|
||||
Vector vec2(Vector(seg->v2));
|
||||
Vector tmpVec = vec2-vec1;
|
||||
added_seglen[seg->sidedef - sides]+= tmpVec.Length();
|
||||
#endif
|
||||
linesegs[seg->sidedef - sides].Push(seg);
|
||||
}
|
||||
}
|
||||
MissingSides.Clear();
|
||||
for(int i=0;i<numsides;i++)
|
||||
{
|
||||
side_t * side =&sides[i];
|
||||
line_t * line = &lines[side->linenum];
|
||||
|
||||
//float linelen = (*line->v2 - *line->v1).Length();
|
||||
#ifdef _MSC_VER
|
||||
float linelen = (Vector(line->v2)-Vector(line->v1)).Length();
|
||||
#else
|
||||
Vector vec1(Vector(line->v1));
|
||||
Vector vec2(Vector(line->v2));
|
||||
Vector tmpVec = (vec2-vec1);
|
||||
float linelen = tmpVec.Length();
|
||||
#endif
|
||||
|
||||
if (added_seglen[i] < linelen -1)
|
||||
{
|
||||
Printf("Sidedef %d (linedef %d) incomplete (Length = %f of %f)\n",
|
||||
i,side->linenum, added_seglen[i], linelen);
|
||||
|
||||
// create a seg for the sidedef
|
||||
seg_t seg;
|
||||
seg.sidedef = side;
|
||||
seg.linedef = line;
|
||||
if (side == &sides[line->sidenum[0]])
|
||||
{
|
||||
seg.v1 = line->v1;
|
||||
seg.v2 = line->v2;
|
||||
seg.frontsector = line->frontsector;
|
||||
seg.backsector = line->backsector;
|
||||
}
|
||||
else
|
||||
{
|
||||
seg.v2 = line->v1;
|
||||
seg.v1 = line->v2;
|
||||
seg.backsector = line->frontsector;
|
||||
seg.frontsector = line->backsector;
|
||||
}
|
||||
seg.Subsector = NULL;
|
||||
seg.PartnerSeg=NULL;
|
||||
seg.bPolySeg=false;
|
||||
|
||||
if (linesegs[i].Size()!=0)
|
||||
{
|
||||
// There are already segs for this line so
|
||||
// we have to fill in the gaps. To make polyobject
|
||||
// spawning possible the sidedef has do be properly
|
||||
// split into segs that span its entire length
|
||||
compareseg = &seg;
|
||||
|
||||
// Sort the segs so inserting new ones becomes easier
|
||||
qsort(&linesegs[i][0], linesegs[i].Size(), sizeof(seg_t*), segcmp);
|
||||
|
||||
for(unsigned int j=0;j<linesegs[i].Size();j++)
|
||||
{
|
||||
if (linesegs[i][j]->v1 != seg.v1)
|
||||
{
|
||||
seg_t newseg = seg;
|
||||
newseg.v2 = linesegs[i][j]->v1;
|
||||
MissingSides.Push(newseg);
|
||||
}
|
||||
seg.v1 = linesegs[i][j]->v2;
|
||||
}
|
||||
}
|
||||
if (seg.v1!=seg.v2)
|
||||
{
|
||||
MissingSides.Push(seg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (MissingSides.Size())
|
||||
{
|
||||
// Now we have to add the newly created segs to the segs array so
|
||||
// that the polyobject spawn code has access to them.
|
||||
seg_t * newsegs = new seg_t[numsegs + MissingSides.Size()];
|
||||
|
||||
memcpy(newsegs, segs, sizeof(seg_t) * numsegs);
|
||||
memcpy(newsegs+numsegs, &MissingSides[0], sizeof(seg_t)*MissingSides.Size());
|
||||
for(int i = 0; i < numsegs; i++)
|
||||
{
|
||||
if (newsegs[i].PartnerSeg && newsegs[i].PartnerSeg>=segs && newsegs[i].PartnerSeg<segs+numsegs)
|
||||
newsegs[i].PartnerSeg = newsegs + (newsegs[i].PartnerSeg - segs);
|
||||
else newsegs[i].PartnerSeg=NULL;
|
||||
}
|
||||
numsegs += MissingSides.Size();
|
||||
delete [] segs;
|
||||
segs=newsegs;
|
||||
|
||||
Printf("%d missing segs counted\n", MissingSides.Size());
|
||||
}
|
||||
delete [] linesegs;
|
||||
delete [] added_seglen;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Render those lines
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void gl_RenderMissingLines()
|
||||
{
|
||||
for(int i=firstmissingseg;i<numsegs;i++)
|
||||
{
|
||||
seg_t * seg = &segs[i];
|
||||
|
||||
// This line has already been processed
|
||||
if (seg->linedef->validcount==validcount) continue;
|
||||
|
||||
// Don't draw lines facing away from the viewer
|
||||
divline_t dl = { seg->v1->x, seg->v1->y, seg->v2->x-seg->v1->x, seg->v2->y-seg->v1->y };
|
||||
if (P_PointOnDivlineSide(viewx, viewy, &dl)) continue;
|
||||
|
||||
// Unfortunately there is no simple means to exclude lines here so we have
|
||||
// to draw them all.
|
||||
sector_t ffakesec, bfakesec;
|
||||
|
||||
sector_t * sector = gl_FakeFlat(seg->frontsector, &ffakesec, false);
|
||||
sector_t * backsector;
|
||||
|
||||
if (seg->frontsector == seg->backsector) backsector=sector;
|
||||
else if (!seg->backsector) backsector=NULL;
|
||||
else backsector = gl_FakeFlat(seg->backsector, &bfakesec, true);
|
||||
|
||||
GLWall wall;
|
||||
|
||||
SetupWall.Clock();
|
||||
|
||||
wall.Process(seg, sector, backsector, NULL);
|
||||
rendered_lines++;
|
||||
|
||||
SetupWall.Unclock();
|
||||
}
|
||||
}
|
|
@ -55,7 +55,6 @@
|
|||
|
||||
// This is for debugging maps.
|
||||
CVAR(Bool, gl_notexturefill, false, 0);
|
||||
extern int firstmissingseg;
|
||||
|
||||
|
||||
FreeList<gl_subsectorrendernode> SSR_List;
|
||||
|
@ -939,7 +938,7 @@ ADD_STAT(missingtextures)
|
|||
|
||||
void GLDrawInfo::AddHackedSubsector(subsector_t * sub)
|
||||
{
|
||||
if (firstmissingseg==numsegs && !(level.flags & LEVEL_HEXENFORMAT))
|
||||
if (!(level.flags & LEVEL_HEXENFORMAT))
|
||||
{
|
||||
SubsectorHackInfo sh={sub, 0};
|
||||
SubsectorHacks.Push (sh);
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "doomerrors.h"
|
||||
#include "p_setup.h"
|
||||
#include "x86.h"
|
||||
#include "version.h"
|
||||
|
||||
node_t * gamenodes;
|
||||
int numgamenodes;
|
||||
|
@ -108,6 +109,49 @@ typedef struct
|
|||
} gl5_mapnode_t;
|
||||
|
||||
#define GL5_NF_SUBSECTOR (1 << 31)
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Collect all sidedefs which are not entirely covered by segs
|
||||
// Old ZDBSPs could create such maps. If such a BSP is discovered
|
||||
// a node rebuild must be done to ensure proper rendering
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int gl_CheckForMissingSegs()
|
||||
{
|
||||
float *added_seglen = new float[numsides];
|
||||
int missing = 0;
|
||||
|
||||
memset(added_seglen, 0, sizeof(float)*numsides);
|
||||
for(int i=0;i<numsegs;i++)
|
||||
{
|
||||
seg_t * seg = &segs[i];
|
||||
|
||||
if (seg->sidedef!=NULL)
|
||||
{
|
||||
// check all the segs and calculate the length they occupy on their sidedef
|
||||
TVector2<double> vec1(seg->v2->x - seg->v1->x, seg->v2->y - seg->v1->y);
|
||||
added_seglen[seg->sidedef - sides] += float(vec1.Length());
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0;i<numsides;i++)
|
||||
{
|
||||
side_t * side =&sides[i];
|
||||
line_t * line = &lines[side->linenum];
|
||||
|
||||
TVector2<double> lvec(line->dx, line->dy);
|
||||
float linelen = float(lvec.Length());
|
||||
|
||||
missing += (added_seglen[i] < linelen - 1);
|
||||
}
|
||||
|
||||
delete [] added_seglen;
|
||||
return missing;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Checks whether the nodes are suitable for GL rendering
|
||||
|
@ -144,7 +188,13 @@ bool gl_CheckForGLNodes()
|
|||
}
|
||||
// all subsectors were closed but there are no minisegs
|
||||
// Although unlikely this can happen. Such nodes are not a problem.
|
||||
return true;
|
||||
// all that is left is to check whether the BSP covers all sidedefs completely.
|
||||
int missing = gl_CheckForMissingSegs();
|
||||
if (missing > 0)
|
||||
{
|
||||
Printf("%d missing segs counted\nThe BSP needs to be rebuilt", missing);
|
||||
}
|
||||
return missing == 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -186,7 +236,7 @@ static bool gl_LoadVertexes(FileReader * f, wadlump_t * lump)
|
|||
// GLNodes V1 and V4 are unsupported.
|
||||
// V1 because the precision is insufficient and
|
||||
// V4 due to the missing partner segs
|
||||
Printf("GL nodes v%d found. This format is not supported by GZDoom\n",
|
||||
Printf("GL nodes v%d found. This format is not supported by "GAMENAME"\n",
|
||||
(*(int *)gldata == gNd4)? 4:1);
|
||||
|
||||
delete [] gldata;
|
||||
|
@ -256,7 +306,9 @@ bool gl_LoadGLSegs(FileReader * f, wadlump_t * lump)
|
|||
f->Read(data, lump->Size);
|
||||
segs=NULL;
|
||||
|
||||
try
|
||||
#ifdef _MSC_VER
|
||||
__try
|
||||
#endif
|
||||
{
|
||||
if (!format5 && memcmp(data, "gNd3", 4))
|
||||
{
|
||||
|
@ -346,16 +398,19 @@ bool gl_LoadGLSegs(FileReader * f, wadlump_t * lump)
|
|||
delete [] data;
|
||||
return true;
|
||||
}
|
||||
catch(...)
|
||||
#ifdef _MSC_VER
|
||||
__except(1)
|
||||
{
|
||||
// Invalid data has the bas habit of requiring extensive checks here
|
||||
// so let's just catch anything invalid and output a message.
|
||||
// (at least under MSVC. GCC can't do SEH even for Windows... :( )
|
||||
Printf("Invalid GL segs. The BSP will have to be rebuilt.\n");
|
||||
delete [] data;
|
||||
delete [] segs;
|
||||
segs = NULL;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -612,7 +667,7 @@ bool gl_DoLoadGLNodes(FileReader * f, wadlump_t * lumps)
|
|||
seg_t * seg = &segs[subsectors[i].firstline];
|
||||
if (!seg->sidedef)
|
||||
{
|
||||
Printf("GWA file contains invalid nodes. The BSP has to be rebuilt.\n");
|
||||
Printf("GL nodes contain invalid data. The BSP has to be rebuilt.\n");
|
||||
delete [] nodes;
|
||||
nodes = NULL;
|
||||
delete [] subsectors;
|
||||
|
@ -622,7 +677,14 @@ bool gl_DoLoadGLNodes(FileReader * f, wadlump_t * lumps)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
// check whether the BSP covers all sidedefs completely.
|
||||
int missing = gl_CheckForMissingSegs();
|
||||
if (missing > 0)
|
||||
{
|
||||
Printf("%d missing segs counted in GL nodes.\nThe BSP has to be rebuilt", missing);
|
||||
}
|
||||
return missing == 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -898,5 +960,4 @@ void gl_CheckNodes(MapData * map)
|
|||
gamesubsectors = subsectors;
|
||||
numgamesubsectors = numsubsectors;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -247,7 +247,7 @@ private:
|
|||
|
||||
public:
|
||||
|
||||
void Process(seg_t *seg, sector_t * frontsector, sector_t * backsector, subsector_t * polysub);
|
||||
void Process(seg_t *seg, sector_t * frontsector, sector_t * backsector, subsector_t * polysub, bool render_segs);
|
||||
void ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t * backsector);
|
||||
void Draw(int pass);
|
||||
|
||||
|
|
|
@ -342,7 +342,6 @@ static void ProcessScene()
|
|||
|
||||
// And now the crappy hacks that have to be done to avoid rendering anomalies:
|
||||
|
||||
gl_RenderMissingLines(); // Omitted lines by the node builder
|
||||
gl_drawinfo->HandleMissingTextures(); // Missing upper/lower textures
|
||||
gl_drawinfo->HandleHackedSubsectors(); // open sector hacks for deep water
|
||||
gl_drawinfo->ProcessSectorStacks(); // merge visplanes of sector stacks
|
||||
|
|
|
@ -163,6 +163,8 @@ public:
|
|||
line.sidedef = seg->sidedef;
|
||||
line.linedef = seg->linedef;
|
||||
line.refseg = seg;
|
||||
line.polysub = NULL;
|
||||
line.otherside = -1;
|
||||
|
||||
if (loop->numlines == 0)
|
||||
{
|
||||
|
|
|
@ -625,7 +625,7 @@ void GLShader::Bind(int cm, int lightmode, float Speed)
|
|||
|
||||
void GLShader::Unbind()
|
||||
{
|
||||
if (gl.flags & RFL_GLSL)
|
||||
if ((gl.flags & RFL_GLSL) && gl_activeShader != NULL)
|
||||
{
|
||||
gl.UseProgramObjectARB(0);
|
||||
gl_activeShader=NULL;
|
||||
|
|
|
@ -159,11 +159,9 @@ struct FGLSectionLine
|
|||
vertex_t *end;
|
||||
side_t *sidedef;
|
||||
line_t *linedef;
|
||||
union
|
||||
{
|
||||
int otherside;
|
||||
seg_t *refseg;
|
||||
};
|
||||
seg_t *refseg; // we need to reference at least one seg for each line.
|
||||
subsector_t *polysub; // If this is part of a polyobject we need a reference to the containing subsector
|
||||
int otherside;
|
||||
};
|
||||
|
||||
struct FGLSectionLoop
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include "gl/gl_functions.h"
|
||||
#include "gl/gl_shader.h"
|
||||
#include "gl/gl_translate.h"
|
||||
#include "gl/gl_hqresize.h"
|
||||
|
||||
CUSTOM_CVAR(Bool, gl_texture_usehires, true, CVAR_ARCHIVE|CVAR_NOINITCALL)
|
||||
{
|
||||
|
@ -1164,6 +1165,9 @@ unsigned char * FGLTexture::CreateTexBuffer(ETexUse use, int _cm, int translatio
|
|||
tex->FTexture::CopyTrueColorPixels(&bmp, GetLeftOffset(use) - tex->LeftOffset, GetTopOffset(use) - tex->TopOffset);
|
||||
}
|
||||
|
||||
// [BB] Potentially upsample the buffer.
|
||||
buffer = gl_CreateUpsampledTextureBuffer ( this, buffer, W, H, w, h );
|
||||
|
||||
if ((!(gl.flags & RFL_GLSL) || !gl_warp_shader) && tex->bWarped && W <= 256 && H <= 256)
|
||||
{
|
||||
buffer = WarpBuffer(buffer, W, H, tex->bWarped);
|
||||
|
@ -1209,7 +1213,7 @@ const PatchTextureInfo * FGLTexture::GetPatchTextureInfo()
|
|||
|
||||
//===========================================================================
|
||||
//
|
||||
// Checls if a shader needs to be used for this texture
|
||||
// Checks if a shader needs to be used for this texture
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
|
|
|
@ -1364,7 +1364,7 @@ void GLWall::DoFFloorBlocks(seg_t * seg,sector_t * frontsector,sector_t * backse
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector, subsector_t * polysub)
|
||||
void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector, subsector_t * polysub, bool render_segs)
|
||||
{
|
||||
vertex_t * v1, * v2;
|
||||
fixed_t fch1;
|
||||
|
@ -1410,7 +1410,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector,
|
|||
glseg.fracleft=0;
|
||||
glseg.fracright=1;
|
||||
|
||||
if (gl_render_segs)
|
||||
if (render_segs)
|
||||
{
|
||||
if (abs(v1->x-v2->x) > abs(v1->y-v2->y))
|
||||
{
|
||||
|
|
|
@ -267,6 +267,8 @@ static FSaveGameNode NewSaveNode;
|
|||
|
||||
static int epi; // Selected episode
|
||||
|
||||
static const char *saved_playerclass = NULL;
|
||||
|
||||
// PRIVATE MENU DEFINITIONS ------------------------------------------------
|
||||
|
||||
//
|
||||
|
@ -1821,15 +1823,18 @@ void M_Episode (int choice)
|
|||
|
||||
if (AllSkills.Size() == 1)
|
||||
{
|
||||
saved_playerclass = NULL;
|
||||
M_ChooseSkill(0);
|
||||
return;
|
||||
}
|
||||
else if (EpisodeNoSkill[choice])
|
||||
{
|
||||
saved_playerclass = NULL;
|
||||
M_ChooseSkill(AllSkills.Size() == 2? 1:2);
|
||||
return;
|
||||
}
|
||||
M_StartupSkillMenu(NULL);
|
||||
M_StartupSkillMenu(saved_playerclass);
|
||||
saved_playerclass = NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1856,6 +1861,7 @@ static void SCClass (int option)
|
|||
|
||||
if (EpiDef.numitems > 1)
|
||||
{
|
||||
saved_playerclass = playerclass;
|
||||
M_SetupNextMenu (&EpiDef);
|
||||
}
|
||||
else if (AllSkills.Size() == 1)
|
||||
|
@ -1888,6 +1894,7 @@ static void M_ChooseClass (int choice)
|
|||
|
||||
if (EpiDef.numitems > 1)
|
||||
{
|
||||
saved_playerclass = playerclass;
|
||||
M_SetupNextMenu (&EpiDef);
|
||||
}
|
||||
else if (AllSkills.Size() == 1)
|
||||
|
|
|
@ -1044,17 +1044,25 @@ static menuitem_t DMFlagsItems[] = {
|
|||
{ bitflag, "Infinite ammo", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_INFINITE_AMMO} },
|
||||
{ bitflag, "Infinite inventory", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_INFINITE_INVENTORY} },
|
||||
{ bitflag, "No monsters", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_NO_MONSTERS} },
|
||||
{ bitflag, "No monsters to exit", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_KILL_MONSTERS} },
|
||||
{ bitflag, "Monsters respawn", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_MONSTERS_RESPAWN} },
|
||||
{ bitflag, "No respawn", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_NO_RESPAWN} },
|
||||
{ bitflag, "Items respawn", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_ITEMS_RESPAWN} },
|
||||
{ bitflag, "Big powerups respawn", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_RESPAWN_SUPER} },
|
||||
{ bitflag, "Fast monsters", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_FAST_MONSTERS} },
|
||||
{ bitflag, "Degeneration", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_DEGENERATION} },
|
||||
{ bitflag, "Allow Autoaim", {&dmflags2}, {1}, {0}, {0}, {(value_t *)DF2_NOAUTOAIM} },
|
||||
{ bitflag, "Disallow Suicide", {&dmflags2}, {1}, {0}, {0}, {(value_t *)DF2_NOSUICIDE} },
|
||||
{ bitmask, "Allow jump", {&dmflags}, {3.0}, {DF_NO_JUMP|DF_YES_JUMP}, {0}, {DF_Jump} },
|
||||
{ bitmask, "Allow crouch", {&dmflags}, {3.0}, {DF_NO_CROUCH|DF_YES_CROUCH}, {0}, {DF_Crouch} },
|
||||
{ bitflag, "Allow freelook", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_FREELOOK} },
|
||||
{ bitflag, "Allow FOV", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_FOV} },
|
||||
{ bitflag, "Allow BFG aiming", {&dmflags2}, {1}, {0}, {0}, {(value_t *)DF2_NO_FREEAIMBFG} },
|
||||
{ bitflag, "Allow automap", {&dmflags2}, {1}, {0}, {0}, {(value_t *)DF2_NO_AUTOMAP} },
|
||||
{ bitflag, "Automap allies", {&dmflags2}, {1}, {0}, {0}, {(value_t *)DF2_NO_AUTOMAP_ALLIES} },
|
||||
{ bitflag, "Allow spying", {&dmflags2}, {1}, {0}, {0}, {(value_t *)DF2_DISALLOW_SPYING} },
|
||||
{ bitflag, "Chasecam cheat", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_CHASECAM} },
|
||||
|
||||
{ redtext, " ", {NULL}, {0}, {0}, {0}, {NULL} },
|
||||
{ whitetext,"Deathmatch Settings", {NULL}, {0}, {0}, {0}, {NULL} },
|
||||
{ bitflag, "Weapons stay", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_WEAPONS_STAY} },
|
||||
|
|
|
@ -1451,6 +1451,10 @@ CCMD (kill)
|
|||
}
|
||||
else
|
||||
{
|
||||
// If suiciding is disabled, then don't do it.
|
||||
if (dmflags2 & DF2_NOSUICIDE)
|
||||
return;
|
||||
|
||||
// Kill the player
|
||||
Net_WriteByte (DEM_SUICIDE);
|
||||
}
|
||||
|
|
|
@ -135,6 +135,10 @@ bool CheckIfExitIsGood (AActor *self, level_info_t *info)
|
|||
if (self == NULL)
|
||||
return true;
|
||||
|
||||
// We must kill all monsters to exit the level.
|
||||
if ((dmflags2 & DF2_KILL_MONSTERS) && level.killed_monsters != level.total_monsters)
|
||||
return false;
|
||||
|
||||
// Is this a deathmatch game and we're not allowed to exit?
|
||||
if ((deathmatch || alwaysapplydmflags) && (dmflags & DF_NO_EXIT))
|
||||
{
|
||||
|
|
|
@ -686,6 +686,31 @@ AWeapon *APlayerPawn::PickNewWeapon (const PClass *ammotype)
|
|||
return best;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APlayerPawn :: CheckWeaponSwitch
|
||||
//
|
||||
// Checks if weapons should be changed after picking up ammo
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APlayerPawn::CheckWeaponSwitch(const PClass *ammotype)
|
||||
{
|
||||
if (!player->userinfo.neverswitch &&
|
||||
player->PendingWeapon == WP_NOCHANGE &&
|
||||
(player->ReadyWeapon == NULL ||
|
||||
(player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)))
|
||||
{
|
||||
AWeapon *best = BestWeapon (ammotype);
|
||||
if (best != NULL && (player->ReadyWeapon == NULL ||
|
||||
best->SelectionOrder < player->ReadyWeapon->SelectionOrder))
|
||||
{
|
||||
player->PendingWeapon = best;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APlayerPawn :: GiveDeathmatchInventory
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
// This file was automatically generated by the
|
||||
// updaterevision tool. Do not edit by hand.
|
||||
|
||||
#define ZD_SVN_REVISION_STRING "1327"
|
||||
#define ZD_SVN_REVISION_NUMBER 1327
|
||||
#define ZD_SVN_REVISION_STRING "1333"
|
||||
#define ZD_SVN_REVISION_NUMBER 1333
|
||||
|
|
|
@ -325,7 +325,14 @@ do_stop:
|
|||
sc.ScriptError("Negative jump offsets are not allowed");
|
||||
}
|
||||
|
||||
x = new FxStateByIndex(bag.statedef.GetStateCount() + v, sc);
|
||||
if (x > 0)
|
||||
{
|
||||
x = new FxStateByIndex(bag.statedef.GetStateCount() + v, sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = new FxConstant((FState*)NULL, sc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue