# Conflicts:
#	src/CMakeLists.txt
#	src/asm_ia32/tmap2.asm
#	src/r_draw.h
#	src/r_drawt.cpp
#	src/r_main.cpp
#	src/r_things.cpp
#	src/r_things.h
#	src/win32/fb_d3d9.cpp
This commit is contained in:
nashmuhandes 2016-11-04 12:22:39 +08:00
commit e3df34845d
31 changed files with 624 additions and 112 deletions

View file

@ -94,6 +94,15 @@ function( add_pk3 PK3_NAME PK3_DIR )
SOURCES ${PK3_SRCS})
# Phase 3: Assign source files to a nice folder structure in the IDE
assort_pk3_source_folder("Source Files" ${PK3_DIR})
# Phase 4: Add the resulting PK3 to the install target.
if( WIN32 )
set( INSTALL_PK3_PATH . CACHE STRING "Directory where zdoom.pk3 will be placed during install." )
else()
set( INSTALL_PK3_PATH share/games/doom CACHE STRING "Directory where zdoom.pk3 will be placed during install." )
endif()
install(FILES "${PROJECT_BINARY_DIR}/${PK3_NAME}"
DESTINATION ${INSTALL_PK3_PATH}
COMPONENT "Game resources")
endfunction()
# Macro for building libraries without debugging information
@ -251,6 +260,7 @@ if( ZLIB_FOUND AND NOT FORCE_INTERNAL_ZLIB )
message( STATUS "Using system zlib, includes found at ${ZLIB_INCLUDE_DIR}" )
else()
message( STATUS "Using internal zlib" )
set( SKIP_INSTALL_ALL TRUE ) # Avoid installing zlib alongside zdoom
add_subdirectory( zlib )
set( ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zlib )
set( ZLIB_LIBRARIES z )
@ -294,6 +304,16 @@ if( NOT CMAKE_CROSSCOMPILING )
endif()
endif()
# Install the entire docs directory in the distributed zip package
if( WIN32 )
set( INSTALL_DOCS_PATH docs CACHE STRING "Directory where the documentation will be placed during install." )
else()
set( INSTALL_DOCS_PATH share/doc/${ZDOOM_EXE_NAME} CACHE STRING "Directory where the zdoom documentation will be placed during install." )
endif()
install(DIRECTORY docs/
DESTINATION ${INSTALL_DOCS_PATH}
COMPONENT "Documentation")
add_subdirectory( lzma )
add_subdirectory( tools )
add_subdirectory( dumb )

View file

