/*
* SSEQ Player - Track structure
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
*
* Adapted from source code of FeOS Sound System
* By fincs
* https://github.com/fincs/FSS
*/
#pragma once
#include <bitset>
#include <functional>
#include <cstdint>
#include "common.h"
#include "consts.h"
struct Player;
enum class StackType
{
Call,
Loop
};
struct StackValue
{
StackType type;
const std::uint8_t *dest;
StackValue() : type(StackType::Call), dest(nullptr) { }
StackValue(StackType newType, const std::uint8_t *newDest) : type(newType), dest(newDest) { }
};
struct Override
{
bool overriding;
int cmd;
int value;
int extraValue;
Override() : overriding(false), cmd(0), value(0), extraValue(0) { }
bool operator()() const { return this->overriding; }
bool &operator()() { return this->overriding; }
int val(const std::uint8_t **pData, std::function<int (const std::uint8_t **)> reader, bool returnExtra = false)
{
if (this->overriding)
return returnExtra ? this->extraValue : this->value;
else
return reader(pData);
}
};
struct Track
{
std::int8_t trackId;
std::bitset<ToIntegral(TrackState::Bits)> state;
std::uint8_t num, prio;
Player *ply;
const std::uint8_t *startPos;
const std::uint8_t *pos;
StackValue stack[FSS_TRACKSTACKSIZE];
std::uint8_t stackPos;
std::uint8_t loopCount[FSS_TRACKSTACKSIZE];
Override overriding;
bool lastComparisonResult;
int wait;
std::uint16_t patch;
std::uint8_t portaKey, portaTime;
std::int16_t sweepPitch;
std::uint8_t vol, expr;
std::int8_t pan; // -64..63
std::uint8_t pitchBendRange;
std::int8_t pitchBend;
std::int8_t transpose;
std::uint8_t a, d, s, r;
std::uint8_t modType, modSpeed, modDepth, modRange;
std::uint16_t modDelay;
std::bitset<ToIntegral(TrackUpdateFlag::Bits)> updateFlags;
Track();
void Init(std::uint8_t handle, Player *ply, const std::uint8_t *pos, int n);
void Zero();
void ClearState();
void Free();
int NoteOn(int key, int vel, int len);
int NoteOnTie(int key, int vel);
void ReleaseAllNotes();
void Run();
};