Electronic Dice for the SPB

Post Here To Discuss The Super Pixel Bros Video Game

Moderators: Chuckt, Garth, bitfogav

Post Reply
User avatar
bitfogav
Moderator
Moderator
Posts: 915
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Electronic Dice for the SPB

Post by bitfogav » Thu Sep 13, 2012 7:36 am

Since I got my SPB I often thought I had to make something for it!, untill just recently I haven't found the time to look at the full workings of the SPB board apart from the day when I built the kit from iteadstudio.

I know this isn't anything new an "Electronic Dice", but its surely new to the SPB :lol:

So heres my version of an Electronic Dice for the SPB :) I've reused some code from the SBP for controlling the matrix, why change something that already works!?. It also includes some sounds from the Monofonic audio chip!.

Its simple to operate, the electronic dice starts up on the title screen simular the Brads SPB game and plays a song, to start the electronic dice you press button B, once started you just have to press button B again to start the dice rolling again. on each dice roll a random FX sound from the Monofonic audio chip will play and the dice will roll. to exit back to the title screen you just press button A.
Ive also made it so you can turn the sound off by pressing and holding the down button whilst powering on the board.

The code uses a Random Generator (RandGen2) simular to the one that Brad uses in his SPB game, but this version is slightly different, it allows us to get a random number between 0 to 6, this was used to then select the number on the dice, Ill include the randgen2 below.

The Dice value will be shown on the LCD aswell as on the matrix as some Dice patterns.


This is the title screen:


The electronic dice in operation:

RandGen2.rar
(1023 Bytes) Downloaded 393 times
The Code:

Code: Select all

' Electronic Dice Source Code Version 1
' By Gavin Wigget Sept 2012
'
'

Device = 18F4550             
Clock = 8                      
Config FOSC= INTOSCIO_EC 

// some LCD options...
#option LCD_DATA = PORTB.4     
#option LCD_EN = PORTE.0                
#option LCD_RS = PORTE.1             

Include "LCD.bas"        
Include "convert.bas"
Include "RandGen2.bas"
Include "utils.bas"      
                      
// Arrays
          
// Title screen  (Dice, Dice)
Const RedTitleData(96) As Byte =    (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111110,%01001010,%01001010,%01000010,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111110,%01000010,%01000010,%01000010,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00111100,%01000010,%01000010,%00111100,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111110,%01000010,%01000010,%01000010,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111110,%01000010,%01000010,%01000010,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)
Const GreenTitleData(96) As Byte =  (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111110,%00000010,%00000010,%00000010,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01000000,%01000000,%01111110,%01000000,%01000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111110,%00100000,%00010000,%00001000,%01111110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111110,%01000010,%01000010,%00111100,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111110,%01001010,%01001010,%01000010,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)
Const BlueTitleData(96) As Byte =   (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111110,%01001010,%01001010,%01000010,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111110,%01001000,%01001100,%00110010,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%01111110,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)

// Dice numbers
Const Red1Data(8) As Byte =    (%00000000,%00000000,%00000000,%00011000,%00011000,%00000000,%00000000,%00000000)
Const Green1Data(8) As Byte =  (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)
Const Blue1Data(8) As Byte =   (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)
Const Red2Data(8) As Byte =    (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)
Const Green2Data(8) As Byte =  (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)
Const Blue2Data(8) As Byte =   (%00000000,%01100000,%01100000,%00000000,%00000000,%00000110,%00000110,%00000000)
Const Red3Data(8) As Byte =    (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)
Const Green3Data(8) As Byte =  (%11000000,%11000000,%00000000,%00011000,%00011000,%00000000,%00000011,%00000011)
Const Blue3Data(8) As Byte =   (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)
Const Red4Data(8) As Byte =    (%00000000,%01100110,%01100110,%00000000,%00000000,%01100110,%01100110,%00000000)
Const Green4Data(8) As Byte =  (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)
Const Blue4Data(8) As Byte =   (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)
Const Red5Data(8) As Byte =    (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)
Const Green5Data(8) As Byte =  (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)
Const Blue5Data(8) As Byte =   (%11000011,%11000011,%00000000,%00011000,%00011000,%00000000,%11000011,%11000011)
Const Red6Data(8) As Byte =    (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)
Const Green6Data(8) As Byte =  (%01100110,%01100110,%00000000,%01100110,%01100110,%00000000,%01100110,%01100110)
Const Blue6Data(8) As Byte =   (%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000)

// buffer
Dim DisplayBufferRed(8) As Byte 
Dim DisplayBufferGreen(8) As Byte 
Dim DisplayBufferBlue(8) As Byte

// lcd timer
Dim LCDTimer As Word

// variable declaration
Dim x As Word
Dim i As Byte
Dim j As Byte
Dim k As Byte
Dim GraphicDataOutGreen As Byte
Dim GraphicDataOutRed As Byte
Dim GraphicDataOutBlue As Byte
Dim StartColumn As Word
Dim AnimationSpeed As Byte 

// buttons
Dim ButtonStart As PORTD.0
Dim ButtonExit As PORTD.2
Dim ButtonSoundOff As PORTD.6
Dim ButtonLockoutDelay As Byte

// random gen
Dim RandomVal As LongWord       // used to store the random number

// Flags
Dim SoundONflag As Bit
Dim DisTitle As Bit   
Dim PlayGame As Bit 

// Matrix control (Outputs)
Dim RedLatch As PORTC.7
Dim GreenLatch As PORTC.6
Dim BlueLatch As PORTA.3
Dim AnodeLatch As PORTA.4
Dim EnableLeds As PORTC.0
Dim DataBus As PORTB

// FX sound chip
Dim SoundSelect0 As PORTC.2
Dim SoundSelect1 As PORTC.1
Dim SoundSelect2 As PORTE.2
Dim SoundEnable As PORTA.5


// Sub Routines

Sub PlaySoundFX(ByVal pFX As Byte = 0)
   Select pFX
      Case 0
         SoundSelect0 = 0  '
         SoundSelect1 = 0  ' Jump
         SoundSelect2 = 0  '
         SoundEnable = 1   ' Enable sound
         SoundEnable = 0   
      Case 1
         SoundSelect0 = 1  '
         SoundSelect1 = 0  ' Falling
         SoundSelect2 = 0  '
         SoundEnable = 1   ' Enable sound
         SoundEnable = 0   
      Case 2
         SoundSelect0 = 0  '
         SoundSelect1 = 1  ' Squash
         SoundSelect2 = 0  '
         SoundEnable = 1   ' Enable sound
         SoundEnable = 0   
      Case 3
         SoundSelect0 = 1  '
         SoundSelect1 = 1  ' Dying
         SoundSelect2 = 0  '
         SoundEnable = 1   ' Enable sound
         SoundEnable = 0   
      Case 4
         SoundSelect0 = 0  '
         SoundSelect1 = 0  ' Coins
         SoundSelect2 = 1  '
         SoundEnable = 1   ' Enable sound
         SoundEnable = 0   
      Case 5
         SoundSelect0 = 1  '
         SoundSelect1 = 0  ' Phaser
         SoundSelect2 = 1  '
         SoundEnable = 1   ' Enable sound
         SoundEnable = 0   
      End Select
End Sub

Sub DrawGraphics()
    If PlayGame = 1 Then
        For x = StartColumn To (StartColumn + 7)
            GraphicDataOutRed = 0
            GraphicDataOutGreen = 0
            GraphicDataOutBlue = 0
            GraphicDataOutRed = DisplayBufferRed(x) 
            GraphicDataOutGreen = DisplayBufferGreen(x)
            GraphicDataOutBlue = DisplayBufferBlue(x)
            
            ' this next piece of code takes care of sending the data to the LED's 
            DataBus = GraphicDataOutRed Xor %11111111
            RedLatch = 1
            RedLatch = 0  
            DataBus = GraphicDataOutGreen Xor %11111111
            GreenLatch = 1
            GreenLatch = 0  
            DataBus = GraphicDataOutBlue Xor %11111111
            BlueLatch = 1
            BlueLatch = 0
            ' now that all the data has been sent out, we can turn on a column of cathodes to display the data
            DataBus = 0
            DataBus.bits(7 - (x - StartColumn)) = 1
            AnodeLatch = 1
            AnodeLatch = 0
            DataBus = 0
            EnableLeds = 0      ' turn the LED's on
            DelayMS(1)
            EnableLeds = 1      ' turn the LED's off
        Next
    EndIf 
    
    If DisTitle = 1 Then
        For x = StartColumn To (StartColumn + 7)
            GraphicDataOutGreen = GreenTitleData(x)
            GraphicDataOutRed = RedTitleData(x)
            GraphicDataOutBlue = BlueTitleData(x)
            ' this next piece of code takes care of sending the data to the LED's 
            DataBus = GraphicDataOutRed Xor %11111111
            RedLatch = 1
            RedLatch = 0  
            DataBus = GraphicDataOutGreen Xor %11111111
            GreenLatch = 1
            GreenLatch = 0  
            DataBus = GraphicDataOutBlue Xor %11111111
            BlueLatch = 1
            BlueLatch = 0
            ' now that all the data has been sent out, we can turn on a column of cathodes to display the data
            DataBus = 0
            DataBus.bits(7 - (x - StartColumn)) = 1
            AnodeLatch = 1
            AnodeLatch = 0
            DataBus = 0
            EnableLeds = 0      ' turn the LED's on
            DelayMS(1)
            EnableLeds = 1      ' turn the LED's off
        Next
    EndIf   
End Sub

Sub GetRandData()
   ' this will keep generating a random number aslong as the button is pressed
   ' helps to make the dice value more random
   RandGen2.SetRndMax(7)  ' reset random gen max value (0-6)
   Repeat
      RandomVal = RandGen2.rand () 
      DelayMS(1)
   Until ButtonStart = 1
   
   ' check if sound On
   If SoundONflag = 1 Then
      RandGen2.SetRndMax(6) ' set randsom gen max value (0-5)
      RandomVal = RandGen2.rand ()
      PlaySoundFX(RandomVal)   ' select a random sound 
   EndIf
   
   For k = 0 To 10
      ' reset random gen max value (0-6) and
      ' get a random value, exit loop if random gen is not a ZERO
      RandGen2.SetRndMax(7)
      Repeat
         RandomVal = RandGen2.rand()
      Until RandomVal <> 0

      Select RandomVal ' load data buffer
         Case 1
            For i = 0 To 7
            DisplayBufferRed(i) = Red1Data(i)
            DisplayBufferGreen(i) = Green1Data(i)
            DisplayBufferBlue(i) = Blue1Data(i)
            Next
         Case 2
            For i = 0 To 7
            DisplayBufferRed(i) = Red2Data(i)
            DisplayBufferGreen(i) = Green2Data(i)
            DisplayBufferBlue(i) = Blue2Data(i)
            Next
         Case 3 
            For i = 0 To 7
            DisplayBufferRed(i) = Red3Data(i)
            DisplayBufferGreen(i) = Green3Data(i)
            DisplayBufferBlue(i) = Blue3Data(i)
            Next
         Case 4
            For i = 0 To 7
            DisplayBufferRed(i) = Red4Data(i)
            DisplayBufferGreen(i) = Green4Data(i)
            DisplayBufferBlue(i) = Blue4Data(i)
            Next
         Case 5
            For i = 0 To 7
            DisplayBufferRed(i) = Red5Data(i)
            DisplayBufferGreen(i) = Green5Data(i)
            DisplayBufferBlue(i) = Blue5Data(i)
            Next
         Case 6
            For i = 0 To 7
            DisplayBufferRed(i) = Red6Data(i)
            DisplayBufferGreen(i) = Green6Data(i)
            DisplayBufferBlue(i) = Blue6Data(i)
            Next
      Else
         ' should never come here
         LCD.WriteAt(2,1,"No Value .RndGen")
      End Select
      
      ' now draw the data to matrix
      For j = 0 To 20
         DrawGraphics()
      Next
    Next
End Sub

Sub ScrollText()
    If DisTitle = 1 Then
        If AnimationSpeed <> 0 Then
            Dec(AnimationSpeed)
        Else
               AnimationSpeed = 6
            StartColumn = StartColumn + 1
            If StartColumn + 8 = 96 Then            ' 120 is the pixel width of the levels
                StartColumn = 0
            EndIf
        EndIf
    EndIf
End Sub 

Sub CheckForStart()
    If DisTitle = 1 Then
        If ButtonLockoutDelay <> 0 Then
           Dec(ButtonLockoutDelay)
        Else                            
           If ButtonStart = 0 Then  ' if we press either of the two game buttons then start the game and reset all variables
                ButtonLockoutDelay = 200 ' this is so we have a little delay between showing the title and starting or restarting the game                  
                AnimationSpeed = 10     
                DisTitle = 0        ' disable the title
                PlayGame = 1        ' enable the game
                StartColumn = 0     ' make sure we start back at the first column (because the title also uses this variable)
                LCD.Cls
                GetRandData()       ' get random data to start with.
                SoundEnable = 0     ' turn off title screen music
           EndIf
        EndIf
    EndIf 
   If PlayGame = 1 Then
      If ButtonLockoutDelay <> 0 Then
         Dec(ButtonLockoutDelay)
      Else
         If ButtonStart = 0 Then
            SoundEnable = 0     ' make sure title screen music is off
            GetRandData()
            ButtonLockoutDelay = 15 
         ElseIf ButtonExit = 0 Then
            ButtonLockoutDelay = 250
            AnimationSpeed = 10
            DisTitle = 1
            PlayGame = 0
            StartColumn = 0
            If SoundONflag = 1 Then
               SoundSelect0 = 1  '
               SoundSelect1 = 1  ' End song
               SoundSelect2 = 1  ' 
               SoundEnable = 1   ' start song
            EndIf 
         EndIf
      EndIf
   EndIf
End Sub


Sub WriteLCD()
    ' display dice num and cycle through 2 lcd screens
    If PlayGame = 1 Then
      If LCDTimer <> 0 Then
         LCDTimer = LCDTimer - 1
      Else
         LCDTimer = 200
      EndIf
      
      Select LCDTimer
      Case 0 To 100
         LCD.WriteAt(1,1,"Dice number = ",Convert.DecToStr(RandomVal))
         LCD.WriteAt(2,1,"press B to start")
      Case 101 To 200
         LCD.WriteAt(1,1,"Dice number = ",Convert.DecToStr(RandomVal)) 
         LCD.WriteAt(2,1,"press A to exit ")
      End Select
    EndIf
    ' title screen 
    If DisTitle = 1 Then 
      LCD.WriteAt(1,1,"Electronic Dice ") 
      LCD.WriteAt(2,1,"press B to start")
    EndIf
End Sub

// Start Of Program... 
SoundEnable = 0
OSCCON = %01111111                  // Sets the internal oscillator for 8Mhz
SetAllDigital                       // Make all Pins digital I/O's    
TRISA = %00000000
TRISB = %00000000               
TRISC = %00000000
TRISD = %11111111
TRISE = %00000000

' setup Random Gen
RandGen2.Initialize (119)        // Initialize the Random Number generator (set to 119 but can be changed) 
RandGen2.SetRndMax(7)
               
AnimationSpeed = 50
ButtonLockoutDelay = 250  
StartColumn = 0
PlayGame = 0
DisTitle = 1
SoundONflag = 0
LCDTimer = 100

SoundSelect0 = 1  '
SoundSelect1 = 1  ' End song
SoundSelect2 = 1  '

// some functions before prog starts
' check sound On/Off (controlled by pressing and holding the buttonsoundoff on start up)
If ButtonSoundOff = 0 Then
   SoundEnable = 0
   SoundONflag = 0
Else
   SoundEnable = 1   ' Enable song
   SoundONflag = 1 
EndIf 

// Main Loop
While True()     
      CheckForStart()             
      DrawGraphics()
      ScrollText()
      WriteLCD()
Wend       
If you don't know what Voltage your country is using, you shouldn't be doing electronics ;-)

User avatar
bitfogav
Moderator
Moderator
Posts: 915
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Electronic Dice for the SPB

Post by bitfogav » Thu Sep 13, 2012 7:38 am

If anyone has any questions then please ask :)

Here is the Hex file:
Electronic Dice.rar
(3.35 KiB) Downloaded 387 times
If you don't know what Voltage your country is using, you shouldn't be doing electronics ;-)

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm

Re: Electronic Dice for the SPB

Post by brad » Fri Sep 14, 2012 8:58 am

I've said this before and I'll say it again - very cool bitfogav!

I especially think it's great that someone has done something extra with Super Pixel Bros.

What we should do is put in an accelerometer then you can literally throw the SPB board and the accelerometer will start the dice rolling. Although you would need to make sure the screen always landed the correct way up...

User avatar
bitfogav
Moderator
Moderator
Posts: 915
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Electronic Dice for the SPB

Post by bitfogav » Fri Sep 14, 2012 10:06 am

Im actually waiting for some accelerometers to turn up. :D
If you don't know what Voltage your country is using, you shouldn't be doing electronics ;-)

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm

Re: Electronic Dice for the SPB

Post by brad » Sat Sep 15, 2012 9:00 am

bitfogav wrote:Im actually waiting for some accelerometers to turn up. :D
Which ones? I bought a couple that are great (haven't done much with them yet) but they simply have three analog outputs for X, Y and Z. they can vary from 0v to 3.3v depending on how each axis is tilted :)

User avatar
bitfogav
Moderator
Moderator
Posts: 915
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Electronic Dice for the SPB

Post by bitfogav » Sat Sep 15, 2012 9:04 am

Some MMA7361 on a breakout board from ebay :D
If you don't know what Voltage your country is using, you shouldn't be doing electronics ;-)

User avatar
brad
Site Admin
Site Admin
Posts: 2578
Joined: Fri Mar 26, 2010 10:30 pm

Re: Electronic Dice for the SPB

Post by brad » Sat Sep 15, 2012 9:16 am

Yep, same as mine!

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest