Jump to content



Tutorial info Visit support topic

  • Added on: Aug 31 2015 07:39 PM
  • Views: 4402
 


* * * * *
2 Ratings

UltraDMD Code Examples

After Reading the UDMD fundamentals, now you want some examples huh? Well, here ya go.

Posted by Shoopity on Aug 31 2015 07:39 PM

So, here are some examples of how I implemented UDMD into America's Most Haunted.  First off, remember that I tried my darndest to keep as much of original code untouched (syntax adjustments aside) and changed/rewrote/created sub routines only when needed.  For example, in the original code there are two separate calls to either play a scene or queue a scene, meaning he wrote two routines that either immediately played a scene if it had the same or greater priority as the current scene playing, and another routine to always queue the scene to play as soon as the current one (if there was one) finished.  With UDMD, you could probably just have one routine that would would either interrupt the current scene, queue the current called scene, or do nothing depending on the priority.  I'll go into more details.

 

To start, here's my code for calling scenes:

Sub DMDScene (background, toptext, topbright, bottomtext, bottombright, animatein, pause, animateout, prio)		'regular DMD call with priority
	If prio >= OldDMDPrio Then
		DMDSceneInt background, toptext, topbright, bottomtext, bottombright, animatein, pause, animateout
		OldDMDPrio = prio
	End If
End Sub

Sub DMDSceneInt (background, toptext, topbright, bottomtext, bottombright, animatein, pause, animateout)		'This gets called if the priority is greater than or equal to the current scene in order to interrupt it
	Dim X
	If Not UltraDMD is Nothing Then
		UltraDMD.CancelRendering
		UltraDMD.DisplayScene00 background, toptext, topbright, bottomtext, bottombright, animatein, pause*PauseAdjuster, animateout
		If pause > 0 OR animateIn < 14 OR animateOut < 14 Then
			TiDMDScore.Enabled = False
			TiDMDScore.Enabled = True
        End If
	End If
End Sub

Sub DMDSceneQ (background, toptext, topbright, bottomtext, bottombright, animatein, pause, animateout)			'EP- Called to queue up a video
	Dim X
	If Not UltraDMD is Nothing Then
		UltraDMD.DisplayScene00 background, toptext, topbright, bottomtext, bottombright, animatein, pause*PauseAdjuster, animateout
		If pause > 0 OR animateIn < 14 OR animateOut < 14 Then
			TiDMDScore.Enabled = False
			TiDMDScore.Enabled = True
        End If
	End If
End Sub

Sub TiDMDScore_Timer()
	If Not UltraDMD is Nothing Then
		On Error Resume Next
		If Not UltraDMD.IsRendering Then
			'When the scene finishes rendering, then immediately display the scoreboard
			me.Enabled = False
			DMDScore()
		End If
		On Error GoTo 0
	End If
End Sub

Sub DMDScore()
	If Not UltraDMD is Nothing Then
		On Error Resume Next
		OldDMDPrio = 0
		UltraDMD.DisplayScoreboard numPlayers, Player, PlayerScore(1), PlayerScore(2), PlayerScore(3), PlayerScore(4), "Ball " & Ball, "Credits " & credits
		On Error GoTo 0
	End If
End sub

NOTE: PauseAdjuster is set to 60 in my table.  All the gifs are at 15 FPS; so 15/1000 = 66 2/3.  I just rounded down to 60... for no real reason actually.  So I can just pass in the number of frames, which is easy to see in IrfanView since I didn't create these gifs, and the pause adjuster will change it to the approximate pause time.

 

Then here's an example of what gets called when a bumper gets hit (slightly edited to remove the original code compatibility):

DMDScene "WAZ.gif", "", -1, "", -1, 14, 40, 14, 250

Let's say this is the very first thing that happens in the game (so OldDMDPrio = 0), here's what happens:

A bumper gets hit and calls the routine DMDScene passing in those arguments

