Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4322 → Rev 4323

/programs/games/bomber/ssmix.inc
0,0 → 1,571
SSMIX_CHANMODE_FREE equ 0
SSMIX_CHANMODE_SINGLE equ 1
SSMIX_CHANMODE_REPEAT equ 2
SSMIX_CHANMODE_SINGLE_WITHOUT_RESET equ 3
SSMIX_CHANMODE_WAITRESET equ 4
 
include 'snd.inc'
include 'snd_const.inc'
include 'proc32.inc'
;include 'macros.inc'
;include 'debug.inc'
 
SSMIX_CHANNEL_COUNT equ 32
 
DEBUG equ 0 ; 0
 
 
; èíèöèàëèçàöèÿ ìèêøåðà
ssmix_init:
; âûäåëèòü ïàìÿòü äëÿ êàíàëîâ ìèêøåðà
mov eax, 68
mov ebx, 12
mov ecx, 4*8*SSMIX_CHANNEL_COUNT
int 0x40
mov [ssmix_channels], eax
; âûäåëèòü ïàìÿòü äëÿ ñòåêà ïîòîêà ìèêøåðà
mov eax, 68
mov ebx, 12
mov ecx, 4096
int 0x40
mov [ssmix_thread_stack], eax
; âêëþ÷èòü ìèêøåð
mov [ssmix_state], 1
; óñòàíîâèòü ãðîìêîñòè ñòåðåîêàíàëîâ
mov [ssmix_volumeL], 128
mov [ssmix_volumeR], 128
; ñîçäàòü ïîòîê
mov eax, 51
mov ebx, 1
mov ecx, ssmix_thread_proc
mov edx,[ssmix_thread_stack]
add edx,4092
int 0x40
 
ret
 
 
 
; çàâåðøåíèå ðàáîòû ìèêøåðà
ssmix_release:
; âûêëþ÷èòü ìèêøåð
mov [ssmix_state], 0
 
ret
 
 
 
; îñâîáîæäåíèå ïàìÿòè
ssmix_free:
; îñâîáîäèòü ïàìÿòü êàíàëîâ ìèêøåðà
mov eax, 68
mov ebx, 13
mov ecx, [ssmix_channels]
int 0x40
; îñâîáîäèòü ïàìÿòü ñòåêà ïîòîêà ìèêøåðà
mov eax, 68
mov ebx, 13
mov ecx, [ssmix_thread_stack]
int 0x40
 
ret
 
; óñòàíîâèòü ãðîìêîñòü
ssmix_setvolume: ; stdcall
; LeftVolume: dword, RightVolume: dword
 
push eax
mov eax, [esp+8] ; ãðîìêîñòü ëåâîãî êàíàëà
cmp eax, 255
jle @f
mov eax, 255
@@:
cmp eax, 0
jge @f
mov eax, 0
@@:
mov [ssmix_volumeL], eax
 
mov eax, [esp+12] ; ãðîìêîñòü ïðàâîãî êàíàëà
cmp eax, 255
jle @f
mov eax, 255
@@:
cmp eax, 0
jge @f
mov eax, 0
@@:
mov [ssmix_volumeR], eax
pop eax
 
ret
 
 
; âîñïðîèçâåñòè òðåê
ssmix_playtrack: ; stdcall
; p_starttrack:dword, p_endtrack:dword, volumeL: dword, volumeR: dword; playmode:dword;
; return eax - number of channel, if eax=-1 then no free channel
 
