概要
中古ノート買ってみた。
windows10でfasmをやってみた。
ddraw見つけたので、やってみた。
写真
サンプルコード
format PE64 GUI 5.0
entry start
include 'win64a.inc'
include 'ddraw64.inc'
section '.text' code readable executable
start:
sub rsp, 8
and [DDraw], 0
and [DDSPrimary], 0
and [DDSBack], 0
invoke GetModuleHandle, NULL
mov [hinstance], rax
mov [wc.hInstance], rax
invoke LoadIcon, NULL,IDI_APPLICATION
mov [wc.hIcon], rax
invoke LoadCursor, NULL,IDC_ARROW
mov [wc.hCursor], rax
invoke RegisterClassEx, wc
test rax, rax
jz startup_error
invoke CreateWindowEx, 0,_class,_title,WS_POPUP+WS_VISIBLE,0,0,0,0,NULL,NULL,[hinstance],NULL
test rax, rax
jz startup_error
mov [hwnd], rax
invoke DirectDrawCreate, NULL,DDraw,NULL
test rax, rax
jnz ddraw_error
cominvk DDraw, SetCooperativeLevel,[hwnd],DDSCL_EXCLUSIVE+DDSCL_FULLSCREEN
test rax, rax
jnz ddraw_error
cominvk DDraw, SetDisplayMode,640,480,32
test rax, rax
jnz ddraw_error
mov [ddsd.dwSize], sizeof.DDSURFACEDESC
mov [ddsd.dwFlags], DDSD_CAPS+DDSD_BACKBUFFERCOUNT
mov [ddsd.ddsCaps.dwCaps], DDSCAPS_PRIMARYSURFACE+DDSCAPS_FLIP+DDSCAPS_COMPLEX
mov [ddsd.dwBackBufferCount], 1
cominvk DDraw, CreateSurface,ddsd,DDSPrimary,NULL
or eax, eax
jnz ddraw_error
mov [ddscaps.dwCaps], DDSCAPS_BACKBUFFER
cominvk DDSPrimary, GetAttachedSurface,ddscaps,DDSBack
or eax, eax
jnz ddraw_error
refresh:
cominvk DDSPrimary, IsLost
test rax, rax
jz paint
cmp eax, DDERR_SURFACELOST
jne end_loop
cominvk DDSPrimary, Restore
paint:
mov [ddsd.dwSize], sizeof.DDSURFACEDESC
mov [ddsd.dwFlags], 0
cominvk DDSBack, Lock,NULL,ddsd,DDLOCK_SURFACEMEMORYPTR+DDLOCK_WAIT,NULL
test rax, rax
jnz main_loop
mov rdi, [ddsd.lpSurface]
mov r10d, [ddsd.lPitch]
xor edx, edx
movsd xmm8, [y_top]
screen:
xor ebx, ebx
movsd xmm7, [x_left]
unpcklpd xmm7, xmm8
row:
mov rcx, 255
xorpd xmm1, xmm1
iterate:
movapd xmm3, xmm1
unpckhpd xmm3, xmm3
mulsd xmm3, xmm1
addsd xmm3, xmm3
mulpd xmm1, xmm1
movapd xmm2, xmm1 ; for SSE3-capable processor
unpckhpd xmm2, xmm2 ; these three instructions can be
subsd xmm1, xmm2 ; replaced with HSUBPD XMM1,XMM1
unpcklpd xmm1, xmm3
addpd xmm1, xmm7
movapd xmm0, xmm1
mulpd xmm0, xmm0
movapd xmm2, xmm0 ; for SSE3-capable processor
shufpd xmm2, xmm2,1 ; these three instructions can be
addsd xmm0, xmm2 ; replaced with HADDPD XMM0,XMM0
sqrtpd xmm0, xmm0
comisd xmm0, [limit]
ja over
loop iterate
over:
xor al, al
stosb
mov al, cl
stosb
ror al, 3
stosb
stosb
movsd xmm0, [x_step]
addpd xmm7, xmm0
inc ebx
cmp ebx, 640
jb row
sub rdi, 640 * 4
add rdi, r10
subsd xmm8, [y_step]
inc edx
cmp edx, 480
jb screen
mov [refresh_needed], 0
cominvk DDSBack, Unlock,NULL
cominvk DDSPrimary, Flip,0,0
main_loop:
invoke PeekMessage, msg,NULL,0,0,PM_NOREMOVE
or eax, eax
jz no_message
invoke GetMessage, msg,NULL,0,0
cmp eax, 1
jb end_loop
jne no_message
invoke TranslateMessage, msg
invoke DispatchMessage, msg
cmp [refresh_needed], 0
jne refresh
jmp main_loop
no_message:
invoke WaitMessage
jmp main_loop
ddraw_error:
invoke wsprintf, buffer,_ddraw_error,rax
invoke MessageBox, [hwnd],buffer,_error,MB_OK+MB_ICONERROR
invoke DestroyWindow, [hwnd]
invoke PostQuitMessage, 2
jmp main_loop
startup_error:
invoke MessageBox, [hwnd],_startup_error,_error,MB_OK+MB_ICONERROR
invoke ExitProcess, 1
end_loop:
cominvk DDraw, RestoreDisplayMode
cmp [DDSBack], 0
je back_surface_released
cominvk DDSPrimary, DeleteAttachedSurface,0,DDSBack
back_surface_released:
cmp [DDSPrimary], 0
je primary_surface_released
cominvk DDSPrimary, Release
primary_surface_released:
cmp [DDraw], 0
je ddraw_released
cominvk DDraw, Release
ddraw_released:
invoke ExitProcess, [msg.wParam]
proc WindowProc uses rbx rsi rdi, hwnd,wmsg,wparam,lparam
cmp edx, WM_CREATE
je .wmcreate
cmp edx, WM_DESTROY
je .wmdestroy
cmp edx, WM_LBUTTONDOWN
je .wmlbuttondown
cmp edx, WM_RBUTTONDOWN
je .wmrbuttondown
cmp edx, WM_KEYDOWN
je .wmkeydown
cmp edx, WM_ACTIVATE
je .wmactivate
.defwindowproc:
invoke DefWindowProc, rcx,rdx,r8,r9
jmp .finish
.wmcreate:
xor eax, eax
jmp .finish
.wmactivate:
test r8, r8
jz .finish
or [refresh_needed], 1
jmp .finish
.wmlbuttondown:
movapd xmm0, [step]
divpd xmm0, [zoom]
movapd xmm1, xmm0
subpd xmm1, [step]
movapd [step], xmm0
movzx eax, r9w
cvtsi2sd xmm3, eax
shr r9, 16
movzx eax, r9w
cvtsi2sd xmm4, eax
unpcklpd xmm3, xmm4
mulpd xmm1, xmm3
xorpd xmm1, [negate]
addpd xmm1, [origin]
movapd [origin], xmm1
or [refresh_needed], 1
jmp .finish
.wmrbuttondown:
movapd xmm0, [step]
mulpd xmm0, [zoom]
movapd xmm1, xmm0
subpd xmm1, [step]
movapd [step], xmm0
movzx eax, r9w
cvtsi2sd xmm3, eax
shr r9, 16
movzx eax, r9w
cvtsi2sd xmm4, eax
unpcklpd xmm3, xmm4
mulpd xmm1, xmm3
xorpd xmm1, [negate]
addpd xmm1, [origin]
movapd [origin], xmm1
or [refresh_needed], 1
jmp .finish
.wmkeydown:
cmp r8d, VK_ESCAPE
jne .finish
.wmdestroy:
invoke PostQuitMessage, 0
xor eax, eax
.finish:
ret
endp
section '.data' data readable writeable
wc WNDCLASSEX sizeof.WNDCLASSEX,0,WindowProc,0,0,NULL,NULL,NULL,NULL,NULL,_class,NULL
_title db 'flat assembler DirectDraw application',0
_class db 'FDDRAW64',0
_error db 'Error',0
_startup_error db 'Startup failed',0
_ddraw_error db 'Direct Draw initialization failed (error code 0x%x).',0
align 16 ; SSE data follows
label origin dqword
x_left dq -2.2
y_top dq 1.25
label step dqword
x_step dq 0.0045
y_step dq 0.0052
label zoom dqword
dq 1.2,1.2
label negate dqword
dq 8000000000000000h,0
limit dq 2.5
section '.bss' readable writeable
hinstance dq ?
hwnd dq ?
msg MSG
ddsd DDSURFACEDESC
ddscaps DDSCAPS
DDraw DirectDraw
DDSPrimary DirectDrawSurface
DDSBack DirectDrawSurface
rect RECT
refresh_needed dd ?
buffer rb 100h
section '.idata' import data readable
library kernel32,'KERNEL32.DLL',user32,'USER32.DLL',ddraw,'DDRAW.DLL'
include 'api\kernel32.inc'
include 'api\user32.inc'
import ddraw,DirectDrawCreate,'DirectDrawCreate'
以上。