The current prio, 250, is greater than OldDMDPrio, 0, so it calls DMDSceneInt (meaning it's going to interrupt the current scene)

-----------

The DMD cancels rendering

The DMD displays the scene with waz.gif as the background, nothing for the top text, the top text has a -1 brightness, nothing for the bottom text, the bottom text has a brightness of -1, it doesn't animate to start (14 means no animation), it pauses for 2400 milliseconds (or 2.4 seconds), it doesn't animate after the pause time is done

Since a pause time was in fact defined, the score timer is turned off and turned back on (probably not needed to turn it off first, but I was having an issue and did this just to make sure and be thorough)

-----------

The TiDMDScore timer now starts running.  On my table it's set to run 100 times a second; you could probably set the timer to be higher (so it runs less times per second)if you're having performance issues.

While it's running, it's constantly checking if the DMD is rendering.  If it is, then nothing else happens, the DMD just continues doing its thang.

But as soon as it finishes rendering, DMDScore is called

-----------

DMDScore now resets the OldDMDPrio (since the DMD will now just show the score board meaning any scene can run next)

The Score Board is displayed passing in the total number of players playing, the current player (1, 2, 3, or 4), the scores of each player, which ball the player is on in the lower left corner, how many credits are in the machine in the bottom right corner

 

Let me take a moment to describe the Score Board since I didn't do that in the previous tutorial.

The score board is a special scene that displays integers in the top/bottom right/left corners of the screen with the option of showing small text in the bottom Left/Right corners (below the scores).  In the AMH code, numPlayers is set to how many people are playing so the scoreboard always know how many scores to display.  In the code, Player is always set to the player number that's currently playing, so the DMD always knows which score to display larger.  In the code, the array PlayerScore() contains each player's score.  The variables Ball and Credits are always set to which Ball is in play and how many credits are being displaying.

 

With that example, you can get an idea of lots of things to do.  The AMH table uses 255 possibilities for a priority (probably due to some hardware bit/byte thing), but you can put whatever number you want in there.  Priority is actually a pretty important thing.

 

In the previous example, that means if a main mode advance animation is running (let's say you made the Hotel shot and you advanced the Hotel for the first time, running the animation that goes along with that) which has a priority of 255, and you make a bumper hit, then nothing happens because 250 is less than 255.

 

 One ideas include using the priority, not only to determine if the scene should overwrite the current scene but also as a pseudo scene, or scene type identifier.  UDMD has a Scene ID functionality for modifying purposes, but currently there's no way to know what scene is currently being displayed.  You could give you bumper hits a unique priority number, then when you do your priority check, you can also check if the priority is that specific number, then you can do specific things.  Like:

Sub DMDScene (background, toptext, topbright, bottomtext, bottombright, animatein, pause, animateout, prio)		'regular DMD call with priority
	If prio >= OldDMDPrio Then
		If prio = 301 AND OldDMDPrio = 301 Then		'Must be a bumper animation'
			UltraDMD.ModifyScene00 15, "", BumperHits
		ElseIf prio = 301 AND OldDMDPrio <> 301 Then
			UltraDMD.DisplayScene00ExWithId 15, False, background, toptext, topbright, -1, bottomtext, bottombright, -1, animatein, pause*pauseadjuster, animateout
		Else
			DMDSceneInt background, toptext, topbright, bottomtext, bottombright, animatein, pause, animateout
		End If
		OldDMDPrio = prio
	End If
End Sub

Or even smarter, break out the modify sub:

Sub DMDScene (background, toptext, topbright, bottomtext, bottombright, animatein, pause, animateout, prio)		'regular DMD call with priority
	If prio >= OldDMDPrio Then
		If prio = 301 AND OldDMDPrio = 301 Then		'Must be a bumper animation'
			DMDModify 15, toptext, bottomtext
		ElseIf prio = 301 AND OldDMDPrio <> 301 Then
			DMDPop background, toptext, topbright, bottomtext, bottombright, animatein, pause, animateout
		Else
			DMDSceneInt background, toptext, topbright, bottomtext, bottombright, animatein, pause, animateout
		End If
		OldDMDPrio = prio
	End If
End Sub

Sub DMDModify(SceneID, toptext, bottomtext)
	UltraDMD.ModifyScene00 15, "", bottomtext
End Sub

Sub DMDpop(background, toptext, topbright, bottomtext, bottombright, animatein, pause, animateout)
	UltraDMD.DisplayScene00ExWithId 15, False, background, toptext, topbright, -1, bottomtext, bottombright, -1, animatein, pause*pauseadjuster, animateout
End Sub

You can also pass in arguments as the background string by concatenation:

DMDScene "Catapult" & CatAdvance & ".gif", "", -1, "", -1, 14, 50, 14, 255

In this instance, first you'd have multiple gifs for advancing the catapult mode, aptly name "Catapult1.gif', "Catapult2.gif", and so on.  Every time someone makes the catapult shot, you increment CatAdvance.  This saves you from having to do if statements like:

If CatAdvance = 1 Then
  DMDScene "Catapult1.gif", "", -1, "", -1, 14, 50, 14, 255
ElseIf CatAdvance = 2 Then
  DMDScene "Catapult2.gif", "", -1, "", -1, 14, 50, 14, 255
ElseIf ...
.
.
.

I think that might be it for now.  If there's a great enough desire for more helpful tips, I'd be happy to write more.