furnace/src/engine/song.h

410 lines
11 KiB
C
Raw Normal View History

2022-02-15 03:12:20 +00:00
/**
* Furnace Tracker - multi-system chiptune tracker
* Copyright (C) 2021-2022 tildearrow and contributors
*
* 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 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
* 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.
*/
2022-01-27 05:29:16 +00:00
#ifndef _SONG_H
#define _SONG_H
#include <stdio.h>
#include <vector>
2022-01-08 06:57:37 +00:00
#define DIV_MAX_CHANS 128
#include "../ta-utils.h"
#include "orders.h"
#include "instrument.h"
#include "pattern.h"
#include "wavetable.h"
#include "sample.h"
enum DivSystem {
DIV_SYSTEM_NULL=0,
DIV_SYSTEM_YMU759,
DIV_SYSTEM_GENESIS, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_GENESIS_EXT, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_SMS,
DIV_SYSTEM_SMS_OPLL, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_GB,
DIV_SYSTEM_PCE,
DIV_SYSTEM_NES,
2022-02-24 02:53:07 +00:00
DIV_SYSTEM_NES_VRC7, // ** COMPOUND SYSTEM - DO NOT USE! **
2022-04-03 22:14:12 +00:00
DIV_SYSTEM_NES_FDS, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_C64_6581,
DIV_SYSTEM_C64_8580,
DIV_SYSTEM_ARCADE, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_YM2610,
2022-01-13 03:58:51 +00:00
DIV_SYSTEM_YM2610_EXT,
DIV_SYSTEM_AY8910,
DIV_SYSTEM_AMIGA,
DIV_SYSTEM_YM2151,
DIV_SYSTEM_YM2612,
DIV_SYSTEM_TIA,
2022-01-14 05:02:10 +00:00
DIV_SYSTEM_SAA1099,
2022-02-02 20:29:20 +00:00
DIV_SYSTEM_AY8930,
DIV_SYSTEM_VIC20,
DIV_SYSTEM_PET,
DIV_SYSTEM_SNES,
2022-02-02 23:24:33 +00:00
DIV_SYSTEM_VRC6,
2022-02-02 20:29:20 +00:00
DIV_SYSTEM_OPLL,
DIV_SYSTEM_FDS,
DIV_SYSTEM_MMC5,
DIV_SYSTEM_N163,
DIV_SYSTEM_OPN,
DIV_SYSTEM_PC98,
DIV_SYSTEM_OPL,
DIV_SYSTEM_OPL2,
DIV_SYSTEM_OPL3,
DIV_SYSTEM_MULTIPCM,
DIV_SYSTEM_PCSPKR,
DIV_SYSTEM_POKEY,
DIV_SYSTEM_RF5C68,
DIV_SYSTEM_SWAN,
DIV_SYSTEM_OPZ,
DIV_SYSTEM_POKEMINI,
DIV_SYSTEM_SEGAPCM,
DIV_SYSTEM_VBOY,
DIV_SYSTEM_VRC7,
DIV_SYSTEM_YM2610B,
DIV_SYSTEM_SFX_BEEPER,
DIV_SYSTEM_YM2612_EXT,
2022-02-02 23:24:33 +00:00
DIV_SYSTEM_SCC,
DIV_SYSTEM_OPL_DRUMS,
DIV_SYSTEM_OPL2_DRUMS,
DIV_SYSTEM_OPL3_DRUMS,
DIV_SYSTEM_YM2610_FULL,
DIV_SYSTEM_YM2610_FULL_EXT,
2022-02-02 23:24:33 +00:00
DIV_SYSTEM_OPLL_DRUMS,
DIV_SYSTEM_LYNX,
DIV_SYSTEM_QSOUND,
2022-03-04 11:13:49 +00:00
DIV_SYSTEM_VERA,
DIV_SYSTEM_YM2610B_EXT,
2022-03-04 11:13:49 +00:00
DIV_SYSTEM_SEGAPCM_COMPAT,
DIV_SYSTEM_X1_010,
DIV_SYSTEM_BUBSYS_WSG
};
struct DivSong {
// version number used for saving the song.
2021-05-13 08:22:57 +00:00
// Furnace will save using the latest possible version,
// known version numbers:
2022-04-08 01:13:11 +00:00
// - 26: v1.1.3
// - changes height of FDS wave to 6-bit (it was 4-bit before)
2022-02-19 07:52:53 +00:00
// - 25: v1.1
// - adds pattern names (in a rather odd way)
// - introduces SMS+OPLL system
// - 24: v0.12/0.13/1.0
// - current format version
// - changes pattern length from char to int, probably to allow for size 256
// - 23: ???
2021-12-04 07:34:13 +00:00
// - what happened here?
2021-12-18 06:09:43 +00:00
// - 20: v11.1 (?)
// - E5xx effect range is now ±1 semitone
// - 19: v11
// - introduces Arcade system
// - changes to the FM instrument format due to YMU759 being dropped
// - 18: v10
// - radically changes STD instrument for Game Boy
// - 17: v9
// - changes C64 volIsCutoff flag from int to char for unknown reasons
// - 16: v8 (?)
// - introduces C64 system
// - 15: v7 (?)
// - 14: v6 (?)
// - introduces NES system
// - changes macro and wave values from char to int
// - 13: v5.1
// - introduces PC Engine system in later version (how?)
// - stores highlight in file
// - 12: v5 (?)
// - introduces Game Boy system
// - introduces wavetables
// - 11: ???
// - introduces Sega Master System
// - custom Hz support
// - instrument type (FM/STD) present
// - prior to this version the instrument type depended on the system
// - 10: ???
// - introduces multiple effect columns
// - 9: v3.9
// - introduces Genesis system
// - introduces system number
// - 7: ???
2021-05-12 22:19:18 +00:00
// - 5: BETA 3 (?)
// - adds arpeggio tick
// - 3: BETA 2
// - possibly the first version that could save
// - basic format, no system number, 16 instruments, one speed, YMU759-only
// - if somebody manages to find a version 2 or even 1 module, please tell me as it will be worth more than a luxury vehicle
unsigned short version;
bool isDMF;
// system
DivSystem system[32];
unsigned char systemLen;
signed char systemVol[32];
signed char systemPan[32];
2022-01-28 08:40:06 +00:00
// interpretation of these flags varies depending on system.
// - most systems:
// - bit 0: PAL
// - NES:
// - bit 0-1: system type
// - 0: NTSC
// - 1: PAL
// - 2: Dendy
// - SMS/SN76489:
2022-01-28 23:12:56 +00:00
// - bit 0-1: clock rate
// - 0: NTSC (3.58MHz)
// - 1: PAL (3.55MHz)
// - 2: Other (4MHz)
// - 3: half NTSC (1.79MHz)
2022-01-28 23:12:56 +00:00
// - bit 2-3: noise type
2022-01-28 08:40:06 +00:00
// - 0: Sega VDP (16-bit noise)
// - 1: real SN76489 (15-bit noise)
// - 2: real SN76489 with Atari-like short noise buzz (15-bit noise)
// - 3: Game Gear (16-bit noise, stereo)
// - bit 4: disable noise phase reset
2022-01-28 08:40:06 +00:00
// - YM2612:
// - bit 0-1: clock rate
// - 0: Genesis NTSC (7.67MHz)
// - 1: Genesis PAL (7.61MHz)
// - 2: 8MHz
2022-02-05 02:35:32 +00:00
// - 3: AtGames Genesis (6.13MHz)
2022-01-28 08:40:06 +00:00
// - YM2151:
// - bit 0-1: clock rate
// - 0: 3.58MHz (NTSC)
// - 1: 3.55MHz (PAL)
// - 2: 4MHz
// - AY-3-8910/AY8930:
// - bit 0-3: clock rate
// - 0: 1.79MHz (MSX NTSC)
// - 1: 1.77MHz (ZX Spectrum, MSX PAL, etc.)
// - 2: 1.75MHz (ZX Spectrum)
// - 3: 2MHz (Atari ST)
// - 4: 1.5MHz (Vectrex)
2022-01-28 22:10:22 +00:00
// - 5: 1MHz (Amstrad CPC)
2022-01-28 08:40:06 +00:00
// - 6: 0.89MHz (Sunsoft 5B)
// - 7: 1.67MHz
2022-01-28 23:12:56 +00:00
// - 8: 0.83MHz (Sunsoft 5B on PAL)
2022-03-06 19:18:18 +00:00
// - 9: 1.10MHz (Gamate/VIC-20 PAL)
// - 10: 2.097152MHz (Game Boy)
2022-01-28 08:40:06 +00:00
// - bit 4-5: chip type (ignored on AY8930)
// - 0: AY-3-8910 or similar
// - 1: YM2149
// - 2: Sunsoft 5B
// - bit 6: stereo
// - 0: mono
// - 1: stereo ABC
// - SAA1099:
// - bit 0-1: clock rate
// - 0: 8MHz (SAM Coupé, Game Blaster)
// - 1: 7.15MHz
// - 2: 7.09MHz
// - Amiga:
2022-01-28 23:12:56 +00:00
// - bit 0: clock rate
2022-01-28 08:40:06 +00:00
// - 0: 7.15MHz (NTSC)
// - 1: 7.09MHz (PAL)
2022-01-28 23:12:56 +00:00
// - bit 1: model
2022-01-28 08:40:06 +00:00
// - 0: Amiga 500
// - 1: Amiga 1200
2022-02-04 22:59:55 +00:00
// - bit 8-14: stereo separation
// - 0 is 0% while 127 is 100%
2022-03-05 05:36:50 +00:00
// - PC Speaker:
// - bit 0-1: speaker type
// - 0: unfiltered
// - 1: cone
// - 2: piezo
// - 3: real (TODO)
2022-02-22 09:01:57 +00:00
// - QSound:
// - bit 12-20: echo feedback
// - Valid values are 0-255
// - bit 0-11: echo delay length
// - Valid values are 0-2725
// - 0 is max length, 2725 is min length
// - OPLL:
// - bit 0-3: clock rate
// - 0: NTSC (3.58MHz)
// - 1: PAL (3.55MHz)
// - 2: Other (4MHz)
// - 3: half NTSC (1.79MHz)
// - bit 4-7: patch set
// - 0: YM2413
// - 1: YMF281
// - 2: YM2423
// - 3: VRC7
// - 4: custom (TODO)
// - X1-010:
// - bit 0-3: clock rate
// - 0: 16MHz (Seta 1)
// - 1: 16.67MHz (Seta 2)
// - bit 4: stereo
// - 0: mono
// - 1: stereo
2022-01-28 08:40:06 +00:00
unsigned int systemFlags[32];
// song information
String name, author;
// legacy song information
String carrier, composer, vendor, category, writer, arranger, copyright, manGroup, manInfo, createdDate, revisionDate;
// other things
String chanName[DIV_MAX_CHANS];
String chanShortName[DIV_MAX_CHANS];
String notes;
// highlight
unsigned char hilightA, hilightB;
// module details
unsigned char timeBase, speed1, speed2, arpLen;
bool pal;
bool customTempo;
2022-03-16 04:30:15 +00:00
float hz;
int patLen, ordersLen, insLen, waveLen, sampleLen;
float masterVol;
float tuning;
2022-01-22 20:30:23 +00:00
// compatibility flags
bool limitSlides;
bool linearPitch;
// loop behavior
// 0: reset on loop
// 1: fake reset on loop
// 2: don't do anything on loop
unsigned char loopModality;
bool properNoiseLayout;
bool waveDutyIsVol;
bool resetMacroOnPorta;
bool legacyVolumeSlides;
bool compatibleArpeggio;
bool noteOffResetsSlides;
bool targetResetsSlides;
bool arpNonPorta;
bool algMacroBehavior;
2022-02-18 06:27:26 +00:00
bool brokenShortcutSlides;
bool ignoreDuplicateSlides;
bool stopPortaOnNoteOff;
bool continuousVibrato;
bool brokenDACMode;
2022-03-12 04:01:18 +00:00
bool oneTickCut;
2022-03-14 06:23:31 +00:00
bool newInsTriggersInPorta;
bool arp0Reset;
bool brokenSpeedSel;
bool noSlidesOnFirstTick;
bool rowResetsArpPos;
bool ignoreJumpAtEnd;
2022-03-27 03:15:15 +00:00
bool buggyPortaAfterSlide;
bool gbInsAffectsEnvelope;
bool sharedExtStat;
2022-01-22 20:30:23 +00:00
DivOrders orders;
std::vector<DivInstrument*> ins;
2022-01-08 06:57:37 +00:00
DivChannelData pat[DIV_MAX_CHANS];
std::vector<DivWavetable*> wave;
std::vector<DivSample*> sample;
bool chanShow[DIV_MAX_CHANS];
bool chanCollapse[DIV_MAX_CHANS];
DivInstrument nullIns;
DivWavetable nullWave;
2022-02-25 03:52:20 +00:00
DivSample nullSample;
2022-03-16 03:05:55 +00:00
/**
* unloads the song, freeing all memory associated with it.
* use before destroying the object.
*/
void unload();
DivSong():
version(0),
isDMF(false),
systemLen(2),
name(""),
author(""),
carrier(""),
composer(""),
vendor(""),
category(""),
writer(""),
arranger(""),
copyright(""),
manGroup(""),
manInfo(""),
createdDate(""),
revisionDate(""),
hilightA(4),
hilightB(16),
2021-12-14 01:31:27 +00:00
timeBase(0),
speed1(6),
speed2(6),
arpLen(1),
2021-12-28 23:23:57 +00:00
pal(true),
customTempo(false),
2022-03-16 04:30:15 +00:00
hz(60.0),
patLen(64),
ordersLen(1),
insLen(0),
waveLen(0),
2022-01-22 20:30:23 +00:00
sampleLen(0),
masterVol(1.0f),
tuning(440.0f),
limitSlides(false),
linearPitch(true),
loopModality(0),
properNoiseLayout(false),
waveDutyIsVol(false),
resetMacroOnPorta(false),
legacyVolumeSlides(false),
compatibleArpeggio(false),
noteOffResetsSlides(true),
targetResetsSlides(true),
arpNonPorta(false),
2022-02-18 06:27:26 +00:00
algMacroBehavior(false),
brokenShortcutSlides(false),
ignoreDuplicateSlides(false),
stopPortaOnNoteOff(false),
continuousVibrato(false),
2022-03-12 04:01:18 +00:00
brokenDACMode(false),
2022-03-14 06:23:31 +00:00
oneTickCut(false),
newInsTriggersInPorta(true),
arp0Reset(true),
brokenSpeedSel(false),
noSlidesOnFirstTick(false),
rowResetsArpPos(false),
2022-03-27 03:15:15 +00:00
ignoreJumpAtEnd(false),
buggyPortaAfterSlide(false),
gbInsAffectsEnvelope(true),
sharedExtStat(true) {
for (int i=0; i<32; i++) {
system[i]=DIV_SYSTEM_NULL;
systemVol[i]=64;
systemPan[i]=0;
2022-01-28 08:40:06 +00:00
systemFlags[i]=0;
}
for (int i=0; i<DIV_MAX_CHANS; i++) {
chanShow[i]=true;
chanCollapse[i]=false;
}
system[0]=DIV_SYSTEM_YM2612;
system[1]=DIV_SYSTEM_SMS;
}
};
2022-01-27 05:29:16 +00:00
2022-02-02 20:29:20 +00:00
#endif