Skip to content

Commit

Permalink
v1.89 mega-commit (unfortunately)
Browse files Browse the repository at this point in the history
  • Loading branch information
8bitbubsy committed Dec 7, 2024
1 parent 5ee6928 commit 987da7a
Show file tree
Hide file tree
Showing 51 changed files with 4,717 additions and 3,129 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ Linux binaries can be found [here](https://repology.org/project/fasttracker2/ver
If these don't work for you, you'll have to compile the code manually.

# Improvements over original DOS version
- The channel resampler/mixer uses floating-point arithmetics for less errors, and has extra interpolation options (4-point "Gaussian" (SNES), 4-point cubic Hermite spline, 8-point/16-point windowed-sinc)
- The channel resampler/mixer uses floating-point arithmetics for less errors, and has extra interpolation options (4-point/6-point cubic Hermite spline, 8-point/16-point windowed-sinc)
- The sample loader supports FLAC/AIFF/BRR (SNES) samples and more WAV types than original FT2. It will also attempt to tune the sample (finetune and rel. note) to its playback frequency on load.
- It contains a new "Trim" feature, which will remove unused stuff to potentially make the module smaller
- Drag n' drop of modules/samples
- The waveform display in the sample editor shows peak based data when zoomed out
- Text boxes has a text marking option, where you can cut/copy/paste
- MOD/STM/S3M import has been slightly improved (S3M import is still not ideal, as it's not compatible with XM)
- Supports loading DIGI Booster (non-Pro) modules
- Supports loading Impulse Tracker modules (Awful support! Don't use this for playback)
- It supports loading XMs with stereo samples, uneven amount of channels, more than 32 channels, more than 16 samples per instrument, more than 128 patterns etc. The unsupported data will be mixed to mono/truncated.
- It has some small additions to make life easier (C4/middle-C Hz display in Instr. Ed., envelope point coordinate display, etc).

Expand Down
113 changes: 56 additions & 57 deletions src/ft2_about.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
#include "ft2_gfxdata.h"
#include "ft2_pattern_ed.h" // exitPatternEditorExtended()

#define LOGO_ALPHA_PERCENTAGE 73
#define LOGO_ALPHA_PERCENTAGE 72
#define STARSHINE_ALPHA_PERCENTAGE 25
#define SINUS_PHASES 1024
#define NUM_STARS 2000
#define NUM_STARS 1500
#define ABOUT_SCREEN_X 3
#define ABOUT_SCREEN_Y 3
#define ABOUT_SCREEN_W 626
Expand All @@ -30,16 +30,16 @@ typedef struct
} matrix_t;

static char *customText0 = "Original FT2 by Magnus \"Vogue\" H\224gdahl & Fredrik \"Mr.H\" Huss";
static char *customText1 = "Clone by Olav \"8bitbubsy\" S\025rensen";
static char *customText1 = "Clone by Olav \"8bitbubsy\" S\233rensen";
static char *customText2 = "https://16-bits.org";
static char customText3[256];
static int16_t customText0X, customText0Y, customText1Y, customText2Y;
static int16_t customText3Y, customText1X, customText2X, customText3X;
static int16_t sin16[SINUS_PHASES];
static uint16_t logoAlpha16, starShineAlpha16;
static uint32_t randSeed, sinp1, sinp2;
static vector_t starPoints[NUM_STARS], rotation;
static matrix_t matrix;
static vector_t starPoints[NUM_STARS], starRotation;
static matrix_t starMatrix;

void seedAboutScreenRandom(uint32_t newseed)
{
Expand All @@ -53,38 +53,6 @@ static int32_t random32(void)
return randSeed;
}

static void rotateMatrix(void)
{
#define F_2PI (float)(2.0 * PI)

const float rx2p = rotation.x * F_2PI;
const float xsin = sinf(rx2p);
const float xcos = cosf(rx2p);

const float ry2p = rotation.y * F_2PI;
const float ysin = sinf(ry2p);
const float ycos = cosf(ry2p);

const float rz2p = rotation.z * F_2PI;
const float zsin = sinf(rz2p);
const float zcos = cosf(rz2p);

// x
matrix.x.x = (xcos * zcos) + (zsin * xsin * ysin);
matrix.y.x = xsin * ycos;
matrix.z.x = (zcos * xsin * ysin) - (xcos * zsin);

// y
matrix.x.y = (zsin * xcos * ysin) - (xsin * zcos);
matrix.y.y = xcos * ycos;
matrix.z.y = (xsin * zsin) + (zcos * xcos * ysin);

// z
matrix.x.z = ycos * zsin;
matrix.y.z = 0.0f - ysin;
matrix.z.z = ycos * zcos;
}

void initAboutScreen(void)
{
vector_t *s = starPoints;
Expand All @@ -103,6 +71,16 @@ void initAboutScreen(void)
sinp2 = SINUS_PHASES/4; // cosine offset
logoAlpha16 = (65535 * LOGO_ALPHA_PERCENTAGE) / 100;
starShineAlpha16 = (65535 * STARSHINE_ALPHA_PERCENTAGE) / 100;

sprintf(customText3, "v%s (%s)", PROG_VER_STR, __DATE__);
customText0X = (SCREEN_W - textWidth(customText0)) / 2;
customText1X = (SCREEN_W - textWidth(customText1)) / 2;
customText2X = (SCREEN_W-8) - textWidth(customText2);
customText3X = (SCREEN_W-8) - textWidth(customText3);
customText0Y = 157-28;
customText1Y = 157-12;
customText2Y = 157-12;
customText3Y = 157;
}

static uint32_t blendPixels(uint32_t pixelA, uint32_t pixelB, uint16_t alpha)
Expand Down Expand Up @@ -137,16 +115,16 @@ static void starfield(void)
if (star->z >= 0.5f)
star->z -= 1.0f;

const float z = (matrix.x.z * star->x) + (matrix.y.z * star->y) + (matrix.z.z * star->z) + 0.5f;
const float z = (starMatrix.x.z * star->x) + (starMatrix.y.z * star->y) + (starMatrix.z.z * star->z) + 0.5f;
if (z <= 0.0f)
continue;

float y = (((matrix.x.y * star->x) + (matrix.y.y * star->y) + (matrix.z.y * star->z)) / z) * 400.0f;
float y = (((starMatrix.x.y * star->x) + (starMatrix.y.y * star->y) + (starMatrix.z.y * star->z)) / z) * 400.0f;
const int32_t outY = (ABOUT_SCREEN_Y+(ABOUT_SCREEN_H/2)) + (int32_t)y;
if (outY < ABOUT_SCREEN_Y || outY >= ABOUT_SCREEN_Y+ABOUT_SCREEN_H)
continue;

float x = (((matrix.x.x * star->x) + (matrix.y.x * star->y) + (matrix.z.x * star->z)) / z) * 400.0f;
float x = (((starMatrix.x.x * star->x) + (starMatrix.y.x * star->y) + (starMatrix.z.x * star->z)) / z) * 400.0f;
const int32_t outX = (ABOUT_SCREEN_X+(ABOUT_SCREEN_W/2)) + (int32_t)x;
if (outX < ABOUT_SCREEN_X || outX >= ABOUT_SCREEN_X+ABOUT_SCREEN_W)
continue;
Expand Down Expand Up @@ -189,17 +167,48 @@ static void starfield(void)
}
}

