shithub: ft²

Download patch

ref: 5ffa61cd4ef639f057683070f1c85fe5ecaeec0c
parent: 7631018400739f8f20f36d8f038d93ef028fae0a
parent: e3b56c7ee293cf8c61f2a2c480e660527fcbd575
author: qwx <qwx@sciops.net>
date: Fri Mar 14 21:26:48 EDT 2025

sync with upstream

--- a/LICENSES.txt
+++ b/LICENSES.txt
@@ -9,9 +9,9 @@
 rtmidi:
 src\rtmidi\LICENSE.txt
 
-Graphics, except a few bitmaps: by Magnus H�gdahl
+Graphics, except a few bitmaps: by Magnus H�gdahl
 (CC BY-NC-SA 4.0):
 src\gfxdata\bmp\LICENSE.txt
 
 SDL2:
-vs2019_project\ft2-clone\sdl\LICENSE.txt
\ No newline at end of file
+vs2019_project\ft2-clone\sdl\LICENSE.txt
--- /dev/null
+++ b/make-plan9.rc
@@ -1,0 +1,23 @@
+#!/bin/rc
+rfork ne
+
+fn pragma_pack {
+	sed 's/#pragma[ 	]+pack[ 	(]*(push|1)[ 	)]*/#pragma pack on/g
+s/#pragma[ 	]+pack[ 	(]*(pop|0)[ 	)]*/#pragma pack off/g
+s/#ifdef[ 	]+_MSC_VER/#if defined(_MSC_VER) || defined(__plan9__)/g' $1
+}
+
+for(f in src/*.[ch] src/*/*.[ch]){
+	grep -s '^#pragma[ 	]+pack' $f && ! grep -s '^#pragma pack off' $f && {
+		pragma_pack $f >$f.p
+		mv $f.p $f
+	}
+}
+
+{ test -d npe -o -d /sys/include/npe || {
+	hget https://git.sr.ht/~ft/npe/archive/master.tar.gz | tar xz &&
+	cd npe-master &&
+	mk install &&
+	cd .. &&
+	mv npe-master npe
+} } && mk -f mkfile.plan9 $*
--- /dev/null
+++ b/midi.c
@@ -1,0 +1,103 @@
+#include <stdio.h>
+#include <thread.h>
+#include "ft2_header.h"
+#include "ft2_edit.h"
+#include "ft2_config.h"
+#include "ft2_gui.h"
+#include "ft2_midi.h"
+#include "ft2_audio.h"
+#include "ft2_mouse.h"
+#include "ft2_pattern_ed.h"
+#include "ft2_structs.h"
+#include "rtmidi/rtmidi_c.h"
+
+static struct RtMidiWrapper notrt;
+static RtMidiCCallback callback;
+static int mpfd = -1;
+
+unsigned int
+rtmidi_get_port_count(RtMidiPtr)
+{
+	if(access("/srv/midi", AREAD) < 0){
+		notrt.ok = false;
+		return 0;
+	}
+	notrt.ok = true;
+	return 1;
+}
+
+char *
+rtmidi_get_port_name(RtMidiPtr, unsigned int)
+{
+	char *s;
+
+	if((s = strdup("/srv/midi")) == nil)
+		sysfatal("strdup: %r");
+	return s;
+}
+
+void
+rtmidi_in_cancel_callback(RtMidiInPtr)
+{
+}
+
+void rtmidi_close_port(RtMidiPtr)
+{
+	close(mpfd);
+	mpfd = -1;
+	callback = nil;
+	notrt.ok = false;
+}
+
+void rtmidi_in_free(RtMidiInPtr)
+{
+}
+
+RtMidiInPtr
+rtmidi_in_create_default(void)
+{
+	notrt.ok = true;
+	return &notrt;
+}
+
+void
+midiproc(void *)
+{
+	int fd, n, k;
+	uchar buf[1024];
+
+	while((n = read(mpfd, buf, sizeof buf)) > 0){
+		if(n & 3)
+			fprint(2, "midiproc: malformed message size %d\n", n);
+		for(k=0; k<n; k+=4)
+			if(callback != nil)
+				callback(.0, buf+k+1, 3, nil);
+			else
+				fprint(2, "midiproc: discarding message\n");
+	}
+	fprint(2, "midiproc is off this merry-go-round: %r\n");
+	mpfd = -1;
+}
+
+void
+rtmidi_open_port(RtMidiPtr, unsigned int, char *)
+{
+	notrt.ok = true;
+	if((mpfd = open("/srv/midi", OREAD)) < 0){
+		notrt.ok = false;
+		return;
+	}
+	if(procrfork(midiproc, nil, mainstacksize, RFFDG) < 0)
+		sysfatal("proccreate: %r");
+}
+
+void
+rtmidi_in_set_callback(RtMidiInPtr, RtMidiCCallback fn, void *)
+{
+	callback = fn;
+}
+
+void
+rtmidi_in_ignore_types(RtMidiInPtr, bool, bool, bool)
+{
+}
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,4 @@
+default:V: all
+
+%:V:
+	./make-plan9.rc $stem
--- /dev/null
+++ b/mkfile.plan9
@@ -1,0 +1,145 @@
+</$objtype/mkfile
+
+BIN=/$objtype/bin/audio
+TARG=ft2
+CFLAGS=$CFLAGS -p -Isrc -Isrc/rtmidi -I/sys/include/npe -D__plan9__ -DHAS_MIDI
+
+HFILES=\
+	src/ft2_about.h\
+	src/ft2_audio.h\
+	src/ft2_audioselector.h\
+	src/ft2_bmp.h\
+	src/ft2_checkboxes.h\
+	src/ft2_config.h\
+	src/ft2_cpu.h\
+	src/ft2_diskop.h\
+	src/ft2_edit.h\
+	src/ft2_events.h\
+	src/ft2_gfxdata.h\
+	src/ft2_gui.h\
+	src/ft2_header.h\
+	src/ft2_help.h\
+	src/ft2_hpc.h\
+	src/ft2_inst_ed.h\
+	src/ft2_keyboard.h\
+	src/ft2_midi.h\
+	src/ft2_module_loader.h\
+	src/ft2_module_saver.h\
+	src/ft2_mouse.h\
+	src/ft2_nibbles.h\
+	src/ft2_palette.h\
+	src/ft2_pattern_draw.h\
+	src/ft2_pattern_ed.h\
+	src/ft2_pushbuttons.h\
+	src/ft2_radiobuttons.h\
+	src/ft2_random.h\
+	src/ft2_replayer.h\
+	src/ft2_sample_ed.h\
+	src/ft2_sample_ed_features.h\
+	src/ft2_sample_loader.h\
+	src/ft2_sample_saver.h\
+	src/ft2_sampling.h\
+	src/ft2_scrollbars.h\
+	src/ft2_smpfx.h\
+	src/ft2_structs.h\
+	src/ft2_sysreqs.h\
+	src/ft2_tables.h\
+	src/ft2_textboxes.h\
+	src/ft2_trim.h\
+	src/ft2_unicode.h\
+	src/ft2_video.h\
+	src/ft2_wav_renderer.h\
+	src/helpdata/ft2_help_data.h\
+	src/mixer/ft2_cubic_spline.h\
+	src/mixer/ft2_mix.h\
+	src/mixer/ft2_mix_macros.h\
+	src/mixer/ft2_quadratic_spline.h\
+	src/mixer/ft2_silence_mix.h\
+	src/mixer/ft2_windowed_sinc.h\
+	src/scopes/ft2_scope_macros.h\
+	src/scopes/ft2_scopedraw.h\
+	src/scopes/ft2_scopes.h\
+
+OFILES=\
+	src/ft2_about.$O\
+	src/ft2_audio.$O\
+	src/ft2_audioselector.$O\
+	src/ft2_bmp.$O\
+	src/ft2_checkboxes.$O\
+	src/ft2_config.$O\
+	src/ft2_diskop.$O\
+	src/ft2_edit.$O\
+	src/ft2_events.$O\
+	src/ft2_gui.$O\
+	src/ft2_help.$O\
+	src/ft2_hpc.$O\
+	src/ft2_inst_ed.$O\
+	src/ft2_keyboard.$O\
+	src/ft2_main.$O\
+	src/ft2_midi.$O\
+	src/ft2_module_loader.$O\
+	src/ft2_module_saver.$O\
+	src/ft2_mouse.$O\
+	src/ft2_nibbles.$O\
+	src/ft2_palette.$O\
+	src/ft2_pattern_draw.$O\
+	src/ft2_pattern_ed.$O\
+	src/ft2_pushbuttons.$O\
+	src/ft2_radiobuttons.$O\
+	src/ft2_random.$O\
+	src/ft2_replayer.$O\
+	src/ft2_sample_ed.$O\
+	src/ft2_sample_ed_features.$O\
+	src/ft2_sample_loader.$O\
+	src/ft2_sample_saver.$O\
+	src/ft2_sampling.$O\
+	src/ft2_scrollbars.$O\
+	src/ft2_smpfx.$O\
+	src/ft2_structs.$O\
+	src/ft2_sysreqs.$O\
+	src/ft2_tables.$O\
+	src/ft2_textboxes.$O\
+	src/ft2_trim.$O\
+	src/ft2_unicode.$O\
+	src/ft2_video.$O\
+	src/ft2_wav_renderer.$O\
+	src/gfxdata/ft2_bmp_fonts.$O\
+	src/gfxdata/ft2_bmp_gui.$O\
+	src/gfxdata/ft2_bmp_instr.$O\
+	src/gfxdata/ft2_bmp_logo.$O\
+	src/gfxdata/ft2_bmp_looppins.$O\
+	src/gfxdata/ft2_bmp_midi.$O\
+	src/gfxdata/ft2_bmp_mouse.$O\
+	src/gfxdata/ft2_bmp_nibbles.$O\
+	src/gfxdata/ft2_bmp_scopes.$O\
+	src/mixer/ft2_cubic_spline.$O\
+	src/mixer/ft2_mix.$O\
+	src/mixer/ft2_quadratic_spline.$O\
+	src/mixer/ft2_silence_mix.$O\
+	src/mixer/ft2_windowed_sinc.$O\
+	src/modloaders/ft2_load_bem.$O\
+	src/modloaders/ft2_load_digi.$O\
+	src/modloaders/ft2_load_it.$O\
+	src/modloaders/ft2_load_mod.$O\
+	src/modloaders/ft2_load_s3m.$O\
+	src/modloaders/ft2_load_stk.$O\
+	src/modloaders/ft2_load_stm.$O\
+	src/modloaders/ft2_load_xm.$O\
+	src/scopes/ft2_scopedraw.$O\
+	src/scopes/ft2_scopes.$O\
+	src/smploaders/ft2_load_aiff.$O\
+	src/smploaders/ft2_load_brr.$O\
+	src/smploaders/ft2_load_flac.$O\
+	src/smploaders/ft2_load_iff.$O\
+	src/smploaders/ft2_load_raw.$O\
+	src/smploaders/ft2_load_wav.$O\
+	midi.$O\
+
+default:V: all
+
+CLEANFILES=$OFILES
+
+</sys/src/cmd/mkone
+
+%.$O: %.c
+	$CC $CFLAGS -o $target $stem.c
--- a/release/linux/.gitignore
+++ b/release/linux/.gitignore
@@ -1,4 +1,4 @@
 # Ignore everything in this directory
 *
 # Except this file
-!.gitignore
\ No newline at end of file
+!.gitignore
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Headers
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Headers
@@ -1,1 +1,0 @@
-Versions/Current/Headers
\ No newline at end of file
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Resources
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Resources
@@ -1,1 +1,0 @@
-Versions/Current/Resources
\ No newline at end of file
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/SDL2
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/SDL2
@@ -1,1 +1,0 @@
-Versions/Current/SDL2
\ No newline at end of file
binary files a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/SDL2 b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/SDL2 differ
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/Current
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/Current
@@ -1,1 +1,0 @@
-A
\ No newline at end of file
binary files a/release/win32/SDL2.dll b/release/win32/SDL2.dll differ
binary files a/release/win64/SDL2.dll b/release/win64/SDL2.dll differ
--- a/src/LICENSE.txt
+++ b/src/LICENSE.txt
@@ -1,6 +1,6 @@
 BSD 3-clause license:
 
-Copyright (c) 2016-2025, Olav S�rensen
+Copyright (c) 2016-2025, Olav S�rensen
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -17,10 +17,11 @@
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL OLAV S�RENSEN BE LIABLE FOR ANY
+DISCLAIMED. IN NO EVENT SHALL OLAV S�RENSEN BE LIABLE FOR ANY
 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\ No newline at end of file
