From 779afcb97ae836a42181f5fee06cc29a318c82c7 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 14 Oct 2023 08:10:37 -0300 Subject: [PATCH 01/74] WIP: adding ESFM (ESS ES1488/ESS ES1868 etc.) system --- .gitignore | 1 + CMakeLists.txt | 5 + extern/ESFMu/.clangd | 2 + extern/ESFMu/.gitignore | 1 + extern/ESFMu/LICENSE | 504 +++++++++++++ extern/ESFMu/MODIFIED.md | 6 + extern/ESFMu/README.md | 67 ++ extern/ESFMu/esfm.c | 1164 ++++++++++++++++++++++++++++++ extern/ESFMu/esfm.h | 305 ++++++++ extern/ESFMu/esfm_registers.c | 995 +++++++++++++++++++++++++ src/engine/dispatchContainer.cpp | 4 + src/engine/engine.cpp | 6 + src/engine/instrument.cpp | 77 +- src/engine/instrument.h | 110 +++ src/engine/platform/esfm.cpp | 854 ++++++++++++++++++++++ src/engine/platform/esfm.h | 144 ++++ src/engine/song.h | 45 +- src/engine/sysDef.cpp | 12 + src/gui/fmPreview.cpp | 57 ++ src/gui/gui.h | 3 + src/gui/guiConst.cpp | 5 + src/gui/insEdit.cpp | 501 ++++++++----- src/gui/intConst.cpp | 2 + src/gui/intConst.h | 2 + 24 files changed, 4705 insertions(+), 167 deletions(-) create mode 100644 extern/ESFMu/.clangd create mode 100644 extern/ESFMu/.gitignore create mode 100644 extern/ESFMu/LICENSE create mode 100644 extern/ESFMu/MODIFIED.md create mode 100644 extern/ESFMu/README.md create mode 100644 extern/ESFMu/esfm.c create mode 100644 extern/ESFMu/esfm.h create mode 100644 extern/ESFMu/esfm_registers.c create mode 100644 src/engine/platform/esfm.cpp create mode 100644 src/engine/platform/esfm.h diff --git a/.gitignore b/.gitignore index 09314bb24..06812e61e 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ res/docpdf/manual.pdf res/docpdf/.venv res/docpdf/htmldoc/ res/furnace.appdata.xml +compile_commands.json diff --git a/CMakeLists.txt b/CMakeLists.txt index 6278184b5..f7a2a3dd9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required(VERSION 3.0) +set(CMAKE_EXPORT_COMPILE_COMMANDS on) + if (APPLE) set(MACOSX_DEPLOYMENT_TARGET 10.9) endif() @@ -454,6 +456,8 @@ extern/Nuked-PSG/ympsg.c extern/opm/opm.c extern/Nuked-OPLL/opll.c extern/opl/opl3.c +extern/ESFMu/esfm.c +extern/ESFMu/esfm_registers.c src/pch.cpp @@ -660,6 +664,7 @@ src/engine/platform/pv1000.cpp src/engine/platform/k053260.cpp src/engine/platform/ted.cpp src/engine/platform/c140.cpp +src/engine/platform/esfm.cpp src/engine/platform/pcmdac.cpp src/engine/platform/dummy.cpp diff --git a/extern/ESFMu/.clangd b/extern/ESFMu/.clangd new file mode 100644 index 000000000..f6023d41f --- /dev/null +++ b/extern/ESFMu/.clangd @@ -0,0 +1,2 @@ +CompileFlags: + Add: ["-xc", "-Wall", "-Wextra"] diff --git a/extern/ESFMu/.gitignore b/extern/ESFMu/.gitignore new file mode 100644 index 000000000..7cb2b78a0 --- /dev/null +++ b/extern/ESFMu/.gitignore @@ -0,0 +1 @@ +test_scripts/* diff --git a/extern/ESFMu/LICENSE b/extern/ESFMu/LICENSE new file mode 100644 index 000000000..8000a6faa --- /dev/null +++ b/extern/ESFMu/LICENSE @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random + Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/extern/ESFMu/MODIFIED.md b/extern/ESFMu/MODIFIED.md new file mode 100644 index 000000000..78625584c --- /dev/null +++ b/extern/ESFMu/MODIFIED.md @@ -0,0 +1,6 @@ +# Modification disclaimer + +This is a modified version of ESFMu v1.0.1 which implements a function for reading the waveform output of the individual FM channels. The modification was made by Kagamiin~ (original author of ESFMu) herself. + +Kagamiin~ notes: +> In hindsight, I might merge back this functionality into a future version of the core, as it could be be useful for generating oscilloscope views in other tools. diff --git a/extern/ESFMu/README.md b/extern/ESFMu/README.md new file mode 100644 index 000000000..5e04ef6fb --- /dev/null +++ b/extern/ESFMu/README.md @@ -0,0 +1,67 @@ +# ESFMu + +An emulator for the ESS "ESFM" enhanced OPL3 clone, based on Nuke.YKT's **Nuked OPL3** and reverse-engineering efforts from the community. + +## Acknowledgements + +I'd like to thank: + +- **Nuke.YKT** + - Developer of **Nuked OPL3**, which was the basis for **ESFMu**'s code and also a great learning resource on Yamaha FM synthesis for myself. + - Nuke.YKT also gives shoutouts on behalf of **Nuked OPL3** to: + >- MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): + > - Feedback and Rhythm part calculation information. + >- forums.submarine.org.uk(carbon14, opl3): + > - Tremolo and phase generator calculation information. + >- OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): + > - OPL2 ROMs. + >- siliconpr0n.org(John McMaster, digshadow): + > - YMF262 and VRC VII decaps and die shots. +- **rainwarrior** + - For performing the initial research on ESFM drivers and documenting ESS's patent on native mode operator organization. +- **jwt27** + - For kickstarting the ESFM research project and compiling rainwarrior's findings and more in an accessible document ("ESFM Demystified"). +- **pachuco/CatButts** + - For documenting ESS's patent on ESFM's feedback implementation, which was vital in getting **ESFMu**'s sound output to be accurate. +- And everybody who helped out with real hardware testing + +## Usage + +To use **ESFMu**: + +- include the **esfm.h** header file into your source code +- include the **esfm.c** and **esfm_registers.c** files into your build and link process +- declare or allocate a variable of type `esfm_chip` somewhere in your code - this will hold the chip's state +- use the function interface defined in **esfm.h** to interact with the `esfm_chip` structure + +## Function interface + +If you're familiar with **Nuked OPL3**, you'll find many similarities in the function interface provided by **ESFMu**. There are a few things to point out, however: + +### Buffered writes + +Just like **Nuked OPL3**, **ESFMu** offers buffered register writes. However, it offers them in two flavors: "legacy" and fast. + +The fast buffered register writes (`ESFM_write_reg_buffered_fast`) are recommended, since they offer minimal latency which is close to the behavior you'd get with the actual ESS drivers on Windows. + +The "legacy" buffered register writes are only recommended for specific cases, such as programs seeking for a shortcut to emulate the write delays from some sound drivers. + +### Port-level access + +Unlike **Nuked OPL3**, **ESFMu** actually allows port-level access to the ESFM interface. This is relevant because the ESFM port interface is actually modal, meaning that its behavior changes depending on whether the chip is set to emulation (OPL3 compatibility) mode or native (ESFM) mode. + +Using port-level access allows for applications to not need to keep track of whether the chip is in native mode or not, nor to perform the port handling logic on their side. + +Applications that use the register-level access, on the other hand, need to take care to either stick to only one of the operating modes (either native or emulation), or handle the port mapping logic on their own side. + +### Register readback + +ESFM allows for register contents to be read back through its ports, and **ESFMu** implements this functionality, both via dedicated register read functions and via the port read interface. + +Note that in ESFM, register contents can only be read back when the chip is set to native (ESFM) mode, not when the chip is in emulation mode (i.e. OPL3 compatibility mode). + +## Licensing + +**ESFMu** is highly based on **Nuked OPL3**, which is licensed under the GNU Lesser General Public License version 2.1 or later. Therefore, **ESFMu** is licensed under the same license. + +If you'd like to obtain a grant to use **ESFMu** under different terms, you should get in contact with [Nuke.YKT](https://github.com/nukeykt) (author of **Nuked OPL3**) as well as with [Kagamiin~](https://github.com/Kagamiin) (yours truly). diff --git a/extern/ESFMu/esfm.c b/extern/ESFMu/esfm.c new file mode 100644 index 000000000..f1979f8e6 --- /dev/null +++ b/extern/ESFMu/esfm.c @@ -0,0 +1,1164 @@ +/* + * ESFMu: emulator for the ESS "ESFM" enhanced OPL3 clone + * Copyright (C) 2023 Kagamiin~ + * + * This file includes code and data from the Nuked OPL3 project, copyright (C) + * 2013-2023 Nuke.YKT. Its usage, modification and redistribution is allowed + * under the terms of the GNU Lesser General Public License version 2.1 or + * later. + * + * ESFMu is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 + * of the License, or (at your option) any later version. + * + * ESFMu 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ESFMu. If not, see . + */ + +/* + * ESFMu wouldn't have been possible without the hard work and dedication of + * the retro computer hardware research and preservation community. + * + * I'd like to thank: + * - Nuke.YKT + * Developer of Nuked OPL3, which was the basis for ESFMu's code and + * also a great learning resource on Yamaha FM synthesis for myself. + * Nuke.YKT also gives shoutouts on behalf of Nuked OPL3 to: + * - MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): + * Feedback and Rhythm part calculation information. + * - forums.submarine.org.uk(carbon14, opl3): + * Tremolo and phase generator calculation information. + * - OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): + * OPL2 ROMs. + * - siliconpr0n.org(John McMaster, digshadow): + * YMF262 and VRC VII decaps and die shots. + * - rainwarrior + * For performing the initial research on ESFM drivers and documenting + * ESS's patent on native mode operator organization. + * - jwt27 + * For kickstarting the ESFM research project and compiling rainwarrior's + * findings and more in an accessible document ("ESFM Demystified"). + * - pachuco/CatButts + * For documenting ESS's patent on ESFM's feedback implementation, which + * was vital in getting ESFMu's sound output to be accurate. + * - And everybody who helped out with real hardware testing + */ + +#include "esfm.h" +#include +#include +#include +#include +#include + +/* + * Log-scale quarter sine table extracted from OPL3 ROM; taken straight from + * Nuked OPL3 source code. + * TODO: Extract sine table from ESFM die scans... does ESFM even use a sine + * table? Patent documents give a hint to a possible method of generating sine + * waves using some sort of boolean logic wizardry (lol) + */ +static const uint16_t logsinrom[256] = { + 0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471, + 0x443, 0x41a, 0x3f5, 0x3d3, 0x3b5, 0x398, 0x37e, 0x365, + 0x34e, 0x339, 0x324, 0x311, 0x2ff, 0x2ed, 0x2dc, 0x2cd, + 0x2bd, 0x2af, 0x2a0, 0x293, 0x286, 0x279, 0x26d, 0x261, + 0x256, 0x24b, 0x240, 0x236, 0x22c, 0x222, 0x218, 0x20f, + 0x206, 0x1fd, 0x1f5, 0x1ec, 0x1e4, 0x1dc, 0x1d4, 0x1cd, + 0x1c5, 0x1be, 0x1b7, 0x1b0, 0x1a9, 0x1a2, 0x19b, 0x195, + 0x18f, 0x188, 0x182, 0x17c, 0x177, 0x171, 0x16b, 0x166, + 0x160, 0x15b, 0x155, 0x150, 0x14b, 0x146, 0x141, 0x13c, + 0x137, 0x133, 0x12e, 0x129, 0x125, 0x121, 0x11c, 0x118, + 0x114, 0x10f, 0x10b, 0x107, 0x103, 0x0ff, 0x0fb, 0x0f8, + 0x0f4, 0x0f0, 0x0ec, 0x0e9, 0x0e5, 0x0e2, 0x0de, 0x0db, + 0x0d7, 0x0d4, 0x0d1, 0x0cd, 0x0ca, 0x0c7, 0x0c4, 0x0c1, + 0x0be, 0x0bb, 0x0b8, 0x0b5, 0x0b2, 0x0af, 0x0ac, 0x0a9, + 0x0a7, 0x0a4, 0x0a1, 0x09f, 0x09c, 0x099, 0x097, 0x094, + 0x092, 0x08f, 0x08d, 0x08a, 0x088, 0x086, 0x083, 0x081, + 0x07f, 0x07d, 0x07a, 0x078, 0x076, 0x074, 0x072, 0x070, + 0x06e, 0x06c, 0x06a, 0x068, 0x066, 0x064, 0x062, 0x060, + 0x05e, 0x05c, 0x05b, 0x059, 0x057, 0x055, 0x053, 0x052, + 0x050, 0x04e, 0x04d, 0x04b, 0x04a, 0x048, 0x046, 0x045, + 0x043, 0x042, 0x040, 0x03f, 0x03e, 0x03c, 0x03b, 0x039, + 0x038, 0x037, 0x035, 0x034, 0x033, 0x031, 0x030, 0x02f, + 0x02e, 0x02d, 0x02b, 0x02a, 0x029, 0x028, 0x027, 0x026, + 0x025, 0x024, 0x023, 0x022, 0x021, 0x020, 0x01f, 0x01e, + 0x01d, 0x01c, 0x01b, 0x01a, 0x019, 0x018, 0x017, 0x017, + 0x016, 0x015, 0x014, 0x014, 0x013, 0x012, 0x011, 0x011, + 0x010, 0x00f, 0x00f, 0x00e, 0x00d, 0x00d, 0x00c, 0x00c, + 0x00b, 0x00a, 0x00a, 0x009, 0x009, 0x008, 0x008, 0x007, + 0x007, 0x007, 0x006, 0x006, 0x005, 0x005, 0x005, 0x004, + 0x004, 0x004, 0x003, 0x003, 0x003, 0x002, 0x002, 0x002, + 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000 +}; + +/* + * Inverse exponent table extracted from OPL3 ROM; taken straight from + * Nuked OPL3 source code. + * TODO: Verify if ESFM uses an exponent table or if it possibly uses another + * method to skirt around Yamaha's patents? + */ +static const uint16_t exprom[256] = { + 0x7fa, 0x7f5, 0x7ef, 0x7ea, 0x7e4, 0x7df, 0x7da, 0x7d4, + 0x7cf, 0x7c9, 0x7c4, 0x7bf, 0x7b9, 0x7b4, 0x7ae, 0x7a9, + 0x7a4, 0x79f, 0x799, 0x794, 0x78f, 0x78a, 0x784, 0x77f, + 0x77a, 0x775, 0x770, 0x76a, 0x765, 0x760, 0x75b, 0x756, + 0x751, 0x74c, 0x747, 0x742, 0x73d, 0x738, 0x733, 0x72e, + 0x729, 0x724, 0x71f, 0x71a, 0x715, 0x710, 0x70b, 0x706, + 0x702, 0x6fd, 0x6f8, 0x6f3, 0x6ee, 0x6e9, 0x6e5, 0x6e0, + 0x6db, 0x6d6, 0x6d2, 0x6cd, 0x6c8, 0x6c4, 0x6bf, 0x6ba, + 0x6b5, 0x6b1, 0x6ac, 0x6a8, 0x6a3, 0x69e, 0x69a, 0x695, + 0x691, 0x68c, 0x688, 0x683, 0x67f, 0x67a, 0x676, 0x671, + 0x66d, 0x668, 0x664, 0x65f, 0x65b, 0x657, 0x652, 0x64e, + 0x649, 0x645, 0x641, 0x63c, 0x638, 0x634, 0x630, 0x62b, + 0x627, 0x623, 0x61e, 0x61a, 0x616, 0x612, 0x60e, 0x609, + 0x605, 0x601, 0x5fd, 0x5f9, 0x5f5, 0x5f0, 0x5ec, 0x5e8, + 0x5e4, 0x5e0, 0x5dc, 0x5d8, 0x5d4, 0x5d0, 0x5cc, 0x5c8, + 0x5c4, 0x5c0, 0x5bc, 0x5b8, 0x5b4, 0x5b0, 0x5ac, 0x5a8, + 0x5a4, 0x5a0, 0x59c, 0x599, 0x595, 0x591, 0x58d, 0x589, + 0x585, 0x581, 0x57e, 0x57a, 0x576, 0x572, 0x56f, 0x56b, + 0x567, 0x563, 0x560, 0x55c, 0x558, 0x554, 0x551, 0x54d, + 0x549, 0x546, 0x542, 0x53e, 0x53b, 0x537, 0x534, 0x530, + 0x52c, 0x529, 0x525, 0x522, 0x51e, 0x51b, 0x517, 0x514, + 0x510, 0x50c, 0x509, 0x506, 0x502, 0x4ff, 0x4fb, 0x4f8, + 0x4f4, 0x4f1, 0x4ed, 0x4ea, 0x4e7, 0x4e3, 0x4e0, 0x4dc, + 0x4d9, 0x4d6, 0x4d2, 0x4cf, 0x4cc, 0x4c8, 0x4c5, 0x4c2, + 0x4be, 0x4bb, 0x4b8, 0x4b5, 0x4b1, 0x4ae, 0x4ab, 0x4a8, + 0x4a4, 0x4a1, 0x49e, 0x49b, 0x498, 0x494, 0x491, 0x48e, + 0x48b, 0x488, 0x485, 0x482, 0x47e, 0x47b, 0x478, 0x475, + 0x472, 0x46f, 0x46c, 0x469, 0x466, 0x463, 0x460, 0x45d, + 0x45a, 0x457, 0x454, 0x451, 0x44e, 0x44b, 0x448, 0x445, + 0x442, 0x43f, 0x43c, 0x439, 0x436, 0x433, 0x430, 0x42d, + 0x42a, 0x428, 0x425, 0x422, 0x41f, 0x41c, 0x419, 0x416, + 0x414, 0x411, 0x40e, 0x40b, 0x408, 0x406, 0x403, 0x400 +}; + +/* + * Frequency multiplier table multiplied by 2; taken straight from Nuked OPL3 + * source code. + */ +static const uint8_t mt[16] = { + 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30 +}; + +/* + * This is used during the envelope generation to apply KSL to the envelope by + * determining how much to shift right the keyscale attenuation value before + * adding it to the envelope level. + */ +static const uint8_t kslshift[4] = { + 8, 1, 2, 0 +}; + +/* + * This encodes which emulation mode channels are the secondary channel in a + * 4-op channel pair (where the entry is non-negative), and which is the + * corresponding primary channel for that secondary channel. + */ +static const int emu_4op_secondary_to_primary[18] = +{ + -1, -1, -1, 0, 1, 2, -1, -1, -1, + -1, -1, -1, 9, 10, 11, -1, -1, -1 +}; + +/* + * Envelope generator dither table, taken straight from Nuked OPL3 source code. + */ +static const uint8_t eg_incstep[4][4] = { + { 0, 0, 0, 0 }, + { 1, 0, 0, 0 }, + { 1, 0, 1, 0 }, + { 1, 1, 1, 0 } +}; + +typedef int13(*envelope_sinfunc)(uint10 phase, uint10 envelope); + +/* ------------------------------------------------------------------------- */ +static uint12 +ESFM_envelope_calc_exp(uint16 level) +{ + if (level > 0x1fff) + { + level = 0x1fff; + } + return (exprom[level & 0xff] << 1) >> (level >> 8); +} + +/* ------------------------------------------------------------------------- */ +static int13 +ESFM_envelope_calc_sin0(uint10 phase, uint10 envelope) +{ + uint16 out = 0; + int13 neg = 0; + phase &= 0x3ff; + if (phase & 0x200) + { + neg = ~(0); + } + if (phase & 0x100) + { + out = logsinrom[(phase & 0xff) ^ 0xff]; + } + else + { + out = logsinrom[phase & 0xff]; + } + return ESFM_envelope_calc_exp(out + (envelope << 3)) ^ neg; +} + +/* ------------------------------------------------------------------------- */ +static int13 +ESFM_envelope_calc_sin1(uint10 phase, uint10 envelope) +{ + uint16 out = 0; + phase &= 0x3ff; + if (phase & 0x200) + { + out = 0x1000; + } + else if (phase & 0x100) + { + out = logsinrom[(phase & 0xff) ^ 0xff]; + } + else + { + out = logsinrom[phase & 0xff]; + } + return ESFM_envelope_calc_exp(out + (envelope << 3)); +} + +/* ------------------------------------------------------------------------- */ +static int13 +ESFM_envelope_calc_sin2(uint10 phase, uint10 envelope) +{ + uint16 out = 0; + phase &= 0x3ff; + if (phase & 0x100) + { + out = logsinrom[(phase & 0xff) ^ 0xff]; + } + else + { + out = logsinrom[phase & 0xff]; + } + return ESFM_envelope_calc_exp(out + (envelope << 3)); +} + +/* ------------------------------------------------------------------------- */ +static int13 +ESFM_envelope_calc_sin3(uint10 phase, uint10 envelope) +{ + uint16 out = 0; + phase &= 0x3ff; + if (phase & 0x100) + { + out = 0x1000; + } + else + { + out = logsinrom[phase & 0xff]; + } + return ESFM_envelope_calc_exp(out + (envelope << 3)); +} + +/* ------------------------------------------------------------------------- */ +static int13 +ESFM_envelope_calc_sin4(uint10 phase, uint10 envelope) +{ + uint16 out = 0; + int13 neg = 0; + phase &= 0x3ff; + if ((phase & 0x300) == 0x100) + { + neg = ~(0); + } + if (phase & 0x200) + { + out = 0x1000; + } + else if (phase & 0x80) + { + out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; + } + else + { + out = logsinrom[(phase << 1) & 0xff]; + } + return ESFM_envelope_calc_exp(out + (envelope << 3)) ^ neg; +} + +/* ------------------------------------------------------------------------- */ +static int13 +ESFM_envelope_calc_sin5(uint10 phase, uint10 envelope) +{ + uint16 out = 0; + phase &= 0x3ff; + if (phase & 0x200) + { + out = 0x1000; + } + else if (phase & 0x80) + { + out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; + } + else + { + out = logsinrom[(phase << 1) & 0xff]; + } + return ESFM_envelope_calc_exp(out + (envelope << 3)); +} + +/* ------------------------------------------------------------------------- */ +static int13 +ESFM_envelope_calc_sin6(uint10 phase, uint10 envelope) +{ + int13 neg = 0; + phase &= 0x3ff; + if (phase & 0x200) + { + neg = ~(0); + } + return ESFM_envelope_calc_exp(envelope << 3) ^ neg; +} + +/* ------------------------------------------------------------------------- */ +static int13 +ESFM_envelope_calc_sin7(uint10 phase, uint10 envelope) +{ + uint16 out = 0; + int13 neg = 0; + phase &= 0x3ff; + if (phase & 0x200) + { + neg = ~(0); + phase = (phase & 0x1ff) ^ 0x1ff; + } + out = phase << 3; + return ESFM_envelope_calc_exp(out + (envelope << 3)) ^ neg; +} + +/* ------------------------------------------------------------------------- */ +static const envelope_sinfunc envelope_sin[8] = +{ + ESFM_envelope_calc_sin0, + ESFM_envelope_calc_sin1, + ESFM_envelope_calc_sin2, + ESFM_envelope_calc_sin3, + ESFM_envelope_calc_sin4, + ESFM_envelope_calc_sin5, + ESFM_envelope_calc_sin6, + ESFM_envelope_calc_sin7 +}; + +/* ------------------------------------------------------------------------- */ +static void +ESFM_envelope_calc(esfm_slot *slot) +{ + uint8 nonzero; + uint8 rate; + uint5 rate_hi; + uint2 rate_lo; + uint4 reg_rate = 0; + uint4 ks; + uint8 eg_shift, shift; + bool eg_off; + uint9 eg_rout; + int16 eg_inc; + bool reset = 0; + bool key_on; + + key_on = *slot->in.key_on; + if (!slot->chip->native_mode) + { + int pair_primary_idx = emu_4op_secondary_to_primary[slot->channel->channel_idx]; + if (pair_primary_idx >= 0) + { + esfm_channel *pair_primary = &slot->channel->chip->channels[pair_primary_idx]; + if (pair_primary->emu_mode_4op_enable) + { + key_on = *pair_primary->slots[0].in.key_on; + } + } + else if ((slot->channel->channel_idx == 7 || slot->channel->channel_idx == 8) + && slot->slot_idx == 1) + { + key_on = slot->channel->key_on_2; + } + } + + slot->in.eg_output = slot->in.eg_position + (slot->t_level << 2) + + (slot->in.eg_ksl_offset >> kslshift[slot->ksl]); + if (slot->tremolo_en) + { + uint8 tremolo; + if (slot->chip->native_mode) + { + tremolo = slot->channel->chip->tremolo >> ((!slot->tremolo_deep << 1) + 2); + } + else + { + tremolo = slot->channel->chip->tremolo >> ((!slot->chip->emu_tremolo_deep << 1) + 2); + } + slot->in.eg_output += tremolo; + } + if (key_on && slot->in.eg_state == EG_RELEASE) + { + if (!slot->in.eg_delay_run && slot->chip->native_mode) + { + slot->in.eg_delay_run = 1; + slot->in.eg_delay_counter = slot->env_delay ? 0x100 : 0; + } + + if (slot->in.eg_delay_counter == 0 || !slot->chip->native_mode) + { + slot->in.eg_delay_run = 0; + reset = 1; + reg_rate = slot->attack_rate; + } + else + { + if ((slot->chip->global_timer & ((1 << slot->env_delay) - 1)) == 0) + { + slot->in.eg_delay_counter--; + } + reg_rate = slot->release_rate; + } + } + else + { + switch (slot->in.eg_state) + { + case EG_ATTACK: + reg_rate = slot->attack_rate; + break; + case EG_DECAY: + reg_rate = slot->decay_rate; + break; + case EG_SUSTAIN: + if (!slot->env_sustaining) + { + reg_rate = slot->release_rate; + } + break; + case EG_RELEASE: + reg_rate = slot->release_rate; + break; + } + } + slot->in.phase_reset = reset; + ks = slot->in.keyscale >> ((!slot->ksr) << 1); + nonzero = (reg_rate != 0); + rate = ks + (reg_rate << 2); + rate_hi = rate >> 2; + rate_lo = rate & 0x03; + if (rate_hi & 0x10) + { + rate_hi = 0x0f; + } + eg_shift = rate_hi + slot->chip->eg_clocks; + shift = 0; + if (nonzero) + { + if (rate_hi < 12) + { + if (slot->chip->eg_tick) + { + switch (eg_shift) + { + case 12: + shift = 1; + break; + case 13: + shift = (rate_lo >> 1) & 0x01; + break; + case 14: + shift = rate_lo & 0x01; + break; + default: + break; + } + } + } + else + { + shift = (rate_hi & 0x03) + + eg_incstep[rate_lo][slot->chip->global_timer & 0x03]; + if (shift & 0x04) + { + shift = 0x03; + } + if (!shift) + { + shift = slot->chip->eg_tick; + } + } + } + eg_rout = slot->in.eg_position; + eg_inc = 0; + eg_off = 0; + /* Instant attack */ + if (reset && rate_hi == 0x0f) + { + eg_rout = 0x00; + } + /* Envelope off */ + if ((slot->in.eg_position & 0x1f8) == 0x1f8) + { + eg_off = 1; + } + if (slot->in.eg_state != EG_ATTACK && !reset && eg_off) + { + eg_rout = 0x1ff; + } + switch (slot->in.eg_state) + { + case EG_ATTACK: + if (slot->in.eg_position == 0) + { + slot->in.eg_state = EG_DECAY; + } + else if (key_on && shift > 0 && rate_hi != 0x0f) + { + eg_inc = ~slot->in.eg_position >> (4 - shift); + } + break; + case EG_DECAY: + if ((slot->in.eg_position >> 4) == slot->sustain_lvl) + { + slot->in.eg_state = EG_SUSTAIN; + } + else if (!eg_off && !reset && shift > 0) + { + eg_inc = 1 << (shift - 1); + } + break; + case EG_SUSTAIN: + case EG_RELEASE: + if (!eg_off && !reset && shift > 0) + { + eg_inc = 1 << (shift - 1); + } + break; + } + slot->in.eg_position = (eg_rout + eg_inc) & 0x1ff; + /* Key off */ + if (reset) + { + slot->in.eg_state = EG_ATTACK; + } + if (!key_on) + { + slot->in.eg_state = EG_RELEASE; + slot->in.eg_delay_run = 0; + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_phase_generate(esfm_slot *slot) +{ + esfm_chip *chip; + uint10 f_num; + uint32 basefreq; + bool rm_xor, n_bit; + uint23 noise; + uint10 phase; + + chip = slot->chip; + f_num = slot->f_num; + if (slot->vibrato_en) + { + int8_t range; + uint8_t vibpos; + + range = (f_num >> 7) & 7; + vibpos = chip->vibrato_pos; + + if (!(vibpos & 3)) + { + range = 0; + } + else if (vibpos & 1) + { + range >>= 1; + } + range >>= !slot->vibrato_deep; + + if (vibpos & 4) + { + range = -range; + } + f_num += range; + } + basefreq = (f_num << slot->block) >> 1; + phase = (uint10)(slot->in.phase_acc >> 9); + if (slot->in.phase_reset) + { + slot->in.phase_acc = 0; + } + slot->in.phase_acc += (basefreq * mt[slot->mult]) >> 1; + slot->in.phase_acc &= (1 << 19) - 1; + slot->in.phase_out = phase; + /* Noise mode (rhythm) sounds */ + noise = chip->lfsr; + if (slot->slot_idx == 3 && slot->rhy_noise) + { + esfm_slot *prev_slot = &slot->channel->slots[2]; + + chip->rm_hh_bit2 = (phase >> 2) & 1; + chip->rm_hh_bit3 = (phase >> 3) & 1; + chip->rm_hh_bit7 = (phase >> 7) & 1; + chip->rm_hh_bit8 = (phase >> 8) & 1; + + chip->rm_tc_bit3 = (prev_slot->in.phase_out >> 3) & 1; + chip->rm_tc_bit5 = (prev_slot->in.phase_out >> 5) & 1; + + rm_xor = (chip->rm_hh_bit2 ^ chip->rm_hh_bit7) + | (chip->rm_hh_bit3 ^ chip->rm_tc_bit5) + | (chip->rm_tc_bit3 ^ chip->rm_tc_bit5); + + switch(slot->rhy_noise) + { + case 1: + // SD + slot->in.phase_out = (chip->rm_hh_bit8 << 9) + | ((chip->rm_hh_bit8 ^ (noise & 1)) << 8); + break; + case 2: + // HH + slot->in.phase_out = rm_xor << 9; + if (rm_xor ^ (noise & 1)) + { + slot->in.phase_out |= 0xd0; + } + else + { + slot->in.phase_out |= 0x34; + } + break; + case 3: + // TC + slot->in.phase_out = (rm_xor << 9) | 0x80; + break; + } + } + + n_bit = ((noise >> 14) ^ noise) & 0x01; + chip->lfsr = (noise >> 1) | (n_bit << 22); +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_phase_generate_emu(esfm_slot *slot) +{ + esfm_chip *chip; + uint3 block; + uint10 f_num; + uint32 basefreq; + bool rm_xor, n_bit; + uint23 noise; + uint10 phase; + int pair_primary_idx; + + chip = slot->chip; + block = slot->channel->slots[0].block; + f_num = slot->channel->slots[0].f_num; + + pair_primary_idx = emu_4op_secondary_to_primary[slot->channel->channel_idx]; + if (pair_primary_idx >= 0) + { + esfm_channel *pair_primary = &slot->channel->chip->channels[pair_primary_idx]; + if (pair_primary->emu_mode_4op_enable) + { + block = pair_primary->slots[0].block; + f_num = pair_primary->slots[0].f_num; + } + } + + if (slot->vibrato_en) + { + int8_t range; + uint8_t vibpos; + + range = (f_num >> 7) & 7; + vibpos = chip->vibrato_pos; + + if (!(vibpos & 3)) + { + range = 0; + } + else if (vibpos & 1) + { + range >>= 1; + } + range >>= !chip->emu_vibrato_deep; + + if (vibpos & 4) + { + range = -range; + } + f_num += range; + } + basefreq = (f_num << block) >> 1; + phase = (uint10)(slot->in.phase_acc >> 9); + if (slot->in.phase_reset) + { + slot->in.phase_acc = 0; + } + slot->in.phase_acc += (basefreq * mt[slot->mult]) >> 1; + slot->in.phase_acc &= (1 << 19) - 1; + slot->in.phase_out = phase; + + /* Noise mode (rhythm) sounds */ + noise = chip->lfsr; + // HH + if (slot->channel->channel_idx == 7 && slot->slot_idx == 0) + { + chip->rm_hh_bit2 = (phase >> 2) & 1; + chip->rm_hh_bit3 = (phase >> 3) & 1; + chip->rm_hh_bit7 = (phase >> 7) & 1; + chip->rm_hh_bit8 = (phase >> 8) & 1; + } + // TC + if (slot->channel->channel_idx == 8 && slot->slot_idx == 1) + { + chip->rm_tc_bit3 = (phase >> 3) & 1; + chip->rm_tc_bit5 = (phase >> 5) & 1; + } + if (chip->emu_rhy_mode_flags & 0x20) + { + rm_xor = (chip->rm_hh_bit2 ^ chip->rm_hh_bit7) + | (chip->rm_hh_bit3 ^ chip->rm_tc_bit5) + | (chip->rm_tc_bit3 ^ chip->rm_tc_bit5); + if (slot->channel->channel_idx == 7) + { + if (slot->slot_idx == 0) { + // HH + slot->in.phase_out = rm_xor << 9; + if (rm_xor ^ (noise & 1)) + { + slot->in.phase_out |= 0xd0; + } + else + { + slot->in.phase_out |= 0x34; + } + } + else if (slot->slot_idx == 1) + { + // SD + slot->in.phase_out = (chip->rm_hh_bit8 << 9) + | ((chip->rm_hh_bit8 ^ (noise & 1)) << 8); + } + } + else if (slot->channel->channel_idx == 8 && slot->slot_idx == 1) + { + // TC + slot->in.phase_out = (rm_xor << 9) | 0x80; + } + } + + n_bit = ((noise >> 14) ^ noise) & 0x01; + chip->lfsr = (noise >> 1) | (n_bit << 22); +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_slot_generate(esfm_slot *slot) +{ + envelope_sinfunc wavegen = envelope_sin[slot->waveform]; + int16 phase = slot->in.phase_out; + if (slot->mod_in_level) + { + phase += *slot->in.mod_input >> (7 - slot->mod_in_level); + } + slot->in.output = wavegen((uint10)(phase & 0x3ff), slot->in.eg_output); + if (slot->output_level) + { + int13 output_value = slot->in.output >> (7 - slot->output_level); + slot->channel->output[0] += output_value & slot->out_enable[0]; + slot->channel->output[1] += output_value & slot->out_enable[1]; + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_slot_generate_emu(esfm_slot *slot) +{ + esfm_chip *chip = slot->chip; + envelope_sinfunc wavegen = envelope_sin[ + slot->waveform & (chip->emu_newmode != 0 ? 0x07 : 0x03)]; + bool rhythm_slot_double_volume = (slot->chip->emu_rhy_mode_flags & 0x20) != 0 + && slot->channel->channel_idx >= 6 && slot->channel->channel_idx < 9; + int16 phase = slot->in.phase_out; + int14 output_value; + + phase += *slot->in.mod_input & slot->in.emu_mod_enable; + slot->in.output = wavegen((uint10)(phase & 0x3ff), slot->in.eg_output); + output_value = (slot->in.output & slot->in.emu_output_enable) << rhythm_slot_double_volume; + if (chip->emu_newmode) + { + slot->channel->output[0] += output_value & slot->channel->slots[0].out_enable[0]; + slot->channel->output[1] += output_value & slot->channel->slots[0].out_enable[1]; + } + else + { + slot->channel->output[0] += output_value; + slot->channel->output[1] += output_value; + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_slot_calc_feedback(esfm_slot *slot) +{ + esfm_chip *chip = slot->chip; + uint32 basefreq, phase_offset; + uint3 block; + uint10 f_num; + int13 in1 = 0, in2 = 0, wave_out; + int16 phase, phase_feedback; + uint19 regressed_phase; + int iter_counter; + envelope_sinfunc wavegen; + + if (slot->mod_in_level) + { + if (chip->native_mode) + { + wavegen = envelope_sin[slot->waveform]; + } + else + { + wavegen = envelope_sin[slot->waveform & (0x03 | (0x02 << (chip->emu_newmode != 0)))]; + } + f_num = slot->f_num; + block = slot->block; + basefreq = (f_num << block) >> 1; + phase_offset = (basefreq * mt[slot->mult]) >> 1; + + for (iter_counter = 28; iter_counter >= 0; iter_counter--) + { + regressed_phase = (uint19)((uint32)slot->in.phase_acc - iter_counter * phase_offset) & ((1 << 19) - 1); + phase = (int16)(regressed_phase >> 9); + phase_feedback = (in1 + in2) >> 2; + phase += phase_feedback >> (7 - slot->mod_in_level); + wave_out = wavegen((uint10)(phase & 0x3ff), slot->in.eg_output); + in2 = in1; + in1 = wave_out; + } + + // TODO: Figure out - is this how the ESFM chip does it, like the + // patent literally says? (it's really hacky...) + // slot->in.output = wave_out; + + // This would be the more canonical way to do it, reusing the rest of + // the synthesis pipeline to finish the calculation: + if (chip->native_mode) + { + slot->in.feedback_buf = phase_feedback; + } + else + { + slot->in.feedback_buf = phase_feedback >> (7 - slot->mod_in_level); + } + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_process_channel(esfm_channel *channel) +{ + int slot_idx; + channel->output[0] = channel->output[1] = 0; + for (slot_idx = 0; slot_idx < 4; slot_idx++) + { + esfm_slot *slot = &channel->slots[slot_idx]; + ESFM_envelope_calc(slot); + ESFM_phase_generate(slot); + if(slot_idx > 0) + { + ESFM_slot_generate(slot); + } + } + // ESFM feedback calculation takes a large number of clock cycles, so + // defer slot 0 generation to the end + // TODO: verify this behavior on real hardware + ESFM_slot_calc_feedback(&channel->slots[0]); + ESFM_slot_generate(&channel->slots[0]); +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_process_channel_emu(esfm_channel *channel) +{ + int slot_idx; + channel->output[0] = channel->output[1] = 0; + for (slot_idx = 0; slot_idx < 2; slot_idx++) + { + esfm_slot *slot = &channel->slots[slot_idx]; + ESFM_envelope_calc(slot); + ESFM_phase_generate_emu(slot); + if(slot_idx > 0) + { + ESFM_slot_generate_emu(slot); + } + } + // ESFM feedback calculation takes a large number of clock cycles, so + // defer slot 0 generation to the end + // TODO: verify this behavior on real hardware + if (channel->slots[0].in.mod_input == &channel->slots[0].in.feedback_buf) + { + ESFM_slot_calc_feedback(&channel->slots[0]); + } + ESFM_slot_generate_emu(&channel->slots[0]); +} + +/* ------------------------------------------------------------------------- */ +static int16_t +ESFM_clip_sample(int32 sample) +{ + // TODO: Supposedly, the real ESFM chip actually overflows rather than + // clipping. Verify that. + if (sample > 32767) + { + sample = 32767; + } + else if (sample < -32768) + { + sample = -32768; + } + return (int16_t)sample; +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_update_timers(esfm_chip *chip) +{ + // Tremolo + if ((chip->global_timer & 0x3f) == 0x3f) + { + chip->tremolo_pos = (chip->tremolo_pos + 1) % 210; + if (chip->tremolo_pos < 105) + { + chip->tremolo = chip->tremolo_pos; + } + else + { + chip->tremolo = (210 - chip->tremolo_pos); + } + } + + // Vibrato + if ((chip->global_timer & 0x3ff) == 0x3ff) + { + chip->vibrato_pos = (chip->vibrato_pos + 1) & 0x07; + } + + chip->global_timer = (chip->global_timer + 1) & 0x3ff; + + // Envelope generator dither clocks + chip->eg_clocks = 0; + if (chip->eg_timer) + { + uint8 shift = 0; + while (shift < 36 && ((chip->eg_timer >> shift) & 1) == 0) + { + shift++; + } + + if (shift <= 12) + { + chip->eg_clocks = shift + 1; + } + } + + if (chip->eg_tick || chip->eg_timer_overflow) + { + if (chip->eg_timer == (1llu << 36) - 1) + { + chip->eg_timer = 0; + chip->eg_timer_overflow = 1; + } + else + { + chip->eg_timer++; + chip->eg_timer_overflow = 0; + } + } + + chip->eg_tick ^= 1; +} + +#define KEY_ON_REGS_START (18 * 4 * 8) +/* ------------------------------------------------------------------------- */ +int +ESFM_reg_write_chan_idx(esfm_chip *chip, uint16_t reg) +{ + int which_reg = -1; + if (chip->native_mode) + { + bool is_key_on_reg = reg >= KEY_ON_REGS_START && reg < (KEY_ON_REGS_START + 20); + if (is_key_on_reg) + { + which_reg = reg - KEY_ON_REGS_START; + } + } + else + { + uint8_t reg_low = reg & 0xff; + bool high = reg & 0x100; + bool is_key_on_reg = reg_low >= 0xb0 && reg_low < 0xb9; + if (is_key_on_reg) + { + which_reg = (reg_low & 0x0f) + high * 9; + } + } + + return which_reg; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_update_write_buffer(esfm_chip *chip) +{ + esfm_write_buf *write_buf; + bool note_off_written[20]; + bool bassdrum_written = false; + int i; + for (i = 0; i < 20; i++) + { + note_off_written[i] = false; + } + while((write_buf = &chip->write_buf[chip->write_buf_start]), + write_buf->valid && write_buf->timestamp <= chip->write_buf_timestamp) + { + int is_which_note_on_reg = + ESFM_reg_write_chan_idx(chip, write_buf->address); + if (is_which_note_on_reg >= 0) + { + if ((chip->native_mode && (write_buf->data & 0x01) == 0) + || (!chip->native_mode && (write_buf->data & 0x20) == 0) + ) + { + // this is a note off command; note down that we got note off for this channel + note_off_written[is_which_note_on_reg] = true; + } + else + { + // this is a note on command; have we gotten a note off for this channel in this cycle? + if (note_off_written[is_which_note_on_reg]) + { + // we have a conflict; let the note off be processed first and defer the + // rest of the buffer to the next cycle + break; + } + } + } + if ((chip->native_mode && write_buf->address == 0x4bd) + || (!chip->native_mode && (write_buf->address & 0xff) == 0xbd) + ) + { + // bassdrum register write (rhythm mode note-on/off control) + // have we already written to the bassdrum register in this cycle + if (bassdrum_written) { + // we have a conflict + break; + } + bassdrum_written = true; + } + + write_buf->valid = 0; + ESFM_write_reg(chip, write_buf->address, write_buf->data); + chip->write_buf_start = (chip->write_buf_start + 1) % ESFM_WRITEBUF_SIZE; + } + + chip->write_buf_timestamp++; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_generate(esfm_chip *chip, int16_t *buf) +{ + int channel_idx; + + chip->output_accm[0] = chip->output_accm[1] = 0; + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + esfm_channel *channel = &chip->channels[channel_idx]; + if (chip->native_mode) + { + ESFM_process_channel(channel); + } + else + { + ESFM_process_channel_emu(channel); + } + + chip->output_accm[0] += channel->output[0]; + chip->output_accm[1] += channel->output[1]; + } + + buf[0] = ESFM_clip_sample(chip->output_accm[0]); + buf[1] = ESFM_clip_sample(chip->output_accm[1]); + + ESFM_update_timers(chip); + ESFM_update_write_buffer(chip); +} + +/* ------------------------------------------------------------------------- */ +int16_t +ESFM_get_channel_output_native(esfm_chip *chip, int channel_idx) +{ + int16_t result; + int32_t temp_mix = 0; + int i; + + if (channel_idx < 0 || channel_idx >= 18) + { + return 0; + } + + for (i = 0; i < 4; i++) + { + esfm_slot *slot = &chip->channels[channel_idx].slots[i]; + + if (slot->output_level) + { + int13 output_value = slot->in.output >> (7 - slot->output_level); + temp_mix += output_value & slot->out_enable[0]; + temp_mix += output_value & slot->out_enable[1]; + } + } + + if (temp_mix > 32767) + { + temp_mix = 32767; + } + else if (temp_mix < -32768) + { + temp_mix = -32768; + } + result = temp_mix; + return result; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_generate_stream(esfm_chip *chip, int16_t *sndptr, uint32_t num_samples) +{ + uint32_t i; + + for (i = 0; i < num_samples; i++) + { + ESFM_generate(chip, sndptr); + sndptr += 2; + } +} diff --git a/extern/ESFMu/esfm.h b/extern/ESFMu/esfm.h new file mode 100644 index 000000000..a37300ca0 --- /dev/null +++ b/extern/ESFMu/esfm.h @@ -0,0 +1,305 @@ +/* + * ESFMu: emulator for the ESS "ESFM" enhanced OPL3 clone + * Copyright (C) 2023 Kagamiin~ + * + * ESFMu is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 + * of the License, or (at your option) any later version. + * + * ESFMu 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ESFMu. If not, see . + */ + +/* + * ESFMu wouldn't have been possible without the hard work and dedication of + * the retro computer hardware research and preservation community. + * + * I'd like to thank: + * - Nuke.YKT + * Developer of Nuked OPL3, which was the basis for ESFMu's code and + * also a great learning resource on Yamaha FM synthesis for myself. + * Nuke.YKT also gives shoutouts on behalf of Nuked OPL3 to: + * - MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): + * Feedback and Rhythm part calculation information. + * - forums.submarine.org.uk(carbon14, opl3): + * Tremolo and phase generator calculation information. + * - OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): + * OPL2 ROMs. + * - siliconpr0n.org(John McMaster, digshadow): + * YMF262 and VRC VII decaps and die shots. + * - rainwarrior + * For performing the initial research on ESFM drivers and documenting + * ESS's patent on native mode operator organization. + * - jwt27 + * For kickstarting the ESFM research project and compiling rainwarrior's + * findings and more in an accessible document ("ESFM Demystified"). + * - pachuco/CatButts + * For documenting ESS's patent on ESFM's feedback implementation, which + * was vital in getting ESFMu's sound output to be accurate. + * - And everybody who helped out with real hardware testing + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _esfm_slot esfm_slot; +typedef struct _esfm_slot_internal esfm_slot_internal; +typedef struct _esfm_channel esfm_channel; +typedef struct _esfm_chip esfm_chip; + + +void ESFM_init (esfm_chip *chip); +void ESFM_write_reg (esfm_chip *chip, uint16_t address, uint8_t data); +void ESFM_write_reg_buffered (esfm_chip *chip, uint16_t address, uint8_t data); +void ESFM_write_reg_buffered_fast (esfm_chip *chip, uint16_t address, uint8_t data); +void ESFM_write_port (esfm_chip *chip, uint8_t offset, uint8_t data); +uint8_t ESFM_readback_reg (esfm_chip *chip, uint16_t address); +uint8_t ESFM_read_port (esfm_chip *chip, uint8_t offset); +void ESFM_generate(esfm_chip *chip, int16_t *buf); +void ESFM_generate_stream(esfm_chip *chip, int16_t *sndptr, uint32_t num_samples); +// Modification by Kagamiin~: +int16_t ESFM_get_channel_output_native(esfm_chip *chip, int channel_idx); + + +// These are fake types just for syntax sugar. +// Beware of their underlying types when reading/writing to them. +#ifndef __NO_ESFM_FAST_TYPES +#ifndef __ESFM_FAST_TYPES +#define __ESFM_FAST_TYPES +#endif +#endif + +#ifdef __ESFM_FAST_TYPES + +typedef uint_fast8_t flag; +typedef uint_fast8_t uint2; +typedef uint_fast8_t uint3; +typedef uint_fast8_t uint4; +typedef uint_fast8_t uint5; +typedef uint_fast8_t uint6; +typedef uint_fast8_t uint8; +typedef uint_fast16_t uint9; +typedef uint_fast16_t uint10; +typedef uint_fast16_t uint11; +typedef uint_fast16_t uint12; +typedef uint_fast16_t uint16; +typedef uint_fast32_t uint19; +typedef uint_fast32_t uint23; +typedef uint_fast32_t uint32; +typedef uint_fast64_t uint36; + +typedef int_fast16_t int13; +typedef int_fast16_t int14; +typedef int_fast16_t int16; +typedef int_fast32_t int32; + +#else +typedef uint8_t flag; +typedef uint8_t uint2; +typedef uint8_t uint3; +typedef uint8_t uint4; +typedef uint8_t uint5; +typedef uint8_t uint6; +typedef uint8_t uint8; +typedef uint16_t uint9; +typedef uint16_t uint10; +typedef uint16_t uint11; +typedef uint16_t uint12; +typedef uint16_t uint16; +typedef uint32_t uint19; +typedef uint32_t uint23; +typedef uint32_t uint32; +typedef uint64_t uint36; + +typedef int16_t int13; +typedef int16_t int14; +typedef int16_t int16; +typedef int32_t int32; + +#endif + +enum eg_states +{ + EG_ATTACK, + EG_DECAY, + EG_SUSTAIN, + EG_RELEASE +}; + + +typedef struct _esfm_write_buf +{ + uint64_t timestamp; + uint16_t address; + uint8_t data; + flag valid; + +} esfm_write_buf; + +typedef struct _emu_slot_channel_mapping +{ + int channel_idx; + int slot_idx; + +} emu_slot_channel_mapping; + +typedef struct _esfm_slot_internal +{ + uint9 eg_position; + uint9 eg_ksl_offset; + uint10 eg_output; + + uint4 keyscale; + + int13 output; + int13 emu_output_enable; + int13 emu_mod_enable; + int13 feedback_buf; + int13 *mod_input; + + uint19 phase_acc; + uint10 phase_out; + flag phase_reset; + flag *key_on; + + uint2 eg_state; + flag eg_delay_run; + uint9 eg_delay_counter; + +} esfm_slot_internal; + +struct _esfm_slot +{ + // Metadata + esfm_channel *channel; + esfm_chip *chip; + uint2 slot_idx; + + // Register data + int13 out_enable[2]; + uint10 f_num; + uint3 block; + uint3 output_level; + // a.k.a. feedback level in emu mode + uint3 mod_in_level; + + uint6 t_level; + uint4 mult; + uint3 waveform; + // Only for 4th slot + uint2 rhy_noise; + + uint4 attack_rate; + uint4 decay_rate; + uint4 sustain_lvl; + uint4 release_rate; + + flag tremolo_en; + flag tremolo_deep; + flag vibrato_en; + flag vibrato_deep; + flag emu_connection_typ; + flag env_sustaining; + flag ksr; + uint2 ksl; + uint3 env_delay; + // overlaps with env_delay bit 0 + // TODO: check if emu mode only uses this, or if it actually overwrites the channel field used by native mode + flag emu_key_on; + + // Internal state + esfm_slot_internal in; +}; + +struct _esfm_channel +{ + esfm_chip *chip; + esfm_slot slots[4]; + uint5 channel_idx; + int16 output[2]; + flag key_on; + flag emu_mode_4op_enable; + // Only for 17th and 18th channels + flag key_on_2; + flag emu_mode_4op_enable_2; +}; + +#define ESFM_WRITEBUF_SIZE 1024 +#define ESFM_WRITEBUF_DELAY 2 + +struct _esfm_chip +{ + esfm_channel channels[18]; + int32 output_accm[2]; + uint_fast16_t addr_latch; + + flag emu_wavesel_enable; + flag emu_newmode; + flag native_mode; + + flag keyscale_mode; + + // Global state + uint36 eg_timer; + uint10 global_timer; + uint8 eg_clocks; + flag eg_tick; + flag eg_timer_overflow; + uint8 tremolo; + uint8 tremolo_pos; + uint8 vibrato_pos; + uint23 lfsr; + + flag rm_hh_bit2; + flag rm_hh_bit3; + flag rm_hh_bit7; + flag rm_hh_bit8; + flag rm_tc_bit3; + flag rm_tc_bit5; + + // 0xbd register in emulation mode, exposed in 0x4bd in native mode + // ("bass drum" register) + uint8 emu_rhy_mode_flags; + + flag emu_vibrato_deep; + flag emu_tremolo_deep; + + uint8 timer_reload[2]; + uint8 timer_counter[2]; + flag timer_enable[2]; + flag timer_mask[2]; + flag timer_overflow[2]; + flag irq_bit; + + // Halts the envelope generators from advancing. + flag test_bit_eg_halt; + /* + * Activates some sort of waveform test mode that amplifies the output volume greatly + * and continuously shifts the waveform table downwards, possibly also outputting the + * waveform's derivative? (it's so weird!) + */ + flag test_bit_distort; + // Appears to attenuate the output by about 3 dB. + flag test_bit_attenuate; + // Resets all phase generators and holds them in the reset state while this bit is set. + flag test_bit_phase_stop_reset; + + esfm_write_buf write_buf[ESFM_WRITEBUF_SIZE]; + size_t write_buf_start; + size_t write_buf_end; + uint64_t write_buf_timestamp; +}; + +#ifdef __cplusplus +} +#endif diff --git a/extern/ESFMu/esfm_registers.c b/extern/ESFMu/esfm_registers.c new file mode 100644 index 000000000..789c68ea7 --- /dev/null +++ b/extern/ESFMu/esfm_registers.c @@ -0,0 +1,995 @@ +/* + * ESFMu: emulator for the ESS "ESFM" enhanced OPL3 clone + * Copyright (C) 2023 Kagamiin~ + * + * This file includes code and data from the Nuked OPL3 project, copyright (C) + * 2013-2023 Nuke.YKT. Its usage, modification and redistribution is allowed + * under the terms of the GNU Lesser General Public License version 2.1 or + * later. + * + * ESFMu is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 + * of the License, or (at your option) any later version. + * + * ESFMu 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ESFMu. If not, see . + */ + +/* + * ESFMu wouldn't have been possible without the hard work and dedication of + * the retro computer hardware research and preservation community. + * + * I'd like to thank: + * - Nuke.YKT + * Developer of Nuked OPL3, which was the basis for ESFMu's code and + * also a great learning resource on Yamaha FM synthesis for myself. + * Nuke.YKT also gives shoutouts on behalf of Nuked OPL3 to: + * - MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): + * Feedback and Rhythm part calculation information. + * - forums.submarine.org.uk(carbon14, opl3): + * Tremolo and phase generator calculation information. + * - OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): + * OPL2 ROMs. + * - siliconpr0n.org(John McMaster, digshadow): + * YMF262 and VRC VII decaps and die shots. + * - rainwarrior + * For performing the initial research on ESFM drivers and documenting + * ESS's patent on native mode operator organization. + * - jwt27 + * For kickstarting the ESFM research project and compiling rainwarrior's + * findings and more in an accessible document ("ESFM Demystified"). + * - pachuco/CatButts + * For documenting ESS's patent on ESFM's feedback implementation, which + * was vital in getting ESFMu's sound output to be accurate. + * - And everybody who helped out with real hardware testing + */ + +#include "esfm.h" +#include +#include +#include +#include + + +/* + * Table of KSL values extracted from OPL3 ROM; taken straight from Nuked OPL3 + * source code. + * TODO: Check if ESFM uses the same KSL values. + */ + +static const int16 kslrom[16] = { + 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64 +}; + +/* + * This maps the low 5 bits of emulation mode address to an emulation mode + * slot; taken straight from Nuked OPL3. Used for decoding certain emulation + * mode address ranges. + */ +static const int8_t ad_slot[0x20] = { + 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1, + 12, 13, 14, 15, 16, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +/* + * This maps an emulation mode slot index to a tuple representing the + * corresponding native mode channel and slot. + */ +static const emu_slot_channel_mapping emu_slot_map[36] = +{ + { 0, 0}, { 1, 0}, { 2, 0}, { 0, 1}, { 1, 1}, { 2, 1}, + { 3, 0}, { 4, 0}, { 5, 0}, { 3, 1}, { 4, 1}, { 5, 1}, + { 6, 0}, { 7, 0}, { 8, 0}, { 6, 1}, { 7, 1}, { 8, 1}, + { 9, 0}, {10, 0}, {11, 0}, { 9, 1}, {10, 1}, {11, 1}, + {12, 0}, {13, 0}, {14, 0}, {12, 1}, {13, 1}, {14, 1}, + {15, 0}, {16, 0}, {17, 0}, {15, 1}, {16, 1}, {17, 1} +}; + +/* + * This encodes which emulation mode channels are the secondary channel in a + * 4-op channel pair (where the entry is non-negative), and which is the + * corresponding primary channel for that secondary channel. + */ +static const int emu_4op_secondary_to_primary[18] = +{ + -1, -1, -1, 0, 1, 2, -1, -1, -1, + -1, -1, -1, 9, 10, 11, -1, -1, -1 +}; + +/* + * This encodes the operator outputs to be enabled or disabled for + * each 4-op algorithm in emulation mode. + * Indices: FM+FM, FM+AM, AM+FM, AM+AM (lower channel MSB, upper channel LSB) + * Values: enable OP1, OP2, OP3, OP4 + */ +static const bool emu_4op_alg_output_enable[4][4] = +{ + {0, 0, 0, 1}, + {0, 1, 0, 1}, + {1, 0, 0, 1}, + {1, 0, 1, 1} +}; + +/* + * This encodes the operator interconnections to be enabled or disabled for + * each 4-op algorithm in emulation mode. + * Indices: FM+FM, FM+AM, AM+FM, AM+AM (lower channel MSB, upper channel LSB) + * Values: enable OP1FB, OP1->2, OP2->3, OP3->4 + */ +static const bool emu_4op_alg_mod_enable[4][4] = +{ + {1, 1, 1, 1}, + {1, 1, 0, 1}, + {1, 0, 1, 1}, + {1, 0, 1, 0} +}; + + +/* ------------------------------------------------------------------------- */ +static void +ESFM_emu_rearrange_connections(esfm_channel *channel) +{ + int secondary_to_primary; + + secondary_to_primary = emu_4op_secondary_to_primary[channel->channel_idx]; + if (secondary_to_primary >= 0) + { + esfm_channel *pair_primary = &channel->chip->channels[secondary_to_primary]; + if (pair_primary->emu_mode_4op_enable) + { + // always work from primary channel in pair when dealing with 4-op + channel = pair_primary; + } + } + + if (channel->emu_mode_4op_enable && (channel->channel_idx % 9) < 3 && channel->chip->emu_newmode) + { + esfm_channel *secondary = &channel->chip->channels[channel->channel_idx + 3]; + uint2 algorithm = ((channel->slots[0].emu_connection_typ != 0) << 1) + | (secondary->slots[0].emu_connection_typ != 0); + int i; + + secondary->slots[0].in.mod_input = &channel->slots[1].in.output; + + for (i = 0; i < 2; i++) + { + channel->slots[i].in.emu_mod_enable = + emu_4op_alg_mod_enable[algorithm][i] ? ~((int13) 0) : 0; + channel->slots[i].in.emu_output_enable = + emu_4op_alg_output_enable[algorithm][i] ? ~((int13) 0) : 0; + + secondary->slots[i].in.emu_mod_enable = + emu_4op_alg_mod_enable[algorithm][i + 2] ? ~((int13) 0) : 0; + secondary->slots[i].in.emu_output_enable = + emu_4op_alg_output_enable[algorithm][i + 2] ? ~((int13) 0) : 0; + } + } + else if ((channel->chip->emu_rhy_mode_flags & 0x20) != 0 + && (channel->channel_idx == 7 || channel->channel_idx == 8)) + { + channel->slots[0].in.emu_mod_enable = 0; + channel->slots[1].in.emu_mod_enable = 0; + channel->slots[0].in.emu_output_enable = ~((int13) 0); + channel->slots[1].in.emu_output_enable = ~((int13) 0); + } + else + { + channel->slots[0].in.mod_input = &channel->slots[0].in.feedback_buf; + + channel->slots[0].in.emu_mod_enable = ~((int13) 0); + channel->slots[0].in.emu_output_enable = + (channel->slots[0].emu_connection_typ != 0) ? ~((int13) 0) : 0; + channel->slots[1].in.emu_output_enable = ~((int13) 0); + channel->slots[1].in.emu_mod_enable = + (channel->slots[0].emu_connection_typ != 0) ? 0 : ~((int13) 0); + } +} + + +/* ------------------------------------------------------------------------- */ +static void +ESFM_emu_to_native_switch(esfm_chip *chip) +{ + size_t channel_idx, slot_idx; + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + for (slot_idx = 0; slot_idx < 4; slot_idx++) + { + esfm_channel *channel = &chip->channels[channel_idx]; + esfm_slot *slot = &channel->slots[slot_idx]; + + if (slot_idx == 0) + { + slot->in.mod_input = &slot->in.feedback_buf; + } + else + { + esfm_slot *prev_slot = &channel->slots[slot_idx - 1]; + slot->in.mod_input = &prev_slot->in.output; + } + } + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_native_to_emu_switch(esfm_chip *chip) +{ + size_t channel_idx; + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + ESFM_emu_rearrange_connections(&chip->channels[channel_idx]); + } +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_slot_update_keyscale(esfm_slot *slot) +{ + if (slot->slot_idx > 0 && !slot->chip->native_mode) + { + return; + } + + int16 ksl = (kslrom[slot->f_num >> 6] << 2) - ((0x08 - slot->block) << 5); + if (ksl < 0) + { + ksl = 0; + } + slot->in.eg_ksl_offset = ksl; + slot->in.keyscale = (slot->block << 1) + | ((slot->f_num >> (8 + !slot->chip->keyscale_mode)) & 0x01); +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_emu_channel_update_keyscale(esfm_channel *channel) +{ + int secondary_to_primary; + + secondary_to_primary = emu_4op_secondary_to_primary[channel->channel_idx]; + if (secondary_to_primary >= 0) + { + esfm_channel *pair_primary = &channel->chip->channels[secondary_to_primary]; + if (pair_primary->emu_mode_4op_enable) + { + // always work from primary channel in pair when dealing with 4-op + channel = pair_primary; + } + } + + ESFM_slot_update_keyscale(&channel->slots[0]); + channel->slots[1].in.eg_ksl_offset = channel->slots[0].in.eg_ksl_offset; + channel->slots[1].in.keyscale = channel->slots[0].in.keyscale; + + if (channel->emu_mode_4op_enable && (channel->channel_idx % 9) < 3 && channel->chip->emu_newmode) + { + int i; + esfm_channel *secondary = &channel->chip->channels[channel->channel_idx + 3]; + secondary->slots[0].f_num = channel->slots[0].f_num; + secondary->slots[0].block = channel->slots[0].block; + + for (i = 0; i < 2; i++) + { + secondary->slots[i].in.eg_ksl_offset = channel->slots[0].in.eg_ksl_offset; + secondary->slots[i].in.keyscale = channel->slots[0].in.keyscale; + } + } +} + +/* ------------------------------------------------------------------------- */ +static inline uint8_t +ESFM_slot_readback (esfm_slot *slot, uint8_t register_idx) +{ + uint8_t data = 0; + switch (register_idx & 0x07) + { + case 0x00: + data |= (slot->tremolo_en != 0) << 7; + data |= (slot->vibrato_en != 0) << 6; + data |= (slot->env_sustaining != 0) << 5; + data |= (slot->vibrato_en != 0) << 4; + data |= slot->mult & 0x0f; + break; + case 0x01: + data |= slot->ksl << 6; + data |= slot->t_level & 0x3f; + break; + case 0x02: + data |= slot->attack_rate << 4; + data |= slot->decay_rate & 0x0f; + break; + case 0x03: + data |= slot->sustain_lvl << 4; + data |= slot->release_rate & 0x0f; + break; + case 0x04: + data = slot->f_num & 0xff; + break; + case 0x05: + data |= slot->env_delay << 5; + data |= (slot->block & 0x07) << 2; + data |= (slot->f_num >> 8) & 0x03; + break; + case 0x06: + data |= (slot->tremolo_deep != 0) << 7; + data |= (slot->vibrato_deep != 0) << 6; + data |= (slot->out_enable[1] != 0) << 5; + data |= (slot->out_enable[0] != 0) << 4; + data |= (slot->mod_in_level & 0x07) << 1; + data |= slot->emu_connection_typ & 0x01; + break; + case 0x07: + data |= slot->output_level << 5; + data |= (slot->rhy_noise & 0x03) << 3; + data |= slot->waveform & 0x07; + break; + } + return data; +} + +/* ------------------------------------------------------------------------- */ +static inline void +ESFM_slot_write (esfm_slot *slot, uint8_t register_idx, uint8_t data) +{ + switch (register_idx & 0x07) + { + case 0x00: + slot->tremolo_en = (data & 0x80) != 0; + slot->vibrato_en = (data & 0x40) != 0; + slot->env_sustaining = (data & 0x20) != 0; + slot->ksr = (data & 0x10) != 0; + slot->mult = data & 0x0f; + break; + case 0x01: + slot->ksl = data >> 6; + slot->t_level = data & 0x3f; + ESFM_slot_update_keyscale(slot); + break; + case 0x02: + slot->attack_rate = data >> 4; + slot->decay_rate = data & 0x0f; + break; + case 0x03: + slot->sustain_lvl = data >> 4; + slot->release_rate = data & 0x0f; + break; + case 0x04: + slot->f_num = (slot->f_num & 0x300) | data; + ESFM_slot_update_keyscale(slot); + break; + case 0x05: + slot->env_delay = data >> 5; + slot->emu_key_on = (data >> 5) & 0x01; + slot->block = (data >> 2) & 0x07; + slot->f_num = (slot->f_num & 0xff) | ((data & 0x03) << 8); + ESFM_slot_update_keyscale(slot); + break; + case 0x06: + slot->tremolo_deep = (data & 0x80) != 0; + slot->vibrato_deep = (data & 0x40) != 0; + slot->out_enable[1] = (data & 0x20) ? ~((int13) 0) : 0; + slot->out_enable[0] = (data & 0x10) ? ~((int13) 0) : 0; + slot->mod_in_level = (data >> 1) & 0x07; + slot->emu_connection_typ = data & 0x01; + break; + case 0x07: + slot->output_level = data >> 5; + slot->rhy_noise = (data >> 3) & 0x03; + slot->waveform = data & 0x07; + break; + } +} + +#define KEY_ON_REGS_START (18 * 4 * 8) +#define TIMER1_REG (0x402) +#define TIMER2_REG (0x403) +#define TIMER_SETUP_REG (0x404) +#define CONFIG_REG (0x408) +#define BASSDRUM_REG (0x4bd) +#define TEST_REG (0x501) +#define FOUROP_CONN_REG (0x504) +#define NATIVE_MODE_REG (0x505) + +/* ------------------------------------------------------------------------- */ +static void +ESFM_write_reg_native (esfm_chip *chip, uint16_t address, uint8_t data) +{ + int i; + address = address & 0x7ff; + + if (address < KEY_ON_REGS_START) + { + // Slot register write + size_t channel_idx = address >> 5; + size_t slot_idx = (address >> 3) & 0x03; + size_t register_idx = address & 0x07; + esfm_slot *slot = &chip->channels[channel_idx].slots[slot_idx]; + + ESFM_slot_write(slot, register_idx, data); + } + else if (address < KEY_ON_REGS_START + 16) + { + // Key-on registers + size_t channel_idx = (address - KEY_ON_REGS_START); + esfm_channel *channel = &chip->channels[channel_idx]; + channel->key_on = data & 0x01; + channel->emu_mode_4op_enable = (data & 0x02) != 0; + } + else if (address < KEY_ON_REGS_START + 20) + { + // Key-on channels 17 and 18 (each half) + size_t channel_idx = 16 + ((address & 0x02) >> 1); + bool second_half = address & 0x01; + esfm_channel *channel = &chip->channels[channel_idx]; + if (second_half) + { + channel->key_on_2 = data & 0x01; + channel->emu_mode_4op_enable_2 = (data & 0x02) != 0; + } + else + { + channel->key_on = data & 0x01; + channel->emu_mode_4op_enable = (data & 0x02) != 0; + } + } + else + { + switch (address & 0x5ff) + { + case TIMER1_REG: + chip->timer_reload[0] = data; + break; + case TIMER2_REG: + chip->timer_reload[1] = data; + break; + case TIMER_SETUP_REG: + if (data & 0x80) + { + chip->timer_overflow[0] = 0; + chip->timer_overflow[1] = 0; + chip->irq_bit = 0; + } + chip->timer_enable[0] = (data & 0x01) != 0; + chip->timer_enable[1] = (data & 0x02) != 0; + chip->timer_mask[0] = (data & 0x20) != 0; + chip->timer_mask[1] = (data & 0x40) != 0; + break; + case CONFIG_REG: + chip->keyscale_mode = (data & 0x40) != 0; + break; + case BASSDRUM_REG: + chip->emu_rhy_mode_flags = data & 0x3f; + chip->emu_vibrato_deep = (data & 0x40) != 0; + chip->emu_tremolo_deep = (data & 0x80) != 0; + break; + case FOUROP_CONN_REG: + for (i = 0; i < 3; i++) + { + chip->channels[i].emu_mode_4op_enable = (data >> i) & 0x01; + chip->channels[i + 9].emu_mode_4op_enable = (data >> (i + 3)) & 0x01; + } + break; + case TEST_REG: + chip->test_bit_eg_halt = (data & 0x01) | ((data & 0x20) != 0); + chip->test_bit_distort = (data & 0x02) != 0; + chip->test_bit_attenuate = (data & 0x10) != 0; + chip->test_bit_phase_stop_reset = (data & 0x40) != 0; + break; + } + } +} + +/* ------------------------------------------------------------------------- */ +static uint8_t +ESFM_readback_reg_native (esfm_chip *chip, uint16_t address) +{ + int i; + uint8_t data = 0; + address = address & 0x7ff; + + if (address < KEY_ON_REGS_START) + { + // Slot register read + size_t channel_idx = address >> 5; + size_t slot_idx = (address >> 3) & 0x03; + size_t register_idx = address & 0x07; + esfm_slot *slot = &chip->channels[channel_idx].slots[slot_idx]; + + data = ESFM_slot_readback(slot, register_idx); + } + else if (address < KEY_ON_REGS_START + 16) + { + // Key-on registers + size_t channel_idx = (address - KEY_ON_REGS_START); + esfm_channel *channel = &chip->channels[channel_idx]; + + data |= channel->key_on != 0; + data |= (channel->emu_mode_4op_enable != 0) << 1; + } + else if (address < KEY_ON_REGS_START + 20) + { + // Key-on channels 17 and 18 (each half) + size_t channel_idx = 16 + ((address & 0x02) >> 1); + bool second_half = address & 0x01; + esfm_channel *channel = &chip->channels[channel_idx]; + if (second_half) + { + data |= channel->key_on_2 != 0; + data |= (channel->emu_mode_4op_enable_2 != 0) << 1; + } + else + { + data |= channel->key_on != 0; + data |= (channel->emu_mode_4op_enable != 0) << 1; + } + } + else + { + switch (address & 0x5ff) + { + case TIMER1_REG: + data = chip->timer_reload[0]; + break; + case TIMER2_REG: + data = chip->timer_reload[1]; + break; + case TIMER_SETUP_REG: + data |= chip->timer_enable[0] != 0; + data |= (chip->timer_enable[1] != 0) << 1; + data |= (chip->timer_mask[0] != 0) << 5; + data |= (chip->timer_mask[1] != 0) << 6; + break; + case CONFIG_REG: + data |= (chip->keyscale_mode != 0) << 6; + break; + case BASSDRUM_REG: + data |= chip->emu_rhy_mode_flags; + data |= chip->emu_vibrato_deep << 6; + data |= chip->emu_tremolo_deep << 7; + break; + case TEST_REG: + data |= chip->test_bit_eg_halt != 0; + data |= (chip->test_bit_distort != 0) << 1; + data |= (chip->test_bit_attenuate != 0) << 4; + data |= (chip->test_bit_eg_halt != 0) << 5; + data |= (chip->test_bit_phase_stop_reset != 0) << 6; + break; + case FOUROP_CONN_REG: + for (i = 0; i < 3; i++) + { + data |= (chip->channels[i].emu_mode_4op_enable != 0) << i; + data |= (chip->channels[i + 9].emu_mode_4op_enable != 0) << (i + 3); + } + break; + case NATIVE_MODE_REG: + data |= (chip->native_mode != 0) << 7; + break; + } + } + return data; +} + +/* ------------------------------------------------------------------------- */ +static void +ESFM_write_reg_emu (esfm_chip *chip, uint16_t address, uint8_t data) +{ + bool high = (address & 0x100) != 0; + uint8_t reg = address & 0xff; + int emu_slot_idx = ad_slot[address & 0x1f]; + int natv_chan_idx = -1; + int natv_slot_idx = -1; + int emu_chan_idx = (reg & 0x0f) > 8 ? -1 : ((reg & 0x0f) + high * 9); + + if (emu_slot_idx >= 0) + { + if (high) + { + emu_slot_idx += 18; + } + + natv_chan_idx = emu_slot_map[emu_slot_idx].channel_idx; + natv_slot_idx = emu_slot_map[emu_slot_idx].slot_idx; + } + + if (reg == 0xbd) + { + chip->emu_rhy_mode_flags = data & 0x3f; + chip->emu_vibrato_deep = (data & 0x40) != 0; + chip->emu_tremolo_deep = (data & 0x80) != 0; + if (chip->emu_rhy_mode_flags & 0x20) + { + // TODO: check if writes to 0xbd actually affect the readable key-on flags at + // 0x246, 0x247, 0x248; and if there's any visible effect from the SD and TC flags + chip->channels[6].key_on = (data & 0x10) != 0; + chip->channels[7].key_on = (data & 0x01) != 0; + chip->channels[8].key_on = (data & 0x04) != 0; + chip->channels[7].key_on_2 = (data & 0x08) != 0; + chip->channels[8].key_on_2 = (data & 0x02) != 0; + } + ESFM_emu_rearrange_connections(&chip->channels[7]); + ESFM_emu_rearrange_connections(&chip->channels[8]); + return; + } + + switch(reg & 0xf0) + { + case 0x00: + if (high) + { + int i; + switch(reg & 0x0f) + { + case 0x01: + chip->emu_wavesel_enable = (data & 0x20) != 0; + break; + case 0x02: + chip->timer_reload[0] = data; + break; + case 0x03: + chip->timer_reload[1] = data; + break; + case 0x04: + for (i = 0; i < 3; i++) + { + chip->channels[i].emu_mode_4op_enable = (data >> i) & 0x01; + chip->channels[i + 9].emu_mode_4op_enable = (data >> (i + 3)) & 0x01; + } + for (i = 0; i < 6; i++) + { + ESFM_emu_rearrange_connections(&chip->channels[i]); + ESFM_emu_rearrange_connections(&chip->channels[i + 9]); + } + break; + case 0x05: + chip->emu_newmode = data & 0x01; + if ((data & 0x80) != 0) + { + chip->native_mode = 1; + ESFM_emu_to_native_switch(chip); + } + break; + case 0x08: + chip->keyscale_mode = (data & 0x40) != 0; + break; + } + } + else + { + switch(reg & 0x0f) + { + case 0x01: + chip->emu_wavesel_enable = (data & 0x20) != 0; + break; + case 0x02: + chip->timer_reload[0] = data; + break; + case 0x03: + chip->timer_reload[1] = data; + break; + case 0x04: + chip->timer_enable[0] = data & 0x01; + chip->timer_enable[1] = (data & 0x02) != 0; + chip->timer_mask[0] = (data & 0x20) != 0; + chip->timer_mask[1] = (data & 0x40) != 0; + if (data & 0x80) + { + chip->irq_bit = 0; + } + break; + case 0x08: + chip->keyscale_mode = (data & 0x40) != 0; + break; + } + } + break; + case 0x20: case 0x30: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x0, data); + } + break; + case 0x40: case 0x50: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x1, data); + ESFM_emu_channel_update_keyscale(&chip->channels[natv_chan_idx]); + } + break; + case 0x60: case 0x70: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x2, data); + } + break; + case 0x80: case 0x90: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x3, data); + } + break; + case 0xa0: + if (emu_chan_idx >= 0) + { + ESFM_slot_write(&chip->channels[emu_chan_idx].slots[0], 0x4, data); + ESFM_emu_channel_update_keyscale(&chip->channels[emu_chan_idx]); + } + break; + case 0xb0: + if (emu_chan_idx >= 0) + { + esfm_channel *channel = &chip->channels[emu_chan_idx]; + // TODO: check if emulation mode actually writes to the native mode key on registers + // it might only use slot 0's emu key on field... + channel->key_on = (data & 0x20) != 0; + if (channel->channel_idx == 7 || channel->channel_idx == 8) + { + channel->key_on_2 = (data & 0x20) != 0; + } + ESFM_slot_write(&channel->slots[0], 0x5, data); + ESFM_emu_channel_update_keyscale(&chip->channels[emu_chan_idx]); + } + break; + case 0xc0: + if (emu_chan_idx >= 0) + { + ESFM_slot_write(&chip->channels[emu_chan_idx].slots[0], 0x6, data); + ESFM_emu_rearrange_connections(&chip->channels[emu_chan_idx]); + } + break; + case 0xe0: case 0xf0: + if (emu_slot_idx >= 0) + { + ESFM_slot_write(&chip->channels[natv_chan_idx].slots[natv_slot_idx], 0x7, data); + } + break; + } +} + + +/* ------------------------------------------------------------------------- */ +void +ESFM_write_reg (esfm_chip *chip, uint16_t address, uint8_t data) +{ + if (chip->native_mode) + { + ESFM_write_reg_native(chip, address, data); + return; + } + else + { + ESFM_write_reg_emu(chip, address, data); + return; + } +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_write_reg_buffered (esfm_chip *chip, uint16_t address, uint8_t data) +{ + uint64_t timestamp; + esfm_write_buf *new_entry, *last_entry; + + new_entry = &chip->write_buf[chip->write_buf_end]; + last_entry = &chip->write_buf[(chip->write_buf_end - 1) % ESFM_WRITEBUF_SIZE]; + + if (new_entry->valid) { + ESFM_write_reg(chip, new_entry->address, new_entry->data); + chip->write_buf_start = (chip->write_buf_end + 1) % ESFM_WRITEBUF_SIZE; + } + + new_entry->valid = 1; + new_entry->address = address; + new_entry->data = data; + timestamp = last_entry->timestamp + ESFM_WRITEBUF_DELAY; + if (timestamp < chip->write_buf_timestamp) + { + timestamp = chip->write_buf_timestamp; + } + + new_entry->timestamp = timestamp; + chip->write_buf_end = (chip->write_buf_end + 1) % ESFM_WRITEBUF_SIZE; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_write_reg_buffered_fast (esfm_chip *chip, uint16_t address, uint8_t data) +{ + esfm_write_buf *new_entry; + + new_entry = &chip->write_buf[chip->write_buf_end]; + + if (new_entry->valid) { + ESFM_write_reg(chip, new_entry->address, new_entry->data); + chip->write_buf_start = (chip->write_buf_end + 1) % ESFM_WRITEBUF_SIZE; + } + + new_entry->valid = 1; + new_entry->address = address; + new_entry->data = data; + new_entry->timestamp = chip->write_buf_timestamp; + chip->write_buf_end = (chip->write_buf_end + 1) % ESFM_WRITEBUF_SIZE; +} + +/* ------------------------------------------------------------------------- */ +uint8_t +ESFM_readback_reg (esfm_chip *chip, uint16_t address) +{ + if (chip->native_mode) + { + return ESFM_readback_reg_native(chip, address); + } + else + { + return 0; + } +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_write_port (esfm_chip *chip, uint8_t offset, uint8_t data) +{ + if (chip->native_mode) + { + switch(offset) + { + case 0: + chip->native_mode = 0; + ESFM_native_to_emu_switch(chip); + chip->addr_latch = data; + break; + case 1: + ESFM_write_reg_native(chip, chip->addr_latch, data); + break; + case 2: + chip->addr_latch = (chip->addr_latch & 0xff00) | data; + break; + case 3: + chip->addr_latch = chip->addr_latch & 0xff; + chip->addr_latch |= (uint16)data << 8; + break; + } + } + else + { + switch(offset) + { + case 0: + chip->addr_latch = data; + break; + case 1: case 3: + ESFM_write_reg_emu(chip, chip->addr_latch, data); + break; + case 2: + chip->addr_latch = (uint16)data | 0x100; + break; + } + } +} + +/* ------------------------------------------------------------------------- */ +uint8_t +ESFM_read_port (esfm_chip *chip, uint8_t offset) +{ + uint8_t data = 0; + if (chip->native_mode) + { + switch(offset) + { + case 0: + // TODO: actually implement timer count, trigger and reset + data |= (chip->irq_bit != 0) << 7; + data |= (chip->timer_overflow[0] != 0) << 6; + data |= (chip->timer_overflow[1] != 0) << 5; + break; + case 1: + data = ESFM_readback_reg_native(chip, chip->addr_latch); + break; + // TODO: verify what the ESFM chip actually returns when reading + // from the other address ports + } + } + else + { + switch(offset) + { + case 0: + data |= (chip->irq_bit != 0) << 7; + data |= (chip->timer_overflow[0] != 0) << 6; + data |= (chip->timer_overflow[1] != 0) << 5; + break; + case 1: + data = 0; + break; + case 2: case 3: + // This matches OPL3 behavior. + // TODO: verify what the ESFM chip actually returns when reading + // from address ports in emulation mode + data = 0xff; + break; + } + } + return data; +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_set_mode (esfm_chip *chip, bool native_mode) +{ + native_mode = native_mode != 0; + + if (native_mode != (chip->native_mode != 0)) + { + chip->native_mode = native_mode; + if (native_mode) + { + ESFM_emu_to_native_switch(chip); + } + else + { + ESFM_native_to_emu_switch(chip); + } + } +} + +/* ------------------------------------------------------------------------- */ +void +ESFM_init (esfm_chip *chip) +{ + esfm_slot *slot; + esfm_channel *channel; + size_t channel_idx, slot_idx; + + memset(chip, 0, sizeof(esfm_chip)); + for (channel_idx = 0; channel_idx < 18; channel_idx++) + { + for (slot_idx = 0; slot_idx < 4; slot_idx++) + { + channel = &chip->channels[channel_idx]; + slot = &channel->slots[slot_idx]; + + channel->chip = chip; + channel->channel_idx = channel_idx; + slot->channel = channel; + slot->chip = chip; + slot->slot_idx = slot_idx; + slot->in.eg_position = slot->in.eg_output = 0x1ff; + slot->in.eg_state = EG_RELEASE; + slot->in.emu_mod_enable = ~((int13) 0); + if (slot_idx == 0) + { + slot->in.mod_input = &slot->in.feedback_buf; + } + else + { + esfm_slot *prev_slot = &channel->slots[slot_idx - 1]; + slot->in.mod_input = &prev_slot->in.output; + } + + if (slot_idx == 1) + { + slot->in.emu_output_enable = ~((int13) 0); + } + + if (channel_idx > 15 && slot_idx & 0x02) + { + slot->in.key_on = &channel->key_on_2; + } + else + { + slot->in.key_on = &channel->key_on; + } + + slot->out_enable[0] = slot->out_enable[1] = ~((int13) 0); + } + } + + chip->lfsr = 1; +} + diff --git a/src/engine/dispatchContainer.cpp b/src/engine/dispatchContainer.cpp index 8ff1a33c7..cf4349887 100644 --- a/src/engine/dispatchContainer.cpp +++ b/src/engine/dispatchContainer.cpp @@ -82,6 +82,7 @@ #include "platform/ted.h" #include "platform/c140.h" #include "platform/pcmdac.h" +#include "platform/esfm.h" #include "platform/dummy.h" #include "../ta-log.h" #include "song.h" @@ -596,6 +597,9 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do case DIV_SYSTEM_PCM_DAC: dispatch=new DivPlatformPCMDAC; break; + case DIV_SYSTEM_ESFM: + dispatch=new DivPlatformESFM; + break; case DIV_SYSTEM_DUMMY: dispatch=new DivPlatformDummy; break; diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 1467377c1..b8c2eb62a 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1371,6 +1371,9 @@ DivInstrument* DivEngine::getIns(int index, DivInstrumentType fallbackType) { case DIV_INS_OPL_DRUMS: return &song.nullInsOPLDrums; break; + case DIV_INS_ESFM: + return &song.nullInsESFM; + break; default: break; } @@ -2328,6 +2331,9 @@ int DivEngine::addInstrument(int refChan, DivInstrumentType fallbackType) { case DIV_INS_OPL_DRUMS: *ins=song.nullInsOPLDrums; break; + case DIV_INS_ESFM: + *ins=song.nullInsESFM; + break; default: break; } diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index abd06a26a..0e1340e90 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -228,6 +228,28 @@ bool DivInstrumentSNES::operator==(const DivInstrumentSNES& other) { ); } +bool DivInstrumentESFM::operator==(const DivInstrumentESFM& other) { + return ( + _C(noise) && + _C(op[0]) && + _C(op[1]) && + _C(op[2]) && + _C(op[3]) + ); +} + +bool DivInstrumentESFM::Operator::operator==(const DivInstrumentESFM::Operator& other) { + return ( + _C(delay) && + _C(outLvl) && + _C(modIn) && + _C(left) && + _C(right) && + _C(ct) && + _C(dt) + ); +} + #undef _C #define FEATURE_BEGIN(x) \ @@ -734,6 +756,22 @@ void DivInstrument::writeFeatureNE(SafeWriter* w) { FEATURE_END; } +void DivInstrument::writeFeatureEF(SafeWriter* w) { + FEATURE_BEGIN("EF"); + + w->writeC(esfm.noise&3); + for (int i=0; i<4; i++) { + DivInstrumentESFM::Operator& op=esfm.op[i]; + + w->writeC(((op.delay&7)<<5)|((op.outLvl&7)<<2)|((op.right&1)<<1)|(op.left&1)); + w->writeC(op.modIn&7); + w->writeC(op.ct); + w->writeC(op.dt); + } + + FEATURE_END; +} + void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bool insName) { size_t blockStartSeek=0; size_t blockEndSeek=0; @@ -777,6 +815,7 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo bool featureES=false; bool featureX1=false; bool featureNE=false; + bool featureEF=false; bool checkForWL=false; @@ -990,7 +1029,10 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo featureSM=true; featureSL=true; break; - + case DIV_INS_ESFM: + featureFM=true; + featureEF=true; + break; case DIV_INS_MAX: break; case DIV_INS_NULL: @@ -1038,6 +1080,9 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo if (x1_010!=defaultIns.x1_010) { featureX1=true; } + if (esfm!=defaultIns.esfm) { + featureEF=true; + } } // check ins name @@ -1180,6 +1225,9 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo if (featureNE) { writeFeatureNE(w); } + if (featureEF) { + writeFeatureEF(w); + } if (fui && (featureSL || featureWL)) { w->write("EN",2); @@ -2579,6 +2627,31 @@ void DivInstrument::readFeatureNE(SafeReader& reader, short version) { READ_FEAT_END; } +void DivInstrument::readFeatureEF(SafeReader& reader, short version) { + READ_FEAT_BEGIN; + + unsigned char next=reader.readC(); + esfm.noise = next&3; + + for (int i=0; i<4; i++) { + DivInstrumentESFM::Operator& op=esfm.op[i]; + + next=reader.readC(); + op.delay=(next>>5)&7; + op.outLvl=(next>>2)&7; + op.right=(next>>1)&1; + op.left=next&1; + + next=reader.readC(); + op.modIn=next&7; + + op.ct=reader.readC(); + op.dt=reader.readC(); + } + + READ_FEAT_END; +} + DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, bool fui, DivSong* song) { unsigned char featCode[2]; @@ -2646,6 +2719,8 @@ DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, b readFeatureX1(reader,version); } else if (memcmp(featCode,"NE",2)==0) { // NES (DPCM) readFeatureNE(reader,version); + } else if (memcmp(featCode,"EF",2)==0) { // ESFM + readFeatureEF(reader,version); } else { if (song==NULL && (memcmp(featCode,"SL",2)==0 || (memcmp(featCode,"WL",2)==0))) { // nothing diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 477962dfa..91a6d2a6b 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -85,6 +85,8 @@ enum DivInstrumentType: unsigned short { DIV_INS_TED=52, DIV_INS_C140=53, DIV_INS_C219=54, + // TODO: Ask tilde to standardize this!!! + DIV_INS_ESFM=55, DIV_INS_MAX, DIV_INS_NULL }; @@ -150,6 +152,8 @@ enum DivMacroTypeOp: unsigned char { // - AM, AR, DR, MULT (CRS), RR, SL, TL, DT2, RS, DT, D2R // - WS, DVB = MULT (FINE), DAM = REV, KSL = EGShift, EGT = Fixed + + struct DivInstrumentFM { unsigned char alg, fb, fms, ams, fms2, ams2, ops, opllPreset; bool fixedDrums; @@ -750,6 +754,108 @@ struct DivInstrumentSNES { d2(0) {} }; +// ESFM operator structure: +// - DELAY, OUT, MOD, L, R, NOISE +// - Virtual: CT, DT, DTRAW +// - In FM struct: AM, DAM, AR, DR, MULT, RR, SL, TL +// - In FM struct: KSL, VIB, DVB, WS, SUS, KSR +// - Not in struct: FNUML, FNUMH, BLOCK + +struct DivInstrumentESFM { + bool operator==(const DivInstrumentESFM& other); + bool operator!=(const DivInstrumentESFM& other) { + return !(*this==other); + } + + // Only works on OP4, so putting it outside the Operator struct instead + unsigned char noise; + struct Operator { + unsigned char delay, outLvl, modIn, left, right; + signed char ct, dt; + + bool operator==(const Operator& other); + bool operator!=(const Operator& other) { + return !(*this==other); + } + Operator(): + delay(0), + outLvl(0), + modIn(0), + left(true), + right(true), + ct(0), + dt(0) {} + } op[4]; + DivInstrumentESFM(): + noise(0) + { + op[0].modIn=4; + op[0].outLvl=0; + + op[1].modIn=7; + op[1].outLvl=0; + + op[2].modIn=7; + op[2].outLvl=0; + + op[3].modIn=7; + op[3].outLvl=7; + } + +#if 0 + void syncFrom(DivInstrumentFM &other) { + for (int i=0; i<4; i++) { + this->op[i].am=other.op[i].am; + this->op[i].dam=other.op[i].dam; + this->op[i].ar=other.op[i].ar; + this->op[i].dr=other.op[i].dr; + this->op[i].mult=other.op[i].mult; + this->op[i].rr=other.op[i].rr; + this->op[i].sl=other.op[i].sl; + this->op[i].tl=other.op[i].tl; + this->op[i].ssgEnv=other.op[i].ssgEnv; + this->op[i].ksl=other.op[i].ksl; + this->op[i].vib=other.op[i].vib; + this->op[i].dvb=other.op[i].dvb; + this->op[i].ws=other.op[i].ws; + this->op[i].ksr=other.op[i].ksr; + this->op[i].ct=0; + // from dtTable at fmsharedbase.h + if (other.op[i].dt>=7){ + // trap out of range dt values + // TODO: check if any systems legitimately use dt values higher than 7 + this->op[i].dt=0; + } else { + this->op[i].dt=other.op[i].dt - 3; + } + } + } + + void syncTo(DivInstrumentFM &other) { + for (int i=0; i<4; i++) { + other.op[i].am=this->op[i].am; + other.op[i].dam=this->op[i].dam; + other.op[i].ar=this->op[i].ar; + other.op[i].dr=this->op[i].dr; + other.op[i].mult=this->op[i].mult; + other.op[i].rr=this->op[i].rr; + other.op[i].sl=this->op[i].sl; + other.op[i].tl=this->op[i].tl; + other.op[i].ssgEnv=this->op[i].ssgEnv; + other.op[i].ksl=this->op[i].ksl; + other.op[i].vib=this->op[i].vib; + other.op[i].dvb=this->op[i].dvb; + other.op[i].ws=this->op[i].ws; + other.op[i].ksr=this->op[i].ksr; + // dt field conversion is unfortunately lossy, as the dt field on DivInstrumentFM + // spans from 0..6 (eff. -3..3), while on DivInstrumentESFM it spans from -128..127. + other.op[i].dt=CLAMP(this->op[i].dt, -3, 3) + 3; + } + } +#endif + +}; + struct DivInstrument { String name; DivInstrumentType type; @@ -766,6 +872,8 @@ struct DivInstrument { DivInstrumentSoundUnit su; DivInstrumentES5506 es5506; DivInstrumentSNES snes; + DivInstrumentESFM esfm; + // TODO I only added the esfm member here, still need to implement everything else related /** * these are internal functions. @@ -790,6 +898,7 @@ struct DivInstrument { void writeFeatureES(SafeWriter* w); void writeFeatureX1(SafeWriter* w); void writeFeatureNE(SafeWriter* w); + void writeFeatureEF(SafeWriter* w); void readFeatureNA(SafeReader& reader, short version); void readFeatureFM(SafeReader& reader, short version); @@ -810,6 +919,7 @@ struct DivInstrument { void readFeatureES(SafeReader& reader, short version); void readFeatureX1(SafeReader& reader, short version); void readFeatureNE(SafeReader& reader, short version); + void readFeatureEF(SafeReader& reader, short version); DivDataErrors readInsDataOld(SafeReader& reader, short version); DivDataErrors readInsDataNew(SafeReader& reader, short version, bool fui, DivSong* song); diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp new file mode 100644 index 000000000..0c1a11e97 --- /dev/null +++ b/src/engine/platform/esfm.cpp @@ -0,0 +1,854 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2023 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 "esfm.h" +#include "../engine.h" +#include "../../ta-log.h" +#include +#include +#include + +#define CHIP_FREQBASE (32768*288) + +#define OFFSET_AM_VIB_SUS_KSR_MULT 0x00 +#define OFFSET_KSL_TL 0x01 +#define OFFSET_AR_DR 0x02 +#define OFFSET_SL_RR 0x03 +#define OFFSET_FREQL 0x04 +#define OFFSET_FREQH_BLOCK_DELAY 0x05 +#define OFFSET_DAM_DVB_LEFT_RIGHT_MODIN 0x06 +#define OFFSET_OUTLVL_NOISE_WS 0x07 + +#define KEY_ON_REGS_START (18 * 8 * 4) + +void DivPlatformESFM::acquire(short** buf, size_t len) { + thread_local short o[2]; + for (size_t h=0; hdata[oscBuf[c]->needle++]=ESFM_get_channel_output_native(&chip,c); + } + + buf[0][h]=o[0]; + buf[1][h]=o[1]; + } +} + +void DivPlatformESFM::tick(bool sysTick) { + for (int i=0; i<18; i++) { + chan[i].std.next(); + + if (chan[i].std.vol.had) { + chan[i].outVol=VOL_SCALE_LOG_BROKEN(chan[i].vol,MIN(63,chan[i].std.vol.val),63); + for (int o=0; o<4; o++) { + unsigned short baseAddr=i*32 + o*8; + DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o]; + unsigned char noise=chan[i].state.esfm.noise&3; + + if (isMuted[i]) { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + } else { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + if (KVS(i, o)) { + rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[i].outVol&0x3f,63))|(op.ksl<<6)); + } else { + rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + } + } + } + } + + if (NEW_ARP_STRAT) { + chan[i].handleArp(); + } else if (chan[i].std.arp.had) { + if (!chan[i].inPorta) { + chan[i].baseFreq=NOTE_FREQUENCY(parent->calcArp(chan[i].note,chan[i].std.arp.val)); + } + chan[i].freqChanged=true; + } + + // TODO: check why I disabled globalPan here? +#if 0 + if (chan[i].std.panL.had) { + chan[i].globalPan=((chan[i].std.panL.val&1)<<1)|((chan[i].std.panL.val&2)>>1); + } +#endif + + if (chan[i].std.pitch.had) { + if (chan[i].std.pitch.mode) { + chan[i].pitch2+=chan[i].std.pitch.val; + CLAMP_VAR(chan[i].pitch2,-131071,131071); + } else { + chan[i].pitch2=chan[i].std.pitch.val; + } + chan[i].freqChanged=true; + } + + if (chan[i].std.phaseReset.had) { + if (chan[i].std.phaseReset.val==1 && chan[i].active) { + chan[i].keyOn=true; + } + } + + for (int o=0; o<4; o++) { + unsigned short baseAddr=i*32 + o*8; + DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; + DivMacroInt::IntOp& m=chan[i].std.op[o]; + + if (m.am.had) { + op.am=m.am.val; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + } + if (m.vib.had) { + op.vib=m.vib.val; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + } + if (m.sus.had) { + op.sus=m.sus.val; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + } + if (m.ksr.had) { + op.ksr=m.ksr.val; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + } + if (m.mult.had) { + op.mult=m.mult.val; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + } + + if (m.ar.had) { + op.ar=m.ar.val; + rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); + } + if (m.dr.had) { + op.dr=m.dr.val; + rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); + } + if (m.sl.had) { + op.sl=m.sl.val; + rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); + } + if (m.rr.had) { + op.rr=m.rr.val; + rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); + } + + if (m.tl.had || m.ksl.had) { + if (m.tl.had) { + op.tl=m.tl.val&63; + } + if (m.ksl.had) { + op.ksl=m.ksl.val; + } + + if (KVS(i, o)) { + rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[i].outVol&0x3f,63))|(op.ksl<<6)); + } else { + rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + } + } + } + } + + for (int i=0; icalcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,octave(chan[i].baseFreq)*2,chan[i].pitch2,chipClock,CHIP_FREQBASE); + if (chan[i].freq<0) chan[i].freq=0; + if (chan[i].freq>131071) chan[i].freq=131071; + + for (int o=0; o<4; o++) { + unsigned short baseAddr=i*32 + o*8; + DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o]; + int ct=(int)opE.ct; + int dt=(int)opE.dt; + int opFreq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride+ct:chan[i].arpOff+ct,chan[i].fixedArp,false,octave(chan[i].baseFreq)*2,chan[i].pitch2+dt,chipClock,CHIP_FREQBASE); + if (opFreq<0) opFreq=0; + if (opFreq>131071) opFreq=131071; + int freqt=toFreq(opFreq); + chan[i].freqL[o]=freqt&0xff; + chan[i].freqH[o]=freqt>>8; + immWrite(baseAddr+OFFSET_FREQL,chan[i].freqL[o]); + immWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[i].freqH[o]|(opE.delay<<5)); + } + chan[i].freqChanged=false; + } + if (chan[i].keyOn && !chan[i].hardReset) { + // logI("chan[%d] soft key on", i); + if (i<16) { + immWrite(KEY_ON_REGS_START+i, 1); + } else { + // Handle writing to the split key-on registers of channels 16 and 17 + immWrite(KEY_ON_REGS_START+16+(i-16)*2, 1); + immWrite(KEY_ON_REGS_START+16+1+(i-16)*2, 1); + } + chan[i].keyOn=false; + } + } + + if (mustHardReset) { + for (int i=0; i<18; i++) { + if (chan[i].hardReset && chan[i].keyOn) { + // logI("chan[%d] hard reset key on, writing original slrr back", i); + for (int o=0; o<4; o++) { + unsigned short baseAddr=i*32 + o*8; + DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; + immWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); + } + if (i<16) { + immWrite(KEY_ON_REGS_START+i, 1); + } else { + // Handle writing to the split key-on registers of channels 16 and 17 + immWrite(KEY_ON_REGS_START+16+(i-16)*2, 1); + immWrite(KEY_ON_REGS_START+16+1+(i-16)*2, 1); + } + chan[i].keyOn=false; + } + } + } +} + +int DivPlatformESFM::octave(int freq) { + if (freq>=0x3ff<<6) { + return 1<<7; + } else if (freq>=0x3ff<<5) { + return 1<<6; + } else if (freq>=0x3ff<<4) { + return 1<<5; + } else if (freq>=0x3ff<<3) { + return 1<<4; + } else if (freq>=0x3ff<<2) { + return 1<<3; + } else if (freq>=0x3ff<<1) { + return 1<<2; + } else if (freq>=0x3ff) { + return 1<<1; + } else { + return 1<<0; + } + return 1<<0; +} + +int DivPlatformESFM::toFreq(int freq) { + if (freq>=0x3ff<<6) { + return 0x1c00|((freq>>7)&0x3ff); + } else if (freq>=0x3ff<<5) { + return 0x1800|((freq>>6)&0x3ff); + } else if (freq>=0x3ff<<4) { + return 0x1400|((freq>>5)&0x3ff); + } else if (freq>=0x3ff<<3) { + return 0x1000|((freq>>4)&0x3ff); + } else if (freq>=0x3ff<<2) { + return 0xc00|((freq>>3)&0x3ff); + } else if (freq>=0x3ff<<1) { + return 0x800|((freq>>2)&0x3ff); + } else if (freq>=0x3ff<<0) { + return 0x400|((freq>>1)&0x3ff); + } else { + return freq&0x3ff; + } +} + +void DivPlatformESFM::muteChannel(int ch, bool mute) { + isMuted[ch]=mute; + + for (int o=0; o<4; o++) { + unsigned short baseAddr=ch*32 + o*8; + DivInstrumentFM::Operator& op=chan[ch].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[ch].state.esfm.op[o]; + unsigned char noise=chan[ch].state.esfm.noise&3; + + if (isMuted[ch]) { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + } else { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + if (KVS(ch, o)) { + rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[ch].outVol&0x3f,63))|(op.ksl<<6)); + } else { + rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + } + } + } +} + +void DivPlatformESFM::commitState(int ch, DivInstrument* ins) { + if (chan[ch].insChanged) { + chan[ch].state.fm=ins->fm; + chan[ch].state.esfm=ins->esfm; + for (int o=0; o<4; o++) { + unsigned short baseAddr=ch*32 + o*8; + DivInstrumentFM::Operator& op=chan[ch].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[ch].state.esfm.op[o]; + unsigned char noise=chan[ch].state.esfm.noise&3; + + if (isMuted[ch]) { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + } else { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + if (KVS(ch, o)) { + rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[ch].outVol&0x3f,63))|(op.ksl<<6)); + } else { + rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + } + } + + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); + rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); + rWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[ch].freqH[o]|(opE.delay<<5)); + rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[ch].globalPan)&1)<<4)|(((opE.right&(chan[ch].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + } + } +} + +int DivPlatformESFM::dispatch(DivCommand c) { + switch (c.cmd) { + case DIV_CMD_NOTE_ON: { + DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_ESFM); + + chan[c.chan].macroInit(ins); + if (!chan[c.chan].std.vol.will) { + chan[c.chan].outVol=chan[c.chan].vol; + } + + commitState(c.chan,ins); + chan[c.chan].insChanged=false; + + if (c.value!=DIV_NOTE_NULL) { + chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value); + chan[c.chan].note=c.value; + chan[c.chan].freqChanged=true; + } + chan[c.chan].keyOn=true; + chan[c.chan].active=true; + break; + } + case DIV_CMD_NOTE_OFF: + chan[c.chan].keyOff=true; + chan[c.chan].keyOn=false; + chan[c.chan].active=false; + break; + case DIV_CMD_NOTE_OFF_ENV: + chan[c.chan].keyOff=true; + chan[c.chan].keyOn=false; + chan[c.chan].active=false; + chan[c.chan].std.release(); + break; + case DIV_CMD_ENV_RELEASE: + chan[c.chan].std.release(); + break; + case DIV_CMD_VOLUME: { + chan[c.chan].vol=c.value; + if (!chan[c.chan].std.vol.has) { + chan[c.chan].outVol=c.value; + } + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + if (KVS(c.chan, o)) { + rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); + } else { + rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + } + } + break; + } + case DIV_CMD_GET_VOLUME: + return chan[c.chan].vol; + break; + case DIV_CMD_INSTRUMENT: + if (chan[c.chan].ins!=c.value || c.value2==1) { + chan[c.chan].insChanged=true; + } + chan[c.chan].ins=c.value; + break; + case DIV_CMD_PANNING: { + chan[c.chan].globalPan=(c.value>0)|((c.value2>0)<<1); + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + + rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + } + break; + } + case DIV_CMD_PITCH: + chan[c.chan].pitch=c.value; + chan[c.chan].freqChanged=true; + break; + case DIV_CMD_NOTE_PORTA: { + int destFreq=NOTE_FREQUENCY(c.value2); + int newFreq; + bool return2=false; + if (destFreq>chan[c.chan].baseFreq) { + newFreq=chan[c.chan].baseFreq+c.value*((parent->song.linearPitch==2)?1:octave(chan[c.chan].baseFreq)); + if (newFreq>=destFreq) { + newFreq=destFreq; + return2=true; + } + } else { + newFreq=chan[c.chan].baseFreq-c.value*((parent->song.linearPitch==2)?1:octave(chan[c.chan].baseFreq)); + if (newFreq<=destFreq) { + newFreq=destFreq; + return2=true; + } + } + if (!chan[c.chan].portaPause && parent->song.linearPitch!=2) { + if (octave(chan[c.chan].baseFreq)!=octave(newFreq)) { + chan[c.chan].portaPause=true; + break; + } + } + chan[c.chan].baseFreq=newFreq; + chan[c.chan].portaPause=false; + chan[c.chan].freqChanged=true; + if (return2) { + chan[c.chan].inPorta=false; + return 2; + } + break; + } + case DIV_CMD_LEGATO: { + if (chan[c.chan].insChanged) { + DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_ESFM); + commitState(c.chan,ins); + chan[c.chan].insChanged=false; + } + chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value); + chan[c.chan].note=c.value; + chan[c.chan].freqChanged=true; + break; + } + case DIV_CMD_FM_MULT: { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.mult=c.value2&15; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + break; + } + case DIV_CMD_FM_TL: { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.tl=c.value2&63; + if (KVS(c.chan, o)) { + rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); + } else { + rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + } + break; + } + case DIV_CMD_FM_AR: { + if (c.value<0) { + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.ar=c.value2&15; + rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); + } + } else { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.ar=c.value2&15; + rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); + } + break; + } + case DIV_CMD_FM_DR: { + if (c.value<0) { + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.dr=c.value2&15; + rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); + } + } else { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.dr=c.value2&15; + rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); + } + break; + } + case DIV_CMD_FM_SL: { + if (c.value<0) { + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.sl=c.value2&15; + rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); + } + } else { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.sl=c.value2&15; + rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); + } + break; + } + case DIV_CMD_FM_RR: { + if (c.value<0) { + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.rr=c.value2&15; + rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|op.rr); + } + } else { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.rr=c.value2&15; + rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|op.rr); + } + break; + } + case DIV_CMD_FM_AM: { + if (c.value<0) { + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.am=c.value2&1; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + } + } else { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.am=c.value2&1; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + } + break; + } + case DIV_CMD_FM_VIB: { + if (c.value<0) { + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.vib=c.value2&1; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + } + } else { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.vib=c.value2&1; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + } + break; + } + case DIV_CMD_FM_SUS: { + if (c.value<0) { + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.sus=c.value2&1; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + } + } else { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.sus=c.value2&1; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + } + break; + } + case DIV_CMD_FM_KSR: { + if (c.value<0) { + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.ksr=c.value2&1; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + } + } else { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.ksr=c.value2&1; + rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + } + break; + } + case DIV_CMD_FM_WS: { + if (c.value<0) { + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + unsigned char noise=chan[c.chan].state.esfm.noise&3; + op.ws=c.value2&7; + if (isMuted[c.chan]) { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + } else { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + } + } + } else { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + unsigned char noise=chan[c.chan].state.esfm.noise&3; + op.ws=c.value2&7; + if (isMuted[c.chan]) { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + } else { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + } + } + break; + } + // KSL + case DIV_CMD_FM_RS: { + if (c.value<0) { + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.ksl=c.value2&3; + if (KVS(c.chan, o)) { + rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); + } else { + rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + } + } + } else { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + op.ksl=c.value2&3; + if (KVS(c.chan, o)) { + rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); + } else { + rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + } + } + break; + } + case DIV_CMD_FM_HARD_RESET: + chan[c.chan].hardReset=c.value; + break; + case DIV_CMD_MACRO_OFF: + chan[c.chan].std.mask(c.value,true); + break; + case DIV_CMD_MACRO_ON: + chan[c.chan].std.mask(c.value,false); + break; + case DIV_ALWAYS_SET_VOLUME: + return 0; + break; + case DIV_CMD_GET_VOLMAX: + return 63; + break; + case DIV_CMD_PRE_PORTA: + if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will && !NEW_ARP_STRAT) { + chan[c.chan].baseFreq=NOTE_FREQUENCY(chan[c.chan].note); + } + chan[c.chan].inPorta=c.value; + break; + default: + break; + } + return 1; +} + +void DivPlatformESFM::forceIns() { + for (int i=0; i<18; i++) { + chan[i].insChanged=true; + chan[i].freqChanged=true; + } + for (int i=0; i>1); +} + +DivDispatchOscBuffer* DivPlatformESFM::getOscBuffer(int ch) { + return oscBuf[ch]; +} + +unsigned char* DivPlatformESFM::getRegisterPool() { + // TODO: DEBUG, remove this, it impacts performance + for (int i=0; i& wlist) { + for (DivRegWrite& i: wlist) immWrite(i.addr,i.val); +} + +void DivPlatformESFM::setFlags(const DivConfig& flags) { + rate=49716; + chipClock=COLOR_NTSC*4.0; +} + +int DivPlatformESFM::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { + parent=p; + dumpWrites=false; + skipRegisterWrites=false; + for (int i=0; i<18; i++) { + isMuted[i]=false; + oscBuf[i]=new DivDispatchOscBuffer; + } + setFlags(flags); + reset(); + + return 18; +} + +void DivPlatformESFM::quit() { + for (int i=0; i<18; i++) { + delete oscBuf[i]; + } +} + +DivPlatformESFM::~DivPlatformESFM() { +} diff --git a/src/engine/platform/esfm.h b/src/engine/platform/esfm.h new file mode 100644 index 000000000..558571a84 --- /dev/null +++ b/src/engine/platform/esfm.h @@ -0,0 +1,144 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2023 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 "../dispatch.h" +#include "../../fixedQueue.h" +#include "../../../extern/ESFMu/esfm.h" + +// ESFM register address space technically spans 0x800 (2048) bytes, +// but we only need the first 0x254 (596) during normal use. +// Rounding it up to 0x260 (608) bytes, the nearest multiple of 16. +#define ESFM_REG_POOL_SIZE 0x260 + +class DivPlatformESFM: public DivDispatch { + struct Channel: public SharedChannel { + struct { + DivInstrumentFM fm; + DivInstrumentESFM esfm; + } state; + unsigned char freqL[4], freqH[4]; + bool hardReset; + unsigned char globalPan; + int macroVolMul; + Channel(): + SharedChannel(0), + freqL{0, 0, 0, 0}, + freqH{0, 0, 0, 0}, + globalPan(3), + macroVolMul(64) {} + }; + Channel chan[18]; + DivDispatchOscBuffer* oscBuf[18]; + bool isMuted[18]; + struct QueuedWrite { + unsigned short addr; + unsigned char val; + bool addrOrVal; + QueuedWrite(): addr(0), val(0), addrOrVal(false) {} + QueuedWrite(unsigned short a, unsigned char v): addr(a), val(v), addrOrVal(false) {} + }; + FixedQueue writes; + esfm_chip chip; + + unsigned char regPool[ESFM_REG_POOL_SIZE]; + short oldWrites[ESFM_REG_POOL_SIZE]; + short pendingWrites[ESFM_REG_POOL_SIZE]; + + int octave(int freq); + int toFreq(int freq); + void commitState(int ch, DivInstrument* ins); + + friend void putDispatchChip(void*,int); + friend void putDispatchChan(void*,int,int); + + inline void rWrite(unsigned short a, short v) { + if (!skipRegisterWrites && a 0 and o == 3 (last operator), + * or op[o].outLvl > 0 and (op[o].outLvl - op[o + 1].modIn) >= 2, + * or op[o].outLvl > 0 and op[o + 1].modIn == 0. + */ + inline bool KVS(int c, int o) { + if (c < 0 || c >= 18 || o < 0 || o >= 4) return false; + + if (chan[c].state.fm.op[o].kvs==1) return true; + + if (chan[c].state.fm.op[o].kvs==2) { + if (chan[c].state.esfm.op[o].outLvl==7) return true; + else if (chan[c].state.esfm.op[o].outLvl>0) { + if (o==3) return true; + else if ((chan[c].state.esfm.op[o].outLvl-chan[c].state.esfm.op[o+1].modIn) >= 2) { + return true; + } + else if (chan[c].state.esfm.op[o+1].modIn==0) { + return true; + } + } + } + return false; + } + + public: + void acquire(short** buf, size_t len); + int dispatch(DivCommand c); + void* getChanState(int chan); + DivMacroInt* getChanMacroInt(int ch); + unsigned short getPan(int ch); + DivDispatchOscBuffer* getOscBuffer(int chan); + unsigned char* getRegisterPool(); + int getRegisterPoolSize(); + int getOutputCount(); + void reset(); + void forceIns(); + void tick(bool sysTick=true); + void muteChannel(int ch, bool mute); + bool keyOffAffectsArp(int ch); + bool keyOffAffectsPorta(int ch); + void toggleRegisterDump(bool enable); + void notifyInsChange(int ins); + void notifyInsDeletion(void* ins); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); + void setFlags(const DivConfig& flags); + int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); + void quit(); + ~DivPlatformESFM(); +}; diff --git a/src/engine/song.h b/src/engine/song.h index 7a7e267c2..3a1c9baf4 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -131,7 +131,9 @@ enum DivSystem { DIV_SYSTEM_K053260, DIV_SYSTEM_TED, DIV_SYSTEM_C140, - DIV_SYSTEM_C219 + DIV_SYSTEM_C219, + // TODO: Ask Tilde to standardize! + DIV_SYSTEM_ESFM, }; enum DivEffectType: unsigned short { @@ -394,7 +396,7 @@ struct DivSong { std::vector effects; - DivInstrument nullIns, nullInsOPLL, nullInsOPL, nullInsOPLDrums, nullInsQSound; + DivInstrument nullIns, nullInsOPLL, nullInsOPL, nullInsOPLDrums, nullInsQSound, nullInsESFM; DivWavetable nullWave; DivSample nullSample; @@ -603,6 +605,45 @@ struct DivSong { nullInsOPLDrums.fm.op[3].mult=2; nullInsQSound.std.panLMacro.mode=true; + + // ESFM default instrument - port of OPM default instrument? + // TODO: adjust these values so they actually match + nullInsESFM.esfm.noise=0; + nullInsESFM.esfm.op[0].outLvl=0; + nullInsESFM.esfm.op[0].modIn=4; + nullInsESFM.fm.op[0].tl=21; + nullInsESFM.fm.op[0].ar=15; + nullInsESFM.fm.op[0].dr=9; + nullInsESFM.fm.op[0].sl=7; + nullInsESFM.fm.op[0].rr=3; + nullInsESFM.fm.op[0].mult=7; + + nullInsESFM.esfm.op[1].outLvl=0; + nullInsESFM.esfm.op[1].modIn=7; + nullInsESFM.fm.op[1].tl=24; + nullInsESFM.fm.op[1].ar=15; + nullInsESFM.fm.op[1].dr=2; + nullInsESFM.fm.op[1].sl=11; + nullInsESFM.fm.op[1].rr=2; + nullInsESFM.fm.op[1].mult=1; + + nullInsESFM.esfm.op[2].outLvl=0; + nullInsESFM.esfm.op[2].modIn=7; + nullInsESFM.fm.op[2].tl=17; + nullInsESFM.fm.op[2].ar=15; + nullInsESFM.fm.op[2].dr=4; + nullInsESFM.fm.op[2].sl=15; + nullInsESFM.fm.op[2].rr=3; + nullInsESFM.fm.op[2].mult=2; + + nullInsESFM.esfm.op[3].outLvl=7; + nullInsESFM.esfm.op[3].modIn=7; + nullInsESFM.fm.op[3].tl=0; + nullInsESFM.fm.op[3].ar=15; + nullInsESFM.fm.op[3].dr=3; + nullInsESFM.fm.op[3].sl=15; + nullInsESFM.fm.op[3].rr=9; + nullInsESFM.fm.op[3].mult=1; } }; diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index aee338493..769650723 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1917,6 +1917,18 @@ void DivEngine::registerSystems() { {0x12, {DIV_CMD_SNES_INVERT, "12xy: Set invert mode (x: surround; y: invert)"}}, } ); + + // TODO: ask Tilde to standardize! + sysDefs[DIV_SYSTEM_ESFM]=new DivSysDef( + "ESFM (TODO: gimme a better name)", NULL, 0xd0, 0, 18, true, false, 0, false, 0, + "TODO: give ESFM the beautiful description it deserves", + {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "FM 9", "FM 10", "FM 11", "FM 12", "FM 13", "FM 14", "FM 15", "FM 16", "FM 17", "FM 18"}, + {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18"}, + {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM}, + {DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM}, + {}, + {} + ); sysDefs[DIV_SYSTEM_DUMMY]=new DivSysDef( "Dummy System", NULL, 0xfd, 0, 8, false, true, 0, false, 0, diff --git a/src/gui/fmPreview.cpp b/src/gui/fmPreview.cpp index 5586d1c20..14b21e018 100644 --- a/src/gui/fmPreview.cpp +++ b/src/gui/fmPreview.cpp @@ -22,6 +22,7 @@ #include "../../extern/opn/ym3438.h" #include "../../extern/opm/opm.h" #include "../../extern/opl/opl3.h" +#include "../../extern/ESFMu/esfm.h" extern "C" { #include "../../extern/Nuked-OPLL/opll.h" } @@ -337,6 +338,60 @@ void FurnaceGUI::renderFMPreviewOPZ(const DivInstrumentFM& params, int pos) { } } +#define ESFM_WRITE(addr,val) \ + ESFM_write_reg_buffered_fast((esfm_chip*)fmPreviewESFM,(addr),(val)) + +void FurnaceGUI::renderFMPreviewESFM(const DivInstrumentFM& params, const DivInstrumentESFM& esfmParams, int pos) { + if (fmPreviewESFM==NULL) { + fmPreviewESFM=new esfm_chip; + pos=0; + } + short out[4]; + bool mult0=false; + + if (pos==0) { + ESFM_init((esfm_chip*)fmPreviewESFM); + // set native mode + ESFM_WRITE(0x105, 0x80); + + // set params + for (int i=0; i<4; i++) { + if ((params.op[i].mult&15)==0) { + mult0=true; + break; + } + } + + for (int i=0; i<4; i++) { + const DivInstrumentFM::Operator& op=params.op[i]; + const DivInstrumentESFM::Operator& opE=esfmParams.op[i]; + unsigned short baseAddr=i*8; + + ESFM_WRITE(baseAddr+0,(op.am<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0x0f)); + ESFM_WRITE(baseAddr+1,(op.ksl<<6)|(op.tl&0x3f)); + ESFM_WRITE(baseAddr+2,(op.ar<<4)|(op.dr&0x0f)); + ESFM_WRITE(baseAddr+3,(op.sl<<4)|(op.rr&0x0f)); + + // TODO: implement ct/dt detune... how will we do that? + ESFM_WRITE(baseAddr+4,0); + ESFM_WRITE(baseAddr+5,(opE.delay<<5)|(mult0?0x0a:0x06)); + + ESFM_WRITE(baseAddr+6,(op.dam<<7)|((op.dvb&1)<<6)|((opE.right&1)<<5)|((opE.left&1)<<4)|((opE.modIn&7)<<1)); + ESFM_WRITE(baseAddr+7,(opE.outLvl<<5)|((i==3?esfmParams.noise:0)<<3)|(op.ws&7)); + } + } + + // note on + ESFM_WRITE(0x240, 1); + + // render + for (int i=0; itype) { case DIV_INS_FM: @@ -354,6 +409,8 @@ void FurnaceGUI::renderFMPreview(const DivInstrument* ins, int pos) { case DIV_INS_OPZ: renderFMPreviewOPZ(ins->fm,pos); break; + case DIV_INS_ESFM: + renderFMPreviewESFM(ins->fm,ins->esfm,pos); default: break; } diff --git a/src/gui/gui.h b/src/gui/gui.h index a7b1f3ac1..0cff7b595 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -258,6 +258,7 @@ enum FurnaceGUIColors { GUI_COLOR_INSTR_TED, GUI_COLOR_INSTR_C140, GUI_COLOR_INSTR_C219, + GUI_COLOR_INSTR_ESFM, GUI_COLOR_INSTR_UNKNOWN, GUI_COLOR_CHANNEL_BG, @@ -1379,6 +1380,7 @@ class FurnaceGUI { void* fmPreviewOPLL; void* fmPreviewOPZ; void* fmPreviewOPZInterface; + void* fmPreviewESFM; String* editString; SDL_Event userEvent; @@ -2218,6 +2220,7 @@ class FurnaceGUI { void renderFMPreviewOPLL(const DivInstrumentFM& params, int pos=0); void renderFMPreviewOPL(const DivInstrumentFM& params, int pos=0); void renderFMPreviewOPZ(const DivInstrumentFM& params, int pos=0); + void renderFMPreviewESFM(const DivInstrumentFM& params, const DivInstrumentESFM& esfmParams, int pos=0); // these ones offer ctrl-wheel fine value changes. bool CWSliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format=NULL, ImGuiSliderFlags flags=0); diff --git a/src/gui/guiConst.cpp b/src/gui/guiConst.cpp index e2874c31c..4c3c7646c 100644 --- a/src/gui/guiConst.cpp +++ b/src/gui/guiConst.cpp @@ -175,6 +175,8 @@ const char* insTypes[DIV_INS_MAX+1][3]={ {"TED",ICON_FA_BAR_CHART,ICON_FUR_INS_TED}, {"C140",ICON_FA_VOLUME_UP,ICON_FUR_INS_C140}, {"C219",ICON_FA_VOLUME_UP,ICON_FUR_INS_C219}, + // TODO: add ICON_FUR_INS_ESFM to furIcons.h and font_furicon.cpp and update here + {"FM (ESFM)",ICON_FA_AREA_CHART,ICON_FA_AREA_CHART}, {NULL,ICON_FA_QUESTION,ICON_FA_QUESTION} }; @@ -941,6 +943,7 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={ D(GUI_COLOR_INSTR_TED,"",ImVec4(0.7f,0.6f,1.0f,1.0f)), D(GUI_COLOR_INSTR_C140,"",ImVec4(1.0f,1.0f,0.0f,1.0f)), D(GUI_COLOR_INSTR_C219,"",ImVec4(1.0f,0.8f,0.0f,1.0f)), + D(GUI_COLOR_INSTR_ESFM,"",ImVec4(0.3f,1.0f,0.9f,1.0f)), D(GUI_COLOR_INSTR_UNKNOWN,"",ImVec4(0.3f,0.3f,0.3f,1.0f)), D(GUI_COLOR_CHANNEL_BG,"",ImVec4(0.4f,0.6f,0.8f,1.0f)), @@ -1136,6 +1139,7 @@ const int availableSystems[]={ DIV_SYSTEM_C140, DIV_SYSTEM_C219, DIV_SYSTEM_PCM_DAC, + DIV_SYSTEM_ESFM, DIV_SYSTEM_PONG, 0 // don't remove this last one! }; @@ -1171,6 +1175,7 @@ const int chipsFM[]={ DIV_SYSTEM_OPL3, DIV_SYSTEM_OPL3_DRUMS, DIV_SYSTEM_OPZ, + DIV_SYSTEM_ESFM, 0 // don't remove this last one! }; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index f6c6310eb..61c815c9d 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -44,6 +44,14 @@ const char* fmParamNames[3][32]={ {"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "D2R", "RR", "SL", "TL", "RS", "MULT", "DT", "DT2", "SSG-EG", "AM", "DAM", "DVB", "EGT", "EGS", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2"} }; +const char* esfmParamNames[8]={ + "OP4 Noise Mode", "Envelope Delay", "Output Level", "Modulation Input Level", "Left Output", "Right Output", "Coarse Tune (semitones)", "Detune" +}; + +const char* esfmParamShortNames[8]={ + "RHY", "DLY", "OL", "MI", "L", "R", "CT", "DT" +}; + const char* fmParamShortNames[3][32]={ {"ALG", "FB", "FMS", "AMS", "A", "D", "D2", "R", "S", "TL", "RS", "ML", "DT", "DT2", "SSG", "AM", "DAM", "DVB", "SUS", "SUS", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS2", "AMS2"}, {"ALG", "FB", "FMS", "AMS", "A", "D", "SR", "R", "S", "TL", "KS", "ML", "DT", "DT2", "SSG", "AM", "AMD", "FMD", "EGT", "EGT", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS2", "AMS2"}, @@ -153,6 +161,10 @@ const char* oplDrumNames[4]={ "Snare", "Tom", "Top", "HiHat" }; +const char* esfmNoiseModeNames[4]={ + "Noise disabled", "Snare (square + noise)", "HiHat (ringmod from OP3, + noise)", "Top (ringmod from OP3)" +}; + const bool opIsOutput[8][4]={ {false,false,false,true}, {false,false,false,true}, @@ -206,8 +218,21 @@ enum FMParams { FM_AMS2=31 }; +enum ESFMParams { + ESFM_NOISE=0, + ESFM_DELAY=1, + ESFM_OUTLVL=2, + ESFM_MODIN=3, + ESFM_LEFT=4, + ESFM_RIGHT=5, + ESFM_CT=6, + ESFM_DT=7 +}; + #define FM_NAME(x) fmParamNames[settings.fmNames][x] #define FM_SHORT_NAME(x) fmParamShortNames[settings.fmNames][x] +#define ESFM_NAME(x) (esfmParamNames[x]) +#define ESFM_SHORT_NAME(x) (esfmParamShortNames[x]) const char* macroTypeLabels[4]={ ICON_FA_BAR_CHART "##IMacroType", @@ -2951,7 +2976,7 @@ void FurnaceGUI::drawInsEdit() { if (ImGui::BeginTabBar("insEditTab")) { std::vector macroList; - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPM) { + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPM || ins->type==DIV_INS_ESFM) { char label[32]; int opCount=4; if (ins->type==DIV_INS_OPLL) opCount=2; @@ -2985,171 +3010,205 @@ void FurnaceGUI::drawInsEdit() { } } - if (ImGui::BeginTable("fmDetails",3,ImGuiTableFlags_SizingStretchSame)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0); - ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.0); + if (ins->type!=DIV_INS_ESFM) { + if (ImGui::BeginTable("fmDetails",3,ImGuiTableFlags_SizingStretchSame)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0); + ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.0); - ImGui::TableNextRow(); - switch (ins->type) { - case DIV_INS_FM: - case DIV_INS_OPM: - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable - ImGui::TableNextColumn(); - if (fmPreviewOn) { - drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - if (!fmPreviewPaused) { - renderFMPreview(ins,1); - WAKE_UP; - } - } else { - drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - } - kvsConfig(ins); - break; - case DIV_INS_OPZ: - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_FMS2),ImGuiDataType_U8,&ins->fm.fms2,&_ZERO,&_SEVEN)); rightClickable - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable - P(CWSliderScalar(FM_NAME(FM_AMS2),ImGuiDataType_U8,&ins->fm.ams2,&_ZERO,&_THREE)); rightClickable - ImGui::TableNextColumn(); - if (fmPreviewOn) { - drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - if (!fmPreviewPaused) { - renderFMPreview(ins,1); - WAKE_UP; - } - } else { - drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - } - kvsConfig(ins); - - if (ImGui::Button("Request from TX81Z")) { - doAction(GUI_ACTION_TX81Z_REQUEST); - } - /* - ImGui::SameLine(); - if (ImGui::Button("Send to TX81Z")) { - showError("Coming soon!"); - } - */ - break; - case DIV_INS_OPL: - case DIV_INS_OPL_DRUMS: { - bool fourOp=(ins->fm.ops==4 || ins->type==DIV_INS_OPL_DRUMS); - bool drums=ins->fm.opllPreset==16; - int algMax=fourOp?3:1; - ImGui::TableNextColumn(); - ins->fm.alg&=algMax; - P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable - if (ins->type==DIV_INS_OPL) { - ImGui::BeginDisabled(ins->fm.opllPreset==16); - if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER - ins->fm.ops=fourOp?4:2; - } - ImGui::EndDisabled(); - } - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&algMax)); rightClickable - if (ins->type==DIV_INS_OPL) { - if (ImGui::Checkbox("Drums",&drums)) { PARAMETER - ins->fm.opllPreset=drums?16:0; - } - } - ImGui::TableNextColumn(); - if (fmPreviewOn) { - drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - if (!fmPreviewPaused) { - renderFMPreview(ins,1); - WAKE_UP; - } - } else { - drawAlgorithm(ins->fm.alg&algMax,fourOp?FM_ALGS_4OP_OPL:FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - } - kvsConfig(ins); - break; - } - case DIV_INS_OPLL: { - bool dc=fmOrigin.fms; - bool dm=fmOrigin.ams; - bool sus=ins->fm.alg; - ImGui::TableNextColumn(); - ImGui::BeginDisabled(ins->fm.opllPreset!=0); - P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&fmOrigin.fb,&_ZERO,&_SEVEN)); rightClickable - if (ImGui::Checkbox(FM_NAME(FM_DC),&dc)) { PARAMETER - fmOrigin.fms=dc; - } - ImGui::EndDisabled(); - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_NAME(FM_SUS),&sus)) { PARAMETER - ins->fm.alg=sus; - } - ImGui::BeginDisabled(ins->fm.opllPreset!=0); - if (ImGui::Checkbox(FM_NAME(FM_DM),&dm)) { PARAMETER - fmOrigin.ams=dm; - } - ImGui::EndDisabled(); - ImGui::TableNextColumn(); - if (fmPreviewOn) { - drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); - if (!fmPreviewPaused) { - renderFMPreview(ins,1); - WAKE_UP; - } - } else { - drawAlgorithm(0,FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); - } - kvsConfig(ins,false); - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - - if (ImGui::BeginCombo("##LLPreset",opllInsNames[presentWhich][ins->fm.opllPreset])) { - if (isPresentCount>1) { - if (ImGui::BeginTable("LLPresetList",isPresentCount)) { - ImGui::TableNextRow(ImGuiTableRowFlags_Headers); - for (int i=0; i<4; i++) { - if (!isPresent[i]) continue; - ImGui::TableNextColumn(); - ImGui::Text("%s name",opllVariants[i]); - } - for (int i=0; i<17; i++) { - ImGui::TableNextRow(); - for (int j=0; j<4; j++) { - if (!isPresent[j]) continue; - ImGui::TableNextColumn(); - ImGui::PushID(j*17+i); - if (ImGui::Selectable(opllInsNames[j][i])) { - ins->fm.opllPreset=i; - } - ImGui::PopID(); - } - } - ImGui::EndTable(); + ImGui::TableNextRow(); + switch (ins->type) { + case DIV_INS_FM: + case DIV_INS_OPM: + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; } } else { - for (int i=0; i<17; i++) { - if (ImGui::Selectable(opllInsNames[presentWhich][i])) { - ins->fm.opllPreset=i; - } + drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + } + kvsConfig(ins); + break; + case DIV_INS_OPZ: + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_FMS2),ImGuiDataType_U8,&ins->fm.fms2,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable + P(CWSliderScalar(FM_NAME(FM_AMS2),ImGuiDataType_U8,&ins->fm.ams2,&_ZERO,&_THREE)); rightClickable + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; + } + } else { + drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + } + kvsConfig(ins); + + if (ImGui::Button("Request from TX81Z")) { + doAction(GUI_ACTION_TX81Z_REQUEST); + } + /* + ImGui::SameLine(); + if (ImGui::Button("Send to TX81Z")) { + showError("Coming soon!"); + } + */ + break; + case DIV_INS_OPL: + case DIV_INS_OPL_DRUMS: { + bool fourOp=(ins->fm.ops==4 || ins->type==DIV_INS_OPL_DRUMS); + bool drums=ins->fm.opllPreset==16; + int algMax=fourOp?3:1; + ImGui::TableNextColumn(); + ins->fm.alg&=algMax; + P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable + if (ins->type==DIV_INS_OPL) { + ImGui::BeginDisabled(ins->fm.opllPreset==16); + if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER + ins->fm.ops=fourOp?4:2; + } + ImGui::EndDisabled(); + } + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&algMax)); rightClickable + if (ins->type==DIV_INS_OPL) { + if (ImGui::Checkbox("Drums",&drums)) { PARAMETER + ins->fm.opllPreset=drums?16:0; } } - ImGui::EndCombo(); + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; + } + } else { + drawAlgorithm(ins->fm.alg&algMax,fourOp?FM_ALGS_4OP_OPL:FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + } + kvsConfig(ins); + break; } - break; + case DIV_INS_OPLL: { + bool dc=fmOrigin.fms; + bool dm=fmOrigin.ams; + bool sus=ins->fm.alg; + ImGui::TableNextColumn(); + ImGui::BeginDisabled(ins->fm.opllPreset!=0); + P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&fmOrigin.fb,&_ZERO,&_SEVEN)); rightClickable + if (ImGui::Checkbox(FM_NAME(FM_DC),&dc)) { PARAMETER + fmOrigin.fms=dc; + } + ImGui::EndDisabled(); + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_NAME(FM_SUS),&sus)) { PARAMETER + ins->fm.alg=sus; + } + ImGui::BeginDisabled(ins->fm.opllPreset!=0); + if (ImGui::Checkbox(FM_NAME(FM_DM),&dm)) { PARAMETER + fmOrigin.ams=dm; + } + ImGui::EndDisabled(); + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; + } + } else { + drawAlgorithm(0,FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); + } + kvsConfig(ins,false); + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + + if (ImGui::BeginCombo("##LLPreset",opllInsNames[presentWhich][ins->fm.opllPreset])) { + if (isPresentCount>1) { + if (ImGui::BeginTable("LLPresetList",isPresentCount)) { + ImGui::TableNextRow(ImGuiTableRowFlags_Headers); + for (int i=0; i<4; i++) { + if (!isPresent[i]) continue; + ImGui::TableNextColumn(); + ImGui::Text("%s name",opllVariants[i]); + } + for (int i=0; i<17; i++) { + ImGui::TableNextRow(); + for (int j=0; j<4; j++) { + if (!isPresent[j]) continue; + ImGui::TableNextColumn(); + ImGui::PushID(j*17+i); + if (ImGui::Selectable(opllInsNames[j][i])) { + ins->fm.opllPreset=i; + } + ImGui::PopID(); + } + } + ImGui::EndTable(); + } + } else { + for (int i=0; i<17; i++) { + if (ImGui::Selectable(opllInsNames[presentWhich][i])) { + ins->fm.opllPreset=i; + } + } + } + ImGui::EndCombo(); + } + break; + } + case DIV_INS_ESFM: { + // unreachable + break; + } + default: + break; } - default: - break; + ImGui::EndTable(); + } + } else { + // ESFM + if (ImGui::BeginTable("fmDetails",3,ImGuiTableFlags_SizingStretchProp)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.50f); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.15f); + ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.35f); + + ImGui::TableNextRow(); + { + ImGui::TableNextColumn(); + P(CWSliderScalar(ESFM_NAME(ESFM_NOISE),ImGuiDataType_U8,&ins->esfm.noise,&_ZERO,&_THREE)); rightClickable + ImGui::TextUnformatted(esfmNoiseModeNames[ins->esfm.noise&3]); + ImGui::TableNextColumn(); + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; + } + } else { + //drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + ImGui::TextUnformatted("TODO: implement fancy ESFM\nauto algorithm drawing"); + } + kvsConfig(ins); + } + ImGui::EndTable(); } - ImGui::EndTable(); } if (((ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL) && ins->fm.opllPreset==16) || ins->type==DIV_INS_OPL_DRUMS) { @@ -3236,9 +3295,15 @@ void FurnaceGUI::drawInsEdit() { if (ins->type==DIV_INS_OPL ||ins->type==DIV_INS_OPL_DRUMS) numCols=13; if (ins->type==DIV_INS_OPLL) numCols=12; if (ins->type==DIV_INS_OPZ) numCols=19; + if (ins->type==DIV_INS_ESFM) numCols=19; if (ImGui::BeginTable("FMOperators",numCols,ImGuiTableFlags_SizingStretchProp|ImGuiTableFlags_BordersH|ImGuiTableFlags_BordersOuterV)) { // configure columns ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed); // op name + if (ins->type==DIV_INS_ESFM) { + ImGui::TableSetupColumn("c0e0",ImGuiTableColumnFlags_WidthStretch,0.05f); // outLvl + ImGui::TableSetupColumn("c0e1",ImGuiTableColumnFlags_WidthFixed); // -separator- + ImGui::TableSetupColumn("c0e2",ImGuiTableColumnFlags_WidthStretch,0.05f); // delay + } ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.05f); // ar ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.05f); // dr ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch,0.05f); // sl @@ -3253,13 +3318,20 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableSetupColumn("c8z0",ImGuiTableColumnFlags_WidthStretch,0.05f); // egs ImGui::TableSetupColumn("c8z1",ImGuiTableColumnFlags_WidthStretch,0.05f); // rev } + if (ins->type==DIV_INS_ESFM) { + ImGui::TableSetupColumn("c8e0",ImGuiTableColumnFlags_WidthStretch,0.05f); // outLvl + } ImGui::TableSetupColumn("c9",ImGuiTableColumnFlags_WidthStretch,0.05f); // mult if (ins->type==DIV_INS_OPZ) { ImGui::TableSetupColumn("c9z",ImGuiTableColumnFlags_WidthStretch,0.05f); // fine } - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + if (ins->type==DIV_INS_ESFM) { + ImGui::TableSetupColumn("c9e",ImGuiTableColumnFlags_WidthStretch,0.05f); // ct + } + + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM || ins->type==DIV_INS_ESFM) { ImGui::TableSetupColumn("c10",ImGuiTableColumnFlags_WidthStretch,0.05f); // dt } if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { @@ -3276,7 +3348,17 @@ void FurnaceGUI::drawInsEdit() { // header ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableNextColumn(); - + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_TEXT(ESFM_SHORT_NAME(ESFM_MODIN)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_MODIN)); + TOOLTIP_TEXT(ESFM_NAME(ESFM_MODIN)); + ImGui::TableNextColumn(); + ImGui::TableNextColumn(); + CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DELAY)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DELAY)); + TOOLTIP_TEXT(ESFM_NAME(ESFM_DELAY)); + } ImGui::TableNextColumn(); CENTER_TEXT(FM_SHORT_NAME(FM_AR)); ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR)); @@ -3332,6 +3414,12 @@ void FurnaceGUI::drawInsEdit() { ImGui::TextUnformatted(FM_SHORT_NAME(FM_REV)); TOOLTIP_TEXT(FM_NAME(FM_REV)); } + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_TEXT(ESFM_SHORT_NAME(ESFM_OUTLVL)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_OUTLVL)); + TOOLTIP_TEXT(ESFM_NAME(ESFM_OUTLVL)); + } ImGui::TableNextColumn(); CENTER_TEXT(FM_SHORT_NAME(FM_MULT)); ImGui::TextUnformatted(FM_SHORT_NAME(FM_MULT)); @@ -3342,6 +3430,12 @@ void FurnaceGUI::drawInsEdit() { ImGui::TextUnformatted(FM_SHORT_NAME(FM_FINE)); TOOLTIP_TEXT(FM_NAME(FM_FINE)); } + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_TEXT(ESFM_SHORT_NAME(ESFM_CT)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_CT)); + TOOLTIP_TEXT(ESFM_NAME(ESFM_CT)); + } ImGui::TableNextColumn(); if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { CENTER_TEXT(FM_SHORT_NAME(FM_DT)); @@ -3349,6 +3443,12 @@ void FurnaceGUI::drawInsEdit() { TOOLTIP_TEXT(FM_NAME(FM_DT)); ImGui::TableNextColumn(); } + if (ins->type==DIV_INS_ESFM) { + CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DT)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DT)); + TOOLTIP_TEXT(ESFM_NAME(ESFM_DT)); + ImGui::TableNextColumn(); + } if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { CENTER_TEXT(FM_SHORT_NAME(FM_DT2)); ImGui::TextUnformatted(FM_SHORT_NAME(FM_DT2)); @@ -3364,7 +3464,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::TextUnformatted("Other"); } ImGui::TableNextColumn(); - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ) { + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) { ImGui::TableNextColumn(); CENTER_TEXT(FM_NAME(FM_WS)); ImGui::TextUnformatted(FM_NAME(FM_WS)); @@ -3381,6 +3481,8 @@ void FurnaceGUI::drawInsEdit() { for (int i=0; itype!=DIV_INS_OPL_DRUMS)?opOrder[i]:i]; + DivInstrumentESFM::Operator& opE=ins->esfm.op[i]; + ImGui::TableNextRow(); ImGui::TableNextColumn(); @@ -3389,6 +3491,17 @@ void FurnaceGUI::drawInsEdit() { bool mod=true; if (ins->type==DIV_INS_OPL_DRUMS) { mod=false; + } else if (ins->type==DIV_INS_ESFM) { + // this is the same as the KVS heuristic in platform/esfm.h + if (opE.outLvl==7) mod=false; + else if (opE.outLvl>0) { + if (i==3) mod=false; + else { + DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; + if (opENext.modIn==0) mod=false; + else if ((opE.outLvl-opENext.modIn) >= 2) mod=false; + } + } } else if (opCount==4) { if (ins->type==DIV_INS_OPL) { if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false; @@ -3440,7 +3553,7 @@ void FurnaceGUI::drawInsEdit() { } else { ImGui::TextUnformatted(opNameLabel.c_str()); } - + // drag point OP_DRAG_POINT; @@ -3452,7 +3565,7 @@ void FurnaceGUI::drawInsEdit() { maxTl=63; } } - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) { + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { maxTl=63; } int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15; @@ -3461,6 +3574,18 @@ void FurnaceGUI::drawInsEdit() { bool vibOn=op.vib; bool susOn=op.sus; unsigned char ssgEnv=op.ssgEnv&7; + + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_VSLIDER; + P(CWVSliderScalar("##MODIN",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.modIn,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); + ImGui::TableNextColumn(); + opE.delay&=7; + CENTER_VSLIDER; + P(CWVSliderScalar("##DELAY",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.delay,&_ZERO,&_SEVEN)); rightClickable + } ImGui::TableNextColumn(); op.ar&=maxArDr; @@ -3528,6 +3653,12 @@ void FurnaceGUI::drawInsEdit() { P(CWVSliderScalar("##REV",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dam,&_ZERO,&_SEVEN)); rightClickable } + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_VSLIDER; + P(CWVSliderScalar("##OUTLVL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.outLvl,&_ZERO,&_SEVEN)); rightClickable + } + ImGui::TableNextColumn(); CENTER_VSLIDER; P(CWVSliderScalar("##MULT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN)); rightClickable @@ -3538,6 +3669,12 @@ void FurnaceGUI::drawInsEdit() { P(CWVSliderScalar("##FINE",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dvb,&_ZERO,&_FIFTEEN)); rightClickable } + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_VSLIDER; + P(CWVSliderScalar("##CT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_S8,&opE.ct,&_MINUS_TWELVE,&_TWELVE)); rightClickable + } + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7]; ImGui::TableNextColumn(); @@ -3608,6 +3745,42 @@ void FurnaceGUI::drawInsEdit() { op.ssgEnv=(op.ssgEnv&8)|(ssgEnv&7); } } + } else if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_VSLIDER; + P(CWVSliderScalar("##DT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable + + ImGui::TableNextColumn(); + bool amOn=op.am; + bool leftOn=opE.left; + bool rightOn=opE.right; + if (ImGui::BeginTable("panCheckboxes",2,ImGuiTableFlags_SizingStretchSame)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_LEFT),&leftOn)) { PARAMETER + opE.left=leftOn; + } + ImGui::TableNextColumn(); + if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER + opE.right=rightOn; + } + ImGui::EndTable(); + } + if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER + op.am=amOn; + } + if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER + op.vib=vibOn; + } + if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER + op.ksr=ksrOn; + } + if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER + op.sus=susOn; + } } else if (ins->type!=DIV_INS_OPM) { ImGui::TableNextColumn(); bool amOn=op.am; @@ -3632,7 +3805,7 @@ void FurnaceGUI::drawInsEdit() { } } - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ) { + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) { ImGui::TableNextColumn(); ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); ImGui::TableNextColumn(); diff --git a/src/gui/intConst.cpp b/src/gui/intConst.cpp index 167fdd7e8..cf0140e23 100644 --- a/src/gui/intConst.cpp +++ b/src/gui/intConst.cpp @@ -24,6 +24,7 @@ const int _ONE=1; const int _THREE=3; const int _SEVEN=7; const int _TEN=10; +const int _TWELVE=12; const int _FIFTEEN=15; const int _SIXTEEN=16; const int _THIRTY_ONE=31; @@ -35,5 +36,6 @@ const int _FIVE_HUNDRED_ELEVEN=511; const int _TWO_THOUSAND_FORTY_SEVEN=2047; const int _FOUR_THOUSAND_NINETY_FIVE=4095; const int _SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE=65535; +const int _MINUS_TWELVE=-12; const int _MINUS_ONE_HUNDRED_TWENTY_SEVEN=-127; const int _MINUS_ONE_HUNDRED_TWENTY_EIGHT=-128; diff --git a/src/gui/intConst.h b/src/gui/intConst.h index 082f421a7..18c4ae556 100644 --- a/src/gui/intConst.h +++ b/src/gui/intConst.h @@ -26,6 +26,7 @@ extern const int _ONE; extern const int _THREE; extern const int _SEVEN; extern const int _TEN; +extern const int _TWELVE; extern const int _FIFTEEN; extern const int _SIXTEEN; extern const int _THIRTY_ONE; @@ -37,5 +38,6 @@ extern const int _FIVE_HUNDRED_ELEVEN; extern const int _TWO_THOUSAND_FORTY_SEVEN; extern const int _FOUR_THOUSAND_NINETY_FIVE; extern const int _SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE; +extern const int _MINUS_TWELVE; extern const int _MINUS_ONE_HUNDRED_TWENTY_SEVEN; extern const int _MINUS_ONE_HUNDRED_TWENTY_EIGHT; From 696433c7846cba7b9f3ab1a405889ab9064e2462 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 14 Oct 2023 09:10:42 -0300 Subject: [PATCH 02/74] Fix operator order in GUI for ESFM --- CMakeLists.txt | 2 -- src/gui/insEdit.cpp | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f7a2a3dd9..57dec2fc9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,5 @@ cmake_minimum_required(VERSION 3.0) -set(CMAKE_EXPORT_COMPILE_COMMANDS on) - if (APPLE) set(MACOSX_DEPLOYMENT_TARGET 10.9) endif() diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 61c815c9d..c861d93b6 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -3480,7 +3480,7 @@ void FurnaceGUI::drawInsEdit() { float sliderHeight=32.0f*dpiScale; for (int i=0; itype!=DIV_INS_OPL_DRUMS)?opOrder[i]:i]; + DivInstrumentFM::Operator& op=fmOrigin.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i]; DivInstrumentESFM::Operator& opE=ins->esfm.op[i]; ImGui::TableNextRow(); @@ -3851,7 +3851,8 @@ void FurnaceGUI::drawInsEdit() { ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,ImVec2(8.0f*dpiScale,4.0f*dpiScale)); if (ImGui::BeginTable("AltFMOperators",columns,ImGuiTableFlags_SizingStretchSame|ImGuiTableFlags_BordersInner)) { for (int i=0; itype!=DIV_INS_OPL_DRUMS)?opOrder[i]:i]; + DivInstrumentFM::Operator& op=fmOrigin.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i]; + DivInstrumentESFM::Operator& opE=ins->esfm.op[i]; if ((settings.fmLayout!=6 && ((i+1)&1)) || i==0 || settings.fmLayout==5) ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::PushID(fmt::sprintf("op%d",i).c_str()); @@ -3861,6 +3862,17 @@ void FurnaceGUI::drawInsEdit() { bool mod=true; if (ins->type==DIV_INS_OPL_DRUMS) { mod=false; + } else if (ins->type==DIV_INS_ESFM) { + // this is the same as the KVS heuristic in platform/esfm.h + if (opE.outLvl==7) mod=false; + else if (opE.outLvl>0) { + if (i==3) mod=false; + else { + DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; + if (opENext.modIn==0) mod=false; + else if ((opE.outLvl-opENext.modIn) >= 2) mod=false; + } + } } else if (opCount==4) { if (ins->type==DIV_INS_OPL) { if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false; From 6733f4d1f4bd640023c1b3208caee696b5f5ea16 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 14 Oct 2023 14:00:31 -0300 Subject: [PATCH 03/74] Adding alternate layout for ESFM --- src/gui/insEdit.cpp | 178 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 161 insertions(+), 17 deletions(-) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index c861d93b6..002d6d9af 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -44,12 +44,12 @@ const char* fmParamNames[3][32]={ {"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "D2R", "RR", "SL", "TL", "RS", "MULT", "DT", "DT2", "SSG-EG", "AM", "DAM", "DVB", "EGT", "EGS", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2"} }; -const char* esfmParamNames[8]={ - "OP4 Noise Mode", "Envelope Delay", "Output Level", "Modulation Input Level", "Left Output", "Right Output", "Coarse Tune (semitones)", "Detune" +const char* esfmParamNames[9]={ + "OP4 Noise Mode", "Envelope Delay", "Output Level", "Modulation Input Level", "Left Output", "Right Output", "Coarse Tune (semitones)", "Coarse Tn.", "Detune" }; -const char* esfmParamShortNames[8]={ - "RHY", "DLY", "OL", "MI", "L", "R", "CT", "DT" +const char* esfmParamShortNames[9]={ + "RHY", "DL", "OL", "MI", "L", "R", "CT", "CT", "DT" }; const char* fmParamShortNames[3][32]={ @@ -226,7 +226,8 @@ enum ESFMParams { ESFM_LEFT=4, ESFM_RIGHT=5, ESFM_CT=6, - ESFM_DT=7 + ESFM_CT_SHORT=7, + ESFM_DT=8 }; #define FM_NAME(x) fmParamNames[settings.fmNames][x] @@ -3927,8 +3928,8 @@ void FurnaceGUI::drawInsEdit() { } float sliderHeight=200.0f*dpiScale; - float waveWidth=140.0*dpiScale; - float waveHeight=sliderHeight-ImGui::GetFrameHeightWithSpacing()*((ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL)?5.0f:4.5f); + float waveWidth=140.0*dpiScale*((ins->type==DIV_INS_ESFM)?0.8f:1.0f); + float waveHeight=sliderHeight-ImGui::GetFrameHeightWithSpacing()*((ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL || ins->type==DIV_INS_ESFM)?5.0f:4.5f); int maxTl=127; if (ins->type==DIV_INS_OPLL) { @@ -3938,7 +3939,7 @@ void FurnaceGUI::drawInsEdit() { maxTl=63; } } - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) { + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { maxTl=63; } int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15; @@ -3960,9 +3961,15 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextRow(); ImGui::TableNextColumn(); float textY=ImGui::GetCursorPosY(); - CENTER_TEXT_20(FM_SHORT_NAME(FM_AR)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR)); - TOOLTIP_TEXT(FM_NAME(FM_AR)); + if (ins->type==DIV_INS_ESFM) { + CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_DELAY)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DELAY)); + TOOLTIP_TEXT(ESFM_NAME(ESFM_DELAY)); + } else { + CENTER_TEXT_20(FM_SHORT_NAME(FM_AR)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR)); + TOOLTIP_TEXT(FM_NAME(FM_AR)); + } ImGui::TableNextColumn(); if (ins->type==DIV_INS_FM) { ImGui::Text("SSG-EG"); @@ -3972,14 +3979,18 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextColumn(); ImGui::Text("Envelope"); ImGui::TableNextColumn(); - CENTER_TEXT(FM_SHORT_NAME(FM_TL)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL)); - TOOLTIP_TEXT(FM_NAME(FM_TL)); // A/D/S/R ImGui::TableNextColumn(); + if (ins->type==DIV_INS_ESFM) { + opE.delay&=7; + P(CWVSliderScalar("##DELAY",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.delay,&_ZERO,&_SEVEN)); rightClickable + ImGui::SameLine(); + } + op.ar&=maxArDr; + float textX_AR=ImGui::GetCursorPosX(); P(CWVSliderScalar("##AR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); rightClickable ImGui::SameLine(); @@ -4016,8 +4027,15 @@ void FurnaceGUI::drawInsEdit() { } ImVec2 prevCurPos=ImGui::GetCursorPos(); - + // labels + if (ins->type==DIV_INS_ESFM) { + ImGui::SetCursorPos(ImVec2(textX_AR,textY)); + CENTER_TEXT_20(FM_SHORT_NAME(FM_AR)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR)); + TOOLTIP_TEXT(FM_NAME(FM_AR)); + } + ImGui::SetCursorPos(ImVec2(textX_DR,textY)); CENTER_TEXT_20(FM_SHORT_NAME(FM_DR)); ImGui::TextUnformatted(FM_SHORT_NAME(FM_DR)); @@ -4259,13 +4277,54 @@ void FurnaceGUI::drawInsEdit() { P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE,tempID)); rightClickable break; } + case DIV_INS_ESFM: + // waveform + drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight)); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable + + // params + ImGui::Separator(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); + P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_CT_SHORT)); + P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWELVE,&_TWELVE,tempID)); rightClickable + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_DT)); + P(CWSliderScalar("##DT",ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN,tempID)); rightClickable + + if (ImGui::BeginTable("panCheckboxes",2,ImGuiTableFlags_SizingStretchSame)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0f); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0f); + + float yPosOutsideTablePadding=ImGui::GetCursorPosY(); + bool leftOn=opE.left; + bool rightOn=opE.right; + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yPosOutsideTablePadding); + if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_LEFT),&leftOn)) { PARAMETER + opE.left=leftOn; + } + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yPosOutsideTablePadding); + if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER + opE.right=rightOn; + } + ImGui::EndTable(); + } + break; default: break; } ImGui::TableNextColumn(); float envHeight=sliderHeight;//-ImGui::GetStyle().ItemSpacing.y*2.0f; - if (ins->type==DIV_INS_OPZ) { + if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) { envHeight-=ImGui::GetFrameHeightWithSpacing()*2.0f; } drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,envHeight),ins->type); @@ -4309,9 +4368,58 @@ void FurnaceGUI::drawInsEdit() { } } + if (ins->type==DIV_INS_ESFM) { + ImGui::Separator(); + if (ImGui::BeginTable("FMParamsInnerESFM",2)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.64f); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.36f); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_SHORT_NAME(FM_KSL)); + P(CWSliderScalar("##KSL",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE,tempID)); rightClickable + + bool amOn=op.am; + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_KSR),&ksrOn)) { PARAMETER + op.ksr=ksrOn; + } + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (ImGui::BeginTable("vibAmCheckboxes",2)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0f); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0f); + + float yPosOutsideTablePadding=ImGui::GetCursorPosY(); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yPosOutsideTablePadding); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_VIB),&vibOn)) { PARAMETER + op.vib=vibOn; + } + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yPosOutsideTablePadding); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_AM),&amOn)) { PARAMETER + op.am=amOn; + } + ImGui::EndTable(); + } + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_SUS),&susOn)) { PARAMETER + op.sus=susOn; + } + + ImGui::EndTable(); + } + } + ImGui::TableNextColumn(); op.tl&=maxTl; - P(CWVSliderScalar("##TL",ImVec2(ImGui::GetFrameHeight(),sliderHeight-((ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM)?(ImGui::GetFrameHeightWithSpacing()+ImGui::CalcTextSize(FM_SHORT_NAME(FM_AM)).y+ImGui::GetStyle().ItemSpacing.y):0.0f)),ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable + float tlSliderWidth=(ins->type==DIV_INS_ESFM)?20.0f*dpiScale:ImGui::GetFrameHeight(); + float tlSliderHeight=sliderHeight-((ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM)?(ImGui::GetFrameHeightWithSpacing()+ImGui::CalcTextSize(FM_SHORT_NAME(FM_AM)).y+ImGui::GetStyle().ItemSpacing.y):0.0f); + float textX_tl=ImGui::GetCursorPosX(); + P(CWVSliderScalar("##TL",ImVec2(tlSliderWidth,tlSliderHeight),ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) { CENTER_TEXT(FM_SHORT_NAME(FM_AM)); @@ -4323,6 +4431,42 @@ void FurnaceGUI::drawInsEdit() { } } + if (ins->type==DIV_INS_ESFM) { + ImGui::SameLine(); + float textX_outLvl=ImGui::GetCursorPosX(); + P(CWVSliderScalar("##OUTLVL",ImVec2(tlSliderWidth,tlSliderHeight),ImGuiDataType_U8,&opE.outLvl,&_ZERO,&_SEVEN)); rightClickable + + ImGui::SameLine(); + float textX_modIn=ImGui::GetCursorPosX(); + P(CWVSliderScalar("##MODIN",ImVec2(tlSliderWidth,tlSliderHeight),ImGuiDataType_U8,&opE.modIn,&_ZERO,&_SEVEN)); rightClickable + + prevCurPos=ImGui::GetCursorPos(); + ImGui::SetCursorPos(ImVec2(textX_tl,textY)); + CENTER_TEXT_20(FM_SHORT_NAME(FM_TL)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL)); + TOOLTIP_TEXT(FM_NAME(FM_TL)); + + ImGui::SetCursorPos(ImVec2(textX_outLvl,textY)); + CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_OUTLVL)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_OUTLVL)); + TOOLTIP_TEXT(ESFM_NAME(ESFM_OUTLVL)); + + ImGui::SetCursorPos(ImVec2(textX_modIn,textY)); + CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_MODIN)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_MODIN)); + TOOLTIP_TEXT(ESFM_NAME(ESFM_MODIN)); + + ImGui::SetCursorPos(prevCurPos); + } else { + prevCurPos=ImGui::GetCursorPos(); + ImGui::SetCursorPos(ImVec2(textX_tl,textY)); + CENTER_TEXT(FM_SHORT_NAME(FM_TL)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL)); + TOOLTIP_TEXT(FM_NAME(FM_TL)); + + ImGui::SetCursorPos(prevCurPos); + } + ImGui::EndTable(); } ImGui::PopStyleVar(); From cfa0628a32127fbb1b3b85276ad709e3a5eec8b9 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 14 Oct 2023 17:07:34 -0300 Subject: [PATCH 04/74] Removing unused code --- src/engine/instrument.h | 53 ----------------------------------------- 1 file changed, 53 deletions(-) diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 91a6d2a6b..4c1778304 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -802,58 +802,6 @@ struct DivInstrumentESFM { op[3].outLvl=7; } -#if 0 - void syncFrom(DivInstrumentFM &other) { - for (int i=0; i<4; i++) { - this->op[i].am=other.op[i].am; - this->op[i].dam=other.op[i].dam; - this->op[i].ar=other.op[i].ar; - this->op[i].dr=other.op[i].dr; - this->op[i].mult=other.op[i].mult; - this->op[i].rr=other.op[i].rr; - this->op[i].sl=other.op[i].sl; - this->op[i].tl=other.op[i].tl; - this->op[i].ssgEnv=other.op[i].ssgEnv; - this->op[i].ksl=other.op[i].ksl; - this->op[i].vib=other.op[i].vib; - this->op[i].dvb=other.op[i].dvb; - this->op[i].ws=other.op[i].ws; - this->op[i].ksr=other.op[i].ksr; - this->op[i].ct=0; - // from dtTable at fmsharedbase.h - if (other.op[i].dt>=7){ - // trap out of range dt values - // TODO: check if any systems legitimately use dt values higher than 7 - this->op[i].dt=0; - } else { - this->op[i].dt=other.op[i].dt - 3; - } - } - } - - void syncTo(DivInstrumentFM &other) { - for (int i=0; i<4; i++) { - other.op[i].am=this->op[i].am; - other.op[i].dam=this->op[i].dam; - other.op[i].ar=this->op[i].ar; - other.op[i].dr=this->op[i].dr; - other.op[i].mult=this->op[i].mult; - other.op[i].rr=this->op[i].rr; - other.op[i].sl=this->op[i].sl; - other.op[i].tl=this->op[i].tl; - other.op[i].ssgEnv=this->op[i].ssgEnv; - other.op[i].ksl=this->op[i].ksl; - other.op[i].vib=this->op[i].vib; - other.op[i].dvb=this->op[i].dvb; - other.op[i].ws=this->op[i].ws; - other.op[i].ksr=this->op[i].ksr; - // dt field conversion is unfortunately lossy, as the dt field on DivInstrumentFM - // spans from 0..6 (eff. -3..3), while on DivInstrumentESFM it spans from -128..127. - other.op[i].dt=CLAMP(this->op[i].dt, -3, 3) + 3; - } - } -#endif - }; struct DivInstrument { @@ -873,7 +821,6 @@ struct DivInstrument { DivInstrumentES5506 es5506; DivInstrumentSNES snes; DivInstrumentESFM esfm; - // TODO I only added the esfm member here, still need to implement everything else related /** * these are internal functions. From 484b6f4411c43f3d4d71bbf752107f1c9a2daa84 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 14 Oct 2023 17:09:18 -0300 Subject: [PATCH 05/74] Adding classic layout; fixing operator swapping and KSL bit order --- src/gui/insEdit.cpp | 145 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 115 insertions(+), 30 deletions(-) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 002d6d9af..48b72b72f 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -44,12 +44,16 @@ const char* fmParamNames[3][32]={ {"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "D2R", "RR", "SL", "TL", "RS", "MULT", "DT", "DT2", "SSG-EG", "AM", "DAM", "DVB", "EGT", "EGS", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2"} }; -const char* esfmParamNames[9]={ - "OP4 Noise Mode", "Envelope Delay", "Output Level", "Modulation Input Level", "Left Output", "Right Output", "Coarse Tune (semitones)", "Coarse Tn.", "Detune" +const char* esfmParamLongNames[8]={ + "OP4 Noise Mode", "Envelope Delay", "Output Level", "Modulation Input Level", "Left Output", "Right Output", "Coarse Tune (semitones)", "Detune" }; -const char* esfmParamShortNames[9]={ - "RHY", "DL", "OL", "MI", "L", "R", "CT", "CT", "DT" +const char* esfmParamNames[8]={ + "OP4 Noise Mode", "Env. Delay", "Output Level", "ModInput", "Left", "Right", "Coarse Tn.", "Detune" +}; + +const char* esfmParamShortNames[8]={ + "RHY", "DL", "OL", "MI", "L", "R", "CT", "DT" }; const char* fmParamShortNames[3][32]={ @@ -226,12 +230,12 @@ enum ESFMParams { ESFM_LEFT=4, ESFM_RIGHT=5, ESFM_CT=6, - ESFM_CT_SHORT=7, - ESFM_DT=8 + ESFM_DT=7 }; #define FM_NAME(x) fmParamNames[settings.fmNames][x] #define FM_SHORT_NAME(x) fmParamShortNames[settings.fmNames][x] +#define ESFM_LONG_NAME(x) (esfmParamLongNames[x]) #define ESFM_NAME(x) (esfmParamNames[x]) #define ESFM_SHORT_NAME(x) (esfmParamShortNames[x]) @@ -2313,17 +2317,21 @@ void FurnaceGUI::alterSampleMap(int column, int val) { if (dragItem!=NULL) { \ if (dragItem->IsDataType("FUR_OP")) { \ if (opToMove!=i && opToMove>=0) { \ - int destOp=(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS)?opOrder[i]:i; \ - int sourceOp=(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS)?opOrder[opToMove]:opToMove; \ + int destOp=(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i; \ + int sourceOp=(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[opToMove]:opToMove; \ if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) { \ e->lockEngine([ins,destOp,sourceOp]() { \ ins->fm.op[destOp]=ins->fm.op[sourceOp]; \ + ins->esfm.op[destOp]=ins->esfm.op[sourceOp]; \ }); \ } else { \ e->lockEngine([ins,destOp,sourceOp]() { \ DivInstrumentFM::Operator origOp=ins->fm.op[sourceOp]; \ + DivInstrumentESFM::Operator origOpE=ins->esfm.op[sourceOp]; \ ins->fm.op[sourceOp]=ins->fm.op[destOp]; \ + ins->esfm.op[sourceOp]=ins->esfm.op[destOp]; \ ins->fm.op[destOp]=origOp; \ + ins->esfm.op[destOp]=origOpE; \ }); \ } \ PARAMETER; \ @@ -3192,7 +3200,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextRow(); { ImGui::TableNextColumn(); - P(CWSliderScalar(ESFM_NAME(ESFM_NOISE),ImGuiDataType_U8,&ins->esfm.noise,&_ZERO,&_THREE)); rightClickable + P(CWSliderScalar(ESFM_LONG_NAME(ESFM_NOISE),ImGuiDataType_U8,&ins->esfm.noise,&_ZERO,&_THREE)); rightClickable ImGui::TextUnformatted(esfmNoiseModeNames[ins->esfm.noise&3]); ImGui::TableNextColumn(); ImGui::TableNextColumn(); @@ -3353,12 +3361,12 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextColumn(); CENTER_TEXT(ESFM_SHORT_NAME(ESFM_MODIN)); ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_MODIN)); - TOOLTIP_TEXT(ESFM_NAME(ESFM_MODIN)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_MODIN)); ImGui::TableNextColumn(); ImGui::TableNextColumn(); CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DELAY)); ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DELAY)); - TOOLTIP_TEXT(ESFM_NAME(ESFM_DELAY)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DELAY)); } ImGui::TableNextColumn(); CENTER_TEXT(FM_SHORT_NAME(FM_AR)); @@ -3419,7 +3427,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextColumn(); CENTER_TEXT(ESFM_SHORT_NAME(ESFM_OUTLVL)); ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_OUTLVL)); - TOOLTIP_TEXT(ESFM_NAME(ESFM_OUTLVL)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_OUTLVL)); } ImGui::TableNextColumn(); CENTER_TEXT(FM_SHORT_NAME(FM_MULT)); @@ -3435,7 +3443,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextColumn(); CENTER_TEXT(ESFM_SHORT_NAME(ESFM_CT)); ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_CT)); - TOOLTIP_TEXT(ESFM_NAME(ESFM_CT)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_CT)); } ImGui::TableNextColumn(); if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { @@ -3447,7 +3455,7 @@ void FurnaceGUI::drawInsEdit() { if (ins->type==DIV_INS_ESFM) { CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DT)); ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DT)); - TOOLTIP_TEXT(ESFM_NAME(ESFM_DT)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DT)); ImGui::TableNextColumn(); } if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { @@ -3823,7 +3831,7 @@ void FurnaceGUI::drawInsEdit() { } ImGui::TableNextColumn(); - drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight),ins->type); + drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_ESFM)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight),ins->type); if (settings.separateFMColors) { popAccentColors(); @@ -3964,7 +3972,7 @@ void FurnaceGUI::drawInsEdit() { if (ins->type==DIV_INS_ESFM) { CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_DELAY)); ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DELAY)); - TOOLTIP_TEXT(ESFM_NAME(ESFM_DELAY)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DELAY)); } else { CENTER_TEXT_20(FM_SHORT_NAME(FM_AR)); ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR)); @@ -4290,7 +4298,7 @@ void FurnaceGUI::drawInsEdit() { P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_CT_SHORT)); + snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_CT)); P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWELVE,&_TWELVE,tempID)); rightClickable ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); @@ -4327,7 +4335,7 @@ void FurnaceGUI::drawInsEdit() { if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) { envHeight-=ImGui::GetFrameHeightWithSpacing()*2.0f; } - drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,envHeight),ins->type); + drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_ESFM)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,envHeight),ins->type); if (ins->type==DIV_INS_OPZ) { ImGui::Separator(); @@ -4377,8 +4385,12 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_SHORT_NAME(FM_KSL)); - P(CWSliderScalar("##KSL",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE,tempID)); rightClickable + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_KSL)); + int ksl=kslMap[op.ksl&3]; + if (CWSliderInt("##KSL",&ksl,0,3,tempID)) { + op.ksl=kslMap[ksl&3]; + PARAMETER; + } rightClickable bool amOn=op.am; ImGui::TableNextColumn(); @@ -4449,12 +4461,12 @@ void FurnaceGUI::drawInsEdit() { ImGui::SetCursorPos(ImVec2(textX_outLvl,textY)); CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_OUTLVL)); ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_OUTLVL)); - TOOLTIP_TEXT(ESFM_NAME(ESFM_OUTLVL)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_OUTLVL)); ImGui::SetCursorPos(ImVec2(textX_modIn,textY)); CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_MODIN)); ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_MODIN)); - TOOLTIP_TEXT(ESFM_NAME(ESFM_MODIN)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_MODIN)); ImGui::SetCursorPos(prevCurPos); } else { @@ -4495,7 +4507,8 @@ void FurnaceGUI::drawInsEdit() { } if (ImGui::BeginTable("FMOperators",columns,ImGuiTableFlags_SizingStretchSame)) { for (int i=0; itype!=DIV_INS_OPL_DRUMS)?opOrder[i]:i]; + DivInstrumentFM::Operator& op=fmOrigin.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i]; + DivInstrumentESFM::Operator& opE=ins->esfm.op[i]; if ((settings.fmLayout!=3 && ((i+1)&1)) || i==0 || settings.fmLayout==2) ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Separator(); @@ -4506,6 +4519,17 @@ void FurnaceGUI::drawInsEdit() { bool mod=true; if (ins->type==DIV_INS_OPL_DRUMS) { mod=false; + } else if (ins->type==DIV_INS_ESFM) { + // this is the same as the KVS heuristic in platform/esfm.h + if (opE.outLvl==7) mod=false; + else if (opE.outLvl>0) { + if (i==3) mod=false; + else { + DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; + if (opENext.modIn==0) mod=false; + else if ((opE.outLvl-opENext.modIn) >= 2) mod=false; + } + } } else if (opCount==4) { if (ins->type==DIV_INS_OPL) { if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false; @@ -4573,7 +4597,7 @@ void FurnaceGUI::drawInsEdit() { maxTl=63; } } - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) { + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { maxTl=63; } int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15; @@ -4583,14 +4607,14 @@ void FurnaceGUI::drawInsEdit() { bool vibOn=op.vib; bool susOn=op.sus; // don't you make fun of this one unsigned char ssgEnv=op.ssgEnv&7; - if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_OPZ && ins->type!=DIV_INS_OPM) { + if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_OPZ && ins->type!=DIV_INS_OPM && ins->type!=DIV_INS_ESFM) { ImGui::SameLine(); if (ImGui::Checkbox((ins->type==DIV_INS_OPLL)?FM_NAME(FM_EGS):"SSG On",&ssgOn)) { PARAMETER op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3); } } - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) { + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { ImGui::SameLine(); if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER op.sus=susOn; @@ -4606,12 +4630,22 @@ void FurnaceGUI::drawInsEdit() { } //52.0 controls vert scaling; default 96 - drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,52.0*dpiScale),ins->type); + drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_ESFM)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,52.0*dpiScale),ins->type); //P(CWSliderScalar(FM_NAME(FM_AR),ImGuiDataType_U8,&op.ar,&_ZERO,&_THIRTY_ONE)); rightClickable if (ImGui::BeginTable("opParams",2,ImGuiTableFlags_SizingStretchProp)) { ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); \ ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,0.0); \ + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + opE.delay&=7; + P(CWSliderScalar("##DELAY",ImGuiDataType_U8,&opE.delay,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",ESFM_NAME(ESFM_DELAY)); + } + ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); @@ -4796,7 +4830,24 @@ void FurnaceGUI::drawInsEdit() { } } - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ) { + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWELVE,&_TWELVE)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",ESFM_NAME(ESFM_CT)); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##DT",ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",ESFM_NAME(ESFM_DT)); + + } + + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) { ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); @@ -4807,11 +4858,33 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextColumn(); ImGui::Text("%s",FM_NAME(FM_WS)); } - + + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Separator(); + ImGui::TableNextColumn(); + ImGui::Separator(); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##OUTLVL",ImGuiDataType_U8,&opE.outLvl,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",ESFM_NAME(ESFM_OUTLVL)); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##MODIN",ImGuiDataType_U8,&opE.modIn,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",ESFM_NAME(ESFM_MODIN)); + } + ImGui::EndTable(); } - if (ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) { + if (ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER op.vib=vibOn; } @@ -4820,6 +4893,18 @@ void FurnaceGUI::drawInsEdit() { op.ksr=ksrOn; } } + + if (ins->type==DIV_INS_ESFM) { + bool leftOn=opE.left; + bool rightOn=opE.right; + if (ImGui::Checkbox(ESFM_NAME(ESFM_LEFT),&leftOn)) { PARAMETER + opE.left=leftOn; + } + ImGui::SameLine(); + if (ImGui::Checkbox(ESFM_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER + opE.right=rightOn; + } + } if (settings.separateFMColors) { popAccentColors(); From 84e0ec9dae70ebcd85f86458c510df3991edaace Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sun, 15 Oct 2023 11:44:12 -0300 Subject: [PATCH 06/74] bump ct range to 24; fix bug in modern layout for OPL and ESFM --- src/gui/insEdit.cpp | 25 ++++++++++++++++++++----- src/gui/intConst.cpp | 4 ++-- src/gui/intConst.h | 4 ++-- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 48b72b72f..8ff7735d8 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -3537,7 +3537,17 @@ void FurnaceGUI::drawInsEdit() { } } - if (i==0) sliderHeight=(ImGui::GetContentRegionAvail().y/opCount)-ImGui::GetStyle().ItemSpacing.y; + if (i==0) { + sliderHeight=(ImGui::GetContentRegionAvail().y/opCount)-ImGui::GetStyle().ItemSpacing.y; + float sliderMinHeightOPL=ImGui::GetFrameHeight()*4.0+ImGui::GetStyle().ItemSpacing.y*3.0; + float sliderMinHeightESFM=ImGui::GetFrameHeight()*5.0+ImGui::GetStyle().ItemSpacing.y*4.0; + if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL) && sliderHeighttype==DIV_INS_ESFM && sliderHeighttype==DIV_INS_ESFM) { ImGui::TableNextColumn(); CENTER_VSLIDER; - P(CWVSliderScalar("##CT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_S8,&opE.ct,&_MINUS_TWELVE,&_TWELVE)); rightClickable + P(CWVSliderScalar("##CT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR)); rightClickable } if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { @@ -3763,21 +3773,26 @@ void FurnaceGUI::drawInsEdit() { bool amOn=op.am; bool leftOn=opE.left; bool rightOn=opE.right; + ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*5.0-ImGui::GetStyle().ItemSpacing.y*4.0)); if (ImGui::BeginTable("panCheckboxes",2,ImGuiTableFlags_SizingStretchSame)) { ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0); + float yCoordBeforeTablePadding=ImGui::GetCursorPosY(); ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yCoordBeforeTablePadding); if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_LEFT),&leftOn)) { PARAMETER opE.left=leftOn; } ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yCoordBeforeTablePadding); if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER opE.right=rightOn; } ImGui::EndTable(); } + ImGui::SetCursorPosY(ImGui::GetCursorPosY()-0.5*ImGui::GetStyle().ItemSpacing.y); if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER op.am=amOn; } @@ -4299,7 +4314,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_CT)); - P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWELVE,&_TWELVE,tempID)); rightClickable + P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR,tempID)); rightClickable ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_DT)); @@ -4834,7 +4849,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWELVE,&_TWELVE)); rightClickable + P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR)); rightClickable ImGui::TableNextColumn(); ImGui::Text("%s",ESFM_NAME(ESFM_CT)); @@ -4893,7 +4908,7 @@ void FurnaceGUI::drawInsEdit() { op.ksr=ksrOn; } } - + if (ins->type==DIV_INS_ESFM) { bool leftOn=opE.left; bool rightOn=opE.right; diff --git a/src/gui/intConst.cpp b/src/gui/intConst.cpp index cf0140e23..da5c6065e 100644 --- a/src/gui/intConst.cpp +++ b/src/gui/intConst.cpp @@ -24,9 +24,9 @@ const int _ONE=1; const int _THREE=3; const int _SEVEN=7; const int _TEN=10; -const int _TWELVE=12; const int _FIFTEEN=15; const int _SIXTEEN=16; +const int _TWENTY_FOUR=24; const int _THIRTY_ONE=31; const int _SIXTY_FOUR=64; const int _ONE_HUNDRED=100; @@ -36,6 +36,6 @@ const int _FIVE_HUNDRED_ELEVEN=511; const int _TWO_THOUSAND_FORTY_SEVEN=2047; const int _FOUR_THOUSAND_NINETY_FIVE=4095; const int _SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE=65535; -const int _MINUS_TWELVE=-12; +const int _MINUS_TWENTY_FOUR=-24; const int _MINUS_ONE_HUNDRED_TWENTY_SEVEN=-127; const int _MINUS_ONE_HUNDRED_TWENTY_EIGHT=-128; diff --git a/src/gui/intConst.h b/src/gui/intConst.h index 18c4ae556..7acbbcf6b 100644 --- a/src/gui/intConst.h +++ b/src/gui/intConst.h @@ -26,9 +26,9 @@ extern const int _ONE; extern const int _THREE; extern const int _SEVEN; extern const int _TEN; -extern const int _TWELVE; extern const int _FIFTEEN; extern const int _SIXTEEN; +extern const int _TWENTY_FOUR; extern const int _THIRTY_ONE; extern const int _SIXTY_FOUR; extern const int _ONE_HUNDRED; @@ -38,6 +38,6 @@ extern const int _FIVE_HUNDRED_ELEVEN; extern const int _TWO_THOUSAND_FORTY_SEVEN; extern const int _FOUR_THOUSAND_NINETY_FIVE; extern const int _SIXTY_FIVE_THOUSAND_FIVE_HUNDRED_THIRTY_FIVE; -extern const int _MINUS_TWELVE; +extern const int _MINUS_TWENTY_FOUR; extern const int _MINUS_ONE_HUNDRED_TWENTY_SEVEN; extern const int _MINUS_ONE_HUNDRED_TWENTY_EIGHT; From 4a0295fd1f4eb34990d45c23bf1dfa55e27be644 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sun, 15 Oct 2023 19:46:07 -0300 Subject: [PATCH 07/74] WIP: adding fixed pitch mode; fix UB in ESFM driver --- src/engine/instrument.cpp | 4 +- src/engine/instrument.h | 9 ++-- src/engine/platform/esfm.cpp | 21 ++++++---- src/engine/platform/esfm.h | 1 + src/gui/insEdit.cpp | 81 +++++++++++++++++++++++++++++------- 5 files changed, 88 insertions(+), 28 deletions(-) diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index 0e1340e90..d92fe4504 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -245,6 +245,7 @@ bool DivInstrumentESFM::Operator::operator==(const DivInstrumentESFM::Operator& _C(modIn) && _C(left) && _C(right) && + _C(fixed) && _C(ct) && _C(dt) ); @@ -764,7 +765,7 @@ void DivInstrument::writeFeatureEF(SafeWriter* w) { DivInstrumentESFM::Operator& op=esfm.op[i]; w->writeC(((op.delay&7)<<5)|((op.outLvl&7)<<2)|((op.right&1)<<1)|(op.left&1)); - w->writeC(op.modIn&7); + w->writeC((op.fixed&1)<<3|(op.modIn&7)); w->writeC(op.ct); w->writeC(op.dt); } @@ -2644,6 +2645,7 @@ void DivInstrument::readFeatureEF(SafeReader& reader, short version) { next=reader.readC(); op.modIn=next&7; + op.fixed=(next>>3)&1; op.ct=reader.readC(); op.dt=reader.readC(); diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 4c1778304..6dfb49716 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -756,7 +756,7 @@ struct DivInstrumentSNES { // ESFM operator structure: // - DELAY, OUT, MOD, L, R, NOISE -// - Virtual: CT, DT, DTRAW +// - Virtual: CT, DT, FIXED // - In FM struct: AM, DAM, AR, DR, MULT, RR, SL, TL // - In FM struct: KSL, VIB, DVB, WS, SUS, KSR // - Not in struct: FNUML, FNUMH, BLOCK @@ -770,7 +770,7 @@ struct DivInstrumentESFM { // Only works on OP4, so putting it outside the Operator struct instead unsigned char noise; struct Operator { - unsigned char delay, outLvl, modIn, left, right; + unsigned char delay, outLvl, modIn, left, right, fixed; signed char ct, dt; bool operator==(const Operator& other); @@ -781,8 +781,9 @@ struct DivInstrumentESFM { delay(0), outLvl(0), modIn(0), - left(true), - right(true), + left(1), + right(1), + fixed(0), ct(0), dt(0) {} } op[4]; diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 0c1a11e97..5d08205c3 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -218,12 +218,17 @@ void DivPlatformESFM::tick(bool sysTick) { DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o]; int ct=(int)opE.ct; int dt=(int)opE.dt; - int opFreq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride+ct:chan[i].arpOff+ct,chan[i].fixedArp,false,octave(chan[i].baseFreq)*2,chan[i].pitch2+dt,chipClock,CHIP_FREQBASE); - if (opFreq<0) opFreq=0; - if (opFreq>131071) opFreq=131071; - int freqt=toFreq(opFreq); - chan[i].freqL[o]=freqt&0xff; - chan[i].freqH[o]=freqt>>8; + if (opE.fixed) { + chan[i].freqL[o]=opE.dt; + chan[i].freqH[o]=opE.ct&0x1f; + } else { + int opFreq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride+ct:chan[i].arpOff+ct,chan[i].fixedArp,false,octave(chan[i].baseFreq)*2,chan[i].pitch2+dt,chipClock,CHIP_FREQBASE); + if (opFreq<0) opFreq=0; + if (opFreq>131071) opFreq=131071; + int freqt=toFreq(opFreq); + chan[i].freqL[o]=freqt&0xff; + chan[i].freqH[o]=freqt>>8; + } immWrite(baseAddr+OFFSET_FREQL,chan[i].freqL[o]); immWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[i].freqH[o]|(opE.delay<<5)); } @@ -558,7 +563,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32 + o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.rr=c.value2&15; - rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|op.rr); + rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); } } else { unsigned int o = c.value; @@ -566,7 +571,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32 + o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.rr=c.value2&15; - rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|op.rr); + rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); } break; } diff --git a/src/engine/platform/esfm.h b/src/engine/platform/esfm.h index 558571a84..2c4a8c982 100644 --- a/src/engine/platform/esfm.h +++ b/src/engine/platform/esfm.h @@ -40,6 +40,7 @@ class DivPlatformESFM: public DivDispatch { SharedChannel(0), freqL{0, 0, 0, 0}, freqH{0, 0, 0, 0}, + hardReset(false), globalPan(3), macroVolMul(64) {} }; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 8ff7735d8..63600289e 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -44,16 +44,16 @@ const char* fmParamNames[3][32]={ {"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "D2R", "RR", "SL", "TL", "RS", "MULT", "DT", "DT2", "SSG-EG", "AM", "DAM", "DVB", "EGT", "EGS", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2"} }; -const char* esfmParamLongNames[8]={ - "OP4 Noise Mode", "Envelope Delay", "Output Level", "Modulation Input Level", "Left Output", "Right Output", "Coarse Tune (semitones)", "Detune" +const char* esfmParamLongNames[9]={ + "OP4 Noise Mode", "Envelope Delay", "Output Level", "Modulation Input Level", "Left Output", "Right Output", "Coarse Tune (semitones)", "Detune", "Fixed Frequency Mode" }; -const char* esfmParamNames[8]={ - "OP4 Noise Mode", "Env. Delay", "Output Level", "ModInput", "Left", "Right", "Coarse Tn.", "Detune" +const char* esfmParamNames[9]={ + "OP4 Noise Mode", "Env. Delay", "Output Level", "ModInput", "Left", "Right", "Coarse Tn.", "Detune", "Fixed" }; -const char* esfmParamShortNames[8]={ - "RHY", "DL", "OL", "MI", "L", "R", "CT", "DT" +const char* esfmParamShortNames[9]={ + "RHY", "DL", "OL", "MI", "L", "R", "CT", "DT", "FIX" }; const char* fmParamShortNames[3][32]={ @@ -230,7 +230,8 @@ enum ESFMParams { ESFM_LEFT=4, ESFM_RIGHT=5, ESFM_CT=6, - ESFM_DT=7 + ESFM_DT=7, + ESFM_FIXED=8 }; #define FM_NAME(x) fmParamNames[settings.fmNames][x] @@ -3951,7 +3952,7 @@ void FurnaceGUI::drawInsEdit() { } float sliderHeight=200.0f*dpiScale; - float waveWidth=140.0*dpiScale*((ins->type==DIV_INS_ESFM)?0.8f:1.0f); + float waveWidth=140.0*dpiScale*((ins->type==DIV_INS_ESFM)?0.85f:1.0f); float waveHeight=sliderHeight-ImGui::GetFrameHeightWithSpacing()*((ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL || ins->type==DIV_INS_ESFM)?5.0f:4.5f); int maxTl=127; @@ -4312,13 +4313,44 @@ void FurnaceGUI::drawInsEdit() { snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_CT)); - P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR,tempID)); rightClickable + if (opE.fixed) { + int block=(opE.ct>>2)&7; + int freqNum=((opE.ct&3)<<8)|((unsigned char)opE.dt); + ImGui::Text("Blk"); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Block"); + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + //ImVec2 cursorAlign=ImGui::GetCursorPos(); + if (ImGui::InputInt("##Block",&block,1,1)) { + if (block<0) block=0; + if (block>7) block=7; + opE.ct=(opE.ct&(~(7<<2)))|(block<<2); + } + + ImGui::Text("F"); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Frequency (F-Num)"); + } + ImGui::SameLine(); + //ImGui::SetCursorPos(ImVec2(cursorAlign.x,ImGui::GetCursorPosY())); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (ImGui::InputInt("##FreqNum",&freqNum,1,16)) { + if (freqNum<0) freqNum=0; + if (freqNum>1023) freqNum=1023; + opE.dt=freqNum&0xff; + opE.ct=(opE.ct&(~3))|(freqNum>>8); + } + } else { + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_CT)); + P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR,tempID)); rightClickable - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_DT)); - P(CWSliderScalar("##DT",ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN,tempID)); rightClickable + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_DT)); + P(CWSliderScalar("##DT",ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN,tempID)); rightClickable + } if (ImGui::BeginTable("panCheckboxes",2,ImGuiTableFlags_SizingStretchSame)) { ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0f); @@ -4347,9 +4379,12 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextColumn(); float envHeight=sliderHeight;//-ImGui::GetStyle().ItemSpacing.y*2.0f; - if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) { + if (ins->type==DIV_INS_OPZ) { envHeight-=ImGui::GetFrameHeightWithSpacing()*2.0f; } + if (ins->type==DIV_INS_ESFM) { + envHeight-=ImGui::GetFrameHeightWithSpacing()*3.0f; + } drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_ESFM)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,envHeight),ins->type); if (ins->type==DIV_INS_OPZ) { @@ -4408,6 +4443,7 @@ void FurnaceGUI::drawInsEdit() { } rightClickable bool amOn=op.am; + bool fixedOn=opE.fixed; ImGui::TableNextColumn(); if (ImGui::Checkbox(FM_SHORT_NAME(FM_KSR),&ksrOn)) { PARAMETER op.ksr=ksrOn; @@ -4430,12 +4466,27 @@ void FurnaceGUI::drawInsEdit() { if (ImGui::Checkbox(FM_SHORT_NAME(FM_AM),&amOn)) { PARAMETER op.am=amOn; } + + bool damOn=op.dam; + bool dvbOn=op.dvb; + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_DVB),&dvbOn)) { PARAMETER + op.dvb=dvbOn; + } + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_DAM),&damOn)) { PARAMETER + op.dam=damOn; + } ImGui::EndTable(); } ImGui::TableNextColumn(); if (ImGui::Checkbox(FM_SHORT_NAME(FM_SUS),&susOn)) { PARAMETER op.sus=susOn; } + if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER + opE.fixed=fixedOn; + } ImGui::EndTable(); } From 39001dcb6a53f7a9a299b84180729876f6b1d4e4 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Mon, 16 Oct 2023 16:57:04 -0300 Subject: [PATCH 08/74] Adding operator routing visualization --- src/engine/sysDef.cpp | 4 +- src/gui/gui.h | 1 + src/gui/insEdit.cpp | 111 +++++++++++++++++++++++++++++++++++--- src/gui/sysConf.cpp | 1 + src/gui/sysPartNumber.cpp | 2 + 5 files changed, 111 insertions(+), 8 deletions(-) diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index 769650723..1773ad4a6 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1920,8 +1920,8 @@ void DivEngine::registerSystems() { // TODO: ask Tilde to standardize! sysDefs[DIV_SYSTEM_ESFM]=new DivSysDef( - "ESFM (TODO: gimme a better name)", NULL, 0xd0, 0, 18, true, false, 0, false, 0, - "TODO: give ESFM the beautiful description it deserves", + "ESS ES1xxx-series (ESFM)", NULL, 0xd0, 0, 18, true, false, 0, false, 0, + "A unique FM synth featured in PC sound cards.\nBased on the OPL3 design, but with lots of its features extended.", {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "FM 9", "FM 10", "FM 11", "FM 12", "FM 13", "FM 14", "FM 15", "FM 16", "FM 17", "FM 18"}, {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18"}, {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM}, diff --git a/src/gui/gui.h b/src/gui/gui.h index 0cff7b595..b450be196 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -2209,6 +2209,7 @@ class FurnaceGUI { void drawSSGEnv(unsigned char type, const ImVec2& size); void drawWaveform(unsigned char type, bool opz, const ImVec2& size); void drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, const ImVec2& size); + void drawESFMAlgorithm(DivInstrumentESFM& esfm, const ImVec2& size); void drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, unsigned char d2r, unsigned char rr, unsigned char sl, unsigned char sus, unsigned char egt, unsigned char algOrGlobalSus, float maxTl, float maxArDr, float maxRr, const ImVec2& size, unsigned short instType); void drawGBEnv(unsigned char vol, unsigned char len, unsigned char sLen, bool dir, const ImVec2& size); bool drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& flags, bool modifyOnChange, bool fromMenu=false); diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 63600289e..f1b8ecabe 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -1164,6 +1164,110 @@ void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, cons } } +void FurnaceGUI::drawESFMAlgorithm(DivInstrumentESFM& esfm, const ImVec2& size) { + ImDrawList* dl=ImGui::GetWindowDrawList(); + ImGuiWindow* window=ImGui::GetCurrentWindow(); + + ImVec2 minArea=window->DC.CursorPos; + ImVec2 maxArea=ImVec2( + minArea.x+size.x, + minArea.y+size.y + ); + ImRect rect=ImRect(minArea,maxArea); + ImGuiStyle& style=ImGui::GetStyle(); + ImU32 colorM=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_MOD]); + ImU32 colorC=ImGui::GetColorU32(uiColors[GUI_COLOR_FM_CAR]); + ImU32 colorsL[8]; + for (int i=0; i<8; i++){ + float alpha=(float)i/7.0f; + ImVec4 color=uiColors[GUI_COLOR_FM_ALG_LINE]; + color.w *= alpha; + colorsL[i]=ImGui::GetColorU32(color); + } + ImGui::ItemSize(size,style.FramePadding.y); + if (ImGui::ItemAdd(rect,ImGui::GetID("alg"))) { + ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(uiColors[GUI_COLOR_FM_ALG_BG]),true,style.FrameRounding); + const float circleRadius=6.0f*dpiScale+1.0f; + //int modFb = esfm.op[0].modIn&7; + int mod12 = esfm.op[1].modIn&7; + int mod23 = esfm.op[2].modIn&7; + int mod34 = esfm.op[3].modIn&7; + int out1 = esfm.op[0].outLvl&7; + int out2 = esfm.op[1].outLvl&7; + int out3 = esfm.op[2].outLvl&7; + int out4 = esfm.op[3].outLvl&7; + bool isMod[4]; + for (int i=0; i<4; i++) { + DivInstrumentESFM::Operator& opE = esfm.op[i]; + isMod[i]=true; + if (opE.outLvl==7) isMod[i]=false; + else if (opE.outLvl>0) { + if (i==3) isMod[i]=false; + else { + DivInstrumentESFM::Operator& opENext=esfm.op[i+1]; + if (opENext.modIn==0) isMod[i]=false; + else if ((opE.outLvl-opENext.modIn) >= 2) isMod[i]=false; + } + } + } + + ImVec2 posOp1=ImLerp(rect.Min,rect.Max,ImVec2(0.2f,0.25f)); + ImVec2 posOp2=ImLerp(rect.Min,rect.Max,ImVec2(0.4f,0.25f)); + ImVec2 posOp3=ImLerp(rect.Min,rect.Max,ImVec2(0.6f,0.25f)); + ImVec2 posOp4=ImLerp(rect.Min,rect.Max,ImVec2(0.8f,0.25f)); + ImVec2 posBusbarOp1=ImLerp(rect.Min,rect.Max,ImVec2(0.2f,0.75f)); + ImVec2 posBusbarOp2=ImLerp(rect.Min,rect.Max,ImVec2(0.4f,0.75f)); + ImVec2 posBusbarOp3=ImLerp(rect.Min,rect.Max,ImVec2(0.6f,0.75f)); + ImVec2 posBusbarOp4=ImLerp(rect.Min,rect.Max,ImVec2(0.8f,0.75f)); + + ImVec2 posBusbarStart=ImLerp(rect.Min,rect.Max,ImVec2(0.15f,0.75f)); + ImVec2 posBusbarEnd=ImLerp(rect.Min,rect.Max,ImVec2(0.85f,0.75f)); + bool busbarStartSeen=false; + for (int i=0; i<4; i++) { + DivInstrumentESFM::Operator& opE=esfm.op[i]; + if (opE.outLvl>0) { + if (!busbarStartSeen) { + busbarStartSeen=true; + posBusbarStart=ImLerp(rect.Min,rect.Max,ImVec2(0.15f+0.2f*i,0.75f)); + } + posBusbarEnd=ImLerp(rect.Min,rect.Max,ImVec2(0.25f+0.2f*i,0.75f)); + } + } + + if (mod12) addAALine(dl,posOp1,posOp2,colorsL[mod12]); + if (mod23) addAALine(dl,posOp2,posOp3,colorsL[mod23]); + if (mod34) addAALine(dl,posOp3,posOp4,colorsL[mod34]); + if (out1) addAALine(dl,posOp1,posBusbarOp1,colorsL[out1]); + if (out2) addAALine(dl,posOp2,posBusbarOp2,colorsL[out2]); + if (out3) addAALine(dl,posOp3,posBusbarOp3,colorsL[out3]); + if (out4) addAALine(dl,posOp4,posBusbarOp4,colorsL[out4]); + + addAALine(dl,posBusbarStart,posBusbarEnd,colorsL[2]); + // addAALine(dl,posBusbarEnd,posBusbarEnd+ImVec2(-8.0f*dpiScale,-4.0f*dpiScale),colorsL[2]); + // addAALine(dl,posBusbarEnd,posBusbarEnd+ImVec2(-8.0f*dpiScale,4.0f*dpiScale),colorsL[2]); + // addAALine(dl,posBusbarStart+ImVec2(4.0f*dpiScale,-4.0f*dpiScale),posBusbarStart+ImVec2(4.0f*dpiScale,4.0f*dpiScale),colorsL[2]); + + dl->AddCircle(posOp1,6.0f*dpiScale+1.0f,isMod[0]?colorM:colorC); + dl->AddCircleFilled(posOp1,4.0f*dpiScale+1.0f,isMod[0]?colorM:colorC); + dl->AddCircleFilled(posOp2,4.0f*dpiScale+1.0f,isMod[1]?colorM:colorC); + dl->AddCircleFilled(posOp3,4.0f*dpiScale+1.0f,isMod[2]?colorM:colorC); + dl->AddCircleFilled(posOp4,4.0f*dpiScale+1.0f,isMod[3]?colorM:colorC); + + posOp1.x-=ImGui::CalcTextSize("1").x+circleRadius+3.0f*dpiScale; + posOp2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0f*dpiScale; + posOp3.x-=ImGui::CalcTextSize("3").x+circleRadius+3.0f*dpiScale; + posOp4.x-=ImGui::CalcTextSize("4").x+circleRadius+3.0f*dpiScale; + posOp1.y-=ImGui::CalcTextSize("1").y*0.5f; + posOp2.y-=ImGui::CalcTextSize("2").y*0.5f; + posOp3.y-=ImGui::CalcTextSize("3").y*0.5f; + posOp4.y-=ImGui::CalcTextSize("4").y*0.5f; + dl->AddText(posOp1,isMod[0]?colorM:colorC,"1"); + dl->AddText(posOp2,isMod[1]?colorM:colorC,"2"); + dl->AddText(posOp3,isMod[2]?colorM:colorC,"3"); + dl->AddText(posOp4,isMod[3]?colorM:colorC,"4"); + } +} + void FurnaceGUI::drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, unsigned char d2r, unsigned char rr, unsigned char sl, unsigned char sus, unsigned char egt, unsigned char algOrGlobalSus, float maxTl, float maxArDr, float maxRr, const ImVec2& size, unsigned short instType) { ImDrawList* dl=ImGui::GetWindowDrawList(); ImGuiWindow* window=ImGui::GetCurrentWindow(); @@ -3182,10 +3286,6 @@ void FurnaceGUI::drawInsEdit() { } break; } - case DIV_INS_ESFM: { - // unreachable - break; - } default: break; } @@ -3212,8 +3312,7 @@ void FurnaceGUI::drawInsEdit() { WAKE_UP; } } else { - //drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - ImGui::TextUnformatted("TODO: implement fancy ESFM\nauto algorithm drawing"); + drawESFMAlgorithm(ins->esfm, ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); } kvsConfig(ins); } diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index b8caa7390..813942d0c 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -2225,6 +2225,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl case DIV_SYSTEM_C219: break; case DIV_SYSTEM_YMU759: + case DIV_SYSTEM_ESFM: supportsCustomRate=false; ImGui::Text("nothing to configure"); break; diff --git a/src/gui/sysPartNumber.cpp b/src/gui/sysPartNumber.cpp index d71e65a98..3facab9cd 100644 --- a/src/gui/sysPartNumber.cpp +++ b/src/gui/sysPartNumber.cpp @@ -277,6 +277,8 @@ const char* FurnaceGUI::getSystemPartNumber(DivSystem sys, DivConfig& flags) { case DIV_SYSTEM_C219: return "C219"; break; + case DIV_SYSTEM_ESFM: + return "ES1xxx"; default: return FurnaceGUI::getSystemName(sys); break; From aee939bd3e441cb90c9dd8aec6785eaa7d0ee390 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 17 Oct 2023 15:47:08 -0300 Subject: [PATCH 09/74] Implement fixed frequency mode for modern and classic layouts --- src/gui/insEdit.cpp | 172 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 146 insertions(+), 26 deletions(-) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index f1b8ecabe..2565e9355 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -3692,6 +3692,7 @@ void FurnaceGUI::drawInsEdit() { bool ksrOn=op.ksr; bool vibOn=op.vib; bool susOn=op.sus; + bool fixedOn=opE.fixed; unsigned char ssgEnv=op.ssgEnv&7; if (ins->type==DIV_INS_ESFM) { @@ -3873,10 +3874,18 @@ void FurnaceGUI::drawInsEdit() { bool amOn=op.am; bool leftOn=opE.left; bool rightOn=opE.right; + ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*5.0-ImGui::GetStyle().ItemSpacing.y*4.0)); - if (ImGui::BeginTable("panCheckboxes",2,ImGuiTableFlags_SizingStretchSame)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0); + ImVec2 curPosBeforeDummy = ImGui::GetCursorPos(); + ImGui::Dummy(ImVec2(ImGui::GetFrameHeightWithSpacing()*2.0f+ImGui::CalcTextSize(FM_SHORT_NAME(FM_DAM)).x*2.0f,1.0f)); + ImGui::SetCursorPos(curPosBeforeDummy); + + if (ImGui::BeginTable("panCheckboxes",(fixedOn)?3:2,ImGuiTableFlags_SizingStretchProp)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,1.0); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,1.0); + if (fixedOn) { + ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,1.2); + } float yCoordBeforeTablePadding=ImGui::GetCursorPosY(); ImGui::TableNextRow(); @@ -3890,20 +3899,81 @@ void FurnaceGUI::drawInsEdit() { if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER opE.right=rightOn; } + if (fixedOn) { + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yCoordBeforeTablePadding); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_AM),&amOn)) { PARAMETER + op.am=amOn; + } + } + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_KSR),&ksrOn)) { PARAMETER + op.ksr=ksrOn; + } + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_SUS),&susOn)) { PARAMETER + op.sus=susOn; + } + if (fixedOn) { + bool damOn=op.dam; + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_DAM),&damOn)) { PARAMETER + op.dam=damOn; + } + } ImGui::EndTable(); } ImGui::SetCursorPosY(ImGui::GetCursorPosY()-0.5*ImGui::GetStyle().ItemSpacing.y); - if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER - op.am=amOn; + if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER + opE.fixed=fixedOn; } - if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER - op.vib=vibOn; - } - if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER - op.ksr=ksrOn; - } - if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER - op.sus=susOn; + if (ins->type==DIV_INS_ESFM) { + if (fixedOn) { + int block=(opE.ct>>2)&7; + int freqNum=((opE.ct&3)<<8)|((unsigned char)opE.dt); + if (ImGui::InputInt("Block",&block,1,1)) { + if (block<0) block=0; + if (block>7) block=7; + opE.ct=(opE.ct&(~(7<<2)))|(block<<2); + } + if (ImGui::InputInt("FreqNum",&freqNum,1,16)) { + if (freqNum<0) freqNum=0; + if (freqNum>1023) freqNum=1023; + opE.dt=freqNum&0xff; + opE.ct=(opE.ct&(~3))|(freqNum>>8); + } + } else { + if (ImGui::BeginTable("amVibCheckboxes",2,ImGuiTableFlags_SizingStretchSame)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0); + + float yCoordBeforeTablePadding=ImGui::GetCursorPosY(); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yCoordBeforeTablePadding); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_AM),&amOn)) { PARAMETER + op.am=amOn; + } + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yCoordBeforeTablePadding); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_VIB),&vibOn)) { PARAMETER + op.vib=vibOn; + } + bool damOn=op.dam; + bool dvbOn=op.dvb; + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_DAM),&damOn)) { PARAMETER + op.dam=damOn; + } + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_DVB),&dvbOn)) { PARAMETER + op.dvb=dvbOn; + } + ImGui::EndTable(); + } + } } } else if (ins->type!=DIV_INS_OPM) { ImGui::TableNextColumn(); @@ -3934,12 +4004,21 @@ void FurnaceGUI::drawInsEdit() { ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); ImGui::TableNextColumn(); - drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight-ImGui::GetFrameHeightWithSpacing())); + drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight-ImGui::GetFrameHeightWithSpacing()*((ins->type==DIV_INS_ESFM && fixedOn)?3.0f:1.0f))); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) { ImGui::SetTooltip("OPL2/3 only (last 4 waveforms are OPL3 only)"); } + if (ins->type==DIV_INS_ESFM && fixedOn) { + if (ImGui::Checkbox(FM_SHORT_NAME(FM_VIB),&vibOn)) { PARAMETER + op.vib=vibOn; + } + bool dvbOn=op.dvb; + if (ImGui::Checkbox(FM_SHORT_NAME(FM_DVB),&dvbOn)) { PARAMETER + op.dvb=dvbOn; + } + } } else if (ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPM) { ImGui::TableNextColumn(); ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); @@ -4996,19 +5075,46 @@ void FurnaceGUI::drawInsEdit() { } if (ins->type==DIV_INS_ESFM) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",ESFM_NAME(ESFM_CT)); + bool fixedOn=opE.fixed; + if (fixedOn) { + int block=(opE.ct>>2)&7; + int freqNum=((opE.ct&3)<<8)|((unsigned char)opE.dt); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (ImGui::InputInt("##Block",&block,1,1)) { + if (block<0) block=0; + if (block>7) block=7; + opE.ct=(opE.ct&(~(7<<2)))|(block<<2); + } + ImGui::TableNextColumn(); + ImGui::Text("Block"); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (ImGui::InputInt("##FreqNum",&freqNum,1,16)) { + if (freqNum<0) freqNum=0; + if (freqNum>1023) freqNum=1023; + opE.dt=freqNum&0xff; + opE.ct=(opE.ct&(~3))|(freqNum>>8); + } + ImGui::TableNextColumn(); + ImGui::Text("FreqNum"); + } else { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",ESFM_NAME(ESFM_CT)); - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##DT",ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",ESFM_NAME(ESFM_DT)); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##DT",ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",ESFM_NAME(ESFM_DT)); + } } @@ -5060,8 +5166,18 @@ void FurnaceGUI::drawInsEdit() { } if (ins->type==DIV_INS_ESFM) { + bool dvbOn=op.dvb; + bool damOn=op.dam; bool leftOn=opE.left; bool rightOn=opE.right; + bool fixedOn=opE.fixed; + if (ImGui::Checkbox(FM_NAME(FM_DVB),&dvbOn)) { PARAMETER + op.dvb=dvbOn; + } + ImGui::SameLine(); + if (ImGui::Checkbox(FM_NAME(FM_DAM),&damOn)) { PARAMETER + op.dam=damOn; + } if (ImGui::Checkbox(ESFM_NAME(ESFM_LEFT),&leftOn)) { PARAMETER opE.left=leftOn; } @@ -5069,6 +5185,10 @@ void FurnaceGUI::drawInsEdit() { if (ImGui::Checkbox(ESFM_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER opE.right=rightOn; } + ImGui::SameLine(); + if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER + opE.fixed=fixedOn; + } } if (settings.separateFMColors) { From a01ddd381e347413d44f81b01230490ed3082b10 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 17 Oct 2023 19:24:57 -0300 Subject: [PATCH 10/74] Implement ESFM macros --- src/engine/instrument.h | 1 - src/engine/platform/esfm.cpp | 91 +++++++++++++++++++++++++-- src/gui/insEdit.cpp | 119 ++++++++++++++++++++++------------- 3 files changed, 163 insertions(+), 48 deletions(-) diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 6dfb49716..80c5dc3a6 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -802,7 +802,6 @@ struct DivInstrumentESFM { op[3].modIn=7; op[3].outLvl=7; } - }; struct DivInstrument { diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 5d08205c3..92f32c78d 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -93,12 +93,15 @@ void DivPlatformESFM::tick(bool sysTick) { chan[i].freqChanged=true; } - // TODO: check why I disabled globalPan here? -#if 0 if (chan[i].std.panL.had) { chan[i].globalPan=((chan[i].std.panL.val&1)<<1)|((chan[i].std.panL.val&2)>>1); + for (int o=0; o<4; o++) { + unsigned short baseAddr=i*32 + o*8; + DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o]; + rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + } } -#endif if (chan[i].std.pitch.had) { if (chan[i].std.pitch.mode) { @@ -115,12 +118,28 @@ void DivPlatformESFM::tick(bool sysTick) { chan[i].keyOn=true; } } - + + if (chan[i].std.duty.had) { + int o=3; + unsigned short baseAddr=i*32 + o*8; + DivInstrumentESFM& ins=chan[i].state.esfm; + DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o]; + ins.noise=chan[i].std.duty.val; + + if (isMuted[i]) { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?ins.noise&3:0)<<3)|0); + } else { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?ins.noise&3:0)<<3)|((opE.outLvl&7)<<5)); + } + } + for (int o=0; o<4; o++) { unsigned short baseAddr=i*32 + o*8; DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o]; DivMacroInt::IntOp& m=chan[i].std.op[o]; - + if (m.am.had) { op.am=m.am.val; rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); @@ -173,6 +192,68 @@ void DivPlatformESFM::tick(bool sysTick) { rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); } } + + if (m.dam.had) { + op.dam=m.dam.val; + rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + } + if (m.dvb.had) { + op.dvb=m.dvb.val; + rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + } + if (m.rs.had) { + // operator panning + opE.left=(m.rs.val&2)!=0; + opE.right=(m.rs.val&1)!=0; + rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + } + if (m.d2r.had) { + // modIn + opE.modIn=m.d2r.val; + rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + } + + if (m.egt.had | m.ws.had) { + unsigned char noise=chan[i].state.esfm.noise&3; + if (m.egt.had) { + // outLvl + opE.outLvl=m.egt.val; + } + if (m.ws.had) { + op.ws=m.ws.val; + } + + if (isMuted[i]) { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + } else { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + } + } + + if (opE.fixed) { + if (m.ssg.had) { + opE.ct=(opE.ct&(~(7<<2)))|((m.ssg.val&7)<<2); + chan[i].freqChanged=true; + } + if (m.dt.had) { + opE.dt=m.dt.val&0xff; + opE.ct=(opE.ct&(~3))|((m.dt.val>>8)&3); + chan[i].freqChanged=true; + } + } else { + if (m.ssg.had) { + opE.ct=(signed char)m.ssg.val; + chan[i].freqChanged=true; + } + if (m.dt.had) { + opE.dt=(signed char)m.dt.val; + chan[i].freqChanged=true; + } + } + if (m.dt2.had) { + opE.delay=m.dt2.val; + rWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[i].freqH[o]|(opE.delay<<5)); + } } } diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 0a08bc93c..14648e33c 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -5216,46 +5216,48 @@ void FurnaceGUI::drawInsEdit() { ImGui::EndDisabled(); ImGui::EndTabItem(); } - if (ImGui::BeginTabItem("FM Macros")) { - if (ins->type==DIV_INS_OPLL) { - macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SUS),&ins->std.algMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); - macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FB),&ins->std.fbMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DC),&ins->std.fmsMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); - macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DM),&ins->std.amsMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); - } else { - macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_ALG),&ins->std.algMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FB),&ins->std.fbMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); - if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS) { - if (ins->type==DIV_INS_OPZ) { - // TODO: FMS2/AMS2 macros - macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FMS),&ins->std.fmsMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AMS),&ins->std.amsMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER])); - } else { - macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FMS),&ins->std.fmsMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AMS),&ins->std.amsMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER])); + if (ins->type!=DIV_INS_ESFM) { + if (ImGui::BeginTabItem("FM Macros")) { + if (ins->type==DIV_INS_OPLL) { + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SUS),&ins->std.algMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FB),&ins->std.fbMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DC),&ins->std.fmsMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DM),&ins->std.amsMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + } else { + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_ALG),&ins->std.algMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FB),&ins->std.fbMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); + if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS) { + if (ins->type==DIV_INS_OPZ) { + // TODO: FMS2/AMS2 macros + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FMS),&ins->std.fmsMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AMS),&ins->std.amsMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER])); + } else { + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FMS),&ins->std.fmsMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AMS),&ins->std.amsMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER])); + } } } + + if (ins->type==DIV_INS_FM) { + macroList.push_back(FurnaceGUIMacroDesc("LFO Speed",&ins->std.ex3Macro,0,8,96,uiColors[GUI_COLOR_MACRO_OTHER])); + } + if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + macroList.push_back(FurnaceGUIMacroDesc("AM Depth",&ins->std.ex1Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("PM Depth",&ins->std.ex2Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("LFO Speed",&ins->std.ex3Macro,0,255,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("LFO Shape",&ins->std.waveMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroLFOWaves)); + } + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) { + macroList.push_back(FurnaceGUIMacroDesc("OpMask",&ins->std.ex4Macro,0,4,128,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,fmOperatorBits)); + } else if (ins->type==DIV_INS_OPZ) { + macroList.push_back(FurnaceGUIMacroDesc("AM Depth 2",&ins->std.ex5Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("PM Depth 2",&ins->std.ex6Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("LFO2 Speed",&ins->std.ex7Macro,0,255,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("LFO2 Shape",&ins->std.ex8Macro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroLFOWaves)); + } + drawMacros(macroList,macroEditStateFM); + ImGui::EndTabItem(); } - - if (ins->type==DIV_INS_FM) { - macroList.push_back(FurnaceGUIMacroDesc("LFO Speed",&ins->std.ex3Macro,0,8,96,uiColors[GUI_COLOR_MACRO_OTHER])); - } - if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - macroList.push_back(FurnaceGUIMacroDesc("AM Depth",&ins->std.ex1Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("PM Depth",&ins->std.ex2Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("LFO Speed",&ins->std.ex3Macro,0,255,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("LFO Shape",&ins->std.waveMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroLFOWaves)); - } - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) { - macroList.push_back(FurnaceGUIMacroDesc("OpMask",&ins->std.ex4Macro,0,4,128,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,fmOperatorBits)); - } else if (ins->type==DIV_INS_OPZ) { - macroList.push_back(FurnaceGUIMacroDesc("AM Depth 2",&ins->std.ex5Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("PM Depth 2",&ins->std.ex6Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("LFO2 Speed",&ins->std.ex7Macro,0,255,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("LFO2 Shape",&ins->std.ex8Macro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroLFOWaves)); - } - drawMacros(macroList,macroEditStateFM); - ImGui::EndTabItem(); } for (int i=0; itype==DIV_INS_OPL_DRUMS) { @@ -5275,7 +5277,7 @@ void FurnaceGUI::drawInsEdit() { maxTl=63; } } - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) { + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { maxTl=63; } int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15; @@ -5307,6 +5309,33 @@ void FurnaceGUI::drawInsEdit() { macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_VIB),&ins->std.opMacros[ordi].vibMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_KSR),&ins->std.opMacros[ordi].ksrMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_EGS),&ins->std.opMacros[ordi].egtMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + } else if (ins->type==DIV_INS_ESFM) { + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_TL),&ins->std.opMacros[ordi].tlMacro,0,maxTl,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_DELAY),&ins->std.opMacros[ordi].dt2Macro,0,7,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AR),&ins->std.opMacros[ordi].arMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DR),&ins->std.opMacros[ordi].drMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SL),&ins->std.opMacros[ordi].slMacro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_RR),&ins->std.opMacros[ordi].rrMacro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_KSL),&ins->std.opMacros[ordi].kslMacro,0,3,32,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_MULT),&ins->std.opMacros[ordi].multMacro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_WS),&ins->std.opMacros[ordi].wsMacro,0,7,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_OUTLVL),&ins->std.opMacros[ordi].egtMacro,0,7,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_MODIN),&ins->std.opMacros[ordi].d2rMacro,0,7,64,uiColors[GUI_COLOR_MACRO_OTHER])); + if (ins->esfm.op[ordi].fixed) { + macroList.push_back(FurnaceGUIMacroDesc("Block",&ins->std.opMacros[ordi].ssgMacro,0,7,64,uiColors[GUI_COLOR_MACRO_OTHER],true)); + macroList.push_back(FurnaceGUIMacroDesc("FreqNum",&ins->std.opMacros[ordi].dtMacro,0,1023,160,uiColors[GUI_COLOR_MACRO_OTHER])); + } else { + macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_CT),&ins->std.opMacros[ordi].ssgMacro,-24,24,128,uiColors[GUI_COLOR_MACRO_OTHER],true)); + macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_DT),&ins->std.opMacros[ordi].dtMacro,-128,127,160,uiColors[GUI_COLOR_MACRO_OTHER])); + } + + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AM),&ins->std.opMacros[ordi].amMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_VIB),&ins->std.opMacros[ordi].vibMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DAM),&ins->std.opMacros[ordi].damMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DVB),&ins->std.opMacros[ordi].dvbMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_KSR),&ins->std.opMacros[ordi].ksrMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SUS),&ins->std.opMacros[ordi].susMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + macroList.push_back(FurnaceGUIMacroDesc("Op. Panning",&ins->std.opMacros[ordi].rsMacro,0,2,40,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); } else { macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_TL),&ins->std.opMacros[ordi].tlMacro,0,maxTl,128,uiColors[GUI_COLOR_MACRO_OTHER])); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AR),&ins->std.opMacros[ordi].arMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_OTHER])); @@ -6448,7 +6477,7 @@ void FurnaceGUI::drawInsEdit() { if (ins->type==DIV_INS_PCE || ins->type==DIV_INS_AY8930 || ins->type==DIV_INS_SM8521) { volMax=31; } - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_VERA || ins->type==DIV_INS_VRC6_SAW) { + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_VERA || ins->type==DIV_INS_VRC6_SAW || ins->type==DIV_INS_ESFM) { volMax=63; } if (ins->type==DIV_INS_AMIGA) { @@ -6628,6 +6657,10 @@ void FurnaceGUI::drawInsEdit() { dutyLabel="Echo Level"; dutyMax=32767; } + if (ins->type==DIV_INS_ESFM) { + dutyLabel="OP4 Noise Mode"; + dutyMax=3; + } const char* waveLabel="Waveform"; int waveMax=(ins->type==DIV_INS_VERA)?3:(MAX(1,e->song.waveLen-1)); @@ -6641,7 +6674,7 @@ void FurnaceGUI::drawInsEdit() { if (ins->type==DIV_INS_TIA || ins->type==DIV_INS_VIC || ins->type==DIV_INS_OPLL) waveMax=15; if (ins->type==DIV_INS_C64) waveMax=4; if (ins->type==DIV_INS_SAA1099) waveMax=2; - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) waveMax=0; + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM || ins->type==DIV_INS_ESFM) waveMax=0; if (ins->type==DIV_INS_MIKEY) waveMax=0; if (ins->type==DIV_INS_MULTIPCM) waveMax=0; if (ins->type==DIV_INS_ADPCMA) waveMax=0; @@ -6742,7 +6775,8 @@ void FurnaceGUI::drawInsEdit() { ins->type==DIV_INS_MSM6258 || ins->type==DIV_INS_VERA || ins->type==DIV_INS_ADPCMA || - ins->type==DIV_INS_ADPCMB) { + ins->type==DIV_INS_ADPCMB || + ins->type==DIV_INS_ESFM) { panMax=2; panSingle=true; } @@ -6885,7 +6919,8 @@ void FurnaceGUI::drawInsEdit() { ins->type==DIV_INS_K053260 || ins->type==DIV_INS_C140 || ins->type==DIV_INS_C219 || - ins->type==DIV_INS_TED) { + ins->type==DIV_INS_TED || + ins->type==DIV_INS_ESFM) { macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); } if (ex1Max>0) { From 6ce2fd0c9a710633353670eda3fc53da621df00a Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 17 Oct 2023 20:16:38 -0300 Subject: [PATCH 11/74] Adding ESFM letter-style instrument icon Thanks to Electric Keet for providing me with the icon! --- res/icons.sfd | 457 +++++++++++++++++++++++++++- res/icons.ttf | Bin 28552 -> 28880 bytes src/gui/font_furicon.cpp | 628 ++++++++++++++++++++------------------- src/gui/furIcons.h | 3 +- src/gui/guiConst.cpp | 3 +- 5 files changed, 762 insertions(+), 329 deletions(-) diff --git a/res/icons.sfd b/res/icons.sfd index f8e0f1efb..01fda2f2b 100644 --- a/res/icons.sfd +++ b/res/icons.sfd @@ -21,7 +21,7 @@ OS2Version: 0 OS2_WeightWidthSlopeOnly: 0 OS2_UseTypoMetrics: 0 CreationTime: 1691897631 -ModificationTime: 1693208149 +ModificationTime: 1697583349 PfmFamily: 81 TTFWeight: 400 TTFWidth: 5 @@ -47,13 +47,13 @@ LangName: 1033 Encoding: UnicodeBmp UnicodeInterp: none NameList: AGL For New Fonts -DisplaySize: -24 +DisplaySize: -48 AntiAlias: 1 FitToEm: 0 WinInfo: 57568 16 10 BeginPrivate: 0 EndPrivate -BeginChars: 65536 73 +BeginChars: 65536 74 StartChar: space Encoding: 32 32 0 @@ -4902,12 +4902,12 @@ Flags: HW LayerCount: 2 Fore SplineSet --717.389648438 -10.8251953125 m 8 +-717.389648438 -10.8251953125 m 12 NamedP: "baseline 2" - 717.249023438 -10.8251953125 l 1024 --896 0 m 8 + 717.249023438 -10.8251953125 l 1028 +-896 0 m 12 NamedP: "baseline 1" - 896 0 l 1024 + 896 0 l 1028 EndSplineSet Comment: "O" Colour: ff00ff @@ -5844,13 +5844,6 @@ LBearingChange: 0 UnicodeEnc: 0 InstructionsLength: 0 EndUndoOperation -UndoOperation -Index: 1 -Type: 3 -WasModified: 0 -WasOrder2: 0 -Layer: 2 -EndUndoOperation EndUndoes Redoes EndRedoes @@ -5965,5 +5958,441 @@ SplineSet 1449.28027344 618.5 l 1 EndSplineSet EndChar + +StartChar: uniE143 +Encoding: 57667 57667 73 +Width: 1792 +Flags: HW +LayerCount: 2 +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 +-7.4218750005 -10.8251953125 m 5 + -7.4218750005 -8.033203125 -7.4218750005 -5.2412109375 -7.4218750005 -2.44921875 c 5 + -5.67805989633 -2.44921875 -3.93424479217 -2.44921875 -2.190429688 -2.44921875 c 5 + -2.190429688 -2.84928385417 -2.190429688 -3.24934895833 -2.190429688 -3.6494140625 c 5 + -3.4824218755 -3.6494140625 -4.774414063 -3.6494140625 -6.0664062505 -3.6494140625 c 5 + -6.0664062505 -4.42545572917 -6.0664062505 -5.20149739583 -6.0664062505 -5.9775390625 c 5 + -4.91829427133 -5.9775390625 -3.77018229217 -5.9775390625 -2.622070313 -5.9775390625 c 5 + -2.622070313 -6.37727864583 -2.622070313 -6.77701822917 -2.622070313 -7.1767578125 c 5 + -3.77018229217 -7.1767578125 -4.91829427133 -7.1767578125 -6.0664062505 -7.1767578125 c 5 + -6.0664062505 -8.39290364583 -6.0664062505 -9.60904947917 -6.0664062505 -10.8251953125 c 5 + -6.51822916717 -10.8251953125 -6.97005208383 -10.8251953125 -7.4218750005 -10.8251953125 c 5 +5.9863281245 -4.4169921875 m 5 + 5.96614583283 -4.4169921875 5.94596354117 -4.4169921875 5.9257812495 -4.4169921875 c 5 + 5.70572916617 -4.869140625 5.48567708283 -5.3212890625 5.2656249995 -5.7734375 c 5 + 4.65364583283 -6.88932291667 4.04166666617 -8.00520833333 3.4296874995 -9.12109375 c 5 + 2.81770833283 -8.00520833333 2.20572916617 -6.88932291667 1.5937499995 -5.7734375 c 5 + 1.37369791617 -5.3212890625 1.15364583283 -4.869140625 0.9335937495 -4.4169921875 c 5 + 0.913736978667 -4.4169921875 0.893880207833 -4.4169921875 0.874023437 -4.4169921875 c 5 + 0.874023437 -6.55305989583 0.874023437 -8.68912760417 0.874023437 -10.8251953125 c 5 + 0.442057291167 -10.8251953125 0.0100911453333 -10.8251953125 -0.4218750005 -10.8251953125 c 5 + -0.4218750005 -8.033203125 -0.4218750005 -5.2412109375 -0.4218750005 -2.44921875 c 5 + 0.113932291167 -2.44921875 0.649739582833 -2.44921875 1.1855468745 -2.44921875 c 5 + 1.9335937495 -3.869140625 2.6816406245 -5.2890625 3.4296874995 -6.708984375 c 5 + 3.45377604117 -6.708984375 3.47786458283 -6.708984375 3.5019531245 -6.708984375 c 5 + 4.2499999995 -5.2890625 4.9980468745 -3.869140625 5.7460937495 -2.44921875 c 5 + 6.25813802033 -2.44921875 6.77018229117 -2.44921875 7.282226562 -2.44921875 c 5 + 7.282226562 -5.2412109375 7.282226562 -8.033203125 7.282226562 -10.8251953125 c 5 + 6.85026041617 -10.8251953125 6.41829427033 -10.8251953125 5.9863281245 -10.8251953125 c 5 + 5.9863281245 -8.68912760417 5.9863281245 -6.55305989583 5.9863281245 -4.4169921875 c 5 +-6.271484375 0 m 5 + -6.271484375 2.7919921875 -6.271484375 5.583984375 -6.271484375 8.3759765625 c 5 + -4.48372395833 8.3759765625 -2.69596354167 8.3759765625 -0.908203125 8.3759765625 c 5 + -0.908203125 7.97591145833 -0.908203125 7.57584635417 -0.908203125 7.17578125 c 5 + -2.244140625 7.17578125 -3.580078125 7.17578125 -4.916015625 7.17578125 c 5 + -4.916015625 6.39973958333 -4.916015625 5.62369791667 -4.916015625 4.84765625 c 5 + -3.70377604167 4.84765625 -2.49153645833 4.84765625 -1.279296875 4.84765625 c 5 + -1.279296875 4.44791666667 -1.279296875 4.04817708333 -1.279296875 3.6484375 c 5 + -2.49153645833 3.6484375 -3.70377604167 3.6484375 -4.916015625 3.6484375 c 5 + -4.916015625 2.83235677083 -4.916015625 2.01627604167 -4.916015625 1.2001953125 c 5 + -3.580078125 1.2001953125 -2.244140625 1.2001953125 -0.908203125 1.2001953125 c 5 + -0.908203125 0.800130208333 -0.908203125 0.400065104167 -0.908203125 0 c 5 + -2.69596354167 -0 -4.48372395833 0 -6.271484375 0 c 5 +3.236328125 -0.1435546875 m 4 + 2.53125 -0.1435546875 1.93359375 -0.0156250000001 1.44140625 0.240234375 c 132 + 0.94921875 0.49609375 0.52734375 0.83984375 0.17578125 1.2724609375 c 5 + 0.487630208334 1.564453125 0.799479166666 1.8564453125 1.111328125 2.1484375 c 5 + 1.408203125 1.7880859375 1.734375 1.515625 2.08984375 1.33203125 c 132 + 2.4453125 1.1484375 2.8515625 1.0556640625 3.30859375 1.0556640625 c 4 + 3.84375 1.0556640625 4.248046875 1.17578125 4.51953125 1.416015625 c 132 + 4.791015625 1.65625 4.927734375 1.98046875 4.927734375 2.3876953125 c 4 + 4.927734375 2.7158203125 4.83203125 2.9755859375 4.640625 3.16796875 c 132 + 4.447265625 3.3603515625 4.107421875 3.50390625 3.619140625 3.599609375 c 5 + 3.37109375 3.64388020833 3.123046875 3.68815104167 2.875 3.732421875 c 5 + 2.060546875 3.8837890625 1.447265625 4.15234375 1.0390625 4.5361328125 c 132 + 0.630859375 4.919921875 0.427734375 5.4482421875 0.427734375 6.1201171875 c 4 + 0.427734375 6.48828125 0.498046875 6.822265625 0.638671875 7.1220703125 c 132 + 0.77734375 7.421875 0.974609375 7.673828125 1.2265625 7.8779296875 c 132 + 1.478515625 8.08203125 1.783203125 8.240234375 2.14453125 8.3515625 c 132 + 2.50390625 8.4638671875 2.908203125 8.51953125 3.35546875 8.51953125 c 4 + 3.98828125 8.51953125 4.53515625 8.41015625 5 8.1904296875 c 132 + 5.462890625 7.9697265625 5.859375 7.65234375 6.1875 7.236328125 c 5 + 5.87174479167 6.95638020833 5.55598958333 6.67643229167 5.240234375 6.396484375 c 5 + 5.0234375 6.67578125 4.759765625 6.900390625 4.447265625 7.068359375 c 132 + 4.13671875 7.236328125 3.748046875 7.3203125 3.283203125 7.3203125 c 4 + 2.8046875 7.3203125 2.431640625 7.2236328125 2.16796875 7.0322265625 c 132 + 1.904296875 6.83984375 1.771484375 6.5595703125 1.771484375 6.1923828125 c 4 + 1.771484375 5.83984375 1.87890625 5.578125 2.095703125 5.40625 c 132 + 2.3125 5.234375 2.6484375 5.103515625 3.103515625 5.015625 c 5 + 3.3515625 4.9638671875 3.599609375 4.912109375 3.84765625 4.8603515625 c 5 + 4.6875 4.7001953125 5.302734375 4.427734375 5.689453125 4.0439453125 c 132 + 6.078125 3.66015625 6.271484375 3.1318359375 6.271484375 2.4599609375 c 4 + 6.271484375 2.068359375 6.203125 1.7119140625 6.068359375 1.3916015625 c 132 + 5.931640625 1.072265625 5.734375 0.7978515625 5.474609375 0.5703125 c 132 + 5.212890625 0.341796875 4.896484375 0.166015625 4.51953125 0.0419921875 c 132 + 4.14453125 -0.0820312500001 3.71484375 -0.1435546875 3.236328125 -0.1435546875 c 4 +EndSplineSet +EndUndoOperation +UndoOperation +Index: 1 +Type: 3 +WasModified: 1 +WasOrder2: 0 +Layer: 2 +EndUndoOperation +UndoOperation +Index: 2 +Type: 1 +WasModified: 1 +WasOrder2: 0 +Layer: 2 +Width: 1792 +VWidth: 1792 +LBearingChange: 0 +UnicodeEnc: 0 +InstructionsLength: 0 +SplineSet +-7.4218750005 -10.8251953125 m 1 + -7.4218750005 -8.033203125 -7.4218750005 -5.2412109375 -7.4218750005 -2.44921875 c 1 + -5.67805989633 -2.44921875 -3.93424479217 -2.44921875 -2.190429688 -2.44921875 c 1 + -2.190429688 -2.84928385417 -2.190429688 -3.24934895833 -2.190429688 -3.6494140625 c 1 + -3.4824218755 -3.6494140625 -4.774414063 -3.6494140625 -6.0664062505 -3.6494140625 c 1 + -6.0664062505 -4.42545572917 -6.0664062505 -5.20149739583 -6.0664062505 -5.9775390625 c 1 + -4.91829427133 -5.9775390625 -3.77018229217 -5.9775390625 -2.622070313 -5.9775390625 c 1 + -2.622070313 -6.37727864583 -2.622070313 -6.77701822917 -2.622070313 -7.1767578125 c 1 + -3.77018229217 -7.1767578125 -4.91829427133 -7.1767578125 -6.0664062505 -7.1767578125 c 1 + -6.0664062505 -8.39290364583 -6.0664062505 -9.60904947917 -6.0664062505 -10.8251953125 c 1 + -6.51822916717 -10.8251953125 -6.97005208383 -10.8251953125 -7.4218750005 -10.8251953125 c 1 +5.9863281245 -4.4169921875 m 1 + 5.96614583283 -4.4169921875 5.94596354117 -4.4169921875 5.9257812495 -4.4169921875 c 1 + 5.70572916617 -4.869140625 5.48567708283 -5.3212890625 5.2656249995 -5.7734375 c 1 + 4.65364583283 -6.88932291667 4.04166666617 -8.00520833333 3.4296874995 -9.12109375 c 1 + 2.81770833283 -8.00520833333 2.20572916617 -6.88932291667 1.5937499995 -5.7734375 c 1 + 1.37369791617 -5.3212890625 1.15364583283 -4.869140625 0.9335937495 -4.4169921875 c 1 + 0.913736978667 -4.4169921875 0.893880207833 -4.4169921875 0.874023437 -4.4169921875 c 1 + 0.874023437 -6.55305989583 0.874023437 -8.68912760417 0.874023437 -10.8251953125 c 1 + 0.442057291167 -10.8251953125 0.0100911453333 -10.8251953125 -0.4218750005 -10.8251953125 c 1 + -0.4218750005 -8.033203125 -0.4218750005 -5.2412109375 -0.4218750005 -2.44921875 c 1 + 0.113932291167 -2.44921875 0.649739582833 -2.44921875 1.1855468745 -2.44921875 c 1 + 1.9335937495 -3.869140625 2.6816406245 -5.2890625 3.4296874995 -6.708984375 c 1 + 3.45377604117 -6.708984375 3.47786458283 -6.708984375 3.5019531245 -6.708984375 c 1 + 4.2499999995 -5.2890625 4.9980468745 -3.869140625 5.7460937495 -2.44921875 c 1 + 6.25813802033 -2.44921875 6.77018229117 -2.44921875 7.282226562 -2.44921875 c 1 + 7.282226562 -5.2412109375 7.282226562 -8.033203125 7.282226562 -10.8251953125 c 1 + 6.85026041617 -10.8251953125 6.41829427033 -10.8251953125 5.9863281245 -10.8251953125 c 1 + 5.9863281245 -8.68912760417 5.9863281245 -6.55305989583 5.9863281245 -4.4169921875 c 1 +-6.271484375 0 m 1 + -6.271484375 2.7919921875 -6.271484375 5.583984375 -6.271484375 8.3759765625 c 1 + -4.48372395833 8.3759765625 -2.69596354167 8.3759765625 -0.908203125 8.3759765625 c 1 + -0.908203125 7.97591145833 -0.908203125 7.57584635417 -0.908203125 7.17578125 c 1 + -2.244140625 7.17578125 -3.580078125 7.17578125 -4.916015625 7.17578125 c 1 + -4.916015625 6.39973958333 -4.916015625 5.62369791667 -4.916015625 4.84765625 c 1 + -3.70377604167 4.84765625 -2.49153645833 4.84765625 -1.279296875 4.84765625 c 1 + -1.279296875 4.44791666667 -1.279296875 4.04817708333 -1.279296875 3.6484375 c 1 + -2.49153645833 3.6484375 -3.70377604167 3.6484375 -4.916015625 3.6484375 c 1 + -4.916015625 2.83235677083 -4.916015625 2.01627604167 -4.916015625 1.2001953125 c 1 + -3.580078125 1.2001953125 -2.244140625 1.2001953125 -0.908203125 1.2001953125 c 1 + -0.908203125 0.800130208333 -0.908203125 0.400065104167 -0.908203125 0 c 1 + -2.69596354167 -0 -4.48372395833 0 -6.271484375 0 c 1 +3.236328125 -0.1435546875 m 0 + 2.53125 -0.1435546875 1.93359375 -0.0156250000001 1.44140625 0.240234375 c 128 + 0.94921875 0.49609375 0.52734375 0.83984375 0.17578125 1.2724609375 c 1 + 0.487630208334 1.564453125 0.799479166666 1.8564453125 1.111328125 2.1484375 c 1 + 1.408203125 1.7880859375 1.734375 1.515625 2.08984375 1.33203125 c 128 + 2.4453125 1.1484375 2.8515625 1.0556640625 3.30859375 1.0556640625 c 0 + 3.84375 1.0556640625 4.248046875 1.17578125 4.51953125 1.416015625 c 128 + 4.791015625 1.65625 4.927734375 1.98046875 4.927734375 2.3876953125 c 0 + 4.927734375 2.7158203125 4.83203125 2.9755859375 4.640625 3.16796875 c 128 + 4.447265625 3.3603515625 4.107421875 3.50390625 3.619140625 3.599609375 c 1 + 3.37109375 3.64388020833 3.123046875 3.68815104167 2.875 3.732421875 c 1 + 2.060546875 3.8837890625 1.447265625 4.15234375 1.0390625 4.5361328125 c 128 + 0.630859375 4.919921875 0.427734375 5.4482421875 0.427734375 6.1201171875 c 0 + 0.427734375 6.48828125 0.498046875 6.822265625 0.638671875 7.1220703125 c 128 + 0.77734375 7.421875 0.974609375 7.673828125 1.2265625 7.8779296875 c 128 + 1.478515625 8.08203125 1.783203125 8.240234375 2.14453125 8.3515625 c 128 + 2.50390625 8.4638671875 2.908203125 8.51953125 3.35546875 8.51953125 c 0 + 3.98828125 8.51953125 4.53515625 8.41015625 5 8.1904296875 c 128 + 5.462890625 7.9697265625 5.859375 7.65234375 6.1875 7.236328125 c 1 + 5.87174479167 6.95638020833 5.55598958333 6.67643229167 5.240234375 6.396484375 c 1 + 5.0234375 6.67578125 4.759765625 6.900390625 4.447265625 7.068359375 c 128 + 4.13671875 7.236328125 3.748046875 7.3203125 3.283203125 7.3203125 c 0 + 2.8046875 7.3203125 2.431640625 7.2236328125 2.16796875 7.0322265625 c 128 + 1.904296875 6.83984375 1.771484375 6.5595703125 1.771484375 6.1923828125 c 0 + 1.771484375 5.83984375 1.87890625 5.578125 2.095703125 5.40625 c 128 + 2.3125 5.234375 2.6484375 5.103515625 3.103515625 5.015625 c 1 + 3.3515625 4.9638671875 3.599609375 4.912109375 3.84765625 4.8603515625 c 1 + 4.6875 4.7001953125 5.302734375 4.427734375 5.689453125 4.0439453125 c 128 + 6.078125 3.66015625 6.271484375 3.1318359375 6.271484375 2.4599609375 c 0 + 6.271484375 2.068359375 6.203125 1.7119140625 6.068359375 1.3916015625 c 128 + 5.931640625 1.072265625 5.734375 0.7978515625 5.474609375 0.5703125 c 128 + 5.212890625 0.341796875 4.896484375 0.166015625 4.51953125 0.0419921875 c 128 + 4.14453125 -0.0820312500001 3.71484375 -0.1435546875 3.236328125 -0.1435546875 c 0 +-717.389648438 -10.8251953125 m 12 +NamedP: "baseline 2" + 717.249023438 -10.8251953125 l 1028 +EndSplineSet +EndUndoOperation +UndoOperation +Index: 3 +Type: 1 +WasModified: 1 +WasOrder2: 0 +Layer: 2 +Width: 1792 +VWidth: 1792 +LBearingChange: 0 +UnicodeEnc: 0 +InstructionsLength: 0 +SplineSet +-6.271484375 0 m 1 + -6.271484375 2.7919921875 -6.271484375 5.583984375 -6.271484375 8.3759765625 c 1 + -4.48372395833 8.3759765625 -2.69596354167 8.3759765625 -0.908203125 8.3759765625 c 1 + -0.908203125 7.97591145833 -0.908203125 7.57584635417 -0.908203125 7.17578125 c 1 + -2.244140625 7.17578125 -3.580078125 7.17578125 -4.916015625 7.17578125 c 1 + -4.916015625 6.39973958333 -4.916015625 5.62369791667 -4.916015625 4.84765625 c 1 + -3.70377604167 4.84765625 -2.49153645833 4.84765625 -1.279296875 4.84765625 c 1 + -1.279296875 4.44791666667 -1.279296875 4.04817708333 -1.279296875 3.6484375 c 1 + -2.49153645833 3.6484375 -3.70377604167 3.6484375 -4.916015625 3.6484375 c 1 + -4.916015625 2.83235677083 -4.916015625 2.01627604167 -4.916015625 1.2001953125 c 1 + -3.580078125 1.2001953125 -2.244140625 1.2001953125 -0.908203125 1.2001953125 c 1 + -0.908203125 0.800130208333 -0.908203125 0.400065104167 -0.908203125 0 c 1 + -2.69596354167 -0 -4.48372395833 0 -6.271484375 0 c 1 +3.236328125 -0.1435546875 m 0 + 2.53125 -0.1435546875 1.93359375 -0.0156250000001 1.44140625 0.240234375 c 128 + 0.94921875 0.49609375 0.52734375 0.83984375 0.17578125 1.2724609375 c 1 + 0.487630208334 1.564453125 0.799479166666 1.8564453125 1.111328125 2.1484375 c 1 + 1.408203125 1.7880859375 1.734375 1.515625 2.08984375 1.33203125 c 128 + 2.4453125 1.1484375 2.8515625 1.0556640625 3.30859375 1.0556640625 c 0 + 3.84375 1.0556640625 4.248046875 1.17578125 4.51953125 1.416015625 c 128 + 4.791015625 1.65625 4.927734375 1.98046875 4.927734375 2.3876953125 c 0 + 4.927734375 2.7158203125 4.83203125 2.9755859375 4.640625 3.16796875 c 128 + 4.447265625 3.3603515625 4.107421875 3.50390625 3.619140625 3.599609375 c 1 + 3.37109375 3.64388020833 3.123046875 3.68815104167 2.875 3.732421875 c 1 + 2.060546875 3.8837890625 1.447265625 4.15234375 1.0390625 4.5361328125 c 128 + 0.630859375 4.919921875 0.427734375 5.4482421875 0.427734375 6.1201171875 c 0 + 0.427734375 6.48828125 0.498046875 6.822265625 0.638671875 7.1220703125 c 128 + 0.77734375 7.421875 0.974609375 7.673828125 1.2265625 7.8779296875 c 128 + 1.478515625 8.08203125 1.783203125 8.240234375 2.14453125 8.3515625 c 128 + 2.50390625 8.4638671875 2.908203125 8.51953125 3.35546875 8.51953125 c 0 + 3.98828125 8.51953125 4.53515625 8.41015625 5 8.1904296875 c 128 + 5.462890625 7.9697265625 5.859375 7.65234375 6.1875 7.236328125 c 1 + 5.87174479167 6.95638020833 5.55598958333 6.67643229167 5.240234375 6.396484375 c 1 + 5.0234375 6.67578125 4.759765625 6.900390625 4.447265625 7.068359375 c 128 + 4.13671875 7.236328125 3.748046875 7.3203125 3.283203125 7.3203125 c 0 + 2.8046875 7.3203125 2.431640625 7.2236328125 2.16796875 7.0322265625 c 128 + 1.904296875 6.83984375 1.771484375 6.5595703125 1.771484375 6.1923828125 c 0 + 1.771484375 5.83984375 1.87890625 5.578125 2.095703125 5.40625 c 128 + 2.3125 5.234375 2.6484375 5.103515625 3.103515625 5.015625 c 1 + 3.3515625 4.9638671875 3.599609375 4.912109375 3.84765625 4.8603515625 c 1 + 4.6875 4.7001953125 5.302734375 4.427734375 5.689453125 4.0439453125 c 128 + 6.078125 3.66015625 6.271484375 3.1318359375 6.271484375 2.4599609375 c 0 + 6.271484375 2.068359375 6.203125 1.7119140625 6.068359375 1.3916015625 c 128 + 5.931640625 1.072265625 5.734375 0.7978515625 5.474609375 0.5703125 c 128 + 5.212890625 0.341796875 4.896484375 0.166015625 4.51953125 0.0419921875 c 128 + 4.14453125 -0.0820312500001 3.71484375 -0.1435546875 3.236328125 -0.1435546875 c 0 +-717.389648438 -10.8251953125 m 12 +NamedP: "baseline 2" + 717.249023438 -10.8251953125 l 1028 +EndSplineSet +EndUndoOperation +UndoOperation +Index: 4 +Type: 1 +WasModified: 1 +WasOrder2: 0 +Layer: 2 +Width: 1792 +VWidth: 1792 +LBearingChange: 0 +UnicodeEnc: 0 +InstructionsLength: 0 +SplineSet +-6.271484375 0 m 1 + -6.271484375 2.7919921875 -6.271484375 5.583984375 -6.271484375 8.3759765625 c 1 + -4.48372395833 8.3759765625 -2.69596354167 8.3759765625 -0.908203125 8.3759765625 c 1 + -0.908203125 7.97591145833 -0.908203125 7.57584635417 -0.908203125 7.17578125 c 1 + -2.244140625 7.17578125 -3.580078125 7.17578125 -4.916015625 7.17578125 c 1 + -4.916015625 6.39973958333 -4.916015625 5.62369791667 -4.916015625 4.84765625 c 1 + -3.70377604167 4.84765625 -2.49153645833 4.84765625 -1.279296875 4.84765625 c 1 + -1.279296875 4.44791666667 -1.279296875 4.04817708333 -1.279296875 3.6484375 c 1 + -2.49153645833 3.6484375 -3.70377604167 3.6484375 -4.916015625 3.6484375 c 1 + -4.916015625 2.83235677083 -4.916015625 2.01627604167 -4.916015625 1.2001953125 c 1 + -3.580078125 1.2001953125 -2.244140625 1.2001953125 -0.908203125 1.2001953125 c 1 + -0.908203125 0.800130208333 -0.908203125 0.400065104167 -0.908203125 0 c 1 + -2.69596354167 -0 -4.48372395833 0 -6.271484375 0 c 1 +3.236328125 -0.1435546875 m 0 + 2.53125 -0.1435546875 1.93359375 -0.0156250000001 1.44140625 0.240234375 c 128 + 0.94921875 0.49609375 0.52734375 0.83984375 0.17578125 1.2724609375 c 1 + 0.487630208334 1.564453125 0.799479166666 1.8564453125 1.111328125 2.1484375 c 1 + 1.408203125 1.7880859375 1.734375 1.515625 2.08984375 1.33203125 c 128 + 2.4453125 1.1484375 2.8515625 1.0556640625 3.30859375 1.0556640625 c 0 + 3.84375 1.0556640625 4.248046875 1.17578125 4.51953125 1.416015625 c 128 + 4.791015625 1.65625 4.927734375 1.98046875 4.927734375 2.3876953125 c 0 + 4.927734375 2.7158203125 4.83203125 2.9755859375 4.640625 3.16796875 c 128 + 4.447265625 3.3603515625 4.107421875 3.50390625 3.619140625 3.599609375 c 1 + 3.37109375 3.64388020833 3.123046875 3.68815104167 2.875 3.732421875 c 1 + 2.060546875 3.8837890625 1.447265625 4.15234375 1.0390625 4.5361328125 c 128 + 0.630859375 4.919921875 0.427734375 5.4482421875 0.427734375 6.1201171875 c 0 + 0.427734375 6.48828125 0.498046875 6.822265625 0.638671875 7.1220703125 c 128 + 0.77734375 7.421875 0.974609375 7.673828125 1.2265625 7.8779296875 c 128 + 1.478515625 8.08203125 1.783203125 8.240234375 2.14453125 8.3515625 c 128 + 2.50390625 8.4638671875 2.908203125 8.51953125 3.35546875 8.51953125 c 0 + 3.98828125 8.51953125 4.53515625 8.41015625 5 8.1904296875 c 128 + 5.462890625 7.9697265625 5.859375 7.65234375 6.1875 7.236328125 c 1 + 5.87174479167 6.95638020833 5.55598958333 6.67643229167 5.240234375 6.396484375 c 1 + 5.0234375 6.67578125 4.759765625 6.900390625 4.447265625 7.068359375 c 128 + 4.13671875 7.236328125 3.748046875 7.3203125 3.283203125 7.3203125 c 0 + 2.8046875 7.3203125 2.431640625 7.2236328125 2.16796875 7.0322265625 c 128 + 1.904296875 6.83984375 1.771484375 6.5595703125 1.771484375 6.1923828125 c 0 + 1.771484375 5.83984375 1.87890625 5.578125 2.095703125 5.40625 c 128 + 2.3125 5.234375 2.6484375 5.103515625 3.103515625 5.015625 c 1 + 3.3515625 4.9638671875 3.599609375 4.912109375 3.84765625 4.8603515625 c 1 + 4.6875 4.7001953125 5.302734375 4.427734375 5.689453125 4.0439453125 c 128 + 6.078125 3.66015625 6.271484375 3.1318359375 6.271484375 2.4599609375 c 0 + 6.271484375 2.068359375 6.203125 1.7119140625 6.068359375 1.3916015625 c 128 + 5.931640625 1.072265625 5.734375 0.7978515625 5.474609375 0.5703125 c 128 + 5.212890625 0.341796875 4.896484375 0.166015625 4.51953125 0.0419921875 c 128 + 4.14453125 -0.0820312500001 3.71484375 -0.1435546875 3.236328125 -0.1435546875 c 0 +-717.389648438 -10.8251953125 m 8 +NamedP: "baseline 2" + 717.249023438 -10.8251953125 l 1024 +-896 0 m 12 +NamedP: "baseline 1" + 896 0 l 1028 +EndSplineSet +EndUndoOperation +UndoOperation +Index: 5 +Type: 1 +WasModified: 1 +WasOrder2: 0 +Layer: 2 +Width: 1792 +VWidth: 1792 +LBearingChange: 0 +UnicodeEnc: 0 +InstructionsLength: 0 +SplineSet +-717.389648438 -10.8251953125 m 8 +NamedP: "baseline 2" + 717.249023438 -10.8251953125 l 1024 +-896 0 m 12 +NamedP: "baseline 1" + 896 0 l 1028 +EndSplineSet +EndUndoOperation +UndoOperation +Index: 6 +Type: 3 +WasModified: 0 +WasOrder2: 0 +Layer: 2 +EndUndoOperation +EndUndoes +Redoes +EndRedoes +EndUndoRedoHistory +Fore +SplineSet +302.25 -247.515625 m 5 + 302.25 -24.15625 302.25 199.203125 302.25 422.5625 c 5 + 441.754882812 422.5625 581.260742188 422.5625 720.765625 422.5625 c 5 + 720.765625 390.557617188 720.765625 358.551757812 720.765625 326.546875 c 5 + 617.40625 326.546875 514.046875 326.546875 410.6875 326.546875 c 5 + 410.6875 264.463867188 410.6875 202.379882812 410.6875 140.296875 c 5 + 502.536132812 140.296875 594.385742188 140.296875 686.234375 140.296875 c 5 + 686.234375 108.317382812 686.234375 76.3388671875 686.234375 44.359375 c 5 + 594.385742188 44.359375 502.536132812 44.359375 410.6875 44.359375 c 5 + 410.6875 -52.9326171875 410.6875 -150.223632812 410.6875 -247.515625 c 5 + 374.541992188 -247.515625 338.395507812 -247.515625 302.25 -247.515625 c 5 +1374.90625 265.140625 m 5 + 1373.29199219 265.140625 1371.67675781 265.140625 1370.0625 265.140625 c 5 + 1352.45800781 228.96875 1334.85449219 192.796875 1317.25 156.625 c 5 + 1268.29199219 67.3544921875 1219.33300781 -21.9169921875 1170.375 -111.1875 c 5 + 1121.41699219 -21.9169921875 1072.45800781 67.3544921875 1023.5 156.625 c 5 + 1005.89550781 192.796875 988.291992188 228.96875 970.6875 265.140625 c 5 + 969.098632812 265.140625 967.510742188 265.140625 965.921875 265.140625 c 5 + 965.921875 94.2548828125 965.921875 -76.6298828125 965.921875 -247.515625 c 5 + 931.364257812 -247.515625 896.807617188 -247.515625 862.25 -247.515625 c 5 + 862.25 -24.15625 862.25 199.203125 862.25 422.5625 c 5 + 905.114257812 422.5625 947.979492188 422.5625 990.84375 422.5625 c 5 + 1050.6875 308.96875 1110.53125 195.375 1170.375 81.78125 c 5 + 1172.30175781 81.78125 1174.22949219 81.78125 1176.15625 81.78125 c 5 + 1236 195.375 1295.84375 308.96875 1355.6875 422.5625 c 5 + 1396.65136719 422.5625 1437.61425781 422.5625 1478.578125 422.5625 c 5 + 1478.578125 199.203125 1478.578125 -24.15625 1478.578125 -247.515625 c 5 + 1444.02050781 -247.515625 1409.46386719 -247.515625 1374.90625 -247.515625 c 5 + 1374.90625 -76.6298828125 1374.90625 94.2548828125 1374.90625 265.140625 c 5 +394.28125 618.5 m 5 + 394.28125 841.859375 394.28125 1065.21875 394.28125 1288.578125 c 5 + 537.301757812 1288.578125 680.323242188 1288.578125 823.34375 1288.578125 c 5 + 823.34375 1256.57324219 823.34375 1224.56738281 823.34375 1192.5625 c 5 + 716.46875 1192.5625 609.59375 1192.5625 502.71875 1192.5625 c 5 + 502.71875 1130.47949219 502.71875 1068.39550781 502.71875 1006.3125 c 5 + 599.698242188 1006.3125 696.676757812 1006.3125 793.65625 1006.3125 c 5 + 793.65625 974.333007812 793.65625 942.354492188 793.65625 910.375 c 5 + 696.676757812 910.375 599.698242188 910.375 502.71875 910.375 c 5 + 502.71875 845.088867188 502.71875 779.801757812 502.71875 714.515625 c 5 + 609.59375 714.515625 716.46875 714.515625 823.34375 714.515625 c 5 + 823.34375 682.510742188 823.34375 650.504882812 823.34375 618.5 c 5 + 680.323242188 618.5 537.301757812 618.5 394.28125 618.5 c 5 +1154.90625 607.015625 m 4 + 1098.5 607.015625 1050.6875 617.25 1011.3125 637.71875 c 132 + 971.9375 658.1875 938.1875 685.6875 910.0625 720.296875 c 5 + 935.010742188 743.65625 959.958007812 767.015625 984.90625 790.375 c 5 + 1008.65625 761.546875 1034.75 739.75 1063.1875 725.0625 c 132 + 1091.625 710.375 1124.125 702.953125 1160.6875 702.953125 c 4 + 1203.5 702.953125 1235.84375 712.5625 1257.5625 731.78125 c 132 + 1279.28125 751 1290.21875 776.9375 1290.21875 809.515625 c 4 + 1290.21875 835.765625 1282.5625 856.546875 1267.25 871.9375 c 132 + 1251.78125 887.328125 1224.59375 898.8125 1185.53125 906.46875 c 5 + 1165.6875 910.010742188 1145.84375 913.551757812 1126 917.09375 c 5 + 1060.84375 929.203125 1011.78125 950.6875 979.125 981.390625 c 132 + 946.46875 1012.09375 930.21875 1054.359375 930.21875 1108.109375 c 4 + 930.21875 1137.5625 935.84375 1164.28125 947.09375 1188.265625 c 132 + 958.1875 1212.25 973.96875 1232.40625 994.125 1248.734375 c 132 + 1014.28125 1265.0625 1038.65625 1277.71875 1067.5625 1286.625 c 132 + 1096.3125 1295.609375 1128.65625 1300.0625 1164.4375 1300.0625 c 4 + 1215.0625 1300.0625 1258.8125 1291.3125 1296 1273.734375 c 132 + 1333.03125 1256.078125 1364.75 1230.6875 1391 1197.40625 c 5 + 1365.73925781 1175.01074219 1340.47949219 1152.61425781 1315.21875 1130.21875 c 5 + 1297.875 1152.5625 1276.78125 1170.53125 1251.78125 1183.96875 c 132 + 1226.9375 1197.40625 1195.84375 1204.125 1158.65625 1204.125 c 4 + 1120.375 1204.125 1090.53125 1196.390625 1069.4375 1181.078125 c 132 + 1048.34375 1165.6875 1037.71875 1143.265625 1037.71875 1113.890625 c 4 + 1037.71875 1085.6875 1046.3125 1064.75 1063.65625 1051 c 132 + 1081 1037.25 1107.875 1026.78125 1144.28125 1019.75 c 5 + 1164.125 1015.609375 1183.96875 1011.46875 1203.8125 1007.328125 c 5 + 1271 994.515625 1320.21875 972.71875 1351.15625 942.015625 c 132 + 1382.25 911.3125 1397.71875 869.046875 1397.71875 815.296875 c 4 + 1397.71875 783.96875 1392.25 755.453125 1381.46875 729.828125 c 132 + 1370.53125 704.28125 1354.75 682.328125 1333.96875 664.125 c 132 + 1313.03125 645.84375 1287.71875 631.78125 1257.5625 621.859375 c 132 + 1227.5625 611.9375 1193.1875 607.015625 1154.90625 607.015625 c 4 +EndSplineSet +EndChar EndChars EndSplineFont diff --git a/res/icons.ttf b/res/icons.ttf index 028b424afcdc06dd1308e590dd4a3a87247046d5..217d1714a2e62a22739f361f475710d0df8d4c64 100644 GIT binary patch delta 741 zcmYLGT}YEr7=F(8v!6aqolchCgDmPn_mGZM4Jb;Hq1L$&MTGFe}Mp@s0EIyGSXp+8OL7VQIJQuNm} zGBvXiw}oTlleH_w=ZQZfem5HLSKoJU-lql~#Bayc$pmhSbeClww2rE=!9~x5Iv{d` zwCzNEY+SatJ^^AgfGA~$rGbxJv3SoG__m=Kv~&+x-AT`9>RQk930}zjtdk#OXIKkg zU`vh6m9a8oWVa>T1^7%X6P^VUUQpH15~x~Nf3CIgSz(cNBz>Zm@qlzk@CK6`(!^ke z#9V2e{8~0bk1Dt@49G>5#_TF${86xkubz^Xe-asd+HK@tt<}}c#qOovvf|V?aaq<^ z>rH)oOnoN3O(%!1CN)c!!++}dN58N4moOiC8cKZohLa@dW=UHQemUG;lw%;pO4 z;K=?OJ8tD7kdTk{9F|eQ3UgS4Jl4z~k2vi;2xMZC^b}G#UgfZi3VhFD4NS~RvGGX6 z%zaTEcSJ&ZH=5vt8x5RC9E!Wi>27d(8a&?rr?w(0?}%2?M~z131a>s3i5(Jj+KJI~ O0e7R9x5xb={pDXS`mLt` delta 512 zcmccckg?-FV?6^S0|NseLjwadLxP)Ii0{H@CzmlWBzTP#FUQV+N2PmYkbdaD3AF7Yqzc2|%$&$z>%94Aw093=AwTKzWw*#NvYg|A8hm zh(Be?d-ua^m^mZ9vDcfDD|Kn^;l6FpU|gml4EQ$V<#kt#04b!N8Ce0TlaG zkY8M~FlPHB28J9Tpd){QJqz@(A%lBQJipCX25upCpgsnM2Y>(12hk4&|6QFdz-Y_p zGue+ZmeFbQ8pbUKKyjcKz*q)s0t3SxAP*F9G7KyX2Y@sO5HbO2g$G|AI!&I!w05&I zGaKV%cb54;(akSdN>e9K%{EfkWS9vxfQ5mV;Xahj%D~Ua3uUu0@GzQBewVGQ8N}cU zvV?^bXoVERVJMrGL5|@ql+DH Date: Wed, 18 Oct 2023 17:01:46 -0300 Subject: [PATCH 12/74] Updating ESFMu with envelope delay fix; fixing macro op ordering --- extern/ESFMu/esfm.c | 50 ++++++++++++++++++++++++++++++++------------- extern/ESFMu/esfm.h | 4 ++-- src/gui/insEdit.cpp | 2 +- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/extern/ESFMu/esfm.c b/extern/ESFMu/esfm.c index f1979f8e6..f0043fba6 100644 --- a/extern/ESFMu/esfm.c +++ b/extern/ESFMu/esfm.c @@ -373,6 +373,8 @@ ESFM_envelope_calc(esfm_slot *slot) int16 eg_inc; bool reset = 0; bool key_on; + bool key_on_signal; + uint16 delay_counter_compare; key_on = *slot->in.key_on; if (!slot->chip->native_mode) @@ -408,26 +410,46 @@ ESFM_envelope_calc(esfm_slot *slot) } slot->in.eg_output += tremolo; } + + if (slot->in.eg_delay_run && slot->in.eg_delay_counter < 32768) + { + slot->in.eg_delay_counter++; + } + + // triggers on key-on edge + if (key_on && !slot->in.key_on_gate) + { + slot->in.eg_delay_run = 1; + slot->in.eg_delay_counter = 0; + } + else if (!key_on) + { + slot->in.eg_delay_run = 0; + } + + delay_counter_compare = 0; + if (slot->env_delay > 0) + { + delay_counter_compare = 256 << slot->env_delay; + } + + if (key_on && ((slot->in.eg_delay_counter >= delay_counter_compare) || !slot->chip->native_mode)) + { + key_on_signal = 1; + } else { + key_on_signal = 0; + } + if (key_on && slot->in.eg_state == EG_RELEASE) { - if (!slot->in.eg_delay_run && slot->chip->native_mode) - { - slot->in.eg_delay_run = 1; - slot->in.eg_delay_counter = slot->env_delay ? 0x100 : 0; - } - if (slot->in.eg_delay_counter == 0 || !slot->chip->native_mode) + if ((slot->in.eg_delay_counter >= delay_counter_compare) || !slot->chip->native_mode) { - slot->in.eg_delay_run = 0; reset = 1; reg_rate = slot->attack_rate; } else { - if ((slot->chip->global_timer & ((1 << slot->env_delay) - 1)) == 0) - { - slot->in.eg_delay_counter--; - } reg_rate = slot->release_rate; } } @@ -452,6 +474,7 @@ ESFM_envelope_calc(esfm_slot *slot) break; } } + slot->in.key_on_gate = key_on; slot->in.phase_reset = reset; ks = slot->in.keyscale >> ((!slot->ksr) << 1); nonzero = (reg_rate != 0); @@ -524,7 +547,7 @@ ESFM_envelope_calc(esfm_slot *slot) { slot->in.eg_state = EG_DECAY; } - else if (key_on && shift > 0 && rate_hi != 0x0f) + else if (key_on_signal && shift > 0 && rate_hi != 0x0f) { eg_inc = ~slot->in.eg_position >> (4 - shift); } @@ -553,10 +576,9 @@ ESFM_envelope_calc(esfm_slot *slot) { slot->in.eg_state = EG_ATTACK; } - if (!key_on) + if (!key_on_signal) { slot->in.eg_state = EG_RELEASE; - slot->in.eg_delay_run = 0; } } diff --git a/extern/ESFMu/esfm.h b/extern/ESFMu/esfm.h index a37300ca0..d5c734b49 100644 --- a/extern/ESFMu/esfm.h +++ b/extern/ESFMu/esfm.h @@ -67,7 +67,6 @@ uint8_t ESFM_readback_reg (esfm_chip *chip, uint16_t address); uint8_t ESFM_read_port (esfm_chip *chip, uint8_t offset); void ESFM_generate(esfm_chip *chip, int16_t *buf); void ESFM_generate_stream(esfm_chip *chip, int16_t *sndptr, uint32_t num_samples); -// Modification by Kagamiin~: int16_t ESFM_get_channel_output_native(esfm_chip *chip, int channel_idx); @@ -171,10 +170,11 @@ typedef struct _esfm_slot_internal uint10 phase_out; flag phase_reset; flag *key_on; + flag key_on_gate; uint2 eg_state; flag eg_delay_run; - uint9 eg_delay_counter; + uint16 eg_delay_counter; } esfm_slot_internal; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 14648e33c..874d3e4f4 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -5268,7 +5268,7 @@ void FurnaceGUI::drawInsEdit() { } if (ImGui::BeginTabItem(label)) { ImGui::PushID(i); - int ordi=(opCount==4)?orderedOps[i]:i; + int ordi=(opCount==4 && ins->type!=DIV_INS_ESFM)?orderedOps[i]:i; int maxTl=127; if (ins->type==DIV_INS_OPLL) { if (i==1) { From a1b7e524676bfa0777d7b6acad94e6e94fe3b503 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sat, 21 Oct 2023 14:35:20 -0300 Subject: [PATCH 13/74] Implementing pattern effects, detune on FM preview, default instrument --- src/engine/dispatch.h | 5 + src/engine/instrument.h | 1 - src/engine/platform/esfm.cpp | 201 ++++++++++++++++++++++++++--------- src/engine/playback.cpp | 7 +- src/engine/song.h | 37 ++++--- src/engine/sysDef.cpp | 58 +++++++++- src/gui/fmPreview.cpp | 22 +++- 7 files changed, 258 insertions(+), 73 deletions(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 3f2dda6b1..72cb8a3a8 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -240,6 +240,11 @@ enum DivDispatchCmds { DIV_ALWAYS_SET_VOLUME, // () -> alwaysSetVol + DIV_CMD_ESFM_OP_PANNING, // (op, value) + DIV_CMD_ESFM_OUTLVL, // (op, value) + DIV_CMD_ESFM_MODIN, // (op, value) + DIV_CMD_ESFM_ENV_DELAY, // (op, value) + DIV_CMD_MAX }; diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 80c5dc3a6..0f9329a59 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -85,7 +85,6 @@ enum DivInstrumentType: unsigned short { DIV_INS_TED=52, DIV_INS_C140=53, DIV_INS_C219=54, - // TODO: Ask tilde to standardize this!!! DIV_INS_ESFM=55, DIV_INS_MAX, DIV_INS_NULL diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 92f32c78d..a54043a8a 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -230,6 +230,7 @@ void DivPlatformESFM::tick(bool sysTick) { } } + // detune/fixed pitch if (opE.fixed) { if (m.ssg.had) { opE.ct=(opE.ct&(~(7<<2)))|((m.ssg.val&7)<<2); @@ -351,44 +352,21 @@ void DivPlatformESFM::tick(bool sysTick) { } int DivPlatformESFM::octave(int freq) { - if (freq>=0x3ff<<6) { - return 1<<7; - } else if (freq>=0x3ff<<5) { - return 1<<6; - } else if (freq>=0x3ff<<4) { - return 1<<5; - } else if (freq>=0x3ff<<3) { - return 1<<4; - } else if (freq>=0x3ff<<2) { - return 1<<3; - } else if (freq>=0x3ff<<1) { - return 1<<2; - } else if (freq>=0x3ff) { - return 1<<1; - } else { - return 1<<0; + int result=1; + while (freq>0x3ff) { + freq>>=1; + result<<=1; } - return 1<<0; + return result; } int DivPlatformESFM::toFreq(int freq) { - if (freq>=0x3ff<<6) { - return 0x1c00|((freq>>7)&0x3ff); - } else if (freq>=0x3ff<<5) { - return 0x1800|((freq>>6)&0x3ff); - } else if (freq>=0x3ff<<4) { - return 0x1400|((freq>>5)&0x3ff); - } else if (freq>=0x3ff<<3) { - return 0x1000|((freq>>4)&0x3ff); - } else if (freq>=0x3ff<<2) { - return 0xc00|((freq>>3)&0x3ff); - } else if (freq>=0x3ff<<1) { - return 0x800|((freq>>2)&0x3ff); - } else if (freq>=0x3ff<<0) { - return 0x400|((freq>>1)&0x3ff); - } else { - return freq&0x3ff; + int block=0; + while (freq>0x3ff) { + freq>>=1; + block++; } + return ((block&7)<<10)|(freq&0x3ff); } void DivPlatformESFM::muteChannel(int ch, bool mute) { @@ -510,7 +488,6 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32 + o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; - rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); } break; @@ -585,7 +562,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { break; } case DIV_CMD_FM_AR: { - if (c.value<0) { + if (c.value<0) { for (int o=0; o<4; o++) { unsigned short baseAddr=c.chan*32 + o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; @@ -603,7 +580,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { break; } case DIV_CMD_FM_DR: { - if (c.value<0) { + if (c.value<0) { for (int o=0; o<4; o++) { unsigned short baseAddr=c.chan*32 + o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; @@ -621,7 +598,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { break; } case DIV_CMD_FM_SL: { - if (c.value<0) { + if (c.value<0) { for (int o=0; o<4; o++) { unsigned short baseAddr=c.chan*32 + o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; @@ -639,7 +616,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { break; } case DIV_CMD_FM_RR: { - if (c.value<0) { + if (c.value<0) { for (int o=0; o<4; o++) { unsigned short baseAddr=c.chan*32 + o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; @@ -657,7 +634,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { break; } case DIV_CMD_FM_AM: { - if (c.value<0) { + if (c.value<0) { for (int o=0; o<4; o++) { unsigned short baseAddr=c.chan*32 + o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; @@ -675,7 +652,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { break; } case DIV_CMD_FM_VIB: { - if (c.value<0) { + if (c.value<0) { for (int o=0; o<4; o++) { unsigned short baseAddr=c.chan*32 + o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; @@ -693,7 +670,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { break; } case DIV_CMD_FM_SUS: { - if (c.value<0) { + if (c.value<0) { for (int o=0; o<4; o++) { unsigned short baseAddr=c.chan*32 + o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; @@ -711,7 +688,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { break; } case DIV_CMD_FM_KSR: { - if (c.value<0) { + if (c.value<0) { for (int o=0; o<4; o++) { unsigned short baseAddr=c.chan*32 + o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; @@ -729,7 +706,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { break; } case DIV_CMD_FM_WS: { - if (c.value<0) { + if (c.value<0) { for (int o=0; o<4; o++) { unsigned short baseAddr=c.chan*32 + o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; @@ -760,7 +737,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { } // KSL case DIV_CMD_FM_RS: { - if (c.value<0) { + if (c.value<0) { for (int o=0; o<4; o++) { unsigned short baseAddr=c.chan*32 + o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; @@ -785,6 +762,134 @@ int DivPlatformESFM::dispatch(DivCommand c) { } break; } + case DIV_CMD_FM_AM_DEPTH: { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + op.dam=c.value2&1; + rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + break; + } + case DIV_CMD_FM_PM_DEPTH: { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + op.dvb=c.value2&1; + rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + break; + } + case DIV_CMD_FM_FIXFREQ: { + unsigned int o=c.value&3; + bool isFNum=c.value&4; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + if (!opE.fixed) break; + if (isFNum) { + opE.dt=(c.value2)&0xff; + opE.ct=(opE.ct&(~3))|((c.value2>>8)&3); + chan[c.chan].freqChanged=true; + } else { + opE.ct=(opE.ct&(~(7<<2)))|((c.value2&7)<<2); + chan[c.chan].freqChanged=true; + } + break; + } + case DIV_CMD_ESFM_OP_PANNING: { + unsigned int o=c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + opE.left=c.value2&1; + opE.right=(c.value2&2)>>1; + rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + break; + } + case DIV_CMD_ESFM_OUTLVL: { + if (c.value<0) { + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + unsigned char noise=chan[c.chan].state.esfm.noise&3; + opE.outLvl=c.value2&7; + if (isMuted[c.chan]) { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + } else { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + } + } + } else { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + unsigned char noise=chan[c.chan].state.esfm.noise&3; + opE.outLvl=c.value2&7; + if (isMuted[c.chan]) { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + } else { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + } + } + break; + } + case DIV_CMD_ESFM_MODIN: { + if (c.value<0) { + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + opE.modIn=c.value2&7; + rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + } + } else { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + opE.modIn=c.value2&7; + rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + } + break; + } + case DIV_CMD_ESFM_ENV_DELAY: { + if (c.value<0) { + for (int o=0; o<4; o++) { + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + opE.delay=c.value2&7; + rWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[c.chan].freqH[o]|(opE.delay<<5)); + } + } else { + unsigned int o = c.value; + if (o >= 4) break; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + opE.delay=c.value2&7; + rWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[c.chan].freqH[o]|(opE.delay<<5)); + } + break; + } + case DIV_CMD_STD_NOISE_MODE: { + unsigned int o=3; + unsigned short baseAddr=c.chan*32 + o*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + DivInstrumentESFM insE=chan[c.chan].state.esfm; + insE.noise=c.value&3; + if (isMuted[c.chan]) { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|(insE.noise<<3)|0); + } else { + rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|(insE.noise<<3)|((opE.outLvl&7)<<5)); + } + break; + } case DIV_CMD_FM_HARD_RESET: chan[c.chan].hardReset=c.value; break; @@ -843,10 +948,10 @@ DivDispatchOscBuffer* DivPlatformESFM::getOscBuffer(int ch) { } unsigned char* DivPlatformESFM::getRegisterPool() { - // TODO: DEBUG, remove this, it impacts performance - for (int i=0; i int effectValAnd(unsigned char, unsigned char val) { return val&mask; }; @@ -612,6 +616,52 @@ void DivEngine::registerSystems() { {0x20, {DIV_CMD_SAMPLE_FREQ, "20xx: Set PCM frequency"}} }; + EffectHandlerMap fmESFMPostEffectHandlerMap={ + {0x12, {DIV_CMD_FM_TL, "12xx: Set level of operator 1 (0 highest, 3F lowest)", constVal<0>, effectVal}}, + {0x13, {DIV_CMD_FM_TL, "13xx: Set level of operator 2 (0 highest, 3F lowest)", constVal<1>, effectVal}}, + {0x14, {DIV_CMD_FM_TL, "14xx: Set level of operator 3 (0 highest, 3F lowest)", constVal<2>, effectVal}}, + {0x15, {DIV_CMD_FM_TL, "15xx: Set level of operator 4 (0 highest, 3F lowest)", constVal<3>, effectVal}}, + {0x16, {DIV_CMD_FM_MULT, "16xy: Set operator multiplier (x: operator from 1 to 4; y: multiplier)", effectOpValNoZero<4>, effectValAnd<15>}}, + {0x19, {DIV_CMD_FM_AR, "19xx: Set attack of all operators (0 to F)", constVal<-1>, effectValAnd<15>}}, + {0x1a, {DIV_CMD_FM_AR, "1Axx: Set attack of operator 1 (0 to F)", constVal<0>, effectValAnd<15>}}, + {0x1b, {DIV_CMD_FM_AR, "1Bxx: Set attack of operator 2 (0 to F)", constVal<1>, effectValAnd<15>}}, + {0x1c, {DIV_CMD_FM_AR, "1Cxx: Set attack of operator 3 (0 to F)", constVal<2>, effectValAnd<15>}}, + {0x1d, {DIV_CMD_FM_AR, "1Dxx: Set attack of operator 4 (0 to F)", constVal<3>, effectValAnd<15>}}, + {0x1e, {DIV_CMD_FM_AM_DEPTH, "1Exy: Set AM depth (x: operator from 1 to 4 (0 for all ops); y: depth (0: 1dB, 1: 4.8dB))", effectOpVal<4>, effectValAnd<1>}}, + {0x1f, {DIV_CMD_FM_PM_DEPTH, "1Fxy: Set vibrato depth (x: operator from 1 to 4 (0 for all ops); y: depth (0: normal, 1: double))", effectOpVal<4>, effectValAnd<1>}}, + {0x20, {DIV_CMD_ESFM_OP_PANNING, "20xy: Set panning of operator 1 (x: left; y: right)", constVal<0>, effectValNibbleFlagPackReversed}}, + {0x21, {DIV_CMD_ESFM_OP_PANNING, "21xy: Set panning of operator 2 (x: left; y: right)", constVal<1>, effectValNibbleFlagPackReversed}}, + {0x22, {DIV_CMD_ESFM_OP_PANNING, "22xy: Set panning of operator 3 (x: left; y: right)", constVal<2>, effectValNibbleFlagPackReversed}}, + {0x23, {DIV_CMD_ESFM_OP_PANNING, "23xy: Set panning of operator 4 (x: left; y: right)", constVal<3>, effectValNibbleFlagPackReversed}}, + {0x24, {DIV_CMD_ESFM_OUTLVL, "24xy: Set output level register (x: operator from 1 to 4 (0 for all ops); y: level from 0 to 7)", effectOpVal<4>, effectValAnd<7>}}, + {0x25, {DIV_CMD_ESFM_MODIN, "25xy: Set modulation input level (x: operator from 1 to 4 (0 for all ops); y: level from 0 to 7)", effectOpVal<4>, effectValAnd<7>}}, + {0x26, {DIV_CMD_ESFM_ENV_DELAY, "26xy: Set envelope delay (x: operator from 1 to 4 (0 for all ops); y: delay from 0 to 7)", effectOpVal<4>, effectValAnd<7>}}, + {0x27, {DIV_CMD_STD_NOISE_MODE, "27xx: Set noise mode for operator 4 (x: mode from 0 to 3)", effectValAnd<3>}}, + {0x2a, {DIV_CMD_FM_WS, "2Axy: Set waveform (x: operator from 1 to 4 (0 for all ops); y: waveform from 0 to 7)", effectOpVal<4>, effectValAnd<7>}}, + {0x2f, {DIV_CMD_FM_FIXFREQ, "2Fxy: Set fixed frequency block (x: operator from 1 to 4; y: octave from 0 to 7)", effectOpValNoZero<4>, effectValAnd<7>}}, + {0x50, {DIV_CMD_FM_AM, "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)", effectOpVal<4>, effectValAnd<1>}}, + {0x51, {DIV_CMD_FM_SL, "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)", effectOpVal<4>, effectValAnd<15>}}, + {0x52, {DIV_CMD_FM_RR, "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)", effectOpVal<4>, effectValAnd<15>}}, + {0x53, {DIV_CMD_FM_VIB, "53xy: Set vibrato (x: operator from 1 to 4 (0 for all ops); y: enabled)", effectOpVal<4>, effectValAnd<1>}}, + {0x54, {DIV_CMD_FM_RS, "54xy: Set envelope scale (x: operator from 1 to 4 (0 for all ops); y: scale from 0 to 3)", effectOpVal<4>, effectValAnd<3>}}, + {0x55, {DIV_CMD_FM_SUS, "55xy: Set envelope sustain (x: operator from 1 to 4 (0 for all ops); y: enabled)", effectOpVal<4>, effectValAnd<1>}}, + {0x56, {DIV_CMD_FM_DR, "56xx: Set decay of all operators (0 to F)", constVal<-1>, effectValAnd<15>}}, + {0x57, {DIV_CMD_FM_DR, "57xx: Set decay of operator 1 (0 to F)", constVal<0>, effectValAnd<15>}}, + {0x58, {DIV_CMD_FM_DR, "58xx: Set decay of operator 2 (0 to F)", constVal<1>, effectValAnd<15>}}, + {0x59, {DIV_CMD_FM_DR, "59xx: Set decay of operator 3 (0 to F)", constVal<2>, effectValAnd<15>}}, + {0x5a, {DIV_CMD_FM_DR, "5Axx: Set decay of operator 4 (0 to F)", constVal<3>, effectValAnd<15>}}, + {0x5b, {DIV_CMD_FM_KSR, "5Bxy: Set whether key will scale envelope (x: operator from 1 to 4 (0 for all ops); y: enabled)", effectOpVal<4>, effectValAnd<1>}} + }; + const EffectHandler fmESFMFixFreqFNumHandler[4]={ + {DIV_CMD_FM_FIXFREQ, "3xyy: Set fixed frequency F-num of operator 1 (x: high 2 bits from 0 to 3; y: low 8 bits of F-num)", constVal<4>, effectValLong<10>}, + {DIV_CMD_FM_FIXFREQ, "3xyy: Set fixed frequency F-num of operator 2 (x: high 2 bits from 4 to 7; y: low 8 bits of F-num)", constVal<5>, effectValLong<10>}, + {DIV_CMD_FM_FIXFREQ, "3xyy: Set fixed frequency F-num of operator 3 (x: high 2 bits from 8 to B; y: low 8 bits of F-num)", constVal<6>, effectValLong<10>}, + {DIV_CMD_FM_FIXFREQ, "3xyy: Set fixed frequency F-num of operator 4 (x: high 2 bits from C to F; y: low 8 bits of F-num)", constVal<7>, effectValLong<10>}, + }; + for (int i=0; i<16; i++) { + fmESFMPostEffectHandlerMap.emplace(0x30+i,fmESFMFixFreqFNumHandler[i/4]); + } + // SysDefs // this chip uses YMZ ADPCM, but the emulator uses ADPCM-B because I got it wrong back then. @@ -1917,8 +1967,7 @@ void DivEngine::registerSystems() { {0x12, {DIV_CMD_SNES_INVERT, "12xy: Set invert mode (x: surround; y: invert)"}}, } ); - - // TODO: ask Tilde to standardize! + sysDefs[DIV_SYSTEM_ESFM]=new DivSysDef( "ESS ES1xxx-series (ESFM)", NULL, 0xd0, 0, 18, true, false, 0, false, 0, "A unique FM synth featured in PC sound cards.\nBased on the OPL3 design, but with lots of its features extended.", @@ -1927,7 +1976,10 @@ void DivEngine::registerSystems() { {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM}, {DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM, DIV_INS_ESFM}, {}, - {} + { + {0x2e, {DIV_CMD_FM_HARD_RESET, "2Exx: Toggle hard envelope reset on new notes"}}, + }, + fmESFMPostEffectHandlerMap ); sysDefs[DIV_SYSTEM_DUMMY]=new DivSysDef( diff --git a/src/gui/fmPreview.cpp b/src/gui/fmPreview.cpp index 14b21e018..290175e23 100644 --- a/src/gui/fmPreview.cpp +++ b/src/gui/fmPreview.cpp @@ -366,15 +366,31 @@ void FurnaceGUI::renderFMPreviewESFM(const DivInstrumentFM& params, const DivIns const DivInstrumentFM::Operator& op=params.op[i]; const DivInstrumentESFM::Operator& opE=esfmParams.op[i]; unsigned short baseAddr=i*8; + unsigned char freqL, freqH; + if (opE.fixed) { + freqL=opE.dt; + freqH=opE.ct&0x1f; + } else { + // perform detune calculation + int offset=(opE.ct<<7)+opE.dt; + double fbase=(mult0?2048.0:1024.0)*pow(2.0,(float)offset/(128.0*12.0)); + int bf=round(fbase); + int block=0; + while (bf>0x3ff) { + bf>>=1; + block++; + } + freqL=bf&0xff; + freqH=((block&7)<<2)|((bf>>8)&3); + } ESFM_WRITE(baseAddr+0,(op.am<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0x0f)); ESFM_WRITE(baseAddr+1,(op.ksl<<6)|(op.tl&0x3f)); ESFM_WRITE(baseAddr+2,(op.ar<<4)|(op.dr&0x0f)); ESFM_WRITE(baseAddr+3,(op.sl<<4)|(op.rr&0x0f)); - // TODO: implement ct/dt detune... how will we do that? - ESFM_WRITE(baseAddr+4,0); - ESFM_WRITE(baseAddr+5,(opE.delay<<5)|(mult0?0x0a:0x06)); + ESFM_WRITE(baseAddr+4,freqL); + ESFM_WRITE(baseAddr+5,(opE.delay<<5)|freqH); ESFM_WRITE(baseAddr+6,(op.dam<<7)|((op.dvb&1)<<6)|((opE.right&1)<<5)|((opE.left&1)<<4)|((opE.modIn&7)<<1)); ESFM_WRITE(baseAddr+7,(opE.outLvl<<5)|((i==3?esfmParams.noise:0)<<3)|(op.ws&7)); From 64baa7c97fad88893b29ef0fe34b8120559616bf Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sun, 22 Oct 2023 11:46:34 -0300 Subject: [PATCH 14/74] Some refactoring --- src/engine/instrument.cpp | 2 +- src/engine/platform/esfm.cpp | 132 +++++++------- src/engine/platform/esfm.h | 4 +- src/gui/insEdit.cpp | 344 +++++++++++++++++------------------ src/gui/sysConf.cpp | 22 ++- 5 files changed, 256 insertions(+), 248 deletions(-) diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index d92fe4504..918a9a3fe 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -2632,7 +2632,7 @@ void DivInstrument::readFeatureEF(SafeReader& reader, short version) { READ_FEAT_BEGIN; unsigned char next=reader.readC(); - esfm.noise = next&3; + esfm.noise=next&3; for (int i=0; i<4; i++) { DivInstrumentESFM::Operator& op=esfm.op[i]; diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index a54043a8a..59a91d05b 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -35,7 +35,7 @@ #define OFFSET_DAM_DVB_LEFT_RIGHT_MODIN 0x06 #define OFFSET_OUTLVL_NOISE_WS 0x07 -#define KEY_ON_REGS_START (18 * 8 * 4) +#define KEY_ON_REGS_START (18*8*4) void DivPlatformESFM::acquire(short** buf, size_t len) { thread_local short o[2]; @@ -66,7 +66,7 @@ void DivPlatformESFM::tick(bool sysTick) { if (chan[i].std.vol.had) { chan[i].outVol=VOL_SCALE_LOG_BROKEN(chan[i].vol,MIN(63,chan[i].std.vol.val),63); for (int o=0; o<4; o++) { - unsigned short baseAddr=i*32 + o*8; + unsigned short baseAddr=i*32+o*8; DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o]; unsigned char noise=chan[i].state.esfm.noise&3; @@ -96,7 +96,7 @@ void DivPlatformESFM::tick(bool sysTick) { if (chan[i].std.panL.had) { chan[i].globalPan=((chan[i].std.panL.val&1)<<1)|((chan[i].std.panL.val&2)>>1); for (int o=0; o<4; o++) { - unsigned short baseAddr=i*32 + o*8; + unsigned short baseAddr=i*32+o*8; DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o]; rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); @@ -121,7 +121,7 @@ void DivPlatformESFM::tick(bool sysTick) { if (chan[i].std.duty.had) { int o=3; - unsigned short baseAddr=i*32 + o*8; + unsigned short baseAddr=i*32+o*8; DivInstrumentESFM& ins=chan[i].state.esfm; DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o]; @@ -135,7 +135,7 @@ void DivPlatformESFM::tick(bool sysTick) { } for (int o=0; o<4; o++) { - unsigned short baseAddr=i*32 + o*8; + unsigned short baseAddr=i*32+o*8; DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o]; DivMacroInt::IntOp& m=chan[i].std.op[o]; @@ -283,7 +283,7 @@ void DivPlatformESFM::tick(bool sysTick) { mustHardReset=true; // logI("chan[%d] hard reset, slrr := 0x0f", i); for (int o=0; o<4; o++) { - unsigned short baseAddr=i*32 + o*8; + unsigned short baseAddr=i*32+o*8; immWrite(baseAddr+OFFSET_SL_RR,0x0f); } } @@ -296,7 +296,7 @@ void DivPlatformESFM::tick(bool sysTick) { if (chan[i].freq>131071) chan[i].freq=131071; for (int o=0; o<4; o++) { - unsigned short baseAddr=i*32 + o*8; + unsigned short baseAddr=i*32+o*8; DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o]; int ct=(int)opE.ct; int dt=(int)opE.dt; @@ -334,7 +334,7 @@ void DivPlatformESFM::tick(bool sysTick) { if (chan[i].hardReset && chan[i].keyOn) { // logI("chan[%d] hard reset key on, writing original slrr back", i); for (int o=0; o<4; o++) { - unsigned short baseAddr=i*32 + o*8; + unsigned short baseAddr=i*32+o*8; DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; immWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); } @@ -371,13 +371,13 @@ int DivPlatformESFM::toFreq(int freq) { void DivPlatformESFM::muteChannel(int ch, bool mute) { isMuted[ch]=mute; - + for (int o=0; o<4; o++) { - unsigned short baseAddr=ch*32 + o*8; + unsigned short baseAddr=ch*32+o*8; DivInstrumentFM::Operator& op=chan[ch].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[ch].state.esfm.op[o]; unsigned char noise=chan[ch].state.esfm.noise&3; - + if (isMuted[ch]) { rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); } else { @@ -396,7 +396,7 @@ void DivPlatformESFM::commitState(int ch, DivInstrument* ins) { chan[ch].state.fm=ins->fm; chan[ch].state.esfm=ins->esfm; for (int o=0; o<4; o++) { - unsigned short baseAddr=ch*32 + o*8; + unsigned short baseAddr=ch*32+o*8; DivInstrumentFM::Operator& op=chan[ch].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[ch].state.esfm.op[o]; unsigned char noise=chan[ch].state.esfm.noise&3; @@ -463,7 +463,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { chan[c.chan].outVol=c.value; } for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; if (KVS(c.chan, o)) { rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); @@ -485,7 +485,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_PANNING: { chan[c.chan].globalPan=(c.value>0)|((c.value2>0)<<1); for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); @@ -540,18 +540,18 @@ int DivPlatformESFM::dispatch(DivCommand c) { break; } case DIV_CMD_FM_MULT: { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.mult=c.value2&15; rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); break; } case DIV_CMD_FM_TL: { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.tl=c.value2&63; if (KVS(c.chan, o)) { @@ -564,15 +564,15 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_FM_AR: { if (c.value<0) { for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ar=c.value2&15; rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); } } else { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ar=c.value2&15; rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); @@ -582,15 +582,15 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_FM_DR: { if (c.value<0) { for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.dr=c.value2&15; rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); } } else { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.dr=c.value2&15; rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); @@ -600,15 +600,15 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_FM_SL: { if (c.value<0) { for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.sl=c.value2&15; rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); } } else { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.sl=c.value2&15; rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); @@ -618,15 +618,15 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_FM_RR: { if (c.value<0) { for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.rr=c.value2&15; rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); } } else { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.rr=c.value2&15; rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); @@ -636,15 +636,15 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_FM_AM: { if (c.value<0) { for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.am=c.value2&1; rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } } else { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.am=c.value2&1; rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); @@ -654,15 +654,15 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_FM_VIB: { if (c.value<0) { for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.vib=c.value2&1; rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } } else { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.vib=c.value2&1; rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); @@ -672,15 +672,15 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_FM_SUS: { if (c.value<0) { for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.sus=c.value2&1; rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } } else { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.sus=c.value2&1; rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); @@ -690,15 +690,15 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_FM_KSR: { if (c.value<0) { for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ksr=c.value2&1; rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } } else { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ksr=c.value2&1; rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); @@ -708,7 +708,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_FM_WS: { if (c.value<0) { for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; unsigned char noise=chan[c.chan].state.esfm.noise&3; @@ -720,9 +720,9 @@ int DivPlatformESFM::dispatch(DivCommand c) { } } } else { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; unsigned char noise=chan[c.chan].state.esfm.noise&3; @@ -739,7 +739,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_FM_RS: { if (c.value<0) { for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ksl=c.value2&3; if (KVS(c.chan, o)) { @@ -749,9 +749,9 @@ int DivPlatformESFM::dispatch(DivCommand c) { } } } else { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ksl=c.value2&3; if (KVS(c.chan, o)) { @@ -763,9 +763,9 @@ int DivPlatformESFM::dispatch(DivCommand c) { break; } case DIV_CMD_FM_AM_DEPTH: { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; op.dam=c.value2&1; @@ -773,9 +773,9 @@ int DivPlatformESFM::dispatch(DivCommand c) { break; } case DIV_CMD_FM_PM_DEPTH: { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; op.dvb=c.value2&1; @@ -800,7 +800,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_ESFM_OP_PANNING: { unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; opE.left=c.value2&1; @@ -811,7 +811,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_ESFM_OUTLVL: { if (c.value<0) { for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; unsigned char noise=chan[c.chan].state.esfm.noise&3; @@ -823,9 +823,9 @@ int DivPlatformESFM::dispatch(DivCommand c) { } } } else { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; unsigned char noise=chan[c.chan].state.esfm.noise&3; @@ -841,16 +841,16 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_ESFM_MODIN: { if (c.value<0) { for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; opE.modIn=c.value2&7; rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); } } else { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; opE.modIn=c.value2&7; @@ -861,15 +861,15 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_ESFM_ENV_DELAY: { if (c.value<0) { for (int o=0; o<4; o++) { - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; opE.delay=c.value2&7; rWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[c.chan].freqH[o]|(opE.delay<<5)); } } else { - unsigned int o = c.value; + unsigned int o=c.value; if (o >= 4) break; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; opE.delay=c.value2&7; rWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[c.chan].freqH[o]|(opE.delay<<5)); @@ -878,7 +878,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { } case DIV_CMD_STD_NOISE_MODE: { unsigned int o=3; - unsigned short baseAddr=c.chan*32 + o*8; + unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; DivInstrumentESFM insE=chan[c.chan].state.esfm; @@ -969,9 +969,9 @@ void DivPlatformESFM::reset() { ESFM_write_reg(&chip, 0x408, 0x00); for (int i=0; i 0 and op[o + 1].modIn == 0. */ inline bool KVS(int c, int o) { - if (c < 0 || c >= 18 || o < 0 || o >= 4) return false; + if (c<0 || c>=18 || o<0 || o>=4) return false; if (chan[c].state.fm.op[o].kvs==1) return true; @@ -106,7 +106,7 @@ class DivPlatformESFM: public DivDispatch { if (chan[c].state.esfm.op[o].outLvl==7) return true; else if (chan[c].state.esfm.op[o].outLvl>0) { if (o==3) return true; - else if ((chan[c].state.esfm.op[o].outLvl-chan[c].state.esfm.op[o+1].modIn) >= 2) { + else if ((chan[c].state.esfm.op[o].outLvl-chan[c].state.esfm.op[o+1].modIn)>=2) { return true; } else if (chan[c].state.esfm.op[o+1].modIn==0) { diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 874d3e4f4..873760d85 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -166,7 +166,7 @@ const char* oplDrumNames[4]={ }; const char* esfmNoiseModeNames[4]={ - "Noise disabled", "Snare (square + noise)", "HiHat (ringmod from OP3, + noise)", "Top (ringmod from OP3)" + "Noise disabled", "Snare (square + noise)", "HiHat (ringmod from OP3, + noise)", "Top (ringmod from OP3)\nWARNING - not emulated properly! Will change in future versions." }; const bool opIsOutput[8][4]={ @@ -1198,7 +1198,7 @@ void FurnaceGUI::drawESFMAlgorithm(DivInstrumentESFM& esfm, const ImVec2& size) int out4 = esfm.op[3].outLvl&7; bool isMod[4]; for (int i=0; i<4; i++) { - DivInstrumentESFM::Operator& opE = esfm.op[i]; + DivInstrumentESFM::Operator& opE=esfm.op[i]; isMod[i]=true; if (opE.outLvl==7) isMod[i]=false; else if (opE.outLvl>0) { @@ -1206,7 +1206,7 @@ void FurnaceGUI::drawESFMAlgorithm(DivInstrumentESFM& esfm, const ImVec2& size) else { DivInstrumentESFM::Operator& opENext=esfm.op[i+1]; if (opENext.modIn==0) isMod[i]=false; - else if ((opE.outLvl-opENext.modIn) >= 2) isMod[i]=false; + else if ((opE.outLvl-opENext.modIn)>=2) isMod[i]=false; } } } @@ -3137,182 +3137,168 @@ void FurnaceGUI::drawInsEdit() { } } - if (ins->type!=DIV_INS_ESFM) { - if (ImGui::BeginTable("fmDetails",3,ImGuiTableFlags_SizingStretchSame)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0); - ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.0); + if (ImGui::BeginTable("fmDetails",3,(ins->type==DIV_INS_ESFM)?ImGuiTableFlags_SizingStretchProp:ImGuiTableFlags_SizingStretchSame)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.50f:0.0f)); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.15f:0.0f)); + ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.35f:0.0f)); - ImGui::TableNextRow(); - switch (ins->type) { - case DIV_INS_FM: - case DIV_INS_OPM: - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable - ImGui::TableNextColumn(); - if (fmPreviewOn) { - drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - if (!fmPreviewPaused) { - renderFMPreview(ins,1); - WAKE_UP; - } - } else { - drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + ImGui::TableNextRow(); + switch (ins->type) { + case DIV_INS_FM: + case DIV_INS_OPM: + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; } - kvsConfig(ins); - break; - case DIV_INS_OPZ: - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_FMS2),ImGuiDataType_U8,&ins->fm.fms2,&_ZERO,&_SEVEN)); rightClickable - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable - P(CWSliderScalar(FM_NAME(FM_AMS2),ImGuiDataType_U8,&ins->fm.ams2,&_ZERO,&_THREE)); rightClickable - ImGui::TableNextColumn(); - if (fmPreviewOn) { - drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - if (!fmPreviewPaused) { - renderFMPreview(ins,1); - WAKE_UP; - } - } else { - drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - } - kvsConfig(ins); - - if (ImGui::Button("Request from TX81Z")) { - doAction(GUI_ACTION_TX81Z_REQUEST); - } - /* - ImGui::SameLine(); - if (ImGui::Button("Send to TX81Z")) { - showError("Coming soon!"); - } - */ - break; - case DIV_INS_OPL: - case DIV_INS_OPL_DRUMS: { - bool fourOp=(ins->fm.ops==4 || ins->type==DIV_INS_OPL_DRUMS); - bool drums=ins->fm.opllPreset==16; - int algMax=fourOp?3:1; - ImGui::TableNextColumn(); - ins->fm.alg&=algMax; - P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable - if (ins->type==DIV_INS_OPL) { - ImGui::BeginDisabled(ins->fm.opllPreset==16); - if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER - ins->fm.ops=fourOp?4:2; - } - ImGui::EndDisabled(); - } - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&algMax)); rightClickable - if (ins->type==DIV_INS_OPL) { - if (ImGui::Checkbox("Drums",&drums)) { PARAMETER - ins->fm.opllPreset=drums?16:0; - } - } - ImGui::TableNextColumn(); - if (fmPreviewOn) { - drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - if (!fmPreviewPaused) { - renderFMPreview(ins,1); - WAKE_UP; - } - } else { - drawAlgorithm(ins->fm.alg&algMax,fourOp?FM_ALGS_4OP_OPL:FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - } - kvsConfig(ins); - break; + } else { + drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); } - case DIV_INS_OPLL: { - bool dc=fmOrigin.fms; - bool dm=fmOrigin.ams; - bool sus=ins->fm.alg; - ImGui::TableNextColumn(); - ImGui::BeginDisabled(ins->fm.opllPreset!=0); - P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&fmOrigin.fb,&_ZERO,&_SEVEN)); rightClickable - if (ImGui::Checkbox(FM_NAME(FM_DC),&dc)) { PARAMETER - fmOrigin.fms=dc; + kvsConfig(ins); + break; + case DIV_INS_OPZ: + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_FMS2),ImGuiDataType_U8,&ins->fm.fms2,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable + P(CWSliderScalar(FM_NAME(FM_AMS2),ImGuiDataType_U8,&ins->fm.ams2,&_ZERO,&_THREE)); rightClickable + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; + } + } else { + drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + } + kvsConfig(ins); + + if (ImGui::Button("Request from TX81Z")) { + doAction(GUI_ACTION_TX81Z_REQUEST); + } + /* + ImGui::SameLine(); + if (ImGui::Button("Send to TX81Z")) { + showError("Coming soon!"); + } + */ + break; + case DIV_INS_OPL: + case DIV_INS_OPL_DRUMS: { + bool fourOp=(ins->fm.ops==4 || ins->type==DIV_INS_OPL_DRUMS); + bool drums=ins->fm.opllPreset==16; + int algMax=fourOp?3:1; + ImGui::TableNextColumn(); + ins->fm.alg&=algMax; + P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable + if (ins->type==DIV_INS_OPL) { + ImGui::BeginDisabled(ins->fm.opllPreset==16); + if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER + ins->fm.ops=fourOp?4:2; } ImGui::EndDisabled(); - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_NAME(FM_SUS),&sus)) { PARAMETER - ins->fm.alg=sus; - } - ImGui::BeginDisabled(ins->fm.opllPreset!=0); - if (ImGui::Checkbox(FM_NAME(FM_DM),&dm)) { PARAMETER - fmOrigin.ams=dm; - } - ImGui::EndDisabled(); - ImGui::TableNextColumn(); - if (fmPreviewOn) { - drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); - if (!fmPreviewPaused) { - renderFMPreview(ins,1); - WAKE_UP; - } - } else { - drawAlgorithm(0,FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); - } - kvsConfig(ins,false); - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - - if (ImGui::BeginCombo("##LLPreset",opllInsNames[presentWhich][ins->fm.opllPreset])) { - if (isPresentCount>1) { - if (ImGui::BeginTable("LLPresetList",isPresentCount)) { - ImGui::TableNextRow(ImGuiTableRowFlags_Headers); - for (int i=0; i<4; i++) { - if (!isPresent[i]) continue; - ImGui::TableNextColumn(); - ImGui::Text("%s name",opllVariants[i]); - } - for (int i=0; i<17; i++) { - ImGui::TableNextRow(); - for (int j=0; j<4; j++) { - if (!isPresent[j]) continue; - ImGui::TableNextColumn(); - ImGui::PushID(j*17+i); - if (ImGui::Selectable(opllInsNames[j][i])) { - ins->fm.opllPreset=i; - } - ImGui::PopID(); - } - } - ImGui::EndTable(); - } - } else { - for (int i=0; i<17; i++) { - if (ImGui::Selectable(opllInsNames[presentWhich][i])) { - ins->fm.opllPreset=i; - } - } - } - ImGui::EndCombo(); - } - break; } - default: - break; + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&algMax)); rightClickable + if (ins->type==DIV_INS_OPL) { + if (ImGui::Checkbox("Drums",&drums)) { PARAMETER + ins->fm.opllPreset=drums?16:0; + } + } + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; + } + } else { + drawAlgorithm(ins->fm.alg&algMax,fourOp?FM_ALGS_4OP_OPL:FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + } + kvsConfig(ins); + break; } - ImGui::EndTable(); - } - } else { - // ESFM - if (ImGui::BeginTable("fmDetails",3,ImGuiTableFlags_SizingStretchProp)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.50f); - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.15f); - ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.35f); - - ImGui::TableNextRow(); - { + case DIV_INS_OPLL: { + bool dc=fmOrigin.fms; + bool dm=fmOrigin.ams; + bool sus=ins->fm.alg; + ImGui::TableNextColumn(); + ImGui::BeginDisabled(ins->fm.opllPreset!=0); + P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&fmOrigin.fb,&_ZERO,&_SEVEN)); rightClickable + if (ImGui::Checkbox(FM_NAME(FM_DC),&dc)) { PARAMETER + fmOrigin.fms=dc; + } + ImGui::EndDisabled(); + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_NAME(FM_SUS),&sus)) { PARAMETER + ins->fm.alg=sus; + } + ImGui::BeginDisabled(ins->fm.opllPreset!=0); + if (ImGui::Checkbox(FM_NAME(FM_DM),&dm)) { PARAMETER + fmOrigin.ams=dm; + } + ImGui::EndDisabled(); + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; + } + } else { + drawAlgorithm(0,FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); + } + kvsConfig(ins,false); + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + + if (ImGui::BeginCombo("##LLPreset",opllInsNames[presentWhich][ins->fm.opllPreset])) { + if (isPresentCount>1) { + if (ImGui::BeginTable("LLPresetList",isPresentCount)) { + ImGui::TableNextRow(ImGuiTableRowFlags_Headers); + for (int i=0; i<4; i++) { + if (!isPresent[i]) continue; + ImGui::TableNextColumn(); + ImGui::Text("%s name",opllVariants[i]); + } + for (int i=0; i<17; i++) { + ImGui::TableNextRow(); + for (int j=0; j<4; j++) { + if (!isPresent[j]) continue; + ImGui::TableNextColumn(); + ImGui::PushID(j*17+i); + if (ImGui::Selectable(opllInsNames[j][i])) { + ins->fm.opllPreset=i; + } + ImGui::PopID(); + } + } + ImGui::EndTable(); + } + } else { + for (int i=0; i<17; i++) { + if (ImGui::Selectable(opllInsNames[presentWhich][i])) { + ins->fm.opllPreset=i; + } + } + } + ImGui::EndCombo(); + } + break; + } + case DIV_INS_ESFM: { ImGui::TableNextColumn(); P(CWSliderScalar(ESFM_LONG_NAME(ESFM_NOISE),ImGuiDataType_U8,&ins->esfm.noise,&_ZERO,&_THREE)); rightClickable ImGui::TextUnformatted(esfmNoiseModeNames[ins->esfm.noise&3]); @@ -3329,8 +3315,10 @@ void FurnaceGUI::drawInsEdit() { } kvsConfig(ins); } - ImGui::EndTable(); + default: + break; } + ImGui::EndTable(); } if (((ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL) && ins->fm.opllPreset==16) || ins->type==DIV_INS_OPL_DRUMS) { @@ -3621,7 +3609,7 @@ void FurnaceGUI::drawInsEdit() { else { DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; if (opENext.modIn==0) mod=false; - else if ((opE.outLvl-opENext.modIn) >= 2) mod=false; + else if ((opE.outLvl-opENext.modIn)>=2) mod=false; } } } else if (opCount==4) { @@ -3707,7 +3695,7 @@ void FurnaceGUI::drawInsEdit() { bool susOn=op.sus; bool fixedOn=opE.fixed; unsigned char ssgEnv=op.ssgEnv&7; - + if (ins->type==DIV_INS_ESFM) { ImGui::TableNextColumn(); CENTER_VSLIDER; @@ -4086,7 +4074,7 @@ void FurnaceGUI::drawInsEdit() { else { DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; if (opENext.modIn==0) mod=false; - else if ((opE.outLvl-opENext.modIn) >= 2) mod=false; + else if ((opE.outLvl-opENext.modIn)>=2) mod=false; } } } else if (opCount==4) { @@ -4519,7 +4507,7 @@ void FurnaceGUI::drawInsEdit() { if (block>7) block=7; opE.ct=(opE.ct&(~(7<<2)))|(block<<2); } - + ImGui::Text("F"); if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Frequency (F-Num)"); @@ -4784,7 +4772,7 @@ void FurnaceGUI::drawInsEdit() { else { DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; if (opENext.modIn==0) mod=false; - else if ((opE.outLvl-opENext.modIn) >= 2) mod=false; + else if ((opE.outLvl-opENext.modIn)>=2) mod=false; } } } else if (opCount==4) { diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index 813942d0c..edfdc6730 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -2215,6 +2215,27 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl } break; } + case DIV_SYSTEM_ESFM: { + supportsCustomRate=false; + + // TODO: Remove the text below and uncomment the rest when overflow emulation is added to ESFMu + // (still under research) + ImGui::Text("nothing to configure"); + + // bool emulateOverflow=flags.getBool("emulateOverflow", false); + // + // if (ImGui::Checkbox("Enable overflow emulation", &emulateOverflow)) { + // altered=true; + // mustRender=true; + // } + // + // if (altered) { + // e->lockSave([&]() { + // flags.set("emulateOverflow", emulateOverflow); + // }); + // } + break; + } case DIV_SYSTEM_SWAN: case DIV_SYSTEM_BUBSYS_WSG: case DIV_SYSTEM_PET: @@ -2225,7 +2246,6 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl case DIV_SYSTEM_C219: break; case DIV_SYSTEM_YMU759: - case DIV_SYSTEM_ESFM: supportsCustomRate=false; ImGui::Text("nothing to configure"); break; From 96fbd1524a32ce567dc0ec2ffc15a361abbb36fb Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sun, 22 Oct 2023 16:49:23 -0300 Subject: [PATCH 15/74] Updating ESFMu - accuracy improvements for noise mode --- extern/ESFMu/MODIFIED.md | 6 ----- extern/ESFMu/esfm.c | 58 +++++++++++++++++++++++++++++++++++----- extern/ESFMu/esfm.h | 2 ++ 3 files changed, 54 insertions(+), 12 deletions(-) delete mode 100644 extern/ESFMu/MODIFIED.md diff --git a/extern/ESFMu/MODIFIED.md b/extern/ESFMu/MODIFIED.md deleted file mode 100644 index 78625584c..000000000 --- a/extern/ESFMu/MODIFIED.md +++ /dev/null @@ -1,6 +0,0 @@ -# Modification disclaimer - -This is a modified version of ESFMu v1.0.1 which implements a function for reading the waveform output of the individual FM channels. The modification was made by Kagamiin~ (original author of ESFMu) herself. - -Kagamiin~ notes: -> In hindsight, I might merge back this functionality into a future version of the core, as it could be be useful for generating oscilloscope views in other tools. diff --git a/extern/ESFMu/esfm.c b/extern/ESFMu/esfm.c index f0043fba6..2d1c9afdb 100644 --- a/extern/ESFMu/esfm.c +++ b/extern/ESFMu/esfm.c @@ -196,11 +196,13 @@ static int13 ESFM_envelope_calc_sin0(uint10 phase, uint10 envelope) { uint16 out = 0; - int13 neg = 0; + uint13 neg = 0; + bool inc = 0; phase &= 0x3ff; if (phase & 0x200) { neg = ~(0); + inc = 1; } if (phase & 0x100) { @@ -210,7 +212,7 @@ ESFM_envelope_calc_sin0(uint10 phase, uint10 envelope) { out = logsinrom[phase & 0xff]; } - return ESFM_envelope_calc_exp(out + (envelope << 3)) ^ neg; + return (int13)(((uint13)ESFM_envelope_calc_exp(out + (envelope << 3)) ^ neg) + inc); } /* ------------------------------------------------------------------------- */ @@ -274,10 +276,12 @@ ESFM_envelope_calc_sin4(uint10 phase, uint10 envelope) { uint16 out = 0; int13 neg = 0; + bool inc = 0; phase &= 0x3ff; if ((phase & 0x300) == 0x100) { neg = ~(0); + inc = 1; } if (phase & 0x200) { @@ -291,7 +295,7 @@ ESFM_envelope_calc_sin4(uint10 phase, uint10 envelope) { out = logsinrom[(phase << 1) & 0xff]; } - return ESFM_envelope_calc_exp(out + (envelope << 3)) ^ neg; + return (int13)(((uint13)ESFM_envelope_calc_exp(out + (envelope << 3)) ^ neg) + inc); } /* ------------------------------------------------------------------------- */ @@ -320,12 +324,14 @@ static int13 ESFM_envelope_calc_sin6(uint10 phase, uint10 envelope) { int13 neg = 0; + bool inc = 0; phase &= 0x3ff; if (phase & 0x200) { neg = ~(0); + inc = 1; } - return ESFM_envelope_calc_exp(envelope << 3) ^ neg; + return (int13)(((uint13)ESFM_envelope_calc_exp(envelope << 3) ^ neg) + inc); } /* ------------------------------------------------------------------------- */ @@ -334,14 +340,16 @@ ESFM_envelope_calc_sin7(uint10 phase, uint10 envelope) { uint16 out = 0; int13 neg = 0; + bool inc = 0; phase &= 0x3ff; if (phase & 0x200) { neg = ~(0); + inc = 1; phase = (phase & 0x1ff) ^ 0x1ff; } out = phase << 3; - return ESFM_envelope_calc_exp(out + (envelope << 3)) ^ neg; + return (int13)(((uint13)ESFM_envelope_calc_exp(out + (envelope << 3)) ^ neg) + inc); } /* ------------------------------------------------------------------------- */ @@ -791,6 +799,37 @@ ESFM_phase_generate_emu(esfm_slot *slot) chip->lfsr = (noise >> 1) | (n_bit << 22); } +/** + * TODO: Figure out what's ACTUALLY going on inside the real chip! + * This is not accurate at all, but it's the closest I was able to get with + * empirical testing (and it's closer than nothing). + */ +/* ------------------------------------------------------------------------- */ +static int16 +ESFM_slot3_noise3_mod_input_calc(esfm_slot *slot) +{ + esfm_channel *channel = slot->channel; + envelope_sinfunc wavegen = envelope_sin[channel->slots[2].waveform]; + int16 phase; + int13 output_buf = *channel->slots[1].in.mod_input; + int i; + + // Go through previous slots' partial results and recalculate outputs + // (we skip slot 0 because its calculation happens at the end, not at the beginning) + for (i = 1; i < 3; i++) + { + // double the pitch + phase = channel->slots[i].in.phase_acc >> 8; + if (channel->slots[i].mod_in_level) + { + phase += output_buf >> (7 - channel->slots[i].mod_in_level); + } + output_buf = wavegen((uint10)(phase & 0x3ff), channel->slots[i].in.eg_output); + } + + return output_buf >> (8 - slot->mod_in_level); +} + /* ------------------------------------------------------------------------- */ static void ESFM_slot_generate(esfm_slot *slot) @@ -799,7 +838,14 @@ ESFM_slot_generate(esfm_slot *slot) int16 phase = slot->in.phase_out; if (slot->mod_in_level) { - phase += *slot->in.mod_input >> (7 - slot->mod_in_level); + if (slot->slot_idx == 3 && slot->rhy_noise == 3) + { + phase += ESFM_slot3_noise3_mod_input_calc(slot); + } + else + { + phase += *slot->in.mod_input >> (7 - slot->mod_in_level); + } } slot->in.output = wavegen((uint10)(phase & 0x3ff), slot->in.eg_output); if (slot->output_level) diff --git a/extern/ESFMu/esfm.h b/extern/ESFMu/esfm.h index d5c734b49..70897990b 100644 --- a/extern/ESFMu/esfm.h +++ b/extern/ESFMu/esfm.h @@ -91,6 +91,7 @@ typedef uint_fast16_t uint9; typedef uint_fast16_t uint10; typedef uint_fast16_t uint11; typedef uint_fast16_t uint12; +typedef uint_fast16_t uint13; typedef uint_fast16_t uint16; typedef uint_fast32_t uint19; typedef uint_fast32_t uint23; @@ -114,6 +115,7 @@ typedef uint16_t uint9; typedef uint16_t uint10; typedef uint16_t uint11; typedef uint16_t uint12; +typedef uint16_t uint13; typedef uint16_t uint16; typedef uint32_t uint19; typedef uint32_t uint23; From 39f29f49c34ddc8ff4579978b8ef3d8a22ace674 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sun, 22 Oct 2023 17:28:50 -0300 Subject: [PATCH 16/74] Small fix for potential undefined behavior in ESFM emulator --- extern/ESFMu/esfm.c | 32 ++++++++++++-------------------- extern/ESFMu/esfm.h | 2 -- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/extern/ESFMu/esfm.c b/extern/ESFMu/esfm.c index 2d1c9afdb..54af9cc30 100644 --- a/extern/ESFMu/esfm.c +++ b/extern/ESFMu/esfm.c @@ -196,13 +196,11 @@ static int13 ESFM_envelope_calc_sin0(uint10 phase, uint10 envelope) { uint16 out = 0; - uint13 neg = 0; - bool inc = 0; + int13 neg = 1; phase &= 0x3ff; if (phase & 0x200) { - neg = ~(0); - inc = 1; + neg = -1; } if (phase & 0x100) { @@ -212,7 +210,7 @@ ESFM_envelope_calc_sin0(uint10 phase, uint10 envelope) { out = logsinrom[phase & 0xff]; } - return (int13)(((uint13)ESFM_envelope_calc_exp(out + (envelope << 3)) ^ neg) + inc); + return ESFM_envelope_calc_exp(out + (envelope << 3)) * neg; } /* ------------------------------------------------------------------------- */ @@ -275,13 +273,11 @@ static int13 ESFM_envelope_calc_sin4(uint10 phase, uint10 envelope) { uint16 out = 0; - int13 neg = 0; - bool inc = 0; + int13 neg = 1; phase &= 0x3ff; if ((phase & 0x300) == 0x100) { - neg = ~(0); - inc = 1; + neg = -1; } if (phase & 0x200) { @@ -295,7 +291,7 @@ ESFM_envelope_calc_sin4(uint10 phase, uint10 envelope) { out = logsinrom[(phase << 1) & 0xff]; } - return (int13)(((uint13)ESFM_envelope_calc_exp(out + (envelope << 3)) ^ neg) + inc); + return ESFM_envelope_calc_exp(out + (envelope << 3)) * neg; } /* ------------------------------------------------------------------------- */ @@ -323,15 +319,13 @@ ESFM_envelope_calc_sin5(uint10 phase, uint10 envelope) static int13 ESFM_envelope_calc_sin6(uint10 phase, uint10 envelope) { - int13 neg = 0; - bool inc = 0; + int13 neg = 1; phase &= 0x3ff; if (phase & 0x200) { - neg = ~(0); - inc = 1; + neg = -1; } - return (int13)(((uint13)ESFM_envelope_calc_exp(envelope << 3) ^ neg) + inc); + return ESFM_envelope_calc_exp(envelope << 3) * neg; } /* ------------------------------------------------------------------------- */ @@ -339,17 +333,15 @@ static int13 ESFM_envelope_calc_sin7(uint10 phase, uint10 envelope) { uint16 out = 0; - int13 neg = 0; - bool inc = 0; + int13 neg = 1; phase &= 0x3ff; if (phase & 0x200) { - neg = ~(0); - inc = 1; + neg = -1; phase = (phase & 0x1ff) ^ 0x1ff; } out = phase << 3; - return (int13)(((uint13)ESFM_envelope_calc_exp(out + (envelope << 3)) ^ neg) + inc); + return ESFM_envelope_calc_exp(out + (envelope << 3)) * neg; } /* ------------------------------------------------------------------------- */ diff --git a/extern/ESFMu/esfm.h b/extern/ESFMu/esfm.h index 70897990b..d5c734b49 100644 --- a/extern/ESFMu/esfm.h +++ b/extern/ESFMu/esfm.h @@ -91,7 +91,6 @@ typedef uint_fast16_t uint9; typedef uint_fast16_t uint10; typedef uint_fast16_t uint11; typedef uint_fast16_t uint12; -typedef uint_fast16_t uint13; typedef uint_fast16_t uint16; typedef uint_fast32_t uint19; typedef uint_fast32_t uint23; @@ -115,7 +114,6 @@ typedef uint16_t uint9; typedef uint16_t uint10; typedef uint16_t uint11; typedef uint16_t uint12; -typedef uint16_t uint13; typedef uint16_t uint16; typedef uint32_t uint19; typedef uint32_t uint23; From 23b1c4107ea436ad54f252d80821573d53514c78 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 24 Oct 2023 14:29:37 -0300 Subject: [PATCH 17/74] Fix hard reset handling; add detune effect; change some labels --- src/engine/platform/esfm.cpp | 15 +++++++++++++++ src/engine/sysDef.cpp | 12 ++++++++++-- src/gui/insEdit.cpp | 10 +++++++--- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 59a91d05b..88d7a8051 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -265,6 +265,7 @@ void DivPlatformESFM::tick(bool sysTick) { } } + int hardResetElapsed=0; bool mustHardReset=false; for (int i=0; i<18; i++) { @@ -285,6 +286,7 @@ void DivPlatformESFM::tick(bool sysTick) { for (int o=0; o<4; o++) { unsigned short baseAddr=i*32+o*8; immWrite(baseAddr+OFFSET_SL_RR,0x0f); + hardResetElapsed++; } } } @@ -313,6 +315,7 @@ void DivPlatformESFM::tick(bool sysTick) { } immWrite(baseAddr+OFFSET_FREQL,chan[i].freqL[o]); immWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[i].freqH[o]|(opE.delay<<5)); + hardResetElapsed+=2; } chan[i].freqChanged=false; } @@ -330,6 +333,9 @@ void DivPlatformESFM::tick(bool sysTick) { } if (mustHardReset) { + for (unsigned int i=hardResetElapsed; i<128; i++) { + immWrite(0x25f, i&0xff); + } for (int i=0; i<18; i++) { if (chan[i].hardReset && chan[i].keyOn) { // logI("chan[%d] hard reset key on, writing original slrr back", i); @@ -890,6 +896,15 @@ int DivPlatformESFM::dispatch(DivCommand c) { } break; } + case DIV_CMD_FM_DT: { + unsigned int o=c.value; + if (o >= 4) break; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + if (opE.fixed) break; + opE.dt=c.value2; + chan[c.chan].freqChanged=true; + break; + } case DIV_CMD_FM_HARD_RESET: chan[c.chan].hardReset=c.value; break; diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index 8ae4ab357..9e086a425 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -396,6 +396,10 @@ int effectValNibbleFlagPackReversed(unsigned char, unsigned char val) { return (((val&0x0f)!=0)<<1)|((val&0xf0)!=0); } +int effectValExcessOf80Hex(unsigned char, unsigned char val) { + return val-0x80; +} + template int effectValAnd(unsigned char, unsigned char val) { return val&mask; }; @@ -617,18 +621,18 @@ void DivEngine::registerSystems() { }; EffectHandlerMap fmESFMPostEffectHandlerMap={ + {0x10, {DIV_CMD_FM_AM_DEPTH, "10xy: Set AM depth (x: operator from 1 to 4 (0 for all ops); y: depth (0: 1dB, 1: 4.8dB))", effectOpVal<4>, effectValAnd<1>}}, {0x12, {DIV_CMD_FM_TL, "12xx: Set level of operator 1 (0 highest, 3F lowest)", constVal<0>, effectVal}}, {0x13, {DIV_CMD_FM_TL, "13xx: Set level of operator 2 (0 highest, 3F lowest)", constVal<1>, effectVal}}, {0x14, {DIV_CMD_FM_TL, "14xx: Set level of operator 3 (0 highest, 3F lowest)", constVal<2>, effectVal}}, {0x15, {DIV_CMD_FM_TL, "15xx: Set level of operator 4 (0 highest, 3F lowest)", constVal<3>, effectVal}}, {0x16, {DIV_CMD_FM_MULT, "16xy: Set operator multiplier (x: operator from 1 to 4; y: multiplier)", effectOpValNoZero<4>, effectValAnd<15>}}, + {0x17, {DIV_CMD_FM_PM_DEPTH, "17xy: Set vibrato depth (x: operator from 1 to 4 (0 for all ops); y: depth (0: normal, 1: double))", effectOpVal<4>, effectValAnd<1>}}, {0x19, {DIV_CMD_FM_AR, "19xx: Set attack of all operators (0 to F)", constVal<-1>, effectValAnd<15>}}, {0x1a, {DIV_CMD_FM_AR, "1Axx: Set attack of operator 1 (0 to F)", constVal<0>, effectValAnd<15>}}, {0x1b, {DIV_CMD_FM_AR, "1Bxx: Set attack of operator 2 (0 to F)", constVal<1>, effectValAnd<15>}}, {0x1c, {DIV_CMD_FM_AR, "1Cxx: Set attack of operator 3 (0 to F)", constVal<2>, effectValAnd<15>}}, {0x1d, {DIV_CMD_FM_AR, "1Dxx: Set attack of operator 4 (0 to F)", constVal<3>, effectValAnd<15>}}, - {0x1e, {DIV_CMD_FM_AM_DEPTH, "1Exy: Set AM depth (x: operator from 1 to 4 (0 for all ops); y: depth (0: 1dB, 1: 4.8dB))", effectOpVal<4>, effectValAnd<1>}}, - {0x1f, {DIV_CMD_FM_PM_DEPTH, "1Fxy: Set vibrato depth (x: operator from 1 to 4 (0 for all ops); y: depth (0: normal, 1: double))", effectOpVal<4>, effectValAnd<1>}}, {0x20, {DIV_CMD_ESFM_OP_PANNING, "20xy: Set panning of operator 1 (x: left; y: right)", constVal<0>, effectValNibbleFlagPackReversed}}, {0x21, {DIV_CMD_ESFM_OP_PANNING, "21xy: Set panning of operator 2 (x: left; y: right)", constVal<1>, effectValNibbleFlagPackReversed}}, {0x22, {DIV_CMD_ESFM_OP_PANNING, "22xy: Set panning of operator 3 (x: left; y: right)", constVal<2>, effectValNibbleFlagPackReversed}}, @@ -639,6 +643,10 @@ void DivEngine::registerSystems() { {0x27, {DIV_CMD_STD_NOISE_MODE, "27xx: Set noise mode for operator 4 (x: mode from 0 to 3)", effectValAnd<3>}}, {0x2a, {DIV_CMD_FM_WS, "2Axy: Set waveform (x: operator from 1 to 4 (0 for all ops); y: waveform from 0 to 7)", effectOpVal<4>, effectValAnd<7>}}, {0x2f, {DIV_CMD_FM_FIXFREQ, "2Fxy: Set fixed frequency block (x: operator from 1 to 4; y: octave from 0 to 7)", effectOpValNoZero<4>, effectValAnd<7>}}, + {0x40, {DIV_CMD_FM_DT, "40xx: Set detune of operator 1 (80 = base pitch)", constVal<0>, effectValExcessOf80Hex}}, + {0x41, {DIV_CMD_FM_DT, "41xx: Set detune of operator 2 (80 = base pitch)", constVal<1>, effectValExcessOf80Hex}}, + {0x42, {DIV_CMD_FM_DT, "42xx: Set detune of operator 3 (80 = base pitch)", constVal<2>, effectValExcessOf80Hex}}, + {0x43, {DIV_CMD_FM_DT, "43xx: Set detune of operator 4 (80 = base pitch)", constVal<3>, effectValExcessOf80Hex}}, {0x50, {DIV_CMD_FM_AM, "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)", effectOpVal<4>, effectValAnd<1>}}, {0x51, {DIV_CMD_FM_SL, "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)", effectOpVal<4>, effectValAnd<15>}}, {0x52, {DIV_CMD_FM_RR, "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)", effectOpVal<4>, effectValAnd<15>}}, diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 873760d85..fbc054b0b 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -166,7 +166,11 @@ const char* oplDrumNames[4]={ }; const char* esfmNoiseModeNames[4]={ - "Noise disabled", "Snare (square + noise)", "HiHat (ringmod from OP3, + noise)", "Top (ringmod from OP3)\nWARNING - not emulated properly! Will change in future versions." + "Normal", "Snare", "HiHat", "Top" +}; + +const char* esfmNoiseModeDescriptions[4]={ + "Noise disabled", "Square + noise", "Ringmod from OP3 + noise", "Ringmod from OP3 + double pitch ModInput\nWARNING - has emulation issues, subject to change" }; const bool opIsOutput[8][4]={ @@ -3300,8 +3304,8 @@ void FurnaceGUI::drawInsEdit() { } case DIV_INS_ESFM: { ImGui::TableNextColumn(); - P(CWSliderScalar(ESFM_LONG_NAME(ESFM_NOISE),ImGuiDataType_U8,&ins->esfm.noise,&_ZERO,&_THREE)); rightClickable - ImGui::TextUnformatted(esfmNoiseModeNames[ins->esfm.noise&3]); + P(CWSliderScalar(ESFM_LONG_NAME(ESFM_NOISE),ImGuiDataType_U8,&ins->esfm.noise,&_ZERO,&_THREE,esfmNoiseModeNames[ins->esfm.noise&3])); rightClickable + ImGui::TextUnformatted(esfmNoiseModeDescriptions[ins->esfm.noise&3]); ImGui::TableNextColumn(); ImGui::TableNextColumn(); if (fmPreviewOn) { From b79938335155e8d436b16245071380e2388c1042 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 24 Oct 2023 14:34:26 -0300 Subject: [PATCH 18/74] Changing detune effect description for consistency --- src/engine/sysDef.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index 9e086a425..8f6aa6021 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -643,10 +643,10 @@ void DivEngine::registerSystems() { {0x27, {DIV_CMD_STD_NOISE_MODE, "27xx: Set noise mode for operator 4 (x: mode from 0 to 3)", effectValAnd<3>}}, {0x2a, {DIV_CMD_FM_WS, "2Axy: Set waveform (x: operator from 1 to 4 (0 for all ops); y: waveform from 0 to 7)", effectOpVal<4>, effectValAnd<7>}}, {0x2f, {DIV_CMD_FM_FIXFREQ, "2Fxy: Set fixed frequency block (x: operator from 1 to 4; y: octave from 0 to 7)", effectOpValNoZero<4>, effectValAnd<7>}}, - {0x40, {DIV_CMD_FM_DT, "40xx: Set detune of operator 1 (80 = base pitch)", constVal<0>, effectValExcessOf80Hex}}, - {0x41, {DIV_CMD_FM_DT, "41xx: Set detune of operator 2 (80 = base pitch)", constVal<1>, effectValExcessOf80Hex}}, - {0x42, {DIV_CMD_FM_DT, "42xx: Set detune of operator 3 (80 = base pitch)", constVal<2>, effectValExcessOf80Hex}}, - {0x43, {DIV_CMD_FM_DT, "43xx: Set detune of operator 4 (80 = base pitch)", constVal<3>, effectValExcessOf80Hex}}, + {0x40, {DIV_CMD_FM_DT, "40xx: Set detune of operator 1 (80: center)", constVal<0>, effectValExcessOf80Hex}}, + {0x41, {DIV_CMD_FM_DT, "41xx: Set detune of operator 2 (80: center)", constVal<1>, effectValExcessOf80Hex}}, + {0x42, {DIV_CMD_FM_DT, "42xx: Set detune of operator 3 (80: center)", constVal<2>, effectValExcessOf80Hex}}, + {0x43, {DIV_CMD_FM_DT, "43xx: Set detune of operator 4 (80: center)", constVal<3>, effectValExcessOf80Hex}}, {0x50, {DIV_CMD_FM_AM, "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)", effectOpVal<4>, effectValAnd<1>}}, {0x51, {DIV_CMD_FM_SL, "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)", effectOpVal<4>, effectValAnd<15>}}, {0x52, {DIV_CMD_FM_RR, "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)", effectOpVal<4>, effectValAnd<15>}}, From 7d0eee7a95026843c45716c6305827e41ead4989 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 24 Oct 2023 14:49:12 -0300 Subject: [PATCH 19/74] Removing dash from system name Because it causes problems with e.g. KDE in the window title. --- src/engine/sysDef.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index 8f6aa6021..7c92997fa 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1977,7 +1977,7 @@ void DivEngine::registerSystems() { ); sysDefs[DIV_SYSTEM_ESFM]=new DivSysDef( - "ESS ES1xxx-series (ESFM)", NULL, 0xd0, 0, 18, true, false, 0, false, 0, + "ESS ES1xxx series (ESFM)", NULL, 0xd0, 0, 18, true, false, 0, false, 0, "A unique FM synth featured in PC sound cards.\nBased on the OPL3 design, but with lots of its features extended.", {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "FM 9", "FM 10", "FM 11", "FM 12", "FM 13", "FM 14", "FM 15", "FM 16", "FM 17", "FM 18"}, {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18"}, From 928ff5c2d8cf199665f94eacb9bfda8751c794c4 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Tue, 24 Oct 2023 14:59:00 -0300 Subject: [PATCH 20/74] Removing placeholder --- src/gui/sysConf.cpp | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index edfdc6730..813942d0c 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -2215,27 +2215,6 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl } break; } - case DIV_SYSTEM_ESFM: { - supportsCustomRate=false; - - // TODO: Remove the text below and uncomment the rest when overflow emulation is added to ESFMu - // (still under research) - ImGui::Text("nothing to configure"); - - // bool emulateOverflow=flags.getBool("emulateOverflow", false); - // - // if (ImGui::Checkbox("Enable overflow emulation", &emulateOverflow)) { - // altered=true; - // mustRender=true; - // } - // - // if (altered) { - // e->lockSave([&]() { - // flags.set("emulateOverflow", emulateOverflow); - // }); - // } - break; - } case DIV_SYSTEM_SWAN: case DIV_SYSTEM_BUBSYS_WSG: case DIV_SYSTEM_PET: @@ -2246,6 +2225,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl case DIV_SYSTEM_C219: break; case DIV_SYSTEM_YMU759: + case DIV_SYSTEM_ESFM: supportsCustomRate=false; ImGui::Text("nothing to configure"); break; From f25d254eea82695358eaaf31ad408ad2a807ecc7 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 25 Oct 2023 10:10:59 -0300 Subject: [PATCH 21/74] Adding system presets for ESFM --- src/gui/presets.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/gui/presets.cpp b/src/gui/presets.cpp index b83794638..74599b4ba 100644 --- a/src/gui/presets.cpp +++ b/src/gui/presets.cpp @@ -1070,6 +1070,17 @@ void FurnaceGUI::initSystemPresets() { CH(DIV_SYSTEM_PCSPKR, 1.0f, 0, "") } ); + ENTRY( + "PC + ESS ES1488 (native ESFM mode)", { + CH(DIV_SYSTEM_ESFM, 1.0f, 0, ""), + CH(DIV_SYSTEM_PCM_DAC, 1.0f, 0, + "rate=44100\n" + "outDepth=15\n" + "stereo=true\n" + ), + CH(DIV_SYSTEM_PCSPKR, 1.0f, 0, "") + } + ); ENTRY( "PC + PC-FXGA", { CH(DIV_SYSTEM_PCE, 1.0f, 0, ""), // HuC6230 (WSG from HuC6280 but with built in 2 OKI ADPCM playback engines) @@ -2364,6 +2375,11 @@ void FurnaceGUI::initSystemPresets() { ) } ); + ENTRY( + "ESS ES1xxx series (ESFM)", { + CH(DIV_SYSTEM_ESFM, 1.0f, 0, "") + } + ); if (settings.hiddenSystems) { ENTRY( "Yamaha YMU759 (MA-2)", { From 6ae49e4985c41976d220a6be0dce4b466f81ecda Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 25 Oct 2023 12:32:58 -0300 Subject: [PATCH 22/74] Rectifying ESFM preset name --- src/gui/presets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/presets.cpp b/src/gui/presets.cpp index 74599b4ba..9947f29c7 100644 --- a/src/gui/presets.cpp +++ b/src/gui/presets.cpp @@ -1071,7 +1071,7 @@ void FurnaceGUI::initSystemPresets() { } ); ENTRY( - "PC + ESS ES1488 (native ESFM mode)", { + "PC + ESS AudioDrive ES1488 (native ESFM mode)", { CH(DIV_SYSTEM_ESFM, 1.0f, 0, ""), CH(DIV_SYSTEM_PCM_DAC, 1.0f, 0, "rate=44100\n" From 91e6d848e60724511966b439692ba9657e01d880 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 25 Oct 2023 13:49:57 -0300 Subject: [PATCH 23/74] Changing ESFM chip ID (0xd0 is taken) --- src/engine/sysDef.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index 7c92997fa..f676b62d2 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1977,7 +1977,7 @@ void DivEngine::registerSystems() { ); sysDefs[DIV_SYSTEM_ESFM]=new DivSysDef( - "ESS ES1xxx series (ESFM)", NULL, 0xd0, 0, 18, true, false, 0, false, 0, + "ESS ES1xxx series (ESFM)", NULL, 0xd1, 0, 18, true, false, 0, false, 0, "A unique FM synth featured in PC sound cards.\nBased on the OPL3 design, but with lots of its features extended.", {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "FM 9", "FM 10", "FM 11", "FM 12", "FM 13", "FM 14", "FM 15", "FM 16", "FM 17", "FM 18"}, {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18"}, From d47fcd96168c64acb9dd4c76af222c14f1770e63 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 25 Oct 2023 14:02:52 -0300 Subject: [PATCH 24/74] Adding placeholder for Namco C352 --- src/engine/song.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/song.h b/src/engine/song.h index 4545ed126..fd7304050 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -132,6 +132,7 @@ enum DivSystem { DIV_SYSTEM_TED, DIV_SYSTEM_C140, DIV_SYSTEM_C219, + DIV_SYSTEM_C352, DIV_SYSTEM_ESFM }; From 59d56b169bed9989a519c9007f3b78a0bb304630 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 25 Oct 2023 17:33:57 -0300 Subject: [PATCH 25/74] Removing stray space --- src/engine/instrument.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 40559cf59..244b104c0 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -151,8 +151,6 @@ enum DivMacroTypeOp: unsigned char { // - AM, AR, DR, MULT (CRS), RR, SL, TL, DT2, RS, DT, D2R // - WS, DVB = MULT (FINE), DAM = REV, KSL = EGShift, EGT = Fixed - - struct DivInstrumentFM { unsigned char alg, fb, fms, ams, fms2, ams2, ops, opllPreset; bool fixedDrums; From 170248e61a65c1953da707a854a6e0192a394a86 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Thu, 26 Oct 2023 09:43:01 -0300 Subject: [PATCH 26/74] Code review suggestions Haven't had a good peer review in ages. --- .gitignore | 1 - extern/ESFMu/.clangd | 2 - src/engine/platform/esfm.cpp | 222 +++++++++++++++++------------------ src/engine/platform/esfm.h | 4 +- src/engine/song.h | 1 - src/engine/sysDef.cpp | 26 ++-- src/gui/insEdit.cpp | 2 +- 7 files changed, 122 insertions(+), 136 deletions(-) delete mode 100644 extern/ESFMu/.clangd diff --git a/.gitignore b/.gitignore index 06812e61e..09314bb24 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,3 @@ res/docpdf/manual.pdf res/docpdf/.venv res/docpdf/htmldoc/ res/furnace.appdata.xml -compile_commands.json diff --git a/extern/ESFMu/.clangd b/extern/ESFMu/.clangd deleted file mode 100644 index f6023d41f..000000000 --- a/extern/ESFMu/.clangd +++ /dev/null @@ -1,2 +0,0 @@ -CompileFlags: - Add: ["-xc", "-Wall", "-Wextra"] diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 88d7a8051..f02fd6ef5 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -26,14 +26,14 @@ #define CHIP_FREQBASE (32768*288) -#define OFFSET_AM_VIB_SUS_KSR_MULT 0x00 -#define OFFSET_KSL_TL 0x01 -#define OFFSET_AR_DR 0x02 -#define OFFSET_SL_RR 0x03 -#define OFFSET_FREQL 0x04 -#define OFFSET_FREQH_BLOCK_DELAY 0x05 -#define OFFSET_DAM_DVB_LEFT_RIGHT_MODIN 0x06 -#define OFFSET_OUTLVL_NOISE_WS 0x07 +#define ADDR_AM_VIB_SUS_KSR_MULT 0x00 +#define ADDR_KSL_TL 0x01 +#define ADDR_AR_DR 0x02 +#define ADDR_SL_RR 0x03 +#define ADDR_FREQL 0x04 +#define ADDR_FREQH_BLOCK_DELAY 0x05 +#define ADDR_DAM_DVB_LEFT_RIGHT_MODIN 0x06 +#define ADDR_OUTLVL_NOISE_WS 0x07 #define KEY_ON_REGS_START (18*8*4) @@ -72,13 +72,13 @@ void DivPlatformESFM::tick(bool sysTick) { unsigned char noise=chan[i].state.esfm.noise&3; if (isMuted[i]) { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); } else { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); - if (KVS(i, o)) { - rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[i].outVol&0x3f,63))|(op.ksl<<6)); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + if (KVS(i,o)) { + rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[i].outVol&0x3f,63))|(op.ksl<<6)); } else { - rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); } } } @@ -99,7 +99,7 @@ void DivPlatformESFM::tick(bool sysTick) { unsigned short baseAddr=i*32+o*8; DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o]; - rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + rWrite(baseAddr+ADDR_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); } } @@ -120,17 +120,16 @@ void DivPlatformESFM::tick(bool sysTick) { } if (chan[i].std.duty.had) { - int o=3; - unsigned short baseAddr=i*32+o*8; + unsigned short baseAddr=i*32+3*8; DivInstrumentESFM& ins=chan[i].state.esfm; - DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; - DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o]; + DivInstrumentFM::Operator& op=chan[i].state.fm.op[3]; + DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[3]; ins.noise=chan[i].std.duty.val; if (isMuted[i]) { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?ins.noise&3:0)<<3)|0); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((ins.noise&3)<<3)|0); } else { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?ins.noise&3:0)<<3)|((opE.outLvl&7)<<5)); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((ins.noise&3)<<3)|((opE.outLvl&7)<<5)); } } @@ -142,40 +141,40 @@ void DivPlatformESFM::tick(bool sysTick) { if (m.am.had) { op.am=m.am.val; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } if (m.vib.had) { op.vib=m.vib.val; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } if (m.sus.had) { op.sus=m.sus.val; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } if (m.ksr.had) { op.ksr=m.ksr.val; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } if (m.mult.had) { op.mult=m.mult.val; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } if (m.ar.had) { op.ar=m.ar.val; - rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); + rWrite(baseAddr+ADDR_AR_DR,(op.ar<<4)|(op.dr&0xf)); } if (m.dr.had) { op.dr=m.dr.val; - rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); + rWrite(baseAddr+ADDR_AR_DR,(op.ar<<4)|(op.dr&0xf)); } if (m.sl.had) { op.sl=m.sl.val; - rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); + rWrite(baseAddr+ADDR_SL_RR,(op.sl<<4)|(op.rr&0xf)); } if (m.rr.had) { op.rr=m.rr.val; - rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); + rWrite(baseAddr+ADDR_SL_RR,(op.sl<<4)|(op.rr&0xf)); } if (m.tl.had || m.ksl.had) { @@ -187,30 +186,30 @@ void DivPlatformESFM::tick(bool sysTick) { } if (KVS(i, o)) { - rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[i].outVol&0x3f,63))|(op.ksl<<6)); + rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[i].outVol&0x3f,63))|(op.ksl<<6)); } else { - rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); } } if (m.dam.had) { op.dam=m.dam.val; - rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + rWrite(baseAddr+ADDR_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); } if (m.dvb.had) { op.dvb=m.dvb.val; - rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + rWrite(baseAddr+ADDR_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); } if (m.rs.had) { // operator panning opE.left=(m.rs.val&2)!=0; opE.right=(m.rs.val&1)!=0; - rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + rWrite(baseAddr+ADDR_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); } if (m.d2r.had) { // modIn opE.modIn=m.d2r.val; - rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + rWrite(baseAddr+ADDR_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); } if (m.egt.had | m.ws.had) { @@ -224,9 +223,9 @@ void DivPlatformESFM::tick(bool sysTick) { } if (isMuted[i]) { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); } else { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); } } @@ -253,7 +252,7 @@ void DivPlatformESFM::tick(bool sysTick) { } if (m.dt2.had) { opE.delay=m.dt2.val; - rWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[i].freqH[o]|(opE.delay<<5)); + rWrite(baseAddr+ADDR_FREQH_BLOCK_DELAY,chan[i].freqH[o]|(opE.delay<<5)); } } } @@ -285,7 +284,7 @@ void DivPlatformESFM::tick(bool sysTick) { // logI("chan[%d] hard reset, slrr := 0x0f", i); for (int o=0; o<4; o++) { unsigned short baseAddr=i*32+o*8; - immWrite(baseAddr+OFFSET_SL_RR,0x0f); + immWrite(baseAddr+ADDR_SL_RR,0x0f); hardResetElapsed++; } } @@ -313,8 +312,8 @@ void DivPlatformESFM::tick(bool sysTick) { chan[i].freqL[o]=freqt&0xff; chan[i].freqH[o]=freqt>>8; } - immWrite(baseAddr+OFFSET_FREQL,chan[i].freqL[o]); - immWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[i].freqH[o]|(opE.delay<<5)); + immWrite(baseAddr+ADDR_FREQL,chan[i].freqL[o]); + immWrite(baseAddr+ADDR_FREQH_BLOCK_DELAY,chan[i].freqH[o]|(opE.delay<<5)); hardResetElapsed+=2; } chan[i].freqChanged=false; @@ -342,7 +341,7 @@ void DivPlatformESFM::tick(bool sysTick) { for (int o=0; o<4; o++) { unsigned short baseAddr=i*32+o*8; DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; - immWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); + immWrite(baseAddr+ADDR_SL_RR,(op.sl<<4)|(op.rr&0xf)); } if (i<16) { immWrite(KEY_ON_REGS_START+i, 1); @@ -385,13 +384,13 @@ void DivPlatformESFM::muteChannel(int ch, bool mute) { unsigned char noise=chan[ch].state.esfm.noise&3; if (isMuted[ch]) { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); } else { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); - if (KVS(ch, o)) { - rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[ch].outVol&0x3f,63))|(op.ksl<<6)); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + if (KVS(ch,o)) { + rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[ch].outVol&0x3f,63))|(op.ksl<<6)); } else { - rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); } } } @@ -408,21 +407,21 @@ void DivPlatformESFM::commitState(int ch, DivInstrument* ins) { unsigned char noise=chan[ch].state.esfm.noise&3; if (isMuted[ch]) { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); } else { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); - if (KVS(ch, o)) { - rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[ch].outVol&0x3f,63))|(op.ksl<<6)); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + if (KVS(ch,o)) { + rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[ch].outVol&0x3f,63))|(op.ksl<<6)); } else { - rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); } } - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); - rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); - rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); - rWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[ch].freqH[o]|(opE.delay<<5)); - rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[ch].globalPan)&1)<<4)|(((opE.right&(chan[ch].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AR_DR,(op.ar<<4)|(op.dr&0xf)); + rWrite(baseAddr+ADDR_SL_RR,(op.sl<<4)|(op.rr&0xf)); + rWrite(baseAddr+ADDR_FREQH_BLOCK_DELAY,chan[ch].freqH[o]|(opE.delay<<5)); + rWrite(baseAddr+ADDR_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[ch].globalPan)&1)<<4)|(((opE.right&(chan[ch].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); } } } @@ -471,10 +470,10 @@ int DivPlatformESFM::dispatch(DivCommand c) { for (int o=0; o<4; o++) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; - if (KVS(c.chan, o)) { - rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); + if (KVS(c.chan,o)) { + rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); } else { - rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); } } break; @@ -494,7 +493,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; - rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + rWrite(baseAddr+ADDR_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); } break; } @@ -551,7 +550,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.mult=c.value2&15; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); break; } case DIV_CMD_FM_TL: { @@ -560,10 +559,10 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.tl=c.value2&63; - if (KVS(c.chan, o)) { - rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); + if (KVS(c.chan,o)) { + rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); } else { - rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); } break; } @@ -573,7 +572,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ar=c.value2&15; - rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); + rWrite(baseAddr+ADDR_AR_DR,(op.ar<<4)|(op.dr&0xf)); } } else { unsigned int o=c.value; @@ -581,7 +580,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ar=c.value2&15; - rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); + rWrite(baseAddr+ADDR_AR_DR,(op.ar<<4)|(op.dr&0xf)); } break; } @@ -591,7 +590,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.dr=c.value2&15; - rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); + rWrite(baseAddr+ADDR_AR_DR,(op.ar<<4)|(op.dr&0xf)); } } else { unsigned int o=c.value; @@ -599,7 +598,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.dr=c.value2&15; - rWrite(baseAddr+OFFSET_AR_DR,(op.ar<<4)|(op.dr&0xf)); + rWrite(baseAddr+ADDR_AR_DR,(op.ar<<4)|(op.dr&0xf)); } break; } @@ -609,7 +608,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.sl=c.value2&15; - rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); + rWrite(baseAddr+ADDR_SL_RR,(op.sl<<4)|(op.rr&0xf)); } } else { unsigned int o=c.value; @@ -617,7 +616,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.sl=c.value2&15; - rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); + rWrite(baseAddr+ADDR_SL_RR,(op.sl<<4)|(op.rr&0xf)); } break; } @@ -627,7 +626,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.rr=c.value2&15; - rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); + rWrite(baseAddr+ADDR_SL_RR,(op.sl<<4)|(op.rr&0xf)); } } else { unsigned int o=c.value; @@ -635,7 +634,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.rr=c.value2&15; - rWrite(baseAddr+OFFSET_SL_RR,(op.sl<<4)|(op.rr&0xf)); + rWrite(baseAddr+ADDR_SL_RR,(op.sl<<4)|(op.rr&0xf)); } break; } @@ -645,7 +644,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.am=c.value2&1; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } } else { unsigned int o=c.value; @@ -653,7 +652,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.am=c.value2&1; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } break; } @@ -663,7 +662,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.vib=c.value2&1; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } } else { unsigned int o=c.value; @@ -671,7 +670,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.vib=c.value2&1; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } break; } @@ -681,7 +680,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.sus=c.value2&1; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } } else { unsigned int o=c.value; @@ -689,7 +688,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.sus=c.value2&1; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } break; } @@ -699,7 +698,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ksr=c.value2&1; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } } else { unsigned int o=c.value; @@ -707,7 +706,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ksr=c.value2&1; - rWrite(baseAddr+OFFSET_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); + rWrite(baseAddr+ADDR_AM_VIB_SUS_KSR_MULT,((op.am&1)<<7)|((op.vib&1)<<6)|((op.sus&1)<<5)|((op.ksr&1)<<4)|(op.mult&0xf)); } break; } @@ -720,9 +719,9 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned char noise=chan[c.chan].state.esfm.noise&3; op.ws=c.value2&7; if (isMuted[c.chan]) { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); } else { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); } } } else { @@ -734,9 +733,9 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned char noise=chan[c.chan].state.esfm.noise&3; op.ws=c.value2&7; if (isMuted[c.chan]) { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); } else { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); } } break; @@ -748,10 +747,10 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ksl=c.value2&3; - if (KVS(c.chan, o)) { - rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); + if (KVS(c.chan,o)) { + rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); } else { - rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); } } } else { @@ -760,10 +759,10 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ksl=c.value2&3; - if (KVS(c.chan, o)) { - rWrite(baseAddr+OFFSET_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); + if (KVS(c.chan,o)) { + rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); } else { - rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); + rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); } } break; @@ -775,7 +774,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; op.dam=c.value2&1; - rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + rWrite(baseAddr+ADDR_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); break; } case DIV_CMD_FM_PM_DEPTH: { @@ -785,7 +784,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; op.dvb=c.value2&1; - rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + rWrite(baseAddr+ADDR_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); break; } case DIV_CMD_FM_FIXFREQ: { @@ -809,9 +808,9 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; - opE.left=c.value2&1; - opE.right=(c.value2&2)>>1; - rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + opE.left=(c.value2&0xf0)!=0; + opE.right=(c.value2&0x0f)!=0; + rWrite(baseAddr+ADDR_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); break; } case DIV_CMD_ESFM_OUTLVL: { @@ -823,9 +822,9 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned char noise=chan[c.chan].state.esfm.noise&3; opE.outLvl=c.value2&7; if (isMuted[c.chan]) { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); } else { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); } } } else { @@ -837,9 +836,9 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned char noise=chan[c.chan].state.esfm.noise&3; opE.outLvl=c.value2&7; if (isMuted[c.chan]) { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); } else { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); } } break; @@ -851,7 +850,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; opE.modIn=c.value2&7; - rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + rWrite(baseAddr+ADDR_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); } } else { unsigned int o=c.value; @@ -860,7 +859,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; opE.modIn=c.value2&7; - rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); + rWrite(baseAddr+ADDR_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[c.chan].globalPan)&1)<<4)|(((opE.right&(chan[c.chan].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7)); } break; } @@ -870,7 +869,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; opE.delay=c.value2&7; - rWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[c.chan].freqH[o]|(opE.delay<<5)); + rWrite(baseAddr+ADDR_FREQH_BLOCK_DELAY,chan[c.chan].freqH[o]|(opE.delay<<5)); } } else { unsigned int o=c.value; @@ -878,21 +877,20 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; opE.delay=c.value2&7; - rWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[c.chan].freqH[o]|(opE.delay<<5)); + rWrite(baseAddr+ADDR_FREQH_BLOCK_DELAY,chan[c.chan].freqH[o]|(opE.delay<<5)); } break; } case DIV_CMD_STD_NOISE_MODE: { - unsigned int o=3; - unsigned short baseAddr=c.chan*32+o*8; - DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; - DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; + unsigned short baseAddr=c.chan*32+3*8; + DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[3]; + DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[3]; DivInstrumentESFM insE=chan[c.chan].state.esfm; insE.noise=c.value&3; if (isMuted[c.chan]) { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|(insE.noise<<3)|0); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|(insE.noise<<3)|0); } else { - rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|(insE.noise<<3)|((opE.outLvl&7)<<5)); + rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|(insE.noise<<3)|((opE.outLvl&7)<<5)); } break; } @@ -901,7 +899,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { if (o >= 4) break; DivInstrumentESFM::Operator& opE=chan[c.chan].state.esfm.op[o]; if (opE.fixed) break; - opE.dt=c.value2; + opE.dt=c.value2-0x80; chan[c.chan].freqChanged=true; break; } @@ -1032,8 +1030,8 @@ void DivPlatformESFM::poke(std::vector& wlist) { } void DivPlatformESFM::setFlags(const DivConfig& flags) { - rate=49716; chipClock=COLOR_NTSC*4.0; + rate=chipClock/288.0; } int DivPlatformESFM::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { diff --git a/src/engine/platform/esfm.h b/src/engine/platform/esfm.h index 5fc000c20..698313ad8 100644 --- a/src/engine/platform/esfm.h +++ b/src/engine/platform/esfm.h @@ -23,8 +23,8 @@ // ESFM register address space technically spans 0x800 (2048) bytes, // but we only need the first 0x254 (596) during normal use. -// Rounding it up to 0x260 (608) bytes, the nearest multiple of 16. -#define ESFM_REG_POOL_SIZE 0x260 +// Rounding it up to 0x400 bytes, the nearest power of 2. +#define ESFM_REG_POOL_SIZE 0x400 class DivPlatformESFM: public DivDispatch { struct Channel: public SharedChannel { diff --git a/src/engine/song.h b/src/engine/song.h index fd7304050..4545ed126 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -132,7 +132,6 @@ enum DivSystem { DIV_SYSTEM_TED, DIV_SYSTEM_C140, DIV_SYSTEM_C219, - DIV_SYSTEM_C352, DIV_SYSTEM_ESFM }; diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index ae25e6673..c348de34c 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -392,14 +392,6 @@ int negEffectVal(unsigned char, unsigned char val) { return -(int)val; }; -int effectValNibbleFlagPackReversed(unsigned char, unsigned char val) { - return (((val&0x0f)!=0)<<1)|((val&0xf0)!=0); -} - -int effectValExcessOf80Hex(unsigned char, unsigned char val) { - return val-0x80; -} - template int effectValAnd(unsigned char, unsigned char val) { return val&mask; }; @@ -635,20 +627,20 @@ void DivEngine::registerSystems() { {0x1b, {DIV_CMD_FM_AR, "1Bxx: Set attack of operator 2 (0 to F)", constVal<1>, effectValAnd<15>}}, {0x1c, {DIV_CMD_FM_AR, "1Cxx: Set attack of operator 3 (0 to F)", constVal<2>, effectValAnd<15>}}, {0x1d, {DIV_CMD_FM_AR, "1Dxx: Set attack of operator 4 (0 to F)", constVal<3>, effectValAnd<15>}}, - {0x20, {DIV_CMD_ESFM_OP_PANNING, "20xy: Set panning of operator 1 (x: left; y: right)", constVal<0>, effectValNibbleFlagPackReversed}}, - {0x21, {DIV_CMD_ESFM_OP_PANNING, "21xy: Set panning of operator 2 (x: left; y: right)", constVal<1>, effectValNibbleFlagPackReversed}}, - {0x22, {DIV_CMD_ESFM_OP_PANNING, "22xy: Set panning of operator 3 (x: left; y: right)", constVal<2>, effectValNibbleFlagPackReversed}}, - {0x23, {DIV_CMD_ESFM_OP_PANNING, "23xy: Set panning of operator 4 (x: left; y: right)", constVal<3>, effectValNibbleFlagPackReversed}}, + {0x20, {DIV_CMD_ESFM_OP_PANNING, "20xy: Set panning of operator 1 (x: left; y: right)", constVal<0>, effectVal}}, + {0x21, {DIV_CMD_ESFM_OP_PANNING, "21xy: Set panning of operator 2 (x: left; y: right)", constVal<1>, effectVal}}, + {0x22, {DIV_CMD_ESFM_OP_PANNING, "22xy: Set panning of operator 3 (x: left; y: right)", constVal<2>, effectVal}}, + {0x23, {DIV_CMD_ESFM_OP_PANNING, "23xy: Set panning of operator 4 (x: left; y: right)", constVal<3>, effectVal}}, {0x24, {DIV_CMD_ESFM_OUTLVL, "24xy: Set output level register (x: operator from 1 to 4 (0 for all ops); y: level from 0 to 7)", effectOpVal<4>, effectValAnd<7>}}, {0x25, {DIV_CMD_ESFM_MODIN, "25xy: Set modulation input level (x: operator from 1 to 4 (0 for all ops); y: level from 0 to 7)", effectOpVal<4>, effectValAnd<7>}}, {0x26, {DIV_CMD_ESFM_ENV_DELAY, "26xy: Set envelope delay (x: operator from 1 to 4 (0 for all ops); y: delay from 0 to 7)", effectOpVal<4>, effectValAnd<7>}}, {0x27, {DIV_CMD_STD_NOISE_MODE, "27xx: Set noise mode for operator 4 (x: mode from 0 to 3)", effectValAnd<3>}}, {0x2a, {DIV_CMD_FM_WS, "2Axy: Set waveform (x: operator from 1 to 4 (0 for all ops); y: waveform from 0 to 7)", effectOpVal<4>, effectValAnd<7>}}, {0x2f, {DIV_CMD_FM_FIXFREQ, "2Fxy: Set fixed frequency block (x: operator from 1 to 4; y: octave from 0 to 7)", effectOpValNoZero<4>, effectValAnd<7>}}, - {0x40, {DIV_CMD_FM_DT, "40xx: Set detune of operator 1 (80: center)", constVal<0>, effectValExcessOf80Hex}}, - {0x41, {DIV_CMD_FM_DT, "41xx: Set detune of operator 2 (80: center)", constVal<1>, effectValExcessOf80Hex}}, - {0x42, {DIV_CMD_FM_DT, "42xx: Set detune of operator 3 (80: center)", constVal<2>, effectValExcessOf80Hex}}, - {0x43, {DIV_CMD_FM_DT, "43xx: Set detune of operator 4 (80: center)", constVal<3>, effectValExcessOf80Hex}}, + {0x40, {DIV_CMD_FM_DT, "40xx: Set detune of operator 1 (80: center)", constVal<0>, effectVal}}, + {0x41, {DIV_CMD_FM_DT, "41xx: Set detune of operator 2 (80: center)", constVal<1>, effectVal}}, + {0x42, {DIV_CMD_FM_DT, "42xx: Set detune of operator 3 (80: center)", constVal<2>, effectVal}}, + {0x43, {DIV_CMD_FM_DT, "43xx: Set detune of operator 4 (80: center)", constVal<3>, effectVal}}, {0x50, {DIV_CMD_FM_AM, "50xy: Set AM (x: operator from 1 to 4 (0 for all ops); y: AM)", effectOpVal<4>, effectValAnd<1>}}, {0x51, {DIV_CMD_FM_SL, "51xy: Set sustain level (x: operator from 1 to 4 (0 for all ops); y: sustain)", effectOpVal<4>, effectValAnd<15>}}, {0x52, {DIV_CMD_FM_RR, "52xy: Set release (x: operator from 1 to 4 (0 for all ops); y: release)", effectOpVal<4>, effectValAnd<15>}}, @@ -1980,7 +1972,7 @@ void DivEngine::registerSystems() { sysDefs[DIV_SYSTEM_ESFM]=new DivSysDef( "ESS ES1xxx series (ESFM)", NULL, 0xd1, 0, 18, true, false, 0, false, 0, - "A unique FM synth featured in PC sound cards.\nBased on the OPL3 design, but with lots of its features extended.", + "a unique FM synth featured in PC sound cards.\nbased on the OPL3 design, but with lots of its features extended.", {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "FM 9", "FM 10", "FM 11", "FM 12", "FM 13", "FM 14", "FM 15", "FM 16", "FM 17", "FM 18"}, {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18"}, {DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM}, diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 3e7dffbec..ef3b35c8c 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -49,7 +49,7 @@ const char* esfmParamLongNames[9]={ }; const char* esfmParamNames[9]={ - "OP4 Noise Mode", "Env. Delay", "Output Level", "ModInput", "Left", "Right", "Coarse Tn.", "Detune", "Fixed" + "OP4 Noise Mode", "Env. Delay", "Output Level", "ModInput", "Left", "Right", "Tune", "Detune", "Fixed" }; const char* esfmParamShortNames[9]={ From 47c4273e5cb7155aa5143c62f85f142f7ecf6f9b Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Thu, 26 Oct 2023 09:45:46 -0300 Subject: [PATCH 27/74] Code review suggestions 2 --- src/engine/platform/esfm.cpp | 2 +- src/gui/insEdit.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index f02fd6ef5..30143ba1e 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -185,7 +185,7 @@ void DivPlatformESFM::tick(bool sysTick) { op.ksl=m.ksl.val; } - if (KVS(i, o)) { + if (KVS(i,o)) { rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[i].outVol&0x3f,63))|(op.ksl<<6)); } else { rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index ef3b35c8c..fbd513a57 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -53,7 +53,7 @@ const char* esfmParamNames[9]={ }; const char* esfmParamShortNames[9]={ - "RHY", "DL", "OL", "MI", "L", "R", "CT", "DT", "FIX" + "NOI", "DL", "OL", "MI", "L", "R", "CT", "DT", "FIX" }; const char* fmParamShortNames[3][32]={ From 46024277b2470a618b954494b0116eda1f02fe7f Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 27 Oct 2023 12:01:39 -0300 Subject: [PATCH 28/74] Removing channel deactivaton upon note off --- src/engine/platform/esfm.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 30143ba1e..961c84f39 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -451,12 +451,10 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_NOTE_OFF: chan[c.chan].keyOff=true; chan[c.chan].keyOn=false; - chan[c.chan].active=false; break; case DIV_CMD_NOTE_OFF_ENV: chan[c.chan].keyOff=true; chan[c.chan].keyOn=false; - chan[c.chan].active=false; chan[c.chan].std.release(); break; case DIV_CMD_ENV_RELEASE: From 403799d1a32285eff09ba320c65aa8beee4e37c2 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 15 Dec 2023 14:20:56 -0300 Subject: [PATCH 29/74] Updating sysDef; implementing mapVelocity --- src/engine/platform/esfm.cpp | 7 +++++++ src/engine/platform/esfm.h | 1 + src/engine/sysDef.cpp | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 961c84f39..baefa1291 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -1019,6 +1019,13 @@ void DivPlatformESFM::notifyInsDeletion(void* ins) { } } +int DivPlatformESFM::mapVelocity(int ch, unsigned char vel) { + const int volMax=MAX(1,dispatch(DivCommand(DIV_CMD_GET_VOLMAX,MAX(ch,0)))); + double attenDb=40*log10(vel/127); + double attenUnits=attenDb*(8.0/6.0); // negative + return MAX(0,volMax+attenUnits); +} + void DivPlatformESFM::poke(unsigned int addr, unsigned short val) { immWrite(addr,val); } diff --git a/src/engine/platform/esfm.h b/src/engine/platform/esfm.h index 698313ad8..8ec29fb8c 100644 --- a/src/engine/platform/esfm.h +++ b/src/engine/platform/esfm.h @@ -136,6 +136,7 @@ class DivPlatformESFM: public DivDispatch { void toggleRegisterDump(bool enable); void notifyInsChange(int ins); void notifyInsDeletion(void* ins); + int mapVelocity(int ch, unsigned char vel); void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); void setFlags(const DivConfig& flags); diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index 5420dbf77..792b731c3 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1972,7 +1972,7 @@ void DivEngine::registerSystems() { ); sysDefs[DIV_SYSTEM_ESFM]=new DivSysDef( - "ESS ES1xxx series (ESFM)", NULL, 0xd1, 0, 18, true, false, 0, false, 0, + "ESS ES1xxx series (ESFM)", NULL, 0xd1, 0, 18, true, false, 0, false, 0, 0, 0, "a unique FM synth featured in PC sound cards.\nbased on the OPL3 design, but with lots of its features extended.", {"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "FM 7", "FM 8", "FM 9", "FM 10", "FM 11", "FM 12", "FM 13", "FM 14", "FM 15", "FM 16", "FM 17", "FM 18"}, {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18"}, From e32b45a1ebe9fe7a085506393e2f0ef2bae82dfe Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Fri, 15 Dec 2023 14:57:12 -0300 Subject: [PATCH 30/74] Changing mapVelocity to linear mapping --- src/engine/platform/esfm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index baefa1291..4b23522fd 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -1021,8 +1021,8 @@ void DivPlatformESFM::notifyInsDeletion(void* ins) { int DivPlatformESFM::mapVelocity(int ch, unsigned char vel) { const int volMax=MAX(1,dispatch(DivCommand(DIV_CMD_GET_VOLMAX,MAX(ch,0)))); - double attenDb=40*log10(vel/127); - double attenUnits=attenDb*(8.0/6.0); // negative + double attenDb=20*log10(vel/127); // 20dB/decade for a linear mapping + double attenUnits=attenDb*(8.0/6.0); return MAX(0,volMax+attenUnits); } From 71841aaf4f9759069a8e82f30d0a2278f279b5b2 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sun, 17 Dec 2023 09:05:46 -0300 Subject: [PATCH 31/74] Updated mapVelocity; also changed back to MIDI standard --- src/engine/platform/esfm.cpp | 6 +++--- src/engine/platform/esfm.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 4b23522fd..13604abf4 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -1019,10 +1019,10 @@ void DivPlatformESFM::notifyInsDeletion(void* ins) { } } -int DivPlatformESFM::mapVelocity(int ch, unsigned char vel) { +int DivPlatformESFM::mapVelocity(int ch, float vel) { const int volMax=MAX(1,dispatch(DivCommand(DIV_CMD_GET_VOLMAX,MAX(ch,0)))); - double attenDb=20*log10(vel/127); // 20dB/decade for a linear mapping - double attenUnits=attenDb*(8.0/6.0); + double attenDb=40*log10(vel); // 40dB/decade for a quadratic mapping, per MIDI standard + double attenUnits=attenDb/0.75; // 0.75dB/unit return MAX(0,volMax+attenUnits); } diff --git a/src/engine/platform/esfm.h b/src/engine/platform/esfm.h index 8ec29fb8c..fbb971003 100644 --- a/src/engine/platform/esfm.h +++ b/src/engine/platform/esfm.h @@ -136,7 +136,7 @@ class DivPlatformESFM: public DivDispatch { void toggleRegisterDump(bool enable); void notifyInsChange(int ins); void notifyInsDeletion(void* ins); - int mapVelocity(int ch, unsigned char vel); + int mapVelocity(int ch, float vel); void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); void setFlags(const DivConfig& flags); From b6d632bc9cbc3805fec6291a66d66d020f38f8fc Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sun, 17 Dec 2023 10:40:59 -0300 Subject: [PATCH 32/74] Adding text export fixtures for ESFM instruments --- src/engine/fileOps.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index cb6f4fa90..7622662a7 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -6445,7 +6445,7 @@ SafeWriter* DivEngine::saveText(bool separatePatterns) { w->writeText(fmt::sprintf("- type: %d\n",(int)ins->type)); - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPM) { + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPM || ins->type==DIV_INS_ESFM) { w->writeText("- FM parameters:\n"); w->writeText(fmt::sprintf(" - ALG: %d\n",ins->fm.alg)); w->writeText(fmt::sprintf(" - FB: %d\n",ins->fm.fb)); @@ -6489,6 +6489,25 @@ SafeWriter* DivEngine::saveText(bool separatePatterns) { } } + if (ins->type==DIV_INS_ESFM) { + w->writeText("- ESFM parameters:\n"); + w->writeText(fmt::sprintf(" - noise mode: %d\n",ins->esfm.noise)); + + for (int j=0; jfm.ops; j++) { + DivInstrumentESFM::Operator& opE=ins->esfm.op[j]; + + w->writeText(fmt::sprintf(" - operator %d:\n",j)); + w->writeText(fmt::sprintf(" - DL: %d\n",opE.delay)); + w->writeText(fmt::sprintf(" - OL: %d\n",opE.outLvl)); + w->writeText(fmt::sprintf(" - MI: %d\n",opE.modIn)); + w->writeText(fmt::sprintf(" - output left: %s\n",trueFalse[opE.left?1:0])); + w->writeText(fmt::sprintf(" - output right: %s\n",trueFalse[opE.right?1:0])); + w->writeText(fmt::sprintf(" - CT: %d\n",opE.ct)); + w->writeText(fmt::sprintf(" - DT: %d\n",opE.dt)); + w->writeText(fmt::sprintf(" - fixed frequency: %s\n",trueFalse[opE.fixed?1:0])); + } + } + if (ins->type==DIV_INS_GB) { w->writeText("- Game Boy parameters:\n"); w->writeText(fmt::sprintf(" - volume: %d\n",ins->gb.envVol)); From a25bc61ff254b49aeaa7f3ad4ed30f003f00674f Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Sun, 17 Dec 2023 16:46:03 -0300 Subject: [PATCH 33/74] Reverting back to linear --- src/engine/platform/esfm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 13604abf4..bf319fb1a 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -1021,7 +1021,7 @@ void DivPlatformESFM::notifyInsDeletion(void* ins) { int DivPlatformESFM::mapVelocity(int ch, float vel) { const int volMax=MAX(1,dispatch(DivCommand(DIV_CMD_GET_VOLMAX,MAX(ch,0)))); - double attenDb=40*log10(vel); // 40dB/decade for a quadratic mapping, per MIDI standard + double attenDb=20*log10(vel); // 20dB/decade for a linear mapping double attenUnits=attenDb/0.75; // 0.75dB/unit return MAX(0,volMax+attenUnits); } From fd4570f973aeeb63fb029b772e4e170f05baa058 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 28 Dec 2023 14:37:10 -0500 Subject: [PATCH 34/74] fix description of 88xy effect --- src/engine/engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index b2150ec1b..b425f5dc1 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -83,7 +83,7 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul case 0x82: return "82xx: Set panning (right channel)"; case 0x88: - return "88xx: Set panning (rear channels; x: left; y: right)"; + return "88xy: Set panning (rear channels; x: left; y: right)"; break; case 0x89: return "89xx: Set panning (rear left channel)"; From 65b50f4accb827e512883f3e436b3f1810c525b2 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 28 Dec 2023 17:32:40 -0500 Subject: [PATCH 35/74] GUI: improve mobile order input --- src/gui/gui.cpp | 51 +++++++++++++++++++++++++--------------------- src/gui/gui.h | 1 + src/gui/orders.cpp | 8 ++++++-- src/gui/piano.cpp | 12 +++++++---- 4 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 7d17af0ee..b8da63237 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1319,6 +1319,32 @@ void FurnaceGUI::valueInput(int num, bool direct, int target) { } } +void FurnaceGUI::orderInput(int num) { + if (orderCursor>=0 && orderCursorgetTotalChannelCount()) { + prepareUndo(GUI_UNDO_CHANGE_ORDER); + e->lockSave([this,num]() { + if (!curNibble && !settings.pushNibble) e->curOrders->ord[orderCursor][curOrder]=0; + e->curOrders->ord[orderCursor][curOrder]=((e->curOrders->ord[orderCursor][curOrder]<<4)|num); + }); + MARK_MODIFIED; + curNibble=!curNibble; + if (orderEditMode==2 || orderEditMode==3) { + if (!curNibble) { + if (orderEditMode==2) { + orderCursor++; + if (orderCursor>=e->getTotalChannelCount()) orderCursor=0; + } else if (orderEditMode==3) { + if (curOrdercurSubSong->ordersLen-1) { + setOrder(curOrder+1); + } + } + } + } + e->walkSong(loopOrder,loopRow,loopEnd); + makeUndo(GUI_UNDO_CHANGE_ORDER); + } +} + #define changeLatch(x) \ if (x<0) x=0; \ if (!latchNibble && !settings.pushNibble) x=0; \ @@ -1529,29 +1555,7 @@ void FurnaceGUI::keyDown(SDL_Event& ev) { auto it=valueKeys.find(ev.key.keysym.sym); if (it!=valueKeys.cend()) { int num=it->second; - if (orderCursor>=0 && orderCursorgetTotalChannelCount()) { - prepareUndo(GUI_UNDO_CHANGE_ORDER); - e->lockSave([this,num]() { - if (!curNibble && !settings.pushNibble) e->curOrders->ord[orderCursor][curOrder]=0; - e->curOrders->ord[orderCursor][curOrder]=((e->curOrders->ord[orderCursor][curOrder]<<4)|num); - }); - MARK_MODIFIED; - curNibble=!curNibble; - if (orderEditMode==2 || orderEditMode==3) { - if (!curNibble) { - if (orderEditMode==2) { - orderCursor++; - if (orderCursor>=e->getTotalChannelCount()) orderCursor=0; - } else if (orderEditMode==3) { - if (curOrdercurSubSong->ordersLen-1) { - setOrder(curOrder+1); - } - } - } - } - e->walkSong(loopOrder,loopRow,loopEnd); - makeUndo(GUI_UNDO_CHANGE_ORDER); - } + orderInput(num); } } break; @@ -4518,6 +4522,7 @@ bool FurnaceGUI::loop() { ordersOpen=true; curWindow=GUI_WINDOW_ORDERS; MEASURE(orders,drawOrders()); + MEASURE(piano,drawPiano()); break; case GUI_SCENE_INSTRUMENT: insEditOpen=true; diff --git a/src/gui/gui.h b/src/gui/gui.h index 51abb74ae..0e78b3b6e 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -2555,6 +2555,7 @@ class FurnaceGUI { DivSystem systemPicker(); void noteInput(int num, int key, int vol=-1); void valueInput(int num, bool direct=false, int target=-1); + void orderInput(int num); void doGenerateWave(); diff --git a/src/gui/orders.cpp b/src/gui/orders.cpp index 43dba3d79..4b0ae27d0 100644 --- a/src/gui/orders.cpp +++ b/src/gui/orders.cpp @@ -181,6 +181,10 @@ void FurnaceGUI::drawOrderButtons() { } NEXT_BUTTON; + if (orderEditMode==0 && mobileUI) { + orderEditMode=1; + } + const char* orderEditModeLabel="?##OrderEditMode"; if (orderEditMode==3) { orderEditModeLabel=ICON_FA_ARROWS_V "##OrderEditMode"; @@ -193,7 +197,7 @@ void FurnaceGUI::drawOrderButtons() { } if (ImGui::Button(orderEditModeLabel)) { handleUnimportant orderEditMode++; - if (orderEditMode>3) orderEditMode=0; + if (orderEditMode>3) orderEditMode=mobileUI?1:0; curNibble=false; } if (ImGui::IsItemHovered()) { @@ -219,7 +223,7 @@ void FurnaceGUI::drawOrders() { if (!ordersOpen) return; if (mobileUI) { patWindowPos=(portrait?ImVec2(0.0f,(mobileMenuPos*-0.65*canvasH)):ImVec2((0.16*canvasH)+0.5*canvasW*mobileMenuPos,0.0f)); - patWindowSize=(portrait?ImVec2(canvasW,canvasH-(0.16*canvasW)):ImVec2(canvasW-(0.16*canvasH),canvasH)); + patWindowSize=(portrait?ImVec2(canvasW,canvasH-(0.16*canvasW)-(pianoOpen?(0.4*canvasW):0.0f)):ImVec2(canvasW-(0.16*canvasH),canvasH-(pianoOpen?(0.3*canvasH):0.0f))); ImGui::SetNextWindowPos(patWindowPos); ImGui::SetNextWindowSize(patWindowSize); } else { diff --git a/src/gui/piano.cpp b/src/gui/piano.cpp index a167b1b89..4e20142c7 100644 --- a/src/gui/piano.cpp +++ b/src/gui/piano.cpp @@ -42,7 +42,11 @@ const bool isTopKey[12]={ #define VALUE_DIGIT(x,label) \ if (ImGui::Button(label,buttonSize)) { \ - valueInput(x,false); \ + if (curWindow==GUI_WINDOW_ORDERS && orderEditMode>0) { \ + orderInput(x); \ + } else { \ + valueInput(x,false); \ + } \ } void FurnaceGUI::drawPiano() { @@ -166,7 +170,7 @@ void FurnaceGUI::drawPiano() { } ImGui::TableNextColumn(); - if (pianoInputPadMode==PIANO_INPUT_PAD_REPLACE && cursor.xFine>0 && curWindow==GUI_WINDOW_PATTERN) { + if (pianoInputPadMode==PIANO_INPUT_PAD_REPLACE && ((cursor.xFine>0 && curWindow==GUI_WINDOW_PATTERN) || (curWindow==GUI_WINDOW_ORDERS && orderEditMode>0))) { ImVec2 buttonSize=ImGui::GetContentRegionAvail(); if (ImGui::BeginTable("InputPadP",8,ImGuiTableFlags_SizingFixedSame)) { ImGui::TableNextRow(); @@ -443,9 +447,9 @@ void FurnaceGUI::drawPiano() { ImGui::End(); // draw input pad if necessary - if ((curWindow==GUI_WINDOW_PATTERN || !mobileUI) && ((pianoInputPadMode==PIANO_INPUT_PAD_SPLIT_AUTO && cursor.xFine>0) || pianoInputPadMode==PIANO_INPUT_PAD_SPLIT_VISIBLE)) { + if ((curWindow==GUI_WINDOW_ORDERS || curWindow==GUI_WINDOW_PATTERN || !mobileUI) && ((pianoInputPadMode==PIANO_INPUT_PAD_SPLIT_AUTO && (cursor.xFine>0 || (curWindow==GUI_WINDOW_ORDERS && orderEditMode>0))) || pianoInputPadMode==PIANO_INPUT_PAD_SPLIT_VISIBLE)) { if (ImGui::Begin("Input Pad",NULL,ImGuiWindowFlags_NoTitleBar)) { - ImGui::BeginDisabled(cursor.xFine==0); + ImGui::BeginDisabled(cursor.xFine==0 && !(curWindow==GUI_WINDOW_ORDERS && orderEditMode>0)); if (ImGui::BeginTable("InputPad",3,ImGuiTableFlags_Borders)) { ImGui::TableNextRow(); ImGui::TableNextColumn(); From c1c2b52ba7656c9d1eae6c1c127bc8ae3496655f Mon Sep 17 00:00:00 2001 From: Daniel Konar Date: Wed, 27 Dec 2023 08:53:09 +0100 Subject: [PATCH 36/74] Add button in midi settings to refresh midi devices Deletes and creates a new RT midi instance allowing for midi devices to be plugged in without restarting --- src/audio/midi.cpp | 5 +++++ src/audio/taAudio.h | 2 ++ src/engine/engine.cpp | 9 +++++++++ src/engine/engine.h | 3 +++ src/gui/settings.cpp | 7 +++++++ 5 files changed, 26 insertions(+) diff --git a/src/audio/midi.cpp b/src/audio/midi.cpp index fa3faf1f4..ea46cc20e 100644 --- a/src/audio/midi.cpp +++ b/src/audio/midi.cpp @@ -58,4 +58,9 @@ void TAAudio::quitMidi() { delete midiOut; midiOut=NULL; } +} + +bool TAAudio::reinitMidi(bool jack) { + quitMidi(); + initMidi(jack); } \ No newline at end of file diff --git a/src/audio/taAudio.h b/src/audio/taAudio.h index 0b6f530c6..3d21cbaff 100644 --- a/src/audio/taAudio.h +++ b/src/audio/taAudio.h @@ -178,6 +178,8 @@ class TAAudio { virtual std::vector listAudioDevices(); bool initMidi(bool jack); void quitMidi(); + /** remove and reload midi to allow hotswaping midi devices */ + bool reinitMidi(bool jack); virtual bool init(TAAudioDesc& request, TAAudioDesc& response); TAAudio(): diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index b425f5dc1..76c56cb16 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -3473,6 +3473,15 @@ void DivEngine::rescanAudioDevices() { } } + +void DivEngine::rescanMidiDevices() { + if (output!=NULL) { + logV("reloading midi..."); + output->reinitMidi(false); + rescanAudioDevices(); + } +} + void DivEngine::initDispatch(bool isRender) { BUSY_BEGIN; logV("initializing dispatch..."); diff --git a/src/engine/engine.h b/src/engine/engine.h index eb4bc5bbb..a5b73b2ba 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -1077,6 +1077,9 @@ class DivEngine { // rescan audio devices void rescanAudioDevices(); + /** rescan midi devices */ + void rescanMidiDevices(); + // set the console mode. void setConsoleMode(bool enable); diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 8c503d72b..df0ca64eb 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -1129,6 +1129,13 @@ void FurnaceGUI::drawSettings() { ImGui::EndCombo(); } + ImGui::SameLine(); + if (ImGui::Button("Reload MIDI devices")) { + e->rescanMidiDevices(); + audioEngineChanged=true; + settingsChanged=false; + } + if (hasToReloadMidi) { midiMap.read(e->getConfigPath()+DIR_SEPARATOR_STR+"midiIn_"+stripName(settings.midiInDevice)+".cfg"); midiMap.compile(); From 049088f77c00fb5b1e230546bae6367a6c112e4f Mon Sep 17 00:00:00 2001 From: Daniel Konar Date: Wed, 27 Dec 2023 09:10:28 +0100 Subject: [PATCH 37/74] Fix return of reinitMidi --- src/audio/midi.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/audio/midi.cpp b/src/audio/midi.cpp index ea46cc20e..3da138868 100644 --- a/src/audio/midi.cpp +++ b/src/audio/midi.cpp @@ -62,5 +62,6 @@ void TAAudio::quitMidi() { bool TAAudio::reinitMidi(bool jack) { quitMidi(); - initMidi(jack); + return initMidi(jack); + } \ No newline at end of file From 3039ce24164a5ebb190f3627d3479a78eac8fb5b Mon Sep 17 00:00:00 2001 From: Daniel Konar Date: Thu, 28 Dec 2023 10:11:30 +0100 Subject: [PATCH 38/74] Change reload to re-scan and refactor Remove rt midi reinitialization (not needed as per docs) Move midi rescan code to rescanMidiDevices as MIDI is not audio (rescanAudioDevices also appears to be unused) --- src/audio/midi.cpp | 6 ------ src/audio/taAudio.h | 2 -- src/engine/engine.cpp | 15 ++++++--------- src/gui/settings.cpp | 2 +- 4 files changed, 7 insertions(+), 18 deletions(-) diff --git a/src/audio/midi.cpp b/src/audio/midi.cpp index 3da138868..fa3faf1f4 100644 --- a/src/audio/midi.cpp +++ b/src/audio/midi.cpp @@ -58,10 +58,4 @@ void TAAudio::quitMidi() { delete midiOut; midiOut=NULL; } -} - -bool TAAudio::reinitMidi(bool jack) { - quitMidi(); - return initMidi(jack); - } \ No newline at end of file diff --git a/src/audio/taAudio.h b/src/audio/taAudio.h index 3d21cbaff..0b6f530c6 100644 --- a/src/audio/taAudio.h +++ b/src/audio/taAudio.h @@ -178,8 +178,6 @@ class TAAudio { virtual std::vector listAudioDevices(); bool initMidi(bool jack); void quitMidi(); - /** remove and reload midi to allow hotswaping midi devices */ - bool reinitMidi(bool jack); virtual bool init(TAAudioDesc& request, TAAudioDesc& response); TAAudio(): diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 76c56cb16..fc5d45477 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -3464,6 +3464,12 @@ void DivEngine::rescanAudioDevices() { audioDevs.clear(); if (output!=NULL) { audioDevs=output->listAudioDevices(); + } +} + +void DivEngine::rescanMidiDevices() { + if (output!=NULL) { + logV("re-scanning midi..."); if (output->midiIn!=NULL) { midiIns=output->midiIn->listDevices(); } @@ -3473,15 +3479,6 @@ void DivEngine::rescanAudioDevices() { } } - -void DivEngine::rescanMidiDevices() { - if (output!=NULL) { - logV("reloading midi..."); - output->reinitMidi(false); - rescanAudioDevices(); - } -} - void DivEngine::initDispatch(bool isRender) { BUSY_BEGIN; logV("initializing dispatch..."); diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index df0ca64eb..3f4bd9de7 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -1130,7 +1130,7 @@ void FurnaceGUI::drawSettings() { } ImGui::SameLine(); - if (ImGui::Button("Reload MIDI devices")) { + if (ImGui::Button("Re-scan MIDI devices")) { e->rescanMidiDevices(); audioEngineChanged=true; settingsChanged=false; From 673e3246d21fb42e8e1e00869166bef7d1fb4dd6 Mon Sep 17 00:00:00 2001 From: nk <98922449+LoKiToon@users.noreply.github.com> Date: Thu, 28 Dec 2023 22:02:52 +0300 Subject: [PATCH 39/74] Add files via upload --- demos/misc/fragments_turbosound.fur | Bin 0 -> 2114 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 demos/misc/fragments_turbosound.fur diff --git a/demos/misc/fragments_turbosound.fur b/demos/misc/fragments_turbosound.fur new file mode 100644 index 0000000000000000000000000000000000000000..61064a7fcbe4dad65d2d8eb925e1f4da56ce1080 GIT binary patch literal 2114 zcmV-I2)*}soZVPkY+Oef{^wkF*T;Kt9NU=_$MG4c1juZYI22Nqs4W=o2DsL;sqWM0)Zm+tqLH-YlQk-79qq_-w;oL`Q|?t zZ(=*aQd6ZI=bM@T{{J&`X3i!*RIi;H8!vj5>4|!|nE#N7JX(1U3=fTbU}BI+h~2v{ zeQO`JlhxM3vM&M)3-rKe-$R}UTNC{mvA=FTOzY7-dp&QoFnGLg=*5BO4-F2F7Wzhp z`Ud(6qeu6H`ck3q@ZfOY@qw2-Z?D$PzdV~ibzo{F?>)2M%X_=}cl7Vs(Z5?uY2oAN zh=kBygEko5L3I~wqOJtdJ3uW-^iNpmcqzX-zvt;)J9$k9U&t4}Ju-4I zKX~jguTHbO`^Ha1YsF66&|>Q7?y>+3zyvJ71`;`b@D_oZfq;R*%Mo zVs-DX{->Qs<#u5Iffw6&qVcrwrm*ZpGNt*^8KB3>NJpPfh5kF}KcoZ=546x&t?HGh zr>it{=n47<1Up~r?cJAKzdtlkBD`e@T82v_n|3lzQlywN$xNDAa>(2l&<5`;{25^% zkDIZEJk(h(9I|M6nR*ZIM+u&N*uEo%2T{r3u&(1=Tt|jxily3wS1s4ar)D=$%N|`z z8$y`KH@8eZP49|nE_00*841Bdfl`BkwcM0akj<-cHa1Pv>Xi*-(a$p)M9bx}nKa%? zP`@Ry8#jVwh-KlE_}Ra!|A`Vwt&aau96!gas&hEK(Y2j<=-L{ARP^?Cc5cmlMk_tn zw9+Tar8DCvXT5T9Y+?hIJ*g`*gUWK5Rx>OTuZd~I>zj_&*IYfn-)Vkp>Sw0C;;C0Q z5I>Fhk#}RY_sQ6MnkL7liry>J<$9&KfdDQ7MBC<7y=??4#J2gdSRL)aCYy@;_$%e za3+4IOZ2`uNz0nqLBY)zF>gtucOhl4EFWHAWY$yXfkm^FTH;=#23{@YGbTY#rr4-6 z2oXEHAsw+Ob0aKFg$_yFW_mHYhm&(wjznF|+x0Aod9i3^LNd*yJ?H4YZu_7Y!C!=Y z4)i?Keb6&7uZmf_3VK$|YjY;kOxiP!?yL43yPLJ=A)f&~3-!6CRFHSFs#7V6nq7jh zCT6rRCeuvXRY&(FPHhJK8ID!5YgwIg&7Ok!gs9jPpev%L&6!LyX-_%2pWxJL;MX9Z z0$qW6l~ehMQ^A_#%0|w^L<+MeTFZuK*7eAo35cp#Pr_`pOfWlA15u47ff^(y3`Cg_ zW`&1ZqZ0AWDY2e}*=U(ycBBSkDwf0wO|@B{-`dIs%s9jesZw*mYUm#kuz(BO(psB|06I!%pk!y&eDg)8lWd^df3QgR*h>xtyNaa&5Q&XYu zsi1!*SGJ9vj#&7zZ8%)$>F|jC6warX@IXq6+k7J3wl(9nT{S`8re||UY~dMBn-pCf z`VSmB`T3q>oc&zPrtp%X?h<_>-tV47+awTLV6wmr1^k;)f0#50n(wBaEI0H`;)mCh z&nWRV<%idkzLu7_uLalBlWd1${)Zc};!Dl2@5$yyR9rf|@Mur&3%~MA=KX?sx~|cL zXOi?RxlY&I{;zsy=>gsPdh4~E^G`Tu<8jWJ^Sl}SE_vMYTnfKw_#4Ms`NsJs)7T2V zXOoV#LmJkCSn|a=U!3>F1z%kB#p}MfDP1Y8TL$bC-{IxhEPE*I}A0%@lE zBi)6X1~iS>iv=%M93g=Si8y)+(Nl3|4l;A%tkcLk9aoe^pln=i8v?b(GtrJf?eQ#i zAW%mA&&au7%R-P0^TqCNQSId>;5LfYMEVt09I&*(U7&eiLk=4kA^J! zSUBJ;e!y86pLrHdTjH0Tf)%8&t<^Kq84v!qWjrJ0X>AEstEa6rkB1M? Date: Fri, 29 Dec 2023 02:16:55 -0500 Subject: [PATCH 40/74] pull request #1663 but optimized --- demos/nes/christmas-fever.fur | Bin 0 -> 63881 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 demos/nes/christmas-fever.fur diff --git a/demos/nes/christmas-fever.fur b/demos/nes/christmas-fever.fur new file mode 100644 index 0000000000000000000000000000000000000000..87453024201dcb2256f0ef6c590dcf3d64a323c3 GIT binary patch literal 63881 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]BXQzVi6dz9YTeqa#4O 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 literal 0 HcmV?d00001 From 4459a7d6599b922e843d7e43fe1dd39acb314753 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Mon, 1 Jan 2024 14:59:00 -0300 Subject: [PATCH 41/74] Implementing per-op arpeggio/pitch macro Co-authored-by: LTVA1 <87536432+LTVA1@users.noreply.github.com> --- src/engine/platform/esfm.cpp | 28 ++++++++++----- src/engine/platform/esfm.h | 66 +++++++++++++++++++++++++++++++++++- src/gui/gui.h | 8 +++-- src/gui/insEdit.cpp | 17 +++++++--- 4 files changed, 103 insertions(+), 16 deletions(-) diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index bf319fb1a..c9f8a6c62 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -229,6 +229,8 @@ void DivPlatformESFM::tick(bool sysTick) { } } + + // detune/fixed pitch if (opE.fixed) { if (m.ssg.had) { @@ -241,15 +243,10 @@ void DivPlatformESFM::tick(bool sysTick) { chan[i].freqChanged=true; } } else { - if (m.ssg.had) { - opE.ct=(signed char)m.ssg.val; - chan[i].freqChanged=true; - } - if (m.dt.had) { - opE.dt=(signed char)m.dt.val; - chan[i].freqChanged=true; - } + chan[i].handleArpFmOp(0, o); + chan[i].handlePitchFmOp(o); } + if (m.dt2.had) { opE.delay=m.dt2.val; rWrite(baseAddr+ADDR_FREQH_BLOCK_DELAY,chan[i].freqH[o]|(opE.delay<<5)); @@ -257,6 +254,8 @@ void DivPlatformESFM::tick(bool sysTick) { } } + + for (int i=0; icalcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride+ct:chan[i].arpOff+ct,chan[i].fixedArp,false,octave(chan[i].baseFreq)*2,chan[i].pitch2+dt,chipClock,CHIP_FREQBASE); + int arp=chan[i].fixedArp?chan[i].baseNoteOverride+ct:chan[i].arpOff+ct; + int pitch2=chan[i].pitch2+dt; + int fixedArp=chan[i].fixedArp; + if(chan[i].opsState[o].hasOpArp) { + arp=chan[i].opsState[o].fixedArp?chan[i].opsState[o].baseNoteOverride+ct:chan[i].opsState[o].arpOff+ct; + fixedArp=chan[i].opsState[o].fixedArp; + } + if(chan[i].opsState[o].hasOpPitch) { + pitch2=chan[i].opsState[o].pitch2+dt; + } + int opFreq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,arp,fixedArp,false,octave(chan[i].baseFreq)*2,pitch2,chipClock,CHIP_FREQBASE); if (opFreq<0) opFreq=0; if (opFreq>131071) opFreq=131071; int freqt=toFreq(opFreq); @@ -432,6 +441,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_ESFM); chan[c.chan].macroInit(ins); + memset(chan[c.chan].opsState, 0, sizeof(chan[c.chan].opsState)); if (!chan[c.chan].std.vol.will) { chan[c.chan].outVol=chan[c.chan].vol; } diff --git a/src/engine/platform/esfm.h b/src/engine/platform/esfm.h index fbb971003..a183925c7 100644 --- a/src/engine/platform/esfm.h +++ b/src/engine/platform/esfm.h @@ -36,13 +36,77 @@ class DivPlatformESFM: public DivDispatch { bool hardReset; unsigned char globalPan; int macroVolMul; + struct { + int baseNoteOverride; + bool fixedArp; + int arpOff; + int pitch2; + bool hasOpArp; + bool hasOpPitch; + } opsState[4]; + + void handleArpFmOp(int offset=0, int o=0) { + DivMacroInt::IntOp& m=this->std.op[o]; + if (m.ssg.had) { + opsState[o].hasOpArp=true; + + if (m.ssg.val<0) { + if (!(m.ssg.val&0x40000000)) { + opsState[o].baseNoteOverride=(m.ssg.val|0x40000000)+offset; + opsState[o].fixedArp=true; + } else { + opsState[o].arpOff=m.ssg.val; + opsState[o].fixedArp=false; + } + } else { + if (m.ssg.val&0x40000000) { + opsState[o].baseNoteOverride=(m.ssg.val&(~0x40000000))+offset; + opsState[o].fixedArp=true; + } else { + opsState[o].arpOff=m.ssg.val; + opsState[o].fixedArp=false; + } + } + freqChanged=true; + } + + else + { + opsState[o].hasOpArp=false; + } + } + + void handlePitchFmOp(int o) + { + DivMacroInt::IntOp& m=this->std.op[o]; + + if (m.dt.had) { + opsState[o].hasOpPitch=true; + + if (m.dt.mode) { + opsState[o].pitch2+=m.dt.val; + CLAMP_VAR(opsState[o].pitch2,-131071,131071); + } else { + opsState[o].pitch2=m.dt.val; + } + this->freqChanged=true; + } + + else + { + opsState[o].hasOpPitch=false; + } + } + Channel(): SharedChannel(0), freqL{0, 0, 0, 0}, freqH{0, 0, 0, 0}, hardReset(false), globalPan(3), - macroVolMul(64) {} + macroVolMul(64) { + memset(opsState, 0, sizeof(opsState)); + } }; Channel chan[18]; DivDispatchOscBuffer* oscBuf[18]; diff --git a/src/gui/gui.h b/src/gui/gui.h index 162ebb0ac..3e0e53137 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1245,8 +1245,10 @@ struct FurnaceGUIMacroDesc { bool isBitfield, blockMode, bit30; String (*hoverFunc)(int,float,void*); void* hoverFuncUser; + bool isArp; + bool isPitch; - FurnaceGUIMacroDesc(const char* name, DivInstrumentMacro* m, int macroMin, int macroMax, float macroHeight, ImVec4 col=ImVec4(1.0f,1.0f,1.0f,1.0f), bool block=false, const char* mName=NULL, String (*hf)(int,float,void*)=NULL, bool bitfield=false, const char** bfVal=NULL, unsigned int bitOff=0, bool bit30Special=false, void* hfu=NULL): + FurnaceGUIMacroDesc(const char* name, DivInstrumentMacro* m, int macroMin, int macroMax, float macroHeight, ImVec4 col=ImVec4(1.0f,1.0f,1.0f,1.0f), bool block=false, const char* mName=NULL, String (*hf)(int,float,void*)=NULL, bool bitfield=false, const char** bfVal=NULL, unsigned int bitOff=0, bool bit30Special=false, void* hfu=NULL, bool isArp=false, bool isPitch=false): macro(m), height(macroHeight), displayName(name), @@ -1258,7 +1260,9 @@ struct FurnaceGUIMacroDesc { blockMode(block), bit30(bit30Special), hoverFunc(hf), - hoverFuncUser(hfu) { + hoverFuncUser(hfu), + isArp(isArp), + isPitch(isPitch) { // MSVC -> hell this->min=macroMin; this->max=macroMax; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 40515099e..bc0859811 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -1537,10 +1537,10 @@ void FurnaceGUI::drawMacroEdit(FurnaceGUIMacroDesc& i, int totalFit, float avail ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0.0f,0.0f)); if (i.macro->vZoom<1) { - if (i.macro->macroType==DIV_MACRO_ARP) { + if (i.macro->macroType==DIV_MACRO_ARP || i.isArp) { i.macro->vZoom=24; i.macro->vScroll=120-12; - } else if (i.macro->macroType==DIV_MACRO_PITCH) { + } else if (i.macro->macroType==DIV_MACRO_PITCH || i.isPitch) { i.macro->vZoom=128; i.macro->vScroll=2048-64; } else { @@ -3937,6 +3937,9 @@ void FurnaceGUI::drawInsEdit() { ImGui::SetCursorPosY(ImGui::GetCursorPosY()-0.5*ImGui::GetStyle().ItemSpacing.y); if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER opE.fixed=fixedOn; + // HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly + ins->std.opMacros[i].ssgMacro.vZoom=-1; + ins->std.opMacros[i].dtMacro.vZoom=-1; } if (ins->type==DIV_INS_ESFM) { if (fixedOn) { @@ -4674,6 +4677,9 @@ void FurnaceGUI::drawInsEdit() { } if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER opE.fixed=fixedOn; + // HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly + ins->std.opMacros[i].ssgMacro.vZoom=-1; + ins->std.opMacros[i].dtMacro.vZoom=-1; } ImGui::EndTable(); @@ -5198,6 +5204,9 @@ void FurnaceGUI::drawInsEdit() { ImGui::SameLine(); if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER opE.fixed=fixedOn; + // HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly + ins->std.opMacros[i].ssgMacro.vZoom=-1; + ins->std.opMacros[i].dtMacro.vZoom=-1; } } @@ -5322,8 +5331,8 @@ void FurnaceGUI::drawInsEdit() { macroList.push_back(FurnaceGUIMacroDesc("Block",&ins->std.opMacros[ordi].ssgMacro,0,7,64,uiColors[GUI_COLOR_MACRO_OTHER],true)); macroList.push_back(FurnaceGUIMacroDesc("FreqNum",&ins->std.opMacros[ordi].dtMacro,0,1023,160,uiColors[GUI_COLOR_MACRO_OTHER])); } else { - macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_CT),&ins->std.opMacros[ordi].ssgMacro,-24,24,128,uiColors[GUI_COLOR_MACRO_OTHER],true)); - macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_DT),&ins->std.opMacros[ordi].dtMacro,-128,127,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Op. Arpeggio",&ins->std.opMacros[ordi].ssgMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,0,true,ins->std.opMacros[ordi].ssgMacro.val,true)); + macroList.push_back(FurnaceGUIMacroDesc("Op. Pitch",&ins->std.opMacros[ordi].dtMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode,NULL,false,NULL,0,false,NULL,false,true)); } macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AM),&ins->std.opMacros[ordi].amMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); From 8a14435b4adc4e9119d9091cd6f1585d164048f3 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 6 Jan 2024 21:59:17 -0500 Subject: [PATCH 42/74] highlight Game Boy --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 213c55e8c..f7de671ef 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,8 @@ for other operating systems, you may [build the source](#developer-info). - Casio PV-1000 - TIA used in Atari 2600 - POKEY used in Atari 8-bit computers - - Game Boy + - **Game Boy** + - including SOFTWARE ENVELOPES (zombie mode) - Virtual Boy - modern/fantasy: - Commander X16 VERA From 53c625354b5e0d9f47181aa127caed0ea3503604 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 11 Jan 2024 14:50:53 -0500 Subject: [PATCH 43/74] PC speaker: add option to reset phase on freq chan ge some motherboards do so --- src/engine/platform/pcspkr.cpp | 4 ++++ src/engine/platform/pcspkr.h | 2 +- src/gui/sysConf.cpp | 6 ++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/engine/platform/pcspkr.cpp b/src/engine/platform/pcspkr.cpp index 593c41b8a..bd49c9e68 100644 --- a/src/engine/platform/pcspkr.cpp +++ b/src/engine/platform/pcspkr.cpp @@ -373,6 +373,9 @@ void DivPlatformPCSpeaker::tick(bool sysTick) { if (chan[i].keyOff) { on=false; } + if (freq!=chan[i].freq && resetPhase) { + pos=0; + } freq=chan[i].freq; if (chan[i].keyOn) chan[i].keyOn=false; if (chan[i].keyOff) chan[i].keyOff=false; @@ -610,6 +613,7 @@ void DivPlatformPCSpeaker::setFlags(const DivConfig& flags) { CHECK_CUSTOM_CLOCK; rate=chipClock/PCSPKR_DIVIDER; speakerType=flags.getInt("speakerType",0)&3; + resetPhase=flags.getBool("resetPhase",false); oscBuf->rate=rate; switch (speakerType) { diff --git a/src/engine/platform/pcspkr.h b/src/engine/platform/pcspkr.h index b1a394444..758111259 100644 --- a/src/engine/platform/pcspkr.h +++ b/src/engine/platform/pcspkr.h @@ -51,7 +51,7 @@ class DivPlatformPCSpeaker: public DivDispatch { FixedQueue realQueue; std::mutex realQueueLock; bool isMuted[1]; - bool on, flip, lastOn, realOutEnabled; + bool on, flip, lastOn, realOutEnabled, resetPhase; int pos, speakerType, beepFD, realOutMethod; float low, band; float low2, high2, band2; diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index 99baf47e4..f7ef4b925 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -997,6 +997,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl case DIV_SYSTEM_PCSPKR: { int clockSel=flags.getInt("clockSel",0); int speakerType=flags.getInt("speakerType",0); + bool resetPhase=flags.getBool("resetPhase",false); ImGui::Text("Clock rate:"); ImGui::Indent(); @@ -1034,10 +1035,15 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl } ImGui::Unindent(); + if (ImGui::Checkbox("Reset phase on frequency change",&resetPhase)) { + altered=true; + } + if (altered) { e->lockSave([&]() { flags.set("clockSel",clockSel); flags.set("speakerType",speakerType); + flags.set("resetPhase",resetPhase); }); } break; From cca9fe9498b9b1ca455c9d71f74e4d98bc1f690b Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 11 Jan 2024 21:16:48 -0500 Subject: [PATCH 44/74] YM2612: possibly fix arp issue on non-linear pitch on channel 6... thanks LTVA for reporting --- src/engine/platform/genesis.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index c90404eae..4d8d95f8b 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -348,7 +348,7 @@ void DivPlatformGenesis::tick(bool sysTick) { } } - if (i>=5 && chan[i].furnaceDac) { + if (i>=5 && chan[i].furnaceDac && chan[i].dacMode) { if (NEW_ARP_STRAT) { chan[i].handleArp(); } else if (chan[i].std.arp.had) { From 8841b3d5181b9ec97be3493e99403b9ff848f64a Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 13 Jan 2024 17:09:49 -0500 Subject: [PATCH 45/74] improve instrument editor documentation --- doc/4-instrument/README.md | 145 +++++++++++++++++++++++-------------- 1 file changed, 90 insertions(+), 55 deletions(-) diff --git a/doc/4-instrument/README.md b/doc/4-instrument/README.md index 56386082a..f9d029242 100644 --- a/doc/4-instrument/README.md +++ b/doc/4-instrument/README.md @@ -1,16 +1,24 @@ # instrument editor -the instrument editor always starts with this section: +the instrument editor allows you to edit instruments. +it can be activated by double-clicking on an instrument in the instrument list. + +alternatively, window > instrument editor displays it. + +## main ![top of instrument editor](instrument-editor-top.png) -- top-left numeric dropdown: instrument selector. -- folder icon: open an instrument file. -- save icon: save current instrument as a file. - - right-clicking gives the option to save a .dmp format DefleMask preset. -- **Name**: instrument name. -- **Type**: the system for which the instrument is intended. - - if changed, all applicable settings and macros will remain as they are. numbers will not be adjusted. +**TODO: add descriptions to buttons in the image. it really needs them.** + +- **Instrument Selector**: displays a list of instruments in the song. +- **Open**: open an instrument file. +- **Save**: save current instrument to a file. + - right-click to see additional options, such as saving in DefleMask preset format (.dmp). +- **Name**: changes the instrument name. +- **Type**: changes the instrument type (usually chip-specific). + - if changed, all applicable settings and macros will remain unchanged. + - you may have to adjust them afterwards. ## instrument types @@ -76,59 +84,56 @@ after creating an instrument, open the Instrument Editor and select the "Macros" ![macro view](macroview.png) -the very first numeric entry sets the visible width of the bars in sequence-type macros. the scrollbar affects the view of all macros at once. there's a matching scrollbar at the bottom underneath all the macros. +the very first numeric entry sets the visible width of the bars in sequence-type macros. the scrollbar affects the view of all macros at once. there is a matching scrollbar at the bottom underneath all the macros. -each macro has two buttons on the left. -- macro type (explained below). -- timing editor, which pops up a small dialog: - - **Step Length (ticks)**: determines how many ticks pass before each change of value. default is 1. - - **Delay**: delays the start of the macro until this many ticks have passed. default is 0. - - the button is highlighted if either of these is set differently from default. -- release mode. this determines how macro release is handled: - - **Active**: jumps to release position. - - **Passive**: does not jump to release position. if release position hasn't been reached yet, there will be a delay. +each macro has the following parameters: +- macro type (explained below) +- timing options: + - **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. + - 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 -every macro can be defined though one of three methods, selectable with the leftmost button under the macro type label: +there are three macro types: -- ![sequence](macro-button-seq.png) **Sequence:** displayed as a bar graph, this is a sequence of numeric values. -- ![ADSR](macro-button-ADSR.png) **ADSR:** this is a traditional ADSR envelope, defined by the rate of increase and decrease of value over time. -- ![LFO](macro-button-LFO.png) **LFO:** the Low Frequency Oscillator generates a repeating wave of values. +- ![sequence](macro-button-seq.png) **Sequence:** a sequence of numeric values. +- ![ADSR](macro-button-ADSR.png) **ADSR:** this is an attack/decay/sustain/release envelope. +- ![LFO](macro-button-LFO.png) **LFO:** Low Frequency Oscillator. ### sequence +this is the most basic macro type. when the instrument is played, every value in the macro will be output sequentially, from left to right. + ![sequence macro editor](macro-seq.png) ![clipped sequence macro editor](macro-seq-clip.png) ![bitmask sequence macro editor](macro-seq-bitmask.png) -the number between the macro type label and the macro type button is the macro length in steps. the `-` and `+` buttons change the length of the macro. start out by adding at least a few steps. +**TODO: once again, text in the image. this sucks.** -the values of the macro can be drawn in the "bar graph" box. -- arpeggio and pitch macros may have values above or below the visible area; small chevrons will be shown until they are scrolled into view. -- bitmask-style macros show labels for each of their bits, and these are edited as toggles. +the Length field allows you to set the number of steps in the sequence. -arpeggio macros have a short bar for setting whether to interpret the values as being "relative" or "fixed". -- by default, values are offsets **relative** to the note. -- if clicked on, a value becomes **fixed** and will be played at its corresponding note without regard to the note entered into the pattern. - - values are counted from `C-0`. for example, a fixed value of 48 produces a `C-4` note. - - fixed values are especially useful for noise instruments with preset periods. +the sequence view allows you to edit the macro. +- press and hold the left mouse button to start drawing. release to stop drawing. +- press and hold the right mouse button to draw a line. + - the start point will be set to the cursor position. + - move the cursor to change the end point. + - release to finish drawing the line. -below this is a short bar that controls macro loop and release. -- click to set the start point of a loop; the end point is the last value or release point. it appears as half-height bars. right-click to remove the loop. -- shift-click to set the release point. when played, the macro will hold here until the note is released. it appears as a full-height bar. right-click to remove the release point. +the sequence view may be adjusted using the following combinations: +- hold Ctrl and use the scroll wheel to zoom horizontally. +- hold Ctrl-Shift and use the scroll wheel to zoom vertically. +- the scrollbar at the right allows you to scroll vertically (if possible). +- you may hold Shift and use the scroll wheel to scroll vertically as well. -finally, the sequence of values can be directly edited in the text box at the bottom. -- the loop start is entered as a `|`. -- the release point is entered as a `/`. -- in arpeggio macros, a value starting with a `@` is a fixed value as described above. -- in bitmask-style macros, the values are added up in binary and converted to decimal. see [the hexadecimal guide](../1-intro/hex.md) for more info. - -in all cases except bitmask macros, right-clicking on the graph opens up an editing menu: -- **copy**: copies the macro. -- **paste**: pastes the macro in the clipboard. +right-click on the sequence view to open a menu: +- **copy**: copy this macro to clipboard. +- **paste**: pastes the macro. - **clear**: clears the macro. - **clear contents**: resets all values to 0. - **offset**: @@ -139,19 +144,46 @@ in all cases except bitmask macros, right-clicking on the graph opens up an edit - **Y**: multiplies all values by the scale factor, clipping them if they would exceed the allowed range. - **randomize**: replaces all values with random values between **Min** and **Max**. +arpeggio and pitch macros may have values above or below the visible area. indicators will be shown until they are scrolled into view. + +bitmask-style macros show labels for each of their bits. these are edited as toggles. +- drawing lines is not possible in these macros. + +under the sequence view there is a bar that allows you to set loop and release points. +- click to set the loop start point; the end point is the last step or release point. + - right-click to remove the loop point. +- shift-click to set the release point. + - the macro will stop at the release point until the note is released (`===` or `REL`). + - if the loop point is set, and it is placed before the release point, the macro will loop until note release instead. + - shift-right-click to remove the release point. + +arpeggio macros have an additional bar under the sequence view to set steps to "relative" or "fixed": +- by default, step values are offsets **relative** to the note. +- if clicked on, a step value becomes **fixed** and will be played at its corresponding note without regard to the currently playing note. + - values are counted from `C-0`. for example, a fixed value of 48 produces a `C-4` note. + - fixed values are especially useful for noise or percussion. + +the sequence can be edited in the text input field at the very bottom. the following symbols have special meanings: +- `|`: loop point. +- `/`: release point. +- in arpeggio macros, `@` prefixed to a value indicates that it is a fixed value as described above. + +in bitmask-style macros, the values are added up in binary and converted to decimal. + ### ADSR ![ADSR macro editor](macro-ADSR.png) -- **Bottom** and **Top** determine the range of outputs generated by the macro. (Bottom can be larger than Top to invert the envelope!) All outputs will be between these two values. +- **Bottom** and **Top** determine the macro's output range (Bottom can be larger than Top to invert the envelope!). all outputs will be between these two values. - Attack, Decay, Sustain, SusDecay, and Release accept inputs between 0 to 255. these are scaled to the distance between Bottom and Top. -- **Attack** is how much the value moves toward Top with each tick. -- **Hold** sets how many ticks to stay at Top before Decay. -- **Decay** is how much the value moves to the Sustain level. -- **Sustain** is how far from Bottom the value stays while the note is held. -- **SusTime** is how many ticks to stay at Sustain until SusDecay. -- **SusDecay** is how much the value moves toward Bottom with each tick while the note is held. -- **Release** is how much the value moves toward Bottom with each tick after the note is released. + - the output starts at Bottom. + - **Attack** is how much the output moves toward Top with each tick. + - **Hold** sets how many ticks to stay at Top before Decay. + - **Decay** is how much the output moves to the Sustain level. + - **Sustain** is how far from Bottom the value stays while the note is on. + - **SusTime** is how many ticks to stay at Sustain until SusDecay. + - **SusDecay** is how much the output moves toward Bottom with each tick while the note is on. + - **Release** is how much the output moves toward Bottom with each tick after the note is released. ![macro ADSR chart](macro-ADSRchart.png) @@ -159,10 +191,13 @@ in all cases except bitmask macros, right-clicking on the graph opens up an edit ![LFO macro editor](macro-LFO.png) -- **Bottom** and **Top** determine the range of values generated by the macro. (Bottom can be larger than Top to invert the waveform!) -- **Speed** is how quickly the values change - the frequency of the oscillator. -- **Phase** is which part of the waveform the macro will start at, measured in 1/1024 increments. -- **Shape** is the waveform used. triangle is the default, and Saw and Square are exactly as they say. +- **Bottom** and **Top** determine the macro's output range (Bottom can be larger than Top to invert the waveform!). +- **Speed** is how quickly the LFO position moves. +- **Phase** defines the starting LFO position, measured in 1/1024 increments. +- **Shape** is the waveform of the LFO. there are three waveforms: + - Triangle: Bottom > Top > Bottom. + - Saw: moves from Bottom to Top, and then jumps back to Bottom. + - Square: alternates between Bottom and Top. From f3ddf947bcfce8c382adc1ec73e5dec508ef7bdc Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 13 Jan 2024 17:11:21 -0500 Subject: [PATCH 46/74] ok why are these CRLF?! --- doc/4-instrument/README.md | 442 +++++++++++++++++------------------ doc/4-instrument/beeper.md | 18 +- doc/4-instrument/msm5232.md | 32 +-- doc/4-instrument/nes.md | 104 ++++----- doc/4-instrument/pokemini.md | 16 +- doc/4-instrument/pokey.md | 50 ++-- doc/4-instrument/psg.md | 30 +-- doc/4-instrument/t6w28.md | 26 +-- 8 files changed, 359 insertions(+), 359 deletions(-) diff --git a/doc/4-instrument/README.md b/doc/4-instrument/README.md index f9d029242..1825371a7 100644 --- a/doc/4-instrument/README.md +++ b/doc/4-instrument/README.md @@ -1,221 +1,221 @@ -# instrument editor - -the instrument editor allows you to edit instruments. -it can be activated by double-clicking on an instrument in the instrument list. - -alternatively, window > instrument editor displays it. - -## main - -![top of instrument editor](instrument-editor-top.png) - -**TODO: add descriptions to buttons in the image. it really needs them.** - -- **Instrument Selector**: displays a list of instruments in the song. -- **Open**: open an instrument file. -- **Save**: save current instrument to a file. - - right-click to see additional options, such as saving in DefleMask preset format (.dmp). -- **Name**: changes the instrument name. -- **Type**: changes the instrument type (usually chip-specific). - - if changed, all applicable settings and macros will remain unchanged. - - you may have to adjust them afterwards. - -## instrument types - -the following instrument types are available: - -- [SN76489/Sega PSG](psg.md) - for use with TI SN76489 and derivatives like Sega Master System's PSG. -- [FM (OPN)](fm-opn.md) - for use with YM2612, YM2203, YM2608, YM2610 and YM2610B. -- [Game Boy](game-boy.md) - for use with Game Boy APU. -- [C64](c64.md) - for use with Commodore 64 SID. -- [Generic Sample](sample.md) for controlling Amiga and other sample channels/chips like YM2612's Channel 6 PCM mode, NES channel 5, Sega PCM, X1-010 and PC Engine's sample playback mode. -- [PC Engine](pce.md) - for use with PC Engine's wavetable synthesizer. -- [AY-3-8910/SSG](ay8910.md) - for use with AY-3-8910 PSG sound source and SSG portion in YM2610. -- [AY8930](ay8930.md) - for use with Microchip AY8930 E-PSG sound source. -- [TIA](tia.md) - for use with Atari 2600 chip. -- [SAA1099](saa.md) - for use with Philips SAA1099 PSG sound source. -- [VIC](vic.md) - for use with VIC-20 sound chip. -- [PET](pet.md) - for use with Commodore PET. -- [VRC6](vrc6.md) - for use with VRC6's PSG sound source. -- [FM (OPLL)](fm-opll.md) - for use with YM2413. -- [FM (OPL)](fm-opll.md) - for use with YM3526 (OPL), YM3812 (OPL2) and YMF262 (OPL3). -- [FDS](fds.md) - for use with Famicom Disk System sound source. -- [Virtual Boy](virtual-boy.md) - for use with Virtual Boy. -- [Namco 163](n163.md) - for use with Namco 163. -- [Konami SCC/Bubble System WSG](scc.md) - for use with Konami SCC and Wavetable portion in Bubble System's sound hardware. -- [FM (OPZ)](fm-opz.md) - for use with YM2414. -- [POKEY](pokey.md) - for use with Atari 8-bit computers and their POKEY sound source. -- [Beeper](beeper.md) - for use with PC Speaker and ZX Spectrum Beeper (SFX-like engine). -- [WonderSwan](wonderswan.md) - for use with WonderSwan's wavetable synthesizer. -- [Atari Lynx](lynx.md) - for use with Atari Lynx handheld console. -- [VERA](vera.md) - for use with Commander X16 VERA. -- [Seta/Allumer X1-010](x1_010.md) - for use with Wavetable portion in Seta/Allumer X1-010. -- [ES5506](es5506.md) - for use with Ensoniq ES5506 sound chip. -- [SNES](snes.md) - for use with SNES. -- [Sound Unit](su.md) - for use with Sound Unit chip. -- [Namco WSG](wsg.md) - for use with Namco WSG wavetable chips, including C15 and C30. -- [FM (OPM)](fm-opm.md) - for use with YM2151. -- [NES](nes.md) - for use with NES. -- [MSM6258](msm6258.md) - for use with MSM6258 sample chip. -- [MSM6295](msm6295.md) - for use with MSM6295 sample chip. -- [ADPCM-A](adpcm-a.md) - for use with ADPCM-A sample chip. -- [ADPCM-B](adpcm-b.md) - for use with ADPCM-B sample chip. -- [SegaPCM](segapcm.md) - for use with SegaPCM sample chip. -- [QSound](qsound.md) - for use with QSound sample chip. -- [YMZ280B](ymz280b.md) - for use with YMZ280B sample chip. -- [RF5C68](rf5c68.md) - for use with RF5C68 sample chip. -- [MSM5232](msm5232.md) - for use with MSM5232 PSG sound source. -- [T6W28](t6w28.md) - for use with Toshiba T6W28 PSG sound source. -- [K007232](k007232.md) - for use with K007232 sample chip. -- [GA20](ga20.md) - for use with GA20 sample chip. -- [Pokémon Mini/QuadTone](pokemini.md) - for use with these systems. -- [SM8521](sm8521.md) - for use with SM8521 chip, used in Tiger Game.com. -- [PV-1000](pv1000.md) - for use with Casio PV-1000. -- [K053260](k053260.md) - for use with K053260 sample 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. -- [C219](c219.md) - for use with C219 sample chip. - -## macros - -macros are incredibly versatile tools for automating instrument parameters. - -after creating an instrument, open the Instrument Editor and select the "Macros" tab. there may be multiple macro tabs to control individual FM operators and such. - -![macro view](macroview.png) - -the very first numeric entry sets the visible width of the bars in sequence-type macros. the scrollbar affects the view of all macros at once. there is a matching scrollbar at the bottom underneath all the macros. - -each macro has the following parameters: -- macro type (explained below) -- timing options: - - **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. - - 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 - -there are three macro types: - -- ![sequence](macro-button-seq.png) **Sequence:** a sequence of numeric values. -- ![ADSR](macro-button-ADSR.png) **ADSR:** this is an attack/decay/sustain/release envelope. -- ![LFO](macro-button-LFO.png) **LFO:** Low Frequency Oscillator. - -### sequence - -this is the most basic macro type. when the instrument is played, every value in the macro will be output sequentially, from left to right. - -![sequence macro editor](macro-seq.png) - -![clipped sequence macro editor](macro-seq-clip.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 sequence view allows you to edit the macro. -- press and hold the left mouse button to start drawing. release to stop drawing. -- press and hold the right mouse button to draw a line. - - the start point will be set to the cursor position. - - move the cursor to change the end point. - - release to finish drawing the line. - -the sequence view may be adjusted using the following combinations: -- hold Ctrl and use the scroll wheel to zoom horizontally. -- hold Ctrl-Shift and use the scroll wheel to zoom vertically. -- the scrollbar at the right allows you to scroll vertically (if possible). -- you may hold Shift and use the scroll wheel to scroll vertically as well. - -right-click on the sequence view to open a menu: -- **copy**: copy this macro to clipboard. -- **paste**: pastes the macro. -- **clear**: clears the macro. -- **clear contents**: resets all values to 0. -- **offset**: - - **X**: slides the data "horizontally" within the macro, filling the gap with zeroes. data moved past the start or end is lost. - - **Y**: increases or decreases all values, clipping them if they would move past the allowed range. -- **scale**: - - **X**: stretches the macro. - - **Y**: multiplies all values by the scale factor, clipping them if they would exceed the allowed range. -- **randomize**: replaces all values with random values between **Min** and **Max**. - -arpeggio and pitch macros may have values above or below the visible area. indicators will be shown until they are scrolled into view. - -bitmask-style macros show labels for each of their bits. these are edited as toggles. -- drawing lines is not possible in these macros. - -under the sequence view there is a bar that allows you to set loop and release points. -- click to set the loop start point; the end point is the last step or release point. - - right-click to remove the loop point. -- shift-click to set the release point. - - the macro will stop at the release point until the note is released (`===` or `REL`). - - if the loop point is set, and it is placed before the release point, the macro will loop until note release instead. - - shift-right-click to remove the release point. - -arpeggio macros have an additional bar under the sequence view to set steps to "relative" or "fixed": -- by default, step values are offsets **relative** to the note. -- if clicked on, a step value becomes **fixed** and will be played at its corresponding note without regard to the currently playing note. - - values are counted from `C-0`. for example, a fixed value of 48 produces a `C-4` note. - - fixed values are especially useful for noise or percussion. - -the sequence can be edited in the text input field at the very bottom. the following symbols have special meanings: -- `|`: loop point. -- `/`: release point. -- in arpeggio macros, `@` prefixed to a value indicates that it is a fixed value as described above. - -in bitmask-style macros, the values are added up in binary and converted to decimal. - -### ADSR - -![ADSR macro editor](macro-ADSR.png) - -- **Bottom** and **Top** determine the macro's output range (Bottom can be larger than Top to invert the envelope!). all outputs will be between these two values. -- Attack, Decay, Sustain, SusDecay, and Release accept inputs between 0 to 255. these are scaled to the distance between Bottom and Top. - - the output starts at Bottom. - - **Attack** is how much the output moves toward Top with each tick. - - **Hold** sets how many ticks to stay at Top before Decay. - - **Decay** is how much the output moves to the Sustain level. - - **Sustain** is how far from Bottom the value stays while the note is on. - - **SusTime** is how many ticks to stay at Sustain until SusDecay. - - **SusDecay** is how much the output moves toward Bottom with each tick while the note is on. - - **Release** is how much the output moves toward Bottom with each tick after the note is released. - -![macro ADSR chart](macro-ADSRchart.png) - -### LFO - -![LFO macro editor](macro-LFO.png) - -- **Bottom** and **Top** determine the macro's output range (Bottom can be larger than Top to invert the waveform!). -- **Speed** is how quickly the LFO position moves. -- **Phase** defines the starting LFO position, measured in 1/1024 increments. -- **Shape** is the waveform of the LFO. there are three waveforms: - - Triangle: Bottom > Top > Bottom. - - Saw: moves from Bottom to Top, and then jumps back to Bottom. - - Square: alternates between Bottom and Top. - - - -## wavetable - -this tab appears for PC Engine, FDS, Namco WSG, and other wavetable-based instruments. - -![wavetable tab](wavetable.png) - -when **Enable synthesizer** is off, the wavetable used for the instrument may be selected by creating a Waveform macro with a single value. - -to use the wavetable synthesizer, refer to [the wavetable synthesizer section](wavesynth.md). - - -## sample - -this tab appears for Generic PCM DAC, Amiga and SNES. - -![sample tab](sample-map.png) - -see the [Generic Sample section](sample.md) for more information. +# instrument editor + +the instrument editor allows you to edit instruments. +it can be activated by double-clicking on an instrument in the instrument list. + +alternatively, window > instrument editor displays it. + +## main + +![top of instrument editor](instrument-editor-top.png) + +**TODO: add descriptions to buttons in the image. it really needs them.** + +- **Instrument Selector**: displays a list of instruments in the song. +- **Open**: open an instrument file. +- **Save**: save current instrument to a file. + - right-click to see additional options, such as saving in DefleMask preset format (.dmp). +- **Name**: changes the instrument name. +- **Type**: changes the instrument type (usually chip-specific). + - if changed, all applicable settings and macros will remain unchanged. + - you may have to adjust them afterwards. + +## instrument types + +the following instrument types are available: + +- [SN76489/Sega PSG](psg.md) - for use with TI SN76489 and derivatives like Sega Master System's PSG. +- [FM (OPN)](fm-opn.md) - for use with YM2612, YM2203, YM2608, YM2610 and YM2610B. +- [Game Boy](game-boy.md) - for use with Game Boy APU. +- [C64](c64.md) - for use with Commodore 64 SID. +- [Generic Sample](sample.md) for controlling Amiga and other sample channels/chips like YM2612's Channel 6 PCM mode, NES channel 5, Sega PCM, X1-010 and PC Engine's sample playback mode. +- [PC Engine](pce.md) - for use with PC Engine's wavetable synthesizer. +- [AY-3-8910/SSG](ay8910.md) - for use with AY-3-8910 PSG sound source and SSG portion in YM2610. +- [AY8930](ay8930.md) - for use with Microchip AY8930 E-PSG sound source. +- [TIA](tia.md) - for use with Atari 2600 chip. +- [SAA1099](saa.md) - for use with Philips SAA1099 PSG sound source. +- [VIC](vic.md) - for use with VIC-20 sound chip. +- [PET](pet.md) - for use with Commodore PET. +- [VRC6](vrc6.md) - for use with VRC6's PSG sound source. +- [FM (OPLL)](fm-opll.md) - for use with YM2413. +- [FM (OPL)](fm-opll.md) - for use with YM3526 (OPL), YM3812 (OPL2) and YMF262 (OPL3). +- [FDS](fds.md) - for use with Famicom Disk System sound source. +- [Virtual Boy](virtual-boy.md) - for use with Virtual Boy. +- [Namco 163](n163.md) - for use with Namco 163. +- [Konami SCC/Bubble System WSG](scc.md) - for use with Konami SCC and Wavetable portion in Bubble System's sound hardware. +- [FM (OPZ)](fm-opz.md) - for use with YM2414. +- [POKEY](pokey.md) - for use with Atari 8-bit computers and their POKEY sound source. +- [Beeper](beeper.md) - for use with PC Speaker and ZX Spectrum Beeper (SFX-like engine). +- [WonderSwan](wonderswan.md) - for use with WonderSwan's wavetable synthesizer. +- [Atari Lynx](lynx.md) - for use with Atari Lynx handheld console. +- [VERA](vera.md) - for use with Commander X16 VERA. +- [Seta/Allumer X1-010](x1_010.md) - for use with Wavetable portion in Seta/Allumer X1-010. +- [ES5506](es5506.md) - for use with Ensoniq ES5506 sound chip. +- [SNES](snes.md) - for use with SNES. +- [Sound Unit](su.md) - for use with Sound Unit chip. +- [Namco WSG](wsg.md) - for use with Namco WSG wavetable chips, including C15 and C30. +- [FM (OPM)](fm-opm.md) - for use with YM2151. +- [NES](nes.md) - for use with NES. +- [MSM6258](msm6258.md) - for use with MSM6258 sample chip. +- [MSM6295](msm6295.md) - for use with MSM6295 sample chip. +- [ADPCM-A](adpcm-a.md) - for use with ADPCM-A sample chip. +- [ADPCM-B](adpcm-b.md) - for use with ADPCM-B sample chip. +- [SegaPCM](segapcm.md) - for use with SegaPCM sample chip. +- [QSound](qsound.md) - for use with QSound sample chip. +- [YMZ280B](ymz280b.md) - for use with YMZ280B sample chip. +- [RF5C68](rf5c68.md) - for use with RF5C68 sample chip. +- [MSM5232](msm5232.md) - for use with MSM5232 PSG sound source. +- [T6W28](t6w28.md) - for use with Toshiba T6W28 PSG sound source. +- [K007232](k007232.md) - for use with K007232 sample chip. +- [GA20](ga20.md) - for use with GA20 sample chip. +- [Pokémon Mini/QuadTone](pokemini.md) - for use with these systems. +- [SM8521](sm8521.md) - for use with SM8521 chip, used in Tiger Game.com. +- [PV-1000](pv1000.md) - for use with Casio PV-1000. +- [K053260](k053260.md) - for use with K053260 sample 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. +- [C219](c219.md) - for use with C219 sample chip. + +## macros + +macros are incredibly versatile tools for automating instrument parameters. + +after creating an instrument, open the Instrument Editor and select the "Macros" tab. there may be multiple macro tabs to control individual FM operators and such. + +![macro view](macroview.png) + +the very first numeric entry sets the visible width of the bars in sequence-type macros. the scrollbar affects the view of all macros at once. there is a matching scrollbar at the bottom underneath all the macros. + +each macro has the following parameters: +- macro type (explained below) +- timing options: + - **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. + - 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 + +there are three macro types: + +- ![sequence](macro-button-seq.png) **Sequence:** a sequence of numeric values. +- ![ADSR](macro-button-ADSR.png) **ADSR:** this is an attack/decay/sustain/release envelope. +- ![LFO](macro-button-LFO.png) **LFO:** Low Frequency Oscillator. + +### sequence + +this is the most basic macro type. when the instrument is played, every value in the macro will be output sequentially, from left to right. + +![sequence macro editor](macro-seq.png) + +![clipped sequence macro editor](macro-seq-clip.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 sequence view allows you to edit the macro. +- press and hold the left mouse button to start drawing. release to stop drawing. +- press and hold the right mouse button to draw a line. + - the start point will be set to the cursor position. + - move the cursor to change the end point. + - release to finish drawing the line. + +the sequence view may be adjusted using the following combinations: +- hold Ctrl and use the scroll wheel to zoom horizontally. +- hold Ctrl-Shift and use the scroll wheel to zoom vertically. +- the scrollbar at the right allows you to scroll vertically (if possible). +- you may hold Shift and use the scroll wheel to scroll vertically as well. + +right-click on the sequence view to open a menu: +- **copy**: copy this macro to clipboard. +- **paste**: pastes the macro. +- **clear**: clears the macro. +- **clear contents**: resets all values to 0. +- **offset**: + - **X**: slides the data "horizontally" within the macro, filling the gap with zeroes. data moved past the start or end is lost. + - **Y**: increases or decreases all values, clipping them if they would move past the allowed range. +- **scale**: + - **X**: stretches the macro. + - **Y**: multiplies all values by the scale factor, clipping them if they would exceed the allowed range. +- **randomize**: replaces all values with random values between **Min** and **Max**. + +arpeggio and pitch macros may have values above or below the visible area. indicators will be shown until they are scrolled into view. + +bitmask-style macros show labels for each of their bits. these are edited as toggles. +- drawing lines is not possible in these macros. + +under the sequence view there is a bar that allows you to set loop and release points. +- click to set the loop start point; the end point is the last step or release point. + - right-click to remove the loop point. +- shift-click to set the release point. + - the macro will stop at the release point until the note is released (`===` or `REL`). + - if the loop point is set, and it is placed before the release point, the macro will loop until note release instead. + - shift-right-click to remove the release point. + +arpeggio macros have an additional bar under the sequence view to set steps to "relative" or "fixed": +- by default, step values are offsets **relative** to the note. +- if clicked on, a step value becomes **fixed** and will be played at its corresponding note without regard to the currently playing note. + - values are counted from `C-0`. for example, a fixed value of 48 produces a `C-4` note. + - fixed values are especially useful for noise or percussion. + +the sequence can be edited in the text input field at the very bottom. the following symbols have special meanings: +- `|`: loop point. +- `/`: release point. +- in arpeggio macros, `@` prefixed to a value indicates that it is a fixed value as described above. + +in bitmask-style macros, the values are added up in binary and converted to decimal. + +### ADSR + +![ADSR macro editor](macro-ADSR.png) + +- **Bottom** and **Top** determine the macro's output range (Bottom can be larger than Top to invert the envelope!). all outputs will be between these two values. +- Attack, Decay, Sustain, SusDecay, and Release accept inputs between 0 to 255. these are scaled to the distance between Bottom and Top. + - the output starts at Bottom. + - **Attack** is how much the output moves toward Top with each tick. + - **Hold** sets how many ticks to stay at Top before Decay. + - **Decay** is how much the output moves to the Sustain level. + - **Sustain** is how far from Bottom the value stays while the note is on. + - **SusTime** is how many ticks to stay at Sustain until SusDecay. + - **SusDecay** is how much the output moves toward Bottom with each tick while the note is on. + - **Release** is how much the output moves toward Bottom with each tick after the note is released. + +![macro ADSR chart](macro-ADSRchart.png) + +### LFO + +![LFO macro editor](macro-LFO.png) + +- **Bottom** and **Top** determine the macro's output range (Bottom can be larger than Top to invert the waveform!). +- **Speed** is how quickly the LFO position moves. +- **Phase** defines the starting LFO position, measured in 1/1024 increments. +- **Shape** is the waveform of the LFO. there are three waveforms: + - Triangle: Bottom > Top > Bottom. + - Saw: moves from Bottom to Top, and then jumps back to Bottom. + - Square: alternates between Bottom and Top. + + + +## wavetable + +this tab appears for PC Engine, FDS, Namco WSG, and other wavetable-based instruments. + +![wavetable tab](wavetable.png) + +when **Enable synthesizer** is off, the wavetable used for the instrument may be selected by creating a Waveform macro with a single value. + +to use the wavetable synthesizer, refer to [the wavetable synthesizer section](wavesynth.md). + + +## sample + +this tab appears for Generic PCM DAC, Amiga and SNES. + +![sample tab](sample-map.png) + +see the [Generic Sample section](sample.md) for more information. diff --git a/doc/4-instrument/beeper.md b/doc/4-instrument/beeper.md index 18fca296d..75c61d6ae 100644 --- a/doc/4-instrument/beeper.md +++ b/doc/4-instrument/beeper.md @@ -1,9 +1,9 @@ -# beeper instrument editor - -used in PC Speaker and ZX Spectrum (SFX-like engine). - -- **Volume**: on-off volume sequence. -- **Arpeggio**: pitch sequence. -- **Pulse Width**: pulse width sequence. - - only on ZX Spectrum. -- **Pitch**: fine pitch. +# beeper instrument editor + +used in PC Speaker and ZX Spectrum (SFX-like engine). + +- **Volume**: on-off volume sequence. +- **Arpeggio**: pitch sequence. +- **Pulse Width**: pulse width sequence. + - only on ZX Spectrum. +- **Pitch**: fine pitch. diff --git a/doc/4-instrument/msm5232.md b/doc/4-instrument/msm5232.md index 31c10320e..0c7648afe 100644 --- a/doc/4-instrument/msm5232.md +++ b/doc/4-instrument/msm5232.md @@ -1,16 +1,16 @@ -# MSM5232 instrument editor - -the instrument editor for MSM5232 consists of these macros: - -- **Volume**: volume sequence. - - only has effect when the envelope mode of a group is set to External. -- **Arpeggio**: pitch sequence. -- **Group Ctrl**: group control sequence: - - **sustain**: enable sustain mode. - - **2'**: enable 2' overtone. - - **4'**: enable 4' overtone. - - **8'**: enable 8' overtone. - - **16'**: enable 16' overtone. -- **Group Attack**: set attack rate of group. -- **Group Decay**: set decay rate of group. -- **Noise**: toggle noise mode. +# MSM5232 instrument editor + +the instrument editor for MSM5232 consists of these macros: + +- **Volume**: volume sequence. + - only has effect when the envelope mode of a group is set to External. +- **Arpeggio**: pitch sequence. +- **Group Ctrl**: group control sequence: + - **sustain**: enable sustain mode. + - **2'**: enable 2' overtone. + - **4'**: enable 4' overtone. + - **8'**: enable 8' overtone. + - **16'**: enable 16' overtone. +- **Group Attack**: set attack rate of group. +- **Group Decay**: set decay rate of group. +- **Noise**: toggle noise mode. diff --git a/doc/4-instrument/nes.md b/doc/4-instrument/nes.md index 64f5c0d08..742fc2109 100644 --- a/doc/4-instrument/nes.md +++ b/doc/4-instrument/nes.md @@ -1,52 +1,52 @@ -# NES instrument editor - -the NES instrument editor consists of two tabs. - -## DPCM - -this tab is somewhat similar to [the Sample instrument editor](sample.md), but it has been tailored for use with NES' DPCM channel. - -- **Sample**: specifies which sample should be assigned to the instrument. -- **Use sample map**: enables mapping different samples to notes. see next section for more information. - - when this option is disabled, 16 notes (from C-0 to D#1 and repeating) will map to the DPCM channel's 16 possible pitches. - -### sample map - -the sample map allows you to set a sample for each note. - -after enabling this option, a table appears with the contents of the sample map. -- the first column represents the input note. -- the second column allows you to type in a sample number for each note. - - you may press Delete to clear it. -- the third one is used to set the DPCM pitch at which the specified sample will play. - - for possible values, refer to the table below. - - you may press Delete to clear it. if no value is specified, the last pitch is used. -- the fourth column allows you to set the initial delta counter value when playing the sample. - - this is an hexadecimal number. - - the range is `00` to `7F`. - - you may press Delete to clear it. if no value is specified, the delta counter isn't altered. -- the fifth and last column provides a combo box for selecting a sample. - -you may right-click anywhere in the number, pitch and delta columns for additional options: -- **set entire map to this pitch**: sets the DPCM pitch of all notes to the selected cell's. -- **set entire map to this delta counter value**: sets the initial delta counter value of all notes to the selected cell's. -- **set entire map to this sample**: sets the sample number of all notes to the selected cell's. -- **reset pitches**: resets the sample map's DPCM pitches to defaults (15). -- **clear delta counter values**: removes all delta counter values from the map. -- **clear map samples**: removes all samples from the map. - -## Macros - -- **Volume**: volume sequence. -- **Arpeggio**: pitch sequence. -- **Duty/Noise**: duty cycle and noise mode. - - pulse duty cycles: - - `0`: 12.5% - - `1`: 25% - - `2`: 50% - - `3`: 75% - - noise modes: - - `0`: long noise - - `1`: short noise -- **Pitch**: fine pitch. -- **Phase Reset**: trigger restart of waveform. +# NES instrument editor + +the NES instrument editor consists of two tabs. + +## DPCM + +this tab is somewhat similar to [the Sample instrument editor](sample.md), but it has been tailored for use with NES' DPCM channel. + +- **Sample**: specifies which sample should be assigned to the instrument. +- **Use sample map**: enables mapping different samples to notes. see next section for more information. + - when this option is disabled, 16 notes (from C-0 to D#1 and repeating) will map to the DPCM channel's 16 possible pitches. + +### sample map + +the sample map allows you to set a sample for each note. + +after enabling this option, a table appears with the contents of the sample map. +- the first column represents the input note. +- the second column allows you to type in a sample number for each note. + - you may press Delete to clear it. +- the third one is used to set the DPCM pitch at which the specified sample will play. + - for possible values, refer to the table below. + - you may press Delete to clear it. if no value is specified, the last pitch is used. +- the fourth column allows you to set the initial delta counter value when playing the sample. + - this is an hexadecimal number. + - the range is `00` to `7F`. + - you may press Delete to clear it. if no value is specified, the delta counter isn't altered. +- the fifth and last column provides a combo box for selecting a sample. + +you may right-click anywhere in the number, pitch and delta columns for additional options: +- **set entire map to this pitch**: sets the DPCM pitch of all notes to the selected cell's. +- **set entire map to this delta counter value**: sets the initial delta counter value of all notes to the selected cell's. +- **set entire map to this sample**: sets the sample number of all notes to the selected cell's. +- **reset pitches**: resets the sample map's DPCM pitches to defaults (15). +- **clear delta counter values**: removes all delta counter values from the map. +- **clear map samples**: removes all samples from the map. + +## Macros + +- **Volume**: volume sequence. +- **Arpeggio**: pitch sequence. +- **Duty/Noise**: duty cycle and noise mode. + - pulse duty cycles: + - `0`: 12.5% + - `1`: 25% + - `2`: 50% + - `3`: 75% + - noise modes: + - `0`: long noise + - `1`: short noise +- **Pitch**: fine pitch. +- **Phase Reset**: trigger restart of waveform. diff --git a/doc/4-instrument/pokemini.md b/doc/4-instrument/pokemini.md index ceec01a1c..3368c2506 100644 --- a/doc/4-instrument/pokemini.md +++ b/doc/4-instrument/pokemini.md @@ -1,8 +1,8 @@ -# Pokémon Mini/QuadTone instrument editor - -used in these two chips/systems. these macros are available: - -- **Volume**: volume sequence. -- **Arpeggio**: pitch sequence. -- **Pulse Width**: pulse width sequence. -- **Pitch**: fine pitch. +# Pokémon Mini/QuadTone instrument editor + +used in these two chips/systems. these macros are available: + +- **Volume**: volume sequence. +- **Arpeggio**: pitch sequence. +- **Pulse Width**: pulse width sequence. +- **Pitch**: fine pitch. diff --git a/doc/4-instrument/pokey.md b/doc/4-instrument/pokey.md index 8b3ac7fc4..091e8f45a 100644 --- a/doc/4-instrument/pokey.md +++ b/doc/4-instrument/pokey.md @@ -1,25 +1,25 @@ -# Atari POKEY instrument editor - -the instrument editor for POKEY consists of these macros: - -- **Volume**: volume sequence. -- **Arpeggio**: pitch sequence. -- **AUDCTL**: audio control register sequence: - - **poly9**: reduces size of LFSR. only on noise waveforms! - - **high1**: runs channel 1 at 1.79MHz. - - **high3**: runs channel 3 at 1.79MHz. - - **16-bit 1+2**: enables 16-bit frequency mode by combining channels 1 and 2. - - **16-bit 3+4**: enables 16-bit frequency mode by combining channels 3 and 4. - - **filter 1+3**: applies a high-pass "filter" by combining channels 1 and 3. - - **filter 2+4**: applies a high-pass "filter" by combining channels 2 and 4. - - **15KHz**: runs channels at 15KHz. -- **Waveform**: wave selection sequence: - - 0: harsh noise (poly5+17) - - 1: square buzz (poly5) - - 2: weird noise (poly4+5) - - 3: square buzz (poly5) - - 4: soft noise (poly17) - - 5: square - - 6: bass (poly4) - - 7: buzz (poly4) -- **Pitch**: fine pitch. +# Atari POKEY instrument editor + +the instrument editor for POKEY consists of these macros: + +- **Volume**: volume sequence. +- **Arpeggio**: pitch sequence. +- **AUDCTL**: audio control register sequence: + - **poly9**: reduces size of LFSR. only on noise waveforms! + - **high1**: runs channel 1 at 1.79MHz. + - **high3**: runs channel 3 at 1.79MHz. + - **16-bit 1+2**: enables 16-bit frequency mode by combining channels 1 and 2. + - **16-bit 3+4**: enables 16-bit frequency mode by combining channels 3 and 4. + - **filter 1+3**: applies a high-pass "filter" by combining channels 1 and 3. + - **filter 2+4**: applies a high-pass "filter" by combining channels 2 and 4. + - **15KHz**: runs channels at 15KHz. +- **Waveform**: wave selection sequence: + - 0: harsh noise (poly5+17) + - 1: square buzz (poly5) + - 2: weird noise (poly4+5) + - 3: square buzz (poly5) + - 4: soft noise (poly17) + - 5: square + - 6: bass (poly4) + - 7: buzz (poly4) +- **Pitch**: fine pitch. diff --git a/doc/4-instrument/psg.md b/doc/4-instrument/psg.md index 6b09e534f..aac9260c1 100644 --- a/doc/4-instrument/psg.md +++ b/doc/4-instrument/psg.md @@ -1,15 +1,15 @@ -# Sega PSG instrument editor - -the instrument editor for Sega PSG (SMS, and other TI SN76489 derivatives) consists of these macros: - -- **Volume**: volume sequence. -- **Arpeggio**: pitch sequence. -- **Duty**: noise mode. - - `0`: short noise; preset frequencies. - - `1`: long noise; preset frequencies. - - `2`: short noise; use channel 3 for frequency. - - `3`: long noise; use channel 3 for frequency. -- **Panning**: output for left and right channels. - - only on Game Gear! -- **Pitch**: fine pitch. -- **Phase Reset**: trigger restart of waveform. +# Sega PSG instrument editor + +the instrument editor for Sega PSG (SMS, and other TI SN76489 derivatives) consists of these macros: + +- **Volume**: volume sequence. +- **Arpeggio**: pitch sequence. +- **Duty**: noise mode. + - `0`: short noise; preset frequencies. + - `1`: long noise; preset frequencies. + - `2`: short noise; use channel 3 for frequency. + - `3`: long noise; use channel 3 for frequency. +- **Panning**: output for left and right channels. + - only on Game Gear! +- **Pitch**: fine pitch. +- **Phase Reset**: trigger restart of waveform. diff --git a/doc/4-instrument/t6w28.md b/doc/4-instrument/t6w28.md index 8343733bd..3d548408e 100644 --- a/doc/4-instrument/t6w28.md +++ b/doc/4-instrument/t6w28.md @@ -1,13 +1,13 @@ -# T6W28 instrument editor - -the instrument editor for T6W28 consists of these macros: - -- **Volume**: volume sequence. -- **Arpeggio**: pitch sequence. -- **Noise Type**: noise type sequence: - - `0`: short noise - - `1`: long noise -- **Panning (left)**: output level for left channel. -- **Panning (right)**: output level for right channel. -- **Pitch**: fine pitch. -- **Phase Reset**: trigger restart of waveform. +# T6W28 instrument editor + +the instrument editor for T6W28 consists of these macros: + +- **Volume**: volume sequence. +- **Arpeggio**: pitch sequence. +- **Noise Type**: noise type sequence: + - `0`: short noise + - `1`: long noise +- **Panning (left)**: output level for left channel. +- **Panning (right)**: output level for right channel. +- **Pitch**: fine pitch. +- **Phase Reset**: trigger restart of waveform. From 4667fe1c11314ed07c629af500866de4c70dfbbb Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 13 Jan 2024 17:12:33 -0500 Subject: [PATCH 47/74] more de-CRLFization --- doc/7-systems/dac.md | 26 ++++++------ doc/7-systems/es5506.md | 92 ++++++++++++++++++++--------------------- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/doc/7-systems/dac.md b/doc/7-systems/dac.md index 7639495ea..74a9c7df7 100644 --- a/doc/7-systems/dac.md +++ b/doc/7-systems/dac.md @@ -1,13 +1,13 @@ -# Generic PCM DAC - -a sample channel, with freely selectable rate, mono/stereo and bit depth settings. - -with it, you can emulate PCM DACs found in Williams arcade boards, Sound Blasters, MSX TurboR, Atari STe, NEC PC-9801-86, among others. - -## effects - -none yet. - -## info - -this chip uses the [Generic Sample](../4-instrument/sample.md) instrument editor. +# Generic PCM DAC + +a sample channel, with freely selectable rate, mono/stereo and bit depth settings. + +with it, you can emulate PCM DACs found in Williams arcade boards, Sound Blasters, MSX TurboR, Atari STe, NEC PC-9801-86, among others. + +## effects + +none yet. + +## info + +this chip uses the [Generic Sample](../4-instrument/sample.md) instrument editor. diff --git a/doc/7-systems/es5506.md b/doc/7-systems/es5506.md index d6ddb9d79..ff4eb1db3 100644 --- a/doc/7-systems/es5506.md +++ b/doc/7-systems/es5506.md @@ -1,46 +1,46 @@ -# Ensoniq ES5506 (OTTO) - -sample-based synthesis chip used in a bunch of Taito arcade machines and PC sound cards like Soundscape Elite. a variant of it was the heart of the well-known Gravis Ultrasound. - -it has a whopping 32 channels of 16-bit PCM and: - -- real time digital filters -- linear interpolation -- loop start and stop positions for each voice (bidirectional and reverse looping) -- internal volume multiplication and stereo panning -- hardware support for short envelopes - -## effects - -- `10xx`: **set waveform.** -- `11xx`: **set filter mode.** values are `0` through `3`. -- `120x`: **set pause (bit 0).** pauses the sample until the bit is unset; it will then resume where it left off. -- `14xx`: **set filter coefficient K1 low byte.** -- `15xx`: **set filter coefficient K1 high byte.** -- `16xx`: **set filter coefficient K2 low byte.** -- `17xx`: **set filter coefficient K2 high byte.** -- `18xx`: **set filter coefficient K1 slide up.** -- `19xx`: **set filter coefficient K1 slide down.** -- `1Axx`: **set filter coefficient K2 slide up.** -- `1Bxx`: **set filter coefficient K2 slide down.** -- `20xx`: **set envelope count.** -- `22xx`: **set envelope left volume ramp.** -- `23xx`: **set envelope right volume ramp.** -- `24xx`: **set envelope filter coefficient K1 ramp.** -- `25xx`: **set envelope filter coefficient K1 ramp (slower).** -- `26xx`: **set envelope filter coefficient K2 ramp.** -- `27xx`: **set envelope filter coefficient K2 ramp (slower).** -- `3xxx`: **set coarse filter coefficient K1.** -- `4xxx`: **set coarse filter coefficient K2.** -- `81xx`: **set panning (left channel).** -- `82xx`: **set panning (right channel).** -- `88xx`: **set panning (rear channels).** -- `89xx`: **set panning (rear left channel).** -- `8Axx`: **set panning (rear right channel).** -- `9xxx`: **set sample offset.** - - resets sample position to `xxx * 0x100`. -- `DFxx`: **set sample playback direction.** - -## info - -this chip uses the [ES5506](../4-instrument/es5506.md) instrument editor. +# Ensoniq ES5506 (OTTO) + +sample-based synthesis chip used in a bunch of Taito arcade machines and PC sound cards like Soundscape Elite. a variant of it was the heart of the well-known Gravis Ultrasound. + +it has a whopping 32 channels of 16-bit PCM and: + +- real time digital filters +- linear interpolation +- loop start and stop positions for each voice (bidirectional and reverse looping) +- internal volume multiplication and stereo panning +- hardware support for short envelopes + +## effects + +- `10xx`: **set waveform.** +- `11xx`: **set filter mode.** values are `0` through `3`. +- `120x`: **set pause (bit 0).** pauses the sample until the bit is unset; it will then resume where it left off. +- `14xx`: **set filter coefficient K1 low byte.** +- `15xx`: **set filter coefficient K1 high byte.** +- `16xx`: **set filter coefficient K2 low byte.** +- `17xx`: **set filter coefficient K2 high byte.** +- `18xx`: **set filter coefficient K1 slide up.** +- `19xx`: **set filter coefficient K1 slide down.** +- `1Axx`: **set filter coefficient K2 slide up.** +- `1Bxx`: **set filter coefficient K2 slide down.** +- `20xx`: **set envelope count.** +- `22xx`: **set envelope left volume ramp.** +- `23xx`: **set envelope right volume ramp.** +- `24xx`: **set envelope filter coefficient K1 ramp.** +- `25xx`: **set envelope filter coefficient K1 ramp (slower).** +- `26xx`: **set envelope filter coefficient K2 ramp.** +- `27xx`: **set envelope filter coefficient K2 ramp (slower).** +- `3xxx`: **set coarse filter coefficient K1.** +- `4xxx`: **set coarse filter coefficient K2.** +- `81xx`: **set panning (left channel).** +- `82xx`: **set panning (right channel).** +- `88xx`: **set panning (rear channels).** +- `89xx`: **set panning (rear left channel).** +- `8Axx`: **set panning (rear right channel).** +- `9xxx`: **set sample offset.** + - resets sample position to `xxx * 0x100`. +- `DFxx`: **set sample playback direction.** + +## info + +this chip uses the [ES5506](../4-instrument/es5506.md) instrument editor. From 52f9f888fc1195135c17ef4bb25d2d84cfa935da Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 16 Jan 2024 16:40:10 -0500 Subject: [PATCH 48/74] GUI: display pattern view label opts with pat font --- src/gui/settings.cpp | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 3f4bd9de7..c4185e038 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -2754,11 +2754,31 @@ void FurnaceGUI::drawSettings() { ImGui::Unindent(); ImGui::Text("Pattern view labels:"); - if (ImGui::InputTextWithHint("Note off (3-char)","OFF",&settings.noteOffLabel)) settingsChanged=true; - if (ImGui::InputTextWithHint("Note release (3-char)","===",&settings.noteRelLabel)) settingsChanged=true; - if (ImGui::InputTextWithHint("Macro release (3-char)","REL",&settings.macroRelLabel)) settingsChanged=true; - if (ImGui::InputTextWithHint("Empty field (3-char)","...",&settings.emptyLabel)) settingsChanged=true; - if (ImGui::InputTextWithHint("Empty field (2-char)","..",&settings.emptyLabel2)) settingsChanged=true; + ImGui::PushFont(patFont); + if (ImGui::InputTextWithHint("##PVLOff","OFF",&settings.noteOffLabel)) settingsChanged=true; + ImGui::PopFont(); + ImGui::SameLine(); + ImGui::Text("Note off (3-char)"); + ImGui::PushFont(patFont); + if (ImGui::InputTextWithHint("##PVLRel","===",&settings.noteRelLabel)) settingsChanged=true; + ImGui::PopFont(); + ImGui::SameLine(); + ImGui::Text("Note release (3-char)"); + ImGui::PushFont(patFont); + if (ImGui::InputTextWithHint("##PVLMacroRel","REL",&settings.macroRelLabel)) settingsChanged=true; + ImGui::PopFont(); + ImGui::SameLine(); + ImGui::Text("Macro release (3-char)"); + ImGui::PushFont(patFont); + if (ImGui::InputTextWithHint("##PVLE3","...",&settings.emptyLabel)) settingsChanged=true; + ImGui::PopFont(); + ImGui::SameLine(); + ImGui::Text("Empty field (3-char)"); + ImGui::PushFont(patFont); + if (ImGui::InputTextWithHint("##PVLE2","..",&settings.emptyLabel2)) settingsChanged=true; + ImGui::PopFont(); + ImGui::SameLine(); + ImGui::Text("Empty field (2-char)"); ImGui::Text("Pattern view spacing after:"); From 6e5a25d824e19d4d02ecd14d6f41b907988f2b19 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 16 Jan 2024 17:09:26 -0500 Subject: [PATCH 49/74] GUI: insEdit code style --- src/gui/insEdit.cpp | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index bc0859811..f125df426 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -3612,13 +3612,18 @@ void FurnaceGUI::drawInsEdit() { mod=false; } else if (ins->type==DIV_INS_ESFM) { // this is the same as the KVS heuristic in platform/esfm.h - if (opE.outLvl==7) mod=false; - else if (opE.outLvl>0) { - if (i==3) mod=false; - else { + if (opE.outLvl==7) { + mod=false; + } else if (opE.outLvl>0) { + if (i==3) { + mod=false; + } else { DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; - if (opENext.modIn==0) mod=false; - else if ((opE.outLvl-opENext.modIn)>=2) mod=false; + if (opENext.modIn==0) { + mod=false; + } else if ((opE.outLvl-opENext.modIn)>=2) { + mod=false; + } } } } else if (opCount==4) { @@ -4781,13 +4786,18 @@ void FurnaceGUI::drawInsEdit() { mod=false; } else if (ins->type==DIV_INS_ESFM) { // this is the same as the KVS heuristic in platform/esfm.h - if (opE.outLvl==7) mod=false; - else if (opE.outLvl>0) { - if (i==3) mod=false; - else { + if (opE.outLvl==7) { + mod=false; + } else if (opE.outLvl>0) { + if (i==3) { + mod=false; + } else { DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; - if (opENext.modIn==0) mod=false; - else if ((opE.outLvl-opENext.modIn)>=2) mod=false; + if (opENext.modIn==0) { + mod=false; + } else if ((opE.outLvl-opENext.modIn)>=2) { + mod=false; + } } } } else if (opCount==4) { From 878a899d18036edf29975cca5d18ccc79e6b05c4 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 16 Jan 2024 17:12:36 -0500 Subject: [PATCH 50/74] ESFM: do not re-define KVS macro --- src/engine/platform/esfm.cpp | 16 ++++++++-------- src/engine/platform/esfm.h | 6 +----- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index c9f8a6c62..46ea1bb90 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -75,7 +75,7 @@ void DivPlatformESFM::tick(bool sysTick) { rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); } else { rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); - if (KVS(i,o)) { + if (KVS_ES(i,o)) { rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[i].outVol&0x3f,63))|(op.ksl<<6)); } else { rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); @@ -185,7 +185,7 @@ void DivPlatformESFM::tick(bool sysTick) { op.ksl=m.ksl.val; } - if (KVS(i,o)) { + if (KVS_ES(i,o)) { rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[i].outVol&0x3f,63))|(op.ksl<<6)); } else { rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); @@ -396,7 +396,7 @@ void DivPlatformESFM::muteChannel(int ch, bool mute) { rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); } else { rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); - if (KVS(ch,o)) { + if (KVS_ES(ch,o)) { rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[ch].outVol&0x3f,63))|(op.ksl<<6)); } else { rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); @@ -419,7 +419,7 @@ void DivPlatformESFM::commitState(int ch, DivInstrument* ins) { rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0); } else { rWrite(baseAddr+ADDR_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5)); - if (KVS(ch,o)) { + if (KVS_ES(ch,o)) { rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[ch].outVol&0x3f,63))|(op.ksl<<6)); } else { rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); @@ -478,7 +478,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { for (int o=0; o<4; o++) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; - if (KVS(c.chan,o)) { + if (KVS_ES(c.chan,o)) { rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); } else { rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); @@ -567,7 +567,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.tl=c.value2&63; - if (KVS(c.chan,o)) { + if (KVS_ES(c.chan,o)) { rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); } else { rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); @@ -755,7 +755,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ksl=c.value2&3; - if (KVS(c.chan,o)) { + if (KVS_ES(c.chan,o)) { rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); } else { rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); @@ -767,7 +767,7 @@ int DivPlatformESFM::dispatch(DivCommand c) { unsigned short baseAddr=c.chan*32+o*8; DivInstrumentFM::Operator& op=chan[c.chan].state.fm.op[o]; op.ksl=c.value2&3; - if (KVS(c.chan,o)) { + if (KVS_ES(c.chan,o)) { rWrite(baseAddr+ADDR_KSL_TL,(63-VOL_SCALE_LOG_BROKEN(63-op.tl,chan[c.chan].outVol&0x3f,63))|(op.ksl<<6)); } else { rWrite(baseAddr+ADDR_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); diff --git a/src/engine/platform/esfm.h b/src/engine/platform/esfm.h index a183925c7..36768af8a 100644 --- a/src/engine/platform/esfm.h +++ b/src/engine/platform/esfm.h @@ -147,10 +147,6 @@ class DivPlatformESFM: public DivDispatch { } } -#ifdef KVS -#undef KVS -#endif - /** * ESFM doesn't have predef algorithms, so a custom KVS heuristic for auto mode is needed. * This is a bit too complex for a macro. @@ -161,7 +157,7 @@ class DivPlatformESFM: public DivDispatch { * or op[o].outLvl > 0 and (op[o].outLvl - op[o + 1].modIn) >= 2, * or op[o].outLvl > 0 and op[o + 1].modIn == 0. */ - inline bool KVS(int c, int o) { + inline bool KVS_ES(int c, int o) { if (c<0 || c>=18 || o<0 || o>=4) return false; if (chan[c].state.fm.op[o].kvs==1) return true; From ab3624789b135b0d978988cae78b974d9fefc27f Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 16 Jan 2024 17:15:46 -0500 Subject: [PATCH 51/74] update to-do list --- TODO.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO.md b/TODO.md index f1918edef..9389f7edb 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,6 @@ # to-do +- individual macro retrigger - finish color import improvements (settings refactor) - new undo stuff - fix some bugs From 928bfd2afd06e4301de615c291eac81fad751237 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 16 Jan 2024 21:12:34 -0500 Subject: [PATCH 52/74] add sample rate parameter in raw sample import --- src/engine/engine.h | 2 +- src/engine/fileOpsSample.cpp | 6 +++--- src/gui/gui.cpp | 12 +++++++++++- src/gui/gui.h | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index a5b73b2ba..b12bc926c 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -954,7 +954,7 @@ class DivEngine { DivSample* sampleFromFile(const char* path); // get raw sample - DivSample* sampleFromFileRaw(const char* path, DivSampleDepth depth, int channels, bool bigEndian, bool unsign, bool swapNibbles); + DivSample* sampleFromFileRaw(const char* path, DivSampleDepth depth, int channels, bool bigEndian, bool unsign, bool swapNibbles, int rate); // delete sample void delSample(int index); diff --git a/src/engine/fileOpsSample.cpp b/src/engine/fileOpsSample.cpp index 4a44d0192..55969df33 100644 --- a/src/engine/fileOpsSample.cpp +++ b/src/engine/fileOpsSample.cpp @@ -302,7 +302,7 @@ DivSample* DivEngine::sampleFromFile(const char* path) { #endif } -DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth, int channels, bool bigEndian, bool unsign, bool swapNibbles) { +DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth, int channels, bool bigEndian, bool unsign, bool swapNibbles, int rate) { if (song.sample.size()>=256) { lastError="too many samples!"; return NULL; @@ -420,8 +420,8 @@ DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth, return NULL; } - sample->rate=32000; - sample->centerRate=32000; + sample->rate=rate; + sample->centerRate=rate; sample->depth=depth; sample->init(samples); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index b8da63237..a3d2690e5 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -5988,6 +5988,15 @@ bool FurnaceGUI::loop() { pendingRawSampleBigEndian=false; } + ImGui::AlignTextToFramePadding(); + ImGui::Text("Sample rate"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(120.0f*dpiScale); + if (ImGui::InputInt("##RSRate",&pendingRawSampleRate,100,1000)) { + if (pendingRawSampleRate<100) pendingRawSampleRate=100; + if (pendingRawSampleRate>384000) pendingRawSampleRate=384000; + } + if (pendingRawSampleDepth==DIV_SAMPLE_DEPTH_8BIT || pendingRawSampleDepth==DIV_SAMPLE_DEPTH_16BIT) { ImGui::AlignTextToFramePadding(); ImGui::Text("Channels"); @@ -6033,7 +6042,7 @@ bool FurnaceGUI::loop() { } if (ImGui::Button("OK")) { - DivSample* s=e->sampleFromFileRaw(pendingRawSample.c_str(),(DivSampleDepth)pendingRawSampleDepth,pendingRawSampleChannels,pendingRawSampleBigEndian,pendingRawSampleUnsigned,pendingRawSampleSwapNibbles); + DivSample* s=e->sampleFromFileRaw(pendingRawSample.c_str(),(DivSampleDepth)pendingRawSampleDepth,pendingRawSampleChannels,pendingRawSampleBigEndian,pendingRawSampleUnsigned,pendingRawSampleSwapNibbles,pendingRawSampleRate); if (s==NULL) { showError(e->getLastError()); } else { @@ -7225,6 +7234,7 @@ FurnaceGUI::FurnaceGUI(): editString(NULL), pendingRawSampleDepth(8), pendingRawSampleChannels(1), + pendingRawSampleRate(32000), pendingRawSampleUnsigned(false), pendingRawSampleBigEndian(false), pendingRawSampleSwapNibbles(false), diff --git a/src/gui/gui.h b/src/gui/gui.h index 3e0e53137..b2facc682 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1497,7 +1497,7 @@ class FurnaceGUI { SDL_Event userEvent; String pendingRawSample; - int pendingRawSampleDepth, pendingRawSampleChannels; + int pendingRawSampleDepth, pendingRawSampleChannels, pendingRawSampleRate; bool pendingRawSampleUnsigned, pendingRawSampleBigEndian, pendingRawSampleSwapNibbles, pendingRawSampleReplace; ImGuiWindowFlags globalWinFlags; From 88b42ddd58a7a6e0df0a219261599eac0474ac4b Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 16 Jan 2024 21:26:57 -0500 Subject: [PATCH 53/74] update copyright year --- README.md | 2 +- doc/README.md | 2 +- res/docpdf/make_paper.py | 2 +- res/releaseReadme/stable-linux.txt | 2 +- res/releaseReadme/stable-mac.txt | 2 +- res/releaseReadme/stable-win.txt | 2 +- src/audio/abstract.cpp | 2 +- src/audio/jack.cpp | 2 +- src/audio/jack.h | 2 +- src/audio/midi.cpp | 2 +- src/audio/pa.cpp | 2 +- src/audio/pa.h | 2 +- src/audio/rtmidi.cpp | 2 +- src/audio/rtmidi.h | 2 +- src/audio/sdlAudio.cpp | 2 +- src/audio/sdlAudio.h | 2 +- src/audio/taAudio.h | 2 +- src/baseutils.cpp | 2 +- src/baseutils.h | 2 +- src/cli/cli.cpp | 2 +- src/cli/cli.h | 2 +- src/engine/bsr.h | 2 +- src/engine/chipUtils.h | 2 +- src/engine/cmdStream.cpp | 2 +- src/engine/cmdStream.h | 2 +- src/engine/cmdStreamOps.cpp | 2 +- src/engine/config.cpp | 2 +- src/engine/config.h | 2 +- src/engine/configEngine.cpp | 2 +- src/engine/dataErrors.h | 2 +- src/engine/defines.h | 2 +- src/engine/dispatch.h | 2 +- src/engine/dispatchContainer.cpp | 2 +- src/engine/effect.h | 2 +- src/engine/effect/abstract.cpp | 2 +- src/engine/effect/dummy.cpp | 2 +- src/engine/effect/dummy.h | 2 +- src/engine/effectContainer.cpp | 2 +- src/engine/engine.cpp | 2 +- src/engine/engine.h | 2 +- src/engine/export.cpp | 2 +- src/engine/export.h | 2 +- src/engine/export/abstract.cpp | 2 +- src/engine/export/amigaValidation.cpp | 2 +- src/engine/export/amigaValidation.h | 2 +- src/engine/fileOps.cpp | 2 +- src/engine/fileOpsIns.cpp | 2 +- src/engine/fileOpsSample.cpp | 2 +- src/engine/filter.cpp | 2 +- src/engine/filter.h | 2 +- src/engine/instrument.cpp | 2 +- src/engine/instrument.h | 2 +- src/engine/macroInt.cpp | 2 +- src/engine/macroInt.h | 2 +- src/engine/orders.h | 2 +- src/engine/pattern.cpp | 2 +- src/engine/pattern.h | 2 +- src/engine/pitchTable.cpp | 2 +- src/engine/platform/abstract.cpp | 2 +- src/engine/platform/amiga.cpp | 2 +- src/engine/platform/amiga.h | 2 +- src/engine/platform/arcade.cpp | 2 +- src/engine/platform/arcade.h | 2 +- src/engine/platform/ay.cpp | 2 +- src/engine/platform/ay.h | 2 +- src/engine/platform/ay8930.cpp | 2 +- src/engine/platform/ay8930.h | 2 +- src/engine/platform/bubsyswsg.cpp | 2 +- src/engine/platform/bubsyswsg.h | 2 +- src/engine/platform/c140.cpp | 2 +- src/engine/platform/c140.h | 2 +- src/engine/platform/c64.cpp | 2 +- src/engine/platform/c64.h | 2 +- src/engine/platform/dummy.cpp | 2 +- src/engine/platform/dummy.h | 2 +- src/engine/platform/es5506.cpp | 2 +- src/engine/platform/es5506.h | 2 +- src/engine/platform/esfm.cpp | 2 +- src/engine/platform/esfm.h | 2 +- src/engine/platform/fds.cpp | 2 +- src/engine/platform/fds.h | 2 +- src/engine/platform/fmshared_OPM.h | 2 +- src/engine/platform/fmshared_OPN.h | 2 +- src/engine/platform/fmsharedbase.h | 2 +- src/engine/platform/ga20.cpp | 2 +- src/engine/platform/ga20.h | 2 +- src/engine/platform/gb.cpp | 2 +- src/engine/platform/gb.h | 2 +- src/engine/platform/genesis.cpp | 2 +- src/engine/platform/genesis.h | 2 +- src/engine/platform/genesisext.cpp | 2 +- src/engine/platform/genesisext.h | 2 +- src/engine/platform/k007232.cpp | 2 +- src/engine/platform/k007232.h | 2 +- src/engine/platform/k053260.cpp | 2 +- src/engine/platform/k053260.h | 2 +- src/engine/platform/lynx.cpp | 2 +- src/engine/platform/lynx.h | 2 +- src/engine/platform/mmc5.cpp | 2 +- src/engine/platform/mmc5.h | 2 +- src/engine/platform/msm5232.cpp | 2 +- src/engine/platform/msm5232.h | 2 +- src/engine/platform/msm6258.cpp | 2 +- src/engine/platform/msm6258.h | 2 +- src/engine/platform/msm6295.cpp | 2 +- src/engine/platform/msm6295.h | 2 +- src/engine/platform/n163.cpp | 2 +- src/engine/platform/n163.h | 2 +- src/engine/platform/namcowsg.cpp | 2 +- src/engine/platform/namcowsg.h | 2 +- src/engine/platform/nes.cpp | 2 +- src/engine/platform/nes.h | 2 +- src/engine/platform/opl.cpp | 2 +- src/engine/platform/opl.h | 2 +- src/engine/platform/oplAInterface.cpp | 2 +- src/engine/platform/opll.cpp | 2 +- src/engine/platform/opll.h | 2 +- src/engine/platform/pce.cpp | 2 +- src/engine/platform/pce.h | 2 +- src/engine/platform/pcmdac.cpp | 2 +- src/engine/platform/pcmdac.h | 2 +- src/engine/platform/pcspkr.cpp | 2 +- src/engine/platform/pcspkr.h | 2 +- src/engine/platform/pet.cpp | 2 +- src/engine/platform/pet.h | 2 +- src/engine/platform/pokemini.cpp | 2 +- src/engine/platform/pokemini.h | 2 +- src/engine/platform/pokey.cpp | 2 +- src/engine/platform/pokey.h | 2 +- src/engine/platform/pong.cpp | 2 +- src/engine/platform/pong.h | 2 +- src/engine/platform/pv1000.cpp | 2 +- src/engine/platform/pv1000.h | 2 +- src/engine/platform/qsound.cpp | 2 +- src/engine/platform/qsound.h | 2 +- src/engine/platform/rf5c68.cpp | 2 +- src/engine/platform/rf5c68.h | 2 +- src/engine/platform/saa.cpp | 2 +- src/engine/platform/saa.h | 2 +- src/engine/platform/scc.cpp | 2 +- src/engine/platform/scc.h | 2 +- src/engine/platform/segapcm.cpp | 2 +- src/engine/platform/segapcm.h | 2 +- src/engine/platform/sm8521.cpp | 2 +- src/engine/platform/sm8521.h | 2 +- src/engine/platform/sms.cpp | 2 +- src/engine/platform/sms.h | 2 +- src/engine/platform/snes.cpp | 2 +- src/engine/platform/snes.h | 2 +- src/engine/platform/su.cpp | 2 +- src/engine/platform/su.h | 2 +- src/engine/platform/swan.cpp | 2 +- src/engine/platform/swan.h | 2 +- src/engine/platform/t6w28.cpp | 2 +- src/engine/platform/t6w28.h | 2 +- src/engine/platform/ted.cpp | 2 +- src/engine/platform/ted.h | 2 +- src/engine/platform/tia.cpp | 2 +- src/engine/platform/tia.h | 2 +- src/engine/platform/tx81z.cpp | 2 +- src/engine/platform/tx81z.h | 2 +- src/engine/platform/vb.cpp | 2 +- src/engine/platform/vb.h | 2 +- src/engine/platform/vera.cpp | 2 +- src/engine/platform/vera.h | 2 +- src/engine/platform/vic20.cpp | 2 +- src/engine/platform/vic20.h | 2 +- src/engine/platform/vrc6.cpp | 2 +- src/engine/platform/vrc6.h | 2 +- src/engine/platform/x1_010.cpp | 2 +- src/engine/platform/x1_010.h | 2 +- src/engine/platform/ym2203.cpp | 2 +- src/engine/platform/ym2203.h | 2 +- src/engine/platform/ym2203ext.cpp | 2 +- src/engine/platform/ym2203ext.h | 2 +- src/engine/platform/ym2608.cpp | 2 +- src/engine/platform/ym2608.h | 2 +- src/engine/platform/ym2608Interface.cpp | 2 +- src/engine/platform/ym2608ext.cpp | 2 +- src/engine/platform/ym2608ext.h | 2 +- src/engine/platform/ym2610.cpp | 2 +- src/engine/platform/ym2610.h | 2 +- src/engine/platform/ym2610Interface.cpp | 2 +- src/engine/platform/ym2610b.cpp | 2 +- src/engine/platform/ym2610b.h | 2 +- src/engine/platform/ym2610bext.cpp | 2 +- src/engine/platform/ym2610bext.h | 2 +- src/engine/platform/ym2610ext.cpp | 2 +- src/engine/platform/ym2610ext.h | 2 +- src/engine/platform/ym2610shared.h | 2 +- src/engine/platform/ymz280b.cpp | 2 +- src/engine/platform/ymz280b.h | 2 +- src/engine/platform/zxbeeper.cpp | 2 +- src/engine/platform/zxbeeper.h | 2 +- src/engine/platform/zxbeeperquadtone.cpp | 2 +- src/engine/platform/zxbeeperquadtone.h | 2 +- src/engine/playback.cpp | 2 +- src/engine/safeReader.cpp | 2 +- src/engine/safeReader.h | 2 +- src/engine/safeWriter.cpp | 2 +- src/engine/safeWriter.h | 2 +- src/engine/sample.cpp | 2 +- src/engine/sample.h | 2 +- src/engine/sfWrapper.cpp | 2 +- src/engine/sfWrapper.h | 2 +- src/engine/song.cpp | 2 +- src/engine/song.h | 2 +- src/engine/sysDef.cpp | 2 +- src/engine/vgmOps.cpp | 2 +- src/engine/wavOps.cpp | 2 +- src/engine/waveSynth.cpp | 2 +- src/engine/waveSynth.h | 2 +- src/engine/wavetable.cpp | 2 +- src/engine/wavetable.h | 2 +- src/engine/winStuff.cpp | 2 +- src/engine/winStuff.h | 2 +- src/engine/workPool.cpp | 2 +- src/engine/workPool.h | 2 +- src/engine/zsm.cpp | 2 +- src/engine/zsm.h | 2 +- src/engine/zsmOps.cpp | 2 +- src/fileutils.cpp | 2 +- src/fileutils.h | 2 +- src/fixedQueue.h | 2 +- src/gui/about.cpp | 4 ++-- src/gui/actionUtil.h | 2 +- src/gui/chanOsc.cpp | 2 +- src/gui/channels.cpp | 2 +- src/gui/clock.cpp | 2 +- src/gui/compatFlags.cpp | 2 +- src/gui/cursor.cpp | 2 +- src/gui/dataList.cpp | 2 +- src/gui/debug.cpp | 2 +- src/gui/debug.h | 2 +- src/gui/debugWindow.cpp | 2 +- src/gui/doAction.cpp | 2 +- src/gui/editControls.cpp | 2 +- src/gui/editing.cpp | 2 +- src/gui/exportOptions.cpp | 2 +- src/gui/findReplace.cpp | 2 +- src/gui/fmPreview.cpp | 2 +- src/gui/fonts.cpp | 2 +- src/gui/fonts.h | 2 +- src/gui/gradient.cpp | 2 +- src/gui/grooves.cpp | 2 +- src/gui/gui.cpp | 2 +- src/gui/gui.h | 2 +- src/gui/guiConst.cpp | 2 +- src/gui/guiConst.h | 2 +- src/gui/image.cpp | 2 +- src/gui/image.h | 2 +- src/gui/insEdit.cpp | 2 +- src/gui/intConst.cpp | 2 +- src/gui/intConst.h | 2 +- src/gui/intro.cpp | 2 +- src/gui/introTune.h | 2 +- src/gui/log.cpp | 2 +- src/gui/macstuff.h | 2 +- src/gui/mixer.cpp | 2 +- src/gui/newSong.cpp | 2 +- src/gui/orders.cpp | 2 +- src/gui/osc.cpp | 2 +- src/gui/patManager.cpp | 2 +- src/gui/pattern.cpp | 2 +- src/gui/piano.cpp | 2 +- src/gui/plot_nolerp.cpp | 2 +- src/gui/plot_nolerp.h | 2 +- src/gui/presets.cpp | 2 +- src/gui/regView.cpp | 2 +- src/gui/render.cpp | 2 +- src/gui/render/abstract.cpp | 2 +- src/gui/render/renderDX11.cpp | 2 +- src/gui/render/renderDX11.h | 2 +- src/gui/render/renderGL.cpp | 2 +- src/gui/render/renderGL.h | 2 +- src/gui/render/renderSDL.cpp | 2 +- src/gui/render/renderSDL.h | 2 +- src/gui/sampleEdit.cpp | 2 +- src/gui/sampleUtil.h | 2 +- src/gui/scaling.cpp | 2 +- src/gui/scaling.h | 2 +- src/gui/settings.cpp | 2 +- src/gui/songInfo.cpp | 2 +- src/gui/songNotes.cpp | 2 +- src/gui/speed.cpp | 2 +- src/gui/spoiler.cpp | 2 +- src/gui/stats.cpp | 2 +- src/gui/sysConf.cpp | 2 +- src/gui/sysManager.cpp | 2 +- src/gui/sysPartNumber.cpp | 2 +- src/gui/sysPicker.cpp | 2 +- src/gui/tutorial.cpp | 2 +- src/gui/util.cpp | 2 +- src/gui/util.h | 2 +- src/gui/volMeter.cpp | 2 +- src/gui/waveEdit.cpp | 2 +- src/gui/xyOsc.cpp | 2 +- src/log.cpp | 2 +- src/main.cpp | 4 ++-- src/pch.cpp | 2 +- src/pch.h | 2 +- src/ta-log.h | 2 +- src/ta-utils.h | 2 +- src/utfutils.cpp | 2 +- src/utfutils.h | 2 +- src/winMain.cpp | 2 +- 306 files changed, 308 insertions(+), 308 deletions(-) diff --git a/README.md b/README.md index f7de671ef..5abdc8127 100644 --- a/README.md +++ b/README.md @@ -361,7 +361,7 @@ you should only save as .dmf if you're really sure, because the DefleMask format --- # footnotes -copyright (C) 2021-2023 tildearrow and contributors. +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. diff --git a/doc/README.md b/doc/README.md index 9870cb925..be719e561 100644 --- a/doc/README.md +++ b/doc/README.md @@ -27,7 +27,7 @@ the index follows. ## information -copyright © 2023 tildearrow and other authors. +copyright © 2024 tildearrow and other authors. this documentation is under the [Creative Commons Attribution 3.0 Unported](https://creativecommons.org/licenses/by/3.0/) license. 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. diff --git a/res/docpdf/make_paper.py b/res/docpdf/make_paper.py index fed4e9fee..72708a436 100644 --- a/res/docpdf/make_paper.py +++ b/res/docpdf/make_paper.py @@ -344,7 +344,7 @@ if __name__ == "__main__":
  • tildearrow
  • special thanks to ZoomTen for providing tools which assisted in the production of this document!

    -

    copyright © 2023 tildearrow and other authors.

    +

    copyright © 2024 tildearrow and other authors.

    this documentation is under the Creative Commons Attribution 3.0 Unported license.

    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.

    this documentation is provided as-is and without warranty of any kind.

    diff --git a/res/releaseReadme/stable-linux.txt b/res/releaseReadme/stable-linux.txt index 979720a83..be3b0078a 100644 --- a/res/releaseReadme/stable-linux.txt +++ b/res/releaseReadme/stable-linux.txt @@ -22,7 +22,7 @@ if you find issues (e.g. bugs or annoyances), report them. links below. # notes -copyright (C) 2021-2023 tildearrow and contributors. +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. diff --git a/res/releaseReadme/stable-mac.txt b/res/releaseReadme/stable-mac.txt index d2a50cd89..63bad6b0d 100644 --- a/res/releaseReadme/stable-mac.txt +++ b/res/releaseReadme/stable-mac.txt @@ -32,7 +32,7 @@ if you find issues (e.g. bugs or annoyances), report them. links below. # notes -copyright (C) 2021-2023 tildearrow and contributors. +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. diff --git a/res/releaseReadme/stable-win.txt b/res/releaseReadme/stable-win.txt index 562037c2c..c691defec 100644 --- a/res/releaseReadme/stable-win.txt +++ b/res/releaseReadme/stable-win.txt @@ -22,7 +22,7 @@ if you find issues (e.g. bugs or annoyances), report them. links below. # notes -copyright (C) 2021-2023 tildearrow and contributors. +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. diff --git a/src/audio/abstract.cpp b/src/audio/abstract.cpp index e360d1cb1..f80116e1c 100644 --- a/src/audio/abstract.cpp +++ b/src/audio/abstract.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/audio/jack.cpp b/src/audio/jack.cpp index 64c106c54..8e6ee56f0 100644 --- a/src/audio/jack.cpp +++ b/src/audio/jack.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/audio/jack.h b/src/audio/jack.h index 41d76824b..2742ef877 100644 --- a/src/audio/jack.h +++ b/src/audio/jack.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/audio/midi.cpp b/src/audio/midi.cpp index fa3faf1f4..bf40f2a9c 100644 --- a/src/audio/midi.cpp +++ b/src/audio/midi.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/audio/pa.cpp b/src/audio/pa.cpp index 3ae960860..ec1c40a9b 100644 --- a/src/audio/pa.cpp +++ b/src/audio/pa.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/audio/pa.h b/src/audio/pa.h index 846fc7087..30922c7d2 100644 --- a/src/audio/pa.h +++ b/src/audio/pa.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/audio/rtmidi.cpp b/src/audio/rtmidi.cpp index ea1903c36..51d70a157 100644 --- a/src/audio/rtmidi.cpp +++ b/src/audio/rtmidi.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/audio/rtmidi.h b/src/audio/rtmidi.h index 33a71af56..5ebbf1d9f 100644 --- a/src/audio/rtmidi.h +++ b/src/audio/rtmidi.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/audio/sdlAudio.cpp b/src/audio/sdlAudio.cpp index e01f073c8..8f074a5aa 100644 --- a/src/audio/sdlAudio.cpp +++ b/src/audio/sdlAudio.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/audio/sdlAudio.h b/src/audio/sdlAudio.h index a827b059d..b3b0a1843 100644 --- a/src/audio/sdlAudio.h +++ b/src/audio/sdlAudio.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/audio/taAudio.h b/src/audio/taAudio.h index 0b6f530c6..c57037605 100644 --- a/src/audio/taAudio.h +++ b/src/audio/taAudio.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/baseutils.cpp b/src/baseutils.cpp index 787496c7b..957d15b60 100644 --- a/src/baseutils.cpp +++ b/src/baseutils.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/baseutils.h b/src/baseutils.h index 7e3d8e8eb..292c57626 100644 --- a/src/baseutils.h +++ b/src/baseutils.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 546c5000f..a2e9a1ca9 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/cli/cli.h b/src/cli/cli.h index b77df2e8a..fbb88567a 100644 --- a/src/cli/cli.h +++ b/src/cli/cli.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/bsr.h b/src/engine/bsr.h index ac3da44d9..437b02870 100644 --- a/src/engine/bsr.h +++ b/src/engine/bsr.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/chipUtils.h b/src/engine/chipUtils.h index 4ddc0738d..d7cef0e28 100644 --- a/src/engine/chipUtils.h +++ b/src/engine/chipUtils.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/cmdStream.cpp b/src/engine/cmdStream.cpp index 7b1a6033d..841524f46 100644 --- a/src/engine/cmdStream.cpp +++ b/src/engine/cmdStream.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/cmdStream.h b/src/engine/cmdStream.h index 0c660b7af..cd0a786b7 100644 --- a/src/engine/cmdStream.h +++ b/src/engine/cmdStream.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/cmdStreamOps.cpp b/src/engine/cmdStreamOps.cpp index bff6bc66a..b3be6dddf 100644 --- a/src/engine/cmdStreamOps.cpp +++ b/src/engine/cmdStreamOps.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/config.cpp b/src/engine/config.cpp index ef8bf3a0e..71edc775b 100644 --- a/src/engine/config.cpp +++ b/src/engine/config.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/config.h b/src/engine/config.h index b9f5e43e1..b8d91a4ef 100644 --- a/src/engine/config.h +++ b/src/engine/config.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/configEngine.cpp b/src/engine/configEngine.cpp index f226d1364..bc12fd417 100644 --- a/src/engine/configEngine.cpp +++ b/src/engine/configEngine.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/dataErrors.h b/src/engine/dataErrors.h index e6d8fdc42..c5f0fffcc 100644 --- a/src/engine/dataErrors.h +++ b/src/engine/dataErrors.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/defines.h b/src/engine/defines.h index 9564f418d..8d9a501db 100644 --- a/src/engine/defines.h +++ b/src/engine/defines.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index f6ce9f525..fef7dd78f 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/dispatchContainer.cpp b/src/engine/dispatchContainer.cpp index 126c84571..ffcbe91eb 100644 --- a/src/engine/dispatchContainer.cpp +++ b/src/engine/dispatchContainer.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/effect.h b/src/engine/effect.h index 5c735d31d..c1e399b39 100644 --- a/src/engine/effect.h +++ b/src/engine/effect.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/effect/abstract.cpp b/src/engine/effect/abstract.cpp index 9be95daa0..fd31353ef 100644 --- a/src/engine/effect/abstract.cpp +++ b/src/engine/effect/abstract.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/effect/dummy.cpp b/src/engine/effect/dummy.cpp index 13df4f3f5..4b6003ecd 100644 --- a/src/engine/effect/dummy.cpp +++ b/src/engine/effect/dummy.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/effect/dummy.h b/src/engine/effect/dummy.h index c8a42919d..77ab20d3f 100644 --- a/src/engine/effect/dummy.h +++ b/src/engine/effect/dummy.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/effectContainer.cpp b/src/engine/effectContainer.cpp index d51ddfe57..7c6908e1f 100644 --- a/src/engine/effectContainer.cpp +++ b/src/engine/effectContainer.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 1ebab4059..809dc87b4 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/engine.h b/src/engine/engine.h index b12bc926c..3bf2a9826 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/export.cpp b/src/engine/export.cpp index 141736d9e..2ea35327f 100644 --- a/src/engine/export.cpp +++ b/src/engine/export.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/export.h b/src/engine/export.h index 3a51ee236..d8e1878f1 100644 --- a/src/engine/export.h +++ b/src/engine/export.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/export/abstract.cpp b/src/engine/export/abstract.cpp index ce07519c0..bd39e3aa0 100644 --- a/src/engine/export/abstract.cpp +++ b/src/engine/export/abstract.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/export/amigaValidation.cpp b/src/engine/export/amigaValidation.cpp index e1aa4dfdb..a613ee422 100644 --- a/src/engine/export/amigaValidation.cpp +++ b/src/engine/export/amigaValidation.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/export/amigaValidation.h b/src/engine/export/amigaValidation.h index 94d5eabbe..11a4ecd48 100644 --- a/src/engine/export/amigaValidation.h +++ b/src/engine/export/amigaValidation.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index 8cfbc292e..9faf0923d 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/fileOpsIns.cpp b/src/engine/fileOpsIns.cpp index 8236ebe0f..817c28463 100644 --- a/src/engine/fileOpsIns.cpp +++ b/src/engine/fileOpsIns.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/fileOpsSample.cpp b/src/engine/fileOpsSample.cpp index 55969df33..3c5aa8087 100644 --- a/src/engine/fileOpsSample.cpp +++ b/src/engine/fileOpsSample.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/filter.cpp b/src/engine/filter.cpp index ee325052b..3c81ce777 100644 --- a/src/engine/filter.cpp +++ b/src/engine/filter.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/filter.h b/src/engine/filter.h index 1406ee145..f45e9980f 100644 --- a/src/engine/filter.h +++ b/src/engine/filter.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index b1ea08063..71aaeb012 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 767fdc31f..4304d5526 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index 557777cc8..0599d3966 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/macroInt.h b/src/engine/macroInt.h index 28e605029..4c100562c 100644 --- a/src/engine/macroInt.h +++ b/src/engine/macroInt.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/orders.h b/src/engine/orders.h index 170eb4ad4..771ec982d 100644 --- a/src/engine/orders.h +++ b/src/engine/orders.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/pattern.cpp b/src/engine/pattern.cpp index ea0cca7e0..aec429a51 100644 --- a/src/engine/pattern.cpp +++ b/src/engine/pattern.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/pattern.h b/src/engine/pattern.h index 8bb8fa21e..7b46e315f 100644 --- a/src/engine/pattern.h +++ b/src/engine/pattern.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/pitchTable.cpp b/src/engine/pitchTable.cpp index 818a97dce..97a91d1f6 100644 --- a/src/engine/pitchTable.cpp +++ b/src/engine/pitchTable.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index 9886dae37..6da4b3e79 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index a884c21ce..d9a8fca82 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/amiga.h b/src/engine/platform/amiga.h index 903d7bd31..5a60d8658 100644 --- a/src/engine/platform/amiga.h +++ b/src/engine/platform/amiga.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index ab26b5b08..a84259009 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/arcade.h b/src/engine/platform/arcade.h index 39ae3705e..1aadf513c 100644 --- a/src/engine/platform/arcade.h +++ b/src/engine/platform/arcade.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index f8c5bde9e..ed352e982 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ay.h b/src/engine/platform/ay.h index 642ae59cf..480e23f4e 100644 --- a/src/engine/platform/ay.h +++ b/src/engine/platform/ay.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 2199d5ccd..9fd4c1629 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ay8930.h b/src/engine/platform/ay8930.h index 64f8e9318..902c69517 100644 --- a/src/engine/platform/ay8930.h +++ b/src/engine/platform/ay8930.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/bubsyswsg.cpp b/src/engine/platform/bubsyswsg.cpp index 94202de19..1429c55b3 100644 --- a/src/engine/platform/bubsyswsg.cpp +++ b/src/engine/platform/bubsyswsg.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/bubsyswsg.h b/src/engine/platform/bubsyswsg.h index c3891bf69..955b1d029 100644 --- a/src/engine/platform/bubsyswsg.h +++ b/src/engine/platform/bubsyswsg.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/c140.cpp b/src/engine/platform/c140.cpp index 09d08e304..bcfae3773 100644 --- a/src/engine/platform/c140.cpp +++ b/src/engine/platform/c140.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/c140.h b/src/engine/platform/c140.h index c84ab23ff..dbfc0b050 100644 --- a/src/engine/platform/c140.h +++ b/src/engine/platform/c140.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index cf0687d34..3a80a43ef 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/c64.h b/src/engine/platform/c64.h index 5f7882c68..c24ee3159 100644 --- a/src/engine/platform/c64.h +++ b/src/engine/platform/c64.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/dummy.cpp b/src/engine/platform/dummy.cpp index 18fa5ca93..d0723a08d 100644 --- a/src/engine/platform/dummy.cpp +++ b/src/engine/platform/dummy.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/dummy.h b/src/engine/platform/dummy.h index 51a399796..5b54acb85 100644 --- a/src/engine/platform/dummy.h +++ b/src/engine/platform/dummy.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/es5506.cpp b/src/engine/platform/es5506.cpp index 64aca0be5..85c70d17e 100644 --- a/src/engine/platform/es5506.cpp +++ b/src/engine/platform/es5506.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/es5506.h b/src/engine/platform/es5506.h index 6bac20c37..b51ee9f2c 100644 --- a/src/engine/platform/es5506.h +++ b/src/engine/platform/es5506.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 46ea1bb90..0df388084 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/esfm.h b/src/engine/platform/esfm.h index 36768af8a..d7a5a574d 100644 --- a/src/engine/platform/esfm.h +++ b/src/engine/platform/esfm.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/fds.cpp b/src/engine/platform/fds.cpp index ea903cede..66b713ca2 100644 --- a/src/engine/platform/fds.cpp +++ b/src/engine/platform/fds.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/fds.h b/src/engine/platform/fds.h index 5eda2c12f..49b52d063 100644 --- a/src/engine/platform/fds.h +++ b/src/engine/platform/fds.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/fmshared_OPM.h b/src/engine/platform/fmshared_OPM.h index 2002db333..41be72567 100644 --- a/src/engine/platform/fmshared_OPM.h +++ b/src/engine/platform/fmshared_OPM.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/fmshared_OPN.h b/src/engine/platform/fmshared_OPN.h index e7d06c7f5..5671e136e 100644 --- a/src/engine/platform/fmshared_OPN.h +++ b/src/engine/platform/fmshared_OPN.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/fmsharedbase.h b/src/engine/platform/fmsharedbase.h index f20292a0d..63669002b 100644 --- a/src/engine/platform/fmsharedbase.h +++ b/src/engine/platform/fmsharedbase.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ga20.cpp b/src/engine/platform/ga20.cpp index cc796bd61..af7fbed90 100644 --- a/src/engine/platform/ga20.cpp +++ b/src/engine/platform/ga20.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ga20.h b/src/engine/platform/ga20.h index 3831d32c2..995a7cc15 100644 --- a/src/engine/platform/ga20.h +++ b/src/engine/platform/ga20.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index 741fe2c3c..c1af65415 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/gb.h b/src/engine/platform/gb.h index 0e7fb52d3..6fe094020 100644 --- a/src/engine/platform/gb.h +++ b/src/engine/platform/gb.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 4d8d95f8b..393b0c07f 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/genesis.h b/src/engine/platform/genesis.h index a12e6625d..a24cabb52 100644 --- a/src/engine/platform/genesis.h +++ b/src/engine/platform/genesis.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/genesisext.cpp b/src/engine/platform/genesisext.cpp index 0097f763f..bdfb8bfc6 100644 --- a/src/engine/platform/genesisext.cpp +++ b/src/engine/platform/genesisext.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/genesisext.h b/src/engine/platform/genesisext.h index d6ab86924..caf752e02 100644 --- a/src/engine/platform/genesisext.h +++ b/src/engine/platform/genesisext.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/k007232.cpp b/src/engine/platform/k007232.cpp index b2d92e2fc..7d84e6d35 100644 --- a/src/engine/platform/k007232.cpp +++ b/src/engine/platform/k007232.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/k007232.h b/src/engine/platform/k007232.h index 5eb379985..379d41106 100644 --- a/src/engine/platform/k007232.h +++ b/src/engine/platform/k007232.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index e05b13a70..12128308c 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/k053260.h b/src/engine/platform/k053260.h index 27b2a7910..4f1afea2d 100644 --- a/src/engine/platform/k053260.h +++ b/src/engine/platform/k053260.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/lynx.cpp b/src/engine/platform/lynx.cpp index f06de0415..722b139cc 100644 --- a/src/engine/platform/lynx.cpp +++ b/src/engine/platform/lynx.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/lynx.h b/src/engine/platform/lynx.h index e081f7ff7..1ce093187 100644 --- a/src/engine/platform/lynx.h +++ b/src/engine/platform/lynx.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/mmc5.cpp b/src/engine/platform/mmc5.cpp index e9ac6be9c..ad3e44431 100644 --- a/src/engine/platform/mmc5.cpp +++ b/src/engine/platform/mmc5.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/mmc5.h b/src/engine/platform/mmc5.h index 291a1baf4..1f95d6161 100644 --- a/src/engine/platform/mmc5.h +++ b/src/engine/platform/mmc5.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/msm5232.cpp b/src/engine/platform/msm5232.cpp index 997ab607e..d1a24ba56 100644 --- a/src/engine/platform/msm5232.cpp +++ b/src/engine/platform/msm5232.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/msm5232.h b/src/engine/platform/msm5232.h index efa5c919c..ec7739a30 100644 --- a/src/engine/platform/msm5232.h +++ b/src/engine/platform/msm5232.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/msm6258.cpp b/src/engine/platform/msm6258.cpp index c5d5c2c0e..d60535e91 100644 --- a/src/engine/platform/msm6258.cpp +++ b/src/engine/platform/msm6258.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/msm6258.h b/src/engine/platform/msm6258.h index 2a4c3512b..c31c083c3 100644 --- a/src/engine/platform/msm6258.h +++ b/src/engine/platform/msm6258.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/msm6295.cpp b/src/engine/platform/msm6295.cpp index 6fba09fd1..d770a845e 100644 --- a/src/engine/platform/msm6295.cpp +++ b/src/engine/platform/msm6295.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/msm6295.h b/src/engine/platform/msm6295.h index 19815f0da..d8778926a 100644 --- a/src/engine/platform/msm6295.h +++ b/src/engine/platform/msm6295.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/n163.cpp b/src/engine/platform/n163.cpp index 1d6596f12..f96d13216 100644 --- a/src/engine/platform/n163.cpp +++ b/src/engine/platform/n163.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/n163.h b/src/engine/platform/n163.h index e4d5b24d2..648a7af24 100644 --- a/src/engine/platform/n163.h +++ b/src/engine/platform/n163.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/namcowsg.cpp b/src/engine/platform/namcowsg.cpp index 223216f66..abc762de7 100644 --- a/src/engine/platform/namcowsg.cpp +++ b/src/engine/platform/namcowsg.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/namcowsg.h b/src/engine/platform/namcowsg.h index ab4451705..f023e8ba7 100644 --- a/src/engine/platform/namcowsg.h +++ b/src/engine/platform/namcowsg.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 32319fcbb..e1e883673 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/nes.h b/src/engine/platform/nes.h index 48ed6a1b8..43377fee2 100644 --- a/src/engine/platform/nes.h +++ b/src/engine/platform/nes.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index c68271743..b64d4f020 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/opl.h b/src/engine/platform/opl.h index bef02db5e..15f9e41c1 100644 --- a/src/engine/platform/opl.h +++ b/src/engine/platform/opl.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/oplAInterface.cpp b/src/engine/platform/oplAInterface.cpp index 60e1db15b..37ebda7f0 100644 --- a/src/engine/platform/oplAInterface.cpp +++ b/src/engine/platform/oplAInterface.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index 9228568ef..b9aaed317 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/opll.h b/src/engine/platform/opll.h index 70ece9c1e..30273a5ef 100644 --- a/src/engine/platform/opll.h +++ b/src/engine/platform/opll.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index 1cff48278..8bff7f77e 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pce.h b/src/engine/platform/pce.h index 591c94cef..ceba204be 100644 --- a/src/engine/platform/pce.h +++ b/src/engine/platform/pce.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pcmdac.cpp b/src/engine/platform/pcmdac.cpp index adc8770ee..e8930e579 100644 --- a/src/engine/platform/pcmdac.cpp +++ b/src/engine/platform/pcmdac.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pcmdac.h b/src/engine/platform/pcmdac.h index 17513690a..91befa623 100644 --- a/src/engine/platform/pcmdac.h +++ b/src/engine/platform/pcmdac.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pcspkr.cpp b/src/engine/platform/pcspkr.cpp index bd49c9e68..fcc812986 100644 --- a/src/engine/platform/pcspkr.cpp +++ b/src/engine/platform/pcspkr.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pcspkr.h b/src/engine/platform/pcspkr.h index 758111259..3a5a8067f 100644 --- a/src/engine/platform/pcspkr.h +++ b/src/engine/platform/pcspkr.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pet.cpp b/src/engine/platform/pet.cpp index e7f135759..e24fa048b 100644 --- a/src/engine/platform/pet.cpp +++ b/src/engine/platform/pet.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pet.h b/src/engine/platform/pet.h index 771d5cbb5..72bdfea0d 100644 --- a/src/engine/platform/pet.h +++ b/src/engine/platform/pet.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pokemini.cpp b/src/engine/platform/pokemini.cpp index aa8adc0d7..c441b2db3 100644 --- a/src/engine/platform/pokemini.cpp +++ b/src/engine/platform/pokemini.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pokemini.h b/src/engine/platform/pokemini.h index 4e14bf572..b0f8c8c52 100644 --- a/src/engine/platform/pokemini.h +++ b/src/engine/platform/pokemini.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pokey.cpp b/src/engine/platform/pokey.cpp index da2ec7030..d9db9c1d3 100644 --- a/src/engine/platform/pokey.cpp +++ b/src/engine/platform/pokey.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pokey.h b/src/engine/platform/pokey.h index 35bc595f3..6407c0778 100644 --- a/src/engine/platform/pokey.h +++ b/src/engine/platform/pokey.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pong.cpp b/src/engine/platform/pong.cpp index 7d478b83b..e2e09981e 100644 --- a/src/engine/platform/pong.cpp +++ b/src/engine/platform/pong.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pong.h b/src/engine/platform/pong.h index 4fb13477c..2bde92d9b 100644 --- a/src/engine/platform/pong.h +++ b/src/engine/platform/pong.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pv1000.cpp b/src/engine/platform/pv1000.cpp index 0d7d728d0..d6e488a0b 100644 --- a/src/engine/platform/pv1000.cpp +++ b/src/engine/platform/pv1000.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/pv1000.h b/src/engine/platform/pv1000.h index 740f16c4b..e4ce1da42 100644 --- a/src/engine/platform/pv1000.h +++ b/src/engine/platform/pv1000.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/qsound.cpp b/src/engine/platform/qsound.cpp index 95a455e3f..838abecda 100644 --- a/src/engine/platform/qsound.cpp +++ b/src/engine/platform/qsound.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/qsound.h b/src/engine/platform/qsound.h index 6daccc120..929411402 100644 --- a/src/engine/platform/qsound.h +++ b/src/engine/platform/qsound.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/rf5c68.cpp b/src/engine/platform/rf5c68.cpp index c183cd505..b83c8d540 100644 --- a/src/engine/platform/rf5c68.cpp +++ b/src/engine/platform/rf5c68.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/rf5c68.h b/src/engine/platform/rf5c68.h index 9c706ccd5..3ae081017 100644 --- a/src/engine/platform/rf5c68.h +++ b/src/engine/platform/rf5c68.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/saa.cpp b/src/engine/platform/saa.cpp index b1ba48826..d3bdfc875 100644 --- a/src/engine/platform/saa.cpp +++ b/src/engine/platform/saa.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/saa.h b/src/engine/platform/saa.h index 339799d2e..586f180e7 100644 --- a/src/engine/platform/saa.h +++ b/src/engine/platform/saa.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/scc.cpp b/src/engine/platform/scc.cpp index cd97ff309..251e1e3f6 100644 --- a/src/engine/platform/scc.cpp +++ b/src/engine/platform/scc.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/scc.h b/src/engine/platform/scc.h index f075753aa..f7aad5fb1 100644 --- a/src/engine/platform/scc.h +++ b/src/engine/platform/scc.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index f81dbc487..975052073 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/segapcm.h b/src/engine/platform/segapcm.h index b03459f5d..192c47be0 100644 --- a/src/engine/platform/segapcm.h +++ b/src/engine/platform/segapcm.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/sm8521.cpp b/src/engine/platform/sm8521.cpp index 52c3442ce..f1ec91e91 100644 --- a/src/engine/platform/sm8521.cpp +++ b/src/engine/platform/sm8521.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/sm8521.h b/src/engine/platform/sm8521.h index f9faeebda..40baf36df 100644 --- a/src/engine/platform/sm8521.h +++ b/src/engine/platform/sm8521.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 0b5e6183e..57cd02aea 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h index 092010a56..199a87d87 100644 --- a/src/engine/platform/sms.h +++ b/src/engine/platform/sms.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/snes.cpp b/src/engine/platform/snes.cpp index 0b6bdbbc9..0b7860b66 100644 --- a/src/engine/platform/snes.cpp +++ b/src/engine/platform/snes.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/snes.h b/src/engine/platform/snes.h index 8c48c6c72..315f5a89b 100644 --- a/src/engine/platform/snes.h +++ b/src/engine/platform/snes.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index 5a88618f3..0a3f22545 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/su.h b/src/engine/platform/su.h index 7062cbc8b..f39a59cc7 100644 --- a/src/engine/platform/su.h +++ b/src/engine/platform/su.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index 25260a44c..d50e2dddd 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/swan.h b/src/engine/platform/swan.h index 4dab6eb7c..aa5f9dd95 100644 --- a/src/engine/platform/swan.h +++ b/src/engine/platform/swan.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/t6w28.cpp b/src/engine/platform/t6w28.cpp index 8fd0cb2ee..0c0e388cf 100644 --- a/src/engine/platform/t6w28.cpp +++ b/src/engine/platform/t6w28.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/t6w28.h b/src/engine/platform/t6w28.h index eae0f92f9..e6ddeb13c 100644 --- a/src/engine/platform/t6w28.h +++ b/src/engine/platform/t6w28.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ted.cpp b/src/engine/platform/ted.cpp index a1e431bb4..3b9c61aab 100644 --- a/src/engine/platform/ted.cpp +++ b/src/engine/platform/ted.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ted.h b/src/engine/platform/ted.h index a2bd1d636..e6b27b2e7 100644 --- a/src/engine/platform/ted.h +++ b/src/engine/platform/ted.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/tia.cpp b/src/engine/platform/tia.cpp index 86038216a..50bb82d64 100644 --- a/src/engine/platform/tia.cpp +++ b/src/engine/platform/tia.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/tia.h b/src/engine/platform/tia.h index 4e7420b79..fbc7dacfe 100644 --- a/src/engine/platform/tia.h +++ b/src/engine/platform/tia.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/tx81z.cpp b/src/engine/platform/tx81z.cpp index f677429ff..40bcd9a39 100644 --- a/src/engine/platform/tx81z.cpp +++ b/src/engine/platform/tx81z.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/tx81z.h b/src/engine/platform/tx81z.h index 93da1cd7a..8c97ed22e 100644 --- a/src/engine/platform/tx81z.h +++ b/src/engine/platform/tx81z.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/vb.cpp b/src/engine/platform/vb.cpp index c94867fa7..28651b7d3 100644 --- a/src/engine/platform/vb.cpp +++ b/src/engine/platform/vb.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/vb.h b/src/engine/platform/vb.h index 940491f60..a270c1c23 100644 --- a/src/engine/platform/vb.h +++ b/src/engine/platform/vb.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/vera.cpp b/src/engine/platform/vera.cpp index 38b166bd1..830cd2ece 100644 --- a/src/engine/platform/vera.cpp +++ b/src/engine/platform/vera.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/vera.h b/src/engine/platform/vera.h index 992bb0798..d23ac8100 100644 --- a/src/engine/platform/vera.h +++ b/src/engine/platform/vera.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/vic20.cpp b/src/engine/platform/vic20.cpp index 05705f7c7..8d12ce24e 100644 --- a/src/engine/platform/vic20.cpp +++ b/src/engine/platform/vic20.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/vic20.h b/src/engine/platform/vic20.h index b1c1533ab..962c1ef7e 100644 --- a/src/engine/platform/vic20.h +++ b/src/engine/platform/vic20.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/vrc6.cpp b/src/engine/platform/vrc6.cpp index 96088d937..0610cb2fa 100644 --- a/src/engine/platform/vrc6.cpp +++ b/src/engine/platform/vrc6.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/vrc6.h b/src/engine/platform/vrc6.h index f20e0d39c..5a02a350a 100644 --- a/src/engine/platform/vrc6.h +++ b/src/engine/platform/vrc6.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index 7015fa517..70cd77f53 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/x1_010.h b/src/engine/platform/x1_010.h index 632d95424..f4a815455 100644 --- a/src/engine/platform/x1_010.h +++ b/src/engine/platform/x1_010.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index 913f84045..9f6f54f50 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2203.h b/src/engine/platform/ym2203.h index fb96a2b60..334d8f650 100644 --- a/src/engine/platform/ym2203.h +++ b/src/engine/platform/ym2203.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2203ext.cpp b/src/engine/platform/ym2203ext.cpp index bcb84e19b..c2587f53c 100644 --- a/src/engine/platform/ym2203ext.cpp +++ b/src/engine/platform/ym2203ext.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2203ext.h b/src/engine/platform/ym2203ext.h index f0e468158..c735e196b 100644 --- a/src/engine/platform/ym2203ext.h +++ b/src/engine/platform/ym2203ext.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 9ec5518b0..dcda75982 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2608.h b/src/engine/platform/ym2608.h index e7a8bc6e5..2b51da1d6 100644 --- a/src/engine/platform/ym2608.h +++ b/src/engine/platform/ym2608.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2608Interface.cpp b/src/engine/platform/ym2608Interface.cpp index d357caa23..1422f2d26 100644 --- a/src/engine/platform/ym2608Interface.cpp +++ b/src/engine/platform/ym2608Interface.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2608ext.cpp b/src/engine/platform/ym2608ext.cpp index 589bd542a..c2428993c 100644 --- a/src/engine/platform/ym2608ext.cpp +++ b/src/engine/platform/ym2608ext.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2608ext.h b/src/engine/platform/ym2608ext.h index 159a6c807..52a3619ad 100644 --- a/src/engine/platform/ym2608ext.h +++ b/src/engine/platform/ym2608ext.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 01d5a3bb6..50cccd3a3 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2610.h b/src/engine/platform/ym2610.h index 99b1e73b7..0df5573be 100644 --- a/src/engine/platform/ym2610.h +++ b/src/engine/platform/ym2610.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2610Interface.cpp b/src/engine/platform/ym2610Interface.cpp index 916cab0ad..da8239744 100644 --- a/src/engine/platform/ym2610Interface.cpp +++ b/src/engine/platform/ym2610Interface.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 1937abd62..9d83c1a0e 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2610b.h b/src/engine/platform/ym2610b.h index 80c040e77..6d46dedb1 100644 --- a/src/engine/platform/ym2610b.h +++ b/src/engine/platform/ym2610b.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2610bext.cpp b/src/engine/platform/ym2610bext.cpp index c0b0282b2..09efc620c 100644 --- a/src/engine/platform/ym2610bext.cpp +++ b/src/engine/platform/ym2610bext.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2610bext.h b/src/engine/platform/ym2610bext.h index e7feaf3c2..a215507e9 100644 --- a/src/engine/platform/ym2610bext.h +++ b/src/engine/platform/ym2610bext.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2610ext.cpp b/src/engine/platform/ym2610ext.cpp index 063fd5c36..c468c02e7 100644 --- a/src/engine/platform/ym2610ext.cpp +++ b/src/engine/platform/ym2610ext.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2610ext.h b/src/engine/platform/ym2610ext.h index 666f0d40f..256235111 100644 --- a/src/engine/platform/ym2610ext.h +++ b/src/engine/platform/ym2610ext.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ym2610shared.h b/src/engine/platform/ym2610shared.h index 36db018f2..0c96e5447 100644 --- a/src/engine/platform/ym2610shared.h +++ b/src/engine/platform/ym2610shared.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ymz280b.cpp b/src/engine/platform/ymz280b.cpp index 9a8b45e9d..02b701b20 100644 --- a/src/engine/platform/ymz280b.cpp +++ b/src/engine/platform/ymz280b.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/ymz280b.h b/src/engine/platform/ymz280b.h index 913b8ec6e..703cef6c8 100644 --- a/src/engine/platform/ymz280b.h +++ b/src/engine/platform/ymz280b.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/zxbeeper.cpp b/src/engine/platform/zxbeeper.cpp index 3592c049b..7e48662c8 100644 --- a/src/engine/platform/zxbeeper.cpp +++ b/src/engine/platform/zxbeeper.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/zxbeeper.h b/src/engine/platform/zxbeeper.h index 9bd3678a8..8fe97f8ca 100644 --- a/src/engine/platform/zxbeeper.h +++ b/src/engine/platform/zxbeeper.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/zxbeeperquadtone.cpp b/src/engine/platform/zxbeeperquadtone.cpp index 3be196ad0..dc93c2455 100644 --- a/src/engine/platform/zxbeeperquadtone.cpp +++ b/src/engine/platform/zxbeeperquadtone.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/platform/zxbeeperquadtone.h b/src/engine/platform/zxbeeperquadtone.h index 8291f8646..4efd66c07 100644 --- a/src/engine/platform/zxbeeperquadtone.h +++ b/src/engine/platform/zxbeeperquadtone.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index efede06a0..357e43361 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/safeReader.cpp b/src/engine/safeReader.cpp index 5ac416e27..09c012a5f 100644 --- a/src/engine/safeReader.cpp +++ b/src/engine/safeReader.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/safeReader.h b/src/engine/safeReader.h index 8fd4d105e..7ab5e6b81 100644 --- a/src/engine/safeReader.h +++ b/src/engine/safeReader.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/safeWriter.cpp b/src/engine/safeWriter.cpp index acdf9ad6b..3f62569ac 100644 --- a/src/engine/safeWriter.cpp +++ b/src/engine/safeWriter.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/safeWriter.h b/src/engine/safeWriter.h index 28a3d9b91..640e78c47 100644 --- a/src/engine/safeWriter.h +++ b/src/engine/safeWriter.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/sample.cpp b/src/engine/sample.cpp index 4332503cd..bb8a21d3f 100644 --- a/src/engine/sample.cpp +++ b/src/engine/sample.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/sample.h b/src/engine/sample.h index 253fe347c..63d219259 100644 --- a/src/engine/sample.h +++ b/src/engine/sample.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/sfWrapper.cpp b/src/engine/sfWrapper.cpp index 62ddf949f..814f9c00f 100644 --- a/src/engine/sfWrapper.cpp +++ b/src/engine/sfWrapper.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/sfWrapper.h b/src/engine/sfWrapper.h index e4746b530..c32c8ba19 100644 --- a/src/engine/sfWrapper.h +++ b/src/engine/sfWrapper.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/song.cpp b/src/engine/song.cpp index 828f0a1bc..70d625597 100644 --- a/src/engine/song.cpp +++ b/src/engine/song.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/song.h b/src/engine/song.h index 3cb645b3e..6f5ab68f5 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index 792b731c3..0da85e855 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/vgmOps.cpp b/src/engine/vgmOps.cpp index c8c6cef79..5e3ad32a1 100644 --- a/src/engine/vgmOps.cpp +++ b/src/engine/vgmOps.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/wavOps.cpp b/src/engine/wavOps.cpp index 7c89dd710..edf4a8885 100644 --- a/src/engine/wavOps.cpp +++ b/src/engine/wavOps.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/waveSynth.cpp b/src/engine/waveSynth.cpp index 6fe34f261..5ef9899b3 100644 --- a/src/engine/waveSynth.cpp +++ b/src/engine/waveSynth.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/waveSynth.h b/src/engine/waveSynth.h index 21b6055ff..65046eb60 100644 --- a/src/engine/waveSynth.h +++ b/src/engine/waveSynth.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/wavetable.cpp b/src/engine/wavetable.cpp index a14c28bbe..00e2d1d2d 100644 --- a/src/engine/wavetable.cpp +++ b/src/engine/wavetable.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/wavetable.h b/src/engine/wavetable.h index 52405082e..a7085527d 100644 --- a/src/engine/wavetable.h +++ b/src/engine/wavetable.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/winStuff.cpp b/src/engine/winStuff.cpp index 4452a5143..83eec6c08 100644 --- a/src/engine/winStuff.cpp +++ b/src/engine/winStuff.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/winStuff.h b/src/engine/winStuff.h index a569f6a09..105f93f69 100644 --- a/src/engine/winStuff.h +++ b/src/engine/winStuff.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/workPool.cpp b/src/engine/workPool.cpp index 60d580acf..b7372f082 100644 --- a/src/engine/workPool.cpp +++ b/src/engine/workPool.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/workPool.h b/src/engine/workPool.h index ec12843aa..48d1b96e0 100644 --- a/src/engine/workPool.h +++ b/src/engine/workPool.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/zsm.cpp b/src/engine/zsm.cpp index 03d294638..87dbde8d2 100644 --- a/src/engine/zsm.cpp +++ b/src/engine/zsm.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/zsm.h b/src/engine/zsm.h index 79b8b116c..d1fd8ec04 100644 --- a/src/engine/zsm.h +++ b/src/engine/zsm.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/engine/zsmOps.cpp b/src/engine/zsmOps.cpp index 3c72da663..a2f9385ba 100644 --- a/src/engine/zsmOps.cpp +++ b/src/engine/zsmOps.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/fileutils.cpp b/src/fileutils.cpp index ede4054c8..eca6bf3b7 100644 --- a/src/fileutils.cpp +++ b/src/fileutils.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/fileutils.h b/src/fileutils.h index 38b5732be..e35c9cfbf 100644 --- a/src/fileutils.h +++ b/src/fileutils.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/fixedQueue.h b/src/fixedQueue.h index 4e3379622..68f883edc 100644 --- a/src/fixedQueue.h +++ b/src/fixedQueue.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/about.cpp b/src/gui/about.cpp index 31b6ed00a..41ea34d7a 100644 --- a/src/gui/about.cpp +++ b/src/gui/about.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 @@ -234,7 +234,7 @@ const char* aboutLine[]={ "Xenium Demoparty", "all members of Deflers of Noice!", "", - "copyright © 2021-2023 tildearrow", + "copyright © 2021-2024 tildearrow", "(and contributors).", "licensed under GPLv2+! see", "LICENSE for more information.", diff --git a/src/gui/actionUtil.h b/src/gui/actionUtil.h index 51fffa002..2987b6262 100644 --- a/src/gui/actionUtil.h +++ b/src/gui/actionUtil.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index f702fdb96..9a4d38af9 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/channels.cpp b/src/gui/channels.cpp index 608604ea8..69ed7385c 100644 --- a/src/gui/channels.cpp +++ b/src/gui/channels.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/clock.cpp b/src/gui/clock.cpp index a44ae13d5..2f4a541c6 100644 --- a/src/gui/clock.cpp +++ b/src/gui/clock.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/compatFlags.cpp b/src/gui/compatFlags.cpp index a11200544..8470179ce 100644 --- a/src/gui/compatFlags.cpp +++ b/src/gui/compatFlags.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/cursor.cpp b/src/gui/cursor.cpp index ca5f51b64..80dcd17f8 100644 --- a/src/gui/cursor.cpp +++ b/src/gui/cursor.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/dataList.cpp b/src/gui/dataList.cpp index b45739dcb..6ae3fb8b7 100644 --- a/src/gui/dataList.cpp +++ b/src/gui/dataList.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/debug.cpp b/src/gui/debug.cpp index df634f1e8..6eceb12a1 100644 --- a/src/gui/debug.cpp +++ b/src/gui/debug.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/debug.h b/src/gui/debug.h index 4ec4cd87c..76c81fb57 100644 --- a/src/gui/debug.h +++ b/src/gui/debug.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/debugWindow.cpp b/src/gui/debugWindow.cpp index 1efde1e09..ce56f470b 100644 --- a/src/gui/debugWindow.cpp +++ b/src/gui/debugWindow.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/doAction.cpp b/src/gui/doAction.cpp index c04f14118..f27f0a09d 100644 --- a/src/gui/doAction.cpp +++ b/src/gui/doAction.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/editControls.cpp b/src/gui/editControls.cpp index 1ce85020d..1a611b264 100644 --- a/src/gui/editControls.cpp +++ b/src/gui/editControls.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/editing.cpp b/src/gui/editing.cpp index 50c92aadf..fd2715bc8 100644 --- a/src/gui/editing.cpp +++ b/src/gui/editing.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/exportOptions.cpp b/src/gui/exportOptions.cpp index 165ba5f95..16dd7eeda 100644 --- a/src/gui/exportOptions.cpp +++ b/src/gui/exportOptions.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/findReplace.cpp b/src/gui/findReplace.cpp index 5e2825231..dd87d5313 100644 --- a/src/gui/findReplace.cpp +++ b/src/gui/findReplace.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/fmPreview.cpp b/src/gui/fmPreview.cpp index 290175e23..525d30339 100644 --- a/src/gui/fmPreview.cpp +++ b/src/gui/fmPreview.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/fonts.cpp b/src/gui/fonts.cpp index 4ab0f6a4c..e7d9c5df9 100644 --- a/src/gui/fonts.cpp +++ b/src/gui/fonts.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/fonts.h b/src/gui/fonts.h index 25e186c07..cbebb8253 100644 --- a/src/gui/fonts.h +++ b/src/gui/fonts.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/gradient.cpp b/src/gui/gradient.cpp index a36768ead..b9ef9e48f 100644 --- a/src/gui/gradient.cpp +++ b/src/gui/gradient.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/grooves.cpp b/src/gui/grooves.cpp index eee8db56e..431cae610 100644 --- a/src/gui/grooves.cpp +++ b/src/gui/grooves.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index a3d2690e5..02cb0beef 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2,7 +2,7 @@ // OK, sorry for inserting the define here but I'm so tired of this extension /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/gui.h b/src/gui/gui.h index b2facc682..ec7520c3e 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/guiConst.cpp b/src/gui/guiConst.cpp index c5fc02311..92247e874 100644 --- a/src/gui/guiConst.cpp +++ b/src/gui/guiConst.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/guiConst.h b/src/gui/guiConst.h index 0695a6013..4456ebd3c 100644 --- a/src/gui/guiConst.h +++ b/src/gui/guiConst.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/image.cpp b/src/gui/image.cpp index a5c7baec3..a31c1dd9f 100644 --- a/src/gui/image.cpp +++ b/src/gui/image.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/image.h b/src/gui/image.h index d4c0bf6a5..39fcf6cf4 100644 --- a/src/gui/image.h +++ b/src/gui/image.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index f125df426..49e7f476c 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/intConst.cpp b/src/gui/intConst.cpp index 741a3ddff..dde39ea34 100644 --- a/src/gui/intConst.cpp +++ b/src/gui/intConst.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/intConst.h b/src/gui/intConst.h index f0b7bc952..26f3b9e8b 100644 --- a/src/gui/intConst.h +++ b/src/gui/intConst.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/intro.cpp b/src/gui/intro.cpp index 0fc1c9600..e87482d9d 100644 --- a/src/gui/intro.cpp +++ b/src/gui/intro.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/introTune.h b/src/gui/introTune.h index 43f44e7a3..eda8c72ee 100644 --- a/src/gui/introTune.h +++ b/src/gui/introTune.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/log.cpp b/src/gui/log.cpp index 0dc56e5de..552259e91 100644 --- a/src/gui/log.cpp +++ b/src/gui/log.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/macstuff.h b/src/gui/macstuff.h index 242abd17f..6fd8247c8 100644 --- a/src/gui/macstuff.h +++ b/src/gui/macstuff.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/mixer.cpp b/src/gui/mixer.cpp index c023445ab..d4ddbfa85 100644 --- a/src/gui/mixer.cpp +++ b/src/gui/mixer.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/newSong.cpp b/src/gui/newSong.cpp index 98c44357c..3fed2da3b 100644 --- a/src/gui/newSong.cpp +++ b/src/gui/newSong.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/orders.cpp b/src/gui/orders.cpp index 4b0ae27d0..f01168e1d 100644 --- a/src/gui/orders.cpp +++ b/src/gui/orders.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/osc.cpp b/src/gui/osc.cpp index 8f8e8add4..d6537373c 100644 --- a/src/gui/osc.cpp +++ b/src/gui/osc.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/patManager.cpp b/src/gui/patManager.cpp index 17dfb91e7..8721ef200 100644 --- a/src/gui/patManager.cpp +++ b/src/gui/patManager.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/pattern.cpp b/src/gui/pattern.cpp index 9e5c6e538..2e4db92cc 100644 --- a/src/gui/pattern.cpp +++ b/src/gui/pattern.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/piano.cpp b/src/gui/piano.cpp index 4e20142c7..d71740cdb 100644 --- a/src/gui/piano.cpp +++ b/src/gui/piano.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/plot_nolerp.cpp b/src/gui/plot_nolerp.cpp index f4d03717d..69361b4d3 100644 --- a/src/gui/plot_nolerp.cpp +++ b/src/gui/plot_nolerp.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/plot_nolerp.h b/src/gui/plot_nolerp.h index fbc66c1eb..cdd5a1df5 100644 --- a/src/gui/plot_nolerp.h +++ b/src/gui/plot_nolerp.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/presets.cpp b/src/gui/presets.cpp index bb07b8078..d1a21cc26 100644 --- a/src/gui/presets.cpp +++ b/src/gui/presets.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/regView.cpp b/src/gui/regView.cpp index 729f17c6e..6ad6c0814 100644 --- a/src/gui/regView.cpp +++ b/src/gui/regView.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 94600246a..f7d004ce9 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/render/abstract.cpp b/src/gui/render/abstract.cpp index cf76ebbb0..a970705de 100644 --- a/src/gui/render/abstract.cpp +++ b/src/gui/render/abstract.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/render/renderDX11.cpp b/src/gui/render/renderDX11.cpp index 26bfd0937..80b877034 100644 --- a/src/gui/render/renderDX11.cpp +++ b/src/gui/render/renderDX11.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/render/renderDX11.h b/src/gui/render/renderDX11.h index 39cc32df8..8348d068f 100644 --- a/src/gui/render/renderDX11.h +++ b/src/gui/render/renderDX11.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/render/renderGL.cpp b/src/gui/render/renderGL.cpp index 38fa4966b..840f3088e 100644 --- a/src/gui/render/renderGL.cpp +++ b/src/gui/render/renderGL.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/render/renderGL.h b/src/gui/render/renderGL.h index 55d399730..da7fa844d 100644 --- a/src/gui/render/renderGL.h +++ b/src/gui/render/renderGL.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/render/renderSDL.cpp b/src/gui/render/renderSDL.cpp index de1e28d3c..2aae041cb 100644 --- a/src/gui/render/renderSDL.cpp +++ b/src/gui/render/renderSDL.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/render/renderSDL.h b/src/gui/render/renderSDL.h index f19135841..ba68f5366 100644 --- a/src/gui/render/renderSDL.h +++ b/src/gui/render/renderSDL.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/sampleEdit.cpp b/src/gui/sampleEdit.cpp index 3ab8fe7a3..d00852c8b 100644 --- a/src/gui/sampleEdit.cpp +++ b/src/gui/sampleEdit.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/sampleUtil.h b/src/gui/sampleUtil.h index bdef166f4..bb1a254ae 100644 --- a/src/gui/sampleUtil.h +++ b/src/gui/sampleUtil.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/scaling.cpp b/src/gui/scaling.cpp index 6df1db087..f680e91dd 100644 --- a/src/gui/scaling.cpp +++ b/src/gui/scaling.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/scaling.h b/src/gui/scaling.h index be2c9f035..72c4b4cfb 100644 --- a/src/gui/scaling.h +++ b/src/gui/scaling.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index c4185e038..50730c857 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/songInfo.cpp b/src/gui/songInfo.cpp index 7c9b6063b..b67970d73 100644 --- a/src/gui/songInfo.cpp +++ b/src/gui/songInfo.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/songNotes.cpp b/src/gui/songNotes.cpp index d0218f7bf..e45ddf331 100644 --- a/src/gui/songNotes.cpp +++ b/src/gui/songNotes.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/speed.cpp b/src/gui/speed.cpp index b9b4988bc..3acb81518 100644 --- a/src/gui/speed.cpp +++ b/src/gui/speed.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/spoiler.cpp b/src/gui/spoiler.cpp index 05e6d0ead..74026a6df 100644 --- a/src/gui/spoiler.cpp +++ b/src/gui/spoiler.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/stats.cpp b/src/gui/stats.cpp index 5bc2ee102..49c1f6cf6 100644 --- a/src/gui/stats.cpp +++ b/src/gui/stats.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index e3c94bf58..efa453c3c 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/sysManager.cpp b/src/gui/sysManager.cpp index 07741e44c..efe2c29a1 100644 --- a/src/gui/sysManager.cpp +++ b/src/gui/sysManager.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/sysPartNumber.cpp b/src/gui/sysPartNumber.cpp index 3facab9cd..1ce6e2f38 100644 --- a/src/gui/sysPartNumber.cpp +++ b/src/gui/sysPartNumber.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/sysPicker.cpp b/src/gui/sysPicker.cpp index 8607de05d..b374a815f 100644 --- a/src/gui/sysPicker.cpp +++ b/src/gui/sysPicker.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/tutorial.cpp b/src/gui/tutorial.cpp index 7774b95f0..d3c45a95f 100644 --- a/src/gui/tutorial.cpp +++ b/src/gui/tutorial.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/util.cpp b/src/gui/util.cpp index 80ed73781..f1b657725 100644 --- a/src/gui/util.cpp +++ b/src/gui/util.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/util.h b/src/gui/util.h index 6dd2c3a6f..d82466a25 100644 --- a/src/gui/util.h +++ b/src/gui/util.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/volMeter.cpp b/src/gui/volMeter.cpp index a4cf11d7e..8252cccc5 100644 --- a/src/gui/volMeter.cpp +++ b/src/gui/volMeter.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/waveEdit.cpp b/src/gui/waveEdit.cpp index cb4cf0462..90f6e3f52 100644 --- a/src/gui/waveEdit.cpp +++ b/src/gui/waveEdit.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/gui/xyOsc.cpp b/src/gui/xyOsc.cpp index 28136d645..930ed5d60 100644 --- a/src/gui/xyOsc.cpp +++ b/src/gui/xyOsc.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/log.cpp b/src/log.cpp index 2fbf24dd3..3c6149fd3 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/main.cpp b/src/main.cpp index b3b9f3b04..cbfdaa369 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 @@ -188,7 +188,7 @@ TAParamResult pLogLevel(String val) { TAParamResult pVersion(String) { printf("Furnace version " DIV_VERSION ".\n\n"); - printf("copyright (C) 2021-2023 tildearrow and contributors.\n"); + printf("copyright (C) 2021-2024 tildearrow and contributors.\n"); printf("licensed under the GNU General Public License version 2 or later\n"); printf(".\n\n"); printf("this is free software with ABSOLUTELY NO WARRANTY.\n"); diff --git a/src/pch.cpp b/src/pch.cpp index b1cd9d3f5..83194adff 100644 --- a/src/pch.cpp +++ b/src/pch.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/pch.h b/src/pch.h index 7821ee302..1d071166b 100644 --- a/src/pch.h +++ b/src/pch.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/ta-log.h b/src/ta-log.h index de93e24a7..43aecaafb 100644 --- a/src/ta-log.h +++ b/src/ta-log.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/ta-utils.h b/src/ta-utils.h index 6b3c201f5..93bbdf5b0 100644 --- a/src/ta-utils.h +++ b/src/ta-utils.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/utfutils.cpp b/src/utfutils.cpp index 408a5e712..fdbb989da 100644 --- a/src/utfutils.cpp +++ b/src/utfutils.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/utfutils.h b/src/utfutils.h index e55aa07ab..15b7c6685 100644 --- a/src/utfutils.h +++ b/src/utfutils.h @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 diff --git a/src/winMain.cpp b/src/winMain.cpp index 85dd27770..6453137db 100644 --- a/src/winMain.cpp +++ b/src/winMain.cpp @@ -1,6 +1,6 @@ /** * Furnace Tracker - multi-system chiptune tracker - * Copyright (C) 2021-2023 tildearrow and contributors + * 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 From 95aff38cb23a3c0223dc58eb9a788c1459639587 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 16 Jan 2024 22:01:17 -0500 Subject: [PATCH 54/74] GUI: add settings to round tabs and scrollbars --- src/gui/gui.h | 4 ++++ src/gui/settings.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/gui/gui.h b/src/gui/gui.h index ec7520c3e..3227efede 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1619,6 +1619,8 @@ class FurnaceGUI { int roundedWindows; int roundedButtons; int roundedMenus; + int roundedTabs; + int roundedScrollbars; int loadJapanese; int loadChinese; int loadChineseTraditional; @@ -1817,6 +1819,8 @@ class FurnaceGUI { roundedWindows(1), roundedButtons(1), roundedMenus(0), + roundedTabs(1), + roundedScrollbars(1), loadJapanese(0), loadChinese(0), loadChineseTraditional(0), diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 50730c857..2ec4a0fd2 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -3192,6 +3192,18 @@ void FurnaceGUI::drawSettings() { settingsChanged=true; } + bool roundedTabsB=settings.roundedTabs; + if (ImGui::Checkbox("Rounded tabs",&roundedTabsB)) { + settings.roundedTabs=roundedTabsB; + settingsChanged=true; + } + + bool roundedScrollbarsB=settings.roundedScrollbars; + if (ImGui::Checkbox("Rounded scrollbars",&roundedScrollbarsB)) { + settings.roundedScrollbars=roundedScrollbarsB; + settingsChanged=true; + } + bool frameBordersB=settings.frameBorders; if (ImGui::Checkbox("Borders around widgets",&frameBordersB)) { settings.frameBorders=frameBordersB; @@ -3943,6 +3955,8 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) { settings.roundedWindows=conf.getInt("roundedWindows",1); settings.roundedButtons=conf.getInt("roundedButtons",1); settings.roundedMenus=conf.getInt("roundedMenus",0); + settings.roundedTabs=conf.getInt("roundedTabs",1); + settings.roundedScrollbars=conf.getInt("roundedScrollbars",1); settings.separateFMColors=conf.getInt("separateFMColors",0); settings.insEditColorize=conf.getInt("insEditColorize",0); @@ -4108,6 +4122,8 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) { clampSetting(settings.roundedWindows,0,1); clampSetting(settings.roundedButtons,0,1); clampSetting(settings.roundedMenus,0,1); + clampSetting(settings.roundedTabs,0,1); + clampSetting(settings.roundedScrollbars,0,1); clampSetting(settings.loadJapanese,0,1); clampSetting(settings.loadChinese,0,1); clampSetting(settings.loadChineseTraditional,0,1); @@ -4401,6 +4417,8 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) { conf.set("roundedWindows",settings.roundedWindows); conf.set("roundedButtons",settings.roundedButtons); conf.set("roundedMenus",settings.roundedMenus); + conf.set("roundedTabs",settings.roundedTabs); + conf.set("roundedScrollbars",settings.roundedScrollbars); conf.set("separateFMColors",settings.separateFMColors); conf.set("insEditColorize",settings.insEditColorize); @@ -5175,6 +5193,16 @@ void FurnaceGUI::applyUISettings(bool updateFonts) { sty.GrabRounding=6.0f; } if (settings.roundedMenus) sty.PopupRounding=8.0f; + if (settings.roundedTabs) { + sty.TabRounding=4.0f; + } else { + sty.TabRounding=0.0f; + } + if (settings.roundedScrollbars) { + sty.ScrollbarRounding=9.0f; + } else { + sty.ScrollbarRounding=0.0f; + } if (settings.frameBorders) { sty.FrameBorderSize=1.0f; From f8187b9a5fbfe25d48da8082c0fd013ec7840e43 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 16 Jan 2024 23:54:32 -0500 Subject: [PATCH 55/74] dev191 - kind of remove DIV_ALWAYS_SET_VOLUME it's useless crap I put during the Defle compat days it serves nearly no purpose nowadays also why is it a command? --- papers/format.md | 3 ++- src/engine/cmdStreamOps.cpp | 2 -- src/engine/dispatch.h | 9 +++++++-- src/engine/engine.h | 4 ++-- src/engine/fileOps.cpp | 14 ++++++++++++-- src/engine/platform/abstract.cpp | 4 ++++ src/engine/platform/amiga.cpp | 3 --- src/engine/platform/arcade.cpp | 3 --- src/engine/platform/ay.cpp | 7 ++++--- src/engine/platform/ay.h | 1 + src/engine/platform/ay8930.cpp | 7 ++++--- src/engine/platform/ay8930.h | 1 + src/engine/platform/bubsyswsg.cpp | 3 --- src/engine/platform/c140.cpp | 3 --- src/engine/platform/c64.cpp | 3 --- src/engine/platform/es5506.cpp | 3 --- src/engine/platform/esfm.cpp | 7 ++++--- src/engine/platform/esfm.h | 1 + src/engine/platform/fds.cpp | 3 --- src/engine/platform/fmsharedbase.h | 4 ++++ src/engine/platform/ga20.cpp | 3 --- src/engine/platform/gb.cpp | 3 --- src/engine/platform/genesis.cpp | 3 --- src/engine/platform/genesisext.cpp | 3 --- src/engine/platform/k007232.cpp | 3 --- src/engine/platform/k053260.cpp | 3 --- src/engine/platform/lynx.cpp | 7 ++++--- src/engine/platform/lynx.h | 1 + src/engine/platform/mmc5.cpp | 3 --- src/engine/platform/msm5232.cpp | 3 --- src/engine/platform/msm6258.cpp | 7 ++++--- src/engine/platform/msm6258.h | 1 + src/engine/platform/msm6295.cpp | 7 ++++--- src/engine/platform/msm6295.h | 1 + src/engine/platform/n163.cpp | 3 --- src/engine/platform/namcowsg.cpp | 3 --- src/engine/platform/nes.cpp | 3 --- src/engine/platform/opl.cpp | 9 +++++---- src/engine/platform/opl.h | 1 + src/engine/platform/opll.cpp | 7 ++++--- src/engine/platform/opll.h | 1 + src/engine/platform/pce.cpp | 3 --- src/engine/platform/pcmdac.cpp | 3 --- src/engine/platform/pcspkr.cpp | 3 --- src/engine/platform/pet.cpp | 3 --- src/engine/platform/pokemini.cpp | 3 --- src/engine/platform/pokey.cpp | 3 --- src/engine/platform/pong.cpp | 3 --- src/engine/platform/pv1000.cpp | 3 --- src/engine/platform/qsound.cpp | 3 --- src/engine/platform/rf5c68.cpp | 3 --- src/engine/platform/saa.cpp | 7 ++++--- src/engine/platform/saa.h | 1 + src/engine/platform/scc.cpp | 3 --- src/engine/platform/segapcm.cpp | 7 ++++--- src/engine/platform/segapcm.h | 1 + src/engine/platform/sm8521.cpp | 3 --- src/engine/platform/sms.cpp | 7 ++++--- src/engine/platform/sms.h | 1 + src/engine/platform/su.cpp | 3 --- src/engine/platform/swan.cpp | 3 --- src/engine/platform/t6w28.cpp | 3 --- src/engine/platform/ted.cpp | 3 --- src/engine/platform/tia.cpp | 7 ++++--- src/engine/platform/tia.h | 1 + src/engine/platform/tx81z.cpp | 3 --- src/engine/platform/vb.cpp | 3 --- src/engine/platform/vera.cpp | 7 ++++--- src/engine/platform/vera.h | 1 + src/engine/platform/vic20.cpp | 3 --- src/engine/platform/vrc6.cpp | 3 --- src/engine/platform/x1_010.cpp | 3 --- src/engine/platform/ym2203.cpp | 3 --- src/engine/platform/ym2203ext.cpp | 3 --- src/engine/platform/ym2608.cpp | 3 --- src/engine/platform/ym2608ext.cpp | 3 --- src/engine/platform/ym2610.cpp | 3 --- src/engine/platform/ym2610b.cpp | 3 --- src/engine/platform/ym2610bext.cpp | 3 --- src/engine/platform/ym2610ext.cpp | 3 --- src/engine/platform/ymz280b.cpp | 3 --- src/engine/platform/zxbeeper.cpp | 3 --- src/engine/platform/zxbeeperquadtone.cpp | 3 --- src/engine/playback.cpp | 7 +------ src/engine/song.h | 4 +++- src/gui/compatFlags.cpp | 4 ++++ src/gui/pattern.cpp | 1 - 87 files changed, 105 insertions(+), 207 deletions(-) diff --git a/papers/format.md b/papers/format.md index 242e8bcc4..1a5a466a0 100644 --- a/papers/format.md +++ b/papers/format.md @@ -364,7 +364,8 @@ size | description 1 | disable new NES DPCM features (>=183) 1 | reset arp effect phase on new note (>=184) 1 | linear volume scaling rounds up (>=188) - 2 | reserved + 1 | legacy "always set volume" behavior (>=191) + 1 | reserved --- | **speed pattern of first song** (>=139) 1 | length of speed pattern (fail if this is lower than 0 or higher than 16) 16 | speed pattern (this overrides speed 1 and speed 2 settings) diff --git a/src/engine/cmdStreamOps.cpp b/src/engine/cmdStreamOps.cpp index b3be6dddf..4ba6cd893 100644 --- a/src/engine/cmdStreamOps.cpp +++ b/src/engine/cmdStreamOps.cpp @@ -312,8 +312,6 @@ SafeWriter* DivEngine::saveCommand(bool binary) { for (DivCommand& i: cmdStream) { switch (i.cmd) { // strip away hinted/useless commands - case DIV_ALWAYS_SET_VOLUME: - break; case DIV_CMD_GET_VOLUME: break; case DIV_CMD_VOLUME: diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index fef7dd78f..4f9812caa 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -248,8 +248,6 @@ enum DivDispatchCmds { DIV_CMD_ESFM_MODIN, // (op, value) DIV_CMD_ESFM_ENV_DELAY, // (op, value) - DIV_ALWAYS_SET_VOLUME, // () -> alwaysSetVol - DIV_CMD_MAX }; @@ -611,6 +609,13 @@ class DivDispatch { */ virtual int getPortaFloor(int ch); + /** + * check whether to always set volume on volume change (even when same volume). + * only for compatibility purposes! + * @return truth. + */ + virtual bool getLegacyAlwaysSetVolume(); + /** * get the required amplification level of this dispatch's output. * @return the amplification level. diff --git a/src/engine/engine.h b/src/engine/engine.h index 3bf2a9826..1e13e3ccb 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "dev190" -#define DIV_ENGINE_VERSION 190 +#define DIV_VERSION "dev191" +#define DIV_ENGINE_VERSION 191 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index 9faf0923d..d4c02347a 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -187,6 +187,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { ds.oldDPCM=true; ds.delayBehavior=0; ds.jumpTreatment=2; + ds.oldAlwaysSetVolume=true; // 1.1 compat flags if (ds.version>24) { @@ -1876,6 +1877,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { if (ds.version<188) { ds.ceilVolumeScaling=false; } + if (ds.version<191) { + ds.oldAlwaysSetVolume=true; + } ds.isDMF=false; reader.readS(); // reserved @@ -2424,7 +2428,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { } else { reader.readC(); } - for (int i=0; i<2; i++) { + if (ds.version>=191) { + ds.oldAlwaysSetVolume=reader.readC(); + } else { + reader.readC(); + } + for (int i=0; i<1; i++) { reader.readC(); } } @@ -5522,7 +5531,8 @@ SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) { w->writeC(song.oldDPCM); w->writeC(song.resetArpPhaseOnNewNote); w->writeC(song.ceilVolumeScaling); - for (int i=0; i<2; i++) { + w->writeC(song.oldAlwaysSetVolume); + for (int i=0; i<1; i++) { w->writeC(0); } diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index 6da4b3e79..ae16c7d2f 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -111,6 +111,10 @@ int DivDispatch::getPortaFloor(int ch) { return 0x00; } +bool DivDispatch::getLegacyAlwaysSetVolume() { + return true; +} + float DivDispatch::getPostAmp() { return 1.0f; } diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index d9a8fca82..107c1493a 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -721,9 +721,6 @@ int DivPlatformAmiga::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index a84259009..b760d8e6a 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -783,9 +783,6 @@ int DivPlatformArcade::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: return 127; break; diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index ed352e982..823b0b3a1 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -651,9 +651,6 @@ int DivPlatformAY8910::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: return 15; break; @@ -779,6 +776,10 @@ bool DivPlatformAY8910::keyOffAffectsArp(int ch) { return true; } +bool DivPlatformAY8910::getLegacyAlwaysSetVolume() { + return false; +} + void DivPlatformAY8910::notifyInsDeletion(void* ins) { for (int i=0; i<3; i++) { chan[i].std.notifyInsDeletion((DivInstrument*)ins); diff --git a/src/engine/platform/ay.h b/src/engine/platform/ay.h index 480e23f4e..fe0a6758a 100644 --- a/src/engine/platform/ay.h +++ b/src/engine/platform/ay.h @@ -144,6 +144,7 @@ class DivPlatformAY8910: public DivDispatch { bool keyOffAffectsArp(int ch); DivMacroInt* getChanMacroInt(int ch); DivSamplePos getSamplePos(int ch); + bool getLegacyAlwaysSetVolume(); bool getDCOffRequired(); void notifyInsDeletion(void* ins); void poke(unsigned int addr, unsigned short val); diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 9fd4c1629..4fc32ac5c 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -653,9 +653,6 @@ int DivPlatformAY8930::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: return 31; break; @@ -778,6 +775,10 @@ bool DivPlatformAY8930::keyOffAffectsArp(int ch) { return true; } +bool DivPlatformAY8930::getLegacyAlwaysSetVolume() { + return false; +} + void DivPlatformAY8930::notifyInsDeletion(void* ins) { for (int i=0; i<3; i++) { chan[i].std.notifyInsDeletion((DivInstrument*)ins); diff --git a/src/engine/platform/ay8930.h b/src/engine/platform/ay8930.h index 902c69517..b43ec0fcd 100644 --- a/src/engine/platform/ay8930.h +++ b/src/engine/platform/ay8930.h @@ -144,6 +144,7 @@ class DivPlatformAY8930: public DivDispatch { bool keyOffAffectsArp(int ch); DivMacroInt* getChanMacroInt(int ch); DivSamplePos getSamplePos(int ch); + bool getLegacyAlwaysSetVolume(); void notifyInsDeletion(void* ins); void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); diff --git a/src/engine/platform/bubsyswsg.cpp b/src/engine/platform/bubsyswsg.cpp index 1429c55b3..452fb8f89 100644 --- a/src/engine/platform/bubsyswsg.cpp +++ b/src/engine/platform/bubsyswsg.cpp @@ -246,9 +246,6 @@ int DivPlatformBubSysWSG::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/c140.cpp b/src/engine/platform/c140.cpp index bcfae3773..46f793a9a 100644 --- a/src/engine/platform/c140.cpp +++ b/src/engine/platform/c140.cpp @@ -441,9 +441,6 @@ int DivPlatformC140::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 3a80a43ef..4c3245b82 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -536,9 +536,6 @@ int DivPlatformC64::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/es5506.cpp b/src/engine/platform/es5506.cpp index 85c70d17e..0121d19d5 100644 --- a/src/engine/platform/es5506.cpp +++ b/src/engine/platform/es5506.cpp @@ -1022,9 +1022,6 @@ int DivPlatformES5506::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 0df388084..1981b855d 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -920,9 +920,6 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: return 63; break; @@ -1015,6 +1012,10 @@ bool DivPlatformESFM::keyOffAffectsPorta(int ch) { return false; } +bool DivPlatformESFM::getLegacyAlwaysSetVolume() { + return false; +} + void DivPlatformESFM::notifyInsChange(int ins) { for (int i=0; i<18; i++) { if (chan[i].ins==ins) { diff --git a/src/engine/platform/esfm.h b/src/engine/platform/esfm.h index d7a5a574d..58fafbfab 100644 --- a/src/engine/platform/esfm.h +++ b/src/engine/platform/esfm.h @@ -193,6 +193,7 @@ class DivPlatformESFM: public DivDispatch { void muteChannel(int ch, bool mute); bool keyOffAffectsArp(int ch); bool keyOffAffectsPorta(int ch); + bool getLegacyAlwaysSetVolume(); void toggleRegisterDump(bool enable); void notifyInsChange(int ins); void notifyInsDeletion(void* ins); diff --git a/src/engine/platform/fds.cpp b/src/engine/platform/fds.cpp index 66b713ca2..1afcd0df0 100644 --- a/src/engine/platform/fds.cpp +++ b/src/engine/platform/fds.cpp @@ -387,9 +387,6 @@ int DivPlatformFDS::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/fmsharedbase.h b/src/engine/platform/fmsharedbase.h index 63669002b..3f5db9229 100644 --- a/src/engine/platform/fmsharedbase.h +++ b/src/engine/platform/fmsharedbase.h @@ -136,6 +136,10 @@ class DivPlatformFMBase: public DivDispatch { return CLAMP(round(128.0-(56.0-log2(vel*127.0)*8.0)),0,127); } + bool getLegacyAlwaysSetVolume() { + return true; + } + friend void putDispatchChan(void*,int,int); DivPlatformFMBase(): diff --git a/src/engine/platform/ga20.cpp b/src/engine/platform/ga20.cpp index af7fbed90..a2ff81eb3 100644 --- a/src/engine/platform/ga20.cpp +++ b/src/engine/platform/ga20.cpp @@ -311,9 +311,6 @@ int DivPlatformGA20::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index c1af65415..4f9c85960 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -553,9 +553,6 @@ int DivPlatformGB::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 393b0c07f..9a2b514d0 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -1183,9 +1183,6 @@ int DivPlatformGenesis::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: return 127; break; diff --git a/src/engine/platform/genesisext.cpp b/src/engine/platform/genesisext.cpp index bdfb8bfc6..a3860f09d 100644 --- a/src/engine/platform/genesisext.cpp +++ b/src/engine/platform/genesisext.cpp @@ -418,9 +418,6 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: opChan[ch].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_PRE_PORTA: break; default: diff --git a/src/engine/platform/k007232.cpp b/src/engine/platform/k007232.cpp index 7d84e6d35..ba742a2dc 100644 --- a/src/engine/platform/k007232.cpp +++ b/src/engine/platform/k007232.cpp @@ -395,9 +395,6 @@ int DivPlatformK007232::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index 12128308c..2af1d5bd3 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -345,9 +345,6 @@ int DivPlatformK053260::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/lynx.cpp b/src/engine/platform/lynx.cpp index 722b139cc..909e4b20c 100644 --- a/src/engine/platform/lynx.cpp +++ b/src/engine/platform/lynx.cpp @@ -353,9 +353,6 @@ int DivPlatformLynx::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; default: break; } @@ -438,6 +435,10 @@ bool DivPlatformLynx::keyOffAffectsPorta(int ch) { return true; } +bool DivPlatformLynx::getLegacyAlwaysSetVolume() { + return false; +} + //int DivPlatformLynx::getPortaFloor(int ch) { // return 12; //} diff --git a/src/engine/platform/lynx.h b/src/engine/platform/lynx.h index 1ce093187..7d705261d 100644 --- a/src/engine/platform/lynx.h +++ b/src/engine/platform/lynx.h @@ -84,6 +84,7 @@ class DivPlatformLynx: public DivDispatch { int getOutputCount(); bool keyOffAffectsArp(int ch); bool keyOffAffectsPorta(int ch); + bool getLegacyAlwaysSetVolume(); //int getPortaFloor(int ch); void notifyInsDeletion(void* ins); void poke(unsigned int addr, unsigned short val); diff --git a/src/engine/platform/mmc5.cpp b/src/engine/platform/mmc5.cpp index ad3e44431..656288c6a 100644 --- a/src/engine/platform/mmc5.cpp +++ b/src/engine/platform/mmc5.cpp @@ -327,9 +327,6 @@ int DivPlatformMMC5::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/msm5232.cpp b/src/engine/platform/msm5232.cpp index d1a24ba56..ef4e14afc 100644 --- a/src/engine/platform/msm5232.cpp +++ b/src/engine/platform/msm5232.cpp @@ -297,9 +297,6 @@ int DivPlatformMSM5232::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/msm6258.cpp b/src/engine/platform/msm6258.cpp index d60535e91..1b7b2434b 100644 --- a/src/engine/platform/msm6258.cpp +++ b/src/engine/platform/msm6258.cpp @@ -268,9 +268,6 @@ int DivPlatformMSM6258::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: return 8; break; @@ -371,6 +368,10 @@ bool DivPlatformMSM6258::keyOffAffectsArp(int ch) { return false; } +bool DivPlatformMSM6258::getLegacyAlwaysSetVolume() { + return false; +} + void DivPlatformMSM6258::notifyInsChange(int ins) { for (int i=0; i<1; i++) { if (chan[i].ins==ins) { diff --git a/src/engine/platform/msm6258.h b/src/engine/platform/msm6258.h index c31c083c3..9b84c2236 100644 --- a/src/engine/platform/msm6258.h +++ b/src/engine/platform/msm6258.h @@ -75,6 +75,7 @@ class DivPlatformMSM6258: public DivDispatch { void muteChannel(int ch, bool mute); int getOutputCount(); bool keyOffAffectsArp(int ch); + bool getLegacyAlwaysSetVolume(); void notifyInsChange(int ins); void notifyInsDeletion(void* ins); void poke(unsigned int addr, unsigned short val); diff --git a/src/engine/platform/msm6295.cpp b/src/engine/platform/msm6295.cpp index d770a845e..8ca92d9fb 100644 --- a/src/engine/platform/msm6295.cpp +++ b/src/engine/platform/msm6295.cpp @@ -226,9 +226,6 @@ int DivPlatformMSM6295::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: return 8; break; @@ -312,6 +309,10 @@ bool DivPlatformMSM6295::keyOffAffectsArp(int ch) { return false; } +bool DivPlatformMSM6295::getLegacyAlwaysSetVolume() { + return false; +} + float DivPlatformMSM6295::getPostAmp() { return 3.0f; } diff --git a/src/engine/platform/msm6295.h b/src/engine/platform/msm6295.h index d8778926a..b7ebf5bf9 100644 --- a/src/engine/platform/msm6295.h +++ b/src/engine/platform/msm6295.h @@ -77,6 +77,7 @@ class DivPlatformMSM6295: public DivDispatch, public vgsound_emu_mem_intf { virtual void tick(bool sysTick=true) override; virtual void muteChannel(int ch, bool mute) override; virtual bool keyOffAffectsArp(int ch) override; + virtual bool getLegacyAlwaysSetVolume() override; virtual float getPostAmp() override; virtual void notifyInsChange(int ins) override; virtual void notifyInsDeletion(void* ins) override; diff --git a/src/engine/platform/n163.cpp b/src/engine/platform/n163.cpp index f96d13216..c1320ef1a 100644 --- a/src/engine/platform/n163.cpp +++ b/src/engine/platform/n163.cpp @@ -452,9 +452,6 @@ int DivPlatformN163::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/namcowsg.cpp b/src/engine/platform/namcowsg.cpp index abc762de7..7c56b1c5e 100644 --- a/src/engine/platform/namcowsg.cpp +++ b/src/engine/platform/namcowsg.cpp @@ -445,9 +445,6 @@ int DivPlatformNamcoWSG::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index e1e883673..1b15c5da5 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -659,9 +659,6 @@ int DivPlatformNES::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index b64d4f020..088c72f38 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1343,7 +1343,7 @@ void DivPlatformOPL::commitState(int ch, DivInstrument* ins) { int DivPlatformOPL::dispatch(DivCommand c) { if (c.chan>=totalChans && c.chan!=adpcmChan) return 0; // ineffective in 4-op mode - if (oplType==3 && c.chan!=adpcmChan && c.chan<14 && (c.chan&1) && c.cmd!=DIV_CMD_GET_VOLMAX && c.cmd!=DIV_ALWAYS_SET_VOLUME) { + if (oplType==3 && c.chan!=adpcmChan && c.chan<14 && (c.chan&1) && c.cmd!=DIV_CMD_GET_VOLMAX) { if (chan[c.chan-1].fourOp) return 0; } switch (c.cmd) { @@ -1970,9 +1970,6 @@ int DivPlatformOPL::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: if (c.chan==adpcmChan) return 255; if (pretendYMU) return 127; @@ -2279,6 +2276,10 @@ bool DivPlatformOPL::keyOffAffectsPorta(int ch) { return false; } +bool DivPlatformOPL::getLegacyAlwaysSetVolume() { + return false; +} + void DivPlatformOPL::notifyInsChange(int ins) { for (int i=0; i& wlist); diff --git a/src/engine/platform/scc.cpp b/src/engine/platform/scc.cpp index 251e1e3f6..f0075822e 100644 --- a/src/engine/platform/scc.cpp +++ b/src/engine/platform/scc.cpp @@ -261,9 +261,6 @@ int DivPlatformSCC::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index 975052073..c2dc6f3d5 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -339,9 +339,6 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: return 127; break; @@ -372,6 +369,10 @@ void DivPlatformSegaPCM::forceIns() { } } +bool DivPlatformSegaPCM::getLegacyAlwaysSetVolume() { + return false; +} + void DivPlatformSegaPCM::notifyInsChange(int ins) { for (int i=0; i<16; i++) { if (chan[i].ins==ins) { diff --git a/src/engine/platform/segapcm.h b/src/engine/platform/segapcm.h index 192c47be0..f99da7317 100644 --- a/src/engine/platform/segapcm.h +++ b/src/engine/platform/segapcm.h @@ -103,6 +103,7 @@ class DivPlatformSegaPCM: public DivDispatch { void renderSamples(int chipID); void setFlags(const DivConfig& flags); int getOutputCount(); + bool getLegacyAlwaysSetVolume(); void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); const void* getSampleMem(int index=0); diff --git a/src/engine/platform/sm8521.cpp b/src/engine/platform/sm8521.cpp index f1ec91e91..55430c552 100644 --- a/src/engine/platform/sm8521.cpp +++ b/src/engine/platform/sm8521.cpp @@ -277,9 +277,6 @@ int DivPlatformSM8521::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 57cd02aea..83351e855 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -420,9 +420,6 @@ int DivPlatformSMS::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; default: break; } @@ -509,6 +506,10 @@ bool DivPlatformSMS::keyOffAffectsPorta(int ch) { return true; } +bool DivPlatformSMS::getLegacyAlwaysSetVolume() { + return false; +} + int DivPlatformSMS::getPortaFloor(int ch) { return 12; } diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h index 199a87d87..d2d0c901f 100644 --- a/src/engine/platform/sms.h +++ b/src/engine/platform/sms.h @@ -89,6 +89,7 @@ class DivPlatformSMS: public DivDispatch { int getOutputCount(); bool keyOffAffectsArp(int ch); bool keyOffAffectsPorta(int ch); + bool getLegacyAlwaysSetVolume(); float getPostAmp(); int getPortaFloor(int ch); void setFlags(const DivConfig& flags); diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index 0a3f22545..891bab206 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -502,9 +502,6 @@ int DivPlatformSoundUnit::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index d50e2dddd..0f7b6911f 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -446,9 +446,6 @@ int DivPlatformSwan::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/t6w28.cpp b/src/engine/platform/t6w28.cpp index 0c0e388cf..138d395be 100644 --- a/src/engine/platform/t6w28.cpp +++ b/src/engine/platform/t6w28.cpp @@ -271,9 +271,6 @@ int DivPlatformT6W28::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/ted.cpp b/src/engine/platform/ted.cpp index 3b9c61aab..5078a9a37 100644 --- a/src/engine/platform/ted.cpp +++ b/src/engine/platform/ted.cpp @@ -236,9 +236,6 @@ int DivPlatformTED::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/tia.cpp b/src/engine/platform/tia.cpp index 50bb82d64..d49d00af6 100644 --- a/src/engine/platform/tia.cpp +++ b/src/engine/platform/tia.cpp @@ -258,9 +258,6 @@ int DivPlatformTIA::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: return 15; break; @@ -340,6 +337,10 @@ bool DivPlatformTIA::keyOffAffectsArp(int ch) { return true; } +bool DivPlatformTIA::getLegacyAlwaysSetVolume() { + return false; +} + void DivPlatformTIA::notifyInsDeletion(void* ins) { for (int i=0; i<2; i++) { chan[i].std.notifyInsDeletion((DivInstrument*)ins); diff --git a/src/engine/platform/tia.h b/src/engine/platform/tia.h index fbc7dacfe..a66de9cbd 100644 --- a/src/engine/platform/tia.h +++ b/src/engine/platform/tia.h @@ -59,6 +59,7 @@ class DivPlatformTIA: public DivDispatch { float getPostAmp(); int getOutputCount(); bool keyOffAffectsArp(int ch); + bool getLegacyAlwaysSetVolume(); void notifyInsDeletion(void* ins); void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); diff --git a/src/engine/platform/tx81z.cpp b/src/engine/platform/tx81z.cpp index 40bcd9a39..7d68342be 100644 --- a/src/engine/platform/tx81z.cpp +++ b/src/engine/platform/tx81z.cpp @@ -880,9 +880,6 @@ int DivPlatformTX81Z::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: return 127; break; diff --git a/src/engine/platform/vb.cpp b/src/engine/platform/vb.cpp index 28651b7d3..c0e5b49af 100644 --- a/src/engine/platform/vb.cpp +++ b/src/engine/platform/vb.cpp @@ -395,9 +395,6 @@ int DivPlatformVB::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/vera.cpp b/src/engine/platform/vera.cpp index 830cd2ece..48b800672 100644 --- a/src/engine/platform/vera.cpp +++ b/src/engine/platform/vera.cpp @@ -437,9 +437,6 @@ int DivPlatformVERA::dispatch(DivCommand c) { case DIV_CMD_EXTERNAL: rWriteZSMSync(c.value); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; default: break; } @@ -470,6 +467,10 @@ int DivPlatformVERA::getRegisterPoolSize() { return 67; } +bool DivPlatformVERA::getLegacyAlwaysSetVolume() { + return false; +} + void DivPlatformVERA::muteChannel(int ch, bool mute) { isMuted[ch]=mute; if (ch<16) { diff --git a/src/engine/platform/vera.h b/src/engine/platform/vera.h index d23ac8100..db2005bd7 100644 --- a/src/engine/platform/vera.h +++ b/src/engine/platform/vera.h @@ -73,6 +73,7 @@ class DivPlatformVERA: public DivDispatch { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); void setFlags(const DivConfig& flags); + bool getLegacyAlwaysSetVolume(); void notifyInsDeletion(void* ins); float getPostAmp(); int getOutputCount(); diff --git a/src/engine/platform/vic20.cpp b/src/engine/platform/vic20.cpp index 8d12ce24e..66a11fadd 100644 --- a/src/engine/platform/vic20.cpp +++ b/src/engine/platform/vic20.cpp @@ -252,9 +252,6 @@ int DivPlatformVIC20::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/vrc6.cpp b/src/engine/platform/vrc6.cpp index 0610cb2fa..3b2f660ac 100644 --- a/src/engine/platform/vrc6.cpp +++ b/src/engine/platform/vrc6.cpp @@ -412,9 +412,6 @@ int DivPlatformVRC6::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index 70cd77f53..e5cfe72ac 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -832,9 +832,6 @@ int DivPlatformX1_010::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index 9f6f54f50..a666a62b9 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -861,9 +861,6 @@ int DivPlatformYM2203::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: if (c.chan>2) return 15; return 127; diff --git a/src/engine/platform/ym2203ext.cpp b/src/engine/platform/ym2203ext.cpp index c2587f53c..bd2e6c4a5 100644 --- a/src/engine/platform/ym2203ext.cpp +++ b/src/engine/platform/ym2203ext.cpp @@ -375,9 +375,6 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: opChan[ch].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_PRE_PORTA: break; default: diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index dcda75982..7738ae979 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -1352,9 +1352,6 @@ int DivPlatformYM2608::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: if (c.chan>14) return 255; if (c.chan>8) return 31; diff --git a/src/engine/platform/ym2608ext.cpp b/src/engine/platform/ym2608ext.cpp index c2428993c..d27703c58 100644 --- a/src/engine/platform/ym2608ext.cpp +++ b/src/engine/platform/ym2608ext.cpp @@ -399,9 +399,6 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: opChan[ch].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_PRE_PORTA: break; default: diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 50cccd3a3..e982fe086 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -1324,9 +1324,6 @@ int DivPlatformYM2610::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: if (c.chan>=adpcmBChanOffs) return 255; if (c.chan>=adpcmAChanOffs) return 31; diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 9d83c1a0e..6c183a57d 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -1391,9 +1391,6 @@ int DivPlatformYM2610B::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_GET_VOLMAX: if (c.chan>=adpcmBChanOffs) return 255; if (c.chan>=adpcmAChanOffs) return 31; diff --git a/src/engine/platform/ym2610bext.cpp b/src/engine/platform/ym2610bext.cpp index 09efc620c..519c7004e 100644 --- a/src/engine/platform/ym2610bext.cpp +++ b/src/engine/platform/ym2610bext.cpp @@ -395,9 +395,6 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: opChan[ch].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_PRE_PORTA: break; default: diff --git a/src/engine/platform/ym2610ext.cpp b/src/engine/platform/ym2610ext.cpp index c468c02e7..d9a111114 100644 --- a/src/engine/platform/ym2610ext.cpp +++ b/src/engine/platform/ym2610ext.cpp @@ -395,9 +395,6 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: opChan[ch].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 0; - break; case DIV_CMD_PRE_PORTA: break; default: diff --git a/src/engine/platform/ymz280b.cpp b/src/engine/platform/ymz280b.cpp index 02b701b20..4158b4fa9 100644 --- a/src/engine/platform/ymz280b.cpp +++ b/src/engine/platform/ymz280b.cpp @@ -321,9 +321,6 @@ int DivPlatformYMZ280B::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/zxbeeper.cpp b/src/engine/platform/zxbeeper.cpp index 7e48662c8..70272613a 100644 --- a/src/engine/platform/zxbeeper.cpp +++ b/src/engine/platform/zxbeeper.cpp @@ -218,9 +218,6 @@ int DivPlatformZXBeeper::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/platform/zxbeeperquadtone.cpp b/src/engine/platform/zxbeeperquadtone.cpp index dc93c2455..35a8a5d1d 100644 --- a/src/engine/platform/zxbeeperquadtone.cpp +++ b/src/engine/platform/zxbeeperquadtone.cpp @@ -288,9 +288,6 @@ int DivPlatformZXBeeperQuadTone::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; - case DIV_ALWAYS_SET_VOLUME: - return 1; - break; default: break; } diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 357e43361..06ce4ed1c 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -246,9 +246,6 @@ const char* cmdName[]={ "ESFM_OUTLVL", "ESFM_MODIN", "ESFM_ENV_DELAY", - - "ALWAYS_SET_VOLUME", - }; static_assert((sizeof(cmdName)/sizeof(void*))==DIV_CMD_MAX,"update cmdName!"); @@ -273,8 +270,6 @@ int DivEngine::dispatchCmd(DivCommand c) { if (!skipping) { switch (c.cmd) { // strip away hinted/useless commands - case DIV_ALWAYS_SET_VOLUME: - break; case DIV_CMD_GET_VOLUME: break; case DIV_CMD_VOLUME: @@ -621,7 +616,7 @@ void DivEngine::processRow(int i, bool afterDelay) { // volume if (pat->data[whatRow][3]!=-1) { - if (dispatchCmd(DivCommand(DIV_ALWAYS_SET_VOLUME,i)) || (MIN(chan[i].volMax,chan[i].volume)>>8)!=pat->data[whatRow][3]) { + if (!song.oldAlwaysSetVolume || disCont[dispatchOfChan[i]].dispatch->getLegacyAlwaysSetVolume() || (MIN(chan[i].volMax,chan[i].volume)>>8)!=pat->data[whatRow][3]) { if (pat->data[whatRow][0]==0 && pat->data[whatRow][1]==0) { chan[i].midiAftertouch=true; } diff --git a/src/engine/song.h b/src/engine/song.h index 6f5ab68f5..7f29ddb69 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -383,6 +383,7 @@ struct DivSong { bool oldDPCM; bool resetArpPhaseOnNewNote; bool ceilVolumeScaling; + bool oldAlwaysSetVolume; std::vector ins; std::vector wave; @@ -505,7 +506,8 @@ struct DivSong { preNoteNoEffect(false), oldDPCM(false), resetArpPhaseOnNewNote(false), - ceilVolumeScaling(false) { + ceilVolumeScaling(false), + oldAlwaysSetVolume(false) { for (int i=0; isong.oldAlwaysSetVolume); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("behavior changed in 0.6.1\nthis flag will be removed if I find out that none of the songs break after disabling it."); + } ImGui::EndTabItem(); } if (ImGui::BeginTabItem(".mod import")) { diff --git a/src/gui/pattern.cpp b/src/gui/pattern.cpp index 2e4db92cc..762d8ceca 100644 --- a/src/gui/pattern.cpp +++ b/src/gui/pattern.cpp @@ -1463,7 +1463,6 @@ void FurnaceGUI::drawPattern() { if (i.cmd==DIV_CMD_PRE_NOTE) continue; if (i.cmd==DIV_CMD_SAMPLE_BANK) continue; if (i.cmd==DIV_CMD_GET_VOLUME) continue; - if (i.cmd==DIV_ALWAYS_SET_VOLUME) continue; if (i.cmd==DIV_CMD_HINT_VOLUME || i.cmd==DIV_CMD_HINT_PORTA || i.cmd==DIV_CMD_HINT_LEGATO || From bbb53f78e30c4813a83d55201cd5eb3292117298 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 16 Jan 2024 23:57:52 -0500 Subject: [PATCH 56/74] GUI: color for ESFM instruments --- src/gui/guiConst.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/guiConst.cpp b/src/gui/guiConst.cpp index 92247e874..900669dd0 100644 --- a/src/gui/guiConst.cpp +++ b/src/gui/guiConst.cpp @@ -985,7 +985,7 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={ D(GUI_COLOR_INSTR_TED,"",ImVec4(0.7f,0.6f,1.0f,1.0f)), D(GUI_COLOR_INSTR_C140,"",ImVec4(1.0f,1.0f,0.0f,1.0f)), D(GUI_COLOR_INSTR_C219,"",ImVec4(1.0f,0.8f,0.0f,1.0f)), - D(GUI_COLOR_INSTR_ESFM,"",ImVec4(0.3f,1.0f,0.9f,1.0f)), + D(GUI_COLOR_INSTR_ESFM,"",ImVec4(0.1f,0.9f,1.0f,1.0f)), D(GUI_COLOR_INSTR_UNKNOWN,"",ImVec4(0.3f,0.3f,0.3f,1.0f)), D(GUI_COLOR_CHANNEL_BG,"",ImVec4(0.4f,0.6f,0.8f,1.0f)), From 6bfb08d5bbdb98d232887f382ccd8376a952ec19 Mon Sep 17 00:00:00 2001 From: freq-mod <32672779+freq-mod@users.noreply.github.com> Date: Tue, 16 Jan 2024 23:06:37 +0100 Subject: [PATCH 57/74] ESFM demo song Sakura Sakura Japanize Dream --- demos/misc/pcbend.fur | Bin 0 -> 4451 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 demos/misc/pcbend.fur diff --git a/demos/misc/pcbend.fur b/demos/misc/pcbend.fur new file mode 100644 index 0000000000000000000000000000000000000000..033e8c0e5723ca3d190d1dd9dfbc6de55933aaa6 GIT binary patch literal 4451 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 literal 0 HcmV?d00001 From 912c249a50133bf611e37d6761a9e0873793698e Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 17 Jan 2024 00:00:47 -0500 Subject: [PATCH 58/74] ESFM demo song directory --- demos/{misc => esfm}/pcbend.fur | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename demos/{misc => esfm}/pcbend.fur (100%) diff --git a/demos/misc/pcbend.fur b/demos/esfm/pcbend.fur similarity index 100% rename from demos/misc/pcbend.fur rename to demos/esfm/pcbend.fur From c1bf577ccf95344d1a8b86865fd5d1f68e63dd58 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 17 Jan 2024 00:37:45 -0500 Subject: [PATCH 59/74] ESFM: documentation --- doc/4-instrument/fm-esfm.md | 77 +++++++++++++++++++++++++++ doc/7-systems/esfm.md | 101 ++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 doc/4-instrument/fm-esfm.md create mode 100644 doc/7-systems/esfm.md diff --git a/doc/4-instrument/fm-esfm.md b/doc/4-instrument/fm-esfm.md new file mode 100644 index 000000000..50fdec3d8 --- /dev/null +++ b/doc/4-instrument/fm-esfm.md @@ -0,0 +1,77 @@ +# ESFM instrument editor + +the ESFM editor is divided into 6 tabs: + +- **FM**: for controlling the basic parameters of FM sound source. +- **Macros (OP1)**: for macros controlling FM parameters of operator 1. +- **Macros (OP2)**: for macros controlling FM parameters of operator 2. +- **Macros (OP3)**: for macros controlling FM parameters of operator 3. +- **Macros (OP4)**: for macros controlling FM parameters of operator 4. +- **Macros**: for other macros (volume/arp/pitch/pan/noise mode). + +## FM + +ESFM is four-operator, but it is different from the rest of FM chips. + +the concept of an algorithm does not exist in ESFM. instead, modulation routing is arbitrary, with each operator having output level and modulation input parameters. + +these apply to the instrument as a whole: +- **OP4 Noise Mode**: determines the mode used to produce noise in operator 4. + - Normal: noise is disabled. + - Snare: takes the snare noise generation mode from OPL. square + noise. + - HiHat: ring modulates with operator 3 and adds noise. + - Top: ring modulates with operator 3 and double pitch modulation input. + - this mode is not emulated correctly. subject to change! + +these apply to each operator: +- the crossed-arrows button can be dragged to rearrange operators. +- **Amplitude Modulation (AM)**: makes the operator affected by LFO tremolo. +- **Sustain flag (SUS)**: when enabled, value of Sustain Level is in effect. +- **AM Depth (AMD)**: when enabled, LFO tremolo is deeper. +- **Attack Rate (AR)**: determines the rising time for the sound. the bigger the value, the faster the attack (0 to 15). +- **Decay Rate (DR)**: determines the diminishing time for the sound. the higher the value, the shorter the decay. it's the initial amplitude decay rate (0 to 15). +- **Sustain Level (SL)**: determines the point at which the sound ceases to decay and changes to a sound having a constant level. the sustain level is expressed as a fraction of the maximum level (0 to 15). +- **Release Rate (RR)**: determines the rate at which the sound disappears after note off. the higher the value, the shorter the release (0 to 15). + +- **Total Level (TL)**: represents the envelope’s highest amplitude, with 0 being the largest and 63 (decimal) the smallest. a change of one unit is about 0.75 dB. +- **Output Level (OL)**: determines the volume at which the operator will be output. +- **Modulation Input (MI)**: determines how much to take from the previous operator for modulation. + - this controls feedback level in the case of operator 1. +- **Key Scale Level (KSL)**: also known as "Level Scale". determines the degree to which the amplitude decreases according to the pitch. + +![FM ADSR chart](FM-ADSRchart.png) + +- **Key Scale Rate (KSR)**: also known as "Rate Scale". determines the degree to which the envelope execution speed increases according to the pitch. +- **Frequency Multiplier (MULT)**: sets the coarse pitch offset in relation to the note (0 to 15). 0 is -1 octave, 1 is 0 octaves, 2 is 1 octave, 3 is 1 octave 7 semitones, and so on. + - note that values 11, 13 and 14 behave as 10, 12 and 12 respectively. +- **Waveform Select (WS)**: changes the waveform of the operator (0 to 7). +- **Vibrato (VIB)**: makes the operator affected by LFO vibrato. +- **FM Depth (FMD)**: when enabled, vibrato is deeper. + +- **Tune**: sets the coarse tune of the operator. +- **Detune**: sets the fine tune of the operator. + +- **Left (L)**: output on the left channel. +- **Right (R)**: output on the right channel. + +### fixed frequency mode + +each operator has a Fixed Frequency mode. once enabled, the operator runs at the specified frequency regardless of the note. + +## macros + +these macros allow you to control several parameters of FM per tick. + +## OP1-OP4 Macros + +all parameters are listed above. + +## Macros + +- **Volume**: volume sequence. +- **Arpeggio**: pitch sequence. +- **OP4 Noise Mode**: noise mode sequence. +- **Panning**: enables output on left/right channels. +- **Pitch**: fine pitch. + - **Relative**: when enabled, pitch changes are relative to the current pitch. +- **Phase Reset**: restarts all operators and resets the waveform to its start. diff --git a/doc/7-systems/esfm.md b/doc/7-systems/esfm.md new file mode 100644 index 000000000..bd53589a4 --- /dev/null +++ b/doc/7-systems/esfm.md @@ -0,0 +1,101 @@ +# ESS ESFM + +an enhanced version of Yamaha's OPL3, adding many features which weren't present on the original chip, such as 4-op on all channels, coarse/fine detune, per-op panning, envelope delay, noise generator and advanced modulation routing (no more algorithms!). + +the technology was present in many of ESS' sound cards (the ES1xxx series in particular). + +## effects + +- `10xy`: **set AM depth.** + - `x` is the operator from 1 to 4. a value of `0` means "all operators". + - `y` is either `0` (1dB, shallow) or `1` (4.8dB, deep). +- `12xx`: **set operator 1 level.** +- `13xx`: **set operator 2 level.** +- `14xx`: **set operator 3 level.** +- `15xx`: **set operator 4 level.** +- `16xy`: **set multiplier of operator.** + - `x` is the operator (1-4). + - `y` is the new MULT value.. +- `17xy`: **set vibrato depth.** + - `x` is the operator from 1 to 4. a value of `0` means "all operators". + - `y` is either `0` (normal) or `1` (double). +- `19xx`: **set attack of all operators.** +- `1Axx`: **set attack of operator 1.** +- `1Bxx`: **set attack of operator 2.** +- `1Cxx`: **set attack of operator 3.** +- `1Dxx`: **set attack of operator 4.** +- `20xy`: **set panning of operator 1.** + - `x` determines whether to output on left. + - `y` determines whether to output on right. +- `21xy`: **set panning of operator 2.** + - `x` determines whether to output on left. + - `y` determines whether to output on right. +- `22xy`: **set panning of operator 3.** + - `x` determines whether to output on left. + - `y` determines whether to output on right. +- `23xy`: **set panning of operator 4.** + - `x` determines whether to output on left. + - `y` determines whether to output on right. +- `24xy`: **set output level of operator.** + - `x` is the operator from 1 to 4. a value of `0` means "all operators". + - `y` is the value. +- `25xy`: **set modulation input level of operator.** + - `x` is the operator from 1 to 4. a value of `0` means "all operators". + - `y` is the value. +- `26xy`: **set envelope delay of operator.** + - `x` is the operator from 1 to 4. a value of `0` means "all operators". + - `y` is the value. +- `27xx`: **set operator 4 noise mode.** + - `0`: noise off + - `1`: square + noise + - `2`: ring mod from operator 3 + noise + - `3`: ring mod from operator 3 + double pitch modulation input + - note: emulation issues. subject to change! +- `2Axy`: **set waveform of operator.** + - `x` is the operator from 1 to 4. a value of `0` means "all operators". + - `y` is the value. +- `2Exx`: **enable envelope hard reset.** +- `2Fxy`: **set fixed frequency block (octave).** + - `x` is the operator from 1 to 4. + - `y` is the block/octave from 0 to 7. +- `3xyy`: **set fixed frequency f-num.** + - `x` contains operator number and high bits of f-num may be any of the following: + - `0` to `3` for operator 1 + - `4` to `7` for operator 2 + - `8` to `B` for operator 3 + - `C` to `F` for operator 4 + - `y` are the lower bits of f-num. +- `40xx`: **set operator 1 detune.** +- `41xx`: **set operator 1 detune.** +- `42xx`: **set operator 1 detune.** +- `43xx`: **set operator 1 detune.** +- `50xy`: **set AM of operator.** + - `x` is the operator from 1 to 4. a value of `0` means "all operators". + - `y` determines whether AM is on. +- `51xy`: **set SL of operator.** + - `x` is the operator from 1 to 4. a value of `0` means "all operators". + - `y` is the value. +- `52xy`: **set RR of operator.** + - `x` is the operator from 1 to 4. a value of `0` means "all operators". + - `y` is the value. +- `53xy`: **set VIB of operator.** + - `x` is the operator from 1 to 4. a value of `0` means "all operators". + - `y` determines whether VIB is on. +- `54xy`: **set KSL of operator.** + - `x` is the operator from 1 to 4. a value of `0` means "all operators". + - `y` is the value. +- `55xy`: **set SUS of operator.** + - `x` is the operator from 1 to 4. a value of `0` means "all operators". + - `y` determines whether SUS is on. +- `56xx`: **set DR of all operators.** +- `57xx`: **set DR of operator 1.** +- `58xx`: **set DR of operator 2.** +- `59xx`: **set DR of operator 3.** +- `5Axx`: **set DR of operator 4.** +- `5Bxy`: **set KSR of operator.** + - `x` is the operator from 1 to 4. a value of `0` means "all operators". + - `y` determines whether KSR is on. + +## info + +this chip uses the [FM (ESFM)](../4-instrument/fm-esfm.md) instrument editor. From 25475af0f90c46d4acce0d4b8f5961f5c60862db Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 17 Jan 2024 00:38:52 -0500 Subject: [PATCH 60/74] mention ESFM in doc (ins and sys list) --- doc/4-instrument/README.md | 1 + doc/7-systems/README.md | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/4-instrument/README.md b/doc/4-instrument/README.md index 1825371a7..1ba003c13 100644 --- a/doc/4-instrument/README.md +++ b/doc/4-instrument/README.md @@ -39,6 +39,7 @@ the following instrument types are available: - [VRC6](vrc6.md) - for use with VRC6's PSG sound source. - [FM (OPLL)](fm-opll.md) - for use with YM2413. - [FM (OPL)](fm-opll.md) - for use with YM3526 (OPL), YM3812 (OPL2) and YMF262 (OPL3). +- [FM (ESFM)](fm-esfm.md) - for use with ESFM. - [FDS](fds.md) - for use with Famicom Disk System sound source. - [Virtual Boy](virtual-boy.md) - for use with Virtual Boy. - [Namco 163](n163.md) - for use with Namco 163. diff --git a/doc/7-systems/README.md b/doc/7-systems/README.md index a8387d85e..4c1d09f98 100644 --- a/doc/7-systems/README.md +++ b/doc/7-systems/README.md @@ -108,8 +108,9 @@ this is the full list of chips that Furnace supports. - [VRC6](vrc6.md) - [WonderSwan](wonderswan.md) - [X1-010](x1-010.md) -- [VRC7, Y8950, YM3526, YM3812 and YMF262 (OPL)](opl.md) -- [YM2413 (OPLL)](opll.md) +- [Y8950, YM3526, YM3812 and YMF262 (OPL)](opl.md) +- [ESFM](esfm.md) +- [VRC7 and YM2413 (OPLL)](opll.md) - [YM2414 (OPZ)](opz.md) - [YM2151 (OPM)](ym2151.md) - [YM2203 (OPN)](ym2203.md) From a2b6dda2516e6d1aa20c9c93fa6a85147a803d3a Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 17 Jan 2024 00:39:27 -0500 Subject: [PATCH 61/74] update credits --- src/gui/about.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/about.cpp b/src/gui/about.cpp index 41ea34d7a..e00359046 100644 --- a/src/gui/about.cpp +++ b/src/gui/about.cpp @@ -39,6 +39,7 @@ const char* aboutLine[]={ "cam900", "djtuBIG-MaliceX", "Eknous", + "Kagamiin~", "laoo", "LTVA1", "MooingLemur", From 3cb8190258992563f9e67cbae728ea15f2c84f3c Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 17 Jan 2024 00:41:50 -0500 Subject: [PATCH 62/74] update credits again --- src/gui/about.cpp | 1 + src/main.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/gui/about.cpp b/src/gui/about.cpp index e00359046..64f2cbae5 100644 --- a/src/gui/about.cpp +++ b/src/gui/about.cpp @@ -194,6 +194,7 @@ const char* aboutLine[]={ "adpcm by superctr", "Nuked-OPL3/OPLL/OPM/OPN2/PSG by nukeykt", "YM3812-LLE, YMF262-LLE and YMF276-LLE by nukeykt", + "ESFMu by Kagamiin~", "ymfm by Aaron Giles", "MAME SN76496 by Nicola Salmoria", "MAME AY-3-8910 by Couriersud", diff --git a/src/main.cpp b/src/main.cpp index cbfdaa369..df9a9577f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -218,6 +218,7 @@ TAParamResult pVersion(String) { printf("- YM3812-LLE by nukeykt (GPLv2)\n"); printf("- YMF262-LLE by nukeykt (GPLv2)\n"); printf("- YMF276-LLE by nukeykt (GPLv2)\n"); + printf("- ESFMu by Kagamiin~ (LGPLv2.1)\n"); printf("- ymfm by Aaron Giles (BSD 3-clause)\n"); printf("- adpcm by superctr (public domain)\n"); printf("- MAME SN76496 emulation core by Nicola Salmoria (BSD 3-clause)\n"); From 7f94cdc930a80f8b916606540bed71dfcae3d4d0 Mon Sep 17 00:00:00 2001 From: LTVA1 <87536432+LTVA1@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:28:29 +0300 Subject: [PATCH 63/74] port macro retrigger to orig Furnace --- doc/3-pattern/effects.md | 2 + src/engine/cmdStream.cpp | 1 + src/engine/cmdStreamOps.cpp | 1 + src/engine/dispatch.h | 1 + src/engine/engine.cpp | 2 + src/engine/macroInt.cpp | 71 ++++++++++++++++++++++++ src/engine/macroInt.h | 5 ++ src/engine/platform/amiga.cpp | 3 + src/engine/platform/arcade.cpp | 3 + src/engine/platform/ay.cpp | 3 + src/engine/platform/ay8930.cpp | 3 + src/engine/platform/bubsyswsg.cpp | 3 + src/engine/platform/c140.cpp | 3 + src/engine/platform/c64.cpp | 3 + src/engine/platform/es5506.cpp | 3 + src/engine/platform/esfm.cpp | 3 + src/engine/platform/fds.cpp | 3 + src/engine/platform/ga20.cpp | 3 + src/engine/platform/gb.cpp | 3 + src/engine/platform/genesis.cpp | 3 + src/engine/platform/k007232.cpp | 3 + src/engine/platform/k053260.cpp | 3 + src/engine/platform/lynx.cpp | 3 + src/engine/platform/mmc5.cpp | 3 + src/engine/platform/msm5232.cpp | 3 + src/engine/platform/msm6258.cpp | 3 + src/engine/platform/msm6295.cpp | 3 + src/engine/platform/n163.cpp | 3 + src/engine/platform/namcowsg.cpp | 3 + src/engine/platform/nes.cpp | 3 + src/engine/platform/opl.cpp | 3 + src/engine/platform/opll.cpp | 3 + src/engine/platform/pce.cpp | 3 + src/engine/platform/pcmdac.cpp | 3 + src/engine/platform/pcspkr.cpp | 3 + src/engine/platform/pet.cpp | 3 + src/engine/platform/pokemini.cpp | 3 + src/engine/platform/pokey.cpp | 3 + src/engine/platform/pong.cpp | 3 + src/engine/platform/pv1000.cpp | 3 + src/engine/platform/qsound.cpp | 3 + src/engine/platform/rf5c68.cpp | 3 + src/engine/platform/saa.cpp | 3 + src/engine/platform/scc.cpp | 3 + src/engine/platform/segapcm.cpp | 3 + src/engine/platform/sm8521.cpp | 3 + src/engine/platform/sms.cpp | 3 + src/engine/platform/snes.cpp | 3 + src/engine/platform/su.cpp | 3 + src/engine/platform/swan.cpp | 3 + src/engine/platform/t6w28.cpp | 3 + src/engine/platform/ted.cpp | 3 + src/engine/platform/tia.cpp | 3 + src/engine/platform/tx81z.cpp | 3 + src/engine/platform/vb.cpp | 3 + src/engine/platform/vera.cpp | 3 + src/engine/platform/vic20.cpp | 3 + src/engine/platform/vrc6.cpp | 3 + src/engine/platform/x1_010.cpp | 3 + src/engine/platform/ym2203.cpp | 3 + src/engine/platform/ym2608.cpp | 3 + src/engine/platform/ym2610.cpp | 3 + src/engine/platform/ym2610b.cpp | 3 + src/engine/platform/ymz280b.cpp | 3 + src/engine/platform/zxbeeper.cpp | 3 + src/engine/platform/zxbeeperquadtone.cpp | 3 + src/engine/playback.cpp | 4 ++ src/gui/guiConst.cpp | 2 +- 68 files changed, 265 insertions(+), 1 deletion(-) diff --git a/doc/3-pattern/effects.md b/doc/3-pattern/effects.md index c76826c02..152ff23df 100644 --- a/doc/3-pattern/effects.md +++ b/doc/3-pattern/effects.md @@ -93,7 +93,9 @@ not all chips support these effects. - this effect is currently incomplete. - `F5xx`: **Disable macro.** - `F6xx`: **Enable macro.** +- `F7xx`: **Retrigger macro.** - see macro table at the end of this document for possible values. + - `F7xx` resets LFO macro phase to the phase that is set in instrument macro settings. additionally, [each chip has its own effects](../7-systems/README.md). diff --git a/src/engine/cmdStream.cpp b/src/engine/cmdStream.cpp index 841524f46..16301f7d7 100644 --- a/src/engine/cmdStream.cpp +++ b/src/engine/cmdStream.cpp @@ -233,6 +233,7 @@ bool DivCSPlayer::tick() { case DIV_CMD_AMIGA_PM: case DIV_CMD_MACRO_OFF: case DIV_CMD_MACRO_ON: + case DIV_CMD_MACRO_RETRIG: arg0=(unsigned char)stream.readC(); break; case DIV_CMD_FM_TL: diff --git a/src/engine/cmdStreamOps.cpp b/src/engine/cmdStreamOps.cpp index 4ba6cd893..cc1094ae3 100644 --- a/src/engine/cmdStreamOps.cpp +++ b/src/engine/cmdStreamOps.cpp @@ -153,6 +153,7 @@ void writePackedCommandValues(SafeWriter* w, const DivCommand& c) { case DIV_CMD_AMIGA_PM: case DIV_CMD_MACRO_OFF: case DIV_CMD_MACRO_ON: + case DIV_CMD_MACRO_RETRIG: case DIV_CMD_HINT_ARP_TIME: w->writeC(1); // length w->writeC(c.value); diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 4f9812caa..c5babefc3 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -213,6 +213,7 @@ enum DivDispatchCmds { DIV_CMD_MACRO_OFF, // (which) DIV_CMD_MACRO_ON, // (which) + DIV_CMD_MACRO_RETRIG, // (which) DIV_CMD_SURROUND_PANNING, // (out, val) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 809dc87b4..81937b99c 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -129,6 +129,8 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul return "F5xx: Disable macro (see manual)"; case 0xf6: return "F6xx: Enable macro (see manual)"; + case 0xf7: + return "F7xx: Retrigger macro (see manual)"; case 0xf8: return "F8xx: Single tick volume slide up"; case 0xf9: diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index 0599d3966..1876bc2e4 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -245,6 +245,77 @@ void DivMacroInt::mask(unsigned char id, bool enabled) { #undef CONSIDER_OP #undef CONSIDER +void DivMacroInt::retrig(unsigned char id) +{ + if(id < 0x20) + { + DivMacroStruct* m = NULL; + DivInstrumentMacro* sm = NULL; + + for(int i = 0; i < macroListLen; i++) + { + if(macroList[i]->macroType == id) + { + m = macroList[i]; + sm = macroSource[i]; + break; + } + } + + if(sm == NULL || m == NULL) return; + if(sm->len == 0 && m->type == 0) return; + + m->has=m->had=m->actualHad=m->will=true; + m->lfoPos = sm->val[13]; + m->pos = 0; + m->lastPos = 0; + m->delay = 0; + } + + else //here we can't run the search since macros share ID + { + DivMacroStruct* m = NULL; + DivInstrumentMacro* sm = NULL; + + int oper = (id >> 5) - 1; + int type = (id & 0x1f) + 0x20; + + switch(type) + { + case DIV_MACRO_OP_AM: m = &op[oper].am; sm = &ins->std.opMacros[oper].amMacro; break; + case DIV_MACRO_OP_AR: m = &op[oper].ar; sm = &ins->std.opMacros[oper].arMacro; break; + case DIV_MACRO_OP_DR: m = &op[oper].dr; sm = &ins->std.opMacros[oper].drMacro; break; + case DIV_MACRO_OP_MULT: m = &op[oper].mult; sm = &ins->std.opMacros[oper].multMacro; break; + case DIV_MACRO_OP_RR: m = &op[oper].rr; sm = &ins->std.opMacros[oper].rrMacro; break; + case DIV_MACRO_OP_SL: m = &op[oper].sl; sm = &ins->std.opMacros[oper].slMacro; break; + case DIV_MACRO_OP_TL: m = &op[oper].tl; sm = &ins->std.opMacros[oper].tlMacro; break; + case DIV_MACRO_OP_DT2: m = &op[oper].dt2; sm = &ins->std.opMacros[oper].dt2Macro; break; + case DIV_MACRO_OP_RS: m = &op[oper].rs; sm = &ins->std.opMacros[oper].rsMacro; break; + case DIV_MACRO_OP_DT: m = &op[oper].dt; sm = &ins->std.opMacros[oper].dtMacro; break; + case DIV_MACRO_OP_D2R: m = &op[oper].d2r; sm = &ins->std.opMacros[oper].d2rMacro; break; + case DIV_MACRO_OP_SSG: m = &op[oper].ssg; sm = &ins->std.opMacros[oper].ssgMacro; break; + case DIV_MACRO_OP_DAM: m = &op[oper].dam; sm = &ins->std.opMacros[oper].damMacro; break; + case DIV_MACRO_OP_DVB: m = &op[oper].dvb; sm = &ins->std.opMacros[oper].dvbMacro; break; + case DIV_MACRO_OP_EGT: m = &op[oper].egt; sm = &ins->std.opMacros[oper].egtMacro; break; + case DIV_MACRO_OP_KSL: m = &op[oper].ksl; sm = &ins->std.opMacros[oper].kslMacro; break; + case DIV_MACRO_OP_SUS: m = &op[oper].sus; sm = &ins->std.opMacros[oper].susMacro; break; + case DIV_MACRO_OP_VIB: m = &op[oper].vib; sm = &ins->std.opMacros[oper].vibMacro; break; + case DIV_MACRO_OP_WS: m = &op[oper].ws; sm = &ins->std.opMacros[oper].wsMacro; break; + case DIV_MACRO_OP_KSR: m = &op[oper].ksr; sm = &ins->std.opMacros[oper].ksrMacro; break; + default: return; break; + } + + if(sm == NULL || m == NULL) return; + if(sm->len == 0 && m->type == 0) return; + + m->has=m->had=m->actualHad=m->will=true; + m->lfoPos = sm->val[13]; + m->pos = 0; + m->lastPos = 0; + m->delay = 0; + } +} + void DivMacroInt::release() { released=true; } diff --git a/src/engine/macroInt.h b/src/engine/macroInt.h index 4c100562c..7e01dd080 100644 --- a/src/engine/macroInt.h +++ b/src/engine/macroInt.h @@ -119,6 +119,11 @@ class DivMacroInt { */ void release(); + /** + * retrigger macro. + */ + void retrig(unsigned char id); + /** * trigger next macro tick. */ diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index 107c1493a..a8ac48408 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -721,6 +721,9 @@ int DivPlatformAmiga::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index b760d8e6a..50ab1c917 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -783,6 +783,9 @@ int DivPlatformArcade::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: return 127; break; diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index 823b0b3a1..6996fb3df 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -651,6 +651,9 @@ int DivPlatformAY8910::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: return 15; break; diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 4fc32ac5c..b99c60acc 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -653,6 +653,9 @@ int DivPlatformAY8930::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: return 31; break; diff --git a/src/engine/platform/bubsyswsg.cpp b/src/engine/platform/bubsyswsg.cpp index 452fb8f89..fbc5f6d18 100644 --- a/src/engine/platform/bubsyswsg.cpp +++ b/src/engine/platform/bubsyswsg.cpp @@ -246,6 +246,9 @@ int DivPlatformBubSysWSG::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/c140.cpp b/src/engine/platform/c140.cpp index 46f793a9a..508560198 100644 --- a/src/engine/platform/c140.cpp +++ b/src/engine/platform/c140.cpp @@ -441,6 +441,9 @@ int DivPlatformC140::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 4c3245b82..2aae1f068 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -536,6 +536,9 @@ int DivPlatformC64::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/es5506.cpp b/src/engine/platform/es5506.cpp index 0121d19d5..5c5253dea 100644 --- a/src/engine/platform/es5506.cpp +++ b/src/engine/platform/es5506.cpp @@ -1022,6 +1022,9 @@ int DivPlatformES5506::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 1981b855d..11609c931 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -920,6 +920,9 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: return 63; break; diff --git a/src/engine/platform/fds.cpp b/src/engine/platform/fds.cpp index 1afcd0df0..c6bd2e82b 100644 --- a/src/engine/platform/fds.cpp +++ b/src/engine/platform/fds.cpp @@ -387,6 +387,9 @@ int DivPlatformFDS::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/ga20.cpp b/src/engine/platform/ga20.cpp index a2ff81eb3..295032fad 100644 --- a/src/engine/platform/ga20.cpp +++ b/src/engine/platform/ga20.cpp @@ -311,6 +311,9 @@ int DivPlatformGA20::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index 4f9c85960..100e882ab 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -553,6 +553,9 @@ int DivPlatformGB::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 9a2b514d0..b71d27fd7 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -1183,6 +1183,9 @@ int DivPlatformGenesis::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: return 127; break; diff --git a/src/engine/platform/k007232.cpp b/src/engine/platform/k007232.cpp index ba742a2dc..9be466338 100644 --- a/src/engine/platform/k007232.cpp +++ b/src/engine/platform/k007232.cpp @@ -395,6 +395,9 @@ int DivPlatformK007232::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index 2af1d5bd3..2c7551662 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -345,6 +345,9 @@ int DivPlatformK053260::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/lynx.cpp b/src/engine/platform/lynx.cpp index 909e4b20c..b12962aa3 100644 --- a/src/engine/platform/lynx.cpp +++ b/src/engine/platform/lynx.cpp @@ -353,6 +353,9 @@ int DivPlatformLynx::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/mmc5.cpp b/src/engine/platform/mmc5.cpp index 656288c6a..5d22a0310 100644 --- a/src/engine/platform/mmc5.cpp +++ b/src/engine/platform/mmc5.cpp @@ -327,6 +327,9 @@ int DivPlatformMMC5::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/msm5232.cpp b/src/engine/platform/msm5232.cpp index ef4e14afc..9a3fa0367 100644 --- a/src/engine/platform/msm5232.cpp +++ b/src/engine/platform/msm5232.cpp @@ -297,6 +297,9 @@ int DivPlatformMSM5232::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/msm6258.cpp b/src/engine/platform/msm6258.cpp index 1b7b2434b..4d6bd0029 100644 --- a/src/engine/platform/msm6258.cpp +++ b/src/engine/platform/msm6258.cpp @@ -268,6 +268,9 @@ int DivPlatformMSM6258::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: return 8; break; diff --git a/src/engine/platform/msm6295.cpp b/src/engine/platform/msm6295.cpp index 8ca92d9fb..563a085ba 100644 --- a/src/engine/platform/msm6295.cpp +++ b/src/engine/platform/msm6295.cpp @@ -226,6 +226,9 @@ int DivPlatformMSM6295::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: return 8; break; diff --git a/src/engine/platform/n163.cpp b/src/engine/platform/n163.cpp index c1320ef1a..2bcd101db 100644 --- a/src/engine/platform/n163.cpp +++ b/src/engine/platform/n163.cpp @@ -452,6 +452,9 @@ int DivPlatformN163::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/namcowsg.cpp b/src/engine/platform/namcowsg.cpp index 7c56b1c5e..888319991 100644 --- a/src/engine/platform/namcowsg.cpp +++ b/src/engine/platform/namcowsg.cpp @@ -445,6 +445,9 @@ int DivPlatformNamcoWSG::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 1b15c5da5..1e55c7fb5 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -659,6 +659,9 @@ int DivPlatformNES::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 088c72f38..ec2d86517 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1970,6 +1970,9 @@ int DivPlatformOPL::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: if (c.chan==adpcmChan) return 255; if (pretendYMU) return 127; diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index 1c0831c35..b1577e657 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -853,6 +853,9 @@ int DivPlatformOPLL::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: return 15; break; diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index f28fb5a8d..3bb517547 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -474,6 +474,9 @@ int DivPlatformPCE::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/pcmdac.cpp b/src/engine/platform/pcmdac.cpp index 7d242f556..b30755b42 100644 --- a/src/engine/platform/pcmdac.cpp +++ b/src/engine/platform/pcmdac.cpp @@ -452,6 +452,9 @@ int DivPlatformPCMDAC::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/pcspkr.cpp b/src/engine/platform/pcspkr.cpp index ee0051cbd..73a4f87fa 100644 --- a/src/engine/platform/pcspkr.cpp +++ b/src/engine/platform/pcspkr.cpp @@ -476,6 +476,9 @@ int DivPlatformPCSpeaker::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/pet.cpp b/src/engine/platform/pet.cpp index 17e044d03..da1cf68d9 100644 --- a/src/engine/platform/pet.cpp +++ b/src/engine/platform/pet.cpp @@ -239,6 +239,9 @@ int DivPlatformPET::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/pokemini.cpp b/src/engine/platform/pokemini.cpp index b589adbbd..4623f3a63 100644 --- a/src/engine/platform/pokemini.cpp +++ b/src/engine/platform/pokemini.cpp @@ -253,6 +253,9 @@ int DivPlatformPokeMini::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/pokey.cpp b/src/engine/platform/pokey.cpp index ecab418f9..ede9345e9 100644 --- a/src/engine/platform/pokey.cpp +++ b/src/engine/platform/pokey.cpp @@ -374,6 +374,9 @@ int DivPlatformPOKEY::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/pong.cpp b/src/engine/platform/pong.cpp index f2cfb3e1c..3e2a4bc6a 100644 --- a/src/engine/platform/pong.cpp +++ b/src/engine/platform/pong.cpp @@ -180,6 +180,9 @@ int DivPlatformPong::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/pv1000.cpp b/src/engine/platform/pv1000.cpp index abfe9f990..20a1847a7 100644 --- a/src/engine/platform/pv1000.cpp +++ b/src/engine/platform/pv1000.cpp @@ -188,6 +188,9 @@ int DivPlatformPV1000::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/qsound.cpp b/src/engine/platform/qsound.cpp index f8ae9d3c4..3991a4ec1 100644 --- a/src/engine/platform/qsound.cpp +++ b/src/engine/platform/qsound.cpp @@ -587,6 +587,9 @@ int DivPlatformQSound::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/rf5c68.cpp b/src/engine/platform/rf5c68.cpp index ce2723e34..8e1f5179e 100644 --- a/src/engine/platform/rf5c68.cpp +++ b/src/engine/platform/rf5c68.cpp @@ -291,6 +291,9 @@ int DivPlatformRF5C68::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/saa.cpp b/src/engine/platform/saa.cpp index 93a40579e..c5bae98ea 100644 --- a/src/engine/platform/saa.cpp +++ b/src/engine/platform/saa.cpp @@ -316,6 +316,9 @@ int DivPlatformSAA1099::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: return 15; break; diff --git a/src/engine/platform/scc.cpp b/src/engine/platform/scc.cpp index f0075822e..239b171a1 100644 --- a/src/engine/platform/scc.cpp +++ b/src/engine/platform/scc.cpp @@ -261,6 +261,9 @@ int DivPlatformSCC::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index c2dc6f3d5..1d9543d56 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -339,6 +339,9 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: return 127; break; diff --git a/src/engine/platform/sm8521.cpp b/src/engine/platform/sm8521.cpp index 55430c552..f11cb4d66 100644 --- a/src/engine/platform/sm8521.cpp +++ b/src/engine/platform/sm8521.cpp @@ -277,6 +277,9 @@ int DivPlatformSM8521::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 83351e855..4c3007a7a 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -420,6 +420,9 @@ int DivPlatformSMS::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/snes.cpp b/src/engine/platform/snes.cpp index 0b7860b66..4c9a02307 100644 --- a/src/engine/platform/snes.cpp +++ b/src/engine/platform/snes.cpp @@ -587,6 +587,9 @@ int DivPlatformSNES::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index 891bab206..e82fdb219 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -502,6 +502,9 @@ int DivPlatformSoundUnit::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index 0f7b6911f..51e76b5d9 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -446,6 +446,9 @@ int DivPlatformSwan::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/t6w28.cpp b/src/engine/platform/t6w28.cpp index 138d395be..f4a58e9e0 100644 --- a/src/engine/platform/t6w28.cpp +++ b/src/engine/platform/t6w28.cpp @@ -271,6 +271,9 @@ int DivPlatformT6W28::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/ted.cpp b/src/engine/platform/ted.cpp index 5078a9a37..05f1f97ba 100644 --- a/src/engine/platform/ted.cpp +++ b/src/engine/platform/ted.cpp @@ -236,6 +236,9 @@ int DivPlatformTED::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/tia.cpp b/src/engine/platform/tia.cpp index d49d00af6..3157fc223 100644 --- a/src/engine/platform/tia.cpp +++ b/src/engine/platform/tia.cpp @@ -258,6 +258,9 @@ int DivPlatformTIA::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: return 15; break; diff --git a/src/engine/platform/tx81z.cpp b/src/engine/platform/tx81z.cpp index 7d68342be..8c2d21851 100644 --- a/src/engine/platform/tx81z.cpp +++ b/src/engine/platform/tx81z.cpp @@ -880,6 +880,9 @@ int DivPlatformTX81Z::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: return 127; break; diff --git a/src/engine/platform/vb.cpp b/src/engine/platform/vb.cpp index c0e5b49af..b40998976 100644 --- a/src/engine/platform/vb.cpp +++ b/src/engine/platform/vb.cpp @@ -395,6 +395,9 @@ int DivPlatformVB::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/vera.cpp b/src/engine/platform/vera.cpp index 48b800672..b2445475c 100644 --- a/src/engine/platform/vera.cpp +++ b/src/engine/platform/vera.cpp @@ -434,6 +434,9 @@ int DivPlatformVERA::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_EXTERNAL: rWriteZSMSync(c.value); break; diff --git a/src/engine/platform/vic20.cpp b/src/engine/platform/vic20.cpp index 66a11fadd..d110dca49 100644 --- a/src/engine/platform/vic20.cpp +++ b/src/engine/platform/vic20.cpp @@ -252,6 +252,9 @@ int DivPlatformVIC20::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/vrc6.cpp b/src/engine/platform/vrc6.cpp index 3b2f660ac..98e6e524d 100644 --- a/src/engine/platform/vrc6.cpp +++ b/src/engine/platform/vrc6.cpp @@ -412,6 +412,9 @@ int DivPlatformVRC6::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index e5cfe72ac..b3ce96cdf 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -832,6 +832,9 @@ int DivPlatformX1_010::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index a666a62b9..50682eed3 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -861,6 +861,9 @@ int DivPlatformYM2203::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: if (c.chan>2) return 15; return 127; diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 7738ae979..e2dce991f 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -1352,6 +1352,9 @@ int DivPlatformYM2608::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: if (c.chan>14) return 255; if (c.chan>8) return 31; diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index e982fe086..6ed818058 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -1324,6 +1324,9 @@ int DivPlatformYM2610::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: if (c.chan>=adpcmBChanOffs) return 255; if (c.chan>=adpcmAChanOffs) return 31; diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 6c183a57d..cf2dfe87d 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -1391,6 +1391,9 @@ int DivPlatformYM2610B::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; case DIV_CMD_GET_VOLMAX: if (c.chan>=adpcmBChanOffs) return 255; if (c.chan>=adpcmAChanOffs) return 31; diff --git a/src/engine/platform/ymz280b.cpp b/src/engine/platform/ymz280b.cpp index 4158b4fa9..0c5c37179 100644 --- a/src/engine/platform/ymz280b.cpp +++ b/src/engine/platform/ymz280b.cpp @@ -321,6 +321,9 @@ int DivPlatformYMZ280B::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/zxbeeper.cpp b/src/engine/platform/zxbeeper.cpp index 70272613a..7a0c0ed7c 100644 --- a/src/engine/platform/zxbeeper.cpp +++ b/src/engine/platform/zxbeeper.cpp @@ -218,6 +218,9 @@ int DivPlatformZXBeeper::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/platform/zxbeeperquadtone.cpp b/src/engine/platform/zxbeeperquadtone.cpp index 35a8a5d1d..d1591e30a 100644 --- a/src/engine/platform/zxbeeperquadtone.cpp +++ b/src/engine/platform/zxbeeperquadtone.cpp @@ -288,6 +288,9 @@ int DivPlatformZXBeeperQuadTone::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RETRIG: + chan[c.chan].std.retrig(c.value); + break; default: break; } diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 06ce4ed1c..d634ec674 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -212,6 +212,7 @@ const char* cmdName[]={ "MACRO_OFF", "MACRO_ON", + "MACRO_RETRIG", "SURROUND_PANNING", @@ -1006,6 +1007,9 @@ void DivEngine::processRow(int i, bool afterDelay) { case 0xf6: // enable macro dispatchCmd(DivCommand(DIV_CMD_MACRO_ON,i,effectVal&0xff)); break; + case 0xf7: // retrigger macro + dispatchCmd(DivCommand(DIV_CMD_MACRO_RETRIG,i,effectVal&0xff)); + break; case 0xf8: // single volume ramp up chan[i].volume=MIN(chan[i].volume+effectVal*256,chan[i].volMax); dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8)); diff --git a/src/gui/guiConst.cpp b/src/gui/guiConst.cpp index 900669dd0..f48b8b906 100644 --- a/src/gui/guiConst.cpp +++ b/src/gui/guiConst.cpp @@ -516,7 +516,7 @@ const FurnaceGUIColors fxColors[256]={ GUI_COLOR_PATTERN_EFFECT_VOLUME, // F4 GUI_COLOR_PATTERN_EFFECT_MISC, // F5 GUI_COLOR_PATTERN_EFFECT_MISC, // F6 - GUI_COLOR_PATTERN_EFFECT_INVALID, // F7 + GUI_COLOR_PATTERN_EFFECT_MISC, // F7 GUI_COLOR_PATTERN_EFFECT_VOLUME, // F8 GUI_COLOR_PATTERN_EFFECT_VOLUME, // F9 GUI_COLOR_PATTERN_EFFECT_VOLUME, // FA From 91c3fba181de2e53143a3f280034b8e8b174b646 Mon Sep 17 00:00:00 2001 From: LTVA1 <87536432+LTVA1@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:37:18 +0300 Subject: [PATCH 64/74] fix --- src/engine/macroInt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index 1876bc2e4..6698a93b3 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -252,7 +252,7 @@ void DivMacroInt::retrig(unsigned char id) DivMacroStruct* m = NULL; DivInstrumentMacro* sm = NULL; - for(int i = 0; i < macroListLen; i++) + for(int i = 0; i < (int)macroListLen; i++) { if(macroList[i]->macroType == id) { From cb38cf8f67dec415eed61ab82fbf52444b8c825b Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 17 Jan 2024 10:33:02 -0300 Subject: [PATCH 65/74] Updating ESFMu to version v1.1.1 (envelope delay patch) --- extern/ESFMu/esfm.c | 34 ++++++++++++++++++++++++++++------ extern/ESFMu/esfm.h | 5 +++++ extern/ESFMu/esfm_registers.c | 8 ++++++++ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/extern/ESFMu/esfm.c b/extern/ESFMu/esfm.c index 54af9cc30..277927096 100644 --- a/extern/ESFMu/esfm.c +++ b/extern/ESFMu/esfm.c @@ -374,7 +374,6 @@ ESFM_envelope_calc(esfm_slot *slot) bool reset = 0; bool key_on; bool key_on_signal; - uint16 delay_counter_compare; key_on = *slot->in.key_on; if (!slot->chip->native_mode) @@ -421,19 +420,42 @@ ESFM_envelope_calc(esfm_slot *slot) { slot->in.eg_delay_run = 1; slot->in.eg_delay_counter = 0; + slot->in.eg_delay_transitioned_01 = 0; + slot->in.eg_delay_transitioned_01_gate = 0; + slot->in.eg_delay_transitioned_10 = 0; + slot->in.eg_delay_transitioned_10_gate = 0; + slot->in.eg_delay_counter_compare = 0; + if (slot->env_delay > 0) + { + slot->in.eg_delay_counter_compare = 256 << slot->env_delay; + } } else if (!key_on) { slot->in.eg_delay_run = 0; } - delay_counter_compare = 0; - if (slot->env_delay > 0) + // TODO: is this really how the chip behaves? Can it only transition the envelope delay once? Am I implementing this in a sane way? I feel like this is a roundabout hack. + if ((slot->in.eg_delay_transitioned_10 && !slot->in.eg_delay_transitioned_10_gate) || + (slot->in.eg_delay_transitioned_01 && !slot->in.eg_delay_transitioned_01_gate) + ) { - delay_counter_compare = 256 << slot->env_delay; + slot->in.eg_delay_counter_compare = 0; + if (slot->env_delay > 0) + { + slot->in.eg_delay_counter_compare = 256 << slot->env_delay; + } + if (slot->in.eg_delay_transitioned_10) + { + slot->in.eg_delay_transitioned_10_gate = 1; + } + if (slot->in.eg_delay_transitioned_01) + { + slot->in.eg_delay_transitioned_01_gate = 1; + } } - if (key_on && ((slot->in.eg_delay_counter >= delay_counter_compare) || !slot->chip->native_mode)) + if (key_on && ((slot->in.eg_delay_counter >= slot->in.eg_delay_counter_compare) || !slot->chip->native_mode)) { key_on_signal = 1; } else { @@ -443,7 +465,7 @@ ESFM_envelope_calc(esfm_slot *slot) if (key_on && slot->in.eg_state == EG_RELEASE) { - if ((slot->in.eg_delay_counter >= delay_counter_compare) || !slot->chip->native_mode) + if ((slot->in.eg_delay_counter >= slot->in.eg_delay_counter_compare) || !slot->chip->native_mode) { reset = 1; reg_rate = slot->attack_rate; diff --git a/extern/ESFMu/esfm.h b/extern/ESFMu/esfm.h index d5c734b49..f410558eb 100644 --- a/extern/ESFMu/esfm.h +++ b/extern/ESFMu/esfm.h @@ -174,7 +174,12 @@ typedef struct _esfm_slot_internal uint2 eg_state; flag eg_delay_run; + flag eg_delay_transitioned_10; + flag eg_delay_transitioned_10_gate; + flag eg_delay_transitioned_01; + flag eg_delay_transitioned_01_gate; uint16 eg_delay_counter; + uint16 eg_delay_counter_compare; } esfm_slot_internal; diff --git a/extern/ESFMu/esfm_registers.c b/extern/ESFMu/esfm_registers.c index 789c68ea7..d87a5944f 100644 --- a/extern/ESFMu/esfm_registers.c +++ b/extern/ESFMu/esfm_registers.c @@ -365,6 +365,14 @@ ESFM_slot_write (esfm_slot *slot, uint8_t register_idx, uint8_t data) ESFM_slot_update_keyscale(slot); break; case 0x05: + if (slot->env_delay < (data >> 5)) + { + slot->in.eg_delay_transitioned_01 = 1; + } + else if (slot->env_delay > (data >> 5)) + { + slot->in.eg_delay_transitioned_10 = 1; + } slot->env_delay = data >> 5; slot->emu_key_on = (data >> 5) & 0x01; slot->block = (data >> 2) & 0x07; From 514c642b601d9ead283b886eb025a613fe793699 Mon Sep 17 00:00:00 2001 From: Kagamiin~ Date: Wed, 17 Jan 2024 10:37:23 -0300 Subject: [PATCH 66/74] Fix ESFM blank instrument; fix ESFM envelope drawing Co-authored-by: LTVA1 <87536432+LTVA1@users.noreply.github.com> --- src/gui/doAction.cpp | 5 +++++ src/gui/insEdit.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gui/doAction.cpp b/src/gui/doAction.cpp index f27f0a09d..0d43a2eea 100644 --- a/src/gui/doAction.cpp +++ b/src/gui/doAction.cpp @@ -643,6 +643,11 @@ void FurnaceGUI::doAction(int what) { e->song.ins[curIns]->fm.op[i].rr=15; e->song.ins[curIns]->fm.op[i].tl=127; e->song.ins[curIns]->fm.op[i].dt=3; + + e->song.ins[curIns]->esfm.op[i].ct=0; + e->song.ins[curIns]->esfm.op[i].dt=0; + e->song.ins[curIns]->esfm.op[i].modIn=0; + e->song.ins[curIns]->esfm.op[i].outLvl=0; } } wantScrollList=true; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 49e7f476c..e96d1b64e 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -1338,7 +1338,7 @@ void FurnaceGUI::drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, //addAALine(dl,pos3,posSLineVEnd,colorS); //draw vert. line through sustain level addAALine(dl,pos1,pos2,color); //A addAALine(dl,pos2,posDecayRate0Pt,color); //Line from A to end of graph - } else if (d2r==0.0 || ((instType==DIV_INS_OPL || instType==DIV_INS_SNES) && sus==1.0) || (instType==DIV_INS_OPLL && egt!=0.0)) { //envelope stays at the sustain level forever + } else if (d2r==0.0 || ((instType==DIV_INS_OPL || instType==DIV_INS_SNES || instType==DIV_INS_ESFM) && sus==1.0) || (instType==DIV_INS_OPLL && egt!=0.0)) { //envelope stays at the sustain level forever dl->AddTriangleFilled(posRStart,posREnd,pos1,colorS); //draw release as shaded triangle behind everything addAALine(dl,pos3,posSLineHEnd,colorR); //draw horiz line through sustain level addAALine(dl,pos3,posSLineVEnd,colorR); //draw vert. line through sustain level From ee2f407ae0f507089285f9f348134a38651d35e7 Mon Sep 17 00:00:00 2001 From: James Alan Nguyen Date: Wed, 17 Jan 2024 21:34:54 +1100 Subject: [PATCH 67/74] contrib esfm patches for foinace --- instruments/ESFM/djtBMX_1chostinato.fui | Bin 0 -> 259 bytes instruments/ESFM/djtBMX_4opBassESFM.fui | Bin 0 -> 92 bytes instruments/ESFM/djtBMX_4opESFMStrings.fui | Bin 0 -> 126 bytes instruments/ESFM/djtBMX_4opESFMStrings2.fui | Bin 0 -> 127 bytes instruments/ESFM/djtBMX_4opESFMStrings3.fui | Bin 0 -> 127 bytes instruments/ESFM/djtBMX_4opESFMStrings4.fui | Bin 0 -> 127 bytes instruments/ESFM/djtBMX_4opRubbaBassESFM.fui | Bin 0 -> 97 bytes instruments/ESFM/djtBMX_ESFMBRAS.fui | Bin 0 -> 89 bytes instruments/ESFM/djtBMX_ESFMBRASSSECT.fui | Bin 0 -> 93 bytes instruments/ESFM/djtBMX_ESFMGIT.fui | Bin 0 -> 88 bytes instruments/ESFM/djtBMX_ESFMPWM.fui | Bin 0 -> 88 bytes instruments/ESFM/djtBMX_ESFMSYN.fui | Bin 0 -> 88 bytes instruments/ESFM/djtBMX_ESFMresobell-short.fui | Bin 0 -> 99 bytes instruments/ESFM/djtBMX_ESFMresobell.fui | Bin 0 -> 93 bytes instruments/ESFM/djtBMX_ESFMresopipe.fui | Bin 0 -> 93 bytes instruments/ESFM/djtBMX_PULSELESSBUZZER.fui | Bin 0 -> 114 bytes instruments/ESFM/djtBMX_analogoctbas.fui | Bin 0 -> 94 bytes instruments/ESFM/djtBMX_bells.fui | Bin 0 -> 90 bytes instruments/ESFM/djtBMX_brarsesin.fui | Bin 0 -> 106 bytes instruments/ESFM/djtBMX_brassin.fui | Bin 0 -> 121 bytes instruments/ESFM/djtBMX_bwaro.fui | Bin 0 -> 102 bytes instruments/ESFM/djtBMX_chorbel.fui | Bin 0 -> 90 bytes instruments/ESFM/djtBMX_chorpad.fui | Bin 0 -> 86 bytes instruments/ESFM/djtBMX_clanger.fui | Bin 0 -> 104 bytes instruments/ESFM/djtBMX_clanger2.fui | Bin 0 -> 122 bytes instruments/ESFM/djtBMX_clanger3.fui | Bin 0 -> 108 bytes instruments/ESFM/djtBMX_clanger4.fui | Bin 0 -> 118 bytes instruments/ESFM/djtBMX_compile-basskick.fui | Bin 0 -> 90 bytes instruments/ESFM/djtBMX_compile-closehh.fui | Bin 0 -> 93 bytes instruments/ESFM/djtBMX_compile-marimba.fui | Bin 0 -> 108 bytes instruments/ESFM/djtBMX_compile-openhh.fui | Bin 0 -> 109 bytes instruments/ESFM/djtBMX_compile-padbrass.fui | Bin 0 -> 117 bytes instruments/ESFM/djtBMX_compile-sinetom.fui | Bin 0 -> 102 bytes instruments/ESFM/djtBMX_compile-snare.fui | Bin 0 -> 87 bytes instruments/ESFM/djtBMX_compile-springbass.fui | Bin 0 -> 95 bytes instruments/ESFM/djtBMX_compileagogo.fui | Bin 0 -> 165 bytes instruments/ESFM/djtBMX_compilebrass.fui | Bin 0 -> 128 bytes instruments/ESFM/djtBMX_compilefartbass.fui | Bin 0 -> 154 bytes instruments/ESFM/djtBMX_didgeritune.fui | Bin 0 -> 108 bytes instruments/ESFM/djtBMX_drlead.fui | Bin 0 -> 85 bytes instruments/ESFM/djtBMX_egless-kick.fui | Bin 0 -> 92 bytes instruments/ESFM/djtBMX_explosion.fui | Bin 0 -> 107 bytes instruments/ESFM/djtBMX_falcomkey.fui | Bin 0 -> 91 bytes instruments/ESFM/djtBMX_gitbsyn3.fui | Bin 0 -> 89 bytes instruments/ESFM/djtBMX_gitbsyn4.fui | Bin 0 -> 89 bytes instruments/ESFM/djtBMX_gitsyn2.fui | Bin 0 -> 88 bytes instruments/ESFM/djtBMX_gitty.fui | Bin 0 -> 80 bytes instruments/ESFM/djtBMX_hammeredkeypad.fui | Bin 0 -> 120 bytes instruments/ESFM/djtBMX_kikbas.fui | Bin 0 -> 81 bytes instruments/ESFM/djtBMX_lfotest.fui | Bin 0 -> 100 bytes instruments/ESFM/djtBMX_lofibrass.fui | Bin 0 -> 89 bytes instruments/ESFM/djtBMX_lylemays.fui | Bin 0 -> 286 bytes instruments/ESFM/djtBMX_m1stylepaino.fui | Bin 0 -> 82 bytes instruments/ESFM/djtBMX_m1stylepaino2.fui | Bin 0 -> 82 bytes instruments/ESFM/djtBMX_m1stylepaino3.fui | Bin 0 -> 82 bytes instruments/ESFM/djtBMX_m1stylepaino4.fui | Bin 0 -> 82 bytes instruments/ESFM/djtBMX_m1stylepaino5.fui | Bin 0 -> 82 bytes instruments/ESFM/djtBMX_nearest-drone.fui | Bin 0 -> 109 bytes instruments/ESFM/djtBMX_neophytekick.fui | Bin 0 -> 174 bytes instruments/ESFM/djtBMX_neophytekick2.fui | Bin 0 -> 175 bytes instruments/ESFM/djtBMX_noisytom.fui | Bin 0 -> 152 bytes instruments/ESFM/djtBMX_panfluter.fui | Bin 0 -> 281 bytes instruments/ESFM/djtBMX_pianoyorgan.fui | Bin 0 -> 93 bytes instruments/ESFM/djtBMX_piezoclavi.fui | Bin 0 -> 107 bytes instruments/ESFM/djtBMX_pulselesspulse.fui | Bin 0 -> 113 bytes instruments/ESFM/djtBMX_pulselesspwm.fui | Bin 0 -> 132 bytes instruments/ESFM/djtBMX_pwm2.fui | Bin 0 -> 83 bytes instruments/ESFM/djtBMX_pwm3.fui | Bin 0 -> 83 bytes instruments/ESFM/djtBMX_pwminv.fui | Bin 0 -> 85 bytes instruments/ESFM/djtBMX_quantizedcalilope.fui | Bin 0 -> 135 bytes instruments/ESFM/djtBMX_quantizedcalilope2.fui | Bin 0 -> 136 bytes instruments/ESFM/djtBMX_quantizedcalilope3.fui | Bin 0 -> 116 bytes instruments/ESFM/djtBMX_quantizeddrone2.fui | Bin 0 -> 113 bytes instruments/ESFM/djtBMX_quantizedhorn.fui | Bin 0 -> 113 bytes instruments/ESFM/djtBMX_santur.fui | Bin 0 -> 87 bytes instruments/ESFM/djtBMX_santurys.fui | Bin 0 -> 105 bytes instruments/ESFM/djtBMX_segapiano.fui | Bin 0 -> 90 bytes instruments/ESFM/djtBMX_shttomsz.fui | Bin 0 -> 189 bytes instruments/ESFM/djtBMX_sinusoidgit.fui | Bin 0 -> 111 bytes instruments/ESFM/djtBMX_sitardrone.fui | Bin 0 -> 89 bytes instruments/ESFM/djtBMX_slapbass.fui | Bin 0 -> 76 bytes .../ESFM/djtBMX_softstar-string-enhanced.fui | Bin 0 -> 98 bytes instruments/ESFM/djtBMX_springbass2.fui | Bin 0 -> 76 bytes instruments/ESFM/djtBMX_springbass3.fui | Bin 0 -> 76 bytes instruments/ESFM/djtBMX_springbass4.fui | Bin 0 -> 85 bytes instruments/ESFM/djtBMX_squeiuz.fui | Bin 0 -> 103 bytes instruments/ESFM/djtBMX_sunsoftbass.fui | Bin 0 -> 93 bytes instruments/ESFM/djtBMX_sunsoftbass2.fui | Bin 0 -> 94 bytes instruments/ESFM/djtBMX_sunsoftbass3.fui | Bin 0 -> 94 bytes instruments/ESFM/djtBMX_sunsoftbass4.fui | Bin 0 -> 94 bytes instruments/ESFM/djtBMX_sunsoftbass5.fui | Bin 0 -> 94 bytes instruments/ESFM/djtBMX_superpwm.fui | Bin 0 -> 200 bytes instruments/ESFM/djtBMX_sync-invtest.fui | Bin 0 -> 109 bytes instruments/ESFM/djtBMX_syncpwm-abuse.fui | Bin 0 -> 138 bytes instruments/ESFM/djtBMX_tabla.fui | Bin 0 -> 99 bytes instruments/ESFM/djtBMX_tarnceseq.fui | Bin 0 -> 88 bytes instruments/ESFM/djtBMX_vic20square.fui | Bin 0 -> 108 bytes instruments/ESFM/djtBMX_vic20squaretest.fui | Bin 0 -> 253 bytes instruments/ESFM/djtBMX_wurly.fui | Bin 0 -> 103 bytes 99 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 instruments/ESFM/djtBMX_1chostinato.fui create mode 100644 instruments/ESFM/djtBMX_4opBassESFM.fui create mode 100644 instruments/ESFM/djtBMX_4opESFMStrings.fui create mode 100644 instruments/ESFM/djtBMX_4opESFMStrings2.fui create mode 100644 instruments/ESFM/djtBMX_4opESFMStrings3.fui create mode 100644 instruments/ESFM/djtBMX_4opESFMStrings4.fui create mode 100644 instruments/ESFM/djtBMX_4opRubbaBassESFM.fui create mode 100644 instruments/ESFM/djtBMX_ESFMBRAS.fui create mode 100644 instruments/ESFM/djtBMX_ESFMBRASSSECT.fui create mode 100644 instruments/ESFM/djtBMX_ESFMGIT.fui create mode 100644 instruments/ESFM/djtBMX_ESFMPWM.fui create mode 100644 instruments/ESFM/djtBMX_ESFMSYN.fui create mode 100644 instruments/ESFM/djtBMX_ESFMresobell-short.fui create mode 100644 instruments/ESFM/djtBMX_ESFMresobell.fui create mode 100644 instruments/ESFM/djtBMX_ESFMresopipe.fui create mode 100644 instruments/ESFM/djtBMX_PULSELESSBUZZER.fui create mode 100644 instruments/ESFM/djtBMX_analogoctbas.fui create mode 100644 instruments/ESFM/djtBMX_bells.fui create mode 100644 instruments/ESFM/djtBMX_brarsesin.fui create mode 100644 instruments/ESFM/djtBMX_brassin.fui create mode 100644 instruments/ESFM/djtBMX_bwaro.fui create mode 100644 instruments/ESFM/djtBMX_chorbel.fui create mode 100644 instruments/ESFM/djtBMX_chorpad.fui create mode 100644 instruments/ESFM/djtBMX_clanger.fui create mode 100644 instruments/ESFM/djtBMX_clanger2.fui create mode 100644 instruments/ESFM/djtBMX_clanger3.fui create mode 100644 instruments/ESFM/djtBMX_clanger4.fui create mode 100644 instruments/ESFM/djtBMX_compile-basskick.fui create mode 100644 instruments/ESFM/djtBMX_compile-closehh.fui create mode 100644 instruments/ESFM/djtBMX_compile-marimba.fui create mode 100644 instruments/ESFM/djtBMX_compile-openhh.fui create mode 100644 instruments/ESFM/djtBMX_compile-padbrass.fui create mode 100644 instruments/ESFM/djtBMX_compile-sinetom.fui create mode 100644 instruments/ESFM/djtBMX_compile-snare.fui create mode 100644 instruments/ESFM/djtBMX_compile-springbass.fui create mode 100644 instruments/ESFM/djtBMX_compileagogo.fui create mode 100644 instruments/ESFM/djtBMX_compilebrass.fui create mode 100644 instruments/ESFM/djtBMX_compilefartbass.fui create mode 100644 instruments/ESFM/djtBMX_didgeritune.fui create mode 100644 instruments/ESFM/djtBMX_drlead.fui create mode 100644 instruments/ESFM/djtBMX_egless-kick.fui create mode 100644 instruments/ESFM/djtBMX_explosion.fui create mode 100644 instruments/ESFM/djtBMX_falcomkey.fui create mode 100644 instruments/ESFM/djtBMX_gitbsyn3.fui create mode 100644 instruments/ESFM/djtBMX_gitbsyn4.fui create mode 100644 instruments/ESFM/djtBMX_gitsyn2.fui create mode 100644 instruments/ESFM/djtBMX_gitty.fui create mode 100644 instruments/ESFM/djtBMX_hammeredkeypad.fui create mode 100644 instruments/ESFM/djtBMX_kikbas.fui create mode 100644 instruments/ESFM/djtBMX_lfotest.fui create mode 100644 instruments/ESFM/djtBMX_lofibrass.fui create mode 100644 instruments/ESFM/djtBMX_lylemays.fui create mode 100644 instruments/ESFM/djtBMX_m1stylepaino.fui create mode 100644 instruments/ESFM/djtBMX_m1stylepaino2.fui create mode 100644 instruments/ESFM/djtBMX_m1stylepaino3.fui create mode 100644 instruments/ESFM/djtBMX_m1stylepaino4.fui create mode 100644 instruments/ESFM/djtBMX_m1stylepaino5.fui create mode 100644 instruments/ESFM/djtBMX_nearest-drone.fui create mode 100644 instruments/ESFM/djtBMX_neophytekick.fui create mode 100644 instruments/ESFM/djtBMX_neophytekick2.fui create mode 100644 instruments/ESFM/djtBMX_noisytom.fui create mode 100644 instruments/ESFM/djtBMX_panfluter.fui create mode 100644 instruments/ESFM/djtBMX_pianoyorgan.fui create mode 100644 instruments/ESFM/djtBMX_piezoclavi.fui create mode 100644 instruments/ESFM/djtBMX_pulselesspulse.fui create mode 100644 instruments/ESFM/djtBMX_pulselesspwm.fui create mode 100644 instruments/ESFM/djtBMX_pwm2.fui create mode 100644 instruments/ESFM/djtBMX_pwm3.fui create mode 100644 instruments/ESFM/djtBMX_pwminv.fui create mode 100644 instruments/ESFM/djtBMX_quantizedcalilope.fui create mode 100644 instruments/ESFM/djtBMX_quantizedcalilope2.fui create mode 100644 instruments/ESFM/djtBMX_quantizedcalilope3.fui create mode 100644 instruments/ESFM/djtBMX_quantizeddrone2.fui create mode 100644 instruments/ESFM/djtBMX_quantizedhorn.fui create mode 100644 instruments/ESFM/djtBMX_santur.fui create mode 100644 instruments/ESFM/djtBMX_santurys.fui create mode 100644 instruments/ESFM/djtBMX_segapiano.fui create mode 100644 instruments/ESFM/djtBMX_shttomsz.fui create mode 100644 instruments/ESFM/djtBMX_sinusoidgit.fui create mode 100644 instruments/ESFM/djtBMX_sitardrone.fui create mode 100644 instruments/ESFM/djtBMX_slapbass.fui create mode 100644 instruments/ESFM/djtBMX_softstar-string-enhanced.fui create mode 100644 instruments/ESFM/djtBMX_springbass2.fui create mode 100644 instruments/ESFM/djtBMX_springbass3.fui create mode 100644 instruments/ESFM/djtBMX_springbass4.fui create mode 100644 instruments/ESFM/djtBMX_squeiuz.fui create mode 100644 instruments/ESFM/djtBMX_sunsoftbass.fui create mode 100644 instruments/ESFM/djtBMX_sunsoftbass2.fui create mode 100644 instruments/ESFM/djtBMX_sunsoftbass3.fui create mode 100644 instruments/ESFM/djtBMX_sunsoftbass4.fui create mode 100644 instruments/ESFM/djtBMX_sunsoftbass5.fui create mode 100644 instruments/ESFM/djtBMX_superpwm.fui create mode 100644 instruments/ESFM/djtBMX_sync-invtest.fui create mode 100644 instruments/ESFM/djtBMX_syncpwm-abuse.fui create mode 100644 instruments/ESFM/djtBMX_tabla.fui create mode 100644 instruments/ESFM/djtBMX_tarnceseq.fui create mode 100644 instruments/ESFM/djtBMX_vic20square.fui create mode 100644 instruments/ESFM/djtBMX_vic20squaretest.fui create mode 100644 instruments/ESFM/djtBMX_wurly.fui diff --git a/instruments/ESFM/djtBMX_1chostinato.fui b/instruments/ESFM/djtBMX_1chostinato.fui new file mode 100644 index 0000000000000000000000000000000000000000..ee26b7b39396d874c7c07a5acfd16a1425718cbd GIT binary patch literal 259 zcmZ?s^b6k4V9wy@D8u0E@9(Fl;GC0RoSLE#T#%TYs*qn?l9`uSlF#7gtHSVwg@GY} zfs4gK2thMI`7qkoQHX(qfsg(Fe+EVd8%7XdVEFHEC;${?XN8Ee0|8LXNEs-`$N>=p z>Sq7~E_Ns%r~<0YSOr-b7f2l!13M?wD4-s&(*OP@ib(1ph5_Z+pvFTCb9EC0x`u%p Nh}nRci9sHy9{`l`FFODL literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_4opBassESFM.fui b/instruments/ESFM/djtBMX_4opBassESFM.fui new file mode 100644 index 0000000000000000000000000000000000000000..f902ec50dcc7abd26a9ae6bb5656189a8e3ab954 GIT binary patch literal 92 zcmZ?s^b6k4V9wy@D9n(ORpR6u5pR-T;FMTg>>BLm%i!j#!tjNKfgxUlpUuITfgx}? qAFD$n0|VnsepUxj1_mYueny9v3=FPrf(#7I>{8yfxfdK&Wy%EO% literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_4opESFMStrings.fui b/instruments/ESFM/djtBMX_4opESFMStrings.fui new file mode 100644 index 0000000000000000000000000000000000000000..b942199c574a7e02841227e798ef58e1bf6d22e8 GIT binary patch literal 126 zcmZ?s^b6k4V9wy@D8`VIRpR6u5pR-T;2P}a8(dP9nU`M7;O48s@P&neAyk81)xnT~ zAz&J}lS3#2149Elvx5o)19JmglY<2VgRi4B0|x_(0KK)?kBAohP(H$k9U S76x`^c80(5>H)#0|P??Ta!Wr1Ea5_Gy?|%ivYuaMn@yYZ$Q8W1t9i+S2sZh W24>bT%*^Zz|K!;j80DE6{sRE?G9VEE literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_4opESFMStrings3.fui b/instruments/ESFM/djtBMX_4opESFMStrings3.fui new file mode 100644 index 0000000000000000000000000000000000000000..b2e661504db1326fa5df40e85f32e84898b9dda9 GIT binary patch literal 127 zcmZ?s^b6k4V9wy@D9(_QRpR6u5pR-T;2P}a8(dP9nU`K{%;4s$!tjNKfgx0!OO?Tp zfgxxzr;|b`0~137D>H)#h-Pb2FlS)$b(Ch{U|H)#0|RpdTa$u01B0)lGy?|%ivYuaMn@yYZ$Q8W1t9i+S2sbR UT2=-|W_E^u^6U(Z@+=Jh0p$B13;+NC literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_4opRubbaBassESFM.fui b/instruments/ESFM/djtBMX_4opRubbaBassESFM.fui new file mode 100644 index 0000000000000000000000000000000000000000..4ff3a2a3aa66911b19f05c2127aae5bedefb75f3 GIT binary patch literal 97 zcmZ?s^b6k4V9wy@D8Z1DRpR6u5pR-T5LB9!l<1ULT1_oC*K?VkS79K`s79K8nc80(5tUL?=ZXysr literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_ESFMPWM.fui b/instruments/ESFM/djtBMX_ESFMPWM.fui new file mode 100644 index 0000000000000000000000000000000000000000..f07c0d121d36746feabca702c95698cb643181c4 GIT binary patch literal 88 zcmZ?s^b6k4V9wy@$j^|HRpR6u5$_u8<{J?1%i!j#!tjNKfgzxQpUEMgfhn+oi^V~U jfi0jF$o~)Gb1;MWu5N-149v_74Dzf%nt|aXkp2h&m-7-n literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_ESFMSYN.fui b/instruments/ESFM/djtBMX_ESFMSYN.fui new file mode 100644 index 0000000000000000000000000000000000000000..0d86beaeed64d17db44e274e3df90c78ed4b39b8 GIT binary patch literal 88 zcmZ?s^b6k4V9wy@$j^|HRpR6u5$_u8<{KR8$Kd9x!tjNKfg!MkozY=B0|QF~Ka+zd okl)3{=rE0el@Y|(VPJ4|6J%guW@ccNXJ=q!W@Pv)&&I$20DHs`f&c&j literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_ESFMresobell-short.fui b/instruments/ESFM/djtBMX_ESFMresobell-short.fui new file mode 100644 index 0000000000000000000000000000000000000000..dc65c7d8c989ab78ed011a53a5b5ec74d05acb5e GIT binary patch literal 99 zcmZ?s^b6k4V9wy@D8-PHRpR6u5$_u8=3A6noS&4MlcQUlkzZ88;O48s@P&neAzp&Z z-JyYjA!;@Uqk|Iz1OH4;RtF&l1`Y;(9tUv-23I#h1_owkhOf-*4F7?cNuHg70RRg* B6+-|3 literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_ESFMresobell.fui b/instruments/ESFM/djtBMX_ESFMresobell.fui new file mode 100644 index 0000000000000000000000000000000000000000..7422641a5f6059ae848786e654a8d8bd485909a7 GIT binary patch literal 93 zcmZ?s^b6k4V9wy@D8i7ERpR6u5$_u8=3A6noS&4Mlf&TVtHSVwg@GYng3H~Zfq@}v vHV31F69WVPOioq@AqEBx27X3|#|#XvZh{O9%*+g5nb{fs12L04I|Bm%MgS9` literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_ESFMresopipe.fui b/instruments/ESFM/djtBMX_ESFMresopipe.fui new file mode 100644 index 0000000000000000000000000000000000000000..08cc3bceab55518051042bf3d7679c60aae1b28e GIT binary patch literal 93 zcmZ?s^b6k4V9wy@D8i7ERpR6u5$_u8=3A6noL`VxkjmiZtHSVwg@GYlg3H~(oq-{= ufrAl5v&`gVbr51;U}9ilba=(U;OZvGz`)GRq%6<==RY$8&qsN79tHqAfE0%S literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_PULSELESSBUZZER.fui b/instruments/ESFM/djtBMX_PULSELESSBUZZER.fui new file mode 100644 index 0000000000000000000000000000000000000000..55040d931c576f13fd0ab0a13c0c14f2a42dd05c GIT binary patch literal 114 zcmZ?s^b6j_V9wy@D9MnLRpR6u5noW6Q=F=slUiJ?;1n7a7`=BvW+g@u73U_U>< yLjeOjLjym90|O8s(;N&8{)RjZ91Pry|Nk>E0^xsGH$eslW}rG|{s&+z52OJ+3>cXJ literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_analogoctbas.fui b/instruments/ESFM/djtBMX_analogoctbas.fui new file mode 100644 index 0000000000000000000000000000000000000000..907b4cf86231708f3d0e0e957fa5473adc75fcba GIT binary patch literal 94 zcmZ?s^b6j_V9wy@D9VtMRpR6up^%uDn3JELpInlZSX|8D=BvW+g@u73WD_^D!+QpX v!0B8}4rUAt4AXcN9M~8b8X7nmK(woyAOiz41H*r276vY6c81UL>pS2sZh24;qzf92VKGBGnSFv+tsFaQAKrW1?+ literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_brarsesin.fui b/instruments/ESFM/djtBMX_brarsesin.fui new file mode 100644 index 0000000000000000000000000000000000000000..2d3c970f204ddfc69af089dd85ea1d26f1acab57 GIT binary patch literal 106 zcmZ?s^b6j_V9wy@D9DhKRpR6u5ua3)SX7)^oSDbq=BvW+g@u73a1IZX!&3$ZhOPVz z4nT^bfsMg|9Yh2991INphCB=$4BU+W|1&TG;eS^*K?Vk9Rv_koAPU3`@<0p#Q2Z9u literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_brassin.fui b/instruments/ESFM/djtBMX_brassin.fui new file mode 100644 index 0000000000000000000000000000000000000000..9d58d0b9101714251cd433fdc29600cdbbb7f6bc GIT binary patch literal 121 zcmZ?s^b6k4V9wy@$j^|HRpR6u5ua3)SX`W$$Kd9x!tjNKfgxZ&JF|ln0~5mxE@lT~ z26l!9eg+2yAZXxVaNuBI@HgaP;9%fp{QsYU5eWbL8}S193``)t4N&C2tD7JL12a$q LGyelHmIu-Rb5R*3 literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_bwaro.fui b/instruments/ESFM/djtBMX_bwaro.fui new file mode 100644 index 0000000000000000000000000000000000000000..e84d877f1b5c86dba0b9ab09f97e54ae00a58d93 GIT binary patch literal 102 zcmZ?s^b6k4V9wy@$jgwDRpR6u5ua3^Sd`D;=BvW+g@u73U_T41gDV3ALkmBH1CU~9 vU}JD#2hl)22Lpq@ArAuw12^OU{|t;k_}|q{kb!}j6^QvCumUlIJP-o_fL|12 literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_chorbel.fui b/instruments/ESFM/djtBMX_chorbel.fui new file mode 100644 index 0000000000000000000000000000000000000000..47b0fe3a735769cda7a2a6f4a8f09f0a3841ddd6 GIT binary patch literal 90 zcmZ?s^b6k4V9wy@D9GTMSFB*9qmZ1Dn3tEDqhQ3~=BvW+g^__FOqq+xA&`M7hyhF^ c_^c4VtD7JL12a&eJUatJG9$z9dUl520AoNA9{>OV literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_chorpad.fui b/instruments/ESFM/djtBMX_chorpad.fui new file mode 100644 index 0000000000000000000000000000000000000000..900743510804af71a68152fef40dd92dddd18ad2 GIT binary patch literal 86 zcmZ?s^b6k4V9wy@$jjiFS6ot5nwy$eqF~10=BvW+g@u8EaSmIPgA0QKV*?ALgDa4~ jM2*QoM1TRz4`E<%brWP@U}j+8k!NT4%go5|8bkvCXf_f6 literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_clanger.fui b/instruments/ESFM/djtBMX_clanger.fui new file mode 100644 index 0000000000000000000000000000000000000000..6d54e300b8af31697a85fa651b00a76204e6e24d GIT binary patch literal 104 zcmZ?s^b6j_V9wy@$j^|HRpR6u5$~Lnn3tYf#Ng(u!tjNKfgzxSi^0K)fq`o|JClPc z10zERE2BdT0}}%SFPno21B1UI4+94SH{<{RKsiQ+|E_L=3=GVyK+FKd{BL&2vokON E0LE7oJ^%m! literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_clanger2.fui b/instruments/ESFM/djtBMX_clanger2.fui new file mode 100644 index 0000000000000000000000000000000000000000..84becd228cae470fad0e2cc9c96c82d774ea9db0 GIT binary patch literal 122 zcmZ?s^b6j_V9wy@sK}6#RpR6u5$~Lnn3tYfwH@U|?bS|DVB;fpN}`*9`w%-2@pJm{}QE<=GinnHd=V H0qK7LEGZw4 literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_compile-openhh.fui b/instruments/ESFM/djtBMX_compile-openhh.fui new file mode 100644 index 0000000000000000000000000000000000000000..55b8236b810f2ca5b625285c9e8a3a978f592be4 GIT binary patch literal 109 zcmZ?s^b6k4V9wy@D9n(YpIeZbld6zkkea8Ek(rTL!rZCZ_-Y85kKDIoSWZx(PBcFtaoKgJK4Gb_NCjmm3z4 literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_compile-padbrass.fui b/instruments/ESFM/djtBMX_compile-padbrass.fui new file mode 100644 index 0000000000000000000000000000000000000000..fe27ce49fe51995c53ce43f74e88a683636add3c GIT binary patch literal 117 zcmZ?s^b6k4V9wy@D9DhUpIeZbld4dVn37bKSX|8D=BvW+#f?G1NQ9rkfq{X+shxw_ z;TQvhqB4YU*ucf$z{bGf>nP5^!N9`9@So99lJWQN->hH&Wc+t^6J%gu2C9)~2hu<@ GKr{e>i5Wit literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_compile-sinetom.fui b/instruments/ESFM/djtBMX_compile-sinetom.fui new file mode 100644 index 0000000000000000000000000000000000000000..8de198fa4637cd9f1ebc6f87be61cc88520734a9 GIT binary patch literal 102 zcmZ?s^b6k4V9wy@D9ezXpIeZbld4dhnU|_ilAo&q5=bn`Ov*{sWN`CUVfbRspkUqL t&*H$y!0=GcpWVfTfx)1`pTj`~NHYNGnG6iBZh{O9%>52S^G7yzn^7DWI6 literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_compile-snare.fui b/instruments/ESFM/djtBMX_compile-snare.fui new file mode 100644 index 0000000000000000000000000000000000000000..a4b7f7e282af040ea9978387806872657280ff04 GIT binary patch literal 87 zcmZ?s^b6k4V9wy@$j6YJpIeZbld4dhmspg_;O48s@Wq`$!JdJiG4dM&gFyp7yZ?6v hhRu`CyN84LE&gmFK-$$!kb!}joq<6fh?yB6GypB&6p{b{ literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_compile-springbass.fui b/instruments/ESFM/djtBMX_compile-springbass.fui new file mode 100644 index 0000000000000000000000000000000000000000..9b5d90cd4c79038ab6abc5916882bb4d8ec0a409 GIT binary patch literal 95 zcmZ?s^b6k4V9wy@D8`VSpIeZbld4c$P?VXMu8@>iT&!Tk;O48s@P(B@Aybr})!mta rAyt>3#a)zvAwh_r*V>J-$WQB#sLvy0|QpZ|E_L=3=GWd3{3Lu41bsz82$ihCII>% BD>488 literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_compilebrass.fui b/instruments/ESFM/djtBMX_compilebrass.fui new file mode 100644 index 0000000000000000000000000000000000000000..fa34f2841526f90b6d58f8c3fa27b7822128ae8e GIT binary patch literal 128 zcmZ?s^b6k4V9wy@D8i7OpIeZbld6zZlvrG>k(QX9s>$HytHSU_ok78H3KzSx83V({ z1~yg&Nd^Xk1`aj_F%Zqprtpn{!QYUNfrEjG`Tu_gMg~T9M&|$iM!Y}~Mka^|8|Qyl XH$eslW_AV!c_0?&k{ zquUDxh5#;p7MCCf27z9G4mS-327g0I1`Y-$mjC}57#SGZSy@?xnILQi#{d3CydX)a f01HsS1X+NA`@gH3AOiz4E5ko|b|4KzK>9BLFZ&^P literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_didgeritune.fui b/instruments/ESFM/djtBMX_didgeritune.fui new file mode 100644 index 0000000000000000000000000000000000000000..69a910c4647bc169024090340bc27c45e8e697c7 GIT binary patch literal 108 zcmZ?s^b6j_V9wy@D9n(ORpR6u5ucKolAcEGB7Z+GO)}VE6%~IRI-S5%d56 literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_egless-kick.fui b/instruments/ESFM/djtBMX_egless-kick.fui new file mode 100644 index 0000000000000000000000000000000000000000..237db9f2da645ee67cea8f08b933520b15d261f9 GIT binary patch literal 92 zcmZ?s^b6j_V9wy@D9n(ORpR6u5uci#lUiJ?ke!*F&EV#%!tjNKfgxxkKd-}j1_lOR teijF91{Q_}es+fhAisf=!GVK;!PQNWfq|Lf9|JS@2R3H@2MqE+3;-p#6omi) literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_explosion.fui b/instruments/ESFM/djtBMX_explosion.fui new file mode 100644 index 0000000000000000000000000000000000000000..33b5d67dbdfac8fb75e11a4be7dd453944820727 GIT binary patch literal 107 zcmZ?s^b6j_V9wy@D8!IjoR+JbT2YXbU!0krSDaSC;O48s@P&neA)t$&-ywm4fuVt) z!2w9YX$D><2QdZ)e?uMy4hC+<|Nj{nf$+bpn;-)NGXukIX3iJ<%=`}+;dxC85o!vIQSia@~&=z3=GWd4D9mk46Muy3_pPMHvrf@5*Gjf literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_gitbsyn3.fui b/instruments/ESFM/djtBMX_gitbsyn3.fui new file mode 100644 index 0000000000000000000000000000000000000000..4680aac41f7c18691ac4ee7266c0439a54eb753d GIT binary patch literal 89 zcmZ?s^b6j_V9wy@D8P`CRpR6up^%1OQ2A1G8Tucs` q3=9m-JW3AJ7#Nxw_!%9(F)+Bg2{JG+Gcf#TW@liMXJ_~c#0&uNN)#mk literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_gitty.fui b/instruments/ESFM/djtBMX_gitty.fui new file mode 100644 index 0000000000000000000000000000000000000000..dbf633f16e08949b3cd11a4a1441cbc1afd0fbc9 GIT binary patch literal 80 zcmZ?s^b6j_V9wy@$j*?SSyEC`$>8Rz!tjNaf#LF0E>;IK28J6`IhY;X85jck_+1>- i7+As@_!%9hGcdTi2{JG+Gc){WW@lgpVrF^v7YqO!3=tdv literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_hammeredkeypad.fui b/instruments/ESFM/djtBMX_hammeredkeypad.fui new file mode 100644 index 0000000000000000000000000000000000000000..286c106f3e78a2b59b7c2940b8bfc80605c9fff9 GIT binary patch literal 120 zcmZ?s^b6j_V9wy@D8i6hoR+Jbk(isCT9lfSomyFtn8M)ZtHSVwg@K_}ke|yTjDel8 zfuGgkCj(0(13$ZiJp%*7RFx(NQwAk}BXI@}1}2{W{}~t=7+FDp1q7Ly{=2#fGB8MU Q@ZXYW2h!{k3_w}|0PT<%LI3~& literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_kikbas.fui b/instruments/ESFM/djtBMX_kikbas.fui new file mode 100644 index 0000000000000000000000000000000000000000..c92ffa5e3d44f175676eed15a2d771a0333cdfc5 GIT binary patch literal 81 zcmZ?s^b6j_V9wy@$ia}EnVg-JSj^z&tHSVwoq?f;m!B)%gMp!OCJ%>qJOe`l1204T ce+C9d27WN@>L$p*z{~=~K*jPP%*?<50Pz!by0L+q!GV*3!PQNWfq|KU;XgA!kOpFTAO--(e-UN? literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_lylemays.fui b/instruments/ESFM/djtBMX_lylemays.fui new file mode 100644 index 0000000000000000000000000000000000000000..469f7a61a1274e93dd6852d8953647d4941c133f GIT binary patch literal 286 zcmZ?s^b6j{V9wy@D9VtMRpR6u5ua0;ld6!LSXr!_S)9S(=BvW+g@u73WI3CQg9igc zPy-vgg9VVk0>}r_FuuQ`4g&`Rr`Z4h42%qn2HI+ha?+AwB0>WEe7ro|T$~*2Y^>bO z5LqThhX4LXB&s)tt9N8zym0l_{YOuqzk2iT!^cmbzkL1n{m0K=zrp4MW&iyLnr}jy QdRI3=1_pTsAZAC<0QW{)=Kufz literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_m1stylepaino.fui b/instruments/ESFM/djtBMX_m1stylepaino.fui new file mode 100644 index 0000000000000000000000000000000000000000..b11fb2aa28e23c4cbc7ffd6e1841f6330667f501 GIT binary patch literal 82 zcmZ?s^b6j_V9wy@$jRVq7+;W>nU~Mt=BvW+g`I&Ri<4hPTZKV3RfgZq-jIPIk)L0~ k&4_`4v4Nk(Rh@ys)lHCrftig{o0*+K2#9~kvorh$0Kcma^8f$< literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_m1stylepaino2.fui b/instruments/ESFM/djtBMX_m1stylepaino2.fui new file mode 100644 index 0000000000000000000000000000000000000000..44af11d14f93fe13314f4860347fc4b4b0b49752 GIT binary patch literal 82 zcmZ?s^b6j_V9wy@$jRVq7+;W>nU~Mt=BvW+g`I&RU5MXBTZKU?U54My-jIPIQJCMu k&4_`4v4Nk(Rh@ys)lHCrftih+m6@G^1&II1vorh$0Le@b3IG5A literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_m1stylepaino3.fui b/instruments/ESFM/djtBMX_m1stylepaino3.fui new file mode 100644 index 0000000000000000000000000000000000000000..68b3d6838f90645bd752104675a6f41935dd37ce GIT binary patch literal 82 zcmZ?s^b6j_V9wy@$jRVq7+;W>nU~Mt=BvW+g`I&RLx|s9TZKV3S&HAy-jIPIk&oZQ l&4_`4v4Nk(Rh@ys)lHCrftihum6`n~3o|>zA9;3${{Yhc5C#AM literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_m1stylepaino4.fui b/instruments/ESFM/djtBMX_m1stylepaino4.fui new file mode 100644 index 0000000000000000000000000000000000000000..4e390c0a9017051ef7c3a07049b16fd543f31552 GIT binary patch literal 82 zcmZ?s^b6j_V9wy@$jRVq7+;W>nU~Mt=BvW+g`I&RLyF&BTZKV3S(=~C-jIPIQGnmW l&4_`4v4Nk_^*aNDtD7JL12Y>RD>M5~7G`#aKl1Dh{{h{@5S{=4 literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_m1stylepaino5.fui b/instruments/ESFM/djtBMX_m1stylepaino5.fui new file mode 100644 index 0000000000000000000000000000000000000000..1ce005eda72f1de719e5ec4a0307f15d5922ef1b GIT binary patch literal 82 zcmZ?s^b6j{V9wy@$jRVq7+;W>nU~Mt=BvW+g`I&ROOxM4TZKU`Rf6Bm-jIPIQJCMu k&4_`4v4Nk(Rh@ys)lHCrftgK$m6@G^1&II1vorh$0MKg>Hvj+t literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_nearest-drone.fui b/instruments/ESFM/djtBMX_nearest-drone.fui new file mode 100644 index 0000000000000000000000000000000000000000..83c826b86b1adc6c7405484a8b162e14c1baab08 GIT binary patch literal 109 zcmZ?s^b6k4V9wy@D8i7ERpR6u5ucZuSd>~^l2VkPm&)MgtHSVwg@GYpKR>^NIRgVj z0~52u4+bWN27U$y1_pM923`gS4h9B)LmmbW25!dx{}~v8@V~2@AOiz4P(3sM12C2c F(g5AB7)byC literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_neophytekick.fui b/instruments/ESFM/djtBMX_neophytekick.fui new file mode 100644 index 0000000000000000000000000000000000000000..7134f0f3725340066992844ff347c727ec5c378c GIT binary patch literal 174 zcmZ?s^b6j_V9wy@D9VspoR+JQmzrOYQCX6zke-;7lv>2#=BvW+g_S`eLzth{-I;+c zRhFN{U6g?-L5QE(T?9xo@H2USV_@?)@nPU#;1v1)pP`X~@geg*=4H&i%vH=e%yG<~ z%$Cd=%>2whm>x4-VA{vDl4%B0BU27jC=<6JP`x7qqo|0mkRU%F4-XeR3*+Bk-#`C% ZbrWP@U}j}yVCH|(z|8)QL7x3T0|3>oD~SLA literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_neophytekick2.fui b/instruments/ESFM/djtBMX_neophytekick2.fui new file mode 100644 index 0000000000000000000000000000000000000000..4d17e19cc5dce1f533db29a509e857bbd8ef0b00 GIT binary patch literal 175 zcmV;g08sx%NlsI`05Vr6nN07gwD0Q3a_AZG^; z1qVj}0AiRA1Sc5)24R2?2L~bm17H9T0txc~22V6h00;mH6#xGKfdB#F1HJ>M1C0ZE z18f6c14#op11JLz1NZ{t0?-1!0;vL+0)YZ-0#yPF5&!=HK>z_56af4B`1bVj@$m2M d?Cb05|3yX-00093^#B780)PVt`2ZgW{{SI*G^YRn literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_noisytom.fui b/instruments/ESFM/djtBMX_noisytom.fui new file mode 100644 index 0000000000000000000000000000000000000000..b80ed42bd453a533a617cd95ff4a9b1ffecf88b8 GIT binary patch literal 152 zcmZ?s^b6j{V9wy@$jOkGpIKa4lAp`q=BvW+g^htBpn;#+;R^#p@FaeI2WAF_AQ1mE zSRBmvHxy>zVBq9n_|NFbz@h*Kr%(U)H`WFT3jl>11z9crL*NMpR0tFQ@9HMVz`)GP Rzyic;WZ4;h$Z<0;0|4IbDcb-5 literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_panfluter.fui b/instruments/ESFM/djtBMX_panfluter.fui new file mode 100644 index 0000000000000000000000000000000000000000..6e022e2bba1a0addc5c684d7c840ba8a6f5a6141 GIT binary patch literal 281 zcmZ?s^b6k4V9wy@D8i7ERpR6u5$~R#pAwLm=ay4ilFH!btHSVwoq-{6F+YO?0|P@q zKP!`iI*?ukf`pWlA{_ctO< zxiPZxNLzhbA)s4O!M|TWe*I@+Wn*Ie?{7kqa#uG&1_ovp1}1rShX2g042(dU0RX?# BV1fVu literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_pianoyorgan.fui b/instruments/ESFM/djtBMX_pianoyorgan.fui new file mode 100644 index 0000000000000000000000000000000000000000..5f5bc8d408cf1ad684512fd6d1c72ea57a175d1d GIT binary patch literal 93 zcmZ?s^b6j>V9wy@D8i7ERpR6up-_;Sn3rFvkYALZn8)DetHSVwg@GZUgP*}6A4o3% q(q;?{3=Ke9o`InYMDsH+xVi~4Ffg++Ff;Q%(2-|nkP~NSU<3d{;}Zt} literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_piezoclavi.fui b/instruments/ESFM/djtBMX_piezoclavi.fui new file mode 100644 index 0000000000000000000000000000000000000000..30d571355dd451d31488c6872042078199ff1962 GIT binary patch literal 107 zcmZ?s^b6j_V9wy@D8!JGRpR6u5nqs*T9u!ilUSC?;O48s@P&neAz(j0t3v|=J3|9M ug98H)z-e9v2Mz`{e?uMy4hC+<|Nj{nf$+bpn;-)-Gf*8f{{t|V2hspzEEdK9 literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_pulselesspulse.fui b/instruments/ESFM/djtBMX_pulselesspulse.fui new file mode 100644 index 0000000000000000000000000000000000000000..ef67474a4805f443613aab80526d188b5ecd2b70 GIT binary patch literal 113 zcmZ?s^b6j_V9wy@D8Z1DRpR6u5noW6Q=F=slUiJ?0A@0{`KmB{VPRkh+|SSN(7?dJ y(8SN+0HhciU^Fj-0|x_xzab9;2Lm_b|Njh(K=|L)O^|_s8K{n#{{a}w18D$Ci5Tes literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_pulselesspwm.fui b/instruments/ESFM/djtBMX_pulselesspwm.fui new file mode 100644 index 0000000000000000000000000000000000000000..ea11256aa3285e7f4dbaa90cdaef35ff424c6570 GIT binary patch literal 132 zcmZ?s^b6j_V9wy@D8`VIRpR6u5noW6Q=F=slUiJ?5D@Om;O48s@P&neAz(j0ze589 z149Epg9DI4&^!zdKzV;dMFtKAHeQDR42%rSHnw(lwl>yQmKK&)*4&K$L4u47|6Sb# R8JL-Ynwj|@fU!J~1_0$!8`=N> literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_pwm2.fui b/instruments/ESFM/djtBMX_pwm2.fui new file mode 100644 index 0000000000000000000000000000000000000000..266225e61824f6478c258268fd086d4befeee537 GIT binary patch literal 83 zcmZ?s^b6j_V9wy@$i{6J%fjiZd|tKLBHS GAPoR-HM4y>I_T_4ZI8v91JY}hCB=$4BU+W|1&TG;eS^*K?Vk9pn7Ij1_ovR2ZHka G4;TPO1Qu5S literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_segapiano.fui b/instruments/ESFM/djtBMX_segapiano.fui new file mode 100644 index 0000000000000000000000000000000000000000..43987085a2fe4ea017ad0fd950b6b8fb22e75fe1 GIT binary patch literal 90 zcmZ?s^b6j>V9wy@D9DhKRpR6up-`Nfo>-8Xn3vDs=BvW+g@u73po5>mA)kRMbTPk+ qgD?XF^BjIg2V(|?#s+>zhi?oFu5N-rK@JusW_AV;{wL4QzyJUTQ4=)) literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_shttomsz.fui b/instruments/ESFM/djtBMX_shttomsz.fui new file mode 100644 index 0000000000000000000000000000000000000000..b461b135a4e5cc9e0a977e4b28800088d3f9fce5 GIT binary patch literal 189 zcmYMstqQ_W0EXdrzegu}7^1MEAPNd5i*-|WKw&FGSP{#D48-7)&Aag$yaJQ=BG?Rb z7?dZx<>OPUIJq$=4%%dSv53-Ln5gKqFN)*gjEaW5Oh|3%_&GxNM z28ONt3=Tkwp@DZ3IoG~>0BHxE({Eb n4g5?_77PrN8#ozU*ccdG-2@pJm>GbWoq<7`o#C%M_X8FH{K^m~ literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_squeiuz.fui b/instruments/ESFM/djtBMX_squeiuz.fui new file mode 100644 index 0000000000000000000000000000000000000000..6597f8037dab928816658ce261a9f51d8f28471b GIT binary patch literal 103 zcmZ?s^b6j_V9wy@$j6Y9RpR6u5no(bnwnX~;O48s@P&neA!rHK9F9( p&)~quz{Jo1r1=>b8X+{3tD7JL12Y4|KW6?1+VboSzvY=2SO784=Lp_jg t;AeIaV_;-x;9+p!XJBY-;0DvKZh{O9%nS^lnfV_u$g?xB$+Ix9003$06YBr~ literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_sunsoftbass3.fui b/instruments/ESFM/djtBMX_sunsoftbass3.fui new file mode 100644 index 0000000000000000000000000000000000000000..4a66fef8a9dc58cc13b716a736f00b97c48fa1c4 GIT binary patch literal 94 zcmZ?s^b6j_V9wy@D9VtMRpR6up-^0!SDc?#qL7qWTx`tX=BvW+g@u9P@_v362Y&{J vfEoPE4q^r4*U!ZO%2=(AllVUkb!}jf#E+h{{t3zc80(5KurLRmlccv literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_superpwm.fui b/instruments/ESFM/djtBMX_superpwm.fui new file mode 100644 index 0000000000000000000000000000000000000000..1caf342deb01d8df9b562548d4c20d835106965a GIT binary patch literal 200 zcmZ?s^b6j{V9wy@D9DhKRpR6u5no(dkXocrP@c=+=BvW+g@u73uz`)$K>|c`fM~XW z22K#o6xhH8=KCA+F>o+&Gynh3z{tSJ#K`d9-$)TC!pRL0QB#l>6Bgj*=3r+-QDh9) z=E%VK?>|tR30xacgTEmU0|x^)8|pCtDJh2k42;5z>}+hTK)?b7%*@P8OpJ_7%q%RdZ0zjZjQ@cu WfbhSon;-)NGtg*e{s&+z52OKCKNoWV literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_tabla.fui b/instruments/ESFM/djtBMX_tabla.fui new file mode 100644 index 0000000000000000000000000000000000000000..6a971c0b27d5958a8a0f086f44012384c43822ee GIT binary patch literal 99 zcmZ?s^b6j_V9wy@$i+~Sn3R(U0t{}xDhyv(7#Nxu_&FRR7#Nxv_}Lx4GcYjh=jV6$ nfuQ{jc^EhtxEcTdXJ7=v|E_L=3=HxN3|#U+&CKjC8bBBToP!pK literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_tarnceseq.fui b/instruments/ESFM/djtBMX_tarnceseq.fui new file mode 100644 index 0000000000000000000000000000000000000000..0a09cab3b4b9a88d1eeab0537d3b2065b67da309 GIT binary patch literal 88 zcmZ?s^b6j_V9wy@$j^{koR+Iwl30|NoLZb($l&Iy!tjNKfgwnRU)3Ri! nft{g&pWPvW0SGvm9KskFT-^j27?^=vX8tEU%=`}+Y-CVeSejUr%HZa!!tjNKfgzxQhr=PBfsLV& tpTU6v2pW)R4h9B)LmmbW25!dx{}~v8@V~2@AOiz4P#rV>12C2c(g0957GD4W literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_vic20squaretest.fui b/instruments/ESFM/djtBMX_vic20squaretest.fui new file mode 100644 index 0000000000000000000000000000000000000000..3c27a510c06d61a718e03a2e4d5bd94a52520a6e GIT binary patch literal 253 zcmZ?s^b6j_V9wy@D9(_QRpR6u5nq;>Y-CVeSejUrT9R5^!rup#{l9RF)%VQv#_$Ub8vET z^YHTV3kV7ci-?MeOGrvd%gD;fD<~={tEj4}YiMd|>*(s~8yFfHo0yuJTUc6I+t}LK z+u7P!TUlC|o0*yz8yOnt>*?xfYiVkztEs9eD=8|-%gM?}OG!$Ii;0Q|3keGF^YQX< fb8&L8v$3);Gco>mbrWP@Um literal 0 HcmV?d00001 diff --git a/instruments/ESFM/djtBMX_wurly.fui b/instruments/ESFM/djtBMX_wurly.fui new file mode 100644 index 0000000000000000000000000000000000000000..453349e84a24679f1011ca11024682f11dc41a48 GIT binary patch literal 103 zcmZ?s^b6j_V9wy@$j6XcoR+I=lwVL@T9i}C;O48s@P&nep|OFV*`b4hfdNFf18IAH peuw`E+TW0efrEjY@&A7YMj-s}>L$p*AkV Date: Wed, 17 Jan 2024 14:51:09 -0500 Subject: [PATCH 68/74] it's called restart --- doc/3-pattern/effects.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/3-pattern/effects.md b/doc/3-pattern/effects.md index 152ff23df..8182d4c93 100644 --- a/doc/3-pattern/effects.md +++ b/doc/3-pattern/effects.md @@ -93,9 +93,8 @@ not all chips support these effects. - this effect is currently incomplete. - `F5xx`: **Disable macro.** - `F6xx`: **Enable macro.** -- `F7xx`: **Retrigger macro.** +- `F7xx`: **Restart macro.** - see macro table at the end of this document for possible values. - - `F7xx` resets LFO macro phase to the phase that is set in instrument macro settings. additionally, [each chip has its own effects](../7-systems/README.md). From 7c9df02b2ccbdab95c96d9f7f8d1031d293cc47d Mon Sep 17 00:00:00 2001 From: Eknous-P Date: Wed, 17 Jan 2024 20:19:44 +0400 Subject: [PATCH 69/74] newline option attempt 2 hopefully the freakin submodule wont get in --- doc/8-advanced/chanosc.md | 1 + src/gui/chanOsc.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/doc/8-advanced/chanosc.md b/doc/8-advanced/chanosc.md index 720b550fe..6a2cd27ed 100644 --- a/doc/8-advanced/chanosc.md +++ b/doc/8-advanced/chanosc.md @@ -33,6 +33,7 @@ right-clicking the view will display the configuration view shown above: - `%v`: volume (decimal) - `%V`: volume (percentage) - `%b`: volume (hex) + - `%l`: new line - `%%`: percent sign click on OK to return to the main view. diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index 9a4d38af9..ae568107f 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -348,6 +348,7 @@ void FurnaceGUI::drawChanOsc() { "- %v: volume (decimal)\n" "- %V: volume (percentage)\n" "- %b: volume (hex)\n" + "- %l: new line\n" "- %%: percent sign" ); ImGui::EndTooltip(); @@ -751,6 +752,10 @@ void FurnaceGUI::drawChanOsc() { text+=fmt::sprintf("%s",noteName(noteMod,oct)); break; } + case 'l': { + text+="\n"; + break; + } case '%': text+='%'; break; From 020498fd5d413013f32ebe6c3db238701a385421 Mon Sep 17 00:00:00 2001 From: Eknous-P Date: Thu, 18 Jan 2024 00:32:50 +0400 Subject: [PATCH 70/74] single quotes --- src/gui/chanOsc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index ae568107f..dca83ddec 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -753,7 +753,7 @@ void FurnaceGUI::drawChanOsc() { break; } case 'l': { - text+="\n"; + text+='\n'; break; } case '%': From 250f81cb97268019df5d3ecd73c7d533e61b232c Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 17 Jan 2024 17:55:49 -0500 Subject: [PATCH 71/74] update to-do list --- TODO.md | 1 - 1 file changed, 1 deletion(-) diff --git a/TODO.md b/TODO.md index 9389f7edb..f1918edef 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,5 @@ # to-do -- individual macro retrigger - finish color import improvements (settings refactor) - new undo stuff - fix some bugs From e03686cdd7071a08be254d3524900578ba098bca Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 18 Jan 2024 00:41:36 -0500 Subject: [PATCH 72/74] Eternal_Forest_TaitoArcade.fur update --- demos/arcade/Eternal_Forest_TaitoArcade.fur | Bin 510557 -> 171602 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/demos/arcade/Eternal_Forest_TaitoArcade.fur b/demos/arcade/Eternal_Forest_TaitoArcade.fur index e15c1f9cea6afa3a78cb9b10c2864fd7fd1b0111..448276a668a48f165e8034a8f50cd3d000634668 100644 GIT binary patch literal 171602 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�=XF8L{O|uqr{M6Mdfj(Y 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

    B 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 K1-8%JpV`@r9gC5xyeC{s!hdNsd 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 Date: Thu, 18 Jan 2024 00:44:06 -0500 Subject: [PATCH 73/74] vortex_opm.fur by leejh20 --- demos/misc/vortex_opm.fur | Bin 0 -> 4446 bytes src/gui/about.cpp | 1 + 2 files changed, 1 insertion(+) create mode 100644 demos/misc/vortex_opm.fur diff --git a/demos/misc/vortex_opm.fur b/demos/misc/vortex_opm.fur new file mode 100644 index 0000000000000000000000000000000000000000..5fd6a1a84870a90248a278b4958fa05b1ecfca94 GIT binary patch literal 4446 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 literal 0 HcmV?d00001 diff --git a/src/gui/about.cpp b/src/gui/about.cpp index 64f2cbae5..8c014121f 100644 --- a/src/gui/about.cpp +++ b/src/gui/about.cpp @@ -110,6 +110,7 @@ const char* aboutLine[]={ "Korbo", "jaezu", "Laggy", + "leejh20", "LovelyA72", "LTVA1", "LunaMoth", From b2ab282c4fc3bc2144a9efc8018796a1cba1e97f Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 18 Jan 2024 04:28:03 -0500 Subject: [PATCH 74/74] CI: make sure it produces artifacts for esfm-con --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fe4d4579e..115571cf1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: Build furnace on: push: - branches: master + branches: [master, esfm-contest] pull_request: branches: master