static void rotateStarfieldMatrix(void)
{
#define F_2PI (float)(2.0 * PI)

const float rx2p = starRotation.x * F_2PI;
const float xsin = sinf(rx2p);
const float xcos = cosf(rx2p);

const float ry2p = starRotation.y * F_2PI;
const float ysin = sinf(ry2p);
const float ycos = cosf(ry2p);

const float rz2p = starRotation.z * F_2PI;
const float zsin = sinf(rz2p);
const float zcos = cosf(rz2p);

// x
starMatrix.x.x = (xcos * zcos) + (zsin * xsin * ysin);
starMatrix.y.x = xsin * ycos;
starMatrix.z.x = (zcos * xsin * ysin) - (xcos * zsin);

// y
starMatrix.x.y = (zsin * xcos * ysin) - (xsin * zcos);
starMatrix.y.y = xcos * ycos;
starMatrix.z.y = (xsin * zsin) + (zcos * xcos * ysin);

// z
starMatrix.x.z = ycos * zsin;
starMatrix.y.z = 0.0f - ysin;
starMatrix.z.z = ycos * zcos;
}

void renderAboutScreenFrame(void)
{
// remember the days when you couldn't afford to do this per frame?
clearRect(ABOUT_SCREEN_X, ABOUT_SCREEN_Y, ABOUT_SCREEN_W, ABOUT_SCREEN_H);

// 3D starfield
rotateMatrix();
rotation.x -= 0.0003f;
rotation.y -= 0.0002f;
rotation.z += 0.0001f;
starfield();
starRotation.x -= 0.0003f;
starRotation.y -= 0.0002f;
starRotation.z += 0.0001f;
rotateStarfieldMatrix();

// waving FT2 logo

Expand All @@ -223,13 +232,13 @@ void renderAboutScreenFrame(void)
sinp1 = (sinp1 + 2) & (SINUS_PHASES-1);
sinp2 = (sinp2 + 3) & (SINUS_PHASES-1);

// static texts
// render static texts
textOut(customText0X, customText0Y, PAL_FORGRND, customText0);
textOut(customText1X, customText1Y, PAL_FORGRND, customText1);
textOut(customText2X, customText2Y, PAL_FORGRND, customText2);
textOut(customText3X, customText3Y, PAL_FORGRND, customText3);

showPushButton(PB_EXIT_ABOUT); // yes, we have to redraw the exit button per frame :)
showPushButton(PB_EXIT_ABOUT); // yes, we also have to redraw the exit button per frame :)
}

