The MASM Forum
Projects => Game Development => Topic started by: zedd151 on January 12, 2019, 04:32:28 AM
-
Here goes..
I recently created a slot machine game. The code is not yet commented, as I did not intend to post it just yet.
My internet time is limited, so I can only post what I have so far. I have a version that uses BitBlt under
developement. Any comments, criticisms, etc can be posted here.
disclaimer1:
The images are not mine, I got them somewhere from on the net, and presumably
copyright registered trademarks of their owner, whoever that is.
/ end discalimer1
disclaimer2;
Gambling (with real money) is an addiction,
If you are a gambling addict, get help.
/ end disclaimer2
It is 32bit code, tested under both Windows 10/64 bit and Windows 7/ 64 bit.
Presumably it will work under the 32 bit versions of those OS's
-
Nice one, where can I cash in my credits? :biggrin:
-
Nice one, where can I cash in my credits? :biggrin:
lol.
Just a simple contribution to the Game Dev subforum
-
nice slotmachine
probably gets it paid out in Zedd-dollars(dollar bill with Zedds face on) :biggrin:
I got the jackpot today and it flew out loads of coins from cooling system :P
How did you manage to code that? :greenclp: :badgrin:
-
Nice work! :icon14:
-
Nice work! :icon14:
thank you, felipe...
What I have so far for the version that uses BitBlt
;--------------------------------------------------------------------------
include \masm32\include\masm32rt.inc
; -------------------------------------------------------------------------
WinMain proto
WndProc proto :dword, :dword, :dword, :dword
aproc proto :dword, :dword, :dword, :dword
bproc proto :dword, :dword, :dword, :dword
cproc proto :dword, :dword, :dword, :dword
TopXY proto :dword, :dword
randb proto :dword
convert proto :dword, :dword, :dword ; translates the random generated value to associated bmp handle
getnext proto :dword
intermediate proto :dword, :dword, :dword, :dword, :dword, :dword ; handles WM_TIMER events
PaintProc proto :dword, :dword ; where the actual Bit Blitting is done
;--------------------------------------------------------------------------
.data
; vars for winmain
hWnd dd 0
hInstance dd 0
Icon dd 900
Menu dd 100
Wwd dd 784
Wht dd 446
;--------------------------------------------------
hmain dd 0 ; handle to main window
wa dd 0 ; handle for reel window A
wb dd 0 ; handle for reel window B
wc dd 0 ; etc
lpaproc dd 0 ; wndproc for reel A
lpbproc dd 0 ; wndproc for reel B
lpcproc dd 0 ; wndproc for reel C
va dd 0 ; current value for reel A
vb dd 0 ; current value for reel B
vc dd 0 ; etc
tmpbmpa dd 0
tmpbmpb dd 0
tmpbmpc dd 0
timea dd 0
timeb dd 0
timec dd 0
spinninga dd ?
spinningb dd ?
spinningc dd ?
mainback dd 0 ; backgd image for main window
cherry0 dd 0
cherry1 dd 0
cherry2 dd 0
one0 dd 0
one1 dd 0
one2 dd 0
two0 dd 0
two1 dd 0
two2 dd 0
three0 dd 0
three1 dd 0
three2 dd 0
bell0 dd 0
bell1 dd 0
bell2 dd 0
plum0 dd 0
plum1 dd 0
plum2 dd 0
melon0 dd 0
melon1 dd 0
melon2 dd 0
seven0 dd 0
seven1 dd 0
seven2 dd 0
orange0 dd 0
orange1 dd 0
orange2 dd 0
blank0 dd 0
blank1 dd 0
blank2 dd 0
; -------------------- displayed values
credit dd 0
win dd 0
bet dd 0
; -----------------------------------------
DisplayName db "Simple Window", 0
ClassName db "WINMAIN", 0
sclass db "STATIC", 0
;--------------------------------------------------------------------------
.code
;--------------------------------------------------------------------------
start:
invoke GetModuleHandle, 0
mov hInstance, eax
invoke WinMain
invoke ExitProcess, eax
;--------------------------------------------------------------------------
WinMain proc
local WC:WNDCLASSEX, msg:MSG, Wtx:dword, Wty:dword
mov WC.cbSize, sizeof WNDCLASSEX
mov eax, CS_HREDRAW
or eax, CS_VREDRAW
or eax, CS_BYTEALIGNWINDOW
mov WC.style, 0
lea eax, WndProc
mov WC.lpfnWndProc, eax
mov WC.cbClsExtra, 0
mov WC.cbWndExtra, 0
mov eax, hInstance
mov WC.hInstance, eax
invoke GetStockObject, BLACK_BRUSH
mov WC.hbrBackground, eax
mov WC.lpszMenuName, 0
lea eax, ClassName
mov WC.lpszClassName, eax
invoke LoadIcon, hInstance, Icon
mov WC.hIcon, eax
invoke LoadCursor, 0, IDC_ARROW
mov WC.hCursor, eax
mov WC.hIconSm, 0
invoke RegisterClassEx, addr WC
invoke GetSystemMetrics, SM_CXSCREEN
invoke TopXY, Wwd, eax
mov Wtx, eax
invoke GetSystemMetrics, SM_CYSCREEN
invoke TopXY, Wht, eax
mov Wty, eax
invoke CreateWindowEx,
WS_EX_TOPMOST,
addr ClassName,
addr DisplayName,
WS_OVERLAPPEDWINDOW,
Wtx,
Wty,
Wwd,
Wht,
0,
0,
hInstance,
0
mov hWnd, eax
invoke LoadMenu, hInstance, 10000
invoke SetMenu, hWnd, eax
invoke ShowWindow, hWnd, SW_SHOW
invoke UpdateWindow, hWnd
StartLoop:
invoke GetMessage, addr msg, 0, 0, 0
cmp eax, 0
je ExitLoop
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
jmp StartLoop
ExitLoop:
ret
WinMain endp
;--------------------------------------------------------------------------
TopXY proc wDim:dword, sDim:dword
mov eax, sDim
sub eax, wDim
shr eax, 1
ret
TopXY endp
;--------------------------------------------------------------------------
WndProc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
local rct:RECT, hdc:dword, ps:PAINTSTRUCT, memdc:dword, hold:dword
local ctx:dword, bmp:dword
.if uMsg == WM_COMMAND
.if wParam == 10099
invoke SendMessage, hWin, WM_CLOSE, 0, 0
.elseif wParam == 10003
invoke randb, 10
mov va, eax
invoke randb, 10
mov vb, eax
invoke randb, 10
mov vc, eax
mov eax, 0
mov timea, eax
mov timeb, eax
mov timec, eax
mov spinninga, 20
mov spinningb, 30
mov spinningc, 40
invoke SetTimer, wa, 1000, 0, 0
invoke getnext, va
mov va, eax
invoke SetTimer, wb, 1000, 0, 0
invoke getnext, vb
mov vb, eax
invoke SetTimer, wc, 1000, 0, 0
invoke getnext, vc
mov vc, eax
.elseif wParam == 10033
invoke SetTimer, wa, 1000, 0, 0
invoke getnext, va
mov va, eax
.elseif wParam == 11033
invoke SetTimer, wb, 1000, 0, 0
invoke getnext, vb
mov vb, eax
.elseif wParam == 12033
invoke SetTimer, wc, 1000, 0, 0
invoke getnext, vc
mov vc, eax
.endif
.elseif uMsg == WM_CREATE
mov esi, 32000 ; loading 'reel' images from resource section
lea edi, cherry0
xor ebx, ebx
@@:
lea edx, [esi+ebx]
invoke LoadImage, hInstance, edx, 0, 148, 152, LR_CREATEDIBSECTION
lea edx, [edi+ebx*4]
mov [edx], eax
inc ebx
cmp ebx, 30
jnz @b ; looping in this fashion greatly reduces code here
invoke LoadImage, hInstance, 9999, 0, 0, 0, LR_CREATEDIBSECTION
mov mainback, eax
invoke CreateWindowEx,WS_EX_LEFT,ADDR sclass,0, \
WS_CHILDWINDOW or WS_VISIBLE or SS_BITMAP,0,0,1024,768,hWin,0,hInstance,0
mov hmain, eax
invoke SendMessage,hmain,STM_SETIMAGE,IMAGE_BITMAP,mainback
invoke CreateWindowEx,WS_EX_LEFT,ADDR sclass,0, \
WS_CHILDWINDOW or WS_VISIBLE or SS_BITMAP,4, 106,248,186,hmain,0,hInstance,0
mov wa, eax
invoke SetWindowLong, wa, GWL_WNDPROC, aproc
mov lpaproc, eax
invoke SendMessage, wa, WM_CREATE, wParam, lParam
invoke CreateWindowEx,WS_EX_LEFT,ADDR sclass,0, \
WS_CHILDWINDOW or WS_VISIBLE or SS_BITMAP,260, 106,248,186,hmain,0,hInstance,0
mov wb, eax
invoke SetWindowLong, wb, GWL_WNDPROC, bproc
mov lpbproc, eax
invoke SendMessage, wb, WM_CREATE, wParam, lParam
invoke CreateWindowEx,WS_EX_LEFT,ADDR sclass,0, \
WS_CHILDWINDOW or WS_VISIBLE or SS_BITMAP,516, 106,248,186,hmain,0,hInstance,0
mov wc, eax
invoke SetWindowLong, wc, GWL_WNDPROC, cproc
mov lpcproc, eax
invoke SendMessage, wc, WM_CREATE, wParam, lParam
.elseif uMsg == WM_PAINT
.elseif uMsg == WM_CLOSE
invoke PostQuitMessage, 0
xor eax, eax
.endif
invoke DefWindowProc, hWin, uMsg, wParam, lParam
ret
WndProc endp
;--------------------------------------------------------------------------
getnext proc vx:dword
.if vx == 0
mov eax, 7
.elseif vx == 1
mov eax, 8
.elseif vx == 2
mov eax, 9
.elseif vx == 3
mov eax, 6
.elseif vx == 4
mov eax, 5
.elseif vx == 5
mov eax, 2
.elseif vx == 6
mov eax, 4
.elseif vx == 7
mov eax, 1
.elseif vx == 8
mov eax, 3
.elseif vx == 9
mov eax, 0
.endif
ret
getnext endp
;--------------------------------------------------------------------------
convert proc, vx:dword, lpBmp:dword, No:dword
.if No == 1
.if vx == 0
mov eax, blank1
.elseif vx == 1
mov eax, seven1
.elseif vx == 2
mov eax, plum1
.elseif vx == 3
mov eax, orange1
.elseif vx == 4
mov eax, melon1
.elseif vx == 5
mov eax, bell1
.elseif vx == 6
mov eax, three1
.elseif vx == 7
mov eax, cherry1
.elseif vx == 8
mov eax, one1
.elseif vx == 9
mov eax, two1
.endif
.elseif No == 2
.if vx == 0
mov eax, blank2
.elseif vx == 1
mov eax, seven2
.elseif vx == 2
mov eax, plum2
.elseif vx == 3
mov eax, orange2
.elseif vx == 4
mov eax, melon2
.elseif vx == 5
mov eax, bell2
.elseif vx == 6
mov eax, three2
.elseif vx == 7
mov eax, cherry2
.elseif vx == 8
mov eax, one2
.elseif vx == 9
mov eax, two2
.endif
.elseif No == 3
.if vx == 0
mov eax, cherry0
.elseif vx == 1
mov eax, one0
.elseif vx == 2
mov eax, two0
.elseif vx == 3
mov eax, three0
.elseif vx == 4
mov eax, bell0
.elseif vx == 5
mov eax, plum0
.elseif vx == 6
mov eax, melon0
.elseif vx == 7
mov eax, seven0
.elseif vx == 8
mov eax, orange0
.elseif vx == 9
mov eax, blank0
.endif
.endif
mov ecx, lpBmp
mov [ecx], eax
ret
convert endp
;--------------------------------------------------------------------------
randb proc numbr:dword
.data
random_seed dd 0
.code
push ecx
push edx
invoke GetTickCount
add eax, random_seed
xor edx, edx
mov ecx, 127773
div ecx
mov ecx, eax
mov eax, 432836
mul edx
sub ecx, eax
xor edx, edx
mov eax, ecx
mov random_seed, ecx
div numbr
mov eax, edx
pop edx
pop ecx
ret
randb endp
;--------------------------------------------------------------------------
aproc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
local ps:PAINTSTRUCT, hdc:dword, rct:RECT, memdc:dword, tim:dword
.if uMsg == WM_CREATE
mov va, 7 ; initialize with a '7'
invoke intermediate, va, addr tmpbmpa, 3, hWin, addr rct, timea
.elseif uMsg == WM_TIMER
.if wParam == 1000
invoke intermediate, va, addr tmpbmpa, 1, hWin, addr rct, timea
.elseif wParam == 1001
invoke intermediate, va, addr tmpbmpa, 2, hWin, addr rct, timea
.elseif wParam == 1002
invoke intermediate, va, addr tmpbmpa, 3, hWin, addr rct, timea
sub spinninga, 1
cmp spinninga, 0
jz mmm
invoke SendMessage, hWnd, WM_COMMAND, 10033, lParam
mmm:
.endif
.elseif uMsg == WM_PAINT
invoke PaintProc, hWin, tmpbmpa
.endif
invoke CallWindowProc, lpaproc, hWin, uMsg, wParam, lParam
ret
aproc endp
;--------------------------------------------------------------------------
bproc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
local ps:PAINTSTRUCT, hdc:dword, rct:RECT, memdc:dword
.if uMsg == WM_CREATE
mov vb, 7 ; initialize with a '7'
invoke intermediate, vb, addr tmpbmpb, 3, hWin, addr rct, timeb
.elseif uMsg == WM_TIMER
.if wParam == 1000
invoke intermediate, vb, addr tmpbmpb, 1, hWin, addr rct, timeb
.elseif wParam == 1001
invoke intermediate, vb, addr tmpbmpb, 2, hWin, addr rct, timeb
.elseif wParam == 1002
invoke intermediate, vb, addr tmpbmpb, 3, hWin, addr rct, timeb
sub spinningb, 1
cmp spinningb, 0
jz @f
invoke SendMessage, hWnd, WM_COMMAND, 11033, lParam
@@:
.endif
.elseif uMsg == WM_PAINT
invoke PaintProc, hWin, tmpbmpb
.endif
invoke CallWindowProc, lpbproc, hWin, uMsg, wParam, lParam
ret
bproc endp
;--------------------------------------------------------------------------
cproc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
local ps:PAINTSTRUCT, hdc:dword, rct:RECT, memdc:dword
.if uMsg == WM_CREATE
mov vc, 7 ; initialize with a '7'
invoke intermediate, vc, addr tmpbmpc, 3, hWin, addr rct, timec
.elseif uMsg == WM_TIMER
.if wParam == 1000
invoke intermediate, vc, addr tmpbmpc, 1, hWin, addr rct, timec
.elseif wParam == 1001
invoke intermediate, vc, addr tmpbmpc, 2, hWin, addr rct, timec
.elseif wParam == 1002
invoke intermediate, vc, addr tmpbmpc, 3, hWin, addr rct, timec
sub spinningc, 1
cmp spinningc, 0
jz @f
invoke SendMessage, hWnd, WM_COMMAND, 12033, lParam
@@:
.endif
.elseif uMsg == WM_PAINT
invoke PaintProc, hWin, tmpbmpc
.endif
invoke CallWindowProc, lpcproc, hWin, uMsg, wParam, lParam
ret
cproc endp
;--------------------------------------------------------------------------
intermediate proc vx:dword, ptmpbmpx:dword, sequence:dword, hWinx:dword, pRct:dword, timex:dword
invoke convert, vx, ptmpbmpx, sequence
invoke GetClientRect, hWinx, pRct
invoke InvalidateRect, hWinx, pRct, TRUE
.if sequence == 1
invoke SetTimer, hWinx, 1001, timex, 0
invoke KillTimer, hWinx, 1000
.elseif sequence == 2
invoke SetTimer, hWinx, 1002, timex, 0
invoke KillTimer, hWinx, 1001
.elseif sequence == 3
invoke SetTimer, hWinx, 1003, timex, 0
invoke KillTimer, hWinx, 1002
.endif
ret
intermediate endp
;--------------------------------------------------------------------------
PaintProc proc hWin:dword, tmpbmpx:dword
local ps:PAINTSTRUCT, hdc:dword, rct:RECT, memdc:dword
invoke ShowCursor, 0
invoke BeginPaint, hWin, addr ps
mov hdc, eax
invoke CreateCompatibleDC, 0
mov memdc, eax
invoke SelectObject, memdc, tmpbmpx
invoke BitBlt, hdc, 48, 18, 148, 152, memdc,0,0, SRCCOPY
invoke DeleteDC, memdc
invoke EndPaint, hWin, addr ps
invoke ShowCursor, 1
ret
PaintProc endp
;--------------------------------------------------------------------------
end start
Sparse commenting, I know... But will post a fully commented version, when the project is *almost* completed.
The exe is an unfinished version. To test it, simply click on 'Play' on the menu bar.
-
Maybe to have just a one bitmap stripe and show only a part of it in those windows ?
-
Maybe to have just a one bitmap stripe and show only a part of it in those windows ?
That would just complicate things. I try to keep it simple.
-
Maybe.
An example with scrolling bitmap.
void InitDlg(HWND hwndDlg)
{
InitCommonControls();
hBitmap = LoadBitmap(GetModuleHandle(TEXT("comctl32")), MAKEINTRESOURCE(121));
SetTimer(hwndDlg, 1, 50, NULL);
}
void OnPaint(HWND hwndDlg)
{
PAINTSTRUCT ps;
HDC hdcSrc, hdcDst;
hdcDst = BeginPaint(hwndDlg, &ps);
if ((hdcSrc = CreateCompatibleDC(NULL)) != NULL) {
SelectObject(hdcSrc, hBitmap);
BitBlt(ps.hdc, 1, 0, 24, 24, hdcSrc, x1, 0, SRCCOPY);
BitBlt(ps.hdc, 26, 0, 24, 24, hdcSrc, x2, 0, SRCCOPY);
BitBlt(ps.hdc, 51, 0, 24, 24, hdcSrc, x3, 0, SRCCOPY);
DeleteDC(hdcSrc);
}
EndPaint(hwndDlg, &ps);
}
void OnTimer(HWND hwndDlg)
{
char szTmp[100];
x1 += 2;
if (x1 > 15*24) x1 = 0;
x2 += 24;
if (x2 > 15*24) x2 = 0;
x3 += 12;
if (x3 > 15*24) x3 = 0;
InvalidateRect(hwndDlg, NULL, FALSE);
wsprintf(szTmp, "x1: %d", x1);
SetWindowText(hwndDlg, szTmp);
}
-
Okay Tim, I see what you're getting at now. That looks fairly simple. The code is C but thats an easy conversion to assembler.
Thanks for the examples. I will try it some time in the future. :t