├── README.md └── sfxr ├── CHANGES.txt ├── CMakeLists.txt ├── INSTALL.txt ├── LICENSE.txt ├── Makefile.am ├── README.txt ├── autogen.sh ├── configure.ac ├── data ├── sfxr.1 └── sfxr.desktop ├── images ├── font.tga ├── ld48.tga ├── sfxr.bmp └── sfxr.png └── source ├── main.cpp ├── sdlkit.cpp ├── sdlkit.h ├── tools.cpp └── tools.h /README.md: -------------------------------------------------------------------------------- 1 | sfxr is a generator for simple sound effects, created by DrPetter (http://www.drpetter.se). You can use it to create easy retro sounds for remixing or video games. 2 | 3 | sfxr News: 4 | 5 | Increpare has created bfxr, a web remake of sfxr with many more exciting features: http://www.bfxr.net/ 6 | 7 | Thomas Vian from superflashbros.net ported sfxr to ActionScript 3. You can find it here: http://code.google.com/p/as3sfxr/ or you can get it like this: svn checkout http://sfxr.googlecode.com/svn/branches/as3sfxr as3sfxr 8 | 9 | Chris Gassib has ported sfxr to the iPhone. You should be able to find it in the App Store. The code has been added as a branch that you can access like so: svn checkout http://sfxr.googlecode.com/svn/branches/sfxr-iPhoneOS sfxr-iPhoneOS 10 | -------------------------------------------------------------------------------- /sfxr/CHANGES.txt: -------------------------------------------------------------------------------- 1 | sfxr-sdl-1.0 2 | ------------ 3 | * Initial SDL port of sfxr by mjau/GerryJJ 4 | 5 | sfxr-sdl-1.1 6 | ------------ 7 | * Various small improvements and 1 bugfix by Hans de Goede 8 | : 9 | * Fix a small bug in the audio setup which could cause a quite noticable 10 | delay between pressing a button and hearing the sound 11 | * Add an icon and .desktop file 12 | * Add a make install target, note: hardcoded to /usr but it does understand 13 | the DESTDIR make parameter 14 | 15 | sfxr-sdl-1.2.0 16 | ------------- 17 | * Changed version number convention: .. 18 | * Added checkbox: Drag bars (the old default) 19 | * Clicking sets the value of a slider 20 | * Sound now plays when an attribute is clicked (a more involved change, like looping, would be needed for dragging) 21 | * Sound now plays on waveform change 22 | * Very simple undo (one slider change) with Z 23 | * Removed GTK save/load dialog 24 | * Added CMake build -------------------------------------------------------------------------------- /sfxr/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010 Bart Veldstra 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | # THE SOFTWARE. 20 | 21 | cmake_minimum_required (VERSION 2.6) 22 | project (sfxr) 23 | 24 | find_package(SDL REQUIRED) 25 | include_directories(include ${SDL_INCLUDE_DIR}) 26 | link_libraries(${SDL_LIBRARY}) 27 | 28 | add_definitions("-Wall --pedantic -O2") 29 | 30 | set(SRC_FILES 31 | source/main.cpp 32 | source/sdlkit.cpp 33 | source/tools.cpp 34 | ) 35 | 36 | add_executable(sfxr ${SRC_FILES}) 37 | 38 | install(TARGETS sfxr 39 | RUNTIME DESTINATION bin) 40 | install(FILES images/font.tga images/ld48.tga images/sfxr.bmp 41 | DESTINATION share/sfxr/images) 42 | install(FILES images/sfxr.png 43 | DESTINATION share/icons/hicolor/48x48/apps) 44 | install(FILES data/sfxr.1 45 | DESTINATION share/man/man1) 46 | install(FILES data/sfxr.desktop 47 | DESTINATION share/applications) 48 | 49 | -------------------------------------------------------------------------------- /sfxr/INSTALL.txt: -------------------------------------------------------------------------------- 1 | You can build and install with either Automake or CMake. Use CMake if you are not using Linux/Unix. 2 | 3 | Automake: 4 | ./autogen.sh 5 | ./configure 6 | make 7 | sudo make install 8 | 9 | CMake (not GUI): 10 | cmake -G Unix\ Makefiles 11 | make 12 | sudo make install 13 | 14 | Note the install is hardcoded to /usr, you can also run sfxr from the build 15 | dir after make (./sfxr) without installing. 16 | 17 | -------------------------------------------------------------------------------- /sfxr/LICENSE.txt: -------------------------------------------------------------------------------- 1 | ----------------------------- 2 | sfxr - sound effect generator 3 | ----------------------------- 4 | by DrPetter, 2007-12-14 5 | developed for LD48#10 6 | ----------------------------- 7 | 8 | 9 | License 10 | ------- 11 | 12 | Basically, I don't care what you do with it, anything goes. 13 | 14 | To please all the troublesome folks who request a formal license, 15 | I attach the "MIT license" as follows: 16 | 17 | -- 18 | 19 | Copyright (c) 2007 Tomas Pettersson 20 | 21 | Permission is hereby granted, free of charge, to any person 22 | obtaining a copy of this software and associated documentation 23 | files (the "Software"), to deal in the Software without 24 | restriction, including without limitation the rights to use, 25 | copy, modify, merge, publish, distribute, sublicense, and/or sell 26 | copies of the Software, and to permit persons to whom the 27 | Software is furnished to do so, subject to the following 28 | conditions: 29 | 30 | The above copyright notice and this permission notice shall be 31 | included in all copies or substantial portions of the Software. 32 | 33 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 39 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 40 | OTHER DEALINGS IN THE SOFTWARE. 41 | -------------------------------------------------------------------------------- /sfxr/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS = foreign 2 | 3 | CFLAGS = --pedantic -Wall -O2 4 | CXXFLAGS=$(CFLAGS) `sdl-config --cflags` 5 | CPPFLAGS=-DDATADIR='$(pkgdatadir)' 6 | LDFLAGS=`sdl-config --libs` 7 | 8 | bin_PROGRAMS = sfxr 9 | 10 | sfxr_SOURCES := source/main.cpp source/sdlkit.cpp source/tools.cpp source/sdlkit.h source/tools.h 11 | -------------------------------------------------------------------------------- /sfxr/README.txt: -------------------------------------------------------------------------------- 1 | ----------------------------- 2 | sfxr - sound effect generator 3 | ----------------------------- 4 | by DrPetter, 2007-12-14 5 | developed for LD48#10 6 | ----------------------------- 7 | 8 | 9 | Basic usage: 10 | 11 | Start the application, then hit 12 | some of the buttons on the left 13 | side to generate random sounds 14 | matching the button descriptions. 15 | 16 | Press "Export .WAV" to save the 17 | current sound as a WAV audio file. 18 | Click the buttons below to change 19 | WAV format in terms of bits per 20 | sample and sample rate. 21 | 22 | If you find a sound that is sort 23 | of interesting but not quite what 24 | you want, you can drag some sliders 25 | around until it sounds better. 26 | 27 | The Randomize button generates 28 | something completely random. 29 | 30 | Mutate slightly alters the current 31 | parameters to automatically create 32 | a variation of the sound. 33 | 34 | 35 | 36 | Advanced usage: 37 | 38 | Figure out what each slider does and 39 | use them to adjust particular aspects 40 | of the current sound... 41 | 42 | Press the right mouse button on a slider 43 | to reset it to a value of zero. 44 | 45 | Press Space or Enter to play the current sound. 46 | 47 | The Save/Load sound buttons allow saving 48 | and loading of program parameters to work 49 | on a sound over several sessions. 50 | 51 | Volume setting is saved with the sound and 52 | exported to WAV. If you increase it too much 53 | there's a risk of clipping. 54 | 55 | Some parameters influence the sound during 56 | playback (particularly when using a non-zero 57 | repeat speed), and dragging these sliders 58 | can cause some interesting effects. 59 | To record this you will need to use an external 60 | recording application, for instance Audacity. 61 | Set the recording source in that application 62 | to "Wave", "Stereo Mix", "Mixed Output" or similar. 63 | 64 | Using an external sound editor to capture and edit 65 | sound can also be used to string several sounds 66 | together for more complex results. 67 | 68 | Parameter description: 69 | - The top four buttons select base waveform 70 | - First four parameters control the volume envelope 71 | Attack is the beginning of the sound, 72 | longer attack means a smoother start. 73 | Sustain is how long the volume is held constant 74 | before fading out. 75 | Increase Sustain Punch to cause a popping 76 | effect with increased (and falling) volume 77 | during the sustain phase. 78 | Decay is the fade-out time. 79 | - Next six are for controlling the sound pitch or 80 | frequency. 81 | Start frequency is pretty obvious. Has a large 82 | impact on the overall sound. 83 | Min frequency represents a cutoff that stops all 84 | sound if it's passed during a downward slide. 85 | Slide sets the speed at which the frequency should 86 | be swept (up or down). 87 | Delta slide is the "slide of slide", or rate of change 88 | in the slide speed. 89 | Vibrato depth/speed makes for an oscillating 90 | frequency effect at various strengths and rates. 91 | - Then we have two parameters for causing an abrupt 92 | change in pitch after a ceratin delay. 93 | Amount is pitch change (up or down) 94 | and Speed indicates time to wait before changing 95 | the pitch. 96 | - Following those are two parameters specific to the 97 | squarewave waveform. 98 | The duty cycle of a square describes its shape 99 | in terms of how large the positive vs negative 100 | sections are. It can be swept up or down by 101 | changing the second parameter. 102 | - Repeat speed, when not zero, causes the frequency 103 | and duty parameters to be reset at regular intervals 104 | while the envelope and filter continue unhindered. 105 | This can make for some interesting pulsating effects. 106 | - Phaser offset overlays a delayed copy of the audio 107 | stream on top of itself, resulting in a kind of tight 108 | reverb or sci-fi effect. 109 | This parameter can also be swept like many others. 110 | - Finally, the bottom five sliders control two filters 111 | which are applied after all other effects. 112 | The first one is a resonant lowpass filter which has 113 | a sweepable cutoff frequency. 114 | The other is a highpass filter which can be used to 115 | remove undesired low frequency hum in "light" sounds. 116 | 117 | 118 | ---------------------- 119 | 120 | 121 | License 122 | ------- 123 | 124 | Basically, I don't care what you do with it, anything goes. 125 | 126 | To please all the troublesome folks who request a formal license, 127 | I attach the "MIT license" as follows: 128 | 129 | -- 130 | 131 | Copyright (c) 2007 Tomas Pettersson 132 | 133 | Permission is hereby granted, free of charge, to any person 134 | obtaining a copy of this software and associated documentation 135 | files (the "Software"), to deal in the Software without 136 | restriction, including without limitation the rights to use, 137 | copy, modify, merge, publish, distribute, sublicense, and/or sell 138 | copies of the Software, and to permit persons to whom the 139 | Software is furnished to do so, subject to the following 140 | conditions: 141 | 142 | The above copyright notice and this permission notice shall be 143 | included in all copies or substantial portions of the Software. 144 | 145 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 146 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 147 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 148 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 149 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 150 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 151 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 152 | OTHER DEALINGS IN THE SOFTWARE. 153 | 154 | 155 | 156 | ---------------------- 157 | 158 | http://www.drpetter.se 159 | 160 | drpetter@gmail.com 161 | 162 | ---------------------- 163 | 164 | -------------------------------------------------------------------------------- /sfxr/autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | aclocal \ 4 | && autoheader \ 5 | && automake --add-missing \ 6 | && autoconf -------------------------------------------------------------------------------- /sfxr/configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ([2.64]) 5 | AC_INIT([sfxr], [1.2.0], [grimfang4@gmail.com],[sfxr-1.2.0.tar],[http://code.google.com/p/sfxr]) 6 | AM_INIT_AUTOMAKE(sfxr, 1.2.0) 7 | AM_CONFIG_HEADER(config.h:config.in) 8 | 9 | AC_CONFIG_SRCDIR([source/sdlkit.h]) 10 | 11 | 12 | # Checks for programs. 13 | AC_PROG_CXX 14 | AC_PROG_CC 15 | AC_PROG_INSTALL 16 | 17 | # Checks for libraries. 18 | 19 | # Checks for header files. 20 | AC_CHECK_HEADERS([malloc.h stdlib.h string.h]) 21 | 22 | AC_CHECK_LIB(SDL, SDL_Init, [], [ 23 | echo "**Error** libSDL was not found." 24 | exit -1 25 | ]) 26 | 27 | # Checks for typedefs, structures, and compiler characteristics. 28 | AC_HEADER_STDBOOL 29 | 30 | # Checks for library functions. 31 | AC_FUNC_ERROR_AT_LINE 32 | AC_FUNC_MALLOC 33 | AC_CHECK_FUNCS([atexit memset pow]) 34 | 35 | 36 | 37 | AC_OUTPUT(Makefile) 38 | -------------------------------------------------------------------------------- /sfxr/data/sfxr.1: -------------------------------------------------------------------------------- 1 | '\" t 2 | .\" Title: sfxr 3 | .\" Author: [see the "AUTHOR" section] 4 | .\" Generator: DocBook XSL Stylesheets v1.75.2 5 | .\" Date: 04/04/2010 6 | .\" Manual: \ \& 7 | .\" Source: \ \& 8 | .\" Language: English 9 | .\" 10 | .TH "SFXR" "1" "04/04/2010" "\ \&" "\ \&" 11 | .\" ----------------------------------------------------------------- 12 | .\" * Define some portability stuff 13 | .\" ----------------------------------------------------------------- 14 | .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 15 | .\" http://bugs.debian.org/507673 16 | .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html 17 | .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 18 | .ie \n(.g .ds Aq \(aq 19 | .el .ds Aq ' 20 | .\" ----------------------------------------------------------------- 21 | .\" * set default formatting 22 | .\" ----------------------------------------------------------------- 23 | .\" disable hyphenation 24 | .nh 25 | .\" disable justification (adjust text to left margin only) 26 | .ad l 27 | .\" ----------------------------------------------------------------- 28 | .\" * MAIN CONTENT STARTS HERE * 29 | .\" ----------------------------------------------------------------- 30 | .SH "NAME" 31 | sfxr \- sound effects generator 32 | .SH "DESCRIPTION" 33 | .sp 34 | This is a little tool made in connection with the 10th Ludum Dare competition held in December 2007\&. Its original purpose was to provide a simple means of getting basic sound effects into a game for those people who were working hard to get their entries done within the 48 hours and didn\(cqt have time to spend looking for suitable ways of doing this\&. 35 | .sp 36 | The idea was that they could just hit a few buttons in this application and get some largely randomized effects that were custom in the sense that the user could accept/reject each proposed sound\&. 37 | .SH "BASIC USAGE" 38 | .sp 39 | Start the application, then hit some of the buttons on the left side to generate random sounds matching the button descriptions\&. 40 | .sp 41 | Press "Export \&.WAV" to save the current sound as a WAV audio file\&. Click the buttons below to change WAV format in terms of bits per sample and sample rate\&. 42 | .sp 43 | If you find a sound that is sort of interesting but not quite what you want, you can drag some sliders around until it sounds better\&. 44 | .sp 45 | The Randomize button generates something completely random\&. 46 | .sp 47 | Mutate slightly alters the current parameters to automatically create a variation of the sound\&. 48 | .SH "ADVANCED USAGE" 49 | .sp 50 | Figure out what each slider does and use them to adjust particular aspects of the current sound\&... 51 | .sp 52 | Press the right mouse button on a slider to reset it to a value of zero\&. 53 | .sp 54 | Press Space or Enter to play the current sound\&. 55 | .sp 56 | The Save/Load sound buttons allow saving and loading of program parameters to work on a sound over several sessions\&. 57 | .sp 58 | Volume setting is saved with the sound and exported to WAV\&. If you increase it too much there\(cqs a risk of clipping\&. 59 | .sp 60 | Some parameters influence the sound during playback (particularly when using a non\-zero repeat speed), and dragging these sliders can cause some interesting effects\&. To record this you will need to use an external recording application, for instance Audacity\&. Set the recording source in that application to "Wave", "Stereo Mix", "Mixed Output" or similar\&. 61 | .sp 62 | Using an external sound editor to capture and edit sound can also be used to string several sounds together for more complex results\&. 63 | .SH "SLIDER DESCRIPTIONS" 64 | .PP 65 | \fBSquarewave\fR, \fBSawtooth\fR, \fBSinewave\fR, \fBNoise\fR 66 | .RS 4 67 | Selects the base waveform\&. 68 | .RE 69 | .PP 70 | \fBAttack time\fR 71 | .RS 4 72 | The beginning of the sound, longer attack means a smoother start\&. 73 | .RE 74 | .PP 75 | \fBSustain time\fR 76 | .RS 4 77 | How long the volume is held constant before fading out\&. 78 | .RE 79 | .PP 80 | \fBSustain punch\fR 81 | .RS 4 82 | Cause a popping effect with increased (and falling) volume during the sustain phase\&. 83 | .RE 84 | .PP 85 | \fBDecay time\fR 86 | .RS 4 87 | Fade\-out time\&. 88 | .RE 89 | .PP 90 | \fBStart frequency\fR 91 | .RS 4 92 | Starting frequency of the sample\&. Has a large impact on the overall sound\&. 93 | .RE 94 | .PP 95 | \fBMin frequency\fR 96 | .RS 4 97 | Represents a cutoff that stops all sound if it\(cqs passed during a downward slide\&. 98 | .RE 99 | .PP 100 | \fBSlide\fR 101 | .RS 4 102 | Sets the speed at which the frequency should be swept (up or down)\&. 103 | .RE 104 | .PP 105 | \fBDelta slide\fR 106 | .RS 4 107 | The "slide of slide", or rate of change in the slide speed\&. 108 | .RE 109 | .PP 110 | \fBVibrato depth\fR, \fBVibrato speed\fR 111 | .RS 4 112 | Makes for an oscillating frequency effect at various strengths and rates\&. 113 | .RE 114 | .PP 115 | \fBChange amount\fR 116 | .RS 4 117 | Pitch amount to change (up or down) after a certain delay\&. 118 | .RE 119 | .PP 120 | \fBChange speed\fR 121 | .RS 4 122 | Time to wait before changing the pitch\&. 123 | .RE 124 | .PP 125 | \fBSquare duty\fR 126 | .RS 4 127 | Describes its shape in terms of how large the positive versus negative sections are\&. This option applies to 128 | \fBSquarewave\fR 129 | waveforms only\&. 130 | .RE 131 | .PP 132 | \fBDuty sweep\fR 133 | .RS 4 134 | Sweep amount of the waveform\&. This option applies to 135 | \fBSquarewave\fR 136 | waveforms only\&. 137 | .RE 138 | .PP 139 | \fBRepeat speed\fR 140 | .RS 4 141 | When not zero, this parameter causes the frequency and duty parameters to be reset at regular intervals while the envelope and filter continue unhindered\&. This can make for some interesting pulsating effects\&. 142 | .RE 143 | .PP 144 | \fBPhaser offset\fR 145 | .RS 4 146 | Overlay a delayed copy of the audio stream on top of itself, resulting in a kind of tight reverb or sci\-fi effect\&. 147 | .RE 148 | .PP 149 | \fBPhaser sweep\fR 150 | .RS 4 151 | Sweep amount of the 152 | \fBphaser offset\fR\&. 153 | .RE 154 | .PP 155 | \fBLP filter cutoff\fR 156 | .RS 4 157 | Set the cutoff for the lowpass filter\&. 158 | .RE 159 | .PP 160 | \fBLP filter cutoff sweep\fR 161 | .RS 4 162 | Sweep amount for the 163 | \fBLP filter cutoff\fR\&. 164 | .RE 165 | .PP 166 | \fBLP filter resonance\fR 167 | .RS 4 168 | Set the resonance for the lowpass filter\&. 169 | .RE 170 | .PP 171 | \fBHP filter cutoff\fR 172 | .RS 4 173 | Set the cutoff for the highpass filter\&. It can be used to remove undesired low frequency hum in "light" sounds\&. 174 | .RE 175 | .PP 176 | \fBHP filter cutoff sweep\fR 177 | .RS 4 178 | Sweep amount for the 179 | \fBHP filter cutoff\fR\&. 180 | .RE 181 | .SH "COPYING" 182 | .sp 183 | Copyright (C) 2007 Tomas Pettersson \&. Permission is granted to copy, distribute and/or modify the software under the terms of the MIT license\&. 184 | .SH "RESOURCES" 185 | .sp 186 | Main web site: http://code\&.google\&.com/p/sfxr/ 187 | .sp 188 | Original author web site: http://www\&.drpetter\&.se/ 189 | .SH "AUTHOR" 190 | .sp 191 | This manual page is written by Bart Veldstra , based on the original \fBreadme\&.txt\fR written by Tomas Pettersson\&. Permission is granted to copy, distribute and/or modify this document under the terms of the MIT license\&. 192 | -------------------------------------------------------------------------------- /sfxr/data/sfxr.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=sfxr 3 | Comment=Generate sound effects 4 | Exec=sfxr 5 | Icon=sfxr 6 | Terminal=false 7 | StartupNotify=false 8 | Type=Application 9 | Categories=AudioVideo;Audio;AudioVideoEditing; 10 | -------------------------------------------------------------------------------- /sfxr/images/font.tga: -------------------------------------------------------------------------------- 1 | 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000TRUEVISION-XFILE. -------------------------------------------------------------------------------- /sfxr/images/ld48.tga: -------------------------------------------------------------------------------- 1 | ]000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000TRUEVISION-XFILE. -------------------------------------------------------------------------------- /sfxr/images/sfxr.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grimfang4/sfxr/48ce8f1ee3951c6313cf40948a65d8f76df4d77e/sfxr/images/sfxr.bmp -------------------------------------------------------------------------------- /sfxr/images/sfxr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grimfang4/sfxr/48ce8f1ee3951c6313cf40948a65d8f76df4d77e/sfxr/images/sfxr.png -------------------------------------------------------------------------------- /sfxr/source/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2007 Tomas Pettersson 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | */ 23 | 24 | #include "sdlkit.h" 25 | #include "tools.h" 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "SDL.h" 35 | 36 | #define rnd(n) (rand()%(n+1)) 37 | 38 | #define PI 3.14159265f 39 | 40 | float frnd(float range) 41 | { 42 | return (float)rnd(10000)/10000*range; 43 | } 44 | 45 | 46 | Spriteset font; 47 | Spriteset ld48; 48 | 49 | struct Category 50 | { 51 | char name[32]; 52 | }; 53 | 54 | Category categories[10]; 55 | 56 | int wave_type; 57 | 58 | float p_base_freq; 59 | float p_freq_limit; 60 | float p_freq_ramp; 61 | float p_freq_dramp; 62 | float p_duty; 63 | float p_duty_ramp; 64 | 65 | float p_vib_strength; 66 | float p_vib_speed; 67 | float p_vib_delay; 68 | 69 | float p_env_attack; 70 | float p_env_sustain; 71 | float p_env_decay; 72 | float p_env_punch; 73 | 74 | bool filter_on; 75 | float p_lpf_resonance; 76 | float p_lpf_freq; 77 | float p_lpf_ramp; 78 | float p_hpf_freq; 79 | float p_hpf_ramp; 80 | 81 | float p_pha_offset; 82 | float p_pha_ramp; 83 | 84 | float p_repeat_speed; 85 | 86 | float p_arp_speed; 87 | float p_arp_mod; 88 | 89 | float master_vol=0.05f; 90 | 91 | float sound_vol=0.5f; 92 | 93 | 94 | bool playing_sample=false; 95 | int phase; 96 | double fperiod; 97 | double fmaxperiod; 98 | double fslide; 99 | double fdslide; 100 | int period; 101 | float square_duty; 102 | float square_slide; 103 | int env_stage; 104 | int env_time; 105 | int env_length[3]; 106 | float env_vol; 107 | float fphase; 108 | float fdphase; 109 | int iphase; 110 | float phaser_buffer[1024]; 111 | int ipp; 112 | float noise_buffer[32]; 113 | float fltp; 114 | float fltdp; 115 | float fltw; 116 | float fltw_d; 117 | float fltdmp; 118 | float fltphp; 119 | float flthp; 120 | float flthp_d; 121 | float vib_phase; 122 | float vib_speed; 123 | float vib_amp; 124 | int rep_time; 125 | int rep_limit; 126 | int arp_time; 127 | int arp_limit; 128 | double arp_mod; 129 | 130 | float* vselected=NULL; 131 | int vcurbutton=-1; 132 | 133 | int wav_bits=16; 134 | int wav_freq=44100; 135 | 136 | int file_sampleswritten; 137 | float filesample=0.0f; 138 | int fileacc=0; 139 | 140 | float* lastChanged = NULL; // For undo 141 | float undoValue = 0.0f; 142 | 143 | void SetUndo(float* valueptr, float oldValue) 144 | { 145 | lastChanged = valueptr; 146 | undoValue = oldValue; 147 | } 148 | 149 | void Undo() 150 | { 151 | if(lastChanged != NULL) 152 | { 153 | *lastChanged = undoValue; 154 | lastChanged = NULL; 155 | undoValue = 0.0f; 156 | } 157 | } 158 | 159 | void ResetParams() 160 | { 161 | lastChanged = NULL; 162 | wave_type=0; 163 | 164 | p_base_freq=0.3f; 165 | p_freq_limit=0.0f; 166 | p_freq_ramp=0.0f; 167 | p_freq_dramp=0.0f; 168 | p_duty=0.0f; 169 | p_duty_ramp=0.0f; 170 | 171 | p_vib_strength=0.0f; 172 | p_vib_speed=0.0f; 173 | p_vib_delay=0.0f; 174 | 175 | p_env_attack=0.0f; 176 | p_env_sustain=0.3f; 177 | p_env_decay=0.4f; 178 | p_env_punch=0.0f; 179 | 180 | filter_on=false; 181 | p_lpf_resonance=0.0f; 182 | p_lpf_freq=1.0f; 183 | p_lpf_ramp=0.0f; 184 | p_hpf_freq=0.0f; 185 | p_hpf_ramp=0.0f; 186 | 187 | p_pha_offset=0.0f; 188 | p_pha_ramp=0.0f; 189 | 190 | p_repeat_speed=0.0f; 191 | 192 | p_arp_speed=0.0f; 193 | p_arp_mod=0.0f; 194 | } 195 | 196 | bool LoadSettings(char* filename) 197 | { 198 | lastChanged = NULL; 199 | FILE* file=fopen(filename, "rb"); 200 | if(!file) 201 | return false; 202 | 203 | size_t n; 204 | (void)n; 205 | int version=0; 206 | n = fread(&version, 1, sizeof(int), file); 207 | if(version!=100 && version!=101 && version!=102) 208 | return false; 209 | 210 | n = fread(&wave_type, 1, sizeof(int), file); 211 | 212 | sound_vol=0.5f; 213 | if(version==102) 214 | n = fread(&sound_vol, 1, sizeof(float), file); 215 | 216 | n = fread(&p_base_freq, 1, sizeof(float), file); 217 | n = fread(&p_freq_limit, 1, sizeof(float), file); 218 | n = fread(&p_freq_ramp, 1, sizeof(float), file); 219 | if(version>=101) 220 | n = fread(&p_freq_dramp, 1, sizeof(float), file); 221 | n = fread(&p_duty, 1, sizeof(float), file); 222 | n = fread(&p_duty_ramp, 1, sizeof(float), file); 223 | 224 | n = fread(&p_vib_strength, 1, sizeof(float), file); 225 | n = fread(&p_vib_speed, 1, sizeof(float), file); 226 | n = fread(&p_vib_delay, 1, sizeof(float), file); 227 | 228 | n = fread(&p_env_attack, 1, sizeof(float), file); 229 | n = fread(&p_env_sustain, 1, sizeof(float), file); 230 | n = fread(&p_env_decay, 1, sizeof(float), file); 231 | n = fread(&p_env_punch, 1, sizeof(float), file); 232 | 233 | n = fread(&filter_on, 1, sizeof(bool), file); 234 | n = fread(&p_lpf_resonance, 1, sizeof(float), file); 235 | n = fread(&p_lpf_freq, 1, sizeof(float), file); 236 | n = fread(&p_lpf_ramp, 1, sizeof(float), file); 237 | n = fread(&p_hpf_freq, 1, sizeof(float), file); 238 | n = fread(&p_hpf_ramp, 1, sizeof(float), file); 239 | 240 | n = fread(&p_pha_offset, 1, sizeof(float), file); 241 | n = fread(&p_pha_ramp, 1, sizeof(float), file); 242 | 243 | n = fread(&p_repeat_speed, 1, sizeof(float), file); 244 | 245 | if(version>=101) 246 | { 247 | n = fread(&p_arp_speed, 1, sizeof(float), file); 248 | n = fread(&p_arp_mod, 1, sizeof(float), file); 249 | } 250 | 251 | fclose(file); 252 | return true; 253 | } 254 | 255 | bool SaveSettings(char* filename) 256 | { 257 | FILE* file=fopen(filename, "wb"); 258 | if(!file) 259 | return false; 260 | 261 | int version=102; 262 | fwrite(&version, 1, sizeof(int), file); 263 | 264 | fwrite(&wave_type, 1, sizeof(int), file); 265 | 266 | fwrite(&sound_vol, 1, sizeof(float), file); 267 | 268 | fwrite(&p_base_freq, 1, sizeof(float), file); 269 | fwrite(&p_freq_limit, 1, sizeof(float), file); 270 | fwrite(&p_freq_ramp, 1, sizeof(float), file); 271 | fwrite(&p_freq_dramp, 1, sizeof(float), file); 272 | fwrite(&p_duty, 1, sizeof(float), file); 273 | fwrite(&p_duty_ramp, 1, sizeof(float), file); 274 | 275 | fwrite(&p_vib_strength, 1, sizeof(float), file); 276 | fwrite(&p_vib_speed, 1, sizeof(float), file); 277 | fwrite(&p_vib_delay, 1, sizeof(float), file); 278 | 279 | fwrite(&p_env_attack, 1, sizeof(float), file); 280 | fwrite(&p_env_sustain, 1, sizeof(float), file); 281 | fwrite(&p_env_decay, 1, sizeof(float), file); 282 | fwrite(&p_env_punch, 1, sizeof(float), file); 283 | 284 | fwrite(&filter_on, 1, sizeof(bool), file); 285 | fwrite(&p_lpf_resonance, 1, sizeof(float), file); 286 | fwrite(&p_lpf_freq, 1, sizeof(float), file); 287 | fwrite(&p_lpf_ramp, 1, sizeof(float), file); 288 | fwrite(&p_hpf_freq, 1, sizeof(float), file); 289 | fwrite(&p_hpf_ramp, 1, sizeof(float), file); 290 | 291 | fwrite(&p_pha_offset, 1, sizeof(float), file); 292 | fwrite(&p_pha_ramp, 1, sizeof(float), file); 293 | 294 | fwrite(&p_repeat_speed, 1, sizeof(float), file); 295 | 296 | fwrite(&p_arp_speed, 1, sizeof(float), file); 297 | fwrite(&p_arp_mod, 1, sizeof(float), file); 298 | 299 | fclose(file); 300 | return true; 301 | } 302 | 303 | void ResetSample(bool restart) 304 | { 305 | if(!restart) 306 | phase=0; 307 | fperiod=100.0/(p_base_freq*p_base_freq+0.001); 308 | period=(int)fperiod; 309 | fmaxperiod=100.0/(p_freq_limit*p_freq_limit+0.001); 310 | fslide=1.0-pow((double)p_freq_ramp, 3.0)*0.01; 311 | fdslide=-pow((double)p_freq_dramp, 3.0)*0.000001; 312 | square_duty=0.5f-p_duty*0.5f; 313 | square_slide=-p_duty_ramp*0.00005f; 314 | if(p_arp_mod>=0.0f) 315 | arp_mod=1.0-pow((double)p_arp_mod, 2.0)*0.9; 316 | else 317 | arp_mod=1.0+pow((double)p_arp_mod, 2.0)*10.0; 318 | arp_time=0; 319 | arp_limit=(int)(pow(1.0f-p_arp_speed, 2.0f)*20000+32); 320 | if(p_arp_speed==1.0f) 321 | arp_limit=0; 322 | if(!restart) 323 | { 324 | // reset filter 325 | fltp=0.0f; 326 | fltdp=0.0f; 327 | fltw=pow(p_lpf_freq, 3.0f)*0.1f; 328 | fltw_d=1.0f+p_lpf_ramp*0.0001f; 329 | fltdmp=5.0f/(1.0f+pow(p_lpf_resonance, 2.0f)*20.0f)*(0.01f+fltw); 330 | if(fltdmp>0.8f) fltdmp=0.8f; 331 | fltphp=0.0f; 332 | flthp=pow(p_hpf_freq, 2.0f)*0.1f; 333 | flthp_d=1.0+p_hpf_ramp*0.0003f; 334 | // reset vibrato 335 | vib_phase=0.0f; 336 | vib_speed=pow(p_vib_speed, 2.0f)*0.01f; 337 | vib_amp=p_vib_strength*0.5f; 338 | // reset envelope 339 | env_vol=0.0f; 340 | env_stage=0; 341 | env_time=0; 342 | env_length[0]=(int)(p_env_attack*p_env_attack*100000.0f); 343 | env_length[1]=(int)(p_env_sustain*p_env_sustain*100000.0f); 344 | env_length[2]=(int)(p_env_decay*p_env_decay*100000.0f); 345 | 346 | fphase=pow(p_pha_offset, 2.0f)*1020.0f; 347 | if(p_pha_offset<0.0f) fphase=-fphase; 348 | fdphase=pow(p_pha_ramp, 2.0f)*1.0f; 349 | if(p_pha_ramp<0.0f) fdphase=-fdphase; 350 | iphase=abs((int)fphase); 351 | ipp=0; 352 | for(int i=0;i<1024;i++) 353 | phaser_buffer[i]=0.0f; 354 | 355 | for(int i=0;i<32;i++) 356 | noise_buffer[i]=frnd(2.0f)-1.0f; 357 | 358 | rep_time=0; 359 | rep_limit=(int)(pow(1.0f-p_repeat_speed, 2.0f)*20000+32); 360 | if(p_repeat_speed==0.0f) 361 | rep_limit=0; 362 | } 363 | } 364 | 365 | void PlaySample() 366 | { 367 | ResetSample(false); 368 | playing_sample=true; 369 | } 370 | 371 | void SynthSample(int length, float* buffer, FILE* file) 372 | { 373 | for(int i=0;i=rep_limit) 380 | { 381 | rep_time=0; 382 | ResetSample(true); 383 | } 384 | 385 | // frequency envelopes/arpeggios 386 | arp_time++; 387 | if(arp_limit!=0 && arp_time>=arp_limit) 388 | { 389 | arp_limit=0; 390 | fperiod*=arp_mod; 391 | } 392 | fslide+=fdslide; 393 | fperiod*=fslide; 394 | if(fperiod>fmaxperiod) 395 | { 396 | fperiod=fmaxperiod; 397 | if(p_freq_limit>0.0f) 398 | playing_sample=false; 399 | } 400 | float rfperiod=fperiod; 401 | if(vib_amp>0.0f) 402 | { 403 | vib_phase+=vib_speed; 404 | rfperiod=fperiod*(1.0+sin(vib_phase)*vib_amp); 405 | } 406 | period=(int)rfperiod; 407 | if(period<8) period=8; 408 | square_duty+=square_slide; 409 | if(square_duty<0.0f) square_duty=0.0f; 410 | if(square_duty>0.5f) square_duty=0.5f; 411 | // volume envelope 412 | env_time++; 413 | if(env_time>env_length[env_stage]) 414 | { 415 | env_time=0; 416 | env_stage++; 417 | if(env_stage==3) 418 | playing_sample=false; 419 | } 420 | if(env_stage==0) 421 | env_vol=(float)env_time/env_length[0]; 422 | if(env_stage==1) 423 | env_vol=1.0f+pow(1.0f-(float)env_time/env_length[1], 1.0f)*2.0f*p_env_punch; 424 | if(env_stage==2) 425 | env_vol=1.0f-(float)env_time/env_length[2]; 426 | 427 | // phaser step 428 | fphase+=fdphase; 429 | iphase=abs((int)fphase); 430 | if(iphase>1023) iphase=1023; 431 | 432 | if(flthp_d!=0.0f) 433 | { 434 | flthp*=flthp_d; 435 | if(flthp<0.00001f) flthp=0.00001f; 436 | if(flthp>0.1f) flthp=0.1f; 437 | } 438 | 439 | float ssample=0.0f; 440 | for(int si=0;si<8;si++) // 8x supersampling 441 | { 442 | float sample=0.0f; 443 | phase++; 444 | if(phase>=period) 445 | { 446 | // phase=0; 447 | phase%=period; 448 | if(wave_type==3) 449 | for(int i=0;i<32;i++) 450 | noise_buffer[i]=frnd(2.0f)-1.0f; 451 | } 452 | // base waveform 453 | float fp=(float)phase/period; 454 | switch(wave_type) 455 | { 456 | case 0: // square 457 | if(fp0.1f) fltw=0.1f; 477 | if(p_lpf_freq!=1.0f) 478 | { 479 | fltdp+=(sample-fltp)*fltw; 480 | fltdp-=fltdp*fltdmp; 481 | } 482 | else 483 | { 484 | fltp=sample; 485 | fltdp=0.0f; 486 | } 487 | fltp+=fltdp; 488 | // hp filter 489 | fltphp+=fltp-pp; 490 | fltphp-=fltphp*flthp; 491 | sample=fltphp; 492 | // phaser 493 | phaser_buffer[ipp&1023]=sample; 494 | sample+=phaser_buffer[(ipp-iphase+1024)&1023]; 495 | ipp=(ipp+1)&1023; 496 | // final accumulation and envelope application 497 | ssample+=sample*env_vol; 498 | } 499 | ssample=ssample/8*master_vol; 500 | 501 | ssample*=2.0f*sound_vol; 502 | 503 | if(buffer!=NULL) 504 | { 505 | if(ssample>1.0f) ssample=1.0f; 506 | if(ssample<-1.0f) ssample=-1.0f; 507 | *buffer++=ssample; 508 | } 509 | if(file!=NULL) 510 | { 511 | // quantize depending on format 512 | // accumulate/count to accomodate variable sample rate? 513 | ssample*=4.0f; // arbitrary gain to get reasonable output volume... 514 | if(ssample>1.0f) ssample=1.0f; 515 | if(ssample<-1.0f) ssample=-1.0f; 516 | filesample+=ssample; 517 | fileacc++; 518 | if(wav_freq==44100 || fileacc==2) 519 | { 520 | filesample/=fileacc; 521 | fileacc=0; 522 | if(wav_bits==16) 523 | { 524 | short isample=(short)(filesample*32000); 525 | fwrite(&isample, 1, 2, file); 526 | } 527 | else 528 | { 529 | unsigned char isample=(unsigned char)(filesample*127+128); 530 | fwrite(&isample, 1, 1, file); 531 | } 532 | filesample=0.0f; 533 | } 534 | file_sampleswritten++; 535 | } 536 | } 537 | } 538 | 539 | DPInput *input; 540 | bool mute_stream; 541 | 542 | //lets use SDL instead 543 | static void SDLAudioCallback(void *userdata, Uint8 *stream, int len) 544 | { 545 | if (playing_sample && !mute_stream) 546 | { 547 | unsigned int l = len/2; 548 | float* fbuf = new float[l]; 549 | memset(fbuf, 0, sizeof(fbuf)); 550 | SynthSample(l, fbuf, NULL); 551 | while (l--) 552 | { 553 | float f = fbuf[l]; 554 | if (f < -1.0) f = -1.0; 555 | if (f > 1.0) f = 1.0; 556 | ((Sint16*)stream)[l] = (Sint16)(f * 32767); 557 | } 558 | delete[] fbuf; 559 | } 560 | else memset(stream, 0, len); 561 | } 562 | 563 | bool ExportWAV(const char* filename) 564 | { 565 | FILE* foutput=fopen(filename, "wb"); 566 | if(!foutput) 567 | return false; 568 | // write wav header 569 | unsigned int dword=0; 570 | unsigned short word=0; 571 | fwrite("RIFF", 4, 1, foutput); // "RIFF" 572 | dword=0; 573 | fwrite(&dword, 1, 4, foutput); // remaining file size 574 | fwrite("WAVE", 4, 1, foutput); // "WAVE" 575 | 576 | fwrite("fmt ", 4, 1, foutput); // "fmt " 577 | dword=16; 578 | fwrite(&dword, 1, 4, foutput); // chunk size 579 | word=1; 580 | fwrite(&word, 1, 2, foutput); // compression code 581 | word=1; 582 | fwrite(&word, 1, 2, foutput); // channels 583 | dword=wav_freq; 584 | fwrite(&dword, 1, 4, foutput); // sample rate 585 | dword=wav_freq*wav_bits/8; 586 | fwrite(&dword, 1, 4, foutput); // bytes/sec 587 | word=wav_bits/8; 588 | fwrite(&word, 1, 2, foutput); // block align 589 | word=wav_bits; 590 | fwrite(&word, 1, 2, foutput); // bits per sample 591 | 592 | fwrite("data", 4, 1, foutput); // "data" 593 | dword=0; 594 | int foutstream_datasize=ftell(foutput); 595 | fwrite(&dword, 1, 4, foutput); // chunk size 596 | 597 | // write sample data 598 | mute_stream=true; 599 | file_sampleswritten=0; 600 | filesample=0.0f; 601 | fileacc=0; 602 | PlaySample(); 603 | while(playing_sample) 604 | SynthSample(256, NULL, foutput); 605 | mute_stream=false; 606 | 607 | // seek back to header and write size info 608 | fseek(foutput, 4, SEEK_SET); 609 | dword=0; 610 | dword=foutstream_datasize-4+file_sampleswritten*wav_bits/8; 611 | fwrite(&dword, 1, 4, foutput); // remaining file size 612 | fseek(foutput, foutstream_datasize, SEEK_SET); 613 | dword=file_sampleswritten*wav_bits/8; 614 | fwrite(&dword, 1, 4, foutput); // chunk size (data) 615 | fclose(foutput); 616 | 617 | return true; 618 | } 619 | 620 | #include "tools.h" 621 | 622 | bool firstframe=true; 623 | int refresh_counter=0; 624 | bool dragOnLeftClick = false; 625 | 626 | bool Slider(int x, int y, float& value, bool bipolar, const char* text) 627 | { 628 | bool result = false; 629 | if(MouseInBox(x, y, 100, 10)) 630 | { 631 | if(mouse_rightclick) 632 | { 633 | value=0.0f; 634 | result = true; 635 | } 636 | if(mouse_leftclick) 637 | { 638 | if(dragOnLeftClick) 639 | vselected=&value; 640 | else 641 | { 642 | if(bipolar) 643 | value = (mouse_x - x)/50.0f - 1.0f; 644 | else 645 | value = (mouse_x - x)/100.0f; 646 | result = true; 647 | } 648 | } 649 | } 650 | float mv=(float)(mouse_x-mouse_px); 651 | if(vselected!=&value) 652 | mv=0.0f; 653 | if(bipolar) 654 | { 655 | value+=mv*0.005f; 656 | if(value<-1.0f) value=-1.0f; 657 | if(value>1.0f) value=1.0f; 658 | } 659 | else 660 | { 661 | value+=mv*0.0025f; 662 | if(value<0.0f) value=0.0f; 663 | if(value>1.0f) value=1.0f; 664 | } 665 | DrawBar(x-1, y, 102, 10, 0x000000); 666 | int ival=(int)(value*99); 667 | if(bipolar) 668 | ival=(int)(value*49.5f+49.5f); 669 | DrawBar(x, y+1, ival, 8, 0xF0C090); 670 | DrawBar(x+ival, y+1, 100-ival, 8, 0x807060); 671 | DrawBar(x+ival, y+1, 1, 8, 0xFFFFFF); 672 | if(bipolar) 673 | { 674 | DrawBar(x+50, y-1, 1, 3, 0x000000); 675 | DrawBar(x+50, y+8, 1, 3, 0x000000); 676 | } 677 | DWORD tcol=0x000000; 678 | if(wave_type!=0 && (&value==&p_duty || &value==&p_duty_ramp)) 679 | tcol=0x808080; 680 | DrawText(font, x-4-strlen(text)*8, y+1, tcol, text); 681 | return result; 682 | } 683 | 684 | bool Button(int x, int y, bool highlight, const char* text, int id) 685 | { 686 | DWORD color1=0x000000; 687 | DWORD color2=0xA09088; 688 | DWORD color3=0x000000; 689 | bool hover=MouseInBox(x, y, 100, 17); 690 | if(hover && mouse_leftclick) 691 | vcurbutton=id; 692 | bool current=(vcurbutton==id); 693 | if(highlight) 694 | { 695 | color1=0x000000; 696 | color2=0x988070; 697 | color3=0xFFF0E0; 698 | } 699 | if(current && hover) 700 | { 701 | color1=0xA09088; 702 | color2=0xFFF0E0; 703 | color3=0xA09088; 704 | } 705 | DrawBar(x-1, y-1, 102, 19, color1); 706 | DrawBar(x, y, 100, 17, color2); 707 | DrawText(font, x+5, y+5, color3, text); 708 | if(current && hover && !mouse_left) 709 | return true; 710 | return false; 711 | } 712 | 713 | bool ButtonWH(int x, int y, int w, int h, bool highlight, const char* text, int id) 714 | { 715 | DWORD color1=0x000000; 716 | DWORD color2=0xA09088; 717 | DWORD color3=0x000000; 718 | bool hover=MouseInBox(x, y, w, h); 719 | if(hover && mouse_leftclick) 720 | vcurbutton=id; 721 | bool current=(vcurbutton==id); 722 | if(highlight) 723 | { 724 | color1=0x000000; 725 | color2=0x988070; 726 | color3=0xFFF0E0; 727 | } 728 | if(current && hover) 729 | { 730 | color1=0xA09088; 731 | color2=0xFFF0E0; 732 | color3=0xA09088; 733 | } 734 | DrawBar(x-1, y-1, w + 2, h + 2, color1); 735 | DrawBar(x, y, w, h, color2); 736 | DrawText(font, x+5, y+5, color3, text); 737 | if(current && hover && !mouse_left) 738 | return true; 739 | return false; 740 | } 741 | 742 | int drawcount=0; 743 | 744 | void DrawScreen() 745 | { 746 | bool redraw=true; 747 | if(!firstframe && mouse_x-mouse_px==0 && mouse_y-mouse_py==0 && !mouse_left && !mouse_right) 748 | redraw=false; 749 | if(!mouse_left) 750 | { 751 | if(vselected!=NULL || vcurbutton>-1) 752 | { 753 | redraw=true; 754 | refresh_counter=2; 755 | } 756 | vselected=NULL; 757 | } 758 | if(refresh_counter>0) 759 | { 760 | refresh_counter--; 761 | redraw=true; 762 | } 763 | 764 | if(playing_sample) 765 | redraw=true; 766 | 767 | if(drawcount++>20) 768 | { 769 | redraw=true; 770 | drawcount=0; 771 | } 772 | 773 | if(!redraw) 774 | return; 775 | 776 | firstframe=false; 777 | 778 | ddkLock(); 779 | 780 | ClearScreen(0xC0B090); 781 | 782 | DrawText(font, 10, 10, 0x504030, "GENERATOR"); 783 | for(int i=0;i<7;i++) 784 | { 785 | if(Button(5, 35+i*30, false, categories[i].name, 300+i)) 786 | { 787 | switch(i) 788 | { 789 | case 0: // pickup/coin 790 | ResetParams(); 791 | p_base_freq=0.4f+frnd(0.5f); 792 | p_env_attack=0.0f; 793 | p_env_sustain=frnd(0.1f); 794 | p_env_decay=0.1f+frnd(0.4f); 795 | p_env_punch=0.3f+frnd(0.3f); 796 | if(rnd(1)) 797 | { 798 | p_arp_speed=0.5f+frnd(0.2f); 799 | p_arp_mod=0.2f+frnd(0.4f); 800 | } 801 | break; 802 | case 1: // laser/shoot 803 | ResetParams(); 804 | wave_type=rnd(2); 805 | if(wave_type==2 && rnd(1)) 806 | wave_type=rnd(1); 807 | p_base_freq=0.5f+frnd(0.5f); 808 | p_freq_limit=p_base_freq-0.2f-frnd(0.6f); 809 | if(p_freq_limit<0.2f) p_freq_limit=0.2f; 810 | p_freq_ramp=-0.15f-frnd(0.2f); 811 | if(rnd(2)==0) 812 | { 813 | p_base_freq=0.3f+frnd(0.6f); 814 | p_freq_limit=frnd(0.1f); 815 | p_freq_ramp=-0.35f-frnd(0.3f); 816 | } 817 | if(rnd(1)) 818 | { 819 | p_duty=frnd(0.5f); 820 | p_duty_ramp=frnd(0.2f); 821 | } 822 | else 823 | { 824 | p_duty=0.4f+frnd(0.5f); 825 | p_duty_ramp=-frnd(0.7f); 826 | } 827 | p_env_attack=0.0f; 828 | p_env_sustain=0.1f+frnd(0.2f); 829 | p_env_decay=frnd(0.4f); 830 | if(rnd(1)) 831 | p_env_punch=frnd(0.3f); 832 | if(rnd(2)==0) 833 | { 834 | p_pha_offset=frnd(0.2f); 835 | p_pha_ramp=-frnd(0.2f); 836 | } 837 | if(rnd(1)) 838 | p_hpf_freq=frnd(0.3f); 839 | break; 840 | case 2: // explosion 841 | ResetParams(); 842 | wave_type=3; 843 | if(rnd(1)) 844 | { 845 | p_base_freq=0.1f+frnd(0.4f); 846 | p_freq_ramp=-0.1f+frnd(0.4f); 847 | } 848 | else 849 | { 850 | p_base_freq=0.2f+frnd(0.7f); 851 | p_freq_ramp=-0.2f-frnd(0.2f); 852 | } 853 | p_base_freq*=p_base_freq; 854 | if(rnd(4)==0) 855 | p_freq_ramp=0.0f; 856 | if(rnd(2)==0) 857 | p_repeat_speed=0.3f+frnd(0.5f); 858 | p_env_attack=0.0f; 859 | p_env_sustain=0.1f+frnd(0.3f); 860 | p_env_decay=frnd(0.5f); 861 | if(rnd(1)==0) 862 | { 863 | p_pha_offset=-0.3f+frnd(0.9f); 864 | p_pha_ramp=-frnd(0.3f); 865 | } 866 | p_env_punch=0.2f+frnd(0.6f); 867 | if(rnd(1)) 868 | { 869 | p_vib_strength=frnd(0.7f); 870 | p_vib_speed=frnd(0.6f); 871 | } 872 | if(rnd(2)==0) 873 | { 874 | p_arp_speed=0.6f+frnd(0.3f); 875 | p_arp_mod=0.8f-frnd(1.6f); 876 | } 877 | break; 878 | case 3: // powerup 879 | ResetParams(); 880 | if(rnd(1)) 881 | wave_type=1; 882 | else 883 | p_duty=frnd(0.6f); 884 | if(rnd(1)) 885 | { 886 | p_base_freq=0.2f+frnd(0.3f); 887 | p_freq_ramp=0.1f+frnd(0.4f); 888 | p_repeat_speed=0.4f+frnd(0.4f); 889 | } 890 | else 891 | { 892 | p_base_freq=0.2f+frnd(0.3f); 893 | p_freq_ramp=0.05f+frnd(0.2f); 894 | if(rnd(1)) 895 | { 896 | p_vib_strength=frnd(0.7f); 897 | p_vib_speed=frnd(0.6f); 898 | } 899 | } 900 | p_env_attack=0.0f; 901 | p_env_sustain=frnd(0.4f); 902 | p_env_decay=0.1f+frnd(0.4f); 903 | break; 904 | case 4: // hit/hurt 905 | ResetParams(); 906 | wave_type=rnd(2); 907 | if(wave_type==2) 908 | wave_type=3; 909 | if(wave_type==0) 910 | p_duty=frnd(0.6f); 911 | p_base_freq=0.2f+frnd(0.6f); 912 | p_freq_ramp=-0.3f-frnd(0.4f); 913 | p_env_attack=0.0f; 914 | p_env_sustain=frnd(0.1f); 915 | p_env_decay=0.1f+frnd(0.2f); 916 | if(rnd(1)) 917 | p_hpf_freq=frnd(0.3f); 918 | break; 919 | case 5: // jump 920 | ResetParams(); 921 | wave_type=0; 922 | p_duty=frnd(0.6f); 923 | p_base_freq=0.3f+frnd(0.3f); 924 | p_freq_ramp=0.1f+frnd(0.2f); 925 | p_env_attack=0.0f; 926 | p_env_sustain=0.1f+frnd(0.3f); 927 | p_env_decay=0.1f+frnd(0.2f); 928 | if(rnd(1)) 929 | p_hpf_freq=frnd(0.3f); 930 | if(rnd(1)) 931 | p_lpf_freq=1.0f-frnd(0.6f); 932 | break; 933 | case 6: // blip/select 934 | ResetParams(); 935 | wave_type=rnd(1); 936 | if(wave_type==0) 937 | p_duty=frnd(0.6f); 938 | p_base_freq=0.2f+frnd(0.4f); 939 | p_env_attack=0.0f; 940 | p_env_sustain=0.1f+frnd(0.1f); 941 | p_env_decay=frnd(0.2f); 942 | p_hpf_freq=0.1f; 943 | break; 944 | default: 945 | break; 946 | } 947 | 948 | PlaySample(); 949 | } 950 | } 951 | DrawBar(110, 0, 2, 480, 0x000000); 952 | DrawText(font, 120, 10, 0x504030, "MANUAL SETTINGS"); 953 | DrawSprite(ld48, 8, 440, 0, 0xB0A080); 954 | 955 | 956 | bool do_play=false; 957 | 958 | if(Button(130, 30, wave_type==0, "SQUAREWAVE", 10)) 959 | { 960 | wave_type=0; 961 | do_play=true; 962 | } 963 | if(Button(250, 30, wave_type==1, "SAWTOOTH", 11)) 964 | { 965 | wave_type=1; 966 | do_play=true; 967 | } 968 | if(Button(370, 30, wave_type==2, "SINEWAVE", 12)) 969 | { 970 | wave_type=2; 971 | do_play=true; 972 | } 973 | if(Button(490, 30, wave_type==3, "NOISE", 13)) 974 | { 975 | wave_type=3; 976 | do_play=true; 977 | } 978 | if(dragOnLeftClick) 979 | { 980 | if(ButtonWH(490, 140, 17, 17, dragOnLeftClick, "X", 101)) 981 | dragOnLeftClick = !dragOnLeftClick; 982 | } 983 | else 984 | { 985 | if(ButtonWH(490, 140, 17, 17, dragOnLeftClick, "", 101)) 986 | dragOnLeftClick = !dragOnLeftClick; 987 | } 988 | DrawText(font, 515, 145, 0x000000, "DRAG BARS"); 989 | 990 | DrawBar(5-1-1, 412-1-1, 102+2, 19+2, 0x000000); 991 | if(Button(5, 412, false, "RANDOMIZE", 40)) 992 | { 993 | p_base_freq=pow(frnd(2.0f)-1.0f, 2.0f); 994 | if(rnd(1)) 995 | p_base_freq=pow(frnd(2.0f)-1.0f, 3.0f)+0.5f; 996 | p_freq_limit=0.0f; 997 | p_freq_ramp=pow(frnd(2.0f)-1.0f, 5.0f); 998 | if(p_base_freq>0.7f && p_freq_ramp>0.2f) 999 | p_freq_ramp=-p_freq_ramp; 1000 | if(p_base_freq<0.2f && p_freq_ramp<-0.05f) 1001 | p_freq_ramp=-p_freq_ramp; 1002 | p_freq_dramp=pow(frnd(2.0f)-1.0f, 3.0f); 1003 | p_duty=frnd(2.0f)-1.0f; 1004 | p_duty_ramp=pow(frnd(2.0f)-1.0f, 3.0f); 1005 | p_vib_strength=pow(frnd(2.0f)-1.0f, 3.0f); 1006 | p_vib_speed=frnd(2.0f)-1.0f; 1007 | p_vib_delay=frnd(2.0f)-1.0f; 1008 | p_env_attack=pow(frnd(2.0f)-1.0f, 3.0f); 1009 | p_env_sustain=pow(frnd(2.0f)-1.0f, 2.0f); 1010 | p_env_decay=frnd(2.0f)-1.0f; 1011 | p_env_punch=pow(frnd(0.8f), 2.0f); 1012 | if(p_env_attack+p_env_sustain+p_env_decay<0.2f) 1013 | { 1014 | p_env_sustain+=0.2f+frnd(0.3f); 1015 | p_env_decay+=0.2f+frnd(0.3f); 1016 | } 1017 | p_lpf_resonance=frnd(2.0f)-1.0f; 1018 | p_lpf_freq=1.0f-pow(frnd(1.0f), 3.0f); 1019 | p_lpf_ramp=pow(frnd(2.0f)-1.0f, 3.0f); 1020 | if(p_lpf_freq<0.1f && p_lpf_ramp<-0.05f) 1021 | p_lpf_ramp=-p_lpf_ramp; 1022 | p_hpf_freq=pow(frnd(1.0f), 5.0f); 1023 | p_hpf_ramp=pow(frnd(2.0f)-1.0f, 5.0f); 1024 | p_pha_offset=pow(frnd(2.0f)-1.0f, 3.0f); 1025 | p_pha_ramp=pow(frnd(2.0f)-1.0f, 3.0f); 1026 | p_repeat_speed=frnd(2.0f)-1.0f; 1027 | p_arp_speed=frnd(2.0f)-1.0f; 1028 | p_arp_mod=frnd(2.0f)-1.0f; 1029 | do_play=true; 1030 | } 1031 | 1032 | if(ButtonWH(5, 352, 75, 17, false, "UNDO (Z)", 102)) 1033 | { 1034 | Undo(); 1035 | } 1036 | if(Button(5, 382, false, "MUTATE", 30)) 1037 | { 1038 | if(rnd(1)) p_base_freq+=frnd(0.1f)-0.05f; 1039 | // if(rnd(1)) p_freq_limit+=frnd(0.1f)-0.05f; 1040 | if(rnd(1)) p_freq_ramp+=frnd(0.1f)-0.05f; 1041 | if(rnd(1)) p_freq_dramp+=frnd(0.1f)-0.05f; 1042 | if(rnd(1)) p_duty+=frnd(0.1f)-0.05f; 1043 | if(rnd(1)) p_duty_ramp+=frnd(0.1f)-0.05f; 1044 | if(rnd(1)) p_vib_strength+=frnd(0.1f)-0.05f; 1045 | if(rnd(1)) p_vib_speed+=frnd(0.1f)-0.05f; 1046 | if(rnd(1)) p_vib_delay+=frnd(0.1f)-0.05f; 1047 | if(rnd(1)) p_env_attack+=frnd(0.1f)-0.05f; 1048 | if(rnd(1)) p_env_sustain+=frnd(0.1f)-0.05f; 1049 | if(rnd(1)) p_env_decay+=frnd(0.1f)-0.05f; 1050 | if(rnd(1)) p_env_punch+=frnd(0.1f)-0.05f; 1051 | if(rnd(1)) p_lpf_resonance+=frnd(0.1f)-0.05f; 1052 | if(rnd(1)) p_lpf_freq+=frnd(0.1f)-0.05f; 1053 | if(rnd(1)) p_lpf_ramp+=frnd(0.1f)-0.05f; 1054 | if(rnd(1)) p_hpf_freq+=frnd(0.1f)-0.05f; 1055 | if(rnd(1)) p_hpf_ramp+=frnd(0.1f)-0.05f; 1056 | if(rnd(1)) p_pha_offset+=frnd(0.1f)-0.05f; 1057 | if(rnd(1)) p_pha_ramp+=frnd(0.1f)-0.05f; 1058 | if(rnd(1)) p_repeat_speed+=frnd(0.1f)-0.05f; 1059 | if(rnd(1)) p_arp_speed+=frnd(0.1f)-0.05f; 1060 | if(rnd(1)) p_arp_mod+=frnd(0.1f)-0.05f; 1061 | do_play=true; 1062 | } 1063 | 1064 | DrawText(font, 515, 170, 0x000000, "VOLUME"); 1065 | DrawBar(490-1-1+60, 180-1+5, 70, 2, 0x000000); 1066 | DrawBar(490-1-1+60+68, 180-1+5, 2, 205, 0x000000); 1067 | DrawBar(490-1-1+60, 180-1, 42+2, 10+2, 0xFF0000); 1068 | if(Slider(490, 180, sound_vol, false, " ")) 1069 | PlaySample(); 1070 | if(Button(490, 200, false, "PLAY SOUND", 20)) 1071 | PlaySample(); 1072 | 1073 | if(Button(490, 290, false, "LOAD SOUND", 14)) 1074 | { 1075 | char filename[256]; 1076 | if(FileSelectorLoad(filename, 1)) 1077 | { 1078 | ResetParams(); 1079 | LoadSettings(filename); 1080 | PlaySample(); 1081 | } 1082 | } 1083 | if(Button(490, 320, false, "SAVE SOUND", 15)) 1084 | { 1085 | char filename[256]; 1086 | if(FileSelectorSave(filename, 1)) 1087 | SaveSettings(filename); 1088 | } 1089 | 1090 | DrawBar(490-1-1+60, 380-1+9, 70, 2, 0x000000); 1091 | DrawBar(490-1-2, 380-1-2, 102+4, 19+4, 0x000000); 1092 | if(Button(490, 380, false, "EXPORT .WAV", 16)) 1093 | { 1094 | std::string filename = new_file(".wav"); 1095 | //char filename[256]; 1096 | //if(FileSelectorSave(filename, 0)) 1097 | if(filename.size() > 0) 1098 | ExportWAV(filename.c_str()); 1099 | } 1100 | char str[10]; 1101 | sprintf(str, "%i HZ", wav_freq); 1102 | if(Button(490, 410, false, str, 18)) 1103 | { 1104 | if(wav_freq==44100) 1105 | wav_freq=22050; 1106 | else 1107 | wav_freq=44100; 1108 | } 1109 | sprintf(str, "%i-BIT", wav_bits); 1110 | if(Button(490, 440, false, str, 19)) 1111 | { 1112 | if(wav_bits==16) 1113 | wav_bits=8; 1114 | else 1115 | wav_bits=16; 1116 | } 1117 | 1118 | int ypos=4; 1119 | 1120 | int xpos=350; 1121 | 1122 | DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000); 1123 | 1124 | float oldValue = 0; 1125 | 1126 | oldValue = p_env_attack; 1127 | if(Slider(xpos, (ypos++)*18, p_env_attack, false, "ATTACK TIME")) 1128 | { 1129 | do_play = true; 1130 | SetUndo(&p_env_attack, oldValue); 1131 | } 1132 | oldValue = p_env_sustain; 1133 | if(Slider(xpos, (ypos++)*18, p_env_sustain, false, "SUSTAIN TIME")) 1134 | { 1135 | do_play = true; 1136 | SetUndo(&p_env_sustain, oldValue); 1137 | } 1138 | oldValue = p_env_punch; 1139 | if(Slider(xpos, (ypos++)*18, p_env_punch, false, "SUSTAIN PUNCH")) 1140 | { 1141 | do_play = true; 1142 | SetUndo(&p_env_punch, oldValue); 1143 | } 1144 | oldValue = p_env_decay; 1145 | if(Slider(xpos, (ypos++)*18, p_env_decay, false, "DECAY TIME")) 1146 | { 1147 | do_play = true; 1148 | SetUndo(&p_env_decay, oldValue); 1149 | } 1150 | 1151 | DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000); 1152 | 1153 | oldValue = p_base_freq; 1154 | if(Slider(xpos, (ypos++)*18, p_base_freq, false, "START FREQUENCY")) 1155 | { 1156 | do_play = true; 1157 | SetUndo(&p_base_freq, oldValue); 1158 | } 1159 | oldValue = p_freq_limit; 1160 | if(Slider(xpos, (ypos++)*18, p_freq_limit, false, "MIN FREQUENCY")) 1161 | { 1162 | do_play = true; 1163 | SetUndo(&p_freq_limit, oldValue); 1164 | } 1165 | oldValue = p_freq_ramp; 1166 | if(Slider(xpos, (ypos++)*18, p_freq_ramp, true, "SLIDE")) 1167 | { 1168 | do_play = true; 1169 | SetUndo(&p_freq_ramp, oldValue); 1170 | } 1171 | oldValue = p_freq_dramp; 1172 | if(Slider(xpos, (ypos++)*18, p_freq_dramp, true, "DELTA SLIDE")) 1173 | { 1174 | do_play = true; 1175 | SetUndo(&p_freq_dramp, oldValue); 1176 | } 1177 | 1178 | oldValue = p_vib_strength; 1179 | if(Slider(xpos, (ypos++)*18, p_vib_strength, false, "VIBRATO DEPTH")) 1180 | { 1181 | do_play = true; 1182 | SetUndo(&p_vib_strength, oldValue); 1183 | } 1184 | oldValue = p_vib_speed; 1185 | if(Slider(xpos, (ypos++)*18, p_vib_speed, false, "VIBRATO SPEED")) 1186 | { 1187 | do_play = true; 1188 | SetUndo(&p_vib_speed, oldValue); 1189 | } 1190 | 1191 | DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000); 1192 | 1193 | oldValue = p_arp_mod; 1194 | if(Slider(xpos, (ypos++)*18, p_arp_mod, true, "CHANGE AMOUNT")) 1195 | { 1196 | do_play = true; 1197 | SetUndo(&p_arp_mod, oldValue); 1198 | } 1199 | oldValue = p_arp_speed; 1200 | if(Slider(xpos, (ypos++)*18, p_arp_speed, false, "CHANGE SPEED")) 1201 | { 1202 | do_play = true; 1203 | SetUndo(&p_arp_speed, oldValue); 1204 | } 1205 | 1206 | DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000); 1207 | 1208 | oldValue = p_duty; 1209 | if(Slider(xpos, (ypos++)*18, p_duty, false, "SQUARE DUTY")) 1210 | { 1211 | do_play = true; 1212 | SetUndo(&p_duty, oldValue); 1213 | } 1214 | oldValue = p_duty_ramp; 1215 | if(Slider(xpos, (ypos++)*18, p_duty_ramp, true, "DUTY SWEEP")) 1216 | { 1217 | do_play = true; 1218 | SetUndo(&p_duty_ramp, oldValue); 1219 | } 1220 | 1221 | DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000); 1222 | 1223 | oldValue = p_repeat_speed; 1224 | if(Slider(xpos, (ypos++)*18, p_repeat_speed, false, "REPEAT SPEED")) 1225 | { 1226 | do_play = true; 1227 | SetUndo(&p_repeat_speed, oldValue); 1228 | } 1229 | 1230 | DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000); 1231 | 1232 | oldValue = p_pha_offset; 1233 | if(Slider(xpos, (ypos++)*18, p_pha_offset, true, "PHASER OFFSET")) 1234 | { 1235 | do_play = true; 1236 | SetUndo(&p_pha_offset, oldValue); 1237 | } 1238 | oldValue = p_pha_ramp; 1239 | if(Slider(xpos, (ypos++)*18, p_pha_ramp, true, "PHASER SWEEP")) 1240 | { 1241 | do_play = true; 1242 | SetUndo(&p_pha_ramp, oldValue); 1243 | } 1244 | 1245 | DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000); 1246 | 1247 | oldValue = p_lpf_freq; 1248 | if(Slider(xpos, (ypos++)*18, p_lpf_freq, false, "LP FILTER CUTOFF")) 1249 | { 1250 | do_play = true; 1251 | SetUndo(&p_lpf_freq, oldValue); 1252 | } 1253 | oldValue = p_lpf_ramp; 1254 | if(Slider(xpos, (ypos++)*18, p_lpf_ramp, true, "LP FILTER CUTOFF SWEEP")) 1255 | { 1256 | do_play = true; 1257 | SetUndo(&p_lpf_ramp, oldValue); 1258 | } 1259 | oldValue = p_lpf_resonance; 1260 | if(Slider(xpos, (ypos++)*18, p_lpf_resonance, false, "LP FILTER RESONANCE")) 1261 | { 1262 | do_play = true; 1263 | SetUndo(&p_lpf_resonance, oldValue); 1264 | } 1265 | oldValue = p_hpf_freq; 1266 | if(Slider(xpos, (ypos++)*18, p_hpf_freq, false, "HP FILTER CUTOFF")) 1267 | { 1268 | do_play = true; 1269 | SetUndo(&p_hpf_freq, oldValue); 1270 | } 1271 | oldValue = p_hpf_ramp; 1272 | if(Slider(xpos, (ypos++)*18, p_hpf_ramp, true, "HP FILTER CUTOFF SWEEP")) 1273 | { 1274 | do_play = true; 1275 | SetUndo(&p_hpf_ramp, oldValue); 1276 | } 1277 | 1278 | DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000); 1279 | 1280 | DrawBar(xpos-190, 4*18-5, 1, (ypos-4)*18, 0x0000000); 1281 | DrawBar(xpos-190+299, 4*18-5, 1, (ypos-4)*18, 0x0000000); 1282 | 1283 | if(do_play) 1284 | PlaySample(); 1285 | 1286 | ddkUnlock(); 1287 | 1288 | if(!mouse_left) 1289 | vcurbutton=-1; 1290 | } 1291 | 1292 | bool keydown=false; 1293 | 1294 | bool ddkCalcFrame() 1295 | { 1296 | input->Update(); // (for keyboard input) 1297 | 1298 | if(input->KeyPressed(DIK_SPACE) || input->KeyPressed(DIK_RETURN)) // (keyboard input only for convenience, ok to remove) 1299 | { 1300 | if(!keydown) 1301 | { 1302 | PlaySample(); 1303 | keydown=true; 1304 | } 1305 | } 1306 | else if(input->KeyPressed(DIK_Z)) 1307 | { 1308 | Undo(); 1309 | keydown=true; 1310 | } 1311 | else 1312 | keydown=false; 1313 | 1314 | DrawScreen(); 1315 | 1316 | SDL_Delay(5); 1317 | return true; 1318 | } 1319 | 1320 | void ddkInit() 1321 | { 1322 | srand(time(NULL)); 1323 | 1324 | ddkSetMode(640,480, 32, 60, DDK_WINDOW, "sfxr"); // requests window size etc from ddrawkit 1325 | 1326 | if (LoadTGA(font, "/usr/local/share/sfxr/images/font.tga")) { 1327 | /* Try again in cwd */ 1328 | if (LoadTGA(font, "images/font.tga")) { 1329 | fprintf(stderr, 1330 | "Error could not open /usr/local/share/sfxr/images/font.tga" 1331 | " nor images/font.tga\n"); 1332 | exit(1); 1333 | } 1334 | } 1335 | 1336 | if (LoadTGA(ld48, "/usr/local/share/sfxr/images/ld48.tga")) { 1337 | /* Try again in cwd */ 1338 | if (LoadTGA(ld48, "images/ld48.tga")) { 1339 | fprintf(stderr, 1340 | "Error could not open /usr/local/share/sfxr/images/ld48.tga" 1341 | " nor images/ld48.tga\n"); 1342 | exit(1); 1343 | } 1344 | } 1345 | 1346 | ld48.width=ld48.pitch; 1347 | 1348 | input=new DPInput; 1349 | 1350 | strcpy(categories[0].name, "PICKUP/COIN"); 1351 | strcpy(categories[1].name, "LASER/SHOOT"); 1352 | strcpy(categories[2].name, "EXPLOSION"); 1353 | strcpy(categories[3].name, "POWERUP"); 1354 | strcpy(categories[4].name, "HIT/HURT"); 1355 | strcpy(categories[5].name, "JUMP"); 1356 | strcpy(categories[6].name, "BLIP/SELECT"); 1357 | 1358 | ResetParams(); 1359 | 1360 | SDL_AudioSpec des; 1361 | des.freq = 44100; 1362 | des.format = AUDIO_S16SYS; 1363 | des.channels = 1; 1364 | des.samples = 512; 1365 | des.callback = SDLAudioCallback; 1366 | des.userdata = NULL; 1367 | VERIFY(!SDL_OpenAudio(&des, NULL)); 1368 | SDL_PauseAudio(0); 1369 | } 1370 | 1371 | void ddkFree() 1372 | { 1373 | delete input; 1374 | free(ld48.data); 1375 | free(font.data); 1376 | } 1377 | 1378 | -------------------------------------------------------------------------------- /sfxr/source/sdlkit.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2007 mjau/GerryJJ 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #include "sdlkit.h" 24 | 25 | 26 | #include 27 | #include 28 | 29 | void error (const char *file, unsigned int line, const char *msg) 30 | { 31 | fprintf(stderr, "[!] %s:%u %s\n", file, line, msg); 32 | exit(1); 33 | } 34 | 35 | 36 | bool keys[SDLK_LAST]; 37 | 38 | bool DPInput::KeyPressed(SDLKey key) 39 | { 40 | bool r = keys[key]; 41 | keys[key] = false; 42 | return r; 43 | } 44 | 45 | Uint32 *ddkscreen32; 46 | Uint16 *ddkscreen16; 47 | int ddkpitch; 48 | int mouse_x, mouse_y, mouse_px, mouse_py; 49 | bool mouse_left = false, mouse_right = false, mouse_middle = false; 50 | bool mouse_leftclick = false, mouse_rightclick = false, mouse_middleclick = false; 51 | 52 | SDL_Surface *sdlscreen = NULL; 53 | 54 | void sdlupdate () 55 | { 56 | mouse_px = mouse_x; 57 | mouse_py = mouse_y; 58 | Uint8 buttons = SDL_GetMouseState(&mouse_x, &mouse_y); 59 | bool mouse_left_p = mouse_left; 60 | bool mouse_right_p = mouse_right; 61 | bool mouse_middle_p = mouse_middle; 62 | mouse_left = buttons & SDL_BUTTON(1); 63 | mouse_right = buttons & SDL_BUTTON(3); 64 | mouse_middle = buttons & SDL_BUTTON(2); 65 | mouse_leftclick = mouse_left && !mouse_left_p; 66 | mouse_rightclick = mouse_right && !mouse_right_p; 67 | mouse_middleclick = mouse_middle && !mouse_middle_p; 68 | } 69 | 70 | bool ddkLock () 71 | { 72 | if(SDL_MUSTLOCK(sdlscreen)) 73 | { 74 | if(SDL_LockSurface(sdlscreen) < 0) 75 | return false; 76 | } 77 | ddkpitch = sdlscreen->pitch / (sdlscreen->format->BitsPerPixel == 32 ? 4 : 2); 78 | ddkscreen16 = (Uint16*)(sdlscreen->pixels); 79 | ddkscreen32 = (Uint32*)(sdlscreen->pixels); 80 | return true; 81 | } 82 | 83 | void ddkUnlock () 84 | { 85 | if(SDL_MUSTLOCK(sdlscreen)) 86 | { 87 | SDL_UnlockSurface(sdlscreen); 88 | } 89 | } 90 | 91 | void ddkSetMode (int width, int height, int bpp, int refreshrate, int fullscreen, const char *title) 92 | { 93 | VERIFY(sdlscreen = SDL_SetVideoMode(width, height, bpp, fullscreen ? SDL_FULLSCREEN : 0)); 94 | SDL_WM_SetCaption(title, title); 95 | } 96 | 97 | #include 98 | #include 99 | 100 | 101 | bool Button(int x, int y, bool highlight, const char* text, int id); 102 | 103 | #include 104 | #include 105 | 106 | 107 | #include 108 | #include 109 | 110 | bool ioIsDir(const std::string& filename) 111 | { 112 | using namespace std; 113 | struct stat status; 114 | stat(filename.c_str(), &status); 115 | 116 | return (status.st_mode & S_IFDIR); 117 | } 118 | 119 | std::list ioList(const std::string& dirname, bool directories, bool files) 120 | { 121 | using namespace std; 122 | list dirList; 123 | list fileList; 124 | 125 | DIR* dir = opendir(dirname.c_str()); 126 | dirent* entry; 127 | 128 | while ((entry = readdir(dir)) != NULL) 129 | { 130 | #ifdef WIN32 131 | if(ioIsDir(dirname + "/" + entry->d_name)) 132 | #else 133 | if(entry->d_type == DT_DIR) 134 | #endif 135 | { 136 | if(directories) 137 | dirList.push_back(entry->d_name); 138 | } 139 | else if(files) 140 | fileList.push_back(entry->d_name); 141 | } 142 | 143 | closedir(dir); 144 | 145 | dirList.sort(); 146 | fileList.sort(); 147 | 148 | fileList.splice(fileList.begin(), dirList); 149 | 150 | 151 | return fileList; 152 | } 153 | 154 | extern DPInput *input; 155 | 156 | bool file_select_update() 157 | { 158 | input->Update(); // (for keyboard input) 159 | 160 | //keydown=false; 161 | 162 | return true; 163 | } 164 | 165 | std::string stoupper(const std::string& s) 166 | { 167 | std::string result = s; 168 | std::string::iterator i = result.begin(); 169 | std::string::iterator end = result.end(); 170 | 171 | while(i != end) 172 | { 173 | *i = std::toupper((unsigned char)*i); 174 | ++i; 175 | } 176 | return result; 177 | } 178 | 179 | 180 | bool ioExists(const std::string& filename) 181 | { 182 | return (access(filename.c_str(), 0) == 0); 183 | } 184 | 185 | bool ioNew(const std::string& filename, bool readable, bool writeable) 186 | { 187 | if(ioExists(filename)) 188 | return false; 189 | 190 | FILE* file = fopen(filename.c_str(), "wb"); 191 | if(file == NULL) 192 | return false; 193 | fclose(file); 194 | return true; 195 | } 196 | 197 | 198 | void ClearScreen(DWORD color); 199 | extern int vcurbutton; 200 | 201 | #include "tools.h" 202 | 203 | extern Spriteset font; 204 | 205 | std::string new_file(const std::string& forced_extension) 206 | { 207 | using namespace std; 208 | SDL_EnableUNICODE(1); 209 | SDL_EnableKeyRepeat(0, 0); 210 | 211 | string result; 212 | 213 | bool done = false; 214 | SDL_Event e; 215 | while (!done) 216 | { 217 | while(SDL_PollEvent(&e)) 218 | { 219 | switch (e.type) 220 | { 221 | case SDL_QUIT: 222 | exit(0); 223 | 224 | case SDL_KEYDOWN: 225 | if(e.key.keysym.sym == SDLK_ESCAPE) 226 | { 227 | return ""; 228 | } 229 | if(e.key.keysym.sym == SDLK_RETURN) 230 | { 231 | done = true; 232 | break; 233 | } 234 | 235 | { 236 | char c = e.key.keysym.unicode; 237 | if(0x21 <= c && c <= 0x7E) 238 | result += c; 239 | } 240 | 241 | default: break; 242 | } 243 | } 244 | sdlupdate(); 245 | 246 | ClearScreen(0xC0B090); 247 | 248 | DrawText(font, 90, 150, 0x000000, "TYPE NEW FILE NAME:"); 249 | DrawText(font, 100, 200, 0x000000, "%s", stoupper(result).c_str()); 250 | 251 | SDL_Delay(5); 252 | 253 | SDL_Flip(sdlscreen); 254 | } 255 | 256 | SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); 257 | SDL_EnableUNICODE(0); 258 | 259 | //if(result.size() == 0) 260 | // throw runtime_error("New file name is empty string."); 261 | 262 | if(result.size() < 6 || result.substr(result.size()-1 - 4, string::npos) != forced_extension) 263 | result += forced_extension; 264 | 265 | return result; 266 | } 267 | 268 | void DrawFileSelectScreen(std::list& files, char* buf, bool& gotFile, bool& done, bool showNewButton) 269 | { 270 | using namespace std; 271 | 272 | ddkLock(); 273 | 274 | ClearScreen(0xC0B090); 275 | 276 | 277 | int i = 0, j = 0; 278 | for(list::iterator e = files.begin(); e != files.end(); e++) 279 | { 280 | if(40 + 20*i > sdlscreen->h - 50) 281 | { 282 | j++; 283 | i = 0; 284 | } 285 | if(Button(30 + 150*j, 40 + 20*i, false, stoupper(*e).c_str(), 31 + i + j)) 286 | { 287 | gotFile = true; 288 | sprintf(buf, "%s", e->c_str()); 289 | done = true; 290 | } 291 | i++; 292 | } 293 | 294 | if(Button(10, 10, false, "CANCEL", 400)) 295 | { 296 | gotFile = false; 297 | done = true; 298 | } 299 | 300 | if(showNewButton && Button(120, 10, false, "NEW FILE", 401)) 301 | { 302 | string s = new_file(".sfxr"); 303 | if(s != "") 304 | { 305 | ioNew(s, true, true); 306 | files = ioList(".", false, true); 307 | 308 | for(list::iterator e = files.begin(); e != files.end();) 309 | { 310 | if(e->find(".sfxr") == string::npos) 311 | { 312 | e = files.erase(e); 313 | continue; 314 | } 315 | 316 | e++; 317 | } 318 | } 319 | } 320 | 321 | ddkUnlock(); 322 | 323 | if(!mouse_left) 324 | vcurbutton=-1; 325 | } 326 | 327 | 328 | bool select_file (char *buf, bool showNewButton) 329 | { 330 | // FIXME: Needs directory browsing 331 | 332 | bool gotFile = false; 333 | using namespace std; 334 | list files; 335 | files = ioList(".", false, true); 336 | 337 | for(list::iterator e = files.begin(); e != files.end();) 338 | { 339 | if(e->find(".sfxr") == string::npos) 340 | { 341 | e = files.erase(e); 342 | continue; 343 | } 344 | 345 | e++; 346 | } 347 | 348 | bool done = false; 349 | SDL_Event e; 350 | while (!done) 351 | { 352 | SDL_PollEvent(&e); 353 | switch (e.type) 354 | { 355 | case SDL_QUIT: 356 | exit(0); 357 | 358 | case SDL_KEYDOWN: 359 | keys[e.key.keysym.sym] = true; 360 | 361 | default: break; 362 | } 363 | sdlupdate(); 364 | 365 | DrawFileSelectScreen(files, buf, gotFile, done, showNewButton); 366 | 367 | SDL_Delay(5); 368 | 369 | SDL_Flip(sdlscreen); 370 | } 371 | return gotFile; 372 | } 373 | 374 | void sdlquit () 375 | { 376 | ddkFree(); 377 | SDL_Quit(); 378 | } 379 | 380 | void sdlinit () 381 | { 382 | SDL_Surface *icon; 383 | VERIFY(!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)); 384 | icon = SDL_LoadBMP("/usr/local/share/sfxr/images/sfxr.bmp"); 385 | if (!icon) 386 | icon = SDL_LoadBMP("images/sfxr.bmp"); 387 | if (icon) 388 | SDL_WM_SetIcon(icon, NULL); 389 | atexit(sdlquit); 390 | memset(keys, 0, sizeof(keys)); 391 | ddkInit(); 392 | } 393 | 394 | void loop (void) 395 | { 396 | SDL_Event e; 397 | while (true) 398 | { 399 | SDL_PollEvent(&e); 400 | switch (e.type) 401 | { 402 | case SDL_QUIT: 403 | exit(0); 404 | 405 | case SDL_KEYDOWN: 406 | keys[e.key.keysym.sym] = true; 407 | 408 | default: break; 409 | } 410 | sdlupdate(); 411 | if (!ddkCalcFrame()) 412 | return; 413 | SDL_Flip(sdlscreen); 414 | } 415 | } 416 | 417 | int main(int argc, char *argv[]) 418 | { 419 | sdlinit(); 420 | loop(); 421 | return 0; 422 | } 423 | 424 | -------------------------------------------------------------------------------- /sfxr/source/sdlkit.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2007 mjau/GerryJJ 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #ifndef SDLKIT_H 24 | #define SDLKIT_H 25 | 26 | #include "SDL.h" 27 | #include 28 | 29 | 30 | #define ERROR(x) error(__FILE__, __LINE__, #x) 31 | #define VERIFY(x) do { if (!(x)) ERROR(x); } while (0) 32 | 33 | typedef Uint32 DWORD; 34 | typedef Uint16 WORD; 35 | 36 | #define DIK_SPACE SDLK_SPACE 37 | #define DIK_RETURN SDLK_RETURN 38 | #define DIK_Z SDLK_z 39 | #define DDK_WINDOW 0 40 | 41 | 42 | extern Uint32 *ddkscreen32; 43 | extern Uint16 *ddkscreen16; 44 | extern int ddkpitch; 45 | 46 | 47 | extern int mouse_x, mouse_y, mouse_px, mouse_py; 48 | extern bool mouse_left, mouse_right, mouse_middle; 49 | extern bool mouse_leftclick, mouse_rightclick, mouse_middleclick; 50 | 51 | 52 | void error (const char *file, unsigned int line, const char *msg); 53 | 54 | void ddkInit(); // Will be called on startup 55 | bool ddkCalcFrame(); // Will be called every frame, return true to continue running or false to quit 56 | void ddkFree(); // Will be called on shutdown 57 | 58 | class DPInput { 59 | public: 60 | DPInput() {} 61 | ~DPInput() {} 62 | static void Update () {} 63 | 64 | static bool KeyPressed(SDLKey key); 65 | 66 | }; 67 | 68 | void sdlupdate (); 69 | 70 | bool ddkLock (); 71 | 72 | void ddkUnlock (); 73 | 74 | void ddkSetMode (int width, int height, int bpp, int refreshrate, int fullscreen, const char *title); 75 | 76 | 77 | //void selected_file (GtkWidget *button, GtkFileSelection *fs); 78 | 79 | bool select_file (char *buf, bool showNewButton); 80 | std::string new_file(const std::string& forced_extension); 81 | 82 | #define FileSelectorLoad(file,y) select_file(file, false) 83 | #define FileSelectorSave(file,y) select_file(file, true) 84 | 85 | void sdlquit (); 86 | 87 | void sdlinit (); 88 | 89 | void loop (); 90 | 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /sfxr/source/tools.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2007 Tomas Pettersson 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #include "sdlkit.h" 24 | #include "tools.h" 25 | 26 | int LoadTGA(Spriteset& tiles, const char *filename) 27 | { 28 | FILE *file; 29 | unsigned char byte, crap[16], id_length; 30 | int i, width, height, channels, x, y; 31 | file=fopen(filename, "rb"); 32 | if (!file) 33 | return -1; 34 | 35 | int n; 36 | (void)n; 37 | n = fread(&id_length, 1, 1, file); 38 | n = fread(crap, 1, 11, file); 39 | width=0; 40 | height=0; 41 | n = fread(&width, 1, 2, file); // width 42 | n = fread(&height, 1, 2, file); // height 43 | n = fread(&byte, 1, 1, file); // bits 44 | channels=byte/8; 45 | (void)channels; 46 | n = fread(&byte, 1, 1, file); // image descriptor byte (per-bit info) 47 | for(i=0;i=0;y--) 51 | for(x=0;x8) 96 | for(x1=0;x1=x && mouse_x=y && mouse_y 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _TOOLS_H__ 24 | #define _TOOLS_H__ 25 | 26 | typedef Uint32 DWORD; 27 | typedef Uint16 WORD; 28 | 29 | struct Spriteset 30 | { 31 | DWORD *data; 32 | int width; 33 | int height; 34 | int pitch; 35 | }; 36 | 37 | int LoadTGA(Spriteset& tiles, const char *filename); 38 | 39 | void ClearScreen(DWORD color); 40 | 41 | void DrawBar(int sx, int sy, int w, int h, DWORD color); 42 | 43 | void DrawBox(int sx, int sy, int w, int h, DWORD color); 44 | 45 | void DrawSprite(Spriteset& sprites, int sx, int sy, int i, DWORD color); 46 | 47 | void DrawText(Spriteset& font, int sx, int sy, DWORD color, const char *string, ...); 48 | 49 | bool MouseInBox(int x, int y, int w, int h); 50 | 51 | #endif 52 | 53 | --------------------------------------------------------------------------------