I seem to be having some trouble getting to grips with multithreading.
My idea was to spawn one thread for drawing, another for generating audio. The drawing thread works well, the problem is that I can't get Saida's synth to work in a multithreading prog.
The synth works just fine if you simply call the proc but it will not work if I launch the synth as a thread, nor will it work if I launch the draw proc as a thread then call synth directly.
It's probably something ridiculously simple but I just can't see it. Can anybody spot what I'm missing here?
stdcall
format pe console
entry start
include "windows.inc"
RESX = 0x100
RESY = 0x0C0
data import
library kernel32, "kernel32",\
user32, "user32",\
gdi32, "gdi32",\
winmm, "winmm.dll"
include "api\kernel32.inc"
include "api\user32.inc"
include "api\gdi32.inc"
import winmm,\
midiOutClose, "midiOutClose",\
midiOutOpen, "midiOutOpen",\
midiOutShortMsg, "midiOutShortMsg"
end data
proc start
;xor edi, edi
;invoke GetModuleHandle, edi, edi
;invoke CreateWindowEx, edi, edit, edi, WS_POPUP+WS_VISIBLE+WS_MAXIMIZE, edi, edi, edi, edi, edi, edi, eax, edi
;mov [hWnd], eax
;invoke GetDC, [hWnd]
;mov [hDC], eax
;invoke ShowCursor;, 0 ; <- was the second param for GetModuleHandle(0,wtf)
;invoke CreateThread, 0, 0, draw, 0, 0, idDraw
;mov [hDraw], eax
;invoke CreateThread, 0, 0, synth, 0, 0, idSynth
;mov [hSynth], eax
call synth
;.main:
;invoke GetAsyncKeyState, VK_ESCAPE
;test eax, eax
;jz .main
;invoke CloseHandle, [hSynth]
;invoke CloseHandle, [hDraw]
;invoke midiOutClose, [hMidi]
;invoke ReleaseDC, [hWnd], [hDC]
;invoke DestroyWindow, [hWnd]
;invoke ExitProcess, 0
ret
endp
proc draw
invoke GetClientRect, [hWnd], rc
invoke StretchDIBits, [hDC], 0, 0, [rc.right], [rc.bottom], 0, 0, RESX, RESY, pixel, bmi, 0, SRCCOPY
inc [curFrame]
mov edi, pixel
mov ecx, RESX*RESY
.draw:
movzx eax, cl
dec al
xor al, ch
add eax, [curFrame]
stosd
loop .draw
jmp draw
endp
proc synth
xor eax, eax
mov edi, hMidi
push eax
push eax
push eax
dec eax
invoke midiOutOpen, edi, eax
.reset:
mov esi, edi
lodsd
.load:
lodsb
xchg ah, al
xor ebx, ebx
add bl, ah
jz .reset
shr bl, 5
and ebx, 00000011b
mov bx, word [edi-16+(2*ebx)]
mov ecx, eax
and ax, 0001111100000000b
or eax, 00000000011111110010000010010001b
push eax
push dword [edi]
xchg eax, ecx
sahf
mov eax, [edi-8]
js .done
mov eax, [edi-4]
.done:
push eax
push dword [edi]
invoke midiOutShortMsg
invoke midiOutShortMsg
invoke Sleep, ebx
jmp .load
endp
lengths dw 240, 1, 0, 0
Instruments dd 12594625, 12594625
hMidi dd ?
db 10000101b,10101001b,10001100b
db 10000000b,10101001b,10001100b
db 10000101b,10101001b,10001100b
db 10000000b,10101001b,10001100b
db 10000101b,10101001b,10001100b
db 10000000b,10101001b,10001100b
db 10000101b,10000000b,10000010b
db 10000100b,00000000b
edit db "edit",0
bmi dd 40,RESX,RESY,0x200001,?,?,?,?,?,?,?,?,?,?
hWnd dd ?
hDC dd ?
rc RECT ?,?,?,?
curFrame dd ?
idDraw dd ?
hDraw dd ?
idSynth dd ?
hSynth dd ?
pixel dd RESX*RESY dup ?
Multithreaded
format pe console
entry start
include "windows.inc"
RESX = 0x100
RESY = 0x0C0
data import
library kernel32, "kernel32",\
user32, "user32",\
gdi32, "gdi32",\
winmm, "winmm.dll"
include "api\kernel32.inc"
include "api\user32.inc"
include "api\gdi32.inc"
import winmm,\
midiOutClose, "midiOutClose",\
midiOutOpen, "midiOutOpen",\
midiOutShortMsg, "midiOutShortMsg"
end data
proc start
xor edi, edi
invoke GetModuleHandle, edi, edi
invoke CreateWindowEx, edi, edit, edi, WS_POPUP+WS_VISIBLE+WS_MAXIMIZE, edi, edi, edi, edi, edi, edi, eax, edi
mov [hWnd], eax
invoke GetDC, [hWnd]
mov [hDC], eax
invoke ShowCursor;, 0 ; <- was the second param for GetModuleHandle(0,wtf)
invoke CreateThread, 0, 0, draw, 0, 0, idDraw
mov [hDraw], eax
invoke CreateThread, 0, 0, synth, 0, 0, idSynth
mov [hSynth], eax
;call synth
.main:
invoke GetAsyncKeyState, VK_ESCAPE
test eax, eax
jz .main
invoke CloseHandle, [hSynth]
invoke CloseHandle, [hDraw]
invoke midiOutClose, [hMidi]
invoke ReleaseDC, [hWnd], [hDC]
invoke DestroyWindow, [hWnd]
invoke ExitProcess, 0
ret
endp
proc draw
invoke GetClientRect, [hWnd], rc
invoke StretchDIBits, [hDC], 0, 0, [rc.right], [rc.bottom], 0, 0, RESX, RESY, pixel, bmi, 0, SRCCOPY
inc [curFrame]
mov edi, pixel
mov ecx, RESX*RESY
.draw:
movzx eax, cl
dec al
xor al, ch
add eax, [curFrame]
stosd
loop .draw
jmp draw
endp
proc synth
xor eax, eax
mov edi, hMidi
push eax
push eax
push eax
dec eax
invoke midiOutOpen, edi, eax
.reset:
mov esi, edi
lodsd
.load:
lodsb
xchg ah, al
xor ebx, ebx
add bl, ah
jz .reset
shr bl, 5
and ebx, 00000011b
mov bx, word [edi-16+(2*ebx)]
mov ecx, eax
and ax, 0001111100000000b
or eax, 00000000011111110010000010010001b
push eax
push dword [edi]
xchg eax, ecx
sahf
mov eax, [edi-8]
js .done
mov eax, [edi-4]
.done:
push eax
push dword [edi]
invoke midiOutShortMsg
invoke midiOutShortMsg
invoke Sleep, ebx
jmp .load
endp
lengths dw 240, 1, 0, 0
Instruments dd 12594625, 12594625
hMidi dd ?
db 10000101b,10101001b,10001100b
db 10000000b,10101001b,10001100b
db 10000101b,10101001b,10001100b
db 10000000b,10101001b,10001100b
db 10000101b,10101001b,10001100b
db 10000000b,10101001b,10001100b
db 10000101b,10000000b,10000010b
db 10000100b,00000000b
edit db "edit",0
bmi dd 40,RESX,RESY,0x200001,?,?,?,?,?,?,?,?,?,?
hWnd dd ?
hDC dd ?
rc RECT ?,?,?,?
curFrame dd ?
idDraw dd ?
hDraw dd ?
idSynth dd ?
hSynth dd ?
pixel dd RESX*RESY dup ?