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

This commit is contained in:
Natt Akuma 2024-02-03 16:14:29 +07:00
commit da9b3b8925
125 changed files with 999 additions and 915 deletions

View file

@ -16,7 +16,7 @@ set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_PROJECT_VERSION_MAJOR 0) set(CMAKE_PROJECT_VERSION_MAJOR 0)
set(CMAKE_PROJECT_VERSION_MINOR 6) set(CMAKE_PROJECT_VERSION_MINOR 6)
set(CMAKE_PROJECT_VERSION_PATCH 0) set(CMAKE_PROJECT_VERSION_PATCH 1)
set(BUILD_GUI_DEFAULT ON) set(BUILD_GUI_DEFAULT ON)
set(USE_SDL2_DEFAULT ON) set(USE_SDL2_DEFAULT ON)

View file

@ -31,6 +31,7 @@ for other operating systems, you may [build the source](#developer-info).
- YM3812 (OPL2) - YM3812 (OPL2)
- YMF262 (OPL3) with full 4-op support! - YMF262 (OPL3) with full 4-op support!
- Y8950 (OPL with ADPCM) - Y8950 (OPL with ADPCM)
- ESS ESFM (like OPL3 but with more features)
- square wave chips: - square wave chips:
- AY-3-8910/YM2149(F) used in several computers and game consoles - AY-3-8910/YM2149(F) used in several computers and game consoles
- Commodore VIC used in the VIC-20 - Commodore VIC used in the VIC-20
@ -86,6 +87,7 @@ for other operating systems, you may [build the source](#developer-info).
- modern/fantasy: - modern/fantasy:
- Commander X16 VERA - Commander X16 VERA
- tildearrow Sound Unit - tildearrow Sound Unit
- PowerNoise
- Generic PCM DAC - Generic PCM DAC
- mix and match sound chips! - mix and match sound chips!
- over 200 ready to use presets from computers, game consoles and arcade boards... - over 200 ready to use presets from computers, game consoles and arcade boards...

View file

@ -1,13 +1,5 @@
# to-do # to-do
- finish color import improvements (settings refactor)
- new undo stuff
- fix some bugs
- finish auto-clone - finish auto-clone
once you have done all of this (maybe not the first one), release 0.6.1
# and then
- new oscilloscope renderer - custom code that uses texture and fixes two issues: too many vertices, and broken anti-aliasing - new oscilloscope renderer - custom code that uses texture and fixes two issues: too many vertices, and broken anti-aliasing
- new pattern renderer - performance improvements - new pattern renderer - performance improvements

View file

@ -15,8 +15,8 @@ android {
} }
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 26 targetSdkVersion 26
versionCode 181 versionCode 192
versionName "0.6" versionName "0.6.1"
externalNativeBuild { externalNativeBuild {
cmake { cmake {
arguments "-DANDROID_APP_PLATFORM=android-21", "-DANDROID_STL=c++_static", "-DWARNINGS_ARE_ERRORS=ON" 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"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.tildearrow.furnace" package="org.tildearrow.furnace"
android:versionCode="181" android:versionCode="192"
android:versionName="0.6" android:versionName="0.6.1"
android:installLocation="auto"> android:installLocation="auto">
<!-- OpenGL ES 2.0 --> <!-- OpenGL ES 2.0 -->

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
demos/esfm/AAAA.fur Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
demos/esfm/Deadline.fur Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
demos/esfm/Ken_Stage.fur Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
demos/esfm/Perilous059.fur Normal file

Binary file not shown.

BIN
demos/esfm/Poets_I.fur Normal file

Binary file not shown.

BIN
demos/esfm/Redial.fur Normal file

Binary file not shown.

Binary file not shown.

BIN
demos/esfm/Second_Start.fur Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
demos/esfm/esfm_ins.fur Normal file

Binary file not shown.

BIN
demos/esfm/experiment.fur Normal file

Binary file not shown.

BIN
demos/esfm/flashback.fur Normal file

Binary file not shown.

BIN
demos/esfm/frosty_dusk.fur Normal file

Binary file not shown.

Binary file not shown.

BIN
demos/esfm/her_wishes.fur Normal file

Binary file not shown.

BIN
demos/esfm/ledstorm.fur Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
demos/esfm/sticker1.fur Normal file

Binary file not shown.

BIN
demos/esfm/synthy.fur Normal file

Binary file not shown.

BIN
demos/esfm/wack.fur Normal file

Binary file not shown.

BIN
demos/esfm/x_evil_soul.fur Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
demos/misc/T_Six_T6W28.fur Normal file

Binary file not shown.

BIN
demos/msx/Morning_Alarm.fur Normal file

Binary file not shown.

Binary file not shown.

BIN
demos/nes/Fur_Nes.fur Normal file

Binary file not shown.

Binary file not shown.

BIN
demos/specs2/spa.fur Normal file

Binary file not shown.

View file

@ -9,10 +9,8 @@ alternatively, window > instrument editor displays it.
![top of instrument editor](instrument-editor-top.png) ![top of instrument editor](instrument-editor-top.png)
**TODO: add descriptions to buttons in the image. it really needs them.** - **Select**: displays a list of instruments in the song.
- **Load**: open an instrument file.
- **Instrument Selector**: displays a list of instruments in the song.
- **Open**: open an instrument file.
- **Save**: save current instrument to a file. - **Save**: save current instrument to a file.
- right-click to see additional options, such as saving in DefleMask preset format (.dmp). - right-click to see additional options, such as saving in DefleMask preset format (.dmp).
- **Name**: changes the instrument name. - **Name**: changes the instrument name.
@ -76,6 +74,7 @@ the following instrument types are available:
- [TED](ted.md) - for use with Commodore Plus/4 and Commodore 16's TED chip. - [TED](ted.md) - for use with Commodore Plus/4 and Commodore 16's TED chip.
- [C140](c140.md) - for use with C140 sample chip. - [C140](c140.md) - for use with C140 sample chip.
- [C219](c219.md) - for use with C219 sample chip. - [C219](c219.md) - for use with C219 sample chip.
- [PowerNoise](powernoise.md) - for use with PowerNoise chip.
## macros ## macros
@ -93,9 +92,6 @@ each macro has the following parameters:
- **Step Length (ticks)**: determines the number of ticks between macro steps. default is 1. - **Step Length (ticks)**: determines the number of ticks between macro steps. default is 1.
- **Delay**: delays the macro until this many ticks have elapsed. default is 0. - **Delay**: delays the macro until this many ticks have elapsed. default is 0.
- the button is highlighted if either of these parameters is set to non-default values. - the button is highlighted if either of these parameters is set to non-default values.
- release mode: determines how macro release (`===` or `REL` in the pattern) is handled:
- **Active**: jumps to release position on release.
- **Passive**: does not jump to release position. this will result in delay if release position has not been reached yet.
## macro types ## macro types
@ -115,8 +111,6 @@ this is the most basic macro type. when the instrument is played, every value in
![bitmask sequence macro editor](macro-seq-bitmask.png) ![bitmask sequence macro editor](macro-seq-bitmask.png)
**TODO: once again, text in the image. this sucks.**
the Length field allows you to set the number of steps in the sequence. the Length field allows you to set the number of steps in the sequence.
the sequence view allows you to edit the macro. the sequence view allows you to edit the macro.
@ -171,6 +165,10 @@ the sequence can be edited in the text input field at the very bottom. the follo
in bitmask-style macros, the values are added up in binary and converted to decimal. in bitmask-style macros, the values are added up in binary and converted to decimal.
the release mode parameter determines how macro release (`===` or `REL` in the pattern) is handled:
- **Active**: jumps to release position on release.
- **Passive**: does not jump to release position. this will result in delay if release position has not been reached yet.
### ADSR ### ADSR
![ADSR macro editor](macro-ADSR.png) ![ADSR macro editor](macro-ADSR.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View file

@ -24,6 +24,20 @@ note that using samples on Lynx is CPU expensive!
Atari Lynx generates sound using a 12-bit linear feedback shift register with configurable tap. nine separate bits can be enabled to be the source of feedback: 0, 1, 2, 3, 4, 5, 7, 10 and 11. to generate _any_ sound at least one bit _must_ be enabled. Atari Lynx generates sound using a 12-bit linear feedback shift register with configurable tap. nine separate bits can be enabled to be the source of feedback: 0, 1, 2, 3, 4, 5, 7, 10 and 11. to generate _any_ sound at least one bit _must_ be enabled.
### LFSR-based synthesis
a linear-feedback shift register is one method used for random number generation.
it works by shifting a sequence of binary numbers (bits), taking the last bit into the output. then some of the bits are combined with others, doing a XOR (exclusive or) operation and then being pushed back.
think of it as a conveyor carrying glass bottles. each bottle may be empty or carrying water.
the bottle at the end is taken. if there's water, then the output is 1. if it's empty, the output is 0.
depending on the LFSR configuration, many bottles at specific positions ("taps") are looked at. these are combined from left to right, two by two:
- if two bottles are identical, an empty bottle is pushed.
- if one bottle has water but the other is empty, a water bottle is pushed.
the process is repeated indefinitely.
unlike PowerNoise, Lynx's taps are in fixed positions, but it has many of them.
### square wave ### square wave
the LFSR is shifted at the rate define by sound pitch and generates square wave by setting channel output value to +volume or -volume, depending on the bit shifted in. the LFSR is shifted at the rate define by sound pitch and generates square wave by setting channel output value to +volume or -volume, depending on the bit shifted in.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View file

@ -15,7 +15,7 @@ depending on the LFSR configuration:
- a bottle is pushed into the conveyor. it is either empty or filled with water depending on the bottle at a specific position in the conveyor (this is called a "tap"), or - a bottle is pushed into the conveyor. it is either empty or filled with water depending on the bottle at a specific position in the conveyor (this is called a "tap"), or
- two bottles at specific positions ("taps") are looked at and combined as follows: - two bottles at specific positions ("taps") are looked at and combined as follows:
- if the bottles are identical, an empty bottle is pushed. - if the bottles are identical, an empty bottle is pushed.
- if one bottle has water but the other is empty, a watee bottle is pushed. - if one bottle has water but the other is empty, a water bottle is pushed.
the process is repeated indefinitely. the process is repeated indefinitely.
PowerNoise uses either one or two taps for the LFSR, configurable via the Control macro. PowerNoise uses either one or two taps for the LFSR, configurable via the Control macro.

View file

@ -90,6 +90,7 @@ this is the full list of chips that Furnace supports.
- [PET](pet.md) - [PET](pet.md)
- [Pokémon Mini](pokemini.md) - [Pokémon Mini](pokemini.md)
- [POKEY](pokey.md) - [POKEY](pokey.md)
- [PowerNoise](powernoise.md)
- [PV-1000](pv1000.md) - [PV-1000](pv1000.md)
- [QSound](qsound.md) - [QSound](qsound.md)
- [RF5C68/RF5C164](ricoh.md) - [RF5C68/RF5C164](ricoh.md)

View file

@ -1442,6 +1442,8 @@ void FMOPL3_Clock(fmopl3_t *chip)
int sign; int sign;
chip->op_value_debug = chip->op_value;
int accm_a = chip->fsm_out[6] ? 0 : chip->accm_a[1]; int accm_a = chip->fsm_out[6] ? 0 : chip->accm_a[1];
accm_a += (chip->pan_l[1][1] & 1) != 0 ? value : 0; accm_a += (chip->pan_l[1][1] & 1) != 0 ? value : 0;
chip->accm_a[0] = accm_a; chip->accm_a[0] = accm_a;

View file

@ -297,6 +297,7 @@ typedef struct
int op_mod[2]; int op_mod[2];
int op_value; int op_value;
int op_value_debug;
int accm_a[2]; int accm_a[2];
int accm_b[2]; int accm_b[2];

View file

@ -4253,7 +4253,7 @@ public:
} }
#ifdef _WIN32 #ifdef _WIN32
MessageBox(NULL,"Error","Furnace has crashed! please report this to the issue tracker immediately:\r\nhttps://github.com/tildearrow/furnace/issues/new\r\n\r\na file called furnace_crash.txt will be created in your user directory.\r\nthis will be important for locating the origin of the crash.",MB_OK|MB_ICONERROR); MessageBox(NULL,"Error","Furnace has crashed! please report this to the issue tracker immediately:\r\nhttps://github.com/tildearrow/furnace/issues/new\r\n\r\na file called furnace_crash.txt will be created in your user directory.\r\nthis will be important for locating the origin of the crash.\r\n\r\nif Furnace keeps crashing and you believe it is caused by a configuration problem, you may start Furnace with the -safemode parameter.",MB_OK|MB_ICONERROR);
std::string crashLocation; std::string crashLocation;
char* userProfile=getenv("USERPROFILE"); char* userProfile=getenv("USERPROFILE");
if (userProfile==NULL) { if (userProfile==NULL) {
@ -4492,7 +4492,7 @@ private:
printer.print(st, std::cerr); printer.print(st, std::cerr);
#ifdef _WIN32 #ifdef _WIN32
MessageBox(NULL,"Furnace has crashed! please report this to the issue tracker immediately:\r\nhttps://github.com/tildearrow/furnace/issues/new\r\n\r\na file called furnace_crash.txt will be created in your user directory.\r\nthis will be important for locating the origin of the crash.","Error",MB_OK|MB_ICONERROR); MessageBox(NULL,"Furnace has crashed! please report this to the issue tracker immediately:\r\nhttps://github.com/tildearrow/furnace/issues/new\r\n\r\na file called furnace_crash.txt will be created in your user directory.\r\nthis will be important for locating the origin of the crash.\r\n\r\nif Furnace keeps crashing and you believe it is caused by a configuration problem, you may start Furnace with the -safemode parameter.","Error",MB_OK|MB_ICONERROR);
std::string crashLocation; std::string crashLocation;
char* userProfile=getenv("USERPROFILE"); char* userProfile=getenv("USERPROFILE");
if (userProfile==NULL) { if (userProfile==NULL) {

View file

@ -6,7 +6,7 @@ when copying pattern data from Furnace, it's stored in the clipboard as plain te
org.tildearrow.furnace - Pattern Data (144) org.tildearrow.furnace - Pattern Data (144)
``` ```
this top line of text is always the same except for the number in parentheses, which is the internal build number. for example, 0.6 is `181`. this top line of text is always the same except for the number in parentheses, which is the internal build number. for example, 0.6.1 is `192`.
the second line is a number between 0 and 18 (decimal) which indicates which column the clip starts from. the second line is a number between 0 and 18 (decimal) which indicates which column the clip starts from.
- `0`: note. - `0`: note.

View file

@ -32,6 +32,7 @@ these fields are 0 in format versions prior to 100 (0.6pre1).
the format versions are: the format versions are:
- 192: Furnace 0.6.1
- 181: Furnace 0.6 - 181: Furnace 0.6
- 180: Furnace 0.6pre18 - 180: Furnace 0.6pre18
- 179: Furnace 0.6pre17 - 179: Furnace 0.6pre17

View file

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

View file

@ -325,7 +325,7 @@ if __name__ == "__main__":
<h1>Furnace<br/>User Manual</h1> <h1>Furnace<br/>User Manual</h1>
</div> </div>
<div> <div>
<i>for version 0.6</i> <i>for version 0.6.1</i>
</div> </div>
</section> </section>
<section id="authors"> <section id="authors">
@ -348,7 +348,7 @@ if __name__ == "__main__":
<p>this documentation is under the <a href="https://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported</a> license.</p> <p>this documentation is under the <a href="https://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported</a> license.</p>
<p>you may reproduce, modify and/or distribute this documentation provided this copyright notice (including license and attribution) is present and any necessary disclaimers whether modifications have been made.</p> <p>you may reproduce, modify and/or distribute this documentation provided this copyright notice (including license and attribution) is present and any necessary disclaimers whether modifications have been made.</p>
<p>this documentation is provided as-is and without warranty of any kind.</p> <p>this documentation is provided as-is and without warranty of any kind.</p>
<p>this manual is written for version 0.6 of Furnace.<br/>it may not necessarily apply to previous or future versions.</p> <p>this manual is written for version 0.6.1 of Furnace.<br/>it may not necessarily apply to previous or future versions.</p>
</section> </section>
<section id="index"> <section id="index">
%s %s

View file

@ -4,6 +4,10 @@
<name>Furnace</name> <name>Furnace</name>
<summary>Open-source chiptune tracker</summary> <summary>Open-source chiptune tracker</summary>
<developer id="tildearrow.org">
<name>tildearrow and contributors</name>
</developer>
<developer_name>tildearrow and contributors</developer_name>
<url type="homepage">https://github.com/tildearrow/furnace</url> <url type="homepage">https://github.com/tildearrow/furnace</url>
<metadata_license>CC0-1.0</metadata_license> <metadata_license>CC0-1.0</metadata_license>
@ -32,7 +36,8 @@
<launchable type="desktop-id">furnace.desktop</launchable> <launchable type="desktop-id">furnace.desktop</launchable>
<screenshots> <screenshots>
<screenshot type="default"> <screenshot type="default">
<image>https://tildearrow.org/storage/images/furnace.png</image> <caption>Furnace during playback</caption>
<image>https://raw.githubusercontent.com/tildearrow/furnace/94cce861800c0473bdddb8270e462ebcdd18202a/papers/screenshot3.png</image>
</screenshot> </screenshot>
</screenshots> </screenshots>

View file

@ -21,7 +21,7 @@ OS2Version: 0
OS2_WeightWidthSlopeOnly: 0 OS2_WeightWidthSlopeOnly: 0
OS2_UseTypoMetrics: 0 OS2_UseTypoMetrics: 0
CreationTime: 1691897631 CreationTime: 1691897631
ModificationTime: 1701817435 ModificationTime: 1706927377
PfmFamily: 81 PfmFamily: 81
TTFWeight: 400 TTFWeight: 400
TTFWidth: 5 TTFWidth: 5
@ -47,13 +47,13 @@ LangName: 1033
Encoding: UnicodeBmp Encoding: UnicodeBmp
UnicodeInterp: none UnicodeInterp: none
NameList: AGL For New Fonts NameList: AGL For New Fonts
DisplaySize: -96 DisplaySize: -24
AntiAlias: 1 AntiAlias: 1
FitToEm: 0 FitToEm: 0
WinInfo: 57672 8 5 WinInfo: 57540 21 12
BeginPrivate: 0 BeginPrivate: 0
EndPrivate EndPrivate
BeginChars: 65536 96 BeginChars: 65536 98
StartChar: space StartChar: space
Encoding: 32 32 0 Encoding: 32 32 0
@ -2270,15 +2270,15 @@ SplineSet
1653.60449219 798.544921875 1681.75488281 781.904296875 1709.90625 765.263671875 c 1 1653.60449219 798.544921875 1681.75488281 781.904296875 1709.90625 765.263671875 c 1
1688.8125 716.044921875 1660.609375 678.232421875 1625.453125 651.982421875 c 0 1688.8125 716.044921875 1660.609375 678.232421875 1625.453125 651.982421875 c 0
1590.21875 625.732421875 1544.125 612.685546875 1487.171875 612.685546875 c 0xcbcd 1590.21875 625.732421875 1544.125 612.685546875 1487.171875 612.685546875 c 0xcbcd
1289.23339844 435.383789062 m 1 1289.23339844 435.383789062 m 5
1289.23339844 -25.1181640625 l 1 1289.23339844 -25.1181640625 l 5
1585.29882812 247.456054688 l 1 1585.29882812 247.456054688 l 5
1585.29882812 117.280273438 l 1 1585.29882812 117.280273438 l 5
1187.45410156 -248.998046875 l 1xd3ce 1187.45410156 -248.998046875 l 5xd3ce
1187.45410156 211.504882812 l 1 1187.45410156 211.504882812 l 5
891.388671875 -61.0693359375 l 1 891.388671875 -61.0693359375 l 5
891.388671875 69.1064453125 l 1 891.388671875 69.1064453125 l 5
1289.23339844 435.383789062 l 1 1289.23339844 435.383789062 l 5
EndSplineSet EndSplineSet
EndChar EndChar
@ -6736,54 +6736,8 @@ EndChar
StartChar: uniE159 StartChar: uniE159
Encoding: 57689 57689 95 Encoding: 57689 57689 95
Width: 1792 Width: 1792
Flags: HWO Flags: HW
LayerCount: 2 LayerCount: 2
UndoRedoHistory
Layer: 0
Undoes
UndoOperation
Index: 0
Type: 1
WasModified: 0
WasOrder2: 0
Layer: 1
Width: 1792
VWidth: 1792
LBearingChange: 0
UnicodeEnc: 0
InstructionsLength: 0
SplineSet
1632 70 m 1
1632 -50 l 1025
160 1210 m 1
160 1330 l 1025
EndSplineSet
EndUndoOperation
UndoOperation
Index: 1
Type: 1
WasModified: 0
WasOrder2: 0
Layer: 2
Width: 1792
VWidth: 1792
LBearingChange: 0
UnicodeEnc: 0
InstructionsLength: 0
SplineSet
160 1270 m 25
160 1270 560 1270 896 640 c 0
1232 10 1632 10 1632 10 c 1025
1632 70 m 5
1632 -50 l 1029
160 1210 m 5
160 1330 l 1029
EndSplineSet
EndUndoOperation
EndUndoes
Redoes
EndRedoes
EndUndoRedoHistory
Back Back
SplineSet SplineSet
160 1270 m 25 160 1270 m 25
@ -6794,314 +6748,6 @@ SplineSet
160 1210 m 1 160 1210 m 1
160 1330 l 1025 160 1330 l 1025
EndSplineSet EndSplineSet
UndoRedoHistory
Layer: 1
Undoes
UndoOperation
Index: 0
Type: 1
WasModified: 1
WasOrder2: 0
Layer: 2
Width: 1792
VWidth: 1792
LBearingChange: 0
UnicodeEnc: 0
InstructionsLength: 0
SplineSet
1632 1210.01171875 m 1
1632 1329.98828125 l 1
1619.75878906 1329.98828125 1193.45019531 1325.24316406 843.048828125 668.2421875 c 0
755.229492188 503.581054688 663.75 384.705078125 577.82421875 298.780273438 c 0
473.91796875 194.873046875 377.610351562 138.502929688 303.73046875 107.581054688 c 0
262.674804688 90.396484375 228.48828125 81.078125 203.702148438 76.0087890625 c 0
176.166992188 70.3779296875 160.23046875 70 159.536132812 69.986328125 c 1
159.698242188 69.9873046875 160 69.98828125 160 69.98828125 c 1
160 -49.98828125 l 1
172.241210938 -49.98828125 598.549804688 -45.2431640625 948.951171875 611.7578125 c 0
1036.77050781 776.418945312 1128.25 895.294921875 1214.17578125 981.219726562 c 0
1318.08203125 1085.12695312 1414.38964844 1141.49707031 1488.26953125 1172.41894531 c 0
1529.32519531 1189.60351562 1563.51171875 1198.921875 1588.29785156 1203.99121094 c 0
1615.83300781 1209.62207031 1631.76953125 1210 1632.46386719 1210.01367188 c 1
1632.30175781 1210.01269531 1632 1210.01171875 1632 1210.01171875 c 1
159.999999952 1210.01176537 m 1
159.999999952 1329.98823463 l 1
170.809951102 1329.98823463 504.536374276 1326.28810718 823.734604363 872.948478072 c 1
800.889124326 837.280193024 778.251310121 799.419416229 755.928040313 759.232259114 c 1
695.916689064 850.735795855 635.614260663 923.430234862 577.824293264 981.220202232 c 0
473.917602143 1085.12689335 377.61065751 1141.49706263 303.730893464 1172.41936621 c 0
262.674555191 1189.60345677 228.488523437 1198.92230209 203.702403502 1203.99126863 c 0
176.167181121 1209.62244935 160.230079948 1210.00005891 159.536222574 1210.01396385 c 1
159.698263781 1210.01275358 159.999999952 1210.01176537 159.999999952 1210.01176537 c 1
1632 1090.03515625 m 5
1632 1449.96484375 l 5
1558.47725996 1449.96484375 1167.58409474 1409.79522486 823.734604363 872.948478072 c 5
865.988935134 812.936984165 907.988680731 745.046220598 948.951069976 668.241740764 c 4
977.706682766 614.324966782 1006.85482384 565.317167145 1036.07195969 520.767740886 c 5
1042.35821703 532.084488601 1048.61953126 543.58571637 1054.85351562 555.274414062 c 4
1093.06152344 626.915039062 1265.13574219 948.919921875 1534.69042969 1061.74121094 c 4
1536.87304688 1062.65429688 1591.23828125 1085.29492188 1632 1090.03515625 c 5
1036.07195969 520.767740886 m 1
1096.08331094 429.264204145 1156.38573934 356.569765138 1214.17570674 298.779797768 c 0
1318.08239786 194.873106647 1414.38934249 138.502937368 1488.26910654 107.580633787 c 0
1529.32544481 90.3965432265 1563.51147656 81.0776979108 1588.2975965 76.0087313726 c 0
1615.83281888 70.3775506458 1631.76992005 69.9999410877 1632.46377743 69.986036148 c 1
1632.30173622 69.9872464204 1632.00000005 69.9882346324 1632.00000005 69.9882346324 c 1
1632.00000005 -49.9882346324 l 1
1621.1900489 -49.9882346324 1287.46362572 -46.2881071791 968.265395637 407.051521928 c 1
991.110875674 442.719806976 1013.74868988 480.580583771 1036.07195969 520.767740886 c 1
968.265395637 407.051521928 m 5
926.011064866 467.063015835 884.011319269 534.953779402 843.048930024 611.758259236 c 4
814.293317234 665.675033218 785.145176159 714.682832855 755.928040313 759.232259114 c 5
749.641782968 747.9155114 743.380468741 736.41428363 737.146484375 724.725585938 c 4
698.938476562 653.084960938 526.864257812 331.080078125 257.309570312 218.258789062 c 4
255.126953125 217.345703125 200.76171875 194.705078125 160 189.96484375 c 5
160 -169.96484375 l 5
233.522740042 -169.96484375 624.415905262 -129.795224857 968.265395637 407.051521928 c 5
EndSplineSet
EndUndoOperation
UndoOperation
Index: 1
Type: 1
WasModified: 0
WasOrder2: 0
Layer: 2
Width: 1792
VWidth: 1792
LBearingChange: 0
UnicodeEnc: 0
InstructionsLength: 0
SplineSet
1632 1090.03515625 m 5
1632 1449.96484375 l 5
1552.21679688 1449.96484375 1098.71386719 1402.66308594 737.146484375 724.725585938 c 4
698.938476562 653.084960938 526.864257812 331.080078125 257.309570312 218.258789062 c 4
255.126953125 217.345703125 200.76171875 194.705078125 160 189.96484375 c 5
160 -169.96484375 l 5
239.783203125 -169.96484375 693.286132812 -122.663085938 1054.85351562 555.274414062 c 4
1093.06152344 626.915039062 1265.13574219 948.919921875 1534.69042969 1061.74121094 c 4
1536.87304688 1062.65429688 1591.23828125 1085.29492188 1632 1090.03515625 c 5
1632 1210.01171875 m 1
1632 1329.98828125 l 1
1619.75878906 1329.98828125 1193.45019531 1325.24316406 843.048828125 668.2421875 c 0
755.229492188 503.581054688 663.75 384.705078125 577.82421875 298.780273438 c 0
473.91796875 194.873046875 377.610351562 138.502929688 303.73046875 107.581054688 c 0
262.674804688 90.396484375 228.48828125 81.078125 203.702148438 76.0087890625 c 0
176.166992188 70.3779296875 160.23046875 70 159.536132812 69.986328125 c 1
159.698242188 69.9873046875 160 69.98828125 160 69.98828125 c 1
160 -49.98828125 l 1
172.241210938 -49.98828125 598.549804688 -45.2431640625 948.951171875 611.7578125 c 0
1036.77050781 776.418945312 1128.25 895.294921875 1214.17578125 981.219726562 c 0
1318.08203125 1085.12695312 1414.38964844 1141.49707031 1488.26953125 1172.41894531 c 0
1529.32519531 1189.60351562 1563.51171875 1198.921875 1588.29785156 1203.99121094 c 0
1615.83300781 1209.62207031 1631.76953125 1210 1632.46386719 1210.01367188 c 1
1632.30175781 1210.01269531 1632 1210.01171875 1632 1210.01171875 c 1
159.999999952 1210.01176537 m 5
159.999999952 1329.98823463 l 5
172.240934135 1329.98823462 598.550052583 1325.24364837 948.951069976 668.241740764 c 4
1036.77007573 503.581104976 1128.25010681 384.70539769 1214.17570674 298.779797768 c 4
1318.08239786 194.873106647 1414.38934249 138.502937368 1488.26910654 107.580633787 c 4
1529.32544481 90.3965432265 1563.51147656 81.0776979108 1588.2975965 76.0087313726 c 4
1615.83281888 70.3775506458 1631.76992005 69.9999410877 1632.46377743 69.986036148 c 5
1632.30173622 69.9872464204 1632.00000005 69.9882346324 1632.00000005 69.9882346324 c 5
1632.00000005 -49.9882346324 l 5
1619.75906587 -49.9882346228 1193.44994742 -45.2436483754 843.048930024 611.758259236 c 4
755.229924271 776.418895024 663.749893187 895.29460231 577.824293264 981.220202232 c 4
473.917602143 1085.12689335 377.61065751 1141.49706263 303.730893464 1172.41936621 c 4
262.674555191 1189.60345677 228.488523437 1198.92230209 203.702403502 1203.99126863 c 4
176.167181121 1209.62244935 160.230079948 1210.00005891 159.536222574 1210.01396385 c 5
159.698263781 1210.01275358 159.999999952 1210.01176537 159.999999952 1210.01176537 c 5
EndSplineSet
EndUndoOperation
UndoOperation
Index: 2
Type: 1
WasModified: 1
WasOrder2: 0
Layer: 2
Width: 1792
VWidth: 1792
LBearingChange: 0
UnicodeEnc: 0
InstructionsLength: 0
SplineSet
160 1270 m 29
160 1270 560 1270 896 640 c 4
1232 10 1632 10 1632 10 c 1029
1632 1210.01171875 m 1
1632 1329.98828125 l 1
1619.75878906 1329.98828125 1193.45019531 1325.24316406 843.048828125 668.2421875 c 0
755.229492188 503.581054688 663.75 384.705078125 577.82421875 298.780273438 c 0
473.91796875 194.873046875 377.610351562 138.502929688 303.73046875 107.581054688 c 0
262.674804688 90.396484375 228.48828125 81.078125 203.702148438 76.0087890625 c 0
176.166992188 70.3779296875 160.23046875 70 159.536132812 69.986328125 c 1
159.698242188 69.9873046875 160 69.98828125 160 69.98828125 c 1
160 -49.98828125 l 1
172.241210938 -49.98828125 598.549804688 -45.2431640625 948.951171875 611.7578125 c 0
1036.77050781 776.418945312 1128.25 895.294921875 1214.17578125 981.219726562 c 0
1318.08203125 1085.12695312 1414.38964844 1141.49707031 1488.26953125 1172.41894531 c 0
1529.32519531 1189.60351562 1563.51171875 1198.921875 1588.29785156 1203.99121094 c 0
1615.83300781 1209.62207031 1631.76953125 1210 1632.46386719 1210.01367188 c 1
1632.30175781 1210.01269531 1632 1210.01171875 1632 1210.01171875 c 1
1632 1090.03515625 m 1
1632 1449.96484375 l 1
1552.21679688 1449.96484375 1098.71386719 1402.66308594 737.146484375 724.725585938 c 0
698.938476562 653.084960938 526.864257812 331.080078125 257.309570312 218.258789062 c 0
255.126953125 217.345703125 200.76171875 194.705078125 160 189.96484375 c 1
160 -169.96484375 l 1
239.783203125 -169.96484375 693.286132812 -122.663085938 1054.85351562 555.274414062 c 0
1093.06152344 626.915039062 1265.13574219 948.919921875 1534.69042969 1061.74121094 c 0
1536.87304688 1062.65429688 1591.23828125 1085.29492188 1632 1090.03515625 c 1
EndSplineSet
EndUndoOperation
UndoOperation
Index: 3
Type: 3
WasModified: 1
WasOrder2: 0
Layer: 2
EndUndoOperation
UndoOperation
Index: 4
Type: 1
WasModified: 1
WasOrder2: 0
Layer: 2
Width: 1792
VWidth: 1792
LBearingChange: 0
UnicodeEnc: 0
InstructionsLength: 0
SplineSet
159.999999952 1210.01176537 m 5
159.999999952 1329.98823463 l 5
172.240934135 1329.98823462 598.550052583 1325.24364837 948.951069976 668.241740764 c 4
1036.77007573 503.581104976 1128.25010681 384.70539769 1214.17570674 298.779797768 c 4
1318.08239786 194.873106647 1414.38934249 138.502937368 1488.26910654 107.580633787 c 4
1529.32544481 90.3965432265 1563.51147656 81.0776979108 1588.2975965 76.0087313726 c 4
1615.83281888 70.3775506458 1631.76992005 69.9999410877 1632.46377743 69.986036148 c 5
1632.30173622 69.9872464204 1632.00000005 69.9882346324 1632.00000005 69.9882346324 c 5
1632.00000005 -49.9882346324 l 5
1619.75906587 -49.9882346228 1193.44994742 -45.2436483754 843.048930024 611.758259236 c 4
755.229924271 776.418895024 663.749893187 895.29460231 577.824293264 981.220202232 c 4
473.917602143 1085.12689335 377.61065751 1141.49706263 303.730893464 1172.41936621 c 4
262.674555191 1189.60345677 228.488523437 1198.92230209 203.702403502 1203.99126863 c 4
176.167181121 1209.62244935 160.230079948 1210.00005891 159.536222574 1210.01396385 c 5
159.698263781 1210.01275358 159.999999952 1210.01176537 159.999999952 1210.01176537 c 5
159.999999857 1090.0352961 m 5
159.999999857 1449.9647039 l 5
239.782893731 1449.96470383 693.286263441 1402.66324695 1054.85320993 724.725222292 c 4
1093.06152816 653.084625607 1265.13598183 331.080480771 1534.69080463 218.25857115 c 4
1536.87267214 217.345352617 1591.23876559 194.705394151 1632.00000014 189.964703897 c 5
1632.00000014 -169.964703897 l 5
1552.21710627 -169.964703835 1098.71373656 -122.663246954 737.146790073 555.274777708 c 4
698.938471842 626.915374393 526.864018169 948.919519229 257.309195374 1061.74142885 c 4
255.127327856 1062.65464738 200.761234414 1085.29460585 159.999999857 1090.0352961 c 5
EndSplineSet
EndUndoOperation
UndoOperation
Index: 5
Type: 3
WasModified: 1
WasOrder2: 0
Layer: 2
EndUndoOperation
UndoOperation
Index: 6
Type: 1
WasModified: 1
WasOrder2: 0
Layer: 2
Width: 1792
VWidth: 1792
LBearingChange: 0
UnicodeEnc: 0
InstructionsLength: 0
SplineSet
160 1270 m 29
160 1270 560 1270 896 640 c 4
1232 10 1632 10 1632 10 c 1029
159.999999952 1210.01176537 m 1
159.999999952 1329.98823463 l 1
172.240934135 1329.98823462 598.550052583 1325.24364837 948.951069976 668.241740764 c 0
1036.77007573 503.581104976 1128.25010681 384.70539769 1214.17570674 298.779797768 c 0
1318.08239786 194.873106647 1414.38934249 138.502937368 1488.26910654 107.580633787 c 0
1529.32544481 90.3965432265 1563.51147656 81.0776979108 1588.2975965 76.0087313726 c 0
1615.83281888 70.3775506458 1631.76992005 69.9999410877 1632.46377743 69.986036148 c 1
1632.30173622 69.9872464204 1632.00000005 69.9882346324 1632.00000005 69.9882346324 c 1
1632.00000005 -49.9882346324 l 1
1619.75906587 -49.9882346228 1193.44994742 -45.2436483754 843.048930024 611.758259236 c 0
755.229924271 776.418895024 663.749893187 895.29460231 577.824293264 981.220202232 c 0
473.917602143 1085.12689335 377.61065751 1141.49706263 303.730893464 1172.41936621 c 0
262.674555191 1189.60345677 228.488523437 1198.92230209 203.702403502 1203.99126863 c 0
176.167181121 1209.62244935 160.230079948 1210.00005891 159.536222574 1210.01396385 c 1
159.698263781 1210.01275358 159.999999952 1210.01176537 159.999999952 1210.01176537 c 1
EndSplineSet
EndUndoOperation
UndoOperation
Index: 7
Type: 3
WasModified: 1
WasOrder2: 0
Layer: 2
EndUndoOperation
UndoOperation
Index: 8
Type: 1
WasModified: 1
WasOrder2: 0
Layer: 2
Width: 1792
VWidth: 1792
LBearingChange: 0
UnicodeEnc: 0
InstructionsLength: 0
SplineSet
160 1270 m 29
160 1270 560 1270 896 640 c 4
1232 10 1632 10 1632 10 c 1029
EndSplineSet
EndUndoOperation
UndoOperation
Index: 9
Type: 3
WasModified: 1
WasOrder2: 0
Layer: 2
EndUndoOperation
UndoOperation
Index: 10
Type: 2
WasModified: 1
WasOrder2: 0
Layer: 2
Width: 1792
VWidth: 1792
LBearingChange: 0
UnicodeEnc: 0
InstructionsLength: 0
SplineSet
160 1270 m 29
160 1270 560 1270 896 640 c 4
1232 10 1632 10 1632 10 c 1029
EndSplineSet
EndUndoOperation
UndoOperation
Index: 11
Type: 1
WasModified: 1
WasOrder2: 0
Layer: 1
Width: 1792
VWidth: 1792
LBearingChange: 0
UnicodeEnc: 0
InstructionsLength: 0
EndUndoOperation
EndUndoes
Redoes
EndRedoes
EndUndoRedoHistory
Fore Fore
SplineSet SplineSet
1632 1210.01171875 m 1 1632 1210.01171875 m 1
@ -7139,5 +6785,102 @@ SplineSet
991.110875674 442.719806976 1013.74868988 480.580583771 1036.07195969 520.767740886 c 1 991.110875674 442.719806976 1013.74868988 480.580583771 1036.07195969 520.767740886 c 1
EndSplineSet EndSplineSet
EndChar EndChar
StartChar: uniE15A
Encoding: 57690 57690 96
Width: 1792
Flags: HW
LayerCount: 2
Fore
SplineSet
170.8046875 72.1796875 m 1
170.8046875 351.37890625 170.8046875 630.578125 170.8046875 909.77734375 c 1
290.791992188 909.77734375 410.778320312 909.77734375 530.765625 909.77734375 c 1
608.40234375 909.77734375 668.36328125 887.0234375 710.74609375 841.41796875 c 128
753.2265625 795.8125 774.41796875 734.58203125 774.41796875 657.82421875 c 256
774.41796875 580.96875 753.2265625 519.73828125 710.74609375 474.1328125 c 128
668.36328125 428.625 608.40234375 405.7734375 530.765625 405.7734375 c 1
455.9609375 405.7734375 381.15625 405.7734375 306.3515625 405.7734375 c 1
306.3515625 294.576171875 306.3515625 183.377929688 306.3515625 72.1796875 c 1
261.168945312 72.1796875 215.987304688 72.1796875 170.8046875 72.1796875 c 1
306.3515625 524.62109375 m 1
378.356445312 524.62109375 450.362304688 524.62109375 522.3671875 524.62109375 c 1
556.7421875 524.62109375 583.59765625 533.60546875 602.73828125 551.57421875 c 128
621.9765625 569.54296875 631.546875 595.421875 631.546875 629.015625 c 1
631.546875 648.189453125 631.546875 667.362304688 631.546875 686.53515625 c 1
631.546875 720.2265625 621.9765625 746.0078125 602.73828125 763.9765625 c 128
583.59765625 781.9453125 556.7421875 791.02734375 522.3671875 791.02734375 c 1
450.362304688 791.02734375 378.356445312 791.02734375 306.3515625 791.02734375 c 1
306.3515625 702.225585938 306.3515625 613.423828125 306.3515625 524.62109375 c 1
1196.390625 535.36328125 m 1
1165.59667969 594.576171875 1134.80175781 653.788085938 1104.0078125 713 c 1
1102.80371094 713 1101.59863281 713 1100.39453125 713 c 1
1100.39453125 499.393554688 1100.39453125 285.787109375 1100.39453125 72.1796875 c 1
1057.19824219 72.1796875 1014.00097656 72.1796875 970.8046875 72.1796875 c 1
970.8046875 351.37890625 970.8046875 630.578125 970.8046875 909.77734375 c 1
1021.1953125 909.77734375 1071.5859375 909.77734375 1121.9765625 909.77734375 c 1
1213.1875 755.3828125 1304.3984375 600.98828125 1395.609375 446.59375 c 1
1426.40332031 387.381835938 1457.19824219 328.169921875 1487.9921875 268.95703125 c 1
1489.19628906 268.95703125 1490.40136719 268.95703125 1491.60546875 268.95703125 c 1
1491.60546875 482.564453125 1491.60546875 696.170898438 1491.60546875 909.77734375 c 1
1534.80175781 909.77734375 1577.99902344 909.77734375 1621.1953125 909.77734375 c 1
1621.1953125 630.578125 1621.1953125 351.37890625 1621.1953125 72.1796875 c 1
1570.8046875 72.1796875 1520.4140625 72.1796875 1470.0234375 72.1796875 c 1
1378.8125 226.57421875 1287.6015625 380.96875 1196.390625 535.36328125 c 1
EndSplineSet
EndChar
StartChar: uniE15B
Encoding: 57691 57691 97
Width: 1792
Flags: HWO
LayerCount: 2
Fore
SplineSet
938.209960938 435.383789062 m 1
938.209960938 -25.1181640625 l 1
1234.27539062 247.456054688 l 1
1234.27539062 117.280273438 l 1
836.430664062 -248.998046875 l 1xd3ce
836.430664062 211.504882812 l 1
540.365234375 -61.0693359375 l 1
540.365234375 69.1064453125 l 1
938.209960938 435.383789062 l 1
315.962890625 621 m 1
315.962890625 844.359375 315.962890625 1067.71875 315.962890625 1291.078125 c 1
411.952148438 1291.078125 507.942382812 1291.078125 603.931640625 1291.078125 c 1
666.041015625 1291.078125 714.009765625 1272.875 747.916015625 1236.390625 c 128
781.900390625 1199.90625 798.853515625 1150.921875 798.853515625 1089.515625 c 256
798.853515625 1028.03125 781.900390625 979.046875 747.916015625 942.5625 c 128
714.009765625 906.15625 666.041015625 887.875 603.931640625 887.875 c 1
544.087890625 887.875 484.244140625 887.875 424.400390625 887.875 c 1
424.400390625 798.916992188 424.400390625 709.958984375 424.400390625 621 c 1
388.254882812 621 352.108398438 621 315.962890625 621 c 1
424.400390625 982.953125 m 1
482.004882812 982.953125 539.608398438 982.953125 597.212890625 982.953125 c 1
624.712890625 982.953125 646.197265625 990.140625 661.509765625 1004.515625 c 128
676.900390625 1018.890625 684.556640625 1039.59375 684.556640625 1066.46875 c 1
684.556640625 1081.80761719 684.556640625 1097.14648438 684.556640625 1112.484375 c 1
684.556640625 1139.4375 676.900390625 1160.0625 661.509765625 1174.4375 c 128
646.197265625 1188.8125 624.712890625 1196.078125 597.212890625 1196.078125 c 1
539.608398438 1196.078125 482.004882812 1196.078125 424.400390625 1196.078125 c 1
424.400390625 1125.03710938 424.400390625 1053.99511719 424.400390625 982.953125 c 1
1136.43164062 991.546875 m 1
1111.79589844 1038.91699219 1087.16113281 1086.28710938 1062.52539062 1133.65625 c 1
1061.56152344 1133.65625 1060.59863281 1133.65625 1059.63476562 1133.65625 c 1
1059.63476562 962.771484375 1059.63476562 791.885742188 1059.63476562 621 c 1
1025.07714844 621 990.520507812 621 955.962890625 621 c 1
955.962890625 844.359375 955.962890625 1067.71875 955.962890625 1291.078125 c 1
996.275390625 1291.078125 1036.58789062 1291.078125 1076.90039062 1291.078125 c 1
1149.86914062 1167.5625 1222.83789062 1044.046875 1295.80664062 920.53125 c 1
1320.44238281 873.162109375 1345.07714844 825.791992188 1369.71289062 778.421875 c 1
1370.67675781 778.421875 1371.63964844 778.421875 1372.60351562 778.421875 c 1
1372.60351562 949.307617188 1372.60351562 1120.19335938 1372.60351562 1291.078125 c 1
1407.16113281 1291.078125 1441.71777344 1291.078125 1476.27539062 1291.078125 c 1
1476.27539062 1067.71875 1476.27539062 844.359375 1476.27539062 621 c 1
1435.96289062 621 1395.65039062 621 1355.33789062 621 c 1
1282.36914062 744.515625 1209.40039062 868.03125 1136.43164062 991.546875 c 1
EndSplineSet
EndChar
EndChars EndChars
EndSplineFont EndSplineFont

Binary file not shown.

View file

@ -16,9 +16,9 @@ if you find issues (e.g. bugs or annoyances), report them. links below.
- Furnace on GitHub (project page and issue tracker): https://github.com/tildearrow/furnace - Furnace on GitHub (project page and issue tracker): https://github.com/tildearrow/furnace
- issues: https://github.com/tildearrow/furnace/issues - issues: https://github.com/tildearrow/furnace/issues
- discussion: https://github.com/tildearrow/furnace/discussions - discussion: https://github.com/tildearrow/furnace/discussions
- Furnace on Revolt: https://rvlt.gg/GRPS6tmc
- Furnace on Discord: https://discord.gg/EfrwT2wq7z - Furnace on Discord: https://discord.gg/EfrwT2wq7z
- online manual: https://tildearrow.org/furnace/doc/v0.6/ - Furnace on Revolt: https://rvlt.gg/GRPS6tmc
- online manual: https://tildearrow.org/furnace/doc/v0.6.1/
# notes # notes

View file

@ -26,9 +26,9 @@ if you find issues (e.g. bugs or annoyances), report them. links below.
- Furnace on GitHub (project page and issue tracker): https://github.com/tildearrow/furnace - Furnace on GitHub (project page and issue tracker): https://github.com/tildearrow/furnace
- issues: https://github.com/tildearrow/furnace/issues - issues: https://github.com/tildearrow/furnace/issues
- discussion: https://github.com/tildearrow/furnace/discussions - discussion: https://github.com/tildearrow/furnace/discussions
- Furnace on Revolt: https://rvlt.gg/GRPS6tmc
- Furnace on Discord: https://discord.gg/EfrwT2wq7z - Furnace on Discord: https://discord.gg/EfrwT2wq7z
- online manual: https://tildearrow.org/furnace/doc/v0.6/ - Furnace on Revolt: https://rvlt.gg/GRPS6tmc
- online manual: https://tildearrow.org/furnace/doc/v0.6.1/
# notes # notes

View file

@ -16,9 +16,9 @@ if you find issues (e.g. bugs or annoyances), report them. links below.
- Furnace on GitHub (project page and issue tracker): https://github.com/tildearrow/furnace - Furnace on GitHub (project page and issue tracker): https://github.com/tildearrow/furnace
- issues: https://github.com/tildearrow/furnace/issues - issues: https://github.com/tildearrow/furnace/issues
- discussion: https://github.com/tildearrow/furnace/discussions - discussion: https://github.com/tildearrow/furnace/discussions
- Furnace on Revolt: https://rvlt.gg/GRPS6tmc
- Furnace on Discord: https://discord.gg/EfrwT2wq7z - Furnace on Discord: https://discord.gg/EfrwT2wq7z
- online manual: https://tildearrow.org/furnace/doc/v0.6/ - Furnace on Revolt: https://rvlt.gg/GRPS6tmc
- online manual: https://tildearrow.org/furnace/doc/v0.6.1/
# notes # notes

View file

@ -8,11 +8,11 @@ fi
cd /tmp/furnace cd /tmp/furnace
if [ ! -e linuxbuild ]; then if [ ! -e aibuild ]; then
mkdir linuxbuild || exit 1 mkdir aibuild || exit 1
fi fi
cd linuxbuild cd aibuild
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-O2" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Werror" -DWITH_DEMOS=OFF -DWITH_INSTRUMENTS=OFF -DWITH_WAVETABLES=OFF .. || exit 1 cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-O2" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Werror" -DWITH_DEMOS=OFF -DWITH_INSTRUMENTS=OFF -DWITH_WAVETABLES=OFF .. || exit 1
make -j4 || exit 1 make -j4 || exit 1
@ -20,7 +20,7 @@ make -j4 || exit 1
cd .. cd ..
mkdir -p release/linux/furnace.AppDir || exit 1 mkdir -p release/linux/furnace.AppDir || exit 1
cd linuxbuild cd aibuild
make DESTDIR=/tmp/furnace/release/linux/furnace.AppDir install || exit 1 make DESTDIR=/tmp/furnace/release/linux/furnace.AppDir install || exit 1

22
src/divasm/divasm.cpp Normal file
View file

@ -0,0 +1,22 @@
/**
* Furnace Tracker - multi-system chiptune tracker
* Copyright (C) 2021-2024 tildearrow and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "divasm.h"

View file

@ -1,3 +1,27 @@
/**
* Furnace Tracker - multi-system chiptune tracker
* Copyright (C) 2021-2024 tildearrow and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// this is a mini-assembler written for Furnace.
// it will be used in future ROM export (yes, that's right, ROM is baked at export time).
#include "../engine/safeWriter.h"
struct DivASMResult { struct DivASMResult {
int line, err; int line, err;
DivASMResult(): DivASMResult():
@ -5,26 +29,34 @@ struct DivASMResult {
err(0) {} err(0) {}
}; };
struct DivASMFile {
String name;
SafeReader* data;
};
enum DivASMTarget { enum DivASMTarget {
DIV_ASM_TARGET_DUMMY=0, DIV_ASM_TARGET_DUMMY=0,
DIV_ASM_TARGET_6502, DIV_ASM_TARGET_6502,
DIV_ASM_TARGET_SPC700 DIV_ASM_TARGET_SPC700,
DIV_ASM_TARGET_Z80
};
struct DivLabel {
String name;
unsigned int location;
bool direct;
};
struct DivOper {
String operation;
int line;
}; };
class DivASM { class DivASM {
std::vector<DivASMFile> files;
SafeWriter* result; SafeWriter* result;
std::vector<DivLabel> labels;
std::vector<DivOper> ops;
public: public:
DivASMResult getError(); DivASMResult getError();
SafeWriter* assemble(String name); SafeWriter* assemble(SafeReader* data);
void addFile(String name, SafeReader* data);
DivASM(DivASMTarget target); DivASM();
~DivASM(); ~DivASM();
}; };

30
src/divasm/standalone.cpp Normal file
View file

@ -0,0 +1,30 @@
/**
* Furnace Tracker - multi-system chiptune tracker
* Copyright (C) 2021-2024 tildearrow and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "divasm.h"
int main(int argc, char** argv) {
if (argc<2) {
printf("usage: %s file\n",argv[0]);
return 1;
}
return 0;
}

View file

@ -20,6 +20,7 @@
#ifndef _CHIP_UTILS_H #ifndef _CHIP_UTILS_H
#define _CHIP_UTILS_H #define _CHIP_UTILS_H
#include "defines.h"
#include "macroInt.h" #include "macroInt.h"
// custom clock limits // custom clock limits
@ -29,7 +30,7 @@
// common shared channel struct // common shared channel struct
template<typename T> struct SharedChannel { template<typename T> struct SharedChannel {
int freq, baseFreq, baseNoteOverride, pitch, pitch2, arpOff; int freq, baseFreq, baseNoteOverride, pitch, pitch2, arpOff;
int ins, note; int ins, note, sampleNote, sampleNoteDelta;
bool active, insChanged, freqChanged, fixedArp, keyOn, keyOff, portaPause, inPorta; bool active, insChanged, freqChanged, fixedArp, keyOn, keyOff, portaPause, inPorta;
T vol, outVol; T vol, outVol;
DivMacroInt std; DivMacroInt std;
@ -71,6 +72,8 @@ template<typename T> struct SharedChannel {
arpOff(0), arpOff(0),
ins(-1), ins(-1),
note(0), note(0),
sampleNote(DIV_NOTE_NULL),
sampleNoteDelta(0),
active(false), active(false),
insChanged(true), insChanged(true),
freqChanged(false), freqChanged(false),

View file

@ -36,5 +36,6 @@
// dispatch // dispatch
#define DIV_MAX_OUTPUTS 16 #define DIV_MAX_OUTPUTS 16
#define DIV_NOTE_NULL 0x7fffffff
#endif #endif

View file

@ -25,11 +25,10 @@
#include "../pch.h" #include "../pch.h"
#include "config.h" #include "config.h"
#include "chipUtils.h" #include "chipUtils.h"
#include "defines.h"
#define ONE_SEMITONE 2200 #define ONE_SEMITONE 2200
#define DIV_NOTE_NULL 0x7fffffff
#define addWrite(a,v) regWrites.push_back(DivRegWrite(a,v)); #define addWrite(a,v) regWrites.push_back(DivRegWrite(a,v));
// HOW TO ADD A NEW COMMAND: // HOW TO ADD A NEW COMMAND:

View file

@ -52,10 +52,10 @@ class DivWorkPool;
#define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock(); #define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock();
#define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false; #define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false;
#define DIV_UNSTABLE //#define DIV_UNSTABLE
#define DIV_VERSION "dev191" #define DIV_VERSION "0.6.1"
#define DIV_ENGINE_VERSION 191 #define DIV_ENGINE_VERSION 192
// for imports // for imports
#define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_MOD 0xff01
#define DIV_VERSION_FC 0xff02 #define DIV_VERSION_FC 0xff02

View file

@ -370,20 +370,10 @@ void DivPlatformAmiga::tick(bool sysTick) {
chan[i].outVol=((chan[i].vol%65)*MIN(64,chan[i].std.vol.val))>>6; chan[i].outVol=((chan[i].vol%65)*MIN(64,chan[i].std.vol.val))>>6;
chan[i].writeVol=true; chan[i].writeVol=true;
} }
double off=1.0;
if (!chan[i].useWave && chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(chan[i].sample);
if (s->centerRate<1) {
off=1.0;
} else {
off=8363.0/(double)s->centerRate;
}
}
if (NEW_ARP_STRAT) { if (NEW_ARP_STRAT) {
chan[i].handleArp(); chan[i].handleArp();
} else if (chan[i].std.arp.had) { } else if (chan[i].std.arp.had) {
// TODO: why the off mult? this may be a bug! chan[i].baseFreq=round(NOTE_PERIODIC_NOROUND(parent->calcArp(chan[i].note,chan[i].std.arp.val)));
chan[i].baseFreq=round(off*NOTE_PERIODIC_NOROUND(parent->calcArp(chan[i].note,chan[i].std.arp.val)));
chan[i].freqChanged=true; chan[i].freqChanged=true;
} }
if (chan[i].useWave && chan[i].std.wave.had) { if (chan[i].useWave && chan[i].std.wave.had) {
@ -577,10 +567,14 @@ int DivPlatformAmiga::dispatch(DivCommand c) {
chan[c.chan].updateWave=true; chan[c.chan].updateWave=true;
} }
} }
chan[c.chan].sampleNote=DIV_NOTE_NULL;
chan[c.chan].sampleNoteDelta=0;
} else { } else {
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value); chan[c.chan].sample=ins->amiga.getSample(c.value);
chan[c.chan].sampleNote=c.value;
c.value=ins->amiga.getFreq(c.value); c.value=ins->amiga.getFreq(c.value);
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
} }
chan[c.chan].useWave=false; chan[c.chan].useWave=false;
} }
@ -657,9 +651,7 @@ int DivPlatformAmiga::dispatch(DivCommand c) {
chan[c.chan].updateWave=true; chan[c.chan].updateWave=true;
break; break;
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); int destFreq=round(NOTE_PERIODIC_NOROUND(c.value2+chan[c.chan].sampleNoteDelta));
chan[c.chan].sample=ins->amiga.getSample(c.value2);
int destFreq=round(NOTE_PERIODIC_NOROUND(c.value2));
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value; chan[c.chan].baseFreq+=c.value;
@ -682,7 +674,7 @@ int DivPlatformAmiga::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
chan[c.chan].baseFreq=round(NOTE_PERIODIC_NOROUND(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0)))); chan[c.chan].baseFreq=round(NOTE_PERIODIC_NOROUND(c.value+chan[c.chan].sampleNoteDelta+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0))));
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
break; break;

View file

@ -405,7 +405,12 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
if (!parent->song.disableSampleMacro && (ins->type==DIV_INS_AMIGA || ins->amiga.useSample)) { if (!parent->song.disableSampleMacro && (ins->type==DIV_INS_AMIGA || ins->amiga.useSample)) {
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].dac.sample=ins->amiga.getSample(c.value); chan[c.chan].dac.sample=ins->amiga.getSample(c.value);
chan[c.chan].sampleNote=c.value;
c.value=ins->amiga.getFreq(c.value); c.value=ins->amiga.getFreq(c.value);
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
chan[c.chan].dac.sample=ins->amiga.getSample(chan[c.chan].sampleNote);
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
} }
if (chan[c.chan].dac.sample<0 || chan[c.chan].dac.sample>=parent->song.sampleLen) { if (chan[c.chan].dac.sample<0 || chan[c.chan].dac.sample>=parent->song.sampleLen) {
chan[c.chan].dac.sample=-1; chan[c.chan].dac.sample=-1;
@ -457,6 +462,8 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
break; break;
} }
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sampleNote=DIV_NOTE_NULL;
chan[c.chan].sampleNoteDelta=0;
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
@ -526,7 +533,7 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
int destFreq=NOTE_PERIODIC(c.value2); int destFreq=NOTE_PERIODIC(c.value2+chan[c.chan].sampleNoteDelta);
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value; chan[c.chan].baseFreq+=c.value;
@ -549,7 +556,7 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+chan[c.chan].sampleNoteDelta);
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
} }

View file

@ -406,7 +406,12 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) { if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) {
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].dac.sample=ins->amiga.getSample(c.value); chan[c.chan].dac.sample=ins->amiga.getSample(c.value);
chan[c.chan].sampleNote=c.value;
c.value=ins->amiga.getFreq(c.value); c.value=ins->amiga.getFreq(c.value);
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
chan[c.chan].dac.sample=ins->amiga.getSample(chan[c.chan].sampleNote);
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
} }
if (chan[c.chan].dac.sample<0 || chan[c.chan].dac.sample>=parent->song.sampleLen) { if (chan[c.chan].dac.sample<0 || chan[c.chan].dac.sample>=parent->song.sampleLen) {
chan[c.chan].dac.sample=-1; chan[c.chan].dac.sample=-1;
@ -458,6 +463,8 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
break; break;
} }
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sampleNote=DIV_NOTE_NULL;
chan[c.chan].sampleNoteDelta=0;
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
@ -520,7 +527,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
int destFreq=NOTE_PERIODIC(c.value2); int destFreq=NOTE_PERIODIC(c.value2+chan[c.chan].sampleNoteDelta);
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value; chan[c.chan].baseFreq+=c.value;
@ -543,7 +550,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+chan[c.chan].sampleNoteDelta);
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
} }

View file

@ -320,7 +320,9 @@ int DivPlatformC140::dispatch(DivCommand c) {
chan[c.chan].macroPanMul=ins->type==DIV_INS_AMIGA?127:255; chan[c.chan].macroPanMul=ins->type==DIV_INS_AMIGA?127:255;
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value); chan[c.chan].sample=ins->amiga.getSample(c.value);
chan[c.chan].sampleNote=c.value;
c.value=ins->amiga.getFreq(c.value); c.value=ins->amiga.getFreq(c.value);
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
} }
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value); chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
@ -393,7 +395,7 @@ int DivPlatformC140::dispatch(DivCommand c) {
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
int destFreq=NOTE_FREQUENCY(c.value2); int destFreq=NOTE_FREQUENCY(c.value2+chan[c.chan].sampleNoteDelta);
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value; chan[c.chan].baseFreq+=c.value;
@ -416,7 +418,7 @@ int DivPlatformC140::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0))); chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value+chan[c.chan].sampleNoteDelta+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0)));
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
break; break;

View file

@ -719,27 +719,51 @@ void DivPlatformES5506::tick(bool sysTick) {
} }
} }
// man this code
// part of the reason why it's so messy is because the chip is
// overly complex and because when this pull request was made,
// Furnace still was in an early state with no support for sample
// maps or whatever...
// one day I'll come back and clean this up
int DivPlatformES5506::dispatch(DivCommand c) { int DivPlatformES5506::dispatch(DivCommand c) {
switch (c.cmd) { switch (c.cmd) {
case DIV_CMD_NOTE_ON: { case DIV_CMD_NOTE_ON: {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_ES5506); DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_ES5506);
bool sampleValid=false; bool sampleValid=false;
if (((ins->amiga.useNoteMap) && (c.value>=0 && c.value<120)) || if (c.value!=DIV_NOTE_NULL) {
((!ins->amiga.useNoteMap) && (ins->amiga.initSample>=0 && ins->amiga.initSample<parent->song.sampleLen))) {
int sample=ins->amiga.getSample(c.value); int sample=ins->amiga.getSample(c.value);
chan[c.chan].sampleNote=c.value;
if (sample>=0 && sample<parent->song.sampleLen) { if (sample>=0 && sample<parent->song.sampleLen) {
sampleValid=true; sampleValid=true;
chan[c.chan].volMacroMax=ins->type==DIV_INS_AMIGA?64:0xfff; chan[c.chan].volMacroMax=ins->type==DIV_INS_AMIGA?64:0xfff;
chan[c.chan].panMacroMax=ins->type==DIV_INS_AMIGA?127:0xfff; chan[c.chan].panMacroMax=ins->type==DIV_INS_AMIGA?127:0xfff;
chan[c.chan].pcm.next=ins->amiga.useNoteMap?c.value:sample; chan[c.chan].pcm.next=ins->amiga.useNoteMap?c.value:sample;
c.value=ins->amiga.getFreq(c.value); c.value=ins->amiga.getFreq(c.value);
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
chan[c.chan].pcm.note=c.value; chan[c.chan].pcm.note=c.value;
chan[c.chan].filter=ins->es5506.filter; chan[c.chan].filter=ins->es5506.filter;
chan[c.chan].envelope=ins->es5506.envelope; chan[c.chan].envelope=ins->es5506.envelope;
} else {
chan[c.chan].sampleNoteDelta=0;
}
} else {
int sample=ins->amiga.getSample(chan[c.chan].sampleNote);
if (sample>=0 && sample<parent->song.sampleLen) {
sampleValid=true;
chan[c.chan].volMacroMax=ins->type==DIV_INS_AMIGA?64:0xfff;
chan[c.chan].panMacroMax=ins->type==DIV_INS_AMIGA?127:0xfff;
chan[c.chan].pcm.next=ins->amiga.useNoteMap?chan[c.chan].sampleNote:sample;
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
chan[c.chan].pcm.note=c.value;
chan[c.chan].filter=ins->es5506.filter;
chan[c.chan].envelope=ins->es5506.envelope;
} else {
chan[c.chan].sampleNoteDelta=0;
} }
} }
if (!sampleValid) { if (!sampleValid) {
chan[c.chan].pcm.index=chan[c.chan].pcm.next=-1; chan[c.chan].pcm.index=chan[c.chan].pcm.next=-1;
chan[c.chan].sampleNoteDelta=0;
chan[c.chan].filter=DivInstrumentES5506::Filter(); chan[c.chan].filter=DivInstrumentES5506::Filter();
chan[c.chan].envelope=DivInstrumentES5506::Envelope(); chan[c.chan].envelope=DivInstrumentES5506::Envelope();
} }
@ -962,7 +986,7 @@ int DivPlatformES5506::dispatch(DivCommand c) {
break; break;
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
int nextFreq=chan[c.chan].baseFreq; int nextFreq=chan[c.chan].baseFreq;
const int destFreq=NOTE_ES5506(c.chan,c.value2); const int destFreq=NOTE_ES5506(c.chan,c.value2+chan[c.chan].sampleNoteDelta);
bool return2=false; bool return2=false;
if (destFreq>nextFreq) { if (destFreq>nextFreq) {
nextFreq+=c.value; nextFreq+=c.value;
@ -987,7 +1011,7 @@ int DivPlatformES5506::dispatch(DivCommand c) {
} }
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
chan[c.chan].nextNote=chan[c.chan].note+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0)); chan[c.chan].nextNote=chan[c.chan].note+chan[c.chan].sampleNoteDelta+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0));
chan[c.chan].noteChanged.note=1; chan[c.chan].noteChanged.note=1;
break; break;
} }

View file

@ -207,7 +207,9 @@ int DivPlatformGA20::dispatch(DivCommand c) {
chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:255; chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:255;
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value); chan[c.chan].sample=ins->amiga.getSample(c.value);
chan[c.chan].sampleNote=c.value;
c.value=ins->amiga.getFreq(c.value); c.value=ins->amiga.getFreq(c.value);
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
} }
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
@ -263,7 +265,7 @@ int DivPlatformGA20::dispatch(DivCommand c) {
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
const int destFreq=NOTE_PERIODIC(c.value2); const int destFreq=NOTE_PERIODIC(c.value2+chan[c.chan].sampleNoteDelta);
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value; chan[c.chan].baseFreq+=c.value;
@ -286,7 +288,7 @@ int DivPlatformGA20::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0))); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+chan[c.chan].sampleNoteDelta+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0)));
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
break; break;

View file

@ -704,8 +704,12 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
} else if (chan[c.chan].furnaceDac) { } else if (chan[c.chan].furnaceDac) {
chan[c.chan].dacMode=0; chan[c.chan].dacMode=0;
rWrite(0x2b,0<<7); rWrite(0x2b,0<<7);
chan[c.chan].sampleNote=DIV_NOTE_NULL;
chan[c.chan].sampleNoteDelta=0;
} else if (!chan[c.chan].dacMode) { } else if (!chan[c.chan].dacMode) {
rWrite(0x2b,0<<7); rWrite(0x2b,0<<7);
chan[c.chan].sampleNote=DIV_NOTE_NULL;
chan[c.chan].sampleNoteDelta=0;
} }
} }
if (c.chan>=5 && chan[c.chan].dacMode) { if (c.chan>=5 && chan[c.chan].dacMode) {
@ -713,7 +717,12 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
if (ins->type==DIV_INS_AMIGA) { // Furnace mode if (ins->type==DIV_INS_AMIGA) { // Furnace mode
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].dacSample=ins->amiga.getSample(c.value); chan[c.chan].dacSample=ins->amiga.getSample(c.value);
chan[c.chan].sampleNote=c.value;
c.value=ins->amiga.getFreq(c.value); c.value=ins->amiga.getFreq(c.value);
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
chan[c.chan].dacSample=ins->amiga.getSample(chan[c.chan].sampleNote);
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
} }
if (chan[c.chan].dacSample<0 || chan[c.chan].dacSample>=parent->song.sampleLen) { if (chan[c.chan].dacSample<0 || chan[c.chan].dacSample>=parent->song.sampleLen) {
chan[c.chan].dacSample=-1; chan[c.chan].dacSample=-1;
@ -752,6 +761,8 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
} }
chan[c.chan].sampleNote=DIV_NOTE_NULL;
chan[c.chan].sampleNoteDelta=0;
chan[c.chan].dacSample=12*chan[c.chan].sampleBank+chan[c.chan].note%12; chan[c.chan].dacSample=12*chan[c.chan].sampleBank+chan[c.chan].note%12;
if (chan[c.chan].dacSample>=parent->song.sampleLen) { if (chan[c.chan].dacSample>=parent->song.sampleLen) {
chan[c.chan].dacSample=-1; chan[c.chan].dacSample=-1;
@ -863,7 +874,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
} }
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
if (parent->song.linearPitch==2) { if (parent->song.linearPitch==2) {
int destFreq=NOTE_FREQUENCY(c.value2); int destFreq=NOTE_FREQUENCY(c.value2+chan[c.chan].sampleNoteDelta);
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value; chan[c.chan].baseFreq+=c.value;
@ -909,7 +920,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
break; break;
} }
if (c.chan>=5 && chan[c.chan].furnaceDac && chan[c.chan].dacMode) { if (c.chan>=5 && chan[c.chan].furnaceDac && chan[c.chan].dacMode) {
int destFreq=parent->calcBaseFreq(1,1,c.value2,false); int destFreq=parent->calcBaseFreq(1,1,c.value2+chan[c.chan].sampleNoteDelta,false);
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value*16; chan[c.chan].baseFreq+=c.value*16;
@ -963,7 +974,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
if (c.chan==csmChan) { if (c.chan==csmChan) {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
} else if (c.chan>=5 && chan[c.chan].furnaceDac && chan[c.chan].dacMode) { } else if (c.chan>=5 && chan[c.chan].furnaceDac && chan[c.chan].dacMode) {
chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false); chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value+chan[c.chan].sampleNoteDelta,false);
} else { } else {
if (chan[c.chan].insChanged) { if (chan[c.chan].insChanged) {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM); DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);

View file

@ -281,7 +281,9 @@ int DivPlatformK007232::dispatch(DivCommand c) {
chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:15; chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:15;
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value); chan[c.chan].sample=ins->amiga.getSample(c.value);
chan[c.chan].sampleNote=c.value;
c.value=ins->amiga.getFreq(c.value); c.value=ins->amiga.getFreq(c.value);
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
} }
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
@ -347,7 +349,7 @@ int DivPlatformK007232::dispatch(DivCommand c) {
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
const int destFreq=NOTE_PERIODIC(c.value2); const int destFreq=NOTE_PERIODIC(c.value2+chan[c.chan].sampleNoteDelta);
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value; chan[c.chan].baseFreq+=c.value;
@ -370,7 +372,7 @@ int DivPlatformK007232::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0))); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+chan[c.chan].sampleNoteDelta+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0)));
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
break; break;

View file

@ -230,7 +230,9 @@ int DivPlatformK053260::dispatch(DivCommand c) {
chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:127; chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:127;
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value); chan[c.chan].sample=ins->amiga.getSample(c.value);
chan[c.chan].sampleNote=c.value;
c.value=ins->amiga.getFreq(c.value); c.value=ins->amiga.getFreq(c.value);
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
} }
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
@ -291,7 +293,7 @@ int DivPlatformK053260::dispatch(DivCommand c) {
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
int destFreq=NOTE_PERIODIC(c.value2); int destFreq=NOTE_PERIODIC(c.value2+chan[c.chan].sampleNoteDelta);
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value; chan[c.chan].baseFreq+=c.value;
@ -314,7 +316,7 @@ int DivPlatformK053260::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0))); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+chan[c.chan].sampleNoteDelta+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0)));
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
break; break;

View file

@ -228,19 +228,28 @@ int DivPlatformLynx::dispatch(DivCommand c) {
WRITE_CONTROL(c.chan,0x18); WRITE_CONTROL(c.chan,0x18);
WRITE_BACKUP(c.chan,0); WRITE_BACKUP(c.chan,0);
} else { } else {
chan[c.chan].sampleNote=DIV_NOTE_NULL;
chan[c.chan].sampleNoteDelta=0;
WRITE_FEEDBACK(c.chan,chan[c.chan].duty.feedback); WRITE_FEEDBACK(c.chan,chan[c.chan].duty.feedback);
WRITE_CONTROL(c.chan,(chan[c.chan].fd.clockDivider|0x18|chan[c.chan].duty.int_feedback7)); WRITE_CONTROL(c.chan,(chan[c.chan].fd.clockDivider|0x18|chan[c.chan].duty.int_feedback7));
WRITE_BACKUP(c.chan,chan[c.chan].fd.backup); WRITE_BACKUP(c.chan,chan[c.chan].fd.backup);
} }
} }
if (c.value!=DIV_NOTE_NULL) {
if (chan[c.chan].pcm) { if (chan[c.chan].pcm) {
if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value); chan[c.chan].sample=ins->amiga.getSample(c.value);
chan[c.chan].sampleNote=c.value;
c.value=ins->amiga.getFreq(c.value); c.value=ins->amiga.getFreq(c.value);
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
chan[c.chan].sampleBaseFreq=NOTE_FREQUENCY(c.value); chan[c.chan].sampleBaseFreq=NOTE_FREQUENCY(c.value);
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(chan[c.chan].sampleNote);
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
}
chan[c.chan].sampleAccum=0; chan[c.chan].sampleAccum=0;
chan[c.chan].samplePos=0; chan[c.chan].samplePos=0;
} }
if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
@ -301,7 +310,7 @@ int DivPlatformLynx::dispatch(DivCommand c) {
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
int destFreq=NOTE_PERIODIC(c.value2); int destFreq=NOTE_PERIODIC(c.value2+chan[c.chan].sampleNoteDelta);
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value; chan[c.chan].baseFreq+=c.value;
@ -327,7 +336,7 @@ int DivPlatformLynx::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
int whatAMess=c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0)); int whatAMess=c.value+chan[c.chan].sampleNoteDelta+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0));
chan[c.chan].baseFreq=NOTE_PERIODIC(whatAMess); chan[c.chan].baseFreq=NOTE_PERIODIC(whatAMess);
if (chan[c.chan].pcm) { if (chan[c.chan].pcm) {
chan[c.chan].sampleBaseFreq=NOTE_FREQUENCY(whatAMess); chan[c.chan].sampleBaseFreq=NOTE_FREQUENCY(whatAMess);

View file

@ -178,7 +178,12 @@ int DivPlatformMMC5::dispatch(DivCommand c) {
if (ins->type==DIV_INS_AMIGA) { if (ins->type==DIV_INS_AMIGA) {
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
dacSample=ins->amiga.getSample(c.value); dacSample=ins->amiga.getSample(c.value);
chan[c.chan].sampleNote=c.value;
c.value=ins->amiga.getFreq(c.value); c.value=ins->amiga.getFreq(c.value);
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
dacSample=ins->amiga.getSample(chan[c.chan].sampleNote);
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
} }
if (dacSample<0 || dacSample>=parent->song.sampleLen) { if (dacSample<0 || dacSample>=parent->song.sampleLen) {
dacSample=-1; dacSample=-1;
@ -189,8 +194,8 @@ int DivPlatformMMC5::dispatch(DivCommand c) {
} }
dacPos=0; dacPos=0;
dacPeriod=0; dacPeriod=0;
chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false);
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false);
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
} }
@ -270,7 +275,7 @@ int DivPlatformMMC5::dispatch(DivCommand c) {
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
int destFreq=(c.chan==2)?(parent->calcBaseFreq(1,1,c.value2,false)):(NOTE_PERIODIC(c.value2)); int destFreq=(c.chan==2)?(parent->calcBaseFreq(1,1,c.value2+chan[c.chan].sampleNoteDelta,false)):(NOTE_PERIODIC(c.value2));
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value; chan[c.chan].baseFreq+=c.value;
@ -304,7 +309,7 @@ int DivPlatformMMC5::dispatch(DivCommand c) {
break; break;
case DIV_CMD_LEGATO: case DIV_CMD_LEGATO:
if (c.chan==2) { if (c.chan==2) {
chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0)),false); chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value+chan[c.chan].sampleNoteDelta+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0)),false);
} else { } else {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0))); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0)));
} }

View file

@ -407,7 +407,14 @@ int DivPlatformNES::dispatch(DivCommand c) {
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
dacSample=ins->amiga.getSample(c.value); dacSample=ins->amiga.getSample(c.value);
if (ins->type==DIV_INS_AMIGA) { if (ins->type==DIV_INS_AMIGA) {
chan[c.chan].sampleNote=c.value;
c.value=ins->amiga.getFreq(c.value); c.value=ins->amiga.getFreq(c.value);
chan[c.chan].sampleNoteDelta=c.value-chan[c.chan].sampleNote;
}
} else if (chan[c.chan].sampleNote!=DIV_NOTE_NULL) {
dacSample=ins->amiga.getSample(chan[c.chan].sampleNote);
if (ins->type==DIV_INS_AMIGA) {
c.value=ins->amiga.getFreq(chan[c.chan].sampleNote);
} }
} }
if (dacSample<0 || dacSample>=parent->song.sampleLen) { if (dacSample<0 || dacSample>=parent->song.sampleLen) {
@ -535,7 +542,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
int destFreq=(c.chan==4)?(parent->calcBaseFreq(1,1,c.value2,false)):(NOTE_PERIODIC(c.value2)); int destFreq=(c.chan==4)?(parent->calcBaseFreq(1,1,c.value2+chan[c.chan].sampleNoteDelta,false)):(NOTE_PERIODIC(c.value2));
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value; chan[c.chan].baseFreq+=c.value;
@ -636,7 +643,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
case DIV_CMD_LEGATO: case DIV_CMD_LEGATO:
if (c.chan==3) break; if (c.chan==3) break;
if (c.chan==4) { if (c.chan==4) {
chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0)),false); chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value+chan[c.chan].sampleNoteDelta+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0)),false);
} else { } else {
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0))); chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0)));
} }

Some files were not shown because too many files have changed in this diff Show more