push ebx ecx
mov ebx, [ssmix_channels]
mov ecx, SSMIX_CHANNEL_COUNT
.channel_loop:
mov eax, [ebx]
cmp eax, SSMIX_CHANMODE_FREE
je .find_free_channel
add ebx, 32
dec ecx
jnz .channel_loop
mov eax, -1
jmp .end
.find_free_channel:
mov eax, [esp+28] ; ðåæèì âîñïðîèçâåäåíèÿ
mov [ebx], eax
mov eax, [esp+20] ; ãðîìêîñòü ëåâîãî êàíàëà
imul eax, [ssmix_volumeL]
sar eax, 7
mov [ebx+4], eax
mov eax, [esp+24] ; ãðîìêîñòü ïðàâîãî êàíàëà
imul eax, [ssmix_volumeR]
sar eax, 7
mov [ebx+8], eax
mov eax, [esp+12] ; íà÷àëî òðåêà
mov [ebx+16], eax
mov [ebx+20], eax
mov eax, [esp+16] ; êîíåö òðåêà
mov [ebx+24], eax
mov eax, SSMIX_CHANNEL_COUNT
sub eax, ecx
.end:
pop ecx ebx
 
ret 20
 
 
; îñòàíîâèòü òðåê ïî íîìåðó êàíàëà
ssmix_stoptrack: ; stdcall
; numchannel: dword
push eax ebx
mov ebx, [esp+12]
cmp ebx, 0
jl .end
cmp ebx, SSMIX_CHANNEL_COUNT
jge .end
shl ebx, 5
add ebx, [ssmix_channels]
mov eax, SSMIX_CHANMODE_FREE
mov [ebx], eax
.end:
pop ebx eax
 
ret 4
 
 
; îñòàíîâèòü âñå òðåêè
ssmix_stopalltracks:
 
push eax ebx ecx
mov eax, SSMIX_CHANMODE_FREE
mov ebx, [ssmix_channels]
mov ecx, SSMIX_CHANNEL_COUNT
.channel_loop:
mov [ebx], eax
add ebx, 32
dec ecx
jnz .channel_loop
pop ecx ebx eax
 
ret
 
 
; ïîòîê ìèêøåðà
ssmix_thread_proc:
 
stdcall _InitSound@4, ssmix_driver_version
test eax, eax
jz @f
if DEBUG
print "ssmix. Cannot load sound driver"
end if
jmp .end
@@:
 
mov ecx, [ssmix_driver_version]
cmp cx, SOUND_VERSION
jae @f
shr ecx, 16
cmp ecx, SOUND_VERSION
jbe @f
if DEBUG
print "ssmix. Sound version mismatch"
end if
jmp .end
@@:
 
stdcall _CreateBuffer@12, PCM_2_16_11+PCM_RING, 0, ssmix_hbuffer
test eax, eax
jz @f
if DEBUG
print "ssmix. create buffer error"
end if
jmp .end
@@:
 
stdcall _GetBufferSize@8, [ssmix_hbuffer], ssmix_buffer_size
test eax, eax
jz @f
if DEBUG
print "ssmix. getbuffersize procedure error"
end if
jmp .destroy_buffer
@@:
 
mov ecx, [ssmix_buffer_size]
shr ecx, 1
mov [ssmix_buffer_size], ecx
if DEBUG
print "ssmix. buffer size"
dph ecx
newline
end if
 
; âûäåëèòü ïàìÿòü äëÿ áóôôåðà âîñïðîèçâåäåíèÿ
mov eax, 68
mov ebx, 12
mov ecx, [ssmix_buffer_size]
int 0x40
test eax, eax
jnz @f
if DEBUG
print "ssmix. malloc memory error"
end if
jmp .destroy_buffer
@@:
mov [ssmix_pbuffer], eax
 
stdcall _PlayBuffer@8, [ssmix_hbuffer], 0
test eax, eax
jz @f
if DEBUG
print "ssmix. playbuffer error"
end if
jmp .free_buffer_memory
@@:
 
