327 lines
6.0 KiB
NASM
327 lines
6.0 KiB
NASM
|
|
||
|
; DirectDraw programming example
|
||
|
|
||
|
format PE GUI 4.0
|
||
|
entry start
|
||
|
|
||
|
include 'win32a.inc'
|
||
|
|
||
|
include 'ddraw.inc'
|
||
|
|
||
|
section '.text' code readable executable
|
||
|
|
||
|
start:
|
||
|
|
||
|
and [DDraw],0
|
||
|
and [DDSPrimary],0
|
||
|
and [DDSBack],0
|
||
|
and [DDPalette],0
|
||
|
and [DDSPicture],0
|
||
|
|
||
|
invoke GetModuleHandleA,NULL
|
||
|
mov [hinstance],eax
|
||
|
|
||
|
invoke LoadIconA,NULL,IDI_APPLICATION
|
||
|
mov [wc.hIcon],eax
|
||
|
|
||
|
invoke LoadCursorA,NULL,IDC_ARROW
|
||
|
mov [wc.hCursor],eax
|
||
|
|
||
|
mov [wc.style],0
|
||
|
mov [wc.lpfnWndProc],WindowProc
|
||
|
mov [wc.cbClsExtra],0
|
||
|
mov [wc.cbWndExtra],0
|
||
|
mov eax,[hinstance]
|
||
|
mov [wc.hInstance],eax
|
||
|
mov [wc.hbrBackground],0
|
||
|
mov dword [wc.lpszMenuName],NULL
|
||
|
mov dword [wc.lpszClassName],_class
|
||
|
invoke RegisterClassA,wc
|
||
|
test eax,eax
|
||
|
jz startup_error
|
||
|
|
||
|
invoke CreateWindowExA,\
|
||
|
0,_class,_title,WS_POPUP+WS_VISIBLE,0,0,0,0,NULL,NULL,[hinstance],NULL
|
||
|
test eax,eax
|
||
|
jz startup_error
|
||
|
mov [hwnd],eax
|
||
|
|
||
|
invoke DirectDrawCreate,NULL,DDraw,NULL
|
||
|
or eax,eax
|
||
|
jnz ddraw_error
|
||
|
|
||
|
cominvk DDraw,SetCooperativeLevel,\
|
||
|
[hwnd],DDSCL_EXCLUSIVE+DDSCL_FULLSCREEN
|
||
|
or eax,eax
|
||
|
jnz ddraw_error
|
||
|
|
||
|
cominvk DDraw,SetDisplayMode,\
|
||
|
640,480,8
|
||
|
or eax,eax
|
||
|
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
|
||
|
|
||
|
mov esi,picture
|
||
|
call load_picture
|
||
|
jc open_error
|
||
|
|
||
|
mov esi,picture
|
||
|
call load_palette
|
||
|
jc open_error
|
||
|
|
||
|
invoke GetTickCount
|
||
|
mov [last_tick],eax
|
||
|
|
||
|
jmp paint
|
||
|
|
||
|
main_loop:
|
||
|
|
||
|
invoke PeekMessageA,msg,NULL,0,0,PM_NOREMOVE
|
||
|
or eax,eax
|
||
|
jz no_message
|
||
|
invoke GetMessageA,msg,NULL,0,0
|
||
|
or eax,eax
|
||
|
jz end_loop
|
||
|
invoke TranslateMessage,msg
|
||
|
invoke DispatchMessageA,msg
|
||
|
|
||
|
jmp main_loop
|
||
|
|
||
|
no_message:
|
||
|
cmp [active],0
|
||
|
je sleep
|
||
|
|
||
|
cominvk DDSPrimary,IsLost
|
||
|
or eax,eax
|
||
|
jz paint
|
||
|
cmp eax,DDERR_SURFACELOST
|
||
|
jne end_loop
|
||
|
|
||
|
cominvk DDSPrimary,Restore
|
||
|
|
||
|
paint:
|
||
|
|
||
|
mov [rect.top],0
|
||
|
mov [rect.bottom],480
|
||
|
mov [rect.left],0
|
||
|
mov [rect.right],640
|
||
|
|
||
|
cominvk DDSBack,BltFast,\
|
||
|
0,0,[DDSPicture],rect,DDBLTFAST_SRCCOLORKEY
|
||
|
or eax,eax
|
||
|
jnz paint_done
|
||
|
|
||
|
movzx eax,[frame]
|
||
|
xor edx,edx
|
||
|
mov ebx,10
|
||
|
div ebx
|
||
|
|
||
|
sal eax,6
|
||
|
add eax,480
|
||
|
mov [rect.top],eax
|
||
|
add eax,64
|
||
|
mov [rect.bottom],eax
|
||
|
sal edx,6
|
||
|
mov [rect.left],edx
|
||
|
add edx,64
|
||
|
mov [rect.right],edx
|
||
|
|
||
|
cominvk DDSBack,BltFast,\
|
||
|
[x],[y],[DDSPicture],rect,DDBLTFAST_SRCCOLORKEY
|
||
|
|
||
|
cominvk DDSPrimary,SetPalette,[DDPalette]
|
||
|
|
||
|
cominvk DDSPrimary,Flip,0,0
|
||
|
|
||
|
paint_done:
|
||
|
|
||
|
invoke GetTickCount
|
||
|
mov ebx,eax
|
||
|
sub ebx,[last_tick]
|
||
|
cmp ebx,20
|
||
|
jb main_loop
|
||
|
add [last_tick],20
|
||
|
|
||
|
inc [frame]
|
||
|
cmp [frame],60
|
||
|
jb main_loop
|
||
|
mov [frame],0
|
||
|
jmp main_loop
|
||
|
|
||
|
sleep:
|
||
|
invoke WaitMessage
|
||
|
jmp main_loop
|
||
|
|
||
|
ddraw_error:
|
||
|
mov eax,_ddraw_error
|
||
|
jmp error
|
||
|
open_error:
|
||
|
mov eax,_open_error
|
||
|
error:
|
||
|
invoke MessageBoxA,[hwnd],eax,_error,MB_OK+MB_ICONERROR
|
||
|
invoke DestroyWindow,[hwnd]
|
||
|
invoke PostQuitMessage,1
|
||
|
jmp main_loop
|
||
|
startup_error:
|
||
|
invoke MessageBoxA,[hwnd],_startup_error,_error,MB_OK+MB_ICONERROR
|
||
|
end_loop:
|
||
|
|
||
|
cmp [DDSPicture],0
|
||
|
je picture_released
|
||
|
cominvk DDSPicture,Release
|
||
|
picture_released:
|
||
|
cmp [DDPalette],0
|
||
|
je palette_released
|
||
|
cominvk DDPalette,Release
|
||
|
palette_released:
|
||
|
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]
|
||
|
|
||
|
include 'gif87a.inc'
|
||
|
|
||
|
proc WindowProc hwnd,wmsg,wparam,lparam
|
||
|
push ebx esi edi
|
||
|
mov eax,[wmsg]
|
||
|
cmp eax,WM_CREATE
|
||
|
je .wmcreate
|
||
|
cmp eax,WM_DESTROY
|
||
|
je .wmdestroy
|
||
|
cmp eax,WM_ACTIVATE
|
||
|
je .wmactivate
|
||
|
cmp eax,WM_SETCURSOR
|
||
|
je .wmsetcursor
|
||
|
cmp eax,WM_MOUSEMOVE
|
||
|
je .wmmousemove
|
||
|
cmp eax,WM_KEYDOWN
|
||
|
je .wmkeydown
|
||
|
.defwindowproc:
|
||
|
invoke DefWindowProcA,[hwnd],[wmsg],[wparam],[lparam]
|
||
|
jmp .finish
|
||
|
.wmcreate:
|
||
|
xor eax,eax
|
||
|
jmp .finish
|
||
|
.wmkeydown:
|
||
|
cmp [wparam],VK_ESCAPE
|
||
|
jne .finish
|
||
|
.wmdestroy:
|
||
|
cominvk DDraw,RestoreDisplayMode
|
||
|
invoke PostQuitMessage,0
|
||
|
xor eax,eax
|
||
|
jmp .finish
|
||
|
.wmactivate:
|
||
|
mov eax,[wparam]
|
||
|
mov [active],al
|
||
|
jmp .finish
|
||
|
.wmsetcursor:
|
||
|
invoke SetCursor,0
|
||
|
xor eax,eax
|
||
|
jmp .finish
|
||
|
.wmmousemove:
|
||
|
movsx eax,word [lparam]
|
||
|
mov [x],eax
|
||
|
movsx eax,word [lparam+2]
|
||
|
mov [y],eax
|
||
|
.finish:
|
||
|
pop edi esi ebx
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
section '.data' data readable writeable
|
||
|
|
||
|
_title db 'flat assembler DirectDraw application',0
|
||
|
_class db 'FDDRAW32',0
|
||
|
|
||
|
_error db 'Error',0
|
||
|
_startup_error db 'Startup failed.',0
|
||
|
_ddraw_error db 'Direct Draw initialization failed.',0
|
||
|
_open_error db 'Failed opening data file.',0
|
||
|
|
||
|
picture db 'DDRAW.GIF',0
|
||
|
|
||
|
section '.bss' readable writeable
|
||
|
|
||
|
hinstance dd ?
|
||
|
hwnd dd ?
|
||
|
wc WNDCLASS
|
||
|
msg MSG
|
||
|
|
||
|
ddsd DDSURFACEDESC
|
||
|
ddscaps DDSCAPS
|
||
|
|
||
|
DDraw DirectDraw
|
||
|
DDSPrimary DirectDrawSurface
|
||
|
DDSBack DirectDrawSurface
|
||
|
|
||
|
DDSPicture DirectDrawSurface
|
||
|
DDPalette DirectDrawPalette
|
||
|
|
||
|
bytes_count dd ?
|
||
|
last_tick dd ?
|
||
|
frame db ?
|
||
|
active db ?
|
||
|
LZW_bits db ?
|
||
|
LZW_table rd (0F00h-2)*2
|
||
|
buffer rb 40000h
|
||
|
rect RECT
|
||
|
x dd ?
|
||
|
y dd ?
|
||
|
|
||
|
section '.idata' import data readable
|
||
|
|
||
|
library kernel,'KERNEL32.DLL',\
|
||
|
user,'USER32.DLL',\
|
||
|
ddraw,'DDRAW.DLL'
|
||
|
|
||
|
import kernel,\
|
||
|
GetModuleHandleA,'GetModuleHandleA',\
|
||
|
CreateFileA,'CreateFileA',\
|
||
|
ReadFile,'ReadFile',\
|
||
|
CloseHandle,'CloseHandle',\
|
||
|
GetTickCount,'GetTickCount',\
|
||
|
ExitProcess,'ExitProcess'
|
||
|
|
||
|
import user,\
|
||
|
RegisterClassA,'RegisterClassA',\
|
||
|
CreateWindowExA,'CreateWindowExA',\
|
||
|
DestroyWindow,'DestroyWindow',\
|
||
|
DefWindowProcA,'DefWindowProcA',\
|
||
|
GetMessageA,'GetMessageA',\
|
||
|
PeekMessageA,'PeekMessageA',\
|
||
|
TranslateMessage,'TranslateMessage',\
|
||
|
DispatchMessageA,'DispatchMessageA',\
|
||
|
LoadCursorA,'LoadCursorA',\
|
||
|
LoadIconA,'LoadIconA',\
|
||
|
SetCursor,'SetCursor',\
|
||
|
MessageBoxA,'MessageBoxA',\
|
||
|
PostQuitMessage,'PostQuitMessage',\
|
||
|
WaitMessage,'WaitMessage'
|
||
|
|
||
|
import ddraw,\
|
||
|
DirectDrawCreate,'DirectDrawCreate'
|