forked from KolibriOS/kolibrios
240 lines
5.3 KiB
NASM
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
|