; öèêë âîñïðîèçâåäåíèÿ
.mixloop:
; ïîëó÷èòü äàííûå ñîáûòèÿ îò äðàéâåðà
mov eax, 68
mov ebx, 14
mov ecx, ssmix_driver_notify_struct
int 0x40
; ïðîâåðêà íà code
mov eax, [ssmix_driver_notify_struct]
cmp eax, 0xFF000001
jne .mixloop
; ïðîâåðêà íà stream
mov eax, [ssmix_driver_notify_struct+8]
cmp eax, [ssmix_hbuffer]
jne .mixloop
; ïîëó÷èòü ñìåùåíèå â áóôôåðå
mov eax, [ssmix_driver_notify_struct+12]
mov [ssmix_buffer_offset], eax
; öèêë çàïîëíåíèÿ áóôôåðà
mov ebx, [ssmix_pbuffer]
mov ecx, [ssmix_buffer_size]
shr ecx, 2
.fill_buffer_loop:
push ebx ecx
; öèêë ñìåøèâàíèÿ êàíàëîâ
mov esi, 0 ; ñóììà äëÿ ëåâîãî ñòåðåîêàíàëà
mov edi, 0 ; ñóììà äëÿ ïðàâîãî ñòåðåîêàíàëà
mov edx, [ssmix_channels]
mov ecx, SSMIX_CHANNEL_COUNT
.channel_loop:
mov eax, [edx]
cmp eax, SSMIX_CHANMODE_FREE
je .channel_end
cmp eax, SSMIX_CHANMODE_WAITRESET
je .channel_end
push ecx
; ñìåøèâàíèå êàíàëîâ ñ ó÷åòîì ãðîìêîñòè
mov ebx, [edx+4]
mov ecx, [edx+16]
movsx eax, word [ecx]
imul eax, ebx
add esi, eax
mov ebx, [edx+8]
movsx eax, word [ecx+2]
imul eax, ebx
add edi, eax
; ïðîâåðêà íà çàâåðøåíèå òðåêà
add ecx, 4
cmp ecx, [edx+24]
jb .notrackend
mov eax, [edx]
cmp eax, SSMIX_CHANMODE_SINGLE
jne @f
mov ebx, SSMIX_CHANMODE_FREE
mov [edx], ebx
jmp .notrackend
@@:
cmp eax, SSMIX_CHANMODE_REPEAT
jne @f
mov ecx, [edx+20]
jmp .notrackend
@@:
cmp eax, SSMIX_CHANMODE_SINGLE_WITHOUT_RESET
jne @f
mov ebx, SSMIX_CHANMODE_WAITRESET
mov [edx], ebx
jmp .notrackend
@@:
.notrackend:
mov [edx+16], ecx
pop ecx
.channel_end:
add edx, 32
dec ecx
jnz .channel_loop
; íîðìàëèçàöèÿ ñòåðåîêàíàëîâ
sar esi, 7
cmp esi, 0x7FFF
jle @f
mov esi, 0x7FFF
@@:
cmp esi, -0x8000
jge @f
mov esi, -0x8000
@@:
sar edi, 7
cmp edi, 0x7FFF
jle @f
mov edi, 0x7FFF
@@:
cmp edi, -0x8000
jge @f
mov edi, -0x8000
@@:
; ñîõðàíåíèå ðåçóëüòàòà â áóôôåðå ìèêøåðà
shl edi, 16
add esi, edi
pop ecx ebx
mov [ebx], esi
add ebx, 4
dec ecx
jnz .fill_buffer_loop
; óñòàíîâêà áóôôåðà äðàéâåðà
stdcall _SetBuffer@16, [ssmix_hbuffer], [ssmix_pbuffer], [ssmix_buffer_offset], [ssmix_buffer_size]
cmp [ssmix_state], 1
je .mixloop
 
; îñâîáîäèòü ïàìÿòü áóôôåðà âîñïðîèçâåäåíèÿ
.free_buffer_memory:
mov eax, 68
mov ebx, 13
mov ecx, [ssmix_pbuffer]
; óíè÷òîæèòü áóôôåð äðàéâåðà
.destroy_buffer:
stdcall _DestroyBuffer@4, [ssmix_hbuffer]
 
; çàâåðøèòü ðàáîòó ïîòîêà
.end:
call ssmix_free
mov eax, -1
int 0x40
 
;ret
 
 
;=================================================================================
 
align 4
_InitSound@4: ;p_ver:dword
 
push ebx
push ecx
 
mov eax, 68
mov ebx, 16
mov ecx, ssmix_szInfinity
int 0x40
mov [ssmix_hSound], eax
test eax, eax
jz .fail
 
