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

This commit is contained in:
PoroCYon 2019-05-11 01:29:45 +02:00
parent e841ea9644
commit ccd962699e
5 changed files with 112 additions and 82 deletions

View File

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

View File

@ -5,7 +5,13 @@ struct sample {
short left,right;
};
#ifndef WIN32
#define __stdcall
#endif
#ifdef __cplusplus
extern "C" {
#endif
// Generate the whole music in to music buffer. When this function
// returns, Clinkster_MusicBuffer will be filled with sound data,
// and Clinkster_StartMusic can be called.
@ -52,6 +58,8 @@ extern "C" {
// Write these 44 bytes followed by Clinkster_MusicBuffer with a
// length of Clinkster_WavFileHeader[10].
extern unsigned int Clinkster_WavFileHeader[11];
#ifdef __cplusplus
};
#endif
#endif

View File

@ -1,11 +1,17 @@
extern Clinkster_GenerateMusic
extern Clinkster_StartMusic
extern Clinkster_GetPosition
extern Clinkster_GetInstrumentTrigger
%include "platform.inc"
extern PUBLIC_FN(Clinkster_GenerateMusic,0)
extern PUBLIC_FN(Clinkster_StartMusic,0)
extern PUBLIC_FN(Clinkster_GetPosition,0)
extern PUBLIC_FN(Clinkster_GetInstrumentTrigger,8)
extern PUBLIC_DATA(Clinkster_MusicBuffer)
extern PUBLIC_DATA(Clinkster_TicksPerSecond)
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)
extern Clinkster_MusicBuffer
extern Clinkster_NoteTiming
extern Clinkster_TicksPerSecond
extern Clinkster_MusicLength
extern Clinkster_NumTracks

View File

@ -10,8 +10,13 @@
; appropriate for typical display latencies for high-framerate effects.
%define CLINKSTER_TIMER_OFFSET 2048
%include "platform.inc"
%include "music.asm"
%ifndef WIN32
%error "Multithreaded playback code not ported yet."
%endif
;; ********** Definitions **********

View File

@ -0,0 +1,25 @@
%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
%define SECT_BSS(n) section .bss.clinkster. %+ n nobits alloc noexec write
%define SECT_DATA(n) section .data.clinkster. %+ n progbits alloc noexec write
%define SECT_RDATA(n) section .rodata.clinkster. %+ n progbits alloc noexec nowrite
%define SECT_TEXT(n) section .text.clinkster. %+ n progbits alloc exec nowrite
%else
%define SECT_BSS(n) section .clinkster. %+ n bss
%define SECT_DATA(n) section .clinkster. %+ n data
%define SECT_RDATA(n) section .clinkster. %+ n rdata
%define SECT_TEXT(n) section .clinkster. %+ n code
%endif