├── .gitattributes ├── .gitignore ├── README.md ├── bin ├── linux-64bit │ ├── Propulse │ ├── libSDL2-2.0.so.0 │ ├── libbass.so │ └── libsoxr.so.0 └── propulse-win32.zip ├── data ├── font │ ├── Commodore 64 8x8.pcx │ ├── Convertible 8x8.pcx │ ├── Giana 8x8.pcx │ ├── Impulse Tracker 8x8.pcx │ ├── MicroKnight 8x8.pcx │ ├── Miditri 10x12.pcx │ ├── Olympiad Austin 9x16.pcx │ ├── Propulse 12x12.pcx │ ├── Propulse 12x13.pcx │ ├── Propulse 16x16.pcx │ ├── Propulse 24x24.pcx │ ├── Propulse 4x6.pcx │ ├── Propulse 7x7.pcx │ ├── Propulse 8x8.pcx │ ├── Spy vs Spy 8x8.pcx │ ├── Topaz 8x16.pcx │ ├── Topaz 8x8.pcx │ ├── ToshibaLCD 8x16.pcx │ └── ToshibaLCD 8x8.pcx ├── gradient.pcx ├── help.txt ├── icon.bmp ├── layout │ ├── Editor-alt.layout │ └── Editor.layout ├── logo.pcx ├── midi │ ├── Akai APC Key 25.ini │ ├── Numark DJ2Go.ini │ └── font6x5.pcx ├── mouse.pcx ├── mouse2.pcx ├── palette.ini └── palette │ ├── Camouflage.ini │ ├── ProTracker.ini │ ├── Propulse.ini │ └── Strawberry Ice Cream.ini ├── docs ├── building.txt ├── images │ ├── ss1.png │ ├── ss2.png │ └── ss3.png ├── status.txt └── whatsnew.txt ├── libsoxr-copyright.txt ├── license.txt └── src ├── Propulse.ctpr ├── Propulse.lpi ├── configurationmanager.pas ├── cwe ├── cwe.core.pas ├── cwe.dialogs.pas ├── cwe.externalapi.pas ├── cwe.mainmenu.pas ├── cwe.mousecursor.pas └── widgets │ ├── cwe.widgets.numeric.pas │ ├── cwe.widgets.scrollers.pas │ ├── cwe.widgets.text.pas │ └── sampleview.pas ├── dialog ├── dialog.cleanup.pas ├── dialog.generatewaveform.pas ├── dialog.jumptotime.pas ├── dialog.moduleinfo.pas ├── dialog.newmodule.pas ├── dialog.renderaudio.pas └── dialog.valuequery.pas ├── floatsampleeffects.pas ├── include ├── bass │ ├── bass.h │ ├── bass.pas │ ├── makefile │ └── makefile.in ├── buildinfo.pas ├── filestreamex.pas ├── fileutils.pas ├── fpwavformat.pas ├── fpwavreader.pas ├── fpwavwriter.pas ├── graphics32-license.txt ├── graphics32.pas ├── graphics32_lowlevel.pas ├── hkafileutils.pas ├── midiio.pas ├── pcx.pas ├── sdl2 │ ├── LICENSE │ ├── README.md │ ├── jedi.inc │ ├── sdl.inc │ ├── sdl2.pas │ ├── sdl2_gfx.pas │ ├── sdl2_image.pas │ ├── sdl2_mixer.pas │ ├── sdl2_net.pas │ ├── sdl2_ttf.pas │ ├── sdlaudio.inc │ ├── sdlblendmode.inc │ ├── sdlclipboard.inc │ ├── sdlcpuinfo.inc │ ├── sdlerror.inc │ ├── sdlevents.inc │ ├── sdlfilesystem.inc │ ├── sdlgamecontroller.inc │ ├── sdlgesture.inc │ ├── sdlhaptic.inc │ ├── sdlhints.inc │ ├── sdljoystick.inc │ ├── sdlkeyboard.inc │ ├── sdlloadso.inc │ ├── sdllog.inc │ ├── sdlmessagebox.inc │ ├── sdlmouse.inc │ ├── sdlmutex.inc │ ├── sdlpixels.inc │ ├── sdlplatform.inc │ ├── sdlpower.inc │ ├── sdlrect.inc │ ├── sdlrenderer.inc │ ├── sdlrwops.inc │ ├── sdlscancode.inc │ ├── sdlshape.inc │ ├── sdlsurface.inc │ ├── sdlsystem.inc │ ├── sdlsyswm.inc │ ├── sdlthread.inc │ ├── sdltimer.inc │ ├── sdltouch.inc │ ├── sdltype.inc │ ├── sdlversion.inc │ └── sdlvideo.inc └── soxr.pas ├── layout.pas ├── mainwindow.pas ├── propulse.ico ├── propulse.inc ├── propulse.pas ├── propulse.res ├── protracker ├── protracker.editor.pas ├── protracker.filters.pas ├── protracker.format.it.pas ├── protracker.format.p61.pas ├── protracker.format.s3m.pas ├── protracker.format.xm.pas ├── protracker.import.pas ├── protracker.messaging.pas ├── protracker.midi.pas ├── protracker.paula.pas ├── protracker.player.pas ├── protracker.sample.pas └── protracker.util.pas ├── sampleeditor.pas ├── screen ├── fx.vectorlogo.pas ├── screen.config.pas ├── screen.editor.pas ├── screen.filereq.pas ├── screen.filereqsample.pas ├── screen.help.pas ├── screen.log.pas ├── screen.samples.pas └── screen.splash.pas ├── shortcutmanager.pas └── textmode.pas /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | 49 | # Custom 50 | backup 51 | lib 52 | Propulse 53 | debug\.txt 54 | *.lps 55 | *.bak 56 | *.dll 57 | *.exe 58 | *.rar 59 | *.dbg 60 | *.so 61 | *.s 62 | *.o 63 | *.ppu 64 | *.pdf 65 | *.zip 66 | *.tar\.gz 67 | *.mod 68 | *.sh 69 | *.0 70 | data/palette/Image1\.png 71 | src/include/lazsdl2/bin/ 72 | src/include/lazsdl2/tests/ 73 | src/include/lazsdl2/java_templates/ 74 | src/include/generics\.collections/ 75 | src/include/_generics\.collections/ 76 | Propulse\.app/ 77 | !bin/ 78 | !bin/* 79 | !bin/linux-64bit/ 80 | !bin/linux-64bit/* 81 | !bin/windows-32bit/ 82 | !bin/windows-32bit/* 83 | 84 | *.log 85 | 86 | data/commands\.txt 87 | 88 | src/include/bass/delphi/3dTest/ 89 | 90 | src/include/bass/delphi/ 91 | 92 | src/include/bass/bass\.chm 93 | 94 | src/include/bass/bass\.txt 95 | 96 | src/screen/fx\.plasma\.pas 97 | 98 | propulse-win32/ 99 | 100 | src/include/lazsdl2/bin/x86_64-win64/ 101 | 102 | *.log~ 103 | 104 | src/include/lazsdl2/bin/i386-win32/ 105 | 106 | src/include/lazsdl2/bin/i386-linux/ 107 | 108 | src/include/lazsdl2/bin/x86_64-linux/ 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Propulse Tracker 2 | 3 | A crossplatform tracker for making Amiga ProTracker compatible 4 | tracker modules using an Impulse/Schism Tracker style user interface. 5 | 6 | Should build and run on Windows, Linux and macOS. 7 | 8 | ![Editor screenshot](https://github.com/hukkax/Propulse/blob/trunk/docs/images/ss1.png) 9 | 10 | Features: 11 | 12 | - Super accurate playback engine based on work by 8bitbubsy (itself based on a disassembly of the original Amiga ProTracker); things like black_queen.mod and MPT test cases play correctly 13 | - Familiar Impulse/Schism Trackerish interface with familiar keyboard commands 14 | - User configurable keybindings, colors, fonts of any size, even screen layouts... 15 | - WAV export with optional looping and fade out 16 | - Integrated mouse-driven sample editor 17 | 18 | Supported formats: 19 | 20 | - MOD - Loads and saves Amiga ProTracker modules (including load support for 15-sample Ultimate SoundTracker mods, NoiseTracker, and PowerPacked files) 21 | - P61A - Imports The Player 6.1a crunched modules 22 | - IT and S3M - Imports Impulse Tracker and Scream Tracker 3 modules 23 | - Samples: raw, IFF 8SVX, WAV, MP3 & Ogg Vorbis (when using BASS) 24 | 25 | ![Sample Editor screenshot](https://github.com/hukkax/Propulse/blob/trunk/docs/images/ss2.png) 26 | 27 | ![Settings screen screenshot](https://github.com/hukkax/Propulse/blob/trunk/docs/images/ss3.png) 28 | -------------------------------------------------------------------------------- /bin/linux-64bit/Propulse: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/bin/linux-64bit/Propulse -------------------------------------------------------------------------------- /bin/linux-64bit/libSDL2-2.0.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/bin/linux-64bit/libSDL2-2.0.so.0 -------------------------------------------------------------------------------- /bin/linux-64bit/libbass.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/bin/linux-64bit/libbass.so -------------------------------------------------------------------------------- /bin/linux-64bit/libsoxr.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/bin/linux-64bit/libsoxr.so.0 -------------------------------------------------------------------------------- /bin/propulse-win32.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/bin/propulse-win32.zip -------------------------------------------------------------------------------- /data/font/Commodore 64 8x8.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Commodore 64 8x8.pcx -------------------------------------------------------------------------------- /data/font/Convertible 8x8.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Convertible 8x8.pcx -------------------------------------------------------------------------------- /data/font/Giana 8x8.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Giana 8x8.pcx -------------------------------------------------------------------------------- /data/font/Impulse Tracker 8x8.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Impulse Tracker 8x8.pcx -------------------------------------------------------------------------------- /data/font/MicroKnight 8x8.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/MicroKnight 8x8.pcx -------------------------------------------------------------------------------- /data/font/Miditri 10x12.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Miditri 10x12.pcx -------------------------------------------------------------------------------- /data/font/Olympiad Austin 9x16.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Olympiad Austin 9x16.pcx -------------------------------------------------------------------------------- /data/font/Propulse 12x12.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Propulse 12x12.pcx -------------------------------------------------------------------------------- /data/font/Propulse 12x13.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Propulse 12x13.pcx -------------------------------------------------------------------------------- /data/font/Propulse 16x16.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Propulse 16x16.pcx -------------------------------------------------------------------------------- /data/font/Propulse 24x24.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Propulse 24x24.pcx -------------------------------------------------------------------------------- /data/font/Propulse 4x6.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Propulse 4x6.pcx -------------------------------------------------------------------------------- /data/font/Propulse 7x7.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Propulse 7x7.pcx -------------------------------------------------------------------------------- /data/font/Propulse 8x8.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Propulse 8x8.pcx -------------------------------------------------------------------------------- /data/font/Spy vs Spy 8x8.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Spy vs Spy 8x8.pcx -------------------------------------------------------------------------------- /data/font/Topaz 8x16.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Topaz 8x16.pcx -------------------------------------------------------------------------------- /data/font/Topaz 8x8.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/Topaz 8x8.pcx -------------------------------------------------------------------------------- /data/font/ToshibaLCD 8x16.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/ToshibaLCD 8x16.pcx -------------------------------------------------------------------------------- /data/font/ToshibaLCD 8x8.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/font/ToshibaLCD 8x8.pcx -------------------------------------------------------------------------------- /data/gradient.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/gradient.pcx -------------------------------------------------------------------------------- /data/help.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/help.txt -------------------------------------------------------------------------------- /data/icon.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/icon.bmp -------------------------------------------------------------------------------- /data/layout/Editor-alt.layout: -------------------------------------------------------------------------------- 1 | [000] 2 | Type=Box 3 | ID=Song Title 4 | X1=10 5 | Y1=02 6 | X2=30 7 | Y2=03 8 | Border=sunken pixel 9 | Data=0B00 10 | 11 | [001] 12 | Type=Box 13 | ID=Song Filename 14 | X1=10 15 | Y1=04 16 | X2=30 17 | Y2=05 18 | Border=sunken pixel 19 | Data=0B00 20 | 21 | [002] 22 | Type=Box 23 | ID=Scope 24 | X1=48 25 | Y1=04 26 | X2=64 27 | Y2=07 28 | ColorText=03 29 | ColorBack=00 30 | Border=sunken pixel 31 | Data=0D 32 | 33 | [003] 34 | Type=Box 35 | ID=PatternView 36 | X1=01 37 | Y1=12 38 | X2=59 39 | Y2=44 40 | Border=fat sunken 41 | Data=0D0E0F0803090900030003 42 | 43 | [004] 44 | Type=Box 45 | ID=OrderList 46 | X1=61 47 | Y1=11 48 | X2=67 49 | Y2=44 50 | Border=fat sunken 51 | 52 | [005] 53 | Type=Text 54 | ID=App Title and Build Data 55 | Caption=PoroTracker 56 | X1=00 57 | Y1=00 58 | X2=80 59 | Y2=01 60 | TextAlign=1 61 | 62 | [006] 63 | Type=Text 64 | ID=PatternNum 65 | Caption=00/00 66 | X1=10 67 | Y1=06 68 | X2=15 69 | Y2=07 70 | Border=sunken pixel 71 | 72 | [007] 73 | Type=Text 74 | ID=OrderNum 75 | Caption=000/000 76 | X1=23 77 | Y1=06 78 | X2=30 79 | Y2=07 80 | Border=sunken pixel 81 | 82 | [008] 83 | Type=Text 84 | ID=Current Sample 85 | Caption=01: 86 | X1=39 87 | Y1=02 88 | X2=64 89 | Y2=03 90 | Border=sunken pixel 91 | 92 | [009] 93 | Type=Text 94 | ID=Current Octave 95 | Caption=Hi 96 | X1=39 97 | Y1=04 98 | X2=41 99 | Y2=05 100 | Border=sunken pixel 101 | 102 | [010] 103 | Type=Text 104 | ID=Current Speed 105 | Caption=000/125 106 | X1=39 107 | Y1=06 108 | X2=46 109 | Y2=07 110 | Border=sunken pixel 111 | 112 | [011] 113 | Type=Text 114 | ID=Playback Indicator 115 | X1=00 116 | Y1=00 117 | X2=09 118 | Y2=01 119 | 120 | [012] 121 | Type=Text 122 | ID=Time Display 123 | Caption= 0:00:00 124 | X1=72 125 | Y1=00 126 | X2=80 127 | Y2=01 128 | TextAlign=2 129 | 130 | [013] 131 | Type=Text 132 | ID=Song size 133 | Caption=Song: 134 | X1=66 135 | Y1=02 136 | X2=79 137 | Y2=03 138 | 139 | [014] 140 | Type=Text 141 | ID=Samples size 142 | Caption=Samples: 143 | X1=66 144 | Y1=+1 145 | 146 | [015] 147 | Type=Text 148 | ID=Total size 149 | Caption=Total: 150 | X1=66 151 | Y1=+1 152 | 153 | [016] 154 | Type=Text 155 | Caption=Pattern Editor (%sc:Screen.PatternEditor%) 156 | X1=01 157 | Y1=09 158 | X2=59 159 | Y2=10 160 | TextAlign=3 161 | 162 | [017] 163 | Type=Text 164 | Caption=Orders (%sc:Screen.OrderList%) 165 | X1=61 166 | Y1=09 167 | X2=79 168 | Y2=10 169 | TextAlign=3 170 | 171 | [018] 172 | Type=Text 173 | ID=\"Channel 1\" 174 | Caption=Channel 1 175 | X1=04 176 | Y1=11 177 | X2=17 178 | Y2=12 179 | TextAlign=1 180 | 181 | [019] 182 | Type=Text 183 | ID=\"Channel 2\" 184 | Caption=Channel 2 185 | X1=18 186 | Y1=11 187 | X2=31 188 | Y2=12 189 | TextAlign=1 190 | 191 | [020] 192 | Type=Text 193 | ID=\"Channel 3\" 194 | Caption=Channel 3 195 | X1=32 196 | Y1=11 197 | X2=45 198 | Y2=12 199 | TextAlign=1 200 | 201 | [021] 202 | Type=Text 203 | ID=\"Channel 4\" 204 | Caption=Channel 4 205 | X1=46 206 | Y1=11 207 | X2=59 208 | Y2=12 209 | TextAlign=1 210 | 211 | [022] 212 | Type=Text 213 | Caption=Songname 214 | X1=01 215 | Y1=02 216 | X2=09 217 | Y2=03 218 | 219 | [023] 220 | Type=Text 221 | Caption=Filename 222 | X1=01 223 | Y1=04 224 | X2=09 225 | Y2=05 226 | 227 | [024] 228 | Type=Text 229 | Caption=Pattern 230 | X1=01 231 | Y1=06 232 | X2=09 233 | Y2=07 234 | 235 | [025] 236 | Type=Text 237 | Caption=Order 238 | X1=17 239 | Y1=06 240 | X2=22 241 | Y2=07 242 | 243 | [026] 244 | Type=Text 245 | Caption=Sample 246 | X1=32 247 | Y1=02 248 | X2=38 249 | Y2=03 250 | 251 | [027] 252 | Type=Text 253 | Caption=Octave 254 | X1=32 255 | Y1=04 256 | X2=38 257 | Y2=05 258 | 259 | [028] 260 | Type=Text 261 | Caption=Tempo 262 | X1=32 263 | Y1=06 264 | X2=38 265 | Y2=07 266 | 267 | [029] 268 | Type=Button 269 | Caption=Menu 270 | X1=69 271 | Y1=11 272 | X2=79 273 | Shortcut=#Program.Menu 274 | 275 | [030] 276 | Type=Text 277 | Caption=Module 278 | X1=69 279 | Y1=+3 280 | X2=79 281 | Y2=14 282 | TextAlign=3 283 | ColorText=1 284 | 285 | [031] 286 | Type=Button 287 | Caption=New. 288 | X1=69 289 | Y1=+2 290 | X2=79 291 | Shortcut=#Song.New 292 | 293 | [032] 294 | Type=Button 295 | Caption=Load 296 | Y1=+2 297 | Shortcut=#Screen.Load 298 | 299 | [033] 300 | Type=Button 301 | Caption=Save 302 | Y1=+2 303 | Shortcut=#Screen.Save 304 | 305 | [034] 306 | Type=Button 307 | Caption=Info 308 | Y1=+2 309 | Shortcut=#Song.Length 310 | 311 | [035] 312 | Type=Button 313 | Caption=Clean Up 314 | Y1=+2 315 | Shortcut=#Song.Cleanup 316 | 317 | [036] 318 | Type=Button 319 | Caption=Samples 320 | Y1=+2 321 | Shortcut=#Screen.Samples 322 | 323 | [037] 324 | Type=Text 325 | Caption=Play 326 | Y1=+3 327 | TextAlign=3 328 | ColorText=1 329 | 330 | [038] 331 | Type=Button 332 | Caption=Song 333 | Y1=+2 334 | Shortcut=#Playback.Song 335 | 336 | [039] 337 | Type=Button 338 | Caption=Pattern 339 | Y1=+2 340 | Shortcut=#Playback.Pattern 341 | 342 | [040] 343 | Type=Button 344 | Caption=Stop 345 | Y1=+2 346 | Shortcut=#Playback.Stop 347 | 348 | [041] 349 | Type=Text 350 | Caption=Misc 351 | Y1=+4 352 | TextAlign=3 353 | ColorText=1 354 | 355 | [042] 356 | Type=Button 357 | Caption=Help 358 | Y1=+2 359 | Shortcut=#Screen.Help 360 | 361 | [043] 362 | Type=Button 363 | Caption=Settings 364 | Y1=+2 365 | Shortcut=#Screen.Config 366 | -------------------------------------------------------------------------------- /data/layout/Editor.layout: -------------------------------------------------------------------------------- 1 | [] 2 | Type=Box 3 | ID=Song Title 4 | X1=10 5 | Y1=02 6 | X2=30 7 | Y2=03 8 | Border=sunken pixel 9 | Data=0B00 10 | 11 | [] 12 | Type=Box 13 | ID=Song Filename 14 | X1=10 15 | Y1=04 16 | X2=30 17 | Y2=05 18 | Border=sunken pixel 19 | Data=0B00 20 | 21 | [] 22 | Type=Box 23 | ID=Scope 24 | X1=64 25 | Y1=02 26 | X2=79 27 | Y2=05 28 | ColorText=03 29 | ColorBack=00 30 | Border=sunken pixel 31 | Data=0D 32 | 33 | [] 34 | Type=Box 35 | ID=PatternView 36 | X1=01 37 | Y1=12 38 | X2=59 39 | Y2=44 40 | Border=fat sunken 41 | Data=0D0E0F0803090900030003 42 | 43 | [] 44 | Type=Box 45 | ID=OrderList 46 | X1=61 47 | Y1=11 48 | X2=67 49 | Y2=44 50 | Border=fat sunken 51 | 52 | [] 53 | Type=Text 54 | ID=App Title and Build Data 55 | Caption=Propulse Tracker 56 | X1=00 57 | Y1=00 58 | X2=80 59 | Y2=01 60 | TextAlign=1 61 | 62 | [] 63 | Type=Text 64 | ID=PatternNum 65 | Caption=00/00 66 | X1=10 67 | Y1=06 68 | X2=15 69 | Y2=07 70 | Border=sunken pixel 71 | 72 | [] 73 | Type=Text 74 | ID=OrderNum 75 | Caption=000/000 76 | X1=23 77 | Y1=06 78 | X2=30 79 | Y2=07 80 | Border=sunken pixel 81 | 82 | [] 83 | Type=Text 84 | ID=Current Sample 85 | Caption=01: 86 | X1=38 87 | Y1=02 88 | X2=63 89 | Border=sunken pixel 90 | 91 | [] 92 | Type=Text 93 | ID=Current Octave 94 | Caption=Hi 95 | X1=38 96 | Y1=+2 97 | X2=40 98 | Border=sunken pixel 99 | 100 | [] 101 | Type=Text 102 | ID=Current Speed 103 | Caption=00/125 104 | X1=38 105 | Y1=+2 106 | X2=44 107 | Border=sunken pixel 108 | 109 | [] 110 | Type=Text 111 | ID=Playback Indicator 112 | X1=00 113 | Y1=00 114 | X2=09 115 | Y2=01 116 | 117 | [] 118 | Type=Text 119 | ID=Time Display 120 | Caption= 0:00:00 121 | X1=72 122 | Y1=00 123 | X2=80 124 | Y2=01 125 | TextAlign=2 126 | 127 | [] 128 | Type=Text 129 | ID=Song size 130 | Caption=Song: 131 | TextAlign=2 132 | X1=47 133 | Y1=04 134 | X2=63 135 | 136 | [] 137 | Type=Text 138 | ID=Samples size 139 | Caption=Samples: 140 | TextAlign=2 141 | Y1=+1 142 | 143 | [] 144 | Type=Text 145 | ID=Total size 146 | Caption=Total: 147 | TextAlign=2 148 | Y1=+1 149 | 150 | [] 151 | Type=Text 152 | Caption=Pattern Editor (%sc:Screen.PatternEditor%) 153 | X1=01 154 | Y1=09 155 | X2=59 156 | TextAlign=3 157 | 158 | [] 159 | Type=Text 160 | Caption=Orders (%sc:Screen.OrderList%) 161 | X1=61 162 | Y1=09 163 | X2=79 164 | TextAlign=3 165 | 166 | [] 167 | Type=Text 168 | ID=\"Channel 1\" 169 | Caption=Channel 1 170 | X1=04 171 | Y1=11 172 | X2=17 173 | TextAlign=1 174 | 175 | [] 176 | Type=Text 177 | ID=\"Channel 2\" 178 | Caption=Channel 2 179 | X1=18 180 | X2=31 181 | TextAlign=1 182 | 183 | [] 184 | Type=Text 185 | ID=\"Channel 3\" 186 | Caption=Channel 3 187 | X1=32 188 | X2=45 189 | TextAlign=1 190 | 191 | [] 192 | Type=Text 193 | ID=\"Channel 4\" 194 | Caption=Channel 4 195 | X1=46 196 | X2=59 197 | TextAlign=1 198 | 199 | [] 200 | Type=Text 201 | Caption=Songname 202 | X1=01 203 | Y1=02 204 | X2=09 205 | 206 | [] 207 | Type=Text 208 | Caption=Filename 209 | X1=01 210 | Y1=04 211 | X2=09 212 | 213 | [] 214 | Type=Text 215 | Caption=Pattern 216 | X1=01 217 | Y1=06 218 | X2=09 219 | 220 | [] 221 | Type=Text 222 | Caption=Order 223 | X1=17 224 | Y1=06 225 | X2=22 226 | 227 | [] 228 | Type=Text 229 | Caption=Sample 230 | X1=31 231 | Y1=02 232 | X2=37 233 | 234 | [] 235 | Type=Text 236 | Caption=Octave 237 | X1=31 238 | Y1=+2 239 | 240 | [] 241 | Type=Text 242 | Caption=Tempo 243 | Y1=+2 244 | 245 | [] 246 | Type=Box 247 | ID=AmpSlider 248 | X1=68 249 | Y1=06 250 | X2=75 251 | Border=sunken pixel 252 | 253 | [] 254 | Type=Text 255 | ID=AmpLabel 256 | Caption=0.0 257 | X1=76 258 | X2=79 259 | 260 | [] 261 | Type=Text 262 | Caption=Amp 263 | X1=64 264 | X2=67 265 | 266 | [] 267 | Type=Box 268 | Border=sunken pixel 269 | X1=00 270 | X2=80 271 | Y1=08 272 | Y2=08 273 | 274 | [] 275 | Type=Button 276 | Caption=Menu 277 | X1=69 278 | Y1=11 279 | X2=79 280 | Shortcut=#Program.Menu 281 | 282 | [] 283 | Type=Text 284 | Caption=Module 285 | X1=69 286 | Y1=+2 287 | Y2=14 288 | TextAlign=3 289 | ColorText=1 290 | 291 | [] 292 | Type=Button 293 | Caption=New. 294 | X1=69 295 | Y1=+2 296 | Shortcut=#Song.New 297 | 298 | [] 299 | Type=Button 300 | Caption=Load 301 | Y1=+2 302 | Shortcut=#Screen.Load 303 | 304 | [] 305 | Type=Button 306 | Caption=Save 307 | Y1=+2 308 | Shortcut=#Screen.Save 309 | 310 | [] 311 | Type=Button 312 | Caption=Clean Up 313 | Y1=+2 314 | Shortcut=#Song.Cleanup 315 | 316 | [] 317 | Type=Button 318 | Caption=Info 319 | Y1=+2 320 | Shortcut=#Song.Length 321 | 322 | [] 323 | Type=Button 324 | Caption=Seek To 325 | Y1=+2 326 | Shortcut=#Song.JumpToTime 327 | 328 | [] 329 | Type=Button 330 | Caption=Samples 331 | Y1=+2 332 | Shortcut=#Screen.Samples 333 | 334 | [] 335 | Type=Text 336 | Caption=Play 337 | Y1=+2 338 | TextAlign=3 339 | ColorText=1 340 | 341 | [] 342 | Type=Button 343 | Caption=Song 344 | Y1=+2 345 | Shortcut=#Playback.Song 346 | 347 | [] 348 | Type=Button 349 | Caption=Pattern 350 | Y1=+2 351 | Shortcut=#Playback.Pattern 352 | 353 | [] 354 | Type=Button 355 | Caption=Stop 356 | Y1=+2 357 | Shortcut=#Playback.Stop 358 | 359 | [] 360 | Type=Text 361 | Caption=Misc 362 | Y1=+2 363 | TextAlign=3 364 | ColorText=1 365 | 366 | [] 367 | Type=Button 368 | Caption=Help 369 | Y1=+2 370 | Shortcut=#Screen.Help 371 | 372 | [] 373 | Type=Button 374 | Caption=About 375 | Y1=+2 376 | Shortcut=#Screen.About 377 | 378 | [] 379 | Type=Button 380 | Caption=Settings 381 | Y1=+2 382 | Shortcut=#Screen.Config 383 | -------------------------------------------------------------------------------- /data/logo.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/logo.pcx -------------------------------------------------------------------------------- /data/midi/Akai APC Key 25.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/midi/Akai APC Key 25.ini -------------------------------------------------------------------------------- /data/midi/Numark DJ2Go.ini: -------------------------------------------------------------------------------- 1 | [Controller] 2 | ; 3 | ; Display name and names of MIDI input and output devices 4 | ; 5 | Version=1.0 6 | 7 | Name=Numark DJ2Go 8 | Input=Numark DJ2Go 9 | Output=Numark DJ2Go 10 | 11 | Led.On=KeyOn,ID,255 12 | Led.Off=KeyOff,ID,255 13 | 14 | ; 15 | ; Buttons 16 | ; 17 | [$9033] 18 | Name=A Cue 19 | Function=Deck1.Cue 20 | Led=True 21 | 22 | [$903B] 23 | Name=A Play/Pause 24 | Function=Deck1.Play 25 | Led=True 26 | 27 | [$9040] 28 | Name=A Sync 29 | Function=Deck1.MatchBPM 30 | 31 | [$9065] 32 | Name=A PFL 33 | Function=Deck1.Monitor 34 | Led=True 35 | 36 | [$904B] 37 | Name=A Load 38 | Function=Deck1.Load 39 | 40 | [$9043] 41 | Name=A Pitch Bend + 42 | Function=Deck1.Bend.+ 43 | 44 | [$9044] 45 | Name=A Pitch Bend - 46 | Function=Deck1.Bend.- 47 | 48 | [$903C] 49 | Name=B Cue 50 | Function=Deck2.Cue 51 | Led=True 52 | 53 | [$9042] 54 | Name=B Play/Pause 55 | Function=Deck2.Play 56 | Led=True 57 | 58 | [$9047] 59 | Name=B Sync 60 | Function=Deck2.MatchBPM 61 | 62 | [$9066] 63 | Name=B PFL 64 | Function=Deck2.Monitor 65 | Led=True 66 | 67 | [$9034] 68 | Name=B Load 69 | Function=Deck2.Load 70 | 71 | [$9045] 72 | Name=B Pitch Bend + 73 | Function=Deck2.Bend.+ 74 | 75 | [$9046] 76 | Name=B Pitch Bend - 77 | Function=Deck2.Bend.- 78 | 79 | [$9059] 80 | Function=Back 81 | 82 | [$905A] 83 | Function=Enter 84 | 85 | ; 86 | ; Pots & faders (absolute values) 87 | ; 88 | [$B008] 89 | Type=Absolute 90 | Name=A Volume 91 | Function=Deck1.Volume 92 | 93 | [$B009] 94 | Type=Absolute 95 | Name=B Volume 96 | Function=Deck2.Volume 97 | 98 | [$B00A] 99 | Type=Absolute 100 | Function=Crossfader 101 | 102 | [$B00D] 103 | Type=Absolute 104 | Name=A Pitch 105 | Function=Deck1.Tempo 106 | 107 | [$B00E] 108 | Type=Absolute 109 | Name=B Pitch 110 | Function=Deck2.Tempo 111 | 112 | [$B017] 113 | Type=Absolute 114 | Name=Master Gain 115 | Function=Volume.Master 116 | 117 | [$B00B] 118 | Type=Absolute 119 | Name=Headphone Gain 120 | Function=Volume.Monitor 121 | 122 | ; 123 | ; Encoders & wheels (relative values) 124 | ; 125 | [$B01A] 126 | Type=Relative 127 | Function=Browse 128 | 129 | [$B019] 130 | Type=Relative 131 | Name=A Wheel 132 | Function=Deck1.Wheel 133 | 134 | [$B018] 135 | Type=Relative 136 | Name=B Wheel 137 | Function=Deck2.Wheel 138 | -------------------------------------------------------------------------------- /data/midi/font6x5.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/midi/font6x5.pcx -------------------------------------------------------------------------------- /data/mouse.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/mouse.pcx -------------------------------------------------------------------------------- /data/mouse2.pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/data/mouse2.pcx -------------------------------------------------------------------------------- /data/palette.ini: -------------------------------------------------------------------------------- 1 | [Palette] 2 | Color 00 R=0 3 | Color 00 G=0 4 | Color 00 B=0 5 | Color 01 R=31 6 | Color 01 G=24 7 | Color 01 B=15 8 | Color 02 R=50 9 | Color 02 G=43 10 | Color 02 B=34 11 | Color 03 R=63 12 | Color 03 G=57 13 | Color 03 B=48 14 | Color 04 R=45 15 | Color 04 G=4 16 | Color 04 B=21 17 | Color 05 R=63 18 | Color 05 G=63 19 | Color 05 B=21 20 | Color 06 R=19 21 | Color 06 G=40 22 | Color 06 B=20 23 | Color 07 R=19 24 | Color 07 G=3 25 | Color 07 B=6 26 | Color 08 R=10 27 | Color 08 G=22 28 | Color 08 B=28 29 | Color 09 R=8 30 | Color 09 G=28 31 | Color 09 B=38 32 | Color 10 R=27 33 | Color 10 G=34 34 | Color 10 B=40 35 | Color 11 R=63 36 | Color 11 G=63 37 | Color 11 B=63 38 | Color 12 R=38 39 | Color 12 G=38 40 | Color 12 B=38 41 | Color 13 R=34 42 | Color 13 G=8 43 | Color 13 B=21 44 | Color 14 R=22 45 | Color 14 G=16 46 | Color 14 B=15 47 | Color 15 R=14 48 | Color 15 G=14 49 | Color 15 B=13 50 | 51 | [Scrollbar] 52 | Gutter=15 53 | Thumb=2 54 | Button=2 55 | Icon=0 56 | Hover=3 57 | Active=2 58 | 59 | [PatternEditor] 60 | CUR_FG=0 61 | CUR_BG=3 62 | HL_ROW=14 63 | HL_BEAT=15 64 | SEL_BG=8 65 | SEL_FG=3 66 | HL_SEL_ROW=9 67 | HL_SEL_BEAT=9 68 | ROW=0 69 | ROW_CURRENT=3 70 | ROW_CURRENTOTHER=6 71 | INVALID=7 72 | FG=6 73 | BG=0 74 | 75 | [General] 76 | Blank=0 77 | Text=4 78 | Panel=2 79 | 3D Dark=1 80 | 3D Light=3 81 | Light=11 82 | 83 | [Sample] 84 | Background=8 85 | Waveform=8 86 | Waveform >64K=8 87 | Center Line=8 88 | Loop Point=8 89 | Loop Point Hover=8 90 | Selection FG=8 91 | Selection BG=8 92 | 93 | [Waveform] 94 | Background=0 95 | Waveform=6 96 | Overrun=4 97 | Center line=15 98 | Loop point=5 99 | Loop hover=2 100 | Selection fore=11 101 | Selection back=4 102 | Playback pos.=11 103 | 104 | [File Requester] 105 | Bookmark=10 106 | Drive=2 107 | ParentDir=11 108 | Directory=6 109 | File Size=2 110 | File Date=10 111 | PT Module=3 112 | Other Module=2 113 | Sample File=6 114 | Empty Sample=15 115 | -------------------------------------------------------------------------------- /data/palette/Camouflage.ini: -------------------------------------------------------------------------------- 1 | [Palette] 2 | Color 00 R=0 3 | Color 00 G=0 4 | Color 00 B=0 5 | Color 01 R=31 6 | Color 01 G=22 7 | Color 01 B=17 8 | Color 02 R=45 9 | Color 02 G=37 10 | Color 02 B=30 11 | Color 03 R=58 12 | Color 03 G=58 13 | Color 03 B=50 14 | Color 04 R=44 15 | Color 04 G=0 16 | Color 04 B=21 17 | Color 05 R=63 18 | Color 05 G=63 19 | Color 05 B=21 20 | Color 06 R=17 21 | Color 06 G=38 22 | Color 06 B=18 23 | Color 07 R=19 24 | Color 07 G=3 25 | Color 07 B=6 26 | Color 08 R=8 27 | Color 08 G=21 28 | Color 08 B=0 29 | Color 09 R=6 30 | Color 09 G=29 31 | Color 09 B=11 32 | Color 10 R=14 33 | Color 10 G=39 34 | Color 10 B=29 35 | Color 11 R=55 36 | Color 11 G=58 37 | Color 11 B=56 38 | Color 12 R=40 39 | Color 12 G=40 40 | Color 12 B=40 41 | Color 13 R=35 42 | Color 13 G=5 43 | Color 13 B=21 44 | Color 14 R=22 45 | Color 14 G=16 46 | Color 14 B=15 47 | Color 15 R=13 48 | Color 15 G=12 49 | Color 15 B=11 50 | 51 | [Scrollbar] 52 | Gutter=1 53 | Thumb=2 54 | Button=2 55 | Icon=0 56 | Hover=3 57 | Active=11 58 | [PatternEditor] 59 | FG=6 60 | BG=0 61 | CUR_FG=0 62 | CUR_BG=3 63 | HL_ROW=14 64 | HL_BEAT=15 65 | SEL_BG=8 66 | SEL_FG=3 67 | HL_SEL_ROW=9 68 | HL_SEL_BEAT=9 69 | ROW=0 70 | ROW_CURRENT=3 71 | ROW_CURRENTOTHER=6 72 | INVALID=13 73 | [General] 74 | Blank=0 75 | Panel=2 76 | 3D Dark=1 77 | 3D Light=3 78 | Light=11 79 | -------------------------------------------------------------------------------- /data/palette/ProTracker.ini: -------------------------------------------------------------------------------- 1 | [Palette] 2 | Color 00 R=0 3 | Color 00 G=0 4 | Color 00 B=0 5 | Color 01 R=19 6 | Color 01 G=19 7 | Color 01 B=19 8 | Color 02 R=34 9 | Color 02 G=34 10 | Color 02 B=34 11 | Color 03 R=47 12 | Color 03 G=47 13 | Color 03 B=47 14 | Color 04 R=42 15 | Color 04 G=4 16 | Color 04 B=21 17 | Color 05 R=63 18 | Color 05 G=55 19 | Color 05 B=4 20 | Color 06 R=17 21 | Color 06 G=23 22 | Color 06 B=63 23 | Color 07 R=10 24 | Color 07 G=10 25 | Color 07 B=10 26 | Color 08 R=3 27 | Color 08 G=16 28 | Color 08 B=34 29 | Color 09 R=4 30 | Color 09 G=24 31 | Color 09 B=50 32 | Color 10 R=5 33 | Color 10 G=38 34 | Color 10 B=54 35 | Color 11 R=51 36 | Color 11 G=53 37 | Color 11 B=52 38 | Color 12 R=23 39 | Color 12 G=32 40 | Color 12 B=60 41 | Color 13 R=0 42 | Color 13 G=63 43 | Color 13 B=0 44 | Color 14 R=1 45 | Color 14 G=9 46 | Color 14 B=23 47 | Color 15 R=1 48 | Color 15 G=5 49 | Color 15 B=13 50 | [General] 51 | Blank=0 52 | Panel=2 53 | 3D Dark=1 54 | 3D Light=3 55 | Light=11 56 | [PatternEditor] 57 | FG=6 58 | BG=0 59 | CUR_FG=0 60 | CUR_BG=3 61 | HL_ROW=14 62 | HL_BEAT=15 63 | SEL_BG=8 64 | SEL_FG=3 65 | HL_SEL_ROW=9 66 | HL_SEL_BEAT=9 67 | ROW=0 68 | ROW_CURRENT=3 69 | ROW_CURRENTOTHER=6 70 | INVALID=4 71 | [Scrollbar] 72 | Gutter=8 73 | Thumb=10 74 | Button=10 75 | Icon=0 76 | Hover=2 77 | Active=11 78 | [Waveform] 79 | Background=0 80 | Waveform=5 81 | Overrun=4 82 | Center line=7 83 | Loop point=13 84 | Loop hover=13 85 | Selection fore=11 86 | Selection back=4 87 | -------------------------------------------------------------------------------- /data/palette/Propulse.ini: -------------------------------------------------------------------------------- 1 | [Palette] 2 | Color 00 R=0 3 | Color 00 G=0 4 | Color 00 B=0 5 | Color 01 R=31 6 | Color 01 G=24 7 | Color 01 B=15 8 | Color 02 R=50 9 | Color 02 G=43 10 | Color 02 B=34 11 | Color 03 R=63 12 | Color 03 G=57 13 | Color 03 B=48 14 | Color 04 R=45 15 | Color 04 G=4 16 | Color 04 B=21 17 | Color 05 R=63 18 | Color 05 G=63 19 | Color 05 B=21 20 | Color 06 R=19 21 | Color 06 G=40 22 | Color 06 B=20 23 | Color 07 R=19 24 | Color 07 G=3 25 | Color 07 B=6 26 | Color 08 R=10 27 | Color 08 G=22 28 | Color 08 B=28 29 | Color 09 R=8 30 | Color 09 G=28 31 | Color 09 B=38 32 | Color 10 R=27 33 | Color 10 G=34 34 | Color 10 B=40 35 | Color 11 R=63 36 | Color 11 G=63 37 | Color 11 B=63 38 | Color 12 R=38 39 | Color 12 G=38 40 | Color 12 B=38 41 | Color 13 R=34 42 | Color 13 G=8 43 | Color 13 B=21 44 | Color 14 R=22 45 | Color 14 G=16 46 | Color 14 B=15 47 | Color 15 R=14 48 | Color 15 G=14 49 | Color 15 B=13 50 | 51 | [Scrollbar] 52 | Gutter=8 53 | Thumb=10 54 | Button=10 55 | Icon=0 56 | Hover=2 57 | Active=11 58 | [General] 59 | Blank=0 60 | Panel=2 61 | 3D Dark=1 62 | 3D Light=3 63 | Light=11 64 | [PatternEditor] 65 | FG=6 66 | BG=0 67 | CUR_FG=0 68 | CUR_BG=3 69 | HL_ROW=14 70 | HL_BEAT=15 71 | SEL_BG=8 72 | SEL_FG=3 73 | HL_SEL_ROW=9 74 | HL_SEL_BEAT=9 75 | ROW=0 76 | ROW_CURRENT=3 77 | ROW_CURRENTOTHER=6 78 | INVALID=4 79 | [Waveform] 80 | Background=0 81 | Waveform=6 82 | Overrun=4 83 | Center line=15 84 | Loop point=5 85 | Loop hover=2 86 | Selection fore=11 87 | Selection back=4 88 | Playback pos.=11 89 | -------------------------------------------------------------------------------- /data/palette/Strawberry Ice Cream.ini: -------------------------------------------------------------------------------- 1 | [Palette] 2 | Color 00 R=0 3 | Color 00 G=0 4 | Color 00 B=0 5 | Color 01 R=39 6 | Color 01 G=16 7 | Color 01 B=18 8 | Color 02 R=63 9 | Color 02 G=40 10 | Color 02 B=42 11 | Color 03 R=63 12 | Color 03 G=63 13 | Color 03 B=52 14 | Color 04 R=45 15 | Color 04 G=4 16 | Color 04 B=21 17 | Color 05 R=63 18 | Color 05 G=63 19 | Color 05 B=36 20 | Color 06 R=30 21 | Color 06 G=40 22 | Color 06 B=60 23 | Color 07 R=53 24 | Color 07 G=31 25 | Color 07 B=30 26 | Color 08 R=20 27 | Color 08 G=2 28 | Color 08 B=2 29 | Color 09 R=28 30 | Color 09 G=8 31 | Color 09 B=13 32 | Color 10 R=15 33 | Color 10 G=37 34 | Color 10 B=28 35 | Color 11 R=63 36 | Color 11 G=63 37 | Color 11 B=63 38 | Color 12 R=38 39 | Color 12 G=38 40 | Color 12 B=38 41 | Color 13 R=34 42 | Color 13 G=8 43 | Color 13 B=21 44 | Color 14 R=22 45 | Color 14 G=16 46 | Color 14 B=15 47 | Color 15 R=14 48 | Color 15 G=14 49 | Color 15 B=13 50 | -------------------------------------------------------------------------------- /docs/building.txt: -------------------------------------------------------------------------------- 1 | Propulse Tracker build instructions 2 | ------------------------------------------------------------------------------- 3 | Requirements: 4 | 5 | - FreePascal 3.0+: http://www.freepascal.org/ 6 | - Lazarus: http://www.lazarus-ide.org/ 7 | 8 | The following headers are contained in the src/include directory: 9 | 10 | Required: 11 | 12 | - SDL2: http://libsdl.org/ 13 | - Generics.Collections for FreePascal, if using an old version where they are 14 | not included by default: https://github.com/dathox/generics.collections 15 | 16 | Optional (but strongly recommended): 17 | 18 | - BASS: http://www.un4seen.com/ (required for mp3/ogg/other sample import) 19 | - libSOXR for resampling: https://sourceforge.net/p/soxr/wiki/Home/ 20 | 21 | The prebuilt binaries require these libraries in order to run. 22 | 23 | ------------------------------------------------------------------------------- 24 | 25 | Building on Windows: 26 | 27 | - Install the latest FreePascal and Lazarus (e.g. using fpcupdeluxe) 28 | - Place sdl2.dll/bass.dll/soxr.dll from the Propulse binary distribution 29 | in the project's root dir if not already there 30 | - Open Propulse.lps in Lazarus or Propulse.ctpr (outdated) in CodeTyphon 31 | - Open propulse.inc and modify options if required 32 | - Press Shift-F9 to build 33 | - Probably complain to me if it didn't work 34 | 35 | Building on Linux: 36 | 37 | - Install SDL2 development packages (libsdl2-dev) 38 | - Download the latest Linux build of BASS (un4seen.com) 39 | - (Optionally) Install/build libSOXR (libsoxr-dev) 40 | - Extract/copy libbass.so into Propulse's root dir or default library path 41 | - Start up Lazarus and build the project file, or from command line: 42 | cd 43 | lazbuild --build-mode=Release src/Propulse.lpi 44 | 45 | Building on Mac (courtesy of @nilsding): 46 | 47 | - Install the Xcode command-line tools 48 | - Install SDL2 from Homebrew: brew install sdl2 49 | - Copy /usr/local/lib/libSDL2.dylib to the project's root directory (Propulse 50 | will not run otherwise) 51 | - Download BASS for macOS from http://www.un4seen.com/ and copy libbass.dylib 52 | into the project's root directory 53 | - Append this line to your /etc/fpc.cfg if you are running 10.14 (Mojave) or 54 | newer: -XR/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk 55 | - Follow the above instructions for building on Windows 56 | 57 | ------------------------------------------------------------------------------- 58 | hukka 2020-11-23 - hukkax@gmail.com - https://github.com/hukkax/Propulse 59 | -------------------------------------------------------------------------------- /docs/images/ss1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/docs/images/ss1.png -------------------------------------------------------------------------------- /docs/images/ss2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/docs/images/ss2.png -------------------------------------------------------------------------------- /docs/images/ss3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/docs/images/ss3.png -------------------------------------------------------------------------------- /docs/status.txt: -------------------------------------------------------------------------------- 1 | Propulse Tracker current status 2 | =============================== 3 | 4 | - Basically operational on Win/Linux/Mac 5 | - Need someone else to do the Mac binary builds 6 | 7 | To be fixed: 8 | 9 | - "Boost highs" in resampling options is nonfunctional 10 | - Font and mouse pointer images must be in 1/4/8-bit PCX format 11 | - Palette preset loading/saving disabled for now due to lack of file requester 12 | 13 | Platform specific: 14 | 15 | - Setting "task priority" only available on Windows 16 | - Some file operations are untested on non-Windows platforms 17 | 18 | 19 | Regressions/changes from PoroTracker 0.8.9.3 20 | ============================================ 21 | 22 | New features: 23 | 24 | - Common file/directory operations can now be performed in the file requesters: 25 | Use the context menu (Esc) on file/directory listings or use keyboard: 26 | Shift-F2 to rename file, Shift-F5 to copy file, Shift-F6 to move file, 27 | Shift-F7 to create directory, Shift-F8 to delete file (or dir in Windows) 28 | - Bookmarks can now be renamed 29 | - Support for loading/editing samples larger than 128K 30 | - Improved waveform display 31 | 32 | Permanent changes: 33 | 34 | - Settings for audio API and graphics rendering API selection removed 35 | - Setting "use OS file requesters" removed 36 | - Window scaling (pixel doubling) is changed via settings instead of simply 37 | resizing the window 38 | - Rendering the current module or selection to WAV is done via the Save Module 39 | screen by entering a filename ending in .wav. This will display the export 40 | dialog. 41 | - Changed visual effect in splash screen 42 | 43 | 44 | Bugs fixed from PoroTracker 0.8.9.3 45 | =================================== 46 | 47 | - WAV saving: corrected a value in the wav format header 48 | - Scrollbars didn't work after clicking on them until mouse was moved away 49 | - Various other widget engine fixes and improvements 50 | - Incorrect sample format shown in file requester 51 | - Other stuff I forgot to write down 52 | 53 | -- 54 | hukka 2019-09-26 - hukkax@gmail.com 55 | http://hukka.ncn.fi/propulse/ - https://github.com/hukkax/Propulse 56 | -------------------------------------------------------------------------------- /docs/whatsnew.txt: -------------------------------------------------------------------------------- 1 | Propulse Tracker 0.9.6.1 2 | ------------------------ 3 | Maintenance update. 4 | 5 | - Correct bitdepth and audio format are now shown in sample file requester 6 | - Fixed a double-free bug which could cause a crash on sample import 7 | - Improved and corrected audio initialization/playback via SDL2 8 | - Device can be chosen instead of always using the default output device 9 | - Audio device setting is stored separately from BASS audio device setting 10 | - No longer using deprecated API calls 11 | - Improved the way libraries are loaded on Linux 12 | - Set RPATH in binary, don't use custom dynamic loader code/APIs 13 | - Removed some dependencies for a smaller binary and cleaner code 14 | 15 | Propulse Tracker 0.9.6.0 16 | ------------------------ 17 | Big update; important playroutine and sample-related fixes and features. 18 | 19 | Additions: 20 | 21 | - Implemented "Browse to File" and "Delete Directory" on all platforms 22 | - Added "Insert pattern" and "Delete pattern" (Ctrl+Insert, Ctrl+Delete) 23 | - Added "Truncate samples at loop end" in Cleanup dialog 24 | - Doubleclicking on the sample waveform now selects the sample, loop, pre-loop 25 | or post-loop data depending on location 26 | - Pressing F3 in the sample screen now brings focus back to the sample list 27 | - You can now click on a row number to the left of the pattern view to jump 28 | to that row; use right mouse button to center the clicked row 29 | - Improved orderlist coloring 30 | - Added option to display pattern row numbers in hexadecimal 31 | - Added "slide effect values" (Alt+X) and "clear effect values" (Shift+Alt+X); 32 | these were never properly implemented in the editor 33 | - Added "full clear" editor command (Shift+Period) which will clear the current 34 | column and all the columns following it on the channel 35 | - BASS is no longer required; SDL2 can be used for audio instead (but requires 36 | a recompile; also support for mp3/ogg/other samples will be missing) 37 | - Added a 7x7 font 38 | 39 | Fixes: 40 | 41 | - Fixed compile errors on newer FPC versions 42 | - Fixed fullscreen on Linux 43 | - Brought the playroutine more in line with ProTracker Clone behavior: 44 | - Fixed invalid notes and some effects producing sound when they shouldn't 45 | - Reset Paula properly when changing patterns on the fly while playing 46 | - Muted Paula channels are now always emulated to fix problems related to 47 | unmuting channels and for display on quadrascopes 48 | - Fixed invalid sample loop handling which could cause the playroutine to crash 49 | - Fixed selection not getting drawn on the rightmost pixels in sample waveform 50 | - Fixed quadrascope getting drawn out of bounds on certain font sizes 51 | - Pattern view is now properly restored upon stopping song playback 52 | - Fixed some bad behavior when editing the effect or volume columns when there 53 | already was data in the other column 54 | - Fixed a crash when attempting to merge modules 55 | - Fixed a crash on loading/browsing sample files if the file couldn't be opened 56 | - Fixes and improvements for loading samples from inside modules: 57 | - Fixed an issue with loading looped samples from SoundTracker modules 58 | - Fixed file size display 59 | - Show sample numbers 60 | 61 | Propulse Tracker 0.9.5.5 62 | ------------------------ 63 | Fixes bugs caused by pattern and replayer code simplifications in v0.9.5.0. 64 | 65 | - Regression fix: off-by-one error when modifying a note's octave via editing 66 | the octave column value caused the note B unable to be modified 67 | - Regression fix: off-by-one error when transposing notes in pattern caused 68 | A#3 to be the highest available destination note 69 | - Regression fix: off-by-one error when playing notes via keyboard in the 70 | sample list caused incorrect pitches being heard 71 | - Sample names were incorrectly padded with spaces instead of zeroes in 72 | saved modules 73 | - Fixed formatting issues with the sample list dialog shown by sample functions 74 | such as Replace with/Swap with/Copy from 75 | - Added config option for muted channel colors in quadrascope 76 | 77 | Propulse Tracker 0.9.5.2 78 | ------------------------ 79 | 80 | - New option to center the currently playing row like in Impulse Tracker 81 | - New option to reset song tempo when stopping playback like in Impulse 82 | Tracker. The default speed and tempo can be modified by clicking on the 83 | Speed/BPM indicator in the Pattern Editor screen 84 | - BPM changes now show instantly in the Speed/BPM indicator 85 | - Mouse wheel on the Order indicator changes orderlist position during playback 86 | - Mouse wheel on the Pattern label selects a pattern 87 | - Removed unnecessary leading zero from Speed indicator 88 | - When clicking on a pattern the cursor is moved to the proper column 89 | - Added new fonts 90 | 91 | Propulse Tracker 0.9.5.0 92 | ------------------------ 93 | New features 94 | 95 | - S3M import 96 | - Merge module function: press Shift-Enter on a module file (or use the 97 | context menu) to merge the module into the current one 98 | - You can now sort files by extension in the file requesters 99 | - Added Upsample and Downsample effects to samples screen 100 | - Added "Browse to current module" to file requester context menu 101 | - Text edit controls now support clipboard copy and paste (Ctrl-C, Ctrl-V) 102 | - F1 in pattern editor already showed a short description of the command 103 | under the cursor, but now pressing it again brings up a help popup with the 104 | complete description of the command 105 | - Per-channel scopes (finally); click on the scope to toggle between the 106 | normal scope and per-channel scopes. Use mousewheel, Shift+mousewheel or the 107 | palette configuration screen to modify colors used 108 | 109 | Improvements 110 | 111 | - Importing a module with more than 4 channels now lets you specify which 112 | channels to import 113 | - Module loader is now more robust and can load some broken modules 114 | - Improved file sorting in file requesters 115 | - The Cleanup dialog now allows to clean up duplicate patterns and samples 116 | - Invalid (out-of-range) notes in imported modules now show the original 117 | note value instead of "???" 118 | - If module loading fails the currently loaded module is kept in memory instead 119 | of clearing everything 120 | - Illegal sample loops are now handled better (fixes mod.shorttune2 etc.) 121 | - Sample loops are now retained after using the Resample function 122 | - Updated the help file 123 | - GUI improvements and fixes 124 | - You can now press Enter on an item in the configuration screen to 125 | modify the value via a popup window 126 | - For dialogs that ask you to select an item in a listbox, you can now 127 | doubleclick on the list to select the item and acknowledge the dialog 128 | - If there were errors or warnings when loading a module a dialog box 129 | will be displayed 130 | - Fixed incorrect size and range with scrollbar thumb in certain situations 131 | - Fixed the Ctrl and Delete keys not working in text edit controls 132 | 133 | Bugfixes 134 | 135 | - Paste function in the sample editor now works properly 136 | - File requester no longer hides filenames with more than one period in them 137 | - Impulse Tracker sample decompression is now faster and no longer generates 138 | trashed sampledata 139 | - Automatic resampling at module import no longer trashes samples 140 | - Playing notes without inserting them to the pattern using the Shift key 141 | didn't work at all 142 | - Space and period (.) keys in pattern editor didn't work like in IT 143 | -------------------------------------------------------------------------------- /libsoxr-copyright.txt: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: libsoxr 3 | Upstream-Contact: Rob Sykes 4 | Source: https://sourceforge.net/projects/soxr/files/ 5 | 6 | Files: * 7 | Copyright: 2007-2013, Rob Sykes 8 | License: LGPL-2.1+ 9 | 10 | Files: cmake/Modules/FindOpenMP.cmake cmake/Modules/FindSIMD.cmake 11 | Copyright: 2009, Kitware, Inc. 12 | 2008-2009, André Rigland Brodtkorb 13 | License: BSD-3-clause 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are 16 | met: 17 | . 18 | * Redistributions of source code must retain the above copyright notice, 19 | this list of conditions and the following disclaimer. 20 | . 21 | * Redistributions in binary form must reproduce the above copyright notice, 22 | this list of conditions and the following disclaimer in the documentation 23 | and/or other materials provided with the distribution. 24 | . 25 | * The names of Kitware, Inc., the Insight Consortium, or the names of 26 | any consortium members, or of any contributors, may not be used to 27 | endorse or promote products derived from this software without 28 | specific prior written permission. 29 | . 30 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' 31 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR 34 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 36 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 37 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 38 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | 41 | Files: src/pffft.c src/pffft.h 42 | Copyright: 2011, Julien Pommier 43 | 2004, The University Corporation for Atmospheric Research 44 | License: Spherepack 45 | Redistribution and use of the Software in source and binary forms, 46 | with or without modification, is permitted provided that the 47 | following conditions are met: 48 | . 49 | - Neither the names of NCAR's Computational and Information Systems 50 | Laboratory, the University Corporation for Atmospheric Research, 51 | nor the names of its sponsors or contributors may be used to 52 | endorse or promote products derived from this Software without 53 | specific prior written permission. 54 | . 55 | - Redistributions of source code must retain the above copyright 56 | notices, this list of conditions, and the disclaimer below. 57 | . 58 | - Redistributions in binary form must reproduce the above copyright 59 | notice, this list of conditions, and the disclaimer below in the 60 | documentation and/or other materials provided with the 61 | distribution. 62 | . 63 | THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 64 | EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE WARRANTIES OF 65 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 66 | NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT 67 | HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL, 68 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY, WHETHER IN AN 69 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 70 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE 71 | SOFTWARE. 72 | 73 | Files: src/fft4g.c 74 | Copyright: 1996-2001, Takuya OOURA 75 | License: permissive1 76 | You may use, copy, modify and distribute this code for any 77 | purpose (include commercial use) and without fee. Please 78 | refer to this package when you modify this code. 79 | http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html 80 | 81 | Files: src/dbesi0.c 82 | Copyright: 1996, Takuya OOURA 83 | License: permissive2 84 | You may use, copy, modify this code for any purpose and 85 | without fee. 86 | 87 | Files: debian/* 88 | Copyright: 2012-2013, Benjamin Drung 89 | License: LGPL-2.1+ 90 | 91 | License: LGPL-2.1+ 92 | This library is free software; you can redistribute it and/or modify it 93 | under the terms of the GNU Lesser General Public License as published by 94 | the Free Software Foundation; either version 2.1 of the License, or (at 95 | your option) any later version. 96 | . 97 | This library is distributed in the hope that it will be useful, but 98 | WITHOUT ANY WARRANTY; without even the implied warranty of 99 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 100 | General Public License for more details. 101 | . 102 | You should have received a copy of the GNU Lesser General Public License 103 | along with this library; if not, write to the Free Software Foundation, 104 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 105 | . 106 | On Debian systems, the full text of the GNU Lesser General Public 107 | License version 2.1 can be found in the file 108 | `/usr/share/common-licenses/LGPL-2.1'. 109 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /src/configurationmanager.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/src/configurationmanager.pas -------------------------------------------------------------------------------- /src/cwe/cwe.externalapi.pas: -------------------------------------------------------------------------------- 1 | // 2 | // interface CWE with SDL2 3 | // 4 | unit CWE.ExternalAPI; 5 | 6 | {$mode delphi} 7 | 8 | interface 9 | 10 | uses 11 | Classes, SysUtils, 12 | SDL2, 13 | CWE.Widgets.Text; 14 | 15 | const 16 | KEY_DOWN = SDLK_DOWN; 17 | KEY_UP = SDLK_UP; 18 | KEY_RETURN = SDLK_RETURN; 19 | KEY_BACKSPACE = SDLK_BACKSPACE; 20 | 21 | 22 | procedure ClipboardCopy(Sender: TCWEEdit); 23 | procedure ClipboardPaste(Sender: TCWEEdit); 24 | 25 | 26 | implementation 27 | 28 | uses 29 | Math, 30 | MainWindow; 31 | 32 | procedure ClipboardCopy(Sender: TCWEEdit); 33 | begin 34 | SDL_SetClipboardText(PChar(Sender.Caption)); 35 | end; 36 | 37 | procedure ClipboardPaste(Sender: TCWEEdit); 38 | var 39 | S: PAnsiChar; 40 | Text, Dest: AnsiString; 41 | X: Integer; 42 | begin 43 | if SDL_HasClipboardText = SDL_TRUE then 44 | begin 45 | if Sender.AllowedChars <> '' then Exit; 46 | S := SDL_GetClipboardText; 47 | Text := StrPas(S); 48 | if Text <> '' then 49 | begin 50 | Dest := Sender.Caption; 51 | X := Sender.Cursor.X; 52 | Dest.Insert(X, Text); 53 | Sender.SetCaption(Dest); 54 | Sender.Cursor.X := Min(X + Length(Text), Length(Dest)); 55 | Sender.Paint; 56 | Sender.Change(Sender.ReportAnyChange); 57 | end; 58 | //SDL_Free(S); // crashes 59 | end; 60 | end; 61 | 62 | end. 63 | 64 | -------------------------------------------------------------------------------- /src/cwe/cwe.mainmenu.pas: -------------------------------------------------------------------------------- 1 | unit CWE.MainMenu; 2 | 3 | interface 4 | 5 | uses 6 | Classes, SysUtils, Types, 7 | ShortcutManager, 8 | CWE.Core, CWE.Widgets.Text; 9 | 10 | type 11 | TCWEMainMenuList = class(TCWETwoColumnList) 12 | public 13 | function KeyDown(var Key: Integer; Shift: TShiftState): Boolean; override; 14 | end; 15 | 16 | TCWEMainMenu = class 17 | private 18 | Section: TKeyBindings; 19 | List: TCWEMainMenuList; 20 | public 21 | procedure Show; 22 | procedure MainMenuCommand(Sender: TCWEControl); 23 | 24 | procedure SetSection(var ASection: TKeyBindings); 25 | procedure AddSection(const Caption: AnsiString); 26 | procedure AddCmd(Key: Cardinal; const Caption: AnsiString); 27 | procedure AddCmdEx(Key: Cardinal; const Caption: AnsiString); 28 | end; 29 | 30 | var 31 | ContextMenu: TCWEMainMenu; 32 | 33 | implementation 34 | 35 | uses 36 | MainWindow, 37 | TextMode, SDL2, 38 | ProTracker.Util, CWE.Dialogs; 39 | 40 | { TCWEMainMenu } 41 | 42 | procedure TCWEMainMenu.SetSection(var ASection: TKeyBindings); 43 | begin 44 | Section := ASection; 45 | end; 46 | 47 | procedure TCWEMainMenu.AddSection(const Caption: AnsiString); 48 | begin 49 | List.Items.Add(TCWEListItem.Create(Caption, LISTITEM_HEADER, nil, 3, 2)); 50 | end; 51 | 52 | procedure TCWEMainMenu.AddCmd(Key: Cardinal; const Caption: AnsiString); 53 | begin 54 | List.Items.Add(TCWEListItem.Create( 55 | Caption + COLUMNSEPARATOR + ShortCuts.GetShortcut(Section, Key), 56 | Ord(Key), Pointer(Section))); 57 | end; 58 | 59 | procedure TCWEMainMenu.AddCmdEx(Key: Cardinal; const Caption: AnsiString); 60 | begin 61 | List.Items.Add(TCWEListItem.Create(Caption, $80000000 + Key, Pointer(Section))); 62 | end; 63 | 64 | procedure TCWEMainMenu.Show; 65 | var 66 | Dlg: TCWEScreen; 67 | i, W, H: Integer; 68 | begin 69 | W := 34+6; 70 | H := 32; 71 | 72 | if (ModalDialog.Dialog <> nil) or (CurrentScreen = nil) then 73 | Exit; 74 | 75 | Dlg := ModalDialog.CreateDialog(DIALOG_CONTEXTMENU, Bounds( 76 | (Console.Width div 2) - (W div 2), 77 | (Console.Height div 2) - (H div 2), W, H), 78 | 'Menu'); 79 | 80 | List := TCWEMainMenuList.Create(Dlg, '', 'Menu', 81 | Types.Rect(1, 2, W-1, H-1), True); 82 | 83 | with List do 84 | begin 85 | ColorBack := TConsole.COLOR_PANEL; 86 | ColorFore := TConsole.COLOR_TEXT; 87 | ColumnColor[0] := ColorFore; 88 | ColumnColor[1] := TConsole.COLOR_3DDARK; 89 | ColumnWidth[1] := 13; 90 | ColumnWidth[0] := Width - ColumnWidth[1]; 91 | OnActivate := MainMenuCommand; 92 | Selection3D := True; 93 | Data[0].Value := TConsole.COLOR_LIGHT; // bright white 94 | for i := 1 to 3 do 95 | Data[i].Value := 8; // hover bg + border 96 | end; 97 | 98 | // fill context menu items; only add global items if 99 | // CurrentScreen.OnContextMenu returns True 100 | Window.OnContextMenu(CurrentScreen.OnContextMenu); 101 | 102 | H := List.Items.Count + 3; 103 | ModalDialog.SetBounds(Bounds( 104 | (Console.Width div 2) - (W div 2), 105 | (Console.Height div 2) - (H div 2), W, H)); 106 | List.SetBounds(Types.Rect(1, 2, W-1, H-1)); 107 | List.ItemIndex := 1; 108 | List.Scrollbar.Visible := False; 109 | 110 | ModalDialog.Show; 111 | end; 112 | 113 | procedure TCWEMainMenu.MainMenuCommand(Sender: TCWEControl); 114 | var 115 | Item: TCWEListItem; 116 | Sect: TKeyBindings; 117 | Binding: TKeyBinding; 118 | i: Integer; 119 | Cmd: Cardinal; 120 | Key: Integer; 121 | Shift: TShiftState; 122 | begin 123 | // get the Key and Shift codes for a keybinding const (e.g. keyScreenHelp -> F1, []) 124 | 125 | Item := List.Items[List.ItemIndex]; 126 | if Item.ObjData = nil then Exit; 127 | Cmd := Item.Data; 128 | 129 | if (Cmd and $80000000) = 0 then 130 | begin 131 | i := Shortcuts.Sections.IndexOf(TKeyBindings(Item.ObjData)); 132 | if i < 0 then 133 | begin 134 | Log(TEXT_WARNING+'Section not found!'); 135 | Exit; 136 | end; 137 | 138 | Sect := Shortcuts.Sections[i]; 139 | Binding := Sect.FindKey(Cmd); 140 | 141 | if Binding = nil then 142 | begin 143 | Log(TEXT_WARNING+'Binding not found!'); 144 | Exit; 145 | end 146 | else 147 | begin 148 | Key := Binding.Shortcut.Key; 149 | Shift := Binding.Shortcut.Shift; 150 | if Key <> 0 then 151 | begin 152 | ModalDialog.Close; 153 | Window.OnKeyDown(Key, Shift); 154 | end 155 | else 156 | Log(TEXT_WARNING+'Unhandled command!'); 157 | end; 158 | end 159 | else 160 | begin 161 | ModalDialog.Close; 162 | CurrentScreen.HandleCommand(Cmd and $7FFFFFFF); 163 | end; 164 | end; 165 | 166 | function TCWEMainMenuList.KeyDown(var Key: Integer; Shift: TShiftState): Boolean; 167 | var 168 | Sc: ControlKeyNames; 169 | begin 170 | Sc := ControlKeyNames(Shortcuts.Find(ControlKeys, Key, Shift)); 171 | Result := True; 172 | case Sc of 173 | ctrlkeyRETURN: 174 | ContextMenu.MainMenuCommand(Self); 175 | ctrlkeyESCAPE: 176 | ModalDialog.Close; 177 | else 178 | Result := inherited; 179 | end; 180 | end; 181 | 182 | 183 | end. 184 | 185 | -------------------------------------------------------------------------------- /src/cwe/cwe.mousecursor.pas: -------------------------------------------------------------------------------- 1 | unit CWE.MouseCursor; 2 | 3 | interface 4 | 5 | uses 6 | Classes, Types, CWE.Core, TextMode, Graphics32; 7 | 8 | const 9 | CURSOR_SYSTEM = 0; 10 | CURSOR_CUSTOM = 1; 11 | CURSOR_NONE = 2; 12 | 13 | type 14 | TMouseCursor = class 15 | private 16 | function ValidCoords(var X, Y: Integer): Boolean; 17 | public 18 | Show, 19 | InWindow: Boolean; 20 | Bitmap, 21 | Background: TBitmap32; 22 | Size, 23 | HotSpot, 24 | Scaling, 25 | OldPos, 26 | Pos: TPoint; 27 | 28 | procedure Draw; 29 | procedure Erase; 30 | procedure SetImage(const Filename: String); 31 | constructor Create(const Filename: String); 32 | destructor Destroy; override; 33 | end; 34 | 35 | var 36 | MouseCursor: TMouseCursor; 37 | 38 | 39 | implementation 40 | 41 | 42 | constructor TMouseCursor.Create(const Filename: String); 43 | begin 44 | inherited Create; 45 | 46 | Bitmap := TBitmap32.Create; 47 | Background := TBitmap32.Create; 48 | 49 | SetImage(Filename); 50 | 51 | HotSpot.X := 0; 52 | HotSpot.Y := 0; 53 | 54 | Pos := Types.Point(-1, -1); 55 | InWindow := False; 56 | Show := False; 57 | end; 58 | 59 | destructor TMouseCursor.Destroy; 60 | begin 61 | Bitmap.Free; 62 | Background.Free; 63 | 64 | inherited; 65 | end; 66 | 67 | procedure TMouseCursor.SetImage(const Filename: String); 68 | begin 69 | LoadImage(Filename, Bitmap); 70 | 71 | Size.X := Bitmap.Width; 72 | Size.Y := Bitmap.Height; 73 | 74 | Background.SetSize(Size.X, Size.Y); 75 | end; 76 | 77 | function TMouseCursor.ValidCoords(var X, Y: Integer): Boolean; 78 | begin 79 | X := Pos.X - HotSpot.X; 80 | Y := Pos.Y - HotSpot.Y; 81 | Result := (Show) and (InWindow) and 82 | (X >= 0) and (Y >= 0) and 83 | (X < Console.Bitmap.Width) and (Y < Console.Bitmap.Height); 84 | end; 85 | 86 | procedure TMouseCursor.Draw; 87 | var 88 | X, Y: Integer; 89 | begin 90 | if ValidCoords(X, Y) then 91 | begin 92 | Background.Draw(0, 0, Bounds(X, Y, Size.X, Size.Y), Console.Bitmap); 93 | Console.Bitmap.DrawColorKey(X, Y, $FFFF00FF, Bitmap); 94 | end; 95 | end; 96 | 97 | procedure TMouseCursor.Erase; 98 | var 99 | X, Y: Integer; 100 | begin 101 | if ValidCoords(X, Y) then 102 | Console.Bitmap.Draw(X, Y, Background); 103 | end; 104 | 105 | end. 106 | -------------------------------------------------------------------------------- /src/dialog/dialog.generatewaveform.pas: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // Generate waveform into sample data 3 | // ========================================================================== 4 | unit Dialog.GenerateWaveform; 5 | 6 | interface 7 | 8 | uses 9 | Types, Classes, 10 | CWE.Core, CWE.Dialogs, 11 | SampleEditor; 12 | 13 | 14 | type 15 | TGenerateWaveformSettings = class 16 | public 17 | Waveform: TWavetype; 18 | Length: Integer; // length in samples 19 | SampleNote: Byte; 20 | DestNote: Byte; 21 | DestOctave: Byte; 22 | 23 | procedure DialogCallback(ID: Word; Button: TDialogButton; 24 | Tag: Integer; Data: Variant; Dlg: TCWEDialog); 25 | end; 26 | 27 | procedure Dialog_GenerateWaveform; 28 | 29 | 30 | implementation 31 | 32 | uses 33 | Screen.Config, 34 | ProTracker.Util; 35 | 36 | var 37 | GenerateWaveformSettings: TGenerateWaveformSettings; 38 | 39 | procedure TGenerateWaveformSettings.DialogCallback(ID: Word; Button: TDialogButton; 40 | Tag: Integer; Data: Variant; Dlg: TCWEDialog); 41 | begin 42 | if Dlg <> nil then Exit; 43 | 44 | if Button = btnOK then 45 | with GenerateWaveformSettings do 46 | SampleEdit.GenerateAudio(Waveform, Length, 47 | PeriodToHz(PeriodTable[SampleNote]), 48 | NoteHz[DestOctave * 12 + DestNote]); 49 | end; 50 | 51 | procedure Dialog_GenerateWaveform; 52 | const 53 | W = 26; 54 | H = 10; 55 | var 56 | Dlg: TCWEScreen; 57 | List: TCWEConfigList; 58 | Sect: AnsiString; 59 | begin 60 | Dlg := ModalDialog.CreateDialog(0, Bounds( 61 | (Console.Width div 2) - (W div 2), 62 | (Console.Height div 2) - (H div 2), W, H), 63 | 'Generate Waveform', False); 64 | 65 | List := TCWEConfigList.Create(Dlg, '', 'Waveform', 66 | Types.Rect(1, 2, W-1, H-3), True); 67 | List.ColumnWidth[1] := 8; 68 | List.Border.Pixel := True; 69 | List.Scrollbar.Visible := False; 70 | 71 | with ModalDialog do 72 | begin 73 | CreateConfigManager; 74 | Sect := 'Gen'; 75 | 76 | ConfigManager.AddByte(Sect, '', 77 | @GenerateWaveformSettings.Waveform, Ord(GenerateWaveformSettings.Waveform)). 78 | SetInfo('Waveform', Ord(WAVE_SILENCE), Ord(WAVE_NOISE), 79 | ['Silence', 'Sine', 'Square', 'Saw', 'Triangle', 'Noise']); 80 | ConfigManager.AddInteger(Sect, '', 81 | @GenerateWaveformSettings.Length, GenerateWaveformSettings.Length). 82 | SetInfo('Length', 1, $1FFFF, [], nil, '', 1, 100); 83 | ConfigManager.AddByte(Sect, '', 84 | @GenerateWaveformSettings.SampleNote, GenerateWaveformSettings.SampleNote) 85 | .SetInfo('Sample note', 0, 35, NoteNames, nil, '', 1, 12); 86 | ConfigManager.AddByte(Sect, '', 87 | @GenerateWaveformSettings.DestNote, GenerateWaveformSettings.DestNote) 88 | .SetInfo('Dest. Note', 0, 11, 89 | ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']); 90 | ConfigManager.AddByte(Sect, '', 91 | @GenerateWaveformSettings.DestOctave, GenerateWaveformSettings.DestOctave) 92 | .SetInfo('Dest. Octave', 0, 8, []); 93 | 94 | List.Init(ConfigManager); 95 | 96 | AddResultButton(btnOK, 'OK', 1, H-2, True); 97 | AddResultButton(btnCancel, 'Cancel', W-9, H-2); 98 | ButtonCallback := GenerateWaveformSettings.DialogCallback; 99 | 100 | Dialog.ActiveControl := List; 101 | Show; 102 | end; 103 | end; 104 | 105 | initialization 106 | 107 | GenerateWaveformSettings := TGenerateWaveformSettings.Create; 108 | 109 | with GenerateWaveformSettings do 110 | begin 111 | Waveform := WAVE_SILENCE; 112 | Length := 1024; 113 | SampleNote := 24; // C-3 114 | DestNote := 0; 115 | DestOctave := 3; 116 | end; 117 | 118 | finalization 119 | 120 | GenerateWaveformSettings.Free; 121 | 122 | end. 123 | 124 | -------------------------------------------------------------------------------- /src/dialog/dialog.jumptotime.pas: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // Jump to a specific time in module 3 | // ========================================================================== 4 | unit Dialog.JumpToTime; 5 | 6 | interface 7 | 8 | uses 9 | Types, Classes, 10 | CWE.Core, CWE.Dialogs; 11 | 12 | type 13 | TJumpToTimeDialog = class 14 | public 15 | Minutes, 16 | Seconds: Byte; 17 | procedure DialogCallback(ID: Word; Button: TDialogButton; 18 | Tag: Integer; Data: Variant; Dlg: TCWEDialog); 19 | end; 20 | 21 | procedure Dialog_JumpToTime; 22 | 23 | 24 | implementation 25 | 26 | uses 27 | Screen.Config, Screen.Editor, 28 | ProTracker.Player; 29 | 30 | var 31 | JumpToTimeDialog: TJumpToTimeDialog; 32 | 33 | 34 | procedure TJumpToTimeDialog.DialogCallback(ID: Word; Button: TDialogButton; 35 | Tag: Integer; Data: Variant; Dlg: TCWEDialog); 36 | begin 37 | if (Dlg = nil) and (Button = btnOK) then 38 | with JumpToTimeDialog do 39 | begin 40 | Module.JumpToTime(Minutes, Seconds); 41 | Editor.SeekTo(Module.PlayPos.Order, Module.PlayPos.Row); 42 | end; 43 | end; 44 | 45 | procedure Dialog_JumpToTime; 46 | const 47 | W = 20; 48 | H = 7; 49 | var 50 | Dlg: TCWEScreen; 51 | List: TCWEConfigList; 52 | Sect: AnsiString; 53 | begin 54 | Dlg := ModalDialog.CreateDialog(0, Bounds( 55 | (Console.Width div 2) - (W div 2), 56 | (Console.Height div 2) - (H div 2), W, H), 57 | 'Jump To Time', True); 58 | 59 | List := TCWEConfigList.Create(Dlg, '', 'Jumplist', 60 | Types.Rect(1, 2, W-1, H-3), True); 61 | List.ColumnWidth[1] := 8; 62 | List.Border.Pixel := True; 63 | List.Scrollbar.Visible := False; 64 | 65 | with ModalDialog do 66 | begin 67 | CreateConfigManager; 68 | Sect := 'Time'; 69 | 70 | ConfigManager.AddByte(Sect, '', 71 | @JumpToTimeDialog.Minutes, JumpToTimeDialog.Minutes). 72 | SetInfo('Minutes', 0, 99, []); 73 | ConfigManager.AddByte(Sect, '', 74 | @JumpToTimeDialog.Seconds, JumpToTimeDialog.Seconds). 75 | SetInfo('Seconds', 0, 59, []); 76 | 77 | List.Init(ConfigManager); 78 | 79 | AddResultButton(btnOK, 'OK', 1, H-2, True); 80 | AddResultButton(btnCancel, 'Cancel', W-9, H-2); 81 | ButtonCallback := JumpToTimeDialog.DialogCallback; 82 | 83 | Dialog.ActiveControl := List; 84 | Show; 85 | end; 86 | end; 87 | 88 | initialization 89 | 90 | JumpToTimeDialog := TJumpToTimeDialog.Create; 91 | 92 | finalization 93 | 94 | JumpToTimeDialog.Free; 95 | 96 | end. 97 | 98 | -------------------------------------------------------------------------------- /src/dialog/dialog.moduleinfo.pas: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // Display module playback length and data sizes 3 | // ========================================================================== 4 | unit Dialog.ModuleInfo; 5 | 6 | interface 7 | 8 | uses 9 | Types, Classes, 10 | CWE.Core, 11 | CWE.Dialogs; 12 | 13 | procedure Dialog_ModuleInfo; 14 | 15 | 16 | implementation 17 | 18 | uses 19 | SysUtils, 20 | CWE.Widgets.Text, 21 | ProTracker.Util, 22 | ProTracker.Player, 23 | MainWindow; 24 | 25 | 26 | procedure Dialog_ModuleInfo; 27 | var 28 | Dlg: TCWEScreen; 29 | SizeFmt: String; 30 | sizeSamp, sizePatt: Cardinal; 31 | List: TCWETwoColumnList; 32 | const 33 | W = 27; 34 | H = 12-2; 35 | begin 36 | Dlg := ModalDialog.CreateDialog(0, Bounds( 37 | (Console.Width div 2) - (W div 2), 38 | (Console.Height div 2) - (H div 2), W, H), 39 | 'Module Info'); 40 | 41 | List := TCWETwoColumnList.Create(Dlg, '', 'Module Info', 42 | Types.Rect(1, 2, W-1, H-3), True); 43 | List.ColumnWidth[1] := 14; 44 | List.Scrollbar.Visible := False; 45 | List.Border.Pixel := True; 46 | 47 | sizeSamp := 0; 48 | for sizePatt := 0 to Module.Samples.Count-1 do 49 | Inc(sizeSamp, Module.Samples[sizePatt].Length * 2); 50 | sizePatt := 1084 + ((Module.Info.PatternCount + 1) * 1024); 51 | 52 | if Options.Display.SizesAsDecimal then 53 | SizeFmt := '%7d (%dK)' 54 | else 55 | SizeFmt := '%7x (%dK)'; 56 | 57 | with ModalDialog do 58 | begin 59 | List.Items.Add(TCWEListItem.Create('Total song time: ' + 60 | FormatDateTime('hh:nn:ss', Module.GetLength / SecsPerDay) )); 61 | List.Items.Add(TCWEListItem.Create('', LISTITEM_HEADER)); 62 | List.Items.Add(TCWEListItem.Create( 63 | Format('Song size:' + COLUMNSEPARATOR + SizeFmt, 64 | [sizePatt, Round( sizePatt / 1024 )]) )); 65 | List.Items.Add(TCWEListItem.Create( 66 | Format('Samples:' + COLUMNSEPARATOR + SizeFmt, 67 | [sizeSamp, Round( sizeSamp / 1024 )]) )); 68 | List.Items.Add(TCWEListItem.Create( 69 | Format('Total:' + COLUMNSEPARATOR + SizeFmt, 70 | [sizePatt + sizeSamp, Round( (sizePatt + sizeSamp) / 1024 )]) )); 71 | 72 | AddResultButton(btnOK, 'OK', W div 2 - 3, H-2, True); 73 | ButtonCallback := Window.DialogCallback; 74 | Show; 75 | end; 76 | end; 77 | 78 | 79 | end. 80 | 81 | -------------------------------------------------------------------------------- /src/dialog/dialog.newmodule.pas: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // Initialize a new module 3 | // ========================================================================== 4 | unit Dialog.NewModule; 5 | 6 | interface 7 | 8 | uses 9 | Types, Classes, CWE.Core, CWE.Dialogs; 10 | 11 | const 12 | CLEAR_PATTERNS = 0; 13 | CLEAR_SAMPLES = 1; 14 | CLEAR_ORDERS = 2; 15 | 16 | 17 | procedure NewModule(DoDialog: Boolean); 18 | procedure Dialog_NewModule; 19 | 20 | 21 | implementation 22 | 23 | uses 24 | MainWindow, SysUtils, 25 | ProTracker.Util, 26 | ProTracker.Player, 27 | ProTracker.Sample, 28 | ProTracker.Editor, 29 | Screen.Editor, 30 | Screen.Config; 31 | 32 | 33 | procedure NewModule(DoDialog: Boolean); 34 | var 35 | p, ch, y: Integer; 36 | begin 37 | if DoDialog then 38 | Dialog_NewModule 39 | else 40 | begin 41 | Module.Stop; 42 | 43 | if DialogBooleans[CLEAR_PATTERNS] then 44 | begin 45 | Module.Pause(True); 46 | for p := 0 to MAX_PATTERNS do 47 | for ch := 0 to AMOUNT_CHANNELS-1 do 48 | for y := 0 to 63 do 49 | Module.Notes[p, ch, y] := EmptyNote; 50 | Module.Info.PatternCount := 1; 51 | Module.Info.Speed := 6; 52 | Module.Info.BPM := 125; 53 | Module.CurrentSpeed := Module.Info.Speed; 54 | Module.CurrentBPM := Module.Info.BPM; 55 | Module.Info.Filename := ''; 56 | CurrentPattern := 0; 57 | end; 58 | 59 | if DialogBooleans[CLEAR_SAMPLES] then 60 | begin 61 | Module.Pause(True); 62 | Module.Samples.Clear; 63 | for p := 0 to 31 do 64 | Module.Samples.Add(TSample.Create); 65 | end; 66 | 67 | if DialogBooleans[CLEAR_ORDERS] then 68 | begin 69 | for p := 0 to 127 do 70 | Module.OrderList[p] := 0; 71 | Module.Info.OrderCount := 1; 72 | Module.Info.RestartPos := 0; 73 | end; 74 | 75 | with Module do 76 | begin 77 | Reset; 78 | Info.Title := ''; 79 | Info.Filesize := 0; 80 | Pause(False); 81 | end; 82 | 83 | Editor.Reset; 84 | Editor.ActiveControl := PatternEditor; 85 | end; 86 | end; 87 | 88 | procedure Dialog_NewModule; 89 | const 90 | W = 22; 91 | H = 10; 92 | var 93 | Dlg: TCWEScreen; 94 | List: TCWEConfigList; 95 | begin 96 | Dlg := ModalDialog.CreateDialog(ACTION_NEWMODULE, Bounds( 97 | (Console.Width div 2) - (W div 2), 98 | (Console.Height div 2) - (H div 2), W, H), 99 | 'New Module'); 100 | 101 | List := TCWEConfigList.Create(Dlg, '', 'New', 102 | Types.Rect(2, 3, W-2, H-4), True); 103 | List.ColumnWidth[1] := 6; 104 | List.Scrollbar.Visible := False; 105 | 106 | with ModalDialog do 107 | begin 108 | CreateConfigManager; 109 | 110 | ConfigManager.AddBoolean('New', '', 111 | @DialogBooleans[CLEAR_PATTERNS], True). 112 | SetInfo('Patterns', 0, 1, ['Keep', 'Clear']); 113 | ConfigManager.AddBoolean('New', '', 114 | @DialogBooleans[CLEAR_SAMPLES], True). 115 | SetInfo('Samples', 0, 1, ['Keep', 'Clear']); 116 | ConfigManager.AddBoolean('New', '', 117 | @DialogBooleans[CLEAR_ORDERS], True). 118 | SetInfo('Orderlist', 0, 1, ['Keep', 'Clear']); 119 | 120 | List.Init(ConfigManager); 121 | 122 | AddResultButton(btnOK, 'OK', 2, H-2, True); 123 | AddResultButton(btnCancel, 'Cancel', W-10, H-2); 124 | ButtonCallback := Window.DialogCallback; 125 | 126 | Dialog.ActiveControl := List; 127 | Show; 128 | end; 129 | end; 130 | 131 | end. 132 | 133 | -------------------------------------------------------------------------------- /src/dialog/dialog.renderaudio.pas: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // Render song/pattern/selection to WAV/sample 3 | // ========================================================================== 4 | unit Dialog.RenderAudio; 5 | 6 | interface 7 | 8 | uses 9 | Types, Classes, 10 | CWE.Core, 11 | CWE.Dialogs; 12 | 13 | const 14 | ACTION_RENDER = 0; 15 | ACTION_SAMPLEOVERWRITE = 1; 16 | 17 | BTN_SAM_SEL = 0; // Selection to sample 18 | BTN_FILE_SEL = 1; // Selection to file 19 | BTN_FILE_SONG = 2; // Song to file 20 | BTN_CANCEL = 3; 21 | 22 | type 23 | TAudioRender = class 24 | private 25 | class procedure CancelMessage; 26 | public 27 | class procedure SelToSample; 28 | class procedure SelToWAV; 29 | class procedure SongToWAV(Filename: String); 30 | class procedure DialogCallback(ID: Word; ModalResult: TDialogButton; 31 | Tag: Integer; Data: Variant; Dlg: TCWEDialog); 32 | end; 33 | 34 | TAudioRenderSettings = record 35 | Filename: String; 36 | LoopTimes, 37 | FadeOutLength, 38 | DestNote: Byte; 39 | Normalize, 40 | BoostHighs, 41 | FadeOut: Boolean; 42 | end; 43 | 44 | procedure Dialog_Render(ToSample: Boolean; Filename: String = ''); 45 | 46 | // ========================================================================== 47 | 48 | implementation 49 | 50 | uses 51 | SysUtils, 52 | CWE.Widgets.Text, 53 | ProTracker.Util, 54 | ProTracker.Player, 55 | ProTracker.Sample, 56 | ProTracker.Editor, 57 | Screen.Editor, 58 | ConfigurationManager, 59 | Screen.Config; 60 | 61 | var 62 | AudioRenderSettings: TAudioRenderSettings; 63 | 64 | 65 | 66 | // ========================================================================== 67 | 68 | class procedure TAudioRender.DialogCallback(ID: Word; ModalResult: TDialogButton; 69 | Tag: Integer; Data: Variant; Dlg: TCWEDialog); 70 | begin 71 | if Dlg <> nil then Exit; 72 | 73 | if ModalResult = btnCancel then 74 | begin 75 | if ID <> ACTION_RENDER then 76 | CancelMessage; 77 | Exit; 78 | end; 79 | 80 | if ID = ACTION_RENDER then 81 | case Tag of 82 | 83 | BTN_FILE_SEL: 84 | SelToWAV; 85 | 86 | BTN_FILE_SONG: 87 | SongToWAV(AudioRenderSettings.Filename); 88 | 89 | BTN_SAM_SEL: 90 | if not IsEmptySample(Module.Samples[CurrentSample-1]) then 91 | begin 92 | ModalDialog.MessageDialog(ACTION_SAMPLEOVERWRITE, 93 | 'Overwrite Sample', 94 | 'Current sample is not empty. Proceed?', 95 | [btnYes, btnCancel], btnCancel, DialogCallback, 0); 96 | end 97 | else 98 | SelToSample; 99 | 100 | end 101 | else 102 | if ID = ACTION_SAMPLEOVERWRITE then 103 | SelToSample; 104 | end; 105 | 106 | // ========================================================================== 107 | // Shows the render settings dialog 108 | // ========================================================================== 109 | 110 | procedure Dialog_Render(ToSample: Boolean; Filename: String = ''); 111 | var 112 | Dlg: TCWEScreen; 113 | 114 | function AddButton(const sCaption: AnsiString; aID: Word; X, Y: Byte): TCWEButton; 115 | begin 116 | with ModalDialog do 117 | begin 118 | Result := TCWEButton.Create(Dlg, sCaption, 'b' + Trim(sCaption), 119 | Types.Rect(X, Y, X+Length(sCaption)+2, Y+1)); 120 | Result.ModalResult := Ord(btnOK); 121 | Result.Tag := aID; 122 | Result.OnChange := ButtonClickHandler; 123 | end; 124 | end; 125 | 126 | var 127 | Sect: AnsiString; 128 | List: TCWEConfigList; 129 | LH, W, H, Y: Byte; 130 | begin 131 | // ---------------------------------------------------------------------- 132 | // Create the dialog 133 | // ---------------------------------------------------------------------- 134 | 135 | // W = 48-11-2; 136 | if ToSample then 137 | begin 138 | Sect := 'Selection To Sample'; 139 | LH := 2; 140 | W := 24; 141 | end 142 | else 143 | begin 144 | Sect := 'Render To File'; 145 | LH := 3; 146 | W := 34; 147 | end; 148 | 149 | H := LH + 4; 150 | 151 | Dlg := ModalDialog.CreateDialog(ACTION_RENDER, Bounds( 152 | (Console.Width div 2) - (W div 2), 153 | (Console.Height div 2) - ((H+1) div 2), W, H+1), 154 | Sect); 155 | 156 | List := TCWEConfigList.Create(Dlg, '', 'Render Audio', 157 | Types.Rect(1, 2, W-1, 2+LH), True); 158 | 159 | if ToSample then 160 | List.ColumnWidth[1] := 3 161 | else 162 | List.ColumnWidth[1] := 10; 163 | 164 | with ModalDialog do 165 | begin 166 | CreateConfigManager; 167 | 168 | Sect := ''; 169 | 170 | // Normalize volume: B 171 | ConfigManager.AddBoolean(Sect, '', 172 | @AudioRenderSettings.Normalize, AudioRenderSettings.Normalize). 173 | SetInfo('Normalize volume', 0, 1, CN_YESNO); 174 | 175 | if ToSample then 176 | begin 177 | // Sect := 'Selection to sample'; 178 | 179 | // Destination note: X 180 | ConfigManager.AddByte(Sect, '', 181 | @AudioRenderSettings.DestNote, AudioRenderSettings.DestNote) 182 | .SetInfo('Destination note', 0, 35, NoteNames); 183 | 184 | // Boost highs: B 185 | ConfigManager.AddBoolean(Sect, '', 186 | @AudioRenderSettings.BoostHighs, AudioRenderSettings.BoostHighs). 187 | SetInfo('Boost highs', 0, 1, CN_YESNO); 188 | end 189 | else 190 | begin 191 | // Sect := 'Song to WAV'; 192 | 193 | // Loop: I times 194 | ConfigManager.AddByte(Sect, '', 195 | @AudioRenderSettings.LoopTimes, AudioRenderSettings.LoopTimes). 196 | SetInfo('Song looping', 0, 5, 197 | ['Don''t loop', 'Loop once', 'Loop 2x', 'Loop 3x', 'Loop 4x', 'Loop 5x']); 198 | 199 | // Enable fadeout: B 200 | ConfigManager.AddBoolean(Sect, '', 201 | @AudioRenderSettings.FadeOut, AudioRenderSettings.FadeOut). 202 | SetInfo('Fadeout at end', 0, 1, CN_YESNO); 203 | 204 | // Fadeout length: I seconds 205 | ConfigManager.AddByte(Sect, '', 206 | @AudioRenderSettings.FadeOutLength, AudioRenderSettings.FadeOutLength). 207 | SetInfo('Fadeout length (sec)', 1, 255, []); 208 | 209 | AudioRenderSettings.Filename := Filename; 210 | end; 211 | 212 | List.Init(ConfigManager); 213 | List.Scrollbar.Visible := False; 214 | List.Border.Pixel := True; 215 | List.Items.Delete(0); // 'general' heading 216 | 217 | Y := H - 1; 218 | 219 | if ToSample then 220 | begin 221 | AddButton(' Render ', BTN_SAM_SEL, 1, Y); 222 | AddButton('Cancel', BTN_CANCEL, W-9, Y).ModalResult := Ord(btnCancel); 223 | end 224 | else 225 | begin 226 | AddButton(' Song ', BTN_FILE_SONG, 1, Y); 227 | AddButton('Selection', BTN_FILE_SEL, 12, Y); 228 | AddButton('Cancel', BTN_CANCEL, W-9, Y).ModalResult := Ord(btnCancel); 229 | end; 230 | 231 | ButtonCallback := TAudioRender.DialogCallback; 232 | 233 | Dialog.ActiveControl := List; 234 | Show; 235 | end; 236 | end; 237 | 238 | class procedure TAudioRender.SelToSample; 239 | begin 240 | Module.RenderToSample(CurrentSample-1, PeriodTable[AudioRenderSettings.DestNote], 241 | PatternEditor.PrepareSelectionForRender, 242 | AudioRenderSettings.Normalize, AudioRenderSettings.BoostHighs); 243 | Editor.MessageText('Rendered selection to sample #' + IntToStr(CurrentSample)); 244 | Module.SetModified; 245 | end; 246 | 247 | class procedure TAudioRender.SelToWAV; 248 | begin 249 | if AudioRenderSettings.Filename <> '' then 250 | begin 251 | Module.PatternToWAV(AudioRenderSettings.Filename, 252 | PeriodTable[AudioRenderSettings.DestNote], 253 | PatternEditor.PrepareSelectionForRender, 254 | AudioRenderSettings.Normalize, 255 | AudioRenderSettings.BoostHighs); 256 | Editor.MessageText('Rendered selection to ' + 257 | ExtractFileName(AudioRenderSettings.Filename), True); 258 | end 259 | else 260 | Editor.MessageText('No filename given!'); 261 | end; 262 | 263 | class procedure TAudioRender.SongToWAV(Filename: String); 264 | var 265 | Fade: Byte; 266 | begin 267 | if Filename = '' then 268 | Filename := AudioRenderSettings.Filename; 269 | 270 | if AudioRenderSettings.FadeOut then 271 | Fade := AudioRenderSettings.FadeOutLength 272 | else 273 | Fade := 0; 274 | 275 | // Window.Progress.Start; 276 | Module.RenderToWAV(Filename, AudioRenderSettings.LoopTimes, Fade); 277 | // Window.Progress.Finish; 278 | end; 279 | 280 | class procedure TAudioRender.CancelMessage; 281 | begin 282 | Editor.MessageText('Canceled by user.'); 283 | end; 284 | 285 | initialization 286 | 287 | with AudioRenderSettings do 288 | begin 289 | LoopTimes := 1; 290 | FadeOutLength := 10; 291 | DestNote := 24; // C-3 292 | Normalize := True; 293 | BoostHighs := False; 294 | FadeOut := True; 295 | end; 296 | 297 | end. 298 | 299 | -------------------------------------------------------------------------------- /src/dialog/dialog.valuequery.pas: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // Ask user for a value: numeric with a slider, or select from a list 3 | // ========================================================================== 4 | unit Dialog.ValueQuery; 5 | 6 | interface 7 | 8 | uses 9 | Types, Classes, 10 | CWE.Core, 11 | CWE.Dialogs; 12 | 13 | procedure AskString(ID: Word; const Caption: AnsiString; const Text: AnsiString; 14 | NumbersOnly: Boolean; 15 | Callback: TButtonClickedEvent); 16 | procedure AskValue(ID: Word; const Caption: AnsiString; Min, Max, Pos: Integer; 17 | Callback: TButtonClickedEvent); 18 | procedure AskList(ID: Word; const Caption: AnsiString; Index: Word; 19 | const Items: array of AnsiString; 20 | Callback: TButtonClickedEvent); 21 | 22 | function GetAskedValue(var V: Integer): Boolean; 23 | 24 | 25 | implementation 26 | 27 | uses 28 | SysUtils, 29 | CWE.Widgets.Numeric, 30 | CWE.Widgets.Text; 31 | 32 | procedure AskString; 33 | const 34 | W = 21; 35 | H = 8; 36 | var 37 | Dlg: TCWEScreen; 38 | Edit: TCWEEdit; 39 | begin 40 | Dlg := ModalDialog.CreateDialog(ID, Bounds( 41 | (Console.Width div 2) - (W div 2), 42 | (Console.Height div 2) - (H div 2), W, H), 43 | Caption, False); 44 | 45 | Edit := TCWEEdit.Create(Dlg, '', 'Edit', 46 | Types.Rect(1, 3, W-1, 4), True); 47 | Edit.SetCaption(Text); 48 | Edit.SetBorder(True, False, True, True); 49 | if NumbersOnly then 50 | Edit.AllowedChars := AllowedNumberKeys; 51 | 52 | with ModalDialog do 53 | begin 54 | AddResultButton(btnOK, 'OK', 1, H-2, True); 55 | AddResultButton(btnCancel, 'Cancel', W-9, H-2); 56 | ButtonCallback := Callback; 57 | Dialog.ActivateControl(Edit); 58 | Show; 59 | end; 60 | end; 61 | 62 | procedure AskValue; 63 | const 64 | W = 34; 65 | H = 6; 66 | var 67 | Dlg: TCWEScreen; 68 | Slider: TCWESlider; 69 | Edit: TCWENumericEdit; 70 | L: Integer; 71 | begin 72 | L := Length(IntToStr(Max)); 73 | 74 | Dlg := ModalDialog.CreateDialog(ID, Bounds( 75 | (Console.Width div 2) - (W div 2), 76 | (Console.Height div 2) - (H div 2), W, H), 77 | Caption, False); 78 | 79 | Slider := TCWESlider.Create(Dlg, '', 'Slider', 80 | Types.Rect(1, 2, W-2-L, 3), True); 81 | Slider.Min := Min; 82 | Slider.Max := Max; 83 | Slider.Position := Pos; 84 | //Slider.CreateLabelControl; 85 | 86 | Edit := TCWENumericEdit.Create(Dlg, '', 'Edit', 87 | Types.Rect(W-1-L, 2, W-1, 3), True); 88 | Edit.Min := Min; 89 | Edit.Max := Max; 90 | Edit.Position := Pos; 91 | Edit.SetBorder(True, False, True, True); 92 | 93 | Slider.EditCtrl := Edit; 94 | Edit.SliderCtrl := Slider; 95 | 96 | with ModalDialog do 97 | begin 98 | AddResultButton(btnOK, 'OK', 1, H-2, True); 99 | AddResultButton(btnCancel, 'Cancel', W-9, H-2); 100 | ButtonCallback := Callback; 101 | Dialog.ActivateControl(Slider); 102 | Show; 103 | end; 104 | end; 105 | 106 | function GetAskedValue(var V: Integer): Boolean; 107 | var 108 | ctrl: TCWEControl; 109 | begin 110 | Result := False; 111 | if (ModalDialog = nil) or (ModalDialog.Dialog = nil) then Exit; 112 | 113 | ctrl := ModalDialog.Dialog.FindControl('Slider'); // ugh 114 | if ctrl <> nil then 115 | begin 116 | V := TCWESlider(ctrl).Position; 117 | Result := True; 118 | end; 119 | end; 120 | 121 | procedure AskList; 122 | const 123 | Margin = 2; 124 | var 125 | W, H, LW, LH: Integer; 126 | Dlg: TCWEScreen; 127 | List: TCWEList; 128 | begin 129 | LW := 10; 130 | for H := 0 to High(Items) do 131 | if Length(Items[H]) > LW then 132 | LW := Length(Items[H]); 133 | W := LW + (Margin*2); 134 | 135 | // size list to fit its contents and dialog to fit list 136 | LH := High(Items)+1; 137 | H := LH + 7; 138 | if H > (Console.Height - 2) then 139 | H := Console.Height - 2; 140 | 141 | Dlg := ModalDialog.CreateDialog(ID, Bounds( 142 | (Console.Width div 2) - (W div 2), 143 | (Console.Height div 2) - (H div 2), W, H), 144 | Caption); 145 | 146 | List := TCWEList.Create(Dlg, '', 'List', Bounds(Margin, 3, LW, LH), True); 147 | List.CanCloseDialog := True; 148 | List.Scrollbar.Visible := (List.Items.Count > List.Height); 149 | 150 | for LH := 0 to High(Items) do 151 | List.AddItem(Items[LH]); 152 | if Index in [0..List.Items.Count-1] then 153 | List.ItemIndex := Index; 154 | 155 | with ModalDialog do 156 | begin 157 | AddResultButton(btnOK, 'OK', Margin, H-2, True); 158 | AddResultButton(btnCancel, 'Cancel', W-6-Margin-2, H-2); 159 | ButtonCallback := Callback; 160 | Dialog.ActivateControl(List); 161 | Show; 162 | end; 163 | end; 164 | 165 | end. 166 | 167 | -------------------------------------------------------------------------------- /src/floatsampleeffects.pas: -------------------------------------------------------------------------------- 1 | unit FloatSampleEffects; 2 | 3 | interface 4 | 5 | uses 6 | Types, ProTracker.Util; 7 | 8 | const 9 | FILTERS_BASE_FREQ = 16574; 10 | 11 | 12 | function LimitSample(sample: Single): Single; inline; 13 | procedure Amplify(var buffer: TFloatArray; amp: Single; dB: Boolean); 14 | procedure Normalize(var buffer: TFloatArray; maxdB: Single = 0.0); 15 | procedure Equalize(var buffer: TFloatArray; 16 | lowfreq, highfreq, mixfreq: Word; 17 | BassGain, MidGain, HighGain: Single); 18 | procedure Filter(var buffer: TFloatArray; Cutoff: Word; LP: Boolean); 19 | 20 | 21 | implementation 22 | 23 | uses 24 | Math, 25 | ProTracker.Filters; 26 | 27 | 28 | function LimitSample(sample: Single): Single; inline; 29 | const 30 | MINMAX = 1.0; 31 | begin 32 | if sample <= -MINMAX then 33 | Result := -MINMAX 34 | else 35 | if sample >= MINMAX then 36 | Result := MINMAX 37 | else 38 | Result := sample; 39 | end; 40 | 41 | procedure Amplify(var buffer: TFloatArray; amp: Single; dB: Boolean); 42 | var 43 | i: Integer; 44 | begin 45 | if dB then 46 | amp := DecibelToLinear(amp); 47 | //Log('Amplify: amp=%f', [amp]); 48 | for i := 0 to Length(buffer)-1 do 49 | buffer[i] := LimitSample(buffer[i] * amp); 50 | end; 51 | 52 | procedure Normalize(var buffer: TFloatArray; maxdB: Single = 0.0); 53 | var 54 | i: Integer; 55 | sam, amp: Single; 56 | begin 57 | if (buffer = nil) or (Length(buffer) < 1) then Exit; 58 | 59 | amp := 0; 60 | for i := 0 to Length(buffer)-1 do 61 | begin 62 | sam := Abs(buffer[i]); 63 | if sam > amp then 64 | amp := sam; 65 | end; 66 | 67 | amp := 1.0 / amp; 68 | 69 | if (maxdB > 0.1) and (amp <= 1.0) then 70 | begin 71 | // sam := DecibelToLinear(maxdB); 72 | amp := maxdB; 73 | // Log('Normalize: amp = %f - %f', [amp, sam]); 74 | end; 75 | 76 | //if amp > 0.99 then 77 | begin 78 | //Log('Normalize: amp = %f', [amp]); 79 | Amplify(buffer, amp, False); 80 | end; 81 | end; 82 | 83 | // TODO fix this (seems broken on fpc linux at least) 84 | // public domain, adapted from 85 | // http://www.musicdsp.org/showArchiveComment.php?ArchiveID=236 86 | procedure Equalize(var buffer: TFloatArray; 87 | lowfreq, highfreq, mixfreq: Word; 88 | BassGain, MidGain, HighGain: Single); 89 | {const 90 | vsa = 1.0 / 4294967295.0; // Very small amount (Denormal Fix) 91 | var 92 | i: Integer; 93 | l, m, h, 94 | lf, f1p0, f1p1, f1p2, f1p3, 95 | hf, f2p0, f2p1, f2p2, f2p3, 96 | sdm1, sdm2, sdm3, 97 | lg, mg, hg: Single; 98 | sample: Single;} 99 | begin 100 | (* 101 | { (880, 5000, 44100, 1.5, 0.75, 1.0) -> 102 | eq.lg := 1.5; // Boost bass by 50% 103 | eq.mg := 0.75; // Cut mid by 25% 104 | eq.hg := 1.0; // Leave high band alone } 105 | 106 | lg := {1 +} (BassGain {/ 100}); 107 | mg := {1 +} (MidGain {/ 100}); 108 | hg := {1 +} (HighGain {/ 100}); 109 | 110 | // Calculate filter cutoff frequencies 111 | lf := 2 * Sin(PI * (lowfreq / mixfreq)); 112 | hf := 2 * Sin(PI * (highfreq / mixfreq)); 113 | 114 | f1p0 := 0; f1p1 := 0; f1p2 := 0; f1p3 := 0; 115 | f2p0 := 0; f2p1 := 0; f2p2 := 0; f2p3 := 0; 116 | sdm1 := 0; sdm2 := 0; sdm3 := 0; 117 | 118 | //Log('Equalize %d', [Length(buffer)]); 119 | 120 | for i := 0 to Length(buffer)-1 do 121 | begin 122 | sample := buffer[i]; 123 | 124 | // Filter #1 (lowpass) 125 | f1p0 := f1p0 + (lf * (sample - f1p0)) + vsa; 126 | f1p1 := f1p1 + (lf * (f1p0 - f1p1)); 127 | f1p2 := f1p2 + (lf * (f1p1 - f1p2)); 128 | f1p3 := f1p3 + (lf * (f1p2 - f1p3)); 129 | 130 | l := f1p3; 131 | 132 | // Filter #2 (highpass) 133 | f2p0 := f2p0 + (hf * (sample - f2p0)) + vsa; 134 | f2p1 := f2p1 + (hf * (f2p0 - f2p1)); 135 | f2p2 := f2p2 + (hf * (f2p1 - f2p2)); 136 | f2p3 := f2p3 + (hf * (f2p2 - f2p3)); 137 | 138 | h := sdm3 - f2p3; 139 | 140 | // Calculate midrange (signal - (low + high)) 141 | m := sdm3 - (h + l); 142 | 143 | // Scale, Combine and store 144 | l := l * lg; 145 | m := m * mg; 146 | h := h * hg; 147 | 148 | // Shuffle history buffer 149 | sdm3 := sdm2; 150 | sdm2 := sdm1; 151 | sdm1 := sample; 152 | 153 | // Return result 154 | buffer[i] := LimitSample(l + m + h); 155 | end; 156 | *) 157 | end; 158 | 159 | procedure Filter(var buffer: TFloatArray; Cutoff: Word; LP: Boolean); 160 | var 161 | i: Integer; 162 | _in, _out: array [0..1] of Single; 163 | filter: TLossyIntegrator; 164 | 165 | procedure DoFilter; 166 | begin 167 | _in[0] := buffer[i]; 168 | if LP then 169 | lossyIntegrator(@filter, @_in, @_out) 170 | else 171 | lossyIntegratorHighPass(@filter, @_in, @_out); 172 | buffer[i] := LimitSample(_out[0]); 173 | end; 174 | 175 | begin 176 | CutOff := Max(1, Min(CutOff, FILTERS_BASE_FREQ div 2)); 177 | 178 | filter.coeff[0] := Tan(M_PI_F * CutOff / FILTERS_BASE_FREQ); 179 | filter.coeff[1] := 1.0 / (1.0 + filter.coeff[0]); 180 | 181 | filter.buffer[0] := 0.0; 182 | for i := 0 to Length(buffer)-1 do 183 | DoFilter; 184 | 185 | filter.buffer[0] := 0.0; 186 | for i := Length(buffer)-1 downto 0 do 187 | DoFilter; 188 | end; 189 | 190 | end. 191 | -------------------------------------------------------------------------------- /src/include/bass/makefile: -------------------------------------------------------------------------------- 1 | EXAMPLES = 3dtest basstest contest custloop devlist dsptest fxtest livespec modtest multi netradio plugins rectest speakers spectrum synth writewav 2 | 3 | .PHONY: all clean $(EXAMPLES) 4 | 5 | all: $(EXAMPLES) 6 | 7 | clean: 8 | @$(foreach x,$(EXAMPLES),$(MAKE) -C $(x) clean;) 9 | 10 | $(EXAMPLES): 11 | $(MAKE) -C $@ 12 | -------------------------------------------------------------------------------- /src/include/bass/makefile.in: -------------------------------------------------------------------------------- 1 | BASSPATH = .. 2 | # get absolute path 3 | BASSPATH := $(shell cd $(BASSPATH); pwd) 4 | 5 | FLAGS = -Os -I$(BASSPATH) -L$(BASSPATH) -L$(BASSPATH)/x64 -lbass -lm -Wl,--no-warn-search-mismatch,-rpath,$(BASSPATH):$(BASSPATH)/x64 6 | FLAGS += $(foreach pkg,$(PACKAGES),`pkg-config $(pkg) --cflags --libs`) 7 | ifneq (,$(findstring libglade,$(PACKAGES))) 8 | FLAGS += -export-dynamic 9 | # path to glade file 10 | FLAGS += -D'GLADE_PATH="$(shell pwd)/"' 11 | endif 12 | 13 | .PHONY: all clean 14 | 15 | %: %.c 16 | $(CC) $*.c $(FLAGS) -o $@ 17 | -------------------------------------------------------------------------------- /src/include/buildinfo.pas: -------------------------------------------------------------------------------- 1 | unit BuildInfo; 2 | 3 | interface 4 | 5 | const 6 | CompileDate = {$I %DATE%}; 7 | CompileTime = {$I %TIME%}; 8 | 9 | var 10 | Build: record 11 | CompileDate: String; 12 | CompileTime: String; 13 | end; 14 | 15 | implementation 16 | 17 | uses 18 | SysUtils, StrUtils; 19 | 20 | initialization 21 | 22 | Build.CompileDate := Trim(ReplaceStr(CompileDate, '/', '-')); 23 | Build.CompileTime := Trim(CompileTime); 24 | 25 | end. 26 | 27 | -------------------------------------------------------------------------------- /src/include/fileutils.pas: -------------------------------------------------------------------------------- 1 | // ====================================================================================== 2 | // Utility functions for file handling, hukka 2015 3 | // ====================================================================================== 4 | 5 | unit FileUtils; 6 | 7 | interface 8 | 9 | uses 10 | Types, Classes, SysUtils; //, IOUtils; 11 | 12 | const 13 | IllegalFilenameChars = '<>:"/\|?*'; 14 | 15 | function IsFile(const Filename: String): Boolean; 16 | function ValidateFilename(const Filename: String): String; 17 | function GetFileInfo(const Filename: String; out FileSize: Cardinal; 18 | out DateModified: TDateTime): Boolean; 19 | function GetFileSize(const Filename: String): Cardinal; inline; 20 | function GetFileModifiedDate(const Filename: String): TDateTime; 21 | function CreateIni(const Filename, Name: String): Boolean; 22 | function DeleteToBin(const Filename: String): Boolean; overload; 23 | function DeleteToBin(const Filenames: TStrings): Boolean; overload; 24 | function GetParentDir(const Path: String): String; 25 | function MoveDirectory(const fromDir, toDir: String): Boolean; 26 | function CopyFileSHFileOperation(const srcFile, destFile: String): Boolean; 27 | function IsSameFolder(const OldPath, NewPath: String): Boolean; 28 | function IsSubFolder(const OldPath, NewPath: String): Boolean; 29 | procedure FileSearch(const PathName, Extensions: String; var lstFiles: TStringList); 30 | 31 | 32 | implementation 33 | 34 | {$IFDEF WINDOWS} 35 | uses 36 | //DSiWin32, 37 | ProTracker.Util, 38 | ShellAPI; 39 | {$ENDIF} 40 | 41 | function GetParentDir(const Path: String): String; inline; 42 | begin 43 | Result := ExpandFileName(Path + '..'); 44 | end; 45 | 46 | function IsSameFolder(const OldPath, NewPath: String): Boolean; inline; 47 | begin 48 | Result := 49 | LowerCase(IncludeTrailingPathDelimiter(OldPath)) = 50 | LowerCase(IncludeTrailingPathDelimiter(NewPath)); 51 | end; 52 | 53 | function IsSubFolder(const OldPath, NewPath: String): Boolean; inline; 54 | begin 55 | Result := (Pos( 56 | LowerCase(IncludeTrailingPathDelimiter(OldPath)), 57 | LowerCase(IncludeTrailingPathDelimiter(NewPath))) = 1); 58 | end; 59 | 60 | // Determines whether a path is a file or directory 61 | // 62 | function IsFile(const Filename: String): Boolean; inline; 63 | var 64 | Attrs: Integer; 65 | begin 66 | Attrs := FileGetAttr(Filename); 67 | Result := (Attrs and faDirectory) <> 0; 68 | end; 69 | 70 | function ValidateFilename(const Filename: String): String; 71 | var 72 | X: Integer; 73 | begin 74 | Result := Filename; 75 | for X := 1 to Length(Filename) do 76 | if Pos(Filename[X], IllegalFilenameChars) > 0 then 77 | Result[X] := ' '; 78 | end; 79 | 80 | function CopyFileSHFileOperation(const srcFile, destFile: String): Boolean; 81 | {$IFDEF WINDOWS} 82 | var 83 | shFOS: TShFileOpStruct; 84 | begin 85 | ZeroMemory(@shFOS, SizeOf(TShFileOpStruct)); 86 | 87 | shFOS.Wnd := 0; //Application.MainForm.Handle; !!! 88 | shFOS.wFunc := FO_COPY; 89 | shFOS.pFrom := PChar(srcFile + #0); 90 | shFOS.pTo := PChar(destFile + #0); 91 | 92 | //Do not ask the user to confirm the creation of a 93 | //new directory if the operation requires one to be created. 94 | shFOS.fFlags := FOF_NOCONFIRMATION {or FOF_NOCONFIRMMKDIR}; 95 | 96 | Result := SHFileOperation(shFOS) = 0; 97 | end; 98 | {$ELSE} 99 | begin 100 | Result := False; 101 | end; 102 | {$ENDIF} 103 | 104 | function MoveDirectory(const fromDir, toDir: String): Boolean; 105 | {$IFDEF WINDOWS} 106 | var 107 | fos: TSHFileOpStruct; 108 | begin 109 | ZeroMemory(@fos, SizeOf(fos)); 110 | with fos do 111 | begin 112 | wFunc := FO_MOVE; 113 | fFlags := FOF_FILESONLY; 114 | pFrom := PChar(fromDir + #0); 115 | pTo := PChar(toDir) 116 | end; 117 | Result := (0 = ShFileOperation(fos)); 118 | end; 119 | {$ELSE} 120 | begin 121 | Result := False; 122 | end; 123 | {$ENDIF} 124 | 125 | // Gets file size and date 126 | // 127 | function GetFileInfo(const Filename: String; out FileSize: Cardinal; 128 | out DateModified: TDateTime): Boolean; 129 | begin 130 | FileSize := GetFileSize(Filename); 131 | DateModified := GetFileModifiedDate(Filename); 132 | end; 133 | 134 | function GetFileSize(const Filename: String): Cardinal; inline; 135 | var 136 | F: file of Byte; 137 | begin 138 | Assign (F, Filename); 139 | Reset(F); 140 | Result := FileSize(F); 141 | Close(F); 142 | end; 143 | 144 | function GetFileModifiedDate(const Filename: String): TDateTime; inline; 145 | begin 146 | Result := FileDateToDateTime(FileAge(Filename)); 147 | end; 148 | 149 | {var 150 | info: TWin32FileAttributeData; 151 | begin 152 | if GetFileAttributesEx(PWideChar(Filename), GetFileExInfoStandard, @info) then 153 | Result := DSiFileTimeToDateTime(info.ftLastWriteTime); 154 | end;} 155 | 156 | // If an inifile doesn't exist, creates it from internal resource 157 | // 158 | function CreateIni(const Filename, Name: String): Boolean; 159 | var 160 | RS: TResourceStream; 161 | Sl: TStrings; 162 | Path: String; 163 | begin 164 | if not FileExists(Filename) then 165 | begin 166 | Path := ExtractFilePath(Filename); 167 | if not DirectoryExists(Path) then 168 | ForceDirectories(Path); 169 | RS := TResourceStream.Create(hInstance, Name, RT_RCDATA); 170 | Sl := TStringList.Create; 171 | Sl.LoadFromStream(RS); 172 | Sl.SaveToFile(Filename); 173 | Sl.Free; 174 | RS.Free; 175 | Result := False; 176 | end 177 | else 178 | Result := True; 179 | end; 180 | 181 | // Deletes files to Recycle Bin. 182 | // "Filenames" is a list of files and directories you want to delete. 183 | // After executing, you have to check which files were really deleted 184 | // because the user can cancel the deleting procedure. 185 | function DeleteToBin(const Filenames: TStrings): Boolean; 186 | {$IFDEF WINDOWS} 187 | var 188 | iFile: Integer; 189 | sFilenames: String; 190 | Op: TSHFileOpStruct; 191 | begin 192 | if (Filenames.Count < 1) then Exit(False); 193 | 194 | // Create a zero delimited string with two trailing zeros 195 | sFilenames := ''; 196 | for iFile := 0 to Filenames.Count-1 do 197 | sFilenames := sFilenames + 198 | ExcludeTrailingPathDelimiter(Filenames.Strings[iFile]) + #0; 199 | 200 | FillChar(Op, SizeOf(Op), 0); 201 | 202 | //Op.Wnd := Seymour.WindowHandle; // not used, no dialog displayed 203 | Op.wFunc := FO_DELETE; 204 | Op.pFrom := PChar(sFilenames + #0); 205 | Op.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT; 206 | 207 | Result := (SHFileOperation(Op) = 0); 208 | end; 209 | {$ELSE} 210 | var 211 | S: String; 212 | begin 213 | for S in Filenames do 214 | DeleteFile(S); 215 | Result := True; 216 | end; 217 | {$ENDIF} 218 | 219 | function DeleteToBin(const Filename: String): Boolean; 220 | {$IFDEF WINDOWS} 221 | var 222 | Op: TSHFileOpStruct; 223 | begin 224 | FillChar(Op, SizeOf(Op), 0); 225 | 226 | //Op.Wnd := Seymour.WindowHandle; 227 | Op.wFunc := FO_DELETE; 228 | Op.pFrom := PChar(Filename + #0); 229 | Op.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT; 230 | 231 | Result := (ShFileOperation(Op) = 0); 232 | end; 233 | {$ELSE} 234 | begin 235 | DeleteFile(Filename); 236 | Result := True; 237 | end; 238 | {$ENDIF} 239 | 240 | procedure FileSearch(const PathName, Extensions: String; var lstFiles: TStringList); 241 | const 242 | FileMask = '*.*'; 243 | var 244 | Rec: TSearchRec; 245 | Path: String; 246 | begin 247 | if not Assigned(lstFiles) then 248 | lstFiles := TStringList.Create; 249 | 250 | Path := IncludeTrailingPathDelimiter(PathName); 251 | if FindFirst(Path + FileMask, faAnyFile - faDirectory, Rec) = 0 then 252 | try 253 | repeat 254 | if AnsiPos(ExtractFileExt(Rec.name), Extensions) > 0 then 255 | lstFiles.Add(Path + Rec.name); 256 | until FindNext(Rec) <> 0; 257 | finally 258 | SysUtils.FindClose(Rec); 259 | end; 260 | if FindFirst(Path + '*.*', faDirectory, Rec) = 0 then 261 | try 262 | repeat 263 | if ((Rec.Attr and faDirectory) <> 0) and (Rec.name <> '.') and (Rec.name <> '..') then 264 | FileSearch(Path + Rec.name, Extensions, lstFiles); 265 | until FindNext(Rec) <> 0; 266 | finally 267 | FindClose(Rec); 268 | end; 269 | end; 270 | 271 | end. 272 | -------------------------------------------------------------------------------- /src/include/fpwavformat.pas: -------------------------------------------------------------------------------- 1 | {*****************************************************************************} 2 | { 3 | This file is part of the Free Pascal's "Free Components Library". 4 | Copyright (c) 2014 by Mazen NEIFER of the Free Pascal development team 5 | and was adapted from wavopenal.pas copyright (c) 2010 Dmitry Boyarintsev. 6 | 7 | RIFF/WAVE sound file basic types and constants. 8 | 9 | See the file COPYING.FPC, included in this distribution, 10 | for details about the copyright. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 | } 16 | unit fpwavformat; 17 | 18 | {$mode objfpc}{$H+} 19 | 20 | interface 21 | 22 | const 23 | AUDIO_CHUNK_ID_RIFF = 'RIFF'; 24 | AUDIO_CHUNK_ID_WAVE = 'WAVE'; 25 | AUDIO_CHUNK_ID_fmt = 'fmt '; 26 | AUDIO_CHUNK_ID_data = 'data'; 27 | AUDIO_CHUNK_ID_smpl = 'smpl'; 28 | AUDIO_FORMAT_PCM = 1; 29 | 30 | type 31 | TChunkID = array [0..3] of Char; 32 | TChunkHeader = packed record 33 | ID: TChunkID; 34 | Size: UInt32; 35 | end; 36 | TRiffHeader = packed record 37 | ChunkHeader: TChunkHeader; 38 | Format: TChunkID; 39 | end; 40 | TWaveFormat = packed record 41 | ChunkHeader: TChunkHeader; 42 | Format: UInt16; 43 | Channels: UInt16; 44 | SampleRate: UInt32; 45 | ByteRate: UInt32; 46 | BlockAlign: UInt16; 47 | BitsPerSample: UInt16; 48 | end; 49 | 50 | implementation 51 | 52 | end. 53 | 54 | -------------------------------------------------------------------------------- /src/include/fpwavreader.pas: -------------------------------------------------------------------------------- 1 | {*****************************************************************************} 2 | { 3 | This file is part of the Free Pascal's "Free Components Library". 4 | Copyright (c) 2014 by Mazen NEIFER of the Free Pascal development team 5 | and was adapted from wavopenal.pas copyright (c) 2010 Dmitry Boyarintsev. 6 | 7 | RIFF/WAVE sound file reader implementation. 8 | 9 | See the file COPYING.FPC, included in this distribution, 10 | for details about the copyright. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 | } 16 | unit fpwavreader; 17 | 18 | {$mode objfpc}{$H+} 19 | 20 | interface 21 | 22 | uses 23 | fpWavFormat, Classes; 24 | 25 | type 26 | TSmplLoop = record 27 | CuePointID, 28 | LoopType, 29 | LoopStart, 30 | LoopEnd, 31 | Fraction, 32 | PlayCount: Cardinal; 33 | end; 34 | 35 | TSmplChunk = record 36 | MainChunk: record 37 | Manufacturer, 38 | Product, 39 | SamplePeriod, 40 | MIDIUnityNote, 41 | MIDIPitchFraction, 42 | SMPTEFormat, 43 | SMPTEOffset, 44 | NumSampleLoops, 45 | SamplerData: Cardinal; 46 | end; 47 | Exists: Boolean; 48 | LoopInfo: TSmplLoop; // support only one loop for now 49 | end; 50 | 51 | { TWavReader } 52 | TWavReader = class(TObject) 53 | private 54 | DataChunk: TChunkHeader; 55 | ChunkPos: Int64; 56 | EoF: Boolean; 57 | FStream: TStream; 58 | FFileName: String; 59 | public 60 | fmt: TWaveFormat; 61 | smpl: TSmplChunk; 62 | dataSize: Cardinal; 63 | 64 | destructor Destroy; override; 65 | function LoadFromFile(const FileName: String): Boolean; 66 | function LoadFromStream(AStream: TStream): Boolean; 67 | function ReadBuf(var Buffer; BufferSize: Integer): Integer; 68 | end; 69 | 70 | implementation 71 | 72 | uses 73 | SysUtils; 74 | 75 | procedure LEtoN(var fmt: TWaveFormat); overload; 76 | begin 77 | with fmt, ChunkHeader do 78 | begin 79 | Size := LEtoN(Size); 80 | Format := LEtoN(Format); 81 | Channels := LEtoN(Channels); 82 | SampleRate := LEtoN(SampleRate); 83 | ByteRate := LEtoN(ByteRate); 84 | BlockAlign := LEtoN(BlockAlign); 85 | BitsPerSample := LEtoN(BitsPerSample); 86 | end; 87 | end; 88 | 89 | { TWavReader } 90 | 91 | destructor TWavReader.Destroy; 92 | begin 93 | if (FFileName <> '') and Assigned(FStream) then 94 | FStream.Free; 95 | inherited Destroy; 96 | end; 97 | 98 | function TWavReader.LoadFromFile(const FileName: String): Boolean; 99 | begin 100 | if (FFileName <> '') and Assigned(FStream) then 101 | FStream.Free; 102 | 103 | FStream := TFileStream.Create(FileName, fmOpenRead + fmShareDenyWrite); 104 | if Assigned(FStream) then 105 | begin 106 | Result := LoadFromStream(FStream); 107 | FFileName := FileName; 108 | end 109 | else 110 | Result := False; 111 | end; 112 | 113 | function TWavReader.LoadFromStream(AStream: TStream): Boolean; 114 | var 115 | RIFF: TRiffHeader; 116 | datahdr: TChunkHeader; 117 | begin 118 | FStream := AStream; 119 | FFileName := ''; 120 | Result := FStream.Read(RIFF, SizeOf(RIFF)) = SizeOf(RIFF); 121 | RIFF.ChunkHeader.Size := LEtoN(RIFF.ChunkHeader.Size); 122 | Result := Result and 123 | (RIFF.ChunkHeader.ID = AUDIO_CHUNK_ID_RIFF) and 124 | (RIFF.Format = AUDIO_CHUNK_ID_WAVE); 125 | Result := Result and (FStream.Read(fmt, SizeOf(fmt)) = SizeOf(fmt)); 126 | LEtoN(fmt); 127 | Result := Result and (fmt.ChunkHeader.ID = AUDIO_CHUNK_ID_fmt); 128 | if Result and (fmt.Format <> 1) then 129 | begin 130 | //writeln('WAVE file is using compression. Sorry, cannot load. Please provide uncompressed .wav'); 131 | Exit(False); 132 | end; 133 | FStream.Read(datahdr, SizeOf(datahdr)); 134 | dataSize := datahdr.Size; 135 | FStream.Seek(-SizeOf(datahdr), soFromCurrent); 136 | end; 137 | 138 | function Min(a, b: Integer): Integer; 139 | begin 140 | if a < b then 141 | Result := a 142 | else 143 | Result := b; 144 | end; 145 | 146 | function TWavReader.ReadBuf(var Buffer; BufferSize: Integer): Integer; 147 | var 148 | sz: Integer; 149 | p: TByteArray absolute Buffer; 150 | i: Integer; 151 | smplhdr: TChunkHeader; 152 | begin 153 | i := 0; 154 | while (not EoF) and (i < bufferSize) do 155 | begin 156 | if ChunkPos >= DataChunk.Size then 157 | begin 158 | sz := FStream.Read(DataChunk, SizeOf(DataChunk)); 159 | EoF := sz < SizeOf(DataChunk); 160 | if not EoF then 161 | begin 162 | DataChunk.Size := LEtoN(DataChunk.Size); 163 | if DataChunk.Id <> AUDIO_CHUNK_ID_data then 164 | ChunkPos := DataChunk.Size 165 | else 166 | ChunkPos := 0; 167 | end; 168 | end 169 | else 170 | begin 171 | sz := Min(BufferSize, DataChunk.Size - ChunkPos); 172 | sz := FStream.Read(p[i], sz); 173 | EoF := sz <= 0; 174 | Inc(ChunkPos, sz); 175 | Inc(i, sz); 176 | end; 177 | end; 178 | Result := i; 179 | 180 | // read smpl chunk if it exists 181 | smpl.Exists := False; 182 | if (BufferSize = dataSize) then 183 | begin 184 | i := FStream.Size - FStream.Position; 185 | if i >= 10 then 186 | begin 187 | FStream.Read(smplhdr, SizeOf(smplhdr)); 188 | if (smplhdr.ID = AUDIO_CHUNK_ID_smpl) and 189 | (smplhdr.Size >= SizeOf(smpl.MainChunk)) then 190 | begin 191 | FStream.Read(smpl.MainChunk, SizeOf(smpl.MainChunk)); 192 | smpl.Exists:= True; 193 | if smpl.MainChunk.NumSampleLoops > 0 then 194 | FStream.Read(smpl.LoopInfo, SizeOf(smpl.LoopInfo)); 195 | end; 196 | end; 197 | end; 198 | end; 199 | 200 | end. 201 | 202 | -------------------------------------------------------------------------------- /src/include/fpwavwriter.pas: -------------------------------------------------------------------------------- 1 | {*****************************************************************************} 2 | { 3 | This file is part of the Free Pascal's "Free Components Library". 4 | Copyright (c) 2014 by Mazen NEIFER of the Free Pascal development team 5 | and was adapted from wavopenal.pas copyright (c) 2010 Dmitry Boyarintsev. 6 | 7 | RIFF/WAVE sound file writer implementation. 8 | 9 | See the file COPYING.FPC, included in this distribution, 10 | for details about the copyright. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 | } 16 | unit fpwavwriter; 17 | 18 | {$mode objfpc}{$H+} 19 | 20 | interface 21 | 22 | uses 23 | fpWavFormat, 24 | Classes; 25 | 26 | type 27 | { TWaveReader } 28 | 29 | { TWavWriter } 30 | 31 | TWavWriter = class(TObject) 32 | private 33 | fStream: TStream; 34 | FFreeStreamOnClose: Boolean; 35 | public 36 | fmt: TWaveFormat; 37 | destructor Destroy; override; 38 | function CloseAudioFile: Boolean; 39 | function FlushHeader: Boolean; 40 | function StoreToFile(const FileName: string): Boolean; 41 | function StoreToStream(AStream: TStream): Boolean; 42 | function WriteBuf(var Buffer; BufferSize: Integer): Integer; 43 | end; 44 | 45 | implementation 46 | 47 | uses 48 | SysUtils; 49 | 50 | procedure NtoLE(var fmt: TWaveFormat); overload; 51 | begin 52 | with fmt, ChunkHeader do begin 53 | Size := NtoLE(Size); 54 | Format := NtoLE(Format); 55 | Channels := NtoLE(Channels); 56 | SampleRate := NtoLE(SampleRate); 57 | ByteRate := NtoLE(ByteRate); 58 | BlockAlign := NtoLE(BlockAlign); 59 | BitsPerSample := NtoLE(BitsPerSample); 60 | end; 61 | end; 62 | 63 | { TWaveWriter } 64 | 65 | destructor TWavWriter.Destroy; 66 | begin 67 | CloseAudioFile; 68 | inherited Destroy; 69 | end; 70 | 71 | function TWavWriter.CloseAudioFile: Boolean; 72 | begin 73 | Result := True; 74 | if not Assigned(fStream) then begin 75 | Exit(True); 76 | end; 77 | FlushHeader; 78 | if FFreeStreamOnClose then begin 79 | fStream.Free; 80 | end; 81 | end; 82 | 83 | function TWavWriter.FlushHeader: Boolean; 84 | var 85 | riff: TRiffHeader; 86 | fmtLE: TWaveFormat; 87 | DataChunk: TChunkHeader; 88 | Pos, Sz: Int64; 89 | begin 90 | Pos := fStream.Position; 91 | with riff, ChunkHeader do begin 92 | ID := AUDIO_CHUNK_ID_RIFF; 93 | Sz := Pos - SizeOf(ChunkHeader); 94 | if Sz < 0 then Sz := 0; 95 | Size := NtoLE(Sz); 96 | Format := AUDIO_CHUNK_ID_WAVE; 97 | end; 98 | fmtLE := fmt; 99 | NtoLE(fmtLE); 100 | with fStream do begin 101 | Position := 0; 102 | Result := Write(riff, SizeOf(riff)) = SizeOf(riff); 103 | Result := Write(fmtLE, sizeof(fmtLE)) = SizeOf(fmtLE); 104 | end; 105 | with DataChunk do begin 106 | Id := AUDIO_CHUNK_ID_data; 107 | Sz := Pos - SizeOf(DataChunk) - fStream.Position; 108 | if Sz < 0 then Sz := 0; 109 | Size := Sz; 110 | end; 111 | with fStream do begin 112 | Result := Write(DataChunk, SizeOf(DataChunk)) = SizeOf(DataChunk); 113 | end; 114 | end; 115 | 116 | function TWavWriter.StoreToFile(const FileName: string): Boolean; 117 | begin 118 | CloseAudioFile; 119 | fStream := TFileStream.Create(FileName, fmCreate + fmOpenWrite); 120 | if Assigned(fStream) then begin 121 | Result := StoreToStream(fStream); 122 | FFreeStreamOnClose := True; 123 | end else begin 124 | Result := False; 125 | end; 126 | end; 127 | 128 | function TWavWriter.StoreToStream(AStream:TStream): Boolean; 129 | begin 130 | fStream := AStream; 131 | FFreeStreamOnClose := False; 132 | with fmt, ChunkHeader do 133 | begin 134 | ID := AUDIO_CHUNK_ID_fmt; 135 | Size := SizeOf(fmt) - SizeOf(ChunkHeader); 136 | Format := AUDIO_FORMAT_PCM; 137 | end; 138 | Result := FlushHeader; 139 | end; 140 | 141 | function TWavWriter.WriteBuf(var Buffer; BufferSize: Integer): Integer; 142 | var 143 | sz: Integer; 144 | begin 145 | Result := 0; 146 | with fStream do 147 | begin 148 | sz := Write(Buffer, BufferSize); 149 | if sz < 0 then Exit; 150 | Inc(Result, sz); 151 | end; 152 | end; 153 | 154 | end. 155 | 156 | -------------------------------------------------------------------------------- /src/include/pcx.pas: -------------------------------------------------------------------------------- 1 | unit PCX; 2 | 3 | interface 4 | 5 | uses 6 | SysUtils, Classes, Graphics32; 7 | 8 | type 9 | TPCXImage = class 10 | public 11 | BitsPerPixel, 12 | Width, 13 | Height: Cardinal; 14 | Palette: TPalette32; 15 | Pixels: packed array of packed array of Byte; 16 | 17 | constructor Create(W, H: Integer); overload; 18 | 19 | function LoadFromFile(const Filename: String): Boolean; 20 | 21 | procedure Clear(val: Byte); 22 | procedure DrawTo(var buffer: TBitmap32); 23 | end; 24 | 25 | 26 | implementation 27 | 28 | uses 29 | FileStreamEx; 30 | 31 | 32 | constructor TPCXImage.Create(W, H: Integer); 33 | begin 34 | inherited Create; 35 | Width := W; 36 | Height := H; 37 | SetLength(Pixels, W, H); 38 | Clear(0); 39 | end; 40 | 41 | function TPCXImage.LoadFromFile(const Filename: String): Boolean; 42 | var 43 | Bf: array of array of Byte; 44 | fsize: Int64; 45 | b: Byte; 46 | tavu1, tavu2, x, y, 47 | position, bytesperline: Integer; 48 | PCXFile: TFileStreamEx; 49 | label 50 | Done; 51 | begin 52 | Result := False; 53 | if not FileExists(Filename) then Exit; 54 | 55 | PCXFile := TFileStreamEx.Create(Filename, fmOpenRead, fmShareDenyNone); 56 | 57 | fsize := PCXFile.Size; 58 | 59 | if PCXFile.ReadByte <> $A then goto Done; 60 | PCXFile.SeekTo(3); 61 | BitsPerPixel := PCXFile.ReadByte; 62 | 63 | PCXFile.SeekTo(8); 64 | Width := PCXFile.ReadWord + 1; 65 | Height := PCXFile.ReadWord + 1; 66 | 67 | SetLength(Bf, Width, Height); 68 | SetLength(Pixels, Width, Height); 69 | 70 | PCXFile.SeekTo($42); 71 | bytesperline := PCXFile.ReadWord; 72 | //bytestoread := Height * bytesperline; 73 | //linepadding := ((bytesperline * (8 div BitsPerPixel)) - Width) div 8; 74 | 75 | PCXFile.SeekTo(128); 76 | position := PCXFile.Position; 77 | 78 | for y := 0 to Height-1 do 79 | begin 80 | x := 0; 81 | while x < bytesperline do 82 | begin 83 | tavu1 := PCXFile.ReadByte; 84 | Inc(position); 85 | if position > fsize then Break; 86 | if tavu1 > 192 then 87 | begin 88 | tavu2 := PCXFile.ReadByte; 89 | Inc(position); 90 | while tavu1 > 192 do 91 | begin 92 | Bf[x, y] := tavu2; 93 | Inc(x); 94 | Dec(tavu1); 95 | if x > bytesperline then Break; 96 | end; 97 | end 98 | else 99 | begin 100 | Bf[x, y] := tavu1; 101 | Inc(x); 102 | end; 103 | end; 104 | {if linepadding > 0 then 105 | PCXFile.Skip(linepadding);} 106 | end; 107 | 108 | // read 16-color palette 109 | PCXFile.SeekTo($10); 110 | for Y := 0 to 15 do 111 | Palette[Y] := Color32( 112 | PCXFile.ReadByte, PCXFile.ReadByte, PCXFile.ReadByte); 113 | 114 | Result := True; 115 | 116 | case BitsPerPixel of 117 | 1: begin 118 | // get pixels 119 | for tavu1 := 0 to Height-1 do 120 | for tavu2 := 0 to bytesperline-1 do 121 | begin 122 | b := Bf[tavu2, tavu1]; 123 | 124 | for y := 0 to 7 do 125 | begin 126 | x := tavu2 * 8 + y; 127 | if x >= Width then Break; 128 | 129 | if (b and 128) <> 0 then 130 | Pixels[x,tavu1] := 1 131 | else 132 | Pixels[x,tavu1] := 0; 133 | 134 | b := Byte(b shl 1); 135 | Inc(x); 136 | end; 137 | end; 138 | end; 139 | 140 | 4: begin 141 | bytesperline := Width div 2; 142 | // get pixels 143 | for tavu1 := 0 to Height-1 do 144 | for tavu2 := 0 to bytesperline-1 do 145 | begin 146 | b := Bf[tavu2, tavu1]; 147 | Pixels[tavu2*2+0,tavu1] := b shr 4; 148 | Pixels[tavu2*2+1,tavu1] := b and 15; 149 | end; 150 | end; 151 | 152 | 8: begin 153 | // get pixels 154 | for tavu1 := 0 to Height-1 do 155 | for tavu2 := 0 to Width-1 do 156 | Pixels[tavu2,tavu1] := Bf[tavu2, tavu1]; 157 | 158 | // read palette 159 | if (fsize > 768) then 160 | begin 161 | PCXFile.SeekTo(fsize - 768); 162 | for Y := 0 to 255 do 163 | Palette[Y] := Color32( 164 | PCXFile.ReadByte, PCXFile.ReadByte, PCXFile.ReadByte); 165 | end; 166 | end; 167 | else 168 | Result := False; 169 | end; 170 | 171 | Done: 172 | PCXFile.Free; 173 | end; 174 | 175 | procedure TPCXImage.Clear(val: Byte); 176 | var 177 | X, Y: Integer; 178 | begin 179 | for Y := 0 to Height-1 do 180 | for X := 0 to Width-1 do 181 | Pixels[X, Y] := val; 182 | end; 183 | 184 | procedure TPCXImage.DrawTo(var buffer: TBitmap32); 185 | var 186 | X, Y: Integer; 187 | begin 188 | for Y := 0 to Height-1 do 189 | for X := 0 to Width-1 do 190 | buffer.SetPixel(X, Y, Palette[Pixels[X, Y]]); 191 | end; 192 | 193 | end. 194 | 195 | -------------------------------------------------------------------------------- /src/include/sdl2/README.md: -------------------------------------------------------------------------------- 1 | Pascal-SDL-2-Headers 2 | ==================== 3 | 4 | This are the Pascal SDL 2 Headers. -------------------------------------------------------------------------------- /src/include/sdl2/sdl.inc: -------------------------------------------------------------------------------- 1 | //from "sdl.h" 2 | 3 | const 4 | 5 | SDL_INIT_TIMER = $00000001; 6 | {$EXTERNALSYM SDL_INIT_TIMER} 7 | SDL_INIT_AUDIO = $00000010; 8 | {$EXTERNALSYM SDL_INIT_AUDIO} 9 | SDL_INIT_VIDEO = $00000020; 10 | {$EXTERNALSYM SDL_INIT_VIDEO} 11 | SDL_INIT_JOYSTICK = $00000200; 12 | {$EXTERNALSYM SDL_INIT_JOYSTICK} 13 | SDL_INIT_HAPTIC = $00001000; 14 | {$EXTERNALSYM SDL_INIT_HAPTIC} 15 | SDL_INIT_GAMECONTROLLER = $00002000; //turn on game controller also implicitly does JOYSTICK 16 | {$EXTERNALSYM SDL_INIT_GAMECONTROLLER} 17 | SDL_INIT_NOPARACHUTE = $00100000; //Don't catch fatal signals 18 | {$EXTERNALSYM SDL_INIT_NOPARACHUTE} 19 | SDL_INIT_EVERYTHING = SDL_INIT_TIMER or 20 | SDL_INIT_AUDIO or 21 | SDL_INIT_VIDEO or 22 | SDL_INIT_JOYSTICK or 23 | SDL_INIT_HAPTIC or 24 | SDL_INIT_GAMECONTROLLER; 25 | {$EXTERNALSYM SDL_INIT_EVERYTHING} 26 | 27 | {** 28 | * This function initializes the subsystems specified by flags 29 | * Unless the SDL_INIT_NOPARACHUTE flag is set, it will install cleanup 30 | * signal handlers for some commonly ignored fatal signals (like SIGSEGV). 31 | *} 32 | 33 | function SDL_Init(flags: UInt32): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_Init' {$ENDIF} {$ENDIF}; 34 | 35 | {** 36 | * This function initializes specific SDL subsystems 37 | *} 38 | 39 | function SDL_InitSubSystem(flags: UInt32): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_InitSubSystem' {$ENDIF} {$ENDIF}; 40 | 41 | {** 42 | * This function cleans up specific SDL subsystems 43 | *} 44 | 45 | procedure SDL_QuitSubSystem(flags: UInt32) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_QuitSubSystem' {$ENDIF} {$ENDIF}; 46 | 47 | {** 48 | * This function returns a mask of the specified subsystems which have 49 | * previously been initialized. 50 | * 51 | * If flags is 0, it returns a mask of all initialized subsystems. 52 | *} 53 | 54 | function SDL_WasInit(flags: UInt32): UInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WasInit' {$ENDIF} {$ENDIF}; 55 | 56 | {** 57 | * This function cleans up all initialized subsystems. You should 58 | * call it upon all exit conditions. 59 | *} 60 | 61 | procedure SDL_Quit() cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_Quit' {$ENDIF} {$ENDIF}; 62 | 63 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlblendmode.inc: -------------------------------------------------------------------------------- 1 | //from "sdl_blendmode.h" 2 | 3 | {** 4 | * The blend mode used in SDL_RenderCopy() and drawing operations. 5 | *} 6 | 7 | type 8 | PSDL_BlendMode = ^TSDL_BlendMode; 9 | TSDL_BlendMode = DWord; 10 | 11 | const 12 | SDL_BLENDMODE_NONE = $00000000; {**< No blending *} 13 | SDL_BLENDMODE_BLEND = $00000001; {**< dst = (src * A) + (dst * (1-A)) *} 14 | SDL_BLENDMODE_ADD = $00000002; {**< dst = (src * A) + dst *} 15 | SDL_BLENDMODE_MOD = $00000004; {**< dst = src * dst *} 16 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlclipboard.inc: -------------------------------------------------------------------------------- 1 | 2 | {* Function prototypes *} 3 | 4 | {** 5 | * \brief Put UTF-8 text into the clipboard 6 | * 7 | * \sa SDL_GetClipboardText() 8 | *} 9 | function SDL_SetClipboardText(const text: PAnsiChar): Integer cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetClipboardText' {$ENDIF} {$ENDIF}; 10 | 11 | {** 12 | * \brief Get UTF-8 text from the clipboard, which must be freed with SDL_free() 13 | * 14 | * \sa SDL_SetClipboardText() 15 | *} 16 | function SDL_GetClipboardText(): PAnsiChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetClipboardText' {$ENDIF} {$ENDIF}; 17 | 18 | {** 19 | * \brief Returns a flag indicating whether the clipboard exists and contains a text string that is non-empty 20 | * 21 | * \sa SDL_GetClipboardText() 22 | *} 23 | function SDL_HasClipboardText(): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasClipboardText' {$ENDIF} {$ENDIF}; 24 | 25 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlcpuinfo.inc: -------------------------------------------------------------------------------- 1 | 2 | {* This is a guess for the cacheline size used for padding. 3 | * Most x86 processors have a 64 byte cache line. 4 | * The 64-bit PowerPC processors have a 128 byte cache line. 5 | * We'll use the larger value to be generally safe. 6 | *} 7 | const 8 | SDL_CACHELINE_SIZE = 128; 9 | 10 | {** 11 | * This function returns the number of CPU cores available. 12 | *} 13 | function SDL_GetCPUCount(): Integer; cdecl external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCPUCount' {$ENDIF} {$ENDIF}; 14 | 15 | {** 16 | * This function returns the L1 cache line size of the CPU 17 | * 18 | * This is useful for determining multi-threaded structure padding 19 | * or SIMD prefetch sizes. 20 | *} 21 | function SDL_GetCPUCacheLineSize(): Integer cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCPUCacheLineSize' {$ENDIF} {$ENDIF}; 22 | 23 | {** 24 | * This function returns true if the CPU has the RDTSC instruction. 25 | *} 26 | function SDL_HasRDTSC(): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasRDTSC' {$ENDIF} {$ENDIF}; 27 | 28 | {** 29 | * This function returns true if the CPU has AltiVec features. 30 | *} 31 | function SDL_HasAltiVec(): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasAltiVec' {$ENDIF} {$ENDIF}; 32 | 33 | {** 34 | * This function returns true if the CPU has MMX features. 35 | *} 36 | function SDL_HasMMX(): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasMMX' {$ENDIF} {$ENDIF}; 37 | 38 | {** 39 | * This function returns true if the CPU has 3DNow! features. 40 | *} 41 | function SDL_Has3DNow(): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_Has3DNow' {$ENDIF} {$ENDIF}; 42 | 43 | {** 44 | * This function returns true if the CPU has SSE features. 45 | *} 46 | function SDL_HasSSE(): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasSSE' {$ENDIF} {$ENDIF}; 47 | 48 | {** 49 | * This function returns true if the CPU has SSE2 features. 50 | *} 51 | function SDL_HasSSE2(): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasSSE2' {$ENDIF} {$ENDIF}; 52 | 53 | {** 54 | * This function returns true if the CPU has SSE3 features. 55 | *} 56 | function SDL_HasSSE3(): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasSSE3' {$ENDIF} {$ENDIF}; 57 | 58 | {** 59 | * This function returns true if the CPU has SSE4.1 features. 60 | *} 61 | function SDL_HasSSE41(): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasSSE41' {$ENDIF} {$ENDIF}; 62 | 63 | {** 64 | * This function returns true if the CPU has SSE4.2 features. 65 | *} 66 | function SDL_HasSSE42(): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasSSE42' {$ENDIF} {$ENDIF}; 67 | 68 | {** 69 | * This function returns true if the CPU has AVX features. 70 | *} 71 | function SDL_HasAVX(): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasAVX' {$ENDIF} {$ENDIF}; 72 | 73 | {** 74 | * This function returns true if the CPU has AVX2 features. 75 | *} 76 | function SDL_HasAVX2(): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasAVX2' {$ENDIF} {$ENDIF}; 77 | 78 | {** 79 | * This function returns the amount of RAM configured in the system, in MB. 80 | *} 81 | function SDL_GetSystemRAM(): Integer cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSystemRAM' {$ENDIF} {$ENDIF}; 82 | 83 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlerror.inc: -------------------------------------------------------------------------------- 1 | //from "sdl_error.h" 2 | const 3 | ERR_MAX_STRLEN = 128; 4 | ERR_MAX_ARGS = 5; 5 | 6 | {* Public functions *} 7 | 8 | {* SDL_SetError() unconditionally returns -1. *} 9 | function SDL_SetError(const fmt: PAnsiChar): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetError' {$ENDIF} {$ENDIF}; 10 | function SDL_GetError: PAnsiChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetError' {$ENDIF} {$ENDIF}; 11 | procedure SDL_ClearError cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ClearError' {$ENDIF} {$ENDIF}; 12 | {*Internal error functions*} 13 | {** 14 | * Internal error functions 15 | * 16 | * Private error reporting function - used internally. 17 | *} 18 | 19 | { 20 | #define SDL_OutOfMemory() SDL_Error(SDL_ENOMEM) 21 | #define SDL_Unsupported() SDL_Error(SDL_UNSUPPORTED) 22 | #define SDL_InvalidParamError(param) SDL_SetError("Parameter '%s' is invalid", (param)) 23 | } 24 | type 25 | TSDL_ErrorCode = (SDL_ENOMEM, 26 | SDL_EFREAD, 27 | SDL_EFWRITE, 28 | SDL_EFSEEK, 29 | SDL_UNSUPPORTED, 30 | SDL_LASTERROR); 31 | 32 | TSDL_Error = record 33 | {* This is a numeric value corresponding to the current error *} 34 | error: SInt32; 35 | 36 | {* This is a key used to index into a language hashtable containing 37 | internationalized versions of the SDL error messages. If the key 38 | is not in the hashtable, or no hashtable is available, the key is 39 | used directly as an error message format string. 40 | *} 41 | key: String[ERR_MAX_STRLEN]; 42 | 43 | {* These are the arguments for the error functions *} 44 | argc: SInt32; 45 | case SInt32 of 46 | {* What is a character anyway? (UNICODE issues) *} 47 | 0: (value_c: Byte;); 48 | 1: (value_ptr: Pointer;); 49 | 2: (value_i: SInt32;); 50 | 3: (value_f: Double;); 51 | 4: (buf: String[ERR_MAX_STRLEN];); 52 | end; 53 | 54 | {* SDL_Error() unconditionally returns -1. *} 55 | function SDL_Error(code: TSDL_ErrorCode): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_Error' {$ENDIF} {$ENDIF}; 56 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlfilesystem.inc: -------------------------------------------------------------------------------- 1 | 2 | {** 3 | * \brief Get the path where the application resides. 4 | * 5 | * Get the "base path". This is the directory where the application was run 6 | * from, which is probably the installation directory, and may or may not 7 | * be the process's current working directory. 8 | * 9 | * This returns an absolute path in UTF-8 encoding, and is guaranteed to 10 | * end with a path separator ('\\' on Windows, '/' most other places). 11 | * 12 | * The pointer returned by this function is owned by you. Please call 13 | * SDL_free() on the pointer when you are done with it, or it will be a 14 | * memory leak. This is not necessarily a fast call, though, so you should 15 | * call this once near startup and save the string if you need it. 16 | * 17 | * Some platforms can't determine the application's path, and on other 18 | * platforms, this might be meaningless. In such cases, this function will 19 | * return NULL. 20 | * 21 | * \return String of base dir in UTF-8 encoding, or NULL on error. 22 | * 23 | * \sa SDL_GetPrefPath 24 | *} 25 | function SDL_GetBasePath(): PChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetBasePath' {$ENDIF} {$ENDIF}; 26 | 27 | {** 28 | * \brief Get the user-and-app-specific path where files can be written. 29 | * 30 | * Get the "pref dir". This is meant to be where users can write personal 31 | * files (preferences and save games, etc) that are specific to your 32 | * application. This directory is unique per user, per application. 33 | * 34 | * This function will decide the appropriate location in the native filesystem, 35 | * create the directory if necessary, and return a string of the absolute 36 | * path to the directory in UTF-8 encoding. 37 | * 38 | * On Windows, the string might look like: 39 | * "C:\\Users\\bob\\AppData\\Roaming\\My Company\\My Program Name\\" 40 | * 41 | * On Linux, the string might look like: 42 | * "/home/bob/.local/share/My Program Name/" 43 | * 44 | * On Mac OS X, the string might look like: 45 | * "/Users/bob/Library/Application Support/My Program Name/" 46 | * 47 | * (etc.) 48 | * 49 | * You specify the name of your organization (if it's not a real organization, 50 | * your name or an Internet domain you own might do) and the name of your 51 | * application. These should be untranslated proper names. 52 | * 53 | * Both the org and app strings may become part of a directory name, so 54 | * please follow these rules: 55 | * 56 | * - Try to use the same org string (including case-sensitivity) for 57 | * all your applications that use this function. 58 | * - Always use a unique app string for each one, and make sure it never 59 | * changes for an app once you've decided on it. 60 | * - Unicode characters are legal, as long as it's UTF-8 encoded, but... 61 | * - ...only use letters, numbers, and spaces. Avoid punctuation like 62 | * "Game Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient. 63 | * 64 | * This returns an absolute path in UTF-8 encoding, and is guaranteed to 65 | * end with a path separator ('\\' on Windows, '/' most other places). 66 | * 67 | * The pointer returned by this function is owned by you. Please call 68 | * SDL_free() on the pointer when you are done with it, or it will be a 69 | * memory leak. This is not necessarily a fast call, though, so you should 70 | * call this once near startup and save the string if you need it. 71 | * 72 | * You should assume the path returned by this function is the only safe 73 | * place to write files (and that SDL_GetBasePath(), while it might be 74 | * writable, or even the parent of the returned path, aren't where you 75 | * should be writing things). 76 | * 77 | * Some platforms can't determine the pref path, and on other 78 | * platforms, this might be meaningless. In such cases, this function will 79 | * return NULL. 80 | * 81 | * \param org The name of your organization. 82 | * \param app The name of your application. 83 | * \return UTF-8 string of user dir in platform-dependent notation. NULL 84 | * if there's a problem (creating directory failed, etc). 85 | * 86 | * \sa SDL_GetBasePath 87 | *} 88 | function SDL_GetPrefPath(const org: PAnsiChar; const app: PAnsiChar): PChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPrefPath' {$ENDIF} {$ENDIF}; 89 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlgesture.inc: -------------------------------------------------------------------------------- 1 | //from "sdl_gesture.h" 2 | 3 | type 4 | TSDL_GestureID = SInt64; 5 | 6 | {* Function prototypes *} 7 | 8 | {** 9 | * Begin Recording a gesture on the specified touch, or all touches (-1) 10 | * 11 | * 12 | *} 13 | function SDL_RecordGesture(touchId: TSDL_TouchID): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RecordGesture' {$ENDIF} {$ENDIF}; 14 | 15 | {** 16 | * Save all currently loaded Dollar Gesture templates 17 | * 18 | * 19 | *} 20 | function SDL_SaveAllDollarTemplates(src: PSDL_RWops): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SaveAllDollarTemplates' {$ENDIF} {$ENDIF}; 21 | 22 | {** 23 | * Save a currently loaded Dollar Gesture template 24 | * 25 | * 26 | *} 27 | function SDL_SaveDollarTemplate(gestureId: TSDL_GestureID; src: PSDL_RWops): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SaveDollarTemplate' {$ENDIF} {$ENDIF}; 28 | 29 | 30 | {** 31 | * Load Dollar Gesture templates from a file 32 | * 33 | * 34 | *} 35 | function SDL_LoadDollarTemplates(touchId: TSDL_TouchID; src: PSDL_RWops): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LoadDollarTemplates' {$ENDIF} {$ENDIF}; 36 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlkeyboard.inc: -------------------------------------------------------------------------------- 1 | //from "sdl_keyboard.h" 2 | 3 | type 4 | PKeyStateArr = ^TKeyStateArr; 5 | TKeyStateArr = array[0..65000] of UInt8; 6 | 7 | {** 8 | * The SDL keysym structure, used in key events. 9 | *} 10 | PSDL_Keysym = ^TSDL_Keysym; 11 | TSDL_Keysym = record 12 | scancode: TSDL_ScanCode; // SDL physical key code - see SDL_Scancode for details 13 | sym: TSDL_KeyCode; // SDL virtual key code - see SDL_Keycode for details 14 | _mod: UInt16; // current key modifiers 15 | unicode: UInt32; // (deprecated) use SDL_TextInputEvent instead 16 | end; 17 | 18 | {** 19 | * Get the window which currently has keyboard focus. 20 | *} 21 | 22 | function SDL_GetKeyboardFocus: PSDL_Window cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyboardFocus' {$ENDIF}{$ENDIF}; 23 | 24 | {** 25 | * Get a snapshot of the current state of the keyboard. 26 | * 27 | * numkeys if non-nil, receives the length of the returned array. 28 | * 29 | * An array of key states. Indexes into this array are obtained by using SDL_Scancode values. 30 | * 31 | *} 32 | 33 | function SDL_GetKeyboardState(numkeys: PInt): PUInt8 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyboardState' {$ENDIF}{$ENDIF}; 34 | 35 | {** 36 | * Get the current key modifier state for the keyboard. 37 | *} 38 | 39 | function SDL_GetModState: TSDL_KeyMod cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetModState' {$ENDIF}{$ENDIF}; 40 | 41 | {** 42 | * Set the current key modifier state for the keyboard. 43 | * 44 | * This does not change the keyboard state, only the key modifier flags. 45 | *} 46 | 47 | procedure SDL_SetModState(modstate: TSDL_KeyMod) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetModState' {$ENDIF}{$ENDIF}; 48 | 49 | {** 50 | * Get the key code corresponding to the given scancode according 51 | * to the current keyboard layout. 52 | * 53 | * See SDL_Keycode for details. 54 | * 55 | * SDL_GetKeyName() 56 | *} 57 | 58 | function SDL_GetKeyFromScancode(scancode: TSDL_ScanCode): TSDL_KeyCode cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyFromScancode' {$ENDIF}{$ENDIF}; 59 | 60 | {** 61 | * Get the scancode corresponding to the given key code according to the 62 | * current keyboard layout. 63 | * 64 | * See SDL_Scancode for details. 65 | * 66 | * SDL_GetScancodeName() 67 | *} 68 | 69 | function SDL_GetScancodeFromKey(key: TSDL_KeyCode): TSDL_ScanCode cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetScancodeFromKey' {$ENDIF}{$ENDIF}; 70 | 71 | {** 72 | * Get a human-readable name for a scancode. 73 | * 74 | * A pointer to the name for the scancode. 75 | * 76 | * If the scancode doesn't have a name, this function returns 77 | * an empty string (""). 78 | * 79 | *} 80 | 81 | function SDL_GetScancodeName(scancode: TSDL_ScanCode): PAnsiChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetScancodeName' {$ENDIF}{$ENDIF}; 82 | 83 | {** 84 | * Get a scancode from a human-readable name 85 | * 86 | * scancode, or SDL_SCANCODE_UNKNOWN if the name wasn't recognized 87 | * 88 | * SDL_Scancode 89 | *} 90 | 91 | function SDL_GetScancodeFromName(const name: PAnsiChar): TSDL_ScanCode cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetScancodeFromName' {$ENDIF}{$ENDIF}; 92 | 93 | {** 94 | * Get a human-readable name for a key. 95 | * 96 | * A pointer to a UTF-8 string that stays valid at least until the next 97 | * call to this function. If you need it around any longer, you must 98 | * copy it. If the key doesn't have a name, this function returns an 99 | * empty string (""). 100 | * 101 | * SDL_Key 102 | *} 103 | 104 | function SDL_GetKeyName(key: TSDL_KeyCode): PAnsiChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyName' {$ENDIF}{$ENDIF}; 105 | 106 | {** 107 | * Get a key code from a human-readable name 108 | * 109 | * key code, or SDLK_UNKNOWN if the name wasn't recognized 110 | * 111 | * SDL_Keycode 112 | *} 113 | 114 | function SDL_GetKeyFromName(const name: PAnsiChar): TSDL_KeyCode cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyFromName' {$ENDIF}{$ENDIF}; 115 | 116 | {** 117 | * Start accepting Unicode text input events. 118 | * This function will show the on-screen keyboard if supported. 119 | * 120 | * SDL_StopTextInput() 121 | * SDL_SetTextInputRect() 122 | * SDL_HasScreenKeyboardSupport() 123 | *} 124 | 125 | procedure SDL_StartTextInput cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_StartTextInput' {$ENDIF}{$ENDIF}; 126 | 127 | {** 128 | * Return whether or not Unicode text input events are enabled. 129 | * 130 | * SDL_StartTextInput() 131 | * SDL_StopTextInput() 132 | *} 133 | 134 | function SDL_IsTextInputActive: TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IsTextInputActive' {$ENDIF}{$ENDIF}; 135 | 136 | {** 137 | * Stop receiving any text input events. 138 | * This function will hide the on-screen keyboard if supported. 139 | * 140 | * SDL_StartTextInput() 141 | * SDL_HasScreenKeyboardSupport() 142 | *} 143 | 144 | procedure SDL_StopTextInput cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_StopTextInput' {$ENDIF}{$ENDIF}; 145 | 146 | {** 147 | * Set the rectangle used to type Unicode text inputs. 148 | * This is used as a hint for IME and on-screen keyboard placement. 149 | * 150 | * SDL_StartTextInput() 151 | *} 152 | 153 | procedure SDL_SetTextInputRect(rect: PSDL_Rect) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetTextInputRect' {$ENDIF}{$ENDIF}; 154 | 155 | {** 156 | * Returns whether the platform has some screen keyboard support. 157 | * 158 | * SDL_TRUE if some keyboard support is available else SDL_FALSE. 159 | * 160 | * Not all screen keyboard functions are supported on all platforms. 161 | * 162 | * SDL_IsScreenKeyboardShown() 163 | *} 164 | 165 | function SDL_HasScreenKeyboardSupport: TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasScreenKeyboardSupport' {$ENDIF}{$ENDIF}; 166 | 167 | {** 168 | * Returns whether the screen keyboard is shown for given window. 169 | * 170 | * window The window for which screen keyboard should be queried. 171 | * 172 | * Result - SDL_TRUE if screen keyboard is shown else SDL_FALSE. 173 | * 174 | * SDL_HasScreenKeyboardSupport() 175 | *} 176 | 177 | function SDL_IsScreenKeyboardShown(window: PSDL_Window): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IsScreenKeyboardShown' {$ENDIF}{$ENDIF}; 178 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlloadso.inc: -------------------------------------------------------------------------------- 1 | //from sdl_loadso.h 2 | 3 | {** 4 | * This function dynamically loads a shared object and returns a pointer 5 | * to the object handle (or NULL if there was an error). 6 | * The 'sofile' parameter is a system dependent name of the object file. 7 | *} 8 | function SDL_LoadObject(Const sofile: PAnsiChar): Pointer; cdecl; 9 | external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LoadObject' {$ENDIF}{$ENDIF}; 10 | 11 | {** 12 | * Given an object handle, this function looks up the address of the 13 | * named function in the shared object and returns it. This address 14 | * is no longer valid after calling SDL_UnloadObject(). 15 | *} 16 | function SDL_LoadFunction(handle: Pointer; Const name: PAnsiChar): Pointer; cdecl; 17 | external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LoadFunction' {$ENDIF}{$ENDIF}; 18 | 19 | {** 20 | * Unload a shared object from memory. 21 | *} 22 | procedure SDL_UnloadObject(handle: Pointer); cdecl; 23 | external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnloadObject' {$ENDIF}{$ENDIF}; 24 | -------------------------------------------------------------------------------- /src/include/sdl2/sdllog.inc: -------------------------------------------------------------------------------- 1 | 2 | //since the array of const in delphi is not C compatible: 3 | {$IFDEF FPC} 4 | 5 | {** 6 | * \brief The maximum size of a log message 7 | * 8 | * Messages longer than the maximum size will be truncated 9 | *} 10 | const 11 | SDL_MAX_LOG_MESSAGE = 4096; 12 | 13 | {** 14 | * \brief The predefined log categories 15 | * 16 | * By default the application category is enabled at the INFO level, 17 | * the assert category is enabled at the WARN level, test is enabled 18 | * at the VERBOSE level and all other categories are enabled at the 19 | * CRITICAL level. 20 | *} 21 | type 22 | TSDL_LogCategory = (SDL_LOG_CATEGORY_APPLICATION, 23 | SDL_LOG_CATEGORY_ERROR, 24 | SDL_LOG_CATEGORY_ASSERT, 25 | SDL_LOG_CATEGORY_SYSTEM, 26 | SDL_LOG_CATEGORY_AUDIO, 27 | SDL_LOG_CATEGORY_VIDEO, 28 | SDL_LOG_CATEGORY_RENDER, 29 | SDL_LOG_CATEGORY_INPUT, 30 | SDL_LOG_CATEGORY_TEST, 31 | 32 | {* Reserved for future SDL library use *} 33 | SDL_LOG_CATEGORY_RESERVED1, 34 | SDL_LOG_CATEGORY_RESERVED2, 35 | SDL_LOG_CATEGORY_RESERVED3, 36 | SDL_LOG_CATEGORY_RESERVED4, 37 | SDL_LOG_CATEGORY_RESERVED5, 38 | SDL_LOG_CATEGORY_RESERVED6, 39 | SDL_LOG_CATEGORY_RESERVED7, 40 | SDL_LOG_CATEGORY_RESERVED8, 41 | SDL_LOG_CATEGORY_RESERVED9, 42 | SDL_LOG_CATEGORY_RESERVED10, 43 | 44 | {* Beyond this point is reserved for application use *} 45 | SDL_LOG_CATEGORY_CUSTOM); 46 | 47 | {** 48 | * \brief The predefined log priorities 49 | *} 50 | const 51 | SDL_LOG_PRIORITY_VERBOSE = 1; 52 | SDL_LOG_PRIORITY_DEBUG = 2; 53 | SDL_LOG_PRIORITY_INFO = 3; 54 | SDL_LOG_PRIORITY_WARN = 4; 55 | SDL_LOG_PRIORITY_ERROR = 5; 56 | SDL_LOG_PRIORITY_CRITICAL = 6; 57 | SDL_NUM_LOG_PRIORITIES = 7; 58 | type 59 | TSDL_LogPriority = Integer; 60 | 61 | 62 | {** 63 | * \brief Set the priority of all log categories 64 | *} 65 | procedure SDL_LogSetAllPriority(priority: TSDL_LogPriority) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogSetAllPriority' {$ENDIF} {$ENDIF}; 66 | 67 | {** 68 | * \brief Set the priority of a particular log category 69 | *} 70 | procedure SDL_LogSetPriority(category: Integer; priority: TSDL_LogPriority) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogSetPriority' {$ENDIF} {$ENDIF}; 71 | 72 | {** 73 | * \brief Get the priority of a particular log category 74 | *} 75 | function SDL_LogGetPriority(category: Integer): TSDL_LogPriority cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogGetPriority' {$ENDIF} {$ENDIF}; 76 | 77 | {** 78 | * \brief Reset all priorities to default. 79 | * 80 | * \note This is called in SDL_Quit(). 81 | *} 82 | procedure SDL_LogResetPriorities() cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogResetPriorities' {$ENDIF} {$ENDIF}; 83 | 84 | {** 85 | * \brief Log a message with SDL_LOG_CATEGORY_APPLICATION and SDL_LOG_PRIORITY_INFO 86 | *} 87 | procedure SDL_Log(const fmt: PAnsiChar; pars: array of const) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_Log' {$ENDIF} {$ENDIF}; 88 | 89 | {** 90 | * \brief Log a message with SDL_LOG_PRIORITY_VERBOSE 91 | *} 92 | procedure SDL_LogVerbose(category: Integer; const fmt: PAnsiChar; pars: array of const) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogVerbose' {$ENDIF} {$ENDIF}; 93 | 94 | {** 95 | * \brief Log a message with SDL_LOG_PRIORITY_DEBUG 96 | *} 97 | procedure SDL_LogDebug(category: Integer; const fmt: PAnsiChar; pars: array of const) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogDebug' {$ENDIF} {$ENDIF}; 98 | 99 | {** 100 | * \brief Log a message with SDL_LOG_PRIORITY_INFO 101 | *} 102 | procedure SDL_LogInfo(category: Integer; const fmt: PAnsiChar; pars: array of const) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogInfo' {$ENDIF} {$ENDIF}; 103 | 104 | {** 105 | * \brief Log a message with SDL_LOG_PRIORITY_WARN 106 | *} 107 | procedure SDL_LogWarn(category: Integer; const fmt: PAnsiChar; pars: array of const) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogWarn' {$ENDIF} {$ENDIF}; 108 | 109 | {** 110 | * \brief Log a message with SDL_LOG_PRIORITY_ERROR 111 | *} 112 | procedure SDL_LogError(category: Integer; const fmt: PAnsiChar; pars: array of const) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogError' {$ENDIF} {$ENDIF}; 113 | 114 | {** 115 | * \brief Log a message with SDL_LOG_PRIORITY_CRITICAL 116 | *} 117 | procedure SDL_LogCritical(category: Integer; const fmt: PAnsiChar; pars: array of const) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogCritical' {$ENDIF} {$ENDIF}; 118 | 119 | {** 120 | * \brief Log a message with the specified category and priority. 121 | *} 122 | procedure SDL_LogMessage(category: Integer; priority: TSDL_LogPriority; const fmt: PAnsiChar; pars: array of const) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogMessage' {$ENDIF} {$ENDIF}; 123 | 124 | {** 125 | * \brief Log a message with the specified category and priority. 126 | *} 127 | procedure SDL_LogMessageV(category: Integer; priority: TSDL_LogPriority; const fmt: PAnsiChar; ap: array of const) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogMessageV' {$ENDIF} {$ENDIF}; 128 | 129 | {** 130 | * \brief The prototype for the log output function 131 | *} 132 | type 133 | TSDL_LogOutputFunction = procedure(userdata: Pointer; category: Integer; priority: TSDL_LogPriority; const msg: PAnsiChar); 134 | PSDL_LogOutputFunction = ^TSDL_LogOutputFunction; 135 | 136 | {** 137 | * \brief Get the current log output function. 138 | *} 139 | procedure SDL_LogGetOutputFunction(callback: PSDL_LogOutputFunction; userdata: PPointer) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogGetOutputFunction' {$ENDIF} {$ENDIF}; 140 | 141 | {** 142 | * \brief This function allows you to replace the default log output 143 | * function with one of your own. 144 | *} 145 | procedure SDL_LogSetOutputFunction(callback: TSDL_LogOutputFunction; userdata: Pointer) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LogSetOutputFunction' {$ENDIF} {$ENDIF}; 146 | 147 | {$ENDIF} 148 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlmessagebox.inc: -------------------------------------------------------------------------------- 1 | //from "sdl_messagebox.h" 2 | 3 | {** 4 | * SDL_MessageBox flags. If supported will display warning icon, etc. 5 | *} 6 | 7 | const 8 | SDL_MESSAGEBOX_ERROR = $00000010; {**< error dialog *} 9 | SDL_MESSAGEBOX_WARNING = $00000020; {**< warning dialog *} 10 | SDL_MESSAGEBOX_INFORMATION = $00000040; {**< informational dialog *} 11 | 12 | type 13 | TSDL_MessageBoxFlags = Byte; 14 | 15 | {** 16 | * Flags for SDL_MessageBoxButtonData. 17 | *} 18 | const 19 | SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT = $00000001; {**< Marks the default button when return is hit *} 20 | SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT = $00000002; {**< Marks the default button when escape is hit *} 21 | type 22 | TSDL_MessageBoxButtonFlags = Byte; 23 | 24 | {** 25 | * Individual button data. 26 | *} 27 | type 28 | PSDL_MessageBoxButtonData = ^TSDL_MessageBoxButtonData; 29 | TSDL_MessageBoxButtonData = record 30 | flags: UInt32; {**< ::SDL_MessageBoxButtonFlags *} 31 | buttonid: Integer; {**< User defined button id (value returned via SDL_ShowMessageBox) *} 32 | text: PAnsiChar; {**< The UTF-8 button text *} 33 | end; 34 | 35 | {** 36 | * RGB value used in a message box color scheme 37 | *} 38 | type 39 | PSDL_MessageBoxColor = ^TSDL_MessageBoxColor; 40 | TSDL_MessageBoxColor = record 41 | r, g, b: UInt8; 42 | end; 43 | 44 | PSDL_MessageBoxColorType = ^TSDL_MessageBoxColorType; 45 | TSDL_MessageBoxColorType = (SDL_MESSAGEBOX_COLOR_BACKGROUND, 46 | SDL_MESSAGEBOX_COLOR_TEXT, 47 | SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, 48 | SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, 49 | SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, 50 | SDL_MESSAGEBOX_COLOR_MAX); 51 | 52 | {** 53 | * A set of colors to use for message box dialogs 54 | *} 55 | type 56 | PSDL_MessageBoxColorScheme = ^TSDL_MessageBoxColorScheme; 57 | TSDL_MessageBoxColorScheme = record 58 | //colors: array[0..SDL_MESSAGEBOX_COLOR_MAX-1] of TSDL_MessageBoxColor; 59 | colors: array[0..4] of TSDL_MessageBoxColor; //right?! 60 | end; 61 | 62 | {** 63 | * MessageBox structure containing title, text, window, etc. 64 | *} 65 | type 66 | PSDL_MessageBoxData = ^TSDL_MessageBoxData; 67 | TSDL_MessageBoxData = record 68 | flags: UInt32; {**< SDL_MessageBoxFlags *} 69 | window: PSDL_Window; {**< Parent window, can be NULL *} 70 | title: PAnsiChar; {**< UTF-8 title *} 71 | _message: PAnsiChar; {**< UTF-8 message text *} 72 | 73 | numbuttons: Integer; 74 | buttons: PSDL_MessageBoxButtonData; 75 | 76 | colorScheme: PSDL_MessageBoxColorScheme; {**< SDL_MessageBoxColorScheme, can be NULL to use system settings *} 77 | end; 78 | 79 | {** 80 | * Create a modal message box. 81 | * 82 | * messageboxdata The SDL_MessageBoxData structure with title, text, etc. 83 | * buttonid The pointer to which user id of hit button should be copied. 84 | * 85 | * -1 on error, otherwise 0 and buttonid contains user id of button 86 | * hit or -1 if dialog was closed. 87 | * 88 | * This function should be called on the thread that created the parent 89 | * window, or on the main thread if the messagebox has no parent. It will 90 | * block execution of that thread until the user clicks a button or 91 | * closes the messagebox. 92 | *} 93 | function SDL_ShowMessageBox(messageboxdata: PSDL_MessageBoxData; buttonid: PInt): Integer cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ShowMessageBox' {$ENDIF} {$ENDIF}; 94 | 95 | {** 96 | * Create a simple modal message box 97 | * 98 | * flags SDL_MessageBoxFlags 99 | * title UTF-8 title text 100 | * message UTF-8 message text 101 | * window The parent window, or NULL for no parent 102 | * 103 | * 0 on success, -1 on error 104 | * 105 | * SDL_ShowMessageBox 106 | *} 107 | function SDL_ShowSimpleMessageBox(flags: UInt32; title: PAnsiChar; _message: PAnsiChar; window: PSDL_Window): Integer cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ShowSimpleMessageBox' {$ENDIF} {$ENDIF}; 108 | 109 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlmutex.inc: -------------------------------------------------------------------------------- 1 | //from "sdl_mutex.h" 2 | 3 | {** 4 | * Synchronization functions which can time out return this value 5 | * if they time out. 6 | *} 7 | const 8 | SDL_MUTEX_TIMEDOUT = 1; 9 | 10 | {** 11 | * This is the timeout value which corresponds to never time out. 12 | *} 13 | //SDL_MUTEX_MAXWAIT (~(Uint32)0) 14 | 15 | 16 | {** 17 | * Mutex functions 18 | *} 19 | type 20 | {* The SDL mutex structure, defined in SDL_mutex.c *} 21 | PSDL_Mutex = Pointer; //todo! 22 | 23 | {** 24 | * Create a mutex, initialized unlocked. 25 | *} 26 | function SDL_CreateMutex: PSDL_Mutex cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateMutex' {$ENDIF} {$ENDIF}; 27 | 28 | {** 29 | * Lock the mutex. 30 | * 31 | * 0, or -1 on error. 32 | *} 33 | //#define SDL_mutexP(m) SDL_LockMutex(m) 34 | function SDL_LockMutex(mutex: PSDL_Mutex): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LockMutex' {$ENDIF} {$ENDIF}; 35 | 36 | {** 37 | * Try to lock the mutex 38 | * 39 | * 0, SDL_MUTEX_TIMEDOUT, or -1 on error 40 | *} 41 | function SDL_TryLockMutex(mutex: PSDL_Mutex): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_TryLockMutex' {$ENDIF} {$ENDIF}; 42 | 43 | {** 44 | * Unlock the mutex. 45 | * 46 | * 0, or -1 on error. 47 | * 48 | * It is an error to unlock a mutex that has not been locked by 49 | * the current thread, and doing so results in undefined behavior. 50 | *} 51 | //#define SDL_mutexV(m) SDL_UnlockMutex(m) 52 | function SDL_UnlockMutex(mutex: PSDL_Mutex): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnlockMutex' {$ENDIF} {$ENDIF}; 53 | 54 | {** 55 | * Destroy a mutex. 56 | *} 57 | procedure SDL_DestroyMutex(mutex: PSDL_Mutex) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DestroyMutex' {$ENDIF} {$ENDIF}; 58 | 59 | {*Mutex functions*} 60 | 61 | {** 62 | * Semaphore functions 63 | *} 64 | type 65 | {* The SDL semaphore structure, defined in SDL_sem.c *} 66 | PSDL_Sem = Pointer; //todo! 67 | 68 | {** 69 | * Create a semaphore, initialized with value, returns NULL on failure. 70 | *} 71 | function SDL_CreateSemaphore(initial_value: UInt32): PSDL_sem cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateSemaphore' {$ENDIF} {$ENDIF}; 72 | 73 | {** 74 | * Destroy a semaphore. 75 | *} 76 | procedure SDL_DestroySemaphore(sem: PSDL_Sem) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DestroySemaphore' {$ENDIF} {$ENDIF}; 77 | 78 | {** 79 | * This function suspends the calling thread until the semaphore pointed 80 | * to by sem has a positive count. It then atomically decreases the 81 | * semaphore count. 82 | *} 83 | function SDL_SemWait(sem: PSDL_Sem): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SemWait' {$ENDIF} {$ENDIF}; 84 | 85 | {** 86 | * Non-blocking variant of SDL_SemWait(). 87 | * 88 | * 0 if the wait succeeds, SDL_MUTEX_TIMEDOUT if the wait would 89 | * block, and -1 on error. 90 | *} 91 | function SDL_SemTryWait(sem: PSDL_Sem): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SemTryWait' {$ENDIF} {$ENDIF}; 92 | 93 | {** 94 | * Variant of SDL_SemWait() with a timeout in milliseconds. 95 | * 96 | * 0 if the wait succeeds, ::SDL_MUTEX_TIMEDOUT if the wait does not 97 | * succeed in the allotted time, and -1 on error. 98 | * 99 | * On some platforms this function is implemented by looping with a 100 | * delay of 1 ms, and so should be avoided if possible. 101 | *} 102 | function SDL_SemWaitTimeout(sem: PSDL_Sem; ms: UInt32): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SemWaitTimeout' {$ENDIF} {$ENDIF}; 103 | 104 | {** 105 | * Atomically increases the semaphore'_S count (not blocking). 106 | * 107 | * 0, or -1 on error. 108 | *} 109 | function SDL_SemPost(sem: PSDL_Sem): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SemPost' {$ENDIF} {$ENDIF}; 110 | 111 | {** 112 | * Returns the current count of the semaphore. 113 | *} 114 | function SDL_SemValue(sem: PSDL_Sem): UInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SemValue' {$ENDIF} {$ENDIF}; 115 | 116 | {*Semaphore functions*} 117 | 118 | {** 119 | * Condition variable functions 120 | * } 121 | type 122 | {* The SDL condition variable structure, defined in SDL_cond.c *} 123 | PSDL_Cond = Pointer; //todo!! 124 | 125 | {** 126 | * Create a condition variable. 127 | * 128 | * Typical use of condition variables: 129 | * 130 | * Thread A: 131 | * SDL_LockMutex(lock); 132 | * while ( not condition ) 133 | * begin 134 | * SDL_CondWait(cond, lock); 135 | * end; 136 | * SDL_UnlockMutex(lock); 137 | * 138 | * Thread B: 139 | * SDL_LockMutex(lock); 140 | * ... 141 | * condition := true; 142 | * ... 143 | * SDL_CondSignal(cond); 144 | * SDL_UnlockMutex(lock); 145 | * 146 | * There is some discussion whether to signal the condition variable 147 | * with the mutex locked or not. There is some potential performance 148 | * benefit to unlocking first on some platforms, but there are some 149 | * potential race conditions depending on how your code is structured. 150 | * 151 | * In general it'_S safer to signal the condition variable while the 152 | * mutex is locked. 153 | *} 154 | function SDL_CreateCond: PSDL_Cond cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateCond' {$ENDIF} {$ENDIF}; 155 | 156 | {** 157 | * Destroy a condition variable. 158 | *} 159 | procedure SDL_DestroyCond(cond: PSDL_Cond) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DestroyCond' {$ENDIF} {$ENDIF}; 160 | 161 | {** 162 | * Restart one of the threads that are waiting on the condition variable. 163 | * 164 | * 0 or -1 on error. 165 | *} 166 | function SDL_CondSignal(cond: PSDL_Cond): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CondSignal' {$ENDIF} {$ENDIF}; 167 | 168 | {** 169 | * Restart all threads that are waiting on the condition variable. 170 | * 171 | * 0 or -1 on error. 172 | *} 173 | function SDL_CondBroadcast(cond: PSDL_Cond): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CondBroadcast' {$ENDIF} {$ENDIF}; 174 | 175 | {** 176 | * Wait on the condition variable, unlocking the provided mutex. 177 | * 178 | * The mutex must be locked before entering this function! 179 | * 180 | * The mutex is re-locked once the condition variable is signaled. 181 | * 182 | * 0 when it is signaled, or -1 on error. 183 | *} 184 | function SDL_CondWait(cond: PSDL_Cond; mutex: PSDL_Mutex): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CondWait' {$ENDIF} {$ENDIF}; 185 | 186 | {** 187 | * Waits for at most ms milliseconds, and returns 0 if the condition 188 | * variable is signaled, SDL_MUTEX_TIMEDOUT if the condition is not 189 | * signaled in the allotted time, and -1 on error. 190 | * 191 | * On some platforms this function is implemented by looping with a 192 | * delay of 1 ms, and so should be avoided if possible. 193 | *} 194 | function SDL_CondWaitTimeout(cond: PSDL_Cond; mutex: PSDL_Mutex; ms: UInt32): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CondWaitTimeout' {$ENDIF} {$ENDIF}; 195 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlplatform.inc: -------------------------------------------------------------------------------- 1 | //from sdl_platform.h 2 | 3 | {** 4 | * Gets the name of the platform. 5 | *} 6 | function SDL_GetPlatform: PAnsiChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPlatform' {$ENDIF} {$ENDIF}; 7 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlpower.inc: -------------------------------------------------------------------------------- 1 | //from "sdl_power.h" 2 | 3 | {** 4 | * The basic state for the system's power supply. 5 | *} 6 | type 7 | TSDL_PowerState = (SDL_POWERSTATE_UNKNOWN, {**< cannot determine power status *} 8 | SDL_POWERSTATE_ON_BATTERY, {**< Not plugged in, running on the battery *} 9 | SDL_POWERSTATE_NO_BATTERY, {**< Plugged in, no battery available *} 10 | SDL_POWERSTATE_CHARGING, {**< Plugged in, charging battery *} 11 | SDL_POWERSTATE_CHARGED); {**< Plugged in, battery charged *} 12 | 13 | {** 14 | * Get the current power supply details. 15 | * 16 | * secs Seconds of battery life left. You can pass a NULL here if 17 | * you don't care. Will return -1 if we can't determine a 18 | * value, or we're not running on a battery. 19 | * 20 | * pct Percentage of battery life left, between 0 and 100. You can 21 | * pass a NULL here if you don't care. Will return -1 if we 22 | * can't determine a value, or we're not running on a battery. 23 | * 24 | * The state of the battery (if any). 25 | *} 26 | function SDL_GetPowerInfo(secs: PInt; pct: PInt): TSDL_PowerState cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPowerInfo' {$ENDIF} {$ENDIF}; 27 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlrect.inc: -------------------------------------------------------------------------------- 1 | //from "sdl_rect.h" 2 | 3 | type 4 | {** 5 | * The structure that defines a point 6 | * 7 | * SDL_EnclosePoints 8 | *} 9 | 10 | PSDL_Point = ^TSDL_Point; 11 | TSDL_Point = record 12 | x: SInt32; 13 | y: SInt32; 14 | end; 15 | 16 | {** 17 | * A rectangle, with the origin at the upper left. 18 | * 19 | * SDL_RectEmpty 20 | * SDL_RectEquals 21 | * SDL_HasIntersection 22 | * SDL_IntersectRect 23 | * SDL_UnionRect 24 | * SDL_EnclosePoints 25 | *} 26 | 27 | PSDL_Rect = ^TSDL_Rect; 28 | TSDL_Rect = record 29 | x,y: SInt32; 30 | w,h: SInt32; 31 | end; 32 | 33 | {** 34 | * \brief Returns true if point resides inside a rectangle. 35 | *} 36 | function SDL_PointInRect(const p: PSDL_Point; const r: PSDL_Rect): Boolean; Inline; 37 | 38 | {** 39 | * Returns true if the rectangle has no area. 40 | *} 41 | 42 | //changed from variant(b�����h!) to TSDL_Rect 43 | //maybe PSDL_Rect? 44 | function SDL_RectEmpty(const r: PSDL_Rect): Boolean; inline; 45 | 46 | {** 47 | * Returns true if the two rectangles are equal. 48 | *} 49 | 50 | function SDL_RectEquals(const a, b: PSDL_Rect): Boolean; inline; 51 | 52 | {** 53 | * Determine whether two rectangles intersect. 54 | * 55 | * SDL_TRUE if there is an intersection, SDL_FALSE otherwise. 56 | *} 57 | 58 | function SDL_HasIntersection(const a, b: PSDL_Rect): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasIntersection' {$ENDIF} {$ENDIF}; 59 | 60 | {** 61 | * Calculate the intersection of two rectangles. 62 | * 63 | * SDL_TRUE if there is an intersection, SDL_FALSE otherwise. 64 | *} 65 | 66 | function SDL_IntersectRect(const A, B: PSDL_Rect; result: PSDL_Rect): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IntersectRect' {$ENDIF} {$ENDIF}; 67 | 68 | {** 69 | * Calculate the union of two rectangles. 70 | *} 71 | 72 | procedure SDL_UnionRect(const A, B: PSDL_Rect; result: PSDL_Rect) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnionRect' {$ENDIF} {$ENDIF}; 73 | 74 | {** 75 | * Calculate a minimal rectangle enclosing a set of points 76 | * 77 | * SDL_TRUE if any points were within the clipping rect 78 | *} 79 | 80 | function SDL_EnclosePoints(const points: PSDL_Point; count: SInt32; const clip: PSDL_Rect; result: PSDL_Rect): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_EnclosePoints' {$ENDIF} {$ENDIF}; 81 | 82 | {** 83 | * Calculate the intersection of a rectangle and line segment. 84 | * 85 | * SDL_TRUE if there is an intersection, SDL_FALSE otherwise. 86 | *} 87 | 88 | function SDL_IntersectRectAndLine(const rect: PSDL_Rect; X1, Y1, X2, Y2: PInt): TSDL_Bool cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IntersectRectAndLine' {$ENDIF} {$ENDIF}; 89 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlrwops.inc: -------------------------------------------------------------------------------- 1 | //from "sdl_rwops" 2 | 3 | const 4 | {* RWops Types *} 5 | SDL_RWOPS_UNKNOWN = 0; {* Unknown stream type *} 6 | SDL_RWOPS_WINFILE = 1; {* Win32 file *} 7 | SDL_RWOPS_STDFILE = 2; {* Stdio file *} 8 | SDL_RWOPS_JNIFILE = 3; {* Android asset *} 9 | SDL_RWOPS_MEMORY = 4; {* Memory stream *} 10 | SDL_RWOPS_MEMORY_RO = 5; {* Read-Only memory stream *} 11 | 12 | type 13 | PSDL_RWops = ^TSDL_RWops; 14 | 15 | {** 16 | * This is the read/write operation structure -- very basic. 17 | *} 18 | 19 | {** 20 | * Return the size of the file in this rwops, or -1 if unknown 21 | *} 22 | TSize = function(context: PSDL_RWops): SInt64; {$IFNDEF GPC} cdecl; {$ENDIF} 23 | 24 | {** 25 | * Seek to offset relative to whence, one of stdio's whence values: 26 | * RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END 27 | * 28 | * the final offset in the data stream, or -1 on error. 29 | *} 30 | TSeek = function(context: PSDL_RWops; offset: SInt64; whence: SInt32): SInt64; {$IFNDEF GPC} cdecl; {$ENDIF} 31 | 32 | {** 33 | * Read up to maxnum objects each of size size from the data 34 | * stream to the area pointed at by ptr. 35 | * 36 | * the number of objects read, or 0 at error or end of file. 37 | *} 38 | 39 | TRead = function(context: PSDL_RWops; ptr: Pointer; size: size_t; maxnum: size_t): size_t; {$IFNDEF GPC} cdecl; {$ENDIF} 40 | 41 | {** 42 | * Write exactly num objects each of size size from the area 43 | * pointed at by ptr to data stream. 44 | * 45 | * the number of objects written, or 0 at error or end of file. 46 | *} 47 | 48 | TWrite = function(context: PSDL_RWops; const ptr: Pointer; size: size_t; num: size_t): size_t; {$IFNDEF GPC} cdecl; {$ENDIF} 49 | 50 | {** 51 | * Close and free an allocated SDL_RWops structure. 52 | * 53 | * 0 if successful or -1 on write error when flushing data. 54 | *} 55 | 56 | TClose = function(context: PSDL_RWops): SInt32; {$IFNDEF GPC} cdecl; {$ENDIF} 57 | 58 | TStdio = record 59 | autoclose: TSDL_Bool; 60 | fp: file; 61 | end; 62 | 63 | TMem = record 64 | base: PUInt8; 65 | here: PUInt8; 66 | stop: PUInt8; 67 | end; 68 | 69 | TUnknown = record 70 | data1: Pointer; 71 | end; 72 | 73 | TAndroidIO = record 74 | fileNameRef: Pointer; 75 | inputStreamRef: Pointer; 76 | readableByteChannelRef: Pointer; 77 | readMethod: Pointer; 78 | assetFileDescriptorRef: Pointer; 79 | position: LongInt; 80 | size: LongInt; 81 | offset: LongInt; 82 | fd: SInt32; 83 | end; 84 | 85 | TWindowsIOBuffer = record 86 | data: Pointer; 87 | size: size_t; 88 | left: size_t; 89 | end; 90 | 91 | TWindowsIO = record 92 | append: TSDL_Bool; 93 | h: Pointer; 94 | buffer: TWindowsIOBuffer; 95 | end; 96 | 97 | TSDL_RWops = packed record 98 | size: TSize; 99 | seek: TSeek; 100 | read: TRead; 101 | write: TWrite; 102 | close: TClose; 103 | 104 | _type: UInt32; 105 | 106 | case Integer of 107 | 0: (stdio: TStdio); 108 | 1: (mem: TMem); 109 | 2: (unknown: TUnknown); 110 | {$IFDEF ANDROID} 111 | 3: (androidio: TAndroidIO); 112 | {$ENDIF} 113 | {$IFDEF WINDOWS} 114 | 3: (windowsio: TWindowsIO); 115 | {$ENDIF} 116 | end; 117 | 118 | {** 119 | * RWFrom functions 120 | * 121 | * Functions to create SDL_RWops structures from various data streams. 122 | *} 123 | 124 | function SDL_RWFromFile(const _file: PAnsiChar; const mode: PAnsiChar): PSDL_RWops; cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RWFromFile' {$ENDIF} {$ENDIF}; 125 | 126 | {function SDL_RWFromFP(fp: file; autoclose: TSDL_Bool): PSDL_RWops; cdecl; external SDL_LibName;} //don't know if this works 127 | 128 | function SDL_RWFromFP(fp: Pointer; autoclose: TSDL_Bool): PSDL_RWops; cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RWFromFP' {$ENDIF} {$ENDIF}; 129 | 130 | function SDL_RWFromMem(mem: Pointer; size: SInt32): PSDL_RWops; cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RWFromMem' {$ENDIF} {$ENDIF}; 131 | function SDL_RWFromConstMem(const mem: Pointer; size: SInt32): PSDL_RWops; cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RWFromConstMem' {$ENDIF} {$ENDIF}; 132 | 133 | {*RWFrom functions*} 134 | 135 | 136 | function SDL_AllocRW: PSDL_RWops; cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AllocRW' {$ENDIF} {$ENDIF}; 137 | procedure SDL_FreeRW(area: PSDL_RWops); cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FreeRW' {$ENDIF} {$ENDIF}; 138 | 139 | const 140 | RW_SEEK_SET = 0; {**< Seek from the beginning of data *} 141 | RW_SEEK_CUR = 1; {**< Seek relative to current read point *} 142 | RW_SEEK_END = 2; {**< Seek relative to the end of data *} 143 | 144 | {** 145 | * Read/write macros 146 | * 147 | * Macros to easily read and write from an SDL_RWops structure. 148 | *} 149 | 150 | function SDL_RWsize(ctx: PSDL_RWops): SInt64; {$IFNDEF DELPHI} inline; {$ELSE} {$IFDEF DELPHI10UP} inline; {$ENDIF} {$ENDIF} 151 | function SDL_RWseek(ctx: PSDL_RWops; offset: SInt64; whence: SInt32): SInt64; {$IFNDEF DELPHI} inline; {$ELSE} {$IFDEF DELPHI10UP} inline; {$ENDIF} {$ENDIF} 152 | function SDL_RWtell(ctx: PSDL_RWops): SInt64; {$IFNDEF DELPHI} inline; {$ELSE} {$IFDEF DELPHI10UP} inline; {$ENDIF} {$ENDIF} 153 | function SDL_RWread(ctx: PSDL_RWops; ptr: Pointer; size: size_t; n: size_t): size_t; {$IFNDEF DELPHI} inline; {$ELSE} {$IFDEF DELPHI10UP} inline; {$ENDIF} {$ENDIF} 154 | function SDL_RWwrite(ctx: PSDL_RWops; ptr: Pointer; size: size_t; n: size_t): size_t; {$IFNDEF DELPHI} inline; {$ELSE} {$IFDEF DELPHI10UP} inline; {$ENDIF} {$ENDIF} 155 | function SDL_RWclose(ctx: PSDL_RWops): SInt32; {$IFNDEF DELPHI} inline; {$ELSE} {$IFDEF DELPHI10UP} inline; {$ENDIF} {$ENDIF} 156 | { Read/write macros } 157 | 158 | 159 | {** 160 | * Read endian functions 161 | * 162 | * Read an item of the specified endianness and return in native format. 163 | *} 164 | 165 | function SDL_ReadU8(src: PSDL_RWops): UInt8 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadU8' {$ENDIF} {$ENDIF}; 166 | function SDL_ReadLE16(src: PSDL_RWops): UInt16 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadLE16' {$ENDIF} {$ENDIF}; 167 | function SDL_ReadBE16(src: PSDL_RWops): UInt16 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadBE16' {$ENDIF} {$ENDIF}; 168 | function SDL_ReadLE32(src: PSDL_RWops): UInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadLE32' {$ENDIF} {$ENDIF}; 169 | function SDL_ReadBE32(src: PSDL_RWops): UInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadBE32' {$ENDIF} {$ENDIF}; 170 | function SDL_ReadLE64(src: PSDL_RWops): UInt64 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadLE64' {$ENDIF} {$ENDIF}; 171 | function SDL_ReadBE64(src: PSDL_RWops): UInt64 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReadBE64' {$ENDIF} {$ENDIF}; 172 | 173 | {*Read endian functions*} 174 | 175 | {** 176 | * Write endian functions 177 | * 178 | * Write an item of native format to the specified endianness. 179 | *} 180 | 181 | function SDL_WriteU8(dst: PSDL_RWops; value: UInt8): size_t cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteU8' {$ENDIF} {$ENDIF}; 182 | function SDL_WriteLE16(dst: PSDL_RWops; value: UInt16): size_t cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteLE16' {$ENDIF} {$ENDIF}; 183 | function SDL_WriteBE16(dst: PSDL_RWops; value: UInt16): size_t cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteBE16' {$ENDIF} {$ENDIF}; 184 | function SDL_WriteLE32(dst: PSDL_RWops; value: UInt32): size_t cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteLE32' {$ENDIF} {$ENDIF}; 185 | function SDL_WriteBE32(dst: PSDL_RWops; value: UInt32): size_t cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteBE32' {$ENDIF} {$ENDIF}; 186 | function SDL_WriteLE64(dst: PSDL_RWops; value: UInt64): size_t cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteLE64' {$ENDIF} {$ENDIF}; 187 | function SDL_WriteBE64(dst: PSDL_RWops; value: UInt64): size_t cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WriteBE64' {$ENDIF} {$ENDIF}; 188 | { Write endian functions } 189 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlshape.inc: -------------------------------------------------------------------------------- 1 | //from "sdl_shape.h" 2 | 3 | {** SDL_shape.h 4 | * 5 | * Header file for the shaped window API. 6 | *} 7 | const 8 | SDL_NONSHAPEABLE_WINDOW = -1; 9 | SDL_INVALID_SHAPE_ARGUMENT = -2; 10 | SDL_WINDOW_LACKS_SHAPE = -3; 11 | 12 | type 13 | PPSDL_Window = ^PSDL_Window; 14 | PSDL_Window = ^TSDL_Window; 15 | 16 | {** An enum denoting the specific type of contents present in an SDL_WindowShapeParams union. *} 17 | TWindowShapeMode = ({** The default mode, a binarized alpha cutoff of 1. *} 18 | ShapeModeDefault, 19 | {** A binarized alpha cutoff with a given integer value. *} 20 | ShapeModeBinarizeAlpha, 21 | {** A binarized alpha cutoff with a given integer value, but with the opposite comparison. *} 22 | ShapeModeReverseBinarizeAlpha, 23 | {** A color key is applied. *} 24 | ShapeModeColorKey); 25 | 26 | //#define SDL_SHAPEMODEALPHA(mode) (mode == ShapeModeDefault || mode == ShapeModeBinarizeAlpha || mode == ShapeModeReverseBinarizeAlpha) 27 | 28 | {** A union containing parameters for shaped windows. *} 29 | TSDL_WindowShapeParams = record 30 | case Integer of 31 | {** a cutoff alpha value for binarization of the window shape's alpha channel. *} 32 | 0: (binarizationCutoff: UInt8;); 33 | 1: (colorKey: TSDL_Color;); 34 | end; 35 | 36 | {** A struct that tags the SDL_WindowShapeParams union with an enum describing the type of its contents. *} 37 | PSDL_WindowShapeMode = ^TSDL_WindowShapeMode; 38 | TSDL_WindowShapeMode = record 39 | {** The mode of these window-shape parameters. *} 40 | mode: TWindowShapeMode; 41 | {** Window-shape parameters. *} 42 | parameters: TSDL_WindowShapeParams; 43 | end; 44 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlsystem.inc: -------------------------------------------------------------------------------- 1 | // from "SDL_system.h" 2 | 3 | (* Platform specific functions for Windows *) 4 | {$IF DEFINED(WIN32) OR DEFINED(WIN64)} 5 | 6 | {** 7 | * \brief Set a function that is called for every windows message, before TranslateMessage() 8 | *} 9 | Type 10 | TSDL_WindowsMessageHook = Procedure(userdata, hWnd: Pointer; mesage: UInt32; wParam: UInt64; lParam: SInt64); cdecl; 11 | 12 | Procedure SDL_SetWindowsMessageHook(callback: TSDL_WindowsMessageHook; userdata: Pointer); cdecl; 13 | external SDL_LibName; 14 | 15 | {* Returns the D3D9 adapter index that matches the specified display index. 16 | * This adapter index can be passed to IDirect3D9::CreateDevice and controls 17 | * on which monitor a full screen application will appear. 18 | *} 19 | Function SDL_Direct3D9GetAdapterIndex(displayIndex:SInt32):SInt32; 20 | cdecl; external SDL_LibName; 21 | 22 | {* Returns the D3D device associated with a renderer, or NULL if it's not a D3D renderer. 23 | * Once you are done using the device, you should release it to avoid a resource leak. 24 | *} 25 | Type PIDirect3DDevice9 = Pointer; 26 | Function SDL_RenderGetD3D9Device(renderer:PSDL_Renderer):PIDirect3DDevice9; 27 | cdecl; external SDL_LibName; 28 | 29 | {* Returns the DXGI Adapter and Output indices for the specified display index. 30 | * These can be passed to EnumAdapters and EnumOutputs respectively to get the objects 31 | * required to create a DX10 or DX11 device and swap chain. 32 | *} 33 | function SDL_DXGIGetOutputInfo(displayIndex :SInt32; adapterIndex, outputIndex :PSInt32): TSDL_Bool; 34 | cdecl; external SDL_LibName; 35 | 36 | {$IFEND} 37 | 38 | 39 | (* Platform specific functions for WinRT *) 40 | {$IFDEF __WINRT__} 41 | 42 | {** 43 | * \brief WinRT / Windows Phone path types 44 | *} 45 | Type 46 | TSDL_WinRT_Path = ( 47 | 48 | {** \brief The installed app's root directory. 49 | Files here are likely to be read-only. *} 50 | SDL_WINRT_PATH_INSTALLED_LOCATION = 0, 51 | 52 | {** \brief The app's local data store. Files may be written here *} 53 | SDL_WINRT_PATH_LOCAL_FOLDER = 1, 54 | 55 | {** \brief The app's roaming data store. Unsupported on Windows Phone. 56 | Files written here may be copied to other machines via a network 57 | connection. 58 | *} 59 | SDL_WINRT_PATH_ROAMING_FOLDER = 2, 60 | 61 | {** \brief The app's temporary data store. Unsupported on Windows Phone. 62 | Files written here may be deleted at any time. *} 63 | SDL_WINRT_PATH_TEMP_FOLDER = 3 64 | 65 | ); 66 | 67 | 68 | {** 69 | * \brief Retrieves a WinRT defined path on the local file system 70 | * 71 | * \note Documentation on most app-specific path types on WinRT 72 | * can be found on MSDN, at the URL: 73 | * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx 74 | * 75 | * \param pathType The type of path to retrieve. 76 | * \ret A UCS-2 string (16-bit, wide-char) containing the path, or NULL 77 | * if the path is not available for any reason. Not all paths are 78 | * available on all versions of Windows. This is especially true on 79 | * Windows Phone. Check the documentation for the given 80 | * SDL_WinRT_Path for more information on which path types are 81 | * supported where. 82 | *} 83 | Function SDL_WinRTGetFSPathUNICODE(pathType :TSDL_WinRT_Path):PWideChar; 84 | cdecl; external SDL_LibName; 85 | 86 | 87 | {** 88 | * \brief Retrieves a WinRT defined path on the local file system 89 | * 90 | * \note Documentation on most app-specific path types on WinRT 91 | * can be found on MSDN, at the URL: 92 | * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx 93 | * 94 | * \param pathType The type of path to retrieve. 95 | * \ret A UTF-8 string (8-bit, multi-byte) containing the path, or NULL 96 | * if the path is not available for any reason. Not all paths are 97 | * available on all versions of Windows. This is especially true on 98 | * Windows Phone. Check the documentation for the given 99 | * SDL_WinRT_Path for more information on which path types are 100 | * supported where. 101 | *} 102 | Function SDL_WinRTGetFSPathUTF8(pathType :TSDL_WinRT_Path):PChar; 103 | cdecl; external SDL_LibName; 104 | 105 | {$ENDIF} 106 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlsyswm.inc: -------------------------------------------------------------------------------- 1 | // from sdl_syswm.h 2 | 3 | {$IFDEF WINDOWS} 4 | {$DEFINE SDL_VIDEO_DRIVER_WINDOWS} 5 | {$ENDIF} 6 | 7 | {$IF DEFINED (LINUX) OR DEFINED(UNIX) AND NOT DEFINED(ANDROID)} 8 | {$DEFINE SDL_VIDEO_DRIVER_X11} 9 | {$IFEND} 10 | 11 | {$IFDEF DARWIN} 12 | {$DEFINE SDL_VIDEO_DRIVER_COCOA} 13 | {$ENDIF} 14 | 15 | {$IFDEF ANDROID} 16 | {$DEFINE SDL_VIDEO_DRIVER_ANDROID} 17 | {$ENDIF} 18 | 19 | {$IFDEF VIVANTE} 20 | {$DEFINE SDL_VIDEO_DRIVER_VIVANTE} 21 | {$ENDIF} 22 | 23 | 24 | {** 25 | * These are the various supported windowing subsystems 26 | *} 27 | Type 28 | TSDL_SYSWM_TYPE = ( 29 | SDL_SYSWM_UNKNOWN, 30 | SDL_SYSWM_WINDOWS, 31 | SDL_SYSWM_X11, 32 | SDL_SYSWM_DIRECTFB, 33 | SDL_SYSWM_COCOA, 34 | SDL_SYSWM_UIKIT, 35 | SDL_SYSWM_WAYLAND, // Since SDL 2.0.2 36 | SDL_SYSWM_MIR, // Since SDL 2.0.2 37 | SDL_SYSWM_WINRT, // Since SDL 2.0.3 38 | SDL_SYSWM_ANDROID, // Since SDL 2.0.4 39 | SDL_SYSWM_VIVANTE // Since SDL 2.0.5 40 | ); 41 | 42 | /// sdl_syswm.h uses anonymous structs, declared right in SDL_SysWMmsg. 43 | /// Since Pascal does not allow this, we workaround by introducing named types 44 | /// before the proper TSDL_SysWMmsg definition. 45 | {$IFDEF SDL_VIDEO_DRIVER_WINDOWS} 46 | __SYSWM_WINDOWS = record 47 | hwnd: HWND; {**< The window for the message } 48 | msg: uInt; {**< The type of message *} 49 | wParam: WPARAM; {**< WORD message parameter *} 50 | lParam: LPARAM; {**< WORD message parameter *} 51 | end; 52 | {$ENDIF} 53 | {$IFDEF SDL_VIDEO_DRIVER_X11} 54 | __SYSWM_X11 = record 55 | event: {$IFDEF FPC} TXEvent {$ELSE} XEvent {$ENDIF}; 56 | end; 57 | {$ENDIF} 58 | {$IFDEF SDL_VIDEO_DRIVER_DIRECTFB} 59 | __SYSWM_DIRECTFB = record 60 | event: DFBEvent; 61 | end; 62 | {$ENDIF} 63 | {$IFDEF SDL_VIDEO_DRIVER_COCOA} 64 | __SYSWM_COCOA = record 65 | (* No Cocoa window events yet *) 66 | dummy: integer; 67 | end; 68 | {$ENDIF} 69 | {$IFDEF SDL_VIDEO_DRIVER_UIKIT} 70 | __SYSWM_UIKIT = record 71 | (* No UIKit window events yet *) 72 | dummy: integer; 73 | end; 74 | {$ENDIF} 75 | {$IFDEF SDL_VIDEO_DRIVER_VIVANTE} 76 | __SYSWM_VIVANTE = record 77 | (* No Vivante window events yet *) 78 | dummy: integer; 79 | end; 80 | {$ENDIF} 81 | 82 | {** 83 | * The custom event structure. 84 | *} 85 | PSDL_SysWMmsg = ^TSDL_SysWMmsg; 86 | TSDL_SysWMmsg = record 87 | version: TSDL_version; 88 | subsystem: TSDL_SYSWM_TYPE; 89 | {$IFDEF SDL_VIDEO_DRIVER_WINDOWS} 90 | win: __SYSWM_WINDOWS; 91 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_X11} 92 | x11: __SYSWM_X11; 93 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_DIRECTFB} 94 | dfb: __SYSWM_DIRECTFB; 95 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_COCOA} 96 | cocoa: __SYSWM_COCOA; 97 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_UIKIT} 98 | uikit: __SYSWM_UIKIT; 99 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_VIVANTE} 100 | vivante: __SYSWM_VIVANTE; 101 | {$ELSE} 102 | (* Cannot have empty record case *) 103 | dummy: integer; 104 | {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} 105 | end; 106 | 107 | /// Once again, sdl_syswm.h uses anonymous structs, declared right in SDL_SysWMinfo. 108 | /// We workaround by introducing named types before the proper TSDL_SysWMinfo definition. 109 | {$IFDEF SDL_VIDEO_DRIVER_WINDOWS} 110 | __WMINFO_WINDOWS = record 111 | window: HWND; {**< The window handle *} 112 | hdc: HDC; {**< The window device context *} 113 | end; 114 | {$ENDIF} 115 | {$IFDEF SDL_VIDEO_DRIVER_WINRT} // Since SDL 2.0.3 116 | __WMINFO_WINRT = record 117 | window: IInspectable; {**< The WinRT CoreWindow *} 118 | end; 119 | {$ENDIF} 120 | {$IFDEF SDL_VIDEO_DRIVER_X11} 121 | __WMINFO_X11 = record 122 | display: PDisplay; {**< The X11 display *} 123 | window: TWindow; {**< The X11 window *} 124 | end; 125 | {$ENDIF} 126 | {$IFDEF SDL_VIDEO_DRIVER_DIRECTFB} 127 | __WMINFO_DFB = record 128 | dfb: IDirectFB; {**< The directfb main interface *} 129 | window: IDirectFBWindow; {**< The directfb window handle *} 130 | surface: IDirectFBSurface; {**< The directfb client surface *} 131 | end; 132 | {$ENDIF} 133 | {$IFDEF SDL_VIDEO_DRIVER_COCOA} 134 | __WMINFO_COCOA = record 135 | window: NSWindow; {* The Cocoa window *} 136 | end; 137 | {$ENDIF} 138 | {$IFDEF SDL_VIDEO_DRIVER_UIKIT} 139 | __WMINFO_UIKIT = record 140 | window: UIWindow; {* The UIKit window *} 141 | framebuffer: GLuint; {* The GL view's Framebuffer Object. It must be bound when rendering to the screen using GL. *} 142 | colorbuffer: GLuint; {* The GL view's color Renderbuffer Object. It must be bound when SDL_GL_SwapWindow is called. *} 143 | resolveFramebuffer: GLuint; {* The Framebuffer Object which holds the resolve color Renderbuffer, when MSAA is used. *} 144 | end; 145 | {$ENDIF} 146 | {$IFDEF SDL_VIDEO_DRIVER_WAYLAND} // Since SDL 2.0.2 147 | __WMINFO_WAYLAND = record 148 | display: wl_display; {**< Wayland display *} 149 | surface: wl_surface; {**< Wayland surface *} 150 | shell_surface: wl_shell_surface; {**< Wayland shell_surface (window manager handle) *} 151 | end; 152 | {$ENDIF} 153 | {$IFDEF SDL_VIDEO_DRIVER_MIR} // Since SDL 2.0.2 154 | __WMINFO_MIR = record 155 | connection: PMirConnection; {**< Mir display server connection *} 156 | surface: PMirSurface; {**< Mir surface *} 157 | end; 158 | {$ENDIF} 159 | {$IFDEF SDL_VIDEO_DRIVER_ANDROID} 160 | __WMINFO_ANDROID = record 161 | window: Pointer; // PANativeWindow; 162 | surface: Pointer; // PEGLSurface; 163 | end; 164 | {$ENDIF} 165 | {$IFDEF SDL_VIDEO_DRIVER_VIVANTE} 166 | __WMINFO_VIVANTE = record 167 | display: EGLNativeDisplayType; 168 | window: EGLNativeWindowType; 169 | end; 170 | {$ENDIF} 171 | 172 | {** 173 | * The custom window manager information structure. 174 | * 175 | * When this structure is returned, it holds information about which 176 | * low level system it is using, and will be one of SDL_SYSWM_TYPE. 177 | *} 178 | PSDL_SysWMinfo = ^TSDL_SysWMinfo; 179 | TSDL_SysWMinfo = record 180 | version: TSDL_version; 181 | subsystem: TSDL_SYSWM_TYPE; 182 | {$IFDEF SDL_VIDEO_DRIVER_WINDOWS} 183 | win : __WMINFO_WINDOWS; 184 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_WINRT} 185 | winrt : __WMINFO_WINRT; 186 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_X11} 187 | x11 : __WMINFO_X11; 188 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_DIRECTFB} 189 | dfb : __WMINFO_DFB; 190 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_COCOA} 191 | cocoa : __WMINFO_COCOA; 192 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_UIKIT} 193 | uikit : __WMINFO_UIKIT; 194 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_WAYLAND} 195 | wl : __WMINFO_WAYLAND; 196 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_MIR} 197 | mir : __WMINFO_MIR; 198 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_ANDROID} 199 | android: __WMINFO_ANDROID; 200 | {$ELSE} {$IFDEF SDL_VIDEO_DRIVER_VIVANTE} 201 | vivante: __WMINFO_VIVANTE; 202 | {$ELSE} 203 | (* Cannot have empty record case *) 204 | dummy: integer; 205 | {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} 206 | end; 207 | 208 | {* Function prototypes *} 209 | (** 210 | * \brief This function allows access to driver-dependent window information. 211 | * 212 | * \param window The window about which information is being requested 213 | * \param info This structure must be initialized with the SDL version, and is 214 | * then filled in with information about the given window. 215 | * 216 | * \return SDL_TRUE if the function is implemented and the version member of 217 | * the \c info struct is valid, SDL_FALSE otherwise. 218 | * 219 | * You typically use this function like this: 220 | * \code 221 | * SDL_SysWMinfo info; 222 | * SDL_VERSION(&info.version); 223 | * if ( SDL_GetWindowWMInfo(window, &info) ) { ... } 224 | * \endcode 225 | *) 226 | Function SDL_GetWindowWMInfo(window:PSDL_Window; info : PSDL_SysWMinfo):TSDL_bool; cdecl; 227 | external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowWMInfo' {$ENDIF} {$ENDIF}; 228 | -------------------------------------------------------------------------------- /src/include/sdl2/sdltimer.inc: -------------------------------------------------------------------------------- 1 | //from "sdl_timer.h" 2 | 3 | {** 4 | * Get the number of milliseconds since the SDL library initialization. 5 | * 6 | * This value wraps if the program runs for more than ~49 days. 7 | *} 8 | function SDL_GetTicks: UInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTicks' {$ENDIF} {$ENDIF}; 9 | 10 | {** 11 | * Get the current value of the high resolution counter 12 | *} 13 | function SDL_GetPerformanceCounter: UInt64 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPerformanceCounter' {$ENDIF} {$ENDIF}; 14 | 15 | {** 16 | * Get the count per second of the high resolution counter 17 | *} 18 | function SDL_GetPerformanceFrequency: UInt64 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPerformanceFrequency' {$ENDIF} {$ENDIF}; 19 | 20 | {** 21 | * Wait a specified number of milliseconds before returning. 22 | *} 23 | procedure SDL_Delay(ms: UInt32) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_Delay' {$ENDIF} {$ENDIF}; 24 | 25 | {** 26 | * Function prototype for the timer callback function. 27 | * 28 | * The callback function is passed the current timer interval and returns 29 | * the next timer interval. If the returned value is the same as the one 30 | * passed in, the periodic alarm continues, otherwise a new alarm is 31 | * scheduled. If the callback returns 0, the periodic alarm is cancelled. 32 | *} 33 | 34 | type 35 | TSDL_TimerCallback = function(interval: UInt32; param: Pointer): UInt32; cdecl; 36 | 37 | {** 38 | * Definition of the timer ID type. 39 | *} 40 | TSDL_TimerID = SInt32; 41 | 42 | {** 43 | * Add a new timer to the pool of timers already running. 44 | * 45 | * A timer ID, or NULL when an error occurs. 46 | *} 47 | function SDL_AddTimer(interval: UInt32; callback: TSDL_TimerCallback; param: Pointer): TSDL_TimerID cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AddTimer' {$ENDIF} {$ENDIF}; 48 | 49 | {** 50 | * Remove a timer knowing its ID. 51 | * 52 | * A boolean value indicating success or failure. 53 | * 54 | * It is not safe to remove a timer multiple times. 55 | *} 56 | function SDL_RemoveTimer(id: TSDL_TimerID): Boolean cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RemoveTimer' {$ENDIF} {$ENDIF}; 57 | 58 | {** 59 | * Compare SDL ticks values, and return true if A has passed B. 60 | *} 61 | function SDL_TICKS_PASSED(Const A, B:UInt32):Boolean; 62 | -------------------------------------------------------------------------------- /src/include/sdl2/sdltouch.inc: -------------------------------------------------------------------------------- 1 | //from "sdl_touch.h" 2 | 3 | type 4 | PSDL_TouchID = ^TSDL_TouchID; 5 | TSDL_TouchID = SInt64; 6 | 7 | PSDL_FingerID = ^TSDL_FingerID; 8 | TSDL_FingerID = SInt64; 9 | 10 | PSDL_Finger = ^TSDL_Finger; 11 | TSDL_Finger = record 12 | id: TSDL_FingerID; 13 | x: Float; 14 | y: Float; 15 | pressure: Float; 16 | end; 17 | 18 | {* Used as the device ID for mouse events simulated with touch input *} 19 | const 20 | SDL_TOUCH_MOUSEID = UInt32(-1); 21 | 22 | {* Function prototypes *} 23 | 24 | {** 25 | * Get the number of registered touch devices. 26 | *} 27 | function SDL_GetNumTouchDevices: SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumTouchDevices' {$ENDIF} {$ENDIF}; 28 | 29 | {** 30 | * Get the touch ID with the given index, or 0 if the index is invalid. 31 | *} 32 | function SDL_GetTouchDevice(index: SInt32): TSDL_TouchID cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTouchDevice' {$ENDIF} {$ENDIF}; 33 | 34 | {** 35 | * Get the number of active fingers for a given touch device. 36 | *} 37 | function SDL_GetNumTouchFingers(touchID: TSDL_TouchID): SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumTouchFingers' {$ENDIF} {$ENDIF}; 38 | 39 | {** 40 | * Get the finger object of the given touch, with the given index. 41 | *} 42 | function SDL_GetTouchFinger(touchID: TSDL_TouchID; index: SInt32): PSDL_Finger cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTouchFinger' {$ENDIF} {$ENDIF}; 43 | 44 | -------------------------------------------------------------------------------- /src/include/sdl2/sdltype.inc: -------------------------------------------------------------------------------- 1 | //types from SDLtype_s.h / SDL_stdinc.h 2 | type 3 | 4 | TSDL_Bool = (SDL_FALSE,SDL_TRUE); 5 | 6 | DWord = LongWord; 7 | 8 | PUInt8Array = ^TUInt8Array; 9 | PUInt8 = ^UInt8; 10 | PPUInt8 = ^PUInt8; 11 | UInt8 = Byte; 12 | {$EXTERNALSYM UInt8} 13 | TUInt8Array = array [0..MAXINT shr 1] of UInt8; 14 | 15 | PUInt16 = ^UInt16; 16 | UInt16 = word; 17 | {$EXTERNALSYM UInt16} 18 | 19 | PSInt8 = ^SInt8; 20 | SInt8 = Shortint; 21 | {$EXTERNALSYM SInt8} 22 | 23 | PSInt16 = ^SInt16; 24 | SInt16 = smallint; 25 | {$EXTERNALSYM SInt16} 26 | 27 | PUInt32 = ^UInt32; 28 | UInt32 = Cardinal; 29 | {$EXTERNALSYM UInt32} 30 | 31 | PSInt32 = ^SInt32; 32 | SInt32 = LongInt; 33 | {$EXTERNALSYM SInt32} 34 | 35 | PFloat = ^Float; 36 | PInt = ^LongInt; 37 | 38 | PShortInt = ^ShortInt; 39 | 40 | {$IFNDEF Has_Int64} 41 | PUInt64 = ^UInt64; 42 | UInt64 = record 43 | hi: UInt32; 44 | lo: UInt32; 45 | end; 46 | {$EXTERNALSYM UInt64} 47 | 48 | PInt64 = ^Int64; 49 | Int64 = record 50 | hi: UInt32; 51 | lo: UInt32; 52 | end; 53 | {$EXTERNALSYM Int64} 54 | 55 | PSInt64 = ^SInt64; 56 | SInt64 = Int64; 57 | {$EXTERNALSYM SInt64} 58 | {$ELSE} 59 | PSInt64 = ^SInt64; 60 | SInt64 = Int64; 61 | {$ENDIF} 62 | 63 | {$IFNDEF WIN64} 64 | size_t = UInt32; 65 | {$ELSE} 66 | size_t = UInt64; 67 | {$ENDIF} 68 | {$EXTERNALSYM SIZE_T} 69 | 70 | Float = Single; 71 | {$EXTERNALSYM Float} 72 | -------------------------------------------------------------------------------- /src/include/sdl2/sdlversion.inc: -------------------------------------------------------------------------------- 1 | //from "sdl_version.h" 2 | 3 | {** 4 | * Information the version of SDL in use. 5 | * 6 | * Represents the library's version as three levels: major revision 7 | * (increments with massive changes, additions, and enhancements), 8 | * minor revision (increments with backwards-compatible changes to the 9 | * major revision), and patchlevel (increments with fixes to the minor 10 | * revision). 11 | * 12 | * SDL_VERSION 13 | * SDL_GetVersion 14 | *} 15 | type 16 | PSDL_Version = ^TSDL_Version; 17 | TSDL_Version = record 18 | major, {**< major version *} 19 | minor, {**< minor version *} 20 | patch: UInt8; {**< update version *} 21 | end; 22 | 23 | {* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL 24 | *} 25 | const 26 | SDL_MAJOR_VERSION = 2; 27 | SDL_MINOR_VERSION = 0; 28 | SDL_PATCHLEVEL = 4; 29 | 30 | {** 31 | * Macro to determine SDL version program was compiled against. 32 | * 33 | * This macro fills in a SDL_version structure with the version of the 34 | * library you compiled against. This is determined by what header the 35 | * compiler uses. Note that if you dynamically linked the library, you might 36 | * have a slightly newer or older version at runtime. That version can be 37 | * determined with SDL_GetVersion(), which, unlike SDL_VERSION(), 38 | * is not a macro. 39 | * 40 | * x An instance on TSDL_Version to fill with version data. 41 | * 42 | * SDL_version 43 | * SDL_GetVersion 44 | *} 45 | procedure SDL_VERSION(Out x: TSDL_Version); 46 | 47 | {** 48 | * This macro turns the version numbers into a numeric value: 49 | * 50 | * (1,2,3) -> (1203) 51 | * 52 | * 53 | * This assumes that there will never be more than 100 patchlevels. 54 | *} 55 | function SDL_VERSIONNUM(X,Y,Z: UInt32): Cardinal; 56 | 57 | {** 58 | * This is the version number macro for the current SDL version. 59 | *} 60 | function SDL_COMPILEDVERSION: Cardinal; 61 | 62 | {** 63 | * This macro will evaluate to true if compiled with SDL at least X.Y.Z. 64 | *} 65 | function SDL_VERSION_ATLEAST(X,Y,Z: Cardinal): Boolean; 66 | 67 | {** 68 | * Get the version of SDL that is linked against your program. 69 | * 70 | * If you are linking to SDL dynamically, then it is possible that the 71 | * current version will be different than the version you compiled against. 72 | * This function returns the current version, while SDL_VERSION() is a 73 | * macro that tells you what version you compiled with. 74 | * 75 | * 76 | * compiled: TSDL_Version; 77 | * linked: TSDL_Version; 78 | * 79 | * SDL_VERSION(@compiled); 80 | * SDL_GetVersion(@linked); 81 | * WriteLn('We compiled against SDL version: ' + 82 | * IntToStr(compiled.major) + 83 | * IntToStr(compiled.minor) + 84 | * IntToStr(compiled.patch)); 85 | * WriteLn('But we linked against SDL version:' + 86 | * IntToStr(compiled.major) + 87 | * IntToStr(compiled.minor) + 88 | * IntToStr(compiled.patch)); 89 | * 90 | * 91 | * This function may be called safely at any time, even before SDL_Init(). 92 | * 93 | * SDL_VERSION 94 | *} 95 | procedure SDL_GetVersion(ver: PSDL_Version) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetVersion' {$ENDIF} {$ENDIF}; 96 | 97 | {** 98 | * Get the code revision of SDL that is linked against your program. 99 | * 100 | * Returns an arbitrary string (a hash value) uniquely identifying the 101 | * exact revision of the SDL library in use, and is only useful in comparing 102 | * against other revisions. It is NOT an incrementing number. 103 | *} 104 | function SDL_GetRevision: PAnsiChar cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRevision' {$ENDIF} {$ENDIF}; 105 | 106 | {** 107 | * Get the revision number of SDL that is linked against your program. 108 | * 109 | * Returns a number uniquely identifying the exact revision of the SDL 110 | * library in use. It is an incrementing number based on commits to 111 | * hg.libsdl.org. 112 | *} 113 | function SDL_GetRevisionNumber: SInt32 cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRevisionNumber' {$ENDIF} {$ENDIF}; 114 | -------------------------------------------------------------------------------- /src/propulse.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/src/propulse.ico -------------------------------------------------------------------------------- /src/propulse.inc: -------------------------------------------------------------------------------- 1 | {$IFDEF UNIX} 2 | {.$DEFINE DISABLE_FULLSCREEN} // disable broken SDL fullscreen mode 3 | {.$DEFINE LIMIT_KEYBOARD_EVENTS} // fix duplicate keyboard events on Linux with FCITX 4 | {$ENDIF} 5 | 6 | {$IFDEF WINDOWS} 7 | {.$DEFINE MIDI} // enable experimental MIDI input support 8 | {.$DEFINE MIDI_DISPLAY} // test code to show fx on an APC Key25 led matrix 9 | {$ENDIF} 10 | 11 | {$DEFINE BASS} 12 | {$DEFINE SOXR} 13 | 14 | -------------------------------------------------------------------------------- /src/propulse.pas: -------------------------------------------------------------------------------- 1 | program Propulse; 2 | 3 | (* Propulse - a ProTracker clone with an Impulse Tracker-style interface 4 | 5 | Copyright 2016-2019 Joel Toivonen (hukka) 6 | Portions of code adapted from pt2play.c Copyright Olav Sørensen (8bitbubsy) 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | *) 21 | 22 | {$R propulse.res} 23 | {$I propulse.inc} 24 | 25 | uses 26 | {$IFDEF UNIX} cthreads, Classes, SysUtils, {$ENDIF} 27 | MainWindow; 28 | 29 | {$IFDEF UNIX} 30 | // on Unix we need to initialize the threading system before 31 | // using custom callbacks with BASS or we crash! 32 | type 33 | TDummyThread = class(TThread) 34 | procedure Execute; override; 35 | end; 36 | 37 | procedure TDummyThread.Execute; 38 | begin 39 | end; 40 | {$ENDIF} 41 | 42 | begin 43 | {$IFNDEF WINDOWS} 44 | with TDummyThread.Create(False) do 45 | begin 46 | WaitFor; 47 | Free; 48 | end; 49 | {$ENDIF} 50 | 51 | {$IF declared(UseHeapTrace)} 52 | GlobalSkipIfNoLeaks := True; 53 | SetHeapTraceOutput('trace.log'); 54 | {$ENDIF} 55 | 56 | Window := TWindow.Create; 57 | 58 | while not QuitFlag do 59 | Window.ProcessFrame; 60 | 61 | Window.Free; 62 | end. 63 | 64 | -------------------------------------------------------------------------------- /src/propulse.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/src/propulse.res -------------------------------------------------------------------------------- /src/protracker/protracker.filters.pas: -------------------------------------------------------------------------------- 1 | unit ProTracker.Filters; 2 | 3 | interface 4 | 5 | uses 6 | ProTracker.Util, Math; 7 | 8 | const 9 | M_PI_F = 3.1415927; 10 | M_2PI_F = 6.2831855; 11 | 12 | BLEP_ZC = 8; 13 | BLEP_OS = 5; 14 | BLEP_SP = 5; 15 | BLEP_NS = BLEP_ZC * BLEP_OS div BLEP_SP; 16 | BLEP_RNS = 7; // RNS = (2^ > NS) - 1 17 | 18 | 19 | type 20 | TBlep = record 21 | index: Integer; 22 | SamplesLeft: Integer; 23 | Buffer: array [0..BLEP_RNS+1] of Single; 24 | LastValue: Single; 25 | end; 26 | PBlep = ^TBlep; 27 | 28 | TLossyIntegrator = record 29 | Buffer, coeff: array [0..2] of Single; 30 | end; 31 | PLossyIntegrator = ^TLossyIntegrator; 32 | 33 | TLedFilter = record 34 | led: array [0..3] of Single; 35 | end; 36 | PLedFilter = ^TLedFilter; 37 | 38 | TLedFilterCoeff = record 39 | led, 40 | ledFb: Single; 41 | end; 42 | PLedFilterCoeff = ^TLedFilterCoeff; 43 | 44 | function LERP(const x, y, z: Single): Single; inline; 45 | 46 | procedure CalcCoeffLossyIntegrator(sr, hz: Single; filter: PLossyIntegrator); 47 | procedure ClearLossyIntegrator(filter: PLossyIntegrator); 48 | procedure LossyIntegrator(filter: PLossyIntegrator; _in, _out: PArrayOfSingle); 49 | procedure LossyIntegratorHighPass(filter: PLossyIntegrator; _in, _out: PArrayOfSingle); 50 | 51 | procedure CalcCoeffLED(sr, hz: Single; filter: PLedFilterCoeff); 52 | procedure ClearLEDFilter(filter: PLedFilter); 53 | procedure LossyIntegratorLED(filterC: PLedFilterCoeff; filter: PLedFilter; _in, _out: PArrayOfSingle); 54 | 55 | procedure BlepAdd(b: PBlep; offset, amplitude: Single); 56 | function BlepRun(b: PBlep): Single; 57 | procedure ZeroBlep(blep: PBlep); 58 | 59 | 60 | implementation 61 | 62 | 63 | const 64 | blepData: array [0..47] of Single {uint32} = ( 65 | 0.999541342258453, 0.999348163604736, 66 | 0.999368846416473, 0.999342143535614, 67 | 0.998741447925568, 0.996602177619934, 68 | 0.991206049919128, 0.979688584804535, 69 | 0.957750201225281, 0.919731378555298, 70 | 0.859310805797577, 0.770949482917786, 71 | 0.651933908462524, 0.504528284072876, 72 | 0.337462306022644, 0.165925666689873, 73 | 0.0095284366980195, -0.111686512827873, 74 | -0.182304441928864, -0.196162655949593, 75 | -0.158864945173264, -0.0870067626237869, 76 | -0.00398899614810944, 0.0664445236325264, 77 | 0.106864832341671, 0.1107332482934, 78 | 0.0833132192492485, 0.0386873260140419, 79 | -0.00589261529967189, -0.0361355841159821, 80 | -0.0450748540461063, -0.0342595390975475, 81 | -0.0117176882922649, 0.0121078062802553, 82 | 0.0286061242222786, 0.0337694510817528, 83 | 0.0286726150661707, 0.0179044492542744, 84 | 0.00698232231661677, 0,0,0,0,0,0,0,0,0 85 | ); 86 | 87 | 88 | function LERP(const x, y, z: Single): Single; 89 | begin 90 | Result := ((x) + ((y) - (x)) * (z)); 91 | end; 92 | 93 | 94 | // ========================================================================== 95 | // Filters 96 | // ========================================================================== 97 | 98 | procedure CalcCoeffLossyIntegrator(sr, hz: Single; filter: PLossyIntegrator); 99 | begin 100 | if (sr = 0) or (hz = 0) then Exit; 101 | filter^.coeff[0] := Tan(M_PI_F * hz / sr); 102 | filter^.coeff[1] := 1.0 / (1.0 + filter^.coeff[0]); 103 | end; 104 | 105 | procedure ClearLossyIntegrator(filter: PLossyIntegrator); 106 | begin 107 | filter^.buffer[0] := 0.0; 108 | filter^.buffer[1] := 0.0; 109 | end; 110 | 111 | procedure LossyIntegrator(filter: PLossyIntegrator; _in, _out: PArrayOfSingle); 112 | var 113 | output: Single; 114 | begin 115 | // left channel low-pass 116 | output := (filter^.coeff[0] * _in[0] + filter^.buffer[0]) * filter^.coeff[1]; 117 | filter^.buffer[0] := filter^.coeff[0] * (_in[0] - output) + output + 1e-10; 118 | _out[0] := output; 119 | 120 | // right channel low-pass 121 | output := (filter^.coeff[0] * _in[1] + filter^.buffer[1]) * filter^.coeff[1]; 122 | filter^.buffer[1] := filter^.coeff[0] * (_in[1] - output) + output + 1e-10; 123 | _out[1] := output; 124 | end; 125 | 126 | procedure LossyIntegratorHighPass(filter: PLossyIntegrator; _in, _out: PArrayOfSingle); 127 | var 128 | low: array[0..1] of Single; 129 | begin 130 | lossyIntegrator(filter, _in, @low); 131 | _out[0] := _in[0] - low[0]; 132 | _out[1] := _in[1] - low[1]; 133 | end; 134 | 135 | // ========================================================================== 136 | // LED filter 137 | // ========================================================================== 138 | 139 | procedure CalcCoeffLED(sr, hz: Single; filter: PLedFilterCoeff); 140 | begin 141 | if (hz < (sr / 2.0)) then 142 | filter^.led := (M_2PI_F * hz) / sr 143 | else 144 | filter^.led := 1.0; 145 | 146 | // Fb := 0.125 : Q ~= 1/sqrt(2) (Butterworth) 147 | filter^.ledFb := 0.125 + (0.125 / (1.0 - filter^.led)); 148 | end; 149 | 150 | procedure ClearLEDFilter(filter: PLedFilter); 151 | begin 152 | filter^.led[0] := 0.0; 153 | filter^.led[1] := 0.0; 154 | filter^.led[2] := 0.0; 155 | filter^.led[3] := 0.0; 156 | end; 157 | 158 | procedure LossyIntegratorLED(filterC: PLedFilterCoeff; filter: PLedFilter; _in, _out: PArrayOfSingle); 159 | begin 160 | // left channel 161 | filter^.led[0] := filter^.led[0] + 162 | (filterC^.led * (_in[0] - filter^.led[0]) + 163 | filterC^.ledFb * (filter^.led[0] - filter^.led[1]) + 1e-10); 164 | filter^.led[1] := filter^.led[1] + 165 | (filterC^.led * (filter^.led[0] - filter^.led[1]) + 1e-10); 166 | _out[0] := filter^.led[1]; 167 | 168 | // right channel 169 | filter^.led[2] := filter^.led[2] + 170 | (filterC^.led * (_in[1] - filter^.led[2]) + 171 | filterC^.ledFb * (filter^.led[2] - filter^.led[3]) + 1e-10); 172 | filter^.led[3] := filter^.led[3] + 173 | (filterC^.led * (filter^.led[2] - filter^.led[3]) + 1e-10); 174 | _out[1] := filter^.led[3]; 175 | end; 176 | 177 | // ========================================================================== 178 | // BLEP 179 | // ========================================================================== 180 | 181 | procedure BlepAdd(b: PBlep; offset, amplitude: Single); 182 | var 183 | n, i, blepSrc: Integer; 184 | f: Single; 185 | begin 186 | i := Trunc(offset * BLEP_SP); 187 | blepSrc := i + BLEP_OS; 188 | f := (offset * BLEP_SP) - i; 189 | 190 | i := b^.Index; 191 | n := BLEP_NS; 192 | 193 | while n > 0 do 194 | begin 195 | b^.Buffer[i] := b^.Buffer[i] + 196 | (amplitude * LERP(blepData[blepSrc], blepData[blepSrc+1], f)); 197 | 198 | Inc(blepSrc, BLEP_SP); 199 | Inc(i); 200 | i := i and BLEP_RNS; // i = 0..7 201 | Dec(n); 202 | end; 203 | 204 | b^.SamplesLeft := BLEP_NS; 205 | end; 206 | 207 | function BlepRun(b: PBlep): Single; 208 | begin 209 | Result := b^.Buffer[b^.Index]; 210 | b^.Buffer[b^.Index] := 0.0; 211 | Inc(b^.Index); 212 | b^.Index := b^.Index and BLEP_RNS; 213 | Dec(b^.SamplesLeft); 214 | end; 215 | 216 | procedure ZeroBlep(blep: PBlep); 217 | var 218 | j: Integer; 219 | begin 220 | blep^.index := 0; 221 | blep^.SamplesLeft := 0; 222 | blep^.LastValue := 0.0; 223 | for j := 0 to High(blep^.Buffer) do 224 | blep^.Buffer[j] := 0.0; 225 | end; 226 | 227 | end. 228 | -------------------------------------------------------------------------------- /src/protracker/protracker.messaging.pas: -------------------------------------------------------------------------------- 1 | unit ProTracker.Messaging; 2 | 3 | {$mode delphi} 4 | 5 | interface 6 | 7 | uses 8 | Classes, SysUtils, 9 | SDL2; 10 | 11 | function RegisterMessages(Message, Count: Integer): Integer; 12 | function GetMessageValue(const InputEvent: TSDL_Event): Integer; inline; 13 | procedure PostMessagePtr(EventType: Byte; Data: Pointer); 14 | procedure PostMessageValue(EventType: Byte; Data: Integer); 15 | 16 | 17 | implementation 18 | 19 | uses 20 | MainWindow; 21 | 22 | 23 | function RegisterMessages(Message, Count: Integer): Integer; 24 | var 25 | i: Integer; 26 | begin 27 | Result := Integer(SDL_RegisterEvents(Count)); 28 | end; 29 | 30 | function GetMessageValue(const InputEvent: TSDL_Event): Integer; inline; 31 | begin 32 | Result := PtrInt(InputEvent.user.data1); 33 | end; 34 | 35 | procedure PostMessagePtr(EventType: Byte; Data: Pointer); 36 | var 37 | event: TSDL_Event; 38 | begin 39 | event.type_ := SDL_USEREVENT; 40 | event.user.code := EventType; 41 | event.user.data1 := Data; 42 | SDL_PushEvent(@event); 43 | end; 44 | 45 | procedure PostMessageValue(EventType: Byte; Data: Integer); 46 | var 47 | event: TSDL_Event; 48 | begin 49 | event.type_ := SDL_USEREVENT; 50 | event.user.code := EventType; 51 | event.user.data1 := Pointer(Data); 52 | SDL_PushEvent(@event); 53 | end; 54 | 55 | end. 56 | 57 | -------------------------------------------------------------------------------- /src/protracker/protracker.paula.pas: -------------------------------------------------------------------------------- 1 | unit ProTracker.Paula; 2 | 3 | interface 4 | 5 | uses 6 | ProTracker.Util, 7 | ProTracker.Sample; 8 | 9 | type 10 | TPaulaVoice = class 11 | public 12 | Enabled, 13 | HasSound: Boolean; 14 | 15 | SRC_DAT: PArrayOfShortInt; 16 | SRC_LEN: uint32; 17 | SRC_VOL: Single; 18 | 19 | DMA_DAT: PArrayOfShortInt; 20 | DMA_LEN: uint32; 21 | DMA_POS: uint32; 22 | 23 | f_OutputFreq: Single; 24 | PANL, PANR: Single; 25 | 26 | DELTA, LASTDELTA: Single; 27 | FRAC, LASTFRAC: Single; 28 | 29 | Volume: Single; 30 | 31 | Sample, 32 | QueuedSample: SmallInt; 33 | QueuedOffset: Cardinal; 34 | PlayPos: Integer; 35 | 36 | constructor Create(OutputFreq: Word); 37 | 38 | procedure Kill; 39 | procedure TurnOffDMA; inline; 40 | procedure RestartDMA; 41 | procedure SetData(NewSample: Byte; NewOffset: Integer); inline; 42 | procedure SetDataPtr(const src: PArrayOfShortInt); inline; 43 | procedure SetLength(len: Cardinal); inline; 44 | procedure SetPeriod(period: Word); inline; 45 | procedure SetVolume(vol: Word); 46 | end; 47 | 48 | var 49 | EmptySample: TSample; 50 | 51 | 52 | implementation 53 | 54 | uses 55 | Math, 56 | ProTracker.Player; 57 | 58 | 59 | constructor TPaulaVoice.Create(OutputFreq: Word); 60 | begin 61 | inherited Create; 62 | 63 | f_OutputFreq := OutputFreq; 64 | 65 | SRC_DAT := nil; 66 | DMA_DAT := nil; 67 | 68 | Sample := -1; 69 | QueuedSample := Sample; 70 | end; 71 | 72 | procedure TPaulaVoice.TurnOffDMA; 73 | begin 74 | Volume := 0; 75 | end; 76 | 77 | procedure TPaulaVoice.RestartDMA; 78 | begin 79 | FRAC := 0.0; 80 | DMA_POS := 0; 81 | DMA_DAT := SRC_DAT; 82 | DMA_LEN := Max(SRC_LEN, 2); 83 | PlayPos := -1; 84 | Sample := QueuedSample; 85 | 86 | if (Enabled) and (Sample >= 0) and (Sample < Module.Samples.Count) then 87 | begin 88 | with Module.Samples[Sample] do 89 | begin 90 | Age := 6;//Trunc(6 * SRC_VOL) + 2; 91 | PlayPos := QueuedOffset; 92 | if PlayPos > MaxPlayPos then 93 | MaxPlayPos := PlayPos; 94 | end; 95 | end; 96 | 97 | QueuedOffset := 0; 98 | Volume := SRC_VOL; 99 | end; 100 | 101 | procedure TPaulaVoice.Kill; 102 | begin 103 | DMA_DAT := nil; 104 | SRC_DAT := nil; 105 | SRC_LEN := 0; 106 | DMA_LEN := 0; 107 | DMA_POS := 0; 108 | SRC_VOL := 0; 109 | DELTA := 0; 110 | FRAC := 0; 111 | LASTDELTA := 0; 112 | LASTFRAC := 0; 113 | Volume := 0; 114 | PlayPos := -1; 115 | Sample := -1; 116 | QueuedSample := -1; 117 | HasSound := False; 118 | end; 119 | 120 | procedure TPaulaVoice.SetPeriod(period: Word); 121 | begin 122 | // This is what really happens on Paula on a real Amiga 123 | // on normal video modes. Tested and confirmed by 8bitbubsy! 124 | if period > 0 then 125 | begin 126 | DELTA := (PAULA_PAL_CLK / Max(period, 113)) / f_outputFreq; 127 | HasSound := True; 128 | end 129 | else 130 | begin 131 | DELTA := 0.0; 132 | HasSound := False; 133 | end; 134 | if LASTDELTA = 0.0 then 135 | LASTDELTA := DELTA; 136 | end; 137 | 138 | procedure TPaulaVoice.SetVolume(vol: Word); 139 | var 140 | SV: Single; 141 | begin 142 | if (vol and (1 shl 6)) <> 0 then 143 | vol := $0040 144 | else 145 | vol := vol and $003F; 146 | 147 | SV := SRC_VOL; 148 | SRC_VOL := vol * (1.0 / 64.0); 149 | if SV <> SRC_VOL then 150 | Volume := SRC_VOL; 151 | end; 152 | 153 | procedure TPaulaVoice.SetLength(len: Cardinal); 154 | begin 155 | SRC_LEN := len * 2; 156 | end; 157 | 158 | procedure TPaulaVoice.SetData(NewSample: Byte; NewOffset: Integer); 159 | begin 160 | if NewOffset >= 0 then 161 | begin 162 | SRC_DAT := @Module.Samples[NewSample].Data[NewOffset]; 163 | QueuedSample := NewSample; 164 | QueuedOffset := NewOffset; 165 | end 166 | else 167 | SetDataPtr(nil); 168 | end; 169 | 170 | procedure TPaulaVoice.SetDataPtr(const src: PArrayOfShortInt); 171 | begin 172 | if src <> nil then 173 | SRC_DAT := src 174 | else 175 | begin 176 | SRC_DAT := @EmptySample.Data[0]; 177 | QueuedSample := -1; 178 | end; 179 | end; 180 | 181 | initialization 182 | 183 | EmptySample := TSample.Create; 184 | EmptySample.Resize(16); 185 | 186 | finalization 187 | 188 | EmptySample.Free; 189 | 190 | end. 191 | -------------------------------------------------------------------------------- /src/protracker/protracker.player.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/src/protracker/protracker.player.pas -------------------------------------------------------------------------------- /src/screen/screen.config.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/src/screen/screen.config.pas -------------------------------------------------------------------------------- /src/screen/screen.help.pas: -------------------------------------------------------------------------------- 1 | unit Screen.Help; 2 | 3 | interface 4 | 5 | uses 6 | Classes, Types, 7 | TextMode, CWE.Core, CWE.Widgets.Text; 8 | 9 | type 10 | THelpScreen = class(TCWEScreen) 11 | private 12 | Timestamp: LongInt; 13 | public 14 | Memo: TCWEMemo; 15 | 16 | function HelpFileName: String; 17 | function LoadHelp: Boolean; 18 | procedure Show(Context: AnsiString); reintroduce; 19 | 20 | constructor Create(var Con: TConsole; const sCaption, sID: AnsiString); override; 21 | end; 22 | 23 | var 24 | Help: THelpScreen; 25 | 26 | 27 | implementation 28 | 29 | uses 30 | SysUtils, 31 | ProTracker.Util, 32 | Layout; 33 | 34 | 35 | constructor THelpScreen.Create; 36 | begin 37 | inherited; 38 | 39 | RegisterScreenLayout(Self, 'HelpViewer'); 40 | 41 | Memo := TCWEMemo.Create(Self, '', 'Text View', 42 | Types.Rect(1, 1, Console.Width-2, Console.Height-1), True); 43 | 44 | Memo.ColorFore := 6; 45 | ActiveControl := Memo; 46 | 47 | LoadLayout(Self); 48 | 49 | LoadHelp; 50 | end; 51 | 52 | function THelpScreen.HelpFileName: String; 53 | begin 54 | Result := GetDataFile('help.txt'); 55 | end; 56 | 57 | function THelpScreen.LoadHelp: Boolean; 58 | var 59 | sl: TStringList; 60 | S: AnsiString; 61 | Fn: String; 62 | begin 63 | Memo.Lines.Clear; 64 | 65 | Fn := HelpFileName; 66 | Result := FileExists(Fn); 67 | 68 | if Result then 69 | begin 70 | Timestamp := FileAge(Fn); 71 | sl := TStringList.Create; 72 | sl.LoadFromFile(Fn); 73 | for S in sl do 74 | if Copy(S, 1, 1) <> ';' then 75 | Memo.Add(S); 76 | sl.Free; 77 | end 78 | else 79 | begin 80 | Timestamp := 0; 81 | Memo.Add('

