Olav SørensenPushed v1.62 code4188e803 years agoHistory
1329 lines · 29.6 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 <ctype.h>#include "pt2_textout.h"#include "pt2_visuals.h"#include "pt2_helpers.h"#include "pt2_replayer.h"#include "pt2_bmp.h"#include "pt2_mouse.h"#include "pt2_edit.h"#include "pt2_config.h"#include "pt2_diskop.h"#include "pt2_sampler.h"#include "pt2_audio.h"#include "pt2_chordmaker.h"#include "pt2_textedit.h" // PATH_MAX is the absolute longest editable string possiblestatic char oldText[PATH_MAX+2];static uint32_t oldTextLength; void renderTextEditCursor(void){	if (!ui.editTextFlag)		return; 	const int32_t x = textEdit.cursorStartX + (textEdit.cursorBlock * FONT_CHAR_W);	const int32_t y = textEdit.cursorStartY;	const int32_t w = 7;	const int32_t h = 2; 	if (x < 0 || x+w >= SCREEN_W || y < 0 || y+h >= SCREEN_H)		return; 	fillRect(x, y, w, h, video.palette[PAL_TEXTMARK]);} void removeTextEditCursor(void){	if (!ui.editTextFlag)		return; 	const int32_t x = textEdit.cursorStartX + (textEdit.cursorBlock * FONT_CHAR_W);	const int32_t y = textEdit.cursorStartY;	const int32_t w = 7;	const int32_t h = 2; 	if (x < 0 || x+w >= SCREEN_W || y < 0 || y+h >= SCREEN_H)		return; 	if (textEdit.object == PTB_PE_PATT || textEdit.object == PTB_PE_PATTNAME)	{		// position editor text editing needs different handling 		// rewrite border pixels (below second row of text edit cursor)		hLine(x, y, w, video.palette[PAL_GENBKG2]); 		ui.updatePosEd = true; // this also erases the first row of the text edit cursor	}	else	{		// all others		fillRect(x, y, w, h, video.palette[PAL_GENBKG]);	}} static void moveTextCursorLeft(void){	if (textEdit.cursorBlock > 0)	{		removeTextEditCursor();		textEdit.cursorBlock--;		renderTextEditCursor();	}	else if (textEdit.scrollable)	{		if (textEdit.scrollOffset > 0)		{			textEdit.scrollOffset--; 			if (textEdit.object == PTB_DO_DATAPATH)				ui.updateDiskOpPathText = true;			else if (textEdit.object == PTB_PE_PATTNAME)				ui.updatePosEd = true;		}	}} static void moveTextCursorRight(void){	if (textEdit.type == TEXT_EDIT_STRING)	{		if (textEdit.cursorBlock < textEdit.numBlocks-1)		{			removeTextEditCursor();			textEdit.cursorBlock++;			renderTextEditCursor();		}		else if (textEdit.scrollable)		{			if (textEdit.textPtr <= textEdit.textEndPtr)			{				textEdit.scrollOffset++; 				if (textEdit.object == PTB_DO_DATAPATH)					ui.updateDiskOpPathText = true;				else if (textEdit.object == PTB_PE_PATTNAME)					ui.updatePosEd = true;			}		}	}	else	{		// we end up here when entering a number/hex digit 		if (textEdit.cursorBlock < textEdit.numDigits)			removeTextEditCursor(); 		textEdit.cursorBlock++; 		if (textEdit.cursorBlock < textEdit.numDigits)			renderTextEditCursor(); 		// don't clamp now, textEdit.cursorBlock is tested elsewhere	}} void editTextPrevChar(void){	if (textEdit.type != TEXT_EDIT_STRING)	{		if (textEdit.cursorBlock > 0)		{			removeTextEditCursor();			textEdit.cursorBlock--;			renderTextEditCursor();		} 		return;	} 	if (editor.mixFlag && textEdit.cursorBlock <= 4) // kludge...		return; 	if (textEdit.textPtr > textEdit.textStartPtr)	{		removeTextEditCursor(); 		textEdit.textPtr--;		moveTextCursorLeft(); 		if (editor.mixFlag) // special case for "Mix" input field in Edit. Op.		{			if (textEdit.cursorBlock == 12)			{				textEdit.textPtr--; moveTextCursorLeft();				textEdit.textPtr--; moveTextCursorLeft();				textEdit.textPtr--; moveTextCursorLeft();				textEdit.textPtr--; moveTextCursorLeft();			}			else if (textEdit.cursorBlock == 6)			{				textEdit.textPtr--;				moveTextCursorLeft();			}		} 		renderTextEditCursor();	} 	textEdit.endReached = false;} void editTextNextChar(void){	if (textEdit.type != TEXT_EDIT_STRING)	{		if (textEdit.cursorBlock < textEdit.numDigits-1)		{			removeTextEditCursor();			textEdit.cursorBlock++;			renderTextEditCursor();		} 		return;	} 	if (editor.mixFlag && textEdit.cursorBlock >= 14) // kludge		return; 	if (textEdit.textPtr < textEdit.textEndPtr)	{		if (*textEdit.textPtr != '\0')		{			removeTextEditCursor(); 			textEdit.textPtr++;			moveTextCursorRight(); 			if (editor.mixFlag) // special case for "Mix" input field in Edit. Op.			{				if (textEdit.cursorBlock == 9)				{					textEdit.textPtr++; moveTextCursorRight();					textEdit.textPtr++; moveTextCursorRight();					textEdit.textPtr++; moveTextCursorRight();					textEdit.textPtr++; moveTextCursorRight();				}				else if (textEdit.cursorBlock == 6)				{					textEdit.textPtr++;					moveTextCursorRight();				}			} 			renderTextEditCursor();		}		else		{			textEdit.endReached = true;		}	}	else	{		textEdit.endReached = true;	}} void handleTextEditing(uint8_t mouseButton) // handle mouse while editing text/numbers{	if (!ui.editTextFlag)		return; 	if (textEdit.type != TEXT_EDIT_STRING)	{		if (mouseButton == SDL_BUTTON_RIGHT)			leaveTextEditMode(EDIT_TEXT_NO_UPDATE);	}	else if (mouseButton == SDL_BUTTON_LEFT && !editor.mixFlag) // string type	{		// jump to edit character under the mouse pointer 		int32_t tmp32 = mouse.y - textEdit.cursorStartY;		if (tmp32 <= 2 && tmp32 >= -9)		{			assert(textEdit.textStartPtr != NULL);			const int32_t textLength = (int32_t)strlen(textEdit.textStartPtr);			int32_t cursorBlock = (mouse.x - textEdit.cursorStartX) / FONT_CHAR_W;			const int32_t textPos = CLAMP(textEdit.scrollOffset + cursorBlock, 0, textLength); 			cursorBlock = CLAMP(cursorBlock, 0, textEdit.numBlocks-1);			if (cursorBlock > textLength)				cursorBlock = textLength; 			removeTextEditCursor();			textEdit.cursorBlock = (uint16_t)cursorBlock;			textEdit.textPtr = textEdit.textStartPtr + textPos;			renderTextEditCursor();		}		else		{			// if we clicked outside of the vertical edit area, stop edit mode 			if (textEdit.object != PTB_PE_PATTNAME) // special case...				leaveTextEditMode(EDIT_TEXT_UPDATE);		}	}	else if (mouseButton == SDL_BUTTON_RIGHT)	{		if (editor.mixFlag)		{			leaveTextEditMode(EDIT_TEXT_UPDATE);			editor.mixFlag = false;			ui.updateMixText = true;		}		else		{			// delete text			const uint32_t charsToZero = (uint32_t)(textEdit.textEndPtr - textEdit.textStartPtr);			memset(textEdit.textStartPtr, '\0', charsToZero); 			if (textEdit.object == PTB_DO_DATAPATH)			{				/* Don't exit text edit mode if the Disk Op. path was about to				** be deleted with the right mouse button.				** Set text cursor to beginning instead.				*/				removeTextEditCursor();				textEdit.cursorBlock = 0;				textEdit.textPtr = textEdit.textStartPtr;				textEdit.scrollOffset = 0;				renderTextEditCursor(); 				ui.updateDiskOpPathText = true;			}			else			{				if (textEdit.object == PTB_SONGNAME)					ui.updateSongName = true;				else if (textEdit.object == PTB_SAMPLENAME)					ui.updateCurrSampleName = true; 				leaveTextEditMode(EDIT_TEXT_UPDATE);			}		}	}} void enterTextEditMode(int16_t editObject){	pointerSetMode(POINTER_MODE_MSG1, NO_CARRY); 	textEdit.textPtr = textEdit.textStartPtr;	textEdit.cursorBlock = 0;	textEdit.scrollOffset = 0;	textEdit.type = TEXT_EDIT_STRING;	textEdit.object = editObject;	textEdit.endReached = false;	ui.editTextFlag = true; 	// make backup of old text (for handling 'song modified' flag later)	oldTextLength = (uint32_t)strlen(textEdit.textPtr);	memset(oldText, '\0', sizeof (oldText));	memcpy(oldText, textEdit.textPtr, oldTextLength);		if (editor.mixFlag) // skip to editable text section	{		editTextNextChar();		editTextNextChar();		editTextNextChar();		editTextNextChar();	} 	renderTextEditCursor();	SDL_StartTextInput();} void enterNumberEditMode(uint8_t type, int16_t editObject){	pointerSetMode(POINTER_MODE_MSG1, NO_CARRY); 	textEdit.cursorBlock = 0;	textEdit.type = type;	textEdit.object = editObject;	textEdit.endReached = false;	ui.editTextFlag = true; 	renderTextEditCursor();	SDL_StartTextInput();} static void redrawTextEditObject(void){	switch (textEdit.object)	{		default: break;		case PTB_SONGNAME: ui.updateSongName = true; break;		case PTB_SAMPLENAME: ui.updateCurrSampleName = true; break;		case PTB_PE_PATT: ui.updatePosEd = true; break;		case PTB_PE_PATTNAME: ui.updatePosEd = true; break;		case PTB_EO_QUANTIZE: ui.updateQuantizeText = true; break;		case PTB_EO_METRO_1: ui.updateMetro1Text = true; break;		case PTB_EO_METRO_2: ui.updateMetro2Text = true; break;		case PTB_EO_FROM_NUM: ui.updateFromText = true; break;		case PTB_EO_TO_NUM: ui.updateToText = true; break;		case PTB_EO_MIX: ui.updateMixText = true; break;		case PTB_EO_POS_NUM: ui.updatePosText = true; break;		case PTB_EO_MOD_NUM: ui.updateModText = true; break;		case PTB_EO_VOL_NUM: ui.updateVolText = true; break;		case PTB_DO_DATAPATH: ui.updateDiskOpPathText = true; break;		case PTB_POSS: ui.updateSongPos = true; break;		case PTB_PATTERNS: ui.updateSongPattern = true; break;		case PTB_LENGTHS: ui.updateSongLength = true; break;		case PTB_SAMPLES: ui.updateCurrSampleNum = true; break;		case PTB_SVOLUMES: ui.updateCurrSampleVolume = true; break;		case PTB_SLENGTHS: ui.updateCurrSampleLength = true; break;		case PTB_SREPEATS: ui.updateCurrSampleRepeat = true; break;		case PTB_SREPLENS: ui.updateCurrSampleReplen = true; break;		case PTB_PATTDATA: ui.updateCurrPattText = true; break;		case PTB_SA_VOL_FROM_NUM: ui.updateVolFromText = true; break;		case PTB_SA_VOL_TO_NUM: ui.updateVolToText = true; break;		case PTB_SA_FIL_LP_CUTOFF: ui.updateLPText = true; break;		case PTB_SA_FIL_HP_CUTOFF: ui.updateHPText = true; break;	}} void leaveTextEditMode(bool updateValue){	int8_t tmp8;	int16_t tmp16;	int32_t tmp32; 	SDL_StopTextInput(); 	// if user updated the disk op path text	if (ui.diskOpScreenShown && textEdit.object == PTB_DO_DATAPATH)	{		UNICHAR *pathU = (UNICHAR *)calloc(PATH_MAX + 2, sizeof (UNICHAR));		if (pathU != NULL)		{#ifdef _WIN32			MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, editor.currPath, -1, pathU, PATH_MAX);#else			strcpy(pathU, editor.currPath);#endif			diskOpSetPath(pathU, DISKOP_CACHE);			free(pathU);		}	} 	if (textEdit.type != TEXT_EDIT_STRING)	{		if (textEdit.cursorBlock != textEdit.numDigits)			removeTextEditCursor(); 		redrawTextEditObject();	}	else	{		removeTextEditCursor(); 		// yet another kludge...		if (textEdit.object == PTB_PE_PATT || textEdit.object == PTB_PE_PATTNAME)			ui.updatePosEd = true;	} 	ui.editTextFlag = false; 	if (textEdit.type == TEXT_EDIT_STRING)	{		pointerSetPreviousMode(); 		// handle song modified state (only for some text edit objects)		if (textEdit.object != PTB_EO_MIX && textEdit.object != PTB_PE_PATTNAME && textEdit.object != PTB_DO_DATAPATH)		{			if (strcmp(textEdit.textStartPtr, oldText) != 0)				updateWindowTitle(MOD_IS_MODIFIED);		}	}	else	{		// set back GUI text pointers and update values (if requested) 		moduleSample_t *s = &song->samples[editor.currSample];		switch (textEdit.object)		{			case PTB_SA_FIL_LP_CUTOFF:			{				editor.lpCutOffDisp = &editor.lpCutOff; 				if (updateValue)				{					editor.lpCutOff = textEdit.tmpDisp16;					if (editor.lpCutOff > (uint16_t)(FILTERS_BASE_FREQ/2))						editor.lpCutOff = (uint16_t)(FILTERS_BASE_FREQ/2); 					ui.updateLPText = true;				}			}			break; 			case PTB_SA_FIL_HP_CUTOFF:			{				editor.hpCutOffDisp = &editor.hpCutOff; 				if (updateValue)				{					editor.hpCutOff = textEdit.tmpDisp16;					if (editor.hpCutOff > (uint16_t)(FILTERS_BASE_FREQ/2))						editor.hpCutOff = (uint16_t)(FILTERS_BASE_FREQ/2); 					ui.updateHPText = true;				}			}			break; 			case PTB_SA_VOL_FROM_NUM:			{				editor.vol1Disp = &editor.vol1; 				if (updateValue)				{					editor.vol1 = textEdit.tmpDisp16;					if (editor.vol1 > 200)						editor.vol1 = 200; 					ui.updateVolFromText = true;					showVolFromSlider();				}			}			break; 			case PTB_SA_VOL_TO_NUM:			{				editor.vol2Disp = &editor.vol2;

Lines 1–500 of 1329.

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