Wow Xeda, there really is a lot to grammer, great work! I love the particle engine, and I can't wait to see the new features in Grammer 3!
(Heck, for all I know you could add custom objects and gravity for the screen next time Razz)
Thanks for all your help!
(Although I might have some more questions later on :c)
How would I make a tile map and turn it into an appvar?
It might actually be easier to create the tilemap of whatever size you need and edit the data that way. For example, if you need a 50x50 tilemap, you might make a 2502 byte appvar, where the first 2 bytes hold the width and height of the map (in tiles, not pixels):

Code:

Send(2502,"UTileMap0→Z
int(Z,50
IS>(Z      ;just to increment Z
int(Z,50
IS>(Z      ;just to increment Z

Grammer stores tilemaps by column first, then row, so the first 50 bytes of the appvar corresponds to the first column, the second 50 bytes corresponds tot he second column, and so on. Then if you want to edit the byte at column C and row R with the tile number N:

Code:

int(Z+R+50*C,N

And to read the tile number:

Code:

(Z+R+50*C
Have you anymore plans for properties or more rulesets in particles for Grammar 3?
(Like each given particle only has a certain anount of life-span or it could duplaicate itself rapidly.)

And what are the new commands for the latest version of grammar?
I use the documentation for looking things up, but it doesn't list everything, sadly..
For Grammer 3, yes, there can definitely be more rules and whatnot. It will have the ability to have a customisable command set, too. That way if there is need for more advanced commands, like calculus stuff, or really advanced GUI routines, users can install the given package and programs that use it will run properly.

The new commands... there are good number of them that may not be documented yet :[ Here are a few I can come up with for The_Warlord (modified a little)
-You can draw text to different buffers and particles
-You can use If...Then...Else...End
-You can display large numbers (32-bit) and signed numbers (signed requires setting a specific mode with Fix)
-You can do some really crazy new things with the error handler like create your own commands (if you try to run an unsupported command, an error is thrown that can be redirected to an error handler and you can use some commands to parse arguments of the token). This functions by using the ']' token to parse an argument at a given address and using the '?' token since it points to the next byte that would have been read if the error hadn't occured. So basically, ']?' reads the next argument (and you can do this several times for several arguments).
-You can use functions like prgm(ptr,Arg1,Arg2,... This uses the same ']?' syntax for passing arguments. I really keep forgetting about this snazzy tool.
-There is a pretty nice Menu( command that returns the number of the selected item. It only uses the fixed width font, though, but it can draw to pixel coordinates. Inputs are Menu(y,x,width,"Header","Item0","Item1"...
-Fix has more fine-tuned control, such as using the 'or ',' and ', and ' xor ' tokens to perform bitwise operations.
-There is 4-level grayscale and 3-level grayscale which can be controlled using 12 different saturation modes.
-There is rectangle clipping, now
-Input looks gorgeous now. Seriously. It starts the input after the last drawn text and allows you to append text to the end of your input. For example, you could do:

Code:

Text(0,0,"func(
Input ")→A

And then anything you input will be wrapped between the last text drawn and the ")" token. Also, the input is highlighted.
-You can now fine tune the particle effects. Particles also run even faster. With 2048 particles on the screen, you can now manage about 5.66FPS compared to 3.60FPS before. (You already knew this)
-Sprites and circles have some arguments that can be omitted, now
-Text( has a handful of new variations to control cursor movement and whatnot. For example, if you want to add 6 to the last Y coordinate and set the x coordinate to 0 (essentially moving down another line):

Code:

Text(+6,0,"Text

You can also just set the coordinates by omitting a third argument:

Code:

Text(0,0

And you can get the X and Y coordinate returned in two registers using just Text(:

Code:

Text(→XY


Also, if you do something like →XY, where you are using two pointer variables, the value of theta' gets stored to the first p-var and the normal result get stored to the second. This is useful for some 32-bit math.
Tell me more about creating my own commands Surprised
Any examples?
This is getting more and more amazing the more I ask about it x3
Haha, that could be complicated, but let's see what can be done. Sometimes it will be easier just to use the prgm( command.

First, I need to explain the error handler. If you have your own error handler installed using solve(3, all errors will get passed to that code. θ' will contain the error code 0=ON error, 1=Memory error, 3=Token Error. As well, the '?' variable will be updated with the address of the program counter. So an error handler might look like:

Code:

.ERR
!If θ'
Goto Lbl "SAVEQUIT
If θ'≠3
solve(4,θ'       ;let Grammer throw the given error.
If πB5≠(?-1    ;check if the token is the dim( token. If not, Error
solve(4,2,"Bad Token    ;custom error

It isn't finished. Now we need to figure out what to do with the dim( token. Let's have it test the value of a grayscale pixel. We will use dim(Y,X,GrayBuf), so continue:

Code:

]?→Y     ;parse the Y argument
]?→X     ;Parse the X argument
pxl-Test(Y,X,]?
+Ans+pxl-Test(Y,X
End)      ;a special End that returns Ans and θ' modified.

Normally, the error handler restores Ans and θ' before exitign, but if you are trying to create your own function, that isn't useful, so you end with End). It basically returns a value of 0 to 3 based on the pixel values on the primary and secondary buffer.
Complex o_o
How does width in the menu command work?
How could I do grayscale? Very Happy
The width should just be the width in pixels of the menu. Height is calculated based on how many menu items there are.

For grayscale, you can use the Disp command to define a primary and secondary buffer. Setting the same buffer as both simply makes a b/w image. Setting it to another buffer like pi86EC (saveSScreen for assembly programmers) will sample the primary and secondary buffer using the given saturation level. By default, it is 50-50, so if the pixel is ON in both buffers, it appears black, if it is OFF in both buffers, it appears white, and if it is ON in one buffer and off in the other, it appears as gray. If you use #→Disp to define the grayscale mode, you can make it so that if the pixel is ON in the primary buffer but OFF in the secondary buffer, it makes a dark gray, whereas if it is the other way around you get light gray. There should be documentation about that in the readme. Also remember that you need to be using DispGraph frequently to update the LCD fast enough for it to appear gray. The drawing commands should all have some method of drawing to another buffer (usually an optional argument).

If you look for the Grayscale topic in the tutorial/readme you will find the following code for a simple grayscale drawing program using 4-level gray:

Code:

:.0:
:π9872→Z      ;9872h is the default buffer for particles, but we can use it for a secondary buffer.
:Disp Z
:ClrDraw
:ClrDrawZ
:0→X→Y
:2→Disp
:Repeat getKey(15
:Pxl-Change(Y,X ;Just drawing the cursor
:Pxl-Change(Y,X,Z ;Pixel changing it on both buffers
:DispGraph
:Pxl-Change(Y,X
:Pxl-Change(Y,X,Z
:getKey→A
:If =54: or A=9 ;If [2nd] or [Enter]
:Pxl-On(Y,X,Z
:If A=9: or A=48 ;If [Enter] or [Alpha]
:Pxl-On(Y,X
:If A=56: or A=54 ;If [Del] or [2nd]
:Pxl-Off(Y,X
:If A=56: or A=48 ;If [Del] or [Alpha]
:Pxl-Off(Y,X,Z
:X+getKey(3:-getKey(2:If <96
:→X
:Y+getKey(1:-getKey(4:If <64
:→Y
:End
:Stop
Is it possible to have a program still perform a few commands while it's not being run? So, if the program was run once and x=0, would there be a way to increase X while the calc is off or program isn't running?
gaventemples31415 wrote:
Is it possible to have a program still perform a few commands while it's not being run? So, if the program was run once and x=0, would there be a way to increase X while the calc is off or program isn't running?


Short answer: No.

It would be possible with assembly and I believe it would have been possible with an old version of Grammer, too. I used to allow the creation of an actual interrupt that runs a chunk of Grammer code, but now I just use a code counter timer thing so it isn't actually an interrupt in the Assembly sense. Regardless, it would have been too complicated to get it to keep running (reliably) after the main program was finished.
So the long answer: Yes, but with more difficulty and effort than what I would care to put in at the time :/
Okay, then, so I won't do it. Thank you.
A few more questions:
How exactly do I send and read data to or from an appvar?
Grayscale doesn't seem to work for me, even though I copied down the example code. Any ideas why?
I don't understand Input. Could you explain it, please?
Is it possible to play chords rather than single notes?
And, lastly, how would I create a custom font?
I know, it's a lot, but I'm extremely confused about most of Grammer's capabilities. Thank you!
gaventemples31415 wrote:

How exactly do I send and read data to or from an appvar?

You will want to use Get( and Send( for such control. In the Data Types section of the PDF, it says U or 5 can be used for an appvar name. This means if you wanted to access the appvar named HELLO, you would use the string "UHELLO" for the name.

Get( is used to get information about the variable. So Get("UHELLO" returns:
0 if appvar HELLO does not exist
<32768 if the appvar is archived
>32768 if the appvar exists and is in RAM
Ɵ' contains the flash page the variable is on, if it is archived,
otherwise Ɵ' is 0. This is for advanced stuff.

Send( can be used to create a variable. If you wanted it to have 1000 bytes of data, you would do:

Code:

Send(1000,"UHELLO"


Both of these commands return a pointer to the data bytes of the variable (if it exists). There are a few ways to read and write data, but there are (almost) no safety checks for writing data.

The following examples overwrite the appvar HELLO and recreate it as 1000 bytes, then writes data to the appvar HELLO:

Code:

Send(1000,"UHELLO→Z
int(Z,7
iPart(Z+1,1337
Z+3
[1,2,3,4

int( writes 1-byte values (0 to 255) and iPart( writes 2-byte values (0 to 65535). Whenever we use Z+<number>, we are accessing a byte number. Z+0 is the first byte of the appvar, Z+999 is the last byte. The two lines, "Z+3:[quote="gaventemples31415"] in Ans, then that is used as the address for where to write the bytes
gaventemples31415 wrote:
r more stuff, look at the "Memory Access" section.
[quote="gaventemples31415"]
Grayscale doesn't seem to work for me, even though I copied down the example code. Any ideas why?

I'm not sure why it wouldn't work. Maybe I introduced more bugs after trying to fix old ones... What version do you have?
gaventemples31415 wrote:

I don't understand Input. Could you explain it, please?

Input is actually pretty decent in Grammer, so I hope I can explain it well. Anyways, if you want to have the user input something that gets evaluated as a numerical value:

Code:

expr(Input →A

The Input prompt will occur directly after the last drawn text (it uses the internal text pixel coordinates). Vaguely like BASIC, you can also display text with the input. The huge difference is that the text comes after the input. So for example:

Code:

expr(Input "-"→A

This will make it so that as the user enters a number or letter or whatever, the "-" still stays ahead of the cursor. You might ask how this can be useful, but try this code:

Code:

.0:Return
ClrDraw
Text("Coordinates=(
expr(Input ",)"→X
Text(",
expr(Input ")"→Y
DispGraph
Stop

EDIT:

gaventemples31415 wrote:

Is it possible to play chords rather than single notes?

I don't know the mathematics involved for that and I feel like it would be too complicated, sorry :/
gaventemples31415 wrote:

And, lastly, how would I create a custom font?

Actually, this is a font editor that includes Grammer and Batlib compatible fonts. To use in Grammer, create a font and export it as the .asm format. Then use your favorite z80 compiler to compile to an appvar (I use ORG since it's an option). And there you go!
gaventemples31415 wrote:

I know, it's a lot, but I'm extremely confused about most of Grammer's capabilities. Thank you!

I'm glad for the questions ^_^ I'm a bit rusty on the language, so it helps me remember Razz
Oh, wow, this helped a lot!

Xeda112358 wrote:
gaventemples31415 wrote:
Grayscale doesn't seem to work for me, even though I copied down the example code. Any ideas why?


I'm not sure why it wouldn't work. Maybe I introduced more bugs after trying to fix old ones... What version do you have?

I have Grammer 2, the app.

When I read the section on Memory Access, there are two options for copying data: forwards and backwards. What is the difference, and what does little endian mean?
So, how would I create a tilemap and use it in a game?
Can you make a 12x12 sprite, or can they only be multiples of 8?
How do lists work in Grammer?
gaventemples31415 wrote:

I have Grammer 2, the app.

I gathered that, but which version/revision of Grammer 2? When you run the Grammer app, it should say at the bottom v2.xx.yy.zz
gaventemples31415 wrote:

When I read the section on Memory Access, there are two options for copying data: forwards and backwards. What is the difference, and what does little endian mean?

Forward means that if you have the string of bytes 1,2,3,4,5 at address 0x8000 and you wanted to copy that to 0x9872, you would use 0x8000, 0x9872, and the bytes copied would be 1, then 2, then 3...
Backwards means that you would have to use the pointers 0x8004 and 0x9876, and the bytes copied would be 5, 4, 3, 2, 1, moving backwards through memory (so it would still be 1,2,3,4,5 copied 0x9872).

Basically, it's the difference between copying forwards from the head of the data, or backwards from the tail of the data. Both methods have their uses.

As to the question of little-endian, you can think of it as printing a number "backwards." So instead of it being 1337 in memory, it would be 7331. However, in Grammer and other languages that offer low-level memory access, we are working with bytes. 1337 in hexadecimal is 0x0539, so the bytes are 05 and 39, but they are stored "little end first" (or "little end in" -> little endian). So internally, 39 05. Most users won't have to worry about this. Presumably, if you write a 2-byte word to an address, you are going to read it as a 2-byte word. In this case, it will read the number back as expected Smile

The people to whom the clarification of endian-ness is useful are those who wish to do pretty low-level stuff. These would usually be people pretty familiar with Assembly, anyways Razz

gaventemples31415 wrote:

So, how would I create a tilemap and use it in a game?

Well, lets say you have 256 different tiles or fewer. Then each tile ID can fit in one byte. If the tile map is 20x20, then you need 400 bytes. So create the appvar with 400 bytes. If you are making your own tilemap routine, then it is completely up to you in what order you store the data. If you use the built-in tilemap routine, then the first 20 bytes correspond to the first row of 20 tiles, then the next 20 bytes correspond to the second row. So give (X,Y), you would use X+20*Y as the offset into your appvar for where the tile data is.

To actually display the tilemap:

Code:

Get("UMap00→Z
Get("UTiles→W
 Pt-Change(0,Z,W,20,0,0,0

gaventemples31415 wrote:

Can you make a 12x12 sprite, or can they only be multiples of 8?

The width must be a multiple of 8, but the height is not restricted this way.
gaventemples31415 wrote:

How do lists work in Grammer?

Grammer does not have "lists" like TI-BASIC does. You can create an array of data, like in an appvar and then edit the bytes manually. You would use int(Z+index,value to write to a byte, and (Z+index to read a byte.
Xeda, your font editor program is not working on the TI-84 Plus SE. Whenever I press [+] or [MODE], it crashes. Any ideas?
Hmm, it has been so long since I have worked on Grammer that I do not know. Which version of Grammer do you have ?
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 2 of 2
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement