DVD Studio Pro :: Scripting :: Code Lock Example
COW Library : Apple DVD Studio Pro Tutorials : Alex Alexzander : DVD Studio Pro :: Scripting :: Code Lock Example
As many more users of DVD Studio Pro discover its scripting capabilities we see many more questions for basic examples exploring interactive scripting. In this article, Creative COW leader Alex Alexzander explores the Code Lock script -- one of the scripts most asked about.
DVD Studio Pro is a rare application in its price range. While DVD Studio Pro offers tremendous ease of use, it also balances this ease with a powerful scripting language. This scripting language allows capable authors to expand the functionality of their DVDs with the use of GPRMs (General Purpose Register Memory), SPRMs (System Parameter Register Memory), Navigational Commands, and Conditions-based logic.
When we combine these basic elements in our scripting efforts, we can create a variety of simple and interactive elements that enhance our DVDs just a little further than most authoring systems in our price range.
As many more users of DVD Studio Pro discover its scripting capabilities we see many more questions for basic examples exploring interactive scripting. One of the most common scripts I am asked to explore is the Code Lock script.
The Code Lock script is a script that allows you to place a menu with an interactive code entry panel, which allows the user to use a menu as a code entry keypad. This keypad can be used to deny or allow access to another part of the DVD, such as menu or a track.
It should be noted that this is not a very secure method of locking content on your DVD. A determined user can bypass this form of interactivity. However, it is an interesting and fun script to explore nontheless.
Before we get started, let's go over a few basics about how this project is structured. Please download and open the PROJECT file available for download here. Once you have downloaded the project folder, unstuff the contents and open the folder called PROJECT.
You’ll see a few Photoshop-based PSD documents, a PICT document, and a DVD Studio Pro project icon. Double-click on the DVD Studio Pro project icon to load our project example. If you like, feel free to explore the project on your own. This is a fully functional project and can be formatted into a working DVD if you would like to test it. We're going to talk about some of the elements of this project, so if you would like to follow along with the actual project files go ahead and load the project now.
In the Outline tab, click on the Keypad Menu in the Menus folder. Using the Menu tab, click on one of the buttons in our menu. Take note of what the target for the button is. The target is the only script in the project called Code Script. Now click on the other buttons in the menu. Notice that every button has the same target: Code Script.
You'll also notice that the menu itself instructs you to enter a 3-digit code. Now each time you click on one of the menu buttons labeled 1, 2, 3, 4, 5, 6, 7, 8, 9, and 0, you are taken to the script which processes that single button selection and then returns you to the menu to await another button selection. The script is designed to process three button selections from the user and translate those button selections into a working code which is compared to an actual code stored within the script itself.
Once the third menu selection is made, the script will notify the user of the condition of the code entered with one of two possible conditions: Code Accepted, or Invalid Code. If the code is accepted, you will go to a menu for 3 seconds that notifies the user the code has been accepted before it automatically begins to play our sample title track, which is the only track asset in our project.
If the code is found to be invalid, then the user is taken to a menu which displays Code Invalid before the user is taken back to the 3-digit keypad entry page. Once the user has returned to the keypad menu, they must try another code.
If you would like to test this in the simulator now, feel free to do so. The correct code is 567.
Once you have tested the project, you might question how we translated the menu buttons into a working code entry system. I'd like to briefly explore that topic before we get started explaining how this script actually functions because I think it will help you understand this process better.
Within each DVD using a 4:3 menu, as we are using in this project, we have the option of using up to 36 buttons. In our example we are making use of only 10 buttons, labeled 1, 2, 3, 4, 5, 6, 7, 8, 9, and 0. When we select a button in a menu, we are changing the status of a System Register. System Registers, also known as System Parameter Register Memory, or SPRM for short, are a series of machine specific items, such as what language or audio type is currently set for. There are some 24 SPRMs. However, for the purposes of this tutorial we only need to talk about one of them. This SPRM is simply called SPRM 8, and its function is to hold the current menu item selected.
Each SPRM is actually a 16-bit register. SPRM 8 however uses only 6 of its 16 bits to identify any of the 36 possible buttons you may have on any 4:3 menu. So how does this work exactly? Let's take a look at SPRM 8 in binary form, and trust me, this is much easier than it sounds.
The first bit location is bit 0, and the final bit location is bit 15, for a total of 16 bits in this register. The last 6 bits, or bits 10, 11, 12, 13, 14, and 15, are the bits used to define any of the 36 possible button values in terms of SPRM values. Notice how bit 10 is the first bit in use and its value is 1024. This is a key point to remember. Button 1 is actually bit 10 on, and all other bits off. Button 1 = 1024 in terms of the SPRM 8 value.
Let's explore this a little further, shall we?
Take a look at the table below. Here we have all 10 of the buttons we will use in our script. Notice how the button numbers 1 through 10 are really multiples of 1024. Button 1 = 1024, while Button 2 = 2048, Button 3 = 3072, and so on. We can also see how this actually looks in the SPRM 8 register. Only 4 of 6 bits used to define all 36 buttons are actually used here in these first 10 buttons.
The most important point to take away from this is that button values are multiples of 1024, starting with Button 1 and up. As we explore this script, we'll make use of this information as we translate what the user selects as menu buttons into numeric values that we will compare to the code tucked away inside the script.
So how do we compare these button selections with the numeric values of a code?
Each time a button is selected it points to our script. Our script looks at SPRM 8. Specifically it looks at whatever current value is stored in SPRM 8. So, for example, if the user selects Button 1, the target is our script. Our script then checks the value stored in SPRM 8, which would be 1024. Now, our code is 567, so we need to further refine the Button 1 from 1024 into just values between 1 through 10. We do this by dividing the SPRM 8 value by 1024. With this simple adjustment, Button 1 no longer equals 1024. Instead, Button 1 equals just 1. Button 2 no longer equals 2048. It now equals 2.
We accomplish this task with a simple script that copies the SPRM 8 register into a blank register that we can use to modify values and compare conditions. These blank registers are called General Purpose registers, formally known as General Purpose Register Memory, or GPRM for short. Each GPRM is a full 16-bit register, and we have the use of 8 of these registers.
Let's look at a simple translation value system.
1. mov GPRM 1, SPRM 8
Here we can see the effects of these simple scripts. In line 1, we copy the value of SPRM 8 into GPRM 1. At that very moment, GPRM 1 and SPRM 8 are exactly the same value of 1024. In line 2, we modify GPRM 1 with the use of the div command applied to GPRM 1, which reduces any of the values fed into this program by 1024. So Button 1 now equals 1. Button 2 now equals 2, and so on.
Each time the user presses any button on our keypad menu, the value of the menu button is translated just like this into a simple value which we will compare one single digit at a time to our complete code of 567. Therefore, we intend to run this script three times in a loop; once for each button on the keypad the user selects. At the end of the third selection, we will notify the user of the results of the code entry.
Hopefully, we have provided a foundation from which to understand how our code example functions and interacts with the user.
This script works in exactly three stages. The way to accomplish this is by counting how many times the script has actually been executed. Take a look at line 1 of our script. The very first command adds a value to GPRM 0. Now remember, we have use of 8 GPRMs; however, in this project we will only use 3 GPRMs and of course, the 1 SPRM known as SPRM 8. Let's define what these GPRMs are. You do not need to memorize this now, but you will want to refer back to this later on as you read through the script.
GPRM 0 = A Counter. It makes sure we only access this script three times. The third time we access this script it will inform the user of the status of the code entered. Our code is a 3-digit code. The correct answer to this code is 567.
GPRM 1 = A temp register to hold the value of SPRM 8 long enough to divide it by 1024 so we can compare it digit by digit to our code.
GPRM 2 = This register is used solely as a condition. The first two times we accept a digit from the user, we determine if those individual digits are correct. If they are correct, then in the final stage of this script we determine if the final digit is also correct. The final condition asks if the first two individual digits are correct, and if the third digit is also correct then the entire 3-digit code is correct.
The first time the user enters this script, we see in line 1 that GPRM 0 becomes a value of 1. The second time we enter this script, GPRM 0 becomes a value of 2, and the third time we enter this script GPRM 0 becomes a value of 3. This GPRM 0 register works together with lines 4, 5, and 6.
Take a look at lines 2 and 3, and notice these are the commands we talked about earlier. These two lines translate the button values held in SPRM 8 into GPRM 1, which then divides that value by 1024. Each time the user arrives at this script, we translate the button number used to get here into a number value equal to the button graphic. Button 1 for example is a graphic of a number 1. Button 2 is a graphic of a number 2, and so on. However, as we talked about earlier, button values held in SPRM 8 are really multiples of 1024. This is exactly why we are now dividing them by 1024. Now the button number, such as Button 1, also equals 1.
Look at the blue arrow for a minute. If GPRM 0 = 1 then line 4 directs us to go to line 8. Remember GPRM 0 is the register which holds how many times we have arrived at this script. Take a look at the red arrow next. If GPRM 0 = 2, meaning the second time we arrive at this script, we are told to go to line 12. Now take a look at the green arrow. The third time we arrive at this script we are told to go directly to line 17.
This script really operates just like three different scripts in a way. Each time you arrive at this script you execute a different section of it. The first, second, and third sections each do a similar job. They each watch which button you pressed on the key pad. They each test that value against one of three actual digits that make up our 3-digit code.
Take a look at this quick table to better understand what each stage is comparing to.
If GPRM 0 = 1, then GPRM 1 must equal a 5.
If any of the three conditions above are not equal to their respective parts, meaning, 5, 6, and 7, then the code is invalid.
Let's look a little closer at how this works.
Take a look at the highlighted areas. I have dimmed the rest of this script so you focus only on what is actually executed the first time we arrive at this script.
At this stage, GPRM 0 = 1, and GPRM 1 = the button number that the user has selected divided by 1024. Because GPRM 0 = 1, we execute line 4, which states that we must go to line 8.
Lines 8, 9, and 10 actually work together in a way. They basically create one long condition, but the condition we want to create must be broken down into these three basic components. Let's look at what lines 8, 9, and 10 actually mean as a whole. Once we understand that, we can break that down into the three lines of code we see here.
As a whole, these three lines do the following:
Our first digit in our code is a 5, and we want to know if the first digit selected through the keypad menu was not a 5, because if it isn't a 5 then we want to go back to the menu and await the user's second entry. If it is a 5, then we want to make a note of that by adding a value of 1 in GPRM 2. We do this because later on we will check to see if GPRM 2 has a value of 1 inside of it, and if it does, we know that the user entered the correct answer in the first digit entered.
Now in order to accomplish this in this script, it took three lines of code. Let's go over that code now beginning with line 8.
8. Jump Keypad Menu::Button 1 if (GPRM 1 != 5)
Here we are saying, jump back to the keypad menu if GPRM 1 doesn't equal a 5. Because we leave this script right now, if the answer is wrong, we never get to add a value to GPRM 2. If the user did select a 5 on the keypad, then the Jump condition is not met. Remember, it says Jump IF GPRM 1 doesn't equal 5. So if it does equal 5, we do nothing, and continue to execute the rest of this script. That leads us to line 9, which is where we add a value of 1 to GPRM 2 as a marker that means the first digit entered is the correct digit.
Line 10 instructs us to go back to the Keypad Menu and select another digit. So in both conditions set forth in lines 8, 9, and 10 we will go back to the menu to make another digit selection. The difference here is that if the correct digit is entered, then GPRM 2 gets a value of 1 added to it. Each of the next few stages we go over work almost exactly this same way.
Let's take a look at Stage 2 now. This is almost exactly the same. At this stage, GPRM 0 = 2, and GPRM 1 = the button number that the user has selected for the second time divided by 1024. Because GPRM 0 = 2, we execute line 5, which states that we must go to line 12. We also have a new register to think of now. That is GPRM 2. GPRM 2 at this stage will equal either a 1 or a 0. GPRM 2 will equal a 1 if the first digit in the first round was selected correctly. If selected incorrectly, GPRM 2 will hold a value of 0.
Just as before, lines 12, 13, 14, and 15 all work together. The catch this time is that there is an extra line. Not only do we wish to know if the current digit is correct, we also want to know if the last digit is correct. Here is why. Suppose for a minute that the last digit is not the right one. If that is the case, the whole code is going to be wrong anyway, so we won't even bother checking to see if this current digit is right or wrong. Instead we'll simply leave this script now and go back to await the third and final digit entry. This is exactly what line 12 means. It basically states that if GPRM 2 does not equal 1, to simply go back to the keypad menu and await the third and final digit. Remember, GPRM 2 would only have a value of 1 at this stage had the prior digit been correctly selected in the first of the three rounds.
Now, if the first digit in the first round has been selected correctly, then we go to the next line, which should be familiar to you. This line says jump back to the keypad menu to await a third and final digit only if the selection made is not 6. The correct second entry of our three-part code is 6. The whole code, again, is 567. If the user did select 6, then the condition of this line has not been met, which means the user did select correctly and we go to the next line.
Line 14 says add a value of 1 to GPRM 2 again.
Now, let me point out a few things you might have missed. We never get to add a value of 1 to GPRM 2 unless the user always makes the right selections. When the user makes incorrect selections, they always exit the script. So now if GPRM 2 gets a value added here at all, it means that the user has selected correctly two times in a row. If that's the case, that makes the next section very easy. All we have to do in the next section is first ask if GPRM 2 holds a value of 2. If it does, then we want to know if the third selection made is also correct. If it is, all three selections are correct and we have a successful 3-digit code entered.
Line 15 of course sends us back to get that third and final digit from the user.
Let's take a look at Stage 3 now. This is almost exactly the same as stage 2. At this stage, GPRM 0 = 3, and GPRM 1 = the button number that the user has selected for the third time divided by 1024. Because GPRM 0 = 3, we execute line 6, which states that we must go to line 17. GPRM 2 at this stage will equal either a 2 or a 0. GPRM 2 will equal a 2 if the last two digits in the last two rounds were selected correctly. If selected incorrectly, GPRM 2 will hold a value of 0.
Now as you look at lines 17 through 25, you will notice a lot more code here than in the prior two sections. The reason for this is we are at the final stage now, and whether the user is right or wrong, we need to clear these registers once the code has been accepted or denied. Now, since there are two possible outcomes to this, meaning the answer is either right or wrong, we need to clear the registers in both cases. This adds four more lines of code that otherwise wouldn't be here.
Let's start with line 17 and 18 briefly, then get a little more in depth. Lines 17 and 18 both state that the user will go to line 23 if their respective conditions are met. Line 17 says that if GPRM 2 does not equal 2 then go to line 23 now. Line 23 essentially clears the current registers and sends us to a notification menu which tells the user the code is not valid. GPRM 2 holds the answer to the following question: Have the last two digits selected been correct? If they have not been correct, then this code is invalid, so we go to line 23 and clear our registers so we can again ask for the code all over again starting with digit one.
Let's say that line 17's condition is not met. That must mean that the past two selected digits were both correct. Now we need to know if the final digit is also correct. Line 18 sets another condition. It says, if GPRM 1 isn't a 7, then go to 23, clear the register and start over because the code is invalid. The correct digit is a 7, and if this condition is not met, then it means the user correctly selected 7, therefore the user got all three digits correct.
We now clear the registers in lines 19 and 20, before we execute line 21. Line 21 instructs us to jump to the accepted menu, where we are told our code has been accepted.
Well, I hope you have enjoyed this quick lesson and example of a code lock script. Hopefully the concepts set forth here will enable you to explore further on your own other script-based tasks with DVD Studio Pro 3.
[Top]©Copyright 2004 Alex Alexzander and Creative Cow
All Rights Reserved
Please visit the forums or read other articles at Creativecow.net if you found this page from a direct link.