void showAboutScreen(void) // called once when about screen is opened
Expand All @@ -244,16 +253,6 @@ void showAboutScreen(void) // called once when about screen is opened

showPushButton(PB_EXIT_ABOUT);

sprintf(customText3, "v%s (%s)", PROG_VER_STR, __DATE__);
customText0X = (SCREEN_W - textWidth(customText0)) / 2;
customText1X = (SCREEN_W - textWidth(customText1)) / 2;
customText2X = (SCREEN_W-8) - textWidth(customText2);
customText3X = (SCREEN_W-8) - textWidth(customText3);
customText0Y = 157-28;
customText1Y = 157-12;
customText2Y = 157-12;
customText3Y = 157;

ui.aboutScreenShown = true;
}

Expand Down
26 changes: 22 additions & 4 deletions src/ft2_audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "ft2_wav_renderer.h"
#include "ft2_tables.h"
#include "ft2_structs.h"
#include "ft2_audioselector.h"
#include "mixer/ft2_mix.h"
#include "mixer/ft2_silence_mix.h"

Expand Down Expand Up @@ -961,13 +962,28 @@ bool setupAudio(bool showErrorMsg)
want.callback = audioCallback;
want.samples = configAudioBufSize;

audio.dev = SDL_OpenAudioDevice(audio.currOutputDevice, 0, &want, &have, SDL_AUDIO_ALLOW_ANY_CHANGE);
char *device = audio.currOutputDevice;
if (device != NULL && strcmp(device, DEFAULT_AUDIO_DEV_STR) == 0)
device = NULL; // force default device

audio.dev = SDL_OpenAudioDevice(device, 0, &want, &have, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
if (audio.dev == 0)
{
if (showErrorMsg)
showErrorMsgBox("Couldn't open audio device:\n\"%s\"\n\nDo you have an audio device enabled and plugged in?", SDL_GetError());
audio.dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
if (audio.currOutputDevice != NULL)
{
free(audio.currOutputDevice);
audio.currOutputDevice = NULL;
}
audio.currOutputDevice = strdup(DEFAULT_AUDIO_DEV_STR);

return false;
if (audio.dev == 0)
{
if (showErrorMsg)
showErrorMsgBox("Couldn't open audio device:\n\"%s\"\n\nDo you have an audio device enabled and plugged in?", SDL_GetError());

return false;
}
}

// test if the received audio format is compatible
Expand All @@ -991,6 +1007,7 @@ bool setupAudio(bool showErrorMsg)
return false;
}

/*
if (have.freq != 44100 && have.freq != 48000 && have.freq != 96000)
{
if (showErrorMsg)
Expand All @@ -999,6 +1016,7 @@ bool setupAudio(bool showErrorMsg)
closeAudio();
return false;
}
*/

if (!setupAudioBuffers())
{
Expand Down
45 changes: 22 additions & 23 deletions src/ft2_audioselector.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,6 @@ enum
#pragma warning(disable: 4996)
#endif

static char *getReasonableAudioDevice(int32_t iscapture) // can and will return NULL
{
int32_t numAudioDevs = SDL_GetNumAudioDevices(iscapture);
if (numAudioDevs == 0 || numAudioDevs > 1)
return NULL; // we don't know which audio output device is the default device

const char *devName = SDL_GetAudioDeviceName(0, iscapture);
if (devName == NULL)
return NULL;

return strdup(devName);
}

char *getAudioOutputDeviceFromConfig(void)
{
bool audioDeviceRead = false;
Expand Down Expand Up @@ -74,7 +61,7 @@ char *getAudioOutputDeviceFromConfig(void)
if (devString != NULL)
free(devString);

devString = getReasonableAudioDevice(OUTPUT_DEVICE);
devString = strdup(DEFAULT_AUDIO_DEV_STR);
}

// SDL_OpenAudioDevice() doesn't seem to like an empty audio device string
Expand Down Expand Up @@ -123,7 +110,7 @@ char *getAudioInputDeviceFromConfig(void)
if (devString != NULL)
free(devString);

devString = getReasonableAudioDevice(INPUT_DEVICE);
devString = strdup(DEFAULT_AUDIO_DEV_STR);
}

