Commit a51a2497 authored by PoroCYon's avatar PoroCYon
Browse files

make player code portable

parent c1bb2393
...@@ -9,28 +9,33 @@ ...@@ -9,28 +9,33 @@
; Set to 0 if you don't care about Oidos_GenerateMusic preserving registers ; Set to 0 if you don't care about Oidos_GenerateMusic preserving registers
%define OIDOS_SAVE_REGISTERS 1 %define OIDOS_SAVE_REGISTERS 1
%include "music.asm" %include "platform.inc"
%include "music.asm"
;; ********** Definitions ********** ;; ********** Definitions **********
global _Oidos_GenerateMusic global PUBLIC_FN(Oidos_GenerateMusic)
global _Oidos_StartMusic %ifdef WIN32
global _Oidos_GetPosition global PUBLIC_FN(Oidos_StartMusic)
global PUBLIC_FN(Oidos_GetPosition)
%endif
global _Oidos_MusicBuffer global PUBLIC_FN(Oidos_MusicBuffer)
global _Oidos_TicksPerSecond global PUBLIC_FN(Oidos_TicksPerSecond)
global _Oidos_MusicLength global PUBLIC_FN(Oidos_MusicLength)
global _Oidos_WavFileHeader global PUBLIC_FN(Oidos_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
extern _Oidos_RandomData extern PUBLIC_FN(Oidos_RandomData)
%define SAMPLE_RATE 44100 %define SAMPLE_RATE 44100
%define BASE_FREQ 0.00232970791933 ; 440/((2^(1/12))^(9+12*4))/44100*(2*3.14159265358979) %define BASE_FREQ 0.00232970791933 ; 440/((2^(1/12))^(9+12*4))/44100*(2*3.14159265358979)
...@@ -38,21 +43,21 @@ extern _Oidos_RandomData ...@@ -38,21 +43,21 @@ extern _Oidos_RandomData
;; ********** Public variables ********** ;; ********** Public variables **********
section tps rdata align=4 SECT_RDATA(tps) align=4
_Oidos_TicksPerSecond: PUBLIC_FN(Oidos_TicksPerSecond):
dd TICKS_PER_SECOND dd TICKS_PER_SECOND
section muslen rdata align=4 SECT_DATA(muslen) align=4
_Oidos_MusicLength: PUBLIC_FN(Oidos_MusicLength):
dd MUSIC_LENGTH dd MUSIC_LENGTH
section MusBuf bss align=4 SECT_BSS(MusBuf) align=4
_Oidos_MusicBuffer: PUBLIC_FN(Oidos_MusicBuffer):
.align24 ;.align24
resw TOTAL_SAMPLES*2 resw TOTAL_SAMPLES*2
section WavFile rdata align=4 SECT_DATA(WavFile) align=4
_Oidos_WavFileHeader: PUBLIC_FN(Oidos_WavFileHeader):
db "RIFF" db "RIFF"
dd 36+TOTAL_SAMPLES*4 dd 36+TOTAL_SAMPLES*4
db "WAVE" db "WAVE"
...@@ -68,53 +73,53 @@ _Oidos_WavFileHeader: ...@@ -68,53 +73,53 @@ _Oidos_WavFileHeader:
;; ********** System structures ********** ;; ********** System structures **********
section WaveForm rdata align=1 SECT_DATA(WaveForm) align=1
_WaveFormat: 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 SECT_DATA(WaveHdr) align=4
_WaveHdr: WaveHdr:
dd _Oidos_MusicBuffer dd PUBLIC_FN(Oidos_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 SECT_BSS(wavehand) align=4
_WaveOutHandle: WaveOutHandle:
.align16 .align16:
resd 1 resd 1
section WaveTime data align=4 SECT_DATA(WaveTime) align=4
_WaveTime: WaveTime:
dd 4,0,0,0,0,0,0,0 dd 4,0,0,0,0,0,0,0
;; ********** Internal buffers ********** ;; ********** Internal buffers **********
section freqarr bss align=16 SECT_BSS(freqarr) align=16
PartialArray: PartialArray:
.align16: .align16:
resq 10000*3*2 resq 10000*3*2
section sampbuf bss align=16 SECT_BSS(sampbuf) align=16
SampleBuffer: SampleBuffer:
.align24: .align24:
reso MAX_TOTAL_INSTRUMENT_SAMPLES reso MAX_TOTAL_INSTRUMENT_SAMPLES
section mixbuf bss align=16 SECT_BSS(mixbuf) align=16
MixingBuffer: MixingBuffer:
.align24: .align24:
reso TOTAL_SAMPLES reso TOTAL_SAMPLES
%if NUM_TRACKS_WITH_REVERB > 0 %if NUM_TRACKS_WITH_REVERB > 0
section revbuf bss align=16 SECT_BSS(revbuf) align=16
ReverbBuffer: ReverbBuffer:
.align24: .align24:
reso TOTAL_SAMPLES reso TOTAL_SAMPLES
section delbuf bss align=8 SECT_BSS(delbuf) align=8
DelayBuffer: DelayBuffer:
.align16: .align16:
resq 25600 resq 25600
...@@ -150,7 +155,7 @@ struc params ...@@ -150,7 +155,7 @@ struc params
;; ********** Internal constants and tables ********** ;; ********** Internal constants and tables **********
section base data align=16 SECT_DATA(base) align=16
baseptr: baseptr:
c_oneone: dq 1.0,1.0 c_oneone: dq 1.0,1.0
...@@ -168,11 +173,11 @@ ReverbParams: ...@@ -168,11 +173,11 @@ ReverbParams:
dd REVERB_FILTER_HIGH, REVERB_FILTER_LOW, REVERB_DAMPEN_HIGH, REVERB_DAMPEN_LOW, REVERB_VOLUME_LEFT dd REVERB_FILTER_HIGH, REVERB_FILTER_LOW, REVERB_DAMPEN_HIGH, REVERB_DAMPEN_LOW, REVERB_VOLUME_LEFT
%endif %endif
ParamsPtr: dd _InstrumentParams ParamsPtr: dd InstrumentParams
TonesPtr: dd _InstrumentTones TonesPtr: dd InstrumentTones
TovelPtr: dd _TrackData TovelPtr: dd TrackData
LengthPtr: dd _NoteLengths LengthPtr: dd NoteLengths
NotePtr: dd _NoteSamples NotePtr: dd NoteSamples
MixingPtr: dd 0 MixingPtr: dd 0
%if NUM_TRACKS_WITH_REVERB > 0 %if NUM_TRACKS_WITH_REVERB > 0
...@@ -180,11 +185,11 @@ ReverbState: ...@@ -180,11 +185,11 @@ ReverbState:
dq 0.0,0.0,0.0,0.0 dq 0.0,0.0,0.0,0.0
%endif %endif
section offset rdata align=4 SECT_RDATA(offset) align=4
c_timeoffset: c_timeoffset:
dd OIDOS_TIMER_OFFSET*4 dd OIDOS_TIMER_OFFSET*4
section tempo rdata align=4 SECT_RDATA(tempo) align=4
c_ticklength: c_ticklength:
dd SAMPLES_PER_TICK*4 dd SAMPLES_PER_TICK*4
...@@ -233,7 +238,7 @@ c_ticklength: ...@@ -233,7 +238,7 @@ c_ticklength:
;; ********** Instrument calculation ********** ;; ********** Instrument calculation **********
section makeinst text align=1 SECT_TEXT(makeinst) align=1
MakeInstrument: MakeInstrument:
mov PARAMS, [BASE + ParamsPtr] mov PARAMS, [BASE + ParamsPtr]
...@@ -255,7 +260,7 @@ MakeInstrument: ...@@ -255,7 +260,7 @@ MakeInstrument:
add RANDOM, [PARAMS] ; seed add RANDOM, [PARAMS] ; seed
add PARAMS, byte 4 add PARAMS, byte 4
shl RANDOM, 2 shl RANDOM, 2
add RANDOM, _Oidos_RandomData add RANDOM, PUBLIC_FN(Oidos_RandomData)
GETRANDOM ; subtone GETRANDOM ; subtone
fabs fabs
...@@ -437,7 +442,7 @@ MakeInstrument: ...@@ -437,7 +442,7 @@ MakeInstrument:
;; ********** Track mixing ********** ;; ********** Track mixing **********
section makechan text align=1 SECT_TEXT(makechan) align=1
MakeChannel: MakeChannel:
mov SAMPLE, SampleBuffer mov SAMPLE, SampleBuffer
push byte 0 push byte 0
...@@ -589,8 +594,8 @@ MakeChannel: ...@@ -589,8 +594,8 @@ MakeChannel:
;; ********** Main ********** ;; ********** Main **********
section synth text align=1 SECT_TEXT(synth) align=1
_Oidos_GenerateMusic: PUBLIC_FN(Oidos_GenerateMusic):
%if OIDOS_SAVE_REGISTERS %if OIDOS_SAVE_REGISTERS
pusha pusha
%endif %endif
...@@ -615,7 +620,7 @@ _Oidos_GenerateMusic: ...@@ -615,7 +620,7 @@ _Oidos_GenerateMusic:
%if REVERB_MIN_DELAY != 0 %if REVERB_MIN_DELAY != 0
sub eax, REVERB_MIN_DELAY sub eax, REVERB_MIN_DELAY
%endif %endif
mul dword [_Oidos_RandomData + REVERB_RANDOMSEED*4 + ecx*4] mul dword [PUBLIC_FN(Oidos_RandomData) + REVERB_RANDOMSEED*4 + ecx*4]
cmp edx, esi cmp edx, esi
jae short .skip jae short .skip
...@@ -692,7 +697,7 @@ _Oidos_GenerateMusic: ...@@ -692,7 +697,7 @@ _Oidos_GenerateMusic:
fcmovnb st0, st1 fcmovnb st0, st1
fchs fchs
fistp word [_Oidos_MusicBuffer + ebx*2] fistp word [PUBLIC_FN(Oidos_MusicBuffer) + ebx*2]
add ebx, byte 1 add ebx, byte 1
cmp ebx, TOTAL_SAMPLES*2 cmp ebx, TOTAL_SAMPLES*2
...@@ -704,7 +709,7 @@ _Oidos_GenerateMusic: ...@@ -704,7 +709,7 @@ _Oidos_GenerateMusic:
%endif %endif
ret ret
section rfilter text align=1 SECT_TEXT(rfilter) align=1
ReverbFilter: ReverbFilter:
%macro FILTER 0 %macro FILTER 0
; Basic low-pass filter ; Basic low-pass filter
...@@ -731,40 +736,43 @@ ReverbFilter: ...@@ -731,40 +736,43 @@ ReverbFilter:
ret ret
;; ********** Play ********** ; ********** Play **********
section startsnd text align=1 %ifdef WIN32
_Oidos_StartMusic: SECT_TEXT(startsnd) align=1
PUBLIC_FN(Oidos_StartMusic):
; Start music ; Start music
push byte 0 push byte 0
push byte 0 push byte 0
push byte 0 push byte 0
push _WaveFormat push WaveFormat
push byte -1 push byte -1
push _WaveOutHandle push WaveOutHandle
call [__imp__waveOutOpen@24] call [__imp__waveOutOpen@24]
push byte 32 ; sizeof(WAVEHDR) push byte 32 ; sizeof(WAVEHDR)
push _WaveHdr push WaveHdr
push dword [_WaveOutHandle] ; waveOutHandle push dword [WaveOutHandle] ; waveOutHandle
call [__imp__waveOutPrepareHeader@12] call [__imp__waveOutPrepareHeader@12]
push byte 32 ; sizeof(WAVEHDR) push byte 32 ; sizeof(WAVEHDR)
push _WaveHdr push WaveHdr
push dword [_WaveOutHandle] push dword [WaveOutHandle]
call [__imp__waveOutWrite@12] call [__imp__waveOutWrite@12]
ret ret
section getpos text align=1 SECT_TEXT(getpos) align=1
_Oidos_GetPosition: PUBLIC_FN(Oidos_GetPosition):
push byte 32 ; sizeof(MMTIME) push byte 32 ; sizeof(MMTIME)
push _WaveTime push WaveTime
push dword [_WaveOutHandle] push dword [WaveOutHandle]
call [__imp__waveOutGetPosition@12] call [__imp__waveOutGetPosition@12]
fild dword [_WaveTime+4] fild dword [WaveTime+4]
%if OIDOS_TIMER_OFFSET>0 %if OIDOS_TIMER_OFFSET>0
fiadd dword [c_timeoffset] fiadd dword [c_timeoffset]
%endif %endif
fidiv dword [c_ticklength] fidiv dword [c_ticklength]
ret ret
%endif
#ifndef _OIDOS_H_ #ifndef _OIDOS_H_
#define _OIDOS_H_ #define _OIDOS_H_
#include <stdint.h>
struct sample { struct sample {
short left,right; short left,right;
}; };
#ifdef __cplusplus
extern "C" { extern "C" {
#endif
// Fill the block of random data used by Oidos. // Fill the block of random data used by Oidos.
// Must be called before Oidos_GenerateMusic. // Must be called before Oidos_GenerateMusic.
void Oidos_FillRandomData(); void Oidos_FillRandomData();
...@@ -15,6 +19,9 @@ extern "C" { ...@@ -15,6 +19,9 @@ extern "C" {
// and Oidos_StartMusic can be called. // and Oidos_StartMusic can be called.
void Oidos_GenerateMusic(); void Oidos_GenerateMusic();
// On Linux, there are too many sound APIs to choose from,
// so I can't just force anyone to use a specific one. -pcy
#ifdef WIN32
// Play the music // Play the music
void Oidos_StartMusic(); void Oidos_StartMusic();
...@@ -22,6 +29,7 @@ extern "C" { ...@@ -22,6 +29,7 @@ extern "C" {
// Use this function as the timer for the visuals in your intro. // Use this function as the timer for the visuals in your intro.
// Returned value is measured in music ticks (pattern rows). // Returned value is measured in music ticks (pattern rows).
float Oidos_GetPosition(); float Oidos_GetPosition();
#endif
// Buffer containing the music. // Buffer containing the music.
extern struct sample Oidos_MusicBuffer[]; extern struct sample Oidos_MusicBuffer[];
...@@ -41,11 +49,10 @@ extern "C" { ...@@ -41,11 +49,10 @@ extern "C" {
// Can also be useful as a 3D noise texture. // Can also be useful as a 3D noise texture.
#define NOISESIZE 64 #define NOISESIZE 64
extern unsigned Oidos_RandomData[NOISESIZE * NOISESIZE * NOISESIZE]; extern unsigned Oidos_RandomData[NOISESIZE * NOISESIZE * NOISESIZE];
#ifdef __cplusplus
}; };
// If you are using D3D11, you can re-use this GUID.
#ifdef GUID_DEFINED
extern GUID ID3D11Texture2D_ID;
#endif #endif
extern uint32_t ID3D11Texture2D_ID[4];
#endif #endif
; See oidos.h for documentation. ; See oidos.h for documentation.
%include "platform.inc"
; Functions ; Functions
extern _Oidos_FillRandomData extern PUBLIC_FN(Oidos_FillRandomData)
extern _Oidos_GenerateMusic extern PUBLIC_FN(Oidos_GenerateMusic)
extern _Oidos_StartMusic extern PUBLIC_FN(Oidos_StartMusic)
extern _Oidos_GetPosition extern PUBLIC_FN(Oidos_GetPosition)
; Variables ; Variables
extern _Oidos_MusicBuffer extern PUBLIC_FN(Oidos_MusicBuffer)
extern _Oidos_TicksPerSecond extern PUBLIC_FN(Oidos_TicksPerSecond)
extern _Oidos_MusicLength extern PUBLIC_FN(Oidos_MusicLength)
extern _Oidos_WavFileHeader extern PUBLIC_FN(Oidos_WavFileHeader)
extern _Oidos_RandomData extern PUBLIC_FN(Oidos_RandomData)
; GUID ; GUID
extern ?ID3D11Texture2D_ID@@3U_GUID@@A extern ID3D11Texture2D_ID
; vim: set ft=asm
%ifdef LINUX
%define PUBLIC_FN(n) n
%else
%define PUBLIC_FN(n) _ %+ n
%endif
%ifdef WIN32
%define ID3D11Texture2D_ID ?ID3D11Texture2D_ID@@3U_GUID@@A
%endif
%ifdef LINUX
%define SECT_BSS(n) section .bss.oidos. %+ n nobits alloc noexec write
%define SECT_DATA(n) section .data.oidos. %+ n progbits alloc noexec write
%define SECT_RDATA(n) section .rodata.oidos. %+ n progbits alloc noexec nowrite
%define SECT_TEXT(n) section .text.oidos. %+ n progbits alloc exec nowrite
%else
%define SECT_BSS(n) section .oidos. %+ n bss
%define SECT_DATA(n) section .oidos. %+ n data
%define SECT_RDATA(n) section .oidos. %+ n rdata
%define SECT_TEXT(n) section .oidos. %+ n code
%endif
; Stand-alone executable for playing an Oidos song. ; Stand-alone executable for playing an Oidos song.
; (Windows-only)
%include "oidos.inc" %include "oidos.inc"
global _main global _main
......
#include <unistd.h>
#include "oidos.h"
int main() {
Oidos_FillRandomData();
Oidos_GenerateMusic();
#ifndef NO_WAV_HEADER
write(STDOUT_FILENO, Oidos_WavFileHeader, sizeof(Oidos_WavFileHeader));
#endif
write(STDOUT_FILENO, Oidos_MusicBuffer, Oidos_WavFileHeader[10]);
}
; Block of random data used by Oidos. ; Block of random data used by Oidos.
; Can also be useful as a 3D noise texture. ; Can also be useful as a 3D noise texture.
global _Oidos_FillRandomData %include "platform.inc"
global _Oidos_RandomData
global ?ID3D11Texture2D_ID@@3U_GUID@@A global PUBLIC_FN(Oidos_FillRandomData)
global PUBLIC_FN(Oidos_RandomData)
global ID3D11Texture2D_ID
%define NOISESIZE 64 %define NOISESIZE 64
section guid data align=4 SECT_DATA(d3dtex) align=4
; If you are using D3D11, you can re-use this GUID. ; If you are using D3D11, you can re-use this GUID.
?ID3D11Texture2D_ID@@3U_GUID@@A: ; It's used as a rng seed, so this can't simply be thrown out on Linux -pcy
ID3D11Texture2D_ID:
db 0xF2,0xAA,0x15,0x6F, 0x08,0xD2,0x89,0x4E, 0x9A,0xB4,0x48,0x95, 0x35,0xD3,0x4F,0x9C db 0xF2,0xAA,0x15,0x6F, 0x08,0xD2,0x89,0x4E, 0x9A,0xB4,0x48,0x95, 0x35,0xD3,0x4F,0x9C
section randdata bss align=4 SECT_BSS(randomdat) align=4
_Oidos_RandomData: PUBLIC_FN(Oidos_RandomData):
.align16
resd NOISESIZE*NOISESIZE*NOISESIZE resd NOISESIZE*NOISESIZE*NOISESIZE
section fillrand text align=1 SECT_TEXT(fillrandom) align=1
_Oidos_FillRandomData: PUBLIC_FN(Oidos_FillRandomData):
mov eax, _Oidos_RandomData mov eax, PUBLIC_FN(Oidos_RandomData)
.loop: .loop:
mov edx, ?ID3D11Texture2D_ID@@3U_GUID@@A mov edx, ID3D11Texture2D_ID
mov ecx, [edx] mov ecx, [edx]
ror ecx, cl ror ecx, cl
...@@ -49,6 +51,6 @@ _Oidos_FillRandomData: ...@@ -49,6 +51,6 @@ _Oidos_FillRandomData:
xor [eax], ecx xor [eax], ecx
add eax, byte 4 add eax, byte 4
cmp eax, _Oidos_RandomData+NOISESIZE*NOISESIZE*NOISESIZE*4 cmp eax, PUBLIC_FN(Oidos_RandomData)+NOISESIZE*NOISESIZE*NOISESIZE*4