--- a/src/ft2_about.h
+++ b/src/ft2_about.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_about_h_
+#define _ft2_about_h_
 
 void renderAboutScreenFrame(void);
 void initAboutScreen(void);
@@ -5,3 +6,5 @@
 void showAboutScreen(void);
 void hideAboutScreen(void);
 void exitAboutScreen(void);
+
+#endif
--- a/src/ft2_audio.c
+++ b/src/ft2_audio.c
@@ -5,6 +5,7 @@
 
 #include <stdio.h>
 #include <stdint.h>
+#include <math.h>
 #include "ft2_header.h"
 #include "ft2_config.h"
 #include "scopes/ft2_scopes.h"
--- a/src/ft2_audio.h
+++ b/src/ft2_audio.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_audio_h_
+#define _ft2_audio_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -74,9 +75,9 @@
 	float fVolume, fCurrVolumeL, fCurrVolumeR, fVolumeLDelta, fVolumeRDelta, fTargetVolumeL, fTargetVolumeR;
 } voice_t;
 
-#ifdef _MSC_VER
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct pattSyncData_t // used for audio/video sync queue (pack to save RAM)
 {
@@ -87,8 +88,8 @@
 __attribute__ ((packed))
 #endif
 pattSyncData_t;
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 typedef struct pattSync_t
@@ -156,3 +157,5 @@
 extern pattSync_t pattSync;
 
 extern volatile bool pattQueueClearing, chQueueClearing;
+
+#endif
--- a/src/ft2_audioselector.h
+++ b/src/ft2_audioselector.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_audioselector_h_
+#define _ft2_audioselector_h_
 
 #include <stdint.h>
 
@@ -20,3 +21,5 @@
 void sbAudInputSetPos(uint32_t pos);
 void freeAudioDeviceLists(void);
 void freeAudioDeviceSelectorBuffers(void);
+
+#endif
--- a/src/ft2_bmp.h
+++ b/src/ft2_bmp.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_bmp_h_
+#define _ft2_bmp_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -17,3 +18,5 @@
 
 bool loadBMPs(void);
 void freeBMPs(void);
+
+#endif
--- a/src/ft2_checkboxes.h
+++ b/src/ft2_checkboxes.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_checkboxes_h_
+#define _ft2_checkboxes_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -123,3 +124,5 @@
 void handleCheckBoxesWhileMouseDown(void);
 bool testCheckBoxMouseDown(void);
 void testCheckBoxMouseRelease(void);
+
+#endif
--- a/src/ft2_config.h
+++ b/src/ft2_config.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_config_h_
+#define _ft2_config_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -85,9 +86,9 @@
 	START_IN_FULLSCR = 128,
 };
 
-#ifdef _MSC_VER
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct highScoreType_t
 {
@@ -162,8 +163,8 @@
 #endif
 config_t;
 
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 void resetConfig(void);
@@ -277,3 +278,5 @@
 void sbMIDISens(uint32_t pos);
 
 extern config_t config;
+
+#endif
--- /dev/null
+++ b/src/ft2_cpu.h
@@ -1,0 +1,35 @@
+#ifndef _ft2_cpu_h_
+#define _ft2_cpu_h_
+
+#include <stdint.h>
+
+#ifdef _WIN32
+
+#ifdef _WIN64
+#define CPU_64BIT 1
+#else
+#define CPU_64BIT 0
+#endif
+
+#else
+#include <limits.h>
+
+#if __WORDSIZE == 64
+#define CPU_64BIT 1
+#else
+#define CPU_64BIT 0
+#endif
+
+#endif
+
+#if CPU_64BIT
+#define CPU_BITS 64
+#define uintCPUWord_t uint64_t
+#define intCPUWord_t int64_t
+#else
+#define CPU_BITS 32
+#define uintCPUWord_t uint32_t
+#define intCPUWord_t int32_t
+#endif
+
+#endif
--- a/src/ft2_diskop.c
+++ b/src/ft2_diskop.c
@@ -1568,14 +1568,15 @@
 {
 	DirRec *dirEntry = &FReq_Buffer[rad];
 
-	char *name = unicharToCp850(dirEntry->nameU, true);
-	if (name == NULL)
-		return NULL;
+	//char *name = unicharToCp850(dirEntry->nameU, true);
+	//if (name == NULL)
+	//	return NULL;
+	char *name = dirEntry->nameU;
 
 	const int32_t nameLen = (int32_t)strlen(name);
 	if (nameLen == 0)
 	{
-		free(name);
+		//free(name);
 		return NULL;
 	}
 
@@ -1582,7 +1583,7 @@
 	char *p = (char *)malloc(nameLen+1+1);
 	if (p == NULL)
 	{
-		free(name);
+		//free(name);
 		return NULL;
 	}
 
@@ -1597,7 +1598,7 @@
 
 		strcpy(&p[1], name);
 
-		free(name);
+		//free(name);
 		return p;
 	}
 	else
@@ -1609,7 +1610,7 @@
 		{
 			// sort by filename
 			strcpy(p, name);
-			free(name);
+			//free(name);
 			return p;
 		}
 		else
@@ -1619,7 +1620,7 @@
 			if (extLen <= 1)
 			{
 				strcpy(p, name);
-				free(name);
+				//free(name);
 				return p;
 			}
 
@@ -1628,12 +1629,27 @@
 			memcpy(&p[extLen-1], name, i);
 			p[nameLen-1] = '\0';
 
-			free(name);
+			//free(name);
 			return p;
 		}
 	}
 }
 
