Files
2026-02-02 04:50:13 +01:00

136 lines
4.0 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 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
* 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "m4/wscript/ws_timer.h"
#include "m4/vars.h"
namespace M4 {
static void dispose_timeRequest(onTimeReq *timeReq);
bool ws_InitWSTimer(void) {
_GWS(firstTimeReq) = nullptr;
return true;
}
void ws_KillTime() {
onTimeReq *tempTime = _GWS(firstTimeReq);
while (tempTime) {
_GWS(firstTimeReq) = _GWS(firstTimeReq)->next;
dispose_timeRequest(tempTime);
tempTime = _GWS(firstTimeReq);
}
}
static onTimeReq *new_timeRequest() {
return (onTimeReq *)mem_alloc(sizeof(onTimeReq), "onTimeReq");
}
static void dispose_timeRequest(onTimeReq *timeReq) {
if (timeReq) {
mem_free(timeReq);
}
}
void ws_MakeOnTimeReq(int32 wakeUpTime, machine *myXM, int32 pcOffset, int32 pcCount) {
// Create a new time request struct and set it's fields
onTimeReq *newTimeReq = new_timeRequest();
newTimeReq->myTime = wakeUpTime;
newTimeReq->myXM = myXM;
newTimeReq->pcOffset = pcOffset;
newTimeReq->pcCount = pcCount;
// Insert the new time req into the list in ascending order
// If the list is empty...
if (!_GWS(firstTimeReq)) {
newTimeReq->next = nullptr;
_GWS(firstTimeReq) = newTimeReq;
} else if (newTimeReq->myTime <= _GWS(firstTimeReq)->myTime) {
// Else if it belongs at the front of a non-empty list..
newTimeReq->next = _GWS(firstTimeReq);
_GWS(firstTimeReq) = newTimeReq;
} else {
// Else it belongs in the middle/end of a non-empty list...
onTimeReq *tempTimeReq = _GWS(firstTimeReq);
while (tempTimeReq->next && (tempTimeReq->next->myTime < newTimeReq->myTime)) {
tempTimeReq = tempTimeReq->next;
}
newTimeReq->next = tempTimeReq->next;
tempTimeReq->next = newTimeReq;
}
}
void ws_CancelOnTimeReqs(machine *m) {
if (!m)
return;
// Pass through the linked list, removing any requests for machine* m.
onTimeReq *prevTimeReq = _GWS(firstTimeReq);
onTimeReq *tempTimeReq = _GWS(firstTimeReq);
while (tempTimeReq) {
// If tempTimeReq is one to be cancelled...
if (tempTimeReq->myXM == m) {
// If req is first in the list
if (tempTimeReq == _GWS(firstTimeReq)) {
_GWS(firstTimeReq) = _GWS(firstTimeReq)->next;
prevTimeReq = _GWS(firstTimeReq);
dispose_timeRequest(tempTimeReq);
tempTimeReq = _GWS(firstTimeReq);
} else {
// Else prevTimeReq is the parent of tempTimeReq
prevTimeReq->next = tempTimeReq->next;
dispose_timeRequest(tempTimeReq);
tempTimeReq = prevTimeReq->next;
}
} else {
// Else check next req in list, maintain prevTimeReq is parent of tempTimeReq
if (prevTimeReq != tempTimeReq) {
prevTimeReq = prevTimeReq->next;
}
tempTimeReq = tempTimeReq->next;
}
}
}
void ws_CheckTimeReqs(int32 curTime) {
// Loop through the list, answering all expired time requests
onTimeReq *tempTimeReq = _GWS(firstTimeReq);
while (tempTimeReq && (tempTimeReq->myTime <= curTime)) {
// Extract all important information from request
machine *myXM = tempTimeReq->myXM;
int32 pcOffset = tempTimeReq->pcOffset;
int32 pcCount = tempTimeReq->pcCount;
// Remove it from the list and dispose
_GWS(firstTimeReq) = _GWS(firstTimeReq)->next;
dispose_timeRequest(tempTimeReq);
// Execute machine instructions for onTimeReq
ws_StepWhile(myXM, pcOffset, pcCount);
tempTimeReq = _GWS(firstTimeReq);
}
}
} // End of namespace M4