@ -87,16 +87,14 @@ conversation // Starts a dialog.
page // Starts a new page. Pages are automatically numbered starting at 1.
{
name = <string>; // Name that goes in the upper left hand corner
panel = <string>; // Name of lump to render as the background.
voice = <string>; // Narration sound lump.
dialog = <string>; // Dialog of the page.
goodbye = <string>; // Custom goodbye message. If omitted then the
// generic goodbyes will be displayed instead.
drop = <integer>; // mobj for the object to drop if the actor is
// killed.
link = <integer>; // Page to jump to if all ifitem conditions are
// satisified.
name = <string>; // Name that goes in the upper left hand corner
panel = <string>; // Name of lump to render as the background.
voice = <string>; // Narration sound lump.
dialog = <string>; // Dialog of the page.
drop = <integer>; // mobj for the object to drop if the actor is
// killed.
link = <integer>; // Page to jump to if all ifitem conditions are
// satisified.
// jumps to the specified page if the player has the specified amount
// or more of item in their inventory. This can be repeated as many

View file

@ -76,8 +76,8 @@ namespace = "ZDoom";
III.A : Conversations
---------------------
This block only lists the newly added fields. Currently ZDoom only adds one
field to the specification:
This block only lists the newly added fields. Currently ZDoom only adds a few
fields to the specification:
conversation // Starts a dialog.
{
@ -86,6 +86,35 @@ conversation // Starts a dialog.
// the standard conversation ID ('actor' property) is used instead
// for this purpose but since 'ZDoom' namespace requires the actor
// to be a class name it needs a separate field for this.
page
{
goodbye = <string>; // Custom goodbye message. If omitted then the
// generic goodbyes will be displayed instead.
choice
{
// The amount of an item needed for this option to become available.
// You can have as many as needed. All require blocks must be satisfied
// to show this option.
require
{
item = <string>; // Item that is required to show this option.
amount = <integer>; // Minimum amount of the item needed.
}
// The undesired amount of an item. This option will become available
// if you have less than the specified amount. You can have as many
// as needed. All exclude blocks must be satisfied to show this option.
// Note: if both require and exclude are defined then all require
// and all exclude blocks must be satisfied to show this option.
exclude
{
item = <string>; // Item that is unwanted to show this option.
amount = <integer>; // Unwanted minimum amount of the item.
}
}
}
}
===============================================================================

View file

@ -1233,6 +1233,15 @@ if( APPLE )
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/posix/osx/zdoom-info.plist" )
endif()
if( WIN32 )
set( INSTALL_PATH . CACHE STRING "Directory where the zdoom executable will be placed during install." )
else()
set( INSTALL_PATH bin CACHE STRING "Directory where the zdoom executable will be placed during install." )
endif()
install(TARGETS zdoom
DESTINATION ${INSTALL_PATH}
COMPONENT "Game executable")
source_group("Audio Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/.+")
source_group("Audio Files\\Timidity\\Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.h$")
source_group("Audio Files\\Timidity\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.cpp$")

View file

@ -72,6 +72,9 @@ extern bool netgame;
// Bot game? Like netgame, but doesn't involve network communication.
extern bool multiplayer;
// [SP] Map dm/coop implementation - invokes fake multiplayer without bots
extern bool multiplayernext;
// Flag: true only if started as net deathmatch.
EXTERN_CVAR (Int, deathmatch)

View file

@ -165,6 +165,7 @@ bool viewactive;
bool netgame; // only true if packets are broadcast
bool multiplayer;
bool multiplayernext = false; // [SP] Map coop/dm implementation
player_t players[MAXPLAYERS];
bool playeringame[MAXPLAYERS];
@ -1656,9 +1657,10 @@ static void G_QueueBody (AActor *body)
//
// G_DoReborn
//
EXTERN_CVAR(Bool, sv_singleplayerrespawn)
void G_DoReborn (int playernum, bool freshbot)
{
if (!multiplayer && !(level.flags2 & LEVEL2_ALLOWRESPAWN))
if (!multiplayer && !(level.flags2 & LEVEL2_ALLOWRESPAWN) && !sv_singleplayerrespawn)
{
if (BackupSaveName.Len() > 0 && FileExists (BackupSaveName.GetChars()))
{ // Load game from the last point it was saved

View file

@ -90,6 +90,8 @@
#include "g_hub.h"
#include <string.h>
void STAT_StartNewGame(const char *lev);
void STAT_ChangeLevel(const char *newl);
@ -181,6 +183,16 @@ CCMD (map)
}
else
{
if (argv.argc() > 2 && stricmp(argv[2], "coop") == 0)
{
deathmatch = false;
multiplayernext = true;
}
else if (argv.argc() > 2 && stricmp(argv[2], "dm") == 0)
{
deathmatch = true;
multiplayernext = true;
}
G_DeferedInitNew (argv[1]);
}
}
@ -192,7 +204,7 @@ CCMD (map)
}
else
{
Printf ("Usage: map <map name>\n");
Printf ("Usage: map <map name> [coop|dm]\n");
}
}
@ -218,6 +230,16 @@ CCMD(recordmap)
}
else
{
if (argv.argc() > 3 && stricmp(argv[3], "coop") == 0)
{
deathmatch = false;
multiplayernext = true;
}
else if (argv.argc() > 3 && stricmp(argv[3], "dm") == 0)
{
deathmatch = true;
multiplayernext = true;
}
G_DeferedInitNew(argv[2]);
gameaction = ga_recordgame;
newdemoname = argv[1];
@ -232,7 +254,7 @@ CCMD(recordmap)
}
else
{
Printf("Usage: recordmap <filename> <map name>\n");
Printf("Usage: recordmap <filename> <map name> [coop|dm]\n");
}
}
@ -258,13 +280,23 @@ CCMD (open)
}
else
{
if (argv.argc() > 2 && stricmp(argv[2], "coop") == 0)
{
deathmatch = false;
multiplayernext = true;
}
else if (argv.argc() > 2 && stricmp(argv[2], "dm") == 0)
{
deathmatch = true;
multiplayernext = true;
}
gameaction = ga_newgame2;
d_skill = -1;
}
}
else
{
Printf ("Usage: open <map file>\n");
Printf ("Usage: open <map file> [coop|dm]\n");
}
}
@ -293,7 +325,8 @@ void G_NewInit ()
G_ClearSnapshots ();
ST_SetNeedRefresh();
netgame = false;
multiplayer = false;
multiplayer = multiplayernext;
multiplayernext = false;
if (demoplayback)
{
C_RestoreCVars ();
@ -526,6 +559,8 @@ static bool unloading;
//
//==========================================================================
EXTERN_CVAR(Bool, sv_singleplayerrespawn)
void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill)
{
level_info_t *nextinfo = NULL;
@ -634,7 +669,7 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill
// If this is co-op, respawn any dead players now so they can
// keep their inventory on the next map.
if ((multiplayer || level.flags2 & LEVEL2_ALLOWRESPAWN) && !deathmatch && player->playerstate == PST_DEAD)
if ((multiplayer || level.flags2 & LEVEL2_ALLOWRESPAWN || sv_singleplayerrespawn) && !deathmatch && player->playerstate == PST_DEAD)
{
// Copied from the end of P_DeathThink [[
player->cls = NULL; // Force a new class if the player is using a random class

View file

@ -640,6 +640,7 @@ void AWeapon::PostMorphWeapon ()
pspr = Owner->player->GetPSprite(PSP_WEAPON);
pspr->y = WEAPONBOTTOM;
pspr->ResetInterpolation();
pspr->SetState(GetUpState());
}

View file

@ -585,6 +585,8 @@ xx(Ifitem)
xx(Choice)
xx(Link)
xx(Goodbye)
xx(Require)
xx(Exclude)
// Special menus
xx(Mainmenu)

View file

@ -375,6 +375,7 @@ void ACSStringPool::Clear()
int ACSStringPool::AddString(const char *str)
{
if (str == nullptr) str = "";
size_t len = strlen(str);
unsigned int h = SuperFastHash(str, len);
unsigned int bucketnum = h % NUM_BUCKETS;
@ -791,6 +792,10 @@ void ACSStringPool::WriteStrings(FSerializer &file, const char *key) const
{
if (file.BeginObject(nullptr))
{
if (i == 430)
{
int a = 0;
}
file("index", i)
("string", entry->Str)
("lockcount", entry->LockCount)
@ -5345,7 +5350,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
case ACSF_PlaySound:
case ACSF_PlayActorSound:
// PlaySound(tid, "SoundName", channel, volume, looping, attenuation)
// PlaySound(tid, "SoundName", channel, volume, looping, attenuation, local)
{
FSoundID sid;
@ -5366,6 +5371,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
float vol = argCount > 3 ? ACSToFloat(args[3]) : 1.f;
INTBOOL looping = argCount > 4 ? args[4] : false;
float atten = argCount > 5 ? ACSToFloat(args[5]) : ATTN_NORM;
INTBOOL local = argCount > 6 ? args[6] : false;
if (args[0] == 0)
{
@ -5382,11 +5388,11 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
{
if (!looping)
{
S_Sound(spot, chan, sid, vol, atten);
S_PlaySound(spot, chan, sid, vol, atten, local);
}
else if (!S_IsActorPlayingSomething(spot, chan & 7, sid))
{
S_Sound(spot, chan | CHAN_LOOP, sid, vol, atten);
S_PlaySound(spot, chan | CHAN_LOOP, sid, vol, atten, local);
}
}
}

View file

@ -1032,16 +1032,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PlaySound)
PARAM_FLOAT_OPT (volume) { volume = 1; }
PARAM_BOOL_OPT (looping) { looping = false; }
PARAM_FLOAT_OPT (attenuation) { attenuation = ATTN_NORM; }
PARAM_BOOL_OPT (local) { local = false; }
if (!looping)
{
S_Sound (self, channel, soundid, (float)volume, (float)attenuation);
S_PlaySound(self, channel, soundid, (float)volume, (float)attenuation, local);
}
else
{
if (!S_IsActorPlayingSomething (self, channel&7, soundid))
{
S_Sound (self, channel | CHAN_LOOP, soundid, (float)volume, (float)attenuation);
S_PlaySound(self, channel | CHAN_LOOP, soundid, (float)volume, (float)attenuation, local);
}
}
return 0;

View file

@ -516,6 +516,8 @@ static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses)
reply->ItemCheck[k].Item = dyn_cast<PClassInventory>(GetStrifeType(rsp->Item[k]));
reply->ItemCheck[k].Amount = rsp->Count[k];
}
reply->ItemCheckRequire.Clear();
reply->ItemCheckExclude.Clear();
// If the first item check has a positive amount required, then
// add that to the reply string. Otherwise, use the reply as-is.
@ -656,6 +658,38 @@ CUSTOM_CVAR(Float, dlg_musicvolume, 1.0f, CVAR_ARCHIVE)
else if (self > 1.f) self = 1.f;
}
//============================================================================
//
// ShouldSkipReply
//
// Determines whether this reply should be skipped or not.
//
//============================================================================
static bool ShouldSkipReply(FStrifeDialogueReply *reply, player_t *player)
{
if (reply->Reply == nullptr)
return true;
int i;
for (i = 0; i < (int)reply->ItemCheckRequire.Size(); ++i)
{
if (!CheckStrifeItem(player, reply->ItemCheckRequire[i].Item, reply->ItemCheckRequire[i].Amount))
{
return true;
}
}
for (i = 0; i < (int)reply->ItemCheckExclude.Size(); ++i)
{
if (CheckStrifeItem(player, reply->ItemCheckExclude[i].Item, reply->ItemCheckExclude[i].Amount))
{
return true;
}
}
return false;
}
//============================================================================
//
// The conversation menu
@ -673,6 +707,7 @@ class DConversationMenu : public DMenu
bool mShowGold;
FStrifeDialogueNode *mCurNode;
int mYpos;
player_t *mPlayer;
public:
static int mSelection;
@ -683,9 +718,10 @@ public:
//
//=============================================================================
DConversationMenu(FStrifeDialogueNode *CurNode)
DConversationMenu(FStrifeDialogueNode *CurNode, player_t *player)
{
mCurNode = CurNode;
mPlayer = player;
mDialogueLines = NULL;
mShowGold = false;
@ -720,7 +756,7 @@ public:
int i,j;
for (reply = CurNode->Children, i = 1; reply != NULL; reply = reply->Next)
{
if (reply->Reply == NULL)
if (ShouldSkipReply(reply, mPlayer))
{
continue;
}
@ -778,6 +814,13 @@ public:
}
ConversationMenuY = mYpos;
//ConversationMenu.indent = 50;
// Because replies can be selectively hidden mResponses.Size() won't be consistent.
// So make sure mSelection doesn't exceed mResponses.Size(). [FishyClockwork]
if (mSelection >= (int)mResponses.Size())
{
mSelection = mResponses.Size() - 1;
}
}
//=============================================================================
@ -839,12 +882,24 @@ public:
}
else
{
// Send dialogue and reply numbers across the wire.
assert((unsigned)mCurNode->ThisNodeNum < StrifeDialogues.Size());
assert(StrifeDialogues[mCurNode->ThisNodeNum] == mCurNode);
// This is needed because mSelection represents the replies currently being displayed which will
// not match up with what's supposed to be selected if there are any hidden/skipped replies. [FishyClockwork]
FStrifeDialogueReply *reply = mCurNode->Children;
int replynum = mSelection;
for (int i = 0; i <= mSelection && reply != nullptr; reply = reply->Next)
{
if (ShouldSkipReply(reply, mPlayer))
replynum++;
else
i++;
}
// Send dialogue and reply numbers across the wire.
Net_WriteByte(DEM_CONVREPLY);
Net_WriteWord(mCurNode->ThisNodeNum);
Net_WriteByte(mSelection);
Net_WriteByte(replynum);
}
Close();
return true;
@ -1169,7 +1224,7 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang
S_Sound (npc, CHAN_VOICE|CHAN_NOPAUSE, CurNode->SpeakerVoice, 1, ATTN_NORM);
}
DConversationMenu *cmenu = new DConversationMenu(CurNode);
DConversationMenu *cmenu = new DConversationMenu(CurNode, pc->player);
if (CurNode != PrevNode)