+static int dcmp(void *a, void *b)
+{
+	DirRec *d, *e;
+	char *n, *m;
+
+	// FIXME: reimplement dcmp with the stuff the rest does
+	d = a;
+	e = b;
+	//n = d->nameU;//unicharToCp437(d->nameU, true);
+	//m = e->nameU;//unicharToCp437(e->nameU, true);
+	n = ach(d - FReq_Buffer);
+	m = ach(e - FReq_Buffer);
+	return _stricmp(n, m);
+}
+
 static void sortDirectory(void)
 {
 	bool didSwap;
@@ -1640,6 +1656,8 @@
 
 	if (FReq_FileCount < 2)
 		return; // no need to sort
+	qsort(FReq_Buffer, FReq_FileCount, sizeof *FReq_Buffer, dcmp);
+	return;
 
 	uint32_t offset = FReq_FileCount >> 1;
 	while (offset > 0)
--- a/src/ft2_diskop.h
+++ b/src/ft2_diskop.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_diskop_h_
+#define _ft2_diskop_h_
 
 #include <stdint.h>
 #include "ft2_unicode.h"
@@ -84,3 +85,5 @@
 void trimEntryName(char *name, bool isDir);
 void createFileOverwriteText(char *filename, char *buffer);
 bool fileExistsAnsi(char *str);
+
+#endif
--- a/src/ft2_edit.h
+++ b/src/ft2_edit.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_edit_h_
+#define _ft2_edit_h_
 
 #include <stdint.h>
 #include <SDL2/SDL.h>
@@ -76,3 +77,5 @@
 void remapTrack(void);
 void remapPattern(void);
 void remapSong(void);
+
+#endif
--- a/src/ft2_events.h
+++ b/src/ft2_events.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_events_h_
+#define _ft2_events_h_
 
 #include <SDL2/SDL.h>
 #include <stdint.h>
@@ -20,4 +21,6 @@
 #ifdef _WIN32
 bool handleSingleInstancing(int32_t argc, char **argv);
 void closeSingleInstancing(void);
+#endif
+
 #endif
--- a/src/ft2_gfxdata.h
+++ b/src/ft2_gfxdata.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_gfxdata_h_
+#define _ft2_gfxdata_h_
 
 #include <stdint.h>
 
@@ -45,3 +46,5 @@
 // ft2_bmp_gui.c
 extern const uint8_t checkboxGfxBMP[776];
 extern const uint8_t radiobuttonGfxBMP[404];
+
+#endif
--- a/src/ft2_gui.h
+++ b/src/ft2_gui.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_gui_h_
+#define _ft2_gui_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -120,3 +121,5 @@
 void hideTopScreen(void);
 void showTopScreen(bool restoreScreens);
 void showBottomScreen(void);
+
+#endif
--- a/src/ft2_header.h
+++ b/src/ft2_header.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_header_h_
+#define _ft2_header_h_
 
 #include <SDL2/SDL.h>
 #include <stdint.h>
@@ -96,3 +97,5 @@
 {
 	int8_t *origPtr, *ptr;
 } smpPtr_t;
+
+#endif
--- a/src/ft2_help.h
+++ b/src/ft2_help.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_help_h_
+#define _ft2_help_h_
 
 #include <stdint.h>
 
@@ -20,3 +21,5 @@
 void rbHelpHowToUseFT2(void);
 void rbHelpFAQ(void);
 void rbHelpKnownBugs(void);
+
+#endif
--- a/src/ft2_hpc.h
+++ b/src/ft2_hpc.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_hpc_h_
+#define _ft2_hpc_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -23,3 +24,5 @@
 void hpc_SetDurationInMs(hpc_t *hpc, double dMs); // dMs = minimum 0.2442002442 ms
 void hpc_ResetCounters(hpc_t *hpc);
 void hpc_Wait(hpc_t *hpc);
+
+#endif
--- a/src/ft2_inst_ed.c
+++ b/src/ft2_inst_ed.c
@@ -23,9 +23,9 @@
 #include "ft2_structs.h"
 #include "ft2_bmp.h"
 
-#ifdef _MSC_VER
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct patHdr_t
 {
--- a/src/ft2_inst_ed.h
+++ b/src/ft2_inst_ed.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_inst_ed_h_
+#define _ft2_inst_ed_h_
 
 #include <stdint.h>
 #include "ft2_header.h"
@@ -104,3 +105,5 @@
 void showInstEditorExt(void);
 void hideInstEditorExt(void);
 void toggleInstEditorExt(void);
+
+#endif
--- a/src/ft2_keyboard.c
+++ b/src/ft2_keyboard.c
@@ -352,6 +352,27 @@
 		}
 		return;
 
+		case SDL_SCANCODE_VOLUMEUP:
+			if (config.masterVol <= 256-16)
+				config.masterVol += 16;
+			else
+				config.masterVol = 256;
+
+			setAudioAmp(config.boostLevel, config.masterVol, !!(config.specialFlags & BITDEPTH_32));
+			if (ui.configScreenShown && editor.currConfigScreen == CONFIG_SCREEN_AUDIO)
+				showConfigScreen();
+			break;
+		case SDL_SCANCODE_VOLUMEDOWN:
+			if (config.masterVol >= 16)
+				config.masterVol -= 16;
+			else
+				config.masterVol = 0;
+
+			setAudioAmp(config.boostLevel, config.masterVol, !!(config.specialFlags & BITDEPTH_32));
+			if (ui.configScreenShown && editor.currConfigScreen == CONFIG_SCREEN_AUDIO)
+				showConfigScreen();
+			break;
+
 		default: break;
 	}
 
--- a/src/ft2_keyboard.h
+++ b/src/ft2_keyboard.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_keyboard_h_
+#define _ft2_keyboard_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -18,3 +19,5 @@
 void keyUpHandler(SDL_Scancode scancode, SDL_Keycode keycode);
 void keyDownHandler(SDL_Scancode scancode, SDL_Keycode keycode, bool keyWasRepeated);
 void readKeyModifiers(void);
