asm_dip/toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.ASM
2024-11-24 23:13:28 -05:00

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'