Author Topic: Slot machine  (Read 888 times)

zedd151

  • Member
  • ****
  • Posts: 870
Slot machine
« 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
I'm not always the sharpest knife in the drawer, but I have my moments.  :P

Siekmanski

  • Member
  • *****
  • Posts: 1830
Re: Slot machine
« Reply #1 on: January 12, 2019, 06:04:22 AM »
Nice one, where can I cash in my credits?  :biggrin:
Creative coders use backward thinking techniques as a strategy.

zedd151

  • Member
  • ****
  • Posts: 870
Re: Slot machine
« Reply #2 on: January 12, 2019, 06:43:56 AM »
Nice one, where can I cash in my credits?  :biggrin:

lol.
 
Just a simple contribution to the Game Dev subforum
I'm not always the sharpest knife in the drawer, but I have my moments.  :P

daydreamer

  • Member
  • ****
  • Posts: 830
  • watch Chebyshev on the backside of the Moon
Re: Slot machine
« Reply #3 on: January 13, 2019, 12:49:48 AM »
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:
« Last Edit: January 14, 2019, 07:36:03 AM by daydreamer »
Quote from Flashdance
Nick  :  When you give up your dream, you die
*wears a flameproof asbestos suit*

felipe

  • Member
  • *****
  • Posts: 1200
  • Eagles are just great!
Re: Slot machine
« Reply #4 on: January 14, 2019, 04:26:59 AM »
Nice work!  :icon14:
Felipe.

zedd151

  • Member
  • ****
  • Posts: 870
Re: Slot machine
« Reply #5 on: January 15, 2019, 03:52:13 AM »
Nice work!  :icon14:

thank you, felipe...

What I have so far for the version that uses BitBlt

Code: [Select]
;--------------------------------------------------------------------------

      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 can de downloaded here:
https://www.dropbox.com/s/aksd3ukucc30xct/slots2109.zip?dl=1

The exe is an unfinished version. To test it, simply click on 'Play' on the menu bar.
I'm not always the sharpest knife in the drawer, but I have my moments.  :P

TimoVJL

  • Member
  • ***
  • Posts: 324
Re: Slot machine
« Reply #6 on: January 15, 2019, 05:00:23 AM »
Maybe to have just a one bitmap stripe and show only a part of it in those windows ?
May the source be with you

zedd151

  • Member
  • ****
  • Posts: 870
Re: Slot machine
« Reply #7 on: January 15, 2019, 05:13:23 AM »
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.
I'm not always the sharpest knife in the drawer, but I have my moments.  :P

TimoVJL

  • Member
  • ***
  • Posts: 324
Re: Slot machine
« Reply #8 on: January 15, 2019, 07:49:59 AM »
Maybe.
An example with scrolling bitmap.
Code: [Select]
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);
}
« Last Edit: January 15, 2019, 08:42:17 PM by TimoVJL »
May the source be with you

zedd151

  • Member
  • ****
  • Posts: 870
Re: Slot machine
« Reply #9 on: January 18, 2019, 05:15:53 AM »
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
I'm not always the sharpest knife in the drawer, but I have my moments.  :P