Olav SørensenPushed v1.62 code4188e803 years agoHistory
1118 lines · 24.5 KB · C
RawDownload
// for finding memory leaks in debug mode with Visual Studio #if defined _DEBUG && defined _MSC_VER#include <crtdbg.h>#endif #include <stdint.h>#include <stdbool.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#ifdef _WIN32#include <direct.h>#else#include <unistd.h>#endif#include "pt2_helpers.h"#include "pt2_textout.h"#include "pt2_tables.h"#include "pt2_diskop.h"#include "pt2_sampler.h"#include "pt2_visuals.h"#include "pt2_keyboard.h"#include "pt2_config.h"#include "pt2_audio.h"#include "pt2_chordmaker.h"#include "pt2_edit.h"#include "pt2_replayer.h"#include "pt2_visuals_sync.h" static const int8_t scancode2NoteLo[52] = // "USB usage page standard" order{	 7,  4,  3, 16, -1,  6,  8, 24,	10, -1, 13, 11,  9, 26, 28, 12,	17,  1, 19, 23,  5, 14,  2, 21,	 0, -1, 13, 15, -1, 18, 20, 22,	-1, 25, 27, -1, -1, -1, -1, -1,	-1, 30, 29, 31, 30, -1, 15, -1,	-1, 12, 14, 16}; static const int8_t scancode2NoteHi[52] = // "USB usage page standard" order{	19, 16, 15, 28, -1, 18, 20, -2,	22, -1, 25, 23, 21, -2, -2, 24,	29, 13, 31, 35, 17, 26, 14, 33,	12, -1, 25, 27, -1, 30, 32, 34,	-1, -2, -2, -1, -1, -1, -1, -1,	-1, -2, -2, -2, -2, -1, 27, -1,	-1, 24, 26, 28}; static uint8_t quantizeCheck(uint8_t row){	assert(song != NULL);	if (song == NULL)		return row; 	const uint8_t quantize = (uint8_t)config.quantizeValue; 	editor.didQuantize = false;	if (editor.currMode == MODE_RECORD)	{		if (quantize == 0)		{			return row;		}		else if (quantize == 1)		{			if (song->tick > song->speed>>1)			{				row = (row + 1) & 63;				editor.didQuantize = true;			}		}		else		{			uint8_t tempRow = ((((quantize >> 1) + row) & 63) / quantize) * quantize;			if (tempRow > row)				editor.didQuantize = true; 			return tempRow;		}	} 	return row;} static void jamAndPlaceSample(SDL_Scancode scancode, bool normalMode){	uint8_t chNum = cursor.channel;	assert(chNum < PAULA_VOICES); 	moduleChannel_t *ch = &song->channels[chNum];	note_t *note = &song->patterns[song->currPattern][(quantizeCheck(song->currRow) * PAULA_VOICES) + chNum]; 	int8_t noteVal = normalMode ? keyToNote(scancode) : pNoteTable[editor.currSample];	if (noteVal >= 0)	{		moduleSample_t *s = &song->samples[editor.currSample]; 		int16_t tempPeriod  = periodTable[((s->fineTune & 0xF) * 37) + noteVal];		uint16_t cleanPeriod = periodTable[noteVal]; 		editor.currPlayNote = noteVal; 		// play current sample 		// don't play sample if we quantized to another row (will be played in modplayer instead)		if (editor.currMode != MODE_RECORD || !editor.didQuantize)		{			lockAudio(); 			ch->n_samplenum = editor.currSample;			ch->n_volume = s->volume;			ch->n_period = tempPeriod;			ch->n_start = &song->sampleData[s->offset];			ch->n_length = (uint16_t)((s->loopStart > 0) ? (s->loopStart + s->loopLength) >> 1 : s->length >> 1);			ch->n_loopstart = &song->sampleData[s->offset + s->loopStart];			ch->n_replen = (uint16_t)(s->loopLength >> 1); 			if (ch->n_length == 0)				ch->n_length = 1; 			const uint32_t voiceAddr = 0xDFF0A0 + (chNum * 16);			paulaWriteWord(voiceAddr + 8, ch->n_volume);			paulaWriteWord(voiceAddr + 6, ch->n_period);			paulaWritePtr(voiceAddr + 0, ch->n_start);			paulaWriteWord(voiceAddr + 4, ch->n_length); 			if (!editor.muted[chNum])				paulaWriteWord(0xDFF096, 0x8000 | ch->n_dmabit); // voice DMA on			else				paulaWriteWord(0xDFF096, ch->n_dmabit); // voice DMA off 			// these take effect after the current DMA cycle is done			paulaWritePtr(voiceAddr + 0, ch->n_loopstart);			paulaWriteWord(voiceAddr + 4, ch->n_replen); 			// update tracker visuals 			setVisualsVolume(chNum, ch->n_volume);			setVisualsPeriod(chNum, ch->n_period);			setVisualsDataPtr(chNum, ch->n_start);			setVisualsLength(chNum, ch->n_length); 			if (!editor.muted[chNum])				setVisualsDMACON(0x8000 | ch->n_dmabit);			else				setVisualsDMACON(ch->n_dmabit); 			setVisualsDataPtr(chNum, ch->n_loopstart);			setVisualsLength(chNum, ch->n_replen); 			unlockAudio();		} 		// normalMode = normal keys, or else keypad keys (in jam mode)		if (normalMode || editor.pNoteFlag != 0)		{			if (normalMode || editor.pNoteFlag == 2)			{				// insert note and sample number				if (!ui.samplerScreenShown && (editor.currMode == MODE_EDIT || editor.currMode == MODE_RECORD))				{					note->sample = editor.sampleZero ? 0 : (editor.currSample + 1);					note->period = cleanPeriod; 					if (editor.autoInsFlag)					{						note->command = editor.effectMacros[editor.autoInsSlot] >> 8;						note->param = editor.effectMacros[editor.autoInsSlot] & 0xFF;					} 					if (editor.currMode != MODE_RECORD)						modSetPos(DONT_SET_ORDER, (song->currRow + editor.editMoveAdd) & 63); 					updateWindowTitle(MOD_IS_MODIFIED);				}			} 			if (editor.multiFlag)				gotoNextMulti();		} 		// PT quirk: spectrum analyzer is still handled here even if channel is muted		updateSpectrumAnalyzer(s->volume, tempPeriod);	}	else if (noteVal == -2)	{		// delete note and sample if illegal note (= -2, -1 = ignore) key was entered 		if (normalMode || editor.pNoteFlag == 2)		{			if (!ui.samplerScreenShown && (editor.currMode == MODE_EDIT || editor.currMode == MODE_RECORD))			{				note->period = 0;				note->sample = 0; 				if (editor.currMode != MODE_RECORD)					modSetPos(DONT_SET_ORDER, (song->currRow + editor.editMoveAdd) & 63); 				updateWindowTitle(MOD_IS_MODIFIED);			}		}	}} void handleEditKeys(SDL_Scancode scancode, bool normalMode){	if (ui.editTextFlag)		return; 	if (ui.samplerScreenShown || (editor.currMode == MODE_IDLE || editor.currMode == MODE_PLAY))	{		// at this point it will only jam, not place it		if (!keyb.leftAltPressed && !keyb.leftAmigaPressed && !keyb.leftCtrlPressed && !keyb.shiftPressed)			jamAndPlaceSample(scancode, normalMode); 		return;	} 	// handle modified (ALT/CTRL/SHIFT etc) keys for editing	if (editor.currMode == MODE_EDIT || editor.currMode == MODE_RECORD)	{		if (handleSpecialKeys(scancode))		{			if (editor.currMode != MODE_RECORD)				modSetPos(DONT_SET_ORDER, (song->currRow + editor.editMoveAdd) & 63); 			return;		}	} 	// are we editing a note, or other stuff?	if (cursor.mode != CURSOR_NOTE)	{		// if we held down any key modifier at this point, then do nothing		if (keyb.leftAltPressed || keyb.leftAmigaPressed || keyb.leftCtrlPressed || keyb.shiftPressed)			return; 		if (editor.currMode == MODE_EDIT || editor.currMode == MODE_RECORD)		{			int8_t hexKey, numberKey; 			if (scancode == SDL_SCANCODE_0)				numberKey = 0;			else if (scancode >= SDL_SCANCODE_1 && scancode <= SDL_SCANCODE_9)				numberKey = (int8_t)scancode - (SDL_SCANCODE_1-1);			else				numberKey = -1; 			if (scancode >= SDL_SCANCODE_A && scancode <= SDL_SCANCODE_F)				hexKey = 10 + ((int8_t)scancode - SDL_SCANCODE_A);			else				hexKey = -1; 			int8_t key = -1;			if (numberKey != -1)			{				if (key == -1)					key = 0; 				key += numberKey;			} 			if (hexKey != -1)			{				if (key == -1)					key = 0; 				key += hexKey;			} 			note_t *note = &song->patterns[song->currPattern][(song->currRow * PAULA_VOICES) + cursor.channel];			switch (cursor.mode)			{				case CURSOR_SAMPLE1:				{					if (key != -1 && key < 2)					{						note->sample = (uint8_t)((note->sample & 0x0F) | (key << 4)); 						if (editor.currMode != MODE_RECORD)							modSetPos(DONT_SET_ORDER, (song->currRow + editor.editMoveAdd) & 63); 						updateWindowTitle(MOD_IS_MODIFIED);					}				}				break; 				case CURSOR_SAMPLE2:				{					if (key != -1 && key < 16)					{						note->sample = (uint8_t)((note->sample & 0xF0) | key); 						if (editor.currMode != MODE_RECORD)							modSetPos(DONT_SET_ORDER, (song->currRow + editor.editMoveAdd) & 63); 						updateWindowTitle(MOD_IS_MODIFIED);					}				}				break; 				case CURSOR_CMD:				{					if (key != -1 && key < 16)					{						note->command = (uint8_t)key; 						if (editor.currMode != MODE_RECORD)							modSetPos(DONT_SET_ORDER, (song->currRow + editor.editMoveAdd) & 63); 						updateWindowTitle(MOD_IS_MODIFIED);					}				}				break; 				case CURSOR_PARAM1:				{					if (key != -1 && key < 16)					{						note->param = (uint8_t)((note->param & 0x0F) | (key << 4)); 						if (editor.currMode != MODE_RECORD)							modSetPos(DONT_SET_ORDER, (song->currRow + editor.editMoveAdd) & 63); 						updateWindowTitle(MOD_IS_MODIFIED);					}				}				break; 				case CURSOR_PARAM2:				{					if (key != -1 && key < 16)					{						note->param = (uint8_t)((note->param & 0xF0) | key); 						if (editor.currMode != MODE_RECORD)							modSetPos(DONT_SET_ORDER, (song->currRow + editor.editMoveAdd) & 63); 						updateWindowTitle(MOD_IS_MODIFIED);					}				}				break; 				default: break;			}		}	}	else	{		if (scancode == SDL_SCANCODE_DELETE)		{			if (editor.currMode == MODE_EDIT || editor.currMode == MODE_RECORD)			{				note_t *note = &song->patterns[song->currPattern][(song->currRow * PAULA_VOICES) + cursor.channel]; 				if (!keyb.leftAltPressed)				{					note->sample = 0;					note->period = 0;				} 				if (keyb.shiftPressed || keyb.leftAltPressed)				{					note->command = 0;					note->param = 0;				} 				if (editor.currMode != MODE_RECORD)					modSetPos(DONT_SET_ORDER, (song->currRow + editor.editMoveAdd) & 63); 				updateWindowTitle(MOD_IS_MODIFIED);			}		}		else		{			// if we held down any key modifier at this point, then do nothing			if (keyb.leftAltPressed || keyb.leftAmigaPressed || keyb.leftCtrlPressed || keyb.shiftPressed)				return; 			jamAndPlaceSample(scancode, normalMode);		}	}} bool handleSpecialKeys(SDL_Scancode scancode){	if (!keyb.leftAltPressed)		return false; 	note_t *patt = song->patterns[song->currPattern];	note_t *note = &patt[(song->currRow * PAULA_VOICES) + cursor.channel];	note_t *prevNote = &patt[(((song->currRow - 1) & 63) * PAULA_VOICES) + cursor.channel]; 	if (scancode >= SDL_SCANCODE_1 && scancode <= SDL_SCANCODE_0)	{		// insert stored effect (buffer[0..8])		note->command = editor.effectMacros[scancode - SDL_SCANCODE_1] >> 8;		note->param = editor.effectMacros[scancode - SDL_SCANCODE_1] & 0xFF; 		updateWindowTitle(MOD_IS_MODIFIED);		return true;	} 	// copy command+effect from above into current command+effect	if (scancode == SDL_SCANCODE_BACKSLASH)	{		note->command = prevNote->command;		note->param = prevNote->param; 		updateWindowTitle(MOD_IS_MODIFIED);		return true;	} 	// copy command+(effect + 1) from above into current command+effect	if (scancode == SDL_SCANCODE_EQUALS)	{		note->command = prevNote->command;		note->param = prevNote->param + 1; // wraps 0x00..0xFF 		updateWindowTitle(MOD_IS_MODIFIED);		return true;	} 	// copy command+(effect - 1) from above into current command+effect	if (scancode == SDL_SCANCODE_MINUS)	{		note->command = prevNote->command;		note->param = prevNote->param - 1; // wraps 0x00..0xFF 		updateWindowTitle(MOD_IS_MODIFIED);		return true;	} 	return false;} void handleSampleJamming(SDL_Scancode scancode) // used for the sampling feature (in SAMPLER){	const int32_t chNum = cursor.channel; 	if (scancode == SDL_SCANCODE_NONUSBACKSLASH)	{		turnOffVoices(); // magic "kill all voices" button		return;	} 	int8_t noteVal = keyToNote(scancode);	if (noteVal < 0 || noteVal > 35)		return; 	moduleSample_t *s = &song->samples[editor.currSample];	if (s->length <= 1)		return; 	moduleChannel_t *ch = &song->channels[chNum]; 	int8_t *n_start = &song->sampleData[s->offset];	int8_t vol = 64;	uint16_t n_length = (uint16_t)(s->length >> 1);	uint16_t period = periodTable[((s->fineTune & 0xF) * 37) + noteVal]; 	lockAudio(); 	ch->n_samplenum = editor.currSample; // needed for sample playback/sampling line 	const uint32_t voiceAddr = 0xDFF0A0 + (chNum * 16);	paulaWriteWord(voiceAddr +  8, vol);	paulaWriteWord(voiceAddr + 6, period);	paulaWritePtr(voiceAddr + 0, n_start);	paulaWriteWord(voiceAddr + 4, n_length); 	if (!editor.muted[chNum])		paulaWriteWord(0xDFF096, 0x8000 | ch->n_dmabit); // voice DMA on	else		paulaWriteWord(0xDFF096, ch->n_dmabit); // voice DMA off 	// these take effect after the current DMA cycle is done	paulaWritePtr(voiceAddr + 0, NULL); // data	paulaWriteWord(voiceAddr + 4, 1); // length 	// update tracker visuals 	setVisualsVolume(chNum, vol);	setVisualsPeriod(chNum, period);	setVisualsDataPtr(chNum, n_start);	setVisualsLength(chNum, n_length); 	if (!editor.muted[chNum])		setVisualsDMACON(0x8000 | ch->n_dmabit);	else		setVisualsDMACON(ch->n_dmabit); 	setVisualsDataPtr(chNum, NULL);	setVisualsLength(chNum, 1); 	unlockAudio();}

Lines 1–500 of 1118.

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