1197 lines · 31.1 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 "ft2_header.h"#include "ft2_pattern_ed.h"#include "ft2_config.h"#include "ft2_gui.h"#include "ft2_video.h"#include "ft2_tables.h"#include "ft2_bmp.h"#include "ft2_structs.h" static note_t emptyPattern[MAX_CHANNELS * MAX_PATT_LEN]; static const uint8_t *font4Ptr, *font5Ptr;static const uint8_t vol2charTab1[16] = { 39, 0, 1, 2, 3, 4, 36, 52, 53, 54, 28, 31, 25, 58, 59, 22 };static const uint8_t vol2charTab2[16] = { 42, 0, 1, 2, 3, 4, 36, 37, 38, 39, 28, 31, 25, 40, 41, 22 };static const uint8_t columnModeTab[12] = { 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 3 };static const uint8_t sharpNote1Char_small[12] = {  8*6,  8*6,  9*6,  9*6, 10*6, 11*6, 11*6, 12*6, 12*6, 13*6, 13*6, 14*6 };static const uint8_t sharpNote2Char_small[12] = { 16*6, 15*6, 16*6, 15*6, 16*6, 16*6, 15*6, 16*6, 15*6, 16*6, 15*6, 16*6 };static const uint8_t flatNote1Char_small[12] = {  8*6,  9*6,  9*6, 10*6, 10*6, 11*6, 12*6, 12*6, 13*6, 13*6, 14*6, 14*6 };static const uint8_t flatNote2Char_small[12] = { 16*6, 17*6, 16*6, 17*6, 16*6, 16*6, 17*6, 16*6, 17*6, 16*6, 17*6, 16*6 };static const uint8_t sharpNote1Char_med[12] = { 12*8, 12*8, 13*8, 13*8, 14*8, 15*8, 15*8, 16*8, 16*8, 10*8, 10*8, 11*8 };static const uint16_t sharpNote2Char_med[12] = { 36*8, 37*8, 36*8, 37*8, 36*8, 36*8, 37*8, 36*8, 37*8, 36*8, 37*8, 36*8 };static const uint8_t flatNote1Char_med[12] = { 12*8, 13*8, 13*8, 14*8, 14*8, 15*8, 16*8, 16*8, 10*8, 10*8, 11*8, 11*8 };static const uint16_t flatNote2Char_med[12] = { 36*8, 38*8, 36*8, 38*8, 36*8, 36*8, 38*8, 36*8, 38*8, 36*8, 38*8, 36*8 };static const uint16_t sharpNote1Char_big[12] = { 12*16, 12*16, 13*16, 13*16, 14*16, 15*16, 15*16, 16*16, 16*16, 10*16, 10*16, 11*16 };static const uint16_t sharpNote2Char_big[12] = { 36*16, 37*16, 36*16, 37*16, 36*16, 36*16, 37*16, 36*16, 37*16, 36*16, 37*16, 36*16 };static const uint16_t flatNote1Char_big[12] = { 12*16, 13*16, 13*16, 14*16, 14*16, 15*16, 16*16, 16*16, 10*16, 10*16, 11*16, 11*16 };static const uint16_t flatNote2Char_big[12] = { 36*16, 38*16, 36*16, 38*16, 36*16, 36*16, 38*16, 36*16, 38*16, 36*16, 38*16, 36*16 }; static void pattCharOut(uint32_t xPos, uint32_t yPos, uint8_t chr, uint8_t fontType, uint32_t color);static void drawEmptyNoteSmall(uint32_t xPos, uint32_t yPos, uint32_t color);static void drawKeyOffSmall(uint32_t xPos, uint32_t yPos, uint32_t color);static void drawNoteSmall(uint32_t xPos, uint32_t yPos, int32_t noteNum, uint32_t color);static void drawEmptyNoteMedium(uint32_t xPos, uint32_t yPos, uint32_t color);static void drawKeyOffMedium(uint32_t xPos, uint32_t yPos, uint32_t color);static void drawNoteMedium(uint32_t xPos, uint32_t yPos, int32_t noteNum, uint32_t color);static void drawEmptyNoteBig(uint32_t xPos, uint32_t yPos, uint32_t color);static void drawKeyOffBig(uint32_t xPos, uint32_t yPos, uint32_t color);static void drawNoteBig(uint32_t xPos, uint32_t yPos, int32_t noteNum, uint32_t color); void updatePattFontPtrs(void){	//config.ptnFont is pre-clamped and safe to use	font4Ptr = &bmp.font4[config.ptnFont * (FONT4_WIDTH * FONT4_CHAR_H)];	font5Ptr = &bmp.font4[(4 + config.ptnFont) * (FONT4_WIDTH * FONT4_CHAR_H)];} void drawPatternBorders(void){	// get heights/pos/rows depending on configuration	const pattCoord2_t *pattCoord = &pattCoord2Table[config.ptnStretch][ui.pattChanScrollShown][ui.extended]; 	// set pattern cursor Y position	editor.ptnCursorY = pattCoord->lowerRowsY - 9; 	int32_t chans = ui.numChannelsShown;	if (chans > ui.maxVisibleChannels)		chans = ui.maxVisibleChannels; 	// in some configurations, there will be two empty channels to the right, fix that	if (chans == 2)		chans = 4;	else if (chans == 10 && !config.ptnShowVolColumn)		chans = 12; 	assert(chans >= 2 && chans <= 12); 	const uint16_t chanWidth = chanWidths[(chans >> 1) - 1] + 2; 	// fill scrollbar framework (if needed)	if (ui.pattChanScrollShown)		drawFramework(0, 383, 632, 17, FRAMEWORK_TYPE1); 	if (config.ptnFrmWrk)	{		// pattern editor w/ framework 		if (ui.extended)		{			vLine(0,   54, 345, PAL_DSKTOP1);			vLine(631, 53, 346, PAL_DSKTOP2); 			vLine(1,   54, 345, PAL_DESKTOP);			vLine(630, 54, 345, PAL_DESKTOP); 			hLine(0, 53, 631, PAL_DSKTOP1);			hLine(1, 54, 630, PAL_DESKTOP); 			if (!ui.pattChanScrollShown)			{				hLine(1, 398, 630, PAL_DESKTOP);				hLine(0, 399, 632, PAL_DSKTOP2);			}		}		else		{			vLine(0,   174, 225, PAL_DSKTOP1);			vLine(631, 173, 226, PAL_DSKTOP2); 			vLine(1,   174, 225, PAL_DESKTOP);			vLine(630, 174, 225, PAL_DESKTOP); 			hLine(0, 173, 631, PAL_DSKTOP1);			hLine(1, 174, 630, PAL_DESKTOP); 			if (!ui.pattChanScrollShown)			{				hLine(1, 398, 630, PAL_DESKTOP);				hLine(0, 399, 632, PAL_DSKTOP2);			}		} 		// fill middle (current row)		fillRect(2, pattCoord->lowerRowsY - 9, 628, 9, PAL_DESKTOP); 		// fill row number boxes		drawFramework(2, pattCoord->upperRowsY, 25, pattCoord->upperRowsH, FRAMEWORK_TYPE2); // top left		drawFramework(604, pattCoord->upperRowsY, 26, pattCoord->upperRowsH, FRAMEWORK_TYPE2); // top right		drawFramework(2, pattCoord->lowerRowsY, 25, pattCoord->lowerRowsH, FRAMEWORK_TYPE2); // bottom left		drawFramework(604, pattCoord->lowerRowsY, 26, pattCoord->lowerRowsH, FRAMEWORK_TYPE2); // bottom right 		// draw channels		uint16_t xOffs = 28;		for (int32_t i = 0; i < chans; i++)		{			vLine(xOffs - 1, pattCoord->upperRowsY, pattCoord->upperRowsH, PAL_DESKTOP);			vLine(xOffs - 1, pattCoord->lowerRowsY, pattCoord->lowerRowsH + 1, PAL_DESKTOP); 			drawFramework(xOffs, pattCoord->upperRowsY, chanWidth, pattCoord->upperRowsH, FRAMEWORK_TYPE2); // top part			drawFramework(xOffs, pattCoord->lowerRowsY, chanWidth, pattCoord->lowerRowsH, FRAMEWORK_TYPE2); // bottom part 			xOffs += chanWidth+1;		} 		vLine(xOffs-1, pattCoord->upperRowsY, pattCoord->upperRowsH, PAL_DESKTOP);		vLine(xOffs-1, pattCoord->lowerRowsY, pattCoord->lowerRowsH+1, PAL_DESKTOP);	}	else	{		// pattern editor without framework 		if (ui.extended)		{			const int32_t clearSize = ui.pattChanScrollShown ? (SCREEN_W * sizeof (int32_t) * 330) : (SCREEN_W * sizeof (int32_t) * 347);			memset(&video.frameBuffer[53 * SCREEN_W], 0, clearSize);		}		else		{			const int32_t clearSize = ui.pattChanScrollShown ? (SCREEN_W * sizeof(int32_t) * 210) : (SCREEN_W * sizeof(int32_t) * 227);			memset(&video.frameBuffer[173 * SCREEN_W], 0, clearSize);		} 		drawFramework(0, pattCoord->lowerRowsY - 10, SCREEN_W, 11, FRAMEWORK_TYPE1);	} 	if (ui.pattChanScrollShown)	{		showScrollBar(SB_CHAN_SCROLL);		showPushButton(PB_CHAN_SCROLL_LEFT);		showPushButton(PB_CHAN_SCROLL_RIGHT);	}	else	{		hideScrollBar(SB_CHAN_SCROLL);		hidePushButton(PB_CHAN_SCROLL_LEFT);		hidePushButton(PB_CHAN_SCROLL_RIGHT); 		setScrollBarPos(SB_CHAN_SCROLL, 0, false);	}} static void writeCursor(void){	const int32_t tabOffset = (config.ptnShowVolColumn * 32) + (columnModeTab[ui.numChannelsShown-1] * 8) + cursor.object; 	int32_t xPos = pattCursorXTab[tabOffset];	const int32_t width = pattCursorWTab[tabOffset]; 	assert(editor.ptnCursorY > 0 && xPos > 0 && width > 0);	xPos += ((cursor.ch - ui.channelOffset) * ui.patternChannelWidth); 	uint32_t *dstPtr = &video.frameBuffer[(editor.ptnCursorY * SCREEN_W) + xPos];	for (int32_t y = 0; y < 9; y++)	{		for (int32_t x = 0; x < width; x++)			dstPtr[x] = video.palette[(dstPtr[x] >> 24) ^ 4]; // ">> 24" to get palette, XOR 4 to change to cursor palette 		dstPtr += SCREEN_W;	}} static void writePatternBlockMark(int32_t currRow, uint32_t rowHeight, const pattCoord_t *pattCoord){	int32_t y1, y2; 	// this can happen (buggy FT2 code), treat like no mark	if (pattMark.markY1 > pattMark.markY2)		return; 	const int32_t startCh = ui.channelOffset;	const int32_t endCh = ui.channelOffset + (ui.numChannelsShown - 1);	const int32_t startRow = currRow - pattCoord->numUpperRows;	const int32_t endRow = currRow + pattCoord->numLowerRows; 	// test if pattern marking is outside of visible area (don't draw)	if (pattMark.markX1 > endCh || pattMark.markX2 < startCh || pattMark.markY1 > endRow || pattMark.markY2 < startRow)		return; 	const markCoord_t *markCoord = &markCoordTable[config.ptnStretch][ui.pattChanScrollShown][ui.extended];	const int32_t pattYStart = markCoord->upperRowsY; 	// X1 	int32_t x1 = 32 + ((pattMark.markX1 - ui.channelOffset) * ui.patternChannelWidth);	if (x1 < 32)		x1 = 32; 	// X2 	int32_t x2 = (32 - 8) + (((pattMark.markX2 + 1) - ui.channelOffset) * ui.patternChannelWidth);	if (x2 > 608)		x2 = 608; 	// Y1 	if (pattMark.markY1 < currRow)	{		y1 = pattYStart + ((pattMark.markY1 - startRow) * rowHeight);		if (y1 < pattYStart)			y1 = pattYStart;	}	else if (pattMark.markY1 == currRow)	{		y1 = markCoord->midRowY;	}	else	{		y1 = markCoord->lowerRowsY + ((pattMark.markY1 - (currRow + 1)) * rowHeight);	} 	// Y2 	if (pattMark.markY2-1 < currRow)	{		y2 = pattYStart + ((pattMark.markY2 - startRow) * rowHeight);	}	else if (pattMark.markY2-1 == currRow)	{		y2 = markCoord->midRowY + 11;	}	else	{		const int32_t pattYEnd = markCoord->lowerRowsY + (pattCoord->numLowerRows * rowHeight); 		y2 = markCoord->lowerRowsY + ((pattMark.markY2 - (currRow + 1)) * rowHeight);		if (y2 > pattYEnd)			y2 = pattYEnd;	} 	// kludge! (some mark situations could overwrite illegal areas)	if (config.ptnStretch && ui.pattChanScrollShown)	{		if (y1 == pattCoord->upperRowsY-1 || y1 == pattCoord->lowerRowsY-1)			y1++; 		if (y2 == 384)			y2--; 		// this can actually happen here, don't render in that case		if (y1 >= y2)			return;	} 	assert(x1 > 0 && x1 < SCREEN_W && x2 > 0 && x2 < SCREEN_W &&	       y1 > 0 && y1 < SCREEN_H && y2 > 0 && y2 < SCREEN_H); 	// pattern mark drawing 	const int32_t w = x2 - x1;	const int32_t h = y2 - y1; 	assert(x1+w <= SCREEN_W && y1+h <= SCREEN_H); 	uint32_t *ptr32 = &video.frameBuffer[(y1 * SCREEN_W) + x1];	for (int32_t y = 0; y < h; y++)	{		for (int32_t x = 0; x < w; x++)			ptr32[x] = video.palette[(ptr32[x] >> 24) ^ 2]; // ">> 24" to get palette of pixel, XOR 2 to change to mark palette 		ptr32 += SCREEN_W;	}} static void drawChannelNumbering(uint16_t yPos){	uint16_t xPos = 30;	int32_t ch = ui.channelOffset + 1; 	for (uint8_t i = 0; i < ui.numChannelsShown; i++)	{		if (ch < 10)		{			charOutOutlined(xPos, yPos, PAL_MOUSEPT, '0' + (char)ch);		}		else		{			charOutOutlined(xPos, yPos, PAL_MOUSEPT, chDecTab1[ch]);			charOutOutlined(xPos + (FONT1_CHAR_W + 1), yPos, PAL_MOUSEPT, chDecTab2[ch]);		} 		ch++;		xPos += ui.patternChannelWidth;	}} static void drawRowNums(int32_t yPos, uint8_t row, bool selectedRowFlag){#define LEFT_ROW_XPOS 8#define RIGHT_ROW_XPOS 608 	uint32_t pixVal; 	// set color based on some conditions	if (selectedRowFlag)		pixVal = video.palette[PAL_FORGRND];	else if (config.ptnLineLight && !(row & 3))		pixVal = video.palette[PAL_BLCKTXT];	else		pixVal = video.palette[PAL_PATTEXT]; 	if (!config.ptnHex)		row = hex2Dec[row]; 	const uint8_t *src1Ptr = &font4Ptr[(row   >> 4) * FONT4_CHAR_W];	const uint8_t *src2Ptr = &font4Ptr[(row & 0x0F) * FONT4_CHAR_W];	uint32_t *dst1Ptr = &video.frameBuffer[(yPos * SCREEN_W) + LEFT_ROW_XPOS];	uint32_t *dst2Ptr = dst1Ptr + (RIGHT_ROW_XPOS - LEFT_ROW_XPOS); 	for (int32_t y = 0; y < FONT4_CHAR_H; y++)	{		for (int32_t x = 0; x < FONT4_CHAR_W; x++)		{			if (src1Ptr[x])			{				dst1Ptr[x] = pixVal; // left side				dst2Ptr[x] = pixVal; // right side			} 			if (src2Ptr[x])			{				dst1Ptr[FONT4_CHAR_W+x] = pixVal; // left side				dst2Ptr[FONT4_CHAR_W+x] = pixVal; // right side			}		} 		src1Ptr += FONT4_WIDTH;		src2Ptr += FONT4_WIDTH;		dst1Ptr += SCREEN_W;		dst2Ptr += SCREEN_W;	}} // DRAWING ROUTINES (WITH VOLUME COLUMN) static void showNoteNum(uint32_t xPos, uint32_t yPos, int16_t note, uint32_t color){	xPos += 3; 	assert(note >= 0 && note <= 97); 	if (ui.numChannelsShown <= 4)	{		if (note <= 0 || note > 97)			drawEmptyNoteBig(xPos, yPos, color);		else if (note == NOTE_OFF)			drawKeyOffBig(xPos, yPos, color);		else			drawNoteBig(xPos, yPos, note, color);	}	else	{		if (note <= 0 || note > 97)			drawEmptyNoteMedium(xPos, yPos, color);		else if (note == NOTE_OFF)			drawKeyOffMedium(xPos, yPos, color);		else			drawNoteMedium(xPos, yPos, note, color);	}} static void showInstrNum(uint32_t xPos, uint32_t yPos, uint8_t ins, uint32_t color){	uint8_t charW, fontType; 	if (ui.numChannelsShown <= 4)	{		fontType = FONT_TYPE4;		charW = FONT4_CHAR_W;		xPos += 67;	}	else if (ui.numChannelsShown <= 6)	{		fontType = FONT_TYPE4;		charW = FONT4_CHAR_W;		xPos += 27;	}	else	{		fontType = FONT_TYPE3;		charW = FONT3_CHAR_W;		xPos += 31;	} 	if (config.ptnInstrZero)	{		pattCharOut(xPos,         yPos, ins >> 4,   fontType, color);		pattCharOut(xPos + charW, yPos, ins & 0x0F, fontType, color);	}	else	{		const uint8_t chr1 = ins >> 4;		const uint8_t chr2 = ins & 0x0F; 		if (chr1 > 0)			pattCharOut(xPos, yPos, chr1, fontType, color); 		if (chr1 > 0 || chr2 > 0)			pattCharOut(xPos + charW, yPos, chr2, fontType, color);	}} static void showVolEfx(uint32_t xPos, uint32_t yPos, uint8_t vol, uint32_t color){	uint8_t char1, char2, fontType, charW; 	if (ui.numChannelsShown <= 4)	{		fontType = FONT_TYPE4;		charW = FONT4_CHAR_W;		xPos += 91; 		char1 = vol2charTab1[vol >> 4];		if (vol < 0x10)			char2 = 39;		else			char2 = vol & 0x0F;	}	else if (ui.numChannelsShown <= 6)	{		fontType = FONT_TYPE4;		charW = FONT4_CHAR_W;		xPos += 51; 		char1 = vol2charTab1[vol >> 4];		if (vol < 0x10)			char2 = 39;		else			char2 = vol & 0x0F;	}	else	{		fontType = FONT_TYPE3;		charW = FONT3_CHAR_W;		xPos += 43; 		char1 = vol2charTab2[vol >> 4];		if (vol < 0x10)			char2 = 42;		else			char2 = vol & 0x0F;	} 	pattCharOut(xPos,         yPos, char1, fontType, color);	pattCharOut(xPos + charW, yPos, char2, fontType, color);} static void showEfx(uint32_t xPos, uint32_t yPos, uint8_t efx, uint8_t efxData, uint32_t color){	uint8_t fontType, charW; 	if (ui.numChannelsShown <= 4)	{		fontType = FONT_TYPE4;		charW = FONT4_CHAR_W;		xPos += 115;	}	else if (ui.numChannelsShown <= 6)	{		fontType = FONT_TYPE4;		charW = FONT4_CHAR_W;		xPos += 67;	}	else	{

Lines 1–500 of 1197.

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