// SDL_OpenAudioDevice() doesn't seem to like an empty audio device string
Expand Down Expand Up @@ -183,8 +170,12 @@ void drawAudioOutputList(void)
if (strcmp(audio.currOutputDevice, audio.outputDeviceNames[deviceEntry]) == 0)
fillRect(114, y, AUDIO_SELECTORS_BOX_WIDTH, 10, PAL_BOXSLCT); // selection background color
}
else if (i == 0) // default audio device (always on top)
{
fillRect(114, y, AUDIO_SELECTORS_BOX_WIDTH, 10, PAL_BOXSLCT); // selection background color
}

char *tmpString = utf8ToCp437(audio.outputDeviceNames[deviceEntry], true);
char *tmpString = utf8ToCp850(audio.outputDeviceNames[deviceEntry], true);
if (tmpString != NULL)
{
textOutClipX(114, y, PAL_FORGRND, tmpString, 114 + AUDIO_SELECTORS_BOX_WIDTH);
Expand Down Expand Up @@ -219,8 +210,12 @@ void drawAudioInputList(void)
if (strcmp(audio.currInputDevice, audio.inputDeviceNames[deviceEntry]) == 0)
fillRect(114, y, AUDIO_SELECTORS_BOX_WIDTH, 10, PAL_BOXSLCT); // selection background color
}
else if (i == 0) // default audio device (always on top)
{
fillRect(114, y, AUDIO_SELECTORS_BOX_WIDTH, 10, PAL_BOXSLCT); // selection background color
}

char *tmpString = utf8ToCp437(audio.inputDeviceNames[deviceEntry], true);
char *tmpString = utf8ToCp850(audio.inputDeviceNames[deviceEntry], true);
if (tmpString != NULL)
{
textOutClipX(114, y, PAL_FORGRND, tmpString, 114 + AUDIO_SELECTORS_BOX_WIDTH);
Expand Down Expand Up @@ -406,13 +401,15 @@ void rescanAudioDevices(void)

// GET AUDIO OUTPUT DEVICES

audio.outputDeviceNum = SDL_GetNumAudioDevices(false);
audio.outputDeviceNum = 1 + SDL_GetNumAudioDevices(false);
if (audio.outputDeviceNum > MAX_AUDIO_DEVICES)
audio.outputDeviceNum = MAX_AUDIO_DEVICES;

for (int32_t i = 0; i < audio.outputDeviceNum; i++)
audio.outputDeviceNames[0] = strdup(DEFAULT_AUDIO_DEV_STR);

for (int32_t i = 1; i < audio.outputDeviceNum; i++)
{
const char *deviceName = SDL_GetAudioDeviceName(i, false);
const char *deviceName = SDL_GetAudioDeviceName(i-1, false);
if (deviceName == NULL)
{
audio.outputDeviceNum--; // hide device
Expand All @@ -431,13 +428,15 @@ void rescanAudioDevices(void)

// GET AUDIO INPUT DEVICES

audio.inputDeviceNum = SDL_GetNumAudioDevices(true);
audio.inputDeviceNum = 1 + SDL_GetNumAudioDevices(true);
if (audio.inputDeviceNum > MAX_AUDIO_DEVICES)
audio.inputDeviceNum = MAX_AUDIO_DEVICES;

for (int32_t i = 0; i < audio.inputDeviceNum; i++)
audio.inputDeviceNames[0] = strdup(DEFAULT_AUDIO_DEV_STR);

for (int32_t i = 1; i < audio.inputDeviceNum; i++)
{
const char *deviceName = SDL_GetAudioDeviceName(i, true);
const char *deviceName = SDL_GetAudioDeviceName(i-1, true);
if (deviceName == NULL)
{
audio.inputDeviceNum--; // hide device
Expand Down
1 change: 1 addition & 0 deletions src/ft2_audioselector.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <stdint.h>

#define DEFAULT_AUDIO_DEV_STR "(Default Audio Device)"
#define AUDIO_SELECTORS_BOX_WIDTH 247

void setToDefaultAudioOutputDevice(void);
Expand Down
Loading

0 comments on commit 987da7a

Please sign in to comment.