Sigrid Solveig Haflínudóttirport to Plan 9 using npe8d7fffe3 years agoHistory
2605 lines · 53.7 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 <stdlib.h>#include <stdint.h>#include <stdbool.h>#include <math.h>#include "pt2_helpers.h"#include "pt2_textout.h"#include "pt2_audio.h"#include "pt2_tables.h"#include "pt2_visuals.h"#include "pt2_scopes.h"#include "pt2_sampler.h"#include "pt2_config.h"#include "pt2_bmp.h"#include "pt2_rcfilters.h"#include "pt2_chordmaker.h"#include "pt2_replayer.h"#include "pt2_visuals_sync.h" #define CENTER_LINE_COLOR 0x303030#define MARK_COLOR_1 0x666666 /* inverted background */#define MARK_COLOR_2 0xCCCCCC /* inverted waveform */#define MARK_COLOR_3 0x7D7D7D /* inverted center line */ #define SAMPLE_AREA_Y_CENTER 169#define SAMPLE_AREA_HEIGHT 64 static int32_t samOffsetScaled, lastDrawX, lastDrawY;static uint16_t TToneBit;static uint32_t waveInvertTable[8]; sampler_t sampler; // globalized static const int8_t tuneToneData[32] = // Tuning Tone (sine, regenerated with 127-scale instead of 128){	   0,   25,   49,   71,   90,  106,  117,  125,	 127,  125,  117,  106,   90,   71,   49,   25,	   0,  -25,  -49,  -71,  -90, -106, -117, -125,	-127, -125, -117, -106,  -90,  -71,  -49,  -25}; void killSample(void){	if (editor.sampleZero)	{		statusNotSampleZero();		return;	} 	turnOffVoices();	moduleSample_t *s = &song->samples[editor.currSample]; 	s->fineTune = 0;	s->volume = 0;	s->length = 0;	s->loopStart = 0;	s->loopLength = 2; 	memset(s->text, 0, sizeof (s->text));	memset(&song->sampleData[(editor.currSample * config.maxSampleLength)], 0, config.maxSampleLength); 	editor.samplePos = 0;	updateCurrSample(); 	ui.updateSongSize = true;	updateWindowTitle(MOD_IS_MODIFIED);} void upSample(void){	if (editor.sampleZero)	{		statusNotSampleZero();		return;	} 	moduleSample_t *s = &song->samples[editor.currSample]; 	int32_t newLength = (s->length >> 1) & config.maxSampleLength;	if (newLength < 2)		return; 	turnOffVoices(); 	// upsample	int8_t *ptr8 = &song->sampleData[s->offset];	for (int32_t i = 0; i < newLength; i++)		ptr8[i] = ptr8[i << 1]; 	// clear junk after shrunk sample	if (newLength < config.maxSampleLength)		memset(&ptr8[newLength], 0, config.maxSampleLength - newLength); 	s->length = newLength;	s->loopStart = (s->loopStart >> 1) & ~1;	s->loopLength = (s->loopLength >> 1) & ~1; 	if (s->loopLength < 2)	{		s->loopStart = 0;		s->loopLength = 2;	} 	fixSampleBeep(s);	updateCurrSample(); 	ui.updateSongSize = true;	updateWindowTitle(MOD_IS_MODIFIED);} void downSample(void){	if (editor.sampleZero)	{		statusNotSampleZero();		return;	} 	moduleSample_t *s = &song->samples[editor.currSample]; 	int32_t newLength = s->length << 1;	if (newLength > config.maxSampleLength)		newLength = config.maxSampleLength; 	turnOffVoices(); 	// downsample 	int8_t *ptr8 = &song->sampleData[s->offset];	int8_t *ptr8_2 = ptr8 - 1;	for (int32_t i = s->length-1; i > 0; i--)	{		ptr8[i<<1] = ptr8[i];		ptr8_2[i<<1] = ptr8_2[i];	} 	s->length = newLength; 	if (s->loopLength > 2)	{		int32_t loopStart = s->loopStart << 1;		int32_t loopLength = s->loopLength << 1; 		if (loopStart+loopLength > s->length)		{			loopStart = 0;			loopLength = 2;		} 		s->loopStart = loopStart;		s->loopLength = loopLength;	} 	fixSampleBeep(s);	updateCurrSample(); 	ui.updateSongSize = true;	updateWindowTitle(MOD_IS_MODIFIED);} void createSampleMarkTable(void){	// used for invertRange() (sample data marking) 	waveInvertTable[0] = 0x00000000 | video.palette[PAL_BACKGRD];	waveInvertTable[1] = 0x01000000 | video.palette[PAL_QADSCP];	waveInvertTable[2] = 0x02000000 | CENTER_LINE_COLOR;	waveInvertTable[3] = 0x03000000; // spacer, not used	waveInvertTable[4] = 0x04000000 | MARK_COLOR_1;	waveInvertTable[5] = 0x05000000 | MARK_COLOR_2;	waveInvertTable[6] = 0x06000000 | MARK_COLOR_3;	waveInvertTable[7] = 0x07000000; // spacer, not used} static void updateSamOffset(void){	if (sampler.samDisplay == 0)		samOffsetScaled = 0;	else		samOffsetScaled = (sampler.samOffset * SAMPLE_AREA_WIDTH) / sampler.samDisplay; // truncate here} void fixSampleBeep(moduleSample_t *s){	if (s->length >= 2 && s->loopStart+s->loopLength <= 2)	{		song->sampleData[s->offset+0] = 0;		song->sampleData[s->offset+1] = 0;	}} void updateSamplePos(void){	moduleSample_t *s; 	assert(editor.currSample >= 0 && editor.currSample <= 30);	if (editor.currSample >= 0 && editor.currSample <= 30)	{		s = &song->samples[editor.currSample];		if (editor.samplePos > s->length)			editor.samplePos = s->length; 		if (ui.editOpScreenShown && ui.editOpScreen == 2)			ui.updatePosText = true;	}} void fillSampleFilterUndoBuffer(void){	moduleSample_t *s; 	assert(editor.currSample >= 0 && editor.currSample <= 30);	if (editor.currSample >= 0 && editor.currSample <= 30)	{		s = &song->samples[editor.currSample];		memcpy(editor.tempSample, &song->sampleData[s->offset], s->length);	}} void sampleLine(int32_t line_x1, int32_t line_x2, int32_t line_y1, int32_t line_y2){	const uint32_t color = 0x01000000 | video.palette[PAL_QADSCP]; // set alpha to 0x10 ( used for invertRange() as a hack ) 	assert(line_x1 >= 0 || line_x2 >= 0 || line_x1 < SCREEN_W || line_x2 < SCREEN_W);	assert(line_y1 >= 0 || line_y2 >= 0 || line_y1 < SCREEN_H || line_y2 < SCREEN_H); 	int32_t dx = line_x2 - line_x1;	int32_t ax = ABS(dx) * 2;	int32_t sx = SGN(dx);	int32_t dy = line_y2 - line_y1;	int32_t ay = ABS(dy) * 2;	int32_t sy = SGN(dy);	int32_t x  = line_x1;	int32_t y  = line_y1; 	if (ax > ay)	{		int32_t d = ay - ((uint16_t)ax >> 1);		while (true)		{			assert(y >= 0 || x >= 0 || y < SCREEN_H || x < SCREEN_W); 			video.frameBuffer[(y * SCREEN_W) + x] = color; 			if (x == line_x2)				break; 			if (d >= 0)			{				y += sy;				d -= ax;			} 			x += sx;			d += ay;		}	}	else	{		int32_t d = ax - ((uint16_t)ay >> 1);		while (true)		{			assert(y >= 0 || x >= 0 || y < SCREEN_H || x < SCREEN_W); 			video.frameBuffer[(y * SCREEN_W) + x] = color; 			if (y == line_y2)				break; 			if (d >= 0)			{				x += sx;				d -= ay;			} 			y += sy;			d += ax;		}	}} static void setDragBar(void){	// clear drag bar background	fillRect(4, 206, 312, 4, video.palette[PAL_BACKGRD]); 	if (sampler.samLength > 0 && sampler.samDisplay != sampler.samLength)	{		const int32_t roundingBias = sampler.samLength >> 1; 		// update drag bar coordinates		int32_t pos = 4 + (((sampler.samOffset * 311) + roundingBias) / sampler.samLength);		sampler.dragStart = (uint16_t)CLAMP(pos, 4, 315); 		pos = 5 + ((((sampler.samDisplay + sampler.samOffset) * 311) + roundingBias) / sampler.samLength);		sampler.dragEnd = (uint16_t)CLAMP(pos, 5, 316); 		if (sampler.dragStart > sampler.dragEnd-1)			sampler.dragStart = sampler.dragEnd-1; 		// draw drag bar 		const uint32_t dragWidth = sampler.dragEnd - sampler.dragStart;		if (dragWidth > 0)			fillRect(sampler.dragStart, 206, dragWidth, 4, video.palette[PAL_QADSCP]);	}} static int8_t getScaledSample(int32_t index){	if (sampler.samLength <= 0 || index < 0 || index > sampler.samLength)		return 0; 	const int8_t *ptr8 = sampler.samStart;	if (ptr8 == NULL)		return 0; 	return ptr8[index] >> 2;} int32_t smpPos2Scr(int32_t pos) // sample pos -> screen x pos{	if (sampler.samDisplay == 0)		return 0; 	const uint32_t roundingBias = (const uint32_t)sampler.samDisplay >> 1; 	pos = (((uint32_t)pos * SAMPLE_AREA_WIDTH) + roundingBias) / (uint32_t)sampler.samDisplay; // rounded	pos -= samOffsetScaled; 	return pos;} int32_t scr2SmpPos(int32_t x) // screen x pos -> sample pos{	if (sampler.samDisplay == 0)		return 0; 	if (x < 0)		x = 0; 	x += samOffsetScaled;	x = (uint32_t)(x * sampler.samDisplay) / SAMPLE_AREA_WIDTH; // truncate here 	if (x > sampler.samLength)		x = sampler.samLength; 	return x;} static void getSampleDataPeak(int8_t *smpPtr, int32_t numBytes, int16_t *outMin, int16_t *outMax){	int8_t smpMin = 127;	int8_t smpMax = -128; 	for (int32_t i = 0; i < numBytes; i++)	{		int8_t smp = smpPtr[i];		if (smp < smpMin) smpMin = smp;		if (smp > smpMax) smpMax = smp;	} 	*outMin = SAMPLE_AREA_Y_CENTER - (smpMin >> 2);	*outMax = SAMPLE_AREA_Y_CENTER - (smpMax >> 2);} void renderSampleData(void){	moduleSample_t *s = &song->samples[editor.currSample]; 	// clear sample data background	fillRect(3, 138, SAMPLE_AREA_WIDTH, SAMPLE_VIEW_HEIGHT, video.palette[PAL_BACKGRD]); 	// display center line (if enabled)	if (config.waveformCenterLine)	{		uint32_t *dstPtr = &video.frameBuffer[(SAMPLE_AREA_Y_CENTER * SCREEN_W) + 3];		for (int32_t x = 0; x < SAMPLE_AREA_WIDTH; x++)			dstPtr[x] = 0x02000000 | CENTER_LINE_COLOR;	} 	// render sample data	if (sampler.samDisplay >= 0 && sampler.samDisplay <= config.maxSampleLength)	{		int16_t y1 = SAMPLE_AREA_Y_CENTER - getScaledSample(scr2SmpPos(0)); 		if (sampler.samDisplay <= SAMPLE_AREA_WIDTH)		{			// 1:1 or zoomed in			for (int32_t x = 1; x < SAMPLE_AREA_WIDTH; x++)			{				int16_t y2 = SAMPLE_AREA_Y_CENTER - getScaledSample(scr2SmpPos(x));				sampleLine(x + 2, x + 3, y1, y2);				y1 = y2;			}		}		else		{			// zoomed out 			int16_t min, max; 			int16_t oldMin = y1;			int16_t oldMax = y1; 			int8_t *smpPtr = &song->sampleData[s->offset];			for (int32_t x = 0; x < SAMPLE_AREA_WIDTH; x++)			{				int32_t smpIdx = scr2SmpPos(x);				int32_t smpNum = scr2SmpPos(x+1) - smpIdx; 				// prevent look-up overflow (yes, this can happen near the end of the sample)				if (smpIdx+smpNum > sampler.samLength)					smpNum = sampler.samLength - smpNum; 				if (smpNum < 1)					smpNum = 1; 				getSampleDataPeak(&smpPtr[smpIdx], smpNum, &min, &max); 				if (x > 0)				{					if (min > oldMax) sampleLine(x + 2, x + 3, oldMax, min);					if (max < oldMin) sampleLine(x + 2, x + 3, oldMin, max);				} 				sampleLine(x + 3, x + 3, max, min); 				oldMin = min;				oldMax = max;			}		}	} 	if (ui.samplingBoxShown)		return; 	// render "sample display" text 	if (config.maxSampleLength == 0xFFFE)	{		if (sampler.samStart == sampler.blankSample)			printFiveDecimalsBg(272, 214, 0, video.palette[PAL_GENTXT], video.palette[PAL_GENBKG]);		else			printFiveDecimalsBg(272, 214, sampler.samDisplay, video.palette[PAL_GENTXT], video.palette[PAL_GENBKG]);	}	else	{		if (sampler.samStart == sampler.blankSample)			printSixDecimalsBg(270, 214, 0, video.palette[PAL_GENTXT], video.palette[PAL_GENBKG]);		else			printSixDecimalsBg(270, 214, sampler.samDisplay, video.palette[PAL_GENTXT], video.palette[PAL_GENBKG]);	} 	setDragBar();	setLoopSprites();} void invertRange(void){	if (editor.markStartOfs == -1)		return; // no marking 	int32_t start = smpPos2Scr(editor.markStartOfs);	int32_t end = smpPos2Scr(editor.markEndOfs); 	if (sampler.samDisplay < sampler.samLength && (start >= SAMPLE_AREA_WIDTH || end < 0))		return; // range is outside of view 	start = CLAMP(start, 0, SAMPLE_AREA_WIDTH-1);	end = CLAMP(end, 0, SAMPLE_AREA_WIDTH-1); 	int32_t rangeLen = (end + 1) - start;	if (rangeLen < 1)		rangeLen = 1; 	uint32_t *dstPtr = &video.frameBuffer[(138 * SCREEN_W) + (start + 3)];	for (int32_t y = 0; y < 64; y++)	{		for (int32_t x = 0; x < rangeLen; x++)			dstPtr[x] = waveInvertTable[((dstPtr[x] >> 24) & 7) ^ 4]; // ptr[x]>>24 = wave/invert color number 		dstPtr += SCREEN_W;	}} void displaySample(void){	if (!ui.samplerScreenShown)		return; 	renderSampleData();	if (editor.markStartOfs != -1)		invertRange(); 

Lines 1–500 of 2605.

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