+
+#endif
--- a/src/ft2_main.c
+++ b/src/ft2_main.c
@@ -91,12 +91,13 @@
 	}
 #endif
 
-	// ALT+F4 is used in FT2, but is "close program" in some cases...
+	// ALT+F4 is used in FT2, but is "close program" in Windows...
 #if SDL_MINOR_VERSION >= 24 || (SDL_MINOR_VERSION == 0 && SDL_PATCHLEVEL >= 4)
 	SDL_SetHint("SDL_WINDOWS_NO_CLOSE_ON_ALT_F4", "1");
 #endif
 
 #ifdef _WIN32
+
 #ifndef _MSC_VER
 	SetProcessDPIAware();
 #endif
--- a/src/ft2_midi.c
+++ b/src/ft2_midi.c
@@ -279,8 +279,10 @@
 {
 	uint32_t i;
 
-	if (midiInDev == NULL || editor.midiConfigFileLocationU == NULL)
+	if (midiInDev == NULL || editor.midiConfigFileLocationU == NULL) {
 		goto setDefMidiInputDev;
+		//midi.inputDeviceName = NULL;
+	}
 
 	const uint32_t numDevices = getNumMidiInDevices();
 	if (numDevices == 0)
@@ -487,7 +489,12 @@
 	closeMidiInDevice();
 	freeMidiIn();
 	initMidiIn();
-	openMidiInDevice(midi.inputDevice);
+	if(!openMidiInDevice(midi.inputDevice)){
+		free(midi.inputDeviceName);
+		midi.inputDeviceName = NULL;
+		midi.inputDevice = -1;
+		return false;
+	}
 
 	drawMidiInputList();
 	return true;
--- a/src/ft2_module_loader.h
+++ b/src/ft2_module_loader.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_module_loader_h_
+#define _ft2_module_loader_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -23,3 +24,5 @@
 extern note_t *patternTmp[MAX_PATTERNS];
 extern instr_t *instrTmp[1+256];
 extern song_t songTmp;
+
+#endif
--- a/src/ft2_module_saver.h
+++ b/src/ft2_module_saver.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_module_saver_h_
+#define _ft2_module_saver_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -6,3 +7,5 @@
 
 void saveMusic(UNICHAR *filenameU);
 bool saveXM(UNICHAR *filenameU);
+
+#endif
--- a/src/ft2_mouse.h
+++ b/src/ft2_mouse.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_mouse_h_
+#define _ft2_mouse_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -52,3 +53,5 @@
 void handleLastGUIObjectDown(void);
 void readMouseXY(void);
 void resetMouseBusyAnimation(void);
+
+#endif
--- a/src/ft2_nibbles.h
+++ b/src/ft2_nibbles.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_nibbles_h_
+#define _ft2_nibbles_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -24,3 +25,5 @@
 void nibblesToggleGrid(void);
 void nibblesToggleWrap(void);
 bool testNibblesCheatCodes(SDL_Keycode keycode);
+
+#endif
--- a/src/ft2_palette.h
+++ b/src/ft2_palette.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_palette_h_
+#define _ft2_palette_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -44,9 +45,9 @@
 	PAL_NUM
 };
 
-#ifdef _MSC_VER
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct pal16_t
 {
@@ -56,8 +57,8 @@
 __attribute__ ((packed))
 #endif
 pal16;
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 void setCustomPalColor(uint32_t color);
@@ -99,3 +100,5 @@
 void rbConfigPalUserDefined(void);
 
 extern uint8_t cfg_ColorNum;
+
+#endif
--- a/src/ft2_pattern_draw.h
+++ b/src/ft2_pattern_draw.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_pattern_draw_h_
+#define _ft2_pattern_draw_h_
 
 #include <stdint.h>
 
@@ -6,3 +7,5 @@
 void drawPatternBorders(void);
 void writePattern(int32_t currRow, int32_t currPattern);
 void pattTwoHexOut(uint32_t xPos, uint32_t yPos, uint8_t val, uint32_t color);
+
+#endif
--- a/src/ft2_pattern_ed.h
+++ b/src/ft2_pattern_ed.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_pattern_ed_h_
+#define _ft2_pattern_ed_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -172,3 +173,5 @@
 void sbSmpBankPos(uint32_t pos);
 void pbToggleLogo(void);
 void pbToggleBadge(void);
+
+#endif
--- a/src/ft2_pushbuttons.h
+++ b/src/ft2_pushbuttons.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_pushbuttons_h_
+#define _ft2_pushbuttons_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -419,3 +420,5 @@
 void handlePushButtonsWhileMouseDown(void);
 bool testPushButtonMouseDown(void);
 int16_t testPushButtonMouseRelease(bool runCallback);
+
+#endif
--- a/src/ft2_radiobuttons.h
+++ b/src/ft2_radiobuttons.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_radiobuttons_h_
+#define _ft2_radiobuttons_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -231,3 +232,5 @@
 void handleRadioButtonsWhileMouseDown(void);
 bool testRadioButtonMouseDown(void);
 void testRadioButtonMouseRelease(void);
+
+#endif
--- a/src/ft2_replayer.h
+++ b/src/ft2_replayer.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_replayer_h_
+#define _ft2_replayer_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -89,9 +90,9 @@
 ** absolutely know what you are doing!
 */
 
-#ifdef _MSC_VER
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct xmHdr_t
 {
@@ -204,8 +205,8 @@
 #endif
 syncedChannel_t;
 
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 typedef struct sample_t
@@ -357,3 +358,5 @@
 extern song_t song;
 extern instr_t *instr[128+4];
 extern note_t *pattern[MAX_PATTERNS];
+
+#endif
--- a/src/ft2_sample_ed.h
+++ b/src/ft2_sample_ed.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_sample_ed_h_
+#define _ft2_sample_ed_h_
 
 #include <stdint.h>
 #include "ft2_header.h"
@@ -87,3 +88,5 @@
 void sampleLine(int32_t x1, int32_t x2, int32_t y1, int32_t y2);
 
 extern int32_t smpEd_Rx1, smpEd_Rx2;
+
+#endif
--- a/src/ft2_sample_ed_features.h
+++ b/src/ft2_sample_ed_features.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_sample_ed_features_h_
+#define _ft2_sample_ed_features_h_
 
 #include <stdint.h>
 
@@ -7,3 +8,5 @@
 void pbSampleMix(void);
 void pbSampleVolume(void);
 void handleEchoToolPanic(void);
+
+#endif
--- a/src/ft2_sample_loader.h
+++ b/src/ft2_sample_loader.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_sample_loader_h_
+#define _ft2_sample_loader_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -28,3 +29,5 @@
 
 // file extensions accepted by Disk Op. in sample mode
 extern char *supportedSmpExtensions[];
+
+#endif
--- a/src/ft2_sample_saver.h
+++ b/src/ft2_sample_saver.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_sample_saver_h_
+#define _ft2_sample_saver_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -11,3 +12,5 @@
 };
 
 void saveSample(UNICHAR *filenameU, bool saveAsRange);
+
+#endif
--- a/src/ft2_sampling.h
+++ b/src/ft2_sampling.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_sampling_h_
+#define _ft2_sampling_h_
 
 enum
 {
@@ -10,3 +11,5 @@
 void startSampling(void);
 void stopSampling(void);
 void handleSamplingUpdates(void);
+
+#endif
--- a/src/ft2_scrollbars.c
+++ b/src/ft2_scrollbars.c
@@ -252,7 +252,7 @@
 		}
 
 		// prevent scrollbar thumb coords from being outside of the scrollbar area
-		thumbX = CLAMP(thumbX, scrollBar->x, scrollEnd-1);
+		thumbX = CLAMP((int)thumbX, (int)scrollBar->x, (int)scrollEnd-1);
 		if (thumbX+thumbW > scrollEnd)
 			thumbW = scrollEnd - thumbX;
 	}
