Merge branch 'master' of https://github.com/tildearrow/furnace into k053260

This commit is contained in:
cam900 2023-07-09 13:11:53 +09:00
commit 2a4e7267aa
21 changed files with 126 additions and 42 deletions

View File

@ -9,7 +9,9 @@ the biggest multi-system chiptune tracker ever made!
---
## downloads
check out the [Releases](https://github.com/tildearrow/furnace/releases) page. available for Windows, macOS and Linux (AppImage).
check out the [Releases](https://github.com/tildearrow/furnace/releases) page. available for Windows, macOS and Linux.
for other operating systems, you may [build the source](#developer-info).
[see here](https://nightly.link/tildearrow/furnace/workflows/build/master) for the latest unstable build.
@ -79,6 +81,7 @@ check out the [Releases](https://github.com/tildearrow/furnace/releases) page. a
- modern/fantasy:
- Commander X16 VERA
- tildearrow Sound Unit
- Generic PCM DAC
- mix and match sound chips!
- over 200 ready to use presets from computers, game consoles and arcade boards...
- ...or create your own - up to 32 of them or a total of 128 channels!
@ -90,6 +93,7 @@ check out the [Releases](https://github.com/tildearrow/furnace/releases) page. a
- clean-room design (guesswork and ABX tests only, no decompilation involved)
- some bug/quirk implementation for increased playback accuracy through compatibility flags
- VGM export
- ZSM export for Commander X16
- modular layout that you may adapt to your needs
- audio file export - entire song, per chip or per channel
- quality emulation cores (Nuked, MAME, SameBoy, Mednafen PCE, NSFplay, puNES, reSID, Stella, SAASound, vgsound_emu and ymfm)
@ -120,11 +124,11 @@ check out the [Releases](https://github.com/tildearrow/furnace/releases) page. a
# quick references
- **discussion**: see the [Discussions](https://github.com/tildearrow/furnace/discussions) section, the [official Revolt](https://rvlt.gg/GRPS6tmc) or the [official Discord server](https://discord.gg/EfrwT2wq7z).
- **help**: check out the [documentation](doc/README.md). it's incomplete though.
- **help**: check out the [documentation](doc/README.md). it's about 80% complete.
## packages
[![Packaging status](https://repology.org/badge/tiny-repos/furnace.svg)](https://repology.org/project/furnace/versions)
[![Packaging status](https://repology.org/badge/vertical-allrepos/furnace.svg)](https://repology.org/project/furnace/versions)
some people have provided packages for Unix/Unix-like distributions. here's a list.
@ -156,6 +160,7 @@ otherwise, you may also need the following:
- libx11
- libasound
- libGL
- any other libraries which may be used by SDL
some Linux distributions (e.g. Ubuntu or openSUSE) will require you to install the `-dev` versions of these.
@ -255,6 +260,17 @@ Available options:
| `WITH_INSTRUMENTS` | `ON` | Install demo instruments on `make install` |
| `WITH_WAVETABLES` | `ON` | Install wavetables on `make install` |
## CMake Error
if it says something about a missing subdirectory in `extern`, then either:
1. you didn't set up submodules, or
2. you downloaded the source as a .zip or .tar.gz. don't do this.
if 1, you may run `git submodule update --init --recursive`. this will initialize submodules.
if 2, clone this repo.
## console usage
(note: if on Windows, type `furnace.exe` instead, or `Debug\furnace.exe` on MSVC)
@ -289,7 +305,7 @@ this is due to Apple's application signing policy. a workaround is to right clic
> it says "Furnace" is damaged and can't be opened!
**as of Monterey, this workaround no longer works (especially on ARM).** yeah, Apple has decided to be strict on the matter.
if you happen to be on that version, use this workaround instead (on a Terminal):
if you happen to be on that version (or later), use this workaround instead (on a Terminal):
```
xattr -d com.apple.quarantine /path/to/Furnace.app
@ -301,7 +317,7 @@ you may need to log out and/or reboot after doing this.
> where's the manual?
see [doc/](doc/README.md). it's kind of incomplete though.
it is in [doc/](doc/README.md).
> is there a tutorial?

View File

@ -1,4 +1,4 @@
# to-do for 0.6pre6
# to-do for 0.6pre7
- tutorial?
- ease-of-use improvements... ideas:

View File

@ -15,8 +15,8 @@ android {
}
minSdkVersion 21
targetSdkVersion 26
versionCode 158
versionName "0.6pre5"
versionCode 161
versionName "0.6pre6"
externalNativeBuild {
cmake {
arguments "-DANDROID_APP_PLATFORM=android-21", "-DANDROID_STL=c++_static", "-DWARNINGS_ARE_ERRORS=ON"

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.tildearrow.furnace"
android:versionCode="158"
android:versionName="0.6pre5"
android:versionCode="161"
android:versionName="0.6pre6"
android:installLocation="auto">
<!-- OpenGL ES 2.0 -->

View File

@ -524,7 +524,15 @@ _wreaddir_r(
entry->d_off = 0;
entry->d_reclen = sizeof (struct _wdirent);
#ifdef _WIN64
entry->dwin_size = ((size_t)datap->nFileSizeHigh<<32) | datap->nFileSizeLow;
#else
if (datap->nFileSizeHigh) {
entry->dwin_size = 0xffffffff;
} else {
entry->dwin_size = datap->nFileSizeLow;
}
#endif
entry->dwin_mtime = datap->ftLastWriteTime;
/* Set result address */
@ -817,7 +825,15 @@ readdir_r(
entry->d_off = 0;
entry->d_reclen = sizeof (struct dirent);
#ifdef _WIN64
entry->dwin_size = ((size_t)datap->nFileSizeHigh<<32) | datap->nFileSizeLow;
#else
if (datap->nFileSizeHigh) {
entry->dwin_size = 0xffffffff;
} else {
entry->dwin_size = datap->nFileSizeLow;
}
#endif
entry->dwin_mtime = datap->ftLastWriteTime;
} else {

View File

@ -361,9 +361,9 @@ static void ImGui_ImplDX11_CreateFontsTexture()
D3D11_SAMPLER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
desc.MipLODBias = 0.f;
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
desc.MinLOD = 0.f;

View File

@ -32,6 +32,8 @@ these fields are 0 in format versions prior to 100 (0.6pre1).
the format versions are:
- 161: Furnace 0.6pre6
- 160: Furnace dev160
- 159: Furnace dev159
- 158: Furnace 0.6pre5
- 157: Furnace dev157

View File

@ -15,17 +15,17 @@
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>0.6pre5</string>
<string>0.6pre6</string>
<key>CFBundleName</key>
<string>Furnace</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.6pre5</string>
<string>0.6pre6</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.6pre5</string>
<string>0.6pre6</string>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>NSHighResolutionCapable</key>

View File

@ -18,6 +18,9 @@
<p>
it also offers DefleMask compatibility, allowing you to import your songs and even export them back for interoperability.
</p>
<p>
<b>rationale for intense profanity:</b> the tracker itself is clean, but a few demo songs and instruments contain a small amount of strong language.
</p>
</description>
<content_rating type="oars-1.0">

View File

@ -15,7 +15,7 @@ fi
cd win32build
# TODO: potential Arch-ism?
i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type -Werror" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=ON .. || exit 1
i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type -Werror" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=ON -DWITH_RENDER_DX11=OFF .. || exit 1
make -j8 || exit 1
cd ..

View File

@ -54,8 +54,8 @@
#define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock();
#define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false;
#define DIV_VERSION "dev160"
#define DIV_ENGINE_VERSION 160
#define DIV_VERSION "0.6pre6"
#define DIV_ENGINE_VERSION 161
// for imports
#define DIV_VERSION_MOD 0xff01
#define DIV_VERSION_FC 0xff02

View File

@ -130,14 +130,15 @@ class DivPlatformOPN: public DivPlatformFMBase {
unsigned char freqH, freqL;
int portaPauseFreq;
signed char konCycles;
bool mask;
bool mask, hardReset;
OPNOpChannel():
SharedChannel<int>(0),
freqH(0),
freqL(0),
portaPauseFreq(0),
konCycles(0),
mask(true) {}
mask(true),
hardReset(false) {}
};
struct OPNOpChannelStereo: public OPNOpChannel {

View File

@ -397,6 +397,14 @@ int DivPlatformGB::dispatch(DivCommand c) {
chan[c.chan].vol=chan[c.chan].envVol;
chan[c.chan].outVol=chan[c.chan].envVol;
}
} else if (chan[c.chan].softEnv && c.chan!=2) {
if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) {
chan[c.chan].outVol=chan[c.chan].vol;
chan[c.chan].envVol=chan[c.chan].outVol;
}
chan[c.chan].envLen=0;
chan[c.chan].envDir=1;
chan[c.chan].soundLen=64;
}
if (c.chan==2 && chan[c.chan].softEnv) {
chan[c.chan].soundLen=64;
@ -674,8 +682,6 @@ void DivPlatformGB::setFlags(const DivConfig& flags) {
CHECK_CUSTOM_CLOCK;
rate=chipClock/16;
for (int i=0; i<4; i++) {
isMuted[i]=false;
oscBuf[i]=new DivDispatchOscBuffer;
oscBuf[i]->rate=rate;
}
}
@ -686,6 +692,12 @@ int DivPlatformGB::init(DivEngine* p, int channels, int sugRate, const DivConfig
skipRegisterWrites=false;
model=GB_MODEL_DMG_B;
gb=new GB_gameboy_t;
for (int i=0; i<4; i++) {
isMuted[i]=false;
oscBuf[i]=new DivDispatchOscBuffer;
}
setFlags(flags);
reset();
return 4;

View File

@ -123,7 +123,9 @@ void DivPlatformGenesis::processDAC(int iRate) {
chan[5].dacReady=false;
}
} else {
urgentWrite(0x2a,0x80);
if (chan[5].dacReady && writes.size()<16) {
urgentWrite(0x2a,0x80);
}
}
chan[5].dacPos++;
if (!chan[5].dacDirection && (s->isLoopable() && chan[5].dacPos>=(unsigned int)s->loopEnd)) {

View File

@ -396,6 +396,9 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) {
}
break;
}
case DIV_CMD_FM_HARD_RESET:
opChan[ch].hardReset=c.value;
break;
case DIV_CMD_GET_VOLMAX:
return 127;
break;

View File

@ -195,9 +195,6 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
chan[c.chan].pcm.sample=-1;
rWrite(0x86+(c.chan<<3),3);
chan[c.chan].macroInit(NULL);
if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) {
chan[c.chan].outVol=chan[c.chan].vol;
}
break;
}
if (c.value!=DIV_NOTE_NULL) {
@ -207,6 +204,16 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
}
chan[c.chan].furnacePCM=true;
chan[c.chan].macroInit(ins);
if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) {
chan[c.chan].outVol=chan[c.chan].vol;
if (parent->song.newSegaPCM) {
chan[c.chan].chVolL=(chan[c.chan].outVol*chan[c.chan].chPanL)/127;
chan[c.chan].chVolR=(chan[c.chan].outVol*chan[c.chan].chPanR)/127;
rWrite(2+(c.chan<<3),chan[c.chan].chVolL);
rWrite(3+(c.chan<<3),chan[c.chan].chVolR);
}
}
chan[c.chan].active=true;
chan[c.chan].keyOn=true;
} else {

View File

@ -548,19 +548,25 @@ void DivPlatformSwan::poke(std::vector<DivRegWrite>& wlist) {
for (DivRegWrite& i: wlist) rWrite(i.addr,i.val);
}
int DivPlatformSwan::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {
parent=p;
dumpWrites=false;
skipRegisterWrites=false;
void DivPlatformSwan::setFlags(const DivConfig& flags) {
chipClock=3072000;
CHECK_CUSTOM_CLOCK;
rate=chipClock/16; // = 192000kHz, should be enough
for (int i=0; i<4; i++) {
isMuted[i]=false;
oscBuf[i]=new DivDispatchOscBuffer;
oscBuf[i]->rate=rate;
}
}
int DivPlatformSwan::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {
parent=p;
dumpWrites=false;
skipRegisterWrites=false;
for (int i=0; i<4; i++) {
isMuted[i]=false;
oscBuf[i]=new DivDispatchOscBuffer;
}
ws=new WSwan();
setFlags(flags);
reset();
return 4;
}

View File

@ -68,6 +68,7 @@ class DivPlatformSwan: public DivDispatch {
void forceIns();
void tick(bool sysTick=true);
void muteChannel(int ch, bool mute);
void setFlags(const DivConfig& flags);
void notifyWaveChange(int wave);
void notifyInsDeletion(void* ins);
int getOutputCount();

View File

@ -82,6 +82,7 @@ const char* aboutLine[]={
"Dippy",
"djtuBIG-MaliceX",
"dumbut",
"Eknous-P",
"ElectricKeet",
"EpicTyphlosion",
"FΛDE",

View File

@ -506,12 +506,26 @@ void FurnaceGUI::drawChanOsc() {
text+=fmt::sprintf("%d",e->dispatchOfChan[ch]);
break;
}
case 'v':
case 'v': {
DivChannelState* chanState=e->getChanState(ch);
if (chanState==NULL) break;
text+=fmt::sprintf("%d",chanState->volume>>8);
break;
case 'V':
}
case 'V': {
DivChannelState* chanState=e->getChanState(ch);
if (chanState==NULL) break;
int volMax=chanState->volMax>>8;
if (volMax<1) volMax=1;
text+=fmt::sprintf("%d%%",(chanState->volume>>8)/volMax);
break;
case 'b':
}
case 'b': {
DivChannelState* chanState=e->getChanState(ch);
if (chanState==NULL) break;
text+=fmt::sprintf("%.2X",chanState->volume>>8);
break;
}
case '%':
text+='%';
break;

View File

@ -6261,9 +6261,9 @@ bool FurnaceGUI::init() {
logV("window size: %dx%d",scrW,scrH);
if (!initRender()) {
if (settings.renderBackend!="SDL" && !settings.renderBackend.empty()) {
settings.renderBackend="";
e->setConf("renderBackend","");
if (settings.renderBackend!="SDL") {
settings.renderBackend="SDL";
e->setConf("renderBackend","SDL");
e->saveConf();
lastError=fmt::sprintf("\r\nthe render backend has been set to a safe value. please restart Furnace.");
} else {
@ -6362,9 +6362,9 @@ bool FurnaceGUI::init() {
if (!rend->init(sdlWin)) {
if (settings.renderBackend!="SDL") {
settings.renderBackend="SDL";
//e->setConf("renderBackend","");
//e->saveConf();
//lastError=fmt::sprintf("\r\nthe render backend has been set to a safe value. please restart Furnace.");
e->setConf("renderBackend","");
e->saveConf();
lastError=fmt::sprintf("\r\nthe render backend has been set to a safe value. please restart Furnace.");
} else {
lastError=fmt::sprintf("could not init renderer! %s",SDL_GetError());
if (!settings.renderDriver.empty()) {