shithub: ft2-clone

Download patch

ref: ac5d22ae6614f0f65553b1628ecb644bc8ea4126
parent: bb383fc54a3b9eeea70eb1eddd0c9583e7b0f444
author: Olav Sørensen <[email protected]>
date: Wed Apr 22 14:03:42 EDT 2020

Fixed some bugs and replaced "Space Pigs" color scheme

1) macOS/Linux: The initial working directory would not get properly set when opening Disk Op.
2) "Space Pigs" palette replaced with a new (low contrast) "Dark mode" palette
3) Changed rounding in period -> delta conversion (audio channel mixer)

--- a/src/ft2_about.c
+++ b/src/ft2_about.c
@@ -234,7 +234,6 @@
 
 void showAboutScreen(void) // called once when About screen is opened
 {
-#define TEXT_BORDER_COL 0x2E2E2E
 
 	const char *infoString = "Clone by Olav \"8bitbubsy\" S\025rensen - https://16-bits.org";
 	char verText[32];
--- a/src/ft2_audio.h
+++ b/src/ft2_audio.h
@@ -112,6 +112,8 @@
 void resetCachedMixerVars(void);
 #endif
 
+void calcAudioTables(void);
+
 int32_t pattQueueReadSize(void);
 int32_t pattQueueWriteSize(void);
 bool pattQueuePush(pattSyncData_t t);
--- a/src/ft2_config.c
+++ b/src/ft2_config.c
@@ -986,7 +986,7 @@
 		case PAL_JUNGLE:          tmpID = RB_CONFIG_PAL_JUNGLE;          break;
 		case PAL_LITHE_DARK:      tmpID = RB_CONFIG_PAL_LITHE_DARK;      break;
 		case PAL_ROSE:            tmpID = RB_CONFIG_PAL_ROSE;            break;
-		case PAL_SPACE_PIGS:      tmpID = RB_CONFIG_PAL_SPACE_PIGS;      break;
+		case PAL_DARK_MODE:       tmpID = RB_CONFIG_PAL_DARK_MODE;       break;
 		case PAL_VIOLENT:         tmpID = RB_CONFIG_PAL_VIOLENT;         break;
 		case PAL_WHY_COLORS:      tmpID = RB_CONFIG_PAL_WHY_COLORS;      break;
 		case PAL_USER_DEFINED:    tmpID = RB_CONFIG_PAL_USER_DEFINED;    break;
@@ -1257,7 +1257,7 @@
 			textOutShadow(414, 104, PAL_FORGRND, PAL_DSKTOP2, "Aurora Borealis");
 			textOutShadow(528, 104, PAL_FORGRND, PAL_DSKTOP2, "Rose");
 			textOutShadow(414, 118, PAL_FORGRND, PAL_DSKTOP2, "Blues");
-			textOutShadow(528, 118, PAL_FORGRND, PAL_DSKTOP2, "Space Pigs");
+			textOutShadow(528, 118, PAL_FORGRND, PAL_DSKTOP2, "Dark mode");
 			textOutShadow(414, 132, PAL_FORGRND, PAL_DSKTOP2, "Gold");
 			textOutShadow(528, 132, PAL_FORGRND, PAL_DSKTOP2, "Violent");
 			textOutShadow(414, 146, PAL_FORGRND, PAL_DSKTOP2, "Heavy Metal");
--- a/src/ft2_config.h
+++ b/src/ft2_config.h
@@ -45,7 +45,7 @@
 	PAL_JUNGLE = 5,
 	PAL_LITHE_DARK = 6,
 	PAL_ROSE = 7,
-	PAL_SPACE_PIGS = 8,
+	PAL_DARK_MODE = 8,
 	PAL_VIOLENT = 9,
 	PAL_WHY_COLORS = 10, // default
 	PAL_USER_DEFINED = 11,
--- a/src/ft2_diskop.c
+++ b/src/ft2_diskop.c
@@ -75,7 +75,7 @@
 static char *modTmpFName, *insTmpFName, *smpTmpFName, *patTmpFName, *trkTmpFName;
 static char *modTmpFNameUTF8; // for window title
 static uint8_t FReq_Item;
-static bool FReq_ShowAllFiles, modPathSet, insPathSet, smpPathSet, patPathSet, trkPathSet;
+static bool FReq_ShowAllFiles, insPathSet, smpPathSet, patPathSet, trkPathSet, firstTimeOpeningDiskOp = true;
 static int32_t FReq_EntrySelected = -1, FReq_FileCount, FReq_DirPos, lastMouseY;
 static UNICHAR *FReq_CurPathU, *FReq_ModCurPathU, *FReq_InsCurPathU, *FReq_SmpCurPathU, *FReq_PatCurPathU, *FReq_TrkCurPathU;
 static DirRec *FReq_Buffer;
@@ -172,20 +172,11 @@
 
 static void setupInitialPaths(void)
 {
-#ifdef _WIN32
-	UNICHAR pathU[PATH_MAX + 2];
-#endif
-
-	UNICHAR_GETCWD(FReq_ModCurPathU, PATH_MAX);
-
 	// the UNICHAR paths are already zeroed out
 
 #ifdef _WIN32
 	if (config.modulesPath[0] != '\0')
-	{
 		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.modulesPath, -1, FReq_ModCurPathU, 80);
-		modPathSet = true;
-	}
 
 	if (config.instrPath[0] != '\0')
 	{
@@ -212,10 +203,7 @@
 	}
 #else
 	if (config.modulesPath[0] != '\0')
-	{
 		strncpy(FReq_ModCurPathU, config.modulesPath, 80);
-		modPathSet = true;
-	}
 
 	if (config.instrPath[0] != '\0')
 	{
@@ -241,21 +229,6 @@
 		trkPathSet = true;
 	}
 #endif
-
-	// set initial path to user directory
-#ifdef _WIN32
-	if (SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, pathU) >= 0)
-		UNICHAR_CHDIR(pathU);
-#else
-	UNICHAR_CHDIR(getenv("HOME"));
-#endif
-
-	// if we couldn't set present in config, set custom "modules" path
-	if (modPathSet && UNICHAR_CHDIR(FReq_ModCurPathU) != 0)
-	{
-		UNICHAR_GETCWD(FReq_ModCurPathU, PATH_MAX);
-		modPathSet = true;
-	}
 }
 
 static void freeDirRecBuffer(void)
@@ -1943,8 +1916,6 @@
 	uint8_t lastFindFileFlag;
 	DirRec tmpBuffer, *newPtr;
 
-	(void)ptr;
-
 	FReq_DirPos = 0;
 
 	// free old buffer
@@ -2018,6 +1989,7 @@
 
 	setMouseBusy(false);
 
+	(void)ptr;
 	return true;
 }
 
@@ -2199,10 +2171,6 @@
 		memset(FReq_CurPathU, 0, (PATH_MAX + 2) * sizeof (UNICHAR));
 		UNICHAR_STRCPY(FReq_CurPathU, FReq_ModCurPathU);
 	}
-	else
-	{
-		UNICHAR_CHDIR(FReq_CurPathU);
-	}
 
 	textBoxes[TB_DISKOP_FILENAME].textPtr = FReq_FileName;
 
@@ -2285,6 +2253,28 @@
 
 void showDiskOpScreen(void)
 {
+	// if first time opening Disk Op., set initial directory
+	if (firstTimeOpeningDiskOp)
+	{
+		assert(FReq_ModCurPathU != NULL);
+
+		// first test if we can change the dir to the one stored in the config (if present)
+		if (UNICHAR_STRLEN(FReq_ModCurPathU) == 0 || UNICHAR_CHDIR(FReq_ModCurPathU) != 0)
+		{
+			// nope, couldn't do that, set Disk Op. path to user/home directory
+#ifdef _WIN32
+			SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, FReq_ModCurPathU);
+#else
+			if (getenv("HOME") != NULL)
+				UNICHAR_STRCPY(FReq_ModCurPathU, getenv("HOME"));
+#endif
+			UNICHAR_CHDIR(FReq_ModCurPathU);
+		}
+
+		UNICHAR_GETCWD(FReq_ModCurPathU, PATH_MAX);
+		firstTimeOpeningDiskOp = false;
+	}
+
 	if (editor.ui.extended)
 		exitPatternEditorExtended();
 
--- a/src/ft2_main.c
+++ b/src/ft2_main.c
@@ -181,7 +181,7 @@
 		// one LAST attempt (with default audio device and settings)
 		config.audioFreq = 48000;
 
