Showing posts with label SmileBASIC. Show all posts
Showing posts with label SmileBASIC. Show all posts

Thursday, December 17, 2020

SmileBASIC 3DS DIALOG Instruction: Undocumented DIALOG Types

I don't know if these are documented anywhere and I'm too lazy to do the most cursory of research, so here I am posting the results of my independent discovery.  Gather 'round, because it's time for everyone's favorite thing in the world: Storytime with XT!

I was poking around the Smile tool when I noticed that the graphics editor presents a strange-looking dialog when you press Y.  It lets you press A, X, or Y to achieve various goals, or B to return to what you were doing without modifying anything.  This dialog is presented in the same graphical style as those produced by the DIALOG instruction, but it doesn't have the buttons at the bottom of the touchscreen that are normally there.  The built-in documentation for the DIALOG instruction only covers six types:
0: OK (default) 1: No/Yes 2: Back/Next 3: Cancel/Confirm 4: Cancel/Execute 5: Next
This piqued my interest, so I looked into the code.  If you also wish to do so, a simple LOAD "PRG0:SYS/SBGED" from direct mode will load the code into slot 0.  I searched through for a DIALOG instruction and came across a procedure definition on line 1228 called DLG that uses it and parameterizes the text (to a label representing DATA instructions to read), type, and caption for calling code.  Searching for code that calls it, I found that the line of code on line 1141 produces this strange dialog by calling DLG() with the type -1.

Yeah, negative one.  Interest fully attained, what other valid values are there?  I explored the negative dimension and here are the results:
-1: A/B/X/Y (A: 128, B: 129, X: 130, Y: 131) -2: D-pad (Up: 132, Down: 133, Left: 134, Right: 135) -3: A/B/X/Y and D-pad -4: L/R (L: 136, R: 137) -5: L/R and A/B/X/Y -6: L/R and D-pad -7: L/R, A/B/X/Y, and D-Pad -8: Touchscreen (Tap: 140) -9: Touchscreen and A/B/X/Y -10: Touchscreen and D-pad -11: Touchscreen, A/B/X/Y, and D-pad -12: Touchscreen and L/R -13: Touchscreen, L/R, and A/B/X/Y -14: Touchscreen, L/R, and D-pad -15: Touchscreen, L/R, A/B/X/Y, and D-pad
The numbers in parentheses are the return values from the DIALOG instruction.  These don't make it into RESULT, you have to assign it to a variable.  If it looks confusing to you, I can explain it.

Ignore all of them except for -1, -2, -4, and -8.  Notice how they only enable one distinct set of inputs to dismiss the dialog?  This is a bit field.  You can compute any of the other values by adding some or all of these four together.  Should you want to do this more easily, you can just stick this in your program:
VAR ABXY=-1 VAR DPAD=-2 VAR LR=-4 VAR TOUCHSCREEN=-8
After that, you can just add together your desired combination using the variable names and it will be self-documenting.  You may also find it cromulent to have similar variable names for the return values:
VAR DLGA=128 VAR DLGB=129 VAR DLGX=130 VAR DLGY=131 VAR DLGUP=132 VAR DLGDOWN=133 VAR DLGLEFT=134 VAR DLGRIGHT=135 VAR DLGL=136 VAR DLGR=137 VAR DLGTOUCH=140
Yes, I am beginning to hate the 3DS version of SmileBASIC for lacking user-defined constants.  All the more reason I should get SmileBASIC 4 on my Switch, I guess.

I have observed that ZL and ZR are nowhere to be found, and the return values 138 and 139 are also missing.  I tested all fifteen DIALOG types with XON EXPAD enabled on my New 3DS XL, and ZL and ZR did nothing with any of them.

I tested a handful of other values for the type parameter but came up empty.  Any value I tried that was less than -15 or greater than 5 produced an out of range error.

For the sake of completeness: If you want to inspect RESULT after showing a dialog using one of these types, it works as you'd expect for the DIALOG instruction, except that RESULT will never be -1.  Confirmation and timeout are the only values RESULT will indicate.

I hope that anyone still using SmileBASIC on the 3DS finds this useful.  I'm not sure how applicable this is to SmileBASIC 4, or the Japan-exclusive SmileBASIC BIG on the Wii U.  If this behavior was already documented elsewhere, now it's documented here as well.

