Commit ccd96269 authored by PoroCYon's avatar PoroCYon
Browse files

[clinkster] attempt at making the player portable (untested)

parent e841ea96
...@@ -10,39 +10,33 @@ ...@@ -10,39 +10,33 @@
; appropriate for typical display latencies for high-framerate effects. ; appropriate for typical display latencies for high-framerate effects.
%define CLINKSTER_TIMER_OFFSET 2048 %define CLINKSTER_TIMER_OFFSET 2048
%include "platform.inc"
%include "music.asm" %include "music.asm"
;; ********** Definitions ********** ;; ********** Definitions **********
global Clinkster_GenerateMusic global PUBLIC_FN(Clinkster_GenerateMusic,0)
global _Clinkster_GenerateMusic@0 global PUBLIC_FN(Clinkster_StartMusic,0)
global Clinkster_StartMusic global PUBLIC_FN(Clinkster_GetPosition,0)
global _Clinkster_StartMusic@0 global PUBLIC_FN(Clinkster_GetInstrumentTrigger,8)
global Clinkster_GetPosition
global _Clinkster_GetPosition@0 global PUBLIC_DATA(Clinkster_MusicBuffer)
global Clinkster_GetInstrumentTrigger global PUBLIC_DATA(Clinkster_TicksPerSecond)
global _Clinkster_GetInstrumentTrigger@8 global PUBLIC_DATA(Clinkster_MusicLength)
global PUBLIC_DATA(Clinkster_NumTracks)
global Clinkster_MusicBuffer
global _Clinkster_MusicBuffer
global Clinkster_TicksPerSecond
global _Clinkster_TicksPerSecond
global Clinkster_MusicLength
global _Clinkster_MusicLength
global Clinkster_NumTracks
global _Clinkster_NumTracks
%if CLINKSTER_GENERATE_TIMING_DATA %if CLINKSTER_GENERATE_TIMING_DATA
global Clinkster_NoteTiming global PUBLIC_DATA(Clinkster_NoteTiming)
global _Clinkster_NoteTiming
%endif %endif
global Clinkster_WavFileHeader global PUBLIC_DATA(Clinkster_WavFileHeader)
global _Clinkster_WavFileHeader
%ifdef WIN32
extern __imp__waveOutOpen@24 extern __imp__waveOutOpen@24
extern __imp__waveOutPrepareHeader@12 extern __imp__waveOutPrepareHeader@12
extern __imp__waveOutWrite@12 extern __imp__waveOutWrite@12
extern __imp__waveOutGetPosition@12 extern __imp__waveOutGetPosition@12
%endif
%define SAMPLE_RATE 44100 %define SAMPLE_RATE 44100
%define WAVE_SIZE 65536 %define WAVE_SIZE 65536
...@@ -51,31 +45,26 @@ extern __imp__waveOutGetPosition@12 ...@@ -51,31 +45,26 @@ extern __imp__waveOutGetPosition@12
;; ********** Public variables ********** ;; ********** Public variables **********
section MusBuf bss align=4 section MusBuf bss align=4
Clinkster_MusicBuffer: PUBLIC_DATA(Clinkster_MusicBuffer):
_Clinkster_MusicBuffer:
.align24 .align24
resw (TOTAL_SAMPLES*2) resw (TOTAL_SAMPLES*2)
resw 2 ; padding to catch extra write in conversion resw 2 ; padding to catch extra write in conversion
section tps rdata align=4 section tps rdata align=4
Clinkster_TicksPerSecond: PUBLIC_DATA(Clinkster_TicksPerSecond):
_Clinkster_TicksPerSecond:
dd TICKS_PER_SECOND dd TICKS_PER_SECOND
section muslen rdata align=4 section muslen rdata align=4
Clinkster_MusicLength: PUBLIC_DATA(Clinkster_MusicLength):
_Clinkster_MusicLength:
dd MUSIC_LENGTH dd MUSIC_LENGTH
section numtr rdata align=4 section numtr rdata align=4
Clinkster_NumTracks: PUBLIC_DATA(Clinkster_NumTracks):
_Clinkster_NumTracks:
dd NUMTRACKS dd NUMTRACKS
%if CLINKSTER_GENERATE_TIMING_DATA %if CLINKSTER_GENERATE_TIMING_DATA
section musdat bss align=4 section musdat bss align=4
Clinkster_NoteTiming: PUBLIC_DATA(Clinkster_NoteTiming):
_Clinkster_NoteTiming:
.align16 .align16
resd 2*(NUMTRACKS<<LOGNUMTICKS) resd 2*(NUMTRACKS<<LOGNUMTICKS)
...@@ -84,8 +73,7 @@ timing_ptr: dd Clinkster_NoteTiming ...@@ -84,8 +73,7 @@ timing_ptr: dd Clinkster_NoteTiming
%endif %endif
section WavFile rdata align=4 section WavFile rdata align=4
Clinkster_WavFileHeader: PUBLIC_DATA(Clinkster_WavFileHeader):
_Clinkster_WavFileHeader:
db "RIFF" db "RIFF"
dd 36+TOTAL_SAMPLES*4 dd 36+TOTAL_SAMPLES*4
db "WAVE" db "WAVE"
...@@ -102,25 +90,25 @@ _Clinkster_WavFileHeader: ...@@ -102,25 +90,25 @@ _Clinkster_WavFileHeader:
;; ********** System structures ********** ;; ********** System structures **********
section WaveForm rdata align=1 section WaveForm rdata align=1
_WaveFormat: PUBLIC_DATA(WaveFormat):
dw 1,2 dw 1,2
dd SAMPLE_RATE dd SAMPLE_RATE
dd SAMPLE_RATE*4 dd SAMPLE_RATE*4
dw 4,16,0 dw 4,16,0
section WaveHdr data align=4 section WaveHdr data align=4
_WaveHdr: PUBLIC_DATA(WaveHdr):
dd Clinkster_MusicBuffer dd PUBLIC_DATA(Clinkster_MusicBuffer)
dd (TOTAL_SAMPLES*4) dd (TOTAL_SAMPLES*4)
dd 0,0,0,0,0,0 dd 0,0,0,0,0,0
section wavehand bss align=4 section wavehand bss align=4
_WaveOutHandle: PUBLIC_DATA(WaveOutHandle):
.align16 .align16
resd 1 resd 1
section WaveTime data align=4 section WaveTime data align=4
_WaveTime: PUBLIC_DATA(WaveTime):
dd 4,0,0,0,0,0,0,0 dd 4,0,0,0,0,0,0,0
...@@ -128,28 +116,28 @@ _WaveTime: ...@@ -128,28 +116,28 @@ _WaveTime:
section MixBuf bss align=4 section MixBuf bss align=4
resd MAX_DELAY_LENGTH resd MAX_DELAY_LENGTH
_MixingBuffer: PUBLIC_DATA(MixingBuffer):
.align24 .align24
resd TOTAL_SAMPLES resd TOTAL_SAMPLES
section InstrBuf bss align=4 section InstrBuf bss align=4
_InstrumentBuffer: PUBLIC_DATA(InstrumentBuffer):
.align16 .align16
resd MAX_INSTRUMENT_SUBSAMPLES resd MAX_INSTRUMENT_SUBSAMPLES
section InstrRen bss align=4 section InstrRen bss align=4
resd 256 resd 256
_InstrumentRender: PUBLIC_DATA(InstrumentRender):
.align16 .align16
resd MAX_INSTRUMENT_SUBSAMPLES resd MAX_INSTRUMENT_SUBSAMPLES
section InstrSto bss align=4 section InstrSto bss align=4
_InstrumentStore: PUBLIC_DATA(InstrumentStore):
.align16 .align16
resd MAX_TOTAL_INSTRUMENT_SAMPLES resd MAX_TOTAL_INSTRUMENT_SAMPLES
section InstrPoi bss align=4 section InstrPoi bss align=4
_InstrumentPointers: PUBLIC_DATA(InstrumentPointers):
.align16 .align16
resd MAX_TRACK_INSTRUMENT_RENDERS+1 resd MAX_TRACK_INSTRUMENT_RENDERS+1
...@@ -354,7 +342,7 @@ makelayer: ...@@ -354,7 +342,7 @@ makelayer:
; Loop over samples ; Loop over samples
fldz ; b phase fldz ; b phase
fldz ; m phase fldz ; m phase
mov edi, _InstrumentBuffer mov edi, PUBLIC_DATA(InstrumentBuffer)
; Calculate max note size ; Calculate max note size
xor eax, eax xor eax, eax
...@@ -476,7 +464,7 @@ apply_adsr: ...@@ -476,7 +464,7 @@ apply_adsr:
fdivp st1, st0 fdivp st1, st0
.adsrloop: .adsrloop:
fld dword [_InstrumentBuffer + ecx*4] fld dword [PUBLIC_DATA(InstrumentBuffer) + ecx*4]
fmul st0, st3 ; velocity / nlayers fmul st0, st3 ; velocity / nlayers
fmul st0, st2 ; envelope value fmul st0, st2 ; envelope value
...@@ -492,7 +480,7 @@ apply_adsr: ...@@ -492,7 +480,7 @@ apply_adsr:
fmulp st1, st0 fmulp st1, st0
%endif %endif
fstp dword [_InstrumentRender + ecx*4] fstp dword [PUBLIC_DATA(InstrumentRender) + ecx*4]
fadd st1, st0 fadd st1, st0
inc ecx inc ecx
...@@ -507,8 +495,7 @@ apply_adsr: ...@@ -507,8 +495,7 @@ apply_adsr:
;; ********** Main music generation ********** ;; ********** Main music generation **********
section genMus text align=1 section genMus text align=1
Clinkster_GenerateMusic: PUBLIC_FN(Clinkster_GenerateMusic,0):
_Clinkster_GenerateMusic@0:
pusha pusha
fninit fninit
...@@ -606,15 +593,15 @@ _Clinkster_GenerateMusic@0: ...@@ -606,15 +593,15 @@ _Clinkster_GenerateMusic@0:
%endif %endif
.stereoloop: .stereoloop:
mov dword [noteposptr], _NotePositions mov dword [noteposptr], PUBLIC_DATA(NotePositions)
mov dword [notesamptr], _NoteSamples mov dword [notesamptr], PUBLIC_DATA(NoteSamples)
xor eax, eax xor eax, eax
mov edi, _MixingBuffer mov edi, PUBLIC_DATA(MixingBuffer)
mov ecx, TOTAL_SAMPLES mov ecx, TOTAL_SAMPLES
rep stosd rep stosd
mov esi, _InstrumentData mov esi, PUBLIC_DATA(InstrumentData)
%if USES_DELAY %if USES_DELAY
jmp short .trackloop jmp short .trackloop
...@@ -623,7 +610,7 @@ _Clinkster_GenerateMusic@0: ...@@ -623,7 +610,7 @@ _Clinkster_GenerateMusic@0:
mov edx, (LEFT_DELAY_LENGTH-RIGHT_DELAY_LENGTH)*4/2 mov edx, (LEFT_DELAY_LENGTH-RIGHT_DELAY_LENGTH)*4/2
mul edx mul edx
sub eax, LEFT_DELAY_LENGTH*4 sub eax, LEFT_DELAY_LENGTH*4
mov edi, _MixingBuffer mov edi, PUBLIC_DATA(MixingBuffer)
mov ecx, TOTAL_SAMPLES mov ecx, TOTAL_SAMPLES
.delayloop: .delayloop:
fld dword [edi+eax] fld dword [edi+eax]
...@@ -645,7 +632,7 @@ _Clinkster_GenerateMusic@0: ...@@ -645,7 +632,7 @@ _Clinkster_GenerateMusic@0:
fild dword [esp] fild dword [esp]
pop eax pop eax
fmul dword [param_weights-4+ecx*4] fmul dword [param_weights-4+ecx*4]
fstp dword [edi] fstp dword [edi]
scasd scasd
loop .ploop loop .ploop
...@@ -661,8 +648,8 @@ _Clinkster_GenerateMusic@0: ...@@ -661,8 +648,8 @@ _Clinkster_GenerateMusic@0:
scasd scasd
loop .cubeloop loop .cubeloop
mov ebx, _InstrumentPointers mov ebx, PUBLIC_DATA(InstrumentPointers)
mov dword [ebx], _InstrumentStore ; store first instrument instance address mov dword [ebx], PUBLIC_DATA(InstrumentStore) ; store first instrument instance address
fld dword [c_basefreq] fld dword [c_basefreq]
; Loop over instrument tones ; Loop over instrument tones
...@@ -683,7 +670,7 @@ _Clinkster_GenerateMusic@0: ...@@ -683,7 +670,7 @@ _Clinkster_GenerateMusic@0:
mov dword [layer_random], ecx mov dword [layer_random], ecx
xor eax, eax xor eax, eax
mov edi, _InstrumentBuffer mov edi, PUBLIC_DATA(InstrumentBuffer)
mov ecx, MAX_INSTRUMENT_SUBSAMPLES mov ecx, MAX_INSTRUMENT_SUBSAMPLES
rep stosd rep stosd
...@@ -716,11 +703,11 @@ _Clinkster_GenerateMusic@0: ...@@ -716,11 +703,11 @@ _Clinkster_GenerateMusic@0:
fld1 ; attack amplitude target fld1 ; attack amplitude target
fld qword [layer_attack]; attack length fld qword [layer_attack]; attack length
call apply_adsr call apply_adsr
fld IP(sustain,FLOAT) ; decay amplitude target fld IP(sustain,FLOAT) ; decay amplitude target
fld qword [layer_decay] ; decay length fld qword [layer_decay] ; decay length
call apply_adsr call apply_adsr
xor eax, eax xor eax, eax
%if USES_LONG_NOTES %if USES_LONG_NOTES
cmp [esi], byte 0 cmp [esi], byte 0
...@@ -742,7 +729,7 @@ _Clinkster_GenerateMusic@0: ...@@ -742,7 +729,7 @@ _Clinkster_GenerateMusic@0:
fldz ; release amplitude target fldz ; release amplitude target
fld qword [layer_release];release length fld qword [layer_release];release length
call apply_adsr call apply_adsr
fldz ; padding amplitude fldz ; padding amplitude
fld1 ; padding length fld1 ; padding length
call apply_adsr call apply_adsr
...@@ -755,7 +742,7 @@ _Clinkster_GenerateMusic@0: ...@@ -755,7 +742,7 @@ _Clinkster_GenerateMusic@0:
add ebx, byte 4 add ebx, byte 4
xchg edx, eax xchg edx, eax
mov ebp, _InstrumentRender - FILTER_SIZE*4 mov ebp, PUBLIC_DATA(InstrumentRender) - FILTER_SIZE*4
.resampleloop: .resampleloop:
fldz fldz
mov ecx, FILTER_SIZE mov ecx, FILTER_SIZE
...@@ -793,8 +780,8 @@ _Clinkster_GenerateMusic@0: ...@@ -793,8 +780,8 @@ _Clinkster_GenerateMusic@0:
fstp st0 fstp st0
; Mixing ; Mixing
mov ebx, _InstrumentPointers mov ebx, PUBLIC_DATA(InstrumentPointers)
mov ebp, _MixingBuffer mov ebp, PUBLIC_DATA(MixingBuffer)
xchg esi, dword [notesamptr] xchg esi, dword [notesamptr]
.noteloop: .noteloop:
xchg esi, dword [noteposptr] xchg esi, dword [noteposptr]
...@@ -828,7 +815,7 @@ _Clinkster_GenerateMusic@0: ...@@ -828,7 +815,7 @@ _Clinkster_GenerateMusic@0:
lodsb lodsb
mov edx, dword [ebx + eax*4] ; Instrument instance ptr mov edx, dword [ebx + eax*4] ; Instrument instance ptr
mov edi, ebp mov edi, ebp
.mixloop: .mixloop:
fld dword [edx] fld dword [edx]
fadd dword [edi] fadd dword [edi]
...@@ -864,11 +851,11 @@ _Clinkster_GenerateMusic@0: ...@@ -864,11 +851,11 @@ _Clinkster_GenerateMusic@0:
; Clamp and convert to shorts ; Clamp and convert to shorts
fld1 fld1
mov edi, Clinkster_MusicBuffer mov edi, PUBLIC_DATA(Clinkster_MusicBuffer)
mov ecx, TOTAL_SAMPLES mov ecx, TOTAL_SAMPLES
add edi, dword [stereo] add edi, dword [stereo]
.sloop: .sloop:
fld dword [_MixingBuffer + ecx*4] fld dword [PUBLIC_DATA(MixingBuffer) + ecx*4]
fcomi st0, st1 fcomi st0, st1
fcmovnb st0, st1 fcmovnb st0, st1
fchs fchs
...@@ -890,9 +877,9 @@ _Clinkster_GenerateMusic@0: ...@@ -890,9 +877,9 @@ _Clinkster_GenerateMusic@0:
;; ********** Start music ********** ;; ********** Start music **********
%ifdef WIN32
section startmus text align=1 section startmus text align=1
Clinkster_StartMusic: PUBLIC_FN(Clinkster_StartMusic,0):
_Clinkster_StartMusic@0:
; Start music ; Start music
push byte 0 push byte 0
push byte 0 push byte 0
...@@ -917,8 +904,7 @@ _Clinkster_StartMusic@0: ...@@ -917,8 +904,7 @@ _Clinkster_StartMusic@0:
;; ********** Get current play position ********** ;; ********** Get current play position **********
section getpos text align=1 section getpos text align=1
Clinkster_GetPosition: PUBLIC_FN(Clinkster_GetPosition,0):
_Clinkster_GetPosition@0:
push byte 32 ; sizeof(MMTIME) push byte 32 ; sizeof(MMTIME)
push _WaveTime push _WaveTime
push dword [_WaveOutHandle] push dword [_WaveOutHandle]
...@@ -930,18 +916,18 @@ _Clinkster_GetPosition@0: ...@@ -930,18 +916,18 @@ _Clinkster_GetPosition@0:
%endif %endif
fidiv dword [c_ticklength] fidiv dword [c_ticklength]
ret ret
%endif
;; ********** Get time since instrument trigger ********** ;; ********** Get time since instrument trigger **********
%if CLINKSTER_GENERATE_TIMING_DATA %if CLINKSTER_GENERATE_TIMING_DATA
section insttrig text align=1 section insttrig text align=1
Clinkster_GetInstrumentTrigger: PUBLIC_FN(Clinkster_GetInstrumentTrigger,8):
_Clinkster_GetInstrumentTrigger@8:
cvttss2si eax, [esp+8] cvttss2si eax, [esp+8]
mov ecx, [esp+4] mov ecx, [esp+4]
shl ecx, LOGNUMTICKS+2 shl ecx, LOGNUMTICKS+2
fld dword [esp+8] fld dword [esp+8]
fisub dword [Clinkster_NoteTiming+ecx+eax*4] fisub dword [PUBLIC_DATA(Clinkster_NoteTiming)+ecx+eax*4]
ret 8 ret 8
%endif %endif
...@@ -5,7 +5,13 @@ struct sample { ...@@ -5,7 +5,13 @@ struct sample {
short left,right; short left,right;
}; };
#ifndef WIN32
#define __stdcall
#endif
#ifdef __cplusplus
extern "C" { extern "C" {
#endif
// Generate the whole music in to music buffer. When this function // Generate the whole music in to music buffer. When this function
// returns, Clinkster_MusicBuffer will be filled with sound data, // returns, Clinkster_MusicBuffer will be filled with sound data,
// and Clinkster_StartMusic can be called. // and Clinkster_StartMusic can be called.
...@@ -52,6 +58,8 @@ extern "C" { ...@@ -52,6 +58,8 @@ extern "C" {
// Write these 44 bytes followed by Clinkster_MusicBuffer with a // Write these 44 bytes followed by Clinkster_MusicBuffer with a
// length of Clinkster_WavFileHeader[10]. // length of Clinkster_WavFileHeader[10].
extern unsigned int Clinkster_WavFileHeader[11]; extern unsigned int Clinkster_WavFileHeader[11];
#ifdef __cplusplus
}; };
#endif
#endif #endif
extern Clinkster_GenerateMusic %include "platform.inc"
extern Clinkster_StartMusic
extern Clinkster_GetPosition extern PUBLIC_FN(Clinkster_GenerateMusic,0)
extern Clinkster_GetInstrumentTrigger extern PUBLIC_FN(Clinkster_StartMusic,0)
extern PUBLIC_FN(Clinkster_GetPosition,0)
extern Clinkster_MusicBuffer extern PUBLIC_FN(Clinkster_GetInstrumentTrigger,8)
extern Clinkster_NoteTiming
extern Clinkster_TicksPerSecond extern PUBLIC_DATA(Clinkster_MusicBuffer)
extern Clinkster_MusicLength extern PUBLIC_DATA(Clinkster_TicksPerSecond)
extern Clinkster_NumTracks extern PUBLIC_DATA(Clinkster_MusicLength)
extern PUBLIC_DATA(Clinkster_NumTracks)
%if CLINKSTER_GENERATE_TIMING_DATA
extern PUBLIC_DATA(Clinkster_NoteTiming)
%endif
extern PUBLIC_DATA(Clinkster_WavFileHeader)
...@@ -10,8 +10,13 @@ ...@@ -10,8 +10,13 @@
; appropriate for typical display latencies for high-framerate effects. ; appropriate for typical display latencies for high-framerate effects.
%define CLINKSTER_TIMER_OFFSET 2048 %define CLINKSTER_TIMER_OFFSET 2048
%include "platform.inc"
%include "music.asm" %include "music.asm"
%ifndef WIN32
%error "Multithreaded playback code not ported yet."
%endif
;; ********** Definitions ********** ;; ********** Definitions **********
......
%ifdef LINUX
%define PUBLIC_FN(n,i) n
%define PUBLIC_DATA(n) n
%elifdef WIN32
%define PUBLIC_FN(n,i) _ %+ n @ %+ i
%define PUBLIC_DATA(n) _ %+ n
%else
; mac osx
%define PUBLIC_FN(n,i) _ %+ n
%define PUBLIC_DATA(n) _ %+ n
%endif
%ifdef LINUX