3512 lines · 81.2 KB · C
RawDownload
// for finding memory leaks in debug mode with Visual Studio#if defined _DEBUG && defined _MSC_VER#include <crtdbg.h>#endif #include <stdio.h>#include <stdint.h>#include <stdbool.h>#include <math.h>#include "ft2_header.h"#include "ft2_config.h"#include "ft2_audio.h"#include "ft2_pattern_ed.h"#include "ft2_gui.h"#include "scopes/ft2_scopes.h"#include "ft2_sample_ed.h"#include "ft2_mouse.h"#include "ft2_video.h"#include "ft2_sample_loader.h"#include "ft2_diskop.h"#include "ft2_tables.h"#include "ft2_bmp.h"#include "ft2_structs.h"#include "ft2_bmp.h" #ifdef _MSC_VER#pragma pack(push)#pragma pack(1)#endiftypedef struct patHdr_t{	char ID[22], junk1[60];	uint8_t numInstrs, junk2, numChannels;	int16_t waveforms, masterVol;	int32_t dataSize;	char junk4[36];	int16_t junk5;	char instrName[16];	int32_t instrSize;	uint8_t layers;	char junk6[40];	uint8_t junk7, junk8;	int32_t junk9;	uint8_t numSamples;	char junk10[40];}#ifdef __GNUC____attribute__ ((packed))#endifpatHdr_t; typedef struct patWaveHdr_t{	char name[7];	uint8_t fractions;	int32_t sampleLength, loopStart, loopEnd;	uint16_t sampleRate;	int32_t lowFrq, highFreq, rootFrq;	int16_t finetune;	uint8_t panning, envRate[6], envOfs[6], tremSweep, tremRate;	uint8_t tremDepth, vibSweep, vibRate, vibDepth, flags;	int16_t junk1;	uint16_t junk2;	char junk3[36];}#ifdef __GNUC____attribute__ ((packed))#endifpatWaveHdr_t; typedef struct xiHdr_t{	char ID[21], name[23], progName[20];	uint16_t version;	uint8_t note2SampleLUT[96];	int16_t volEnvPoints[12][2], panEnvPoints[12][2];	uint8_t volEnvLength, panEnvLength, volEnvSustain, volEnvLoopStart, volEnvLoopEnd, panEnvSustain, panEnvLoopStart;	uint8_t panEnvLoopEnd, volEnvFlags, panEnvFlags, vibType, vibSweep, vibDepth, vibRate;	uint16_t fadeout;	uint8_t midiOn, midiChannel;	int16_t midiProgram, midiBend;	uint8_t mute, reserved[15];	int16_t numSamples;	xmSmpHdr_t smp[16];}#ifdef __GNUC____attribute__ ((packed))#endifxiHdr_t; #define PIANOKEY_WHITE_W 10#define PIANOKEY_WHITE_H 46#define PIANOKEY_BLACK_W 7#define PIANOKEY_BLACK_H 29 static const bool keyIsBlackTab[12] = { false, true, false, true, false, false, true, false, true, false, true };static const char sharpNote1Char[12] = { 'C', 'C', 'D', 'D', 'E', 'F', 'F', 'G', 'G', 'A', 'A', 'B' };static const char sharpNote2Char[12] = { '-', '#', '-', '#', '-', '-', '#', '-', '#', '-', '#', '-' };static const char flatNote1Char[12]  = { 'C', 'D', 'D', 'E', 'E', 'F', 'G', 'G', 'A', 'A', 'B', 'B' };static const char flatNote2Char[12]  = { '-', 'b', '-', 'b', '-', '-', 'b', '-', 'b', '-', 'b', '-' };static const uint8_t whiteKeyIndex[7] = { 0, 2, 4, 5, 7, 9, 11 };static const uint16_t whiteKeysBmpOrder[12] = { 0, 0, 506, 0, 1012, 0, 0, 506, 0, 506, 0, 1012 };static const uint8_t keyDigitXPos[12] = { 11, 16, 22, 27, 33, 44, 49, 55, 60, 66, 71, 77 };static const uint8_t keyXPos[12] = { 8, 15, 19, 26, 30, 41, 48, 52, 59, 63, 70, 74 };static volatile bool updateVolEnv, updatePanEnv;static bool pianoKeyStatus[96];static int32_t lastMouseX, lastMouseY, saveMouseX, saveMouseY; static const uint8_t mx2PianoKey[77] ={	0,0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,	4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,	9,9,9,9,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11}; // thread datastatic uint16_t saveInstrNum;static SDL_Thread *thread; extern const uint16_t *note2Period; // ft2_replayer.c void updateInstEditor(void);void updateNewInstrument(void); void sanitizeInstrument(instr_t *ins){	if (ins == NULL)		return; 	ins->midiProgram = CLAMP(ins->midiProgram, 0, 127);	ins->midiBend = CLAMP(ins->midiBend, 0, 36); 	if (ins->midiChannel > 15) ins->midiChannel = 15;	if (ins->autoVibDepth > 0x0F) ins->autoVibDepth = 0x0F;	if (ins->autoVibRate > 0x3F) ins->autoVibRate = 0x3F;	if (ins->autoVibType > 3) ins->autoVibType = 0; 	for (int32_t i = 0; i < 96; i++)	{		if (ins->note2SampleLUT[i] >= MAX_SMP_PER_INST)			ins->note2SampleLUT[i] = MAX_SMP_PER_INST-1;	} 	if (ins->volEnvLength > 12) ins->volEnvLength = 12;	if (ins->volEnvLoopStart > 11) ins->volEnvLoopStart = 11;	if (ins->volEnvLoopEnd > 11) ins->volEnvLoopEnd = 11;	if (ins->volEnvSustain > 11) ins->volEnvSustain = 11;	if (ins->panEnvLength > 12) ins->panEnvLength = 12;	if (ins->panEnvLoopStart > 11) ins->panEnvLoopStart = 11;	if (ins->panEnvLoopEnd > 11) ins->panEnvLoopEnd = 11;	if (ins->panEnvSustain > 11) ins->panEnvSustain = 11; 	for (int32_t i = 0; i < 12; i++)	{		if ((uint16_t)ins->volEnvPoints[i][0] > 32767) ins->volEnvPoints[i][0] = 32767;		if ((uint16_t)ins->panEnvPoints[i][0] > 32767) ins->panEnvPoints[i][0] = 32767;		if ((uint16_t)ins->volEnvPoints[i][1] > 64) ins->volEnvPoints[i][1] = 64;		if ((uint16_t)ins->panEnvPoints[i][1] > 63) ins->panEnvPoints[i][1] = 63;	}} static instr_t *getCurDispInstr(void){	if (instr[editor.curInstr] == NULL)		return instr[131]; 	return instr[editor.curInstr];} static int32_t SDLCALL copyInstrThread(void *ptr){	const int16_t dstIns = editor.curInstr;	const int16_t srcIns = editor.srcInstr; 	pauseAudio();	freeInstr(dstIns); 	bool error = false;	if (instr[srcIns] != NULL)	{		error = true;		if (allocateInstr(dstIns))		{			int16_t i; 			sample_t *srcSmp;			sample_t *dstSmp; 			memcpy(instr[dstIns], instr[srcIns], sizeof (instr_t)); 			// clear all copied sample structs (set up in cloneSample() later)			dstSmp = instr[dstIns]->smp;			for (i = 0; i < MAX_SMP_PER_INST; i++, dstSmp++)				memset(dstSmp, 0, sizeof (sample_t)); 			// clone all the samples 			srcSmp = instr[srcIns]->smp;			dstSmp = instr[dstIns]->smp; 			for (i = 0; i < MAX_SMP_PER_INST; i++, srcSmp++, dstSmp++)			{				if (!cloneSample(srcSmp, dstSmp))					break;			} 			if (i == MAX_SMP_PER_INST) // did we manage to successfully copy the samples?				error = false; // yes		}	} 	resumeAudio(); 	if (error)		okBoxThreadSafe(0, "System message", "Not enough memory!"); 	// do not change instrument names! 	if (!error)	{		editor.updateCurInstr = true;		setSongModifiedFlag();	} 	setMouseBusy(false); 	return false;	(void)ptr;} void copyInstr(void) // dstInstr = srcInstr{	if (editor.curInstr == 0 || editor.srcInstr == editor.curInstr)		return; 	mouseAnimOn();	thread = SDL_CreateThread(copyInstrThread, NULL, NULL);	if (thread == NULL)	{		okBox(0, "System message", "Couldn't create thread!");		return;	} 	SDL_DetachThread(thread);} void xchgInstr(void) // dstInstr <-> srcInstr{	if (editor.curInstr == 0 || editor.srcInstr == editor.curInstr)		return; 	lockMixerCallback(); 	// swap instruments	instr_t *dstTmp = instr[editor.curInstr];	instr[editor.curInstr] = instr[editor.srcInstr];	instr[editor.srcInstr] = dstTmp; 	// we do not swap instrument names (like FT2) 	unlockMixerCallback(); 	updateNewInstrument();	setSongModifiedFlag();} static void drawMIDICh(void){	instr_t *ins = getCurDispInstr();	assert(ins->midiChannel <= 15);	const uint8_t val = ins->midiChannel + 1;	textOutFixed(156, 132, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[val]);} static void drawMIDIPrg(void){	instr_t *ins = getCurDispInstr();	assert(ins->midiProgram <= 127);	textOutFixed(149, 146, PAL_FORGRND, PAL_DESKTOP, dec3StrTab[ins->midiProgram]);} static void drawMIDIBend(void){	instr_t *ins = getCurDispInstr();	assert(ins->midiBend <= 36);	textOutFixed(156, 160, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->midiBend]);} void midiChDown(void){	if (editor.curInstr != 0 && instr[editor.curInstr] != NULL)		scrollBarScrollLeft(SB_INST_EXT_MIDI_CH, 1);} void midiChUp(void){	if (editor.curInstr != 0 && instr[editor.curInstr] != NULL)		scrollBarScrollRight(SB_INST_EXT_MIDI_CH, 1);} void midiPrgDown(void){	if (editor.curInstr != 0 && instr[editor.curInstr] != NULL)		scrollBarScrollLeft(SB_INST_EXT_MIDI_PRG, 1);} void midiPrgUp(void){	if (editor.curInstr != 0 && instr[editor.curInstr] != NULL)		scrollBarScrollRight(SB_INST_EXT_MIDI_PRG, 1);} void midiBendDown(void){	if (editor.curInstr != 0 && instr[editor.curInstr] != NULL)		scrollBarScrollLeft(SB_INST_EXT_MIDI_BEND, 1);} void midiBendUp(void){	if (editor.curInstr != 0 && instr[editor.curInstr] != NULL)		scrollBarScrollRight(SB_INST_EXT_MIDI_BEND, 1);} void sbMidiChPos(uint32_t pos){	instr_t *ins = instr[editor.curInstr];	if (ins == NULL || editor.curInstr == 0)	{		setScrollBarPos(SB_INST_EXT_MIDI_CH, 0, false);		return;	} 	if (ins->midiChannel != (uint8_t)pos)	{		ins->midiChannel = (uint8_t)pos;		drawMIDICh();		setSongModifiedFlag();	}} void sbMidiPrgPos(uint32_t pos){	instr_t *ins = instr[editor.curInstr];	if (ins == NULL || editor.curInstr == 0)	{		setScrollBarPos(SB_INST_EXT_MIDI_PRG, 0, false);		return;	} 	if (ins->midiProgram != (int16_t)pos)	{		ins->midiProgram = (int16_t)pos;		drawMIDIPrg();		setSongModifiedFlag();	}} void sbMidiBendPos(uint32_t pos){	instr_t *ins = instr[editor.curInstr];	if (ins == NULL || editor.curInstr == 0)	{		setScrollBarPos(SB_INST_EXT_MIDI_BEND, 0, false);		return;	} 	if (ins->midiBend != (int16_t)pos)	{		ins->midiBend = (int16_t)pos;		drawMIDIBend();		setSongModifiedFlag();	}} void updateNewSample(void){	if (ui.instrSwitcherShown)		updateInstrumentSwitcher(); 	updateSampleEditorSample(); 	if (ui.sampleEditorShown)		updateSampleEditor(); 	if (ui.instEditorShown || ui.instEditorExtShown)		updateInstEditor();} void updateNewInstrument(void){	updateTextBoxPointers(); 	if (ui.instrSwitcherShown)		updateInstrumentSwitcher(); 	editor.currVolEnvPoint = 0;	editor.currPanEnvPoint = 0; 	updateSampleEditorSample(); 	if (ui.sampleEditorShown)		updateSampleEditor(); 	if (ui.instEditorShown || ui.instEditorExtShown)		updateInstEditor(); 	if (ui.advEditShown)		updateAdvEdit();} static void drawVolEnvSus(void){	instr_t *ins = getCurDispInstr();	assert(ins->volEnvSustain < 100);	textOutFixed(382, 206, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->volEnvSustain]);} static void drawVolEnvRepS(void){	instr_t *ins = getCurDispInstr();	assert(ins->volEnvLoopStart < 100);	textOutFixed(382, 233, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->volEnvLoopStart]);} static void drawVolEnvRepE(void){	instr_t *ins = getCurDispInstr();	assert(ins->volEnvLoopEnd < 100);	textOutFixed(382, 247, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->volEnvLoopEnd]);} static void drawPanEnvSus(void){	instr_t *ins = getCurDispInstr();	assert(ins->panEnvSustain < 100);	textOutFixed(382, 293, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->panEnvSustain]);} static void drawPanEnvRepS(void){	instr_t *ins = getCurDispInstr();	assert(ins->panEnvLoopStart < 100);	textOutFixed(382, 320, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->panEnvLoopStart]);} static void drawPanEnvRepE(void){	instr_t *ins = getCurDispInstr();	assert(ins->panEnvLoopEnd < 100);	textOutFixed(382, 334, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->panEnvLoopEnd]);} static void drawVolume(void){	sample_t *s;	if (instr[editor.curInstr] == NULL)		s = &instr[0]->smp[0];	else		s = &instr[editor.curInstr]->smp[editor.curSmp]; 	hexOutBg(505, 177, PAL_FORGRND, PAL_DESKTOP, s->volume, 2);} static void drawPanning(void){	sample_t *s;	if (instr[editor.curInstr] == NULL)		s = &instr[0]->smp[0];	else		s = &instr[editor.curInstr]->smp[editor.curSmp]; 	hexOutBg(505, 191, PAL_FORGRND, PAL_DESKTOP, s->panning, 2);} void drawC4Rate(void){	fillRect(465, 299, 71, 8, PAL_DESKTOP); 	int32_t C4Hz = 0;	if (editor.curInstr != 0)	{		instr_t *ins = instr[editor.curInstr];		if (ins != NULL)			C4Hz = (int32_t)(getSampleC4Rate(&ins->smp[editor.curSmp]) + 0.5); // rounded	} 	char str[64];	sprintf(str, "%dHz", C4Hz);	textOut(465, 299, PAL_FORGRND, str);} static void drawFineTune(void){	sample_t *s;	if (instr[editor.curInstr] == NULL)		s = &instr[0]->smp[0];	else		s = &instr[editor.curInstr]->smp[editor.curSmp]; 

Lines 1–500 of 3512.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t