-		// try 16-bit audio at 1024 samples (44.1kHz/48kHz)
+		// try 48kHz 16-bit audio at 1024 samples
 		config.specialFlags &= ~(BITDEPTH_32 + BUFFSIZE_512 + BUFFSIZE_2048);
 		config.specialFlags |=  (BITDEPTH_16 + BUFFSIZE_1024);
 
@@ -227,9 +227,10 @@
 
 	setupWaitVBL(); // this is needed for potential okBox() calls in handleModuleLoadFromArg()
 	handleModuleLoadFromArg(argc, argv);
-	setupWaitVBL(); // yes, this is needed again for main loop
 
 	editor.mainLoopOngoing = true;
+	setupWaitVBL(); // this must be the very last thing done before entering the main loop
+
 	while (editor.programRunning)
 	{
 		beginFPSCounter();
@@ -310,6 +311,8 @@
 	editor.programRunning = true;
 
 	audio.linearFreqTable = true;
+
+	calcAudioTables();
 }
 
 static void cleanUpAndExit(void) // never call this inside the main loop!
--- a/src/ft2_palette.c
+++ b/src/ft2_palette.c
@@ -17,7 +17,7 @@
 static uint8_t palContrast[12][2] = // palette desktop/button contrasts
 {
 	{59, 55}, {59, 53}, {56, 59}, {68, 55}, {57, 59}, {48, 55},
-	{66, 62}, {68, 57}, {46, 57}, {57, 55}, {62, 57}, {52, 57}
+	{66, 62}, {68, 57}, {58, 42}, {57, 55}, {62, 57}, {52, 57}
 };
 
 void setCustomPalColor(uint32_t color)
@@ -27,7 +27,7 @@
 
 void setPal16(pal16 *p, bool redrawScreen)
 {
-#define LOOP_PIN_COL_SUB 118
+#define LOOP_PIN_COL_SUB 75
 #define TEXT_MARK_COLOR 0x0078D7
 #define BOX_SELECT_COLOR 0x7F7F7F
 
@@ -71,6 +71,11 @@
 	okBox(0, "System message", "Default colors cannot be modified.");
 }
 
+static void showMouseColorErrorMsg(void)
+{
+	okBox(0, "System message", "Mouse color can only be changed when \"Software mouse\" is enabled.");
+}
+
 static double palPow(double dX, double dY)
 {
 	if (dY == 1.0)
@@ -139,7 +144,7 @@
 	if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNr == 3)
 	{
 		updatePaletteEditor(); // resets colors/contrast vars
-		okBox(0, "System message", "Mouse color can only be changed when \"Software mouse\" is enabled.");
+		showMouseColorErrorMsg();
 		return;
 	}
 
@@ -230,6 +235,8 @@
 {
 	if (config.cfg_StdPalNr != PAL_USER_DEFINED)
 		showColorErrorMsg();
+	else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNr == 3)
+		showMouseColorErrorMsg();
 	else
 		scrollBarScrollLeft(SB_PAL_R, 1);
 }
@@ -238,6 +245,8 @@
 {
 	if (config.cfg_StdPalNr != PAL_USER_DEFINED)
 		showColorErrorMsg();
+	else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNr == 3)
+		showMouseColorErrorMsg();
 	else
 		scrollBarScrollRight(SB_PAL_R, 1);
 }
@@ -246,6 +255,8 @@
 {
 	if (config.cfg_StdPalNr != PAL_USER_DEFINED)
 		showColorErrorMsg();
+	else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNr == 3)
+		showMouseColorErrorMsg();
 	else
 		scrollBarScrollLeft(SB_PAL_G, 1);
 }
@@ -254,6 +265,8 @@
 {
 	if (config.cfg_StdPalNr != PAL_USER_DEFINED)
 		showColorErrorMsg();
+	else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNr == 3)
+		showMouseColorErrorMsg();
 	else
 		scrollBarScrollRight(SB_PAL_G, 1);
 }
@@ -262,6 +275,8 @@
 {
 	if (config.cfg_StdPalNr != PAL_USER_DEFINED)
 		showColorErrorMsg();
+	else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNr == 3)
+		showMouseColorErrorMsg();
 	else
 		scrollBarScrollLeft(SB_PAL_B, 1);
 }