View file

@ -45,6 +45,8 @@ struct FStrifeDialogueReply
int ActionSpecial;
int Args[5];
TArray<FStrifeDialogueItemCheck> ItemCheck;
TArray<FStrifeDialogueItemCheck> ItemCheckRequire;
TArray<FStrifeDialogueItemCheck> ItemCheckExclude;
char *Reply;
char *QuickYes;
int NextNode; // index into StrifeDialogues

View file

@ -1,4 +1,4 @@
// Emacs style mode select -*- C++ -*-
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id:$
@ -4496,6 +4496,7 @@ void AActor::AdjustFloorClip ()
// Most of the player structure stays unchanged between levels.
//
EXTERN_CVAR (Bool, chasedemo)
EXTERN_CVAR(Bool, sv_singleplayerrespawn)
extern bool demonew;
@ -4683,7 +4684,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
{ // Give all cards in death match mode.
p->mo->GiveDeathmatchInventory ();
}
else if ((multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN)) && state == PST_REBORN && oldactor != NULL)
else if ((multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN) || sv_singleplayerrespawn) && state == PST_REBORN && oldactor != NULL)
{ // Special inventory handling for respawning in coop
p->mo->FilterCoopRespawnInventory (oldactor);
}

View file

@ -262,8 +262,7 @@ void DPSprite::NewTick()
while (pspr)
{
pspr->processPending = true;
pspr->oldx = pspr->x;
pspr->oldy = pspr->y;
pspr->ResetInterpolation();
pspr = pspr->Next;
}

View file

@ -30,11 +30,8 @@
#define WEAPONBOTTOM 128.
// [RH] +0x6000 helps it meet the screen bottom
// at higher resolutions while still being in
// the right spot at 320x200.
#define WEAPONTOP (32+6./16)
#define WEAPONTOP 32.
#define WEAPON_FUDGE_Y 0.375
class AInventory;
//
@ -79,6 +76,7 @@ public:
DPSprite* GetNext() { return Next; }
AActor* GetCaller() { return Caller; }
void SetCaller(AActor *newcaller) { Caller = newcaller; }
void ResetInterpolation() { oldx = x; oldy = y; }
double x, y;
double oldx, oldy;

View file

@ -76,11 +76,11 @@ class USDFParser : public UDMFParserBase
//===========================================================================
//
// Parse a cost block
// Parse a cost/require/exclude block
//
//===========================================================================
bool ParseCost(FStrifeDialogueReply *response)
bool ParseCostRequireExclude(FStrifeDialogueReply *response, FName type)
{
FStrifeDialogueItemCheck check;
check.Item = NULL;
@ -101,7 +101,12 @@ class USDFParser : public UDMFParserBase
}
}
response->ItemCheck.Push(check);
switch (type)
{
case NAME_Cost: response->ItemCheck.Push(check); break;
case NAME_Require: response->ItemCheckRequire.Push(check); break;
case NAME_Exclude: response->ItemCheckExclude.Push(check); break;
}
return true;
}
@ -206,8 +211,15 @@ class USDFParser : public UDMFParserBase
switch(key)
{
case NAME_Cost:
ParseCost(reply);
break;
case NAME_Require:
case NAME_Exclude:
// Require and Exclude are exclusive to namespace ZDoom. [FishyClockwork]
if (key == NAME_Cost || namespace_bits == Zd)
{
ParseCostRequireExclude(reply, key);
break;
}
// Intentional fall-through
default:
sc.UnGet();
@ -333,7 +345,11 @@ class USDFParser : public UDMFParserBase
break;
case NAME_Goodbye:
Goodbye = CheckString(key);
// Custom goodbyes are exclusive to namespace ZDoom. [FishyClockwork]
if (namespace_bits == Zd)
{
Goodbye = CheckString(key);
}
break;
}
}