@@ -294,7 +294,7 @@
 		}
 
 		// prevent scrollbar thumb coords from being outside of the scrollbar area
-		thumbY = CLAMP(thumbY, scrollBar->y, scrollEnd - 1);
+		thumbY = CLAMP((int)thumbY, (int)scrollBar->y, (int)scrollEnd - 1);
 		if (thumbY+thumbH > scrollEnd)
 			thumbH = scrollEnd - thumbY;
 	}
@@ -519,7 +519,7 @@
 
 					scrollPos = mouse.x - scrollBias - scrollBar->x;
 					assert(scrollBar->w > 0);
-					scrollPos = CLAMP(scrollPos, 0, scrollBar->w);
+					scrollPos = CLAMP((int)scrollPos, 0, (int)scrollBar->w);
 
 					if (scrollBar->thumbType == SCROLLBAR_FIXED_THUMB_SIZE)
 						length = scrollBar->w - scrollBar->thumbW;
@@ -556,7 +556,7 @@
 					scrollPos = mouse.y - scrollBias - scrollBar->y;
 
 					assert(scrollBar->h > 0);
-					scrollPos = CLAMP(scrollPos, 0, scrollBar->h);
+					scrollPos = CLAMP((int)scrollPos, 0, (int)scrollBar->h);
 
 					length = scrollBar->h + (scrollBar->originalThumbSize - scrollBar->thumbH);
 					if (length < 1)
--- a/src/ft2_scrollbars.h
+++ b/src/ft2_scrollbars.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_scrollbars_h_
+#define _ft2_scrollbars_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -93,3 +94,5 @@
 void testScrollBarMouseRelease(void);
 void handleScrollBarsWhileMouseDown(void);
 void initializeScrollBars(void);
+
+#endif
--- a/src/ft2_structs.h
+++ b/src/ft2_structs.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_structs_h_
+#define _ft2_structs_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -81,3 +82,5 @@
 extern editor_t editor;
 extern ui_t ui;
 extern cursor_t cursor;
+
+#endif
--- a/src/ft2_sysreqs.h
+++ b/src/ft2_sysreqs.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_sysreqs_h_
+#define _ft2_sysreqs_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -35,3 +36,5 @@
 extern void (*loaderMsgBox)(const char *, ...);
 extern int16_t (*loaderSysReq)(int16_t, const char *, const char *, void (*)(void));
 // ---------------
+
+#endif
--- a/src/ft2_tables.h
+++ b/src/ft2_tables.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_tables_h_
+#define _ft2_tables_h_
 
 #include <stdint.h>
 #include "ft2_palette.h" // pal16 typedef
@@ -48,3 +49,5 @@
 extern const uint8_t defConfigData[CONFIG_FILE_SIZE];
 
 extern const uint64_t musicTimeTab52[(MAX_BPM-MIN_BPM)+1];
+
+#endif
--- a/src/ft2_textboxes.h
+++ b/src/ft2_textboxes.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_textboxes_h_
+#define _ft2_textboxes_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -76,3 +77,5 @@
 void handleTextEditInputChar(char textChar);
 void handleTextBoxWhileMouseDown(void);
 void freeTextBoxes(void);
+
+#endif
--- a/src/ft2_trim.h
+++ b/src/ft2_trim.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_trim_h_
+#define _ft2_trim_h_
 
 void drawTrimScreen(void);
 void hideTrimScreen(void);
@@ -15,3 +16,5 @@
 void cbTrimSmpsTo8Bit(void);
 void pbTrimCalc(void);
 void pbTrimDoTrim(void);
+
+#endif
--- a/src/ft2_video.h
+++ b/src/ft2_video.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_video_h_
+#define _ft2_video_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -73,3 +74,5 @@
 void setWindowSizeFromConfig(bool updateRenderer);
 bool recreateTexture(void);
 void toggleFullscreen(void);
+
+#endif
--- a/src/ft2_wav_renderer.h
+++ b/src/ft2_wav_renderer.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_wav_renderer_h_
+#define _ft2_wav_renderer_h_
 
 #include <stdint.h>
 #include "ft2_header.h"
@@ -27,3 +28,5 @@
 void resetWavRenderer(void);
 void rbWavRenderBitDepth16(void);
 void rbWavRenderBitDepth32(void);