@@ -270,6 +285,8 @@
 {
 	if (config.cfg_StdPalNr != PAL_USER_DEFINED)
 		showColorErrorMsg();
+	else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNr == 3)
+		showMouseColorErrorMsg();
 	else
 		scrollBarScrollRight(SB_PAL_B, 1);
 }
@@ -278,6 +295,8 @@
 {
 	if (config.cfg_StdPalNr != PAL_USER_DEFINED)
 		showColorErrorMsg();
+	else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNr == 3)
+		showMouseColorErrorMsg();
 	else
 		scrollBarScrollLeft(SB_PAL_CONTRAST, 1);
 }
@@ -286,6 +305,8 @@
 {
 	if (config.cfg_StdPalNr != PAL_USER_DEFINED)
 		showColorErrorMsg();
+	else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNr == 3)
+		showMouseColorErrorMsg();
 	else
 		scrollBarScrollRight(SB_PAL_CONTRAST, 1);
 }
@@ -398,12 +419,12 @@
 	checkRadioButton(RB_CONFIG_PAL_BLUES);
 }
 
-void rbConfigPalSpacePigs(void)
+void rbConfigPalDarkMode(void)
 {
-	config.cfg_StdPalNr = PAL_SPACE_PIGS;
+	config.cfg_StdPalNr = PAL_DARK_MODE;
 	updatePaletteEditor();
 	setPal16(palTable[config.cfg_StdPalNr], true);
-	checkRadioButton(RB_CONFIG_PAL_SPACE_PIGS);
+	checkRadioButton(RB_CONFIG_PAL_DARK_MODE);
 }
 
 void rbConfigPalGold(void)
--- a/src/ft2_palette.h
+++ b/src/ft2_palette.h
@@ -81,7 +81,7 @@
 void rbConfigPalAuroraBorealis(void);
 void rbConfigPalRose(void);
 void rbConfigPalBlues(void);
-void rbConfigPalSpacePigs(void);
+void rbConfigPalDarkMode(void);
 void rbConfigPalGold(void);
 void rbConfigPalViolent(void);
 void rbConfigPalHeavyMetal(void);
--- a/src/ft2_radiobuttons.c
+++ b/src/ft2_radiobuttons.c
@@ -151,7 +151,7 @@
 	{ 399, 103, 105, RB_GROUP_CONFIG_PAL_PRESET, rbConfigPalAuroraBorealis },
 	{ 512, 103,  45, RB_GROUP_CONFIG_PAL_PRESET, rbConfigPalRose },
 	{ 399, 117,  47, RB_GROUP_CONFIG_PAL_PRESET, rbConfigPalBlues },
-	{ 512, 117,  81, RB_GROUP_CONFIG_PAL_PRESET, rbConfigPalSpacePigs },
+	{ 512, 117,  77, RB_GROUP_CONFIG_PAL_PRESET, rbConfigPalDarkMode },
 	{ 399, 131,  40, RB_GROUP_CONFIG_PAL_PRESET, rbConfigPalGold },
 	{ 512, 131,  56, RB_GROUP_CONFIG_PAL_PRESET, rbConfigPalViolent },
 	{ 399, 145,  87, RB_GROUP_CONFIG_PAL_PRESET, rbConfigPalHeavyMetal },
--- a/src/ft2_radiobuttons.h
+++ b/src/ft2_radiobuttons.h
@@ -113,7 +113,7 @@
 	RB_CONFIG_PAL_AURORA_BOREALIS,
 	RB_CONFIG_PAL_ROSE,
 	RB_CONFIG_PAL_BLUES,
-	RB_CONFIG_PAL_SPACE_PIGS,
+	RB_CONFIG_PAL_DARK_MODE,
 	RB_CONFIG_PAL_GOLD,
 	RB_CONFIG_PAL_VIOLENT,
 	RB_CONFIG_PAL_HEAVY_METAL,
--- a/src/ft2_replayer.c
+++ b/src/ft2_replayer.c
@@ -30,11 +30,13 @@
 */
 
 static uint32_t musicTimeTab[256-32];
