2017-08-26 19:45:16 +00:00
|
|
|
/**
|
|
|
|
* @file nevent.c
|
|
|
|
* @brief Implementation of the event
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "compiler.h"
|
|
|
|
#include "nevent.h"
|
|
|
|
#include "cpucore.h"
|
|
|
|
#include "pccore.h"
|
|
|
|
|
|
|
|
_NEVENT g_nevent;
|
|
|
|
|
|
|
|
void nevent_allreset(void)
|
|
|
|
{
|
2019-03-21 11:48:05 +00:00
|
|
|
/* すべてをリセット */
|
2017-08-26 19:45:16 +00:00
|
|
|
memset(&g_nevent, 0, sizeof(g_nevent));
|
|
|
|
}
|
|
|
|
|
|
|
|
void nevent_get1stevent(void)
|
|
|
|
{
|
2019-03-21 11:48:05 +00:00
|
|
|
/* 最短のイベントのクロック数をセット */
|
2017-08-26 19:45:16 +00:00
|
|
|
if (g_nevent.readyevents)
|
|
|
|
{
|
|
|
|
CPU_BASECLOCK = g_nevent.item[g_nevent.level[0]].clock;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-03-21 11:48:05 +00:00
|
|
|
/* イベントがない場合のクロック数をセット */
|
2017-08-26 19:45:16 +00:00
|
|
|
CPU_BASECLOCK = NEVENT_MAXCLOCK;
|
|
|
|
}
|
|
|
|
|
2019-03-21 11:48:05 +00:00
|
|
|
/* カウンタへセット */
|
2017-08-26 19:45:16 +00:00
|
|
|
CPU_REMCLOCK = CPU_BASECLOCK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void nevent_execute(void)
|
|
|
|
{
|
|
|
|
UINT nEvents;
|
|
|
|
UINT i;
|
|
|
|
NEVENTID id;
|
|
|
|
NEVENTITEM item;
|
|
|
|
|
|
|
|
nEvents = 0;
|
|
|
|
for (i = 0; i < g_nevent.waitevents; i++)
|
|
|
|
{
|
|
|
|
id = g_nevent.waitevent[i];
|
|
|
|
item = &g_nevent.item[id];
|
|
|
|
|
2019-03-21 11:48:05 +00:00
|
|
|
/* コールバックの実行 */
|
2017-08-26 19:45:16 +00:00
|
|
|
if (item->proc != NULL)
|
|
|
|
{
|
|
|
|
item->proc(item);
|
|
|
|
|
2019-03-21 11:48:05 +00:00
|
|
|
/* 次回に持ち越しのイベントのチェック */
|
2017-08-26 19:45:16 +00:00
|
|
|
if (item->flag & NEVENT_WAIT)
|
|
|
|
{
|
|
|
|
g_nevent.waitevent[nEvents++] = id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
item->flag &= ~(NEVENT_WAIT);
|
|
|
|
}
|
|
|
|
item->flag &= ~(NEVENT_SETEVENT);
|
|
|
|
}
|
|
|
|
g_nevent.waitevents = nEvents;
|
|
|
|
}
|
|
|
|
|
|
|
|
void nevent_progress(void)
|
|
|
|
{
|
|
|
|
UINT nEvents;
|
|
|
|
SINT32 nextbase;
|
|
|
|
UINT i;
|
|
|
|
NEVENTID id;
|
|
|
|
NEVENTITEM item;
|
2019-01-08 10:53:22 +00:00
|
|
|
UINT8 fevtchk = 0;
|
2017-08-26 19:45:16 +00:00
|
|
|
|
|
|
|
CPU_CLOCK += CPU_BASECLOCK;
|
|
|
|
nEvents = 0;
|
|
|
|
nextbase = NEVENT_MAXCLOCK;
|
|
|
|
for (i = 0; i < g_nevent.readyevents; i++)
|
|
|
|
{
|
|
|
|
id = g_nevent.level[i];
|
|
|
|
item = &g_nevent.item[id];
|
|
|
|
item->clock -= CPU_BASECLOCK;
|
|
|
|
if (item->clock > 0)
|
|
|
|
{
|
2019-03-21 11:48:05 +00:00
|
|
|
/* イベント待ち中 */
|
2017-08-26 19:45:16 +00:00
|
|
|
g_nevent.level[nEvents++] = id;
|
|
|
|
if (nextbase >= item->clock)
|
|
|
|
{
|
|
|
|
nextbase = item->clock;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-03-21 11:48:05 +00:00
|
|
|
/* イベント発生 */
|
2017-08-26 19:45:16 +00:00
|
|
|
if (!(item->flag & (NEVENT_SETEVENT | NEVENT_WAIT)))
|
|
|
|
{
|
|
|
|
g_nevent.waitevent[g_nevent.waitevents++] = id;
|
|
|
|
}
|
|
|
|
item->flag |= NEVENT_SETEVENT;
|
|
|
|
item->flag &= ~(NEVENT_ENABLE);
|
|
|
|
// TRACEOUT(("event = %x", id));
|
|
|
|
}
|
2019-01-08 10:53:22 +00:00
|
|
|
fevtchk |= (id==NEVENT_FLAMES ? 1 : 0);
|
2017-08-26 19:45:16 +00:00
|
|
|
}
|
|
|
|
g_nevent.readyevents = nEvents;
|
|
|
|
CPU_BASECLOCK = nextbase;
|
|
|
|
CPU_REMCLOCK += nextbase;
|
|
|
|
nevent_execute();
|
2019-01-08 10:53:22 +00:00
|
|
|
|
2019-03-21 11:48:05 +00:00
|
|
|
// NEVENT_FLAMESが消える問題に暫定対処
|
2019-01-08 10:53:22 +00:00
|
|
|
if(!fevtchk){
|
|
|
|
printf("NEVENT_FLAMES is missing!!\n");
|
|
|
|
pcstat.screendispflag = 0;
|
|
|
|
}
|
2017-08-26 19:45:16 +00:00
|
|
|
// TRACEOUT(("nextbase = %d (%d)", nextbase, CPU_REMCLOCK));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nevent_reset(NEVENTID id)
|
|
|
|
{
|
|
|
|
UINT i;
|
|
|
|
|
2019-03-21 11:48:05 +00:00
|
|
|
/* 現在進行してるイベントを検索 */
|
2017-08-26 19:45:16 +00:00
|
|
|
for (i = 0; i < g_nevent.readyevents; i++)
|
|
|
|
{
|
|
|
|
if (g_nevent.level[i] == id)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-03-21 11:48:05 +00:00
|
|
|
/* イベントは存在した? */
|
2017-08-26 19:45:16 +00:00
|
|
|
if (i < g_nevent.readyevents)
|
|
|
|
{
|
2019-03-21 11:48:05 +00:00
|
|
|
/* 存在していたら削る */
|
2017-08-26 19:45:16 +00:00
|
|
|
g_nevent.readyevents--;
|
|
|
|
for (; i < g_nevent.readyevents; i++)
|
|
|
|
{
|
|
|
|
g_nevent.level[i] = g_nevent.level[i + 1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nevent_waitreset(NEVENTID id)
|
|
|
|
{
|
|
|
|
UINT i;
|
|
|
|
|
2019-03-21 11:48:05 +00:00
|
|
|
/* 現在進行してるイベントを検索 */
|
2017-08-26 19:45:16 +00:00
|
|
|
for (i = 0; i < g_nevent.waitevents; i++)
|
|
|
|
{
|
|
|
|
if (g_nevent.waitevent[i] == id)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-03-21 11:48:05 +00:00
|
|
|
/* イベントは存在した? */
|
2017-08-26 19:45:16 +00:00
|
|
|
if (i < g_nevent.waitevents)
|
|
|
|
{
|
2019-03-21 11:48:05 +00:00
|
|
|
/* 存在していたら削る */
|
2017-08-26 19:45:16 +00:00
|
|
|
g_nevent.waitevents--;
|
|
|
|
for (; i < g_nevent.waitevents; i++)
|
|
|
|
{
|
|
|
|
g_nevent.waitevent[i] = g_nevent.waitevent[i + 1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nevent_set(NEVENTID id, SINT32 eventclock, NEVENTCB proc, NEVENTPOSITION absolute)
|
|
|
|
{
|
|
|
|
SINT32 clk;
|
|
|
|
NEVENTITEM item;
|
|
|
|
UINT eventId;
|
|
|
|
UINT i;
|
|
|
|
|
|
|
|
// TRACEOUT(("event %d - %xclocks", id, eventclock));
|
|
|
|
|
|
|
|
clk = CPU_BASECLOCK - CPU_REMCLOCK;
|
|
|
|
item = &g_nevent.item[id];
|
|
|
|
item->proc = proc;
|
|
|
|
item->flag = 0;
|
|
|
|
if (absolute)
|
|
|
|
{
|
|
|
|
item->clock = eventclock + clk;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->clock += eventclock;
|
|
|
|
}
|
|
|
|
#if 0
|
|
|
|
if (item->clock < clk)
|
|
|
|
{
|
|
|
|
item->clock = clk;
|
|
|
|
}
|
|
|
|
#endif
|
2019-03-21 11:48:05 +00:00
|
|
|
/* イベントの削除 */
|
2017-08-26 19:45:16 +00:00
|
|
|
nevent_reset(id);
|
|
|
|
|
2019-03-21 11:48:05 +00:00
|
|
|
/* イベントの挿入位置の検索 */
|
2017-08-26 19:45:16 +00:00
|
|
|
for (eventId = 0; eventId < g_nevent.readyevents; eventId++)
|
|
|
|
{
|
|
|
|
if (item->clock < g_nevent.item[g_nevent.level[eventId]].clock)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-21 11:48:05 +00:00
|
|
|
/* イベントの挿入 */
|
2017-08-26 19:45:16 +00:00
|
|
|
for (i = g_nevent.readyevents; i > eventId; i--)
|
|
|
|
{
|
|
|
|
g_nevent.level[i] = g_nevent.level[i - 1];
|
|
|
|
}
|
|
|
|
g_nevent.level[eventId] = id;
|
|
|
|
g_nevent.readyevents++;
|
|
|
|
|
2019-03-21 11:48:05 +00:00
|
|
|
/* もし最短イベントだったら... */
|
2017-08-26 19:45:16 +00:00
|
|
|
if (eventId == 0)
|
|
|
|
{
|
|
|
|
clk = CPU_BASECLOCK - item->clock;
|
|
|
|
CPU_BASECLOCK -= clk;
|
|
|
|
CPU_REMCLOCK -= clk;
|
|
|
|
// TRACEOUT(("reset nextbase -%d (%d)", clock, CPU_REMCLOCK));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nevent_setbyms(NEVENTID id, SINT32 ms, NEVENTCB proc, NEVENTPOSITION absolute)
|
|
|
|
{
|
|
|
|
nevent_set(id, (pccore.realclock / 1000) * ms, proc, absolute);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL nevent_iswork(NEVENTID id)
|
|
|
|
{
|
|
|
|
UINT i;
|
|
|
|
|
2019-03-21 11:48:05 +00:00
|
|
|
/* 現在進行してるイベントを検索 */
|
2017-08-26 19:45:16 +00:00
|
|
|
for (i = 0; i < g_nevent.readyevents; i++)
|
|
|
|
{
|
|
|
|
if (g_nevent.level[i] == id)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
SINT32 nevent_getremain(NEVENTID id)
|
|
|
|
{
|
|
|
|
UINT i;
|
|
|
|
|
2019-03-21 11:48:05 +00:00
|
|
|
/* 現在進行してるイベントを検索 */
|
2017-08-26 19:45:16 +00:00
|
|
|
for (i = 0; i < g_nevent.readyevents; i++)
|
|
|
|
{
|
|
|
|
if (g_nevent.level[i] == id)
|
|
|
|
{
|
|
|
|
return (g_nevent.item[id].clock - (CPU_BASECLOCK - CPU_REMCLOCK));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void nevent_forceexit(void)
|
|
|
|
{
|
|
|
|
if (CPU_REMCLOCK > 0)
|
|
|
|
{
|
|
|
|
CPU_BASECLOCK -= CPU_REMCLOCK;
|
|
|
|
CPU_REMCLOCK = 0;
|
|
|
|
}
|
|
|
|
}
|