View file

@ -66,6 +66,9 @@ static FRandom pr_skullpop ("SkullPop");
// [RH] # of ticks to complete a turn180
#define TURN180_TICKS ((TICRATE / 4) + 1)
// [SP] Allows respawn in single player
CVAR(Bool, sv_singleplayerrespawn, false, CVAR_SERVERINFO | CVAR_LATCH)
// Variables for prediction
CVAR (Bool, cl_noprediction, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR(Bool, cl_predict_specials, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
@ -2212,7 +2215,9 @@ void P_DeathThink (player_t *player)
if (level.time >= player->respawn_time || ((player->cmd.ucmd.buttons & BT_USE) && player->Bot == NULL))
{
player->cls = NULL; // Force a new class if the player is using a random class
player->playerstate = (multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN)) ? PST_REBORN : PST_ENTER;
player->playerstate =
(multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN) || sv_singleplayerrespawn)
? PST_REBORN : PST_ENTER;
if (player->mo->special1 > 2)
{
player->mo->special1 = 0;

83
src/posix/zdoom.xpm Normal file
View file

@ -0,0 +1,83 @@
/* XPM */
static char * zdoom_xpm[] = {
"48 48 32 1",
" c None",
". c #ADA990",
"+ c #999966",
"@ c #666666",
"# c #393939",
"$ c #555555",
"% c #996666",
"& c #777777",
"* c #5F5F5F",
"= c #333333",
"- c #4D4D4D",
"; c #868686",
"> c #969696",
", c #1C1C1C",
"' c #339933",
") c #336633",
"! c #66CC66",
"~ c #66FF66",
"{ c #66CC33",
"] c #222222",
"^ c #333300",
"/ c #292929",
"( c #040404",
"_ c #0C0C0C",
": c #663333",
"< c #996633",
"[ c #CC9966",
"} c #CC6633",
"| c #CC9999",
"1 c #FFCC99",
"2 c #FF9966",
"3 c #FFCCCC",
" ... ",
" ++@##$+ ",
" +...+%&+ ",
" %*=-*&;$=&* ",
" %**=$@;>@=&*% ",
" &**@$*@@$-.+& ",
" %$%@*..$@.. ",
" ,#@+++@@#& ",
" $,#$$@@$#=$'' ",
" )!!!~!{=],,,,]^)'!{') =/, ",
" )){'~!!'')=],=))'{)'')) /=],( ",
" )'!!'!)~'{'),)''''''')) @@/==](( ",
" ^)''')'{{''')'''''),))) $$@$/,( ",
" ,^))),))''''))'')^,__/$$$-#-(( ",
" :<[}<,_)))))))),___,]#@@-/]] ",
" :<|12<:_,,,,,_,#$$-#/,^^=^}}< ",
" :<[1}::,^,,__,#$-==/,,::^:<<< ",
" ::&+@#^,,__/)#-=/,,,,-::^<::= ",
" :*+12[:==_,$-=/,,,,/,#::::=^ ",
" #*}331}-$]-==/,,,,// ##:=^ ",
" /]<13[---],,,,,,,]_] ",
" ,:--/,___]]]]:^___/ ",
" _______,^^,^,__/# ",
" ______:::::/$,,/# ",
" ____^:::=,^^^^,^^ ",
" __,,:=^,,)))^,,= ",
" _,,),,,,,^)^^^,, ",
" ,^,,),__,^))),,^ ",
" ,,,^^,,,,,)))),, ",
" ,,,,,,,)^))))^ ",
" ,,^,,,^^)))))^ ",
" ,^^,,,,)))))), ",
" ,^,,,,))^))), ",
" ],,,,,$&&&*$# ",
" ],,,]#****$# ",
" ]]]]]^####, ",
" ]]]]*,,,,#* ",
" ,_,#@&&@*/ ",
" __$####=# ",
" ,_/$$$$$# ",
" ,,,$*$$$ ",
" ],,,$**$# ",
" ],,,@&&@# ",
" ],,,$**#= ",
" ,,=+++%$ ",
" *%%%*$ ",
" /$*$#/ ",
" ],,]] "};

View file

@ -221,10 +221,26 @@ void R_MapPlane (int y, int x1)
distance = planeheight * yslope[y];
ds_xstep = xs_ToFixed(32-ds_xbits, distance * xstepscale);
ds_ystep = xs_ToFixed(32-ds_ybits, distance * ystepscale);
ds_xfrac = xs_ToFixed(32-ds_xbits, distance * basexfrac) + pviewx;
ds_yfrac = xs_ToFixed(32-ds_ybits, distance * baseyfrac) + pviewy;
if (ds_xbits != 0)
{
ds_xstep = xs_ToFixed(32 - ds_xbits, distance * xstepscale);
ds_xfrac = xs_ToFixed(32 - ds_xbits, distance * basexfrac) + pviewx;
}
else
{
ds_xstep = 0;
ds_xfrac = 0;
}
if (ds_ybits != 0)
{
ds_ystep = xs_ToFixed(32 - ds_ybits, distance * ystepscale);
ds_yfrac = xs_ToFixed(32 - ds_ybits, distance * baseyfrac) + pviewy;
}
else
{
ds_ystep = 0;
ds_yfrac = 0;
}
if (plane_shade)
{
@ -357,7 +373,7 @@ void R_CalcTiltedLighting (double lval, double lend, int width)
//
//==========================================================================
void R_MapTiltedPlane (int y, int x1)
void R_MapTiltedPlane(int y, int x1)
{
int x2 = spanend[y];
int width = x2 - x1;
@ -366,18 +382,18 @@ void R_MapTiltedPlane (int y, int x1)
DWORD u, v;
int i;
iz = plane_sz[2] + plane_sz[1]*(centery-y) + plane_sz[0]*(x1-centerx);
iz = plane_sz[2] + plane_sz[1] * (centery - y) + plane_sz[0] * (x1 - centerx);
// Lighting is simple. It's just linear interpolation from start to end
if (plane_shade)
{
uz = (iz + plane_sz[0]*width) * planelightfloat;
uz = (iz + plane_sz[0] * width) * planelightfloat;
vz = iz * planelightfloat;
R_CalcTiltedLighting (vz, uz, width);
R_CalcTiltedLighting(vz, uz, width);
}
uz = plane_su[2] + plane_su[1]*(centery-y) + plane_su[0]*(x1-centerx);
vz = plane_sv[2] + plane_sv[1]*(centery-y) + plane_sv[0]*(x1-centerx);
uz = plane_su[2] + plane_su[1] * (centery - y) + plane_su[0] * (x1 - centerx);
vz = plane_sv[2] + plane_sv[1] * (centery - y) + plane_sv[0] * (x1 - centerx);
fb = ylookup[y] + x1 + dc_destorg;
@ -595,9 +611,10 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl
fixed_t alpha = FLOAT2FIXED(Alpha);
//angle_t angle = (xform.Angle + xform.baseAngle).BAMs();
FTransform nulltransform;
if (picnum == skyflatnum) // killough 10/98
{ // most skies map together
FTransform nulltransform;
lightlevel = 0;
xform = &nulltransform;
nulltransform.xOffs = nulltransform.yOffs = nulltransform.baseyOffs = 0;
@ -1887,6 +1904,15 @@ void R_DrawTiltedPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t
}
}
// Hack in support for 1 x Z and Z x 1 texture sizes
if (ds_ybits == 0)
{
plane_sv[2] = plane_sv[1] = plane_sv[0] = 0;
}
if (ds_xbits == 0)
{
plane_su[2] = plane_su[1] = plane_su[0] = 0;
}
#if defined(X86_ASM)
if (ds_source != ds_curtiltedsource)
R_SetTiltedSpanSource_ASM (ds_source);

View file

@ -173,7 +173,7 @@ CVAR(Bool, r_drawmirrors, true, 0)
float *MaskedSWall;
float MaskedScaleY;
static void BlastMaskedColumn (void (*blastfunc)(const BYTE *pixels, const FTexture::Span *spans), FTexture *tex)
static void BlastMaskedColumn (FTexture *tex, bool useRt)
{
// calculate lighting
if (fixedcolormap == NULL && fixedlightlev < 0)
@ -198,7 +198,7 @@ static void BlastMaskedColumn (void (*blastfunc)(const BYTE *pixels, const FText
// draw the texture
const FTexture::Span *spans;
const BYTE *pixels = tex->GetColumn (maskedtexturecol[dc_x] >> FRACBITS, &spans);
blastfunc (pixels, spans);
R_DrawMaskedColumn(pixels, spans, useRt);
rw_light += rw_lightstep;
spryscale += rw_scalestep;
}
@ -441,7 +441,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
{
for (dc_x = x1; dc_x < x2; ++dc_x)
{
BlastMaskedColumn (R_DrawMaskedColumn, tex);
BlastMaskedColumn (tex, false);
}
}
else
@ -456,24 +456,24 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
while ((dc_x < stop) && (dc_x & 3))
{
BlastMaskedColumn (R_DrawMaskedColumn, tex);
BlastMaskedColumn (tex, false);
dc_x++;
}
while (dc_x < stop)
{
rt_initcols();
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex); dc_x++;
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex); dc_x++;
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex); dc_x++;
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex);
BlastMaskedColumn (tex, true); dc_x++;
BlastMaskedColumn (tex, true); dc_x++;
BlastMaskedColumn (tex, true); dc_x++;
BlastMaskedColumn (tex, true);
rt_draw4cols (dc_x - 3);
dc_x++;
}
while (dc_x < x2)
{
BlastMaskedColumn (R_DrawMaskedColumn, tex);
BlastMaskedColumn (tex, false);
dc_x++;
}
}
@ -1104,6 +1104,12 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l
rw_pic->GetHeight(); // Make sure texture size is loaded
fracbits = 32 - rw_pic->HeightBits;
if (fracbits == 32)
{ // Hack for one pixel tall textures
fracbits = 0;
yrepeat = 0;
dc_texturemid = 0;
}
setupvline(fracbits);
xoffset = rw_offset;
basecolormapdata = basecolormap->Maps;
@ -1456,6 +1462,12 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_
rw_pic->GetHeight(); // Make sure texture size is loaded
fracbits = 32- rw_pic->HeightBits;
if (fracbits == 32)
{ // Hack for one pixel tall textures
fracbits = 0;
yrepeat = 0;
dc_texturemid = 0;
}
setupmvline(fracbits);
xoffset = rw_offset;
basecolormapdata = basecolormap->Maps;
@ -1631,6 +1643,12 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f
rw_pic->GetHeight(); // Make sure texture size is loaded
fracbits = 32 - rw_pic->HeightBits;
if (fracbits == 32)
{ // Hack for one pixel tall textures
fracbits = 0;
yrepeat = 0;
dc_texturemid = 0;
}
setuptmvline(fracbits);
xoffset = rw_offset;
basecolormapdata = basecolormap->Maps;
@ -2521,7 +2539,7 @@ void R_StoreWallRange (int start, int stop)
lwal = (fixed_t *)(openings + ds_p->maskedtexturecol);
swal = (float *)(openings + ds_p->swall);
FTexture *pic = TexMan(sidedef->GetTexture(side_t::mid), true);
double yscale = pic->Scale.X * sidedef->GetTextureYScale(side_t::mid);
double yscale = pic->Scale.Y * sidedef->GetTextureYScale(side_t::mid);
fixed_t xoffset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid));
if (pic->bWorldPanning)
@ -3245,7 +3263,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
{ // calculate lighting
dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT);
}
R_WallSpriteColumn (R_DrawMaskedColumn);
R_WallSpriteColumn (false);
dc_x++;
}
@ -3258,7 +3276,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
rt_initcols();
for (int zz = 4; zz; --zz)
{
R_WallSpriteColumn (R_DrawMaskedColumnHoriz);
R_WallSpriteColumn (true);
dc_x++;
}
rt_draw4cols (dc_x - 4);
@ -3270,7 +3288,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
{ // calculate lighting
dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT);
}
R_WallSpriteColumn (R_DrawMaskedColumn);
R_WallSpriteColumn (false);
dc_x++;
}
}