-static uint64_t period2ScopeDeltaTab[65536], scopeLogTab[768], scopeAmigaPeriodDiv;
+static uint64_t period2ScopeDeltaTab[65536];
+static double dLogTab[768], dLogTabMul[32], dAudioRateFactor;
+
 #if defined _WIN64 || defined __amd64__
-static uint64_t period2DeltaTab[65536], logTab[768], amigaPeriodDiv;
+static uint64_t period2DeltaTab[65536];
 #else
-static uint32_t period2DeltaTab[65536], logTab[768], amigaPeriodDiv;
+static uint32_t period2DeltaTab[65536];
 #endif
 
 static bool bxxOverflow;
@@ -224,46 +226,48 @@
 }
 
 // called every time you change linear/amiga mode and mixing frequency
-static void calcDelta2PeriodTabs(void)
+static void calcPeriod2DeltaTables(void)
 {
 	int32_t baseDelta;
 	uint32_t i;
 
-	period2DeltaTab[0] = 0; // FT2 converts period 0 to a delta of 0
+	period2DeltaTab[0] = 0; // in FT2, a period of 0 is converted to a delta of 0
 
+	const double dScopeRateFactor = SCOPE_FRAC_SCALE / (double)SCOPE_HZ;
+
 	if (audio.linearFreqTable)
 	{
+		// linear periods
 		for (i = 1; i < 65536; i++)
 		{
 			const uint16_t invPeriod = (12 * 192 * 4) - (uint16_t)i; // this intentionally overflows uint16_t to be accurate to FT2
 			const int32_t octave = invPeriod / 768;
 			const int32_t period = invPeriod % 768;
-			const int32_t shift = (14 - octave) & 0x1F; // this is exactly how FT2 does it
+			const int32_t shift = (14 - octave) & 0x1F; // 100% accurate to FT2!
 
+			const double dHz = dLogTab[period] * dLogTabMul[shift];
+
 #if defined _WIN64 || defined __amd64__
-			uint64_t delta = logTab[period];
+			period2DeltaTab[i] = (uint64_t)((dHz * dAudioRateFactor) + 0.5);
 #else
-			uint32_t delta = logTab[period];
+			period2DeltaTab[i] = (uint32_t)((dHz * dAudioRateFactor) + 0.5);
 #endif
-			uint64_t scopeDelta = scopeLogTab[period];
-
-			if (shift > 0)
-			{
-				delta >>= shift;
-				scopeDelta >>= shift;
-			}
-
-			period2DeltaTab[i] = delta;
-			period2ScopeDeltaTab[i] = scopeDelta;
+			period2ScopeDeltaTab[i] = (uint64_t)((dHz * dScopeRateFactor) + 0.5);
 		}
 	}
 	else
 	{
-		// Note: these calculations should remain truncated and not rounded!
+		// Amiga periods
 		for (i = 1; i < 65536; i++)
 		{
-			period2DeltaTab[i] = amigaPeriodDiv / i;
-			period2ScopeDeltaTab[i] = scopeAmigaPeriodDiv / i;
+			double dHz = (8363.0 * 1712.0) / i;
+
+#if defined _WIN64 || defined __amd64__
+			period2DeltaTab[i] = (uint64_t)((dHz * dAudioRateFactor) + 0.5);
+#else
+			period2DeltaTab[i] = (uint32_t)((dHz * dAudioRateFactor) + 0.5);
+#endif
+			period2ScopeDeltaTab[i] = (uint64_t)((dHz * dScopeRateFactor) + 0.5);
 		}
 	}
 
@@ -289,7 +293,7 @@
 	else
 		note2Period = amigaPeriods;
 
-	calcDelta2PeriodTabs();
+	calcPeriod2DeltaTables();
 
 	resumeAudio();
 
@@ -381,6 +385,18 @@
 	}
 }
 
