mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-22 12:01:33 +00:00
This commit is contained in:
commit
d84ba4b953
14 changed files with 245 additions and 23 deletions
|
@ -210,6 +210,9 @@ struct FCommandBuffer
|
|||
unsigned CursorPos;
|
||||
unsigned StartPos; // First character to display
|
||||
|
||||
FString YankBuffer; // Deleted text buffer
|
||||
bool AppendToYankBuffer; // Append consecutive deletes to buffer
|
||||
|
||||
FCommandBuffer()
|
||||
{
|
||||
CursorPos = StartPos = 0;
|
||||
|
@ -282,6 +285,30 @@ struct FCommandBuffer
|
|||
StartPos = MAX(0, n);
|
||||
}
|
||||
|
||||
unsigned WordBoundaryRight()
|
||||
{
|
||||
unsigned index = CursorPos;
|
||||
while (index < Text.Len() && Text[index] == ' ') {
|
||||
index++;
|
||||
}
|
||||
while (index < Text.Len() && Text[index] != ' ') {
|
||||
index++;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
unsigned WordBoundaryLeft()
|
||||
{
|
||||
int index = CursorPos - 1;
|
||||
while (index > -1 && Text[index] == ' ') {
|
||||
index--;
|
||||
}
|
||||
while (index > -1 && Text[index] != ' ') {
|
||||
index--;
|
||||
}
|
||||
return (unsigned)index + 1;
|
||||
}
|
||||
|
||||
void CursorStart()
|
||||
{
|
||||
CursorPos = 0;
|
||||
|
@ -313,6 +340,18 @@ struct FCommandBuffer
|
|||
}
|
||||
}
|
||||
|
||||
void CursorWordLeft()
|
||||
{
|
||||
CursorPos = WordBoundaryLeft();
|
||||
MakeStartPosGood();
|
||||
}
|
||||
|
||||
void CursorWordRight()
|
||||
{
|
||||
CursorPos = WordBoundaryRight();
|
||||
MakeStartPosGood();
|
||||
}
|
||||
|
||||
void DeleteLeft()
|
||||
{
|
||||
if (CursorPos > 0)
|
||||
|
@ -332,6 +371,50 @@ struct FCommandBuffer
|
|||
}
|
||||
}
|
||||
|
||||
void DeleteWordLeft()
|
||||
{
|
||||
if (CursorPos > 0)
|
||||
{
|
||||
unsigned index = WordBoundaryLeft();
|
||||
if (AppendToYankBuffer) {
|
||||
YankBuffer = FString(&Text[index], CursorPos - index) + YankBuffer;
|
||||
} else {
|
||||
YankBuffer = FString(&Text[index], CursorPos - index);
|
||||
}
|
||||
Text.Remove(index, CursorPos - index);
|
||||
CursorPos = index;
|
||||
MakeStartPosGood();
|
||||
}
|
||||
}
|
||||
|
||||
void DeleteLineLeft()
|
||||
{
|
||||
if (CursorPos > 0)
|
||||
{
|
||||
if (AppendToYankBuffer) {
|
||||
YankBuffer = FString(&Text[0], CursorPos) + YankBuffer;
|
||||
} else {
|
||||
YankBuffer = FString(&Text[0], CursorPos);
|
||||
}
|
||||
Text.Remove(0, CursorPos);
|
||||
CursorStart();
|
||||
}
|
||||
}
|
||||
|
||||
void DeleteLineRight()
|
||||
{
|
||||
if (CursorPos < Text.Len())
|
||||
{
|
||||
if (AppendToYankBuffer) {
|
||||
YankBuffer += FString(&Text[CursorPos], Text.Len() - CursorPos);
|
||||
} else {
|
||||
YankBuffer = FString(&Text[CursorPos], Text.Len() - CursorPos);
|
||||
}
|
||||
Text.Truncate(CursorPos);
|
||||
CursorEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void AddChar(int character)
|
||||
{
|
||||
///FIXME: Not Unicode-aware
|
||||
|
@ -1349,6 +1432,7 @@ DEFINE_ACTION_FUNCTION(_Console, Printf)
|
|||
static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer)
|
||||
{
|
||||
int data1 = ev->data1;
|
||||
bool keepappending = false;
|
||||
|
||||
switch (ev->subtype)
|
||||
{
|
||||
|
@ -1356,8 +1440,22 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer)
|
|||
return false;
|
||||
|
||||
case EV_GUI_Char:
|
||||
if (ev->data2)
|
||||
{
|
||||
// Bash-style shortcuts
|
||||
if (data1 == 'b')
|
||||
{
|
||||
buffer.CursorWordLeft();
|
||||
break;
|
||||
}
|
||||
else if (data1 == 'f')
|
||||
{
|
||||
buffer.CursorWordRight();
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Add keypress to command line
|
||||
buffer.AddChar(ev->data1);
|
||||
buffer.AddChar(data1);
|
||||
HistPos = NULL;
|
||||
TabbedLast = false;
|
||||
TabbedList = false;
|
||||
|
@ -1658,6 +1756,56 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// Bash-style shortcuts
|
||||
case 'A':
|
||||
if (ev->data3 & GKM_CTRL)
|
||||
{
|
||||
buffer.CursorStart();
|
||||
}
|
||||
break;
|
||||
case 'E':
|
||||
if (ev->data3 & GKM_CTRL)
|
||||
{
|
||||
buffer.CursorEnd();
|
||||
}
|
||||
break;
|
||||
case 'W':
|
||||
if (ev->data3 & GKM_CTRL)
|
||||
{
|
||||
buffer.DeleteWordLeft();
|
||||
keepappending = true;
|
||||
TabbedLast = false;
|
||||
TabbedList = false;
|
||||
}
|
||||
break;
|
||||
case 'U':
|
||||
if (ev->data3 & GKM_CTRL)
|
||||
{
|
||||
buffer.DeleteLineLeft();
|
||||
keepappending = true;
|
||||
TabbedLast = false;
|
||||
TabbedList = false;
|
||||
}
|
||||
break;
|
||||
case 'K':
|
||||
if (ev->data3 & GKM_CTRL)
|
||||
{
|
||||
buffer.DeleteLineRight();
|
||||
keepappending = true;
|
||||
TabbedLast = false;
|
||||
TabbedList = false;
|
||||
}
|
||||
break;
|
||||
case 'Y':
|
||||
if (ev->data3 & GKM_CTRL)
|
||||
{
|
||||
buffer.AddString(buffer.YankBuffer);
|
||||
TabbedLast = false;
|
||||
TabbedList = false;
|
||||
HistPos = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1668,6 +1816,9 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer)
|
|||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
buffer.AppendToYankBuffer = keepappending;
|
||||
|
||||
// Ensure that the cursor is always visible while typing
|
||||
CursorTicker = C_BLINKRATE;
|
||||
cursoron = 1;
|
||||
|
|
|
@ -86,6 +86,7 @@ enum
|
|||
CP_SETTHINGZ,
|
||||
CP_SETTAG,
|
||||
CP_SETTHINGFLAGS,
|
||||
CP_SETVERTEX,
|
||||
};
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
@ -345,7 +346,19 @@ void ParseCompatibility()
|
|||
sc.MustGetNumber();
|
||||
CompatParams.Push(sc.Number);
|
||||
}
|
||||
else
|
||||
else if (sc.Compare("setvertex"))
|
||||
{
|
||||
if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
|
||||
CompatParams.Push(CP_SETVERTEX);
|
||||
sc.MustGetNumber();
|
||||
CompatParams.Push(sc.Number);
|
||||
sc.MustGetFloat();
|
||||
CompatParams.Push(int(sc.Float * 256)); // do not use full fixed here so that it can eventually handle larger levels
|
||||
sc.MustGetFloat();
|
||||
CompatParams.Push(int(sc.Float * 256)); // do not use full fixed here so that it can eventually handle larger levels
|
||||
flags.CompatFlags[SLOT_BCOMPAT] |= BCOMPATF_REBUILDNODES;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.UnGet();
|
||||
break;
|
||||
|
@ -600,6 +613,16 @@ void SetCompatibilityParams()
|
|||
i += 3;
|
||||
break;
|
||||
}
|
||||
case CP_SETVERTEX:
|
||||
{
|
||||
if ((unsigned)CompatParams[i + 1] < level.vertexes.Size())
|
||||
{
|
||||
level.vertexes[CompatParams[i + 1]].p.X = CompatParams[i + 2] / 256.;
|
||||
level.vertexes[CompatParams[i + 1]].p.Y = CompatParams[i + 3] / 256.;
|
||||
}
|
||||
i += 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2307,7 +2307,7 @@ void PStruct::WriteFields(FSerializer &ar, const void *addr, const TArray<PField
|
|||
{
|
||||
const PField *field = fields[i];
|
||||
// Skip fields without or with native serialization
|
||||
if (!(field->Flags & VARF_Transient))
|
||||
if (!(field->Flags & (VARF_Transient|VARF_Meta)))
|
||||
{
|
||||
field->Type->WriteValue(ar, field->SymbolName.GetChars(), (const BYTE *)addr + field->Offset);
|
||||
}
|
||||
|
@ -2340,6 +2340,11 @@ bool PStruct::ReadFields(FSerializer &ar, void *addr) const
|
|||
DPrintf(DMSG_ERROR, "Symbol %s in %s is not a field\n",
|
||||
label, TypeName.GetChars());
|
||||
}
|
||||
else if ((static_cast<const PField *>(sym)->Flags & (VARF_Transient | VARF_Meta)))
|
||||
{
|
||||
DPrintf(DMSG_ERROR, "Symbol %s in %s is not a serializable field\n",
|
||||
label, TypeName.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
readsomething |= static_cast<const PField *>(sym)->Type->ReadValue(ar, nullptr,
|
||||
|
@ -2638,7 +2643,7 @@ static void RecurseWriteFields(const PClass *type, FSerializer &ar, const void *
|
|||
// Don't write this part if it has no non-transient variables
|
||||
for (unsigned i = 0; i < type->Fields.Size(); ++i)
|
||||
{
|
||||
if (!(type->Fields[i]->Flags & VARF_Transient))
|
||||
if (!(type->Fields[i]->Flags & (VARF_Transient|VARF_Meta)))
|
||||
{
|
||||
// Tag this section with the class it came from in case
|
||||
// a more-derived class has variables that shadow a less-
|
||||
|
@ -3397,7 +3402,6 @@ PClass *PClass::FindClassTentative(FName name)
|
|||
PClass *type = static_cast<PClass *>(GetClass()->CreateNew());
|
||||
DPrintf(DMSG_SPAMMY, "Creating placeholder class %s : %s\n", name.GetChars(), TypeName.GetChars());
|
||||
|
||||
assert(MetaSize == 0);
|
||||
Derive(type, name);
|
||||
type->Size = TentativeClass;
|
||||
TypeTable.AddType(type, RUNTIME_CLASS(PClass), 0, name, bucket);
|
||||
|
|
|
@ -203,7 +203,8 @@ void ADynamicLight::Activate(AActor *activator)
|
|||
float pulseTime = specialf1 / TICRATE;
|
||||
|
||||
m_lastUpdate = level.maptime;
|
||||
m_cycler.SetParams(float(args[LIGHT_SECONDARY_INTENSITY]), float(args[LIGHT_INTENSITY]), pulseTime);
|
||||
if (!swapped) m_cycler.SetParams(float(args[LIGHT_SECONDARY_INTENSITY]), float(args[LIGHT_INTENSITY]), pulseTime);
|
||||
else m_cycler.SetParams(float(args[LIGHT_INTENSITY]), float(args[LIGHT_SECONDARY_INTENSITY]), pulseTime);
|
||||
m_cycler.ShouldCycle(true);
|
||||
m_cycler.SetCycleType(CYCLE_Sin);
|
||||
m_currentRadius = m_cycler.GetVal();
|
||||
|
|
|
@ -135,6 +135,16 @@ public:
|
|||
void SetDontLightSelf(bool add) { m_dontlightself = add; }
|
||||
void SetAttenuate(bool on) { m_attenuate = on; }
|
||||
void SetHalo(bool halo) { m_halo = halo; }
|
||||
|
||||
void OrderIntensities()
|
||||
{
|
||||
if (m_Args[LIGHT_INTENSITY] > m_Args[LIGHT_SECONDARY_INTENSITY])
|
||||
{
|
||||
std::swap(m_Args[LIGHT_INTENSITY], m_Args[LIGHT_SECONDARY_INTENSITY]);
|
||||
m_swapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
FName m_Name;
|
||||
int m_Args[5];
|
||||
|
@ -143,6 +153,7 @@ protected:
|
|||
ELightType m_type;
|
||||
int8_t m_attenuate;
|
||||
bool m_subtractive, m_additive, m_halo, m_dontlightself;
|
||||
bool m_swapped = false;
|
||||
};
|
||||
|
||||
TArray<FLightDefaults *> LightDefaults;
|
||||
|
@ -178,8 +189,8 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const
|
|||
light->SetOffset(m_Pos);
|
||||
light->halo = m_halo;
|
||||
for (int a = 0; a < 3; a++) light->args[a] = clamp<int>((int)(m_Args[a]), 0, 255);
|
||||
light->args[LIGHT_INTENSITY] = int(m_Args[LIGHT_INTENSITY]);
|
||||
light->args[LIGHT_SECONDARY_INTENSITY] = int(m_Args[LIGHT_SECONDARY_INTENSITY]);
|
||||
light->args[LIGHT_INTENSITY] = m_Args[LIGHT_INTENSITY];
|
||||
light->args[LIGHT_SECONDARY_INTENSITY] = m_Args[LIGHT_SECONDARY_INTENSITY];
|
||||
light->flags4 &= ~(MF4_ADDITIVE | MF4_SUBTRACTIVE | MF4_DONTLIGHTSELF);
|
||||
if (m_subtractive) light->flags4 |= MF4_SUBTRACTIVE;
|
||||
if (m_additive) light->flags4 |= MF4_ADDITIVE;
|
||||
|
@ -190,11 +201,13 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const
|
|||
float pulseTime = float(m_Param / TICRATE);
|
||||
|
||||
light->m_lastUpdate = level.maptime;
|
||||
light->m_cycler.SetParams(float(light->args[LIGHT_SECONDARY_INTENSITY]), float(light->args[LIGHT_INTENSITY]), pulseTime, oldtype == PulseLight);
|
||||
if (m_swapped) light->m_cycler.SetParams(float(light->args[LIGHT_SECONDARY_INTENSITY]), float(light->args[LIGHT_INTENSITY]), pulseTime, oldtype == PulseLight);
|
||||
else light->m_cycler.SetParams(float(light->args[LIGHT_INTENSITY]), float(light->args[LIGHT_SECONDARY_INTENSITY]), pulseTime, oldtype == PulseLight);
|
||||
light->m_cycler.ShouldCycle(true);
|
||||
light->m_cycler.SetCycleType(CYCLE_Sin);
|
||||
light->m_currentRadius = light->m_cycler.GetVal();
|
||||
if (light->m_currentRadius <= 0) light->m_currentRadius = 1;
|
||||
light->swapped = m_swapped;
|
||||
}
|
||||
|
||||
switch (m_attenuate)
|
||||
|
@ -474,13 +487,7 @@ void gl_ParsePulseLight(FScanner &sc)
|
|||
sc.ScriptError("Unknown tag: %s\n", sc.String);
|
||||
}
|
||||
}
|
||||
if (defaults->GetArg(LIGHT_INTENSITY) > defaults->GetArg(LIGHT_SECONDARY_INTENSITY))
|
||||
{
|
||||
auto i = defaults->GetArg(LIGHT_INTENSITY);
|
||||
auto j = defaults->GetArg(LIGHT_SECONDARY_INTENSITY);
|
||||
defaults->SetArg(LIGHT_INTENSITY, j);
|
||||
defaults->SetArg(LIGHT_SECONDARY_INTENSITY, i);
|
||||
}
|
||||
defaults->OrderIntensities();
|
||||
|
||||
gl_AddLightDefaults(defaults);
|
||||
}
|
||||
|
@ -564,6 +571,7 @@ void gl_ParseFlickerLight(FScanner &sc)
|
|||
sc.ScriptError("Unknown tag: %s\n", sc.String);
|
||||
}
|
||||
}
|
||||
defaults->OrderIntensities();
|
||||
gl_AddLightDefaults(defaults);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -141,6 +141,7 @@ public:
|
|||
bool halo;
|
||||
BYTE color2[3];
|
||||
bool visibletoplayer;
|
||||
bool swapped;
|
||||
int bufferindex;
|
||||
|
||||
|
||||
|
|
|
@ -395,9 +395,10 @@ void MessagePump (const SDL_Event &sev)
|
|||
{
|
||||
event.type = EV_GUI_Event;
|
||||
event.subtype = sev.type == SDL_KEYDOWN ? EV_GUI_KeyDown : EV_GUI_KeyUp;
|
||||
event.data3 = ((sev.key.keysym.mod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
|
||||
((sev.key.keysym.mod & KMOD_CTRL) ? GKM_CTRL : 0) |
|
||||
((sev.key.keysym.mod & KMOD_ALT) ? GKM_ALT : 0);
|
||||
SDL_Keymod kmod = SDL_GetModState();
|
||||
event.data3 = ((kmod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
|
||||
((kmod & KMOD_CTRL) ? GKM_CTRL : 0) |
|
||||
((kmod & KMOD_ALT) ? GKM_ALT : 0);
|
||||
|
||||
if (event.subtype == EV_GUI_KeyDown)
|
||||
{
|
||||
|
@ -458,6 +459,7 @@ void MessagePump (const SDL_Event &sev)
|
|||
event.type = EV_GUI_Event;
|
||||
event.subtype = EV_GUI_Char;
|
||||
event.data1 = sev.text.text[0];
|
||||
event.data2 = !!(SDL_GetModState() & KMOD_ALT);
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1059,6 +1059,33 @@ DEFINE_PROPERTY(bloodcolor, C, Actor)
|
|||
static_cast<PClassActor *>(info)->BloodColor = pe;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(bloodtype, Sss, Actor)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0)
|
||||
PROP_STRING_PARM(str1, 1)
|
||||
PROP_STRING_PARM(str2, 2)
|
||||
|
||||
FName blood = str;
|
||||
// normal blood
|
||||
defaults->NameVar("BloodType") = blood;
|
||||
|
||||
if (PROP_PARM_COUNT > 1)
|
||||
{
|
||||
blood = str1;
|
||||
}
|
||||
// blood splatter
|
||||
defaults->NameVar("BloodType2") = blood;
|
||||
|
||||
if (PROP_PARM_COUNT > 2)
|
||||
{
|
||||
blood = str2;
|
||||
}
|
||||
// axe blood
|
||||
defaults->NameVar("BloodType3") = blood;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -393,7 +393,6 @@ void FString::Remove(size_t index, size_t remlen)
|
|||
}
|
||||
else
|
||||
{
|
||||
remlen = Len() - remlen < remlen ? Len() - remlen : remlen;
|
||||
if (Data()->RefCount == 1)
|
||||
{ // Can do this in place
|
||||
memmove(Chars + index, Chars + index + remlen, Len() - index - remlen);
|
||||
|
|
|
@ -497,6 +497,12 @@ ABC4EB5A1535ECCD0061AD14F3547908 // Plutonia Experiment, map26
|
|||
setsectorspecial 156 0
|
||||
}
|
||||
|
||||
B68EB7CFB4CC481796E2919B9C16DFBD // Moc11.wad e1m6
|
||||
{
|
||||
setvertex 1650 -3072 2671
|
||||
setvertex 1642 -2944 2671
|
||||
}
|
||||
|
||||
712BB4CFBD0753178CA0C6814BE4C288 // map12 BTSX_E1 - patch some rendering glitches that are problematic to detect
|
||||
{
|
||||
setsectortag 545 32000
|
||||
|
|
|
@ -106,7 +106,6 @@ CMPTMNU_RENDERINGBEHAVIOR = "Rendering Behaviour";
|
|||
CMPTMNU_SOUNDBEHAVIOR = "Sound Behaviour";
|
||||
CMPTMNU_SECTORSOUNDS = "Sector sounds use centre as source";
|
||||
OPTVAL_MAPDEFINEDCOLORSONLY = "Map defined colours only";
|
||||
OPTVAL_NODOORS = "All except doors";
|
||||
C_GRAY = "\ccgrey";
|
||||
C_DARKGRAY = "\cudark grey";
|
||||
|
||||
|
|
|
@ -2298,6 +2298,7 @@ OPTVAL_FRONT = "Front";
|
|||
OPTVAL_ANIMATED = "Animated";
|
||||
OPTVAL_ROTATED = "Rotated";
|
||||
OPTVAL_MAPDEFINEDCOLORSONLY = "Map defined colors only";
|
||||
OPTVAL_NODOORS = "All except doors";
|
||||
OPTVAL_DOUBLE = "Double";
|
||||
OPTVAL_TRIPLE = "Triple";
|
||||
OPTVAL_QUADRUPLE = "Quadruple";
|
||||
|
|
|
@ -1052,7 +1052,7 @@ OptionValue MapBackTypes
|
|||
OptionValue MapTriggers
|
||||
{
|
||||
0, "$OPTVAL_OFF"
|
||||
1, "$OPTVAL_NO_DOORS"
|
||||
1, "$OPTVAL_NODOORS"
|
||||
2, "$OPTVAL_ON"
|
||||
}
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ class Actor : Thinker native
|
|||
Property DontHurtShooter: DontHurtShooter;
|
||||
Property ExplosionRadius: ExplosionRadius;
|
||||
Property ExplosionDamage: ExplosionDamage;
|
||||
Property BloodType: BloodType, BloodType2, BloodType3;
|
||||
//Property BloodType: BloodType, BloodType2, BloodType3;
|
||||
Property FastSpeed: FastSpeed;
|
||||
Property HowlSound: HowlSound;
|
||||
Property GibHealth: GibHealth;
|
||||
|
|
Loading…
Reference in a new issue