+
+#endif
--- /dev/null
+++ b/src/mixer/ft2_center_mix.h
@@ -1,0 +1,79 @@
+#ifndef _ft2_center_mix_h_
+#define _ft2_center_mix_h_
+
+#include <stdint.h>
+#include "../ft2_audio.h"
+
+// no volume ramping
+
+// 8-bit
+void centerMix8bNoLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bBidiLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bNoLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bBidiLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bNoLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bBidiLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bNoLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bBidiLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bNoLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bBidiLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+
+// 16-bit
+void centerMix16bNoLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bBidiLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bNoLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bBidiLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bNoLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bBidiLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bNoLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bBidiLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bNoLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bBidiLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+
+// volume ramping
+
+// 8-bit
+void centerMix8bRampNoLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampBidiLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampNoLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampBidiLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampNoLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampBidiLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampNoLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampBidiLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampNoLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix8bRampBidiLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+
+// 16bit
+void centerMix16bRampNoLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampBidiLoop(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampNoLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampBidiLoopS8Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampNoLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampBidiLoopLIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampNoLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampBidiLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampNoLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+void centerMix16bRampBidiLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+
+#endif
--- a/src/mixer/ft2_mix.h
+++ b/src/mixer/ft2_mix.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_mix_h_
+#define _ft2_mix_h_
 
 #include <stdint.h>
 
@@ -17,6 +18,7 @@
 };
 
 #define MAX_TAPS 16
+
 #define MAX_LEFT_TAPS ((MAX_TAPS/2)-1)
 #define MAX_RIGHT_TAPS (MAX_TAPS/2)
 
@@ -29,3 +31,5 @@
 typedef void (*mixFunc)(void *, uint32_t, uint32_t);
 
 extern const mixFunc mixFuncTab[]; // ft2_mix.c
+
+#endif
--- a/src/mixer/ft2_mix_macros.h
+++ b/src/mixer/ft2_mix_macros.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_mix_macros_h_
+#define _ft2_mix_macros_h_
 
 #include "../ft2_audio.h"
 #include "ft2_quadratic_spline.h"
@@ -214,23 +215,45 @@
 #define WINDOWED_SINC16_INTERPOLATION(s, f, scale) \
 { \
 	const float *t = v->fSincLUT + (((uint32_t)(f) >> SINC2_FRACSHIFT) & SINC2_FRACMASK); \
-	fSample = (( s[-7] * t[0]) + \
-	           ( s[-6] * t[1]) + \
-	           ( s[-5] * t[2]) + \
-	           ( s[-4] * t[3]) + \
-	           ( s[-3] * t[4]) + \
-	           ( s[-2] * t[5]) + \
-	           ( s[-1] * t[6]) + \
-	           (  s[0] * t[7]) + \
-	           (  s[1] * t[8]) + \
-	           (  s[2] * t[9]) + \
-	           (  s[3] * t[10]) + \
-	           (  s[4] * t[11]) + \
-	           (  s[5] * t[12]) + \
-	           (  s[6] * t[13]) + \
-	           (  s[7] * t[14]) + \
-	           (  s[8] * t[15])) * (1.0f / scale); \
+	fSample = ((s[-7] * t[0]) + \
+	           (s[-6] * t[1]) + \
+	           (s[-5] * t[2]) + \
+	           (s[-4] * t[3]) + \
+	           (s[-3] * t[4]) + \
+	           (s[-2] * t[5]) + \
+	           (s[-1] * t[6]) + \
+	           ( s[0] * t[7]) + \
+	           ( s[1] * t[8]) + \
+	           ( s[2] * t[9]) + \
+	           ( s[3] * t[10]) + \
+	           ( s[4] * t[11]) + \
+	           ( s[5] * t[12]) + \
+	           ( s[6] * t[13]) + \
+	           ( s[7] * t[14]) + \
+	           ( s[8] * t[15])) * (1.0f / scale); \
 }
+#else
+#define WINDOWED_SINC16_INTERPOLATION(s, f, scale) \
+{ \
+	const float *t = v->fSincLUT + (((uint32_t)(f) << -SINC16_FSHIFT) & SINC16_FMASK); \
+	fSample = ((s[-7] * t[0]) + \
+	           (s[-6] * t[1]) + \
+	           (s[-5] * t[2]) + \
+	           (s[-4] * t[3]) + \
+	           (s[-3] * t[4]) + \
+	           (s[-2] * t[5]) + \
+	           (s[-1] * t[6]) + \
+	           ( s[0] * t[7]) + \
+	           ( s[1] * t[8]) + \
+	           ( s[2] * t[9]) + \
+	           ( s[3] * t[10]) + \
+	           ( s[4] * t[11]) + \
+	           ( s[5] * t[12]) + \
+	           ( s[6] * t[13]) + \
+	           ( s[7] * t[14]) + \
+	           ( s[8] * t[15])) * (1.0f / scale); \
+}
+#endif
 
 #define RENDER_8BIT_SMP_S8INTRP \
 	WINDOWED_SINC8_INTERPOLATION(smpPtr, positionFrac, 128) \
@@ -334,6 +357,24 @@
 		v->volumeRampLength -= samplesToMix; \
 	}
 
+#define LIMIT_MIX_NUM_MONO_RAMP \
+	if (v->volumeRampLength == 0) \
+	{ \
+		fVolumeLDelta = 0.0f; \
+		if (v->isFadeOutVoice) \
+		{ \
+			v->active = false; /* volume ramp fadeout-voice is done, shut it down */ \
+			return; \
+		} \
+	} \
+	else \
+	{ \
+		if (samplesToMix > v->volumeRampLength) \
+			samplesToMix = v->volumeRampLength; \
+		\
+		v->volumeRampLength -= samplesToMix; \
+	}
+
 #define HANDLE_SAMPLE_END \
 	position = (int32_t)(smpPtr - base); \
 	if (position >= v->sampleEnd) \
@@ -379,3 +420,4 @@
 	{ \
 		position = (int32_t)(smpPtr - base); \
 	}