+void calcAudioTables(void)
+{
+	int32_t i;
+
+	for (i = 0; i < 768; i++)
+		dLogTab[i] = exp2(i / 768.0) * (8363.0 * 256.0);
+
+	dLogTabMul[0] = 1.0;
+	for (i = 1; i < 32; i++)
+		dLogTabMul[i] = exp2(-i);
+}
+
 void calcReplayRate(int32_t rate)
 {
 	int32_t i;
@@ -387,30 +403,9 @@
 
 	if (rate == 0)
 		return;
+	
+	dAudioRateFactor = (double)MIXER_FRAC_SCALE / rate;
 
-	const double dScopeRateFactor = SCOPE_FRAC_SCALE / (double)SCOPE_HZ;
-	const double dAudioRateFactor = MIXER_FRAC_SCALE / (double)rate;
-
-	scopeAmigaPeriodDiv = (uint64_t)(((8363.0 * 1712.0) * dScopeRateFactor) + 0.5);
-
-#if defined _WIN64 || defined __amd64__
-	amigaPeriodDiv = (uint64_t)(((8363.0 * 1712.0) * dAudioRateFactor) + 0.5);
-	for (i = 0; i < 768; i++)
-	{
-		double dHz = exp2(i * (1.0 / 768.0)) * (8363.0 * 256.0);
-		logTab[i] = (uint64_t)((dHz * dAudioRateFactor) + 0.5);
-		scopeLogTab[i] = (uint64_t)((dHz * dScopeRateFactor) + 0.5);
-	}
-#else
-	amigaPeriodDiv = (uint32_t)(((8363 * 1712) * dAudioRateFactor) + 0.5);
-	for (i = 0; i < 768; i++)
-	{
-		double dHz = exp2(i * (1.0 / 768.0)) * (8363.0 * 256.0);
-		logTab[i] = (uint32_t)((dHz * dAudioRateFactor) + 0.5);
-		scopeLogTab[i] = (uint64_t)((dHz * dScopeRateFactor) + 0.5);
-	}
-#endif
-
 	audio.quickVolSizeVal = rate / 200; // FT2 truncates here
 	audio.rampQuickVolMul = (int32_t)(((UINT32_MAX + 1.0) / audio.quickVolSizeVal) + 0.5);
 	audio.dSpeedValMul = editor.dPerfFreq / rate; // for audio/video sync
@@ -424,7 +419,7 @@
 		musicTimeTab[i-32] = (int32_t)(dVal + 0.5);
 	}
 
-	calcDelta2PeriodTabs();
+	calcPeriod2DeltaTables();
 }
 
 #if defined _WIN64 || defined __amd64__
@@ -2144,7 +2139,7 @@
 		return;
 	}
 
-	assert(song.speed >= 32 && song.speed <= 2);
+	assert(song.speed >= 32 && song.speed <= 255);
 	song.musicTime64 += musicTimeTab[song.speed-32]; // for playback counter
 
 	readNewNote = false;
--- a/src/ft2_sysreqs.c
+++ b/src/ft2_sysreqs.c
@@ -199,9 +199,9 @@
 	if (wlen > 600)
 		wlen = 600;
 
-	headlineX = (SCREEN_W - hlen) / 2;
-	textX = (SCREEN_W - tlen) / 2;
-	x = (SCREEN_W - wlen) / 2;
+	headlineX = (SCREEN_W - hlen) >> 1;
+	textX = (SCREEN_W - tlen) >> 1;
+	x = (SCREEN_W - wlen) >> 1;
 
 	// the box y position differs in extended pattern editor mode
 	y = editor.ui.extended ? SYSTEM_REQUEST_Y_EXT : SYSTEM_REQUEST_Y;
