gosu 0.15.2 → 1.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/dependencies/SDL/include/SDL.h +138 -0
- data/dependencies/SDL/include/SDL_assert.h +293 -0
- data/dependencies/SDL/include/SDL_atomic.h +295 -0
- data/dependencies/SDL/include/SDL_audio.h +859 -0
- data/dependencies/SDL/include/SDL_bits.h +121 -0
- data/dependencies/SDL/include/SDL_blendmode.h +123 -0
- data/dependencies/SDL/include/SDL_clipboard.h +71 -0
- data/dependencies/SDL/include/SDL_config.h +55 -0
- data/dependencies/SDL/include/SDL_config_android.h +182 -0
- data/dependencies/SDL/include/SDL_config_iphoneos.h +207 -0
- data/dependencies/SDL/include/SDL_config_macosx.h +266 -0
- data/dependencies/SDL/include/SDL_config_minimal.h +85 -0
- data/dependencies/SDL/include/SDL_config_os2.h +188 -0
- data/dependencies/SDL/include/SDL_config_pandora.h +135 -0
- data/dependencies/SDL/include/SDL_config_psp.h +165 -0
- data/dependencies/SDL/include/SDL_config_windows.h +288 -0
- data/dependencies/SDL/include/SDL_config_winrt.h +243 -0
- data/dependencies/SDL/include/SDL_config_wiz.h +149 -0
- data/dependencies/SDL/include/SDL_copying.h +20 -0
- data/dependencies/SDL/include/SDL_cpuinfo.h +299 -0
- data/dependencies/SDL/include/SDL_egl.h +1676 -0
- data/dependencies/SDL/include/SDL_endian.h +263 -0
- data/dependencies/SDL/include/SDL_error.h +112 -0
- data/dependencies/SDL/include/SDL_events.h +827 -0
- data/dependencies/SDL/include/SDL_filesystem.h +136 -0
- data/dependencies/SDL/include/SDL_gamecontroller.h +541 -0
- data/dependencies/SDL/include/SDL_gesture.h +87 -0
- data/dependencies/SDL/include/SDL_haptic.h +1247 -0
- data/dependencies/SDL/include/SDL_hints.h +1578 -0
- data/dependencies/SDL/include/SDL_joystick.h +499 -0
- data/dependencies/SDL/include/SDL_keyboard.h +217 -0
- data/dependencies/SDL/include/SDL_keycode.h +351 -0
- data/dependencies/SDL/include/SDL_loadso.h +81 -0
- data/dependencies/SDL/include/SDL_locale.h +101 -0
- data/dependencies/SDL/include/SDL_log.h +211 -0
- data/dependencies/SDL/include/SDL_main.h +180 -0
- data/dependencies/SDL/include/SDL_messagebox.h +146 -0
- data/dependencies/SDL/include/SDL_metal.h +117 -0
- data/dependencies/SDL/include/SDL_misc.h +75 -0
- data/dependencies/SDL/include/SDL_mouse.h +302 -0
- data/dependencies/SDL/include/SDL_mutex.h +251 -0
- data/dependencies/SDL/include/SDL_name.h +33 -0
- data/dependencies/SDL/include/SDL_opengl.h +2183 -0
- data/dependencies/SDL/include/SDL_opengl_glext.h +11180 -0
- data/dependencies/SDL/include/SDL_opengles.h +39 -0
- data/dependencies/SDL/include/SDL_opengles2.h +52 -0
- data/dependencies/SDL/include/SDL_opengles2_gl2.h +621 -0
- data/dependencies/SDL/include/SDL_opengles2_gl2ext.h +2050 -0
- data/dependencies/SDL/include/SDL_opengles2_gl2platform.h +30 -0
- data/dependencies/SDL/include/SDL_opengles2_khrplatform.h +282 -0
- data/dependencies/SDL/include/SDL_pixels.h +479 -0
- data/dependencies/SDL/include/SDL_platform.h +198 -0
- data/dependencies/SDL/include/SDL_power.h +75 -0
- data/dependencies/SDL/include/SDL_quit.h +58 -0
- data/dependencies/SDL/include/SDL_rect.h +174 -0
- data/dependencies/SDL/include/SDL_render.h +1158 -0
- data/dependencies/SDL/include/SDL_revision.h +2 -0
- data/dependencies/SDL/include/SDL_rwops.h +283 -0
- data/dependencies/SDL/include/SDL_scancode.h +413 -0
- data/dependencies/SDL/include/SDL_sensor.h +267 -0
- data/dependencies/SDL/include/SDL_shape.h +144 -0
- data/dependencies/SDL/include/SDL_stdinc.h +647 -0
- data/dependencies/SDL/include/SDL_surface.h +563 -0
- data/dependencies/SDL/include/SDL_system.h +325 -0
- data/dependencies/SDL/include/SDL_syswm.h +354 -0
- data/dependencies/SDL/include/SDL_test.h +69 -0
- data/dependencies/SDL/include/SDL_test_assert.h +105 -0
- data/dependencies/SDL/include/SDL_test_common.h +218 -0
- data/dependencies/SDL/include/SDL_test_compare.h +69 -0
- data/dependencies/SDL/include/SDL_test_crc32.h +124 -0
- data/dependencies/SDL/include/SDL_test_font.h +81 -0
- data/dependencies/SDL/include/SDL_test_fuzzer.h +384 -0
- data/dependencies/SDL/include/SDL_test_harness.h +134 -0
- data/dependencies/SDL/include/SDL_test_images.h +78 -0
- data/dependencies/SDL/include/SDL_test_log.h +67 -0
- data/dependencies/SDL/include/SDL_test_md5.h +129 -0
- data/dependencies/SDL/include/SDL_test_memory.h +63 -0
- data/dependencies/SDL/include/SDL_test_random.h +115 -0
- data/dependencies/SDL/include/SDL_thread.h +366 -0
- data/dependencies/SDL/include/SDL_timer.h +115 -0
- data/dependencies/SDL/include/SDL_touch.h +102 -0
- data/dependencies/SDL/include/SDL_types.h +29 -0
- data/dependencies/SDL/include/SDL_version.h +162 -0
- data/dependencies/SDL/include/SDL_video.h +1282 -0
- data/dependencies/SDL/include/SDL_vulkan.h +276 -0
- data/dependencies/SDL/include/begin_code.h +166 -0
- data/dependencies/SDL/include/close_code.h +40 -0
- data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
- data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
- data/dependencies/SDL_sound/SDL_sound.c +795 -0
- data/dependencies/SDL_sound/SDL_sound.h +725 -0
- data/dependencies/SDL_sound/SDL_sound_aiff.c +537 -0
- data/dependencies/SDL_sound/SDL_sound_au.c +352 -0
- data/dependencies/SDL_sound/SDL_sound_coreaudio.c +747 -0
- data/dependencies/SDL_sound/SDL_sound_flac.c +182 -0
- data/dependencies/SDL_sound/SDL_sound_internal.h +304 -0
- data/dependencies/SDL_sound/SDL_sound_modplug.c +228 -0
- data/dependencies/SDL_sound/SDL_sound_mp3.c +184 -0
- data/dependencies/SDL_sound/SDL_sound_raw.c +164 -0
- data/dependencies/SDL_sound/SDL_sound_shn.c +1309 -0
- data/dependencies/SDL_sound/SDL_sound_voc.c +550 -0
- data/dependencies/SDL_sound/SDL_sound_vorbis.c +223 -0
- data/dependencies/SDL_sound/SDL_sound_wav.c +783 -0
- data/dependencies/SDL_sound/dr_flac.h +5906 -0
- data/dependencies/SDL_sound/dr_mp3.h +2832 -0
- data/dependencies/SDL_sound/libmodplug/fastmix.c +1748 -0
- data/dependencies/SDL_sound/libmodplug/libmodplug.h +1001 -0
- data/dependencies/SDL_sound/libmodplug/load_669.c +188 -0
- data/dependencies/SDL_sound/libmodplug/load_abc.c +4725 -0
- data/dependencies/SDL_sound/libmodplug/load_amf.c +403 -0
- data/dependencies/SDL_sound/libmodplug/load_ams.c +587 -0
- data/dependencies/SDL_sound/libmodplug/load_dbm.c +357 -0
- data/dependencies/SDL_sound/libmodplug/load_dmf.c +531 -0
- data/dependencies/SDL_sound/libmodplug/load_dsm.c +232 -0
- data/dependencies/SDL_sound/libmodplug/load_far.c +253 -0
- data/dependencies/SDL_sound/libmodplug/load_it.c +796 -0
- data/dependencies/SDL_sound/libmodplug/load_mdl.c +488 -0
- data/dependencies/SDL_sound/libmodplug/load_med.c +757 -0
- data/dependencies/SDL_sound/libmodplug/load_mid.c +1405 -0
- data/dependencies/SDL_sound/libmodplug/load_mod.c +269 -0
- data/dependencies/SDL_sound/libmodplug/load_mt2.c +546 -0
- data/dependencies/SDL_sound/libmodplug/load_mtm.c +142 -0
- data/dependencies/SDL_sound/libmodplug/load_okt.c +192 -0
- data/dependencies/SDL_sound/libmodplug/load_pat.c +1143 -0
- data/dependencies/SDL_sound/libmodplug/load_pat.h +25 -0
- data/dependencies/SDL_sound/libmodplug/load_psm.c +350 -0
- data/dependencies/SDL_sound/libmodplug/load_ptm.c +204 -0
- data/dependencies/SDL_sound/libmodplug/load_s3m.c +325 -0
- data/dependencies/SDL_sound/libmodplug/load_stm.c +180 -0
- data/dependencies/SDL_sound/libmodplug/load_ult.c +206 -0
- data/dependencies/SDL_sound/libmodplug/load_umx.c +51 -0
- data/dependencies/SDL_sound/libmodplug/load_xm.c +554 -0
- data/dependencies/SDL_sound/libmodplug/mmcmp.c +382 -0
- data/dependencies/SDL_sound/libmodplug/modplug.c +170 -0
- data/dependencies/SDL_sound/libmodplug/modplug.h +90 -0
- data/dependencies/SDL_sound/libmodplug/snd_dsp.c +301 -0
- data/dependencies/SDL_sound/libmodplug/snd_flt.c +63 -0
- data/dependencies/SDL_sound/libmodplug/snd_fx.c +2350 -0
- data/dependencies/SDL_sound/libmodplug/sndfile.c +1169 -0
- data/dependencies/SDL_sound/libmodplug/sndmix.c +1034 -0
- data/dependencies/SDL_sound/libmodplug/tables.h +371 -0
- data/{src/stb_vorbis.c → dependencies/SDL_sound/stb_vorbis.h} +143 -78
- data/dependencies/al_soft/AL/al.h +655 -0
- data/dependencies/al_soft/AL/alc.h +270 -0
- data/dependencies/al_soft/AL/alext.h +585 -0
- data/dependencies/al_soft/AL/efx-creative.h +3 -0
- data/dependencies/al_soft/AL/efx-presets.h +402 -0
- data/dependencies/al_soft/AL/efx.h +762 -0
- data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
- data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
- data/{src → dependencies/stb}/stb_image.h +330 -127
- data/{src → dependencies/stb}/stb_image_write.h +156 -85
- data/{src → dependencies/stb}/stb_truetype.h +192 -69
- data/{src → dependencies/utf8proc}/utf8proc.c +0 -0
- data/{src → dependencies/utf8proc}/utf8proc.h +0 -0
- data/{src → dependencies/utf8proc}/utf8proc_data.h +0 -0
- data/ext/gosu/extconf.rb +56 -22
- data/{Gosu → include/Gosu}/Audio.hpp +6 -8
- data/{Gosu → include/Gosu}/AutoLink.hpp +0 -0
- data/include/Gosu/Bitmap.hpp +100 -0
- data/{Gosu → include/Gosu}/Buttons.hpp +94 -35
- data/{Gosu → include/Gosu}/Channel.h +0 -0
- data/{Gosu → include/Gosu}/Color.h +0 -0
- data/{Gosu → include/Gosu}/Color.hpp +0 -0
- data/{Gosu → include/Gosu}/Directories.hpp +0 -0
- data/{Gosu → include/Gosu}/Font.h +0 -0
- data/{Gosu → include/Gosu}/Font.hpp +0 -0
- data/{Gosu → include/Gosu}/Fwd.hpp +0 -0
- data/{Gosu → include/Gosu}/Gosu.h +3 -0
- data/{Gosu → include/Gosu}/Gosu.hpp +0 -0
- data/{Gosu → include/Gosu}/Graphics.hpp +0 -0
- data/{Gosu → include/Gosu}/GraphicsBase.hpp +0 -0
- data/{Gosu → include/Gosu}/IO.hpp +0 -0
- data/{Gosu → include/Gosu}/Image.h +0 -0
- data/{Gosu → include/Gosu}/Image.hpp +7 -6
- data/{Gosu → include/Gosu}/ImageData.hpp +0 -0
- data/{Gosu → include/Gosu}/Input.hpp +30 -15
- data/{Gosu → include/Gosu}/Inspection.hpp +0 -0
- data/{Gosu → include/Gosu}/Math.hpp +0 -0
- data/{Gosu → include/Gosu}/Platform.hpp +0 -0
- data/{Gosu → include/Gosu}/Sample.h +0 -0
- data/{Gosu → include/Gosu}/Song.h +0 -0
- data/{Gosu → include/Gosu}/Text.hpp +0 -0
- data/{Gosu → include/Gosu}/TextInput.h +0 -0
- data/{Gosu → include/Gosu}/TextInput.hpp +0 -0
- data/{Gosu → include/Gosu}/Timing.hpp +0 -0
- data/{Gosu → include/Gosu}/Utility.hpp +1 -1
- data/{Gosu → include/Gosu}/Version.hpp +0 -0
- data/{Gosu → include/Gosu}/Window.h +2 -0
- data/{Gosu → include/Gosu}/Window.hpp +21 -13
- data/lib/OpenAL32.dll +0 -0
- data/lib/SDL2.dll +0 -0
- data/lib/gosu.rb +0 -3
- data/lib/gosu/patches.rb +0 -9
- data/lib/gosu/swig_patches.rb +3 -2
- data/lib/libmpg123.dll +0 -0
- data/lib/libsndfile.dll +0 -0
- data/lib64/OpenAL32.dll +0 -0
- data/lib64/SDL2.dll +0 -0
- data/lib64/libmpg123.dll +0 -0
- data/lib64/libsndfile.dll +0 -0
- data/rdoc/gosu.rb +95 -20
- data/src/Audio.cpp +50 -224
- data/src/AudioFile.hpp +17 -37
- data/src/AudioFileAudioToolbox.cpp +237 -0
- data/src/AudioFileSDLSound.cpp +147 -0
- data/src/AudioImpl.cpp +3 -12
- data/src/AudioImpl.hpp +3 -1
- data/src/Bitmap.cpp +85 -83
- data/src/BitmapIO.cpp +52 -58
- data/src/Constants.cpp +80 -33
- data/src/Font.cpp +3 -1
- data/src/GosuWrapper.cpp +19 -0
- data/src/Graphics.cpp +7 -4
- data/src/Image.cpp +13 -16
- data/src/Input.cpp +408 -159
- data/src/LargeImageData.cpp +1 -1
- data/src/MarkupParser.cpp +2 -1
- data/src/RubyGosu.cxx +349 -83
- data/src/RubyGosu.h +4 -2
- data/src/TexChunk.cpp +1 -1
- data/src/TextBuilder.cpp +3 -1
- data/src/Texture.cpp +1 -1
- data/src/TrueTypeFont.cpp +1 -1
- data/src/Utility.cpp +11 -7
- data/src/Window.cpp +30 -39
- data/src/WindowWrapper.cpp +28 -0
- metadata +207 -52
- data/Gosu/Bitmap.hpp +0 -113
- data/src/AudioToolboxFile.hpp +0 -210
- data/src/OggFile.hpp +0 -92
- data/src/SndFile.hpp +0 -174
- data/src/WinMain.cpp +0 -64
@@ -0,0 +1,269 @@
|
|
1
|
+
/*
|
2
|
+
* This source code is public domain.
|
3
|
+
*
|
4
|
+
* Authors: Olivier Lapicque <olivierl@jps.net>,
|
5
|
+
* Adam Goode <adam@evdebs.org> (endian and char fixes for PPC)
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include "libmodplug.h"
|
9
|
+
#include "tables.h"
|
10
|
+
|
11
|
+
//////////////////////////////////////////////////////////
|
12
|
+
// ProTracker / NoiseTracker MOD/NST file support
|
13
|
+
|
14
|
+
void CSoundFile_ConvertModCommand(CSoundFile *_this, MODCOMMAND *m)
|
15
|
+
//-----------------------------------------------------
|
16
|
+
{
|
17
|
+
UINT command = m->command, param = m->param;
|
18
|
+
|
19
|
+
switch(command)
|
20
|
+
{
|
21
|
+
case 0x00: if (param) command = CMD_ARPEGGIO; break;
|
22
|
+
case 0x01: command = CMD_PORTAMENTOUP; break;
|
23
|
+
case 0x02: command = CMD_PORTAMENTODOWN; break;
|
24
|
+
case 0x03: command = CMD_TONEPORTAMENTO; break;
|
25
|
+
case 0x04: command = CMD_VIBRATO; break;
|
26
|
+
case 0x05: command = CMD_TONEPORTAVOL; if (param & 0xF0) param &= 0xF0; break;
|
27
|
+
case 0x06: command = CMD_VIBRATOVOL; if (param & 0xF0) param &= 0xF0; break;
|
28
|
+
case 0x07: command = CMD_TREMOLO; break;
|
29
|
+
case 0x08: command = CMD_PANNING8; break;
|
30
|
+
case 0x09: command = CMD_OFFSET; break;
|
31
|
+
case 0x0A: command = CMD_VOLUMESLIDE; if (param & 0xF0) param &= 0xF0; break;
|
32
|
+
case 0x0B: command = CMD_POSITIONJUMP; break;
|
33
|
+
case 0x0C: command = CMD_VOLUME; break;
|
34
|
+
case 0x0D: command = CMD_PATTERNBREAK; param = ((param >> 4) * 10) + (param & 0x0F); break;
|
35
|
+
case 0x0E: command = CMD_MODCMDEX; break;
|
36
|
+
case 0x0F: command = (param <= (UINT)((_this->m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) ? 0x1F : 0x20)) ? CMD_SPEED : CMD_TEMPO;
|
37
|
+
if ((param == 0xFF) && (_this->m_nSamples == 15)) command = 0; break;
|
38
|
+
// Extension for XM extended effects
|
39
|
+
case 'G' - 55: command = CMD_GLOBALVOLUME; break;
|
40
|
+
case 'H' - 55: command = CMD_GLOBALVOLSLIDE; if (param & 0xF0) param &= 0xF0; break;
|
41
|
+
case 'K' - 55: command = CMD_KEYOFF; break;
|
42
|
+
case 'L' - 55: command = CMD_SETENVPOSITION; break;
|
43
|
+
case 'M' - 55: command = CMD_CHANNELVOLUME; break;
|
44
|
+
case 'N' - 55: command = CMD_CHANNELVOLSLIDE; break;
|
45
|
+
case 'P' - 55: command = CMD_PANNINGSLIDE; if (param & 0xF0) param &= 0xF0; break;
|
46
|
+
case 'R' - 55: command = CMD_RETRIG; break;
|
47
|
+
case 'T' - 55: command = CMD_TREMOR; break;
|
48
|
+
case 'X' - 55: command = CMD_XFINEPORTAUPDOWN; break;
|
49
|
+
case 'Y' - 55: command = CMD_PANBRELLO; break;
|
50
|
+
case 'Z' - 55: command = CMD_MIDI; break;
|
51
|
+
default: command = 0;
|
52
|
+
}
|
53
|
+
m->command = command;
|
54
|
+
m->param = param;
|
55
|
+
}
|
56
|
+
|
57
|
+
|
58
|
+
#pragma pack(1)
|
59
|
+
|
60
|
+
typedef struct _MODSAMPLE
|
61
|
+
{
|
62
|
+
CHAR name[22];
|
63
|
+
WORD length;
|
64
|
+
BYTE finetune;
|
65
|
+
BYTE volume;
|
66
|
+
WORD loopstart;
|
67
|
+
WORD looplen;
|
68
|
+
} MODSAMPLE, *PMODSAMPLE;
|
69
|
+
|
70
|
+
typedef struct _MODMAGIC
|
71
|
+
{
|
72
|
+
BYTE nOrders;
|
73
|
+
BYTE nRestartPos;
|
74
|
+
BYTE Orders[128];
|
75
|
+
char Magic[4]; // changed from CHAR
|
76
|
+
} MODMAGIC, *PMODMAGIC;
|
77
|
+
|
78
|
+
#pragma pack()
|
79
|
+
|
80
|
+
static BOOL IsMagic(LPCSTR s1, LPCSTR s2)
|
81
|
+
{
|
82
|
+
return ((*(DWORD *)s1) == (*(DWORD *)s2)) ? TRUE : FALSE;
|
83
|
+
}
|
84
|
+
|
85
|
+
|
86
|
+
BOOL CSoundFile_ReadMod(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLength)
|
87
|
+
//---------------------------------------------------------------
|
88
|
+
{
|
89
|
+
char s[1024]; // changed from CHAR
|
90
|
+
DWORD dwMemPos, dwTotalSampleLen;
|
91
|
+
PMODMAGIC pMagic;
|
92
|
+
UINT nErr;
|
93
|
+
|
94
|
+
if ((!lpStream) || (dwMemLength < 0x600)) return FALSE;
|
95
|
+
dwMemPos = 20;
|
96
|
+
_this->m_nSamples = 31;
|
97
|
+
_this->m_nChannels = 4;
|
98
|
+
pMagic = (PMODMAGIC)(lpStream+dwMemPos+sizeof(MODSAMPLE)*31);
|
99
|
+
// Check Mod Magic
|
100
|
+
SDL_memcpy(s, pMagic->Magic, 4);
|
101
|
+
if ((IsMagic(s, "M.K.")) || (IsMagic(s, "M!K!"))
|
102
|
+
|| (IsMagic(s, "M&K!")) || (IsMagic(s, "N.T."))) _this->m_nChannels = 4; else
|
103
|
+
if ((IsMagic(s, "CD81")) || (IsMagic(s, "OKTA"))) _this->m_nChannels = 8; else
|
104
|
+
if ((s[0]=='F') && (s[1]=='L') && (s[2]=='T') && (s[3]>='4') && (s[3]<='9')) _this->m_nChannels = s[3] - '0'; else
|
105
|
+
if ((s[0]>='2') && (s[0]<='9') && (s[1]=='C') && (s[2]=='H') && (s[3]=='N')) _this->m_nChannels = s[0] - '0'; else
|
106
|
+
if ((s[0]=='1') && (s[1]>='0') && (s[1]<='9') && (s[2]=='C') && (s[3]=='H')) _this->m_nChannels = s[1] - '0' + 10; else
|
107
|
+
if ((s[0]=='2') && (s[1]>='0') && (s[1]<='9') && (s[2]=='C') && (s[3]=='H')) _this->m_nChannels = s[1] - '0' + 20; else
|
108
|
+
if ((s[0]=='3') && (s[1]>='0') && (s[1]<='2') && (s[2]=='C') && (s[3]=='H')) _this->m_nChannels = s[1] - '0' + 30; else
|
109
|
+
if ((s[0]=='T') && (s[1]=='D') && (s[2]=='Z') && (s[3]>='4') && (s[3]<='9')) _this->m_nChannels = s[3] - '0'; else
|
110
|
+
if (IsMagic(s,"16CN")) _this->m_nChannels = 16; else
|
111
|
+
if (IsMagic(s,"32CN")) _this->m_nChannels = 32; else _this->m_nSamples = 15;
|
112
|
+
// Load Samples
|
113
|
+
nErr = 0;
|
114
|
+
dwTotalSampleLen = 0;
|
115
|
+
for (UINT i=1; i<=_this->m_nSamples; i++)
|
116
|
+
{
|
117
|
+
PMODSAMPLE pms = (PMODSAMPLE)(lpStream+dwMemPos);
|
118
|
+
MODINSTRUMENT *psmp = &_this->Ins[i];
|
119
|
+
UINT loopstart, looplen;
|
120
|
+
|
121
|
+
psmp->uFlags = 0;
|
122
|
+
psmp->nLength = bswapBE16(pms->length)*2;
|
123
|
+
dwTotalSampleLen += psmp->nLength;
|
124
|
+
psmp->nFineTune = MOD2XMFineTune(pms->finetune & 0x0F);
|
125
|
+
psmp->nVolume = 4*pms->volume;
|
126
|
+
if (psmp->nVolume > 256) { psmp->nVolume = 256; nErr++; }
|
127
|
+
psmp->nGlobalVol = 64;
|
128
|
+
psmp->nPan = 128;
|
129
|
+
loopstart = bswapBE16(pms->loopstart)*2;
|
130
|
+
looplen = bswapBE16(pms->looplen)*2;
|
131
|
+
// Fix loops
|
132
|
+
if ((looplen > 2) && (loopstart+looplen > psmp->nLength)
|
133
|
+
&& (loopstart/2+looplen <= psmp->nLength))
|
134
|
+
{
|
135
|
+
loopstart /= 2;
|
136
|
+
}
|
137
|
+
psmp->nLoopStart = loopstart;
|
138
|
+
psmp->nLoopEnd = loopstart + looplen;
|
139
|
+
if (psmp->nLength < 4) psmp->nLength = 0;
|
140
|
+
if (psmp->nLength)
|
141
|
+
{
|
142
|
+
if (psmp->nLoopStart >= psmp->nLength) { psmp->nLoopStart = psmp->nLength-1; }
|
143
|
+
if (psmp->nLoopEnd > psmp->nLength) { psmp->nLoopEnd = psmp->nLength; }
|
144
|
+
|
145
|
+
if ((psmp->nLoopStart > psmp->nLoopEnd) || (psmp->nLoopEnd <= 8)
|
146
|
+
|| (psmp->nLoopEnd - psmp->nLoopStart <= 4))
|
147
|
+
{
|
148
|
+
psmp->nLoopStart = 0;
|
149
|
+
psmp->nLoopEnd = 0;
|
150
|
+
}
|
151
|
+
if (psmp->nLoopEnd > psmp->nLoopStart)
|
152
|
+
{
|
153
|
+
psmp->uFlags |= CHN_LOOP;
|
154
|
+
}
|
155
|
+
}
|
156
|
+
dwMemPos += sizeof(MODSAMPLE);
|
157
|
+
}
|
158
|
+
if ((_this->m_nSamples == 15) && (dwTotalSampleLen > dwMemLength * 4)) return FALSE;
|
159
|
+
pMagic = (PMODMAGIC)(lpStream+dwMemPos);
|
160
|
+
dwMemPos += sizeof(MODMAGIC);
|
161
|
+
if (_this->m_nSamples == 15) dwMemPos -= 4;
|
162
|
+
SDL_memset(_this->Order, 0,sizeof(_this->Order));
|
163
|
+
SDL_memcpy(_this->Order, pMagic->Orders, 128);
|
164
|
+
|
165
|
+
UINT nbp, nbpbuggy, nbpbuggy2, norders;
|
166
|
+
|
167
|
+
norders = pMagic->nOrders;
|
168
|
+
if ((!norders) || (norders > 0x80))
|
169
|
+
{
|
170
|
+
norders = 0x80;
|
171
|
+
while ((norders > 1) && (!_this->Order[norders-1])) norders--;
|
172
|
+
}
|
173
|
+
nbpbuggy = 0;
|
174
|
+
nbpbuggy2 = 0;
|
175
|
+
nbp = 0;
|
176
|
+
for (UINT iord=0; iord<128; iord++)
|
177
|
+
{
|
178
|
+
UINT i = _this->Order[iord];
|
179
|
+
if ((i < 0x80) && (nbp <= i))
|
180
|
+
{
|
181
|
+
nbp = i+1;
|
182
|
+
if (iord<norders) nbpbuggy = nbp;
|
183
|
+
}
|
184
|
+
if (i >= nbpbuggy2) nbpbuggy2 = i+1;
|
185
|
+
}
|
186
|
+
for (UINT iend=norders; iend<MAX_ORDERS; iend++) _this->Order[iend] = 0xFF;
|
187
|
+
norders--;
|
188
|
+
_this->m_nRestartPos = pMagic->nRestartPos;
|
189
|
+
if (_this->m_nRestartPos >= 0x78) _this->m_nRestartPos = 0;
|
190
|
+
if (_this->m_nRestartPos + 1 >= (UINT)norders) _this->m_nRestartPos = 0;
|
191
|
+
if (!nbp) return FALSE;
|
192
|
+
DWORD dwWowTest = dwTotalSampleLen+dwMemPos;
|
193
|
+
if ((IsMagic(pMagic->Magic, "M.K.")) && (dwWowTest + nbp*8*256 == dwMemLength)) _this->m_nChannels = 8;
|
194
|
+
if ((nbp != nbpbuggy) && (dwWowTest + nbp*_this->m_nChannels*256 != dwMemLength))
|
195
|
+
{
|
196
|
+
if (dwWowTest + nbpbuggy*_this->m_nChannels*256 == dwMemLength) nbp = nbpbuggy;
|
197
|
+
else nErr += 8;
|
198
|
+
} else
|
199
|
+
if ((nbpbuggy2 > nbp) && (dwWowTest + nbpbuggy2*_this->m_nChannels*256 == dwMemLength))
|
200
|
+
{
|
201
|
+
nbp = nbpbuggy2;
|
202
|
+
}
|
203
|
+
if ((dwWowTest < 0x600) || (dwWowTest > dwMemLength)) nErr += 8;
|
204
|
+
if ((_this->m_nSamples == 15) && (nErr >= 16)) return FALSE;
|
205
|
+
// Default settings
|
206
|
+
_this->m_nType = MOD_TYPE_MOD;
|
207
|
+
_this->m_nDefaultSpeed = 6;
|
208
|
+
_this->m_nDefaultTempo = 125;
|
209
|
+
_this->m_nMinPeriod = 14 << 2;
|
210
|
+
_this->m_nMaxPeriod = 3424 << 2;
|
211
|
+
// Setting channels pan
|
212
|
+
for (UINT ich=0; ich<_this->m_nChannels; ich++)
|
213
|
+
{
|
214
|
+
_this->ChnSettings[ich].nVolume = 64;
|
215
|
+
if (_this->gdwSoundSetup & SNDMIX_MAXDEFAULTPAN)
|
216
|
+
_this->ChnSettings[ich].nPan = (((ich&3)==1) || ((ich&3)==2)) ? 256 : 0;
|
217
|
+
else
|
218
|
+
_this->ChnSettings[ich].nPan = (((ich&3)==1) || ((ich&3)==2)) ? 0xC0 : 0x40;
|
219
|
+
}
|
220
|
+
// Reading channels
|
221
|
+
for (UINT ipat=0; ipat<nbp; ipat++)
|
222
|
+
{
|
223
|
+
if (ipat < MAX_PATTERNS)
|
224
|
+
{
|
225
|
+
if ((_this->Patterns[ipat] = CSoundFile_AllocatePattern(64, _this->m_nChannels)) == NULL) break;
|
226
|
+
_this->PatternSize[ipat] = 64;
|
227
|
+
if (dwMemPos + _this->m_nChannels*256 >= dwMemLength) break;
|
228
|
+
MODCOMMAND *m = _this->Patterns[ipat];
|
229
|
+
LPCBYTE p = lpStream + dwMemPos;
|
230
|
+
for (UINT j=_this->m_nChannels*64; j; m++,p+=4,j--)
|
231
|
+
{
|
232
|
+
BYTE A0=p[0], A1=p[1], A2=p[2], A3=p[3];
|
233
|
+
UINT n = ((((UINT)A0 & 0x0F) << 8) | (A1));
|
234
|
+
if ((n) && (n != 0xFFF)) m->note = CSoundFile_GetNoteFromPeriod(_this, n << 2);
|
235
|
+
m->instr = ((UINT)A2 >> 4) | (A0 & 0x10);
|
236
|
+
m->command = A2 & 0x0F;
|
237
|
+
m->param = A3;
|
238
|
+
if ((m->command) || (m->param)) CSoundFile_ConvertModCommand(_this, m);
|
239
|
+
}
|
240
|
+
}
|
241
|
+
dwMemPos += _this->m_nChannels*256;
|
242
|
+
}
|
243
|
+
// Reading instruments
|
244
|
+
DWORD dwErrCheck = 0;
|
245
|
+
for (UINT ismp=1; ismp<=_this->m_nSamples; ismp++) if (_this->Ins[ismp].nLength)
|
246
|
+
{
|
247
|
+
LPSTR p = (LPSTR)(lpStream+dwMemPos);
|
248
|
+
UINT flags = 0;
|
249
|
+
if (dwMemPos + 5 >= dwMemLength) break;
|
250
|
+
if (!SDL_strncasecmp(p, "ADPCM", 5))
|
251
|
+
{
|
252
|
+
flags = 3;
|
253
|
+
p += 5;
|
254
|
+
dwMemPos += 5;
|
255
|
+
}
|
256
|
+
DWORD dwSize = CSoundFile_ReadSample(_this, &_this->Ins[ismp], flags, p, dwMemLength - dwMemPos);
|
257
|
+
if (dwSize)
|
258
|
+
{
|
259
|
+
dwMemPos += dwSize;
|
260
|
+
dwErrCheck++;
|
261
|
+
}
|
262
|
+
}
|
263
|
+
#ifdef MODPLUG_TRACKER
|
264
|
+
return TRUE;
|
265
|
+
#else
|
266
|
+
return (dwErrCheck) ? TRUE : FALSE;
|
267
|
+
#endif
|
268
|
+
}
|
269
|
+
|
@@ -0,0 +1,546 @@
|
|
1
|
+
#include "libmodplug.h"
|
2
|
+
|
3
|
+
#pragma pack(1)
|
4
|
+
|
5
|
+
typedef struct _MT2FILEHEADER
|
6
|
+
{
|
7
|
+
DWORD dwMT20; // 0x3032544D "MT20"
|
8
|
+
DWORD dwSpecial;
|
9
|
+
WORD wVersion;
|
10
|
+
CHAR szTrackerName[32]; // "MadTracker 2.0"
|
11
|
+
CHAR szSongName[64];
|
12
|
+
WORD nOrders;
|
13
|
+
WORD wRestart;
|
14
|
+
WORD wPatterns;
|
15
|
+
WORD wChannels;
|
16
|
+
WORD wSamplesPerTick;
|
17
|
+
BYTE bTicksPerLine;
|
18
|
+
BYTE bLinesPerBeat;
|
19
|
+
DWORD fulFlags; // b0=packed patterns
|
20
|
+
WORD wInstruments;
|
21
|
+
WORD wSamples;
|
22
|
+
BYTE Orders[256];
|
23
|
+
} MT2FILEHEADER;
|
24
|
+
|
25
|
+
typedef struct _MT2PATTERN
|
26
|
+
{
|
27
|
+
WORD wLines;
|
28
|
+
DWORD wDataLen;
|
29
|
+
} MT2PATTERN;
|
30
|
+
|
31
|
+
typedef struct _MT2COMMAND
|
32
|
+
{
|
33
|
+
BYTE note; // 0=nothing, 97=note off
|
34
|
+
BYTE instr;
|
35
|
+
BYTE vol;
|
36
|
+
BYTE pan;
|
37
|
+
BYTE fxcmd;
|
38
|
+
BYTE fxparam1;
|
39
|
+
BYTE fxparam2;
|
40
|
+
} MT2COMMAND;
|
41
|
+
|
42
|
+
typedef struct _MT2DRUMSDATA
|
43
|
+
{
|
44
|
+
WORD wDrumPatterns;
|
45
|
+
WORD wDrumSamples[8];
|
46
|
+
BYTE DrumPatternOrder[256];
|
47
|
+
} MT2DRUMSDATA;
|
48
|
+
|
49
|
+
typedef struct _MT2AUTOMATION
|
50
|
+
{
|
51
|
+
DWORD dwFlags;
|
52
|
+
DWORD dwEffectId;
|
53
|
+
DWORD nEnvPoints;
|
54
|
+
} MT2AUTOMATION;
|
55
|
+
|
56
|
+
typedef struct _MT2INSTRUMENT
|
57
|
+
{
|
58
|
+
DWORD dwDataLen;
|
59
|
+
WORD wSamples;
|
60
|
+
BYTE GroupsMapping[96];
|
61
|
+
BYTE bVibType;
|
62
|
+
BYTE bVibSweep;
|
63
|
+
BYTE bVibDepth;
|
64
|
+
BYTE bVibRate;
|
65
|
+
WORD wFadeOut;
|
66
|
+
WORD wNNA;
|
67
|
+
WORD wInstrFlags;
|
68
|
+
WORD wEnvFlags1;
|
69
|
+
WORD wEnvFlags2;
|
70
|
+
} MT2INSTRUMENT;
|
71
|
+
|
72
|
+
typedef struct _MT2ENVELOPE
|
73
|
+
{
|
74
|
+
BYTE nFlags;
|
75
|
+
BYTE nPoints;
|
76
|
+
BYTE nSustainPos;
|
77
|
+
BYTE nLoopStart;
|
78
|
+
BYTE nLoopEnd;
|
79
|
+
BYTE bReserved[3];
|
80
|
+
BYTE EnvData[64];
|
81
|
+
} MT2ENVELOPE;
|
82
|
+
|
83
|
+
typedef struct _MT2SYNTH
|
84
|
+
{
|
85
|
+
BYTE nSynthId;
|
86
|
+
BYTE nFxId;
|
87
|
+
WORD wCutOff;
|
88
|
+
BYTE nResonance;
|
89
|
+
BYTE nAttack;
|
90
|
+
BYTE nDecay;
|
91
|
+
BYTE bReserved[25];
|
92
|
+
} MT2SYNTH;
|
93
|
+
|
94
|
+
typedef struct _MT2SAMPLE
|
95
|
+
{
|
96
|
+
DWORD dwDataLen;
|
97
|
+
DWORD dwLength;
|
98
|
+
DWORD dwFrequency;
|
99
|
+
BYTE nQuality;
|
100
|
+
BYTE nChannels;
|
101
|
+
BYTE nFlags;
|
102
|
+
BYTE nLoop;
|
103
|
+
DWORD dwLoopStart;
|
104
|
+
DWORD dwLoopEnd;
|
105
|
+
WORD wVolume;
|
106
|
+
BYTE nPan;
|
107
|
+
BYTE nBaseNote;
|
108
|
+
WORD wSamplesPerBeat;
|
109
|
+
} MT2SAMPLE;
|
110
|
+
|
111
|
+
typedef struct _MT2GROUP
|
112
|
+
{
|
113
|
+
BYTE nSmpNo;
|
114
|
+
BYTE nVolume; // 0-128
|
115
|
+
BYTE nFinePitch;
|
116
|
+
BYTE Reserved[5];
|
117
|
+
} MT2GROUP;
|
118
|
+
|
119
|
+
#pragma pack()
|
120
|
+
|
121
|
+
|
122
|
+
static VOID ConvertMT2Command(CSoundFile *that, MODCOMMAND *m, const MT2COMMAND *p)
|
123
|
+
//---------------------------------------------------------------------------
|
124
|
+
{
|
125
|
+
// Note
|
126
|
+
m->note = 0;
|
127
|
+
if (p->note) m->note = (p->note > 96) ? 0xFF : p->note+12;
|
128
|
+
// Instrument
|
129
|
+
m->instr = p->instr;
|
130
|
+
// Volume Column
|
131
|
+
if ((p->vol >= 0x10) && (p->vol <= 0x90))
|
132
|
+
{
|
133
|
+
m->volcmd = VOLCMD_VOLUME;
|
134
|
+
m->vol = (p->vol - 0x10) >> 1;
|
135
|
+
} else
|
136
|
+
if ((p->vol >= 0xA0) && (p->vol <= 0xAF))
|
137
|
+
{
|
138
|
+
m->volcmd = VOLCMD_VOLSLIDEDOWN;
|
139
|
+
m->vol = (p->vol & 0x0f);
|
140
|
+
} else
|
141
|
+
if ((p->vol >= 0xB0) && (p->vol <= 0xBF))
|
142
|
+
{
|
143
|
+
m->volcmd = VOLCMD_VOLSLIDEUP;
|
144
|
+
m->vol = (p->vol & 0x0f);
|
145
|
+
} else
|
146
|
+
if ((p->vol >= 0xC0) && (p->vol <= 0xCF))
|
147
|
+
{
|
148
|
+
m->volcmd = VOLCMD_FINEVOLDOWN;
|
149
|
+
m->vol = (p->vol & 0x0f);
|
150
|
+
} else
|
151
|
+
if ((p->vol >= 0xD0) && (p->vol <= 0xDF))
|
152
|
+
{
|
153
|
+
m->volcmd = VOLCMD_FINEVOLUP;
|
154
|
+
m->vol = (p->vol & 0x0f);
|
155
|
+
} else
|
156
|
+
{
|
157
|
+
m->volcmd = 0;
|
158
|
+
m->vol = 0;
|
159
|
+
}
|
160
|
+
// Effects
|
161
|
+
m->command = 0;
|
162
|
+
m->param = 0;
|
163
|
+
if ((p->fxcmd) || (p->fxparam1) || (p->fxparam2))
|
164
|
+
{
|
165
|
+
if (!p->fxcmd)
|
166
|
+
{
|
167
|
+
m->command = p->fxparam2;
|
168
|
+
m->param = p->fxparam1;
|
169
|
+
CSoundFile_ConvertModCommand(that, m);
|
170
|
+
} else
|
171
|
+
{
|
172
|
+
// TODO: MT2 Effects
|
173
|
+
}
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
177
|
+
|
178
|
+
BOOL CSoundFile_ReadMT2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
179
|
+
//-----------------------------------------------------------
|
180
|
+
{
|
181
|
+
const MT2FILEHEADER *pfh = (MT2FILEHEADER *)lpStream;
|
182
|
+
DWORD dwMemPos, dwDrumDataPos, dwExtraDataPos;
|
183
|
+
UINT nDrumDataLen, nExtraDataLen;
|
184
|
+
const MT2DRUMSDATA *pdd;
|
185
|
+
const MT2INSTRUMENT *InstrMap[255];
|
186
|
+
const MT2SAMPLE *SampleMap[256];
|
187
|
+
|
188
|
+
if ((!lpStream) || (dwMemLength < sizeof(MT2FILEHEADER))
|
189
|
+
|| (pfh->dwMT20 != 0x3032544D)
|
190
|
+
|| (pfh->wVersion < 0x0200) || (pfh->wVersion >= 0x0300)
|
191
|
+
|| (pfh->wChannels < 4) || (pfh->wChannels > 64)) return FALSE;
|
192
|
+
pdd = NULL;
|
193
|
+
_this->m_nType = MOD_TYPE_MT2;
|
194
|
+
_this->m_nChannels = pfh->wChannels;
|
195
|
+
_this->m_nRestartPos = pfh->wRestart;
|
196
|
+
_this->m_nDefaultSpeed = pfh->bTicksPerLine;
|
197
|
+
_this->m_nDefaultTempo = 125;
|
198
|
+
if ((pfh->wSamplesPerTick > 100) && (pfh->wSamplesPerTick < 5000))
|
199
|
+
{
|
200
|
+
_this->m_nDefaultTempo = 110250 / pfh->wSamplesPerTick;
|
201
|
+
}
|
202
|
+
for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
|
203
|
+
{
|
204
|
+
_this->Order[iOrd] = (BYTE)((iOrd < pfh->nOrders) ? pfh->Orders[iOrd] : 0xFF);
|
205
|
+
}
|
206
|
+
dwMemPos = sizeof(MT2FILEHEADER);
|
207
|
+
nDrumDataLen = *(WORD *)(lpStream + dwMemPos);
|
208
|
+
dwDrumDataPos = dwMemPos + 2;
|
209
|
+
if (nDrumDataLen >= 2) pdd = (MT2DRUMSDATA *)(lpStream+dwDrumDataPos);
|
210
|
+
dwMemPos += 2 + nDrumDataLen;
|
211
|
+
if (dwMemPos >= dwMemLength-12) return TRUE;
|
212
|
+
if (!*(DWORD *)(lpStream+dwMemPos)) dwMemPos += 4;
|
213
|
+
if (!*(DWORD *)(lpStream+dwMemPos)) dwMemPos += 4;
|
214
|
+
nExtraDataLen = *(DWORD *)(lpStream+dwMemPos);
|
215
|
+
dwExtraDataPos = dwMemPos + 4;
|
216
|
+
dwMemPos += 4;
|
217
|
+
if (dwMemPos + nExtraDataLen >= dwMemLength) return TRUE;
|
218
|
+
while (dwMemPos+8 < dwExtraDataPos + nExtraDataLen)
|
219
|
+
{
|
220
|
+
DWORD dwId = *(DWORD *)(lpStream+dwMemPos);
|
221
|
+
DWORD dwLen = *(DWORD *)(lpStream+dwMemPos+4);
|
222
|
+
dwMemPos += 8;
|
223
|
+
if (dwMemPos + dwLen > dwMemLength) return TRUE;
|
224
|
+
switch(dwId)
|
225
|
+
{
|
226
|
+
// MSG
|
227
|
+
case 0x0047534D:
|
228
|
+
break;
|
229
|
+
// SUM -> author name (or "Unregistered")
|
230
|
+
// TMAP
|
231
|
+
// TRKS
|
232
|
+
case 0x534b5254:
|
233
|
+
break;
|
234
|
+
}
|
235
|
+
dwMemPos += dwLen;
|
236
|
+
}
|
237
|
+
// Load Patterns
|
238
|
+
dwMemPos = dwExtraDataPos + nExtraDataLen;
|
239
|
+
for (UINT iPat=0; iPat<pfh->wPatterns; iPat++) if (dwMemPos < dwMemLength-6)
|
240
|
+
{
|
241
|
+
const MT2PATTERN *pmp = (MT2PATTERN *)(lpStream+dwMemPos);
|
242
|
+
UINT wDataLen = (pmp->wDataLen + 1) & ~1;
|
243
|
+
dwMemPos += 6;
|
244
|
+
if (dwMemPos + wDataLen > dwMemLength) break;
|
245
|
+
UINT nLines = pmp->wLines;
|
246
|
+
if ((iPat < MAX_PATTERNS) && (nLines > 0) && (nLines <= 256))
|
247
|
+
{
|
248
|
+
_this->PatternSize[iPat] = nLines;
|
249
|
+
_this->Patterns[iPat] = CSoundFile_AllocatePattern(nLines, _this->m_nChannels);
|
250
|
+
if (!_this->Patterns[iPat]) return TRUE;
|
251
|
+
MODCOMMAND *m = _this->Patterns[iPat];
|
252
|
+
UINT len = wDataLen;
|
253
|
+
if (pfh->fulFlags & 1) // Packed Patterns
|
254
|
+
{
|
255
|
+
BYTE *p = (BYTE *)(lpStream+dwMemPos);
|
256
|
+
UINT pos = 0, row=0, ch=0;
|
257
|
+
while (pos < len)
|
258
|
+
{
|
259
|
+
MT2COMMAND cmd;
|
260
|
+
UINT infobyte = p[pos++];
|
261
|
+
UINT rptcount = 0;
|
262
|
+
if (infobyte == 0xff)
|
263
|
+
{
|
264
|
+
rptcount = p[pos++];
|
265
|
+
infobyte = p[pos++];
|
266
|
+
}
|
267
|
+
if (infobyte & 0x7f)
|
268
|
+
{
|
269
|
+
UINT patpos = row*_this->m_nChannels+ch;
|
270
|
+
cmd.note = cmd.instr = cmd.vol = cmd.pan = cmd.fxcmd = cmd.fxparam1 = cmd.fxparam2 = 0;
|
271
|
+
if (infobyte & 1) cmd.note = p[pos++];
|
272
|
+
if (infobyte & 2) cmd.instr = p[pos++];
|
273
|
+
if (infobyte & 4) cmd.vol = p[pos++];
|
274
|
+
if (infobyte & 8) cmd.pan = p[pos++];
|
275
|
+
if (infobyte & 16) cmd.fxcmd = p[pos++];
|
276
|
+
if (infobyte & 32) cmd.fxparam1 = p[pos++];
|
277
|
+
if (infobyte & 64) cmd.fxparam2 = p[pos++];
|
278
|
+
ConvertMT2Command(_this, &m[patpos], &cmd);
|
279
|
+
}
|
280
|
+
row += rptcount+1;
|
281
|
+
while (row >= nLines) { row-=nLines; ch++; }
|
282
|
+
if (ch >= _this->m_nChannels) break;
|
283
|
+
}
|
284
|
+
} else
|
285
|
+
{
|
286
|
+
const MT2COMMAND *p = (MT2COMMAND *)(lpStream+dwMemPos);
|
287
|
+
UINT n = 0;
|
288
|
+
while ((len > sizeof(MT2COMMAND)) && (n < _this->m_nChannels*nLines))
|
289
|
+
{
|
290
|
+
ConvertMT2Command(_this, m, p);
|
291
|
+
len -= sizeof(MT2COMMAND);
|
292
|
+
n++;
|
293
|
+
p++;
|
294
|
+
m++;
|
295
|
+
}
|
296
|
+
}
|
297
|
+
}
|
298
|
+
dwMemPos += wDataLen;
|
299
|
+
}
|
300
|
+
// Skip Drum Patterns
|
301
|
+
if (pdd)
|
302
|
+
{
|
303
|
+
for (UINT iDrm=0; iDrm<pdd->wDrumPatterns; iDrm++)
|
304
|
+
{
|
305
|
+
if (dwMemPos > dwMemLength-2) return TRUE;
|
306
|
+
UINT nLines = *(WORD *)(lpStream+dwMemPos);
|
307
|
+
dwMemPos += 2 + nLines * 32;
|
308
|
+
}
|
309
|
+
}
|
310
|
+
// Automation
|
311
|
+
if (pfh->fulFlags & 2)
|
312
|
+
{
|
313
|
+
UINT nAutoCount = _this->m_nChannels;
|
314
|
+
if (pfh->fulFlags & 0x10) nAutoCount++; // Master Automation
|
315
|
+
if ((pfh->fulFlags & 0x08) && (pdd)) nAutoCount += 8; // Drums Automation
|
316
|
+
nAutoCount *= pfh->wPatterns;
|
317
|
+
for (UINT iAuto=0; iAuto<nAutoCount; iAuto++)
|
318
|
+
{
|
319
|
+
if (dwMemPos+12 >= dwMemLength) return TRUE;
|
320
|
+
const MT2AUTOMATION *pma = (MT2AUTOMATION *)(lpStream+dwMemPos);
|
321
|
+
dwMemPos += (pfh->wVersion <= 0x201) ? 4 : 8;
|
322
|
+
for (UINT iEnv=0; iEnv<14; iEnv++)
|
323
|
+
{
|
324
|
+
if (pma->dwFlags & (1 << iEnv))
|
325
|
+
{
|
326
|
+
dwMemPos += 260;
|
327
|
+
}
|
328
|
+
}
|
329
|
+
}
|
330
|
+
}
|
331
|
+
// Load Instruments
|
332
|
+
SDL_memset(InstrMap, 0, sizeof(InstrMap));
|
333
|
+
_this->m_nInstruments = (pfh->wInstruments < MAX_INSTRUMENTS) ? pfh->wInstruments : MAX_INSTRUMENTS-1;
|
334
|
+
for (UINT iIns=1; iIns<=255; iIns++)
|
335
|
+
{
|
336
|
+
if (dwMemPos+36 > dwMemLength) return TRUE;
|
337
|
+
const MT2INSTRUMENT *pmi = (MT2INSTRUMENT *)(lpStream+dwMemPos);
|
338
|
+
INSTRUMENTHEADER *penv = NULL;
|
339
|
+
if (iIns <= _this->m_nInstruments)
|
340
|
+
{
|
341
|
+
penv = (INSTRUMENTHEADER *) SDL_malloc(sizeof (INSTRUMENTHEADER));
|
342
|
+
_this->Headers[iIns] = penv;
|
343
|
+
if (penv)
|
344
|
+
{
|
345
|
+
SDL_memset(penv, 0, sizeof(INSTRUMENTHEADER));
|
346
|
+
penv->nGlobalVol = 64;
|
347
|
+
penv->nPan = 128;
|
348
|
+
for (UINT i=0; i<NOTE_MAX; i++)
|
349
|
+
{
|
350
|
+
penv->NoteMap[i] = i+1;
|
351
|
+
}
|
352
|
+
}
|
353
|
+
}
|
354
|
+
if (((LONG)pmi->dwDataLen > 0) && (dwMemPos <= dwMemLength - 40) && (pmi->dwDataLen <= dwMemLength - (dwMemPos + 40)))
|
355
|
+
{
|
356
|
+
InstrMap[iIns-1] = pmi;
|
357
|
+
if (penv)
|
358
|
+
{
|
359
|
+
penv->nFadeOut = pmi->wFadeOut;
|
360
|
+
penv->nNNA = pmi->wNNA & 3;
|
361
|
+
penv->nDCT = (pmi->wNNA>>8) & 3;
|
362
|
+
penv->nDNA = (pmi->wNNA>>12) & 3;
|
363
|
+
MT2ENVELOPE *pehdr[4];
|
364
|
+
WORD *pedata[4];
|
365
|
+
if (pfh->wVersion <= 0x201)
|
366
|
+
{
|
367
|
+
DWORD dwEnvPos = dwMemPos + sizeof(MT2INSTRUMENT) - 4;
|
368
|
+
pehdr[0] = (MT2ENVELOPE *)(lpStream+dwEnvPos);
|
369
|
+
pehdr[1] = (MT2ENVELOPE *)(lpStream+dwEnvPos+8);
|
370
|
+
pehdr[2] = pehdr[3] = NULL;
|
371
|
+
pedata[0] = (WORD *)(lpStream+dwEnvPos+16);
|
372
|
+
pedata[1] = (WORD *)(lpStream+dwEnvPos+16+64);
|
373
|
+
pedata[2] = pedata[3] = NULL;
|
374
|
+
} else
|
375
|
+
{
|
376
|
+
DWORD dwEnvPos = dwMemPos + sizeof(MT2INSTRUMENT);
|
377
|
+
for (UINT i=0; i<4; i++)
|
378
|
+
{
|
379
|
+
if (pmi->wEnvFlags1 & (1<<i))
|
380
|
+
{
|
381
|
+
pehdr[i] = (MT2ENVELOPE *)(lpStream+dwEnvPos);
|
382
|
+
pedata[i] = (WORD *)pehdr[i]->EnvData;
|
383
|
+
dwEnvPos += sizeof(MT2ENVELOPE);
|
384
|
+
} else
|
385
|
+
{
|
386
|
+
pehdr[i] = NULL;
|
387
|
+
pedata[i] = NULL;
|
388
|
+
}
|
389
|
+
}
|
390
|
+
}
|
391
|
+
// Load envelopes
|
392
|
+
for (UINT iEnv=0; iEnv<4; iEnv++) if (pehdr[iEnv])
|
393
|
+
{
|
394
|
+
const MT2ENVELOPE *pme = pehdr[iEnv];
|
395
|
+
WORD *pEnvPoints = NULL;
|
396
|
+
BYTE *pEnvData = NULL;
|
397
|
+
switch(iEnv)
|
398
|
+
{
|
399
|
+
// Volume Envelope
|
400
|
+
case 0:
|
401
|
+
if (pme->nFlags & 1) penv->dwFlags |= ENV_VOLUME;
|
402
|
+
if (pme->nFlags & 2) penv->dwFlags |= ENV_VOLSUSTAIN;
|
403
|
+
if (pme->nFlags & 4) penv->dwFlags |= ENV_VOLLOOP;
|
404
|
+
penv->nVolEnv = (pme->nPoints > 16) ? 16 : pme->nPoints;
|
405
|
+
penv->nVolSustainBegin = penv->nVolSustainEnd = pme->nSustainPos;
|
406
|
+
penv->nVolLoopStart = pme->nLoopStart;
|
407
|
+
penv->nVolLoopEnd = pme->nLoopEnd;
|
408
|
+
pEnvPoints = penv->VolPoints;
|
409
|
+
pEnvData = penv->VolEnv;
|
410
|
+
break;
|
411
|
+
|
412
|
+
// Panning Envelope
|
413
|
+
case 1:
|
414
|
+
if (pme->nFlags & 1) penv->dwFlags |= ENV_PANNING;
|
415
|
+
if (pme->nFlags & 2) penv->dwFlags |= ENV_PANSUSTAIN;
|
416
|
+
if (pme->nFlags & 4) penv->dwFlags |= ENV_PANLOOP;
|
417
|
+
penv->nPanEnv = (pme->nPoints > 16) ? 16 : pme->nPoints;
|
418
|
+
penv->nPanSustainBegin = penv->nPanSustainEnd = pme->nSustainPos;
|
419
|
+
penv->nPanLoopStart = pme->nLoopStart;
|
420
|
+
penv->nPanLoopEnd = pme->nLoopEnd;
|
421
|
+
pEnvPoints = penv->PanPoints;
|
422
|
+
pEnvData = penv->PanEnv;
|
423
|
+
break;
|
424
|
+
|
425
|
+
// Pitch/Filter envelope
|
426
|
+
default:
|
427
|
+
if (pme->nFlags & 1) penv->dwFlags |= (iEnv==3) ? (ENV_PITCH|ENV_FILTER) : ENV_PITCH;
|
428
|
+
if (pme->nFlags & 2) penv->dwFlags |= ENV_PITCHSUSTAIN;
|
429
|
+
if (pme->nFlags & 4) penv->dwFlags |= ENV_PITCHLOOP;
|
430
|
+
penv->nPitchEnv = (pme->nPoints > 16) ? 16 : pme->nPoints;
|
431
|
+
penv->nPitchSustainBegin = penv->nPitchSustainEnd = pme->nSustainPos;
|
432
|
+
penv->nPitchLoopStart = pme->nLoopStart;
|
433
|
+
penv->nPitchLoopEnd = pme->nLoopEnd;
|
434
|
+
pEnvPoints = penv->PitchPoints;
|
435
|
+
pEnvData = penv->PitchEnv;
|
436
|
+
}
|
437
|
+
// Envelope data
|
438
|
+
if ((pEnvPoints) && (pEnvData) && (pedata[iEnv]))
|
439
|
+
{
|
440
|
+
WORD *psrc = pedata[iEnv];
|
441
|
+
for (UINT i=0; i<16; i++)
|
442
|
+
{
|
443
|
+
pEnvPoints[i] = psrc[i*2];
|
444
|
+
pEnvData[i] = (BYTE)psrc[i*2+1];
|
445
|
+
}
|
446
|
+
}
|
447
|
+
}
|
448
|
+
}
|
449
|
+
dwMemPos += pmi->dwDataLen + 36;
|
450
|
+
if (pfh->wVersion > 0x201) dwMemPos += 4; // ?
|
451
|
+
} else
|
452
|
+
{
|
453
|
+
dwMemPos += 36;
|
454
|
+
}
|
455
|
+
}
|
456
|
+
SDL_memset(SampleMap, 0, sizeof(SampleMap));
|
457
|
+
_this->m_nSamples = (pfh->wSamples < MAX_SAMPLES) ? pfh->wSamples : MAX_SAMPLES-1;
|
458
|
+
for (UINT iSmp=1; iSmp<=256; iSmp++)
|
459
|
+
{
|
460
|
+
if (dwMemPos+36 > dwMemLength) return TRUE;
|
461
|
+
const MT2SAMPLE *pms = (MT2SAMPLE *)(lpStream+dwMemPos);
|
462
|
+
if (pms->dwDataLen > 0)
|
463
|
+
{
|
464
|
+
SampleMap[iSmp-1] = pms;
|
465
|
+
if (iSmp < MAX_SAMPLES)
|
466
|
+
{
|
467
|
+
MODINSTRUMENT *psmp = &_this->Ins[iSmp];
|
468
|
+
psmp->nGlobalVol = 64;
|
469
|
+
psmp->nVolume = (pms->wVolume >> 7);
|
470
|
+
psmp->nPan = (pms->nPan == 0x80) ? 128 : (pms->nPan^0x80);
|
471
|
+
psmp->nLength = pms->dwLength;
|
472
|
+
psmp->nC4Speed = pms->dwFrequency;
|
473
|
+
psmp->nLoopStart = pms->dwLoopStart;
|
474
|
+
psmp->nLoopEnd = pms->dwLoopEnd;
|
475
|
+
CSoundFile_FrequencyToTransposeInstrument(psmp);
|
476
|
+
psmp->RelativeTone -= pms->nBaseNote - 49;
|
477
|
+
psmp->nC4Speed = CSoundFile_TransposeToFrequency(psmp->RelativeTone, psmp->nFineTune);
|
478
|
+
if (pms->nQuality == 2) { psmp->uFlags |= CHN_16BIT; psmp->nLength >>= 1; }
|
479
|
+
if (pms->nChannels == 2) { psmp->nLength >>= 1; }
|
480
|
+
if (pms->nLoop == 1) psmp->uFlags |= CHN_LOOP;
|
481
|
+
if (pms->nLoop == 2) psmp->uFlags |= CHN_LOOP|CHN_PINGPONGLOOP;
|
482
|
+
}
|
483
|
+
dwMemPos += pms->dwDataLen + 36;
|
484
|
+
} else
|
485
|
+
{
|
486
|
+
dwMemPos += 36;
|
487
|
+
}
|
488
|
+
}
|
489
|
+
for (UINT iMap=0; iMap<255; iMap++) if (InstrMap[iMap])
|
490
|
+
{
|
491
|
+
if (dwMemPos+8 > dwMemLength) return TRUE;
|
492
|
+
const MT2INSTRUMENT *pmi = InstrMap[iMap];
|
493
|
+
INSTRUMENTHEADER *penv = NULL;
|
494
|
+
if (iMap<_this->m_nInstruments) penv = _this->Headers[iMap+1];
|
495
|
+
for (UINT iGrp=0; iGrp<pmi->wSamples; iGrp++)
|
496
|
+
{
|
497
|
+
if (penv)
|
498
|
+
{
|
499
|
+
const MT2GROUP *pmg = (MT2GROUP *)(lpStream+dwMemPos);
|
500
|
+
for (UINT i=0; i<96; i++)
|
501
|
+
{
|
502
|
+
if (pmi->GroupsMapping[i] == iGrp)
|
503
|
+
{
|
504
|
+
UINT nSmp = pmg->nSmpNo+1;
|
505
|
+
penv->Keyboard[i+12] = (BYTE)nSmp;
|
506
|
+
if (nSmp <= _this->m_nSamples)
|
507
|
+
{
|
508
|
+
_this->Ins[nSmp].nVibType = pmi->bVibType;
|
509
|
+
_this->Ins[nSmp].nVibSweep = pmi->bVibSweep;
|
510
|
+
_this->Ins[nSmp].nVibDepth = pmi->bVibDepth;
|
511
|
+
_this->Ins[nSmp].nVibRate = pmi->bVibRate;
|
512
|
+
}
|
513
|
+
}
|
514
|
+
}
|
515
|
+
}
|
516
|
+
dwMemPos += 8;
|
517
|
+
}
|
518
|
+
}
|
519
|
+
for (UINT iData=0; iData<256; iData++) if ((iData < _this->m_nSamples) && (SampleMap[iData]))
|
520
|
+
{
|
521
|
+
const MT2SAMPLE *pms = SampleMap[iData];
|
522
|
+
MODINSTRUMENT *psmp = &_this->Ins[iData+1];
|
523
|
+
if (!(pms->nFlags & 5))
|
524
|
+
{
|
525
|
+
if (psmp->nLength > 0)
|
526
|
+
{
|
527
|
+
UINT rsflags;
|
528
|
+
|
529
|
+
if (pms->nChannels == 2)
|
530
|
+
rsflags = (psmp->uFlags & CHN_16BIT) ? RS_STPCM16D : RS_STPCM8D;
|
531
|
+
else
|
532
|
+
rsflags = (psmp->uFlags & CHN_16BIT) ? RS_PCM16D : RS_PCM8D;
|
533
|
+
|
534
|
+
dwMemPos += CSoundFile_ReadSample(_this, psmp, rsflags, (LPCSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
|
535
|
+
}
|
536
|
+
} else
|
537
|
+
if (dwMemPos+4 < dwMemLength)
|
538
|
+
{
|
539
|
+
UINT nNameLen = *(DWORD *)(lpStream+dwMemPos);
|
540
|
+
dwMemPos += nNameLen + 16;
|
541
|
+
}
|
542
|
+
if (dwMemPos+4 >= dwMemLength) break;
|
543
|
+
}
|
544
|
+
return TRUE;
|
545
|
+
}
|
546
|
+
|