📄 fireworks.asm
字号:
mov lightx,eax ; Light last one
mov eax,y
mov lighty,eax
mov eax,flash ; having only one light source
add eax,3200 ; 3200 million jouls...!
mov flash,eax ; add if previous lighting not extinguished
invoke random,20
inc eax
imul minlife
mov ebx,eax ; sync explosions by mouse clicks with rest
mov eax,[edi] ; by maintaining minimum delay of 'minlife'
xor edx,edx
idiv minlife
add edx,ebx
mov [edi],edx
invoke random,30 ; like its real world counterpart, creation process
add eax,10 ; is long and boring but the end product is explodin..
mov [esp-4],eax ; refer C++ source also. Most of the below area
mov eax,10000 ; is blind translation of that original C code
mov [esp-8],eax ; i crawled on that code as a Human C compiler...!
fld1
fild dword ptr[esp-4]
fidiv dword ptr[esp-8]
fsubp st(1),st(0)
fstp dword ptr[edi+AIR]
add edi,SPARC
fild y
fild x
mov eax,1000
mov [esp-4],eax
fild dword ptr[esp-4] ; 1000 (constant)
invoke random,maxpower
inc eax
mov [esp-4],eax
fild dword ptr[esp-4] ; power
mov ecx,nd
dec ecx
shl ecx,4
@@:
push ecx
invoke random,2000
mov [esp-4],eax
fild dword ptr[esp-4]
fsub st(0),st(2)
fdiv st(0),st(2)
fmul st(0),st(1)
mov ecx,[esp]
fstp dword ptr[edi+ecx+4]
fld st(0)
fmul st(0),st(0)
fld dword ptr[edi+ecx+4]
fmul st(0),st(0)
fsubp st(1),st(0)
fsqrt
invoke random,2000
mov [esp-4],eax
fild dword ptr[esp-4]
fsub st(0),st(3)
fdiv st(0),st(3)
fmulp st(1),st(0)
mov ecx,[esp]
fstp dword ptr[edi+ecx+12]
fld st(2)
fstp dword ptr[edi+ecx]
fld st(3)
fstp dword ptr[edi+ecx+8]
pop ecx
sub ecx,16
jnc @B
fcompp
fcompp
ret
FShell_recycle ENDP
; -------------------------------------------------------------------------
FireThread:
invoke SetThreadPriority,idThread1,THREAD_PRIORITY_HIGHEST
invoke GetDC,hwnd
mov wnddc,eax
invoke GetProcessHeap
mov hHeap,eax
invoke HeapAlloc,hHeap,HEAP_ZERO_MEMORY,4194304
add eax,4096 ; blur: -1'th line problem
mov bitmap1,eax
invoke HeapAlloc,hHeap,HEAP_ZERO_MEMORY,4194304
add eax,4096 ; blur: -1'th line problem
mov bitmap2,eax
mov eax,nd
shl eax,4
add eax,SPARC
mov sb,eax ; size of FShell = nd*16+8
imul nb ; array size = nb*sb
invoke HeapAlloc,hHeap,HEAP_ZERO_MEMORY,eax
mov hFShells,eax
finit ; initialise floating point unit
mov ax,07fh ; low precision floats
mov word ptr[esp-4],ax ; fireworks... not space rockets
fldcw word ptr[esp-4]
sub ebp,12 ; as 3 local variables
mov eax,nb
mov [ebp],eax
mov eax,hFShells
mov [ebp+4],eax
initshells:
;mov eax,maxx ; naah... not needed
;shr eax,1 ; trusting auto-zero
;invoke FShell_recycle,[ebp+4],eax,maxy
;mov eax,sb
;add [ebp+4],eax
;dec dword ptr[ebp]
;jnz initFShells
;mov flash,6400
lp1:
mov eax,motionQ
mov dword ptr[ebp+8],eax
lp2:
mov eax,nb
mov [ebp],eax
mov eax,hFShells
mov [ebp+4],eax
lp3:
invoke FShell_render,[ebp+4],[ebp]
mov eax,GMode
mov ecx,offset FShell_explodeAG
mov ebx,offset FShell_explodeOS
test eax,eax
cmovz ecx,ebx
push [ebp+4]
call ecx
test eax,eax
jns @F
invoke random,maxy
push eax
mov eax,maxx
add eax,eax
invoke random,eax
mov edx,maxx
shr edx,1
sub eax,edx
push eax
push [ebp+4]
call FShell_recycle
@@:
mov eax,sb
add [ebp+4],eax
dec dword ptr[ebp]
jnz lp3
dec dword ptr[ebp+8]
jnz lp2
mov eax,EMode
test eax,eax
jz r1
mov eax,CMode ; switch pre/post blur according to -
test eax,eax ; current chemical in fire
jz @F
invoke Blur_MMX2
@@:
invoke Light_Flash3,lightx,lighty,flash,bitmap1,bitmap2
invoke SetDIBitsToDevice,wnddc,0,0,maxx,maxy,\
0,0,0,maxy,bitmap2,ADDR bminf,DIB_RGB_COLORS
mov eax,CMode
test eax,eax
jnz r2
invoke Blur_MMX2
jmp r2
r1:
invoke SetDIBitsToDevice,wnddc,0,0,maxx,maxy,\
0,0,0,maxy,bitmap1,ADDR bminf,DIB_RGB_COLORS
mov eax,maxx
imul maxy
lea eax,[eax+eax*2]
invoke RtlZeroMemory,bitmap1,eax
r2:
inc fcount ; count the frames
fild flash
fmul flfactor
fistp flash
invoke Sleep,5 ; control, if frames rate goes too high
mov eax,stop
test eax,eax
jz lp1
invoke ReleaseDC,hwnd,wnddc
invoke HeapFree,hHeap,0,bitmap1
invoke HeapFree,hHeap,0,bitmap2
invoke HeapFree,hHeap,0,hFShells
mov idThread1,-1
invoke ExitThread,2003
hlt ; ...! i8085 memories
; -------------------------------------------------------------------------
.data
fps db 64 dup (0)
fmat db "fps = %u [www.ronybc.8k.com]",0
.code
MoniThread:
invoke Sleep,1000
invoke wsprintf,ADDR fps,ADDR fmat,fcount
invoke SetWindowText,hwnd,ADDR fps
xor eax,eax
mov fcount,eax
mov eax,stop
test eax,eax
jz MoniThread
mov idThread2,-1
invoke ExitThread,2003
; -------------------------------------------------------------------------
Switch PROC oMode:DWORD, iid:DWORD
xor eax,eax
mov edx,oMode
or al,byte ptr [edx]
setz byte ptr [edx]
mov eax,[edx]
mov ebx,MF_CHECKED
shl eax,3
and eax,ebx
or eax,MF_BYCOMMAND
invoke CheckMenuItem,hmnu,iid,eax
ret
Switch ENDP
; -------------------------------------------------------------------------
WndProc PROC hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_MOUSEMOVE && wParam==MK_CONTROL
xor edx,edx
mov flash,2400
mov eax,lParam
mov dx,ax
shr eax,16
mov lightx,edx
mov lighty,eax
.ELSEIF uMsg==WM_SIZE && wParam!=SIZE_MINIMIZED
xor edx,edx
mov eax,lParam
mov dx,ax
shr eax,16
shr edx,2
shl edx,2
mov maxx,edx
mov maxy,eax
mov bminf.bmiHeader.biWidth,edx
neg eax ; -maxy
mov bminf.bmiHeader.biHeight,eax
.ELSEIF uMsg==WM_KEYDOWN && wParam==VK_SPACE
invoke Switch,OFFSET GMode,1200
.ELSEIF uMsg==WM_KEYDOWN && wParam==VK_RETURN
invoke Switch,OFFSET EMode,1220
mov flash,0
.ELSEIF uMsg==WM_RBUTTONDOWN
invoke MessageBox,hWnd,ADDR info,ADDR AppName,MB_OK or MB_ICONASTERISK
.ELSEIF uMsg==WM_LBUTTONDOWN
xor edx,edx
mov eax,lParam
mov dx,ax
shr eax,16
push eax
push edx
mov edx,nb
dec edx
mov eax,click
dec eax
cmovs eax,edx
mov click,eax
imul sb
add eax,hFShells
push eax
call FShell_recycle
.ELSEIF uMsg==WM_CLOSE
mov stop,1 ; stop running threads
invoke Sleep,100 ; avoid FireThread drawing without window
invoke DestroyWindow,hwnd
invoke PostQuitMessage,0
.ELSEIF uMsg==WM_COMMAND
.IF wParam==1010
invoke SendMessage,hwnd,WM_CLOSE,0,0
.ELSEIF wParam==1000
invoke SuspendThread,hFThread ; suffering technical difiiculties :)
mov eax,maxx ; major motiv - to see ZeroMem in acion
imul maxy
lea eax,[eax+eax*2]
invoke RtlZeroMemory,bitmap1,eax ; this thing is fast,
invoke RtlZeroMemory,bitmap2,eax ; but hidden from some API docs
push nb
push hFShells
@@:
mov eax,maxx
;shr eax,1
shr eax,2
mov edx,[esp+4]
dec edx
imul eax,edx
mov ebx,maxy
shr ebx,1
invoke FShell_recycle,[esp+8],eax,ebx
mov eax,sb
add [esp],eax
dec dword ptr[esp+4]
jnz @B
;mov flash,6400
invoke ResumeThread,hFThread
pop eax
pop eax
.ELSEIF wParam==1200
invoke Switch,OFFSET GMode,1200
.ELSEIF wParam==1210
invoke Switch,OFFSET CMode,1210
mov ecx,CMode
mov eax,16
shr eax,cl
mov motionQ,eax ; changing motionQ affects speed
.ELSEIF wParam==1220
invoke Switch,OFFSET EMode,1220
mov flash,0
.ELSEIF wParam==1300
invoke CheckMenuItem,hmnu,1310,MF_BYCOMMAND or MF_UNCHECKED
invoke CheckMenuItem,hmnu,1300,MF_BYCOMMAND or MF_CHECKED
mov minlife,500 ; long interval between shoots
.ELSEIF wParam==1310
invoke CheckMenuItem,hmnu,1300,MF_BYCOMMAND or MF_UNCHECKED
invoke CheckMenuItem,hmnu,1310,MF_BYCOMMAND or MF_CHECKED
mov minlife,100 ; short interval
.ELSEIF wParam==1400
invoke MessageBox,hWnd,ADDR info,ADDR AppName,MB_OK or MB_ICONASTERISK
.ENDIF
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc ENDP
; -------------------------------------------------------------------------
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
mov wc.hInstance,eax
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style,CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNCLIENT
mov wc.lpfnWndProc,OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
mov wc.hbrBackground,COLOR_MENUTEXT
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke LoadIcon,hInstance,500
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke RegisterClassEx,ADDR wc
invoke CreateWindowEx,WS_EX_OVERLAPPEDWINDOW,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,wwidth,wheight,NULL,NULL,\
hInstance,NULL
mov hwnd,eax
add seed,eax ;)
invoke LoadMenu,hInstance,600
mov hmnu,eax
invoke SetMenu,hwnd,eax
invoke CheckMenuItem,hmnu,1200,MF_BYCOMMAND or MF_CHECKED
invoke CheckMenuItem,hmnu,1220,MF_BYCOMMAND or MF_CHECKED
invoke CheckMenuItem,hmnu,1300,MF_BYCOMMAND or MF_CHECKED
invoke ShowWindow,hwnd,SW_SHOWNORMAL
invoke UpdateWindow,hwnd
invoke CreateThread,0,4096,ADDR MoniThread,0,0,ADDR idThread1
invoke CreateThread,0,4096,ADDR FireThread,0,0,ADDR idThread2
mov hFThread,eax
MsgLoop:
invoke GetMessage,ADDR msg,0,0,0
test eax,eax
jz EndLoop
invoke TranslateMessage,ADDR msg
invoke DispatchMessage,ADDR msg
jmp MsgLoop
EndLoop:
@@: mov eax,idThread1
or eax,idThread2
not eax
and eax,eax
jnz @B
invoke ExitProcess,eax
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -