2779 lines · 59.0 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 "ft2_header.h"#include "ft2_config.h"#include "ft2_pattern_ed.h"#include "ft2_gui.h"#include "ft2_sample_ed.h"#include "ft2_pattern_draw.h"#include "ft2_inst_ed.h"#include "scopes/ft2_scopes.h"#include "ft2_diskop.h"#include "ft2_audio.h"#include "ft2_wav_renderer.h"#include "ft2_mouse.h"#include "ft2_video.h"#include "ft2_tables.h"#include "ft2_bmp.h"#include "ft2_structs.h"  // for pattern marking w/ keyboardstatic int8_t lastChMark;static int16_t lastRowMark; // for pattern marking w/ mousestatic int32_t lastMarkX1 = -1, lastMarkX2 = -1, lastMarkY1 = -1, lastMarkY2 = -1; static const uint8_t ptnNumRows[8] = { 27, 25, 20, 19, 42, 40, 31, 30 };static const uint8_t ptnLineSub[8] = { 13, 12,  9,  9, 20, 19, 15, 14 };static const uint8_t iSwitchExtW[4] = { 40, 40, 40, 39 };static const uint8_t iSwitchExtY[8] = { 2, 2, 2, 2, 19, 19, 19, 19 };static const uint8_t iSwitchY[8] = { 2, 19, 36, 53, 73, 90, 107, 124 };static const uint16_t iSwitchExtX[4] = { 221, 262, 303, 344 }; static int32_t lastMouseX, lastMouseY;static int32_t last_TimeH, last_TimeM, last_TimeS; static note_t tmpPattern[MAX_CHANNELS * MAX_PATT_LEN]; pattMark_t pattMark; // globalized bool allocatePattern(uint16_t pattNum) // for tracker use only, not in loader!{	const bool audioWasntLocked = !audio.locked;	if (audioWasntLocked)		lockAudio(); 	if (pattern[pattNum] == NULL)	{		/* Original FT2 allocates only the amount of rows needed, but we don't		** do that to avoid out of bondary row look-up between out-of-sync replayer		** state and tracker state (yes it used to happen, rarely). We're not wasting		** too much RAM for a modern computer anyway. Worst case: 256 allocated		** patterns would be ~10MB.		**/ 		pattern[pattNum] = (note_t *)calloc((MAX_PATT_LEN * TRACK_WIDTH) + 16, 1);		if (pattern[pattNum] == NULL)		{			if (audioWasntLocked)				unlockAudio(); 			return false;		} 		song.currNumRows = patternNumRows[pattNum];	} 	if (audioWasntLocked)		unlockAudio(); 	return true;} void killPatternIfUnused(uint16_t pattNum) // for tracker use only, not in loader!{	const bool audioWasntLocked = !audio.locked;	if (audioWasntLocked)		lockAudio(); 	if (patternEmpty(pattNum))	{		if (pattern[pattNum] != NULL)		{			free(pattern[pattNum]);			pattern[pattNum] = NULL;		}	} 	if (audioWasntLocked)		unlockAudio();} uint8_t getMaxVisibleChannels(void){	assert(config.ptnMaxChannels >= 0 && config.ptnMaxChannels <= 3);	if (config.ptnShowVolColumn)		return maxVisibleChans1[config.ptnMaxChannels];	else		return maxVisibleChans2[config.ptnMaxChannels];} void updatePatternWidth(void){	if (ui.numChannelsShown > ui.maxVisibleChannels)		ui.numChannelsShown = ui.maxVisibleChannels; 	assert(ui.numChannelsShown >= 2 && ui.numChannelsShown <= 12); 	ui.patternChannelWidth = chanWidths[(ui.numChannelsShown / 2) - 1] + 3;} void updateAdvEdit(void){	hexOutBg(92, 113, PAL_FORGRND, PAL_DESKTOP, editor.srcInstr, 2);	hexOutBg(92, 126, PAL_FORGRND, PAL_DESKTOP, editor.curInstr, 2);} void setAdvEditCheckBoxes(void){	checkBoxes[CB_ENABLE_MASKING].checked = editor.copyMaskEnable;	checkBoxes[CB_COPY_MASK_0].checked = editor.copyMask[0];	checkBoxes[CB_COPY_MASK_1].checked = editor.copyMask[1];	checkBoxes[CB_COPY_MASK_2].checked = editor.copyMask[2];	checkBoxes[CB_COPY_MASK_3].checked = editor.copyMask[3];	checkBoxes[CB_COPY_MASK_4].checked = editor.copyMask[4];	checkBoxes[CB_PASTE_MASK_0].checked = editor.pasteMask[0];	checkBoxes[CB_PASTE_MASK_1].checked = editor.pasteMask[1];	checkBoxes[CB_PASTE_MASK_2].checked = editor.pasteMask[2];	checkBoxes[CB_PASTE_MASK_3].checked = editor.pasteMask[3];	checkBoxes[CB_PASTE_MASK_4].checked = editor.pasteMask[4];	checkBoxes[CB_TRANSP_MASK_0].checked = editor.transpMask[0];	checkBoxes[CB_TRANSP_MASK_1].checked = editor.transpMask[1];	checkBoxes[CB_TRANSP_MASK_2].checked = editor.transpMask[2];	checkBoxes[CB_TRANSP_MASK_3].checked = editor.transpMask[3];	checkBoxes[CB_TRANSP_MASK_4].checked = editor.transpMask[4]; 	showCheckBox(CB_ENABLE_MASKING);	showCheckBox(CB_COPY_MASK_0);	showCheckBox(CB_COPY_MASK_1);	showCheckBox(CB_COPY_MASK_2);	showCheckBox(CB_COPY_MASK_3);	showCheckBox(CB_COPY_MASK_4);	showCheckBox(CB_PASTE_MASK_0);	showCheckBox(CB_PASTE_MASK_1);	showCheckBox(CB_PASTE_MASK_2);	showCheckBox(CB_PASTE_MASK_3);	showCheckBox(CB_PASTE_MASK_4);	showCheckBox(CB_TRANSP_MASK_0);	showCheckBox(CB_TRANSP_MASK_1);	showCheckBox(CB_TRANSP_MASK_2);	showCheckBox(CB_TRANSP_MASK_3);	showCheckBox(CB_TRANSP_MASK_4);} void drawAdvEdit(void){	drawFramework(  0,  92, 110,  17, FRAMEWORK_TYPE1);	drawFramework(  0, 109, 110,  64, FRAMEWORK_TYPE1);	drawFramework(110,  92, 124,  81, FRAMEWORK_TYPE1);	drawFramework(234,  92,  19,  81, FRAMEWORK_TYPE1);	drawFramework(253,  92,  19,  81, FRAMEWORK_TYPE1);	drawFramework(272,  92,  19,  81, FRAMEWORK_TYPE1); 	textOutShadow(  4,  96, PAL_FORGRND, PAL_DSKTOP2, "Instr. remap:");	textOutShadow(  4, 113, PAL_FORGRND, PAL_DSKTOP2, "Old number");	textOutShadow(  4, 126, PAL_FORGRND, PAL_DSKTOP2, "New number");	textOutShadow(129,  96, PAL_FORGRND, PAL_DSKTOP2, "Masking enable");	textOutShadow(114, 109, PAL_FORGRND, PAL_DSKTOP2, "Note");	textOutShadow(114, 122, PAL_FORGRND, PAL_DSKTOP2, "Instrument number");	textOutShadow(114, 135, PAL_FORGRND, PAL_DSKTOP2, "Volume column");	textOutShadow(114, 148, PAL_FORGRND, PAL_DSKTOP2, "Effect digit 1");	textOutShadow(114, 161, PAL_FORGRND, PAL_DSKTOP2, "Effect digit 2,3"); 	charOutShadow(239, 95, PAL_FORGRND, PAL_DSKTOP2, 'C');	charOutShadow(258, 95, PAL_FORGRND, PAL_DSKTOP2, 'P');	charOutShadow(277, 95, PAL_FORGRND, PAL_DSKTOP2, 'T'); 	showPushButton(PB_REMAP_TRACK);	showPushButton(PB_REMAP_PATTERN);	showPushButton(PB_REMAP_SONG);	showPushButton(PB_REMAP_BLOCK); 	setAdvEditCheckBoxes(); 	updateAdvEdit();} void hideAdvEdit(void){	ui.advEditShown = false; 	hidePushButton(PB_REMAP_TRACK);	hidePushButton(PB_REMAP_PATTERN);	hidePushButton(PB_REMAP_SONG);	hidePushButton(PB_REMAP_BLOCK); 	hideCheckBox(CB_ENABLE_MASKING);	hideCheckBox(CB_COPY_MASK_0);	hideCheckBox(CB_COPY_MASK_1);	hideCheckBox(CB_COPY_MASK_2);	hideCheckBox(CB_COPY_MASK_3);	hideCheckBox(CB_COPY_MASK_4);	hideCheckBox(CB_PASTE_MASK_0);	hideCheckBox(CB_PASTE_MASK_1);	hideCheckBox(CB_PASTE_MASK_2);	hideCheckBox(CB_PASTE_MASK_3);	hideCheckBox(CB_PASTE_MASK_4);	hideCheckBox(CB_TRANSP_MASK_0);	hideCheckBox(CB_TRANSP_MASK_1);	hideCheckBox(CB_TRANSP_MASK_2);	hideCheckBox(CB_TRANSP_MASK_3);	hideCheckBox(CB_TRANSP_MASK_4); 	ui.scopesShown = true;	drawScopeFramework();} void showAdvEdit(void){	if (ui.extended)		exitPatternEditorExtended(); 	hideTopScreen();	showTopScreen(false); 	ui.advEditShown = true;	ui.scopesShown  = false;	drawAdvEdit();} void toggleAdvEdit(void){	if (ui.advEditShown)		hideAdvEdit();	else		showAdvEdit();} void drawTranspose(void){	drawFramework(0,    92,  53,  16, FRAMEWORK_TYPE1);	drawFramework(53,   92, 119,  16, FRAMEWORK_TYPE1);	drawFramework(172,  92, 119,  16, FRAMEWORK_TYPE1);	drawFramework(0,   108,  53,  65, FRAMEWORK_TYPE1);	drawFramework(53,  108, 119,  65, FRAMEWORK_TYPE1);	drawFramework(172, 108, 119,  65, FRAMEWORK_TYPE1); 	textOutShadow(4,    95, PAL_FORGRND, PAL_DSKTOP2, "Transp.");	textOutShadow(58,   95, PAL_FORGRND, PAL_DSKTOP2, "Current instrument");	textOutShadow(188,  95, PAL_FORGRND, PAL_DSKTOP2, "All instruments");	textOutShadow(4,   114, PAL_FORGRND, PAL_DSKTOP2, "Track");	textOutShadow(4,   129, PAL_FORGRND, PAL_DSKTOP2, "Pattern");	textOutShadow(4,   144, PAL_FORGRND, PAL_DSKTOP2, "Song");	textOutShadow(4,   159, PAL_FORGRND, PAL_DSKTOP2, "Block"); 	showPushButton(PB_TRANSP_CUR_INS_TRK_UP);	showPushButton(PB_TRANSP_CUR_INS_TRK_DN);	showPushButton(PB_TRANSP_CUR_INS_TRK_12UP);	showPushButton(PB_TRANSP_CUR_INS_TRK_12DN);	showPushButton(PB_TRANSP_ALL_INS_TRK_UP);	showPushButton(PB_TRANSP_ALL_INS_TRK_DN);	showPushButton(PB_TRANSP_ALL_INS_TRK_12UP);	showPushButton(PB_TRANSP_ALL_INS_TRK_12DN);	showPushButton(PB_TRANSP_CUR_INS_PAT_UP);	showPushButton(PB_TRANSP_CUR_INS_PAT_DN);	showPushButton(PB_TRANSP_CUR_INS_PAT_12UP);	showPushButton(PB_TRANSP_CUR_INS_PAT_12DN);	showPushButton(PB_TRANSP_ALL_INS_PAT_UP);	showPushButton(PB_TRANSP_ALL_INS_PAT_DN);	showPushButton(PB_TRANSP_ALL_INS_PAT_12UP);	showPushButton(PB_TRANSP_ALL_INS_PAT_12DN);	showPushButton(PB_TRANSP_CUR_INS_SNG_UP);	showPushButton(PB_TRANSP_CUR_INS_SNG_DN);	showPushButton(PB_TRANSP_CUR_INS_SNG_12UP);	showPushButton(PB_TRANSP_CUR_INS_SNG_12DN);	showPushButton(PB_TRANSP_ALL_INS_SNG_UP);	showPushButton(PB_TRANSP_ALL_INS_SNG_DN);	showPushButton(PB_TRANSP_ALL_INS_SNG_12UP);	showPushButton(PB_TRANSP_ALL_INS_SNG_12DN);	showPushButton(PB_TRANSP_CUR_INS_BLK_UP);	showPushButton(PB_TRANSP_CUR_INS_BLK_DN);	showPushButton(PB_TRANSP_CUR_INS_BLK_12UP);	showPushButton(PB_TRANSP_CUR_INS_BLK_12DN);	showPushButton(PB_TRANSP_ALL_INS_BLK_UP);	showPushButton(PB_TRANSP_ALL_INS_BLK_DN);	showPushButton(PB_TRANSP_ALL_INS_BLK_12UP);	showPushButton(PB_TRANSP_ALL_INS_BLK_12DN);} void showTranspose(void){	if (ui.extended)		exitPatternEditorExtended(); 	hideTopScreen();	showTopScreen(false); 	ui.transposeShown = true;	ui.scopesShown = false;	drawTranspose();} void hideTranspose(void){	hidePushButton(PB_TRANSP_CUR_INS_TRK_UP);	hidePushButton(PB_TRANSP_CUR_INS_TRK_DN);	hidePushButton(PB_TRANSP_CUR_INS_TRK_12UP);	hidePushButton(PB_TRANSP_CUR_INS_TRK_12DN);	hidePushButton(PB_TRANSP_ALL_INS_TRK_UP);	hidePushButton(PB_TRANSP_ALL_INS_TRK_DN);	hidePushButton(PB_TRANSP_ALL_INS_TRK_12UP);	hidePushButton(PB_TRANSP_ALL_INS_TRK_12DN);	hidePushButton(PB_TRANSP_CUR_INS_PAT_UP);	hidePushButton(PB_TRANSP_CUR_INS_PAT_DN);	hidePushButton(PB_TRANSP_CUR_INS_PAT_12UP);	hidePushButton(PB_TRANSP_CUR_INS_PAT_12DN);	hidePushButton(PB_TRANSP_ALL_INS_PAT_UP);	hidePushButton(PB_TRANSP_ALL_INS_PAT_DN);	hidePushButton(PB_TRANSP_ALL_INS_PAT_12UP);	hidePushButton(PB_TRANSP_ALL_INS_PAT_12DN);	hidePushButton(PB_TRANSP_CUR_INS_SNG_UP);	hidePushButton(PB_TRANSP_CUR_INS_SNG_DN);	hidePushButton(PB_TRANSP_CUR_INS_SNG_12UP);	hidePushButton(PB_TRANSP_CUR_INS_SNG_12DN);	hidePushButton(PB_TRANSP_ALL_INS_SNG_UP);	hidePushButton(PB_TRANSP_ALL_INS_SNG_DN);	hidePushButton(PB_TRANSP_ALL_INS_SNG_12UP);	hidePushButton(PB_TRANSP_ALL_INS_SNG_12DN);	hidePushButton(PB_TRANSP_CUR_INS_BLK_UP);	hidePushButton(PB_TRANSP_CUR_INS_BLK_DN);	hidePushButton(PB_TRANSP_CUR_INS_BLK_12UP);	hidePushButton(PB_TRANSP_CUR_INS_BLK_12DN);	hidePushButton(PB_TRANSP_ALL_INS_BLK_UP);	hidePushButton(PB_TRANSP_ALL_INS_BLK_DN);	hidePushButton(PB_TRANSP_ALL_INS_BLK_12UP);	hidePushButton(PB_TRANSP_ALL_INS_BLK_12DN); 	ui.transposeShown = false;	ui.scopesShown = true;	drawScopeFramework();} void toggleTranspose(void){	if (ui.transposeShown)		hideTranspose();	else		showTranspose();} // ----- PATTERN CURSOR FUNCTIONS ----- void cursorChannelLeft(void){	cursor.object = CURSOR_EFX2; 	if (cursor.ch == 0)	{		cursor.ch = (uint8_t)(song.numChannels - 1);		if (ui.pattChanScrollShown)			setScrollBarPos(SB_CHAN_SCROLL, song.numChannels, true);	}	else	{		cursor.ch--;		if (ui.pattChanScrollShown)		{			if (cursor.ch < ui.channelOffset)				scrollBarScrollUp(SB_CHAN_SCROLL, 1);		}	}} void cursorChannelRight(void){	cursor.object = CURSOR_NOTE; 	if (cursor.ch >= song.numChannels-1)	{		cursor.ch = 0;		if (ui.pattChanScrollShown)			setScrollBarPos(SB_CHAN_SCROLL, 0, true);	}	else	{		cursor.ch++;		if (ui.pattChanScrollShown && cursor.ch >= ui.channelOffset+ui.numChannelsShown)			scrollBarScrollDown(SB_CHAN_SCROLL, 1);	}} void cursorTabLeft(void){	if (cursor.object == CURSOR_NOTE)		cursorChannelLeft(); 	cursor.object = CURSOR_NOTE;	ui.updatePatternEditor = true;} void cursorTabRight(void){	cursorChannelRight();	cursor.object = CURSOR_NOTE;	ui.updatePatternEditor = true;} void chanLeft(void){	cursorChannelLeft();	cursor.object = CURSOR_NOTE;	ui.updatePatternEditor = true;} void chanRight(void){	cursorChannelRight();	cursor.object = CURSOR_NOTE;	ui.updatePatternEditor = true;} void cursorLeft(void){	cursor.object--; 	if (!config.ptnShowVolColumn)	{		while (cursor.object == CURSOR_VOL1 || cursor.object == CURSOR_VOL2)			cursor.object--;	} 	if (cursor.object == -1)	{		cursor.object = CURSOR_EFX2;		cursorChannelLeft();	} 	ui.updatePatternEditor = true;} void cursorRight(void){	cursor.object++; 	if (!config.ptnShowVolColumn)	{		while (cursor.object == CURSOR_VOL1 || cursor.object == CURSOR_VOL2)			cursor.object++;	} 	if (cursor.object == 8)	{		cursor.object = CURSOR_NOTE;		cursorChannelRight();	} 	ui.updatePatternEditor = true;} void showPatternEditor(void){	ui.patternEditorShown = true;	updateChanNums();	drawPatternBorders();	ui.updatePatternEditor = true;} void hidePatternEditor(void){	hideScrollBar(SB_CHAN_SCROLL);	hidePushButton(PB_CHAN_SCROLL_LEFT);	hidePushButton(PB_CHAN_SCROLL_RIGHT); 	ui.patternEditorShown = false;} static void updatePatternEditorGUI(void){	uint16_t i;	pushButton_t *p;	textBox_t *t; 	if (ui.extended)	{		// extended pattern editor 		// instrument names		t = &textBoxes[TB_INST1];		for (i = 0; i < 8; i++, t++)		{			if (i < 4)			{				t->x = 406;

Lines 1–500 of 2779.

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