d21a6e85e7
git-svn-id: svn://kolibrios.org@1845 a494cfbc-eb01-0410-851d-a64ba20cac60
226 lines
5.5 KiB
NASM
226 lines
5.5 KiB
NASM
; MINI.ASM
|
|
; --------
|
|
; Minimalistic uFMOD usage example.
|
|
|
|
; Shows how to play an XM track in memory,
|
|
; including proper error handling.
|
|
|
|
BITS 32
|
|
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:
|
|
%define f48000 ; Set sampling rate to 48KHz (22050, 44100, 48000)
|
|
%define STRONG ; Select STRONG interpolation (NONE, WEAK, STRONG)
|
|
%define UNSAFE ; Select UNSAFE mode (NORMAL, UNSAFE)
|
|
%define NODEBUG ; Skip debug-board messages
|
|
%define NOLINKER ; Select "no linker" mode
|
|
|
|
; uFMOD constants:
|
|
%define uFMOD_MIN_VOL 0
|
|
%define uFMOD_MAX_VOL 25
|
|
%define uFMOD_DEFAULT_VOL 25
|
|
|
|
; The XM track.
|
|
xm incbin "..\ufmodlib\media\mini.xm"
|
|
xm_length equ $ - xm
|
|
|
|
; Optimization:
|
|
; This header file is suitable for mini.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\mini.eff.inc"
|
|
|
|
; UI text messages.
|
|
msg_txt db "uFMOD ruleZ!"
|
|
msg_txt_l equ $ - msg_txt
|
|
msg_cap db "NASM",0
|
|
err_txt db "Error"
|
|
err_txt_l equ $ - 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
|
|
|
|
; Wait for user input.
|
|
push _uFMOD_WaveOut ; cbProc <- continue fetching data!
|
|
push msg_txt_l ; cbString
|
|
push msg_txt ; lpString
|
|
push msg_cap ; szCap
|
|
call _MessageBoxCB
|
|
; add esp,16
|
|
|
|
; Stop playback.
|
|
call _uFMOD_StopSong
|
|
|
|
r: ; Exit.
|
|
xor eax,eax
|
|
dec eax
|
|
int 40h
|
|
|
|
error:
|
|
push 0 ; cbProc <- no callback
|
|
push err_txt_l ; cbString
|
|
push err_txt ; lpString
|
|
push err_cap ; szCap
|
|
call _MessageBoxCB
|
|
; add esp,16
|
|
jmp r
|
|
|
|
; ---------------------------------------------------------------
|
|
; void _cdecl _MessageBoxCB(szCap, lpString, cbString, cbProc);
|
|
; ---------------------------------------------------------------
|
|
|
|
; This is similar to a Win32 MessageBox. The box is centered
|
|
; on screen. It contains a single-line text message and an
|
|
; "OK" button. This function returns when user closes the
|
|
; box (via the X button or via the OK button). An optional
|
|
; callback subroutine may be specified to be called when no
|
|
; events are pending in the event queue.
|
|
|
|
; NOTE: Doesn't work if you already have defined a window
|
|
; in the current process! Doesn't modify the event mask. So,
|
|
; make sure keyboard events are enabled before calling this
|
|
; function. This function doesn't check the validity of the
|
|
; supplied parameters!
|
|
|
|
; Parameters:
|
|
; szCap - A pointer to the ASCIIz string containing the
|
|
; caption. A trailing zero char IS required.
|
|
; lpString - A pointer to an ASCII string containing a single
|
|
; line message to pop up in the box. No trailing
|
|
; zero char is required.
|
|
; cbString - number of characters in string.
|
|
; cbProc - Address of the callback subroutine. Can be NULL.
|
|
|
|
sOK db "OK"
|
|
_MessageBoxCB:
|
|
push ebp
|
|
push esi
|
|
push edi
|
|
push ebx
|
|
xor ebp,ebp ; global 0
|
|
mov esi,[esp+28] ; cbString
|
|
mov edi,[esp+20] ; szCap
|
|
|
|
; 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
|
|
lea ebx,[esi*2+esi]
|
|
lea ebx,[ebx*2+28] ; w = string len * 6 + 28
|
|
sub ecx,ebx
|
|
shr ecx,1
|
|
shl ecx,16
|
|
or ebx,ecx
|
|
lea ecx,[ebp+52h] ; h = 52h
|
|
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
|
|
|
|
_MessageBoxCB_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
|
|
int 40h
|
|
|
|
; Define the OK button.
|
|
push esi
|
|
lea eax,[ebp+8]
|
|
sub ebx,28+0Ah
|
|
shr bx,1
|
|
shl ebx,16 ; x = (window w - button w) / 2
|
|
mov bx,18+0Ah ; w = 18 + 0Ah
|
|
mov ecx,001C0012h ; y = 1Ch, h = 12h
|
|
lea edx,[ebp+1] ; ID = close
|
|
mov esi,0C0C0C0h ; color
|
|
int 40h
|
|
|
|
; Draw the OK label.
|
|
lea eax,[ebp+4]
|
|
add ebx,90000h ; x = button x + 9
|
|
mov bx,22h ; y = 22h
|
|
xor ecx,ecx ; style, font and color
|
|
mov edx,sOK ; string
|
|
lea esi,[ebp+2] ; length
|
|
int 40h
|
|
pop esi
|
|
|
|
; Draw text string.
|
|
lea eax,[ebp+4]
|
|
mov ebx,000A000Ah ; x = 0Ah, y = 0Ah
|
|
xor ecx,ecx ; style, font and color
|
|
mov edx,[esp+28] ; lpString
|
|
int 40h
|
|
|
|
; End redraw.
|
|
lea eax,[ebp+12]
|
|
lea ebx,[ebp+2]
|
|
int 40h
|
|
|
|
_MessageBoxCB_eventloop:
|
|
mov edx,[esp+36] ; cbProc
|
|
test edx,edx
|
|
lea eax,[ebp+10]
|
|
jz _MessageBoxCB_peekevent
|
|
|
|
; Invoke the callback.
|
|
call edx
|
|
|
|
lea eax,[ebp+23]
|
|
lea ebx,[ebp+10] ; wait for at most 0.1 sec
|
|
_MessageBoxCB_peekevent:
|
|
int 40h
|
|
dec eax
|
|
js _MessageBoxCB_eventloop
|
|
|
|
pop edx
|
|
jz _MessageBoxCB_redraw
|
|
|
|
pop ebx
|
|
pop edi
|
|
pop esi
|
|
pop ebp
|
|
ret
|
|
|
|
; Include the whole uFMOD sources here. (Right after
|
|
; your main code to avoid naming conflicts, but still
|
|
; inside your code section.)
|
|
%include "nasm.asm"
|
|
|
|
alignb 4
|
|
resb 1020
|
|
STACK_B resd 1 ; Stack bottom
|
|
MEMORY_END: ; End of uninitialized (BSS) data
|