+
--- a/src/mixer/ft2_silence_mix.h
+++ b/src/mixer/ft2_silence_mix.h
@@ -1,6 +1,9 @@
-#pragma once
+#ifndef _ft2_silence_mix_h_
+#define _ft2_silence_mix_h_
 
 #include <stdint.h>
 #include "../ft2_audio.h"
 
 void silenceMixRoutine(voice_t *v, int32_t numSamples);
+
+#endif
--- a/src/mixer/ft2_windowed_sinc.h
+++ b/src/mixer/ft2_windowed_sinc.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_windowed_sinc_h_
+#define _ft2_windowed_sinc_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -25,3 +26,5 @@
 
 bool setupWindowedSincTables(void);
 void freeWindowedSincTables(void);
+
+#endif
--- a/src/modloaders/ft2_load_bem.c
+++ b/src/modloaders/ft2_load_bem.c
@@ -17,9 +17,9 @@
 #define FLAG_XMPERIODS 1
 #define FLAG_LINEARSLIDES 2
 
-#ifdef _MSC_VER // please don't mess with these structs!
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__) // please don't mess with these structs!
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct bemHdr_t
 {
@@ -40,8 +40,8 @@
 __attribute__((packed))
 #endif
 bemHdr_t;
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 enum
--- a/src/modloaders/ft2_load_digi.c
+++ b/src/modloaders/ft2_load_digi.c
@@ -13,9 +13,9 @@
 #include "../ft2_tables.h"
 #include "../ft2_sysreqs.h"
 
-#ifdef _MSC_VER  // please don't mess with this struct!
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)  // please don't mess with this struct!
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct digiHdr_t
 {
@@ -40,8 +40,8 @@
 __attribute__ ((packed))
 #endif
 digiHdr_t;
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 static void readPatternNote(FILE *f, note_t *p);
--- a/src/modloaders/ft2_load_it.c
+++ b/src/modloaders/ft2_load_it.c
@@ -17,9 +17,9 @@
 #include "../ft2_sample_ed.h"
 #include "../ft2_sysreqs.h"
 
-#ifdef _MSC_VER
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct itHdr_t
 {
@@ -108,8 +108,8 @@
 #endif
 itSmpHdr_t;
 
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 static uint8_t decompBuffer[65536];
--- a/src/modloaders/ft2_load_s3m.c
+++ b/src/modloaders/ft2_load_s3m.c
@@ -13,9 +13,9 @@
 #include "../ft2_tables.h"
 #include "../ft2_sysreqs.h"
 
-#ifdef _MSC_VER // please don't mess with these structs!
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__) // please don't mess with these structs!
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct s3mSmpHdr_t
 {
@@ -47,8 +47,8 @@
 __attribute__ ((packed))
 #endif
 s3mHdr_t;
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 static uint8_t pattBuff[12288];
--- a/src/modloaders/ft2_load_stk.c
+++ b/src/modloaders/ft2_load_stk.c
@@ -13,9 +13,9 @@
 #include "../ft2_tables.h"
 #include "../ft2_sysreqs.h"
 
-#ifdef _MSC_VER  // please don't mess with this struct!
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)  // please don't mess with this struct!
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct stkHdr_t
 {
@@ -27,8 +27,8 @@
 __attribute__ ((packed))
 #endif
 stkHdr_t;
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 bool loadSTK(FILE *f, uint32_t filesize)
--- a/src/modloaders/ft2_load_stm.c
+++ b/src/modloaders/ft2_load_stm.c
@@ -13,9 +13,9 @@
 #include "../ft2_tables.h"
 #include "../ft2_sysreqs.h"
 
-#ifdef _MSC_VER // please don't mess with these structs!
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__) // please don't mess with these structs!
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct stmSmpHdr_t
 {
@@ -45,8 +45,8 @@
 __attribute__ ((packed))
 #endif
 stmHdr_t;
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 static const uint8_t stmEfx[16] = { 0, 0, 11, 0, 10, 2, 1, 3, 4, 7, 0, 5, 6, 0, 0, 0 };
--- a/src/scopes/ft2_scope_macros.h
+++ b/src/scopes/ft2_scope_macros.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_scope_macros_h_
+#define _ft2_scope_macros_h_
 
 #include <stdint.h>
 #include "../ft2_header.h"
@@ -336,3 +337,5 @@
 		\
 		s->hasLooped = true; \
 	}
+
+#endif
--- a/src/scopes/ft2_scopes.h
+++ b/src/scopes/ft2_scopes.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_scopes_h_
+#define _ft2_scopes_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -55,3 +56,5 @@
 } lastChInstr_t;
 
 extern lastChInstr_t lastChInstr[MAX_CHANNELS];
+
+#endif
binary files a/vs2019_project/ft2-clone/SDL2.dll b/vs2019_project/ft2-clone/SDL2.dll differ
--- a/vs2019_project/ft2-clone/ft2-clone.vcxproj
+++ b/vs2019_project/ft2-clone/ft2-clone.vcxproj
@@ -455,4 +455,5 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
+\ No newline at end of file
--- a/vs2019_project/ft2-clone/ft2-clone.vcxproj.filters
+++ b/vs2019_project/ft2-clone/ft2-clone.vcxproj.filters
@@ -375,4 +375,5 @@
   <ItemGroup>
     <ResourceCompile Include="..\..\src\ft2-clone.rc" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
+\ No newline at end of file
binary files a/vs2019_project/ft2-clone/sdl/lib/SDL2.lib b/vs2019_project/ft2-clone/sdl/lib/SDL2.lib differ
binary files a/vs2019_project/ft2-clone/sdl/lib/SDL2main.lib b/vs2019_project/ft2-clone/sdl/lib/SDL2main.lib differ
binary files a/vs2019_project/ft2-clone/sdl/lib64/SDL2.lib b/vs2019_project/ft2-clone/sdl/lib64/SDL2.lib differ
binary files a/vs2019_project/ft2-clone/sdl/lib64/SDL2main.lib b/vs2019_project/ft2-clone/sdl/lib64/SDL2main.lib differ
binary files a/vs2019_project/x64/Debug/SDL2.dll b/vs2019_project/x64/Debug/SDL2.dll differ