ref: 30d4fcf2791b1e2e9d7ae5aa008feb8dbda30c0d
parent: 824199e016e6ad8747489995fb518d43726ee8d7
parent: 93c93a0a467b6a31cc4e866c3df41a65bf2a7481
author: qwx <qwx@sciops.net>
date: Thu Mar 30 02:15:51 EDT 2023
sync upstream
--- /dev/null
+++ b/make-plan9.rc
@@ -1,0 +1,36 @@
+#!/bin/rc
+rfork ne
+
+fn pragma_once {
+ h=_^`"{echo $1 | sed 's,.*/,,g;s/\..*//g' | tr -d '
+'}^_h_
+ sed 's/#pragma once/#ifndef '^$h^'\n#define '^$h^'/g' $1 && echo && echo '#endif'
+}
+
+for(f in src/*.h src/*/*.h){
+ grep -s '^#pragma[ ]+once' $f && {
+ pragma_once $f >$f.p
+ mv $f.p $f
+ }
+}
+
+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,170 @@
+#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 mpid = -1;
+static char *epfile, *eptab[MAX_MIDI_DEVICES];
+static int disable[MAX_MIDI_DEVICES];
+static int neps;
+
+static int
+scaneps(void)
+{
+ int fd, i, n, m;
+ char *s, **t, **e, buf[512], *fl[32];
+ Dir *d;
+
+ e = eptab + nelem(eptab);
+ for(t=eptab; t<e; t++){
+ free(*t);
+ *t = nil;
+ }
+ neps = 0;
+ t = eptab;
+ /* special case for plugging in any non endpoint file */
+ if((s = getenv("midikbd")) != nil){
+ *t++ = s;
+ neps++;
+ }
+ if((fd = open("/dev/usb", OREAD)) < 0){
+ fprint(2, "scaneps: %r\n");
+ return neps;
+ }
+ n = dirreadall(fd, &d);
+ close(fd);
+ if(n < 0){
+ fprint(2, "scaneps: %r\n");
+ return neps;
+ }
+ for(i=0; i<n; i++){
+ snprint(buf, sizeof buf, "/dev/usb/%s/ctl", d[i].name);
+ if(epfile != nil && (s = strrchr(epfile, '/')) != nil){
+ if(strncmp(buf, epfile, s - epfile) == 0)
+ goto gotit;
+ }
+ if((fd = open(buf, OREAD)) < 0)
+ continue;
+ if((m = pread(fd, buf, sizeof buf, 0)) <= 0)
+ continue;
+ close(fd);
+ buf[m-1] = 0;
+ if(getfields(buf, fl, nelem(fl), 0, " ") < 26)
+ continue;
+ if(strcmp(fl[0], "enabled") != 0
+ || strcmp(fl[2], "r") != 0 && strcmp(fl[2], "rw") != 0
+ || strcmp(fl[25], "idle") != 0)
+ continue;
+ gotit:
+ if((*t++ = smprint("/dev/usb/%s/data", d[i].name)) == nil)
+ sysfatal("smprint: %r\n");
+ neps++;
+ if(t >= e)
+ break;
+ }
+ free(d);
+ return neps;
+}
+
+unsigned int
+rtmidi_get_port_count(RtMidiPtr)
+{
+ notrt.ok = true;
+ return scaneps();
+}
+
+char *
+rtmidi_get_port_name(RtMidiPtr, unsigned int i)
+{
+ char *s;
+
+ if(i >= neps)
+ return NULL;
+ if((s = strdup(eptab[i])) == nil)
+ sysfatal("strdup: %r");
+ return s;
+}
+
+void
+rtmidi_in_cancel_callback(RtMidiInPtr)
+{
+}
+
+void rtmidi_close_port(RtMidiPtr)
+{
+ threadkill(mpid);
+ mpid = -1;
+ callback = nil;
+ notrt.ok = false;
+ epfile = nil;
+}
+
+void rtmidi_in_free(RtMidiInPtr)
+{
+}
+
+RtMidiInPtr
+rtmidi_in_create_default(void)
+{
+ notrt.ok = true;
+ return ¬rt;
+}
+
+void
+midiproc(void *)
+{
+ int fd, n, k;
+ uchar buf[1024];
+
+ if((fd = open(epfile, OREAD)) < 0){
+ fprint(2, "midiproc: could not open stream: %r; exiting");
+ goto end;
+ }
+ while((n = read(fd, 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");
+end:
+ epfile = nil;
+ notrt.ok = false;
+ mpid = -1;
+}
+
+void
+rtmidi_open_port(RtMidiPtr, unsigned int i, char *)
+{
+ assert(mpid < 0);
+ if(i >= neps)
+ return;
+ notrt.ok = true;
+ epfile = eptab[i];
+ if((mpid = proccreate(midiproc, nil, mainstacksize)) < 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,136 @@
+</$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_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_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_center_mix.h\
+ src/mixer/ft2_mix.h\
+ src/mixer/ft2_mix_macros.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_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_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_center_mix.$O\
+ src/mixer/ft2_mix.$O\
+ src/mixer/ft2_silence_mix.$O\
+ src/mixer/ft2_windowed_sinc.$O\
+ src/modloaders/ft2_load_digi.$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_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/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_diskop.c
+++ b/src/ft2_diskop.c
@@ -1565,14 +1565,15 @@
{
DirRec *dirEntry = &FReq_Buffer[rad];
- char *name = unicharToCp437(dirEntry->nameU, true);
- if (name == NULL)
- return NULL;
+ //char *name = unicharToCp437(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;
}
@@ -1579,7 +1580,7 @@
char *p = (char *)malloc(nameLen+1+1);
if (p == NULL)
{
- free(name);
+ //free(name);
return NULL;
}
@@ -1594,7 +1595,7 @@
strcpy(&p[1], name);
- free(name);
+ //free(name);
return p;
}
else
@@ -1606,7 +1607,7 @@
{
// sort by filename
strcpy(p, name);
- free(name);
+ //free(name);
return p;
}
else
@@ -1616,7 +1617,7 @@
if (extLen <= 1)
{
strcpy(p, name);
- free(name);
+ //free(name);
return p;
}
@@ -1625,12 +1626,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;
@@ -1637,6 +1653,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_keyboard.c
+++ b/src/ft2_keyboard.c
@@ -346,6 +346,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_IO_DEVICES)
+ 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_IO_DEVICES)
+ showConfigScreen();
+ break;
+
default: break;
}
--- a/src/ft2_main.c
+++ b/src/ft2_main.c
@@ -93,12 +93,12 @@
}
#endif
-#ifdef _WIN32
-
// 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_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1");
#endif
+
+#ifdef _WIN32
#ifndef _MSC_VER
SetProcessDPIAware();
--- a/src/ft2_midi.c
+++ b/src/ft2_midi.c
@@ -194,8 +194,11 @@
if (midiDev == NULL)
return false;
- if (getNumMidiInDevices() == 0)
+ const uint32_t numDevices = getNumMidiInDevices();
+ if (numDevices == 0 || numDevices != midi.numInputDevices){
+ midi.rescanDevicesFlag = true;
return false;
+ }
rtmidi_open_port(midiDev, deviceID, "FT2 Clone MIDI Port");
if (!midiDev->ok)
@@ -285,7 +288,10 @@
uint32_t i;
if (midi.inputDeviceName != NULL)
+ {
free(midi.inputDeviceName);
+ midi.inputDeviceName = NULL;
+ }
const uint32_t numDevices = getNumMidiInDevices();
if (numDevices == 0)
@@ -477,7 +483,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_scrollbars.c
+++ b/src/ft2_scrollbars.c
@@ -224,7 +224,7 @@
{
dTmp = (scrollBar->w / (double)scrollBar->end) * scrollBar->page;
tmp32 = (int32_t)(dTmp + 0.5);
- realThumbLength = (int16_t)CLAMP(tmp32, 1, scrollBar->w);
+ realThumbLength = (int16_t)CLAMP(tmp32, 1, (int)scrollBar->w);
}
else
{
@@ -251,7 +251,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;
}
@@ -267,7 +267,7 @@
{
dTmp = (scrollBar->h / (double)scrollBar->end) * scrollBar->page;
tmp32 = (int32_t)(dTmp + 0.5);
- realThumbLength = (int16_t)CLAMP(tmp32, 1, scrollBar->h);
+ realThumbLength = (int16_t)CLAMP(tmp32, 1, (int)scrollBar->h);
}
else
{
@@ -293,7 +293,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;
}
@@ -523,7 +523,7 @@
}
assert(scrollBar->w > 0);
- scrollPos = CLAMP(scrollPos, 0, scrollBar->w);
+ scrollPos = CLAMP((int)scrollPos, 0, (int)scrollBar->w);
length = scrollBar->w + (scrollBar->realThumbLength - scrollBar->thumbW);
if (length < 1)
@@ -549,7 +549,7 @@
scrollPos = mouse.lastScrollY - scrollBar->y - mouse.saveMouseY;
assert(scrollBar->h > 0);
- scrollPos = CLAMP(scrollPos, 0, scrollBar->h);
+ scrollPos = CLAMP((int)scrollPos, 0, (int)scrollBar->h);
length = scrollBar->h + (scrollBar->realThumbLength - scrollBar->thumbH);
if (length < 1)
@@ -617,7 +617,7 @@
}
assert(scrollBar->w > 0);
- scrollX = CLAMP(scrollX, 0, scrollBar->w);
+ scrollX = CLAMP((int)scrollX, 0, (int)scrollBar->w);
length = scrollBar->w + (scrollBar->realThumbLength - scrollBar->thumbW);
if (length < 1)
@@ -641,7 +641,7 @@
scrollY = mouse.lastScrollY - mouse.saveMouseY - scrollBar->y;
assert(scrollBar->h > 0);
- scrollY = CLAMP(scrollY, 0, scrollBar->h);
+ scrollY = CLAMP((int)scrollY, 0, (int)scrollBar->h);
length = scrollBar->h + (scrollBar->realThumbLength - scrollBar->thumbH);
if (length < 1)