mov eax, 68
mov ebx, 16
mov ecx, ssmix_szSound
int 0x40
mov [ssmix_hrdwSound], eax
 
lea eax, [esp+12] ;p_ver
xor ebx, ebx
 
push 4 ;.out_size
push eax ;.output
push ebx ;.inp_size
push ebx ;.input
push SRV_GETVERSION ;.code
push [ssmix_hSound] ;.handle
 
mov eax, 68
mov ebx, 17
mov ecx, esp ;[handle]
int 0x40
add esp, 24
pop ecx
pop ebx
ret 4
.fail:
or eax, -1
pop ecx
pop ebx
ret 4
 
 
align 4
_CreateBuffer@12: ;format:dword,size:dword,p_str:dword
 
push ebx
push ecx
lea eax, [esp+20] ;p_str
lea ebx, [esp+12] ;format
 
push 4 ;.out_size
push eax ;.output
push 8 ;.inp_size
push ebx ;.input
push SND_CREATE_BUFF;.code
push [ssmix_hSound] ;.handle
 
mov eax, 68
mov ebx, 17
mov ecx, esp
int 0x40
add esp, 24 ;io_cintrol
pop ecx
pop ebx
ret 12
 
align 4
_DestroyBuffer@4: ;str:dword
 
push ebx
push ecx
 
xor eax, eax
lea ebx, [esp+12] ;[stream]
 
push eax ;.out_size
push eax ;.output
push 4 ;.inp_size
push ebx ;.input
push SND_DESTROY_BUFF;.code
push [ssmix_hSound] ;.handle
 
mov eax, 68
mov ebx, 17
mov ecx, esp ;[handle]
int 0x40
add esp, 24
pop ecx
pop ebx
ret 4
 
align 4
_GetBufferSize@8: ;str:dword, p_size:dword
push ebx
push ecx
lea eax, [esp+16]
lea ebx, [esp+12] ;[stream]
 
push 4 ;.out_size
push eax ;.output
push 4 ;.inp_size
push ebx ;.input
push SND_GETBUFFSIZE;.code
push dword [ssmix_hSound] ;.handle
 
mov eax, 68
mov ebx, 17
mov ecx, esp
int 0x40
add esp, 24
pop ecx
pop ebx
ret 8
 
align 4
_SetBuffer@16: ;str:dword, src:dword, offs:dword, size:dword
 
push ebx
push ecx
xor eax, eax
lea ebx, [esp+12] ;[stream]
 
push eax ;.out_size
push eax ;.output
push 16 ;.inp_size
push ebx ;.input
push SND_SETBUFF ;.code
push dword [ssmix_hSound] ;.handle
 
mov eax, 68
mov ebx, 17
mov ecx, esp
int 0x40
add esp, 24
pop ecx
pop ebx
ret 16
align 4
_PlayBuffer@8: ;str:dword,flags:dword
 
push ebx
push ecx
 
xor eax, eax
lea ebx, [esp+12] ;[stream]
 
push eax ;.out_size
push eax ;.output
push 8 ;.inp_size
push ebx ;.input
push SND_PLAY ;.code
push dword [ssmix_hSound] ;.handle
 
mov eax, 68
mov ebx, 17
mov ecx, esp
int 0x40
add esp, 24
pop ecx
pop ebx
ret 8
 
 
 
; ========================= data =====================================
 
ssmix_hSound dd ?
ssmix_hrdwSound dd ?
 
ssmix_szInfinity db 'INFINITY',0
ssmix_szSound db 'SOUND',0
 
ssmix_channels dd 0
ssmix_thread_stack dd 0
ssmix_state dd 0
ssmix_volumeL dd ?
ssmix_volumeR dd ?
ssmix_driver_version dd ?
ssmix_hbuffer dd ?
ssmix_pbuffer dd 0
ssmix_buffer_size dd ?
ssmix_buffer_offset dd ?
ssmix_driver_notify_struct rd 6 ; ñòêóêòóðà ñîáûòèÿ îò äðàéâåðà