commit 52e10a1761bd0a29edea87e8a33118f507af0150
parent 810e31341a27350a9b63a03934797398875b0180
Author: Erick Vásquez García <41172072+Erick194@users.noreply.github.com>
Date: Wed, 18 Nov 2020 00:20:50 -0600
Add files via upload
Diffstat:
A | Doom 64/wesshand.c | | | 1003 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | Doom 64/wessseq.c | | | 900 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | Doom 64/wessshell.c | | | 27 | +++++++++++++++++++++++++++ |
A | Doom 64/wesstrak.c | | | 312 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | Doom 64/wesstwek.c | | | 88 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | Doom 64/z_zone.c | | | 574 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
6 files changed, 2904 insertions(+), 0 deletions(-)
diff --git a/Doom 64/wesshand.c b/Doom 64/wesshand.c
@@ -0,0 +1,1003 @@
+
+/* ULTRA64 LIBRARIES */
+#include <ultra64.h>
+#include "ultratypes.h"
+#include <libaudio.h>
+
+/* WESS API INCLUDES */
+#include "wessapi.h" // audio stuff...
+#include "seqload.h"
+#include "soundhw.h"
+#include "wessarc.h"
+#include "wessseq.h"
+
+#include "funqueue.h"
+
+#include "wessedit.h"
+#include "wesstrak.h"
+#include "wesshand.h"
+
+#ifndef NOUSEWESSCODE
+extern pmasterstat *pm_stat; //0x800B41CC
+extern unsigned char CmdLength[36];
+extern unsigned char CmdSort[44];
+extern void(*DrvFunctions[36])(track_status *);
+
+/* used by wess trigger functions */
+enum HandleFlag { NoHandle, YesHandle };
+
+enum HandleStatus { HANDLE_INVALID, HANDLE_STOPPED, HANDLE_PLAYING };
+
+
+char scratch_area[32];//800B41E0
+
+void tracksetspecial(track_status *ptmp, TriggerPlayAttr *attr); // 8003429C
+void trackgetspecial(track_status *ptmp, TriggerPlayAttr *attr); // 80034508
+
+sequence_status *gethandleseq(int handle) // 80032E80
+{
+ char hindx;
+ sequence_status *psq;
+
+ if ((handle > 0) && (handle <= wess_driver_sequences))
+ {
+ hindx = handle - 1;
+ if ((psq = (pm_stat->pseqstattbl + hindx))->flags & SEQ_HANDLE)
+ {
+ return(psq);
+ }
+ }
+ return(NULL);
+}
+
+track_status *gethandletrk(int handle, int track) // 80032EE0
+{
+ char hindx;
+ sequence_status *psq;
+ track_status *ptrk;
+
+ if (handle > 0 && handle <= wess_driver_sequences)
+ {
+ hindx = handle - 1;
+ if ((psq = (pm_stat->pseqstattbl + hindx))->flags & SEQ_HANDLE)
+ {
+ if (*(psq->ptrk_indxs + track) != 0xFF)
+ {
+ if ((ptrk = pm_stat->ptrkstattbl + *(psq->ptrk_indxs + track))->flags & TRK_HANDLED)
+ {
+ return(ptrk);
+ }
+ }
+ }
+ }
+ return(NULL);
+}
+
+int wess_handle_get(int seq_num) // 80032F80
+{
+ sequence_data *psq_info;
+
+ if (!Is_Seq_Num_Valid(seq_num))
+ return(NULL);
+
+ psq_info = (pm_stat->pmod_info->pseq_info + seq_num);
+ return wess_seq_structrig(psq_info, seq_num, 0, YesHandle, NULL);
+}
+
+int wess_handle_status(int handle) // 80032FD8
+{
+ sequence_status *psq_stat;
+ int status;
+
+ if(!Is_Module_Loaded())
+ return HANDLE_INVALID;
+
+ psq_stat = gethandleseq(handle);
+
+ status = HANDLE_INVALID;
+ if (psq_stat)
+ {
+ if (psq_stat->playmode)
+ {
+ if (psq_stat->playmode == SEQ_STATE_STOPPED)
+ status = HANDLE_STOPPED;
+ else if (psq_stat->playmode == SEQ_STATE_PLAYING)
+ status = HANDLE_PLAYING;
+ }
+ }
+
+ return status;
+}
+
+void wess_handle_return(int handle) // 80033048
+{
+ sequence_status *psq_stat;
+ track_status *ptmp;
+
+ int li, lj;
+ char *lpdest;
+
+ int _handle;
+
+ _handle = handle;
+
+ if (!Is_Module_Loaded())
+ return;
+
+ wess_disable();
+
+ psq_stat = gethandleseq(_handle);
+
+ if (psq_stat)
+ {
+ li = psq_stat->tracks_active;
+ lj = pm_stat->max_trks_perseq;
+
+ /* *lpdest refers to an active track if not 0xFF */
+ lpdest = psq_stat->ptrk_indxs;
+ while (lj--)
+ {
+ if (*lpdest != 0xFF)
+ {
+ ptmp = (pm_stat->ptrkstattbl + (*lpdest));
+ ptmp->flags &= ~TRK_HANDLED;
+ CmdFuncArr[ptmp->patchtype][TrkOff](ptmp);
+ if (!--li) break;
+ }
+ lpdest++;
+ }
+
+ psq_stat->flags &= ~SEQ_HANDLE;
+ }
+
+ wess_enable();
+
+ return;
+}
+
+void wess_handle_play_special(int handle, TriggerPlayAttr *attr) // 80033180
+{
+ sequence_status *psq_stat;
+ track_status *ptmp;
+
+ int li, lj;
+ char *lpdest;
+
+ int _handle;
+ TriggerPlayAttr *_attr;
+
+ _handle = handle;
+ _attr = attr;
+
+ if (!Is_Module_Loaded())
+ return;
+
+ wess_disable();
+
+ psq_stat = gethandleseq(_handle);
+
+ if (psq_stat)
+ {
+ li = psq_stat->tracks_active;
+ lj = pm_stat->max_trks_perseq;
+
+ /* *lpdest refers to an active track if not 0xFF */
+ lpdest = psq_stat->ptrk_indxs;
+ while (lj--)
+ {
+ if (*lpdest != 0xFF)
+ {
+ ptmp = (pm_stat->ptrkstattbl + (*lpdest));
+ trackstart(ptmp, psq_stat);
+ tracksetspecial(ptmp, _attr);
+ if (!--li) break;
+ }
+ lpdest++;
+ }
+
+ psq_stat->playmode = SEQ_STATE_PLAYING;
+ }
+
+ wess_enable();
+
+ return;
+}
+
+void wess_handle_play(int handle) // 80033298()
+{
+ wess_handle_play_special(handle, 0);
+}
+
+void wess_handle_play_track_special(int handle, int track, TriggerPlayAttr *attr) // 800332B8
+{
+ sequence_status *psq_stat;
+ track_status *ptmp;
+
+ int _handle;
+ int _track;
+ TriggerPlayAttr *_attr;
+
+ _handle = handle;
+ _track = track;
+ _attr = attr;
+
+ if (!Is_Module_Loaded())
+ return;
+
+ wess_disable();
+
+ psq_stat = gethandleseq(_handle);
+
+ if (psq_stat)
+ {
+ ptmp = gethandletrk(_handle, _track);
+
+ if (ptmp)
+ {
+ trackstart(ptmp, psq_stat);
+ tracksetspecial(ptmp, _attr);
+ }
+ }
+
+ wess_enable();
+
+ return;
+}
+
+void wess_handle_play_track(int handle, int track) // 80033344
+{
+ wess_handle_play_track_special(handle, track, 0);
+ return;
+}
+
+void wess_handle_get_special(int handle, TriggerPlayAttr *attr) // 80033364
+{
+ sequence_status *psq_stat;
+ track_status *ptmp;
+
+ int li, lj;
+ char *lpdest;
+
+ int _handle;
+ TriggerPlayAttr *_attr;
+
+ _handle = handle;
+ _attr = attr;
+
+ if (!Is_Module_Loaded())
+ return;
+
+ wess_disable();
+
+ psq_stat = gethandleseq(_handle);
+
+ if (psq_stat)
+ {
+ li = psq_stat->tracks_active;
+ lj = pm_stat->max_trks_perseq;
+
+ /* *lpdest refers to an active track if not 0xFF */
+ lpdest = psq_stat->ptrk_indxs;
+ while (lj--)
+ {
+ if (*lpdest != 0xFF)
+ {
+ ptmp = (pm_stat->ptrkstattbl + (*lpdest));
+ trackgetspecial(ptmp, _attr);
+ if (!--li) break;
+ }
+ lpdest++;
+ }
+ }
+
+ wess_enable();
+
+ return;
+}
+
+void wess_handle_set_special(int handle, TriggerPlayAttr *attr) // 80033454
+{
+ sequence_status *psq_stat;
+ track_status *ptmp;
+
+ int li, lj;
+ char *lpdest;
+
+ int _handle;
+ TriggerPlayAttr *_attr;
+
+ _handle = handle;
+ _attr = attr;
+
+ if (!Is_Module_Loaded())
+ return;
+
+ wess_disable();
+
+ psq_stat = gethandleseq(_handle);
+
+ if (psq_stat)
+ {
+ li = psq_stat->tracks_active;
+ lj = pm_stat->max_trks_perseq;
+
+ /* *lpdest refers to an active track if not 0xFF */
+ lpdest = psq_stat->ptrk_indxs;
+ while (lj--)
+ {
+ if (*lpdest != 0xFF)
+ {
+ ptmp = (pm_stat->ptrkstattbl + (*lpdest));
+ tracksetspecial(ptmp, _attr);
+ if (!--li) break;
+ }
+ lpdest++;
+ }
+ }
+
+ wess_enable();
+
+ return;
+}
+
+void wess_handle_stop(int handle) // 80033544
+{
+ sequence_status *psq_stat;
+ track_status *ptmp;
+
+ int li, lj;
+ char *lpdest;
+
+ int _handle;
+
+ _handle = handle;
+
+ if (!Is_Module_Loaded())
+ return;
+
+ wess_disable();
+
+ psq_stat = gethandleseq(_handle);
+
+ if (psq_stat)
+ {
+ li = psq_stat->tracks_active;
+ lj = pm_stat->max_trks_perseq;
+
+ /* *lpdest refers to an active track if not 0xFF */
+ lpdest = psq_stat->ptrk_indxs;
+ while (lj--)
+ {
+ if (*lpdest != 0xFF)
+ {
+ ptmp = (pm_stat->ptrkstattbl + (*lpdest));
+ CmdFuncArr[ptmp->patchtype][TrkOff](ptmp);
+ if (!--li) break;
+ }
+ lpdest++;
+ }
+ }
+
+ wess_enable();
+
+ return;
+}
+
+void wess_handle_fastsettempo(int handle, short tempo) // 80033658
+{
+ sequence_status *psq_stat;
+ track_status *ptmp;
+
+ int li, lj;
+ char *lpdest;
+ unsigned long ppi;
+
+ int _handle;
+ short _tempo;
+
+ _handle = handle;
+ _tempo = tempo;
+
+ if (!Is_Module_Loaded())
+ return;
+
+ wess_disable();
+
+ psq_stat = gethandleseq(_handle);
+ ppi = 0;
+
+ if (psq_stat)
+ {
+ li = psq_stat->tracks_active;
+ lj = pm_stat->max_trks_perseq;
+
+ /* *lpdest refers to an active track if not 0xFF */
+ lpdest = psq_stat->ptrk_indxs;
+ while (lj--)
+ {
+ if (*lpdest != 0xFF)
+ {
+ ptmp = (pm_stat->ptrkstattbl + (*lpdest));
+ ptmp->qpm = _tempo;
+ if (ppi == 0)
+ ppi = CalcPartsPerInt(GetIntsPerSec(), ptmp->ppq, ptmp->qpm);
+ ptmp->ppi = ppi;
+
+ if (!--li) break;
+ }
+ lpdest++;
+ }
+ }
+
+ wess_enable();
+
+ return;
+}
+
+int wess_handle_fade(void) // 80033788
+{
+ return Is_Module_Loaded();
+}
+
+void wess_handle_resetposition(int handle) // 800337B0
+{
+ sequence_status *psq_stat;
+ track_status *ptmp;
+
+ int li, lj;
+ char *lpdest;
+
+ int _handle;
+
+ _handle = handle;
+
+ if (!Is_Module_Loaded())
+ return;
+
+ wess_disable();
+
+ psq_stat = gethandleseq(_handle);
+
+ if (psq_stat)
+ {
+ li = psq_stat->tracks_active;
+ lj = pm_stat->max_trks_perseq;
+
+ /* *lpdest refers to an active track if not 0xFF */
+ lpdest = psq_stat->ptrk_indxs;
+ while (lj--)
+ {
+ if (*lpdest != 0xFF)
+ {
+ ptmp = (pm_stat->ptrkstattbl + (*lpdest));
+ CmdFuncArr[ptmp->patchtype][TrkMute](ptmp);
+
+ ptmp->starppi = 0;
+ ptmp->totppi = 0;
+ ptmp->ppos = Read_Vlq(ptmp->pstart, &ptmp->deltatime);
+
+ if (!--li) break;
+ }
+ lpdest++;
+ }
+ }
+
+ wess_enable();
+ return;
+}
+
+int wess_track_gotoposition(track_status *ptmp, int position, char *ppos) // 800338F0
+{
+ int deltatime;
+ int status;
+ int accppi;
+
+
+ deltatime = ptmp->deltatime;
+ accppi = ptmp->totppi + (ptmp->starppi >> 16);
+
+ while (1)
+ {
+ accppi += deltatime;
+
+ if (position <= accppi)
+ {
+ status = 1;
+ break;
+ }
+
+ if (*ptmp->ppos == TrkEnd)
+ {
+ status = 0;
+ break;
+ }
+
+ if (*ptmp->ppos == NoteOn || *ptmp->ppos == NoteOff)
+ {
+ ptmp->ppos += CmdLength[*ptmp->ppos];
+ ptmp->ppos = Read_Vlq(ptmp->ppos, &deltatime);
+ continue;
+ }
+ else
+ {
+ if ((*ptmp->ppos < PatchChg) || (*ptmp->ppos > NoteOff))
+ {
+ if ((*ptmp->ppos < StatusMark) || (*ptmp->ppos > NullEvent))
+ {
+ Eng_SeqEnd(ptmp);
+ }
+ else
+ {
+ DrvFunctions[*ptmp->ppos](ptmp);
+
+ if (ptmp->flags & TRK_SKIP)
+ {
+ ptmp->flags &= ~TRK_SKIP;
+ }
+ else
+ {
+ ptmp->ppos += CmdLength[*ptmp->ppos];
+ ptmp->ppos = Read_Vlq(ptmp->ppos, &deltatime);
+ }
+ }
+ }
+ else
+ {
+ CmdFuncArr[ptmp->patchtype][*ptmp->ppos](ptmp);
+ ptmp->ppos += CmdLength[*ptmp->ppos];
+ ptmp->ppos = Read_Vlq(ptmp->ppos, &deltatime);
+ }
+ }
+ }
+
+ if (status)
+ {
+ ptmp->deltatime = accppi - position;
+ ptmp->starppi = 0;
+ ptmp->totppi = position;
+ }
+ else
+ {
+ ptmp->deltatime = 0;
+ ptmp->starppi = 0;
+ ptmp->totppi = accppi;
+ }
+
+ ppos = ptmp->ppos;
+
+ return ptmp->totppi;
+}
+
+int wess_track_setposition(track_status *ptmp, int position, char *ppos) // 80033B24
+{
+ int deltatime;
+ int val;
+ int accppi;
+ int status;
+
+ deltatime = 0;
+ accppi = 0;
+ ptmp->ppos = ptmp->pstart;
+ ptmp->ppos = Read_Vlq(ptmp->ppos, &deltatime);
+
+ while (1)
+ {
+ accppi += deltatime;
+
+ if (position <= accppi)
+ {
+ status = 1;
+ break;
+ }
+
+ if (*ptmp->ppos == TrkEnd)
+ {
+ status = 0;
+ break;
+ }
+
+ if (*ptmp->ppos == NoteOn || *ptmp->ppos == NoteOff)
+ {
+ ptmp->ppos += CmdLength[*ptmp->ppos];
+ ptmp->ppos = Read_Vlq(ptmp->ppos, &deltatime);
+ continue;
+ }
+ else
+ {
+ if ((*ptmp->ppos < PatchChg) || (*ptmp->ppos > NoteOff))
+ {
+ if ((*ptmp->ppos < StatusMark) || (*ptmp->ppos > NullEvent))
+ {
+ Eng_SeqEnd(ptmp);
+ }
+ else
+ {
+ DrvFunctions[*ptmp->ppos](ptmp);
+
+ if (ptmp->flags & TRK_SKIP)
+ {
+ ptmp->flags &= ~TRK_SKIP;
+ }
+ else
+ {
+ ptmp->ppos += CmdLength[*ptmp->ppos];
+ ptmp->ppos = Read_Vlq(ptmp->ppos, &deltatime);
+ }
+ }
+ }
+ else
+ {
+ CmdFuncArr[ptmp->patchtype][*ptmp->ppos](ptmp);
+ ptmp->ppos += CmdLength[*ptmp->ppos];
+ ptmp->ppos = Read_Vlq(ptmp->ppos, &deltatime);
+ }
+ }
+ }
+
+ if (status)
+ {
+ ptmp->deltatime = (accppi - position);
+ ptmp->starppi = 0;
+ ptmp->totppi = position;
+ }
+ else
+ {
+ ptmp->deltatime = 0;
+ ptmp->starppi = 0;
+ ptmp->totppi = accppi;
+ }
+
+ ppos = ptmp->ppos;
+
+ return ptmp->totppi;
+}
+
+int wess_handle_advposition(int handle, int position) // 80033D58
+{
+ sequence_status *psq_stat;
+ track_status *ptmp;
+ char ppos[12];
+
+ int li, lj;
+ char *lpdest;
+
+ int _handle, _position;
+
+ _handle = handle;
+ _position = position;
+
+ if (!Is_Module_Loaded())
+ return 0;
+
+ wess_disable();
+
+ psq_stat = gethandleseq(_handle);
+
+ if (psq_stat)
+ {
+ li = psq_stat->tracks_active;
+ lj = pm_stat->max_trks_perseq;
+
+ /* *lpdest refers to an active track if not 0xFF */
+ lpdest = psq_stat->ptrk_indxs;
+ while (lj--)
+ {
+ if (*lpdest != 0xFF)
+ {
+ ptmp = (pm_stat->ptrkstattbl + (*lpdest));
+ CmdFuncArr[ptmp->patchtype][TrkMute](ptmp);
+ wess_track_gotoposition(ptmp, ptmp->totppi + _position, ppos);
+ if (!--li) break;
+ }
+ lpdest++;
+ }
+ }
+
+ wess_enable();
+ return wess_handle_getposition(_handle);
+}
+
+int wess_handle_setposition(int handle, int position) // 80033EB8
+{
+ sequence_status *psq_stat;
+ track_status *ptmp;
+ char ppos[12];
+
+ int li, lj;
+ char *lpdest;
+
+ int _handle, _position;
+
+ _handle = handle;
+ _position = position;
+
+ if (!Is_Module_Loaded())
+ return 0;
+
+ wess_disable();
+
+ psq_stat = gethandleseq(_handle);
+
+ if (psq_stat)
+ {
+ li = psq_stat->tracks_active;
+ lj = pm_stat->max_trks_perseq;
+
+ /* *lpdest refers to an active track if not 0xFF */
+ lpdest = psq_stat->ptrk_indxs;
+ while (lj--)
+ {
+ if (*lpdest != 0xFF)
+ {
+ ptmp = (pm_stat->ptrkstattbl + (*lpdest));
+ CmdFuncArr[ptmp->patchtype][TrkMute](ptmp);
+ wess_track_setposition(ptmp, _position, ppos);
+ if (!--li) break;
+ }
+ lpdest++;
+ }
+ }
+
+ wess_enable();
+ return wess_handle_getposition(_handle);
+}
+
+int wess_handle_getposition(int handle) // 80034010
+{
+ sequence_status *psq_stat;
+ track_status *ptmp;
+
+ int li, lj;
+ char *lpdest;
+ int position;
+
+ int _handle;
+
+ _handle = handle;
+
+ position = 0;
+
+ if (!Is_Module_Loaded())
+ return 0;
+
+ wess_disable();
+
+ psq_stat = gethandleseq(_handle);
+
+ if (psq_stat)
+ {
+ li = psq_stat->tracks_active;
+ lj = pm_stat->max_trks_perseq;
+
+ /* *lpdest refers to an active track if not 0xFF */
+ lpdest = psq_stat->ptrk_indxs;
+ while (lj--)
+ {
+ if (*lpdest != 0xFF)
+ {
+ ptmp = (pm_stat->ptrkstattbl + (*lpdest));
+ if(position < ptmp->totppi)
+ position = ptmp->totppi;
+
+ if (!--li) break;
+ }
+ lpdest++;
+ }
+ }
+
+ wess_enable();
+
+ return position;
+}
+
+void patch_chg_action(track_status *ptmp, int patch_num) // 800340E0
+{
+ ptmp->ppos[0] = PatchChg;
+ ptmp->ppos[1] = patch_num;
+ ptmp->ppos[2] = patch_num >> 8;
+ CmdFuncArr[ptmp->patchtype][PatchChg](ptmp);
+}
+
+void pitch_mod_action(track_status *ptmp, int pitch_cntr) // 80034144
+{
+ ptmp->ppos[0] = PitchMod;
+ ptmp->ppos[1] = pitch_cntr;
+ ptmp->ppos[2] = pitch_cntr >> 8;
+ CmdFuncArr[ptmp->patchtype][PitchMod](ptmp);
+}
+
+void volume_mod_action(track_status *ptmp, int volume_cntr) // 800341A8
+{
+ ptmp->ppos[0] = VolumeMod;
+ ptmp->ppos[1] = volume_cntr;
+ CmdFuncArr[ptmp->patchtype][VolumeMod](ptmp);
+}
+
+void pan_mod_action(track_status *ptmp, int pan_cntr) // 80034200
+{
+ ptmp->ppos[0] = PanMod;
+ ptmp->ppos[1] = pan_cntr;
+ CmdFuncArr[ptmp->patchtype][PanMod](ptmp);
+}
+
+void wess_track_parm_mod(track_status *ptmp, int value, WessAction funcion) // 80034258
+{
+ char *ppos;
+
+ //save
+ ppos = ptmp->ppos;
+ ptmp->ppos = scratch_area;
+ funcion(ptmp, value);
+ //restore
+ ptmp->ppos = ppos;
+}
+
+void tracksetspecial(track_status *ptmp, TriggerPlayAttr *attr) // 8003429C
+{
+ int mask;
+
+ ptmp->flags &= ~(TRK_TIMED | TRK_LOOPED);
+
+ if (attr != NULL)
+ {
+ mask = attr->mask;
+ if (mask)
+ {
+ if (mask & TRIGGER_VOLUME)
+ {
+ ptmp->volume_cntrl = attr->volume;
+ wess_track_parm_mod(ptmp, attr->volume, volume_mod_action);
+
+ mask &= ~TRIGGER_VOLUME;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_PAN)
+ {
+ ptmp->pan_cntrl = attr->pan;
+ wess_track_parm_mod(ptmp, attr->pan, pan_mod_action);
+
+ mask &= ~TRIGGER_PAN;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_PATCH)
+ {
+ ptmp->patchnum = attr->patch;
+ wess_track_parm_mod(ptmp, attr->patch, patch_chg_action);
+
+ mask &= ~TRIGGER_PATCH;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_PITCH)
+ {
+ ptmp->pitch_cntrl = attr->pitch;
+ wess_track_parm_mod(ptmp, attr->pitch, pitch_mod_action);
+
+ mask &= ~TRIGGER_PITCH;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_MUTEMODE)
+ {
+ if (ptmp->mutemask & (1 << attr->mutemode))
+ {
+ ptmp->flags |= TRK_MUTE;
+ CmdFuncArr[ptmp->patchtype][TrkMute](ptmp);
+ }
+ ptmp->flags &= ~TRK_MUTE;
+
+ mask &= ~TRIGGER_MUTEMODE;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_TEMPO)
+ {
+ ptmp->qpm = attr->tempo;
+ ptmp->ppi = CalcPartsPerInt(GetIntsPerSec(), ptmp->ppq, ptmp->qpm);
+
+ mask &= ~TRIGGER_TEMPO;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_TIMED)
+ {
+ ptmp->endppi = ptmp->totppi + attr->timeppq;
+ ptmp->flags |= TRK_TIMED;
+
+ mask &= ~TRIGGER_TIMED;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_LOOPED)
+ {
+ ptmp->flags |= TRK_LOOPED;
+ }
+ }
+ }
+}
+
+void trackgetspecial(track_status *ptmp, TriggerPlayAttr *attr) // 80034508
+{
+ int mask;
+
+ mask = attr->mask;
+
+ if (mask)
+ {
+ if (mask & TRIGGER_VOLUME)
+ {
+ attr->volume = ptmp->volume_cntrl;
+ mask &= ~TRIGGER_VOLUME;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_PAN)
+ {
+ attr->pan = ptmp->pan_cntrl;
+ mask &= ~TRIGGER_PAN;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_PATCH)
+ {
+ attr->patch = ptmp->patchnum;
+ mask &= ~TRIGGER_PATCH;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_PITCH)
+ {
+ attr->pitch = ptmp->pitch_cntrl;
+ mask &= ~TRIGGER_PITCH;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_MUTEMODE)
+ {
+ attr->mutemode = ptmp->mutemask;
+ mask &= ~TRIGGER_MUTEMODE;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_TEMPO)
+ {
+ attr->tempo = ptmp->qpm;
+ mask &= ~TRIGGER_TEMPO;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_TIMED)
+ {
+ if (!(ptmp->flags & TRK_TIMED))
+ attr->mask &= ~TRIGGER_TIMED;
+ else
+ attr->timeppq = ptmp->endppi - ptmp->totppi;
+
+ mask &= ~TRIGGER_TIMED;
+ if (!(mask))
+ return;
+ }
+
+ if (mask & TRIGGER_LOOPED)
+ {
+ if (!(ptmp->flags & TRK_LOOPED))
+ attr->mask &= ~TRIGGER_LOOPED;
+ }
+ }
+}
+#endif // 0
diff --git a/Doom 64/wessseq.c b/Doom 64/wessseq.c
@@ -0,0 +1,900 @@
+// Reconstruido por Erick Vasquez Garcia 16/05/2019 [GEC]
+// Update_1 20/10/2019 [GEC]
+// Update_2 31/01/2020 [GEC]
+
+#include "wessseq.h"
+
+#include "graph.h"
+#ifndef NOUSEWESSCODE
+extern void (**CmdFuncArr[10])(track_status *);
+extern void(*DrvFunctions[36])(track_status *);
+
+char *Read_Vlq(char *pstart, void *deltatime);
+char *Write_Vlq(char *dest, unsigned int value);
+int Len_Vlq(unsigned int value);
+
+void Eng_DriverInit (track_status *ptk_stat);//(master_status_structure *pm_stat);
+void Eng_DriverExit (track_status *ptk_stat);
+void Eng_DriverEntry1 (track_status *ptk_stat);
+void Eng_DriverEntry2 (track_status *ptk_stat);
+void Eng_DriverEntry3 (track_status *ptk_stat);
+void Eng_TrkOff (track_status *ptk_stat);
+void Eng_TrkMute (track_status *ptk_stat);
+void Eng_PatchChg (track_status *ptk_stat);
+void Eng_PatchMod (track_status *ptk_stat);
+void Eng_PitchMod (track_status *ptk_stat);
+void Eng_ZeroMod (track_status *ptk_stat);
+void Eng_ModuMod (track_status *ptk_stat);
+void Eng_VolumeMod (track_status *ptk_stat);
+void Eng_PanMod (track_status *ptk_stat);
+void Eng_PedalMod (track_status *ptk_stat);
+void Eng_ReverbMod (track_status *ptk_stat);
+void Eng_ChorusMod (track_status *ptk_stat);
+void Eng_NoteOn (track_status *ptk_stat);
+void Eng_NoteOff (track_status *ptk_stat);
+void Eng_StatusMark (track_status *ptk_stat);
+void Eng_GateJump (track_status *ptk_stat);
+void Eng_IterJump (track_status *ptk_stat);
+void Eng_ResetGates (track_status *ptk_stat);
+void Eng_ResetIters (track_status *ptk_stat);
+void Eng_WriteIterBox (track_status *ptk_stat);
+void Eng_SeqTempo (track_status *ptk_stat);
+void Eng_SeqGosub (track_status *ptk_stat);
+void Eng_SeqJump (track_status *ptk_stat);
+void Eng_SeqRet (track_status *ptk_stat);
+void Eng_SeqEnd (track_status *ptk_stat);
+void Eng_TrkTempo (track_status *ptk_stat);
+void Eng_TrkGosub (track_status *ptk_stat);
+void Eng_TrkJump (track_status *ptk_stat);
+void Eng_TrkRet (track_status *ptk_stat);
+void Eng_TrkEnd (track_status *ptk_stat);
+void Eng_NullEvent (track_status *ptk_stat);
+
+void(*DrvFunctions[36])(track_status *) =
+{
+ Eng_DriverInit,
+ Eng_DriverExit,
+ Eng_DriverEntry1,
+ Eng_DriverEntry2,
+ Eng_DriverEntry3,
+ Eng_TrkOff,
+ Eng_TrkMute,
+ Eng_PatchChg,
+ Eng_PatchMod,
+ Eng_PitchMod,
+ Eng_ZeroMod,
+ Eng_ModuMod,
+ Eng_VolumeMod,
+ Eng_PanMod,
+ Eng_PedalMod,
+ Eng_ReverbMod,
+ Eng_ChorusMod,
+ Eng_NoteOn,
+ Eng_NoteOff,
+ Eng_StatusMark, //0x13
+ Eng_GateJump, //0x14
+ Eng_IterJump, //0x15
+ Eng_ResetGates, //0x16
+ Eng_ResetIters, //0x17
+ Eng_WriteIterBox, //0x18
+ Eng_SeqTempo, //0x19
+ Eng_SeqGosub, //0x1A
+ Eng_SeqJump, //0x1B
+ Eng_SeqRet, //0x1C
+ //SeqFunctions ??
+ Eng_SeqEnd, //0x1D
+ Eng_TrkTempo, //0x1E
+ Eng_TrkGosub, //0x1F
+ Eng_TrkJump, //0x20
+ Eng_TrkRet, //0x21
+ Eng_TrkEnd, //0x22
+ Eng_NullEvent //0x23
+};
+
+unsigned char CmdLength[36] = { // 8005D9F0
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+0x02, 0x03, 0x02, 0x04, 0x05, 0x05, 0x02, 0x02,
+0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03,
+0x03, 0x01, 0x01, 0x01
+};
+
+unsigned char CmdSort[44] = { // 8005DA14
+0x00, 0x01, 0x02, 0x03, 0x04, 0x07, 0x06, 0x16,
+0x17, 0x18, 0x15, 0x1A, 0x1E, 0x19, 0x1B, 0x1D,
+0x1C, 0x1F, 0x05, 0x0F, 0x08, 0x09, 0x12, 0x11,
+0x10, 0x14, 0x0D, 0x0B, 0x22, 0x23, 0x13, 0x0C,
+0x0A, 0x20, 0x21, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00
+};
+
+//-----------------------------------------------------------
+// Vlq System
+//-----------------------------------------------------------
+
+//extern unsigned int data01; //L8007F024
+//extern unsigned char data02; //L8007F028
+
+char *Read_Vlq(char *pstart, void *deltatime)//L80035F80()
+{
+ static int v;//800B6630
+ static char c;//800B6634
+
+ v = *pstart++;
+ if (v & 0x80)
+ {
+ v &= 0x7f;
+ do
+ {
+ c = *pstart++;
+ v = (c & 0x7f) + (v << 7);
+ } while (c & 0x80);
+ }
+ *(int*)deltatime = v;
+
+ return pstart;
+}
+
+char *Write_Vlq(char *dest, unsigned int value)//L8004744C()
+{
+ char data[10];
+ char *ptr;
+
+ data[0] = (value & 0x7f);
+ ptr = (char*)&data + 1;
+
+ value >>= 7;
+ if (value)
+ {
+ do
+ {
+ *ptr++ = ((value & 0x7f) | 0x80);
+ value >>= 7;
+ } while (value);
+ }
+
+ do
+ {
+ ptr--;
+ *dest++ = *ptr;
+ } while (*ptr & 0x80);
+
+ return dest;
+}
+
+int Len_Vlq(unsigned int value)//L800474AC()
+{
+ char buff[16];
+ char data[10];
+ char *ptr;
+ char *dest, *start;
+
+ dest = start = (char*)&buff;
+
+ data[0] = (value & 0x7f);
+ ptr = (char*)&data + 1;
+
+ value >>= 7;
+ if (value)
+ {
+ do
+ {
+ *ptr++ = ((value & 0x7f) | 0x80);
+ value >>= 7;
+ } while (value);
+ }
+
+ do
+ {
+ ptr--;
+ *dest++ = *ptr;
+ } while (*ptr & 0x80);
+
+ return (int)(dest - start);
+}
+//-----------------------------------------------------------
+// Engine System
+//-----------------------------------------------------------
+
+static unsigned char ntwa = 0; //8005DAD4
+static track_status *ptsbase = 0; //8005DAD8
+static sequence_status *pssbase = 0; //8005DADC
+static master_status_structure *pmsbase = 0; //8005DAE0
+
+void Eng_DriverInit (track_status *ptk_stat) // 800360C4
+{
+ master_status_structure *pm_stat;
+
+ pm_stat = (master_status_structure*)ptk_stat;
+
+ //PRINTF_D2(WHITE,0,10,"Eng_DriverInit");
+ ntwa = wess_driver_tracks;
+ ptsbase = pm_stat->ptrkstattbl;
+ pssbase = pm_stat->pseqstattbl;
+ pmsbase = pm_stat;
+
+ //PRINTF_D(WHITE,"ntwa %d\n", ntwa);
+ //PRINTF_D(WHITE,"ptsbase %x\n", (int)&ptsbase);
+ //PRINTF_D(WHITE,"pssbase %x\n", (int)&pssbase);
+ //PRINTF_D(WHITE,"pmsbase %x\n", (int)&pmsbase);
+}
+
+void Eng_DriverExit (track_status *ptk_stat) // 800360FC
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_DriverExit");
+}
+
+void Eng_DriverEntry1 (track_status *ptk_stat) // 80036104
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_DriverEntry1");
+}
+
+void Eng_DriverEntry2 (track_status *ptk_stat) // 8003610C
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_DriverEntry2");
+}
+
+void Eng_DriverEntry3 (track_status *ptk_stat) // 80036114
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_DriverEntry3");
+}
+
+void Eng_TrkOff (track_status *ptk_stat) // 8003611C
+{
+ static sequence_status *lpseq; //800B6638
+ static char *lpdest;//800B663C
+ static unsigned long lj; //800B6640
+
+ //PRINTF_D2(WHITE,0,10,"Eng_TrkOff");
+
+ lpseq = (pmsbase->pseqstattbl + ptk_stat->seq_owner);
+
+ if (!(ptk_stat->flags & TRK_STOPPED))
+ {
+ ptk_stat->flags |= TRK_STOPPED;
+
+ if (!--lpseq->tracks_playing)
+ {
+ lpseq->playmode = SEQ_STATE_STOPPED;
+ }
+ }
+
+ if (!(ptk_stat->flags & TRK_HANDLED))
+ {
+ lj = pmsbase->max_trks_perseq;
+ lpdest = lpseq->ptrk_indxs;
+
+ while (lj--)
+ {
+ if (ptk_stat->refindx == *lpdest)
+ {
+ *lpdest++ = 0xff;
+ break;
+ }
+ lpdest++;
+ }
+
+ ptk_stat->flags &= ~TRK_ACTIVE;
+ pmsbase->trks_active--;
+
+ if (!--lpseq->tracks_active)
+ {
+ lpseq->flags &= ~SEQ_ACTIVE;
+ pmsbase->seqs_active--;
+ }
+ }
+
+ ptk_stat->flags &= ~TRK_TIMED;
+}
+
+void Eng_TrkMute (track_status *ptk_stat) // 80036298
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_TrkMute");
+}
+
+void Eng_PatchChg (track_status *ptk_stat) // 800362A0
+{
+ static unsigned char thepatch;//800B6644
+
+ //PRINTF_D2(WHITE,0,10,"Eng_PatchChg");
+
+ thepatch = (*(ptk_stat->ppos + 1) | (*(ptk_stat->ppos + 2) << 8));
+ ptk_stat->patchnum = (unsigned short)thepatch;
+}
+
+
+void Eng_PatchMod (track_status *ptk_stat) // 800362C8
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_PatchMod");
+}
+
+void Eng_PitchMod (track_status *ptk_stat) // 800362D0
+{
+ static short thepitchmod;//800B6646
+
+ //PRINTF_D2(WHITE,0,10,"Eng_PitchMod");
+
+ thepitchmod = (*(ptk_stat->ppos + 1) | (*(ptk_stat->ppos + 2) << 8));
+ ptk_stat->pitch_cntrl = thepitchmod;
+}
+
+void Eng_ZeroMod (track_status *ptk_stat) // 800362F4
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_ZeroMod");
+}
+
+void Eng_ModuMod (track_status *ptk_stat) // 800362FC
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_ModuMod");
+}
+
+void Eng_VolumeMod (track_status *ptk_stat) // 80036304
+{
+ static unsigned char thevolume; //800B6648
+
+ //PRINTF_D2(WHITE,0,10,"Eng_VolumeMod");
+
+ thevolume = *(ptk_stat->ppos + 1);
+ ptk_stat->volume_cntrl = thevolume;
+}
+
+void Eng_PanMod (track_status *ptk_stat) // 80036320
+{
+ static unsigned char thepan; //0x800B6649
+
+ //PRINTF_D2(WHITE,0,10,"Eng_PanMod");
+ thepan = *(ptk_stat->ppos + 1);
+ ptk_stat->pan_cntrl = thepan;
+}
+
+void Eng_PedalMod (track_status *ptk_stat) // 8003633C
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_PedalMod");
+}
+
+void Eng_ReverbMod (track_status *ptk_stat) // 80036344
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_ReverbMod");
+}
+
+void Eng_ChorusMod (track_status *ptk_stat) // 8003634C
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_ChorusMod");
+}
+
+void Eng_NoteOn (track_status *ptk_stat) // 80036354
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_NoteOn");
+}
+
+void Eng_NoteOff (track_status *ptk_stat) // 8003635C
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_NoteOff");
+}
+
+void Eng_StatusMark (track_status *ptk_stat) // 80036364
+{
+ static char si, sn; //800B664A, 800B664B
+ static callback_status *cbs; //800B664C
+
+ //PRINTF_D2(WHITE,0,10,"Eng_StatusMark");
+
+ sn = pmsbase->callbacks_active;
+ if (sn)
+ {
+ cbs = pmsbase->pcalltable;
+ si = wess_driver_callbacks;
+ if(wess_driver_callbacks)
+ {
+ while (si--)
+ {
+ if (cbs->active)
+ {
+ if (cbs->type == *(ptk_stat->ppos + 1))
+ {
+ cbs->curval = (*(ptk_stat->ppos + 2) | (*(ptk_stat->ppos + 3) << 8));
+ cbs->callfunc(cbs->type, cbs->curval);
+ break;
+ }
+
+ if (!--sn) break;
+ }
+
+ cbs++;
+ }
+ }
+ }
+}
+
+void Eng_GateJump (track_status *ptk_stat) // 80036488
+{
+ static short lindex; //800B6650
+ static char *laboff; //800B6654
+ static char *pgate; //800B6658
+
+ //PRINTF_D2(WHITE,0,10,"Eng_GateJump");
+ pgate = (pssbase + ptk_stat->seq_owner)->pgates + *(ptk_stat->ppos + 1);
+
+ if (*pgate != 0)
+ {
+ if (*pgate == 0xff)
+ {
+ *pgate = *(ptk_stat->ppos + 2);
+ }
+
+ lindex = (*(ptk_stat->ppos + 3) | (*(ptk_stat->ppos + 4) << 8));
+
+ if (lindex >= 0)
+ {
+ if (lindex < ptk_stat->labellist_count)
+ {
+ laboff = ptk_stat->pstart + *(ptk_stat->plabellist + lindex);
+ ptk_stat->ppos = laboff;
+ ptk_stat->deltatime = 0;
+ ptk_stat->flags |= TRK_SKIP;
+ }
+ }
+ }
+}
+
+void Eng_IterJump (track_status *ptk_stat) // 80036568
+{
+ static short lindex; //800B665C
+ static char *laboff; //800B6660
+ static char *piter; //800B6664
+
+ //PRINTF_D2(WHITE,0,10,"Eng_IterJump");
+ piter = (pssbase + ptk_stat->seq_owner)->piters + *(ptk_stat->ppos + 1);
+
+ if (*piter != 0)
+ {
+ if (*piter == 0xFF)
+ {
+ *piter = *(ptk_stat->ppos + 2);
+ }
+ else
+ {
+ *piter = *piter + 0xFF;
+ }
+
+ lindex = (*(ptk_stat->ppos + 3) | (*(ptk_stat->ppos + 4) << 8));
+
+ if (lindex >= 0)
+ {
+ if (lindex < ptk_stat->labellist_count)
+ {
+ laboff = ptk_stat->pstart + *(ptk_stat->plabellist + lindex);
+ ptk_stat->ppos = laboff;
+ ptk_stat->deltatime = 0;
+ ptk_stat->flags |= TRK_SKIP;
+ }
+ }
+ }
+}
+
+void Eng_ResetGates (track_status *ptk_stat) // 80036654
+{
+ static unsigned char gi; //800B6668
+ static char *pgate; //800B666C
+
+ //PRINTF_D2(WHITE,0,10,"Eng_ResetGates");
+ if (*(ptk_stat->ppos + 1) == 0xff)
+ {
+ gi = wess_driver_gates;
+ pgate = (pssbase + ptk_stat->seq_owner)->pgates;
+
+ while (gi--)
+ {
+ *pgate++ = 0xFF;
+ }
+ }
+ else
+ {
+ pgate = (pssbase + ptk_stat->seq_owner)->pgates + *(ptk_stat->ppos + 1);
+ *pgate = 0xff;
+ }
+}
+
+void Eng_ResetIters (track_status *ptk_stat) // 80036720
+{
+ static unsigned char ii; //800B6670
+ static char *piter; //800B6674
+
+ //PRINTF_D2(WHITE,0,10,"Eng_ResetIters");
+ if (*(ptk_stat->ppos + 1) == 0xff)
+ {
+ ii = wess_driver_iters;
+ piter = (pssbase + ptk_stat->seq_owner)->piters;
+
+ while (ii--)
+ {
+ *piter++ = 0xFF;
+ }
+ }
+ else
+ {
+ piter = (pssbase + ptk_stat->seq_owner)->piters + *(ptk_stat->ppos + 1);
+ *piter = 0xff;
+ }
+}
+
+void Eng_WriteIterBox (track_status *ptk_stat) // 800367EC
+{
+ static char *piter;//800B6678
+
+ //PRINTF_D2(WHITE,0,10,"Eng_WriteIterBox");
+ piter = (pssbase + ptk_stat->seq_owner)->piters + *(ptk_stat->ppos + 1);
+ *piter = *(ptk_stat->ppos + 2);
+}
+
+void Eng_SeqTempo (track_status *ptk_stat) // 8003682C
+{
+ static unsigned short ntracks; //800B667C
+ static unsigned char nactive; //800B667E
+ static unsigned char *ptindxs; //800B6680
+ static track_status *ptstemp; //800B6684
+ static sequence_status *psstemp; //800B6688
+
+ //PRINTF_D2(WHITE,0,10,"Eng_SeqTempo");
+
+ psstemp = (pssbase + ptk_stat->seq_owner);
+ ptindxs = (unsigned char *)psstemp->ptrk_indxs;
+ nactive = psstemp->tracks_active;
+ ntracks = (pmsbase->pmod_info->pseq_info + psstemp->seq_num)->seq_hdr.tracks;
+
+ while (ntracks--)
+ {
+ if (*ptindxs != 0xff)
+ {
+ ptstemp = (ptsbase + (*ptindxs));
+ ptstemp->qpm = (unsigned short)(*(ptk_stat->ppos + 1) | (*(ptk_stat->ppos + 2) << 8));
+ ptstemp->ppi = CalcPartsPerInt(GetIntsPerSec(), ptstemp->ppq, ptstemp->qpm);
+
+ if (!--nactive) break;
+ }
+ ptindxs++;
+ }
+}
+
+void Eng_SeqGosub (track_status *ptk_stat) // 800369C8
+{
+ static short lindex; //800B668C
+ static unsigned short ntracks; //800B668E
+ static char *laboff; //800B6690
+ static unsigned char nactive; //800B6694
+ static unsigned char *ptindxs; //800B6698
+ static track_status *ptstemp; //800B669C
+ static sequence_status *psstemp; //800B66A0
+
+ //PRINTF_D2(WHITE,0,10,"Eng_SeqGosub");
+
+ lindex = (*(ptk_stat->ppos + 1) | (*(ptk_stat->ppos + 2) << 8));
+
+ if ((lindex >= 0) && (lindex < ptk_stat->labellist_count))
+ {
+ psstemp = (pssbase + ptk_stat->seq_owner);
+ ptindxs = (unsigned char *)psstemp->ptrk_indxs;
+ nactive = psstemp->tracks_active;
+ ntracks = (pmsbase->pmod_info->pseq_info + psstemp->seq_num)->seq_hdr.tracks;
+
+ while (ntracks--)
+ {
+ if (*ptindxs != 0xFF)
+ {
+ ptstemp = (ptsbase + (*ptindxs));
+
+ ptstemp->psp = (unsigned char*)ptstemp->ppos + CmdLength[26];
+ ptstemp->psp++;
+ laboff = ptstemp->pstart + *(ptstemp->plabellist + lindex);
+ ptstemp->ppos = laboff;
+ ptstemp->deltatime = 0;
+ ptstemp->flags |= TRK_SKIP;
+
+ if (!--nactive) break;
+ }
+ ptindxs++;
+ }
+ }
+}
+
+void Eng_SeqJump (track_status *ptk_stat) // 80036B80
+{
+ static short lindex; //800B66A4
+ static unsigned short ntracks; //800B66A6
+ static char *laboff; //800B66A8
+ static unsigned char nactive; //800B66AC
+ static unsigned char *ptindxs; //800B66B0
+ static track_status *ptstemp; //800B66B4
+ static sequence_status *psstemp; //800B66B8
+
+ //PRINTF_D2(WHITE,0,10,"Eng_SeqJump");
+
+ lindex = (*(ptk_stat->ppos + 1) | (*(ptk_stat->ppos + 2) << 8));
+
+ if ((lindex >= 0) && (lindex < ptk_stat->labellist_count))
+ {
+ psstemp = (pssbase + ptk_stat->seq_owner);
+ ptindxs = (unsigned char *)psstemp->ptrk_indxs;
+ nactive = psstemp->tracks_active;
+ ntracks = (pmsbase->pmod_info->pseq_info + psstemp->seq_num)->seq_hdr.tracks;
+
+ while (ntracks--)
+ {
+ if (*ptindxs != 0xFF)
+ {
+ ptstemp = (ptsbase + (*ptindxs));
+ laboff = ptstemp->pstart + *(ptstemp->plabellist + lindex);
+ ptstemp->ppos = laboff;
+ ptstemp->deltatime = 0;
+ ptstemp->flags |= TRK_SKIP;
+
+ if (!--nactive) break;
+ }
+ ptindxs++;
+ }
+ }
+}
+
+void Eng_SeqRet (track_status *ptk_stat) // 80036D10
+{
+ static unsigned short ntracks; //800B66BC
+ static unsigned char nactive; //800B66BE
+ static unsigned char *ptindxs; //800B66C0
+ static track_status *ptstemp; //800B66C4
+ static sequence_status *psstemp; //800B66C8
+
+ //PRINTF_D2(WHITE,0,10,"Eng_SeqRet");
+
+ psstemp = (pssbase + ptk_stat->seq_owner);
+ ptindxs = (unsigned char *)psstemp->ptrk_indxs;
+ nactive = psstemp->tracks_active;
+ ntracks = (pmsbase->pmod_info->pseq_info + psstemp->seq_num)->seq_hdr.tracks;
+
+ while (ntracks--)
+ {
+ if (*ptindxs != 0xFF)
+ {
+ ptstemp = (ptsbase + (*ptindxs));
+ ptstemp->psp--;
+ ptstemp->deltatime = 0;
+ ptstemp->flags |= TRK_SKIP;
+ ptstemp->ppos = (unsigned char*)ptstemp->psp;
+
+ if (!--nactive) break;
+ }
+ ptindxs++;
+ }
+}
+
+void Eng_SeqEnd (track_status *ptk_stat) // 80036E48
+{
+ static sequence_status *lpseq; //800B66CC
+ static track_status *ptmp; //800B66D0
+ static unsigned char *lpdest; //800B66D4
+ static unsigned char li; //800B66D8
+ static unsigned long lj; //800B66DC
+
+ //PRINTF_D2(WHITE,0,10,"Eng_SeqEnd");
+
+ if (ptk_stat->flags & TRK_HANDLED)
+ {
+ lpseq = (pmsbase->pseqstattbl + ptk_stat->seq_owner);
+ lpdest = (unsigned char *)lpseq->ptrk_indxs;
+ li = lpseq->tracks_active;
+ lj = pmsbase->max_trks_perseq;
+
+ while (lj--)
+ {
+ if (*lpdest != 0xFF)
+ {
+ ptmp = (ptsbase + *lpdest);
+ CmdFuncArr[ptmp->patchtype][TrkOff]((track_status *)ptmp);
+
+ if (!--li) break;
+ }
+
+ lpdest++;
+ }
+
+ ptk_stat->flags |= TRK_SKIP;
+ }
+ else
+ {
+ lpseq = (pmsbase->pseqstattbl + ptk_stat->seq_owner);
+ lpdest = (unsigned char *)lpseq->ptrk_indxs;
+ li = lpseq->tracks_active;
+ lj = pmsbase->max_trks_perseq;
+
+ while (lj--)
+ {
+ if (*lpdest != 0xFF)
+ {
+ ptmp = (ptsbase + *lpdest);
+ CmdFuncArr[ptmp->patchtype][TrkOff]((track_status *)ptmp);
+
+ if (!--li) break;
+ }
+
+ lpdest++;
+ }
+ }
+}
+
+void Eng_TrkTempo (track_status *ptk_stat) // 800370D8
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_TrkTempo");
+ ptk_stat->qpm = *(ptk_stat->ppos + 1) | (*(ptk_stat->ppos + 2) << 8);
+ ptk_stat->ppi = CalcPartsPerInt(GetIntsPerSec(), ptk_stat->ppq, ptk_stat->qpm);
+}
+
+void Eng_TrkGosub (track_status *ptk_stat) // 8003713C
+{
+ unsigned int position;
+
+ //PRINTF_D2(WHITE,0,10,"Eng_TrkGosub");
+
+ position = (unsigned int)(*(ptk_stat->ppos + 1) | (*(ptk_stat->ppos + 2) << 8));
+ if ((position >= 0) && (position < ptk_stat->labellist_count))
+ {
+ ptk_stat->psp = (unsigned char*)ptk_stat->ppos + CmdLength[26];
+ ptk_stat->psp++;
+ ptk_stat->ppos = ptk_stat->pstart + *(ptk_stat->plabellist + position);
+ ptk_stat->deltatime = 0;
+ ptk_stat->flags |= TRK_SKIP;
+ }
+}
+
+void Eng_TrkJump (track_status *ptk_stat) // 800371C4
+{
+ unsigned int position;
+
+ //PRINTF_D2(WHITE,0,10,"Eng_TrkJump");
+
+ position = (unsigned int)(*(ptk_stat->ppos + 1) | (*(ptk_stat->ppos + 2) << 8));
+ if ((position >= 0) && (position < ptk_stat->labellist_count))
+ {
+ ptk_stat->ppos = ptk_stat->pstart + *(ptk_stat->plabellist + position);
+ ptk_stat->deltatime = 0;
+ ptk_stat->flags |= TRK_SKIP;
+ }
+}
+
+void Eng_TrkRet (track_status *ptk_stat) // 80037230
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_TrkRet");
+ ptk_stat->psp--;
+ ptk_stat->ppos = (unsigned char*)ptk_stat->psp;
+ ptk_stat->ppos = Read_Vlq(ptk_stat->ppos, &ptk_stat->deltatime);
+ ptk_stat->deltatime = 0;
+ ptk_stat->flags |= TRK_SKIP;
+}
+
+void Eng_TrkEnd (track_status *ptk_stat) // 8003728C
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_TrkEnd");
+
+ if (ptk_stat->flags & TRK_HANDLED)
+ {
+ if ((ptk_stat->flags & TRK_LOOPED) && (ptk_stat->totppi > 15))
+ {
+ ptk_stat->flags |= TRK_SKIP;
+ ptk_stat->ppos = ptk_stat->pstart;
+ ptk_stat->ppos = Read_Vlq(ptk_stat->pstart, &ptk_stat->deltatime);
+ }
+ else
+ {
+ CmdFuncArr[ptk_stat->patchtype][TrkOff](ptk_stat);
+ ptk_stat->flags |= TRK_SKIP;
+ }
+ }
+ else
+ {
+ if ((ptk_stat->flags & TRK_LOOPED) && (ptk_stat->totppi > 15))
+ {
+ ptk_stat->flags |= TRK_SKIP;
+ ptk_stat->ppos = ptk_stat->pstart;
+ ptk_stat->ppos = Read_Vlq(ptk_stat->pstart, &ptk_stat->deltatime);
+ }
+ else
+ {
+ CmdFuncArr[ptk_stat->patchtype][TrkOff](ptk_stat);
+ }
+ }
+}
+
+void Eng_NullEvent (track_status *ptk_stat) // 800373A4
+{
+ //PRINTF_D2(WHITE,0,10,"Eng_NullEvent");
+}
+
+void SeqEngine(void) // 800373AC
+{
+ static track_status *pts; //800B66E0
+ static unsigned char na; //800B66E4
+ static unsigned int ni; //800B66E8
+ static char *nn; //800B66EC
+
+ track_status *ptrkstattbl;
+ //PRINTF_D2(WHITE,0,9,"SeqEngine %d\n",SeqOn);
+
+ na = pmsbase->trks_active;
+ //PRINTF_D2(WHITE,0,4,"trks_active %d",na);
+ //PRINTF_D2(WHITE,0,5,"ptsbase->patchtype %d",ptsbase->patchtype);
+
+ if (na)
+ {
+ //printf("trks_active %d\n",na);
+ pts = ptsbase;
+ ni = ntwa;
+
+ while (ni--)
+ {
+ if ((pts->flags & TRK_ACTIVE))
+ {
+ if (!(pts->flags & TRK_STOPPED))
+ {
+ pts->starppi += pts->ppi;
+ pts->totppi += (pts->starppi >> 16);
+ pts->accppi += (pts->starppi >> 16);
+ pts->starppi &= 65535;
+ //printf("totppi %d\n",pts->totppi);
+ //printf("accppi %d\n",pts->accppi);
+ //printf("starppi %d\n",pts->starppi);
+
+ if (!(pts->flags & TRK_TIMED) || (pts->totppi < pts->endppi))
+ {
+ /*printf("totppi %d\n",pts->totppi);
+ printf("accppi %d\n",pts->accppi);
+ printf("starppi %d\n",pts->starppi);
+ printf("deltatime %d\n",pts->deltatime);*/
+
+ while (pts->deltatime <= pts->accppi &&
+ ((pts->flags & (TRK_STOPPED | TRK_ACTIVE)) == TRK_ACTIVE))
+ {
+ pts->accppi -= pts->deltatime;
+ nn = (pts->ppos);
+
+ if (!(*nn < 7) && (*nn < 19))
+ {
+ CmdFuncArr[pts->patchtype][*nn]((track_status *)pts);
+
+ pts->ppos += CmdLength[*nn];
+ pts->ppos = Read_Vlq(pts->ppos, &pts->deltatime);
+ }
+ else if (!(*nn < 19) && (*nn < 36))
+ {
+ DrvFunctions[*nn]((track_status *)pts);
+
+ if ((pts->flags & (TRK_ACTIVE | TRK_SKIP)) == TRK_ACTIVE)
+ {
+ pts->ppos += CmdLength[*nn];
+ pts->ppos = Read_Vlq(pts->ppos, &pts->deltatime);
+ }
+ else
+ {
+ pts->flags &= ~TRK_SKIP;
+ }
+ }
+ else
+ {
+ Eng_SeqEnd((track_status *)pts);
+ }
+ }
+ }
+ else
+ {
+ CmdFuncArr[pts->patchtype][TrkOff]((track_status *)pts);
+ }
+ }
+
+ if (!--na) break;
+ }
+
+ pts++;
+ }
+ }
+
+ CmdFuncArr[ptsbase->patchtype][2](ptsbase);
+}
+
+#endif
diff --git a/Doom 64/wessshell.c b/Doom 64/wessshell.c
@@ -0,0 +1,27 @@
+/* ULTRA64 LIBRARIES */
+#include <ultra64.h>
+#include "ultratypes.h"
+#include <libaudio.h>
+
+#include "wessarc.h"
+#include "wessshell.h"
+#ifndef NOUSEWESSCODE
+ALPlayer wessnode; //800B4140
+ALPlayer *wessstate;//800B4154
+
+void SSP_SeqpNew(void) // 8002F100
+{
+ wessnode.next = NULL;
+ wessnode.handler = __wessVoiceHandler;
+ wessnode.callTime = 0;
+ wessnode.samplesLeft = 0;
+ wessnode.clientData = wessstate;
+ alSynAddPlayer(&alGlobals->drvr, &wessnode);
+}
+
+ALMicroTime __wessVoiceHandler(void *node) // 8002F154
+{
+ WessInterruptHandler();
+ return 8333; /* call back in 8.333 millisecond */
+}
+#endif // 0
diff --git a/Doom 64/wesstrak.c b/Doom 64/wesstrak.c
@@ -0,0 +1,312 @@
+
+/* ULTRA64 LIBRARIES */
+#include <ultra64.h>
+#include "ultratypes.h"
+#include <libaudio.h>
+
+/* WESS API INCLUDES */
+#include "wessapi.h" // audio stuff...
+#include "seqload.h"
+#include "soundhw.h"
+#include "wessarc.h"
+#include "wessseq.h"
+
+#include "funqueue.h"
+
+#include "wessedit.h"
+#include "wesstrak.h"
+#include "wesshand.h"
+
+#ifndef NOUSEWESSCODE
+
+/*
+PatchChg 7
+{
+ Tuning Program Change
+}
+
+PitchMod 9
+{
+ Pitch Bend Sensitivity
+}
+
+ZeroMod 11
+{
+ MIDI_Controller = 0 (Bank Select)
+}
+
+ModuMod 11
+{
+ MIDI_Controller = 1 (Modulation Wheel or Lever)
+}
+
+VolumeMod 12
+{
+ MIDI_Controller = 7 (Channel Volume(formerly Main Volume))
+}
+
+PanMod 13
+{
+ MIDI_Controller = 10 (Pan)
+}
+
+PedalMod 14
+{
+ MIDI_Controller = 64 (Damper Pedal on / off(Sustain))
+}
+
+ReverbMod 15
+{
+ MIDI_Controller = 91 (Effects 1 Depth->Reverb Send Level)
+}
+
+ChorusMod 16
+{
+ MIDI_Controller = 93 (Effects 3 Depth->Chorus Send Level)
+}
+*/
+
+extern char scratch_area[32];//800B41E0
+
+extern void patch_chg_action(track_status *ptmp, int patch_num); // 800340E0
+extern void pitch_mod_action(track_status *ptmp, int pitch_cntr); // 80034144
+extern void volume_mod_action(track_status *ptmp, int volume_cntr); // 800341A8
+extern void pan_mod_action(track_status *ptmp, int pan_cntr); // 80034200
+extern track_status *gethandletrk(int handle, int track); // 80032EE0
+
+void queue_wess_handle_noteon(int handle, int track, char keynum, char velnum);
+void wess_handle_parm_mod(int handle, int track, int value, WessAction function);
+void queue_wess_handle_parm_mod(int handle, int track, int value, WessAction function);
+
+void wess_handle_patchchg(int handle, int track, short patchnum) // 80034664
+{
+ wess_handle_parm_mod(handle, track, patchnum, patch_chg_action);
+}
+
+void wess_handle_noteon(int handle, int track, char keynum, char velnum) // 8003469C
+{
+ int _handle;
+ int _track;
+ char _keynum;
+ char _velnum;
+
+ _handle = handle;
+ _track = track;
+ _keynum = keynum;
+ _velnum = velnum;
+
+ wess_disable();
+ queue_the_function(QUEUE_HANDLE_NOTEON);
+ queue_the_data(&_handle, sizeof(int));
+ queue_the_data(&_track, sizeof(int));
+ queue_the_data(&_keynum, sizeof(char));
+ queue_the_data(&_velnum, sizeof(char));
+ wess_enable();
+}
+
+void run_queue_wess_handle_noteon(void) // 80034708
+{
+ int handle;
+ int track;
+ char keynum;
+ char velnum;
+
+ unqueue_the_data(&handle, sizeof(int));
+ unqueue_the_data(&track, sizeof(int));
+ unqueue_the_data(&keynum, sizeof(char));
+ unqueue_the_data(&velnum, sizeof(char));
+ queue_wess_handle_noteon(handle, track, keynum, velnum);
+}
+
+void queue_wess_handle_noteon(int handle, int track, char keynum, char velnum) // 80034768
+{
+ track_status *ptmp;
+ char *ppos;
+
+ int _handle;
+ int _track;
+ char _keynum;
+ char _velnum;
+
+ _handle = handle;
+ _track = track;
+ _keynum = keynum;
+ _velnum = velnum;
+
+ if (Is_Module_Loaded())
+ {
+ wess_disable();
+ ptmp = gethandletrk(_handle, _track);
+
+ if (ptmp)
+ {
+ //save
+ ppos = ptmp->ppos;
+
+ // set tmp buffer ppos
+ ptmp->ppos = scratch_area;
+ ptmp->ppos[0] = NoteOn;
+ ptmp->ppos[1] = _keynum;
+ ptmp->ppos[2] = _velnum;
+
+ CmdFuncArr[ptmp->patchtype][NoteOn](ptmp);
+
+ //restore
+ ptmp->ppos = ppos;
+ }
+
+ wess_enable();
+ }
+}
+
+void noteoff_action(track_status *ptmp, int keynum) // 8003483C
+{
+ ptmp->ppos[0]= NoteOff;
+ ptmp->ppos[1]= keynum;
+ CmdFuncArr[ptmp->patchtype][NoteOff](ptmp);
+}
+
+void wess_handle_noteoff(int handle, int track, char keynum) // 80034894
+{
+ wess_handle_parm_mod(handle, track, keynum, noteoff_action);
+}
+
+void wess_handle_pitchmod(int handle, int track, short pitch_cntrl) // 800348C0
+{
+ wess_handle_parm_mod(handle, track, pitch_cntrl, pitch_mod_action);
+}
+
+void zero_mod_action(track_status *ptmp, int value) // 800348F0
+{
+ ptmp->ppos[0] = ZeroMod;
+ ptmp->ppos[1] = value;
+ CmdFuncArr[ptmp->patchtype][ZeroMod](ptmp);
+}
+
+void wess_handle_zeromod(int handle, int track, char value) // 80034948
+{
+ wess_handle_parm_mod(handle, track, value, zero_mod_action);
+}
+
+void modu_mod_action(track_status *ptmp, int value) // 80034974
+{
+ ptmp->ppos[0]= ModuMod;
+ ptmp->ppos[1] = value;
+ CmdFuncArr[ptmp->patchtype][ModuMod](ptmp);
+}
+
+void wess_handle_modumod(int handle, int track, char value) // 800349CC
+{
+ wess_handle_parm_mod(handle, track, value, modu_mod_action);
+}
+
+void wess_handle_volumemod(int handle, int track, char volume_cntrl) // 800349F8
+{
+ wess_handle_parm_mod(handle, track, volume_cntrl, volume_mod_action);
+}
+
+void wess_handle_panmod(int handle, int track, char pan_cntr) // 80034A24
+{
+ wess_handle_parm_mod(handle, track, pan_cntr, pan_mod_action);
+}
+
+void pedal_mod_action(track_status *ptmp, int value) // 80034A50
+{
+ ptmp->ppos[0] = PedalMod;
+ ptmp->ppos[1] = value;
+ CmdFuncArr[ptmp->patchtype][PedalMod](ptmp);
+}
+
+void wess_handle_pedalmod(int handle, int track, char value) // 80034AA8
+{
+ wess_handle_parm_mod(handle, track, value, pedal_mod_action);
+}
+
+void reverb_mod_action(track_status *ptmp, int reverb) // 80034AD4
+{
+ ptmp->ppos[0] = ReverbMod;
+ ptmp->ppos[1] = reverb;
+ CmdFuncArr[ptmp->patchtype][ReverbMod](ptmp);
+}
+
+void wess_handle_reverbmod(int handle, int track, char reverb) // 80034B2C
+{
+ wess_handle_parm_mod(handle, track, reverb, reverb_mod_action);
+}
+
+void chorus_mod_action(track_status *ptmp, int chorus) // 80034B58
+{
+ ptmp->ppos[0] = ChorusMod;
+ ptmp->ppos[1] = chorus;
+ CmdFuncArr[ptmp->patchtype][ChorusMod](ptmp);
+}
+
+void wess_handle_chorusmod(int handle, int track, char chorus) // 80034BB0
+{
+ wess_handle_parm_mod(handle, track, chorus, chorus_mod_action);
+}
+
+void wess_handle_parm_mod(int handle, int track, int value, WessAction function) // 80034BDC
+{
+ int _handle;
+ int _track;
+ int _value;
+ WessAction _function;
+
+ _handle = handle;
+ _track = track;
+ _value = value;
+ _function = function;
+
+ wess_disable();
+ queue_the_function(QUEUE_HANDLE_PARM_MOD);
+ queue_the_data(&_handle, sizeof(int));
+ queue_the_data(&_track, sizeof(int));
+ queue_the_data(&_value, sizeof(int));
+ queue_the_data(&_function, sizeof(WessAction));
+ wess_enable();
+}
+
+void run_queue_wess_handle_parm_mod(void) // 80034C48
+{
+ int handle;
+ int track;
+ int value;
+ WessAction function;
+
+ unqueue_the_data(&handle, sizeof(int));
+ unqueue_the_data(&track, sizeof(int));
+ unqueue_the_data(&value, sizeof(int));
+ unqueue_the_data(&function, sizeof(WessAction));
+ queue_wess_handle_parm_mod(handle, track, value, function);
+}
+
+void queue_wess_handle_parm_mod(int handle, int track, int value, WessAction function) // 80034CA8
+{
+ track_status *ptmp;
+ char *ppos;
+
+ int _handle;
+ int _track;
+ int _value;
+ WessAction _function;
+
+ _handle = handle;
+ _track = track;
+ _value = value;
+ _function = function;
+
+ if (Is_Module_Loaded())
+ {
+ wess_disable();
+ ptmp = gethandletrk(_handle, _track);
+
+ if (ptmp)
+ {
+ wess_track_parm_mod(ptmp, _value, _function);
+ }
+
+ wess_enable();
+ }
+}
+#endif // 0
diff --git a/Doom 64/wesstwek.c b/Doom 64/wesstwek.c
@@ -0,0 +1,88 @@
+
+/* ULTRA64 LIBRARIES */
+#include <ultra64.h>
+#include "ultratypes.h"
+#include <libaudio.h>
+
+/* WESS API INCLUDES */
+#include "wessapi.h" // audio stuff...
+#include "seqload.h"
+#include "soundhw.h"
+#include "wessarc.h"
+#include "wessseq.h"
+
+#include "funqueue.h"
+
+#include "wessedit.h"
+#include "wesstrak.h"
+#include "wesshand.h"
+
+
+#include "graph.h"
+
+#ifndef NOUSEWESSCODE
+
+void wess_set_tweaks(WessTweakAttr *attr) // 8002F180
+{
+ if (attr->mask & TWEAK_DMA_BUFFERS)
+ wess_driver_num_dma_buffers = attr->dma_buffers;
+
+ if (attr->mask & TWEAK_DMA_MESSAGES)
+ wess_driver_num_dma_messages = attr->dma_messages;
+
+ if (attr->mask & TWEAK_DMA_BUFFER_LENGTH)
+ wess_driver_dma_buffer_length = attr->dma_buffer_length;
+
+ if (attr->mask & TWEAK_EXTRA_SAMPLES)
+ wess_driver_extra_samples = attr->extra_samples;
+
+ if (attr->mask & TWEAK_FRAME_LAG)
+ wess_driver_frame_lag = attr->frame_lag;
+
+ if (attr->mask & TWEAK_VOICES)
+ wess_driver_voices = attr->voices;
+
+ if (attr->mask & TWEAK_UPDATES)
+ wess_driver_updates = attr->updates;
+
+ if (attr->mask & TWEAK_SEQUENCES)
+ wess_driver_sequences = attr->sequences;
+
+ if (attr->mask & TWEAK_TRACKS)
+ wess_driver_tracks = attr->tracks;
+
+ if (attr->mask & TWEAK_GATES)
+ wess_driver_gates = attr->gates;
+
+ if (attr->mask & TWEAK_ITERS)
+ wess_driver_iters = attr->iters;
+
+ if (attr->mask & TWEAK_CALLBACKS)
+ wess_driver_callbacks = attr->callbacks;
+
+ if (attr->mask & TWEAK_MAX_TRKS_PER_SEQ)
+ wess_driver_max_trks_per_seq = attr->max_trks_per_seq;
+
+ if (attr->mask & TWEAK_MAX_SUBS_PER_TRK)
+ wess_driver_max_subs_per_trk = attr->max_subs_per_trk;
+}
+
+void wess_get_tweaks(WessTweakAttr *attr) // 8002F348
+{
+ attr->mask = 0;
+ attr->dma_buffers = wess_driver_num_dma_buffers;
+ attr->dma_messages = wess_driver_num_dma_messages;
+ attr->dma_buffer_length = wess_driver_dma_buffer_length;
+ attr->extra_samples = wess_driver_extra_samples;
+ attr->frame_lag = wess_driver_frame_lag;
+ attr->voices = wess_driver_voices;
+ attr->updates = wess_driver_updates;
+ attr->sequences = wess_driver_sequences;
+ attr->tracks = wess_driver_tracks;
+ attr->gates = wess_driver_gates;
+ attr->iters = wess_driver_iters;
+ attr->callbacks = wess_driver_callbacks;
+ attr->max_trks_per_seq = wess_driver_max_trks_per_seq;
+ attr->max_subs_per_trk = wess_driver_max_subs_per_trk;
+}
+#endif
diff --git a/Doom 64/z_zone.c b/Doom 64/z_zone.c
@@ -0,0 +1,574 @@
+/* Z_zone.c */
+
+#include "doomdef.h"
+
+/*
+==============================================================================
+
+ ZONE MEMORY ALLOCATION
+
+There is never any space between memblocks, and there will never be two
+contiguous free memblocks.
+
+The rover can be left pointing at a non-empty block
+
+It is of no value to free a cachable block, because it will get overwritten
+automatically if needed
+
+==============================================================================
+*/
+
+#define DEBUG_ 0
+
+extern u32 NextFrameIdx;
+
+memzone_t *mainzone;
+
+#define MEM_HEAP_SIZE (0x26B510) // 2.41 MB
+extern u64 mem_heap[MEM_HEAP_SIZE / sizeof(u64)]; // 800BA2F0
+
+/*
+========================
+=
+= Z_Init
+=
+========================
+*/
+
+#include "graph.h"
+
+void Z_Init (void) // 8002C8F0
+{
+ byte *mem;
+ int size;
+
+ mem = (byte *)(u32)(((u32)mem_heap + 15) & ~15);
+ size = (u32)(mem_heap+(MEM_HEAP_SIZE / sizeof(u64))) - (u32)mem;
+
+ /* mars doesn't have a refzone */
+ mainzone = Z_InitZone(mem, size);
+
+ //PRINTF_D2(WHITE, 0, 25, "%d", (u32)size);
+ //while(1){}
+}
+
+/*
+========================
+=
+= Z_InitZone
+=
+========================
+*/
+
+memzone_t *Z_InitZone(byte *base, int size) // 8002C934
+{
+ memzone_t *zone;
+
+ zone = (memzone_t *)base;
+ zone->size = size;
+ zone->rover = &zone->blocklist;
+ zone->rover2 = &zone->blocklist;
+ zone->rover3 = &zone->blocklist;
+ zone->blocklist.size = size - (int)((byte *)&zone->blocklist - (byte *)zone);
+ zone->blocklist.user = NULL;
+ zone->blocklist.tag = 0;
+ zone->blocklist.id = ZONEID;
+ zone->blocklist.next = NULL;
+ zone->blocklist.prev = NULL;
+ //zone->blocklist.lockframe = -1;
+
+ return zone;
+}
+
+/*
+========================
+=
+= Z_SetAllocBase
+= Exclusive Doom64
+=
+========================
+*/
+
+void Z_SetAllocBase(memzone_t *mainzone) // 8002C970
+{
+ mainzone->rover2 = mainzone->rover;
+}
+
+/*
+========================
+=
+= Z_Malloc2
+=
+= You can pass a NULL user if the tag is < PU_PURGELEVEL
+========================
+*/
+
+#define MINFRAGMENT 64
+
+void *Z_Malloc2 (memzone_t *mainzone, int size, int tag, void *user) // 8002C97C
+{
+ int extra;
+ memblock_t *start, *rover, *newblock, *base;
+
+ #if DEBUG_
+ Z_CheckZone (mainzone); /* DEBUG */
+ #endif
+
+ /* */
+ /* scan through the block list looking for the first free block */
+ /* of sufficient size, throwing out any purgable blocks along the way */
+ /* */
+
+ size += sizeof(memblock_t); /* account for size of block header */
+ size = (size+15) & ~15; /* phrase align everything */
+
+ start = base = mainzone->rover;
+
+ while (base->user || base->size < size)
+ {
+ if (base->user)
+ rover = base;
+ else
+ rover = base->next;
+
+ if (!rover)
+ goto backtostart;
+
+ if (rover->user)
+ {
+ if (!(rover->tag & PU_PURGELEVEL))
+ {
+ if (!(rover->tag & PU_CACHE) || (u32)rover->lockframe >= (NextFrameIdx - 1))
+ {
+ /* hit an in use block, so move base past it */
+ base = rover->next;
+ if (!base)
+ {
+ backtostart:
+ base = mainzone->rover2;
+ }
+
+ if (base == start) /* scaned all the way around the list */
+ {
+ Z_DumpHeap(mainzone);
+ I_Error("Z_Malloc2: failed allocation on %i", size);
+ }
+ continue;
+ }
+ }
+
+ /* */
+ /* free the rover block (adding the size to base) */
+ /* */
+ Z_Free((byte *)rover + sizeof(memblock_t)); /* mark as free */
+ }
+
+ if (base != rover)
+ { /* merge with base */
+ base->size += rover->size;
+ base->next = rover->next;
+ if (rover->next)
+ rover->next->prev = base;
+ else
+ mainzone->rover3 = base;
+ }
+ }
+
+ /* */
+ /* found a block big enough */
+ /* */
+ extra = base->size - size;
+ if (extra > MINFRAGMENT)
+ { /* there will be a free fragment after the allocated block */
+ newblock = (memblock_t *) ((byte *)base + size );
+ newblock->prev = base;
+ newblock->next = base->next;
+ if (newblock->next)
+ newblock->next->prev = newblock;
+ else
+ mainzone->rover3 = newblock;
+
+ base->next = newblock;
+ base->size = size;
+
+ newblock->size = extra;
+ newblock->user = NULL; /* free block */
+ newblock->tag = 0;
+ newblock->id = ZONEID;
+ }
+
+ if (user)
+ {
+ base->user = user; /* mark as an in use block */
+ *(void **)user = (void *)((byte *)base + sizeof(memblock_t));
+ }
+ else
+ {
+ if (tag >= PU_PURGELEVEL)
+ I_Error ("Z_Malloc: an owner is required for purgable blocks");
+ base->user = (void *)1; /* mark as in use, but unowned */
+ }
+
+ base->tag = tag;
+ base->id = ZONEID;
+ base->lockframe = NextFrameIdx;
+
+ mainzone->rover = base->next; /* next allocation will start looking here */
+ if (!mainzone->rover)
+ {
+ mainzone->rover3 = base;
+ mainzone->rover = mainzone->rover2;//mainzone->rover = &mainzone->blocklist;
+ }
+
+ #if DEBUG_
+ Z_CheckZone (mainzone); /* DEBUG */
+ #endif
+
+ return (void *) ((byte *)base + sizeof(memblock_t));
+}
+
+
+/*
+========================
+=
+= Z_Alloc2
+=
+= You can pass a NULL user if the tag is < PU_PURGELEVEL
+= Exclusive Psx Doom
+========================
+*/
+
+void *Z_Alloc2(memzone_t *mainzone, int size, int tag, void *user) // 8002CBE0
+{
+ int extra;
+ memblock_t *rover, *base, *block, *newblock;
+
+ #if DEBUG_
+ Z_CheckZone (mainzone); /* DEBUG */
+ #endif
+
+ /* */
+ /* scan through the block list looking for the first free block */
+ /* of sufficient size, throwing out any purgable blocks along the way */
+ /* */
+
+ size += sizeof(memblock_t); /* account for size of block header */
+ size = (size+15) & ~15; /* phrase align everything */
+
+ base = mainzone->rover3;
+
+ while (base->user || base->size < size)
+ {
+ if (base->user)
+ rover = base;
+ else
+ {
+ /* hit an in use block, so move base past it */
+ rover = base->prev;
+ if (!rover)
+ {
+ Z_DumpHeap(mainzone);
+ I_Error("Z_Alloc: failed allocation on %i", size);
+ }
+ }
+
+ if (rover->user)
+ {
+ if (!(rover->tag & PU_PURGELEVEL))
+ {
+ if (!(rover->tag & PU_CACHE) || (u32)rover->lockframe >= (NextFrameIdx - 1))
+ {
+ /* hit an in use block, so move base past it */
+ base = rover->prev;
+ if (!base)
+ {
+ Z_DumpHeap(mainzone);
+ I_Error("Z_Alloc: failed allocation on %i", size);
+ }
+ continue;
+ }
+ }
+
+ /* */
+ /* free the rover block (adding the size to base) */
+ /* */
+ Z_Free((byte *)rover + sizeof(memblock_t)); /* mark as free */
+ }
+
+ if (base != rover)
+ {
+ /* merge with base */
+ rover->size += base->size;
+ rover->next = base->next;
+
+ if (base->next)
+ base->next->prev = rover;
+ else
+ mainzone->rover3 = rover;
+
+ base = rover;
+ }
+ }
+
+ /* */
+ /* found a block big enough */
+ /* */
+ extra = (base->size - size);
+
+ newblock = base;
+ block = base;
+
+ if (extra > MINFRAGMENT)
+ {
+ block = (memblock_t *)((byte *)base + extra);
+ block->prev = newblock;
+ block->next = (void *) newblock->next;
+
+ if (newblock->next)
+ newblock->next->prev = block;
+
+ newblock->next = block;
+ block->size = size;
+ newblock->size = extra;
+ newblock->user = 0;
+ newblock->tag = 0;
+ newblock->id = ZONEID;
+ }
+
+ if (block->next == 0)
+ mainzone->rover3 = block;
+
+ if (user)
+ {
+ block->user = user; /* mark as an in use block */
+ *(void **)user = (void *)((byte *)block + sizeof(memblock_t));
+ }
+ else
+ {
+ if (tag >= PU_PURGELEVEL)
+ I_Error("Z_Alloc: an owner is required for purgable blocks");
+ block->user = (void *)1; /* mark as in use, but unowned */
+ }
+
+ block->id = ZONEID;
+ block->tag = tag;
+ block->lockframe = NextFrameIdx;
+
+ #if DEBUG_
+ Z_CheckZone (mainzone); /* DEBUG */
+ #endif
+
+ return (void *) ((byte *)block + sizeof(memblock_t));
+}
+
+/*
+========================
+=
+= Z_Free2
+=
+========================
+*/
+
+void Z_Free2(memzone_t *mainzone, void *ptr) // 8002CE28
+{
+ memblock_t *block;
+
+ block = (memblock_t *)((byte *)ptr - sizeof(memblock_t));
+ if (block->id != ZONEID)
+ I_Error("Z_Free: freed a pointer without ZONEID");
+
+ if (block->user > (void **)0x100) /* smaller values are not pointers */
+ *block->user = 0; /* clear the user's mark */
+ block->user = NULL; /* mark as free */
+ block->tag = 0;
+}
+
+/*
+========================
+=
+= Z_FreeTags
+=
+========================
+*/
+
+void Z_FreeTags (memzone_t *mainzone, int tag) // 8002CE8C
+{
+ memblock_t *block, *next;
+
+ for (block = &mainzone->blocklist; block ; block = next)
+ {
+ /* get link before freeing */
+ next = block->next;
+
+ /* free block */
+ if (block->user)
+ {
+ if(block->tag & tag)
+ {
+ Z_Free((byte *)block + sizeof(memblock_t));
+ }
+ }
+ }
+
+ for (block = &mainzone->blocklist; block; block = next)
+ {
+ /* get link before freeing */
+ next = block->next;
+
+ if (!block->user && next && !next->user)
+ {
+ block->size += next->size;
+ block->next = next->next;
+ if (next->next)
+ next->next->prev = block;
+ next = block;
+ }
+ }
+
+ mainzone->rover = &mainzone->blocklist;
+ mainzone->rover2 = &mainzone->blocklist;
+ mainzone->rover3 = &mainzone->blocklist;
+
+ block = mainzone->blocklist.next;
+ while (block)
+ {
+ mainzone->rover3 = block;
+ block = block->next;
+ }
+}
+
+/*
+========================
+=
+= Z_Touch
+= Exclusive Doom64
+=
+========================
+*/
+
+void Z_Touch(void *ptr) // 8002CF9C
+{
+ memblock_t *block;
+
+ block = (memblock_t *)((byte *)ptr - sizeof(memblock_t));
+ if (block->id != ZONEID)
+ I_Error("Z_Touch: touched a pointer without ZONEID");
+
+ block->lockframe = NextFrameIdx;
+}
+
+
+/*
+========================
+=
+= Z_CheckZone
+=
+========================
+*/
+
+void Z_CheckZone (memzone_t *mainzone) // 8002CFEC
+{
+ memblock_t *checkblock;
+ int size;
+
+ for (checkblock = &mainzone->blocklist ; checkblock; checkblock = checkblock->next)
+ {
+ if(checkblock->id != ZONEID)
+ I_Error("Z_CheckZone: block missing ZONEID");
+
+ if (!checkblock->next)
+ {
+ size = (byte *)checkblock + checkblock->size - (byte *)mainzone;
+ if (size != mainzone->size)
+ I_Error ("Z_CheckZone: zone size changed from %d to %d\n", mainzone->size, size);
+ break;
+ }
+
+ if ( (byte *)checkblock + checkblock->size != (byte *)checkblock->next)
+ I_Error ("Z_CheckZone: block size does not touch the next block\n");
+ if ( checkblock->next->prev != checkblock)
+ I_Error ("Z_CheckZone: next block doesn't have proper back link\n");
+ }
+
+ #if DEBUG_
+ Z_DumpHeap(mainzone);
+ #endif
+}
+
+
+/*
+========================
+=
+= Z_ChangeTag
+=
+========================
+*/
+
+void Z_ChangeTag (void *ptr, int tag) // 8002D0F0
+{
+ memblock_t *block;
+
+ block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
+ if (block->id != ZONEID)
+ I_Error ("Z_ChangeTag: freed a pointer without ZONEID");
+ if (tag >= PU_PURGELEVEL && (int)block->user < 0x100)
+ I_Error ("Z_ChangeTag: an owner is required for purgable blocks");
+ block->tag = tag;
+ block->lockframe = NextFrameIdx;
+}
+
+
+/*
+========================
+=
+= Z_FreeMemory
+=
+========================
+*/
+
+int Z_FreeMemory (memzone_t *mainzone) // 8002D188
+{
+ memblock_t *block;
+ int free;
+
+ free = 0;
+ for (block = &mainzone->blocklist ; block ; block = block->next)
+ {
+ if (!block->user)
+ free += block->size;
+ }
+
+ return free;
+}
+
+/*
+========================
+=
+= Z_DumpHeap
+=
+========================
+*/
+
+void Z_DumpHeap(memzone_t *mainzone) // 8002D1C8
+{
+#if DEBUG_
+ memblock_t *block;
+
+ printf("zone size: %i location: %p\n", mainzone->size, mainzone);
+
+ for (block = &mainzone->blocklist; block; block = block->next)
+ {
+ printf("block:%p size:%7i user:%p tag:%3i frame:%i\n",
+ block, block->size, block->user, block->tag, block->lockframe);
+
+ if (!block->next)
+ continue;
+
+ if ((byte *)block + block->size != (byte *)block->next)
+ printf("ERROR: block size does not touch the next block\n");
+ if (block->next->prev != block)
+ printf("ERROR: next block doesn't have proper back link\n");
+ }
+#endif
+}
+