diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 6888bbba4..72d3aad4e 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -1,13 +1,13 @@ //------------------------------------------------------------------------- /* -Copyright (C) 2010-2019 EDuke32 developers and contributors -Copyright (C) 2019 Nuke.YKT +Copyright (C) 2020 Christoph Oelckers & Mitchell Richters -This file is part of NBlood. +This file is part of Raze. -NBlood is free software; you can redistribute it and/or +Raze is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/source/blood/src/eventq.cpp b/source/blood/src/eventq.cpp index 95c1951f7..a125f73cc 100644 --- a/source/blood/src/eventq.cpp +++ b/source/blood/src/eventq.cpp @@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include +#include #include "build.h" #include "common_game.h" @@ -34,7 +35,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "eventq.h" #include "globals.h" #include "loadsave.h" -#include "pqueue.h" #include "triggers.h" #include "view.h" #include "nnexts.h" @@ -42,41 +42,49 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS + +struct queueItem +{ + uint32_t priority; + EVENT data; + + bool operator<(const queueItem& other) const + { + return priority < other.priority; + } +}; + class EventQueue { public: - PriorityQueue* PQueue; - EventQueue() - { - PQueue = NULL; - } - ~EventQueue() - { - if (PQueue) delete PQueue; - } + std::multiset set; + bool IsNotEmpty(unsigned int nTime) { - return PQueue->Size() > 0 && nTime >= PQueue->LowestPriority(); + return set.size() > 0 && nTime >= set.begin()->priority; } EVENT ERemove(void) { - return PQueue->Remove(); + assert(set.size() > 0); + EVENT data = set.begin()->data; + set.erase(set.begin()); + return data; + } + + template + void Kill(func pMatch) + { + for (auto i = set.begin(); i != set.end();) + { + if (pMatch(i->data)) + i = set.erase(i); + else + i++; + } } - void Kill(int, int); - void Kill(int, int, CALLBACK_ID); }; EventQueue eventQ; -void EventQueue::Kill(int a1, int a2) -{ - PQueue->Kill([=](EVENT nItem)->bool {return nItem.index == a1 && nItem.type == a2; }); -} - -void EventQueue::Kill(int a1, int a2, CALLBACK_ID a3) -{ - EVENT evn = { (unsigned int)a1, (unsigned int)a2, kCmdCallback, (unsigned int)a3 }; - PQueue->Kill([=](EVENT nItem)->bool {return !memcmp(&nItem, &evn, sizeof(EVENT)); }); -} RXBUCKET rxBucket[kChannelMax+1]; @@ -265,13 +273,7 @@ unsigned short bucketHead[1024+1]; void evInit(void) { - if (eventQ.PQueue) - delete eventQ.PQueue; - if (VanillaMode()) - eventQ.PQueue = new VanillaPriorityQueue(); - else - eventQ.PQueue = new StdPriorityQueue(); - eventQ.PQueue->Clear(); + eventQ.set.clear(); int nCount = 0; for (int i = 0; i < numsectors; i++) { @@ -501,7 +503,7 @@ void evPost(int nIndex, int nType, unsigned int nDelta, COMMAND_ID command) { evn.index = nIndex; evn.type = nType; evn.cmd = command; - eventQ.PQueue->Insert(gFrameClock+nDelta, evn); + eventQ.set.insert({ gFrameClock + nDelta, evn }); } void evPost(int nIndex, int nType, unsigned int nDelta, CALLBACK_ID callback) { @@ -510,23 +512,11 @@ void evPost(int nIndex, int nType, unsigned int nDelta, CALLBACK_ID callback) { evn.type = nType; evn.cmd = kCmdCallback; evn.funcID = callback; - eventQ.PQueue->Insert(gFrameClock+nDelta, evn); + eventQ.set.insert({ gFrameClock + nDelta, evn }); } void evProcess(unsigned int nTime) { -#if 0 - while (1) - { - // Inlined? - char bDone; - if (eventQ.fNodeCount > 0 && nTime >= eventQ.queueItems[1]) - bDone = 1; - else - bDone = 0; - if (!bDone) - break; -#endif while(eventQ.IsNotEmpty(nTime)) { EVENT event = eventQ.ERemove(); @@ -556,12 +546,13 @@ void evProcess(unsigned int nTime) void evKill(int a1, int a2) { - eventQ.Kill(a1, a2); + eventQ.Kill([=](EVENT nItem)->bool {return nItem.index == a1 && nItem.type == a2; }); } void evKill(int a1, int a2, CALLBACK_ID a3) { - eventQ.Kill(a1, a2, a3); + EVENT evn = { (unsigned int)a1, (unsigned int)a2, kCmdCallback, (unsigned int)a3 }; + eventQ.Kill([=](EVENT nItem)->bool {return !memcmp(&nItem, &evn, sizeof(EVENT)); }); } class EventQLoadSave : public LoadSave @@ -573,22 +564,14 @@ public: void EventQLoadSave::Load() { - if (eventQ.PQueue) - delete eventQ.PQueue; - Read(&eventQ, sizeof(eventQ)); - if (VanillaMode()) - eventQ.PQueue = new VanillaPriorityQueue(); - else - eventQ.PQueue = new StdPriorityQueue(); + eventQ.set.clear(); int nEvents; Read(&nEvents, sizeof(nEvents)); for (int i = 0; i < nEvents; i++) { - EVENT event = {}; - unsigned int eventtime; - Read(&eventtime, sizeof(eventtime)); + queueItem event = {}; Read(&event, sizeof(event)); - eventQ.PQueue->Insert(eventtime, event); + eventQ.set.insert(event); } Read(rxBucket, sizeof(rxBucket)); Read(bucketHead, sizeof(bucketHead)); @@ -596,22 +579,11 @@ void EventQLoadSave::Load() void EventQLoadSave::Save() { - EVENT events[1024]; - unsigned int eventstime[1024]; - Write(&eventQ, sizeof(eventQ)); - int nEvents = eventQ.PQueue->Size(); + int nEvents = eventQ.set.size(); Write(&nEvents, sizeof(nEvents)); - for (int i = 0; i < nEvents; i++) + for (auto &item : eventQ.set) { - eventstime[i] = eventQ.PQueue->LowestPriority(); - events[i] = eventQ.ERemove(); - Write(&eventstime[i], sizeof(eventstime[i])); - Write(&events[i], sizeof(events[i])); - } - assert(eventQ.PQueue->Size() == 0); - for (int i = 0; i < nEvents; i++) - { - eventQ.PQueue->Insert(eventstime[i], events[i]); + Write(&item, sizeof(item)); } Write(rxBucket, sizeof(rxBucket)); Write(bucketHead, sizeof(bucketHead)); diff --git a/source/blood/src/loadsave.cpp b/source/blood/src/loadsave.cpp index e0708dba7..9fcb6c89c 100644 --- a/source/blood/src/loadsave.cpp +++ b/source/blood/src/loadsave.cpp @@ -465,7 +465,7 @@ void LoadSave::Read(void *pData, int nSize) I_Error("Error reading save file."); } -void LoadSave::Write(void *pData, int nSize) +void LoadSave::Write(const void *pData, int nSize) { dword_27AA38 += nSize; dword_27AA3C += nSize; diff --git a/source/blood/src/loadsave.h b/source/blood/src/loadsave.h index 732a41763..c0e72caa1 100644 --- a/source/blood/src/loadsave.h +++ b/source/blood/src/loadsave.h @@ -40,7 +40,7 @@ public: virtual void Save(void); virtual void Load(void); void Read(void *, int); - void Write(void *, int); + void Write(const void *, int); }; void LoadSaveSetup(void); diff --git a/source/blood/src/pqueue.h b/source/blood/src/pqueue.h deleted file mode 100644 index ea6a05dd2..000000000 --- a/source/blood/src/pqueue.h +++ /dev/null @@ -1,191 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2010-2019 EDuke32 developers and contributors -Copyright (C) 2019 Nuke.YKT - -This file is part of NBlood. - -NBlood is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- -#pragma once -#include -#include -#include "common_game.h" - -BEGIN_BLD_NS - -enum { kPQueueSize = 1024 }; - -template struct queueItem -{ - uint32_t TotalKills; // priority - T Kills; // data - bool operator>(const queueItem& other) const - { - return TotalKills > other.TotalKills; - } - bool operator<(const queueItem& other) const - { - return TotalKills < other.TotalKills; - } - bool operator>=(const queueItem& other) const - { - return TotalKills >= other.TotalKills; - } - bool operator<=(const queueItem& other) const - { - return TotalKills <= other.TotalKills; - } - bool operator!=(const queueItem& other) const - { - return TotalKills != other.TotalKills; - } - bool operator==(const queueItem& other) const - { - return TotalKills == other.TotalKills; - } -}; - -template class PriorityQueue -{ -public: - virtual ~PriorityQueue() {} - virtual uint32_t Size(void) = 0; - virtual void Clear(void) = 0; - virtual void Insert(uint32_t, T) = 0; - virtual T Remove(void) = 0; - virtual uint32_t LowestPriority(void) = 0; - virtual void Kill(std::function pMatch) = 0; -}; - -template class VanillaPriorityQueue : public PriorityQueue -{ -public: - queueItem queueItems[kPQueueSize + 1]; - uint32_t fNodeCount; // at2008 - ~VanillaPriorityQueue() {} - uint32_t Size(void) { return fNodeCount; }; - void Clear(void) - { - fNodeCount = 0; - memset(queueItems, 0, sizeof(queueItems)); - } - void Upheap(void) - { - queueItem item = queueItems[fNodeCount]; - queueItems[0].TotalKills = 0; - uint32_t x = fNodeCount; - while (queueItems[x>>1] > item) - { - queueItems[x] = queueItems[x>>1]; - x >>= 1; - } - queueItems[x] = item; - } - void Downheap(uint32_t n) - { - queueItem item = queueItems[n]; - while (fNodeCount/2 >= n) - { - uint32_t t = n*2; - if (t < fNodeCount && queueItems[t] > queueItems[t+1]) - t++; - if (item <= queueItems[t]) - break; - queueItems[n] = queueItems[t]; - n = t; - } - queueItems[n] = item; - } - void Delete(uint32_t k) - { - assert(k <= fNodeCount); - queueItems[k] = queueItems[fNodeCount--]; - Downheap(k); - } - void Insert(uint32_t a1, T a2) - { - assert(fNodeCount < kPQueueSize); - fNodeCount++; - queueItems[fNodeCount].TotalKills = a1; - queueItems[fNodeCount].Kills = a2; - Upheap(); - } - T Remove(void) - { - T data = queueItems[1].Kills; - queueItems[1] = queueItems[fNodeCount--]; - Downheap(1); - return data; - } - uint32_t LowestPriority(void) - { - assert(fNodeCount > 0); - return queueItems[1].TotalKills; - } - void Kill(std::function pMatch) - { - for (unsigned int i = 1; i <= fNodeCount;) - { - if (pMatch(queueItems[i].Kills)) - Delete(i); - else - i++; - } - } -}; - -template class StdPriorityQueue : public PriorityQueue -{ -public: - std::multiset> stdQueue; - ~StdPriorityQueue() - { - stdQueue.clear(); - } - uint32_t Size(void) { return stdQueue.size(); }; - void Clear(void) - { - stdQueue.clear(); - } - void Insert(uint32_t nPriority, T data) - { - stdQueue.insert({ nPriority, data }); - } - T Remove(void) - { - assert(stdQueue.size() > 0); - T data = stdQueue.begin()->Kills; - stdQueue.erase(stdQueue.begin()); - return data; - } - uint32_t LowestPriority(void) - { - return stdQueue.begin()->TotalKills; - } - void Kill(std::function pMatch) - { - for (auto i = stdQueue.begin(); i != stdQueue.end();) - { - if (pMatch(i->Kills)) - i = stdQueue.erase(i); - else - i++; - } - } -}; - -END_BLD_NS