; 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