Sunday, October 18, 2015

SmileBASIC Tutorial: The Touchscreen

This tutorial, as well as any and all of my future tutorials, assume that you understand basic programming concepts such as variables, keywords, control structures, branching, etc.  If you don't understand these things, there's actually a primer in the digital manual for SmileBASIC.  Just select it on your 3DS' home menu and tap the Manual button.  I'm mainly going to focus on accomplishing specific tasks, which will be supplemented with simple programs.  The task of putting all of this knowledge together and making a game out of it will be left as an exercise for the reader.

SmileBASIC also has a complete reference to all of its built-in keywords and functions.  Just start typing something.  See the keywords and so forth that appear in the green boxes at the top of the touchscreen?  Tap one of them, then tap the question mark on the right.  Instant reference for anything in the language, and it's super helpful.

That said, let's begin.

The touchscreen is pretty simple to read from in SmileBASIC.  Consider this line of code.


TOUCH is the meat and potatoes of this instruction.  There's actually another parameter that can go between TOUCH and OUT that specifies the "Terminal ID", this is for writing programs that make use of the 3DS' wifi card.  Wireless connectivity is outside the scope of this tutorial, so let's move on.  OUT directs the output to the three variables provided.  The first one, TIME, is the amount of time that the touchscreen has been touched.  If this is zero, the user is not touching the touchscreen.  X and Y are the coordinates of the touch.  The origin (0, 0) is the top left corner of the screen.  However, SmileBASIC won't return a touch in the outermost five pixels of the touchscreen on each side, so the range you have to work with is 5..314 for X, and 5..234 for Y.

To actually get started, you'll need to set the screen mode using the XSCREEN instruction.  SmileBASIC defaults to XSCREEN 0, which allows the top screen to use stereoscopic 3D effects, but doesn't use the bottom screen.  The bottom screen will continue to be the on-screen keyboard.  XSCREEN 1 disables stereoscopic 3D on the top screen, but also doesn't use the touchscreen.  To actually use the touchscreen, you'll want XSCREEN 2, XSCREEN 3, or XSCREEN 4XSCREEN 4 is a bit weird for tutorial purposes, and you probably won't want to mess around with the stereoscopic 3D just as you're learning to work with the touchscreen, so the one you'll want is XSCREEN 3XSCREEN has other arguments, that deal with sprites and background images, but they're optional, so let's keep it simple and not pass values to them for now.

However, before that, you don't really know with 100% certainty what state the screens are in.  You could have been messing around in DIRECT mode just running instructions, or a previous program could have left stuff there.  You'll want to return to a nice known state, and this is made very easy with the ACLS instruction.  Inspect the help on it to see exactly what it does, because it does a lot of stuff.  The important thing to know is that after the ACLS instruction, the displays and graphics pages will always be in a known state, so it can only help to begin your program with it.  Since it explicitly sets some things that you may want to override for the purposes of your own program, make sure it's the first line of code and all your changes happen after it.

Like any other form of reading input, you'll want to read from the touchscreen in a loop.  It's fair to assume that you'll also be reading button input in this loop, as you get on to bigger and better projects.  Consider this sample code.


That code should give you an idea of what your game loop might look like in its most basic form.  We read button input so that our loop can check to see if the Y button is among those being pressed, and if it is, the loop will exit.

Now, let's actually output some stuff, so you can see what you're reading from the touchscreen.  This is a rather simple application of LOCATE, the FORMAT$() function, the PRINT statement, and the VSYNC instruction.  Behold, our modified sample code.


The VSYNC instruction is important, because it waits for the rest of the screen to be drawn before letting execution continue.  The argument, in this case, 1, speciifies the number of frames to wait.  Since we want to grab input on every frame, we specify 1.  Specifying 1 is actually optional, but I like to do it.  It's handy at times to update the screen multiple times per frame, perhaps to draw several things at once, but in this case all we're doing is outputting text, so it's pointless to output more than once per frame.

From there, the sky's your limit.  I turned it into a program that allowed drawing on the touchscreen, using the d-pad to change sliders for the RGB value of the color, so that drawing in different colors could happen.  If you'd like to check it out, the public key is B5EXV23E.