@@ -211,7 +211,7 @@
 	{
 		p = &pushButtons[i];
 
-		p->x = ((SCREEN_W - tx) / 2) + (i * 100);
+		p->x = ((SCREEN_W - tx) >> 1) + (i * 100);
 		p->y = y + 42;
 		p->w = PUSHBUTTON_W;
 		p->h = 16;
@@ -326,13 +326,13 @@
 
 		// draw OK box
 		drawWindow(wlen);
-		textOutShadow(headlineX, y +  4, PAL_BUTTON1, PAL_BUTTON2, headline);
-		textOutShadow(textX,     y + 24, PAL_BUTTON1, PAL_BUTTON2, text);
+		textOutShadow(headlineX, y +  4, PAL_FORGRND, PAL_BUTTON2, headline);
+		textOutShadow(textX,     y + 24, PAL_FORGRND, PAL_BUTTON2, text);
 		for (i = 0; i < knp; i++) drawPushButton(i);
 		if (typ >= 6 && typ <= 7)
 		{
 			drawCheckBox(0);
-			textOutShadow(x + 21, y + 52, PAL_BUTTON1, PAL_BUTTON2, "Don't show again");
+			textOutShadow(x + 21, y + 52, PAL_FORGRND, PAL_BUTTON2, "Don't show again");
 		}
 
 		flipFrame();
@@ -397,7 +397,7 @@
 	t->changeMouseCursor = true;
 	t->renderBufW = (9 + 1) * t->maxChars; // 9 = max character/glyph width possible
 	t->renderBufH = 10; // 10 = max character height possible
-	t->renderW = t->w - (t->tx * 2);
+	t->renderW = t->w - (t->tx << 1);
 
 	t->renderBuf = (uint8_t *)malloc(t->renderBufW * t->renderBufH * sizeof (int8_t));
 	if (t->renderBuf == NULL)
@@ -412,7 +412,7 @@
 	mouseAnimOff();
 
 	wlen = textWidth(headline);
-	headlineX = (SCREEN_W - wlen) / 2;
+	headlineX = (SCREEN_W - wlen) >> 1;
 
 	// count number of buttons
 	knp = 0;
@@ -435,7 +435,7 @@
 	y = editor.ui.extended ? SYSTEM_REQUEST_Y_EXT : SYSTEM_REQUEST_Y;
 
 	// set further text box settings
-	t->x = (SCREEN_W - TEXTBOX_W) / 2;
+	t->x = (SCREEN_W - TEXTBOX_W) >> 1;
 	t->y = y + 24;
 	t->visible = true;
 
@@ -446,7 +446,7 @@
 
 		p->w = PUSHBUTTON_W;
 		p->h = 16;
-		p->x = ((SCREEN_W - tx) / 2) + (i * 100);
+		p->x = ((SCREEN_W - tx) >> 1) + (i * 100);
 		p->y = y + 42;
 		p->caption = buttonText[typ][i];
 		p->visible = true;
@@ -567,7 +567,7 @@
 
 		// draw input box
 		drawWindow(wlen);
-		textOutShadow(headlineX, y + 4, PAL_BUTTON1, PAL_BUTTON2, headline);
+		textOutShadow(headlineX, y + 4, PAL_FORGRND, PAL_BUTTON2, headline);
 		clearRect(t->x, t->y, t->w, t->h);
 		hLine(t->x - 1,    t->y - 1,    t->w + 2, PAL_BUTTON2);
 		vLine(t->x - 1,    t->y,        t->h + 1, PAL_BUTTON2);
--- a/src/ft2_tables.c
+++ b/src/ft2_tables.c
@@ -453,11 +453,11 @@
 		{11, 6, 8},{63, 38, 50},{15, 15, 15},{63, 63, 63},
 		{63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63}
 	},
-	{
-		{0, 0, 0},{63, 0, 63},{0, 21, 0},{63, 44, 0},
-		{0, 63, 0},{63, 63, 63},{63, 0, 0},{0, 0, 0},
-		{0, 28, 0},{0, 63, 0},{23, 0, 0},{63, 0, 0},
-		{0, 63, 63},{0, 63, 63},{0, 63, 63},{0, 63, 63}
+	{ // "Space Pigs" -> new "Dark mode"
+		{0, 0, 0},{31, 36, 42},{6, 6, 9},{47, 50, 54},
+		{11, 12, 13},{55, 55, 56},{32, 32, 33},{0, 0, 0},
+		{3, 4, 4},{22, 24, 26},{15, 15, 15},{50, 50, 52},
+		{55, 55, 56},{63, 63, 63},{63, 63, 63},{63, 63, 63}
 	},
 	{
 		{0, 0, 0},{50, 46, 63},{15, 0, 16},{59, 58, 63},
--- /dev/null
+++ b/vs2019_project/ft2-clone/newpal.txt
@@ -1,0 +1,4 @@
+		{0, 0, 0},{31, 36, 42},{6, 6, 9},{47, 50, 54},
+		{11, 12, 13},{55, 55, 56},{32, 32, 33},{0, 0, 0},
+		{3, 4, 4},{22, 24, 26},{15, 15, 15},{50, 50, 52},
+		{55, 55, 56},{63, 63, 63},{63, 63, 63},{63, 63, 63}
binary files /dev/null b/vs2019_project/ft2-clone/x64/Debug/ft2_diskop.obj.enc differ