View file

@ -1302,6 +1302,32 @@ void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, fl
S_StartSound (NULL, sec, NULL, NULL, channel, sfxid, volume, attenuation);
}
//==========================================================================
//
// S_PlaySound - Subfunction used by ACS and DECORATE
//
// Has a local parameter to make the sound audible only to the source
//
//==========================================================================
void S_PlaySound(AActor *a, int chan, FSoundID sid, float vol, float atten, bool local)
{
if (a == nullptr)
return;
if (!local)
{
S_Sound(a, chan, sid, vol, atten);
}
else
{
if (a->CheckLocalView(consoleplayer))
{
S_Sound(chan, sid, vol, ATTN_NONE);
}
}
}
//==========================================================================
//
// S_LoadSound

View file

@ -242,6 +242,9 @@ void S_Sound (const FPolyObj *poly, int channel, FSoundID sfxid, float volume, f
void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, float attenuation);
void S_Sound(const DVector3 &pos, int channel, FSoundID sfxid, float volume, float attenuation);
// [Nash] Used by ACS and DECORATE
void S_PlaySound(AActor *a, int chan, FSoundID sid, float vol, float atten, bool local);
// sound channels
// channel 0 never willingly overrides
// other channels (1-7) always override a playing sound on that channel

View file

@ -67,6 +67,143 @@
char nulspace[1024 * 1024 * 4];
bool save_full = false; // for testing. Should be removed afterward.
int utf8_encode(int32_t codepoint, char *buffer, int *size)
{
if (codepoint < 0)
return -1;
else if (codepoint < 0x80)
{
buffer[0] = (char)codepoint;
*size = 1;
}
else if (codepoint < 0x800)
{
buffer[0] = 0xC0 + ((codepoint & 0x7C0) >> 6);
buffer[1] = 0x80 + ((codepoint & 0x03F));
*size = 2;
}
else if (codepoint < 0x10000)
{
buffer[0] = 0xE0 + ((codepoint & 0xF000) >> 12);
buffer[1] = 0x80 + ((codepoint & 0x0FC0) >> 6);
buffer[2] = 0x80 + ((codepoint & 0x003F));
*size = 3;
}
else if (codepoint <= 0x10FFFF)
{
buffer[0] = 0xF0 + ((codepoint & 0x1C0000) >> 18);
buffer[1] = 0x80 + ((codepoint & 0x03F000) >> 12);
buffer[2] = 0x80 + ((codepoint & 0x000FC0) >> 6);
buffer[3] = 0x80 + ((codepoint & 0x00003F));
*size = 4;
}
else
return -1;
return 0;
}
int utf8_decode(const char *src, int *size)
{
int c = src[0] & 255;
int r;
*size = 1;
if ((c & 0x80) == 0)
{
return c;
}
int c1 = src[1] & 255;
if ((c & 0xE0) == 0xC0)
{
r = ((c & 0x1F) << 6) | c1;
if (r >= 128)
{
*size = 2;
return r;
}
return -1;
}
int c2 = src[2] & 255;
if ((c & 0xF0) == 0xE0)
{
r = ((c & 0x0F) << 12) | (c1 << 6) | c2;
if (r >= 2048 && (r < 55296 || r > 57343))
{
*size = 3;
return r;
}
return -1;
}
int c3 = src[3] & 255;
if ((c & 0xF8) == 0xF0)
{
r = ((c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
if (r >= 65536 && r <= 1114111)
{
*size = 4;
return r;
}
}
return -1;
}
static TArray<char> out;
static const char *StringToUnicode(const char *cc, int size = -1)
{
int ch;
const char *c = cc;
int count = 0;
int count1 = 0;
out.Clear();
while (ch = (*c++) & 255)
{
count1++;
if (ch >= 128)
{
if (ch < 0x800) count += 2;
else count += 3;
// The source cannot contain 4-byte chars.
}
else count++;
if (count1 == size && size > 0) break;
}
if (count == count1) return cc; // string is pure ASCII.
// we need to convert
out.Resize(count + 1);
out.Last() = 0;
c = cc;
int i = 0;
while (ch = (*c++) & 255)
{
utf8_encode(ch, &out[i], &count1);
i += count1;
}
return &out[0];
}
static const char *UnicodeToString(const char *cc)
{
out.Resize((unsigned)strlen(cc) + 1);
int ndx = 0;
while (*cc != 0)
{
int size;
int c = utf8_decode(cc, &size);
if (c < 0 || c > 255) c = '?';
out[ndx++] = c;
cc += size;
}
out[ndx] = 0;
return &out[0];
}
//==========================================================================
//
//
@ -99,8 +236,8 @@ struct FJSONObject
struct FWriter
{
typedef rapidjson::Writer<rapidjson::StringBuffer, rapidjson::ASCII<> > Writer;
typedef rapidjson::PrettyWriter<rapidjson::StringBuffer, rapidjson::ASCII<> > PrettyWriter;
typedef rapidjson::Writer<rapidjson::StringBuffer, rapidjson::UTF8<> > Writer;
typedef rapidjson::PrettyWriter<rapidjson::StringBuffer, rapidjson::UTF8<> > PrettyWriter;
Writer *mWriter1;
PrettyWriter *mWriter2;
@ -173,14 +310,16 @@ struct FWriter
void String(const char *k)
{
k = StringToUnicode(k);
if (mWriter1) mWriter1->String(k);
else if (mWriter2) mWriter2->String(k);
}
void String(const char *k, int size)
{
if (mWriter1) mWriter1->String(k, size);
else if (mWriter2) mWriter2->String(k, size);
k = StringToUnicode(k, size);
if (mWriter1) mWriter1->String(k);
else if (mWriter2) mWriter2->String(k);
}
void Bool(bool k)
@ -602,7 +741,7 @@ FSerializer &FSerializer::Args(const char *key, int *args, int *defargs, int spe
}
else if (i == 0 && aval.IsString())
{
args[i] = -FName(aval.GetString());
args[i] = -FName(UnicodeToString(aval.GetString()));
}
else
{
@ -654,7 +793,7 @@ FSerializer &FSerializer::ScriptNum(const char *key, int &num)
}
else if (val->IsString())
{
num = -FName(val->GetString());
num = -FName(UnicodeToString(val->GetString()));
}
else
{
@ -709,7 +848,7 @@ FSerializer &FSerializer::Sprite(const char *key, int32_t &spritenum, int32_t *d
{
if (val->IsString())
{
uint32_t name = *reinterpret_cast<const uint32_t*>(val->GetString());
uint32_t name = *reinterpret_cast<const uint32_t*>(UnicodeToString(val->GetString()));
for (auto hint = NumStdSprites; hint-- != 0; )
{
if (sprites[hint].dwName == name)
@ -747,7 +886,7 @@ FSerializer &FSerializer::StringPtr(const char *key, const char *&charptr)
{
if (val->IsString())
{
charptr = val->GetString();
charptr = UnicodeToString(val->GetString());
}
else
{
@ -1403,7 +1542,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe
assert(nameval.IsString() && typeval.IsInt());
if (nameval.IsString() && typeval.IsInt())
{
value = TexMan.GetTexture(nameval.GetString(), typeval.GetInt());
value = TexMan.GetTexture(UnicodeToString(nameval.GetString()), typeval.GetInt());
}
else
{
@ -1553,7 +1692,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FName &value, FName *d
assert(val->IsString());
if (val->IsString())
{
value = val->GetString();
value = UnicodeToString(val->GetString());
}
else
{
@ -1638,7 +1777,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundI
assert(val->IsString() || val->IsNull());
if (val->IsString())
{
sid = val->GetString();
sid = UnicodeToString(val->GetString());
}
else if (val->IsNull())
{
@ -1687,7 +1826,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClassActor
assert(val->IsString() || val->IsNull());
if (val->IsString())
{
clst = PClass::FindActor(val->GetString());
clst = PClass::FindActor(UnicodeToString(val->GetString()));
}
else if (val->IsNull())
{
@ -1735,7 +1874,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClass *&cl
{
if (val->IsString())
{
clst = PClass::FindClass(val->GetString());
clst = PClass::FindClass(UnicodeToString(val->GetString()));
}
else if (val->IsNull())
{
@ -1810,7 +1949,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FState *&state, FState
assert(cls.IsString() && ndx.IsUint());
if (cls.IsString() && ndx.IsUint())
{
PClassActor *clas = PClass::FindActor(cls.GetString());
PClassActor *clas = PClass::FindActor(UnicodeToString(cls.GetString()));
if (clas && ndx.GetUint() < (unsigned)clas->NumOwnedStates)
{
state = clas->OwnedStates + ndx.GetUint();
@ -1932,7 +2071,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FString *&p
}
else if (val->IsString())
{
pstr = AActor::mStringPropertyData.Alloc(val->GetString());
pstr = AActor::mStringPropertyData.Alloc(UnicodeToString(val->GetString()));
}
else
{
@ -1974,7 +2113,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FString &pstr, FString
}
else if (val->IsString())
{
pstr = val->GetString();
pstr = UnicodeToString(val->GetString());
}
else
{
@ -2023,7 +2162,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, char *&pstr
}
else if (val->IsString())
{
pstr = copystring(val->GetString());
pstr = copystring(UnicodeToString(val->GetString()));
}
else
{

View file

@ -192,6 +192,7 @@ protected:
int UseType = TEX_Null;
bool Silent = false;
bool HasLine = false;
bool UseOffsets = false;
FScriptPosition sc;
};
@ -297,8 +298,6 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl
Printf ("Texture %s is left without any patches\n", Name.GetChars());
}
CheckForHacks ();
DefinitionLump = deflumpnum;
}
@ -1142,11 +1141,7 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, TexInit &init)
}
else if (sc.Compare("useoffsets"))
{
if (part.Texture != NULL)
{
part.OriginX -= part.Texture->LeftOffset;
part.OriginY -= part.Texture->TopOffset;
}
init.UseOffsets = true;
}
}
}
@ -1324,6 +1319,29 @@ void FMultiPatchTexture::ResolvePatches()
for (int i = 0; i < NumParts; i++)
{
FTextureID texno = TexMan.CheckForTexture(Inits[i].TexName, Inits[i].UseType);
if (texno == id) // we found ourselves. Try looking for another one with the same name which is not a multipatch texture itself.
{
TArray<FTextureID> list;
TexMan.ListTextures(Inits[i].TexName, list, true);
for (int i = list.Size() - 1; i >= 0; i--)
{
if (list[i] != id && !TexMan[list[i]]->bMultiPatch)
{
texno = list[i];
break;
}
}
if (texno == id)
{
if (Inits[i].HasLine) Inits[i].sc.Message(MSG_WARNING, "Texture '%s' references itself as patch\n", Inits[i].TexName.GetChars());
else Printf(TEXTCOLOR_YELLOW "Texture '%s' references itself as patch\n", Inits[i].TexName.GetChars());
}
else
{
// If it could be resolved, just print a developer warning.
DPrintf(DMSG_WARNING, "Resolved self-referencing texture by picking an older entry for %s\n", Inits[i].TexName.GetChars());
}
}
if (!texno.isValid())
{
@ -1338,6 +1356,11 @@ void FMultiPatchTexture::ResolvePatches()
Parts[i].Texture = TexMan[texno];
bComplex |= Parts[i].Texture->bComplex;
Parts[i].Texture->bKeepAround = true;
if (Inits[i].UseOffsets)
{
Parts[i].OriginX -= Parts[i].Texture->LeftOffset;
Parts[i].OriginY -= Parts[i].Texture->TopOffset;
}
}
}
for (int i = 0; i < NumParts; i++)
@ -1353,6 +1376,8 @@ void FMultiPatchTexture::ResolvePatches()
delete[] Inits;
Inits = nullptr;
CheckForHacks();
// If this texture is just a wrapper around a single patch, we can simply
// forward GetPixels() and GetColumn() calls to that patch.

View file

@ -210,8 +210,9 @@ void FTexture::CalcBitSize ()
}
WidthMask = (1 << WidthBits) - 1;
// The minimum height is 2, because we cannot shift right 32 bits.
for (i = 1; (1 << i) < Height; ++i)
// <hr>The minimum height is 2, because we cannot shift right 32 bits.</hr>
// Scratch that. Somebody actually made a 1x1 texture, so now we have to handle it.
for (i = 0; (1 << i) < Height; ++i)
{ }
HeightBits = i;
@ -615,8 +616,6 @@ namespace
PalEntry FTexture::GetSkyCapColor(bool bottom)
{
PalEntry col;
int w;
int h;
if (!bSWSkyColorDone)
{

View file

@ -267,7 +267,7 @@ FTextureID FTextureManager::CheckForTexture (const char *name, int usetype, BITF
//
//==========================================================================
int FTextureManager::ListTextures (const char *name, TArray<FTextureID> &list)
int FTextureManager::ListTextures (const char *name, TArray<FTextureID> &list, bool listall)
{
int i;
@ -293,11 +293,14 @@ int FTextureManager::ListTextures (const char *name, TArray<FTextureID> &list)
// NULL textures must be ignored.
if (tex->UseType!=FTexture::TEX_Null)
{
unsigned int j;
for(j = 0; j < list.Size(); j++)
unsigned int j = list.Size();
if (!listall)
{
// Check for overriding definitions from newer WADs
if (Textures[list[j].GetIndex()].Texture->UseType == tex->UseType) break;
for (j = 0; j < list.Size(); j++)
{
// Check for overriding definitions from newer WADs
if (Textures[list[j].GetIndex()].Texture->UseType == tex->UseType) break;
}
}
if (j==list.Size()) list.Push(FTextureID(i));
}

View file

@ -412,7 +412,7 @@ public:
FTextureID CheckForTexture (const char *name, int usetype, BITFIELD flags=TEXMAN_TryAny);
FTextureID GetTexture (const char *name, int usetype, BITFIELD flags=0);
int ListTextures (const char *name, TArray<FTextureID> &list);
int ListTextures (const char *name, TArray<FTextureID> &list, bool listall = false);
void AddTexturesLump (const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup=0, bool texture1=false);
void AddTexturesLumps (int lump1, int lump2, int patcheslump);

View file

@ -294,7 +294,7 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
while ((dc_x < stop4) && (dc_x & 3))
{
pixels = img->GetColumn(frac >> FRACBITS, spanptr);
R_DrawMaskedColumn(pixels, spans);
R_DrawMaskedColumn(pixels, spans, false);
dc_x++;
frac += xiscale_i;
}
@ -305,7 +305,7 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
for (int zz = 4; zz; --zz)
{
pixels = img->GetColumn(frac >> FRACBITS, spanptr);
R_DrawMaskedColumnHoriz(pixels, spans);
R_DrawMaskedColumn(pixels, spans, true);
dc_x++;
frac += xiscale_i;
}
@ -315,7 +315,7 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
while (dc_x < x2_i)
{
pixels = img->GetColumn(frac >> FRACBITS, spanptr);
R_DrawMaskedColumn(pixels, spans);
R_DrawMaskedColumn(pixels, spans, false);
dc_x++;
frac += xiscale_i;
}
@ -1325,6 +1325,13 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
return;
}
BYTE *destorgsave = dc_destorg;
dc_destorg = screen->GetBuffer();
if (dc_destorg == NULL)
{
I_FatalError("Attempt to write to buffer of hardware canvas");
}
scalex /= tex->Scale.X;
scaley /= tex->Scale.Y;
@ -1427,6 +1434,7 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
pt1 = pt2;
pt2--; if (pt2 < 0) pt2 = npoints;
} while (pt1 != botpt);
dc_destorg = destorgsave;
#endif
}

View file

@ -191,7 +191,7 @@ ACTOR Actor native //: Thinker
action native A_ComboAttack();
action native A_BulletAttack();
action native A_WolfAttack(int flags = 0, sound whattoplay = "weapons/pistol", float snipe = 1.0, int maxdamage = 64, int blocksize = 128, int pointblank = 2, int longrange = 4, float runspeed = 160.0, class<Actor> pufftype = "BulletPuff");
action native A_PlaySound(sound whattoplay = "weapons/pistol", int slot = CHAN_BODY, float volume = 1.0, bool looping = false, float attenuation = ATTN_NORM);
action native A_PlaySound(sound whattoplay = "weapons/pistol", int slot = CHAN_BODY, float volume = 1.0, bool looping = false, float attenuation = ATTN_NORM, bool local = false);
native void A_PlayWeaponSound(sound whattoplay);
action native A_FLoopActiveSound();
action native A_LoopActiveSound();

View file

@ -675,14 +675,14 @@ OptionMenu "VideoOptions"
Slider "$DSPLYMNU_SCREENSIZE", "screenblocks", 3.0, 12.0, 1.0, 0
Slider "$DSPLYMNU_GAMMA", "Gamma", 0.75, 3.0, 0.05, 2
Slider "$DSPLYMNU_BRIGHTNESS", "vid_brightness", -0.8,0.8, 0.05
Slider "$DSPLYMNU_BRIGHTNESS", "vid_brightness", -0.8,0.8, 0.05,2
Slider "$DSPLYMNU_CONTRAST", "vid_contrast", 0.1, 3.0, 0.1
Option "$DSPLYMNU_HWGAMMA", "vid_hwgamma", "HWGammaModes"
Option "$DSPLYMNU_VSYNC", "vid_vsync", "OnOff"
Option "$DSPLYMNU_CAPFPS", "cl_capfps", "OffOn"
Slider "$DSPLYMNU_BLOODFADE", "blood_fade_scalar", 0.0, 1.0, 0.05, 1
Slider "$DSPLYMNU_PICKUPFADE", "pickup_fade_scalar", 0.0, 1.0, 0.05, 1
Slider "$DSPLYMNU_BLOODFADE", "blood_fade_scalar", 0.0, 1.0, 0.05, 2
Slider "$DSPLYMNU_PICKUPFADE", "pickup_fade_scalar", 0.0, 1.0, 0.05, 2
Option "$DSPLYMNU_COLUMNMETHOD", "r_columnmethod", "ColumnMethods"
StaticText " "
@ -714,7 +714,7 @@ OptionMenu "VideoOptions"
ColorPicker "$DSPLYMNU_DIMCOLOR", "dimcolor"
Slider "$DSPLYMNU_MOVEBOB", "movebob", 0, 1.0, 0.05, 2
Slider "$DSPLYMNU_STILLBOB", "stillbob", 0, 1.0, 0.05, 2
Slider "$DSPLYMNU_BOBSPEED", "wbobspeed", 0, 2.0, 0.1, 2
Slider "$DSPLYMNU_BOBSPEED", "wbobspeed", 0, 2.0, 0.1
}
@ -1256,7 +1256,7 @@ OptionMenu GameplayOptions
Title "$GMPLYMNU_TITLE"
//Indent 222
Option "$GMPLYMNU_TEAMPLAY", "teamplay", "OnOff"
Slider "$GMPLYMNU_TEAMDAMAGE", "teamdamage", 0, 1, 0.05
Slider "$GMPLYMNU_TEAMDAMAGE", "teamdamage", 0, 1, 0.05,2
StaticText " "
Option "$GMPLYMNU_SMARTAUTOAIM", "sv_smartaim", "SmartAim"
StaticText " "
@ -1801,7 +1801,7 @@ OptionMenu NetworkOptions
StaticText "$NETMNU_LOCALOPTIONS", 1
Option "$NETMNU_MOVEPREDICTION", "cl_noprediction", "OffOn"
Option "$NETMNU_LINESPECIALPREDICTION", "cl_predict_specials", "OnOff"
Slider "$NETMNU_PREDICTIONLERPSCALE", "cl_predict_lerpscale", 0.0, 0.5, 0.05
Slider "$NETMNU_PREDICTIONLERPSCALE", "cl_predict_lerpscale", 0.0, 0.5, 0.05, 2
Slider "$NETMNU_LERPTHRESHOLD", "cl_predict_lerpthreshold", 0.1, 16.0, 0.1
StaticText " "
StaticText "$NETMNU_HOSTOPTIONS", 1