As a follow-up to the Direct Draw article in APJ#5, here are two complete
DirectDraw sample programs. The first uses an 8-bit palette, while the
second uses a 32-bit (truecolor) palette. To compile these, you will need to
obtain Ddraw.inc ( {http://asmjournal.freeservers.com/files/Ddraw.inc.html} )
for the necessary DirectDraw definitions.
;Ddplasma8.asm_________________________________________________________________
;---------------------------------------;
; DDRAW Plasma Demo ;
; ;
; Author : X-Calibre ;
; ASM version : Ewald Snel ;
; Copyright (C) 1999, Diamond Crew ;
; ;
; {http://here.is/diamond/} ;
;---------------------------------------;
TITLE WIN32ASM EXAMPLE
.486
.MODEL FLAT, STDCALL
option casemap :none
;-----------------------------------------------------------;
; WIN32ASM / DDRAW PLASMA DEMO ;
;-----------------------------------------------------------;
INCLUDE \masm32\include\windows.inc
; -----------------------------------
; Note that the following is the
; include file written by Ewald Snel.
; -----------------------------------
INCLUDE \masm32\include\ddraw.inc
INCLUDE \masm32\include\gdi32.inc
INCLUDE \masm32\include\kernel32.inc
INCLUDE \masm32\include\user32.inc
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\ddraw.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
nextFrame PROTO
initPlasma PROTO
RETURN MACRO arg
IFNB <arg>
mov eax, arg
ENDIF
ret
ENDM
LRETURN MACRO arg
IFNB <arg>
mov eax, arg
ENDIF
leave
ret
ENDM
FATAL MACRO msg
LOCAL @@msg
.DATA
@@msg db msg, 0
.CODE
INVOKE MessageBox, hWnd, ADDR @@msg, ADDR szDisplayName, MB_OK
INVOKE ExitProcess, 0
ENDM
.DATA?
hWnd HWND ? ; surface window
lpDD LPDIRECTDRAW ? ; DDraw object
lpDDSPrimary LPDIRECTDRAWSURFACE ? ; DDraw primary surface
ddsd DDSURFACEDESC <?> ; DDraw surface descriptor
ddscaps DDSCAPS <?> ; DDraw capabilities
palette dd 256 dup (?)
table dd 512 dup (?)
lpDDPalette dd ?
.DATA
ddwidth EQU 320 ; display mode width
ddheight EQU 200 ; display mode height
ddbpp EQU 8 ; display mode color depth
phaseA dd 0
phaseB dd 0
factor1 EQU -2
factor2 EQU -1
factor3 EQU 1
factor4 EQU -2
red dd 500.0
green dd 320.0
blue dd 372.0
scale1 dd 2.0
scale2 dd 128.0
scale3 dd 256.0
scale4 dd 127.0
szClassName db "DDRAW Plasma Demo", 0 ; class name
szDisplayName EQU <szClassName> ; window name
color dd 0
wc WNDCLASSEX < SIZEOF WNDCLASSEX, CS_HREDRAW OR CS_VREDRAW,
OFFSET WndProc, 0, 0, , 0, 0, , 0,
OFFSET szClassName, 0
>
.CODE
- start
INVOKE GetModuleHandle, NULL
INVOKE WinMain, eax, NULL, NULL, SW_SHOWDEFAULT
INVOKE ExitProcess, eax
;-----------------------------------------------------------;
; Calculate Next Plasma Frame ;
;-----------------------------------------------------------;
nextFrame PROC
push ebx
push esi
push edi
mov ecx , ddheight ; # of scanlines
mov edi , [ddsd.lpSurface] ; pixel output
@@scanline:
push ecx
push edi
mov esi , [phaseA]
mov edx , [phaseB]
sub esi , ecx
and edx , 0ffH
and esi , 0ffH
mov edx , [table][4edx][2564]
mov esi , [table][4*esi] ; [x] + table0[a + y]
sub edx , ecx ; [y] + table1[b]
mov ecx , ddwidth ; [x] --> pixel counter
@@pixel:
and esi , 0ffH
and edx , 0ffH
mov eax , [table][4esi]
mov ebx , [table][4edx][256*4]
add eax , ebx
add esi , factor3
shr eax , 1
inc edi
add edx , factor4
dec ecx
mov [edi][-1] , al
jnz @@pixel
pop edi
pop ecx
add edi , [ddsd.lPitch] ; inc. display position
dec ecx
jnz @@scanline
add [phaseA] , factor1
add [phaseB] , factor2
pop edi
pop esi
pop ebx
ret
nextFrame ENDP
;-----------------------------------------------------------;
; Initalize Plasma Tables ;
;-----------------------------------------------------------;
initPlasma PROC
LOCAL @@i :DWORD
LOCAL @@r :DWORD
LOCAL @@g :DWORD
LOCAL @@b :DWORD
LOCAL temp :DWORD
mov [@@i] , 0
.WHILE @@i < 256
mov edx , [@@i]
; Calculate table0 value
fldpi
fimul DWORD PTR [@@i]
fmul REAL4 PTR [scale1]
fdiv REAL4 PTR [scale3]
fsin
fmul REAL4 PTR [scale4]
fadd REAL4 PTR [scale2]
fistp DWORD PTR [table][4*edx]
; Calculate table1 value
fldpi
fimul DWORD PTR [@@i]
fmul REAL4 PTR [scale1]
fdiv REAL4 PTR [scale3]
fcos
fmul REAL4 PTR [scale2]
fadd REAL4 PTR [scale2]
fldpi
fmulp st(1), st
fmul REAL4 PTR [scale1]
fdiv REAL4 PTR [scale3]
fsin
fmul REAL4 PTR [scale4]
fadd REAL4 PTR [scale2]
fistp DWORD PTR [table][4edx][4256]
; Calculate palette value
xor eax , eax
FOR comp, <red, green, blue>
fldpi
fimul DWORD PTR [@@i]
fmul REAL4 PTR [scale1]
fdiv REAL4 PTR [comp]
fcos
fmul REAL4 PTR [scale4]
fadd REAL4 PTR [scale2]
fistp DWORD PTR [temp]
shl eax , 8
or eax , [temp]
ENDM
bswap eax
shr eax, 8
mov [palette][4*edx] , eax
inc [@@i]
.ENDW
; Set palette
DDINVOKE CreatePalette, lpDD, DDPCAPS_8BIT or DDPCAPS_ALLOW256,
ADDR palette, ADDR lpDDPalette, NULL
.IF eax != DD_OK
FATAL "Couldn't create palette"
.ENDIF
DDSINVOKE SetPalette, lpDDSPrimary, lpDDPalette
.IF eax != DD_OK
FATAL "Couldn't set palette"
.ENDIF
ret
initPlasma ENDP
;-----------------------------------------------------------;
; WinMain ( entry point ) ;
;-----------------------------------------------------------;
WinMain PROC hInst :DWORD,
hPrevInst :DWORD,
CmdLine :DWORD,
CmdShow :DWORD
LOCAL msg :MSG
; Fill WNDCLASSEX structure with required variables
mov eax , [hInst]
mov [wc.hInstance] , eax
INVOKE GetStockObject , BLACK_BRUSH
mov [wc.hbrBackground] , eax
INVOKE RegisterClassEx, ADDR wc
; Create window at following size
INVOKE CreateWindowEx, 0,
ADDR szClassName,
ADDR szDisplayName,
WS_POPUP,
0, 0, ddwidth, ddheight,
NULL, NULL,
hInst, NULL
mov [hWnd] , eax
INVOKE ShowWindow, hWnd, SW_MAXIMIZE
INVOKE SetFocus, hWnd
INVOKE ShowCursor, 0
; Initialize display
INVOKE DirectDrawCreate, NULL, ADDR lpDD, NULL
.IF eax != DD_OK
FATAL "Couldn't init DirectDraw"
.ENDIF
DDINVOKE SetCooperativeLevel, lpDD, hWnd, DDSCL_EXCLUSIVE OR DDSCL_FULLSCREEN
.IF eax != DD_OK
FATAL "Couldn't set DirectDraw cooperative level"
.ENDIF
DDINVOKE SetDisplayMode, lpDD, ddwidth, ddheight, ddbpp
.IF eax != DD_OK
FATAL "Couldn't set display mode"
.ENDIF
mov [ddsd.dwSize] , SIZEOF DDSURFACEDESC
mov [ddsd.dwFlags] , DDSD_CAPS
mov [ddsd.ddsCaps.dwCaps] , DDSCAPS_PRIMARYSURFACE
DDINVOKE CreateSurface, lpDD, ADDR ddsd, ADDR lpDDSPrimary, NULL
.IF eax != DD_OK
FATAL "Couldn't create primary surface"
.ENDIF
call initPlasma
; Loop until PostQuitMessage is sent
.WHILE 1
INVOKE PeekMessage, ADDR msg, NULL, 0, 0, PM_REMOVE
.IF eax != 0
.IF msg.message == WM_QUIT
INVOKE PostQuitMessage, msg.wParam
.BREAK
.ELSE
INVOKE TranslateMessage, ADDR msg
INVOKE DispatchMessage, ADDR msg
.ENDIF
.ELSE
INVOKE GetFocus
.IF eax == hWnd
mov [ddsd.dwSize] , SIZEOF DDSURFACEDESC
mov [ddsd.dwFlags] , DDSD_PITCH
.WHILE 1
DDSINVOKE mLock, lpDDSPrimary, NULL, ADDR ddsd, DDLOCK_WAIT, NULL
.BREAK .IF eax == DD_OK
.IF eax == DDERR_SURFACELOST
DDSINVOKE Restore, lpDDSPrimary
.ELSE
FATAL "Couldn't lock surface"
.ENDIF
.ENDW
DDINVOKE WaitForVerticalBlank, lpDD, DDWAITVB_BLOCKBEGIN, NULL
call nextFrame
DDSINVOKE Unlock, lpDDSPrimary, ddsd.lpSurface
.ENDIF
.ENDIF
.ENDW
.IF lpDD != NULL
.IF lpDDSPrimary != NULL
DDSINVOKE Release, lpDDSPrimary
mov [lpDDSPrimary] , NULL
.ENDIF
DDINVOKE Release, lpDD
mov [lpDD] , NULL
.ENDIF
LRETURN msg.wParam
WinMain ENDP
;-----------------------------------------------------------;
; Window Proc ( handle events ) ;
;-----------------------------------------------------------;
WndProc PROC hWin :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD
.IF uMsg == WM_KEYDOWN
.IF wParam == VK_ESCAPE
INVOKE PostQuitMessage, NULL
RETURN 0
.ENDIF
.ELSEIF uMsg == WM_DESTROY
INVOKE PostQuitMessage, NULL
RETURN 0
.ENDIF
INVOKE DefWindowProc, hWin, uMsg, wParam, lParam
ret
WndProc ENDP
END start
;End_Ddplasma8.asm_____________________________________________________________
;Ddplasma32.asm________________________________________________________________
;---------------------------------------;
; DDRAW Plasma Demo ;
; ;
; Author : X-Calibre ;
; ASM version : Ewald Snel ;
; Copyright (C) 1999, Diamond Crew ;
; ;
; {http://here.is/diamond/} ;
;---------------------------------------;
TITLE WIN32ASM EXAMPLE
.386
.MODEL FLAT, STDCALL
option casemap :none
;-----------------------------------------------------------;
; WIN32ASM / DDRAW PLASMA DEMO ;
;-----------------------------------------------------------;
INCLUDE \masm32\include\windows.inc
; -----------------------------------
; Note that the following is the
; include file written by Ewald Snel.
; -----------------------------------
INCLUDE .\ddraw.inc
INCLUDE \masm32\include\gdi32.inc
INCLUDE \masm32\include\kernel32.inc
INCLUDE \masm32\include\user32.inc
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\ddraw.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
nextFrame PROTO
initPlasma PROTO
RETURN MACRO arg
IFNB <arg>
mov eax, arg
ENDIF
ret
ENDM
LRETURN MACRO arg
IFNB <arg>
mov eax, arg
ENDIF
leave
ret
ENDM
FATAL MACRO msg
LOCAL @@msg
.DATA
@@msg db msg, 0
.CODE
INVOKE MessageBox, hWnd, ADDR @@msg, ADDR szDisplayName, MB_OK
INVOKE ExitProcess, 0
ENDM
.DATA?
palette dd 256 dup (?)
table dd 512 dup (?)
hWnd HWND ? ; surface window
lpDD LPDIRECTDRAW ? ; DDraw object
lpDDSPrimary LPDIRECTDRAWSURFACE ? ; DDraw primary surface
ddsd DDSURFACEDESC <?> ; DDraw surface descriptor
ddscaps DDSCAPS <?> ; DDraw capabilities
.DATA
ddwidth EQU 320 ; display mode width
ddheight EQU 200 ; display mode height
ddbpp EQU 32 ; display mode color depth
phaseA dd 0
phaseB dd 0
factor1 EQU -2
factor2 EQU -1
factor3 EQU 1
factor4 EQU -2
red dd 500.0
green dd 320.0
blue dd 372.0
scale1 dd 2.0
scale2 dd 128.0
scale3 dd 256.0
scale4 dd 127.0
szClassName db "DDRAW Plasma Demo", 0 ; class name
szDisplayName EQU <szClassName> ; window name
color dd 0
wc WNDCLASSEX < SIZEOF WNDCLASSEX, CS_HREDRAW OR CS_VREDRAW,
OFFSET WndProc, 0, 0, , 0, 0, , 0,
OFFSET szClassName, 0 >
.CODE
- start
INVOKE GetModuleHandle, NULL
INVOKE WinMain, eax, NULL, NULL, SW_SHOWDEFAULT
INVOKE ExitProcess, eax
;-----------------------------------------------------------;
; Calculate Next Plasma Frame ;
;-----------------------------------------------------------;
nextFrame PROC
push ebx
push esi
push edi
mov ecx , ddheight ; # of scanlines
mov edi , [ddsd.lpSurface] ; pixel output
@@scanline:
push ecx
push edi
mov esi , [phaseA]
mov edx , [phaseB]
sub esi , ecx
and edx , 0ffH
and esi , 0ffH
mov edx , [table][4edx][2564]
mov esi , [table][4*esi] ; [x] + table0[a + y]
sub edx , ecx ; [y] + table1[b]
mov ecx , ddwidth ; [x] --> pixel counter
@@pixel:
and esi , 0ffH
and edx , 0ffH
mov eax , [table][4esi]
mov ebx , [table][4edx][2564]
add eax , ebx
add esi , factor3
shr eax , 1
add edx , factor4
and eax , 0ffH
add edi , 4
mov eax , [palette][4eax]
dec ecx
mov [edi][-4] , eax
jnz @@pixel
pop edi
pop ecx
add edi , [ddsd.lPitch] ; inc. display position
dec ecx
jnz @@scanline
add [phaseA] , factor1
add [phaseB] , factor2
pop edi
pop esi
pop ebx
ret
nextFrame ENDP
;-----------------------------------------------------------;
; Initalize Plasma Tables ;
;-----------------------------------------------------------;
initPlasma PROC
LOCAL @@i :DWORD
LOCAL @@r :DWORD
LOCAL @@g :DWORD
LOCAL @@b :DWORD
LOCAL temp :DWORD
mov [@@i] , 0
.WHILE @@i < 256
mov edx , [@@i]
; Calculate table0 value
fldpi
fimul DWORD PTR [@@i]
fmul REAL4 PTR [scale1]
fdiv REAL4 PTR [scale3]
fsin
fmul REAL4 PTR [scale4]
fadd REAL4 PTR [scale2]
fistp DWORD PTR [table][4*edx]
; Calculate table1 value
fldpi
fimul DWORD PTR [@@i]
fmul REAL4 PTR [scale1]
fdiv REAL4 PTR [scale3]
fcos
fmul REAL4 PTR [scale2]
fadd REAL4 PTR [scale2]
fldpi
fmulp st(1), st
fmul REAL4 PTR [scale1]
fdiv REAL4 PTR [scale3]
fsin
fmul REAL4 PTR [scale4]
fadd REAL4 PTR [scale2]
fistp DWORD PTR [table][4edx][4256]
; Calculate palette value
xor eax , eax
FOR comp, <red, green, blue>
fldpi
fimul DWORD PTR [@@i]
fmul REAL4 PTR [scale1]
fdiv REAL4 PTR [comp]
fcos
fmul REAL4 PTR [scale4]
fadd REAL4 PTR [scale2]
fistp DWORD PTR [temp]
shl eax , 8
or eax , [temp]
ENDM
mov [palette][4*edx] , eax
inc [@@i]
.ENDW
ret
initPlasma ENDP
;-----------------------------------------------------------;
; WinMain ( entry point ) ;
;-----------------------------------------------------------;
WinMain PROC hInst :DWORD,
hPrevInst :DWORD,
CmdLine :DWORD,
CmdShow :DWORD
LOCAL msg :MSG
; Fill WNDCLASSEX structure with required variables
mov eax , [hInst]
mov [wc.hInstance] , eax
INVOKE GetStockObject, BLACK_BRUSH
mov [wc.hbrBackground] , eax
INVOKE RegisterClassEx, ADDR wc
; Create window at following size
INVOKE CreateWindowEx, 0,
ADDR szClassName,
ADDR szDisplayName,
WS_POPUP,
0, 0, ddwidth, ddheight,
NULL, NULL,
hInst, NULL
mov [hWnd] , eax
INVOKE ShowWindow, hWnd, SW_MAXIMIZE
INVOKE SetFocus, hWnd
INVOKE ShowCursor, 0
; Initialize display
INVOKE DirectDrawCreate, NULL, ADDR lpDD, NULL
.IF eax != DD_OK
FATAL "Couldn't init DirectDraw"
.ENDIF
DDINVOKE SetCooperativeLevel, lpDD, hWnd, DDSCL_EXCLUSIVE OR DDSCL_FULLSCREEN
.IF eax != DD_OK
FATAL "Couldn't set DirectDraw cooperative level"
.ENDIF
DDINVOKE SetDisplayMode, lpDD, ddwidth, ddheight, ddbpp
.IF eax != DD_OK
FATAL "Couldn't set display mode"
.ENDIF
mov [ddsd.dwSize] , SIZEOF DDSURFACEDESC
mov [ddsd.dwFlags] , DDSD_CAPS
mov [ddsd.ddsCaps.dwCaps] , DDSCAPS_PRIMARYSURFACE
DDINVOKE CreateSurface, lpDD, ADDR ddsd, ADDR lpDDSPrimary, NULL
.IF eax != DD_OK
FATAL "Couldn't create primary surface"
.ENDIF
call initPlasma
; Loop until PostQuitMessage is sent
.WHILE 1
INVOKE PeekMessage, ADDR msg, NULL, 0, 0, PM_REMOVE
.IF eax != 0
.IF msg.message == WM_QUIT
INVOKE PostQuitMessage, msg.wParam
.BREAK
.ELSE
INVOKE TranslateMessage, ADDR msg
INVOKE DispatchMessage, ADDR msg
.ENDIF
.ELSE
INVOKE GetFocus
.IF eax == hWnd
mov [ddsd.dwSize] , SIZEOF DDSURFACEDESC
mov [ddsd.dwFlags] , DDSD_PITCH
.WHILE 1
DDSINVOKE mLock, lpDDSPrimary, NULL, ADDR ddsd, DDLOCK_WAIT, NULL
.BREAK .IF eax == DD_OK
.IF eax == DDERR_SURFACELOST
DDSINVOKE Restore, lpDDSPrimary
.ELSE
FATAL "Couldn't lock surface"
.ENDIF
.ENDW
DDINVOKE WaitForVerticalBlank, lpDD, DDWAITVB_BLOCKBEGIN, NULL
call nextFrame
DDSINVOKE Unlock, lpDDSPrimary, ddsd.lpSurface
.ENDIF
.ENDIF
.ENDW
.IF lpDD != NULL
.IF lpDDSPrimary != NULL
DDSINVOKE Release, lpDDSPrimary
mov [lpDDSPrimary] , NULL
.ENDIF
DDINVOKE Release, lpDD
mov [lpDD] , NULL
.ENDIF
LRETURN msg.wParam
WinMain ENDP
;-----------------------------------------------------------;
; Window Proc ( handle events ) ;
;-----------------------------------------------------------;
WndProc PROC hWin :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD
.IF uMsg == WM_KEYDOWN
.IF wParam == VK_ESCAPE
INVOKE PostQuitMessage, NULL
RETURN 0
.ENDIF
.ELSEIF uMsg == WM_DESTROY
INVOKE PostQuitMessage, NULL
RETURN 0
.ENDIF
INVOKE DefWindowProc, hWin, uMsg, wParam, lParam
ret
WndProc ENDP
END start
;End_Ddplasma32.asm____________________________________________________________
I had mail problems last time... I don't think the example program from
the DDRAW tut ever reached you... and now you were looking for a Windows
article for issue #6... Maybe you can put the example in there... It's
Win32, and it would also double as a sequel to the article of issue #5
:)
Well, there's 2 examples actually... They look the same on screen, but 1
displays how to use 8 bit palette mode (like good old mode 13h), where
the other shows 32 bit truecolor mode...
I also included the original DDRAW.INC, so people can assemble the
sources themselves...
I hope this time it reaches you, and that I could have been of help to
you,
X-Calibre
WINDOWS
|