kolibrios/programs/develop/libraries/ufmod/Fasm/jmp2pat.asm
Yogev Ezra d21a6e85e7 Added libraries/ufmod source code.
git-svn-id: svn://kolibrios.org@1845 a494cfbc-eb01-0410-851d-a64ba20cac60
2011-02-04 20:13:33 +00:00

240 lines
5.3 KiB
NASM

; JMP2PAT.ASM
; -----------
; Sometimes it makes sense merging various XM tracks
; sharing the same instruments in a single XM file.
; This example program uses such an XM file actually
; containing 3 tracks and the _uFMOD_Jump2Pattern
; function to play all 3 tracks in the same file.
; A precompiled version (not packed or whatever) is
; available in bin\
use32
org 0
db 'MENUET01'
dd 1
dd START ; Entry point
dd uFMOD_IMG_END ; End of code and initialized data
dd MEMORY_END ; End of uninitialized (BSS) data
dd STACK_B ; Bottom of the stack
dd 0 ; Args
dd 0 ; Reserved
; uFMOD setup:
UF_FREQ equ 48000 ; Set sampling rate to 48KHz (22050, 44100, 48000)
UF_RAMP equ STRONG ; Select STRONG interpolation (NONE, WEAK, STRONG)
UD_MODE equ UNSAFE ; Select UNSAFE mode (NORMAL, UNSAFE)
DEBUG equ 0 ; Skip debug-board messages
NOLINKER equ 1 ; Select "no linker" mode
; uFMOD constants:
XM_MEMORY = 1
XM_FILE = 2
XM_NOLOOP = 8
XM_SUSPENDED = 16
uFMOD_MIN_VOL = 0
uFMOD_MAX_VOL = 25
uFMOD_DEFAULT_VOL = 25
; BLITZXMK.XM tracked by Kim (aka norki):
; [00:07] - track #1
; [08:10] - track #2
; [11:13] - track #3
xm file '..\ufmodlib\media\BLITZXMK.XM'
xm_length = $ - xm
; Optimization:
; This header file is suitable for blitzxmk.xm track only!
; If you change the track, update the optimization header.
; (Use the standart eff.inc file for a general purpose player app.)
include '..\ufmodlib\media\blitz.eff.inc'
; Include the GUI framework.
FRMWRK_CALLBACK_ON equ 0 ; Disable callback
include 'frmwrk.asm'
; UI text messages.
vals dd 0,8,11 ; Preset pattern indexes
wnd_btns1 db "1 2 3 Pause "
wnd_btns2 db "1 2 3 Resume"
wnd_btns_l = $ - wnd_btns2
wnd_cap db "Jump2Pattern",0
err_txt db "Error"
err_txt_l = $ - err_txt
err_cap db ":-(",0
START:
; Start playback.
push XM_MEMORY
push xm_length
push xm
call _uFMOD_LoadSong
; Stack fixing is required here, but in this simple
; example leaving ESP as it is won't harm. In a real
; application you should uncomment the following line:
; add esp,12
test eax,eax
jz error
xor ebp,ebp ; global 0
mov [wnd_btns],wnd_btns1
; Switch keyboard mode to SCANCODE.
lea ebx,[ebp+1]
lea eax,[ebp+66]
mov ecx,ebx
int 40h
; Get screen metrics.
lea eax,[ebp+14]
int 40h
mov ecx,eax
movzx eax,ax
shr ecx,16 ; screen w
xchg eax,edx ; screen h
mov ebx,wnd_btns_l*6+42
sub ecx,ebx
shr ecx,1
shl ecx,16
or ebx,ecx
lea ecx,[ebp+40h] ; h = 40h
sub edx,ecx
shr edx,1
shl edx,16
or ecx,edx ; y = (screen h - window h) / 2
mov edx,ebx ; x = (screen w - window w) / 2
redraw:
; Start redraw.
push edx
lea eax,[ebp+12]
lea ebx,[ebp+1]
int 40h
; Define and draw window.
xor eax,eax
mov ebx,edx ; x, w (ECX: y, h)
mov edx,34C0C0C0h ; style and BG color
mov edi,wnd_cap
int 40h
; Define the 1 2 3 Pause/Resume buttons.
lea eax,[ebp+8]
mov ebx,0A0012h ; x = 0Ah, w = 12h
mov ecx,0A0012h ; y = 0Ah, h = 10h
lea edx,[ebp+10] ; ID = #10
mov esi,0C0C0C0h ; color
int 40h
mov ebx,280012h ; x = 28h, w = 12h
inc edx ; ID = #11
int 40h
mov ebx,460012h ; x = 46h, w = 12h
inc edx ; ID = #12
int 40h
mov ebx,640030h ; x = 64h, w = 30h
inc edx ; ID = #13
int 40h
; Draw the labels.
lea eax,[ebp+4]
mov ebx,120011h ; x = 12h, y = 11h
xor ecx,ecx ; style, font and color
mov edx,[wnd_btns] ; string
lea esi,[ebp+wnd_btns_l] ; length
int 40h
; End redraw.
lea eax,[ebp+12]
lea ebx,[ebp+2]
int 40h
eventloop:
; Update the PCM buffer.
call _uFMOD_WaveOut
lea eax,[ebp+23]
lea ebx,[ebp+10] ; wait for at most 0.1 sec
int 40h
dec eax
js eventloop ; 0 = idle
jz redraw ; 1 = redraw
dec eax ; 2 = keyboard event
jnz chk_eventbutton
; Get key scancode.
lea eax,[ebp+2]
int 40h
cmp ah,19h ; P
je do_PauseResume
cmp ah,13h ; R
je do_PauseResume
chk_kb123:
movzx eax,ah
sub eax,2
jmp do_Jump2Pat123
chk_eventbutton: ; 3 = button event
lea eax,[ebp+17]
int 40h
cmp ah,1 ; Close
je break_loop
cmp ah,13 ; Pause/Resume
jne chk_btn123
do_PauseResume:
cmp BYTE [paused],1
mov edx,_uFMOD_Resume
mov ebx,wnd_btns1
je do_Resume
mov edx,_uFMOD_Pause
mov ebx,wnd_btns2
do_Resume:
call edx
xor BYTE [paused],1
mov [wnd_btns],ebx
jmp redraw
chk_btn123: ; 1 2 3
movzx eax,ah
sub eax,10
do_Jump2Pat123:
cmp eax,3
jae eventloop
push DWORD [vals+eax*4]
call _uFMOD_Jump2Pattern
pop eax ; fix stack
jmp eventloop
break_loop:
; Stop playback.
call _uFMOD_StopSong
r: ; Exit.
xor eax,eax
dec eax
int 40h
error:
push err_txt_l ; cbString
push err_txt ; lpString
push err_cap ; szCap
call _MessageBox
; add esp,16
jmp r
; Include the whole uFMOD sources here. (Right after
; your main code to avoid naming conflicts, but still
; inside your code section.)
macro PUBLIC symbol {} ; hide all publics
include '..\ufmodlib\src\fasm.asm'
wnd_btns dd ?
paused db ?
align 4
rb 1020
STACK_B dd ? ; Stack bottom
MEMORY_END: ; End of uninitialized (BSS) data