Help file not found!'); 82 | end; 83 | end; 84 | 85 | procedure THelpScreen.Show(Context: AnsiString); 86 | var 87 | Fn: String; 88 | begin 89 | Fn := HelpFileName; 90 | if (FileExists(Fn)) and (FileAge(Fn) <> Timestamp) then 91 | LoadHelp; // reload help file if it's been modified 92 | 93 | if Memo.JumpToSection(Context) < 0 then 94 | Memo.ScrollTo(0); 95 | ChangeScreen(TCWEScreen(Self)); 96 | end; 97 | 98 | end. 99 | 100 | -------------------------------------------------------------------------------- /src/screen/screen.log.pas: -------------------------------------------------------------------------------- 1 | unit Screen.Log; 2 | 3 | interface 4 | 5 | uses 6 | Classes, Types, 7 | TextMode, CWE.Core, CWE.Widgets.Text; 8 | 9 | type 10 | TLogScreen = class(TCWEScreen) 11 | private 12 | LastLoggedEmpty: Boolean; 13 | public 14 | Memo: TCWEMemo; 15 | 16 | procedure Log(const Msg: AnsiString); 17 | 18 | constructor Create(var Con: TConsole; const sCaption, sID: AnsiString); override; 19 | end; 20 | 21 | var 22 | LogScreen: TLogScreen; 23 | 24 | 25 | implementation 26 | 27 | uses 28 | Layout, ProTracker.Util, SysUtils, MainWindow; 29 | 30 | procedure TLogScreen.Log(const Msg: AnsiString); 31 | var 32 | S: AnsiString; 33 | begin 34 | if Msg = '-' then 35 | begin 36 | if not LastLoggedEmpty then 37 | Memo.Add(StringOfChar(#205, Memo.Width+1), 15); 38 | LastLoggedEmpty := True; 39 | end 40 | else 41 | if Copy(Msg, 1, 1) = '$' then 42 | begin 43 | S := Copy(Msg, 3, Length(Msg)); 44 | if not ((LastLoggedEmpty) and (S = '')) then 45 | Memo.Add(' ' + S, StrToInt(Copy(Msg, 1, 2))); 46 | end 47 | else 48 | begin 49 | S := Msg; 50 | if not ((LastLoggedEmpty) and (S = '')) then 51 | Memo.Add(' ' + S); 52 | end; 53 | 54 | LastLoggedEmpty := (S = ''); 55 | if Active then 56 | begin 57 | Paint; 58 | Window.ProcessFrame; 59 | end; 60 | end; 61 | 62 | constructor TLogScreen.Create(var Con: TConsole; const sCaption, sID: AnsiString); 63 | begin 64 | inherited; 65 | 66 | RegisterScreenLayout(Self, 'MessageLog'); 67 | 68 | Memo := TCWEMemo.Create(Self, '', 'Message Log', 69 | Types.Rect(1, 1, Console.Width-2, Console.Height-1), True); 70 | RegisterLayoutControl(Memo, CTRLKIND_BOX, False, True, True); 71 | Memo.ColorFore := 12; 72 | 73 | ActiveControl := Memo; 74 | 75 | LoadLayout(Self); 76 | OnLog := Self.Log; 77 | end; 78 | 79 | 80 | end. 81 | -------------------------------------------------------------------------------- /src/screen/screen.splash.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hukkax/Propulse/8d4f62b810f01e2f5b2aceb81140b66767d35868/src/screen/screen.splash.pas --------------------------------------------------------------------------------